Hello, I've recently done some work for http://www.siriusit.co.uk/ to carry out a pam-ldap and nss-ldap installation on some RHEL4, Solaris machines. It appears that Solaris doesn't have any functionality at the PAM level to limit which users can access a service (by user-name list, or group etc.). There is some support for this functionality at application level, but it is inconsistent, and will apply to users from all of the password databases, (not just LDAP which is what we needed).... I got this functionality on the Linux boxes using pam_listfile, and since http://www.kernel.org/pub/linux/libs/pam/whereislinuxpam.html says that people use it on Solaris, I thought I'd give it a go. It would appear to have been a while since Linux-PAM compiled on Solaris out-of-the-box... The attached patch is a bit rough (particularly the pam_lastlog bit, which you may want to drop - unfortunately, this project has already over-run considerably, and I don't have time to fix it), but may be a good starting point.... Also attached are some notes on building under Solaris 8 and 10, which are hopefully of some use. Thanks, and keep up the good work! Tim.
diff -aur Linux-PAM-1.0.1.orig/libpam/include/security/pam_modutil.h Linux-PAM-1.0.1/libpam/include/security/pam_modutil.h --- Linux-PAM-1.0.1.orig/libpam/include/security/pam_modutil.h 2007-12-07 15:40:01.000000000 +0000 +++ Linux-PAM-1.0.1/libpam/include/security/pam_modutil.h 2008-07-08 12:43:18.815053000 +0100 @@ -51,6 +51,10 @@ extern "C" { #endif +#ifdef __sun__ +#include <sys/types.h> +#endif + #include <security/_pam_types.h> extern struct passwd * PAM_NONNULL((1,2)) diff -aur Linux-PAM-1.0.1.orig/libpam/pam_modutil_getpwnam.c Linux-PAM-1.0.1/libpam/pam_modutil_getpwnam.c --- Linux-PAM-1.0.1.orig/libpam/pam_modutil_getpwnam.c 2007-08-30 05:00:39.000000000 +0100 +++ Linux-PAM-1.0.1/libpam/pam_modutil_getpwnam.c 2008-07-21 14:19:38.211561000 +0100 @@ -7,6 +7,10 @@ * XXX - or at least it should provide a thread-safe alternative. */ +#ifdef __sun__ +#define _POSIX_PTHREAD_SEMANTICS +#endif + #include "pam_modutil_private.h" #include <errno.h> diff -aur Linux-PAM-1.0.1.orig/libpam/pam_modutil_getspnam.c Linux-PAM-1.0.1/libpam/pam_modutil_getspnam.c --- Linux-PAM-1.0.1.orig/libpam/pam_modutil_getspnam.c 2007-08-30 05:00:39.000000000 +0100 +++ Linux-PAM-1.0.1/libpam/pam_modutil_getspnam.c 2008-07-08 15:36:31.663293000 +0100 @@ -53,9 +53,19 @@ /* make the re-entrant call to get the spwd structure */ errno = 0; +#ifdef __sun__ + result = getspnam_r(user, buffer, + sizeof(struct spwd) + (char *) buffer, + length); + if (result) + status = 0; + else + status = -1; +#else status = getspnam_r(user, buffer, sizeof(struct spwd) + (char *) buffer, length, &result); +#endif /* __sun__ */ if (!status && (result == buffer)) { char *data_name; const void *ignore; diff -aur Linux-PAM-1.0.1.orig/libpam/pam_modutil_private.h Linux-PAM-1.0.1/libpam/pam_modutil_private.h --- Linux-PAM-1.0.1.orig/libpam/pam_modutil_private.h 2005-09-21 11:00:58.000000000 +0100 +++ Linux-PAM-1.0.1/libpam/pam_modutil_private.h 2008-07-08 14:03:32.183706000 +0100 @@ -7,6 +7,10 @@ * Copyright (c) 2001 Andrew Morgan <morgan@xxxxxxxxxx> */ +#ifdef __sun__ +#define _POSIX_PTHREAD_SEMANTICS +#endif + #include "config.h" #include <security/_pam_macros.h> diff -aur Linux-PAM-1.0.1.orig/libpam/pam_private.h Linux-PAM-1.0.1/libpam/pam_private.h --- Linux-PAM-1.0.1.orig/libpam/pam_private.h 2007-12-06 20:20:07.000000000 +0000 +++ Linux-PAM-1.0.1/libpam/pam_private.h 2008-07-21 14:20:35.526273000 +0100 @@ -22,6 +22,11 @@ #include <security/pam_modules.h> #include <security/pam_ext.h> +#ifdef __sun__ +#include "../../gcc-4.3.1/include/libiberty.h" +#endif + + /* the Linux-PAM configuration file */ #define PAM_CONFIG "/etc/pam.conf" diff -aur Linux-PAM-1.0.1.orig/libpamc/include/security/pam_client.h Linux-PAM-1.0.1/libpamc/include/security/pam_client.h --- Linux-PAM-1.0.1.orig/libpamc/include/security/pam_client.h 2005-05-20 15:58:58.000000000 +0100 +++ Linux-PAM-1.0.1/libpamc/include/security/pam_client.h 2008-07-08 17:13:25.969013000 +0100 @@ -18,6 +18,11 @@ #include <stdio.h> #include <sys/types.h> +#ifdef __sun__ +typedef uint32_t u_int32_t; +typedef uint8_t u_int8_t; +#endif + /* opaque agent handling structure */ typedef struct pamc_handle_s *pamc_handle_t; diff -aur Linux-PAM-1.0.1.orig/modules/pam_filter/upperLOWER/upperLOWER.c Linux-PAM-1.0.1/modules/pam_filter/upperLOWER/upperLOWER.c --- Linux-PAM-1.0.1.orig/modules/pam_filter/upperLOWER/upperLOWER.c 2008-02-13 14:39:41.000000000 +0000 +++ Linux-PAM-1.0.1/modules/pam_filter/upperLOWER/upperLOWER.c 2008-07-08 17:31:03.544275000 +0100 @@ -18,6 +18,12 @@ #include "pam_filter.h" #include <security/pam_modutil.h> +#ifdef __sun__ +/* FIXME Is this the correct fix for Solaris? + <netinet/ip_compat.h> defines this on S10 */ +#define LOG_AUTHPRIV (10<<3) +#endif + /* ---------------------------------------------------------------- */ static void do_transpose(char *buffer,int len) diff -aur Linux-PAM-1.0.1.orig/modules/pam_lastlog/pam_lastlog.c Linux-PAM-1.0.1/modules/pam_lastlog/pam_lastlog.c --- Linux-PAM-1.0.1.orig/modules/pam_lastlog/pam_lastlog.c 2006-08-24 19:29:30.000000000 +0100 +++ Linux-PAM-1.0.1/modules/pam_lastlog/pam_lastlog.c 2008-07-21 14:32:28.768750000 +0100 @@ -27,8 +27,9 @@ #include <syslog.h> #include <unistd.h> -#if defined(hpux) || defined(sunos) || defined(solaris) +#if defined(hpux) || defined(sunos) || defined(solaris) || defined(__sun__) # ifndef _PATH_LASTLOG +# include <lastlog.h> # define _PATH_LASTLOG "/usr/adm/lastlog" # endif /* _PATH_LASTLOG */ # ifndef UT_HOSTSIZE @@ -46,6 +47,14 @@ }; #endif /* hpux */ + +#if defined (__sun__) && defined(__GNUC__) +#include <utmpx.h> +#include <sys/stat.h> +extern int asprintf (char **, const char *, ...); +#endif + + /* XXX - time before ignoring lock. Is 1 sec enough? */ #define LASTLOG_IGNORE_LOCK_TIME 1 @@ -310,7 +319,20 @@ if (announce & LASTLOG_WTMP) { /* write wtmp entry for user */ +#if defined (__sun__) && defined(__GNUC__) + struct utmpx utx; + /* Set information in new entry. */ + memset (&utx, 0, sizeof (utx)); + utx.ut_pid = getpid(); + utx.ut_type = LOGIN_PROCESS; + strncpy (utx.ut_host, remote_host, sizeof utx.ut_host); + utx.ut_syslen = strlen(remote_host) + 1; + strncpy (utx.ut_user, user, sizeof utx.ut_user); + strncpy (utx.ut_line, terminal_line, sizeof utx.ut_line); + updwtmpx (_WTMPX_FILE, &utx); +#else logwtmp(last_login.ll_line, user, remote_host); +#endif } /* cleanup */ @@ -425,10 +447,37 @@ if (!(_pam_parse(pamh, flags, argc, argv) & LASTLOG_WTMP)) return PAM_SUCCESS; +#ifndef __sun__ terminal_line = get_tty(pamh); /* Wipe out utmp logout entry */ logwtmp(terminal_line, "", ""); +#else + + struct utmpx entry; + memset (&entry, 0, sizeof (entry)); + + +/* entry.ut_type=USER_PROCESS; + entry.ut_pid=getpid(); + strncpy (entry.ut_line, terminal_line, sizeof entry.ut_line); + time(&entry.ut_time); + strncpy(entry.ut_user,getpwuid(getuid())->pw_name, sizeof entry.ut_user); + setutent(); + pututline(&entry); + + system("echo after adding entry:;who"); +*/ + entry.ut_type=DEAD_PROCESS; +/* memset(entry.ut_line,0,UT_LINESIZE); + entry.ut_time=0; + memset(entry.ut_user,0,UT_NAMESIZE); */ + setutxent(); + pututxline(&entry); + + + endutxent(); +#endif return PAM_SUCCESS; } diff -aur Linux-PAM-1.0.1.orig/modules/pam_unix/passverify.c Linux-PAM-1.0.1/modules/pam_unix/passverify.c --- Linux-PAM-1.0.1.orig/modules/pam_unix/passverify.c 2008-01-28 13:20:29.000000000 +0000 +++ Linux-PAM-1.0.1/modules/pam_unix/passverify.c 2008-07-18 14:00:32.629536000 +0100 @@ -47,6 +47,13 @@ # include "./lckpwdf.-c" #endif +#ifdef __sun__ +/* <netinet/ip_compat.h> defines this on S10, but + we don't want to include the whole file... */ +#define LOG_AUTHPRIV (10<<3) +#endif + + static void strip_hpux_aging(char *hash) { diff -aur Linux-PAM-1.0.1.orig/modules/pam_unix/support.c Linux-PAM-1.0.1/modules/pam_unix/support.c --- Linux-PAM-1.0.1.orig/modules/pam_unix/support.c 2008-01-23 15:35:13.000000000 +0000 +++ Linux-PAM-1.0.1/modules/pam_unix/support.c 2008-07-18 13:52:16.518083000 +0100 @@ -35,6 +35,10 @@ #define SELINUX_ENABLED 0 #endif +#if defined (__sun__) +#define YPERR_SUCCESS 0 +#endif + /* this is a front-end for module-application conversations */ int _make_remark(pam_handle_t * pamh, unsigned int ctrl,
This document was written in 2008 by tim@xxxxxxxxxxx for Sirius - http://www.siriusit.co.uk/ This document is covered by the same licensing as "Linux-PAM-1.0.1" package - see Linux-PAM-1.0.1/COPYING for details. It is necessary to build the Linux PAM stack "Linux-PAM" to get various useful bits which are missing from the Solaris PAM stack. In particular, I built this because there is no equivalent to pam_listfile.so in Solaris. Status: A few modules won't compile or work under Solaris without additional patches: Solaris 10: pam_limits: There is a warning to the affect that the code is only known to work on Linux, compilation fails, I didn't investage further. Disable as workaround. pam_xauth: Uses the fsuid() call, which is not present on Solaris. Disable as workaround. Solaris 8: Modules which don't work on Solaris 10 also don't work on Solaris 8 - additionally - pam_mail: Doesn't compile, possibly because alphasort is documented as non-thread-safe. May be fixable, didn't investiage further. Disable as workaround. pam_unix: Doesn't compile - seems to be missing some signal number definitions. May be fixable, didn't investiage further. Disable as workaround. Caveats: I built using gcc from the "Blastwave" repository of GNU tools for Solaris. You will need at least gcc and flex (probably others). Install the "gnulinks" package, and put "/opt/csw/gnu" in your shell's binary search PATH. . The only thing I've tested is pam_listfile. Linking against libiberty needs fixing up. Gnulib may be needed by some modules. . Libiberty is needed as Solaris omits some function calls which are supplied by glibc, and used in Linux-PAM, such as asprintf. . Blastwave supplies libiberty as a position-dependant static library - this is not so good for linking into shared modules (which should use position-independant-code), we tell gcc to ignore this by passing -mimpure-text to the linker. I don't know if this makes the whole library unsharable, or just the particular libiberty code pages. If you want to fix this up, you could include the code from libiberty directly when linking the PAM modules, or make a shared libiberty, and link the pam libraries against it. . Blastwave doesn't seem to ship libiberty.h - I used the one that ships with gcc-4.3.1 (in gcc-4.3.1/include/ - you will also need the corresponding ansidecl.h) To Build: 1. untar Linux-PAM-1.0.1 2. Apply the attached Linux-PAM-1.0.1-solaris.diff 3. Configure with: $ GCC_EXEC_PREFIX=/opt/csw/gcc4/ LDFLAGS="-mimpure-text -L/opt/csw/lib -R/opt/csw/lib -liberty -lintl" CPPFLAGS="-I/opt/csw/include -I</where/you/put/libiberty.h>" ./configure --prefix=/usr/local --with-libintl-prefix=/opt/csw I then carried out the following bodges during build: . Edit modules/pam_lastlog/Makefile: remove "-lutil" . Edit modules/Makefile: remove modules which don't compile on Solaris from build subdir list (see above) $ make # make install TODO: Things which Should Be Done (but I don't currently have time to carry out): Fix modules/pam_lastlog/Makefile.am: '-lutil' should be omitted on Solaris Fix modules/Makefile.am - disable modules which don't work on Solaris Include an option to install under /usr without clashing with Solaris' own libraries, by renaming the modules with a prefix which is supplied at compile-time (e.g. pam_unix.so -> lp_pam_unix.so etc.) Create a Blastwave package for Linux-PAM
_______________________________________________ Pam-list mailing list Pam-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/pam-list