113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle/* Author: Mark Goldman <mgoldman@tresys.com> 213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle * Paul Rosenfeld <prosenfeld@tresys.com> 313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle * Todd C. Miller <tmiller@tresys.com> 413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle * 513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle * Copyright (C) 2007 Tresys Technology, LLC 613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle * 713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle * This library is free software; you can redistribute it and/or modify 813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle * it under the terms of the GNU Lesser General Public License as 913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle * published by the Free Software Foundation; either version 2.1 of the 1013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle * License, or (at your option) any later version. 1113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle * 1213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle * This library is distributed in the hope that it will be useful, but 1313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle * WITHOUT ANY WARRANTY; without even the implied warranty of 1413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 1513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle * Lesser General Public License for more details. 1613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle * 1713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle * You should have received a copy of the GNU Lesser General Public 1813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle * License along with this library; if not, write to the Free Software 1913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 2013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle * 02110-1301 USA 2113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle */ 2213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 2313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle#include <semanage/handle.h> 2413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle#include <semanage/seusers_policy.h> 2513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle#include <semanage/users_policy.h> 2613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle#include <semanage/user_record.h> 2713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle#include <semanage/fcontext_record.h> 2813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle#include <semanage/fcontexts_policy.h> 2913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle#include <sepol/context.h> 3013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle#include <sepol/context_record.h> 3113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle#include "semanage_store.h" 3213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle#include "seuser_internal.h" 3313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle#include "debug.h" 3413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 3513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle#include "utilities.h" 3613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle#include "genhomedircon.h" 3713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 3813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle#include <assert.h> 39300b8ad4235688171f2a91e7aeb14d0ee3561c13Nicolas Iooss#include <ctype.h> 4013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle#include <limits.h> 4113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle#include <stdio.h> 4213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle#include <stdlib.h> 4313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle#include <string.h> 4413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle#include <sys/types.h> 4513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle#include <sys/stat.h> 4613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle#include <fcntl.h> 4713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle#include <pwd.h> 4813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle#include <errno.h> 4913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle#include <unistd.h> 5013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle#include <regex.h> 5167b328a91c6f6f22d8eaf220aaefe06623112f32Gary Tierney#include <grp.h> 5267b328a91c6f6f22d8eaf220aaefe06623112f32Gary Tierney#include <search.h> 5313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 5413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle/* paths used in get_home_dirs() */ 5513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle#define PATH_ETC_USERADD "/etc/default/useradd" 5613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle#define PATH_ETC_LIBUSER "/etc/libuser.conf" 5713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle#define PATH_DEFAULT_HOME "/home" 5813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle#define PATH_EXPORT_HOME "/export/home" 5913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle#define PATH_ETC_LOGIN_DEFS "/etc/login.defs" 6013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 6113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle/* other paths */ 6213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle#define PATH_SHELLS_FILE "/etc/shells" 6313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle#define PATH_NOLOGIN_SHELL "/sbin/nologin" 6413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 6513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle/* comments written to context file */ 6613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle#define COMMENT_FILE_CONTEXT_HEADER "#\n#\n# " \ 6713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle "User-specific file contexts, generated via libsemanage\n" \ 6813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle "# use semanage command to manage system users to change" \ 6913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle " the file_context\n#\n#\n" 7013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 7113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle#define COMMENT_USER_HOME_CONTEXT "\n\n#\n# Home Context for user %s" \ 7213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle "\n#\n\n" 7313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 7413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle/* placeholders used in the template file 7513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle which are searched for and replaced */ 7613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle#define TEMPLATE_HOME_ROOT "HOME_ROOT" 7713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle#define TEMPLATE_HOME_DIR "HOME_DIR" 7808cde98b606cd04e26061d16ec537a2549f5199cJason Zaman/* these are legacy */ 7913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle#define TEMPLATE_USER "USER" 8013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle#define TEMPLATE_ROLE "ROLE" 8108cde98b606cd04e26061d16ec537a2549f5199cJason Zaman/* new names */ 8208cde98b606cd04e26061d16ec537a2549f5199cJason Zaman#define TEMPLATE_USERNAME "%{USERNAME}" 8308cde98b606cd04e26061d16ec537a2549f5199cJason Zaman#define TEMPLATE_USERID "%{USERID}" 8408cde98b606cd04e26061d16ec537a2549f5199cJason Zaman 85925914acea3e2a95f4ccc9d39498cede345061d5Jason Zaman#define FALLBACK_SENAME "user_u" 86925914acea3e2a95f4ccc9d39498cede345061d5Jason Zaman#define FALLBACK_PREFIX "user" 87925914acea3e2a95f4ccc9d39498cede345061d5Jason Zaman#define FALLBACK_LEVEL "s0" 885ebc83b1d395d1ad9e122935834f7ef7f9fb17aaJason Zaman#define FALLBACK_NAME "[^/]+" 893b23f12eb9aa2ee828561ffb414efa8c2031e75fJason Zaman#define FALLBACK_UIDGID "[0-9]+" 9013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle#define DEFAULT_LOGIN "__default__" 9113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 92d97292639cf816a946919aa0f2ed086f14c7db44Gary Tierney#define CONTEXT_NONE "<<none>>" 93d97292639cf816a946919aa0f2ed086f14c7db44Gary Tierney 9413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindletypedef struct user_entry { 9513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle char *name; 963b23f12eb9aa2ee828561ffb414efa8c2031e75fJason Zaman char *uid; 973b23f12eb9aa2ee828561ffb414efa8c2031e75fJason Zaman char *gid; 9813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle char *sename; 9913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle char *prefix; 10013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle char *home; 101d784fd71b56cb8f57d5b9fcd784094e004bf7c6aRussell Coker char *level; 10267b328a91c6f6f22d8eaf220aaefe06623112f32Gary Tierney char *login; 10388e334f1923396d5ace56b8439c731dcde0d1f3bGary Tierney char *homedir_role; 10413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle struct user_entry *next; 10513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle} genhomedircon_user_entry_t; 10613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 10713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindletypedef struct { 108c90780aaf767485fbdc063eab905422d756f22b5Jason Zaman const char *fcfilepath; 109c90780aaf767485fbdc063eab905422d756f22b5Jason Zaman int usepasswd; 110c90780aaf767485fbdc063eab905422d756f22b5Jason Zaman const char *homedir_template_path; 111c90780aaf767485fbdc063eab905422d756f22b5Jason Zaman genhomedircon_user_entry_t *fallback; 112c90780aaf767485fbdc063eab905422d756f22b5Jason Zaman semanage_handle_t *h_semanage; 113c90780aaf767485fbdc063eab905422d756f22b5Jason Zaman sepol_policydb_t *policydb; 114c90780aaf767485fbdc063eab905422d756f22b5Jason Zaman} genhomedircon_settings_t; 115c90780aaf767485fbdc063eab905422d756f22b5Jason Zaman 116c90780aaf767485fbdc063eab905422d756f22b5Jason Zamantypedef struct { 11713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle const char *search_for; 11813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle const char *replace_with; 11913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle} replacement_pair_t; 12013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 12113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindletypedef struct { 12213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle const char *dir; 12313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle int matched; 12413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle} fc_match_handle_t; 12513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 126915b5f885f030aa24a2ca648a184fa02cb5bbdcdEric Paristypedef struct IgnoreDir { 127915b5f885f030aa24a2ca648a184fa02cb5bbdcdEric Paris struct IgnoreDir *next; 128915b5f885f030aa24a2ca648a184fa02cb5bbdcdEric Paris char *dir; 129915b5f885f030aa24a2ca648a184fa02cb5bbdcdEric Paris} ignoredir_t; 130915b5f885f030aa24a2ca648a184fa02cb5bbdcdEric Paris 131915b5f885f030aa24a2ca648a184fa02cb5bbdcdEric Parisignoredir_t *ignore_head = NULL; 132915b5f885f030aa24a2ca648a184fa02cb5bbdcdEric Paris 133915b5f885f030aa24a2ca648a184fa02cb5bbdcdEric Parisstatic void ignore_free(void) { 134915b5f885f030aa24a2ca648a184fa02cb5bbdcdEric Paris ignoredir_t *next; 135915b5f885f030aa24a2ca648a184fa02cb5bbdcdEric Paris 136915b5f885f030aa24a2ca648a184fa02cb5bbdcdEric Paris while (ignore_head) { 137915b5f885f030aa24a2ca648a184fa02cb5bbdcdEric Paris next = ignore_head->next; 138915b5f885f030aa24a2ca648a184fa02cb5bbdcdEric Paris free(ignore_head->dir); 139915b5f885f030aa24a2ca648a184fa02cb5bbdcdEric Paris free(ignore_head); 140915b5f885f030aa24a2ca648a184fa02cb5bbdcdEric Paris ignore_head = next; 141915b5f885f030aa24a2ca648a184fa02cb5bbdcdEric Paris } 142915b5f885f030aa24a2ca648a184fa02cb5bbdcdEric Paris} 143915b5f885f030aa24a2ca648a184fa02cb5bbdcdEric Paris 144915b5f885f030aa24a2ca648a184fa02cb5bbdcdEric Parisstatic int ignore_setup(char *ignoredirs) { 145915b5f885f030aa24a2ca648a184fa02cb5bbdcdEric Paris char *tok; 146915b5f885f030aa24a2ca648a184fa02cb5bbdcdEric Paris ignoredir_t *ptr = NULL; 147915b5f885f030aa24a2ca648a184fa02cb5bbdcdEric Paris 148915b5f885f030aa24a2ca648a184fa02cb5bbdcdEric Paris tok = strtok(ignoredirs, ";"); 149915b5f885f030aa24a2ca648a184fa02cb5bbdcdEric Paris while(tok) { 150915b5f885f030aa24a2ca648a184fa02cb5bbdcdEric Paris ptr = calloc(sizeof(ignoredir_t),1); 151915b5f885f030aa24a2ca648a184fa02cb5bbdcdEric Paris if (!ptr) 152915b5f885f030aa24a2ca648a184fa02cb5bbdcdEric Paris goto err; 153915b5f885f030aa24a2ca648a184fa02cb5bbdcdEric Paris ptr->dir = strdup(tok); 154915b5f885f030aa24a2ca648a184fa02cb5bbdcdEric Paris if (!ptr->dir) 155915b5f885f030aa24a2ca648a184fa02cb5bbdcdEric Paris goto err; 156915b5f885f030aa24a2ca648a184fa02cb5bbdcdEric Paris 157915b5f885f030aa24a2ca648a184fa02cb5bbdcdEric Paris ptr->next = ignore_head; 158915b5f885f030aa24a2ca648a184fa02cb5bbdcdEric Paris ignore_head = ptr; 159915b5f885f030aa24a2ca648a184fa02cb5bbdcdEric Paris 160915b5f885f030aa24a2ca648a184fa02cb5bbdcdEric Paris tok = strtok(NULL, ";"); 161915b5f885f030aa24a2ca648a184fa02cb5bbdcdEric Paris } 162915b5f885f030aa24a2ca648a184fa02cb5bbdcdEric Paris 163915b5f885f030aa24a2ca648a184fa02cb5bbdcdEric Paris return 0; 164915b5f885f030aa24a2ca648a184fa02cb5bbdcdEric Pariserr: 165915b5f885f030aa24a2ca648a184fa02cb5bbdcdEric Paris free(ptr); 166915b5f885f030aa24a2ca648a184fa02cb5bbdcdEric Paris ignore_free(); 167915b5f885f030aa24a2ca648a184fa02cb5bbdcdEric Paris return -1; 168915b5f885f030aa24a2ca648a184fa02cb5bbdcdEric Paris} 169915b5f885f030aa24a2ca648a184fa02cb5bbdcdEric Paris 170915b5f885f030aa24a2ca648a184fa02cb5bbdcdEric Parisstatic int ignore(const char *homedir) { 171915b5f885f030aa24a2ca648a184fa02cb5bbdcdEric Paris ignoredir_t *ptr = ignore_head; 172915b5f885f030aa24a2ca648a184fa02cb5bbdcdEric Paris while (ptr) { 173915b5f885f030aa24a2ca648a184fa02cb5bbdcdEric Paris if (strcmp(ptr->dir, homedir) == 0) { 174915b5f885f030aa24a2ca648a184fa02cb5bbdcdEric Paris return 1; 175915b5f885f030aa24a2ca648a184fa02cb5bbdcdEric Paris } 176915b5f885f030aa24a2ca648a184fa02cb5bbdcdEric Paris ptr = ptr->next; 177915b5f885f030aa24a2ca648a184fa02cb5bbdcdEric Paris } 178915b5f885f030aa24a2ca648a184fa02cb5bbdcdEric Paris return 0; 179915b5f885f030aa24a2ca648a184fa02cb5bbdcdEric Paris} 180915b5f885f030aa24a2ca648a184fa02cb5bbdcdEric Paris 18188e334f1923396d5ace56b8439c731dcde0d1f3bGary Tierneystatic int prefix_is_homedir_role(const semanage_user_t *user, 18288e334f1923396d5ace56b8439c731dcde0d1f3bGary Tierney const char *prefix) 18388e334f1923396d5ace56b8439c731dcde0d1f3bGary Tierney{ 18488e334f1923396d5ace56b8439c731dcde0d1f3bGary Tierney return strcmp(OBJECT_R, prefix) == 0 || 18588e334f1923396d5ace56b8439c731dcde0d1f3bGary Tierney semanage_user_has_role(user, prefix); 18688e334f1923396d5ace56b8439c731dcde0d1f3bGary Tierney} 18788e334f1923396d5ace56b8439c731dcde0d1f3bGary Tierney 18813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindlestatic semanage_list_t *default_shell_list(void) 18913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle{ 19013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle semanage_list_t *list = NULL; 19113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 19213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (semanage_list_push(&list, "/bin/csh") 19313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle || semanage_list_push(&list, "/bin/tcsh") 19413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle || semanage_list_push(&list, "/bin/ksh") 19513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle || semanage_list_push(&list, "/bin/bsh") 19613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle || semanage_list_push(&list, "/bin/ash") 19713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle || semanage_list_push(&list, "/usr/bin/ksh") 19813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle || semanage_list_push(&list, "/usr/bin/pdksh") 19913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle || semanage_list_push(&list, "/bin/zsh") 20013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle || semanage_list_push(&list, "/bin/sh") 20113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle || semanage_list_push(&list, "/bin/bash")) 20213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle goto fail; 20313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 20413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return list; 20513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 20613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle fail: 20713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle semanage_list_destroy(&list); 20813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return NULL; 20913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle} 21013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 21113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindlestatic semanage_list_t *get_shell_list(void) 21213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle{ 21313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle FILE *shells; 21413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle char *temp = NULL; 21513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle semanage_list_t *list = NULL; 21613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle size_t buff_len = 0; 21713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle ssize_t len; 21813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 21913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle shells = fopen(PATH_SHELLS_FILE, "r"); 22013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (!shells) 22113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return default_shell_list(); 22213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle while ((len = getline(&temp, &buff_len, shells)) > 0) { 22313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (temp[len-1] == '\n') temp[len-1] = 0; 22413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (strcmp(temp, PATH_NOLOGIN_SHELL)) { 22513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (semanage_list_push(&list, temp)) { 22613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle free(temp); 22713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle semanage_list_destroy(&list); 22813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return default_shell_list(); 22913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 23013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 23113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 23213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle free(temp); 23313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 23413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return list; 23513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle} 23613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 23713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle/* Helper function called via semanage_fcontext_iterate() */ 23813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindlestatic int fcontext_matches(const semanage_fcontext_t *fcontext, void *varg) 23913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle{ 24013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle const char *oexpr = semanage_fcontext_get_expr(fcontext); 24113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle fc_match_handle_t *handp = varg; 242300b8ad4235688171f2a91e7aeb14d0ee3561c13Nicolas Iooss char *expr = NULL; 24313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle regex_t re; 24413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle int type, retval = -1; 245300b8ad4235688171f2a91e7aeb14d0ee3561c13Nicolas Iooss size_t len; 24613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 24713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle /* Only match ALL or DIR */ 24813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle type = semanage_fcontext_get_type(fcontext); 2495b0ad2f00ec730b86eb871d30cb98661dc7a6554Nicolas Iooss if (type != SEMANAGE_FCONTEXT_ALL && type != SEMANAGE_FCONTEXT_DIR) 25013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return 0; 25113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 252300b8ad4235688171f2a91e7aeb14d0ee3561c13Nicolas Iooss len = strlen(oexpr); 253300b8ad4235688171f2a91e7aeb14d0ee3561c13Nicolas Iooss /* Define a macro to strip a literal string from the end of oexpr */ 254300b8ad4235688171f2a91e7aeb14d0ee3561c13Nicolas Iooss#define rstrip_oexpr_len(cstr, cstrlen) \ 255300b8ad4235688171f2a91e7aeb14d0ee3561c13Nicolas Iooss do { \ 256300b8ad4235688171f2a91e7aeb14d0ee3561c13Nicolas Iooss if (len >= (cstrlen) && !strncmp(oexpr + len - (cstrlen), (cstr), (cstrlen))) \ 257300b8ad4235688171f2a91e7aeb14d0ee3561c13Nicolas Iooss len -= (cstrlen); \ 258300b8ad4235688171f2a91e7aeb14d0ee3561c13Nicolas Iooss } while (0) 259300b8ad4235688171f2a91e7aeb14d0ee3561c13Nicolas Iooss#define rstrip_oexpr(cstr) rstrip_oexpr_len(cstr, sizeof(cstr) - 1) 260300b8ad4235688171f2a91e7aeb14d0ee3561c13Nicolas Iooss 261300b8ad4235688171f2a91e7aeb14d0ee3561c13Nicolas Iooss rstrip_oexpr(".+"); 262300b8ad4235688171f2a91e7aeb14d0ee3561c13Nicolas Iooss rstrip_oexpr(".*"); 263300b8ad4235688171f2a91e7aeb14d0ee3561c13Nicolas Iooss rstrip_oexpr("(/.*)?"); 264300b8ad4235688171f2a91e7aeb14d0ee3561c13Nicolas Iooss rstrip_oexpr("/"); 265300b8ad4235688171f2a91e7aeb14d0ee3561c13Nicolas Iooss 266300b8ad4235688171f2a91e7aeb14d0ee3561c13Nicolas Iooss#undef rstrip_oexpr_len 267300b8ad4235688171f2a91e7aeb14d0ee3561c13Nicolas Iooss#undef rstrip_oexpr 268300b8ad4235688171f2a91e7aeb14d0ee3561c13Nicolas Iooss 269300b8ad4235688171f2a91e7aeb14d0ee3561c13Nicolas Iooss /* Anchor oexpr at the beginning and append pattern to eat up trailing slashes */ 270300b8ad4235688171f2a91e7aeb14d0ee3561c13Nicolas Iooss if (asprintf(&expr, "^%.*s/*$", (int)len, oexpr) < 0) 271300b8ad4235688171f2a91e7aeb14d0ee3561c13Nicolas Iooss return -1; 27213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 27313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle /* Check dir against expr */ 274300b8ad4235688171f2a91e7aeb14d0ee3561c13Nicolas Iooss if (regcomp(&re, expr, REG_EXTENDED) != 0) 27513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle goto done; 27613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (regexec(&re, handp->dir, 0, NULL, 0) == 0) 27713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle handp->matched = 1; 27813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle regfree(&re); 27913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 28013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle retval = 0; 28113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 28213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindledone: 283300b8ad4235688171f2a91e7aeb14d0ee3561c13Nicolas Iooss free(expr); 28413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 28513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return retval; 28613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle} 28713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 28813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindlestatic semanage_list_t *get_home_dirs(genhomedircon_settings_t * s) 28913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle{ 29013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle semanage_list_t *homedir_list = NULL; 29113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle semanage_list_t *shells = NULL; 29213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle fc_match_handle_t hand; 29313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle char *path = NULL; 294f18320d56330af157c19dfa63886119bac6cf082Manoj Srivastava uid_t temp, minuid = 500, maxuid = 60000; 29588f0c1aa6659f99a89770622f4bc2914435db1bbStephen Smalley int minuid_set = 0; 2962c651e0a2822368c74587efe6ec920e64e72f37bPatrick Steinhardt struct passwd *pwbuf; 29713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle struct stat buf; 29813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 29913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle path = semanage_findval(PATH_ETC_USERADD, "HOME", "="); 30013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (path && *path) { 30113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (semanage_list_push(&homedir_list, path)) 30213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle goto fail; 30313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 30413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle free(path); 30513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 30613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle path = semanage_findval(PATH_ETC_LIBUSER, "LU_HOMEDIRECTORY", "="); 30713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (path && *path) { 30813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (semanage_list_push(&homedir_list, path)) 30913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle goto fail; 31013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 31113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle free(path); 31213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle path = NULL; 31313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 31413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (!homedir_list) { 31513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (semanage_list_push(&homedir_list, PATH_DEFAULT_HOME)) { 31613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle goto fail; 31713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 31813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 31913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 32013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (!stat(PATH_EXPORT_HOME, &buf)) { 32113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (S_ISDIR(buf.st_mode)) { 32213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (semanage_list_push(&homedir_list, PATH_EXPORT_HOME)) { 32313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle goto fail; 32413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 32513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 32613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 32713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 32813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (!(s->usepasswd)) 32913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return homedir_list; 33013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 3315812ec2fbbb9e9244e31525737ea967c7a795252Eric Paris shells = get_shell_list(); 3325812ec2fbbb9e9244e31525737ea967c7a795252Eric Paris assert(shells); 3335812ec2fbbb9e9244e31525737ea967c7a795252Eric Paris 33413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle path = semanage_findval(PATH_ETC_LOGIN_DEFS, "UID_MIN", NULL); 33513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (path && *path) { 33613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle temp = atoi(path); 337d1c606ba46f661b950d6a6b2b29dfc07a536fb0aEric Paris minuid = temp; 338d1c606ba46f661b950d6a6b2b29dfc07a536fb0aEric Paris minuid_set = 1; 33913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 34013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle free(path); 34113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle path = NULL; 34213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 343f18320d56330af157c19dfa63886119bac6cf082Manoj Srivastava path = semanage_findval(PATH_ETC_LOGIN_DEFS, "UID_MAX", NULL); 344f18320d56330af157c19dfa63886119bac6cf082Manoj Srivastava if (path && *path) { 345f18320d56330af157c19dfa63886119bac6cf082Manoj Srivastava temp = atoi(path); 346f18320d56330af157c19dfa63886119bac6cf082Manoj Srivastava maxuid = temp; 347f18320d56330af157c19dfa63886119bac6cf082Manoj Srivastava } 348f18320d56330af157c19dfa63886119bac6cf082Manoj Srivastava free(path); 349f18320d56330af157c19dfa63886119bac6cf082Manoj Srivastava path = NULL; 350f18320d56330af157c19dfa63886119bac6cf082Manoj Srivastava 35113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle path = semanage_findval(PATH_ETC_LIBUSER, "LU_UIDNUMBER", "="); 35213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (path && *path) { 35313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle temp = atoi(path); 35413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (!minuid_set || temp < minuid) { 35513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle minuid = temp; 35613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle minuid_set = 1; 35713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 35813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 35913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle free(path); 36013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle path = NULL; 36113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 3622c651e0a2822368c74587efe6ec920e64e72f37bPatrick Steinhardt errno = 0; 36313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle setpwent(); 3642c651e0a2822368c74587efe6ec920e64e72f37bPatrick Steinhardt while ((pwbuf = getpwent()) != NULL) { 365f18320d56330af157c19dfa63886119bac6cf082Manoj Srivastava if (pwbuf->pw_uid < minuid || pwbuf->pw_uid > maxuid) 36613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle continue; 36713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (!semanage_list_find(shells, pwbuf->pw_shell)) 36813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle continue; 369faff0a77c679e8290bac6595c9764dc8929f32d6Daniel J Walsh int len = strlen(pwbuf->pw_dir) -1; 370faff0a77c679e8290bac6595c9764dc8929f32d6Daniel J Walsh for(; len > 0 && pwbuf->pw_dir[len] == '/'; len--) { 371faff0a77c679e8290bac6595c9764dc8929f32d6Daniel J Walsh pwbuf->pw_dir[len] = '\0'; 372faff0a77c679e8290bac6595c9764dc8929f32d6Daniel J Walsh } 37313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (strcmp(pwbuf->pw_dir, "/") == 0) 37413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle continue; 375915b5f885f030aa24a2ca648a184fa02cb5bbdcdEric Paris if (ignore(pwbuf->pw_dir)) 376915b5f885f030aa24a2ca648a184fa02cb5bbdcdEric Paris continue; 37713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (semanage_str_count(pwbuf->pw_dir, '/') <= 1) 37813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle continue; 37913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (!(path = strdup(pwbuf->pw_dir))) { 38013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle break; 38113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 38213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 38313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle semanage_rtrim(path, '/'); 38413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 38513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (!semanage_list_find(homedir_list, path)) { 38613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle /* 38713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle * Now check for an existing file context that matches 38813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle * so we don't label a non-homedir as a homedir. 38913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle */ 39013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle hand.dir = path; 39113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle hand.matched = 0; 39213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (semanage_fcontext_iterate(s->h_semanage, 39313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle fcontext_matches, &hand) == STATUS_ERR) 39413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle goto fail; 39513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 39613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle /* NOTE: old genhomedircon printed a warning on match */ 39713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (hand.matched) { 398f18320d56330af157c19dfa63886119bac6cf082Manoj Srivastava WARN(s->h_semanage, "%s homedir %s or its parent directory conflicts with a file context already specified in the policy. This usually indicates an incorrectly defined system account. If it is a system account please make sure its uid is less than %u or greater than %u or its login shell is /sbin/nologin.", pwbuf->pw_name, pwbuf->pw_dir, minuid, maxuid); 39913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } else { 40013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (semanage_list_push(&homedir_list, path)) 40113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle goto fail; 40213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 40313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 40413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle free(path); 40513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle path = NULL; 4062c651e0a2822368c74587efe6ec920e64e72f37bPatrick Steinhardt errno = 0; 40713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 40813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 4092c651e0a2822368c74587efe6ec920e64e72f37bPatrick Steinhardt if (errno) { 41013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle WARN(s->h_semanage, "Error while fetching users. " 41113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle "Returning list so far."); 41213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 413e1400f04044e8405419ee4534f8ff4f45c5d532aEric Paris 414e1400f04044e8405419ee4534f8ff4f45c5d532aEric Paris if (semanage_list_sort(&homedir_list)) 415e1400f04044e8405419ee4534f8ff4f45c5d532aEric Paris goto fail; 416e1400f04044e8405419ee4534f8ff4f45c5d532aEric Paris 41713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle endpwent(); 41813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle semanage_list_destroy(&shells); 41913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 42013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return homedir_list; 42113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 42213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle fail: 42313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle endpwent(); 42413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle free(path); 42513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle semanage_list_destroy(&homedir_list); 42613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle semanage_list_destroy(&shells); 42713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return NULL; 42813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle} 42913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 43013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle/** 43113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle * @param out the FILE to put all the output in. 43213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle * @return 0 on success 43313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle */ 434d67b1ea1cbe30afb4894634f06ca25916b03cbd7Eric Parisstatic int write_file_context_header(FILE * out) 43513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle{ 43613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (fprintf(out, COMMENT_FILE_CONTEXT_HEADER) < 0) { 43713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return STATUS_ERR; 43813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 43913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 44013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return STATUS_SUCCESS; 44113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle} 44213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 44313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle/* Predicates for use with semanage_slurp_file_filter() the homedir_template 44413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle * file currently contains lines that serve as the template for a user's 44513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle * homedir. 44613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle * 44713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle * It also contains lines that are the template for the parent of a 44813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle * user's home directory. 44913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle * 45013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle * Currently, the only lines that apply to the the root of a user's home 45113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle * directory are all prefixed with the string "HOME_ROOT". All other 45213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle * lines apply to a user's home directory. If this changes the 45313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle * following predicates need to change to reflect that. 45413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle */ 45513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindlestatic int HOME_ROOT_PRED(const char *string) 45613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle{ 45713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return semanage_is_prefix(string, TEMPLATE_HOME_ROOT); 45813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle} 45913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 46013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindlestatic int HOME_DIR_PRED(const char *string) 46113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle{ 46213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return semanage_is_prefix(string, TEMPLATE_HOME_DIR); 46313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle} 46413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 46508cde98b606cd04e26061d16ec537a2549f5199cJason Zaman/* new names */ 46608cde98b606cd04e26061d16ec537a2549f5199cJason Zamanstatic int USERNAME_CONTEXT_PRED(const char *string) 46708cde98b606cd04e26061d16ec537a2549f5199cJason Zaman{ 46808cde98b606cd04e26061d16ec537a2549f5199cJason Zaman return (int)( 46908cde98b606cd04e26061d16ec537a2549f5199cJason Zaman (strstr(string, TEMPLATE_USERNAME) != NULL) || 47008cde98b606cd04e26061d16ec537a2549f5199cJason Zaman (strstr(string, TEMPLATE_USERID) != NULL) 47108cde98b606cd04e26061d16ec537a2549f5199cJason Zaman ); 47208cde98b606cd04e26061d16ec537a2549f5199cJason Zaman} 47308cde98b606cd04e26061d16ec537a2549f5199cJason Zaman 47408cde98b606cd04e26061d16ec537a2549f5199cJason Zaman/* This will never match USER if USERNAME or USERID are found. */ 47513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindlestatic int USER_CONTEXT_PRED(const char *string) 47613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle{ 47708cde98b606cd04e26061d16ec537a2549f5199cJason Zaman if (USERNAME_CONTEXT_PRED(string)) 47808cde98b606cd04e26061d16ec537a2549f5199cJason Zaman return 0; 47908cde98b606cd04e26061d16ec537a2549f5199cJason Zaman 48013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return (int)(strstr(string, TEMPLATE_USER) != NULL); 48113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle} 48213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 48367b328a91c6f6f22d8eaf220aaefe06623112f32Gary Tierneystatic int STR_COMPARATOR(const void *a, const void *b) 48467b328a91c6f6f22d8eaf220aaefe06623112f32Gary Tierney{ 48567b328a91c6f6f22d8eaf220aaefe06623112f32Gary Tierney return strcmp((const char *) a, (const char *) b); 48667b328a91c6f6f22d8eaf220aaefe06623112f32Gary Tierney} 48767b328a91c6f6f22d8eaf220aaefe06623112f32Gary Tierney 48813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle/* make_tempate 48913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle * @param s the settings holding the paths to various files 49013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle * @param pred function pointer to function to use as filter for slurp 49113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle * file filter 49213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle * @return a list of lines from the template file with inappropriate 49313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle * lines filtered out. 49413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle */ 49513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindlestatic semanage_list_t *make_template(genhomedircon_settings_t * s, 49613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle int (*pred) (const char *)) 49713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle{ 49813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle FILE *template_file = NULL; 49913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle semanage_list_t *template_data = NULL; 50013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 50113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle template_file = fopen(s->homedir_template_path, "r"); 50213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (!template_file) 50313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return NULL; 50413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle template_data = semanage_slurp_file_filter(template_file, pred); 50513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle fclose(template_file); 50613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 50713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return template_data; 50813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle} 50913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 510300b8ad4235688171f2a91e7aeb14d0ee3561c13Nicolas Ioossstatic char *replace_all(const char *str, const replacement_pair_t * repl) 51113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle{ 512300b8ad4235688171f2a91e7aeb14d0ee3561c13Nicolas Iooss char *retval, *retval2; 51313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle int i; 51413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 51513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (!str || !repl) 516300b8ad4235688171f2a91e7aeb14d0ee3561c13Nicolas Iooss return NULL; 51713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 518300b8ad4235688171f2a91e7aeb14d0ee3561c13Nicolas Iooss retval = strdup(str); 519300b8ad4235688171f2a91e7aeb14d0ee3561c13Nicolas Iooss for (i = 0; retval != NULL && repl[i].search_for; i++) { 520300b8ad4235688171f2a91e7aeb14d0ee3561c13Nicolas Iooss retval2 = semanage_str_replace(repl[i].search_for, 521300b8ad4235688171f2a91e7aeb14d0ee3561c13Nicolas Iooss repl[i].replace_with, retval, 0); 522300b8ad4235688171f2a91e7aeb14d0ee3561c13Nicolas Iooss free(retval); 523300b8ad4235688171f2a91e7aeb14d0ee3561c13Nicolas Iooss retval = retval2; 52413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 52513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return retval; 52613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle} 52713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 528300b8ad4235688171f2a91e7aeb14d0ee3561c13Nicolas Ioossstatic const char *extract_context(const char *line) 52913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle{ 530300b8ad4235688171f2a91e7aeb14d0ee3561c13Nicolas Iooss const char *p = line; 531300b8ad4235688171f2a91e7aeb14d0ee3561c13Nicolas Iooss size_t off; 532300b8ad4235688171f2a91e7aeb14d0ee3561c13Nicolas Iooss 533300b8ad4235688171f2a91e7aeb14d0ee3561c13Nicolas Iooss off = strlen(p); 534300b8ad4235688171f2a91e7aeb14d0ee3561c13Nicolas Iooss p += off; 535300b8ad4235688171f2a91e7aeb14d0ee3561c13Nicolas Iooss /* consider trailing whitespaces */ 536300b8ad4235688171f2a91e7aeb14d0ee3561c13Nicolas Iooss while (off > 0) { 537300b8ad4235688171f2a91e7aeb14d0ee3561c13Nicolas Iooss p--; 538300b8ad4235688171f2a91e7aeb14d0ee3561c13Nicolas Iooss off--; 539300b8ad4235688171f2a91e7aeb14d0ee3561c13Nicolas Iooss if (!isspace(*p)) 540300b8ad4235688171f2a91e7aeb14d0ee3561c13Nicolas Iooss break; 541300b8ad4235688171f2a91e7aeb14d0ee3561c13Nicolas Iooss } 542300b8ad4235688171f2a91e7aeb14d0ee3561c13Nicolas Iooss if (off == 0) 54313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return NULL; 544300b8ad4235688171f2a91e7aeb14d0ee3561c13Nicolas Iooss 545300b8ad4235688171f2a91e7aeb14d0ee3561c13Nicolas Iooss /* find the last field in line */ 546300b8ad4235688171f2a91e7aeb14d0ee3561c13Nicolas Iooss while (off > 0 && !isspace(*(p - 1))) { 547300b8ad4235688171f2a91e7aeb14d0ee3561c13Nicolas Iooss p--; 548300b8ad4235688171f2a91e7aeb14d0ee3561c13Nicolas Iooss off--; 549300b8ad4235688171f2a91e7aeb14d0ee3561c13Nicolas Iooss } 550300b8ad4235688171f2a91e7aeb14d0ee3561c13Nicolas Iooss return p; 55113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle} 55213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 553300b8ad4235688171f2a91e7aeb14d0ee3561c13Nicolas Ioossstatic int check_line(genhomedircon_settings_t * s, const char *line) 55413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle{ 55513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle sepol_context_t *ctx_record = NULL; 55613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle const char *ctx_str; 55713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle int result; 55813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 55913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle ctx_str = extract_context(line); 56013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (!ctx_str) 56113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return STATUS_ERR; 56213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 56313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle result = sepol_context_from_string(s->h_semanage->sepolh, 56413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle ctx_str, &ctx_record); 56513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (result == STATUS_SUCCESS && ctx_record != NULL) { 56613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle result = sepol_context_check(s->h_semanage->sepolh, 56713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle s->policydb, ctx_record); 56813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle sepol_context_free(ctx_record); 56913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 57013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return result; 57113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle} 57213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 573a63b96b7e2d3edb4b3b1283558da7ca6735d66daJason Zamanstatic int write_replacements(genhomedircon_settings_t * s, FILE * out, 574a63b96b7e2d3edb4b3b1283558da7ca6735d66daJason Zaman const semanage_list_t * tpl, 575a63b96b7e2d3edb4b3b1283558da7ca6735d66daJason Zaman const replacement_pair_t *repl) 57613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle{ 577300b8ad4235688171f2a91e7aeb14d0ee3561c13Nicolas Iooss char *line; 57813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 57913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle for (; tpl; tpl = tpl->next) { 58013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle line = replace_all(tpl->data, repl); 58113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (!line) 58213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle goto fail; 58313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (check_line(s, line) == STATUS_SUCCESS) { 584300b8ad4235688171f2a91e7aeb14d0ee3561c13Nicolas Iooss if (fprintf(out, "%s\n", line) < 0) 58513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle goto fail; 58613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 587300b8ad4235688171f2a91e7aeb14d0ee3561c13Nicolas Iooss free(line); 58813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 58913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return STATUS_SUCCESS; 59013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 59113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle fail: 592300b8ad4235688171f2a91e7aeb14d0ee3561c13Nicolas Iooss free(line); 59313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return STATUS_ERR; 59413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle} 59513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 596d97292639cf816a946919aa0f2ed086f14c7db44Gary Tierneystatic int write_contexts(genhomedircon_settings_t *s, FILE *out, 597d97292639cf816a946919aa0f2ed086f14c7db44Gary Tierney semanage_list_t *tpl, const replacement_pair_t *repl, 598d97292639cf816a946919aa0f2ed086f14c7db44Gary Tierney const genhomedircon_user_entry_t *user) 599d97292639cf816a946919aa0f2ed086f14c7db44Gary Tierney{ 600300b8ad4235688171f2a91e7aeb14d0ee3561c13Nicolas Iooss char *line, *temp; 60103298a22f7dc6f45885307976d09c9a2f070f9fdNicolas Iooss sepol_context_t *context; 60203298a22f7dc6f45885307976d09c9a2f070f9fdNicolas Iooss char *new_context_str; 603d97292639cf816a946919aa0f2ed086f14c7db44Gary Tierney 604d97292639cf816a946919aa0f2ed086f14c7db44Gary Tierney for (; tpl; tpl = tpl->next) { 60503298a22f7dc6f45885307976d09c9a2f070f9fdNicolas Iooss context = NULL; 60603298a22f7dc6f45885307976d09c9a2f070f9fdNicolas Iooss new_context_str = NULL; 607d97292639cf816a946919aa0f2ed086f14c7db44Gary Tierney line = replace_all(tpl->data, repl); 608d97292639cf816a946919aa0f2ed086f14c7db44Gary Tierney if (!line) { 609d97292639cf816a946919aa0f2ed086f14c7db44Gary Tierney goto fail; 610d97292639cf816a946919aa0f2ed086f14c7db44Gary Tierney } 611d97292639cf816a946919aa0f2ed086f14c7db44Gary Tierney 612d97292639cf816a946919aa0f2ed086f14c7db44Gary Tierney const char *old_context_str = extract_context(line); 613d97292639cf816a946919aa0f2ed086f14c7db44Gary Tierney if (!old_context_str) { 614d97292639cf816a946919aa0f2ed086f14c7db44Gary Tierney goto fail; 615d97292639cf816a946919aa0f2ed086f14c7db44Gary Tierney } 616d97292639cf816a946919aa0f2ed086f14c7db44Gary Tierney 617d97292639cf816a946919aa0f2ed086f14c7db44Gary Tierney if (strcmp(old_context_str, CONTEXT_NONE) == 0) { 618d97292639cf816a946919aa0f2ed086f14c7db44Gary Tierney if (check_line(s, line) == STATUS_SUCCESS && 619300b8ad4235688171f2a91e7aeb14d0ee3561c13Nicolas Iooss fprintf(out, "%s\n", line) < 0) { 620d97292639cf816a946919aa0f2ed086f14c7db44Gary Tierney goto fail; 621d97292639cf816a946919aa0f2ed086f14c7db44Gary Tierney } 622300b8ad4235688171f2a91e7aeb14d0ee3561c13Nicolas Iooss free(line); 623d97292639cf816a946919aa0f2ed086f14c7db44Gary Tierney continue; 624d97292639cf816a946919aa0f2ed086f14c7db44Gary Tierney } 625d97292639cf816a946919aa0f2ed086f14c7db44Gary Tierney 626d97292639cf816a946919aa0f2ed086f14c7db44Gary Tierney sepol_handle_t *sepolh = s->h_semanage->sepolh; 627d97292639cf816a946919aa0f2ed086f14c7db44Gary Tierney 628d97292639cf816a946919aa0f2ed086f14c7db44Gary Tierney if (sepol_context_from_string(sepolh, old_context_str, 629d97292639cf816a946919aa0f2ed086f14c7db44Gary Tierney &context) < 0) { 630d97292639cf816a946919aa0f2ed086f14c7db44Gary Tierney goto fail; 631d97292639cf816a946919aa0f2ed086f14c7db44Gary Tierney } 632d97292639cf816a946919aa0f2ed086f14c7db44Gary Tierney 6334cf9b9ce2df06fd5a29e5264a6552c9b02ec0b5bStephen Smalley if (sepol_context_set_user(sepolh, context, user->sename) < 0) { 6344cf9b9ce2df06fd5a29e5264a6552c9b02ec0b5bStephen Smalley goto fail; 6354cf9b9ce2df06fd5a29e5264a6552c9b02ec0b5bStephen Smalley } 6364cf9b9ce2df06fd5a29e5264a6552c9b02ec0b5bStephen Smalley 6374cf9b9ce2df06fd5a29e5264a6552c9b02ec0b5bStephen Smalley if (sepol_policydb_mls_enabled(s->policydb) && 638d97292639cf816a946919aa0f2ed086f14c7db44Gary Tierney sepol_context_set_mls(sepolh, context, user->level) < 0) { 639d97292639cf816a946919aa0f2ed086f14c7db44Gary Tierney goto fail; 640d97292639cf816a946919aa0f2ed086f14c7db44Gary Tierney } 641d97292639cf816a946919aa0f2ed086f14c7db44Gary Tierney 64288e334f1923396d5ace56b8439c731dcde0d1f3bGary Tierney if (user->homedir_role && 64388e334f1923396d5ace56b8439c731dcde0d1f3bGary Tierney sepol_context_set_role(sepolh, context, user->homedir_role) < 0) { 64488e334f1923396d5ace56b8439c731dcde0d1f3bGary Tierney goto fail; 64588e334f1923396d5ace56b8439c731dcde0d1f3bGary Tierney } 64688e334f1923396d5ace56b8439c731dcde0d1f3bGary Tierney 647d97292639cf816a946919aa0f2ed086f14c7db44Gary Tierney if (sepol_context_to_string(sepolh, context, 648d97292639cf816a946919aa0f2ed086f14c7db44Gary Tierney &new_context_str) < 0) { 649d97292639cf816a946919aa0f2ed086f14c7db44Gary Tierney goto fail; 650d97292639cf816a946919aa0f2ed086f14c7db44Gary Tierney } 651d97292639cf816a946919aa0f2ed086f14c7db44Gary Tierney 652300b8ad4235688171f2a91e7aeb14d0ee3561c13Nicolas Iooss temp = semanage_str_replace(old_context_str, new_context_str, 653300b8ad4235688171f2a91e7aeb14d0ee3561c13Nicolas Iooss line, 1); 654300b8ad4235688171f2a91e7aeb14d0ee3561c13Nicolas Iooss if (!temp) { 655d97292639cf816a946919aa0f2ed086f14c7db44Gary Tierney goto fail; 656d97292639cf816a946919aa0f2ed086f14c7db44Gary Tierney } 657300b8ad4235688171f2a91e7aeb14d0ee3561c13Nicolas Iooss free(line); 658300b8ad4235688171f2a91e7aeb14d0ee3561c13Nicolas Iooss line = temp; 659d97292639cf816a946919aa0f2ed086f14c7db44Gary Tierney 660d97292639cf816a946919aa0f2ed086f14c7db44Gary Tierney if (check_line(s, line) == STATUS_SUCCESS) { 661300b8ad4235688171f2a91e7aeb14d0ee3561c13Nicolas Iooss if (fprintf(out, "%s\n", line) < 0) 662d97292639cf816a946919aa0f2ed086f14c7db44Gary Tierney goto fail; 663d97292639cf816a946919aa0f2ed086f14c7db44Gary Tierney } 664d97292639cf816a946919aa0f2ed086f14c7db44Gary Tierney 665300b8ad4235688171f2a91e7aeb14d0ee3561c13Nicolas Iooss free(line); 666d97292639cf816a946919aa0f2ed086f14c7db44Gary Tierney sepol_context_free(context); 667d97292639cf816a946919aa0f2ed086f14c7db44Gary Tierney free(new_context_str); 668d97292639cf816a946919aa0f2ed086f14c7db44Gary Tierney } 669d97292639cf816a946919aa0f2ed086f14c7db44Gary Tierney 670d97292639cf816a946919aa0f2ed086f14c7db44Gary Tierney return STATUS_SUCCESS; 671d97292639cf816a946919aa0f2ed086f14c7db44Gary Tierneyfail: 672300b8ad4235688171f2a91e7aeb14d0ee3561c13Nicolas Iooss free(line); 673d97292639cf816a946919aa0f2ed086f14c7db44Gary Tierney sepol_context_free(context); 674d97292639cf816a946919aa0f2ed086f14c7db44Gary Tierney free(new_context_str); 675d97292639cf816a946919aa0f2ed086f14c7db44Gary Tierney return STATUS_ERR; 676d97292639cf816a946919aa0f2ed086f14c7db44Gary Tierney} 677d97292639cf816a946919aa0f2ed086f14c7db44Gary Tierney 678a63b96b7e2d3edb4b3b1283558da7ca6735d66daJason Zamanstatic int write_home_dir_context(genhomedircon_settings_t * s, FILE * out, 679c90780aaf767485fbdc063eab905422d756f22b5Jason Zaman semanage_list_t * tpl, const genhomedircon_user_entry_t *user) 680a63b96b7e2d3edb4b3b1283558da7ca6735d66daJason Zaman{ 681a63b96b7e2d3edb4b3b1283558da7ca6735d66daJason Zaman replacement_pair_t repl[] = { 682c90780aaf767485fbdc063eab905422d756f22b5Jason Zaman {.search_for = TEMPLATE_HOME_DIR,.replace_with = user->home}, 683c90780aaf767485fbdc063eab905422d756f22b5Jason Zaman {.search_for = TEMPLATE_ROLE,.replace_with = user->prefix}, 684a63b96b7e2d3edb4b3b1283558da7ca6735d66daJason Zaman {NULL, NULL} 685a63b96b7e2d3edb4b3b1283558da7ca6735d66daJason Zaman }; 686a63b96b7e2d3edb4b3b1283558da7ca6735d66daJason Zaman 687c90780aaf767485fbdc063eab905422d756f22b5Jason Zaman if (strcmp(user->name, FALLBACK_NAME) == 0) { 688c90780aaf767485fbdc063eab905422d756f22b5Jason Zaman if (fprintf(out, COMMENT_USER_HOME_CONTEXT, FALLBACK_SENAME) < 0) 689c90780aaf767485fbdc063eab905422d756f22b5Jason Zaman return STATUS_ERR; 690c90780aaf767485fbdc063eab905422d756f22b5Jason Zaman } else { 691c90780aaf767485fbdc063eab905422d756f22b5Jason Zaman if (fprintf(out, COMMENT_USER_HOME_CONTEXT, user->name) < 0) 692c90780aaf767485fbdc063eab905422d756f22b5Jason Zaman return STATUS_ERR; 693c90780aaf767485fbdc063eab905422d756f22b5Jason Zaman } 694a63b96b7e2d3edb4b3b1283558da7ca6735d66daJason Zaman 695d97292639cf816a946919aa0f2ed086f14c7db44Gary Tierney return write_contexts(s, out, tpl, repl, user); 696a63b96b7e2d3edb4b3b1283558da7ca6735d66daJason Zaman} 697a63b96b7e2d3edb4b3b1283558da7ca6735d66daJason Zaman 69813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindlestatic int write_home_root_context(genhomedircon_settings_t * s, FILE * out, 69913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle semanage_list_t * tpl, char *homedir) 70013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle{ 70113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle replacement_pair_t repl[] = { 70213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle {.search_for = TEMPLATE_HOME_ROOT,.replace_with = homedir}, 70313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle {NULL, NULL} 70413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle }; 70513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 706a63b96b7e2d3edb4b3b1283558da7ca6735d66daJason Zaman return write_replacements(s, out, tpl, repl); 70713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle} 70813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 7094bbec88baa66d1376629fb6f860eb51657429b91Jason Zamanstatic int write_username_context(genhomedircon_settings_t * s, FILE * out, 7104bbec88baa66d1376629fb6f860eb51657429b91Jason Zaman semanage_list_t * tpl, 7114bbec88baa66d1376629fb6f860eb51657429b91Jason Zaman const genhomedircon_user_entry_t *user) 7124bbec88baa66d1376629fb6f860eb51657429b91Jason Zaman{ 7134bbec88baa66d1376629fb6f860eb51657429b91Jason Zaman replacement_pair_t repl[] = { 7144bbec88baa66d1376629fb6f860eb51657429b91Jason Zaman {.search_for = TEMPLATE_USERNAME,.replace_with = user->name}, 7154bbec88baa66d1376629fb6f860eb51657429b91Jason Zaman {.search_for = TEMPLATE_USERID,.replace_with = user->uid}, 7164bbec88baa66d1376629fb6f860eb51657429b91Jason Zaman {.search_for = TEMPLATE_ROLE,.replace_with = user->prefix}, 7174bbec88baa66d1376629fb6f860eb51657429b91Jason Zaman {NULL, NULL} 7184bbec88baa66d1376629fb6f860eb51657429b91Jason Zaman }; 7194bbec88baa66d1376629fb6f860eb51657429b91Jason Zaman 720d97292639cf816a946919aa0f2ed086f14c7db44Gary Tierney return write_contexts(s, out, tpl, repl, user); 7214bbec88baa66d1376629fb6f860eb51657429b91Jason Zaman} 7224bbec88baa66d1376629fb6f860eb51657429b91Jason Zaman 72313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindlestatic int write_user_context(genhomedircon_settings_t * s, FILE * out, 724c90780aaf767485fbdc063eab905422d756f22b5Jason Zaman semanage_list_t * tpl, const genhomedircon_user_entry_t *user) 72513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle{ 72613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle replacement_pair_t repl[] = { 727c90780aaf767485fbdc063eab905422d756f22b5Jason Zaman {.search_for = TEMPLATE_USER,.replace_with = user->name}, 728c90780aaf767485fbdc063eab905422d756f22b5Jason Zaman {.search_for = TEMPLATE_ROLE,.replace_with = user->prefix}, 72913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle {NULL, NULL} 73013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle }; 73113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 732d97292639cf816a946919aa0f2ed086f14c7db44Gary Tierney return write_contexts(s, out, tpl, repl, user); 73313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle} 73413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 73567b328a91c6f6f22d8eaf220aaefe06623112f32Gary Tierneystatic int seuser_sort_func(const void *arg1, const void *arg2) 73667b328a91c6f6f22d8eaf220aaefe06623112f32Gary Tierney{ 73767b328a91c6f6f22d8eaf220aaefe06623112f32Gary Tierney const semanage_seuser_t **u1 = (const semanage_seuser_t **) arg1; 73867b328a91c6f6f22d8eaf220aaefe06623112f32Gary Tierney const semanage_seuser_t **u2 = (const semanage_seuser_t **) arg2;; 73967b328a91c6f6f22d8eaf220aaefe06623112f32Gary Tierney const char *name1 = semanage_seuser_get_name(*u1); 74067b328a91c6f6f22d8eaf220aaefe06623112f32Gary Tierney const char *name2 = semanage_seuser_get_name(*u2); 74167b328a91c6f6f22d8eaf220aaefe06623112f32Gary Tierney 74267b328a91c6f6f22d8eaf220aaefe06623112f32Gary Tierney if (name1[0] == '%' && name2[0] == '%') { 74367b328a91c6f6f22d8eaf220aaefe06623112f32Gary Tierney return 0; 74467b328a91c6f6f22d8eaf220aaefe06623112f32Gary Tierney } else if (name1[0] == '%') { 74567b328a91c6f6f22d8eaf220aaefe06623112f32Gary Tierney return 1; 74667b328a91c6f6f22d8eaf220aaefe06623112f32Gary Tierney } else if (name2[0] == '%') { 74767b328a91c6f6f22d8eaf220aaefe06623112f32Gary Tierney return -1; 74867b328a91c6f6f22d8eaf220aaefe06623112f32Gary Tierney } 74967b328a91c6f6f22d8eaf220aaefe06623112f32Gary Tierney 75067b328a91c6f6f22d8eaf220aaefe06623112f32Gary Tierney return strcmp(name1, name2); 75167b328a91c6f6f22d8eaf220aaefe06623112f32Gary Tierney} 75267b328a91c6f6f22d8eaf220aaefe06623112f32Gary Tierney 75313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindlestatic int user_sort_func(semanage_user_t ** arg1, semanage_user_t ** arg2) 75413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle{ 75513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return strcmp(semanage_user_get_name(*arg1), 75613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle semanage_user_get_name(*arg2)); 75713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle} 75813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 75913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindlestatic int name_user_cmp(char *key, semanage_user_t ** val) 76013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle{ 76113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return strcmp(key, semanage_user_get_name(*val)); 76213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle} 76313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 76413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindlestatic int push_user_entry(genhomedircon_user_entry_t ** list, const char *n, 7653b23f12eb9aa2ee828561ffb414efa8c2031e75fJason Zaman const char *u, const char *g, const char *sen, 76667b328a91c6f6f22d8eaf220aaefe06623112f32Gary Tierney const char *pre, const char *h, const char *l, 76788e334f1923396d5ace56b8439c731dcde0d1f3bGary Tierney const char *ln, const char *hd_role) 76813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle{ 76913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle genhomedircon_user_entry_t *temp = NULL; 77013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle char *name = NULL; 7713b23f12eb9aa2ee828561ffb414efa8c2031e75fJason Zaman char *uid = NULL; 7723b23f12eb9aa2ee828561ffb414efa8c2031e75fJason Zaman char *gid = NULL; 77313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle char *sename = NULL; 77413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle char *prefix = NULL; 77513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle char *home = NULL; 776d784fd71b56cb8f57d5b9fcd784094e004bf7c6aRussell Coker char *level = NULL; 77767b328a91c6f6f22d8eaf220aaefe06623112f32Gary Tierney char *lname = NULL; 77888e334f1923396d5ace56b8439c731dcde0d1f3bGary Tierney char *homedir_role = NULL; 77913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 78013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle temp = malloc(sizeof(genhomedircon_user_entry_t)); 78113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (!temp) 78213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle goto cleanup; 78313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle name = strdup(n); 78413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (!name) 78513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle goto cleanup; 7863b23f12eb9aa2ee828561ffb414efa8c2031e75fJason Zaman uid = strdup(u); 7873b23f12eb9aa2ee828561ffb414efa8c2031e75fJason Zaman if (!uid) 7883b23f12eb9aa2ee828561ffb414efa8c2031e75fJason Zaman goto cleanup; 7893b23f12eb9aa2ee828561ffb414efa8c2031e75fJason Zaman gid = strdup(g); 7903b23f12eb9aa2ee828561ffb414efa8c2031e75fJason Zaman if (!gid) 7913b23f12eb9aa2ee828561ffb414efa8c2031e75fJason Zaman goto cleanup; 79213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle sename = strdup(sen); 79313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (!sename) 79413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle goto cleanup; 79513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle prefix = strdup(pre); 79613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (!prefix) 79713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle goto cleanup; 79813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle home = strdup(h); 79913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (!home) 80013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle goto cleanup; 801d784fd71b56cb8f57d5b9fcd784094e004bf7c6aRussell Coker level = strdup(l); 802d784fd71b56cb8f57d5b9fcd784094e004bf7c6aRussell Coker if (!level) 803d784fd71b56cb8f57d5b9fcd784094e004bf7c6aRussell Coker goto cleanup; 80467b328a91c6f6f22d8eaf220aaefe06623112f32Gary Tierney lname = strdup(ln); 80567b328a91c6f6f22d8eaf220aaefe06623112f32Gary Tierney if (!lname) 80667b328a91c6f6f22d8eaf220aaefe06623112f32Gary Tierney goto cleanup; 80788e334f1923396d5ace56b8439c731dcde0d1f3bGary Tierney if (hd_role) { 80888e334f1923396d5ace56b8439c731dcde0d1f3bGary Tierney homedir_role = strdup(hd_role); 80988e334f1923396d5ace56b8439c731dcde0d1f3bGary Tierney if (!homedir_role) 81088e334f1923396d5ace56b8439c731dcde0d1f3bGary Tierney goto cleanup; 81188e334f1923396d5ace56b8439c731dcde0d1f3bGary Tierney } 81213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 81313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle temp->name = name; 8143b23f12eb9aa2ee828561ffb414efa8c2031e75fJason Zaman temp->uid = uid; 8153b23f12eb9aa2ee828561ffb414efa8c2031e75fJason Zaman temp->gid = gid; 81613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle temp->sename = sename; 81713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle temp->prefix = prefix; 81813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle temp->home = home; 819d784fd71b56cb8f57d5b9fcd784094e004bf7c6aRussell Coker temp->level = level; 82067b328a91c6f6f22d8eaf220aaefe06623112f32Gary Tierney temp->login = lname; 82188e334f1923396d5ace56b8439c731dcde0d1f3bGary Tierney temp->homedir_role = homedir_role; 82213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle temp->next = (*list); 82313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle (*list) = temp; 82413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 82513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return STATUS_SUCCESS; 82613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 82713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle cleanup: 82813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle free(name); 8293b23f12eb9aa2ee828561ffb414efa8c2031e75fJason Zaman free(uid); 8303b23f12eb9aa2ee828561ffb414efa8c2031e75fJason Zaman free(gid); 83113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle free(sename); 83213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle free(prefix); 83313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle free(home); 834d784fd71b56cb8f57d5b9fcd784094e004bf7c6aRussell Coker free(level); 83567b328a91c6f6f22d8eaf220aaefe06623112f32Gary Tierney free(lname); 83688e334f1923396d5ace56b8439c731dcde0d1f3bGary Tierney free(homedir_role); 83713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle free(temp); 83813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return STATUS_ERR; 83913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle} 84013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 84113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindlestatic void pop_user_entry(genhomedircon_user_entry_t ** list) 84213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle{ 84313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle genhomedircon_user_entry_t *temp; 84413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 84513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (!list || !(*list)) 84613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return; 84713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 84813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle temp = *list; 84913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle *list = temp->next; 85013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle free(temp->name); 8513b23f12eb9aa2ee828561ffb414efa8c2031e75fJason Zaman free(temp->uid); 8523b23f12eb9aa2ee828561ffb414efa8c2031e75fJason Zaman free(temp->gid); 85313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle free(temp->sename); 85413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle free(temp->prefix); 85513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle free(temp->home); 856d784fd71b56cb8f57d5b9fcd784094e004bf7c6aRussell Coker free(temp->level); 85767b328a91c6f6f22d8eaf220aaefe06623112f32Gary Tierney free(temp->login); 85888e334f1923396d5ace56b8439c731dcde0d1f3bGary Tierney free(temp->homedir_role); 85913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle free(temp); 86013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle} 86113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 86213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindlestatic int setup_fallback_user(genhomedircon_settings_t * s) 86313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle{ 86413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle semanage_seuser_t **seuser_list = NULL; 86513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle unsigned int nseusers = 0; 86613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle semanage_user_key_t *key = NULL; 86713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle semanage_user_t *u = NULL; 86813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle const char *name = NULL; 86913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle const char *seuname = NULL; 87013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle const char *prefix = NULL; 871d784fd71b56cb8f57d5b9fcd784094e004bf7c6aRussell Coker const char *level = NULL; 87288e334f1923396d5ace56b8439c731dcde0d1f3bGary Tierney const char *homedir_role = NULL; 87313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle unsigned int i; 87413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle int retval; 87513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle int errors = 0; 87613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 87713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle retval = semanage_seuser_list(s->h_semanage, &seuser_list, &nseusers); 87813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (retval < 0 || (nseusers < 1)) { 87913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle /* if there are no users, this function can't do any other work */ 88013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return errors; 88113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 88213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 88313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle for (i = 0; i < nseusers; i++) { 88413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle name = semanage_seuser_get_name(seuser_list[i]); 88513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (strcmp(name, DEFAULT_LOGIN) == 0) { 88613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle seuname = semanage_seuser_get_sename(seuser_list[i]); 88713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 88813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle /* find the user structure given the name */ 88913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (semanage_user_key_create(s->h_semanage, seuname, 89013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle &key) < 0) { 89113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle errors = STATUS_ERR; 89213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle break; 89313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 89413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (semanage_user_query(s->h_semanage, key, &u) < 0) 895d784fd71b56cb8f57d5b9fcd784094e004bf7c6aRussell Coker { 89613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle prefix = name; 897925914acea3e2a95f4ccc9d39498cede345061d5Jason Zaman level = FALLBACK_LEVEL; 898d784fd71b56cb8f57d5b9fcd784094e004bf7c6aRussell Coker } 89913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle else 900d784fd71b56cb8f57d5b9fcd784094e004bf7c6aRussell Coker { 90113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle prefix = semanage_user_get_prefix(u); 902d784fd71b56cb8f57d5b9fcd784094e004bf7c6aRussell Coker level = semanage_user_get_mlslevel(u); 90318649484eee7e4ca7b0be572365aca368a3471b5Xin Ouyang if (!level) 904925914acea3e2a95f4ccc9d39498cede345061d5Jason Zaman level = FALLBACK_LEVEL; 905d784fd71b56cb8f57d5b9fcd784094e004bf7c6aRussell Coker } 90613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 90788e334f1923396d5ace56b8439c731dcde0d1f3bGary Tierney if (prefix_is_homedir_role(u, prefix)) { 90888e334f1923396d5ace56b8439c731dcde0d1f3bGary Tierney homedir_role = prefix; 90988e334f1923396d5ace56b8439c731dcde0d1f3bGary Tierney } 91088e334f1923396d5ace56b8439c731dcde0d1f3bGary Tierney 911c90780aaf767485fbdc063eab905422d756f22b5Jason Zaman if (push_user_entry(&(s->fallback), FALLBACK_NAME, 9123b23f12eb9aa2ee828561ffb414efa8c2031e75fJason Zaman FALLBACK_UIDGID, FALLBACK_UIDGID, 91367b328a91c6f6f22d8eaf220aaefe06623112f32Gary Tierney seuname, prefix, "", level, 91488e334f1923396d5ace56b8439c731dcde0d1f3bGary Tierney FALLBACK_NAME, homedir_role) != 0) 91513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle errors = STATUS_ERR; 91613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle semanage_user_key_free(key); 91713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (u) 91813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle semanage_user_free(u); 91913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle break; 92013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 92113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 92213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 92313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle for (i = 0; i < nseusers; i++) 92413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle semanage_seuser_free(seuser_list[i]); 92513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle free(seuser_list); 92613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 92713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return errors; 92813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle} 92913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 93067b328a91c6f6f22d8eaf220aaefe06623112f32Gary Tierneystatic genhomedircon_user_entry_t *find_user(genhomedircon_user_entry_t *head, 93167b328a91c6f6f22d8eaf220aaefe06623112f32Gary Tierney const char *name) 93267b328a91c6f6f22d8eaf220aaefe06623112f32Gary Tierney{ 93367b328a91c6f6f22d8eaf220aaefe06623112f32Gary Tierney for(; head; head = head->next) { 93467b328a91c6f6f22d8eaf220aaefe06623112f32Gary Tierney if (strcmp(head->name, name) == 0) { 93567b328a91c6f6f22d8eaf220aaefe06623112f32Gary Tierney return head; 93667b328a91c6f6f22d8eaf220aaefe06623112f32Gary Tierney } 93767b328a91c6f6f22d8eaf220aaefe06623112f32Gary Tierney } 93867b328a91c6f6f22d8eaf220aaefe06623112f32Gary Tierney 93967b328a91c6f6f22d8eaf220aaefe06623112f32Gary Tierney return NULL; 94067b328a91c6f6f22d8eaf220aaefe06623112f32Gary Tierney} 94167b328a91c6f6f22d8eaf220aaefe06623112f32Gary Tierney 94267b328a91c6f6f22d8eaf220aaefe06623112f32Gary Tierneystatic int add_user(genhomedircon_settings_t * s, 94367b328a91c6f6f22d8eaf220aaefe06623112f32Gary Tierney genhomedircon_user_entry_t **head, 94467b328a91c6f6f22d8eaf220aaefe06623112f32Gary Tierney semanage_user_t *user, 94567b328a91c6f6f22d8eaf220aaefe06623112f32Gary Tierney const char *name, 94667b328a91c6f6f22d8eaf220aaefe06623112f32Gary Tierney const char *sename, 94767b328a91c6f6f22d8eaf220aaefe06623112f32Gary Tierney const char *selogin) 94867b328a91c6f6f22d8eaf220aaefe06623112f32Gary Tierney{ 94967b328a91c6f6f22d8eaf220aaefe06623112f32Gary Tierney if (selogin[0] == '%') { 95067b328a91c6f6f22d8eaf220aaefe06623112f32Gary Tierney genhomedircon_user_entry_t *orig = find_user(*head, name); 95167b328a91c6f6f22d8eaf220aaefe06623112f32Gary Tierney if (orig != NULL && orig->login[0] == '%') { 95267b328a91c6f6f22d8eaf220aaefe06623112f32Gary Tierney ERR(s->h_semanage, "User %s is already mapped to" 95367b328a91c6f6f22d8eaf220aaefe06623112f32Gary Tierney " group %s, but also belongs to group %s. Add an" 95467b328a91c6f6f22d8eaf220aaefe06623112f32Gary Tierney " explicit mapping for this user to" 95567b328a91c6f6f22d8eaf220aaefe06623112f32Gary Tierney " override group mappings.", 95667b328a91c6f6f22d8eaf220aaefe06623112f32Gary Tierney name, orig->login + 1, selogin + 1); 95767b328a91c6f6f22d8eaf220aaefe06623112f32Gary Tierney return STATUS_ERR; 95867b328a91c6f6f22d8eaf220aaefe06623112f32Gary Tierney } else if (orig != NULL) { 95967b328a91c6f6f22d8eaf220aaefe06623112f32Gary Tierney // user mappings take precedence 96067b328a91c6f6f22d8eaf220aaefe06623112f32Gary Tierney return STATUS_SUCCESS; 96167b328a91c6f6f22d8eaf220aaefe06623112f32Gary Tierney } 96267b328a91c6f6f22d8eaf220aaefe06623112f32Gary Tierney } 96367b328a91c6f6f22d8eaf220aaefe06623112f32Gary Tierney 96467b328a91c6f6f22d8eaf220aaefe06623112f32Gary Tierney int retval = STATUS_ERR; 96567b328a91c6f6f22d8eaf220aaefe06623112f32Gary Tierney 96667b328a91c6f6f22d8eaf220aaefe06623112f32Gary Tierney char *rbuf = NULL; 96767b328a91c6f6f22d8eaf220aaefe06623112f32Gary Tierney long rbuflen; 96867b328a91c6f6f22d8eaf220aaefe06623112f32Gary Tierney struct passwd pwstorage, *pwent = NULL; 96967b328a91c6f6f22d8eaf220aaefe06623112f32Gary Tierney const char *prefix = NULL; 97067b328a91c6f6f22d8eaf220aaefe06623112f32Gary Tierney const char *level = NULL; 97188e334f1923396d5ace56b8439c731dcde0d1f3bGary Tierney const char *homedir_role = NULL; 97267b328a91c6f6f22d8eaf220aaefe06623112f32Gary Tierney char uid[11]; 97367b328a91c6f6f22d8eaf220aaefe06623112f32Gary Tierney char gid[11]; 97467b328a91c6f6f22d8eaf220aaefe06623112f32Gary Tierney 97567b328a91c6f6f22d8eaf220aaefe06623112f32Gary Tierney /* Allocate space for the getpwnam_r buffer */ 97667b328a91c6f6f22d8eaf220aaefe06623112f32Gary Tierney rbuflen = sysconf(_SC_GETPW_R_SIZE_MAX); 97767b328a91c6f6f22d8eaf220aaefe06623112f32Gary Tierney if (rbuflen <= 0) 97867b328a91c6f6f22d8eaf220aaefe06623112f32Gary Tierney goto cleanup; 97967b328a91c6f6f22d8eaf220aaefe06623112f32Gary Tierney rbuf = malloc(rbuflen); 98067b328a91c6f6f22d8eaf220aaefe06623112f32Gary Tierney if (rbuf == NULL) 98167b328a91c6f6f22d8eaf220aaefe06623112f32Gary Tierney goto cleanup; 98267b328a91c6f6f22d8eaf220aaefe06623112f32Gary Tierney 98367b328a91c6f6f22d8eaf220aaefe06623112f32Gary Tierney if (user) { 98467b328a91c6f6f22d8eaf220aaefe06623112f32Gary Tierney prefix = semanage_user_get_prefix(user); 98567b328a91c6f6f22d8eaf220aaefe06623112f32Gary Tierney level = semanage_user_get_mlslevel(user); 98667b328a91c6f6f22d8eaf220aaefe06623112f32Gary Tierney 98767b328a91c6f6f22d8eaf220aaefe06623112f32Gary Tierney if (!level) { 98867b328a91c6f6f22d8eaf220aaefe06623112f32Gary Tierney level = FALLBACK_LEVEL; 98967b328a91c6f6f22d8eaf220aaefe06623112f32Gary Tierney } 99067b328a91c6f6f22d8eaf220aaefe06623112f32Gary Tierney } else { 99167b328a91c6f6f22d8eaf220aaefe06623112f32Gary Tierney prefix = name; 99267b328a91c6f6f22d8eaf220aaefe06623112f32Gary Tierney level = FALLBACK_LEVEL; 99367b328a91c6f6f22d8eaf220aaefe06623112f32Gary Tierney } 99467b328a91c6f6f22d8eaf220aaefe06623112f32Gary Tierney 99588e334f1923396d5ace56b8439c731dcde0d1f3bGary Tierney if (prefix_is_homedir_role(user, prefix)) { 99688e334f1923396d5ace56b8439c731dcde0d1f3bGary Tierney homedir_role = prefix; 99788e334f1923396d5ace56b8439c731dcde0d1f3bGary Tierney } 99888e334f1923396d5ace56b8439c731dcde0d1f3bGary Tierney 99967b328a91c6f6f22d8eaf220aaefe06623112f32Gary Tierney retval = getpwnam_r(name, &pwstorage, rbuf, rbuflen, &pwent); 100067b328a91c6f6f22d8eaf220aaefe06623112f32Gary Tierney if (retval != 0 || pwent == NULL) { 100167b328a91c6f6f22d8eaf220aaefe06623112f32Gary Tierney if (retval != 0 && retval != ENOENT) { 100267b328a91c6f6f22d8eaf220aaefe06623112f32Gary Tierney goto cleanup; 100367b328a91c6f6f22d8eaf220aaefe06623112f32Gary Tierney } 100467b328a91c6f6f22d8eaf220aaefe06623112f32Gary Tierney 100567b328a91c6f6f22d8eaf220aaefe06623112f32Gary Tierney WARN(s->h_semanage, 100667b328a91c6f6f22d8eaf220aaefe06623112f32Gary Tierney "user %s not in password file", name); 100767b328a91c6f6f22d8eaf220aaefe06623112f32Gary Tierney retval = STATUS_SUCCESS; 100867b328a91c6f6f22d8eaf220aaefe06623112f32Gary Tierney goto cleanup; 100967b328a91c6f6f22d8eaf220aaefe06623112f32Gary Tierney } 101067b328a91c6f6f22d8eaf220aaefe06623112f32Gary Tierney 101167b328a91c6f6f22d8eaf220aaefe06623112f32Gary Tierney int len = strlen(pwent->pw_dir) -1; 101267b328a91c6f6f22d8eaf220aaefe06623112f32Gary Tierney for(; len > 0 && pwent->pw_dir[len] == '/'; len--) { 101367b328a91c6f6f22d8eaf220aaefe06623112f32Gary Tierney pwent->pw_dir[len] = '\0'; 101467b328a91c6f6f22d8eaf220aaefe06623112f32Gary Tierney } 101567b328a91c6f6f22d8eaf220aaefe06623112f32Gary Tierney 101667b328a91c6f6f22d8eaf220aaefe06623112f32Gary Tierney if (strcmp(pwent->pw_dir, "/") == 0) { 101767b328a91c6f6f22d8eaf220aaefe06623112f32Gary Tierney /* don't relabel / genhomdircon checked to see if root 101867b328a91c6f6f22d8eaf220aaefe06623112f32Gary Tierney * was the user and if so, set his home directory to 101967b328a91c6f6f22d8eaf220aaefe06623112f32Gary Tierney * /root */ 102067b328a91c6f6f22d8eaf220aaefe06623112f32Gary Tierney retval = STATUS_SUCCESS; 102167b328a91c6f6f22d8eaf220aaefe06623112f32Gary Tierney goto cleanup; 102267b328a91c6f6f22d8eaf220aaefe06623112f32Gary Tierney } 102367b328a91c6f6f22d8eaf220aaefe06623112f32Gary Tierney 102467b328a91c6f6f22d8eaf220aaefe06623112f32Gary Tierney if (ignore(pwent->pw_dir)) { 102567b328a91c6f6f22d8eaf220aaefe06623112f32Gary Tierney retval = STATUS_SUCCESS; 102667b328a91c6f6f22d8eaf220aaefe06623112f32Gary Tierney goto cleanup; 102767b328a91c6f6f22d8eaf220aaefe06623112f32Gary Tierney } 102867b328a91c6f6f22d8eaf220aaefe06623112f32Gary Tierney 102967b328a91c6f6f22d8eaf220aaefe06623112f32Gary Tierney len = snprintf(uid, sizeof(uid), "%u", pwent->pw_uid); 103067b328a91c6f6f22d8eaf220aaefe06623112f32Gary Tierney if (len < 0 || len >= (int)sizeof(uid)) { 103167b328a91c6f6f22d8eaf220aaefe06623112f32Gary Tierney goto cleanup; 103267b328a91c6f6f22d8eaf220aaefe06623112f32Gary Tierney } 103367b328a91c6f6f22d8eaf220aaefe06623112f32Gary Tierney 103467b328a91c6f6f22d8eaf220aaefe06623112f32Gary Tierney len = snprintf(gid, sizeof(gid), "%u", pwent->pw_gid); 103567b328a91c6f6f22d8eaf220aaefe06623112f32Gary Tierney if (len < 0 || len >= (int)sizeof(gid)) { 103667b328a91c6f6f22d8eaf220aaefe06623112f32Gary Tierney goto cleanup; 103767b328a91c6f6f22d8eaf220aaefe06623112f32Gary Tierney } 103867b328a91c6f6f22d8eaf220aaefe06623112f32Gary Tierney 103967b328a91c6f6f22d8eaf220aaefe06623112f32Gary Tierney retval = push_user_entry(head, name, uid, gid, sename, prefix, 104088e334f1923396d5ace56b8439c731dcde0d1f3bGary Tierney pwent->pw_dir, level, selogin, homedir_role); 104167b328a91c6f6f22d8eaf220aaefe06623112f32Gary Tierneycleanup: 104267b328a91c6f6f22d8eaf220aaefe06623112f32Gary Tierney free(rbuf); 104367b328a91c6f6f22d8eaf220aaefe06623112f32Gary Tierney return retval; 104467b328a91c6f6f22d8eaf220aaefe06623112f32Gary Tierney} 104567b328a91c6f6f22d8eaf220aaefe06623112f32Gary Tierney 104667b328a91c6f6f22d8eaf220aaefe06623112f32Gary Tierneystatic int get_group_users(genhomedircon_settings_t * s, 104767b328a91c6f6f22d8eaf220aaefe06623112f32Gary Tierney genhomedircon_user_entry_t **head, 104867b328a91c6f6f22d8eaf220aaefe06623112f32Gary Tierney semanage_user_t *user, 104967b328a91c6f6f22d8eaf220aaefe06623112f32Gary Tierney const char *sename, 105067b328a91c6f6f22d8eaf220aaefe06623112f32Gary Tierney const char *selogin) 105167b328a91c6f6f22d8eaf220aaefe06623112f32Gary Tierney{ 105267b328a91c6f6f22d8eaf220aaefe06623112f32Gary Tierney int retval = STATUS_ERR; 105367b328a91c6f6f22d8eaf220aaefe06623112f32Gary Tierney unsigned int i; 105467b328a91c6f6f22d8eaf220aaefe06623112f32Gary Tierney 105567b328a91c6f6f22d8eaf220aaefe06623112f32Gary Tierney long grbuflen; 105667b328a91c6f6f22d8eaf220aaefe06623112f32Gary Tierney char *grbuf = NULL; 105767b328a91c6f6f22d8eaf220aaefe06623112f32Gary Tierney struct group grstorage, *group = NULL; 10582c651e0a2822368c74587efe6ec920e64e72f37bPatrick Steinhardt struct passwd *pw = NULL; 105967b328a91c6f6f22d8eaf220aaefe06623112f32Gary Tierney 106067b328a91c6f6f22d8eaf220aaefe06623112f32Gary Tierney grbuflen = sysconf(_SC_GETGR_R_SIZE_MAX); 106167b328a91c6f6f22d8eaf220aaefe06623112f32Gary Tierney if (grbuflen <= 0) 106267b328a91c6f6f22d8eaf220aaefe06623112f32Gary Tierney goto cleanup; 106367b328a91c6f6f22d8eaf220aaefe06623112f32Gary Tierney grbuf = malloc(grbuflen); 106467b328a91c6f6f22d8eaf220aaefe06623112f32Gary Tierney if (grbuf == NULL) 106567b328a91c6f6f22d8eaf220aaefe06623112f32Gary Tierney goto cleanup; 106667b328a91c6f6f22d8eaf220aaefe06623112f32Gary Tierney 106767b328a91c6f6f22d8eaf220aaefe06623112f32Gary Tierney const char *grname = selogin + 1; 106867b328a91c6f6f22d8eaf220aaefe06623112f32Gary Tierney 106967b328a91c6f6f22d8eaf220aaefe06623112f32Gary Tierney if (getgrnam_r(grname, &grstorage, grbuf, 107067b328a91c6f6f22d8eaf220aaefe06623112f32Gary Tierney (size_t) grbuflen, &group) != 0) { 107167b328a91c6f6f22d8eaf220aaefe06623112f32Gary Tierney goto cleanup; 107267b328a91c6f6f22d8eaf220aaefe06623112f32Gary Tierney } 107367b328a91c6f6f22d8eaf220aaefe06623112f32Gary Tierney 107467b328a91c6f6f22d8eaf220aaefe06623112f32Gary Tierney if (group == NULL) { 107567b328a91c6f6f22d8eaf220aaefe06623112f32Gary Tierney ERR(s->h_semanage, "Can't find group named %s\n", grname); 107667b328a91c6f6f22d8eaf220aaefe06623112f32Gary Tierney goto cleanup; 107767b328a91c6f6f22d8eaf220aaefe06623112f32Gary Tierney } 107867b328a91c6f6f22d8eaf220aaefe06623112f32Gary Tierney 107967b328a91c6f6f22d8eaf220aaefe06623112f32Gary Tierney size_t nmembers = 0; 108067b328a91c6f6f22d8eaf220aaefe06623112f32Gary Tierney char **members = group->gr_mem; 108167b328a91c6f6f22d8eaf220aaefe06623112f32Gary Tierney 108267b328a91c6f6f22d8eaf220aaefe06623112f32Gary Tierney while (*members != NULL) { 108367b328a91c6f6f22d8eaf220aaefe06623112f32Gary Tierney nmembers++; 108467b328a91c6f6f22d8eaf220aaefe06623112f32Gary Tierney members++; 108567b328a91c6f6f22d8eaf220aaefe06623112f32Gary Tierney } 108667b328a91c6f6f22d8eaf220aaefe06623112f32Gary Tierney 108767b328a91c6f6f22d8eaf220aaefe06623112f32Gary Tierney for (i = 0; i < nmembers; i++) { 108867b328a91c6f6f22d8eaf220aaefe06623112f32Gary Tierney const char *uname = group->gr_mem[i]; 108967b328a91c6f6f22d8eaf220aaefe06623112f32Gary Tierney 109067b328a91c6f6f22d8eaf220aaefe06623112f32Gary Tierney if (add_user(s, head, user, uname, sename, selogin) < 0) { 109167b328a91c6f6f22d8eaf220aaefe06623112f32Gary Tierney goto cleanup; 109267b328a91c6f6f22d8eaf220aaefe06623112f32Gary Tierney } 109367b328a91c6f6f22d8eaf220aaefe06623112f32Gary Tierney } 109467b328a91c6f6f22d8eaf220aaefe06623112f32Gary Tierney 109567b328a91c6f6f22d8eaf220aaefe06623112f32Gary Tierney setpwent(); 10962c651e0a2822368c74587efe6ec920e64e72f37bPatrick Steinhardt while ((pw = getpwent()) != NULL) { 109767b328a91c6f6f22d8eaf220aaefe06623112f32Gary Tierney // skip users who also have this group as their 109867b328a91c6f6f22d8eaf220aaefe06623112f32Gary Tierney // primary group 109967b328a91c6f6f22d8eaf220aaefe06623112f32Gary Tierney if (lfind(pw->pw_name, group->gr_mem, &nmembers, 110067b328a91c6f6f22d8eaf220aaefe06623112f32Gary Tierney sizeof(char *), &STR_COMPARATOR)) { 110167b328a91c6f6f22d8eaf220aaefe06623112f32Gary Tierney continue; 110267b328a91c6f6f22d8eaf220aaefe06623112f32Gary Tierney } 110367b328a91c6f6f22d8eaf220aaefe06623112f32Gary Tierney 110467b328a91c6f6f22d8eaf220aaefe06623112f32Gary Tierney if (group->gr_gid == pw->pw_gid) { 110567b328a91c6f6f22d8eaf220aaefe06623112f32Gary Tierney if (add_user(s, head, user, pw->pw_name, 110667b328a91c6f6f22d8eaf220aaefe06623112f32Gary Tierney sename, selogin) < 0) { 110767b328a91c6f6f22d8eaf220aaefe06623112f32Gary Tierney goto cleanup; 110867b328a91c6f6f22d8eaf220aaefe06623112f32Gary Tierney } 110967b328a91c6f6f22d8eaf220aaefe06623112f32Gary Tierney } 111067b328a91c6f6f22d8eaf220aaefe06623112f32Gary Tierney } 111167b328a91c6f6f22d8eaf220aaefe06623112f32Gary Tierney 111267b328a91c6f6f22d8eaf220aaefe06623112f32Gary Tierney retval = STATUS_SUCCESS; 111367b328a91c6f6f22d8eaf220aaefe06623112f32Gary Tierneycleanup: 111467b328a91c6f6f22d8eaf220aaefe06623112f32Gary Tierney endpwent(); 111567b328a91c6f6f22d8eaf220aaefe06623112f32Gary Tierney free(grbuf); 111667b328a91c6f6f22d8eaf220aaefe06623112f32Gary Tierney 111767b328a91c6f6f22d8eaf220aaefe06623112f32Gary Tierney return retval; 111867b328a91c6f6f22d8eaf220aaefe06623112f32Gary Tierney} 111967b328a91c6f6f22d8eaf220aaefe06623112f32Gary Tierney 112013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindlestatic genhomedircon_user_entry_t *get_users(genhomedircon_settings_t * s, 112113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle int *errors) 112213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle{ 112313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle genhomedircon_user_entry_t *head = NULL; 112413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle semanage_seuser_t **seuser_list = NULL; 112513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle unsigned int nseusers = 0; 112613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle semanage_user_t **user_list = NULL; 112713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle unsigned int nusers = 0; 112813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle semanage_user_t **u = NULL; 112913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle const char *name = NULL; 113013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle const char *seuname = NULL; 113113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle unsigned int i; 113213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle int retval; 113313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 113413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle *errors = 0; 113513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle retval = semanage_seuser_list(s->h_semanage, &seuser_list, &nseusers); 113613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (retval < 0 || (nseusers < 1)) { 113713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle /* if there are no users, this function can't do any other work */ 113813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return NULL; 113913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 114013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 114113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (semanage_user_list(s->h_semanage, &user_list, &nusers) < 0) { 114213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle nusers = 0; 114313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 114413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 114567b328a91c6f6f22d8eaf220aaefe06623112f32Gary Tierney qsort(seuser_list, nseusers, sizeof(semanage_seuser_t *), 114667b328a91c6f6f22d8eaf220aaefe06623112f32Gary Tierney &seuser_sort_func); 114713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle qsort(user_list, nusers, sizeof(semanage_user_t *), 114813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle (int (*)(const void *, const void *))&user_sort_func); 114913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 115013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle for (i = 0; i < nseusers; i++) { 115113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle seuname = semanage_seuser_get_sename(seuser_list[i]); 115213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle name = semanage_seuser_get_name(seuser_list[i]); 115313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 115413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (strcmp(name, DEFAULT_LOGIN) == 0) 115513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle continue; 115613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 115713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle /* find the user structure given the name */ 115813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle u = bsearch(seuname, user_list, nusers, sizeof(semanage_user_t *), 115913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle (int (*)(const void *, const void *)) 116013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle &name_user_cmp); 116113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 116267b328a91c6f6f22d8eaf220aaefe06623112f32Gary Tierney /* %groupname syntax */ 116367b328a91c6f6f22d8eaf220aaefe06623112f32Gary Tierney if (name[0] == '%') { 116467b328a91c6f6f22d8eaf220aaefe06623112f32Gary Tierney retval = get_group_users(s, &head, *u, seuname, 116567b328a91c6f6f22d8eaf220aaefe06623112f32Gary Tierney name); 116667b328a91c6f6f22d8eaf220aaefe06623112f32Gary Tierney } else { 116767b328a91c6f6f22d8eaf220aaefe06623112f32Gary Tierney retval = add_user(s, &head, *u, name, 116867b328a91c6f6f22d8eaf220aaefe06623112f32Gary Tierney seuname, name); 1169faff0a77c679e8290bac6595c9764dc8929f32d6Daniel J Walsh } 1170faff0a77c679e8290bac6595c9764dc8929f32d6Daniel J Walsh 117167b328a91c6f6f22d8eaf220aaefe06623112f32Gary Tierney if (retval != 0) { 11723b23f12eb9aa2ee828561ffb414efa8c2031e75fJason Zaman *errors = STATUS_ERR; 11733b23f12eb9aa2ee828561ffb414efa8c2031e75fJason Zaman goto cleanup; 11743b23f12eb9aa2ee828561ffb414efa8c2031e75fJason Zaman } 117513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 117613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 117713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle cleanup: 117813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (*errors) { 117913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle for (; head; pop_user_entry(&head)) { 118013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle /* the pop function takes care of all the cleanup 118113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle so the loop body is just empty */ 118213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 118313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 118413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle for (i = 0; i < nseusers; i++) { 118513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle semanage_seuser_free(seuser_list[i]); 118613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 118713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle free(seuser_list); 118813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 118913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle for (i = 0; i < nusers; i++) { 119013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle semanage_user_free(user_list[i]); 119113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 119213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle free(user_list); 119313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 119413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return head; 119513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle} 119613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 119713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindlestatic int write_gen_home_dir_context(genhomedircon_settings_t * s, FILE * out, 11984bbec88baa66d1376629fb6f860eb51657429b91Jason Zaman semanage_list_t * username_context_tpl, 119913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle semanage_list_t * user_context_tpl, 120013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle semanage_list_t * homedir_context_tpl) 120113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle{ 120213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle genhomedircon_user_entry_t *users; 120313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle int errors = 0; 120413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 120513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle users = get_users(s, &errors); 120613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (!users && errors) { 120713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return STATUS_ERR; 120813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 120913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 121013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle for (; users; pop_user_entry(&users)) { 1211c90780aaf767485fbdc063eab905422d756f22b5Jason Zaman if (write_home_dir_context(s, out, homedir_context_tpl, users)) 12127d83d86ba10e2fc251a249df4745c6f339e9c523Eric Paris goto err; 12134bbec88baa66d1376629fb6f860eb51657429b91Jason Zaman if (write_username_context(s, out, username_context_tpl, users)) 12144bbec88baa66d1376629fb6f860eb51657429b91Jason Zaman goto err; 1215c90780aaf767485fbdc063eab905422d756f22b5Jason Zaman if (write_user_context(s, out, user_context_tpl, users)) 12167d83d86ba10e2fc251a249df4745c6f339e9c523Eric Paris goto err; 121713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 121813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 121913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return STATUS_SUCCESS; 12207d83d86ba10e2fc251a249df4745c6f339e9c523Eric Pariserr: 12217d83d86ba10e2fc251a249df4745c6f339e9c523Eric Paris for (; users; pop_user_entry(&users)) { 12227d83d86ba10e2fc251a249df4745c6f339e9c523Eric Paris /* the pop function takes care of all the cleanup 12237d83d86ba10e2fc251a249df4745c6f339e9c523Eric Paris * so the loop body is just empty */ 12247d83d86ba10e2fc251a249df4745c6f339e9c523Eric Paris } 12257d83d86ba10e2fc251a249df4745c6f339e9c523Eric Paris 12267d83d86ba10e2fc251a249df4745c6f339e9c523Eric Paris return STATUS_ERR; 122713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle} 122813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 122913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle/** 123013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle * @param s settings structure, stores various paths etc. Must never be NULL 123113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle * @param out the FILE to put all the output in. 123213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle * @return 0 on success 123313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle */ 123413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindlestatic int write_context_file(genhomedircon_settings_t * s, FILE * out) 123513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle{ 123613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle semanage_list_t *homedirs = NULL; 123713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle semanage_list_t *h = NULL; 123813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle semanage_list_t *homedir_context_tpl = NULL; 123913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle semanage_list_t *homeroot_context_tpl = NULL; 124008cde98b606cd04e26061d16ec537a2549f5199cJason Zaman semanage_list_t *username_context_tpl = NULL; 124108cde98b606cd04e26061d16ec537a2549f5199cJason Zaman semanage_list_t *user_context_tpl = NULL; 124213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle int retval = STATUS_SUCCESS; 124313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 124413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle homedir_context_tpl = make_template(s, &HOME_DIR_PRED); 124513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle homeroot_context_tpl = make_template(s, &HOME_ROOT_PRED); 124608cde98b606cd04e26061d16ec537a2549f5199cJason Zaman username_context_tpl = make_template(s, &USERNAME_CONTEXT_PRED); 124713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle user_context_tpl = make_template(s, &USER_CONTEXT_PRED); 124813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 124908cde98b606cd04e26061d16ec537a2549f5199cJason Zaman if (!homedir_context_tpl 125008cde98b606cd04e26061d16ec537a2549f5199cJason Zaman && !homeroot_context_tpl 125108cde98b606cd04e26061d16ec537a2549f5199cJason Zaman && !username_context_tpl 125208cde98b606cd04e26061d16ec537a2549f5199cJason Zaman && !user_context_tpl) 125313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle goto done; 125413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 1255d67b1ea1cbe30afb4894634f06ca25916b03cbd7Eric Paris if (write_file_context_header(out) != STATUS_SUCCESS) { 125613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle retval = STATUS_ERR; 125713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle goto done; 125813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 125913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 126013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (setup_fallback_user(s) != 0) { 126113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle retval = STATUS_ERR; 126213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle goto done; 126313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 126413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 126513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (homedir_context_tpl || homeroot_context_tpl) { 126613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle homedirs = get_home_dirs(s); 126713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (!homedirs) { 126813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle WARN(s->h_semanage, 126913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle "no home directories were available, exiting without writing"); 127013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle goto done; 127113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 127213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 127313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle for (h = homedirs; h; h = h->next) { 1274300b8ad4235688171f2a91e7aeb14d0ee3561c13Nicolas Iooss char *temp = NULL; 127513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 1276300b8ad4235688171f2a91e7aeb14d0ee3561c13Nicolas Iooss if (asprintf(&temp, "%s/%s", h->data, FALLBACK_NAME) < 0) { 127713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle retval = STATUS_ERR; 127813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle goto done; 127913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 128013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 1281c90780aaf767485fbdc063eab905422d756f22b5Jason Zaman free(s->fallback->home); 1282300b8ad4235688171f2a91e7aeb14d0ee3561c13Nicolas Iooss s->fallback->home = temp; 1283c90780aaf767485fbdc063eab905422d756f22b5Jason Zaman 1284c90780aaf767485fbdc063eab905422d756f22b5Jason Zaman if (write_home_dir_context(s, out, homedir_context_tpl, 1285c90780aaf767485fbdc063eab905422d756f22b5Jason Zaman s->fallback) != STATUS_SUCCESS) { 1286300b8ad4235688171f2a91e7aeb14d0ee3561c13Nicolas Iooss free(temp); 1287c90780aaf767485fbdc063eab905422d756f22b5Jason Zaman s->fallback->home = NULL; 128813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle retval = STATUS_ERR; 128913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle goto done; 129013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 129113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (write_home_root_context(s, out, 129213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle homeroot_context_tpl, 129313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle h->data) != STATUS_SUCCESS) { 1294300b8ad4235688171f2a91e7aeb14d0ee3561c13Nicolas Iooss free(temp); 1295c90780aaf767485fbdc063eab905422d756f22b5Jason Zaman s->fallback->home = NULL; 129613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle retval = STATUS_ERR; 129713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle goto done; 129813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 129913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 1300300b8ad4235688171f2a91e7aeb14d0ee3561c13Nicolas Iooss free(temp); 1301c90780aaf767485fbdc063eab905422d756f22b5Jason Zaman s->fallback->home = NULL; 130213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 130313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 13044bbec88baa66d1376629fb6f860eb51657429b91Jason Zaman if (user_context_tpl || username_context_tpl) { 13054bbec88baa66d1376629fb6f860eb51657429b91Jason Zaman if (write_username_context(s, out, username_context_tpl, 13064bbec88baa66d1376629fb6f860eb51657429b91Jason Zaman s->fallback) != STATUS_SUCCESS) { 13074bbec88baa66d1376629fb6f860eb51657429b91Jason Zaman retval = STATUS_ERR; 13084bbec88baa66d1376629fb6f860eb51657429b91Jason Zaman goto done; 13094bbec88baa66d1376629fb6f860eb51657429b91Jason Zaman } 13104bbec88baa66d1376629fb6f860eb51657429b91Jason Zaman 131113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (write_user_context(s, out, user_context_tpl, 1312c90780aaf767485fbdc063eab905422d756f22b5Jason Zaman s->fallback) != STATUS_SUCCESS) { 131313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle retval = STATUS_ERR; 131413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle goto done; 131513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 131613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 13174bbec88baa66d1376629fb6f860eb51657429b91Jason Zaman if (write_gen_home_dir_context(s, out, username_context_tpl, 13184bbec88baa66d1376629fb6f860eb51657429b91Jason Zaman user_context_tpl, homedir_context_tpl) 13194bbec88baa66d1376629fb6f860eb51657429b91Jason Zaman != STATUS_SUCCESS) { 132013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle retval = STATUS_ERR; 132113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 132213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 132313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 132413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindledone: 132513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle /* Cleanup */ 132613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle semanage_list_destroy(&homedirs); 132708cde98b606cd04e26061d16ec537a2549f5199cJason Zaman semanage_list_destroy(&username_context_tpl); 132813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle semanage_list_destroy(&user_context_tpl); 132913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle semanage_list_destroy(&homedir_context_tpl); 133013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle semanage_list_destroy(&homeroot_context_tpl); 133113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 133213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return retval; 133313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle} 133413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 133513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindleint semanage_genhomedircon(semanage_handle_t * sh, 133613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle sepol_policydb_t * policydb, 1337915b5f885f030aa24a2ca648a184fa02cb5bbdcdEric Paris int usepasswd, 1338915b5f885f030aa24a2ca648a184fa02cb5bbdcdEric Paris char *ignoredirs) 133913cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle{ 134013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle genhomedircon_settings_t s; 134113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle FILE *out = NULL; 134213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle int retval = 0; 134313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 134413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle assert(sh); 134513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 134613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle s.homedir_template_path = 134713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle semanage_path(SEMANAGE_TMP, SEMANAGE_HOMEDIR_TMPL); 13485007687feb62e27678ee961243984bc319a22911Vit Mojzis s.fcfilepath = 13495007687feb62e27678ee961243984bc319a22911Vit Mojzis semanage_path(SEMANAGE_TMP, SEMANAGE_STORE_FC_HOMEDIRS); 135013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 1351c90780aaf767485fbdc063eab905422d756f22b5Jason Zaman s.fallback = calloc(1, sizeof(genhomedircon_user_entry_t)); 1352c90780aaf767485fbdc063eab905422d756f22b5Jason Zaman if (s.fallback == NULL) { 1353c90780aaf767485fbdc063eab905422d756f22b5Jason Zaman retval = STATUS_ERR; 1354c90780aaf767485fbdc063eab905422d756f22b5Jason Zaman goto done; 1355c90780aaf767485fbdc063eab905422d756f22b5Jason Zaman } 1356c90780aaf767485fbdc063eab905422d756f22b5Jason Zaman 1357c90780aaf767485fbdc063eab905422d756f22b5Jason Zaman s.fallback->name = strdup(FALLBACK_NAME); 1358c90780aaf767485fbdc063eab905422d756f22b5Jason Zaman s.fallback->sename = strdup(FALLBACK_SENAME); 1359c90780aaf767485fbdc063eab905422d756f22b5Jason Zaman s.fallback->prefix = strdup(FALLBACK_PREFIX); 1360c90780aaf767485fbdc063eab905422d756f22b5Jason Zaman s.fallback->level = strdup(FALLBACK_LEVEL); 1361c90780aaf767485fbdc063eab905422d756f22b5Jason Zaman if (s.fallback->name == NULL 1362c90780aaf767485fbdc063eab905422d756f22b5Jason Zaman || s.fallback->sename == NULL 1363c90780aaf767485fbdc063eab905422d756f22b5Jason Zaman || s.fallback->prefix == NULL 1364c90780aaf767485fbdc063eab905422d756f22b5Jason Zaman || s.fallback->level == NULL) { 13656263ad719c6c75a88dc6eee8e3973ba0ade36c98Thomas Hurd retval = STATUS_ERR; 13666263ad719c6c75a88dc6eee8e3973ba0ade36c98Thomas Hurd goto done; 13676263ad719c6c75a88dc6eee8e3973ba0ade36c98Thomas Hurd } 136813cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 1369915b5f885f030aa24a2ca648a184fa02cb5bbdcdEric Paris if (ignoredirs) ignore_setup(ignoredirs); 1370915b5f885f030aa24a2ca648a184fa02cb5bbdcdEric Paris 137113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle s.usepasswd = usepasswd; 137213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle s.h_semanage = sh; 137313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle s.policydb = policydb; 137413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 137513cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle if (!(out = fopen(s.fcfilepath, "w"))) { 137613cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle /* couldn't open output file */ 137713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle ERR(sh, "Could not open the file_context file for writing"); 13786263ad719c6c75a88dc6eee8e3973ba0ade36c98Thomas Hurd retval = STATUS_ERR; 13796263ad719c6c75a88dc6eee8e3973ba0ade36c98Thomas Hurd goto done; 138013cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle } 138113cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 138213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle retval = write_context_file(&s, out); 138313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 13846263ad719c6c75a88dc6eee8e3973ba0ade36c98Thomas Hurddone: 13856263ad719c6c75a88dc6eee8e3973ba0ade36c98Thomas Hurd if (out != NULL) 13866263ad719c6c75a88dc6eee8e3973ba0ade36c98Thomas Hurd fclose(out); 138713cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 1388c15f495a65e26933189b8f7da2f8fb93f5b0d6e8Jan Zarsky while (s.fallback) 1389c15f495a65e26933189b8f7da2f8fb93f5b0d6e8Jan Zarsky pop_user_entry(&(s.fallback)); 1390c15f495a65e26933189b8f7da2f8fb93f5b0d6e8Jan Zarsky 1391915b5f885f030aa24a2ca648a184fa02cb5bbdcdEric Paris ignore_free(); 139213cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle 139313cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle return retval; 139413cd4c8960688af11ad23b4c946149015c80d54Joshua Brindle} 1395