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