Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 19 Sep 2005 14:01:21 GMT
From:      soc-bushman <soc-bushman@FreeBSD.org>
To:        Perforce Change Reviews <perforce@freebsd.org>
Subject:   PERFORCE change 83906 for review
Message-ID:  <200509191401.j8JE1LBv045197@repoman.freebsd.org>

next in thread | raw e-mail | index | archive | help
http://perforce.freebsd.org/chv.cgi?CH=83906

Change 83906 by soc-bushman@soc-bushman_stinger on 2005/09/19 14:01:11

	some minor fixes - preparing to start a new branch

Affected files ...

.. //depot/projects/soc2005/nsswitch_cached/release/cached-0.1/bin/cached.c#6 edit
.. //depot/projects/soc2005/nsswitch_cached/release/cached-0.1/bin/mp_rs_query.c#5 edit
.. //depot/projects/soc2005/nsswitch_cached/release/cached-0.1/bin/mp_rs_query.h#5 edit
.. //depot/projects/soc2005/nsswitch_cached/release/cached-0.1/bin/mp_ws_query.c#5 edit
.. //depot/projects/soc2005/nsswitch_cached/release/cached-0.1/bin/mp_ws_query.h#5 edit
.. //depot/projects/soc2005/nsswitch_cached/release/cached-0.1/bin/protocol.h#4 edit
.. //depot/projects/soc2005/nsswitch_cached/release/cached-0.1/bin/query.c#5 edit
.. //depot/projects/soc2005/nsswitch_cached/release/cached-0.1/bin/query.h#5 edit
.. //depot/projects/soc2005/nsswitch_cached/tests/nsdispatch_test/nsdispatch_test.c#7 edit

Differences ...

==== //depot/projects/soc2005/nsswitch_cached/release/cached-0.1/bin/cached.c#6 (text+ko) ====

@@ -207,6 +207,7 @@
 	memset(retval, 0, sizeof(struct runtime_env));
 	
 	retval->sockfd = socket(PF_LOCAL, SOCK_STREAM, 0);
+	TRACE_INT(retval->sockfd);
 
 	if (config->force_unlink == 1)
 		unlink(config->socket_path);
@@ -227,8 +228,13 @@
 		TRACE_OUT(init_runtime_env);
 		return (NULL);
 	}
+	
+	/* 
+	 * Here we're marking socket as non-blocking and setting its backlog 
+	 * to the maximum value 
+	 */
 	chmod(config->socket_path, config->socket_mode);
-	listen(retval->sockfd, 100);
+	listen(retval->sockfd, -1);
 	fcntl(retval->sockfd, F_SETFL, O_NONBLOCK);
 	
 	retval->queue = kqueue();
@@ -262,26 +268,40 @@
 	struct query_state	*qstate;
 	
 	struct sockaddr	addr;
-	size_t			addr_len;
+	socklen_t			addr_len;
 	int				fd;
 	int				res;
+	
+	uid_t	euid;
+	gid_t	egid;
 		
 	TRACE_IN(accept_connection);
 	addr_len = sizeof(struct sockaddr);
 	fd = accept(event_data->ident, &addr, &addr_len);
 	if (fd == -1) {
-		/* do something */
-		TRACE_POINT();
+		/* TODO: do something */
+		TRACE_OUT(accept_connection);
+		return;
+	}
+	
+	if (getpeereid(fd, &euid, &egid) != 0) {
+		/* TODO: do something */
+		TRACE_OUT(accept_connection);
 		return;
 	}
 	
-	qstate = init_query_state(fd, sizeof(int));
-	memset(&timeout, 0, sizeof(struct timespec));
+	qstate = init_query_state(fd, sizeof(int), euid, egid);
+	if (qstate == NULL) {
+		/* TODO: do something */
+		TRACE_OUT(accept_connection);
+		return;
+	}
 	
+	memset(&timeout, 0, sizeof(struct timespec));	
+	EV_SET(&eventlist[0], fd, EVFILT_TIMER, EV_ADD | EV_ONESHOT,
+		0, qstate->timeout.tv_sec * 1000, qstate);
 	EV_SET(&eventlist[1], fd, EVFILT_READ, EV_ADD | EV_ONESHOT, 
 		NOTE_LOWAT, qstate->kevent_watermark, qstate);
