Add support for "Defaults" line in sudoers to make configuration variables

changable at runtime (and on a global, per-host and per-user basis).
Both the names and the internal representation are still subject to change.
It was necessary to make sudo_user.runas but a char ** instead of a
char * since this value can be changed by a Defaults line.  There is a
similar (but more complicated) issue with sudo_user.prompt but it
is handled differently at the moment.

Add a "-L" flag to list the name of options with their descriptions.  This
may only be temporary.

Move some prototypes to parse.h

Be much less restrictive on what is allowed for a username.
This commit is contained in:
Todd C. Miller
1999-09-08 08:06:28 +00:00
parent 093fbe1e47
commit 13bf42675d
31 changed files with 3114 additions and 1928 deletions

4
BUGS
View File

@@ -11,3 +11,7 @@ Known bugs in sudo version 1.6
given. This is a flaw in GNU autoconf.
4) On DUNIX in sia mode, hitting return at the prompt does not quit.
5) In parse.lex, '@" should not need to be a special character.
For some reason, if it is not excluded from WORD, Defaults@ doesn't
match.

10
INSTALL
View File

@@ -55,6 +55,10 @@ For most systems and configurations it is possible simply to:
site. You will probably want to refer the sample.sudoers
file and sudoers man page included with the sudo package.
8) If you want to use syslogd(8) to do the logging, you'll need
to update your /etc/syslog.conf file. See the sample.syslog.conf
file included in the distribution for an example.
Available configure options
===========================
@@ -208,7 +212,8 @@ Special features/options:
--with-loglen
Number of characters per line for the file log. This is only used if
you are to "file" or "both". This value is used to decide when to wrap
lines for nicer log files. The default is 80.
lines for nicer log files. The default is 80. Setting this to 0
will disable the wrapping.
--with-ignore-dot
If set, sudo will ignore '.' or '' (current dir) in $PATH.
@@ -404,9 +409,6 @@ Special features/options:
--enable-log-host
Log the hostname in the log file.
--disable-log-wrap
Do not wrap long lines in the log file.
--enable-noargs-shell
If sudo is invoked with no arguments it acts as if the "-s" flag had
been given. That is, it runs a shell as root (the shell is determined

View File

@@ -110,26 +110,26 @@ SHELL = /bin/sh
PROGS = @PROGS@
SRCS = alloc.c alloca.c check.c fileops.c find_path.c fnmatch.c getcwd.c \
getspwuid.c goodpath.c interfaces.c lex.yy.c lsearch.c logging.c \
parse.c parse.lex parse.yacc putenv.c snprintf.c strcasecmp.c \
SRCS = alloc.c alloca.c check.c defaults.c fileops.c find_path.c fnmatch.c \
getcwd.c getspwuid.c goodpath.c interfaces.c lex.yy.c lsearch.c \
logging.c parse.c parse.lex parse.yacc putenv.c snprintf.c strcasecmp.c \
strerror.c sudo.c sudo.tab.c sudo_setenv.c testsudoers.c tgetpass.c \
utime.c version.c visudo.c $(AUTH_SRCS)
utime.c visudo.c $(AUTH_SRCS)
AUTH_SRCS = auth/afs.c auth/aix_auth.c auth/dce.c auth/fwtk.c auth/kerb4.c \
auth/kerb5.c auth/pam.c auth/passwd.c auth/rfc1938.c \
auth/secureware.c auth/securid.c auth/sia.c auth/sudo_auth.c
HDRS = compat.h ins_2001.h ins_classic.h ins_csops.h ins_goons.h insults.h \
interfaces.h logging.h parse.h sudo.h sudo.tab.h version.h \
HDRS = compat.h defaults.h ins_2001.h ins_classic.h ins_csops.h ins_goons.h \
insults.h interfaces.h logging.h parse.h sudo.h sudo.tab.h version.h \
auth/sudo_auth.h emul/fnmatch.h emul/search.h emul/utime.h
AUTH_OBJS = sudo_auth.o @AUTH_OBJS@
PARSEOBJS = sudo.tab.o lex.yy.o alloc.o
PARSEOBJS = sudo.tab.o lex.yy.o alloc.o defaults.o
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 version.o \
logging.o parse.o sudo.o sudo_setenv.o tgetpass.o \
$(AUTH_OBJS) $(PARSEOBJS)
VISUDOBJS = visudo.o fileops.o $(PARSEOBJS)
@@ -148,8 +148,8 @@ DISTFILES = $(SRCS) $(HDRS) BUGS CHANGES FAQ HISTORY INSTALL INSTALL.configure \
sudo.man sudo.pod sudoers sudoers.cat sudoers.man sudoers.pod \
visudo.cat visudo.man visudo.pod auth/API
SUDODEP = $(srcdir)/sudo.h $(srcdir)/compat.h $(srcdir)/logging.h \
config.h pathnames.h
SUDODEP = $(srcdir)/sudo.h $(srcdir)/compat.h $(srcdir)/defaults.h \
$(srcdir)/logging.h config.h pathnames.h
AUTHDEP = $(SUDODEP) $(authdir)/sudo_auth.h
@@ -200,13 +200,13 @@ logging.o: logging.c $(SUDODEP)
sudo_setenv.o: sudo_setenv.c $(SUDODEP)
tgetpass.o: tgetpass.c $(SUDODEP)
visudo.o: visudo.c $(SUDODEP) version.h
sudo.o: sudo.c $(SUDODEP) interfaces.h
sudo.o: sudo.c $(SUDODEP) interfaces.h version.h
interfaces.o: interfaces.c $(SUDODEP) interfaces.h
testsudoers.o: testsudoers.c $(SUDODEP) parse.h interfaces.h
parse.o: parse.c $(SUDODEP) parse.h interfaces.h
lex.yy.o: lex.yy.c $(SUDODEP) parse.h sudo.tab.h
sudo.tab.o: sudo.tab.c $(SUDODEP) parse.h
version.o: version.c $(SUDODEP) version.h auth/sudo_auth.h
defaults.o: defaults.c $(SUDODEP) auth/sudo_auth.h
fnmatch.o: fnmatch.c config.h compat.h emul/fnmatch.h
getcwd.o: getcwd.c config.h compat.h
lsearch.o: lsearch.c config.h compat.h emul/search.h

4
TODO
View File

@@ -68,3 +68,7 @@ TODO list (most will be addressed in sudo 2.0)
user.
24) Use strtol() and strtoul(), not atoi()?
25) In parse.yacc get rid on unneeded '{ ; }'
26) Look into %e, %p, %k in parse.lex

20
aclocal.m4 vendored
View File

@@ -304,26 +304,6 @@ AC_MSG_RESULT($sudo_cv_uid_t_len)
AC_DEFINE_UNQUOTED(MAX_UID_T_LEN, $sudo_cv_uid_t_len)
])
dnl
dnl check for facilitynames and prioritynames in syslog.h
dnl 4.4BSD has these but most others do not.
dnl
AC_DEFUN(SUDO_SYSLOG_NAMES,
[AC_MSG_CHECKING(for facilitynames and prioritynames in syslog.h)
AC_CACHE_VAL(sudo_cv_syslog_names,
[
AC_TRY_COMPILE([
#define SYSLOG_NAMES
#include <stdio.h>
#include <syslog.h>
], [ CODE *p=&prioritynames[0]; CODE *f=&facilitynames[0]; ],
sudo_cv_syslog_names=yes, sudo_cv_syslog_names=no)])dnl
AC_MSG_RESULT($sudo_cv_syslog_names)
if test $sudo_cv_syslog_names = yes; then
AC_DEFINE(HAVE_SYSLOG_NAMES)
fi
])
dnl
dnl check for "long long"
dnl XXX hard to cache since it includes 2 tests

View File

@@ -67,7 +67,7 @@ aixauth_verify(pw, prompt, auth)
char *message, *pass;
int reenter = 1;
pass = tgetpass(prompt, PASSWORD_TIMEOUT * 60, 1);
pass = tgetpass(prompt, sudo_inttable[I_PW_TIMEOUT] * 60, 1);
if (authenticate(pw->pw_name, pass, &reenter, &message) == 0)
return(AUTH_SUCCESS);
else

View File

@@ -117,9 +117,9 @@ fwtk_verify(pw, prompt, auth)
/* Get the password/response from the user. */
if (strncmp(resp, "challenge ", 10) == 0) {
(void) snprintf(buf, sizeof(buf), "%s\nResponse: ", &resp[10]);
pass = tgetpass(buf, PASSWORD_TIMEOUT * 60, 0);
pass = tgetpass(buf, sudo_inttable[I_PW_TIMEOUT] * 60, 0);
} else if (strncmp(resp, "password", 8) == 0) {
pass = tgetpass(prompt, PASSWORD_TIMEOUT * 60, 1);
pass = tgetpass(prompt, sudo_inttable[I_PW_TIMEOUT] * 60, 1);
} else {
(void) fprintf(stderr, "%s: %s\n", Argv[0], resp);
return(AUTH_FATAL);

View File

@@ -103,7 +103,7 @@ kerb5_init(pw, promptp, auth)
realm = lrealm;
/* Only rewrite prompt if user didn't specify their own. */
if (!strcmp(prompt, PASSPROMPT))
if (user_prompt == NULL)
easprintf(promptp, "Password for %s@%s: ", pw->pw_name, realm);
return(AUTH_SUCCESS);
}

View File

@@ -143,7 +143,7 @@ sudo_conv(num_msg, msg, response, appdata_ptr)
if (strcmp(p, "Password: ") && strcmp(p, "Password:"))
p = (char *) pm->msg;
pr->resp = estrdup((char *) tgetpass(p,
PASSWORD_TIMEOUT * 60, !echo));
sudo_inttable[I_PW_TIMEOUT] * 60, !echo));
if (*pr->resp == '\0')
nil_pw = 1; /* empty password */
break;

View File

@@ -93,6 +93,9 @@ rfc1938_setup(pw, promptp, auth)
/* Ignore trailing colon (we will add our own) */
if (orig_prompt[op_len - 1] == ':')
op_len--;
else if (op_len >= 2 && orig_prompt[op_len - 1] == ' '
&& orig_prompt[op_len - 2] == ':')
op_len -= 2;
}
#ifdef HAVE_SKEY
@@ -123,11 +126,11 @@ rfc1938_setup(pw, promptp, auth)
new_prompt = (char *) erealloc(new_prompt, np_size);
}
#ifdef LONG_OTP_PROMPT
(void) sprintf(new_prompt, "%s\n%s", challenge, orig_prompt);
#else
(void) sprintf(new_prompt, "%.*s [ %s ]:", op_len, orig_prompt, challenge);
#endif /* LONG_OTP_PROMPT */
if (sudo_flag_set(FL_LONG_OTP_PROMPT))
(void) sprintf(new_prompt, "%s\n%s", challenge, orig_prompt);
else
(void) sprintf(new_prompt, "%.*s [ %s ]:", op_len, orig_prompt,
challenge);
*promptp = new_prompt;
return(AUTH_SUCCESS);

View File

