cyrus-pop3 and saslauthd. username check in mailbox.db?

Igor Brezac igor at ipass.net
Thu Dec 16 11:54:43 EST 2004



On Thu, 16 Dec 2004, Thomas Vogt wrote:

> Am Donnerstag, den 16.12.2004, 11:14 -0500 schrieb Igor Brezac:
>>> First of all. Do I've to definied the ldap_filter in imapd.conf and in
>>> saslauthd.conf? I thought sasl_pwcheck_method: saslauthd for imapd.conf
>>> is enough.
>>>
>>
>> Correct.  You can only define ldap_filter in saslauthd.conf.
>
> Thnx.
>
>>> Is it not possible to authenticate a user in cyrus-imapd with other
>>> names than the default uid/mailbox name even if I've set ldap_filter? Is
>>> the username check limited to the mailbox.db?
>>> I mean cyrus can always get the uid if a user authenticate itself as
>>> with another entry in den ldap server.
>>
>> This is not how it works.  saslauthd verifies passwords only.
>>
>> There are several ways to implement user rewriting functionality.  I would
>> write a custom sasl canon plugin.
>
> Ok. I know that there is a short explanation about canon_user plugin at
> http://asg.web.cmu.edu/cyrus/download/sasl/plugprog.html#canon_user
>
> I'm not a C Coder. Do you have any code snipet or a real custom sasl
> canon plugin as an example?

I attached a canon plugin which fully qualifies usernames based on the 
interface reverse lookup.  I used it with sendmail.

-- 
Igor
-------------- next part --------------
/* COPYRIGHT
 * Copyright (c) 2002-2002 Igor Brezac
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY IGOR BREZAC. ``AS IS'' AND ANY
 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL IGOR BREZAC OR
 * ITS EMPLOYEES OR AGENTS BE LIABLE FOR ANY DIRECT, INDIRECT,
 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
 * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
 * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
 * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
 * DAMAGE.
 * END COPYRIGHT */

#include <config.h>
#include <sasl.h>
#include <string.h>
#include <ctype.h>
#include <prop.h>
#include <stdio.h>
#include <syslog.h>

#include "plugin_common.h"

#ifdef MIN
#undef MIN
#endif
#define MIN(a,b) (((a) < (b))? (a):(b))

extern sasl_canonuser_plug_t fqu_canonuser_plugin;

static int fqu_getdn(const sasl_server_params_t *params, 
		     const char *addr, 
		     char **ret)
{   
	struct hostent *hp = NULL;
	struct sockaddr_in ss;
	char *dn;
	int rc;

	rc = _plug_ipfromstring(params->utils, addr, (struct sockaddr *)&ss, sizeof(ss));
	if (rc != SASL_OK) {
		return rc;
	}                  

	hp = gethostbyaddr((char *)&ss.sin_addr, sizeof(ss.sin_addr), AF_INET);
	if (hp == NULL) {
		return SASL_FAIL;
	}

	dn = strchr(hp->h_name, '.');
	if (dn == NULL) {
		dn = hp->h_name;
	} else {
		dn++;
	}

	*ret = dn;
	return SASL_OK;
}

static int fqu_trim(const sasl_utils_t *utils, 
		    const char *in, 
		    char **ret, 
		    unsigned *retlen)
{
	unsigned i;
	const char *temp;
	char *out;
	unsigned len;

	len = strlen(in);

	for(i=0; isspace((int)in[i]) && i<len; i++);
	temp = &(in[i]);
	if(i>0) {
		len -= i;
	}

	for(; isspace((int)temp[len-1]) && len > 0; len--);
	if(temp == &(in[len])) {
		return SASL_FAIL;
	}

	out = utils->malloc((len + 2) * sizeof(char));
	if (out == NULL) {
		return SASL_NOMEM;
	}

	memcpy(out, temp, len);
	out[len] = '\0';

	*ret = out;
	if (*retlen) {
		*retlen = len;
	}

	return SASL_OK;
}


static int fqu(void *glob_context __attribute__((unused)),
	       sasl_server_params_t *sparams,
	       const char *user, unsigned ulen,
	       unsigned flags __attribute__((unused)),
	       char *out_user,
	       unsigned out_umax, unsigned *out_ulen)
{
	int rc = 0;
	char *dn = NULL;
	unsigned dnlen;
	char *userin;
	sasl_utils_t *utils;

	utils = (sasl_utils_t *)sparams->utils;

	if(!utils || !user) {
		return SASL_BADPARAM;
	}

	if (!sparams->iplocalport) {
		syslog(LOG_ERR|LOG_AUTH, "Local IP/Port is unknown.");
		return SASL_BADPARAM;
	}

	if (!sparams->appname) {
		syslog(LOG_ERR|LOG_AUTH, "Application name is unknown.");
		return SASL_BADPARAM;
	}

	rc = fqu_trim(utils, user, &userin, &ulen);
	if (rc != SASL_OK) {
		utils->seterror(utils->conn, 0, "All-whitespace username.");
		return rc;
	}

	if (ulen > out_umax)
		return SASL_BUFOVER;
	memcpy(out_user, userin, ulen);

	if (!strchr(userin, '@')) {
		rc = fqu_getdn(sparams, sparams->iplocalport, &dn);
		if (rc == SASL_OK) {
			dnlen = strlen(dn);
			out_user[ulen++] = '@';
			if ((ulen+dnlen) > out_umax) {
				utils->free(userin);
				return SASL_BUFOVER;
			}
			memcpy(out_user+ulen, dn, dnlen);
			ulen += dnlen;
		} else {
			syslog(LOG_ERR|LOG_AUTH, "Cannot determine the hostname for %s.", sparams->iplocalport);
		}
	}

	out_user[ulen] = '\0';
	if(out_ulen) {
		*out_ulen = ulen;
	}

	utils->free(userin);

	return SASL_OK;
}


static sasl_canonuser_plug_t fqu_canonuser_plugin = {
        0, 			/* features */
	0, 			/* spare */
	NULL, 			/* glob_context */
	"fqu",			/* name */
	NULL, 			/* canon_user_free */
	fqu,
	NULL,
	NULL,
	NULL,
	NULL
};


int fqu_canonuser_plug_init(const sasl_utils_t *utils __attribute__((unused)),
			int max_version,
			int *out_version,
			sasl_canonuser_plug_t **plug,
			const char *plugname __attribute__((unused))) 
{
    if(!out_version || !plug) return SASL_BADPARAM;

    if(max_version < SASL_CANONUSER_PLUG_VERSION) return SASL_BADVERS;
    
    *out_version = SASL_CANONUSER_PLUG_VERSION;

    *plug = &fqu_canonuser_plugin;

    return SASL_OK;
}


More information about the Info-cyrus mailing list