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

📄 rlm_ldap.c

📁 RADIUS认证协议
💻 C
📖 第 1 页 / 共 5 页
字号:
			return i;		}	}	return -1;}static inline void ldap_release_conn(int i, LDAP_CONN *conns){	DEBUG("rlm_ldap: ldap_release_conn: Release Id: %d",i);	conns[i].locked = 0;	pthread_mutex_unlock(&(conns[i].mutex));}/************************************************************************* * *	Function: rlm_ldap_instantiate * *	Purpose: Uses section of radiusd config file passed as parameter *		 to create an instance of the module. * *************************************************************************/static intldap_instantiate(CONF_SECTION * conf, void **instance){	ldap_instance  *inst;	int i = 0;	int atts_num = 0;	int reply_map_num = 0;	int check_map_num = 0;	int att_map[3] = {0,0,0};	TLDAP_RADIUS *pair;	ATTR_FLAGS flags;	char *xlat_name;	inst = rad_malloc(sizeof *inst);	if (!inst) {		return -1;	}	memset(inst, 0, sizeof(*inst));	if (cf_section_parse(conf, inst, module_config) < 0) {		free(inst);		return -1;	}	if (inst->server == NULL) {		radlog(L_ERR, "rlm_ldap: missing 'server' directive.");		free(inst);		return -1;	}	inst->is_url = 0;	if (ldap_is_ldap_url(inst->server)){#ifdef HAVE_LDAP_INITIALIZE		inst->is_url = 1;		inst->port = 0;#else		radlog(L_ERR, "rlm_ldap: 'server' directive is in URL form but ldap_initialize() is not available.");		free(inst);		return -1;#endif	}	inst->timeout.tv_usec = 0;	inst->net_timeout.tv_usec = 0;	/* workaround for servers which support LDAPS but not START TLS */	if(inst->port == LDAPS_PORT || inst->tls_mode)		inst->tls_mode = LDAP_OPT_X_TLS_HARD;	else		inst->tls_mode = 0;	inst->reply_item_map = NULL;	inst->check_item_map = NULL;	inst->conns = NULL;	inst->failed_conns = 0;	DEBUG("rlm_ldap: Registering ldap_groupcmp for Ldap-Group");	paircompare_register(PW_LDAP_GROUP, PW_USER_NAME, ldap_groupcmp, inst);	xlat_name = cf_section_name2(conf);	if (xlat_name != NULL){		char *group_name;		DICT_ATTR *dattr;		/*		 * Allocate room for <instance>-Ldap-Group		 */		group_name = malloc((strlen(xlat_name) + 1 + 11) * sizeof(char));		rad_assert(group_name != NULL);		sprintf(group_name,"%s-Ldap-Group",xlat_name);		DEBUG("rlm_ldap: Creating new attribute %s",group_name);		dict_addattr(group_name, 0, PW_TYPE_STRING, -1, flags);		dattr = dict_attrbyname(group_name);		if (dattr == NULL){			radlog(L_ERR, "rlm_ldap: Failed to create attribute %s",group_name);			free(inst);			return -1;		}		DEBUG("rlm_ldap: Registering ldap_groupcmp for %s",group_name);		paircompare_register(dattr->attr, PW_USER_NAME, ldap_groupcmp, inst);	}	else {		xlat_name = cf_section_name1(conf);		rad_assert(xlat_name != NULL); /* or all hell breaks loose */	}	inst->xlat_name = strdup(xlat_name);	DEBUG("rlm_ldap: Registering ldap_xlat with xlat_name %s",xlat_name);	xlat_register(xlat_name,ldap_xlat,inst);#ifdef NOVELL	/*	 * (LDAP_Instance, V1) attribute-value pair in the config items list means	 * that the 'authorize' method of the instance 'V1' of the LDAP module has	 * processed this request.	 */	dict_addattr("LDAP-Instance", 0, PW_TYPE_STRING, -1, flags);	/*	 * ('eDir-APC', '1') in config items list => Do not perform eDirectory account	 *                                           policy check (APC)	 * ('eDir-APC', '2') in config items list => Perform eDirectory APC	 * ('eDir-APC', '3') in config items list => eDirectory APC has been completed	 */	dict_addattr("eDir-APC", 0, PW_TYPE_INTEGER, -1, flags);#endif	if (inst->num_conns <= 0){		radlog(L_ERR, "rlm_ldap: Invalid ldap connections number passed.");		free(inst);		return -1;	}	inst->conns = (LDAP_CONN *)malloc(sizeof(LDAP_CONN)*inst->num_conns);	if (inst->conns == NULL){		radlog(L_ERR, "rlm_ldap: Could not allocate memory. Aborting.");		free(inst);		return -1;	}	for(;i<inst->num_conns;i++){		inst->conns[i].bound = 0;		inst->conns[i].locked = 0;		inst->conns[i].failed_conns = 0;		inst->conns[i].ld = NULL;		pthread_mutex_init(&inst->conns[i].mutex, NULL);	}#ifdef NOVELL	/*	 * 'inst->apc_conns' is a separate connection pool to be used for performing	 * eDirectory account policy check in the 'postauth' method. This avoids	 * changing the (RADIUS server) credentials associated with the 'inst->conns'	 * connection pool.	 */	inst->apc_conns = (LDAP_CONN *)malloc(sizeof(LDAP_CONN)*inst->num_conns);	if (inst->apc_conns == NULL){		radlog(L_ERR, "rlm_ldap: Could not allocate memory. Aborting.");		free(inst);		return -1;	}	for(i = 0; i < inst->num_conns; i++){		inst->apc_conns[i].bound = 0;		inst->apc_conns[i].locked = 0;		inst->apc_conns[i].failed_conns = 0;		inst->apc_conns[i].ld = NULL;		pthread_mutex_init(&inst->apc_conns[i].mutex, NULL);	}#endif	if (read_mappings(inst) != 0) {		radlog(L_ERR, "rlm_ldap: Reading dictionary mappings from file %s failed",		       inst->dictionary_mapping);		free(inst);		return -1;	}	if (inst->check_item_map == NULL && inst->reply_item_map == NULL){		radlog(L_ERR, "rlm_ldap: dictionary mappings file %s did not contain any mappings",			inst->dictionary_mapping);		free(inst);		return -1;	}	pair = inst->check_item_map;	while(pair != NULL){		atts_num++;		pair = pair->next;	}	check_map_num = (atts_num - 1);	pair = inst->reply_item_map;	while(pair != NULL){		atts_num++;		pair = pair->next;	}	reply_map_num = (atts_num - 1);	if (inst->profile_attr)		atts_num++;	if (inst->passwd_attr)		atts_num++;	if (inst->access_attr)		atts_num++;	inst->atts = (char **)malloc(sizeof(char *)*(atts_num + 1));	if (inst->atts == NULL){		radlog(L_ERR, "rlm_ldap: Could not allocate memory. Aborting.");		free(inst);		return -1;	}	pair = inst->check_item_map;	if (pair == NULL)		pair = inst->reply_item_map;	for(i=0;i<atts_num;i++){		if (i <= check_map_num ){			inst->atts[i] = pair->attr;			if (i == check_map_num)				pair = inst->reply_item_map;			else				pair = pair->next;		}		else if (i <= reply_map_num){			inst->atts[i] = pair->attr;			pair = pair->next;		}		else{			if (inst->profile_attr && !att_map[0]){				inst->atts[i] = inst->profile_attr;				att_map[0] = 1;			}			else if (inst->passwd_attr && !att_map[1]){				inst->atts[i] = inst->passwd_attr;				att_map[1] = 1;			}			else if (inst->access_attr && !att_map[2]){				inst->atts[i] = inst->access_attr;				att_map[2] = 1;			}		}	}	inst->atts[atts_num] = NULL;	DEBUG("conns: %p",inst->conns);	*instance = inst;	return 0;}/* * read_mappings(...) reads a ldap<->radius mappings file to inst->reply_item_map and inst->check_item_map */#define MAX_LINE_LEN 160#define GENERIC_ATTRIBUTE_ID "$GENERIC$"static intread_mappings(ldap_instance* inst){	FILE* mapfile;	char *filename;	/* all buffers are of MAX_LINE_LEN so we can use sscanf without being afraid of buffer overflows */	char buf[MAX_LINE_LEN], itemType[MAX_LINE_LEN], radiusAttribute[MAX_LINE_LEN], ldapAttribute[MAX_LINE_LEN];	int linenumber;	/* open the mappings file for reading */	filename = inst->dictionary_mapping;	DEBUG("rlm_ldap: reading ldap<->radius mappings from file %s", filename);	mapfile = fopen(filename, "r");	if (mapfile == NULL) {		radlog(L_ERR, "rlm_ldap: Opening file %s failed", filename);		return -1; /* error */	}	/* read file line by line. Note that if line length exceed MAX_LINE_LEN, line numbers will be mixed up */	linenumber = 0;	while (fgets(buf, sizeof buf, mapfile)!=NULL) {		char* ptr;		int token_count;		TLDAP_RADIUS* pair;		linenumber++;		/* strip comments */		ptr = strchr(buf, '#');		if (ptr) *ptr = 0;		/* empty line */		if (buf[0] == 0) continue;		/* extract tokens from the string */		token_count = sscanf(buf, "%s %s %s", itemType, radiusAttribute, ldapAttribute);		if (token_count <= 0) /* no tokens */			continue;		if (token_count != 3) {			radlog(L_ERR, "rlm_ldap: Skipping %s line %i: %s", filename, linenumber, buf);			radlog(L_ERR, "rlm_ldap: Expected 3 tokens "			       "(Item type, RADIUS Attribute and LDAP Attribute) but found only %i", token_count);			continue;		}		/* create new TLDAP_RADIUS list node */		pair = rad_malloc(sizeof(TLDAP_RADIUS));		pair->attr = strdup(ldapAttribute);		pair->radius_attr = strdup(radiusAttribute);		if ( (pair->attr == NULL) || (pair->radius_attr == NULL) ) {			radlog(L_ERR, "rlm_ldap: Out of memory");			if (pair->attr) free(pair->attr);			if (pair->radius_attr) free(pair->radius_attr);			free(pair);			fclose(mapfile);			return -1;		}		/* push node to correct list */		if (strcasecmp(itemType, "checkItem") == 0) {			pair->next = inst->check_item_map;			inst->check_item_map = pair;		} else if (strcasecmp(itemType, "replyItem") == 0) {			pair->next = inst->reply_item_map;			inst->reply_item_map = pair;		} else {			radlog(L_ERR, "rlm_ldap: file %s: skipping line %i: unknown itemType %s",			       filename, linenumber, itemType);			free(pair->attr);			free(pair->radius_attr);			free(pair);			continue;		}		DEBUG("rlm_ldap: LDAP %s mapped to RADIUS %s",		      pair->attr, pair->radius_attr);	}	fclose(mapfile);	return 0; /* success */}static intperform_search(void *instance, LDAP_CONN *conn, char *search_basedn, int scope, char *filter,		char **attrs, LDAPMessage ** result){	int             res = RLM_MODULE_OK;	int		ldap_errno = 0;	ldap_instance  *inst = instance;	int		search_retry = 0;	*result = NULL;	if (!conn){		radlog(L_ERR, "rlm_ldap: NULL connection handle passed");		return RLM_MODULE_FAIL;	}	if (conn->failed_conns > MAX_FAILED_CONNS_START){		conn->failed_conns++;		if (conn->failed_conns >= MAX_FAILED_CONNS_END){			conn->failed_conns = MAX_FAILED_CONNS_RESTART;			conn->bound = 0;		}	}retry:	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, inst->login,					     inst->password, 0, &res, NULL)) == NULL) {			radlog(L_ERR, "rlm_ldap: (re)connection attempt failed");			if (search_retry == 0)				conn->failed_conns++;			return (RLM_MODULE_FAIL);		}		conn->bound = 1;		conn->failed_conns = 0;	}	DEBUG2("rlm_ldap: performing search in %s, with filter %s", search_basedn ? search_basedn : "(null)" , filter);	switch (ldap_search_st(conn->ld, search_basedn, scope, filter, attrs, 0, &(inst->timeout), result)) {	case LDAP_SUCCESS:	case LDAP_NO_SUCH_OBJECT:		break;

⌨️ 快捷键说明

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