int listusers(const char *path, listcb_t *cb) { int result; DB *mbdb = NULL; DBC *cursor; DBT key, data; /* open the db */ result=berkeleydb_open(path, &mbdb); if (result!=SASL_OK) goto cleanup; /* make cursor */ #if DB_VERSION_FULL < 0x03060000 result = mbdb->cursor(mbdb, NULL,&cursor); #else result = mbdb->cursor(mbdb, NULL,&cursor, 0); #endif /* DB_VERSION_FULL < 0x03060000 */ if (result!=0) { fprintf(stderr,"Making cursor failure: %s\n",db_strerror(result)); result = SASL_FAIL; goto cleanup; } memset(&key,0, sizeof(key)); memset(&data,0,sizeof(data)); /* loop thru */ result = cursor->c_get(cursor, &key, &data, DB_FIRST); while (result != DB_NOTFOUND) { char *authid; char *realm; char *tmp; unsigned int len; char mech[1024]; int numnulls = 0; unsigned int lup; /* make sure there are exactly 2 null's */ for (lup=0;lup<key.size;lup++) if (((char *)key.data)[lup]=='\0') numnulls++; if (numnulls != 2) { fprintf(stderr,"warning: probable database corruption\n"); result = cursor->c_get(cursor, &key, &data, DB_NEXT); continue; } authid = key.data; realm = authid + strlen(authid)+1; tmp = realm + strlen(realm)+1; len = key.size - (tmp - authid); /* make sure we have enough space of mech */ if (len >=sizeof(mech)) { fprintf(stderr,"warning: absurdly long mech name\n"); result = cursor->c_get(cursor, &key, &data, DB_NEXT); continue; } memcpy(mech, tmp, key.size - (tmp - ((char *)key.data))); mech[key.size - (tmp - ((char *)key.data))] = '\0'; if (*authid) { /* don't check return values */ cb(authid,realm,mech,data.data,data.size); } result = cursor->c_get(cursor, &key, &data, DB_NEXT); } if (result != DB_NOTFOUND) { fprintf(stderr,"failure: %s\n",db_strerror(result)); result = SASL_FAIL; goto cleanup; } result = cursor->c_close(cursor); if (result!=0) result = SASL_FAIL; result = SASL_OK; cleanup: if (mbdb != NULL) berkeleydb_close(mbdb); return result; }
/* * Retrieve the secret from the database. * * Return SASL_NOUSER if entry doesn't exist * */ int _sasldb_getdata(const sasl_utils_t *utils, sasl_conn_t *context, const char *auth_identity, const char *realm, const char *propName, char *out, const size_t max_out, size_t *out_len) { int result = SASL_OK; char *key; size_t key_len; DBT dbkey, data; DB *mbdb = NULL; if(!utils) return SASL_BADPARAM; /* check parameters */ if (!auth_identity || !realm || !propName || !out || !max_out) { utils->seterror(context, 0, "Bad parameter in db_berkeley.c: _sasldb_getdata"); return SASL_BADPARAM; } if (!db_ok) { utils->seterror(context, 0, "Database not checked"); return SASL_FAIL; } /* allocate a key */ result = _sasldb_alloc_key(utils, auth_identity, realm, propName, &key, &key_len); if (result != SASL_OK) { utils->seterror(context, 0, "Could not allocate key in _sasldb_getdata"); return result; } /* open the db */ result = berkeleydb_open(utils, context, 0, &mbdb); if (result != SASL_OK) goto cleanup; /* zero out and create the key to search for */ memset(&dbkey, 0, sizeof(dbkey)); memset(&data, 0, sizeof(data)); dbkey.data = key; dbkey.size = key_len; /* ask berkeley db for the entry */ result = mbdb->get(mbdb, NULL, &dbkey, &data, 0); switch (result) { case 0: /* success */ break; case DB_NOTFOUND: result = SASL_NOUSER; utils->seterror(context, SASL_NOLOG, "user: %s@%s property: %s not found in sasldb", auth_identity,realm,propName); goto cleanup; break; default: utils->seterror(context, 0, "error fetching from sasldb: %s", db_strerror(result)); result = SASL_FAIL; goto cleanup; break; } if(data.size > max_out + 1) return SASL_BUFOVER; if(out_len) *out_len = data.size; memcpy(out, data.data, data.size); out[data.size] = '\0'; cleanup: if (mbdb != NULL) berkeleydb_close(utils, mbdb); utils->free(key); return result; }
int _sasldb_putdata(const sasl_utils_t *utils, sasl_conn_t *context, const char *authid, const char *realm, const char *propName, const char *data_in, size_t data_len) { int result = SASL_OK; char *key; size_t key_len; DBT dbkey; DB *mbdb = NULL; if (!utils) return SASL_BADPARAM; if (!authid || !realm || !propName) { utils->seterror(context, 0, "Bad parameter in db_berkeley.c: _sasldb_putdata"); return SASL_BADPARAM; } if (!db_ok) { utils->seterror(context, 0, "Database not checked"); return SASL_FAIL; } result = _sasldb_alloc_key(utils, authid, realm, propName, &key, &key_len); if (result != SASL_OK) { utils->seterror(context, 0, "Could not allocate key in _sasldb_putdata"); return result; } /* open the db */ result=berkeleydb_open(utils, context, 1, &mbdb); if (result!=SASL_OK) goto cleanup; /* create the db key */ memset(&dbkey, 0, sizeof(dbkey)); dbkey.data = key; dbkey.size = key_len; if (data_in) { /* putting secret */ DBT data; memset(&data, 0, sizeof(data)); data.data = (char *)data_in; if(!data_len) data_len = strlen(data_in); data.size = data_len; result = mbdb->put(mbdb, NULL, &dbkey, &data, 0); if (result != 0) { utils->log(NULL, SASL_LOG_ERR, "error updating sasldb: %s", db_strerror(result)); utils->seterror(context, SASL_NOLOG, "Couldn't update db"); result = SASL_FAIL; goto cleanup; } } else { /* removing secret */ result=mbdb->del(mbdb, NULL, &dbkey, 0); if (result != 0) { utils->log(NULL, SASL_LOG_ERR, "error deleting entry from sasldb: %s", db_strerror(result)); utils->seterror(context, SASL_NOLOG, "Couldn't update db"); if (result == DB_NOTFOUND) result = SASL_NOUSER; else result = SASL_FAIL; goto cleanup; } } cleanup: if (mbdb != NULL) berkeleydb_close(utils, mbdb); utils->free(key); return result; }
void sasldb_auxprop_free (void *glob_context, const sasl_utils_t *utils) { if (g_db != NULL) berkeleydb_close(utils, g_db); }