On Wed, 2019-06-19 at 13:20 -0400, Stephen Smalley wrote: > On 6/4/19 1:08 PM, Richard Haines wrote: > > Remove legacy local boolean and user code, and to preserve API/ABI > > compatibility the following functions int values should be set to > > '0' > > as they are no longer used: > > selinux_mkload_policy(int preservebools) > > security_set_boolean_list(.... int permanent) > > and the following are now no-op: > > security_load_booleans(char *path) - return '0' > > selinux_booleans_path(void) - return NULL > > selinux_users_path(void) - return NULL > > > > Also "SETLOCALDEFS" removed from SELinux config file and code. > > > > Signed-off-by: Richard Haines <richard_c_haines@xxxxxxxxxxxxxx> > > --- > > libselinux/include/selinux/selinux.h | 18 +- > > libselinux/src/booleans.c | 226 +------------- > > libselinux/src/file_path_suffixes.h | 2 - > > libselinux/src/load_policy.c | 100 +----- > > libselinux/src/selinux_config.c | 59 ++-- > > libselinux/src/selinux_internal.h | 1 - > > libsepol/include/sepol/booleans.h | 18 -- > > libsepol/include/sepol/policydb/services.h | 6 - > > libsepol/include/sepol/users.h | 17 - > > libsepol/src/genbools.c | 279 ---------------- > > - > > libsepol/src/genusers.c | 343 ---------------- > > ----- > > libsepol/src/libsepol.map.in | 4 +- > > 12 files changed, 46 insertions(+), 1027 deletions(-) > > delete mode 100644 libsepol/src/genbools.c > > delete mode 100644 libsepol/src/genusers.c > > > > diff --git a/libselinux/include/selinux/selinux.h > > b/libselinux/include/selinux/selinux.h > > index f54f236b..10ecdf99 100644 > > --- a/libselinux/include/selinux/selinux.h > > +++ b/libselinux/include/selinux/selinux.h > > @@ -286,11 +286,7 @@ extern int > > security_get_initial_context_raw(const char *name, > > * manipulating it as needed for current boolean settings and/or > > local > > * definitions, and then calling security_load_policy to load it. > > * > > - * 'preservebools' is a boolean flag indicating whether current > > - * policy boolean values should be preserved into the new policy > > (if 1) > > - * or reset to the saved policy settings (if 0). The former case > > is the > > - * default for policy reloads, while the latter case is an option > > for policy > > - * reloads but is primarily for the initial policy load. > > + * 'preservebools' is no longer supported, set to 0. > > */ > > extern int selinux_mkload_policy(int preservebools); > > > > @@ -316,13 +312,15 @@ typedef struct { > > char *name; > > int value; > > } SELboolean; > > -/* save a list of booleans in a single transaction. */ > > +/* save a list of booleans in a single transaction. 'permanent' is > > no > > + * longer supported, set to 0. > > + */ > > extern int security_set_boolean_list(size_t boolcnt, > > SELboolean * boollist, int > > permanent); > > > > -/* Load policy boolean settings. > > - Path may be NULL, in which case the booleans are loaded from > > - the active policy boolean configuration file. */ > > +/* Load policy boolean settings. Deprecated as local policy > > booleans no > > + * longer supported. Will always return 0. > > + */ > > extern int security_load_booleans(char *path); > > > > /* Check the validity of a security context. */ > > @@ -569,8 +567,10 @@ extern const char > > *selinux_systemd_contexts_path(void); > > extern const char *selinux_contexts_path(void); > > extern const char *selinux_securetty_types_path(void); > > extern const char *selinux_booleans_subs_path(void); > > +/* Deprecated as local policy booleans no longer supported. > > Returns NULL */ > > extern const char *selinux_booleans_path(void); > > extern const char *selinux_customizable_types_path(void); > > +/* Deprecated as policy ./users no longer supported. Returns NULL > > */ > > extern const char *selinux_users_path(void); > > extern const char *selinux_usersconf_path(void); > > extern const char *selinux_translations_path(void); > > diff --git a/libselinux/src/booleans.c b/libselinux/src/booleans.c > > index ab1e0754..93c9e1f3 100644 > > --- a/libselinux/src/booleans.c > > +++ b/libselinux/src/booleans.c > > @@ -322,175 +322,6 @@ int security_commit_booleans(void) > > return -1; > > } > > > > -static char *strtrim(char *dest, char *source, int size) > > -{ > > - int i = 0; > > - char *ptr = source; > > - i = 0; > > - while (isspace(*ptr) && i < size) { > > - ptr++; > > - i++; > > - } > > - strncpy(dest, ptr, size); > > - for (i = strlen(dest) - 1; i > 0; i--) { > > - if (!isspace(dest[i])) > > - break; > > - } > > - dest[i + 1] = '\0'; > > - return dest; > > -} > > -static int process_boolean(char *buffer, char *name, int namesize, > > int *val) > > -{ > > - char name1[BUFSIZ]; > > - char *ptr = NULL; > > - char *tok; > > - > > - /* Skip spaces */ > > - while (isspace(buffer[0])) > > - buffer++; > > - /* Ignore comments */ > > - if (buffer[0] == '#') > > - return 0; > > - > > - tok = strtok_r(buffer, "=", &ptr); > > - if (!tok) { > > - errno = EINVAL; > > - return -1; > > - } > > - strncpy(name1, tok, BUFSIZ - 1); > > - strtrim(name, name1, namesize - 1); > > - > > - tok = strtok_r(NULL, "\0", &ptr); > > - if (!tok) { > > - errno = EINVAL; > > - return -1; > > - } > > - > > - while (isspace(*tok)) > > - tok++; > > - > > - *val = -1; > > - if (isdigit(tok[0])) > > - *val = atoi(tok); > > - else if (!strncasecmp(tok, "true", sizeof("true") - 1)) > > - *val = 1; > > - else if (!strncasecmp(tok, "false", sizeof("false") - 1)) > > - *val = 0; > > - if (*val != 0 && *val != 1) { > > - errno = EINVAL; > > - return -1; > > - } > > - return 1; > > -} > > -static int save_booleans(size_t boolcnt, SELboolean * boollist) > > -{ > > - ssize_t len; > > - size_t i; > > - char outbuf[BUFSIZ]; > > - char *inbuf = NULL; > > - > > - /* Open file */ > > - const char *bool_file = selinux_booleans_path(); > > - char local_bool_file[PATH_MAX]; > > - char tmp_bool_file[PATH_MAX]; > > - FILE *boolf; > > - int fd; > > - int *used = (int *)malloc(sizeof(int) * boolcnt); > > - if (!used) { > > - return -1; > > - } > > - /* zero out used field */ > > - for (i = 0; i < boolcnt; i++) > > - used[i] = 0; > > - > > - snprintf(tmp_bool_file, sizeof(tmp_bool_file), "%s.XXXXXX", > > bool_file); > > - fd = mkstemp(tmp_bool_file); > > - if (fd < 0) { > > - free(used); > > - return -1; > > - } > > - > > - snprintf(local_bool_file, sizeof(local_bool_file), "%s.local", > > - bool_file); > > - boolf = fopen(local_bool_file, "re"); > > - if (boolf != NULL) { > > - ssize_t ret; > > - size_t size = 0; > > - int val; > > - char boolname[BUFSIZ-3]; > > - char *buffer; > > - inbuf = NULL; > > - __fsetlocking(boolf, FSETLOCKING_BYCALLER); > > - while ((len = getline(&inbuf, &size, boolf)) > 0) { > > - buffer = strdup(inbuf); > > - if (!buffer) > > - goto close_remove_fail; > > - ret = > > - process_boolean(inbuf, boolname, > > sizeof(boolname), > > - &val); > > - if (ret != 1) { > > - ret = write(fd, buffer, len); > > - free(buffer); > > - if (ret != len) > > - goto close_remove_fail; > > - } else { > > - free(buffer); > > - for (i = 0; i < boolcnt; i++) { > > - if (strcmp(boollist[i].name, > > boolname) > > - == 0) { > > - snprintf(outbuf, > > sizeof(outbuf), > > - "%s=%d\n", > > boolname, > > - boollist[i].va > > lue); > > - len = strlen(outbuf); > > - used[i] = 1; > > - if (write(fd, outbuf, > > len) != > > - len) > > - goto > > close_remove_fail; > > - else > > - break; > > - } > > - } > > - if (i == boolcnt) { > > - val = !!val; > > - snprintf(outbuf, > > sizeof(outbuf), > > - "%s=%d\n", boolname, > > val); > > - len = strlen(outbuf); > > - if (write(fd, outbuf, len) != > > len) > > - goto close_remove_fail; > > - } > > - } > > - free(inbuf); > > - inbuf = NULL; > > - } > > - fclose(boolf); > > - } > > - > > - for (i = 0; i < boolcnt; i++) { > > - if (used[i] == 0) { > > - snprintf(outbuf, sizeof(outbuf), "%s=%d\n", > > - boollist[i].name, boollist[i].value); > > - len = strlen(outbuf); > > - if (write(fd, outbuf, len) != len) { > > - close_remove_fail: > > - free(inbuf); > > - close(fd); > > - remove_fail: > > - unlink(tmp_bool_file); > > - free(used); > > - return -1; > > - } > > - } > > - > > - } > > - if (fchmod(fd, S_IRUSR | S_IWUSR) != 0) > > - goto close_remove_fail; > > - close(fd); > > - if (rename(tmp_bool_file, local_bool_file) != 0) > > - goto remove_fail; > > - > > - free(used); > > - return 0; > > -} > > static void rollback(SELboolean * boollist, int end) > > { > > int i; > > @@ -502,7 +333,7 @@ static void rollback(SELboolean * boollist, int > > end) > > } > > > > int security_set_boolean_list(size_t boolcnt, SELboolean * > > boollist, > > - int permanent) > > + int permanent __attribute__((unused))) > > { > > > > size_t i; > > @@ -519,62 +350,13 @@ int security_set_boolean_list(size_t boolcnt, > > SELboolean * boollist, > > return -1; > > } > > > > - if (permanent) > > - return save_booleans(boolcnt, boollist); > > - > > Optionally, return an error here in order to indicate that this > isn't > supported? Will fix to return error. > > > return 0; > > } > > -int security_load_booleans(char *path) > > -{ > > - FILE *boolf; > > - char *inbuf; > > - char localbools[BUFSIZ]; > > - size_t len = 0, errors = 0; > > - int val; > > - char name[BUFSIZ]; > > - > > - boolf = fopen(path ? path : selinux_booleans_path(), "re"); > > - if (boolf == NULL) > > - goto localbool; > > - > > - __fsetlocking(boolf, FSETLOCKING_BYCALLER); > > - while (getline(&inbuf, &len, boolf) > 0) { > > - int ret = process_boolean(inbuf, name, sizeof(name), > > &val); > > - if (ret == -1) > > - errors++; > > - if (ret == 1) > > - if (security_set_boolean(name, val) < 0) { > > - errors++; > > - } > > - } > > - fclose(boolf); > > - localbool: > > - snprintf(localbools, sizeof(localbools), "%s.local", > > - (path ? path : selinux_booleans_path())); > > - boolf = fopen(localbools, "re"); > > - > > - if (boolf != NULL) { > > - int ret; > > - __fsetlocking(boolf, FSETLOCKING_BYCALLER); > > - while (getline(&inbuf, &len, boolf) > 0) { > > - ret = process_boolean(inbuf, name, > > sizeof(name), &val); > > - if (ret == -1) > > - errors++; > > - if (ret == 1) > > - if (security_set_boolean(name, val) < > > 0) { > > - errors++; > > - } > > - } > > - fclose(boolf); > > - } > > - if (security_commit_booleans() < 0) > > - return -1; > > > > - if (errors) > > - errno = EINVAL; > > - return errors ? -1 : 0; > > +int security_load_booleans(char *path __attribute__((unused))) > > +{ > > + return 0; > > } > > Ditto? Will fix to return error > > > - > > #else > > > > #include <stdlib.h> > > diff --git a/libselinux/src/file_path_suffixes.h > > b/libselinux/src/file_path_suffixes.h > > index 2d3ca497..7ee27bb5 100644 > > --- a/libselinux/src/file_path_suffixes.h > > +++ b/libselinux/src/file_path_suffixes.h > > @@ -8,11 +8,9 @@ S_(BINPOLICY, "/policy/policy") > > S_(FAILSAFE_CONTEXT, "/contexts/failsafe_context") > > S_(DEFAULT_TYPE, "/contexts/default_type") > > S_(SECURETTY_TYPES, "/contexts/securetty_types") > > - S_(BOOLEANS, "/booleans") > > S_(MEDIA_CONTEXTS, "/contexts/files/media") > > S_(REMOVABLE_CONTEXT, "/contexts/removable_context") > > S_(CUSTOMIZABLE_TYPES, "/contexts/customizable_types") > > - S_(USERS_DIR, "/users/") > > Only concern is if there are any external users of the functions > that > return these paths that will go boom if they get NULL > back. Probably > not but might want to check. I checked the selinux code, however as I cannot check all other code. So how about I leave these in, and remove the man page entries. > > > S_(SEUSERS, "/seusers") > > S_(TRANSLATIONS, "/setrans.conf") > > S_(NETFILTER_CONTEXTS, "/contexts/netfilter_contexts") > > diff --git a/libselinux/src/load_policy.c > > b/libselinux/src/load_policy.c > > index 20052beb..9e75292d 100644 > > --- a/libselinux/src/load_policy.c > > +++ b/libselinux/src/load_policy.c > > @@ -48,22 +48,18 @@ int security_load_policy(void *data, size_t > > len) > > hidden_def(security_load_policy) > > > > #ifndef ANDROID > > -int load_setlocaldefs hidden = 1; > > - > > #undef max > > #define max(a, b) (((a) > (b)) ? (a) : (b)) > > > > -int selinux_mkload_policy(int preservebools) > > +int selinux_mkload_policy(int preservebools > > __attribute__((unused))) > > { > > int kernvers = security_policyvers(); > > int maxvers = kernvers, minvers = DEFAULT_POLICY_VERSION, vers; > > - int setlocaldefs = load_setlocaldefs; > > char path[PATH_MAX]; > > struct stat sb; > > - struct utsname uts; > > size_t size; > > void *map, *data; > > - int fd, rc = -1, prot; > > + int fd, rc = -1; > > sepol_policydb_t *policydb; > > sepol_policy_file_t *pf; > > int usesepol = 0; > > @@ -77,9 +73,6 @@ int selinux_mkload_policy(int preservebools) > > int (*policydb_read)(sepol_policydb_t *, sepol_policy_file_t *) > > = NULL; > > int (*policydb_set_vers)(sepol_policydb_t *, unsigned int) = > > NULL; > > int (*policydb_to_image)(sepol_handle_t *, sepol_policydb_t *, > > void **, size_t *) = NULL; > > - int (*genbools_array)(void *data, size_t len, char **names, int > > *values, int nel) = NULL; > > - int (*genusers)(void *data, size_t len, const char *usersdir, > > void **newdata, size_t * newlen) = NULL; > > - int (*genbools)(void *data, size_t len, const char *boolpath) = > > NULL; > > > > #ifdef SHARED > > char *errormsg = NULL; > > @@ -110,13 +103,6 @@ int selinux_mkload_policy(int preservebools) > > DLERR(); > > policydb_to_image = dlsym(libsepolh, > > "sepol_policydb_to_image"); > > DLERR(); > > - genbools_array = dlsym(libsepolh, > > "sepol_genbools_array"); > > - DLERR(); > > - genusers = dlsym(libsepolh, "sepol_genusers"); > > - DLERR(); > > - genbools = dlsym(libsepolh, "sepol_genbools"); > > - DLERR(); > > - > > #undef DLERR > > } > > #else > > @@ -131,42 +117,11 @@ int selinux_mkload_policy(int preservebools) > > policydb_read = sepol_policydb_read; > > policydb_set_vers = sepol_policydb_set_vers; > > policydb_to_image = sepol_policydb_to_image; > > - genbools_array = sepol_genbools_array; > > - genusers = sepol_genusers; > > - genbools = sepol_genbools; > > - > > #endif > > > > - /* > > - * Check whether we need to support local boolean and user > > definitions. > > - */ > > - if (setlocaldefs) { > > - if (access(selinux_booleans_path(), F_OK) == 0) > > - goto checkbool; > > - snprintf(path, sizeof path, "%s.local", > > selinux_booleans_path()); > > - if (access(path, F_OK) == 0) > > - goto checkbool; > > - snprintf(path, sizeof path, "%s/local.users", > > selinux_users_path()); > > - if (access(path, F_OK) == 0) > > - goto checkbool; > > - /* No local definition files, so disable setlocaldefs. > > */ > > - setlocaldefs = 0; > > - } > > - > > -checkbool: > > - /* > > - * As of Linux 2.6.22, the kernel preserves boolean > > - * values across a reload, so we do not need to > > - * preserve them in userspace. > > - */ > > - if (preservebools && uname(&uts) == 0 && > > strverscmp(uts.release, "2.6.22") >= 0) > > - preservebools = 0; > > - > > if (usesepol) { > > - maxvers = vers_max(); > > + maxvers = max(kernvers, vers_max()); > > minvers = vers_min(); > > - if (!setlocaldefs && !preservebools) > > - maxvers = max(kernvers, maxvers); > > } > > > > vers = maxvers; > > @@ -195,12 +150,8 @@ checkbool: > > goto close; > > } > > > > - prot = PROT_READ; > > - if (setlocaldefs || preservebools) > > - prot |= PROT_WRITE; > > - > > size = sb.st_size; > > - data = map = mmap(NULL, size, prot, MAP_PRIVATE, fd, 0); > > + data = map = mmap(NULL, size, PROT_READ, MAP_PRIVATE, fd, 0); > > if (map == MAP_FAILED) { > > fprintf(stderr, > > "SELinux: Could not map policy file > > %s: %s\n", > > @@ -239,49 +190,6 @@ checkbool: > > policydb_free(policydb); > > } > > > > - if (usesepol) { > > - if (setlocaldefs) { > > - void *olddata = data; > > - size_t oldsize = size; > > - rc = genusers(olddata, oldsize, > > selinux_users_path(), > > - &data, &size); > > - if (rc < 0) { > > - /* Fall back to the prior image if > > genusers failed. */ > > - data = olddata; > > - size = oldsize; > > - rc = 0; > > - } else { > > - if (olddata != map) > > - free(olddata); > > - } > > - } > > - > > - if (preservebools) { > > - int *values, len, i; > > - char **names; > > - rc = security_get_boolean_names(&names, &len); > > - if (!rc) { > > - values = malloc(sizeof(int) * len); > > - if (!values) { > > - free(names); > > - goto unmap; > > - } > > - for (i = 0; i < len; i++) > > - values[i] = > > - security_get_boolean_ac > > tive(names[i]); > > - (void)genbools_array(data, size, names, > > values, > > - len); > > - free(values); > > - for (i = 0; i < len; i++) > > - free(names[i]); > > - free(names); > > - } > > - } else if (setlocaldefs) { > > - (void)genbools(data, size, > > selinux_booleans_path()); > > - } > > - } > > - > > - > > rc = security_load_policy(data, size); > > > > if (rc) > > diff --git a/libselinux/src/selinux_config.c > > b/libselinux/src/selinux_config.c > > index b06cb63b..272f48b8 100644 > > --- a/libselinux/src/selinux_config.c > > +++ b/libselinux/src/selinux_config.c > > @@ -16,7 +16,6 @@ > > #define SELINUXDEFAULT "targeted" > > #define SELINUXTYPETAG "SELINUXTYPE=" > > #define SELINUXTAG "SELINUX=" > > -#define SETLOCALDEFS "SETLOCALDEFS=" > > #define REQUIRESEUSERS "REQUIRESEUSERS=" > > > > /* Indices for file paths arrays. */ > > @@ -28,31 +27,29 @@ > > #define USER_CONTEXTS 5 > > #define FAILSAFE_CONTEXT 6 > > #define DEFAULT_TYPE 7 > > -#define BOOLEANS 8 > > -#define MEDIA_CONTEXTS 9 > > -#define REMOVABLE_CONTEXT 10 > > -#define CUSTOMIZABLE_TYPES 11 > > -#define USERS_DIR 12 > > -#define SEUSERS 13 > > -#define TRANSLATIONS 14 > > -#define NETFILTER_CONTEXTS 15 > > -#define FILE_CONTEXTS_HOMEDIR 16 > > -#define FILE_CONTEXTS_LOCAL 17 > > -#define SECURETTY_TYPES 18 > > -#define X_CONTEXTS 19 > > -#define COLORS 20 > > -#define VIRTUAL_DOMAIN 21 > > -#define VIRTUAL_IMAGE 22 > > -#define FILE_CONTEXT_SUBS 23 > > -#define SEPGSQL_CONTEXTS 24 > > -#define FILE_CONTEXT_SUBS_DIST 25 > > -#define LXC_CONTEXTS 26 > > -#define BOOLEAN_SUBS 27 > > -#define OPENSSH_CONTEXTS 28 > > -#define SYSTEMD_CONTEXTS 29 > > -#define SNAPPERD_CONTEXTS 30 > > -#define OPENRC_CONTEXTS 31 > > -#define NEL 32 > > +#define MEDIA_CONTEXTS 8 > > +#define REMOVABLE_CONTEXT 9 > > +#define CUSTOMIZABLE_TYPES 10 > > +#define SEUSERS 11 > > +#define TRANSLATIONS 12 > > +#define NETFILTER_CONTEXTS 13 > > +#define FILE_CONTEXTS_HOMEDIR 14 > > +#define FILE_CONTEXTS_LOCAL 15 > > +#define SECURETTY_TYPES 16 > > +#define X_CONTEXTS 17 > > +#define COLORS 18 > > +#define VIRTUAL_DOMAIN 19 > > +#define VIRTUAL_IMAGE 20 > > +#define FILE_CONTEXT_SUBS 21 > > +#define SEPGSQL_CONTEXTS 22 > > +#define FILE_CONTEXT_SUBS_DIST 23 > > +#define LXC_CONTEXTS 24 > > +#define BOOLEAN_SUBS 25 > > +#define OPENSSH_CONTEXTS 26 > > +#define SYSTEMD_CONTEXTS 27 > > +#define SNAPPERD_CONTEXTS 28 > > +#define OPENRC_CONTEXTS 29 > > +#define NEL 30 > > > > /* Part of one-time lazy init */ > > static pthread_once_t once = PTHREAD_ONCE_INIT; > > @@ -192,10 +189,6 @@ static void init_selinux_config(void) > > } > > free(type); > > continue; > > - } else if (!strncmp(buf_p, SETLOCALDEFS, > > - sizeof(SETLOCALDEFS) - 1)) > > { > > - value = buf_p + sizeof(SETLOCALDEFS) - > > 1; > > - intptr = &load_setlocaldefs; > > } else if (!strncmp(buf_p, REQUIRESEUSERS, > > sizeof(REQUIRESEUSERS) - > > 1)) { > > value = buf_p + sizeof(REQUIRESEUSERS) > > - 1; > > @@ -410,16 +403,18 @@ const char *selinux_user_contexts_path(void) > > > > hidden_def(selinux_user_contexts_path) > > > > +/* Deprecated as local policy booleans no longer supported. */ > > const char *selinux_booleans_path(void) > > { > > - return get_path(BOOLEANS); > > + return NULL; > > } > > > > hidden_def(selinux_booleans_path) > > > > +/* Deprecated as no longer supported. */ > > const char *selinux_users_path(void) > > { > > - return get_path(USERS_DIR); > > + return NULL; > > } > > Just want to make sure we don't make anything crash by not returning > a > string here. As mentioned above, I could just leave these and delete man page entries. > > > > > hidden_def(selinux_users_path) > > diff --git a/libselinux/src/selinux_internal.h > > b/libselinux/src/selinux_internal.h > > index acd59c7c..8b4bed2f 100644 > > --- a/libselinux/src/selinux_internal.h > > +++ b/libselinux/src/selinux_internal.h > > @@ -110,7 +110,6 @@ hidden_proto(selinux_reset_config); > > > > hidden void flush_class_cache(void); > > > > -extern int load_setlocaldefs hidden; > > extern int require_seusers hidden; > > extern int selinux_page_size hidden; > > > > diff --git a/libsepol/include/sepol/booleans.h > > b/libsepol/include/sepol/booleans.h > > index 2966903d..25229057 100644 > > --- a/libsepol/include/sepol/booleans.h > > +++ b/libsepol/include/sepol/booleans.h > > @@ -10,24 +10,6 @@ > > extern "C" { > > #endif > > > > -/*--------------compatibility--------------*/ > > - > > -/* Given an existing binary policy (starting at 'data', with > > length 'len') > > - and a boolean configuration file named by 'boolpath', rewrite > > the binary > > - policy for the boolean settings in the boolean configuration > > file. > > - The binary policy is rewritten in place in memory. > > - Returns 0 upon success, or -1 otherwise. */ > > -extern int sepol_genbools(void *data, size_t len, const char > > *boolpath); > > - > > -/* Given an existing binary policy (starting at 'data', with > > length 'len') > > - and boolean settings specified by the parallel arrays ('names', > > 'values') > > - with 'nel' elements, rewrite the binary policy for the boolean > > settings. > > - The binary policy is rewritten in place in memory. > > - Returns 0 upon success or -1 otherwise. */ > > -extern int sepol_genbools_array(void *data, size_t len, > > - char **names, int *values, int nel); > > -/*---------------end compatbility------------*/ > > - > > /* Set the specified boolean */ > > extern int sepol_bool_set(sepol_handle_t * handle, > > sepol_policydb_t * policydb, > > diff --git a/libsepol/include/sepol/policydb/services.h > > b/libsepol/include/sepol/policydb/services.h > > index 6ef27a8c..776c2cff 100644 > > --- a/libsepol/include/sepol/policydb/services.h > > +++ b/libsepol/include/sepol/policydb/services.h > > @@ -30,12 +30,6 @@ extern "C" { > > extern int sepol_set_policydb(policydb_t * p); > > extern int sepol_set_sidtab(sidtab_t * s); > > > > -/* Modify a policydb for boolean settings. */ > > -int sepol_genbools_policydb(policydb_t * policydb, const char > > *booleans); > > - > > -/* Modify a policydb for user settings. */ > > -int sepol_genusers_policydb(policydb_t * policydb, const char > > *usersdir); > > - > > /* Load the security policy. This initializes the policydb > > and sidtab based on the provided binary policy. */ > > extern int sepol_load_policy(void *data, size_t len); > > diff --git a/libsepol/include/sepol/users.h > > b/libsepol/include/sepol/users.h > > index ad23f89b..156d1adb 100644 > > --- a/libsepol/include/sepol/users.h > > +++ b/libsepol/include/sepol/users.h > > @@ -10,23 +10,6 @@ > > extern "C" { > > #endif > > > > -/*---------compatibility------------*/ > > - > > -/* Given an existing binary policy (starting at 'data with length > > 'len') > > - and user configurations living in 'usersdir', generate a new > > binary > > - policy for the new user configurations. Sets '*newdata' and > > '*newlen' > > - to refer to the new binary policy image. */ > > -extern int sepol_genusers(void *data, size_t len, > > - const char *usersdir, > > - void **newdata, size_t * newlen); > > - > > -/* Enable or disable deletion of users by sepol_genusers(3) when > > - a user in original binary policy image is not defined by the > > - new user configurations. Defaults to disabled. */ > > -extern void sepol_set_delusers(int on); > > - > > -/*--------end compatibility----------*/ > > - > > /* Modify the user, or add it, if the key is not found */ > > extern int sepol_user_modify(sepol_handle_t * handle, > > sepol_policydb_t * policydb, > > diff --git a/libsepol/src/genbools.c b/libsepol/src/genbools.c > > deleted file mode 100644 > > index d4a2df62..00000000 > > --- a/libsepol/src/genbools.c > > +++ /dev/null > > @@ -1,279 +0,0 @@ > > -#include <stdio.h> > > -#include <stdlib.h> > > -#include <ctype.h> > > -#include <errno.h> > > - > > -#include <sepol/policydb/policydb.h> > > -#include <sepol/policydb/conditional.h> > > - > > -#include "debug.h" > > -#include "private.h" > > -#include "dso.h" > > - > > -/* -- Deprecated -- */ > > - > > -static char *strtrim(char *dest, char *source, int size) > > -{ > > - int i = 0; > > - char *ptr = source; > > - i = 0; > > - while (isspace(*ptr) && i < size) { > > - ptr++; > > - i++; > > - } > > - strncpy(dest, ptr, size); > > - for (i = strlen(dest) - 1; i > 0; i--) { > > - if (!isspace(dest[i])) > > - break; > > - } > > - dest[i + 1] = '\0'; > > - return dest; > > -} > > - > > -static int process_boolean(char *buffer, char *name, int namesize, > > int *val) > > -{ > > - char name1[BUFSIZ]; > > - char *ptr = NULL; > > - char *tok; > > - > > - /* Skip spaces */ > > - while (isspace(buffer[0])) > > - buffer++; > > - /* Ignore comments */ > > - if (buffer[0] == '#') > > - return 0; > > - > > - tok = strtok_r(buffer, "=", &ptr); > > - if (!tok) { > > - ERR(NULL, "illegal boolean definition %s", buffer); > > - return -1; > > - } > > - strncpy(name1, tok, BUFSIZ - 1); > > - strtrim(name, name1, namesize - 1); > > - > > - tok = strtok_r(NULL, "\0", &ptr); > > - if (!tok) { > > - ERR(NULL, "illegal boolean definition %s=%s", name, > > buffer); > > - return -1; > > - } > > - > > - while (isspace(*tok)) > > - tok++; > > - > > - *val = -1; > > - if (isdigit(tok[0])) > > - *val = atoi(tok); > > - else if (!strncasecmp(tok, "true", sizeof("true") - 1)) > > - *val = 1; > > - else if (!strncasecmp(tok, "false", sizeof("false") - 1)) > > - *val = 0; > > - if (*val != 0 && *val != 1) { > > - ERR(NULL, "illegal value for boolean %s=%s", name, > > tok); > > - return -1; > > - } > > - return 1; > > -} > > - > > -static int load_booleans(struct policydb *policydb, const char > > *path, > > - int *changesp) > > -{ > > - FILE *boolf; > > - char *buffer = NULL; > > - char localbools[BUFSIZ]; > > - char name[BUFSIZ]; > > - int val; > > - int errors = 0, changes = 0; > > - struct cond_bool_datum *datum; > > - > > - boolf = fopen(path, "r"); > > - if (boolf == NULL) > > - goto localbool; > > - > > -#ifdef __APPLE__ > > - if ((buffer = (char *)malloc(255 * sizeof(char))) == NULL) > > { > > - ERR(NULL, "out of memory"); > > - return -1; > > - } > > - > > - while(fgets(buffer, 255, boolf) != NULL) { > > -#else > > - size_t size = 0; > > - while (getline(&buffer, &size, boolf) > 0) { > > -#endif > > - int ret = process_boolean(buffer, name, sizeof(name), > > &val); > > - if (ret == -1) > > - errors++; > > - if (ret == 1) { > > - datum = hashtab_search(policydb->p_bools.table, > > name); > > - if (!datum) { > > - ERR(NULL, "unknown boolean %s", name); > > - errors++; > > - continue; > > - } > > - if (datum->state != val) { > > - datum->state = val; > > - changes++; > > - } > > - } > > - } > > - fclose(boolf); > > - localbool: > > - snprintf(localbools, sizeof(localbools), "%s.local", path); > > - boolf = fopen(localbools, "r"); > > - if (boolf != NULL) { > > - > > -#ifdef __APPLE__ > > - > > - while(fgets(buffer, 255, boolf) != NULL) { > > -#else > > - > > - while (getline(&buffer, &size, boolf) > 0) { > > -#endif > > - int ret = > > - process_boolean(buffer, name, sizeof(name), > > &val); > > - if (ret == -1) > > - errors++; > > - if (ret == 1) { > > - datum = > > - hashtab_search(policydb- > > >p_bools.table, > > - name); > > - if (!datum) { > > - ERR(NULL, "unknown boolean %s", > > name); > > - errors++; > > - continue; > > - } > > - if (datum->state != val) { > > - datum->state = val; > > - changes++; > > - } > > - } > > - } > > - fclose(boolf); > > - } > > - free(buffer); > > - if (errors) > > - errno = EINVAL; > > - *changesp = changes; > > - return errors ? -1 : 0; > > -} > > - > > -int sepol_genbools(void *data, size_t len, const char *booleans) > > -{ > > - struct policydb policydb; > > - struct policy_file pf; > > - int rc, changes = 0; > > - > > - if (policydb_init(&policydb)) > > - goto err; > > - if (policydb_from_image(NULL, data, len, &policydb) < 0) > > - goto err; > > - > > - if (load_booleans(&policydb, booleans, &changes) < 0) { > > - WARN(NULL, "error while reading %s", booleans); > > - } > > - > > - if (!changes) > > - goto out; > > - > > - if (evaluate_conds(&policydb) < 0) { > > - ERR(NULL, "error while re-evaluating conditionals"); > > - errno = EINVAL; > > - goto err_destroy; > > - } > > - > > - policy_file_init(&pf); > > - pf.type = PF_USE_MEMORY; > > - pf.data = data; > > - pf.len = len; > > - rc = policydb_write(&policydb, &pf); > > - if (rc) { > > - ERR(NULL, "unable to write new binary policy image"); > > - errno = EINVAL; > > - goto err_destroy; > > - } > > - > > - out: > > - policydb_destroy(&policydb); > > - return 0; > > - > > - err_destroy: > > - policydb_destroy(&policydb); > > - > > - err: > > - return -1; > > -} > > - > > -int hidden sepol_genbools_policydb(policydb_t * policydb, const > > char *booleans) > > -{ > > - int rc, changes = 0; > > - > > - rc = load_booleans(policydb, booleans, &changes); > > - if (!rc && changes) > > - rc = evaluate_conds(policydb); > > - if (rc) > > - errno = EINVAL; > > - return rc; > > -} > > - > > -/* -- End Deprecated -- */ > > - > > -int sepol_genbools_array(void *data, size_t len, char **names, int > > *values, > > - int nel) > > -{ > > - struct policydb policydb; > > - struct policy_file pf; > > - int rc, i, errors = 0; > > - struct cond_bool_datum *datum; > > - > > - /* Create policy database from image */ > > - if (policydb_init(&policydb)) > > - goto err; > > - if (policydb_from_image(NULL, data, len, &policydb) < 0) > > - goto err; > > - > > - for (i = 0; i < nel; i++) { > > - datum = hashtab_search(policydb.p_bools.table, > > names[i]); > > - if (!datum) { > > - ERR(NULL, "boolean %s no longer in policy", > > names[i]); > > - errors++; > > - continue; > > - } > > - if (values[i] != 0 && values[i] != 1) { > > - ERR(NULL, "illegal value %d for boolean %s", > > - values[i], names[i]); > > - errors++; > > - continue; > > - } > > - datum->state = values[i]; > > - } > > - > > - if (evaluate_conds(&policydb) < 0) { > > - ERR(NULL, "error while re-evaluating conditionals"); > > - errno = EINVAL; > > - goto err_destroy; > > - } > > - > > - policy_file_init(&pf); > > - pf.type = PF_USE_MEMORY; > > - pf.data = data; > > - pf.len = len; > > - rc = policydb_write(&policydb, &pf); > > - if (rc) { > > - ERR(NULL, "unable to write binary policy"); > > - errno = EINVAL; > > - goto err_destroy; > > - } > > - if (errors) { > > - errno = EINVAL; > > - goto err_destroy; > > - } > > - > > - policydb_destroy(&policydb); > > - return 0; > > - > > - err_destroy: > > - policydb_destroy(&policydb); > > - > > - err: > > - return -1; > > -} > > diff --git a/libsepol/src/genusers.c b/libsepol/src/genusers.c > > deleted file mode 100644 > > index c375c669..00000000 > > --- a/libsepol/src/genusers.c > > +++ /dev/null > > @@ -1,343 +0,0 @@ > > -#include <stdio.h> > > - > > -#include <stdlib.h> > > -#include <ctype.h> > > -#include <errno.h> > > -#include <limits.h> > > - > > -#include <sepol/policydb/policydb.h> > > - > > -#ifndef __APPLE__ > > -#include <stdio_ext.h> > > -#endif > > - > > -#include <stdarg.h> > > - > > -#include "debug.h" > > -#include "private.h" > > -#include "dso.h" > > -#include "mls.h" > > - > > -/* -- Deprecated -- */ > > - > > -void sepol_set_delusers(int on __attribute((unused))) > > -{ > > - WARN(NULL, "Deprecated interface"); > > -} > > - > > -#undef BADLINE > > -#define BADLINE() { \ > > - ERR(NULL, "invalid entry %s (%s:%u)", \ > > - buffer, path, lineno); \ > > - continue; \ > > -} > > - > > -static int load_users(struct policydb *policydb, const char *path) > > -{ > > - FILE *fp; > > - char *buffer = NULL, *p, *q, oldc; > > - ssize_t nread; > > - unsigned lineno = 0, islist = 0, bit; > > - user_datum_t *usrdatum; > > - role_datum_t *roldatum; > > - ebitmap_node_t *rnode; > > - > > - fp = fopen(path, "r"); > > - if (fp == NULL) > > - return -1; > > - > > -#ifdef __APPLE__ > > - if ((buffer = (char *)malloc(255 * sizeof(char))) == NULL) { > > - ERR(NULL, "out of memory"); > > - return -1; > > - } > > - > > - while(fgets(buffer, 255, fp) != NULL) { > > - nread = strlen(buffer); > > -#else > > - size_t len = 0; > > - __fsetlocking(fp, FSETLOCKING_BYCALLER); > > - while ((nread = getline(&buffer, &len, fp)) > 0) { > > -#endif > > - > > - lineno++; > > - if (buffer[nread - 1] == '\n') > > - buffer[nread - 1] = 0; > > - p = buffer; > > - while (*p && isspace(*p)) > > - p++; > > - if (!(*p) || *p == '#') > > - continue; > > - > > - if (strncasecmp(p, "user", 4)) > > - BADLINE(); > > - p += 4; > > - if (!isspace(*p)) > > - BADLINE(); > > - while (*p && isspace(*p)) > > - p++; > > - if (!(*p)) > > - BADLINE(); > > - q = p; > > - while (*p && !isspace(*p)) > > - p++; > > - if (!(*p)) > > - BADLINE(); > > - *p++ = 0; > > - > > - usrdatum = hashtab_search(policydb->p_users.table, q); > > - if (usrdatum) { > > - /* Replacing an existing user definition. */ > > - ebitmap_destroy(&usrdatum->roles.roles); > > - ebitmap_init(&usrdatum->roles.roles); > > - } else { > > - char *id = strdup(q); > > - > > - if (!id) { > > - ERR(NULL, "out of memory"); > > - free(buffer); > > - fclose(fp); > > - return -1; > > - } > > - > > - /* Adding a new user definition. */ > > - usrdatum = malloc(sizeof(user_datum_t)); > > - if (!usrdatum) { > > - ERR(NULL, "out of memory"); > > - free(buffer); > > - free(id); > > - fclose(fp); > > - return -1; > > - } > > - > > - user_datum_init(usrdatum); > > - usrdatum->s.value = ++policydb->p_users.nprim; > > - if (hashtab_insert(policydb->p_users.table, > > - id, (hashtab_datum_t) > > usrdatum)) { > > - ERR(NULL, "out of memory"); > > - free(buffer); > > - free(id); > > - user_datum_destroy(usrdatum); > > - free(usrdatum); > > - fclose(fp); > > - return -1; > > - } > > - } > > - > > - while (*p && isspace(*p)) > > - p++; > > - if (!(*p)) > > - BADLINE(); > > - if (strncasecmp(p, "roles", 5)) > > - BADLINE(); > > - p += 5; > > - if (!isspace(*p)) > > - BADLINE(); > > - while (*p && isspace(*p)) > > - p++; > > - if (!(*p)) > > - BADLINE(); > > - if (*p == '{') { > > - islist = 1; > > - p++; > > - } else > > - islist = 0; > > - > > - oldc = 0; > > - do { > > - while (*p && isspace(*p)) > > - p++; > > - if (!(*p)) > > - break; > > - > > - q = p; > > - while (*p && *p != ';' && *p != '}' && > > !isspace(*p)) > > - p++; > > - if (!(*p)) > > - break; > > - if (*p == '}') > > - islist = 0; > > - oldc = *p; > > - *p++ = 0; > > - if (!q[0]) > > - break; > > - > > - roldatum = hashtab_search(policydb- > > >p_roles.table, q); > > - if (!roldatum) { > > - ERR(NULL, "undefined role %s (%s:%u)", > > - q, path, lineno); > > - continue; > > - } > > - /* Set the role and every role it dominates */ > > - ebitmap_for_each_positive_bit(&roldatum- > > >dominates, rnode, bit) { > > - if (ebitmap_set_bit > > - (&usrdatum->roles.roles, bit, 1)) { > > - ERR(NULL, "out of memory"); > > - free(buffer); > > - fclose(fp); > > - return -1; > > - } > > - } > > - } while (islist); > > - if (oldc == 0) > > - BADLINE(); > > - > > - if (policydb->mls) { > > - context_struct_t context; > > - char *scontext, *r, *s; > > - > > - while (*p && isspace(*p)) > > - p++; > > - if (!(*p)) > > - BADLINE(); > > - if (strncasecmp(p, "level", 5)) > > - BADLINE(); > > - p += 5; > > - if (!isspace(*p)) > > - BADLINE(); > > - while (*p && isspace(*p)) > > - p++; > > - if (!(*p)) > > - BADLINE(); > > - q = p; > > - while (*p && (!isspace(*p) || strncasecmp(p + > > 1, "range", 5))) > > - p++; > > - if (!(*p) || p == q) > > - BADLINE(); > > - *p = 0; > > - p++; > > - > > - scontext = malloc(p - q); > > - if (!scontext) { > > - ERR(NULL, "out of memory"); > > - free(buffer); > > - fclose(fp); > > - return -1; > > - } > > - r = scontext; > > - s = q; > > - while (*s) { > > - if (!isspace(*s)) > > - *r++ = *s; > > - s++; > > - } > > - *r = 0; > > - r = scontext; > > - > > - context_init(&context); > > - if (mls_context_to_sid(policydb, oldc, &r, > > &context) < > > - 0) { > > - ERR(NULL, "invalid level %s (%s:%u)", > > scontext, > > - path, lineno); > > - free(scontext); > > - continue; > > - > > - } > > - free(scontext); > > - memcpy(&usrdatum->dfltlevel, > > &context.range.level[0], > > - sizeof(usrdatum->dfltlevel)); > > - > > - if (strncasecmp(p, "range", 5)) > > - BADLINE(); > > - p += 5; > > - if (!isspace(*p)) > > - BADLINE(); > > - while (*p && isspace(*p)) > > - p++; > > - if (!(*p)) > > - BADLINE(); > > - q = p; > > - while (*p && *p != ';') > > - p++; > > - if (!(*p)) > > - BADLINE(); > > - *p++ = 0; > > - > > - scontext = malloc(p - q); > > - if (!scontext) { > > - ERR(NULL, "out of memory"); > > - free(buffer); > > - fclose(fp); > > - return -1; > > - } > > - r = scontext; > > - s = q; > > - while (*s) { > > - if (!isspace(*s)) > > - *r++ = *s; > > - s++; > > - } > > - *r = 0; > > - r = scontext; > > - > > - context_init(&context); > > - if (mls_context_to_sid(policydb, oldc, &r, > > &context) < > > - 0) { > > - ERR(NULL, "invalid range %s (%s:%u)", > > scontext, > > - path, lineno); > > - free(scontext); > > - continue; > > - } > > - free(scontext); > > - memcpy(&usrdatum->range, &context.range, > > - sizeof(usrdatum->range)); > > - } > > - } > > - > > - free(buffer); > > - fclose(fp); > > - return 0; > > -} > > - > > -int sepol_genusers(void *data, size_t len, > > - const char *usersdir, void **newdata, size_t * > > newlen) > > -{ > > - struct policydb policydb; > > - char path[PATH_MAX]; > > - > > - /* Construct policy database */ > > - if (policydb_init(&policydb)) > > - goto err; > > - if (policydb_from_image(NULL, data, len, &policydb) < 0) > > - goto err; > > - > > - /* Load locally defined users. */ > > - snprintf(path, sizeof path, "%s/local.users", usersdir); > > - if (load_users(&policydb, path) < 0) > > - goto err_destroy; > > - > > - /* Write policy database */ > > - if (policydb_to_image(NULL, &policydb, newdata, newlen) < 0) > > - goto err_destroy; > > - > > - policydb_destroy(&policydb); > > - return 0; > > - > > - err_destroy: > > - policydb_destroy(&policydb); > > - > > - err: > > - return -1; > > -} > > - > > -int hidden sepol_genusers_policydb(policydb_t * policydb, const > > char *usersdir) > > -{ > > - char path[PATH_MAX]; > > - > > - /* Load locally defined users. */ > > - snprintf(path, sizeof path, "%s/local.users", usersdir); > > - if (load_users(policydb, path) < 0) { > > - ERR(NULL, "unable to load local.users: %s", > > strerror(errno)); > > - return -1; > > - } > > - > > - if (policydb_reindex_users(policydb) < 0) { > > - ERR(NULL, "unable to reindex users: %s", > > strerror(errno)); > > - return -1; > > - > > - } > > - > > - return 0; > > -} > > - > > -/* -- End Deprecated -- */ > > diff --git a/libsepol/src/libsepol.map.in > > b/libsepol/src/libsepol.map.in > > index d879016c..d997e524 100644 > > --- a/libsepol/src/libsepol.map.in > > +++ b/libsepol/src/libsepol.map.in > > @@ -2,14 +2,14 @@ LIBSEPOL_1.0 { > > global: > > expand_module_avrules; > > sepol_module_package_*; sepol_link_modules; > > sepol_expand_module; sepol_link_packages; > > - sepol_bool_*; sepol_genbools*; > > + sepol_bool_*; > > sepol_context_*; sepol_mls_*; sepol_check_context; > > sepol_iface_*; > > sepol_port_*; > > sepol_ibpkey_*; > > sepol_ibendport_*; > > sepol_node_*; > > - sepol_user_*; sepol_genusers; sepol_set_delusers; > > + sepol_user_*; sepol_set_delusers; > > sepol_msg_*; sepol_debug; > > sepol_handle_*; > > sepol_policydb_*; sepol_set_policydb_from_file; > > We have to keep at least stubs for the libsepol interfaces exported > in > the map file because those are part of the shared library ABI and we > can't break ABI. So trivial sepol_genbools*() and sepol_genusers() > that > return an error are ok but not complete removal. Okay will fix. I plan to add them to a 'deprecated_funcs.c' file with some notes. > > We should test this on RHEL7 too to confirm no breakage. I only have Fedora 30 & Rawhide so I'll leave that to others. > > In the next patchset I'll add the manpage changes as well.