r16945: Sync trunk -> 3.0 for 3.0.24 code. Still need
[ira/wip.git] / source3 / nsswitch / winbindd_cache.c
index b267a3f770517425e3e2fe8ae73824038b1de58f..95a66420c5918609d402e5c41a961839a7d9cede 100644 (file)
@@ -66,7 +66,7 @@ void winbindd_check_cache_size(time_t t)
                return;
        }
 
-       if (fstat(wcache->tdb->fd, &st) == -1) {
+       if (fstat(tdb_fd(wcache->tdb), &st) == -1) {
                DEBUG(0, ("Unable to check size of tdb cache %s!\n", strerror(errno) ));
                return;
        }
@@ -259,7 +259,7 @@ static char *centry_string(struct cache_entry *centry, TALLOC_CTX *mem_ctx)
                smb_panic("centry_string");
        }
 
-       ret = TALLOC(mem_ctx, len+1);
+       ret = TALLOC_ARRAY(mem_ctx, char, len+1);
        if (!ret) {
                smb_panic("centry_string out of memory\n");
        }
@@ -567,7 +567,8 @@ static void centry_expand(struct cache_entry *centry, uint32 len)
        if (centry->len - centry->ofs >= len)
                return;
        centry->len *= 2;
-       centry->data = SMB_REALLOC(centry->data, centry->len);
+       centry->data = SMB_REALLOC_ARRAY(centry->data, unsigned char,
+                                        centry->len);
        if (!centry->data) {
                DEBUG(0,("out of memory: needed %d bytes in centry_expand\n", centry->len));
                smb_panic("out of memory in centry_expand");
@@ -1316,6 +1317,128 @@ do_query:
        return status;
 }
 
+static NTSTATUS rids_to_names(struct winbindd_domain *domain,
+                             TALLOC_CTX *mem_ctx,
+                             const DOM_SID *domain_sid,
+                             uint32 *rids,
+                             size_t num_rids,
+                             char **domain_name,
+                             char ***names,
+                             enum SID_NAME_USE **types)
+{
+       struct winbind_cache *cache = get_cache(domain);
+       size_t i;
+       NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
+       BOOL have_mapped;
+       BOOL have_unmapped;
+
+       *domain_name = NULL;
+       *names = NULL;
+       *types = NULL;
+
+       if (!cache->tdb) {
+               goto do_query;
+       }
+
+       if (num_rids == 0) {
+               return NT_STATUS_OK;
+       }
+
+       *names = TALLOC_ARRAY(mem_ctx, char *, num_rids);
+       *types = TALLOC_ARRAY(mem_ctx, enum SID_NAME_USE, num_rids);
+
+       if ((*names == NULL) || (*types == NULL)) {
+               result = NT_STATUS_NO_MEMORY;
+               goto error;
+       }
+
+       have_mapped = have_unmapped = False;
+
+       for (i=0; i<num_rids; i++) {
+               DOM_SID sid;
+               struct cache_entry *centry;
+
+               if (!sid_compose(&sid, domain_sid, rids[i])) {
+                       result = NT_STATUS_INTERNAL_ERROR;
+                       goto error;
+               }
+
+               centry = wcache_fetch(cache, domain, "SN/%s",
+                                     sid_string_static(&sid));
+               if (!centry) {
+                       goto do_query;
+               }
+
+               (*types)[i] = SID_NAME_UNKNOWN;
+               (*names)[i] = talloc_strdup(*names, "");
+
+               if (NT_STATUS_IS_OK(centry->status)) {
+                       char *dom;
+                       have_mapped = True;
+                       (*types)[i] = (enum SID_NAME_USE)centry_uint32(centry);
+                       dom = centry_string(centry, mem_ctx);
+                       if (*domain_name == NULL) {
+                               *domain_name = dom;
+                       } else {
+                               talloc_free(dom);
+                       }
+                       (*names)[i] = centry_string(centry, *names);
+               } else {
+                       have_unmapped = True;
+               }
+
+               centry_free(centry);
+       }
+
+       if (!have_mapped) {
+               return NT_STATUS_NONE_MAPPED;
+       }
+       if (!have_unmapped) {
+               return NT_STATUS_OK;
+       }
+       return STATUS_SOME_UNMAPPED;
+
+ do_query:
+
+       TALLOC_FREE(*names);
+       TALLOC_FREE(*types);
+
+       result = domain->backend->rids_to_names(domain, mem_ctx, domain_sid,
+                                               rids, num_rids, domain_name,
+                                               names, types);
+
+       if (!NT_STATUS_IS_OK(result) &&
+           !NT_STATUS_EQUAL(result, STATUS_SOME_UNMAPPED)) {
+               return result;
+       }
+
+       refresh_sequence_number(domain, False);
+
+       for (i=0; i<num_rids; i++) {
+               DOM_SID sid;
+               NTSTATUS status;
+
+               if (!sid_compose(&sid, domain_sid, rids[i])) {
+                       result = NT_STATUS_INTERNAL_ERROR;
+                       goto error;
+               }
+
+               status = (*types)[i] == SID_NAME_UNKNOWN ?
+                       NT_STATUS_NONE_MAPPED : NT_STATUS_OK;
+
+               wcache_save_sid_to_name(domain, status, &sid, *domain_name,
+                                       (*names)[i], (*types)[i]);
+       }
+
+       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, 
@@ -1914,7 +2037,7 @@ void cache_store_response(pid_t pid, struct winbindd_response *response)
 
        fstr_sprintf(key_str, "DR/%d", pid);
        if (tdb_store(wcache->tdb, string_tdb_data(key_str), 
-                     make_tdb_data((void *)response, sizeof(*response)),
+                     make_tdb_data((const char *)response, sizeof(*response)),
                      TDB_REPLACE) == -1)
                return;
 
@@ -1928,7 +2051,7 @@ void cache_store_response(pid_t pid, struct winbindd_response *response)
 
        fstr_sprintf(key_str, "DE/%d", pid);
        if (tdb_store(wcache->tdb, string_tdb_data(key_str),
-                     make_tdb_data(response->extra_data.data,
+                     make_tdb_data((const char *)response->extra_data.data,
                                    response->length - sizeof(*response)),
                      TDB_REPLACE) == 0)
                return;
@@ -2313,7 +2436,7 @@ BOOL set_global_winbindd_state_offline(void)
                return True;
        }
 
-       wcache->tdb->ecode = 0;
+/*     wcache->tdb->ecode = 0; */
 
        data = tdb_fetch_bystring( wcache->tdb, "WINBINDD_OFFLINE" );
 
@@ -2368,6 +2491,7 @@ struct winbindd_methods cache_methods = {
        enum_local_groups,
        name_to_sid,
        sid_to_name,
+       rids_to_names,
        query_user,
        lookup_usergroups,
        lookup_useraliases,