Enabling sudo for non-administrators

Continuing the discussion from Can't remove Command Line Tools:

Since I mentioned it …

The behavior of the sudo command is configured via a text file, /etc/sudoers. Note that only the root account and users in the “wheel” group can read this file. But you can view it (from an account with sudo access, like an administrator), by typing “sudo cat /etc/sudoers” from a terminal window.

There’s a lot of stuff in there, but the most important lines, for the purpose of this thread, are:

root     ALL = (ALL) ALL
%admin   ALL = (ALL) ALL

Each line of this form authorizes a particular user or group of users to run a program or group of programs as root (or as another specified user).

The general form of these lines is:

<user>      <host> = (<run-as>) <commands>
%<group>    <host> = (<run-as>) <commands>

Where:

  • <user> is a user name. If it begins with #, then a user ID
  • <group> is a group name. If it begins with #, then a group ID
  • <host> is a host name. “ALL” means “all hosts”
    • This field exists because this config file could be on a network server, shared by many computers. So you can configure rules to apply to only some computers on the network.
  • <run-as> indicates which users and groups the user/group is allowed to run the commands as. “ALL” means “all users and groups”. (sudo can be used to run a command as any user or group in the system, not just root. The config file can be used to restrict this.)
  • <commands> is a comma-separated list of CLI command the user/group is allowed to run via sudo. “ALL” means “all commands”.
    • You can also prefix commands with various keywords to further configure what can be done.

So, to explain the default entries:

root ALL = (ALL) ALL

This allows the root user (first term), running on any host (second term), to run any command (fourth term) as any user (third, parenthesized term).

%admin ALL = (ALL) ALL

This is similar, but allows any user in the admin group to run any command as any user.

So, if you want to add another specific user (e.g., a non-admin user) to the set of those allowed to run anything as anybody via sudo, you can add a line of the form:

username ALL = (ALL) ALL

And if you want to, for example, let a particular user run only diskutil, but no other commands as root, you could add a line like:

username ALL = (root) /usr/sbin/diskutil

And if you want to let him run this command without providing a password:

username ALL = (root) NOPASSWD: /usr/sbin/diskutil

And just for completeness, if you want to allow this user to run anything as anybody, not require a password for diskutil, but to require one for anything else:

username ALL = (ALL) PASSWD: ALL, NOPASSWD: /usr/sbin/diskutil

(“ALL” comes first because when a command matches multiple entries, the last match is the one that takes effect.)

The syntax supports far more than the above summary, but a full discussion could be an hours-long presentation. For all the ugly details type man sudoers or look here: sudoers(5) - Linux manual page

One final thing:

Although /etc/sudoers is a text file, you should not edit it with an ordinary text editor. This is because errors can cause sudo to stop working altogether. If you break it, you’ll need to gain root-level access through some other mechanism (most of which are disabled by default in macOS) in order to edit the file so you can recover from the mistake.

Instead, use a command visduo. This command invokes the vi text editor (or some other editor, configurable via environment variables), but it syntax-checks the file before letting you save it. So you can’t accidentally break anything, as long as you don’t ignore its warnings. See also: visudo(8) - Linux manual page

8 Likes

If a non-administrator is permitted to sudo, then are they not effectively an administrator?

I’d think they would be able to do anything an admin can, including raising their own account to be an admin account.

I think an important distinction is that sudo can be far more finely grained than “admin vs non-admin”, e.g., @shamino’s example of granting sudo privileges to a user for only for the diskutil program, but not others.

There are some other subtleties that I can’t recall at the moment, owing in part to macOS’s unusual implementation of the “root” account so that it does not quite have the omnipotent capabilities found in other Unix/Unix-like operating systems. There are still more peculiarities about running sudo (vs su, for example) from the command-line, but those are relatively uncommon in routine Mac usage.

2 Likes

Temporarily, in the Terminal, yes. That’s the point.

Sure. But here’s a use case:

I have a Mac mini media server that automatically logs in to a standard account if it is restarted. It’s not connected to a monitor, and we’re not always home, so I want the Mac running and logged in after a power outage. By allowing that account to sudo, I can do things at the command line that a standard account would not be able to do, without logging in as an admin. But if somebody steals the machine, they cannot do admin tasks, see any files that don’t belong to that standard account, etc., unless they know the account password.

2 Likes

Yes and no. With respect to the fact that (if you configure it for (ALL) ALL), you can use sudo to run a command as root knowing only your own password, yes.

But administrative accounts have other permissions beside that. For instance:

  • Administrative accounts don’t need to unlock various system settings pages (e.g., network settings) in order to make changes.
  • When installing software or making changes to locked system settings, a non-admin user (even with sudo access) must still provide an admin user name and password.
2 Likes

I’ve done this, but it’s annoying that the sodoers file gets reset back to the default every time there is an update.

1 Like

Yes, but you don’t need to edit the /etc/sudoers file itself. If you look at the last few lines:

## Read drop-in files from /private/etc/sudoers.d
## (the '#' here does not indicate a comment)
#includedir /private/etc/sudoers.d

Create a file in /etc/sudoers.d. Name it anything you want. Put your customizations in there. They won’t be touched by software updates.

For safety, you can (and should) still edit the file with visudo:

sudo visudo /etc/sudoers.d/my_rules

5 Likes

While my sudoers file remains unchanged after all software updates (lucky, I guess?), thanks for the great tip. I know I’m doing this from now on.

MacOS is unusual, but not alone in what it does with the super user privileges. Some of the Linux distros I use (Fedora and RHEL come to mind) install with the root account disabled for login by default so it’s expected to use sudo when needed. It’s a bit easier to enable the root account for those distros than in macOS, though.

And if you use SELinux, that can take away some of the omnipotent powers of the root account when operating in enforcement mode. From what I understand about SELinux, it can do some very fine grained control over Linux - probably a superset of what SIP can do.

Some of my customers wouldn’t even give the root password for their Linux systems to their sysadmins. They forced the use of sudo so they could restrict and log privileged actions.

Yes, that is exactly the sort of thing I had in mind when I wrote my comment. It’s a long way from the trouble you could get yourself into with some of the old commercial Unix flavors.

Cool, thanks for the tip!

minor note: apple clobbers edits you made to the sudoers file when they update the o/s.