r4847: Hand over a acb_mask to pdb_setsampwent in load_sampwd_entries().
authorGünther Deschner <gd@samba.org>
Wed, 19 Jan 2005 16:13:26 +0000 (16:13 +0000)
committerGerald (Jerry) Carter <jerry@samba.org>
Wed, 10 Oct 2007 15:53:59 +0000 (10:53 -0500)
This allows the ldap-backend to search much more effeciently. Machines
will be searched in the ldap_machine_suffix and users in the
ldap_users_suffix. (Note that we already use the ldap_group_suffix in
ldapsam_setsamgrent for quite some time).

Using the specific ldap-bases becomes notably important in large
domains: On my testmachine "net rpc trustdom list" has to search through
40k accounts just to list 3 interdomain-trust-accounts, similiar effects
show up the non-user query_dispinfo-calls, etc.

Also renamed all_machines to only_machines in load_sampwd_entries()
since that reflects better what is really meant.

Guenther
(This used to be commit 6394257cc721ca739bda0e320375f04506913533)

source3/include/passdb.h
source3/passdb/pdb_interface.c
source3/passdb/pdb_ldap.c
source3/passdb/pdb_mysql.c
source3/passdb/pdb_pgsql.c
source3/passdb/pdb_smbpasswd.c
source3/passdb/pdb_tdb.c
source3/passdb/pdb_xml.c
source3/rpc_server/srv_samr_nt.c
source3/smbd/lanman.c
source3/utils/pdbedit.c

index db6bc2ac75ec9d5d2a80df6887dabf030d136502..1b9ccc50ee47e872253c54c5ccfb8fbd4e4edeaa 100644 (file)
@@ -241,7 +241,7 @@ struct acct_info
  * this SAMBA will load. Increment this if *ANY* changes are made to the interface. 
  */
 
-#define PASSDB_INTERFACE_VERSION 5
+#define PASSDB_INTERFACE_VERSION 6
 
 typedef struct pdb_context 
 {
@@ -251,7 +251,7 @@ typedef struct pdb_context
        /* These functions are wrappers for the functions listed above.
           They may do extra things like re-reading a SAM_ACCOUNT on update */
 
-       NTSTATUS (*pdb_setsampwent)(struct pdb_context *, BOOL update);
+       NTSTATUS (*pdb_setsampwent)(struct pdb_context *, BOOL update, uint16 acb_mask);
        
        void (*pdb_endsampwent)(struct pdb_context *);
        
@@ -349,7 +349,7 @@ typedef struct pdb_methods
        struct pdb_methods *next;
        struct pdb_methods *prev;
 
-       NTSTATUS (*setsampwent)(struct pdb_methods *, BOOL update);
+       NTSTATUS (*setsampwent)(struct pdb_methods *, BOOL update, uint16 acb_mask);
        
        void (*endsampwent)(struct pdb_methods *);
        
index 9bc38fb44491c5a5a76ca9d4f81a67d3e2251d22..ea097c10f694d87a5db4200f114a58bc522f85b6 100644 (file)
@@ -119,7 +119,7 @@ static struct pdb_init_function_entry *pdb_find_backend_entry(const char *name)
        return NULL;
 }
 
-static NTSTATUS context_setsampwent(struct pdb_context *context, BOOL update)
+static NTSTATUS context_setsampwent(struct pdb_context *context, BOOL update, uint16 acb_mask)
 {
        NTSTATUS ret = NT_STATUS_UNSUCCESSFUL;
 
@@ -135,7 +135,7 @@ static NTSTATUS context_setsampwent(struct pdb_context *context, BOOL update)
                return ret;
        }
 
