1#include <stdio.h> 2 3#include <stdlib.h> 4#include <ctype.h> 5#include <errno.h> 6#include <limits.h> 7 8#include <sepol/policydb/policydb.h> 9 10#ifndef DARWIN 11#include <stdio_ext.h> 12#endif 13 14#include <stdarg.h> 15 16#include "debug.h" 17#include "private.h" 18#include "dso.h" 19#include "mls.h" 20 21/* -- Deprecated -- */ 22 23void sepol_set_delusers(int on __attribute((unused))) 24{ 25 WARN(NULL, "Deprecated interface"); 26} 27 28#undef BADLINE 29#define BADLINE() { \ 30 ERR(NULL, "invalid entry %s (%s:%u)", \ 31 buffer, path, lineno); \ 32 continue; \ 33} 34 35static int load_users(struct policydb *policydb, const char *path) 36{ 37 FILE *fp; 38 char *buffer = NULL, *p, *q, oldc; 39 size_t len = 0; 40 ssize_t nread; 41 unsigned lineno = 0, islist = 0, bit; 42 user_datum_t *usrdatum; 43 role_datum_t *roldatum; 44 ebitmap_node_t *rnode; 45 46 fp = fopen(path, "r"); 47 if (fp == NULL) 48 return -1; 49 50#ifdef DARWIN 51 if ((buffer = (char *)malloc(255 * sizeof(char))) == NULL) { 52 ERR(NULL, "out of memory"); 53 return -1; 54 } 55 56 while(fgets(buffer, 255, fp) != NULL) { 57#else 58 __fsetlocking(fp, FSETLOCKING_BYCALLER); 59 while ((nread = getline(&buffer, &len, fp)) > 0) { 60#endif 61 62 lineno++; 63 if (buffer[nread - 1] == '\n') 64 buffer[nread - 1] = 0; 65 p = buffer; 66 while (*p && isspace(*p)) 67 p++; 68 if (!(*p) || *p == '#') 69 continue; 70 71 if (strncasecmp(p, "user", 4)) 72 BADLINE(); 73 p += 4; 74 if (!isspace(*p)) 75 BADLINE(); 76 while (*p && isspace(*p)) 77 p++; 78 if (!(*p)) 79 BADLINE(); 80 q = p; 81 while (*p && !isspace(*p)) 82 p++; 83 if (!(*p)) 84 BADLINE(); 85 *p++ = 0; 86 87 usrdatum = hashtab_search(policydb->p_users.table, q); 88 if (usrdatum) { 89 /* Replacing an existing user definition. */ 90 ebitmap_destroy(&usrdatum->roles.roles); 91 ebitmap_init(&usrdatum->roles.roles); 92 } else { 93 char *id = strdup(q); 94 95 /* Adding a new user definition. */ 96 usrdatum = 97 (user_datum_t *) malloc(sizeof(user_datum_t)); 98 if (!id || !usrdatum) { 99 ERR(NULL, "out of memory"); 100 free(buffer); 101 fclose(fp); 102 return -1; 103 } 104 memset(usrdatum, 0, sizeof(user_datum_t)); 105 usrdatum->s.value = ++policydb->p_users.nprim; 106 ebitmap_init(&usrdatum->roles.roles); 107 if (hashtab_insert(policydb->p_users.table, 108 id, (hashtab_datum_t) usrdatum)) { 109 ERR(NULL, "out of memory"); 110 free(buffer); 111 fclose(fp); 112 return -1; 113 } 114 } 115 116 while (*p && isspace(*p)) 117 p++; 118 if (!(*p)) 119 BADLINE(); 120 if (strncasecmp(p, "roles", 5)) 121 BADLINE(); 122 p += 5; 123 if (!isspace(*p)) 124 BADLINE(); 125 while (*p && isspace(*p)) 126 p++; 127 if (!(*p)) 128 BADLINE(); 129 if (*p == '{') { 130 islist = 1; 131 p++; 132 } else 133 islist = 0; 134 135 oldc = 0; 136 do { 137 while (*p && isspace(*p)) 138 p++; 139 if (!(*p)) 140 break; 141 142 q = p; 143 while (*p && *p != ';' && *p != '}' && !isspace(*p)) 144 p++; 145 if (!(*p)) 146 break; 147 if (*p == '}') 148 islist = 0; 149 oldc = *p; 150 *p++ = 0; 151 if (!q[0]) 152 break; 153 154 roldatum = hashtab_search(policydb->p_roles.table, q); 155 if (!roldatum) { 156 ERR(NULL, "undefined role %s (%s:%u)", 157 q, path, lineno); 158 continue; 159 } 160 /* Set the role and every role it dominates */ 161 ebitmap_for_each_bit(&roldatum->dominates, rnode, bit) { 162 if (ebitmap_node_get_bit(rnode, bit)) 163 if (ebitmap_set_bit 164 (&usrdatum->roles.roles, bit, 1)) { 165 ERR(NULL, "out of memory"); 166 free(buffer); 167 fclose(fp); 168 return -1; 169 } 170 } 171 } while (islist); 172 if (oldc == 0) 173 BADLINE(); 174 175 if (policydb->mls) { 176 context_struct_t context; 177 char *scontext, *r, *s; 178 179 while (*p && isspace(*p)) 180 p++; 181 if (!(*p)) 182 BADLINE(); 183 if (strncasecmp(p, "level", 5)) 184 BADLINE(); 185 p += 5; 186 if (!isspace(*p)) 187 BADLINE(); 188 while (*p && isspace(*p)) 189 p++; 190 if (!(*p)) 191 BADLINE(); 192 q = p; 193 while (*p && strncasecmp(p, "range", 5)) 194 p++; 195 if (!(*p)) 196 BADLINE(); 197 *--p = 0; 198 p++; 199 200 scontext = malloc(p - q); 201 if (!scontext) { 202 ERR(NULL, "out of memory"); 203 free(buffer); 204 fclose(fp); 205 return -1; 206 } 207 r = scontext; 208 s = q; 209 while (*s) { 210 if (!isspace(*s)) 211 *r++ = *s; 212 s++; 213 } 214 *r = 0; 215 r = scontext; 216 217 context_init(&context); 218 if (mls_context_to_sid(policydb, oldc, &r, &context) < 219 0) { 220 ERR(NULL, "invalid level %s (%s:%u)", scontext, 221 path, lineno); 222 free(scontext); 223 continue; 224 225 } 226 free(scontext); 227 memcpy(&usrdatum->dfltlevel, &context.range.level[0], 228 sizeof(usrdatum->dfltlevel)); 229 230 if (strncasecmp(p, "range", 5)) 231 BADLINE(); 232 p += 5; 233 if (!isspace(*p)) 234 BADLINE(); 235 while (*p && isspace(*p)) 236 p++; 237 if (!(*p)) 238 BADLINE(); 239 q = p; 240 while (*p && *p != ';') 241 p++; 242 if (!(*p)) 243 BADLINE(); 244 *p++ = 0; 245 246 scontext = malloc(p - q); 247 if (!scontext) { 248 ERR(NULL, "out of memory"); 249 free(buffer); 250 fclose(fp); 251 return -1; 252 } 253 r = scontext; 254 s = q; 255 while (*s) { 256 if (!isspace(*s)) 257 *r++ = *s; 258 s++; 259 } 260 *r = 0; 261 r = scontext; 262 263 context_init(&context); 264 if (mls_context_to_sid(policydb, oldc, &r, &context) < 265 0) { 266 ERR(NULL, "invalid range %s (%s:%u)", scontext, 267 path, lineno); 268 free(scontext); 269 continue; 270 } 271 free(scontext); 272 memcpy(&usrdatum->range, &context.range, 273 sizeof(usrdatum->range)); 274 } 275 } 276 277 free(buffer); 278 fclose(fp); 279 return 0; 280} 281 282int sepol_genusers(void *data, size_t len, 283 const char *usersdir, void **newdata, size_t * newlen) 284{ 285 struct policydb policydb; 286 char path[PATH_MAX]; 287 288 /* Construct policy database */ 289 if (policydb_init(&policydb)) 290 goto err; 291 if (policydb_from_image(NULL, data, len, &policydb) < 0) 292 goto err; 293 294 /* Load locally defined users. */ 295 snprintf(path, sizeof path, "%s/local.users", usersdir); 296 if (load_users(&policydb, path) < 0) 297 goto err_destroy; 298 299 /* Write policy database */ 300 if (policydb_to_image(NULL, &policydb, newdata, newlen) < 0) 301 goto err_destroy; 302 303 policydb_destroy(&policydb); 304 return 0; 305 306 err_destroy: 307 policydb_destroy(&policydb); 308 309 err: 310 return -1; 311} 312 313int hidden sepol_genusers_policydb(policydb_t * policydb, const char *usersdir) 314{ 315 char path[PATH_MAX]; 316 317 /* Load locally defined users. */ 318 snprintf(path, sizeof path, "%s/local.users", usersdir); 319 if (load_users(policydb, path) < 0) { 320 ERR(NULL, "unable to load local.users: %s", strerror(errno)); 321 return -1; 322 } 323 324 if (policydb_reindex_users(policydb) < 0) { 325 ERR(NULL, "unable to reindex users: %s", strerror(errno)); 326 return -1; 327 328 } 329 330 return 0; 331} 332 333/* -- End Deprecated -- */ 334