/*
* Handle group entries via struct group
*
- * Copyright (C) 2019 Simon Ruderich
+ * Copyright (C) 2019-2021 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
#include <pthread.h>
-#include "cash.h"
#include "cash_nss.h"
#include "file.h"
#include "search.h"
// 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;
*
* 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) {
};
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;
}
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);
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;
}
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);