]> granicus.if.org Git - linux-pam/commitdiff
Use hash from /etc/login.defs as default if no
authorThorsten Kukuk <kukuk@orinoco.thkukuk.de>
Tue, 18 Jun 2013 14:27:15 +0000 (16:27 +0200)
committerThorsten Kukuk <kukuk@orinoco.thkukuk.de>
Tue, 18 Jun 2013 14:27:15 +0000 (16:27 +0200)
other one is specified as argument.

* modules/pam_unix/support.c: Add search_key, call from __set_ctrl
* modules/pam_unix/support.h: Add define for /etc/login.defs
* modules/pam_unix/pam_unix.8.xml: Document new behavior.
* modules/pam_umask/pam_umask.c: Add missing NULL pointer check

modules/pam_umask/pam_umask.c
modules/pam_unix/pam_unix.8.xml
modules/pam_unix/support.c
modules/pam_unix/support.h

index 6d2ec1ac23bf40400d61e4ea5c3253c1fd89f356..863f0387c8d186c7080b03be992f08cb56513fd5 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2005, 2006, 2007, 2010 Thorsten Kukuk <kukuk@thkukuk.de>
+ * Copyright (c) 2005, 2006, 2007, 2010, 2013 Thorsten Kukuk <kukuk@thkukuk.de>
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -112,6 +112,10 @@ search_key (const char *filename)
         {
           buflen = BUF_SIZE;
           buf = malloc (buflen);
+         if (buf == NULL) {
+           fclose (fp);
+           return NULL;
+         }
         }
       buf[0] = '\0';
       if (fgets (buf, buflen - 1, fp) == NULL)
index 0a42d7a3dea8852e10651c1a82cd67ce1eda58c0..9ce084e36e7ce2c194b7ee4f69338b9ea0cce16e 100644 (file)
@@ -81,7 +81,9 @@
 
     <para>
       The password component of this module performs the task of updating
-      the user's password.
+      the user's password. The default encryption hash is taken from the
+      <emphasis remap='B'>ENCRYPT_METHOD</emphasis> variable from
+      <emphasis>/etc/login.defs</emphasis>
     </para>
 
     <para>
@@ -392,6 +394,9 @@ session    required   pam_unix.so
   <refsect1 id='pam_unix-see_also'>
     <title>SEE ALSO</title>
     <para>
+      <citerefentry>
+       <refentrytitle>login.defs</refentrytitle><manvolnum>5</manvolnum>
+      </citerefentry>,
       <citerefentry>
        <refentrytitle>pam.conf</refentrytitle><manvolnum>5</manvolnum>
       </citerefentry>,
index ab04535f485d51703a91216621b9bebf73342da4..f36786e450e58c23d70bbf3cce96933b5ac88708 100644 (file)
 #define SELINUX_ENABLED 0
 #endif
 
