2N/A/*
2N/A * CDDL HEADER START
2N/A *
2N/A * The contents of this file are subject to the terms of the
2N/A * Common Development and Distribution License (the "License").
2N/A * You may not use this file except in compliance with the License.
2N/A *
2N/A * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
2N/A * or http://www.opensolaris.org/os/licensing.
2N/A * See the License for the specific language governing permissions
2N/A * and limitations under the License.
2N/A *
2N/A * When distributing Covered Code, include this CDDL HEADER in each
2N/A * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
2N/A * If applicable, add the following below this CDDL HEADER, with the
2N/A * fields enclosed by brackets "[]" replaced with your own identifying
2N/A * information: Portions Copyright [yyyy] [name of copyright owner]
2N/A *
2N/A * CDDL HEADER END
2N/A */
2N/A
2N/A/*
2N/A * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
2N/A * Use is subject to license terms.
2N/A */
2N/A
2N/A/*
2N/A * Windows to Solaris Identity Mapping
2N/A * This module provides the libidmap idmap_cache.
2N/A */
2N/A
2N/A
2N/A#include <sys/types.h>
2N/A#include <sys/avl.h>
2N/A#include <assert.h>
2N/A#include <pthread.h>
2N/A#include <strings.h>
2N/A#include <sys/idmap.h>
2N/A#include <stddef.h>
2N/A#include <stdlib.h>
2N/A#include <rpcsvc/idmap_prot.h>
2N/A#include "idmap_cache.h"
2N/A
2N/A
2N/A/*
2N/A * Internal definitions and functions
2N/A */
2N/A
2N/A#define CACHE_UID_TRIGGER_SIZE 4096
2N/A#define CACHE_GID_TRIGGER_SIZE 2048
2N/A#define CACHE_UID_GID_TRIGGER_SIZE \
2N/A (CACHE_UID_TRIGGER_SIZE + CACHE_GID_TRIGGER_SIZE)
2N/A
2N/A
2N/A#define UNDEF_UID ((uid_t)-1)
2N/A#define UNDEF_GID ((gid_t)-1)
2N/A#define UNDEF_ISUSER (-1)
2N/A
2N/A#define CACHE_PURGE_INTERVAL (60 * 3)
2N/A#define CACHE_TTL (60 * 10)
2N/A
2N/A
2N/A
2N/A
2N/A#define list_insert(head, ele)\
2N/A do {\
2N/A (ele)->flink = (head)->flink;\
2N/A (head)->flink = (ele);\
2N/A (ele)->blink = (ele)->flink->blink;\
2N/A (ele)->flink->blink = (ele);\
2N/A } while (0)
2N/A
2N/A
2N/A
2N/A#define list_remove(ele)\
2N/A do {\
2N/A (ele)->flink->blink = (ele)->blink;\
2N/A (ele)->blink->flink = (ele)->flink;\
2N/A } while (0)
2N/A
2N/A
2N/A#define list_move(head, ele) \
2N/A do {\
2N/A if ((head)->flink != (ele)) {\
2N/A list_remove(ele);\
2N/A list_insert(head, ele);\
2N/A }\
2N/A } while (0)
2N/A
2N/Atypedef struct sid2uid_gid {
2N/A avl_node_t avl_link;
2N/A struct sid2uid_gid *flink;
2N/A struct sid2uid_gid *blink;
2N/A const char *sid_prefix;
2N/A idmap_rid_t rid;
2N/A uid_t uid;
2N/A time_t uid_ttl;
2N/A gid_t gid;
2N/A time_t gid_ttl;
2N/A int is_user;
2N/A} sid2uid_gid_t;
2N/A
2N/A
2N/Atypedef struct pid2sid_winname {
2N/A avl_node_t avl_link;
2N/A struct pid2sid_winname *flink;
2N/A struct pid2sid_winname *blink;
2N/A uid_t pid;
2N/A const char *sid_prefix;
2N/A idmap_rid_t rid;
2N/A time_t sid_ttl;
2N/A const char *winname;
2N/A const char *windomain;
2N/A time_t winname_ttl;
2N/A} pid2sid_winname_t;
2N/A
2N/A
2N/Atypedef struct winname2uid_gid {
2N/A avl_node_t avl_link;
2N/A struct winname2uid_gid *flink;
2N/A struct winname2uid_gid *blink;
2N/A const char *winname;
2N/A const char *windomain;
2N/A uid_t uid;
2N/A time_t uid_ttl;
2N/A gid_t gid;
2N/A time_t gid_ttl;
2N/A} winname2uid_gid_t;
2N/A
2N/A
2N/Atypedef struct sid2uid_gid_cache {
2N/A avl_tree_t tree;
2N/A pthread_mutex_t mutex;
2N/A sid2uid_gid_t head;
2N/A sid2uid_gid_t *prev;
2N/A time_t purge_time;
2N/A int uid_num;
2N/A int gid_num;
2N/A int pid_num;
2N/A} sid2uid_gid_cache_t;
2N/A
2N/A
2N/Atypedef struct pid2sid_winname_cache {
2N/A avl_tree_t tree;
2N/A pthread_mutex_t mutex;
2N/A pid2sid_winname_t head;
2N/A pid2sid_winname_t *prev;
2N/A time_t purge_time;
2N/A int sid_num;
2N/A int winname_num;
2N/A} pid2sid_winname_cache_t;
2N/A
2N/A
2N/A
2N/Atypedef struct winname2uid_gid_cache {
2N/A avl_tree_t tree;
2N/A pthread_mutex_t mutex;
2N/A winname2uid_gid_t head;
2N/A winname2uid_gid_t *prev;
2N/A time_t purge_time;
2N/A int uid_num;
2N/A int gid_num;
2N/A} winname2uid_gid_cache_t;
2N/A
2N/A
2N/Atypedef struct idmap_cache {
2N/A sid2uid_gid_cache_t sid2uid_gid;
2N/A pid2sid_winname_cache_t uid2sid_winname;
2N/A pid2sid_winname_cache_t gid2sid_winname;
2N/A winname2uid_gid_cache_t winname2uid_gid;
2N/A} idmap_cache_t;
2N/A
2N/A
2N/A
2N/Atypedef int (*avl_comp_fn)(const void*, const void*);
2N/A
2N/Astatic void
2N/Aidmap_purge_sid2uid_gid_cache(sid2uid_gid_cache_t *cache, size_t limit);
2N/A
2N/Astatic void
2N/Aidmap_purge_pid2sid_winname_cache(pid2sid_winname_cache_t *cache, size_t limit);
2N/A
2N/Astatic void
2N/Aidmap_purge_winname2uid_gid_cache(winname2uid_gid_cache_t *avl, size_t limit);
2N/A
2N/A/*
2N/A * Global structures
2N/A */
2N/A
2N/Astatic idmap_cache_t idmap_cache;
2N/A
2N/A
2N/A
2N/A
2N/Astatic int
2N/Aidmap_compare_sid(const sid2uid_gid_t *entry1, const sid2uid_gid_t *entry2)
2N/A{
2N/A int64_t comp = ((int64_t)entry2->rid) - ((int64_t)entry1->rid);
2N/A
2N/A if (comp == 0)
2N/A comp = strcmp(entry2->sid_prefix, entry1->sid_prefix);
2N/A
2N/A if (comp < 0)
2N/A comp = -1;
2N/A else if (comp > 0)
2N/A comp = 1;
2N/A
2N/A return ((int)comp);
2N/A}
2N/A
2N/A
2N/Astatic int
2N/Aidmap_compare_pid(const pid2sid_winname_t *entry1,
2N/A const pid2sid_winname_t *entry2)
2N/A{
2N/A if (entry2->pid > entry1->pid)
2N/A return (1);
2N/A if (entry2->pid < entry1->pid)
2N/A return (-1);
2N/A return (0);
2N/A}
2N/A
2N/A
2N/Astatic int
2N/Aidmap_compare_winname(const winname2uid_gid_t *entry1,
2N/A const winname2uid_gid_t *entry2)
2N/A{
2N/A int comp;
2N/A
2N/A comp = strcasecmp(entry2->winname, entry1->winname);
2N/A if (comp == 0) {
2N/A if (entry2->windomain == NULL && entry1->windomain == NULL)
2N/A return (0);
2N/A if (entry1->windomain == NULL)
2N/A return (1);
2N/A if (entry2->windomain == NULL)
2N/A return (-1);
2N/A
2N/A comp = strcasecmp(entry2->windomain, entry1->windomain);
2N/A }
2N/A
2N/A if (comp < 0)
2N/A comp = -1;
2N/A else if (comp > 0)
2N/A comp = 1;
2N/A
2N/A return (comp);
2N/A}
2N/A
2N/A/*
2N/A * Routine to update item
2N/A *
2N/A * Returns: 0 Success
2N/A * -1 Error
2N/A */
2N/Astatic int
2N/Aupdate_str(const char **item, const char *str)
2N/A{
2N/A char *tmp;
2N/A
2N/A if (*item != NULL && str != NULL) {
2N/A if (strcmp(*item, str) != 0) {
2N/A if ((tmp = strdup(str)) == NULL)
2N/A return (-1);
2N/A free((char *)*item);
2N/A *item = tmp;
2N/A }
2N/A } else if (str != NULL) {
2N/A /* *item is NULL */
2N/A if ((*item = strdup(str)) == NULL)
2N/A return (-1);
2N/A } else if (*item != NULL) {
2N/A /* str is NULL */
2N/A free((char *)*item);
2N/A *item = NULL;
2N/A }
2N/A
2N/A return (0);
2N/A}
2N/A
2N/A/*
2N/A * The Cache is initialized on loading libidmap.so
2N/A */
2N/A#pragma init(idmap_cache_create)
2N/A
2N/Avoid
2N/Aidmap_cache_create(void)
2N/A{
2N/A avl_create(&idmap_cache.sid2uid_gid.tree,
2N/A (avl_comp_fn)idmap_compare_sid, sizeof (sid2uid_gid_t),
2N/A offsetof(sid2uid_gid_t, avl_link));
2N/A (void) pthread_mutex_init(&idmap_cache.sid2uid_gid.mutex, NULL);
2N/A idmap_cache.sid2uid_gid.head.flink = &idmap_cache.sid2uid_gid.head;
2N/A idmap_cache.sid2uid_gid.head.blink = &idmap_cache.sid2uid_gid.head;
2N/A idmap_cache.sid2uid_gid.prev = NULL;
2N/A idmap_cache.sid2uid_gid.purge_time = 0;
2N/A idmap_cache.sid2uid_gid.uid_num = 0;
2N/A idmap_cache.sid2uid_gid.gid_num = 0;
2N/A idmap_cache.sid2uid_gid.pid_num = 0;
2N/A
2N/A avl_create(&idmap_cache.uid2sid_winname.tree,
2N/A (avl_comp_fn)idmap_compare_pid, sizeof (pid2sid_winname_t),
2N/A offsetof(pid2sid_winname_t, avl_link));
2N/A (void) pthread_mutex_init(&idmap_cache.uid2sid_winname.mutex, NULL);
2N/A idmap_cache.uid2sid_winname.head.flink =
2N/A &idmap_cache.uid2sid_winname.head;
2N/A idmap_cache.uid2sid_winname.head.blink =
2N/A &idmap_cache.uid2sid_winname.head;
2N/A idmap_cache.uid2sid_winname.prev = NULL;
2N/A idmap_cache.uid2sid_winname.purge_time = 0;
2N/A idmap_cache.uid2sid_winname.sid_num = 0;
2N/A idmap_cache.uid2sid_winname.winname_num = 0;
2N/A
2N/A avl_create(&idmap_cache.gid2sid_winname.tree,
2N/A (avl_comp_fn)idmap_compare_pid, sizeof (pid2sid_winname_t),
2N/A offsetof(pid2sid_winname_t, avl_link));
2N/A (void) pthread_mutex_init(&idmap_cache.gid2sid_winname.mutex, NULL);
2N/A idmap_cache.gid2sid_winname.head.flink =
2N/A &idmap_cache.gid2sid_winname.head;
2N/A idmap_cache.gid2sid_winname.head.blink =
2N/A &idmap_cache.gid2sid_winname.head;
2N/A idmap_cache.gid2sid_winname.prev = NULL;
2N/A idmap_cache.gid2sid_winname.purge_time = 0;
2N/A idmap_cache.gid2sid_winname.sid_num = 0;
2N/A idmap_cache.gid2sid_winname.winname_num = 0;
2N/A
2N/A avl_create(&idmap_cache.winname2uid_gid.tree,
2N/A (avl_comp_fn)idmap_compare_winname, sizeof (winname2uid_gid_t),
2N/A offsetof(winname2uid_gid_t, avl_link));
2N/A (void) pthread_mutex_init(&idmap_cache.winname2uid_gid.mutex, NULL);
2N/A idmap_cache.winname2uid_gid.head.flink =
2N/A &idmap_cache.winname2uid_gid.head;
2N/A idmap_cache.winname2uid_gid.head.blink =
2N/A &idmap_cache.winname2uid_gid.head;
2N/A idmap_cache.winname2uid_gid.prev = NULL;
2N/A idmap_cache.winname2uid_gid.purge_time = 0;
2N/A idmap_cache.winname2uid_gid.uid_num = 0;
2N/A idmap_cache.winname2uid_gid.gid_num = 0;
2N/A}
2N/A
2N/A
2N/Avoid
2N/Aidmap_cache_purge(void)
2N/A{
2N/A sid2uid_gid_t *sid2uid_gid;
2N/A pid2sid_winname_t *uid2sid_winname;
2N/A pid2sid_winname_t *gid2sid_winname;
2N/A winname2uid_gid_t *winname2uid_gid;
2N/A void *cookie;
2N/A
2N/A (void) pthread_mutex_lock(&idmap_cache.sid2uid_gid.mutex);
2N/A cookie = NULL;
2N/A while ((sid2uid_gid = avl_destroy_nodes(
2N/A &idmap_cache.sid2uid_gid.tree, &cookie)) != NULL) {
2N/A free((char *)sid2uid_gid->sid_prefix);
2N/A free(sid2uid_gid);
2N/A }
2N/A avl_destroy(&idmap_cache.sid2uid_gid.tree);
2N/A avl_create(&idmap_cache.sid2uid_gid.tree,
2N/A (avl_comp_fn)idmap_compare_sid, sizeof (sid2uid_gid_t),
2N/A offsetof(sid2uid_gid_t, avl_link));
2N/A idmap_cache.sid2uid_gid.head.flink = &idmap_cache.sid2uid_gid.head;
2N/A idmap_cache.sid2uid_gid.head.blink = &idmap_cache.sid2uid_gid.head;
2N/A idmap_cache.sid2uid_gid.prev = NULL;
2N/A idmap_cache.sid2uid_gid.purge_time = 0;
2N/A idmap_cache.sid2uid_gid.uid_num = 0;
2N/A idmap_cache.sid2uid_gid.gid_num = 0;
2N/A idmap_cache.sid2uid_gid.pid_num = 0;
2N/A (void) pthread_mutex_unlock(&idmap_cache.sid2uid_gid.mutex);
2N/A
2N/A
2N/A (void) pthread_mutex_lock(&idmap_cache.uid2sid_winname.mutex);
2N/A cookie = NULL;
2N/A while ((uid2sid_winname = avl_destroy_nodes(
2N/A &idmap_cache.uid2sid_winname.tree, &cookie)) != NULL) {
2N/A free((char *)uid2sid_winname->sid_prefix);
2N/A free((char *)uid2sid_winname->winname);
2N/A if (uid2sid_winname->windomain != NULL)
2N/A free((char *)uid2sid_winname->windomain);
2N/A free(uid2sid_winname);
2N/A }
2N/A avl_destroy(&idmap_cache.uid2sid_winname.tree);
2N/A avl_create(&idmap_cache.uid2sid_winname.tree,
2N/A (avl_comp_fn)idmap_compare_pid, sizeof (pid2sid_winname_t),
2N/A offsetof(pid2sid_winname_t, avl_link));
2N/A idmap_cache.uid2sid_winname.head.flink =
2N/A &idmap_cache.uid2sid_winname.head;
2N/A idmap_cache.uid2sid_winname.head.blink =
2N/A &idmap_cache.uid2sid_winname.head;
2N/A idmap_cache.uid2sid_winname.prev = NULL;
2N/A idmap_cache.uid2sid_winname.purge_time = 0;
2N/A idmap_cache.uid2sid_winname.sid_num = 0;
2N/A idmap_cache.uid2sid_winname.winname_num = 0;
2N/A (void) pthread_mutex_unlock(&idmap_cache.uid2sid_winname.mutex);
2N/A
2N/A
2N/A (void) pthread_mutex_lock(&idmap_cache.gid2sid_winname.mutex);
2N/A cookie = NULL;
2N/A while ((gid2sid_winname = avl_destroy_nodes(
2N/A &idmap_cache.gid2sid_winname.tree, &cookie)) != NULL) {
2N/A free((char *)gid2sid_winname->sid_prefix);
2N/A free((char *)gid2sid_winname->winname);
2N/A if (gid2sid_winname->windomain != NULL)
2N/A free((char *)gid2sid_winname->windomain);
2N/A free(gid2sid_winname);
2N/A }
2N/A avl_destroy(&idmap_cache.gid2sid_winname.tree);
2N/A avl_create(&idmap_cache.gid2sid_winname.tree,
2N/A (avl_comp_fn)idmap_compare_pid, sizeof (pid2sid_winname_t),
2N/A offsetof(pid2sid_winname_t, avl_link));
2N/A idmap_cache.gid2sid_winname.head.flink =
2N/A &idmap_cache.gid2sid_winname.head;
2N/A idmap_cache.gid2sid_winname.head.blink =
2N/A &idmap_cache.gid2sid_winname.head;
2N/A idmap_cache.gid2sid_winname.prev = NULL;
2N/A idmap_cache.gid2sid_winname.purge_time = 0;
2N/A idmap_cache.gid2sid_winname.sid_num = 0;
2N/A idmap_cache.gid2sid_winname.winname_num = 0;
2N/A (void) pthread_mutex_unlock(&idmap_cache.gid2sid_winname.mutex);
2N/A
2N/A (void) pthread_mutex_lock(&idmap_cache.winname2uid_gid.mutex);
2N/A cookie = NULL;
2N/A while ((winname2uid_gid = avl_destroy_nodes(
2N/A &idmap_cache.winname2uid_gid.tree, &cookie)) != NULL) {
2N/A free((char *)winname2uid_gid->winname);
2N/A if (winname2uid_gid->windomain)
2N/A free((char *)winname2uid_gid->windomain);
2N/A free(winname2uid_gid);
2N/A }
2N/A avl_destroy(&idmap_cache.winname2uid_gid.tree);
2N/A avl_create(&idmap_cache.winname2uid_gid.tree,
2N/A (avl_comp_fn)idmap_compare_winname, sizeof (winname2uid_gid_t),
2N/A offsetof(winname2uid_gid_t, avl_link));
2N/A idmap_cache.winname2uid_gid.head.flink =
2N/A &idmap_cache.winname2uid_gid.head;
2N/A idmap_cache.winname2uid_gid.head.blink =
2N/A &idmap_cache.winname2uid_gid.head;
2N/A idmap_cache.winname2uid_gid.prev = NULL;
2N/A idmap_cache.winname2uid_gid.purge_time = 0;
2N/A idmap_cache.winname2uid_gid.uid_num = 0;
2N/A idmap_cache.winname2uid_gid.gid_num = 0;
2N/A (void) pthread_mutex_unlock(&idmap_cache.winname2uid_gid.mutex);
2N/A
2N/A}
2N/A
2N/A
2N/Avoid
2N/Aidmap_cache_get_data(size_t *uidbysid, size_t *gidbysid,
2N/A size_t *pidbysid, size_t *sidbyuid, size_t *sidbygid,
2N/A size_t *winnamebyuid, size_t *winnamebygid,
2N/A size_t *uidbywinname, size_t *gidbywinname)
2N/A{
2N/A (void) pthread_mutex_lock(&idmap_cache.sid2uid_gid.mutex);
2N/A *uidbysid = idmap_cache.sid2uid_gid.uid_num;
2N/A *gidbysid = idmap_cache.sid2uid_gid.gid_num;
2N/A *pidbysid = idmap_cache.sid2uid_gid.pid_num;
2N/A (void) pthread_mutex_unlock(&idmap_cache.sid2uid_gid.mutex);
2N/A
2N/A (void) pthread_mutex_lock(&idmap_cache.uid2sid_winname.mutex);
2N/A *sidbyuid = idmap_cache.uid2sid_winname.sid_num;
2N/A *winnamebyuid = idmap_cache.uid2sid_winname.winname_num;
2N/A (void) pthread_mutex_unlock(&idmap_cache.uid2sid_winname.mutex);
2N/A
2N/A (void) pthread_mutex_lock(&idmap_cache.gid2sid_winname.mutex);
2N/A *sidbygid = idmap_cache.gid2sid_winname.sid_num;
2N/A *winnamebygid = idmap_cache.gid2sid_winname.winname_num;
2N/A (void) pthread_mutex_unlock(&idmap_cache.gid2sid_winname.mutex);
2N/A
2N/A (void) pthread_mutex_lock(&idmap_cache.winname2uid_gid.mutex);
2N/A *uidbywinname = idmap_cache.winname2uid_gid.uid_num;
2N/A *gidbywinname = idmap_cache.winname2uid_gid.gid_num;
2N/A (void) pthread_mutex_unlock(&idmap_cache.winname2uid_gid.mutex);
2N/A}
2N/A
2N/A
2N/Aidmap_stat
2N/Aidmap_cache_lookup_uidbysid(const char *sid_prefix,
2N/A idmap_rid_t rid, uid_t *uid)
2N/A{
2N/A sid2uid_gid_t entry;
2N/A sid2uid_gid_t *result;
2N/A avl_index_t where;
2N/A int status = IDMAP_ERR_NOMAPPING;
2N/A time_t now = time(NULL);
2N/A
2N/A entry.sid_prefix = sid_prefix;
2N/A entry.rid = rid;
2N/A
2N/A (void) pthread_mutex_lock(&idmap_cache.sid2uid_gid.mutex);
2N/A
2N/A result = avl_find(&idmap_cache.sid2uid_gid.tree, &entry, &where);
2N/A if (result != NULL) {
2N/A list_move(&idmap_cache.sid2uid_gid.head, result);
2N/A if (result->uid != UNDEF_UID && result->uid_ttl > now) {
2N/A *uid = result->uid;
2N/A status = IDMAP_SUCCESS;
2N/A }
2N/A }
2N/A
2N/A (void) pthread_mutex_unlock(&idmap_cache.sid2uid_gid.mutex);
2N/A
2N/A return (status);
2N/A}
2N/A
2N/A
2N/A
2N/Aidmap_stat
2N/Aidmap_cache_lookup_gidbysid(const char *sid_prefix,
2N/A idmap_rid_t rid, gid_t *gid)
2N/A{
2N/A sid2uid_gid_t entry;
2N/A sid2uid_gid_t *result;
2N/A avl_index_t where;
2N/A int status = IDMAP_ERR_NOMAPPING;
2N/A time_t now = time(NULL);
2N/A
2N/A entry.sid_prefix = sid_prefix;
2N/A entry.rid = rid;
2N/A
2N/A (void) pthread_mutex_lock(&idmap_cache.sid2uid_gid.mutex);
2N/A
2N/A result = avl_find(&idmap_cache.sid2uid_gid.tree, &entry, &where);
2N/A if (result != NULL) {
2N/A list_move(&idmap_cache.sid2uid_gid.head, result);
2N/A if (result->gid != UNDEF_GID && result->gid_ttl > now) {
2N/A *gid = result->gid;
2N/A status = IDMAP_SUCCESS;
2N/A }
2N/A }
2N/A
2N/A (void) pthread_mutex_unlock(&idmap_cache.sid2uid_gid.mutex);
2N/A
2N/A return (status);
2N/A}
2N/A
2N/A
2N/A
2N/A
2N/Aidmap_stat
2N/Aidmap_cache_lookup_pidbysid(const char *sid_prefix,
2N/A idmap_rid_t rid, uid_t *pid, int *is_user)
2N/A{
2N/A sid2uid_gid_t entry;
2N/A sid2uid_gid_t *result;
2N/A avl_index_t where;
2N/A int status = IDMAP_ERR_NOMAPPING;
2N/A time_t now = time(NULL);
2N/A
2N/A entry.sid_prefix = sid_prefix;
2N/A entry.rid = rid;
2N/A
2N/A (void) pthread_mutex_lock(&idmap_cache.sid2uid_gid.mutex);
2N/A
2N/A result = avl_find(&idmap_cache.sid2uid_gid.tree, &entry, &where);
2N/A if (result != NULL) {
2N/A list_move(&idmap_cache.sid2uid_gid.head, result);
2N/A if (result->is_user != UNDEF_ISUSER) {
2N/A *is_user = result->is_user;
2N/A if (result->is_user && result->uid_ttl > now) {
2N/A *pid = result->uid;
2N/A status = IDMAP_SUCCESS;
2N/A } else if (!result->is_user && result->gid_ttl > now) {
2N/A *pid = result->gid;
2N/A status = IDMAP_SUCCESS;
2N/A }
2N/A }
2N/A }
2N/A
2N/A (void) pthread_mutex_unlock(&idmap_cache.sid2uid_gid.mutex);
2N/A
2N/A return (status);
2N/A}
2N/A
2N/A
2N/A
2N/Aidmap_stat
2N/Aidmap_cache_lookup_sidbyuid(char **sid_prefix,
2N/A idmap_rid_t *rid, uid_t uid)
2N/A{
2N/A pid2sid_winname_t entry;
2N/A pid2sid_winname_t *result;
2N/A avl_index_t where;
2N/A int status = IDMAP_ERR_NOMAPPING;
2N/A time_t now = time(NULL);
2N/A
2N/A entry.pid = uid;
2N/A
2N/A (void) pthread_mutex_lock(&idmap_cache.uid2sid_winname.mutex);
2N/A
2N/A result = avl_find(&idmap_cache.uid2sid_winname.tree, &entry, &where);
2N/A if (result != NULL) {
2N/A list_move(&idmap_cache.uid2sid_winname.head, result);
2N/A if (result->sid_ttl > now) {
2N/A *rid = result->rid;
2N/A *sid_prefix = strdup(result->sid_prefix);
2N/A if (*sid_prefix != NULL)
2N/A status = IDMAP_SUCCESS;
2N/A else
2N/A status = IDMAP_ERR_MEMORY;
2N/A }
2N/A }
2N/A
2N/A (void) pthread_mutex_unlock(&idmap_cache.uid2sid_winname.mutex);
2N/A
2N/A return (status);
2N/A}
2N/A
2N/Aidmap_stat
2N/Aidmap_cache_lookup_sidbygid(char **sid_prefix,
2N/A idmap_rid_t *rid, gid_t gid)
2N/A{
2N/A pid2sid_winname_t entry;
2N/A pid2sid_winname_t *result;
2N/A avl_index_t where;
2N/A int status = IDMAP_ERR_NOMAPPING;
2N/A time_t now = time(NULL);
2N/A
2N/A entry.pid = gid;
2N/A
2N/A (void) pthread_mutex_lock(&idmap_cache.gid2sid_winname.mutex);
2N/A
2N/A result = avl_find(&idmap_cache.gid2sid_winname.tree, &entry, &where);
2N/A if (result != NULL) {
2N/A list_move(&idmap_cache.gid2sid_winname.head, result);
2N/A if (result->sid_ttl > now) {
2N/A *rid = result->rid;
2N/A *sid_prefix = strdup(result->sid_prefix);
2N/A if (*sid_prefix != NULL)
2N/A status = IDMAP_SUCCESS;
2N/A else
2N/A status = IDMAP_ERR_MEMORY;
2N/A }
2N/A }
2N/A
2N/A (void) pthread_mutex_unlock(&idmap_cache.gid2sid_winname.mutex);
2N/A
2N/A return (status);
2N/A}
2N/A
2N/A
2N/Aidmap_stat
2N/Aidmap_cache_lookup_winnamebyuid(char **name, char **domain, uid_t uid)
2N/A{
2N/A pid2sid_winname_t entry;
2N/A pid2sid_winname_t *result;
2N/A avl_index_t where;
2N/A int status = IDMAP_ERR_NOMAPPING;
2N/A time_t now = time(NULL);
2N/A
2N/A entry.pid = uid;
2N/A
2N/A (void) pthread_mutex_lock(&idmap_cache.uid2sid_winname.mutex);
2N/A
2N/A result = avl_find(&idmap_cache.uid2sid_winname.tree, &entry, &where);
2N/A if (result != NULL) {
2N/A list_move(&idmap_cache.uid2sid_winname.head, result);
2N/A if (result->winname_ttl > now) {
2N/A *name = strdup(result->winname);
2N/A if (*name != NULL) {
2N/A if (domain != NULL) {
2N/A if (result->windomain != NULL) {
2N/A *domain =
2N/A strdup(result->windomain);
2N/A if (*domain != NULL)
2N/A status = IDMAP_SUCCESS;
2N/A else
2N/A status =
2N/A IDMAP_ERR_MEMORY;
2N/A } else {
2N/A *domain = NULL;
2N/A status = IDMAP_SUCCESS;
2N/A }
2N/A } else
2N/A status = IDMAP_SUCCESS;
2N/A } else
2N/A status = IDMAP_ERR_MEMORY;
2N/A }
2N/A }
2N/A
2N/A (void) pthread_mutex_unlock(&idmap_cache.uid2sid_winname.mutex);
2N/A
2N/A return (status);
2N/A}
2N/A
2N/A
2N/Aidmap_stat
2N/Aidmap_cache_lookup_winnamebygid(char **name, char **domain, gid_t gid)
2N/A{
2N/A pid2sid_winname_t entry;
2N/A pid2sid_winname_t *result;
2N/A avl_index_t where;
2N/A int status = IDMAP_ERR_NOMAPPING;
2N/A time_t now = time(NULL);
2N/A
2N/A entry.pid = gid;
2N/A
2N/A (void) pthread_mutex_lock(&idmap_cache.gid2sid_winname.mutex);
2N/A
2N/A result = avl_find(&idmap_cache.gid2sid_winname.tree, &entry, &where);
2N/A if (result != NULL) {
2N/A list_move(&idmap_cache.gid2sid_winname.head, result);
2N/A if (result->winname_ttl > now) {
2N/A *name = strdup(result->winname);
2N/A if (*name != NULL) {
2N/A if (domain != NULL) {
2N/A if (result->windomain != NULL) {
2N/A *domain =
2N/A strdup(result->windomain);
2N/A if (*domain != NULL)
2N/A status = IDMAP_SUCCESS;
2N/A else
2N/A status =
2N/A IDMAP_ERR_MEMORY;
2N/A } else {
2N/A *domain = NULL;
2N/A status = IDMAP_SUCCESS;
2N/A }
2N/A } else
2N/A status = IDMAP_SUCCESS;
2N/A } else
2N/A status = IDMAP_ERR_MEMORY;
2N/A }
2N/A }
2N/A
2N/A (void) pthread_mutex_unlock(&idmap_cache.gid2sid_winname.mutex);
2N/A
2N/A return (status);
2N/A}
2N/A
2N/A
2N/Aidmap_stat
2N/Aidmap_cache_lookup_uidbywinname(const char *name, const char *domain,
2N/A uid_t *uid)
2N/A{
2N/A winname2uid_gid_t entry;
2N/A winname2uid_gid_t *result;
2N/A avl_index_t where;
2N/A int status = IDMAP_ERR_NOMAPPING;
2N/A time_t now = time(NULL);
2N/A
2N/A entry.winname = name;
2N/A entry.windomain = domain;
2N/A
2N/A (void) pthread_mutex_lock(&idmap_cache.winname2uid_gid.mutex);
2N/A
2N/A result = avl_find(&idmap_cache.winname2uid_gid.tree, &entry, &where);
2N/A if (result != NULL) {
2N/A list_move(&idmap_cache.winname2uid_gid.head, result);
2N/A if (result->uid != UNDEF_UID && result->uid_ttl > now) {
2N/A *uid = result->uid;
2N/A status = IDMAP_SUCCESS;
2N/A }
2N/A }
2N/A
2N/A (void) pthread_mutex_unlock(&idmap_cache.winname2uid_gid.mutex);
2N/A
2N/A return (status);
2N/A}
2N/A
2N/A
2N/Aidmap_stat
2N/Aidmap_cache_lookup_gidbywinname(const char *name, const char *domain,
2N/A gid_t *gid)
2N/A{
2N/A winname2uid_gid_t entry;
2N/A winname2uid_gid_t *result;
2N/A avl_index_t where;
2N/A int status = IDMAP_ERR_NOMAPPING;
2N/A time_t now = time(NULL);
2N/A
2N/A entry.winname = name;
2N/A entry.windomain = domain;
2N/A
2N/A (void) pthread_mutex_lock(&idmap_cache.winname2uid_gid.mutex);
2N/A
2N/A result = avl_find(&idmap_cache.winname2uid_gid.tree, &entry, &where);
2N/A if (result != NULL) {
2N/A list_move(&idmap_cache.winname2uid_gid.head, result);
2N/A if (result->gid != UNDEF_GID && result->gid_ttl > now) {
2N/A *gid = result->gid;
2N/A status = IDMAP_SUCCESS;
2N/A }
2N/A }
2N/A
2N/A (void) pthread_mutex_unlock(&idmap_cache.winname2uid_gid.mutex);
2N/A
2N/A return (status);
2N/A}
2N/A
2N/A
2N/Avoid
2N/Aidmap_cache_add_sid2uid(const char *sid_prefix,
2N/A idmap_rid_t rid, uid_t uid, int direction)
2N/A
2N/A{
2N/A avl_index_t where;
2N/A time_t ttl = CACHE_TTL + time(NULL);
2N/A
2N/A
2N/A if (direction == IDMAP_DIRECTION_BI ||
2N/A direction == IDMAP_DIRECTION_W2U) {
2N/A sid2uid_gid_t find;
2N/A sid2uid_gid_t *result;
2N/A sid2uid_gid_t *new;
2N/A
2N/A find.sid_prefix = sid_prefix;
2N/A find.rid = rid;
2N/A
2N/A (void) pthread_mutex_lock(&idmap_cache.sid2uid_gid.mutex);
2N/A result = avl_find(&idmap_cache.sid2uid_gid.tree, &find, &where);
2N/A
2N/A if (result) {
2N/A if (result->uid_ttl == 0)
2N/A idmap_cache.sid2uid_gid.uid_num++;
2N/A result->uid = uid;
2N/A result->uid_ttl = ttl;
2N/A } else {
2N/A new = malloc(sizeof (sid2uid_gid_t));
2N/A if (new == NULL)
2N/A goto exit_sid2uid_gid;
2N/A new->sid_prefix = strdup(sid_prefix);
2N/A if (new->sid_prefix == NULL) {
2N/A free(new);
2N/A goto exit_sid2uid_gid;
2N/A }
2N/A new->rid = rid;
2N/A new->uid = uid;
2N/A new->uid_ttl = ttl;
2N/A new->gid = UNDEF_GID;
2N/A new->gid_ttl = 0;
2N/A new->is_user = UNDEF_ISUSER; /* Unknown */
2N/A idmap_cache.sid2uid_gid.uid_num++;
2N/A
2N/A list_insert(&idmap_cache.sid2uid_gid.head, new);
2N/A avl_insert(&idmap_cache.sid2uid_gid.tree, new, where);
2N/A }
2N/A if ((avl_numnodes(&idmap_cache.sid2uid_gid.tree) >
2N/A CACHE_UID_GID_TRIGGER_SIZE) &&
2N/A (idmap_cache.sid2uid_gid.purge_time + CACHE_PURGE_INTERVAL <
2N/A time(NULL)))
2N/A idmap_purge_sid2uid_gid_cache(&idmap_cache.sid2uid_gid,
2N/A CACHE_UID_GID_TRIGGER_SIZE);
2N/A
2N/Aexit_sid2uid_gid:
2N/A (void) pthread_mutex_unlock(&idmap_cache.sid2uid_gid.mutex);
2N/A }
2N/A
2N/A if (direction == IDMAP_DIRECTION_BI ||
2N/A direction == IDMAP_DIRECTION_U2W) {
2N/A pid2sid_winname_t find;
2N/A pid2sid_winname_t *result;
2N/A pid2sid_winname_t *new;
2N/A
2N/A find.pid = uid;
2N/A
2N/A (void) pthread_mutex_lock(&idmap_cache.uid2sid_winname.mutex);
2N/A result = avl_find(&idmap_cache.uid2sid_winname.tree, &find,
2N/A &where);
2N/A
2N/A if (result) {
2N/A if (update_str(&result->sid_prefix, sid_prefix) != 0)
2N/A goto exit_pid2sid_winname;
2N/A if (result->sid_ttl == 0)
2N/A idmap_cache.uid2sid_winname.sid_num++;
2N/A result->rid = rid;
2N/A result->sid_ttl = ttl;
2N/A } else {
2N/A new = malloc(sizeof (pid2sid_winname_t));
2N/A if (new == NULL)
2N/A goto exit_pid2sid_winname;
2N/A new->pid = uid;
2N/A new->sid_prefix = strdup(sid_prefix);
2N/A if (new->sid_prefix == NULL) {
2N/A free(new);
2N/A goto exit_pid2sid_winname;
2N/A }
2N/A new->rid = rid;
2N/A new->sid_ttl = ttl;
2N/A new->winname = NULL;
2N/A new->windomain = NULL;
2N/A new->winname_ttl = 0;
2N/A idmap_cache.uid2sid_winname.sid_num ++;
2N/A
2N/A list_insert(&idmap_cache.uid2sid_winname.head, new);
2N/A avl_insert(&idmap_cache.uid2sid_winname.tree, new,
2N/A where);
2N/A }
2N/A if ((avl_numnodes(&idmap_cache.uid2sid_winname.tree) >
2N/A CACHE_UID_TRIGGER_SIZE) &&
2N/A (idmap_cache.uid2sid_winname.purge_time +
2N/A CACHE_PURGE_INTERVAL < time(NULL)))
2N/A idmap_purge_pid2sid_winname_cache(
2N/A &idmap_cache.uid2sid_winname,
2N/A CACHE_UID_TRIGGER_SIZE);
2N/A
2N/A
2N/Aexit_pid2sid_winname:
2N/A (void) pthread_mutex_unlock(&idmap_cache.uid2sid_winname.mutex);
2N/A }
2N/A}
2N/A
2N/A
2N/A
2N/Avoid
2N/Aidmap_cache_add_sid2gid(const char *sid_prefix,
2N/A idmap_rid_t rid, gid_t gid, int direction)
2N/A{
2N/A avl_index_t where;
2N/A time_t ttl = CACHE_TTL + time(NULL);
2N/A
2N/A
2N/A if (direction == IDMAP_DIRECTION_BI ||
2N/A direction == IDMAP_DIRECTION_W2U) {
2N/A sid2uid_gid_t find;
2N/A sid2uid_gid_t *result;
2N/A sid2uid_gid_t *new;
2N/A
2N/A find.sid_prefix = sid_prefix;
2N/A find.rid = rid;
2N/A
2N/A (void) pthread_mutex_lock(&idmap_cache.sid2uid_gid.mutex);
2N/A result = avl_find(&idmap_cache.sid2uid_gid.tree, &find, &where);
2N/A
2N/A if (result) {
2N/A if (result->gid_ttl == 0)
2N/A idmap_cache.sid2uid_gid.gid_num++;
2N/A result->gid = gid;
2N/A result->gid_ttl = ttl;
2N/A } else {
2N/A new = malloc(sizeof (sid2uid_gid_t));
2N/A if (new == NULL)
2N/A goto exit_sid2uid_gid;
2N/A new->sid_prefix = strdup(sid_prefix);
2N/A if (new->sid_prefix == NULL) {
2N/A free(new);
2N/A goto exit_sid2uid_gid;
2N/A }
2N/A new->rid = rid;
2N/A new->uid = UNDEF_UID;
2N/A new->uid_ttl = 0;
2N/A new->gid = gid;
2N/A new->gid_ttl = ttl;
2N/A new->is_user = UNDEF_ISUSER; /* Unknown */
2N/A idmap_cache.sid2uid_gid.gid_num++;
2N/A
2N/A list_insert(&idmap_cache.sid2uid_gid.head, new);
2N/A avl_insert(&idmap_cache.sid2uid_gid.tree, new, where);
2N/A }
2N/A if ((avl_numnodes(&idmap_cache.sid2uid_gid.tree) >
2N/A CACHE_UID_GID_TRIGGER_SIZE) &&
2N/A (idmap_cache.sid2uid_gid.purge_time + CACHE_PURGE_INTERVAL <
2N/A time(NULL)))
2N/A idmap_purge_sid2uid_gid_cache(&idmap_cache.sid2uid_gid,
2N/A CACHE_UID_GID_TRIGGER_SIZE);
2N/A
2N/Aexit_sid2uid_gid:
2N/A (void) pthread_mutex_unlock(&idmap_cache.sid2uid_gid.mutex);
2N/A }
2N/A
2N/A if (direction == IDMAP_DIRECTION_BI ||
2N/A direction == IDMAP_DIRECTION_U2W) {
2N/A pid2sid_winname_t find;
2N/A pid2sid_winname_t *result;
2N/A pid2sid_winname_t *new;
2N/A
2N/A find.pid = gid;
2N/A
2N/A (void) pthread_mutex_lock(&idmap_cache.gid2sid_winname.mutex);
2N/A result = avl_find(&idmap_cache.gid2sid_winname.tree, &find,
2N/A &where);
2N/A
2N/A if (result) {
2N/A if (update_str(&result->sid_prefix, sid_prefix) != 0)
2N/A goto exit_gid2sid_winname;
2N/A if (result->sid_ttl == 0)
2N/A idmap_cache.gid2sid_winname.sid_num++;
2N/A result->rid = rid;
2N/A result->sid_ttl = ttl;
2N/A } else {
2N/A new = malloc(sizeof (pid2sid_winname_t));
2N/A if (new == NULL)
2N/A goto exit_gid2sid_winname;
2N/A new->sid_prefix = strdup(sid_prefix);
2N/A if (new->sid_prefix == NULL) {
2N/A free(new);
2N/A goto exit_gid2sid_winname;
2N/A }
2N/A new->rid = rid;
2N/A new->pid = gid;
2N/A new->sid_ttl = ttl;
2N/A new->winname = NULL;
2N/A new->windomain = NULL;
2N/A new->winname_ttl = 0;
2N/A idmap_cache.gid2sid_winname.sid_num++;
2N/A
2N/A list_insert(&idmap_cache.gid2sid_winname.head, new);
2N/A avl_insert(&idmap_cache.gid2sid_winname.tree, new,
2N/A where);
2N/A }
2N/A if ((avl_numnodes(&idmap_cache.gid2sid_winname.tree) >
2N/A CACHE_GID_TRIGGER_SIZE) &&
2N/A (idmap_cache.gid2sid_winname.purge_time +
2N/A CACHE_PURGE_INTERVAL < time(NULL)))
2N/A idmap_purge_pid2sid_winname_cache(
2N/A &idmap_cache.gid2sid_winname,
2N/A CACHE_GID_TRIGGER_SIZE);
2N/A
2N/Aexit_gid2sid_winname:
2N/A (void) pthread_mutex_unlock(&idmap_cache.gid2sid_winname.mutex);
2N/A }
2N/A}
2N/A
2N/A
2N/Avoid
2N/Aidmap_cache_add_sid2pid(const char *sid_prefix,
2N/A idmap_rid_t rid, uid_t pid, int is_user, int direction)
2N/A{
2N/A avl_index_t where;
2N/A time_t ttl = CACHE_TTL + time(NULL);
2N/A
2N/A
2N/A if (direction == IDMAP_DIRECTION_BI ||
2N/A direction == IDMAP_DIRECTION_W2U) {
2N/A sid2uid_gid_t find;
2N/A sid2uid_gid_t *result;
2N/A sid2uid_gid_t *new;
2N/A
2N/A find.sid_prefix = sid_prefix;
2N/A find.rid = rid;
2N/A
2N/A (void) pthread_mutex_lock(&idmap_cache.sid2uid_gid.mutex);
2N/A result = avl_find(&idmap_cache.sid2uid_gid.tree, &find, &where);
2N/A
2N/A if (result) {
2N/A if (result->is_user == UNDEF_ISUSER)
2N/A idmap_cache.sid2uid_gid.pid_num++;
2N/A result->is_user = is_user;
2N/A if (is_user) {
2N/A if (result->uid_ttl == 0)
2N/A idmap_cache.sid2uid_gid.uid_num++;
2N/A result->uid = pid;
2N/A result->uid_ttl = ttl;
2N/A } else {
2N/A if (result->gid_ttl == 0)
2N/A idmap_cache.sid2uid_gid.gid_num++;
2N/A result->gid = pid;
2N/A result->gid_ttl = ttl;
2N/A }
2N/A } else {
2N/A new = malloc(sizeof (sid2uid_gid_t));
2N/A if (new == NULL)
2N/A goto exit_sid2uid_gid;
2N/A new->sid_prefix = strdup(sid_prefix);
2N/A if (new->sid_prefix == NULL) {
2N/A free(new);
2N/A goto exit_sid2uid_gid;
2N/A }
2N/A new->rid = rid;
2N/A new->is_user = is_user;
2N/A if (is_user) {
2N/A new->uid = pid;
2N/A new->uid_ttl = ttl;
2N/A new->gid = UNDEF_GID;
2N/A new->gid_ttl = 0;
2N/A idmap_cache.sid2uid_gid.uid_num++;
2N/A } else {
2N/A new->uid = UNDEF_UID;
2N/A new->uid_ttl = 0;
2N/A new->gid = pid;
2N/A new->gid_ttl = ttl;
2N/A idmap_cache.sid2uid_gid.gid_num++;
2N/A }
2N/A idmap_cache.sid2uid_gid.pid_num++;
2N/A
2N/A list_insert(&idmap_cache.sid2uid_gid.head, new);
2N/A avl_insert(&idmap_cache.sid2uid_gid.tree, new, where);
2N/A }
2N/A if ((avl_numnodes(&idmap_cache.sid2uid_gid.tree) >
2N/A CACHE_UID_GID_TRIGGER_SIZE) &&
2N/A (idmap_cache.sid2uid_gid.purge_time + CACHE_PURGE_INTERVAL <
2N/A time(NULL)))
2N/A idmap_purge_sid2uid_gid_cache(&idmap_cache.sid2uid_gid,
2N/A CACHE_UID_GID_TRIGGER_SIZE);
2N/A
2N/Aexit_sid2uid_gid:
2N/A (void) pthread_mutex_unlock(&idmap_cache.sid2uid_gid.mutex);
2N/A }
2N/A
2N/A if (direction == IDMAP_DIRECTION_BI ||
2N/A direction == IDMAP_DIRECTION_U2W) {
2N/A pid2sid_winname_t find;
2N/A pid2sid_winname_t *result;
2N/A pid2sid_winname_t *new;
2N/A
2N/A find.pid = pid;
2N/A if (is_user) {
2N/A (void) pthread_mutex_lock(
2N/A &idmap_cache.uid2sid_winname.mutex);
2N/A result = avl_find(&idmap_cache.uid2sid_winname.tree,
2N/A &find, &where);
2N/A
2N/A if (result) {
2N/A if (update_str(&result->sid_prefix, sid_prefix)
2N/A != 0)
2N/A goto exit_uid2sid_winname;
2N/A if (result->sid_ttl == 0)
2N/A idmap_cache.uid2sid_winname.sid_num++;
2N/A result->rid = rid;
2N/A result->sid_ttl = ttl;
2N/A } else {
2N/A new = malloc(sizeof (pid2sid_winname_t));
2N/A if (new == NULL)
2N/A goto exit_uid2sid_winname;
2N/A new->sid_prefix = strdup(sid_prefix);
2N/A if (new->sid_prefix == NULL) {
2N/A free(new);
2N/A goto exit_uid2sid_winname;
2N/A }
2N/A new->rid = rid;
2N/A new->pid = pid;
2N/A new->sid_ttl = ttl;
2N/A new->winname = NULL;
2N/A new->windomain = NULL;
2N/A idmap_cache.uid2sid_winname.sid_num++;
2N/A
2N/A list_insert(&idmap_cache.uid2sid_winname.head,
2N/A new);
2N/A avl_insert(&idmap_cache.uid2sid_winname.tree,
2N/A new, where);
2N/A }
2N/A if ((avl_numnodes(&idmap_cache.uid2sid_winname.tree) >
2N/A CACHE_UID_TRIGGER_SIZE) &&
2N/A (idmap_cache.uid2sid_winname.purge_time +
2N/A CACHE_PURGE_INTERVAL < time(NULL)))
2N/A idmap_purge_pid2sid_winname_cache(
2N/A &idmap_cache.uid2sid_winname,
2N/A CACHE_UID_TRIGGER_SIZE);
2N/A
2N/Aexit_uid2sid_winname:
2N/A (void) pthread_mutex_unlock(
2N/A &idmap_cache.uid2sid_winname.mutex);
2N/A } else {
2N/A (void) pthread_mutex_lock(
2N/A &idmap_cache.gid2sid_winname.mutex);
2N/A result = avl_find(&idmap_cache.gid2sid_winname.tree,
2N/A &find, &where);
2N/A
2N/A if (result) {
2N/A if (update_str(&result->sid_prefix, sid_prefix)
2N/A != 0)
2N/A goto exit_gid2sid_winname;
2N/A if (result->sid_ttl == 0)
2N/A idmap_cache.gid2sid_winname.sid_num++;
2N/A result->rid = rid;
2N/A result->sid_ttl = ttl;
2N/A } else {
2N/A new = malloc(sizeof (pid2sid_winname_t));
2N/A if (new == NULL)
2N/A goto exit_gid2sid_winname;
2N/A new->sid_prefix = strdup(sid_prefix);
2N/A if (new->sid_prefix == NULL) {
2N/A free(new);
2N/A goto exit_gid2sid_winname;
2N/A }
2N/A new->rid = rid;
2N/A new->pid = pid;
2N/A new->sid_ttl = ttl;
2N/A new->winname = NULL;
2N/A new->windomain = NULL;
2N/A idmap_cache.gid2sid_winname.sid_num++;
2N/A
2N/A list_insert(&idmap_cache.gid2sid_winname.head,
2N/A new);
2N/A avl_insert(&idmap_cache.gid2sid_winname.tree,
2N/A new, where);
2N/A }
2N/A if ((avl_numnodes(&idmap_cache.gid2sid_winname.tree) >
2N/A CACHE_GID_TRIGGER_SIZE) &&
2N/A (idmap_cache.gid2sid_winname.purge_time +
2N/A CACHE_PURGE_INTERVAL < time(NULL)))
2N/A idmap_purge_pid2sid_winname_cache(
2N/A &idmap_cache.gid2sid_winname,
2N/A CACHE_GID_TRIGGER_SIZE);
2N/Aexit_gid2sid_winname:
2N/A (void) pthread_mutex_unlock(
2N/A &idmap_cache.gid2sid_winname.mutex);
2N/A }
2N/A }
2N/A}
2N/A
2N/A
2N/A
2N/Avoid
2N/Aidmap_cache_add_winname2uid(const char *name, const char *domain, uid_t uid,
2N/A int direction)
2N/A{
2N/A avl_index_t where;
2N/A time_t ttl = CACHE_TTL + time(NULL);
2N/A
2N/A
2N/A if (direction == IDMAP_DIRECTION_BI ||
2N/A direction == IDMAP_DIRECTION_W2U) {
2N/A winname2uid_gid_t find;
2N/A winname2uid_gid_t *result;
2N/A winname2uid_gid_t *new;
2N/A
2N/A find.winname = name;
2N/A find.windomain = domain;
2N/A
2N/A (void) pthread_mutex_lock(&idmap_cache.winname2uid_gid.mutex);
2N/A result = avl_find(&idmap_cache.winname2uid_gid.tree, &find,
2N/A &where);
2N/A
2N/A if (result) {
2N/A if (result->uid_ttl == 0)
2N/A idmap_cache.winname2uid_gid.uid_num++;
2N/A result->uid = uid;
2N/A result->uid_ttl = ttl;
2N/A } else {
2N/A new = malloc(sizeof (winname2uid_gid_t));
2N/A if (new == NULL)
2N/A goto exit_winname2uid_gid;
2N/A new->winname = strdup(name);
2N/A if (new->winname == NULL) {
2N/A free(new);
2N/A goto exit_winname2uid_gid;
2N/A }
2N/A if (domain != NULL) {
2N/A new->windomain = strdup(domain);
2N/A if (new->winname == NULL) {
2N/A free((char *)new->winname);
2N/A free(new);
2N/A goto exit_winname2uid_gid;
2N/A }
2N/A } else
2N/A new->windomain = NULL;
2N/A new->uid = uid;
2N/A new->uid_ttl = ttl;
2N/A new->gid = UNDEF_GID;
2N/A new->gid_ttl = 0;
2N/A idmap_cache.winname2uid_gid.uid_num++;
2N/A
2N/A list_insert(&idmap_cache.winname2uid_gid.head, new);
2N/A avl_insert(&idmap_cache.winname2uid_gid.tree, new,
2N/A where);
2N/A }
2N/A if ((avl_numnodes(&idmap_cache.winname2uid_gid.tree) >
2N/A CACHE_UID_GID_TRIGGER_SIZE) &&
2N/A (idmap_cache.winname2uid_gid.purge_time +
2N/A CACHE_PURGE_INTERVAL < time(NULL)))
2N/A idmap_purge_winname2uid_gid_cache(
2N/A &idmap_cache.winname2uid_gid,
2N/A CACHE_UID_GID_TRIGGER_SIZE);
2N/Aexit_winname2uid_gid:
2N/A (void) pthread_mutex_unlock(&idmap_cache.winname2uid_gid.mutex);
2N/A }
2N/A
2N/A if (direction == IDMAP_DIRECTION_BI ||
2N/A direction == IDMAP_DIRECTION_U2W) {
2N/A pid2sid_winname_t find;
2N/A pid2sid_winname_t *result;
2N/A pid2sid_winname_t *new;
2N/A
2N/A find.pid = uid;
2N/A
2N/A (void) pthread_mutex_lock(&idmap_cache.uid2sid_winname.mutex);
2N/A result = avl_find(&idmap_cache.uid2sid_winname.tree, &find,
2N/A &where);
2N/A
2N/A if (result) {
2N/A if (update_str(&result->winname, name) != 0)
2N/A goto exit_uid2sid_winname;
2N/A if (update_str(&result->windomain, domain) != 0)
2N/A goto exit_uid2sid_winname;
2N/A if (result->winname_ttl == 0)
2N/A idmap_cache.uid2sid_winname.winname_num++;
2N/A result->winname_ttl = ttl;
2N/A } else {
2N/A new = malloc(sizeof (pid2sid_winname_t));
2N/A if (new == NULL)
2N/A goto exit_uid2sid_winname;
2N/A new->pid = uid;
2N/A new->winname = strdup(name);
2N/A if (new->winname == NULL) {
2N/A free(new);
2N/A goto exit_uid2sid_winname;
2N/A }
2N/A if (domain != NULL) {
2N/A new->windomain = strdup(domain);
2N/A if (new->windomain == NULL) {
2N/A free((char *)new->winname);
2N/A free(new);
2N/A goto exit_uid2sid_winname;
2N/A }
2N/A } else
2N/A new->windomain = NULL;
2N/A new->winname_ttl = ttl;
2N/A new->sid_prefix = NULL;
2N/A new->rid = 0;
2N/A new->sid_ttl = 0;
2N/A idmap_cache.uid2sid_winname.winname_num ++;
2N/A
2N/A list_insert(&idmap_cache.uid2sid_winname.head, new);
2N/A avl_insert(&idmap_cache.uid2sid_winname.tree, new,
2N/A where);
2N/A }
2N/A if ((avl_numnodes(&idmap_cache.uid2sid_winname.tree) >
2N/A CACHE_UID_TRIGGER_SIZE) &&
2N/A (idmap_cache.uid2sid_winname.purge_time +
2N/A CACHE_PURGE_INTERVAL < time(NULL)))
2N/A idmap_purge_pid2sid_winname_cache(
2N/A &idmap_cache.uid2sid_winname,
2N/A CACHE_UID_TRIGGER_SIZE);
2N/Aexit_uid2sid_winname:
2N/A (void) pthread_mutex_unlock(&idmap_cache.uid2sid_winname.mutex);
2N/A }
2N/A}
2N/A
2N/A
2N/A
2N/A
2N/A
2N/Avoid
2N/Aidmap_cache_add_winname2gid(const char *name, const char *domain, gid_t gid,
2N/A int direction)
2N/A{
2N/A avl_index_t where;
2N/A time_t ttl = CACHE_TTL + time(NULL);
2N/A
2N/A
2N/A if (direction == IDMAP_DIRECTION_BI ||
2N/A direction == IDMAP_DIRECTION_W2U) {
2N/A winname2uid_gid_t find;
2N/A winname2uid_gid_t *result;
2N/A winname2uid_gid_t *new;
2N/A
2N/A find.winname = name;
2N/A find.windomain = domain;
2N/A
2N/A (void) pthread_mutex_lock(&idmap_cache.winname2uid_gid.mutex);
2N/A result = avl_find(&idmap_cache.winname2uid_gid.tree, &find,
2N/A &where);
2N/A
2N/A if (result) {
2N/A if (result->uid_ttl == 0)
2N/A idmap_cache.winname2uid_gid.gid_num++;
2N/A result->gid = gid;
2N/A result->gid_ttl = ttl;
2N/A } else {
2N/A new = malloc(sizeof (winname2uid_gid_t));
2N/A if (new == NULL)
2N/A goto exit_winname2uid_gid;
2N/A new->winname = strdup(name);
2N/A if (new->winname == NULL) {
2N/A free(new);
2N/A goto exit_winname2uid_gid;
2N/A }
2N/A if (domain != NULL) {
2N/A new->windomain = strdup(domain);
2N/A if (new->windomain == NULL) {
2N/A free((char *)new->winname);
2N/A free(new);
2N/A goto exit_winname2uid_gid;
2N/A }
2N/A }
2N/A else
2N/A new->windomain = NULL;
2N/A new->uid = UNDEF_UID;
2N/A new->uid_ttl = 0;
2N/A new->gid = gid;
2N/A new->gid_ttl = ttl;
2N/A idmap_cache.winname2uid_gid.gid_num++;
2N/A
2N/A list_insert(&idmap_cache.winname2uid_gid.head, new);
2N/A avl_insert(&idmap_cache.winname2uid_gid.tree, new,
2N/A where);
2N/A }
2N/A if ((avl_numnodes(&idmap_cache.winname2uid_gid.tree) >
2N/A CACHE_UID_GID_TRIGGER_SIZE) &&
2N/A (idmap_cache.winname2uid_gid.purge_time +
2N/A CACHE_PURGE_INTERVAL < time(NULL)))
2N/A idmap_purge_winname2uid_gid_cache(
2N/A &idmap_cache.winname2uid_gid,
2N/A CACHE_UID_GID_TRIGGER_SIZE);
2N/Aexit_winname2uid_gid:
2N/A (void) pthread_mutex_unlock(&idmap_cache.winname2uid_gid.mutex);
2N/A }
2N/A
2N/A if (direction == IDMAP_DIRECTION_BI ||
2N/A direction == IDMAP_DIRECTION_U2W) {
2N/A pid2sid_winname_t find;
2N/A pid2sid_winname_t *result;
2N/A pid2sid_winname_t *new;
2N/A
2N/A find.pid = gid;
2N/A
2N/A (void) pthread_mutex_lock(&idmap_cache.gid2sid_winname.mutex);
2N/A result = avl_find(&idmap_cache.gid2sid_winname.tree, &find,
2N/A &where);
2N/A
2N/A if (result) {
2N/A if (update_str(&result->winname, name) != 0)
2N/A goto exit_gid2sid_winname;
2N/A if (update_str(&result->windomain, domain) != 0)
2N/A goto exit_gid2sid_winname;
2N/A if (result->winname_ttl == 0)
2N/A idmap_cache.gid2sid_winname.winname_num++;
2N/A result->winname_ttl = ttl;
2N/A } else {
2N/A new = malloc(sizeof (pid2sid_winname_t));
2N/A if (new == NULL)
2N/A goto exit_gid2sid_winname;
2N/A new->pid = gid;
2N/A new->winname = strdup(name);
2N/A if (new->winname == NULL) {
2N/A free(new);
2N/A goto exit_gid2sid_winname;
2N/A }
2N/A if (domain != NULL) {
2N/A new->windomain = strdup(domain);
2N/A if (new->windomain == NULL) {
2N/A free((char *)new->winname);
2N/A free(new);
2N/A goto exit_gid2sid_winname;
2N/A }
2N/A }
2N/A else
2N/A new->windomain = NULL;
2N/A new->winname_ttl = ttl;
2N/A new->sid_prefix = NULL;
2N/A new->rid = 0;
2N/A new->sid_ttl = 0;
2N/A idmap_cache.gid2sid_winname.winname_num ++;
2N/A
2N/A list_insert(&idmap_cache.gid2sid_winname.head, new);
2N/A avl_insert(&idmap_cache.gid2sid_winname.tree, new,
2N/A where);
2N/A }
2N/A if ((avl_numnodes(&idmap_cache.gid2sid_winname.tree) >
2N/A CACHE_UID_TRIGGER_SIZE) &&
2N/A (idmap_cache.gid2sid_winname.purge_time +
2N/A CACHE_PURGE_INTERVAL < time(NULL)))
2N/A idmap_purge_pid2sid_winname_cache(
2N/A &idmap_cache.gid2sid_winname,
2N/A CACHE_UID_TRIGGER_SIZE);
2N/Aexit_gid2sid_winname:
2N/A (void) pthread_mutex_unlock(&idmap_cache.gid2sid_winname.mutex);
2N/A }
2N/A}
2N/A
2N/A
2N/Astatic void
2N/Aidmap_purge_sid2uid_gid_cache(sid2uid_gid_cache_t *cache, size_t limit)
2N/A{
2N/A time_t now = time(NULL);
2N/A sid2uid_gid_t *item;
2N/A
2N/A while (avl_numnodes(&cache->tree) > limit) {
2N/A /* Remove least recently used */
2N/A item = cache->head.blink;
2N/A list_remove(item);
2N/A avl_remove(&cache->tree, item);
2N/A if (item->uid_ttl != 0)
2N/A cache->uid_num--;
2N/A if (item->gid_ttl != 0)
2N/A cache->gid_num--;
2N/A if (item->is_user != UNDEF_ISUSER)
2N/A cache->pid_num--;
2N/A
2N/A if (item->sid_prefix)
2N/A free((char *)item->sid_prefix);
2N/A free(item);
2N/A }
2N/A cache->purge_time = now;
2N/A}
2N/A
2N/A
2N/Astatic void
2N/Aidmap_purge_winname2uid_gid_cache(winname2uid_gid_cache_t *cache, size_t limit)
2N/A{
2N/A time_t now = time(NULL);
2N/A winname2uid_gid_t *item;
2N/A
2N/A while (avl_numnodes(&cache->tree) > limit) {
2N/A /* Remove least recently used */
2N/A item = cache->head.blink;
2N/A list_remove(item);
2N/A avl_remove(&cache->tree, item);
2N/A if (item->uid_ttl != 0)
2N/A cache->uid_num--;
2N/A if (item->gid_ttl != 0)
2N/A cache->gid_num--;
2N/A
2N/A if (item->winname)
2N/A free((char *)item->winname);
2N/A if (item->windomain)
2N/A free((char *)item->windomain);
2N/A free(item);
2N/A }
2N/A cache->purge_time = now;
2N/A}
2N/A
2N/A
2N/Astatic void
2N/Aidmap_purge_pid2sid_winname_cache(pid2sid_winname_cache_t *cache, size_t limit)
2N/A{
2N/A time_t now = time(NULL);
2N/A pid2sid_winname_t *item;
2N/A
2N/A while (avl_numnodes(&cache->tree) > limit) {
2N/A /* Remove least recently used */
2N/A item = cache->head.blink;
2N/A list_remove(item);
2N/A avl_remove(&cache->tree, item);
2N/A if (item->winname_ttl != 0)
2N/A cache->winname_num--;
2N/A if (item->sid_ttl != 0)
2N/A cache->sid_num--;
2N/A
2N/A if (item->winname)
2N/A free((char *)item->winname);
2N/A if (item->windomain)
2N/A free((char *)item->windomain);
2N/A if (item->sid_prefix)
2N/A free((char *)item->sid_prefix);
2N/A free(item);
2N/A }
2N/A cache->purge_time = now;
2N/A}