version 1.1.1.1, 2012/02/21 16:23:02
|
version 1.1.1.3, 2012/10/09 09:29:52
|
Line 89 static int timestamp_status(char *, char *, char *,
|
Line 89 static int timestamp_status(char *, char *, char *,
|
static char *expand_prompt(char *, char *, char *); |
static char *expand_prompt(char *, char *, char *); |
static void lecture(int); |
static void lecture(int); |
static void update_timestamp(char *, char *); |
static void update_timestamp(char *, char *); |
static int tty_is_devpts(const char *); | static bool tty_is_devpts(const char *); |
static struct passwd *get_authpw(void); |
static struct passwd *get_authpw(void); |
|
|
/* |
/* |
* Returns TRUE if the user successfully authenticates, else FALSE. | * Returns true if the user successfully authenticates, false if not |
| * or -1 on error. |
*/ |
*/ |
int |
int |
check_user(int validated, int mode) |
check_user(int validated, int mode) |
Line 103 check_user(int validated, int mode)
|
Line 104 check_user(int validated, int mode)
|
char *timestampfile = NULL; |
char *timestampfile = NULL; |
char *prompt; |
char *prompt; |
struct stat sb; |
struct stat sb; |
int status, rval = TRUE; | int status, rval = true; |
int need_pass = def_authenticate; | debug_decl(check_user, SUDO_DEBUG_AUTH) |
|
|
/* |
/* |
* Init authentication system regardless of whether we need a password. |
* Init authentication system regardless of whether we need a password. |
Line 116 check_user(int validated, int mode)
|
Line 117 check_user(int validated, int mode)
|
goto done; |
goto done; |
} |
} |
|
|
if (need_pass) { | /* |
/* Always need a password when -k was specified with the command. */ | * Don't prompt for the root passwd or if the user is exempt. |
if (ISSET(mode, MODE_IGNORE_TICKET)) { | * If the user is not changing uid/gid, no need for a password. |
SET(validated, FLAG_CHECK_USER); | */ |
} else { | if (!def_authenticate || user_uid == 0 || user_is_exempt()) |
/* | |
* Don't prompt for the root passwd or if the user is exempt. | |
* If the user is not changing uid/gid, no need for a password. | |
*/ | |
if (user_uid == 0 || (user_uid == runas_pw->pw_uid && | |
(!runas_gr || user_in_group(sudo_user.pw, runas_gr->gr_name))) | |
|| user_is_exempt()) | |
need_pass = FALSE; | |
} | |
} | |
if (!need_pass) | |
goto done; |
goto done; |
|
if (user_uid == runas_pw->pw_uid && |
|
(!runas_gr || user_in_group(sudo_user.pw, runas_gr->gr_name))) { |
|
#ifdef HAVE_SELINUX |
|
if (user_role == NULL && user_type == NULL) |
|
#endif |
|
#ifdef HAVE_PRIV_SET |
|
if (runas_privs == NULL && runas_limitprivs == NULL) |
|
#endif |
|
goto done; |
|
} |
|
|
|
/* Always need a password when -k was specified with the command. */ |
|
if (ISSET(mode, MODE_IGNORE_TICKET)) |
|
SET(validated, FLAG_CHECK_USER); |
|
|
/* Stash the tty's ctime for tty ticket comparison. */ |
/* Stash the tty's ctime for tty ticket comparison. */ |
if (def_tty_tickets && user_ttypath && stat(user_ttypath, &sb) == 0) { |
if (def_tty_tickets && user_ttypath && stat(user_ttypath, &sb) == 0) { |
tty_info.dev = sb.st_dev; |
tty_info.dev = sb.st_dev; |
Line 154 check_user(int validated, int mode)
|
Line 158 check_user(int validated, int mode)
|
if (status != TS_CURRENT || ISSET(validated, FLAG_CHECK_USER)) { |
if (status != TS_CURRENT || ISSET(validated, FLAG_CHECK_USER)) { |
/* Bail out if we are non-interactive and a password is required */ |
/* Bail out if we are non-interactive and a password is required */ |
if (ISSET(mode, MODE_NONINTERACTIVE)) { |
if (ISSET(mode, MODE_NONINTERACTIVE)) { |
warningx(_("sorry, a password is required to run %s"), getprogname()); | validated |= FLAG_NON_INTERACTIVE; |
| log_auth_failure(validated, 0); |
rval = -1; |
rval = -1; |
goto done; |
goto done; |
} |
} |
Line 166 check_user(int validated, int mode)
|
Line 171 check_user(int validated, int mode)
|
prompt = expand_prompt(user_prompt ? user_prompt : def_passprompt, |
prompt = expand_prompt(user_prompt ? user_prompt : def_passprompt, |
user_name, user_shost); |
user_name, user_shost); |
|
|
rval = verify_user(auth_pw, prompt); | rval = verify_user(auth_pw, prompt, validated); |
} |
} |
/* Only update timestamp if user was validated. */ |
/* Only update timestamp if user was validated. */ |
if (rval == TRUE && ISSET(validated, VALIDATE_OK) && | if (rval == true && ISSET(validated, VALIDATE_OK) && |
!ISSET(mode, MODE_IGNORE_TICKET) && status != TS_ERROR) |
!ISSET(mode, MODE_IGNORE_TICKET) && status != TS_ERROR) |
update_timestamp(timestampdir, timestampfile); |
update_timestamp(timestampdir, timestampfile); |
efree(timestampdir); |
efree(timestampdir); |
Line 177 check_user(int validated, int mode)
|
Line 182 check_user(int validated, int mode)
|
|
|
done: |
done: |
sudo_auth_cleanup(auth_pw); |
sudo_auth_cleanup(auth_pw); |
pw_delref(auth_pw); | sudo_pw_delref(auth_pw); |
|
|
return rval; | debug_return_bool(rval); |
} |
} |
|
|
#define DEFAULT_LECTURE "\n" \ |
#define DEFAULT_LECTURE "\n" \ |
Line 200 lecture(int status)
|
Line 205 lecture(int status)
|
ssize_t nread; |
ssize_t nread; |
struct sudo_conv_message msg; |
struct sudo_conv_message msg; |
struct sudo_conv_reply repl; |
struct sudo_conv_reply repl; |
|
debug_decl(lecture, SUDO_DEBUG_AUTH) |
|
|
if (def_lecture == never || |
if (def_lecture == never || |
(def_lecture == once && status != TS_MISSING && status != TS_ERROR)) |
(def_lecture == once && status != TS_MISSING && status != TS_ERROR)) |
return; | debug_return; |
|
|
memset(&msg, 0, sizeof(msg)); |
memset(&msg, 0, sizeof(msg)); |
memset(&repl, 0, sizeof(repl)); |
memset(&repl, 0, sizeof(repl)); |
|
|
if (def_lecture_file && (fp = fopen(def_lecture_file, "r")) != NULL) { |
if (def_lecture_file && (fp = fopen(def_lecture_file, "r")) != NULL) { |
while ((nread = fread(buf, sizeof(char), sizeof(buf) - 1, fp)) != 0) { |
while ((nread = fread(buf, sizeof(char), sizeof(buf) - 1, fp)) != 0) { |
buf[sizeof(buf) - 1] = '\0'; | buf[nread] = '\0'; |
msg.msg_type = SUDO_CONV_ERROR_MSG; |
msg.msg_type = SUDO_CONV_ERROR_MSG; |
msg.msg = buf; |
msg.msg = buf; |
sudo_conv(1, &msg, &repl); |
sudo_conv(1, &msg, &repl); |
Line 221 lecture(int status)
|
Line 227 lecture(int status)
|
msg.msg = _(DEFAULT_LECTURE); |
msg.msg = _(DEFAULT_LECTURE); |
sudo_conv(1, &msg, &repl); |
sudo_conv(1, &msg, &repl); |
} |
} |
|
debug_return; |
} |
} |
|
|
/* |
/* |
Line 229 lecture(int status)
|
Line 236 lecture(int status)
|
static void |
static void |
update_timestamp(char *timestampdir, char *timestampfile) |
update_timestamp(char *timestampdir, char *timestampfile) |
{ |
{ |
|
debug_decl(update_timestamp, SUDO_DEBUG_AUTH) |
|
|
/* If using tty timestamps but we have no tty there is nothing to do. */ |
/* If using tty timestamps but we have no tty there is nothing to do. */ |
if (def_tty_tickets && !user_ttypath) |
if (def_tty_tickets && !user_ttypath) |
return; | debug_return; |
|
|
if (timestamp_uid != 0) |
if (timestamp_uid != 0) |
set_perms(PERM_TIMESTAMP); |
set_perms(PERM_TIMESTAMP); |
Line 241 update_timestamp(char *timestampdir, char *timestampfi
|
Line 250 update_timestamp(char *timestampdir, char *timestampfi
|
*/ |
*/ |
int fd = open(timestampfile, O_WRONLY|O_CREAT, 0600); |
int fd = open(timestampfile, O_WRONLY|O_CREAT, 0600); |
if (fd == -1) |
if (fd == -1) |
log_error(NO_EXIT|USE_ERRNO, _("unable to open %s"), timestampfile); | log_error(USE_ERRNO, _("unable to open %s"), timestampfile); |
else { |
else { |
lock_file(fd, SUDO_LOCK); |
lock_file(fd, SUDO_LOCK); |
if (write(fd, &tty_info, sizeof(tty_info)) != sizeof(tty_info)) { |
if (write(fd, &tty_info, sizeof(tty_info)) != sizeof(tty_info)) { |
log_error(NO_EXIT|USE_ERRNO, _("unable to write to %s"), | log_error(USE_ERRNO, _("unable to write to %s"), |
timestampfile); |
timestampfile); |
} |
} |
close(fd); |
close(fd); |
Line 253 update_timestamp(char *timestampdir, char *timestampfi
|
Line 262 update_timestamp(char *timestampdir, char *timestampfi
|
} else { |
} else { |
if (touch(-1, timestampdir, NULL) == -1) { |
if (touch(-1, timestampdir, NULL) == -1) { |
if (mkdir(timestampdir, 0700) == -1) { |
if (mkdir(timestampdir, 0700) == -1) { |
log_error(NO_EXIT|USE_ERRNO, _("unable to mkdir %s"), | log_error(USE_ERRNO, _("unable to mkdir %s"), |
timestampdir); |
timestampdir); |
} |
} |
} |
} |
} |
} |
if (timestamp_uid != 0) |
if (timestamp_uid != 0) |
restore_perms(); |
restore_perms(); |
|
debug_return; |
} |
} |
|
|
/* |
/* |
Line 272 expand_prompt(char *old_prompt, char *user, char *host
|
Line 282 expand_prompt(char *old_prompt, char *user, char *host
|
size_t len, n; |
size_t len, n; |
int subst; |
int subst; |
char *p, *np, *new_prompt, *endp; |
char *p, *np, *new_prompt, *endp; |
|
debug_decl(expand_prompt, SUDO_DEBUG_AUTH) |
|
|
/* How much space do we need to malloc for the prompt? */ |
/* How much space do we need to malloc for the prompt? */ |
subst = 0; |
subst = 0; |
Line 382 expand_prompt(char *old_prompt, char *user, char *host
|
Line 393 expand_prompt(char *old_prompt, char *user, char *host
|
} else |
} else |
new_prompt = old_prompt; |
new_prompt = old_prompt; |
|
|
return new_prompt; | debug_return_str(new_prompt); |
|
|
oflow: |
oflow: |
/* We pre-allocate enough space, so this should never happen. */ |
/* We pre-allocate enough space, so this should never happen. */ |
errorx(1, _("internal error, expand_prompt() overflow")); | errorx(1, _("internal error, %s overflow"), "expand_prompt()"); |
} |
} |
|
|
/* |
/* |
* Checks if the user is exempt from supplying a password. |
* Checks if the user is exempt from supplying a password. |
*/ |
*/ |
int | bool |
user_is_exempt(void) |
user_is_exempt(void) |
{ |
{ |
if (!def_exempt_group) | bool rval = false; |
return FALSE; | debug_decl(user_is_exempt, SUDO_DEBUG_AUTH) |
return user_in_group(sudo_user.pw, def_exempt_group); | |
| if (def_exempt_group) |
| rval = user_in_group(sudo_user.pw, def_exempt_group); |
| debug_return_bool(rval); |
} |
} |
|
|
/* |
/* |
Line 408 build_timestamp(char **timestampdir, char **timestampf
|
Line 422 build_timestamp(char **timestampdir, char **timestampf
|
{ |
{ |
char *dirparent; |
char *dirparent; |
int len; |
int len; |
|
debug_decl(build_timestamp, SUDO_DEBUG_AUTH) |
|
|
dirparent = def_timestampdir; |
dirparent = def_timestampdir; |
|
*timestampfile = NULL; |
len = easprintf(timestampdir, "%s/%s", dirparent, user_name); |
len = easprintf(timestampdir, "%s/%s", dirparent, user_name); |
if (len >= PATH_MAX) |
if (len >= PATH_MAX) |
goto bad; |
goto bad; |
Line 440 build_timestamp(char **timestampdir, char **timestampf
|
Line 456 build_timestamp(char **timestampdir, char **timestampf
|
} else |
} else |
*timestampfile = NULL; |
*timestampfile = NULL; |
|
|
return len; | debug_return_int(len); |
bad: |
bad: |
log_error(0, _("timestamp path too long: %s"), *timestampfile); | log_fatal(0, _("timestamp path too long: %s"), |
return -1; | *timestampfile ? *timestampfile : *timestampdir); |
| /* NOTREACHED */ |
| debug_return_int(-1); |
} |
} |
|
|
/* |
/* |
Line 457 timestamp_status(char *timestampdir, char *timestampfi
|
Line 475 timestamp_status(char *timestampdir, char *timestampfi
|
time_t now; |
time_t now; |
char *dirparent = def_timestampdir; |
char *dirparent = def_timestampdir; |
int status = TS_ERROR; /* assume the worst */ |
int status = TS_ERROR; /* assume the worst */ |
|
debug_decl(timestamp_status, SUDO_DEBUG_AUTH) |
|
|
if (timestamp_uid != 0) |
if (timestamp_uid != 0) |
set_perms(PERM_TIMESTAMP); |
set_perms(PERM_TIMESTAMP); |
Line 470 timestamp_status(char *timestampdir, char *timestampfi
|
Line 489 timestamp_status(char *timestampdir, char *timestampfi
|
*/ |
*/ |
if (lstat(dirparent, &sb) == 0) { |
if (lstat(dirparent, &sb) == 0) { |
if (!S_ISDIR(sb.st_mode)) |
if (!S_ISDIR(sb.st_mode)) |
log_error(NO_EXIT, _("%s exists but is not a directory (0%o)"), | log_error(0, _("%s exists but is not a directory (0%o)"), |
dirparent, (unsigned int) sb.st_mode); |
dirparent, (unsigned int) sb.st_mode); |
else if (sb.st_uid != timestamp_uid) |
else if (sb.st_uid != timestamp_uid) |
log_error(NO_EXIT, _("%s owned by uid %u, should be uid %u"), | log_error(0, _("%s owned by uid %u, should be uid %u"), |
dirparent, (unsigned int) sb.st_uid, |
dirparent, (unsigned int) sb.st_uid, |
(unsigned int) timestamp_uid); |
(unsigned int) timestamp_uid); |
else if ((sb.st_mode & 0000022)) |
else if ((sb.st_mode & 0000022)) |
log_error(NO_EXIT, | log_error(0, |
_("%s writable by non-owner (0%o), should be mode 0700"), |
_("%s writable by non-owner (0%o), should be mode 0700"), |
dirparent, (unsigned int) sb.st_mode); |
dirparent, (unsigned int) sb.st_mode); |
else { |
else { |
Line 486 timestamp_status(char *timestampdir, char *timestampfi
|
Line 505 timestamp_status(char *timestampdir, char *timestampfi
|
status = TS_MISSING; |
status = TS_MISSING; |
} |
} |
} else if (errno != ENOENT) { |
} else if (errno != ENOENT) { |
log_error(NO_EXIT|USE_ERRNO, _("unable to stat %s"), dirparent); | log_error(USE_ERRNO, _("unable to stat %s"), dirparent); |
} else { |
} else { |
/* No dirparent, try to make one. */ |
/* No dirparent, try to make one. */ |
if (ISSET(flags, TS_MAKE_DIRS)) { |
if (ISSET(flags, TS_MAKE_DIRS)) { |
if (mkdir(dirparent, S_IRWXU)) |
if (mkdir(dirparent, S_IRWXU)) |
log_error(NO_EXIT|USE_ERRNO, _("unable to mkdir %s"), | log_error(USE_ERRNO, _("unable to mkdir %s"), |
dirparent); |
dirparent); |
else |
else |
status = TS_MISSING; |
status = TS_MISSING; |
Line 514 timestamp_status(char *timestampdir, char *timestampfi
|
Line 533 timestamp_status(char *timestampdir, char *timestampfi
|
if (unlink(timestampdir) == 0) |
if (unlink(timestampdir) == 0) |
status = TS_MISSING; |
status = TS_MISSING; |
} else |
} else |
log_error(NO_EXIT, _("%s exists but is not a directory (0%o)"), | log_error(0, _("%s exists but is not a directory (0%o)"), |
timestampdir, (unsigned int) sb.st_mode); |
timestampdir, (unsigned int) sb.st_mode); |
} else if (sb.st_uid != timestamp_uid) |
} else if (sb.st_uid != timestamp_uid) |
log_error(NO_EXIT, _("%s owned by uid %u, should be uid %u"), | log_error(0, _("%s owned by uid %u, should be uid %u"), |
timestampdir, (unsigned int) sb.st_uid, |
timestampdir, (unsigned int) sb.st_uid, |
(unsigned int) timestamp_uid); |
(unsigned int) timestamp_uid); |
else if ((sb.st_mode & 0000022)) |
else if ((sb.st_mode & 0000022)) |
log_error(NO_EXIT, | log_error(0, |
_("%s writable by non-owner (0%o), should be mode 0700"), |
_("%s writable by non-owner (0%o), should be mode 0700"), |
timestampdir, (unsigned int) sb.st_mode); |
timestampdir, (unsigned int) sb.st_mode); |
else { |
else { |
Line 530 timestamp_status(char *timestampdir, char *timestampfi
|
Line 549 timestamp_status(char *timestampdir, char *timestampfi
|
status = TS_OLD; /* do date check later */ |
status = TS_OLD; /* do date check later */ |
} |
} |
} else if (errno != ENOENT) { |
} else if (errno != ENOENT) { |
log_error(NO_EXIT|USE_ERRNO, _("unable to stat %s"), timestampdir); | log_error(USE_ERRNO, _("unable to stat %s"), timestampdir); |
} else |
} else |
status = TS_MISSING; |
status = TS_MISSING; |
|
|
Line 541 timestamp_status(char *timestampdir, char *timestampfi
|
Line 560 timestamp_status(char *timestampdir, char *timestampfi
|
if (status == TS_MISSING && timestampfile && ISSET(flags, TS_MAKE_DIRS)) { |
if (status == TS_MISSING && timestampfile && ISSET(flags, TS_MAKE_DIRS)) { |
if (mkdir(timestampdir, S_IRWXU) == -1) { |
if (mkdir(timestampdir, S_IRWXU) == -1) { |
status = TS_ERROR; |
status = TS_ERROR; |
log_error(NO_EXIT|USE_ERRNO, _("unable to mkdir %s"), timestampdir); | log_error(USE_ERRNO, _("unable to mkdir %s"), timestampdir); |
} |
} |
} |
} |
|
|
Line 556 timestamp_status(char *timestampdir, char *timestampfi
|
Line 575 timestamp_status(char *timestampdir, char *timestampfi
|
if (lstat(timestampfile, &sb) == 0) { |
if (lstat(timestampfile, &sb) == 0) { |
if (!S_ISREG(sb.st_mode)) { |
if (!S_ISREG(sb.st_mode)) { |
status = TS_ERROR; |
status = TS_ERROR; |
log_error(NO_EXIT, _("%s exists but is not a regular file (0%o)"), | log_error(0, _("%s exists but is not a regular file (0%o)"), |
timestampfile, (unsigned int) sb.st_mode); |
timestampfile, (unsigned int) sb.st_mode); |
} else { |
} else { |
/* If bad uid or file mode, complain and kill the bogus file. */ |
/* If bad uid or file mode, complain and kill the bogus file. */ |
if (sb.st_uid != timestamp_uid) { |
if (sb.st_uid != timestamp_uid) { |
log_error(NO_EXIT, | log_error(0, |
_("%s owned by uid %u, should be uid %u"), |
_("%s owned by uid %u, should be uid %u"), |
timestampfile, (unsigned int) sb.st_uid, |
timestampfile, (unsigned int) sb.st_uid, |
(unsigned int) timestamp_uid); |
(unsigned int) timestamp_uid); |
(void) unlink(timestampfile); |
(void) unlink(timestampfile); |
} else if ((sb.st_mode & 0000022)) { |
} else if ((sb.st_mode & 0000022)) { |
log_error(NO_EXIT, | log_error(0, |
_("%s writable by non-owner (0%o), should be mode 0600"), |
_("%s writable by non-owner (0%o), should be mode 0600"), |
timestampfile, (unsigned int) sb.st_mode); |
timestampfile, (unsigned int) sb.st_mode); |
(void) unlink(timestampfile); |
(void) unlink(timestampfile); |
Line 598 timestamp_status(char *timestampdir, char *timestampfi
|
Line 617 timestamp_status(char *timestampdir, char *timestampfi
|
} |
} |
} |
} |
} else if (errno != ENOENT) { |
} else if (errno != ENOENT) { |
log_error(NO_EXIT|USE_ERRNO, _("unable to stat %s"), timestampfile); | log_error(USE_ERRNO, _("unable to stat %s"), timestampfile); |
status = TS_ERROR; |
status = TS_ERROR; |
} |
} |
} |
} |
Line 621 timestamp_status(char *timestampdir, char *timestampfi
|
Line 640 timestamp_status(char *timestampdir, char *timestampfi
|
*/ |
*/ |
if (mtime.tv_sec > now + 60 * def_timestamp_timeout * 2) { |
if (mtime.tv_sec > now + 60 * def_timestamp_timeout * 2) { |
time_t tv_sec = (time_t)mtime.tv_sec; |
time_t tv_sec = (time_t)mtime.tv_sec; |
log_error(NO_EXIT, | log_error(0, |
_("timestamp too far in the future: %20.20s"), |
_("timestamp too far in the future: %20.20s"), |
4 + ctime(&tv_sec)); |
4 + ctime(&tv_sec)); |
if (timestampfile) |
if (timestampfile) |
Line 641 timestamp_status(char *timestampdir, char *timestampfi
|
Line 660 timestamp_status(char *timestampdir, char *timestampfi
|
done: |
done: |
if (timestamp_uid != 0) |
if (timestamp_uid != 0) |
restore_perms(); |
restore_perms(); |
return status; | debug_return_int(status); |
} |
} |
|
|
/* |
/* |
* Remove the timestamp ticket file/dir. |
* Remove the timestamp ticket file/dir. |
*/ |
*/ |
void |
void |
remove_timestamp(int remove) | remove_timestamp(bool remove) |
{ |
{ |
struct timeval tv; |
struct timeval tv; |
char *timestampdir, *timestampfile, *path; |
char *timestampdir, *timestampfile, *path; |
int status; |
int status; |
|
debug_decl(remove_timestamp, SUDO_DEBUG_AUTH) |
|
|
if (build_timestamp(×tampdir, ×tampfile) == -1) |
if (build_timestamp(×tampdir, ×tampfile) == -1) |
return; | debug_return; |
|
|
status = timestamp_status(timestampdir, timestampfile, user_name, |
status = timestamp_status(timestampdir, timestampfile, user_name, |
TS_REMOVE); |
TS_REMOVE); |
Line 667 remove_timestamp(int remove)
|
Line 687 remove_timestamp(int remove)
|
else |
else |
status = rmdir(timestampdir); |
status = rmdir(timestampdir); |
if (status == -1 && errno != ENOENT) { |
if (status == -1 && errno != ENOENT) { |
log_error(NO_EXIT, | log_error(0, |
_("unable to remove %s (%s), will reset to the epoch"), |
_("unable to remove %s (%s), will reset to the epoch"), |
path, strerror(errno)); |
path, strerror(errno)); |
remove = FALSE; | remove = false; |
} |
} |
} |
} |
if (!remove) { |
if (!remove) { |
Line 679 remove_timestamp(int remove)
|
Line 699 remove_timestamp(int remove)
|
error(1, _("unable to reset %s to the epoch"), path); |
error(1, _("unable to reset %s to the epoch"), path); |
} |
} |
} |
} |
|
|
efree(timestampdir); |
efree(timestampdir); |
efree(timestampfile); |
efree(timestampfile); |
|
|
|
debug_return; |
} |
} |
|
|
/* |
/* |
* Returns TRUE if tty lives on a devpts or /devices filesystem, else FALSE. | * Returns true if tty lives on a devpts, /dev or /devices filesystem, else |
* Unlike most filesystems, the ctime of devpts nodes is not updated when | * false. Unlike most filesystems, the ctime of devpts nodes is not updated |
* the device node is written to, only when the inode's status changes, | * when the device node is written to, only when the inode's status changes, |
* typically via the chmod, chown, link, rename, or utimes system calls. |
* typically via the chmod, chown, link, rename, or utimes system calls. |
* Since the ctime is "stable" in this case, we can stash it the tty ticket |
* Since the ctime is "stable" in this case, we can stash it the tty ticket |
* file and use it to determine whether the tty ticket file is stale. |
* file and use it to determine whether the tty ticket file is stale. |
*/ |
*/ |
static int | static bool |
tty_is_devpts(const char *tty) |
tty_is_devpts(const char *tty) |
{ |
{ |
int retval = FALSE; | bool retval = false; |
#ifdef __linux__ |
#ifdef __linux__ |
struct statfs sfs; |
struct statfs sfs; |
|
debug_decl(tty_is_devpts, SUDO_DEBUG_PTY) |
|
|
#ifndef DEVPTS_SUPER_MAGIC |
#ifndef DEVPTS_SUPER_MAGIC |
# define DEVPTS_SUPER_MAGIC 0x1cd1 |
# define DEVPTS_SUPER_MAGIC 0x1cd1 |
Line 705 tty_is_devpts(const char *tty)
|
Line 727 tty_is_devpts(const char *tty)
|
|
|
if (statfs(tty, &sfs) == 0) { |
if (statfs(tty, &sfs) == 0) { |
if (sfs.f_type == DEVPTS_SUPER_MAGIC) |
if (sfs.f_type == DEVPTS_SUPER_MAGIC) |
retval = TRUE; | retval = true; |
} |
} |
#elif defined(__sun) && defined(__SVR4) |
#elif defined(__sun) && defined(__SVR4) |
struct statvfs sfs; |
struct statvfs sfs; |
|
debug_decl(tty_is_devpts, SUDO_DEBUG_PTY) |
|
|
if (statvfs(tty, &sfs) == 0) { |
if (statvfs(tty, &sfs) == 0) { |
if (strcmp(sfs.f_fstr, "devices") == 0) | if (strcmp(sfs.f_fstr, "dev") == 0 || strcmp(sfs.f_fstr, "devices") == 0) |
retval = TRUE; | retval = true; |
} |
} |
|
#else |
|
debug_decl(tty_is_devpts, SUDO_DEBUG_PTY) |
#endif /* __linux__ */ |
#endif /* __linux__ */ |
return retval; | debug_return_bool(retval); |
} |
} |
|
|
/* |
/* |
Line 727 static struct passwd *
|
Line 752 static struct passwd *
|
get_authpw(void) |
get_authpw(void) |
{ |
{ |
struct passwd *pw; |
struct passwd *pw; |
|
debug_decl(get_authpw, SUDO_DEBUG_AUTH) |
|
|
if (def_rootpw) { |
if (def_rootpw) { |
if ((pw = sudo_getpwuid(ROOT_UID)) == NULL) |
if ((pw = sudo_getpwuid(ROOT_UID)) == NULL) |
log_error(0, _("unknown uid: %u"), ROOT_UID); | log_fatal(0, _("unknown uid: %u"), ROOT_UID); |
} else if (def_runaspw) { |
} else if (def_runaspw) { |
if ((pw = sudo_getpwnam(def_runas_default)) == NULL) |
if ((pw = sudo_getpwnam(def_runas_default)) == NULL) |
log_error(0, _("unknown user: %s"), def_runas_default); | log_fatal(0, _("unknown user: %s"), def_runas_default); |
} else if (def_targetpw) { |
} else if (def_targetpw) { |
if (runas_pw->pw_name == NULL) |
if (runas_pw->pw_name == NULL) |
log_error(NO_MAIL|MSG_ONLY, _("unknown uid: %u"), | log_fatal(NO_MAIL|MSG_ONLY, _("unknown uid: %u"), |
(unsigned int) runas_pw->pw_uid); |
(unsigned int) runas_pw->pw_uid); |
pw_addref(runas_pw); | sudo_pw_addref(runas_pw); |
pw = runas_pw; |
pw = runas_pw; |
} else { |
} else { |
pw_addref(sudo_user.pw); | sudo_pw_addref(sudo_user.pw); |
pw = sudo_user.pw; |
pw = sudo_user.pw; |
} |
} |
|
|
return pw; | debug_return_ptr(pw); |
} |
} |