1 /* db_gdbm.c--SASL gdbm interface
4 * $Id: db_gdbm.c,v 1.4 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.
55 int _sasldb_getdata(const sasl_utils_t *utils,
60 char *out, const size_t max_out, size_t *out_len)
68 sasl_getopt_t *getopt;
69 const char *path = SASL_DB_PATH;
71 if (!utils) return SASL_BADPARAM;
72 if (!authid || !propName || !realm || !out || !max_out) {
73 utils->seterror(conn, 0,
74 "Bad parameter in db_gdbm.c: _sasldb_getdata");
79 utils->seterror(conn, 0,
80 "Database not checked");
84 result = _sasldb_alloc_key(utils, authid, realm, propName,
86 if (result != SASL_OK) {
87 utils->seterror(conn, 0,
88 "Could not allocate key in _sasldb_getdata");
92 if (utils->getcallback(conn, SASL_CB_GETOPT,
93 &getopt, &cntxt) == SASL_OK) {
95 if (getopt(cntxt, NULL, "sasldb_path", &p, NULL) == SASL_OK
96 && p != NULL && *p != 0) {
100 db = gdbm_open((char *)path, 0, GDBM_READER, S_IRUSR | S_IWUSR, NULL);
102 utils->seterror(cntxt, 0, "Could not open %s: gdbm_errno=%d",
108 gkey.dsize = key_len;
109 gvalue = gdbm_fetch(db, gkey);
112 if (gdbm_errno == GDBM_ITEM_NOT_FOUND) {
113 utils->seterror(conn, SASL_NOLOG,
114 "user: %s@%s property: %s not found in %s",
115 authid, realm, propName, path);
116 result = SASL_NOUSER;
118 utils->seterror(conn, 0,
119 "Couldn't fetch entry from %s: gdbm_errno=%d",
126 if((size_t)gvalue.dsize > max_out + 1) {
127 utils->seterror(cntxt, 0, "buffer overflow");
131 if(out_len) *out_len = gvalue.dsize;
132 memcpy(out, gvalue.dptr, gvalue.dsize);
133 out[gvalue.dsize] = '\0';
135 /* Note: not sasl_FREE! This is memory allocated by gdbm,
136 * which is using libc malloc/free. */
145 int _sasldb_putdata(const sasl_utils_t *utils,
149 const char *propName,
150 const char *data, size_t data_len)
152 int result = SASL_OK;
158 sasl_getopt_t *getopt;
159 const char *path = SASL_DB_PATH;
161 if (!utils) return SASL_BADPARAM;
163 if (!authid || !realm || !propName) {
164 utils->seterror(conn, 0,
165 "Bad parameter in db_gdbm.c: _sasldb_putdata");
166 return SASL_BADPARAM;
169 result = _sasldb_alloc_key(utils, authid, realm, propName,
171 if (result != SASL_OK) {
172 utils->seterror(conn, 0,
173 "Could not allocate key in _sasldb_putdata");
177 if (utils->getcallback(conn, SASL_CB_GETOPT,
178 &getopt, &cntxt) == SASL_OK) {
180 if (getopt(cntxt, NULL, "sasldb_path", &p, NULL) == SASL_OK
181 && p != NULL && *p != 0) {
185 db = gdbm_open((char *)path, 0, GDBM_WRCREAT, S_IRUSR | S_IWUSR, NULL);
187 utils->log(conn, SASL_LOG_ERR,
188 "SASL error opening password file. "
189 "Do you have write permissions?\n");
190 utils->seterror(conn, 0, "Could not open %s for write: gdbm_errno=%d",
196 gkey.dsize = key_len;
199 gvalue.dptr = (char *)data;
200 if(!data_len) data_len = strlen(data);
201 gvalue.dsize = data_len;
202 if (gdbm_store(db, gkey, gvalue, GDBM_REPLACE)) {
203 utils->seterror(conn, 0,
204 "Couldn't replace entry in %s: gdbm_errno=%d",
209 if (gdbm_delete(db, gkey)) {
210 utils->seterror(conn, 0,
211 "Couldn't delete entry in %s: gdbm_errno=%d",
213 result = SASL_NOUSER;
224 int _sasl_check_db(const sasl_utils_t *utils,
227 const char *path = SASL_DB_PATH;
230 sasl_getopt_t *getopt;
231 sasl_verifyfile_t *vf;
233 if(!utils) return SASL_BADPARAM;
235 if (utils->getcallback(conn, SASL_CB_GETOPT,
236 &getopt, &cntxt) == SASL_OK) {
238 if (getopt(cntxt, NULL, "sasldb_path", &p, NULL) == SASL_OK
239 && p != NULL && *p != 0) {
244 ret = utils->getcallback(NULL, SASL_CB_VERIFYFILE,
247 utils->seterror(conn, 0,
248 "No verifyfile callback");
252 ret = vf(cntxt, path, SASL_VRFY_PASSWD);
253 if (ret == SASL_OK) {
257 if (ret == SASL_OK || ret == SASL_CONTINUE) {
260 utils->seterror(conn, 0,
261 "Verifyfile failed");
266 typedef struct gdbm_handle
273 sasldb_handle _sasldb_getkeyhandle(const sasl_utils_t *utils,
276 const char *path = SASL_DB_PATH;
277 sasl_getopt_t *getopt;
282 if(!utils || !conn) return NULL;
285 utils->seterror(conn, 0, "Database not OK in _sasldb_getkeyhandle");
289 if (utils->getcallback(conn, SASL_CB_GETOPT,
290 &getopt, &cntxt) == SASL_OK) {
292 if (getopt(cntxt, NULL, "sasldb_path", &p, NULL) == SASL_OK
293 && p != NULL && *p != 0) {
298 db = gdbm_open((char *)path, 0, GDBM_READER, S_IRUSR | S_IWUSR, NULL);
301 utils->seterror(conn, 0, "Could not open %s: gdbm_errno=%d",
306 handle = utils->malloc(sizeof(handle_t));
308 utils->seterror(conn, 0, "no memory in _sasldb_getkeyhandle");
316 return (sasldb_handle)handle;
319 int _sasldb_getnextkey(const sasl_utils_t *utils __attribute__((unused)),
320 sasldb_handle handle, char *out,
321 const size_t max_out, size_t *out_len)
323 handle_t *dbh = (handle_t *)handle;
326 if(!utils || !handle || !out || !max_out)
327 return SASL_BADPARAM;
330 dbh->dkey = gdbm_firstkey(dbh->db);
333 nextkey = gdbm_nextkey(dbh->db, dbh->dkey);
337 if(dbh->dkey.dptr == NULL)
340 if((unsigned)dbh->dkey.dsize > max_out)
343 memcpy(out, dbh->dkey.dptr, dbh->dkey.dsize);
344 if(out_len) *out_len = dbh->dkey.dsize;
346 return SASL_CONTINUE;
349 int _sasldb_releasekeyhandle(const sasl_utils_t *utils,
350 sasldb_handle handle)
352 handle_t *dbh = (handle_t *)handle;
354 if(!utils || !dbh) return SASL_BADPARAM;
356 if(dbh->db) gdbm_close(dbh->db);