@@ -80,8 +80,8 @@ sudo_collect(timeout, rendition, title, nprompts, prompts)
switch (rendition) {
case SIAFORM:
case SIAONELINER:
if (timeout <= 0 || timeout > PASSWORD_TIMEOUT * 60)
timeout = PASSWORD_TIMEOUT * 60;
if (timeout <= 0 || timeout > sudo_inttable[I_PW_TIMEOUT] * 60)
timeout = sudo_inttable[I_PW_TIMEOUT] * 60;
/*
* Substitute custom prompt if a) the sudo prompt is not "Password:"
* and b) the SIA prompt is "Password:" (so we know it is safe).

View File

@@ -95,9 +95,10 @@ sudo_auth auth_switch[] = {
int nil_pw; /* I hate resorting to globals like this... */
void
verify_user()
verify_user(prompt)
char *prompt;
{
short counter = TRIES_FOR_PASSWORD + 1;
short counter = sudo_inttable[I_PW_TRIES] + 1;
short success = AUTH_FAILURE;
short status;
char *p;
@@ -120,7 +121,7 @@ verify_user()
if (NEEDS_USER(auth))
set_perms(PERM_USER, 0);
status = (auth->init)(sudo_user.pw, &user_prompt, auth);
status = (auth->init)(sudo_user.pw, &prompt, auth);
if (status == AUTH_FAILURE)
auth->flags &= ~FLAG_CONFIGURED;
else if (status == AUTH_FATAL) /* XXX log */
@@ -138,7 +139,7 @@ verify_user()
if (NEEDS_USER(auth))
set_perms(PERM_USER, 0);
status = (auth->setup)(sudo_user.pw, &user_prompt, auth);
status = (auth->setup)(sudo_user.pw, &prompt, auth);
if (status == AUTH_FAILURE)
auth->flags &= ~FLAG_CONFIGURED;
else if (status == AUTH_FATAL) /* XXX log */
@@ -152,9 +153,9 @@ verify_user()
/* Get the password unless the auth function will do it for us */
nil_pw = 0;
#ifdef AUTH_STANDALONE
p = user_prompt;
p = prompt;
#else
p = (char *) tgetpass(user_prompt, PASSWORD_TIMEOUT * 60, 1);
p = (char *) tgetpass(prompt, sudo_inttable[I_PW_TIMEOUT] * 60, 1);
if (!p || *p == '\0')
nil_pw = 1;
#endif /* AUTH_STANDALONE */
@@ -181,7 +182,7 @@ verify_user()
/* Exit loop on nil password, but give it a chance to match first. */
if (nil_pw) {
if (counter == TRIES_FOR_PASSWORD)
if (counter == sudo_inttable[I_PW_TRIES])
exit(1);
else
break;
@@ -211,8 +212,8 @@ cleanup:
return;
case AUTH_FAILURE:
log_error(NO_MAIL, "%d incorrect password attempt%s",
TRIES_FOR_PASSWORD - counter,
(TRIES_FOR_PASSWORD - counter == 1) ? "" : "s");
sudo_inttable[I_PW_TRIES] - counter,
(sudo_inttable[I_PW_TRIES] - counter == 1) ? "" : "s");
case AUTH_FATAL:
exit(1);
}
@@ -226,6 +227,17 @@ pass_warn(fp)
#ifdef USE_INSULTS
(void) fprintf(fp, "%s\n", INSULT);
#else
(void) fprintf(fp, "%s\n", INCORRECT_PASSWORD);
(void) fprintf(fp, "%s\n", sudo_strtable[I_BADPASS_MSG]);
#endif /* USE_INSULTS */
}
void
dump_auth_methods()
{
sudo_auth *auth;
(void) fputs("Authentication methods:", stdout);
for (auth = auth_switch; auth->name; auth++)
(void) printf(" '%s'", auth->name);
(void) putchar('\n');
}

91
check.c
View File

