1 /* db_ndbm.c--SASL ndbm interface
4 * $Id: db_ndbm.c,v 1.5 2003/02/13 19:56:14 rjs3 Exp $
7 * Copyright (c) 1998-2003 Carnegie Mellon University. All rights reserved.
9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted provided that the following conditions
13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer.
16 * 2. Redistributions in binary form must reproduce the above copyright
17 * notice, this list of conditions and the following disclaimer in
18 * the documentation and/or other materials provided with the
21 * 3. The name "Carnegie Mellon University" must not be used to
22 * endorse or promote products derived from this software without
23 * prior written permission. For permission or any other legal
24 * details, please contact
25 * Office of Technology Transfer
26 * Carnegie Mellon University
28 * Pittsburgh, PA 15213-3890
29 * (412) 268-4387, fax: (412) 268-7395
30 * tech-transfer@andrew.cmu.edu
32 * 4. Redistributions of any form whatsoever must retain the following
34 * "This product includes software developed by Computing Services
35 * at Carnegie Mellon University (http://www.cmu.edu/computing/)."
37 * CARNEGIE MELLON UNIVERSITY DISCLAIMS ALL WARRANTIES WITH REGARD TO
38 * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
39 * AND FITNESS, IN NO EVENT SHALL CARNEGIE MELLON UNIVERSITY BE LIABLE
40 * FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
41 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
42 * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
43 * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
57 /* This provides a version of _sasl_db_getsecret and
58 * _sasl_db_putsecret which work with ndbm. */
59 int _sasldb_getdata(const sasl_utils_t *utils,
64 char *out, const size_t max_out, size_t *out_len)
72 sasl_getopt_t *getopt;
73 const char *path = SASL_DB_PATH;
75 if (!utils) return SASL_BADPARAM;
76 if (!authid || !propName || !realm || !out || !max_out) {
77 utils->seterror(conn, 0,
78 "Bad parameter in db_ndbm.c: _sasldb_getdata");
82 utils->seterror(conn, 0, "Database not checked");
86 result = _sasldb_alloc_key(utils, authid, realm, propName,
88 if (result != SASL_OK) {
89 utils->seterror(conn, 0,
90 "Could not allocate key in _sasldb_getdata");
94 if (utils->getcallback(conn, SASL_CB_GETOPT,
95 &getopt, &cntxt) == SASL_OK) {
97 if (getopt(cntxt, NULL, "sasldb_path", &p, NULL) == SASL_OK
98 && p != NULL && *p != 0) {
102 db = dbm_open(path, O_RDONLY, S_IRUSR | S_IWUSR);
104 utils->seterror(cntxt, 0, "Could not open db");
109 dkey.dsize = key_len;
110 dvalue = dbm_fetch(db, dkey);
112 utils->seterror(cntxt, 0, "no user in db");
113 result = SASL_NOUSER;
117 if((size_t)dvalue.dsize > max_out + 1) {
118 utils->seterror(cntxt, 0, "buffer overflow");
122 if(out_len) *out_len = dvalue.dsize;
123 memcpy(out, dvalue.dptr, dvalue.dsize);
124 out[dvalue.dsize] = '\0';
127 /* Note: not sasl_FREE! This is memory allocated by ndbm,
128 * which is using libc malloc/free. */
140 int _sasldb_putdata(const sasl_utils_t *utils,
144 const char *propName,
145 const char *data, size_t data_len)
147 int result = SASL_OK;
153 sasl_getopt_t *getopt;
154 const char *path = SASL_DB_PATH;
156 if (!utils) return SASL_BADPARAM;
158 if (!authid || !realm || !propName) {
159 utils->seterror(conn, 0,
160 "Bad parameter in db_ndbm.c: _sasldb_putdata");
161 return SASL_BADPARAM;
164 result = _sasldb_alloc_key(utils, authid, realm, propName,
166 if (result != SASL_OK) {
167 utils->seterror(conn, 0,
168 "Could not allocate key in _sasldb_putdata");
172 if (utils->getcallback(conn, SASL_CB_GETOPT,
173 &getopt, &cntxt) == SASL_OK) {
175 if (getopt(cntxt, NULL, "sasldb_path", &p, NULL) == SASL_OK
176 && p != NULL && *p != 0) {
185 utils->log(conn, SASL_LOG_ERR,
186 "SASL error opening password file. "
187 "Do you have write permissions?\n");
188 utils->seterror(conn, 0, "Could not open db for write");
192 dkey.dsize = key_len;
195 dvalue.dptr = (void *)data;
196 if(!data_len) data_len = strlen(data);
197 dvalue.dsize = data_len;
198 if (dbm_store(db, dkey, dvalue, DBM_REPLACE)) {
199 utils->seterror(conn, 0,
200 "Couldn't update db");
204 if (dbm_delete(db, dkey)) {
205 utils->seterror(conn, 0,
206 "Couldn't update db");
207 result = SASL_NOUSER;
219 #define SUFLEN (strlen(DBM_SUFFIX) + 1)
224 int _sasl_check_db(const sasl_utils_t *utils,
227 const char *path = SASL_DB_PATH;
229 sasl_getopt_t *getopt;
230 sasl_verifyfile_t *vf;
234 if(!utils) return SASL_BADPARAM;
236 if (utils->getcallback(conn, SASL_CB_GETOPT,
237 &getopt, &cntxt) == SASL_OK) {
239 if (getopt(cntxt, NULL, "sasldb_path", &p, NULL) == SASL_OK
240 && p != NULL && *p != 0) {
245 db = utils->malloc(strlen(path) + SUFLEN);
251 ret = utils->getcallback(NULL, SASL_CB_VERIFYFILE,
254 utils->seterror(conn, 0,
255 "No verifyfile callback");
260 if (ret == SASL_OK) {
261 sprintf(db, "%s%s", path, DBM_SUFFIX);
262 ret = vf(cntxt, db, SASL_VRFY_PASSWD);
265 if (ret == SASL_OK) {
266 sprintf(db, "%s.dir", path);
267 ret = vf(cntxt, db, SASL_VRFY_PASSWD);
269 if (ret == SASL_OK) {
270 sprintf(db, "%s.pag", path);
271 ret = vf(cntxt, db, SASL_VRFY_PASSWD);
277 if (ret == SASL_OK) {
281 if (ret == SASL_OK || ret == SASL_CONTINUE) {
284 utils->seterror(conn, 0,
285 "Verifyfile failed");
290 typedef struct ndbm_handle
297 sasldb_handle _sasldb_getkeyhandle(const sasl_utils_t *utils,
300 const char *path = SASL_DB_PATH;
301 sasl_getopt_t *getopt;
306 if(!utils || !conn) return NULL;
309 utils->seterror(conn, 0, "Database not OK in _sasldb_getkeyhandle");
313 if (utils->getcallback(conn, SASL_CB_GETOPT,
314 &getopt, &cntxt) == SASL_OK) {
316 if (getopt(cntxt, NULL, "sasldb_path", &p, NULL) == SASL_OK
317 && p != NULL && *p != 0) {
322 db = dbm_open(path, O_RDONLY, S_IRUSR | S_IWUSR);
325 utils->seterror(conn, 0, "Could not open db");
329 handle = utils->malloc(sizeof(handle_t));
331 utils->seterror(conn, 0, "no memory in _sasldb_getkeyhandle");
339 return (sasldb_handle)handle;
342 int _sasldb_getnextkey(const sasl_utils_t *utils __attribute__((unused)),
343 sasldb_handle handle, char *out,
344 const size_t max_out, size_t *out_len)
346 handle_t *dbh = (handle_t *)handle;
349 if(!utils || !handle || !out || !max_out)
350 return SASL_BADPARAM;
353 dbh->dkey = dbm_firstkey(dbh->db);
356 nextkey = dbm_nextkey(dbh->db);
360 if(dbh->dkey.dptr == NULL)
363 if((unsigned)dbh->dkey.dsize > max_out)
366 memcpy(out, dbh->dkey.dptr, dbh->dkey.dsize);
367 if(out_len) *out_len = dbh->dkey.dsize;
369 return SASL_CONTINUE;
372 int _sasldb_releasekeyhandle(const sasl_utils_t *utils,
373 sasldb_handle handle)
375 handle_t *dbh = (handle_t *)handle;
377 if(!utils || !dbh) return SASL_BADPARAM;
379 if(dbh->db) dbm_close(dbh->db);