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
/* 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;
}

Reply via email to