nsssrv_mmap_cache.c revision 8b7040df8bcfee8cb31903136562eea73232f3d0
eb2e21b764d03544d8161e9956d7f70b07b75f77Simo Sorce/*
eb2e21b764d03544d8161e9956d7f70b07b75f77Simo Sorce SSSD
eb2e21b764d03544d8161e9956d7f70b07b75f77Simo Sorce
eb2e21b764d03544d8161e9956d7f70b07b75f77Simo Sorce NSS Responder - Mmap Cache
eb2e21b764d03544d8161e9956d7f70b07b75f77Simo Sorce
eb2e21b764d03544d8161e9956d7f70b07b75f77Simo Sorce Copyright (C) Simo Sorce <ssorce@redhat.com> 2011
eb2e21b764d03544d8161e9956d7f70b07b75f77Simo Sorce
eb2e21b764d03544d8161e9956d7f70b07b75f77Simo Sorce This program is free software; you can redistribute it and/or modify
eb2e21b764d03544d8161e9956d7f70b07b75f77Simo Sorce it under the terms of the GNU General Public License as published by
eb2e21b764d03544d8161e9956d7f70b07b75f77Simo Sorce the Free Software Foundation; either version 3 of the License, or
eb2e21b764d03544d8161e9956d7f70b07b75f77Simo Sorce (at your option) any later version.
eb2e21b764d03544d8161e9956d7f70b07b75f77Simo Sorce
eb2e21b764d03544d8161e9956d7f70b07b75f77Simo Sorce This program is distributed in the hope that it will be useful,
eb2e21b764d03544d8161e9956d7f70b07b75f77Simo Sorce but WITHOUT ANY WARRANTY; without even the implied warranty of
eb2e21b764d03544d8161e9956d7f70b07b75f77Simo Sorce MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
eb2e21b764d03544d8161e9956d7f70b07b75f77Simo Sorce GNU General Public License for more details.
eb2e21b764d03544d8161e9956d7f70b07b75f77Simo Sorce
eb2e21b764d03544d8161e9956d7f70b07b75f77Simo Sorce You should have received a copy of the GNU General Public License
eb2e21b764d03544d8161e9956d7f70b07b75f77Simo Sorce along with this program. If not, see <http://www.gnu.org/licenses/>.
eb2e21b764d03544d8161e9956d7f70b07b75f77Simo Sorce*/
eb2e21b764d03544d8161e9956d7f70b07b75f77Simo Sorce
eb2e21b764d03544d8161e9956d7f70b07b75f77Simo Sorce#include "util/util.h"
eb2e21b764d03544d8161e9956d7f70b07b75f77Simo Sorce#include "confdb/confdb.h"
eb2e21b764d03544d8161e9956d7f70b07b75f77Simo Sorce#include <sys/mman.h>
eb2e21b764d03544d8161e9956d7f70b07b75f77Simo Sorce#include <fcntl.h>
eb2e21b764d03544d8161e9956d7f70b07b75f77Simo Sorce#include "util/mmap_cache.h"
eb2e21b764d03544d8161e9956d7f70b07b75f77Simo Sorce#include "responder/nss/nsssrv.h"
eb2e21b764d03544d8161e9956d7f70b07b75f77Simo Sorce#include "responder/nss/nsssrv_mmap_cache.h"
eb2e21b764d03544d8161e9956d7f70b07b75f77Simo Sorce
eb2e21b764d03544d8161e9956d7f70b07b75f77Simo Sorce/* arbitrary (avg of my /etc/passwd) */
eb2e21b764d03544d8161e9956d7f70b07b75f77Simo Sorce#define SSS_AVG_PASSWD_PAYLOAD (MC_SLOT_SIZE * 4)
eb2e21b764d03544d8161e9956d7f70b07b75f77Simo Sorce/* short group name and no gids (private user group */
eb2e21b764d03544d8161e9956d7f70b07b75f77Simo Sorce#define SSS_AVG_GROUP_PAYLOAD (MC_SLOT_SIZE * 3)
eb2e21b764d03544d8161e9956d7f70b07b75f77Simo Sorce
eb2e21b764d03544d8161e9956d7f70b07b75f77Simo Sorce#define MC_NEXT_BARRIER(val) ((((val) + 1) & 0x00ffffff) | 0xf0000000)
eb2e21b764d03544d8161e9956d7f70b07b75f77Simo Sorce
eb2e21b764d03544d8161e9956d7f70b07b75f77Simo Sorce#define MC_RAISE_BARRIER(m) do { \
eb2e21b764d03544d8161e9956d7f70b07b75f77Simo Sorce m->b2 = MC_NEXT_BARRIER(m->b1); \
eb2e21b764d03544d8161e9956d7f70b07b75f77Simo Sorce __sync_synchronize(); \
eb2e21b764d03544d8161e9956d7f70b07b75f77Simo Sorce} while (0)
eb2e21b764d03544d8161e9956d7f70b07b75f77Simo Sorce
eb2e21b764d03544d8161e9956d7f70b07b75f77Simo Sorce#define MC_LOWER_BARRIER(m) do { \
eb2e21b764d03544d8161e9956d7f70b07b75f77Simo Sorce __sync_synchronize(); \
eb2e21b764d03544d8161e9956d7f70b07b75f77Simo Sorce m->b1 = m->b2; \
eb2e21b764d03544d8161e9956d7f70b07b75f77Simo Sorce} while (0)
eb2e21b764d03544d8161e9956d7f70b07b75f77Simo Sorce
24451a6231ea0b7fd0e98a9931e8254aa17bf4cfSimo Sorce#define MC_RAISE_INVALID_BARRIER(m) do { \
24451a6231ea0b7fd0e98a9931e8254aa17bf4cfSimo Sorce m->b2 = MC_INVALID_VAL; \
24451a6231ea0b7fd0e98a9931e8254aa17bf4cfSimo Sorce __sync_synchronize(); \
24451a6231ea0b7fd0e98a9931e8254aa17bf4cfSimo Sorce} while (0)
24451a6231ea0b7fd0e98a9931e8254aa17bf4cfSimo Sorce
eb2e21b764d03544d8161e9956d7f70b07b75f77Simo Sorcestruct sss_mc_ctx {
eb2e21b764d03544d8161e9956d7f70b07b75f77Simo Sorce char *name; /* mmap cache name */
eb2e21b764d03544d8161e9956d7f70b07b75f77Simo Sorce enum sss_mc_type type; /* mmap cache type */
eb2e21b764d03544d8161e9956d7f70b07b75f77Simo Sorce char *file; /* mmap cache file name */
eb2e21b764d03544d8161e9956d7f70b07b75f77Simo Sorce int fd; /* file descriptor */
eb2e21b764d03544d8161e9956d7f70b07b75f77Simo Sorce
eb2e21b764d03544d8161e9956d7f70b07b75f77Simo Sorce uint32_t seed; /* pseudo-random seed to avoid collision attacks */
eb2e21b764d03544d8161e9956d7f70b07b75f77Simo Sorce time_t valid_time_slot; /* maximum time the entry is valid in seconds */
eb2e21b764d03544d8161e9956d7f70b07b75f77Simo Sorce
eb2e21b764d03544d8161e9956d7f70b07b75f77Simo Sorce void *mmap_base; /* base address of mmap */
eb2e21b764d03544d8161e9956d7f70b07b75f77Simo Sorce size_t mmap_size; /* total size of mmap */
eb2e21b764d03544d8161e9956d7f70b07b75f77Simo Sorce
eb2e21b764d03544d8161e9956d7f70b07b75f77Simo Sorce uint32_t *hash_table; /* hash table address (in mmap) */
eb2e21b764d03544d8161e9956d7f70b07b75f77Simo Sorce uint32_t ht_size; /* size of hash table */
eb2e21b764d03544d8161e9956d7f70b07b75f77Simo Sorce
eb2e21b764d03544d8161e9956d7f70b07b75f77Simo Sorce uint8_t *free_table; /* free list bitmaps */
eb2e21b764d03544d8161e9956d7f70b07b75f77Simo Sorce uint32_t ft_size; /* size of free table */
eb2e21b764d03544d8161e9956d7f70b07b75f77Simo Sorce uint32_t next_slot; /* the next slot after last allocation */
eb2e21b764d03544d8161e9956d7f70b07b75f77Simo Sorce
eb2e21b764d03544d8161e9956d7f70b07b75f77Simo Sorce uint8_t *data_table; /* data table address (in mmap) */
eb2e21b764d03544d8161e9956d7f70b07b75f77Simo Sorce uint32_t dt_size; /* size of data table */
eb2e21b764d03544d8161e9956d7f70b07b75f77Simo Sorce};
eb2e21b764d03544d8161e9956d7f70b07b75f77Simo Sorce
24451a6231ea0b7fd0e98a9931e8254aa17bf4cfSimo Sorce#define MC_FIND_BIT(base, num) \
24451a6231ea0b7fd0e98a9931e8254aa17bf4cfSimo Sorce uint32_t n = (num); \
24451a6231ea0b7fd0e98a9931e8254aa17bf4cfSimo Sorce uint8_t *b = (base) + n / 8; \
24451a6231ea0b7fd0e98a9931e8254aa17bf4cfSimo Sorce uint8_t c = 0x80 >> (n % 8);
24451a6231ea0b7fd0e98a9931e8254aa17bf4cfSimo Sorce
24451a6231ea0b7fd0e98a9931e8254aa17bf4cfSimo Sorce#define MC_SET_BIT(base, num) do { \
24451a6231ea0b7fd0e98a9931e8254aa17bf4cfSimo Sorce MC_FIND_BIT(base, num) \
24451a6231ea0b7fd0e98a9931e8254aa17bf4cfSimo Sorce *b |= c; \
24451a6231ea0b7fd0e98a9931e8254aa17bf4cfSimo Sorce} while (0)
24451a6231ea0b7fd0e98a9931e8254aa17bf4cfSimo Sorce
24451a6231ea0b7fd0e98a9931e8254aa17bf4cfSimo Sorce#define MC_CLEAR_BIT(base, num) do { \
24451a6231ea0b7fd0e98a9931e8254aa17bf4cfSimo Sorce MC_FIND_BIT(base, num) \
24451a6231ea0b7fd0e98a9931e8254aa17bf4cfSimo Sorce *b &= ~c; \
24451a6231ea0b7fd0e98a9931e8254aa17bf4cfSimo Sorce} while (0)
24451a6231ea0b7fd0e98a9931e8254aa17bf4cfSimo Sorce
24451a6231ea0b7fd0e98a9931e8254aa17bf4cfSimo Sorce#define MC_PROBE_BIT(base, num, used) do { \
24451a6231ea0b7fd0e98a9931e8254aa17bf4cfSimo Sorce MC_FIND_BIT(base, num) \
24451a6231ea0b7fd0e98a9931e8254aa17bf4cfSimo Sorce if (*b & c) used = true; \
24451a6231ea0b7fd0e98a9931e8254aa17bf4cfSimo Sorce else used = false; \
24451a6231ea0b7fd0e98a9931e8254aa17bf4cfSimo Sorce} while (0)
24451a6231ea0b7fd0e98a9931e8254aa17bf4cfSimo Sorce
24451a6231ea0b7fd0e98a9931e8254aa17bf4cfSimo Sorcestatic uint32_t sss_mc_hash(struct sss_mc_ctx *mcc,
24451a6231ea0b7fd0e98a9931e8254aa17bf4cfSimo Sorce const char *key, size_t len)
24451a6231ea0b7fd0e98a9931e8254aa17bf4cfSimo Sorce{
24451a6231ea0b7fd0e98a9931e8254aa17bf4cfSimo Sorce return murmurhash3(key, len, mcc->seed) % MC_HT_ELEMS(mcc->ht_size);
24451a6231ea0b7fd0e98a9931e8254aa17bf4cfSimo Sorce}
24451a6231ea0b7fd0e98a9931e8254aa17bf4cfSimo Sorce
24451a6231ea0b7fd0e98a9931e8254aa17bf4cfSimo Sorcestatic void sss_mc_add_rec_to_chain(struct sss_mc_ctx *mcc,
24451a6231ea0b7fd0e98a9931e8254aa17bf4cfSimo Sorce struct sss_mc_rec *rec,
24451a6231ea0b7fd0e98a9931e8254aa17bf4cfSimo Sorce uint32_t hash)
24451a6231ea0b7fd0e98a9931e8254aa17bf4cfSimo Sorce{
24451a6231ea0b7fd0e98a9931e8254aa17bf4cfSimo Sorce struct sss_mc_rec *cur;
24451a6231ea0b7fd0e98a9931e8254aa17bf4cfSimo Sorce uint32_t slot;
24451a6231ea0b7fd0e98a9931e8254aa17bf4cfSimo Sorce
24451a6231ea0b7fd0e98a9931e8254aa17bf4cfSimo Sorce slot = mcc->hash_table[hash];
24451a6231ea0b7fd0e98a9931e8254aa17bf4cfSimo Sorce if (slot == MC_INVALID_VAL) {
24451a6231ea0b7fd0e98a9931e8254aa17bf4cfSimo Sorce /* no previous record/collision, just add to hash table */
24451a6231ea0b7fd0e98a9931e8254aa17bf4cfSimo Sorce mcc->hash_table[hash] = MC_PTR_TO_SLOT(mcc->data_table, rec);
24451a6231ea0b7fd0e98a9931e8254aa17bf4cfSimo Sorce return;
24451a6231ea0b7fd0e98a9931e8254aa17bf4cfSimo Sorce }
24451a6231ea0b7fd0e98a9931e8254aa17bf4cfSimo Sorce
24451a6231ea0b7fd0e98a9931e8254aa17bf4cfSimo Sorce do {
24451a6231ea0b7fd0e98a9931e8254aa17bf4cfSimo Sorce cur = MC_SLOT_TO_PTR(mcc->data_table, slot, struct sss_mc_rec);
24451a6231ea0b7fd0e98a9931e8254aa17bf4cfSimo Sorce if (cur == rec) {
24451a6231ea0b7fd0e98a9931e8254aa17bf4cfSimo Sorce /* rec already stored in hash chain */
24451a6231ea0b7fd0e98a9931e8254aa17bf4cfSimo Sorce return;
24451a6231ea0b7fd0e98a9931e8254aa17bf4cfSimo Sorce }
24451a6231ea0b7fd0e98a9931e8254aa17bf4cfSimo Sorce slot = cur->next;
24451a6231ea0b7fd0e98a9931e8254aa17bf4cfSimo Sorce } while (slot != MC_INVALID_VAL);
24451a6231ea0b7fd0e98a9931e8254aa17bf4cfSimo Sorce /* end of chain, append our record here */
24451a6231ea0b7fd0e98a9931e8254aa17bf4cfSimo Sorce
24451a6231ea0b7fd0e98a9931e8254aa17bf4cfSimo Sorce /* changing a single uint32_t is atomic, so there is no
24451a6231ea0b7fd0e98a9931e8254aa17bf4cfSimo Sorce * need to use barriers in this case */
24451a6231ea0b7fd0e98a9931e8254aa17bf4cfSimo Sorce cur->next = MC_PTR_TO_SLOT(mcc->data_table, rec);
24451a6231ea0b7fd0e98a9931e8254aa17bf4cfSimo Sorce}
24451a6231ea0b7fd0e98a9931e8254aa17bf4cfSimo Sorce
24451a6231ea0b7fd0e98a9931e8254aa17bf4cfSimo Sorcestatic void sss_mc_rm_rec_from_chain(struct sss_mc_ctx *mcc,
24451a6231ea0b7fd0e98a9931e8254aa17bf4cfSimo Sorce struct sss_mc_rec *rec,
24451a6231ea0b7fd0e98a9931e8254aa17bf4cfSimo Sorce uint32_t hash)
24451a6231ea0b7fd0e98a9931e8254aa17bf4cfSimo Sorce{
24451a6231ea0b7fd0e98a9931e8254aa17bf4cfSimo Sorce struct sss_mc_rec *prev = NULL;
24451a6231ea0b7fd0e98a9931e8254aa17bf4cfSimo Sorce struct sss_mc_rec *cur = NULL;
24451a6231ea0b7fd0e98a9931e8254aa17bf4cfSimo Sorce uint32_t slot;
24451a6231ea0b7fd0e98a9931e8254aa17bf4cfSimo Sorce
24451a6231ea0b7fd0e98a9931e8254aa17bf4cfSimo Sorce slot = mcc->hash_table[hash];
24451a6231ea0b7fd0e98a9931e8254aa17bf4cfSimo Sorce cur = MC_SLOT_TO_PTR(mcc->data_table, slot, struct sss_mc_rec);
24451a6231ea0b7fd0e98a9931e8254aa17bf4cfSimo Sorce if (cur == rec) {
24451a6231ea0b7fd0e98a9931e8254aa17bf4cfSimo Sorce mcc->hash_table[hash] = rec->next;
24451a6231ea0b7fd0e98a9931e8254aa17bf4cfSimo Sorce } else {
24451a6231ea0b7fd0e98a9931e8254aa17bf4cfSimo Sorce slot = cur->next;
24451a6231ea0b7fd0e98a9931e8254aa17bf4cfSimo Sorce while (slot != MC_INVALID_VAL) {
24451a6231ea0b7fd0e98a9931e8254aa17bf4cfSimo Sorce prev = cur;
24451a6231ea0b7fd0e98a9931e8254aa17bf4cfSimo Sorce cur = MC_SLOT_TO_PTR(mcc->data_table, slot, struct sss_mc_rec);
24451a6231ea0b7fd0e98a9931e8254aa17bf4cfSimo Sorce if (cur == rec) {
24451a6231ea0b7fd0e98a9931e8254aa17bf4cfSimo Sorce /* changing a single uint32_t is atomic, so there is no
24451a6231ea0b7fd0e98a9931e8254aa17bf4cfSimo Sorce * need to use barriers in this case */
24451a6231ea0b7fd0e98a9931e8254aa17bf4cfSimo Sorce prev->next = cur->next;
24451a6231ea0b7fd0e98a9931e8254aa17bf4cfSimo Sorce slot = MC_INVALID_VAL;
24451a6231ea0b7fd0e98a9931e8254aa17bf4cfSimo Sorce } else {
24451a6231ea0b7fd0e98a9931e8254aa17bf4cfSimo Sorce slot = cur->next;
24451a6231ea0b7fd0e98a9931e8254aa17bf4cfSimo Sorce }
24451a6231ea0b7fd0e98a9931e8254aa17bf4cfSimo Sorce }
24451a6231ea0b7fd0e98a9931e8254aa17bf4cfSimo Sorce }
24451a6231ea0b7fd0e98a9931e8254aa17bf4cfSimo Sorce}
24451a6231ea0b7fd0e98a9931e8254aa17bf4cfSimo Sorce
24451a6231ea0b7fd0e98a9931e8254aa17bf4cfSimo Sorcestatic void sss_mc_invalidate_rec(struct sss_mc_ctx *mcc,
24451a6231ea0b7fd0e98a9931e8254aa17bf4cfSimo Sorce struct sss_mc_rec *rec)
24451a6231ea0b7fd0e98a9931e8254aa17bf4cfSimo Sorce{
24451a6231ea0b7fd0e98a9931e8254aa17bf4cfSimo Sorce if (rec->b1 == MC_INVALID_VAL) {
24451a6231ea0b7fd0e98a9931e8254aa17bf4cfSimo Sorce /* record already invalid */
24451a6231ea0b7fd0e98a9931e8254aa17bf4cfSimo Sorce return;
24451a6231ea0b7fd0e98a9931e8254aa17bf4cfSimo Sorce }
24451a6231ea0b7fd0e98a9931e8254aa17bf4cfSimo Sorce
24451a6231ea0b7fd0e98a9931e8254aa17bf4cfSimo Sorce /* hash chain 1 */
24451a6231ea0b7fd0e98a9931e8254aa17bf4cfSimo Sorce sss_mc_rm_rec_from_chain(mcc, rec, rec->hash1);
24451a6231ea0b7fd0e98a9931e8254aa17bf4cfSimo Sorce /* hash chain 2 */
24451a6231ea0b7fd0e98a9931e8254aa17bf4cfSimo Sorce sss_mc_rm_rec_from_chain(mcc, rec, rec->hash2);
24451a6231ea0b7fd0e98a9931e8254aa17bf4cfSimo Sorce
24451a6231ea0b7fd0e98a9931e8254aa17bf4cfSimo Sorce MC_RAISE_INVALID_BARRIER(rec);
24451a6231ea0b7fd0e98a9931e8254aa17bf4cfSimo Sorce memset(rec->data, 'X', rec->len - sizeof(struct sss_mc_rec));
24451a6231ea0b7fd0e98a9931e8254aa17bf4cfSimo Sorce rec->len = MC_INVALID_VAL;
24451a6231ea0b7fd0e98a9931e8254aa17bf4cfSimo Sorce rec->expire = (uint64_t)-1;
24451a6231ea0b7fd0e98a9931e8254aa17bf4cfSimo Sorce rec->next = MC_INVALID_VAL;
24451a6231ea0b7fd0e98a9931e8254aa17bf4cfSimo Sorce rec->hash1 = MC_INVALID_VAL;
24451a6231ea0b7fd0e98a9931e8254aa17bf4cfSimo Sorce rec->hash2 = MC_INVALID_VAL;
24451a6231ea0b7fd0e98a9931e8254aa17bf4cfSimo Sorce MC_LOWER_BARRIER(rec);
24451a6231ea0b7fd0e98a9931e8254aa17bf4cfSimo Sorce}
24451a6231ea0b7fd0e98a9931e8254aa17bf4cfSimo Sorce
24451a6231ea0b7fd0e98a9931e8254aa17bf4cfSimo Sorce/* FIXME: This is a very simplistic, inefficient, memory allocator,
24451a6231ea0b7fd0e98a9931e8254aa17bf4cfSimo Sorce * it will just free the oldest entries regardless of expiration if it
24451a6231ea0b7fd0e98a9931e8254aa17bf4cfSimo Sorce * cycled the whole freebits map and found no empty slot */
24451a6231ea0b7fd0e98a9931e8254aa17bf4cfSimo Sorcestatic int sss_mc_find_free_slots(struct sss_mc_ctx *mcc, int num_slots)
24451a6231ea0b7fd0e98a9931e8254aa17bf4cfSimo Sorce{
24451a6231ea0b7fd0e98a9931e8254aa17bf4cfSimo Sorce struct sss_mc_rec *rec;
24451a6231ea0b7fd0e98a9931e8254aa17bf4cfSimo Sorce uint32_t tot_slots;
24451a6231ea0b7fd0e98a9931e8254aa17bf4cfSimo Sorce uint32_t cur;
24451a6231ea0b7fd0e98a9931e8254aa17bf4cfSimo Sorce uint32_t i;
24451a6231ea0b7fd0e98a9931e8254aa17bf4cfSimo Sorce uint32_t t;
24451a6231ea0b7fd0e98a9931e8254aa17bf4cfSimo Sorce bool used;
24451a6231ea0b7fd0e98a9931e8254aa17bf4cfSimo Sorce
24451a6231ea0b7fd0e98a9931e8254aa17bf4cfSimo Sorce tot_slots = mcc->ft_size * 8;
24451a6231ea0b7fd0e98a9931e8254aa17bf4cfSimo Sorce
24451a6231ea0b7fd0e98a9931e8254aa17bf4cfSimo Sorce /* Try to find a free slot w/o removing a nything first */
24451a6231ea0b7fd0e98a9931e8254aa17bf4cfSimo Sorce /* FIXME: is it really worth it ? May be it is easier to
24451a6231ea0b7fd0e98a9931e8254aa17bf4cfSimo Sorce * just recycle the next set of slots ? */
24451a6231ea0b7fd0e98a9931e8254aa17bf4cfSimo Sorce if ((mcc->next_slot + num_slots) > tot_slots) {
24451a6231ea0b7fd0e98a9931e8254aa17bf4cfSimo Sorce cur = 0;
24451a6231ea0b7fd0e98a9931e8254aa17bf4cfSimo Sorce } else {
24451a6231ea0b7fd0e98a9931e8254aa17bf4cfSimo Sorce cur = mcc->next_slot;
24451a6231ea0b7fd0e98a9931e8254aa17bf4cfSimo Sorce }
24451a6231ea0b7fd0e98a9931e8254aa17bf4cfSimo Sorce
24451a6231ea0b7fd0e98a9931e8254aa17bf4cfSimo Sorce /* search for enough (num_slots) consecutive zero bits, indicating
24451a6231ea0b7fd0e98a9931e8254aa17bf4cfSimo Sorce * consecutive empty slots */
24451a6231ea0b7fd0e98a9931e8254aa17bf4cfSimo Sorce for (i = 0; i < mcc->ft_size; i++) {
24451a6231ea0b7fd0e98a9931e8254aa17bf4cfSimo Sorce t = cur / 8;
24451a6231ea0b7fd0e98a9931e8254aa17bf4cfSimo Sorce /* if all full in this byte skip directly to the next */
24451a6231ea0b7fd0e98a9931e8254aa17bf4cfSimo Sorce if (mcc->free_table[t] == 0xff) {
24451a6231ea0b7fd0e98a9931e8254aa17bf4cfSimo Sorce cur = ((cur + 8) & ~7);
24451a6231ea0b7fd0e98a9931e8254aa17bf4cfSimo Sorce if (cur >= tot_slots) {
24451a6231ea0b7fd0e98a9931e8254aa17bf4cfSimo Sorce cur = 0;
24451a6231ea0b7fd0e98a9931e8254aa17bf4cfSimo Sorce }
24451a6231ea0b7fd0e98a9931e8254aa17bf4cfSimo Sorce continue;
24451a6231ea0b7fd0e98a9931e8254aa17bf4cfSimo Sorce }
24451a6231ea0b7fd0e98a9931e8254aa17bf4cfSimo Sorce
24451a6231ea0b7fd0e98a9931e8254aa17bf4cfSimo Sorce /* at least one bit in this byte is marked as empty */
24451a6231ea0b7fd0e98a9931e8254aa17bf4cfSimo Sorce for (t = ((cur + 8) & ~7) ; cur < t; cur++) {
24451a6231ea0b7fd0e98a9931e8254aa17bf4cfSimo Sorce MC_PROBE_BIT(mcc->free_table, cur, used);
24451a6231ea0b7fd0e98a9931e8254aa17bf4cfSimo Sorce if (!used) break;
24451a6231ea0b7fd0e98a9931e8254aa17bf4cfSimo Sorce }
24451a6231ea0b7fd0e98a9931e8254aa17bf4cfSimo Sorce /* check if we have enough slots before hitting the table end */
24451a6231ea0b7fd0e98a9931e8254aa17bf4cfSimo Sorce if ((cur + num_slots) > tot_slots) {
24451a6231ea0b7fd0e98a9931e8254aa17bf4cfSimo Sorce cur = 0;
24451a6231ea0b7fd0e98a9931e8254aa17bf4cfSimo Sorce continue;
24451a6231ea0b7fd0e98a9931e8254aa17bf4cfSimo Sorce }
24451a6231ea0b7fd0e98a9931e8254aa17bf4cfSimo Sorce
24451a6231ea0b7fd0e98a9931e8254aa17bf4cfSimo Sorce /* check if we have at least num_slots empty starting from the first
24451a6231ea0b7fd0e98a9931e8254aa17bf4cfSimo Sorce * we found in the previous steps */
24451a6231ea0b7fd0e98a9931e8254aa17bf4cfSimo Sorce for (t = cur + num_slots; cur < t; cur++) {
24451a6231ea0b7fd0e98a9931e8254aa17bf4cfSimo Sorce MC_PROBE_BIT(mcc->free_table, cur, used);
24451a6231ea0b7fd0e98a9931e8254aa17bf4cfSimo Sorce if (used) break;
24451a6231ea0b7fd0e98a9931e8254aa17bf4cfSimo Sorce }
24451a6231ea0b7fd0e98a9931e8254aa17bf4cfSimo Sorce if (cur == t) {
24451a6231ea0b7fd0e98a9931e8254aa17bf4cfSimo Sorce /* ok found num_slots consecutive free bits */
24451a6231ea0b7fd0e98a9931e8254aa17bf4cfSimo Sorce return cur - num_slots;
24451a6231ea0b7fd0e98a9931e8254aa17bf4cfSimo Sorce }
24451a6231ea0b7fd0e98a9931e8254aa17bf4cfSimo Sorce }
24451a6231ea0b7fd0e98a9931e8254aa17bf4cfSimo Sorce
24451a6231ea0b7fd0e98a9931e8254aa17bf4cfSimo Sorce /* no free slots found, free occupied slots after next_slot */
24451a6231ea0b7fd0e98a9931e8254aa17bf4cfSimo Sorce if ((mcc->next_slot + num_slots) > tot_slots) {
24451a6231ea0b7fd0e98a9931e8254aa17bf4cfSimo Sorce cur = 0;
24451a6231ea0b7fd0e98a9931e8254aa17bf4cfSimo Sorce } else {
24451a6231ea0b7fd0e98a9931e8254aa17bf4cfSimo Sorce cur = mcc->next_slot;
24451a6231ea0b7fd0e98a9931e8254aa17bf4cfSimo Sorce }
24451a6231ea0b7fd0e98a9931e8254aa17bf4cfSimo Sorce for (i = 0; i < num_slots; i++) {
24451a6231ea0b7fd0e98a9931e8254aa17bf4cfSimo Sorce MC_PROBE_BIT(mcc->free_table, cur + i, used);
24451a6231ea0b7fd0e98a9931e8254aa17bf4cfSimo Sorce if (!used) continue;
24451a6231ea0b7fd0e98a9931e8254aa17bf4cfSimo Sorce
24451a6231ea0b7fd0e98a9931e8254aa17bf4cfSimo Sorce rec = MC_SLOT_TO_PTR(mcc->data_table, cur + i, struct sss_mc_rec);
24451a6231ea0b7fd0e98a9931e8254aa17bf4cfSimo Sorce for (t = i + MC_SIZE_TO_SLOTS(rec->len); i < t; i++) {
24451a6231ea0b7fd0e98a9931e8254aa17bf4cfSimo Sorce MC_CLEAR_BIT(mcc->free_table, cur + i);
24451a6231ea0b7fd0e98a9931e8254aa17bf4cfSimo Sorce }
24451a6231ea0b7fd0e98a9931e8254aa17bf4cfSimo Sorce sss_mc_invalidate_rec(mcc, rec);
24451a6231ea0b7fd0e98a9931e8254aa17bf4cfSimo Sorce }
24451a6231ea0b7fd0e98a9931e8254aa17bf4cfSimo Sorce
24451a6231ea0b7fd0e98a9931e8254aa17bf4cfSimo Sorce mcc->next_slot = cur + num_slots;
24451a6231ea0b7fd0e98a9931e8254aa17bf4cfSimo Sorce return cur;
24451a6231ea0b7fd0e98a9931e8254aa17bf4cfSimo Sorce}
24451a6231ea0b7fd0e98a9931e8254aa17bf4cfSimo Sorce
24451a6231ea0b7fd0e98a9931e8254aa17bf4cfSimo Sorcestatic struct sss_mc_rec *sss_mc_find_record(struct sss_mc_ctx *mcc,
24451a6231ea0b7fd0e98a9931e8254aa17bf4cfSimo Sorce struct sized_string *key)
24451a6231ea0b7fd0e98a9931e8254aa17bf4cfSimo Sorce{
24451a6231ea0b7fd0e98a9931e8254aa17bf4cfSimo Sorce struct sss_mc_rec *rec;
24451a6231ea0b7fd0e98a9931e8254aa17bf4cfSimo Sorce uint32_t hash;
24451a6231ea0b7fd0e98a9931e8254aa17bf4cfSimo Sorce uint32_t slot;
24451a6231ea0b7fd0e98a9931e8254aa17bf4cfSimo Sorce rel_ptr_t name_ptr;
24451a6231ea0b7fd0e98a9931e8254aa17bf4cfSimo Sorce char *t_key;
24451a6231ea0b7fd0e98a9931e8254aa17bf4cfSimo Sorce
24451a6231ea0b7fd0e98a9931e8254aa17bf4cfSimo Sorce hash = sss_mc_hash(mcc, key->str, key->len);
24451a6231ea0b7fd0e98a9931e8254aa17bf4cfSimo Sorce
24451a6231ea0b7fd0e98a9931e8254aa17bf4cfSimo Sorce slot = mcc->hash_table[hash];
24451a6231ea0b7fd0e98a9931e8254aa17bf4cfSimo Sorce if (slot > MC_SIZE_TO_SLOTS(mcc->dt_size)) {
24451a6231ea0b7fd0e98a9931e8254aa17bf4cfSimo Sorce return NULL;
24451a6231ea0b7fd0e98a9931e8254aa17bf4cfSimo Sorce }
24451a6231ea0b7fd0e98a9931e8254aa17bf4cfSimo Sorce
24451a6231ea0b7fd0e98a9931e8254aa17bf4cfSimo Sorce while (slot != MC_INVALID_VAL) {
24451a6231ea0b7fd0e98a9931e8254aa17bf4cfSimo Sorce rec = MC_SLOT_TO_PTR(mcc->data_table, slot, struct sss_mc_rec);
24451a6231ea0b7fd0e98a9931e8254aa17bf4cfSimo Sorce name_ptr = *((rel_ptr_t *)rec->data);
24451a6231ea0b7fd0e98a9931e8254aa17bf4cfSimo Sorce
24451a6231ea0b7fd0e98a9931e8254aa17bf4cfSimo Sorce t_key = (char *)rec->data + name_ptr;
24451a6231ea0b7fd0e98a9931e8254aa17bf4cfSimo Sorce if (strcmp(key->str, t_key) == 0) {
24451a6231ea0b7fd0e98a9931e8254aa17bf4cfSimo Sorce break;
24451a6231ea0b7fd0e98a9931e8254aa17bf4cfSimo Sorce }
24451a6231ea0b7fd0e98a9931e8254aa17bf4cfSimo Sorce
24451a6231ea0b7fd0e98a9931e8254aa17bf4cfSimo Sorce slot = rec->next;
24451a6231ea0b7fd0e98a9931e8254aa17bf4cfSimo Sorce }
24451a6231ea0b7fd0e98a9931e8254aa17bf4cfSimo Sorce
24451a6231ea0b7fd0e98a9931e8254aa17bf4cfSimo Sorce if (slot == MC_INVALID_VAL) {
24451a6231ea0b7fd0e98a9931e8254aa17bf4cfSimo Sorce return NULL;
24451a6231ea0b7fd0e98a9931e8254aa17bf4cfSimo Sorce }
24451a6231ea0b7fd0e98a9931e8254aa17bf4cfSimo Sorce
24451a6231ea0b7fd0e98a9931e8254aa17bf4cfSimo Sorce return rec;
24451a6231ea0b7fd0e98a9931e8254aa17bf4cfSimo Sorce}
24451a6231ea0b7fd0e98a9931e8254aa17bf4cfSimo Sorce
24451a6231ea0b7fd0e98a9931e8254aa17bf4cfSimo Sorcestatic struct sss_mc_rec *sss_mc_get_record(struct sss_mc_ctx *mcc,
24451a6231ea0b7fd0e98a9931e8254aa17bf4cfSimo Sorce size_t rec_len,
24451a6231ea0b7fd0e98a9931e8254aa17bf4cfSimo Sorce struct sized_string *key)
24451a6231ea0b7fd0e98a9931e8254aa17bf4cfSimo Sorce{
24451a6231ea0b7fd0e98a9931e8254aa17bf4cfSimo Sorce struct sss_mc_rec *old_rec = NULL;
24451a6231ea0b7fd0e98a9931e8254aa17bf4cfSimo Sorce struct sss_mc_rec *rec;
24451a6231ea0b7fd0e98a9931e8254aa17bf4cfSimo Sorce int old_slots;
24451a6231ea0b7fd0e98a9931e8254aa17bf4cfSimo Sorce int num_slots;
24451a6231ea0b7fd0e98a9931e8254aa17bf4cfSimo Sorce uint32_t base_slot;
24451a6231ea0b7fd0e98a9931e8254aa17bf4cfSimo Sorce int i;
24451a6231ea0b7fd0e98a9931e8254aa17bf4cfSimo Sorce
24451a6231ea0b7fd0e98a9931e8254aa17bf4cfSimo Sorce num_slots = MC_SIZE_TO_SLOTS(rec_len);
24451a6231ea0b7fd0e98a9931e8254aa17bf4cfSimo Sorce
24451a6231ea0b7fd0e98a9931e8254aa17bf4cfSimo Sorce old_rec = sss_mc_find_record(mcc, key);
24451a6231ea0b7fd0e98a9931e8254aa17bf4cfSimo Sorce if (old_rec) {
24451a6231ea0b7fd0e98a9931e8254aa17bf4cfSimo Sorce old_slots = MC_SIZE_TO_SLOTS(old_rec->len);
24451a6231ea0b7fd0e98a9931e8254aa17bf4cfSimo Sorce
24451a6231ea0b7fd0e98a9931e8254aa17bf4cfSimo Sorce if (old_slots == num_slots) {
24451a6231ea0b7fd0e98a9931e8254aa17bf4cfSimo Sorce return old_rec;
24451a6231ea0b7fd0e98a9931e8254aa17bf4cfSimo Sorce }
24451a6231ea0b7fd0e98a9931e8254aa17bf4cfSimo Sorce
24451a6231ea0b7fd0e98a9931e8254aa17bf4cfSimo Sorce /* slot size changed, invalidate record and fall through to get a
24451a6231ea0b7fd0e98a9931e8254aa17bf4cfSimo Sorce * fully new record */
24451a6231ea0b7fd0e98a9931e8254aa17bf4cfSimo Sorce base_slot = MC_PTR_TO_SLOT(mcc->data_table, old_rec);
24451a6231ea0b7fd0e98a9931e8254aa17bf4cfSimo Sorce sss_mc_invalidate_rec(mcc, old_rec);
24451a6231ea0b7fd0e98a9931e8254aa17bf4cfSimo Sorce
24451a6231ea0b7fd0e98a9931e8254aa17bf4cfSimo Sorce /* and now free slots */
24451a6231ea0b7fd0e98a9931e8254aa17bf4cfSimo Sorce for (i = 0; i < old_slots; i++) {
24451a6231ea0b7fd0e98a9931e8254aa17bf4cfSimo Sorce MC_CLEAR_BIT(mcc->free_table, base_slot + i);
24451a6231ea0b7fd0e98a9931e8254aa17bf4cfSimo Sorce }
24451a6231ea0b7fd0e98a9931e8254aa17bf4cfSimo Sorce }
24451a6231ea0b7fd0e98a9931e8254aa17bf4cfSimo Sorce
24451a6231ea0b7fd0e98a9931e8254aa17bf4cfSimo Sorce /* we are going to use more space, find enough free slots */
24451a6231ea0b7fd0e98a9931e8254aa17bf4cfSimo Sorce base_slot = sss_mc_find_free_slots(mcc, num_slots);
24451a6231ea0b7fd0e98a9931e8254aa17bf4cfSimo Sorce
24451a6231ea0b7fd0e98a9931e8254aa17bf4cfSimo Sorce rec = MC_SLOT_TO_PTR(mcc->data_table, base_slot, struct sss_mc_rec);
24451a6231ea0b7fd0e98a9931e8254aa17bf4cfSimo Sorce
24451a6231ea0b7fd0e98a9931e8254aa17bf4cfSimo Sorce /* mark as not valid yet */
24451a6231ea0b7fd0e98a9931e8254aa17bf4cfSimo Sorce MC_RAISE_INVALID_BARRIER(rec);
24451a6231ea0b7fd0e98a9931e8254aa17bf4cfSimo Sorce rec->len = rec_len;
24451a6231ea0b7fd0e98a9931e8254aa17bf4cfSimo Sorce rec->next = MC_INVALID_VAL;
24451a6231ea0b7fd0e98a9931e8254aa17bf4cfSimo Sorce MC_LOWER_BARRIER(rec);
24451a6231ea0b7fd0e98a9931e8254aa17bf4cfSimo Sorce
24451a6231ea0b7fd0e98a9931e8254aa17bf4cfSimo Sorce /* and now mark slots as used */
24451a6231ea0b7fd0e98a9931e8254aa17bf4cfSimo Sorce for (i = 0; i < num_slots; i++) {
24451a6231ea0b7fd0e98a9931e8254aa17bf4cfSimo Sorce MC_SET_BIT(mcc->free_table, base_slot + i);
24451a6231ea0b7fd0e98a9931e8254aa17bf4cfSimo Sorce }
24451a6231ea0b7fd0e98a9931e8254aa17bf4cfSimo Sorce
24451a6231ea0b7fd0e98a9931e8254aa17bf4cfSimo Sorce return rec;
24451a6231ea0b7fd0e98a9931e8254aa17bf4cfSimo Sorce}
24451a6231ea0b7fd0e98a9931e8254aa17bf4cfSimo Sorce
b294d4c50ec4431bc07ad7ec5a73e8af0e53c54fSimo Sorcestatic inline void sss_mmap_set_rec_header(struct sss_mc_ctx *mcc,
b294d4c50ec4431bc07ad7ec5a73e8af0e53c54fSimo Sorce struct sss_mc_rec *rec,
b294d4c50ec4431bc07ad7ec5a73e8af0e53c54fSimo Sorce size_t len, int ttl,
b294d4c50ec4431bc07ad7ec5a73e8af0e53c54fSimo Sorce const char *key1, size_t key1_len,
b294d4c50ec4431bc07ad7ec5a73e8af0e53c54fSimo Sorce const char *key2, size_t key2_len)
b294d4c50ec4431bc07ad7ec5a73e8af0e53c54fSimo Sorce{
b294d4c50ec4431bc07ad7ec5a73e8af0e53c54fSimo Sorce rec->len = len;
b294d4c50ec4431bc07ad7ec5a73e8af0e53c54fSimo Sorce rec->expire = time(NULL) + ttl;
b294d4c50ec4431bc07ad7ec5a73e8af0e53c54fSimo Sorce rec->hash1 = sss_mc_hash(mcc, key1, key1_len);
b294d4c50ec4431bc07ad7ec5a73e8af0e53c54fSimo Sorce rec->hash2 = sss_mc_hash(mcc, key2, key2_len);
b294d4c50ec4431bc07ad7ec5a73e8af0e53c54fSimo Sorce}
b294d4c50ec4431bc07ad7ec5a73e8af0e53c54fSimo Sorce
b294d4c50ec4431bc07ad7ec5a73e8af0e53c54fSimo Sorcestatic inline void sss_mmap_chain_in_rec(struct sss_mc_ctx *mcc,
b294d4c50ec4431bc07ad7ec5a73e8af0e53c54fSimo Sorce struct sss_mc_rec *rec)
b294d4c50ec4431bc07ad7ec5a73e8af0e53c54fSimo Sorce{
b294d4c50ec4431bc07ad7ec5a73e8af0e53c54fSimo Sorce /* name first */
b294d4c50ec4431bc07ad7ec5a73e8af0e53c54fSimo Sorce sss_mc_add_rec_to_chain(mcc, rec, rec->hash1);
b294d4c50ec4431bc07ad7ec5a73e8af0e53c54fSimo Sorce /* then uid/gid */
b294d4c50ec4431bc07ad7ec5a73e8af0e53c54fSimo Sorce sss_mc_add_rec_to_chain(mcc, rec, rec->hash2);
b294d4c50ec4431bc07ad7ec5a73e8af0e53c54fSimo Sorce}
eb2e21b764d03544d8161e9956d7f70b07b75f77Simo Sorce
8088274b2389b76f4be581736e55f26a8322fad1Simo Sorce/***************************************************************************
8088274b2389b76f4be581736e55f26a8322fad1Simo Sorce * generic invalidation
8088274b2389b76f4be581736e55f26a8322fad1Simo Sorce ***************************************************************************/
8088274b2389b76f4be581736e55f26a8322fad1Simo Sorce
8088274b2389b76f4be581736e55f26a8322fad1Simo Sorcestatic errno_t sss_mmap_cache_invalidate(struct sss_mc_ctx *mcc,
8088274b2389b76f4be581736e55f26a8322fad1Simo Sorce struct sized_string *key)
8088274b2389b76f4be581736e55f26a8322fad1Simo Sorce{
8088274b2389b76f4be581736e55f26a8322fad1Simo Sorce struct sss_mc_rec *rec;
8088274b2389b76f4be581736e55f26a8322fad1Simo Sorce
8088274b2389b76f4be581736e55f26a8322fad1Simo Sorce rec = sss_mc_find_record(mcc, key);
8088274b2389b76f4be581736e55f26a8322fad1Simo Sorce if (rec == NULL) {
8088274b2389b76f4be581736e55f26a8322fad1Simo Sorce /* nothing to invalidate */
8088274b2389b76f4be581736e55f26a8322fad1Simo Sorce return ENOENT;
8088274b2389b76f4be581736e55f26a8322fad1Simo Sorce }
8088274b2389b76f4be581736e55f26a8322fad1Simo Sorce
8088274b2389b76f4be581736e55f26a8322fad1Simo Sorce sss_mc_invalidate_rec(mcc, rec);
8088274b2389b76f4be581736e55f26a8322fad1Simo Sorce
8088274b2389b76f4be581736e55f26a8322fad1Simo Sorce return EOK;
8088274b2389b76f4be581736e55f26a8322fad1Simo Sorce}
8088274b2389b76f4be581736e55f26a8322fad1Simo Sorce
6cb1a6e7c7517ab4ccb8ad37ade86f95b5c16a01Simo Sorce/***************************************************************************
6cb1a6e7c7517ab4ccb8ad37ade86f95b5c16a01Simo Sorce * passwd map
6cb1a6e7c7517ab4ccb8ad37ade86f95b5c16a01Simo Sorce ***************************************************************************/
6cb1a6e7c7517ab4ccb8ad37ade86f95b5c16a01Simo Sorce
6cb1a6e7c7517ab4ccb8ad37ade86f95b5c16a01Simo Sorceerrno_t sss_mmap_cache_pw_store(struct sss_mc_ctx *mcc,
6cb1a6e7c7517ab4ccb8ad37ade86f95b5c16a01Simo Sorce struct sized_string *name,
6cb1a6e7c7517ab4ccb8ad37ade86f95b5c16a01Simo Sorce struct sized_string *pw,
6cb1a6e7c7517ab4ccb8ad37ade86f95b5c16a01Simo Sorce uid_t uid, gid_t gid,
6cb1a6e7c7517ab4ccb8ad37ade86f95b5c16a01Simo Sorce struct sized_string *gecos,
6cb1a6e7c7517ab4ccb8ad37ade86f95b5c16a01Simo Sorce struct sized_string *homedir,
6cb1a6e7c7517ab4ccb8ad37ade86f95b5c16a01Simo Sorce struct sized_string *shell)
6cb1a6e7c7517ab4ccb8ad37ade86f95b5c16a01Simo Sorce{
6cb1a6e7c7517ab4ccb8ad37ade86f95b5c16a01Simo Sorce struct sss_mc_rec *rec;
6cb1a6e7c7517ab4ccb8ad37ade86f95b5c16a01Simo Sorce struct sss_mc_pwd_data *data;
6cb1a6e7c7517ab4ccb8ad37ade86f95b5c16a01Simo Sorce struct sized_string uidkey;
6cb1a6e7c7517ab4ccb8ad37ade86f95b5c16a01Simo Sorce char uidstr[11];
6cb1a6e7c7517ab4ccb8ad37ade86f95b5c16a01Simo Sorce size_t data_len;
6cb1a6e7c7517ab4ccb8ad37ade86f95b5c16a01Simo Sorce size_t rec_len;
6cb1a6e7c7517ab4ccb8ad37ade86f95b5c16a01Simo Sorce size_t pos;
6cb1a6e7c7517ab4ccb8ad37ade86f95b5c16a01Simo Sorce int ret;
6cb1a6e7c7517ab4ccb8ad37ade86f95b5c16a01Simo Sorce
6cb1a6e7c7517ab4ccb8ad37ade86f95b5c16a01Simo Sorce ret = snprintf(uidstr, 11, "%ld", (long)uid);
6cb1a6e7c7517ab4ccb8ad37ade86f95b5c16a01Simo Sorce if (ret > 10) {
6cb1a6e7c7517ab4ccb8ad37ade86f95b5c16a01Simo Sorce return EINVAL;
6cb1a6e7c7517ab4ccb8ad37ade86f95b5c16a01Simo Sorce }
6cb1a6e7c7517ab4ccb8ad37ade86f95b5c16a01Simo Sorce to_sized_string(&uidkey, uidstr);
6cb1a6e7c7517ab4ccb8ad37ade86f95b5c16a01Simo Sorce
6cb1a6e7c7517ab4ccb8ad37ade86f95b5c16a01Simo Sorce data_len = name->len + pw->len + gecos->len + homedir->len + shell->len;
6cb1a6e7c7517ab4ccb8ad37ade86f95b5c16a01Simo Sorce rec_len = sizeof(struct sss_mc_rec) +
6cb1a6e7c7517ab4ccb8ad37ade86f95b5c16a01Simo Sorce sizeof(struct sss_mc_pwd_data) +
6cb1a6e7c7517ab4ccb8ad37ade86f95b5c16a01Simo Sorce data_len;
6cb1a6e7c7517ab4ccb8ad37ade86f95b5c16a01Simo Sorce if (rec_len > mcc->dt_size) {
6cb1a6e7c7517ab4ccb8ad37ade86f95b5c16a01Simo Sorce return ENOMEM;
6cb1a6e7c7517ab4ccb8ad37ade86f95b5c16a01Simo Sorce }
6cb1a6e7c7517ab4ccb8ad37ade86f95b5c16a01Simo Sorce
6cb1a6e7c7517ab4ccb8ad37ade86f95b5c16a01Simo Sorce rec = sss_mc_get_record(mcc, rec_len, name);
6cb1a6e7c7517ab4ccb8ad37ade86f95b5c16a01Simo Sorce
6cb1a6e7c7517ab4ccb8ad37ade86f95b5c16a01Simo Sorce data = (struct sss_mc_pwd_data *)rec->data;
6cb1a6e7c7517ab4ccb8ad37ade86f95b5c16a01Simo Sorce pos = 0;
6cb1a6e7c7517ab4ccb8ad37ade86f95b5c16a01Simo Sorce
6cb1a6e7c7517ab4ccb8ad37ade86f95b5c16a01Simo Sorce MC_RAISE_BARRIER(rec);
6cb1a6e7c7517ab4ccb8ad37ade86f95b5c16a01Simo Sorce
6cb1a6e7c7517ab4ccb8ad37ade86f95b5c16a01Simo Sorce /* header */
b294d4c50ec4431bc07ad7ec5a73e8af0e53c54fSimo Sorce sss_mmap_set_rec_header(mcc, rec, rec_len, mcc->valid_time_slot,
b294d4c50ec4431bc07ad7ec5a73e8af0e53c54fSimo Sorce name->str, name->len, uidkey.str, uidkey.len);
6cb1a6e7c7517ab4ccb8ad37ade86f95b5c16a01Simo Sorce
6cb1a6e7c7517ab4ccb8ad37ade86f95b5c16a01Simo Sorce /* passwd struct */
6cb1a6e7c7517ab4ccb8ad37ade86f95b5c16a01Simo Sorce data->name = MC_PTR_DIFF(data->strs, data);
6cb1a6e7c7517ab4ccb8ad37ade86f95b5c16a01Simo Sorce data->uid = uid;
6cb1a6e7c7517ab4ccb8ad37ade86f95b5c16a01Simo Sorce data->gid = gid;
6cb1a6e7c7517ab4ccb8ad37ade86f95b5c16a01Simo Sorce data->strs_len = data_len;
6cb1a6e7c7517ab4ccb8ad37ade86f95b5c16a01Simo Sorce memcpy(&data->strs[pos], name->str, name->len);
6cb1a6e7c7517ab4ccb8ad37ade86f95b5c16a01Simo Sorce pos += name->len;
6cb1a6e7c7517ab4ccb8ad37ade86f95b5c16a01Simo Sorce memcpy(&data->strs[pos], pw->str, pw->len);
6cb1a6e7c7517ab4ccb8ad37ade86f95b5c16a01Simo Sorce pos += pw->len;
6cb1a6e7c7517ab4ccb8ad37ade86f95b5c16a01Simo Sorce memcpy(&data->strs[pos], gecos->str, gecos->len);
6cb1a6e7c7517ab4ccb8ad37ade86f95b5c16a01Simo Sorce pos += gecos->len;
6cb1a6e7c7517ab4ccb8ad37ade86f95b5c16a01Simo Sorce memcpy(&data->strs[pos], homedir->str, homedir->len);
6cb1a6e7c7517ab4ccb8ad37ade86f95b5c16a01Simo Sorce pos += homedir->len;
6cb1a6e7c7517ab4ccb8ad37ade86f95b5c16a01Simo Sorce memcpy(&data->strs[pos], shell->str, shell->len);
6cb1a6e7c7517ab4ccb8ad37ade86f95b5c16a01Simo Sorce pos += shell->len;
6cb1a6e7c7517ab4ccb8ad37ade86f95b5c16a01Simo Sorce
6cb1a6e7c7517ab4ccb8ad37ade86f95b5c16a01Simo Sorce MC_LOWER_BARRIER(rec);
6cb1a6e7c7517ab4ccb8ad37ade86f95b5c16a01Simo Sorce
6cb1a6e7c7517ab4ccb8ad37ade86f95b5c16a01Simo Sorce /* finally chain the rec in the hash table */
b294d4c50ec4431bc07ad7ec5a73e8af0e53c54fSimo Sorce sss_mmap_chain_in_rec(mcc, rec);
6cb1a6e7c7517ab4ccb8ad37ade86f95b5c16a01Simo Sorce
6cb1a6e7c7517ab4ccb8ad37ade86f95b5c16a01Simo Sorce return EOK;
6cb1a6e7c7517ab4ccb8ad37ade86f95b5c16a01Simo Sorce}
6cb1a6e7c7517ab4ccb8ad37ade86f95b5c16a01Simo Sorce
8088274b2389b76f4be581736e55f26a8322fad1Simo Sorceerrno_t sss_mmap_cache_pw_invalidate(struct sss_mc_ctx *mcc,
8088274b2389b76f4be581736e55f26a8322fad1Simo Sorce struct sized_string *name)
8088274b2389b76f4be581736e55f26a8322fad1Simo Sorce{
8088274b2389b76f4be581736e55f26a8322fad1Simo Sorce return sss_mmap_cache_invalidate(mcc, name);
8088274b2389b76f4be581736e55f26a8322fad1Simo Sorce}
8088274b2389b76f4be581736e55f26a8322fad1Simo Sorce
8088274b2389b76f4be581736e55f26a8322fad1Simo Sorceerrno_t sss_mmap_cache_pw_invalidate_uid(struct sss_mc_ctx *mcc, uid_t uid)
8088274b2389b76f4be581736e55f26a8322fad1Simo Sorce{
8088274b2389b76f4be581736e55f26a8322fad1Simo Sorce struct sss_mc_rec *rec;
8088274b2389b76f4be581736e55f26a8322fad1Simo Sorce struct sss_mc_pwd_data *data;
8088274b2389b76f4be581736e55f26a8322fad1Simo Sorce uint32_t hash;
8088274b2389b76f4be581736e55f26a8322fad1Simo Sorce uint32_t slot;
8088274b2389b76f4be581736e55f26a8322fad1Simo Sorce char *uidstr;
8088274b2389b76f4be581736e55f26a8322fad1Simo Sorce errno_t ret;
8088274b2389b76f4be581736e55f26a8322fad1Simo Sorce
8088274b2389b76f4be581736e55f26a8322fad1Simo Sorce uidstr = talloc_asprintf(NULL, "%ld", (long)uid);
8088274b2389b76f4be581736e55f26a8322fad1Simo Sorce if (!uidstr) {
8088274b2389b76f4be581736e55f26a8322fad1Simo Sorce return ENOMEM;
8088274b2389b76f4be581736e55f26a8322fad1Simo Sorce }
8088274b2389b76f4be581736e55f26a8322fad1Simo Sorce
8088274b2389b76f4be581736e55f26a8322fad1Simo Sorce hash = sss_mc_hash(mcc, uidstr, strlen(uidstr) + 1);
8088274b2389b76f4be581736e55f26a8322fad1Simo Sorce
8088274b2389b76f4be581736e55f26a8322fad1Simo Sorce slot = mcc->hash_table[hash];
8088274b2389b76f4be581736e55f26a8322fad1Simo Sorce if (slot > MC_SIZE_TO_SLOTS(mcc->dt_size)) {
8088274b2389b76f4be581736e55f26a8322fad1Simo Sorce ret = ENOENT;
8088274b2389b76f4be581736e55f26a8322fad1Simo Sorce goto done;
8088274b2389b76f4be581736e55f26a8322fad1Simo Sorce }
8088274b2389b76f4be581736e55f26a8322fad1Simo Sorce
8088274b2389b76f4be581736e55f26a8322fad1Simo Sorce while (slot != MC_INVALID_VAL) {
8088274b2389b76f4be581736e55f26a8322fad1Simo Sorce rec = MC_SLOT_TO_PTR(mcc->data_table, slot, struct sss_mc_rec);
8088274b2389b76f4be581736e55f26a8322fad1Simo Sorce data = (struct sss_mc_pwd_data *)(&rec->data);
8088274b2389b76f4be581736e55f26a8322fad1Simo Sorce
8088274b2389b76f4be581736e55f26a8322fad1Simo Sorce if (uid == data->uid) {
8088274b2389b76f4be581736e55f26a8322fad1Simo Sorce break;
8088274b2389b76f4be581736e55f26a8322fad1Simo Sorce }
8088274b2389b76f4be581736e55f26a8322fad1Simo Sorce
8088274b2389b76f4be581736e55f26a8322fad1Simo Sorce slot = rec->next;
8088274b2389b76f4be581736e55f26a8322fad1Simo Sorce }
8088274b2389b76f4be581736e55f26a8322fad1Simo Sorce
8088274b2389b76f4be581736e55f26a8322fad1Simo Sorce if (slot == MC_INVALID_VAL) {
8088274b2389b76f4be581736e55f26a8322fad1Simo Sorce ret = ENOENT;
8088274b2389b76f4be581736e55f26a8322fad1Simo Sorce goto done;
8088274b2389b76f4be581736e55f26a8322fad1Simo Sorce }
8088274b2389b76f4be581736e55f26a8322fad1Simo Sorce
8088274b2389b76f4be581736e55f26a8322fad1Simo Sorce sss_mc_invalidate_rec(mcc, rec);
8088274b2389b76f4be581736e55f26a8322fad1Simo Sorce
8088274b2389b76f4be581736e55f26a8322fad1Simo Sorce ret = EOK;
8088274b2389b76f4be581736e55f26a8322fad1Simo Sorce
8088274b2389b76f4be581736e55f26a8322fad1Simo Sorcedone:
8088274b2389b76f4be581736e55f26a8322fad1Simo Sorce talloc_zfree(uidstr);
8088274b2389b76f4be581736e55f26a8322fad1Simo Sorce return ret;
8088274b2389b76f4be581736e55f26a8322fad1Simo Sorce}
6cb1a6e7c7517ab4ccb8ad37ade86f95b5c16a01Simo Sorce
c3ef027218fe9a7d16a70ca9d2f53e3d995e369fSimo Sorce/***************************************************************************
c3ef027218fe9a7d16a70ca9d2f53e3d995e369fSimo Sorce * group map
c3ef027218fe9a7d16a70ca9d2f53e3d995e369fSimo Sorce ***************************************************************************/
c3ef027218fe9a7d16a70ca9d2f53e3d995e369fSimo Sorce
c3ef027218fe9a7d16a70ca9d2f53e3d995e369fSimo Sorceint sss_mmap_cache_gr_store(struct sss_mc_ctx *mcc,
c3ef027218fe9a7d16a70ca9d2f53e3d995e369fSimo Sorce struct sized_string *name,
c3ef027218fe9a7d16a70ca9d2f53e3d995e369fSimo Sorce struct sized_string *pw,
c3ef027218fe9a7d16a70ca9d2f53e3d995e369fSimo Sorce gid_t gid, size_t memnum,
c3ef027218fe9a7d16a70ca9d2f53e3d995e369fSimo Sorce char *membuf, size_t memsize)
c3ef027218fe9a7d16a70ca9d2f53e3d995e369fSimo Sorce{
c3ef027218fe9a7d16a70ca9d2f53e3d995e369fSimo Sorce struct sss_mc_rec *rec;
c3ef027218fe9a7d16a70ca9d2f53e3d995e369fSimo Sorce struct sss_mc_grp_data *data;
c3ef027218fe9a7d16a70ca9d2f53e3d995e369fSimo Sorce struct sized_string gidkey;
c3ef027218fe9a7d16a70ca9d2f53e3d995e369fSimo Sorce char gidstr[11];
c3ef027218fe9a7d16a70ca9d2f53e3d995e369fSimo Sorce size_t data_len;
c3ef027218fe9a7d16a70ca9d2f53e3d995e369fSimo Sorce size_t rec_len;
c3ef027218fe9a7d16a70ca9d2f53e3d995e369fSimo Sorce size_t pos;
c3ef027218fe9a7d16a70ca9d2f53e3d995e369fSimo Sorce int ret;
c3ef027218fe9a7d16a70ca9d2f53e3d995e369fSimo Sorce
c3ef027218fe9a7d16a70ca9d2f53e3d995e369fSimo Sorce ret = snprintf(gidstr, 11, "%ld", (long)gid);
c3ef027218fe9a7d16a70ca9d2f53e3d995e369fSimo Sorce if (ret > 10) {
c3ef027218fe9a7d16a70ca9d2f53e3d995e369fSimo Sorce return EINVAL;
c3ef027218fe9a7d16a70ca9d2f53e3d995e369fSimo Sorce }
c3ef027218fe9a7d16a70ca9d2f53e3d995e369fSimo Sorce to_sized_string(&gidkey, gidstr);
c3ef027218fe9a7d16a70ca9d2f53e3d995e369fSimo Sorce
c3ef027218fe9a7d16a70ca9d2f53e3d995e369fSimo Sorce data_len = name->len + pw->len + memsize;
c3ef027218fe9a7d16a70ca9d2f53e3d995e369fSimo Sorce rec_len = sizeof(struct sss_mc_rec) +
c3ef027218fe9a7d16a70ca9d2f53e3d995e369fSimo Sorce sizeof(struct sss_mc_grp_data) +
c3ef027218fe9a7d16a70ca9d2f53e3d995e369fSimo Sorce data_len;
c3ef027218fe9a7d16a70ca9d2f53e3d995e369fSimo Sorce if (rec_len > mcc->dt_size) {
c3ef027218fe9a7d16a70ca9d2f53e3d995e369fSimo Sorce return ENOMEM;
c3ef027218fe9a7d16a70ca9d2f53e3d995e369fSimo Sorce }
c3ef027218fe9a7d16a70ca9d2f53e3d995e369fSimo Sorce
c3ef027218fe9a7d16a70ca9d2f53e3d995e369fSimo Sorce rec = sss_mc_get_record(mcc, rec_len, name);
c3ef027218fe9a7d16a70ca9d2f53e3d995e369fSimo Sorce
c3ef027218fe9a7d16a70ca9d2f53e3d995e369fSimo Sorce data = (struct sss_mc_grp_data *)rec->data;
c3ef027218fe9a7d16a70ca9d2f53e3d995e369fSimo Sorce pos = 0;
c3ef027218fe9a7d16a70ca9d2f53e3d995e369fSimo Sorce
c3ef027218fe9a7d16a70ca9d2f53e3d995e369fSimo Sorce MC_RAISE_BARRIER(rec);
c3ef027218fe9a7d16a70ca9d2f53e3d995e369fSimo Sorce
c3ef027218fe9a7d16a70ca9d2f53e3d995e369fSimo Sorce /* header */
b294d4c50ec4431bc07ad7ec5a73e8af0e53c54fSimo Sorce sss_mmap_set_rec_header(mcc, rec, rec_len, mcc->valid_time_slot,
b294d4c50ec4431bc07ad7ec5a73e8af0e53c54fSimo Sorce name->str, name->len, gidkey.str, gidkey.len);
c3ef027218fe9a7d16a70ca9d2f53e3d995e369fSimo Sorce
c3ef027218fe9a7d16a70ca9d2f53e3d995e369fSimo Sorce /* group struct */
c3ef027218fe9a7d16a70ca9d2f53e3d995e369fSimo Sorce data->name = MC_PTR_DIFF(data->strs, data);
c3ef027218fe9a7d16a70ca9d2f53e3d995e369fSimo Sorce data->gid = gid;
c3ef027218fe9a7d16a70ca9d2f53e3d995e369fSimo Sorce data->members = memnum;
c3ef027218fe9a7d16a70ca9d2f53e3d995e369fSimo Sorce data->strs_len = data_len;
c3ef027218fe9a7d16a70ca9d2f53e3d995e369fSimo Sorce memcpy(&data->strs[pos], name->str, name->len);
c3ef027218fe9a7d16a70ca9d2f53e3d995e369fSimo Sorce pos += name->len;
c3ef027218fe9a7d16a70ca9d2f53e3d995e369fSimo Sorce memcpy(&data->strs[pos], pw->str, pw->len);
c3ef027218fe9a7d16a70ca9d2f53e3d995e369fSimo Sorce pos += pw->len;
c3ef027218fe9a7d16a70ca9d2f53e3d995e369fSimo Sorce memcpy(&data->strs[pos], membuf, memsize);
c3ef027218fe9a7d16a70ca9d2f53e3d995e369fSimo Sorce pos += memsize;
c3ef027218fe9a7d16a70ca9d2f53e3d995e369fSimo Sorce
c3ef027218fe9a7d16a70ca9d2f53e3d995e369fSimo Sorce MC_LOWER_BARRIER(rec);
c3ef027218fe9a7d16a70ca9d2f53e3d995e369fSimo Sorce
c3ef027218fe9a7d16a70ca9d2f53e3d995e369fSimo Sorce /* finally chain the rec in the hash table */
b294d4c50ec4431bc07ad7ec5a73e8af0e53c54fSimo Sorce sss_mmap_chain_in_rec(mcc, rec);
c3ef027218fe9a7d16a70ca9d2f53e3d995e369fSimo Sorce
c3ef027218fe9a7d16a70ca9d2f53e3d995e369fSimo Sorce return EOK;
c3ef027218fe9a7d16a70ca9d2f53e3d995e369fSimo Sorce}
c3ef027218fe9a7d16a70ca9d2f53e3d995e369fSimo Sorce
8088274b2389b76f4be581736e55f26a8322fad1Simo Sorceerrno_t sss_mmap_cache_gr_invalidate(struct sss_mc_ctx *mcc,
8088274b2389b76f4be581736e55f26a8322fad1Simo Sorce struct sized_string *name)
8088274b2389b76f4be581736e55f26a8322fad1Simo Sorce{
8088274b2389b76f4be581736e55f26a8322fad1Simo Sorce return sss_mmap_cache_invalidate(mcc, name);
8088274b2389b76f4be581736e55f26a8322fad1Simo Sorce}
8088274b2389b76f4be581736e55f26a8322fad1Simo Sorce
8088274b2389b76f4be581736e55f26a8322fad1Simo Sorceerrno_t sss_mmap_cache_gr_invalidate_gid(struct sss_mc_ctx *mcc, gid_t gid)
8088274b2389b76f4be581736e55f26a8322fad1Simo Sorce{
8088274b2389b76f4be581736e55f26a8322fad1Simo Sorce struct sss_mc_rec *rec;
8088274b2389b76f4be581736e55f26a8322fad1Simo Sorce struct sss_mc_grp_data *data;
8088274b2389b76f4be581736e55f26a8322fad1Simo Sorce uint32_t hash;
8088274b2389b76f4be581736e55f26a8322fad1Simo Sorce uint32_t slot;
8088274b2389b76f4be581736e55f26a8322fad1Simo Sorce char *gidstr;
8088274b2389b76f4be581736e55f26a8322fad1Simo Sorce errno_t ret;
8088274b2389b76f4be581736e55f26a8322fad1Simo Sorce
8088274b2389b76f4be581736e55f26a8322fad1Simo Sorce gidstr = talloc_asprintf(NULL, "%ld", (long)gid);
8088274b2389b76f4be581736e55f26a8322fad1Simo Sorce if (!gidstr) {
8088274b2389b76f4be581736e55f26a8322fad1Simo Sorce return ENOMEM;
8088274b2389b76f4be581736e55f26a8322fad1Simo Sorce }
8088274b2389b76f4be581736e55f26a8322fad1Simo Sorce
8088274b2389b76f4be581736e55f26a8322fad1Simo Sorce hash = sss_mc_hash(mcc, gidstr, strlen(gidstr) + 1);
8088274b2389b76f4be581736e55f26a8322fad1Simo Sorce
8088274b2389b76f4be581736e55f26a8322fad1Simo Sorce slot = mcc->hash_table[hash];
8088274b2389b76f4be581736e55f26a8322fad1Simo Sorce if (slot > MC_SIZE_TO_SLOTS(mcc->dt_size)) {
8088274b2389b76f4be581736e55f26a8322fad1Simo Sorce ret = ENOENT;
8088274b2389b76f4be581736e55f26a8322fad1Simo Sorce goto done;
8088274b2389b76f4be581736e55f26a8322fad1Simo Sorce }
8088274b2389b76f4be581736e55f26a8322fad1Simo Sorce
8088274b2389b76f4be581736e55f26a8322fad1Simo Sorce while (slot != MC_INVALID_VAL) {
8088274b2389b76f4be581736e55f26a8322fad1Simo Sorce rec = MC_SLOT_TO_PTR(mcc->data_table, slot, struct sss_mc_rec);
8088274b2389b76f4be581736e55f26a8322fad1Simo Sorce data = (struct sss_mc_grp_data *)(&rec->data);
8088274b2389b76f4be581736e55f26a8322fad1Simo Sorce
8088274b2389b76f4be581736e55f26a8322fad1Simo Sorce if (gid == data->gid) {
8088274b2389b76f4be581736e55f26a8322fad1Simo Sorce break;
8088274b2389b76f4be581736e55f26a8322fad1Simo Sorce }
8088274b2389b76f4be581736e55f26a8322fad1Simo Sorce
8088274b2389b76f4be581736e55f26a8322fad1Simo Sorce slot = rec->next;
8088274b2389b76f4be581736e55f26a8322fad1Simo Sorce }
8088274b2389b76f4be581736e55f26a8322fad1Simo Sorce
8088274b2389b76f4be581736e55f26a8322fad1Simo Sorce if (slot == MC_INVALID_VAL) {
8088274b2389b76f4be581736e55f26a8322fad1Simo Sorce ret = ENOENT;
8088274b2389b76f4be581736e55f26a8322fad1Simo Sorce goto done;
8088274b2389b76f4be581736e55f26a8322fad1Simo Sorce }
8088274b2389b76f4be581736e55f26a8322fad1Simo Sorce
8088274b2389b76f4be581736e55f26a8322fad1Simo Sorce sss_mc_invalidate_rec(mcc, rec);
8088274b2389b76f4be581736e55f26a8322fad1Simo Sorce
8088274b2389b76f4be581736e55f26a8322fad1Simo Sorce ret = EOK;
8088274b2389b76f4be581736e55f26a8322fad1Simo Sorce
8088274b2389b76f4be581736e55f26a8322fad1Simo Sorcedone:
8088274b2389b76f4be581736e55f26a8322fad1Simo Sorce talloc_zfree(gidstr);
8088274b2389b76f4be581736e55f26a8322fad1Simo Sorce return ret;
8088274b2389b76f4be581736e55f26a8322fad1Simo Sorce}
8088274b2389b76f4be581736e55f26a8322fad1Simo Sorce
c3ef027218fe9a7d16a70ca9d2f53e3d995e369fSimo Sorce
eb2e21b764d03544d8161e9956d7f70b07b75f77Simo Sorce/***************************************************************************
eb2e21b764d03544d8161e9956d7f70b07b75f77Simo Sorce * initialization
eb2e21b764d03544d8161e9956d7f70b07b75f77Simo Sorce ***************************************************************************/
eb2e21b764d03544d8161e9956d7f70b07b75f77Simo Sorce
eb2e21b764d03544d8161e9956d7f70b07b75f77Simo Sorcestatic errno_t sss_mc_set_recycled(int fd)
eb2e21b764d03544d8161e9956d7f70b07b75f77Simo Sorce{
eb2e21b764d03544d8161e9956d7f70b07b75f77Simo Sorce uint32_t w = SSS_MC_HEADER_RECYCLED;
eb2e21b764d03544d8161e9956d7f70b07b75f77Simo Sorce struct sss_mc_header h;
eb2e21b764d03544d8161e9956d7f70b07b75f77Simo Sorce off_t offset;
eb2e21b764d03544d8161e9956d7f70b07b75f77Simo Sorce off_t pos;
eb2e21b764d03544d8161e9956d7f70b07b75f77Simo Sorce int ret;
eb2e21b764d03544d8161e9956d7f70b07b75f77Simo Sorce
eb2e21b764d03544d8161e9956d7f70b07b75f77Simo Sorce offset = MC_PTR_DIFF(&h.status, &h);
eb2e21b764d03544d8161e9956d7f70b07b75f77Simo Sorce
eb2e21b764d03544d8161e9956d7f70b07b75f77Simo Sorce pos = lseek(fd, offset, SEEK_SET);
eb2e21b764d03544d8161e9956d7f70b07b75f77Simo Sorce if (pos == -1) {
eb2e21b764d03544d8161e9956d7f70b07b75f77Simo Sorce /* What do we do now ? */
eb2e21b764d03544d8161e9956d7f70b07b75f77Simo Sorce return errno;
eb2e21b764d03544d8161e9956d7f70b07b75f77Simo Sorce }
9d7d4458d94d0aac0a7edf999368eb18f89cb76aJakub Hrozek
9d7d4458d94d0aac0a7edf999368eb18f89cb76aJakub Hrozek errno = 0;
9d7d4458d94d0aac0a7edf999368eb18f89cb76aJakub Hrozek ret = sss_atomic_write_s(fd, (uint8_t *)&w, sizeof(h.status));
9d7d4458d94d0aac0a7edf999368eb18f89cb76aJakub Hrozek if (ret == -1) {
9d7d4458d94d0aac0a7edf999368eb18f89cb76aJakub Hrozek return errno;
9d7d4458d94d0aac0a7edf999368eb18f89cb76aJakub Hrozek }
9d7d4458d94d0aac0a7edf999368eb18f89cb76aJakub Hrozek
9d7d4458d94d0aac0a7edf999368eb18f89cb76aJakub Hrozek if (ret != sizeof(h.status)) {
9d7d4458d94d0aac0a7edf999368eb18f89cb76aJakub Hrozek /* Write error */
9d7d4458d94d0aac0a7edf999368eb18f89cb76aJakub Hrozek return EIO;
eb2e21b764d03544d8161e9956d7f70b07b75f77Simo Sorce }
eb2e21b764d03544d8161e9956d7f70b07b75f77Simo Sorce
eb2e21b764d03544d8161e9956d7f70b07b75f77Simo Sorce return EOK;
eb2e21b764d03544d8161e9956d7f70b07b75f77Simo Sorce}
eb2e21b764d03544d8161e9956d7f70b07b75f77Simo Sorce
eb2e21b764d03544d8161e9956d7f70b07b75f77Simo Sorce/*
eb2e21b764d03544d8161e9956d7f70b07b75f77Simo Sorce * When we (re)create a new file we must mark the current file as recycled
eb2e21b764d03544d8161e9956d7f70b07b75f77Simo Sorce * so active clients will abandon its use asap.
eb2e21b764d03544d8161e9956d7f70b07b75f77Simo Sorce * We unlink the current file and make a new one
eb2e21b764d03544d8161e9956d7f70b07b75f77Simo Sorce */
eb2e21b764d03544d8161e9956d7f70b07b75f77Simo Sorcestatic errno_t sss_mc_create_file(struct sss_mc_ctx *mc_ctx)
eb2e21b764d03544d8161e9956d7f70b07b75f77Simo Sorce{
eb2e21b764d03544d8161e9956d7f70b07b75f77Simo Sorce mode_t old_mask;
eb2e21b764d03544d8161e9956d7f70b07b75f77Simo Sorce int ofd;
8b7040df8bcfee8cb31903136562eea73232f3d0Jakub Hrozek int ret, uret;
33cbb789ff71be5dccbb4a0acd68814b0d53da34Michal Zidek useconds_t t = 50000;
33cbb789ff71be5dccbb4a0acd68814b0d53da34Michal Zidek int retries = 3;
eb2e21b764d03544d8161e9956d7f70b07b75f77Simo Sorce
eb2e21b764d03544d8161e9956d7f70b07b75f77Simo Sorce ofd = open(mc_ctx->file, O_RDWR);
eb2e21b764d03544d8161e9956d7f70b07b75f77Simo Sorce if (ofd != -1) {
33cbb789ff71be5dccbb4a0acd68814b0d53da34Michal Zidek ret = sss_br_lock_file(ofd, 0, 1, retries, t);
33cbb789ff71be5dccbb4a0acd68814b0d53da34Michal Zidek if (ret != EOK) {
33cbb789ff71be5dccbb4a0acd68814b0d53da34Michal Zidek DEBUG(SSSDBG_FATAL_FAILURE,
33cbb789ff71be5dccbb4a0acd68814b0d53da34Michal Zidek ("Failed to lock file %s.\n", mc_ctx->file));
33cbb789ff71be5dccbb4a0acd68814b0d53da34Michal Zidek }
eb2e21b764d03544d8161e9956d7f70b07b75f77Simo Sorce ret = sss_mc_set_recycled(ofd);
eb2e21b764d03544d8161e9956d7f70b07b75f77Simo Sorce if (ret) {
33cbb789ff71be5dccbb4a0acd68814b0d53da34Michal Zidek DEBUG(SSSDBG_FATAL_FAILURE, ("Failed to mark mmap file %s as"
33cbb789ff71be5dccbb4a0acd68814b0d53da34Michal Zidek " recycled: %d(%s)\n",
33cbb789ff71be5dccbb4a0acd68814b0d53da34Michal Zidek mc_ctx->file, ret, strerror(ret)));
eb2e21b764d03544d8161e9956d7f70b07b75f77Simo Sorce }
eb2e21b764d03544d8161e9956d7f70b07b75f77Simo Sorce
eb2e21b764d03544d8161e9956d7f70b07b75f77Simo Sorce close(ofd);
eb2e21b764d03544d8161e9956d7f70b07b75f77Simo Sorce }
eb2e21b764d03544d8161e9956d7f70b07b75f77Simo Sorce
0d3bd5e0dbdd7579b64cec0b0e93605a3c37cdc1Stephen Gallagher errno = 0;
eb2e21b764d03544d8161e9956d7f70b07b75f77Simo Sorce ret = unlink(mc_ctx->file);
eb2e21b764d03544d8161e9956d7f70b07b75f77Simo Sorce if (ret == -1) {
0d3bd5e0dbdd7579b64cec0b0e93605a3c37cdc1Stephen Gallagher ret = errno;
eb2e21b764d03544d8161e9956d7f70b07b75f77Simo Sorce DEBUG(SSSDBG_TRACE_FUNC, ("Failed to rm mmap file %s: %d(%s)\n",
eb2e21b764d03544d8161e9956d7f70b07b75f77Simo Sorce mc_ctx->file, ret, strerror(ret)));
eb2e21b764d03544d8161e9956d7f70b07b75f77Simo Sorce }
eb2e21b764d03544d8161e9956d7f70b07b75f77Simo Sorce
eb2e21b764d03544d8161e9956d7f70b07b75f77Simo Sorce /* temporarily relax umask as we need the file to be readable
eb2e21b764d03544d8161e9956d7f70b07b75f77Simo Sorce * by everyone for now */
eb2e21b764d03544d8161e9956d7f70b07b75f77Simo Sorce old_mask = umask(0022);
eb2e21b764d03544d8161e9956d7f70b07b75f77Simo Sorce
8b7040df8bcfee8cb31903136562eea73232f3d0Jakub Hrozek errno = 0;
eb2e21b764d03544d8161e9956d7f70b07b75f77Simo Sorce mc_ctx->fd = open(mc_ctx->file, O_CREAT | O_EXCL | O_RDWR, 0644);
8b7040df8bcfee8cb31903136562eea73232f3d0Jakub Hrozek umask(old_mask);
eb2e21b764d03544d8161e9956d7f70b07b75f77Simo Sorce if (mc_ctx->fd == -1) {
eb2e21b764d03544d8161e9956d7f70b07b75f77Simo Sorce ret = errno;
eb2e21b764d03544d8161e9956d7f70b07b75f77Simo Sorce DEBUG(SSSDBG_CRIT_FAILURE, ("Failed to open mmap file %s: %d(%s)\n",
eb2e21b764d03544d8161e9956d7f70b07b75f77Simo Sorce mc_ctx->file, ret, strerror(ret)));
8b7040df8bcfee8cb31903136562eea73232f3d0Jakub Hrozek return ret;
33cbb789ff71be5dccbb4a0acd68814b0d53da34Michal Zidek }
33cbb789ff71be5dccbb4a0acd68814b0d53da34Michal Zidek
33cbb789ff71be5dccbb4a0acd68814b0d53da34Michal Zidek ret = sss_br_lock_file(mc_ctx->fd, 0, 1, retries, t);
33cbb789ff71be5dccbb4a0acd68814b0d53da34Michal Zidek if (ret != EOK) {
33cbb789ff71be5dccbb4a0acd68814b0d53da34Michal Zidek DEBUG(SSSDBG_FATAL_FAILURE,
33cbb789ff71be5dccbb4a0acd68814b0d53da34Michal Zidek ("Failed to lock file %s.\n", mc_ctx->file));
8b7040df8bcfee8cb31903136562eea73232f3d0Jakub Hrozek close(mc_ctx->fd);
eb2e21b764d03544d8161e9956d7f70b07b75f77Simo Sorce
8b7040df8bcfee8cb31903136562eea73232f3d0Jakub Hrozek /* Report on unlink failures but don't overwrite the errno
8b7040df8bcfee8cb31903136562eea73232f3d0Jakub Hrozek * from sss_br_lock_file
8b7040df8bcfee8cb31903136562eea73232f3d0Jakub Hrozek */
8b7040df8bcfee8cb31903136562eea73232f3d0Jakub Hrozek errno = 0;
8b7040df8bcfee8cb31903136562eea73232f3d0Jakub Hrozek uret = unlink(mc_ctx->file);
8b7040df8bcfee8cb31903136562eea73232f3d0Jakub Hrozek if (uret == -1) {
8b7040df8bcfee8cb31903136562eea73232f3d0Jakub Hrozek uret = errno;
8b7040df8bcfee8cb31903136562eea73232f3d0Jakub Hrozek DEBUG(SSSDBG_TRACE_FUNC, ("Failed to rm mmap file %s: %d(%s)\n",
8b7040df8bcfee8cb31903136562eea73232f3d0Jakub Hrozek mc_ctx->file, uret, strerror(uret)));
8b7040df8bcfee8cb31903136562eea73232f3d0Jakub Hrozek }
eb2e21b764d03544d8161e9956d7f70b07b75f77Simo Sorce
8b7040df8bcfee8cb31903136562eea73232f3d0Jakub Hrozek return ret;
33cbb789ff71be5dccbb4a0acd68814b0d53da34Michal Zidek }
33cbb789ff71be5dccbb4a0acd68814b0d53da34Michal Zidek
eb2e21b764d03544d8161e9956d7f70b07b75f77Simo Sorce return ret;
eb2e21b764d03544d8161e9956d7f70b07b75f77Simo Sorce}
eb2e21b764d03544d8161e9956d7f70b07b75f77Simo Sorce
eb2e21b764d03544d8161e9956d7f70b07b75f77Simo Sorcestatic void sss_mc_header_update(struct sss_mc_ctx *mc_ctx, int status)
eb2e21b764d03544d8161e9956d7f70b07b75f77Simo Sorce{
eb2e21b764d03544d8161e9956d7f70b07b75f77Simo Sorce struct sss_mc_header *h;
eb2e21b764d03544d8161e9956d7f70b07b75f77Simo Sorce
eb2e21b764d03544d8161e9956d7f70b07b75f77Simo Sorce /* update header using barriers */
eb2e21b764d03544d8161e9956d7f70b07b75f77Simo Sorce h = (struct sss_mc_header *)mc_ctx->mmap_base;
eb2e21b764d03544d8161e9956d7f70b07b75f77Simo Sorce MC_RAISE_BARRIER(h);
eb2e21b764d03544d8161e9956d7f70b07b75f77Simo Sorce if (status != SSS_MC_HEADER_RECYCLED) {
eb2e21b764d03544d8161e9956d7f70b07b75f77Simo Sorce /* no reason to update anything else if the file is recycled */
eb2e21b764d03544d8161e9956d7f70b07b75f77Simo Sorce h->hash_table = MC_PTR_DIFF(mc_ctx->hash_table, mc_ctx->mmap_base);
eb2e21b764d03544d8161e9956d7f70b07b75f77Simo Sorce h->free_table = MC_PTR_DIFF(mc_ctx->free_table, mc_ctx->mmap_base);
eb2e21b764d03544d8161e9956d7f70b07b75f77Simo Sorce h->data_table = MC_PTR_DIFF(mc_ctx->data_table, mc_ctx->mmap_base);
eb2e21b764d03544d8161e9956d7f70b07b75f77Simo Sorce h->ht_size = mc_ctx->ht_size;
eb2e21b764d03544d8161e9956d7f70b07b75f77Simo Sorce h->ft_size = mc_ctx->ft_size;
eb2e21b764d03544d8161e9956d7f70b07b75f77Simo Sorce h->dt_size = mc_ctx->dt_size;
eb2e21b764d03544d8161e9956d7f70b07b75f77Simo Sorce h->major_vno = SSS_MC_MAJOR_VNO;
eb2e21b764d03544d8161e9956d7f70b07b75f77Simo Sorce h->minor_vno = SSS_MC_MINOR_VNO;
eb2e21b764d03544d8161e9956d7f70b07b75f77Simo Sorce h->seed = mc_ctx->seed;
eb2e21b764d03544d8161e9956d7f70b07b75f77Simo Sorce h->reserved = 0;
eb2e21b764d03544d8161e9956d7f70b07b75f77Simo Sorce }
eb2e21b764d03544d8161e9956d7f70b07b75f77Simo Sorce h->status = status;
eb2e21b764d03544d8161e9956d7f70b07b75f77Simo Sorce MC_LOWER_BARRIER(h);
eb2e21b764d03544d8161e9956d7f70b07b75f77Simo Sorce}
eb2e21b764d03544d8161e9956d7f70b07b75f77Simo Sorce
eb2e21b764d03544d8161e9956d7f70b07b75f77Simo Sorceerrno_t sss_mmap_cache_init(TALLOC_CTX *mem_ctx, const char *name,
eb2e21b764d03544d8161e9956d7f70b07b75f77Simo Sorce enum sss_mc_type type, size_t n_elem,
e9f08ebaba5ec61af74c112f50c7d66257998c97Jan Zeleny time_t timeout, struct sss_mc_ctx **mcc)
eb2e21b764d03544d8161e9956d7f70b07b75f77Simo Sorce{
eb2e21b764d03544d8161e9956d7f70b07b75f77Simo Sorce struct sss_mc_ctx *mc_ctx = NULL;
eb2e21b764d03544d8161e9956d7f70b07b75f77Simo Sorce unsigned int rseed;
eb2e21b764d03544d8161e9956d7f70b07b75f77Simo Sorce int payload;
eb2e21b764d03544d8161e9956d7f70b07b75f77Simo Sorce int ret;
eb2e21b764d03544d8161e9956d7f70b07b75f77Simo Sorce
eb2e21b764d03544d8161e9956d7f70b07b75f77Simo Sorce switch (type) {
eb2e21b764d03544d8161e9956d7f70b07b75f77Simo Sorce case SSS_MC_PASSWD:
eb2e21b764d03544d8161e9956d7f70b07b75f77Simo Sorce payload = SSS_AVG_PASSWD_PAYLOAD;
eb2e21b764d03544d8161e9956d7f70b07b75f77Simo Sorce break;
eb2e21b764d03544d8161e9956d7f70b07b75f77Simo Sorce case SSS_MC_GROUP:
eb2e21b764d03544d8161e9956d7f70b07b75f77Simo Sorce payload = SSS_AVG_GROUP_PAYLOAD;
eb2e21b764d03544d8161e9956d7f70b07b75f77Simo Sorce break;
eb2e21b764d03544d8161e9956d7f70b07b75f77Simo Sorce default:
eb2e21b764d03544d8161e9956d7f70b07b75f77Simo Sorce return EINVAL;
eb2e21b764d03544d8161e9956d7f70b07b75f77Simo Sorce }
eb2e21b764d03544d8161e9956d7f70b07b75f77Simo Sorce
eb2e21b764d03544d8161e9956d7f70b07b75f77Simo Sorce mc_ctx = talloc_zero(mem_ctx, struct sss_mc_ctx);
eb2e21b764d03544d8161e9956d7f70b07b75f77Simo Sorce if (!mc_ctx) {
eb2e21b764d03544d8161e9956d7f70b07b75f77Simo Sorce return ENOMEM;
eb2e21b764d03544d8161e9956d7f70b07b75f77Simo Sorce }
eb2e21b764d03544d8161e9956d7f70b07b75f77Simo Sorce mc_ctx->fd = -1;
eb2e21b764d03544d8161e9956d7f70b07b75f77Simo Sorce
eb2e21b764d03544d8161e9956d7f70b07b75f77Simo Sorce mc_ctx->name = talloc_strdup(mem_ctx, name);
eb2e21b764d03544d8161e9956d7f70b07b75f77Simo Sorce if (!mc_ctx->name) {
eb2e21b764d03544d8161e9956d7f70b07b75f77Simo Sorce ret = ENOMEM;
eb2e21b764d03544d8161e9956d7f70b07b75f77Simo Sorce goto done;
eb2e21b764d03544d8161e9956d7f70b07b75f77Simo Sorce }
eb2e21b764d03544d8161e9956d7f70b07b75f77Simo Sorce
eb2e21b764d03544d8161e9956d7f70b07b75f77Simo Sorce mc_ctx->type = type;
eb2e21b764d03544d8161e9956d7f70b07b75f77Simo Sorce
e9f08ebaba5ec61af74c112f50c7d66257998c97Jan Zeleny mc_ctx->valid_time_slot = timeout;
eb2e21b764d03544d8161e9956d7f70b07b75f77Simo Sorce
eb2e21b764d03544d8161e9956d7f70b07b75f77Simo Sorce mc_ctx->file = talloc_asprintf(mc_ctx, "%s/%s",
eb2e21b764d03544d8161e9956d7f70b07b75f77Simo Sorce SSS_NSS_MCACHE_DIR, name);
eb2e21b764d03544d8161e9956d7f70b07b75f77Simo Sorce if (!mc_ctx->file) {
eb2e21b764d03544d8161e9956d7f70b07b75f77Simo Sorce ret = ENOMEM;
eb2e21b764d03544d8161e9956d7f70b07b75f77Simo Sorce goto done;
eb2e21b764d03544d8161e9956d7f70b07b75f77Simo Sorce }
eb2e21b764d03544d8161e9956d7f70b07b75f77Simo Sorce
eb2e21b764d03544d8161e9956d7f70b07b75f77Simo Sorce /* elements must always be multiple of 8 to make things easier to handle,
eb2e21b764d03544d8161e9956d7f70b07b75f77Simo Sorce * so we increase by the necessary amount if they are not a multiple */
eb2e21b764d03544d8161e9956d7f70b07b75f77Simo Sorce /* We can use MC_ALIGN64 for this */
eb2e21b764d03544d8161e9956d7f70b07b75f77Simo Sorce n_elem = MC_ALIGN64(n_elem);
eb2e21b764d03544d8161e9956d7f70b07b75f77Simo Sorce
eb2e21b764d03544d8161e9956d7f70b07b75f77Simo Sorce /* hash table is double the size because it will store both forward and
eb2e21b764d03544d8161e9956d7f70b07b75f77Simo Sorce * reverse keys (name/uid, name/gid, ..) */
eb2e21b764d03544d8161e9956d7f70b07b75f77Simo Sorce mc_ctx->ht_size = MC_HT_SIZE(n_elem * 2);
eb2e21b764d03544d8161e9956d7f70b07b75f77Simo Sorce mc_ctx->dt_size = MC_DT_SIZE(n_elem, payload);
eb2e21b764d03544d8161e9956d7f70b07b75f77Simo Sorce mc_ctx->ft_size = MC_FT_SIZE(n_elem);
eb2e21b764d03544d8161e9956d7f70b07b75f77Simo Sorce mc_ctx->mmap_size = MC_HEADER_SIZE +
eb2e21b764d03544d8161e9956d7f70b07b75f77Simo Sorce MC_ALIGN64(mc_ctx->dt_size) +
eb2e21b764d03544d8161e9956d7f70b07b75f77Simo Sorce MC_ALIGN64(mc_ctx->ft_size) +
eb2e21b764d03544d8161e9956d7f70b07b75f77Simo Sorce MC_ALIGN64(mc_ctx->ht_size);
eb2e21b764d03544d8161e9956d7f70b07b75f77Simo Sorce
eb2e21b764d03544d8161e9956d7f70b07b75f77Simo Sorce
eb2e21b764d03544d8161e9956d7f70b07b75f77Simo Sorce /* for now ALWAYS create a new file on restart */
eb2e21b764d03544d8161e9956d7f70b07b75f77Simo Sorce
eb2e21b764d03544d8161e9956d7f70b07b75f77Simo Sorce ret = sss_mc_create_file(mc_ctx);
eb2e21b764d03544d8161e9956d7f70b07b75f77Simo Sorce if (ret) {
eb2e21b764d03544d8161e9956d7f70b07b75f77Simo Sorce goto done;
eb2e21b764d03544d8161e9956d7f70b07b75f77Simo Sorce }
eb2e21b764d03544d8161e9956d7f70b07b75f77Simo Sorce
eb2e21b764d03544d8161e9956d7f70b07b75f77Simo Sorce ret = ftruncate(mc_ctx->fd, mc_ctx->mmap_size);
eb2e21b764d03544d8161e9956d7f70b07b75f77Simo Sorce if (ret == -1) {
eb2e21b764d03544d8161e9956d7f70b07b75f77Simo Sorce ret = errno;
eb2e21b764d03544d8161e9956d7f70b07b75f77Simo Sorce DEBUG(SSSDBG_CRIT_FAILURE, ("Failed to resize file %s: %d(%s)\n",
eb2e21b764d03544d8161e9956d7f70b07b75f77Simo Sorce mc_ctx->file, ret, strerror(ret)));
eb2e21b764d03544d8161e9956d7f70b07b75f77Simo Sorce goto done;
eb2e21b764d03544d8161e9956d7f70b07b75f77Simo Sorce }
eb2e21b764d03544d8161e9956d7f70b07b75f77Simo Sorce
eb2e21b764d03544d8161e9956d7f70b07b75f77Simo Sorce mc_ctx->mmap_base = mmap(NULL, mc_ctx->mmap_size,
eb2e21b764d03544d8161e9956d7f70b07b75f77Simo Sorce PROT_READ | PROT_WRITE,
eb2e21b764d03544d8161e9956d7f70b07b75f77Simo Sorce MAP_SHARED, mc_ctx->fd, 0);
eb2e21b764d03544d8161e9956d7f70b07b75f77Simo Sorce if (mc_ctx->mmap_base == MAP_FAILED) {
eb2e21b764d03544d8161e9956d7f70b07b75f77Simo Sorce ret = errno;
eb2e21b764d03544d8161e9956d7f70b07b75f77Simo Sorce DEBUG(SSSDBG_CRIT_FAILURE, ("Failed to mmap file %s(%ld): %d(%s)\n",
eb2e21b764d03544d8161e9956d7f70b07b75f77Simo Sorce mc_ctx->file, mc_ctx->mmap_size,
eb2e21b764d03544d8161e9956d7f70b07b75f77Simo Sorce ret, strerror(ret)));
eb2e21b764d03544d8161e9956d7f70b07b75f77Simo Sorce goto done;
eb2e21b764d03544d8161e9956d7f70b07b75f77Simo Sorce }
eb2e21b764d03544d8161e9956d7f70b07b75f77Simo Sorce
eb2e21b764d03544d8161e9956d7f70b07b75f77Simo Sorce mc_ctx->data_table = MC_PTR_ADD(mc_ctx->mmap_base, MC_HEADER_SIZE);
eb2e21b764d03544d8161e9956d7f70b07b75f77Simo Sorce mc_ctx->free_table = MC_PTR_ADD(mc_ctx->data_table,
eb2e21b764d03544d8161e9956d7f70b07b75f77Simo Sorce MC_ALIGN64(mc_ctx->dt_size));
eb2e21b764d03544d8161e9956d7f70b07b75f77Simo Sorce mc_ctx->hash_table = MC_PTR_ADD(mc_ctx->free_table,
eb2e21b764d03544d8161e9956d7f70b07b75f77Simo Sorce MC_ALIGN64(mc_ctx->ft_size));
eb2e21b764d03544d8161e9956d7f70b07b75f77Simo Sorce
eb2e21b764d03544d8161e9956d7f70b07b75f77Simo Sorce memset(mc_ctx->data_table, 0x00, mc_ctx->dt_size);
eb2e21b764d03544d8161e9956d7f70b07b75f77Simo Sorce memset(mc_ctx->free_table, 0x00, mc_ctx->ft_size);
eb2e21b764d03544d8161e9956d7f70b07b75f77Simo Sorce memset(mc_ctx->hash_table, 0xff, mc_ctx->ht_size);
eb2e21b764d03544d8161e9956d7f70b07b75f77Simo Sorce
eb2e21b764d03544d8161e9956d7f70b07b75f77Simo Sorce /* generate a pseudo-random seed.
eb2e21b764d03544d8161e9956d7f70b07b75f77Simo Sorce * Needed to fend off dictionary based collision attacks */
eb2e21b764d03544d8161e9956d7f70b07b75f77Simo Sorce rseed = time(NULL) * getpid();
eb2e21b764d03544d8161e9956d7f70b07b75f77Simo Sorce mc_ctx->seed = rand_r(&rseed);
eb2e21b764d03544d8161e9956d7f70b07b75f77Simo Sorce
eb2e21b764d03544d8161e9956d7f70b07b75f77Simo Sorce sss_mc_header_update(mc_ctx, SSS_MC_HEADER_ALIVE);
eb2e21b764d03544d8161e9956d7f70b07b75f77Simo Sorce
eb2e21b764d03544d8161e9956d7f70b07b75f77Simo Sorce ret = EOK;
eb2e21b764d03544d8161e9956d7f70b07b75f77Simo Sorce
eb2e21b764d03544d8161e9956d7f70b07b75f77Simo Sorcedone:
eb2e21b764d03544d8161e9956d7f70b07b75f77Simo Sorce if (ret) {
eb2e21b764d03544d8161e9956d7f70b07b75f77Simo Sorce if (mc_ctx && mc_ctx->mmap_base) {
eb2e21b764d03544d8161e9956d7f70b07b75f77Simo Sorce munmap(mc_ctx->mmap_base, mc_ctx->mmap_size);
eb2e21b764d03544d8161e9956d7f70b07b75f77Simo Sorce }
eb2e21b764d03544d8161e9956d7f70b07b75f77Simo Sorce if (mc_ctx && mc_ctx->fd != -1) {
eb2e21b764d03544d8161e9956d7f70b07b75f77Simo Sorce close(mc_ctx->fd);
eb2e21b764d03544d8161e9956d7f70b07b75f77Simo Sorce ret = unlink(mc_ctx->file);
eb2e21b764d03544d8161e9956d7f70b07b75f77Simo Sorce if (ret == -1) {
eb2e21b764d03544d8161e9956d7f70b07b75f77Simo Sorce DEBUG(SSSDBG_CRIT_FAILURE, ("Failed to rm mmap file %s: %d(%s)\n",
eb2e21b764d03544d8161e9956d7f70b07b75f77Simo Sorce mc_ctx->file, ret, strerror(ret)));
eb2e21b764d03544d8161e9956d7f70b07b75f77Simo Sorce }
eb2e21b764d03544d8161e9956d7f70b07b75f77Simo Sorce }
eb2e21b764d03544d8161e9956d7f70b07b75f77Simo Sorce
eb2e21b764d03544d8161e9956d7f70b07b75f77Simo Sorce talloc_free(mc_ctx);
eb2e21b764d03544d8161e9956d7f70b07b75f77Simo Sorce } else {
eb2e21b764d03544d8161e9956d7f70b07b75f77Simo Sorce *mcc = mc_ctx;
eb2e21b764d03544d8161e9956d7f70b07b75f77Simo Sorce }
eb2e21b764d03544d8161e9956d7f70b07b75f77Simo Sorce return ret;
eb2e21b764d03544d8161e9956d7f70b07b75f77Simo Sorce}
eb2e21b764d03544d8161e9956d7f70b07b75f77Simo Sorce
99c99e557020775714f028b28a147edda290c783Michal Zidekerrno_t sss_mmap_cache_reinit(TALLOC_CTX *mem_ctx, size_t n_elem,
99c99e557020775714f028b28a147edda290c783Michal Zidek time_t timeout, struct sss_mc_ctx **mc_ctx)
99c99e557020775714f028b28a147edda290c783Michal Zidek{
99c99e557020775714f028b28a147edda290c783Michal Zidek errno_t ret;
99c99e557020775714f028b28a147edda290c783Michal Zidek TALLOC_CTX* tmp_ctx = NULL;
99c99e557020775714f028b28a147edda290c783Michal Zidek char *name;
99c99e557020775714f028b28a147edda290c783Michal Zidek enum sss_mc_type type;
99c99e557020775714f028b28a147edda290c783Michal Zidek
99c99e557020775714f028b28a147edda290c783Michal Zidek if (mc_ctx == NULL || (*mc_ctx) == NULL) {
99c99e557020775714f028b28a147edda290c783Michal Zidek DEBUG(SSSDBG_CRIT_FAILURE,
99c99e557020775714f028b28a147edda290c783Michal Zidek ("Unable to re-init unitialized memory cache.\n"));
99c99e557020775714f028b28a147edda290c783Michal Zidek return EINVAL;
99c99e557020775714f028b28a147edda290c783Michal Zidek }
99c99e557020775714f028b28a147edda290c783Michal Zidek
99c99e557020775714f028b28a147edda290c783Michal Zidek tmp_ctx = talloc_new(NULL);
99c99e557020775714f028b28a147edda290c783Michal Zidek if (tmp_ctx == NULL) {
99c99e557020775714f028b28a147edda290c783Michal Zidek DEBUG(SSSDBG_CRIT_FAILURE, ("Out of memory.\n"));
99c99e557020775714f028b28a147edda290c783Michal Zidek return ENOMEM;
99c99e557020775714f028b28a147edda290c783Michal Zidek }
99c99e557020775714f028b28a147edda290c783Michal Zidek
99c99e557020775714f028b28a147edda290c783Michal Zidek name = talloc_strdup(tmp_ctx, (*mc_ctx)->name);
99c99e557020775714f028b28a147edda290c783Michal Zidek if (name == NULL) {
99c99e557020775714f028b28a147edda290c783Michal Zidek DEBUG(SSSDBG_CRIT_FAILURE, ("Out of memory.\n"));
99c99e557020775714f028b28a147edda290c783Michal Zidek ret = ENOMEM;
99c99e557020775714f028b28a147edda290c783Michal Zidek goto done;
99c99e557020775714f028b28a147edda290c783Michal Zidek }
99c99e557020775714f028b28a147edda290c783Michal Zidek
99c99e557020775714f028b28a147edda290c783Michal Zidek type = (*mc_ctx)->type;
99c99e557020775714f028b28a147edda290c783Michal Zidek ret = talloc_free(*mc_ctx);
99c99e557020775714f028b28a147edda290c783Michal Zidek if (ret != 0) {
99c99e557020775714f028b28a147edda290c783Michal Zidek /* This can happen only if destructor is associated with this
99c99e557020775714f028b28a147edda290c783Michal Zidek * context */
99c99e557020775714f028b28a147edda290c783Michal Zidek DEBUG(SSSDBG_MINOR_FAILURE, ("Destructor asociated with memory"
99c99e557020775714f028b28a147edda290c783Michal Zidek " context failed.\n"));
99c99e557020775714f028b28a147edda290c783Michal Zidek }
99c99e557020775714f028b28a147edda290c783Michal Zidek
99c99e557020775714f028b28a147edda290c783Michal Zidek ret = sss_mmap_cache_init(mem_ctx, name, type, n_elem, timeout, mc_ctx);
99c99e557020775714f028b28a147edda290c783Michal Zidek if (ret != EOK) {
99c99e557020775714f028b28a147edda290c783Michal Zidek DEBUG(SSSDBG_CRIT_FAILURE, ("Failed to re-initialize mmap cache.\n"));
99c99e557020775714f028b28a147edda290c783Michal Zidek goto done;
99c99e557020775714f028b28a147edda290c783Michal Zidek }
99c99e557020775714f028b28a147edda290c783Michal Zidek
99c99e557020775714f028b28a147edda290c783Michal Zidekdone:
99c99e557020775714f028b28a147edda290c783Michal Zidek talloc_free(tmp_ctx);
99c99e557020775714f028b28a147edda290c783Michal Zidek return ret;
99c99e557020775714f028b28a147edda290c783Michal Zidek}