]> granicus.if.org Git - linux-pam/blobdiff - modules/pam_unix/pam_unix_passwd.c
Add missing ')'
[linux-pam] / modules / pam_unix / pam_unix_passwd.c
index 54b3de8326123a1b4c502f2664f062ed57abe7ca..9aae3b03de3531c5542fc3acaff620819b8ee400 100644 (file)
@@ -1,7 +1,8 @@
 /*
  * Main coding by Elliot Lee <sopwith@redhat.com>, Red Hat Software.
  * Copyright (C) 1996.
- * Copyright (c) Jan Rêkorajski, 1999.
+ * Copyright (c) Jan Rêkorajski, 1999.
+ * Copyright (c) Red Hat, Inc., 2007, 2008.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
 #include <ctype.h>
 #include <sys/time.h>
 #include <sys/stat.h>
-#include <rpc/rpc.h>
-#include <rpcsvc/yp_prot.h>
-#include <rpcsvc/ypclnt.h>
 
 #include <signal.h>
 #include <errno.h>
 #include <sys/wait.h>
-#ifdef WITH_SELINUX
-static int selinux_enabled=-1;
-#include <selinux/selinux.h>
-static security_context_t prev_context=NULL;
-#define SELINUX_ENABLED (selinux_enabled!=-1 ? selinux_enabled : (selinux_enabled=is_selinux_enabled()>0))
-#endif
-
-#ifdef USE_CRACKLIB
-#include <crack.h>
-#endif
+#include <sys/resource.h>
 
 #include <security/_pam_macros.h>
 
 /* indicate the following groups are defined */
 
-#define PAM_SM_PASSWORD
+#ifdef PAM_STATIC
+# include "pam_unix_static.h"
+#else
+# define PAM_SM_PASSWORD
+#endif
 
 #include <security/pam_modules.h>
+#include <security/pam_ext.h>
+#include <security/pam_modutil.h>
 
-#ifndef LINUX_PAM
-#include <security/pam_appl.h>
-#endif                         /* LINUX_PAM */
-
-#include <security/_pam_modutil.h>
-
-#include "yppasswd.h"
 #include "md5.h"
 #include "support.h"
+#include "passverify.h"
+#include "bigcrypt.h"
 
-#if !((__GLIBC__ == 2) && (__GLIBC_MINOR__ >= 1))
-extern int getrpcport(const char *host, unsigned long prognum,
-                     unsigned long versnum, unsigned int proto);
-#endif                         /* GNU libc 2.1 */
+#if (HAVE_YP_GET_DEFAULT_DOMAIN || HAVE_GETDOMAINNAME) && HAVE_YP_MASTER
+# define HAVE_NIS
+#endif
 
-/*
- * PAM framework looks for these entry-points to pass control to the
- * password changing module.
- */
+#ifdef HAVE_NIS
+# include <rpc/rpc.h>
 
-#if defined(USE_LCKPWDF) && !defined(HAVE_LCKPWDF)
-# include "./lckpwdf.-c"
-#endif
+# if HAVE_RPCSVC_YP_PROT_H
+#  include <rpcsvc/yp_prot.h>
+# endif
+
+# if HAVE_RPCSVC_YPCLNT_H
+#  include <rpcsvc/ypclnt.h>
+# endif
+
+# include "yppasswd.h"
 
-extern char *bigcrypt(const char *key, const char *salt);
+# if !HAVE_DECL_GETRPCPORT
+extern int getrpcport(const char *host, unsigned long prognum,
+                     unsigned long versnum, unsigned int proto);
+# endif                                /* GNU libc 2.1 */
+#endif
 
 /*
    How it works:
@@ -113,119 +110,72 @@ extern char *bigcrypt(const char *key, const char *salt);
    Sets it.
  */
 
-/* passwd/salt conversion macros */
-
-#define ascii_to_bin(c) ((c)>='a'?(c-59):(c)>='A'?((c)-53):(c)-'.')
-#define bin_to_ascii(c) ((c)>=38?((c)-38+'a'):(c)>=12?((c)-12+'A'):(c)+'.')
-
 /* data tokens */
 
 #define _UNIX_OLD_AUTHTOK      "-UN*X-OLD-PASS"
 #define _UNIX_NEW_AUTHTOK      "-UN*X-NEW-PASS"
 
 #define MAX_PASSWD_TRIES       3
-#define PW_TMPFILE             "/etc/npasswd"
-#define SH_TMPFILE             "/etc/nshadow"
-#ifndef CRACKLIB_DICTS
-#define CRACKLIB_DICTS         NULL
-#endif
-#define OPW_TMPFILE            "/etc/security/nopasswd"
-#define OLD_PASSWORDS_FILE     "/etc/security/opasswd"
-
-/*
- * i64c - convert an integer to a radix 64 character
- */
-static int i64c(int i)
-{
-       if (i < 0)
-               return ('.');
-       else if (i > 63)
-               return ('z');
-       if (i == 0)
-               return ('.');
-       if (i == 1)
-               return ('/');
-       if (i >= 2 && i <= 11)
-               return ('0' - 2 + i);
-       if (i >= 12 && i <= 37)
-               return ('A' - 12 + i);
-       if (i >= 38 && i <= 63)
-               return ('a' - 38 + i);
-       return ('\0');
-}
 
