(root)/
Linux-PAM-1.5.3/
libpam/
pam_modutil_ingroup.c
       1  /*
       2   * $Id$
       3   *
       4   * This function provides common methods for checking if a user is in a
       5   * specified group.
       6   */
       7  
       8  #include "pam_modutil_private.h"
       9  
      10  #include <stdlib.h>
      11  #include <pwd.h>
      12  #include <grp.h>
      13  
      14  #ifdef HAVE_GETGROUPLIST
      15  
      16  #define NGROUPS_MIN 100
      17  #define NGROUPS_MAX 65536
      18  
      19  static int checkgrouplist(const char *user, gid_t primary, gid_t target)
      20  {
      21  	int ngroups, pgroups, i;
      22  
      23  	ngroups = NGROUPS_MIN;
      24  	do {
      25  		gid_t *grouplist;
      26  
      27  		pgroups = ngroups;
      28  		grouplist = malloc(sizeof(gid_t) * ngroups);
      29  		if (grouplist == NULL) {
      30  			return 0;
      31  		}
      32  		i = getgrouplist(user, primary, grouplist, &ngroups);
      33  		if (i >= 0) {
      34  			for (i = 0; i < ngroups; i++) {
      35  				if (grouplist[i] == target) {
      36  					free(grouplist);
      37  					return 1;
      38  				}
      39  			}
      40  		}
      41  		free(grouplist);
      42  	} while (i < 0 && ngroups > 0 && ngroups != pgroups && ngroups <= NGROUPS_MAX);
      43  	return 0;
      44  }
      45  #endif
      46  
      47  static int
      48  pam_modutil_user_in_group_common(pam_handle_t *pamh UNUSED,
      49  				 struct passwd *pwd,
      50  				 struct group *grp)
      51  {
      52  	int i;
      53  
      54  	if (pwd == NULL) {
      55  		return 0;
      56  	}
      57  	if (grp == NULL) {
      58  		return 0;
      59  	}
      60  
      61  	if (pwd->pw_gid == grp->gr_gid) {
      62  		return 1;
      63  	}
      64  
      65  	for (i = 0; (grp->gr_mem != NULL) && (grp->gr_mem[i] != NULL); i++) {
      66  		if (strcmp(pwd->pw_name, grp->gr_mem[i]) == 0) {
      67  			return 1;
      68  		}
      69  	}
      70  
      71  #ifdef HAVE_GETGROUPLIST
      72  	if (checkgrouplist(pwd->pw_name, pwd->pw_gid, grp->gr_gid)) {
      73  		return 1;
      74  	}
      75  #endif
      76  
      77  	return 0;
      78  }
      79  
      80  int
      81  pam_modutil_user_in_group_nam_nam(pam_handle_t *pamh,
      82  				 const char *user, const char *group)
      83  {
      84  	struct passwd *pwd;
      85  	struct group *grp;
      86  
      87  	pwd = pam_modutil_getpwnam(pamh, user);
      88  	grp = pam_modutil_getgrnam(pamh, group);
      89  
      90  	return pam_modutil_user_in_group_common(pamh, pwd, grp);
      91  }
      92  
      93  int
      94  pam_modutil_user_in_group_nam_gid(pam_handle_t *pamh,
      95  				  const char *user, gid_t group)
      96  {
      97  	struct passwd *pwd;
      98  	struct group *grp;
      99  
     100  	pwd = pam_modutil_getpwnam(pamh, user);
     101  	grp = pam_modutil_getgrgid(pamh, group);
     102  
     103  	return pam_modutil_user_in_group_common(pamh, pwd, grp);
     104  }
     105  
     106  int
     107  pam_modutil_user_in_group_uid_nam(pam_handle_t *pamh,
     108  				  uid_t user, const char *group)
     109  {
     110  	struct passwd *pwd;
     111  	struct group *grp;
     112  
     113  	pwd = pam_modutil_getpwuid(pamh, user);
     114  	grp = pam_modutil_getgrnam(pamh, group);
     115  
     116  	return pam_modutil_user_in_group_common(pamh, pwd, grp);
     117  }
     118  
     119  int
     120  pam_modutil_user_in_group_uid_gid(pam_handle_t *pamh,
     121  				  uid_t user, gid_t group)
     122  {
     123  	struct passwd *pwd;
     124  	struct group *grp;
     125  
     126  	pwd = pam_modutil_getpwuid(pamh, user);
     127  	grp = pam_modutil_getgrgid(pamh, group);
     128  
     129  	return pam_modutil_user_in_group_common(pamh, pwd, grp);
     130  }