📄 rlm_ldap.c
字号:
if ((conn_id = ldap_get_conn(inst->conns,&conn,inst)) == -1){ radlog(L_ERR, "rlm_ldap: All ldap connections are in use"); return RLM_MODULE_FAIL; } if ((res = perform_search(instance, conn, basedn, LDAP_SCOPE_SUBTREE, filter, inst->atts, &result)) != RLM_MODULE_OK) { DEBUG("rlm_ldap: search failed"); if (res == RLM_MODULE_NOTFOUND){ snprintf(module_fmsg,sizeof(module_fmsg),"rlm_ldap: User not found"); module_fmsg_vp = pairmake("Module-Failure-Message", module_fmsg, T_OP_EQ); pairadd(&request->packet->vps, module_fmsg_vp); } ldap_release_conn(conn_id,inst->conns); return (res); } if ((msg = ldap_first_entry(conn->ld, result)) == NULL) { DEBUG("rlm_ldap: ldap_first_entry() failed"); ldap_msgfree(result); ldap_release_conn(conn_id,inst->conns); return RLM_MODULE_FAIL; } if ((user_dn = ldap_get_dn(conn->ld, msg)) == NULL) { DEBUG("rlm_ldap: ldap_get_dn() failed"); ldap_msgfree(result); ldap_release_conn(conn_id,inst->conns); return RLM_MODULE_FAIL; } /* * Adding new attribute containing DN for LDAP object associated with * given username */ pairadd(check_pairs, pairmake("Ldap-UserDn", user_dn, T_OP_EQ)); ldap_memfree(user_dn); /* Remote access is controled by attribute of the user object */ if (inst->access_attr) { if ((vals = ldap_get_values(conn->ld, msg, inst->access_attr)) != NULL) { if (inst->default_allow){ DEBUG("rlm_ldap: checking if remote access for %s is allowed by %s", request->username->vp_strvalue, inst->access_attr); if (!strncmp(vals[0], "FALSE", 5)) { DEBUG("rlm_ldap: dialup access disabled"); snprintf(module_fmsg,sizeof(module_fmsg),"rlm_ldap: Access Attribute denies access"); module_fmsg_vp = pairmake("Module-Failure-Message", module_fmsg, T_OP_EQ); pairadd(&request->packet->vps, module_fmsg_vp); ldap_msgfree(result); ldap_value_free(vals); ldap_release_conn(conn_id,inst->conns); return RLM_MODULE_USERLOCK; } ldap_value_free(vals); } else{ DEBUG("rlm_ldap: %s attribute exists - access denied by default", inst->access_attr); snprintf(module_fmsg,sizeof(module_fmsg),"rlm_ldap: Access Attribute denies access"); module_fmsg_vp = pairmake("Module-Failure-Message", module_fmsg, T_OP_EQ); pairadd(&request->packet->vps, module_fmsg_vp); ldap_msgfree(result); ldap_value_free(vals); ldap_release_conn(conn_id,inst->conns); return RLM_MODULE_USERLOCK; } } else { if (inst->default_allow){ DEBUG("rlm_ldap: no %s attribute - access denied by default", inst->access_attr); snprintf(module_fmsg,sizeof(module_fmsg),"rlm_ldap: Access Attribute denies access"); module_fmsg_vp = pairmake("Module-Failure-Message", module_fmsg, T_OP_EQ); pairadd(&request->packet->vps, module_fmsg_vp); ldap_msgfree(result); ldap_release_conn(conn_id,inst->conns); return RLM_MODULE_USERLOCK; } } } /* * Check for the default profile entry. If it exists then add the * attributes it contains in the check and reply pairs */ user_profile = pairfind(request->config_items, PW_USER_PROFILE); if (inst->default_profile || user_profile){ char *profile = inst->default_profile; strlcpy(filter,inst->base_filter,sizeof(filter)); if (user_profile) profile = user_profile->vp_strvalue; if (profile && strlen(profile)){ if ((res = perform_search(instance, conn, profile, LDAP_SCOPE_BASE, filter, inst->atts, &def_result)) == RLM_MODULE_OK){ if ((def_msg = ldap_first_entry(conn->ld,def_result))){ if ((check_tmp = ldap_pairget(conn->ld,def_msg,inst->check_item_map,check_pairs,1))) { if (inst->do_xlat){ pairxlatmove(request, check_pairs, &check_tmp); pairfree(&check_tmp); } else pairadd(check_pairs,check_tmp); } if ((reply_tmp = ldap_pairget(conn->ld,def_msg,inst->reply_item_map,reply_pairs,0))) { if (inst->do_xlat){ pairxlatmove(request, reply_pairs, &reply_tmp); pairfree(&reply_tmp); } else pairadd(reply_pairs,reply_tmp); } } ldap_msgfree(def_result); } else DEBUG("rlm_ldap: default_profile/user-profile search failed"); } } /* * Check for the profile attribute. If it exists, we assume that it * contains the DN of an entry containg a profile for the user. That * way we can have different general profiles for various user groups * (students,faculty,staff etc) */ if (inst->profile_attr){ if ((vals = ldap_get_values(conn->ld, msg, inst->profile_attr)) != NULL) { unsigned int i=0; strlcpy(filter,inst->base_filter,sizeof(filter)); while(vals[i] != NULL && strlen(vals[i])){ if ((res = perform_search(instance, conn, vals[i], LDAP_SCOPE_BASE, filter, inst->atts, &def_attr_result)) == RLM_MODULE_OK){ if ((def_attr_msg = ldap_first_entry(conn->ld,def_attr_result))){ if ((check_tmp = ldap_pairget(conn->ld,def_attr_msg,inst->check_item_map,check_pairs,1))) { if (inst->do_xlat){ pairxlatmove(request, check_pairs, &check_tmp); pairfree(&check_tmp); } else pairadd(check_pairs,check_tmp); } if ((reply_tmp = ldap_pairget(conn->ld,def_attr_msg,inst->reply_item_map,reply_pairs,0))) { if (inst->do_xlat){ pairxlatmove(request, reply_pairs, &reply_tmp); pairfree(&reply_tmp); } else pairadd(reply_pairs,reply_tmp); } } ldap_msgfree(def_attr_result); } else DEBUG("rlm_ldap: profile_attribute search failed"); i++; } ldap_value_free(vals); } } if (inst->passwd_attr && strlen(inst->passwd_attr)) {#ifdef NOVELL_UNIVERSAL_PASSWORD if (strcasecmp(inst->passwd_attr,"nspmPassword") != 0) {#endif VALUE_PAIR *passwd_item; char **passwd_vals; char *value = NULL; int i; /* * Read the password from the DB, and * add it to the request. */ passwd_vals = ldap_get_values(conn->ld,msg, inst->passwd_attr); /* * Loop over what we received, and parse it. */ if (passwd_vals) for (i = 0; passwd_vals[i] != NULL; i++) { int attr = PW_USER_PASSWORD; if (strlen(passwd_vals[i]) == 0) continue; value = passwd_vals[i]; if (inst->auto_header) { char *p; char autobuf[16]; p = strchr(value, '}'); if (!p) continue; if ((size_t)(p - value + 1) >= sizeof(autobuf)) continue; /* paranoia */ memcpy(autobuf, value, p - value + 1); autobuf[p - value + 1] = '\0'; attr = fr_str2int(header_names, autobuf, 0); if (!attr) continue; value = p + 1; goto create_attr; } else if (inst->passwd_hdr && strlen(inst->passwd_hdr)) { if (strncasecmp(value, inst->passwd_hdr, strlen(inst->passwd_hdr)) == 0) { value += strlen(inst->passwd_hdr); } else { DEBUG("rlm_ldap: Password header not found in password %s for user %s", passwd_vals[0], request->username->vp_strvalue); } } if (!value) continue; create_attr: passwd_item = radius_paircreate(request, &request->config_items, attr, PW_TYPE_STRING); strlcpy(passwd_item->vp_strvalue, value, sizeof(passwd_item->vp_strvalue)); passwd_item->length = strlen(passwd_item->vp_strvalue); DEBUG("rlm_ldap: Added %s = %s in check items", passwd_item->name, passwd_item->vp_strvalue); added_known_password = 1; } ldap_value_free(passwd_vals);#ifdef NOVELL_UNIVERSAL_PASSWORD } else{ /* * Read Universal Password from eDirectory */ VALUE_PAIR *passwd_item; VALUE_PAIR *vp_user_dn; char *universal_password = NULL; size_t universal_password_len = UNIVERSAL_PASS_LEN; char *passwd_val = NULL; res = 0; if ((passwd_item = pairfind(request->config_items, PW_CLEARTEXT_PASSWORD)) == NULL){ universal_password = rad_malloc(universal_password_len); memset(universal_password, 0, universal_password_len); vp_user_dn = pairfind(request->config_items,PW_LDAP_USERDN); res = nmasldap_get_password(conn->ld,vp_user_dn->vp_strvalue,&universal_password_len,universal_password); if (res == 0){ passwd_val = universal_password; if (inst->passwd_hdr && strlen(inst->passwd_hdr)){ passwd_val = strstr(passwd_val,inst->passwd_hdr); if (passwd_val != NULL) passwd_val += strlen((char*)inst->passwd_hdr); else DEBUG("rlm_ldap: Password header not found in password %s for user %s ",passwd_val,request->username->vp_strvalue); } if (passwd_val){ passwd_item = radius_paircreate(request, &request->config_items, PW_CLEARTEXT_PASSWORD, PW_TYPE_STRING); strlcpy(passwd_item->vp_strvalue,passwd_val,sizeof(passwd_item->vp_strvalue)); passwd_item->length = strlen(passwd_item->vp_strvalue); added_known_password = 1;#ifdef NOVELL { DICT_ATTR *dattr; VALUE_PAIR *vp_inst, *vp_apc; int inst_attr, apc_attr; dattr = dict_attrbyname("LDAP-Instance"); inst_attr = dattr->attr; dattr = dict_attrbyname("eDir-APC"); apc_attr = dattr->attr; vp_inst = pairfind(request->config_items, inst_attr); if(vp_inst == NULL){ /* * The authorize method of no other LDAP module instance has * processed this request. */ vp_inst = radius_paircreate(request, &request->config_items, inst_attr, PW_TYPE_STRING); strlcpy(vp_inst->vp_strvalue, inst->xlat_name, sizeof(vp_inst->vp_strvalue)); vp_inst->length = strlen(vp_inst->vp_strvalue); /* * Inform the authenticate / post-auth method about the presence * of UP in the config items list and whether eDirectory account * policy check is to be performed or not. */ vp_apc = radius_paircreate(request, &request->config_items, apc_attr, PW_TYPE_STRING); if(!inst->edir_account_policy_check){ /* Do nothing */ strcpy(vp_apc->vp_strvalue, "1"); }else{ /* Perform eDirectory account-policy check */ strcpy(vp_apc->vp_strvalue, "2"); } vp_apc->length = 1; } }#endif DEBUG("rlm_ldap: Added the eDirectory password %s in check items as %s",passwd_item->vp_strvalue,passwd_item->name); } } else { DEBUG("rlm_ldap: Error reading Universal Password.Return Code = %d",res); } memset(universal_password, 0, universal_password_len); free(universal_password); } }#endif }#ifdef NOVELL { VALUE_PAIR *vp_auth_opt; DICT_ATTR *dattr; char **auth_option; int auth_opt_attr; dattr = dict_attrbyname("eDir-Auth-Option"); auth_opt_attr = dattr->attr; if(pairfind(*check_pairs, auth_opt_attr) == NULL){ if ((auth_option = ldap_get_values(conn->ld, msg, "sasDefaultLoginSequence")) != NULL) { if ((vp_auth_opt = paircreate(auth_opt_attr, PW_TYPE_STRING)) == NULL){ radlog(L_ERR, "rlm_ldap: Could not allocate memory. Aborting."); ldap_msgfree(result); ldap_release_conn(conn_id, inst->conns); } strcpy(vp_auth_opt->vp_strvalue, auth_option[0]); vp_auth_opt->length = strlen(auth_option[0]); pairadd(&request->config_items, vp_auth_opt); }else{ DEBUG("rlm_ldap: No default NMAS login sequence"); } } }#endif DEBUG("rlm_ldap: looking for check items in directory..."); if ((check_tmp = ldap_pairget(conn->ld, msg, inst->check_item_map,check_pairs,1)) != NULL) { if (inst->do_xlat){ pairxlatmove(request, check_pairs, &check_tmp); pairfree(&check_tmp); } else pairadd(check_pairs,check_tmp); } DEBUG("rlm_ldap: looking for reply items in directory..."); if ((reply_tmp = ldap_pairget(conn->ld, msg, inst->reply_item_map,reply_pairs,0)) != NULL) { if (inst->do_xlat){ pairxlatmove(request, reply_pairs, &reply_tmp); pairfree(&reply_tmp); } else pairadd(reply_pairs,reply_tmp); } if (inst->do_comp && paircompare(request,request->packet->vps,*check_pairs,reply_pairs) != 0){#ifdef NOVELL /* Don't perform eDirectory APC if RADIUS authorize fails */ int apc_attr; VALUE_PAIR *vp_apc; DICT_ATTR *dattr; dattr = dict_attrbyname("eDir-APC"); apc_attr = dattr->attr; vp_apc = pairfind(request->config_items, apc_attr); if(vp_apc) vp_apc->vp_strvalue[0] = '1';#endif DEBUG("rlm_ldap: Pairs do not match. Rejecting user."); snprintf(module_fmsg,sizeof(module_fmsg),"rlm_ldap: Pairs do not match"); module_fmsg_vp = pairmake("Module-Failure-Message", module_fmsg, T_OP_EQ); pairadd(&request->packet->vps, module_fmsg_vp); ldap_msgfree(result); ldap_release_conn(conn_id,inst->conns); return RLM_MODULE_REJECT; } /* * More warning messages for people who can't be bothered * to read the documentation. */ if (debug_flag > 1) { if (!pairfind(request->config_items, PW_CLEARTEXT_PASSWORD) && !pairfind(request->config_items, PW_USER_PASSWORD)) { DEBUG("WARNING: No \"known good\" password was found in LDAP. Are you sure that the user is configured correctly?"); } } /* * Module should default to LDAP authentication if no Auth-Type * specified. Note that we do this ONLY if configured, AND we * set the Auth-Type to our module name, which allows multiple * ldap instances to work. */ if (inst->set_auth_type && (pairfind(*check_pairs, PW_AUTH_TYPE) == NULL) && request->password && (request->password->attribute == PW_USER_PASSWORD) && !added_known_password) { pairadd(check_pairs, pairmake("Auth-Type", inst->xlat_name, T_OP_EQ)); DEBUG("rlm_ldap: Setting Auth-Type = %s", inst->xlat_name); } DEBUG("rlm_ldap: user %s authorized to use remote access", request->username->vp_strvalue); ldap_msgfree(result); ldap_release_conn(conn_id,inst->conns); return RLM_MODULE_OK;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -