示例#1
0
/*% Connects / reconnects to LDAP server */
static isc_result_t dlz_ldap_connect (ldap_instance_t * dbi, dbinstance_t * dbc)
{
    isc_result_t result;

    int ldap_result;

    /* if we have a connection, get ride of it. */
    if (dbc->dbconn != NULL)
    {
        ldap_unbind_s ((LDAP *) dbc->dbconn);
        dbc->dbconn = NULL;
    }

    /* now connect / reconnect. */

    /* initialize. */
    dbc->dbconn = ldap_init (dbi->hosts, LDAP_PORT);
    if (dbc->dbconn == NULL)
        return (ISC_R_NOMEMORY);

    /* set protocol version. */
    ldap_result = ldap_set_option ((LDAP *) dbc->dbconn, LDAP_OPT_PROTOCOL_VERSION, &(dbi->protocol));
    if (ldap_result != LDAP_SUCCESS)
    {
        result = ISC_R_NOPERM;
        goto cleanup;
    }

    /* "bind" to server.  i.e. send username / pass */
    ldap_result = ldap_bind_s ((LDAP *) dbc->dbconn, dbi->user, dbi->cred, dbi->method);
    if (ldap_result != LDAP_SUCCESS)
    {
        result = ISC_R_FAILURE;
        goto cleanup;
    }

    return (ISC_R_SUCCESS);

  cleanup:

    /* cleanup if failure. */
    if (dbc->dbconn != NULL)
    {
        ldap_unbind_s ((LDAP *) dbc->dbconn);
        dbc->dbconn = NULL;
    }

    return (result);
}
示例#2
0
DWORD
LwLdapBindDirectoryAnonymous(
    HANDLE hDirectory
    )
{
    DWORD dwError = 0;
    PLW_LDAP_DIRECTORY_CONTEXT pDirectory = (PLW_LDAP_DIRECTORY_CONTEXT)hDirectory;

    LW_BAIL_ON_INVALID_HANDLE(hDirectory);

    dwError = ldap_bind_s(
                    pDirectory->ld,
                    NULL,
                    NULL,
                    LDAP_AUTH_SIMPLE);
    BAIL_ON_LDAP_ERROR(dwError);

cleanup:

    return dwError;

error:

    LW_RTL_LOG_ERROR("Failed on LDAP simple bind (Error code: %u)", dwError);

    if(pDirectory->ld != NULL)
    {
        ldap_unbind_s(pDirectory->ld);
        pDirectory->ld = NULL;
    }

    goto cleanup;
}
示例#3
0
文件: testldap.c 项目: 0jpq0/kbengine
static void test_ldap_connection(abts_case *tc, LDAP *ldap)
{
    int version  = LDAP_VERSION3;
    int failures, result;
    
    /* always default to LDAP V3 */
    ldap_set_option(ldap, LDAP_OPT_PROTOCOL_VERSION, &version);

    for (failures=0; failures<10; failures++)
    {
        result = ldap_simple_bind_s(ldap,
                                    (char *)NULL,
                                    (char *)NULL);
        if (LDAP_SERVER_DOWN != result)
            break;
    }

    ABTS_TRUE(tc, result == LDAP_SUCCESS);
    if (result != LDAP_SUCCESS) {
        abts_log_message("%s\n", ldap_err2string(result));
    }

    ldap_unbind_s(ldap);

    return;
}
示例#4
0
/** unbind and clear variables */
static int _ldapfull_unbind(moddata_t data) {
    ldap_unbind_s(data->ld);
    data->ld = NULL;
    data->binded = 0;
    log_debug(ZONE, "unbinded from ldap server");
    return 0;
}
示例#5
0
/** connect to the ldap host */
static int _ldapfull_connect(moddata_t data)
{
    int ldapversion = LDAP_VERSION3;
    int rc;

    if(data->ld != NULL)
        ldap_unbind_s(data->ld);

    data->binded=0;

    rc = ldap_initialize(&(data->ld), data->uri);
    if( rc != LDAP_SUCCESS )
    {
        log_write(data->ar->c2s->log, LOG_ERR, "ldap: ldap_initialize failed, uri=%s (%d): %s", data->uri, rc, ldap_err2string(rc));
        return 1;
    }

    if (ldap_set_option(data->ld, LDAP_OPT_PROTOCOL_VERSION, &ldapversion) != LDAP_SUCCESS)
    {
        log_write(data->ar->c2s->log, LOG_ERR, "ldap: couldn't set v3 protocol");
        return 1;
    }

    if (ldap_set_option(data->ld, LDAP_OPT_REFERRALS, LDAP_OPT_ON) != LDAP_SUCCESS) {
        log_write(data->ar->c2s->log, LOG_ERR, "ldap: couldn't set LDAP_OPT_REFERRALS");
    }

    log_debug(ZONE, "connected to ldap server");

    return 0;
}
示例#6
0
void
dlz_ldap_destroy(void *driverarg, void *dbdata) {
	UNUSED(driverarg);

	if (dbdata != NULL) {
#ifdef ISC_PLATFORM_USETHREADS
		/* cleanup the list of DBI's */
		ldap_destroy_dblist((db_list_t *)
				    ((ldap_instance_t *)dbdata)->db);

#else /* ISC_PLATFORM_USETHREADS */
		if (((ldap_instance_t *)dbdata)->db->dbconn != NULL)
			ldap_unbind_s((LDAP *)
				      ((ldap_instance_t *)dbdata)->db->dbconn);

		/* destroy single DB instance */
		destroy_sqldbinstance(((ldap_instance_t *)dbdata)->db);
#endif /* ISC_PLATFORM_USETHREADS */

		if (((ldap_instance_t *)dbdata)->hosts != NULL)
			isc_mem_free(ns_g_mctx,
				     ((ldap_instance_t *)dbdata)->hosts);

		if (((ldap_instance_t *)dbdata)->user != NULL)
			isc_mem_free(ns_g_mctx,
				     ((ldap_instance_t *)dbdata)->user);

		if (((ldap_instance_t *)dbdata)->cred != NULL)
			isc_mem_free(ns_g_mctx,
				     ((ldap_instance_t *)dbdata)->cred);

		isc_mem_put(ns_g_mctx, dbdata, sizeof(ldap_instance_t));
	}
}
示例#7
0
/** Detach from the LDAP server and cleanup internal state.
 *
 */
