sudoedit vs rvim

Recently I inherited some systems running Chef client, with a script that has to be called via sudo to edit some root owned Chef provisioned config files (e.g. munin.conf)..

/etc/sudoers contents looked like this

%sudoers hostname=(root) NOPASSWD: /usr/bin/chef-man-provision

and it actually executed rvim

rvim -u /root/.rvimrc /etc/munin/munin.conf

Contents of /root/.rvimrc look like this

" all following options are for securing vi for chef-man-provision script. 
" Security option: disable file opening with `:r` command
cmap r <Nop>
cmap o <Nop>

This «security option» had a pretty nasty effect… We couldn’t use characters «r» and «o» in vi command mode, even in simple search strings

Enter sudoedit! To quote the sudoedit(8) manpage

-e‘ The -e (edit) option indicates that, instead of running a command, the user wishes to edit one or more files. In lieu of a command, the string «sudoedit» is used when consulting the security policy. If the user is authorized by the policy, the following steps are taken:

1. Temporary copies are made of the files to be edited with the owner set to the invoking user.

2. The editor specified by the policy is run to edit the temporary files. The sudoers policy uses the SUDO_EDITOR, VISUAL and EDITOR environment variables (in that order). If none of SUDO_EDITOR, VISUAL or EDITOR are set, the first program listed in the editor sudoers(5) option is used.

3. If they have been modified, the temporary files are copied back to their original location and the temporary versions are removed.

If the specified file does not exist, it will be created. Note that unlike most commands run by sudo, the editor is run with the invoking user’s environment unmodified. If, for some reason, sudo is unable to update a file with its edited version, the user will receive a warning and the edited copy will remain in a temporary file.

So, /etc/sudoers was modified to look like this

%sudoers hostname=(root) NOPASSWD: sudoedit /etc/munin/munin.conf

We now type «sudoedit /etc/munin/munin.conf» and everything works as it should work in the first place, i.e. securely and we can use all the letters!