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 if (!id) { 96 ERR(NULL, "out of memory"); 97 free(buffer); 98 fclose(fp); 99 return -1; 100 } 101 102 /* Adding a new user definition. */ 103 usrdatum = malloc(sizeof(user_datum_t)); 104 if (!usrdatum) { 105 ERR(NULL, "out of memory"); 106 free(buffer); 107 free(id); 108 fclose(fp); 109 return -1; 110 } 111 112 user_datum_init(usrdatum); 113 usrdatum->s.value = ++policydb->p_users.nprim; 114 if (hashtab_insert(policydb->p_users.table, 115 id, (hashtab_datum_t) usrdatum)) { 116 ERR(NULL, "out of memory"); 117 free(buffer); 118 free(id); 119 user_datum_destroy(usrdatum); 120 free(usrdatum); 121 fclose(fp); 122 return -1; 123 } 124 } 125 126 while (*p && isspace(*p)) 127 p++; 128 if (!(*p)) 129 BADLINE(); 130 if (strncasecmp(p, "roles", 5)) 131 BADLINE(); 132 p += 5; 133 if (!isspace(*p)) 134 BADLINE(); 135 while (*p && isspace(*p)) 136 p++; 137 if (!(*p)) 138 BADLINE(); 139 if (*p == '{') { 140 islist = 1; 141 p++; 142 } else 143 islist = 0; 144 145 oldc = 0; 146 do { 147 while (*p && isspace(*p)) 148 p++; 149 if (!(*p)) 150 break; 151 152 q = p; 153 while (*p && *p != ';' && *p != '}' && !isspace(*p)) 154 p++; 155 if (!(*p)) 156 break; 157 if (*p == '}') 158 islist = 0; 159 oldc = *p; 160 *p++ = 0; 161 if (!q[0]) 162 break; 163 164 roldatum = hashtab_search(policydb->p_roles.table, q); 165 if (!roldatum) { 166 ERR(NULL, "undefined role %s (%s:%u)", 167 q, path, lineno); 168 continue; 169 } 170 /* Set the role and every role it dominates */ 171 ebitmap_for_each_bit(&roldatum->dominates, rnode, bit) { 172 if (ebitmap_node_get_bit(rnode, bit)) 173 if (ebitmap_set_bit 174 (&usrdatum->roles.roles, bit, 1)) { 175 ERR(NULL, "out of memory"); 176 free(buffer); 177 fclose(fp); 178 return -1; 179 } 180 } 181 } while (islist); 182 if (oldc == 0) 183 BADLINE(); 184 185 if (policydb->mls) { 186 context_struct_t context; 187 char *scontext, *r, *s; 188 189 while (*p && isspace(*p)) 190 p++; 191 if (!(*p)) 192 BADLINE(); 193 if (strncasecmp(p, "level", 5)) 194 BADLINE(); 195 p += 5; 196 if (!isspace(*p)) 197 BADLINE(); 198 while (*p && isspace(*p)) 199 p++; 200 if (!(*p)) 201 BADLINE(); 202 q = p; 203 while (*p && strncasecmp(p, "range", 5)) 204 p++; 205 if (!(*p)) 206 BADLINE(); 207 *--p = 0; 208 p++; 209 210 scontext = malloc(p - q); 211 if (!scontext) { 212 ERR(NULL, "out of memory"); 213 free(buffer); 214 fclose(fp); 215 return -1; 216 } 217 r = scontext; 218 s = q; 219 while (*s) { 220 if (!isspace(*s)) 221 *r++ = *s; 222 s++; 223 } 224 *r = 0; 225 r = scontext; 226 227 context_init(&context); 228 if (mls_context_to_sid(policydb, oldc, &r, &context) < 229 0) { 230 ERR(NULL, "invalid level %s (%s:%u)", scontext, 231 path, lineno); 232 free(scontext); 233 continue; 234 235 } 236 free(scontext); 237 memcpy(&usrdatum->dfltlevel, &context.range.level[0], 238 sizeof(usrdatum->dfltlevel)); 239 240 if (strncasecmp(p, "range", 5)) 241 BADLINE(); 242 p += 5; 243 if (!isspace(*p)) 244 BADLINE(); 245 while (*p && isspace(*p)) 246 p++; 247 if (!(*p)) 248 BADLINE(); 249 q = p; 250 while (*p && *p != ';') 251 p++; 252 if (!(*p)) 253 BADLINE(); 254 *p++ = 0; 255 256 scontext = malloc(p - q); 257 if (!scontext) { 258 ERR(NULL, "out of memory"); 259 free(buffer); 260 fclose(fp); 261 return -1; 262 } 263 r = scontext; 264 s = q; 265 while (*s) { 266 if (!isspace(*s)) 267 *r++ = *s; 268 s++; 269 } 270 *r = 0; 271 r = scontext; 272 273 context_init(&context); 274 if (mls_context_to_sid(policydb, oldc, &r, &context) < 275 0) { 276 ERR(NULL, "invalid range %s (%s:%u)", scontext, 277 path, lineno); 278 free(scontext); 279 continue; 280 } 281 free(scontext); 282 memcpy(&usrdatum->range, &context.range, 283 sizeof(usrdatum->range)); 284 } 285 } 286 287 free(buffer); 288 fclose(fp); 289 return 0; 290} 291 292int sepol_genusers(void *data, size_t len, 293 const char *usersdir, void **newdata, size_t * newlen) 294{ 295 struct policydb policydb; 296 char path[PATH_MAX]; 297 298 /* Construct policy database */ 299 if (policydb_init(&policydb)) 300 goto err; 301 if (policydb_from_image(NULL, data, len, &policydb) < 0) 302 goto err; 303 304 /* Load locally defined users. */ 305 snprintf(path, sizeof path, "%s/local.users", usersdir); 306 if (load_users(&policydb, path) < 0) 307 goto err_destroy; 308 309 /* Write policy database */ 310 if (policydb_to_image(NULL, &policydb, newdata, newlen) < 0) 311 goto err_destroy; 312 313 policydb_destroy(&policydb); 314 return 0; 315 316 err_destroy: 317 policydb_destroy(&policydb); 318 319 err: 320 return -1; 321} 322 323int hidden sepol_genusers_policydb(policydb_t * policydb, const char *usersdir) 324{ 325 char path[PATH_MAX]; 326 327 /* Load locally defined users. */ 328 snprintf(path, sizeof path, "%s/local.users", usersdir); 329 if (load_users(policydb, path) < 0) { 330 ERR(NULL, "unable to load local.users: %s", strerror(errno)); 331 return -1; 332 } 333 334 if (policydb_reindex_users(policydb) < 0) { 335 ERR(NULL, "unable to reindex users: %s", strerror(errno)); 336 return -1; 337 338 } 339 340 return 0; 341} 342 343/* -- End Deprecated -- */ 344