]> granicus.if.org Git - linux-pam/blobdiff - modules/pam_unix/pam_unix_passwd.c
Relevant BUGIDs: Debian bugs #95220, #175900
[linux-pam] / modules / pam_unix / pam_unix_passwd.c
index 099888166fafab74e7314cb7c66e3a5098e93bbd..c8ee54924fbbaa8aa278a9297eaf7240ed9bfcf8 100644 (file)
@@ -84,6 +84,7 @@ static security_context_t prev_context=NULL;
 #include "yppasswd.h"
 #include "md5.h"
 #include "support.h"
+#include "bigcrypt.h"
 
 #if !((__GLIBC__ == 2) && (__GLIBC_MINOR__ >= 1))
 extern int getrpcport(const char *host, unsigned long prognum,
@@ -99,8 +100,6 @@ extern int getrpcport(const char *host, unsigned long prognum,
 # include "./lckpwdf.-c"
 #endif
 
-extern char *bigcrypt(const char *key, const char *salt);
-
 /*
    How it works:
    Gets in username (has to be done) from the calling program
@@ -310,7 +309,7 @@ static int _unix_run_shadow_binary(pam_handle_t *pamh, unsigned int ctrl, const
        retval = PAM_AUTH_ERR;
     }
 
-    if (sighandler != NULL) {
+    if (sighandler != SIG_ERR) {
         (void) signal(SIGCHLD, sighandler);   /* restore old signal handler */
     }
 
@@ -331,11 +330,12 @@ static int check_old_password(const char *forwho, const char *newpass)
 
        while (fgets(buf, 16380, opwfile)) {
                if (!strncmp(buf, forwho, strlen(forwho))) {
+                       char *sptr;
                        buf[strlen(buf) - 1] = '\0';
-                       s_luser = strtok(buf, ":,");
-                       s_uid = strtok(NULL, ":,");
-                       s_npas = strtok(NULL, ":,");
-                       s_pas = strtok(NULL, ":,");
+                       s_luser = strtok_r(buf, ":,", &sptr);
+                       s_uid = strtok_r(NULL, ":,", &sptr);
+                       s_npas = strtok_r(NULL, ":,", &sptr);
+                       s_pas = strtok_r(NULL, ":,", &sptr);
                        while (s_pas != NULL) {
                                char *md5pass = Goodcrypt_md5(newpass, s_pas);
                                if (!strcmp(md5pass, s_pas)) {
@@ -343,7 +343,7 @@ static int check_old_password(const char *forwho, const char *newpass)
                                        retval = PAM_AUTHTOK_ERR;
                                        break;
                                }
-                               s_pas = strtok(NULL, ":,");
+                               s_pas = strtok_r(NULL, ":,", &sptr);
                                _pam_delete(md5pass);
                        }
                        break;
@@ -433,11 +433,12 @@ static int save_old_password(pam_handle_t *pamh,
 
     while (fgets(buf, 16380, opwfile)) {
        if (!strncmp(buf, forwho, strlen(forwho))) {
+           char *sptr;
            buf[strlen(buf) - 1] = '\0';
-           s_luser = strtok(buf, ":");
-           s_uid = strtok(NULL, ":");
-           s_npas = strtok(NULL, ":");
-           s_pas = strtok(NULL, ":");
+           s_luser = strtok_r(buf, ":", &sptr);
+           s_uid = strtok_r(NULL, ":", &sptr);
+           s_npas = strtok_r(NULL, ":", &sptr);
+           s_pas = strtok_r(NULL, ":", &sptr);
            npas = strtol(s_npas, NULL, 10) + 1;
            while (npas > howmany) {
                s_pas = strpbrk(s_pas, ",");
@@ -471,8 +472,8 @@ static int save_old_password(pam_handle_t *pamh,
            err = 1;
        } else {
            pass = crypt_md5_wrapper(oldpass);
-           snprintf(nbuf, sizeof(nbuf), "%s:%d:1:%s\n",
-                    forwho, pwd->pw_uid, pass);
+           snprintf(nbuf, sizeof(nbuf), "%s:%lu:1:%s\n",
+                    forwho, (unsigned long)pwd->pw_uid, pass);
            _pam_delete(pass);
            if (fputs(nbuf, pwfile) < 0) {
                err = 1;
@@ -481,8 +482,7 @@ static int save_old_password(pam_handle_t *pamh,
     }
 
     if (fclose(pwfile)) {
-       D(("error writing entries to old passwords file: %s\n",
-          strerror(errno)));
+       D(("error writing entries to old passwords file: %m"));
        err = 1;
     }
 
@@ -585,7 +585,7 @@ static int _update_passwd(pam_handle_t *pamh,
            err = 0;
        }
        if (putpwent(tmpent, pwfile)) {
-           D(("error writing entry to password file: %s\n", strerror(errno)));
+           D(("error writing entry to password file: %m"));
            err = 1;
            break;
        }
@@ -594,7 +594,7 @@ static int _update_passwd(pam_handle_t *pamh,
     fclose(opwfile);
 
     if (fclose(pwfile)) {
-       D(("error writing entries to password file: %s\n", strerror(errno)));
+       D(("error writing entries to password file: %m"));
        err = 1;
     }
 
@@ -700,7 +700,7 @@ static int _update_shadow(pam_handle_t *pamh, const char *forwho, char *towhat)
        }
 
        if (putspent(stmpent, pwfile)) {
-           D(("error writing entry to shadow file: %s\n", strerror(errno)));
+           D(("error writing entry to shadow file: %m"));
            err = 1;
            break;
        }
@@ -710,7 +710,7 @@ static int _update_shadow(pam_handle_t *pamh, const char *forwho, char *towhat)
     fclose(opwfile);
 
     if (fclose(pwfile)) {
-       D(("error writing entries to shadow file: %s\n", strerror(errno)));
+       D(("error writing entries to shadow file: %m"));
        err = 1;
     }
 
@@ -765,7 +765,7 @@ static int _do_setpass(pam_handle_t* pamh, const char *forwho,
                struct yppasswd yppwd;
                CLIENT *clnt;
                int status;
-               int err = 0;
+               enum clnt_stat err;
 
                /* Unlock passwd file to avoid deadlock */
 #ifdef USE_LCKPWDF
@@ -1039,11 +1039,10 @@ PAM_EXTERN int pam_sm_chauthtok(pam_handle_t * pamh, int flags,
        if (retval == PAM_SUCCESS) {
                /*
                 * Various libraries at various times have had bugs related to
-                * '+' or '-' as the first character of a user name. Don't take
-                * any chances here. Require that the username starts with an
-                * alphanumeric character.
+                * '+' or '-' as the first character of a user name. Don't
+                * allow them.
                 */
-               if (user == NULL || !isalnum(*user)) {
+               if (user == NULL || user[0] == '-' || user[0] == '+') {
                        pam_syslog(pamh, LOG_ERR, "bad username [%s]", user);
                        return PAM_USER_UNKNOWN;
                }
@@ -1080,13 +1079,6 @@ PAM_EXTERN int pam_sm_chauthtok(pam_handle_t * pamh, int flags,
                                user);
                        return PAM_USER_UNKNOWN;
                }
-               if (!_unix_shadowed(pwd) &&
-                   (strchr(pwd->pw_passwd, '*') != NULL)) {
-                       pam_syslog(pamh, LOG_DEBUG,
-                               "user \"%s\" does not have modifiable password",
-                               user);
-                       return PAM_USER_UNKNOWN;
-               }
        }
 
        /*
@@ -1107,18 +1099,13 @@ PAM_EXTERN int pam_sm_chauthtok(pam_handle_t * pamh, int flags,
                if (_unix_blankpasswd(pamh, ctrl, user)) {
                        return PAM_SUCCESS;
                } else if (off(UNIX__IAMROOT, ctrl)) {
-
                        /* instruct user what is happening */
-#define greeting "Changing password for "
-                       Announce = (char *) malloc(sizeof(greeting) + strlen(user));
-                       if (Announce == NULL) {
+                       if (asprintf(&Announce, _("Changing password for %s."),
+                               user) < 0) {
                                pam_syslog(pamh, LOG_CRIT,
                                         "password - out of memory");
                                return PAM_BUF_ERR;
                        }
-                       (void) strcpy(Announce, greeting);
-                       (void) strcpy(Announce + sizeof(greeting) - 1, user);
-#undef greeting
 
                        lctrl = ctrl;
                        set(UNIX__OLD_PASSWD, lctrl);