summaryrefslogtreecommitdiff
path: root/source4/nsswitch/winbindd_cache.c
diff options
context:
space:
mode:
Diffstat (limited to 'source4/nsswitch/winbindd_cache.c')
-rw-r--r--source4/nsswitch/winbindd_cache.c1016
1 files changed, 0 insertions, 1016 deletions
diff --git a/source4/nsswitch/winbindd_cache.c b/source4/nsswitch/winbindd_cache.c
deleted file mode 100644
index 5fb59e7467..0000000000
--- a/source4/nsswitch/winbindd_cache.c
+++ /dev/null
@@ -1,1016 +0,0 @@
-/*
- Unix SMB/CIFS implementation.
-
- Winbind cache backend functions
-
- Copyright (C) Andrew Tridgell 2001
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-*/
-
-#include "winbindd.h"
-
-#undef DBGC_CLASS
-#define DBGC_CLASS DBGC_WINBIND
-
-struct winbind_cache {
- struct winbindd_methods *backend;
- TDB_CONTEXT *tdb;
-};
-
-struct cache_entry {
- NTSTATUS status;
- uint32 sequence_number;
- uint8 *data;
- uint32 len, ofs;
-};
-
-#define WINBINDD_MAX_CACHE_SIZE (50*1024*1024)
-
-static struct winbind_cache *wcache;
-
-/* flush the cache */
-void wcache_flush_cache(void)
-{
- extern BOOL opt_nocache;
-
- if (!wcache) return;
- if (wcache->tdb) {
- tdb_close(wcache->tdb);
- wcache->tdb = NULL;
- }
- if (opt_nocache) return;
-
- wcache->tdb = tdb_open_log(lock_path("winbindd_cache.tdb"), 5000,
- TDB_CLEAR_IF_FIRST, O_RDWR|O_CREAT, 0600);
-
- if (!wcache->tdb) {
- DEBUG(0,("Failed to open winbindd_cache.tdb!\n"));
- }
-}
-
-void winbindd_check_cache_size(time_t t)
-{
- static time_t last_check_time;
- struct stat st;
-
- if (last_check_time == (time_t)0)
- last_check_time = t;
-
- if (t - last_check_time < 60 && t - last_check_time > 0)
- return;
-
- if (wcache == NULL || wcache->tdb == NULL) {
- DEBUG(0, ("Unable to check size of tdb cache - cache not open !\n"));
- return;
- }
-
- if (fstat(wcache->tdb->fd, &st) == -1) {
- DEBUG(0, ("Unable to check size of tdb cache %s!\n", strerror(errno) ));
- return;
- }
-
- if (st.st_size > WINBINDD_MAX_CACHE_SIZE) {
- DEBUG(10,("flushing cache due to size (%lu) > (%lu)\n",
- (unsigned long)st.st_size,
- (unsigned long)WINBINDD_MAX_CACHE_SIZE));
- wcache_flush_cache();
- }
-}
-
-/* get the winbind_cache structure */
-static struct winbind_cache *get_cache(struct winbindd_domain *domain)
-{
- extern struct winbindd_methods msrpc_methods;
- struct winbind_cache *ret = wcache;
-
- if (ret) return ret;
-
- ret = smb_xmalloc(sizeof(*ret));
- ZERO_STRUCTP(ret);
- switch (lp_security()) {
-#ifdef HAVE_ADS
- case SEC_ADS: {
- extern struct winbindd_methods ads_methods;
- ret->backend = &ads_methods;
- break;
- }
-#endif
- default:
- ret->backend = &msrpc_methods;
- }
-
- wcache = ret;
- wcache_flush_cache();
-
- return ret;
-}
-
-/*
- free a centry structure
-*/
-static void centry_free(struct cache_entry *centry)
-{
- if (!centry) return;
- SAFE_FREE(centry->data);
- free(centry);
-}
-
-
-/*
- pull a uint32 from a cache entry
-*/
-static uint32 centry_uint32(struct cache_entry *centry)
-{
- uint32 ret;
- if (centry->len - centry->ofs < 4) {
- DEBUG(0,("centry corruption? needed 4 bytes, have %d\n",
- centry->len - centry->ofs));
- smb_panic("centry_uint32");
- }
- ret = IVAL(centry->data, centry->ofs);
- centry->ofs += 4;
- return ret;
-}
-
-/*
- pull a uint8 from a cache entry
-*/
-static uint8 centry_uint8(struct cache_entry *centry)
-{
- uint8 ret;
- if (centry->len - centry->ofs < 1) {
- DEBUG(0,("centry corruption? needed 1 bytes, have %d\n",
- centry->len - centry->ofs));
- smb_panic("centry_uint32");
- }
- ret = CVAL(centry->data, centry->ofs);
- centry->ofs += 1;
- return ret;
-}
-
-/* pull a string from a cache entry, using the supplied
- talloc context
-*/
-static char *centry_string(struct cache_entry *centry, TALLOC_CTX *mem_ctx)
-{
- uint32 len;
- char *ret;
-
- len = centry_uint8(centry);
-
- if (len == 0xFF) {
- /* a deliberate NULL string */
- return NULL;
- }
-
- if (centry->len - centry->ofs < len) {
- DEBUG(0,("centry corruption? needed %d bytes, have %d\n",
- len, centry->len - centry->ofs));
- smb_panic("centry_string");
- }
-
- ret = talloc(mem_ctx, len+1);
- if (!ret) {
- smb_panic("centry_string out of memory\n");
- }
- memcpy(ret,centry->data + centry->ofs, len);
- ret[len] = 0;
- centry->ofs += len;
- return ret;
-}
-
-/* pull a string from a cache entry, using the supplied
- talloc context
-*/
-static DOM_SID *centry_sid(struct cache_entry *centry, TALLOC_CTX *mem_ctx)
-{
- DOM_SID *sid;
- char *sid_string;
- sid = talloc(mem_ctx, sizeof(*sid));
- if (!sid) return NULL;
-
- sid_string = centry_string(centry, mem_ctx);
- if (!string_to_sid(sid, sid_string)) {
- return NULL;
- }
- return sid;
-}
-
-/* the server is considered down if it can't give us a sequence number */
-static BOOL wcache_server_down(struct winbindd_domain *domain)
-{
- if (!wcache->tdb) return False;
- return (domain->sequence_number == DOM_SEQUENCE_NONE);
-}
-
-
-/*
- refresh the domain sequence number. If force is True
- then always refresh it, no matter how recently we fetched it
-*/
-static void refresh_sequence_number(struct winbindd_domain *domain, BOOL force)
-{
- NTSTATUS status;
- unsigned time_diff;
- unsigned cache_time = lp_winbind_cache_time();
-
- /* trying to reconnect is expensive, don't do it too often */
- if (domain->sequence_number == DOM_SEQUENCE_NONE) {
- cache_time *= 8;
- }
-
- time_diff = time(NULL) - domain->last_seq_check;
-
- /* see if we have to refetch the domain sequence number */
- if (!force && (time_diff < cache_time)) {
- return;
- }
-
- status = wcache->backend->sequence_number(domain, &domain->sequence_number);
-
- if (!NT_STATUS_IS_OK(status)) {
- domain->sequence_number = DOM_SEQUENCE_NONE;
- }
-
- domain->last_seq_check = time(NULL);
-}
-
-/*
- decide if a cache entry has expired
-*/
-static BOOL centry_expired(struct winbindd_domain *domain, struct cache_entry *centry)
-{
- /* if the server is OK and our cache entry came from when it was down then
- the entry is invalid */
- if (domain->sequence_number != DOM_SEQUENCE_NONE &&
- centry->sequence_number == DOM_SEQUENCE_NONE) {
- return True;
- }
-
- /* if the server is down or the cache entry is not older than the
- current sequence number then it is OK */
- if (wcache_server_down(domain) ||
- centry->sequence_number == domain->sequence_number) {
- return False;
- }
-
- /* it's expired */
- return True;
-}
-
-/*
- fetch an entry from the cache, with a varargs key. auto-fetch the sequence
- number and return status
-*/
-static struct cache_entry *wcache_fetch(struct winbind_cache *cache,
- struct winbindd_domain *domain,
- const char *format, ...) PRINTF_ATTRIBUTE(3,4);
-static struct cache_entry *wcache_fetch(struct winbind_cache *cache,
- struct winbindd_domain *domain,
- const char *format, ...)
-{
- va_list ap;
- char *kstr;
- TDB_DATA data;
- struct cache_entry *centry;
- TDB_DATA key;
-
- refresh_sequence_number(domain, False);
-
- va_start(ap, format);
- smb_xvasprintf(&kstr, format, ap);
- va_end(ap);
-
- key.dptr = kstr;
- key.dsize = strlen(kstr);
- data = tdb_fetch(wcache->tdb, key);
- free(kstr);
- if (!data.dptr) {
- /* a cache miss */
- return NULL;
- }
-
- centry = smb_xmalloc(sizeof(*centry));
- centry->data = data.dptr;
- centry->len = data.dsize;
- centry->ofs = 0;
-
- if (centry->len < 8) {
- /* huh? corrupt cache? */
- centry_free(centry);
- return NULL;
- }
-
- centry->status = NT_STATUS(centry_uint32(centry));
- centry->sequence_number = centry_uint32(centry);
-
- if (centry_expired(domain, centry)) {
- extern BOOL opt_dual_daemon;
-
- if (opt_dual_daemon) {
- extern BOOL background_process;
- background_process = True;
- } else {
- centry_free(centry);
- return NULL;
- }
- }
-
- return centry;
-}
-
-/*
- make sure we have at least len bytes available in a centry
-*/
-static void centry_expand(struct cache_entry *centry, uint32 len)
-{
- uint8 *p;
- if (centry->len - centry->ofs >= len) return;
- centry->len *= 2;
- p = realloc(centry->data, centry->len);
- if (!p) {
- DEBUG(0,("out of memory: needed %d bytes in centry_expand\n", centry->len));
- smb_panic("out of memory in centry_expand");
- }
- centry->data = p;
-}
-
-/*
- push a uint32 into a centry
-*/
-static void centry_put_uint32(struct cache_entry *centry, uint32 v)
-{
- centry_expand(centry, 4);
- SIVAL(centry->data, centry->ofs, v);
- centry->ofs += 4;
-}
-
-/*
- push a uint8 into a centry
-*/
-static void centry_put_uint8(struct cache_entry *centry, uint8 v)
-{
- centry_expand(centry, 1);
- SCVAL(centry->data, centry->ofs, v);
- centry->ofs += 1;
-}
-
-/*
- push a string into a centry
- */
-static void centry_put_string(struct cache_entry *centry, const char *s)
-{
- int len;
-
- if (!s) {
- /* null strings are marked as len 0xFFFF */
- centry_put_uint8(centry, 0xFF);
- return;
- }
-
- len = strlen(s);
- /* can't handle more than 254 char strings. Truncating is probably best */
- if (len > 254) len = 254;
- centry_put_uint8(centry, len);
- centry_expand(centry, len);
- memcpy(centry->data + centry->ofs, s, len);
- centry->ofs += len;
-}
-
-static void centry_put_sid(struct cache_entry *centry, const DOM_SID *sid)
-{
- int len;
- fstring sid_string;
- centry_put_string(centry, sid_to_string(sid_string, sid));
-}
-
-/*
- start a centry for output. When finished, call centry_end()
-*/
-struct cache_entry *centry_start(struct winbindd_domain *domain, NTSTATUS status)
-{
- struct cache_entry *centry;
-
- if (!wcache->tdb) return NULL;
-
- centry = smb_xmalloc(sizeof(*centry));
-
- centry->len = 8192; /* reasonable default */
- centry->data = smb_xmalloc(centry->len);
- centry->ofs = 0;
- centry->sequence_number = domain->sequence_number;
- centry_put_uint32(centry, NT_STATUS_V(status));
- centry_put_uint32(centry, centry->sequence_number);
- return centry;
-}
-
-/*
- finish a centry and write it to the tdb
-*/
-static void centry_end(struct cache_entry *centry, const char *format, ...) PRINTF_ATTRIBUTE(2,3);
-static void centry_end(struct cache_entry *centry, const char *format, ...)
-{
- va_list ap;
- char *kstr;
- TDB_DATA key, data;
-
- va_start(ap, format);
- smb_xvasprintf(&kstr, format, ap);
- va_end(ap);
-
- key.dptr = kstr;
- key.dsize = strlen(kstr);
- data.dptr = centry->data;
- data.dsize = centry->ofs;
-
- tdb_store(wcache->tdb, key, data, TDB_REPLACE);
- free(kstr);
-}
-
-static void wcache_save_name_to_sid(struct winbindd_domain *domain,
- NTSTATUS status,
- const char *name, DOM_SID *sid,
- enum SID_NAME_USE type)
-{
- struct cache_entry *centry;
- uint32 len;
- fstring uname;
- fstring sid_string;
-
- centry = centry_start(domain, status);
- if (!centry) return;
- centry_put_sid(centry, sid);
- fstrcpy(uname, name);
- strupper(uname);
- centry_end(centry, "NS/%s", sid_to_string(sid_string, sid));
- centry_free(centry);
-}
-
-static void wcache_save_sid_to_name(struct winbindd_domain *domain, NTSTATUS status,
- DOM_SID *sid, const char *name, enum SID_NAME_USE type)
-{
- struct cache_entry *centry;
- fstring sid_string;
-
- centry = centry_start(domain, status);
- if (!centry) return;
- if (NT_STATUS_IS_OK(status)) {
- centry_put_uint32(centry, type);
- centry_put_string(centry, name);
- }
- centry_end(centry, "SN/%s", sid_to_string(sid_string, sid));
- centry_free(centry);
-}
-
-
-static void wcache_save_user(struct winbindd_domain *domain, NTSTATUS status, WINBIND_USERINFO *info)
-{
- struct cache_entry *centry;
- fstring sid_string;
-
- centry = centry_start(domain, status);
- if (!centry) return;
- centry_put_string(centry, info->acct_name);
- centry_put_string(centry, info->full_name);
- centry_put_sid(centry, info->user_sid);
- centry_put_sid(centry, info->group_sid);
- centry_end(centry, "U/%s", sid_to_string(sid_string, info->user_sid));
- centry_free(centry);
-}
-
-
-/* Query display info. This is the basic user list fn */
-static NTSTATUS query_user_list(struct winbindd_domain *domain,
- TALLOC_CTX *mem_ctx,
- uint32 *num_entries,
- WINBIND_USERINFO **info)
-{
- struct winbind_cache *cache = get_cache(domain);
- struct cache_entry *centry = NULL;
- NTSTATUS status;
- unsigned int i;
-
- if (!cache->tdb) goto do_query;
-
- centry = wcache_fetch(cache, domain, "UL/%s", domain->name);
- if (!centry) goto do_query;
-
- *num_entries = centry_uint32(centry);
-
- if (*num_entries == 0) goto do_cached;
-
- (*info) = talloc(mem_ctx, sizeof(**info) * (*num_entries));
- if (! (*info)) smb_panic("query_user_list out of memory");
- for (i=0; i<(*num_entries); i++) {
- (*info)[i].acct_name = centry_string(centry, mem_ctx);
- (*info)[i].full_name = centry_string(centry, mem_ctx);
- (*info)[i].user_sid = centry_sid(centry, mem_ctx);
- (*info)[i].group_sid = centry_sid(centry, mem_ctx);
- }
-
-do_cached:
- status = centry->status;
- centry_free(centry);
- return status;
-
-do_query:
- *num_entries = 0;
- *info = NULL;
-
- if (wcache_server_down(domain)) {
- return NT_STATUS_SERVER_DISABLED;
- }
-
- status = cache->backend->query_user_list(domain, mem_ctx, num_entries, info);
-
- /* and save it */
- refresh_sequence_number(domain, True);
- centry = centry_start(domain, status);
- if (!centry) goto skip_save;
- centry_put_uint32(centry, *num_entries);
- for (i=0; i<(*num_entries); i++) {
- centry_put_string(centry, (*info)[i].acct_name);
- centry_put_string(centry, (*info)[i].full_name);
- centry_put_sid(centry, (*info)[i].user_sid);
- centry_put_sid(centry, (*info)[i].group_sid);
- if (cache->backend->consistent) {
- /* when the backend is consistent we can pre-prime some mappings */
- wcache_save_name_to_sid(domain, NT_STATUS_OK,
- (*info)[i].acct_name,
- (*info)[i].user_sid,
- SID_NAME_USER);
- wcache_save_sid_to_name(domain, NT_STATUS_OK,
- (*info)[i].user_sid,
- (*info)[i].acct_name,
- SID_NAME_USER);
- wcache_save_user(domain, NT_STATUS_OK, &(*info)[i]);
- }
- }
- centry_end(centry, "UL/%s", domain->name);
- centry_free(centry);
-
-skip_save:
- return status;
-}
-
-/* list all domain groups */
-static NTSTATUS enum_dom_groups(struct winbindd_domain *domain,
- TALLOC_CTX *mem_ctx,
- uint32 *num_entries,
- struct acct_info **info)
-{
- struct winbind_cache *cache = get_cache(domain);
- struct cache_entry *centry = NULL;
- NTSTATUS status;
- unsigned int i;
-
- if (!cache->tdb) goto do_query;
-
- centry = wcache_fetch(cache, domain, "GL/%s/domain", domain->name);
- if (!centry) goto do_query;
-
- *num_entries = centry_uint32(centry);
-
- if (*num_entries == 0) goto do_cached;
-
- (*info) = talloc(mem_ctx, sizeof(**info) * (*num_entries));
- if (! (*info)) smb_panic("enum_dom_groups out of memory");
- for (i=0; i<(*num_entries); i++) {
- fstrcpy((*info)[i].acct_name, centry_string(centry, mem_ctx));
- fstrcpy((*info)[i].acct_desc, centry_string(centry, mem_ctx));
- (*info)[i].rid = centry_uint32(centry);
- }
-
-do_cached:
- status = centry->status;
- centry_free(centry);
- return status;
-
-do_query:
- *num_entries = 0;
- *info = NULL;
-
- if (wcache_server_down(domain)) {
- return NT_STATUS_SERVER_DISABLED;
- }
-
- status = cache->backend->enum_dom_groups(domain, mem_ctx, num_entries, info);
-
- /* and save it */
- refresh_sequence_number(domain, True);
- centry = centry_start(domain, status);
- if (!centry) goto skip_save;
- centry_put_uint32(centry, *num_entries);
- for (i=0; i<(*num_entries); i++) {
- centry_put_string(centry, (*info)[i].acct_name);
- centry_put_string(centry, (*info)[i].acct_desc);
- centry_put_uint32(centry, (*info)[i].rid);
- }
- centry_end(centry, "GL/%s/domain", domain->name);
- centry_free(centry);
-
-skip_save:
- return status;
-}
-
-/* list all domain groups */
-static NTSTATUS enum_local_groups(struct winbindd_domain *domain,
- TALLOC_CTX *mem_ctx,
- uint32 *num_entries,
- struct acct_info **info)
-{
- struct winbind_cache *cache = get_cache(domain);
- struct cache_entry *centry = NULL;
- NTSTATUS status;
- unsigned int i;
-
- if (!cache->tdb) goto do_query;
-
- centry = wcache_fetch(cache, domain, "GL/%s/local", domain->name);
- if (!centry) goto do_query;
-
- *num_entries = centry_uint32(centry);
-
- if (*num_entries == 0) goto do_cached;
-
- (*info) = talloc(mem_ctx, sizeof(**info) * (*num_entries));
- if (! (*info)) smb_panic("enum_dom_groups out of memory");
- for (i=0; i<(*num_entries); i++) {
- fstrcpy((*info)[i].acct_name, centry_string(centry, mem_ctx));
- fstrcpy((*info)[i].acct_desc, centry_string(centry, mem_ctx));
- (*info)[i].rid = centry_uint32(centry);
- }
-
-do_cached:
-
- /* If we are returning cached data and the domain controller
- is down then we don't know whether the data is up to date
- or not. Return NT_STATUS_MORE_PROCESSING_REQUIRED to
- indicate this. */
-
- if (wcache_server_down(domain)) {
- DEBUG(10, ("query_user_list: returning cached user list and server was down\n"));
- status = NT_STATUS_MORE_PROCESSING_REQUIRED;
- } else
- status = centry->status;
-
- centry_free(centry);
- return status;
-
-do_query:
- *num_entries = 0;
- *info = NULL;
-
- if (wcache_server_down(domain)) {
- return NT_STATUS_SERVER_DISABLED;
- }
-
- status = cache->backend->enum_local_groups(domain, mem_ctx, num_entries, info);
-
- /* and save it */
- refresh_sequence_number(domain, True);
- centry = centry_start(domain, status);
- if (!centry) goto skip_save;
- centry_put_uint32(centry, *num_entries);
- for (i=0; i<(*num_entries); i++) {
- centry_put_string(centry, (*info)[i].acct_name);
- centry_put_string(centry, (*info)[i].acct_desc);
- centry_put_uint32(centry, (*info)[i].rid);
- }
- centry_end(centry, "GL/%s/local", domain->name);
- centry_free(centry);
-
-skip_save:
- return status;
-}
-
-/* convert a single name to a sid in a domain */
-static NTSTATUS name_to_sid(struct winbindd_domain *domain,
- TALLOC_CTX *mem_ctx,
- const char *name,
- DOM_SID *sid,
- enum SID_NAME_USE *type)
-{
- struct winbind_cache *cache = get_cache(domain);
- struct cache_entry *centry = NULL;
- NTSTATUS status;
- fstring uname;
- DOM_SID *sid2;
-
- if (!cache->tdb) goto do_query;
-
- fstrcpy(uname, name);
- strupper(uname);
- centry = wcache_fetch(cache, domain, "NS/%s/%s", domain->name, uname);
- if (!centry) goto do_query;
- *type = centry_uint32(centry);
- sid2 = centry_sid(centry, mem_ctx);
- if (!sid2) {
- ZERO_STRUCTP(sid);
- } else {
- sid_copy(sid, sid2);
- }
-
- status = centry->status;
- centry_free(centry);
- return status;
-
-do_query:
- ZERO_STRUCTP(sid);
-
- if (wcache_server_down(domain)) {
- return NT_STATUS_SERVER_DISABLED;
- }
- status = cache->backend->name_to_sid(domain, mem_ctx, name, sid, type);
-
- /* and save it */
- wcache_save_name_to_sid(domain, status, name, sid, *type);
-
- /* We can't save the sid to name mapping as we don't know the
- correct case of the name without looking it up */
-
- return status;
-}
-
-/* convert a sid to a user or group name. The sid is guaranteed to be in the domain
- given */
-static NTSTATUS sid_to_name(struct winbindd_domain *domain,
- TALLOC_CTX *mem_ctx,
- DOM_SID *sid,
- char **name,
- enum SID_NAME_USE *type)
-{
- struct winbind_cache *cache = get_cache(domain);
- struct cache_entry *centry = NULL;
- NTSTATUS status;
- fstring sid_string;
-
- if (!cache->tdb) goto do_query;
-
- centry = wcache_fetch(cache, domain, "SN/%s", sid_to_string(sid_string, sid));
- if (!centry) goto do_query;
- if (NT_STATUS_IS_OK(centry->status)) {
- *type = centry_uint32(centry);
- *name = centry_string(centry, mem_ctx);
- }
- status = centry->status;
- centry_free(centry);
- return status;
-
-do_query:
- *name = NULL;
-
- if (wcache_server_down(domain)) {
- return NT_STATUS_SERVER_DISABLED;
- }
- status = cache->backend->sid_to_name(domain, mem_ctx, sid, name, type);
-
- /* and save it */
- refresh_sequence_number(domain, True);
- wcache_save_sid_to_name(domain, status, sid, *name, *type);
- wcache_save_name_to_sid(domain, status, *name, sid, *type);
-
- return status;
-}
-
-
-/* Lookup user information from a rid */
-static NTSTATUS query_user(struct winbindd_domain *domain,
- TALLOC_CTX *mem_ctx,
- DOM_SID *user_sid,
- WINBIND_USERINFO *info)
-{
- struct winbind_cache *cache = get_cache(domain);
- struct cache_entry *centry = NULL;
- NTSTATUS status;
- fstring sid_string;
-
- if (!cache->tdb) goto do_query;
-
- centry = wcache_fetch(cache, domain, "U/%s", sid_to_string(sid_string, user_sid));
- if (!centry) goto do_query;
-
- info->acct_name = centry_string(centry, mem_ctx);
- info->full_name = centry_string(centry, mem_ctx);
- info->user_sid = centry_sid(centry, mem_ctx);
- info->group_sid = centry_sid(centry, mem_ctx);
- status = centry->status;
- centry_free(centry);
- return status;
-
-do_query:
- ZERO_STRUCTP(info);
-
- if (wcache_server_down(domain)) {
- return NT_STATUS_SERVER_DISABLED;
- }
-
- status = cache->backend->query_user(domain, mem_ctx, user_sid, info);
-
- /* and save it */
- refresh_sequence_number(domain, True);
- wcache_save_user(domain, status, info);
-
- return status;
-}
-
-
-/* Lookup groups a user is a member of. */
-static NTSTATUS lookup_usergroups(struct winbindd_domain *domain,
- TALLOC_CTX *mem_ctx,
- DOM_SID *user_sid,
- uint32 *num_groups, DOM_SID ***user_gids)
-{
- struct winbind_cache *cache = get_cache(domain);
- struct cache_entry *centry = NULL;
- NTSTATUS status;
- unsigned int i;
- fstring sid_string;
-
- if (!cache->tdb) goto do_query;
-
- centry = wcache_fetch(cache, domain, "UG/%s", sid_to_string(sid_string, user_sid));
- if (!centry) goto do_query;
-
- *num_groups = centry_uint32(centry);
-
- if (*num_groups == 0) goto do_cached;
-
- (*user_gids) = talloc(mem_ctx, sizeof(**user_gids) * (*num_groups));
- if (! (*user_gids)) smb_panic("lookup_usergroups out of memory");
- for (i=0; i<(*num_groups); i++) {
- (*user_gids)[i] = centry_sid(centry, mem_ctx);
- }
-
-do_cached:
- status = centry->status;
- centry_free(centry);
- return status;
-
-do_query:
- (*num_groups) = 0;
- (*user_gids) = NULL;
-
- if (wcache_server_down(domain)) {
- return NT_STATUS_SERVER_DISABLED;
- }
- status = cache->backend->lookup_usergroups(domain, mem_ctx, user_sid, num_groups, user_gids);
-
- /* and save it */
- refresh_sequence_number(domain, True);
- centry = centry_start(domain, status);
- if (!centry) goto skip_save;
- centry_put_uint32(centry, *num_groups);
- for (i=0; i<(*num_groups); i++) {
- centry_put_sid(centry, (*user_gids)[i]);
- }
- centry_end(centry, "UG/%s", sid_to_string(sid_string, user_sid));
- centry_free(centry);
-
-skip_save:
- return status;
-}
-
-
-static NTSTATUS lookup_groupmem(struct winbindd_domain *domain,
- TALLOC_CTX *mem_ctx,
- DOM_SID *group_sid, uint32 *num_names,
- DOM_SID ***sid_mem, char ***names,
- uint32 **name_types)
-{
- struct winbind_cache *cache = get_cache(domain);
- struct cache_entry *centry = NULL;
- NTSTATUS status;
- unsigned int i;
- fstring sid_string;
-
- if (!cache->tdb) goto do_query;
-
- centry = wcache_fetch(cache, domain, "GM/%s", sid_to_string(sid_string, group_sid));
- if (!centry) goto do_query;
-
- *num_names = centry_uint32(centry);
-
- if (*num_names == 0) goto do_cached;
-
- (*sid_mem) = talloc(mem_ctx, sizeof(**sid_mem) * (*num_names));
- (*names) = talloc(mem_ctx, sizeof(**names) * (*num_names));
- (*name_types) = talloc(mem_ctx, sizeof(**name_types) * (*num_names));
-
- if (! (*sid_mem) || ! (*names) || ! (*name_types)) {
- smb_panic("lookup_groupmem out of memory");
- }
-
- for (i=0; i<(*num_names); i++) {
- (*sid_mem)[i] = centry_sid(centry, mem_ctx);
- (*names)[i] = centry_string(centry, mem_ctx);
- (*name_types)[i] = centry_uint32(centry);
- }
-
-do_cached:
- status = centry->status;
- centry_free(centry);
- return status;
-
-do_query:
- (*num_names) = 0;
- (*sid_mem) = NULL;
- (*names) = NULL;
- (*name_types) = NULL;
-
-
- if (wcache_server_down(domain)) {
- return NT_STATUS_SERVER_DISABLED;
- }
- status = cache->backend->lookup_groupmem(domain, mem_ctx, group_sid, num_names,
- sid_mem, names, name_types);
-
- /* and save it */
- refresh_sequence_number(domain, True);
- centry = centry_start(domain, status);
- if (!centry) goto skip_save;
- centry_put_uint32(centry, *num_names);
- for (i=0; i<(*num_names); i++) {
- centry_put_sid(centry, (*sid_mem)[i]);
- centry_put_string(centry, (*names)[i]);
- centry_put_uint32(centry, (*name_types)[i]);
- }
- centry_end(centry, "GM/%s", sid_to_string(sid_string, group_sid));
- centry_free(centry);
-
-skip_save:
- return status;
-}
-
-/* find the sequence number for a domain */
-static NTSTATUS sequence_number(struct winbindd_domain *domain, uint32 *seq)
-{
- refresh_sequence_number(domain, False);
-
- *seq = domain->sequence_number;
-
- return NT_STATUS_OK;
-}
-
-/* enumerate trusted domains */
-static NTSTATUS trusted_domains(struct winbindd_domain *domain,
- TALLOC_CTX *mem_ctx,
- uint32 *num_domains,
- char ***names,
- char ***alt_names,
- DOM_SID **dom_sids)
-{
- struct winbind_cache *cache = get_cache(domain);
-
- /* we don't cache this call */
- return cache->backend->trusted_domains(domain, mem_ctx, num_domains,
- names, alt_names, dom_sids);
-}
-
-/* find the domain sid */
-static NTSTATUS domain_sid(struct winbindd_domain *domain, DOM_SID *sid)
-{
- struct winbind_cache *cache = get_cache(domain);
-
- /* we don't cache this call */
- return cache->backend->domain_sid(domain, sid);
-}
-
-/* find the alternate names for the domain, if any */
-static NTSTATUS alternate_name(struct winbindd_domain *domain)
-{
- struct winbind_cache *cache = get_cache(domain);
-
- /* we don't cache this call */
- return cache->backend->alternate_name(domain);
-}
-
-/* the ADS backend methods are exposed via this structure */
-struct winbindd_methods cache_methods = {
- True,
- query_user_list,
- enum_dom_groups,
- enum_local_groups,
- name_to_sid,
- sid_to_name,
- query_user,
- lookup_usergroups,
- lookup_groupmem,
- sequence_number,
- trusted_domains,
- domain_sid,
- alternate_name
-};