예제 #1
0
int _sasl_locate_entry(void *library,
		       const char *entryname,
		       void **entry_point) 
{
    if(entryname == NULL) {
	_sasl_log(NULL, SASL_LOG_ERR,
		  "no entryname in _sasl_locate_entry");
	return SASL_BADPARAM;
    }

    if(library == NULL) {
	_sasl_log(NULL, SASL_LOG_ERR,
		  "no library in _sasl_locate_entry");
	return SASL_BADPARAM;
    }

    if(entry_point == NULL) {
	_sasl_log(NULL, SASL_LOG_ERR,
		  "no entrypoint output pointer in _sasl_locate_entry");
	return SASL_BADPARAM;
    }

    *entry_point = GetProcAddress(library, entryname);

    if (*entry_point == NULL) {
#if 0 /* This message appears to confuse people */
	_sasl_log(NULL, SASL_LOG_DEBUG,
		  "unable to get entry point %s: %s", entryname,
		  GetLastError());
#endif
	return SASL_FAIL;
    }

    return SASL_OK;
}
예제 #2
0
파일: dlopen.c 프로젝트: 1ack/Impala
int _sasl_locate_entry(void *library, const char *entryname,
		       void **entry_point) 
{
#ifdef DO_DLOPEN
/* note that we still check for known problem systems in
 * case we are cross-compiling */
#if defined(DLSYM_NEEDS_UNDERSCORE) || (defined(__OpenBSD__) && !defined(__ELF__))
    char adj_entryname[1024];
#else
#define adj_entryname entryname
#endif

    if(!entryname) {
	_sasl_log(NULL, SASL_LOG_ERR,
		  "no entryname in _sasl_locate_entry");
	return SASL_BADPARAM;
    }

    if(!library) {
	_sasl_log(NULL, SASL_LOG_ERR,
		  "no library in _sasl_locate_entry");
	return SASL_BADPARAM;
    }

    if(!entry_point) {
	_sasl_log(NULL, SASL_LOG_ERR,
		  "no entrypoint output pointer in _sasl_locate_entry");
	return SASL_BADPARAM;
    }

#if defined(DLSYM_NEEDS_UNDERSCORE) || (defined(__OpenBSD__) && !defined(__ELF__))
    snprintf(adj_entryname, sizeof adj_entryname, "_%s", entryname);
#endif

    *entry_point = NULL;
    *entry_point = dlsym(library, adj_entryname);
    if (*entry_point == NULL) {
#if 0 /* This message appears to confuse people */
	_sasl_log(NULL, SASL_LOG_DEBUG,
		  "unable to get entry point %s: %s", adj_entryname,
		  dlerror());
#endif
	return SASL_FAIL;
    }

    return SASL_OK;
#else
    return SASL_FAIL;
#endif /* DO_DLOPEN */
}
예제 #3
0
파일: auxprop.c 프로젝트: 1ack/Impala
/* add an auxiliary property plugin */
int sasl_auxprop_add_plugin(const char *plugname,
			    sasl_auxprop_init_t *auxpropfunc)
{
    int result, out_version;
    auxprop_plug_list_t *new_item;
    sasl_auxprop_plug_t *plug;
    
    result = auxpropfunc(sasl_global_utils, SASL_AUXPROP_PLUG_VERSION,
			 &out_version, &plug, plugname);

    if(result != SASL_OK) {
	_sasl_log(NULL, SASL_LOG_ERR, "auxpropfunc error %s\n",
		  sasl_errstring(result, NULL, NULL));
	return result;
    }

    /* We require that this function is implemented */
    if(!plug->auxprop_lookup) return SASL_BADPROT;

    new_item = sasl_ALLOC(sizeof(auxprop_plug_list_t));
    if(!new_item) return SASL_NOMEM;    

    /* These will load from least-important to most important */
    new_item->plug = plug;
    new_item->next = auxprop_head;
    auxprop_head = new_item;

    return SASL_OK;
}
예제 #4
0
/* loads a plugin library */
int _sasl_get_plugin(const char *file,
		     const sasl_callback_t *verifyfile_cb,
		     void **libraryptr)
{
    int r = 0;
    HINSTANCE library;
    lib_list_t *newhead;
    
    r = ((sasl_verifyfile_t *)(verifyfile_cb->proc))
		    (verifyfile_cb->context, file, SASL_VRFY_PLUGIN);
    if (r != SASL_OK) return r;

    newhead = sasl_ALLOC(sizeof(lib_list_t));
    if (!newhead) return SASL_NOMEM;

    if (!(library = LoadLibrary (file))) {
	_sasl_log(NULL, SASL_LOG_ERR,
		  "unable to LoadLibrary %s: %s", file, GetLastError());
	sasl_FREE(newhead);
	return SASL_FAIL;
    }

    newhead->library = library;
    newhead->next = lib_list_head;
    lib_list_head = newhead;

    *libraryptr = library;
    return SASL_OK;
}
예제 #5
0
/* add an auxiliary property plugin */
int sasl_auxprop_add_plugin(const char *plugname,
			    sasl_auxprop_init_t *auxpropfunc)
{
	int result = sasl_auxprop_add_plugin_nolog(plugname, auxpropfunc);
	if(result != SASL_OK) {
		_sasl_log(NULL, SASL_LOG_ERR, "auxpropfunc error %s\n",
			sasl_errstring(result, NULL, NULL));
    }
	
	return result;
}
예제 #6
0
/* clear values and optionally requests from property context
 *  ctx      -- property context
 *  requests -- 0 = don't clear requests, 1 = clear requests
 */
void prop_clear(struct propctx *ctx, int requests) 
{
    struct proppool *new_pool, *tmp;
    unsigned i;

    /* We're going to need a new proppool once we reset things */
    new_pool = alloc_proppool(ctx->mem_base->size +
			      (ctx->used_values+1) * sizeof(struct propval));
    if (new_pool == NULL) {
        _sasl_log(NULL, SASL_LOG_ERR, "failed to allocate memory\n");
        exit(1);
    }

    if(requests) {
	/* We're wiping the whole shebang */
	ctx->used_values = 0;
    } else {
	/* Need to keep around old requets */
	struct propval *new_values = (struct propval *)new_pool->data;
	for(i=0; i<ctx->used_values; i++) {
	    new_values[i].name = ctx->values[i].name;
	}
    }

    while(ctx->mem_base) {
	tmp = ctx->mem_base;
	ctx->mem_base = tmp->next;
	sasl_FREE(tmp);
    }
    
    /* Update allocation-related metadata */
    ctx->allocated_values = ctx->used_values+1;
    new_pool->unused =
	new_pool->size - (ctx->allocated_values * sizeof(struct propval));

    /* Setup pointers for the values array */
    ctx->values = (struct propval *)new_pool->data;
    ctx->prev_val = NULL;

    /* Setup the pools */
    ctx->mem_base = ctx->mem_cur = new_pool;

    /* Reset list_end and data_end for the new memory pool */
    ctx->list_end =
	(char **)((char *)ctx->mem_base->data + ctx->allocated_values * sizeof(struct propval));
    ctx->data_end = (char *)ctx->mem_base->data + ctx->mem_base->size;

    return;
}
예제 #7
0
/* loads a plugin library */
static int _tsasl_get_plugin(TCHAR *tfile,
    const sasl_callback_t *verifyfile_cb,
    void **libraryptr)
{
    HINSTANCE library = NULL;
    lib_list_t *newhead;
    char *file;
    int retCode = SASL_OK;

    if (sizeof(TCHAR) != sizeof(char)) {
        file = _sasl_wchar_to_utf8(tfile);
        if (!file) {
            retCode = SASL_NOMEM;
            goto cleanup;
        }
    }
    else {
        file = (char*)tfile;
    }
    retCode = ((sasl_verifyfile_t *)(verifyfile_cb->proc))
		    (verifyfile_cb->context, file, SASL_VRFY_PLUGIN);
    if (retCode != SASL_OK)
        goto cleanup;

    newhead = sasl_ALLOC(sizeof(lib_list_t));
    if (!newhead) {
        retCode = SASL_NOMEM;
        goto cleanup;
    }

    if (!(library = LoadLibrary(tfile))) {
	    _sasl_log(NULL, SASL_LOG_ERR,
		      "unable to LoadLibrary %s: %s", file, GetLastError());
	    sasl_FREE(newhead);
        retCode = SASL_FAIL;
        goto cleanup;
    }

    newhead->library = library;
    newhead->next = lib_list_head;
    lib_list_head = newhead;

    *libraryptr = library;
cleanup:
    if (sizeof(TCHAR) != sizeof(char)) {
        sasl_FREE(file);
    }
    return retCode;
}
예제 #8
0
파일: dlopen.c 프로젝트: 1ack/Impala
static int _sasl_plugin_load(char *plugin, void *library,
			     const char *entryname,
			     int (*add_plugin)(const char *, void *)) 
{
    void *entry_point;
    int result;
    
    result = _sasl_locate_entry(library, entryname, &entry_point);
    if(result == SASL_OK) {
	result = add_plugin(plugin, entry_point);
	if(result != SASL_OK)
	    _sasl_log(NULL, SASL_LOG_DEBUG,
		      "_sasl_plugin_load failed on %s for plugin: %s\n",
		      entryname, plugin);
    }

    return result;
}
예제 #9
0
파일: dlopen.c 프로젝트: 1ack/Impala
/* loads a plugin library */
int _sasl_get_plugin(const char *file,
		     const sasl_callback_t *verifyfile_cb,
		     void **libraryptr)
{
#ifdef DO_DLOPEN
    int r = 0;
    int flag;
    void *library;
    lib_list_t *newhead;
    
    r = ((sasl_verifyfile_t *)(verifyfile_cb->proc))
		    (verifyfile_cb->context, file, SASL_VRFY_PLUGIN);
    if (r != SASL_OK) return r;

#ifdef RTLD_NOW
    flag = RTLD_NOW;
#else
    flag = 0;
#endif

    newhead = sasl_ALLOC(sizeof(lib_list_t));
    if(!newhead) return SASL_NOMEM;

    if (!(library = dlopen(file, flag))) {
	_sasl_log(NULL, SASL_LOG_ERR,
		  "unable to dlopen %s: %s", file, dlerror());
	sasl_FREE(newhead);
	return SASL_FAIL;
    }

    newhead->library = library;
    newhead->next = lib_list_head;
    lib_list_head = newhead;

    *libraryptr = library;
    return SASL_OK;
#else
    return SASL_FAIL;
#endif /* DO_DLOPEN */
}
예제 #10
0
파일: auxprop.c 프로젝트: 1ack/Impala
/* Do the callbacks for auxprop stores */
int sasl_auxprop_store(sasl_conn_t *conn,
		       struct propctx *ctx, const char *user)
{
    sasl_getopt_t *getopt;
    int ret, found = 0;
    void *context;
    const char *plist = NULL;
    auxprop_plug_list_t *ptr;
    sasl_server_params_t *sparams = NULL;
    unsigned userlen = 0;

