⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 util_ldap.c

📁 linux网络服务器工具
💻 C
📖 第 1 页 / 共 5 页
字号:
        /* too many failures */        return result;    }    if (LDAP_SUCCESS != (result = uldap_connection_open(r, ldc))) {        /* connect failed */        return result;    }    result = ldap_compare_s(ldc->ldap,                            (char *)dn,                            (char *)attrib,                            (char *)value);    if (AP_LDAP_IS_SERVER_DOWN(result)) {         /* connection failed - try again */        ldc->reason = "ldap_compare_s() failed with server down";        uldap_connection_unbind(ldc);        goto start_over;    }    ldc->reason = "Comparison complete";    if ((LDAP_COMPARE_TRUE == result) ||        (LDAP_COMPARE_FALSE == result) ||        (LDAP_NO_SUCH_ATTRIBUTE == result)) {        if (curl) {            /* compare completed; caching result */            LDAP_CACHE_LOCK();            the_compare_node.lastcompare = curtime;            the_compare_node.result = result;            /* If the node doesn't exist then insert it, otherwise just update             * it with the last results             */            compare_nodep = util_ald_cache_fetch(curl->compare_cache,                                                 &the_compare_node);            if (   (compare_nodep == NULL)                || (strcmp(the_compare_node.dn, compare_nodep->dn) != 0)                || (strcmp(the_compare_node.attrib,compare_nodep->attrib) != 0)                || (strcmp(the_compare_node.value, compare_nodep->value) != 0))            {                util_ald_cache_insert(curl->compare_cache, &the_compare_node);            }            else {                compare_nodep->lastcompare = curtime;                compare_nodep->result = result;            }            LDAP_CACHE_UNLOCK();        }        if (LDAP_COMPARE_TRUE == result) {            ldc->reason = "Comparison true (adding to cache)";            return LDAP_COMPARE_TRUE;        }        else if (LDAP_COMPARE_FALSE == result) {            ldc->reason = "Comparison false (adding to cache)";            return LDAP_COMPARE_FALSE;        }        else {            ldc->reason = "Comparison no such attribute (adding to cache)";            return LDAP_NO_SUCH_ATTRIBUTE;        }    }    return result;}static int uldap_cache_checkuserid(request_rec *r, util_ldap_connection_t *ldc,                                   const char *url, const char *basedn,                                   int scope, char **attrs, const char *filter,                                   const char *bindpw, const char **binddn,                                   const char ***retvals){    const char **vals = NULL;    int numvals = 0;    int result = 0;    LDAPMessage *res, *entry;    char *dn;    int count;    int failures = 0;    util_url_node_t *curl;              /* Cached URL node */    util_url_node_t curnode;    util_search_node_t *search_nodep;   /* Cached search node */    util_search_node_t the_search_node;    apr_time_t curtime;    util_ldap_state_t *st =        (util_ldap_state_t *)ap_get_module_config(r->server->module_config,        &ldap_module);    /* Get the cache node for this url */    LDAP_CACHE_LOCK();    curnode.url = url;    curl = (util_url_node_t *)util_ald_cache_fetch(st->util_ldap_cache,                                                   &curnode);    if (curl == NULL) {        curl = util_ald_create_caches(st, url);    }    LDAP_CACHE_UNLOCK();    if (curl) {        LDAP_CACHE_LOCK();        the_search_node.username = filter;        search_nodep = util_ald_cache_fetch(curl->search_cache,                                            &the_search_node);        if (search_nodep != NULL) {            /* found entry in search cache... */            curtime = apr_time_now();            /*             * Remove this item from the cache if its expired. If the sent             * password doesn't match the storepassword, the entry will             * be removed and readded later if the credentials pass             * authentication.             */            if ((curtime - search_nodep->lastbind) > st->search_cache_ttl) {                /* ...but entry is too old */                util_ald_cache_remove(curl->search_cache, search_nodep);            }            else if (   (search_nodep->bindpw)                     && (search_nodep->bindpw[0] != '\0')                     && (strcmp(search_nodep->bindpw, bindpw) == 0))            {                /* ...and entry is valid */                *binddn = apr_pstrdup(r->pool, search_nodep->dn);                if (attrs) {                    int i;                    *retvals = apr_pcalloc(r->pool, sizeof(char *) * search_nodep->numvals);                    for (i = 0; i < search_nodep->numvals; i++) {                        (*retvals)[i] = apr_pstrdup(r->pool, search_nodep->vals[i]);                    }                }                LDAP_CACHE_UNLOCK();                ldc->reason = "Authentication successful (cached)";                return LDAP_SUCCESS;            }        }        /* unlock this read lock */        LDAP_CACHE_UNLOCK();    }    /*     * At this point, there is no valid cached search, so lets do the search.     */    /*     * If LDAP operation fails due to LDAP_SERVER_DOWN, control returns here.     */start_over:    if (failures++ > 10) {        return result;    }    if (LDAP_SUCCESS != (result = uldap_connection_open(r, ldc))) {        return result;    }    /* try do the search */    result = ldap_search_ext_s(ldc->ldap,                               (char *)basedn, scope,                               (char *)filter, attrs, 0,                               NULL, NULL, NULL, APR_LDAP_SIZELIMIT, &res);    if (AP_LDAP_IS_SERVER_DOWN(result))    {        ldc->reason = "ldap_search_ext_s() for user failed with server down";        uldap_connection_unbind(ldc);        goto start_over;    }    /* if there is an error (including LDAP_NO_SUCH_OBJECT) return now */    if (result != LDAP_SUCCESS) {        ldc->reason = "ldap_search_ext_s() for user failed";        return result;    }    /*     * We should have found exactly one entry; to find a different     * number is an error.     */    count = ldap_count_entries(ldc->ldap, res);    if (count != 1)    {        if (count == 0 )            ldc->reason = "User not found";        else            ldc->reason = "User is not unique (search found two "                          "or more matches)";        ldap_msgfree(res);        return LDAP_NO_SUCH_OBJECT;    }    entry = ldap_first_entry(ldc->ldap, res);    /* Grab the dn, copy it into the pool, and free it again */    dn = ldap_get_dn(ldc->ldap, entry);    *binddn = apr_pstrdup(r->pool, dn);    ldap_memfree(dn);    /*     * A bind to the server with an empty password always succeeds, so     * we check to ensure that the password is not empty. This implies     * that users who actually do have empty passwords will never be     * able to authenticate with this module. I don't see this as a big     * problem.     */    if (!bindpw || strlen(bindpw) <= 0) {        ldap_msgfree(res);        ldc->reason = "Empty password not allowed";        return LDAP_INVALID_CREDENTIALS;    }    /*     * Attempt to bind with the retrieved dn and the password. If the bind     * fails, it means that the password is wrong (the dn obviously     * exists, since we just retrieved it)     */    result = ldap_simple_bind_s(ldc->ldap,                                (char *)*binddn,                                (char *)bindpw);    if (AP_LDAP_IS_SERVER_DOWN(result)) {        ldc->reason = "ldap_simple_bind_s() to check user credentials "                      "failed with server down";        ldap_msgfree(res);        uldap_connection_unbind(ldc);        goto start_over;    }    /* failure? if so - return */    if (result != LDAP_SUCCESS) {        ldc->reason = "ldap_simple_bind_s() to check user credentials failed";        ldap_msgfree(res);        uldap_connection_unbind(ldc);        return result;    }    else {        /*         * We have just bound the connection to a different user and password         * combination, which might be reused unintentionally next time this         * connection is used from the connection pool. To ensure no confusion,         * we mark the connection as unbound.         */        ldc->bound = 0;    }    /*     * Get values for the provided attributes.     */    if (attrs) {        int k = 0;        int i = 0;        while (attrs[k++]);        vals = apr_pcalloc(r->pool, sizeof(char *) * (k+1));        numvals = k;        while (attrs[i]) {            char **values;            int j = 0;            char *str = NULL;            /* get values */            values = ldap_get_values(ldc->ldap, entry, attrs[i]);            while (values && values[j]) {                str = str ? apr_pstrcat(r->pool, str, "; ", values[j], NULL)                          : apr_pstrdup(r->pool, values[j]);                j++;            }            ldap_value_free(values);            vals[i] = str;            i++;        }        *retvals = vals;    }    /*     * Add the new username to the search cache.     */    if (curl) {        LDAP_CACHE_LOCK();        the_search_node.username = filter;        the_search_node.dn = *binddn;        the_search_node.bindpw = bindpw;        the_search_node.lastbind = apr_time_now();        the_search_node.vals = vals;        the_search_node.numvals = numvals;        /* Search again to make sure that another thread didn't ready insert         * this node into the cache before we got here. If it does exist then         * update the lastbind         */        search_nodep = util_ald_cache_fetch(curl->search_cache,                                            &the_search_node);        if ((search_nodep == NULL) ||            (strcmp(*binddn, search_nodep->dn) != 0)) {            /* Nothing in cache, insert new entry */            util_ald_cache_insert(curl->search_cache, &the_search_node);        }        else if ((!search_nodep->bindpw) ||            (strcmp(bindpw, search_nodep->bindpw) != 0)) {            /* Entry in cache is invalid, remove it and insert new one */            util_ald_cache_remove(curl->search_cache, search_nodep);            util_ald_cache_insert(curl->search_cache, &the_search_node);        }        else {            /* Cache entry is valid, update lastbind */            search_nodep->lastbind = the_search_node.lastbind;        }        LDAP_CACHE_UNLOCK();    }    ldap_msgfree(res);    ldc->reason = "Authentication successful";    return LDAP_SUCCESS;}/* * This function will return the DN of the entry matching userid. * It is used to get the DN in case some other module than mod_auth_ldap * has authenticated the user. * The function is basically a copy of uldap_cache_checkuserid * with password checking removed. */static int uldap_cache_getuserdn(request_rec *r, util_ldap_connection_t *ldc,                                 const char *url, const char *basedn,                                 int scope, char **attrs, const char *filter,                                 const char **binddn, const char ***retvals){    const char **vals = NULL;    int numvals = 0;    int result = 0;    LDAPMessage *res, *entry;    char *dn;    int count;    int failures = 0;    util_url_node_t *curl;              /* Cached URL node */    util_url_node_t curnode;    util_search_node_t *search_nodep;   /* Cached search node */    util_search_node_t the_search_node;    apr_time_t curtime;    util_ldap_state_t *st =        (util_ldap_state_t *)ap_get_module_config(r->server->module_config,        &ldap_module);    /* Get the cache node for this url */    LDAP_CACHE_LOCK();    curnode.url = url;    curl = (util_url_node_t *)util_ald_cache_fetch(st->util_ldap_cache,                                                   &curnode);    if (curl == NULL) {        curl = util_ald_create_caches(st, url);    }    LDAP_CACHE_UNLOCK();    if (curl) {        LDAP_CACHE_LOCK();        the_search_node.username = filter;        search_nodep = util_ald_cache_fetch(curl->search_cache,                                            &the_search_node);        if (search_nodep != NULL) {            /* found entry in search cache... */            curtime = apr_time_now();            /*             * Remove this item from the cache if its expired.             */            if ((curtime - search_nodep->lastbind) > st->search_cache_ttl) {                /* ...but entry is too old */                util_ald_cache_remove(curl->search_cache, search_nodep);            }            else {                /* ...and entry is valid */                *binddn = apr_pstrdup(r->pool, search_nodep->dn);                if (attrs) {                    int i;                    *retvals = apr_pcalloc(r->pool, sizeof(char *) * search_nodep->numvals);                    for (i = 0; i < search_nodep->numvals; i++) {                        (*retvals)[i] = apr_pstrdup(r->pool, search_nodep->vals[i]);                    }                }                LDAP_CACHE_UNLOCK();                ldc->reason = "Search successful (cached)";                return LDAP_SUCCESS;            }        }        /* unlock this read lock */        LDAP_CACHE_UNLOCK();    }    /*     * At this point, there is no valid cached search, so lets do the search.     */    /*     * If LDAP operation fails due to LDAP_SERVER_DOWN, control returns here.     */start_over:    if (failures++ > 10) {        return result;    }    if (LDAP_SUCCESS != (result = uldap_connection_open(r, ldc))) {        return result;    }    /* try do the search */    result = ldap_search_ext_s(ldc->ldap,

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -