it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3 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, see <http://www.gnu.org/licenses/>.
*/
#include "includes.h"
#include "winbindd.h"
+#include "tdb_validate.h"
+#include "../libcli/auth/libcli_auth.h"
#undef DBGC_CLASS
#define DBGC_CLASS DBGC_WINBIND
#define WINBINDD_CACHE_VERSION_KEYSTR "WINBINDD_CACHE_VERSION"
extern struct winbindd_methods reconnect_methods;
-extern bool opt_nocache;
#ifdef HAVE_ADS
extern struct winbindd_methods ads_methods;
#endif
if (ret)
return ret;
-
+
ret = SMB_XMALLOC_P(struct winbind_cache);
ZERO_STRUCTP(ret);
/* pull a sid from a cache entry, using the supplied
talloc context
*/
-static bool centry_sid(struct cache_entry *centry, TALLOC_CTX *mem_ctx, DOM_SID *sid)
+static bool centry_sid(struct cache_entry *centry, struct dom_sid *sid)
{
char *sid_string;
- sid_string = centry_string(centry, mem_ctx);
- if ((sid_string == NULL) || (!string_to_sid(sid, sid_string))) {
+ bool ret;
+
+ sid_string = centry_string(centry, talloc_tos());
+ if (sid_string == NULL) {
return false;
}
- return true;
+ ret = string_to_sid(sid, sid_string);
+ TALLOC_FREE(sid_string);
+ return ret;
}
return ret;
}
-static NTSTATUS fetch_cache_seqnum( struct winbindd_domain *domain, time_t now )
+static bool wcache_fetch_seqnum(const char *domain_name, uint32_t *seqnum,
+ uint32_t *last_seq_check)
{
+ char *key;
TDB_DATA data;
- fstring key;
- uint32 time_diff;
-
- if (!wcache->tdb) {
- DEBUG(10,("fetch_cache_seqnum: tdb == NULL\n"));
- return NT_STATUS_UNSUCCESSFUL;
+
+ if (wcache->tdb == NULL) {
+ DEBUG(10,("wcache_fetch_seqnum: tdb == NULL\n"));
+ return false;
}
-
- fstr_sprintf( key, "SEQNUM/%s", domain->name );
-
- data = tdb_fetch_bystring( wcache->tdb, key );
- if ( !data.dptr || data.dsize!=8 ) {
- DEBUG(10,("fetch_cache_seqnum: invalid data size key [%s]\n", key ));
- return NT_STATUS_UNSUCCESSFUL;
+
+ key = talloc_asprintf(talloc_tos(), "SEQNUM/%s", domain_name);
+ if (key == NULL) {
+ DEBUG(10, ("talloc failed\n"));
+ return false;
}
-
- domain->sequence_number = IVAL(data.dptr, 0);
- domain->last_seq_check = IVAL(data.dptr, 4);
-
+
+ data = tdb_fetch_bystring(wcache->tdb, key);
+ TALLOC_FREE(key);
+
+ if (data.dptr == NULL) {
+ DEBUG(10, ("wcache_fetch_seqnum: %s not found\n",
+ domain_name));
+ return false;
+ }
+ if (data.dsize != 8) {
+ DEBUG(10, ("wcache_fetch_seqnum: invalid data size %d\n",
+ (int)data.dsize));
+ SAFE_FREE(data.dptr);
+ return false;
+ }
+
+ *seqnum = IVAL(data.dptr, 0);
+ *last_seq_check = IVAL(data.dptr, 4);
SAFE_FREE(data.dptr);
+ return true;
+}
+
+static NTSTATUS fetch_cache_seqnum( struct winbindd_domain *domain, time_t now )
+{
+ uint32 last_check, time_diff;
+
+ if (!wcache_fetch_seqnum(domain->name, &domain->sequence_number,
+ &last_check)) {
+ return NT_STATUS_UNSUCCESSFUL;
+ }
+ domain->last_seq_check = last_check;
+
/* have we expired? */
-
+
time_diff = now - domain->last_seq_check;
if ( time_diff > lp_winbind_cache_time() ) {
DEBUG(10,("fetch_cache_seqnum: timeout [%s][%u @ %u]\n",
TDB_DATA data;
fstring key_str;
uint8 buf[8];
-
+
if (!wcache->tdb) {
DEBUG(10,("store_cache_seqnum: tdb == NULL\n"));
return NT_STATUS_UNSUCCESSFUL;
}
-
+
fstr_sprintf( key_str, "SEQNUM/%s", domain->name );
-
+
SIVAL(buf, 0, domain->sequence_number);
SIVAL(buf, 4, domain->last_seq_check);
data.dptr = buf;
data.dsize = 8;
-
+
if ( tdb_store_bystring( wcache->tdb, key_str, data, TDB_REPLACE) == -1 ) {
DEBUG(10,("store_cache_seqnum: tdb_store fail key [%s]\n", key_str ));
return NT_STATUS_UNSUCCESSFUL;
DEBUG(10,("store_cache_seqnum: success [%s][%u @ %u]\n",
domain->name, domain->sequence_number,
(uint32)domain->last_seq_check));
-
+
return NT_STATUS_OK;
}
if ( IS_DOMAIN_OFFLINE(domain) ) {
return;
}
-
+
get_cache( domain );
#if 0 /* JERRY -- disable as the default cache time is now 5 minutes */
DEBUG(10, ("refresh_sequence_number: %s time ok\n", domain->name));
goto done;
}
-
+
/* try to get the sequence number from the tdb cache first */
/* this will update the timestamp as well */
-
+
status = fetch_cache_seqnum( domain, t );
if (NT_STATUS_IS_OK(status) &&
(domain->sequence_number != DOM_SEQUENCE_NONE) &&
DEBUG(10,("refresh_sequence_number: failed with %s\n", nt_errstr(status)));
domain->sequence_number = DOM_SEQUENCE_NONE;
}
-
+
domain->last_status = status;
domain->last_seq_check = time(NULL);
-
+
/* save the new sequence number in the cache */
store_cache_seqnum( domain );
centry_free(centry);
return NULL;
}
-
+
centry->status = centry_ntstatus(centry);
centry->sequence_number = centry_uint32(centry);
char *kstr;
struct cache_entry *centry;
- if (opt_nocache) {
+ if (!winbindd_use_cache()) {
return NULL;
}
char *kstr;
TDB_DATA key, data;
- if (opt_nocache) {
+ if (!winbindd_use_cache()) {
return;
}
}
-static void wcache_save_user(struct winbindd_domain *domain, NTSTATUS status, WINBIND_USERINFO *info)
+static void wcache_save_user(struct winbindd_domain *domain, NTSTATUS status,
+ struct wbint_userinfo *info)
{
struct cache_entry *centry;
fstring sid_string;
static NTSTATUS query_user_list(struct winbindd_domain *domain,
TALLOC_CTX *mem_ctx,
uint32 *num_entries,
- WINBIND_USERINFO **info)
+ struct wbint_userinfo **info)
{
struct winbind_cache *cache = get_cache(domain);
struct cache_entry *centry = NULL;
goto do_query;
*num_entries = centry_uint32(centry);
-
+
if (*num_entries == 0)
goto do_cached;
- (*info) = TALLOC_ARRAY(mem_ctx, WINBIND_USERINFO, *num_entries);
+ (*info) = TALLOC_ARRAY(mem_ctx, struct wbint_userinfo, *num_entries);
if (! (*info)) {
smb_panic_fn("query_user_list out of memory");
}
(*info)[i].full_name = centry_string(centry, mem_ctx);
(*info)[i].homedir = centry_string(centry, mem_ctx);
(*info)[i].shell = centry_string(centry, mem_ctx);
- centry_sid(centry, mem_ctx, &(*info)[i].user_sid);
- centry_sid(centry, mem_ctx, &(*info)[i].group_sid);
+ centry_sid(centry, &(*info)[i].user_sid);
+ centry_sid(centry, &(*info)[i].group_sid);
}
do_cached:
goto do_query;
*num_entries = centry_uint32(centry);
-
+
if (*num_entries == 0)
goto do_cached;
goto do_query;
*num_entries = centry_uint32(centry);
-
+
if (*num_entries == 0)
goto do_cached;
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,
- enum winbindd_cmd orig_cmd,
+NTSTATUS wcache_name_to_sid(struct winbindd_domain *domain,
const char *domain_name,
const char *name,
- DOM_SID *sid,
+ struct dom_sid *sid,
enum lsa_SidType *type)
{
struct winbind_cache *cache = get_cache(domain);
- struct cache_entry *centry = NULL;
+ struct cache_entry *centry;
NTSTATUS status;
- fstring uname;
+ char *uname;
- if (!cache->tdb)
- goto do_query;
+ if (cache->tdb == NULL) {
+ return NT_STATUS_NOT_FOUND;
+ }
+
+ uname = talloc_strdup_upper(talloc_tos(), name);
+ if (uname == NULL) {
+ return NT_STATUS_NO_MEMORY;
+ }
- fstrcpy(uname, name);
- strupper_m(uname);
centry = wcache_fetch(cache, domain, "NS/%s/%s", domain_name, uname);
- if (!centry)
- goto do_query;
+ TALLOC_FREE(uname);
+ if (centry == NULL) {
+ return NT_STATUS_NOT_FOUND;
+ }
status = centry->status;
if (NT_STATUS_IS_OK(status)) {
*type = (enum lsa_SidType)centry_uint32(centry);
- centry_sid(centry, mem_ctx, sid);
+ centry_sid(centry, sid);
}
- DEBUG(10,("name_to_sid: [Cached] - cached name for domain %s status: %s\n",
- domain->name, nt_errstr(status) ));
+ DEBUG(10,("name_to_sid: [Cached] - cached name for domain %s status: "
+ "%s\n", domain->name, nt_errstr(status) ));
centry_free(centry);
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 *domain_name,
+ const char *name,
+ uint32_t flags,
+ DOM_SID *sid,
+ enum lsa_SidType *type)
+{
+ NTSTATUS status;
+
+ status = wcache_name_to_sid(domain, domain_name, name, sid, type);
+ if (!NT_STATUS_EQUAL(status, NT_STATUS_NOT_FOUND)) {
+ return status;
+ }
-do_query:
ZERO_STRUCTP(sid);
/* If the seq number check indicated that there is a problem
DEBUG(10,("name_to_sid: [Cached] - doing backend query for name for domain %s\n",
domain->name ));
- status = domain->backend->name_to_sid(domain, mem_ctx, orig_cmd,
- domain_name, name, sid, type);
+ status = domain->backend->name_to_sid(domain, mem_ctx, domain_name,
+ name, flags, sid, type);
/* and save it */
refresh_sequence_number(domain, false);
wcache_save_sid_to_name(domain, status, sid, domain_name, name, *type);
}
}
-
+
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,
+NTSTATUS wcache_sid_to_name(struct winbindd_domain *domain,
+ const struct dom_sid *sid,
TALLOC_CTX *mem_ctx,
- const DOM_SID *sid,
char **domain_name,
char **name,
enum lsa_SidType *type)
{
struct winbind_cache *cache = get_cache(domain);
- struct cache_entry *centry = NULL;
+ struct cache_entry *centry;
+ char *sid_string;
NTSTATUS status;
- fstring sid_string;
- if (!cache->tdb)
- goto do_query;
+ if (cache->tdb == NULL) {
+ return NT_STATUS_NOT_FOUND;
+ }
- centry = wcache_fetch(cache, domain, "SN/%s",
- sid_to_fstring(sid_string, sid));
- if (!centry)
- goto do_query;
+ sid_string = sid_string_tos(sid);
+ if (sid_string == NULL) {
+ return NT_STATUS_NO_MEMORY;
+ }
- status = centry->status;
- if (NT_STATUS_IS_OK(status)) {
+ centry = wcache_fetch(cache, domain, "SN/%s", sid_string);
+ TALLOC_FREE(sid_string);
+ if (centry == NULL) {
+ return NT_STATUS_NOT_FOUND;
+ }
+
+ if (NT_STATUS_IS_OK(centry->status)) {
*type = (enum lsa_SidType)centry_uint32(centry);
*domain_name = centry_string(centry, mem_ctx);
*name = centry_string(centry, mem_ctx);
}
- DEBUG(10,("sid_to_name: [Cached] - cached name for domain %s status: %s\n",
- domain->name, nt_errstr(status) ));
-
+ status = centry->status;
centry_free(centry);
+
+ DEBUG(10,("sid_to_name: [Cached] - cached name for domain %s status: "
+ "%s\n", domain->name, nt_errstr(status) ));
+
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,
+ const DOM_SID *sid,
+ char **domain_name,
+ char **name,
+ enum lsa_SidType *type)
+{
+ NTSTATUS status;
+
+ status = wcache_sid_to_name(domain, sid, mem_ctx, domain_name, name,
+ type);
+ if (!NT_STATUS_EQUAL(status, NT_STATUS_NOT_FOUND)) {
+ return status;
+ }
-do_query:
*name = NULL;
*domain_name = NULL;
const char *name = "";
const enum lsa_SidType type = SID_NAME_UNKNOWN;
NTSTATUS status = NT_STATUS_NONE_MAPPED;
-
+
if (!sid_compose(&sid, domain_sid, rids[i])) {
return NT_STATUS_INTERNAL_ERROR;
}
return result;
error:
-
TALLOC_FREE(*names);
TALLOC_FREE(*types);
return result;
}
-/* Lookup user information from a rid */
-static NTSTATUS query_user(struct winbindd_domain *domain,
- TALLOC_CTX *mem_ctx,
- const DOM_SID *user_sid,
- WINBIND_USERINFO *info)
+NTSTATUS wcache_query_user(struct winbindd_domain *domain,
+ TALLOC_CTX *mem_ctx,
+ const struct dom_sid *user_sid,
+ struct wbint_userinfo *info)
{
struct winbind_cache *cache = get_cache(domain);
struct cache_entry *centry = NULL;
NTSTATUS status;
- fstring tmp;
+ char *sid_string;
- if (!cache->tdb)
- goto do_query;
+ if (cache->tdb == NULL) {
+ return NT_STATUS_NOT_FOUND;
+ }
- centry = wcache_fetch(cache, domain, "U/%s",
- sid_to_fstring(tmp, user_sid));
-
- /* If we have an access denied cache entry and a cached info3 in the
- samlogon cache then do a query. This will force the rpc back end
- to return the info3 data. */
+ sid_string = sid_string_tos(user_sid);
+ if (sid_string == NULL) {
+ return NT_STATUS_NO_MEMORY;
+ }
+
+ centry = wcache_fetch(cache, domain, "U/%s", sid_string);
+ TALLOC_FREE(sid_string);
+ if (centry == NULL) {
+ return NT_STATUS_NOT_FOUND;
+ }
+
+ /*
+ * If we have an access denied cache entry and a cached info3
+ * in the samlogon cache then do a query. This will force the
+ * rpc back end to return the info3 data.
+ */
- if (NT_STATUS_V(domain->last_status) == NT_STATUS_V(NT_STATUS_ACCESS_DENIED) &&
+ if (NT_STATUS_EQUAL(domain->last_status, NT_STATUS_ACCESS_DENIED) &&
netsamlogon_cache_have(user_sid)) {
- DEBUG(10, ("query_user: cached access denied and have cached info3\n"));
+ DEBUG(10, ("query_user: cached access denied and have cached "
+ "info3\n"));
domain->last_status = NT_STATUS_OK;
centry_free(centry);
- goto do_query;
+ return NT_STATUS_NOT_FOUND;
}
-
- if (!centry)
- goto do_query;
-
+
/* if status is not ok then this is a negative hit
and the rest of the data doesn't matter */
status = centry->status;
info->homedir = centry_string(centry, mem_ctx);
info->shell = centry_string(centry, mem_ctx);
info->primary_gid = centry_uint32(centry);
- centry_sid(centry, mem_ctx, &info->user_sid);
- centry_sid(centry, mem_ctx, &info->group_sid);
+ centry_sid(centry, &info->user_sid);
+ centry_sid(centry, &info->group_sid);
}
- DEBUG(10,("query_user: [Cached] - cached info for domain %s status: %s\n",
- domain->name, nt_errstr(status) ));
+ DEBUG(10,("query_user: [Cached] - cached info for domain %s status: "
+ "%s\n", domain->name, nt_errstr(status) ));
centry_free(centry);
return status;
+}
+
+/* Lookup user information from a rid */
+static NTSTATUS query_user(struct winbindd_domain *domain,
+ TALLOC_CTX *mem_ctx,
+ const DOM_SID *user_sid,
+ struct wbint_userinfo *info)
+{
+ NTSTATUS status;
+
+ status = wcache_query_user(domain, mem_ctx, user_sid, info);
+ if (!NT_STATUS_EQUAL(status, NT_STATUS_NOT_FOUND)) {
+ return status;
+ }
-do_query:
ZERO_STRUCTP(info);
/* Return status value returned by seq number check */
if (!NT_STATUS_IS_OK(domain->last_status))
return domain->last_status;
-
+
DEBUG(10,("query_user: [Cached] - doing backend query for info for domain %s\n",
domain->name ));
return status;
}
-
-/* Lookup groups a user is a member of. */
-static NTSTATUS lookup_usergroups(struct winbindd_domain *domain,
+NTSTATUS wcache_lookup_usergroups(struct winbindd_domain *domain,
TALLOC_CTX *mem_ctx,
- const DOM_SID *user_sid,
- uint32 *num_groups, DOM_SID **user_gids)
+ const struct dom_sid *user_sid,
+ uint32_t *pnum_sids,
+ struct dom_sid **psids)
{
struct winbind_cache *cache = get_cache(domain);
struct cache_entry *centry = NULL;
NTSTATUS status;
- unsigned int i;
+ uint32_t i, num_sids;
+ struct dom_sid *sids;
fstring sid_string;
- if (!cache->tdb)
- goto do_query;
+ if (cache->tdb == NULL) {
+ return NT_STATUS_NOT_FOUND;
+ }
centry = wcache_fetch(cache, domain, "UG/%s",
sid_to_fstring(sid_string, user_sid));
-
+ if (centry == NULL) {
+ return NT_STATUS_NOT_FOUND;
+ }
+
/* If we have an access denied cache entry and a cached info3 in the
samlogon cache then do a query. This will force the rpc back end
to return the info3 data. */
- if (NT_STATUS_V(domain->last_status) == NT_STATUS_V(NT_STATUS_ACCESS_DENIED) &&
- netsamlogon_cache_have(user_sid)) {
- DEBUG(10, ("lookup_usergroups: cached access denied and have cached info3\n"));
+ if (NT_STATUS_EQUAL(domain->last_status, NT_STATUS_ACCESS_DENIED)
+ && netsamlogon_cache_have(user_sid)) {
+ DEBUG(10, ("lookup_usergroups: cached access denied and have "
+ "cached info3\n"));
domain->last_status = NT_STATUS_OK;
centry_free(centry);
- goto do_query;
+ return NT_STATUS_NOT_FOUND;
}
-
- if (!centry)
- goto do_query;
-
- *num_groups = centry_uint32(centry);
-
- if (*num_groups == 0)
- goto do_cached;
- (*user_gids) = TALLOC_ARRAY(mem_ctx, DOM_SID, *num_groups);
- if (! (*user_gids)) {
- smb_panic_fn("lookup_usergroups out of memory");
+ num_sids = centry_uint32(centry);
+ sids = talloc_array(mem_ctx, struct dom_sid, num_sids);
+ if (sids == NULL) {
+ return NT_STATUS_NO_MEMORY;
}
- for (i=0; i<(*num_groups); i++) {
- centry_sid(centry, mem_ctx, &(*user_gids)[i]);
+
+ for (i=0; i<num_sids; i++) {
+ centry_sid(centry, &sids[i]);
}
-do_cached:
status = centry->status;
- DEBUG(10,("lookup_usergroups: [Cached] - cached info for domain %s status: %s\n",
- domain->name, nt_errstr(status) ));
+ DEBUG(10,("lookup_usergroups: [Cached] - cached info for domain %s "
+ "status: %s\n", domain->name, nt_errstr(status)));
centry_free(centry);
+
+ *pnum_sids = num_sids;
+ *psids = sids;
return status;
+}
+
+/* Lookup groups a user is a member of. */
+static NTSTATUS lookup_usergroups(struct winbindd_domain *domain,
+ TALLOC_CTX *mem_ctx,
+ const DOM_SID *user_sid,
+ uint32 *num_groups, DOM_SID **user_gids)
+{
+ struct cache_entry *centry = NULL;
+ NTSTATUS status;
+ unsigned int i;
+ fstring sid_string;
+
+ status = wcache_lookup_usergroups(domain, mem_ctx, user_sid,
+ num_groups, user_gids);
+ if (!NT_STATUS_EQUAL(status, NT_STATUS_NOT_FOUND)) {
+ return status;
+ }
-do_query:
(*num_groups) = 0;
(*user_gids) = NULL;
if ( NT_STATUS_EQUAL(status, NT_STATUS_SYNCHRONIZATION_REQUIRED) )
goto skip_save;
-
+
/* and save it */
refresh_sequence_number(domain, false);
centry = centry_start(domain, status);
return status;
}
-static NTSTATUS lookup_useraliases(struct winbindd_domain *domain,
- TALLOC_CTX *mem_ctx,
- uint32 num_sids, const DOM_SID *sids,
- uint32 *num_aliases, uint32 **alias_rids)
+static char *wcache_make_sidlist(TALLOC_CTX *mem_ctx, uint32_t num_sids,
+ const struct dom_sid *sids)
+{
+ uint32_t i;
+ char *sidlist;
+
+ sidlist = talloc_strdup(mem_ctx, "");
+ if (sidlist == NULL) {
+ return NULL;
+ }
+ for (i=0; i<num_sids; i++) {
+ fstring tmp;
+ sidlist = talloc_asprintf_append_buffer(
+ sidlist, "/%s", sid_to_fstring(tmp, &sids[i]));
+ if (sidlist == NULL) {
+ return NULL;
+ }
+ }
+ return sidlist;
+}
+
+NTSTATUS wcache_lookup_useraliases(struct winbindd_domain *domain,
+ TALLOC_CTX *mem_ctx, uint32_t num_sids,
+ const struct dom_sid *sids,
+ uint32_t *pnum_aliases, uint32_t **paliases)
{
struct winbind_cache *cache = get_cache(domain);
struct cache_entry *centry = NULL;
+ uint32_t num_aliases;
+ uint32_t *aliases;
NTSTATUS status;
- char *sidlist = talloc_strdup(mem_ctx, "");
+ char *sidlist;
int i;
- if (!cache->tdb)
- goto do_query;
+ if (cache->tdb == NULL) {
+ return NT_STATUS_NOT_FOUND;
+ }
if (num_sids == 0) {
- *num_aliases = 0;
- *alias_rids = NULL;
+ *pnum_aliases = 0;
+ *paliases = NULL;
return NT_STATUS_OK;
}
/* We need to cache indexed by the whole list of SIDs, the aliases
* resulting might come from any of the SIDs. */
- for (i=0; i<num_sids; i++) {
- fstring tmp;
- sidlist = talloc_asprintf(mem_ctx, "%s/%s", sidlist,
- sid_to_fstring(tmp, &sids[i]));
- if (sidlist == NULL)
- return NT_STATUS_NO_MEMORY;
+ sidlist = wcache_make_sidlist(talloc_tos(), num_sids, sids);
+ if (sidlist == NULL) {
+ return NT_STATUS_NO_MEMORY;
}
centry = wcache_fetch(cache, domain, "UA%s", sidlist);
+ TALLOC_FREE(sidlist);
+ if (centry == NULL) {
+ return NT_STATUS_NOT_FOUND;
+ }
- if (!centry)
- goto do_query;
-
- *num_aliases = centry_uint32(centry);
- *alias_rids = NULL;
-
- if (*num_aliases) {
- (*alias_rids) = TALLOC_ARRAY(mem_ctx, uint32, *num_aliases);
-
- if ((*alias_rids) == NULL) {
- centry_free(centry);
- return NT_STATUS_NO_MEMORY;
- }
- } else {
- (*alias_rids) = NULL;
+ num_aliases = centry_uint32(centry);
+ aliases = talloc_array(mem_ctx, uint32_t, num_aliases);
+ if (aliases == NULL) {
+ centry_free(centry);
+ return NT_STATUS_NO_MEMORY;
}
- for (i=0; i<(*num_aliases); i++)
- (*alias_rids)[i] = centry_uint32(centry);
+ for (i=0; i<num_aliases; i++) {
+ aliases[i] = centry_uint32(centry);
+ }
status = centry->status;
"status %s\n", domain->name, nt_errstr(status)));
centry_free(centry);
+
+ *pnum_aliases = num_aliases;
+ *paliases = aliases;
+
return status;
+}
+
+static NTSTATUS lookup_useraliases(struct winbindd_domain *domain,
+ TALLOC_CTX *mem_ctx,
+ uint32 num_sids, const DOM_SID *sids,
+ uint32 *num_aliases, uint32 **alias_rids)
+{
+ struct cache_entry *centry = NULL;
+ NTSTATUS status;
+ char *sidlist;
+ int i;
+
+ status = wcache_lookup_useraliases(domain, mem_ctx, num_sids, sids,
+ num_aliases, alias_rids);
+ if (!NT_STATUS_EQUAL(status, NT_STATUS_NOT_FOUND)) {
+ return status;
+ }
- do_query:
(*num_aliases) = 0;
(*alias_rids) = NULL;
DEBUG(10,("lookup_usergroups: [Cached] - doing backend query for info "
"for domain %s\n", domain->name ));
+ sidlist = wcache_make_sidlist(talloc_tos(), num_sids, sids);
+ if (sidlist == NULL) {
+ return NT_STATUS_NO_MEMORY;
+ }
+
status = domain->backend->lookup_useraliases(domain, mem_ctx,
num_sids, sids,
num_aliases, alias_rids);
return status;
}
-
-static NTSTATUS lookup_groupmem(struct winbindd_domain *domain,
+NTSTATUS wcache_lookup_groupmem(struct winbindd_domain *domain,
TALLOC_CTX *mem_ctx,
- const DOM_SID *group_sid, uint32 *num_names,
- DOM_SID **sid_mem, char ***names,
- uint32 **name_types)
+ const struct dom_sid *group_sid,
+ uint32_t *num_names,
+ struct dom_sid **sid_mem, char ***names,
+ uint32_t **name_types)
{
struct winbind_cache *cache = get_cache(domain);
struct cache_entry *centry = NULL;
NTSTATUS status;
unsigned int i;
- fstring sid_string;
+ char *sid_string;
- if (!cache->tdb)
- goto do_query;
+ if (cache->tdb == NULL) {
+ return NT_STATUS_NOT_FOUND;
+ }
- centry = wcache_fetch(cache, domain, "GM/%s",
- sid_to_fstring(sid_string, group_sid));
- if (!centry)
- goto do_query;
+ sid_string = sid_string_tos(group_sid);
+ if (sid_string == NULL) {
+ return NT_STATUS_NO_MEMORY;
+ }
+
+ centry = wcache_fetch(cache, domain, "GM/%s", sid_string);
+ TALLOC_FREE(sid_string);
+ if (centry == NULL) {
+ return NT_STATUS_NOT_FOUND;
+ }
+
+ *sid_mem = NULL;
+ *names = NULL;
+ *name_types = NULL;
*num_names = centry_uint32(centry);
-
- if (*num_names == 0)
- goto do_cached;
+ if (*num_names == 0) {
+ centry_free(centry);
+ return NT_STATUS_OK;
+ }
- (*sid_mem) = TALLOC_ARRAY(mem_ctx, DOM_SID, *num_names);
- (*names) = TALLOC_ARRAY(mem_ctx, char *, *num_names);
- (*name_types) = TALLOC_ARRAY(mem_ctx, uint32, *num_names);
+ *sid_mem = talloc_array(mem_ctx, DOM_SID, *num_names);
+ *names = talloc_array(mem_ctx, char *, *num_names);
+ *name_types = talloc_array(mem_ctx, uint32, *num_names);
- if (! (*sid_mem) || ! (*names) || ! (*name_types)) {
- smb_panic_fn("lookup_groupmem out of memory");
+ if ((*sid_mem == NULL) || (*names == NULL) || (*name_types == NULL)) {
+ TALLOC_FREE(*sid_mem);
+ TALLOC_FREE(*names);
+ TALLOC_FREE(*name_types);
+ centry_free(centry);
+ return NT_STATUS_NO_MEMORY;
}
for (i=0; i<(*num_names); i++) {
- centry_sid(centry, mem_ctx, &(*sid_mem)[i]);
+ centry_sid(centry, &(*sid_mem)[i]);
(*names)[i] = centry_string(centry, mem_ctx);
(*name_types)[i] = centry_uint32(centry);
}
-do_cached:
status = centry->status;
- DEBUG(10,("lookup_groupmem: [Cached] - cached info for domain %s status: %s\n",
- domain->name, nt_errstr(status)));
+ DEBUG(10,("lookup_groupmem: [Cached] - cached info for domain %s "
+ "status: %s\n", domain->name, nt_errstr(status)));
centry_free(centry);
return status;
+}
+
+static NTSTATUS lookup_groupmem(struct winbindd_domain *domain,
+ TALLOC_CTX *mem_ctx,
+ const DOM_SID *group_sid, uint32 *num_names,
+ DOM_SID **sid_mem, char ***names,
+ uint32 **name_types)
+{
+ struct cache_entry *centry = NULL;
+ NTSTATUS status;
+ unsigned int i;
+ fstring sid_string;
+
+ status = wcache_lookup_groupmem(domain, mem_ctx, group_sid, num_names,
+ sid_mem, names, name_types);
+ if (!NT_STATUS_EQUAL(status, NT_STATUS_NOT_FOUND)) {
+ return status;
+ }
-do_query:
(*num_names) = 0;
(*sid_mem) = NULL;
(*names) = NULL;
(*name_types) = NULL;
-
+
/* Return status value returned by seq number check */
if (!NT_STATUS_IS_OK(domain->last_status))
struct cache_entry *centry = NULL;
NTSTATUS status;
int i;
-
+
if (!cache->tdb)
goto do_query;
-
+
centry = wcache_fetch(cache, domain, "TRUSTDOMS/%s", domain->name);
-
+
if (!centry) {
goto do_query;
}
-
+
*num_domains = centry_uint32(centry);
-
+
if (*num_domains) {
(*names) = TALLOC_ARRAY(mem_ctx, char *, *num_domains);
(*alt_names) = TALLOC_ARRAY(mem_ctx, char *, *num_domains);
(*dom_sids) = TALLOC_ARRAY(mem_ctx, DOM_SID, *num_domains);
-
+
if (! (*dom_sids) || ! (*names) || ! (*alt_names)) {
smb_panic_fn("trusted_domains out of memory");
}
(*alt_names) = NULL;
(*dom_sids) = NULL;
}
-
+
for (i=0; i<(*num_domains); i++) {
(*names)[i] = centry_string(centry, mem_ctx);
(*alt_names)[i] = centry_string(centry, mem_ctx);
- if (!centry_sid(centry, mem_ctx, &(*dom_sids)[i])) {
+ if (!centry_sid(centry, &(*dom_sids)[i])) {
sid_copy(&(*dom_sids)[i], &global_sid_NULL);
}
}
status = centry->status;
-
+
DEBUG(10,("trusted_domains: [Cached] - cached info for domain %s (%d trusts) status: %s\n",
domain->name, *num_domains, nt_errstr(status) ));
-
+
centry_free(centry);
return status;
-
+
do_query:
(*num_domains) = 0;
(*dom_sids) = NULL;
(*names) = NULL;
(*alt_names) = NULL;
-
+
/* Return status value returned by seq number check */
if (!NT_STATUS_IS_OK(domain->last_status))
return domain->last_status;
-
+
DEBUG(10,("trusted_domains: [Cached] - doing backend query for info for domain %s\n",
domain->name ));
-
+
status = domain->backend->trusted_domains(domain, mem_ctx, num_domains,
names, alt_names, dom_sids);
/* and save it */
refresh_sequence_number(domain, false);
-
+
centry = centry_start(domain, status);
if (!centry)
goto skip_save;
centry_put_string(centry, (*alt_names)[i]);
centry_put_sid(centry, &(*dom_sids)[i]);
}
-
+
centry_end(centry, "TRUSTDOMS/%s", domain->name);
-
+
centry_free(centry);
-
+
skip_save:
#endif
return true;
/* when working offline we must not clear the cache on restart */
- wcache->tdb = tdb_open_log(lock_path("winbindd_cache.tdb"),
+ wcache->tdb = tdb_open_log(cache_path("winbindd_cache.tdb"),
WINBINDD_CACHE_TDB_DEFAULT_HASH_SIZE,
lp_winbind_offline_logon() ? TDB_DEFAULT : (TDB_DEFAULT | TDB_CLEAR_IF_FIRST),
O_RDWR|O_CREAT, 0600);
tdb_close(wcache->tdb);
wcache->tdb = NULL;
- if (unlink(lock_path("winbindd_cache.tdb")) == -1) {
+ if (unlink(cache_path("winbindd_cache.tdb")) == -1) {
DEBUG(0,("initialize_winbindd_cache: unlink %s failed %s ",
- lock_path("winbindd_cache.tdb"),
+ cache_path("winbindd_cache.tdb"),
strerror(errno) ));
return false;
}
}
}
-void cache_store_response(pid_t pid, struct winbindd_response *response)
-{
- fstring key_str;
-
- if (!init_wcache())
- return;
-
- DEBUG(10, ("Storing response for pid %d, len %d\n",
- pid, response->length));
-
- fstr_sprintf(key_str, "DR/%d", pid);
- if (tdb_store(wcache->tdb, string_tdb_data(key_str),
- make_tdb_data((uint8 *)response, sizeof(*response)),
- TDB_REPLACE) == -1)
- return;
-
- if (response->length == sizeof(*response))
- return;
-
- /* There's extra data */
-
- DEBUG(10, ("Storing extra data: len=%d\n",
- (int)(response->length - sizeof(*response))));
-
- fstr_sprintf(key_str, "DE/%d", pid);
- if (tdb_store(wcache->tdb, string_tdb_data(key_str),
- make_tdb_data((uint8 *)response->extra_data.data,
- response->length - sizeof(*response)),
- TDB_REPLACE) == 0)
- return;
-
- /* We could not store the extra data, make sure the tdb does not
- * contain a main record with wrong dangling extra data */
-
- fstr_sprintf(key_str, "DR/%d", pid);
- tdb_delete(wcache->tdb, string_tdb_data(key_str));
-
- return;
-}
-
-bool cache_retrieve_response(pid_t pid, struct winbindd_response * response)
-{
- TDB_DATA data;
- fstring key_str;
-
- if (!init_wcache())
- return false;
-
- DEBUG(10, ("Retrieving response for pid %d\n", pid));
-
- fstr_sprintf(key_str, "DR/%d", pid);
- data = tdb_fetch(wcache->tdb, string_tdb_data(key_str));
-
- if (data.dptr == NULL)
- return false;
-
- if (data.dsize != sizeof(*response))
- return false;
-
- memcpy(response, data.dptr, data.dsize);
- SAFE_FREE(data.dptr);
-
- if (response->length == sizeof(*response)) {
- response->extra_data.data = NULL;
- return true;
- }
-
- /* There's extra data */
-
- DEBUG(10, ("Retrieving extra data length=%d\n",
- (int)(response->length - sizeof(*response))));
-
- fstr_sprintf(key_str, "DE/%d", pid);
- data = tdb_fetch(wcache->tdb, string_tdb_data(key_str));
-
- if (data.dptr == NULL) {
- DEBUG(0, ("Did not find extra data\n"));
- return false;
- }
-
- if (data.dsize != (response->length - sizeof(*response))) {
- DEBUG(0, ("Invalid extra data length: %d\n", (int)data.dsize));
- SAFE_FREE(data.dptr);
- return false;
- }
-
- dump_data(11, (uint8 *)data.dptr, data.dsize);
-
- response->extra_data.data = data.dptr;
- return true;
-}
-
-void cache_cleanup_response(pid_t pid)
-{
- fstring key_str;
-
- if (!init_wcache())
- return;
-
- fstr_sprintf(key_str, "DR/%d", pid);
- tdb_delete(wcache->tdb, string_tdb_data(key_str));
-
- fstr_sprintf(key_str, "DE/%d", pid);
- tdb_delete(wcache->tdb, string_tdb_data(key_str));
-
- return;
-}
-
-
bool lookup_cached_sid(TALLOC_CTX *mem_ctx, const DOM_SID *sid,
char **domain_name, char **name,
enum lsa_SidType *type)
{
struct winbindd_domain *domain;
- struct winbind_cache *cache;
- struct cache_entry *centry = NULL;
NTSTATUS status;
- fstring tmp;
domain = find_lookup_domain_from_sid(sid);
if (domain == NULL) {
return false;
}
-
- cache = get_cache(domain);
-
- if (cache->tdb == NULL) {
- return false;
- }
-
- centry = wcache_fetch(cache, domain, "SN/%s",
- sid_to_fstring(tmp, sid));
- if (centry == NULL) {
- return false;
- }
-
- if (NT_STATUS_IS_OK(centry->status)) {
- *type = (enum lsa_SidType)centry_uint32(centry);
- *domain_name = centry_string(centry, mem_ctx);
- *name = centry_string(centry, mem_ctx);
- }
-
- status = centry->status;
- centry_free(centry);
+ status = wcache_sid_to_name(domain, sid, mem_ctx, domain_name, name,
+ type);
return NT_STATUS_IS_OK(status);
}
enum lsa_SidType *type)
{
struct winbindd_domain *domain;
- struct winbind_cache *cache;
- struct cache_entry *centry = NULL;
NTSTATUS status;
- fstring uname;
- bool original_online_state;
+ bool original_online_state;
domain = find_lookup_domain_from_name(domain_name);
if (domain == NULL) {
return false;
}
- cache = get_cache(domain);
-
- if (cache->tdb == NULL) {
- return false;
- }
-
- fstrcpy(uname, name);
- strupper_m(uname);
-
/* If we are doing a cached logon, temporarily set the domain
offline so the cache won't expire the entry */
-
+
original_online_state = domain->online;
domain->online = false;
- centry = wcache_fetch(cache, domain, "NS/%s/%s", domain_name, uname);
+ status = wcache_name_to_sid(domain, domain_name, name, sid, type);
domain->online = original_online_state;
-
- if (centry == NULL) {
- return false;
- }
- if (NT_STATUS_IS_OK(centry->status)) {
- *type = (enum lsa_SidType)centry_uint32(centry);
- centry_sid(centry, mem_ctx, sid);
- }
-
- status = centry->status;
- centry_free(centry);
-
return NT_STATUS_IS_OK(status);
}
tdb_close(wcache->tdb);
wcache->tdb = NULL;
}
- if (opt_nocache)
+ if (!winbindd_use_cache()) {
return;
+ }
/* when working offline we must not clear the cache on restart */
- wcache->tdb = tdb_open_log(lock_path("winbindd_cache.tdb"),
+ wcache->tdb = tdb_open_log(cache_path("winbindd_cache.tdb"),
WINBINDD_CACHE_TDB_DEFAULT_HASH_SIZE,
lp_winbind_offline_logon() ? TDB_DEFAULT : (TDB_DEFAULT | TDB_CLEAR_IF_FIRST),
O_RDWR|O_CREAT, 0600);
}
ZERO_STRUCTP(cred);
-
+
/* save a copy of the key */
-
+
fstrcpy(cred->name, (const char *)kbuf.dptr);
DLIST_ADD(wcache_cred_list, cred);
}
-
+
return 0;
}
/* we possibly already have an entry */
if (sid && NT_STATUS_IS_OK(wcache_cached_creds_exist(domain, sid))) {
-
+
fstring key_str, tmp;
DEBUG(11,("we already have an entry, deleting that\n"));
status = NT_STATUS_OBJECT_NAME_NOT_FOUND;
goto done;
}
-
+
t = IVAL(data.dptr, 0);
SAFE_FREE(data.dptr);
done:
SAFE_FREE(wcache_cred_list);
SAFE_FREE(oldest);
-
+
return status;
}
(void)centry_uint32(centry);
if (NT_STATUS_IS_OK(centry->status)) {
DOM_SID sid;
- (void)centry_sid(centry, mem_ctx, &sid);
+ (void)centry_sid(centry, &sid);
}
centry_free(centry);
(void)centry_string(centry, mem_ctx);
(void)centry_string(centry, mem_ctx);
(void)centry_uint32(centry);
- (void)centry_sid(centry, mem_ctx, &sid);
- (void)centry_sid(centry, mem_ctx, &sid);
+ (void)centry_sid(centry, &sid);
+ (void)centry_sid(centry, &sid);
centry_free(centry);
(void)centry_string(centry, mem_ctx);
(void)centry_string(centry, mem_ctx);
(void)centry_string(centry, mem_ctx);
- (void)centry_sid(centry, mem_ctx, &sid);
- (void)centry_sid(centry, mem_ctx, &sid);
+ (void)centry_sid(centry, &sid);
+ (void)centry_sid(centry, &sid);
}
centry_free(centry);
}
num_entries = centry_uint32(centry);
-
+
for (i=0; i< num_entries; i++) {
(void)centry_string(centry, mem_ctx);
(void)centry_string(centry, mem_ctx);
for (i=0; i< num_groups; i++) {
DOM_SID sid;
- centry_sid(centry, mem_ctx, &sid);
+ centry_sid(centry, &sid);
}
centry_free(centry);
for (i=0; i< num_names; i++) {
DOM_SID sid;
- centry_sid(centry, mem_ctx, &sid);
+ centry_sid(centry, &sid);
(void)centry_string(centry, mem_ctx);
(void)centry_uint32(centry);
}
}
num_domains = centry_uint32(centry);
-
+
for (i=0; i< num_domains; i++) {
DOM_SID sid;
(void)centry_string(centry, mem_ctx);
(void)centry_string(centry, mem_ctx);
- (void)centry_sid(centry, mem_ctx, &sid);
+ (void)centry_sid(centry, &sid);
}
centry_free(centry);
int winbindd_validate_cache(void)
{
int ret = -1;
- const char *tdb_path = lock_path("winbindd_cache.tdb");
+ const char *tdb_path = cache_path("winbindd_cache.tdb");
TDB_CONTEXT *tdb = NULL;
DEBUG(10, ("winbindd_validate_cache: replacing panic function\n"));
int winbindd_validate_cache_nobackup(void)
{
int ret = -1;
- const char *tdb_path = lock_path("winbindd_cache.tdb");
+ const char *tdb_path = cache_path("winbindd_cache.tdb");
DEBUG(10, ("winbindd_validate_cache: replacing panic function\n"));
smb_panic_fn = validate_panic;
size_t idx;
int i;
bool set_only = false;
-
+
/* don't allow duplicates */
idx = *num_domains;
list = *domains;
-
+
for ( i=0; i< (*num_domains); i++ ) {
if ( strequal( new_dom->name, list[i].domain_name ) ) {
DEBUG(10,("add_wbdomain_to_tdc_array: Found existing record for %s\n",
new_dom->name));
idx = i;
set_only = true;
-
+
break;
}
}
if ( new_dom->domain_trust_attribs != 0x0 )
list[idx].trust_attribs = new_dom->domain_trust_attribs;
-
+
if ( !set_only ) {
*domains = list;
*num_domains = idx + 1;
{
char *keystr = NULL;
TDB_DATA key = { NULL, 0 };
-
+
if ( !domain_name ) {
DEBUG(5,("make_tdc_key: Keyname workgroup is NULL!\n"));
return key;
}
-
-
+
if (asprintf( &keystr, "TRUSTDOMCACHE/%s", domain_name ) == -1) {
return key;
}
key = string_term_tdb_data(keystr);
-
+
return key;
}
DEBUG(10,("pack_tdc_domains: Packing %d trusted domains\n",
(int)num_domains));
-
+
buflen = 0;
-
+
again:
len = 0;
-
+
/* Store the number of array items first */
len += tdb_pack( buffer+len, buflen-len, "d",
num_domains );
domains[i].domain_name,
domains[i].dns_name ? domains[i].dns_name : "UNKNOWN" ));
}
-
+
len += tdb_pack( buffer+len, buflen-len, "fffddd",
domains[i].domain_name,
domains[i].dns_name,
}
*buf = buffer;
-
+
done:
return buflen;
}
DEBUG(0,("unpack_tdc_domains: Failed to talloc() domain list!\n"));
return 0;
}
-
+
for ( i=0; i<num_domains; i++ ) {
len += tdb_unpack( buf+len, buflen-len, "fffddd",
domain_name,
"SID %s, flags = 0x%x, attribs = 0x%x, type = 0x%x\n",
domain_name, dns_name, sid_string,
flags, attribs, type));
-
+
list[i].domain_name = talloc_strdup( list, domain_name );
list[i].dns_name = talloc_strdup( list, dns_name );
if ( !string_to_sid( &(list[i].sid), sid_string ) ) {
}
*domains = list;
-
+
return num_domains;
}
TDB_DATA key = make_tdc_key( lp_workgroup() );
TDB_DATA data = { NULL, 0 };
int ret;
-
+
if ( !key.dptr )
return false;
-
+
/* See if we were asked to delete the cache entry */
if ( !domains ) {
ret = tdb_delete( wcache->tdb, key );
goto done;
}
-
+
data.dsize = pack_tdc_domains( domains, num_domains, &data.dptr );
-
+
if ( !data.dptr ) {
ret = -1;
goto done;
}
-
+
ret = tdb_store( wcache->tdb, key, data, 0 );
done:
SAFE_FREE( data.dptr );
SAFE_FREE( key.dptr );
-
+
return ( ret != -1 );
}
if ( !key.dptr )
return false;
-
+
data = tdb_fetch( wcache->tdb, key );
SAFE_FREE( key.dptr );
-
+
if ( !data.dptr )
return false;
-
+
*num_domains = unpack_tdc_domains( data.dptr, data.dsize, domains );
SAFE_FREE( data.dptr );
-
+
if ( !*domains )
return false;
domain->domain_flags,
domain->domain_trust_attribs,
domain->domain_type));
-
+
if ( !init_wcache() ) {
return false;
}
-
+
/* fetch the list */
wcache_tdc_fetch_list( &dom_list, &num_domains );
-
+
/* add the new domain */
if ( !add_wbdomain_to_tdc_array( domain, &dom_list, &num_domains ) ) {
if ( !wcache_tdc_store_list( dom_list, num_domains ) ) {
goto done;
}
-
+
/* Success */
ret = true;
done:
TALLOC_FREE( dom_list );
-
+
return ret;
}
if ( !init_wcache() ) {
return false;
}
-
+
/* fetch the list */
wcache_tdc_fetch_list( &dom_list, &num_domains );
-
+
for ( i=0; i<num_domains; i++ ) {
if ( strequal(name, dom_list[i].domain_name) ||
strequal(name, dom_list[i].dns_name) )
{
DEBUG(10,("wcache_tdc_fetch_domain: Found domain %s\n",
name));
-
+
d = TALLOC_P( ctx, struct winbindd_tdc_domain );
if ( !d )
break;
-
+
d->domain_name = talloc_strdup( d, dom_list[i].domain_name );
d->dns_name = talloc_strdup( d, dom_list[i].dns_name );
sid_copy( &d->sid, &dom_list[i].sid );
}
TALLOC_FREE( dom_list );
-
+
return d;
}
return;
wcache_tdc_store_list( NULL, 0 );
-
+
return;
}
centry_put_string( centry, shell );
centry_put_string( centry, gecos );
centry_put_uint32( centry, gid );
-
+
centry_end(centry, "NSS/PWINFO/%s", sid_to_fstring(tmp, user_sid) );
DEBUG(10,("wcache_save_user_pwinfo: %s\n", sid_string_dbg(user_sid) ));
const DOM_SID *user_sid,
TALLOC_CTX *ctx,
ADS_STRUCT *ads, LDAPMessage *msg,
- char **homedir, char **shell, char **gecos,
- gid_t *p_gid)
+ const char **homedir, const char **shell,
+ const char **gecos, gid_t *p_gid)
{
struct winbind_cache *cache = get_cache(domain);
struct cache_entry *centry = NULL;
centry = wcache_fetch(cache, domain, "NSS/PWINFO/%s",
sid_to_fstring(tmp, user_sid));
-
+
if (!centry)
goto do_query;
return NT_STATUS_OK;
do_query:
-
+
nt_status = nss_get_info( domain->name, user_sid, ctx, ads, msg,
homedir, shell, gecos, p_gid );
DEBUG(10, ("result:\n\thomedir = '%s'\n", *homedir));
DEBUGADD(10, ("\tshell = '%s'\n", *shell));
DEBUGADD(10, ("\tgecos = '%s'\n", *gecos));
- DEBUGADD(10, ("\tgid = '%u'\n", *p_gid));
+ DEBUGADD(10, ("\tgid = '%u'\n", (unsigned int)*p_gid));
wcache_save_user_pwinfo( domain, nt_status, user_sid,
*homedir, *shell, *gecos, *p_gid );
password_policy,
trusted_domains
};
+
+static bool wcache_ndr_key(TALLOC_CTX *mem_ctx, char *domain_name,
+ uint32_t opnum, const DATA_BLOB *req,
+ TDB_DATA *pkey)
+{
+ char *key;
+ size_t keylen;
+
+ key = talloc_asprintf(mem_ctx, "NDR/%s/%d/", domain_name, (int)opnum);
+ if (key == NULL) {
+ return false;
+ }
+ keylen = talloc_get_size(key) - 1;
+
+ key = talloc_realloc(mem_ctx, key, char, keylen + req->length);
+ if (key == NULL) {
+ return false;
+ }
+ memcpy(key + keylen, req->data, req->length);
+
+ pkey->dptr = (uint8_t *)key;
+ pkey->dsize = talloc_get_size(key);
+ return true;
+}
+
+bool wcache_fetch_ndr(TALLOC_CTX *mem_ctx, struct winbindd_domain *domain,
+ uint32_t opnum, const DATA_BLOB *req, DATA_BLOB *resp)
+{
+ TDB_DATA key, data;
+ bool ret = false;
+
+ if (wcache->tdb == NULL) {
+ return false;
+ }
+
+ if (!wcache_ndr_key(talloc_tos(), domain->name, opnum, req, &key)) {
+ return false;
+ }
+ data = tdb_fetch(wcache->tdb, key);
+ TALLOC_FREE(key.dptr);
+
+ if (data.dptr == NULL) {
+ return false;
+ }
+ if (data.dsize < 4) {
+ goto fail;
+ }
+
+ if (IS_DOMAIN_ONLINE(domain)) {
+ uint32_t entry_seqnum, dom_seqnum, last_check;
+
+ if (!wcache_fetch_seqnum(domain->name, &dom_seqnum,
+ &last_check)) {
+ goto fail;
+ }
+ entry_seqnum = IVAL(data.dptr, 0);
+ if (entry_seqnum != dom_seqnum) {
+ DEBUG(10, ("Entry has wrong sequence number: %d\n",
+ (int)entry_seqnum));
+ goto fail;
+ }
+ }
+
+ resp->data = (uint8_t *)talloc_memdup(mem_ctx, data.dptr + 4,
+ data.dsize - 4);
+ if (resp->data == NULL) {
+ DEBUG(10, ("talloc failed\n"));
+ goto fail;
+ }
+ resp->length = data.dsize - 4;
+
+ ret = true;
+fail:
+ SAFE_FREE(data.dptr);
+ return ret;
+}
+
+void wcache_store_ndr(struct winbindd_domain *domain, uint32_t opnum,
+ const DATA_BLOB *req, const DATA_BLOB *resp)
+{
+ TDB_DATA key, data;
+ uint32_t dom_seqnum, last_check;
+
+ if (wcache->tdb == NULL) {
+ return;
+ }
+
+ if (!wcache_fetch_seqnum(domain->name, &dom_seqnum, &last_check)) {
+ DEBUG(10, ("could not fetch seqnum for domain %s\n",
+ domain->name));
+ return;
+ }
+
+ if (!wcache_ndr_key(talloc_tos(), domain->name, opnum, req, &key)) {
+ return;
+ }
+
+ data.dsize = resp->length + 4;
+ data.dptr = talloc_array(key.dptr, uint8_t, data.dsize);
+ if (data.dptr == NULL) {
+ goto done;
+ }
+
+ SIVAL(data.dptr, 0, dom_seqnum);
+ memcpy(data.dptr+4, resp->data, resp->length);
+
+ tdb_store(wcache->tdb, key, data, 0);
+
+done:
+ TALLOC_FREE(key.dptr);
+ return;
+}