static int mod_detach(void *instance)
{
	ldap_instance_t *inst = instance;

	fr_connection_pool_delete(inst->pool);

	if (inst->user_map) {
		talloc_free(inst->user_map);
	}

	/*
	 *	Keeping the dummy ld around for the lifetime
	 *	of the module should always work,
	 *	irrespective of what changes happen in libldap.
	 */
	if (inst->handle) {
#ifdef HAVE_LDAP_UNBIND_EXT_S
		ldap_unbind_ext_s(inst->handle, NULL, NULL);
#else
		ldap_unbind_s(inst->handle);
#endif
	}

	return 0;
}
示例#8
0
文件: user-mgr.c 项目: hfeeki/ccnet
static LDAP *ldap_init_and_bind (const char *host,
                                 const char *user_dn,
                                 const char *password)
{
    LDAP *ld;
    int res;
    int desired_version = LDAP_VERSION3;

    res = ldap_initialize (&ld, host);
    if (res != LDAP_SUCCESS) {
        ccnet_warning ("ldap_initialize failed: %s.\n", ldap_err2string(res));
        return NULL;
    }

    /* set the LDAP version to be 3 */
    res = ldap_set_option (ld, LDAP_OPT_PROTOCOL_VERSION, &desired_version);
    if (res != LDAP_OPT_SUCCESS) {
        ccnet_warning ("ldap_set_option failed: %s.\n", ldap_err2string(res));
        return NULL;
    }

    if (user_dn) {
        res = ldap_bind_s (ld, user_dn, password, LDAP_AUTH_SIMPLE);
        if (res != LDAP_SUCCESS ) {
            ccnet_warning ("ldap_bind failed: %s.\n", ldap_err2string(res));
            ldap_unbind_s (ld);
            return NULL;
        }
    }

    return ld;
}
示例#9
0
void
dlz_destroy(void *dbdata) {
	if (dbdata != NULL) {
		ldap_instance_t *db = (ldap_instance_t *)dbdata;
#if PTHREADS
		/* cleanup the list of DBI's */
		if (db->db != NULL)
			ldap_destroy_dblist((db_list_t *)(db->db));
#else /* PTHREADS */
		if (db->db->dbconn != NULL)
			ldap_unbind_s((LDAP *)(db->db->dbconn));

		/* destroy single DB instance */
		destroy_dbinstance(db->db);
#endif /* PTHREADS */

		if (db->hosts != NULL)
			free(db->hosts);
		if (db->user != NULL)
			free(db->user);
		if (db->cred != NULL)
			free(db->cred);
		free(dbdata);
	}
}
示例#10
0
/**
void  close_ldap_connection(LDAP* ld, int clear)

LDAPサーバとの接続を閉じる

@param  ld     LDAPサーバへのセッションハンドラ
@param  clear  TRUEの場合,大域変数 JBXLdapHost, JBXLdapDnBind も削除する.
*/
void  close_ldap_connection(LDAP* ld, int clear)
{
    if (clear==TRUE) {
        del_LDAP_Host(&JBXLdapHost);
        del_LDAP_Dn	 (&JBXLdapDnBind);
    }

    ldap_unbind_s(ld);
}
示例#11
0
static LDAP *ldap_init_and_bind (const char *host,
#ifdef WIN32
                                 gboolean use_ssl,
#endif
                                 const char *user_dn,
                                 const char *password)
{
    LDAP *ld;
    int res;
    int desired_version = LDAP_VERSION3;

#ifndef WIN32
    res = ldap_initialize (&ld, host);
    if (res != LDAP_SUCCESS) {
        ccnet_warning ("ldap_initialize failed: %s.\n", ldap_err2string(res));
        return NULL;
    }
#else
    char *host_copy = g_strdup (host);
    if (!use_ssl)
        ld = ldap_init (host_copy, LDAP_PORT);
    else
        ld = ldap_sslinit (host_copy, LDAP_SSL_PORT, 1);
    g_free (host_copy);
    if (!ld) {
        ccnet_warning ("ldap_init failed: %ul.\n", LdapGetLastError());
        return NULL;
    }
#endif

    /* set the LDAP version to be 3 */
    res = ldap_set_option (ld, LDAP_OPT_PROTOCOL_VERSION, &desired_version);
    if (res != LDAP_OPT_SUCCESS) {
        ccnet_warning ("ldap_set_option failed: %s.\n", ldap_err2string(res));
        return NULL;
    }

    if (user_dn) {
#ifndef WIN32
        res = ldap_bind_s (ld, user_dn, password, LDAP_AUTH_SIMPLE);
#else
        char *dn_copy = g_strdup(user_dn);
        char *password_copy = g_strdup(password);
        res = ldap_bind_s (ld, dn_copy, password_copy, LDAP_AUTH_SIMPLE);
        g_free (dn_copy);
        g_free (password_copy);
#endif
        if (res != LDAP_SUCCESS ) {
            ccnet_warning ("ldap_bind failed: %s.\n", ldap_err2string(res));
            ldap_unbind_s (ld);
            return NULL;
        }
    }

    return ld;
}
示例#12
0
//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
std::string LDAP_UNX::getDistinguishedName( const std::string userID,
	std::string *dname )
{
	*dname = "";
	LDAP *ldap = NULL;	// INITIALISE AND CONNECT TO LDAP SERVER
	std::string	e = initialize( &ldap );
	if ( ! e.empty() )
		{return( e );
		}
	std::string	base = ou + "," + dc;
	std::string	bparam = std::string("CN=LDAPbind,") + base;
	const	int 	ibind = ldap_simple_bind_s( ldap, bparam.c_str(),
		ldap_pw.c_str() );
	if ( ibind != LDAP_SUCCESS )
		{sprintf( ebuf, "ldap_simple_bind_s=%d", ibind );
		return( std::string(ebuf) );
		}
/* SEARCH FOR ENTRY WITH sAMAccountName AS GIVEN BY USER AND GET
 distinguishedName IF IT EXISTS (IF FOUND, THEN USERNAME EXISTS) */
	LDAPMessage *res = ( LDAPMessage * )NULL;
	std::string filter = "(sAMAccountName=" + userID + ")";
	const	int	isearch = ldap_search_s( ldap, base.c_str(),
		LDAP_SCOPE_ONELEVEL, filter.c_str(), ( char ** )NULL, 0, &res );
	if ( isearch != LDAP_SUCCESS )
		{sprintf( ebuf, "ldap_search_s=%d", isearch );
		return( std::string(ebuf) );
		}
	const	int	nentries = ldap_count_entries( ldap, res );
	if ( nentries <= 0 )
		{    // FAILED TO FIND distinguishedName from sAMAccountName
		ldap_msgfree( res );
		ldap_unbind_s( ldap );
		return( "Username not found in LDAP-OU" );
		}
					    // EXTRACT distinguishedNAme
	char 	*dn = ldap_get_dn( ldap, ldap_first_entry( ldap, res ) );
	*dname = std::string( dn );
	ldap_memfree( dn );			    		// TIDY UP
	ldap_msgfree( res );
	ldap_unbind_s( ldap );   			// DROP ASSOCIATION
	return( "" );
 }
示例#13
0
文件: qldap.c 项目: ajtulloch/qmail
static  int
qldap_close(qldap *q)
{
	CHECK(q, CLOSE);
	
	qldap_free_results(q); /* free results */
	/* close and free ldap connection */
	ldap_unbind_s(q->ld);
	q->state = CLOSE;
	return OK;
}
示例#14
0
文件: main.c 项目: meersjo/ldapfs
int main(int ac, char** av) {
  if (!(ld = auth_fldap()))
    return 255;
  openlog("slog", LOG_PID|LOG_CONS, LOG_USER);

  fuse_main(ac, av, &fldap_oper, NULL);
  ldap_unbind_s(ld);

  closelog();
  return 0;
}
示例#15
0
文件: ldap.c 项目: henrikhodne/rldap
static VALUE rldap_unbind(VALUE obj)
{
	RLDAP_WRAP *wrapper;
	int retval;
	
	wrapper = get_wrapper(obj);
	retval = ldap_unbind_s(wrapper->ld);
	if (retval != LDAP_SUCCESS)
		rldap_raise(retval);
	else
		return Qtrue;
}
示例#16
0
/* Like isc_result_check, only for LDAP */
void
ldap_result_check (char *msg, char *dn, int err)
{
  if ((err != LDAP_SUCCESS) && (err != LDAP_ALREADY_EXISTS))
    {
      fprintf(stderr, "Error while adding %s (%s):\n",
		      dn, msg);
      ldap_perror (conn, dn);
      ldap_unbind_s (conn);
      exit (-1);
    }
}
示例#17
0
/** entry-point function for following referrals, required in some cases by Active Directory */
static int rebindProc(LDAP *ld, LDAP_CONST char *url, ber_tag_t request, ber_int_t msgid, void *mdata)
{
    drvdata_t data = mdata;
    data->ld = ld;
    if(ldap_simple_bind_s(data->ld, data->binddn, data->bindpw)) {
        log_debug(ZONE, "ldapvcard: bind failed (to %s): %s", url, ldap_err2string(_ldap_get_lderrno(data->ld)));
        ldap_unbind_s(data->ld);
        data->ld = NULL;
        return LDAP_INAPPROPRIATE_AUTH;
    }

    return LDAP_SUCCESS;
}
示例#18
0
文件: ol_ldap.c 项目: hww3/pexts
/*
 **| method: int unbind();
 **|  Unbind from the bound server.
 **
 **| returns: the LDAP error code
 **
 **| note: this method uses the OpenLDAP synchronous interface.
 **
 **| see_also: the OpenLDAP v2 ldap_unbind(3) manual page.
 */
