Relevant BUGIDs:
authorThorsten Kukuk <kukuk@thkukuk.de>
Sun, 12 Mar 2006 10:26:29 +0000 (10:26 +0000)
committerThorsten Kukuk <kukuk@thkukuk.de>
Sun, 12 Mar 2006 10:26:29 +0000 (10:26 +0000)
Purpose of commit: bugfix/new feature

Commit summary:
---------------

2006-03-12  Thorsten Kukuk  <kukuk@thkukuk.de>

        * libpam/pam_item.c (pam_get_user): Check for valid pamh before
        using it.
        * tests/tst-pam_get_user.c: New.

ChangeLog
libpam/pam_item.c
tests/.cvsignore
tests/Makefile.am
tests/tst-pam_get_user.c [new file with mode: 0644]
tests/tst-pam_set_item.c

index fcb091c25390439fd7bcee464bdca4de4b56efa8..f8a99c4601eb9f5785369f9014cd5421d6ff4f12 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,21 +1,25 @@
 2006-03-12  Thorsten Kukuk  <kukuk@thkukuk.de>
 
+       * libpam/pam_item.c (pam_get_user): Check for valid pamh before
+       using it.
+
        * configure.in: create tests/Makefile
        * Makefile.am (SUBDIRS): Add tests
-       * tests/Makefile.am: New
-       * tests/tst-dlopen.c
-       * tests/tst-pam_acct_mgmt.c
-       * tests/tst-pam_authenticate.c
-       * tests/tst-pam_chauthtok.c
-       * tests/tst-pam_close_session.c
-       * tests/tst-pam_end.c
-       * tests/tst-pam_fail_delay.c
-       * tests/tst-pam_getenvlist.c
-       * tests/tst-pam_get_item.c
-       * tests/tst-pam_open_session.c
-       * tests/tst-pam_setcred.c
-       * tests/tst-pam_set_item.c
-       * tests/tst-pam_start.c
+       * tests/Makefile.am: New.
+       * tests/tst-dlopen.c: New.
+       * tests/tst-pam_acct_mgmt.c: New.
+       * tests/tst-pam_authenticate.c: New.
+       * tests/tst-pam_chauthtok.c: New.
+       * tests/tst-pam_close_session.c: New.
+       * tests/tst-pam_end.c: New.
+       * tests/tst-pam_fail_delay.c: New.
+       * tests/tst-pam_getenvlist.c: New.
+       * tests/tst-pam_get_item.c: New.
+       * tests/tst-pam_open_session.c: New.
+       * tests/tst-pam_setcred.c: New.
+       * tests/tst-pam_set_item.c: New.
+       * tests/tst-pam_start.c: New.
+       * tests/tst-pam_get_user.c: New.
 
        * modules/pam_access/Makefile.am: Add rules for make check
        * modules/pam_access/tst-pam_access: New
index 105a9de7bf66faa1623a447644304ad6fb2f6e1d..52efe80b24af950cf8bdfa2340fccf6050237bf0 100644 (file)
@@ -30,7 +30,7 @@ int pam_set_item (pam_handle_t *pamh, int item_type, const void *item)
     D(("called"));
 
     IF_NO_PAMH("pam_set_item", pamh, PAM_SYSTEM_ERR);
-    
+
     retval = PAM_SUCCESS;
 
     switch (item_type) {
@@ -118,7 +118,7 @@ int pam_set_item (pam_handle_t *pamh, int item_type, const void *item)
            retval = PAM_PERM_DENIED;
        } else {
            struct pam_conv *tconv;
-           
+
            if ((tconv=
                 (struct pam_conv *) malloc(sizeof(struct pam_conv))
                ) == NULL) {
@@ -223,7 +223,7 @@ int pam_get_item (const pam_handle_t *pamh, int item_type, const void **item)
     default:
        retval = PAM_BAD_ITEM;
     }
-  
+
     return retval;
 }
 
@@ -239,13 +239,15 @@ int pam_get_user(pam_handle_t *pamh, const char **user, const char *prompt)
     struct pam_response *resp;
 
     D(("called."));
