Beispiel #1
0
static void unbecomeDC_send_cldap(struct libnet_UnbecomeDC_state *s)
{
	struct composite_context *c = s->creq;
	struct tevent_req *req;
	struct tsocket_address *dest_address;
	int ret;

	s->cldap.io.in.dest_address	= NULL;
	s->cldap.io.in.dest_port	= 0;
	s->cldap.io.in.realm		= s->domain.dns_name;
	s->cldap.io.in.host		= s->dest_dsa.netbios_name;
	s->cldap.io.in.user		= NULL;
	s->cldap.io.in.domain_guid	= NULL;
	s->cldap.io.in.domain_sid	= NULL;
	s->cldap.io.in.acct_control	= -1;
	s->cldap.io.in.version		= NETLOGON_NT_VERSION_5 | NETLOGON_NT_VERSION_5EX;
	s->cldap.io.in.map_response	= true;

	ret = tsocket_address_inet_from_strings(s, "ip",
						s->source_dsa.address,
						lpcfg_cldap_port(s->libnet->lp_ctx),
						&dest_address);
	if (ret != 0) {
		c->status = map_nt_error_from_unix_common(errno);
		if (!composite_is_ok(c)) return;
	}

	c->status = cldap_socket_init(s, NULL, dest_address, &s->cldap.sock);
	if (!composite_is_ok(c)) return;

	req = cldap_netlogon_send(s, s->libnet->event_ctx,
				  s->cldap.sock, &s->cldap.io);
	if (composite_nomem(req, c)) return;
	tevent_req_set_callback(req, unbecomeDC_recv_cldap, s);
}
Beispiel #2
0
/*
  start listening on the given address
*/
static NTSTATUS cldapd_add_socket(struct cldapd_server *cldapd, struct loadparm_context *lp_ctx,
				  const char *address)
{
	struct cldap_socket *cldapsock;
	struct tsocket_address *socket_address;
	NTSTATUS status;
	int ret;

	ret = tsocket_address_inet_from_strings(cldapd,
						"ip",
						address,
						lpcfg_cldap_port(lp_ctx),
						&socket_address);
	if (ret != 0) {
		status = map_nt_error_from_unix_common(errno);
		DEBUG(0,("invalid address %s:%d - %s:%s\n",
			 address, lpcfg_cldap_port(lp_ctx),
			 gai_strerror(ret), nt_errstr(status)));
		return status;
	}

	/* listen for unicasts on the CLDAP port (389) */
	status = cldap_socket_init(cldapd,
				   cldapd->task->event_ctx,
				   socket_address,
				   NULL,
				   &cldapsock);
	if (!NT_STATUS_IS_OK(status)) {
		DEBUG(0,("Failed to bind to %s - %s\n", 
			 tsocket_address_string(socket_address, socket_address),
			 nt_errstr(status)));
		talloc_free(socket_address);
		return status;
	}
	talloc_free(socket_address);

	cldap_set_incoming_handler(cldapsock, cldapd_request_handler, cldapd);

	return NT_STATUS_OK;
}
Beispiel #3
0
static void unbecomeDC_send_cldap(struct libnet_UnbecomeDC_state *s)
{
	struct composite_context *c = s->creq;
	struct tevent_req *req;

	s->cldap.io.in.dest_address	= s->source_dsa.address;
	s->cldap.io.in.dest_port	= lp_cldap_port(s->libnet->lp_ctx);
	s->cldap.io.in.realm		= s->domain.dns_name;
	s->cldap.io.in.host		= s->dest_dsa.netbios_name;
	s->cldap.io.in.user		= NULL;
	s->cldap.io.in.domain_guid	= NULL;
	s->cldap.io.in.domain_sid	= NULL;
	s->cldap.io.in.acct_control	= -1;
	s->cldap.io.in.version		= NETLOGON_NT_VERSION_5 | NETLOGON_NT_VERSION_5EX;
	s->cldap.io.in.map_response	= true;

	c->status = cldap_socket_init(s, s->libnet->event_ctx,
				      NULL, NULL, &s->cldap.sock);//TODO
	if (!composite_is_ok(c)) return;

	req = cldap_netlogon_send(s, s->cldap.sock, &s->cldap.io);
	if (composite_nomem(req, c)) return;
	tevent_req_set_callback(req, unbecomeDC_recv_cldap, s);
}
Beispiel #4
0
/*
  test netlogon operations
*/
static BOOL test_cldap_netlogon(TALLOC_CTX *mem_ctx, const char *dest)
{
	struct cldap_socket *cldap = cldap_socket_init(mem_ctx, NULL);
	NTSTATUS status;
	struct cldap_netlogon search, empty_search;
	union nbt_cldap_netlogon n1;
	struct GUID guid;
	int i;
	BOOL ret = True;

	ZERO_STRUCT(search);
	search.in.dest_address = dest;
	search.in.acct_control = -1;
	search.in.version = 6;

	empty_search = search;

	printf("Trying without any attributes\n");
	search = empty_search;
	status = cldap_netlogon(cldap, mem_ctx, &search);
	CHECK_STATUS(status, NT_STATUS_OK);

	n1 = search.out.netlogon;

	search.in.user         = "******";
	search.in.realm        = n1.logon5.dns_domain;
	search.in.host         = "__cldap_torture__";

	printf("Scanning for netlogon levels\n");
	for (i=0;i<256;i++) {
		search.in.version = i;
		printf("Trying netlogon level %d\n", i);
		status = cldap_netlogon(cldap, mem_ctx, &search);
		CHECK_STATUS(status, NT_STATUS_OK);
	}

	printf("Scanning for netlogon level bits\n");
	for (i=0;i<31;i++) {
		search.in.version = (1<<i);
		printf("Trying netlogon level 0x%x\n", i);
		status = cldap_netlogon(cldap, mem_ctx, &search);
		CHECK_STATUS(status, NT_STATUS_OK);
	}

	search.in.version = 6;
	status = cldap_netlogon(cldap, mem_ctx, &search);
	CHECK_STATUS(status, NT_STATUS_OK);

	printf("Trying with User=NULL\n");

	search.in.user = NULL;
	status = cldap_netlogon(cldap, mem_ctx, &search);
	CHECK_STATUS(status, NT_STATUS_OK);

	printf("Trying with User=Administrator\n");

	search.in.user = "******";
	status = cldap_netlogon(cldap, mem_ctx, &search);
	CHECK_STATUS(status, NT_STATUS_OK);

	printf("Trying with a GUID\n");
	search.in.realm       = NULL;
	search.in.domain_guid = GUID_string(mem_ctx, &n1.logon5.domain_uuid);
	status = cldap_netlogon(cldap, mem_ctx, &search);
	CHECK_STATUS(status, NT_STATUS_OK);

	printf("Trying with a incorrect GUID\n");
	guid = GUID_random();
	search.in.user        = NULL;
	search.in.domain_guid = GUID_string(mem_ctx, &guid);
	status = cldap_netlogon(cldap, mem_ctx, &search);
	CHECK_STATUS(status, NT_STATUS_NOT_FOUND);

	printf("Trying with a AAC\n");
	search.in.acct_control = 0x180;
	search.in.realm = n1.logon5.dns_domain;
	status = cldap_netlogon(cldap, mem_ctx, &search);
	CHECK_STATUS(status, NT_STATUS_OK);

	printf("Trying with a bad AAC\n");
	search.in.acct_control = 0xFF00FF00;
	search.in.realm = n1.logon5.dns_domain;
	status = cldap_netlogon(cldap, mem_ctx, &search);
	CHECK_STATUS(status, NT_STATUS_OK);

	printf("Trying with a user only\n");
	search = empty_search;
	search.in.user = "******";
	status = cldap_netlogon(cldap, mem_ctx, &search);
	CHECK_STATUS(status, NT_STATUS_OK);

	printf("Trying with just a bad username\n");
	search.in.user = "******";
	status = cldap_netlogon(cldap, mem_ctx, &search);
	CHECK_STATUS(status, NT_STATUS_OK);

	printf("Trying with just a bad domain\n");
	search = empty_search;
	search.in.realm = "___no_such_domain___";
	status = cldap_netlogon(cldap, mem_ctx, &search);
	CHECK_STATUS(status, NT_STATUS_NOT_FOUND);

	printf("Trying with a incorrect domain and correct guid\n");
	search.in.domain_guid = GUID_string(mem_ctx, &n1.logon5.domain_uuid);
	status = cldap_netlogon(cldap, mem_ctx, &search);
	CHECK_STATUS(status, NT_STATUS_OK);

	printf("Trying with a incorrect domain and incorrect guid\n");
	search.in.domain_guid = GUID_string(mem_ctx, &guid);
	status = cldap_netlogon(cldap, mem_ctx, &search);
	CHECK_STATUS(status, NT_STATUS_NOT_FOUND);

	printf("Trying with a incorrect GUID and correct domain\n");
	search.in.domain_guid = GUID_string(mem_ctx, &guid);
	search.in.realm = n1.logon5.dns_domain;
	status = cldap_netlogon(cldap, mem_ctx, &search);
	CHECK_STATUS(status, NT_STATUS_OK);

done:
	return ret;	
}
Beispiel #5
0
/*
  test generic cldap operations
*/
static BOOL test_cldap_generic(TALLOC_CTX *mem_ctx, const char *dest)
{
	struct cldap_socket *cldap = cldap_socket_init(mem_ctx, NULL);
	NTSTATUS status;
	struct cldap_search search;
	BOOL ret = True;
	const char *attrs1[] = { "currentTime", "highestCommittedUSN", NULL };
	const char *attrs2[] = { "currentTime", "highestCommittedUSN", "netlogon", NULL };
	const char *attrs3[] = { "netlogon", NULL };

	ZERO_STRUCT(search);
	search.in.dest_address = dest;
	search.in.timeout = 10;
	search.in.retries = 3;

	status = cldap_search(cldap, mem_ctx, &search);
	CHECK_STATUS(status, NT_STATUS_OK);

	printf("fetching whole rootDSE\n");
	search.in.filter = "(objectclass=*)";
	search.in.attributes = NULL;

	status = cldap_search(cldap, mem_ctx, &search);
	CHECK_STATUS(status, NT_STATUS_OK);

	if (DEBUGLVL(3)) cldap_dump_results(&search);

	printf("fetching currentTime and USN\n");
	search.in.filter = "(objectclass=*)";
	search.in.attributes = attrs1;

	status = cldap_search(cldap, mem_ctx, &search);
	CHECK_STATUS(status, NT_STATUS_OK);
	
	if (DEBUGLVL(3)) cldap_dump_results(&search);

	printf("Testing currentTime, USN and netlogon\n");
	search.in.filter = "(objectclass=*)";
	search.in.attributes = attrs2;

	status = cldap_search(cldap, mem_ctx, &search);
	CHECK_STATUS(status, NT_STATUS_OK);

	if (DEBUGLVL(3)) cldap_dump_results(&search);

	printf("Testing objectClass=* and netlogon\n");
	search.in.filter = "(objectclass2=*)";
	search.in.attributes = attrs2;

	status = cldap_search(cldap, mem_ctx, &search);
	CHECK_STATUS(status, NT_STATUS_OK);

	if (DEBUGLVL(3)) cldap_dump_results(&search);

	printf("Testing a false expression\n");
	search.in.filter = "(&(objectclass=*)(highestCommittedUSN=2))";
	search.in.attributes = attrs1;

	status = cldap_search(cldap, mem_ctx, &search);
	CHECK_STATUS(status, NT_STATUS_OK);

	if (DEBUGLVL(3)) cldap_dump_results(&search);	

done:
	return ret;	
}
Beispiel #6
0
/**
 * 1. Setup a CLDAP socket.
 * 2. Lookup the default Site-Name.
 */
