#include "tdb_validate.h"
#include "../libcli/auth/libcli_auth.h"
#include "../librpc/gen_ndr/ndr_wbint.h"
+#include "ads.h"
+#include "nss_info.h"
+#include "../libcli/security/security.h"
#undef DBGC_CLASS
#define DBGC_CLASS DBGC_WINBIND
extern struct winbindd_methods ads_methods;
#endif
extern struct winbindd_methods builtin_passdb_methods;
+extern struct winbindd_methods sam_passdb_methods;
/*
* JRA. KEEP THIS LIST UP TO DATE IF YOU ADD CACHE ENTRIES.
static struct winbind_cache *wcache;
-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(tdb_fd(wcache->tdb), &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)
{
domain->backend = &builtin_passdb_methods;
domain->initialized = True;
}
+
+ if (strequal(domain->name, get_global_sam_name()) &&
+ dom_sid_equal(&domain->sid, get_global_sam_sid())) {
+ domain->backend = &sam_passdb_methods;
+ domain->initialized = True;
+ }
+
if ( !domain->initialized ) {
init_dc_connection( domain );
}
return centry;
}
+static bool is_my_own_sam_domain(struct winbindd_domain *domain)
+{
+ if (strequal(domain->name, get_global_sam_name()) &&
+ dom_sid_equal(&domain->sid, get_global_sam_sid())) {
+ return true;
+ }
+
+ return false;
+}
+
+static bool is_builtin_domain(struct winbindd_domain *domain)
+{
+ if (strequal(domain->name, "BUILTIN") &&
+ dom_sid_equal(&domain->sid, &global_sid_Builtin)) {
+ return true;
+ }
+
+ return false;
+}
+
/*
fetch an entry from the cache, with a varargs key. auto-fetch the sequence
number and return status
char *kstr;
struct cache_entry *centry;
- if (!winbindd_use_cache()) {
+ if (!winbindd_use_cache() ||
+ is_my_own_sam_domain(domain) ||
+ is_builtin_domain(domain)) {
return NULL;
}
centry->ofs += 16;
}
-static void centry_put_sid(struct cache_entry *centry, const DOM_SID *sid)
+static void centry_put_sid(struct cache_entry *centry, const struct dom_sid *sid)
{
fstring sid_string;
centry_put_string(centry, sid_to_fstring(sid_string, sid));
static void wcache_save_name_to_sid(struct winbindd_domain *domain,
NTSTATUS status, const char *domain_name,
- const char *name, const DOM_SID *sid,
+ const char *name, const struct dom_sid *sid,
enum lsa_SidType type)
{
struct cache_entry *centry;
}
static void wcache_save_sid_to_name(struct winbindd_domain *domain, NTSTATUS status,
- const DOM_SID *sid, const char *domain_name, const char *name, enum lsa_SidType type)
+ const struct dom_sid *sid, const char *domain_name, const char *name, enum lsa_SidType type)
{
struct cache_entry *centry;
fstring sid_string;
return status;
}
-NTSTATUS wcache_cached_creds_exist(struct winbindd_domain *domain, const DOM_SID *sid)
+NTSTATUS wcache_cached_creds_exist(struct winbindd_domain *domain, const struct dom_sid *sid)
{
struct winbind_cache *cache = get_cache(domain);
TDB_DATA data;
NTSTATUS wcache_get_creds(struct winbindd_domain *domain,
TALLOC_CTX *mem_ctx,
- const DOM_SID *sid,
+ const struct dom_sid *sid,
const uint8 **cached_nt_pass,
const uint8 **cached_salt)
{
/* Store creds for a SID - only writes out new salted ones. */
NTSTATUS wcache_save_creds(struct winbindd_domain *domain,
- TALLOC_CTX *mem_ctx,
- const DOM_SID *sid,
+ const struct dom_sid *sid,
const uint8 nt_pass[NT_HASH_LEN])
{
struct cache_entry *centry;
const char *domain_name,
const char *name,
uint32_t flags,
- DOM_SID *sid,
+ struct dom_sid *sid,
enum lsa_SidType *type)
{
NTSTATUS status;
given */
static NTSTATUS sid_to_name(struct winbindd_domain *domain,
TALLOC_CTX *mem_ctx,
- const DOM_SID *sid,
+ const struct dom_sid *sid,
char **domain_name,
char **name,
enum lsa_SidType *type)
static NTSTATUS rids_to_names(struct winbindd_domain *domain,
TALLOC_CTX *mem_ctx,
- const DOM_SID *domain_sid,
+ const struct dom_sid *domain_sid,
uint32 *rids,
size_t num_rids,
char **domain_name,
have_mapped = have_unmapped = false;
for (i=0; i<num_rids; i++) {
- DOM_SID sid;
+ struct dom_sid sid;
struct cache_entry *centry;
fstring tmp;
have_mapped = have_unmapped = false;
for (i=0; i<num_rids; i++) {
- DOM_SID sid;
+ struct dom_sid sid;
struct cache_entry *centry;
fstring tmp;
*/
if (NT_STATUS_EQUAL(result, NT_STATUS_NONE_MAPPED)) {
for (i = 0; i < num_rids; i++) {
- DOM_SID sid;
+ struct dom_sid sid;
const char *name = "";
const enum lsa_SidType type = SID_NAME_UNKNOWN;
NTSTATUS status = NT_STATUS_NONE_MAPPED;
refresh_sequence_number(domain, false);
for (i=0; i<num_rids; i++) {
- DOM_SID sid;
+ struct dom_sid sid;
NTSTATUS status;
if (!sid_compose(&sid, domain_sid, rids[i])) {
/* Lookup user information from a rid */
static NTSTATUS query_user(struct winbindd_domain *domain,
TALLOC_CTX *mem_ctx,
- const DOM_SID *user_sid,
+ const struct dom_sid *user_sid,
struct wbint_userinfo *info)
{
NTSTATUS 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)
+ const struct dom_sid *user_sid,
+ uint32 *num_groups, struct dom_sid **user_gids)
{
struct cache_entry *centry = NULL;
NTSTATUS status;
static NTSTATUS lookup_useraliases(struct winbindd_domain *domain,
TALLOC_CTX *mem_ctx,
- uint32 num_sids, const DOM_SID *sids,
+ uint32 num_sids, const struct dom_sid *sids,
uint32 *num_aliases, uint32 **alias_rids)
{
struct cache_entry *centry = NULL;
return NT_STATUS_OK;
}
- *sid_mem = talloc_array(mem_ctx, DOM_SID, *num_names);
+ *sid_mem = talloc_array(mem_ctx, struct dom_sid, *num_names);
*names = talloc_array(mem_ctx, char *, *num_names);
*name_types = talloc_array(mem_ctx, uint32, *num_names);
static NTSTATUS lookup_groupmem(struct winbindd_domain *domain,
TALLOC_CTX *mem_ctx,
- const DOM_SID *group_sid,
+ const struct dom_sid *group_sid,
enum lsa_SidType type,
uint32 *num_names,
- DOM_SID **sid_mem, char ***names,
+ struct dom_sid **sid_mem, char ***names,
uint32 **name_types)
{
struct cache_entry *centry = NULL;
old_status = domain->online;
trusts->count = 0;
trusts->array = NULL;
- if (domain->online) {
- goto do_query;
- }
cache = get_cache(domain);
if (!cache || !cache->tdb) {
goto do_query;
}
+ if (domain->online) {
+ goto do_query;
+ }
+
retval = wcache_tdc_fetch_list(&dom_list, &num_domains);
if (!retval || !num_domains || !dom_list) {
TALLOC_FREE(dom_list);
void wcache_invalidate_samlogon(struct winbindd_domain *domain,
struct netr_SamInfo3 *info3)
{
- DOM_SID sid;
+ struct dom_sid sid;
fstring key_str, sid_string;
struct winbind_cache *cache;
return true;
}
+bool wcache_invalidate_cache_noinit(void)
+{
+ struct winbindd_domain *domain;
+
+ for (domain = domain_list(); domain; domain = domain->next) {
+ struct winbind_cache *cache;
+
+ /* Skip uninitialized domains. */
+ if (!domain->initialized && !domain->internal) {
+ continue;
+ }
+
+ cache = get_cache(domain);
+
+ DEBUG(10, ("wcache_invalidate_cache: invalidating cache "
+ "entries for %s\n", domain->name));
+ if (cache) {
+ if (cache->tdb) {
+ tdb_traverse(cache->tdb, traverse_fn, NULL);
+ /*
+ * Flushing cache has nothing to with domains.
+ * return here if we successfully flushed once.
+ * To avoid unnecessary traversing the cache.
+ */
+ return true;
+ } else {
+ return false;
+ }
+ }
+ }
+ return true;
+}
+
bool init_wcache(void)
{
if (wcache == NULL) {
/* when working offline we must not clear the cache on restart */
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),
+ TDB_INCOMPATIBLE_HASH |
+ (lp_winbind_offline_logon() ? TDB_DEFAULT : (TDB_DEFAULT | TDB_CLEAR_IF_FIRST)),
O_RDWR|O_CREAT, 0600);
if (wcache->tdb == NULL) {
}
}
-bool lookup_cached_sid(TALLOC_CTX *mem_ctx, const DOM_SID *sid,
+bool lookup_cached_sid(TALLOC_CTX *mem_ctx, const struct dom_sid *sid,
char **domain_name, char **name,
enum lsa_SidType *type)
{
return NT_STATUS_IS_OK(status);
}
-bool lookup_cached_name(TALLOC_CTX *mem_ctx,
- const char *domain_name,
+bool lookup_cached_name(const char *domain_name,
const char *name,
- DOM_SID *sid,
+ struct dom_sid *sid,
enum lsa_SidType *type)
{
struct winbindd_domain *domain;
void cache_name2sid(struct winbindd_domain *domain,
const char *domain_name, const char *name,
- enum lsa_SidType type, const DOM_SID *sid)
+ enum lsa_SidType type, const struct dom_sid *sid)
{
refresh_sequence_number(domain, false);
wcache_save_name_to_sid(domain, NT_STATUS_OK, domain_name, name,
/* when working offline we must not clear the cache on restart */
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),
+ TDB_INCOMPATIBLE_HASH |
+ (lp_winbind_offline_logon() ? TDB_DEFAULT : (TDB_DEFAULT | TDB_CLEAR_IF_FIRST)),
O_RDWR|O_CREAT, 0600);
if (!wcache->tdb) {
return 0;
}
-NTSTATUS wcache_remove_oldest_cached_creds(struct winbindd_domain *domain, const DOM_SID *sid)
+NTSTATUS wcache_remove_oldest_cached_creds(struct winbindd_domain *domain, const struct dom_sid *sid)
{
struct winbind_cache *cache = get_cache(domain);
NTSTATUS status;
(void)centry_uint32(centry);
if (NT_STATUS_IS_OK(centry->status)) {
- DOM_SID sid;
+ struct dom_sid sid;
(void)centry_sid(centry, &sid);
}
struct tdb_validation_status *state)
{
struct cache_entry *centry = create_centry_validate(keystr, dbuf, state);
- DOM_SID sid;
+ struct dom_sid sid;
if (!centry) {
return 1;
num_entries = (int32)centry_uint32(centry);
for (i=0; i< num_entries; i++) {
- DOM_SID sid;
+ struct dom_sid sid;
(void)centry_string(centry, mem_ctx);
(void)centry_string(centry, mem_ctx);
(void)centry_string(centry, mem_ctx);
num_groups = centry_uint32(centry);
for (i=0; i< num_groups; i++) {
- DOM_SID sid;
+ struct dom_sid sid;
centry_sid(centry, &sid);
}
num_names = centry_uint32(centry);
for (i=0; i< num_names; i++) {
- DOM_SID sid;
+ struct dom_sid sid;
centry_sid(centry, &sid);
(void)centry_string(centry, mem_ctx);
(void)centry_uint32(centry);
tdb = tdb_open_log(tdb_path,
WINBINDD_CACHE_TDB_DEFAULT_HASH_SIZE,
+ TDB_INCOMPATIBLE_HASH |
( lp_winbind_offline_logon()
? TDB_DEFAULT
: TDB_DEFAULT | TDB_CLEAR_IF_FIRST ),
static void wcache_save_user_pwinfo(struct winbindd_domain *domain,
NTSTATUS status,
- const DOM_SID *user_sid,
+ const struct dom_sid *user_sid,
const char *homedir,
const char *shell,
const char *gecos,
centry_free(centry);
}
+#ifdef HAVE_ADS
+
NTSTATUS nss_get_info_cached( struct winbindd_domain *domain,
- const DOM_SID *user_sid,
+ const struct dom_sid *user_sid,
TALLOC_CTX *ctx,
ADS_STRUCT *ads, LDAPMessage *msg,
const char **homedir, const char **shell,
return nt_status;
}
+#endif
/* the cache backend methods are exposed via this structure */
struct winbindd_methods cache_methods = {
TDB_DATA key, data;
bool ret = false;
- if (!wcache_opnum_cacheable(opnum)) {
+ if (!wcache_opnum_cacheable(opnum) ||
+ is_my_own_sam_domain(domain) ||
+ is_builtin_domain(domain)) {
return false;
}
TDB_DATA key, data;
uint32_t dom_seqnum, last_check;
- if (!wcache_opnum_cacheable(opnum)) {
+ if (!wcache_opnum_cacheable(opnum) ||
+ is_my_own_sam_domain(domain) ||
+ is_builtin_domain(domain)) {
return;
}