Difference between revisions of "Linux admin notes - users and permissions"

From Helpful
Jump to: navigation, search
m (x without r)
m (Practice: Group administration)
 
(48 intermediate revisions by the same user not shown)
Line 389: Line 389:
 
* the SUID and SGID bits in a file's mode will trigger {{search|seteuid() / setegid()}} syscalls at launch time, with the file's current user/group
 
* the SUID and SGID bits in a file's mode will trigger {{search|seteuid() / setegid()}} syscalls at launch time, with the file's current user/group
  
* "SUID root" is the typical case: chown as root, set suid bit, to have root permissions without need for sudo
+
* "SUID root" is the common case of that: chown as root, set suid bit, to have root permissions without need for sudo
 
: can only be set ''by'' root / through sudo (for obvious security reasons)
 
: can only be set ''by'' root / through sudo (for obvious security reasons)
 
: often for daemons. Many of which will, after basic startup, use the same syscalls to give away root permissions again (switch to a normal user)  
 
: often for daemons. Many of which will, after basic startup, use the same syscalls to give away root permissions again (switch to a normal user)  
Line 407: Line 407:
  
  
 
+
For the system side of that, see [[#The_various_UIDs.2F_GIDs.2C_related_syscalls.2C_and_SUID.2FGUID_on_execution]]
 
+
'''Some details'''
+
 
+
Every program runs with an effective user and group.
+
 
+
Under regular circumstances, they are the user (and current group{{verify}}) that executes the executable, which means the program can do exactly what the user can.
+
 
+
 
+
Which securitywise is sensible default behaviour, but doesn't serve all cases.
+
Some things need to get at something more restricted to work {{comment|(some just while initializing, some throughout their execution)}}.
+
 
+
Some system commands need this, including passwd, mount, umount, ping, and su.
+
 
+
For another sort of example, <tt>svgalib</tt> needs root access to access graphics hardware directly, which would mean anything that needs svgalib is only useful when root runs it, or you're allowed to run it via sudo.
+
 
+
 
+
With SUID and/or SGID, once a program starts executing, it reads the user and/or group ID from the file's directory entry, and hands those to <tt>setuid</tt> and/or <tt>setgid</tt>, and the related <tt>seteuid</tt> and <tt>setegid</tt>.
+
 
+
Which are system calls which you can always use, it's just that the file permission flag is a handy way to set this up outside of changing the executable's code.
+
 
+
 
+
 
+
Since you can't really give away ownership (e.g. set a file to be owned by root, unless you ''are'' root), this isn't a security problem.
+
However, you and ''particularly'' root should be careful of what they ''take'' ownership of; whatever files are owned by root, generally accessible, o+x and setuid or setgid will effectively run as root when executed by anyone, and therefore be able to do anything.
+
There are a few fairly simple ways around this, such as to disallow directory access, which can be done by moving files you take ownership of to /root, when it has something like 0700 permissions - like it usually does.
+
 
+
 
+
 
+
=====UID and EUID=====
+
 
+
A process on most *nixish OSes technically manages three UIDs:
+
* real UID - who started the process
+
 
+
* effective UID -
+
: Most things check this one checking a process is allowed to do a thing.
+
 
+
* saved UID - a placeholder for a UID so that it can be restored later
+
: e.g. allows the option of dropping superuser rights temporarily, rather than permanently
+
 
+
 
+
In many cases, UID and EUID are the same (and saved is irrelevant).  
+
 
+
There are a handful of calls relating to real/effective/saved,
+
and their semantics (what they set, and in what cases they refuse to)
+
is most of the details involved. And varies a little between OSes.
+
 
+
 
+
Linux also adds fsuid, which is a separate identity that is used when checking file access permissions. Unless setfsuid
+
 
+
The group stuff (real group ID, effective group ID, saved group id, fsgid) is mostly analogous
+
 
+
 
+
 
+
A [[SUID]] binary is one where effective ID (and the real ID {{verify}}) are set from the file's UID
+
 
+
<!--
+
For example {{inlinecode|passwd}} is typically suid and owned by root, because
+
the password file is root-owned
+
while passwd runs, its UID describes the user which ran it to alter their password,
+
while the EUID will have to be root to write to the password file.
+
 
+
 
+
For another example, a webserver process started as root may wish to set its EUID before it does any filesystem accesses to satisfy a request.
+
 
+
 
+
 
+
The relevant underlying system calls:
+
* <tt>geteuid()</tt>
+
* <tt>getuid()</tt>
+
* <tt>seteuid(uid_t euid)</tt>
+
* <tt>setuid(uid_t ruid)</tt>
+
Also:
+
* <tt>setreuid(uid_t ruid, uid_t euid)</tt> - can set both real and effective UID at once, or just one
+
 
+
 
+
There is analogous logic for the real and effective group (TODO: more explanation).
+
The relevant system calls for it:
+
* <tt>getegid()</tt>
+
* <tt>getgid()</tt>
+
* <tt>setegid(gid_t egid)</tt>
+
* <tt>setgid(gid_t rgid)</tt>
+
Also:
+
* <tt>setregid(gid_t rgid, gid_t egid)</tt> - can set both at once
+
-->
+
 
+
See also:
+
* https://people.eecs.berkeley.edu/~daw/papers/setuid-usenix02.pdf
+
* https://yarchive.net/comp/setuid_mess.html
+
  
 
====umask====
 
====umask====
Line 692: Line 604:
 
* {{search|Andreas Grunbacher, POSIX Access Control Lists on Linux}}
 
* {{search|Andreas Grunbacher, POSIX Access Control Lists on Linux}}
  
===Changing UIDs and GIDs===
+
===Changing account's UID or GID===
 
<!--
 
<!--
  
Line 701: Line 613:
  
  
Note that this does not affect the filesystem. Chances are that you want something along the lines of:
+
Note that this does not affect the filesystem -- which is sometimes exactly why you're doing this, and sometimes why you will mess things up.
 +
 
 +
Chances are that you want to consider something along the lines of:
 
  find / -uid ''olduid'' -xdev -print0 | xargs -0 chown -h ''stillsameusername''
 
  find / -uid ''olduid'' -xdev -print0 | xargs -0 chown -h ''stillsameusername''
 
  find / -gid ''oldgid'' -xdev -print0 | xargs -0 chown -h '':stillsamegroupname''
 
  find / -gid ''oldgid'' -xdev -print0 | xargs -0 chown -h '':stillsamegroupname''
Line 840: Line 754:
 
====Practice: Group administration====
 
====Practice: Group administration====
  
 +
Mostly:
 +
* {{inlinecode|groupadd ''groupname''}} - create group
 +
* {{inlinecode|groupdel ''groupname''}} - remove group
 +
* {{inlinecode|gpasswd}} and {{inlinecode|usermod}} for membership (see below)
  
{{inlinecode|groupadd ''groupname''}}
 
  
{{inlinecode|groupdel ''groupname''}}
+
'''Additional group membership''' is probably easiest via:
 +
* {{inlinecode|gpasswd -a ''user'' ''group''}} also appends to additional groups {{verify}} (but note argument order)
  
usermod and gpasswd (see below)
+
* {{inlinecode|gpasswd -d ''user'' ''group''}} removes a user from a group
  
sometimes {{inlinecode|groupmod}} to change the name, or gid (group ID) [http://linux.die.net/man/8/groupmod]
+
Further group membership stuff:
 +
* {{inlinecode|usermod -g ''group'' ''user''}} set primary group -- and remove all other group membership{{verify}}
  
Sometimes {{inlinecode|gpasswd}}:  
+
* {{inlinecode|usermod -G ''group'' ''user''}} set additional groups to exact list
 +
 
 +
* {{inlinecode|usermod -G -a ''group'' ''user''}} '''append''' to additional groups
 +
: note <tt>-a</tt> is a ''relatively'' recent feature. If you don't have it, you may need to use -G with a full list
 +
 
 +
 
 +
Other
 +
'''gpasswd''' is largely for the fancier group stuff, like:
 
: {{inlinecode|gpasswd ''group''}} to set the group password
 
: {{inlinecode|gpasswd ''group''}} to set the group password
 
: {{inlinecode|gpasswd -r ''group''}} to remove the password
 
: {{inlinecode|gpasswd -r ''group''}} to remove the password
Line 858: Line 784:
  
  
You often have to worry less about creating groups, as<tt>adduser</tt> may be configured to
+
Notes:
: add a group with the same name as the user it creates (is this usually <tt>/etc/adduser.conf</tt>?{{verify}}), OR
+
* {{inlinecode|id}} '''will not show the change within the same login session''', because group membership is queried only at login time and fixed for that session. Running a new shell (even -l{{verify}}) won't do it.
: to have a default group to add everyone to.  
+
: for a quick-ish check:
 +
:: {{inlinecode|id -Gn $USER}} {{comment|(just happens to need to query <tt>/etc/group</tt>)}}
 +
:: or get a shell with new login sesstion via {{inlinecode|su - $USER}} or {{inlinecode|ssh localhost}}
 +
: for a proper change, log out and back in
 +
:: (graphical) session manages may reuse session if you log in within ~30 seconds or so. To be sure, wait that long.
  
  
 +
<!-- I've seen suggestions that getent is preferred over checking /etc files yourself()
  
'''group membership''':
+
* also, getent group
* '''Change additional groups''':
+
** {{inlinecode|usermod -a -G ''group1,group2'' ''user''}}  ''' ''add'' additional''' group membership(s)
+
*** <tt>-a</tt> is a relatively recent feature, so you may not have it, in which case you may need to use...
+
** <tt>usermod -G ''group1,group2''</tt> sets group membership ''' ''to'' exactly this list, so be careful
+
** {{inlinecode|gpasswd -d ''user'' ''group1''}} to '''remove a user's group membership'''
+
  
* '''set primary group''', a.k.a. '''initial login group'''
 
** '''Warning''': {{inlinecode|usermod -g ''group'' ''username''}} works but  '''also removes all other group memberships'''. Look at <tt>-G</tt> to re-add them if you accidentally did that.
 
*** Files in the user's home directory will be [[chown]]ed from the old to the new GID{{verify}}. The rest of the filesystem is unchanged, so you will have to do that yourself.
 
  
 +
* In most contexts you can specify either the group's name or its GID.
  
 +
* tools and calls put more importance on (or work into) '''primary group''', a.k.a. '''initial login group'''.
 +
: For example, <tt>usermod -g</tt> will [[chown]] files in your home directory will be from old to the new GID{{verify}} {{comment|(to ensure you can login; the rest of the filesystem is '''not''' scanned in this way, so you or an admin will need to do that manually)}}
  
Note: In almost all cases you can specify either the group's name or its GID.
+
* Maybe also look at
 +
: <tt>adduser</tt>, in that you may configure it for more sensible defaults in your setup, e.g.
 +
:: add a group with the same name as the user it creates (is this usually <tt>/etc/adduser.conf</tt>?{{verify}}), OR
 +
:: to have a default group to add everyone to.
 +
When this means less worry by default, admins may want to look at what you can configure there.
 +
: {{inlinecode|groupmod}}, but only really to change the name {{comment|(or gid, group ID, but that's rarely what you want to do)}} [http://linux.die.net/man/8/groupmod]
  
 
===Other notes===
 
===Other notes===
Line 1,051: Line 982:
  
  
==su, sudo, sudoers==
+
===The various UIDs/ GIDs, related syscalls, and SUID/GUID on execution===
{{stub}}
+
  
 +
'''Some details'''
  
===tl;dr===
+
For another sort of example, <tt>svgalib</tt> needs root access to access graphics hardware directly, which would mean anything that needs svgalib is only useful when root runs it, or you're allowed to run it via sudo.
  
* {{inlinecode|su}} '''switches active user to another''' {{comment|(by default to root)}}
+
With SUID and/or SGID, once a program starts executing, it reads the user and/or group ID from the file's directory entry, and hands those to <tt>setuid</tt> and/or <tt>setgid</tt>, and the related <tt>seteuid</tt> and <tt>setegid</tt>.
: which requires the password of that user
+
: {{comment|(Not a complete re-login. When things seem to break because of this, su -l can help, and in practice a <tt>ssh</tt> to localhost may be easier)}}
+
: note that root can switch to any account {{comment|(also relevant to sudo su)}}
+
  
 +
Which are system calls which you can always use, it's just that the file permission flag is a handy way to set this up outside of changing the executable's code.
  
* {{inlinecode|sudo}} '''executes something as another user''' {{comment|(by default as root)}}
 
: root can do this arbitrarily
 
: other users/groups can do so when configured as such
 
:: optionally configured to not ask for a password. Which can make sense for mounting - but think about implications.
 
  
  
* {{inlinecode|sudo su}} is mostly the simple combination of the above:
+
Since you can't really give away ownership (e.g. set a file to be owned by root, unless you ''are'' root), this isn't a security problem.
: "switch to a root, given that your account has the (sudo) rights to do so"
+
However, you and ''particularly'' root should be careful of what they ''take'' ownership of; whatever files are owned by root, generally accessible, o+x and setuid or setgid will effectively run as root when executed by anyone, and therefore be able to do anything.
: You don't need the ''other'' user's password, but ''yours'', because you only need to prove to sudo you are who you say you are
+
There are a few fairly simple ways around this, such as to disallow directory access, which can be done by moving files you take ownership of to /root, when it has something like 0700 permissions - like it usually does.
: note that in practice it's similar to sudo bash, but without the new shell (due entirely to what su does in general)
+
  
===su===
+
 
 +
 
 +
=====UID and EUID=====
 
{{stub}}
 
{{stub}}
su can be remembered as 'switch user' (its general purpose) or 'superuser' {{comment|(its default behaviour, and its real name)}}.
 
  
  
When executed as root, su also gives you the ability to switch to accounts that do not have a password - those that are not regular logins and/or cannot be directly logged in as.
+
A process on most unices OSes manages three user and three group IDs:
This can be useful to administer accounts for services {{comment|(that should run as their own user, but that should not imply ability to log in)}}.
+
* '''real UID''' (ruid), real GID (rgid)
 +
: who started the process
 +
: also relates to signal permissions: A non-superuser process can only signals if ruid or euid (or rgid or egid) matches. Note that this implies children can be default, because inheritance
  
 +
* '''effective UID''' (euid), effective GID (egid)
 +
: Most things check this one checking a process is allowed to do a thing.
 +
: euid is assigned to files created by this process
 +
: egid semantics often the same (though there are/were some variations with kernels)
  
Example:
+
* '''saved UID''', more fully "saved set user ID" (suid; note potential confusion with SUID), saved GID (sgid)
su              # switch to root
+
: a placeholder for a UID so that it can be restored later
su ''someuser''     # switch to user ''someuser''
+
: e.g. allows a process to drop existing superuser rights temporarily, rather than permanently {{comment|(and to avoid having to ask the system for permission when setting that later. Basically this encourages processes to drop them while not necessary. This isn't so much a security thing as a procetion against common mistakes)}}
 +
: more precisely, an unprivileged process can set its euid to: its ruid, its suid (and technically its present euid)
 +
: privileged processes - ?{{verify}}
 +
: seems this is only set implicitly -- when switching from euid 0 to non-0 euid {{verify}} (the semantics of other parts take care of the rest)
  
By default you get an interactive shell. You can get a login shell by using {{inlinecode|-}} or {{inlinecode|-l}} or {{inlinecode|--login}}, much more like the environment the user might expect. (If you use the <tt>-</tt> form, it must be the last option)
 
  
su -l              # switch to root with login shell
 
su - ''someuser''    # switch to user ''someuser'' with login shell
 
  
{{comment|(You may want to read [[Bash_and_profiles#login_vs._interactive_shells]])}}
+
: '''Under typical circumstances'''
  
 +
When you don't need privileges (the bulk of cases):
 +
* your process's ruid and euid are the same
 +
* your process's suid is irrelevant
  
 +
Which securitywise is sensible default behaviour, but doesn't serve all cases.
  
For security reasons, su does not preserve the environment that it was called from.
 
Often enough that's right, but sometimes you do want to take things along.
 
You can get (still selective) evironment copying by using -m or -p or --preserve-environment (equivalent)
 
  
  
====X and su; "MIT-MAGIC-COOKIE-1 data did not match"====
+
: '''altering these manually'''
  
See [[X_notes#.22MIT-MAGIC-COOKIE-1_data_did_not_match.22]]
+
There are a handful of syscalls relating to real/effective/saved,
 +
and their semantics - what they set, and in what cases they would be refused.
 +
Note that some of these details vary between OSes.
  
===sudo===
+
Most of them:
{{stub}}
+
* <tt>geteuid()</tt>
 +
* <tt>getuid()</tt>
 +
* <tt>seteuid(uid_t euid)</tt>
 +
* <tt>setuid(uid_t ruid)</tt>
 +
Also:
 +
* <tt>setreuid(uid_t ruid, uid_t euid)</tt> - can set both real and effective UID at once, or just one
  
Sudo {{comment|(super user do ''...'')}} is a framework which allows users/groups/everyone to run specific commands as another user -- often as root.
 
  
The sudo system can log commands and arguments as an audit trail.
+
There is analogous logic for the real and effective group (TODO: more explanation).
 +
The relevant system calls for it:
 +
* <tt>getegid()</tt>
 +
* <tt>getgid()</tt>
 +
* <tt>setegid(gid_t egid)</tt>
 +
* <tt>setgid(gid_t rgid)</tt>
 +
Also:
 +
* <tt>setregid(gid_t rgid, gid_t egid)</tt> - can set both at once
  
  
Sudo mostly changes the effective user of the process to be run{{verify}}.
+
Unprivileged processes may only set euid to ruid, sgid, or (current) euid. {{comment|(and analogous for groups)}}
  
It does ''not'' start a new shell for the user.
+
Privileged processes can set any (though there are cases that are considered errors).  
This may be an insignificant detail, a subtle difference, or a significant problem.
+
Note that this is not a permanent privilege drop, because it can be set back to rgid later. {{verify}}
  
By default leaves most of the environment (but not all{{verify}}) intact.
 
Allowing/blocking environment matters to things like cron jobs (where you use a different effective user)
 
  
 +
<!--
 +
on setgid and supplementary groups
 +
https://unix.stackexchange.com/questions/265199/why-are-privs-required-to-setgid-to-supplementary-groups
 +
-->
  
The <tt>/etc/sudoers</tt> file is its configuration: it controls what commands can be run, by who, ''as'' who, and more.
 
  
 +
: '''on privilege drops'''
  
  
 +
'''permanent privilege drops''' are a little harder, in part because euid and suid are ''designed'' to allow temporary
 +
privilege drops. Basically, you must make sure that none of ruid, euid and suid are privileged.
  
Examples:
 
  
: '''everyone can run a specific command'''
 
  
Say you have a classroom full of workstations, in which you want users to be able to mount CDs (and you do not have an auto-mounter doing that for them).
+
: '''Having effective IDs set via the filesystem'''
  
Since mounting a volume requires root permissions, you could allow users to execute only two commands as root, {{inlinecode|mount /cdrom}} and {{inlinecode|umount /cdrom}} - and for no other devices.
+
Alongside all that are some relevant filesystem entry's mode bits:
 +
* SUID
 +
: kernel reads file's UID and does a seteuid() {{verify}} when doing an execve()
 +
* SGID
 +
: kernel reads file's GID and does a setegid() {{verify}} when doing an execve()
 +
* sticky (no longer relevant{{verify}})
  
  
 +
A filesystem entry with these bits will often have UID (and maybe GID) 0, for root privileges.
  
: '''a specific user can run a specific command'''
+
Some system commands need this, including
 +
: ping (for raw socket access)
 +
: passwd (because the password files are root-owned)
 +
: su
 +
: mount and umount
 +
...and more. For kicks, take a look at the output of:
 +
find /usr/*bin /*bin -perm /6000 -type f -ls
  
I wanted a web-facing port-scan, which means my apache needed to run nmap as root.
+
Note that SUID root regularly sorta violates [[least privilege]], particularly when we only needed it for very limited reasons (see e.g ping), which is roughly why [[capabilities]] became a thing.
  
 +
Note also that this mechanism means user permissions system has now extended to involve ''filesystem'' state.
 +
{{comment|(For root this usually isn't so bad, since even under [[DAC]] only root can alter things owned by root.
 +
...or people with blanket [[sudo]] rights, which is why you want to be careful with that.)}}
  
  
: '''specific people can run anything'''
 
  
Usually, anyone who is considered an administrator for a host is given either root access or sudo rights. Some people prefer sudo rights, because that way you're only ever intentionally dangerous, when you use sudo before a command.
+
: '''related processes'''
  
How this is done depends a little on the exact setup. /etc/sudoers often has a line that allows members of a specific user group sudo rights for everything.
+
A fork() will inherit these three sets from the source process
This is often <tt>sudo</tt> or <tt>wheel</tt>. In sudoers that means
+
 
%sudo ALL=(ALL) ALL   
+
An execve() will inherit the three sets - but SUID/SGID will override when they apply. {{verify}}
# or 
+
 
%wheel ALL=(ALL) ALL   
+
 
...and it would mean [[Linux_admin_notes_-_users_and_permissions#Group_administration|adding the user to the group]].
+
 
 +
 
 +
 
 +
 
 +
: '''fsuid'''
 +
Linux also adds fsuid, which is a separate identity that is used when checking file access permissions.
 +
Unless setfsuid is used,
 +
 
 +
This is not used much.
 +
 
 +
See also http://www.cs.umd.edu/~jkatz/TEACHING/comp_sec_F04/downloads/setuid.pdf
 +
 
 +
 
 +
 
 +
See also:
 +
* https://people.eecs.berkeley.edu/~daw/papers/setuid-usenix02.pdf (or [http://www.cs.umd.edu/~jkatz/TEACHING/comp_sec_F04/downloads/setuid.pdf here])
 +
* https://yarchive.net/comp/setuid_mess.html
 +
* https://cnitarot.github.io/courses/cs526_Spring_2015/s2014_526_os.pdf
 +
* https://www.osso.nl/blog/setuid-seteuid-uid-euid/
  
 +
=====GID and EGID=====
  
 +
See previous section.
  
====<tt>sudo</tt> versus <tt>su</tt> versus <tt>sudo su</tt>====
+
==su, sudo, sudoers, sudo su, etc==
 
{{stub}}
 
{{stub}}
  
Basically:
+
 
* {{inlinecode|su}} switches some amount of the shell to another effective user
+
* '''{{inlinecode|su}}''' can be remembered as 'switch user' {{comment|(by default to root)}}
* {{inlinecode|sudo}} runs a single command as another user
+
: '''starts a non-login shell as the target user'''
: when the admin gave you sudo rights on your account
+
:: when non-login breaks things (e.g. because no user profile), consider su -l
 +
: for non-root users it's similar to login to that other user (requiring their password)
 +
 
 +
: root can switch to other users arbitrarily
 +
:: meaning you can also switch to accounts that do not have a password (so cannot be logged into normally), which is useful to administer accounts for services that preferably run as their own user - without giving them the ability to log in.
 +
: su by default does not preserve the environment that it was called from (security reasons)
 +
:: ({{verify}}su - clears, su keeps, -s and -i effectively clear{{verify}})
 +
:: you can get (still selective) evironment copying by using -m or -p or --preserve-environment (equivalent)
 +
 
 +
 
 +
 
 +
 
 +
* '''{{inlinecode|sudo}}''', 'switch user and do command' {{comment|(by default as root)}}
 +
: '''runs a single command as another user''' {{comment|(e.g. does not start a new shell)}}
 +
: sudo only works when sudoers (see below) gives your user the right (or you are root)
 
: which means you get asked for your password, not root's.
 
: which means you get asked for your password, not root's.
 +
: it is possible to configure sudo to ''not'' ask for a password (for a specific command)
 +
: By default leaves most of the environment (but not all{{verify}}) intact.
 +
: who is allowed to do what, as who (and further features like audit logging) is configurable, see sudoers below
  
As such:
 
* {{inlinecode|sudo su}}
 
: su by default switches to root, but would ask for root's password
 
: running su as root (that's sudo's effect here) to switch to root means it doesn't ask for a password
 
: ...but the sudo just did, and it asked for yours (based on your rights to sudo)
 
: When you're not root, this is often the only way you may be allowed to use su
 
  
  
More notes:
+
 
* You can be given either the right to use sudo in general (useful for admin accounts that are not root), or sudo specific commands (sometimes useful)
+
{{inlinecode|sudo su}} is the combination:
* {{inlinecode|sudo su -}} The dash means "don't just make me root, give me root's environment, as as if I've logged in as root"
+
: "get root rights via sudo, then tell su to run a shell"  
* You ''could'' do {{inlinecode|sudo bash}}, but it's probably cleaner to do one of:
+
 
* {{inlinecode|sudo -i}} means 'simulate a [[login shell]] as root'
+
Not for security reasons {{comment|(rights to run sudo su carry essentially ''all'' the risks for giving out root)}} but more for administrative reasons: you can selectively allow specific users to run a root shell, based on their own password (and based on configuring them via sudoers) rather tham sharing the root password.
 +
 
 +
 
 +
And yes, <tt>sudo bash</tt> would be similar to <tt>sudo su</tt> but not indentical in details, like when bashrc gets sourced{{verify}}.  In fact, for a more predictable environment, consider the below over sudo su (or sudo bash):
 +
 
 +
{{inlinecode|sudo -i}} means 'simulate a [[login shell]] as root'
 
: Some argue this is preferable to {{inlinecode|sudo su}} as your environment will be more predictable {{comment|(arguably only matters when root is an account that you've ever set up a profile for, not so much when you're just using it for the privileges)}}.
 
: Some argue this is preferable to {{inlinecode|sudo su}} as your environment will be more predictable {{comment|(arguably only matters when root is an account that you've ever set up a profile for, not so much when you're just using it for the privileges)}}.
* {{inlinecode|sudo -s}} means 'give me an interactive shell as root'
+
 
 +
{{inlinecode|sudo -s}} means 'give me an interactive shell as root'
 
: So yes, {{inlinecode|su -}} is similar to {{inlinecode|sudo -s}}  
 
: So yes, {{inlinecode|su -}} is similar to {{inlinecode|sudo -s}}  
 
: not all variants/versions of sudo have <tt>-i</tt> (or -s{{verify}} <!--
 
: not all variants/versions of sudo have <tt>-i</tt> (or -s{{verify}} <!--
 
: sudo -s / sudo -i means that sudo invokes a shell itself - which sudoers has to allow{{verify}} -->
 
: sudo -s / sudo -i means that sudo invokes a shell itself - which sudoers has to allow{{verify}} -->
  
* There are some further details to whether the environment is kept/cleared. (su - clears, su keeps, -s and -i effectively clear{{verify}})
+
Also, consider {{comment|(consider also <tt>ssh</tt> to localhost)}}
  
 +
 +
 +
 +
'''su examples'''
 +
 +
Examples:
 +
su              # switch to root
 +
su ''someuser''    # switch to user ''someuser''
 +
 +
# force login shell with -l, or - after the last option
 +
su -l                # switch to root with login shell
 +
su - ''someuser''    # switch to user ''someuser'' with login shell
 +
 +
 +
 +
'''sudo examples'''
 +
# typical examples are software installation
 +
sudo apt install boinc-client
 +
 +
# non-root example:
 +
#  it's easier to run psql (CLI) as the postgres user
 +
#    (because [[pg_hba]] typically has the postgres (=an admin) role trusted to the postgres system user)
 +
sudo -u postgres psql
 +
 +
 +
 +
Notes:
 +
 +
* you may prefer to explain sudo rights as "sudo specific commands".
 +
: it is a good habit to use sudo on all admin commands, to associate using sudo with serious business -- rather than geting an always-root shell (via sudo su or similar)
 +
: sudo is often configured to allow shell users to do successive commands without giving a password each time (for up to a few minutes at a time). This trades a little security for a bunch of convenience when you're doing admin work.
 +
 +
 +
 +
 +
Differences (Su versus regular login and ssh)
 +
* su does not (by default) preserve the source environment.
 +
 +
* su does not start a login shell, other login and ssh usually do
 +
: so among the largest difference is that su doesn't source the target user's ~/.profile
 +
 +
* PAM config may hook in different things to su and ssh
 +
 +
 +
<!--
 +
 +
sudo and cron
 +
 +
:: Allowing/blocking environment matters to things like cron jobs (where you use a different effective user)
 +
 +
 +
 +
-->
 +
 +
 +
<!--
 
* allowing a user to sudo su or otherwise run a new shell lets them do ''anything'' as that user. This is either exactly what you want (e.g. letting a user administer the machine, administer the database as the database user, etc.), or ''not at all'' what you want. Also varying with personal trust.
 
* allowing a user to sudo su or otherwise run a new shell lets them do ''anything'' as that user. This is either exactly what you want (e.g. letting a user administer the machine, administer the database as the database user, etc.), or ''not at all'' what you want. Also varying with personal trust.
  
 
* Allowing an account to sudo su to root means that someone gaining access to that user account can be close equivalent to gaining root privileges (depending on how they got in. If they brute forced the password, for example). This is why admins don't easily give this out
 
* Allowing an account to sudo su to root means that someone gaining access to that user account can be close equivalent to gaining root privileges (depending on how they got in. If they brute forced the password, for example). This is why admins don't easily give this out
 +
-->
 +
 +
 +
 +
===sudoers===
 +
 +
Sudoers is the configuration file that sudo checks.
 +
 +
 +
It allows you to configure things like
 +
* '''everyone can run a specific command'''
 +
 +
Say you have a classroom full of workstations, in which you want users to be able to mount CDs (and you do not have an auto-mounter doing that for them).
 +
 +
Since mounting a volume requires root permissions, you could e.g. allow users to execute only two precise commands as root, {{inlinecode|mount /cdrom}} and {{inlinecode|umount /cdrom}} {{comment|(so that it allows it for this and for no other devices)}}.
 +
 +
 +
 +
* '''a specific user can run a specific command'''
 +
 +
Example: I wanted a web-facing port-scan, which means my apache user (and no one else) needed to run nmap (and nothing else) as root. Something like:
 +
apache      ALL=(root)  NOPASSWD:/usr/bin/nmap
 +
 +
 +
 +
* '''specific people can run anything'''
 +
 +
Usually, anyone who is considered an administrator for a host is given either root access or sudo rights.
 +
 +
When you trust specific people on a host, it is still a good idea to do things via sudo,
 +
so that they are only ever intentionally dangerous, and have a visual reminder (you put sudo before a command).
 +
 +
(Yes, you can sudo su to get out of that. But it's good habit not to.)
 +
 +
How this is done depends a little on the exact setup. /etc/sudoers often has a line that allows members of a specific user group sudo rights for everything.
 +
This is often <tt>sudo</tt> or <tt>wheel</tt>. In sudoers that means
 +
%sudo ALL=(ALL) ALL   
 +
# or 
 +
%wheel ALL=(ALL) ALL   
 +
...and it would mean [[Linux_admin_notes_-_users_and_permissions#Practice:_Group_administration|adding the user to the group]].
 +
  
* sudo is often configured to allow shell users to do successive commands without giving a password each time (for up to a few minutes at a time). This trades a little security for a bunch of convenience when you're doing admin work
 
  
====sudoers====
 
  
 
=====editing=====
 
=====editing=====
Line 1,325: Line 1,418:
 
* http://www.afp548.com/article.php?story=20051025103428232
 
* http://www.afp548.com/article.php?story=20051025103428232
  
====Debugging visudo====
+
=====Debugging visudo=====
 
{{stub}}
 
{{stub}}
 
Perhaps the most useful thing related to figuring out why you can't do what you think you just allowed is:
 
Perhaps the most useful thing related to figuring out why you can't do what you think you just allowed is:
Line 1,343: Line 1,436:
 
* the sudo line should contain the absolute path to the executable.
 
* the sudo line should contain the absolute path to the executable.
  
 +
===Related errors===
 +
 +
=====X and su; "MIT-MAGIC-COOKIE-1 data did not match"=====
 +
 +
See [[X_notes#.22MIT-MAGIC-COOKIE-1_data_did_not_match.22]]
  
  
====Related errors====
 
 
=====error: ''parse error in /etc/sudoers near line -1'' =====
 
=====error: ''parse error in /etc/sudoers near line -1'' =====
  

Latest revision as of 11:57, 7 October 2019

Linux-related notes
Linux user notes

Shell, admin, and both:

Shell - command line and bash notes · shell login - profiles and scripts · Shells and execution ·· find and xargs and parallel · screen and tmux
Linux admin - disk and filesystem · users and permissions · Debugging · security enhanced linux · health and statistics · kernel modules · YP notes · unsorted and muck
Logging and graphing - Logging · RRDtool and munin notes
Network admin - Firewalling and other packet stuff ·


Remote desktops
VNC notes
XDMCP notes



...particularly in the context of filesystems

Filesystem permission basics

Most people know the below to some degree, and should.


'nix file permissions are a simpler system ACLs.

Which sometimes makes them easier to deal with, and sometimes requires serious contortion - which is one reason ACLs slowly being introduced into unices here and there.


Each filesystem entry (files, directories, other) has a set of properties. The most interesting are:

  • the user id (ususally shown as the name, as it is looked up on the current computer)
  • the group id (ususally shown as the name, as it is looked up on the current computer)
  • read, write, execute permissions bits for the owning user
  • read, write, execute permissions bits for the owning group
  • read, write, execute permissions bits for other - things that apply for everyone.

You can also get and set these numerically, as explained further down.


Permission bits are shown in various ways. The form form is the output used by
ls -l
. Its output for a regular file could look like:
-rw-r--r--  1 sarah users 2414 Nov 21  2004 afile.txt

The first bit shows permission bits (and more, explained later). You should read this as a special flag/filetype field, followed by three group of rwx, one for each of user, group, and other. For example:

- rw- r-- r--

The permission is present if the letter is present. In this case, sarah can read and write, anyone in the users group can read, and anyone else can also read this file.

'Other' is used for minimal permissions, since it always applies (regardless of what user or group id a visiting user comes along with), so -rw----r-- has a very similar effect in to -rw-r--r--.


Details explained later:

  • setgid and setuid are also be indicated in those letters
  • rights work slightly differently on directories


Notes: Seeing a plus sign, e.g.

-rw-r--r--+ 1 sarah users 2414 Nov 21  2004 afile.txt

...means that there are ACLs on this listing. See them with things like getfacl

Changing permissions

When changing permissions on a file there are various ways of describing permissions. One common distinction is whether you specify what should change or whether you specify exactly what the new permission set would be.

There are also different ways of describing each permission, and different operations to the permission bits. Choose the one or two you like.


Common usage:

chmod o-rwx afile.txt            # takes all permissions away from other
chmod +x afile.txt               # gives everyone execute permission
                                 # (short for a+x or the equivalent ugo+x)
chmod ug+w -R dataDir            # Gives user and group write permission


It is technically also possible to combine operations:

chmod a-rwx,u+wr,g+r -R dataDir  # A much-at-once style (not seen used much, but useful)
chmod u=rwx,go=rx dataDir        # Set-to-exactly-this style, in this case rwxr-xr-x

The numeric way sets permission bits as octal numbers, and is the shortest way to set all bits in one go. Where r=4, w=2, x=1:

chmod 0777 somefile              # gives full permission to all, like a=rwx.
chmod 0620 somefile              # sets rw- r-- ---
chmod 0750 somefile              # sets rwx r-x ---

...and any other combination. Most people remember just a few cases, such as 0777 as 'allow all', 600 (owner readwrite) or 644 (owner readwrite, others read-only) for files, 755 or 700 for directories, or such.


The leading zero is usually not necessary for command line utilities, since they know to interpret numbers as octals. In code you will usually need to use them, as otherwise they won't be understood as octal numbers.


Note that execute permissions on a file will include it in command autocompletion in shells. It will also allow execution as a binary, according to the hashbang, or using /bin/sh (as a fallback).

Changing ownership

You can change the user, group and each of these permissions, with chown and chmod respectively:

chown frank:goats afile.txt  # sets user to frank, group to goats
chown frank       afile.txt  # sets user to frank, leave group unchanged
chown frank:      afile.txt  # sets user to frank, and group to frank's login group
chown :goats      afile.txt  # sets group to goats
 
chown -R frank dataDir      #recursive: changes entire subtree (files, directories)

For more details on groups, see #Groups.


chown: changing ownership of `/path': Operation not permitted

Only the file/directorory's owning user (and root) can alter user or group membership.

You may expect that the file/dir's owning group can do so too, if it has write access to the file/dir. It can't. The reason seems to be practical one - it makes it easy to give away files that aren't yours, and/or that you can't get back. (is there some reason based in quota systems?(verify))


If you are the owning user (or root) and still can't, it's probably that the immutable attribute is set. See lsattr and chattr.

It may be that SELinux is prohibiting you (even if you're root).


You may be using a non-*nix filesystem, one which does not store file permissions (e.g. FAT).


Filesystem guts you can usually avoid

mode

Programmers may find it interesting that the permission bits mentioned are a subset of the mode.

Mode is a larger integer (now often 32-bit), which stores:

  • permission bits (lowest 9 bits)
  • setgid (S_ISGID, usually 2000). In text representation it's in the group-execute field, an s if the group execute bit is set, or S if the execute bit is missing
  • setuid (S_ISUID, usually 4000). In text representation, see setgid, but for the user execute field/bit.
  • sticky (S_ISVTX, usually 1000). In text presentation, it's in the other-execute field. It's t if the execute bit is present, T if it is missing.
  • file type (see below, and these are read-only)

Most command line tools only show (and allow change of) permission, sticky, setuid, setgid,

The mode may also store OS-specific bits, which you can only get at via OS-specific libraries.


File types:

what constant (octal; may differ(verify)) in text representation of mode
regular file S_IFREG, 0100000 -
directory S_IFDIR, 0040000 d
named pipe, fifo S_IFIFO, 0010000 p
character special device S_IFCHR, 0020000 c
block special device S_IFBLK, 0060000 b
symbolic link S_IFLNK, 0120000 l
socket S_IFSOCK, 0140000 s

You usually only need to care about regular files, directories, and the occasional symlink.


You can get the full mode with a stat(), which is what library functions that test 'is this a directory' use, but even the command-line stat command masks out everything but the permissions bits unless you specifically ask for all of the mode bits.

It also shows it in hex for some reason, so to view the full mode in octal, you'ld have to do something like the following:

$ stat --format %f /tmp | tr [a-f] [A-F] | xargs --replace=@ echo "ibase=16; obase=8; @" | bc
41777


Extended file attributes

This article/section is a stub — probably a pile of half-sorted notes, is not well-checked so may have incorrect bits. (Feel free to ignore, fix, or tell me)


directory permissions, read and execute

tl;dr: In general, r and x are only useful in combination.


In more detail:

  • directory read rights
allows listing the directory's entry names
  • directory write rights allow: create, rename, remove, and alter entries in it (including changing permissions)
(...so o+w is scary)
  • directory execute rights
allow cd into the directory
allow looking up (basically stat()ing) entry's details within this directory (verify)

(If that seems weird, keen in mind that directories are just another entry within their parent directory - just a specific kind due to being marked as a directory in its entry's mode)



For the examples below

mkdir -p a/b c/d e/f
chmod 0111 a
chmod 0444 c
chmod 0000 e

To have:

d--x--x--x 3 user user 4096 Mar 22 18:30 a
dr--r--r-- 3 user user 4096 Mar 22 18:30 c
d--------- 3 user user 4096 Mar 22 18:30 e

(b, d, f have typical permissions, according to your umask. You will typically have rwx. These contents don't need to be directories, but it can help your mental model of how this works in trees a bit)


x without r

You can go there (because x), but you can't listdir() (because no r)

~$ ls a
ls: cannot open directory a: Permission denied
 
~$ cd a
~a/$ ls
ls: cannot open directory .: Permission denied

Note that if you can guess entry names you can open them fine. If you can guess their name and they are directories (with x), change to them fine.

To continue the above example:

~a/$ ls b   # says nothing only because our example gave b no contents
~a/$ stat b 
      # gives full output, omitted here 
~a/$ cd b
~a/b$ ls    # says nothing because no contents
r without x
You can list entry names (because r), but not
cd
to it or stat its contents (because no x)
~$ ls c
ls: cannot access c/d: Permission denied
d

When you can't stat entries in a directory (due to -x on its parent), you also can't do descending into them (because you can't even do the permission check)

~$ cd c
cd: c: Permission denied
~$ cd c/d
cd: c/d: Permission denied


neither r or x

Can't list its entries, can't go there or under it, for the reasons explained above.



in a tree
Mount points and permissions

directory permissions, write

o+w permission is scary since it means that anyone can alter directory entries, even if those entries don't list the user as their owner.

The same applies to g+w if the group is something like 'users' or 'students' and that includes people you may not want to trust implicitly.


Sometimes you may want a directory which can be used to give each other files, or a generally shared directory.


directory permissions, sticky

Without sticky, you can share a directory only if you are in the same group, or allow write permissions to world.


When a directory has the sticky bit set, then this parent directory's owner and each directory entry's actual owner can rename and remove entries (anyone can create files/directories).

With sticky, people can work in the same directory, but can shield each other from accidentally (or purposefully) messing with files and directories they don't own.

/tmp is often a stickied directory for this reason.


(The sticky bit was named for its historical use on regular files, where it was a signal to the OS to keep this around in memory (or in local rather than remote storage), as it would probably be used regularly. Modern caching and drive speed has made this mostly obsolete. (I'm not sure whether modern kernels still listen to the sticky bit(verify))

setuid, setgid, and sticky on files

This article/section is a stub — probably a pile of half-sorted notes, is not well-checked so may have incorrect bits. (Feel free to ignore, fix, or tell me)

tl;dr:

  • the SUID and SGID bits in a file's mode will trigger seteuid() / setegid() syscalls at launch time, with the file's current user/group
  • "SUID root" is the common case of that: chown as root, set suid bit, to have root permissions without need for sudo
can only be set by root / through sudo (for obvious security reasons)
often for daemons. Many of which will, after basic startup, use the same syscalls to give away root permissions again (switch to a normal user)
(the point may e.g. be binding to a port under 1024, which normal users can't do)


These bits are stored in the mode, on top of basic rwx permissions, are:

  • setuid (SUID), shown in the user's execute position, 4000 in octal, add with
    chmod u+s
  • setgid (SGID), shown in the group's execute position, 2000 in octal, add with
    chmod g+s
  • sticky bit, shown in other's execute position, 1000 in octal, add with
    chmod o+t


In
ls -l
they show up instead of the execute field field, e.g.
-rwsrwsr-t 1 root root  1191834 Nov 23  2013 thingie

(When they have these bits without execute, the S and T are shown in uppercase)


For the system side of that, see #The_various_UIDs.2F_GIDs.2C_related_syscalls.2C_and_SUID.2FGUID_on_execution

umask

This article/section is a stub — probably a pile of half-sorted notes, is not well-checked so may have incorrect bits. (Feel free to ignore, fix, or tell me)

The umask removes permission bits from files and directories (programs running as) you create, from mkdir to whatever fanciness you are running.

You can always change them later - the point here is what protection you get by default.

Example: If the umask is 0022:

  • 0022 itself means --- -w- -w-
  • ...which are the things that are removed from permissions
  • in this case meaning that on newly created files, write permissions will never appear for group or other. Read and execute is not masked away, so other people can go into your directories and read files.


When people work in groups -- (but you still want at least processes to have a clear owner, so sharing a single account is not so useful), you might want to not mask anything from the group so that you can work with each others' data by default. Example: 0002 (or so),

If your group is something like 'students' or 'staff', you probably don't want group writability. You might use 0027 (no write on group, nothing on other), or perhaps 0077 if paranoid.


You can make this persistent by adding something like

umask 0002

to your ~/.bashrc (or whatever applies for your shell).

POSIX ACLs

See also:

Changing account's UID or GID

Accounts

By default, account information is backed by /etc/passwd (user list) and /etc/group (group list), and usually also the shadow files.

Note that filesystems store UIDs and GIDs, not usernames and group names, meaning filesystem permissions are inherently local to a computer unless those IDs are centralized / synchronized. This also matters to network filesystems such as NFS


useradd, usermod

useradd
adds a user
adduser
is a wrapper in Debian and derivatives (e.g. Ubuntu) which adds configurable site-specific configuration, making some things easier.
You may wish to use only adduser to avoid confusion.
(though I can never remember which name is which, but man is your friend)
usermod
changes details.

Most people user them so rarely that we just look at the man page.


On homedir:

Notes:

  • useradd isn't always configured to create the user's home directory.
you'll want
useradd -m
(as it's more convenient than manually copying from /etc/skel/ and fiddling with the permissions)
  • (Similarly, whether userdel deletes a home directory, mail spool and such depends on configuration)
  • not having a home directory means the account cannot log in (as does not having a valid shell).
Not having a password set usually also disallows logins, at least remotely(verify).
(This can be useful to e.g. have users for samba to map to, but to not allow them to shell into the same server)


On groups:

Often, default is to create a group of the same name, and add the user to it.

If you want users to go to a shared group instead, you can control this via arguments and, often, configuration files (see the man page for your system to be sure) like:

/etc/login.defs
/etc/defaults/useradd

Changing passwords

Use
passwd


On systems that integrate with networked systems like NIS, you may need to use another executable (like
yppasswd
). A plain
passwd
may tell you so - or may be symlinked to what you need to use.


To not allow password login, use passwd -l. This prepends something (!) at the start of the hash value, meaning no password will ever work. It also means you can unlock (passwd -u) by removing that character again (avoids having to set/remember the hash).

Keep in mind that -l applies only to this type of password login. SSH logins may have their own rules, and may effectively bypass it depending on how it is set up, and on how a user is trying to authenticate.


You may be able to set the hash of a blank password - as in 'accept pressing enter for a password'. While passwd probably won't allow it, you can generate the appropriate hash value via mkpasswd. This is generally a bad idea, though. If you want passwordless remote login, look at using a passphraseless keypair.

Deleting (passwd -d) seems to (usually? always?) mean a blank password (verify) - if so, you rarely want this.



Keep in mind that anyone with root (/general sudo) rights can su to any user, regardless of whether they are allowed remote or local login.

Groups

Theory: group logic

This article/section is a stub — probably a pile of half-sorted notes, is not well-checked so may have incorrect bits. (Feel free to ignore, fix, or tell me)


Some important distinctions:

  • your primary group, a.k.a. initial login group
    • part of your login info
  • your additional group memberships
    • part of your login info, can be queried, but not everything does (verify)
  • a process's current effective group
    • your shell also has a currently effective group - which likely is your primary group, unless it was explicitly forced to be something different.


The easiest command line tool to see a user's currently effective GID(verify), and collection of all group memberships is probably
id
.

For regular users it may be as simple as:

uid=1004(sarah) gid=100(users) groups=100(users)

Root gets around more, and may look like:

uid=0(root) gid=0(root) groups=0(root),1(bin),2(daemon),3(sys),4(adm),
6(disk),10(wheel),11(floppy),18(audio),20(dialout),26(tape),27(video)



Because of the history of how processes work, the mental model and the code is slightly hairy.

Lazy and older programs may test only for the current effective GID and UID. A process can checks for additional memberships, but they have to care, and have to know how to do it.


To change one's own currently effective group (in the shell), use
newgrp groupname
.
  • If you are a member of that group. it will switch without question.
  • If you are not a member, it will either
    • deny you or
    • ask for the group password, ...depending on how the group admin has set up the group.


There is a
sg
[1], analogous to but for groups:

it sets a different group for executing a particular command.

Practice: Group administration

Mostly:

  • groupadd groupname
    - create group
  • groupdel groupname
    - remove group
  • gpasswd
    and
    usermod
    for membership (see below)


Additional group membership is probably easiest via:

  • gpasswd -a user group
    also appends to additional groups (verify) (but note argument order)
  • gpasswd -d user group
    removes a user from a group

Further group membership stuff:

  • usermod -g group user
    set primary group -- and remove all other group membership(verify)
  • usermod -G group user
    set additional groups to exact list
  • usermod -G -a group user
    append to additional groups
note -a is a relatively recent feature. If you don't have it, you may need to use -G with a full list


Other gpasswd is largely for the fancier group stuff, like:

gpasswd group
to set the group password
gpasswd -r group
to remove the password
gpasswd -R group
disables the ability for non-members to use password login
These can be done by a group admin and root.
Group admins are one or more (non-root) users who are allowed to change group membership.
Group admins are added to groups by root, using
gpasswd -A user group
.)}}


Notes:

  • id
    will not show the change within the same login session, because group membership is queried only at login time and fixed for that session. Running a new shell (even -l(verify)) won't do it.
for a quick-ish check:
id -Gn $USER
(just happens to need to query /etc/group)
or get a shell with new login sesstion via
su - $USER
or
ssh localhost
for a proper change, log out and back in
(graphical) session manages may reuse session if you log in within ~30 seconds or so. To be sure, wait that long.


Duplicate UIDs

Change UID

/etc/passwd, /etc/shadow, /etc/groups

These are plain-text, colon-delimited databases containing all information about users, passwords, and group membership.

Password shadowing describes system that separate out publicly fetchable information, and store the actual password hash in a separate file.


It's generally best to modify these with system utils like useradd, usermod, userdel, groupadd, groupmod, groupdel, chpasswd (changing password), gpasswd (changing group membership), chfn (change finger/CEGOS field), chsh (change login shell), ...although there are a number of situations where you can get away with editing them directly.

There is also vigr and vipw.


/etc/passwd is a colon-delimited file that stores basic user information:

  • username (up to 32 chars?(verify))
  • password - in the old days this stored the password hash.
Nowadays it is typical to put the password hash in /etc/shadow (which general users/programs cannot read), and leave this file readable, because the rest of the fields are public and useful.
...so this field will contain something like an x to indicate the real password hash is stored in /etc/shadow (it seems other values have been used, like !(verify))
  • UID - user's numeric ID
  • GID - primary group ID, refers to entry in /etc/group
  • Sometimes called comment, sometimes called GECOS. (Used by finger, if you use it) May contain comma-separated sub-fields including the following (but there are deviations from this)
    • Real name
    • physical address (building, room)
    • phone number
    • other contact info - pager, fax, email address
  • home directory for user
  • login shell to be invoked


/etc/shadow stores the user's password hashes, and some further password-related information

  • username
  • password hash
    • *, x and ! all(verify) seem to indicate 'no password is valid'
    • nothing seems to mean 'no password is present' - which allows passwordless login (verify)
    • starting with $ indicates use of a non-default hash method, and typically starts by specifying which hash.

Apparenrly $1$ is MD5, $2a$ is Blowfish, $3$ is NT hash $5$ is SHA-256, $6$ is SHA-512. (there may be another $ in the value, splitting a salt from the hash)

  • date of last change (days since Jan 1, 1970)
  • minimum days before a next password change is allowed (0, i.e. no limitations, seems common)
  • days after which a password is expired, and change is forced on the next login (99999 basically means "won't expire")
  • amount of days before the previous entry that you get warnings (7 seems common)
  • number of days after expiry after which the account is actually disabled (rather than just forces password change)
  • absolute date of expiry (days since Jan 1, 1970)
  • reserved field

Notes:

  • 99999 days after 1970 is somewhere in October of 2243.
  • Dates in ~2012 are around 15500
  • passwd
    to change the password
  • chage
    ('change user password expiry information') to change most other things, or list the details in a more friendly way.


/etc/groups

  • group name
  • GID
  • password (if any) - though if you use password shadowing, it will be in /etc/gshadow
  • comma-separated list of group members (is this an exact mirror of /etc/gshadow?(verify))


/etc/gshadow

  • group name
  • password
  • comma-separated list of group admins
  • comma-separated list of group members (is this an exact mirror of /etc/groups?(verify))


The various UIDs/ GIDs, related syscalls, and SUID/GUID on execution

Some details

For another sort of example, svgalib needs root access to access graphics hardware directly, which would mean anything that needs svgalib is only useful when root runs it, or you're allowed to run it via sudo.

With SUID and/or SGID, once a program starts executing, it reads the user and/or group ID from the file's directory entry, and hands those to setuid and/or setgid, and the related seteuid and setegid.

Which are system calls which you can always use, it's just that the file permission flag is a handy way to set this up outside of changing the executable's code.


Since you can't really give away ownership (e.g. set a file to be owned by root, unless you are root), this isn't a security problem. However, you and particularly root should be careful of what they take ownership of; whatever files are owned by root, generally accessible, o+x and setuid or setgid will effectively run as root when executed by anyone, and therefore be able to do anything. There are a few fairly simple ways around this, such as to disallow directory access, which can be done by moving files you take ownership of to /root, when it has something like 0700 permissions - like it usually does.


UID and EUID
This article/section is a stub — probably a pile of half-sorted notes, is not well-checked so may have incorrect bits. (Feel free to ignore, fix, or tell me)


A process on most unices OSes manages three user and three group IDs:

  • real UID (ruid), real GID (rgid)
who started the process
also relates to signal permissions: A non-superuser process can only signals if ruid or euid (or rgid or egid) matches. Note that this implies children can be default, because inheritance
  • effective UID (euid), effective GID (egid)
Most things check this one checking a process is allowed to do a thing.
euid is assigned to files created by this process
egid semantics often the same (though there are/were some variations with kernels)
  • saved UID, more fully "saved set user ID" (suid; note potential confusion with SUID), saved GID (sgid)
a placeholder for a UID so that it can be restored later
e.g. allows a process to drop existing superuser rights temporarily, rather than permanently (and to avoid having to ask the system for permission when setting that later. Basically this encourages processes to drop them while not necessary. This isn't so much a security thing as a procetion against common mistakes)
more precisely, an unprivileged process can set its euid to: its ruid, its suid (and technically its present euid)
privileged processes - ?(verify)
seems this is only set implicitly -- when switching from euid 0 to non-0 euid (verify) (the semantics of other parts take care of the rest)


Under typical circumstances

When you don't need privileges (the bulk of cases):

  • your process's ruid and euid are the same
  • your process's suid is irrelevant

Which securitywise is sensible default behaviour, but doesn't serve all cases.


altering these manually

There are a handful of syscalls relating to real/effective/saved, and their semantics - what they set, and in what cases they would be refused. Note that some of these details vary between OSes.

Most of them:

  • geteuid()
  • getuid()
  • seteuid(uid_t euid)
  • setuid(uid_t ruid)

Also:

  • setreuid(uid_t ruid, uid_t euid) - can set both real and effective UID at once, or just one


There is analogous logic for the real and effective group (TODO: more explanation). The relevant system calls for it:

  • getegid()
  • getgid()
  • setegid(gid_t egid)
  • setgid(gid_t rgid)

Also:

  • setregid(gid_t rgid, gid_t egid) - can set both at once


Unprivileged processes may only set euid to ruid, sgid, or (current) euid. (and analogous for groups)

Privileged processes can set any (though there are cases that are considered errors). Note that this is not a permanent privilege drop, because it can be set back to rgid later. (verify)



on privilege drops


permanent privilege drops are a little harder, in part because euid and suid are designed to allow temporary privilege drops. Basically, you must make sure that none of ruid, euid and suid are privileged.


Having effective IDs set via the filesystem

Alongside all that are some relevant filesystem entry's mode bits:

  • SUID
kernel reads file's UID and does a seteuid() (verify) when doing an execve()
  • SGID
kernel reads file's GID and does a setegid() (verify) when doing an execve()
  • sticky (no longer relevant(verify))


A filesystem entry with these bits will often have UID (and maybe GID) 0, for root privileges.

Some system commands need this, including

ping (for raw socket access)
passwd (because the password files are root-owned)
su
mount and umount

...and more. For kicks, take a look at the output of:

find /usr/*bin /*bin -perm /6000 -type f -ls

Note that SUID root regularly sorta violates least privilege, particularly when we only needed it for very limited reasons (see e.g ping), which is roughly why capabilities became a thing.

Note also that this mechanism means user permissions system has now extended to involve filesystem state. (For root this usually isn't so bad, since even under DAC only root can alter things owned by root. ...or people with blanket sudo rights, which is why you want to be careful with that.)


related processes

A fork() will inherit these three sets from the source process

An execve() will inherit the three sets - but SUID/SGID will override when they apply. (verify)




fsuid

Linux also adds fsuid, which is a separate identity that is used when checking file access permissions. Unless setfsuid is used,

This is not used much.

See also http://www.cs.umd.edu/~jkatz/TEACHING/comp_sec_F04/downloads/setuid.pdf


See also:

GID and EGID

See previous section.

su, sudo, sudoers, sudo su, etc

This article/section is a stub — probably a pile of half-sorted notes, is not well-checked so may have incorrect bits. (Feel free to ignore, fix, or tell me)


  • su
    can be remembered as 'switch user' (by default to root)
starts a non-login shell as the target user
when non-login breaks things (e.g. because no user profile), consider su -l
for non-root users it's similar to login to that other user (requiring their password)
root can switch to other users arbitrarily
meaning you can also switch to accounts that do not have a password (so cannot be logged into normally), which is useful to administer accounts for services that preferably run as their own user - without giving them the ability to log in.
su by default does not preserve the environment that it was called from (security reasons)
((verify)su - clears, su keeps, -s and -i effectively clear(verify))
you can get (still selective) evironment copying by using -m or -p or --preserve-environment (equivalent)



  • sudo
    , 'switch user and do command' (by default as root)
runs a single command as another user (e.g. does not start a new shell)
sudo only works when sudoers (see below) gives your user the right (or you are root)
which means you get asked for your password, not root's.
it is possible to configure sudo to not ask for a password (for a specific command)
By default leaves most of the environment (but not all(verify)) intact.
who is allowed to do what, as who (and further features like audit logging) is configurable, see sudoers below



sudo su
is the combination:
"get root rights via sudo, then tell su to run a shell"

Not for security reasons (rights to run sudo su carry essentially all the risks for giving out root) but more for administrative reasons: you can selectively allow specific users to run a root shell, based on their own password (and based on configuring them via sudoers) rather tham sharing the root password.


And yes, sudo bash would be similar to sudo su but not indentical in details, like when bashrc gets sourced(verify). In fact, for a more predictable environment, consider the below over sudo su (or sudo bash):

sudo -i
means 'simulate a login shell as root'
Some argue this is preferable to
sudo su
as your environment will be more predictable (arguably only matters when root is an account that you've ever set up a profile for, not so much when you're just using it for the privileges).
sudo -s
means 'give me an interactive shell as root'
So yes,
su -
is similar to
sudo -s
not all variants/versions of sudo have -i (or -s(verify)

Also, consider (consider also ssh to localhost)



su examples

Examples:

su              # switch to root
su someuser     # switch to user someuser

# force login shell with -l, or - after the last option
su -l                # switch to root with login shell
su - someuser    # switch to user someuser with login shell


sudo examples

# typical examples are software installation
sudo apt install boinc-client

# non-root example:
#  it's easier to run psql (CLI) as the postgres user
#    (because pg_hba typically has the postgres (=an admin) role trusted to the postgres system user)
sudo -u postgres psql


Notes:

  • you may prefer to explain sudo rights as "sudo specific commands".
it is a good habit to use sudo on all admin commands, to associate using sudo with serious business -- rather than geting an always-root shell (via sudo su or similar)
sudo is often configured to allow shell users to do successive commands without giving a password each time (for up to a few minutes at a time). This trades a little security for a bunch of convenience when you're doing admin work.



Differences (Su versus regular login and ssh)

  • su does not (by default) preserve the source environment.
  • su does not start a login shell, other login and ssh usually do
so among the largest difference is that su doesn't source the target user's ~/.profile
  • PAM config may hook in different things to su and ssh




sudoers

Sudoers is the configuration file that sudo checks.


It allows you to configure things like

  • everyone can run a specific command

Say you have a classroom full of workstations, in which you want users to be able to mount CDs (and you do not have an auto-mounter doing that for them).

Since mounting a volume requires root permissions, you could e.g. allow users to execute only two precise commands as root,
mount /cdrom
and
umount /cdrom
(so that it allows it for this and for no other devices).


  • a specific user can run a specific command

Example: I wanted a web-facing port-scan, which means my apache user (and no one else) needed to run nmap (and nothing else) as root. Something like:

apache       ALL=(root)   NOPASSWD:/usr/bin/nmap


  • specific people can run anything

Usually, anyone who is considered an administrator for a host is given either root access or sudo rights.

When you trust specific people on a host, it is still a good idea to do things via sudo, so that they are only ever intentionally dangerous, and have a visual reminder (you put sudo before a command).

(Yes, you can sudo su to get out of that. But it's good habit not to.)

How this is done depends a little on the exact setup. /etc/sudoers often has a line that allows members of a specific user group sudo rights for everything. This is often sudo or wheel. In sudoers that means

%sudo ALL=(ALL) ALL     
# or   
%wheel ALL=(ALL) ALL     

...and it would mean adding the user to the group.



editing
To edit the sudo configuration, run
visudo
. It mostly just invokes an editor on /etc/sudoers, but adds some locking and checking.


The default editor it uses is vi, but you can configure this in sudoers itself (the env_editor flag in the Default section), or tell visudo to not clear the environment (which it does for slightly paranoid security reasons) using
sudo -E visudo
).


Remember you can check the effects of the current sudoers file using sudo -l


Various types of rules
This article/section is a stub — probably a pile of half-sorted notes, is not well-checked so may have incorrect bits. (Feel free to ignore, fix, or tell me)

The basic form of these rules is:

who    where=(aswho) options: /path/to/what, /path/to/what


  • 'who' is who is allowed to do something, and can be
    • username
    •  %systemgroup
    • ALIAS
    • ALL
  • 'where' describes the hostname. For local rules this is usually usually usually 'ALL' or omitted, unless the sysadmin decided to write one sudoers file for use across many hosts.
  • 'aswho' is the user that should be executed as. Usually root.
  • options
    • NOPASSWD is a common one, meaning you don't have to enter your password, useful for scripted and cronned stuff
  • path to the executable
    • note that since you usually use absolute paths in sudoers, you should also do so on the invocation, or the rule won't match
    • essentially a prefix match, so you can force certain arguments

Examples:

#Everyone can run synergyc (with any options) as root, without having to type their password
ALL     ALL=(root) /usr/bin/synergyc
 
#wilma can do anything as the database user (including starting a shell)
#  without needing a password:
wilma		ALL = (dbuser)  NOPASSWD: ALL
# Note: To use aliases in that field, use Runas_Alias

# Anyone can mount and umount removable devices
ALL            NOPASSWD: /bin/mount /mnt/floppy,  \
                         /bin/umount /mnt/floppy, \
                         /bin/mount /mnt/cdrom,  \
                         /bin/umount /mnt/cdrom,

#(are these globs or EBNF/regex style wildcards?)
# Wildcards can be useful in various ways, for example:
ALL            NOPASSWD: /bin/u?mount /mnt/cd*,  \
                         /bin/u?mount /mnt/dvd*, \
                         /bin/u?mount /mnt/flop*

# john can su to everyone except root (negative match)
john		!/usr/bin/su *root*

# PBIS users can mount some personal shares (should probably be more restricted)
%domain^users   ALL=(root) NOPASSWD:/bin/mount
%domain^users   ALL=(root) NOPASSWD:/bin/umount

#Root can do everything everywhere, as anyone
root		ALL = (ALL) ALL
#same for wheel, except it can't run lilo
%wheel		ALL = (ALL) ALL,!/sbin/lilo


Note that blacklist setups are, as in general, not very secure.

Also, note that it is hard to limit people from changing user.

Setting Defaults
This article/section is a stub — probably a pile of half-sorted notes, is not well-checked so may have incorrect bits. (Feel free to ignore, fix, or tell me)
Setting Aliases
This article/section is a stub — probably a pile of half-sorted notes, is not well-checked so may have incorrect bits. (Feel free to ignore, fix, or tell me)

You can add aliases to add your own groups of...

#...users:
User_Alias DEVELOPERS = alice, blob
User_Alias TEMPS      = mike, wendy
# You may prefer using only the system's groups, though.
# ...commands:
Cmnd_Alias PRINT = /usr/sbin/lpc, /usr/bin/lprm
Cmnd_Alias BOOT  = /usr/sbin/shutdown, /usr/sbin/halt, /usr/sbin/fasthalt
Cmnd_Alias SU    = /usr/bin/su
# ...hosts and nets:
Host_Alias WEBHOSTS = www1, www2
Host_Alias OURNET   = 5.5.0.0/255.255.0.0


See also
Debugging visudo
This article/section is a stub — probably a pile of half-sorted notes, is not well-checked so may have incorrect bits. (Feel free to ignore, fix, or tell me)

Perhaps the most useful thing related to figuring out why you can't do what you think you just allowed is:

sudo -l

This will show a list of allowed commands.


You can do stricter checking of the sudoers file to catch bordercases that may be biting you.

visudo -cs

This may also reveal further included sudoers-parsed files that you may not have been directly aware of.


Keep in mind:

  • when there are multiple matches for a given sudo, the first applies.
Generally, that means more broad allow rules should go first
  • the sudo line should contain the absolute path to the executable.

Related errors

X and su; "MIT-MAGIC-COOKIE-1 data did not match"

See X_notes#.22MIT-MAGIC-COOKIE-1_data_did_not_match.22


error: parse error in /etc/sudoers near line -1

Usually means the user that is trying to sudo is not allowed to.

This can happen when there is no applicable rule for them, or when the user for an applicable rule comes from an external system (say, LDAP) and that system did not respond at the time of the sudo command.


no tty present and no askpass program specified

Late 2009(verify) saw a behaviour change where sudo refuses to ask for a password if no tty is present, because it can't turn echo off. You can make it act like it did before this time by using the 'visiblepw' flag.


You'll get this error when (your configuration means) sudo needs to ask for a password, and the way you run it means there is no terminal on which to do so

...which often means that you wrote a NOPASSWD rule that doesn't apply as you think it would (try using full paths, checking whether the right user applies, and such).

Sorry, user username is not allowed to execute 'something' as root on host

When it mentions bash, in response to su

In my case, I had allowed a user /bin/su as specific other user via sudoers, but not to run anything else as that user.

...most relevantly the shell (that sudo implies when invoked like sudo -i or -l). In this specific case, the easy-enough fix was to allow the shell in the same sudoers line.


Note that in the same situation, sudo su won't complain as it's the already-elevated su that invokes that shell.(verify)


In other cases

You may have written rules that don't apply (can be transient failure, e.g. hostname confusion), or confused sudoers in another way.

gksu, kdesu

These are wrapper for GUI programs that may want root permissions. gksu is from/for GNOME, kdesu for/from KDE.

They do little more than ask for the root login when you are not root, but make it much easier for e.g. menu entries to easily deal with system configuration apps to apply to root and non-root users.

Quota

This article/section is a stub — probably a pile of half-sorted notes, is not well-checked so may have incorrect bits. (Feel free to ignore, fix, or tell me)

Quota

  • keeps track of, and limits, users's and/or groups's files
    • both their size (units of 1K blocks) and the number of inodes (usually less relevant)
    • There is a soft limit that you can cross with only a warning, for a configured grace period.
    • The hard limit cannot be crossed. Using both is nicer to your users, and usually you only care about order of magnitude anyway
  • applies per ext[234] filesystem
can work through NFS - clients will ask for quota at the server end (what you'ld want)
other filesystems vary:
XFS is slightly different.
ZFS has its own separate system
  • requires kernel support
  • isn't useful without its management tools
  • stores a record of the current use, in what it calls the index
(There is an old variant, but pretty much everyone will have be using v2 by now)



Setting up:

  • Make sure your kernel supports it (on modern *nix you can assume it)
  • Install the quota tools. Usually called quota. (There are additional tools, such as quotatool, that you may not need)
  • edit /etc/fstab to add usrquota,grpquota to the mount options of the filesystems you want a quotum on
    • you can use journaled quota when supported. This basically means you don't need to run
      quotacheck
      after an unclean shutdown. It would involve adding
      usrjquota=aquota.user,grpjquota=aquota.group,jqfmt=vfsv0
  • make sure the files to store the index exist in the root of each relevant filesystem. Either:
touch aquota.user aquota.group
, or:
use -c when you manually run quotacheck the first time
  • remount, to make usrquot,grpquota apply
For filesystems currently in use (e.g. root filesystem), using
mount -vo remount
is nice
Less-subtle variants: umount and mount, or reboot.
  • create the quota index, to account for existing contents:
    quotacheck -vgum mountpoint
    • note: -a on this and other tools means '...for all mountpoints for which we use quota', which can save typing
    • -v for verbose may be nice for feedback to you.
    • -u for users, -g for groups
    • -m without this, the tool will remount the filesystem read-only, which you may not like on a running filesystem (particularly your root filesystem). This option tells it to leave it read-write, but keep in mind that any file currently changing size will be incorrectly indexed.
    • -c for create the indices (alternative is creating empty files beforehand)
    • if it tells you it can't guess format from filename, use -F vfsv0 (or vfsv1 if supported and wanted)
  • Optional: run
    repquota -a
    to get a summary of the index we just made
  • start keeping track of(verify) and enforcing(verify) quota:
quotaon -v filesystem
you'll probably want to set that at bootup, e.g. in your init script


  • You may want to put
    quotacheck -mug mountpoint
    in your crontab to make sure the index doesn't go off much(verify)
There are warnings about using that on mounted filesystem. Not because it can corrupt things, but because if a user was handling a huge file just when the index was re-made, the quota can be off by that file's size until the next rescan
...so try to schedule for time of light use, like 4AM


Using - users:

  • quota
    display (-s makes for human-readable sizes)


Using - admin:

  • edquota user
    or
    edquota -g group
    - interactively alter quota for user or group.
    • edquota -p user1 user2 user3 ...
      - copy quota settings from user1 to user2, user3, etc. Also works on groups. Sometimes quite convenient.
    • soft: max blocks/inodes the user may have before warning is issued and grace countdown begins.
    • hard: max blocks/inodes
    • 0 means no enforced limit
    • the grace period is the same for both

Example:

edquota -t 7 days
edquota user_or_uid
  • setquota
    is a non-interactive alternative, useful when automating things. Example:
    setquota -u -F vfsv0 quotauser 1048576 2097152 0 0 /
  • repquota mountpoint
    - report quota use per user. Use -g for groups. Use -s for human-readable sizes.
  • TODO: you probably want to automate quota setting for new users.



See also:



Quota over NFS

This article/section is a stub — probably a pile of half-sorted notes, is not well-checked so may have incorrect bits. (Feel free to ignore, fix, or tell me)

NFS supports it, though under some conditions you may "Input/output error" instead of "Disk quota exceeded"(verify) (I got the latter, though, so that seems to work too)


Basically:

  • Server side:
    • Configure quota as usual
    • set up
      rquotad
      to run (...if you want client-side
      quota
      commands to work). This service may be called something else, such as rpcquota (verify)
  • Client side:
    • mount NFS as usual (no quota related mount options, they won't work)
    • add the -r option to edquota to make it contact the relevant NFS server (note: many other quota tools are local-only, so a habit of logging into the server may be easier)


http://chschneider.eu/linux/server/nfs.shtml

Running with different credentials / reduced permissions

This article/section is a stub — probably a pile of half-sorted notes, is not well-checked so may have incorrect bits. (Feel free to ignore, fix, or tell me)

Know the permission details above.

See also su, sudo, sudoers


SUID, SGID


chroot jails


The graphical run-as-root wrapper is
gksu
, or
kdesu
(GNOME and KDE variants). May be injected into the command when the system can guess you'll need it (particularly in Alt-F2 style launching).