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