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

📄 rlm_ldap.c

📁 RADIUS认证协议
💻 C
📖 第 1 页 / 共 5 页
字号:
		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	 */	if ((pairfind(*check_pairs, PW_AUTH_TYPE) == NULL) &&	    request->password &&	    (request->password->attribute == PW_USER_PASSWORD))		pairadd(check_pairs, pairmake("Auth-Type", "LDAP", T_OP_EQ));	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, NULL)) {			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, 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	ld_user = ldap_connect(instance, user_dn, request->password->strvalue,			1, &res, &err);	if(err != NULL){		/* 'err' contains the LDAP connection error description */		DEBUG("rlm_ldap: %s", err);		pairadd(&request->reply->vps, pairmake("Reply-Message", err, T_OP_EQ));		ldap_memfree((void *)err);	}	/* Don't perform eDirectory APC again after attempting to bind here. */	{		int apc_attr;		DICT_ATTR *dattr;		VALUE_PAIR *vp_apc;		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';	}#endif	if (ld_user == NULL){		if (res == RLM_MODULE_REJECT){			inst->failed_conns = 0;			snprintf(module_fmsg,sizeof(module_fmsg),"rlm_ldap: Bind as user failed");			module_fmsg_vp = pairmake("Module-Failure-Message", module_fmsg, T_OP_EQ);			pairadd(&request->packet->vps, module_fmsg_vp);		}		if (res == RLM_MODULE_FAIL){			DEBUG("rlm_ldap: ldap_connect() failed");			inst->failed_conns++;		}		return (res);	}	DEBUG("rlm_ldap: user %s authenticated succesfully",	      request->username->strvalue);	ldap_unbind_s(ld_user);	inst->failed_conns = 0;	return RLM_MODULE_OK;}#ifdef NOVELL/***************************************************************************** * *	Function: rlm_ldap_postauth * *	Purpose: Perform eDirectory account policy check and failed-login reporting *	to eDirectory. * *****************************************************************************/static intldap_postauth(void *instance, REQUEST * request){	int res = RLM_MODULE_FAIL;	int inst_attr, apc_attr;	char password[UNIVERSAL_PASS_LEN];	ldap_instance  *inst = instance;	LDAP_CONN	*conn;	VALUE_PAIR *vp_inst, *vp_apc;	DICT_ATTR *dattr;	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);	/*	 * Check if the password in the config items list is the user's UP which has	 * been read in the authorize method of this instance of the LDAP module.	 */	if((vp_inst == NULL) || strcmp(vp_inst->strvalue, inst->xlat_name))		return RLM_MODULE_NOOP;	vp_apc = pairfind(request->config_items, apc_attr);	switch(vp_apc->strvalue[0]){		case '1':			/* Account policy check not enabled */		case '3':			/* Account policy check has been completed */			res = RLM_MODULE_NOOP;			break;		case '2':			{				int err, conn_id = -1;				char *error_msg = NULL;				VALUE_PAIR *vp_fdn, *vp_pwd;				DICT_ATTR *da;				if(request->reply->code == PW_AUTHENTICATION_REJECT){					/* Bind to eDirectory as the RADIUS user with a wrong password. */					vp_pwd = pairfind(request->config_items, PW_PASSWORD);					strcpy(password, vp_pwd->strvalue);					if(strlen(password) > 0){						if(password[0] != 'a'){							password[0] = 'a';						}else{							password[0] = 'b';						}					}else{						strcpy(password, "dummy_password");					}					res = RLM_MODULE_REJECT;				}else{					/* Bind to eDirectory as the RADIUS user using the user's UP */					vp_pwd = pairfind(request->config_items, PW_PASSWORD);					if(vp_pwd == NULL){						DEBUG("rlm_ldap: User's Universal Password not in config items list.");						return RLM_MODULE_FAIL;					}					strcpy(password, vp_pwd->strvalue);				}				if ((da = dict_attrbyname("Ldap-UserDn")) == NULL) {					DEBUG("rlm_ldap: Attribute for user FDN not found in dictionary. Unable to proceed");					return RLM_MODULE_FAIL;				}				vp_fdn = pairfind(request->packet->vps, da->attr);				if(vp_fdn == NULL){					DEBUG("rlm_ldap: User's FQDN not in config items list.");					return RLM_MODULE_FAIL;				}				if ((conn_id = ldap_get_conn(inst->apc_conns, &conn, inst)) == -1){					radlog(L_ERR, "rlm_ldap: All ldap connections are in use");					return RLM_MODULE_FAIL;				}				/*				 * If there is an existing LDAP connection to the directory, bind over				 * it. Otherwise, establish a new connection.				 */postauth_reconnect:				if (!conn->bound || conn->ld == NULL) {					DEBUG2("rlm_ldap: attempting LDAP reconnection");					if (conn->ld){						DEBUG2("rlm_ldap: closing existing LDAP connection");						ldap_unbind_s(conn->ld);					}					if ((conn->ld = ldap_connect(instance, (char *)vp_fdn->strvalue, password, 0, &res, &error_msg)) == NULL) {						radlog(L_ERR, "rlm_ldap: eDirectory account policy check failed.");						if(error_msg != NULL){							DEBUG("rlm_ldap: %s", error_msg);							pairadd(&request->reply->vps, pairmake("Reply-Message", error_msg, T_OP_EQ));							ldap_memfree((void *)error_msg);						}						vp_apc->strvalue[0] = '3';						ldap_release_conn(conn_id, inst->apc_conns);						return RLM_MODULE_REJECT;					}					conn->bound = 1;				}else if((err = ldap_simple_bind_s(conn->ld, (char *)vp_fdn->strvalue, password)) != LDAP_SUCCESS){					if(err == LDAP_SERVER_DOWN){						conn->bound = 0;						goto postauth_reconnect;					}					DEBUG("rlm_ldap: eDirectory account policy check failed.");					ldap_get_option(conn->ld, LDAP_OPT_ERROR_STRING, &error_msg);					if(error_msg != NULL){						DEBUG("rlm_ldap: %s", error_msg);						pairadd(&request->reply->vps, pairmake("Reply-Message", error_msg, T_OP_EQ));						ldap_memfree((void *)error_msg);					}					vp_apc->strvalue[0] = '3';					ldap_release_conn(conn_id, inst->apc_conns);					return RLM_MODULE_REJECT;				}				vp_apc->strvalue[0] = '3';				ldap_release_conn(conn_id, inst->apc_conns);				return RLM_MODULE_OK;			}	}	return res;}#endifstatic LDAP    *ldap_connect(void *instance, const char *dn, const char *password, int auth, int *result, char **err){	ldap_instance  *inst = instance;	LDAP           *ld = NULL;	int             msgid, rc, ldap_version;	int		ldap_errno = 0;	LDAPMessage    *res;	if (inst->is_url){#ifdef HAVE_LDAP_INITIA

⌨️ 快捷键说明

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