1/* SASL server API implementation 2 * Rob Siemborski 3 * Tim Martin 4 * $Id: sasldb.c,v 1.6 2006/01/24 20:37:26 snsimon Exp $ 5 */ 6/* 7 * Copyright (c) 1998-2003 Carnegie Mellon University. All rights reserved. 8 * 9 * Redistribution and use in source and binary forms, with or without 10 * modification, are permitted provided that the following conditions 11 * are met: 12 * 13 * 1. Redistributions of source code must retain the above copyright 14 * notice, this list of conditions and the following disclaimer. 15 * 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 19 * distribution. 20 * 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 27 * 5000 Forbes Avenue 28 * Pittsburgh, PA 15213-3890 29 * (412) 268-4387, fax: (412) 268-7395 30 * tech-transfer@andrew.cmu.edu 31 * 32 * 4. Redistributions of any form whatsoever must retain the following 33 * acknowledgment: 34 * "This product includes software developed by Computing Services 35 * at Carnegie Mellon University (http://www.cmu.edu/computing/)." 36 * 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. 44 */ 45 46#include <config.h> 47 48/* checkpw stuff */ 49 50#include <stdio.h> 51 52#include "sasl.h" 53#include "saslutil.h" 54#include "saslplug.h" 55#include "../sasldb/sasldb.h" 56 57#include "plugin_common.h" 58 59static void sasldb_auxprop_lookup(void *glob_context __attribute__((unused)), 60 sasl_server_params_t *sparams, 61 unsigned flags, 62 const char *user, 63 unsigned ulen) 64{ 65 char *userid = NULL; 66 char *realm = NULL; 67 const char *user_realm = NULL; 68 int ret; 69 const struct propval *to_fetch, *cur; 70 char value[8192]; 71 size_t value_len; 72 char *user_buf; 73 74 if(!sparams || !user) return; 75 76 user_buf = sparams->utils->malloc(ulen + 1); 77 if(!user_buf) 78 goto done; 79 80 memcpy(user_buf, user, ulen); 81 user_buf[ulen] = '\0'; 82 83 if(sparams->user_realm) { 84 user_realm = sparams->user_realm; 85 } else { 86 user_realm = sparams->serverFQDN; 87 } 88 89 ret = _plug_parseuser(sparams->utils, &userid, &realm, user_realm, 90 sparams->serverFQDN, user_buf); 91 if(ret != SASL_OK) goto done; 92 93 to_fetch = sparams->utils->prop_get(sparams->propctx); 94 if(!to_fetch) goto done; 95 96 for(cur = to_fetch; cur->name; cur++) { 97 const char *realname = cur->name; 98 99 /* Only look up properties that apply to this lookup! */ 100 if(cur->name[0] == '*' && (flags & SASL_AUXPROP_AUTHZID)) continue; 101 if(!(flags & SASL_AUXPROP_AUTHZID)) { 102 if(cur->name[0] != '*') continue; 103 else realname = cur->name + 1; 104 } 105 106 /* If it's there already, we want to see if it needs to be 107 * overridden */ 108 if(cur->values && !(flags & SASL_AUXPROP_OVERRIDE)) 109 continue; 110 else if(cur->values) 111 sparams->utils->prop_erase(sparams->propctx, cur->name); 112 113 ret = _sasldb_getdata(sparams->utils, 114 sparams->utils->conn, userid, realm, 115 realname, value, 8192, &value_len); 116 if(ret != SASL_OK) { 117 /* We didn't find it, leave it as not found */ 118 continue; 119 } 120 121 sparams->utils->prop_set(sparams->propctx, cur->name, 122 value, (unsigned) value_len); 123 } 124 125 done: 126 if (userid) sparams->utils->free(userid); 127 if (realm) sparams->utils->free(realm); 128 if (user_buf) sparams->utils->free(user_buf); 129} 130 131static int sasldb_auxprop_store(void *glob_context __attribute__((unused)), 132 sasl_server_params_t *sparams, 133 struct propctx *ctx, 134 const char *user, 135 unsigned ulen) 136{ 137 char *userid = NULL; 138 char *realm = NULL; 139 const char *user_realm = NULL; 140 int ret = SASL_FAIL; 141 const struct propval *to_store, *cur; 142 char *user_buf; 143 144 /* just checking if we are enabled */ 145 if(!ctx) return SASL_OK; 146 147 if(!sparams || !user) return SASL_BADPARAM; 148 149 user_buf = sparams->utils->malloc(ulen + 1); 150 if(!user_buf) { 151 ret = SASL_NOMEM; 152 goto done; 153 } 154 155 memcpy(user_buf, user, ulen); 156 user_buf[ulen] = '\0'; 157 158 if(sparams->user_realm) { 159 user_realm = sparams->user_realm; 160 } else { 161 user_realm = sparams->serverFQDN; 162 } 163 164 ret = _plug_parseuser(sparams->utils, &userid, &realm, user_realm, 165 sparams->serverFQDN, user_buf); 166 if(ret != SASL_OK) goto done; 167 168 to_store = sparams->utils->prop_get(ctx); 169 if(!to_store) { 170 ret = SASL_BADPARAM; 171 goto done; 172 } 173 174 for(cur = to_store; cur->name; cur++) { 175 /* We only support one value right now. */ 176 ret = _sasldb_putdata(sparams->utils, sparams->utils->conn, 177 userid, realm, cur->name, 178 cur->values && cur->values[0] ? 179 cur->values[0] : NULL, 180 cur->values && cur->values[0] ? 181 strlen(cur->values[0]) : 0); 182 } 183 184 done: 185 if (userid) sparams->utils->free(userid); 186 if (realm) sparams->utils->free(realm); 187 if (user_buf) sparams->utils->free(user_buf); 188 189 return ret; 190} 191 192static sasl_auxprop_plug_t sasldb_auxprop_plugin = { 193 0, /* Features */ 194 0, /* spare */ 195 NULL, /* glob_context */ 196 NULL, /* auxprop_free */ 197 sasldb_auxprop_lookup, /* auxprop_lookup */ 198 "sasldb", /* name */ 199 sasldb_auxprop_store /* auxprop_store */ 200}; 201 202int sasldb_auxprop_plug_init(const sasl_utils_t *utils, 203 int max_version, 204 int *out_version, 205 sasl_auxprop_plug_t **plug, 206 const char *plugname __attribute__((unused))) 207{ 208 if(!out_version || !plug) return SASL_BADPARAM; 209 210 /* Do we have database support? */ 211 /* Note that we can use a NULL sasl_conn_t because our 212 * sasl_utils_t is "blessed" with the global callbacks */ 213 if(_sasl_check_db(utils, NULL) != SASL_OK) 214 return SASL_NOMECH; 215 216 if(max_version < SASL_AUXPROP_PLUG_VERSION) return SASL_BADVERS; 217 218 *out_version = SASL_AUXPROP_PLUG_VERSION; 219 220 *plug = &sasldb_auxprop_plugin; 221 222 return SASL_OK; 223} 224