File sudo-1.8.10p3-groups_resolve.patch of Package sudo.5652
Index: sudo-1.8.10p3/plugins/sudoers/def_data.c
===================================================================
--- sudo-1.8.10p3.orig/plugins/sudoers/def_data.c
+++ sudo-1.8.10p3/plugins/sudoers/def_data.c
@@ -383,6 +383,10 @@ struct sudo_defs_types sudo_defs_table[]
N_("Enable sudoers netgroup support"),
NULL,
}, {
+ "legacy_group_processing", T_FLAG,
+ N_("Don't pre-resolve all group names"),
+ NULL,
+ }, {
NULL, 0, NULL
}
};
Index: sudo-1.8.10p3/plugins/sudoers/defaults.c
===================================================================
--- sudo-1.8.10p3.orig/plugins/sudoers/defaults.c
+++ sudo-1.8.10p3/plugins/sudoers/defaults.c
@@ -364,6 +364,7 @@ init_defaults(void)
}
/* First initialize the flags. */
+ def_legacy_group_processing = true;
#ifdef LONG_OTP_PROMPT
def_long_otp_prompt = true;
#endif
Index: sudo-1.8.10p3/plugins/sudoers/ldap.c
===================================================================
--- sudo-1.8.10p3.orig/plugins/sudoers/ldap.c
+++ sudo-1.8.10p3/plugins/sudoers/ldap.c
@@ -1247,6 +1247,15 @@ sudo_ldap_build_pass1(struct passwd *pw)
}
sz += 13 + MAX_UID_T_LEN;
if ((grlist = sudo_get_grlist(pw)) != NULL) {
+ if (!grlist->groups_resolved) {
+ int rc = sudo_resolve_gids(grlist->gids, grlist->ngids,
+ grlist->groups, grlist->groups_buffer);
+ if (rc < 0) {
+ return NULL;
+ }
+ grlist->ngroups = rc;
+ grlist->groups_resolved = true;
+ }
for (i = 0; i < grlist->ngroups; i++) {
if (grp != NULL && strcasecmp(grlist->groups[i], grp->gr_name) == 0)
continue;
Index: sudo-1.8.10p3/plugins/sudoers/pwutil.c
===================================================================
--- sudo-1.8.10p3.orig/plugins/sudoers/pwutil.c
+++ sudo-1.8.10p3/plugins/sudoers/pwutil.c
@@ -631,12 +631,27 @@ user_in_group(const struct passwd *pw, c
/*
* If it could be a sudo-style group ID check gids first.
*/
+ bool do_gid_lookup = false;
+ gid_t gid;
+
if (group[0] == '#') {
- gid_t gid = (gid_t) atoid(group + 1, NULL, NULL, &errstr);
+ gid = (gid_t) atoid(group + 1, NULL, NULL, &errstr);
if (errstr != NULL) {
sudo_debug_printf(SUDO_DEBUG_DEBUG|SUDO_DEBUG_DIAG,
"gid %s %s", group, errstr);
} else {
+ do_gid_lookup = true;
+ }
+ } else if (def_legacy_group_processing) {
+ struct group *grent = sudo_getgrnam(group);
+ if (grent == NULL) {
+ goto done;
+ }
+ gid = grent->gr_gid;
+ do_gid_lookup = true;
+ }
+
+ if (do_gid_lookup) {
if (gid == pw->pw_gid) {
matched = true;
goto done;
@@ -647,7 +662,19 @@ user_in_group(const struct passwd *pw, c
goto done;
}
}
+ }
+
+ if (def_legacy_group_processing) {
+ goto done;
+ }
+ if (!grlist->groups_resolved) {
+ int rc = sudo_resolve_gids(grlist->gids, grlist->ngids,
+ grlist->groups, grlist->groups_buffer);
+ if (rc < 0) {
+ goto done;
}
+ grlist->ngroups = rc;
+ grlist->groups_resolved = true;
}
/*
Index: sudo-1.8.10p3/plugins/sudoers/pwutil_impl.c
===================================================================
--- sudo-1.8.10p3.orig/plugins/sudoers/pwutil_impl.c
+++ sudo-1.8.10p3/plugins/sudoers/pwutil_impl.c
@@ -220,6 +220,16 @@ sudo_make_gritem(gid_t gid, const char *
debug_return_ptr(&gritem->cache);
}
+static int
+get_groupname_len(void)
+{
+#if defined(HAVE_SYSCONF) && defined(_SC_LOGIN_NAME_MAX)
+ return MAX((int)sysconf(_SC_LOGIN_NAME_MAX), 32);
+#else
+ return MAX(LOGIN_NAME_MAX, 32);
+#endif
+}
+
/*
* Dynamically allocate space for a struct item plus the key and data
* elements. Fills in datum from user_gids or from getgrouplist(3).
@@ -229,11 +239,10 @@ sudo_make_grlist_item(const struct passw
char * const *unused2)
{
char *cp;
- size_t nsize, ngroups, total, len;
+ size_t nsize, total;
struct cache_item_grlist *grlitem;
struct group_list *grlist;
GETGROUPS_T *gids;
- struct group *grp;
int i, ngids, groupname_len;
debug_decl(sudo_make_grlist_item, SUDO_DEBUG_NSS)
@@ -271,11 +280,7 @@ sudo_make_grlist_item(const struct passw
aix_setauthdb((char *) pw->pw_name);
#endif
-#if defined(HAVE_SYSCONF) && defined(_SC_LOGIN_NAME_MAX)
- groupname_len = MAX((int)sysconf(_SC_LOGIN_NAME_MAX), 32);
-#else
- groupname_len = MAX(LOGIN_NAME_MAX, 32);
-#endif
+ groupname_len = get_groupname_len();
/* Allocate in one big chunk for easy freeing. */
nsize = strlen(pw->pw_name) + 1;
@@ -284,7 +289,6 @@ sudo_make_grlist_item(const struct passw
total += sizeof(gid_t *) * ngids;
total += groupname_len * ngids;
-again:
grlitem = ecalloc(1, total);
/*
@@ -312,27 +316,26 @@ again:
for (i = 0; i < ngids; i++)
grlist->gids[i] = gids[i];
grlist->ngids = ngids;
+ grlist->groups_buffer = cp;
/*
- * Resolve and store group names by ID.
+ * Resolve and store group names by ID if legacy_group_processing is off.
*/
- ngroups = 0;
- for (i = 0; i < ngids; i++) {
- if ((grp = sudo_getgrgid(gids[i])) != NULL) {
- len = strlen(grp->gr_name) + 1;
- if (cp - (char *)grlitem + len > total) {
- total += len + groupname_len;
- efree(grlitem);
- sudo_gr_delref(grp);
- goto again;
- }
- memcpy(cp, grp->gr_name, len);
- grlist->groups[ngroups++] = cp;
- cp += len;
- sudo_gr_delref(grp);
- }
+ if (def_legacy_group_processing) {
+ for (i = 0; i < ngids; i++) {
+ grlist->groups[i] = NULL;
+ }
+ grlist->ngroups = 0;
+ grlist->groups_resolved = false;
+ } else {
+ int rc = sudo_resolve_gids(gids, ngids, grlist->groups, grlist->groups_buffer);
+ if (rc < 0) {
+ efree(grlitem);
+ return NULL;
+ }
+ grlist->ngroups = rc;
+ grlist->groups_resolved = true;
}
- grlist->ngroups = ngroups;
efree(gids);
#ifdef HAVE_SETAUTHDB
@@ -341,3 +344,33 @@ again:
debug_return_ptr(&grlitem->cache);
}
+
+int sudo_resolve_gids(GETGROUPS_T *gids, int ngids, char **groups, char *group_buffer)
+{
+ struct group *grp;
+ int space_left = ngids * get_groupname_len();
+ int ngroups = 0;
+ int i;
+ char *cp = group_buffer;
+ debug_decl(sudo_resolve_gids, SUDO_DEBUG_NSS)
+
+ for (i = 0; i < ngids; i++) {
+ if ((grp = sudo_getgrgid(gids[i])) != NULL) {
+ int len = strlen(grp->gr_name) + 1;
+
+ if (space_left < len) {
+ sudo_gr_delref(grp);
+ debug_return_int(-1);
+ }
+
+ memcpy(cp, grp->gr_name, len);
+ groups[ngroups++] = cp;
+ cp += len;
+ space_left -= len;
+ sudo_gr_delref(grp);
+ }
+ }
+
+ debug_return_int(ngroups);
+}
+
Index: sudo-1.8.10p3/plugins/sudoers/sudoers.h
===================================================================
--- sudo-1.8.10p3.orig/plugins/sudoers/sudoers.h
+++ sudo-1.8.10p3/plugins/sudoers/sudoers.h
@@ -53,6 +53,8 @@ struct group_list {
GETGROUPS_T *gids;
int ngroups;
int ngids;
+ int groups_resolved;
+ char *groups_buffer;
};
/*
@@ -303,6 +305,7 @@ __dso_public struct group *sudo_getgrnam
__dso_public void sudo_gr_addref(struct group *);
__dso_public void sudo_gr_delref(struct group *);
bool user_in_group(const struct passwd *, const char *);
+int sudo_resolve_gids(GETGROUPS_T *gids, int ngids, char **groups, char *group_buffer);
struct group *sudo_fakegrnam(const char *);
struct group_list *sudo_get_grlist(const struct passwd *pw);
struct passwd *sudo_fakepwnam(const char *, gid_t);
Index: sudo-1.8.10p3/plugins/sudoers/def_data.h
===================================================================
--- sudo-1.8.10p3.orig/plugins/sudoers/def_data.h
+++ sudo-1.8.10p3/plugins/sudoers/def_data.h
@@ -178,6 +178,8 @@
#define I_MAXSEQ 88
#define def_use_netgroups (sudo_defs_table[89].sd_un.flag)
#define I_USE_NETGROUPS 89
+#define def_legacy_group_processing (sudo_defs_table[90].sd_un.flag)
+#define I_LEGACY_GROUP_PROCESSING 90
enum def_tuple {
never,