Bugzilla – Bug 352
poor logging and shell integration
Last modified: 2019-01-23 03:56:50 MST
Sudo has a number of problems relating to poor logging and poor shell integration that interfere with replacing root shell with sudo as is often advocated (though perhaps by people other than sudo's author). - Filename completion fails if you need to be root see them. bash (etc.) would have to be patched to use sudo for file globbing. - wildcards fail if you need to be root to see them. Quoting the arguments doesn't work. sudo bash -c "ls /etc/*" works but you are now executing bash not ls and have more layers of quoting (/etc/ is actually readable by non-root, used as example). - comments are stripped off by bash before sudo and not logged sudo rm /foo/bar/baz # incompatible with bar v3.0 - there is no sudo command to log a comment. sudo ### begin installation of libfoo1.2.3 Workaround: sudo echo "### begin installation of libfoo1.2.3" - sudo cd /foo/bar doesn't work. cd is not an executable and if it was the effect would happen in a subshell. Yes, the CWD is logged but when trying to use sudo log for system adminstration logging, it is desirable to log the explict command rather than have to run a filter that looks for changes in the command. - variable substitution occurs before sudo and isn't logged. sudo cp foo $usbdrive Is logged with the variables already substituted. - sudo foo=bar doesn't work and isn't logged - This is external to sudo but many systems have a very poor policy of logging to syslog and rotating the logs which interferes with using sudo to log system adminstration commands. Workaround: logfile=/root/syslog.log in sudoers. - There is not a clear separation of system administration and routine commands in log. Sudo could have a separate command admindo (hard linked) and look at argv[0]. Sudo would log which was used. sudo boring stuff admindo important stuff Then one could filter the log for the important stuff. - Password prompt can mess up cut and paste of multiple commands, with potentially hazardous results. Password prompt can appear unexpectedly due to timeout, etc. This causes two or mor commands to fail, the one that prompted for the password and the one(s) which were eaten by the password prompt. sudo mkdir foo cd foo sudo tar zxvf /dist/pkg.tar.gz If first two are destroyed by password prompt, third command happens in the wrong directory. Sudo should slurp all available input after a password prompt to prevent accidents. Actually, it does, before reading, which is good. But doesn't print a message to that effect. - If user doesn't have permissions on a directory that needs to be manipulated, you can't use sudo. sudo mkdir foo sudo chmod o-rwx foo cd foo # fails sudo mkdir bar This one is trickier to fix with shell integration since CWD can be a directory user doesn't have access to. A sudo cd command, with shell interpretation, would not only log but would set the directory properly even if not accessable. This could work as shown by su example: su cd /var/spool/cups # not world readable (but executable) su whitis # directory still /var/spool/whitis ls ls: cannot open directory .: Permission denied So, bash can handle a working directory it doesn't have permission to access. - Sudo should log the output of each command, in a manner similar to bash "script" command, to a file in a configured directory. If there is no output, the file would be deleted. If there was, the name of the file would be included in sudo.log. Override with a noscript command line option if there is info that shouldn't be captured. In short, sudo not being integrated with the shell causes all sorts of problems. Logging is poor quality and users who expect to be able to type normal root commands from instructions on the net preceeding each with sudo will find the results are not as expected. This could be fixed with a shell that is modified to recognize sudo commands, interpret some of them directly, handle globbing, and pass a usertyped environment variable to sudo for logging in addition to the normal log (you still need to log the actual commands executed in case user spoofs the usertyped variable).
Also, shell aliases and user functions may cause problems. Though preserving them could also be used as a means of attack.
Actually, the alias and function security vulnerability would be negligible considering that someone can always walk up to a sudo root user's terminal and redefine sudo itself just as easily. sudo() { /usr/bin/sudo $* /usr/bin/sudo evil command } But this info isn't easy to get outside the shell without modifications. One approach is to have them be special sudo commands. sudo alias ls=ls -lF sudo function() { blah; blah } To some extent, you may be able to use sudo inside of functions. Another problem was: sudo gui-program & The sudo password prompt didn't appear until program was foregrounded with fg and then it had to be suspended with ^Z and backgrounded with bg. Due to the temporary use of the defective editor gedit (emacs wasn't installed yet) which doesn't autosave by default, I did have to attempt recovery of commands from sudo.log. Of course, the logging botched wildcards. But here is a perl incantation to convert sudo.log into a useful format for system administration logging. The first perl undoes sudo's line wrapping. The second one prints just the command field (preceeded by 'sudo ') and intersperses 'cd' commands when the directory changes. cat sudo.log | perl -n -e '$oldline=""; while(<>) { chomp; $newline=$_; if(substr($newline, 1,1) eq " ") { $oldline=$oldline . substr($newline, 3) } else {print $oldline, "\n"; $oldline=$newline} } ' | perl -n -e 'while(<>) { chomp; ($date1,$date2,$date3, $user, $tty, $pwd, $targetuser, $command) = split(/:|;/); $pwd=~s/ *PWD=//; if($lastpwd ne $pwd) {$lastpwd=$pwd; print "cd ",$pwd,"\n"} $command =~ s/ *COMMAND=//; print "sudo ", $command,"\n" }' Or for syslog: (zcat /var/log/auth.log.1.gz; cat /var/log/auth.log.0 /var/log/auth.log) | fgrep sudo | perl -n -e 'while(<>) { chomp; ($date1,$date2,$date3, $user, $tty, $pwd, $targetuser, $command) = split(/:|;/); $pwd=~s/ *PWD=//; if($lastpwd ne $pwd) {$lastpwd=$pwd; print "cd ",$pwd,"\n"} $command =~ s/ *COMMAND=//; print "sudo ", $command,"\n" }' This doesn't strip out the pathnames for applications found on the path. But information about weird copy commands was logged poorly: mkdir /home/whitis/new_dot_files/ cp -rp /home/whitis/.[a-zA-Z]* /home/whitis/new_dot_files/ cp -rp /olddrive/home/whitis/.[a-zA-Z]* /home/whitis cp -rp /olddrive/home/whitis/* /home/whitis/ sudo didn't have access to the wildcards. Yet oddly, when similar commands were done for root, they were logged - because the shell couldn't read /root/ to replace the wildcards. And the command was logged correctly but failed. But it worked when done like this: sudo bash -c 'echo /root/.[a-zA-Z]*' so, that is a workaround if you aren't already using nested quotes and aren't using shell variable substitution. sudo does more or less the right thing if you do something like: sudo printf "foo\nbar\n" sudo printf 'foo\n$$bar\n' Except it loses the quotes. Which in the second case is the wrong thing as the logged command does not have the same effect as the original. Integration with some sort of emacs (or other editor) client that would automatically append the command executed (and a cd command if the directory changed), to an emacs buffer containing a specified logfile would be great. Unfortunately, emacsclient isn't that sophisticated. editortool --append --open /root/captains-log "tar zxvf /dist/package.tar.gz" This is a specific case of the general case of executing an arbitrary program specified in /etc/sudoers after each sudo (or admindo) command. Information on logging, in general: http://www.freelabs.com/~whitis/linux/captains-log/ It should be noted that some of these problems were due to the mistaken decision long ago to have the shell handle wildcards instead of handling them in a command line parsing library - which would have been just as easy though it would make the programs slightly larger in those days (no shared libraries). A decision that has been a constant annoyance ever since because things which aren't filenames are butchered unless quoted. With the implementation of many of these changes, sudo could be a invaluable tool rather than one which is usually used for the wrong reasons (illusion of security and illusion of logging).