📄 rlm_ldap.c
字号:
* * Purpose: Check if user is authorized for remote access * ******************************************************************************/static intldap_authorize(void *instance, REQUEST * request){ LDAPMessage *result = NULL; LDAPMessage *msg = NULL; LDAPMessage *def_msg = NULL; LDAPMessage *def_attr_msg = NULL; LDAPMessage *def_result = NULL; LDAPMessage *def_attr_result = NULL; ldap_instance *inst = instance; char *user_dn = NULL; char filter[MAX_FILTER_STR_LEN]; char basedn[MAX_FILTER_STR_LEN]; VALUE_PAIR *check_tmp; VALUE_PAIR *reply_tmp; int res; VALUE_PAIR **check_pairs, **reply_pairs; char **vals; VALUE_PAIR *module_fmsg_vp; VALUE_PAIR *user_profile; char module_fmsg[MAX_STRING_LEN]; LDAP_CONN *conn; int conn_id = -1; DEBUG("rlm_ldap: - authorize"); if (!request->username){ radlog(L_AUTH, "rlm_ldap: Attribute \"User-Name\" is required for authentication.\n"); return RLM_MODULE_INVALID; } check_pairs = &request->config_items; reply_pairs = &request->reply->vps; /* * Check for valid input, zero length names not permitted */ if (request->username->strvalue == 0) { radlog(L_ERR, "rlm_ldap: zero length username not permitted\n"); return RLM_MODULE_INVALID; } DEBUG("rlm_ldap: performing user authorization for %s", request->username->strvalue); if (!radius_xlat(filter, sizeof(filter), inst->filter, request, ldap_escape_func)) { radlog (L_ERR, "rlm_ldap: unable to create filter.\n"); return RLM_MODULE_INVALID; } if (!radius_xlat(basedn, sizeof(basedn), inst->basedn, request, NULL)) { radlog (L_ERR, "rlm_ldap: unable to create basedn.\n"); return RLM_MODULE_INVALID; } 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(&request->packet->vps, 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->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; strNcpy(filter,inst->base_filter,sizeof(filter)); if (user_profile) profile = user_profile->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; strNcpy(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; if ((passwd_item = pairfind(request->config_items, PW_PASSWORD)) == NULL){ char **passwd_vals; char *passwd_val = NULL; int passwd_len; if ((passwd_vals = ldap_get_values(conn->ld,msg,inst->passwd_attr)) != NULL){ unsigned int i=0; while(passwd_vals[i] != NULL){ if (strlen(passwd_vals[i])){ passwd_val = passwd_vals[i]; if (inst->passwd_hdr && strlen(inst->passwd_hdr)){ passwd_val = strstr(passwd_val,inst->passwd_hdr); if (passwd_val != NULL) passwd_val += strlen(inst->passwd_hdr); else DEBUG("rlm_ldap: Password header not found in password %s for user %s", passwd_vals[0],request->username->strvalue); } if (passwd_val){ if ((passwd_item = paircreate(PW_PASSWORD,PW_TYPE_STRING)) == NULL){ radlog(L_ERR|L_CONS, "no memory"); ldap_value_free(passwd_vals); ldap_msgfree(result); ldap_release_conn(conn_id,inst->conns); return RLM_MODULE_FAIL; } passwd_len = strlen(passwd_val); strncpy(passwd_item->strvalue,passwd_val,MAX_STRING_LEN - 1); passwd_item->length = (passwd_len > (MAX_STRING_LEN - 1)) ? (MAX_STRING_LEN - 1) : passwd_len; pairadd(&request->config_items,passwd_item); DEBUG("rlm_ldap: Added password %s in check items",passwd_item->strvalue); } } i++; } ldap_value_free(passwd_vals); } }#ifdef NOVELL_UNIVERSAL_PASSWORD } else{ /* * Read Universal Password from eDirectory */ VALUE_PAIR *passwd_item; VALUE_PAIR *vp_user_dn; int passwd_len; char *universal_password = NULL; int universal_password_len = UNIVERSAL_PASS_LEN; char *passwd_val = NULL; res = 0; if ((passwd_item = pairfind(request->config_items, PW_PASSWORD)) == NULL){ universal_password = rad_malloc(universal_password_len); memset(universal_password, 0, universal_password_len); vp_user_dn = pairfind(request->packet->vps,PW_LDAP_USERDN); res = nmasldap_get_password(conn->ld,vp_user_dn->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->strvalue); } if (passwd_val){ if ((passwd_item = paircreate(PW_PASSWORD,PW_TYPE_STRING)) == NULL){ radlog(L_ERR, "rlm_ldap: Could not allocate memory. Aborting."); ldap_msgfree(result); ldap_release_conn(conn_id,inst->conns); memset(universal_password, 0, universal_password_len); free(universal_password); return RLM_MODULE_FAIL; } passwd_len = strlen(passwd_val); strncpy(passwd_item->strvalue,passwd_val,MAX_STRING_LEN - 1); passwd_item->length = (passwd_len > (MAX_STRING_LEN - 1)) ? (MAX_STRING_LEN - 1) : passwd_len; pairadd(&request->config_items,passwd_item);#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. */ if ((vp_inst = paircreate(inst_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); memset(universal_password, 0, universal_password_len); free(universal_password); return RLM_MODULE_FAIL; } strcpy(vp_inst->strvalue, inst->xlat_name); vp_inst->length = strlen(vp_inst->strvalue); pairadd(&request->config_items, vp_inst); /* * 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. */ if ((vp_apc = paircreate(apc_attr, PW_TYPE_INTEGER)) == NULL){ radlog(L_ERR, "rlm_ldap: Could not allocate memory. Aborting."); ldap_msgfree(result); ldap_release_conn(conn_id, inst->conns); memset(universal_password, 0, universal_password_len); free(universal_password); return RLM_MODULE_FAIL; } if(!inst->edir_account_policy_check){ /* Do nothing */ strcpy(vp_apc->strvalue, "1"); }else{ /* Perform eDirectory account-policy check */ strcpy(vp_apc->strvalue, "2"); } vp_apc->length = 1; pairadd(&request->config_items, vp_apc); } }#endif DEBUG("rlm_ldap: Added the eDirectory password in check items"); } } else { DEBUG("rlm_ldap: Error reading Universal Password.Return Code = %d",res); } memset(universal_password, 0, universal_password_len); free(universal_password); } } #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) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -