svn commit: samba r22967 - in branches/SAMBA_4_0/source/auth/kerberos: .

abartlet at samba.org abartlet at samba.org
Thu May 17 05:46:47 GMT 2007


Author: abartlet
Date: 2007-05-17 05:46:45 +0000 (Thu, 17 May 2007)
New Revision: 22967

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

Log:
Move to the TCP packet interface for the krb5_send_to_kdc plugin.

This replaces a lump of hand-crafted code with the generic packet
system used in the rest of Samba4.

(I started this while chasing down the epoll bug, which turned out to
be seperate)


Modified:
   branches/SAMBA_4_0/source/auth/kerberos/krb5_init_context.c


Changeset:
Modified: branches/SAMBA_4_0/source/auth/kerberos/krb5_init_context.c
===================================================================
--- branches/SAMBA_4_0/source/auth/kerberos/krb5_init_context.c	2007-05-17 05:44:51 UTC (rev 22966)
+++ branches/SAMBA_4_0/source/auth/kerberos/krb5_init_context.c	2007-05-17 05:46:45 UTC (rev 22967)
@@ -26,6 +26,7 @@
 #include "heimdal/lib/krb5/krb5_locl.h"
 #include "auth/kerberos/kerberos.h"
 #include "lib/socket/socket.h"
+#include "lib/stream/packet.h"
 #include "system/network.h"
 #include "lib/events/events.h"
 #include "roken.h"
@@ -39,9 +40,10 @@
 	/* the fd event */
 	struct fd_event *fde;
 
-	BOOL timeout;
 	NTSTATUS status;
-	DATA_BLOB request, reply, partial;
+	DATA_BLOB request, reply;
+	
+	struct packet_context *packet;
 
 	size_t partial_read;
 
@@ -82,100 +84,50 @@
 	DATA_BLOB blob;
 	size_t nread, dsize;
 
