PERFORCE change 93450 for review

soc-bushman soc-bushman at FreeBSD.org
Fri Mar 17 15:52:17 UTC 2006


http://perforce.freebsd.org/chv.cgi?CH=93450

Change 93450 by soc-bushman at soc-bushman_stinger on 2006/03/17 15:51:16

	the euid/egid checking policy was updated

Affected files ...

.. //depot/projects/soc2005/nsswitch_cached/src/lib/libc/net/nsdispatch.c#15 edit
.. //depot/projects/soc2005/nsswitch_cached/src/usr.sbin/cached/mp_rs_query.c#2 edit
.. //depot/projects/soc2005/nsswitch_cached/src/usr.sbin/cached/mp_rs_query.h#2 edit
.. //depot/projects/soc2005/nsswitch_cached/src/usr.sbin/cached/mp_ws_query.c#2 edit
.. //depot/projects/soc2005/nsswitch_cached/src/usr.sbin/cached/mp_ws_query.h#2 edit
.. //depot/projects/soc2005/nsswitch_cached/src/usr.sbin/cached/query.c#2 edit
.. //depot/projects/soc2005/nsswitch_cached/src/usr.sbin/cached/query.h#2 edit

Differences ...

==== //depot/projects/soc2005/nsswitch_cached/src/lib/libc/net/nsdispatch.c#15 (text+ko) ====

@@ -644,10 +644,10 @@
 #ifdef NS_CACHING
 			if ((strcmp(srclist[i].name, NSSRC_CACHE) == 0) && 
 			    (nss_cache_cycle_prevention_func == NULL)) {
-#ifndef NS_NO_STRICT_EID_CHECKING
+#ifdef NS_STRICT_LIBC_EID_CHECKING
 				if (issetugid() != 0)
 					continue;
-#endif /* NS_NO_STRICT_EID_CHECKING */
+#endif
 				cache_flag = 1;
 				
 				memset(&cache_data, 0, sizeof(nss_cache_data));

==== //depot/projects/soc2005/nsswitch_cached/src/usr.sbin/cached/mp_rs_query.c#2 (text+ko) ====

@@ -30,6 +30,7 @@
 #include <sys/types.h>
 #include <sys/event.h>
 #include <assert.h>
+#include <errno.h>
 #include <stdlib.h>
 #include <string.h>
 #include <stdio.h>
@@ -38,6 +39,7 @@
 #include "config.h"
 #include "debug.h"
 #include "log.h"
+#include "query.h"
 #include "mp_rs_query.h"
 #include "mp_ws_query.h"
 #include "singletons.h"
@@ -174,27 +176,35 @@
 	qstate->config_entry = configuration_find_entry(
 		s_configuration, c_mp_rs_request->entry);	
 	if (qstate->config_entry == NULL) {
+		c_mp_rs_response->error_code = ENOENT;
+		
 		LOG_ERR_2("read_session_request",
 			"can't find configuration entry '%s'."
 			" aborting request", c_mp_rs_request->entry);
-		TRACE_OUT(on_write_request_process);
-		return (-1);
+		goto fin;
 	}
 	
 	if (qstate->config_entry->enabled == 0) {
+		c_mp_rs_response->error_code = EACCES;
+		
 		LOG_ERR_2("read_session_request",
 			"configuration entry '%s' is disabled", 
 			c_mp_rs_request->entry);
-		TRACE_OUT(on_read_request_process);
-		return (-1);
+		goto fin;
 	}	
 
 	if (qstate->config_entry->perform_actual_lookups != 0)
 		dec_cache_entry_name = strdup(
 			qstate->config_entry->mp_cache_params.entry_name);
-	else
+	else {
+		if (check_query_eids(qstate) != 0) {
+			c_mp_rs_response->error_code = EPERM;
+			goto fin;
+		}
+		
 		asprintf(&dec_cache_entry_name, "%s%s", qstate->eid_str,
 			qstate->config_entry->mp_cache_params.entry_name);
+	}
 	
 	assert(dec_cache_entry_name != NULL);	
 	
@@ -301,6 +311,7 @@
 	} else
 		c_mp_rs_response->error_code = -1;
 
+fin:
 	qstate->process_func = on_mp_read_session_response_write1;
 	qstate->kevent_watermark = sizeof(int);
 	qstate->kevent_filter = EVFILT_WRITE;	

==== //depot/projects/soc2005/nsswitch_cached/src/usr.sbin/cached/mp_rs_query.h#2 (text+ko) ====

@@ -28,8 +28,6 @@
 #ifndef __CACHED_MP_RS_QUERY_H__
 #define __CACHED_MP_RS_QUERY_H__
 
-#include "query.h"
-
 extern int on_mp_read_session_request_read1(struct query_state *);
 
 #endif

==== //depot/projects/soc2005/nsswitch_cached/src/usr.sbin/cached/mp_ws_query.c#2 (text+ko) ====

@@ -30,6 +30,7 @@
 #include <sys/types.h>
 #include <sys/event.h>
 #include <assert.h>
+#include <errno.h>
 #include <stdlib.h>
 #include <string.h>
 #include <stdio.h>
@@ -38,6 +39,7 @@
 #include "config.h"
 #include "debug.h"
 #include "log.h"
+#include "query.h"
 #include "mp_ws_query.h"
 #include "singletons.h"
 
@@ -173,28 +175,35 @@
 	qstate->config_entry = configuration_find_entry(
 		s_configuration, c_mp_ws_request->entry);	
 	if (qstate->config_entry == NULL) {
+		c_mp_ws_response->error_code = ENOENT;
+		
 		LOG_ERR_2("write_session_request",
 			"can't find configuration entry '%s'. "
 	    		"aborting request", c_mp_ws_request->entry);
-		TRACE_OUT(on_write_request_process);
-		return (-1);
+	    	goto fin;
 	}
 
 	if (qstate->config_entry->enabled == 0) {
+		c_mp_ws_response->error_code = EACCES;
+		
 		LOG_ERR_2("write_session_request",
 			"configuration entry '%s' is disabled",
 			c_mp_ws_request->entry);
-		TRACE_OUT(on_read_request_process);
-		return (-1);
+		goto fin;
 	}
 	
 	if (qstate->config_entry->perform_actual_lookups != 0) {
+		c_mp_ws_response->error_code = EOPNOTSUPP;
+
 		LOG_ERR_2("write_session_request",
 			"entry '%s' performs lookups by itself: "
 			"can't write to it", c_mp_ws_request->entry);
-		TRACE_OUT(on_write_request_process);
-		return (-1);
-	}
+		goto fin;
+	} else
+		if (check_query_eids(qstate) != 0) {
+			c_mp_ws_response->error_code = EPERM;
+			goto fin;
+		}
 	
 	/*
 	 * All multipart entries are separated by their name decorations.
@@ -233,9 +242,11 @@
 	}
 	configuration_unlock_entry(qstate->config_entry, CELT_MULTIPART);
 
+fin:
 	qstate->process_func = on_mp_write_session_response_write1;
 	qstate->kevent_watermark = sizeof(int);
 	qstate->kevent_filter = EVFILT_WRITE;	
+	
 	TRACE_OUT(on_mp_write_session_request_process);
 	return (0);
 }

==== //depot/projects/soc2005/nsswitch_cached/src/usr.sbin/cached/mp_ws_query.h#2 (text+ko) ====

@@ -28,8 +28,6 @@
 #ifndef __CACHED_MP_WS_QUERY_H__
 #define __CACHED_MP_WS_QUERY_H__
 
-#include "query.h"
-
 extern int on_mp_write_session_request_read1(struct query_state *);
 extern cache_entry register_new_mp_cache_entry(struct query_state *, 
 	const char *);

==== //depot/projects/soc2005/nsswitch_cached/src/usr.sbin/cached/query.c#2 (text+ko) ====

@@ -46,7 +46,7 @@
 static const char negative_data[1] = { 0 };
 
 extern	void get_time_func(struct timeval *);
-	
+
 static 	void clear_config_entry(struct configuration_entry *);
 static 	void clear_config_entry_part(struct configuration_entry *, 
 	const char *, size_t);
@@ -73,7 +73,6 @@
 static	int on_write_request_process(struct query_state *);
 static	int on_write_response_write1(struct query_state *);
 	
-
 /*
  * Clears the specified configuration entry (clears the cache for positive and
  * and negative entries) and also for all multipart entries.
@@ -191,14 +190,21 @@
  * 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)) {
+	if (check_query_eids(qstate) != 0) {
+#ifdef NS_STRICT_CACHED_EID_CHECKING
 		TRACE_OUT(on_query_startup);
 		return (-1);
+#else
+		if ((elem_type != CET_READ_REQUEST) &&
+			(elem_type != CET_MP_READ_SESSION_REQUEST) &&
+			(elem_type != CET_WRITE_REQUEST) &&
+			(elem_type != CET_MP_WRITE_SESSION_REQUEST)) {				
+			TRACE_OUT(on_query_startup);
+			return (-1);
+		}			
+#endif
 	}
-#endif
-		
+
 	switch (elem_type) {
 	case CET_WRITE_REQUEST:
 		qstate->process_func = on_write_request_read1;
@@ -400,27 +406,30 @@
 		s_configuration, write_request->entry);	
 	
 	if (qstate->config_entry == NULL) {
+		write_response->error_code = ENOENT;
+		
 		LOG_ERR_2("write_request", "can't find configuration"
 		    " entry '%s'. aborting request", write_request->entry);
-		TRACE_OUT(on_write_request_process);
-		return (-1);
+		goto fin;
 	}
 	
 	if (qstate->config_entry->enabled == 0) {
+		write_response->error_code = EACCES;
+		
 		LOG_ERR_2("write_request",
 			"configuration entry '%s' is disabled",
 			write_request->entry);
-		TRACE_OUT(on_write_request_process);
-		return (-1);
+		goto fin;
 	}	
 	
 	if (qstate->config_entry->perform_actual_lookups != 0) {
+		write_response->error_code = EOPNOTSUPP;
+		
 		LOG_ERR_2("write_request",
 			"entry '%s' performs lookups by itself: "
 			"can't write to it", write_request->entry);
-		TRACE_OUT(on_write_request_process);
-		return (-1);
-	}	
+		goto fin;
+	}
 
 	configuration_lock_rdlock(s_configuration);
 	c_entry = find_cache_entry(s_cache, 
@@ -445,9 +454,11 @@
 	} else
 		write_response->error_code = -1;
 	
+fin:
 	qstate->kevent_filter = EVFILT_WRITE;
 	qstate->kevent_watermark = sizeof(int);
 	qstate->process_func = on_write_response_write1;
+	
 	TRACE_OUT(on_write_request_process);
 	return (0);
 }
@@ -468,28 +479,35 @@
 		s_configuration, write_request->entry);	
 	
 	if (qstate->config_entry == NULL) {
+		write_response->error_code = ENOENT;
+		
 		LOG_ERR_2("negative_write_request",
 			"can't find configuration"
 		   	" entry '%s'. aborting request", write_request->entry);
-		TRACE_OUT(on_negative_write_request_process);
-		return (-1);
+		goto fin;
 	}
 	
 	if (qstate->config_entry->enabled == 0) {
+		write_response->error_code = EACCES;
+
 		LOG_ERR_2("negative_write_request",
 			"configuration entry '%s' is disabled",
 			write_request->entry);
-		TRACE_OUT(on_negative_write_request_process);
-		return (-1);
+		goto fin;
 	}	
 	
 	if (qstate->config_entry->perform_actual_lookups != 0) {
+		write_response->error_code = EOPNOTSUPP;
+		
 		LOG_ERR_2("negative_write_request",
 			"entry '%s' performs lookups by itself: "
 			"can't write to it", write_request->entry);
-		TRACE_OUT(on_negative_write_request_process);
-		return (-1);
-	}	
+		goto fin;
+	} else
+		if (check_query_eids(qstate) != 0) {
+			write_response->error_code = EPERM;
+			goto fin;
+		}
 	
 	configuration_lock_rdlock(s_configuration);
 	c_entry = find_cache_entry(s_cache, 
@@ -513,9 +531,11 @@
 	} else
 		write_response->error_code = -1;
 	
+fin:
 	qstate->kevent_filter = EVFILT_WRITE;
 	qstate->kevent_watermark = sizeof(int);
 	qstate->process_func = on_write_response_write1;
+	
 	TRACE_OUT(on_negative_write_request_process);
 	return (0);
 }
@@ -541,6 +561,7 @@
 	qstate->kevent_watermark = sizeof(int);
 	qstate->kevent_filter = EVFILT_READ;
 	qstate->process_func = on_rw_mapper;
+	
 	TRACE_OUT(on_write_response_write1);
 	return (0);
 }
@@ -650,19 +671,21 @@
 	qstate->config_entry = configuration_find_entry(
 		s_configuration, read_request->entry);	
 	if (qstate->config_entry == NULL) {
+		read_response->error_code = ENOENT;
+		
 		LOG_ERR_2("read_request",
 			"can't find configuration "
 	    		"entry '%s'. aborting request", read_request->entry);
-		TRACE_OUT(on_read_request_process);
-		return (-1);
+	    	goto fin;
 	}
 	
 	if (qstate->config_entry->enabled == 0) {
+		read_response->error_code = EACCES;
+		
 		LOG_ERR_2("read_request",
 			"configuration entry '%s' is disabled",
 			read_request->entry);
-		TRACE_OUT(on_read_request_process);
-		return (-1);
+		goto fin;
 	}
 
 	/* 
@@ -671,6 +694,12 @@
 	 */
 	if (qstate->config_entry->perform_actual_lookups != 0)
 		memset(read_request->cache_key, 0, qstate->eid_str_length);
+	else
+		if (check_query_eids(qstate) != 0) {
+		/* if the lookup is not self-performing, we check for clients euid/egid */
+			read_response->error_code = EPERM;
+			goto fin;
+		}
 	
 	configuration_lock_rdlock(s_configuration);
 	c_entry = find_cache_entry(s_cache, 
@@ -776,6 +805,7 @@
 	} else
 		read_response->error_code = -1;
 	
+fin:
 	qstate->kevent_filter = EVFILT_WRITE;
 	if (read_response->error_code == 0)
 		qstate->kevent_watermark = sizeof(int) + sizeof(size_t);
@@ -1051,6 +1081,17 @@
 }
 
 /*
+ * Checks if the client's euid and egid do not differ from its uid and gid.
+ * Returns 0 on success.
+ */
+int
+check_query_eids(struct query_state *qstate)
+{
+	
+	return ((qstate->uid != qstate->euid) || (qstate->gid != qstate->egid) ? -1 : 0);
+}
+
+/*
  * Uses the qstate fields to process an "alternate" read - when the buffer is
  * too large to be received during one socket read operation
  */

==== //depot/projects/soc2005/nsswitch_cached/src/usr.sbin/cached/query.h#2 (text+ko) ====

@@ -93,6 +93,8 @@
 	int	use_alternate_io;
 };
 
+extern int check_query_eids(struct query_state *);
+
 extern ssize_t query_io_buffer_read(struct query_state *, void *, size_t);
 extern ssize_t query_io_buffer_write(struct query_state *, const void *, 
 	size_t);


More information about the p4-projects mailing list