NTSTATUS libnet_FindSite(TALLOC_CTX *ctx, struct libnet_context *lctx, struct libnet_JoinSite *r)
{
    NTSTATUS status;
    TALLOC_CTX *tmp_ctx;

    char *site_name_str;
    char *config_dn_str;
    char *server_dn_str;

    struct cldap_socket *cldap = NULL;
    struct cldap_netlogon search;

    tmp_ctx = talloc_named(ctx, 0, "libnet_FindSite temp context");
    if (!tmp_ctx) {
        r->out.error_string = NULL;
        return NT_STATUS_NO_MEMORY;
    }

    /* Resolve the site name. */
    ZERO_STRUCT(search);
    search.in.dest_address = r->in.dest_address;
    search.in.dest_port = r->in.cldap_port;
    search.in.acct_control = -1;
    search.in.version = NETLOGON_NT_VERSION_5 | NETLOGON_NT_VERSION_5EX;
    search.in.map_response = true;

    /* we want to use non async calls, so we're not passing an event context */
    status = cldap_socket_init(tmp_ctx, NULL, NULL, NULL, &cldap);//TODO
    if (!NT_STATUS_IS_OK(status)) {
        talloc_free(tmp_ctx);
        r->out.error_string = NULL;
        return status;
    }
    status = cldap_netlogon(cldap, lp_iconv_convenience(lctx->lp_ctx), tmp_ctx, &search);
    if (!NT_STATUS_IS_OK(status)
            || !search.out.netlogon.data.nt5_ex.client_site) {
        /*
          If cldap_netlogon() returns in error,
          default to using Default-First-Site-Name.
        */
        site_name_str = talloc_asprintf(tmp_ctx, "%s",
                                        "Default-First-Site-Name");
        if (!site_name_str) {
            r->out.error_string = NULL;
            talloc_free(tmp_ctx);
            return NT_STATUS_NO_MEMORY;
        }
    } else {
        site_name_str = talloc_asprintf(tmp_ctx, "%s",
                                        search.out.netlogon.data.nt5_ex.client_site);
        if (!site_name_str) {
            r->out.error_string = NULL;
            talloc_free(tmp_ctx);
            return NT_STATUS_NO_MEMORY;
        }
    }

    /* Generate the CN=Configuration,... DN. */
    /* TODO: look it up! */
    config_dn_str = talloc_asprintf(tmp_ctx, "CN=Configuration,%s", r->in.domain_dn_str);
    if (!config_dn_str) {
        r->out.error_string = NULL;
        talloc_free(tmp_ctx);
        return NT_STATUS_NO_MEMORY;
    }

    /* Generate the CN=Servers,... DN. */
    server_dn_str = talloc_asprintf(tmp_ctx, "CN=%s,CN=Servers,CN=%s,CN=Sites,%s",
                                    r->in.netbios_name, site_name_str, config_dn_str);
    if (!server_dn_str) {
        r->out.error_string = NULL;
        talloc_free(tmp_ctx);
        return NT_STATUS_NO_MEMORY;
    }

    r->out.site_name_str = site_name_str;
    talloc_steal(r, site_name_str);

    r->out.config_dn_str = config_dn_str;
    talloc_steal(r, config_dn_str);

    r->out.server_dn_str = server_dn_str;
    talloc_steal(r, server_dn_str);

    talloc_free(tmp_ctx);
    return NT_STATUS_OK;
}
Beispiel #7
0
static NTSTATUS tcp_ldap_netlogon(void *conn,
				  TALLOC_CTX *mem_ctx,
				  struct cldap_netlogon *io)
{
	struct cldap_search search;
	struct ldap_SearchResEntry *res;
	NTSTATUS status;
	DATA_BLOB *blob;