-	switch (smb_krb5->hi->proto) {
-	case KRB5_KRBHST_UDP:
-		smb_krb5->status = socket_pending(smb_krb5->sock, &dsize);
-		if (!NT_STATUS_IS_OK(smb_krb5->status)) {
-			talloc_free(tmp_ctx);
-			return;
-		}
-
-		blob = data_blob_talloc(tmp_ctx, NULL, dsize);
-		if (blob.data == NULL && dsize != 0) {
-			smb_krb5->status = NT_STATUS_NO_MEMORY;
-			talloc_free(tmp_ctx);
-			return;
-		}
-		
-		smb_krb5->status = socket_recv(smb_krb5->sock, blob.data, blob.length, &nread);
-		if (!NT_STATUS_IS_OK(smb_krb5->status)) {
-			talloc_free(tmp_ctx);
-			return;
-		}
-		blob.length = nread;
-
-		if (nread == 0) {
-			smb_krb5->status = NT_STATUS_UNEXPECTED_NETWORK_ERROR;
-			talloc_free(tmp_ctx);
-			return;
-		}
-		
-		DEBUG(2,("Received smb_krb5 packet of length %d\n", 
-			 (int)blob.length));
-		
-		talloc_steal(smb_krb5, blob.data);
-		smb_krb5->reply = blob;
+	smb_krb5->status = socket_pending(smb_krb5->sock, &dsize);
+	if (!NT_STATUS_IS_OK(smb_krb5->status)) {
 		talloc_free(tmp_ctx);
-		break;
-	case KRB5_KRBHST_TCP:
-		if (smb_krb5->partial.length == 0) {
-			smb_krb5->partial = data_blob_talloc(smb_krb5, NULL, 4);
-			if (!smb_krb5->partial.data) {
-				smb_krb5->status = NT_STATUS_NO_MEMORY;
-				return;
-			}
-			
-			smb_krb5->partial_read = 0;
-		}
-		
-		/* read in the packet length */
-		if (smb_krb5->partial_read < 4) {
-			uint32_t packet_length;
-			
-			smb_krb5->status = socket_recv(smb_krb5->sock, 
-					     smb_krb5->partial.data + smb_krb5->partial_read,
-					     4 - smb_krb5->partial_read,
-					     &nread);
-			/* todo: this should be converted to the packet_*() routines */
-			if (!NT_STATUS_IS_OK(smb_krb5->status)) {
-				return;
-			}
-			
-			smb_krb5->partial_read += nread;
-			if (smb_krb5->partial_read != 4) {
-				return;
-			}
-			
-			packet_length = RIVAL(smb_krb5->partial.data, 0);
-			
-			smb_krb5->partial.data = talloc_realloc(smb_krb5, smb_krb5->partial.data, 
-								uint8_t, packet_length + 4);
-			if (!smb_krb5->partial.data)  {
-				smb_krb5->status = NT_STATUS_NO_MEMORY;
-				return;
-			}
-			
-			smb_krb5->partial.length = packet_length + 4;
-		}
-		
-		/* read in the body */
-		smb_krb5->status = socket_recv(smb_krb5->sock, 
-				     smb_krb5->partial.data + smb_krb5->partial_read,
-				     smb_krb5->partial.length - smb_krb5->partial_read,
-				     &nread);
-		if (!NT_STATUS_IS_OK(smb_krb5->status)) return;
-		
-		smb_krb5->partial_read += nread;
-
-		if (smb_krb5->partial_read != smb_krb5->partial.length) return;
-
-		smb_krb5->reply = data_blob_talloc(smb_krb5, smb_krb5->partial.data + 4, smb_krb5->partial.length - 4);
-		break;
-	case KRB5_KRBHST_HTTP:
 		return;
 	}
+	
+	blob = data_blob_talloc(tmp_ctx, NULL, dsize);
+	if (blob.data == NULL && dsize != 0) {
+		smb_krb5->status = NT_STATUS_NO_MEMORY;
+		talloc_free(tmp_ctx);
+		return;
+	}
+	
+	smb_krb5->status = socket_recv(smb_krb5->sock, blob.data, blob.length, &nread);
+	if (!NT_STATUS_IS_OK(smb_krb5->status)) {
+		talloc_free(tmp_ctx);
+		return;
+	}
+	blob.length = nread;
+	
+	if (nread == 0) {
+		smb_krb5->status = NT_STATUS_UNEXPECTED_NETWORK_ERROR;
+		talloc_free(tmp_ctx);
+		return;
+	}
+	
+	DEBUG(2,("Received smb_krb5 packet of length %d\n", 
+		 (int)blob.length));
+	
+	talloc_steal(smb_krb5, blob.data);
+	smb_krb5->reply = blob;
+	talloc_free(tmp_ctx);
 }
 
+static NTSTATUS smb_krb5_full_packet(void *private, DATA_BLOB data) 
+{
+	struct smb_krb5_socket *smb_krb5 = talloc_get_type(private, struct smb_krb5_socket);
+	talloc_steal(smb_krb5, data.data);
+	smb_krb5->reply = data;
+	smb_krb5->reply.length -= 4;
+	smb_krb5->reply.data += 4;
+	return NT_STATUS_OK;
+}
+
 /*
   handle request timeouts
 */
@@ -185,9 +137,15 @@
 {
 	struct smb_krb5_socket *smb_krb5 = talloc_get_type(private, struct smb_krb5_socket);
 	DEBUG(5,("Timed out smb_krb5 packet\n"));
-	smb_krb5->timeout = True;
+	smb_krb5->status = NT_STATUS_IO_TIMEOUT;
 }
 
+static void smb_krb5_error_handler(void *private, NTSTATUS status) 
+{
+	struct smb_krb5_socket *smb_krb5 = talloc_get_type(private, struct smb_krb5_socket);
+	smb_krb5->status = status;
+}
+
 /*
   handle send events on a smb_krb5 socket
 */
@@ -216,11 +174,26 @@
 				 uint16_t flags, void *private)
 {
 	struct smb_krb5_socket *smb_krb5 = talloc_get_type(private, struct smb_krb5_socket);
-	if (flags & EVENT_FD_WRITE) {
-		smb_krb5_socket_send(smb_krb5);
-	} 
-	if (flags & EVENT_FD_READ) {
-		smb_krb5_socket_recv(smb_krb5);
+	switch (smb_krb5->hi->proto) {
+	case KRB5_KRBHST_UDP:
+		if (flags & EVENT_FD_WRITE) {
+			smb_krb5_socket_send(smb_krb5);
+		} 
+		if (flags & EVENT_FD_READ) {
+			smb_krb5_socket_recv(smb_krb5);
+		}
+		break;
+	case KRB5_KRBHST_TCP:
+		if (flags & EVENT_FD_READ) {
+			packet_recv(smb_krb5->packet);
+		}
+		if (flags & EVENT_FD_WRITE) {
+			packet_queue_run(smb_krb5->packet);
+		}
+		break;
+	case KRB5_KRBHST_HTTP:
+		/* can't happen */
+		break;
 	}
 }
 
@@ -304,7 +277,7 @@
 		}
 		talloc_free(remote_addr);
 
