[SCM] Samba Shared Repository - branch master updated

Stefan Metzmacher metze at samba.org
Wed Jan 13 07:53:01 MST 2010


The branch, master has been updated
       via  129c15c... s4-ntp_signd: Migrate to tsocket.
      from  a4eaa11... Fixed a problem with incorrect default SD owner/group.

http://gitweb.samba.org/?p=samba.git;a=shortlog;h=master


- Log -----------------------------------------------------------------
commit 129c15c08387dbef0d53f7ed092ed47fb0a86753
Author: Andreas Schneider <asn at redhat.com>
Date:   Tue Jan 12 17:30:04 2010 +0100

    s4-ntp_signd: Migrate to tsocket.
    
    Signed-off-by: Stefan Metzmacher <metze at samba.org>

-----------------------------------------------------------------------

Summary of changes:
 source4/ntp_signd/config.mk   |    3 +-
 source4/ntp_signd/ntp_signd.c |  415 ++++++++++++++++++++++++++++-------------
 2 files changed, 286 insertions(+), 132 deletions(-)


Changeset truncated at 500 lines:

diff --git a/source4/ntp_signd/config.mk b/source4/ntp_signd/config.mk
index 07c404d..dd263fc 100644
--- a/source4/ntp_signd/config.mk
+++ b/source4/ntp_signd/config.mk
@@ -6,7 +6,8 @@
 INIT_FUNCTION = server_service_ntp_signd_init
 SUBSYSTEM = service
 PRIVATE_DEPENDENCIES = \
-		SAMDB NDR_NTP_SIGND
+		SAMDB NDR_NTP_SIGND \
+		LIBTSOCKET LIBSAMBA_TSOCKET
 # End SUBSYSTEM NTP_SIGND
 #######################
 
diff --git a/source4/ntp_signd/ntp_signd.c b/source4/ntp_signd/ntp_signd.c
index c611a75..025ff2b 100644
--- a/source4/ntp_signd/ntp_signd.c
+++ b/source4/ntp_signd/ntp_signd.c
@@ -27,6 +27,8 @@
 #include "smbd/service_stream.h"
 #include "smbd/process_model.h"
 #include "lib/stream/packet.h"
+#include "lib/tsocket/tsocket.h"
+#include "libcli/util/tstream.h"
 #include "librpc/gen_ndr/ndr_ntp_signd.h"
 #include "param/param.h"
 #include "dsdb/samdb/samdb.h"
@@ -35,6 +37,7 @@
 #include "lib/ldb/include/ldb.h"
 #include "lib/ldb/include/ldb_errors.h"
 #include "../lib/crypto/md5.h"
+#include "system/network.h"
 #include "system/passwd.h"
 
 /*
@@ -55,67 +58,49 @@ struct ntp_signd_connection {
 	/* the ntp_signd_server the connection belongs to */
 	struct ntp_signd_server *ntp_signd;
 
-	struct packet_context *packet;
+	struct tstream_context *tstream;
+
+	struct tevent_queue *send_queue;
 };
 
-static void ntp_signd_terminate_connection(struct ntp_signd_connection *ntp_signdconn, const char *reason)
+static void ntp_signd_terminate_connection(struct ntp_signd_connection *ntp_signd_conn, const char *reason)
 {
-	stream_terminate_connection(ntp_signdconn->conn, reason);
+	stream_terminate_connection(ntp_signd_conn->conn, reason);
 }
 
 static NTSTATUS signing_failure(struct ntp_signd_connection *ntp_signdconn,
-				uint32_t packet_id) 
+				TALLOC_CTX *mem_ctx,
+				DATA_BLOB *output,
+				uint32_t packet_id)
 {
-	NTSTATUS status;
 	struct signed_reply signed_reply;
-	TALLOC_CTX *tmp_ctx = talloc_new(ntp_signdconn);
-	DATA_BLOB reply, blob;
 	enum ndr_err_code ndr_err;
 
-	NT_STATUS_HAVE_NO_MEMORY(tmp_ctx);
-
 	signed_reply.op = SIGNING_FAILURE;
 	signed_reply.packet_id = packet_id;
 	signed_reply.signed_packet = data_blob(NULL, 0);
 	
-	ndr_err = ndr_push_struct_blob(&reply, tmp_ctx, 
+	ndr_err = ndr_push_struct_blob(output, mem_ctx,
 				       lp_iconv_convenience(ntp_signdconn->ntp_signd->task->lp_ctx),
 				       &signed_reply,
 				       (ndr_push_flags_fn_t)ndr_push_signed_reply);
 
 	if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
 		DEBUG(1,("failed to push ntp error reply\n"));
-		talloc_free(tmp_ctx);
 		return ndr_map_error2ntstatus(ndr_err);
 	}
 
-	blob = data_blob_talloc(ntp_signdconn, NULL, reply.length + 4);
-	if (!blob.data) {
-		talloc_free(tmp_ctx);
-		return NT_STATUS_NO_MEMORY;
-	}
-
-	RSIVAL(blob.data, 0, reply.length);
-	memcpy(blob.data + 4, reply.data, reply.length);	
-
-	status = packet_send(ntp_signdconn->packet, blob);
-
-	/* the call isn't needed any more */
-	talloc_free(tmp_ctx);
-	
-	return status;
+	return NT_STATUS_OK;
 }
 
 /*
   receive a full packet on a NTP_SIGND connection
 */
-static NTSTATUS ntp_signd_recv(void *private_data, DATA_BLOB wrapped_input)
+static NTSTATUS ntp_signd_process(struct ntp_signd_connection *ntp_signd_conn,
+				  TALLOC_CTX *mem_ctx,
+				  DATA_BLOB *input,
+				  DATA_BLOB *output)
 {
-	struct ntp_signd_connection *ntp_signdconn = talloc_get_type(private_data,
-							     struct ntp_signd_connection);
-	NTSTATUS status = NT_STATUS_UNSUCCESSFUL;
-	TALLOC_CTX *tmp_ctx = talloc_new(ntp_signdconn);
-	DATA_BLOB input, output, wrapped_output;
 	const struct dom_sid *domain_sid;
 	struct dom_sid *sid;
 	struct sign_request sign_request;
@@ -128,100 +113,124 @@ static NTSTATUS ntp_signd_recv(void *private_data, DATA_BLOB wrapped_input)
 	uint32_t user_account_control;
 	int ret;
 
-	NT_STATUS_HAVE_NO_MEMORY(tmp_ctx);
-
-	talloc_steal(tmp_ctx, wrapped_input.data);
-
-	input = data_blob_const(wrapped_input.data + 4, wrapped_input.length - 4); 
-
-	ndr_err = ndr_pull_struct_blob_all(&input, tmp_ctx, 
-					   lp_iconv_convenience(ntp_signdconn->ntp_signd->task->lp_ctx),
+	ndr_err = ndr_pull_struct_blob_all(input, mem_ctx,
+					   lp_iconv_convenience(ntp_signd_conn->ntp_signd->task->lp_ctx),
 					   &sign_request,
 					   (ndr_pull_flags_fn_t)ndr_pull_sign_request);
 
 	if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
 		DEBUG(1,("failed to parse ntp signing request\n"));
-		dump_data(1, input.data, input.length);
+		dump_data(1, input->data, input->length);
 		return ndr_map_error2ntstatus(ndr_err);
 	}
 
 	/* We need to implement 'check signature' and 'request server
 	 * to sign' operations at some point */
 	if (sign_request.op != SIGN_TO_CLIENT) {
-		talloc_free(tmp_ctx);
-		return signing_failure(ntp_signdconn, sign_request.packet_id);
+		return signing_failure(ntp_signd_conn,
+				       mem_ctx,
+				       output,
+				       sign_request.packet_id);
 	}
 
 	/* We need to implement 'check signature' and 'request server
 	 * to sign' operations at some point */
 	if (sign_request.version != NTP_SIGND_PROTOCOL_VERSION_0) {
-		talloc_free(tmp_ctx);
-		return signing_failure(ntp_signdconn, sign_request.packet_id);
+		return signing_failure(ntp_signd_conn,
+				       mem_ctx,
+				       output,
+				       sign_request.packet_id);
 	}
 
-	domain_sid = samdb_domain_sid(ntp_signdconn->ntp_signd->samdb);
-	if (!domain_sid) {
-		talloc_free(tmp_ctx);
-		return signing_failure(ntp_signdconn, sign_request.packet_id);
+	domain_sid = samdb_domain_sid(ntp_signd_conn->ntp_signd->samdb);
+	if (domain_sid == NULL) {
+		return signing_failure(ntp_signd_conn,
+				       mem_ctx,
+				       output,
+				       sign_request.packet_id);
 	}
 	
 	/* The top bit is a 'key selector' */
-	sid = dom_sid_add_rid(tmp_ctx, domain_sid, sign_request.key_id & 0x7FFFFFFF);
-	if (!sid) {
-		talloc_free(tmp_ctx);
-		return signing_failure(ntp_signdconn, sign_request.packet_id);
+	sid = dom_sid_add_rid(mem_ctx, domain_sid,
+			      sign_request.key_id & 0x7FFFFFFF);
+	if (sid == NULL) {
+		talloc_free(mem_ctx);
+		return signing_failure(ntp_signd_conn,
+				       mem_ctx,
+				       output,
+				       sign_request.packet_id);
 	}
 
-	ret = ldb_search(ntp_signdconn->ntp_signd->samdb, tmp_ctx,
-				 &res, samdb_base_dn(ntp_signdconn->ntp_signd->samdb),
-				 LDB_SCOPE_SUBTREE, attrs, "(&(objectSid=%s)(objectClass=user))",
-				 dom_sid_string(tmp_ctx, sid));
+	ret = ldb_search(ntp_signd_conn->ntp_signd->samdb, mem_ctx,
+				 &res,
+				 samdb_base_dn(ntp_signd_conn->ntp_signd->samdb),
+				 LDB_SCOPE_SUBTREE,
+				 attrs,
+				 "(&(objectSid=%s)(objectClass=user))",
+				 dom_sid_string(mem_ctx, sid));
 	if (ret != LDB_SUCCESS) {
-		DEBUG(2, ("Failed to search for SID %s in SAM for NTP signing: %s\n", dom_sid_string(tmp_ctx, sid),
-			  ldb_errstring(ntp_signdconn->ntp_signd->samdb)));
-		talloc_free(tmp_ctx);
-		return signing_failure(ntp_signdconn, sign_request.packet_id);
+		DEBUG(2, ("Failed to search for SID %s in SAM for NTP signing: "
+			  "%s\n",
+			  dom_sid_string(mem_ctx, sid),
+			  ldb_errstring(ntp_signd_conn->ntp_signd->samdb)));
+		return signing_failure(ntp_signd_conn,
+				       mem_ctx,
+				       output,
+				       sign_request.packet_id);
 	}
 
 	if (res->count == 0) {
-		DEBUG(5, ("Failed to find SID %s in SAM for NTP signing\n", dom_sid_string(tmp_ctx, sid)));
+		DEBUG(5, ("Failed to find SID %s in SAM for NTP signing\n",
+			  dom_sid_string(mem_ctx, sid)));
 	} else if (res->count != 1) {
-		DEBUG(1, ("Found SID %s %u times in SAM for NTP signing\n", dom_sid_string(tmp_ctx, sid), res->count));
-		talloc_free(tmp_ctx);
-		return signing_failure(ntp_signdconn, sign_request.packet_id);
+		DEBUG(1, ("Found SID %s %u times in SAM for NTP signing\n",
+			  dom_sid_string(mem_ctx, sid), res->count));
+		return signing_failure(ntp_signd_conn,
+				       mem_ctx,
+				       output,
+				       sign_request.packet_id);
 	}
 
-	user_account_control = ldb_msg_find_attr_as_uint(res->msgs[0], "userAccountControl", 0);
+	user_account_control = ldb_msg_find_attr_as_uint(res->msgs[0],
+							 "userAccountControl",
+							 0);
 
 	if (user_account_control & UF_ACCOUNTDISABLE) {
-		DEBUG(1, ("Account %s for SID [%s] is disabled\n", ldb_dn_get_linearized(res->msgs[0]->dn), dom_sid_string(tmp_ctx, sid)));
-		talloc_free(tmp_ctx);
+		DEBUG(1, ("Account %s for SID [%s] is disabled\n",
+			  ldb_dn_get_linearized(res->msgs[0]->dn),
+			  dom_sid_string(mem_ctx, sid)));
 		return NT_STATUS_ACCESS_DENIED;
 	}
 
 	if (!(user_account_control & (UF_INTERDOMAIN_TRUST_ACCOUNT|UF_SERVER_TRUST_ACCOUNT|UF_WORKSTATION_TRUST_ACCOUNT))) {
-		DEBUG(1, ("Account %s for SID [%s] is not a trust account\n", ldb_dn_get_linearized(res->msgs[0]->dn), dom_sid_string(tmp_ctx, sid)));
-		talloc_free(tmp_ctx);
+		DEBUG(1, ("Account %s for SID [%s] is not a trust account\n",
+			  ldb_dn_get_linearized(res->msgs[0]->dn),
+			  dom_sid_string(mem_ctx, sid)));
 		return NT_STATUS_ACCESS_DENIED;
 	}
 
-	nt_hash = samdb_result_hash(tmp_ctx, res->msgs[0], "unicodePwd");
+	nt_hash = samdb_result_hash(mem_ctx, res->msgs[0], "unicodePwd");
 	if (!nt_hash) {
-		DEBUG(1, ("No unicodePwd found on record of SID %s for NTP signing\n", dom_sid_string(tmp_ctx, sid)));
-		talloc_free(tmp_ctx);
-		return signing_failure(ntp_signdconn, sign_request.packet_id);
+		DEBUG(1, ("No unicodePwd found on record of SID %s "
+			  "for NTP signing\n", dom_sid_string(mem_ctx, sid)));
+		return signing_failure(ntp_signd_conn,
+				       mem_ctx,
+				       output,
+				       sign_request.packet_id);
 	}
 
 	/* Generate the reply packet */
 	signed_reply.packet_id = sign_request.packet_id;
 	signed_reply.op = SIGNING_SUCCESS;
-	signed_reply.signed_packet = data_blob_talloc(tmp_ctx, 
+	signed_reply.signed_packet = data_blob_talloc(mem_ctx,
 						      NULL,
 						      sign_request.packet_to_sign.length + 20);
 
 	if (!signed_reply.signed_packet.data) {
-		talloc_free(tmp_ctx);
-		return signing_failure(ntp_signdconn, sign_request.packet_id);
+		return signing_failure(ntp_signd_conn,
+				       mem_ctx,
+				       output,
+				       sign_request.packet_id);
 	}
 
 	memcpy(signed_reply.signed_packet.data, sign_request.packet_to_sign.data, sign_request.packet_to_sign.length);
@@ -235,61 +244,177 @@ static NTSTATUS ntp_signd_recv(void *private_data, DATA_BLOB wrapped_input)
 
 
 	/* Place it into the packet for the wire */
-	ndr_err = ndr_push_struct_blob(&output, tmp_ctx, 
-				       lp_iconv_convenience(ntp_signdconn->ntp_signd->task->lp_ctx),
+	ndr_err = ndr_push_struct_blob(output, mem_ctx,
+				       lp_iconv_convenience(ntp_signd_conn->ntp_signd->task->lp_ctx),
 				       &signed_reply,
 				       (ndr_push_flags_fn_t)ndr_push_signed_reply);
 
 	if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
 		DEBUG(1,("failed to push ntp error reply\n"));
-		talloc_free(tmp_ctx);
 		return ndr_map_error2ntstatus(ndr_err);
 	}
 
-	wrapped_output = data_blob_talloc(ntp_signdconn, NULL, output.length + 4);
-	if (!wrapped_output.data) {
-		talloc_free(tmp_ctx);
-		return NT_STATUS_NO_MEMORY;
-	}
-
-	/* The 'wire' transport for this is wrapped with a 4 byte network byte order length */
-	RSIVAL(wrapped_output.data, 0, output.length);
-	memcpy(wrapped_output.data + 4, output.data, output.length);	
-
-	status = packet_send(ntp_signdconn->packet, wrapped_output);
-
-	/* the call isn't needed any more */
-	talloc_free(tmp_ctx);
-	return status;
+	return NT_STATUS_OK;
 }
 
 /*
-  receive some data on a NTP_SIGND connection
+  called on a tcp recv
 */
-static void ntp_signd_recv_handler(struct stream_connection *conn, uint16_t flags)
+static void ntp_signd_recv(struct stream_connection *conn, uint16_t flags)
 {
-	struct ntp_signd_connection *ntp_signdconn = talloc_get_type(conn->private_data,
-							     struct ntp_signd_connection);
-	packet_recv(ntp_signdconn->packet);
+	struct ntp_signd_connection *ntp_signd_conn = talloc_get_type(conn->private_data,
+							struct ntp_signd_connection);
+	ntp_signd_terminate_connection(ntp_signd_conn,
+				       "ntp_signd_recv: called");
 }
 
 /*
-  called on a tcp recv error
+  called when we can write to a connection
 */
-static void ntp_signd_recv_error(void *private_data, NTSTATUS status)
+static void ntp_signd_send(struct stream_connection *conn, uint16_t flags)
 {
-	struct ntp_signd_connection *ntp_signdconn = talloc_get_type(private_data, struct ntp_signd_connection);
-	ntp_signd_terminate_connection(ntp_signdconn, nt_errstr(status));
+	struct ntp_signd_connection *ntp_signd_conn = talloc_get_type(conn->private_data,
+							struct ntp_signd_connection);
+	/* this should never be triggered! */
+	ntp_signd_terminate_connection(ntp_signd_conn,
+				       "ntp_signd_send: called");
 }
 
-/*
-  called when we can write to a connection
-*/
-static void ntp_signd_send(struct stream_connection *conn, uint16_t flags)
+struct ntp_signd_call {
+	struct ntp_signd_connection *ntp_signd_conn;
+	DATA_BLOB in;
+	DATA_BLOB out;
+	uint8_t out_hdr[4];
+	struct iovec out_iov[2];
+};
+
+static void ntp_signd_call_writev_done(struct tevent_req *subreq);
+
+static void ntp_signd_call_loop(struct tevent_req *subreq)
 {
-	struct ntp_signd_connection *ntp_signdconn = talloc_get_type(conn->private_data,
-							     struct ntp_signd_connection);
-	packet_queue_run(ntp_signdconn->packet);
+	struct ntp_signd_connection *ntp_signd_conn = tevent_req_callback_data(subreq,
+				      struct ntp_signd_connection);
+	struct ntp_signd_call *call;
+	NTSTATUS status;
+
+	call = talloc(ntp_signd_conn, struct ntp_signd_call);
+	if (call == NULL) {
+		ntp_signd_terminate_connection(ntp_signd_conn,
+				"ntp_signd_call_loop: "
+				"no memory for ntp_signd_call");
+		return;
+	}
+	call->ntp_signd_conn = ntp_signd_conn;
+
+	status = tstream_read_pdu_blob_recv(subreq,
+					    call,
+					    &call->in);
+	TALLOC_FREE(subreq);
+	if (!NT_STATUS_IS_OK(status)) {
+		const char *reason;
+
+		reason = talloc_asprintf(call, "ntp_signd_call_loop: "
+					 "tstream_read_pdu_blob_recv() - %s",
+					 nt_errstr(status));
+		if (reason == NULL) {
+			reason = nt_errstr(status);
+		}
+
+		ntp_signd_terminate_connection(ntp_signd_conn, reason);
+		return;
+	}
+
+	DEBUG(10,("Received NTP TCP packet of length %lu from %s\n",
+		 (long) call->in.length,
+		 tsocket_address_string(ntp_signd_conn->conn->remote_address, call)));
+
+	/* skip length header */
+	call->in.data +=4;
+	call->in.length -= 4;
+
+	status = ntp_signd_process(ntp_signd_conn,
+				     call,
+				     &call->in,
+				     &call->out);
+	if (! NT_STATUS_IS_OK(status)) {
+		const char *reason;
+
+		reason = talloc_asprintf(call, "ntp_signd_process failed: %s",
+					 nt_errstr(status));
+		if (reason == NULL) {
+			reason = nt_errstr(status);
+		}
+
+		ntp_signd_terminate_connection(ntp_signd_conn, reason);
+		return;
+	}
+
+	/* First add the length of the out buffer */
+	RSIVAL(call->out_hdr, 0, call->out.length);
+	call->out_iov[0].iov_base = call->out_hdr;
+	call->out_iov[0].iov_len = 4;
+
+	call->out_iov[1].iov_base = call->out.data;
+	call->out_iov[1].iov_len = call->out.length;
+
+	subreq = tstream_writev_queue_send(call,
+					   ntp_signd_conn->conn->event.ctx,
+					   ntp_signd_conn->tstream,
+					   ntp_signd_conn->send_queue,
+					   call->out_iov, 2);
+	if (subreq == NULL) {
+		ntp_signd_terminate_connection(ntp_signd_conn, "ntp_signd_call_loop: "
+				"no memory for tstream_writev_queue_send");
+		return;
+	}
+
+	tevent_req_set_callback(subreq, ntp_signd_call_writev_done, call);
+
+	/*
+	 * The NTP tcp pdu's has the length as 4 byte (initial_read_size),
+	 * packet_full_request_u32 provides the pdu length then.
+	 */
+	subreq = tstream_read_pdu_blob_send(ntp_signd_conn,
+					    ntp_signd_conn->conn->event.ctx,
+					    ntp_signd_conn->tstream,
+					    4, /* initial_read_size */
+					    packet_full_request_u32,
+					    ntp_signd_conn);
+	if (subreq == NULL) {
+		ntp_signd_terminate_connection(ntp_signd_conn, "ntp_signd_call_loop: "
+				"no memory for tstream_read_pdu_blob_send");
+		return;
+	}
+	tevent_req_set_callback(subreq, ntp_signd_call_loop, ntp_signd_conn);
+}
+
+static void ntp_signd_call_writev_done(struct tevent_req *subreq)
+{
+	struct ntp_signd_call *call = tevent_req_callback_data(subreq,
+			struct ntp_signd_call);
+	int sys_errno;
+	int rc;
+
+	rc = tstream_writev_queue_recv(subreq, &sys_errno);
+	TALLOC_FREE(subreq);
+	if (rc == -1) {
+		const char *reason;
+
+		reason = talloc_asprintf(call, "ntp_signd_call_writev_done: "
+					 "tstream_writev_queue_recv() - %d:%s",
+					 sys_errno, strerror(sys_errno));
+		if (!reason) {
+			reason = "ntp_signd_call_writev_done: "
+				 "tstream_writev_queue_recv() failed";
+		}
+
+		ntp_signd_terminate_connection(call->ntp_signd_conn, reason);
+		return;
+	}
+
+	/* We don't care about errors */
+
+	talloc_free(call);
 }
 
 /*
@@ -297,37 +422,65 @@ static void ntp_signd_send(struct stream_connection *conn, uint16_t flags)


-- 
Samba Shared Repository


More information about the samba-cvs mailing list