From 0ef82b0123a7800402c9085353aafbd8a49a8fde Mon Sep 17 00:00:00 2001 From: Mark Reynolds Date: Sep 02 2014 19:58:53 +0000 Subject: Ticket 47850 - "nsslapd-allow-anonymous-access: rootdse" makes login as "admin" fail at the first time Bug Description: If anonymous bind access is restricted, console logins using just the RDN fails. This is becuase the console does anonymous searches to find the real user. Fix Description: Added new config parameters to adm.conf to specfiy a bind DN and password that is only used to search for users. This "authentication" user should reside in o=netscaperoot, and have access permissions to search the "config" database and the "users" database. https://fedorahosted.org/389/ticket/47850 Reviewed by: rmeggins(Thanks!) --- diff --git a/mod_admserv/mod_admserv.c b/mod_admserv/mod_admserv.c index 420e36b..3fc19ff 100644 --- a/mod_admserv/mod_admserv.c +++ b/mod_admserv/mod_admserv.c @@ -1221,7 +1221,7 @@ static int update_admpwd(char *admroot, char *newuid, char *newpw); /* * Miodrag (06-15-98) - * The following metthod is called from the runtime command + * The following method is called from the runtime command * "change_sie_password" after the sie password is changed * * Return value: if successful, 1; otherwise, 0 is returned. @@ -2731,6 +2731,7 @@ static int userauth(request_rec *r) static int authenticate_user(LdapServerData *data, char *baseDN, char *user, const char *pw, request_rec *r) { + AdmldapInfo info; LDAP *server; char *userdn, *ldapURL; int ldapError = LDAP_SUCCESS; @@ -2751,7 +2752,39 @@ authenticate_user(LdapServerData *data, char *baseDN, char *user, const char *pw * is hopefully adequate to detect a DN... */ if (!strchr(user, '=')) { - /* not a DN, so resolve the DN from the uid */ + /* + * Not a DN, so resolve the DN from the uid. + */ + const char *authdn = NULL; + const char *authpw = NULL; + int error = 0; + + if (!(info = admldapBuildInfoOnly(configdir, &error))) { + ap_log_error(APLOG_MARK, APLOG_CRIT, 0 /* status */, NULL, + "authenticate_user(): unable to create AdmldapInfo (error code = %d)", + error); + return DECLINED; + } + authdn = admldapGetAuthDN(info); + authpw = admldapGetAuthPasswd(info); + + if(authdn && authpw){ + LDAPControl **ctrls = NULL; + /* + * An authentication bind DN and passwd was provided, perform the BIND so + * this DN lookup is not using an anonymous search (as anonymous access + * could be restricted on the DS side which would break the console). + */ + ldapError = util_ldap_bind(server, authdn, authpw, + LDAP_SASL_SIMPLE, NULL, &ctrls, NULL, NULL); + + if (ldapError) { + ap_log_error(APLOG_MARK, APLOG_ERR, 0 /* status */, NULL, + "authenticate_user: Could not bind as [%s]: ldap error %d: %s", + authdn, ldapError, ldap_err2string(ldapError)); + return DECLINED; + } + } tries = 0; do { @@ -2763,7 +2796,7 @@ authenticate_user(LdapServerData *data, char *baseDN, char *user, const char *pw closeLDAPConnection(server); if(!(server = openLDAPConnection(data))) { ap_log_rerror(APLOG_MARK, APLOG_NOTICE|APLOG_NOERRNO, 0, r, - "unable to find user [%s] in server [%s:%d] under base DN [%s]", + "authenticate_user: unable to find user [%s] in server [%s:%d] under base DN [%s]", user, data->host, data->port, data->baseDN ? data->baseDN : baseDN); return DECLINED; } @@ -2775,6 +2808,12 @@ authenticate_user(LdapServerData *data, char *baseDN, char *user, const char *pw if ((ldapError == LDAP_CONNECT_ERROR) || (ldapError == LDAP_SERVER_DOWN)) return check_auth_users_cache(user, pw, r, 0); /* DS down. Use the cache, ignoring entry expiration. */ + if(ldapError == LDAP_INAPPROPRIATE_AUTH){ + ap_log_error(APLOG_MARK, APLOG_ERR, 0 /* status */, NULL, + "authenticate_user: anonymous access is probably disabled, try setting " + "\"authdn\" and \"authpw\" in adm.conf"); + } + return DECLINED; /* fall back to final check against admpw */ } } else {