    if (ctx) {
	if (!conn || !user)
	    return SASL_BADPARAM;

	sparams = ((sasl_server_conn_t *) conn)->sparams;
	userlen = (unsigned) strlen(user);
    }
    
    /* Pickup getopt callback from the connection, if conn is not NULL */
    if(_sasl_getcallback(conn, SASL_CB_GETOPT, &getopt, &context) == SASL_OK) {
	ret = getopt(context, NULL, "auxprop_plugin", &plist, NULL);
	if(ret != SASL_OK) plist = NULL;
    }

    ret = SASL_OK;
    if(!plist) {
	/* Do store in all plugins */
	for(ptr = auxprop_head; ptr && ret == SASL_OK; ptr = ptr->next) {
	    found=1;
	    if (ptr->plug->auxprop_store)
		ret = ptr->plug->auxprop_store(ptr->plug->glob_context,
					       sparams, ctx, user, userlen);
	}
    } else {
	char *pluginlist = NULL, *freeptr = NULL, *thisplugin = NULL;

	if(_sasl_strdup(plist, &pluginlist, NULL) != SASL_OK) return SASL_FAIL;
	thisplugin = freeptr = pluginlist;
	
	/* Do store in all *specified* plugins, in order */
	while(*thisplugin) {
	    char *p;
	    int last=0;
	    
	    while(*thisplugin && isspace((int)*thisplugin)) thisplugin++;
	    if(!(*thisplugin)) break;
	    
	    for(p = thisplugin;*p != '\0' && !isspace((int)*p); p++);
	    if(*p == '\0') last = 1;
	    else *p='\0';
	    
	    for(ptr = auxprop_head; ptr && ret == SASL_OK; ptr = ptr->next) {
		/* Skip non-matching plugins */
		if((!ptr->plug->name
		    || strcasecmp(ptr->plug->name, thisplugin)))
		    continue;

		found=1;
		if (ptr->plug->auxprop_store)
		    ret = ptr->plug->auxprop_store(ptr->plug->glob_context,
						   sparams, ctx, user, userlen);
	    }

	    if(last) break;

	    thisplugin = p+1;
	}

	sasl_FREE(freeptr);
    }

    if(!found) {
	_sasl_log(NULL, SASL_LOG_ERR,
		  "could not find auxprop plugin, was searching for %s",
		  plist ? plist : "[all]");
	return SASL_FAIL;
    }

