From 4d621a89d6e7565bd2432a616734ce231a73dd53 Mon Sep 17 00:00:00 2001 From: Petr Lautrbach Date: Nov 22 2016 17:22:54 +0000 Subject: libsemanage-2.5-6 - Fixes bug preventing the installation of base modules - make distclean target work - Do not always print a module name warning - Use pp module name instead of filename when installing module - tests: Do not force using gcc - genhomedircon: add support for %group syntax - genhomedircon: generate contexts for logins mapped to the default ser - Validate and compile file contexts before installing - Swap tcp and udp protocol numbers --- diff --git a/libsemanage-fedora.patch b/libsemanage-fedora.patch index f77ecac..a5c1149 100644 --- a/libsemanage-fedora.patch +++ b/libsemanage-fedora.patch @@ -1,8 +1,19 @@ diff --git libsemanage-2.5/ChangeLog libsemanage-2.5/ChangeLog -index 9b4d5b7..731140a 100644 +index 9b4d5b7..469c4b0 100644 --- libsemanage-2.5/ChangeLog +++ libsemanage-2.5/ChangeLog -@@ -1,3 +1,9 @@ +@@ -1,3 +1,20 @@ ++ * Fixes bug preventing the installation of base modules, from James Carter. ++2.6-rc1 2016-09-30 ++ * make distclean target work, from Nicolas Iooss. ++ * Do not always print a module name warning, from Miroslav Grepl. ++ * Use pp module name instead of filename when installing module, from Petr Lautrbach. ++ * tests: Do not force using gcc, from Nicolas Iooss. ++ * genhomedircon: remove hardcoded refpolicy strings, from Gary Tierney. ++ * genhomedircon: add support for %group syntax, from Gary Tierney. ++ * genhomedircon: generate contexts for logins mapped to the default user, from Gary Tierney. ++ * Validate and compile file contexts before installing, from Stephen Smalley. ++ * Swap tcp and udp protocol numbers, from Miroslav Vadkerti. + * Sort object files for deterministic linking order, from Laurent Bigonville. + * Support overriding Makefile RANLIB, from Julien Pivotto. + * Respect CC and PKG_CONFIG environment variable, from Julien Pivotto. @@ -26,7 +37,7 @@ index 6cad529..c816590 100644 /* returns 0 if not connected, 1 if connected */ diff --git libsemanage-2.5/src/Makefile libsemanage-2.5/src/Makefile -index d1fcc0b..96ee652 100644 +index d1fcc0b..68aab72 100644 --- libsemanage-2.5/src/Makefile +++ libsemanage-2.5/src/Makefile @@ -5,6 +5,7 @@ PYTHON ?= python @@ -51,16 +62,18 @@ index d1fcc0b..96ee652 100644 RUBYINSTALL ?= $(LIBDIR)/ruby/site_ruby/$(RUBYLIBVER)/$(RUBYPLATFORM) LIBBASE=$(shell basename $(LIBDIR)) -@@ -51,7 +52,7 @@ SWIGRUBYSO=$(RUBYPREFIX)_semanage.so +@@ -50,8 +51,8 @@ SWIGFILES=$(SWIGSO) semanage.py + SWIGRUBYSO=$(RUBYPREFIX)_semanage.so LIBSO=$(TARGET).$(LIBVERSION) - GENERATED=$(SWIGCOUT) $(SWIGRUBYCOUT) semanageswig_python_exception.i +-GENERATED=$(SWIGCOUT) $(SWIGRUBYCOUT) semanageswig_python_exception.i -SRCS= $(filter-out $(GENERATED),$(wildcard *.c)) ++GENERATED=$(SWIGCOUT) $(SWIGRUBYCOUT) semanageswig_python_exception.i $(wildcard conf-*.[ch]) +SRCS= $(filter-out $(GENERATED),$(sort $(wildcard *.c))) OBJS= $(patsubst %.c,%.o,$(SRCS)) conf-scan.o conf-parse.o LOBJS= $(patsubst %.c,%.lo,$(SRCS)) conf-scan.lo conf-parse.lo -@@ -61,7 +62,7 @@ SWIG_CFLAGS += -Wno-error -Wno-unused-but-set-variable -Wno-unused-variable -Wno +@@ -61,14 +62,12 @@ SWIG_CFLAGS += -Wno-error -Wno-unused-but-set-variable -Wno-unused-variable -Wno -Wno-unused-parameter override CFLAGS += -I../include -I$(INCLUDEDIR) -D_GNU_SOURCE @@ -69,6 +82,22 @@ index d1fcc0b..96ee652 100644 SWIG = swig -Wall -python -o $(SWIGCOUT) -outdir ./ + SWIGRUBY = swig -Wall -ruby -o $(SWIGRUBYCOUT) -outdir ./ + +-GENERATED=$(SWIGCOUT) $(SWIGRUBYCOUT) $(wildcard conf-*.[ch]) +- + all: $(LIBA) $(LIBSO) $(LIBPC) + + pywrap: all $(SWIGSO) +@@ -162,7 +161,7 @@ clean: + -rm -f $(LIBPC) $(OBJS) $(LOBJS) $(LIBA) $(LIBSO) $(SWIGLOBJ) $(SWIGSO) $(TARGET) conf-parse.c conf-parse.h conf-scan.c *.o *.lo *~ + + distclean: clean +- rm -f $(SWIGCOUT) $(SWIGFILES) ++ rm -f $(GENERATED) $(SWIGFILES) + + indent: + ../../scripts/Lindent $(filter-out $(GENERATED),$(wildcard *.[ch])) diff --git libsemanage-2.5/src/database.h libsemanage-2.5/src/database.h index e460379..6a4a164 100644 --- libsemanage-2.5/src/database.h @@ -82,6 +111,87 @@ index e460379..6a4a164 100644 int (*cache) (struct semanage_handle * handle, dbase_t * dbase); /* Forgets all changes that haven't been written +diff --git libsemanage-2.5/src/direct_api.c libsemanage-2.5/src/direct_api.c +index 2187b65..e5c72cd 100644 +--- libsemanage-2.5/src/direct_api.c ++++ libsemanage-2.5/src/direct_api.c +@@ -363,6 +363,35 @@ static int semanage_direct_begintrans(semanage_handle_t * sh) + + /********************* utility functions *********************/ + ++/* Takes a module stored in 'module_data' and parses its headers. ++ * Sets reference variables 'module_name' to module's name, and ++ * 'version' to module's version. The caller is responsible for ++ * free()ing 'module_name', and 'version'; they will be ++ * set to NULL upon entering this function. Returns 0 on success, -1 ++ * if out of memory. ++ */ ++static int parse_module_headers(semanage_handle_t * sh, char *module_data, ++ size_t data_len, char **module_name, ++ char **version) ++{ ++ struct sepol_policy_file *pf; ++ int file_type; ++ *module_name = *version = NULL; ++ ++ if (sepol_policy_file_create(&pf)) { ++ ERR(sh, "Out of memory!"); ++ return -1; ++ } ++ sepol_policy_file_set_mem(pf, module_data, data_len); ++ sepol_policy_file_set_handle(pf, sh->sepolh); ++ if (module_data != NULL && data_len > 0) ++ sepol_module_package_info(pf, &file_type, module_name, ++ version); ++ sepol_policy_file_free(pf); ++ ++ return 0; ++} ++ + #include + #include + #include +@@ -1524,7 +1553,9 @@ static int semanage_direct_install_file(semanage_handle_t * sh, + char *path = NULL; + char *filename; + char *lang_ext = NULL; ++ char *module_name = NULL; + char *separator; ++ char *version = NULL; + + if ((data_len = map_file(sh, install_filename, &data, &compressed)) <= 0) { + ERR(sh, "Unable to read file %s\n", install_filename); +@@ -1564,10 +1595,29 @@ static int semanage_direct_install_file(semanage_handle_t * sh, + lang_ext = separator + 1; + } + +- retval = semanage_direct_install(sh, data, data_len, filename, lang_ext); ++ if (strcmp(lang_ext, "pp") == 0) { ++ retval = parse_module_headers(sh, data, data_len, &module_name, &version); ++ free(version); ++ if (retval != 0) ++ goto cleanup; ++ } ++ ++ if (module_name == NULL) { ++ module_name = strdup(filename); ++ if (module_name == NULL) { ++ ERR(sh, "No memory available for module_name.\n"); ++ retval = -1; ++ goto cleanup; ++ } ++ } else if (strcmp(module_name, filename) != 0) { ++ fprintf(stderr, "Warning: SELinux userspace will refer to the module from %s as %s rather than %s\n", install_filename, module_name, filename); ++ } ++ ++ retval = semanage_direct_install(sh, data, data_len, module_name, lang_ext); + + cleanup: + if (data_len > 0) munmap(data, data_len); ++ free(module_name); + free(path); + + return retval; diff --git libsemanage-2.5/src/exception.sh libsemanage-2.5/src/exception.sh index 94619d2..d18959c 100644 --- libsemanage-2.5/src/exception.sh @@ -95,10 +205,19 @@ index 94619d2..d18959c 100644 for i in `awk '/extern int/ { print $6 }' temp.aux`; do except $i ; done rm -f -- temp.aux -.o diff --git libsemanage-2.5/src/genhomedircon.c libsemanage-2.5/src/genhomedircon.c -index 1a9e87e..c5ea436 100644 +index 1a9e87e..cce3884 100644 --- libsemanage-2.5/src/genhomedircon.c +++ libsemanage-2.5/src/genhomedircon.c -@@ -73,29 +73,27 @@ +@@ -48,6 +48,8 @@ + #include + #include + #include ++#include ++#include + + /* paths used in get_home_dirs() */ + #define PATH_ETC_USERADD "/etc/default/useradd" +@@ -73,37 +75,45 @@ which are searched for and replaced */ #define TEMPLATE_HOME_ROOT "HOME_ROOT" #define TEMPLATE_HOME_DIR "HOME_DIR" @@ -140,7 +259,9 @@ index 1a9e87e..c5ea436 100644 char *sename; char *prefix; char *home; -@@ -104,6 +102,15 @@ typedef struct user_entry { + char *level; ++ char *login; + struct user_entry *next; } genhomedircon_user_entry_t; typedef struct { @@ -156,7 +277,7 @@ index 1a9e87e..c5ea436 100644 const char *search_for; const char *replace_with; } replacement_pair_t; -@@ -461,8 +468,21 @@ static int HOME_DIR_PRED(const char *string) +@@ -461,11 +471,29 @@ static int HOME_DIR_PRED(const char *string) return semanage_is_prefix(string, TEMPLATE_HOME_DIR); } @@ -178,7 +299,15 @@ index 1a9e87e..c5ea436 100644 return (int)(strstr(string, TEMPLATE_USER) != NULL); } -@@ -548,23 +568,12 @@ static int check_line(genhomedircon_settings_t * s, Ustr *line) ++static int STR_COMPARATOR(const void *a, const void *b) ++{ ++ return strcmp((const char *) a, (const char *) b); ++} ++ + /* make_tempate + * @param s the settings holding the paths to various files + * @param pred function pointer to function to use as filter for slurp +@@ -548,23 +576,12 @@ static int check_line(genhomedircon_settings_t * s, Ustr *line) return result; } @@ -205,7 +334,7 @@ index 1a9e87e..c5ea436 100644 for (; tpl; tpl = tpl->next) { line = replace_all(tpl->data, repl); if (!line) -@@ -582,6 +591,28 @@ static int write_home_dir_context(genhomedircon_settings_t * s, FILE * out, +@@ -582,6 +599,28 @@ static int write_home_dir_context(genhomedircon_settings_t * s, FILE * out, return STATUS_ERR; } @@ -234,7 +363,7 @@ index 1a9e87e..c5ea436 100644 static int write_home_root_context(genhomedircon_settings_t * s, FILE * out, semanage_list_t * tpl, char *homedir) { -@@ -589,52 +620,36 @@ static int write_home_root_context(genhomedircon_settings_t * s, FILE * out, +@@ -589,52 +628,54 @@ static int write_home_root_context(genhomedircon_settings_t * s, FILE * out, {.search_for = TEMPLATE_HOME_ROOT,.replace_with = homedir}, {NULL, NULL} }; @@ -287,7 +416,7 @@ index 1a9e87e..c5ea436 100644 {NULL, NULL} }; - Ustr *line = USTR_NULL; -- + - for (; tpl; tpl = tpl->next) { - line = replace_all(tpl->data, repl); - if (!line) @@ -297,24 +426,41 @@ index 1a9e87e..c5ea436 100644 - goto fail; - } - ustr_sc_free(&line); -- } ++ return write_replacements(s, out, tpl, repl); ++} ++ ++static int seuser_sort_func(const void *arg1, const void *arg2) ++{ ++ const semanage_seuser_t **u1 = (const semanage_seuser_t **) arg1; ++ const semanage_seuser_t **u2 = (const semanage_seuser_t **) arg2;; ++ const char *name1 = semanage_seuser_get_name(*u1); ++ const char *name2 = semanage_seuser_get_name(*u2); ++ ++ if (name1[0] == '%' && name2[0] == '%') { ++ return 0; ++ } else if (name1[0] == '%') { ++ return 1; ++ } else if (name2[0] == '%') { ++ return -1; + } - return STATUS_SUCCESS; - fail: - ustr_sc_free(&line); - return STATUS_ERR; -+ return write_replacements(s, out, tpl, repl); ++ return strcmp(name1, name2); } static int user_sort_func(semanage_user_t ** arg1, semanage_user_t ** arg2) -@@ -649,11 +664,13 @@ static int name_user_cmp(char *key, semanage_user_t ** val) +@@ -649,15 +690,19 @@ static int name_user_cmp(char *key, semanage_user_t ** val) } static int push_user_entry(genhomedircon_user_entry_t ** list, const char *n, - const char *sen, const char *pre, const char *h, - const char *l) + const char *u, const char *g, const char *sen, -+ const char *pre, const char *h, const char *l) ++ const char *pre, const char *h, const char *l, ++ const char *ln) { genhomedircon_user_entry_t *temp = NULL; char *name = NULL; @@ -323,7 +469,12 @@ index 1a9e87e..c5ea436 100644 char *sename = NULL; char *prefix = NULL; char *home = NULL; -@@ -665,6 +682,12 @@ static int push_user_entry(genhomedircon_user_entry_t ** list, const char *n, + char *level = NULL; ++ char *lname = NULL; + + temp = malloc(sizeof(genhomedircon_user_entry_t)); + if (!temp) +@@ -665,6 +710,12 @@ static int push_user_entry(genhomedircon_user_entry_t ** list, const char *n, name = strdup(n); if (!name) goto cleanup; @@ -336,8 +487,13 @@ index 1a9e87e..c5ea436 100644 sename = strdup(sen); if (!sename) goto cleanup; -@@ -679,6 +702,8 @@ static int push_user_entry(genhomedircon_user_entry_t ** list, const char *n, +@@ -677,12 +728,18 @@ static int push_user_entry(genhomedircon_user_entry_t ** list, const char *n, + level = strdup(l); + if (!level) goto cleanup; ++ lname = strdup(ln); ++ if (!lname) ++ goto cleanup; temp->name = name; + temp->uid = uid; @@ -345,7 +501,12 @@ index 1a9e87e..c5ea436 100644 temp->sename = sename; temp->prefix = prefix; temp->home = home; -@@ -690,6 +715,8 @@ static int push_user_entry(genhomedircon_user_entry_t ** list, const char *n, + temp->level = level; ++ temp->login = lname; + temp->next = (*list); + (*list) = temp; + +@@ -690,10 +747,13 @@ static int push_user_entry(genhomedircon_user_entry_t ** list, const char *n, cleanup: free(name); @@ -354,7 +515,12 @@ index 1a9e87e..c5ea436 100644 free(sename); free(prefix); free(home); -@@ -708,6 +735,8 @@ static void pop_user_entry(genhomedircon_user_entry_t ** list) + free(level); ++ free(lname); + free(temp); + return STATUS_ERR; + } +@@ -708,39 +768,16 @@ static void pop_user_entry(genhomedircon_user_entry_t ** list) temp = *list; *list = temp->next; free(temp->name); @@ -363,7 +529,8 @@ index 1a9e87e..c5ea436 100644 free(temp->sename); free(temp->prefix); free(temp->home); -@@ -715,32 +744,6 @@ static void pop_user_entry(genhomedircon_user_entry_t ** list) + free(temp->level); ++ free(temp->login); free(temp); } @@ -396,7 +563,7 @@ index 1a9e87e..c5ea436 100644 static int setup_fallback_user(genhomedircon_settings_t * s) { semanage_seuser_t **seuser_list = NULL; -@@ -775,17 +778,19 @@ static int setup_fallback_user(genhomedircon_settings_t * s) +@@ -775,17 +812,20 @@ static int setup_fallback_user(genhomedircon_settings_t * s) if (semanage_user_query(s->h_semanage, key, &u) < 0) { prefix = name; @@ -415,63 +582,322 @@ index 1a9e87e..c5ea436 100644 - if (set_fallback_user(s, seuname, prefix, level) != 0) + if (push_user_entry(&(s->fallback), FALLBACK_NAME, + FALLBACK_UIDGID, FALLBACK_UIDGID, -+ seuname, prefix, "", level) != 0) ++ seuname, prefix, "", level, ++ FALLBACK_NAME) != 0) errors = STATUS_ERR; semanage_user_key_free(key); if (u) -@@ -814,6 +819,8 @@ static genhomedircon_user_entry_t *get_users(genhomedircon_settings_t * s, - const char *seuname = NULL; - const char *prefix = NULL; - const char *level = NULL; +@@ -801,6 +841,202 @@ static int setup_fallback_user(genhomedircon_settings_t * s) + return errors; + } + ++static genhomedircon_user_entry_t *find_user(genhomedircon_user_entry_t *head, ++ const char *name) ++{ ++ for(; head; head = head->next) { ++ if (strcmp(head->name, name) == 0) { ++ return head; ++ } ++ } ++ ++ return NULL; ++} ++ ++static int add_user(genhomedircon_settings_t * s, ++ genhomedircon_user_entry_t **head, ++ semanage_user_t *user, ++ const char *name, ++ const char *sename, ++ const char *selogin) ++{ ++ if (selogin[0] == '%') { ++ genhomedircon_user_entry_t *orig = find_user(*head, name); ++ if (orig != NULL && orig->login[0] == '%') { ++ ERR(s->h_semanage, "User %s is already mapped to" ++ " group %s, but also belongs to group %s. Add an" ++ " explicit mapping for this user to" ++ " override group mappings.", ++ name, orig->login + 1, selogin + 1); ++ return STATUS_ERR; ++ } else if (orig != NULL) { ++ // user mappings take precedence ++ return STATUS_SUCCESS; ++ } ++ } ++ ++ int retval = STATUS_ERR; ++ ++ char *rbuf = NULL; ++ long rbuflen; ++ struct passwd pwstorage, *pwent = NULL; ++ const char *prefix = NULL; ++ const char *level = NULL; + char uid[11]; + char gid[11]; - struct passwd pwstorage, *pwent = NULL; ++ ++ /* Allocate space for the getpwnam_r buffer */ ++ rbuflen = sysconf(_SC_GETPW_R_SIZE_MAX); ++ if (rbuflen <= 0) ++ goto cleanup; ++ rbuf = malloc(rbuflen); ++ if (rbuf == NULL) ++ goto cleanup; ++ ++ if (user) { ++ prefix = semanage_user_get_prefix(user); ++ level = semanage_user_get_mlslevel(user); ++ ++ if (!level) { ++ level = FALLBACK_LEVEL; ++ } ++ } else { ++ prefix = name; ++ level = FALLBACK_LEVEL; ++ } ++ ++ retval = getpwnam_r(name, &pwstorage, rbuf, rbuflen, &pwent); ++ if (retval != 0 || pwent == NULL) { ++ if (retval != 0 && retval != ENOENT) { ++ goto cleanup; ++ } ++ ++ WARN(s->h_semanage, ++ "user %s not in password file", name); ++ retval = STATUS_SUCCESS; ++ goto cleanup; ++ } ++ ++ int len = strlen(pwent->pw_dir) -1; ++ for(; len > 0 && pwent->pw_dir[len] == '/'; len--) { ++ pwent->pw_dir[len] = '\0'; ++ } ++ ++ if (strcmp(pwent->pw_dir, "/") == 0) { ++ /* don't relabel / genhomdircon checked to see if root ++ * was the user and if so, set his home directory to ++ * /root */ ++ retval = STATUS_SUCCESS; ++ goto cleanup; ++ } ++ ++ if (ignore(pwent->pw_dir)) { ++ retval = STATUS_SUCCESS; ++ goto cleanup; ++ } ++ ++ len = snprintf(uid, sizeof(uid), "%u", pwent->pw_uid); ++ if (len < 0 || len >= (int)sizeof(uid)) { ++ goto cleanup; ++ } ++ ++ len = snprintf(gid, sizeof(gid), "%u", pwent->pw_gid); ++ if (len < 0 || len >= (int)sizeof(gid)) { ++ goto cleanup; ++ } ++ ++ retval = push_user_entry(head, name, uid, gid, sename, prefix, ++ pwent->pw_dir, level, selogin); ++cleanup: ++ free(rbuf); ++ return retval; ++} ++ ++static int get_group_users(genhomedircon_settings_t * s, ++ genhomedircon_user_entry_t **head, ++ semanage_user_t *user, ++ const char *sename, ++ const char *selogin) ++{ ++ int retval = STATUS_ERR; ++ unsigned int i; ++ ++ long grbuflen; ++ char *grbuf = NULL; ++ struct group grstorage, *group = NULL; ++ ++ long prbuflen; ++ char *pwbuf = NULL; ++ struct passwd pwstorage, *pw = NULL; ++ ++ grbuflen = sysconf(_SC_GETGR_R_SIZE_MAX); ++ if (grbuflen <= 0) ++ goto cleanup; ++ grbuf = malloc(grbuflen); ++ if (grbuf == NULL) ++ goto cleanup; ++ ++ const char *grname = selogin + 1; ++ ++ if (getgrnam_r(grname, &grstorage, grbuf, ++ (size_t) grbuflen, &group) != 0) { ++ goto cleanup; ++ } ++ ++ if (group == NULL) { ++ ERR(s->h_semanage, "Can't find group named %s\n", grname); ++ goto cleanup; ++ } ++ ++ size_t nmembers = 0; ++ char **members = group->gr_mem; ++ ++ while (*members != NULL) { ++ nmembers++; ++ members++; ++ } ++ ++ for (i = 0; i < nmembers; i++) { ++ const char *uname = group->gr_mem[i]; ++ ++ if (add_user(s, head, user, uname, sename, selogin) < 0) { ++ goto cleanup; ++ } ++ } ++ ++ prbuflen = sysconf(_SC_GETPW_R_SIZE_MAX); ++ if (prbuflen <= 0) ++ goto cleanup; ++ pwbuf = malloc(prbuflen); ++ if (pwbuf == NULL) ++ goto cleanup; ++ ++ setpwent(); ++ while ((retval = getpwent_r(&pwstorage, pwbuf, prbuflen, &pw)) == 0) { ++ // skip users who also have this group as their ++ // primary group ++ if (lfind(pw->pw_name, group->gr_mem, &nmembers, ++ sizeof(char *), &STR_COMPARATOR)) { ++ continue; ++ } ++ ++ if (group->gr_gid == pw->pw_gid) { ++ if (add_user(s, head, user, pw->pw_name, ++ sename, selogin) < 0) { ++ goto cleanup; ++ } ++ } ++ } ++ ++ retval = STATUS_SUCCESS; ++cleanup: ++ endpwent(); ++ free(pwbuf); ++ free(grbuf); ++ ++ return retval; ++} ++ + static genhomedircon_user_entry_t *get_users(genhomedircon_settings_t * s, + int *errors) + { +@@ -812,12 +1048,7 @@ static genhomedircon_user_entry_t *get_users(genhomedircon_settings_t * s, + semanage_user_t **u = NULL; + const char *name = NULL; + const char *seuname = NULL; +- const char *prefix = NULL; +- const char *level = NULL; +- struct passwd pwstorage, *pwent = NULL; unsigned int i; - long rbuflen; -@@ -846,7 +853,7 @@ static genhomedircon_user_entry_t *get_users(genhomedircon_settings_t * s, +- long rbuflen; +- char *rbuf = NULL; + int retval; + + *errors = 0; +@@ -831,82 +1062,42 @@ static genhomedircon_user_entry_t *get_users(genhomedircon_settings_t * s, + nusers = 0; + } + ++ qsort(seuser_list, nseusers, sizeof(semanage_seuser_t *), ++ &seuser_sort_func); + qsort(user_list, nusers, sizeof(semanage_user_t *), + (int (*)(const void *, const void *))&user_sort_func); + +- /* Allocate space for the getpwnam_r buffer */ +- rbuflen = sysconf(_SC_GETPW_R_SIZE_MAX); +- if (rbuflen <= 0) +- goto cleanup; +- rbuf = malloc(rbuflen); +- if (rbuf == NULL) +- goto cleanup; +- + for (i = 0; i < nseusers; i++) { seuname = semanage_seuser_get_sename(seuser_list[i]); name = semanage_seuser_get_name(seuser_list[i]); - if (strcmp(name,"root") && strcmp(seuname, s->fallback_user) == 0) -+ if (strcmp(name,"root") && strcmp(seuname, s->fallback->sename) == 0) +- continue; +- + if (strcmp(name, DEFAULT_LOGIN) == 0) continue; - if (strcmp(name, DEFAULT_LOGIN) == 0) -@@ -867,10 +874,10 @@ static genhomedircon_user_entry_t *get_users(genhomedircon_settings_t * s, - prefix = semanage_user_get_prefix(*u); - level = semanage_user_get_mlslevel(*u); - if (!level) + if (strcmp(name, TEMPLATE_SEUSER) == 0) + continue; + +- /* %groupname syntax */ +- if (name[0] == '%') +- continue; +- + /* find the user structure given the name */ + u = bsearch(seuname, user_list, nusers, sizeof(semanage_user_t *), + (int (*)(const void *, const void *)) + &name_user_cmp); +- if (u) { +- prefix = semanage_user_get_prefix(*u); +- level = semanage_user_get_mlslevel(*u); +- if (!level) - level = FALLBACK_USER_LEVEL; -+ level = FALLBACK_LEVEL; - } else { - prefix = name; +- } else { +- prefix = name; - level = FALLBACK_USER_LEVEL; -+ level = FALLBACK_LEVEL; - } +- } +- +- retval = getpwnam_r(name, &pwstorage, rbuf, rbuflen, &pwent); +- if (retval != 0 || pwent == NULL) { +- if (retval != 0 && retval != ENOENT) { +- *errors = STATUS_ERR; +- goto cleanup; +- } +- +- WARN(s->h_semanage, +- "user %s not in password file", name); +- continue; +- } - retval = getpwnam_r(name, &pwstorage, rbuf, rbuflen, &pwent); -@@ -898,7 +905,19 @@ static genhomedircon_user_entry_t *get_users(genhomedircon_settings_t * s, +- int len = strlen(pwent->pw_dir) -1; +- for(; len > 0 && pwent->pw_dir[len] == '/'; len--) { +- pwent->pw_dir[len] = '\0'; ++ /* %groupname syntax */ ++ if (name[0] == '%') { ++ retval = get_group_users(s, &head, *u, seuname, ++ name); ++ } else { ++ retval = add_user(s, &head, *u, name, ++ seuname, name); } - if (ignore(pwent->pw_dir)) - continue; + +- if (strcmp(pwent->pw_dir, "/") == 0) { +- /* don't relabel / genhomdircon checked to see if root +- * was the user and if so, set his home directory to +- * /root */ +- continue; +- } +- if (ignore(pwent->pw_dir)) +- continue; - if (push_user_entry(&head, name, seuname, -+ -+ len = snprintf(uid, sizeof(uid), "%u", pwent->pw_uid); -+ if (len < 0 || len >= (int)sizeof(uid)) { -+ *errors = STATUS_ERR; -+ goto cleanup; -+ } -+ len = snprintf(gid, sizeof(gid), "%u", pwent->pw_gid); -+ if (len < 0 || len >= (int)sizeof(gid)) { -+ *errors = STATUS_ERR; -+ goto cleanup; -+ } -+ -+ if (push_user_entry(&head, name, uid, gid, seuname, - prefix, pwent->pw_dir, level) != STATUS_SUCCESS) { +- prefix, pwent->pw_dir, level) != STATUS_SUCCESS) { ++ if (retval != 0) { *errors = STATUS_ERR; - break; -@@ -927,6 +946,7 @@ static genhomedircon_user_entry_t *get_users(genhomedircon_settings_t * s, +- break; ++ goto cleanup; + } + } + + cleanup: +- free(rbuf); + if (*errors) { + for (; head; pop_user_entry(&head)) { + /* the pop function takes care of all the cleanup +@@ -927,6 +1118,7 @@ static genhomedircon_user_entry_t *get_users(genhomedircon_settings_t * s, } static int write_gen_home_dir_context(genhomedircon_settings_t * s, FILE * out, @@ -479,7 +905,7 @@ index 1a9e87e..c5ea436 100644 semanage_list_t * user_context_tpl, semanage_list_t * homedir_context_tpl) { -@@ -939,13 +959,11 @@ static int write_gen_home_dir_context(genhomedircon_settings_t * s, FILE * out, +@@ -939,13 +1131,11 @@ static int write_gen_home_dir_context(genhomedircon_settings_t * s, FILE * out, } for (; users; pop_user_entry(&users)) { @@ -497,7 +923,7 @@ index 1a9e87e..c5ea436 100644 goto err; } -@@ -968,16 +986,21 @@ static int write_context_file(genhomedircon_settings_t * s, FILE * out) +@@ -968,16 +1158,21 @@ static int write_context_file(genhomedircon_settings_t * s, FILE * out) { semanage_list_t *homedirs = NULL; semanage_list_t *h = NULL; @@ -521,7 +947,7 @@ index 1a9e87e..c5ea436 100644 goto done; if (write_file_context_header(out) != STATUS_SUCCESS) { -@@ -1001,19 +1024,19 @@ static int write_context_file(genhomedircon_settings_t * s, FILE * out) +@@ -1001,19 +1196,19 @@ static int write_context_file(genhomedircon_settings_t * s, FILE * out) for (h = homedirs; h; h = h->next) { Ustr *temp = ustr_dup_cstr(h->data); @@ -548,7 +974,7 @@ index 1a9e87e..c5ea436 100644 retval = STATUS_ERR; goto done; } -@@ -1021,23 +1044,31 @@ static int write_context_file(genhomedircon_settings_t * s, FILE * out) +@@ -1021,23 +1216,31 @@ static int write_context_file(genhomedircon_settings_t * s, FILE * out) homeroot_context_tpl, h->data) != STATUS_SUCCESS) { ustr_sc_free(&temp); @@ -585,7 +1011,7 @@ index 1a9e87e..c5ea436 100644 retval = STATUS_ERR; } } -@@ -1045,6 +1076,7 @@ static int write_context_file(genhomedircon_settings_t * s, FILE * out) +@@ -1045,6 +1248,7 @@ static int write_context_file(genhomedircon_settings_t * s, FILE * out) done: /* Cleanup */ semanage_list_destroy(&homedirs); @@ -593,7 +1019,7 @@ index 1a9e87e..c5ea436 100644 semanage_list_destroy(&user_context_tpl); semanage_list_destroy(&homedir_context_tpl); semanage_list_destroy(&homeroot_context_tpl); -@@ -1068,10 +1100,20 @@ int semanage_genhomedircon(semanage_handle_t * sh, +@@ -1068,10 +1272,20 @@ int semanage_genhomedircon(semanage_handle_t * sh, s.fcfilepath = semanage_final_path(SEMANAGE_FINAL_TMP, SEMANAGE_FC_HOMEDIRS); @@ -618,7 +1044,7 @@ index 1a9e87e..c5ea436 100644 retval = STATUS_ERR; goto done; } -@@ -1095,9 +1137,7 @@ done: +@@ -1095,9 +1309,7 @@ done: if (out != NULL) fclose(out); @@ -629,6 +1055,160 @@ index 1a9e87e..c5ea436 100644 ignore_free(); return retval; +diff --git libsemanage-2.5/src/semanage_store.c libsemanage-2.5/src/semanage_store.c +index fa0876f..ca29257 100644 +--- libsemanage-2.5/src/semanage_store.c ++++ libsemanage-2.5/src/semanage_store.c +@@ -292,6 +292,13 @@ static int semanage_init_final_suffix(semanage_handle_t *sh) + goto cleanup; + } + ++ if (asprintf(&semanage_final_suffix[SEMANAGE_FC_BIN], "%s.bin", ++ semanage_final_suffix[SEMANAGE_FC]) < 0) { ++ ERR(sh, "Unable to allocate space for file context path."); ++ status = -1; ++ goto cleanup; ++ } ++ + semanage_final_suffix[SEMANAGE_FC_HOMEDIRS] = + strdup(selinux_file_context_homedir_path() + offset); + if (semanage_final_suffix[SEMANAGE_FC_HOMEDIRS] == NULL) { +@@ -300,6 +307,13 @@ static int semanage_init_final_suffix(semanage_handle_t *sh) + goto cleanup; + } + ++ if (asprintf(&semanage_final_suffix[SEMANAGE_FC_HOMEDIRS_BIN], "%s.bin", ++ semanage_final_suffix[SEMANAGE_FC_HOMEDIRS]) < 0) { ++ ERR(sh, "Unable to allocate space for file context home directory path."); ++ status = -1; ++ goto cleanup; ++ } ++ + semanage_final_suffix[SEMANAGE_FC_LOCAL] = + strdup(selinux_file_context_local_path() + offset); + if (semanage_final_suffix[SEMANAGE_FC_LOCAL] == NULL) { +@@ -308,6 +322,13 @@ static int semanage_init_final_suffix(semanage_handle_t *sh) + goto cleanup; + } + ++ if (asprintf(&semanage_final_suffix[SEMANAGE_FC_LOCAL_BIN], "%s.bin", ++ semanage_final_suffix[SEMANAGE_FC_LOCAL]) < 0) { ++ ERR(sh, "Unable to allocate space for local file context path."); ++ status = -1; ++ goto cleanup; ++ } ++ + semanage_final_suffix[SEMANAGE_NC] = + strdup(selinux_netfilter_context_path() + offset); + if (semanage_final_suffix[SEMANAGE_NC] == NULL) { +@@ -1491,6 +1512,45 @@ static int sefcontext_compile(semanage_handle_t * sh, const char *path) { + return 0; + } + ++static int semanage_validate_and_compile_fcontexts(semanage_handle_t * sh) ++{ ++ int status = -1; ++ ++ if (sh->do_check_contexts) { ++ int ret; ++ ret = semanage_exec_prog( ++ sh, ++ sh->conf->setfiles, ++ semanage_final_path(SEMANAGE_FINAL_TMP, ++ SEMANAGE_KERNEL), ++ semanage_final_path(SEMANAGE_FINAL_TMP, ++ SEMANAGE_FC)); ++ if (ret != 0) { ++ ERR(sh, "setfiles returned error code %d.", ret); ++ goto cleanup; ++ } ++ } ++ ++ if (sefcontext_compile(sh, ++ semanage_final_path(SEMANAGE_FINAL_TMP, SEMANAGE_FC)) != 0) { ++ goto cleanup; ++ } ++ ++ if (sefcontext_compile(sh, ++ semanage_final_path(SEMANAGE_FINAL_TMP, SEMANAGE_FC_LOCAL)) != 0) { ++ goto cleanup; ++ } ++ ++ if (sefcontext_compile(sh, ++ semanage_final_path(SEMANAGE_FINAL_TMP, SEMANAGE_FC_HOMEDIRS)) != 0) { ++ goto cleanup; ++ } ++ ++ status = 0; ++cleanup: ++ return status; ++} ++ + /* Load the contexts of the final tmp into the final selinux directory. + * Return 0 on success, -3 on error. + */ +@@ -1566,35 +1626,6 @@ static int semanage_install_final_tmp(semanage_handle_t * sh) + } + + skip_reload: +- if (sh->do_check_contexts) { +- ret = semanage_exec_prog( +- sh, +- sh->conf->setfiles, +- semanage_final_path(SEMANAGE_FINAL_SELINUX, +- SEMANAGE_KERNEL), +- semanage_final_path(SEMANAGE_FINAL_SELINUX, +- SEMANAGE_FC)); +- if (ret != 0) { +- ERR(sh, "setfiles returned error code %d.", ret); +- goto cleanup; +- } +- } +- +- if (sefcontext_compile(sh, +- semanage_final_path(SEMANAGE_FINAL_SELINUX, SEMANAGE_FC)) != 0) { +- goto cleanup; +- } +- +- if (sefcontext_compile(sh, +- semanage_final_path(SEMANAGE_FINAL_SELINUX, SEMANAGE_FC_LOCAL)) != 0) { +- goto cleanup; +- } +- +- if (sefcontext_compile(sh, +- semanage_final_path(SEMANAGE_FINAL_SELINUX, SEMANAGE_FC_HOMEDIRS)) != 0) { +- goto cleanup; +- } +- + status = 0; + cleanup: + return status; +@@ -1737,6 +1768,9 @@ int semanage_install_sandbox(semanage_handle_t * sh) + goto cleanup; + } + ++ if (semanage_validate_and_compile_fcontexts(sh) < 0) ++ goto cleanup; ++ + if ((commit_num = semanage_commit_sandbox(sh)) < 0) { + retval = commit_num; + goto cleanup; +diff --git libsemanage-2.5/src/semanage_store.h libsemanage-2.5/src/semanage_store.h +index acb6e3f..c5b33c8 100644 +--- libsemanage-2.5/src/semanage_store.h ++++ libsemanage-2.5/src/semanage_store.h +@@ -71,8 +71,11 @@ enum semanage_final_defs { + enum semanage_final_path_defs { + SEMANAGE_FINAL_TOPLEVEL, + SEMANAGE_FC, ++ SEMANAGE_FC_BIN, + SEMANAGE_FC_HOMEDIRS, ++ SEMANAGE_FC_HOMEDIRS_BIN, + SEMANAGE_FC_LOCAL, ++ SEMANAGE_FC_LOCAL_BIN, + SEMANAGE_KERNEL, + SEMANAGE_NC, + SEMANAGE_SEUSERS, diff --git libsemanage-2.5/tests/.gitignore libsemanage-2.5/tests/.gitignore new file mode 100644 index 0000000..f07111d @@ -636,6 +1216,18 @@ index 0000000..f07111d +++ libsemanage-2.5/tests/.gitignore @@ -0,0 +1 @@ +libsemanage-tests +diff --git libsemanage-2.5/tests/Makefile libsemanage-2.5/tests/Makefile +index fec96ff..4b81fed 100644 +--- libsemanage-2.5/tests/Makefile ++++ libsemanage-2.5/tests/Makefile +@@ -10,7 +10,6 @@ LIBS = ../src/libsemanage.a ../../libselinux/src/libselinux.a ../../libsepol/src + ########################################################################### + + EXECUTABLE = libsemanage-tests +-CC = gcc + CFLAGS += -g -O0 -Wall -W -Wundef -Wmissing-noreturn -Wmissing-format-attribute -Wno-unused-parameter + INCLUDE = -I$(TESTSRC) -I$(TESTSRC)/../include + LDFLAGS += -lcunit -lustr -lbz2 -laudit diff --git libsemanage-2.5/utils/semanage_migrate_store libsemanage-2.5/utils/semanage_migrate_store index 0ebd285..2bdcc05 100755 --- libsemanage-2.5/utils/semanage_migrate_store diff --git a/libsemanage.spec b/libsemanage.spec index 7cf30ca..187ac83 100644 --- a/libsemanage.spec +++ b/libsemanage.spec @@ -1,20 +1,20 @@ %global with_python3 1 %{!?python_sitearch: %global python_sitearch %(%{__python} -c "from distutils.sysconfig import get_python_lib; print (get_python_lib(1))")} -%define libsepolver 2.5-7 -%define libselinuxver 2.5-7 +%define libsepolver 2.5-10 +%define libselinuxver 2.5-12 Summary: SELinux binary policy manipulation library Name: libsemanage Version: 2.5 -Release: 5%{?dist} +Release: 6%{?dist} License: LGPLv2+ Group: System Environment/Libraries Source: https://raw.githubusercontent.com/wiki/SELinuxProject/selinux/files/releases/20160223/libsemanage-2.5.tar.gz # download https://raw.githubusercontent.com/fedora-selinux/scripts/master/selinux/make-fedora-selinux-patch.sh # run: # $ VERSION=2.5 ./make-fedora-selinux-patch.sh libsemanage -# HEAD https://github.com/fedora-selinux/selinux/commit/9abe77e2a670f2f2dfb91f9cec46ee37f9c23995 +# HEAD https://github.com/fedora-selinux/selinux/commit/74bcf6ec27dce8b10b82c02d0fc756a125cd6f65 Patch1: libsemanage-fedora.patch URL: https://github.com/SELinuxProject/selinux/wiki Source1: semanage.conf @@ -194,6 +194,17 @@ rm -rf ${RPM_BUILD_ROOT} %endif # if with_python3 %changelog +* Mon Oct 03 2016 Petr Lautrbach 2.5-6 +- Fixes bug preventing the installation of base modules +- make distclean target work +- Do not always print a module name warning +- Use pp module name instead of filename when installing module +- tests: Do not force using gcc +- genhomedircon: add support for %group syntax +- genhomedircon: generate contexts for logins mapped to the default user +- Validate and compile file contexts before installing +- Swap tcp and udp protocol numbers + * Thu Jun 23 2016 Petr Lautrbach - 2.5-5 - Sort object files for deterministic linking order - Support overriding Makefile RANLIB