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

📄 smbldap.c

📁 samba-3.0.22.tar.gz 编译smb服务器的源码
💻 C
📖 第 1 页 / 共 3 页
字号:
	t = SMB_XMALLOC_P(struct smbldap_state_lookup);	ZERO_STRUCTP(t);		DLIST_ADD_END(smbldap_state_lookup_list, t, tmp);	t->ld = ld;	t->smbldap_state = smbldap_state;}/******************************************************************** start TLS on an existing LDAP connection*******************************************************************/int smb_ldap_start_tls(LDAP *ldap_struct, int version){ 	int rc;		if (lp_ldap_ssl() != LDAP_SSL_START_TLS) {		return LDAP_SUCCESS;	}	#ifdef LDAP_OPT_X_TLS	if (version != LDAP_VERSION3) {		DEBUG(0, ("Need LDAPv3 for Start TLS\n"));		return LDAP_OPERATIONS_ERROR;	}	if ((rc = ldap_start_tls_s (ldap_struct, NULL, NULL)) != LDAP_SUCCESS)	{		DEBUG(0,("Failed to issue the StartTLS instruction: %s\n",			 ldap_err2string(rc)));		return rc;	}	DEBUG (3, ("StartTLS issued: using a TLS connection\n"));	return LDAP_SUCCESS;#else	DEBUG(0,("StartTLS not supported by LDAP client libraries!\n"));	return LDAP_OPERATIONS_ERROR;#endif}/******************************************************************** setup a connection to the LDAP server based on a uri*******************************************************************/int smb_ldap_setup_conn(LDAP **ldap_struct, const char *uri){	int rc;	DEBUG(10, ("smb_ldap_setup_connection: %s\n", uri));	#ifdef HAVE_LDAP_INITIALIZE		rc = ldap_initialize(ldap_struct, uri);	if (rc) {		DEBUG(0, ("ldap_initialize: %s\n", ldap_err2string(rc)));	}	return rc;#else 	/* Parse the string manually */	{		int port = 0;		fstring protocol;		fstring host;		SMB_ASSERT(sizeof(protocol)>10 && sizeof(host)>254);		/* skip leading "URL:" (if any) */		if ( strnequal( uri, "URL:", 4 ) ) {			uri += 4;		}				sscanf(uri, "%10[^:]://%254[^:/]:%d", protocol, host, &port);				if (port == 0) {			if (strequal(protocol, "ldap")) {				port = LDAP_PORT;			} else if (strequal(protocol, "ldaps")) {				port = LDAPS_PORT;			} else {				DEBUG(0, ("unrecognised protocol (%s)!\n", protocol));			}		}				if ((*ldap_struct = ldap_init(host, port)) == NULL)	{			DEBUG(0, ("ldap_init failed !\n"));			return LDAP_OPERATIONS_ERROR;		}			        if (strequal(protocol, "ldaps")) {#ifdef LDAP_OPT_X_TLS			int tls = LDAP_OPT_X_TLS_HARD;			if (ldap_set_option (*ldap_struct, LDAP_OPT_X_TLS, &tls) != LDAP_SUCCESS)			{				DEBUG(0, ("Failed to setup a TLS session\n"));			}						DEBUG(3,("LDAPS option set...!\n"));#else			DEBUG(0,("smbldap_open_connection: Secure connection not supported by LDAP client libraries!\n"));			return LDAP_OPERATIONS_ERROR;#endif /* LDAP_OPT_X_TLS */		}	}#endif /* HAVE_LDAP_INITIALIZE */	return LDAP_SUCCESS;}/******************************************************************** try to upgrade to Version 3 LDAP if not already, in either case return current version  *******************************************************************/int smb_ldap_upgrade_conn(LDAP *ldap_struct, int *new_version) {	int version;	int rc;		/* assume the worst */	*new_version = LDAP_VERSION2;	rc = ldap_get_option(ldap_struct, LDAP_OPT_PROTOCOL_VERSION, &version);	if (rc) {		return rc;	}	if (version == LDAP_VERSION3) {		*new_version = LDAP_VERSION3;		return LDAP_SUCCESS;	}	/* try upgrade */	version = LDAP_VERSION3;	rc = ldap_set_option (ldap_struct, LDAP_OPT_PROTOCOL_VERSION, &version);	if (rc) {		return rc;	}			*new_version = LDAP_VERSION3;	return LDAP_SUCCESS;}/******************************************************************* open a connection to the ldap server (just until the bind) ******************************************************************/int smb_ldap_setup_full_conn(LDAP **ldap_struct, const char *uri){	int rc, version;	rc = smb_ldap_setup_conn(ldap_struct, uri);	if (rc) {		return rc;	}	rc = smb_ldap_upgrade_conn(*ldap_struct, &version);	if (rc) {		return rc;	}	rc = smb_ldap_start_tls(*ldap_struct, version);	if (rc) {		return rc;	}	return LDAP_SUCCESS;}/******************************************************************* open a connection to the ldap server.******************************************************************/static int smbldap_open_connection (struct smbldap_state *ldap_state){	int rc = LDAP_SUCCESS;	int version;	LDAP **ldap_struct = &ldap_state->ldap_struct;	rc = smb_ldap_setup_conn(ldap_struct, ldap_state->uri);	if (rc) {		return rc;	}	/* Store the LDAP pointer in a lookup list */	smbldap_store_state(*ldap_struct, ldap_state);	/* Upgrade to LDAPv3 if possible */	rc = smb_ldap_upgrade_conn(*ldap_struct, &version);	if (rc) {		return rc;	}	/* Start TLS if required */	rc = smb_ldap_start_tls(*ldap_struct, version);	if (rc) {		return rc;	}		DEBUG(2, ("smbldap_open_connection: connection opened\n"));	return rc;}/******************************************************************* a rebind function for authenticated referrals This version takes a void* that we can shove useful stuff in :-)******************************************************************/#if defined(LDAP_API_FEATURE_X_OPENLDAP) && (LDAP_API_VERSION > 2000)#elsestatic int rebindproc_with_state  (LDAP * ld, char **whop, char **credp, 				   int *methodp, int freeit, void *arg){	struct smbldap_state *ldap_state = arg;		/** @TODO Should we be doing something to check what servers we rebind to?	    Could we get a referral to a machine that we don't want to give our	    username and password to? */		if (freeit) {		SAFE_FREE(*whop);		memset(*credp, '\0', strlen(*credp));		SAFE_FREE(*credp);	} else {		DEBUG(5,("rebind_proc_with_state: Rebinding as \"%s\"\n", 			  ldap_state->bind_dn));		*whop = SMB_STRDUP(ldap_state->bind_dn);		if (!*whop) {			return LDAP_NO_MEMORY;		}		*credp = SMB_STRDUP(ldap_state->bind_secret);		if (!*credp) {			SAFE_FREE(*whop);			return LDAP_NO_MEMORY;		}		*methodp = LDAP_AUTH_SIMPLE;	}	GetTimeOfDay(&ldap_state->last_rebind);			return 0;}#endif /*defined(LDAP_API_FEATURE_X_OPENLDAP) && (LDAP_API_VERSION > 2000)*//******************************************************************* a rebind function for authenticated referrals This version takes a void* that we can shove useful stuff in :-) and actually does the connection.******************************************************************/#if defined(LDAP_API_FEATURE_X_OPENLDAP) && (LDAP_API_VERSION > 2000)static int rebindproc_connect_with_state (LDAP *ldap_struct, 					  LDAP_CONST char *url, 					  ber_tag_t request,					  ber_int_t msgid, void *arg){	struct smbldap_state *ldap_state = arg;	int rc;	int version;	DEBUG(5,("rebindproc_connect_with_state: Rebinding to %s as \"%s\"\n", 		 url, ldap_state->bind_dn));	/* call START_TLS again (ldaps:// is handled by the OpenLDAP library	 * itself) before rebinding to another LDAP server to avoid to expose	 * our credentials. At least *try* to secure the connection - Guenther */	smb_ldap_upgrade_conn(ldap_struct, &version);	smb_ldap_start_tls(ldap_struct, version);	/** @TODO Should we be doing something to check what servers we rebind to?	    Could we get a referral to a machine that we don't want to give our	    username and password to? */	rc = ldap_simple_bind_s(ldap_struct, ldap_state->bind_dn, ldap_state->bind_secret);		GetTimeOfDay(&ldap_state->last_rebind);	return rc;}#endif /*defined(LDAP_API_FEATURE_X_OPENLDAP) && (LDAP_API_VERSION > 2000)*//******************************************************************* Add a rebind function for authenticated referrals******************************************************************/#if defined(LDAP_API_FEATURE_X_OPENLDAP) && (LDAP_API_VERSION > 2000)#else# if LDAP_SET_REBIND_PROC_ARGS == 2static int rebindproc (LDAP *ldap_struct, char **whop, char **credp,		       int *method, int freeit ){	struct smbldap_state *ldap_state = smbldap_find_state(ldap_struct);	return rebindproc_with_state(ldap_struct, whop, credp,				     method, freeit, ldap_state);	}# endif /*LDAP_SET_REBIND_PROC_ARGS == 2*/#endif /*defined(LDAP_API_FEATURE_X_OPENLDAP) && (LDAP_API_VERSION > 2000)*//******************************************************************* a rebind function for authenticated referrals this also does the connection, but no void*.******************************************************************/#if defined(LDAP_API_FEATURE_X_OPENLDAP) && (LDAP_API_VERSION > 2000)# if LDAP_SET_REBIND_PROC_ARGS == 2static int rebindproc_connect (LDAP * ld, LDAP_CONST char *url, int request,			       ber_int_t msgid){	struct smbldap_state *ldap_state = smbldap_find_state(ld);	return rebindproc_connect_with_state(ld, url, (ber_tag_t)request, msgid, 					     ldap_state);}# endif /*LDAP_SET_REBIND_PROC_ARGS == 2*/#endif /*defined(LDAP_API_FEATURE_X_OPENLDAP) && (LDAP_API_VERSION > 2000)*//******************************************************************* connect to the ldap server under system privilege.******************************************************************/static int smbldap_connect_system(struct smbldap_state *ldap_state, LDAP * ldap_struct){	int rc;	char *ldap_dn;	char *ldap_secret;	int version;	/* get the password */	if (!fetch_ldap_pw(&ldap_dn, &ldap_secret)) {		DEBUG(0, ("ldap_connect_system: Failed to retrieve password from secrets.tdb\n"));		return LDAP_INVALID_CREDENTIALS;	}	ldap_state->bind_dn = ldap_dn;	ldap_state->bind_secret = ldap_secret;	/* removed the sasl_bind_s "EXTERNAL" stuff, as my testsuite 	   (OpenLDAP) doesnt' seem to support it */	   	DEBUG(10,("ldap_connect_system: Binding to ldap server %s as \"%s\"\n",		  ldap_state->uri, ldap_dn));#if defined(LDAP_API_FEATURE_X_OPENLDAP) && (LDAP_API_VERSION > 2000)# if LDAP_SET_REBIND_PROC_ARGS == 2		ldap_set_rebind_proc(ldap_struct, &rebindproc_connect);	# endif# if LDAP_SET_REBIND_PROC_ARGS == 3		ldap_set_rebind_proc(ldap_struct, &rebindproc_connect_with_state, (void *)ldap_state);	# endif#else /*defined(LDAP_API_FEATURE_X_OPENLDAP) && (LDAP_API_VERSION > 2000)*/# if LDAP_SET_REBIND_PROC_ARGS == 2		ldap_set_rebind_proc(ldap_struct, &rebindproc);	# endif# if LDAP_SET_REBIND_PROC_ARGS == 3		ldap_set_rebind_proc(ldap_struct, &rebindproc_with_state, (void *)ldap_state);	# endif#endif /*defined(LDAP_API_FEATURE_X_OPENLDAP) && (LDAP_API_VERSION > 2000)*/	rc = ldap_simple_bind_s(ldap_struct, ldap_dn, ldap_secret);	if (rc != LDAP_SUCCESS) {		char *ld_error = NULL;		ldap_get_option(ldap_state->ldap_struct, LDAP_OPT_ERROR_STRING,				&ld_error);		DEBUG(ldap_state->num_failures ? 2 : 0,		      ("failed to bind to server %s with dn=\"%s\" Error: %s\n\t%s\n",			       ldap_state->uri,			       ldap_dn ? ldap_dn : "(unknown)", ldap_err2string(rc),			       ld_error ? ld_error : "(unknown)"));		SAFE_FREE(ld_error);		ldap_state->num_failures++;		return rc;	}	ldap_state->num_failures = 0;	ldap_state->paged_results = False;	ldap_get_option(ldap_state->ldap_struct, LDAP_OPT_PROTOCOL_VERSION, &version);	if (smbldap_has_control(ldap_state, ADS_PAGE_CTL_OID) && version == 3) {		ldap_state->paged_results = True;	}	DEBUG(3, ("ldap_connect_system: succesful connection to the LDAP server\n"));	DEBUGADD(10, ("ldap_connect_system: LDAP server %s support paged results\n", 		ldap_state->paged_results ? "does" : "does not"));	return rc;}/********************************************************************** Connect to LDAP server (called before every ldap operation)*********************************************************************/static int smbldap_open(struct smbldap_state *ldap_state){	int rc, opt_rc;	BOOL reopen = False;	SMB_ASSERT(ldap_state);		#ifndef NO_LDAP_SECURITY	if (geteuid() != 0) {		DEBUG(0, ("smbldap_open: cannot access LDAP when not root..\n"));		return  LDAP_INSUFFICIENT_ACCESS;	}#endif	if ((ldap_state->ldap_struct != NULL) && ((ldap_state->last_ping + SMBLDAP_DONT_PING_TIME) < time(NULL))) {		struct sockaddr_un addr;		socklen_t len = sizeof(addr);		int sd;		opt_rc = ldap_get_option(ldap_state->ldap_struct, LDAP_OPT_DESC, &sd);		if (opt_rc == 0 && (getpeername(sd, (struct sockaddr *) &addr, &len)) < 0 )			reopen = True;#ifdef HAVE_UNIXSOCKET		if (opt_rc == 0 && addr.sun_family == AF_UNIX)			reopen = True;#endif		if (reopen) {		    	/* the other end has died. reopen. */		    	ldap_unbind_ext(ldap_state->ldap_struct, NULL, NULL);		    	ldap_state->ldap_struct = NULL;		    	ldap_state->last_ping = (time_t)0;		} else {			ldap_state->last_ping = time(NULL);		}     	}	if (ldap_state->ldap_struct != NULL) {		DEBUG(11,("smbldap_open: already connected to the LDAP server\n"));		return LDAP_SUCCESS;	}	if ((rc = smbldap_open_connection(ldap_state))) {		return rc;	}	if ((rc = smbldap_connect_system(ldap_state, ldap_state->ldap_struct))) {		ldap_unbind_ext(ldap_state->ldap_struct, NULL, NULL);		ldap_state->ldap_struct = NULL;		return rc;	}	ldap_state->last_ping = time(NULL);	ldap_state->pid = sys_getpid();	DEBUG(4,("The LDAP server is succesfully connected\n"));	return LDAP_SUCCESS;}/**********************************************************************Disconnect from LDAP server *********************************************************************/static NTSTATUS smbldap_close(struct smbldap_state *ldap_state){	if (!ldap_state)		return NT_STATUS_INVALID_PARAMETER;			if (ldap_state->ldap_struct != NULL) {		ldap_unbind_ext(ldap_state->ldap_struct, NULL, NULL);		ldap_state->ldap_struct = NULL;	}	smbldap_delete_state(ldap_state);		DEBUG(5,("The connection to the LDAP server was closed\n"));	/* maybe free the results here --metze */			return NT_STATUS_OK;}static BOOL got_alarm;static void (*old_handler)(int);static void gotalarm_sig(int dummy){	got_alarm = True;}static int another_ldap_try(struct smbldap_state *ldap_state, int *rc,			    int *attempts, time_t endtime){	time_t now = time(NULL);	int open_rc = LDAP_SERVER_DOWN;	if (*rc != LDAP_SERVER_DOWN)		goto no_next;	if (now >= endtime) {		smbldap_close(ldap_state);		*rc = LDAP_TIMEOUT;		goto no_next;	}	if (*attempts == 0) {		got_alarm = False;		old_handler = CatchSignal(SIGALRM, gotalarm_sig);		alarm(endtime - now);		if (ldap_state->pid != sys_getpid())			smbldap_close(ldap_state);	}	while (1) {		if (*attempts != 0)			smb_msleep(1000);

⌨️ 快捷键说明

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