Attached is first version of support for multiple security items (uid-gid).

First question what I have. I'm currently testing uid and gid as a pair,
so user process must have gid and uid (not only uid or gid). Is that
correct, or you will rather see something, what will check uid OR gid?
(From my point of view, both solution are acceptable and both have some
pros/cons, so I think, there should be major consensus)

Second question. Items are cached, but in list. Steve talked something
about, that this is fast path, so isn't list some performance killer? If
yes, I think we can use:
- hash table (red black tree/...) in case 1. question will be answered,
that we should check uid and gid as a pair
- bit-array of uid and gid, if 1. question will be answered uid OR gid

Third question. I'm not sure, if I should implement some reloading stuff
or not. Because in current implementation, ug_config.uid/gid are never
reloaded, and only logstuff is reloaded.

Fourth think. From my point of view. ug_config.uid/gid no longer make
sense to be used for IPC authentifications (becase this patch should be
full and better replacement), so second patch (corosync-remove-...)
removes this.

And last think. Can please somebody with native English language update
manual pages? Of course I can do that, but ... I'm not sure that my
Czechlish is understandable to anybody different then me, and you, as my
colleagues ;)

Regards,
  Honza
diff --git a/trunk/exec/main.c b/trunk/exec/main.c
index db22e96..8ebf8ad 100644
--- a/trunk/exec/main.c
+++ b/trunk/exec/main.c
@@ -138,6 +138,18 @@ static void sigusr2_handler (int num)
 	}
 }
 
+static void corosync_remove_security_list (void) {
+	struct list_head *iter;
+
+	for (iter = ug_config.security_list.next; iter != &ug_config.security_list; ) {
+		struct security_item *si = list_entry (iter, struct security_item, list);
+		iter = iter->next;
+
+		list_del (&si->list);
+		free (si);
+	}
+}
+
 /*
  * TODO this function needs some love
  */
@@ -150,6 +162,10 @@ void corosync_request_shutdown (void)
 	poll_stop (0);
 	totempg_finalize ();
 	coroipcs_ipc_exit ();
+
+	/*Remove security_list*/
+	corosync_remove_security_list ();
+
 	corosync_exit_error (AIS_DONE_EXIT);
 }
 
@@ -482,12 +498,21 @@ static coroipcs_handler_fn_lvalue corosync_handler_fn_get (unsigned int service,
 
 static int corosync_security_valid (int euid, int egid)
 {
+	struct list_head *iter;
 	if (euid == 0 || egid == 0) {
 		return (1);
 	}
 	if (euid == ug_config.uid || egid == ug_config.gid) {
 		return (1);
 	}
+
+	for (iter = ug_config.security_list.next; iter != &ug_config.security_list; iter = iter->next) {
+		struct security_item *si = list_entry (iter, struct security_item, list);
+
+		if (euid == si->uid && egid == si->gid)
+			return (1);
+	}
+
 	return (0);
 }
 
diff --git a/trunk/exec/mainconfig.c b/trunk/exec/mainconfig.c
index 79e01cd..e20fffc 100644
--- a/trunk/exec/mainconfig.c
+++ b/trunk/exec/mainconfig.c
@@ -671,6 +671,54 @@ static void add_logsys_config_notification(
 
 }
 
+static int corosync_main_config_read_security (
+	struct objdb_iface_ver0 *objdb,
+	const char **error_string,
+	struct ug_config *ug_config)
+{
+	hdb_handle_t object_find_handle;
+	hdb_handle_t object_service_handle;
+	char *value;
+	int uid, gid;
+	struct security_item *si;
+
+	list_init (&ug_config->security_list);
+
+	objdb->object_find_create (
+		OBJECT_PARENT_HANDLE,
+		"security",
+		strlen ("security"),
+		&object_find_handle);
+
+	while (objdb->object_find_next (
+		object_find_handle,
+		&object_service_handle) == 0) {
+		uid = -1;
+		gid = -1;
+
+		if (!objdb_get_string (objdb,object_service_handle, "uid", &value)) {
+			uid = uid_determine(value);
+		}
+
+		if (!objdb_get_string (objdb,object_service_handle, "gid", &value)) {
+			gid = gid_determine(value);
+		}
+
+		if (uid > -1 && gid > -1) {
+			si = malloc (sizeof (*si));
+			if (si == NULL) {
+				_corosync_out_of_memory_error();
+			}
+			si->uid = uid;
+			si->gid = gid;
+			list_add (&si->list, &ug_config->security_list);
+		}
+	}
+	objdb->object_find_destroy (object_find_handle);
+
+	return 0;
+}
+
 int corosync_main_config_read (
 	struct objdb_iface_ver0 *objdb,
 	const char **error_string,
@@ -719,6 +767,8 @@ int corosync_main_config_read (
 		ug_config->gid = gid_determine("ais");
 	}
 
+	corosync_main_config_read_security (objdb, error_string, ug_config);
+
 	add_logsys_config_notification(objdb);
 
 	return 0;
diff --git a/trunk/exec/mainconfig.h b/trunk/exec/mainconfig.h
index c9ab7ea..f3b8cd8 100644
--- a/trunk/exec/mainconfig.h
+++ b/trunk/exec/mainconfig.h
@@ -37,6 +37,7 @@
 
 #include <corosync/engine/objdb.h>
 #include <corosync/engine/logsys.h>
+#include <corosync/list.h>
 
 /*
  * All service handlers in the AIS
@@ -49,14 +50,29 @@ struct dynamic_service {
 };
 #define MAX_DYNAMIC_SERVICES 128
 
+/*
+ * Structure describing cached security item
+ */
+struct security_item {
+	struct list_head list;
+	int uid;
+	int gid;
+};
+
 struct ug_config {
 	/*
 	 * user/group to run as
 	 */
 	int uid;
 	int gid;
+
+	/*
+	 * Allowed users/group to connect. This is of type security item.
+	 */
+	struct list_head security_list;
 };
 
+
 extern int corosync_main_config_read (
 	struct objdb_iface_ver0 *objdb,
 	const char **error_string,
diff --git a/trunk/exec/main.c b/trunk/exec/main.c
index 8ebf8ad..8956127 100644
--- a/trunk/exec/main.c
+++ b/trunk/exec/main.c
@@ -502,9 +502,6 @@ static int corosync_security_valid (int euid, int egid)
 	if (euid == 0 || egid == 0) {
 		return (1);
 	}
-	if (euid == ug_config.uid || egid == ug_config.gid) {
-		return (1);
-	}
 
 	for (iter = ug_config.security_list.next; iter != &ug_config.security_list; iter = iter->next) {
 		struct security_item *si = list_entry (iter, struct security_item, list);
_______________________________________________
Openais mailing list
Openais@lists.linux-foundation.org
https://lists.linux-foundation.org/mailman/listinfo/openais

Reply via email to