-		smb_krb5->fde = event_add_fd(ev, smb_krb5, 
+		smb_krb5->fde = event_add_fd(ev, smb_krb5->sock, 
 					     socket_get_fd(smb_krb5->sock), 
 					     EVENT_FD_AUTOCLOSE,
 					     smb_krb5_socket_handler, smb_krb5);
@@ -315,39 +288,53 @@
 				timeval_current_ofs(context->kdc_timeout, 0),
 				smb_krb5_request_timeout, smb_krb5);
 
-		EVENT_FD_WRITEABLE(smb_krb5->fde);
 		
+		smb_krb5->status = NT_STATUS_OK;
+		smb_krb5->reply = data_blob(NULL, 0);
+
 		switch (hi->proto) {
 		case KRB5_KRBHST_UDP:
+			EVENT_FD_WRITEABLE(smb_krb5->fde);
 			smb_krb5->request = send_blob;
 			break;
 		case KRB5_KRBHST_TCP:
+
+			smb_krb5->packet = packet_init(smb_krb5);
+			if (smb_krb5->packet == NULL) {
+				talloc_free(smb_krb5);
+				return ENOMEM;
+			}
+			packet_set_private(smb_krb5->packet, smb_krb5);
+			packet_set_socket(smb_krb5->packet, smb_krb5->sock);
+			packet_set_callback(smb_krb5->packet, smb_krb5_full_packet);
+			packet_set_full_request(smb_krb5->packet, packet_full_request_u32);
+			packet_set_error_handler(smb_krb5->packet, smb_krb5_error_handler);
+			packet_set_event_context(smb_krb5->packet, ev);
+			packet_set_fde(smb_krb5->packet, smb_krb5->fde);
+
 			smb_krb5->request = data_blob_talloc(smb_krb5, NULL, send_blob.length + 4);
 			RSIVAL(smb_krb5->request.data, 0, send_blob.length);
 			memcpy(smb_krb5->request.data+4, send_blob.data, send_blob.length);
+			packet_send(smb_krb5->packet, smb_krb5->request);
+			EVENT_FD_READABLE(smb_krb5->fde);
 			break;
 		case KRB5_KRBHST_HTTP:
 			talloc_free(smb_krb5);
 			return EINVAL;
 		}
-		smb_krb5->timeout = False;
-		smb_krb5->status = NT_STATUS_OK;
-		smb_krb5->reply = data_blob(NULL, 0);
-		smb_krb5->partial = data_blob(NULL, 0);
-
-		while (!smb_krb5->timeout && (NT_STATUS_IS_OK(smb_krb5->status)) && !smb_krb5->reply.length) {
+		while ((NT_STATUS_IS_OK(smb_krb5->status)) && !smb_krb5->reply.length) {
 			if (event_loop_once(ev) != 0) {
 				talloc_free(smb_krb5);
 				return EINVAL;
 			}
 		}
-		if (!NT_STATUS_IS_OK(smb_krb5->status)) {
-			DEBUG(2,("Error reading smb_krb5 reply packet: %s\n", nt_errstr(smb_krb5->status)));
+		if (NT_STATUS_EQUAL(smb_krb5->status, NT_STATUS_IO_TIMEOUT)) {
 			talloc_free(smb_krb5);
 			continue;
 		}
 
-		if (smb_krb5->timeout) {
+		if (!NT_STATUS_IS_OK(smb_krb5->status)) {
+			DEBUG(2,("Error reading smb_krb5 reply packet: %s\n", nt_errstr(smb_krb5->status)));
 			talloc_free(smb_krb5);
 			continue;
 		}



More information about the samba-cvs mailing list