X-Git-Url: https://ruderich.org/simon/gitweb/?a=blobdiff_plain;f=nss%2Fpw.c;h=fc2128e9ea3145fbe5725eb9462f85627cf23408;hb=1002c514a8530bb6608c556b4446e853be390917;hp=d2c1bfa4acd793b12e5cbdf084de22ddefe6ed33;hpb=4e4725f0f28f60af004efb6e481008715ef5a673;p=nsscash%2Fnsscash.git diff --git a/nss/pw.c b/nss/pw.c index d2c1bfa..fc2128e 100644 --- a/nss/pw.c +++ b/nss/pw.c @@ -1,7 +1,7 @@ /* * Handle passwd entries via struct passwd * - * 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 @@ -25,29 +25,30 @@ #include -#include "cash.h" #include "cash_nss.h" #include "file.h" #include "search.h" +// NOTE: This file is very similar to gr.c, keep in sync! + struct passwd_entry { uint64_t uid; uint64_t gid; - // off_name = 0 + // off_name = 0, not stored on disk uint16_t off_passwd; uint16_t off_gecos; uint16_t off_dir; uint16_t off_shell; - uint16_t data_size; /* * Data contains all strings (name, passwd, gecos, dir, shell) * concatenated, with their trailing NUL. The off_* variables point to * beginning of each string. */ - char data[]; + uint16_t data_size; // size of data in bytes + const char data[]; } __attribute__((packed)); static bool entry_to_passwd(const struct passwd_entry *e, struct passwd *p, char *tmp, size_t space) { @@ -73,24 +74,23 @@ static struct file static_file = { }; static pthread_mutex_t static_file_lock = PTHREAD_MUTEX_INITIALIZER; -enum nss_status _nss_cash_setpwent(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); - // getpwent_r will open the file if necessary when called pthread_mutex_unlock(&static_file_lock); +} + +enum nss_status _nss_cash_setpwent(int x) { + (void)x; + // Unmap is necessary to detect changes when the file was replaced on + // disk; getpwent_r will open the file if necessary when called + internal_unmap_static_file(); return NSS_STATUS_SUCCESS; } enum nss_status _nss_cash_endpwent(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; } @@ -139,9 +139,9 @@ static enum nss_status internal_getpw(struct search_key *key, struct passwd *res 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); @@ -150,7 +150,7 @@ static enum nss_status internal_getpw(struct search_key *key, struct passwd *res return NSS_STATUS_NOTFOUND; } - const char *e = h->data + h->off_data + *off; + const char *e = key->data + *off; if (!entry_to_passwd((struct passwd_entry *)e, result, buffer, buflen)) { unmap_file(&f); errno = ERANGE; @@ -163,9 +163,8 @@ static enum nss_status internal_getpw(struct search_key *key, struct passwd *res } enum nss_status _nss_cash_getpwuid_r(uid_t uid, struct passwd *result, char *buffer, size_t buflen, int *errnop) { - uint64_t id = (uint64_t)uid; struct search_key key = { - .id = &id, + .id = (uint64_t)uid, .offset = offsetof(struct passwd_entry, uid), }; return internal_getpw(&key, result, buffer, buflen, errnop);