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
get_dbinfo(krb5_context context,const krb5_config_binding * db_binding,const char * label,struct hdb_dbinfo ** db)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
hdb_get_dbinfo(krb5_context context,struct hdb_dbinfo ** dbp)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 *
hdb_dbinfo_get_next(struct hdb_dbinfo * dbp,struct hdb_dbinfo * dbprevp)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 *
hdb_dbinfo_get_label(krb5_context context,struct hdb_dbinfo * dbp)186 hdb_dbinfo_get_label(krb5_context context, struct hdb_dbinfo *dbp)
187 {
188 return dbp->label;
189 }
190
191 const char *
hdb_dbinfo_get_realm(krb5_context context,struct hdb_dbinfo * dbp)192 hdb_dbinfo_get_realm(krb5_context context, struct hdb_dbinfo *dbp)
193 {
194 return dbp->realm;
195 }
196
197 const char *
hdb_dbinfo_get_dbname(krb5_context context,struct hdb_dbinfo * dbp)198 hdb_dbinfo_get_dbname(krb5_context context, struct hdb_dbinfo *dbp)
199 {
200 return dbp->dbname;
201 }
202
203 const char *
hdb_dbinfo_get_mkey_file(krb5_context context,struct hdb_dbinfo * dbp)204 hdb_dbinfo_get_mkey_file(krb5_context context, struct hdb_dbinfo *dbp)
205 {
206 return dbp->mkey_file;
207 }
208
209 const char *
hdb_dbinfo_get_acl_file(krb5_context context,struct hdb_dbinfo * dbp)210 hdb_dbinfo_get_acl_file(krb5_context context, struct hdb_dbinfo *dbp)
211 {
212 return dbp->acl_file;
213 }
214
215 const char *
hdb_dbinfo_get_log_file(krb5_context context,struct hdb_dbinfo * dbp)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 *
hdb_dbinfo_get_binding(krb5_context context,struct hdb_dbinfo * dbp)222 hdb_dbinfo_get_binding(krb5_context context, struct hdb_dbinfo *dbp)
223 {
224 return dbp->binding;
225 }
226
227 void
hdb_free_dbinfo(krb5_context context,struct hdb_dbinfo ** dbp)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 *
hdb_db_dir(krb5_context context)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 *
hdb_default_db(krb5_context context)274 hdb_default_db(krb5_context context)
275 {
276 return HDB_DEFAULT_DB;
277 }
278