SSIA.

https://bugzilla.redhat.com/show_bug.cgi?id=501337

Regards,
  Honza
diff --git a/branches/whitetank/exec/aisparser.c b/branches/whitetank/exec/aisparser.c
index bf017ac..2d700be 100644
--- a/branches/whitetank/exec/aisparser.c
+++ b/branches/whitetank/exec/aisparser.c
@@ -44,6 +44,7 @@
 #include <errno.h>
 #include <signal.h>
 #include <string.h>
+#include <dirent.h>
 
 #include "../lcr/lcr_comp.h"
 #include "objdb.h"
@@ -56,6 +57,14 @@ static int read_config_file_into_objdb(
 	char **error_string);
 static char error_string_response[512];
 
+#define PCHECK_ADD_SUBSECTION 1
+#define PCHECK_ADD_ITEM       2
+
+typedef int (*parser_check_item_f)(struct objdb_iface_ver0 *objdb,
+				unsigned int parent_handle,
+				int type,
+				const char *name,
+				char **error_string);
 
 static int aisparser_readconfig (struct objdb_iface_ver0 *objdb, char **error_string)
 {
@@ -83,7 +92,8 @@ static char *remove_whitespace(char *string)
 static int parse_section(FILE *fp,
 			 struct objdb_iface_ver0 *objdb,
 			 unsigned int parent_handle,
-			 char **error_string)
+			 char **error_string,
+			 parser_check_item_f parser_check_item_call)
 {
 	char line[512];
 	int i;
@@ -115,9 +125,15 @@ static int parse_section(FILE *fp,
 
 			loc--;
 			*loc = '\0';
+			if (parser_check_item_call) {
+				if (!parser_check_item_call(objdb, parent_handle, PCHECK_ADD_SUBSECTION,
+				    section, error_string))
+					    return -1;
+			}
+
 			objdb->object_create (parent_handle, &new_parent,
 					      section, strlen (section));
-			if (parse_section(fp, objdb, new_parent, error_string))
+			if (parse_section(fp, objdb, new_parent, error_string, parser_check_item_call))
 				return -1;
 		}
 
@@ -129,6 +145,11 @@ static int parse_section(FILE *fp,
 			*(loc-1) = '\0';
 			key = remove_whitespace(line);
 			value = remove_whitespace(loc);
+			if (parser_check_item_call) {
+				if (!parser_check_item_call(objdb, parent_handle, PCHECK_ADD_ITEM,
+				    key, error_string))
+					    return -1;
+			}
 			objdb->object_key_create (parent_handle, key,
 				strlen (key),
 				value, strlen (value) + 1);
@@ -147,6 +168,73 @@ static int parse_section(FILE *fp,
 	return 0;
 }
 
+static int parser_check_item_uidgid(struct objdb_iface_ver0 *objdb,
+			unsigned int parent_handle,
+			int type,
+			const char *name,
+			char **error_string)
+{
+	if (type == PCHECK_ADD_SUBSECTION) {
+		if (parent_handle != OBJECT_PARENT_HANDLE) {
+			*error_string = "uidgid: Can't add second level subsection";
+			return 0;
+		}
+
+		if (strcmp (name, "uidgid") != 0) {
+			*error_string = "uidgid: Can't add subsection different then uidgid";
+			return 0;
+		}
+	}
+
+	if (type == PCHECK_ADD_ITEM) {
+		if (!(strcmp (name, "uid") == 0 || strcmp (name, "gid") == 0)) {
+			*error_string = "uidgid: Only uid and gid are allowed items";
+			return 0;
+		}
+	}
+
+	return 1;
+}
+
+static int read_uidgid_files_into_objdb(
+	struct objdb_iface_ver0 *objdb,
+	char **error_string)
+{
+	FILE *fp;
+	const char *dirname;
+	DIR *dp;
+	struct dirent *dirent;
+	char filename[PATH_MAX + NAME_MAX + 1];
+	int res = 0;
+
+	dirname = "/etc/ais/uidgid.d";
+	dp = opendir (dirname);
+
+	if (dp == NULL)
+		return 0;
+
+	while ((dirent = readdir (dp))) {
+		if (dirent->d_type == DT_REG) {
+			snprintf(filename, sizeof (filename), "%s/%s", dirname, dirent->d_name);
+
+			fp = fopen (filename, "r");
+			if (fp == NULL) continue;
+
+			res = parse_section(fp, objdb, OBJECT_PARENT_HANDLE, error_string, parser_check_item_uidgid);
+
+			fclose (fp);
+
+			if (res != 0) {
+				goto error_exit;
+			}
+		}
+	}
+
+error_exit:
+	closedir(dp);
+
+	return res;
+}
 
 
 /* Read config file and load into objdb */
@@ -171,10 +259,13 @@ static int read_config_file_into_objdb(
 		return -1;
 	}
 
-	res = parse_section(fp, objdb, OBJECT_PARENT_HANDLE, error_string);
+	res = parse_section(fp, objdb, OBJECT_PARENT_HANDLE, error_string, NULL);
 
 	fclose(fp);
 
+	if (res == 0) {
+		res = read_uidgid_files_into_objdb(objdb, error_string);
+	}
 	return res;
 }
 
diff --git a/branches/whitetank/exec/ipc.c b/branches/whitetank/exec/ipc.c
index cb6435a..0a00287 100644
--- a/branches/whitetank/exec/ipc.c
+++ b/branches/whitetank/exec/ipc.c
@@ -457,7 +457,7 @@ req_setup_recv (
 	if (getpeerucred (conn_info->fd, &uc) == 0) {
 		euid = ucred_geteuid (uc);
 		egid = ucred_getegid (uc);
-		if ((euid == 0) || (egid == g_gid_valid)) {
+		if ((euid == 0) || (egid == g_gid_valid) || ais_security_valid (euid, egid)) {
 			conn_info->authenticated = 1;
 		}
 		ucred_free(uc);
@@ -506,12 +506,12 @@ retry_recv:
 	assert (cmsg);
 	cred = (struct ucred *)CMSG_DATA (cmsg);
 	if (cred) {
-		if (cred->uid == 0 || cred->gid == g_gid_valid) {
+		if (cred->uid == 0 || cred->gid == g_gid_valid || ais_security_valid (cred->uid, cred->gid)) {
 		} else {
 			ipc_disconnect (conn_info);
 			log_printf (LOG_LEVEL_SECURITY,
-				"Connection not authenticated because gid is %d, expecting %d\n",
-				cred->gid, g_gid_valid);
+				"Connection with uid %d and gid %d not authenticated\n",
+				cred->uid, cred->gid);
 			return (-1);
 		}
 	}
diff --git a/branches/whitetank/exec/main.c b/branches/whitetank/exec/main.c
index f0730b4..51e1626 100644
--- a/branches/whitetank/exec/main.c
+++ b/branches/whitetank/exec/main.c
@@ -93,6 +93,8 @@ static char delivery_data[MESSAGE_SIZE_MAX];
 
 static struct objdb_iface_ver0 *objdb = NULL;
 
+static struct list_head uidgid_list;
+
 SaClmClusterNodeT *(*main_clm_get_by_nodeid) (unsigned int node_id);
 
 static void sigusr2_handler (int num)
@@ -279,6 +281,19 @@ static void aisexec_gid_determine (struct main_config *main_config)
 	endgrent();
 }
 
+int ais_security_valid (int euid, int egid)
+{
+	struct list_head *iter;
+
+	for (iter = uidgid_list.next; iter != &uidgid_list; iter = iter->next) {
+		struct uidgid_item *ugi = list_entry (iter, struct uidgid_item, list);
+		if (euid == ugi->uid || egid == ugi->gid)
+			return (1);
+	}
+
+	return (0);
+}
+
 static void aisexec_priv_drop (void)
 {
 return;
@@ -527,7 +542,7 @@ int main (int argc, char **argv)
 		openais_exit_error (AIS_DONE_MAINCONFIGREAD);
 	}
 
-	res = openais_main_config_read (objdb, &error_string, &main_config);
+	res = openais_main_config_read (objdb, &error_string, &main_config, &uidgid_list);
 	if (res == -1) {
 		log_printf (LOG_LEVEL_ERROR, error_string);
 		openais_exit_error (AIS_DONE_MAINCONFIGREAD);
diff --git a/branches/whitetank/exec/main.h b/branches/whitetank/exec/main.h
index df151c9..d56c5e1 100644
--- a/branches/whitetank/exec/main.h
+++ b/branches/whitetank/exec/main.h
@@ -61,4 +61,6 @@ poll_handle aisexec_poll_handle;
 
 extern SaClmClusterNodeT *(*main_clm_get_by_nodeid) (unsigned int node_id);
 
+extern int ais_security_valid (int euid, int egid);
+
 #endif /* AIS_EXEC_H_DEFINED */
diff --git a/branches/whitetank/exec/mainconfig.c b/branches/whitetank/exec/mainconfig.c
index 29edb9e..0ed7ebe 100644
--- a/branches/whitetank/exec/mainconfig.c
+++ b/branches/whitetank/exec/mainconfig.c
@@ -49,6 +49,8 @@
 #include "print.h"
 #include "totem.h"
 #include "service.h"
+#include <pwd.h>
+#include <grp.h>
 
 static char error_string_response[512];
 
@@ -87,10 +89,89 @@ static inline void objdb_get_int (
 	}
 }
 
+static int uid_determine (const char *req_user, char **error_string)
+{
+        struct passwd *passwd;
+        int ais_uid = 0;
+
+        passwd = getpwnam(req_user);
+        if (passwd == 0) {
+               *error_string="ERROR: Can't find user in /etc/passwd, please read the documentation.";
+               return -1;
+        }
+        ais_uid = passwd->pw_uid;
+        endpwent ();
+        return ais_uid;
+}
+
+static int gid_determine (const char *req_group, char **error_string)
+{
+        struct group *group;
+        int ais_gid = 0;
+
+        group = getgrnam (req_group);
+        if (group == 0) {
+               *error_string = "ERROR: Can't find group in /etc/group, please read the documentation.";
+               return -1;
+        }
+        ais_gid = group->gr_gid;
+        endgrent ();
+        return ais_gid;
+}
+
+
+static int ais_main_config_read_uidgid (
+	struct objdb_iface_ver0 *objdb,
+	char **error_string,
+	struct list_head *uidgid_list)
+{
+	unsigned int object_service_handle;
+	char *value;
+	int uid, gid;
+	struct uidgid_item *ugi;
+
+	list_init (uidgid_list);
+
+	objdb->object_find_reset (OBJECT_PARENT_HANDLE);
+
+	while (objdb->object_find (
+		OBJECT_PARENT_HANDLE,
+		"uidgid",
+		strlen ("uidgid"),
+		&object_service_handle) == 0) {
+		uid = -1;
+		gid = -1;
+
+		if (!objdb_get_string (objdb,object_service_handle, "uid", &value)) {
+			if ((uid = uid_determine(value, error_string)) == -1)
+				return 0;
+		}
+
+		if (!objdb_get_string (objdb,object_service_handle, "gid", &value)) {
+			if ((gid = gid_determine(value, error_string)) == -1)
+				return 0;
+		}
+
+		if (uid > -1 || gid > -1) {
+			ugi = malloc (sizeof (*ugi));
+			if (ugi == NULL) {
+				*error_string = "Out of memory";
+				return 0;
+			}
+			ugi->uid = uid;
+			ugi->gid = gid;
+			list_add (&ugi->list, uidgid_list);
+		}
+	}
+
+	return 1;
+}
+
 int openais_main_config_read (
 	struct objdb_iface_ver0 *objdb,
 	char **error_string,
-	struct main_config *main_config)
+	struct main_config *main_config,
+	struct list_head *uidgid_list)
 {
 	unsigned int object_service_handle;
 	unsigned int object_logger_handle;
@@ -297,6 +378,11 @@ int openais_main_config_read (
 	if (!main_config->syslog_facility)
 		main_config->syslog_facility = LOG_DAEMON;
 
+	if (!ais_main_config_read_uidgid (objdb, &error_reason, uidgid_list)) {
+	printf("BLE\n");
+		goto parse_error;
+	}
+
 	return 0;
 
 parse_error:
diff --git a/branches/whitetank/exec/mainconfig.h b/branches/whitetank/exec/mainconfig.h
index 44d9dc7..b2b53a3 100644
--- a/branches/whitetank/exec/mainconfig.h
+++ b/branches/whitetank/exec/mainconfig.h
@@ -41,6 +41,7 @@
 #include "totempg.h"
 */
 #include "objdb.h"
+#include "../include/list.h"
 
 #ifndef MAINCONFIG_H_DEFINED
 #define MAINCONFIG_H_DEFINED
@@ -63,6 +64,16 @@ struct logger_config {
 	int mode;
 };
 
+/*
+ * Structure describing cached uidgid item
+ */
+struct uidgid_item {
+	struct list_head list;
+	int uid;
+	int gid;
+};
+
+
 struct main_config {
 	/*
 	 * logging
@@ -82,6 +93,7 @@ struct main_config {
 extern int openais_main_config_read (
 	struct objdb_iface_ver0 *objdb,
 	char **error_string,
-	struct main_config *main_config);
-	
+	struct main_config *main_config,
+	struct list_head *uidgid_list);
+
 #endif /* MAINCONFIG_H_DEFINED */
_______________________________________________
Openais mailing list
[email protected]
https://lists.linux-foundation.org/mailman/listinfo/openais

Reply via email to