1
0
mirror of https://github.com/samba-team/samba.git synced 2025-01-08 21:18:16 +03:00

s4:cldap: rewrite the cldap library based on tsocket

metze
This commit is contained in:
Stefan Metzmacher 2009-02-13 13:13:54 +01:00
parent b69e72deda
commit c600e8ef42
12 changed files with 1029 additions and 633 deletions

View File

@ -20,8 +20,8 @@
*/
#include "includes.h"
#include <talloc.h>
#include "libcli/ldap/ldap.h"
#include "lib/socket/socket.h"
#include "lib/messaging/irpc.h"
#include "smbd/service_task.h"
#include "smbd/service.h"
@ -34,50 +34,67 @@
#include "ldb_wrap.h"
#include "auth/auth.h"
#include "param/param.h"
#include "../lib/tsocket/tsocket.h"
/*
handle incoming cldap requests
*/
static void cldapd_request_handler(struct cldap_socket *cldap,
struct ldap_message *ldap_msg,
struct socket_address *src)
static void cldapd_request_handler(struct cldap_socket *cldap,
void *private_data,
struct cldap_incoming *in)
{
struct cldapd_server *cldapd = talloc_get_type(private_data,
struct cldapd_server);
struct ldap_SearchRequest *search;
if (ldap_msg->type != LDAP_TAG_SearchRequest) {
DEBUG(0,("Invalid CLDAP request type %d from %s:%d\n",
ldap_msg->type, src->addr, src->port));
cldap_error_reply(cldap, ldap_msg->messageid, src,
if (in->ldap_msg->type != LDAP_TAG_SearchRequest) {
DEBUG(0,("Invalid CLDAP request type %d from %s\n",
in->ldap_msg->type,
tsocket_address_string(in->src, in)));
cldap_error_reply(cldap, in->ldap_msg->messageid, in->src,
LDAP_OPERATIONS_ERROR, "Invalid CLDAP request");
talloc_free(in);
return;
}
search = &ldap_msg->r.SearchRequest;
search = &in->ldap_msg->r.SearchRequest;
if (strcmp("", search->basedn) != 0) {
DEBUG(0,("Invalid CLDAP basedn '%s' from %s:%d\n",
search->basedn, src->addr, src->port));
cldap_error_reply(cldap, ldap_msg->messageid, src,
DEBUG(0,("Invalid CLDAP basedn '%s' from %s\n",
search->basedn,
tsocket_address_string(in->src, in)));
cldap_error_reply(cldap, in->ldap_msg->messageid, in->src,
LDAP_OPERATIONS_ERROR, "Invalid CLDAP basedn");
talloc_free(in);
return;
}
if (search->scope != LDAP_SEARCH_SCOPE_BASE) {
DEBUG(0,("Invalid CLDAP scope %d from %s:%d\n",
search->scope, src->addr, src->port));
cldap_error_reply(cldap, ldap_msg->messageid, src,
DEBUG(0,("Invalid CLDAP scope %d from %s\n",
search->scope,
tsocket_address_string(in->src, in)));
cldap_error_reply(cldap, in->ldap_msg->messageid, in->src,
LDAP_OPERATIONS_ERROR, "Invalid CLDAP scope");
talloc_free(in);
return;
}
if (search->num_attributes == 1 &&
strcasecmp(search->attributes[0], "netlogon") == 0) {
cldapd_netlogon_request(cldap, ldap_msg->messageid,
search->tree, src);
cldapd_netlogon_request(cldap,
cldapd,
in,
in->ldap_msg->messageid,
search->tree,
in->src);
talloc_free(in);
return;
}
cldapd_rootdse_request(cldap, ldap_msg->messageid,
search, src);
cldapd_rootdse_request(cldap, cldapd, in,
in->ldap_msg->messageid,
search, in->src);
talloc_free(in);
}
@ -88,28 +105,36 @@ static NTSTATUS cldapd_add_socket(struct cldapd_server *cldapd, struct loadparm_
const char *address)
{
struct cldap_socket *cldapsock;
struct socket_address *socket_address;
struct tsocket_address *socket_address;
NTSTATUS status;
int ret;
/* listen for unicasts on the CLDAP port (389) */
cldapsock = cldap_socket_init(cldapd, cldapd->task->event_ctx, lp_iconv_convenience(cldapd->task->lp_ctx));
NT_STATUS_HAVE_NO_MEMORY(cldapsock);
socket_address = socket_address_from_strings(cldapsock, cldapsock->sock->backend_name,
address, lp_cldap_port(lp_ctx));
if (!socket_address) {
talloc_free(cldapsock);
return NT_STATUS_NO_MEMORY;
}
status = socket_listen(cldapsock->sock, socket_address, 0, 0);
if (!NT_STATUS_IS_OK(status)) {
DEBUG(0,("Failed to bind to %s:%d - %s\n",
address, lp_cldap_port(lp_ctx), nt_errstr(status)));
talloc_free(cldapsock);
ret = tsocket_address_inet_from_strings(cldapd,
"ip",
address,
lp_cldap_port(lp_ctx),
&socket_address);
if (ret != 0) {
status = map_nt_error_from_unix(errno);
DEBUG(0,("invalid address %s:%d - %s:%s\n",
address, lp_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);
@ -117,7 +142,6 @@ static NTSTATUS cldapd_add_socket(struct cldapd_server *cldapd, struct loadparm_
return NT_STATUS_OK;
}
/*
setup our listening sockets on the configured network interfaces
*/

View File

@ -24,7 +24,6 @@
#include "lib/ldb/include/ldb.h"
#include "lib/ldb/include/ldb_errors.h"
#include "lib/events/events.h"
#include "lib/socket/socket.h"
#include "smbd/service_task.h"
#include "cldap_server/cldap_server.h"
#include "librpc/gen_ndr/ndr_misc.h"
@ -36,6 +35,8 @@
#include "system/network.h"
#include "lib/socket/netif.h"
#include "param/param.h"
#include "../lib/tsocket/tsocket.h"
/*
fill in the cldap netlogon union for a given version
*/
@ -402,12 +403,13 @@ NTSTATUS fill_netlogon_samlogon_response(struct ldb_context *sam_ctx,
/*
handle incoming cldap requests
*/
void cldapd_netlogon_request(struct cldap_socket *cldap,
void cldapd_netlogon_request(struct cldap_socket *cldap,
struct cldapd_server *cldapd,
TALLOC_CTX *tmp_ctx,
uint32_t message_id,
struct ldb_parse_tree *tree,
struct socket_address *src)
struct tsocket_address *src)
{
struct cldapd_server *cldapd = talloc_get_type(cldap->incoming.private_data, struct cldapd_server);
int i;
const char *domain = NULL;
const char *host = NULL;
@ -419,8 +421,6 @@ void cldapd_netlogon_request(struct cldap_socket *cldap,
struct netlogon_samlogon_response netlogon;
NTSTATUS status = NT_STATUS_INVALID_PARAMETER;
TALLOC_CTX *tmp_ctx = talloc_new(cldap);
if (tree->operation != LDB_OP_AND) goto failed;
/* extract the query elements */
@ -478,24 +478,25 @@ void cldapd_netlogon_request(struct cldap_socket *cldap,
domain, host, user, version, domain_guid));
status = fill_netlogon_samlogon_response(cldapd->samctx, tmp_ctx, domain, NULL, NULL, domain_guid,
user, acct_control, src->addr,
user, acct_control,
tsocket_address_inet_addr_string(src, tmp_ctx),
version, cldapd->task->lp_ctx, &netlogon);
if (!NT_STATUS_IS_OK(status)) {
goto failed;
}
status = cldap_netlogon_reply(cldap, message_id, src, version,
status = cldap_netlogon_reply(cldap,
lp_iconv_convenience(cldapd->task->lp_ctx),
message_id, src, version,
&netlogon);
if (!NT_STATUS_IS_OK(status)) {
goto failed;
}
talloc_free(tmp_ctx);
return;
failed:
DEBUG(2,("cldap netlogon query failed domain=%s host=%s version=%d - %s\n",
domain, host, version, nt_errstr(status)));
talloc_free(tmp_ctx);
cldap_empty_reply(cldap, message_id, src);
cldap_empty_reply(cldap, message_id, src);
}

View File

@ -20,19 +20,15 @@
*/
#include "includes.h"
#include <tevent.h>
#include "libcli/ldap/ldap.h"
#include "lib/ldb/include/ldb.h"
#include "lib/ldb/include/ldb_errors.h"
#include "lib/events/events.h"
#include "lib/socket/socket.h"
#include "smbd/service_task.h"
#include "cldap_server/cldap_server.h"
#include "librpc/gen_ndr/ndr_misc.h"
#include "dsdb/samdb/samdb.h"
#include "auth/auth.h"
#include "ldb_wrap.h"
#include "system/network.h"
#include "lib/socket/netif.h"
static void cldapd_rootdse_fill(struct cldapd_server *cldapd,
TALLOC_CTX *mem_ctx,
@ -151,15 +147,15 @@ done:
handle incoming cldap requests
*/
void cldapd_rootdse_request(struct cldap_socket *cldap,
struct cldapd_server *cldapd,
TALLOC_CTX *tmp_ctx,
uint32_t message_id,
struct ldap_SearchRequest *search,
struct socket_address *src)
struct tsocket_address *src)
{
struct cldapd_server *cldapd = talloc_get_type(cldap->incoming.private_data, struct cldapd_server);
NTSTATUS status;
struct cldap_reply reply;
struct ldap_Result result;
TALLOC_CTX *tmp_ctx = talloc_new(cldap);
ZERO_STRUCT(result);
@ -176,6 +172,5 @@ void cldapd_rootdse_request(struct cldap_socket *cldap,
ldb_filter_from_tree(tmp_ctx, search->tree), nt_errstr(status)));
}
talloc_free(tmp_ctx);
return;
}

File diff suppressed because it is too large Load Diff

View File

@ -19,89 +19,29 @@
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "../lib/util/asn1.h"
#include "../libcli/netlogon.h"
struct ldap_message;
struct tsocket_address;
struct cldap_socket;
enum cldap_request_state {CLDAP_REQUEST_SEND,
CLDAP_REQUEST_WAIT,
CLDAP_REQUEST_DONE,
CLDAP_REQUEST_ERROR};
/*
a cldap request packet
*/
struct cldap_request {
struct cldap_request *next, *prev;
struct cldap_socket *cldap;
enum cldap_request_state state;
NTSTATUS status;
/* where to send the request */
struct socket_address *dest;
/* timeout between retries (seconds) */
int timeout;
int num_retries;
bool is_reply;
/* the ldap message_id */
int message_id;
struct tevent_timer *te;
/* the encoded request */
DATA_BLOB encoded;
/* the reply data */
struct asn1_data *asn1;
/* information on what to do on completion */
struct {
void (*fn)(struct cldap_request *);
void *private_data;
} async;
struct cldap_incoming {
int recv_errno;
uint8_t *buf;
size_t len;
struct tsocket_address *src;
struct ldap_message *ldap_msg;
};
/*
context structure for operations on cldap packets
*/
struct cldap_socket {
struct socket_context *sock;
struct tevent_context *event_ctx;
struct smb_iconv_convenience *iconv_convenience;
/* the fd event */
struct tevent_fd *fde;
/* a queue of outgoing requests */
struct cldap_request *send_queue;
/* mapping from message_id to pending request */
struct idr_context *idr;
/* what to do with incoming request packets */
struct {
void (*handler)(struct cldap_socket *, struct ldap_message *,
struct socket_address *);
void *private_data;
} incoming;
};
/*
a general cldap search request
a general cldap search request
*/
struct cldap_search {
struct {
const char *dest_address;
uint16_t dest_port;
const char *filter;
const char **attributes;
const char * const *attributes;
int timeout;
int retries;
} in;
@ -111,39 +51,43 @@ struct cldap_search {
} out;
};
struct cldap_socket *cldap_socket_init(TALLOC_CTX *mem_ctx,
struct tevent_context *event_ctx,
struct smb_iconv_convenience *iconv_convenience);
NTSTATUS cldap_set_incoming_handler(struct cldap_socket *cldap,
void (*handler)(struct cldap_socket *, struct ldap_message *,
struct socket_address *),
void *private_data);
struct cldap_request *cldap_search_send(struct cldap_socket *cldap,
struct cldap_search *io);
NTSTATUS cldap_search_recv(struct cldap_request *req, TALLOC_CTX *mem_ctx,
struct cldap_search *io);
NTSTATUS cldap_search(struct cldap_socket *cldap, TALLOC_CTX *mem_ctx,
struct cldap_search *io);
NTSTATUS cldap_socket_init(TALLOC_CTX *mem_ctx,
struct tevent_context *ev,
const struct tsocket_address *local_addr,
const struct tsocket_address *remote_addr,
struct cldap_socket **_cldap);
NTSTATUS cldap_set_incoming_handler(struct cldap_socket *cldap,
void (*handler)(struct cldap_socket *,
void *private_data,
struct cldap_incoming *),
void *private_data);
struct tevent_req *cldap_search_send(TALLOC_CTX *mem_ctx,
struct cldap_socket *cldap,
const struct cldap_search *io);
NTSTATUS cldap_search_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx,
struct cldap_search *io);
NTSTATUS cldap_search(struct cldap_socket *cldap, TALLOC_CTX *mem_ctx,
struct cldap_search *io);
/*
a general cldap reply
*/
struct cldap_reply {
uint32_t messageid;
struct socket_address *dest;
struct tsocket_address *dest;
struct ldap_SearchResEntry *response;
struct ldap_Result *result;
};
NTSTATUS cldap_reply_send(struct cldap_socket *cldap, struct cldap_reply *io);
NTSTATUS cldap_empty_reply(struct cldap_socket *cldap,
NTSTATUS cldap_empty_reply(struct cldap_socket *cldap,
uint32_t message_id,
struct socket_address *src);
NTSTATUS cldap_error_reply(struct cldap_socket *cldap,
struct tsocket_address *dst);
NTSTATUS cldap_error_reply(struct cldap_socket *cldap,
uint32_t message_id,
struct socket_address *src,
struct tsocket_address *dst,
int resultcode,
const char *errormessage);
@ -168,15 +112,22 @@ struct cldap_netlogon {
} out;
};
struct cldap_request *cldap_netlogon_send(struct cldap_socket *cldap,
struct cldap_netlogon *io);
NTSTATUS cldap_netlogon_recv(struct cldap_request *req,
TALLOC_CTX *mem_ctx,
struct tevent_req *cldap_netlogon_send(TALLOC_CTX *mem_ctx,
struct cldap_socket *cldap,
const struct cldap_netlogon *io);
NTSTATUS cldap_netlogon_recv(struct tevent_req *req,
struct smb_iconv_convenience *iconv_convenience,
TALLOC_CTX *mem_ctx,
struct cldap_netlogon *io);
NTSTATUS cldap_netlogon(struct cldap_socket *cldap,
TALLOC_CTX *mem_ctx, struct cldap_netlogon *io);
NTSTATUS cldap_netlogon_reply(struct cldap_socket *cldap,
NTSTATUS cldap_netlogon(struct cldap_socket *cldap,
struct smb_iconv_convenience *iconv_convenience,
TALLOC_CTX *mem_ctx,
struct cldap_netlogon *io);
NTSTATUS cldap_netlogon_reply(struct cldap_socket *cldap,
struct smb_iconv_convenience *iconv_convenience,
uint32_t message_id,
struct socket_address *src,
struct tsocket_address *dst,
uint32_t version,
struct netlogon_samlogon_response *netlogon);

View File

@ -98,7 +98,7 @@ LIBCLI_DGRAM_OBJ_FILES = $(addprefix $(libclisrcdir)/dgram/, \
[SUBSYSTEM::LIBCLI_CLDAP]
PUBLIC_DEPENDENCIES = LIBCLI_LDAP
PRIVATE_DEPENDENCIES = LIBSAMBA-UTIL LIBLDB LIBCLI_NETLOGON
PRIVATE_DEPENDENCIES = LIBTSOCKET LIBSAMBA-UTIL UTIL_TEVENT LIBLDB LIBCLI_NETLOGON
LIBCLI_CLDAP_OBJ_FILES = $(libclisrcdir)/cldap/cldap.o
# PUBLIC_HEADERS += $(libclisrcdir)/cldap/cldap.h

View File

@ -731,12 +731,12 @@ struct libnet_BecomeDC_state {
struct libnet_BecomeDC_Callbacks callbacks;
};
static void becomeDC_recv_cldap(struct cldap_request *req);
static void becomeDC_recv_cldap(struct tevent_req *req);
static void becomeDC_send_cldap(struct libnet_BecomeDC_state *s)
{
struct composite_context *c = s->creq;
struct cldap_request *req;
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);
@ -749,25 +749,27 @@ static void becomeDC_send_cldap(struct libnet_BecomeDC_state *s)
s->cldap.io.in.version = NETLOGON_NT_VERSION_5 | NETLOGON_NT_VERSION_5EX;
s->cldap.io.in.map_response = true;
s->cldap.sock = cldap_socket_init(s, s->libnet->event_ctx,
lp_iconv_convenience(s->libnet->lp_ctx));
if (composite_nomem(s->cldap.sock, c)) return;
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->cldap.sock, &s->cldap.io);
req = cldap_netlogon_send(s, s->cldap.sock, &s->cldap.io);
if (composite_nomem(req, c)) return;
req->async.fn = becomeDC_recv_cldap;
req->async.private_data = s;
tevent_req_set_callback(req, becomeDC_recv_cldap, s);
}
static void becomeDC_connect_ldap1(struct libnet_BecomeDC_state *s);
static void becomeDC_recv_cldap(struct cldap_request *req)
static void becomeDC_recv_cldap(struct tevent_req *req)
{
struct libnet_BecomeDC_state *s = talloc_get_type(req->async.private_data,
struct libnet_BecomeDC_state *s = tevent_req_callback_data(req,
struct libnet_BecomeDC_state);
struct composite_context *c = s->creq;
c->status = cldap_netlogon_recv(req, s, &s->cldap.io);
c->status = cldap_netlogon_recv(req,
lp_iconv_convenience(s->libnet->lp_ctx),
s, &s->cldap.io);
talloc_free(req);
if (!composite_is_ok(c)) return;
s->cldap.netlogon = s->cldap.io.out.netlogon.data.nt5_ex;

View File

@ -56,8 +56,14 @@ NTSTATUS libnet_FindSite(TALLOC_CTX *ctx, struct libnet_context *lctx, struct li
search.in.version = NETLOGON_NT_VERSION_5 | NETLOGON_NT_VERSION_5EX;
search.in.map_response = true;
cldap = cldap_socket_init(tmp_ctx, lctx->event_ctx, lp_iconv_convenience(lctx->lp_ctx));
status = cldap_netlogon(cldap, tmp_ctx, &search);
/* 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) {
/*

View File

@ -250,12 +250,12 @@ struct libnet_UnbecomeDC_state {
} dest_dsa;
};
static void unbecomeDC_recv_cldap(struct cldap_request *req);
static void unbecomeDC_recv_cldap(struct tevent_req *req);
static void unbecomeDC_send_cldap(struct libnet_UnbecomeDC_state *s)
{
struct composite_context *c = s->creq;
struct cldap_request *req;
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);
@ -268,25 +268,27 @@ static void unbecomeDC_send_cldap(struct libnet_UnbecomeDC_state *s)
s->cldap.io.in.version = NETLOGON_NT_VERSION_5 | NETLOGON_NT_VERSION_5EX;
s->cldap.io.in.map_response = true;
s->cldap.sock = cldap_socket_init(s, s->libnet->event_ctx,
lp_iconv_convenience(s->libnet->lp_ctx));
if (composite_nomem(s->cldap.sock, c)) return;
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->cldap.sock, &s->cldap.io);
req = cldap_netlogon_send(s, s->cldap.sock, &s->cldap.io);
if (composite_nomem(req, c)) return;
req->async.fn = unbecomeDC_recv_cldap;
req->async.private_data = s;
tevent_req_set_callback(req, unbecomeDC_recv_cldap, s);
}
static void unbecomeDC_connect_ldap(struct libnet_UnbecomeDC_state *s);
static void unbecomeDC_recv_cldap(struct cldap_request *req)
static void unbecomeDC_recv_cldap(struct tevent_req *req)
{
struct libnet_UnbecomeDC_state *s = talloc_get_type(req->async.private_data,
struct libnet_UnbecomeDC_state *s = tevent_req_callback_data(req,
struct libnet_UnbecomeDC_state);
struct composite_context *c = s->creq;
c->status = cldap_netlogon_recv(req, s, &s->cldap.io);
c->status = cldap_netlogon_recv(req,
lp_iconv_convenience(s->libnet->lp_ctx),
s, &s->cldap.io);
talloc_free(req);
if (!composite_is_ok(c)) return;
s->cldap.netlogon = s->cldap.io.out.netlogon.data.nt5_ex;

View File

@ -28,6 +28,7 @@
#include "torture/torture.h"
#include "lib/ldb/include/ldb.h"
#include "param/param.h"
#include "../lib/tsocket/tsocket.h"
#define CHECK_STATUS(status, correct) torture_assert_ntstatus_equal(tctx, status, correct, "incorrect status")
@ -45,12 +46,21 @@ static bool test_cldap_netlogon(struct torture_context *tctx, const char *dest)
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;
cldap = cldap_socket_init(tctx, tctx->ev, lp_iconv_convenience(tctx->lp_ctx));
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 = dest;
search.in.dest_port = lp_cldap_port(tctx->lp_ctx);
search.in.dest_address = NULL;//dest;
search.in.dest_port = 0;//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;
@ -59,7 +69,7 @@ static bool test_cldap_netlogon(struct torture_context *tctx, const char *dest)
printf("Trying without any attributes\n");
search = empty_search;
status = cldap_netlogon(cldap, tctx, &search);
status = cldap_netlogon(cldap, iconv_convenience, tctx, &search);
CHECK_STATUS(status, NT_STATUS_OK);
n1 = search.out.netlogon;
@ -72,7 +82,7 @@ static bool test_cldap_netlogon(struct torture_context *tctx, const char *dest)
for (i=0;i<256;i++) {
search.in.version = i;
printf("Trying netlogon level %d\n", i);
status = cldap_netlogon(cldap, tctx, &search);
status = cldap_netlogon(cldap, iconv_convenience, tctx, &search);
CHECK_STATUS(status, NT_STATUS_OK);
}
@ -80,19 +90,19 @@ static bool test_cldap_netlogon(struct torture_context *tctx, const char *dest)
for (i=0;i<31;i++) {
search.in.version = (1<<i);
printf("Trying netlogon level 0x%x\n", i);
status = cldap_netlogon(cldap, tctx, &search);
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, tctx, &search);
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, tctx, &search);
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);
@ -100,20 +110,20 @@ static bool test_cldap_netlogon(struct torture_context *tctx, const char *dest)
printf("Trying with User=Administrator\n");
search.in.user = "Administrator";
status = cldap_netlogon(cldap, tctx, &search);
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, tctx, &search);
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, tctx, &search);
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);
@ -121,7 +131,7 @@ static bool test_cldap_netlogon(struct torture_context *tctx, const char *dest)
printf("Trying with User=Administrator\n");
search.in.user = "Administrator";
status = cldap_netlogon(cldap, tctx, &search);
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);
@ -132,7 +142,7 @@ static bool test_cldap_netlogon(struct torture_context *tctx, const char *dest)
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, tctx, &search);
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);
@ -141,13 +151,13 @@ static bool test_cldap_netlogon(struct torture_context *tctx, const char *dest)
guid = GUID_random();
search.in.user = NULL;
search.in.domain_guid = GUID_string(tctx, &guid);
status = cldap_netlogon(cldap, tctx, &search);
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, tctx, &search);
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, "");
@ -155,7 +165,7 @@ static bool test_cldap_netlogon(struct torture_context *tctx, const char *dest)
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, tctx, &search);
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, "");
@ -164,7 +174,7 @@ static bool test_cldap_netlogon(struct torture_context *tctx, const char *dest)
search.in.acct_control = 0x0;
search.in.user = "Administrator";
search.in.realm = n1.data.nt5_ex.dns_domain;
status = cldap_netlogon(cldap, tctx, &search);
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");
@ -173,7 +183,7 @@ static bool test_cldap_netlogon(struct torture_context *tctx, const char *dest)
search.in.user = NULL;
search.in.acct_control = 0xFF00FF00;
search.in.realm = n1.data.nt5_ex.dns_domain;
status = cldap_netlogon(cldap, tctx, &search);
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, "");
@ -181,14 +191,14 @@ static bool test_cldap_netlogon(struct torture_context *tctx, const char *dest)
printf("Trying with a user only\n");
search = empty_search;
search.in.user = "Administrator";
status = cldap_netlogon(cldap, tctx, &search);
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 = "___no_such_user___";
status = cldap_netlogon(cldap, tctx, &search);
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);
@ -197,12 +207,12 @@ static bool test_cldap_netlogon(struct torture_context *tctx, const char *dest)
printf("Trying with just a bad domain\n");
search = empty_search;
search.in.realm = "___no_such_domain___";
status = cldap_netlogon(cldap, tctx, &search);
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, tctx, &search);
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, "");
@ -210,7 +220,7 @@ static bool test_cldap_netlogon(struct torture_context *tctx, const char *dest)
printf("Trying with a incorrect domain and incorrect guid\n");
search.in.domain_guid = GUID_string(tctx, &guid);
status = cldap_netlogon(cldap, tctx, &search);
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, "");
@ -219,7 +229,7 @@ static bool test_cldap_netlogon(struct torture_context *tctx, const char *dest)
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, tctx, &search);
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, "");
@ -239,10 +249,12 @@ static bool test_cldap_netlogon_flags(struct torture_context *tctx,
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);
cldap = cldap_socket_init(tctx, tctx->ev, 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:\n");
printf("Printing out netlogon server type flags: %s\n", dest);
ZERO_STRUCT(search);
search.in.dest_address = dest;
@ -251,7 +263,7 @@ static bool test_cldap_netlogon_flags(struct torture_context *tctx,
search.in.version = NETLOGON_NT_VERSION_5 | NETLOGON_NT_VERSION_5EX;
search.in.map_response = true;
status = cldap_netlogon(cldap, tctx, &search);
status = cldap_netlogon(cldap, iconv_convenience, tctx, &search);
CHECK_STATUS(status, NT_STATUS_OK);
n1 = search.out.netlogon;
@ -348,10 +360,12 @@ static bool test_cldap_netlogon_flag_ds_dns_forest(struct torture_context *tctx,
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;
cldap = cldap_socket_init(tctx, tctx->ev, lp_iconv_convenience(tctx->lp_ctx));
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: ");
@ -362,7 +376,7 @@ static bool test_cldap_netlogon_flag_ds_dns_forest(struct torture_context *tctx,
search.in.version = NETLOGON_NT_VERSION_5 | NETLOGON_NT_VERSION_5EX;
search.in.map_response = true;
status = cldap_netlogon(cldap, tctx, &search);
status = cldap_netlogon(cldap, iconv_convenience, tctx, &search);
CHECK_STATUS(status, NT_STATUS_OK);
n1 = search.out.netlogon;
@ -423,7 +437,8 @@ static bool test_cldap_generic(struct torture_context *tctx, const char *dest)
const char *attrs2[] = { "currentTime", "highestCommittedUSN", "netlogon", NULL };
const char *attrs3[] = { "netlogon", NULL };
cldap = cldap_socket_init(tctx, tctx->ev, lp_iconv_convenience(tctx->lp_ctx));
status = cldap_socket_init(tctx, NULL, NULL, NULL, &cldap);
CHECK_STATUS(status, NT_STATUS_OK);
ZERO_STRUCT(search);
search.in.dest_address = dest;

View File

@ -20,24 +20,28 @@
*/
#include "includes.h"
#include "lib/events/events.h"
#include <tevent.h>
#include "libcli/cldap/cldap.h"
#include "libcli/resolve/resolve.h"
#include "torture/torture.h"
#include "param/param.h"
struct bench_state {
struct torture_context *tctx;
int pass_count, fail_count;
};
static void request_netlogon_handler(struct cldap_request *req)
static void request_netlogon_handler(struct tevent_req *req)
{
struct cldap_netlogon io;
struct bench_state *state = talloc_get_type(req->async.private_data, struct bench_state);
struct bench_state *state = tevent_req_callback_data(req, struct bench_state);
NTSTATUS status;
TALLOC_CTX *tmp_ctx = talloc_new(NULL);
io.in.version = 6;
status = cldap_netlogon_recv(req, tmp_ctx, &io);
status = cldap_netlogon_recv(req,
lp_iconv_convenience(state->tctx->lp_ctx),
tmp_ctx, &io);
talloc_free(req);
if (NT_STATUS_IS_OK(status)) {
state->pass_count++;
} else {
@ -58,10 +62,13 @@ static bool bench_cldap_netlogon(struct torture_context *tctx, const char *addre
int timelimit = torture_setting_int(tctx, "timelimit", 10);
struct cldap_netlogon search;
struct bench_state *state;
NTSTATUS status;
cldap = cldap_socket_init(tctx, tctx->ev, lp_iconv_convenience(tctx->lp_ctx));
status = cldap_socket_init(tctx, tctx->ev, NULL, NULL, &cldap);
torture_assert_ntstatus_ok(tctx, status, "cldap_socket_init");
state = talloc_zero(tctx, struct bench_state);
state->tctx = tctx;
ZERO_STRUCT(search);
search.in.dest_address = address;
@ -72,11 +79,11 @@ static bool bench_cldap_netlogon(struct torture_context *tctx, const char *addre
printf("Running CLDAP/netlogon for %d seconds\n", timelimit);
while (timeval_elapsed(&tv) < timelimit) {
while (num_sent - (state->pass_count+state->fail_count) < 10) {
struct cldap_request *req;
req = cldap_netlogon_send(cldap, &search);
struct tevent_req *req;
req = cldap_netlogon_send(state, cldap, &search);
tevent_req_set_callback(req, request_netlogon_handler, state);
req->async.private_data = state;
req->async.fn = request_netlogon_handler;
num_sent++;
if (num_sent % 50 == 0) {
if (torture_setting_bool(tctx, "progress", true)) {
@ -88,11 +95,11 @@ static bool bench_cldap_netlogon(struct torture_context *tctx, const char *addre
}
}
event_loop_once(cldap->event_ctx);
tevent_loop_once(tctx->ev);
}
while (num_sent != (state->pass_count + state->fail_count)) {
event_loop_once(cldap->event_ctx);
tevent_loop_once(tctx->ev);
}
printf("%.1f queries per second (%d failures) \n",
@ -103,13 +110,14 @@ static bool bench_cldap_netlogon(struct torture_context *tctx, const char *addre
return ret;
}
static void request_rootdse_handler(struct cldap_request *req)
static void request_rootdse_handler(struct tevent_req *req)
{
struct cldap_search io;
struct bench_state *state = talloc_get_type(req->async.private_data, struct bench_state);
struct bench_state *state = tevent_req_callback_data(req, struct bench_state);
NTSTATUS status;
TALLOC_CTX *tmp_ctx = talloc_new(NULL);
status = cldap_search_recv(req, tmp_ctx, &io);
talloc_free(req);
if (NT_STATUS_IS_OK(status)) {
state->pass_count++;
} else {
@ -130,8 +138,10 @@ static bool bench_cldap_rootdse(struct torture_context *tctx, const char *addres
int timelimit = torture_setting_int(tctx, "timelimit", 10);
struct cldap_search search;
struct bench_state *state;
NTSTATUS status;
cldap = cldap_socket_init(tctx, tctx->ev, lp_iconv_convenience(tctx->lp_ctx));
status = cldap_socket_init(tctx, tctx->ev, NULL, NULL, &cldap);
torture_assert_ntstatus_ok(tctx, status, "cldap_socket_init");
state = talloc_zero(tctx, struct bench_state);
@ -145,11 +155,11 @@ static bool bench_cldap_rootdse(struct torture_context *tctx, const char *addres
printf("Running CLDAP/rootdse for %d seconds\n", timelimit);
while (timeval_elapsed(&tv) < timelimit) {
while (num_sent - (state->pass_count+state->fail_count) < 10) {
struct cldap_request *req;
req = cldap_search_send(cldap, &search);
struct tevent_req *req;
req = cldap_search_send(state, cldap, &search);
tevent_req_set_callback(req, request_rootdse_handler, state);
req->async.private_data = state;
req->async.fn = request_rootdse_handler;
num_sent++;
if (num_sent % 50 == 0) {
if (torture_setting_bool(tctx, "progress", true)) {

View File

@ -273,7 +273,12 @@ static bool test_GetInfo(struct torture_context *tctx, struct DsSyncTest *ctx)
struct cldap_socket *cldap;
struct cldap_netlogon search;
cldap = cldap_socket_init(ctx, tctx->ev, lp_iconv_convenience(tctx->lp_ctx));
status = cldap_socket_init(ctx, NULL, NULL, NULL, &cldap);
if (!NT_STATUS_IS_OK(status)) {
printf("failed to setup cldap socket - %s\n",
nt_errstr(status));
return false;
}
r.in.bind_handle = &ctx->admin.drsuapi.bind_handle;
r.in.level = 1;
@ -311,7 +316,7 @@ static bool test_GetInfo(struct torture_context *tctx, struct DsSyncTest *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, ctx, &search);
status = cldap_netlogon(cldap, lp_iconv_convenience(tctx->lp_ctx), ctx, &search);
if (!NT_STATUS_IS_OK(status)) {
const char *errstr = nt_errstr(status);
ctx->site_name = talloc_asprintf(ctx, "%s", "Default-First-Site-Name");