r11769: Looking at a performance problem enumerating accounts, wondered
authorJeremy Allison <jra@samba.org>
Thu, 17 Nov 2005 22:40:10 +0000 (22:40 +0000)
committerGerald (Jerry) Carter <jerry@samba.org>
Wed, 10 Oct 2007 16:05:27 +0000 (11:05 -0500)
if changing to support samr_connect5 might help so quickly coded
it up. No it doesn't :-(. Don't merge this for 3.0.21 please.
Jeremy.

source/include/rpc_samr.h
source/rpc_parse/parse_samr.c
source/rpc_server/srv_samr.c
source/rpc_server/srv_samr_nt.c

index 6067587654e123c202ed16809d45b39521739775..2c125253b3d510450ac0f15ea735d20075eb0d45 100644 (file)
@@ -143,6 +143,7 @@ SamrTestPrivateFunctionsUser
 #define SAMR_CONNECT           0x39
 #define SAMR_SET_USERINFO      0x3A
 #define SAMR_CONNECT4          0x3E
+#define SAMR_CONNECT5          0x40
 
 typedef struct logon_hours_info
 {
@@ -1697,7 +1698,7 @@ typedef struct q_samr_connect_info
 /* SAMR_R_CONNECT - probably an open */
 typedef struct r_samr_connect_info
 {
-    POLICY_HND connect_pol;       /* policy handle */
+       POLICY_HND connect_pol;       /* policy handle */
        NTSTATUS status;         /* return status */
 
 } SAMR_R_CONNECT;
@@ -1715,6 +1716,31 @@ typedef struct q_samr_connect4_info
 /* SAMR_R_CONNECT4 - same format as connect */
 typedef struct r_samr_connect_info SAMR_R_CONNECT4;       
 
+/* SAMR_Q_CONNECT5 */
+typedef struct q_samr_connect5_info
+{
+       uint32 ptr_srv_name; /* pointer to server name */
+       UNISTR2 uni_srv_name;
+       uint32 access_mask;
+       uint32 level;
+       /* These following are acutally a level dependent
+          value. Fudge it for now. JRA */
+       uint32 info1_unk1;
+       uint32 info1_unk2;
+} SAMR_Q_CONNECT5;
+
+/* SAMR_R_CONNECT5 */
+typedef struct r_samr_connect_info5
+{
+       uint32 level;
+       uint32 info1_unk1;
+       uint32 info1_unk2;
+       POLICY_HND connect_pol;       /* policy handle */
+       NTSTATUS status;         /* return status */
+
+} SAMR_R_CONNECT5;
+
+
 /* SAMR_Q_GET_DOM_PWINFO */
 typedef struct q_samr_get_dom_pwinfo
 {
index dfe80a65e27dea6a8118e0a8380267c9198da61b..7e39b44fe66d143135ec84cdd247f2114e8f8535 100644 (file)
@@ -6734,7 +6734,7 @@ inits a SAMR_Q_CONNECT4 structure.
 void init_samr_q_connect4(SAMR_Q_CONNECT4 * q_u,
                          char *srv_name, uint32 access_mask)
 {
-       DEBUG(5, ("init_samr_q_connect\n"));
+       DEBUG(5, ("init_samr_q_connect4\n"));
 
        /* make PDC server name \\server */
        q_u->ptr_srv_name = (srv_name != NULL && *srv_name) ? 1 : 0;
@@ -6803,6 +6803,116 @@ BOOL samr_io_r_connect4(const char *desc, SAMR_R_CONNECT4 * r_u,
        return True;
 }
 
+/*******************************************************************
+inits a SAMR_Q_CONNECT5 structure.
+********************************************************************/
+
+void init_samr_q_connect5(SAMR_Q_CONNECT5 * q_u,
+                         char *srv_name, uint32 access_mask)
+{
+       DEBUG(5, ("init_samr_q_connect5\n"));
+
+       /* make PDC server name \\server */
+       q_u->ptr_srv_name = (srv_name != NULL && *srv_name) ? 1 : 0;
+       init_unistr2(&q_u->uni_srv_name, srv_name, UNI_STR_TERMINATE);
+
+       /* example values: 0x0000 0002 */
+       q_u->access_mask = access_mask;
+
+       q_u->level = 1;
+       q_u->info1_unk1 = 3;
+       q_u->info1_unk2 = 0;
+}
+
+/*******************************************************************
+inits a SAMR_R_CONNECT5 structure.
+********************************************************************/
+
+void init_samr_r_connect5(SAMR_R_CONNECT5 * r_u, POLICY_HND *pol, NTSTATUS status)
+{
+       DEBUG(5, ("init_samr_q_connect5\n"));
+
+       r_u->level = 1;
+       r_u->info1_unk1 = 3;
+       r_u->info1_unk2 = 0;
+
+       r_u->connect_pol = *pol;
+       r_u->status = status;
+}
+
+/*******************************************************************
+reads or writes a structure.
+********************************************************************/
+
+BOOL samr_io_q_connect5(const char *desc, SAMR_Q_CONNECT5 * q_u,
+                       prs_struct *ps, int depth)
+{
+       if (q_u == NULL)
+               return False;
+
+       prs_debug(ps, depth, desc, "samr_io_q_connect5");
+       depth++;
+
+       if(!prs_align(ps))
+               return False;
+
+       if(!prs_uint32("ptr_srv_name", ps, depth, &q_u->ptr_srv_name))
+               return False;
+       if(!smb_io_unistr2("", &q_u->uni_srv_name, q_u->ptr_srv_name, ps, depth))
+               return False;
+
+       if(!prs_align(ps))
+               return False;
+       if(!prs_uint32("access_mask", ps, depth, &q_u->access_mask))
+               return False;
+
+       if(!prs_uint32("level", ps, depth, &q_u->level))
+               return False;
+       if(!prs_uint32("level", ps, depth, &q_u->level))
+               return False;
+       
+       if(!prs_uint32("info1_unk1", ps, depth, &q_u->info1_unk1))
+               return False;
+       if(!prs_uint32("info1_unk2", ps, depth, &q_u->info1_unk2))
+               return False;
+
+       return True;
+}
+
+/*******************************************************************
+reads or writes a structure.
+********************************************************************/
+
+BOOL samr_io_r_connect5(const char *desc, SAMR_R_CONNECT5 * r_u,
+                       prs_struct *ps, int depth)
+{
+       if (r_u == NULL)
+               return False;
+
+       prs_debug(ps, depth, desc, "samr_io_r_connect5");
+       depth++;
+
+       if(!prs_align(ps))
+               return False;
+
+       if(!prs_uint32("level", ps, depth, &r_u->level))
+               return False;
+       if(!prs_uint32("level", ps, depth, &r_u->level))
+               return False;
+       if(!prs_uint32("info1_unk1", ps, depth, &r_u->info1_unk1))
+               return False;
+       if(!prs_uint32("info1_unk2", ps, depth, &r_u->info1_unk2))
+               return False;
+
+       if(!smb_io_pol_hnd("connect_pol", &r_u->connect_pol, ps, depth))
+               return False;
+
+       if(!prs_ntstatus("status", ps, depth, &r_u->status))
+               return False;
+
+       return True;
+}
+
 /*******************************************************************
 inits a SAMR_Q_CONNECT_ANON structure.
 ********************************************************************/
index ffb7882e110fb72e1aed8184531047a6428a7f95..520bf47a3154fc1bcc31565a07105284e112943e 100644 (file)
@@ -679,6 +679,37 @@ static BOOL api_samr_connect4(pipes_struct *p)
        return True;
 }
 
+/*******************************************************************
+ api_samr_connect5
+ ********************************************************************/
+
+static BOOL api_samr_connect5(pipes_struct *p)
+{
+       SAMR_Q_CONNECT5 q_u;
+       SAMR_R_CONNECT5 r_u;
+       prs_struct *data = &p->in_data.data;
+       prs_struct *rdata = &p->out_data.rdata;
+
+       ZERO_STRUCT(q_u);
+       ZERO_STRUCT(r_u);
+
+       /* grab the samr open policy */
+       if(!samr_io_q_connect5("", &q_u, data, 0)) {
+               DEBUG(0,("api_samr_connect5: unable to unmarshall SAMR_Q_CONNECT5.\n"));
+               return False;
+       }
+
+       r_u.status = _samr_connect5(p, &q_u, &r_u);
+
+       /* store the response in the SMB stream */
+       if(!samr_io_r_connect5("", &r_u, rdata, 0)) {
+               DEBUG(0,("api_samr_connect5: unable to marshall SAMR_R_CONNECT5.\n"));
+               return False;
+       }
+
+       return True;
+}
+
 /**********************************************************************
  api_samr_lookup_domain
  **********************************************************************/
@@ -1492,7 +1523,8 @@ static struct api_struct api_samr_cmds [] =
       {"SAMR_GET_USRDOM_PWINFO" , SAMR_GET_USRDOM_PWINFO, api_samr_get_usrdom_pwinfo},
       {"SAMR_UNKNOWN_2E"        , SAMR_UNKNOWN_2E       , api_samr_unknown_2e       },
       {"SAMR_SET_DOMAIN_INFO"   , SAMR_SET_DOMAIN_INFO  , api_samr_set_dom_info     },
-      {"SAMR_CONNECT4"          , SAMR_CONNECT4         , api_samr_connect4         }
+      {"SAMR_CONNECT4"          , SAMR_CONNECT4         , api_samr_connect4         },
+      {"SAMR_CONNECT5"          , SAMR_CONNECT5         , api_samr_connect5         }
 };
 
 void samr_get_pipe_fns( struct api_struct **fns, int *n_fns )
index 71272a9a98b88d50fc839ef208200966c26f03a9..bfc96ea0f60c916a5bf5c1d2562dcc5c26a97711 100644 (file)
@@ -2293,6 +2293,60 @@ NTSTATUS _samr_connect4(pipes_struct *p, SAMR_Q_CONNECT4 *q_u, SAMR_R_CONNECT4 *
        return r_u->status;
 }
 
+/*******************************************************************
+ samr_connect5
+ ********************************************************************/
+
+NTSTATUS _samr_connect5(pipes_struct *p, SAMR_Q_CONNECT5 *q_u, SAMR_R_CONNECT5 *r_u)
+{
+       struct samr_info *info = NULL;
+       SEC_DESC *psd = NULL;
+       uint32    acc_granted;
+       uint32    des_access = q_u->access_mask;
+       NTSTATUS  nt_status;
+       POLICY_HND pol;
+       size_t    sd_size;
+
+
+       DEBUG(5,("_samr_connect5: %d\n", __LINE__));
+
+       ZERO_STRUCTP(r_u);
+
+       /* Access check */
+
+       if (!pipe_access_check(p)) {
+               DEBUG(3, ("access denied to samr_connect5\n"));
+               r_u->status = NT_STATUS_ACCESS_DENIED;
+               return r_u->status;
+       }
+
+       make_samr_object_sd(p->mem_ctx, &psd, &sd_size, &sam_generic_mapping, NULL, 0);
+       se_map_generic(&des_access, &sam_generic_mapping);
+       
+       nt_status = access_check_samr_object(psd, p->pipe_user.nt_user_token, 
+               NULL, 0, des_access, &acc_granted, "_samr_connect5");
+       
+       if ( !NT_STATUS_IS_OK(nt_status) ) 
+               return nt_status;
+
+       /* associate the user's SID and access granted with the new handle. */
+       if ((info = get_samr_info_by_sid(NULL)) == NULL)
+               return NT_STATUS_NO_MEMORY;
+
+       info->acc_granted = acc_granted;
+       info->status = q_u->access_mask;
+
+       /* get a (unique) handle.  open a policy on it. */
+       if (!create_policy_hnd(p, &pol, free_samr_info, (void *)info))
+               return NT_STATUS_OBJECT_NAME_NOT_FOUND;
+
+       DEBUG(5,("_samr_connect: %d\n", __LINE__));
+
+       init_samr_r_connect5(r_u, &pol, NT_STATUS_OK);
+
+       return r_u->status;
+}
+
 /**********************************************************************
  api_samr_lookup_domain
  **********************************************************************/