1 /* SASL server API implementation
4 * $Id: sasldb.c,v 1.11 2006/04/03 10:58:19 mel 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 #include "../sasldb/sasldb.h"
57 #include "plugin_common.h"
59 static void sasldb_auxprop_lookup(void *glob_context __attribute__((unused)),
60 sasl_server_params_t *sparams,
67 const char *user_realm = NULL;
69 const struct propval *to_fetch, *cur;
74 if(!sparams || !user) return;
76 user_buf = sparams->utils->malloc(ulen + 1);
81 memcpy(user_buf, user, ulen);
82 user_buf[ulen] = '\0';
84 if(sparams->user_realm) {
85 user_realm = sparams->user_realm;
87 user_realm = sparams->serverFQDN;
90 ret = _plug_parseuser(sparams->utils, &userid, &realm, user_realm,
91 sparams->serverFQDN, user_buf);
92 if(ret != SASL_OK) goto done;
94 to_fetch = sparams->utils->prop_get(sparams->propctx);
95 if(!to_fetch) goto done;
97 for(cur = to_fetch; cur->name; cur++) {
98 const char *realname = cur->name;
100 /* Only look up properties that apply to this lookup! */
101 if(cur->name[0] == '*' && (flags & SASL_AUXPROP_AUTHZID)) continue;
102 if(!(flags & SASL_AUXPROP_AUTHZID)) {
103 if(cur->name[0] != '*') continue;
104 else realname = cur->name + 1;
107 /* If it's there already, we want to see if it needs to be
109 if(cur->values && !(flags & SASL_AUXPROP_OVERRIDE))
112 sparams->utils->prop_erase(sparams->propctx, cur->name);
114 ret = _sasldb_getdata(sparams->utils,
115 sparams->utils->conn, userid, realm,
116 realname, value, sizeof(value), &value_len);
118 /* We didn't find it, leave it as not found */
122 sparams->utils->prop_set(sparams->propctx, cur->name,
123 value, (unsigned) value_len);
127 if (userid) sparams->utils->free(userid);
128 if (realm) sparams->utils->free(realm);
129 if (user_buf) sparams->utils->free(user_buf);
132 static int sasldb_auxprop_store(void *glob_context __attribute__((unused)),
133 sasl_server_params_t *sparams,
140 const char *user_realm = NULL;
143 const struct propval *to_store, *cur;
146 /* just checking if we are enabled */
147 if(!ctx) return SASL_OK;
149 if(!sparams || !user) return SASL_BADPARAM;
151 user_buf = sparams->utils->malloc(ulen + 1);
157 memcpy(user_buf, user, ulen);
158 user_buf[ulen] = '\0';
160 if(sparams->user_realm) {
161 user_realm = sparams->user_realm;
163 user_realm = sparams->serverFQDN;
166 ret = _plug_parseuser(sparams->utils, &userid, &realm, user_realm,
167 sparams->serverFQDN, user_buf);
168 if(ret != SASL_OK) goto done;
170 to_store = sparams->utils->prop_get(ctx);
176 /* All iterations return SASL_NOUSER ==> ret = SASL_NOUSER
177 Some iterations return SASL_OK and some SASL_NOUSER ==> ret = SASL_OK
178 At least one iteration returns any other error ==> ret = the error */
180 for(cur = to_store; cur->name; cur++) {
181 /* We only support one value at a time right now. */
182 tmp_res = _sasldb_putdata(sparams->utils, sparams->utils->conn,
183 userid, realm, cur->name,
184 cur->values && cur->values[0] ?
185 cur->values[0] : NULL,
186 cur->values && cur->values[0] ?
187 strlen(cur->values[0]) : 0);
188 /* SASL_NOUSER is returned when _sasldb_putdata fails to delete
189 a non-existent entry, which should not be treated as an error */
190 if ((tmp_res != SASL_NOUSER) &&
191 (ret == SASL_NOUSER || ret == SASL_OK)) {
195 /* Abort the loop if an error has occurred */
196 if (ret != SASL_NOUSER && ret != SASL_OK) {
202 if (userid) sparams->utils->free(userid);
203 if (realm) sparams->utils->free(realm);
204 if (user_buf) sparams->utils->free(user_buf);
209 static sasl_auxprop_plug_t sasldb_auxprop_plugin = {
212 NULL, /* glob_context */
213 sasldb_auxprop_free, /* auxprop_free */
214 sasldb_auxprop_lookup, /* auxprop_lookup */
216 sasldb_auxprop_store /* auxprop_store */
219 int sasldb_auxprop_plug_init(const sasl_utils_t *utils,
222 sasl_auxprop_plug_t **plug,
223 const char *plugname __attribute__((unused)))
225 if(!out_version || !plug) return SASL_BADPARAM;
227 /* Do we have database support? */
228 /* Note that we can use a NULL sasl_conn_t because our
229 * sasl_utils_t is "blessed" with the global callbacks */
230 if(_sasl_check_db(utils, NULL) != SASL_OK)
233 if(max_version < SASL_AUXPROP_PLUG_VERSION) return SASL_BADVERS;
235 *out_version = SASL_AUXPROP_PLUG_VERSION;
237 *plug = &sasldb_auxprop_plugin;