+static char *
+search_key (const char *key, const char *filename)
+{
+  FILE *fp;
+  char *buf = NULL;
+  size_t buflen = 0;
+  char *retval = NULL;
+
+  fp = fopen (filename, "r");
+  if (NULL == fp)
+    return NULL;
+
+  while (!feof (fp))
+    {
+      char *tmp, *cp;
+#if defined(HAVE_GETLINE)
+      ssize_t n = getline (&buf, &buflen, fp);
+#elif defined (HAVE_GETDELIM)
+      ssize_t n = getdelim (&buf, &buflen, '\n', fp);
+#else
+      ssize_t n;
+
+      if (buf == NULL)
+        {
+          buflen = BUF_SIZE;
+          buf = malloc (buflen);
+         if (buf == NULL) {
+           fclose (fp);
+           return NULL;
+         }
+        }
+      buf[0] = '\0';
+      if (fgets (buf, buflen - 1, fp) == NULL)
+        break;
+      else if (buf != NULL)
+        n = strlen (buf);
+      else
+        n = 0;
+#endif /* HAVE_GETLINE / HAVE_GETDELIM */
+      cp = buf;
+
+      if (n < 1)
+        break;
+
+      tmp = strchr (cp, '#');  /* remove comments */
+      if (tmp)
+        *tmp = '\0';
+      while (isspace ((int)*cp))    /* remove spaces and tabs */
+        ++cp;
+      if (*cp == '\0')        /* ignore empty lines */
+        continue;
+
+      if (cp[strlen (cp) - 1] == '\n')
+        cp[strlen (cp) - 1] = '\0';
+
+      tmp = strsep (&cp, " \t=");
+      if (cp != NULL)
+        while (isspace ((int)*cp) || *cp == '=')
+          ++cp;
+
+      if (strcasecmp (tmp, key) == 0)
+        {
+          retval = strdup (cp);
+          break;
+        }
+    }
+  fclose (fp);
+
+  free (buf);
+
+  return retval;
+}
+
+
 /* this is a front-end for module-application conversations */
 
 int _make_remark(pam_handle_t * pamh, unsigned int ctrl,
@@ -58,6 +132,8 @@ int _set_ctrl(pam_handle_t *pamh, int flags, int *remember, int *rounds,
              int *pass_min_len, int argc, const char **argv)
 {
        unsigned int ctrl;
+       char *val;
+       int j;
 
        D(("called."));
 
@@ -81,10 +157,38 @@ int _set_ctrl(pam_handle_t *pamh, int flags, int *remember, int *rounds,
                D(("SILENT"));
                set(UNIX__QUIET, ctrl);
        }
+
+       /* preset encryption method with value from /etc/login.defs */
+       val = search_key ("ENCRYPT_METHOD", LOGIN_DEFS);
+       if (val) {
+         for (j = 0; j < UNIX_CTRLS_; ++j) {
+           if (unix_args[j].token && unix_args[j].is_hash_algo
+               && !strncasecmp(val, unix_args[j].token, strlen(unix_args[j].token))) {
+             break;
+           }
+         }
+         if (j >= UNIX_CTRLS_) {
+           pam_syslog(pamh, LOG_WARNING, "unrecognized ENCRYPT_METHOD value [%s]", val);
+         } else {
+           ctrl &= unix_args[j].mask;  /* for turning things off */
+           ctrl |= unix_args[j].flag;  /* for turning things on  */
+         }
+         free (val);
+
+         /* read number of rounds for crypt algo */
+         if (on(UNIX_SHA256_PASS, ctrl) || on(UNIX_SHA512_PASS, ctrl)) {
+           val=search_key ("SHA_CRYPT_MAX_ROUNDS", LOGIN_DEFS);
+
+           if (val) {
+             *rounds = strtol(val, NULL, 10);
+             free (val);
+           }
+         }
+       }
+
        /* now parse the arguments to this module */
 
        for (; argc-- > 0; ++argv) {
-               int j;
 
                D(("pam_unix arg: %s", *argv));
 
index db4cd9537f56cc6f1a6372bf92681aa909dcca13..65759384fa90bde871686838c65d004a291b9846 100644 (file)
@@ -7,6 +7,12 @@
 
 #include <pwd.h>
 
+/*
+ * File to read value of ENCRYPT_METHOD from.
+ */
+#define LOGIN_DEFS "/etc/login.defs"
+
+
 /*
  * here is the string to inform the user that the new passwords they
  * typed were not the same.
@@ -20,6 +26,7 @@ typedef struct {
        const char *token;
        unsigned int mask;      /* shall assume 32 bits of flags */
        unsigned int flag;
+        unsigned int is_hash_algo;
 } UNIX_Ctrls;
 
 /*
@@ -100,34 +107,34 @@ static const UNIX_Ctrls unix_args[UNIX_CTRLS_] =
 /* symbol                  token name          ctrl mask             ctrl     *
  * ----------------------- ------------------- --------------------- -------- */
 
-/* UNIX__OLD_PASSWD */     {NULL,              _ALL_ON_,                  01},
-/* UNIX__VERIFY_PASSWD */  {NULL,              _ALL_ON_,                  02},
-/* UNIX__IAMROOT */        {NULL,              _ALL_ON_,                  04},
-/* UNIX_AUDIT */           {"audit",           _ALL_ON_,                 010},
-/* UNIX_USE_FIRST_PASS */  {"use_first_pass",  _ALL_ON_^(060),           020},
-/* UNIX_TRY_FIRST_PASS */  {"try_first_pass",  _ALL_ON_^(060),           040},
-/* UNIX_NOT_SET_PASS */    {"not_set_pass",    _ALL_ON_,                0100},
-/* UNIX__PRELIM */         {NULL,              _ALL_ON_^(0600),         0200},
-/* UNIX__UPDATE */         {NULL,              _ALL_ON_^(0600),         0400},
-/* UNIX__NONULL */         {NULL,              _ALL_ON_,               01000},
-/* UNIX__QUIET */          {NULL,              _ALL_ON_,               02000},
-/* UNIX_USE_AUTHTOK */     {"use_authtok",     _ALL_ON_,               04000},
-/* UNIX_SHADOW */          {"shadow",          _ALL_ON_,              010000},
-/* UNIX_MD5_PASS */        {"md5",            _ALL_ON_^(0260420000),  020000},
-/* UNIX__NULLOK */         {"nullok",          _ALL_ON_^(01000),           0},
-/* UNIX_DEBUG */           {"debug",           _ALL_ON_,              040000},
-/* UNIX_NODELAY */         {"nodelay",         _ALL_ON_,             0100000},
-/* UNIX_NIS */             {"nis",             _ALL_ON_,             0200000},
-/* UNIX_BIGCRYPT */        {"bigcrypt",       _ALL_ON_^(0260420000), 0400000},
-/* UNIX_LIKE_AUTH */       {"likeauth",        _ALL_ON_,            01000000},
-/* UNIX_REMEMBER_PASSWD */ {"remember=",       _ALL_ON_,            02000000},
-/* UNIX_NOREAP */          {"noreap",          _ALL_ON_,            04000000},
-/* UNIX_BROKEN_SHADOW */   {"broken_shadow",   _ALL_ON_,           010000000},
-/* UNIX_SHA256_PASS */     {"sha256",       _ALL_ON_^(0260420000), 020000000},
-/* UNIX_SHA512_PASS */     {"sha512",       _ALL_ON_^(0260420000), 040000000},
-/* UNIX_ALGO_ROUNDS */     {"rounds=",         _ALL_ON_,          0100000000},
-/* UNIX_BLOWFISH_PASS */   {"blowfish",    _ALL_ON_^(0260420000), 0200000000},
-/* UNIX_MIN_PASS_LEN */    {"minlen=",         _ALL_ON_,          0400000000},
+/* UNIX__OLD_PASSWD */     {NULL,              _ALL_ON_,                  01, 0},
+/* UNIX__VERIFY_PASSWD */  {NULL,              _ALL_ON_,                  02, 0},
+/* UNIX__IAMROOT */        {NULL,              _ALL_ON_,                  04, 0},
+/* UNIX_AUDIT */           {"audit",           _ALL_ON_,                 010, 0},
+/* UNIX_USE_FIRST_PASS */  {"use_first_pass",  _ALL_ON_^(060),           020, 0},
+/* UNIX_TRY_FIRST_PASS */  {"try_first_pass",  _ALL_ON_^(060),           040, 0},
+/* UNIX_NOT_SET_PASS */    {"not_set_pass",    _ALL_ON_,                0100, 0},
+/* UNIX__PRELIM */         {NULL,              _ALL_ON_^(0600),         0200, 0},
+/* UNIX__UPDATE */         {NULL,              _ALL_ON_^(0600),         0400, 0},
+/* UNIX__NONULL */         {NULL,              _ALL_ON_,               01000, 0},
+/* UNIX__QUIET */          {NULL,              _ALL_ON_,               02000, 0},
+/* UNIX_USE_AUTHTOK */     {"use_authtok",     _ALL_ON_,               04000, 0},
+/* UNIX_SHADOW */          {"shadow",          _ALL_ON_,              010000, 0},
+/* UNIX_MD5_PASS */        {"md5",            _ALL_ON_^(0260420000),  020000, 1},
+/* UNIX__NULLOK */         {"nullok",          _ALL_ON_^(01000),           0, 0},
+/* UNIX_DEBUG */           {"debug",           _ALL_ON_,              040000, 0},
+/* UNIX_NODELAY */         {"nodelay",         _ALL_ON_,             0100000, 0},
+/* UNIX_NIS */             {"nis",             _ALL_ON_,             0200000, 0},
+/* UNIX_BIGCRYPT */        {"bigcrypt",       _ALL_ON_^(0260420000), 0400000, 1},
+/* UNIX_LIKE_AUTH */       {"likeauth",        _ALL_ON_,            01000000, 0},
+/* UNIX_REMEMBER_PASSWD */ {"remember=",       _ALL_ON_,            02000000, 0},
+/* UNIX_NOREAP */          {"noreap",          _ALL_ON_,            04000000, 0},
+/* UNIX_BROKEN_SHADOW */   {"broken_shadow",   _ALL_ON_,           010000000, 0},
+/* UNIX_SHA256_PASS */     {"sha256",       _ALL_ON_^(0260420000), 020000000, 1},
+/* UNIX_SHA512_PASS */     {"sha512",       _ALL_ON_^(0260420000), 040000000, 1},
+/* UNIX_ALGO_ROUNDS */     {"rounds=",         _ALL_ON_,          0100000000, 0},
+/* UNIX_BLOWFISH_PASS */   {"blowfish",    _ALL_ON_^(0260420000), 0200000000, 1},
+/* UNIX_MIN_PASS_LEN */    {"minlen=",         _ALL_ON_,         0400000000, 0},
 };
 
 #define UNIX_DEFAULTS  (unix_args[UNIX__NONULL].flag)