svn commit: samba r22734 - in branches/SAMBA_4_0/source/libnet: .

mimir at samba.org mimir at samba.org
Mon May 7 05:42:27 GMT 2007


Author: mimir
Date: 2007-05-07 05:42:26 +0000 (Mon, 07 May 2007)
New Revision: 22734

WebSVN: http://websvn.samba.org/cgi-bin/viewcvs.cgi?view=rev&root=samba&rev=22734

Log:
- use samr pipe if it is already opened
- close connection handle after domains enumeration
- collect domain names in subsequent rounds of enumeration
  (if there are more than one)


rafal


Modified:
   branches/SAMBA_4_0/source/libnet/libnet_domain.c


Changeset:
Modified: branches/SAMBA_4_0/source/libnet/libnet_domain.c
===================================================================
--- branches/SAMBA_4_0/source/libnet/libnet_domain.c	2007-05-07 03:16:54 UTC (rev 22733)
+++ branches/SAMBA_4_0/source/libnet/libnet_domain.c	2007-05-07 05:42:26 UTC (rev 22734)
@@ -852,6 +852,7 @@
 	struct libnet_RpcConnect rpcconn;
 	struct samr_Connect samrconn;
 	struct samr_EnumDomains enumdom;
+	struct samr_Close samrclose;
 	const char *hostname;
 	struct policy_handle connect_handle;
 	int buf_size;
@@ -866,6 +867,7 @@
 static void continue_rpc_connect(struct composite_context *c);
 static void continue_samr_connect(struct rpc_request *c);
 static void continue_samr_enum_domains(struct rpc_request *req);
+static void continue_samr_close_handle(struct rpc_request *req);
 
 static struct domainlist* get_domain_list(TALLOC_CTX *mem_ctx, struct domain_list_state *s);
 
@@ -927,13 +929,15 @@
 
 /*
   Stage 3: Receive domain names available and repeat the request
-  enumeration is not complete yet
+  enumeration is not complete yet. Close samr connection handle
+  upon completion.
 */
 static void continue_samr_enum_domains(struct rpc_request *req)
 {
 	struct composite_context *c;
 	struct domain_list_state *s;
 	struct rpc_request *enumdom_req;
+	struct rpc_request *samrclose_req;
 
 	c = talloc_get_type(req->async.private, struct composite_context);
 	s = talloc_get_type(c->private_data, struct domain_list_state);
@@ -944,17 +948,18 @@
 	if (NT_STATUS_IS_OK(s->enumdom.out.result)) {
 
 		s->domains = get_domain_list(c, s);
-		composite_done(c);
 
 	} else if (NT_STATUS_EQUAL(s->enumdom.out.result, STATUS_MORE_ENTRIES)) {
 		
 		s->domains = get_domain_list(c, s);
 		
+		/* prepare next round of enumeration */
 		s->enumdom.in.connect_handle = &s->connect_handle;
 		s->enumdom.in.resume_handle  = &s->resume_handle;
 		s->enumdom.in.buf_size       = s->buf_size;
 		s->enumdom.out.resume_handle = &s->resume_handle;
 
+		/* send the request */
 		enumdom_req = dcerpc_samr_EnumDomains_send(s->ctx->samr.pipe, c, &s->enumdom);
 		if (composite_nomem(enumdom_req, c)) return;
 
@@ -962,11 +967,45 @@
 
 	} else {
 		composite_error(c, s->enumdom.out.result);
+		return;
 	}
+
+	/* close samr connection handle */
+	s->samrclose.in.handle  = &s->connect_handle;
+	s->samrclose.out.handle = &s->connect_handle;
+	
+	/* send the request */
+	samrclose_req = dcerpc_samr_Close_send(s->ctx->samr.pipe, c, &s->samrclose);
+	if (composite_nomem(samrclose_req, c)) return;
+
+	composite_continue_rpc(c, samrclose_req, continue_samr_close_handle, c);
 }
 
 
 /*
+  Stage 4: Receive result of closing samr connection handle.
+*/
+static void continue_samr_close_handle(struct rpc_request *req)
+{
+	struct composite_context *c;
+	struct domain_list_state *s;
+
+	c = talloc_get_type(req->async.private, struct composite_context);
+	s = talloc_get_type(c->private_data, struct domain_list_state);
+
+	c->status = dcerpc_ndr_request_recv(req);
+	if (!composite_is_ok(c)) return;
+
+	/* did everything go fine ? */
+	if (!NT_STATUS_IS_OK(s->samrclose.out.result)) {
+		composite_error(c, s->samrclose.out.result);
+	}
+
+	composite_done(c);
+}
+
+
+/*
   Utility function to copy domain names from result of samr_EnumDomains call
 */
 static struct domainlist* get_domain_list(TALLOC_CTX *mem_ctx, struct domain_list_state *s)
