From: Art Cancro Date: Fri, 10 Apr 2009 10:33:49 +0000 (+0000) Subject: * Added a separate authentication mode AUTHMODE_LDAP_AD for Active Directory's nonsta... X-Git-Tag: v7.86~1289 X-Git-Url: https://code.citadel.org/?p=citadel.git;a=commitdiff_plain;h=7dd4c13ad3f294c87ceff8f09ded051fe3bd328f * Added a separate authentication mode AUTHMODE_LDAP_AD for Active Directory's nonstandard schema (shares a lot of code with AUTHMODE_LDAP) --- diff --git a/citadel/citadel.h b/citadel/citadel.h index 92dfc5f6e..a078851dd 100644 --- a/citadel/citadel.h +++ b/citadel/citadel.h @@ -41,7 +41,7 @@ extern "C" { #define REV_LEVEL 760 /* This version */ #define REV_MIN 591 /* Oldest compatible database */ #define EXPORT_REV_MIN 760 /* Oldest compatible export files */ -#define LIBCITADEL_MIN 744 /* Minimum required version of libcitadel */ +#define LIBCITADEL_MIN 760 /* Minimum required version of libcitadel */ #define SERVER_TYPE 0 /* zero for stock Citadel; other developers please obtain SERVER_TYPE codes for your implementations */ @@ -278,7 +278,8 @@ enum { */ #define AUTHMODE_NATIVE 0 /* Native (self-contained or "black box") */ #define AUTHMODE_HOST 1 /* Authenticate against the host OS user database */ -#define AUTHMODE_LDAP 2 /* Authenticate against an LDAP server */ +#define AUTHMODE_LDAP 2 /* Authenticate against an LDAP server with RFC 2307 schema */ +#define AUTHMODE_LDAP_AD 3 /* Authenticate against non-standard MS Active Directory LDAP */ #ifdef __cplusplus } diff --git a/citadel/citadel_ldap.h b/citadel/citadel_ldap.h index 41cae48ea..66f28a2d6 100644 --- a/citadel/citadel_ldap.h +++ b/citadel/citadel_ldap.h @@ -2,7 +2,5 @@ * Configuration for LDAP authentication. Most of this stuff gets pulled out of our site config file. */ -#define SEARCH_STRING "(&(objectclass=posixAccount)(uid=%s))" - int CtdlTryUserLDAP(char *username, char *found_dn, int found_dn_size, char *fullname, int fullname_size, uid_t *found_uid); int CtdlTryPasswordLDAP(char *user_dn, char *password); diff --git a/citadel/config.c b/citadel/config.c index b33e04142..c6565b35d 100644 --- a/citadel/config.c +++ b/citadel/config.c @@ -80,7 +80,7 @@ void get_config(void) { /* Only allow LDAP auth mode if we actually have LDAP support */ #ifndef HAVE_LDAP - if (config.c_auth_mode == AUTHMODE_LDAP) { + if ((config.c_auth_mode == AUTHMODE_LDAP) || (config.c_auth_mode == AUTHMODE_LDAP_AD)) { fprintf(stderr, "Your system is configured for LDAP authentication,\n" "but you are running a server built without OpenLDAP support.\n"); exit(CTDL_EXIT_UNSUP_AUTH); diff --git a/citadel/ldap.c b/citadel/ldap.c index 06f894f7d..7a93098e5 100644 --- a/citadel/ldap.c +++ b/citadel/ldap.c @@ -99,7 +99,12 @@ int CtdlTryUserLDAP(char *username, tv.tv_sec = 10; tv.tv_usec = 0; - sprintf(searchstring, SEARCH_STRING, username); + if (config.c_auth_mode == AUTHMODE_LDAP_AD) { + sprintf(searchstring, "(sAMAccountName=%s)", username); + } + else { + sprintf(searchstring, "(&(objectclass=posixAccount)(uid=%s))", username); + } i = ldap_search_st(ldserver, config.c_ldap_base_dn, @@ -134,32 +139,50 @@ int CtdlTryUserLDAP(char *username, CtdlLogPrintf(CTDL_DEBUG, "dn = %s\n", user_dn); } - values = ldap_get_values(ldserver, search_result, "cn"); - if (values) { - if (values[0]) { - if (fullname) safestrncpy(fullname, values[0], fullname_size); - CtdlLogPrintf(CTDL_DEBUG, "cn = %s\n", values[0]); + if (config.c_auth_mode == AUTHMODE_LDAP_AD) { + values = ldap_get_values(ldserver, search_result, "displayName"); + if (values) { + if (values[0]) { + if (fullname) safestrncpy(fullname, values[0], fullname_size); + CtdlLogPrintf(CTDL_DEBUG, "displayName = %s\n", values[0]); + } + ldap_value_free(values); } - ldap_value_free(values); } - - values = ldap_get_values(ldserver, search_result, "uidNumber"); - if (values) { - if (values[0]) { - CtdlLogPrintf(CTDL_DEBUG, "uidNumber = %s\n", values[0]); - if (uid != NULL) { - *uid = atoi(values[0]); + else { + values = ldap_get_values(ldserver, search_result, "cn"); + if (values) { + if (values[0]) { + if (fullname) safestrncpy(fullname, values[0], fullname_size); + CtdlLogPrintf(CTDL_DEBUG, "cn = %s\n", values[0]); } + ldap_value_free(values); } - ldap_value_free(values); } - values = ldap_get_values(ldserver, search_result, "objectGUID"); - if (values) { - if (values[0]) { - CtdlLogPrintf(CTDL_DEBUG, "objectGUID = (%d characers)\n", strlen(values[0])); + if (config.c_auth_mode == AUTHMODE_LDAP_AD) { + values = ldap_get_values(ldserver, search_result, "objectGUID"); + if (values) { + if (values[0]) { + if (uid != NULL) { + *uid = abs(HashLittle(values[0], strlen(values[0]))); + CtdlLogPrintf(CTDL_DEBUG, "uid hashed from objectGUID = %d\n", *uid); + } + } + ldap_value_free(values); + } + } + else { + values = ldap_get_values(ldserver, search_result, "uidNumber"); + if (values) { + if (values[0]) { + CtdlLogPrintf(CTDL_DEBUG, "uidNumber = %s\n", values[0]); + if (uid != NULL) { + *uid = atoi(values[0]); + } + } + ldap_value_free(values); } - ldap_value_free(values); } } diff --git a/citadel/setup.c b/citadel/setup.c index 5a491dad8..e72c6d476 100644 --- a/citadel/setup.c +++ b/citadel/setup.c @@ -144,7 +144,9 @@ char *setup_text[] = { "\n" " 1. Authenticate users against the host system (unix or linux accounts)\n" "\n" -" 2. Authenticate users against an external LDAP directory\n" +" 2. Authenticate users against an external LDAP directory (RFC 2307 compliant)\n" +"\n" +" 3. Authenticate users against nonstandard MS Active Directory LDAP\n" "\n" "WARNING: do *not* change this setting once your system is installed.\n" "\n" @@ -1309,7 +1311,9 @@ int main(int argc, char *argv[]) /* Go through a series of dialogs prompting for config info */ for (curr = 1; curr <= MAXSETUP; ++curr) { edit_value(curr); - if ((curr == 6) && (config.c_auth_mode != AUTHMODE_LDAP)) curr += 5; /* skip LDAP questions */ + if ((curr == 6) && (config.c_auth_mode != AUTHMODE_LDAP) && (config.c_auth_mode != AUTHMODE_LDAP_AD)) { + curr += 5; /* skip LDAP questions if we're not authenticating against LDAP */ + } } /***** begin version update section ***** */ diff --git a/citadel/user_ops.c b/citadel/user_ops.c index 2ea53478c..bb803982a 100644 --- a/citadel/user_ops.c +++ b/citadel/user_ops.c @@ -543,7 +543,7 @@ int CtdlLoginExistingUser(char *authname, char *trythisname) } #ifdef HAVE_LDAP - else if (config.c_auth_mode == AUTHMODE_LDAP) { + else if ((config.c_auth_mode == AUTHMODE_LDAP) || (config.c_auth_mode == AUTHMODE_LDAP_AD)) { /* LDAP auth mode */ @@ -890,7 +890,7 @@ int CtdlTryPassword(char *password) } #ifdef HAVE_LDAP - else if (config.c_auth_mode == AUTHMODE_LDAP) { + else if ((config.c_auth_mode == AUTHMODE_LDAP) || (config.c_auth_mode == AUTHMODE_LDAP_AD)) { /* LDAP auth mode */ @@ -1112,7 +1112,7 @@ int create_user(char *newusername, int become_user) } #ifdef HAVE_LDAP - if (config.c_auth_mode == AUTHMODE_LDAP) { + if ((config.c_auth_mode == AUTHMODE_LDAP) || (config.c_auth_mode == AUTHMODE_LDAP_AD)) { if (CtdlTryUserLDAP(username, NULL, 0, username, sizeof username, &uid) != 0) { return(ERROR + NO_SUCH_USER); }