📄 rlm_ldap.c
字号:
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_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; } 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 }#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->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 && paircmp(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->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; } /* * 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->strvalue); ldap_msgfree(result); ldap_release_conn(conn_id,inst->conns); return RLM_MODULE_OK;}/***************************************************************************** * * Function: rlm_ldap_authenticate * * Purpose: Check the user's password against ldap database * *****************************************************************************/static intldap_authenticate(void *instance, REQUEST * request){ LDAP *ld_user; LDAPMessage *result, *msg; ldap_instance *inst = instance; char *user_dn, *attrs[] = {"uid", NULL}; char filter[MAX_FILTER_STR_LEN]; char basedn[MAX_FILTER_STR_LEN]; int res; VALUE_PAIR *vp_user_dn; VALUE_PAIR *module_fmsg_vp; char module_fmsg[MAX_STRING_LEN]; LDAP_CONN *conn; int conn_id = -1;#ifdef NOVELL char *err = NULL;#endif DEBUG("rlm_ldap: - authenticate"); /* * Ensure that we're being passed a plain-text password, and not * anything else. */ if (!request->username) { radlog(L_AUTH, "rlm_ldap: Attribute \"User-Name\" is required for authentication.\n"); return RLM_MODULE_INVALID; } if (!request->password){ radlog(L_AUTH, "rlm_ldap: Attribute \"User-Password\" is required for authentication."); return RLM_MODULE_INVALID; } if(request->password->attribute != PW_PASSWORD) { radlog(L_AUTH, "rlm_ldap: Attribute \"User-Password\" is required for authentication. Cannot use \"%s\".", request->password->name); return RLM_MODULE_INVALID; } if (request->password->length == 0) { snprintf(module_fmsg,sizeof(module_fmsg),"rlm_ldap: empty password supplied"); module_fmsg_vp = pairmake("Module-Failure-Message", module_fmsg, T_OP_EQ); pairadd(&request->packet->vps, module_fmsg_vp); return RLM_MODULE_INVALID; } /* * Check that we don't have any failed connections. If we do there's no real need * of runing. Also give it another chance if we have a lot of failed connections. */ if (inst->failed_conns > MAX_FAILED_CONNS_END) inst->failed_conns = 0; if (inst->failed_conns > MAX_FAILED_CONNS_START){ inst->failed_conns++; return RLM_MODULE_FAIL; } DEBUG("rlm_ldap: login attempt by \"%s\" with password \"%s\"", request->username->strvalue, request->password->strvalue); while((vp_user_dn = pairfind(request->packet->vps, PW_LDAP_USERDN)) == NULL) { 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, ldap_escape_func)) { 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, attrs, &result)) != RLM_MODULE_OK) { 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) { 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; } ldap_release_conn(conn_id,inst->conns); pairadd(&request->packet->vps, pairmake("Ldap-UserDn", user_dn, T_OP_EQ)); ldap_memfree(user_dn); ldap_msgfree(result); } user_dn = vp_user_dn->strvalue; DEBUG("rlm_ldap: user DN: %s", user_dn);#ifndef NOVELL ld_user = ldap_connect(instance, user_dn, request->password->strvalue, 1, &res, NULL);#else /* Don't perform eDirectory APC again after attempting to bind here. */ { int apc_attr; DICT_ATTR *dattr; VALUE_PAIR *vp_apc; VALUE_PAIR *vp_auth_opt, *vp_state; int auth_opt_attr; char seq[256]; char host_ipaddr[32]; LDAP_CONN *conn1; int auth_state = -1; char *challenge = NULL; int challenge_len = MAX_CHALLENGE_LEN; char *state = NULL; dattr = dict_attrbyname("eDir-APC"); apc_attr = dattr->attr; vp_apc = pairfind(request->config_items, apc_attr); if(vp_apc && vp_apc->strvalue[0] == '2') vp_apc->strvalue[0] = '3'; res = 0; dattr = dict_attrbyname("eDir-Auth-Option"); auth_opt_attr = dattr->attr; vp_auth_opt = pairfind(request->config_items, auth_opt_attr); if(vp_auth_opt ) { DEBUG("rlm_ldap: ldap auth option = %s", vp_auth_opt->strvalue); strncpy(seq, vp_auth_opt->strvalue, vp_auth_opt->length); seq[vp_auth_opt->length] = '\0'; if( strcmp(seq, "<No Default>") ){ /* Get the client IP address to check for packet validity */ inet_ntop(AF_INET, &request->packet->src_ipaddr, host_ipaddr, sizeof(host_ipaddr)); /* challenge variable is used to receive the challenge from the * Token method (if any) and also to send the state attribute * in case the request packet is a reply to a challenge */ challenge = rad_malloc(MAX_CHALLENGE_LEN); /* If state attribute present in request it is a reply to challenge. */ if((vp_state = pairfind(request->packet->vps, PW_STATE))!= NULL ){ DEBUG("rlm_ldap: Response to Access-Challenge"); strncpy(challenge, vp_state->strvalue, sizeof(challenge)); challenge_len = vp_state->length; challenge[challenge_len] = 0; auth_state = -2; } if ((conn_id = ldap_get_conn(inst->conns, &conn1, inst)) == -1){ radlog(L_ERR, "rlm_ldap: All ldap connections are in use"); res = RLM_MODULE_FAIL; } if(!conn1){ radlog(L_ERR, "rlm_ldap: NULL connection handle passed"); return RLM_MODULE_FAIL; } if (conn1->failed_conns > MAX_FAILED_CONNS_START){ conn1->failed_conns++; if (conn1->failed_conns >= MAX_FAILED_CONNS_END){ conn1->failed_conns = MAX_FAILED_CONNS_RESTART; conn1->bound = 0; } }retry: if (!conn1->bound || conn1->ld == NULL) { DEBUG2("rlm_ldap: attempting LDAP reconnection"); if (conn1->ld){ DEBUG2("rlm_ldap: closing existing LDAP connection"); ldap_unbind_s(conn1->ld); } if ((conn1->ld = ldap_connect(instance, inst->login,inst->password, 0, &res, NULL)) == NULL) { radlog(L_ERR, "rlm_ldap: (re)connection attempt failed"); conn1->failed_conns++; return (RLM_MODULE_FAIL); } conn1->bound = 1; conn1->failed_conns = 0; } DEBUG("rlm_ldap: Performing NMAS Authentication for user: %s, seq: %s \n", user_dn,seq); res = radLdapXtnNMASAuth(conn1->ld, user_dn, request->password->strvalue, seq, host_ipaddr, &challenge_len, challenge, &auth_state ); switch(res){ case LDAP_SUCCESS: ldap_re
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -