]> granicus.if.org Git - shadow/commitdiff
* src/su.c: Add splint annotations.
authornekral-guest <nekral-guest@5a98b0ae-9ef6-0310-add3-de5d479b70d7>
Sun, 14 Aug 2011 21:44:46 +0000 (21:44 +0000)
committernekral-guest <nekral-guest@5a98b0ae-9ef6-0310-add3-de5d479b70d7>
Sun, 14 Aug 2011 21:44:46 +0000 (21:44 +0000)
* 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.

ChangeLog
src/su.c

index 5530983b96cbe85a058226c939dbfbbcf5e0780f..af7ab6a9cfeb1cc74aceef448cfc6c7243f4c21e 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -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>
 
        * src/chgpasswd.c, src/chpasswd.c, src/newusers.c: Replace cflg by
index 03ad6348929e0c4cb32d17f0e8edb1e64342bbb2..a9489a6db4b25b32715182025e0058defa9f3af7 100644 (file)
--- a/src/su.c
+++ b/src/su.c
  * Global variables
  */
 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 uid_t caller_uid;
 #ifndef USE_PAM
-static int caller_on_console = 0;
+static bool caller_on_console = false;
 #ifdef SU_ACCESS
-static char *caller_pass;
+static /*@only@*/char *caller_pass;
 #endif
 #endif                         /* !USE_PAM */
 static bool doshell = false;
 static bool fakelogin = false;
-static char *shellstr = NULL;
-static char *command = NULL;
+static /*@observer@*/const char *shellstr;
+static /*@null@*/char *command = NULL;
 
 
 /* not needed by sulog.c anymore */
@@ -194,7 +194,7 @@ static RETSIGTYPE kill_child (int unused(s))
 /* borrowed from GNU sh-utils' "su.c" */
 static bool restricted_shell (const char *shellname)
 {
-       char *line;
+       /*@observer@*/const char *line;
 
        setusershell ();
        while ((line = getusershell ()) != NULL) {
@@ -402,6 +402,7 @@ static void prepare_pam_close_session (void)
  */
 static void usage (int status)
 {
+       (void)
        fputs (_("Usage: su [options] [LOGIN]\n"
                 "\n"
                 "Options:\n"
@@ -461,6 +462,7 @@ static void check_perms_pam (struct passwd *pw)
 static void check_perms_nopam (struct passwd *pw)
 {
        struct spwd *spwd = NULL;
+       /*@observer@*/const char *password = pw->pw_passwd;
        RETSIGTYPE (*oldsig) (int);
 
        if (caller_is_root) {
@@ -497,7 +499,7 @@ static void check_perms_nopam (struct passwd *pw)
 #ifdef SU_ACCESS
        if (strcmp (pw->pw_passwd, SHADOW_PASSWD_STRING) == 0) {
                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 */
                break;
        case 1: /* require no password */
-               pw->pw_passwd = "";     /* XXX warning: const */
+               password = "";  /* XXX warning: const */
                break;
        case 2: /* require own password */
-               puts (_("(Enter your own password)"));
-               pw->pw_passwd = caller_pass;
+               (void) puts (_("(Enter your own password)"));
+               password = caller_pass;
                break;
        default:        /* access denied (-1) or unexpected value */
                fprintf (stderr,
@@ -529,7 +531,7 @@ static void check_perms_nopam (struct passwd *pw)
         * The first character of an administrator defined method is an '@'
         * 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,
                         "Authentication failed for %s", name));
                fprintf(stderr, _("%s: Authentication failure\n"), Prog);
@@ -635,6 +637,7 @@ static struct passwd * check_perms (void)
                subsystem (pw); /* change to the subsystem root */
                endpwent ();            /* close the old password databases */
                endspent ();
+               pw_free (pw);
                return check_perms ();  /* authenticate in the subsystem */
        }
 
@@ -652,6 +655,7 @@ static struct passwd * check_perms (void)
 static void save_caller_context (char **argv)
 {
        struct passwd *pw = NULL;
+       const char *password = NULL;
        /*
         * Get the program name. The program name is used as a prefix to
         * 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
         * -- chris
         */
+       password = pw->pw_passwd;
        if (strcmp (pw->pw_passwd, SHADOW_PASSWD_STRING) == 0) {
                struct spwd *spwd = getspnam (caller_name);
                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                         /* !USE_PAM */
+       pw_free (pw);
 }
 
 /*
@@ -906,7 +913,10 @@ static void set_environment (struct passwd *pw)
 
        if (change_environment) {
                if (fakelogin) {
-                       pw->pw_shell = shellstr;
+                       if (shellstr != pw->pw_shell) {
+                               free (pw->pw_shell);
+                               pw->pw_shell = xstrdup (shellstr);
+                       }
                        setup_env (pw);
                } else {
                        addenv ("HOME", pw->pw_dir);