-       while (NT_STATUS_IS_ERR(ret = context->pwent_methods->setsampwent(context->pwent_methods, update))) {
+       while (NT_STATUS_IS_ERR(ret = context->pwent_methods->setsampwent(context->pwent_methods, update, acb_mask))) {
                context->pwent_methods = context->pwent_methods->next;
                if (context->pwent_methods == NULL) 
                        return NT_STATUS_UNSUCCESSFUL;
@@ -176,7 +176,7 @@ static NTSTATUS context_getsampwent(struct pdb_context *context, SAM_ACCOUNT *us
                if (context->pwent_methods == NULL)
                        return ret;
        
-               context->pwent_methods->setsampwent(context->pwent_methods, False);
+               context->pwent_methods->setsampwent(context->pwent_methods, False, 0);
        }
        user->methods = context->pwent_methods;
        pdb_force_pw_initialization(user);
@@ -857,7 +857,7 @@ static struct pdb_context *pdb_get_static_context(BOOL reload)
  Backward compatibility functions for the original passdb interface
 *******************************************************************/
 
-BOOL pdb_setsampwent(BOOL update) 
+BOOL pdb_setsampwent(BOOL update, uint16 acb_mask
 {
        struct pdb_context *pdb_context = pdb_get_static_context(False);
 
@@ -865,7 +865,7 @@ BOOL pdb_setsampwent(BOOL update)
                return False;
        }
 
-       return NT_STATUS_IS_OK(pdb_context->pdb_setsampwent(pdb_context, update));
+       return NT_STATUS_IS_OK(pdb_context->pdb_setsampwent(pdb_context, update, acb_mask));
 }
 
 void pdb_endsampwent(void) 
@@ -1243,7 +1243,7 @@ static NTSTATUS pdb_default_delete_sam_account (struct pdb_methods *methods, SAM
        return NT_STATUS_NOT_IMPLEMENTED;
 }
 
-static NTSTATUS pdb_default_setsampwent(struct pdb_methods *methods, BOOL update)
+static NTSTATUS pdb_default_setsampwent(struct pdb_methods *methods, BOOL update, uint16 acb_mask)
 {
        return NT_STATUS_NOT_IMPLEMENTED;
 }
index ee0cb260e8bd0f457a17ba45ba02c8259a6b1308..2cc1798d3fdfb265f93fd7bb2a740783ef614775 100644 (file)
@@ -1180,33 +1180,48 @@ static BOOL init_ldap_from_sam (struct ldapsam_privates *ldap_state,
  Connect to LDAP server for password enumeration.
 *********************************************************************/
 
-static NTSTATUS ldapsam_setsampwent(struct pdb_methods *my_methods, BOOL update)
+static NTSTATUS ldapsam_setsampwent(struct pdb_methods *my_methods, BOOL update, uint16 acb_mask)
 {
        struct ldapsam_privates *ldap_state = (struct ldapsam_privates *)my_methods->private_data;
        int rc;
-       pstring filter;
+       pstring filter, suffix;
        char **attr_list;
+       BOOL machine_mask = False, user_mask = False;
 
        pstr_sprintf( filter, "(&%s%s)", lp_ldap_filter(), 
                get_objclass_filter(ldap_state->schema_ver));
        all_string_sub(filter, "%u", "*", sizeof(pstring));
 
+       machine_mask    = ((acb_mask != 0) && (acb_mask & (ACB_WSTRUST|ACB_SVRTRUST|ACB_DOMTRUST)));
+       user_mask       = ((acb_mask != 0) && (acb_mask & ACB_NORMAL));
+
+       if (machine_mask) {
+               pstrcpy(suffix, lp_ldap_machine_suffix());
+       } else if (user_mask) {
+               pstrcpy(suffix, lp_ldap_user_suffix());
+       } else {
+               pstrcpy(suffix, lp_ldap_suffix());
+       }
+
+       DEBUG(10,("ldapsam_setsampwent: LDAP Query for acb_mask 0x%x will use suffix %s\n", 
+               acb_mask, suffix));
+
        attr_list = get_userattr_list(ldap_state->schema_ver);
-       rc = smbldap_search_suffix(ldap_state->smbldap_state, filter, 
-                                  attr_list, &ldap_state->result);
+       rc = smbldap_search(ldap_state->smbldap_state, suffix, LDAP_SCOPE_SUBTREE, filter, 
+                           attr_list, 0, &ldap_state->result);
        free_attr_list( attr_list );
 
        if (rc != LDAP_SUCCESS) {
                DEBUG(0, ("ldapsam_setsampwent: LDAP search failed: %s\n", ldap_err2string(rc)));
-               DEBUG(3, ("ldapsam_setsampwent: Query was: %s, %s\n", lp_ldap_suffix(), filter));
+               DEBUG(3, ("ldapsam_setsampwent: Query was: %s, %s\n", suffix, filter));
                ldap_msgfree(ldap_state->result);
                ldap_state->result = NULL;
                return NT_STATUS_UNSUCCESSFUL;
        }
 
-       DEBUG(2, ("ldapsam_setsampwent: %d entries in the base!\n",
-               ldap_count_entries(ldap_state->smbldap_state->ldap_struct,
-               ldap_state->result)));
+       DEBUG(2, ("ldapsam_setsampwent: %d entries in the base %s\n",
+               ldap_count_entries(ldap_state->smbldap_state->ldap_struct, 
+               ldap_state->result), suffix));
 
        ldap_state->entry = ldap_first_entry(ldap_state->smbldap_state->ldap_struct,
                                 ldap_state->result);
index 500c9686c5e535bea2d9fda42ec4bdaab9fce496..fbe44233245e2591a6a4c3b410e97c6fa28336b2 100644 (file)
@@ -120,7 +120,7 @@ static NTSTATUS row_to_sam_account(MYSQL_RES * r, SAM_ACCOUNT * u)
        return NT_STATUS_OK;
 }
 
-static NTSTATUS mysqlsam_setsampwent(struct pdb_methods *methods, BOOL update)
+static NTSTATUS mysqlsam_setsampwent(struct pdb_methods *methods, BOOL update, uint16 acb_mask)
 {
        struct pdb_mysql_data *data =
                (struct pdb_mysql_data *) methods->private_data;
index 6578d3d192a97cc27a6ecd0086e587bb65c219b6..0955ea1881f53184ba9b1027f0fad0367f25a96c 100644 (file)
@@ -118,7 +118,7 @@ static NTSTATUS row_to_sam_account ( PGresult *r, long row, SAM_ACCOUNT *u )
   return NT_STATUS_OK ;
 }
 
-static NTSTATUS pgsqlsam_setsampwent(struct pdb_methods *methods, BOOL update)
+static NTSTATUS pgsqlsam_setsampwent(struct pdb_methods *methods, BOOL update, uint16 acb_mask)
 {
   struct pdb_pgsql_data *data ;
   char *query ;
index d75d0ed5c8ce735ee0972373cdaa480e3d286aa1..edb578b1e7447bbeee1f900391cf5faccce5e176 100644 (file)
@@ -1226,7 +1226,7 @@ static BOOL build_sam_account(struct smbpasswd_privates *smbpasswd_state,
  Functions to be implemented by the new passdb API 
  ****************************************************************/
 
-static NTSTATUS smbpasswd_setsampwent (struct pdb_methods *my_methods, BOOL update)
+static NTSTATUS smbpasswd_setsampwent (struct pdb_methods *my_methods, BOOL update, uint16 acb_mask)
 {
        struct smbpasswd_privates *smbpasswd_state = (struct smbpasswd_privates*)my_methods->private_data;
        
index 53baaf580de541e07dbe912cb19852335929fbfc..755e33940b8dedd492f76de9c814c8fce9cfb92b 100644 (file)
@@ -294,7 +294,7 @@ static int tdbsam_traverse_setpwent(TDB_CONTEXT *t, TDB_DATA key, TDB_DATA data,
  Save a list of user keys for iteration.
 ****************************************************************/
 
-static NTSTATUS tdbsam_setsampwent(struct pdb_methods *my_methods, BOOL update)
+static NTSTATUS tdbsam_setsampwent(struct pdb_methods *my_methods, BOOL update, uint16 acb_mask)
 {
        uint32 flags = update ? (O_RDWR|O_CREAT) : O_RDONLY;
        
index 6eb7761a3b477094e7e1e801b37f40fd833adf59..2a21fc8c9f5af812b782b73c107d4b87b5169d89 100644 (file)
@@ -307,7 +307,7 @@ static xmlNodePtr parseSambaXMLFile(struct pdb_xml *data)
        return cur;
 }
 
-static NTSTATUS xmlsam_setsampwent(struct pdb_methods *methods, BOOL update)
+static NTSTATUS xmlsam_setsampwent(struct pdb_methods *methods, BOOL update, uint16 acb_mask)
 {
        pdb_xml *data;
 
index 515eefb1fa6945ce6794ab0d55534b1f14325189..70c0de7da784b6481fd1f601ec4a43c68124dfd1 100644 (file)
@@ -56,7 +56,7 @@ struct samr_info {
        uint32 status; /* some sort of flag.  best to record it.  comes from opnum 0x39 */
        uint32 acc_granted;
        uint16 acb_mask;
-       BOOL all_machines;
+       BOOL only_machines;
        DISP_INFO disp_info;
 
        TALLOC_CTX *mem_ctx;
@@ -209,34 +209,40 @@ static void samr_clear_sam_passwd(SAM_ACCOUNT *sam_pass)
 }
 
 
-static NTSTATUS load_sampwd_entries(struct samr_info *info, uint16 acb_mask, BOOL all_machines)
+static NTSTATUS load_sampwd_entries(struct samr_info *info, uint16 acb_mask, BOOL only_machines)
 {
        SAM_ACCOUNT *pwd = NULL;
        SAM_ACCOUNT *pwd_array = NULL;
        NTSTATUS nt_status = NT_STATUS_OK;
        TALLOC_CTX *mem_ctx = info->mem_ctx;
+       uint16 query_acb_mask = acb_mask;
 
        DEBUG(10,("load_sampwd_entries\n"));
 
        /* if the snapshoot is already loaded, return */
        if ((info->disp_info.user_dbloaded==True) 
            && (info->acb_mask == acb_mask) 
-           && (info->all_machines == all_machines)) {
+           && (info->only_machines == only_machines)) {
                DEBUG(10,("load_sampwd_entries: already in memory\n"));
                return NT_STATUS_OK;
        }
 
        free_samr_users(info);
+       
+       if (only_machines) {
+               query_acb_mask |= ACB_WSTRUST;
+               query_acb_mask |= ACB_SVRTRUST;
+       }
 
-       if (!pdb_setsampwent(False)) {
+       if (!pdb_setsampwent(False, query_acb_mask)) {
                DEBUG(0, ("load_sampwd_entries: Unable to open passdb.\n"));
                return NT_STATUS_ACCESS_DENIED;
        }
 
        for (; (NT_STATUS_IS_OK(nt_status = pdb_init_sam_talloc(mem_ctx, &pwd))) 
                     && pdb_getsampwent(pwd) == True; pwd=NULL) {
-               
-               if (all_machines) {
+       
+               if (only_machines) {
                        if (!((pdb_get_acct_ctrl(pwd) & ACB_WSTRUST) 
                              || (pdb_get_acct_ctrl(pwd) & ACB_SVRTRUST))) {
                                DEBUG(5,("load_sampwd_entries: '%s' is not a machine account - ACB: %x - skipping\n", pdb_get_username(pwd), acb_mask));
@@ -277,7 +283,7 @@ static NTSTATUS load_sampwd_entries(struct samr_info *info, uint16 acb_mask, BOO
        /* the snapshoot is in memory, we're ready to enumerate fast */
 
        info->acb_mask = acb_mask;
-       info->all_machines = all_machines;
+       info->only_machines = only_machines;
        info->disp_info.user_dbloaded=True;
 
        DEBUG(10,("load_sampwd_entries: done\n"));
index 4af11da78440917ceec5cfe311c5637a45bda69b..9f2cd2142598b5bff087e3d61660fde7675c5ec8 100644 (file)
@@ -1874,7 +1874,7 @@ static BOOL api_RNetUserEnum(connection_struct *conn,uint16 vuid, char *param,ch
        
        /* Open the passgrp file - not for update. */
        become_root();
-       if(!pdb_setsampwent(False)) {
+       if(!pdb_setsampwent(False, 0)) {
                DEBUG(0, ("api_RNetUserEnum:unable to open sam database.\n"));
                unbecome_root();
                return False;
index ff08642f4076ecf33374077e7f3315f24747ab47..ea2faebdff42d5aac690ea1780baaf0cedc20d6c 100644 (file)
@@ -64,7 +64,7 @@ static int export_database (struct pdb_context *in, struct pdb_context
 
        DEBUG(3, ("called with username=\"%s\"\n", username));
 
-       if (NT_STATUS_IS_ERR(in->pdb_setsampwent(in, 0))) {
+       if (NT_STATUS_IS_ERR(in->pdb_setsampwent(in, 0, 0))) {
                fprintf(stderr, "Can't sampwent!\n");
                return 1;
        }
@@ -237,7 +237,7 @@ static int print_users_list (struct pdb_context *in, BOOL verbosity, BOOL smbpwd
        SAM_ACCOUNT *sam_pwent=NULL;
        BOOL check, ret;
        
-       check = NT_STATUS_IS_OK(in->pdb_setsampwent(in, False));
+       check = NT_STATUS_IS_OK(in->pdb_setsampwent(in, False, 0));
        if (!check) {
                return 1;
        }
@@ -266,7 +266,7 @@ static int fix_users_list (struct pdb_context *in)
        SAM_ACCOUNT *sam_pwent=NULL;
        BOOL check, ret;
        
-       check = NT_STATUS_IS_OK(in->pdb_setsampwent(in, False));
+       check = NT_STATUS_IS_OK(in->pdb_setsampwent(in, False, 0));
        if (!check) {
                return 1;
        }