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