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