-static char *crypt_md5_wrapper(const char *pass_new)
-{
-       /*
-        * Code lifted from Marek Michalkiewicz's shadow suite. (CG)
-        * removed use of static variables (AGM)
-        */
-
-       struct timeval tv;
-       MD5_CTX ctx;
-       unsigned char result[16];
-       char *cp = (char *) result;
-       unsigned char tmp[16];
-       int i;
-       char *x = NULL;
-
-       GoodMD5Init(&ctx);
-       gettimeofday(&tv, (struct timezone *) 0);
-       GoodMD5Update(&ctx, (void *) &tv, sizeof tv);
-       i = getpid();
-       GoodMD5Update(&ctx, (void *) &i, sizeof i);
-       i = clock();
-       GoodMD5Update(&ctx, (void *) &i, sizeof i);
-       GoodMD5Update(&ctx, result, sizeof result);
-       GoodMD5Final(tmp, &ctx);
-       strcpy(cp, "$1$");      /* magic for the MD5 */
-       cp += strlen(cp);
-       for (i = 0; i < 8; i++)
-               *cp++ = i64c(tmp[i] & 077);
-       *cp = '\0';
-
-       /* no longer need cleartext */
-       x = Goodcrypt_md5(pass_new, (const char *) result);
-
-       return x;
-}
-
-static char *getNISserver(pam_handle_t *pamh)
+#ifdef HAVE_NIS
+static char *getNISserver(pam_handle_t *pamh, unsigned int ctrl)
 {
        char *master;
        char *domainname;
        int port, err;
 
+#ifdef HAVE_YP_GET_DEFAULT_DOMAIN
        if ((err = yp_get_default_domain(&domainname)) != 0) {
-               _log_err(LOG_WARNING, pamh, "can't get local yp domain: %s\n",
+               pam_syslog(pamh, LOG_WARNING, "can't get local yp domain: %s",
                         yperr_string(err));
                return NULL;
        }
+#elif defined(HAVE_GETDOMAINNAME)
+       char domainname_res[256];
+
+       if (getdomainname (domainname_res, sizeof (domainname_res)) == 0)
+         {
+           if (strcmp (domainname_res, "(none)") == 0)
+             {
+               /* If domainname is not set, some systems will return "(none)" */
+               domainname_res[0] = '\0';
+             }
+           domainname = domainname_res;
+         }
+       else domainname = NULL;
+#endif
+
        if ((err = yp_master(domainname, "passwd.byname", &master)) != 0) {
-               _log_err(LOG_WARNING, pamh, "can't find the master ypserver: %s\n",
+               pam_syslog(pamh, LOG_WARNING, "can't find the master ypserver: %s",
                         yperr_string(err));
                return NULL;
        }
        port = getrpcport(master, YPPASSWDPROG, YPPASSWDPROC_UPDATE, IPPROTO_UDP);
        if (port == 0) {
-               _log_err(LOG_WARNING, pamh,
-                        "yppasswdd not running on NIS master host\n");
+               pam_syslog(pamh, LOG_WARNING,
+                        "yppasswdd not running on NIS master host");
                return NULL;
        }
        if (port >= IPPORT_RESERVED) {
-               _log_err(LOG_WARNING, pamh,
-                        "yppasswd daemon running on illegal port.\n");
+               pam_syslog(pamh, LOG_WARNING,
+                        "yppasswd daemon running on illegal port");
                return NULL;
        }
+       if (on(UNIX_DEBUG, ctrl)) {
+         pam_syslog(pamh, LOG_DEBUG, "Use NIS server on %s with port %d",
+                    master, port);
+       }
        return master;
 }
+#endif
 
 #ifdef WITH_SELINUX
 
-static int _unix_run_shadow_binary(pam_handle_t *pamh, unsigned int ctrl, const char *user, const char *fromwhat, const char *towhat)
+static int _unix_run_update_binary(pam_handle_t *pamh, unsigned int ctrl, const char *user,
+    const char *fromwhat, const char *towhat, int remember)
 {
     int retval, child, fds[2];
-    void (*sighandler)(int) = NULL;
+    struct sigaction newsa, oldsa;
 
     D(("called."));
     /* create a pipe for the password */
@@ -243,72 +193,87 @@ static int _unix_run_shadow_binary(pam_handle_t *pamh, unsigned int ctrl, const
         * The "noreap" module argument is provided so that the admin can
         * override this behavior.
         */
-       sighandler = signal(SIGCHLD, SIG_DFL);
+        memset(&newsa, '\0', sizeof(newsa));
+        newsa.sa_handler = SIG_DFL;
+        sigaction(SIGCHLD, &newsa, &oldsa);
     }
 
     /* fork */
     child = fork();
     if (child == 0) {
-        size_t i=0;
+        int i=0;
         struct rlimit rlim;
        static char *envp[] = { NULL };
-       char *args[] = { NULL, NULL, NULL, NULL };
+       char *args[] = { NULL, NULL, NULL, NULL, NULL, NULL };
+        char buffer[16];
 
        /* XXX - should really tidy up PAM here too */
 
-       close(0); close(1);
        /* reopen stdin as pipe */
-       close(fds[1]);
        dup2(fds[0], STDIN_FILENO);
 
        if (getrlimit(RLIMIT_NOFILE,&rlim)==0) {
-         for (i=2; i < rlim.rlim_max; i++) {
-           if ((unsigned int)fds[0] != i)
-                  close(i);
+         if (rlim.rlim_max >= MAX_FD_NO)
+           rlim.rlim_max = MAX_FD_NO;
+         for (i=0; i < (int)rlim.rlim_max; i++) {
+           if (i != STDIN_FILENO)
+               close(i);
          }
        }
+
        /* exec binary helper */
-       args[0] = x_strdup(CHKPWD_HELPER);
+       args[0] = x_strdup(UPDATE_HELPER);
        args[1] = x_strdup(user);
-       args[2] = x_strdup("shadow");
+       args[2] = x_strdup("update");
+       if (on(UNIX_SHADOW, ctrl))
+               args[3] = x_strdup("1");
+       else
+               args[3] = x_strdup("0");
+
+        snprintf(buffer, sizeof(buffer), "%d", remember);
+        args[4] = x_strdup(buffer);
 
-       execve(CHKPWD_HELPER, args, envp);
+       execve(UPDATE_HELPER, args, envp);
 
        /* should not get here: exit with error */
        D(("helper binary is not available"));
-       exit(PAM_AUTHINFO_UNAVAIL);
+       _exit(PAM_AUTHINFO_UNAVAIL);
     } else if (child > 0) {
        /* wait for child */
        /* if the stored password is NULL */
         int rc=0;
        if (fromwhat)
-         _pammodutil_write(fds[1], fromwhat, strlen(fromwhat)+1);
+         pam_modutil_write(fds[1], fromwhat, strlen(fromwhat)+1);
        else
-         _pammodutil_write(fds[1], "", 1);
+         pam_modutil_write(fds[1], "", 1);
        if (towhat) {
-         _pammodutil_write(fds[1], towhat, strlen(towhat)+1);
+         pam_modutil_write(fds[1], towhat, strlen(towhat)+1);
        }
        else
-         _pammodutil_write(fds[1], "", 1);
+         pam_modutil_write(fds[1], "", 1);
 
        close(fds[0]);       /* close here to avoid possible SIGPIPE above */
        close(fds[1]);
-       rc=waitpid(child, &retval, 0);  /* wait for helper to complete */
+       /* wait for helper to complete: */
+       while ((rc=waitpid(child, &retval, 0)) < 0 && errno == EINTR);
        if (rc<0) {
-         _log_err(LOG_ERR, pamh, "unix_chkpwd waitpid returned %d: %s", rc, strerror(errno));
-         retval = PAM_AUTH_ERR;
-       } else {
+         pam_syslog(pamh, LOG_ERR, "unix_update waitpid failed: %m");
+         retval = PAM_AUTHTOK_ERR;
+       } else if (!WIFEXITED(retval)) {
+          pam_syslog(pamh, LOG_ERR, "unix_update abnormal exit: %d", retval);
+          retval = PAM_AUTHTOK_ERR;
+        } else {
          retval = WEXITSTATUS(retval);
        }
     } else {
        D(("fork failed"));
        close(fds[0]);
-       close(fds[1]);
+       close(fds[1]);
        retval = PAM_AUTH_ERR;
     }
 
-    if (sighandler != NULL) {
-        (void) signal(SIGCHLD, sighandler);   /* restore old signal handler */
+    if (off(UNIX_NOREAP, ctrl)) {
+        sigaction(SIGCHLD, &oldsa, NULL);   /* restore old signal handler */
     }
 
     return retval;
@@ -321,18 +286,21 @@ static int check_old_password(const char *forwho, const char *newpass)
        char *s_luser, *s_uid, *s_npas, *s_pas;
        int retval = PAM_SUCCESS;
        FILE *opwfile;
+       size_t len = strlen(forwho);
 
        opwfile = fopen(OLD_PASSWORDS_FILE, "r");
        if (opwfile == NULL)
                return PAM_ABORT;
 
        while (fgets(buf, 16380, opwfile)) {
-               if (!strncmp(buf, forwho, strlen(forwho))) {
+               if (!strncmp(buf, forwho, len) && (buf[len] == ':' ||
+                       buf[len] == ',')) {
+                       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)) {
@@ -340,7 +308,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;
@@ -351,393 +319,6 @@ static int check_old_password(const char *forwho, const char *newpass)
        return retval;
 }
 
-static int save_old_password(pam_handle_t *pamh,
-                            const char *forwho, const char *oldpass,
-                            int howmany)
-{
-    static char buf[16384];
-    static char nbuf[16384];
-    char *s_luser, *s_uid, *s_npas, *s_pas, *pass;
-    int npas;
-    FILE *pwfile, *opwfile;
-    int err = 0;
-    int oldmask;
-    int found = 0;
-    struct passwd *pwd = NULL;
-    struct stat st;
-
-    if (howmany < 0) {
-       return PAM_SUCCESS;
-    }
-
-    if (oldpass == NULL) {
-       return PAM_SUCCESS;
-    }
-
-    oldmask = umask(077);
-
-#ifdef WITH_SELINUX
-    if (SELINUX_ENABLED) {
-      security_context_t passwd_context=NULL;
-      if (getfilecon("/etc/passwd",&passwd_context)<0) {
-        return PAM_AUTHTOK_ERR;
-      };
-      if (getfscreatecon(&prev_context)<0) {
-        freecon(passwd_context);
-        return PAM_AUTHTOK_ERR;
-      }
-      if (setfscreatecon(passwd_context)) {
-        freecon(passwd_context);
-        freecon(prev_context);
-        return PAM_AUTHTOK_ERR;
-      }
-      freecon(passwd_context);
-    }
-#endif
-    pwfile = fopen(OPW_TMPFILE, "w");
-    umask(oldmask);
-    if (pwfile == NULL) {
-      err = 1;
-      goto done;
-    }
-
-    opwfile = fopen(OLD_PASSWORDS_FILE, "r");
-    if (opwfile == NULL) {
-       fclose(pwfile);
-      err = 1;
-      goto done;
-    }
-
-    if (fstat(fileno(opwfile), &st) == -1) {
-       fclose(opwfile);
-       fclose(pwfile);
-       err = 1;
-       goto done;
-    }
-
-    if (fchown(fileno(pwfile), st.st_uid, st.st_gid) == -1) {
-       fclose(opwfile);
-       fclose(pwfile);
-       err = 1;
-       goto done;
-    }
-    if (fchmod(fileno(pwfile), st.st_mode) == -1) {
-       fclose(opwfile);
-       fclose(pwfile);
-       err = 1;
-       goto done;
-    }
-
-    while (fgets(buf, 16380, opwfile)) {
-       if (!strncmp(buf, forwho, strlen(forwho))) {
-           buf[strlen(buf) - 1] = '\0';
-           s_luser = strtok(buf, ":");
-           s_uid = strtok(NULL, ":");
-           s_npas = strtok(NULL, ":");
-           s_pas = strtok(NULL, ":");
-           npas = strtol(s_npas, NULL, 10) + 1;
-           while (npas > howmany) {
-               s_pas = strpbrk(s_pas, ",");
-               if (s_pas != NULL)
-                   s_pas++;
-               npas--;
-           }
-           pass = crypt_md5_wrapper(oldpass);
-           if (s_pas == NULL)
-               snprintf(nbuf, sizeof(nbuf), "%s:%s:%d:%s\n",
-                        s_luser, s_uid, npas, pass);
-           else
-               snprintf(nbuf, sizeof(nbuf),"%s:%s:%d:%s,%s\n",
-                        s_luser, s_uid, npas, s_pas, pass);
-           _pam_delete(pass);
-           if (fputs(nbuf, pwfile) < 0) {
-               err = 1;
-               break;
-           }
-           found = 1;
-       } else if (fputs(buf, pwfile) < 0) {
-           err = 1;
-           break;
-       }
-    }
-    fclose(opwfile);
-
-    if (!found) {
-       pwd = _pammodutil_getpwnam(pamh, forwho);
-       if (pwd == NULL) {
-           err = 1;
-       } else {
-           pass = crypt_md5_wrapper(oldpass);
-           snprintf(nbuf, sizeof(nbuf), "%s:%d:1:%s\n",
-                    forwho, pwd->pw_uid, pass);
-           _pam_delete(pass);
-           if (fputs(nbuf, pwfile) < 0) {
-               err = 1;
-           }
-       }
-    }
-
-    if (fclose(pwfile)) {
-       D(("error writing entries to old passwords file: %s\n",
-          strerror(errno)));
-       err = 1;
-    }
-
-done:
-    if (!err) {
-       if (rename(OPW_TMPFILE, OLD_PASSWORDS_FILE))
-           err = 1;
-    }
-#ifdef WITH_SELINUX
-    if (SELINUX_ENABLED) {
-      if (setfscreatecon(prev_context)) {
-        err = 1;
-      }
-      if (prev_context)
-        freecon(prev_context);
-      prev_context=NULL;
-    }
-#endif
-    if (!err) {
-       return PAM_SUCCESS;
-    } else {
-       unlink(OPW_TMPFILE);
-       return PAM_AUTHTOK_ERR;
-    }
-}
-
-static int _update_passwd(pam_handle_t *pamh,
-                         const char *forwho, const char *towhat)
-{
-    struct passwd *tmpent = NULL;
-    struct stat st;
-    FILE *pwfile, *opwfile;
-    int err = 1;
-    int oldmask;
-
-    oldmask = umask(077);
-#ifdef WITH_SELINUX
-    if (SELINUX_ENABLED) {
-      security_context_t passwd_context=NULL;
-      if (getfilecon("/etc/passwd",&passwd_context)<0) {
-       return PAM_AUTHTOK_ERR;
-      };
-      if (getfscreatecon(&prev_context)<0) {
-       freecon(passwd_context);
-       return PAM_AUTHTOK_ERR;
-      }
-      if (setfscreatecon(passwd_context)) {
-       freecon(passwd_context);
-       freecon(prev_context);
-       return PAM_AUTHTOK_ERR;
-      }
-      freecon(passwd_context);
-    }
-#endif
-    pwfile = fopen(PW_TMPFILE, "w");
-    umask(oldmask);
-    if (pwfile == NULL) {
-      err = 1;
-      goto done;
-    }
-
-    opwfile = fopen("/etc/passwd", "r");
-    if (opwfile == NULL) {
-       fclose(pwfile);
-       err = 1;
-       goto done;
-    }
-
-    if (fstat(fileno(opwfile), &st) == -1) {
-       fclose(opwfile);
-       fclose(pwfile);
-       err = 1;
-       goto done;
-    }
-
-    if (fchown(fileno(pwfile), st.st_uid, st.st_gid) == -1) {
-       fclose(opwfile);
-       fclose(pwfile);
-       err = 1;
-       goto done;
-    }
-    if (fchmod(fileno(pwfile), st.st_mode) == -1) {
-       fclose(opwfile);
-       fclose(pwfile);
-       err = 1;
-       goto done;
-    }
-
-    tmpent = fgetpwent(opwfile);
-    while (tmpent) {
-       if (!strcmp(tmpent->pw_name, forwho)) {
-           /* To shut gcc up */
-           union {
-               const char *const_charp;
-               char *charp;
-           } assigned_passwd;
-           assigned_passwd.const_charp = towhat;
-
-           tmpent->pw_passwd = assigned_passwd.charp;
-           err = 0;
-       }
-       if (putpwent(tmpent, pwfile)) {
-           D(("error writing entry to password file: %s\n", strerror(errno)));
-           err = 1;
-           break;
-       }
-       tmpent = fgetpwent(opwfile);
-    }
-    fclose(opwfile);
-
-    if (fclose(pwfile)) {
-       D(("error writing entries to password file: %s\n", strerror(errno)));
-       err = 1;
-    }
-
-done:
-    if (!err) {
-       if (!rename(PW_TMPFILE, "/etc/passwd"))
-           _log_err(LOG_NOTICE, pamh, "password changed for %s", forwho);
-       else
-           err = 1;
-    }
-#ifdef WITH_SELINUX
-    if (SELINUX_ENABLED) {
-      if (setfscreatecon(prev_context)) {
-       err = 1;
-      }
-      if (prev_context)
-       freecon(prev_context);
-      prev_context=NULL;
-    }
-#endif
-    if (!err) {
-       return PAM_SUCCESS;
-    } else {
-       unlink(PW_TMPFILE);
-       return PAM_AUTHTOK_ERR;
-    }
-}
-
-static int _update_shadow(pam_handle_t *pamh, const char *forwho, char *towhat)
-{
-    struct spwd *spwdent = NULL, *stmpent = NULL;
-    struct stat st;
-    FILE *pwfile, *opwfile;
-    int err = 1;
-    int oldmask;
-
-    spwdent = getspnam(forwho);
-    if (spwdent == NULL) {
-       return PAM_USER_UNKNOWN;
-    }
-    oldmask = umask(077);
-
-#ifdef WITH_SELINUX
-    if (SELINUX_ENABLED) {
-      security_context_t shadow_context=NULL;
-      if (getfilecon("/etc/shadow",&shadow_context)<0) {
-       return PAM_AUTHTOK_ERR;
-      };
-      if (getfscreatecon(&prev_context)<0) {
-       freecon(shadow_context);
-       return PAM_AUTHTOK_ERR;
-      }
-      if (setfscreatecon(shadow_context)) {
-       freecon(shadow_context);
-       freecon(prev_context);
-       return PAM_AUTHTOK_ERR;
-      }
-      freecon(shadow_context);
-    }
-#endif
-    pwfile = fopen(SH_TMPFILE, "w");
-    umask(oldmask);
-    if (pwfile == NULL) {
-       err = 1;
-       goto done;
-    }
-
-    opwfile = fopen("/etc/shadow", "r");
-    if (opwfile == NULL) {
-       fclose(pwfile);
-       err = 1;
-       goto done;
-    }
-
-    if (fstat(fileno(opwfile), &st) == -1) {
-       fclose(opwfile);
-       fclose(pwfile);
-       err = 1;
-       goto done;
-    }
-
-    if (fchown(fileno(pwfile), st.st_uid, st.st_gid) == -1) {
-       fclose(opwfile);
-       fclose(pwfile);
-       err = 1;
-       goto done;
-    }
-    if (fchmod(fileno(pwfile), st.st_mode) == -1) {
-       fclose(opwfile);
-       fclose(pwfile);
-       err = 1;
-       goto done;
-    }
-
-    stmpent = fgetspent(opwfile);
-    while (stmpent) {
-
-       if (!strcmp(stmpent->sp_namp, forwho)) {
-           stmpent->sp_pwdp = towhat;
-           stmpent->sp_lstchg = time(NULL) / (60 * 60 * 24);
-           err = 0;
-           D(("Set password %s for %s", stmpent->sp_pwdp, forwho));
-       }
-
-       if (putspent(stmpent, pwfile)) {
-           D(("error writing entry to shadow file: %s\n", strerror(errno)));
-           err = 1;
-           break;
-       }
-
-       stmpent = fgetspent(opwfile);
-    }
-    fclose(opwfile);
-
-    if (fclose(pwfile)) {
-       D(("error writing entries to shadow file: %s\n", strerror(errno)));
-       err = 1;
-    }
-
- done:
-    if (!err) {
-       if (!rename(SH_TMPFILE, "/etc/shadow"))
-           _log_err(LOG_NOTICE, pamh, "password changed for %s", forwho);
-       else
-           err = 1;
-    }
-
-#ifdef WITH_SELINUX
-    if (SELINUX_ENABLED) {
-      if (setfscreatecon(prev_context)) {
-       err = 1;
-      }
-      if (prev_context)
-       freecon(prev_context);
-      prev_context=NULL;
-    }
-#endif
-
-    if (!err) {
-       return PAM_SUCCESS;
-    } else {
-       unlink(SH_TMPFILE);
-       return PAM_AUTHTOK_ERR;
-    }
-}
-
 static int _do_setpass(pam_handle_t* pamh, const char *forwho,
                       const char *fromwhat,
                       char *towhat, unsigned int ctrl, int remember)
@@ -757,17 +338,16 @@ static int _do_setpass(pam_handle_t* pamh, const char *forwho,
        }
 
        if (on(UNIX_NIS, ctrl) && _unix_comesfromsource(pamh, forwho, 0, 1)) {
-           if ((master=getNISserver(pamh)) != NULL) {
+#ifdef HAVE_NIS
+         if ((master=getNISserver(pamh, ctrl)) != NULL) {
                struct timeval timeout;
                struct yppasswd yppwd;
                CLIENT *clnt;
                int status;
-               int err = 0;
+               enum clnt_stat err;
 
                /* Unlock passwd file to avoid deadlock */
-#ifdef USE_LCKPWDF
-               ulckpwdf();
-#endif
+               unlock_pwdf();
                unlocked = 1;
 
                /* Initialize password information */
@@ -808,7 +388,7 @@ static int _do_setpass(pam_handle_t* pamh, const char *forwho,
                }
                D(("The password has%s been changed on %s.",
                   (err || status) ? " not" : "", master));
-               _log_err(LOG_NOTICE, pamh, "password%s changed for %s on %s",
+               pam_syslog(pamh, LOG_NOTICE, "password%s changed for %s on %s",
                         (err || status) ? " not" : "", pwd->pw_name, master);
 
                auth_destroy(clnt->cl_auth);
@@ -818,133 +398,87 @@ static int _do_setpass(pam_handle_t* pamh, const char *forwho,
                                _("NIS password could not be changed."));
                        retval = PAM_TRY_AGAIN;
                }
-#ifdef DEBUG
+#ifdef PAM_DEBUG
                sleep(5);
 #endif
            } else {
                    retval = PAM_TRY_AGAIN;
            }
+#else
+          if (on(UNIX_DEBUG, ctrl)) {
+            pam_syslog(pamh, LOG_DEBUG, "No NIS support available");
+          }
+
+          retval = PAM_TRY_AGAIN;
+#endif
        }
 
        if (_unix_comesfromsource(pamh, forwho, 1, 0)) {
-#ifdef USE_LCKPWDF
                if(unlocked) {
-                       int i = 0;
-                       /* These values for the number of attempts and the sleep time
-                          are, of course, completely arbitrary.
-                          My reading of the PAM docs is that, once pam_chauthtok() has been
-                          called with PAM_UPDATE_AUTHTOK, we are obliged to take any
-                          reasonable steps to make sure the token is updated; so retrying
-                          for 1/10 sec. isn't overdoing it. */
-                       while((retval = lckpwdf()) != 0 && i < 100) {
-                               usleep(1000);
-                               i++;
-                       }
-                       if(retval != 0) {
+                       if (lock_pwdf() != PAM_SUCCESS) {
                                return PAM_AUTHTOK_LOCK_BUSY;
                        }
                }
+#ifdef WITH_SELINUX
+               if (unix_selinux_confined())
+                         return _unix_run_update_binary(pamh, ctrl, forwho, fromwhat, towhat, remember);
 #endif
                /* first, save old password */
                if (save_old_password(pamh, forwho, fromwhat, remember)) {
                        retval = PAM_AUTHTOK_ERR;
                        goto done;
                }
-               if (on(UNIX_SHADOW, ctrl) || _unix_shadowed(pwd)) {
-                       retval = _update_shadow(pamh, forwho, towhat);
-#ifdef WITH_SELINUX
-                       if (retval != PAM_SUCCESS && SELINUX_ENABLED)
-                         retval = _unix_run_shadow_binary(pamh, ctrl, forwho, fromwhat, towhat);
-#endif
+               if (on(UNIX_SHADOW, ctrl) || is_pwd_shadowed(pwd)) {
+                       retval = unix_update_shadow(pamh, forwho, towhat);
                        if (retval == PAM_SUCCESS)
-                               if (!_unix_shadowed(pwd))
-                                       retval = _update_passwd(pamh, forwho, "x");
+                               if (!is_pwd_shadowed(pwd))
+                                       retval = unix_update_passwd(pamh, forwho, "x");
                } else {
-                       retval = _update_passwd(pamh, forwho, towhat);
+                       retval = unix_update_passwd(pamh, forwho, towhat);
                }
        }
 
 
 done:
-#ifdef USE_LCKPWDF
-       ulckpwdf();
-#endif
+       unlock_pwdf();
 
        return retval;
 }
 
 static int _unix_verify_shadow(pam_handle_t *pamh, const char *user, unsigned int ctrl)
 {
-       struct passwd *pwd = NULL;      /* Password and shadow password */
-       struct spwd *spwdent = NULL;    /* file entries for the user */
-       time_t curdays;
-       int retval = PAM_SUCCESS;
+       struct passwd *pwent = NULL;    /* Password and shadow password */
+       struct spwd *spent = NULL;      /* file entries for the user */
+       int daysleft;
+       int retval;
 
-       /* UNIX passwords area */
-       pwd = getpwnam(user);   /* Get password file entry... */
-       if (pwd == NULL)
-               return PAM_AUTHINFO_UNAVAIL;    /* We don't need to do the rest... */
+       retval = get_account_info(pamh, user, &pwent, &spent);
+       if (retval == PAM_USER_UNKNOWN) {
+               return retval;
+       }
 
-       if (_unix_shadowed(pwd)) {
-               /* ...and shadow password file entry for this user, if shadowing
-                  is enabled */
-               setspent();
-               spwdent = getspnam(user);
-               endspent();
+       if (retval == PAM_SUCCESS && spent == NULL)
+               return PAM_SUCCESS;
 
-#ifdef WITH_SELINUX
-               if (spwdent == NULL && SELINUX_ENABLED )
-                   spwdent = _unix_run_verify_binary(pamh, ctrl, user);
-#endif
-               if (spwdent == NULL)
-                       return PAM_AUTHINFO_UNAVAIL;
-       } else {
-               if (strcmp(pwd->pw_passwd,"*NP*") == 0) { /* NIS+ */
-                       uid_t save_uid;
-
-                       save_uid = geteuid();
-                       seteuid (pwd->pw_uid);
-                       spwdent = getspnam( user );
-                       seteuid (save_uid);
-
-                       if (spwdent == NULL)
-                               return PAM_AUTHINFO_UNAVAIL;
-               } else
-                       spwdent = NULL;
+       if (retval == PAM_UNIX_RUN_HELPER) {
+               retval = _unix_run_verify_binary(pamh, ctrl, user, &daysleft);
+               if (retval == PAM_AUTH_ERR || retval == PAM_USER_UNKNOWN)
+                       return retval;
        }
+       else if (retval == PAM_SUCCESS)
+               retval = check_shadow_expiry(pamh, spent, &daysleft);
+
+       if (on(UNIX__IAMROOT, ctrl) || retval == PAM_NEW_AUTHTOK_REQD)
+               return PAM_SUCCESS;
 
-       if (spwdent != NULL) {
-               /* We have the user's information, now let's check if their account
-                  has expired (60 * 60 * 24 = number of seconds in a day) */
-
-               if (off(UNIX__IAMROOT, ctrl)) {
-                       /* Get the current number of days since 1970 */
-                       curdays = time(NULL) / (60 * 60 * 24);
-                       if ((curdays < (spwdent->sp_lstchg + spwdent->sp_min))
-                           && (spwdent->sp_min != -1))
-                               retval = PAM_AUTHTOK_ERR;
-                       else if ((curdays > (spwdent->sp_lstchg + spwdent->sp_max + spwdent->sp_inact))
-                                && (spwdent->sp_max != -1) && (spwdent->sp_inact != -1)
-                                && (spwdent->sp_lstchg != 0))
-                               /*
-                                * Their password change has been put off too long,
-                                */
-                               retval = PAM_ACCT_EXPIRED;
-                       else if ((curdays > spwdent->sp_expire) && (spwdent->sp_expire != -1)
-                                && (spwdent->sp_lstchg != 0))
-                               /*
-                                * OR their account has just plain expired
-                                */
-                               retval = PAM_ACCT_EXPIRED;
-               }
-       }
        return retval;
 }
 
 static int _pam_unix_approve_pass(pam_handle_t * pamh
                                  ,unsigned int ctrl
                                  ,const char *pass_old
-                                 ,const char *pass_new)
+                                 ,const char *pass_new,
+                                  int pass_min_len)
 {
        const void *user;
        const char *remark = NULL;
@@ -956,7 +490,7 @@ static int _pam_unix_approve_pass(pam_handle_t * pamh
 
        if (pass_new == NULL || (pass_old && !strcmp(pass_old, pass_new))) {
                if (on(UNIX_DEBUG, ctrl)) {
-                       _log_err(LOG_DEBUG, pamh, "bad authentication token");
+                       pam_syslog(pamh, LOG_DEBUG, "bad authentication token");
                }
                _make_remark(pamh, ctrl, PAM_ERROR_MSG, pass_new == NULL ?
                        _("No password supplied") : _("Password unchanged"));
@@ -970,24 +504,19 @@ static int _pam_unix_approve_pass(pam_handle_t * pamh
        retval = pam_get_item(pamh, PAM_USER, &user);
        if (retval != PAM_SUCCESS) {
                if (on(UNIX_DEBUG, ctrl)) {
-                       _log_err(LOG_ERR, pamh, "Can not get username");
+                       pam_syslog(pamh, LOG_ERR, "Can not get username");
                        return PAM_AUTHTOK_ERR;
                }
        }
        if (off(UNIX__IAMROOT, ctrl)) {
-#ifdef USE_CRACKLIB
-               remark = FascistCheck (pass_new, CRACKLIB_DICTS);
-               D(("called cracklib [%s]", remark));
-#else
-               if (strlen(pass_new) < 6)
+               if (strlen(pass_new) < pass_min_len)
                  remark = _("You must choose a longer password");
                D(("length check [%s]", remark));
-#endif
                if (on(UNIX_REMEMBER_PASSWD, ctrl)) {
                        if ((retval = check_old_password(user, pass_new)) == PAM_AUTHTOK_ERR)
                          remark = _("Password has been already used. Choose another.");
                        if (retval == PAM_ABORT) {
-                               _log_err(LOG_ERR, pamh, "can't open %s file to check old passwords",
+                               pam_syslog(pamh, LOG_ERR, "can't open %s file to check old passwords",
                                        OLD_PASSWORDS_FILE);
                                return retval;
                        }
@@ -1000,13 +529,14 @@ static int _pam_unix_approve_pass(pam_handle_t * pamh
        return retval;
 }
 
-
-PAM_EXTERN int pam_sm_chauthtok(pam_handle_t * pamh, int flags,
-                               int argc, const char **argv)
+int
+pam_sm_chauthtok(pam_handle_t *pamh, int flags, int argc, const char **argv)
 {
        unsigned int ctrl, lctrl;
-       int retval, i;
+       int retval;
        int remember = -1;
+       int rounds = -1;
+       int pass_min_len = 0;
 
        /* <DO NOT free() THESE> */
        const char *user;
@@ -1015,7 +545,8 @@ PAM_EXTERN int pam_sm_chauthtok(pam_handle_t * pamh, int flags,
 
        D(("called."));
 
-       ctrl = _set_ctrl(pamh, flags, &remember, argc, argv);
+       ctrl = _set_ctrl(pamh, flags, &remember, &rounds, &pass_min_len,
+                        argc, argv);
 
        /*
         * First get the name of a user
@@ -1024,20 +555,19 @@ 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)) {
-                       _log_err(LOG_ERR, pamh, "bad username [%s]", user);
+               if (user == NULL || user[0] == '-' || user[0] == '+') {
+                       pam_syslog(pamh, LOG_ERR, "bad username [%s]", user);
                        return PAM_USER_UNKNOWN;
                }
                if (retval == PAM_SUCCESS && on(UNIX_DEBUG, ctrl))
-                       _log_err(LOG_DEBUG, pamh, "username [%s] obtained",
+                       pam_syslog(pamh, LOG_DEBUG, "username [%s] obtained",
                                 user);
        } else {
                if (on(UNIX_DEBUG, ctrl))
-                       _log_err(LOG_DEBUG, pamh,
+                       pam_syslog(pamh, LOG_DEBUG,
                                 "password - could not identify user");
                return retval;
        }
@@ -1052,7 +582,7 @@ PAM_EXTERN int pam_sm_chauthtok(pam_handle_t * pamh, int flags,
         * came from, nor should it.  That's our job.
         */
        if (_unix_comesfromsource(pamh, user, 1, on(UNIX_NIS, ctrl)) == 0) {
-               _log_err(LOG_DEBUG, pamh,
+               pam_syslog(pamh, LOG_DEBUG,
                         "user \"%s\" does not exist in /etc/passwd%s",
                         user, on(UNIX_NIS, ctrl) ? " or NIS" : "");
                return PAM_USER_UNKNOWN;
@@ -1060,18 +590,11 @@ PAM_EXTERN int pam_sm_chauthtok(pam_handle_t * pamh, int flags,
                struct passwd *pwd;
                _unix_getpwnam(pamh, user, 1, 1, &pwd);
                if (pwd == NULL) {
-                       _log_err(LOG_DEBUG, pamh,
+                       pam_syslog(pamh, LOG_DEBUG,
                                "user \"%s\" has corrupted passwd entry",
                                user);
                        return PAM_USER_UNKNOWN;
                }
-               if (!_unix_shadowed(pwd) &&
-                   (strchr(pwd->pw_passwd, '*') != NULL)) {
-                       _log_err(LOG_DEBUG, pamh,
-                               "user \"%s\" does not have modifiable password",
-                               user);
-                       return PAM_USER_UNKNOWN;
-               }
        }
 
        /*
@@ -1092,18 +615,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) {
-                               _log_err(LOG_CRIT, pamh,
+                       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);
@@ -1116,8 +634,8 @@ PAM_EXTERN int pam_sm_chauthtok(pam_handle_t * pamh, int flags,
                        free(Announce);
 
                        if (retval != PAM_SUCCESS) {
-                               _log_err(LOG_NOTICE, pamh
-                                ,"password - (old) token not obtained");
+                               pam_syslog(pamh, LOG_NOTICE,
+                                   "password - (old) token not obtained");
                                return retval;
                        }
                        /* verify that this is the password for this user */
@@ -1137,7 +655,7 @@ PAM_EXTERN int pam_sm_chauthtok(pam_handle_t * pamh, int flags,
                retval = pam_set_item(pamh, PAM_OLDAUTHTOK, (const void *) pass_old);
                pass_old = NULL;
                if (retval != PAM_SUCCESS) {
-                       _log_err(LOG_CRIT, pamh,
+                       pam_syslog(pamh, LOG_CRIT,
                                 "failed to set PAM_OLDAUTHTOK");
                }
                retval = _unix_verify_shadow(pamh,user, ctrl);
@@ -1183,7 +701,7 @@ PAM_EXTERN int pam_sm_chauthtok(pam_handle_t * pamh, int flags,
                D(("pass_old [%s]", pass_old));
 
                if (retval != PAM_SUCCESS) {
-                       _log_err(LOG_NOTICE, pamh, "user not authenticated");
+                       pam_syslog(pamh, LOG_NOTICE, "user not authenticated");
                        return retval;
                }
 
@@ -1211,8 +729,8 @@ PAM_EXTERN int pam_sm_chauthtok(pam_handle_t * pamh, int flags,
 
                        if (retval != PAM_SUCCESS) {
                                if (on(UNIX_DEBUG, ctrl)) {
-                                       _log_err(LOG_ALERT, pamh
-                                                ,"password - new password not obtained");
+                                       pam_syslog(pamh, LOG_ALERT,
+                                                "password - new password not obtained");
                                }
                                pass_old = NULL;        /* tidy up */
                                return retval;
@@ -1228,60 +746,47 @@ PAM_EXTERN int pam_sm_chauthtok(pam_handle_t * pamh, int flags,
                        if (*(const char *)pass_new == '\0') {  /* "\0" password = NULL */
                                pass_new = NULL;
                        }
-                       retval = _pam_unix_approve_pass(pamh, ctrl, pass_old, pass_new);
+                       retval = _pam_unix_approve_pass(pamh, ctrl, pass_old,
+                                                       pass_new, pass_min_len);
+
+                       if (retval != PAM_SUCCESS && off(UNIX_NOT_SET_PASS, ctrl)) {
+                               pam_set_item(pamh, PAM_AUTHTOK, NULL);
+                       }
                }
 
                if (retval != PAM_SUCCESS) {
-                       _log_err(LOG_NOTICE, pamh,
+                       pam_syslog(pamh, LOG_NOTICE,
                                 "new password not acceptable");
                        pass_new = pass_old = NULL;     /* tidy up */
                        return retval;
                }
-#ifdef USE_LCKPWDF
-               /* These values for the number of attempts and the sleep time
-                  are, of course, completely arbitrary.
-                  My reading of the PAM docs is that, once pam_chauthtok() has been
-                  called with PAM_UPDATE_AUTHTOK, we are obliged to take any
-                  reasonable steps to make sure the token is updated; so retrying
-                  for 1/10 sec. isn't overdoing it. */
-               i=0;
-               while((retval = lckpwdf()) != 0 && i < 100) {
-                       usleep(1000);
-                       i++;
-               }
-               if(retval != 0) {
+               if (lock_pwdf() != PAM_SUCCESS) {
                        return PAM_AUTHTOK_LOCK_BUSY;
                }
-#endif
 
                if (pass_old) {
                        retval = _unix_verify_password(pamh, user, pass_old, ctrl);
                        if (retval != PAM_SUCCESS) {
-                               _log_err(LOG_NOTICE, pamh, "user password changed by another process");
-#ifdef USE_LCKPWDF
-                               ulckpwdf();
-#endif
+                               pam_syslog(pamh, LOG_NOTICE, "user password changed by another process");
+                               unlock_pwdf();
                                return retval;
                        }
                }
 
                retval = _unix_verify_shadow(pamh, user, ctrl);
                if (retval != PAM_SUCCESS) {
-                       _log_err(LOG_NOTICE, pamh, "user not authenticated 2");
-#ifdef USE_LCKPWDF
-                       ulckpwdf();
-#endif
+                       pam_syslog(pamh, LOG_NOTICE, "user shadow entry expired");
+                       unlock_pwdf();
                        return retval;
                }
 
-               retval = _pam_unix_approve_pass(pamh, ctrl, pass_old, pass_new);
+               retval = _pam_unix_approve_pass(pamh, ctrl, pass_old, pass_new,
+                                               pass_min_len);
                if (retval != PAM_SUCCESS) {
-                       _log_err(LOG_NOTICE, pamh,
+                       pam_syslog(pamh, LOG_NOTICE,
                                 "new password not acceptable 2");
                        pass_new = pass_old = NULL;     /* tidy up */
-#ifdef USE_LCKPWDF
-                       ulckpwdf();
-#endif
+                       unlock_pwdf();
                        return retval;
                }
 
@@ -1294,51 +799,13 @@ PAM_EXTERN int pam_sm_chauthtok(pam_handle_t * pamh, int flags,
                 * First we encrypt the new password.
                 */
 
-               if (on(UNIX_MD5_PASS, ctrl)) {
-                       tpass = crypt_md5_wrapper(pass_new);
-               } else {
-                       /*
-                        * Salt manipulation is stolen from Rick Faith's passwd
-                        * program.  Sorry Rick :) -- alex
-                        */
-
-                       time_t tm;
-                       char salt[3];
-
-                       time(&tm);
-                       salt[0] = bin_to_ascii(tm & 0x3f);
-                       salt[1] = bin_to_ascii((tm >> 6) & 0x3f);
-                       salt[2] = '\0';
-
-                       if (off(UNIX_BIGCRYPT, ctrl) && strlen(pass_new) > 8) {
-                               /*
-                                * to avoid using the _extensions_ of the bigcrypt()
-                                * function we truncate the newly entered password
-                                * [Problems that followed from this are fixed as per
-                                *  Bug 521314.]
-                                */
-                               char *temp = malloc(9);
-
-                               if (temp == NULL) {
-                                       _log_err(LOG_CRIT, pamh,
-                                                "out of memory for password");
-                                       pass_new = pass_old = NULL;     /* tidy up */
-#ifdef USE_LCKPWDF
-                                       ulckpwdf();
-#endif
-                                       return PAM_BUF_ERR;
-                               }
-                               /* copy first 8 bytes of password */
-                               strncpy(temp, pass_new, 8);
-                               temp[8] = '\0';
-
-                               /* no longer need cleartext */
-                               tpass = bigcrypt(temp, salt);
-
-                               _pam_delete(temp);      /* tidy up */
-                       } else {
-                               tpass = bigcrypt(pass_new, salt);
-                       }
+               tpass = create_password_hash(pamh, pass_new, ctrl, rounds);
+               if (tpass == NULL) {
+                       pam_syslog(pamh, LOG_CRIT,
+                               "crypt() failure or out of memory for password");
+                       pass_new = pass_old = NULL;     /* tidy up */
+                       unlock_pwdf();
+                       return PAM_BUF_ERR;
                }
 
                D(("password processed"));
@@ -1347,12 +814,12 @@ PAM_EXTERN int pam_sm_chauthtok(pam_handle_t * pamh, int flags,
 
                retval = _do_setpass(pamh, user, pass_old, tpass, ctrl,
                                     remember);
-               /* _do_setpass has called ulckpwdf for us */
+               /* _do_setpass has called unlock_pwdf for us */
 
                _pam_delete(tpass);
                pass_old = pass_new = NULL;
        } else {                /* something has broken with the module */
-               _log_err(LOG_ALERT, pamh,
+               pam_syslog(pamh, LOG_ALERT,
                         "password received unknown request");
                retval = PAM_ABORT;
        }
@@ -1361,17 +828,3 @@ PAM_EXTERN int pam_sm_chauthtok(pam_handle_t * pamh, int flags,
 
        return retval;
 }
-
-
-/* static module data */
-#ifdef PAM_STATIC
-struct pam_module _pam_unix_passwd_modstruct = {
-    "pam_unix_passwd",
-    NULL,
-    NULL,
-    NULL,
-    NULL,
-    NULL,
-    pam_sm_chauthtok,
-};
-#endif