    return ret;
}
예제 #11
0
파일: auxprop.c 프로젝트: 1ack/Impala
/* Do the callbacks for auxprop lookups */
void _sasl_auxprop_lookup(sasl_server_params_t *sparams,
			  unsigned flags,
			  const char *user, unsigned ulen) 
{
    sasl_getopt_t *getopt;
    int ret, found = 0;
    void *context;
    const char *plist = NULL;
    auxprop_plug_list_t *ptr;

    if(_sasl_getcallback(sparams->utils->conn,
			 SASL_CB_GETOPT, &getopt, &context) == SASL_OK) {
	ret = getopt(context, NULL, "auxprop_plugin", &plist, NULL);
	if(ret != SASL_OK) plist = NULL;
    }

    if(!plist) {
	/* Do lookup in all plugins */
	for(ptr = auxprop_head; ptr; ptr = ptr->next) {
	    found=1;
	    ptr->plug->auxprop_lookup(ptr->plug->glob_context,
				      sparams, flags, user, ulen);
	}
    } else {
	char *pluginlist = NULL, *freeptr = NULL, *thisplugin = NULL;

	if(_sasl_strdup(plist, &pluginlist, NULL) != SASL_OK) return;
	thisplugin = freeptr = pluginlist;
	
	/* Do lookup in all *specified* plugins, in order */
	while(*thisplugin) {
	    char *p;
	    int last=0;
	    
	    while(*thisplugin && isspace((int)*thisplugin)) thisplugin++;
	    if(!(*thisplugin)) break;
	    
	    for(p = thisplugin;*p != '\0' && !isspace((int)*p); p++);
	    if(*p == '\0') last = 1;
	    else *p='\0';
	    
	    for(ptr = auxprop_head; ptr; ptr = ptr->next) {
		/* Skip non-matching plugins */
		if(!ptr->plug->name
		   || strcasecmp(ptr->plug->name, thisplugin))
		    continue;
	    
		found=1;
		ptr->plug->auxprop_lookup(ptr->plug->glob_context,
					  sparams, flags, user, ulen);
	    }

	    if(last) break;

	    thisplugin = p+1;
	}

	sasl_FREE(freeptr);
    }

    if(!found)
	_sasl_log(sparams->utils->conn, SASL_LOG_DEBUG,
		  "could not find auxprop plugin, was searching for '%s'",
		  plist ? plist : "[all]");
}
예제 #12
0
파일: dlopen.c 프로젝트: 1ack/Impala
/* gets the list of mechanisms */
int _sasl_load_plugins(const add_plugin_list_t *entrypoints,
		       const sasl_callback_t *getpath_cb,
		       const sasl_callback_t *verifyfile_cb)
{
    int result;
    const add_plugin_list_t *cur_ep;
#ifdef DO_DLOPEN
    char str[PATH_MAX], tmp[PATH_MAX+2], prefix[PATH_MAX+2];
				/* 1 for '/' 1 for trailing '\0' */
    char c;
    int pos;
    const char *path=NULL;
    int position;
    DIR *dp;
    struct dirent *dir;
#endif
#ifndef PIC
    add_plugin_t *add_plugin;
    _sasl_plug_type type;
    _sasl_plug_rec *p;
#endif

    if (! entrypoints
	|| ! getpath_cb
	|| getpath_cb->id != SASL_CB_GETPATH
	|| ! getpath_cb->proc
	|| ! verifyfile_cb
	|| verifyfile_cb->id != SASL_CB_VERIFYFILE
	|| ! verifyfile_cb->proc)
	return SASL_BADPARAM;

#ifndef PIC
    /* do all the static plugins first */

    for(cur_ep = entrypoints; cur_ep->entryname; cur_ep++) {

	/* What type of plugin are we looking for? */
	if(!strcmp(cur_ep->entryname, "sasl_server_plug_init")) {
	    type = SERVER;
	    add_plugin = (add_plugin_t *)sasl_server_add_plugin;
	} else if (!strcmp(cur_ep->entryname, "sasl_client_plug_init")) {
	    type = CLIENT;
	    add_plugin = (add_plugin_t *)sasl_client_add_plugin;
	} else if (!strcmp(cur_ep->entryname, "sasl_auxprop_plug_init")) {
	    type = AUXPROP;
	    add_plugin = (add_plugin_t *)sasl_auxprop_add_plugin;
	} else if (!strcmp(cur_ep->entryname, "sasl_canonuser_init")) {
	    type = CANONUSER;
	    add_plugin = (add_plugin_t *)sasl_canonuser_add_plugin;
	} else {
	    /* What are we looking for then? */
	    return SASL_FAIL;
	}
	for (p=_sasl_static_plugins; p->type; p++) {
	    if(type == p->type)
	    	result = add_plugin(p->name, p->plug);
	}
    }
#endif /* !PIC */

/* only do the following if:
 * 
 * we support dlopen()
 *  AND we are not staticly compiled
 *      OR we are staticly compiled and TRY_DLOPEN_WHEN_STATIC is defined
 */
#if defined(DO_DLOPEN) && (defined(PIC) || (!defined(PIC) && defined(TRY_DLOPEN_WHEN_STATIC)))
    /* get the path to the plugins */
    result = ((sasl_getpath_t *)(getpath_cb->proc))(getpath_cb->context,
						    &path);
    if (result != SASL_OK) return result;
    if (! path) return SASL_FAIL;

    if (strlen(path) >= PATH_MAX) { /* no you can't buffer overrun */
	return SASL_FAIL;
    }

    position=0;
    do {
	pos=0;
	do {
	    c=path[position];
	    position++;
	    str[pos]=c;
	    pos++;
	} while ((c!=':') && (c!='=') && (c!=0));
	str[pos-1]='\0';

	strcpy(prefix,str);
	strcat(prefix,"/");

	if ((dp=opendir(str)) !=NULL) /* ignore errors */    
	{
	    while ((dir=readdir(dp)) != NULL)
	    {
		size_t length;
		void *library;
		char *c;
		char plugname[PATH_MAX];
		char name[PATH_MAX];

		length = NAMLEN(dir);
		if (length < 4) 
		    continue; /* can not possibly be what we're looking for */

		if (length + pos>=PATH_MAX) continue; /* too big */

		if (strcmp(dir->d_name + (length - strlen(SO_SUFFIX)),
			   SO_SUFFIX)
		    && strcmp(dir->d_name + (length - strlen(LA_SUFFIX)),
			   LA_SUFFIX))
		    continue;

		memcpy(name,dir->d_name,length);
		name[length]='\0';

		result = _parse_la(prefix, name, tmp);
		if(result != SASL_OK)
		    continue;
		
		/* skip "lib" and cut off suffix --
		   this only need be approximate */
		strcpy(plugname, name + 3);
		c = strchr(plugname, (int)'.');
		if(c) *c = '\0';

		result = _sasl_get_plugin(tmp, verifyfile_cb, &library);

		if(result != SASL_OK)
		    continue;

		for(cur_ep = entrypoints; cur_ep->entryname; cur_ep++) {
			_sasl_plugin_load(plugname, library, cur_ep->entryname,
					  cur_ep->add_plugin);
			/* If this fails, it's not the end of the world */
		}
	    }

	    closedir(dp);
	} else {
	    _sasl_log(NULL, SASL_LOG_DEBUG,
		      "looking for plugins in '%s', failed to open directory, error: %s",
		      str,
		      strerror(errno));
	}

    } while ((c!='=') && (c!=0));
#endif /* defined(DO_DLOPEN) && (!defined(PIC) || (defined(PIC) && defined(TRY_DLOPEN_WHEN_STATIC))) */

    return SASL_OK;
}
예제 #13
0
파일: dlopen.c 프로젝트: 1ack/Impala
static int _parse_la(const char *prefix, const char *in, char *out) 
{
    FILE *file;
    size_t length;
    char line[MAX_LINE];
    char *ntmp = NULL;

    if(!in || !out || !prefix || out == in) return SASL_BADPARAM;

    /* Set this so we can detect failure */
    *out = '\0';

    length = strlen(in);

    if (strcmp(in + (length - strlen(LA_SUFFIX)), LA_SUFFIX)) {
	if(!strcmp(in + (length - strlen(SO_SUFFIX)),SO_SUFFIX)) {
	    /* check for a .la file */
	    strcpy(line, prefix);
	    strcat(line, in);
	    length = strlen(line);
	    *(line + (length - strlen(SO_SUFFIX))) = '\0';
	    strcat(line, LA_SUFFIX);
	    file = fopen(line, "r");
	    if(file) {
		/* We'll get it on the .la open */
		fclose(file);
		return SASL_FAIL;
	    }
	}
	strcpy(out, prefix);
	strcat(out, in);
	return SASL_OK;
    }

    strcpy(line, prefix);
    strcat(line, in);

    file = fopen(line, "r");
    if(!file) {
	_sasl_log(NULL, SASL_LOG_WARN,
		  "unable to open LA file: %s", line);
	return SASL_FAIL;
    }
    
    while(!feof(file)) {
	if(!fgets(line, MAX_LINE, file)) break;
	if(line[strlen(line) - 1] != '\n') {
	    _sasl_log(NULL, SASL_LOG_WARN,
		      "LA file has too long of a line: %s", in);
	    return SASL_BUFOVER;
	}
	if(line[0] == '\n' || line[0] == '#') continue;
	if(!strncmp(line, "dlname=", sizeof("dlname=") - 1)) {
	    /* We found the line with the name in it */
	    char *end;
	    char *start;
	    size_t len;
	    end = strrchr(line, '\'');
	    if(!end) continue;
	    start = &line[sizeof("dlname=")-1];
	    len = strlen(start);
	    if(len > 3 && start[0] == '\'') {
		ntmp=&start[1];
		*end='\0';
		/* Do we have dlname="" ? */
		if(ntmp == end) {
		    _sasl_log(NULL, SASL_LOG_DEBUG,
			      "dlname is empty in .la file: %s", in);
		    return SASL_FAIL;
		}
		strcpy(out, prefix);
		strcat(out, ntmp);
	    }
	    break;
	}
    }
    if(ferror(file) || feof(file)) {
	_sasl_log(NULL, SASL_LOG_WARN,
		  "Error reading .la: %s\n", in);
	fclose(file);
	return SASL_FAIL;
    }
    fclose(file);

    if(!(*out)) {
	_sasl_log(NULL, SASL_LOG_WARN,
		  "Could not find a dlname line in .la file: %s", in);
	return SASL_FAIL;
    }

    return SASL_OK;
}
예제 #14
0
/* gets the list of mechanisms */
int _sasl_load_plugins(const add_plugin_list_t *entrypoints,
		       const sasl_callback_t *getpath_cb,
		       const sasl_callback_t *verifyfile_cb)
{
    int result;
    char cur_dir[PATH_MAX], full_name[PATH_MAX+2], prefix[PATH_MAX+2];
				/* 1 for '\\' 1 for trailing '\0' */
    char * pattern;
    char c;
    int pos;
    const char *path=NULL;
    int position;
    const add_plugin_list_t *cur_ep;
    struct stat statbuf;		/* filesystem entry information */
    intptr_t fhandle;			/* file handle for _findnext function */
    struct _finddata_t finddata;	/* data returned by _findnext() */
    size_t prefix_len;

    if (! entrypoints
	|| ! getpath_cb
	|| getpath_cb->id != SASL_CB_GETPATH
	|| ! getpath_cb->proc
	|| ! verifyfile_cb
	|| verifyfile_cb->id != SASL_CB_VERIFYFILE
	|| ! verifyfile_cb->proc)
	return SASL_BADPARAM;

    /* get the path to the plugins */
    result = ((sasl_getpath_t *)(getpath_cb->proc))(getpath_cb->context,
						    &path);
    if (result != SASL_OK) return result;
    if (! path) return SASL_FAIL;

    if (strlen(path) >= PATH_MAX) { /* no you can't buffer overrun */
	return SASL_FAIL;
    }

    position=0;
    do {
	pos=0;
	do {
	    c=path[position];
	    position++;
	    cur_dir[pos]=c;
	    pos++;
	} while ((c!=PATHS_DELIMITER) && (c!=0));
	cur_dir[pos-1]='\0';


/* : check to make sure that a valid directory name was passed in */
	if (stat (cur_dir, &statbuf) < 0) {
	    continue;
	}
	if ((statbuf.st_mode & S_IFDIR) == 0) {
	    continue;
	}

	strcpy (prefix, cur_dir);
	prefix_len = strlen (prefix);

/* : Don't append trailing \ unless required */
	if (prefix[prefix_len-1] != '\\') {
	    strcat (prefix,"\\");
	    prefix_len++;
	}

	pattern = prefix;

/* : Check that we have enough space for "*.dll" */
	if ((prefix_len + DLL_MASK_LEN) > (sizeof(prefix) - 1)) {
	    _sasl_log(NULL, SASL_LOG_WARN, "plugin search mask is too big");
            continue;
	}

	strcat (prefix + prefix_len, "*" DLL_SUFFIX);

        fhandle = _findfirst (pattern, &finddata);
        if (fhandle == -1) {	/* no matching files */
            continue;
        }

/* : Truncate "*.dll" */
	prefix[prefix_len] = '\0';

	do {
	    size_t length;
	    void *library;
	    char *c;
	    char plugname[PATH_MAX];
	    int entries;

	    length = strlen(finddata.name);
	    if (length < 5) { /* At least <Ch>.dll */
		continue; /* can not possibly be what we're looking for */
	    }

/* : Check for overflow */
	    if (length + prefix_len >= PATH_MAX) continue; /* too big */

	    if (stricmp(finddata.name + (length - strlen(DLL_SUFFIX)), DLL_SUFFIX) != 0) {
		continue;
	    }

/* : Check that it is not a directory */
	    if ((finddata.attrib & _A_SUBDIR) == _A_SUBDIR) {
		continue;
	    }

/* : Construct full name from prefix and name */

	    strcpy (full_name, prefix);
	    strcat (full_name, finddata.name);
		
/* cut off .dll suffix -- this only need be approximate */
	    strcpy (plugname, finddata.name);
	    c = strrchr(plugname, '.');
	    if (c != NULL) *c = '\0';

	    result = _sasl_get_plugin (full_name, verifyfile_cb, &library);

	    if (result != SASL_OK) {
		continue;
	    }

	    entries = 0;
	    for (cur_ep = entrypoints; cur_ep->entryname; cur_ep++) {
		result = _sasl_plugin_load(plugname,
					   library,
					   cur_ep->entryname,
					   cur_ep->add_plugin);
		if (result == SASL_OK) {
		    ++entries;
		}
		/* If this fails, it's not the end of the world */
	    }
	    if (entries == 0) {
		_sasl_remove_last_plugin();
	    }

	} while (_findnext (fhandle, &finddata) == 0);
	
	_findclose (fhandle);

    } while ((c!='=') && (c!=0));

    return SASL_OK;
}
예제 #15
0
/* Do the callbacks for auxprop lookups */
int _sasl_auxprop_lookup(sasl_server_params_t *sparams,
			  unsigned flags,
			  const char *user, unsigned ulen) 
{
    sasl_getopt_t *getopt;
    int ret, found = 0;
    void *context;
    const char *plist = NULL;
    auxprop_plug_list_t *ptr;
    int result = SASL_NOMECH;

    if(_sasl_getcallback(sparams->utils->conn,
			 SASL_CB_GETOPT,
			 (sasl_callback_ft *)&getopt,
			 &context) == SASL_OK) {
	ret = getopt(context, NULL, "auxprop_plugin", &plist, NULL);
	if(ret != SASL_OK) plist = NULL;
    }

    if(!plist) {
	/* Do lookup in all plugins */

	/* TODO: Ideally, each auxprop plugin should be marked if its failure
	   should be ignored or treated as a fatal error of the whole lookup. */
	for(ptr = auxprop_head; ptr; ptr = ptr->next) {
	    found=1;
	    ret = ptr->plug->auxprop_lookup(ptr->plug->glob_context,
				      sparams, flags, user, ulen);
	    result = _sasl_account_status (result, ret);
	}
    } else {
	char *pluginlist = NULL, *freeptr = NULL, *thisplugin = NULL;

	if(_sasl_strdup(plist, &pluginlist, NULL) != SASL_OK) return SASL_NOMEM;
	thisplugin = freeptr = pluginlist;
	
	/* Do lookup in all *specified* plugins, in order */
	while(*thisplugin) {
	    char *p;
	    int last=0;
	    
	    while(*thisplugin && isspace((int)*thisplugin)) thisplugin++;
	    if(!(*thisplugin)) break;
	    
	    for(p = thisplugin;*p != '\0' && !isspace((int)*p); p++);
	    if(*p == '\0') last = 1;
	    else *p='\0';
	    
	    for(ptr = auxprop_head; ptr; ptr = ptr->next) {
		/* Skip non-matching plugins */
		if(!ptr->plug->name
		   || strcasecmp(ptr->plug->name, thisplugin))
		    continue;
	    
		found=1;
		ret = ptr->plug->auxprop_lookup(ptr->plug->glob_context,
					  sparams, flags, user, ulen);
		result = _sasl_account_status (result, ret);
	    }

	    if(last) break;

	    thisplugin = p+1;
	}

	sasl_FREE(freeptr);
    }

    if(!found) {
	_sasl_log(sparams->utils->conn, SASL_LOG_DEBUG,
		  "could not find auxprop plugin, was searching for '%s'",
		  plist ? plist : "[all]");
    }

    return result;
}
예제 #16
0
/* gets the list of mechanisms */
int _sasl_load_plugins(const add_plugin_list_t *entrypoints,
		       const sasl_callback_t *getpath_cb,
		       const sasl_callback_t *verifyfile_cb)
{
    int result;
    TCHAR cur_dir[PATH_MAX], full_name[PATH_MAX+2], prefix[PATH_MAX+2];
				/* 1 for '\\' 1 for trailing '\0' */
    TCHAR * pattern;
    TCHAR c;
    int pos;
    int retCode = SASL_OK;
    char *utf8path = NULL;
    TCHAR *path=NULL;
    int position;
    const add_plugin_list_t *cur_ep;
    struct _stat statbuf;		/* filesystem entry information */
    intptr_t fhandle;			/* file handle for _findnext function */
    struct _tfinddata_t finddata;	/* data returned by _findnext() */
    size_t prefix_len;
    
    /* for static plugins */
    add_plugin_t *add_plugin;
    _sasl_plug_type type;
    _sasl_plug_rec *p;

    if (! entrypoints
	|| ! getpath_cb
	|| getpath_cb->id != SASL_CB_GETPATH
	|| ! getpath_cb->proc
	|| ! verifyfile_cb
	|| verifyfile_cb->id != SASL_CB_VERIFYFILE
	|| ! verifyfile_cb->proc)
	return SASL_BADPARAM;

    /* do all the static plugins first */

    for (cur_ep = entrypoints; cur_ep->entryname; cur_ep++) {

        /* What type of plugin are we looking for? */
        if (!strcmp(cur_ep->entryname, "sasl_server_plug_init")) {
            type = SERVER;
            add_plugin = (add_plugin_t *)sasl_server_add_plugin;
        }
        else if (!strcmp(cur_ep->entryname, "sasl_client_plug_init")) {
            type = CLIENT;
            add_plugin = (add_plugin_t *)sasl_client_add_plugin;
        }
        else if (!strcmp(cur_ep->entryname, "sasl_auxprop_plug_init")) {
            type = AUXPROP;
            add_plugin = (add_plugin_t *)sasl_auxprop_add_plugin;
        }
        else if (!strcmp(cur_ep->entryname, "sasl_canonuser_init")) {
            type = CANONUSER;
            add_plugin = (add_plugin_t *)sasl_canonuser_add_plugin;
        }
        else {
            /* What are we looking for then? */
            return SASL_FAIL;
        }
        for (p = _sasl_static_plugins; p->type; p++) {
            if (type == p->type)
                result = add_plugin(p->name, p->plug);
        }
    }

    /* get the path to the plugins */
    result = ((sasl_getpath_t *)(getpath_cb->proc))(getpath_cb->context,
						    &utf8path);
    if (result != SASL_OK) return result;
    if (!utf8path) return SASL_FAIL;

    if (sizeof(TCHAR) == sizeof(char)) {
        path = (TCHAR*)utf8path;
    }
    else {
        path = _sasl_utf8_to_wchar(utf8path);
        if (!path) return SASL_FAIL;
    }

    if (_tcslen(path) >= PATH_MAX) { /* no you can't buffer overrun */
	    retCode = SASL_FAIL;
        goto cleanup;
    }

    position=0;
    do {
	pos=0;
	do {
	    c=path[position];
	    position++;
	    cur_dir[pos]=c;
	    pos++;
	} while ((c!=PATHS_DELIMITER) && (c!=0));
	cur_dir[pos-1]='\0';


/* : check to make sure that a valid directory name was passed in */
	if (_tstat (cur_dir, &statbuf) < 0) {
	    continue;
	}
	if ((statbuf.st_mode & S_IFDIR) == 0) {
	    continue;
	}

    _tcscpy(prefix, cur_dir);
	prefix_len = _tcslen (prefix);

/* : Don't append trailing \ unless required */
	if (prefix[prefix_len-1] != '\\') {
        _tcscat(prefix,_T("\\"));
	    prefix_len++;
	}

	pattern = prefix;

/* : Check that we have enough space for "*.dll" */
	if ((prefix_len + DLL_MASK_LEN) > (sizeof(prefix) / sizeof(TCHAR) - 1)) {
	    _sasl_log(NULL, SASL_LOG_WARN, "plugin search mask is too big");
            continue;
	}

	_tcscat (prefix + prefix_len, _T("*") DLL_SUFFIX);

        fhandle = _tfindfirst (pattern, &finddata);
        if (fhandle == -1) {	/* no matching files */
            continue;
        }

/* : Truncate "*.dll" */
	prefix[prefix_len] = '\0';

	do {
	    size_t length;
	    void *library;
	    char *c;
	    char plugname[PATH_MAX];
	    int entries;

	    length = _tcslen(finddata.name);
	    if (length < 5) { /* At least <Ch>.dll */
		continue; /* can not possibly be what we're looking for */
	    }

/* : Check for overflow */
	    if (length + prefix_len >= PATH_MAX) continue; /* too big */

	    if (_tcscmp(finddata.name + (length - _tcslen(DLL_SUFFIX)), DLL_SUFFIX) != 0) {
		continue;
	    }

/* : Check that it is not a directory */
	    if ((finddata.attrib & _A_SUBDIR) == _A_SUBDIR) {
		continue;
	    }

/* : Construct full name from prefix and name */

        _tcscpy (full_name, prefix);
        _tcscat (full_name, finddata.name);
		
/* cut off .dll suffix -- this only need be approximate */
        if (sizeof(TCHAR) != sizeof(char)) {
            if (WideCharToMultiByte(CP_UTF8, 0, finddata.name, -1, plugname, sizeof(plugname), NULL, NULL) == 0) { // in case of unicode use utf8
                continue;
            }
        }
        else {
            _tcscpy((TCHAR*)plugname, finddata.name); // w/o unicode local enconding is fine
        }
	    c = strchr(plugname, '.');
	    if (c != NULL) *c = '\0';

	    result = _tsasl_get_plugin (full_name, verifyfile_cb, &library);

	    if (result != SASL_OK) {
		continue;
	    }

	    entries = 0;
	    for (cur_ep = entrypoints; cur_ep->entryname; cur_ep++) {
		result = _sasl_plugin_load(plugname,
					   library,
					   cur_ep->entryname,
					   cur_ep->add_plugin);
		if (result == SASL_OK) {
		    ++entries;
		}
		/* If this fails, it's not the end of the world */
	    }
	    if (entries == 0) {
		_sasl_remove_last_plugin();
	    }

	} while (_tfindnext (fhandle, &finddata) == 0);
	
	_findclose (fhandle);

    } while ((c!='=') && (c!=0));

cleanup:
    if (sizeof(TCHAR) != sizeof(char)) {
        sasl_FREE(path); /* It's always allocated in coversion to wchar */
    }
    return retCode;
}