* [ libsepol 3/6] Users
@ 2005-07-21 17:44 Ivan Gyurdiev
2005-07-21 18:15 ` Joshua Brindle
0 siblings, 1 reply; 3+ messages in thread
From: Ivan Gyurdiev @ 2005-07-21 17:44 UTC (permalink / raw)
To: selinux
[-- Attachment #1: Type: text/plain, Size: 411 bytes --]
The following patch is intended to replace
genusers.c (but not yet). It provides functions
to add, delete and load users into a policydb object.
It uses a structure (sepol_uinfo_t) as the
higher level representation for a user, and
takes out the parsing.
libsepol-2.1-users.diff
Disclaimer 1:
The role list must be NULL terminated.
Disclaimer 2:
Not sure MLS processing is correct - please
take a look.
[-- Attachment #2: libsepol-2.1-users.diff --]
[-- Type: text/x-patch, Size: 12058 bytes --]
diff -aru libsepol.work/include/sepol/users.h libsepol-2.1-users/include/sepol/users.h
--- libsepol.work/include/sepol/users.h 2005-07-04 06:37:59.000000000 -0400
+++ libsepol-2.1-users/include/sepol/users.h 2005-07-21 08:49:01.000000000 -0400
@@ -0,0 +1,53 @@
+#ifndef _SEPOL_USERS_H_
+#define _SEPOL_USERS_H_
+
+#include <sepol/policydb.h>
+#include <sys/types.h>
+
+/* High level representation of a user */
+typedef struct sepol_uinfo {
+ const char* name;
+ const char** roles;
+ const char* mls_level;
+ const char* mls_range;
+} sepol_uinfo_t;
+
+/* Clear unused users */
+extern void sepol_clear_unused_users(
+ policydb_t* policydb);
+
+/* Add/delete/load users from the policy
+ Load allows duplicates, but add does not. */
+extern int sepol_user_add(
+ policydb_t* policydb,
+ sepol_uinfo_t* user);
+
+extern int sepol_user_del(
+ policydb_t* policydb,
+ const char *username);
+
+extern int sepol_user_load(
+ policydb_t* policydb,
+ sepol_uinfo_t* user);
+
+/* Check if users or roles are valid */
+extern int sepol_user_is_valid(
+ policydb_t* policydb,
+ const char* user);
+
+extern int sepol_role_is_valid(
+ policydb_t* policydb,
+ const char* role);
+
+/* Obtain an array of all valid users/roles */
+extern int sepol_get_valid_users(
+ policydb_t* policydb,
+ char*** users,
+ size_t* nusers);
+
+extern int sepol_get_valid_roles(
+ policydb_t* policydb,
+ char*** roles,
+ size_t* nroles);
+
+#endif /* _SEPOL_USERS_H_ */
diff -aru libsepol.work/src/genusers.c libsepol-2.1-users/src/genusers.c
--- libsepol.work/src/genusers.c 2005-07-18 15:05:30.000000000 -0400
+++ libsepol-2.1-users/src/genusers.c 2005-07-20 09:42:58.000000000 -0400
@@ -30,12 +30,7 @@
}
}
-static int delusers = 0;
-
-void sepol_set_delusers(int on)
-{
- delusers = on;
-}
+extern int selinux_delusers;
#undef BADLINE
#define BADLINE() { \
@@ -382,7 +377,7 @@
goto err;
}
- if (delusers) {
+ if (selinux_delusers) {
/* Kill unused users and remap to avoid holes. */
ebitmap_init(&free_users);
kud.policydb = &policydb;
diff -aru libsepol.work/src/users.c libsepol-2.1-users/src/users.c
--- libsepol.work/src/users.c 2005-07-04 06:38:26.000000000 -0400
+++ libsepol-2.1-users/src/users.c 2005-07-21 12:18:59.000000000 -0400
@@ -0,0 +1,413 @@
+#include <stdlib.h>
+
+#include "private.h"
+#include "debug.h"
+
+#include <sepol/sepol.h>
+#include <sepol/policydb.h>
+#include <sepol/mls.h>
+#include <sepol/users.h>
+#include <sys/types.h>
+
+int selinux_delusers = 0;
+
+void sepol_set_delusers(int on) {
+ selinux_delusers = on;
+}
+
+/* Select users for removal based on whether they were defined in the
+ new users configuration. */
+static int select_user(
+ hashtab_key_t key, hashtab_datum_t datum, void *datap) {
+ user_datum_t *usrdatum = datum;
+
+ if (!usrdatum->defined)
+ return 1;
+ return 0;
+}
+
+/* Kill the user entries selected by select_user, and
+ record that their slots are free. */
+static void kill_user(
+ hashtab_key_t key,
+ hashtab_datum_t datum,
+ void *arg)
+{
+ user_datum_t *usrdatum = (user_datum_t*) datum;
+ policydb_t* policydb = (policydb_t*) arg;
+
+ /* Locations of user we're deleting, and last user */
+ int old_pos = usrdatum->value - 1;
+ int last_pos = policydb->p_users.nprim - 1;
+
+ /* Fill hole with last user/data pair */
+ if (old_pos != last_pos) {
+
+ char* last_name = policydb->p_user_val_to_name[last_pos];
+ user_datum_t* last_data =
+ policydb->user_val_to_struct[last_pos];
+
+ /* Decrement prim */
+ last_data->value--;
+
+ /* Update sid in reverse mapings */
+ policydb->p_user_val_to_name[old_pos] = last_name;
+ policydb->user_val_to_struct[old_pos] = last_data;
+ }
+
+ /* Decrement prim */
+ policydb->p_users.nprim--;
+
+ /* Free key and data */
+ if (key)
+ free(key);
+ role_set_destroy(&usrdatum->roles);
+ free(datum);
+}
+
+void sepol_clear_unused_users(policydb_t* policydb) {
+ if (selinux_delusers) {
+ hashtab_map_remove_on_error(
+ policydb->p_users.table,
+ &select_user,
+ &kill_user,
+ policydb);
+ }
+}
+
+/* Add a user to the given policydb. The user may not exist already */
+
+int sepol_user_add(policydb_t* policydb, sepol_uinfo_t* user) {
+
+ char* name = NULL;
+ user_datum_t* usrdatum;
+
+ /* See if a user exists */
+ name = strdup(user->name);
+ if (!name)
+ goto omem;
+
+ usrdatum = hashtab_search(policydb->p_users.table, name);
+
+ /* If it does, fail */
+ if (usrdatum) {
+ DEBUG(__FUNCTION__,"%s is already in policy\n", name);
+ goto err;
+ }
+
+ if (sepol_user_load(policydb, user) < 0)
+ goto err;
+
+ return STATUS_SUCCESS;
+
+ omem:
+ DEBUG(__FUNCTION__, "out of memory\n");
+
+ err:
+ DEBUG(__FUNCTION__, "could not add %s to policy\n", user->name);
+ free(name);
+ return STATUS_ERR;
+}
+
+/* Delete a user from the given policydb. This function will
+ * fail if the user does not exist. */
+
+int sepol_user_del(policydb_t* policydb, const char* username) {
+ user_datum_t* usrdatum;
+ char* name = NULL;
+
+ name = strdup(username);
+ if (!name)
+ goto omem;
+
+ /* See if such a user exists */
+ usrdatum = hashtab_search(policydb->p_users.table, name);
+
+ /* If not, fail */
+ if (usrdatum == NULL) {
+ DEBUG(__FUNCTION__, "%s does not exist in policy\n", name);
+ goto err;
+ }
+ else {
+ if ( hashtab_remove(
+ policydb->p_users.table, name,
+ &kill_user, policydb) < 0)
+ goto err;
+ }
+
+ free(name);
+ return STATUS_SUCCESS;
+
+ omem:
+ DEBUG(__FUNCTION__, "out of memory\n");
+
+ err:
+ DEBUG(__FUNCTION__, "could not remove %s from policy\n", name);
+ free(name);
+ return STATUS_ERR;
+}
+
+/* Load a user into policydb. The user may exist already, in
+ * which case the supplied data replaces the existing data. Alternatively,
+ * the user could be new. */
+
+int sepol_user_load(policydb_t* policydb, sepol_uinfo_t* user) {
+
+ /* For user data */
+ const char** tmp_role;
+ char *name = NULL, *role = NULL,
+ *mls_level = NULL, *mls_range = NULL,
+ *key = NULL;
+ user_datum_t* usrdatum = NULL;
+ role_datum_t* roldatum;
+
+ context_struct_t context;
+ unsigned bit;
+ int new = 0;
+
+ /* See if a user exists */
+ name = strdup(user->name);
+ if (!name)
+ goto omem;
+
+ usrdatum = hashtab_search(policydb->p_users.table, name);
+
+ /* If it does, we will modify it */
+ if (usrdatum) {
+ role_set_destroy(&usrdatum->roles);
+ role_set_init(&usrdatum->roles);
+ usrdatum->defined = 1;
+
+ /* Otherwise, create a new one */
+ } else {
+ usrdatum = (user_datum_t *) malloc(sizeof(user_datum_t));
+ if (!usrdatum)
+ goto omem;
+ memset(usrdatum, 0, sizeof(user_datum_t));
+ role_set_init(&usrdatum->roles);
+ usrdatum->defined = 1;
+ new = 1;
+ }
+
+ /* For every role */
+ for (tmp_role = user->roles; *tmp_role; tmp_role++) {
+ role = strdup(*tmp_role);
+ if (!role)
+ goto omem;
+
+ /* Search for the role */
+ roldatum = hashtab_search(policydb->p_roles.table, role);
+ if (!roldatum) {
+ DEBUG(__FUNCTION__, "undefined role %s for user %s\n",
+ role, name);
+ goto err;
+ }
+
+ /* Set the role and every role it dominates */
+ for (bit = ebitmap_startbit(&roldatum->dominates);
+ bit < ebitmap_length(&roldatum->dominates); bit++) {
+
+ if (ebitmap_get_bit(&roldatum->dominates, bit)) {
+ if (ebitmap_set_bit(&(usrdatum->roles.roles), bit, 1))
+ goto omem;
+ }
+ }
+
+ free(role);
+ role = NULL;
+ }
+
+ if (mls_enabled) {
+ context_init(&context);
+
+ /* MLS level */
+ if (user->mls_level == NULL) {
+ DEBUG(__FUNCTION__, "mls is enabled, but no mls "
+ "level found for user %s\n",
+ name);
+ goto err;
+ }
+
+ mls_level = strdup(user->mls_level);
+ if (!mls_level)
+ goto omem;
+
+ if (mls_context_to_sid(policydb, '$', &mls_level, &context)) {
+ DEBUG(__FUNCTION__, "invalid level %s for user %s\n",
+ mls_level, name);
+ goto err;
+ }
+ free(mls_level);
+ mls_level = NULL;
+ memcpy(&usrdatum->dfltlevel, &context.range.level[0],
+ sizeof(usrdatum->dfltlevel));
+
+ /* MLS range */
+ context_init(&context);
+ if (user->mls_range == NULL) {
+ DEBUG(__FUNCTION__, "mls is enabled, but no "
+ "mls range found for user %s\n", name);
+ goto err;
+ }
+
+ mls_range = strdup(user->mls_range);
+ if (!mls_range)
+ goto omem;
+
+ if (mls_context_to_sid(policydb, '$', &mls_range, &context)) {
+ DEBUG(__FUNCTION__, "invalid range %s for user %s\n",
+ mls_range, name);
+ goto err;
+ }
+ free(mls_range);
+ mls_range = NULL;
+ memcpy(&usrdatum->range, &context.range, sizeof(usrdatum->range));
+ }
+
+ /* If there are no errors, and this is a new user, add the user to policy */
+ if (new) {
+ key = strdup(name);
+ void *tmp_ptr;
+
+ if (!key)
+ goto omem;
+
+ /* Ensure reverse lookup array has enough space */
+ tmp_ptr = realloc(policydb->user_val_to_struct,
+ (policydb->p_users.nprim + 1) * sizeof(user_datum_t *));
+ if (!tmp_ptr)
+ goto omem;
+ policydb->user_val_to_struct = tmp_ptr;
+
+
+ tmp_ptr = realloc(policydb->sym_val_to_name[SYM_USERS],
+ (policydb->p_users.nprim + 1) * sizeof(user_datum_t *));
+ if (!tmp_ptr)
+ goto omem;
+ policydb->sym_val_to_name[SYM_USERS] = tmp_ptr;
+
+ /* Store user */
+ usrdatum->value = ++policydb->p_users.nprim;
+ if (hashtab_insert(policydb->p_users.table, key,
+ (hashtab_datum_t) usrdatum) < 0)
+ goto omem;
+
+ /* Set up reverse entry */
+ policydb->p_user_val_to_name[usrdatum->value - 1] = key;
+ policydb->user_val_to_struct[usrdatum->value - 1] = usrdatum;
+ }
+
+ free(name);
+ return STATUS_SUCCESS;
+
+ omem:
+ DEBUG(__FUNCTION__, "out of memory\n");
+
+ err:
+ DEBUG(__FUNCTION__, "could not load %s into policy\n",
+ user->name);
+ free(key);
+ free(name);
+ free(role);
+ free(mls_range);
+ free(mls_level);
+ if (new && usrdatum) {
+ role_set_destroy(&usrdatum->roles);
+ free(usrdatum);
+ }
+ return STATUS_ERR;
+}
+
+/* Check if a user is valid */
+
+int sepol_user_is_valid(policydb_t* policydb, const char* user) {
+ int status;
+ char* user_copy = strdup(user);
+ if (!user_copy) {
+ DEBUG(__FUNCTION__, "out of memory, user check failed\n");
+ return STATUS_ERR;
+ }
+
+ status = hashtab_search(policydb->p_users.table, user_copy) != NULL;
+ free(user_copy);
+ return status;
+}
+
+/* Check if a role is valid */
+
+int sepol_role_is_valid(policydb_t* policydb, const char* role) {
+ int status;
+ char* role_copy = strdup(role);
+ if (!role_copy) {
+ DEBUG(__FUNCTION__, "out of memory, role check failed\n");
+ return STATUS_ERR;
+ }
+
+ status = hashtab_search(policydb->p_roles.table, role_copy) != NULL;
+ free(role_copy);
+ return status;
+}
+
+/* Fill an array with all valid users */
+
+int sepol_get_valid_users(policydb_t* policydb, char*** users, size_t* nusers) {
+ size_t tmp_nusers = policydb->p_users.nprim;
+ char **tmp_users = (char**) malloc(tmp_nusers * sizeof(char*));
+ char **ptr;
+ size_t i;
+ if (!tmp_users)
+ goto omem;
+
+ for (i = 0; i < tmp_nusers; i++) {
+ tmp_users[i] = strdup(policydb->p_user_val_to_name[i]);
+ if (!tmp_users[i])
+ goto omem;
+ }
+
+ *nusers = tmp_nusers;
+ *users = tmp_users;
+
+ return STATUS_SUCCESS;
+
+ omem:
+ DEBUG(__FUNCTION__, "out of memory, could not "
+ "allocate list of valid users\n");
+
+ ptr = tmp_users;
+ while (ptr && *ptr)
+ free(*ptr++);
+ free(tmp_users);
+ return STATUS_ERR;
+}
+
+/* Fill an array with all valid roles */
+
+int sepol_get_valid_roles(policydb_t* policydb, char*** roles, size_t* nroles) {
+ size_t tmp_nroles = policydb->p_roles.nprim;
+ char **tmp_roles = (char**) malloc(tmp_nroles * sizeof(char*));
+ char **ptr;
+ size_t i;
+ if (!tmp_roles)
+ goto omem;
+
+ for (i =0; i < tmp_nroles; i++) {
+ tmp_roles[i] = strdup(policydb->p_role_val_to_name[i]);
+ if (!tmp_roles[i])
+ goto omem;
+ }
+
+ *nroles = tmp_nroles;
+ *roles = tmp_roles;
+
+ return STATUS_SUCCESS;
+
+ omem:
+ DEBUG(__FUNCTION__, "out of memory, could not "
+ "allocate list of valid roles\n");
+
+ ptr = tmp_roles;
+ while (ptr && *ptr)
+ free(*ptr++);
+ free(tmp_roles);
+ return STATUS_ERR;
+}
^ permalink raw reply [flat|nested] 3+ messages in thread
* Re: [ libsepol 3/6] Users
2005-07-21 17:44 [ libsepol 3/6] Users Ivan Gyurdiev
@ 2005-07-21 18:15 ` Joshua Brindle
2005-07-21 18:55 ` Ivan Gyurdiev
0 siblings, 1 reply; 3+ messages in thread
From: Joshua Brindle @ 2005-07-21 18:15 UTC (permalink / raw)
To: gyurdiev; +Cc: selinux
Ivan Gyurdiev wrote:
>The following patch is intended to replace
>genusers.c (but not yet). It provides functions
>to add, delete and load users into a policydb object.
>It uses a structure (sepol_uinfo_t) as the
>higher level representation for a user, and
>takes out the parsing.
>
>libsepol-2.1-users.diff
>
>Disclaimer 1:
>The role list must be NULL terminated.
>
>
>
The libsemanage api I'm writing right now has num_roles, IMO better than
null termination in that it's easier to make mistakes with null termination
struct semanage_user {
char *name; /* Key */
struct semanage_role **roles;
int num_roles;
struct semanage_mls *mls;
}
>Disclaimer 2:
>Not sure MLS processing is correct - please
>take a look.
>
>
I've been talking to the TCS guys while here about the right thing to do
with MLS so the libsemanage api should be correct.
--
This message was distributed to subscribers of the selinux mailing list.
If you no longer wish to subscribe, send mail to majordomo@tycho.nsa.gov with
the words "unsubscribe selinux" without quotes as the message.
^ permalink raw reply [flat|nested] 3+ messages in thread
* Re: [ libsepol 3/6] Users
2005-07-21 18:15 ` Joshua Brindle
@ 2005-07-21 18:55 ` Ivan Gyurdiev
0 siblings, 0 replies; 3+ messages in thread
From: Ivan Gyurdiev @ 2005-07-21 18:55 UTC (permalink / raw)
To: Joshua Brindle; +Cc: selinux
[-- Attachment #1: Type: text/plain, Size: 200 bytes --]
> The libsemanage api I'm writing right now has num_roles, IMO better than
> null termination in that it's easier to make mistakes with null termination
Attached is a new version with num_roles.
[-- Attachment #2: libsepol-2.1-users.diff --]
[-- Type: text/x-patch, Size: 12144 bytes --]
diff -p -aru libsepol.work/include/sepol/users.h libsepol-2.1-users/include/sepol/users.h
--- libsepol.work/include/sepol/users.h 2005-07-04 06:37:59.000000000 -0400
+++ libsepol-2.1-users/include/sepol/users.h 2005-07-21 14:51:14.000000000 -0400
@@ -0,0 +1,54 @@
+#ifndef _SEPOL_USERS_H_
+#define _SEPOL_USERS_H_
+
+#include <sepol/policydb.h>
+#include <sys/types.h>
+
+/* High level representation of a user */
+typedef struct sepol_uinfo {
+ const char* name;
+ const char** roles;
+ size_t num_roles;
+ const char* mls_level;
+ const char* mls_range;
+} sepol_uinfo_t;
+
+/* Clear unused users */
+extern void sepol_clear_unused_users(
+ policydb_t* policydb);
+
+/* Add/delete/load users from the policy
+ Load allows duplicates, but add does not. */
+extern int sepol_user_add(
+ policydb_t* policydb,
+ sepol_uinfo_t* user);
+
+extern int sepol_user_del(
+ policydb_t* policydb,
+ const char *username);
+
+extern int sepol_user_load(
+ policydb_t* policydb,
+ sepol_uinfo_t* user);
+
+/* Check if users or roles are valid */
+extern int sepol_user_is_valid(
+ policydb_t* policydb,
+ const char* user);
+
+extern int sepol_role_is_valid(
+ policydb_t* policydb,
+ const char* role);
+
+/* Obtain an array of all valid users/roles */
+extern int sepol_get_valid_users(
+ policydb_t* policydb,
+ char*** users,
+ size_t* nusers);
+
+extern int sepol_get_valid_roles(
+ policydb_t* policydb,
+ char*** roles,
+ size_t* nroles);
+
+#endif /* _SEPOL_USERS_H_ */
diff -p -aru libsepol.work/src/genusers.c libsepol-2.1-users/src/genusers.c
--- libsepol.work/src/genusers.c 2005-07-18 15:05:30.000000000 -0400
+++ libsepol-2.1-users/src/genusers.c 2005-07-20 09:42:58.000000000 -0400
@@ -30,12 +30,7 @@ void __sepol_debug_printf(const char *fm
}
}
-static int delusers = 0;
-
-void sepol_set_delusers(int on)
-{
- delusers = on;
-}
+extern int selinux_delusers;
#undef BADLINE
#define BADLINE() { \
@@ -382,7 +377,7 @@ int sepol_genusers(void *data, size_t le
goto err;
}
- if (delusers) {
+ if (selinux_delusers) {
/* Kill unused users and remap to avoid holes. */
ebitmap_init(&free_users);
kud.policydb = &policydb;
diff -p -aru libsepol.work/src/users.c libsepol-2.1-users/src/users.c
--- libsepol.work/src/users.c 2005-07-04 06:38:26.000000000 -0400
+++ libsepol-2.1-users/src/users.c 2005-07-21 14:51:22.000000000 -0400
@@ -0,0 +1,413 @@
+#include <stdlib.h>
+
+#include "private.h"
+#include "debug.h"
+
+#include <sepol/sepol.h>
+#include <sepol/policydb.h>
+#include <sepol/mls.h>
+#include <sepol/users.h>
+#include <sys/types.h>
+
+int selinux_delusers = 0;
+
+void sepol_set_delusers(int on) {
+ selinux_delusers = on;
+}
+
+/* Select users for removal based on whether they were defined in the
+ new users configuration. */
+static int select_user(
+ hashtab_key_t key, hashtab_datum_t datum, void *datap) {
+ user_datum_t *usrdatum = datum;
+
+ if (!usrdatum->defined)
+ return 1;
+ return 0;
+}
+
+/* Kill the user entries selected by select_user, and
+ record that their slots are free. */
+static void kill_user(
+ hashtab_key_t key,
+ hashtab_datum_t datum,
+ void *arg)
+{
+ user_datum_t *usrdatum = (user_datum_t*) datum;
+ policydb_t* policydb = (policydb_t*) arg;
+
+ /* Locations of user we're deleting, and last user */
+ int old_pos = usrdatum->value - 1;
+ int last_pos = policydb->p_users.nprim - 1;
+
+ /* Fill hole with last user/data pair */
+ if (old_pos != last_pos) {
+
+ char* last_name = policydb->p_user_val_to_name[last_pos];
+ user_datum_t* last_data =
+ policydb->user_val_to_struct[last_pos];
+
+ /* Decrement prim */
+ last_data->value--;
+
+ /* Update sid in reverse mapings */
+ policydb->p_user_val_to_name[old_pos] = last_name;
+ policydb->user_val_to_struct[old_pos] = last_data;
+ }
+
+ /* Decrement prim */
+ policydb->p_users.nprim--;
+
+ /* Free key and data */
+ if (key)
+ free(key);
+ role_set_destroy(&usrdatum->roles);
+ free(datum);
+}
+
+void sepol_clear_unused_users(policydb_t* policydb) {
+ if (selinux_delusers) {
+ hashtab_map_remove_on_error(
+ policydb->p_users.table,
+ &select_user,
+ &kill_user,
+ policydb);
+ }
+}
+
+/* Add a user to the given policydb. The user may not exist already */
+
+int sepol_user_add(policydb_t* policydb, sepol_uinfo_t* user) {
+
+ char* name = NULL;
+ user_datum_t* usrdatum;
+
+ /* See if a user exists */
+ name = strdup(user->name);
+ if (!name)
+ goto omem;
+
+ usrdatum = hashtab_search(policydb->p_users.table, name);
+
+ /* If it does, fail */
+ if (usrdatum) {
+ DEBUG(__FUNCTION__,"%s is already in policy\n", name);
+ goto err;
+ }
+
+ if (sepol_user_load(policydb, user) < 0)
+ goto err;
+
+ return STATUS_SUCCESS;
+
+ omem:
+ DEBUG(__FUNCTION__, "out of memory\n");
+
+ err:
+ DEBUG(__FUNCTION__, "could not add %s to policy\n", user->name);
+ free(name);
+ return STATUS_ERR;
+}
+
+/* Delete a user from the given policydb. This function will
+ * fail if the user does not exist. */
+
+int sepol_user_del(policydb_t* policydb, const char* username) {
+ user_datum_t* usrdatum;
+ char* name = NULL;
+
+ name = strdup(username);
+ if (!name)
+ goto omem;
+
+ /* See if such a user exists */
+ usrdatum = hashtab_search(policydb->p_users.table, name);
+
+ /* If not, fail */
+ if (usrdatum == NULL) {
+ DEBUG(__FUNCTION__, "%s does not exist in policy\n", name);
+ goto err;
+ }
+ else {
+ if ( hashtab_remove(
+ policydb->p_users.table, name,
+ &kill_user, policydb) < 0)
+ goto err;
+ }
+
+ free(name);
+ return STATUS_SUCCESS;
+
+ omem:
+ DEBUG(__FUNCTION__, "out of memory\n");
+
+ err:
+ DEBUG(__FUNCTION__, "could not remove %s from policy\n", name);
+ free(name);
+ return STATUS_ERR;
+}
+
+/* Load a user into policydb. The user may exist already, in
+ * which case the supplied data replaces the existing data. Alternatively,
+ * the user could be new. */
+
+int sepol_user_load(policydb_t* policydb, sepol_uinfo_t* user) {
+
+ /* For user data */
+ char *name = NULL, *role = NULL,
+ *mls_level = NULL, *mls_range = NULL,
+ *key = NULL;
+ user_datum_t* usrdatum = NULL;
+ role_datum_t* roldatum;
+ int i;
+
+ context_struct_t context;
+ unsigned bit;
+ int new = 0;
+
+ /* See if a user exists */
+ name = strdup(user->name);
+ if (!name)
+ goto omem;
+
+ usrdatum = hashtab_search(policydb->p_users.table, name);
+
+ /* If it does, we will modify it */
+ if (usrdatum) {
+ role_set_destroy(&usrdatum->roles);
+ role_set_init(&usrdatum->roles);
+ usrdatum->defined = 1;
+
+ /* Otherwise, create a new one */
+ } else {
+ usrdatum = (user_datum_t *) malloc(sizeof(user_datum_t));
+ if (!usrdatum)
+ goto omem;
+ memset(usrdatum, 0, sizeof(user_datum_t));
+ role_set_init(&usrdatum->roles);
+ usrdatum->defined = 1;
+ new = 1;
+ }
+
+ /* For every role */
+ for (i = 0; i < user->num_roles; i++) {
+ role = strdup(user->roles[i]);
+ if (!role)
+ goto omem;
+
+ /* Search for the role */
+ roldatum = hashtab_search(policydb->p_roles.table, role);
+ if (!roldatum) {
+ DEBUG(__FUNCTION__, "undefined role %s for user %s\n",
+ role, name);
+ goto err;
+ }
+
+ /* Set the role and every role it dominates */
+ for (bit = ebitmap_startbit(&roldatum->dominates);
+ bit < ebitmap_length(&roldatum->dominates); bit++) {
+
+ if (ebitmap_get_bit(&roldatum->dominates, bit)) {
+ if (ebitmap_set_bit(&(usrdatum->roles.roles), bit, 1))
+ goto omem;
+ }
+ }
+
+ free(role);
+ role = NULL;
+ }
+
+ if (mls_enabled) {
+ context_init(&context);
+
+ /* MLS level */
+ if (user->mls_level == NULL) {
+ DEBUG(__FUNCTION__, "mls is enabled, but no mls "
+ "level found for user %s\n",
+ name);
+ goto err;
+ }
+
+ mls_level = strdup(user->mls_level);
+ if (!mls_level)
+ goto omem;
+
+ if (mls_context_to_sid(policydb, '$', &mls_level, &context)) {
+ DEBUG(__FUNCTION__, "invalid level %s for user %s\n",
+ mls_level, name);
+ goto err;
+ }
+ free(mls_level);
+ mls_level = NULL;
+ memcpy(&usrdatum->dfltlevel, &context.range.level[0],
+ sizeof(usrdatum->dfltlevel));
+
+ /* MLS range */
+ context_init(&context);
+ if (user->mls_range == NULL) {
+ DEBUG(__FUNCTION__, "mls is enabled, but no "
+ "mls range found for user %s\n", name);
+ goto err;
+ }
+
+ mls_range = strdup(user->mls_range);
+ if (!mls_range)
+ goto omem;
+
+ if (mls_context_to_sid(policydb, '$', &mls_range, &context)) {
+ DEBUG(__FUNCTION__, "invalid range %s for user %s\n",
+ mls_range, name);
+ goto err;
+ }
+ free(mls_range);
+ mls_range = NULL;
+ memcpy(&usrdatum->range, &context.range, sizeof(usrdatum->range));
+ }
+
+ /* If there are no errors, and this is a new user, add the user to policy */
+ if (new) {
+ key = strdup(name);
+ void *tmp_ptr;
+
+ if (!key)
+ goto omem;
+
+ /* Ensure reverse lookup array has enough space */
+ tmp_ptr = realloc(policydb->user_val_to_struct,
+ (policydb->p_users.nprim + 1) * sizeof(user_datum_t *));
+ if (!tmp_ptr)
+ goto omem;
+ policydb->user_val_to_struct = tmp_ptr;
+
+
+ tmp_ptr = realloc(policydb->sym_val_to_name[SYM_USERS],
+ (policydb->p_users.nprim + 1) * sizeof(user_datum_t *));
+ if (!tmp_ptr)
+ goto omem;
+ policydb->sym_val_to_name[SYM_USERS] = tmp_ptr;
+
+ /* Store user */
+ usrdatum->value = ++policydb->p_users.nprim;
+ if (hashtab_insert(policydb->p_users.table, key,
+ (hashtab_datum_t) usrdatum) < 0)
+ goto omem;
+
+ /* Set up reverse entry */
+ policydb->p_user_val_to_name[usrdatum->value - 1] = key;
+ policydb->user_val_to_struct[usrdatum->value - 1] = usrdatum;
+ }
+
+ free(name);
+ return STATUS_SUCCESS;
+
+ omem:
+ DEBUG(__FUNCTION__, "out of memory\n");
+
+ err:
+ DEBUG(__FUNCTION__, "could not load %s into policy\n",
+ user->name);
+ free(key);
+ free(name);
+ free(role);
+ free(mls_range);
+ free(mls_level);
+ if (new && usrdatum) {
+ role_set_destroy(&usrdatum->roles);
+ free(usrdatum);
+ }
+ return STATUS_ERR;
+}
+
+/* Check if a user is valid */
+
+int sepol_user_is_valid(policydb_t* policydb, const char* user) {
+ int status;
+ char* user_copy = strdup(user);
+ if (!user_copy) {
+ DEBUG(__FUNCTION__, "out of memory, user check failed\n");
+ return STATUS_ERR;
+ }
+
+ status = hashtab_search(policydb->p_users.table, user_copy) != NULL;
+ free(user_copy);
+ return status;
+}
+
+/* Check if a role is valid */
+
+int sepol_role_is_valid(policydb_t* policydb, const char* role) {
+ int status;
+ char* role_copy = strdup(role);
+ if (!role_copy) {
+ DEBUG(__FUNCTION__, "out of memory, role check failed\n");
+ return STATUS_ERR;
+ }
+
+ status = hashtab_search(policydb->p_roles.table, role_copy) != NULL;
+ free(role_copy);
+ return status;
+}
+
+/* Fill an array with all valid users */
+
+int sepol_get_valid_users(policydb_t* policydb, char*** users, size_t* nusers) {
+ size_t tmp_nusers = policydb->p_users.nprim;
+ char **tmp_users = (char**) malloc(tmp_nusers * sizeof(char*));
+ char **ptr;
+ size_t i;
+ if (!tmp_users)
+ goto omem;
+
+ for (i = 0; i < tmp_nusers; i++) {
+ tmp_users[i] = strdup(policydb->p_user_val_to_name[i]);
+ if (!tmp_users[i])
+ goto omem;
+ }
+
+ *nusers = tmp_nusers;
+ *users = tmp_users;
+
+ return STATUS_SUCCESS;
+
+ omem:
+ DEBUG(__FUNCTION__, "out of memory, could not "
+ "allocate list of valid users\n");
+
+ ptr = tmp_users;
+ while (ptr && *ptr)
+ free(*ptr++);
+ free(tmp_users);
+ return STATUS_ERR;
+}
+
+/* Fill an array with all valid roles */
+
+int sepol_get_valid_roles(policydb_t* policydb, char*** roles, size_t* nroles) {
+ size_t tmp_nroles = policydb->p_roles.nprim;
+ char **tmp_roles = (char**) malloc(tmp_nroles * sizeof(char*));
+ char **ptr;
+ size_t i;
+ if (!tmp_roles)
+ goto omem;
+
+ for (i =0; i < tmp_nroles; i++) {
+ tmp_roles[i] = strdup(policydb->p_role_val_to_name[i]);
+ if (!tmp_roles[i])
+ goto omem;
+ }
+
+ *nroles = tmp_nroles;
+ *roles = tmp_roles;
+
+ return STATUS_SUCCESS;
+
+ omem:
+ DEBUG(__FUNCTION__, "out of memory, could not "
+ "allocate list of valid roles\n");
+
+ ptr = tmp_roles;
+ while (ptr && *ptr)
+ free(*ptr++);
+ free(tmp_roles);
+ return STATUS_ERR;
+}
^ permalink raw reply [flat|nested] 3+ messages in thread
end of thread, other threads:[~2005-07-21 19:02 UTC | newest]
Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2005-07-21 17:44 [ libsepol 3/6] Users Ivan Gyurdiev
2005-07-21 18:15 ` Joshua Brindle
2005-07-21 18:55 ` Ivan Gyurdiev
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.