	ZERO_STRUCT(search);
	search.in.attributes = (const char *[]) { "netlogon", NULL };
	search.in.filter =  cldap_netlogon_create_filter(mem_ctx, io);
	if (search.in.filter == NULL) {
		return NT_STATUS_NO_MEMORY;
	}

	status = tcp_ldap_rootdse(conn, mem_ctx, &search);
	if (!NT_STATUS_IS_OK(status)) {
		return status;
	}

	res = search.out.response;
	if (res == NULL) {
		return NT_STATUS_NOT_FOUND;
	}

	if (res->num_attributes != 1 ||
	    strcasecmp(res->attributes[0].name, "netlogon") != 0 ||
	    res->attributes[0].num_values != 1 ||
	    res->attributes[0].values->length < 2) {
		return NT_STATUS_UNEXPECTED_NETWORK_ERROR;
	}

	blob = res->attributes[0].values;
	status = pull_netlogon_samlogon_response(blob, mem_ctx,
						 &io->out.netlogon);
	if (!NT_STATUS_IS_OK(status)) {
		return status;
	}

	if (io->in.map_response) {
		map_netlogon_samlogon_response(&io->out.netlogon);
	}

	return NT_STATUS_OK;
}

static NTSTATUS udp_ldap_rootdse(void *data, TALLOC_CTX *mem_ctx,
				 struct cldap_search *io)
{
	struct cldap_socket *cldap = talloc_get_type(data,
						     struct cldap_socket);

	return cldap_search(cldap, mem_ctx, io);
}

static bool test_netlogon_extra_attrs(struct torture_context *tctx,
				      request_rootdse_t request_rootdse,
				      void *conn)
{
	struct cldap_search io;
	NTSTATUS status;
	const char *attrs[] = {
		"netlogon",
		"supportedCapabilities",
		NULL
	};
	const char *attrs2[] = { "netlogon", "*", NULL };
	struct ldb_message ldbmsg = { NULL, 0, NULL };

	ZERO_STRUCT(io);
	io.in.dest_address = NULL;
	io.in.dest_port = 0;
	io.in.timeout   = 2;
	io.in.retries   = 2;
	/* Additional attributes may be requested next to netlogon */
	torture_comment(tctx, "Requesting netlogon with additional attribute\n");
	io.in.filter =
		talloc_asprintf(tctx, "(&"
				"(NtVer=%s)(AAC=%s)"
				/* Query for LDAP_CAP_ACTIVE_DIRECTORY_OID */
				"(supportedCapabilities=1.2.840.113556.1.4.800)"
				")",
				ldap_encode_ndr_uint32(tctx,
						       NETLOGON_NT_VERSION_5EX),
				ldap_encode_ndr_uint32(tctx, 0));
	torture_assert(tctx, io.in.filter != NULL, "OOM");
	io.in.attributes = attrs;
	status = request_rootdse(conn, tctx, &io);
	CHECK_STATUS(status, NT_STATUS_OK);
	torture_assert(tctx, io.out.response != NULL, "No Entries found.");
	CHECK_VAL(io.out.response->num_attributes, 2);

	/* netlogon + '*' attr return zero results */
	torture_comment(tctx, "Requesting netlogon and '*' attributes\n");
	io.in.attributes = attrs2;
	status = request_rootdse(conn, tctx, &io);
	CHECK_STATUS(status, NT_STATUS_OK);
	torture_assert(tctx, io.out.response != NULL, "No Entries found.");
	ldbmsg.num_elements = io.out.response->num_attributes;
	ldbmsg.elements = io.out.response->attributes;
	torture_assert(tctx, ldb_msg_find_element(&ldbmsg, "netlogon") != NULL,
		       "Attribute netlogon not found in Result Entry\n");

	/* Wildcards are not allowed in filters when netlogon is requested. */
	torture_comment(tctx, "Requesting netlogon with invalid attr filter\n");
	io.in.filter =
		talloc_asprintf(tctx,
				"(&(NtVer=%s)(AAC=%s)(supportedCapabilities=*))",
				ldap_encode_ndr_uint32(tctx,
						       NETLOGON_NT_VERSION_5EX),
				ldap_encode_ndr_uint32(tctx, 0));
	torture_assert(tctx, io.in.filter != NULL, "OOM");
	io.in.attributes = attrs;
	status = request_rootdse(conn, tctx, &io);
	CHECK_STATUS(status, NT_STATUS_OK);
	torture_assert(tctx, io.out.response == NULL,
		       "A wildcard filter should return no entries.");

	return true;
}


bool torture_netlogon_tcp(struct torture_context *tctx)
{
	const char *host = torture_setting_string(tctx, "host", NULL);
	bool ret = true;
	NTSTATUS status;
	struct ldap_connection *conn;
	TALLOC_CTX *mem_ctx;
	const char *url;

	mem_ctx = talloc_init("torture_ldap_netlogon");

	url = talloc_asprintf(mem_ctx, "ldap://%s/", host);

	status = torture_ldap_connection(tctx, &conn, url);
	if (!NT_STATUS_IS_OK(status)) {
		return false;
	}

	ret &= test_ldap_netlogon(tctx, tcp_ldap_netlogon, conn, host);
	ret &= test_ldap_netlogon_flags(tctx, tcp_ldap_netlogon, conn, host);
	ret &= test_netlogon_extra_attrs(tctx, tcp_ldap_rootdse, conn);

	return ret;
}

static NTSTATUS udp_ldap_netlogon(void *data,
				  TALLOC_CTX *mem_ctx,
				  struct cldap_netlogon *io)
{
	struct cldap_socket *cldap = talloc_get_type(data,
						     struct cldap_socket);

	return cldap_netlogon(cldap, mem_ctx, io);
}

bool torture_netlogon_udp(struct torture_context *tctx)
{
	const char *host = torture_setting_string(tctx, "host", NULL);
	bool ret = true;
	int r;
	struct cldap_socket *cldap;
	NTSTATUS status;
	struct tsocket_address *dest_addr;

	r = tsocket_address_inet_from_strings(tctx, "ip",
					      host,
					      lpcfg_cldap_port(tctx->lp_ctx),
					      &dest_addr);
	CHECK_VAL(r, 0);

	/* cldap_socket_init should now know about the dest. address */
	status = cldap_socket_init(tctx, NULL, dest_addr, &cldap);
	CHECK_STATUS(status, NT_STATUS_OK);

	ret &= test_ldap_netlogon(tctx, udp_ldap_netlogon, cldap, host);
	ret &= test_ldap_netlogon_flags(tctx, udp_ldap_netlogon, cldap, host);
	ret &= test_netlogon_extra_attrs(tctx, udp_ldap_rootdse, cldap);

	return ret;
}
Beispiel #8
0
/*
  test generic cldap operations
*/
static bool test_cldap_generic(struct torture_context *tctx, const char *dest)
{
	struct cldap_socket *cldap;
	NTSTATUS status;
	struct cldap_search search;
	const char *attrs1[] = { "currentTime", "highestCommittedUSN", NULL };
	const char *attrs2[] = { "currentTime", "highestCommittedUSN", "netlogon", NULL };
	const char *attrs3[] = { "netlogon", NULL };

	status = cldap_socket_init(tctx, NULL, NULL, NULL, &cldap);
	CHECK_STATUS(status, NT_STATUS_OK);

	ZERO_STRUCT(search);
	search.in.dest_address = dest;
	search.in.dest_port = lp_cldap_port(tctx->lp_ctx);
	search.in.timeout = 10;
	search.in.retries = 3;

	status = cldap_search(cldap, tctx, &search);
	CHECK_STATUS(status, NT_STATUS_OK);

	printf("fetching whole rootDSE\n");
	search.in.filter = "(objectclass=*)";
	search.in.attributes = NULL;

	status = cldap_search(cldap, tctx, &search);
	CHECK_STATUS(status, NT_STATUS_OK);

	if (DEBUGLVL(3)) cldap_dump_results(&search);

	printf("fetching currentTime and USN\n");
	search.in.filter = "(objectclass=*)";
	search.in.attributes = attrs1;

	status = cldap_search(cldap, tctx, &search);
	CHECK_STATUS(status, NT_STATUS_OK);
	
	if (DEBUGLVL(3)) cldap_dump_results(&search);

	printf("Testing currentTime, USN and netlogon\n");
	search.in.filter = "(objectclass=*)";
	search.in.attributes = attrs2;

	status = cldap_search(cldap, tctx, &search);
	CHECK_STATUS(status, NT_STATUS_OK);

	if (DEBUGLVL(3)) cldap_dump_results(&search);

	printf("Testing objectClass=* and netlogon\n");
	search.in.filter = "(objectclass2=*)";
	search.in.attributes = attrs3;

	status = cldap_search(cldap, tctx, &search);
	CHECK_STATUS(status, NT_STATUS_OK);

	if (DEBUGLVL(3)) cldap_dump_results(&search);

	printf("Testing a false expression\n");
	search.in.filter = "(&(objectclass=*)(highestCommittedUSN=2))";
	search.in.attributes = attrs1;

	status = cldap_search(cldap, tctx, &search);
	CHECK_STATUS(status, NT_STATUS_OK);

	if (DEBUGLVL(3)) cldap_dump_results(&search);	

	return true;	
}
Beispiel #9
0
/*
  test netlogon operations
*/
static bool test_cldap_netlogon(struct torture_context *tctx, const char *dest)
{
	struct cldap_socket *cldap;
	NTSTATUS status;
	struct cldap_netlogon search, empty_search;
	struct netlogon_samlogon_response n1;
	struct GUID guid;
	int i;
	struct smb_iconv_convenience *iconv_convenience = lp_iconv_convenience(tctx->lp_ctx);
	struct tsocket_address *dest_addr;
	int ret;

	ret = tsocket_address_inet_from_strings(tctx, "ip",
						dest,
						lp_cldap_port(tctx->lp_ctx),
						&dest_addr);

	status = cldap_socket_init(tctx, NULL, NULL, dest_addr, &cldap);
	CHECK_STATUS(status, NT_STATUS_OK);

	ZERO_STRUCT(search);
	search.in.dest_address = NULL;
	search.in.dest_port = 0;
	search.in.acct_control = -1;
	search.in.version = NETLOGON_NT_VERSION_5 | NETLOGON_NT_VERSION_5EX;
	search.in.map_response = true;

	empty_search = search;

	printf("Trying without any attributes\n");
	search = empty_search;
	status = cldap_netlogon(cldap, iconv_convenience, tctx, &search);
	CHECK_STATUS(status, NT_STATUS_OK);

	n1 = search.out.netlogon;

	search.in.user         = "******";
	search.in.realm        = n1.data.nt5_ex.dns_domain;
	search.in.host         = "__cldap_torture__";

	printf("Scanning for netlogon levels\n");
	for (i=0;i<256;i++) {
		search.in.version = i;
		printf("Trying netlogon level %d\n", i);
		status = cldap_netlogon(cldap, iconv_convenience, tctx, &search);
		CHECK_STATUS(status, NT_STATUS_OK);
	}

	printf("Scanning for netlogon level bits\n");
	for (i=0;i<31;i++) {
		search.in.version = (1<<i);
		printf("Trying netlogon level 0x%x\n", i);
		status = cldap_netlogon(cldap, iconv_convenience, tctx, &search);
		CHECK_STATUS(status, NT_STATUS_OK);
	}

	search.in.version = NETLOGON_NT_VERSION_5|NETLOGON_NT_VERSION_5EX|NETLOGON_NT_VERSION_IP;

	status = cldap_netlogon(cldap, iconv_convenience, tctx, &search);
	CHECK_STATUS(status, NT_STATUS_OK);

	printf("Trying with User=NULL\n");

	search.in.user = NULL;
	status = cldap_netlogon(cldap, iconv_convenience, tctx, &search);
	CHECK_STATUS(status, NT_STATUS_OK);
	CHECK_STRING(search.out.netlogon.data.nt5_ex.user_name, "");
	CHECK_VAL(search.out.netlogon.data.nt5_ex.command, LOGON_SAM_LOGON_RESPONSE_EX);

	printf("Trying with User=Administrator\n");

	search.in.user = "******";
	status = cldap_netlogon(cldap, iconv_convenience, tctx, &search);
	CHECK_STATUS(status, NT_STATUS_OK);

	CHECK_STRING(search.out.netlogon.data.nt5_ex.user_name, search.in.user);
	CHECK_VAL(search.out.netlogon.data.nt5_ex.command, LOGON_SAM_LOGON_USER_UNKNOWN_EX);

	search.in.version = NETLOGON_NT_VERSION_5;
	status = cldap_netlogon(cldap, iconv_convenience, tctx, &search);
	CHECK_STATUS(status, NT_STATUS_OK);

	printf("Trying with User=NULL\n");

	search.in.user = NULL;
	status = cldap_netlogon(cldap, iconv_convenience, tctx, &search);
	CHECK_STATUS(status, NT_STATUS_OK);
	CHECK_STRING(search.out.netlogon.data.nt5_ex.user_name, "");
	CHECK_VAL(search.out.netlogon.data.nt5_ex.command, LOGON_SAM_LOGON_RESPONSE);

	printf("Trying with User=Administrator\n");

	search.in.user = "******";
	status = cldap_netlogon(cldap, iconv_convenience, tctx, &search);
	CHECK_STATUS(status, NT_STATUS_OK);

	CHECK_STRING(search.out.netlogon.data.nt5_ex.user_name, search.in.user);
	CHECK_VAL(search.out.netlogon.data.nt5_ex.command, LOGON_SAM_LOGON_USER_UNKNOWN);

	search.in.version = NETLOGON_NT_VERSION_5 | NETLOGON_NT_VERSION_5EX;

	printf("Trying with a GUID\n");
	search.in.realm       = NULL;
	search.in.domain_guid = GUID_string(tctx, &n1.data.nt5_ex.domain_uuid);
	status = cldap_netlogon(cldap, iconv_convenience, tctx, &search);
	CHECK_STATUS(status, NT_STATUS_OK);
	CHECK_VAL(search.out.netlogon.data.nt5_ex.command, LOGON_SAM_LOGON_USER_UNKNOWN_EX);
	CHECK_STRING(GUID_string(tctx, &search.out.netlogon.data.nt5_ex.domain_uuid), search.in.domain_guid);

	printf("Trying with a incorrect GUID\n");
	guid = GUID_random();
	search.in.user        = NULL;
	search.in.domain_guid = GUID_string(tctx, &guid);
	status = cldap_netlogon(cldap, iconv_convenience, tctx, &search);
	CHECK_STATUS(status, NT_STATUS_NOT_FOUND);

	printf("Trying with a AAC\n");
	search.in.acct_control = ACB_WSTRUST|ACB_SVRTRUST;
	search.in.realm = n1.data.nt5_ex.dns_domain;
	status = cldap_netlogon(cldap, iconv_convenience, tctx, &search);
	CHECK_STATUS(status, NT_STATUS_OK);
	CHECK_VAL(search.out.netlogon.data.nt5_ex.command, LOGON_SAM_LOGON_RESPONSE_EX);
	CHECK_STRING(search.out.netlogon.data.nt5_ex.user_name, "");

	printf("Trying with a zero AAC\n");
	search.in.acct_control = 0x0;
	search.in.realm = n1.data.nt5_ex.dns_domain;
	status = cldap_netlogon(cldap, iconv_convenience, tctx, &search);
	CHECK_STATUS(status, NT_STATUS_OK);
	CHECK_VAL(search.out.netlogon.data.nt5_ex.command, LOGON_SAM_LOGON_RESPONSE_EX);
	CHECK_STRING(search.out.netlogon.data.nt5_ex.user_name, "");

	printf("Trying with a zero AAC and user=Administrator\n");
	search.in.acct_control = 0x0;
	search.in.user = "******";
	search.in.realm = n1.data.nt5_ex.dns_domain;
	status = cldap_netlogon(cldap, iconv_convenience, tctx, &search);
	CHECK_STATUS(status, NT_STATUS_OK);
	CHECK_VAL(search.out.netlogon.data.nt5_ex.command, LOGON_SAM_LOGON_USER_UNKNOWN_EX);
	CHECK_STRING(search.out.netlogon.data.nt5_ex.user_name, "Administrator");

	printf("Trying with a bad AAC\n");
	search.in.user = NULL;
	search.in.acct_control = 0xFF00FF00;
	search.in.realm = n1.data.nt5_ex.dns_domain;
	status = cldap_netlogon(cldap, iconv_convenience, tctx, &search);
	CHECK_STATUS(status, NT_STATUS_OK);
	CHECK_VAL(search.out.netlogon.data.nt5_ex.command, LOGON_SAM_LOGON_RESPONSE_EX);
	CHECK_STRING(search.out.netlogon.data.nt5_ex.user_name, "");

	printf("Trying with a user only\n");
	search = empty_search;
	search.in.user = "******";
	status = cldap_netlogon(cldap, iconv_convenience, tctx, &search);
	CHECK_STATUS(status, NT_STATUS_OK);
	CHECK_STRING(search.out.netlogon.data.nt5_ex.dns_domain, n1.data.nt5_ex.dns_domain);
	CHECK_STRING(search.out.netlogon.data.nt5_ex.user_name, search.in.user);

	printf("Trying with just a bad username\n");
	search.in.user = "******";
	status = cldap_netlogon(cldap, iconv_convenience, tctx, &search);
	CHECK_STATUS(status, NT_STATUS_OK);
	CHECK_STRING(search.out.netlogon.data.nt5_ex.user_name, search.in.user);
	CHECK_STRING(search.out.netlogon.data.nt5_ex.dns_domain, n1.data.nt5_ex.dns_domain);
	CHECK_VAL(search.out.netlogon.data.nt5_ex.command, LOGON_SAM_LOGON_USER_UNKNOWN_EX);

	printf("Trying with just a bad domain\n");
	search = empty_search;
	search.in.realm = "___no_such_domain___";
	status = cldap_netlogon(cldap, iconv_convenience, tctx, &search);
	CHECK_STATUS(status, NT_STATUS_NOT_FOUND);

	printf("Trying with a incorrect domain and correct guid\n");
	search.in.domain_guid = GUID_string(tctx, &n1.data.nt5_ex.domain_uuid);
	status = cldap_netlogon(cldap, iconv_convenience, tctx, &search);
	CHECK_STATUS(status, NT_STATUS_OK);
	CHECK_STRING(search.out.netlogon.data.nt5_ex.dns_domain, n1.data.nt5_ex.dns_domain);
	CHECK_STRING(search.out.netlogon.data.nt5_ex.user_name, "");
	CHECK_VAL(search.out.netlogon.data.nt5_ex.command, LOGON_SAM_LOGON_RESPONSE_EX);

	printf("Trying with a incorrect domain and incorrect guid\n");
	search.in.domain_guid = GUID_string(tctx, &guid);
	status = cldap_netlogon(cldap, iconv_convenience, tctx, &search);
	CHECK_STATUS(status, NT_STATUS_NOT_FOUND);
	CHECK_STRING(search.out.netlogon.data.nt5_ex.dns_domain, n1.data.nt5_ex.dns_domain);
	CHECK_STRING(search.out.netlogon.data.nt5_ex.user_name, "");
	CHECK_VAL(search.out.netlogon.data.nt5_ex.command, LOGON_SAM_LOGON_RESPONSE_EX);

	printf("Trying with a incorrect GUID and correct domain\n");
	search.in.domain_guid = GUID_string(tctx, &guid);
	search.in.realm = n1.data.nt5_ex.dns_domain;
	status = cldap_netlogon(cldap, iconv_convenience, tctx, &search);
	CHECK_STATUS(status, NT_STATUS_OK);
	CHECK_STRING(search.out.netlogon.data.nt5_ex.dns_domain, n1.data.nt5_ex.dns_domain);
	CHECK_STRING(search.out.netlogon.data.nt5_ex.user_name, "");
	CHECK_VAL(search.out.netlogon.data.nt5_ex.command, LOGON_SAM_LOGON_RESPONSE_EX);

	return true;
}
Beispiel #10
0
/*
  test cldap netlogon server type flag "NBT_SERVER_DS_DNS_FOREST"
*/
static bool test_cldap_netlogon_flag_ds_dns_forest(struct torture_context *tctx,
	const char *dest)
{
	struct cldap_socket *cldap;
	NTSTATUS status;
	struct cldap_netlogon search;
	uint32_t server_type;
	struct netlogon_samlogon_response n1;
	struct smb_iconv_convenience *iconv_convenience = lp_iconv_convenience(tctx->lp_ctx);

	bool result = true;

	status = cldap_socket_init(tctx, NULL, NULL, NULL, &cldap);
	CHECK_STATUS(status, NT_STATUS_OK);

	printf("Testing netlogon server type flag NBT_SERVER_DS_DNS_FOREST: ");

	ZERO_STRUCT(search);
	search.in.dest_address = dest;
	search.in.dest_port = lp_cldap_port(tctx->lp_ctx);
	search.in.acct_control = -1;
	search.in.version = NETLOGON_NT_VERSION_5 | NETLOGON_NT_VERSION_5EX;
	search.in.map_response = true;

	status = cldap_netlogon(cldap, iconv_convenience, tctx, &search);
	CHECK_STATUS(status, NT_STATUS_OK);

	n1 = search.out.netlogon;
	if (n1.ntver == NETLOGON_NT_VERSION_5)
		server_type = n1.data.nt5.server_type;
	else if (n1.ntver == NETLOGON_NT_VERSION_5EX)
		server_type = n1.data.nt5_ex.server_type;

	if (server_type & DS_DNS_FOREST) {
		struct cldap_search search2;
		const char *attrs[] = { "defaultNamingContext", "rootDomainNamingContext", 
			NULL };
		struct ldb_context *ldb;
		struct ldb_message *msg;

		/* Trying to fetch the attributes "defaultNamingContext" and
		   "rootDomainNamingContext" */
		ZERO_STRUCT(search2);
		search2.in.dest_address = dest;
		search2.in.dest_port = lp_cldap_port(tctx->lp_ctx);
		search2.in.timeout = 10;
		search2.in.retries = 3;
		search2.in.filter = "(objectclass=*)";
		search2.in.attributes = attrs;

		status = cldap_search(cldap, tctx, &search2);
		CHECK_STATUS(status, NT_STATUS_OK);

		ldb = ldb_init(NULL, NULL);

		msg = ldap_msg_to_ldb(ldb, ldb, search2.out.response);

		/* Try to compare the two attributes */
		if (ldb_msg_element_compare(ldb_msg_find_element(msg, attrs[0]),
			ldb_msg_find_element(msg, attrs[1])))
			result = false;

		talloc_free(ldb);
	}

	if (result)
		printf("passed\n");
	else
		printf("failed\n");

	return result;
}
Beispiel #11
0
/*
  test cldap netlogon server type flags
*/
static bool test_cldap_netlogon_flags(struct torture_context *tctx,
	const char *dest)
{
	struct cldap_socket *cldap;
	NTSTATUS status;
	struct cldap_netlogon search;
	struct netlogon_samlogon_response n1;
	uint32_t server_type;
	struct smb_iconv_convenience *iconv_convenience = lp_iconv_convenience(tctx->lp_ctx);

	status = cldap_socket_init(tctx, NULL, NULL, NULL, &cldap);
	CHECK_STATUS(status, NT_STATUS_OK);

	printf("Printing out netlogon server type flags: %s\n", dest);

	ZERO_STRUCT(search);
	search.in.dest_address = dest;
	search.in.dest_port = lp_cldap_port(tctx->lp_ctx);
	search.in.acct_control = -1;
	search.in.version = NETLOGON_NT_VERSION_5 | NETLOGON_NT_VERSION_5EX;
	search.in.map_response = true;

	status = cldap_netlogon(cldap, iconv_convenience, tctx, &search);
	CHECK_STATUS(status, NT_STATUS_OK);

	n1 = search.out.netlogon;
	if (n1.ntver == NETLOGON_NT_VERSION_5)
		server_type = n1.data.nt5.server_type;
	else if (n1.ntver == NETLOGON_NT_VERSION_5EX)
		server_type = n1.data.nt5_ex.server_type;	

	printf("The word is: %i\n", server_type);
	if (server_type & NBT_SERVER_PDC)
		printf("NBT_SERVER_PDC ");
	if (server_type & NBT_SERVER_GC)
		printf("NBT_SERVER_GC ");
	if (server_type & NBT_SERVER_LDAP)
		printf("NBT_SERVER_LDAP ");
	if (server_type & NBT_SERVER_DS)
		printf("NBT_SERVER_DS ");
	if (server_type & NBT_SERVER_KDC)
		printf("NBT_SERVER_KDC ");
	if (server_type & NBT_SERVER_TIMESERV)
		printf("NBT_SERVER_TIMESERV ");
	if (server_type & NBT_SERVER_CLOSEST)
		printf("NBT_SERVER_CLOSEST ");
	if (server_type & NBT_SERVER_WRITABLE)
		printf("NBT_SERVER_WRITABLE ");
	if (server_type & NBT_SERVER_GOOD_TIMESERV)
		printf("NBT_SERVER_GOOD_TIMESERV ");
	if (server_type & NBT_SERVER_NDNC)
		printf("NBT_SERVER_NDNC ");
	if (server_type & NBT_SERVER_SELECT_SECRET_DOMAIN_6)
		printf("NBT_SERVER_SELECT_SECRET_DOMAIN_6");
	if (server_type & NBT_SERVER_FULL_SECRET_DOMAIN_6)
		printf("NBT_SERVER_FULL_SECRET_DOMAIN_6");
	if (server_type & DS_DNS_CONTROLLER)
		printf("DS_DNS_CONTROLLER ");
	if (server_type & DS_DNS_DOMAIN)
		printf("DS_DNS_DOMAIN ");
	if (server_type & DS_DNS_FOREST)
		printf("DS_DNS_FOREST ");

	printf("\n");

	return true;
}
Beispiel #12
0
/*
  test cldap netlogon server type flags
*/
static bool test_cldap_netlogon_flags(struct torture_context *tctx,
	const char *dest)
{
	struct cldap_socket *cldap;
	NTSTATUS status;
	struct cldap_netlogon search;
	struct netlogon_samlogon_response n1;
	uint32_t server_type;
	struct tsocket_address *dest_addr;
	int ret;

	ret = tsocket_address_inet_from_strings(tctx, "ip",
						dest,
						lpcfg_cldap_port(tctx->lp_ctx),
						&dest_addr);
	CHECK_VAL(ret, 0);

	/* cldap_socket_init should now know about the dest. address */
	status = cldap_socket_init(tctx, NULL, dest_addr, &cldap);
	CHECK_STATUS(status, NT_STATUS_OK);

	printf("Printing out netlogon server type flags: %s\n", dest);

	ZERO_STRUCT(search);
	search.in.dest_address = NULL;
	search.in.dest_port = 0;
	search.in.acct_control = -1;
	search.in.version = NETLOGON_NT_VERSION_5 | NETLOGON_NT_VERSION_5EX;
	search.in.map_response = true;

	status = cldap_netlogon(cldap, tctx, &search);
	CHECK_STATUS(status, NT_STATUS_OK);

	n1 = search.out.netlogon;
	if (n1.ntver == NETLOGON_NT_VERSION_5)
		server_type = n1.data.nt5.server_type;
	else if (n1.ntver == NETLOGON_NT_VERSION_5EX)
		server_type = n1.data.nt5_ex.server_type;	

	printf("The word is: %i\n", server_type);
	if (server_type & NBT_SERVER_PDC)
		printf("NBT_SERVER_PDC ");
	if (server_type & NBT_SERVER_GC)
		printf("NBT_SERVER_GC ");
	if (server_type & NBT_SERVER_LDAP)
		printf("NBT_SERVER_LDAP ");
	if (server_type & NBT_SERVER_DS)
		printf("NBT_SERVER_DS ");
	if (server_type & NBT_SERVER_KDC)
		printf("NBT_SERVER_KDC ");
	if (server_type & NBT_SERVER_TIMESERV)
		printf("NBT_SERVER_TIMESERV ");
	if (server_type & NBT_SERVER_CLOSEST)
		printf("NBT_SERVER_CLOSEST ");
	if (server_type & NBT_SERVER_WRITABLE)
		printf("NBT_SERVER_WRITABLE ");
	if (server_type & NBT_SERVER_GOOD_TIMESERV)
		printf("NBT_SERVER_GOOD_TIMESERV ");
	if (server_type & NBT_SERVER_NDNC)
		printf("NBT_SERVER_NDNC ");
	if (server_type & NBT_SERVER_SELECT_SECRET_DOMAIN_6)
		printf("NBT_SERVER_SELECT_SECRET_DOMAIN_6");
	if (server_type & NBT_SERVER_FULL_SECRET_DOMAIN_6)
		printf("NBT_SERVER_FULL_SECRET_DOMAIN_6");
	if (server_type & DS_DNS_CONTROLLER)
		printf("DS_DNS_CONTROLLER ");
	if (server_type & DS_DNS_DOMAIN)
		printf("DS_DNS_DOMAIN ");
	if (server_type & DS_DNS_FOREST_ROOT)
		printf("DS_DNS_FOREST_ROOT ");

	printf("\n");

	return true;
}
Beispiel #13
0
bool ads_cldap_netlogon(TALLOC_CTX *mem_ctx,
			const char *server,
			const char *realm,
			uint32_t nt_version,
			struct netlogon_samlogon_response **_reply)
{
	struct cldap_socket *cldap;
	struct cldap_netlogon io;
	struct netlogon_samlogon_response *reply;
	NTSTATUS status;
	struct in_addr addr;
	char addrstr[INET_ADDRSTRLEN];
	const char *dest_str;
	int ret;
	struct tsocket_address *dest_addr;

