Home | History | Annotate | Line # | Download | only in hdb
      1 /*	$NetBSD: dbinfo.c,v 1.2 2017/01/28 21:31:48 christos Exp $	*/
      2 
      3 /*
      4  * Copyright (c) 2005 Kungliga Tekniska Hgskolan
      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