* src/su.c: Add splint annotations.

* src/su.c: Set caller_on_console as boolean.
	* src/su.c: Ignore retunr value from fputs (usage) / puts (prompt).
	* src/su.c: Improved memory management.
This commit is contained in:
nekral-guest 2011-08-14 21:44:46 +00:00
parent 1304a3106b
commit 94c1763f71
2 changed files with 31 additions and 14 deletions

View File

@ -1,3 +1,10 @@
2011-08-14 Nicolas François <nicolas.francois@centraliens.net>
* src/su.c: Add splint annotations.
* src/su.c: Set caller_on_console as boolean.
* src/su.c: Ignore retunr value from fputs (usage) / puts (prompt).
* src/su.c: Improved memory management.
2011-08-14 Nicolas François <nicolas.francois@centraliens.net> 2011-08-14 Nicolas François <nicolas.francois@centraliens.net>
* src/chgpasswd.c, src/chpasswd.c, src/newusers.c: Replace cflg by * src/chgpasswd.c, src/chpasswd.c, src/newusers.c: Replace cflg by

View File

@ -82,19 +82,19 @@
* Global variables * Global variables
*/ */
const char *Prog; const char *Prog;
static const char *caller_tty = NULL; /* Name of tty SU is run from */ static /*@observer@*/const char *caller_tty = NULL; /* Name of tty SU is run from */
static bool caller_is_root = false; static bool caller_is_root = false;
static uid_t caller_uid; static uid_t caller_uid;
#ifndef USE_PAM #ifndef USE_PAM
static int caller_on_console = 0; static bool caller_on_console = false;
#ifdef SU_ACCESS #ifdef SU_ACCESS
static char *caller_pass; static /*@only@*/char *caller_pass;
#endif #endif
#endif /* !USE_PAM */ #endif /* !USE_PAM */
static bool doshell = false; static bool doshell = false;
static bool fakelogin = false; static bool fakelogin = false;
static char *shellstr = NULL; static /*@observer@*/const char *shellstr;
static char *command = NULL; static /*@null@*/char *command = NULL;
/* not needed by sulog.c anymore */ /* not needed by sulog.c anymore */
@ -194,7 +194,7 @@ static RETSIGTYPE kill_child (int unused(s))
/* borrowed from GNU sh-utils' "su.c" */ /* borrowed from GNU sh-utils' "su.c" */
static bool restricted_shell (const char *shellname) static bool restricted_shell (const char *shellname)
{ {
char *line; /*@observer@*/const char *line;
setusershell (); setusershell ();
while ((line = getusershell ()) != NULL) { while ((line = getusershell ()) != NULL) {
@ -402,6 +402,7 @@ static void prepare_pam_close_session (void)
*/ */
static void usage (int status) static void usage (int status)
{ {
(void)
fputs (_("Usage: su [options] [LOGIN]\n" fputs (_("Usage: su [options] [LOGIN]\n"
"\n" "\n"
"Options:\n" "Options:\n"
@ -461,6 +462,7 @@ static void check_perms_pam (struct passwd *pw)
static void check_perms_nopam (struct passwd *pw) static void check_perms_nopam (struct passwd *pw)
{ {
struct spwd *spwd = NULL; struct spwd *spwd = NULL;
/*@observer@*/const char *password = pw->pw_passwd;
RETSIGTYPE (*oldsig) (int); RETSIGTYPE (*oldsig) (int);
if (caller_is_root) { if (caller_is_root) {
@ -497,7 +499,7 @@ static void check_perms_nopam (struct passwd *pw)
#ifdef SU_ACCESS #ifdef SU_ACCESS
if (strcmp (pw->pw_passwd, SHADOW_PASSWD_STRING) == 0) { if (strcmp (pw->pw_passwd, SHADOW_PASSWD_STRING) == 0) {
if (NULL != spwd) { if (NULL != spwd) {
pw->pw_passwd = spwd->sp_pwdp; password = spwd->sp_pwdp;
} }
} }
@ -505,11 +507,11 @@ static void check_perms_nopam (struct passwd *pw)
case 0: /* normal su, require target user's password */ case 0: /* normal su, require target user's password */
break; break;
case 1: /* require no password */ case 1: /* require no password */
pw->pw_passwd = ""; /* XXX warning: const */ password = ""; /* XXX warning: const */
break; break;
case 2: /* require own password */ case 2: /* require own password */
puts (_("(Enter your own password)")); (void) puts (_("(Enter your own password)"));
pw->pw_passwd = caller_pass; password = caller_pass;
break; break;
default: /* access denied (-1) or unexpected value */ default: /* access denied (-1) or unexpected value */
fprintf (stderr, fprintf (stderr,
@ -529,7 +531,7 @@ static void check_perms_nopam (struct passwd *pw)
* The first character of an administrator defined method is an '@' * The first character of an administrator defined method is an '@'
* character. * character.
*/ */
if (pw_auth (pw->pw_passwd, name, PW_SU, (char *) 0) != 0) { if (pw_auth (password, name, PW_SU, (char *) 0) != 0) {
SYSLOG (((pw->pw_uid != 0)? LOG_NOTICE : LOG_WARN, SYSLOG (((pw->pw_uid != 0)? LOG_NOTICE : LOG_WARN,
"Authentication failed for %s", name)); "Authentication failed for %s", name));
fprintf(stderr, _("%s: Authentication failure\n"), Prog); fprintf(stderr, _("%s: Authentication failure\n"), Prog);
@ -635,6 +637,7 @@ static struct passwd * check_perms (void)
subsystem (pw); /* change to the subsystem root */ subsystem (pw); /* change to the subsystem root */
endpwent (); /* close the old password databases */ endpwent (); /* close the old password databases */
endspent (); endspent ();
pw_free (pw);
return check_perms (); /* authenticate in the subsystem */ return check_perms (); /* authenticate in the subsystem */
} }
@ -652,6 +655,7 @@ static struct passwd * check_perms (void)
static void save_caller_context (char **argv) static void save_caller_context (char **argv)
{ {
struct passwd *pw = NULL; struct passwd *pw = NULL;
const char *password = NULL;
/* /*
* Get the program name. The program name is used as a prefix to * Get the program name. The program name is used as a prefix to
* most error messages. * most error messages.
@ -704,15 +708,18 @@ static void save_caller_context (char **argv)
* Sort out the password of user calling su, in case needed later * Sort out the password of user calling su, in case needed later
* -- chris * -- chris
*/ */
password = pw->pw_passwd;
if (strcmp (pw->pw_passwd, SHADOW_PASSWD_STRING) == 0) { if (strcmp (pw->pw_passwd, SHADOW_PASSWD_STRING) == 0) {
struct spwd *spwd = getspnam (caller_name); struct spwd *spwd = getspnam (caller_name);
if (NULL != spwd) { if (NULL != spwd) {
pw->pw_passwd = spwd->sp_pwdp; password = spwd->sp_pwdp;
} }
} }
caller_pass = xstrdup (pw->pw_passwd); free (caller_pass);
caller_pass = xstrdup (password);
#endif /* SU_ACCESS */ #endif /* SU_ACCESS */
#endif /* !USE_PAM */ #endif /* !USE_PAM */
pw_free (pw);
} }
/* /*
@ -906,7 +913,10 @@ static void set_environment (struct passwd *pw)
if (change_environment) { if (change_environment) {
if (fakelogin) { if (fakelogin) {
pw->pw_shell = shellstr; if (shellstr != pw->pw_shell) {
free (pw->pw_shell);
pw->pw_shell = xstrdup (shellstr);
}
setup_env (pw); setup_env (pw);
} else { } else {
addenv ("HOME", pw->pw_dir); addenv ("HOME", pw->pw_dir);