コード例 #1
0
ファイル: hdb-ldap.c プロジェクト: alepharchives/bitrig
static krb5_error_code
LDAP_remove(krb5_context context, HDB * db, hdb_entry * entry)
{
    krb5_error_code ret;
    LDAPMessage *msg, *e;
    char *dn = NULL;
    int rc, limit = LDAP_NO_LIMIT;

    ret = LDAP_principal2message(context, db, entry->principal, &msg);
    if (ret)
	goto out;

    e = ldap_first_entry(HDB2LDAP(db), msg);
    if (e == NULL) {
	ret = HDB_ERR_NOENTRY;
	goto out;
    }

    dn = ldap_get_dn(HDB2LDAP(db), e);
    if (dn == NULL) {
	ret = HDB_ERR_NOENTRY;
	goto out;
    }

    rc = ldap_set_option(HDB2LDAP(db), LDAP_OPT_SIZELIMIT, (const void *)&limit);
    if (rc != LDAP_SUCCESS) {
	krb5_set_error_string(context, "ldap_set_option: %s",
			      ldap_err2string(rc));
	ret = HDB_ERR_BADVERSION;
	goto out;
    }

    rc = ldap_delete_s(HDB2LDAP(db), dn);
    if (check_ldap(context, db, rc)) {
	krb5_set_error_string(context, "ldap_delete_s: %s", 
			      ldap_err2string(rc));
	ret = HDB_ERR_CANT_LOCK_DB;
    } else
	ret = 0;

  out:
    if (dn != NULL)
	free(dn);
    if (msg != NULL)
	ldap_msgfree(msg);

    return ret;
}
コード例 #2
0
static krb5_error_code
LDAP_dn2principal(krb5_context context, HDB * db, const char *dn,
		  krb5_principal * principal)
{
    krb5_error_code ret;
    int rc;
    const char *filter = "(objectClass=krb5Principal)";
    LDAPMessage *res = NULL, *e;
    char *p;

    ret = LDAP_no_size_limit(context, HDB2LDAP(db));
    if (ret)
	goto out;

    rc = ldap_search_ext_s(HDB2LDAP(db), dn, LDAP_SCOPE_SUBTREE,
			   filter, krb5principal_attrs, 0,
			   NULL, NULL, NULL,
			   0, &res);
    if (check_ldap(context, db, rc)) {
	ret = HDB_ERR_NOENTRY;
	krb5_set_error_message(context, ret, "ldap_search_ext_s: "
			       "filter: %s error: %s",
			       filter, ldap_err2string(rc));
	goto out;
    }

    e = ldap_first_entry(HDB2LDAP(db), res);
    if (e == NULL) {
	ret = HDB_ERR_NOENTRY;
	goto out;
    }

    ret = LDAP_get_string_value(db, e, "krb5PrincipalName", &p);
    if (ret) {
	ret = HDB_ERR_NOENTRY;
	goto out;
    }

    ret = krb5_parse_name(context, p, principal);
    free(p);

  out:
    if (res)
	ldap_msgfree(res);

    return ret;
}
コード例 #3
0
ファイル: hdb-ldap.c プロジェクト: alepharchives/bitrig
static krb5_error_code
LDAP_dn2principal(krb5_context context, HDB * db, const char *dn,
		  krb5_principal * principal)
{
    krb5_error_code ret;
    int rc;
    char **values;
    LDAPMessage *res = NULL, *e;

    ret = LDAP_no_size_limit(context, HDB2LDAP(db));
    if (ret)
	goto out;

    rc = ldap_search_s(HDB2LDAP(db), dn, LDAP_SCOPE_SUBTREE,
		       "(objectClass=krb5Principal)", krb5principal_attrs,
		       0, &res);
    if (check_ldap(context, db, rc)) {
	krb5_set_error_string(context, "ldap_search_s: %s",
			      ldap_err2string(rc));
	ret = HDB_ERR_NOENTRY;
	goto out;
    }

    e = ldap_first_entry(HDB2LDAP(db), res);
    if (e == NULL) {
	ret = HDB_ERR_NOENTRY;
	goto out;
    }

    values = ldap_get_values(HDB2LDAP(db), e, "krb5PrincipalName");
    if (values == NULL) {
	ret = HDB_ERR_NOENTRY;
	goto out;
    }

    ret = krb5_parse_name(context, values[0], principal);
    ldap_value_free(values);

  out:
    if (res)
	ldap_msgfree(res);

    return ret;
}
コード例 #4
0
ファイル: simple.c プロジェクト: zabbix/zabbix
int	check_service(AGENT_REQUEST *request, const char *default_addr, AGENT_RESULT *result, int perf)
{
	unsigned short	port = 0;
	char		*service, *ip_str, ip[MAX_ZBX_DNSNAME_LEN + 1], *port_str;
	int		value_int, ret = SYSINFO_RET_FAIL;
	double		check_time;

	check_time = zbx_time();

	if (3 < request->nparam)
	{
		SET_MSG_RESULT(result, zbx_strdup(NULL, "Too many parameters."));
		return SYSINFO_RET_FAIL;
	}

	service = get_rparam(request, 0);
	ip_str = get_rparam(request, 1);
	port_str = get_rparam(request, 2);

	if (NULL == service || '\0' == *service)
	{
		SET_MSG_RESULT(result, zbx_strdup(NULL, "Invalid first parameter."));
		return SYSINFO_RET_FAIL;
	}

	if (NULL == ip_str || '\0' == *ip_str)
		strscpy(ip, default_addr);
	else
		strscpy(ip, ip_str);

	if (NULL != port_str && '\0' != *port_str && SUCCEED != is_ushort(port_str, &port))
	{
		SET_MSG_RESULT(result, zbx_strdup(NULL, "Invalid third parameter."));
		return SYSINFO_RET_FAIL;
	}

	if (0 == strncmp("net.tcp.service", get_rkey(request), 15))
	{
		if (0 == strcmp(service, "ssh"))
		{
			if (NULL == port_str || '\0' == *port_str)
				port = ZBX_DEFAULT_SSH_PORT;
			ret = check_ssh(ip, port, CONFIG_TIMEOUT, &value_int);
		}
		else if (0 == strcmp(service, "ldap"))
		{
#ifdef HAVE_LDAP
			if (NULL == port_str || '\0' == *port_str)
				port = ZBX_DEFAULT_LDAP_PORT;
			ret = check_ldap(ip, port, CONFIG_TIMEOUT, &value_int);
#else
			SET_MSG_RESULT(result, zbx_strdup(NULL, "Support for LDAP check was not compiled in."));
#endif
		}
		else if (0 == strcmp(service, "smtp"))
		{
			if (NULL == port_str || '\0' == *port_str)
				port = ZBX_DEFAULT_SMTP_PORT;
			ret = tcp_expect(ip, port, CONFIG_TIMEOUT, NULL, validate_smtp, "QUIT\r\n", &value_int);
		}
		else if (0 == strcmp(service, "ftp"))
		{
			if (NULL == port_str || '\0' == *port_str)
				port = ZBX_DEFAULT_FTP_PORT;
			ret = tcp_expect(ip, port, CONFIG_TIMEOUT, NULL, validate_ftp, "QUIT\r\n", &value_int);
		}
		else if (0 == strcmp(service, "http"))
		{
			if (NULL == port_str || '\0' == *port_str)
				port = ZBX_DEFAULT_HTTP_PORT;
			ret = tcp_expect(ip, port, CONFIG_TIMEOUT, NULL, NULL, NULL, &value_int);
		}
		else if (0 == strcmp(service, "pop"))
		{
			if (NULL == port_str || '\0' == *port_str)
				port = ZBX_DEFAULT_POP_PORT;
			ret = tcp_expect(ip, port, CONFIG_TIMEOUT, NULL, validate_pop, "QUIT\r\n", &value_int);
		}
		else if (0 == strcmp(service, "nntp"))
		{
			if (NULL == port_str || '\0' == *port_str)
				port = ZBX_DEFAULT_NNTP_PORT;
			ret = tcp_expect(ip, port, CONFIG_TIMEOUT, NULL, validate_nntp, "QUIT\r\n", &value_int);
		}
		else if (0 == strcmp(service, "imap"))
		{
			if (NULL == port_str || '\0' == *port_str)
				port = ZBX_DEFAULT_IMAP_PORT;
			ret = tcp_expect(ip, port, CONFIG_TIMEOUT, NULL, validate_imap, "a1 LOGOUT\r\n", &value_int);
		}
		else if (0 == strcmp(service, "tcp"))
		{
			if (NULL == port_str || '\0' == *port_str)
			{
				SET_MSG_RESULT(result, zbx_strdup(NULL, "Invalid third parameter."));
				return SYSINFO_RET_FAIL;
			}
			ret = tcp_expect(ip, port, CONFIG_TIMEOUT, NULL, NULL, NULL, &value_int);
		}
		else if (0 == strcmp(service, "https"))
		{
#ifdef HAVE_LIBCURL
			if (NULL == port_str || '\0' == *port_str)
				port = ZBX_DEFAULT_HTTPS_PORT;
			ret = check_https(ip, port, CONFIG_TIMEOUT, &value_int);
#else
			SET_MSG_RESULT(result, zbx_strdup(NULL, "Support for HTTPS check was not compiled in."));
#endif
		}
		else if (0 == strcmp(service, "telnet"))
		{
			if (NULL == port_str || '\0' == *port_str)
				port = ZBX_DEFAULT_TELNET_PORT;
			ret = check_telnet(ip, port, CONFIG_TIMEOUT, &value_int);
		}
		else
		{
			SET_MSG_RESULT(result, zbx_strdup(NULL, "Invalid first parameter."));
			return ret;
		}
	}
	else	/* net.udp.service */
	{
		if (0 == strcmp(service, "ntp"))
		{
			if (NULL == port_str || '\0' == *port_str)
				port = ZBX_DEFAULT_NTP_PORT;
			ret = check_ntp(ip, port, CONFIG_TIMEOUT, &value_int);
		}
		else
		{
			SET_MSG_RESULT(result, zbx_strdup(NULL, "Invalid first parameter."));
			return ret;
		}
	}

	if (SYSINFO_RET_OK == ret)
	{
		if (0 != perf)
		{
			if (0 != value_int)
			{
				check_time = zbx_time() - check_time;

				if (ZBX_FLOAT_PRECISION > check_time)
					check_time = ZBX_FLOAT_PRECISION;

				SET_DBL_RESULT(result, check_time);
			}
			else
				SET_DBL_RESULT(result, 0.0);
		}
		else
			SET_UI64_RESULT(result, value_int);
	}

	return ret;
}
コード例 #5
0
ファイル: simple.c プロジェクト: phedders/zabbix
/* check_service[ssh,127.0.0.1,ssh] */
int	CHECK_SERVICE(const char *cmd, const char *param, unsigned flags, AGENT_RESULT *result)
{
	unsigned short	port=0;
	char	service[MAX_STRING_LEN];
	char	ip[MAX_STRING_LEN];
	char	str_port[MAX_STRING_LEN];

	int	ret;
	int	value_int = 0;

        assert(result);

        init_result(result);

        if(num_param(param) > 3)
        {
                return SYSINFO_RET_FAIL;
        }

	if(get_param(param, 1, service, MAX_STRING_LEN) != 0)
        {
                return SYSINFO_RET_FAIL;
        }

	if(get_param(param, 2, ip, MAX_STRING_LEN) != 0)
        {
                ip[0] = '\0';
        }

	if(ip[0] == '\0')
	{
		strscpy(ip, "127.0.0.1");
	}

	if(get_param(param, 3, str_port, MAX_STRING_LEN) != 0)
        {
                str_port[0] = '\0';
        }

	if(str_port[0] != '\0')
	{
		port = atoi(str_port);
	}
	else
	{
		port = 0;
	}

/*	printf("IP:[%s]",ip);
	printf("Service:[%s]",service);
	printf("Port:[%d]",port);*/

	if(strcmp(service,"ssh") == 0)
	{
		if(port == 0)	port=22;
		ret=check_ssh(ip,port,&value_int);
	}
	else if(strcmp(service,"service.ntp") == 0)
	{
		if(port == 0)	port=123;
		ret=check_ntp(ip,port,&value_int);
	}
#ifdef HAVE_LDAP
	else if(strcmp(service,"ldap") == 0)
	{
		if(port == 0)   port=389;
		ret=check_ldap(ip,port,&value_int);
	}
#endif
	else if(strcmp(service,"smtp") == 0)
	{
		if(port == 0)	port=25;
		ret=tcp_expect(ip,port,NULL,"220","QUIT\n",&value_int);
	}
	else if(strcmp(service,"ftp") == 0)
	{
		if(port == 0)	port=21;
		ret=tcp_expect(ip,port,NULL,"220","",&value_int);
	}
	else if(strcmp(service,"http") == 0)
	{
		if(port == 0)	port=80;
		ret=tcp_expect(ip,port,NULL,NULL,"",&value_int);
	}
	else if(strcmp(service,"pop") == 0)
	{
		if(port == 0)	port=110;
		ret=tcp_expect(ip,port,NULL,"+OK","",&value_int);
	}
	else if(strcmp(service,"nntp") == 0)
	{
		if(port == 0)	port=119;
/* 220 is incorrect */
/*		ret=tcp_expect(ip,port,"220","");*/
		ret=tcp_expect(ip,port,NULL,"200","",&value_int);
	}
	else if(strcmp(service,"imap") == 0)
	{
		if(port == 0)	port=143;
		ret=tcp_expect(ip,port,NULL,"* OK","a1 LOGOUT\n",&value_int);
	}
	else if(strcmp(service,"tcp") == 0)
	{
		if(port == 0)	port=80;
		ret=tcp_expect(ip,port,NULL,NULL,"",&value_int);
	}
	else
	{
		return SYSINFO_RET_FAIL;
	}

	if(SYSINFO_RET_OK == ret)
	{
		SET_UI64_RESULT(result, value_int);
	}

	return ret;
}
コード例 #6
0
int	check_service(const char *params, const char *default_addr, AGENT_RESULT *result, int perf)
{
	unsigned short	port = 0;
	char		service[16], ip[64], str_port[8];
	int		value_int, ret = SYSINFO_RET_FAIL;
	double		check_time;

	check_time = zbx_time();

	if (3 < num_param(params))
		return ret;

	if (0 != get_param(params, 1, service, sizeof(service)))
		return ret;

	if (0 != get_param(params, 2, ip, sizeof(ip)) || '\0' == *ip)
		strscpy(ip, default_addr);

	if (0 != get_param(params, 3, str_port, sizeof(str_port)))
		*str_port = '\0';

	if ('\0' != *str_port && FAIL == is_ushort(str_port, &port))
	{
		SET_MSG_RESULT(result, zbx_dsprintf(NULL, "Invalid \"port\" parameter"));
		return ret;
	}

	if (0 == strcmp(service, "ssh"))
	{
		if ('\0' == *str_port)
			port = ZBX_DEFAULT_SSH_PORT;
		ret = check_ssh(ip, port, CONFIG_TIMEOUT, &value_int);
	}
	else if (0 == strcmp(service, "ntp") || 0 == strcmp(service, "service.ntp" /* deprecated */))
	{
		if ('\0' == *str_port)
			port = ZBX_DEFAULT_NTP_PORT;
		ret = check_ntp(ip, port, CONFIG_TIMEOUT, &value_int);
	}
#ifdef HAVE_LDAP
	else if (0 == strcmp(service, "ldap"))
	{
		if ('\0' == *str_port)
			port = ZBX_DEFAULT_LDAP_PORT;
		ret = check_ldap(ip, port, CONFIG_TIMEOUT, &value_int);
	}
#endif
	else if (0 == strcmp(service, "smtp"))
	{
		if ('\0' == *str_port)
			port = ZBX_DEFAULT_SMTP_PORT;
		ret = tcp_expect(ip, port, CONFIG_TIMEOUT, NULL, "220", "QUIT\r\n", &value_int);
	}
	else if (0 == strcmp(service, "ftp"))
	{
		if ('\0' == *str_port)
			port = ZBX_DEFAULT_FTP_PORT;
		ret = tcp_expect(ip, port, CONFIG_TIMEOUT, NULL, "220", "QUIT\n", &value_int);
	}
	else if (0 == strcmp(service, "http"))
	{
		if ('\0' == *str_port)
			port = ZBX_DEFAULT_HTTP_PORT;
		ret = tcp_expect(ip, port, CONFIG_TIMEOUT, NULL, NULL, NULL, &value_int);
	}
	else if (0 == strcmp(service, "pop"))
	{
		if ('\0' == *str_port)
			port = ZBX_DEFAULT_POP_PORT;
		ret = tcp_expect(ip, port, CONFIG_TIMEOUT, NULL, "+OK", "QUIT\n", &value_int);
	}
	else if (0 == strcmp(service, "nntp"))
	{
		if ('\0' == *str_port)
			port = ZBX_DEFAULT_NNTP_PORT;
		ret = tcp_expect(ip, port, CONFIG_TIMEOUT, NULL, "200", "QUIT\n", &value_int);
	}
	else if (0 == strcmp(service, "imap"))
	{
		if ('\0' == *str_port)
			port = ZBX_DEFAULT_IMAP_PORT;
		ret = tcp_expect(ip, port, CONFIG_TIMEOUT, NULL, "* OK", "a1 LOGOUT\n", &value_int);
	}
	else if (0 == strcmp(service, "tcp"))
	{
		if ('\0' == *str_port)
		{
			SET_MSG_RESULT(result, zbx_dsprintf(NULL, "Required \"port\" parameter missing"));
			return ret;
		}
		ret = tcp_expect(ip, port, CONFIG_TIMEOUT, NULL, NULL, NULL, &value_int);
	}
#ifdef HAVE_LIBCURL
	else if (0 == strcmp(service, "https"))
	{
		if ('\0' == *str_port)
			port = ZBX_DEFAULT_HTTPS_PORT;
		ret = check_https(ip, port, CONFIG_TIMEOUT, &value_int);
	}
#endif
	else if (0 == strcmp(service, "telnet"))
	{
		if ('\0' == *str_port)
			port = ZBX_DEFAULT_TELNET_PORT;
		ret = check_telnet(ip, port, CONFIG_TIMEOUT, &value_int);
	}
	else
		return ret;

	if (SYSINFO_RET_OK == ret)
	{
		if (0 != perf)
		{
			if (0 != value_int)
			{
				check_time = zbx_time() - check_time;
				check_time = MAX(check_time, 0.0001);
				SET_DBL_RESULT(result, check_time);
			}
			else
				SET_DBL_RESULT(result, 0.0);
		}
		else
			SET_UI64_RESULT(result, value_int);
	}

	return ret;
}
コード例 #7
0
ファイル: hdb-ldap.c プロジェクト: alepharchives/bitrig
static krb5_error_code
LDAP__lookup_princ(krb5_context context,
		   HDB *db,
		   const char *princname,
		   const char *userid,
		   LDAPMessage **msg)
{
    krb5_error_code ret;
    int rc;
    char *filter = NULL;

    ret = LDAP__connect(context, db);
    if (ret)
	return ret;

    rc = asprintf(&filter,
		  "(&(objectClass=krb5Principal)(krb5PrincipalName=%s))",
		  princname);
    if (rc < 0) {
	krb5_set_error_string(context, "asprintf: out of memory");
	ret = ENOMEM;
	goto out;
    }

    ret = LDAP_no_size_limit(context, HDB2LDAP(db));
    if (ret)
	goto out;

    rc = ldap_search_s(HDB2LDAP(db), HDB2BASE(db), LDAP_SCOPE_SUBTREE, filter, 
		       krb5kdcentry_attrs, 0, msg);
    if (check_ldap(context, db, rc)) {
	krb5_set_error_string(context, "ldap_search_s: %s",
			      ldap_err2string(rc));
	ret = HDB_ERR_NOENTRY;
	goto out;
    }

    if (userid && ldap_count_entries(HDB2LDAP(db), *msg) == 0) {
	free(filter);
	filter = NULL;
	ldap_msgfree(*msg);
	*msg = NULL;
	
	rc = asprintf(&filter,
	    "(&(|(objectClass=sambaSamAccount)(objectClass=%s))(uid=%s))",
		      structural_object, userid);
	if (rc < 0) {
	    krb5_set_error_string(context, "asprintf: out of memory");
	    ret = ENOMEM;
	    goto out;
	}
	    
	ret = LDAP_no_size_limit(context, HDB2LDAP(db));
	if (ret)
	    goto out;

	rc = ldap_search_s(HDB2LDAP(db), HDB2BASE(db), LDAP_SCOPE_SUBTREE, 
			   filter, krb5kdcentry_attrs, 0, msg);
	if (check_ldap(context, db, rc)) {
	    krb5_set_error_string(context, "ldap_search_s: %s",
				  ldap_err2string(rc));
	    ret = HDB_ERR_NOENTRY;
	    goto out;
	}
    }

    ret = 0;

  out:
    if (filter)
	free(filter);

    return ret;
}
コード例 #8
0
ファイル: hdb-ldap.c プロジェクト: alepharchives/bitrig
static krb5_error_code
LDAP_store(krb5_context context, HDB * db, unsigned flags,
	   hdb_entry * entry)
{
    LDAPMod **mods = NULL;
    krb5_error_code ret;
    const char *errfn;
    int rc;
    LDAPMessage *msg = NULL, *e = NULL;
    char *dn = NULL, *name = NULL;

    ret = LDAP_principal2message(context, db, entry->principal, &msg);
    if (ret == 0)
	e = ldap_first_entry(HDB2LDAP(db), msg);

    ret = krb5_unparse_name(context, entry->principal, &name);
    if (ret) {
	free(name);
	return ret;
    }

    ret = hdb_seal_keys(context, db, entry);
    if (ret)
	goto out;

    /* turn new entry into LDAPMod array */
    ret = LDAP_entry2mods(context, db, entry, e, &mods);
    if (ret)
	goto out;

    if (e == NULL) {
	ret = asprintf(&dn, "krb5PrincipalName=%s,%s", name, HDB2CREATE(db));
	if (ret < 0) {
	    krb5_set_error_string(context, "asprintf: out of memory");
	    ret = ENOMEM;
	    goto out;
	}
    } else if (flags & HDB_F_REPLACE) {
	/* Entry exists, and we're allowed to replace it. */
	dn = ldap_get_dn(HDB2LDAP(db), e);
    } else {
	/* Entry exists, but we're not allowed to replace it. Bail. */
	ret = HDB_ERR_EXISTS;
	goto out;
    }

    /* write entry into directory */
    if (e == NULL) {
	/* didn't exist before */
	rc = ldap_add_s(HDB2LDAP(db), dn, mods);
	errfn = "ldap_add_s";
    } else {
	/* already existed, send deltas only */
	rc = ldap_modify_s(HDB2LDAP(db), dn, mods);
	errfn = "ldap_modify_s";
    }

    if (check_ldap(context, db, rc)) {
	char *ld_error = NULL;
	ldap_get_option(HDB2LDAP(db), LDAP_OPT_ERROR_STRING,
			&ld_error);
	krb5_set_error_string(context, "%s: %s (dn=%s) %s: %s", 
			      errfn, name, dn, ldap_err2string(rc), ld_error);
	ret = HDB_ERR_CANT_LOCK_DB;
    } else
	ret = 0;

  out:
    /* free stuff */
    if (dn)
	free(dn);
    if (msg)
	ldap_msgfree(msg);
    if (mods)
	ldap_mods_free(mods, 1);
    if (name)
	free(name);

    return ret;
}
コード例 #9
0
ファイル: hdb-ldap.c プロジェクト: dariaphoebe/heimdal
static krb5_error_code
LDAP__lookup_princ(krb5_context context,
		   HDB *db,
		   const char *princname,
		   const char *userid,
		   LDAPMessage **msg)
{
    struct berval namebv, quotedp;
    krb5_error_code ret;
    int rc;
    char *filter = NULL;

    ret = LDAP__connect(context, db);
    if (ret)
	return ret;

    /* 
     * Quote searches that contain filter language, this quote
     * searches for *@REALM, which takes very long time.
     */

    ber_str2bv(princname, 0, 0, &namebv);
    if (ldap_bv2escaped_filter_value(&namebv, &quotedp) != 0) {
	ret = ENOMEM;
	krb5_set_error_message(context, ret, "malloc: out of memory");
	goto out;
    }
    rc = asprintf(&filter,
		  "(&(objectClass=krb5Principal)(krb5PrincipalName=%s))",
		  quotedp.bv_val);
    ber_memfree(quotedp.bv_val);

    if (rc < 0) {
	ret = ENOMEM;
	krb5_set_error_message(context, ret, "malloc: out of memory");
	goto out;
    }

    ret = LDAP_no_size_limit(context, HDB2LDAP(db));
    if (ret)
	goto out;

    rc = ldap_search_ext_s(HDB2LDAP(db), HDB2BASE(db),
			   LDAP_SCOPE_SUBTREE, filter,
			   krb5kdcentry_attrs, 0,
			   NULL, NULL, NULL,
			   0, msg);
    if (check_ldap(context, db, rc)) {
	ret = HDB_ERR_NOENTRY;
	krb5_set_error_message(context, ret, "ldap_search_ext_s: "
			      "filter: %s - error: %s",
			      filter, ldap_err2string(rc));
	goto out;
    }

    if (userid && ldap_count_entries(HDB2LDAP(db), *msg) == 0) {
	free(filter);
	filter = NULL;
	ldap_msgfree(*msg);
	*msg = NULL;
	
	ber_str2bv(userid, 0, 0, &namebv);
	if (ldap_bv2escaped_filter_value(&namebv, &quotedp) != 0) {
	    ret = ENOMEM;
	    krb5_set_error_message(context, ret, "malloc: out of memory");
	    goto out;
	}

	rc = asprintf(&filter,
	    "(&(|(objectClass=sambaSamAccount)(objectClass=%s))(uid=%s))",
		      structural_object, quotedp.bv_val);
	ber_memfree(quotedp.bv_val);
	if (rc < 0) {
	    ret = ENOMEM;
	    krb5_set_error_message(context, ret, "asprintf: out of memory");
	    goto out;
	}
	
	ret = LDAP_no_size_limit(context, HDB2LDAP(db));
	if (ret)
	    goto out;

	rc = ldap_search_ext_s(HDB2LDAP(db), HDB2BASE(db), LDAP_SCOPE_SUBTREE,
			       filter, krb5kdcentry_attrs, 0,
			       NULL, NULL, NULL,
			       0, msg);
	if (check_ldap(context, db, rc)) {
	    ret = HDB_ERR_NOENTRY;
	    krb5_set_error_message(context, ret,
				   "ldap_search_ext_s: filter: %s error: %s",
				   filter, ldap_err2string(rc));
	    goto out;
	}
    }

    ret = 0;

  out:
    if (filter)
	free(filter);

    return ret;
}