	addr = interpret_addr2(server);
	dest_str = inet_ntop(AF_INET, &addr,
			     addrstr, sizeof(addrstr));
	if (!dest_str) {
		DEBUG(2,("Failed to resolve[%s] into an address for cldap\n",
			 server));
		return false;
	}

	ret = tsocket_address_inet_from_strings(mem_ctx, "ipv4",
						dest_str, LDAP_PORT,
						&dest_addr);
	if (ret != 0) {
		status = map_nt_error_from_unix(errno);
		DEBUG(2,("Failed to create cldap tsocket_address for %s - %s\n",
			 dest_str, nt_errstr(status)));
		return false;
	}

	/*
	 * as we use a connected udp socket
	 */
	status = cldap_socket_init(mem_ctx, NULL, NULL, dest_addr, &cldap);
	TALLOC_FREE(dest_addr);
	if (!NT_STATUS_IS_OK(status)) {
		DEBUG(2,("Failed to create cldap socket to %s: %s\n",
			 dest_str, nt_errstr(status)));
		return false;
	}

	reply = talloc(cldap, struct netlogon_samlogon_response);
	if (!reply) {
		goto failed;
	}

	/*
	 * as we use a connected socket, so we don't need to specify the
	 * destination
	 */
	io.in.dest_address	= NULL;
	io.in.dest_port		= 0;
	io.in.realm		= realm;
	io.in.host		= NULL;
	io.in.user		= NULL;
	io.in.domain_guid	= NULL;
	io.in.domain_sid	= NULL;
	io.in.acct_control	= 0;
	io.in.version		= nt_version;
	io.in.map_response	= false;

	status = cldap_netlogon(cldap, NULL, reply, &io);
	if (!NT_STATUS_IS_OK(status)) {
		DEBUG(2,("cldap_netlogon() failed: %s\n", nt_errstr(status)));
		goto failed;
	}

	*reply = io.out.netlogon;
	*_reply = talloc_move(mem_ctx, &reply);
	TALLOC_FREE(cldap);
	return true;
failed:
	TALLOC_FREE(cldap);
	return false;
}