From 1ed62fde09f382342a396a047975fdeeea7113bb Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Wed, 19 Jan 2005 16:13:26 +0000 Subject: r4847: Hand over a acb_mask to pdb_setsampwent in load_sampwd_entries(). 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 | 6 +++--- source3/passdb/pdb_interface.c | 12 ++++++------ source3/passdb/pdb_ldap.c | 31 +++++++++++++++++++++++-------- source3/passdb/pdb_mysql.c | 2 +- source3/passdb/pdb_pgsql.c | 2 +- source3/passdb/pdb_smbpasswd.c | 2 +- source3/passdb/pdb_tdb.c | 2 +- source3/passdb/pdb_xml.c | 2 +- source3/rpc_server/srv_samr_nt.c | 20 +++++++++++++------- source3/smbd/lanman.c | 2 +- source3/utils/pdbedit.c | 6 +++--- 11 files changed, 54 insertions(+), 33 deletions(-) (limited to 'source3') diff --git a/source3/include/passdb.h b/source3/include/passdb.h index db6bc2ac75..1b9ccc50ee 100644 --- a/source3/include/passdb.h +++ b/source3/include/passdb.h @@ -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 *); diff --git a/source3/passdb/pdb_interface.c b/source3/passdb/pdb_interface.c index 9bc38fb444..ea097c10f6 100644 --- a/source3/passdb/pdb_interface.c +++ b/source3/passdb/pdb_interface.c @@ -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; } diff --git a/source3/passdb/pdb_ldap.c b/source3/passdb/pdb_ldap.c index ee0cb260e8..2cc1798d3f 100644 --- a/source3/passdb/pdb_ldap.c +++ b/source3/passdb/pdb_ldap.c @@ -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); diff --git a/source3/passdb/pdb_mysql.c b/source3/passdb/pdb_mysql.c index 500c9686c5..fbe4423324 100644 --- a/source3/passdb/pdb_mysql.c +++ b/source3/passdb/pdb_mysql.c @@ -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; diff --git a/source3/passdb/pdb_pgsql.c b/source3/passdb/pdb_pgsql.c index 6578d3d192..0955ea1881 100644 --- a/source3/passdb/pdb_pgsql.c +++ b/source3/passdb/pdb_pgsql.c @@ -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 ; diff --git a/source3/passdb/pdb_smbpasswd.c b/source3/passdb/pdb_smbpasswd.c index d75d0ed5c8..edb578b1e7 100644 --- a/source3/passdb/pdb_smbpasswd.c +++ b/source3/passdb/pdb_smbpasswd.c @@ -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; diff --git a/source3/passdb/pdb_tdb.c b/source3/passdb/pdb_tdb.c index 53baaf580d..755e33940b 100644 --- a/source3/passdb/pdb_tdb.c +++ b/source3/passdb/pdb_tdb.c @@ -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; diff --git a/source3/passdb/pdb_xml.c b/source3/passdb/pdb_xml.c index 6eb7761a3b..2a21fc8c9f 100644 --- a/source3/passdb/pdb_xml.c +++ b/source3/passdb/pdb_xml.c @@ -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; diff --git a/source3/rpc_server/srv_samr_nt.c b/source3/rpc_server/srv_samr_nt.c index 515eefb1fa..70c0de7da7 100644 --- a/source3/rpc_server/srv_samr_nt.c +++ b/source3/rpc_server/srv_samr_nt.c @@ -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")); diff --git a/source3/smbd/lanman.c b/source3/smbd/lanman.c index 4af11da784..9f2cd21425 100644 --- a/source3/smbd/lanman.c +++ b/source3/smbd/lanman.c @@ -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; diff --git a/source3/utils/pdbedit.c b/source3/utils/pdbedit.c index ff08642f40..ea2faebdff 100644 --- a/source3/utils/pdbedit.c +++ b/source3/utils/pdbedit.c @@ -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; } -- cgit