Example #1
0
ADS_STATUS ads_sasl_bind(ADS_STRUCT *ads)
{
	const char *attrs[] = {"supportedSASLMechanisms", NULL};
	char **values;
	ADS_STATUS status;
	int i, j;
	LDAPMessage *res;

	/* get a list of supported SASL mechanisms */
	status = ads_do_search(ads, "", LDAP_SCOPE_BASE, "(objectclass=*)", attrs, &res);
	if (!ADS_ERR_OK(status)) return status;

	values = ldap_get_values(ads->ld, res, "supportedSASLMechanisms");

	/* try our supported mechanisms in order */
	for (i=0;sasl_mechanisms[i].name;i++) {
		/* see if the server supports it */
		for (j=0;values && values[j];j++) {
			if (strcmp(values[j], sasl_mechanisms[i].name) == 0) {
				DEBUG(4,("Found SASL mechanism %s\n", values[j]));
				status = sasl_mechanisms[i].fn(ads);
				ldap_value_free(values);
				ldap_msgfree(res);
				return status;
			}
		}
	}

	ldap_value_free(values);
	ldap_msgfree(res);
	return ADS_ERROR(LDAP_AUTH_METHOD_NOT_SUPPORTED);
}
Example #2
0
ADS_STATUS ads_sasl_bind(ADS_STRUCT *ads)
{
	const char *attrs[] = {"supportedSASLMechanisms", NULL};
	char **values;
	ADS_STATUS status;
	int i, j;
	LDAPMessage *res;
	struct ads_saslwrap *wrap = &ads->ldap_wrap_data;

	/* get a list of supported SASL mechanisms */
	status = ads_do_search(ads, "", LDAP_SCOPE_BASE, "(objectclass=*)", attrs, &res);
	if (!ADS_ERR_OK(status)) return status;

	values = ldap_get_values(ads->ldap.ld, res, "supportedSASLMechanisms");

	if (ads->auth.flags & ADS_AUTH_SASL_SEAL) {
		wrap->wrap_type = ADS_SASLWRAP_TYPE_SEAL;
	} else if (ads->auth.flags & ADS_AUTH_SASL_SIGN) {
		wrap->wrap_type = ADS_SASLWRAP_TYPE_SIGN;
	} else {
		wrap->wrap_type = ADS_SASLWRAP_TYPE_PLAIN;
	}

	/* try our supported mechanisms in order */
	for (i=0;sasl_mechanisms[i].name;i++) {
		/* see if the server supports it */
		for (j=0;values && values[j];j++) {
			if (strcmp(values[j], sasl_mechanisms[i].name) == 0) {
				DEBUG(4,("Found SASL mechanism %s\n", values[j]));
retry:
				status = sasl_mechanisms[i].fn(ads);
				if (status.error_type == ENUM_ADS_ERROR_LDAP &&
				    status.err.rc == LDAP_STRONG_AUTH_REQUIRED &&
				    wrap->wrap_type == ADS_SASLWRAP_TYPE_PLAIN)
				{
					DEBUG(3,("SASL bin got LDAP_STRONG_AUTH_REQUIRED "
						 "retrying with signing enabled\n"));
					wrap->wrap_type = ADS_SASLWRAP_TYPE_SIGN;
					goto retry;
				}
				ldap_value_free(values);
				ldap_msgfree(res);
				return status;
			}
		}
	}

	ldap_value_free(values);
	ldap_msgfree(res);
	return ADS_ERROR(LDAP_AUTH_METHOD_NOT_SUPPORTED);
}
Example #3
0
 ADS_STATUS cell_do_search(struct likewise_cell *c,
			  const char *search_base,
			  int scope,
			  const char *expr,
			  const char **attrs,
			  LDAPMessage ** msg)
{
	int search_count = 0;
	ADS_STATUS status;
	NTSTATUS nt_status;

	/* check for a NULL connection */

	if (!c->conn) {
		nt_status = cell_connect(c);
		if (!NT_STATUS_IS_OK(nt_status)) {
			status = ADS_ERROR_NT(nt_status);
			return status;
		}
	}

	DEBUG(10, ("cell_do_search: Base = %s,  Filter = %s, Scope = %d, GC = %s\n",
		   search_base, expr, scope,
		   c->conn->server.gc ? "yes" : "no"));

	/* we try multiple times in case the ADS_STRUCT is bad
	   and we need to reconnect */

	while (search_count < MAX_SEARCH_COUNT) {
		*msg = NULL;
		status = ads_do_search(c->conn, search_base,
				       scope, expr, attrs, msg);
		if (ADS_ERR_OK(status)) {
			if (DEBUGLEVEL >= 10) {
				LDAPMessage *e = NULL;

				int n = ads_count_replies(c->conn, *msg);

				DEBUG(10,("cell_do_search: Located %d entries\n", n));

				for (e=ads_first_entry(c->conn, *msg);
				     e!=NULL;
				     e = ads_next_entry(c->conn, e))
				{
					char *dn = ads_get_dn(c->conn, talloc_tos(), e);

					DEBUGADD(10,("   dn: %s\n", dn ? dn : "<NULL>"));
					TALLOC_FREE(dn);
				}
			}

			return status;
		}


		DEBUG(5, ("cell_do_search: search[%d] failed (%s)\n",
			  search_count, ads_errstr(status)));

		search_count++;

		/* Houston, we have a problem */

		if (status.error_type == ENUM_ADS_ERROR_LDAP) {
			switch (status.err.rc) {
			case LDAP_TIMELIMIT_EXCEEDED:
			case LDAP_TIMEOUT:
			case -1:	/* we get this error if we cannot contact
					   the LDAP server */
				nt_status = cell_connect(c);
				if (!NT_STATUS_IS_OK(nt_status)) {
					status = ADS_ERROR_NT(nt_status);
					return status;
				}
				break;
			default:
				/* we're all done here */
				return status;
			}
		}
	}

	DEBUG(5, ("cell_do_search: exceeded maximum search count!\n"));

	return ADS_ERROR_NT(NT_STATUS_UNSUCCESSFUL);
}
Example #4
0
/*
  a wrapper around ldap_search_s that retries depending on the error code
  this is supposed to catch dropped connections and auto-reconnect
*/
static ADS_STATUS ads_do_search_retry_internal(ADS_STRUCT *ads, const char *bind_path, int scope, 
					       const char *expr,
					       const char **attrs, void *args,
					       LDAPMessage **res)
{
	ADS_STATUS status = ADS_SUCCESS;
	int count = 3;
	char *bp;

	*res = NULL;

	if (!ads->ldap.ld &&
	    time_mono(NULL) - ads->ldap.last_attempt < ADS_RECONNECT_TIME) {
		return ADS_ERROR(LDAP_SERVER_DOWN);
	}

	bp = SMB_STRDUP(bind_path);

	if (!bp) {
		return ADS_ERROR(LDAP_NO_MEMORY);
	}

	*res = NULL;

	/* when binding anonymously, we cannot use the paged search LDAP
	 * control - Guenther */

	if (ads->auth.flags & ADS_AUTH_ANON_BIND) {
		status = ads_do_search(ads, bp, scope, expr, attrs, res);
	} else {
		status = ads_do_search_all_args(ads, bp, scope, expr, attrs, args, res);
	}
	if (ADS_ERR_OK(status)) {
               DEBUG(5,("Search for %s in <%s> gave %d replies\n",
                        expr, bp, ads_count_replies(ads, *res)));
		SAFE_FREE(bp);
		return status;
	}

	while (--count) {

		if (NT_STATUS_EQUAL(ads_ntstatus(status), NT_STATUS_IO_TIMEOUT) && ads->config.ldap_page_size >= 250) {
			int new_page_size = (ads->config.ldap_page_size / 2);
			DEBUG(1, ("Reducing LDAP page size from %d to %d due to IO_TIMEOUT\n",
				  ads->config.ldap_page_size, new_page_size));
			ads->config.ldap_page_size = new_page_size;
		}

		if (*res) 
			ads_msgfree(ads, *res);
		*res = NULL;

		DEBUG(3,("Reopening ads connection to realm '%s' after error %s\n", 
			 ads->config.realm, ads_errstr(status)));

		ads_disconnect(ads);
		status = ads_connect(ads);

		if (!ADS_ERR_OK(status)) {
			DEBUG(1,("ads_search_retry: failed to reconnect (%s)\n",
				 ads_errstr(status)));
			ads_destroy(&ads);
			SAFE_FREE(bp);
			return status;
		}

		*res = NULL;

		/* when binding anonymously, we cannot use the paged search LDAP
		 * control - Guenther */

		if (ads->auth.flags & ADS_AUTH_ANON_BIND) {
			status = ads_do_search(ads, bp, scope, expr, attrs, res);
		} else {
			status = ads_do_search_all_args(ads, bp, scope, expr, attrs, args, res);
		}

		if (ADS_ERR_OK(status)) {
			DEBUG(5,("Search for filter: %s, base: %s gave %d replies\n",
				 expr, bp, ads_count_replies(ads, *res)));
			SAFE_FREE(bp);
			return status;
		}
	}
        SAFE_FREE(bp);

	if (!ADS_ERR_OK(status)) {
		DEBUG(1,("ads reopen failed after error %s\n", 
			 ads_errstr(status)));
	}
	return status;
}