Discrepancy between Linux-PAM-0.75 and pam-redhat-0.75

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



This is an observation from the continuing study of the problem w/ 
PAM-0.75 and gdm-2.2.4 for which I posted earlier. I just installed 
Mandrake 8.1 (my box runs 3 different flavors of Linux), and realized it 
contained pam-0.75 and gdm-2.2.4.1 and they worked.
For the sake of curiosity, I tried to find how they do that, and found 
the code pam_dispatch.c of Mandrake (and Red Hat) pam-0.75 was different 
from Linux-PAM-0.75. Here is the diff:

 >>>
--- pam_dispatch.c.orig    Mon Feb  5 00:50:41 2001
+++ pam_dispatch.c    Mon Apr 23 17:32:19 2001
@@ -3,7 +3,7 @@
 /*
  * Copyright (c) 1998 Andrew G. Morgan <morgan@kernel.org>
  *
- * $Id: pam_dispatch.c,v 1.3 2001/02/05 06:50:41 agmorgan Exp $
+ * $Id: pam_dispatch.c,v 1.2 2001/04/23 22:32:19 nalin Exp $
  */
 
 #include <stdlib.h>
@@ -99,10 +99,14 @@
         return retval;
     }
 
+    cached_retval = -1;
+
     if (use_cached_chain) {
         /* a former stack execution has frozen the chain */
         cached_retval = *(h->cached_retval_p);
-    } else {
+    }
+
+    if (cached_retval == -1) {
         /* this stack execution is defining the frozen chain */
         cached_retval = h->cached_retval = retval;
     }
 >>>

And here is a small program which has similar structure of gdm-2.2.4.1 
and I used for testing:
 >>>
/*
  This program was contributed by Shane Watts
  [modifications by AGM]

  You need to add the following (or equivalent) to the /etc/pam.conf file.
  # check authorization
  check_user   auth       required     /usr/lib/security/pam_unix_auth.so
  check_user   account    required     /usr/lib/security/pam_unix_acct.so
 */

#include <security/pam_appl.h>
#include <security/pam_misc.h>
#include <stdio.h>

int first_part(void);
int second_park(void);

static struct pam_conv conv = {
    misc_conv,
    NULL
};

static const char *user="nobody";
static pam_handle_t *pamh=NULL;

int first_part(void)
{

    int retval, retv;

    retval = pam_start("check_user", user, &conv, &pamh);
       
    if (retval == PAM_SUCCESS)
     {
    retval = pam_authenticate(pamh, 0);    /* is user really user? */

    if (retval == PAM_SUCCESS)
      retval = pam_acct_mgmt(pamh, 0);       /* permitted access? */
     }
  
    /* This is where we have been authorized or not. */

   if (retval != PAM_SUCCESS)
     fprintf(stdout, "Failed at Authentication: %d\n", retval);

   if (pam_end(pamh,retv) != PAM_SUCCESS) {
        pamh = NULL;
        fprintf(stderr, "check_user: failed to release authenticator\n");
        exit(1);
    }

    return ( retval == PAM_SUCCESS ? 0:1 );       /* indicate success */
}

int second_part(void)
{

    int retval, retv;

    retval = pam_start("check_user", user, &conv, &pamh);
       
    if (retval == PAM_SUCCESS) {
       retval = pam_setcred (pamh, 0);

       if (retval != PAM_SUCCESS) {
      fprintf(stdout, "Failed at setcred: %d\n", retval);
       } else {
      retval = pam_open_session (pamh, 0);
      
      if (retval != PAM_SUCCESS) {
         fprintf(stdout, "Failed at open_session: %d\n", retval);
      }
       }
    }
  
    if (pam_end(pamh,retv) != PAM_SUCCESS) {     /* close Linux-PAM */
        pamh = NULL;
        fprintf(stderr, "check_user: failed to release authenticator\n");
        exit(1);
    }

    return ( retval == PAM_SUCCESS ? 0:1 );       /* indicate success */
}

int main(int argc, char *argv[])
{
    int retval;

    if(argc == 2) {
        user = argv[1];
    }

    if(argc > 2) {
        fprintf(stderr, "Usage: check_user [username]\n");
        exit(1);
    }

    retval = first_part();
       
    if (retval == PAM_SUCCESS) {
        fprintf(stdout, "first part done\n");
        retval = second_part();
        if (retval == PAM_SUCCESS) {
       fprintf(stdout, "second part done\n");
    } else {
       fprintf(stdout, "second part failed\n");
    }
    } else {
        fprintf(stdout, "first part failed\n");
    }

    return ( retval == PAM_SUCCESS ? 0:1 );       /* indicate success */
}
 >>>
# /etc/pam.d/check_user
#
auth       required   pam_unix.so likeauth nullok
account    required   pam_unix.so
password   required   pam_cracklib.so retry=3
password   required   pam_unix.so shadow md5 use_authtok
session    required   pam_unix.so
#
# End
 >>>
As you can see, pam_end is called at the end of the first function. If I 
use this program w/ Linux-PAM-0.74 or (Red Hat/MDK) pam-0.75, the second 
function works. However, w/ Linux-PAM-0.75, it doesn't. And from the 
previous posting, I was told it shouldn't work. For curiosity, could 
somebody let me know which is the correct way to use PAM - original 
pam_dispatch.c or Red Hat's patched pam_dispatch.c

By the way, gdm people fixed this problem in the new 2.2.4.2 so that it 
works with the genuine PAM-0.75.

Best regards.





[Index of Archives]     [Fedora Users]     [Kernel]     [Red Hat Install]     [Linux for the blind]     [Gimp]

  Powered by Linux