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

📄 rlm_ldap.c

📁 使用最广泛的radius的linux的源码
💻 C
📖 第 1 页 / 共 5 页
字号:
/* * rlm_ldap.c	LDAP authorization and authentication module. * *   This program is free software; you can redistribute it and/or modify *   it under the terms of the GNU General Public License as published by *   the Free Software Foundation; either version 2 of the License, or *   (at your option) any later version. * *   This program is distributed in the hope that it will be useful, *   but WITHOUT ANY WARRANTY; without even the implied warranty of *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the *   GNU General Public License for more details. * *   You should have received a copy of the GNU General Public License *   along with this program; if not, write to the Free Software *   Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA * *   Copyright 2004,2006 The FreeRADIUS Server Project. */#include <freeradius-devel/ident.h>RCSID("$Id: rlm_ldap.c,v 1.194 2008/04/17 07:59:21 aland Exp $")#include <freeradius-devel/radiusd.h>#include <freeradius-devel/modules.h>#include	<freeradius-devel/rad_assert.h>#include	<pwd.h>#include	<ctype.h>#include	<lber.h>#include        <ldap.h>#ifndef HAVE_PTHREAD_H/* *      This is a lot simpler than putting ifdef's around *      every use of the pthread functions. */#define pthread_mutex_lock(a)#define pthread_mutex_trylock(a) (0)#define pthread_mutex_unlock(a)#define pthread_mutex_init(a,b)#define pthread_mutex_destroy(a)#else#include	<pthread.h>#endif#define MAX_FILTER_STR_LEN	1024#define TIMELIMIT 5/* * These are used in case ldap_search returns LDAP_SERVER_DOWN * In that case we do conn->failed_conns++ and then check it: * If conn->failed_conns <= MAX_FAILED_CONNS_START then we try * to reconnect * conn->failed_conns is also checked on entrance in perform_search: * If conn->failed_conns > MAX_FAILED_CONNS_START then we don't * try to do anything and we just do conn->failed_conns++ and * return RLM_MODULE_FAIL * if conn->failed_conns >= MAX_FAILED_CONNS_END then we give it * another chance and we set it to MAX_FAILED_CONNS_RESTART and * try to reconnect. * * * We are assuming that the majority of the LDAP_SERVER_DOWN cases * will either be an ldap connection timeout or a temporary ldap * server problem. * As a result we make a few attempts to reconnect hoping that the problem * will soon go away. If it does not go away then we just return * RLM_MODULE_FAIL on entrance in perform_search until conn->failed_conns * gets to MAX_FAILED_CONNS_END. After that we give it one more chance by * going back to MAX_FAILED_CONNS_RESTART * */#define MAX_FAILED_CONNS_END		20#define MAX_FAILED_CONNS_RESTART	4#define MAX_FAILED_CONNS_START		5#ifdef NOVELL_UNIVERSAL_PASSWORD/* Universal Password Length */#define UNIVERSAL_PASS_LEN 256int nmasldap_get_password(	LDAP	 *ld,	char     *objectDN,	size_t   *pwdSize,	/* in bytes */	char     *pwd );#endif#ifdef NOVELL#define REQUEST_ACCEPTED   0#define REQUEST_CHALLENGED 1#define REQUEST_REJECTED   2#define MAX_CHALLENGE_LEN  128int radLdapXtnNMASAuth( LDAP *, char *, char *, char *, char *, size_t *, char *, int * );#endif/* linked list of mappings between RADIUS attributes and LDAP attributes */struct TLDAP_RADIUS {	char*                 attr;	char*                 radius_attr;	FR_TOKEN	      operator;	struct TLDAP_RADIUS*  next;};typedef struct TLDAP_RADIUS TLDAP_RADIUS;typedef struct ldap_conn {	LDAP		*ld;	char		bound;	char		locked;	int		failed_conns;#ifdef HAVE_PTHREAD_H	pthread_mutex_t	mutex;#endif} LDAP_CONN;typedef struct {	char           *server;	int             port;	int             timelimit;	int  		net_timeout;	int		timeout;	int             debug;	int             tls_mode;	int		start_tls;	int		num_conns;	int		do_comp;	int		do_xlat;	int		default_allow;	int		failed_conns;	int		is_url;	char           *login;	char           *password;	char           *filter;	char           *base_filter;	char           *basedn;	char           *default_profile;	char           *profile_attr;	char           *access_attr;	char           *passwd_hdr;	char           *passwd_attr;	int		auto_header;	char           *dictionary_mapping;	char	       *groupname_attr;	char	       *groupmemb_filt;	char           *groupmemb_attr;	char		**atts;	TLDAP_RADIUS   *check_item_map;	TLDAP_RADIUS   *reply_item_map;	LDAP_CONN	*conns;#ifdef NOVELL	LDAP_CONN *apc_conns;#endif	int             ldap_debug; /* Debug flag for LDAP SDK */	char		*xlat_name; /* name used to xlat */	char		*tls_cacertfile;	char		*tls_cacertdir;	char		*tls_certfile;	char		*tls_keyfile;	char		*tls_randfile;	char		*tls_require_cert;#ifdef NOVELL	int		 edir_account_policy_check;#endif	int		 set_auth_type;}  ldap_instance;/* The default setting for TLS Certificate Verification */#define TLS_DEFAULT_VERIFY "allow"static CONF_PARSER tls_config[] = {	{"start_tls", PW_TYPE_BOOLEAN,	 offsetof(ldap_instance,start_tls), NULL, "no"},	{"cacertfile", PW_TYPE_FILENAME,	 offsetof(ldap_instance,tls_cacertfile), NULL, NULL},	{"cacertdir", PW_TYPE_FILENAME,	 offsetof(ldap_instance,tls_cacertdir), NULL, NULL},	{"certfile", PW_TYPE_FILENAME,	 offsetof(ldap_instance,tls_certfile), NULL, NULL},	{"keyfile", PW_TYPE_FILENAME,	 offsetof(ldap_instance,tls_keyfile), NULL, NULL},	{"randfile", PW_TYPE_STRING_PTR, /* OK if it changes on HUP */	 offsetof(ldap_instance,tls_randfile), NULL, NULL},	{"require_cert", PW_TYPE_STRING_PTR,	 offsetof(ldap_instance,tls_require_cert), NULL, TLS_DEFAULT_VERIFY},	{ NULL, -1, 0, NULL, NULL }};static const CONF_PARSER module_config[] = {	{"server", PW_TYPE_STRING_PTR,	 offsetof(ldap_instance,server), NULL, "localhost"},	{"port", PW_TYPE_INTEGER,	 offsetof(ldap_instance,port), NULL, "389"},	{"password", PW_TYPE_STRING_PTR,	 offsetof(ldap_instance,password), NULL, ""},	{"identity", PW_TYPE_STRING_PTR,	 offsetof(ldap_instance,login), NULL, ""},	/*	 *	Timeouts & stuff.	 */	/* wait forever on network activity */	{"net_timeout", PW_TYPE_INTEGER,	 offsetof(ldap_instance,net_timeout), NULL, "10"},	/* wait forever for search results */	{"timeout", PW_TYPE_INTEGER,	 offsetof(ldap_instance,timeout), NULL, "20"},	/* allow server unlimited time for search (server-side limit) */	{"timelimit", PW_TYPE_INTEGER,	 offsetof(ldap_instance,timelimit), NULL, "20"},	/*	 *	TLS configuration  The first few are here for backwards	 *	compatibility.  The last is the new subsection.	 */	{"tls_mode", PW_TYPE_BOOLEAN,	 offsetof(ldap_instance,tls_mode), NULL, "no"},	{"start_tls", PW_TYPE_BOOLEAN,	 offsetof(ldap_instance,start_tls), NULL, "no"},	{"tls_cacertfile", PW_TYPE_FILENAME,	 offsetof(ldap_instance,tls_cacertfile), NULL, NULL},	{"tls_cacertdir", PW_TYPE_FILENAME,	 offsetof(ldap_instance,tls_cacertdir), NULL, NULL},	{"tls_certfile", PW_TYPE_FILENAME,	 offsetof(ldap_instance,tls_certfile), NULL, NULL},	{"tls_keyfile", PW_TYPE_FILENAME,	 offsetof(ldap_instance,tls_keyfile), NULL, NULL},	{"tls_randfile", PW_TYPE_STRING_PTR, /* OK if it changes on HUP */	 offsetof(ldap_instance,tls_randfile), NULL, NULL},	{"tls_require_cert", PW_TYPE_STRING_PTR,	 offsetof(ldap_instance,tls_require_cert), NULL, TLS_DEFAULT_VERIFY},	{ "tls", PW_TYPE_SUBSECTION, 0, NULL, (const void *) tls_config },	/*	 *	DN's and filters.	 */	{"basedn", PW_TYPE_STRING_PTR,	 offsetof(ldap_instance,basedn), NULL, "o=notexist"},	{"filter", PW_TYPE_STRING_PTR,	 offsetof(ldap_instance,filter), NULL, "(uid=%u)"},	{"base_filter", PW_TYPE_STRING_PTR,	 offsetof(ldap_instance,base_filter), NULL, "(objectclass=radiusprofile)"},	{"default_profile", PW_TYPE_STRING_PTR,	 offsetof(ldap_instance,default_profile), NULL, NULL},	{"profile_attribute", PW_TYPE_STRING_PTR,	 offsetof(ldap_instance,profile_attr), NULL, NULL},	/*	 *	Getting passwords from the database	 */	{"password_header", PW_TYPE_STRING_PTR,	 offsetof(ldap_instance,passwd_hdr), NULL, NULL},	{"password_attribute", PW_TYPE_STRING_PTR,	 offsetof(ldap_instance,passwd_attr), NULL, NULL},	{"auto_header", PW_TYPE_BOOLEAN,	 offsetof(ldap_instance,auto_header), NULL, "no"},	/*	 *	Access limitations	 */	/* LDAP attribute name that controls remote access */	{"access_attr", PW_TYPE_STRING_PTR,	 offsetof(ldap_instance,access_attr), NULL, NULL},	{"access_attr_used_for_allow", PW_TYPE_BOOLEAN,	 offsetof(ldap_instance,default_allow), NULL, "yes"},	/*	 *	Group checks.  These could probably be done	 *	via dynamic xlat's.	 */	{"groupname_attribute", PW_TYPE_STRING_PTR,	 offsetof(ldap_instance,groupname_attr), NULL, "cn"},	{"groupmembership_filter", PW_TYPE_STRING_PTR,	 offsetof(ldap_instance,groupmemb_filt), NULL, "(|(&(objectClass=GroupOfNames)(member=%{Ldap-UserDn}))(&(objectClass=GroupOfUniqueNames)(uniquemember=%{Ldap-UserDn})))"},	{"groupmembership_attribute", PW_TYPE_STRING_PTR,	 offsetof(ldap_instance,groupmemb_attr), NULL, NULL},	/* file with mapping between LDAP and RADIUS attributes */	{"dictionary_mapping", PW_TYPE_FILENAME,	 offsetof(ldap_instance,dictionary_mapping), NULL, "${confdir}/ldap.attrmap"},	/*	 *	Debugging flags to the server	 */	{"ldap_debug", PW_TYPE_INTEGER,	 offsetof(ldap_instance,ldap_debug), NULL, "0x0000"},	{"ldap_connections_number", PW_TYPE_INTEGER,	 offsetof(ldap_instance,num_conns), NULL, "5"},	{"compare_check_items", PW_TYPE_BOOLEAN,	 offsetof(ldap_instance,do_comp), NULL, "no"},	{"do_xlat", PW_TYPE_BOOLEAN,	 offsetof(ldap_instance,do_xlat), NULL, "yes"},#ifdef NOVELL	/*	 *	Novell magic.	 */	{"edir_account_policy_check", PW_TYPE_BOOLEAN,	 offsetof(ldap_instance,edir_account_policy_check), NULL, "yes"},#endif	{"set_auth_type", PW_TYPE_BOOLEAN, offsetof(ldap_instance,set_auth_type), NULL, "yes"},	{NULL, -1, 0, NULL, NULL}};#define ld_valid                ld_options.ldo_valid#define LDAP_VALID_SESSION      0x2#define LDAP_VALID(ld)  ( (ld)->ld_valid == LDAP_VALID_SESSION )#ifdef FIELDCPYstatic void     fieldcpy(char *, char **);#endifstatic VALUE_PAIR *ldap_pairget(LDAP *, LDAPMessage *, TLDAP_RADIUS *,VALUE_PAIR **,int);static int ldap_groupcmp(void *, REQUEST *, VALUE_PAIR *, VALUE_PAIR *, VALUE_PAIR *, VALUE_PAIR **);static size_t ldap_xlat(void *, REQUEST *, char *, char *, size_t, RADIUS_ESCAPE_STRING);static LDAP    *ldap_connect(void *instance, const char *, const char *, int, int *, char **);static int     read_mappings(ldap_instance* inst);static inline int ldap_get_conn(LDAP_CONN *conns,LDAP_CONN **ret,void *instance){	ldap_instance *inst = instance;	register int i = 0;	for(i=0;i<inst->num_conns;i++){		DEBUG("rlm_ldap: ldap_get_conn: Checking Id: %d",i);		if ((pthread_mutex_trylock(&conns[i].mutex) == 0)) {			if (conns[i].locked == 1) {				/* connection is already being used */				pthread_mutex_unlock(&(conns[i].mutex));				continue;			}			/* found an unused connection */			*ret = &conns[i];			conns[i].locked = 1;			DEBUG("rlm_ldap: ldap_get_conn: Got Id: %d",i);			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;	const 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);	/* FIXME: detach */		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);	/* FIXME: detach */		return -1;#endif	}	/* 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);	memset(&flags, 0, sizeof(flags));	xlat_name = cf_section_name2(conf);	if (xlat_name != NULL){		char *group_name;		DICT_ATTR *dattr;		/*		 * Allocate room for <instance>-Ldap-Group

⌨️ 快捷键说明

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