Re: Authorization with ptloader: Linux and LDAP backend combined

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



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

[Index of Archives]     [Cyrus SASL]     [Squirrel Mail]     [Asterisk PBX]     [Video For Linux]     [Photo]     [Yosemite News]     [gtk]     [KDE]     [Gimp on Windows]     [Steve's Art]

  Powered by Linux