@@ -974,20 +1013,28 @@
 	int i;
 	if (mem_ctx == NULL || s == NULL) return NULL;
 
-	/* number of entries returned (domains enumerated) */
-	s->count = s->enumdom.out.num_entries;
-	
 	/* copy domain names returned from samr_EnumDomains call */
-	s->domains = talloc_array(mem_ctx, struct domainlist, s->enumdom.out.num_entries);
-	for (i = 0; i < s->enumdom.out.num_entries; i++)
+	if (s->domains == NULL) {
+		s->domains = talloc_array(mem_ctx, struct domainlist,
+					  s->enumdom.out.num_entries);
+	} else {
+		s->domains = talloc_realloc(mem_ctx, s->domains, struct domainlist,
+					    s->count + s->enumdom.out.num_entries);
+	}
+
+	for (i = s->count; i < s->count + s->enumdom.out.num_entries; i++)
 	{
+		struct lsa_String *domain_name = &s->enumdom.out.sam->entries[i - s->count].name;
+
 		/* strdup name as a child of allocated array to make it follow the array
 		   in case of talloc_steal or talloc_free */
-		s->domains[i].name = talloc_strdup(s->domains,
-						   s->enumdom.out.sam->entries[i].name.string);
+		s->domains[i].name = talloc_strdup(s->domains, domain_name->string);
 		s->domains[i].sid  = NULL;  /* this is to be filled out later */
 	}
 
+	/* number of entries returned (domains enumerated) */
+	s->count += s->enumdom.out.num_entries;
+	
 	return s->domains;
 }
 
@@ -1009,6 +1056,7 @@
 	struct composite_context *c;
 	struct domain_list_state *s;
 	struct composite_context *rpcconn_req;
+	struct rpc_request *samrconn_req;
 
 	/* composite context and state structure allocation */
 	c = composite_create(ctx, ctx->event_ctx);
@@ -1027,15 +1075,30 @@
 	/* set the default buffer size if not stated explicitly */
 	s->buf_size = (io->in.buf_size == 0) ? 512 : io->in.buf_size;
 
-	/* prepare rpc connect call */
-	s->rpcconn.level           = LIBNET_RPC_CONNECT_SERVER;
-	s->rpcconn.in.name         = s->hostname;
-	s->rpcconn.in.dcerpc_iface = &dcerpc_table_samr;
+	/* check whether samr pipe has already been opened */
+	if (ctx->samr.pipe == NULL) {
+		/* prepare rpc connect call */
+		s->rpcconn.level           = LIBNET_RPC_CONNECT_SERVER;
+		s->rpcconn.in.name         = s->hostname;
+		s->rpcconn.in.dcerpc_iface = &dcerpc_table_samr;
 
-	rpcconn_req = libnet_RpcConnect_send(ctx, c, &s->rpcconn);
-	if (composite_nomem(rpcconn_req, c)) return c;
+		rpcconn_req = libnet_RpcConnect_send(ctx, c, &s->rpcconn);
+		if (composite_nomem(rpcconn_req, c)) return c;
+		
+		composite_continue(c, rpcconn_req, continue_rpc_connect, c);
 
-	composite_continue(c, rpcconn_req, continue_rpc_connect, c);
+	} else {
+		/* prepare samr_Connect call */
+		s->samrconn.in.system_name     = 0;
+		s->samrconn.in.access_mask     = SEC_GENERIC_READ;
+		s->samrconn.out.connect_handle = &s->connect_handle;
+		
+		samrconn_req = dcerpc_samr_Connect_send(s->ctx->samr.pipe, c, &s->samrconn);
+		if (composite_nomem(samrconn_req, c)) return c;
+
+		composite_continue_rpc(c, samrconn_req, continue_samr_connect, c);
+	}
+
 	return c;
 }
 



More information about the samba-cvs mailing list