The bug report that I thought I still needed to put to rest is this one: http://sourceforge.net/tracker/index.php?func=detail&aid=424315&group_id=6663&atid=106663 This Red Hat patch appears to concern legacy behavior. Something that I do appear to have broken. At first glance their patch looks correct. I'll make sure to include this support in the next release. Thanks for making me aware of it! http://sourceforge.net/tracker/index.php?func=detail&aid=468724&group_id=6663&atid=106663 [With respect to your code example, it looks like you never set 'retv'.] Cheers Andrew "S. Park" wrote: > > 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. > > _______________________________________________ > > Pam-list@redhat.com > https://listman.redhat.com/mailman/listinfo/pam-list