Hi A while back, I offered to get the FreeBSD diffs for Linux-PAM back to you guys. Now that I have changed countries/continents (.ZA --> .UK), I have the time to do this :-). General notes: o A lot of the fixes are to fix GCC in "All warnings on and phasers set to kill (-Werror)" mode. :-). FreeBSD currently uses GCC-2.95.3. o FreeBSD uses "$FreeBSD$" as a CVS/RCS version identification string. We'd surely be very grateful if all your $Id$ lines could be repeated with $FreeBSD$ lines. If you are agreeable, I'd be happy to supply a patch. o The FreeBSD modules live in /usr/lib/, not /lib/security/. o The FreeBSD modules are mosly written from scratch and very different from the Linux ones. I have not included them here. I can send a copy if you are interested. o For the manual pages, we have done a general s/Linux-PAM/PAM/. Most of the diffs are trivial, so I have not included them. By choice, FreeBSD uses the -mdoc macros. We recommend these highly :-). Individual comments follow for each file below: Simple warning fix "signed/unsigned comparison". Index: libpam/pam_delay.c =================================================================== RCS file: /home/ncvs/src/contrib/libpam/libpam/pam_delay.c,v retrieving revision 1.1.1.2 diff -u -d -r1.1.1.2 pam_delay.c --- libpam/pam_delay.c 2001/05/03 09:36:04 1.1.1.2 +++ libpam/pam_delay.c 2001/08/07 11:06:44 @@ -133,7 +133,7 @@ int pam_fail_delay(pam_handle_t *pamh, unsigned int usec) { - int largest; + unsigned int largest; IF_NO_PAMH("pam_fail_delay", pamh, PAM_SYSTEM_ERR); Make sure FreeBSD gets definitions for dlopen(3) and friends. This works for static and dynamic modes. Index: libpam/pam_handlers.c =================================================================== RCS file: /home/ncvs/src/contrib/libpam/libpam/pam_handlers.c,v retrieving revision 1.1.1.2 diff -u -d -r1.1.1.2 pam_handlers.c --- libpam/pam_handlers.c 2001/05/03 09:36:04 1.1.1.2 +++ libpam/pam_handlers.c 2001/08/07 14:18:41 @@ -20,17 +20,15 @@ # include <dlfcn.h> # endif /* PAM_SHL */ #endif /* PAM_DYNAMIC */ +#ifdef __FreeBSD__ +# include <dlfcn.h> +# endif /* __FreeBSD__ */ #include <fcntl.h> #include <unistd.h> #include "pam_private.h" - -/* FreeBSD doesn't define this */ -#ifndef RTLD_NOW -# define RTLD_NOW 1 -#endif -/* If not required, define as nothing - FreeBSD needs it to be "_"... */ +/* If not required, define as nothing */ #ifndef SHLIB_SYM_PREFIX # define SHLIB_SYM_PREFIX "" #endif Declare internal function to kill warning. Index: libpam/pam_private.h =================================================================== RCS file: /home/ncvs/src/contrib/libpam/libpam/pam_private.h,v retrieving revision 1.1.1.2 diff -u -d -r1.1.1.2 pam_private.h --- libpam/pam_private.h 2001/05/03 09:36:04 1.1.1.2 +++ libpam/pam_private.h 2001/08/07 11:14:35 @@ -251,6 +251,7 @@ void _pam_system_log(int priority, const char *format, ... ); #define _PAM_SYSTEM_LOG_PREFIX "PAM " +int pam_authenticate_secondary(pam_handle_t *pamh, char *target_username, char *target_module_type, char *target_authn_domain, char *target_supp_data, unsigned char *target_module_authtok, int flags); /* * XXX - Take care with this. It could confuse the logic of a trailing * else Fix "unused argument" warnings. Index: libpam/pam_second.c =================================================================== RCS file: /home/ncvs/src/contrib/libpam/libpam/pam_second.c,v retrieving revision 1.1.1.2 diff -u -d -r1.1.1.2 pam_second.c --- libpam/pam_second.c 2001/05/03 09:36:04 1.1.1.2 +++ libpam/pam_second.c 2001/08/07 11:10:41 @@ -14,12 +14,12 @@ /* p 42 */ int pam_authenticate_secondary(pam_handle_t *pamh, - char *target_username, - char *target_module_type, - char *target_authn_domain, - char *target_supp_data, - unsigned char *target_module_authtok, - int flags) + char *target_username __unused, + char *target_module_type __unused, + char *target_authn_domain __unused, + char *target_supp_data __unused, + unsigned char *target_module_authtok __unused, + int flags __unused) { int retval=PAM_SYSTEM_ERR; FreeBSD modules have dramatically simplified the linkage structure usually placed at the bottom of each module. FreeBSD "linker sets" are used, and a one-line macro is used in the module: PAM_MODULE_ENTRY("pam_foo"); which expands to the correct structure and declarations. This works correctly in both static and dynamic cases. More later. Index: libpam/pam_static.c =================================================================== RCS file: /home/ncvs/src/contrib/libpam/libpam/pam_static.c,v retrieving revision 1.1.1.2 diff -u -d -r1.1.1.2 pam_static.c --- libpam/pam_static.c 2001/05/03 09:36:04 1.1.1.2 +++ libpam/pam_static.c 2001/07/07 12:20:11 @@ -3,51 +3,31 @@ /* created by Michael K. Johnson, johnsonm@redhat.com * * $Id: pam_static.c,v 1.1.1.1 2000/06/20 22:11:21 agmorgan Exp $ + * $FreeBSD: src/contrib/libpam/libpam/pam_static.c,v 1.5 2001/06/14 01:13:29 peter Exp $ */ -/* This whole file is only used for PAM_STATIC */ - -#ifdef PAM_STATIC - #include <stdlib.h> #include <stdio.h> #include <string.h> #include "pam_private.h" -/* - * Need to include pointers to static modules; this was built by each - * of the modules that register... - */ - -#include "../modules/_static_module_list" - -/* - * and here is a structure that connects libpam to the above static - * modules - */ - -static struct pam_module *static_modules[] = { - -#include "../modules/_static_module_entry" +/* This whole file is only used for PAM_STATIC */ - NULL -}; +#ifdef PAM_STATIC -/* - * and now for the functions - */ +SET_DECLARE(_pam_static_modules, struct pam_module); /* Return pointer to data structure used to define a static module */ struct pam_module * _pam_open_static_handler(const char *path) { - int i; const char *clpath = path; char *lpath, *end; + struct pam_module **static_module; if (strchr(clpath, '/')) { /* ignore path and leading "/" */ - clpath = strrchr(lpath, '/') + 1; + clpath = strrchr(clpath, '/') + 1; } /* create copy to muck with (must free before return) */ lpath = _pam_strdup(clpath); @@ -59,21 +39,17 @@ } /* now go find the module */ - for (i = 0; static_modules[i] != NULL; i++) { - D(("%s=?%s\n", lpath, static_modules[i]->name)); - if (static_modules[i]->name && - ! strcmp(static_modules[i]->name, lpath)) { - break; + SET_FOREACH(static_module, _pam_static_modules) { + D(("%s=?%s\n", lpath, (*static_module)->name)); + if ((*static_module)->name && + ! strcmp((*static_module)->name, lpath)) { + free(lpath); + return (*static_module); } } - if (static_modules[i] == NULL) { - _pam_system_log(NULL, NULL, LOG_ERR, "no static module named %s", - lpath); - } - free(lpath); - return (static_modules[i]); + return (NULL); } FreeBSD's PAM_MODULE_ENTRY macro. Index: libpam/include/security/pam_modules.h =================================================================== RCS file: /home/ncvs/src/contrib/libpam/libpam/include/security/pam_modules.h,v retrieving revision 1.1.1.2 retrieving revision 1.3 diff -u -d -r1.1.1.2 -r1.3 --- libpam/include/security/pam_modules.h 2001/05/03 09:36:04 1.1.1.2 +++ libpam/include/security/pam_modules.h 2001/05/03 10:48:54 1.3 @@ -2,12 +2,28 @@ * <security/pam_modules.h> * * $Id: pam_modules.h,v 1.3 2001/02/05 06:50:41 agmorgan Exp $ + * $FreeBSD: src/contrib/libpam/libpam/include/security/pam_modules.h,v 1.3 2001/05/03 10:48:54 markm Exp $ * */ #ifndef _SECURITY_PAM_MODULES_H #define _SECURITY_PAM_MODULES_H +/* + * Define either PAM_STATIC or PAM_DYNAMIC, based on whether PIC + * compilation is being used. + */ +#if !defined(PIC) && !defined(PAM_STATIC) +#define PAM_STATIC +#endif +#ifndef PAM_STATIC +#define PAM_DYNAMIC +#endif + +#ifdef PAM_STATIC +#include <linker_set.h> +#endif + #include <security/_pam_types.h> /* Linux-PAM common defined types */ /* these defines are used by pam_set_item() and pam_get_item() and are @@ -51,9 +67,50 @@ int argc, const char **argv); }; +#ifdef PAM_SM_AUTH +#define PAM_SM_AUTH_ENTRY pam_sm_authenticate +#define PAM_SM_SETCRED_ENTRY pam_sm_setcred +#else +#define PAM_SM_AUTH_ENTRY NULL +#define PAM_SM_SETCRED_ENTRY NULL +#endif + +#ifdef PAM_SM_ACCOUNT +#define PAM_SM_ACCOUNT_ENTRY pam_sm_acct_mgmt +#else +#define PAM_SM_ACCOUNT_ENTRY NULL +#endif + +#ifdef PAM_SM_SESSION +#define PAM_SM_OPEN_SESSION_ENTRY pam_sm_open_session +#define PAM_SM_CLOSE_SESSION_ENTRY pam_sm_close_session +#else +#define PAM_SM_OPEN_SESSION_ENTRY NULL +#define PAM_SM_CLOSE_SESSION_ENTRY NULL +#endif + +#ifdef PAM_SM_PASSWORD +#define PAM_SM_PASSWORD_ENTRY pam_sm_chauthtok +#else +#define PAM_SM_PASSWORD_ENTRY NULL +#endif + +#define PAM_MODULE_ENTRY(name) \ + static struct pam_module _pam_modstruct = { \ + name, \ + PAM_SM_AUTH_ENTRY, \ + PAM_SM_SETCRED_ENTRY, \ + PAM_SM_ACCOUNT_ENTRY, \ + PAM_SM_OPEN_SESSION_ENTRY, \ + PAM_SM_CLOSE_SESSION_ENTRY, \ + PAM_SM_PASSWORD_ENTRY \ + }; \ + DATA_SET(_pam_static_modules, _pam_modstruct) + #else /* !PAM_STATIC */ #define PAM_EXTERN extern +#define PAM_MODULE_ENTRY(name) #endif /* PAM_STATIC */ Unused argument warning fix. /* Return pointer to function requested from static module Index: libpam/pam_strerror.c =================================================================== RCS file: /home/ncvs/src/contrib/libpam/libpam/pam_strerror.c,v retrieving revision 1.1.1.2 diff -u -d -r1.1.1.2 pam_strerror.c --- libpam/pam_strerror.c 2001/05/03 09:36:04 1.1.1.2 +++ libpam/pam_strerror.c 2001/08/07 11:15:57 @@ -6,7 +6,7 @@ #include "pam_private.h" -const char *pam_strerror(pam_handle_t *pamh, int errnum) +const char *pam_strerror(pam_handle_t *pamh __unused, int errnum) { #ifdef UGLY_HACK_FOR_PRIOR_BEHAVIOR_SUPPORT /* will be removed from v 1.0 */ Unused argument warning fixes. Fix for warning about "static" not being first in declaration. Fix read_string to be more similar to FreeBSD's getpass(3); block certain signals return empty string on EOF Index: libpam_misc/misc_conv.c =================================================================== RCS file: /home/ncvs/src/contrib/libpam/libpam_misc/misc_conv.c,v retrieving revision 1.1.1.2 diff -u -d -r1.1.1.2 misc_conv.c --- libpam_misc/misc_conv.c 2001/05/03 09:36:04 1.1.1.2 +++ libpam_misc/misc_conv.c 2001/08/07 13:54:42 @@ -1,5 +1,6 @@ /* * $Id: misc_conv.c,v 1.3 2001/01/20 22:29:47 agmorgan Exp $ + * $FreeBSD: src/contrib/libpam/libpam_misc/misc_conv.c,v 1.5 2001/06/07 08:45:23 markm Exp $ * * A generic conversation function for text based applications * @@ -18,6 +19,7 @@ #include <unistd.h> #include <security/pam_appl.h> +#include <security/pam_client.h> #include <security/pam_misc.h> #define INPUTSIZE PAM_MAX_MSG_SIZE /* maximum length of input+1 */ @@ -45,7 +47,7 @@ * being used. */ -static void pam_misc_conv_delete_binary(void *appdata, +static void pam_misc_conv_delete_binary(void *appdata __unused, pamc_bp_t *delete_me) { PAM_BP_RENEW(delete_me, 0, 0); @@ -57,7 +59,7 @@ /* the following code is used to get text input */ -volatile static int expired=0; +static volatile int expired=0; /* return to the previous signal handling */ static void reset_alarm(struct sigaction *o_ptr) @@ -67,7 +69,7 @@ } /* this is where we intercept the alarm signal */ -static void time_is_up(int ignore) +static void time_is_up(int ignore __unused) { expired = 1; } @@ -130,9 +132,11 @@ static char *read_string(int echo, const char *prompt) { struct termios term_before, term_tmp; + char *input; char line[INPUTSIZE]; struct sigaction old_sig; int delay, nc, have_term=0; + sigset_t oset, nset; D(("called with echo='%s', prompt='%s'.", echo ? "ON":"OFF" , prompt)); @@ -148,6 +152,14 @@ term_tmp.c_lflag &= ~(ECHO); } have_term = 1; + /* + * note - blocking signals isn't necessarily the + * right thing, but we leave it for now. + */ + sigemptyset(&nset); + sigaddset(&nset, SIGINT); + sigaddset(&nset, SIGTSTP); + (void)sigprocmask(SIG_BLOCK, &nset, &oset); } else if (!echo) { D(("<warning: cannot turn echo off>")); @@ -180,8 +192,6 @@ if (expired) { delay = get_delay(); } else if (nc > 0) { /* we got some user input */ - char *input; - if (nc > 0 && line[nc-1] == '\n') { /* <NUL> terminate */ line[--nc] = '\0'; } else { @@ -190,21 +200,25 @@ input = x_strdup(line); _pam_overwrite(line); - return input; /* return malloc()ed string */ + goto cleanexit; /* return malloc()ed string */ } else if (nc == 0) { /* Ctrl-D */ D(("user did not want to type anything")); - fprintf(stderr, "\n"); - break; + input = x_strdup(""); + goto cleanexit; /* return malloc()ed string */ } } } /* getting here implies that the timer expired */ - if (have_term) - (void) tcsetattr(STDIN_FILENO, TCSADRAIN, &term_before); - memset(line, 0, INPUTSIZE); /* clean up */ - return NULL; + input = NULL; + +cleanexit: + if (have_term) { + (void)sigprocmask(SIG_SETMASK, &oset, NULL); + (void) tcsetattr(STDIN_FILENO, TCSADRAIN, &term_before); + } + return input; } Fix undeclared function warnings with standard includes /* end of read_string functions */ Index: libpam_misc/xstrdup.c =================================================================== RCS file: /home/ncvs/src/contrib/libpam/libpam_misc/xstrdup.c,v retrieving revision 1.1.1.2 retrieving revision 1.3 diff -u -d -r1.1.1.2 -r1.3 --- libpam_misc/xstrdup.c 2001/05/03 09:36:04 1.1.1.2 +++ libpam_misc/xstrdup.c 2001/05/03 10:48:55 1.3 @@ -1,7 +1,7 @@ /* $Id: xstrdup.c,v 1.1.1.1 2000/06/20 22:11:25 agmorgan Exp $ */ +/* $FreeBSD: src/contrib/libpam/libpam_misc/xstrdup.c,v 1.3 2001/05/03 10:48:55 markm Exp $ */ -#include <malloc.h> -#include <string.h> +#include <stdlib.h> #include <security/pam_misc.h> /* Declare internal function to silence "function has no prototype" warning. Index: libpam_misc/include/security/pam_misc.h =================================================================== RCS file: /home/ncvs/src/contrib/libpam/libpam_misc/include/security/pam_misc.h,v retrieving revision 1.1.1.1 diff -u -d -r1.1.1.1 pam_misc.h --- libpam_misc/include/security/pam_misc.h 2001/05/03 09:36:05 1.1.1.1 +++ libpam_misc/include/security/pam_misc.h 2001/08/07 13:58:59 @@ -51,7 +51,6 @@ extern int pam_misc_setenv(pam_handle_t *pamh, const char *name , const char *value, int readonly); -#endif +char *xstrdup(const char *x); - - +#endif Silence "signed/unsigned comparison" warnings. Index: libpamc/include/security/pam_client.h =================================================================== RCS file: /home/ncvs/src/contrib/libpam/libpamc/include/security/pam_client.h,v retrieving revision 1.1.1.1 diff -u -d -r1.1.1.1 pam_client.h --- libpamc/include/security/pam_client.h 2001/05/03 09:36:05 1.1.1.1 +++ libpamc/include/security/pam_client.h 2001/08/07 13:56:08 @@ -136,7 +136,7 @@ #define PAM_BP_FILL(prmpt, offset, length, data) \ do { \ - int bp_length; \ + size_t bp_length; \ __u8 *prompt = (__u8 *) (prmpt); \ bp_length = PAM_BP_LENGTH(prompt); \ if (bp_length < ((length)+(offset))) { \ @@ -147,7 +147,7 @@ #define PAM_BP_EXTRACT(prmpt, offset, length, data) \ do { \ - int __bp_length; \ + size_t __bp_length; \ const __u8 *__prompt = (const __u8 *) (prmpt); \ __bp_length = PAM_BP_LENGTH(__prompt); \ if (((offset) < 0) || (__bp_length < ((length)+(offset))) \ Example of FreeBSD module declaration. Index: modules/pam_deny/pam_deny.c =================================================================== RCS file: /home/ncvs/src/contrib/libpam/modules/pam_deny/pam_deny.c,v retrieving revision 1.1.1.2 retrieving revision 1.4 diff -u -d -r1.1.1.2 -r1.4 --- modules/pam_deny/pam_deny.c 2001/05/03 09:36:05 1.1.1.2 +++ modules/pam_deny/pam_deny.c 2001/05/03 10:48:55 1.4 @@ -1,7 +1,8 @@ -/* pam_permit module */ +/* pam_deny module */ /* * $Id: pam_deny.c,v 1.2 2000/12/04 19:02:34 baggins Exp $ + * $FreeBSD: src/contrib/libpam/modules/pam_deny/pam_deny.c,v 1.4 2001/05/03 10:48:55 markm Exp $ * * Written by Andrew Morgan <morgan@parc.power.net> 1996/3/11 * @@ -67,15 +68,4 @@ /* end of module definition */ -/* static module data */ -#ifdef PAM_STATIC -struct pam_module _pam_deny_modstruct = { - "pam_deny", - pam_sm_authenticate, - pam_sm_setcred, - pam_sm_acct_mgmt, - pam_sm_open_session, - pam_sm_close_session, - pam_sm_chauthtok -}; -#endif +PAM_MODULE_ENTRY("pam_deny");