summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVolker Lendecke <vlendec@samba.org>2007-02-26 23:06:17 +0000
committerGerald (Jerry) Carter <jerry@samba.org>2007-10-10 12:18:12 -0500
commitf4a008424f227c1da388e4aa4ac303fc86c460ce (patch)
tree78ddb428bd1f9f6fe9daa63ec6be52c718654bad
parentab6a1df7a6f75637a0f25e02e16847d2441dee6d (diff)
downloadsamba-f4a008424f227c1da388e4aa4ac303fc86c460ce.tar.gz
samba-f4a008424f227c1da388e4aa4ac303fc86c460ce.tar.bz2
samba-f4a008424f227c1da388e4aa4ac303fc86c460ce.zip
r21551: Ok, this is more subtle. More tomorrow :-)
(This used to be commit f63189907efe857ef51ff91470ddb8d21b9a41fa)
-rw-r--r--source3/rpc_server/srv_samr_nt.c102
1 files changed, 37 insertions, 65 deletions
diff --git a/source3/rpc_server/srv_samr_nt.c b/source3/rpc_server/srv_samr_nt.c
index b7a45267a3..d35d97f2a0 100644
--- a/source3/rpc_server/srv_samr_nt.c
+++ b/source3/rpc_server/srv_samr_nt.c
@@ -49,6 +49,7 @@ typedef struct disp_info {
struct disp_info *next, *prev;
TALLOC_CTX *mem_ctx;
DOM_SID sid; /* identify which domain this is. */
+ BOOL builtin_domain; /* Quick flag to check if this is the builtin domain. */
struct pdb_search *users; /* querydispinfo 1 and 4 */
struct pdb_search *machines; /* querydispinfo 2 */
struct pdb_search *groups; /* querydispinfo 3 and 5, enumgroups */
@@ -64,9 +65,12 @@ typedef struct disp_info {
/* We keep a static list of these by SID as modern clients close down
all resources between each request in a complete enumeration. */
+static DISP_INFO *disp_info_list;
+
struct samr_info {
/* for use by the \PIPE\samr policy */
DOM_SID sid;
+ BOOL builtin_domain; /* Quick flag to check if this is the builtin domain. */
uint32 status; /* some sort of flag. best to record it. comes from opnum 0x39 */
uint32 acc_granted;
DISP_INFO *disp_info;
@@ -250,29 +254,22 @@ static NTSTATUS access_check_samr_function(uint32 acc_granted, uint32 acc_requir
Fetch or create a dispinfo struct.
********************************************************************/
-static DISP_INFO *get_samr_dispinfo_by_sid(DOM_SID *psid)
+static DISP_INFO *get_samr_dispinfo_by_sid(DOM_SID *psid, const char *sid_str)
{
- /*
- * We do a static cache for DISP_INFO's here. Explanation can be found
- * in Jeremy's checkin message to r11793:
- *
- * Fix the SAMR cache so it works across completely insane
- * client behaviour (ie.:
- * open pipe/open SAMR handle/enumerate 0 - 1024
- * close SAMR handle, close pipe.
- * open pipe/open SAMR handle/enumerate 1024 - 2048...
- * close SAMR handle, close pipe.
- * And on ad-nausium. Amazing.... probably object-oriented
- * client side programming in action yet again.
- * This change should *massively* improve performance when
- * enumerating users from an LDAP database.
- * Jeremy.
- */
-
- static DISP_INFO *disp_info_list;
TALLOC_CTX *mem_ctx;
DISP_INFO *dpi;
+ /* There are two cases to consider here:
+ 1) The SID is a domain SID and we look for an equality match, or
+ 2) This is an account SID and so we return the DISP_INFO* for our
+ domain */
+
+ if ( psid && sid_check_is_in_our_domain( psid ) ) {
+ DEBUG(10,("get_samr_dispinfo_by_sid: Replacing %s with our domain SID\n",
+ sid_str));
+ psid = get_global_sam_sid();
+ }
+
for (dpi = disp_info_list; dpi; dpi = dpi->next) {
if (sid_equal(psid, &dpi->sid)) {
return dpi;
@@ -283,18 +280,19 @@ static DISP_INFO *get_samr_dispinfo_by_sid(DOM_SID *psid)
can get a list out of smbd using smbcontrol. There will
be one of these per SID we're authorative for. JRA. */
- mem_ctx = talloc_init("DISP_INFO for domain sid %s",
- sid_string_static(psid));
+ mem_ctx = talloc_init("DISP_INFO for domain sid %s", sid_str);
- if ((dpi = TALLOC_ZERO_P(mem_ctx, DISP_INFO)) == NULL) {
- DEBUG(0, ("talloc failed\n"));
- TALLOC_FREE(mem_ctx);
+ if ((dpi = TALLOC_ZERO_P(mem_ctx, DISP_INFO)) == NULL)
return NULL;
- }
dpi->mem_ctx = mem_ctx;
- sid_copy( &dpi->sid, psid);
+ if (psid) {
+ sid_copy( &dpi->sid, psid);
+ dpi->builtin_domain = sid_check_is_builtin(psid);
+ } else {
+ dpi->builtin_domain = False;
+ }
DLIST_ADD(disp_info_list, dpi);
@@ -325,11 +323,20 @@ static struct samr_info *get_samr_info_by_sid(DOM_SID *psid)
DEBUG(10,("get_samr_info_by_sid: created new info for sid %s\n", sid_str));
if (psid) {
sid_copy( &info->sid, psid);
+ info->builtin_domain = sid_check_is_builtin(psid);
} else {
DEBUG(10,("get_samr_info_by_sid: created new info for NULL sid.\n"));
+ info->builtin_domain = False;
}
info->mem_ctx = mem_ctx;
+ info->disp_info = get_samr_dispinfo_by_sid(psid, sid_str);
+
+ if (!info->disp_info) {
+ talloc_destroy(mem_ctx);
+ return NULL;
+ }
+
return info;
}
@@ -486,7 +493,7 @@ static uint32 count_sam_users(struct disp_info *info, uint32 acct_flags)
{
struct samr_displayentry *entry;
- if (sid_check_is_builtin(&info->sid)) {
+ if (info->builtin_domain) {
/* No users in builtin. */
return 0;
}
@@ -510,7 +517,7 @@ static uint32 count_sam_groups(struct disp_info *info)
{
struct samr_displayentry *entry;
- if (sid_check_is_builtin(&info->sid)) {
+ if (info->builtin_domain) {
/* No groups in builtin. */
return 0;
}
@@ -618,11 +625,6 @@ NTSTATUS _samr_open_domain(pipes_struct *p, SAMR_Q_OPEN_DOMAIN *q_u, SAMR_R_OPEN
return NT_STATUS_NO_MEMORY;
info->acc_granted = acc_granted;
- if (!(info->disp_info = get_samr_dispinfo_by_sid(&q_u->dom_sid.sid))) {
- TALLOC_FREE(info->mem_ctx);
- return NT_STATUS_NO_MEMORY;
- }
-
/* get a (unique) handle. open a policy on it. */
if (!create_policy_hnd(p, &r_u->domain_pol, free_samr_info, (void *)info))
return NT_STATUS_OBJECT_NAME_NOT_FOUND;
@@ -677,11 +679,6 @@ static BOOL get_lsa_policy_samr_sid( pipes_struct *p, POLICY_HND *pol,
if (!info)
return False;
- if (!info->disp_info) {
- /* Not a domain */
- return False;
- }
-
*sid = info->sid;
*acc_granted = info->acc_granted;
if (ppdisp_info) {
@@ -914,11 +911,6 @@ NTSTATUS _samr_enum_dom_users(pipes_struct *p, SAMR_Q_ENUM_DOM_USERS *q_u,
if (!find_policy_by_hnd(p, &q_u->pol, (void **)(void *)&info))
return NT_STATUS_INVALID_HANDLE;
- if (!info->disp_info) {
- /* not a domain */
- return NT_STATUS_INVALID_HANDLE;
- }
-
if (!NT_STATUS_IS_OK(r_u->status = access_check_samr_function(info->acc_granted,
SA_RIGHT_DOMAIN_ENUM_ACCOUNTS,
"_samr_enum_dom_users"))) {
@@ -927,7 +919,7 @@ NTSTATUS _samr_enum_dom_users(pipes_struct *p, SAMR_Q_ENUM_DOM_USERS *q_u,
DEBUG(5,("_samr_enum_dom_users: %d\n", __LINE__));
- if (sid_check_is_builtin(&info->sid)) {
+ if (info->builtin_domain) {
/* No users in builtin. */
init_samr_r_enum_dom_users(r_u, q_u->start_idx, 0);
DEBUG(5,("_samr_enum_dom_users: No users in BUILTIN\n"));
@@ -1052,11 +1044,6 @@ NTSTATUS _samr_enum_dom_groups(pipes_struct *p, SAMR_Q_ENUM_DOM_GROUPS *q_u, SAM
if (!find_policy_by_hnd(p, &q_u->pol, (void **)(void *)&info))
return NT_STATUS_INVALID_HANDLE;
- if (!info->disp_info) {
- /* not a domain */
- return NT_STATUS_INVALID_HANDLE;
- }
-
r_u->status = access_check_samr_function(info->acc_granted,
SA_RIGHT_DOMAIN_ENUM_ACCOUNTS,
"_samr_enum_dom_groups");
@@ -1065,7 +1052,7 @@ NTSTATUS _samr_enum_dom_groups(pipes_struct *p, SAMR_Q_ENUM_DOM_GROUPS *q_u, SAM
DEBUG(5,("samr_reply_enum_dom_groups: %d\n", __LINE__));
- if (sid_check_is_builtin(&info->sid)) {
+ if (info->builtin_domain) {
/* No groups in builtin. */
init_samr_r_enum_dom_groups(r_u, q_u->start_idx, 0);
DEBUG(5,("_samr_enum_dom_users: No groups in BUILTIN\n"));
@@ -1116,11 +1103,6 @@ NTSTATUS _samr_enum_dom_aliases(pipes_struct *p, SAMR_Q_ENUM_DOM_ALIASES *q_u, S
if (!find_policy_by_hnd(p, &q_u->pol, (void **)(void *)&info))
return NT_STATUS_INVALID_HANDLE;
- if (!info->disp_info) {
- /* not a domain */
- return NT_STATUS_INVALID_HANDLE;
- }
-
r_u->status = access_check_samr_function(info->acc_granted,
SA_RIGHT_DOMAIN_ENUM_ACCOUNTS,
"_samr_enum_dom_aliases");
@@ -1187,11 +1169,6 @@ NTSTATUS _samr_query_dispinfo(pipes_struct *p, SAMR_Q_QUERY_DISPINFO *q_u,
if (!find_policy_by_hnd(p, &q_u->domain_pol, (void **)(void *)&info))
return NT_STATUS_INVALID_HANDLE;
- if (!info->disp_info) {
- /* not a domain */
- return NT_STATUS_INVALID_HANDLE;
- }
-
/*
* calculate how many entries we will return.
* based on
@@ -2348,11 +2325,6 @@ NTSTATUS _samr_query_domain_info(pipes_struct *p,
if (!find_policy_by_hnd(p, &q_u->domain_pol, (void **)(void *)&info)) {
return NT_STATUS_INVALID_HANDLE;
}
-
- if (!info->disp_info) {
- /* not a domain */
- return NT_STATUS_INVALID_HANDLE;
- }
switch (q_u->switch_value) {
case 0x01: