diff options
author | Michael Stone <michael@laptop.org> | 2008-07-07 20:41:44 (GMT) |
---|---|---|
committer | Michael Stone <michael@laptop.org> | 2008-07-07 20:41:44 (GMT) |
commit | 44f53e59ce5e1cd76c65d38b8a7a026628a4c109 (patch) | |
tree | 1c1f0f2bbe533de1a2083c83b063de2fc9a5b986 | |
parent | fee6e881bdb88329e2b578af4574afe796af595f (diff) |
Grr.
-rw-r--r-- | buf.c | 2 | ||||
-rw-r--r-- | cgen.h | 2 | ||||
-rw-r--r-- | gids.c | 19 | ||||
-rw-r--r-- | nat.c | 1 | ||||
-rw-r--r-- | nss-rainbow.c | 56 | ||||
-rw-r--r-- | test_nat.c | 1 |
6 files changed, 48 insertions, 33 deletions
@@ -1,10 +1,10 @@ +#define _GNU_SOURCE #include <errno.h> #include <stdio.h> #include <syslog.h> #include <string.h> #include <stdarg.h> - #include "cgen.h" #include "buf.h" @@ -3,5 +3,5 @@ #define __XSTRING(X) __STRING(X) #define PERROR(msg) {int __errno_cache = errno; dprintf(2, "%s|%d| %s: %s\nError %d: %s\n", __FILE__, __LINE__, __func__, msg, __errno_cache, strerror(__errno_cache));} #define CHK(EXPR, MSG, ERR_LABEL) {if(EXPR) { PERROR(MSG); goto ERR_LABEL;}} -#define LET(LETEXPR, CONDEXPR, MSG, ERR_LABEL) {LETEXPR; if (CONDEXPR) { PERROR(MSG); goto ERR_LABEL;}} +#define LET(LETEXPR, CONDEXPR, MSG, ERR_LABEL) LETEXPR; if (CONDEXPR) { PERROR(MSG); goto ERR_LABEL;} #define TST(EXPR, ERRNO, MSG, ERR_LABEL) {if (EXPR) {errno = ERRNO; PERROR(MSG); goto ERR_LABEL;}} @@ -1,28 +1,31 @@ #define _GNU_SOURCE -#include <pwd.h> +#include <grp.h> #include <stdio.h> +#include <string.h> #define BUFLEN 4096 int main() { - struct passwd pw, *pwp; + struct group gr, *grp; char buf[BUFLEN]; int i, cnt; cnt = 0; - setpwent(); + setgrent(); while (1) { - i = getpwent_r(&pw, buf, BUFLEN, &pwp); + printf("\n\n"); + i = getgrent_r(&gr, buf, BUFLEN, &grp); if (i) { printf("status: %d\n", i); break; } - printf("%d: %s (%d)\tHOME %s\tSHELL %s\n", cnt, - pwp->pw_name, pwp->pw_uid, - pwp->pw_dir, pwp->pw_shell); + printf("\n%d: %s (%d)\n", cnt, grp->gr_name, grp->gr_gid); + int num_members = strlen((char*)grp->gr_mem) / sizeof(char*); + for (i = 0; i < num_members; i++) + printf("%s ", grp->gr_mem[i]); cnt++; } - endpwent(); + endgrent(); return 0; } @@ -1,3 +1,4 @@ +#define _GNU_SOURCE #include <errno.h> #include <stdio.h> #include <syslog.h> diff --git a/nss-rainbow.c b/nss-rainbow.c index fb3ceae..cb4273f 100644 --- a/nss-rainbow.c +++ b/nss-rainbow.c @@ -202,7 +202,7 @@ out_error_errno: struct uid_list { struct list_head list; uid_t uid; -}; +}; struct gid_list { struct list_head list; @@ -230,7 +230,7 @@ uid_to_gid_filter(const struct dirent* d) { "Unable to parse uid.", exit); CHK(uid < 10000 || uid > 60000, "uid not in valid range.", exit); - + CHK(format_buf(&gid_path_str, &gid_path_len, SPOOL "/uid_to_gid/%d", uid) == 1, "Unable to calculate uid-to-gid-path.", exit); LET(gid_name_len = readlink(gid_path, gid_name, gid_name_len), gid_name_len == -1, @@ -240,28 +240,37 @@ uid_to_gid_filter(const struct dirent* d) { CHK(gid < 10000 || gid > 60000, "gid not in valid range.", exit); - /* We might have already allocated a uid_list for our gid. + /* We might have already allocated a uid_list for our gid. * Therefore, search for it. */ struct gid_list* gid_iter = NULL; - list_for_each_entry(gid_iter, &g_gids.list, list) { - if (gid_iter->gid == gid) - break; + 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)); } + 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); - 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); + } } - /* gid_iter now points to the appropriate gid_list node. + /* gid_iter now points to the appropriate gid_list node. * There's no way that we could already have our current (uid, gid) row. * Therefore, we'll immediately insert it. */ struct uid_list* uid_iter; LET(uid_iter = malloc(sizeof(struct uid_list)), !uid_iter, "Unable to allocate new uid_list node.", exit); + uid_iter->uid = uid; list_add_tail(&(uid_iter->list), &(gid_iter->uids.list)); exit: return 0; @@ -304,14 +313,14 @@ struct group }; */ -int +int fill_group(struct group* result, char* buf, size_t buflen, int *errnop, struct gid_list* gid_iter) { result->gr_gid = gid_iter->gid; result->gr_name = result->gr_passwd = buf; TST(format_buf(&buf, &buflen, "%d", gid_iter->gid) == 1, ENOMEM, "Unable to calculate group name.", out_error_errno); - + /* count the number of members */ struct uid_list* uid_iter; struct list_head* uid_node_iter; @@ -321,11 +330,11 @@ 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 * sizeof(char*) + 1; + size_t member_size = (member_count+1)* sizeof(char*); result->gr_mem = buf; TST(buflen > member_size, EINVAL, "Not enough space for group member pointers.", out_error_errno); - buf[member_size-1] = 0; + result->gr_mem[member_count-1] = 0; buf = buf + member_size; buflen -= member_size; @@ -338,7 +347,7 @@ fill_group(struct group* result, char* buf, size_t buflen, int *errnop, struct g } return 0; - + out_error_errno: *errnop = errno; return 1; @@ -346,14 +355,15 @@ out_error_errno: enum nss_status _nss_rainbow_getgrent_r(struct group *result, char *buf, size_t buflen, int *errnop) { - if (&(g_gid->list.next) == &g_gids.list) - 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); - + return NSS_STATUS_SUCCESS; out_error_errno: @@ -366,7 +376,7 @@ enum nss_status _nss_rainbow_getgrgid_r(gid_t gid, struct group *result, char *buf, size_t buflen, int *errnop) { if (gid < 10000 || gid > 60000) return NSS_STATUS_NOTFOUND; - + /* look up group data */ struct gid_list* gid_iter; list_for_each_entry(gid_iter, &g_gids.list, list) { @@ -1,3 +1,4 @@ +#define _GNU_SOURCE #include <errno.h> #include <stdio.h> #include <syslog.h> |