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

📄 rlm_ldap.c

📁 RADIUS 服务器介绍 RADIUS服务器支持标准的RADIUS协议
💻 C
📖 第 1 页 / 共 4 页
字号:
		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);	ld_user = ldap_connect(instance, user_dn, request->password->strvalue,			       1, &res);	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;}static LDAP    *ldap_connect(void *instance, const char *dn, const char *password, int auth, int *result){	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_INITIALIZE		DEBUG("rlm_ldap: (re)connect to %s, authentication %d", inst->server, auth);		if (ldap_initialize(&ld, inst->server) != LDAP_SUCCESS) {			radlog(L_ERR, "rlm_ldap: ldap_initialize() failed");			*result = RLM_MODULE_FAIL;			return (NULL);		}#endif	}	else{		DEBUG("rlm_ldap: (re)connect to %s:%d, authentication %d", inst->server, inst->port, auth);		if ((ld = ldap_init(inst->server, inst->port)) == NULL) {			radlog(L_ERR, "rlm_ldap: ldap_init() failed");			*result = RLM_MODULE_FAIL;			return (NULL);		}	}	if (ldap_set_option(ld, LDAP_OPT_NETWORK_TIMEOUT, (void *) &(inst->net_timeout)) != LDAP_OPT_SUCCESS) {		radlog(L_ERR, "rlm_ldap: Could not set LDAP_OPT_NETWORK_TIMEOUT %ld.%ld", inst->net_timeout.tv_sec, inst->net_timeout.tv_usec);	}	if (ldap_set_option(ld, LDAP_OPT_TIMELIMIT, (void *) &(inst->timelimit)) != LDAP_OPT_SUCCESS) {		radlog(L_ERR, "rlm_ldap: Could not set LDAP_OPT_TIMELIMIT %d", inst->timelimit);	}	if (inst->ldap_debug && ldap_set_option(NULL, LDAP_OPT_DEBUG_LEVEL, &(inst->ldap_debug)) != LDAP_OPT_SUCCESS) {		radlog(L_ERR, "rlm_ldap: Could not set LDAP_OPT_DEBUG_LEVEL %d", inst->ldap_debug);	}	ldap_version = LDAP_VERSION3;	if (ldap_set_option(ld, LDAP_OPT_PROTOCOL_VERSION, &ldap_version) != LDAP_OPT_SUCCESS) {		radlog(L_ERR, "rlm_ldap: Could not set LDAP version to V3");	}#ifdef HAVE_LDAP_START_TLS        if(inst->tls_mode) {		DEBUG("rlm_ldap: setting TLS mode to %d", inst->tls_mode);        	if(ldap_set_option(ld, LDAP_OPT_X_TLS,	  	           (void *) &(inst->tls_mode)) != LDAP_OPT_SUCCESS) {			ldap_get_option(ld, LDAP_OPT_ERROR_NUMBER, &ldap_errno); 			radlog(L_ERR, "rlm_ldap: could not set LDAP_OPT_X_TLS option %s", ldap_err2string(ldap_errno));		}	}	if (inst->start_tls) {		DEBUG("rlm_ldap: starting TLS");		rc = ldap_start_tls_s(ld, NULL, NULL);		if (rc != LDAP_SUCCESS) {			DEBUG("rlm_ldap: ldap_start_tls_s()");			ldap_get_option(ld, LDAP_OPT_ERROR_NUMBER, &ldap_errno);			radlog(L_ERR, "rlm_ldap: could not start TLS %s", ldap_err2string(ldap_errno));			*result = RLM_MODULE_FAIL;			ldap_unbind_s(ld);			return (NULL);		}	}#endif /* HAVE_LDAP_START_TLS */	if (inst->is_url){		DEBUG("rlm_ldap: bind as %s/%s to %s", dn, password, inst->server);	}	else{		DEBUG("rlm_ldap: bind as %s/%s to %s:%d", dn, password, inst->server, inst->port);	}	msgid = ldap_bind(ld, dn, password,LDAP_AUTH_SIMPLE);	if (msgid == -1) {		ldap_get_option(ld, LDAP_OPT_ERROR_NUMBER, &ldap_errno);		if (inst->is_url)			radlog(L_ERR, "rlm_ldap: %s bind to %s failed: %s",			 	dn, inst->server, ldap_err2string(ldap_errno));		else			radlog(L_ERR, "rlm_ldap: %s bind to %s:%d failed: %s",			 	dn, inst->server, inst->port,			 	ldap_err2string(ldap_errno));		*result = RLM_MODULE_FAIL;		ldap_unbind_s(ld);		return (NULL);	}	DEBUG("rlm_ldap: waiting for bind result ...");	rc = ldap_result(ld, msgid, 1, &(inst->timeout), &res);	if(rc < 1) {		DEBUG("rlm_ldap: ldap_result()");		ldap_get_option(ld, LDAP_OPT_ERROR_NUMBER, &ldap_errno);		if (inst->is_url)			radlog(L_ERR, "rlm_ldap: %s bind to %s failed: %s",				dn, inst->server, (rc == 0) ? "timeout" : ldap_err2string(ldap_errno));		else			radlog(L_ERR, "rlm_ldap: %s bind to %s:%d failed: %s",				dn, inst->server, inst->port,				(rc == 0) ? "timeout" : ldap_err2string(ldap_errno));		*result = RLM_MODULE_FAIL;		ldap_unbind_s(ld);		return (NULL);	}	ldap_errno = ldap_result2error(ld, res, 1);	switch (ldap_errno) {	case LDAP_SUCCESS:		*result = RLM_MODULE_OK;		break;	case LDAP_INVALID_CREDENTIALS:		if (auth) 			*result = RLM_MODULE_REJECT;		else {			radlog(L_ERR, "rlm_ldap: LDAP login failed: check login, password settings in ldap section of radiusd.conf");			*result = RLM_MODULE_FAIL;		}				break;			default:		if (inst->is_url)			radlog(L_ERR,"rlm_ldap: %s bind to %s failed %s",				dn, inst->server, ldap_err2string(ldap_errno));		else			radlog(L_ERR,"rlm_ldap: %s bind to %s:%d failed %s",				dn, inst->server, inst->port,				ldap_err2string(ldap_errno));		*result = RLM_MODULE_FAIL;	}	if (*result != RLM_MODULE_OK) {		ldap_unbind_s(ld);		ld = NULL;	}	return ld;}/***************************************************************************** * *	Detach from the LDAP server and cleanup internal state. * *****************************************************************************/static int ldap_detach(void *instance){	ldap_instance  *inst = instance;	TLDAP_RADIUS *pair, *nextpair;	if (inst->server)		free((char *) inst->server);	if (inst->login)		free((char *) inst->login);	if (inst->password)		free((char *) inst->password);	if (inst->basedn)		free((char *) inst->basedn);	if (inst->dictionary_mapping)		free(inst->dictionary_mapping);	if (inst->filter)		free((char *) inst->filter);	if (inst->passwd_hdr)		free((char *) inst->passwd_hdr);	if (inst->passwd_attr)		free((char *) inst->passwd_attr);	if (inst->groupname_attr)		free((char *) inst->groupname_attr);	if (inst->groupmemb_filt)		free((char *) inst->groupmemb_filt);	if (inst->groupmemb_attr)		free((char *) inst->groupmemb_attr);	if (inst->access_attr)		free((char *) inst->access_attr);	if (inst->profile_attr)		free((char *) inst->profile_attr);	if (inst->conns){		int i=0;		for(;i<inst->num_conns;i++){			if (inst->conns[i].ld){				ldap_unbind_s(inst->conns[i].ld);			}			pthread_mutex_destroy(&inst->conns[i].mutex);		}		free(inst->conns);	}	pair = inst->check_item_map;		while (pair != NULL) {		nextpair = pair->next;		free(pair->attr);		free(pair->radius_attr);		free(pair);		pair = nextpair;	}	pair = inst->reply_item_map;	while (pair != NULL) {		nextpair = pair->next;		free(pair->attr);		free(pair->radius_attr);		free(pair);		pair = nextpair;	}	if (inst->atts)		free(inst->atts);	paircompare_unregister(PW_LDAP_GROUP, ldap_groupcmp);	xlat_unregister(inst->xlat_name,ldap_xlat);	free(inst->xlat_name);	free(inst);	return 0;}#ifdef FIELDCPYstatic void fieldcpy(char *string, char **uptr){	char           *ptr;	ptr = *uptr;	while (*ptr == ' ' || *ptr == '\t') {		ptr++;	}	if (*ptr == '"') {		ptr++;		while (*ptr != '"' && *ptr != '\0' && *ptr != '\n') {			*string++ = *ptr++;		}		*string = '\0';		if (*ptr == '"') {			ptr++;		}		*uptr = ptr;		return;	}	while (*ptr != ' ' && *ptr != '\t' && *ptr != '\0' && *ptr != '\n' &&	       *ptr != '=' && *ptr != ',') {		*string++ = *ptr++;	}	*string = '\0';	*uptr = ptr;	return;}#endif/***************************************************************************** *	Get RADIUS attributes from LDAP object *	( according to draft-adoba-radius-05.txt *	  <http://www.ietf.org/internet-drafts/draft-adoba-radius-05.txt> ) * *****************************************************************************/static VALUE_PAIR *ldap_pairget(LDAP * ld, LDAPMessage * entry,	     TLDAP_RADIUS * item_map, VALUE_PAIR **pairs,char is_check){	char          **vals;	int             vals_count;	int             vals_idx;	char           *ptr;	TLDAP_RADIUS   *element;	LRAD_TOKEN      token;	int             is_generic_attribute;	char            value[256];	VALUE_PAIR     *pairlist = NULL;	VALUE_PAIR     *newpair = NULL;	/* check if there is a mapping from this LDAP attribute to a RADIUS attribute */	for (element = item_map; element != NULL; element = element->next) {	if ((vals = ldap_get_values(ld,entry,element->attr)) != NULL){			/* check whether this is a one-to-one-mapped ldap attribute or a generic			   attribute and set flag accordingly */			if (strcasecmp(element->radius_attr, GENERIC_ATTRIBUTE_ID)==0)				is_generic_attribute = 1;			else				is_generic_attribute = 0;			/* find out how many values there are for the attribute and extract all of them */			vals_count = ldap_count_values(vals);			for (vals_idx = 0; vals_idx < vals_count; vals_idx++) {				ptr = vals[vals_idx];				if (is_generic_attribute) {					/* this is a generic attribute */					LRAD_TOKEN dummy; /* makes pairread happy */										/* not sure if using pairread here is ok ... */					if ( (newpair = pairread(&ptr, &dummy)) != NULL) {						DEBUG("rlm_ldap: extracted attribute %s from generic item %s", 						      newpair->name, vals[vals_idx]);						pairadd(&pairlist, newpair);					} else {						radlog(L_ERR, "rlm_ldap: parsing %s failed: %s", 						       element->attr, vals[vals_idx]);					}				} else {					/* this is a one-to-one-mapped attribute */					token = gettoken(&ptr, value, sizeof(value) - 1);					if (token < T_EQSTART || token > T_EQEND) {						token = (is_check) ? T_OP_CMP_EQ : T_OP_EQ;					} else {						gettoken(&ptr, value, sizeof(value) - 1);					}					if (value[0] == 0) {						DEBUG("rlm_ldap: Attribute %s has no value", element->attr);						break;					}					DEBUG("rlm_ldap: Adding %s as %s, value %s & op=%d", element->attr, element->radius_attr, value, token);						if ((newpair = pairmake(element->radius_attr, value, token)) == NULL)						continue;					if (! vals_idx){						pairdelete(pairs,newpair->attribute);					}					pairadd(&pairlist, newpair);				}			}			ldap_value_free(vals);		}	}	return (pairlist);}/* globally exported name */module_t        rlm_ldap = {	"LDAP",	RLM_TYPE_THREAD_SAFE,	/* type: reserved 	 */	NULL,			/* initialization 	 */	ldap_instantiate,	/* instantiation 	 */	{		ldap_authenticate,	/* authentication 	 */		ldap_authorize,		/* authorization 	 */		NULL,			/* preaccounting 	 */		NULL,			/* accounting 		 */		NULL,			/* checksimul 		 */		NULL,			/* pre-proxy 		 */		NULL,			/* post-proxy 		 */		NULL			/* post-auth 		 */	},	ldap_detach,		/* detach 		 */	NULL,			/* destroy 		 */};

⌨️ 快捷键说明

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