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