-    if (user == NULL) {  /* ensure that the module has supplied a destination */
+
+    IF_NO_PAMH("pam_get_user", pamh, PAM_SYSTEM_ERR);
+
+    if (user == NULL) {
+        /* ensure that the module has supplied a destination */
        pam_syslog(pamh, LOG_ERR, "pam_get_user: nowhere to record username");
        return PAM_PERM_DENIED;
     } else
        *user = NULL;
-    
-    IF_NO_PAMH("pam_get_user", pamh, PAM_SYSTEM_ERR);
 
     if (pamh->pam_conversation == NULL) {
        pam_syslog(pamh, LOG_ERR, "pam_get_user: no conv element in pamh");
@@ -261,13 +263,12 @@ int pam_get_user(pam_handle_t *pamh, const char **user, const char *prompt)
        return pamh->former.fail_user;
 
     /* will need a prompt */
-    use_prompt = prompt;
-    if (use_prompt == NULL) {
-       use_prompt = pamh->prompt;
-       if (use_prompt == NULL) {
-           use_prompt = _("login:");
-       }
-    }
+    if (prompt != NULL)
+      use_prompt = prompt;
+    else if (pamh->prompt != NULL)
+      use_prompt = pamh->prompt;
+    else
+      use_prompt = _("login:");
 
     /* If we are resuming an old conversation, we verify that the prompt
        is the same.  Anything else is an error. */
index 0ab179e81e4ac5a11d930a5b58660ea580a7b99b..9833ca6806ed89193f3e512b46782d7bf4678b52 100644 (file)
@@ -11,6 +11,7 @@ tst-pam_close_session
 tst-pam_end
 tst-pam_fail_delay
 tst-pam_get_item
+tst-pam_get_user
 tst-pam_getenvlist
 tst-pam_open_session
 tst-pam_set_item
index 035a9ceca01b8e6a0ed9472caf60bc59419e1fca..4f0d6a567ee849380aae3452948e23b7646dac9f 100644 (file)
@@ -10,7 +10,7 @@ CLEANFILES = *~
 TESTS = tst-pam_start tst-pam_end tst-pam_fail_delay tst-pam_open_session \
        tst-pam_close_session tst-pam_acct_mgmt tst-pam_authenticate \
        tst-pam_chauthtok tst-pam_setcred tst-pam_get_item tst-pam_set_item \
-       tst-pam_getenvlist
+       tst-pam_getenvlist tst-pam_get_user
 
 check_PROGRAMS = ${TESTS} tst-dlopen
 
diff --git a/tests/tst-pam_get_user.c b/tests/tst-pam_get_user.c
new file mode 100644 (file)
index 0000000..916c6cc
--- /dev/null
@@ -0,0 +1,172 @@
+/*
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, and the entire permission notice in its entirety,
+ *    including the disclaimer of warranties.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote
+ *    products derived from this software without specific prior
+ *    written permission.
+ *
+ * ALTERNATIVELY, this product may be distributed under the terms of
+ * the GNU Public License, in which case the provisions of the GPL are
+ * required INSTEAD OF the above restrictions.  (This clause is
+ * necessary due to a potential bad interaction between the GPL and
+ * the restrictions contained in a BSD-style copyright.)
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <config.h>
+
+#include <stdio.h>
+#include <unistd.h>
+#include <string.h>
+#include <stdlib.h>
+#include <security/pam_appl.h>
+#include <security/pam_modules.h>
+
+static const char *prompt = "myprompt:";
+static const char *user = "itsme";
+
+static int
+login_conv (int num_msg, const struct pam_message **mesg,
+           struct pam_response **resp, void *appdata_ptr UNUSED)
+{
+  struct pam_response *reply;
+  int count;
+
+  reply = calloc(num_msg, sizeof (struct pam_response));
+
+  if (reply == NULL)
+    return PAM_BUF_ERR;
+
+  for (count = 0; count < num_msg; count++)
+    {
+      reply[count].resp_retcode = 0;
+      reply[count].resp = NULL;
+
+      switch (mesg[count]->msg_style)
+       {
+       case PAM_PROMPT_ECHO_ON:
+         if (strcmp (mesg[count]->msg, prompt) != 0)
+           {
+             fprintf (stderr, "conv function called with wrong prompt: %s\n",
+                      mesg[count]->msg);
+             exit (1);
+           }
+         reply[count].resp = strdup (user);
+         break;
+
+       default:
+         fprintf (stderr,
+            "pam_get_user calls conv function with unexpected msg style");
+         exit (1);
+        }
+    }
+
+  *resp = reply;
+  return PAM_SUCCESS;
+}
+
+int
+main (void)
+{
+  const char *service = "dummy";
+  const char *value;
+  struct pam_conv conv = { &login_conv, NULL};
+  pam_handle_t *pamh;
+  int retval;
+
+  /* 1: Call with NULL for every argument */
+  retval = pam_get_user (NULL, NULL, NULL);
+  if (retval == PAM_SUCCESS)
+    {
+      fprintf (stderr,
+               "tst-pam_get_user (NULL, NULL, NULL) returned PAM_SUCCESS\n");
+      return 1;
+    }
+
+ /* setup pam handle */
+  retval = pam_start (service, user, &conv, &pamh);
+  if (retval != PAM_SUCCESS)
+    {
+      fprintf (stderr, "pam_start (%s, %s, &conv, &pamh) returned %d\n",
+               service, user, retval);
+      return 1;
+    }
+
+  /* 2: Call with valid pamh handle but NULL for user */
+  retval = pam_get_user (pamh, NULL, NULL);
+  if (retval == PAM_SUCCESS)
+    {
+      fprintf (stderr,
+               "tst-pam_get_user (pamh, NULL, NULL) returned PAM_SUCCESS\n");
+      return 1;
+    }
+
+  /* 3: Call with valid pamh handle and valid user ptr */
+  retval = pam_get_user (pamh, &value, NULL);
+  if (retval != PAM_SUCCESS)
+    {
+      fprintf (stderr,
+               "tst-pam_get_user (pamh, &value, NULL) returned %d\n",
+              retval);
+      return 1;
+    }
+  if (strcmp (user, value) != 0)
+    {
+      fprintf (stderr,
+               "tst-pam_get_user (pamh, &value, NULL) mismatch:\n"
+              "expected: %s\n"
+              "got: %s\n", user, value);
+      return 1;
+    }
+
+  pam_end (pamh, 0);
+
+ /* setup pam handle without user */
+  retval = pam_start (service, NULL, &conv, &pamh);
+  if (retval != PAM_SUCCESS)
+    {
+      fprintf (stderr, "pam_start (%s, %s, &conv, &pamh) returned %d\n",
+               service, user, retval);
+      return 1;
+    }
+
+  /* 4: Call with valid pamh handle and valid user ptr */
+  retval = pam_get_user (pamh, &value, prompt);
+  if (retval != PAM_SUCCESS)
+    {
+      fprintf (stderr,
+               "tst-pam_get_user (pamh, &value, prompt) returned %d\n",
+              retval);
+      return 1;
+    }
+  if (strcmp (user, value) != 0)
+    {
+      fprintf (stderr,
+               "tst-pam_get_user (pamh, &value, prompt) mismatch:\n"
+              "expected: %s\n"
+              "got: %s\n", user, value);
+      return 1;
+    }
+
+  pam_end (pamh, 0);
+
+  return 0;
+}
index ecc68e6c4b3fc3c349ae3b8bd37f89943a470e53..29944bdc6f38ce36a39b9750e71072104624a5ca 100644 (file)
@@ -33,6 +33,7 @@
 
 #include <stdio.h>
 #include <unistd.h>
+#include <string.h>
 
 #include <security/pam_appl.h>
 
@@ -132,7 +133,7 @@ main (void)
              fprintf (stderr,
                       "pam_get_item got wrong value:\n"
                       "expected: %s\n"
-                      "got: %s\n", items[i].new_value, value);
+                      "got: %s\n", items[i].new_value, (const char *)value);
              return 1;
            }
        }