38 39struct entry { 40 char *principal; 41 char *key; 42 char *max_life; 43 char *max_renew; 44 char *created; 45 char *modified; 46 char *valid_start; 47 char *valid_end; 48 char *pw_end; 49 char *flags; 50 char *etypes; 51}; 52 53static char * 54skip_next(char *p) 55{ 56 while(*p && !isspace((unsigned char)*p)) 57 p++; 58 *p++ = 0; 59 while(*p && isspace((unsigned char)*p)) 60 p++; 61 return p; 62} 63 64/* 65 * Parse the time in `s', returning: 66 * -1 if error parsing 67 * 0 if none present 68 * 1 if parsed ok 69 */ 70 71static int 72parse_time_string(time_t *t, const char *s) 73{ 74 int year, month, date, hour, minute, second; 75 struct tm tm; 76 77 if(strcmp(s, "-") == 0) 78 return 0; 79 if(sscanf(s, "%04d%02d%02d%02d%02d%02d", 80 &year, &month, &date, &hour, &minute, &second) != 6) 81 return -1; 82 tm.tm_year = year - 1900; 83 tm.tm_mon = month - 1; 84 tm.tm_mday = date; 85 tm.tm_hour = hour; 86 tm.tm_min = minute; 87 tm.tm_sec = second; 88 tm.tm_isdst = 0; 89 *t = timegm(&tm); 90 return 1; 91} 92 93/* 94 * parse time, allocating space in *t if it's there 95 */ 96 97static int 98parse_time_string_alloc (time_t **t, const char *s) 99{ 100 time_t tmp; 101 int ret; 102 103 *t = NULL; 104 ret = parse_time_string (&tmp, s); 105 if (ret == 1) { 106 *t = malloc (sizeof (**t)); 107 if (*t == NULL) 108 krb5_errx (context, 1, "malloc: out of memory"); 109 **t = tmp; 110 } 111 return ret; 112} 113 114/* 115 * see parse_time_string for calling convention 116 */ 117 118static int 119parse_integer(unsigned *u, const char *s) 120{ 121 if(strcmp(s, "-") == 0) 122 return 0; 123 if (sscanf(s, "%u", u) != 1) 124 return -1; 125 return 1; 126} 127 128static int 129parse_integer_alloc (int **u, const char *s) 130{ 131 unsigned tmp; 132 int ret; 133 134 *u = NULL; 135 ret = parse_integer (&tmp, s); 136 if (ret == 1) { 137 *u = malloc (sizeof (**u)); 138 if (*u == NULL) 139 krb5_errx (context, 1, "malloc: out of memory"); 140 **u = tmp; 141 } 142 return ret; 143} 144 145/* 146 * Parse dumped keys in `str' and store them in `ent' 147 * return -1 if parsing failed 148 */ 149 150static int 151parse_keys(hdb_entry *ent, char *str) 152{ 153 krb5_error_code ret; 154 int tmp; 155 char *p; 156 int i; 157 158 p = strsep(&str, ":"); 159 if (sscanf(p, "%d", &tmp) != 1) 160 return 1; 161 ent->kvno = tmp; 162 p = strsep(&str, ":"); 163 while(p){ 164 Key *key; 165 key = realloc(ent->keys.val, 166 (ent->keys.len + 1) * sizeof(*ent->keys.val)); 167 if(key == NULL) 168 krb5_errx (context, 1, "realloc: out of memory"); 169 ent->keys.val = key; 170 key = ent->keys.val + ent->keys.len; 171 ent->keys.len++; 172 memset(key, 0, sizeof(*key)); 173 if(sscanf(p, "%d", &tmp) == 1) { 174 key->mkvno = malloc(sizeof(*key->mkvno)); 175 *key->mkvno = tmp; 176 } else 177 key->mkvno = NULL; 178 p = strsep(&str, ":"); 179 if (sscanf(p, "%d", &tmp) != 1) 180 return 1; 181 key->key.keytype = tmp; 182 p = strsep(&str, ":"); 183 ret = krb5_data_alloc(&key->key.keyvalue, (strlen(p) - 1) / 2 + 1); 184 if (ret) 185 krb5_err (context, 1, ret, "krb5_data_alloc"); 186 for(i = 0; i < strlen(p); i += 2) { 187 if(sscanf(p + i, "%02x", &tmp) != 1) 188 return 1; 189 ((u_char*)key->key.keyvalue.data)[i / 2] = tmp; 190 } 191 p = strsep(&str, ":"); 192 if(strcmp(p, "-") != 0){ 193 unsigned type; 194 size_t p_len; 195 196 if(sscanf(p, "%u/", &type) != 1) 197 return 1; 198 p = strchr(p, '/'); 199 if(p == NULL) 200 return 1; 201 p++; 202 p_len = strlen(p); 203 204 key->salt = malloc(sizeof(*key->salt)); 205 if (key->salt == NULL) 206 krb5_errx (context, 1, "malloc: out of memory"); 207 key->salt->type = type; 208 209 if (p_len) { 210 if(*p == '\"') { 211 ret = krb5_data_copy(&key->salt->salt, p + 1, p_len - 2); 212 if (ret) 213 krb5_err (context, 1, ret, "krb5_data_copy"); 214 } else { 215 ret = krb5_data_alloc(&key->salt->salt, 216 (p_len - 1) / 2 + 1); 217 if (ret) 218 krb5_err (context, 1, ret, "krb5_data_alloc"); 219 for(i = 0; i < p_len; i += 2){ 220 if (sscanf(p + i, "%02x", &tmp) != 1) 221 return 1; 222 ((u_char*)key->salt->salt.data)[i / 2] = tmp; 223 } 224 } 225 } else 226 krb5_data_zero (&key->salt->salt); 227 } 228 p = strsep(&str, ":"); 229 } 230 return 0; 231} 232 233/* 234 * see parse_time_string for calling convention 235 */ 236 237static int 238parse_event(Event *ev, char *s) 239{ 240 krb5_error_code ret; 241 char *p; 242 243 if(strcmp(s, "-") == 0) 244 return 0; 245 memset(ev, 0, sizeof(*ev)); 246 p = strsep(&s, ":"); 247 if(parse_time_string(&ev->time, p) != 1) 248 return -1; 249 p = strsep(&s, ":"); 250 ret = krb5_parse_name(context, p, &ev->principal); 251 if (ret) 252 return -1; 253 return 1; 254} 255 256static int 257parse_event_alloc (Event **ev, char *s) 258{ 259 Event tmp; 260 int ret; 261 262 *ev = NULL; 263 ret = parse_event (&tmp, s); 264 if (ret == 1) { 265 *ev = malloc (sizeof (**ev)); 266 if (*ev == NULL) 267 krb5_errx (context, 1, "malloc: out of memory"); 268 **ev = tmp; 269 } 270 return ret; 271} 272 273static int 274parse_hdbflags2int(HDBFlags *f, const char *s) 275{ 276 int ret; 277 unsigned tmp; 278 279 ret = parse_integer (&tmp, s); 280 if (ret == 1) 281 *f = int2HDBFlags (tmp); 282 return ret; 283} 284 285#if 0 286static void 287parse_etypes(char *str, unsigned **val, unsigned *len) 288{ 289 unsigned v; 290 291 *val = NULL; 292 *len = 0; 293 while(sscanf(str, "%u", &v) == 1) { 294 *val = realloc(*val, (*len+1) * sizeof(**val)); 295 (*val)[(*len)++] = v; 296 str = strchr(str, ':'); 297 if(str == NULL) 298 break; 299 str++; 300 } 301} 302#endif 303 304/* 305 * Parse the dump file in `filename' and create the database (merging 306 * iff merge) 307 */ 308 309static int 310doit(const char *filename, int merge) 311{ 312 krb5_error_code ret; 313 FILE *f; 314 char s[1024]; 315 char *p; 316 int line; 317 int flags = O_RDWR; 318 struct entry e; 319 hdb_entry ent; 320 HDB *db = _kadm5_s_get_db(kadm_handle); 321 322 f = fopen(filename, "r"); 323 if(f == NULL){ 324 krb5_warn(context, errno, "fopen(%s)", filename); 325 return 1; 326 } 327 if(!merge) 328 flags |= O_CREAT | O_TRUNC; 329 ret = db->open(context, db, flags, 0600); 330 if(ret){ 331 krb5_warn(context, ret, "hdb_open"); 332 fclose(f); 333 return 1; 334 } 335 line = 0; 336 while(fgets(s, sizeof(s), f)){ 337 line++; 338 e.principal = s; 339 for(p = s; *p; p++){ 340 if(*p == '\\') 341 p++; 342 else if(isspace((unsigned char)*p)) { 343 *p = 0; 344 break; 345 } 346 } 347 p = skip_next(p); 348 349 e.key = p; 350 p = skip_next(p); 351 352 e.created = p; 353 p = skip_next(p); 354 355 e.modified = p; 356 p = skip_next(p); 357 358 e.valid_start = p; 359 p = skip_next(p); 360 361 e.valid_end = p; 362 p = skip_next(p); 363 364 e.pw_end = p; 365 p = skip_next(p); 366 367 e.max_life = p; 368 p = skip_next(p); 369 370 e.max_renew = p; 371 p = skip_next(p); 372 373 e.flags = p; 374 p = skip_next(p); 375 376 e.etypes = p; 377 p = skip_next(p); 378 379 memset(&ent, 0, sizeof(ent)); 380 ret = krb5_parse_name(context, e.principal, &ent.principal); 381 if(ret) { 382 fprintf(stderr, "%s:%d:%s (%s)\n", 383 filename, 384 line, 385 krb5_get_err_text(context, ret), 386 e.principal); 387 continue; 388 } 389 390 if (parse_keys(&ent, e.key)) { 391 fprintf (stderr, "%s:%d:error parsing keys (%s)\n", 392 filename, line, e.key); 393 hdb_free_entry (context, &ent); 394 continue; 395 } 396 397 if (parse_event(&ent.created_by, e.created) == -1) { 398 fprintf (stderr, "%s:%d:error parsing created event (%s)\n", 399 filename, line, e.created); 400 hdb_free_entry (context, &ent); 401 continue; 402 } 403 if (parse_event_alloc (&ent.modified_by, e.modified) == -1) { 404 fprintf (stderr, "%s:%d:error parsing event (%s)\n", 405 filename, line, e.modified); 406 hdb_free_entry (context, &ent); 407 continue; 408 } 409 if (parse_time_string_alloc (&ent.valid_start, e.valid_start) == -1) { 410 fprintf (stderr, "%s:%d:error parsing time (%s)\n", 411 filename, line, e.valid_start); 412 hdb_free_entry (context, &ent); 413 continue; 414 } 415 if (parse_time_string_alloc (&ent.valid_end, e.valid_end) == -1) { 416 fprintf (stderr, "%s:%d:error parsing time (%s)\n", 417 filename, line, e.valid_end); 418 hdb_free_entry (context, &ent); 419 continue; 420 } 421 if (parse_time_string_alloc (&ent.pw_end, e.pw_end) == -1) { 422 fprintf (stderr, "%s:%d:error parsing time (%s)\n", 423 filename, line, e.pw_end); 424 hdb_free_entry (context, &ent); 425 continue; 426 } 427 428 if (parse_integer_alloc (&ent.max_life, e.max_life) == -1) { 429 fprintf (stderr, "%s:%d:error parsing lifetime (%s)\n", 430 filename, line, e.max_life); 431 hdb_free_entry (context, &ent); 432 continue; 433 434 } 435 if (parse_integer_alloc (&ent.max_renew, e.max_renew) == -1) { 436 fprintf (stderr, "%s:%d:error parsing lifetime (%s)\n", 437 filename, line, e.max_renew); 438 hdb_free_entry (context, &ent); 439 continue; 440 } 441
| 38 39struct entry { 40 char *principal; 41 char *key; 42 char *max_life; 43 char *max_renew; 44 char *created; 45 char *modified; 46 char *valid_start; 47 char *valid_end; 48 char *pw_end; 49 char *flags; 50 char *etypes; 51}; 52 53static char * 54skip_next(char *p) 55{ 56 while(*p && !isspace((unsigned char)*p)) 57 p++; 58 *p++ = 0; 59 while(*p && isspace((unsigned char)*p)) 60 p++; 61 return p; 62} 63 64/* 65 * Parse the time in `s', returning: 66 * -1 if error parsing 67 * 0 if none present 68 * 1 if parsed ok 69 */ 70 71static int 72parse_time_string(time_t *t, const char *s) 73{ 74 int year, month, date, hour, minute, second; 75 struct tm tm; 76 77 if(strcmp(s, "-") == 0) 78 return 0; 79 if(sscanf(s, "%04d%02d%02d%02d%02d%02d", 80 &year, &month, &date, &hour, &minute, &second) != 6) 81 return -1; 82 tm.tm_year = year - 1900; 83 tm.tm_mon = month - 1; 84 tm.tm_mday = date; 85 tm.tm_hour = hour; 86 tm.tm_min = minute; 87 tm.tm_sec = second; 88 tm.tm_isdst = 0; 89 *t = timegm(&tm); 90 return 1; 91} 92 93/* 94 * parse time, allocating space in *t if it's there 95 */ 96 97static int 98parse_time_string_alloc (time_t **t, const char *s) 99{ 100 time_t tmp; 101 int ret; 102 103 *t = NULL; 104 ret = parse_time_string (&tmp, s); 105 if (ret == 1) { 106 *t = malloc (sizeof (**t)); 107 if (*t == NULL) 108 krb5_errx (context, 1, "malloc: out of memory"); 109 **t = tmp; 110 } 111 return ret; 112} 113 114/* 115 * see parse_time_string for calling convention 116 */ 117 118static int 119parse_integer(unsigned *u, const char *s) 120{ 121 if(strcmp(s, "-") == 0) 122 return 0; 123 if (sscanf(s, "%u", u) != 1) 124 return -1; 125 return 1; 126} 127 128static int 129parse_integer_alloc (int **u, const char *s) 130{ 131 unsigned tmp; 132 int ret; 133 134 *u = NULL; 135 ret = parse_integer (&tmp, s); 136 if (ret == 1) { 137 *u = malloc (sizeof (**u)); 138 if (*u == NULL) 139 krb5_errx (context, 1, "malloc: out of memory"); 140 **u = tmp; 141 } 142 return ret; 143} 144 145/* 146 * Parse dumped keys in `str' and store them in `ent' 147 * return -1 if parsing failed 148 */ 149 150static int 151parse_keys(hdb_entry *ent, char *str) 152{ 153 krb5_error_code ret; 154 int tmp; 155 char *p; 156 int i; 157 158 p = strsep(&str, ":"); 159 if (sscanf(p, "%d", &tmp) != 1) 160 return 1; 161 ent->kvno = tmp; 162 p = strsep(&str, ":"); 163 while(p){ 164 Key *key; 165 key = realloc(ent->keys.val, 166 (ent->keys.len + 1) * sizeof(*ent->keys.val)); 167 if(key == NULL) 168 krb5_errx (context, 1, "realloc: out of memory"); 169 ent->keys.val = key; 170 key = ent->keys.val + ent->keys.len; 171 ent->keys.len++; 172 memset(key, 0, sizeof(*key)); 173 if(sscanf(p, "%d", &tmp) == 1) { 174 key->mkvno = malloc(sizeof(*key->mkvno)); 175 *key->mkvno = tmp; 176 } else 177 key->mkvno = NULL; 178 p = strsep(&str, ":"); 179 if (sscanf(p, "%d", &tmp) != 1) 180 return 1; 181 key->key.keytype = tmp; 182 p = strsep(&str, ":"); 183 ret = krb5_data_alloc(&key->key.keyvalue, (strlen(p) - 1) / 2 + 1); 184 if (ret) 185 krb5_err (context, 1, ret, "krb5_data_alloc"); 186 for(i = 0; i < strlen(p); i += 2) { 187 if(sscanf(p + i, "%02x", &tmp) != 1) 188 return 1; 189 ((u_char*)key->key.keyvalue.data)[i / 2] = tmp; 190 } 191 p = strsep(&str, ":"); 192 if(strcmp(p, "-") != 0){ 193 unsigned type; 194 size_t p_len; 195 196 if(sscanf(p, "%u/", &type) != 1) 197 return 1; 198 p = strchr(p, '/'); 199 if(p == NULL) 200 return 1; 201 p++; 202 p_len = strlen(p); 203 204 key->salt = malloc(sizeof(*key->salt)); 205 if (key->salt == NULL) 206 krb5_errx (context, 1, "malloc: out of memory"); 207 key->salt->type = type; 208 209 if (p_len) { 210 if(*p == '\"') { 211 ret = krb5_data_copy(&key->salt->salt, p + 1, p_len - 2); 212 if (ret) 213 krb5_err (context, 1, ret, "krb5_data_copy"); 214 } else { 215 ret = krb5_data_alloc(&key->salt->salt, 216 (p_len - 1) / 2 + 1); 217 if (ret) 218 krb5_err (context, 1, ret, "krb5_data_alloc"); 219 for(i = 0; i < p_len; i += 2){ 220 if (sscanf(p + i, "%02x", &tmp) != 1) 221 return 1; 222 ((u_char*)key->salt->salt.data)[i / 2] = tmp; 223 } 224 } 225 } else 226 krb5_data_zero (&key->salt->salt); 227 } 228 p = strsep(&str, ":"); 229 } 230 return 0; 231} 232 233/* 234 * see parse_time_string for calling convention 235 */ 236 237static int 238parse_event(Event *ev, char *s) 239{ 240 krb5_error_code ret; 241 char *p; 242 243 if(strcmp(s, "-") == 0) 244 return 0; 245 memset(ev, 0, sizeof(*ev)); 246 p = strsep(&s, ":"); 247 if(parse_time_string(&ev->time, p) != 1) 248 return -1; 249 p = strsep(&s, ":"); 250 ret = krb5_parse_name(context, p, &ev->principal); 251 if (ret) 252 return -1; 253 return 1; 254} 255 256static int 257parse_event_alloc (Event **ev, char *s) 258{ 259 Event tmp; 260 int ret; 261 262 *ev = NULL; 263 ret = parse_event (&tmp, s); 264 if (ret == 1) { 265 *ev = malloc (sizeof (**ev)); 266 if (*ev == NULL) 267 krb5_errx (context, 1, "malloc: out of memory"); 268 **ev = tmp; 269 } 270 return ret; 271} 272 273static int 274parse_hdbflags2int(HDBFlags *f, const char *s) 275{ 276 int ret; 277 unsigned tmp; 278 279 ret = parse_integer (&tmp, s); 280 if (ret == 1) 281 *f = int2HDBFlags (tmp); 282 return ret; 283} 284 285#if 0 286static void 287parse_etypes(char *str, unsigned **val, unsigned *len) 288{ 289 unsigned v; 290 291 *val = NULL; 292 *len = 0; 293 while(sscanf(str, "%u", &v) == 1) { 294 *val = realloc(*val, (*len+1) * sizeof(**val)); 295 (*val)[(*len)++] = v; 296 str = strchr(str, ':'); 297 if(str == NULL) 298 break; 299 str++; 300 } 301} 302#endif 303 304/* 305 * Parse the dump file in `filename' and create the database (merging 306 * iff merge) 307 */ 308 309static int 310doit(const char *filename, int merge) 311{ 312 krb5_error_code ret; 313 FILE *f; 314 char s[1024]; 315 char *p; 316 int line; 317 int flags = O_RDWR; 318 struct entry e; 319 hdb_entry ent; 320 HDB *db = _kadm5_s_get_db(kadm_handle); 321 322 f = fopen(filename, "r"); 323 if(f == NULL){ 324 krb5_warn(context, errno, "fopen(%s)", filename); 325 return 1; 326 } 327 if(!merge) 328 flags |= O_CREAT | O_TRUNC; 329 ret = db->open(context, db, flags, 0600); 330 if(ret){ 331 krb5_warn(context, ret, "hdb_open"); 332 fclose(f); 333 return 1; 334 } 335 line = 0; 336 while(fgets(s, sizeof(s), f)){ 337 line++; 338 e.principal = s; 339 for(p = s; *p; p++){ 340 if(*p == '\\') 341 p++; 342 else if(isspace((unsigned char)*p)) { 343 *p = 0; 344 break; 345 } 346 } 347 p = skip_next(p); 348 349 e.key = p; 350 p = skip_next(p); 351 352 e.created = p; 353 p = skip_next(p); 354 355 e.modified = p; 356 p = skip_next(p); 357 358 e.valid_start = p; 359 p = skip_next(p); 360 361 e.valid_end = p; 362 p = skip_next(p); 363 364 e.pw_end = p; 365 p = skip_next(p); 366 367 e.max_life = p; 368 p = skip_next(p); 369 370 e.max_renew = p; 371 p = skip_next(p); 372 373 e.flags = p; 374 p = skip_next(p); 375 376 e.etypes = p; 377 p = skip_next(p); 378 379 memset(&ent, 0, sizeof(ent)); 380 ret = krb5_parse_name(context, e.principal, &ent.principal); 381 if(ret) { 382 fprintf(stderr, "%s:%d:%s (%s)\n", 383 filename, 384 line, 385 krb5_get_err_text(context, ret), 386 e.principal); 387 continue; 388 } 389 390 if (parse_keys(&ent, e.key)) { 391 fprintf (stderr, "%s:%d:error parsing keys (%s)\n", 392 filename, line, e.key); 393 hdb_free_entry (context, &ent); 394 continue; 395 } 396 397 if (parse_event(&ent.created_by, e.created) == -1) { 398 fprintf (stderr, "%s:%d:error parsing created event (%s)\n", 399 filename, line, e.created); 400 hdb_free_entry (context, &ent); 401 continue; 402 } 403 if (parse_event_alloc (&ent.modified_by, e.modified) == -1) { 404 fprintf (stderr, "%s:%d:error parsing event (%s)\n", 405 filename, line, e.modified); 406 hdb_free_entry (context, &ent); 407 continue; 408 } 409 if (parse_time_string_alloc (&ent.valid_start, e.valid_start) == -1) { 410 fprintf (stderr, "%s:%d:error parsing time (%s)\n", 411 filename, line, e.valid_start); 412 hdb_free_entry (context, &ent); 413 continue; 414 } 415 if (parse_time_string_alloc (&ent.valid_end, e.valid_end) == -1) { 416 fprintf (stderr, "%s:%d:error parsing time (%s)\n", 417 filename, line, e.valid_end); 418 hdb_free_entry (context, &ent); 419 continue; 420 } 421 if (parse_time_string_alloc (&ent.pw_end, e.pw_end) == -1) { 422 fprintf (stderr, "%s:%d:error parsing time (%s)\n", 423 filename, line, e.pw_end); 424 hdb_free_entry (context, &ent); 425 continue; 426 } 427 428 if (parse_integer_alloc (&ent.max_life, e.max_life) == -1) { 429 fprintf (stderr, "%s:%d:error parsing lifetime (%s)\n", 430 filename, line, e.max_life); 431 hdb_free_entry (context, &ent); 432 continue; 433 434 } 435 if (parse_integer_alloc (&ent.max_renew, e.max_renew) == -1) { 436 fprintf (stderr, "%s:%d:error parsing lifetime (%s)\n", 437 filename, line, e.max_renew); 438 hdb_free_entry (context, &ent); 439 continue; 440 } 441
|