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