summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTodd C. Miller <millert@cvs.openbsd.org>2000-06-05 14:01:17 +0000
committerTodd C. Miller <millert@cvs.openbsd.org>2000-06-05 14:01:17 +0000
commit73091b084d23482ba665f6e69fc121991b50f43a (patch)
treeb85a4bd999c91de9ef12ba05c77592fc031be9f5
parent98fefc7adcf3a7ed66947ca63bfadf4b703223cc (diff)
Update to sudo 1.6.3p4
-rw-r--r--usr.bin/sudo/CHANGES18
-rw-r--r--usr.bin/sudo/alloc.c9
-rw-r--r--usr.bin/sudo/auth/sudo_auth.c11
-rw-r--r--usr.bin/sudo/check.c37
-rw-r--r--usr.bin/sudo/getspwuid.c46
-rw-r--r--usr.bin/sudo/sudo.c38
-rw-r--r--usr.bin/sudo/sudo.h7
-rw-r--r--usr.bin/sudo/version.h2
-rw-r--r--usr.bin/sudo/visudo.c4
9 files changed, 118 insertions, 54 deletions
diff --git a/usr.bin/sudo/CHANGES b/usr.bin/sudo/CHANGES
index 9d56f211303..718ab7f06f7 100644
--- a/usr.bin/sudo/CHANGES
+++ b/usr.bin/sudo/CHANGES
@@ -1297,3 +1297,21 @@ Sudo 1.6.2 released.
not being used correctly and the entry was being applied globally.
Sudo 1.6.3 released.
+
+409) Fixed targetpw, rootpw, and runaspw options when used with non-passwd
+ authentication (pam, etc).
+
+Sudo 1.6.3p1 released.
+
+410) When the targetpw flag is set, use the target username as part
+ of the timestamp path.
+
+Sudo 1.6.3p2 released.
+
+411) Fixed a bug that prevented the -H option from being useful.
+
+Sudo 1.6.3p3 released.
+
+412) Fixed a case where a string was used after it has been freed.
+
+Sudo 1.6.3p4 released.
diff --git a/usr.bin/sudo/alloc.c b/usr.bin/sudo/alloc.c
index 01dc36f7be7..b06f8b50bff 100644
--- a/usr.bin/sudo/alloc.c
+++ b/usr.bin/sudo/alloc.c
@@ -121,7 +121,7 @@ estrdup(src)
* easprintf() calls vasprintf() and exits with an error if vasprintf()
* returns -1 (out of memory).
*/
-void
+int
#ifdef __STDC__
easprintf(char **ret, const char *fmt, ...)
#else
@@ -148,21 +148,24 @@ easprintf(va_alist)
(void) fprintf(stderr, "%s: cannot allocate memory!\n", Argv[0]);
exit(1);
}
+ return(len);
}
/*
* evasprintf() calls vasprintf() and exits with an error if vasprintf()
* returns -1 (out of memory).
*/
-void
+int
evasprintf(ret, format, args)
char **ret;
const char *format;
va_list args;
{
+ int len;
- if (vasprintf(ret, format, args) == -1) {
+ if ((len = vasprintf(ret, format, args)) == -1) {
(void) fprintf(stderr, "%s: cannot allocate memory!\n", Argv[0]);
exit(1);
}
+ return(len);
}
diff --git a/usr.bin/sudo/auth/sudo_auth.c b/usr.bin/sudo/auth/sudo_auth.c
index cb847d452cb..8e62c01bd6d 100644
--- a/usr.bin/sudo/auth/sudo_auth.c
+++ b/usr.bin/sudo/auth/sudo_auth.c
@@ -95,7 +95,8 @@ sudo_auth auth_switch[] = {
int nil_pw; /* I hate resorting to globals like this... */
void
-verify_user(prompt)
+verify_user(pw, prompt)
+ struct passwd *pw;
char *prompt;
{
short counter = def_ival(I_PW_TRIES) + 1;
@@ -121,7 +122,7 @@ verify_user(prompt)
if (NEEDS_USER(auth))
set_perms(PERM_USER, 0);
- status = (auth->init)(sudo_user.pw, &prompt, auth);
+ status = (auth->init)(pw, &prompt, auth);
if (status == AUTH_FAILURE)
auth->flags &= ~FLAG_CONFIGURED;
else if (status == AUTH_FATAL) /* XXX log */
@@ -139,7 +140,7 @@ verify_user(prompt)
if (NEEDS_USER(auth))
set_perms(PERM_USER, 0);
- status = (auth->setup)(sudo_user.pw, &prompt, auth);
+ status = (auth->setup)(pw, &prompt, auth);
if (status == AUTH_FAILURE)
auth->flags &= ~FLAG_CONFIGURED;
else if (status == AUTH_FATAL) /* XXX log */
@@ -169,7 +170,7 @@ verify_user(prompt)
if (NEEDS_USER(auth))
set_perms(PERM_USER, 0);
- success = auth->status = (auth->verify)(sudo_user.pw, p, auth);
+ success = auth->status = (auth->verify)(pw, p, auth);
if (NEEDS_USER(auth))
set_perms(PERM_ROOT, 0);
@@ -199,7 +200,7 @@ cleanup:
if (NEEDS_USER(auth))
set_perms(PERM_USER, 0);
- status = (auth->cleanup)(sudo_user.pw, auth);
+ status = (auth->cleanup)(pw, auth);
if (status == AUTH_FATAL) /* XXX log */
exit(1); /* assume error msg already printed */
diff --git a/usr.bin/sudo/check.c b/usr.bin/sudo/check.c
index d209194588f..6a1c4bdab27 100644
--- a/usr.bin/sudo/check.c
+++ b/usr.bin/sudo/check.c
@@ -102,7 +102,7 @@ check_user()
prompt = expand_prompt(user_prompt ? user_prompt : def_str(I_PASSPROMPT),
user_name, user_shost);
- verify_user(prompt);
+ verify_user(auth_pw, prompt);
}
if (status != TS_ERROR)
update_timestamp(timestampdir, timestampfile);
@@ -251,8 +251,18 @@ build_timestamp(timestampdir, timestampfile)
char **timestampdir;
char **timestampfile;
{
- char *dirparent = def_str(I_TIMESTAMPDIR);
+ char *dirparent;
+ int len;
+
+ dirparent = def_str(I_TIMESTAMPDIR);
+ len = easprintf(timestampdir, "%s/%s", dirparent, user_name);
+ if (len >= MAXPATHLEN)
+ log_error(0, "timestamp path too long: %s", timestampdir);
+ /*
+ * Timestamp file may be a file in the directory or NUL to use
+ * the directory as the timestamp.
+ */
if (def_flag(I_TTY_TICKETS)) {
char *p;
@@ -260,17 +270,20 @@ build_timestamp(timestampdir, timestampfile)
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);
+ if (def_flag(I_TARGETPW))
+ len = easprintf(timestampfile, "%s/%s/%s:%s", dirparent, user_name,
+ p, *user_runas);
+ else
+ len = easprintf(timestampfile, "%s/%s/%s", dirparent, user_name, p);
+ if (len >= MAXPATHLEN)
+ log_error(0, "timestamp path too long: %s", timestampfile);
+ } else if (def_flag(I_TARGETPW)) {
+ len = easprintf(timestampfile, "%s/%s/%s", dirparent, user_name,
+ *user_runas);
+ if (len >= MAXPATHLEN)
+ log_error(0, "timestamp path too long: %s", timestampfile);
+ } else
*timestampfile = NULL;
- }
}
/*
diff --git a/usr.bin/sudo/getspwuid.c b/usr.bin/sudo/getspwuid.c
index f9056c6bf05..2d9248d837e 100644
--- a/usr.bin/sudo/getspwuid.c
+++ b/usr.bin/sudo/getspwuid.c
@@ -93,7 +93,8 @@ int crypt_type = INT_MAX;
/*
* Local functions not visible outside getspwuid.c
*/
-static char *sudo_getshell __P((struct passwd *));
+static char *sudo_getshell __P((struct passwd *));
+static struct passwd *sudo_pwdup __P((struct passwd *));
/*
@@ -191,14 +192,11 @@ sudo_getepw(pw)
* Dynamically allocate space for a struct password and the constituent parts
* that we care about. Fills in pw_passwd from shadow file if necessary.
*/
-struct passwd *
-sudo_getpwuid(uid)
- uid_t uid;
+static struct passwd *
+sudo_pwdup(pw)
+ struct passwd *pw;
{
- struct passwd *pw, *local_pw;
-
- if ((pw = getpwuid(uid)) == NULL)
- return(NULL);
+ struct passwd *local_pw;
/* Allocate space for a local copy of pw. */
local_pw = (struct passwd *) emalloc(sizeof(struct passwd));
@@ -218,3 +216,35 @@ sudo_getpwuid(uid)
return(local_pw);
}
+
+/*
+ * Get a password entry by uid and allocate space for it.
+ * Fills in pw_passwd from shadow file if necessary.
+ */
+struct passwd *
+sudo_getpwuid(uid)
+ uid_t uid;
+{
+ struct passwd *pw;
+
+ if ((pw = getpwuid(uid)) == NULL)
+ return(NULL);
+ else
+ return(sudo_pwdup(pw));
+}
+
+/*
+ * Get a password entry by name and allocate space for it.
+ * Fills in pw_passwd from shadow file if necessary.
+ */
+struct passwd *
+sudo_getpwnam(name)
+ const char *name;
+{
+ struct passwd *pw;
+
+ if ((pw = getpwnam(name)) == NULL)
+ return(NULL);
+ else
+ return(sudo_pwdup(pw));
+}
diff --git a/usr.bin/sudo/sudo.c b/usr.bin/sudo/sudo.c
index 032cdf162d1..ca66a8b953a 100644
--- a/usr.bin/sudo/sudo.c
+++ b/usr.bin/sudo/sudo.c
@@ -115,8 +115,9 @@ static int set_loginclass __P((struct passwd *));
static void add_env __P((int));
static void clean_env __P((char **, struct env_table *));
static void initial_setup __P((void));
-static void update_epasswd __P((void));
+static struct passwd *get_authpw __P((void));
extern struct passwd *sudo_getpwuid __P((uid_t));
+extern struct passwd *sudo_getpwnam __P((const char *));
extern void list_matches __P((void));
/*
@@ -127,6 +128,7 @@ char **Argv;
int NewArgc = 0;
char **NewArgv = NULL;
struct sudo_user sudo_user;
+struct passwd *auth_pw;
FILE *sudoers_fp = NULL;
struct interface *interfaces;
int num_interfaces;
@@ -316,8 +318,8 @@ main(argc, argv)
(void) close(fd);
}
- /* Update encrypted password in user_password if sudoers said to. */
- update_epasswd();
+ /* Fill in passwd struct based on user we are authenticating as. */
+ auth_pw = get_authpw();
/* Require a password unless the NOPASS tag was set. */
if (!(validated & FLAG_NOPASS))
@@ -345,7 +347,7 @@ main(argc, argv)
/* This *must* have been set if we got a match but... */
if (safe_cmnd == NULL) {
log_error(MSG_ONLY,
- "internal error, safe_cmnd never got set for %s; %s",
+ "internal error, cmnd_safe never got set for %s; %s",
user_cmnd,
"please report this error at http://courtesan.com/sudo/bugs/");
}
@@ -1167,39 +1169,35 @@ set_fqdn()
}
/*
- * If the sudoers file says to prompt for a different user's password,
- * update the encrypted password in user_passwd accordingly.
+ * Get passwd entry for the user we are going to authenticate as.
+ * By default, this is the user invoking sudo...
*/
-static void
-update_epasswd()
+static struct passwd *
+get_authpw()
{
struct passwd *pw;
- /* We may be configured to prompt for a password other than the user's */
if (def_ival(I_ROOTPW)) {
- if ((pw = getpwuid(0)) == NULL)
+ if ((pw = sudo_getpwuid(0)) == NULL)
log_error(0, "uid 0 does not exist in the passwd file!");
- free(user_passwd);
- user_passwd = estrdup(sudo_getepw(pw));
} else if (def_ival(I_RUNASPW)) {
- if ((pw = getpwnam(def_str(I_RUNAS_DEF))) == NULL)
+ if ((pw = sudo_getpwnam(def_str(I_RUNAS_DEF))) == NULL)
log_error(0, "user %s does not exist in the passwd file!",
def_str(I_RUNAS_DEF));
- free(user_passwd);
- user_passwd = estrdup(sudo_getepw(pw));
} else if (def_ival(I_TARGETPW)) {
if (**user_runas == '#') {
- if ((pw = getpwuid(atoi(*user_runas + 1))) == NULL)
+ if ((pw = sudo_getpwuid(atoi(*user_runas + 1))) == NULL)
log_error(0, "uid %s does not exist in the passwd file!",
user_runas);
} else {
- if ((pw = getpwnam(*user_runas)) == NULL)
+ if ((pw = sudo_getpwnam(*user_runas)) == NULL)
log_error(0, "user %s does not exist in the passwd file!",
user_runas);
}
- free(user_passwd);
- user_passwd = estrdup(sudo_getepw(pw));
- }
+ } else
+ pw = sudo_user.pw;
+
+ return(pw);
}
/*
diff --git a/usr.bin/sudo/sudo.h b/usr.bin/sudo/sudo.h
index eb30390623e..f3c3471a0b5 100644
--- a/usr.bin/sudo/sudo.h
+++ b/usr.bin/sudo/sudo.h
@@ -196,7 +196,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((char *));
+void verify_user __P((struct passwd *, char *));
int sudoers_lookup __P((int));
void set_perms __P((int, int));
void remove_timestamp __P((int));
@@ -208,8 +208,8 @@ void pass_warn __P((FILE *));
VOID *emalloc __P((size_t));
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));
+int easprintf __P((char **, const char *, ...));
+int evasprintf __P((char **, const char *, va_list));
void dump_defaults __P((void));
void dump_auth_methods __P((void));
int lock_file __P((int, int));
@@ -222,6 +222,7 @@ YY_DECL;
/* Only provide extern declarations outside of sudo.c. */
#ifndef _SUDO_SUDO_C
extern struct sudo_user sudo_user;
+extern struct passwd *auth_pw;
extern int Argc;
extern char **Argv;
diff --git a/usr.bin/sudo/version.h b/usr.bin/sudo/version.h
index 5021306ea85..4226e121c62 100644
--- a/usr.bin/sudo/version.h
+++ b/usr.bin/sudo/version.h
@@ -37,6 +37,6 @@
#ifndef _SUDO_VERSION_H
#define _SUDO_VERSION_H
-static const char version[] = "1.6.3";
+static const char version[] = "1.6.3p4";
#endif /* _SUDO_VERSION_H */
diff --git a/usr.bin/sudo/visudo.c b/usr.bin/sudo/visudo.c
index 7982fcfb4c1..70f763c1467 100644
--- a/usr.bin/sudo/visudo.c
+++ b/usr.bin/sudo/visudo.c
@@ -214,7 +214,6 @@ main(argc, argv)
/* Parse sudoers to pull in editor and env_editor conf values. */
if ((yyin = fopen(stmp, "r"))) {
yyout = stdout;
- init_defaults();
init_parser();
yyparse();
parse_error = FALSE;
@@ -230,7 +229,7 @@ main(argc, argv)
*/
if (!def_flag(I_ENV_EDITOR) ||
(!(Editor = getenv("EDITOR")) && !(Editor = getenv("VISUAL"))))
- Editor = def_str(I_EDITOR);
+ Editor = estrdup(def_str(I_EDITOR));
/*
* Edit the temp file and parse it (for sanity checking)
@@ -286,6 +285,7 @@ main(argc, argv)
}
/* Clean slate for each parse */
+ user_runas = NULL;
init_defaults();
init_parser();