auxprop.c   auxprop.c 
/* auxprop.c - auxilliary property support /* auxprop.c - auxilliary property support
* Rob Siemborski * Rob Siemborski
* $Id: auxprop.c,v 1.16 2006/03/14 14:23:55 mel Exp $ * $Id: auxprop.c,v 1.21 2011/09/01 14:12:53 mel Exp $
*/ */
/* /*
* Copyright (c) 1998-2003 Carnegie Mellon University. All rights reserved . * Copyright (c) 1998-2003 Carnegie Mellon University. All rights reserved .
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions * modification, are permitted provided that the following conditions
* are met: * are met:
* *
* 1. Redistributions of source code must retain the above copyright * 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer. * notice, this list of conditions and the following disclaimer.
skipping to change at line 49 skipping to change at line 49
* FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
* AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/ */
#include <config.h> #include <config.h>
#include <sasl.h> #include <sasl.h>
#include <prop.h> #include <prop.h>
#include <ctype.h> #include <ctype.h>
#include <stdio.h>
#include "saslint.h" #include "saslint.h"
struct proppool struct proppool
{ {
struct proppool *next; struct proppool *next;
size_t size; /* Size of Block */ size_t size; /* Size of Block */
size_t unused; /* Space unused in this pool between end size_t unused; /* Space unused in this pool between end
* of char** area and beginning of char* area */ * of char** area and beginning of char* area */
skipping to change at line 810 skipping to change at line 811
int sasl_auxprop_add_plugin(const char *plugname, int sasl_auxprop_add_plugin(const char *plugname,
sasl_auxprop_init_t *auxpropfunc) sasl_auxprop_init_t *auxpropfunc)
{ {
int result, out_version; int result, out_version;
auxprop_plug_list_t *new_item; auxprop_plug_list_t *new_item;
sasl_auxprop_plug_t *plug; sasl_auxprop_plug_t *plug;
result = auxpropfunc(sasl_global_utils, SASL_AUXPROP_PLUG_VERSION, result = auxpropfunc(sasl_global_utils, SASL_AUXPROP_PLUG_VERSION,
&out_version, &plug, plugname); &out_version, &plug, plugname);
/* Check if out_version is too old.
We only support the current at the moment */
if (result == SASL_OK && out_version < SASL_AUXPROP_PLUG_VERSION) {
result = SASL_BADVERS;
}
if(result != SASL_OK) { if(result != SASL_OK) {
_sasl_log(NULL, SASL_LOG_ERR, "auxpropfunc error %s\n", _sasl_log(NULL, SASL_LOG_ERR, "auxpropfunc error %s\n",
sasl_errstring(result, NULL, NULL)); sasl_errstring(result, NULL, NULL));
return result; return result;
} }
/* We require that this function is implemented */ /* We require that this function is implemented */
if(!plug->auxprop_lookup) return SASL_BADPROT; if(!plug->auxprop_lookup) return SASL_BADPROT;
new_item = sasl_ALLOC(sizeof(auxprop_plug_list_t)); new_item = sasl_ALLOC(sizeof(auxprop_plug_list_t));
skipping to change at line 845 skipping to change at line 852
ptr_next = ptr->next; ptr_next = ptr->next;
if(ptr->plug->auxprop_free) if(ptr->plug->auxprop_free)
ptr->plug->auxprop_free(ptr->plug->glob_context, ptr->plug->auxprop_free(ptr->plug->glob_context,
sasl_global_utils); sasl_global_utils);
sasl_FREE(ptr); sasl_FREE(ptr);
} }
auxprop_head = NULL; auxprop_head = NULL;
} }
/* Return the updated account status based on the current ("so far") and
the specific status returned by the latest auxprop call */
static int
_sasl_account_status (int current_status,
int specific_status)
{
switch (specific_status) {
case SASL_NOVERIFY:
specific_status = SASL_OK;
/* fall through */
case SASL_OK:
if (current_status == SASL_NOMECH ||
current_status == SASL_NOUSER) {
current_status = specific_status;
}
break;
case SASL_NOUSER:
if (current_status == SASL_NOMECH) {
current_status = specific_status;
}
break;
/* NOTE: The disabled flag sticks, unless we hit an error */
case SASL_DISABLED:
if (current_status == SASL_NOMECH ||
current_status == SASL_NOUSER ||
current_status == SASL_OK) {
current_status = specific_status;
}
break;
case SASL_NOMECH:
/* ignore */
break;
/* SASL_UNAVAIL overrides everything */
case SASL_UNAVAIL:
current_status = specific_status;
break;
default:
current_status = specific_status;
break;
}
return (current_status);
}
/* Do the callbacks for auxprop lookups */ /* Do the callbacks for auxprop lookups */
void _sasl_auxprop_lookup(sasl_server_params_t *sparams, int _sasl_auxprop_lookup(sasl_server_params_t *sparams,
unsigned flags, unsigned flags,
const char *user, unsigned ulen) const char *user, unsigned ulen)
{ {
sasl_getopt_t *getopt; sasl_getopt_t *getopt;
int ret, found = 0; int ret, found = 0;
void *context; void *context;
const char *plist = NULL; const char *plist = NULL;
auxprop_plug_list_t *ptr; auxprop_plug_list_t *ptr;
int result = SASL_NOMECH;
if(_sasl_getcallback(sparams->utils->conn, if(_sasl_getcallback(sparams->utils->conn,
SASL_CB_GETOPT, &getopt, &context) == SASL_OK) { SASL_CB_GETOPT,
(sasl_callback_ft *)&getopt,
&context) == SASL_OK) {
ret = getopt(context, NULL, "auxprop_plugin", &plist, NULL); ret = getopt(context, NULL, "auxprop_plugin", &plist, NULL);
if(ret != SASL_OK) plist = NULL; if(ret != SASL_OK) plist = NULL;
} }
if(!plist) { if(!plist) {
/* Do lookup in all plugins */ /* Do lookup in all plugins */
/* TODO: Ideally, each auxprop plugin should be marked if its failur
e
should be ignored or treated as a fatal error of the whole lookup
. */
for(ptr = auxprop_head; ptr; ptr = ptr->next) { for(ptr = auxprop_head; ptr; ptr = ptr->next) {
found=1; found=1;
ptr->plug->auxprop_lookup(ptr->plug->glob_context, ret = ptr->plug->auxprop_lookup(ptr->plug->glob_context,
sparams, flags, user, ulen); sparams, flags, user, ulen);
result = _sasl_account_status (result, ret);
} }
} else { } else {
char *pluginlist = NULL, *freeptr = NULL, *thisplugin = NULL; char *pluginlist = NULL, *freeptr = NULL, *thisplugin = NULL;
if(_sasl_strdup(plist, &pluginlist, NULL) != SASL_OK) return; if(_sasl_strdup(plist, &pluginlist, NULL) != SASL_OK) return SASL_NO MEM;
thisplugin = freeptr = pluginlist; thisplugin = freeptr = pluginlist;
/* Do lookup in all *specified* plugins, in order */ /* Do lookup in all *specified* plugins, in order */
while(*thisplugin) { while(*thisplugin) {
char *p; char *p;
int last=0; int last=0;
while(*thisplugin && isspace((int)*thisplugin)) thisplugin++; while(*thisplugin && isspace((int)*thisplugin)) thisplugin++;
if(!(*thisplugin)) break; if(!(*thisplugin)) break;
skipping to change at line 894 skipping to change at line 956
if(*p == '\0') last = 1; if(*p == '\0') last = 1;
else *p='\0'; else *p='\0';
for(ptr = auxprop_head; ptr; ptr = ptr->next) { for(ptr = auxprop_head; ptr; ptr = ptr->next) {
/* Skip non-matching plugins */ /* Skip non-matching plugins */
if(!ptr->plug->name if(!ptr->plug->name
|| strcasecmp(ptr->plug->name, thisplugin)) || strcasecmp(ptr->plug->name, thisplugin))
continue; continue;
found=1; found=1;
ptr->plug->auxprop_lookup(ptr->plug->glob_context, ret = ptr->plug->auxprop_lookup(ptr->plug->glob_context,
sparams, flags, user, ulen); sparams, flags, user, ulen);
result = _sasl_account_status (result, ret);
} }
if(last) break; if(last) break;
thisplugin = p+1; thisplugin = p+1;
} }
sasl_FREE(freeptr); sasl_FREE(freeptr);
} }
if(!found) if(!found) {
_sasl_log(sparams->utils->conn, SASL_LOG_DEBUG, _sasl_log(sparams->utils->conn, SASL_LOG_DEBUG,
"could not find auxprop plugin, was searching for '%s'", "could not find auxprop plugin, was searching for '%s'",
plist ? plist : "[all]"); plist ? plist : "[all]");
}
return result;
} }
/* Do the callbacks for auxprop stores */ /* Do the callbacks for auxprop stores */
int sasl_auxprop_store(sasl_conn_t *conn, int sasl_auxprop_store(sasl_conn_t *conn,
struct propctx *ctx, const char *user) struct propctx *ctx, const char *user)
{ {
sasl_getopt_t *getopt; sasl_getopt_t *getopt;
int ret, found = 0; int ret;
void *context; void *context;
const char *plist = NULL; const char *plist = NULL;
auxprop_plug_list_t *ptr; auxprop_plug_list_t *ptr;
sasl_server_params_t *sparams = NULL; sasl_server_params_t *sparams = NULL;
unsigned userlen = 0; unsigned userlen = 0;
int num_constraint_violations = 0;
int total_plugins = 0;
if (ctx) { if (ctx) {
if (!conn || !user) if (!conn || !user)
return SASL_BADPARAM; return SASL_BADPARAM;
sparams = ((sasl_server_conn_t *) conn)->sparams; sparams = ((sasl_server_conn_t *) conn)->sparams;
userlen = (unsigned) strlen(user); userlen = (unsigned) strlen(user);
} }
/* Pickup getopt callback from the connection, if conn is not NULL */ /* Pickup getopt callback from the connection, if conn is not NULL */
if(_sasl_getcallback(conn, SASL_CB_GETOPT, &getopt, &context) == SASL_O K) { if(_sasl_getcallback(conn, SASL_CB_GETOPT, (sasl_callback_ft *)&getopt, &context) == SASL_OK) {
ret = getopt(context, NULL, "auxprop_plugin", &plist, NULL); ret = getopt(context, NULL, "auxprop_plugin", &plist, NULL);
if(ret != SASL_OK) plist = NULL; if(ret != SASL_OK) plist = NULL;
} }
ret = SASL_OK; ret = SASL_OK;
if(!plist) { if(!plist) {
/* Do store in all plugins */ /* Do store in all plugins */
for(ptr = auxprop_head; ptr && ret == SASL_OK; ptr = ptr->next) { for(ptr = auxprop_head; ptr && ret == SASL_OK; ptr = ptr->next) {
found=1; total_plugins++;
if (ptr->plug->auxprop_store) if (ptr->plug->auxprop_store) {
ret = ptr->plug->auxprop_store(ptr->plug->glob_context, ret = ptr->plug->auxprop_store(ptr->plug->glob_context,
sparams, ctx, user, userlen); sparams, ctx, user, userlen);
if (ret == SASL_CONSTRAINT_VIOLAT) {
ret = SASL_OK;
num_constraint_violations++;
}
}
} }
} else { } else {
char *pluginlist = NULL, *freeptr = NULL, *thisplugin = NULL; char *pluginlist = NULL, *freeptr = NULL, *thisplugin = NULL;
if(_sasl_strdup(plist, &pluginlist, NULL) != SASL_OK) return SASL_FA IL; if(_sasl_strdup(plist, &pluginlist, NULL) != SASL_OK) return SASL_FA IL;
thisplugin = freeptr = pluginlist; thisplugin = freeptr = pluginlist;
/* Do store in all *specified* plugins, in order */ /* Do store in all *specified* plugins, in order */
while(*thisplugin) { while(*thisplugin) {
char *p; char *p;
skipping to change at line 971 skipping to change at line 1044
for(p = thisplugin;*p != '\0' && !isspace((int)*p); p++); for(p = thisplugin;*p != '\0' && !isspace((int)*p); p++);
if(*p == '\0') last = 1; if(*p == '\0') last = 1;
else *p='\0'; else *p='\0';
for(ptr = auxprop_head; ptr && ret == SASL_OK; ptr = ptr->next) { for(ptr = auxprop_head; ptr && ret == SASL_OK; ptr = ptr->next) {
/* Skip non-matching plugins */ /* Skip non-matching plugins */
if((!ptr->plug->name if((!ptr->plug->name
|| strcasecmp(ptr->plug->name, thisplugin))) || strcasecmp(ptr->plug->name, thisplugin)))
continue; continue;
found=1; total_plugins++;
if (ptr->plug->auxprop_store) if (ptr->plug->auxprop_store) {
ret = ptr->plug->auxprop_store(ptr->plug->glob_context, ret = ptr->plug->auxprop_store(ptr->plug->glob_context,
sparams, ctx, user, userl en); sparams, ctx, user, userl en);
if (ret == SASL_CONSTRAINT_VIOLAT) {
ret = SASL_OK;
num_constraint_violations++;
}
}
} }
if(last) break; if(last) break;
thisplugin = p+1; thisplugin = p+1;
} }
sasl_FREE(freeptr); sasl_FREE(freeptr);
} }
if(!found) { if(total_plugins == 0) {
_sasl_log(NULL, SASL_LOG_ERR, _sasl_log(NULL, SASL_LOG_ERR,
"could not find auxprop plugin, was searching for %s", "could not find auxprop plugin, was searching for %s",
plist ? plist : "[all]"); plist ? plist : "[all]");
return SASL_FAIL; return SASL_FAIL;
} else if (total_plugins == num_constraint_violations) {
ret = SASL_CONSTRAINT_VIOLAT;
} }
return ret; return ret;
} }
/* It would be nice if we can show other information like Author, Company, Year, plugin version */ /* It would be nice if we can show other information like Author, Company, Year, plugin version */
static void static void
_sasl_print_mechanism ( _sasl_print_mechanism (sasl_auxprop_plug_t *m,
sasl_auxprop_plug_t *m, sasl_info_callback_stage_t stage,
sasl_info_callback_stage_t stage, void *rock __attribute__((unused))
void *rock
) )
{ {
char delimiter;
if (stage == SASL_INFO_LIST_START) { if (stage == SASL_INFO_LIST_START) {
printf ("List of auxprop plugins follows\n"); printf ("List of auxprop plugins follows\n");
return; return;
} else if (stage == SASL_INFO_LIST_END) { } else if (stage == SASL_INFO_LIST_END) {
return; return;
} }
/* Process the mechanism */ /* Process the mechanism */
printf ("Plugin \"%s\" ", m->name); printf ("Plugin \"%s\" ", m->name);
 End of changes. 26 change blocks. 
20 lines changed or deleted 99 lines changed or added

This html diff was produced by rfcdiff 1.41. The latest version is available from http://tools.ietf.org/tools/rfcdiff/