From b8239bb34c7dc902d26320cfbe7fe26f0b326100 Mon Sep 17 00:00:00 2001 From: "Todd C. Miller" Date: Sat, 12 Dec 2009 15:37:52 +0000 Subject: [PATCH] Add support for mbr_check_membership() as present in darwin. --- check.c | 14 +++++++++++++- config.h.in | 3 +++ configure | 4 +++- configure.in | 3 ++- match.c | 26 ++++++++++++++++++++++---- sudo.c | 12 +++++++++++- sudo.h | 8 ++++++++ 7 files changed, 62 insertions(+), 8 deletions(-) diff --git a/check.c b/check.c index d8132a6ba..0d5e969fc 100644 --- a/check.c +++ b/check.c @@ -336,8 +336,13 @@ oflow: int user_is_exempt() { - struct group *grp; +#ifdef HAVE_MBR_CHECK_MEMBERSHIP + uuid_t gu; + int ismember; +#else char **gr_mem; +#endif + struct group *grp; if (!def_exempt_group) return(FALSE); @@ -348,10 +353,17 @@ user_is_exempt() if (user_gid == grp->gr_gid) return(TRUE); +#ifdef HAVE_MBR_CHECK_MEMBERSHIP + if (mbr_gid_to_uuid(grp->gr_gid, gu) == 0 && + mbr_check_membership(user_uuid, gu, &ismember) == 0 && ismember) + return(TRUE); +#else + /* XXX - should check stashed group vector */ for (gr_mem = grp->gr_mem; *gr_mem; gr_mem++) { if (strcmp(user_name, *gr_mem) == 0) return(TRUE); } +#endif return(FALSE); } diff --git a/config.h.in b/config.h.in index 9275d53ef..f3935410d 100644 --- a/config.h.in +++ b/config.h.in @@ -309,6 +309,9 @@ /* Define to 1 if you have the header file. */ #undef HAVE_MALLOC_H +/* Define to 1 if you have the `mbr_check_membership' function. */ +#undef HAVE_MBR_CHECK_MEMBERSHIP + /* Define to 1 if you have the `memchr' function. */ #undef HAVE_MEMCHR diff --git a/configure b/configure index d68088732..7b0089e7e 100755 --- a/configure +++ b/configure @@ -16036,11 +16036,13 @@ LIBS=$ac_save_LIBS + for ac_func in dup2 strchr strrchr memchr memcpy memset sysconf tzset \ strftime setrlimit initgroups getgroups fstat gettimeofday \ - regcomp setlocale getaddrinfo setsid setenv vhangup + regcomp setlocale getaddrinfo setsid setenv vhangup \ + mbr_check_membership do as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh` { echo "$as_me:$LINENO: checking for $ac_func" >&5 diff --git a/configure.in b/configure.in index 183783f57..82ddb27f9 100644 --- a/configure.in +++ b/configure.in @@ -1848,7 +1848,8 @@ dnl AC_FUNC_GETGROUPS AC_CHECK_FUNCS(dup2 strchr strrchr memchr memcpy memset sysconf tzset \ strftime setrlimit initgroups getgroups fstat gettimeofday \ - regcomp setlocale getaddrinfo setsid setenv vhangup) + regcomp setlocale getaddrinfo setsid setenv vhangup \ + mbr_check_membership) AC_CHECK_FUNCS(getline, [], [ AC_LIBOBJ(getline) AC_CHECK_FUNCS(fgetln) diff --git a/match.c b/match.c index 2fe853c7e..79eb2fc8f 100644 --- a/match.c +++ b/match.c @@ -819,9 +819,14 @@ usergr_matches(group, user, pw) char *user; struct passwd *pw; { - struct group *grp = NULL; - char **cur; +#ifdef HAVE_MBR_CHECK_MEMBERSHIP + uuid_t gu, uu; + int ismember; +#else + char **gr_mem; int i; +#endif + struct group *grp = NULL; /* make sure we have a valid usergroup, sudo style */ if (*group++ != '%') @@ -847,17 +852,30 @@ usergr_matches(group, user, pw) * supplementary group vector, check it first. */ if (strcmp(user, list_pw ? list_pw->pw_name : user_name) == 0) { +#ifdef HAVE_MBR_CHECK_MEMBERSHIP + if (mbr_gid_to_uuid(grp->gr_gid, gu) == 0 && + mbr_check_membership(user_uuid, gu, &ismember) == 0 && ismember) + return(TRUE); +#else for (i = 0; i < user_ngroups; i++) if (grp->gr_gid == user_groups[i]) return(TRUE); +#endif } check_membership: +#ifdef HAVE_MBR_CHECK_MEMBERSHIP + 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 if (grp != NULL && grp->gr_mem != NULL) { - for (cur = grp->gr_mem; *cur; cur++) - if (strcmp(*cur, user) == 0) + for (gr_mem = grp->gr_mem; *gr_mem; gr_mem++) + if (strcmp(*gr_mem, user) == 0) return(TRUE); } +#endif #ifdef USING_NONUNIX_GROUPS /* not a Unix group, could be an AD group */ diff --git a/sudo.c b/sudo.c index c98741634..76c30194d 100644 --- a/sudo.c +++ b/sudo.c @@ -94,6 +94,9 @@ #ifdef HAVE_SELINUX # include #endif +#ifdef HAVE_MBR_CHECK_MEMBERSHIP +# include +#endif #include #include "sudo.h" @@ -436,8 +439,12 @@ main(argc, argv, envp) if (user_uid == 0 && strcmp(prev_user, "root") != 0) { struct passwd *pw; - if ((pw = sudo_getpwnam(prev_user)) != NULL) + if ((pw = sudo_getpwnam(prev_user)) != NULL) { sudo_user.pw = pw; +#ifdef HAVE_MBR_CHECK_MEMBERSHIP + mbr_uid_to_uuid(user_uid, user_uuid); +#endif + } } } @@ -730,6 +737,9 @@ init_vars(sudo_mode, envp) errorx(1, "unknown uid: %s", pw_name); log_error(0, "unknown uid: %s", pw_name); } +#ifdef HAVE_MBR_CHECK_MEMBERSHIP + mbr_uid_to_uuid(user_uid, user_uuid); +#endif if (user_shell == NULL || *user_shell == '\0') user_shell = estrdup(sudo_user.pw->pw_shell); diff --git a/sudo.h b/sudo.h index 2daa313dc..5a0743aaa 100644 --- a/sudo.h +++ b/sudo.h @@ -35,6 +35,10 @@ #include "missing.h" #include "sudo_nss.h" +#ifdef HAVE_MBR_CHECK_MEMBERSHIP +# include +#endif + /* * Info pertaining to the invoking user. */ @@ -67,6 +71,9 @@ struct sudo_user { #endif char cwd[PATH_MAX]; char sessid[7]; +#ifdef HAVE_MBR_CHECK_MEMBERSHIP + uuid_t uuid; +#endif }; /* @@ -141,6 +148,7 @@ struct sudo_user { #define user_name (sudo_user.pw->pw_name) #define user_passwd (sudo_user.pw->pw_passwd) #define user_uid (sudo_user.pw->pw_uid) +#define user_uuid (sudo_user.uuid) #define user_gid (sudo_user.pw->pw_gid) #define user_dir (sudo_user.pw->pw_dir) #define user_shell (sudo_user.shell)