diff options
author | Günther Deschner <gd@samba.org> | 2008-05-16 13:24:15 +0200 |
---|---|---|
committer | Günther Deschner <gd@samba.org> | 2008-05-16 13:51:09 +0200 |
commit | 08971abdad82ce6b57a85ce77a8cb7906b0dab2f (patch) | |
tree | f9e900eb47c468b44a1801919903d6bad259ed1a | |
parent | 6b2af349cfb7b434fd0e8b1ae6f15b49688d326d (diff) | |
download | samba-08971abdad82ce6b57a85ce77a8cb7906b0dab2f.tar.gz samba-08971abdad82ce6b57a85ce77a8cb7906b0dab2f.tar.xz samba-08971abdad82ce6b57a85ce77a8cb7906b0dab2f.zip |
Fix Bug #5461 and implement a very basic _samr_GetDisplayEnumerationIndex().
Citrix PM cannot use a Samba DC when having more then 900 groups as citrix
insists on calling _samr_GetDisplayEnumerationIndex() after receiving the first
900 groups via _samr_QueryDisplayInfo() to get the continuation index.
Guenther
(This used to be commit 1c4adc8dda68eae9839bdff843aadf8c98dd9e87)
-rw-r--r-- | source3/rpc_server/srv_samr_nt.c | 159 |
1 files changed, 139 insertions, 20 deletions
diff --git a/source3/rpc_server/srv_samr_nt.c b/source3/rpc_server/srv_samr_nt.c index 0d9dd554c6a..f28c771d3ed 100644 --- a/source3/rpc_server/srv_samr_nt.c +++ b/source3/rpc_server/srv_samr_nt.c @@ -5652,6 +5652,145 @@ NTSTATUS _samr_SetDomainInfo(pipes_struct *p, } /**************************************************************** + _samr_GetDisplayEnumerationIndex +****************************************************************/ + +NTSTATUS _samr_GetDisplayEnumerationIndex(pipes_struct *p, + struct samr_GetDisplayEnumerationIndex *r) +{ + struct samr_info *info = NULL; + uint32_t max_entries = (uint32_t) -1; + uint32_t enum_context = 0; + int i; + uint32_t num_account = 0; + struct samr_displayentry *entries = NULL; + + DEBUG(5,("_samr_GetDisplayEnumerationIndex: %d\n", __LINE__)); + + /* find the policy handle. open a policy on it. */ + if (!find_policy_by_hnd(p, r->in.domain_handle, (void **)(void *)&info)) { + return NT_STATUS_INVALID_HANDLE; + } + + if ((r->in.level < 1) || (r->in.level > 3)) { + DEBUG(0,("_samr_GetDisplayEnumerationIndex: " + "Unknown info level (%u)\n", + r->in.level)); + return NT_STATUS_INVALID_INFO_CLASS; + } + + become_root(); + + /* The following done as ROOT. Don't return without unbecome_root(). */ + + switch (r->in.level) { + case 1: + if (info->disp_info->users == NULL) { + info->disp_info->users = pdb_search_users(ACB_NORMAL); + if (info->disp_info->users == NULL) { + unbecome_root(); + return NT_STATUS_ACCESS_DENIED; + } + DEBUG(10,("_samr_GetDisplayEnumerationIndex: " + "starting user enumeration at index %u\n", + (unsigned int)enum_context)); + } else { + DEBUG(10,("_samr_GetDisplayEnumerationIndex: " + "using cached user enumeration at index %u\n", + (unsigned int)enum_context)); + } + num_account = pdb_search_entries(info->disp_info->users, + enum_context, max_entries, + &entries); + break; + case 2: + if (info->disp_info->machines == NULL) { + info->disp_info->machines = + pdb_search_users(ACB_WSTRUST|ACB_SVRTRUST); + if (info->disp_info->machines == NULL) { + unbecome_root(); + return NT_STATUS_ACCESS_DENIED; + } + DEBUG(10,("_samr_GetDisplayEnumerationIndex: " + "starting machine enumeration at index %u\n", + (unsigned int)enum_context)); + } else { + DEBUG(10,("_samr_GetDisplayEnumerationIndex: " + "using cached machine enumeration at index %u\n", + (unsigned int)enum_context)); + } + num_account = pdb_search_entries(info->disp_info->machines, + enum_context, max_entries, + &entries); + break; + case 3: + if (info->disp_info->groups == NULL) { + info->disp_info->groups = pdb_search_groups(); + if (info->disp_info->groups == NULL) { + unbecome_root(); + return NT_STATUS_ACCESS_DENIED; + } + DEBUG(10,("_samr_GetDisplayEnumerationIndex: " + "starting group enumeration at index %u\n", + (unsigned int)enum_context)); + } else { + DEBUG(10,("_samr_GetDisplayEnumerationIndex: " + "using cached group enumeration at index %u\n", + (unsigned int)enum_context)); + } + num_account = pdb_search_entries(info->disp_info->groups, + enum_context, max_entries, + &entries); + break; + default: + unbecome_root(); + smb_panic("info class changed"); + break; + } + + unbecome_root(); + + /* Ensure we cache this enumeration. */ + set_disp_info_cache_timeout(info->disp_info, DISP_INFO_CACHE_TIMEOUT); + + DEBUG(10,("_samr_GetDisplayEnumerationIndex: looking for :%s\n", + r->in.name->string)); + + for (i=0; i<num_account; i++) { + if (strequal(entries[i].account_name, r->in.name->string)) { + DEBUG(10,("_samr_GetDisplayEnumerationIndex: " + "found %s at idx %d\n", + r->in.name->string, i)); + *r->out.idx = i; + return NT_STATUS_OK; + } + } + + /* assuming account_name lives at the very end */ + *r->out.idx = num_account; + + return NT_STATUS_NO_MORE_ENTRIES; +} + +/**************************************************************** + _samr_GetDisplayEnumerationIndex2 +****************************************************************/ + +NTSTATUS _samr_GetDisplayEnumerationIndex2(pipes_struct *p, + struct samr_GetDisplayEnumerationIndex2 *r) +{ + struct samr_GetDisplayEnumerationIndex q; + + q.in.domain_handle = r->in.domain_handle; + q.in.level = r->in.level; + q.in.name = r->in.name; + + q.out.idx = r->out.idx; + + return _samr_GetDisplayEnumerationIndex(p, &q); +} + +/**************************************************************** ****************************************************************/ NTSTATUS _samr_Shutdown(pipes_struct *p, @@ -5694,16 +5833,6 @@ NTSTATUS _samr_ChangePasswordUser(pipes_struct *p, /**************************************************************** ****************************************************************/ -NTSTATUS _samr_GetDisplayEnumerationIndex(pipes_struct *p, - struct samr_GetDisplayEnumerationIndex *r) -{ - p->rng_fault_state = true; - return NT_STATUS_NOT_IMPLEMENTED; -} - -/**************************************************************** -****************************************************************/ - NTSTATUS _samr_TestPrivateFunctionsDomain(pipes_struct *p, struct samr_TestPrivateFunctionsDomain *r) { @@ -5734,16 +5863,6 @@ NTSTATUS _samr_QueryUserInfo2(pipes_struct *p, /**************************************************************** ****************************************************************/ -NTSTATUS _samr_GetDisplayEnumerationIndex2(pipes_struct *p, - struct samr_GetDisplayEnumerationIndex2 *r) -{ - p->rng_fault_state = true; - return NT_STATUS_NOT_IMPLEMENTED; -} - -/**************************************************************** -****************************************************************/ - NTSTATUS _samr_AddMultipleMembersToAlias(pipes_struct *p, struct samr_AddMultipleMembersToAlias *r) { |