X-Git-Url: https://git.gag.com/?a=blobdiff_plain;f=pwutil.c;h=35524f355ee3220921b276b1dfc0c6f5e40e9597;hb=202c474422229f06d161b2beb1cd416999ea33df;hp=29471b6bee986fa54fb6d546e7be0ec060995bfb;hpb=83cad190740ab8312cf2ea953c1bf9dee2e965bf;p=debian%2Fsudo diff --git a/pwutil.c b/pwutil.c index 29471b6..35524f3 100644 --- a/pwutil.c +++ b/pwutil.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 1996, 1998-2005, 2007-2009 + * Copyright (c) 1996, 1998-2005, 2007-2010 * Todd C. Miller * * Permission to use, copy, modify, and distribute this software for any @@ -38,40 +38,22 @@ # include # endif # include -#else -# ifdef HAVE_STRINGS_H -# include -# endif #endif /* HAVE_STRING_H */ +#ifdef HAVE_STRINGS_H +# include +#endif /* HAVE_STRINGS_H */ #ifdef HAVE_UNISTD_H # include #endif /* HAVE_UNISTD_H */ +#ifdef HAVE_SETAUTHDB +# include +#endif /* HAVE_SETAUTHDB */ #include #include #include "sudo.h" #include "redblack.h" -#ifdef MYPW -extern void (*my_setgrent) __P((void)); -extern void (*my_endgrent) __P((void)); -extern struct group *(*my_getgrnam) __P((const char *)); -extern struct group *(*my_getgrgid) __P((gid_t)); -#define setgrent() my_setgrent() -#define endgrent() my_endgrent() -#define getgrnam(n) my_getgrnam(n) -#define getgrgid(g) my_getgrgid(g) - -extern void (*my_setpwent) __P((void)); -extern void (*my_endpwent) __P((void)); -extern struct passwd *(*my_getpwnam) __P((const char *)); -extern struct passwd *(*my_getpwuid) __P((uid_t)); -#define setpwent() my_setpwent() -#define endpwent() my_endpwent() -#define getpwnam(n) my_getpwnam(n) -#define getpwuid(u) my_getpwuid(u) -#endif - /* * The passwd and group caches. */ @@ -106,7 +88,7 @@ cmp_pwnam(v1, v2) { const struct passwd *pw1 = (const struct passwd *) v1; const struct passwd *pw2 = (const struct passwd *) v2; - return(strcmp(pw1->pw_name, pw2->pw_name)); + return(strcasecmp(pw1->pw_name, pw2->pw_name)); } #define FIELD_SIZE(src, name, size) \ @@ -153,7 +135,9 @@ sudo_pwdup(pw) #endif FIELD_SIZE(pw, pw_gecos, gsize); FIELD_SIZE(pw, pw_dir, dsize); - FIELD_SIZE(pw, pw_shell, ssize); + /* Treat shell specially since we expand "" -> _PATH_BSHELL */ + ssize = strlen(pw_shell) + 1; + total += ssize; if ((cp = malloc(total)) == NULL) return(NULL); @@ -172,7 +156,9 @@ sudo_pwdup(pw) #endif FIELD_COPY(pw, newpw, pw_gecos, gsize); FIELD_COPY(pw, newpw, pw_dir, dsize); - FIELD_COPY(pw, newpw, pw_shell, ssize); + /* Treat shell specially since we expand "" -> _PATH_BSHELL */ + memcpy(cp, pw_shell, ssize); + newpw->pw_shell = cp; return(newpw); } @@ -192,11 +178,14 @@ sudo_getpwuid(uid) key.pw_uid = uid; if ((node = rbfind(pwcache_byuid, &key)) != NULL) { pw = (struct passwd *) node->data; - return(pw->pw_name != NULL ? pw : NULL); + goto done; } /* * Cache passwd db entry if it exists or a negative response if not. */ +#ifdef HAVE_SETAUTHDB + aix_setauthdb(IDtouser(uid)); +#endif if ((pw = getpwuid(uid)) != NULL) { pw = sudo_pwdup(pw); cp = sudo_getepw(pw); /* get shadow password */ @@ -206,15 +195,18 @@ sudo_getpwuid(uid) if (rbinsert(pwcache_byuid, (void *) pw) != NULL) errorx(1, "unable to cache uid %lu (%s), already exists", uid, pw->pw_name); - return(pw); } else { pw = emalloc(sizeof(*pw)); zero_bytes(pw, sizeof(*pw)); pw->pw_uid = uid; if (rbinsert(pwcache_byuid, (void *) pw) != NULL) errorx(1, "unable to cache uid %lu, already exists", uid); - return(NULL); } +#ifdef HAVE_SETAUTHDB + aix_restoreauthdb(); +#endif +done: + return(pw->pw_name != NULL ? pw : NULL); } /* @@ -233,11 +225,14 @@ sudo_getpwnam(name) key.pw_name = (char *) name; if ((node = rbfind(pwcache_byname, &key)) != NULL) { pw = (struct passwd *) node->data; - return(pw->pw_uid != (uid_t) -1 ? pw : NULL); + goto done; } /* * Cache passwd db entry if it exists or a negative response if not. */ +#ifdef HAVE_SETAUTHDB + aix_setauthdb((char *) name); +#endif if ((pw = getpwnam(name)) != NULL) { pw = sudo_pwdup(pw); cp = sudo_getepw(pw); /* get shadow password */ @@ -246,7 +241,6 @@ sudo_getpwnam(name) pw->pw_passwd = cp; if (rbinsert(pwcache_byname, (void *) pw) != NULL) errorx(1, "unable to cache user %s, already exists", name); - return(pw); } else { len = strlen(name) + 1; cp = emalloc(sizeof(*pw) + len); @@ -258,8 +252,12 @@ sudo_getpwnam(name) pw->pw_uid = (uid_t) -1; if (rbinsert(pwcache_byname, (void *) pw) != NULL) errorx(1, "unable to cache user %s, already exists", name); - return(NULL); } +#ifdef HAVE_SETAUTHDB + aix_restoreauthdb(); +#endif +done: + return(pw->pw_uid != (uid_t) -1 ? pw : NULL); } /* @@ -408,7 +406,7 @@ cmp_grnam(v1, v2) { const struct group *grp1 = (const struct group *) v1; const struct group *grp2 = (const struct group *) v2; - return(strcmp(grp1->gr_name, grp2->gr_name)); + return(strcasecmp(grp1->gr_name, grp2->gr_name)); } struct group * @@ -471,7 +469,7 @@ sudo_getgrgid(gid) key.gr_gid = gid; if ((node = rbfind(grcache_bygid, &key)) != NULL) { gr = (struct group *) node->data; - return(gr->gr_name != NULL ? gr : NULL); + goto done; } /* * Cache group db entry if it exists or a negative response if not. @@ -481,15 +479,15 @@ sudo_getgrgid(gid) if (rbinsert(grcache_bygid, (void *) gr) != NULL) errorx(1, "unable to cache gid %lu (%s), already exists", gid, gr->gr_name); - return(gr); } else { gr = emalloc(sizeof(*gr)); zero_bytes(gr, sizeof(*gr)); gr->gr_gid = gid; if (rbinsert(grcache_bygid, (void *) gr) != NULL) errorx(1, "unable to cache gid %lu, already exists, gid"); - return(NULL); } +done: + return(gr->gr_name != NULL ? gr : NULL); } /* @@ -507,7 +505,7 @@ sudo_getgrnam(name) key.gr_name = (char *) name; if ((node = rbfind(grcache_byname, &key)) != NULL) { gr = (struct group *) node->data; - return(gr->gr_gid != (gid_t) -1 ? gr : NULL); + goto done; } /* * Cache group db entry if it exists or a negative response if not. @@ -516,7 +514,6 @@ sudo_getgrnam(name) gr = sudo_grdup(gr); if (rbinsert(grcache_byname, (void *) gr) != NULL) errorx(1, "unable to cache group %s, already exists", name); - return(gr); } else { len = strlen(name) + 1; cp = emalloc(sizeof(*gr) + len); @@ -528,8 +525,9 @@ sudo_getgrnam(name) gr->gr_gid = (gid_t) -1; if (rbinsert(grcache_byname, (void *) gr) != NULL) errorx(1, "unable to cache group %s, already exists", name); - return(NULL); } +done: + return(gr->gr_gid != (gid_t) -1 ? gr : NULL); } void @@ -565,3 +563,70 @@ sudo_endgrent() sudo_freegrcache(); #endif } + +int +user_in_group(pw, group) + struct passwd *pw; + const char *group; +{ +#ifdef HAVE_MBR_CHECK_MEMBERSHIP + uuid_t gu, uu; + int ismember; +#else + char **gr_mem; + int i; +#endif + struct group *grp; + +#ifdef HAVE_SETAUTHDB + aix_setauthdb(pw->pw_name); +#endif + grp = sudo_getgrnam(group); +#ifdef HAVE_SETAUTHDB + aix_restoreauthdb(); +#endif + if (grp == NULL) + return(FALSE); + + /* check against user's primary (passwd file) gid */ + if (grp->gr_gid == pw->pw_gid) + return(TRUE); + +#ifdef HAVE_MBR_CHECK_MEMBERSHIP + /* If we are matching the invoking user use the stashed uuid. */ + if (strcmp(pw->pw_name, user_name) == 0) { + if (mbr_gid_to_uuid(grp->gr_gid, gu) == 0 && + mbr_check_membership(user_uuid, gu, &ismember) == 0 && ismember) + return(TRUE); + } else { + if (mbr_uid_to_uuid(pw->pw_uid, uu) == 0 && + mbr_gid_to_uuid(grp->gr_gid, gu) == 0 && + mbr_check_membership(uu, gu, &ismember) == 0 && ismember) + return(TRUE); + } +#else /* HAVE_MBR_CHECK_MEMBERSHIP */ +# ifdef HAVE_GETGROUPS + /* + * If we are matching the invoking or list user and that user has a + * supplementary group vector, check it. + */ + if (user_ngroups >= 0 && + strcmp(pw->pw_name, list_pw ? list_pw->pw_name : user_name) == 0) { + for (i = 0; i < user_ngroups; i++) { + if (grp->gr_gid == user_groups[i]) + return(TRUE); + } + } else +# endif /* HAVE_GETGROUPS */ + { + if (grp != NULL && grp->gr_mem != NULL) { + for (gr_mem = grp->gr_mem; *gr_mem; gr_mem++) { + if (strcmp(*gr_mem, pw->pw_name) == 0) + return(TRUE); + } + } + } +#endif /* HAVE_MBR_CHECK_MEMBERSHIP */ + + return(FALSE); +}