Run most of the code as root, not the invoking user. It doesn't really
gain us anything to run as the user since an attacker can just have an setuid(0) in their egg. Running as root solves potential problems wrt signalling.
This commit is contained in:
18
auth/API
18
auth/API
@@ -31,8 +31,8 @@ The variables in the struct are as follows:
|
|||||||
initialized in the "init" or "setup" routines.
|
initialized in the "init" or "setup" routines.
|
||||||
|
|
||||||
Possible values of sudo_auth.flags:
|
Possible values of sudo_auth.flags:
|
||||||
FLAG_ROOT Whether or not the auth functions should run with
|
FLAG_USER Whether or not the auth functions should run with
|
||||||
an euid of 0 or the uid of the invoking user.
|
the euid of the invoking user instead of 0.
|
||||||
|
|
||||||
FLAG_CONFIGURED If set then the auth method is assumed to have been
|
FLAG_CONFIGURED If set then the auth method is assumed to have been
|
||||||
configured successfully. All auth methods start out
|
configured successfully. All auth methods start out
|
||||||
@@ -102,23 +102,23 @@ in sudo_auth.h. For instance, for a method, ``fooauth'', add:
|
|||||||
|
|
||||||
#elif defined(HAVE_FOOAUTH)
|
#elif defined(HAVE_FOOAUTH)
|
||||||
# define AUTH_STANDALONE \
|
# define AUTH_STANDALONE \
|
||||||
AUTH_ENTRY(FLAG_ROOT, "foo", \
|
AUTH_ENTRY(0, "foo", \
|
||||||
foo_init, foo_setup, foo_verify, foo_cleanup)
|
foo_init, foo_setup, foo_verify, foo_cleanup)
|
||||||
|
|
||||||
If the method doesn't need to run as root, replace FLAG_ROOT with 0.
|
If the method needs to run as the user, not root, replace the first
|
||||||
If you don't have a init/setup/cleanup routine, just use a NULL for that
|
parameter to AUTH_ENTRY (0) with FLAG_USER. If you don't have a
|
||||||
field.
|
init/setup/cleanup routine, just use a NULL for that field.
|
||||||
|
|
||||||
For a normal authentication method, add it to the ``auth_switch'' in
|
For a normal authentication method, add it to the ``auth_switch'' in
|
||||||
sudo_auth.c. If ``fooauth'' is a normal auth method, its entry
|
sudo_auth.c. If ``fooauth'' is a normal auth method, its entry
|
||||||
would look like:
|
would look like:
|
||||||
|
|
||||||
# ifdef HAVE_FOOAUTH
|
# ifdef HAVE_FOOAUTH
|
||||||
AUTH_ENTRY(FLAG_ROOT, "foo", foo_init, foo_setup, foo_verify, foo_cleanup)
|
AUTH_ENTRY(0, "foo", foo_init, foo_setup, foo_verify, foo_cleanup)
|
||||||
# endif
|
# endif
|
||||||
|
|
||||||
Again, if the method doesn't need to run as root, replace FLAG_ROOT
|
Again, if the method doesn't need to run as root, replace the 0 with
|
||||||
with 0. Likewise, if you don't have a init/setup/cleanup routine,
|
FLAG_USER. Likewise, if you don't have a init/setup/cleanup routine,
|
||||||
just use a NULL for that field.
|
just use a NULL for that field.
|
||||||
|
|
||||||
NOTE: You should not make a method both ``standalone'' and
|
NOTE: You should not make a method both ``standalone'' and
|
||||||
|
@@ -65,25 +65,25 @@ sudo_auth auth_switch[] = {
|
|||||||
AUTH_STANDALONE
|
AUTH_STANDALONE
|
||||||
#else
|
#else
|
||||||
# ifndef WITHOUT_PASSWD
|
# ifndef WITHOUT_PASSWD
|
||||||
AUTH_ENTRY(FLAG_ROOT, "passwd", NULL, NULL, passwd_verify, NULL)
|
AUTH_ENTRY(0, "passwd", NULL, NULL, passwd_verify, NULL)
|
||||||
# endif
|
# endif
|
||||||
# if defined(HAVE_SECUREWARE) && !defined(WITHOUT_PASSWD)
|
# if defined(HAVE_SECUREWARE) && !defined(WITHOUT_PASSWD)
|
||||||
AUTH_ENTRY(FLAG_ROOT, "secureware", secureware_init, NULL, secureware_verify, NULL)
|
AUTH_ENTRY(0, "secureware", secureware_init, NULL, secureware_verify, NULL)
|
||||||
# endif
|
# endif
|
||||||
# ifdef HAVE_AFS
|
# ifdef HAVE_AFS
|
||||||
AUTH_ENTRY(FLAG_ROOT, "afs", NULL, NULL, afs_verify, NULL)
|
AUTH_ENTRY(0, "afs", NULL, NULL, afs_verify, NULL)
|
||||||
# endif
|
# endif
|
||||||
# ifdef HAVE_KERB4
|
# ifdef HAVE_KERB4
|
||||||
AUTH_ENTRY(FLAG_ROOT, "kerb4", kerb4_init, NULL, kerb4_verify, NULL)
|
AUTH_ENTRY(0, "kerb4", kerb4_init, NULL, kerb4_verify, NULL)
|
||||||
# endif
|
# endif
|
||||||
# ifdef HAVE_KERB5
|
# ifdef HAVE_KERB5
|
||||||
AUTH_ENTRY(FLAG_ROOT, "kerb5", kerb5_init, NULL, kerb5_verify, NULL)
|
AUTH_ENTRY(0, "kerb5", kerb5_init, NULL, kerb5_verify, NULL)
|
||||||
# endif
|
# endif
|
||||||
# ifdef HAVE_SKEY
|
# ifdef HAVE_SKEY
|
||||||
AUTH_ENTRY(FLAG_ROOT, "S/Key", NULL, rfc1938_setup, rfc1938_verify, NULL)
|
AUTH_ENTRY(0, "S/Key", NULL, rfc1938_setup, rfc1938_verify, NULL)
|
||||||
# endif
|
# endif
|
||||||
# ifdef HAVE_OPIE
|
# ifdef HAVE_OPIE
|
||||||
AUTH_ENTRY(FLAG_ROOT, "OPIE", NULL, rfc1938_setup, rfc1938_verify, NULL)
|
AUTH_ENTRY(0, "OPIE", NULL, rfc1938_setup, rfc1938_verify, NULL)
|
||||||
# endif
|
# endif
|
||||||
#endif /* AUTH_STANDALONE */
|
#endif /* AUTH_STANDALONE */
|
||||||
AUTH_ENTRY(0, NULL, NULL, NULL, NULL, NULL)
|
AUTH_ENTRY(0, NULL, NULL, NULL, NULL, NULL)
|
||||||
@@ -107,8 +107,8 @@ verify_user()
|
|||||||
/* Initialize auth methods and unconfigure the method if necessary. */
|
/* Initialize auth methods and unconfigure the method if necessary. */
|
||||||
for (auth = auth_switch; auth->name; auth++) {
|
for (auth = auth_switch; auth->name; auth++) {
|
||||||
if (auth->init && IS_CONFIGURED(auth)) {
|
if (auth->init && IS_CONFIGURED(auth)) {
|
||||||
if (NEEDS_ROOT(auth))
|
if (NEEDS_USER(auth))
|
||||||
set_perms(PERM_ROOT, 0);
|
set_perms(PERM_USER, 0);
|
||||||
|
|
||||||
status = (auth->init)(sudo_user.pw, &user_prompt, auth);
|
status = (auth->init)(sudo_user.pw, &user_prompt, auth);
|
||||||
if (status == AUTH_FAILURE)
|
if (status == AUTH_FAILURE)
|
||||||
@@ -116,8 +116,8 @@ verify_user()
|
|||||||
else if (status == AUTH_FATAL) /* XXX log */
|
else if (status == AUTH_FATAL) /* XXX log */
|
||||||
exit(1); /* assume error msg already printed */
|
exit(1); /* assume error msg already printed */
|
||||||
|
|
||||||
if (NEEDS_ROOT(auth))
|
if (NEEDS_USER(auth))
|
||||||
set_perms(PERM_USER, 0);
|
set_perms(PERM_ROOT, 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -125,8 +125,8 @@ verify_user()
|
|||||||
/* Do any per-method setup and unconfigure the method if needed */
|
/* Do any per-method setup and unconfigure the method if needed */
|
||||||
for (auth = auth_switch; auth->name; auth++) {
|
for (auth = auth_switch; auth->name; auth++) {
|
||||||
if (auth->setup && IS_CONFIGURED(auth)) {
|
if (auth->setup && IS_CONFIGURED(auth)) {
|
||||||
if (NEEDS_ROOT(auth))
|
if (NEEDS_USER(auth))
|
||||||
set_perms(PERM_ROOT, 0);
|
set_perms(PERM_USER, 0);
|
||||||
|
|
||||||
status = (auth->setup)(sudo_user.pw, &user_prompt, auth);
|
status = (auth->setup)(sudo_user.pw, &user_prompt, auth);
|
||||||
if (status == AUTH_FAILURE)
|
if (status == AUTH_FAILURE)
|
||||||
@@ -134,8 +134,8 @@ verify_user()
|
|||||||
else if (status == AUTH_FATAL) /* XXX log */
|
else if (status == AUTH_FATAL) /* XXX log */
|
||||||
exit(1); /* assume error msg already printed */
|
exit(1); /* assume error msg already printed */
|
||||||
|
|
||||||
if (NEEDS_ROOT(auth))
|
if (NEEDS_USER(auth))
|
||||||
set_perms(PERM_USER, 0);
|
set_perms(PERM_ROOT, 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -154,14 +154,14 @@ verify_user()
|
|||||||
if (!IS_CONFIGURED(auth))
|
if (!IS_CONFIGURED(auth))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (NEEDS_ROOT(auth))
|
if (NEEDS_USER(auth))
|
||||||
set_perms(PERM_ROOT, 0);
|
set_perms(PERM_USER, 0);
|
||||||
|
|
||||||
success = auth->status = (auth->verify)(sudo_user.pw, p, auth);
|
success = auth->status = (auth->verify)(sudo_user.pw, p, auth);
|
||||||
(void) memset(p, 0, strlen(p));
|
(void) memset(p, 0, strlen(p));
|
||||||
|
|
||||||
if (NEEDS_ROOT(auth))
|
if (NEEDS_USER(auth))
|
||||||
set_perms(PERM_USER, 0);
|
set_perms(PERM_ROOT, 0);
|
||||||
|
|
||||||
if (auth->status != AUTH_FAILURE)
|
if (auth->status != AUTH_FAILURE)
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
@@ -182,15 +182,15 @@ cleanup:
|
|||||||
/* Call cleanup routines. */
|
/* Call cleanup routines. */
|
||||||
for (auth = auth_switch; auth->name; auth++) {
|
for (auth = auth_switch; auth->name; auth++) {
|
||||||
if (auth->cleanup && IS_CONFIGURED(auth)) {
|
if (auth->cleanup && IS_CONFIGURED(auth)) {
|
||||||
if (NEEDS_ROOT(auth))
|
if (NEEDS_USER(auth))
|
||||||
set_perms(PERM_ROOT, 0);
|
set_perms(PERM_USER, 0);
|
||||||
|
|
||||||
status = (auth->cleanup)(sudo_user.pw, auth);
|
status = (auth->cleanup)(sudo_user.pw, auth);
|
||||||
if (status == AUTH_FATAL) /* XXX log */
|
if (status == AUTH_FATAL) /* XXX log */
|
||||||
exit(1); /* assume error msg already printed */
|
exit(1); /* assume error msg already printed */
|
||||||
|
|
||||||
if (NEEDS_ROOT(auth))
|
if (NEEDS_USER(auth))
|
||||||
set_perms(PERM_USER, 0);
|
set_perms(PERM_ROOT, 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -55,12 +55,12 @@ typedef struct sudo_auth {
|
|||||||
|
|
||||||
/* Values for sudo_auth.flags. */
|
/* Values for sudo_auth.flags. */
|
||||||
/* XXX - these names are too long for my liking */
|
/* XXX - these names are too long for my liking */
|
||||||
#define FLAG_ROOT 0x01 /* functions must run as root */
|
#define FLAG_USER 0x01 /* functions must run as root */
|
||||||
#define FLAG_CONFIGURED 0x02 /* method configured ok */
|
#define FLAG_CONFIGURED 0x02 /* method configured ok */
|
||||||
#define FLAG_ONEANDONLY 0x04 /* one and only auth method */
|
#define FLAG_ONEANDONLY 0x04 /* one and only auth method */
|
||||||
|
|
||||||
/* Shortcuts for using the flags above. */
|
/* Shortcuts for using the flags above. */
|
||||||
#define NEEDS_ROOT(x) ((x)->flags & FLAG_ROOT)
|
#define NEEDS_USER(x) ((x)->flags & FLAG_USER)
|
||||||
#define IS_CONFIGURED(x) ((x)->flags & FLAG_CONFIGURED)
|
#define IS_CONFIGURED(x) ((x)->flags & FLAG_CONFIGURED)
|
||||||
#define IS_ONEANDONLY(x) ((x)->flags & FLAG_ONEANDONLY)
|
#define IS_ONEANDONLY(x) ((x)->flags & FLAG_ONEANDONLY)
|
||||||
|
|
||||||
@@ -99,27 +99,27 @@ int securid_verify __P((struct passwd *pw, char *pass, sudo_auth *auth));
|
|||||||
/* Some methods cannots (or should not) interoperate with any others */
|
/* Some methods cannots (or should not) interoperate with any others */
|
||||||
#if defined(HAVE_PAM)
|
#if defined(HAVE_PAM)
|
||||||
# define AUTH_STANDALONE \
|
# define AUTH_STANDALONE \
|
||||||
AUTH_ENTRY(FLAG_ROOT, "pam", \
|
AUTH_ENTRY(0, "pam", \
|
||||||
pam_init, NULL, pam_verify, pam_cleanup)
|
pam_init, NULL, pam_verify, pam_cleanup)
|
||||||
#elif defined(HAVE_SECURID)
|
#elif defined(HAVE_SECURID)
|
||||||
# define AUTH_STANDALONE \
|
# define AUTH_STANDALONE \
|
||||||
AUTH_ENTRY(FLAG_ROOT, "SecurId", \
|
AUTH_ENTRY(0, "SecurId",
|
||||||
securid_init, securid_setup, securid_verify, NULL)
|
securid_init, securid_setup, securid_verify, NULL)
|
||||||
#elif defined(HAVE_SIA)
|
#elif defined(HAVE_SIA)
|
||||||
# define AUTH_STANDALONE \
|
# define AUTH_STANDALONE \
|
||||||
AUTH_ENTRY(FLAG_ROOT, "sia", \
|
AUTH_ENTRY(0, "sia", \
|
||||||
NULL, sia_setup, sia_verify, sia_cleanup)
|
NULL, sia_setup, sia_verify, sia_cleanup)
|
||||||
#elif defined(HAVE_DCE)
|
#elif defined(HAVE_DCE)
|
||||||
# define AUTH_STANDALONE \
|
# define AUTH_STANDALONE \
|
||||||
AUTH_ENTRY(FLAG_ROOT, "dce", \
|
AUTH_ENTRY(0, "dce", \
|
||||||
NULL, NULL, dce_verify, NULL)
|
NULL, NULL, dce_verify, NULL)
|
||||||
#elif defined(HAVE_AUTHENTICATE)
|
#elif defined(HAVE_AUTHENTICATE)
|
||||||
# define AUTH_STANDALONE \
|
# define AUTH_STANDALONE \
|
||||||
AUTH_ENTRY(FLAG_ROOT, "aixauth", \
|
AUTH_ENTRY(0, "aixauth", \
|
||||||
NULL, NULL, aixauth_verify, NULL)
|
NULL, NULL, aixauth_verify, NULL)
|
||||||
#elif defined(HAVE_FWTK)
|
#elif defined(HAVE_FWTK)
|
||||||
# define AUTH_STANDALONE \
|
# define AUTH_STANDALONE \
|
||||||
AUTH_ENTRY(FLAG_ROOT, "fwtk", fwtk_init, \
|
AUTH_ENTRY(0, "fwtk", fwtk_init, \
|
||||||
NULL, fwtk_verify, fwtk_cleanup)
|
NULL, fwtk_verify, fwtk_cleanup)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
13
check.c
13
check.c
@@ -137,8 +137,6 @@ update_timestamp(timestampdir, timestampfile)
|
|||||||
char *timestampfile;
|
char *timestampfile;
|
||||||
{
|
{
|
||||||
|
|
||||||
set_perms(PERM_ROOT, 0); /* become root */
|
|
||||||
|
|
||||||
if (touch(timestampfile ? timestampfile : timestampdir, time(NULL)) == -1) {
|
if (touch(timestampfile ? timestampfile : timestampdir, time(NULL)) == -1) {
|
||||||
if (timestampfile) {
|
if (timestampfile) {
|
||||||
int fd = open(timestampfile, O_WRONLY|O_CREAT|O_TRUNC, 0600);
|
int fd = open(timestampfile, O_WRONLY|O_CREAT|O_TRUNC, 0600);
|
||||||
@@ -152,8 +150,6 @@ update_timestamp(timestampdir, timestampfile)
|
|||||||
log_error(NO_EXIT|USE_ERRNO, "Can't mkdir %s", timestampdir);
|
log_error(NO_EXIT|USE_ERRNO, "Can't mkdir %s", timestampdir);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
set_perms(PERM_USER, 0); /* relinquish root */
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -288,8 +284,6 @@ timestamp_status(timestampdir, timestampfile, user, make_dirs)
|
|||||||
time_t now;
|
time_t now;
|
||||||
int status = TS_ERROR; /* assume the worst */
|
int status = TS_ERROR; /* assume the worst */
|
||||||
|
|
||||||
set_perms(PERM_ROOT, 0); /* become root */
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Sanity check _PATH_SUDO_TIMEDIR and make it if it doesn't already exist.
|
* Sanity check _PATH_SUDO_TIMEDIR and make it if it doesn't already exist.
|
||||||
* We start out assuming the worst (that the dir is not sane) and
|
* We start out assuming the worst (that the dir is not sane) and
|
||||||
@@ -325,10 +319,8 @@ timestamp_status(timestampdir, timestampfile, user, make_dirs)
|
|||||||
status = TS_MISSING;
|
status = TS_MISSING;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (status == TS_ERROR) {
|
if (status == TS_ERROR)
|
||||||
set_perms(PERM_USER, 0); /* relinquish root */
|
|
||||||
return(status);
|
return(status);
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Sanity check the user's ticket dir. We start by downgrading
|
* Sanity check the user's ticket dir. We start by downgrading
|
||||||
@@ -435,7 +427,6 @@ timestamp_status(timestampdir, timestampfile, user, make_dirs)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
set_perms(PERM_USER, 0); /* relinquish root */
|
|
||||||
return(status);
|
return(status);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -455,7 +446,6 @@ remove_timestamp(remove)
|
|||||||
status = timestamp_status(timestampdir, timestampfile, user_name, FALSE);
|
status = timestamp_status(timestampdir, timestampfile, user_name, FALSE);
|
||||||
if (status == TS_OLD || status == TS_CURRENT) {
|
if (status == TS_OLD || status == TS_CURRENT) {
|
||||||
ts = timestampfile ? timestampfile : timestampdir;
|
ts = timestampfile ? timestampfile : timestampdir;
|
||||||
set_perms(PERM_ROOT, 0); /* become root */
|
|
||||||
if (remove) {
|
if (remove) {
|
||||||
if (timestampfile)
|
if (timestampfile)
|
||||||
status = unlink(timestampfile);
|
status = unlink(timestampfile);
|
||||||
@@ -471,7 +461,6 @@ remove_timestamp(remove)
|
|||||||
(void) fprintf(stderr, "%s: can't reset %s to epoch: %s\n",
|
(void) fprintf(stderr, "%s: can't reset %s to epoch: %s\n",
|
||||||
Argv[0], ts, strerror(errno));
|
Argv[0], ts, strerror(errno));
|
||||||
}
|
}
|
||||||
set_perms(PERM_USER, 0); /* relinquish root */
|
|
||||||
}
|
}
|
||||||
|
|
||||||
(void) free(timestampdir);
|
(void) free(timestampdir);
|
||||||
|
@@ -112,7 +112,6 @@ find_path(infile, outfile)
|
|||||||
path = estrdup(path);
|
path = estrdup(path);
|
||||||
origpath = path;
|
origpath = path;
|
||||||
|
|
||||||
/* XXX use strtok() */
|
|
||||||
do {
|
do {
|
||||||
if ((n = strchr(path, ':')))
|
if ((n = strchr(path, ':')))
|
||||||
*n = '\0';
|
*n = '\0';
|
||||||
|
@@ -67,19 +67,12 @@ sudo_goodpath(path)
|
|||||||
const char *path;
|
const char *path;
|
||||||
{
|
{
|
||||||
struct stat sb;
|
struct stat sb;
|
||||||
int err;
|
|
||||||
|
|
||||||
/* Check for brain damage */
|
/* Check for brain damage */
|
||||||
if (path == NULL || path[0] == '\0')
|
if (path == NULL || path[0] == '\0')
|
||||||
return(NULL);
|
return(NULL);
|
||||||
|
|
||||||
/* Do the stat() as root. */
|
if (stat(path, &sb))
|
||||||
set_perms(PERM_ROOT, 0);
|
|
||||||
err = stat(path, &sb);
|
|
||||||
set_perms(PERM_USER, 0);
|
|
||||||
|
|
||||||
/* stat() failed */
|
|
||||||
if (err)
|
|
||||||
return(NULL);
|
return(NULL);
|
||||||
|
|
||||||
/* Make sure path describes an executable regular file. */
|
/* Make sure path describes an executable regular file. */
|
||||||
|
24
logging.c
24
logging.c
@@ -161,15 +161,10 @@ do_logfile(msg)
|
|||||||
FILE *fp;
|
FILE *fp;
|
||||||
mode_t oldmask;
|
mode_t oldmask;
|
||||||
time_t now;
|
time_t now;
|
||||||
int oldeuid = geteuid();
|
|
||||||
int maxlen = MAXLOGFILELEN;
|
int maxlen = MAXLOGFILELEN;
|
||||||
|
|
||||||
now = time((time_t) 0);
|
now = time((time_t) 0);
|
||||||
|
|
||||||
/* Become root if we are not already. */
|
|
||||||
if (oldeuid)
|
|
||||||
set_perms(PERM_ROOT, 0);
|
|
||||||
|
|
||||||
oldmask = umask(077);
|
oldmask = umask(077);
|
||||||
fp = fopen(_PATH_SUDO_LOGFILE, "a");
|
fp = fopen(_PATH_SUDO_LOGFILE, "a");
|
||||||
(void) umask(oldmask);
|
(void) umask(oldmask);
|
||||||
@@ -254,9 +249,6 @@ do_logfile(msg)
|
|||||||
(void) lock_file(fileno(fp), SUDO_UNLOCK);
|
(void) lock_file(fileno(fp), SUDO_UNLOCK);
|
||||||
(void) fclose(fp);
|
(void) fclose(fp);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (oldeuid)
|
|
||||||
set_perms(PERM_USER, 0); /* relinquish root */
|
|
||||||
}
|
}
|
||||||
#endif /* LOGGING & SLOG_FILE */
|
#endif /* LOGGING & SLOG_FILE */
|
||||||
|
|
||||||
@@ -299,20 +291,18 @@ log_auth(status, inform_user)
|
|||||||
mail_auth(status, logline); /* send mail based on status */
|
mail_auth(status, logline); /* send mail based on status */
|
||||||
|
|
||||||
/* Inform the user if they failed to authenticate. */
|
/* Inform the user if they failed to authenticate. */
|
||||||
if (inform_user) {
|
if (inform_user && (status & VALIDATE_NOT_OK)) {
|
||||||
if (status & FLAG_NO_USER)
|
if (status & FLAG_NO_USER)
|
||||||
(void) fprintf(stderr, "%s is not in the sudoers file. %s",
|
(void) fprintf(stderr, "%s is not in the sudoers file. %s",
|
||||||
user_name, "This incident will be reported.\n");
|
user_name, "This incident will be reported.\n");
|
||||||
else if (status & FLAG_NO_HOST)
|
else if (status & FLAG_NO_HOST)
|
||||||
(void) fprintf(stderr, "%s is not allowed to run sudo on %s. %s",
|
(void) fprintf(stderr, "%s is not allowed to run sudo on %s. %s",
|
||||||
user_name, user_shost, "This incident will be reported.\n");
|
user_name, user_shost, "This incident will be reported.\n");
|
||||||
else if (status & VALIDATE_NOT_OK)
|
else
|
||||||
(void) fprintf(stderr,
|
(void) fprintf(stderr,
|
||||||
"Sorry, user %s is not allowed to execute '%s%s%s' as %s on %s.\n",
|
"Sorry, user %s is not allowed to execute '%s%s%s' as %s on %s.\n",
|
||||||
user_name, user_cmnd, user_args ? " " : "",
|
user_name, user_cmnd, user_args ? " " : "",
|
||||||
user_args ? user_args : "", user_runas, user_host);
|
user_args ? user_args : "", user_runas, user_host);
|
||||||
else
|
|
||||||
(void) fprintf(stderr, "An unknown error has occurred.\n");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -351,6 +341,10 @@ log_error(va_alist)
|
|||||||
fmt = va_arg(ap, const char *);
|
fmt = va_arg(ap, const char *);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/* Become root if we are not already to avoid user control */
|
||||||
|
if (geteuid() != 0)
|
||||||
|
set_perms(PERM_ROOT, 0);
|
||||||
|
|
||||||
/* Expand printf-style format + args. */
|
/* Expand printf-style format + args. */
|
||||||
evasprintf(&message, fmt, ap);
|
evasprintf(&message, fmt, ap);
|
||||||
va_end(ap);
|
va_end(ap);
|
||||||
@@ -409,6 +403,9 @@ log_error(va_alist)
|
|||||||
free(message);
|
free(message);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Send a message to ALERTMAIL
|
||||||
|
*/
|
||||||
#ifdef _PATH_SENDMAIL
|
#ifdef _PATH_SENDMAIL
|
||||||
static void
|
static void
|
||||||
send_mail(line)
|
send_mail(line)
|
||||||
@@ -481,7 +478,7 @@ send_mail(line)
|
|||||||
user_name, line);
|
user_name, line);
|
||||||
fclose(mail);
|
fclose(mail);
|
||||||
reapchild(0);
|
reapchild(0);
|
||||||
exit(0);
|
_exit(0);
|
||||||
} else {
|
} else {
|
||||||
/* Parent, just return unless there is an error. */
|
/* Parent, just return unless there is an error. */
|
||||||
if (pid == -1) {
|
if (pid == -1) {
|
||||||
@@ -510,6 +507,7 @@ mail_auth(status, line)
|
|||||||
{
|
{
|
||||||
int mail_mask;
|
int mail_mask;
|
||||||
|
|
||||||
|
/* If any of these bits are set in status, we send mail. */
|
||||||
mail_mask = VALIDATE_ERROR;
|
mail_mask = VALIDATE_ERROR;
|
||||||
#ifdef SEND_MAIL_WHEN_OK
|
#ifdef SEND_MAIL_WHEN_OK
|
||||||
mail_mask |= VALIDATE_OK;
|
mail_mask |= VALIDATE_OK;
|
||||||
|
22
parse.c
22
parse.c
@@ -124,26 +124,17 @@ sudoers_lookup(check_cmnd)
|
|||||||
yyin = sudoers_fp;
|
yyin = sudoers_fp;
|
||||||
yyout = stdout;
|
yyout = stdout;
|
||||||
|
|
||||||
/*
|
/* Allocate space for data structures in the parser. */
|
||||||
* Allocate space for data structures in the parser.
|
|
||||||
*/
|
|
||||||
init_parser();
|
init_parser();
|
||||||
|
|
||||||
/*
|
/* Need to be root while stat'ing things in the parser. */
|
||||||
* Need to be root while stat'ing things in the parser.
|
|
||||||
*/
|
|
||||||
set_perms(PERM_ROOT, 0);
|
set_perms(PERM_ROOT, 0);
|
||||||
error = yyparse();
|
error = yyparse();
|
||||||
|
|
||||||
/*
|
/* Close the sudoers file now that we are done with it. */
|
||||||
* Don't need to keep this open...
|
|
||||||
*/
|
|
||||||
(void) fclose(sudoers_fp);
|
(void) fclose(sudoers_fp);
|
||||||
sudoers_fp = NULL;
|
sudoers_fp = NULL;
|
||||||
|
|
||||||
/* relinquish extra privs */
|
|
||||||
set_perms(PERM_USER, 0);
|
|
||||||
|
|
||||||
if (error || parse_error)
|
if (error || parse_error)
|
||||||
return(VALIDATE_ERROR);
|
return(VALIDATE_ERROR);
|
||||||
|
|
||||||
@@ -159,10 +150,9 @@ sudoers_lookup(check_cmnd)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Only check the actual command if the check_cmnd
|
* Only check the actual command if the check_cmnd flag is set.
|
||||||
* flag is set. It is not set for the "validate"
|
* It is not set for the "validate" and "list" pseudo-commands.
|
||||||
* and "list" pseudo-commands. Always check the
|
* Always check the host and user.
|
||||||
* host and user.
|
|
||||||
*/
|
*/
|
||||||
if (check_cmnd == FALSE)
|
if (check_cmnd == FALSE)
|
||||||
while (top) {
|
while (top) {
|
||||||
|
6
sudo.c
6
sudo.c
@@ -258,7 +258,7 @@ main(argc, argv)
|
|||||||
|
|
||||||
cmnd_status = init_vars(sudo_mode);
|
cmnd_status = init_vars(sudo_mode);
|
||||||
|
|
||||||
set_perms(PERM_USER, sudo_mode);
|
/* At this point, ruid == euid == 0 */
|
||||||
|
|
||||||
check_sudoers(); /* check mode/owner on _PATH_SUDOERS */
|
check_sudoers(); /* check mode/owner on _PATH_SUDOERS */
|
||||||
|
|
||||||
@@ -763,7 +763,6 @@ check_sudoers()
|
|||||||
* Fix the mode and group on sudoers file from old default.
|
* Fix the mode and group on sudoers file from old default.
|
||||||
* Only works if filesystem is readable/writable by root.
|
* Only works if filesystem is readable/writable by root.
|
||||||
*/
|
*/
|
||||||
set_perms(PERM_ROOT, 0);
|
|
||||||
if ((rootstat = lstat(_PATH_SUDOERS, &statbuf)) == 0 &&
|
if ((rootstat = lstat(_PATH_SUDOERS, &statbuf)) == 0 &&
|
||||||
SUDOERS_UID == statbuf.st_uid && SUDOERS_MODE != 0400 &&
|
SUDOERS_UID == statbuf.st_uid && SUDOERS_MODE != 0400 &&
|
||||||
(statbuf.st_mode & 0007777) == 0400) {
|
(statbuf.st_mode & 0007777) == 0400) {
|
||||||
@@ -824,8 +823,7 @@ check_sudoers()
|
|||||||
log_error(USE_ERRNO, "can't open %s", _PATH_SUDOERS);
|
log_error(USE_ERRNO, "can't open %s", _PATH_SUDOERS);
|
||||||
}
|
}
|
||||||
|
|
||||||
set_perms(PERM_ROOT, 0);
|
set_perms(PERM_ROOT, 0); /* change back to root */
|
||||||
set_perms(PERM_USER, 0);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
Reference in New Issue
Block a user