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

📄 rlm_ldap.c

📁 RADIUS 服务器介绍 RADIUS服务器支持标准的RADIUS协议
💻 C
📖 第 1 页 / 共 4 页
字号:
 * Do an xlat on an LDAP URL */static int ldap_xlat(void *instance, REQUEST *request, char *fmt, char *out, int freespace,				RADIUS_ESCAPE_STRING func){	char url[MAX_FILTER_STR_LEN];	int res;	int ret = 0;	ldap_instance *inst = instance;	LDAPURLDesc *ldap_url;	LDAPMessage *result = NULL;	LDAPMessage *msg = NULL;	char **vals;	int conn_id = -1;	LDAP_CONN *conn;	DEBUG("rlm_ldap: - ldap_xlat");	if (!radius_xlat(url, sizeof(url), fmt, request, func)) {		radlog (L_ERR, "rlm_ldap: Unable to create LDAP URL.\n");		return 0;	}	if (!ldap_is_ldap_url(url)){		radlog (L_ERR, "rlm_ldap: String passed does not look like an LDAP URL.\n");		return 0;	}	if (ldap_url_parse(url,&ldap_url)){		radlog (L_ERR, "rlm_ldap: LDAP URL parse failed.\n");		return 0;	}	if (ldap_url->lud_attrs == NULL || ldap_url->lud_attrs[0] == NULL || \		( ldap_url->lud_attrs[1] != NULL || ( ! strlen(ldap_url->lud_attrs[0]) || \		! strcmp(ldap_url->lud_attrs[0],"*") ) ) ){		radlog (L_ERR, "rlm_ldap: Invalid Attribute(s) request.\n");		ldap_free_urldesc(ldap_url);		return 0;	}	if (ldap_url->lud_host){		if (strncmp(inst->server,ldap_url->lud_host,strlen(inst->server)) != 0 || \				ldap_url->lud_port != inst->port){			DEBUG("rlm_ldap: Requested server/port is not known to this module instance.");			ldap_free_urldesc(ldap_url);			return 0;		}	}	if ((conn_id = ldap_get_conn(inst->conns,&conn,inst)) == -1){		radlog(L_ERR, "rlm_ldap: All ldap connections are in use");		ldap_free_urldesc(ldap_url);		return 0;	}	if ((res = perform_search(inst, conn, ldap_url->lud_dn, ldap_url->lud_scope, ldap_url->lud_filter, ldap_url->lud_attrs, &result)) != RLM_MODULE_OK){		if (res == RLM_MODULE_NOTFOUND){			DEBUG("rlm_ldap: Search returned not found");			ldap_free_urldesc(ldap_url);			ldap_release_conn(conn_id,inst->conns);			return 0;		}		DEBUG("rlm_ldap: Search returned error");		ldap_free_urldesc(ldap_url);		ldap_release_conn(conn_id,inst->conns);		return 0;	}	if ((msg = ldap_first_entry(conn->ld, result)) == NULL){		DEBUG("rlm_ldap: ldap_first_entry() failed");		ldap_msgfree(result);		ldap_free_urldesc(ldap_url);		ldap_release_conn(conn_id,inst->conns);		return 0;	}	if ((vals = ldap_get_values(conn->ld, msg, ldap_url->lud_attrs[0])) != NULL) {		ret = strlen(vals[0]);		if (ret > freespace){			DEBUG("rlm_ldap: Insufficient string space");			ldap_free_urldesc(ldap_url);			ldap_value_free(vals);			ldap_msgfree(result);			ldap_release_conn(conn_id,inst->conns);			return 0;		}		DEBUG("rlm_ldap: Adding attribute %s, value: %s",ldap_url->lud_attrs[0],vals[0]);		strncpy(out,vals[0],ret);		ldap_value_free(vals);	}	else		ret = 0;	ldap_msgfree(result);	ldap_free_urldesc(ldap_url);	ldap_release_conn(conn_id,inst->conns);	DEBUG("rlm_ldap: - ldap_xlat end");	return ret;}/****************************************************************************** * *      Function: rlm_ldap_authorize * *      Purpose: Check if user is authorized for remote access * ******************************************************************************/static int ldap_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,"(objectclass=radiusprofile)",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))) {						/*pairadd(check_pairs,check_tmp);*/						pairxlatmove(request, check_pairs, &check_tmp);						pairfree(&check_tmp);					}					if ((reply_tmp = ldap_pairget(conn->ld,def_msg,inst->reply_item_map,reply_pairs,0))) {						/*pairadd(reply_pairs,reply_tmp);*/						pairxlatmove(request, reply_pairs, &reply_tmp);						pairfree(&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,"(objectclass=radiusprofile)",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))) {							/*pairadd(check_pairs,check_tmp);*/							pairxlatmove(request, check_pairs, &check_tmp);							pairfree(&check_tmp);						}						if ((reply_tmp = ldap_pairget(conn->ld,def_attr_msg,inst->reply_item_map,reply_pairs,0))) {							/*pairadd(reply_pairs,reply_tmp);*/							pairxlatmove(request, reply_pairs, &reply_tmp);							pairfree(&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)){		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);			}		}	}	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) {		/*pairadd(check_pairs,check_tmp);*/		pairxlatmove(request, check_pairs, &check_tmp);		pairfree(&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) {		/*pairadd(reply_pairs,reply_tmp);*/		pairxlatmove(request, reply_pairs, &reply_tmp);		pairfree(&reply_tmp);	}       if (inst->do_comp && paircmp(request,request->packet->vps,*check_pairs,reply_pairs) != 0){		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_AUTHTYPE) == NULL)		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 int ldap_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;	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) {		radlog(L_ERR, "rlm_ldap: empty password supplied");

⌨️ 快捷键说明

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