Sudo
GitHub Blog Toggle Dark/Light/Auto mode Toggle Dark/Light/Auto mode Toggle Dark/Light/Auto mode Back to homepage

More info with -ll in sudo 1.9.15

Version 1.9.15 of sudo gives more detailed information when using the -ll option. For commands, it adds the rule that allows it. Without a command parameter, it lists rules affecting a given user. It also prints which file contains the given rule, making debugging easier.

Before you begin

Unless you are using a rolling Linux distribution, there is a good chance that sudo 1.9.15 is not yet available for your system. Luckily the sudo project provides you with easy to use binary packages for many popular Linux distributions and UNIX variants. Check https://www.sudo.ws/getting/packages/ to see if your system is supported. If not, you can still build sudo from source.

Configuration and testing

I did my tests on openSUSE Leap 15.4 The /etc/sudoers I use is almost identical to the one in openSUSE. The only minor difference is that I enabled insults, as they are fun (I love sysadmin humor).

eap154b:~ # cat /etc/sudoers | grep -v '^#' | grep -v '^$'
Defaults always_set_home
Defaults secure_path="/usr/sbin:/usr/bin:/sbin:/bin:/usr/local/bin:/usr/local/sbin"
Defaults env_reset
Defaults env_keep = "LANG LC_ADDRESS LC_CTYPE LC_COLLATE LC_IDENTIFICATION LC_MEASUREMENT LC_MESSAGES LC_MONETARY LC_NAME LC_NUMERIC LC_PAPER LC_TELEPHONE LC_TIME LC_ALL LANGUAGE LINGUAS XDG_SESSION_COOKIE"
Defaults insults
Defaults targetpw	# ask for the password of the target user i.e. root
ALL	ALL=(ALL) ALL	# WARNING! Only use this together with 'Defaults targetpw'!
root ALL=(ALL:ALL) ALL
@includedir /etc/sudoers.d

I removed all empty and comment lines to make it compact and easier to read. There is one more config, a single rule affecting the user called “mytest”.

leap154b:~ # cat /etc/sudoers.d/foo
mytest ALL=ALL

I tested an older sudo release and 1.9.15 with the same configuration. I checked both the -l and the -ll options, with and without a command parameter.

Version <= 1.9.14

First I tested the sudo version that comes with openSUSE Leap (1.9.9). When checking -l with a command parameter, sudo prints the command with its full path.

leap154b:~ # sudo -U mytest -l id
/usr/bin/id

Without a command parameter, sudo prints some generic information, what defaults and rules affect the given user.

leap154b:~ # sudo -U mytest -l
Matching Defaults entries for mytest on leap154b:
    always_set_home,
    secure_path=/usr/sbin\:/usr/bin\:/sbin\:/bin\:/usr/local/bin\:/usr/local/sbin,
    env_reset, env_keep="LANG LC_ADDRESS LC_CTYPE LC_COLLATE LC_IDENTIFICATION
    LC_MEASUREMENT LC_MESSAGES LC_MONETARY LC_NAME LC_NUMERIC LC_PAPER
    LC_TELEPHONE LC_TIME LC_ALL LANGUAGE LINGUAS XDG_SESSION_COOKIE", !insults,
    targetpw

User mytest may run the following commands on leap154b:
    (ALL) ALL
    (root) ALL

Now we repeat the two commands, but instead of -l we use -ll. As you can see, nothing is changed when there is a command parameter.

leap154b:~ # sudo -U mytest -ll id
/usr/bin/id

However, without a command parameter, -ll provides you with more detailed output about the rules.

leap154b:~ # sudo -U mytest -ll
Matching Defaults entries for mytest on leap154b:
    always_set_home,
    secure_path=/usr/sbin\:/usr/bin\:/sbin\:/bin\:/usr/local/bin\:/usr/local/sbin,
    env_reset, env_keep="LANG LC_ADDRESS LC_CTYPE LC_COLLATE LC_IDENTIFICATION
    LC_MEASUREMENT LC_MESSAGES LC_MONETARY LC_NAME LC_NUMERIC LC_PAPER
    LC_TELEPHONE LC_TIME LC_ALL LANGUAGE LINGUAS XDG_SESSION_COOKIE", !insults,
    targetpw

User mytest may run the following commands on leap154b:

Sudoers entry:
    RunAsUsers: ALL
    Commands:
	ALL

Sudoers entry:
    RunAsUsers: root
    Commands:
	ALL

Version 1.9.15

Now we repeat everything with sudo 1.9.15. Here I omitted the -l variant, as the output is exactly same as with the earlier version.

However, when you use the -ll option instead of -l, you will see a marked difference compared to earlier versions. Instead of simply showing the command with the full path name, you will see detailed information. It contains the sudo rule allowing the command in detail, and also the file name where the rule is coming from.

leap154b:~ # sudo -U mytest -ll id
Sudoers entry: /etc/sudoers.d/foo
    RunAsUsers: root
    Commands:
	ALL
    Matched: /usr/bin/id

When using the -ll option without a command parameter, the first half of the output stays the same. However, sudo rules now also include the file name where the rule is coming from.