@@ -87,6 +87,7 @@ check_user()
{
char *timestampdir = NULL;
char *timestampfile = NULL;
char *prompt;
int status;
if (user_uid == 0 || user_is_exempt())
@@ -99,9 +100,9 @@ check_user()
lecture(); /* first time through they get a lecture */
/* Expand any escapes in the prompt. */
user_prompt = expand_prompt(user_prompt, user_name, user_shost);
prompt = expand_prompt(user_prompt ? user_prompt : sudo_strtable[I_PASSPROMPT], user_name, user_shost);
verify_user();
verify_user(prompt);
}
if (status != TS_ERROR)
update_timestamp(timestampdir, timestampfile);
@@ -112,20 +113,21 @@ check_user()
/*
* Standard sudo lecture.
* TODO: allow the user to specify a file name instead at compile time.
* TODO: allow the user to specify a file name instead.
*/
static void
lecture()
{
#ifndef NO_LECTURE
(void) fputs("\n\
if (sudo_flag_set(FL_LECTURE)) {
(void) fputs("\n\
We trust you have received the usual lecture from the local System\n\
Administrator. It usually boils down to these two things:\n\
\n\
#1) Respect the privacy of others.\n\
#2) Think before you type.\n\n",
stderr);
#endif /* NO_LECTURE */
}
}
/*
@@ -188,7 +190,7 @@ expand_prompt(old_prompt, user, host)
if (subst) {
new_prompt = (char *) emalloc(len + 1);
for (p = user_prompt, np = new_prompt; *p; p++) {
for (p = old_prompt, np = new_prompt; *p; p++) {
if (lastchar == '%' && (*p == 'h' || *p == 'u' || *p == '%')) {
/* substiture user/host name */
if (*p == 'h') {
@@ -210,7 +212,7 @@ expand_prompt(old_prompt, user, host)
}
*np = '\0';
} else
new_prompt = user_prompt;
new_prompt = old_prompt;
return(new_prompt);
}
@@ -221,11 +223,13 @@ expand_prompt(old_prompt, user, host)
int
user_is_exempt()
{
#ifdef EXEMPTGROUP
struct group *grp;
char **gr_mem;
if (!(grp = getgrnam(EXEMPTGROUP)))
if (!sudo_strtable[I_EXEMPT_GRP])
return(FALSE);
if (!(grp = getgrnam(sudo_strtable[I_EXEMPT_GRP])))
return(FALSE);
if (getgid() == grp->gr_gid)
@@ -235,7 +239,6 @@ user_is_exempt()
if (strcmp(user_name, *gr_mem) == 0)
return(TRUE);
}
#endif
return(FALSE);
}
@@ -248,26 +251,26 @@ build_timestamp(timestampdir, timestampfile)
char **timestampdir;
char **timestampfile;
{
#ifdef USE_TTY_TICKETS
char *p;
char *dirparent = sudo_strtable[I_TIMESTAMPDIR];
if ((p = strrchr(user_tty, '/')))
p++;
else
p = user_tty;
if (sizeof(_PATH_SUDO_TIMEDIR) + strlen(user_name) + strlen(p) + 2 >
MAXPATHLEN)
log_error(0, "timestamp path too long: %s/%s/%s", _PATH_SUDO_TIMEDIR,
user_name, p);
easprintf(timestampdir, "%s/%s", _PATH_SUDO_TIMEDIR, user_name);
easprintf(timestampfile, "%s/%s/%s", _PATH_SUDO_TIMEDIR, user_name, p);
#else
if (sizeof(_PATH_SUDO_TIMEDIR) + strlen(user_name) + 1 > MAXPATHLEN)
log_error(0, "timestamp path too long: %s/%s", _PATH_SUDO_TIMEDIR,
user_name);
easprintf(timestampdir, "%s/%s", _PATH_SUDO_TIMEDIR, user_name);
*timestampfile = NULL;
#endif /* USE_TTY_TICKETS */
if (sudo_flag_set(FL_TTY_TICKETS)) {
char *p;
if ((p = strrchr(user_tty, '/')))
p++;
else
p = user_tty;
if (strlen(dirparent) + strlen(user_name) + strlen(p) + 3 > MAXPATHLEN)
log_error(0, "timestamp path too long: %s/%s/%s", dirparent,
user_name, p);
easprintf(timestampdir, "%s/%s", dirparent, user_name);
easprintf(timestampfile, "%s/%s/%s", dirparent, user_name, p);
} else {
if (strlen(dirparent) + strlen(user_name) + 2 > MAXPATHLEN)
log_error(0, "timestamp path too long: %s/%s", dirparent, user_name);
easprintf(timestampdir, "%s/%s", dirparent, user_name);
*timestampfile = NULL;
}
}
/*
@@ -282,39 +285,40 @@ timestamp_status(timestampdir, timestampfile, user, make_dirs)
{
struct stat sb;
time_t now;
char *dirparent = sudo_strtable[I_TIMESTAMPDIR];
int status = TS_ERROR; /* assume the worst */
/*
* Sanity check _PATH_SUDO_TIMEDIR and make it if it doesn't already exist.
* Sanity check dirparent and make it if it doesn't already exist.
* We start out assuming the worst (that the dir is not sane) and
* if it is ok upgrade the status to ``no timestamp file''.
* Note that we don't check the parent(s) of _PATH_SUDO_TIMEDIR for
* Note that we don't check the parent(s) of dirparent for
* sanity since the sudo dir is often just located in /tmp.
*/
if (lstat(_PATH_SUDO_TIMEDIR, &sb) == 0) {
if (lstat(dirparent, &sb) == 0) {
if (!S_ISDIR(sb.st_mode))
log_error(NO_EXIT, "%s exists but is not a directory (0%o)",
_PATH_SUDO_TIMEDIR, sb.st_mode);
dirparent, sb.st_mode);
else if (sb.st_uid != 0)
log_error(NO_EXIT, "%s owned by uid %ld, should be owned by root",
_PATH_SUDO_TIMEDIR, (long) sb.st_uid);
dirparent, (long) sb.st_uid);
else if ((sb.st_mode & 0000022))
log_error(NO_EXIT,
"%s writable by non-owner (0%o), should be mode 0700",
_PATH_SUDO_TIMEDIR, sb.st_mode);
dirparent, sb.st_mode);
else {
if ((sb.st_mode & 0000777) != 0700)
(void) chmod(_PATH_SUDO_TIMEDIR, 0700);
(void) chmod(dirparent, 0700);
status = TS_MISSING;
}
} else if (errno != ENOENT) {
log_error(NO_EXIT|USE_ERRNO, "can't stat %s", _PATH_SUDO_TIMEDIR);
log_error(NO_EXIT|USE_ERRNO, "can't stat %s", dirparent);
} else {
/* No _PATH_SUDO_TIMEDIR, try to make one. */
/* No dirparent, try to make one. */
if (make_dirs) {
if (mkdir(_PATH_SUDO_TIMEDIR, S_IRWXU))
if (mkdir(dirparent, S_IRWXU))
log_error(NO_EXIT|USE_ERRNO, "can't mkdir %s",
_PATH_SUDO_TIMEDIR);
dirparent);
else
status = TS_MISSING;
}
@@ -408,12 +412,13 @@ timestamp_status(timestampdir, timestampfile, user, make_dirs)
*/
if (status == TS_OLD) {
now = time(NULL);
if (TIMEOUT && now - sb.st_mtime < 60 * TIMEOUT) {
if (sudo_inttable[I_TS_TIMEOUT] &&
now - sb.st_mtime < 60 * sudo_inttable[I_TS_TIMEOUT]) {
/*
* Check for bogus time on the stampfile. The clock may
* have been set back or someone could be trying to spoof us.
*/
if (sb.st_mtime > now + 60 * TIMEOUT * 2) {
if (sb.st_mtime > now + 60 * sudo_inttable[I_TS_TIMEOUT] * 2) {
log_error(NO_EXIT,
"timestamp too far in the future: %20.20s",
4 + ctime(&sb.st_mtime));

View File

@@ -397,9 +397,6 @@
/* Define if you want the hostname to be entered into the log file */
#undef HOST_IN_LOG
/* Define if you want the log file line to be wrapped */
#undef WRAP_LOG
/* Define to be the number of minutes before sudo asks for passwd again. */
#undef TIMEOUT
@@ -454,9 +451,6 @@
/* Define to be the max chars per log line (for line wrapping). */
#undef MAXLOGFILELEN
/* Define if your syslog.h has the prioritynames and facilitynames tables. */
#undef HAVE_SYSLOG_NAMES
/* Define if you want to ignore '.' and '' in $PATH */
#undef IGNORE_DOT_PATH

817
configure vendored

File diff suppressed because it is too large Load Diff

View File

@@ -932,24 +932,6 @@ AC_ARG_ENABLE(log-host,
esac
], AC_MSG_RESULT(no))
AC_MSG_CHECKING(whether to wrap long lines in the log file)
AC_ARG_ENABLE(log-wrap,
[ --disable-log-wrap Do not wrap long lines in the log file],
[ case "$enableval" in
yes) AC_MSG_RESULT(yes)
AC_DEFINE(WRAP_LOG)
;;
no) AC_MSG_RESULT(no)
;;
*) AC_MSG_RESULT(yes)
AC_DEFINE(WRAP_LOG)
echo "Ignoring unknown argument to --enable-log-wrap: $enableval"
;;
esac
], AC_MSG_RESULT(yes)
AC_DEFINE(WRAP_LOG)
)
AC_MSG_CHECKING(whether to invoke a shell if sudo is given no arguments)
AC_ARG_ENABLE(noargs-shell,
[ --enable-noargs-shell If sudo is given no arguments run a shell],
@@ -1470,11 +1452,6 @@ if test "$with_DCE" = "yes" -o "$ac_cv_prog_YACC" = "bison -y"; then
AC_FUNC_ALLOCA
fi
dnl
dnl Check to see if the facility and priority names live in syslog.h
dnl
SUDO_SYSLOG_NAMES
dnl
dnl Kerberos 5
dnl

613
defaults.c Normal file
View File

@@ -0,0 +1,613 @@
/*
* Copyright (c) 1996, 1998, 1999 Todd C. Miller <Todd.Miller@courtesan.com>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* 4. Products derived from this software may not be called "Sudo" nor
* may "Sudo" appear in their names without specific prior written
* permission from the author.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
* AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
* THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "config.h"
#include <stdio.h>
#ifdef STDC_HEADERS
#include <stdlib.h>
#endif /* STDC_HEADERS */
#ifdef HAVE_UNISTD_H
#include <unistd.h>
#endif /* HAVE_UNISTD_H */
#ifdef HAVE_STRING_H
#include <string.h>
#endif /* HAVE_STRING_H */
#ifdef HAVE_STRINGS_H
#include <strings.h>
#endif /* HAVE_STRINGS_H */
#include <sys/types.h>
#include <sys/param.h>
#include "sudo.h"
#ifndef lint
static const char rcsid[] = "$Sudo$";
#endif /* lint */
/*
* For converting between syslog numbers and strings.
*/
struct strmap {
char *name;
int num;
};
static struct strmap facilities[] = {
#ifdef LOG_AUTHPRIV
{ "authpriv", LOG_AUTHPRIV },
#endif
{ "auth", LOG_AUTH },
{ "daemon", LOG_DAEMON },
{ "user", LOG_USER },
{ "local0", LOG_LOCAL0 },
{ "local1", LOG_LOCAL1 },
{ "local2", LOG_LOCAL2 },
{ "local3", LOG_LOCAL3 },
{ "local4", LOG_LOCAL4 },
{ "local5", LOG_LOCAL5 },
{ "local6", LOG_LOCAL6 },
{ "local7", LOG_LOCAL7 },
{ NULL, -1 }
};
static struct strmap priorities[] = {
{ "alert", LOG_ALERT },
{ "crit", LOG_CRIT },
{ "debug", LOG_DEBUG },
{ "emerg", LOG_EMERG },
{ "err", LOG_ERR },
{ "info", LOG_INFO },
{ "notice", LOG_NOTICE },
{ "warning", LOG_WARNING },
{ NULL, -1 }
};
/*
* Local prototypes.
*/
static int store_int __P((char *, int, int));
static int store_str __P((char *, int, int));
static int store_syslogfac __P((char *, int, int));
static int store_syslogpri __P((char *, int, int));
static int store_umask __P((char *, int, int));
static char *num_to_name __P((int, struct strmap *));
/*
* Structure describing compile-time and run-time options.
* Index for T_INT starts at one since index 0 is for flags.
* XXX - syslog things should be strings (and !facility should turn off)
* XXX - some of these names are pretty lame.
*/
struct sudo_defs_types {
char *name;
unsigned int type;
unsigned int index;
int (*store) __P((char *, int, int));
char *desc;
} sudo_defs_table[] = {
{
"long_otp_prompt", T_FLAG, FL_LONG_OTP_PROMPT, NULL,
"Put OTP prompt on its own line"
}, {
"ignore_dot", T_FLAG, FL_IGNORE_DOT, NULL,
"Ignore '.' in $PATH"
}, {
"mail_if_no_user", T_FLAG, FL_MAIL_IF_NOUSER, NULL,
"Send mail if the user is not in sudoers"
}, {
"mail_if_no_host", T_FLAG, FL_MAIL_IF_NOHOST, NULL,
"Send mail if the user is not in sudoers for this host"
}, {
"mail_if_no_perms", T_FLAG, FL_MAIL_IF_NOPERMS, NULL,
"Send mail if the user is not allowed to run a command"
}, {
"tty_tickets", T_FLAG, FL_TTY_TICKETS, NULL,
"Use a separate timestamp for each user/tty combo"
}, {
"lecture", T_FLAG, FL_LECTURE, NULL,
"Lecture user the first time they run sudo"
}, {
"authenticate", T_FLAG, FL_AUTHENTICATE, NULL,
"Require users to authenticate by default"
}, {
"root_sudo", T_FLAG, FL_ROOT_SUDO, NULL,
"Root may run sudo"
}, {
"log_host", T_FLAG, FL_LOG_HOST, NULL,
"Log the hostname in the (non-syslog) log file"
}, {
"shell_noargs", T_FLAG, FL_SHELL_NOARGS, NULL,
"If sudo is invoked with no arguments, start a shell"
}, {
"set_home", T_FLAG, FL_SET_HOME, NULL,
"Set $HOME to the target user when starting a shell with -s"
}, {
"path_info", T_FLAG, FL_PATH_INFO, NULL,
"Allow some information gathering to give useful error messages"
}, {
"fqdn", T_FLAG, FL_FQDN, NULL,
"Require fully-qualified hsotnames in the sudoers file"
}, {
"insults", T_FLAG, FL_INSULTS, NULL,
"Insult the user when they enter an incorrect password"
}, {
"syslog", T_INT|T_BOOL, I_LOGFAC, store_syslogfac,
"Syslog facility: %s"
}, {
"syslog_goodpri", T_INT, I_GOODPRI, store_syslogpri,
"Syslog priority to use when user authenticates successfully: %s"
}, {
"syslog_badpri", T_INT, I_BADPRI, store_syslogpri,
"Syslog priority to use when user authenticates unsuccessfully: %s"
}, {
"loglinelen", T_INT, I_LOGLEN, store_int,
"Number of length at which to wrap log file lines (0 for no wrap): %d"
}, {
"timestamp_timeout", T_INT, I_TS_TIMEOUT, store_int,
"Authentication timestamp timeout: %d minutes"
}, {
"passwd_timeout", T_INT, I_PW_TIMEOUT, store_int,
"Password prompt timeout: %d minutes"
}, {
"passwd_tries", T_INT, I_PW_TRIES, store_int,
"Number of tries to enter a password: %d"
}, {
"umask", T_INT|T_BOOL, I_UMASK, store_umask,
"Umask to use or 0777 to use user's: 0%o"
}, {
"logfile", T_STR, I_LOGFILE, store_str,
"Path to log file: %s"
}, {
"mailerpath", T_STR, I_MAILERPATH, store_str,
"Path to mail program: %s"
}, {
"mailerflags", T_STR, I_MAILERARGS, store_str,
"Flags for mail program: %s"
}, {
"alertmail", T_STR, I_ALERTMAIL, store_str,
"Address to send mail to: %s"
}, {
"mailsub", T_STR, I_MAILSUB, store_str,
"Subject line for mail messages: %s"
}, {
"badpass_message", T_STR, I_BADPASS_MSG, store_str,
"Incorrect password message: %s"
}, {
"timestampdir", T_STR, I_TIMESTAMPDIR, store_str,
"Path to authentication timestamp dir: %s"
}, {
"exempt_group", T_STR, I_EXEMPT_GRP, store_str,
"Users in this group are exempt from password and PATH requirements: %s"
}, {
"passprompt", T_STR, I_PASSPROMPT, store_str,
"Default password prompt: %s"
}, {
"runas_default", T_STR, I_RUNAS_DEF, store_str,
"Default user to run commands as: %s"
}, {
"secure_path", T_STR, I_SECURE_PATH, store_str,
"Override user's $PATH with: %s"
}, {
NULL, 0, 0, NULL, NULL
}
};
unsigned int sudo_inttable[SUDO_INTTABLE_LAST];
char *sudo_strtable[SUDO_STRTABLE_LAST];
/*
* Print version and configure info.
*/
void
dump_defaults()
{
struct sudo_defs_types *cur;
for (cur = sudo_defs_table; cur->name; cur++) {
switch (cur->type & T_MASK) {
case T_FLAG:
if ((sudo_inttable[I_FLAGS]) & (cur->index))
puts(cur->desc);
break;
case T_STR:
if (sudo_strtable[cur->index]) {
(void) printf(cur->desc, sudo_strtable[cur->index]);
putchar('\n');
}
break;
case T_INT:
if (cur->index == I_LOGFAC)
(void) printf(cur->desc,
num_to_name(sudo_inttable[cur->index], facilities));
else if (cur->index == I_GOODPRI || cur->index == I_BADPRI)
(void) printf(cur->desc,
num_to_name(sudo_inttable[cur->index], priorities));
else
(void) printf(cur->desc, sudo_inttable[cur->index]);
putchar('\n');
break;
}
}
#ifdef ENV_EDITOR
(void) printf("Default editor for visudo: %s\n", EDITOR);
#else
(void) printf("Editor for visudo: %s\n", EDITOR);
#endif
}
/*
* List each option along with its description.
*/
void
list_options()
{
struct sudo_defs_types *cur;
char *p;
(void) puts("Available options in a sudoers ``Defaults'' line:\n");
for (cur = sudo_defs_table; cur->name; cur++) {
switch (cur->type & T_MASK) {
case T_FLAG:
(void) printf("%s: %s\n", cur->name, cur->desc);
break;
case T_STR:
case T_INT:
p = strrchr(cur->desc, ':');
if (p)
(void) printf("%s: %.*s\n", cur->name, p - cur->desc,
cur->desc);
else
(void) printf("%s: %s\n", cur->name, cur->desc);
break;
}
}
}
/*
* Convert a syslog number to a name.
*/
static char *
num_to_name(num, table)
int num;
struct strmap *table;
{
struct strmap *t;
for (t = table; t->name; t++)
if (t->num == num)
return(t->name);
return("disabled");
}
/*
* Sets/clears an entry in the defaults structure
* If a variable that takes a value is used in a boolean
* context with op == 0, disable that variable.
* Eg. you may want to turn off logging to a file for some hosts.
* This is only meaningful for variables that are *optional*.
*/
int
set_default(var, val, op)
char *var;
char *val;
int op; /* TRUE or FALSE */
{
struct sudo_defs_types *cur;
extern int sudolineno;
for (cur = sudo_defs_table; cur->name; cur++) {
if (strcmp(var, cur->name) == 0)
break;
}
if (!cur->name) {
(void) fprintf(stderr,
"%s: unknown defaults entry `%s' referenced near line %d\n", Argv[0],
var, sudolineno);
return(FALSE);
}
switch (cur->type & T_MASK) {
case T_STR:
if (!val) {
/* Check for bogus boolean usage or lack of a value. */
if (!(cur->type & T_BOOL) || op != FALSE) {
(void) fprintf(stderr,
"%s: no value specified for `%s' on line %d\n", Argv[0],
var, sudolineno);
return(FALSE);
}
}
if (!cur->store(val, cur->index, op)) {
(void) fprintf(stderr,
"%s: value '%s' is invalid for option '%s'\n", Argv[0],
val, var);
return(FALSE);
}
break;
case T_INT:
if (!val) {
/* Check for bogus boolean usage or lack of a value. */
if (!(cur->type & T_BOOL) || op != FALSE) {
(void) fprintf(stderr,
"%s: no value specified for `%s' on line %d\n", Argv[0],
var, sudolineno);
return(FALSE);
}
}
if (!cur->store(val, cur->index, op)) {
(void) fprintf(stderr,
"%s: value '%s' is invalid for option '%s'\n", Argv[0],
val, var);
return(FALSE);
}
break;
case T_FLAG:
if (val) {
(void) fprintf(stderr,
"%s: option `%s' does not take a value on line %d\n",
Argv[0], var, sudolineno);
return(FALSE);
}
if (op == TRUE)
sudo_inttable[0] |= cur->index;
else
sudo_inttable[0] &= ~(cur->index);
break;
}
return(TRUE);
}
/*
* Set default options to compiled-in values.
* Any of these may be overridden at runtime by a "Defaults" file.
*/
void
init_defaults()
{
static int firsttime = 1;
int i;
/* Free any strings that were set. */
if (!firsttime) {
for (i = 0; i < SUDO_STRTABLE_LAST; i++)
if (sudo_strtable[i])
free(sudo_strtable[i]);
}
memset(sudo_strtable, 0, sizeof(sudo_strtable));
memset(sudo_inttable, 0, sizeof(sudo_inttable));
/* First initialize the flags. */
#ifdef LONG_OTP_PROMPT
sudo_inttable[I_FLAGS] |= FL_LONG_OTP_PROMPT;
#endif
#ifdef IGNORE_DOT_PATH
sudo_inttable[I_FLAGS] |= FL_IGNORE_DOT;
#endif
#ifdef ALWAYS_SEND_MAIL
sudo_inttable[I_FLAGS] |= FL_MAIL_ALWAYS;
#endif
#ifdef SEND_MAIL_WHEN_NO_USER
sudo_inttable[I_FLAGS] |= FL_MAIL_IF_NOUSER;
#endif
#ifdef SEND_MAIL_WHEN_NO_HOST
sudo_inttable[I_FLAGS] |= FL_MAIL_IF_NOHOST;
#endif
#ifdef SEND_MAIL_WHEN_NOT_OK
sudo_inttable[I_FLAGS] |= FL_MAIL_IF_NOPERMS;
#endif
#ifdef USE_TTY_TICKETS
sudo_inttable[I_FLAGS] |= FL_TTY_TICKETS;
#endif
#ifndef NO_LECTURE
sudo_inttable[I_FLAGS] |= FL_LECTURE;
#endif
#ifndef NO_AUTHENTICATION
sudo_inttable[I_FLAGS] |= FL_AUTHENTICATE;
#endif
#ifndef NO_ROOT_SUDO
sudo_inttable[I_FLAGS] |= FL_ROOT_SUDO;
#endif
#ifdef HOST_IN_LOG
sudo_inttable[I_FLAGS] |= FL_LOG_HOST;
#endif
#ifdef SHELL_IF_NO_ARGS
sudo_inttable[I_FLAGS] |= FL_SHELL_NOARGS;
#endif
#ifdef SHELL_SETS_HOME
sudo_inttable[I_FLAGS] |= FL_SET_HOME;
#endif
#ifndef DONT_LEAK_PATH_INFO
sudo_inttable[I_FLAGS] |= FL_PATH_INFO;
#endif
#ifdef FQDN
sudo_inttable[I_FLAGS] |= FL_FQDN;
#endif
#ifdef USE_INSULTS
sudo_inttable[I_FLAGS] |= FL_INSULTS;
#endif
/* Then initialize the ints. */
#if (LOGGING & SLOG_SYSLOG)
sudo_inttable[I_LOGFAC] = LOGFAC;
sudo_inttable[I_GOODPRI] = PRI_SUCCESS;
sudo_inttable[I_BADPRI] = PRI_FAILURE;
#else
sudo_inttable[I_LOGFAC] = (unsigned int)-1;
#endif
#ifdef SUDO_UMASK
sudo_inttable[I_UMASK] = SUDO_UMASK;
#else
sudo_inttable[I_UMASK] = 0777;
#endif
sudo_inttable[I_LOGLEN] = MAXLOGFILELEN;
sudo_inttable[I_TS_TIMEOUT] = TIMEOUT;
sudo_inttable[I_PW_TIMEOUT] = PASSWORD_TIMEOUT;
sudo_inttable[I_PW_TRIES] = TRIES_FOR_PASSWORD;
/* Finally do the strings */
sudo_strtable[I_ALERTMAIL] = estrdup(ALERTMAIL);
sudo_strtable[I_MAILSUB] = estrdup(MAILSUBJECT);
sudo_strtable[I_BADPASS_MSG] = estrdup(INCORRECT_PASSWORD);
sudo_strtable[I_TIMESTAMPDIR] = estrdup(_PATH_SUDO_TIMEDIR);
sudo_strtable[I_PASSPROMPT] = estrdup(PASSPROMPT);
sudo_strtable[I_RUNAS_DEF] = estrdup(RUNAS_DEFAULT);
#ifdef _PATH_SENDMAIL
sudo_strtable[I_MAILERPATH] = estrdup(_PATH_SENDMAIL);
#endif
#if (LOGGING & SLOG_FILE)
sudo_strtable[I_LOGFILE] = estrdup(_PATH_SUDO_LOGFILE);
#endif
#ifdef EXEMPTGROUP
sudo_strtable[I_EXEMPT_GRP] = estrdup(EXEMPTGROUP);
#endif
#ifdef SECURE_PATH
sudo_strtable[I_SECURE_PATH] = estrdup(SECURE_PATH);
#endif
#if 0
/* XXX - implement */
sudo_strtable[I_MAILERARGS] = estrdup(XXX);
#endif
/*
* The following depend on the above values.
* We use a pointer to the string so that if its
* value changes we get the change.
*/
if (user_runas == NULL)
user_runas = &sudo_strtable[I_RUNAS_DEF];
firsttime = 0;
}
static int
store_int(val, index, op)
char *val;
int index;
int op;
{
char *endp;
unsigned long ul;
if (op == FALSE) {
sudo_inttable[index] = 0;
} else {
ul = strtoul(val, &endp, 10);
if (*endp != '\0')
return(FALSE);
/* XXX - should check against UINT_MAX */
sudo_inttable[index] = (unsigned int)ul;
}
return(TRUE);
}
static int
store_str(val, index, op)
char *val;
int index;
int op;
{
if (sudo_strtable[index])
free(sudo_strtable[index]);
if (op == FALSE)
sudo_strtable[index] = NULL;
else
sudo_strtable[index] = estrdup(val);
return(TRUE);
}
static int
store_syslogfac(val, index, op)
char *val;
int index;
int op;
{
struct strmap *fac;
if (op == FALSE) {
sudo_inttable[index] = (unsigned int)-1;
return(TRUE);
}
for (fac = facilities; fac->name && strcmp(val, fac->name); fac++)
;
if (fac->name == NULL)
return(FALSE);
sudo_inttable[index] = fac->num;
return(TRUE);
}
static int
store_syslogpri(val, index, op)
char *val;
int index;
int op;
{
struct strmap *pri;
if (op == FALSE)
return(FALSE);
for (pri = priorities; pri->name && strcmp(val, pri->name); pri++)
;
if (pri->name == NULL)
return(FALSE);
sudo_inttable[index] = pri->num;
return(TRUE);
}
static int
store_umask(val, index, op)
char *val;
int index;
int op;
{
char *endp;
unsigned long ul;
if (op == FALSE) {
sudo_inttable[index] = 0777;
} else {
ul = strtoul(val, &endp, 8);
if (*endp != '\0' || ul >= 0777)
return(FALSE);
sudo_inttable[index] = (mode_t)ul;
}
return(TRUE);
}

117
defaults.h Normal file
View File

@@ -0,0 +1,117 @@
/*
* Copyright (c) 1999 Todd C. Miller <Todd.Miller@courtesan.com>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* 4. Products derived from this software may not be called "Sudo" nor
* may "Sudo" appear in their names without specific prior written
* permission from the author.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
* AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
* THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* $Sudo$
*/
#ifndef _SUDO_DEFAULTS_H
#define _SUDO_DEFAULTS_H
/*
* Four types of defaults: strings, integers, booleans, and flags.
* Note that flags have their value in the index field.
* Also, T_INT or T_STR may be ANDed with T_BOOL to indicate that
* a value is not required.
*/
#define T_INT 0x01
#define T_STR 0x02
#define T_FLAG 0x08
#define T_MASK 0x0F
#define T_BOOL 0x10
/*
* Flag values
*/
#define FL_LONG_OTP_PROMPT 0x00001
#define FL_IGNORE_DOT 0x00002
#define FL_MAIL_ALWAYS 0x00004
#define FL_MAIL_IF_NOUSER 0x00008
#define FL_MAIL_IF_NOHOST 0x00010
#define FL_MAIL_IF_NOPERMS 0x00020
#define FL_TTY_TICKETS 0x00040
#define FL_LECTURE 0x00080
#define FL_AUTHENTICATE 0x00100
#define FL_ROOT_SUDO 0x00200
#define FL_LOG_HOST 0x00400
#define FL_SHELL_NOARGS 0x00800
#define FL_SET_HOME 0x01000
#define FL_PATH_INFO 0x02000
#define FL_FQDN 0x04000
#define FL_INSULTS 0x08000
#define FL_MAX 0xFFFFF
/*
* Indexes into sudo_inttable
*/
#define I_FLAGS 0 /* various flags, as listed above */
#define I_LOGFAC 1 /* syslog facility */
#define I_GOODPRI 2 /* syslog priority for successful auth */
#define I_BADPRI 3 /* syslog priority for unsuccessful auth */
#define I_LOGLEN 4 /* wrap log file line after N chars */
#define I_TS_TIMEOUT 5 /* timestamp stale after N minutes */
#define I_PW_TIMEOUT 6 /* exit if pass not entered in N minutes */
#define I_PW_TRIES 7 /* exit after N bad password tries */
#define I_UMASK 8 /* umask to use or 0777 to use user's */
/*
* Indexes into sudo_strtable
*/
#define I_LOGFILE 0 /* path to logfile (or NULL for none) */
#define I_MAILERPATH 1 /* path to sendmail or other mailer */
#define I_MAILERARGS 2 /* flags to pass to the mailer */
#define I_ALERTMAIL 3 /* who to send bitch mail to */
#define I_MAILSUB 4 /* subject line of mail msg */
#define I_BADPASS_MSG 5 /* what to say when passwd is wrong */
#define I_TIMESTAMPDIR 6 /* path to timestamp dir */
#define I_EXEMPT_GRP 7 /* no password or PATH override for these */
#define I_PASSPROMPT 8 /* password prompt */
#define I_RUNAS_DEF 9 /* default user to run commands as */
#define I_SECURE_PATH 10 /* set $PATH to this if not NULL */
#define SUDO_INTTABLE_LAST 9
#define SUDO_STRTABLE_LAST 11
#define sudo_flag_set(_f) (sudo_inttable[I_FLAGS] & (_f))
extern unsigned int sudo_inttable[SUDO_INTTABLE_LAST];
extern char *sudo_strtable[SUDO_STRTABLE_LAST];
/*
* Prototypes
*/
void dump_default __P((void));
int set_default __P((char *, char *, int));
void init_defaults __P((void));
void list_options __P((void));
#endif /* _SUDO_DEFAULTS_H */

View File

@@ -72,7 +72,7 @@ static const char rcsid[] = "$Sudo$";
* stores it in a statically allocated array, filling in a pointer
* to the array. Returns FOUND if the command was found, NOT_FOUND
* if it was not found, or NOT_FOUND_DOT if it would have been found
* but it is in '.' and IGNORE_DOT_PATH is in effect.
* but it is in '.' and FL_IGNORE_DOT is set.
*/
int
find_path(infile, outfile)
@@ -105,9 +105,12 @@ find_path(infile, outfile)
}
/*
* Grab PATH out of environment and make a local copy
* Grab PATH out of the environment (or from the string table
* if SECURE_PATH is in effect) and make a local copy.
*/
if ((path = getenv("PATH")) == NULL)
if (sudo_strtable[I_SECURE_PATH])
path = sudo_strtable[I_SECURE_PATH];
else if ((path = getenv("PATH")) == NULL)
return(NOT_FOUND);
path = estrdup(path);
origpath = path;
@@ -147,10 +150,8 @@ find_path(infile, outfile)
*/
if (!result && checkdot) {
result = sudo_goodpath(infile);
#ifdef IGNORE_DOT_PATH
if (result)
if (result && sudo_flag_set(FL_IGNORE_DOT))
return(NOT_FOUND_DOT);
#endif /* IGNORE_DOT_PATH */
}
if (result) {

1568
lex.yy.c

File diff suppressed because it is too large Load Diff

213
logging.c
View File

@@ -62,19 +62,14 @@
static const char rcsid[] = "$Sudo$";
#endif /* lint */
#if (LOGGING & SLOG_SYSLOG)
static void do_syslog __P((int, char *));
#endif
#if (LOGGING & SLOG_FILE)
static void do_logfile __P((char *));
#endif
static void send_mail __P((char *));
static void mail_auth __P((int, char *));
#if (LOGGING & SLOG_SYSLOG)
# ifdef BROKEN_SYSLOG
# define MAXSYSLOGTRIES 16 /* num of retries for broken syslogs */
# define SYSLOG syslog_wrapper
#ifdef BROKEN_SYSLOG
# define MAXSYSLOGTRIES 16 /* num of retries for broken syslogs */
# define SYSLOG syslog_wrapper
static void syslog_wrapper __P((int, char *, char *, char *));
@@ -95,9 +90,9 @@ syslog_wrapper(pri, fmt, ap)
if (vsyslog(pri, fmt, ap) == 0)
break;
}
# else
# define SYSLOG syslog
# endif /* BROKEN_SYSLOG */
#else
# define SYSLOG syslog
#endif /* BROKEN_SYSLOG */
/*
* Log a message to syslog, pre-pending the username and splitting the
@@ -149,9 +144,7 @@ do_syslog(pri, msg)
}
}
}
#endif /* LOGGING & SLOG_SYSLOG */
#if (LOGGING & SLOG_FILE)
static void
do_logfile(msg)
char *msg;
@@ -161,96 +154,94 @@ do_logfile(msg)
FILE *fp;
mode_t oldmask;
time_t now;
int maxlen = MAXLOGFILELEN;
int maxlen = sudo_inttable[I_LOGLEN];
now = time((time_t) 0);
oldmask = umask(077);
fp = fopen(_PATH_SUDO_LOGFILE, "a");
fp = fopen(sudo_strtable[I_LOGFILE], "a");
(void) umask(oldmask);
if (fp == NULL) {
easprintf(&full_line, "Can't open log file: %s: %s",
_PATH_SUDO_LOGFILE, strerror(errno));
sudo_strtable[I_LOGFILE], strerror(errno));
send_mail(full_line);
free(full_line);
} else if (!lock_file(fileno(fp), SUDO_LOCK)) {
easprintf(&full_line, "Can't lock log file: %s: %s",
_PATH_SUDO_LOGFILE, strerror(errno));
sudo_strtable[I_LOGFILE], strerror(errno));
send_mail(full_line);
free(full_line);
} else {
# ifndef WRAP_LOG
# ifdef HOST_IN_LOG
(void) fprintf(fp, "%15.15s : %s : HOST=%s : %s\n", ctime(&now) + 4,
user_name, user_shost, msg);
# else
(void) fprintf(fp, "%15.15s : %s : %s\n", ctime(&now) + 4, user_name,
msg);
# endif
# else
# ifdef HOST_IN_LOG
easprintf(&full_line, "%15.15s : %s : HOST=%s : %s",
ctime(&now) + 4, user_name, user_shost, msg);
# else
easprintf(&full_line, "%15.15s : %s : %s", ctime(&now) + 4,
user_name, msg);
# endif
if (sudo_inttable[I_LOGLEN] == 0) {
/* Don't pretty-print long log file lines (hard to grep) */
if (sudo_flag_set(FL_LOG_HOST))
(void) fprintf(fp, "%15.15s : %s : HOST=%s : %s\n",
ctime(&now) + 4, user_name, user_shost, msg);
else
(void) fprintf(fp, "%15.15s : %s : %s\n", ctime(&now) + 4,
user_name, msg);
} else {
if (sudo_flag_set(FL_LOG_HOST))
easprintf(&full_line, "%15.15s : %s : HOST=%s : %s",
ctime(&now) + 4, user_name, user_shost, msg);
else
easprintf(&full_line, "%15.15s : %s : %s", ctime(&now) + 4,
user_name, msg);
/*
* Print out full_line with word wrap
*/
beg = end = full_line;
while (beg) {
oldend = end;
end = strchr(oldend, ' ');
/*
* Print out full_line with word wrap
*/
beg = end = full_line;
while (beg) {
oldend = end;
end = strchr(oldend, ' ');
if (maxlen > 0 && end) {
*end = '\0';
if (strlen(beg) > maxlen) {
/* too far, need to back up & print the line */
if (maxlen > 0 && end) {
*end = '\0';
if (strlen(beg) > maxlen) {
/* too far, need to back up & print the line */
if (beg == (char *)full_line)
maxlen -= 4; /* don't indent first line */
if (beg == (char *)full_line)
maxlen -= 4; /* don't indent first line */
*end = ' ';
if (oldend != beg) {
/* rewind & print */
end = oldend-1;
while (*end == ' ')
--end;
*(++end) = '\0';
(void) fprintf(fp, "%s\n ", beg);
*end = ' ';
if (oldend != beg) {
/* rewind & print */
end = oldend-1;
while (*end == ' ')
--end;
*(++end) = '\0';
(void) fprintf(fp, "%s\n ", beg);
*end = ' ';
} else {
(void) fprintf(fp, "%s\n ", beg);
}
/* reset beg to point to the start of the new substr */
beg = end;
while (*beg == ' ')
++beg;
} else {
(void) fprintf(fp, "%s\n ", beg);
/* we still have room */
*end = ' ';
}
/* reset beg to point to the start of the new substring */
beg = end;
while (*beg == ' ')
++beg;
/* remove leading whitespace */
while (*end == ' ')
++end;
} else {
/* we still have room */
*end = ' ';
/* final line */
(void) fprintf(fp, "%s\n", beg);
beg = NULL; /* exit condition */
}
/* remove leading whitespace */
while (*end == ' ')
++end;
} else {
/* final line */
(void) fprintf(fp, "%s\n", beg);
beg = NULL; /* exit condition */
}
free(full_line);
}
free(full_line);
# endif
(void) fflush(fp);
(void) lock_file(fileno(fp), SUDO_UNLOCK);
(void) fclose(fp);
}
}
#endif /* LOGGING & SLOG_FILE */
/*
* Two main functions, log_error() to log errors and log_auth() to
@@ -263,14 +254,12 @@ log_auth(status, inform_user)
{
char *message;
char *logline;
#if (LOGGING & SLOG_SYSLOG)
int pri;
if (status & VALIDATE_OK)
pri = PRI_SUCCESS;
else
pri = PRI_FAILURE;
#endif /* LOGGING & SLOG_SYSLOG */
/* Set error message, if any. */
if (status & VALIDATE_OK)
@@ -285,7 +274,7 @@ log_auth(status, inform_user)
message = "unknown error ; ";
easprintf(&logline, "%sTTY=%s ; PWD=%s ; USER=%s ; COMMAND=%s%s%s",
message, user_tty, user_cwd, user_runas, user_cmnd,
message, user_tty, user_cwd, *user_runas, user_cmnd,
user_args ? " " : "", user_args ? user_args : "");
mail_auth(status, logline); /* send mail based on status */
@@ -305,18 +294,16 @@ log_auth(status, inform_user)
(void) fprintf(stderr,
"Sorry, user %s is not allowed to execute '%s%s%s' as %s on %s.\n",
user_name, user_cmnd, user_args ? " " : "",
user_args ? user_args : "", user_runas, user_host);
user_args ? user_args : "", *user_runas, user_host);
}
/*
* Log via syslog and/or a file.
*/
#if (LOGGING & SLOG_SYSLOG)
do_syslog(pri, logline);
#endif
#if (LOGGING & SLOG_FILE)
do_logfile(logline);
#endif
if (sudo_inttable[I_LOGFAC] != (unsigned int)-1)
do_syslog(pri, logline);
if (sudo_strtable[I_LOGFILE])
do_logfile(logline);
free(logline);
}
@@ -358,22 +345,22 @@ log_error(va_alist)
if (user_args) {
easprintf(&logline,
"%s: %s ; TTY=%s ; PWD=%s ; USER=%s ; COMMAND=%s %s",
message, strerror(serrno), user_tty, user_cwd, user_runas,
message, strerror(serrno), user_tty, user_cwd, *user_runas,
user_cmnd, user_args);
} else {
easprintf(&logline,
"%s: %s ; TTY=%s ; PWD=%s ; USER=%s ; COMMAND=%s", message,
strerror(serrno), user_tty, user_cwd, user_runas, user_cmnd);
strerror(serrno), user_tty, user_cwd, *user_runas, user_cmnd);
}
} else {
if (user_args) {
easprintf(&logline,
"%s ; TTY=%s ; PWD=%s ; USER=%s ; COMMAND=%s %s", message,
user_tty, user_cwd, user_runas, user_cmnd, user_args);
user_tty, user_cwd, *user_runas, user_cmnd, user_args);
} else {
easprintf(&logline,
"%s ; TTY=%s ; PWD=%s ; USER=%s ; COMMAND=%s", message,
user_tty, user_cwd, user_runas, user_cmnd);
user_tty, user_cwd, *user_runas, user_cmnd);
}
}
@@ -394,12 +381,10 @@ log_error(va_alist)
/*
* Log to syslog and/or a file.
*/
#if (LOGGING & SLOG_SYSLOG)
do_syslog(PRI_FAILURE, logline);
#endif
#if (LOGGING & SLOG_FILE)
do_logfile(logline);
#endif
if (sudo_inttable[I_LOGFAC] != (unsigned int)-1)
do_syslog(PRI_FAILURE, logline);
if (sudo_strtable[I_LOGFILE])
do_logfile(logline);
free(logline);
if (message != logline);
@@ -409,7 +394,6 @@ log_error(va_alist)
/*
* Send a message to ALERTMAIL
*/
#ifdef _PATH_SENDMAIL
static void
send_mail(line)
char *line;
@@ -419,6 +403,10 @@ send_mail(line)
int pfd[2], pid;
time_t now;
/* Just return if mailer is disabled. */
if (!sudo_strtable[I_MAILERPATH])
return;
if ((pid = fork()) > 0) { /* Child. */
/* We do an explicit wait() later on... */
@@ -456,9 +444,9 @@ send_mail(line)
(void) close(pfd[0]);
/* Pipes are all setup, send message via sendmail. */
(void) fprintf(mail, "To: %s\nFrom: %s\nSubject: ", ALERTMAIL,
user_name);
for (p = MAILSUBJECT; *p; p++) {
(void) fprintf(mail, "To: %s\nFrom: %s\nSubject: ",
sudo_strtable[I_ALERTMAIL], user_name);
for (p = sudo_strtable[I_MAILSUB]; *p; p++) {
/* Expand escapes in the subject */
if (*p == '%' && *(p+1) != '%') {
switch (*(++p)) {
@@ -491,14 +479,6 @@ send_mail(line)
}
}
}
#else
static void
send_mail(line)
char *line;
{
return;
}
#endif
/*
* Send mail based on the value of "status" and compile-time options.
@@ -511,19 +491,18 @@ mail_auth(status, line)
int mail_mask;
/* If any of these bits are set in status, we send mail. */
mail_mask = VALIDATE_ERROR;
#ifdef SEND_MAIL_WHEN_OK
mail_mask |= VALIDATE_OK;
#endif
#ifdef SEND_MAIL_WHEN_NO_USER
mail_mask |= FLAG_NO_USER;
#endif
#ifdef SEND_MAIL_WHEN_NO_HOST
mail_mask |= FLAG_NO_HOST;
#endif
#ifdef SEND_MAIL_WHEN_NOT_OK
mail_mask |= VALIDATE_NOT_OK;
#endif
if (sudo_flag_set(FL_MAIL_ALWAYS))
mail_mask =
VALIDATE_ERROR|VALIDATE_OK|FLAG_NO_USER|FLAG_NO_HOST|VALIDATE_NOT_OK;
else {
mail_mask = VALIDATE_ERROR;
if (sudo_flag_set(FL_MAIL_IF_NOUSER))
mail_mask |= FLAG_NO_USER;
if (sudo_flag_set(FL_MAIL_IF_NOHOST))
mail_mask |= FLAG_NO_HOST;
if (sudo_flag_set(FL_MAIL_IF_NOPERMS))
mail_mask |= VALIDATE_NOT_OK;
}
if ((status & mail_mask) != 0)
send_mail(line);

View File

@@ -104,4 +104,12 @@ struct generic_alias {
extern struct matchstack *match;
extern int top;
/*
* Prototypes
*/
int addr_matches __P((char *));
int command_matches __P((char *, char *, char *, char *));
int netgr_matches __P((char *, char *, char *));
int usergr_matches __P((char *, char *));
#endif /* _SUDO_PARSE_H */

126
parse.lex
View File

@@ -93,7 +93,7 @@ extern void yyerror __P((char *));
OCTET (1?[0-9]{1,2})|(2[0-4][0-9])|(25[0-5])
DOTTEDQUAD {OCTET}(\.{OCTET}){3}
HOSTNAME [[:alnum:]_-]+
USERNAME [^:,\) \t\n]+
WORD [^@!=:,\(\) \t\n\\]+
%e 4000
%p 6000
@@ -101,6 +101,7 @@ USERNAME [^:,\) \t\n]+
%s GOTCMND
%s GOTRUNAS
%s GOTDEFS
%%
[ \t]+ { /* throw away space/tabs */
@@ -113,12 +114,26 @@ USERNAME [^:,\) \t\n]+
LEXTRACE("\n\t");
} /* throw away EOL after \ */
<GOTCMND>\\[:\,=\\ \t] {
<GOTCMND>\\[@:\,=\\ \t] {
LEXTRACE("QUOTEDCHAR ");
fill_args(yytext + 1, 1, sawspace);
sawspace = FALSE;
}
<GOTDEFS>\"[^\"]+\" {
/* XXX - should allow " to be quoted */
LEXTRACE("WORD(1) ");
fill(yytext + 1, yyleng - 2);
return(WORD);
}
<GOTDEFS>(#.*)?\n {
BEGIN INITIAL;
++sudolineno;
LEXTRACE("\n");
return(COMMENT);
}
<GOTCMND>[:\,=\n] {
BEGIN INITIAL;
unput(*yytext);
@@ -175,15 +190,17 @@ PASSWD[[:blank:]]*: {
return(PASSWD);
}
\+{USERNAME} {
\+{WORD} {
/* netgroup */
fill(yytext, yyleng);
LEXTRACE("NETGROUP ");
return(NETGROUP);
}
\%{USERNAME} {
\%{WORD} {
/* UN*X group */
fill(yytext, yyleng);
LEXTRACE("GROUP ");
return(USERGROUP);
}
@@ -223,15 +240,71 @@ PASSWD[[:blank:]]*: {
}
}
<GOTRUNAS>#?{USERNAME} {
<GOTRUNAS>#?{WORD} {
/* username/uid that user can run command as */
fill(yytext, yyleng);
LEXTRACE("NAME ");
return(NAME);
LEXTRACE("WORD(2) ");
return(WORD);
}
<GOTRUNAS>\) BEGIN INITIAL;
<GOTRUNAS>\) {
BEGIN INITIAL;
}
[[:upper:]][[:upper:][:digit:]_]* {
if (strcmp(yytext, "ALL") == 0) {
LEXTRACE("ALL ");
return(ALL);
} else {
fill(yytext, yyleng);
LEXTRACE("ALIAS ");
return(ALIAS);
}
}
<GOTDEFS>[^ \t\n,=!]+ {
/* XXX - should allow [!=,] to be quoted */
LEXTRACE("WORD(3) ");
fill(yytext, yyleng);
return(WORD);
}
<INITIAL>^Defaults[:@]? {
BEGIN GOTDEFS;
if (yyleng == 9) {
switch (yytext[8]) {
case ':' :
LEXTRACE("DEFAULTS_USER ");
return(DEFAULTS_USER);
case '@' :
LEXTRACE("DEFAULTS_HOST ");
return(DEFAULTS_HOST);
}
} else {
LEXTRACE("DEFAULTS ");
return(DEFAULTS);
}
}
<INITIAL>^(Host|Cmnd|User|Runas)_Alias {
fill(yytext, yyleng);
if (*yytext == 'H') {
LEXTRACE("HOSTALIAS ");
return(HOSTALIAS);
}
if (*yytext == 'C') {
LEXTRACE("CMNDALIAS ");
return(CMNDALIAS);
}
if (*yytext == 'U') {
LEXTRACE("USERALIAS ");
return(USERALIAS);
}
if (*yytext == 'R') {
LEXTRACE("RUNASALIAS ");
return(RUNASALIAS);
}
}
\/[^\,:=\\ \t\n#]+ {
/* directories can't have args... */
@@ -246,42 +319,15 @@ PASSWD[[:blank:]]*: {
}
} /* a pathname */
[[:upper:]][[:upper:][:digit:]_]* {
if (strcmp(yytext, "ALL") == 0) {
LEXTRACE("ALL ");
return(ALL);
} else {
fill(yytext, yyleng);
LEXTRACE("ALIAS ");
return(ALIAS);
}
}
[[:alnum:]][[:alnum:]_-]* {
{WORD} {
/* a word */
fill(yytext, yyleng);
if (strcmp(yytext, "Host_Alias") == 0) {
LEXTRACE("HOSTALIAS ");
return(HOSTALIAS);
}
if (strcmp(yytext, "Cmnd_Alias") == 0) {
LEXTRACE("CMNDALIAS ");
return(CMNDALIAS);
}
if (strcmp(yytext, "User_Alias") == 0) {
LEXTRACE("USERALIAS ");
return(USERALIAS);
}
if (strcmp(yytext, "Runas_Alias") == 0) {
LEXTRACE("RUNASALIAS ");
return(RUNASALIAS);
}
/* NAME is what RFC1034 calls a label */
LEXTRACE("NAME ");
return(NAME);
LEXTRACE("WORD(4) ");
return(WORD);
}
. {
LEXTRACE("ERROR ");
return(ERROR);
} /* parse error */

View File

@@ -90,11 +90,6 @@ int errorlineno = -1;
int clearaliases = TRUE;
int printmatches = FALSE;
int pedantic = FALSE;
#ifdef NO_AUTHENTICATION
int pwdef = TRUE;
#else
int pwdef = -1;
#endif
/*
* Alias types
@@ -120,7 +115,7 @@ int top = 0, stacksize = 0;
match[top].cmnd = -1; \
match[top].host = -1; \
match[top].runas = -1; \
match[top].nopass = pwdef; \
match[top].nopass = sudo_flag_set(FL_AUTHENTICATE) ? -1 : TRUE; \
top++; \
} while (0)
@@ -173,12 +168,13 @@ static size_t ga_list_len = 0, ga_list_size = 0;
static struct generic_alias *ga_list = NULL;
/*
* Protoypes
* Does this Defaults list pertain to this user?
*/
static int defaults_matches = 0;
/*
* Local protoypes
*/
extern int addr_matches __P((char *));
extern int command_matches __P((char *, char *, char *, char *));
extern int netgr_matches __P((char *, char *, char *));
extern int usergr_matches __P((char *, char *));
static int add_alias __P((char *, int, int));
static void append __P((char *, char **, size_t *, size_t *, char *));
static void expand_ga_list __P((void));
@@ -221,7 +217,10 @@ yyerror(s)
%token <string> FQHOST /* foo.bar.com */
%token <string> NETGROUP /* a netgroup (+NAME) */
%token <string> USERGROUP /* a usergroup (%NAME) */
%token <string> NAME /* a mixed-case name */
%token <string> WORD /* a word */
%token <tok> DEFAULTS /* Defaults entry */
%token <tok> DEFAULTS_HOST /* Host-specific defaults entry */
%token <tok> DEFAULTS_USER /* User-specific defaults entry */
%token <tok> RUNAS /* ( runas_list ) */
%token <tok> NOPASSWD /* no passwd req for command */
%token <tok> PASSWD /* passwd req for command (default) */
@@ -267,8 +266,51 @@ entry : COMMENT
{ ; }
| RUNASALIAS runasaliases
{ ; }
| defaults_line
{ ; }
;
defaults_line : defaults_type defaults_list
defaults_type : DEFAULTS {
defaults_matches = TRUE;
}
| DEFAULTS_USER { push; } userlist {
defaults_matches = user_matches;
pop;
}
| DEFAULTS_HOST { push; } hostlist {
defaults_matches = host_matches;
pop;
}
;
defaults_list : defaults_entry
| defaults_entry ',' defaults_list
defaults_entry : WORD {
if (defaults_matches && !set_default($1, NULL, 1)) {
yyerror(NULL);
YYERROR;
}
free($1);
}
| '!' WORD {
if (defaults_matches && !set_default($2, NULL, 0)) {
yyerror(NULL);
YYERROR;
}
free($2);
}
| WORD '=' WORD {
/* XXX - need to support quoted values */
if (defaults_matches && !set_default($1, $3, 1)) {
yyerror(NULL);
YYERROR;
}
free($1);
free($3);
}
privileges : privilege
| privileges ':' privilege
@@ -282,7 +324,10 @@ privilege : hostlist '=' cmndspeclist {
*/
host_matches = -1;
runas_matches = -1;
no_passwd = pwdef;
if (sudo_flag_set(FL_AUTHENTICATE))
no_passwd = -1;
else
no_passwd = TRUE;
}
;
@@ -312,7 +357,7 @@ host : ALL {
$$ = -1;
free($1);
}
| NAME {
| WORD {
if (strcasecmp(user_shost, $1) == 0)
$$ = TRUE;
else
@@ -411,11 +456,11 @@ runasspec : /* empty */ {
}
/*
* If this is the first entry in a command list
* then check against RUNAS_DEFAULT.
* then check against default runas user.
*/
if (runas_matches == -1)
runas_matches =
(strcmp(RUNAS_DEFAULT, user_runas) == 0);
runas_matches = (strcmp(*user_runas,
sudo_strtable[I_RUNAS_DEF]) == 0);
}
| RUNAS runaslist { ; }
;
@@ -441,7 +486,7 @@ oprunasuser : runasuser {
runas_matches = ! $3;
}
runasuser : NAME {
runasuser : WORD {
if (printmatches == TRUE) {
if (in_alias == TRUE)
append_entries($1, ", ");
@@ -449,7 +494,7 @@ runasuser : NAME {
user_matches == TRUE)
append_runas($1, ", ");
}
if (strcmp($1, user_runas) == 0)
if (strcmp($1, *user_runas) == 0)
$$ = TRUE;
else
$$ = -1;
@@ -463,7 +508,7 @@ runasuser : NAME {
user_matches == TRUE)
append_runas($1, ", ");
}
if (usergr_matches($1, user_runas))
if (usergr_matches($1, *user_runas))
$$ = TRUE;
else
$$ = -1;
@@ -477,7 +522,7 @@ runasuser : NAME {
user_matches == TRUE)
append_runas($1, ", ");
}
if (netgr_matches($1, NULL, user_runas))
if (netgr_matches($1, NULL, *user_runas))
$$ = TRUE;
else
$$ = -1;
@@ -496,7 +541,7 @@ runasuser : NAME {
/* could be an all-caps username */
if (aip)
$$ = aip->val;
else if (strcmp($1, user_runas) == 0)
else if (strcmp($1, *user_runas) == 0)
$$ = TRUE;
else {
if (pedantic) {
@@ -705,7 +750,7 @@ useralias : ALIAS { push; } '=' userlist {
}
;
userlist : opuser { ; }
userlist : opuser
| userlist ',' opuser
;
@@ -718,7 +763,7 @@ opuser : user {
user_matches = ! $2;
}
user : NAME {
user : WORD {
if (strcmp($1, user_name) == 0)
$$ = TRUE;
else
@@ -951,13 +996,13 @@ list_matches()
} while ((p = strtok(NULL, ", ")));
(void) fputs(") ", stdout);
} else {
(void) printf("(%s) ", RUNAS_DEFAULT);
(void) printf("(%s) ", sudo_strtable[I_RUNAS_DEF]);
}
/* Is a password required? */
if (cm_list[i].nopasswd == TRUE && pwdef != TRUE)
if (cm_list[i].nopasswd == TRUE && sudo_flag_set(FL_AUTHENTICATE))
(void) fputs("NOPASSWD: ", stdout);
else if (cm_list[i].nopasswd == FALSE && pwdef == TRUE)
else if (cm_list[i].nopasswd == FALSE && !sudo_flag_set(FL_AUTHENTICATE))
(void) fputs("PASSWD: ", stdout);
/* Print the actual command or expanded Cmnd_Alias. */

188
sudo.c
View File

@@ -75,6 +75,7 @@
#include "sudo.h"
#include "interfaces.h"
#include "version.h"
#ifndef STDC_HEADERS
extern char *getenv __P((char *));
@@ -182,15 +183,6 @@ main(argc, argv)
exit(1);
}
/* Initialize syslog(3) if we are using it. */
#if (LOGGING & SLOG_SYSLOG)
# ifdef LOG_NFACILITIES
openlog("sudo", 0, LOGFAC);
# else
openlog("sudo", 0);
# endif /* LOG_NFACILITIES */
#endif /* LOGGING & SLOG_SYSLOG */
/* Catch children as they die... */
#ifdef POSIX_SIGNALS
(void) memset((VOID *)&sa, 0, sizeof(sa));
@@ -228,18 +220,34 @@ main(argc, argv)
/*
* Set the prompt based on $SUDO_PROMPT (can be overridden by `-p')
*/
if ((user_prompt = getenv("SUDO_PROMPT")) == NULL)
user_prompt = PASSPROMPT;
user_prompt = getenv("SUDO_PROMPT");
/* Parse our arguments. */
sudo_mode = parse_args();
/* Setup defaults data structures. */
init_defaults();
/* Initialize syslog(3) if we are using it. */
if (sudo_inttable[I_LOGFAC] != (unsigned int)-1) {
#ifdef LOG_NFACILITIES
openlog("sudo", 0, sudo_inttable[I_LOGFAC]);
#else
openlog("sudo", 0);
#endif /* LOG_NFACILITIES */
}
if (sudo_mode & MODE_SHELL)
user_cmnd = "shell";
else
switch (sudo_mode) {
case MODE_VERSION:
print_version();
(void) printf("Sudo version %s\n", version);
if (getuid() == 0) {
putchar('\n');
dump_auth_methods();
dump_defaults();
}
exit(0);
break;
case MODE_HELP:
@@ -252,6 +260,10 @@ main(argc, argv)
case MODE_INVALIDATE:
user_cmnd = "kill";
break;
case MODE_LISTDEFS:
list_options();
exit(0);
break;
case MODE_LIST:
user_cmnd = "list";
printmatches = 1;
@@ -281,14 +293,22 @@ main(argc, argv)
validated =
sudoers_lookup((sudo_mode != MODE_VALIDATE && sudo_mode != MODE_LIST));
if (validated & VALIDATE_ERROR)
log_error(0, "parse error in %s near line %d", _PATH_SUDOERS,
errorlineno);
/* Is root even allowed to run sudo? */
if (getuid() == 0 && !sudo_flag_set(FL_ROOT_SUDO)) {
(void) fputs("You are already root, you don't need to use sudo.\n",
stderr);
exit(1);
}
/* Require a password unless the NOPASS tag was set. */
if (!(validated & FLAG_NOPASS))
check_user();
if (validated & VALIDATE_ERROR)
log_error(0, "parse error in %s near line %d", _PATH_SUDOERS,
errorlineno);
else if (validated & VALIDATE_OK) {
if (validated & VALIDATE_OK) {
/* Finally tell the user if the command did not exist. */
if (cmnd_status == NOT_FOUND_DOT) {
(void) fprintf(stderr, "%s: ignoring `%s' found in '.'\nUse `sudo ./%s' if this is the `%s' you wish to run.\n", Argv[0], user_cmnd, user_cmnd, user_cmnd);
@@ -322,9 +342,8 @@ main(argc, argv)
"please report this error to sudo-bugs@courtesan.com");
}
#if (LOGGING & SLOG_SYSLOG)
closelog();
#endif
if (sudo_inttable[I_LOGFAC] != (unsigned int)-1)
closelog();
/* Reset signal mask before we exec. */
#ifdef POSIX_SIGNALS
@@ -333,6 +352,18 @@ main(argc, argv)
(void) sigsetmask(omask);
#endif /* POSIX_SIGNALS */
/* Override user's umask if configured to do so. */
if (sudo_inttable[I_UMASK] != 0777)
(void) umask((mode_t)sudo_inttable[I_UMASK]);
/* Replace the PATH envariable with a secure one. */
if (sudo_strtable[I_SECURE_PATH] && !user_is_exempt())
if (sudo_setenv("PATH", sudo_strtable[I_SECURE_PATH])) {
(void) fprintf(stderr, "%s: cannot allocate memory!\n",
Argv[0]);
exit(1);
}
#ifndef PROFILING
if ((sudo_mode & MODE_BACKGROUND) && fork() > 0)
exit(0);
@@ -351,24 +382,25 @@ main(argc, argv)
log_auth(validated, 1);
exit(1);
} else if (validated & VALIDATE_NOT_OK) {
#ifndef DONT_LEAK_PATH_INFO
/*
* We'd like to not leak path info at all here, but that can
* *really* confuse the users. To really close the leak we'd
* have to say "not allowed to run foo" even when the problem
* is just "no foo in path" since the user can trivially set
* their path to just contain a single dir.
*/
log_auth(validated,
!(cmnd_status == NOT_FOUND_DOT || cmnd_status == NOT_FOUND));
if (cmnd_status == NOT_FOUND)
(void) fprintf(stderr, "%s: %s: command not found\n", Argv[0],
user_cmnd);
else if (cmnd_status == NOT_FOUND_DOT)
(void) fprintf(stderr, "%s: ignoring `%s' found in '.'\nUse `sudo ./%s' if this is the `%s' you wish to run.\n", Argv[0], user_cmnd, user_cmnd, user_cmnd);
#else
log_auth(validated, 1);
#endif /* DONT_LEAK_PATH_INFO */
if (sudo_flag_set(FL_PATH_INFO)) {
/*
* We'd like to not leak path info at all here, but that can
* *really* confuse the users. To really close the leak we'd
* have to say "not allowed to run foo" even when the problem
* is just "no foo in path" since the user can trivially set
* their path to just contain a single dir.
*/
log_auth(validated,
!(cmnd_status == NOT_FOUND_DOT || cmnd_status == NOT_FOUND));
if (cmnd_status == NOT_FOUND)
(void) fprintf(stderr, "%s: %s: command not found\n", Argv[0],
user_cmnd);
else if (cmnd_status == NOT_FOUND_DOT)
(void) fprintf(stderr, "%s: ignoring `%s' found in '.'\nUse `sudo ./%s' if this is the `%s' you wish to run.\n", Argv[0], user_cmnd, user_cmnd, user_cmnd);
} else {
/* Just tell the user they are not allowed to run foo. */
log_auth(validated, 1);
}
exit(1);
} else {
/* should never get here */
@@ -387,17 +419,7 @@ init_vars(sudo_mode)
int sudo_mode;
{
char *p, thost[MAXHOSTNAMELEN];
#ifdef FQDN
struct hostent *hp;
#endif /* FQDN */
#ifdef NO_ROOT_SUDO
if (getuid() == 0) {
(void) fputs("You are already root, you don't need to use sudo.\n",
stderr);
exit(1);
}
#endif
/* Sanity check command from user. */
if (user_cmnd == NULL && strlen(NewArgv[0]) >= MAXPATHLEN) {
@@ -410,21 +432,7 @@ init_vars(sudo_mode)
(void) tzset(); /* set the timezone if applicable */
#endif /* HAVE_TZSET */
#ifdef SECURE_PATH
/* Replace the PATH envariable with a secure one. */
if (!user_is_exempt() && sudo_setenv("PATH", SECURE_PATH)) {
(void) fprintf(stderr, "%s: cannot allocate memory!\n", Argv[0]);
exit(1);
}
#endif /* SECURE_PATH */
#ifdef SUDO_UMASK
(void) umask((mode_t)SUDO_UMASK);
#endif /* SUDO_UMASK */
/* Default values for runas and cmnd, overridden later. */
if (user_runas == NULL)
user_runas = RUNAS_DEFAULT;
/* Default value for cmnd and cwd, overridden later. */
if (user_cmnd == NULL)
user_cmnd = NewArgv[0];
(void) strcpy(user_cwd, "unknown");
@@ -440,13 +448,15 @@ init_vars(sudo_mode)
log_error(USE_ERRNO|MSG_ONLY, "can't get hostname");
} else
user_host = estrdup(thost);
#ifdef FQDN
if (!(hp = gethostbyname(user_host)))
log_error(USE_ERRNO|MSG_ONLY|NO_EXIT,
"unable to lookup %s via gethostbyname()", user_host);
else
user_host = estrdup(hp->h_name);
#endif /* FQDN */
if (sudo_flag_set(FL_FQDN)) {
if (!(hp = gethostbyname(user_host))) {
log_error(USE_ERRNO|MSG_ONLY|NO_EXIT,
"unable to lookup %s via gethostbyname()", user_host);
} else {
free(user_host);
user_host = estrdup(hp->h_name);
}
}
if ((p = strchr(user_host, '.'))) {
*p = '\0';
user_shost = estrdup(user_host);
@@ -545,15 +555,12 @@ parse_args()
NewArgv = Argv + 1;
NewArgc = Argc - 1;
#ifdef SHELL_IF_NO_ARGS
if (Argc < 2) { /* no options and no command */
if (!sudo_flag_set(FL_SHELL_NOARGS))
usage(1);
rval |= MODE_SHELL;
return(rval);
}
#else
if (Argc < 2) /* no options and no command */
usage(1);
#endif /* SHELL_IF_NO_ARGS */
while (NewArgc > 0 && NewArgv[0][0] == '-') {
if (NewArgv[0][1] != '\0' && NewArgv[0][2] != '\0') {
@@ -592,7 +599,7 @@ parse_args()
if (NewArgv[1] == NULL)
usage(1);
user_runas = NewArgv[1];
user_runas = &NewArgv[1];
/* Shift Argv over and adjust Argc. */
NewArgc--;
@@ -619,6 +626,12 @@ parse_args()
usage_excl(1);
excl = 'K';
break;
case 'L':
rval = MODE_LISTDEFS;
if (excl && excl != 'L')
usage_excl(1);
excl = 'L';
break;
case 'l':
rval = MODE_LIST;
if (excl && excl != 'l')
@@ -639,9 +652,8 @@ parse_args()
break;
case 's':
rval |= MODE_SHELL;
#ifdef SHELL_SETS_HOME
rval |= MODE_RESET_HOME;
#endif /* SHELL_SETS_HOME */
if (sudo_flag_set(FL_SET_HOME))
rval |= MODE_RESET_HOME;
break;
case 'H':
rval |= MODE_RESET_HOME;
@@ -649,10 +661,8 @@ parse_args()
case '-':
NewArgc--;
NewArgv++;
#ifdef SHELL_IF_NO_ARGS
if (rval == MODE_RUN)
if (sudo_flag_set(FL_SHELL_NOARGS) && rval == MODE_RUN)
rval |= MODE_SHELL;
#endif /* SHELL_IF_NO_ARGS */
return(rval);
case '\0':
(void) fprintf(stderr, "%s: '-' requires an argument\n",
@@ -913,18 +923,18 @@ set_perms(perm, sudo_mode)
}
/* XXX - add group/gid support */
if (*user_runas == '#') {
if (setuid(atoi(user_runas + 1))) {
if (**user_runas == '#') {
if (setuid(atoi(*user_runas + 1))) {
(void) fprintf(stderr,
"%s: cannot set uid to %s: %s\n",
Argv[0], user_runas, strerror(errno));
Argv[0], *user_runas, strerror(errno));
exit(1);
}
} else {
if (!(pw = getpwnam(user_runas))) {
if (!(pw = getpwnam(*user_runas))) {
(void) fprintf(stderr,
"%s: no passwd entry for %s!\n",
Argv[0], user_runas);
Argv[0], *user_runas);
exit(1);
}
@@ -954,8 +964,8 @@ set_perms(perm, sudo_mode)
* Initialize group vector only if are
* going to run as a non-root user.
*/
if (strcmp(user_runas, "root") != 0 &&
initgroups(user_runas, pw->pw_gid)
if (strcmp(*user_runas, "root") != 0 &&
initgroups(*user_runas, pw->pw_gid)
== -1) {
(void) fprintf(stderr,
"%s: cannot set group vector: %s\n",
@@ -1029,7 +1039,7 @@ usage(exit_val)
int exit_val;
{
(void) fprintf(stderr,
"usage: %s -V | -h | -l | -v | -k | -K | -H | [-b] [-p prompt]\n%*s",
"usage: %s -V | -h | -L | -l | -v | -k | -K | -H | [-b] [-p prompt]\n%*s",
Argv[0], (int) strlen(Argv[0]) + 8, " ");
#ifdef HAVE_KERB5
(void) fprintf(stderr, "[-r realm] ");

15
sudo.h
View File

@@ -39,6 +39,7 @@
#include <pathnames.h>
#include "compat.h"
#include "defaults.h"
#include "logging.h"
/*
@@ -50,7 +51,7 @@ struct sudo_user {
char cwd[MAXPATHLEN];
char *host;
char *shost;
char *runas;
char **runas;
char *prompt;
char *cmnd_safe;
char *cmnd;
@@ -95,9 +96,10 @@ struct sudo_user {
#define MODE_VERSION 00020
#define MODE_HELP 00040
#define MODE_LIST 00100
#define MODE_BACKGROUND 00200
#define MODE_SHELL 00400
#define MODE_RESET_HOME 01000
#define MODE_LISTDEFS 00200
#define MODE_BACKGROUND 00400
#define MODE_SHELL 01000
#define MODE_RESET_HOME 02000
/*
* Used with set_perms()
@@ -173,7 +175,7 @@ int sudo_setenv __P((char *, char *));
char *tgetpass __P((const char *, int, int));
int find_path __P((char *, char **));
void check_user __P((void));
void verify_user __P((void));
void verify_user __P((char *));
int sudoers_lookup __P((int));
void set_perms __P((int, int));
void remove_timestamp __P((int));
@@ -187,7 +189,8 @@ VOID *erealloc __P((VOID *, size_t));
char *estrdup __P((const char *));
void easprintf __P((char **, const char *, ...));
void evasprintf __P((char **, const char *, va_list));
void print_version __P((void));
void dump_defaults __P((void));
void dump_auth_methods __P((void));
int lock_file __P((int, int));
int touch __P((char *, time_t));
YY_DECL;

File diff suppressed because it is too large Load Diff

View File

@@ -4,17 +4,20 @@
#define FQHOST 260
#define NETGROUP 261
#define USERGROUP 262
#define NAME 263
#define RUNAS 264
#define NOPASSWD 265
#define PASSWD 266
#define ALL 267
#define COMMENT 268
#define HOSTALIAS 269
#define CMNDALIAS 270
#define USERALIAS 271
#define RUNASALIAS 272
#define ERROR 273
#define WORD 263
#define DEFAULTS 264
#define DEFAULTS_HOST 265
#define DEFAULTS_USER 266
#define RUNAS 267
#define NOPASSWD 268
#define PASSWD 269
#define ALL 270
#define COMMENT 271
#define HOSTALIAS 272
#define CMNDALIAS 273
#define USERALIAS 274
#define RUNASALIAS 275
#define ERROR 276
typedef union {
char *string;
int BOOLEAN;

View File

@@ -296,9 +296,8 @@ main(argc, argv)
Argv = argv;
Argc = argc;
user_runas = RUNAS_DEFAULT;
if (Argc >= 6 && strcmp(Argv[1], "-u") == 0) {
user_runas = Argv[2];
user_runas = &Argv[2];
pw.pw_name = Argv[3];
user_host = Argv[4];
user_cmnd = Argv[5];
@@ -343,6 +342,9 @@ main(argc, argv)
}
}
/* Initialize default values. */
init_defaults();
/* Warn about aliases that are used before being defined. */
pedantic = TRUE;
@@ -368,7 +370,7 @@ main(argc, argv)
(void) printf("cmnd_match : %d\n", cmnd_matches);
(void) printf("no_passwd : %d\n", no_passwd);
(void) printf("runas_match: %d\n", runas_matches);
(void) printf("runas : %s\n", user_runas);
(void) printf("runas : %s\n", *user_runas);
top--;
}
}

245
version.c
View File

@@ -1,245 +0,0 @@
/*
* Copyright (c) 1996, 1998, 1999 Todd C. Miller <Todd.Miller@courtesan.com>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* 4. Products derived from this software may not be called "Sudo" nor
* may "Sudo" appear in their names without specific prior written
* permission from the author.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
* AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
* THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "config.h"
#include <stdio.h>
#ifdef HAVE_UNISTD_H
#include <unistd.h>
#endif /* HAVE_UNISTD_H */
#ifdef HAVE_STRING_H
#include <string.h>
#endif /* HAVE_STRING_H */
#ifdef HAVE_STRINGS_H
#include <strings.h>
#endif /* HAVE_STRINGS_H */
#include <sys/types.h>
#include <sys/param.h>
#define SYSLOG_NAMES
#include "sudo.h"
#include "version.h"
#include "auth/sudo_auth.h"
#ifndef lint
static const char rcsid[] = "$Sudo$";
#endif /* lint */
#if (LOGGING & SLOG_SYSLOG) && defined(HAVE_SYSLOG_NAMES)
static char *num_to_name __P((int, CODE *));
#endif /* SLOG_SYSLOG && HAVE_SYSLOG_NAMES */
/*
* Print version and configure info.
*/
void
print_version()
{
extern sudo_auth auth_switch[];
sudo_auth *auth;
(void) printf("Sudo version %s\n", version);
/*
* Print compile-time options if root.
* At some point these will all be in a structure of some kind
* to allow overriding the defaults from sudoers.
* XXX - reorganize for readability.
*/
if (getuid() == 0) {
(void) printf("\nSudoers file: %s, mode 0%o, uid %d, gid %d\n",
_PATH_SUDOERS, SUDOERS_MODE, SUDOERS_UID, SUDOERS_GID);
(void) printf("Sudoers temp file: %s\n", _PATH_SUDOERS_TMP);
#ifdef NO_AUTHENTICATION
(void) puts("No Authentication required by default.\n");
#endif
(void) fputs("Authentication methods:", stdout);
for (auth = auth_switch; auth->name; auth++)
(void) printf(" '%s'", auth->name);
(void) putchar('\n');
(void) fputs("Logging:\n", stdout);
#if (LOGGING & SLOG_SYSLOG)
# ifdef HAVE_SYSLOG_NAMES
printf(" syslog: facility '%s', failures to '%s', success to '%s'\n",
num_to_name(LOGFAC, facilitynames),
num_to_name(PRI_FAILURE, prioritynames),
num_to_name(PRI_SUCCESS, prioritynames));
# else
printf(" syslog: facility #%d, failures to #%d, success to #%d\n",
LOGFAC, PRI_FAILURE, PRI_SUCCESS);
# endif /* HAVE_SYSLOG_NAMES */
#endif /* SLOG_SYSLOG */
#if (LOGGING & SLOG_FILE)
(void) printf(" log file: %s", _PATH_SUDO_LOGFILE);
# ifdef HOST_IN_LOG
(void) fputs(", host in log", stdout);
# endif
# ifdef WRAP_LOG
(void) printf(", lines wrap after %d characters", MAXLOGFILELEN);
# endif
(void) putchar('\n');
#endif /* SLOG_FILE */
#ifdef USE_TTY_TICKETS
(void) puts("Timestamp type: userdir/tty");
#else
(void) puts("Timestamp type: userdir");
#endif
#if TIMEOUT
(void) printf("Ticket file timeout: %d minutes\n", TIMEOUT);
#endif
#ifdef USE_INSULTS
(void) fputs("Insult types:", stdout);
# ifdef CLASSIC_INSULTS
(void) fputs(" classic", stdout);
# endif
# ifdef CSOPS_INSULTS
(void) fputs(" CSOps", stdout);
# endif
# ifdef HAL_INSULTS
(void) fputs(" hal", stdout);
# endif
# ifdef GOONS_INSULTS
(void) fputs(" goons", stdout);
# endif
(void) putchar('\n');
# else
(void) printf("Incorrect password message: %s\n", INCORRECT_PASSWORD);
#endif
#ifdef SUDO_UMASK
(void) printf("Umask to enforce: 0%o\n", SUDO_UMASK);
#endif
#if !defined(WITHOUT_PASSWD) && PASSWORD_TIMEOUT
(void) printf("Password timeout: %d minutes\n", PASSWORD_TIMEOUT);
#endif
(void) printf("Password attempts allowed: %d\n", TRIES_FOR_PASSWORD);
(void) printf("Default user to run commands as: %s\n", RUNAS_DEFAULT);
#ifdef FQDN
(void) puts("Fully qualified hostnames required in sudoers");
#endif
#ifdef NO_ROOT_SUDO
(void) puts("Root may not run sudo");
#endif
#ifdef EXEMPTGROUP
(void) printf("Users in group %s are exempt from password and PATH requirements\n", EXEMPTGROUP);
#endif
#ifdef ENV_EDITOR
(void) printf("Default editor for visudo: %s\n", EDITOR);
#else
(void) printf("Editor for visudo: %s\n", EDITOR);
#endif
#if defined(IGNORE_DOT_PATH) || defined(DONT_LEAK_PATH_INFO) || defined(SECURE_PATH)
puts("$PATH options:");
#ifdef SECURE_PATH
(void) printf(" PATH override: %s\n", SECURE_PATH);
#endif
# ifdef IGNORE_DOT_PATH
(void) puts(" ignore '.'");
# endif
# ifdef DONT_LEAK_PATH_INFO
(void) puts(" no information leakage");
# endif
#endif
#ifdef _PATH_SENDMAIL
(void) printf("Mailer path: %s\n", _PATH_SENDMAIL);
(void) printf("Send mail to: %s\n", ALERTMAIL);
(void) printf("Mail subject: %s\n", MAILSUBJECT);
(void) fputs("Send mail on: 'error'", stdout);
# ifdef SEND_MAIL_WHEN_NO_USER
(void) fputs(" 'unlisted user'", stdout);
# endif
# ifdef SEND_MAIL_WHEN_NO_HOST
(void) fputs(" 'unlisted on host'", stdout);
# endif
# ifdef SEND_MAIL_WHEN_NOT_OK
(void) fputs(" 'authentication failure'", stdout);
# endif
(void) putchar('\n');
#endif
#ifdef SHELL_IF_NO_ARGS
puts("When invoked with no arguments sudo will start a shell");
#endif
#ifdef SHELL_SETS_HOME
puts("Sudo will set $HOME to the homedir of the target user");
#endif
(void) printf("Default password prompt: %s\n", PASSPROMPT);
(void) fputs("Lecture user the first time they run sudo? ", stdout);
#ifndef NO_LECTURE
(void) puts("yes");
#else
(void) puts("no");
#endif
}
}
#if (LOGGING & SLOG_SYSLOG) && defined(HAVE_SYSLOG_NAMES)
/*
* Convert a syslog number to a name. At some point in the
* future, sudo will have its own tables internally so syslog
* can be configured at run time.
*/
static char *
num_to_name(num, table)
int num;
CODE *table;
{
CODE *t;
for (t = table; t->c_name; t++)
if (t->c_val == num)
return(t->c_name);
return("unknown");
}
#endif /* SLOG_SYSLOG && HAVE_SYSLOG_NAMES */

View File

@@ -150,7 +150,6 @@ main(argc, argv)
}
/* Mock up a fake sudo_user struct. */
user_runas = RUNAS_DEFAULT;
user_host = user_shost = user_cmnd = "";
if ((sudo_user.pw = getpwuid(getuid())) == NULL) {
(void) fprintf(stderr, "%s: Can't find you in the passwd database.\n",
@@ -273,6 +272,7 @@ main(argc, argv)
}
/* Clean slate for each parse */
init_defaults();
init_parser();
/* Parse the sudoers file */