1 /* 2 * Copyright (c) 2000 Kungliga Tekniska Högskolan 3 * (Royal Institute of Technology, Stockholm, Sweden). 4 * All rights reserved. 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions 8 * are met: 9 * 10 * 1. Redistributions of source code must retain the above copyright 11 * notice, this list of conditions and the following disclaimer. 12 * 13 * 2. Redistributions in binary form must reproduce the above copyright 14 * notice, this list of conditions and the following disclaimer in the 15 * documentation and/or other materials provided with the distribution. 16 * 17 * 3. Neither the name of the Institute nor the names of its contributors 18 * may be used to endorse or promote products derived from this software 19 * without specific prior written permission. 20 * 21 * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND 22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 24 * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE 25 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 31 * SUCH DAMAGE. 32 */ 33 34 #include "hprop.h" 35 36 extern krb5_error_code _hdb_mdb_value2entry(krb5_context context, 37 krb5_data *data, 38 krb5_kvno target_kvno, 39 hdb_entry *entry); 40 41 extern int _hdb_mit_dump2mitdb_entry(krb5_context context, 42 char *line, 43 krb5_storage *sp); 44 45 46 47 /* 48 can have any number of princ stanzas. 49 format is as follows (only \n indicates newlines) 50 princ\t%d\t (%d is KRB5_KDB_V1_BASE_LENGTH, always 38) 51 %d\t (strlen of principal e.g. shadow/foo@ANDREW.CMU.EDU) 52 %d\t (number of tl_data) 53 %d\t (number of key data, e.g. how many keys for this user) 54 %d\t (extra data length) 55 %s\t (principal name) 56 %d\t (attributes) 57 %d\t (max lifetime, seconds) 58 %d\t (max renewable life, seconds) 59 %d\t (expiration, seconds since epoch or 2145830400 for never) 60 %d\t (password expiration, seconds, 0 for never) 61 %d\t (last successful auth, seconds since epoch) 62 %d\t (last failed auth, per above) 63 %d\t (failed auth count) 64 foreach tl_data 0 to number of tl_data - 1 as above 65 %d\t%d\t (data type, data length) 66 foreach tl_data 0 to length-1 67 %02x (tl data contents[element n]) 68 except if tl_data length is 0 69 %d (always -1) 70 \t 71 foreach key 0 to number of keys - 1 as above 72 %d\t%d\t (key data version, kvno) 73 foreach version 0 to key data version - 1 (a key or a salt) 74 %d\t%d\t(data type for this key, data length for this key) 75 foreach key data length 0 to length-1 76 %02x (key data contents[element n]) 77 except if key_data length is 0 78 %d (always -1) 79 \t 80 foreach extra data length 0 to length - 1 81 %02x (extra data part) 82 unless no extra data 83 %d (always -1) 84 ;\n 85 86 */ 87 88 static char * 89 nexttoken(char **p) 90 { 91 char *q; 92 do { 93 q = strsep(p, " \t"); 94 } while(q && *q == '\0'); 95 return q; 96 } 97 98 #include <kadm5/admin.h> 99 100 static int 101 my_fgetln(FILE *f, char **buf, size_t *sz, size_t *len) 102 { 103 char *p, *n; 104 105 if (!*buf) { 106 *buf = malloc(*sz ? *sz : 2048); 107 if (!*buf) 108 return ENOMEM; 109 if (!*sz) 110 *sz = 2048; 111 } 112 *len = 0; 113 while ((p = fgets(&(*buf)[*len], *sz, f))) { 114 if (strcspn(*buf, "\r\n") || feof(f)) { 115 *len = strlen(*buf); 116 return 0; 117 } 118 *len += strlen(&(*buf)[*len]); /* *len should be == *sz */ 119 n = realloc(buf, *sz + (*sz >> 1)); 120 if (!n) { 121 free(*buf); 122 *buf = NULL; 123 *sz = 0; 124 *len = 0; 125 return ENOMEM; 126 } 127 *buf = n; 128 *sz += *sz >> 1; 129 } 130 return 0; /* *len == 0 || no EOL -> EOF */ 131 } 132 133 int 134 mit_prop_dump(void *arg, const char *file) 135 { 136 krb5_error_code ret; 137 size_t line_bufsz = 0; 138 size_t line_len = 0; 139 char *line = NULL; 140 int lineno = 0; 141 FILE *f; 142 struct hdb_entry_ex ent; 143 struct prop_data *pd = arg; 144 krb5_storage *sp = NULL; 145 krb5_data kdb_ent; 146 147 memset(&ent, 0, sizeof (ent)); 148 f = fopen(file, "r"); 149 if (f == NULL) 150 return errno; 151 152 ret = ENOMEM; 153 sp = krb5_storage_emem(); 154 if (!sp) 155 goto out; 156 while ((ret = my_fgetln(f, &line, &line_bufsz, &line_len)) == 0) { 157 char *p = line; 158 char *q; 159 lineno++; 160 161 if(strncmp(line, "kdb5_util", strlen("kdb5_util")) == 0) { 162 int major; 163 q = nexttoken(&p); 164 if (strcmp(q, "kdb5_util")) 165 errx(1, "line %d: unknown version", lineno); 166 q = nexttoken(&p); /* load_dump */ 167 if (strcmp(q, "load_dump")) 168 errx(1, "line %d: unknown version", lineno); 169 q = nexttoken(&p); /* load_dump */ 170 if (strcmp(q, "version")) 171 errx(1, "line %d: unknown version", lineno); 172 q = nexttoken(&p); /* x.0 */ 173 if (sscanf(q, "%d", &major) != 1) 174 errx(1, "line %d: unknown version", lineno); 175 if (major != 4 && major != 5 && major != 6) 176 errx(1, "unknown dump file format, got %d, expected 4-6", 177 major); 178 continue; 179 } else if(strncmp(p, "policy", strlen("policy")) == 0) { 180 warnx("line: %d: ignoring policy (not supported)", lineno); 181 continue; 182 } else if(strncmp(p, "princ", strlen("princ")) != 0) { 183 warnx("line %d: not a principal", lineno); 184 continue; 185 } 186 krb5_storage_truncate(sp, 0); 187 ret = _hdb_mit_dump2mitdb_entry(pd->context, line, sp); 188 if (ret) break; 189 ret = krb5_storage_to_data(sp, &kdb_ent); 190 if (ret) break; 191 ret = _hdb_mdb_value2entry(pd->context, &kdb_ent, 0, &ent.entry); 192 krb5_data_free(&kdb_ent); 193 if (ret) break; 194 ret = v5_prop(pd->context, NULL, &ent, arg); 195 hdb_free_entry(pd->context, &ent); 196 if (ret) break; 197 } 198 199 out: 200 fclose(f); 201 free(line); 202 if (sp) 203 krb5_storage_free(sp); 204 if (ret && ret == ENOMEM) 205 errx(1, "out of memory"); 206 if (ret) 207 errx(1, "line %d: problem parsing dump line", lineno); 208 return ret; 209 } 210 211