From: Todd C. Miller Date: Sat, 1 Apr 2000 21:23:28 +0000 (+0000) Subject: Visudo now checks for the existence of an editor and gives a sensible X-Git-Tag: SUDO_1_6_4~290 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=6dd2d9592ef9c8a824fc35f6e82d07d5b20edb0a;p=sudo Visudo now checks for the existence of an editor and gives a sensible error if it does not exist. The path to the editor for visudo is now a colon-separated list of allowable editors. If the user has $EDITOR set and it matches one of the allowed editors that editor will be used. If not, the first editor in the list that actually exists is used. --- diff --git a/CHANGES b/CHANGES index 9d56f2113..e494e9776 100644 --- a/CHANGES +++ b/CHANGES @@ -1297,3 +1297,11 @@ Sudo 1.6.2 released. not being used correctly and the entry was being applied globally. Sudo 1.6.3 released. + +409) Visudo now checks for the existence of an editor and gives a sensible + error if it does not exist. + +410) The path to the editor for visudo is now a colon-separated list of + allowable editors. If the user has $EDITOR set and it matches + one of the allowed editors that editor will be used. If not, + the first editor that actually exists is used. diff --git a/INSTALL b/INSTALL index ac64197e2..5dfb5e5b8 100644 --- a/INSTALL +++ b/INSTALL @@ -413,15 +413,20 @@ The following options are also configurable at runtime: Don't print the lecture the first time a user runs sudo. --with-editor=path - Specify the default editor used by visudo (and the only editor used - unless --with-env-editor is specified). The default is the path - to vi on your system. + Specify the default editor path for use by visudo. This may be + a single pathname or a colon-separated list of editors. In + the latter case, visudo will choose the editor that matches + the user's USER environment variable or the first editor in + the list that exists. The default is the path to vi on your system. --with-env-editor Makes visudo consult the EDITOR and VISUAL environment variables before - falling back on the default editor. Note that this may create a - security hole as most editors allow a user to get a shell (which would - be a root shell and hence, no logging). + falling back on the default editor list (as specified by --with-editor). + Note that this may create a security hole as it allows the user to + run any arbitrary command as root without logging. A safer alternative + is to use a colon-separated list of editors with the --with-env-editor + option. visudo will then only use the EDITOR or VISUAL if they match + a value specified via --with-editor. --disable-authentication By default, sudo requires the user to authenticate via a diff --git a/Makefile.in b/Makefile.in index 87779ec8f..fd03d1853 100644 --- a/Makefile.in +++ b/Makefile.in @@ -131,7 +131,7 @@ SUDOBJS = check.o getspwuid.o goodpath.o fileops.o find_path.o interfaces.o \ logging.o parse.o sudo.o sudo_setenv.o tgetpass.o \ $(AUTH_OBJS) $(PARSEOBJS) -VISUDOBJS = visudo.o fileops.o $(PARSEOBJS) +VISUDOBJS = visudo.o fileops.o goodpath.o find_path.o $(PARSEOBJS) TESTOBJS = interfaces.o testsudoers.o $(PARSEOBJS) @@ -253,7 +253,7 @@ sia.o: $(authdir)/sia.c $(AUTHDEP) sudo.man.in: $(srcdir)/sudo.pod @rm -f $(srcdir)/$@ - (cd $(srcdir); pod2man --section=`echo @MANSECTSU@|tr A-Z a-z` --release=$(VERSION) --center="MAINTENANCE COMMANDS" sudo.pod > $(srcdir)/$@) + ( cd $(srcdir); pod2man --section=`echo @MANSECTSU@|tr A-Z a-z` --release=$(VERSION) --center="MAINTENANCE COMMANDS" sudo.pod > $@ ) sudo.man: sudo.man.in CONFIG_FILES=$@ CONFIG_HEADERS= sh ./config.status @@ -262,7 +262,7 @@ sudo.cat: sudo.man visudo.man.in: $(srcdir)/visudo.pod @rm -f $(srcdir)/$@ - (cd $(srcdir); pod2man --section=`echo @MANSECTSU@|tr A-Z a-z` --release=$(VERSION) --center="MAINTENANCE COMMANDS" visudo.pod > $(srcdir)/$@) + ( cd $(srcdir); pod2man --section=`echo @MANSECTSU@|tr A-Z a-z` --release=$(VERSION) --center="MAINTENANCE COMMANDS" visudo.pod > $@ ) visudo.man: visudo.man.in CONFIG_FILES=$@ CONFIG_HEADERS= sh ./config.status @@ -271,7 +271,7 @@ visudo.cat: visudo.man sudoers.man.in: $(srcdir)/sudoers.pod @rm -f $(srcdir)/$@ - (cd $(srcdir); pod2man --section=`echo @MANSECTFORM@|tr A-Z a-z` --release=$(VERSION) --center="FILE FORMATS" sudoers.pod | sed 's/"\\f(CW""\\fR"/\\f(CW""\\fR/' > $(srcdir)/$@) + ( cd $(srcdir); pod2man --section=`echo @MANSECTFORM@|tr A-Z a-z` --release=$(VERSION) --center="FILE FORMATS" sudoers.pod | sed 's/"\\f(CW""\\fR"/\\f(CW""\\fR/' > $@ ) sudoers.man:: sudoers.man.in CONFIG_FILES=$@ CONFIG_HEADERS= sh ./config.status diff --git a/sudoers.cat b/sudoers.cat index 97df8c6ec..ed0d9987a 100644 --- a/sudoers.cat +++ b/sudoers.cat @@ -61,7 +61,7 @@ DDDDEEEESSSSCCCCRRRRIIIIPPPPTTTTIIIIOOOONNNN -26/Mar/2000 1.6.3 1 +1/Apr/2000 1.6.3 1 @@ -127,7 +127,7 @@ sudoers(4) FILE FORMATS sudoers(4) -26/Mar/2000 1.6.3 2 +1/Apr/2000 1.6.3 2 @@ -193,7 +193,7 @@ sudoers(4) FILE FORMATS sudoers(4) -26/Mar/2000 1.6.3 3 +1/Apr/2000 1.6.3 3 @@ -259,7 +259,7 @@ sudoers(4) FILE FORMATS sudoers(4) -26/Mar/2000 1.6.3 4 +1/Apr/2000 1.6.3 4 @@ -325,7 +325,7 @@ sudoers(4) FILE FORMATS sudoers(4) -26/Mar/2000 1.6.3 5 +1/Apr/2000 1.6.3 5 @@ -382,16 +382,16 @@ sudoers(4) FILE FORMATS sudoers(4) password. This flag is off by default. env_editor If set, vvvviiiissssuuuuddddoooo will use the value of the - EDITOR or VISUAL environment falling back on - the default editor. Note that this may create - a security hole as most editors allow a user - to get a shell (which would be a root shell - and not be logged). + EDITOR or VISUAL environment variables before + falling back on the default editor list. Note + that this may create a security hole as it + allows the user to run any arbitrary command + as root without logging. A safer alternative + is to place a colon-separated list of editors - -26/Mar/2000 1.6.3 6 +1/Apr/2000 1.6.3 6 @@ -400,18 +400,25 @@ sudoers(4) FILE FORMATS sudoers(4) sudoers(4) FILE FORMATS sudoers(4) + in the editor variable. vvvviiiissssuuuuddddoooo will then only + use the EDITOR or VISUAL if they match a value + specified in editor. This flag is off by + default. + rootpw If set, ssssuuuuddddoooo will prompt for the root password instead of the password of the invoking user. + This flag is off by default. runaspw If set, ssssuuuuddddoooo will prompt for the password of the user defined by the _r_u_n_a_s___d_e_f_a_u_l_t option (defaults to root) instead of the password of - the invoking user. + the invoking user. This flag is off by + default. targetpw If set, ssssuuuuddddoooo will prompt for the password of the user specified by the -u flag (defaults to root) instead of the password of the invoking - user. + user. This flag is off by default. set_logname Normally, ssssuuuuddddoooo will set the LOGNAME and USER environment variables to the name of the @@ -427,7 +434,8 @@ sudoers(4) FILE FORMATS sudoers(4) If set, ssssuuuuddddoooo will apply the defaults specified for the target user's login class if one exists. Only available if ssssuuuuddddoooo is configured - with the --with-logincap option. + with the --with-logincap option. This flag is + off by default. IIIInnnntttteeeeggggeeeerrrrssss: @@ -445,19 +453,11 @@ sudoers(4) FILE FORMATS sudoers(4) log. The default is 80 (use 0 or negate to disable word wrap). - timestamp_timeout - Number of minutes that can elapse before ssssuuuuddddoooo - will ask for a passwd again. The default is - 5, set this to 0 to always prompt for a - password. - passwd_timeout - Number of minutes before the ssssuuuuddddoooo password - prompt times out. The default is 5, set this -26/Mar/2000 1.6.3 7 +1/Apr/2000 1.6.3 7 @@ -466,6 +466,15 @@ sudoers(4) FILE FORMATS sudoers(4) sudoers(4) FILE FORMATS sudoers(4) + timestamp_timeout + Number of minutes that can elapse before ssssuuuuddddoooo + will ask for a passwd again. The default is + 5, set this to 0 to always prompt for a + password. + + passwd_timeout + Number of minutes before the ssssuuuuddddoooo password + prompt times out. The default is 5, set this to 0 for no password timeout. umask Umask to use when running the root command. @@ -509,29 +518,34 @@ sudoers(4) FILE FORMATS sudoers(4) Syslog priority to use when user authenticates unsuccessfully. Defaults to "alert". - editor Path to the editor to be used by vvvviiiissssuuuuddddoooo. The - default is the path to vi on your system. + editor A colon (':') separated list of editors + allowed to be used with vvvviiiissssuuuuddddoooo. vvvviiiissssuuuuddddoooo will - SSSSttttrrrriiiinnnnggggssss tttthhhhaaaatttt ccccaaaannnn bbbbeeee uuuusssseeeedddd iiiinnnn aaaa bbbboooooooolllleeeeaaaannnn ccccoooonnnntttteeeexxxxtttt: - logfile Path to the ssssuuuuddddoooo log file (not the syslog log - file). Setting a path turns on logging to a - file, negating this option turns it off. - syslog Syslog facility if syslog is being used for - logging (negate to disable syslog logging). +1/Apr/2000 1.6.3 8 -26/Mar/2000 1.6.3 8 +sudoers(4) FILE FORMATS sudoers(4) + choose the editor that matches the user's USER + environment variable if possible, or the first + editor in the list that exists and is + executable. The default is the path to vi on + your system. -sudoers(4) FILE FORMATS sudoers(4) + SSSSttttrrrriiiinnnnggggssss tttthhhhaaaatttt ccccaaaannnn bbbbeeee uuuusssseeeedddd iiiinnnn aaaa bbbboooooooolllleeeeaaaannnn ccccoooonnnntttteeeexxxxtttt: + logfile Path to the ssssuuuuddddoooo log file (not the syslog log + file). Setting a path turns on logging to a + file, negating this option turns it off. + syslog Syslog facility if syslog is being used for + logging (negate to disable syslog logging). Defaults to "local2". mailerpath Path to mail program used to send warning @@ -572,31 +586,30 @@ sudoers(4) FILE FORMATS sudoers(4) never The user need never enter a password to use the B<-v> flag. - always The user must always enter a password to use - the B<-v> flag. - The default value is `all'. - listpw This option controls when a password will be - required when a user runs ssssuuuuddddoooo with the ----llll. - It has the following possible values: - all All the user's I entries for the - current host must have the C - flag set to avoid entering a password. +1/Apr/2000 1.6.3 9 -26/Mar/2000 1.6.3 9 - +sudoers(4) FILE FORMATS sudoers(4) + always The user must always enter a password to use + the B<-v> flag. + The default value is `all'. -sudoers(4) FILE FORMATS sudoers(4) + listpw This option controls when a password will be + required when a user runs ssssuuuuddddoooo with the ----llll. + It has the following possible values: + all All the user's I entries for the + current host must have the C + flag set to avoid entering a password. any At least one of the user's I entries for the current host must have the @@ -639,6 +652,18 @@ sudoers(4) FILE FORMATS sudoers(4) Let's break that down into its constituent parts: + + + +1/Apr/2000 1.6.3 10 + + + + + +sudoers(4) FILE FORMATS sudoers(4) + + RRRRuuuunnnnaaaassss____SSSSppppeeeecccc A Runas_Spec is simply a Runas_List (as defined above) @@ -653,17 +678,6 @@ sudoers(4) FILE FORMATS sudoers(4) The user ddddggggbbbb may run _/_b_i_n_/_l_s, _/_b_i_n_/_k_i_l_l, and _/_u_s_r_/_b_i_n_/_l_p_r_m -- but only as ooooppppeeeerrrraaaattttoooorrrr. Eg. - - -26/Mar/2000 1.6.3 10 - - - - - -sudoers(4) FILE FORMATS sudoers(4) - - sudo -u operator /bin/ls. It is also possible to override a Runas_Spec later on in @@ -704,31 +718,30 @@ sudoers(4) FILE FORMATS sudoers(4) pertain to the current host. This behavior may be overridden via the verifypw and listpw options. - WWWWiiiillllddddccccaaaarrrrddddssss ((((aaaakkkkaaaa mmmmeeeettttaaaa cccchhhhaaaarrrraaaacccctttteeeerrrrssss)))):::: - - ssssuuuuddddoooo allows shell-style _w_i_l_d_c_a_r_d_s to be used in pathnames - as well as command line arguments in the _s_u_d_o_e_r_s file. - Wildcard matching is done via the PPPPOOOOSSSSIIIIXXXX fnmatch(3) - routine. Note that these are _n_o_t regular expressions. - * Matches any set of zero or more characters. - ? Matches any single character. - [...] Matches any character in the specified range. +1/Apr/2000 1.6.3 11 -26/Mar/2000 1.6.3 11 +sudoers(4) FILE FORMATS sudoers(4) + WWWWiiiillllddddccccaaaarrrrddddssss ((((aaaakkkkaaaa mmmmeeeettttaaaa cccchhhhaaaarrrraaaacccctttteeeerrrrssss)))):::: + ssssuuuuddddoooo allows shell-style _w_i_l_d_c_a_r_d_s to be used in pathnames + as well as command line arguments in the _s_u_d_o_e_r_s file. + Wildcard matching is done via the PPPPOOOOSSSSIIIIXXXX fnmatch(3) + routine. Note that these are _n_o_t regular expressions. + * Matches any set of zero or more characters. -sudoers(4) FILE FORMATS sudoers(4) + ? Matches any single character. + [...] Matches any character in the specified range. [!...] Matches any character nnnnooootttt in the specified range. @@ -771,6 +784,18 @@ sudoers(4) FILE FORMATS sudoers(4) dangerous since in a command context, it allows the user to run aaaannnnyyyy command on the system. + + + +1/Apr/2000 1.6.3 12 + + + + + +sudoers(4) FILE FORMATS sudoers(4) + + An exclamation point ('!') can be used as a logical _n_o_t operator both in an _a_l_i_a_s and in front of a Cmnd. This allows one to exclude certain values. Note, however, that @@ -785,17 +810,6 @@ sudoers(4) FILE FORMATS sudoers(4) syntactic characters in a _U_s_e_r _S_p_e_c_i_f_i_c_a_t_i_o_n ('=', ':', '(', ')') is optional. - - -26/Mar/2000 1.6.3 12 - - - - - -sudoers(4) FILE FORMATS sudoers(4) - - The following characters must be escaped with a backslash ('\') when used as part of a word (eg. a username or hostname): '@', '!', '=', ':', ',', '(', ')', '\'. @@ -836,6 +850,18 @@ EEEEXXXXAAAAMMMMPPPPLLLLEEEESSSS /usr/local/bin/zsh Cmnd_Alias SU = /usr/bin/su + + + +1/Apr/2000 1.6.3 13 + + + + + +sudoers(4) FILE FORMATS sudoers(4) + + Here we override some of the compiled in default values. We want ssssuuuuddddoooo to log via _s_y_s_l_o_g(3) using the _a_u_t_h facility in all cases. We don't want to subject the full time @@ -851,17 +877,6 @@ EEEEXXXXAAAAMMMMPPPPLLLLEEEESSSS Defaults:millert !authenticate Defaults@SERVERS log_year, logfile=/var/log/sudo.log - - -26/Mar/2000 1.6.3 13 - - - - - -sudoers(4) FILE FORMATS sudoers(4) - - The _U_s_e_r _s_p_e_c_i_f_i_c_a_t_i_o_n is the part that actually determines who may run what. @@ -901,32 +916,32 @@ sudoers(4) FILE FORMATS sudoers(4) /usr/oper/bin/ The ooooppppeeeerrrraaaattttoooorrrr user may run commands limited to simple - maintenance. Here, those are commands related to backups, - killing processes, the printing system, shutting down the - system, and any commands in the directory _/_u_s_r_/_o_p_e_r_/_b_i_n_/. - joe ALL = /usr/bin/su operator - The user jjjjooooeeee may only _s_u(1) to operator. - pete HPPA = /usr/bin/passwd [A-z]*, !/usr/bin/passwd root +1/Apr/2000 1.6.3 14 - The user ppppeeeetttteeee is allowed to change anyone's password - except for root on the _H_P_P_A machines. Note that this - assumes _p_a_s_s_w_d(1) does not take multiple usernames on the - command line. -26/Mar/2000 1.6.3 14 +sudoers(4) FILE FORMATS sudoers(4) + maintenance. Here, those are commands related to backups, + killing processes, the printing system, shutting down the + system, and any commands in the directory _/_u_s_r_/_o_p_e_r_/_b_i_n_/. + joe ALL = /usr/bin/su operator + The user jjjjooooeeee may only _s_u(1) to operator. -sudoers(4) FILE FORMATS sudoers(4) + pete HPPA = /usr/bin/passwd [A-z]*, !/usr/bin/passwd root + The user ppppeeeetttteeee is allowed to change anyone's password + except for root on the _H_P_P_A machines. Note that this + assumes _p_a_s_s_w_d(1) does not take multiple usernames on the + command line. bob SPARC = (OP) ALL : SGI = (OP) ALL @@ -968,32 +983,31 @@ sudoers(4) FILE FORMATS sudoers(4) any commands in the directory /usr/bin/ except for those commands belonging to the _S_U and _S_H_E_L_L_S Cmnd_Aliases. - steve CSNETS = (operator) /usr/local/op_commands/ - The user sssstttteeeevvvveeee may run any command in the directory - /usr/local/op_commands/ but only as user operator. - matt valkyrie = KILL - - On his personal workstation, valkyrie, mmmmaaaatttttttt needs to be - able to kill hung processes. +1/Apr/2000 1.6.3 15 - WEBMASTERS www = (www) ALL, (root) /usr/bin/su www - On the host www, any user in the _W_E_B_M_A_S_T_E_R_S User_Alias - (will, wendy, and wim), may run any command as user www -26/Mar/2000 1.6.3 15 +sudoers(4) FILE FORMATS sudoers(4) + steve CSNETS = (operator) /usr/local/op_commands/ + The user sssstttteeeevvvveeee may run any command in the directory + /usr/local/op_commands/ but only as user operator. + matt valkyrie = KILL -sudoers(4) FILE FORMATS sudoers(4) + On his personal workstation, valkyrie, mmmmaaaatttttttt needs to be + able to kill hung processes. + WEBMASTERS www = (www) ALL, (root) /usr/bin/su www + On the host www, any user in the _W_E_B_M_A_S_T_E_R_S User_Alias + (will, wendy, and wim), may run any command as user www (which owns the web pages) or simply _s_u(1) to www. ALL CDROM = NOPASSWD: /sbin/umount /CDROM,\ @@ -1033,6 +1047,19 @@ CCCCAAAAVVVVEEEEAAAATTTTSSSS hostname be fully qualified as returned by the hostname command or use the _f_q_d_n option in _s_u_d_o_e_r_s. + + + + +1/Apr/2000 1.6.3 16 + + + + + +sudoers(4) FILE FORMATS sudoers(4) + + FFFFIIIILLLLEEEESSSS /etc/sudoers List of who can run what /etc/group Local groups file @@ -1051,7 +1078,46 @@ SSSSEEEEEEEE AAAALLLLSSSSOOOO -26/Mar/2000 1.6.3 16 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +1/Apr/2000 1.6.3 17 @@ -1117,6 +1183,6 @@ sudoers(4) FILE FORMATS sudoers(4) -26/Mar/2000 1.6.3 17 +1/Apr/2000 1.6.3 18 diff --git a/sudoers.man.in b/sudoers.man.in index 85b359607..31d58c67c 100644 --- a/sudoers.man.in +++ b/sudoers.man.in @@ -2,8 +2,14 @@ ''' $RCSfile$$Revision$$Date$ ''' ''' $Log$ -''' Revision 1.5 2000/03/27 03:26:23 millert -''' Use @mansectsu@ and @mansectform@ in the man page bodies as well. +''' Revision 1.6 2000/04/01 21:23:28 millert +''' Visudo now checks for the existence of an editor and gives a sensible +''' error if it does not exist. +''' +''' The path to the editor for visudo is now a colon-separated list of +''' allowable editors. If the user has $EDITOR set and it matches +''' one of the allowed editors that editor will be used. If not, +''' the first editor in the list that actually exists is used. ''' ''' .de Sh @@ -96,7 +102,7 @@ .nr % 0 .rr F .\} -.TH sudoers @mansectform@ "1.6.3" "26/Mar/2000" "FILE FORMATS" +.TH sudoers @mansectform@ "1.6.3" "1/Apr/2000" "FILE FORMATS" .UC .if n .hy 0 .if n .na @@ -469,21 +475,25 @@ of echo when there is no tty present, some sites may with to set this flag to prevent a user from entering a visible password. This flag is off by default. .Ip "env_editor" 12 -If set, \fBvisudo\fR will use the value of the \s-1EDITOR\s0 or \s-1VISUAL\s0 environment -falling back on the default editor. Note that this may create a -security hole as most editors allow a user to get a shell (which -would be a root shell and not be logged). +If set, \fBvisudo\fR will use the value of the \s-1EDITOR\s0 or \s-1VISUAL\s0 +environment variables before falling back on the default editor list. +Note that this may create a security hole as it allows the user to +run any arbitrary command as root without logging. A safer alternative +is to place a colon-separated list of editors in the \f(CWeditor\fR +variable. \fBvisudo\fR will then only use the \s-1EDITOR\s0 or \s-1VISUAL\s0 if +they match a value specified in \f(CWeditor\fR. This flag is off by +default. .Ip "rootpw" 12 If set, \fBsudo\fR will prompt for the root password instead of the password -of the invoking user. +of the invoking user. This flag is off by default. .Ip "runaspw" 12 If set, \fBsudo\fR will prompt for the password of the user defined by the \fIrunas_default\fR option (defaults to root) instead of the password -of the invoking user. +of the invoking user. This flag is off by default. .Ip "targetpw" 12 If set, \fBsudo\fR will prompt for the password of the user specified by the \f(CW-u\fR flag (defaults to root) instead of the password of the -invoking user. +invoking user. This flag is off by default. .Ip "set_logname" 12 Normally, \fBsudo\fR will set the \f(CWLOGNAME\fR and \f(CWUSER\fR environment variables to the name of the target user (usually root unless the \f(CW-u\fR flag is given). @@ -493,7 +503,7 @@ to change this behavior. This can be done by negating the set_logname option. .Ip "use_loginclass" 12 If set, \fBsudo\fR will apply the defaults specified for the target user's login class if one exists. Only available if \fBsudo\fR is configured with -the --with-logincap option. +the --with-logincap option. This flag is off by default. .PP \fBIntegers\fR: .Ip "passwd_tries" 12 @@ -542,8 +552,11 @@ Defaults to \*(L"notice\*(R". Syslog priority to use when user authenticates unsuccessfully. Defaults to \*(L"alert\*(R". .Ip "editor" 12 -Path to the editor to be used by \fBvisudo\fR. The default is the path -to vi on your system. +A colon (':') separated list of editors allowed to be used with +\fBvisudo\fR. \fBvisudo\fR will choose the editor that matches the user's +\s-1USER\s0 environment variable if possible, or the first editor in the +list that exists and is executable. The default is the path to vi +on your system. .PP \fBStrings that can be used in a boolean context\fR: .Ip "logfile" 12 diff --git a/sudoers.pod b/sudoers.pod index ee354c8f7..7862243a8 100644 --- a/sudoers.pod +++ b/sudoers.pod @@ -352,27 +352,31 @@ flag is off by default. =item env_editor -If set, B will use the value of the EDITOR or VISUAL environment -falling back on the default editor. Note that this may create a -security hole as most editors allow a user to get a shell (which -would be a root shell and not be logged). +If set, B will use the value of the EDITOR or VISUAL +environment variables before falling back on the default editor list. +Note that this may create a security hole as it allows the user to +run any arbitrary command as root without logging. A safer alternative +is to place a colon-separated list of editors in the C +variable. B will then only use the EDITOR or VISUAL if +they match a value specified in C. This flag is off by +default. =item rootpw If set, B will prompt for the root password instead of the password -of the invoking user. +of the invoking user. This flag is off by default. =item runaspw If set, B will prompt for the password of the user defined by the I option (defaults to root) instead of the password -of the invoking user. +of the invoking user. This flag is off by default. =item targetpw If set, B will prompt for the password of the user specified by the C<-u> flag (defaults to root) instead of the password of the -invoking user. +invoking user. This flag is off by default. =item set_logname @@ -386,7 +390,7 @@ to change this behavior. This can be done by negating the set_logname option. If set, B will apply the defaults specified for the target user's login class if one exists. Only available if B is configured with -the --with-logincap option. +the --with-logincap option. This flag is off by default. =back @@ -473,8 +477,11 @@ Defaults to "alert". =item editor -Path to the editor to be used by B. The default is the path -to vi on your system. +A colon (':') separated list of editors allowed to be used with +B. B will choose the editor that matches the user's +USER environment variable if possible, or the first editor in the +list that exists and is executable. The default is the path to vi +on your system. =back 12 diff --git a/visudo.c b/visudo.c index 30575cdbf..3dc8b0e45 100644 --- a/visudo.c +++ b/visudo.c @@ -123,6 +123,8 @@ main(argc, argv) { char buf[MAXPATHLEN*2]; /* buffer used for copying files */ char *Editor; /* editor to use */ + char *UserEditor; /* editor user wants to use */ + char *EditorPath; /* colon-separated list of editors */ int sudoers_fd; /* sudoers file descriptor */ int stmp_fd; /* stmp file descriptor */ int n; /* length parameter */ @@ -225,12 +227,99 @@ main(argc, argv) (void) close(stmp_fd); /* - * If we are allowing EDITOR and VISUAL envariables set Editor - * base on whichever exists... + * Check EDITOR and VISUAL environment variables to see which editor + * the user wants to use (we may not end up using it though). + * If the path is not fully-qualified, make it so and check that + * the specified executable actually exists. */ - if (!def_flag(I_ENV_EDITOR) || - (!(Editor = getenv("EDITOR")) && !(Editor = getenv("VISUAL")))) - Editor = def_str(I_EDITOR); + if ((UserEditor = getenv("EDITOR")) == NULL || *UserEditor == '\0') + UserEditor = getenv("VISUAL"); + if (*UserEditor == '\0') + UserEditor = NULL; + else if (UserEditor) { + if (find_path(UserEditor, &Editor) == FOUND) { + UserEditor = Editor; + } else { + if (def_flag(I_ENV_EDITOR)) { + /* If we are honoring $EDITOR this is a fatal error. */ + (void) fprintf(stderr, + "%s: specified editor (%s) doesn't exist!\n", + Argv[0], UserEditor); + Exit(-1); + } else { + /* Otherwise, just ignore $EDITOR. */ + UserEditor = NULL; + } + } + } + + /* + * See if we can use the user's choice of editors either because + * we allow any $EDITOR or because $EDITOR is in the allowable list. + */ + Editor = NULL; + if (def_flag(I_ENV_EDITOR) && UserEditor) + Editor = UserEditor; + else if (UserEditor) { + struct stat editor_sb; + struct stat user_editor_sb; + char *base, *userbase; + + if (stat(UserEditor, &user_editor_sb) != 0) { + /* Should never happen since we already checked above. */ + (void) fprintf(stderr, "%s: unable to stat editor (%s): %s\n", + Argv[0], UserEditor, strerror(errno)); + Exit(-1); + } + EditorPath = estrdup(def_str(I_EDITOR)); + Editor = strtok(EditorPath, ":"); + do { + /* + * Both Editor and UserEditor should be fully qualified but + * check anyway... + */ + if ((base = strrchr(Editor, '/')) == NULL) + continue; + if ((userbase = strrchr(UserEditor, '/')) == NULL) { + Editor = NULL; + break; + } + base++, userbase++; + + /* + * We compare the basenames first and then use stat to match + * for sure. + */ + if (strcmp(base, userbase) == 0) { + if (stat(Editor, &editor_sb) == 0 && S_ISREG(editor_sb.st_mode) + && (editor_sb.st_mode & 0000111) && + editor_sb.st_dev == user_editor_sb.st_dev && + editor_sb.st_ino == user_editor_sb.st_ino) + break; + } + } while ((Editor = strtok(NULL, ":"))); + free(EditorPath); + } + + /* + * Can't use $EDITOR, try each element of I_EDITOR until we + * find one that exists, is regular, and is executable. + */ + if (Editor == NULL || *Editor == '\0') { + EditorPath = estrdup(def_str(I_EDITOR)); + Editor = strtok(EditorPath, ":"); + do { + if (sudo_goodpath(Editor)) + break; + } while ((Editor = strtok(NULL, ":"))); + + /* Bleah, none of the editors existed! */ + if (Editor == NULL || *Editor == '\0') { + (void) fprintf(stderr, "%s: no editor found (editor path = %s)\n", + Argv[0], def_str(I_EDITOR)); + Exit(-1); + } + } /* * Edit the temp file and parse it (for sanity checking) @@ -433,6 +522,12 @@ set_fqdn() return; } +int +user_is_exempt() +{ + return(TRUE); +} + /* * Assuming a parse error occurred, prompt the user for what they want * to do now. Returns the first letter of their choice.