Linux admin notes - users and permissions
| Linux-related notes
Shell, admin, and both:
...particularly in the context of filesystems
- 1 Filesystem permission basics
- 2 Accounts
- 3 su, sudo, sudoers
- 3.1 tl;dr
- 3.2 su
- 3.3 sudo
- 3.3.1 sudo versus su versus sudo su
- 3.3.2 sudoers
- 3.3.3 Debugging visudo
- 3.3.4 Related errors
- 3.4 gksu, kdesu
- 4 Quota
- 5 Running with different credentials / reduced permissions
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 . 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
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.
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).
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).
Extended file attributes
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, usermodadds a user 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)
Most people user them so rarely that we just look at the man page.
- useradd isn't always configured to create the user's home directory.
- you'll want (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)
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:
On systems that integrate with networked systems like NIS, you may need to use another executable (like ). A plain 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.
Theory: group logic
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 .
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 .
- 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 ,
analogous to but for groups:
it sets a different group for executing a particular command.
Practice: Group administration
usermod and gpasswd (see below)sometimes to change the name, or gid (group ID)  Sometimes :
- to set the group password
- to remove the password
- 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 .)}}
You often have to worry less about creating groups, asadduser may be configured to
- add a group with the same name as the user it creates (is this usually /etc/adduser.conf?(verify)), OR
- to have a default group to add everyone to.
- Change additional groups:
add additional group membership(s)
- -a is a relatively recent feature, so you may not have it, in which case you may need to use...
- usermod -G group1,group2 sets additional group membership to exactly this list, so be careful
- to remove a user's group membership
- set primary group, a.k.a. initial login group
Note: In almost all cases you can specify either the group's name or its GID.
Creating homedir after user creation
/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
- password 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
- 99999 days after 1970 is somewhere in October of 2243.
- Dates in ~2012 are around 15500
- to change the password
- ('change user password expiry information') to change most other things, or list the details in a more friendly way.
- group name
- 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))
- group name
- comma-separated list of group admins
- comma-separated list of group members (is this an exact mirror of /etc/groups?(verify))
su, sudo, sudoers
- (by default to root) switches active user to another
- which requires the password of that user
- (Not a complete re-login. When things seem to break because of this, su -l can help, and in practice a ssh to localhost may be easier)
- note that root can switch to any account (also relevant to sudo su)
- (by default as root) executes something as another user
- 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.
- is mostly the simple combination of the above:
- "switch to a root, given that your account has the (sudo) rights to do so"
- 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
- note that in practice it's similar to sudo bash, but without the new shell (due entirely to what su does in general)
su can be remembered as 'switch user' (its general purpose) or 'superuser' (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. This can be useful to administer accounts for services (that should run as their own user, but that should not imply ability to log in).
su # switch to root su someuser # switch to user someuserBy default you get an interactive shell. You can get a login shell by using or or , much more like the environment the user might expect. (If you use the - form, it must be the last option)
su -l # switch to root with login shell su - someuser # switch to user someuser with login shell
(You may want to read Bash_and_profiles#login_vs._interactive_shells)
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"
Sudo (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.
Sudo mostly changes the effective user of the process to be run(verify).
It does not start a new shell for the user. This may be an insignificant detail, a subtle difference, or a significant problem.
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)
The /etc/sudoers file is its configuration: it controls what commands can be run, by who, as who, and more.
- 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 allow users to execute only two commands as root, and - and for no other devices.
- a specific user can run a specific command
I wanted a web-facing port-scan, which means my apache needed to run nmap as root.
- 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.
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.
sudo versus su versus sudo su
- switches some amount of the shell to another effective user
- runs a single command as another user
- when the admin gave you sudo rights on your account
- which means you get asked for your password, not root's.
- 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
- 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)
- The dash means "don't just make me root, give me root's environment, as as if I've logged in as root"
- You could do , but it's probably cleaner to do one of:
- login shell as root' means 'simulate a
- Some argue this is preferable to (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). as your environment will be more predictable
- means 'give me an interactive shell as root'
- So yes, is similar to
- not all variants/versions of sudo have -i (or -s(verify)
- There are some further details to whether the environment is kept/cleared. (su - clears, su keeps, -s and -i effectively clear(verify))
- 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
- 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
editingTo edit the sudo configuration, run . 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 ).
Remember you can check the effects of the current sudoers file using sudo -l
Various types of rules
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
- '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.
- 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
#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.
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 = 188.8.131.52/255.255.0.0
Perhaps the most useful thing related to figuring out why you can't do what you think you just allowed is:
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.
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.
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.
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.
- 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 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)
- 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 after an unclean shutdown. It would involve adding
- make sure the files to store the index exist in the root of each relevant filesystem. Either:
- , 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 is nice
- Less-subtle variants: umount and mount, or reboot.
- create the quota index, to account for existing contents:
- 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 to get a summary of the index we just made
quotaon -v filesystem
- you'll probably want to set that at bootup, e.g. in your init script
- You may want to put verify) in your crontab to make sure the index doesn't go off much(
- 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:
- display (-s makes for human-readable sizes)
Using - admin:
or - interactively alter quota for user or group.
- - 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
edquota -t 7 days edquota user_or_uid
- is a non-interactive alternative, useful when automating things. Example:
- - 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.
Quota over NFS
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)
- Server side:
- Configure quota as usual
- set up verify) to run (...if you want client-side commands to work). This service may be called something else, such as rpcquota (
- 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)
Running with different credentials / reduced permissions
Know the permission details above.
See also su, sudo, sudoers
The graphical run-as-root wrapper is , or (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).