Date: Sun, 5 Oct 2003 10:39:02 -0700 (PDT) From: =?ISO-8859-1?Q?Mikko_Ty=F6l=E4j=E4rvi?= <mbsd@pacbell.net> To: Bill Campbell <freebsd@celestial.com> Cc: freebsd-questions@FreeBSD.ORG Subject: Re: Anyone using Linux-PAM on 5.x? Message-ID: <20031005103043.G3248@atlas.home> In-Reply-To: <20031005003251.GA20735@alexis.mi.celestial.com> References: <3F7F29C5.7030606@relia.net> <20031004164554.X3248@atlas.home> <20031005003251.GA20735@alexis.mi.celestial.com>
next in thread | previous in thread | raw e-mail | index | archive | help
On Sat, 4 Oct 2003, Bill Campbell wrote: > On Sat, Oct 04, 2003, Mikko Työläjärvi wrote: > ... > >Having had some experience writing pam modules on a number of > >platforms, I whipped out my suite of pam test modules to have a look > >at this incredbible breakage you speak of. I mean, there is a > >specification for pam after all. > > Could you suggest where to look for information on writing modules to > handle session tasks? I've looked at the PAM stuff superficially over the > years, and would be very interested in doing something with the session > modules to do things like automatically creating missing home directories > with appropriate links to automounted directories. > > I haven't done much with this on FreeBSD yet since I need pam_ldap and > nss_ldap support which only seems to be available in the 5.x tree. Well, it isn't exactly rocket science, just a small matter of programming. The pam interface itself is not very complicated; any decent programmer can pick it up in an afternoon. The specification can be downloaded from the OpenGroup, abd google will happily locate lots of sample code of varying quality for you. Modules aren't harder to port than any other code, the actual pam bits are mostly the same, modulo non-standard utility extensions, but those are usually trivial to port, replace or re-implement. One of the problems with pam is that there are very few guarantees on the context the module will be called in will look like. Will the uid be zero, or that of a user? Will all phases of the module be called from inside the same process? Will the session be closed twice after a fork? Will the service name stay the same over all phases? Trying to do anything more clever than verifying a password quickly leads to a jungle of special cases (number of pamified applications times number of platforms). Attempts at managing some kind of state between modules or different callbacks in the same module are more or less doomed to fail. Anyhow, just for kicks I grabbed the pam_mkhomedir module from RedHat9, and made it build on FreeBSD. It involved fixing the usual linuxisms (remove non-standard header files, add missing standard header files), and adding some FreeBSD-isms, like the leading "dot." used for template files. A quick test with telnet shows that it seems to work, at least once :) The test also illustrates how the interaction between application and pam doesn't always work smoothly: the FreeBSD login program will already have discovered there there is no home directory, printed an error message and potentially denied access before the session modules are invoked. Thus there login messages contain: No home directory. Logging in with home = "/". Creating directory '/home/testguy'. And then, as a band-aid, I threw in a chdir($HOME) in the session module to avoid having the user end up in "/". Patch and build instructions below. Comes with no warranty. Slippery when wet. May cause bodily injury. Will probably break with NFS automounted home dirs. Etc... Enjoy, /Mikko Build: fetch ftp://ftp.redhat.com/pub/redhat/linux/9/en/os/i386/SRPMS/pam-0.75-48.src.rpm rpm2cpio pam-0.75-48.src.rpm > pam-0.75-48.src.cpio cpio -id < pam-0.75-48.src.cpio tar jxf Linux-PAM-0.75.tar.bz2 patch < pam-0.75-mkhomedir-recurse.patch cd Linux-PAM-0.75/modules/pam_mkhomedir patch < THIS_FILE cc -Wall -shared -fpic -o pam_mkhomedir.so pam_mkhomedir.c -lpam Patch: --- pam_mkhomedir.c.rh9 Sat Oct 4 22:10:49 2003 +++ pam_mkhomedir.c Sat Oct 4 22:14:51 2003 @@ -39,6 +39,8 @@ #include <stdio.h> #include <string.h> #include <dirent.h> +#include <syslog.h> +#include <limits.h> /* * here, we make a definition for the externally accessible function @@ -50,14 +52,15 @@ #define PAM_SM_SESSION #include <security/pam_modules.h> -#include <security/_pam_macros.h> +#include <security/pam_appl.h> +#define D(x) /* argument parsing */ #define MKHOMEDIR_DEBUG 020 /* keep quiet about things */ #define MKHOMEDIR_QUIET 040 /* keep quiet about things */ static unsigned int UMask = 0022; -static char SkelDir[BUFSIZ] = "/etc/skel"; +static char SkelDir[BUFSIZ] = "/usr/share/skel"; /* some syslogging */ static void _log_err(int err, const char *format, ...) @@ -151,15 +154,12 @@ mesg[0] = &msg[0]; msg[0].msg_style = PAM_TEXT_INFO; - msg[0].msg = remark; + msg[0].msg = (char *)remark; retval = converse(pamh, ctrl, 1, mesg, &resp); msg[0].msg = NULL; - if (resp) - { - _pam_drop_reply(resp, 1); - } + free(resp); } else { @@ -232,7 +232,8 @@ continue; /* We'll need the new file's name. */ - snprintf(newdest,sizeof(newdest),"%s/%s",dest,Dir->d_name); + snprintf(newdest,sizeof(newdest),"%s/%s",dest,Dir->d_name + + (strncmp(Dir->d_name, "dot.", 4) == 0 ? 3 : 0)); /* If it's a directory, recurse. */ if (S_ISDIR(St.st_mode)) @@ -351,7 +352,10 @@ if (stat(pwd->pw_dir,&St) == 0) return PAM_SUCCESS; - return create_homedir(pamh,ctrl,pwd,SkelDir,pwd->pw_dir); + retval = create_homedir(pamh,ctrl,pwd,SkelDir,pwd->pw_dir); + chdir(pwd->pw_dir); /* XXX */ + + return retval; } /* Ignore */
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20031005103043.G3248>