* Make.Rules.in: Add targets for installing man pages for modules
(from Linux distributors - kukuk)
* Add pam_xauth module (Bug 436440 - kukuk)
+* Add pam_localuser module (Bug 436444 - kukuk)
+* Add pam_succeed_if module (from Linux distributors - kukuk)
* configure.in: Fix check for libcrypt (Bug 417704 - kukuk)
* Add the "broken_shadow" argument to pam_unix, for ignoring errors
reading shadow information (from Linux distributors - kukuk)
+* Add patches to make PAM modules reentrant (Bug 440107 - kukuk)
0.77: Mon Sep 23 10:25:42 PDT 2002
/* Define if reentrant declarations of standard nss functions are available */
#undef HAVE_GETPWNAM_R
+#undef HAVE_GETPWUID_R
+#undef HAVE_GETSPNAM_R
#undef HAVE_GETGRNAM_R
+#undef HAVE_GETGRGID_R
+#undef HAVE_GETGROUPLIST
/* ugly hack to partially support old pam_strerror syntax */
#undef UGLY_HACK_FOR_PRIOR_BEHAVIOR_SUPPORT
-for ac_func in getpwnam_r getgrnam_r
+
+
+
+
+for ac_func in getpwnam_r getpwuid_r getgrnam_r getgrgid_r getspnam_r getgrouplist
do
as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh`
echo "$as_me:$LINENO: checking for $ac_func" >&5
AC_FUNC_VPRINTF
AC_CHECK_FUNCS(gethostname gettimeofday mkdir select strcspn strdup strerror strspn strstr strtol uname)
-AC_CHECK_FUNCS(getpwnam_r getgrnam_r)
+AC_CHECK_FUNCS(getpwnam_r getpwuid_r getgrnam_r getgrgid_r getspnam_r getgrouplist)
dnl Checks for programs/utilities
AC_CHECK_PROG(HAVE_SGML2TXT, sgml2txt, yes, no)
#include <security/_pam_macros.h>
#include <security/pam_modules.h>
+#include <security/_pam_modutil.h>
/* login_access.c from logdaemon-5.6 with several changes by A.Nogin: */
return 1; /* OK */
}
-typedef int match_func (char *, struct login_info *);
+typedef int match_func (pam_handle_t *, char *, struct login_info *);
-static int list_match (char *, struct login_info *,
- match_func *);
-static int user_match (char *, struct login_info *);
-static int from_match (char *, struct login_info *);
-static int string_match (char *, char *);
+static int list_match (pam_handle_t *, char *, struct login_info *,
+ match_func *);
+static int user_match (pam_handle_t *, char *, struct login_info *);
+static int from_match (pam_handle_t *, char *, struct login_info *);
+static int string_match (pam_handle_t *, char *, char *);
/* login_access - match username/group and host/tty with access control file */
-static int login_access(struct login_info *item)
+static int
+login_access (pam_handle_t *pamh, struct login_info *item)
{
FILE *fp;
char line[BUFSIZ];
item->config_file, lineno);
continue;
}
- match = (list_match(froms, item, from_match)
- && list_match(users, item, user_match));
+ match = (list_match(pamh, froms, item, from_match)
+ && list_match(pamh, users, item, user_match));
}
(void) fclose(fp);
} else if (errno != ENOENT) {
/* list_match - match an item against a list of tokens with exceptions */
-static int list_match(char *list, struct login_info *item, match_func *match_fn)
+static int list_match(pam_handle_t *pamh,
+ char *list, struct login_info *item, match_func *match_fn)
{
char *tok;
int match = NO;
for (tok = strtok(list, sep); tok != 0; tok = strtok((char *) 0, sep)) {
if (strcasecmp(tok, "EXCEPT") == 0) /* EXCEPT: give up */
break;
- if ((match = (*match_fn) (tok, item))) /* YES */
+ if ((match = (*match_fn) (pamh, tok, item))) /* YES */
break;
}
/* Process exceptions to matches. */
if (match != NO) {
while ((tok = strtok((char *) 0, sep)) && strcasecmp(tok, "EXCEPT"))
/* VOID */ ;
- if (tok == 0 || list_match((char *) 0, item, match_fn) == NO)
+ if (tok == 0 || list_match(pamh, (char *) 0, item, match_fn) == NO)
return (match);
}
return (NO);
/* user_match - match a username against one token */
-static int user_match(char *tok, struct login_info *item)
+static int user_match(pam_handle_t *pamh, char *tok, struct login_info *item)
{
char *string = item->user->pw_name;
struct login_info fake_item;
- struct group *group;
- int i;
char *at;
/*
fake_item.from = myhostname();
if (fake_item.from == NULL)
return NO;
- return (user_match(tok, item) && from_match(at + 1, &fake_item));
- } else if (tok[0] == '@') { /* netgroup */
+ return (user_match (pamh, tok, item) && from_match (pamh, at + 1, &fake_item));
+ } else if (tok[0] == '@') /* netgroup */
return (netgroup_match(tok + 1, (char *) 0, string));
- } else if (string_match(tok, string)) { /* ALL or exact match */
- return (YES);
- } else if ((group = getgrnam(tok))) { /* try group membership */
- if (item->user->pw_gid == group->gr_gid)
- return (YES);
- for (i = 0; group->gr_mem[i]; i++)
- if (strcasecmp(string, group->gr_mem[i]) == 0)
- return (YES);
- }
- return (NO);
+ else if (string_match (pamh, tok, string)) /* ALL or exact match */
+ return YES;
+ else if (_pammodutil_user_in_group_nam_nam (pamh, item->user->pw_name, tok))
+ /* try group membership */
+ return YES;
+
+ return NO;
}
/* from_match - match a host or tty against a list of tokens */
-static int from_match(char *tok, struct login_info *item)
+static int
+from_match (pam_handle_t *pamh, char *tok, struct login_info *item)
{
char *string = item->from;
int tok_len;
if (tok[0] == '@') { /* netgroup */
return (netgroup_match(tok + 1, string, (char *) 0));
- } else if (string_match(tok, string)) { /* ALL or exact match */
- return (YES);
- } else if (tok[0] == '.') { /* domain: match last fields */
+ } else if (string_match (pamh, tok, string)) /* ALL or exact match */
+ return YES;
+ else if (tok[0] == '.') { /* domain: match last fields */
if ((str_len = strlen(string)) > (tok_len = strlen(tok))
&& strcasecmp(tok, string + str_len - tok_len) == 0)
return (YES);
/* string_match - match a string against one token */
-static int string_match(char *tok, char *string)
+static int
+string_match (pam_handle_t *pamh, char *tok, char *string)
{
/*
}
- if ((user_pw=getpwnam(user))==NULL) return (PAM_USER_UNKNOWN);
+ if ((user_pw=_pammodutil_getpwnam(pamh, user))==NULL) return (PAM_USER_UNKNOWN);
/*
* Bundle up the arguments to avoid unnecessary clumsiness later on.
return PAM_ABORT;
}
- if (login_access(&loginfo)) {
+ if (login_access(pamh, &loginfo)) {
return (PAM_SUCCESS);
} else {
_log_err("access denied for user `%s' from `%s'",user,from);
#include <security/pam_modules.h>
#include <security/_pam_macros.h>
+#include <security/_pam_modutil.h>
/* --- static functions for checking whether the user should be let in --- */
#define GROUP_BLK 10
#define blk_size(len) (((len-1 + GROUP_BLK)/GROUP_BLK)*GROUP_BLK)
-static int mkgrplist(char *buf, gid_t **list, int len)
+static int mkgrplist(pam_handle_t *pamh, char *buf, gid_t **list, int len)
{
int l,at=0;
int blks;
{
const struct group *grp;
- grp = getgrnam(buf+at);
+ grp = _pammodutil_getgrnam(pamh, buf+at);
if (grp == NULL) {
_log_err("bad group: %s", buf+at);
} else {
}
-static int check_account(const char *service, const char *tty
- , const char *user)
+static int check_account(pam_handle_t *pamh, const char *service,
+ const char *tty, const char *user)
{
int from=0,to=0,fd=-1;
char *buffer=NULL;
if (good) {
D(("adding %s to gid list", buffer));
- good = mkgrplist(buffer, &grps, no_grps);
+ good = mkgrplist(pamh, buffer, &grps, no_grps);
if (good < 0) {
no_grps = 0;
} else {
/* We initialize the pwdb library and check the account */
retval = pwdb_start(); /* initialize */
if (retval == PWDB_SUCCESS) {
- retval = check_account(service,tty,user); /* get groups */
+ retval = check_account(pamh, service,tty,user); /* get groups */
(void) pwdb_end(); /* tidy up */
} else {
D(("failed to initialize pwdb; %s", pwdb_strerror(retval)));
}
#else /* WANT_PWDB */
- retval = check_account(service,tty,user); /* get groups */
+ retval = check_account(pamh,service,tty,user); /* get groups */
#endif /* WANT_PWDB */
return retval;
/* what uid? */
- pwd = getpwnam(user);
+ pwd = _pammodutil_getpwnam (pamh, user);
if (pwd == NULL) {
D(("couldn't identify user %s", user));
return PAM_CRED_INSUFFICIENT;
#include <security/pam_modules.h>
#include <security/_pam_macros.h>
+#include <security/_pam_modutil.h>
/* logging */
static void _pam_log(int err, const char *format, ...)
#define LIMIT_ERR 1 /* error setting a limit */
#define LOGIN_ERR 2 /* too many logins err */
-/* checks if a user is on a list of members of the GID 0 group */
-static int is_on_list(char * const *list, const char *member)
-{
- while (*list) {
- if (strcmp(*list, member) == 0)
- return 1;
- list++;
- }
- return 0;
-}
-
-/*
- * Checks if a user is a member of a group - return non-zero if
- * the user is in the group.
- */
-static int is_in_group(const char *user_name, const char *group_name)
-{
- struct passwd *pwd;
- struct group *grp, *pgrp;
- char uname[LINE_LENGTH], gname[LINE_LENGTH];
-
- if (!user_name || !strlen(user_name))
- return 0;
- if (!group_name || !strlen(group_name))
- return 0;
- memset(uname, 0, sizeof(uname));
- strncpy(uname, user_name, sizeof(uname)-1);
- memset(gname, 0, sizeof(gname));
- strncpy(gname, group_name, sizeof(gname)-1);
-
- pwd = getpwnam(uname);
- if (!pwd)
- return 0;
-
- /* the info about this group */
- grp = getgrnam(gname);
- if (!grp)
- return 0;
-
- /* first check: is a member of the group_name group ? */
- if (is_on_list(grp->gr_mem, uname))
- return 1;
-
- /* next check: user primary group is group_name ? */
- pgrp = getgrgid(pwd->pw_gid);
- if (!pgrp)
- return 0;
- if (!strcmp(pgrp->gr_name, gname))
- return 1;
-
- return 0;
-}
-
/* Counts the number of user logins and check against the limit*/
-static int check_logins(const char *name, int limit, int ctrl,
- struct pam_limit_s *pl)
+static int
+check_logins (pam_handle_t *pamh, const char *name, int limit, int ctrl,
+ struct pam_limit_s *pl)
{
struct utmp *ut;
unsigned int count;
continue;
}
if ((pl->login_limit_def == LIMITS_DEF_ALLGROUP)
- && !is_in_group(ut->UT_USER, name)) {
+ && !_pammodutil_user_in_group_nam_nam(pamh, ut->UT_USER, name)) {
continue;
}
}
return;
}
-static int parse_config_file(const char *uname, int ctrl,
+static int parse_config_file(pam_handle_t *pamh, const char *uname, int ctrl,
struct pam_limit_s *pl)
{
FILE *fil;
_pam_log(LOG_DEBUG, "checking if %s is in group %s",
uname, domain + 1);
}
- if (is_in_group(uname, domain+1))
+ if (_pammodutil_user_in_group_nam_nam(pamh, uname, domain+1))
process_limit(LIMITS_DEF_GROUP, ltype, item, value, ctrl,
pl);
} else if (domain[0]=='%') {
if (strcmp(domain,"%") == 0)
process_limit(LIMITS_DEF_ALL, ltype, item, value, ctrl,
pl);
- else if (is_in_group(uname, domain+1))
+ else if (_pammodutil_user_in_group_nam_nam(pamh, uname, domain+1))
process_limit(LIMITS_DEF_ALLGROUP, ltype, item, value, ctrl,
pl);
} else if (strcmp(domain, "*") == 0)
}
fclose(fil);
return PAM_IGNORE;
- } else if (domain[0] == '@' && is_in_group(uname, domain+1)) {
+ } else if (domain[0] == '@' && _pammodutil_user_in_group_nam_nam(pamh, uname, domain+1)) {
if (ctrl & PAM_DEBUG_ARG) {
_pam_log(LOG_DEBUG, "no limits for '%s' in group '%s'",
uname, domain+1);
return PAM_SUCCESS;
}
-static int setup_limits(const char * uname, uid_t uid, int ctrl,
+static int setup_limits(pam_handle_t *pamh,
+ const char *uname, uid_t uid, int ctrl,
struct pam_limit_s *pl)
{
int i;
if (uid == 0) {
D(("skip login limit check for uid=0"));
} else if (pl->login_limit > 0) {
- if (check_logins(uname, pl->login_limit, ctrl, pl) == LOGIN_ERR) {
+ if (check_logins(pamh, uname, pl->login_limit, ctrl, pl) == LOGIN_ERR) {
retval |= LOGIN_ERR;
}
} else if (pl->login_limit == 0) {
return PAM_IGNORE;
}
- retval = parse_config_file(pwd->pw_name, ctrl, &pl);
+ retval = parse_config_file(pamh, pwd->pw_name, ctrl, &pl);
if (retval == PAM_IGNORE) {
D(("the configuration file has an applicable '<domain> -' entry"));
return PAM_SUCCESS;
if (ctrl & PAM_DO_SETREUID) {
setreuid(pwd->pw_uid, -1);
}
- retval = setup_limits(pwd->pw_name, pwd->pw_uid, ctrl, &pl);
+ retval = setup_limits(pamh, pwd->pw_name, pwd->pw_uid, ctrl, &pl);
if (retval != LIMITED_OK) {
return PAM_PERM_DENIED;
}
#include <security/pam_modules.h>
#include <security/_pam_macros.h>
+#include <security/_pam_modutil.h>
/* some syslogging */
return 0;
}
-/* Checks if a user is a member of a group */
-static int is_on_group(const char *user_name, const char *group_name)
-{
- struct passwd *pwd;
- struct group *grp, *pgrp;
- char uname[BUFSIZ], gname[BUFSIZ];
-
- if (!strlen(user_name))
- return 0;
- if (!strlen(group_name))
- return 0;
- bzero(uname, sizeof(uname));
- strncpy(uname, user_name, sizeof(uname)-1);
- bzero(gname, sizeof(gname));
- strncpy(gname, group_name, sizeof(gname)-1);
-
- pwd = getpwnam(uname);
- if (!pwd)
- return 0;
-
- /* the info about this group */
- grp = getgrnam(gname);
- if (!grp)
- return 0;
-
- /* first check: is a member of the group_name group ? */
- if (is_on_list(grp->gr_mem, uname))
- return 1;
-
- /* next check: user primary group is group_name ? */
- pgrp = getgrgid(pwd->pw_gid);
- if (!pgrp)
- return 0;
- if (!strcmp(pgrp->gr_name, gname))
- return 1;
-
- return 0;
-}
-
/* --- authentication management functions (only) --- */
/* Extended Items that are not directly available via pam_get_item() */
return PAM_IGNORE;
}
} else if(apply_type==APPLY_TYPE_GROUP) {
- if(!is_on_group(user_name,apply_val)) {
+ if(!_pammodutil_user_in_group_nam_nam(pamh,user_name,apply_val)) {
/* Not a member of apply= group */
#ifdef DEBUG
_pam_log(LOG_DEBUG,
if(extitem) {
switch(extitem) {
case EI_GROUP:
- userinfo = getpwnam(citemp);
+ userinfo = _pammodutil_getpwnam(pamh, citemp);
if (userinfo == NULL) {
_pam_log(LOG_ERR,LOCAL_LOG_PREFIX "getpwnam(%s) failed",
citemp);
return onerr;
}
- grpinfo = getgrgid(userinfo->pw_gid);
+ grpinfo = _pammodutil_getgrgid(pamh, userinfo->pw_gid);
if (grpinfo == NULL) {
_pam_log(LOG_ERR,LOCAL_LOG_PREFIX "getgrgid(%d) failed",
(int)userinfo->pw_gid);
/* Assume that we have already gotten PAM_USER in
pam_get_item() - a valid assumption since citem
gets set to PAM_USER in the extitem switch */
- userinfo = getpwnam(citemp);
+ userinfo = _pammodutil_getpwnam(pamh, citemp);
if (userinfo == NULL) {
_pam_log(LOG_ERR,LOCAL_LOG_PREFIX "getpwnam(%s) failed",
citemp);
#include <security/pam_modules.h>
#include <security/_pam_macros.h>
+#include <security/_pam_modutil.h>
/* some syslogging */
if (ctrl & PAM_NEW_MAIL_DIR) {
path = *path_mail;
if (*path == '~') { /* support for $HOME delivery */
- pwd = getpwnam(user);
+ pwd = _pammodutil_getpwnam(pamh, user);
if (pwd == NULL) {
_log_err(LOG_ERR, "user [%s] unknown", user);
_pam_overwrite(*path_mail);
}
/* Get the password entry */
- pwd = getpwnam(user);
+ pwd = _pammodutil_getpwnam (pamh, user);
if (pwd == NULL)
{
D(("couldn't identify user %s", user));
/* private group caveat */
if (opts->opt_private_group) {
- struct group *grp = getgrgid(sbuf.st_gid);
+ struct group *grp = _pammodutil_getgrgid(pamh, sbuf.st_gid);
if (NULL == grp || NULL == grp->gr_name
|| strcmp(luser,grp->gr_name)) {
#define PAM_SM_ACCOUNT
#include <security/pam_modules.h>
+#include <security/_pam_modutil.h>
/* some syslogging */
return (retval == PAM_CONV_AGAIN ? PAM_INCOMPLETE:PAM_SERVICE_ERR);
}
- user_pwd = getpwnam(username);
+ user_pwd = _pammodutil_getpwnam(pamh, username);
if (user_pwd == NULL) {
return PAM_IGNORE;
} else if (user_pwd->pw_uid != 0) { /* If the user is not root,
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
+#include <string.h>
#include <sys/stat.h>
#include <syslog.h>
#include <unistd.h>
#define PAM_SM_ACCOUNT
#include <security/pam_modules.h>
+#include <security/_pam_modutil.h>
/* some syslogging */
return PAM_SERVICE_ERR;
}
- pw = getpwnam(userName);
+ pw = _pammodutil_getpwnam(pamh, userName);
if (!pw) {
return PAM_AUTH_ERR; /* user doesn't exist */
}
*
*/
+#define _GNU_SOURCE
+
#include <sys/types.h>
#include <errno.h>
#include <fcntl.h>
APPLICATION = $(TITLE)
APPMODE = 755
+LINK_PAMMODUTILS = -L../pammodutil -lpammodutil -L../../libpam -lpam
+INCLUDE_PAMMODUTILS = -I../pammodutil/include
+
+LDFLAGS += $(LINK_PAMMODUTILS)
+CFLAGS += $(INCLUDE_PAMMODUTILS)
+
####################### don't edit below #######################
all: dirs $(LIBSHARED) $(LIBSTATIC) register $(APPLICATION)
$(LIBOBJD): $(LIBSRC)
$(LIBSHARED): $(LIBOBJD)
- $(LD_D) -o $@ $(LIBOBJD) -L../../libpam -lpam $(NEED_LINK_LIB_C)
+ $(LD_D) -o $@ $(LIBOBJD) $(LDFLAGS)
$(APPLICATION): $(APPOBJD) $(TITLE).c
- $(CC) $(CFLAGS) -o $@ $(APPOBJD) $(LOADLIBES)
+ $(CC) $(CFLAGS) -o $@ $(APPOBJD) $(LDFLAGS) $(LOADLIBES)
endif
/* #define PAM_SM_PASSWORD */
#include <security/pam_modules.h>
+#include <security/_pam_modutil.h>
/*---------------------------------------------------------------------*/
return PAM_AUTH_ERR;
}
- if ( ! ( pw = getpwnam( user ) ) ) {
+ if ( ! ( pw = _pammodutil_getpwnam( pamh, user ) ) ) {
_pam_log(LOG_ERR,MODULE_NAME ": pam_get_uid; no such user %s",user);
return PAM_USER_UNKNOWN;
}
EXTRAS += -DCHKPWD_HELPER=\"$(SUPLEMENTED)/$(CHKPWD)\"
+LINK_PAMMODUTILS = -L../pammodutil -lpammodutil
+INCLUDE_PAMMODUTILS = -I../pammodutil/include
+
########################################################################
CFLAGS += $(USE_CRACKLIB) $(USE_LCKPWDF) $(NEED_LCKPWDF) $(EXTRAS) \
- -I../pammodutil/include
+ $(INCLUDE_PAMMODUTILS)
-LDLIBS = $(EXTRALS) -L../pammodutil -lpammodutil
+LDLIBS = $(EXTRALS) $(LINK_PAMMODUTILS)
ifdef USE_CRACKLIB
CRACKLIB = -lcrack
#define PAM_SM_ACCOUNT
#include <security/pam_modules.h>
+#include <security/_pam_modutil.h>
#ifndef LINUX_PAM
#include <security/pam_appl.h>
return PAM_USER_UNKNOWN;
}
- pwent = getpwnam(uname);
+ pwent = _pammodutil_getpwnam(pamh, uname);
if (!pwent) {
_log_err(LOG_ALERT, pamh
,"could not identify user (from getpwnam(%s))"
return PAM_CRED_INSUFFICIENT;
}
}
- spent = getspnam( uname );
+ spent = _pammodutil_getspnam (pamh, uname);
if (save_uid == pwent->pw_uid)
setreuid( save_uid, save_euid );
else {
}
} else if (!strcmp( pwent->pw_passwd, "x" )) {
- spent = getspnam(uname);
+ spent = _pammodutil_getspnam (pamh, uname);
} else {
return PAM_SUCCESS;
}
/* if this user does not have a password... */
- if (_unix_blankpasswd(ctrl, name)) {
+ if (_unix_blankpasswd(pamh, ctrl, name)) {
D(("user '%s' has blank passwd", name));
name = NULL;
retval = PAM_SUCCESS;
#include <security/pam_appl.h>
#endif /* LINUX_PAM */
+#include <security/_pam_modutil.h>
+
#include "yppasswd.h"
#include "md5.h"
#include "support.h"
return retval;
}
-static int save_old_password(const char *forwho, const char *oldpass,
+static int save_old_password(pam_handle_t *pamh,
+ const char *forwho, const char *oldpass,
int howmany)
{
static char buf[16384];
fclose(opwfile);
if (!found) {
- pwd = getpwnam(forwho);
+ pwd = _pammodutil_getpwnam(pamh, forwho);
if (pwd == NULL) {
err = 1;
} else {
return retval;
}
/* first, save old password */
- if (save_old_password(forwho, fromwhat, remember)) {
+ if (save_old_password(pamh, forwho, fromwhat, remember)) {
return PAM_AUTHTOK_ERR;
}
D(("prelim check"));
- if (_unix_blankpasswd(ctrl, user)) {
+ if (_unix_blankpasswd(pamh, ctrl, user)) {
return PAM_SUCCESS;
} else if (off(UNIX__IAMROOT, ctrl)) {
* - to avoid prompting for one in such cases (CG)
*/
-int _unix_blankpasswd(unsigned int ctrl, const char *name)
+int
+_unix_blankpasswd (pam_handle_t *pamh, unsigned int ctrl, const char *name)
{
struct passwd *pwd = NULL;
struct spwd *spwdent = NULL;
char *salt = NULL;
int retval;
-#if HAVE_GETPWNAM_R
- char *buf = NULL;
- int bufsize = 0;
- struct passwd pwd_buf;
-
- pwd = &pwd_buf;
-#endif
D(("called"));
/* UNIX passwords area */
/* Get password file entry... */
-#if HAVE_GETPWNAM_R
- bufsize = 1024;
- buf = malloc(bufsize);
-
- if ((retval = getpwnam_r(name, pwd, buf, bufsize, &pwd))) {
- pwd = NULL;
- }
- while (retval == ERANGE) {
- bufsize += 1024;
- buf = realloc(buf, bufsize);
- if ((retval = getpwnam_r(name, pwd, buf, bufsize, &pwd))) {
- pwd = NULL;
- }
- }
-#else
- pwd = getpwnam(name);
-#endif
+ pwd = _pammodutil_getpwnam (pamh, name);
if (pwd != NULL) {
if (strcmp( pwd->pw_passwd, "*NP*" ) == 0)
setreuid( 0, -1 );
if(setreuid( -1, pwd->pw_uid ) == -1)
/* Will fail elsewhere. */
-#if HAVE_GETPWNAM_R
- if (buf)
- free(buf);
-#endif
return 0;
}
}
- spwdent = getspnam( name );
+ spwdent = _pammodutil_getspnam (pamh, name);
if (save_uid == pwd->pw_uid)
setreuid( save_uid, save_euid );
else {
* ...and shadow password file entry for this user,
* if shadowing is enabled
*/
- spwdent = getspnam(name);
+ spwdent = _pammodutil_getspnam(pamh, name);
}
if (spwdent)
salt = x_strdup(spwdent->sp_pwdp);
if (salt)
_pam_delete(salt);
-#if HAVE_GETPWNAM_R
- if (buf)
- free(buf);
-#endif
-
return retval;
}
D(("locating user's record"));
/* UNIX passwords area */
- pwd = getpwnam(name); /* Get password file entry... */
+ pwd = _pammodutil_getpwnam (pamh, name); /* Get password file entry... */
if (pwd != NULL) {
if (strcmp( pwd->pw_passwd, "*NP*" ) == 0)
}
}
- spwdent = getspnam( name );
+ spwdent = _pammodutil_getspnam (pamh, name);
if (save_uid == pwd->pw_uid)
setreuid( save_uid, save_euid );
else {
* ...and shadow password file entry for this user,
* if shadowing is enabled
*/
- spwdent = getspnam(name);
+ spwdent = _pammodutil_getspnam (pamh, name);
}
if (spwdent)
salt = x_strdup(spwdent->sp_pwdp);
,int type, const char *text);
extern int _set_ctrl(pam_handle_t * pamh, int flags, int *remember, int argc,
const char **argv);
-extern int _unix_blankpasswd(unsigned int ctrl, const char *name);
+extern int _unix_blankpasswd(pam_handle_t *pamh,unsigned int ctrl,
+ const char *name);
extern int _unix_verify_password(pam_handle_t * pamh, const char *name
,const char *p, unsigned int ctrl);
extern int _unix_read_password(pam_handle_t * pamh
}
/* su to a uid 0 account ? */
- pwd = getpwnam(username);
+ pwd = _pammodutil_getpwnam (pamh, username);
if (!pwd) {
if (ctrl & PAM_DEBUG_ARG) {
_pam_log(LOG_NOTICE,"unknown user %s",username);
}
if (ctrl & PAM_USE_UID_ARG) {
- tpwd = getpwuid(getuid());
+ tpwd = _pammodutil_getpwuid (pamh, getuid());
if (!tpwd) {
if (ctrl & PAM_DEBUG_ARG) {
_pam_log(LOG_NOTICE, "who is running me ?!");
} else {
fromsu = _pammodutil_getlogin(pamh);
if (fromsu) {
- tpwd = getpwnam(fromsu);
+ tpwd = _pammodutil_getpwnam (pamh, fromsu);
}
if (!fromsu || !tpwd) {
if (ctrl & PAM_DEBUG_ARG) {
*/
if (!use_group[0]) {
- if ((grp = getgrnam("wheel")) == NULL) {
- grp = getgrgid(0);
+ if ((grp = _pammodutil_getgrnam (pamh, "wheel")) == NULL) {
+ grp = _pammodutil_getgrgid (pamh, 0);
}
} else {
- grp = getgrnam(use_group);
+ grp = _pammodutil_getgrnam (pamh, use_group);
}
if (!grp || (!grp->gr_mem && (tpwd->pw_gid != grp->gr_gid))) {
# all the object files we care about
LIBOBJECTS = modutil_cleanup.o modutil_getpwnam.o modutil_getpwuid.o \
- modutil_getlogin.o modutil_ioloop.o
+ modutil_getspnam.o modutil_getgrnam.o modutil_getgrgid.o \
+ modutil_ingroup.o modutil_getlogin.o modutil_ioloop.o
# static library name
LIBSTATIC = $(LIBNAME).a
*/
#include <pwd.h>
+#include <grp.h>
+#include <shadow.h>
#include <sys/types.h>
extern struct passwd *_pammodutil_getpwnam(pam_handle_t *pamh,
extern struct passwd *_pammodutil_getpwuid(pam_handle_t *pamh,
uid_t uid);
+extern struct group *_pammodutil_getgrnam(pam_handle_t *pamh,
+ const char *group);
+
+extern struct group *_pammodutil_getgrgid(pam_handle_t *pamh,
+ gid_t gid);
+
+extern struct spwd *_pammodutil_getspnam(pam_handle_t *pamh,
+ const char *user);
+
+extern int _pammodutil_user_in_group_nam_nam(pam_handle_t *pamh,
+ const char *user,
+ const char *group);
+
+extern int _pammodutil_user_in_group_nam_gid(pam_handle_t *pamh,
+ const char *user,
+ gid_t group);
+
+extern int _pammodutil_user_in_group_uid_nam(pam_handle_t *pamh,
+ uid_t user,
+ const char *group);
+
+extern int _pammodutil_user_in_group_uid_gid(pam_handle_t *pamh,
+ uid_t user,
+ gid_t group);
+
extern void _pammodutil_cleanup(pam_handle_t *pamh, void *data,
int error_status);
#include "pammodutil.h"
+#include <limits.h>
+#include <pthread.h>
#include <pwd.h>
+#include <stdio.h>
#include <stdlib.h>
+static pthread_mutex_t _pammodutil_mutex = PTHREAD_MUTEX_INITIALIZER;
+static void _pammodutil_lock(void)
+{
+ pthread_mutex_lock(&_pammodutil_mutex);
+}
+static void _pammodutil_unlock(void)
+{
+ pthread_mutex_unlock(&_pammodutil_mutex);
+}
+
+static int intlen(int number)
+{
+ int len = 2;
+ while (number != 0) {
+ number /= 10;
+ len++;
+ }
+ return len;
+}
+
struct passwd *_pammodutil_getpwnam(pam_handle_t *pamh, const char *user)
{
#ifdef HAVE_GETPWNAM_R
status = getpwnam_r(user, buffer,
sizeof(struct passwd) + (char *) buffer,
length, &result);
- if (!status && result) {
- status = pam_set_data(pamh, "_pammodutil_getpwnam", result,
- _pammodutil_cleanup);
+ if (!status && (result == buffer)) {
+ char *data_name;
+ const void *ignore;
+ int i;
+
+ data_name = malloc(strlen("_pammodutil_getpwnam") + 1 +
+ strlen(user) + 1 + intlen(INT_MAX) + 1);
+ if ((pamh != NULL) && (data_name == NULL)) {
+ D(("was unable to register the data item [%s]",
+ pam_strerror(pamh, status)));
+ free(buffer);
+ return NULL;
+ }
+
+ if (pamh != NULL) {
+ for (i = 0; i < INT_MAX; i++) {
+ sprintf(data_name, "_pammodutil_getpwnam_%s_%d", user, i);
+ _pammodutil_lock();
+ status = PAM_NO_MODULE_DATA;
+ if (pam_get_data(pamh, data_name, &ignore) != PAM_SUCCESS) {
+ status = pam_set_data(pamh, data_name,
+ result, _pammodutil_cleanup);
+ }
+ _pammodutil_unlock();
+ if (status == PAM_SUCCESS) {
+ break;
+ }
+ }
+ } else {
+ status = PAM_SUCCESS;
+ }
+
+ free(data_name);
+
if (status == PAM_SUCCESS) {
D(("success"));
return result;
#include "pammodutil.h"
+#include <limits.h>
+#include <pthread.h>
#include <pwd.h>
+#include <stdio.h>
#include <stdlib.h>
+static pthread_mutex_t _pammodutil_mutex = PTHREAD_MUTEX_INITIALIZER;
+static void _pammodutil_lock(void)
+{
+ pthread_mutex_lock(&_pammodutil_mutex);
+}
+static void _pammodutil_unlock(void)
+{
+ pthread_mutex_unlock(&_pammodutil_mutex);
+}
+
+static int intlen(int number)
+{
+ int len = 2;
+ while (number != 0) {
+ number /= 10;
+ len++;
+ }
+ return len;
+}
+
+static int longlen(long number)
+{
+ int len = 2;
+ while (number != 0) {
+ number /= 10;
+ len++;
+ }
+ return len;
+}
+
struct passwd *_pammodutil_getpwuid(pam_handle_t *pamh, uid_t uid)
{
-#ifdef HAVE_GETPWNAM_R
+#ifdef HAVE_GETPWUID_R
void *buffer=NULL;
size_t length = PWD_INITIAL_LENGTH;
status = getpwuid_r(uid, buffer,
sizeof(struct passwd) + (char *) buffer,
length, &result);
- if (!status && result) {
- status = pam_set_data(pamh, "_pammodutil_getpwuid", result,
- _pammodutil_cleanup);
+ if (!status && (result == buffer)) {
+ char *data_name;
+ const void *ignore;
+ int i;
+
+ data_name = malloc(strlen("_pammodutil_getpwuid") + 1 +
+ longlen((long) uid) + 1 + intlen(INT_MAX) + 1);
+ if ((pamh != NULL) && (data_name == NULL)) {
+ D(("was unable to register the data item [%s]",
+ pam_strerror(pamh, status)));
+ free(buffer);
+ return NULL;
+ }
+
+ if (pamh != NULL) {
+ for (i = 0; i < INT_MAX; i++) {
+ sprintf(data_name, "_pammodutil_getpwuid_%ld_%d",
+ (long) uid, i);
+ _pammodutil_lock();
+ status = PAM_NO_MODULE_DATA;
+ if (pam_get_data(pamh, data_name, &ignore) != PAM_SUCCESS) {
+ status = pam_set_data(pamh, data_name,
+ result, _pammodutil_cleanup);
+ }
+ _pammodutil_unlock();
+ if (status == PAM_SUCCESS) {
+ break;
+ }
+ }
+ } else {
+ status = PAM_SUCCESS;
+ }
+
+ free(data_name);
+
if (status == PAM_SUCCESS) {
D(("success"));
return result;
free(buffer);
return NULL;
-#else /* ie. ifndef HAVE_GETPWNAM_R */
+#else /* ie. ifndef HAVE_GETPWUID_R */
/*
* Sorry, there does not appear to be a reentrant version of
- * getpwnam(). So, we use the standard libc function.
+ * getpwuid(). So, we use the standard libc function.
*/
return getpwuid(uid);
-#endif /* def HAVE_GETPWNAM_R */
+#endif /* def HAVE_GETPWUID_R */
}