nodens2099 wrote: EA> I want to be able to store the Cyrus IMAP admin credentials EA> locally on the Linux server, while all other users are EA> using LDAP backend for login. [..] EA> this does not work, because I also use ptloader on the Cyrus IMAP EA> server and hence all the authentication is working well, but the EA> authorization fails (because ptloader always tries to query LDAP). CH> We use a similar setup here. LDAP authentication with ptloader, CH> and sasldb access for admin. PTS is used for user / group lookups. CH> So you need to have a match for your admin user in the ldap CH> database, even if it has no password and another authentication CH> mean is called upon admin login. We found that feature of PTS quite annoying, especially when we started building Murders using SSL PKI to authenticate the servers to eachother, so I wrote the attached patch to avoid the need to have dummy LDAP entries for the CNs of each machine's client certificate. The patch adds an imapd.conf option called "ldap_external_ids" which lists identifiers you want PTS to assume are OK. In your case that would the the admin username. This version applies to our 2.3.14++ tree and I haven't tested it for dependencies on other patches. Update to 2.3.16 is on the To Do list... Admittedly it's a matter of taste whether to put these things in LDAP (possibly hidden from everything except PTS by ACLs) or in the config files. My personal preference would be all things end-user-related in LDAP, all things structural to the systems in config files. Cheers Duncan -- Duncan Gibb - Technical Director Sirius Corporation plc - control through freedom http://www.siriusit.co.uk/ || t: +44 870 608 0063 Debian Cyrus Team - https://alioth.debian.org/projects/pkg-cyrus-imapd/
#! /bin/sh /usr/share/dpatch/dpatch-run ## 96-pts_ldap_external.dpatch ## ## All lines beginning with `## DP:' are a description of the patch. ## DP: Add a config option to the LDAP pts module to supply ## DP: a list of canonical identifiers who exist externally. ## DP: Duncan Gibb, Sirius Corporation plc <duncan.gibb@xxxxxxxxxxxxxx> @DPATCH@ diff -Nrub --exclude debian --exclude '*~' reference/lib/imapoptions editing/lib/imapoptions --- reference/lib/imapoptions 2009-04-23 16:40:21.000000000 +0100 +++ editing/lib/imapoptions 2009-05-06 11:32:46.000000000 +0100 @@ -365,6 +365,10 @@ { "ldap_deref", "never", STRINGLIST("search", "find", "always", "never") } /* Specify how aliases dereferencing is handled during search. */ +{ "ldap_external_ids", "", STRING } +/* List of identifiers for the pts ldap module to assume are valid, + without actually looking at the LDAP directory. */ + { "ldap_filter", "(uid=%u)", STRING } /* Specify a filter that searches user identifiers. The following tokens can be used in the filter string: diff -Nrub --exclude debian --exclude '*~' reference/ptclient/ldap.c editing/ptclient/ldap.c --- reference/ptclient/ldap.c 2008-10-29 13:08:23.000000000 +0000 +++ editing/ptclient/ldap.c 2009-05-06 13:08:43.000000000 +0100 @@ -63,6 +63,8 @@ /* Functions like ldap_bind() have been deprecated in OpenLDAP 2.3 */ #define LDAP_DEPRECATED 1 +#define LDAP_EXTERNAL_IDS_MAX 256 + #include <ldap.h> #include <lber.h> @@ -165,6 +167,8 @@ const char *group_base; int group_scope; LDAP *ld; + + const char *external_canon_ids[LDAP_EXTERNAL_IDS_MAX]; } t_ptsm; #define PTSM_OK 0 @@ -526,6 +530,30 @@ ptsm->version = LDAP_VERSION3; ptsm->ld = NULL; + + int i=0, j=0, space=1; + p = config_getstring(IMAPOPT_LDAP_EXTERNAL_IDS); + if(p && strlen(p)) + { + /* Pull the identifiers out of the config option + ** and populate the array */ + /* XXX FIXME: This ought to canonify as it goes */ + char *q = NULL; + if(!(q = xstrdup(p))) + fatal("No memory for pts ldap external ids parser", EC_OSERR); + + for(j=0; q[j] && (i<LDAP_EXTERNAL_IDS_MAX); j++) { + if(space && (!isspace(q[j]))) { + space = 0; + ptsm->external_canon_ids[i++] = (q+j); + } + if(isspace(q[j])) { + space = 1; + q[j] = '\0'; + } + } + } + ptsm->external_canon_ids[i]=NULL; } /* @@ -1180,6 +1208,42 @@ return rc; } +static int ptsmodule_make_authstate_external ( + const char *canon_id, + size_t size, + const char **reply, + int *dsize, + struct auth_state **newstate) +{ + syslog(LOG_DEBUG, "pts ldap fake authstate for external id '%s'.", canon_id); + + *dsize = sizeof(struct auth_state); + *newstate = xmalloc(*dsize); + if (*newstate == NULL) { + *reply = "no memory"; + return PTSM_FAIL; + } + + (*newstate)->ngroups = 0; + strcpy((*newstate)->userid.id, canon_id); + (*newstate)->userid.hash = strhash(canon_id); + (*newstate)->mark = time(0); + + return PTSM_OK; +} + +int pts_is_external(const char *canon_id) +{ + int i; + + for( i=0; ptsm->external_canon_ids[i]; i++ ) + if( !strcmp( canon_id, ptsm->external_canon_ids[i] ) ) + return 1; + + return 0; +} + + static struct auth_state *myauthstate( const char *identifier, size_t size, @@ -1204,6 +1268,8 @@ if (!strncmp(canon_id, "group:", 6)) rc = ptsmodule_make_authstate_group(canon_id, size, reply, dsize, &newstate); + else if (pts_is_external(canon_id)) + rc = ptsmodule_make_authstate_external(canon_id, size, reply, dsize, &newstate); else { if (ptsm->member_method == PTSM_MEMBER_METHOD_ATTRIBUTE) rc = ptsmodule_make_authstate_attribute(canon_id, size, reply, dsize, &newstate); diff -Nrub --exclude debian --exclude '*~' reference/ptclient/ptloader.c editing/ptclient/ptloader.c --- reference/ptclient/ptloader.c 2008-10-29 13:08:23.000000000 +0000 +++ editing/ptclient/ptloader.c 2009-05-06 11:21:43.000000000 +0100 @@ -146,7 +146,7 @@ /* set signal handlers */ signal(SIGPIPE, SIG_IGN); - syslog(LOG_NOTICE, "starting: $Id: ptloader.c,v 1.49 2008/09/04 20:44:08 wescraig Exp $"); + syslog(LOG_NOTICE, "starting: ptloader " EXTRA_IDENT ); while ((opt = getopt(argc, argv, "d:")) != EOF) { switch (opt) {
---- Cyrus Home Page: http://cyrusimap.web.cmu.edu/ Cyrus Wiki/FAQ: http://cyrusimap.web.cmu.edu/twiki List Archives/Info: http://asg.web.cmu.edu/cyrus/mailing-list.html