1 /* $NetBSD: dbinfo.c,v 1.2 2017/01/28 21:31:48 christos Exp $ */ 2 3 /* 4 * Copyright (c) 2005 Kungliga Tekniska Högskolan 5 * (Royal Institute of Technology, Stockholm, Sweden). 6 * All rights reserved. 7 * 8 * Redistribution and use in source and binary forms, with or without 9 * modification, are permitted provided that the following conditions 10 * are met: 11 * 12 * 1. Redistributions of source code must retain the above copyright 13 * notice, this list of conditions and the following disclaimer. 14 * 15 * 2. Redistributions in binary form must reproduce the above copyright 16 * notice, this list of conditions and the following disclaimer in the 17 * documentation and/or other materials provided with the distribution. 18 * 19 * 3. Neither the name of the Institute nor the names of its contributors 20 * may be used to endorse or promote products derived from this software 21 * without specific prior written permission. 22 * 23 * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND 24 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 25 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 26 * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE 27 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 28 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 29 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 30 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 31 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 32 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 33 * SUCH DAMAGE. 34 */ 35 36 #include "hdb_locl.h" 37 38 struct hdb_dbinfo { 39 char *label; 40 char *realm; 41 char *dbname; 42 char *mkey_file; 43 char *acl_file; 44 char *log_file; 45 const krb5_config_binding *binding; 46 struct hdb_dbinfo *next; 47 }; 48 49 static int 50 get_dbinfo(krb5_context context, 51 const krb5_config_binding *db_binding, 52 const char *label, 53 struct hdb_dbinfo **db) 54 { 55 struct hdb_dbinfo *di; 56 const char *p; 57 58 *db = NULL; 59 60 p = krb5_config_get_string(context, db_binding, "dbname", NULL); 61 if(p == NULL) 62 return 0; 63 64 di = calloc(1, sizeof(*di)); 65 if (di == NULL) { 66 krb5_set_error_message(context, ENOMEM, "malloc: out of memory"); 67 return ENOMEM; 68 } 69 di->label = strdup(label); 70 di->dbname = strdup(p); 71 72 p = krb5_config_get_string(context, db_binding, "realm", NULL); 73 if(p) 74 di->realm = strdup(p); 75 p = krb5_config_get_string(context, db_binding, "mkey_file", NULL); 76 if(p) 77 di->mkey_file = strdup(p); 78 p = krb5_config_get_string(context, db_binding, "acl_file", NULL); 79 if(p) 80 di->acl_file = strdup(p); 81 p = krb5_config_get_string(context, db_binding, "log_file", NULL); 82 if(p) 83 di->log_file = strdup(p); 84 85 di->binding = db_binding; 86 87 *db = di; 88 return 0; 89 } 90 91 92 int 93 hdb_get_dbinfo(krb5_context context, struct hdb_dbinfo **dbp) 94 { 95 const krb5_config_binding *db_binding; 96 struct hdb_dbinfo *di, **dt, *databases; 97 const char *default_dbname = HDB_DEFAULT_DB; 98 const char *default_mkey = HDB_DB_DIR "/m-key"; 99 const char *default_acl = HDB_DB_DIR "/kadmind.acl"; 100 const char *p; 101 int ret; 102 103 *dbp = NULL; 104 dt = NULL; 105 databases = NULL; 106 107 db_binding = krb5_config_get_list(context, NULL, 108 "kdc", 109 "database", 110 NULL); 111 if (db_binding) { 112 113 ret = get_dbinfo(context, db_binding, "default", &databases); 114 if (ret == 0 && databases != NULL) 115 dt = &databases->next; 116 117 for ( ; db_binding != NULL; db_binding = db_binding->next) { 118 119 if (db_binding->type != krb5_config_list) 120 continue; 121 122 ret = get_dbinfo(context, db_binding->u.list, 123 db_binding->name, &di); 124 if (ret) 125 krb5_err(context, 1, ret, "failed getting realm"); 126 127 if (di == NULL) 128 continue; 129 130 if (dt) 131 *dt = di; 132 else { 133 hdb_free_dbinfo(context, &databases); 134 databases = di; 135 } 136 dt = &di->next; 137 138 } 139 } 140 141 if (databases == NULL) { 142 /* if there are none specified, create one and use defaults */ 143 databases = calloc(1, sizeof(*databases)); 144 databases->label = strdup("default"); 145 } 146 147 for (di = databases; di; di = di->next) { 148 if (di->dbname == NULL) { 149 di->dbname = strdup(default_dbname); 150 if (di->mkey_file == NULL) 151 di->mkey_file = strdup(default_mkey); 152 } 153 if (di->mkey_file == NULL) { 154 p = strrchr(di->dbname, '.'); 155 if(p == NULL || strchr(p, '/') != NULL) 156 /* final pathname component does not contain a . */ 157 ret = asprintf(&di->mkey_file, "%s.mkey", di->dbname); 158 else 159 /* the filename is something.else, replace .else with 160 .mkey */ 161 ret = asprintf(&di->mkey_file, "%.*s.mkey", 162 (int)(p - di->dbname), di->dbname); 163 if (ret == -1) { 164 hdb_free_dbinfo(context, &databases); 165 return ENOMEM; 166 } 167 } 168 if(di->acl_file == NULL) 169 di->acl_file = strdup(default_acl); 170 } 171 *dbp = databases; 172 return 0; 173 } 174 175 176 struct hdb_dbinfo * 177 hdb_dbinfo_get_next(struct hdb_dbinfo *dbp, struct hdb_dbinfo *dbprevp) 178 { 179 if (dbprevp == NULL) 180 return dbp; 181 else 182 return dbprevp->next; 183 } 184 185 const char * 186 hdb_dbinfo_get_label(krb5_context context, struct hdb_dbinfo *dbp) 187 { 188 return dbp->label; 189 } 190 191 const char * 192 hdb_dbinfo_get_realm(krb5_context context, struct hdb_dbinfo *dbp) 193 { 194 return dbp->realm; 195 } 196 197 const char * 198 hdb_dbinfo_get_dbname(krb5_context context, struct hdb_dbinfo *dbp) 199 { 200 return dbp->dbname; 201 } 202 203 const char * 204 hdb_dbinfo_get_mkey_file(krb5_context context, struct hdb_dbinfo *dbp) 205 { 206 return dbp->mkey_file; 207 } 208 209 const char * 210 hdb_dbinfo_get_acl_file(krb5_context context, struct hdb_dbinfo *dbp) 211 { 212 return dbp->acl_file; 213 } 214 215 const char * 216 hdb_dbinfo_get_log_file(krb5_context context, struct hdb_dbinfo *dbp) 217 { 218 return dbp->log_file; 219 } 220 221 const krb5_config_binding * 222 hdb_dbinfo_get_binding(krb5_context context, struct hdb_dbinfo *dbp) 223 { 224 return dbp->binding; 225 } 226 227 void 228 hdb_free_dbinfo(krb5_context context, struct hdb_dbinfo **dbp) 229 { 230 struct hdb_dbinfo *di, *ndi; 231 232 for(di = *dbp; di != NULL; di = ndi) { 233 ndi = di->next; 234 free (di->label); 235 free (di->realm); 236 free (di->dbname); 237 free (di->mkey_file); 238 free (di->acl_file); 239 free (di->log_file); 240 free(di); 241 } 242 *dbp = NULL; 243 } 244 245 /** 246 * Return the directory where the hdb database resides. 247 * 248 * @param context Kerberos 5 context. 249 * 250 * @return string pointing to directory. 251 */ 252 253 const char * 254 hdb_db_dir(krb5_context context) 255 { 256 const char *p; 257 258 p = krb5_config_get_string(context, NULL, "hdb", "db-dir", NULL); 259 if (p) 260 return p; 261 262 return HDB_DB_DIR; 263 } 264 265 /** 266 * Return the default hdb database resides. 267 * 268 * @param context Kerberos 5 context. 269 * 270 * @return string pointing to directory. 271 */ 272 273 const char * 274 hdb_default_db(krb5_context context) 275 { 276 return HDB_DEFAULT_DB; 277 } 278