]> 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 dcd123c8f2b09ab32a008c1ff58517a145d381d8..c8ee54924fbbaa8aa278a9297eaf7240ed9bfcf8 100644 (file)
@@ -330,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)) {
@@ -342,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;
@@ -432,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, ",");
@@ -1037,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;
                }
@@ -1078,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;
-               }
        }
 
        /*
@@ -1105,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);