📄 mod_auth_ldap.c
字号:
if (result == LDAP_SERVER_DOWN) { if (failures++ <= 5) { goto start_over; } } /* handle bind failure */ if (result != LDAP_SUCCESS) { ap_log_rerror(APLOG_MARK, APLOG_WARNING|APLOG_NOERRNO, 0, r, "[%d] auth_ldap authenticate: " "user %s authentication failed; URI %s [%s][%s]", getpid(), r->user, r->uri, ldc->reason, ldap_err2string(result)); if ((LDAP_INVALID_CREDENTIALS == result) || sec->auth_authoritative) { ap_note_basic_auth_failure(r); return HTTP_UNAUTHORIZED; } else { return DECLINED; } } /* mark the user and DN */ req->dn = apr_pstrdup(r->pool, dn); req->user = r->user; if (sec->user_is_dn) { r->user = req->dn; } /* add environment variables */ if (sec->attributes && vals) { apr_table_t *e = r->subprocess_env; int i = 0; while (sec->attributes[i]) { char *str = apr_pstrcat(r->pool, "AUTHENTICATE_", sec->attributes[i], NULL); int j = 13; while (str[j]) { if (str[j] >= 'a' && str[j] <= 'z') { str[j] = str[j] - ('a' - 'A'); } j++; } apr_table_setn(e, str, vals[i]); i++; } } ap_log_rerror(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, 0, r, "[%d] auth_ldap authenticate: accepting %s", getpid(), r->user); return OK;}/* * Authorisation Phase * ------------------- * * After checking whether the username and password are correct, we need * to check whether that user is authorised to view this resource. The * require directive is used to do this: * * require valid-user Any authenticated is allowed in. * require user <username> This particular user is allowed in. * require group <groupname> The user must be a member of this group * in order to be allowed in. * require dn <dn> The user must have the following DN in the * LDAP tree to be let in. * */int mod_auth_ldap_auth_checker(request_rec *r){ int result = 0; mod_auth_ldap_request_t *req = (mod_auth_ldap_request_t *)ap_get_module_config(r->request_config, &auth_ldap_module); mod_auth_ldap_config_t *sec = (mod_auth_ldap_config_t *)ap_get_module_config(r->per_dir_config, &auth_ldap_module); util_ldap_connection_t *ldc = NULL; int m = r->method_number; const apr_array_header_t *reqs_arr = ap_requires(r); require_line *reqs = reqs_arr ? (require_line *)reqs_arr->elts : NULL; register int x; const char *t; char *w, *value; int method_restricted = 0; if (!sec->enabled) { return DECLINED; } if (!sec->have_ldap_url) { return DECLINED; } if (sec->host) { ldc = util_ldap_connection_find(r, sec->host, sec->port, sec->binddn, sec->bindpw, sec->deref, sec->secure); apr_pool_cleanup_register(r->pool, ldc, mod_auth_ldap_cleanup_connection_close, apr_pool_cleanup_null); } else { ap_log_rerror(APLOG_MARK, APLOG_WARNING|APLOG_NOERRNO, 0, r, "[%d] auth_ldap authorise: no sec->host - weird...?", getpid()); return sec->auth_authoritative? HTTP_UNAUTHORIZED : DECLINED; } /* * If there are no elements in the group attribute array, the default should be * member and uniquemember; populate the array now. */ if (sec->groupattr->nelts == 0) { struct mod_auth_ldap_groupattr_entry_t *grp;#if APR_HAS_THREADS apr_thread_mutex_lock(sec->lock);#endif grp = apr_array_push(sec->groupattr); grp->name = "member"; grp = apr_array_push(sec->groupattr); grp->name = "uniquemember";#if APR_HAS_THREADS apr_thread_mutex_unlock(sec->lock);#endif } if (!reqs_arr) { ap_log_rerror(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, 0, r, "[%d] auth_ldap authorise: no requirements array", getpid()); return sec->auth_authoritative? HTTP_UNAUTHORIZED : DECLINED; } /* Loop through the requirements array until there's no elements * left, or something causes a return from inside the loop */ for(x=0; x < reqs_arr->nelts; x++) { if (! (reqs[x].method_mask & (1 << m))) { continue; } method_restricted = 1; t = reqs[x].requirement; w = ap_getword_white(r->pool, &t); if (strcmp(w, "valid-user") == 0) { /* * Valid user will always be true if we authenticated with ldap, * but when using front page, valid user should only be true if * he exists in the frontpage password file. This hack will get * auth_ldap to look up the user in the the pw file to really be * sure that he's valid. Naturally, it requires mod_auth to be * compiled in, but if mod_auth wasn't in there, then the need * for this hack wouldn't exist anyway. */ if (sec->frontpage_hack) { ap_log_rerror(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, 0, r, "[%d] auth_ldap authorise: " "deferring authorisation to mod_auth (FP Hack)", getpid()); return OK; } else { ap_log_rerror(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, 0, r, "[%d] auth_ldap authorise: " "successful authorisation because user " "is valid-user", getpid()); return OK; } } else if (strcmp(w, "user") == 0) { if (req->dn == NULL || strlen(req->dn) == 0) { ap_log_rerror(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, 0, r, "[%d] auth_ldap authorise: " "require user: user's DN has not been defined; failing authorisation", getpid()); return sec->auth_authoritative? HTTP_UNAUTHORIZED : DECLINED; } /* * First do a whole-line compare, in case it's something like * require user Babs Jensen */ result = util_ldap_cache_compare(r, ldc, sec->url, req->dn, sec->attribute, t); switch(result) { case LDAP_COMPARE_TRUE: { ap_log_rerror(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, 0, r, "[%d] auth_ldap authorise: " "require user: authorisation successful", getpid()); return OK; } default: { ap_log_rerror(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, 0, r, "[%d] auth_ldap authorise: require user: " "authorisation failed [%s][%s]", getpid(), ldc->reason, ldap_err2string(result)); } } /* * Now break apart the line and compare each word on it */ while (t[0]) { w = ap_getword_conf(r->pool, &t); result = util_ldap_cache_compare(r, ldc, sec->url, req->dn, sec->attribute, w); switch(result) { case LDAP_COMPARE_TRUE: { ap_log_rerror(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, 0, r, "[%d] auth_ldap authorise: " "require user: authorisation successful", getpid()); return OK; } default: { ap_log_rerror(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, 0, r, "[%d] auth_ldap authorise: " "require user: authorisation failed [%s][%s]", getpid(), ldc->reason, ldap_err2string(result)); } } } } else if (strcmp(w, "dn") == 0) { if (req->dn == NULL || strlen(req->dn) == 0) { ap_log_rerror(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, 0, r, "[%d] auth_ldap authorise: " "require dn: user's DN has not been defined; failing authorisation", getpid()); return sec->auth_authoritative? HTTP_UNAUTHORIZED : DECLINED; } result = util_ldap_cache_comparedn(r, ldc, sec->url, req->dn, t, sec->compare_dn_on_server); switch(result) { case LDAP_COMPARE_TRUE: { ap_log_rerror(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, 0, r, "[%d] auth_ldap authorise: " "require dn: authorisation successful", getpid()); return OK; } default: { ap_log_rerror(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, 0, r, "[%d] auth_ldap authorise: " "require dn \"%s\": LDAP error [%s][%s]", getpid(), t, ldc->reason, ldap_err2string(result)); } } } else if (strcmp(w, "group") == 0) { struct mod_auth_ldap_groupattr_entry_t *ent = (struct mod_auth_ldap_groupattr_entry_t *) sec->groupattr->elts; int i; if (sec->group_attrib_is_dn) { if (req->dn == NULL || strlen(req->dn) == 0) { ap_log_rerror(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, 0, r, "[%d] auth_ldap authorise: require group: user's DN has not been defined; failing authorisation", getpid()); return sec->auth_authoritative? HTTP_UNAUTHORIZED : DECLINED; } } else { if (req->user == NULL || strlen(req->user) == 0) { /* We weren't called in the authentication phase, so we didn't have a * chance to set the user field. Do so now. */ req->user = r->user; } } ap_log_rerror(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, 0, r, "[%d] auth_ldap authorise: require group: testing for group membership in \"%s\"", getpid(), t); for (i = 0; i < sec->groupattr->nelts; i++) { ap_log_rerror(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, 0, r, "[%d] auth_ldap authorise: require group: testing for %s: %s (%s)", getpid(), ent[i].name, sec->group_attrib_is_dn ? req->dn : req->user, t); result = util_ldap_cache_compare(r, ldc, sec->url, t, ent[i].name, sec->group_attrib_is_dn ? req->dn : req->user); switch(result) { case LDAP_COMPARE_TRUE: { ap_log_rerror(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, 0, r, "[%d] auth_ldap authorise: require group: " "authorisation successful (attribute %s) [%s][%s]", getpid(), ent[i].name, ldc->reason, ldap_err2string(result)); return OK; } default: { ap_log_rerror(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, 0, r, "[%d] auth_ldap authorise: require group \"%s\": " "authorisation failed [%s][%s]", getpid(), t, ldc->reason, ldap_err2string(result)); } } } } else if (strcmp(w, "ldap-attribute") == 0) { while (t[0]) { w = ap_getword(r->pool, &t, '='); value = ap_getword_conf(r->pool, &t); ap_log_rerror(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, 0, r, "[%d] auth_ldap authorise: checking attribute" " %s has value %s", getpid(), w, value); result = util_ldap_cache_compare(r, ldc, sec->url, req->dn, w, value); switch(result) { case LDAP_COMPARE_TRUE: { ap_log_rerror(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, 0, r, "[%d] auth_ldap authorise: " "require attribute: authorisation " "successful", getpid()); return OK; } default: { ap_log_rerror(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, 0, r, "[%d] auth_ldap authorise: " "require attribute: authorisation " "failed [%s][%s]", getpid(), ldc->reason, ldap_err2string(result)); } } } } } if (!method_restricted) { ap_log_rerror(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, 0, r, "[%d] auth_ldap authorise: agreeing because non-restricted", getpid()); return OK; } if (!sec->auth_authoritative) { ap_log_rerror(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, 0, r, "[%d] auth_ldap authorise: declining to authorise", getpid()); return DECLINED; } ap_log_rerror(APLOG_MARK, APLOG_DEBUG|APLOG_NOERRNO, 0, r, "[%d] auth_ldap authorise: authorisation denied", getpid()); ap_note_basic_auth_failure (r); return HTTP_UNAUTHORIZED;}/* ---------------------------------------- *//* config directives */void *mod_auth_ldap_create_dir_config(apr_pool_t *p, char *d){ mod_auth_ldap_config_t *sec = (mod_auth_ldap_config_t *)apr_pcalloc(p, sizeof(mod_auth_ldap_config_t)); sec->pool = p;#if APR_HAS_THREADS apr_thread_mutex_create(&sec->lock, APR_THREAD_MUTEX_DEFAULT, p);#endif sec->auth_authoritative = 1; sec->enabled = 1; sec->groupattr = apr_array_make(p, GROUPATTR_MAX_ELTS, sizeof(struct mod_auth_ldap_groupattr_entry_t)); sec->have_ldap_url = 0;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -