r6351: This is quite a large and intrusive patch, but there are not many pieces that
[metze/samba/wip.git] / source3 / passdb / pdb_interface.c
index 301dc101eb4116ceac3c4ad74630de3df8dc8ed7..edcd1c92223ecc116bca1ccff3e67b38dc24bf85 100644 (file)
@@ -549,24 +549,6 @@ static NTSTATUS context_delete_alias(struct pdb_context *context,
        return context->pdb_methods->delete_alias(context->pdb_methods, sid);
 }
 
-static NTSTATUS context_enum_aliases(struct pdb_context *context,
-                                    const DOM_SID *sid,
-                                    uint32 start_idx, uint32 max_entries,
-                                    uint32 *num_aliases,
-                                    struct acct_info **info)
-{
-       NTSTATUS ret = NT_STATUS_UNSUCCESSFUL;
-
-       if ((!context) || (!context->pdb_methods)) {
-               DEBUG(0, ("invalid pdb_context specified!\n"));
-               return ret;
-       }
-
-       return context->pdb_methods->enum_aliases(context->pdb_methods,
-                                                 sid, start_idx, max_entries,
-                                                 num_aliases, info);
-}
-
 static NTSTATUS context_get_aliasinfo(struct pdb_context *context,
                                      const DOM_SID *sid,
                                      struct acct_info *info)
@@ -683,6 +665,68 @@ static NTSTATUS context_lookup_rids(struct pdb_context *context,
                                                 rids, names, attrs);
 }
 
+static BOOL context_search_users(struct pdb_context *context,
+                                struct pdb_search *search, uint16 acct_flags)
+{
+       if ((!context) || (!context->pdb_methods)) {
+               DEBUG(0, ("invalid pdb_context specified!\n"));
+               return False;
+       }
+
+       return context->pdb_methods->search_users(context->pdb_methods,
+                                                 search, acct_flags);
+}
+
+static BOOL context_search_groups(struct pdb_context *context,
+                                 struct pdb_search *search)
+{
+       if ((!context) || (!context->pdb_methods)) {
+               DEBUG(0, ("invalid pdb_context specified!\n"));
+               return False;
+       }
+
+       return context->pdb_methods->search_groups(context->pdb_methods,
+                                                  search);
+}
+
+static BOOL context_search_aliases(struct pdb_context *context,
+                                  struct pdb_search *search,
+                                  const DOM_SID *sid)
+{
+       if ((!context) || (!context->pdb_methods)) {
+               DEBUG(0, ("invalid pdb_context specified!\n"));
+               return False;
+       }
+
+       return context->pdb_methods->search_aliases(context->pdb_methods,
+                                                   search, sid);
+}
+
+static BOOL context_search_next_entry(struct pdb_context *context,
+                                     struct pdb_search *search,
+                                     struct samr_displayentry *entry)
+{
+       if ((!context) || (!context->pdb_methods)) {
+               DEBUG(0, ("invalid pdb_context specified!\n"));
+               return False;
+       }
+
+       return context->pdb_methods->search_next_entry(context->pdb_methods,
+                                                      search, entry);
+}
+
+static void context_search_end(struct pdb_context *context,
+                              struct pdb_search *search)
+{
+       if ((!context) || (!context->pdb_methods)) {
+               DEBUG(0, ("invalid pdb_context specified!\n"));
+               return;
+       }
+
+       context->pdb_methods->search_end(context->pdb_methods, search);
+       return;
+}
+
 /******************************************************************
   Free and cleanup a pdb context, any associated data and anything
   that the attached modules might have associated.
@@ -805,7 +849,6 @@ static NTSTATUS make_pdb_context(struct pdb_context **context)
        (*context)->pdb_find_alias = context_find_alias;
        (*context)->pdb_create_alias = context_create_alias;
        (*context)->pdb_delete_alias = context_delete_alias;
-       (*context)->pdb_enum_aliases = context_enum_aliases;
        (*context)->pdb_get_aliasinfo = context_get_aliasinfo;
        (*context)->pdb_set_aliasinfo = context_set_aliasinfo;
        (*context)->pdb_add_aliasmem = context_add_aliasmem;
@@ -814,6 +857,12 @@ static NTSTATUS make_pdb_context(struct pdb_context **context)
        (*context)->pdb_enum_alias_memberships = context_enum_alias_memberships;
        (*context)->pdb_lookup_rids = context_lookup_rids;
 
+       (*context)->pdb_search_users = context_search_users;
+       (*context)->pdb_search_groups = context_search_groups;
+       (*context)->pdb_search_aliases = context_search_aliases;
+       (*context)->pdb_search_next_entry = context_search_next_entry;
+       (*context)->pdb_search_end = context_search_end;
+
        (*context)->free_fn = free_pdb_context;
 
        return NT_STATUS_OK;
@@ -1199,22 +1248,6 @@ BOOL pdb_delete_alias(const DOM_SID *sid)
                                                            
 }
 
-BOOL pdb_enum_aliases(const DOM_SID *sid, uint32 start_idx, uint32 max_entries,
-                     uint32 *num_aliases, struct acct_info **info)
-{
-       struct pdb_context *pdb_context = pdb_get_static_context(False);
-
-       if (!pdb_context) {
-               return False;
-       }
-
-       return NT_STATUS_IS_OK(pdb_context->pdb_enum_aliases(pdb_context, sid,
-                                                            start_idx,
-                                                            max_entries,
-                                                            num_aliases,
-                                                            info));
-}
-
 BOOL pdb_get_aliasinfo(const DOM_SID *sid, struct acct_info *info)
 {
        struct pdb_context *pdb_context = pdb_get_static_context(False);
@@ -1543,56 +1576,6 @@ NTSTATUS pdb_default_lookup_rids(struct pdb_methods *methods,
        return result;
 }
 
-NTSTATUS make_pdb_methods(TALLOC_CTX *mem_ctx, PDB_METHODS **methods) 
-{
-       *methods = TALLOC_P(mem_ctx, struct pdb_methods);
-
-       if (!*methods) {
-               return NT_STATUS_NO_MEMORY;
-       }
-
-       ZERO_STRUCTP(*methods);
-
-       (*methods)->setsampwent = pdb_default_setsampwent;
-       (*methods)->endsampwent = pdb_default_endsampwent;
-       (*methods)->getsampwent = pdb_default_getsampwent;
-       (*methods)->getsampwnam = pdb_default_getsampwnam;
-       (*methods)->getsampwsid = pdb_default_getsampwsid;
-       (*methods)->add_sam_account = pdb_default_add_sam_account;
-       (*methods)->update_sam_account = pdb_default_update_sam_account;
-       (*methods)->delete_sam_account = pdb_default_delete_sam_account;
-       (*methods)->update_login_attempts = pdb_default_update_login_attempts;
-
-       (*methods)->getgrsid = pdb_default_getgrsid;
-       (*methods)->getgrgid = pdb_default_getgrgid;
-       (*methods)->getgrnam = pdb_default_getgrnam;
-       (*methods)->add_group_mapping_entry = pdb_default_add_group_mapping_entry;
-       (*methods)->update_group_mapping_entry = pdb_default_update_group_mapping_entry;
-       (*methods)->delete_group_mapping_entry = pdb_default_delete_group_mapping_entry;
-       (*methods)->enum_group_mapping = pdb_default_enum_group_mapping;
-       (*methods)->enum_group_members = pdb_default_enum_group_members;
-       (*methods)->enum_group_memberships = pdb_default_enum_group_memberships;
-       (*methods)->find_alias = pdb_default_find_alias;
-       (*methods)->create_alias = pdb_default_create_alias;
-       (*methods)->delete_alias = pdb_default_delete_alias;
-       (*methods)->enum_aliases = pdb_default_enum_aliases;
-       (*methods)->get_aliasinfo = pdb_default_get_aliasinfo;
-       (*methods)->set_aliasinfo = pdb_default_set_aliasinfo;
-       (*methods)->add_aliasmem = pdb_default_add_aliasmem;
-       (*methods)->del_aliasmem = pdb_default_del_aliasmem;
-       (*methods)->enum_aliasmem = pdb_default_enum_aliasmem;
-       (*methods)->enum_alias_memberships = pdb_default_alias_memberships;
-       (*methods)->lookup_rids = pdb_default_lookup_rids;
-
-       return NT_STATUS_OK;
-}
-
-struct pdb_search *pdb_search_users(uint16 acct_flags);
-struct pdb_search *pdb_search_groups(void);
-struct pdb_search *pdb_search_aliases(const DOM_SID *sid);
-uint32 pdb_search_entries(struct pdb_search *search, uint32 start_idx, uint32 max_entries, struct samr_displayentry **result);
-void pdb_search_destroy(struct pdb_search *search);
-
 static struct pdb_search *pdb_search_init(enum pdb_search_type type)
 {
        TALLOC_CTX *mem_ctx;
@@ -1613,6 +1596,7 @@ static struct pdb_search *pdb_search_init(enum pdb_search_type type)
        result->mem_ctx = mem_ctx;
        result->type = type;
        result->cache = NULL;
+       result->num_entries = 0;
        result->cache_size = 0;
        result->search_ended = False;
 
@@ -1631,12 +1615,18 @@ static void fill_displayentry(TALLOC_CTX *mem_ctx, uint32 rid,
 
        if (account_name != NULL)
                entry->account_name = talloc_strdup(mem_ctx, account_name);
+       else
+               entry->account_name = "";
 
        if (fullname != NULL)
                entry->fullname = talloc_strdup(mem_ctx, fullname);
+       else
+               entry->fullname = "";
 
        if (description != NULL)
                entry->description = talloc_strdup(mem_ctx, description);
+       else
+               entry->description = "";
 }
 
 static BOOL user_search_in_progress = False;
@@ -1644,40 +1634,38 @@ struct user_search {
        uint16 acct_flags;
 };
 
-struct pdb_search *pdb_search_users(uint16 acct_flags)
+static BOOL pdb_default_search_users(struct pdb_methods *methods,
+                                    struct pdb_search *search,
+                                    uint16 acct_flags)
 {
-       struct pdb_search *result;
        struct user_search *state;
 
        if (user_search_in_progress) {
                DEBUG(1, ("user search in progress\n"));
-               return NULL;
+               return False;
        }
 
-       if (!pdb_setsampwent(False, acct_flags))
-               return NULL;
+       if (!pdb_setsampwent(False, acct_flags)) {
+               DEBUG(5, ("Could not start search\n"));
+               return False;
+       }
 
        user_search_in_progress = True;
 
-       result = pdb_search_init(PDB_USER_SEARCH);
-       if (result == NULL)
-               return NULL;
-
-       state = TALLOC_P(result->mem_ctx, struct user_search);
+       state = TALLOC_P(search->mem_ctx, struct user_search);
        if (state == NULL) {
                DEBUG(0, ("talloc failed\n"));
-               talloc_destroy(result->mem_ctx);
-               return NULL;
+               return False;
        }
 
        state->acct_flags = acct_flags;
 
-       result->private = state;
-       return result;
+       search->private = state;
+       return True;
 }
 
-static BOOL pdb_search_entry_users(struct pdb_search *s, TALLOC_CTX *mem_ctx,
-                                  struct samr_displayentry *entry)
+static BOOL pdb_search_next_entry_users(struct pdb_search *s,
+                                       struct samr_displayentry *entry)
 {
        struct user_search *state = s->private;
        SAM_ACCOUNT *user = NULL;
@@ -1701,7 +1689,7 @@ static BOOL pdb_search_entry_users(struct pdb_search *s, TALLOC_CTX *mem_ctx,
                goto next;
        }
 
-       fill_displayentry(mem_ctx, pdb_get_user_rid(user),
+       fill_displayentry(s->mem_ctx, pdb_get_user_rid(user),
                          pdb_get_acct_ctrl(user), pdb_get_username(user),
                          pdb_get_fullname(user), pdb_get_acct_desc(user),
                          entry);
@@ -1721,36 +1709,30 @@ struct group_search {
        int num_groups, current_group;
 };
 
-struct pdb_search *pdb_search_groups(void)
+static BOOL pdb_default_search_groups(struct pdb_methods *methods,
+                                     struct pdb_search *search)
 {
-       struct pdb_search *result;
        struct group_search *state;
 
-       result = pdb_search_init(PDB_GROUP_SEARCH);
-       if (result == NULL)
-               return NULL;
-
-       state = TALLOC_P(result->mem_ctx, struct group_search);
+       state = TALLOC_P(search->mem_ctx, struct group_search);
        if (state == NULL) {
                DEBUG(0, ("talloc failed\n"));
-               talloc_destroy(result->mem_ctx);
-               return NULL;
+               return False;
        }
 
        if (!pdb_enum_group_mapping(SID_NAME_DOM_GRP, &state->groups,
                                    &state->num_groups, True)) {
                DEBUG(0, ("Could not enum groups\n"));
-               talloc_destroy(result->mem_ctx);
-               return NULL;
+               return False;
        }
 
        state->current_group = 0;
-       result->private = state;
-       return result;
+       search->private = state;
+       return True;
 }
 
-static BOOL pdb_search_entry_group(struct pdb_search *s, TALLOC_CTX *mem_ctx,
-                                  struct samr_displayentry *entry)
+static BOOL pdb_search_next_entry_group(struct pdb_search *s,
+                                       struct samr_displayentry *entry)
 {
        struct group_search *state = s->private;
        uint32 rid;
@@ -1761,7 +1743,7 @@ static BOOL pdb_search_entry_group(struct pdb_search *s, TALLOC_CTX *mem_ctx,
 
        sid_peek_rid(&map->sid, &rid);
 
-       fill_displayentry(mem_ctx, rid, 0, map->nt_name, NULL, map->comment,
+       fill_displayentry(s->mem_ctx, rid, 0, map->nt_name, NULL, map->comment,
                          entry);
 
        state->current_group += 1;
@@ -1779,51 +1761,43 @@ struct alias_search {
        int num_aliases, current_alias;
 };
 
-struct pdb_search *pdb_search_aliases(const DOM_SID *sid)
+static BOOL pdb_default_search_aliases(struct pdb_methods *methods,
+                                      struct pdb_search *search,
+                                      const DOM_SID *sid)
 {
-       struct pdb_search *result;
        struct alias_search *state;
        enum SID_NAME_USE type = SID_NAME_UNKNOWN;
-       DOM_SID builtin_sid;
 
        if (sid_equal(sid, get_global_sam_sid()))
                type = SID_NAME_ALIAS;
 
-       string_to_sid(&builtin_sid, "S-1-5-32");
-
-       if (sid_equal(sid, &builtin_sid))
+       if (sid_equal(sid, &global_sid_Builtin))
                type = SID_NAME_WKN_GRP;
 
        if (type == SID_NAME_UNKNOWN) {
                DEBUG(3, ("unknown domain sid: %s\n", sid_string_static(sid)));
-               return NULL;
+               return False;
        }
 
-       result = pdb_search_init(PDB_ALIAS_SEARCH);
-       if (result == NULL)
-               return NULL;
-
-       state = TALLOC_P(result->mem_ctx, struct alias_search);
+       state = TALLOC_P(search->mem_ctx, struct alias_search);
        if (state == NULL) {
                DEBUG(0, ("talloc failed\n"));
-               talloc_destroy(result->mem_ctx);
-               return NULL;
+               return False;
        }
 
        if (!pdb_enum_group_mapping(type, &state->aliases,
                                    &state->num_aliases, False)) {
                DEBUG(0, ("Could not enum aliases\n"));
-               talloc_destroy(result->mem_ctx);
-               return NULL;
+               return False;
        }
 
        state->current_alias = 0;
-       result->private = state;
-       return result;
+       search->private = state;
+       return True;
 }
 
-static BOOL pdb_search_entry_alias(struct pdb_search *s, TALLOC_CTX *mem_ctx,
-                                  struct samr_displayentry *entry)
+static BOOL pdb_search_next_entry_alias(struct pdb_search *s,
+                                       struct samr_displayentry *entry)
 {
        struct alias_search *state = s->private;
        uint32 rid;
@@ -1834,7 +1808,7 @@ static BOOL pdb_search_entry_alias(struct pdb_search *s, TALLOC_CTX *mem_ctx,
 
        sid_peek_rid(&map->sid, &rid);
 
-       fill_displayentry(mem_ctx, rid, 0, map->nt_name, NULL, map->comment,
+       fill_displayentry(s->mem_ctx, rid, 0, map->nt_name, NULL, map->comment,
                          entry);
 
        state->current_alias += 1;
@@ -1847,19 +1821,20 @@ static void pdb_search_end_aliases(struct pdb_search *search)
        SAFE_FREE(state->aliases);
 }
 
-static BOOL pdb_search_entry(struct pdb_search *search, TALLOC_CTX *mem_ctx,
-                            struct samr_displayentry *entry)
+static BOOL pdb_default_search_next_entry(struct pdb_methods *pdb_methods,
+                                         struct pdb_search *search,
+                                         struct samr_displayentry *entry)
 {
        BOOL result = False;
        switch (search->type) {
        case PDB_USER_SEARCH:
-               result = pdb_search_entry_users(search, mem_ctx, entry);
+               result = pdb_search_next_entry_users(search, entry);
                break;
        case PDB_GROUP_SEARCH:
-               result = pdb_search_entry_group(search, mem_ctx, entry);
+               result = pdb_search_next_entry_group(search, entry);
                break;
        case PDB_ALIAS_SEARCH:
-               result = pdb_search_entry_alias(search, mem_ctx, entry);
+               result = pdb_search_next_entry_alias(search, entry);
                break;
        default:
                DEBUG(0, ("unknown search type: %d\n", search->type));
@@ -1868,7 +1843,18 @@ static BOOL pdb_search_entry(struct pdb_search *search, TALLOC_CTX *mem_ctx,
        return result;
 }
 
-static void pdb_search_end(struct pdb_search *search)
+static BOOL pdb_search_next_entry(struct pdb_search *search,
+                                 struct samr_displayentry *entry)
+{
+       struct pdb_context *pdb_context = pdb_get_static_context(False);
+
+       if (pdb_context == NULL) return False;
+
+       return pdb_context->pdb_search_next_entry(pdb_context, search, entry);
+}
+
+static void pdb_default_search_end(struct pdb_methods *pdb_methods,
+                                  struct pdb_search *search)
 {
        switch (search->type) {
        case PDB_USER_SEARCH:
@@ -1886,29 +1872,90 @@ static void pdb_search_end(struct pdb_search *search)
        }
 }
 
+static void pdb_search_end(struct pdb_search *search)
+{
+       struct pdb_context *pdb_context = pdb_get_static_context(False);
+
+       if (pdb_context == NULL) return;
+
+       pdb_context->pdb_search_end(pdb_context, search);
+}
+
 static struct samr_displayentry *pdb_search_getentry(struct pdb_search *search,
                                                     uint32 idx)
 {
-       if (idx < search->cache_size)
+       if (idx < search->num_entries)
                return &search->cache[idx];
 
        if (search->search_ended)
                return NULL;
 
-       while (idx >= search->cache_size) {
+       while (idx >= search->num_entries) {
                struct samr_displayentry entry;
 
-               if (!pdb_search_entry(search, search->mem_ctx, &entry)) {
+               if (!pdb_search_next_entry(search, &entry)) {
                        pdb_search_end(search);
                        search->search_ended = True;
                        break;
                }
 
-               ADD_TO_ARRAY(search->mem_ctx, struct samr_displayentry,
-                            entry, &search->cache, &search->cache_size);
+               ADD_TO_LARGE_ARRAY(search->mem_ctx, struct samr_displayentry,
+                                  entry, &search->cache, &search->num_entries,
+                                  &search->cache_size);
+       }
+
+       return (search->num_entries > idx) ? &search->cache[idx] : NULL;
+}
+
+struct pdb_search *pdb_search_users(uint16 acct_flags)
+{
+       struct pdb_context *pdb_context = pdb_get_static_context(False);
+       struct pdb_search *result;
+
+       if (pdb_context == NULL) return NULL;
+
+       result = pdb_search_init(PDB_USER_SEARCH);
+       if (result == NULL) return NULL;
+
+       if (!pdb_context->pdb_search_users(pdb_context, result, acct_flags)) {
+               talloc_destroy(result->mem_ctx);
+               return NULL;
+       }
+       return result;
+}
+
+struct pdb_search *pdb_search_groups(void)
+{
+       struct pdb_context *pdb_context = pdb_get_static_context(False);
+       struct pdb_search *result;
+
+       if (pdb_context == NULL) return NULL;
+
+       result = pdb_search_init(PDB_GROUP_SEARCH);
+       if (result == NULL) return NULL;
+
+       if (!pdb_context->pdb_search_groups(pdb_context, result)) {
+               talloc_destroy(result->mem_ctx);
+               return NULL;
        }
+       return result;
+}
+
+struct pdb_search *pdb_search_aliases(const DOM_SID *sid)
+{
+       struct pdb_context *pdb_context = pdb_get_static_context(False);
+       struct pdb_search *result;
 
-       return (search->cache_size > idx) ? &search->cache[idx] : NULL;
+       if (pdb_context == NULL) return NULL;
+
+       result = pdb_search_init(PDB_ALIAS_SEARCH);
+       if (result == NULL) return NULL;
+
+       if (!pdb_context->pdb_search_aliases(pdb_context, result, sid)) {
+               talloc_destroy(result->mem_ctx);
+               return NULL;
+       }
+       return result;
 }
 
 uint32 pdb_search_entries(struct pdb_search *search,
@@ -1928,10 +1975,10 @@ uint32 pdb_search_entries(struct pdb_search *search,
        if (end_entry != NULL)
                return max_entries;
 
-       if (start_idx >= search->cache_size)
+       if (start_idx >= search->num_entries)
                return 0;
 
-       return search->cache_size - start_idx;
+       return search->num_entries - start_idx;
 }
 
 void pdb_search_destroy(struct pdb_search *search)
@@ -1944,3 +1991,51 @@ void pdb_search_destroy(struct pdb_search *search)
 
        talloc_destroy(search->mem_ctx);
 }
+
+NTSTATUS make_pdb_methods(TALLOC_CTX *mem_ctx, PDB_METHODS **methods) 
+{
+       *methods = TALLOC_P(mem_ctx, struct pdb_methods);
+
+       if (!*methods) {
+               return NT_STATUS_NO_MEMORY;
+       }
+
+       ZERO_STRUCTP(*methods);
+
+       (*methods)->setsampwent = pdb_default_setsampwent;
+       (*methods)->endsampwent = pdb_default_endsampwent;
+       (*methods)->getsampwent = pdb_default_getsampwent;
+       (*methods)->getsampwnam = pdb_default_getsampwnam;
+       (*methods)->getsampwsid = pdb_default_getsampwsid;
+       (*methods)->add_sam_account = pdb_default_add_sam_account;
+       (*methods)->update_sam_account = pdb_default_update_sam_account;
+       (*methods)->delete_sam_account = pdb_default_delete_sam_account;
+       (*methods)->update_login_attempts = pdb_default_update_login_attempts;
+
+       (*methods)->getgrsid = pdb_default_getgrsid;
+       (*methods)->getgrgid = pdb_default_getgrgid;
+       (*methods)->getgrnam = pdb_default_getgrnam;
+       (*methods)->add_group_mapping_entry = pdb_default_add_group_mapping_entry;
+       (*methods)->update_group_mapping_entry = pdb_default_update_group_mapping_entry;
+       (*methods)->delete_group_mapping_entry = pdb_default_delete_group_mapping_entry;
+       (*methods)->enum_group_mapping = pdb_default_enum_group_mapping;
+       (*methods)->enum_group_members = pdb_default_enum_group_members;
+       (*methods)->enum_group_memberships = pdb_default_enum_group_memberships;
+       (*methods)->find_alias = pdb_default_find_alias;
+       (*methods)->create_alias = pdb_default_create_alias;
+       (*methods)->delete_alias = pdb_default_delete_alias;
+       (*methods)->get_aliasinfo = pdb_default_get_aliasinfo;
+       (*methods)->set_aliasinfo = pdb_default_set_aliasinfo;
+       (*methods)->add_aliasmem = pdb_default_add_aliasmem;
+       (*methods)->del_aliasmem = pdb_default_del_aliasmem;
+       (*methods)->enum_aliasmem = pdb_default_enum_aliasmem;
+       (*methods)->enum_alias_memberships = pdb_default_alias_memberships;
+       (*methods)->lookup_rids = pdb_default_lookup_rids;
+       (*methods)->search_users = pdb_default_search_users;
+       (*methods)->search_groups = pdb_default_search_groups;
+       (*methods)->search_aliases = pdb_default_search_aliases;
+       (*methods)->search_next_entry = pdb_default_search_next_entry;
+       (*methods)->search_end = pdb_default_search_end;
+
+       return NT_STATUS_OK;
+}