static void
f_ldap_unbind(INT32 args)
{
    if (THIS->bound) {
        THIS->lerrno = ldap_unbind_s(THIS->conn);
        THIS->bound = 0;
    } else
        THIS->lerrno = 0;
    
    pop_n_elems(args);

    push_int(THIS->lerrno);
}
示例#19
0
/*
 * @uid: user's uid, list all users if * is passed in.
 */
static int ldap_count_users (CcnetUserManager *manager, const char *uid)
{
    LDAP *ld = NULL;
    int res;
    GString *filter;
    char *filter_str;
    char *attrs[2];
    LDAPMessage *msg = NULL;

    ld = ldap_init_and_bind (manager->ldap_host,
#ifdef WIN32
                             manager->use_ssl,
#endif
                             manager->user_dn,
                             manager->password);
    if (!ld)
        return -1;

    filter = g_string_new (NULL);
    if (!manager->filter)
        g_string_printf (filter, "(%s=%s)", manager->login_attr, uid);
    else
        g_string_printf (filter, "(&(%s=%s) (%s))",
                         manager->login_attr, uid, manager->filter);
    filter_str = g_string_free (filter, FALSE);

    attrs[0] = manager->login_attr;
    attrs[1] = NULL;

    char **base;
    int count = 0;
    for (base = manager->base_list; *base; ++base) {
        res = ldap_search_s (ld, *base, LDAP_SCOPE_SUBTREE,
                             filter_str, attrs, 0, &msg);
        if (res != LDAP_SUCCESS) {
            ccnet_warning ("ldap_search failed: %s.\n", ldap_err2string(res));
            ldap_msgfree (msg);
            count = -1;
            goto out;
        }

        count += ldap_count_entries (ld, msg);
        ldap_msgfree (msg);
    }

out:
    g_free (filter_str);
    if (ld) ldap_unbind_s (ld);
    return count;
}
示例#20
0
/** Free any global libldap resources
 *
 */
void fr_ldap_free(void)
{
	if (--instance_count > 0) return;

	/*
	 *	Keeping the dummy ld around for the lifetime
	 *	of the module should always work,
	 *	irrespective of what changes happen in libldap.
	 */
#ifdef HAVE_LDAP_UNBIND_EXT_S
	ldap_unbind_ext_s(ldap_global_handle, NULL, NULL);
#else
	ldap_unbind_s(ldap_global_handle);
#endif
}
示例#21
0
void
LwLdapCloseDirectory(
    HANDLE hDirectory
    )
{
    PLW_LDAP_DIRECTORY_CONTEXT pDirectory = (PLW_LDAP_DIRECTORY_CONTEXT)hDirectory;

    if (pDirectory) {
        if(pDirectory->ld)
        {
            ldap_unbind_s(pDirectory->ld);
        }
        LwFreeMemory(pDirectory);
    }
    return;
}
示例#22
0
//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
std::string LDAP_UNX::authenticate( const std::string userID,
	const std::string password )
{
	std::string	dist_name;
	std::string	e = getDistinguishedName( userID, &dist_name );
	if ( ! e.empty() )
		{return( e );
		}
	LDAP *ldap = NULL;	// INITIALISE AND CONNECT TO LDAP SERVER
	e = initialize( &ldap );
	if ( ! e.empty() )
		{return( e );
		}
		// ATTEMPT TO BIND distinguishedName WITH PASSWORD GIVEN
	const	int	ibind = ldap_simple_bind_s( ldap, dist_name.c_str(),
		password.c_str() );
	ldap_unbind_s( ldap );
	return( ( LDAP_SUCCESS == ibind )
		?  "" : "Username/password mis-match" );
}
示例#23
0
/*%
 * Properly cleans up a list of database instances.
 * This function is only used when the driver is compiled for
 * multithreaded operation.
 */
static void
ldap_destroy_dblist(db_list_t *dblist) {
	dbinstance_t *ndbi = NULL;
	dbinstance_t *dbi = NULL;

	/* get the first DBI in the list */
	ndbi = DLZ_LIST_HEAD(*dblist);

	/* loop through the list */
	while (ndbi != NULL) {
		dbi = ndbi;
		/* get the next DBI in the list */
		ndbi = DLZ_LIST_NEXT(dbi, link);
		/* release DB connection */
		if (dbi->dbconn != NULL)
			ldap_unbind_s((LDAP *) dbi->dbconn);
		/* release all memory that comprised a DBI */
		destroy_dbinstance(dbi);
	}
	/* release memory for the list structure */
	free(dblist);
}
示例#24
0
文件: user-mgr.c 项目: hfeeki/ccnet
/*
 * @uid: user's uid, list all users if * is passed in.
 */
