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