From 54bd6accb06fdb5227e3ec789d7fcc44dc85c458 Mon Sep 17 00:00:00 2001 From: Michael Stone Date: Tue, 08 Jul 2008 06:21:04 +0000 Subject: A small victory. --- diff --git a/nss-rainbow.c b/nss-rainbow.c index cb4273f..5f5ef5e 100644 --- a/nss-rainbow.c +++ b/nss-rainbow.c @@ -210,6 +210,7 @@ struct gid_list { gid_t gid; }; +size_t g_gids_cnt; struct gid_list g_gids; struct gid_list* g_gid; @@ -243,26 +244,21 @@ uid_to_gid_filter(const struct dirent* d) { /* We might have already allocated a uid_list for our gid. * Therefore, search for it. */ struct gid_list* gid_iter = NULL; - if (list_empty(&g_gids.list)) { - gid_iter = list_entry(&g_gids.list, struct gid_list, list); - gid_iter->gid = gid; - INIT_LIST_HEAD(&(gid_iter->uids.list)); + list_for_each_entry(gid_iter, &g_gids.list, list) { + if (gid_iter->gid == gid) + break; } - else { - list_for_each_entry(gid_iter, &g_gids.list, list) { - if (gid_iter->gid == gid) - break; - } - /* If we find no uid_list, make one and insert it. */ - if (&gid_iter->list == &g_gids.list) { - LET(gid_iter = malloc(sizeof(struct gid_list)), !gid_iter, - "Unable to allocate new gid_list node.", exit); - gid_iter->gid = gid; - INIT_LIST_HEAD(&(gid_iter->uids.list)); - list_add_tail(&(gid_iter->list), &g_gids.list); - } + /* If we find no uid_list, make one and insert it. */ + if (&gid_iter->list == &g_gids.list) { + LET(gid_iter = malloc(sizeof(struct gid_list)), !gid_iter, + "Unable to allocate new gid_list node.", exit); + gid_iter->gid = gid; + INIT_LIST_HEAD(&(gid_iter->uids.list)); + list_add_tail(&(gid_iter->list), &g_gids.list); + g_gid = gid_iter; } + g_gids_cnt++; /* gid_iter now points to the appropriate gid_list node. * There's no way that we could already have our current (uid, gid) row. @@ -280,9 +276,12 @@ exit: enum nss_status _nss_rainbow_setgrent(void) { struct dirent** uids; INIT_LIST_HEAD(&g_gids.list); - g_gid = &g_gids.list; + INIT_LIST_HEAD(&g_gids.uids.list); + g_gids_cnt = 0; + g_gid = &g_gids; CHK(scandir(SPOOL "/uid_to_gid", &uids, uid_to_gid_filter, versionsort) == -1, "Unable to extract uid->gids links from $RAINBOW_SPOOL.", out_error_spool); + g_gid = list_entry(g_gids.list.next, struct gid_list, list); return NSS_STATUS_SUCCESS; out_error_spool: return NSS_STATUS_UNAVAIL; @@ -292,9 +291,9 @@ enum nss_status _nss_rainbow_endgrent(void) { struct gid_list* gid_iter; struct uid_list* uid_iter; while(!list_empty(&g_gids.list)) { - gid_iter = list_entry(&g_gids.list.next, struct gid_list, list); + gid_iter = list_entry(g_gids.list.next, struct gid_list, list); while(!list_empty(&(gid_iter->uids.list))) { - uid_iter = list_entry(&(gid_iter->uids.list.next), struct uid_list, list); + uid_iter = list_entry(gid_iter->uids.list.next, struct uid_list, list); list_del(&(uid_iter->list)); free(uid_iter); } @@ -332,10 +331,10 @@ fill_group(struct group* result, char* buf, size_t buflen, int *errnop, struct g /* reserve space for the member-pointers */ size_t member_size = (member_count+1)* sizeof(char*); result->gr_mem = buf; - TST(buflen > member_size, EINVAL, + TST(buflen < member_size, EINVAL, "Not enough space for group member pointers.", out_error_errno); - result->gr_mem[member_count-1] = 0; - buf = buf + member_size; + result->gr_mem[member_count] = 0; + buf += member_size; buflen -= member_size; /* fill in the members and swing the pointers */ @@ -344,6 +343,7 @@ fill_group(struct group* result, char* buf, size_t buflen, int *errnop, struct g result->gr_mem[member_count] = buf; CHK(format_buf(&buf, &buflen, "%d", uid_iter->uid) == 1, "Unable to write a group member.", out_error_errno); + member_count++; } return 0; @@ -355,14 +355,13 @@ out_error_errno: enum nss_status _nss_rainbow_getgrent_r(struct group *result, char *buf, size_t buflen, int *errnop) { + if (!g_gids_cnt) + return NSS_STATUS_UNAVAIL; CHK(fill_group(result, buf, buflen, errnop, g_gid) == 1, "Unable to fill in group struct.", out_error_errno); - - if (&(g_gid->list.next) == &g_gids.list) - return NSS_STATUS_UNAVAIL; - - g_gid = list_entry(&(g_gid->list.next), struct gid_list, list); + g_gid = list_entry(g_gid->list.next, struct gid_list, list); + --g_gids_cnt; return NSS_STATUS_SUCCESS; -- cgit v0.9.1