static int ldap_count_users (CcnetUserManager *manager, const char *uid)
{
    LDAP *ld = NULL;
    int res;
    GString *filter;
    char *filter_str;
    char *attrs[2];
    LDAPMessage *msg = NULL;
    int count = -1;

    ld = ldap_init_and_bind (manager->ldap_host,
                             manager->user_dn,
                             manager->password);
    if (!ld)
        return -1;

    filter = g_string_new (NULL);
    g_string_printf (filter, "(%s=%s)", manager->login_attr, uid);
    filter_str = g_string_free (filter, FALSE);

    attrs[0] = manager->login_attr;
    attrs[1] = NULL;

    res = ldap_search_s (ld, manager->base, LDAP_SCOPE_SUBTREE,
                         filter_str, attrs, 0, &msg);
    if (res != LDAP_SUCCESS) {
        ccnet_warning ("ldap_search failed: %s.\n", ldap_err2string(res));
        goto out;
    }

    count = ldap_count_entries (ld, msg);

out:
    ldap_msgfree (msg);
    g_free (filter_str);
    if (ld) ldap_unbind_s (ld);
    return count;
}
示例#25
0
handler_t auth_ldap_init(server *srv, mod_auth_plugin_config *s) {
#ifdef USE_LDAP
	int ret;
#if 0
	if (s->auth_ldap_basedn->used == 0) {
		log_error_write(srv, __FILE__, __LINE__, "s", "ldap: auth.backend.ldap.base-dn has to be set");

		return HANDLER_ERROR;
	}
#endif

	if (s->auth_ldap_hostname->used) {
		/* free old context */
		if (NULL != s->ldap) ldap_unbind_s(s->ldap);

		if (NULL == (s->ldap = ldap_init(s->auth_ldap_hostname->ptr, LDAP_PORT))) {
			log_error_write(srv, __FILE__, __LINE__, "ss", "ldap ...", strerror(errno));

			return HANDLER_ERROR;
		}

		ret = LDAP_VERSION3;
		if (LDAP_OPT_SUCCESS != (ret = ldap_set_option(s->ldap, LDAP_OPT_PROTOCOL_VERSION, &ret))) {
			log_error_write(srv, __FILE__, __LINE__, "ss", "ldap:", ldap_err2string(ret));

			return HANDLER_ERROR;
		}

		if (s->auth_ldap_starttls) {
			/* if no CA file is given, it is ok, as we will use encryption
				* if the server requires a CAfile it will tell us */
			if (!buffer_is_empty(s->auth_ldap_cafile)) {
				if (LDAP_OPT_SUCCESS != (ret = ldap_set_option(NULL, LDAP_OPT_X_TLS_CACERTFILE,
								s->auth_ldap_cafile->ptr))) {
					log_error_write(srv, __FILE__, __LINE__, "ss",
							"Loading CA certificate failed:", ldap_err2string(ret));

					return HANDLER_ERROR;
				}
			}

			if (LDAP_OPT_SUCCESS != (ret = ldap_start_tls_s(s->ldap, NULL,  NULL))) {
				log_error_write(srv, __FILE__, __LINE__, "ss", "ldap startTLS failed:", ldap_err2string(ret));

				return HANDLER_ERROR;
			}
		}


		/* 1. */
		if (s->auth_ldap_binddn->used) {
			if (LDAP_SUCCESS != (ret = ldap_simple_bind_s(s->ldap, s->auth_ldap_binddn->ptr, s->auth_ldap_bindpw->ptr))) {
				log_error_write(srv, __FILE__, __LINE__, "ss", "ldap:", ldap_err2string(ret));

				return HANDLER_ERROR;
			}
		} else {
			if (LDAP_SUCCESS != (ret = ldap_simple_bind_s(s->ldap, NULL, NULL))) {
				log_error_write(srv, __FILE__, __LINE__, "ss", "ldap:", ldap_err2string(ret));

				return HANDLER_ERROR;
			}
		}
	}
	return HANDLER_GO_ON;
#else
	UNUSED(s);
	log_error_write(srv, __FILE__, __LINE__, "s", "no ldap support available");
	return HANDLER_ERROR;
#endif
}
示例#26
0
void
add_to_rr_list (char *dn, char *name, char *type,
		char *data, unsigned int ttl, unsigned int flags)
{
  int i;
  int x;
  ldap_info *tmp;
  int attrlist;
  char ldap_type_buffer[128];
  char charttl[64];


  if ((tmp = locate_by_dn (dn)) == NULL)
    {

      /* There wasn't one already there, so we need to allocate a new one,
       * and stick it on the list */

      tmp = (ldap_info *) malloc (sizeof (ldap_info));
      if (tmp == (ldap_info *) NULL)
	{
	  fprintf (stderr, "malloc: %s\n", strerror (errno));
	  ldap_unbind_s (conn);
	  exit (-1);
	}

      tmp->dn = strdup (dn);
      tmp->attrs = (LDAPMod **) calloc (sizeof (LDAPMod *), flags);
      if (tmp->attrs == (LDAPMod **) NULL)
	{
	  fprintf (stderr, "calloc: %s\n", strerror (errno));
	  ldap_unbind_s (conn);
	  exit (-1);
	}

      for (i = 0; i < flags; i++)
	{
	  tmp->attrs[i] = (LDAPMod *) malloc (sizeof (LDAPMod));
	  if (tmp->attrs[i] == (LDAPMod *) NULL)
	    {
	      fprintf (stderr, "malloc: %s\n", strerror (errno));
	      exit (-1);
	    }
	}
      tmp->attrs[0]->mod_op = LDAP_MOD_ADD;
      tmp->attrs[0]->mod_type = "objectClass";

      if (flags == DNS_OBJECT)
	tmp->attrs[0]->mod_values = objectClasses;
      else
	{
	  tmp->attrs[0]->mod_values = topObjectClasses;
	  tmp->attrs[1] = NULL;
	  tmp->attrcnt = 2;
	  tmp->next = ldap_info_base;
	  ldap_info_base = tmp;
	  return;
	}

      tmp->attrs[1]->mod_op = LDAP_MOD_ADD;
      tmp->attrs[1]->mod_type = "relativeDomainName";
      tmp->attrs[1]->mod_values = (char **) calloc (sizeof (char *), 2);

      if (tmp->attrs[1]->mod_values == (char **)NULL)
	       exit(-1);

      tmp->attrs[1]->mod_values[0] = strdup (name);
      tmp->attrs[1]->mod_values[2] = NULL;

      sprintf (ldap_type_buffer, "%sRecord", type);

      tmp->attrs[2]->mod_op = LDAP_MOD_ADD;
      tmp->attrs[2]->mod_type = strdup (ldap_type_buffer);
      tmp->attrs[2]->mod_values = (char **) calloc (sizeof (char *), 2);

       if (tmp->attrs[2]->mod_values == (char **)NULL)
	       exit(-1);

      tmp->attrs[2]->mod_values[0] = strdup (data);
      tmp->attrs[2]->mod_values[1] = NULL;

      tmp->attrs[3]->mod_op = LDAP_MOD_ADD;
      tmp->attrs[3]->mod_type = "dNSTTL";
      tmp->attrs[3]->mod_values = (char **) calloc (sizeof (char *), 2);

      if (tmp->attrs[3]->mod_values == (char **)NULL)
	      exit(-1);

      sprintf (charttl, "%d", ttl);
      tmp->attrs[3]->mod_values[0] = strdup (charttl);
      tmp->attrs[3]->mod_values[1] = NULL;

      tmp->attrs[4]->mod_op = LDAP_MOD_ADD;
      tmp->attrs[4]->mod_type = "zoneName";
      tmp->attrs[4]->mod_values = (char **)calloc(sizeof(char *), 2);
      tmp->attrs[4]->mod_values[0] = gbl_zone;
      tmp->attrs[4]->mod_values[1] = NULL;

      tmp->attrs[5] = NULL;
      tmp->attrcnt = flags;
      tmp->next = ldap_info_base;
      ldap_info_base = tmp;
    }
  else
    {

      for (i = 0; tmp->attrs[i] != NULL; i++)
	{
	  sprintf (ldap_type_buffer, "%sRecord", type);
	  if (!strncmp
	      (ldap_type_buffer, tmp->attrs[i]->mod_type,
	       strlen (tmp->attrs[i]->mod_type)))
	    {
	      attrlist = get_attr_list_size (tmp->attrs[i]->mod_values);
	      tmp->attrs[i]->mod_values =
		(char **) realloc (tmp->attrs[i]->mod_values,
				   sizeof (char *) * (attrlist + 1));

	      if (tmp->attrs[i]->mod_values == (char **) NULL)
		{
		  fprintf (stderr, "realloc: %s\n", strerror (errno));
		  ldap_unbind_s (conn);
		  exit (-1);
		}
	      for (x = 0; tmp->attrs[i]->mod_values[x] != NULL; x++);

	      tmp->attrs[i]->mod_values[x] = strdup (data);
	      tmp->attrs[i]->mod_values[x + 1] = NULL;
	      return;
	    }
	}
      tmp->attrs =
	(LDAPMod **) realloc (tmp->attrs,
			      sizeof (LDAPMod) * ++(tmp->attrcnt));
      if (tmp->attrs == NULL)
	{
	  fprintf (stderr, "realloc: %s\n", strerror (errno));
	  ldap_unbind_s (conn);
	  exit (-1);
	}

      for (x = 0; tmp->attrs[x] != NULL; x++);
      tmp->attrs[x] = (LDAPMod *) malloc (sizeof (LDAPMod));
      tmp->attrs[x]->mod_op = LDAP_MOD_ADD;
      tmp->attrs[x]->mod_type = strdup (ldap_type_buffer);
      tmp->attrs[x]->mod_values = (char **) calloc (sizeof (char *), 2);
      tmp->attrs[x]->mod_values[0] = strdup (data);
      tmp->attrs[x]->mod_values[1] = NULL;
      tmp->attrs[x + 1] = NULL;
    }
}
示例#27
0
static switch_xml_t xml_ldap_search(const char *section, const char *tag_name, const char *key_name, const char *key_value, switch_event_t *params,
									void *user_data)
{
	xml_binding_t *binding = (xml_binding_t *) user_data;
	switch_event_header_t *hi;

	switch_xml_t xml = NULL, sub = NULL;

	struct ldap_c ldap_connection;
	struct ldap_c *ldap = &ldap_connection;

	int auth_method = LDAP_AUTH_SIMPLE;
	int desired_version = LDAP_VERSION3;
	xml_ldap_query_type_t query_type;
	char *dir_exten = NULL, *dir_domain = NULL;

	char *search_filter = NULL, *search_base = NULL;
	int off = 0, ret = 1;

	//char *buf;
	//buf = malloc(4096);


	if (!binding) {
		switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "No bindings...sorry bud returning now\n");
		return NULL;
	}

	if (!strcmp(section, "configuration")) {
		query_type = XML_LDAP_CONFIG;
	} else if (!strcmp(section, "directory")) {
		query_type = XML_LDAP_DIRECTORY;
	} else if (!strcmp(section, "dialplan")) {
		query_type = XML_LDAP_DIALPLAN;
	} else if (!strcmp(section, "phrases")) {
		query_type = XML_LDAP_PHRASE;
	} else if (!strcmp(section, "languages")) {
		query_type = XML_LDAP_LANGUAGE;
	} else {
		switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Invalid section\n");
		return NULL;
	}

	if (params) {
		if ((hi = params->headers)) {
			for (; hi; hi = hi->next) {
				switch (query_type) {
				case XML_LDAP_CONFIG:
					break;

				case XML_LDAP_DIRECTORY:
					if (!strcmp(hi->name, "user")) {
						dir_exten = strdup(hi->value);
					} else if (!strcmp(hi->name, "domain")) {
						dir_domain = strdup(hi->value);
					}
					break;

				case XML_LDAP_DIALPLAN:
				case XML_LDAP_PHRASE:
				case XML_LDAP_LANGUAGE:
					break;
				}
			}
			switch (query_type) {
			case XML_LDAP_CONFIG:
				break;

			case XML_LDAP_DIRECTORY:
				if (dir_exten && dir_domain) {
					if ((xml = switch_xml_new("directory"))) {
						switch_xml_set_attr_d(xml, "type", "freeswitch/xml");

						if ((sub = switch_xml_add_child_d(xml, "section", off++))) {
							switch_xml_set_attr_d(sub, "name", "directory");
						}

						if ((sub = switch_xml_add_child_d(sub, "domain", off++))) {
							switch_xml_set_attr_d(sub, "name", dir_domain);
						}

						if ((sub = switch_xml_add_child_d(sub, "user", off++))) {
							switch_xml_set_attr_d(sub, "id", dir_exten);
						}

					}

					search_filter = switch_mprintf(binding->filter, dir_exten);
					search_base = switch_mprintf(binding->basedn, dir_domain);

					free(dir_exten);
					dir_exten = NULL;

					free(dir_domain);
					dir_domain = NULL;

				} else {
					switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR,
									  "Something bad happened during the query construction phase likely exten(%s) or domain(%s) is null\n", dir_exten,
									  dir_domain);
					goto cleanup;
				}
				break;

			case XML_LDAP_DIALPLAN:
				if ((xml = switch_xml_new("document"))) {
					switch_xml_set_attr_d(xml, "type", "freeswitch/xml");

					if ((sub = switch_xml_add_child_d(xml, "section", off++))) {
						switch_xml_set_attr_d(sub, "name", "dialplan");
					}

					sub = switch_xml_add_child_d(xml, "context", off++);
				}

				break;

			case XML_LDAP_PHRASE:
			case XML_LDAP_LANGUAGE:
				break;
			}
		} else {
			goto cleanup;
		}
	}



	if ((ldap->ld = (LDAP *) ldap_init(binding->host, LDAP_PORT)) == NULL) {
		switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Unable to connect to ldap server.%s\n", binding->host);
		goto cleanup;
	}

	if (ldap_set_option(ldap->ld, LDAP_OPT_PROTOCOL_VERSION, &desired_version) != LDAP_OPT_SUCCESS) {
		goto cleanup;
	}

	ldap_set_option(ldap->ld, LDAP_OPT_X_SASL_SECPROPS, &ldap->sp);



	if (binding->binddn) {
		if (ldap_bind_s(ldap->ld, binding->binddn, binding->bindpass, auth_method) != LDAP_SUCCESS) {
			switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Unable to bind to ldap server %s as %s\n", binding->host, binding->binddn);
			goto cleanup;
		}
	} else {
		if (ldap_sasl_interactive_bind_s
			(ldap->ld, NULL, binding->defaults->mech, NULL, NULL, (unsigned) (intptr_t) LDAP_SASL_SIMPLE, lutil_sasl_interact,
			 binding->defaults) != LDAP_SUCCESS) {
			switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Unable to sasl_bind to ldap server %s as %s\n", binding->host,
							  binding->defaults->authcid);
			goto cleanup;
		}
	}

	if (ldap_search_s(ldap->ld, search_base, LDAP_SCOPE_SUBTREE, search_filter, NULL, 0, &ldap->msg) != LDAP_SUCCESS) {
		switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Query failed: -b \"%s\" \"%s\"\n", search_base, search_filter);
		goto cleanup;
	}

	if (ldap_count_entries(ldap->ld, ldap->msg) <= 0) {
		goto cleanup;
	}

	if (sub && xml_ldap_result(&ldap_connection, binding, &sub, &off, query_type) != SWITCH_STATUS_SUCCESS) {
		goto cleanup;
	}

	ret = 0;

  cleanup:
	if (ldap->msg) {
		ldap_msgfree(ldap->msg);
	}

	if (ldap->ld) {
		ldap_unbind_s(ldap->ld);
	}

	switch_safe_free(search_filter);
	switch_safe_free(search_base);

	//switch_xml_toxml_buf(xml,buf,0,0,1);
	//switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Providing:\n%s\n", buf);

	if (ret) {
		switch_xml_free(xml);
		return NULL;
	}

	return xml;
}
示例#28
0
文件: ldap.c 项目: GavinPayne/curl
static CURLcode Curl_ldap(struct connectdata *conn, bool *done)
{
  CURLcode result = CURLE_OK;
  int rc = 0;
  LDAP *server = NULL;
  LDAPURLDesc *ludp = NULL;
  LDAPMessage *ldapmsg = NULL;
  LDAPMessage *entryIterator;
  int num = 0;
  struct SessionHandle *data=conn->data;
  int ldap_proto = LDAP_VERSION3;
  int ldap_ssl = 0;
  char *val_b64 = NULL;
  size_t val_b64_sz = 0;
  curl_off_t dlsize = 0;
#ifdef LDAP_OPT_NETWORK_TIMEOUT
  struct timeval ldap_timeout = {10,0}; /* 10 sec connection/search timeout */
#endif

  *done = TRUE; /* unconditionally */
  infof(data, "LDAP local: LDAP Vendor = %s ; LDAP Version = %d\n",
          LDAP_VENDOR_NAME, LDAP_VENDOR_VERSION);
  infof(data, "LDAP local: %s\n", data->change.url);

#ifdef HAVE_LDAP_URL_PARSE
  rc = ldap_url_parse(data->change.url, &ludp);
#else
  rc = _ldap_url_parse(conn, &ludp);
#endif
  if(rc != 0) {
    failf(data, "LDAP local: %s", ldap_err2string(rc));
    result = CURLE_LDAP_INVALID_URL;
    goto quit;
  }

  /* Get the URL scheme ( either ldap or ldaps ) */
  if(conn->given->flags & PROTOPT_SSL)
    ldap_ssl = 1;
  infof(data, "LDAP local: trying to establish %s connection\n",
          ldap_ssl ? "encrypted" : "cleartext");

#ifdef LDAP_OPT_NETWORK_TIMEOUT
  ldap_set_option(NULL, LDAP_OPT_NETWORK_TIMEOUT, &ldap_timeout);
#endif
  ldap_set_option(NULL, LDAP_OPT_PROTOCOL_VERSION, &ldap_proto);

  if(ldap_ssl) {
#ifdef HAVE_LDAP_SSL
#ifdef CURL_LDAP_WIN
    /* Win32 LDAP SDK doesn't support insecure mode without CA! */
    server = ldap_sslinit(conn->host.name, (int)conn->port, 1);
    ldap_set_option(server, LDAP_OPT_SSL, LDAP_OPT_ON);
#else
    int ldap_option;
    char* ldap_ca = data->set.str[STRING_SSL_CAFILE];
#if defined(CURL_HAS_NOVELL_LDAPSDK)
    rc = ldapssl_client_init(NULL, NULL);
    if(rc != LDAP_SUCCESS) {
      failf(data, "LDAP local: ldapssl_client_init %s", ldap_err2string(rc));
      result = CURLE_SSL_CERTPROBLEM;
      goto quit;
    }
    if(data->set.ssl.verifypeer) {
      /* Novell SDK supports DER or BASE64 files. */
      int cert_type = LDAPSSL_CERT_FILETYPE_B64;
      if((data->set.str[STRING_CERT_TYPE]) &&
         (Curl_raw_equal(data->set.str[STRING_CERT_TYPE], "DER")))
        cert_type = LDAPSSL_CERT_FILETYPE_DER;
      if(!ldap_ca) {
        failf(data, "LDAP local: ERROR %s CA cert not set!",
              (cert_type == LDAPSSL_CERT_FILETYPE_DER ? "DER" : "PEM"));
        result = CURLE_SSL_CERTPROBLEM;
        goto quit;
      }
      infof(data, "LDAP local: using %s CA cert '%s'\n",
              (cert_type == LDAPSSL_CERT_FILETYPE_DER ? "DER" : "PEM"),
              ldap_ca);
      rc = ldapssl_add_trusted_cert(ldap_ca, cert_type);
      if(rc != LDAP_SUCCESS) {
        failf(data, "LDAP local: ERROR setting %s CA cert: %s",
                (cert_type == LDAPSSL_CERT_FILETYPE_DER ? "DER" : "PEM"),
                ldap_err2string(rc));
        result = CURLE_SSL_CERTPROBLEM;
        goto quit;
      }
      ldap_option = LDAPSSL_VERIFY_SERVER;
    }
    else
      ldap_option = LDAPSSL_VERIFY_NONE;
    rc = ldapssl_set_verify_mode(ldap_option);
    if(rc != LDAP_SUCCESS) {
      failf(data, "LDAP local: ERROR setting cert verify mode: %s",
              ldap_err2string(rc));
      result = CURLE_SSL_CERTPROBLEM;
      goto quit;
    }
    server = ldapssl_init(conn->host.name, (int)conn->port, 1);
    if(server == NULL) {
      failf(data, "LDAP local: Cannot connect to %s:%ld",
              conn->host.name, conn->port);
      result = CURLE_COULDNT_CONNECT;
      goto quit;
    }
#elif defined(LDAP_OPT_X_TLS)
    if(data->set.ssl.verifypeer) {
      /* OpenLDAP SDK supports BASE64 files. */
      if((data->set.str[STRING_CERT_TYPE]) &&
         (!Curl_raw_equal(data->set.str[STRING_CERT_TYPE], "PEM"))) {
        failf(data, "LDAP local: ERROR OpenLDAP only supports PEM cert-type!");
        result = CURLE_SSL_CERTPROBLEM;
        goto quit;
      }
      if(!ldap_ca) {
        failf(data, "LDAP local: ERROR PEM CA cert not set!");
        result = CURLE_SSL_CERTPROBLEM;
        goto quit;
      }
      infof(data, "LDAP local: using PEM CA cert: %s\n", ldap_ca);
      rc = ldap_set_option(NULL, LDAP_OPT_X_TLS_CACERTFILE, ldap_ca);
      if(rc != LDAP_SUCCESS) {
        failf(data, "LDAP local: ERROR setting PEM CA cert: %s",
                ldap_err2string(rc));
        result = CURLE_SSL_CERTPROBLEM;
        goto quit;
      }
      ldap_option = LDAP_OPT_X_TLS_DEMAND;
    }
    else
      ldap_option = LDAP_OPT_X_TLS_NEVER;

    rc = ldap_set_option(NULL, LDAP_OPT_X_TLS_REQUIRE_CERT, &ldap_option);
    if(rc != LDAP_SUCCESS) {
      failf(data, "LDAP local: ERROR setting cert verify mode: %s",
              ldap_err2string(rc));
      result = CURLE_SSL_CERTPROBLEM;
      goto quit;
    }
    server = ldap_init(conn->host.name, (int)conn->port);
    if(server == NULL) {
      failf(data, "LDAP local: Cannot connect to %s:%ld",
              conn->host.name, conn->port);
      result = CURLE_COULDNT_CONNECT;
      goto quit;
    }
    ldap_option = LDAP_OPT_X_TLS_HARD;
    rc = ldap_set_option(server, LDAP_OPT_X_TLS, &ldap_option);
    if(rc != LDAP_SUCCESS) {
      failf(data, "LDAP local: ERROR setting SSL/TLS mode: %s",
              ldap_err2string(rc));
      result = CURLE_SSL_CERTPROBLEM;
      goto quit;
    }
/*
    rc = ldap_start_tls_s(server, NULL, NULL);
    if(rc != LDAP_SUCCESS) {
      failf(data, "LDAP local: ERROR starting SSL/TLS mode: %s",
              ldap_err2string(rc));
      result = CURLE_SSL_CERTPROBLEM;
      goto quit;
    }
*/
#else
    /* we should probably never come up to here since configure
       should check in first place if we can support LDAP SSL/TLS */
    failf(data, "LDAP local: SSL/TLS not supported with this version "
            "of the OpenLDAP toolkit\n");
    result = CURLE_SSL_CERTPROBLEM;
    goto quit;
#endif
#endif
#endif /* CURL_LDAP_USE_SSL */
  }
  else {
    server = ldap_init(conn->host.name, (int)conn->port);
    if(server == NULL) {
      failf(data, "LDAP local: Cannot connect to %s:%ld",
              conn->host.name, conn->port);
      result = CURLE_COULDNT_CONNECT;
      goto quit;
    }
  }
#ifdef CURL_LDAP_WIN
  ldap_set_option(server, LDAP_OPT_PROTOCOL_VERSION, &ldap_proto);
#endif

  rc = ldap_simple_bind_s(server,
                          conn->bits.user_passwd ? conn->user : NULL,
                          conn->bits.user_passwd ? conn->passwd : NULL);
  if(!ldap_ssl && rc != 0) {
    ldap_proto = LDAP_VERSION2;
    ldap_set_option(server, LDAP_OPT_PROTOCOL_VERSION, &ldap_proto);
    rc = ldap_simple_bind_s(server,
                            conn->bits.user_passwd ? conn->user : NULL,
                            conn->bits.user_passwd ? conn->passwd : NULL);
  }
  if(rc != 0) {
    failf(data, "LDAP local: ldap_simple_bind_s %s", ldap_err2string(rc));
    result = CURLE_LDAP_CANNOT_BIND;
    goto quit;
  }

  rc = ldap_search_s(server, ludp->lud_dn, ludp->lud_scope,
                     ludp->lud_filter, ludp->lud_attrs, 0, &ldapmsg);

  if(rc != 0 && rc != LDAP_SIZELIMIT_EXCEEDED) {
    failf(data, "LDAP remote: %s", ldap_err2string(rc));
    result = CURLE_LDAP_SEARCH_FAILED;
    goto quit;
  }

  for(num = 0, entryIterator = ldap_first_entry(server, ldapmsg);
      entryIterator;
      entryIterator = ldap_next_entry(server, entryIterator), num++) {
    BerElement *ber = NULL;
    char  *attribute;       /*! suspicious that this isn't 'const' */
    char  *dn = ldap_get_dn(server, entryIterator);
    int i;

    result = Curl_client_write(conn, CLIENTWRITE_BODY, (char *)"DN: ", 4);
    if(result)
      goto quit;

    result = Curl_client_write(conn, CLIENTWRITE_BODY, (char *)dn, 0);
    if(result)
      goto quit;

    result = Curl_client_write(conn, CLIENTWRITE_BODY, (char *)"\n", 1);
    if(result)
      goto quit;

    dlsize += strlen(dn)+5;

    for(attribute = ldap_first_attribute(server, entryIterator, &ber);
        attribute;
        attribute = ldap_next_attribute(server, entryIterator, ber)) {
      BerValue **vals = ldap_get_values_len(server, entryIterator, attribute);

      if(vals != NULL) {
        for(i = 0; (vals[i] != NULL); i++) {
          result = Curl_client_write(conn, CLIENTWRITE_BODY, (char *)"\t", 1);
          if(result)
            goto quit;

          result = Curl_client_write(conn, CLIENTWRITE_BODY,
                                     (char *)attribute, 0);
          if(result)
            goto quit;

          result = Curl_client_write(conn, CLIENTWRITE_BODY, (char *)": ", 2);
          if(result)
            goto quit;
          dlsize += strlen(attribute)+3;

          if((strlen(attribute) > 7) &&
              (strcmp(";binary",
                      (char *)attribute +
                      (strlen((char *)attribute) - 7)) == 0)) {
            /* Binary attribute, encode to base64. */
            CURLcode error = Curl_base64_encode(data,
                                                vals[i]->bv_val,
                                                vals[i]->bv_len,
                                                &val_b64,
                                                &val_b64_sz);
            if(error) {
              ldap_value_free_len(vals);
              ldap_memfree(attribute);
              ldap_memfree(dn);
              if(ber)
                ber_free(ber, 0);
              result = error;
              goto quit;
            }
            if(val_b64_sz > 0) {
              result = Curl_client_write(conn, CLIENTWRITE_BODY, val_b64,
                                         val_b64_sz);
              free(val_b64);
              if(result)
                goto quit;
              dlsize += val_b64_sz;
            }
          }
          else {
            result = Curl_client_write(conn, CLIENTWRITE_BODY, vals[i]->bv_val,
                                       vals[i]->bv_len);
            if(result)
              goto quit;
            dlsize += vals[i]->bv_len;
          }
          result = Curl_client_write(conn, CLIENTWRITE_BODY, (char *)"\n", 0);
          if(result)
            goto quit;
          dlsize++;
        }

        /* Free memory used to store values */
        ldap_value_free_len(vals);
      }
      result = Curl_client_write(conn, CLIENTWRITE_BODY, (char *)"\n", 1);
      if(result)
        goto quit;
      dlsize++;
      Curl_pgrsSetDownloadCounter(data, dlsize);
      ldap_memfree(attribute);
    }
    ldap_memfree(dn);
    if(ber)
       ber_free(ber, 0);
  }

quit:
  if(ldapmsg) {
    ldap_msgfree(ldapmsg);
    LDAP_TRACE (("Received %d entries\n", num));
  }
  if(rc == LDAP_SIZELIMIT_EXCEEDED)
    infof(data, "There are more than %d entries\n", num);
  if(ludp)
    ldap_free_urldesc(ludp);
  if(server)
    ldap_unbind_s(server);
#if defined(HAVE_LDAP_SSL) && defined(CURL_HAS_NOVELL_LDAPSDK)
  if(ldap_ssl)
    ldapssl_client_deinit();
#endif /* HAVE_LDAP_SSL && CURL_HAS_NOVELL_LDAPSDK */

  /* no data to transfer */
  Curl_setup_transfer(conn, -1, -1, FALSE, NULL, -1, NULL);
  connclose(conn, "LDAP connection always disable re-use");

  return result;
}
示例#29
0
/**
* Get certificate from LDAP-Server.
*/
static int ldap_get_certificate(const char *login) {
	LDAP *ldap_connection;
	int entries;
	LDAPMessage *res;
	LDAPMessage *entry;
	struct berval **bvals = NULL;
	BerElement *ber = NULL;
	char *name = NULL;
	char filter_str[100];
	char *attrs[2];
	int rv = LDAP_SUCCESS;
	void *bv_val;

	char uri[4096];
	char uribuf[4096];
	char *uris[LDAP_CONFIG_URI_MAX + 1];
	const char *p;
	int current_uri = 0, start_uri = 0;

	char *buffer;
	size_t buflen;

	uris[0] = NULL;

	attrs[0] = (char *)attribute;
	attrs[1] = NULL;

	DBG1("ldap_get_certificate(): begin login = %s", login);

	/* Put the login to the %s in Filterstring */
	snprintf(filter_str, sizeof(filter_str), filter, login);

	DBG1("ldap_get_certificate(): filter_str = %s", filter_str);

	/* parse and split URI config entry */
	buffer = uribuf;
	buflen = sizeof (uribuf);

	strncpy(uri, ldapURI, sizeof (uri)-1);

	/* Add a space separated list of URIs */
	/* TODO: no spaces in one URI allowed => URL-encoding? */
	if(strncmp(ldapURI,"",1))
		for (p = uri; p != NULL; )
		{
			char *q = strchr (p, ' ');
			if (q != NULL)
				*q = '\0';

			if( strlen(p) > 1 ) /* SAW: don't add spaces */
				rv = ldap_add_uri (uris, p, &buffer, &buflen);

			p = (q != NULL) ? ++q : NULL;

			if (rv)
				break;
		}
    /* set the default port if no port is given */
  	if (ldapport == 0)
    {
		if (ssl_on == SSL_LDAPS)
		{
		  ldapport = LDAPS_PORT;
		}
		else
		{
		  ldapport = LDAP_PORT;
		}
	}

	/* add ldaphost to uris if set, nevermind "uri" is set in config */
	if( strlen(ldaphost) > 1 )
	{
		/* No port specified in URI and non-default port specified */
		snprintf (uri, sizeof (uri), "%s%s:%d",
		       ssl_on == SSL_LDAPS ? "ldaps://" : "ldap://",
		       ldaphost, ldapport);
		ldap_add_uri (uris, uri, &buffer, &buflen);
	}

  	if (uris[0] == NULL)
    {
		DBG("ldap_get_certificate(): Nor URI or usable Host entry found");
		return(-1);
    }

	/* Attempt to connect to specified URI in order until do_open succeed */
	start_uri = current_uri;
	do
	{
		if(uris[current_uri] != NULL)
			DBG1("ldap_get_certificate(): try do_open for %s", uris[current_uri]);
		rv = do_open(&ldap_connection, uris[current_uri], ldapport, ssl_on);
		/* hot-fix, because in some circumstances an LDAP_SERVER_DOWN is returned */
		if (rv != LDAP_UNAVAILABLE && rv != LDAP_SERVER_DOWN)
			break;
		current_uri++;

		if (uris[current_uri] == NULL)
			current_uri = 0;
	}
	while (current_uri != start_uri);

	if( rv != LDAP_SUCCESS )
	{
		DBG("ldap_get_certificate(): do_open failed");
		return(-2);
	}

	/* TODO: (1) The problem: if an working uri is found it is used
    	     and if there is an (SSL-)error, no other one is tried
    	     (2) There is no session, so we don't know which LDAP_Server
    	     is the last with a successful connection. So we try the same
    	     server again. Perhaps create a state file/smem/etc. ?
    */

	rv = ldap_search_s(
				ldap_connection,
				base,
				sscope[scope],
				filter_str,
				attrs,
				0,
				&res);
	if ( rv != LDAP_SUCCESS ) {
		DBG1("ldap_search_s() failed: %s", ldap_err2string(rv));
		ldap_unbind_s(ldap_connection);
		return(-3);
	} else {
		entries = ldap_count_entries(ldap_connection, res);
		DBG1("ldap_get_certificate(): entries = %d", entries);

		if( entries > 1 ) {
			DBG("!  Warning, more than one entry found. Please choose \"filter\" and");
			DBG("!  \"attribute\" in ldap mapper config section of your config,");
			DBG("!  that only one entry with one attribute is matched");
			DBG("!  Maybe there is another problem in ldap with not unique user");
			DBG("!  entries in your LDAP server.");
		}

		/* Only first entry is used. "filter" and "attribute"
		 *  should be choosen, so that only one entry with
		 * one attribute is returned */
		if ( NULL == (entry = ldap_first_entry(ldap_connection, res))){
			DBG("ldap_first_entry() failed: %s");
			ldap_unbind_s(ldap_connection);
			return(-4);
		}

		/* Only first attribute is used. See comment above... */
		if ( NULL == (name = ldap_first_attribute(ldap_connection, res, &ber))){
			DBG("ldap_first_attribute() failed (rc=%d)");
			ldap_unbind_s(ldap_connection);
			return(-5);
		}
		DBG1("attribute name = %s", name);

		bvals = ldap_get_values_len(ldap_connection, entry, name);
		certcnt = ldap_count_values_len(bvals);

		DBG1("number of user certificates = %d", certcnt);

		ldap_x509 = malloc(sizeof(X509*) * certcnt );
		if (NULL == ldap_x509)
		{
			DBG("not enough memory");
			return(-7);
		}

		rv = 0;
		while(rv < certcnt )
		{
			/* SaW: not nifty, but otherwise gcc doesn't optimize */
			bv_val = &bvals[rv]->bv_val;
#ifdef HAVE_NSS
			{
				SECItem derdata;
				derdata.data = bv_val;
				derdata.len = bvals[rv]->bv_len;

				ldap_x509[rv] = CERT_NewTempCertificate(CERT_GetDefaultCertDB(),
					&derdata, NULL, 0, 1);
			}
#else
			ldap_x509[rv] = d2i_X509(NULL, ((const unsigned char **) bv_val), bvals[rv]->bv_len);
#endif
			if (NULL == ldap_x509[rv]) {
				DBG1("d2i_X509() failed for certificate %d", rv);
				free(ldap_x509);
#ifdef HAVE_NSS
				{
					for (rv=0; rv<certcnt; rv++)
						if (ldap_x509[rv])
							CERT_DestroyCertificate(ldap_x509[rv]);
				}
#endif
				certcnt=0;
				ldap_msgfree(res);
				ldap_unbind_s(ldap_connection);
				return(-6);
			}else {
				DBG1("d2i_X509(): success for certificate %d", rv);
			}
			rv++;
		}
		ldap_msgfree(res);
		/* TODO: this leads to a segfault, but the doc said ... */
		/* ldap_value_free_len(bvals); */
	}
	if ( 0 != ldap_unbind_s(ldap_connection)) {
		DBG("ldap_unbind_s() failed.");
		ldap_perror(ldap_connection, "ldap_unbind_s() failed.");
		return(-1);
	};

	DBG("ldap_get_certificate(): end");
	return 1;
}
示例#30
0
CURLcode Curl_ldap(struct connectdata *conn)
{
  CURLcode status = CURLE_OK;
  int rc;
  void *(*ldap_init)(char *, int);
  int (*ldap_simple_bind_s)(void *, char *, char *);
  int (*ldap_unbind_s)(void *);
  int (*ldap_url_parse)(char *, LDAPURLDesc **);
  void (*ldap_free_urldesc)(void *);
  int (*ldap_search_s)(void *, char *, int, char *, char **, int, void **);
  int (*ldap_search_st)(void *, char *, int, char *, char **, int, void *, void **);
  void *(*ldap_first_entry)(void *, void *);
  void *(*ldap_next_entry)(void *, void *);
  char *(*ldap_err2string)(int);
  char *(*ldap_get_dn)(void *, void *);
  char *(*ldap_first_attribute)(void *, void *, void **);
  char *(*ldap_next_attribute)(void *, void *, void *);
  char **(*ldap_get_values)(void *, void *, char *);
  void (*ldap_value_free)(char **);
  void (*ldap_memfree)(void *);
  void (*ber_free)(void *, int);
 
  void *server;
  LDAPURLDesc *ludp;
  void *result;
  void *entryIterator;
  void *ber;
  void *attribute;

  struct SessionHandle *data=conn->data;
  
  infof(data, "LDAP: %s\n", data->change.url);

  DynaOpen();
  if (libldap == NULL) {
    failf(data, "The needed LDAP library/libraries couldn't be opened");
    return CURLE_LIBRARY_NOT_FOUND;
  }

  /* The types are needed because ANSI C distinguishes between
   * pointer-to-object (data) and pointer-to-function.
   */
  DYNA_GET_FUNCTION(void *(*)(char *, int), ldap_init);
  DYNA_GET_FUNCTION(int (*)(void *, char *, char *), ldap_simple_bind_s);
  DYNA_GET_FUNCTION(int (*)(void *), ldap_unbind_s);
  DYNA_GET_FUNCTION(int (*)(char *, LDAPURLDesc **), ldap_url_parse);
  DYNA_GET_FUNCTION(void (*)(void *), ldap_free_urldesc);
  DYNA_GET_FUNCTION(int (*)(void *, char *, int, char *, char **, int, void **), ldap_search_s);
  DYNA_GET_FUNCTION(int (*)(void *, char *, int, char *, char **, int, void *, void **), ldap_search_st);
  DYNA_GET_FUNCTION(void *(*)(void *, void *), ldap_first_entry);
  DYNA_GET_FUNCTION(void *(*)(void *, void *), ldap_next_entry);
  DYNA_GET_FUNCTION(char *(*)(int), ldap_err2string);
  DYNA_GET_FUNCTION(char *(*)(void *, void *), ldap_get_dn);
  DYNA_GET_FUNCTION(char *(*)(void *, void *, void **), ldap_first_attribute);
  DYNA_GET_FUNCTION(char *(*)(void *, void *, void *), ldap_next_attribute);
  DYNA_GET_FUNCTION(char **(*)(void *, void *, char *), ldap_get_values);
  DYNA_GET_FUNCTION(void (*)(char **), ldap_value_free);
  DYNA_GET_FUNCTION(void (*)(void *), ldap_memfree);
  DYNA_GET_FUNCTION(void (*)(void *, int), ber_free);
  
  server = ldap_init(conn->hostname, conn->port);
  if (server == NULL) {
    failf(data, "LDAP: Cannot connect to %s:%d",
	  conn->hostname, conn->port);
    status = CURLE_COULDNT_CONNECT;
  }
  else {
    rc = ldap_simple_bind_s(server,
                            conn->bits.user_passwd?conn->user:NULL,
                            conn->bits.user_passwd?conn->passwd:NULL);
    if (rc != 0) {
      failf(data, "LDAP: %s", ldap_err2string(rc));
      status = CURLE_LDAP_CANNOT_BIND;
    }
    else {
      rc = ldap_url_parse(data->change.url, &ludp);
      if (rc != 0) {
	failf(data, "LDAP: %s", ldap_err2string(rc));
	status = CURLE_LDAP_INVALID_URL;
      }
      else {
	rc = ldap_search_s(server, ludp->lud_dn, ludp->lud_scope,
                           ludp->lud_filter, ludp->lud_attrs, 0, &result);
	if (rc != 0) {
	  failf(data, "LDAP: %s", ldap_err2string(rc));
	  status = CURLE_LDAP_SEARCH_FAILED;
	}
	else {
	  for (entryIterator = ldap_first_entry(server, result);
	       entryIterator;
	       entryIterator = ldap_next_entry(server, entryIterator)) {
            char *dn = ldap_get_dn(server, entryIterator);
            char **vals;
            int i;
            
            Curl_client_write(data, CLIENTWRITE_BODY, (char *)"DN: ", 4);
            Curl_client_write(data, CLIENTWRITE_BODY, dn, 0);
            Curl_client_write(data, CLIENTWRITE_BODY, (char *)"\n", 1);
            for(attribute = ldap_first_attribute(server, entryIterator,
                                                 &ber); 
                attribute; 
                attribute = ldap_next_attribute(server, entryIterator,
                                                ber) ) {
              vals = ldap_get_values(server, entryIterator, attribute);
              if (vals != NULL) {
                for(i = 0; (vals[i] != NULL); i++) {
                  Curl_client_write(data, CLIENTWRITE_BODY, (char*)"\t", 1);
                  Curl_client_write(data, CLIENTWRITE_BODY, attribute, 0);
                  Curl_client_write(data, CLIENTWRITE_BODY, (char *)": ", 2);
                  Curl_client_write(data, CLIENTWRITE_BODY, vals[i], 0);
                  Curl_client_write(data, CLIENTWRITE_BODY, (char *)"\n", 0);
                }
              }

              /* Free memory used to store values */
              ldap_value_free(vals);
            }
            Curl_client_write(data, CLIENTWRITE_BODY, (char *)"\n", 1);
            
            ldap_memfree(attribute);
            ldap_memfree(dn);
            if (ber) ber_free(ber, 0);
          }
	}

	ldap_free_urldesc(ludp);
      }
      ldap_unbind_s(server);
    }
  }
  DynaClose();

  /* no data to transfer */
  Curl_Transfer(conn, -1, -1, FALSE, NULL, -1, NULL);
  
  return status;
}