-----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1 If you create an seusers file using the sudo syntax %groupname, getseuserbyname will check the user's groups for a match. Match sequence will be: username exists FIRST group match default I will be sending a separate patch to allow semanage to add %groupname -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.9 (GNU/Linux) Comment: Using GnuPG with Fedora - http://enigmail.mozdev.org iEYEARECAAYFAkiS7UsACgkQrlYvE4MpobPa7ACgwAZvdg8hD+KRT2hBY0dhna8o tQ8AmwRgEatZmS8hUuw3Bx/uwdnyG4OG =IRCg -----END PGP SIGNATURE-----
diff --exclude-from=exclude -N -u -r nsalibselinux/src/seusers.c libselinux-2.0.70/src/seusers.c --- nsalibselinux/src/seusers.c 2008-06-12 23:25:14.000000000 -0400 +++ libselinux-2.0.70/src/seusers.c 2008-08-01 06:53:03.000000000 -0400 @@ -89,6 +89,62 @@ int require_seusers hidden = 0; +#include <pwd.h> +#include <grp.h> + +static gid_t get_default_gid(const char *name) { + struct passwd pwstorage, *pwent = NULL; + gid_t gid = -1; + /* Allocate space for the getpwnam_r buffer */ + long rbuflen = sysconf(_SC_GETPW_R_SIZE_MAX); + if (rbuflen <= 0) return -1; + char *rbuf = malloc(rbuflen); + if (rbuf == NULL) return -1; + + int retval = getpwnam_r(name, &pwstorage, rbuf, rbuflen, &pwent); + if (retval == 0 || pwent != NULL) { + gid = pwent->pw_gid; + } + free(rbuf); + return gid; +} + +static int check_group(const char *group, const char *name, const gid_t gid) { + int match = 0; + int i, ng = 0; + gid_t *groups = NULL; + struct group gbuf, *grent = NULL; + + long rbuflen = sysconf(_SC_GETGR_R_SIZE_MAX); + if (rbuflen <= 0) + return 0; + char *rbuf = malloc(rbuflen); + if (rbuf == NULL) + return 0; + + if (getgrnam_r(group, &gbuf, rbuf, rbuflen, + &grent) != 0) + goto done; + + if (getgrouplist(name, gid, NULL, &ng) < 0) { + groups = (gid_t *) malloc(sizeof (gid_t) * ng); + if (!groups) goto done; + if (getgrouplist(name, gid, groups, &ng) < 0) goto done; + } + + for (i = 0; i < ng; i++) { + if (grent->gr_gid == groups[i]) { + match = 1; + goto done; + } + } + + done: + free(groups); + free(rbuf); + return match; +} + int getseuserbyname(const char *name, char **r_seuser, char **r_level) { FILE *cfg = NULL; @@ -101,9 +157,14 @@ char *username = NULL; char *seuser = NULL; char *level = NULL; + char *groupseuser = NULL; + char *grouplevel = NULL; char *defaultseuser = NULL; char *defaultlevel = NULL; + gid_t gid = get_default_gid(name); + if ( gid == (gid_t) -1 ) goto nomatch; + cfg = fopen(selinux_usersconf_path(), "r"); if (!cfg) goto nomatch; @@ -124,31 +185,48 @@ if (!strcmp(username, name)) break; - if (!defaultseuser && !strcmp(username, "__default__")) { - free(username); - defaultseuser = seuser; - defaultlevel = level; + if (username[0] == '%' && + !groupseuser && + check_group(&username[1], name, gid)) { + groupseuser = seuser; + grouplevel = level; } else { - free(username); - free(seuser); - free(level); + if (!defaultseuser && + !strcmp(username, "__default__")) { + defaultseuser = seuser; + defaultlevel = level; + } else { + free(seuser); + free(level); + } } + free(username); + username = NULL; seuser = NULL; } - if (buffer) - free(buffer); + free(buffer); fclose(cfg); if (seuser) { free(username); free(defaultseuser); free(defaultlevel); + free(groupseuser); + free(grouplevel); *r_seuser = seuser; *r_level = level; return 0; } + if (groupseuser) { + free(defaultseuser); + free(defaultlevel); + *r_seuser = groupseuser; + *r_level = grouplevel; + return 0; + } + if (defaultseuser) { *r_seuser = defaultseuser; *r_level = defaultlevel;
Attachment:
diff.sig
Description: Binary data