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