X-Git-Url: https://ruderich.org/simon/gitweb/?a=blobdiff_plain;f=nss%2Fgr.c;h=e0e8873df9e6cbdf24bab735e261d0d2fa46b322;hb=1002c514a8530bb6608c556b4446e853be390917;hp=fbfd02fed3bdcdafcf1526e08d41de673a636a07;hpb=8d862d90f3530d340ef2b3f50973a8abcf9edf99;p=nsscash%2Fnsscash.git diff --git a/nss/gr.c b/nss/gr.c index fbfd02f..e0e8873 100644 --- a/nss/gr.c +++ b/nss/gr.c @@ -1,7 +1,7 @@ /* * Handle group entries via struct group * - * Copyright (C) 2019 Simon Ruderich + * Copyright (C) 2019-2020 Simon Ruderich * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License as published by @@ -32,10 +32,12 @@ // NOTE: This file is very similar to pw.c, keep in sync! +// TODO: adapt offsets to 32 bit to fit more than 5000 users per group (for 9 +// byte user names) struct group_entry { uint64_t gid; - // off_name = 0 + // off_name = 0, not stored on disk uint16_t off_passwd; uint16_t off_mem_off; @@ -51,11 +53,12 @@ struct group_entry { * * All offsets are relative to the beginning of data. */ - uint16_t data_size; - char data[]; + uint16_t data_size; // size of data in bytes + const char data[]; } __attribute__((packed)); static bool entry_to_group(const struct group_entry *e, struct group *g, char *tmp, size_t space) { + // Space required for the gr_mem array const size_t mem_size = (size_t)(e->mem_count + 1) * sizeof(char *); if (space < e->data_size + mem_size) { @@ -88,24 +91,23 @@ static struct file static_file = { }; static pthread_mutex_t static_file_lock = PTHREAD_MUTEX_INITIALIZER; -enum nss_status _nss_cash_setgrent(int x) { - (void)x; - +static void internal_unmap_static_file(void) { pthread_mutex_lock(&static_file_lock); - // Unmap is necessary to detect changes when the file was replaced on - // disk unmap_file(&static_file); - // getgrent_r will open the file if necessary when called pthread_mutex_unlock(&static_file_lock); +} +enum nss_status _nss_cash_setgrent(int x) { + (void)x; + + // Unmap is necessary to detect changes when the file was replaced on + // disk; getgrent_r will open the file if necessary when called + internal_unmap_static_file(); return NSS_STATUS_SUCCESS; } enum nss_status _nss_cash_endgrent(void) { - pthread_mutex_lock(&static_file_lock); - unmap_file(&static_file); - pthread_mutex_unlock(&static_file_lock); - + internal_unmap_static_file(); return NSS_STATUS_SUCCESS; } @@ -154,9 +156,9 @@ static enum nss_status internal_getgr(struct search_key *key, struct group *resu const struct header *h = f.header; key->data = h->data + h->off_data; - uint64_t off_index = (key->id != NULL) - ? h->off_id_index - : h->off_name_index; + uint64_t off_index = (key->name != NULL) + ? h->off_name_index + : h->off_id_index; uint64_t *off = search(key, h->data + off_index, h->count); if (off == NULL) { unmap_file(&f); @@ -165,7 +167,7 @@ static enum nss_status internal_getgr(struct search_key *key, struct group *resu return NSS_STATUS_NOTFOUND; } - const char *e = h->data + h->off_data + *off; + const char *e = key->data + *off; if (!entry_to_group((struct group_entry *)e, result, buffer, buflen)) { unmap_file(&f); errno = ERANGE; @@ -178,9 +180,8 @@ static enum nss_status internal_getgr(struct search_key *key, struct group *resu } enum nss_status _nss_cash_getgrgid_r(gid_t gid, struct group *result, char *buffer, size_t buflen, int *errnop) { - uint64_t id = (uint64_t)gid; struct search_key key = { - .id = &id, + .id = (uint64_t)gid, .offset = offsetof(struct group_entry, gid), }; return internal_getgr(&key, result, buffer, buflen, errnop);