leap154b:~ # sudo -U mytest -ll id
Sudoers entry: /etc/sudoers.d/foo
    RunAsUsers: root
    Commands:
	ALL
    Matched: /usr/bin/id

When using the -ll option without a command parameter, the first half of the output stays the same. However, sudo rules now also include the file name where the rule is coming from.

leap154b:~ # sudo -U mytest -ll
Matching Defaults entries for mytest on leap154b:
    always_set_home, secure_path=/usr/sbin\:/usr/bin\:/sbin\:/bin\:/usr/local/bin\:/usr/local/sbin, env_reset,
    env_keep="LANG LC_ADDRESS LC_CTYPE LC_COLLATE LC_IDENTIFICATION LC_MEASUREMENT LC_MESSAGES LC_MONETARY LC_NAME
    LC_NUMERIC LC_PAPER LC_TELEPHONE LC_TIME LC_ALL LANGUAGE LINGUAS XDG_SESSION_COOKIE", insults, targetpw

User mytest may run the following commands on leap154b:

Sudoers entry: /etc/sudoers
    RunAsUsers: ALL
    Commands:
	ALL

Sudoers entry: /etc/sudoers.d/foo
    RunAsUsers: root
    Commands:
	ALL

New field in JSON logs

If you take a closer look at JSON formatted sudo logs, you will see another change. There is a new field called “source”, pointing you to the exact rule in the configuration, which allowed a command to run.

I ran “sudo ls” twice in the previously described environment: first as my own user, then as user “mytest”. Here are the relevant log messages:

Sep  5 15:36:28 leap154b sudo[3486]: @cee:{"sudo":{"accept":{"uuid":"35c038417c-4670-459b-e3ed-aaf33192b8","server_time":{"seconds":1693920988,"nanoseconds":960161672,"iso8601":"20230905133628Z","localtime":"Sep  5 15:36:28"},"submit_time":{"seconds":1693920987,"nanoseconds":261612712,"iso8601":"20230905133627Z","localtime":"Sep  5 15:36:27"},"submituser":"czanik","command":"/usr/bin/ls","runuser":"root","runcwd":"/home/czanik","source":"/etc/sudoers:66:23","ttyname":"/dev/pts/0","submithost":"leap154b","submitcwd":"/home/czanik","runuid":0,"columns":118,"lines":60,"runargv":["ls"],"runenv":["LANG=en_US.UTF-8","COLORTERM=1","TERM=xterm-256color","MAIL=/var/mail/root","PATH=/usr/sbin:/usr/bin:/sbin:/bin:/usr/local/bin:/usr/local/sbin","LOGNAME=root","USER=root","HOME=/root","SHELL=/bin/bash","SUDO_COMMAND=/usr/bin/ls","SUDO_USER=czanik","SUDO_UID=1000","SUDO_GID=100"]}}}
Sep  5 15:37:28 leap154b sudo[3536]: @cee:{"sudo":{"accept":{"uuid":"5ef15f4253-ee86-4fa4-84d1-42521673b2","server_time":{"seconds":1693921048,"nanoseconds":536346207,"iso8601":"20230905133728Z","localtime":"Sep  5 15:37:28"},"submit_time":{"seconds":1693921046,"nanoseconds":544743964,"iso8601":"20230905133726Z","localtime":"Sep  5 15:37:26"},"submituser":"mytest","command":"/usr/bin/ls","runuser":"root","runcwd":"/home/mytest","source":"/etc/sudoers.d/foo:1:15","ttyname":"/dev/pts/0","submithost":"leap154b","submitcwd":"/home/mytest","runuid":0,"columns":118,"lines":60,"runargv":["ls"],"runenv":["LANG=en_US.UTF-8","COLORTERM=1","TERM=xterm-256color","MAIL=/var/mail/root","PATH=/usr/sbin:/usr/bin:/sbin:/bin:/usr/local/bin:/usr/local/sbin","LOGNAME=root","USER=root","HOME=/root","SHELL=/bin/bash","SUDO_COMMAND=/usr/bin/ls","SUDO_USER=mytest","SUDO_UID=1001","SUDO_GID=100"]}}}

Of course finding information in raw JSON logs is difficult, so here are the relevant fields:

"source":"/etc/sudoers:66:23"
"source":"/etc/sudoers.d/foo:1:15"

As you can see, the rule for my user is in /etc/sudoers, while for user mytest, the rule is coming from /etc/sudoers.d/foo.

You can enable JSON formatted logging in the sudoers file:

Defaults log_format=json

You can learn more about JSON formatted logging at: https://www.syslog-ng.com/community/b/blog/posts/working-with-json-logs-from-sudo-in-syslog-ng

What is next?

In this blog I showed you the extra information sudo version 1.9.15 is able to provide when you use the -ll option to get a detailed list of a user’s privileges. I also showed you the new “source” field in JSON-formatted sudo logs. Check the release notes at https://www.sudo.ws/releases/stable/#1.9.15 for a complete list of changes in sudo 1.9.15.

If you would like to be notified about new posts and sudo news, sign up for the sudo blog announcement mailing list.