Web   ·   Wiki   ·   Activities   ·   Blog   ·   Lists   ·   Chat   ·   Meeting   ·   Bugs   ·   Git   ·   Translate   ·   Archive   ·   People   ·   Donate
summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMichael Stone <michael@laptop.org>2008-07-08 06:21:04 (GMT)
committer Michael Stone <michael@laptop.org>2008-07-08 06:25:36 (GMT)
commit54bd6accb06fdb5227e3ec789d7fcc44dc85c458 (patch)
treebc868d0e3ea8d788f3070e76486f112f214b6778
parent44f53e59ce5e1cd76c65d38b8a7a026628a4c109 (diff)
A small victory.
-rw-r--r--nss-rainbow.c55
1 files changed, 27 insertions, 28 deletions
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;