-	EV_SET(&eventlist[0], fd, EVFILT_TIMER, EV_ADD | EV_ONESHOT,
-		0, qstate->timeout.tv_sec * 1000, qstate);
 	res = kevent(env->queue, eventlist, 2, NULL, 0, &timeout);	
 	TRACE_INT(res);
 	TRACE_INT(fd);
@@ -418,7 +438,7 @@
 		qstate->use_alternate_io = 0;					
 		
 	if (qstate->use_alternate_io == 0) {
-		if (qstate->kevent_watermark > MAX_SOCKET_IO_SIZE)	{
+		if (qstate->kevent_watermark > MAX_SOCKET_IO_SIZE) {
 			if (qstate->io_buffer != NULL)
 				free(qstate->io_buffer);
 			

==== //depot/projects/soc2005/nsswitch_cached/release/cached-0.1/bin/mp_rs_query.c#5 (text+ko) ====

@@ -92,7 +92,7 @@
 			return (-1);
 		}
 		
-		if (c_mp_rs_request->entry_length == 0) {
+		if (BUFSIZE_INVALID(c_mp_rs_request->entry_length)) {
 			TRACE_OUT(on_mp_read_session_request_read1);
 			return (-1);
 		}
@@ -158,7 +158,7 @@
 		return (-1);
 	}
 
-	asprintf(&dec_cache_entry_name, "%s%s", qstate->euid_str,
+	asprintf(&dec_cache_entry_name, "%s%s", qstate->eid_str,
 		qstate->config_entry->c_params->entry_name);
 	assert(dec_cache_entry_name != NULL);	
 	

==== //depot/projects/soc2005/nsswitch_cached/release/cached-0.1/bin/mp_rs_query.h#5 (text+ko) ====


==== //depot/projects/soc2005/nsswitch_cached/release/cached-0.1/bin/mp_ws_query.c#5 (text+ko) ====

@@ -94,7 +94,7 @@
 			return (-1);
 		}
 		
-		if (c_mp_ws_request->entry_length == 0) {
+		if (BUFSIZE_INVALID(c_mp_ws_request->entry_length)) {
 			TRACE_OUT(on_mp_write_session_request_read1);
 			return (-1);
 		}
@@ -161,7 +161,7 @@
 		return (-1);
 	}
 
-	asprintf(&dec_cache_entry_name, "%s%s", qstate->euid_str,
+	asprintf(&dec_cache_entry_name, "%s%s", qstate->eid_str,
 		qstate->config_entry->c_params->entry_name);
 	assert(dec_cache_entry_name != NULL);	
 	
@@ -303,6 +303,11 @@
 		TRACE_OUT(on_mp_write_session_write_request_read1);
 		return (-1);
 	}
+	
+	if (BUFSIZE_INVALID(write_request->data_size)) {
+		TRACE_OUT(on_mp_write_session_write_request_read1);
+		return (-1);
+	}
 			
 	write_request->data = (char *)malloc(write_request->data_size);
 	assert(write_request->data != NULL);

==== //depot/projects/soc2005/nsswitch_cached/release/cached-0.1/bin/mp_ws_query.h#5 (text+ko) ====


==== //depot/projects/soc2005/nsswitch_cached/release/cached-0.1/bin/protocol.h#4 (text+ko) ====

@@ -30,6 +30,13 @@
 
 #include <stdlib.h>
 
+/* maximum buffer size to receive - larger buffers are not allowed */
+#define MAX_BUFFER_SIZE (1 << 20)
+
+/* buffer size correctness checking routine */
+#define BUFSIZE_CORRECT(x) (((x) > 0) && ((x) < MAX_BUFFER_SIZE))
+#define BUFSIZE_INVALID(x) (!BUFSIZE_CORRECT(x))
+
 struct cache_write_request
 {
 	char	*entry;

==== //depot/projects/soc2005/nsswitch_cached/release/cached-0.1/bin/query.c#5 (text+ko) ====

@@ -67,16 +67,15 @@
 {
 	struct msghdr	cred_hdr;
 	struct iovec	iov;
-	int	elem_type;
+	int elem_type;
 
 	struct {
 		struct cmsghdr	hdr;
 		struct cmsgcred	creds;
-	} cmsg;	
+	} cmsg;
 	
 	TRACE_IN(on_query_startup);
 	assert(qstate != NULL);
-	assert(qstate != NULL);
 	
 	memset(&cred_hdr, 0, sizeof(struct msghdr));
 	cred_hdr.msg_iov = &iov;
@@ -88,6 +87,7 @@
 	iov.iov_base = &elem_type;
 	iov.iov_len = sizeof(int);
 
+	TRACE_INT(qstate->sockfd);
 	if (recvmsg(qstate->sockfd, &cred_hdr, 0) == -1) {
 		TRACE_OUT(on_query_startup);
 		return (-1);
@@ -101,19 +101,25 @@
 	}
     
 	qstate->uid = cmsg.creds.cmcred_uid;
-	qstate->euid = cmsg.creds.cmcred_euid;
-	qstate->pid = cmsg.creds.cmcred_pid;
-	
-	if (asprintf(&qstate->euid_str, "%d_", qstate->euid) == -1) {
-	    TRACE_OUT(on_query_startup);
-	    return (-1);
-	}
-	qstate->euid_str_length = strlen(qstate->euid_str);
+	qstate->gid = cmsg.creds.cmcred_gid;
 	
 	TRACE_INT(qstate->uid);
+	TRACE_INT(qstate->gid);
 	TRACE_INT(qstate->euid);
-	TRACE_INT(qstate->pid);
+	TRACE_INT(qstate->egid);	
 	
+/*
+ This check is probably a bit redundant - per-user cache is always separated by
+ the euid/egid pair
+*/
+#ifndef NO_STRICT_EID_CHECKING
+	if ((qstate->uid != qstate->euid) ||
+		(qstate->gid != qstate->egid)) {
+		TRACE_OUT(on_query_startup);
+		return (-1);
+	}
+#endif
+		
 	switch (elem_type) {
 	case CET_WRITE_REQUEST:
 		qstate->process_func = on_write_request_read1;
@@ -131,8 +137,8 @@
 		qstate->process_func = on_mp_read_session_request_read1;
 		break;
 	default:
-		elem_type = -1;
-	break;
+		TRACE_OUT(on_query_startup);
+		return (-1);
 	}
 
 	qstate->kevent_watermark = 0;
@@ -211,9 +217,9 @@
 			return (-1);
 		}
 		
-		if ((write_request->entry_length == 0) ||
-			(write_request->cache_key_length == 0) ||
-			(write_request->data_size == 0)) {
+		if (BUFSIZE_INVALID(write_request->entry_length) ||
+			BUFSIZE_INVALID(write_request->cache_key_length) ||
+			BUFSIZE_INVALID(write_request->data_size)) {
 			TRACE_OUT(on_write_request_read1);
 			return (-1);
 		}
@@ -225,11 +231,11 @@
 		
 		write_request->cache_key = (char *)malloc(
 			write_request->cache_key_length + 
-			qstate->euid_str_length + 1);
+			qstate->eid_str_length + 1);
 		assert(write_request->cache_key != NULL);
-		memcpy(write_request->cache_key, qstate->euid_str, 
-			qstate->euid_str_length);
-		memset(write_request->cache_key + qstate->euid_str_length, 0, 
+		memcpy(write_request->cache_key, qstate->eid_str, 
+			qstate->eid_str_length);
+		memset(write_request->cache_key + qstate->eid_str_length, 0, 
 			write_request->cache_key_length + 1);
 		
 		write_request->data = (char *)malloc(write_request->data_size);
@@ -258,7 +264,7 @@
 	result = qstate->read_func(qstate, write_request->entry, 
 		write_request->entry_length);
 	result += qstate->read_func(qstate, write_request->cache_key + 
-		qstate->euid_str_length, write_request->cache_key_length);
+		qstate->eid_str_length, write_request->cache_key_length);
 	result += qstate->read_func(qstate, write_request->data, 
 		write_request->data_size);
 	
@@ -345,7 +351,7 @@
 	if (result != sizeof(int)) {
 		TRACE_OUT(on_write_response_write1);
 		return (-1);
-		}
+	}
 				
 	finalize_comm_element(&qstate->request);
 	finalize_comm_element(&qstate->response);		
@@ -381,8 +387,8 @@
 			return (-1);
 		}
 		
-		if ((read_request->entry_length == 0) ||
-			(read_request->cache_key_length == 0)) {
+		if (BUFSIZE_INVALID(read_request->entry_length) ||
+			BUFSIZE_INVALID(read_request->cache_key_length)) {
 			TRACE_OUT(on_read_request_read1);
 			return (-1);
 		}
@@ -394,11 +400,11 @@
 				
 		read_request->cache_key = (char *)malloc(
 			read_request->cache_key_length + 
-			qstate->euid_str_length + 1);
+			qstate->eid_str_length + 1);
 		assert(read_request->cache_key != NULL);
-		memcpy(read_request->cache_key, qstate->euid_str, 
-			qstate->euid_str_length);
-		memset(read_request->cache_key + qstate->euid_str_length, 0, 
+		memcpy(read_request->cache_key, qstate->eid_str, 
+			qstate->eid_str_length);
+		memset(read_request->cache_key + qstate->eid_str_length, 0, 
 			read_request->cache_key_length + 1);
 
 		qstate->kevent_watermark = read_request->entry_length + 
@@ -422,7 +428,7 @@
 	result = qstate->read_func(qstate, read_request->entry, 
 		read_request->entry_length);
 	result += qstate->read_func(qstate, 
-		read_request->cache_key + qstate->euid_str_length,
+		read_request->cache_key + qstate->eid_str_length,
 		read_request->cache_key_length);
 	
 	if (result != qstate->kevent_watermark) {
@@ -685,9 +691,18 @@
 	ssize_t	result;
 	
 	TRACE_IN(query_socket_read);
+	if (qstate->socket_failed != 0) {
+		TRACE_POINT();
+		return (-1);
+	}
+	
 	result = read(qstate->sockfd, buf, nbytes);
-	TRACE_OUT(query_socket_read);
+	if ((result == -1) || (result < nbytes)) {
+		qstate->socket_failed = 1;
+		TRACE_POINT();
+	}
 	
+	TRACE_OUT(query_socket_read);	
 	return (result);
 }
 
@@ -697,21 +712,23 @@
 	ssize_t	result;
 	
 	TRACE_IN(query_socket_write);
+	if (qstate->socket_failed != 0) {
+		TRACE_POINT();
+		return (-1);
+	}
+	
 	result = write(qstate->sockfd, buf, nbytes);
-	if (result == -1) {
-		TRACE_INT(qstate->sockfd);
-		TRACE_PTR(buf);
-		TRACE_INT(nbytes);
-		TRACE_INT(errno);
+	if ((result == -1) || (result < nbytes)) {
+		qstate->socket_failed = 1;
+		TRACE_POINT();
 	}
 	
-	TRACE_OUT(query_socket_write);
-	
+	TRACE_OUT(query_socket_write);	
 	return (result);
 }
 
 struct query_state	*
-init_query_state(int sockfd, size_t kevent_watermark)
+init_query_state(int sockfd, size_t kevent_watermark, uid_t euid, gid_t egid)
 {
 	struct query_state	*retval;
 		
@@ -724,6 +741,18 @@
 	retval->kevent_filter = EVFILT_READ;
 	retval->kevent_watermark = kevent_watermark;
 	
+	retval->euid = euid;
+	retval->egid = egid;
+	retval->uid = retval->gid = -1;
+	
+	if (asprintf(&retval->eid_str, "%d_%d_", retval->euid, 
+		retval->egid) == -1) {
+		free(retval);
+	    TRACE_OUT(init_query_state);
+	    return (NULL);
+	}
+	retval->eid_str_length = strlen(retval->eid_str);	
+	
 	init_comm_element(&retval->request, CET_UNDEFINED);
 	init_comm_element(&retval->response, CET_UNDEFINED);
 	retval->process_func = on_query_startup;
@@ -744,8 +773,8 @@
 destroy_query_state(struct query_state *qstate)
 {
 	TRACE_IN(destroy_query_state);
-	if (qstate->euid_str != NULL)
-	    free(qstate->euid_str);
+	if (qstate->eid_str != NULL)
+	    free(qstate->eid_str);
     
 	if (qstate->io_buffer != NULL)
 		free(qstate->io_buffer);

==== //depot/projects/soc2005/nsswitch_cached/release/cached-0.1/bin/query.h#5 (text+ko) ====

@@ -64,18 +64,20 @@
 	query_write_func write_func;		/* data write function */
 	query_read_func read_func;		/* data read function */
 
-	char	*euid_str;	/* string version of the euid */
-	size_t	euid_str_length;
+	char	*eid_str;	/* the user-identifying string (euid_egid_) */
+	size_t	eid_str_length;
 	
-	uid_t	euid;	/* euid of the caller, recevied via credentials */	
-	uid_t	uid;	/* uid of the caller, recevied via credentials */
-	pid_t	pid;	/* pid of the caller, recevied via credentials */
+	uid_t	euid;	/* euid of the caller, received via getpeereid */
+	uid_t	uid;	/* uid of the caller, received via credentials */
+	gid_t	egid;	/* egid of the caller, received via getpeereid */
+	gid_t	gid;	/* gid of the caller received via credentials */
 
 	size_t	io_buffer_size;
 	size_t	io_buffer_watermark;
 	size_t	kevent_watermark;	/* bytes to be sent/received */	
 	int	sockfd;			/* the unix socket to read/write */
-	int	kevent_filter;		/* EVFILT_READ or EVFILT_WRITE */
+	int	kevent_filter;	/* EVFILT_READ or EVFILT_WRITE */
+	int socket_failed;	/* set to 1 if the socket doesn't work correctly */
 	
 	char	*io_buffer;
 	char	*io_buffer_p;
@@ -91,7 +93,7 @@
 extern ssize_t query_socket_write(struct query_state *, const void *, 
 	size_t);
 
-extern struct query_state *init_query_state(int, size_t);
+extern struct query_state *init_query_state(int, size_t, uid_t, gid_t);
 extern void destroy_query_state(struct query_state *);
 	
 extern struct configuration_entry *find_config_entry_by_name_and_euid(

==== //depot/projects/soc2005/nsswitch_cached/tests/nsdispatch_test/nsdispatch_test.c#7 (text+ko) ====

@@ -411,17 +411,17 @@
 	tsystem = __init_test_system("testing system testing :)");
 	assert(tsystem != NULL);	
 
-/*	tinfo = __create_test_info("getservbyname_test", getservbyname_test, 1);
+	tinfo = __create_test_info("getservbyname_test", getservbyname_test, 1);
 	assert(tinfo != NULL);
-	__register_test_info(tsystem, tinfo);*/
+	__register_test_info(tsystem, tinfo);
 	
 	tinfo = __create_test_info("getpwnam_test", getpwnam_test, 1);
 	assert(tinfo != NULL);
 	__register_test_info(tsystem, tinfo);
 
-/*	tinfo = __create_test_info("getgrnam_test", getgrnam_test, 1);
+	tinfo = __create_test_info("getgrnam_test", getgrnam_test, 1);
 	assert(tinfo != NULL);	
-	__register_test_info(tsystem, tinfo);*/
+	__register_test_info(tsystem, tinfo);
 	
 /*	tinfo = __create_test_info("getaddrinfo_test", getaddrinfo_test, 1);
 	assert(tinfo != NULL);	
@@ -435,13 +435,13 @@
 	assert(tinfo != NULL);	
 	__register_test_info(tsystem, tinfo);	*/
 	
-/*	tinfo = __create_test_info("getprotoent_test", getprotoent_test, 1);
+	tinfo = __create_test_info("getprotoent_test", getprotoent_test, 1);
 	assert(tinfo != NULL);
-	__register_test_info(tsystem, tinfo);*/
+	__register_test_info(tsystem, tinfo);
 
-/*	tinfo = __create_test_info("getrpcent_test", getrpcent_test, 1);
+	tinfo = __create_test_info("getrpcent_test", getrpcent_test, 1);
 	assert(tinfo != NULL);
-	__register_test_info(tsystem, tinfo);*/
+	__register_test_info(tsystem, tinfo);
 	
 	__process_tests(tsystem, &passed, &failed);
 	__test_log1("__process_tests returned, %d passed, %d failed\n", passed, failed);



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200509191401.j8JE1LBv045197>