1
0
mirror of https://github.com/samba-team/samba.git synced 2024-12-22 13:34:15 +03:00

r5902: A rather large change...

I wanted to add a simple 'workstation' argument to the DCERPC
authenticated binding calls, but this patch kind of grew from there.

With SCHANNEL, the 'workstation' name (the netbios name of the client)
matters, as this is what ties the session between the NETLOGON ops and
the SCHANNEL bind.  This changes a lot of files, and these will again
be changed when jelmer does the credentials work.

I also correct some schannel IDL to distinguish between workstation
names and account names.  The distinction matters for domain trust
accounts.

Issues in handling this (issues with lifetime of talloc pointers)
caused me to change the 'creds_CredentialsState' and 'struct
dcerpc_binding' pointers to always be talloc()ed pointers.

In the schannel DB, we now store both the domain and computername, and
query on both.  This should ensure we fault correctly when the domain
is specified incorrectly in the SCHANNEL bind.

In the RPC-SCHANNEL test, I finally fixed a bug that vl pointed out,
where the comment claimed we re-used a connection, but in fact we made
a new connection.

This was achived by breaking apart some of the
dcerpc_secondary_connection() logic.

The addition of workstation handling was also propogated to NTLMSSP
and GENSEC, for completeness.

The RPC-SAMSYNC test has been cleaned up a little, using a loop over
usernames/passwords rather than manually expanded tests.  This will be
expanded further (the code in #if 0 in this patch) to use a newly
created user account for testing.

In making this test pass test_rpc.sh, I found a bug in the RPC-ECHO
server, caused by the removal of [ref] and the assoicated pointer from
the IDL.  This has been re-added, until the underlying pidl issues are
solved.
This commit is contained in:
Andrew Bartlett 2005-03-19 08:34:43 +00:00 committed by Gerald (Jerry) Carter
parent d585e1a759
commit 824289dcc2
44 changed files with 717 additions and 545 deletions

View File

@ -2558,6 +2558,7 @@ static BOOL browse_host(const char *query_host)
status = dcerpc_pipe_connect(&p, binding,
DCERPC_SRVSVC_UUID,
DCERPC_SRVSVC_VERSION,
lp_netbios_name(),
domain,
username, password);
if (!NT_STATUS_IS_OK(status)) {

View File

@ -77,7 +77,7 @@ static const char *get_protocol_name(enum epm_protocol protocol)
static void add_epm_entry(TALLOC_CTX *mem_ctx, const char *annotation, struct epm_tower *t)
{
struct dcerpc_binding bd;
struct dcerpc_binding *bd;
int i;
NTSTATUS status;
GtkTreeIter toweriter;
@ -89,10 +89,10 @@ static void add_epm_entry(TALLOC_CTX *mem_ctx, const char *annotation, struct ep
}
/* Don't show UUID's */
ZERO_STRUCT(bd.object);
ZERO_STRUCT(bd->object);
gtk_tree_store_append(store_eps, &toweriter, NULL);
gtk_tree_store_set(store_eps, &toweriter, 0, strdup(annotation), 1, strdup(dcerpc_binding_string(mem_ctx, &bd)), 2, t, -1);
gtk_tree_store_set(store_eps, &toweriter, 0, strdup(annotation), 1, strdup(dcerpc_binding_string(mem_ctx, bd)), 2, t, -1);
for (i = 0; i < t->num_floors; i++) {
const char *data;
@ -187,7 +187,9 @@ static void on_connect_clicked(GtkButton *btn, gpointer user_data)
mem_ctx = talloc_init("connect");
bs = gtk_rpc_binding_dialog_get_binding_string (d, mem_ctx);
status = dcerpc_pipe_connect(&epmapper_pipe, bs, DCERPC_EPMAPPER_UUID, DCERPC_EPMAPPER_VERSION, lp_workgroup(), "", "");
status = dcerpc_pipe_connect(&epmapper_pipe, bs,
DCERPC_EPMAPPER_UUID, DCERPC_EPMAPPER_VERSION,
lp_netbios_name(), lp_workgroup(), "", "");
if (NT_STATUS_IS_ERR(status)) {
gtk_show_ntstatus(mainwin, status);

View File

@ -104,12 +104,13 @@ on_connect_activate (GtkMenuItem *menuitem,
/* If connected, get list of jobs */
status = dcerpc_pipe_connect_b(&at_pipe,
gtk_rpc_binding_dialog_get_binding(d, mem_ctx),
DCERPC_ATSVC_UUID,
DCERPC_ATSVC_VERSION,
gtk_rpc_binding_dialog_get_userdomain(d),
gtk_rpc_binding_dialog_get_username(d),
gtk_rpc_binding_dialog_get_password(d));
gtk_rpc_binding_dialog_get_binding(d, mem_ctx),
DCERPC_ATSVC_UUID,
DCERPC_ATSVC_VERSION,
lp_netbios_name(),
gtk_rpc_binding_dialog_get_userdomain(d),
gtk_rpc_binding_dialog_get_username(d),
gtk_rpc_binding_dialog_get_password(d));
if(!NT_STATUS_IS_OK(status)) {
gtk_show_ntstatus(mainwin, status);

View File

@ -129,11 +129,12 @@ static void connect_sam(void)
mem_ctx = talloc_init("gwsam_connect");
/* If connected, get list of jobs */
status = dcerpc_pipe_connect_b(&sam_pipe,
gtk_rpc_binding_dialog_get_binding(d, mem_ctx),
DCERPC_SAMR_UUID, DCERPC_SAMR_VERSION,
gtk_rpc_binding_dialog_get_userdomain(d),
gtk_rpc_binding_dialog_get_username(d),
gtk_rpc_binding_dialog_get_password(d));
gtk_rpc_binding_dialog_get_binding(d, mem_ctx),
DCERPC_SAMR_UUID, DCERPC_SAMR_VERSION,
lp_netbios_name(),
gtk_rpc_binding_dialog_get_userdomain(d),
gtk_rpc_binding_dialog_get_username(d),
gtk_rpc_binding_dialog_get_password(d));
if(!NT_STATUS_IS_OK(status)) {
gtk_show_ntstatus(mainwin, status);

View File

@ -40,11 +40,15 @@ struct dcom_client_context *dcom_client_init(struct com_context *ctx, const char
return ctx->dcom;
}
static NTSTATUS dcerpc_binding_from_STRINGBINDING(TALLOC_CTX *mem_ctx, struct dcerpc_binding *b, struct STRINGBINDING *bd)
static NTSTATUS dcerpc_binding_from_STRINGBINDING(TALLOC_CTX *mem_ctx, struct dcerpc_binding **b_out, struct STRINGBINDING *bd)
{
char *host, *endpoint;
struct dcerpc_binding *b;
ZERO_STRUCTP(b);
b = talloc_zero(mem_ctx, struct dcerpc_binding);
if (!b) {
return NT_STATUS_NO_MEMORY;
}
b->transport = dcerpc_transport_by_endpoint_protocol(bd->wTowerId);
@ -53,7 +57,7 @@ static NTSTATUS dcerpc_binding_from_STRINGBINDING(TALLOC_CTX *mem_ctx, struct dc
return NT_STATUS_NOT_SUPPORTED;
}
host = talloc_strdup(mem_ctx, bd->NetworkAddr);
host = talloc_strdup(b, bd->NetworkAddr);
endpoint = strchr(host, '[');
if (endpoint) {
@ -64,56 +68,61 @@ static NTSTATUS dcerpc_binding_from_STRINGBINDING(TALLOC_CTX *mem_ctx, struct dc
}
b->host = host;
b->endpoint = endpoint;
b->endpoint = talloc_strdup(b, endpoint);
*b_out = b;
return NT_STATUS_OK;
}
static NTSTATUS dcom_connect_host(struct com_context *ctx, struct dcerpc_pipe **p, const char *server)
{
struct dcerpc_binding bd;
enum dcerpc_transport_t available_transports[] = { NCACN_IP_TCP, NCACN_NP };
struct dcerpc_binding *bd;
const char * available_transports[] = { "ncacn_ip_tcp", "ncacn_np" };
int i;
NTSTATUS status;
TALLOC_CTX *mem_ctx = talloc_init("dcom_connect");
if (server == NULL) {
bd.transport = NCALRPC;
return dcerpc_pipe_connect_b(p, &bd,
DCERPC_IREMOTEACTIVATION_UUID,
DCERPC_IREMOTEACTIVATION_VERSION,
ctx->dcom->domain, ctx->dcom->user, ctx->dcom->password);
return dcerpc_pipe_connect(p, "ncalrpc",
DCERPC_IREMOTEACTIVATION_UUID,
DCERPC_IREMOTEACTIVATION_VERSION,
lp_netbios_name(),
ctx->dcom->domain, ctx->dcom->user, ctx->dcom->password);
}
/* Allow server name to contain a binding string */
if (NT_STATUS_IS_OK(dcerpc_parse_binding(mem_ctx, server, &bd))) {
status = dcerpc_pipe_connect_b(p, &bd,
DCERPC_IREMOTEACTIVATION_UUID,
DCERPC_IREMOTEACTIVATION_VERSION,
ctx->dcom->domain, ctx->dcom->user, ctx->dcom->password);
status = dcerpc_pipe_connect_b(p, bd,
DCERPC_IREMOTEACTIVATION_UUID,
DCERPC_IREMOTEACTIVATION_VERSION,
lp_netbios_name(),
ctx->dcom->domain, ctx->dcom->user, ctx->dcom->password);
talloc_free(mem_ctx);
return status;
}
talloc_free(mem_ctx);
ZERO_STRUCT(bd);
bd.host = server;
for (i = 0; i < ARRAY_SIZE(available_transports); i++)
{
bd.transport = available_transports[i];
char *binding = talloc_asprintf(mem_ctx, "%s:%s", available_transports[i], server);
if (!binding) {
talloc_free(mem_ctx);
return NT_STATUS_NO_MEMORY;
}
status = dcerpc_pipe_connect_b(p, &bd,
DCERPC_IREMOTEACTIVATION_UUID,
DCERPC_IREMOTEACTIVATION_VERSION,
ctx->dcom->domain, ctx->dcom->user, ctx->dcom->password);
status = dcerpc_pipe_connect(p, binding,
DCERPC_IREMOTEACTIVATION_UUID,
DCERPC_IREMOTEACTIVATION_VERSION,
lp_netbios_name(),
ctx->dcom->domain, ctx->dcom->user, ctx->dcom->password);
if (NT_STATUS_IS_OK(status)) {
talloc_free(mem_ctx);
return status;
}
}
talloc_free(mem_ctx);
return status;
}
@ -254,7 +263,7 @@ WERROR dcom_get_class_object(struct com_context *ctx, struct GUID *clsid, const
NTSTATUS dcom_get_pipe (struct IUnknown *iface, struct dcerpc_pipe **pp)
{
struct dcerpc_binding binding;
struct dcerpc_binding *binding;
struct GUID iid;
uint64_t oxid;
NTSTATUS status;
@ -297,14 +306,16 @@ NTSTATUS dcom_get_pipe (struct IUnknown *iface, struct dcerpc_pipe **pp)
if (!NT_STATUS_IS_OK(status)) {
DEBUG(1, ("Error parsing string binding"));
} else {
status = dcerpc_pipe_connect_b(&p, &binding,
status = dcerpc_pipe_connect_b(&p, binding,
uuid, 0.0,
iface->ctx->dcom->domain, iface->ctx->dcom->user,
lp_netbios_name(),
iface->ctx->dcom->domain,
iface->ctx->dcom->user,
iface->ctx->dcom->password);
}
talloc_free(binding);
i++;
} while (NT_STATUS_IS_ERR(status) && ox->bindings.stringbindings[i]);
} while (!NT_STATUS_IS_OK(status) && ox->bindings.stringbindings[i]);
if (NT_STATUS_IS_ERR(status)) {
DEBUG(0, ("Unable to connect to remote host - %s\n", nt_errstr(status)));

View File

@ -384,6 +384,7 @@ WERROR reg_open_remote (struct registry_context **ctx, const char *user, const c
status = dcerpc_pipe_connect(&p, location,
DCERPC_WINREG_UUID,
DCERPC_WINREG_VERSION,
lp_netbios_name(),
lp_workgroup(),
user, pass);
(*ctx)->backend_data = p;

View File

@ -192,12 +192,18 @@ next comes the client specific functions
void creds_client_init(struct creds_CredentialState *creds,
const struct netr_Credential *client_challenge,
const struct netr_Credential *server_challenge,
const char *computer_name,
const char *domain,
const char *account_name,
const struct samr_Password *machine_password,
struct netr_Credential *initial_credential,
uint32_t negotiate_flags)
{
creds->sequence = time(NULL);
creds->negotiate_flags = negotiate_flags;
creds->computer_name = talloc_strdup(creds, computer_name);
creds->domain = talloc_strdup(creds, domain);
creds->account_name = talloc_strdup(creds, account_name);
dump_data_pw("Client chall", client_challenge->data, sizeof(client_challenge->data));
dump_data_pw("Server chall", server_challenge->data, sizeof(server_challenge->data));

View File

@ -30,6 +30,7 @@ struct creds_CredentialState {
struct netr_Credential client;
struct netr_Credential server;
uint16_t secure_channel_type;
const char *domain;
const char *computer_name;
const char *account_name;
uint32_t rid;

View File

@ -148,7 +148,7 @@ static NTSTATUS gensec_start(TALLOC_CTX *mem_ctx, struct gensec_security **gense
* @param mem_ctx The parent TALLOC memory context.
* @param parent The parent GENSEC context
* @param gensec_security Returned GENSEC context pointer.
* @note Used by SPENGO in particular, for the actual implementation mechanism
* @note Used by SPNEGO in particular, for the actual implementation mechanism
*/
NTSTATUS gensec_subcontext_start(TALLOC_CTX *mem_ctx,
@ -617,6 +617,34 @@ const char *gensec_get_domain(struct gensec_security *gensec_security)
return gensec_security->default_user.domain;
}
/**
* Set the client workstation on a GENSEC context - ensures it is talloc()ed
*
*/
NTSTATUS gensec_set_workstation(struct gensec_security *gensec_security, const char *workstation)
{
gensec_security->user.workstation = talloc_strdup(gensec_security, workstation);
if (!gensec_security->user.workstation) {
return NT_STATUS_NO_MEMORY;
}
return NT_STATUS_OK;
}
/**
* Return the client workstation on a GENSEC context - ensures it is talloc()ed
*
*/
const char *gensec_get_workstation(struct gensec_security *gensec_security)
{
if (gensec_security->user.workstation) {
return gensec_security->user.workstation;
} else {
return lp_netbios_name();
}
}
/**
* Set a kerberos realm on a GENSEC context - ensures it is talloc()ed
*

View File

@ -29,6 +29,7 @@
struct gensec_security;
struct gensec_user {
const char *workstation;
const char *domain;
const char *realm;
const char *name;
@ -59,7 +60,7 @@ struct gensec_security_ops {
const char *name;
const char *sasl_name;
uint8_t auth_type; /* 0 if not offered on DCE-RPC */
const char *oid; /* NULL if not offered by SPENGO */
const char *oid; /* NULL if not offered by SPNEGO */
NTSTATUS (*client_start)(struct gensec_security *gensec_security);
NTSTATUS (*server_start)(struct gensec_security *gensec_security);
NTSTATUS (*update)(struct gensec_security *gensec_security, TALLOC_CTX *out_mem_ctx,

View File

@ -245,6 +245,9 @@ static NTSTATUS gensec_ntlmssp_client_start(struct gensec_security *gensec_secur
NT_STATUS_NOT_OK_RETURN(nt_status);
}
nt_status = ntlmssp_set_workstation(gensec_ntlmssp_state->ntlmssp_state,
gensec_get_workstation(gensec_security));
gensec_security->private_data = gensec_ntlmssp_state;
return NT_STATUS_OK;

View File

@ -194,7 +194,7 @@ NTSTATUS ntlmssp_set_domain(struct ntlmssp_state *ntlmssp_state, const char *dom
NTSTATUS ntlmssp_set_workstation(struct ntlmssp_state *ntlmssp_state, const char *workstation)
{
ntlmssp_state->workstation = talloc_strdup(ntlmssp_state, workstation);
if (!ntlmssp_state->domain) {
if (!ntlmssp_state->workstation) {
return NT_STATUS_NO_MEMORY;
}
return NT_STATUS_OK;
@ -346,7 +346,7 @@ static const char *ntlmssp_target_name(struct ntlmssp_state *ntlmssp_state,
*chal_flags |= NTLMSSP_REQUEST_TARGET;
if (ntlmssp_state->server_role == ROLE_STANDALONE) {
*chal_flags |= NTLMSSP_TARGET_TYPE_SERVER;
return ntlmssp_state->get_global_myname();
return ntlmssp_state->server_name;
} else {
*chal_flags |= NTLMSSP_TARGET_TYPE_DOMAIN;
return ntlmssp_state->get_domain();
@ -531,7 +531,7 @@ static NTSTATUS ntlmssp_server_negotiate(struct ntlmssp_state *ntlmssp_state,
msrpc_gen(out_mem_ctx,
&struct_blob, "aaaaa",
NTLMSSP_NAME_TYPE_DOMAIN, target_name,
NTLMSSP_NAME_TYPE_SERVER, ntlmssp_state->get_global_myname(),
NTLMSSP_NAME_TYPE_SERVER, ntlmssp_state->server_name,
NTLMSSP_NAME_TYPE_DOMAIN_DNS, dnsdomname,
NTLMSSP_NAME_TYPE_SERVER_DNS, dnsname,
0, "");
@ -923,7 +923,9 @@ NTSTATUS ntlmssp_server_start(TALLOC_CTX *mem_ctx, struct ntlmssp_state **ntlmss
(*ntlmssp_state)->set_challenge = set_challenge;
(*ntlmssp_state)->may_set_challenge = may_set_challenge;
(*ntlmssp_state)->get_global_myname = lp_netbios_name;
(*ntlmssp_state)->workstation = NULL;
(*ntlmssp_state)->server_name = lp_netbios_name();
(*ntlmssp_state)->get_domain = lp_workgroup;
(*ntlmssp_state)->server_role = ROLE_DOMAIN_MEMBER; /* a good default */
@ -990,7 +992,7 @@ static NTSTATUS ntlmssp_client_initial(struct ntlmssp_state *ntlmssp_state,
NTLMSSP_NEGOTIATE,
ntlmssp_state->neg_flags,
ntlmssp_state->get_domain(),
ntlmssp_state->get_global_myname());
ntlmssp_state->workstation);
ntlmssp_state->expected_state = NTLMSSP_CHALLENGE;
@ -1240,7 +1242,7 @@ static NTSTATUS ntlmssp_client_challenge(struct ntlmssp_state *ntlmssp_state,
nt_response.data, nt_response.length,
ntlmssp_state->domain,
ntlmssp_state->user,
ntlmssp_state->get_global_myname(),
ntlmssp_state->workstation,
encrypted_session_key.data, encrypted_session_key.length,
ntlmssp_state->neg_flags)) {
@ -1279,7 +1281,7 @@ NTSTATUS ntlmssp_client_start(TALLOC_CTX *mem_ctx, struct ntlmssp_state **ntlmss
(*ntlmssp_state)->role = NTLMSSP_CLIENT;
(*ntlmssp_state)->get_global_myname = lp_netbios_name;
(*ntlmssp_state)->workstation = lp_netbios_name();
(*ntlmssp_state)->get_domain = lp_workgroup;
(*ntlmssp_state)->unicode = lp_parm_bool(-1, "ntlmssp_client", "unicode", True);

View File

@ -95,7 +95,7 @@ struct ntlmssp_state
char *user;
char *domain;
char *workstation;
const char *workstation;
char *password;
char *server_domain;
@ -161,7 +161,7 @@ struct ntlmssp_state
*/
NTSTATUS (*check_password)(struct ntlmssp_state *ntlmssp_state, DATA_BLOB *nt_session_key, DATA_BLOB *lm_session_key);
const char *(*get_global_myname)(void);
const char *server_name;
const char *(*get_domain)(void);
/* SMB Signing */

View File

@ -271,25 +271,15 @@ NTSTATUS schannel_sign_packet(struct schannel_state *state,
return NT_STATUS_OK;
}
/*
destroy an schannel context
*/
void schannel_end(struct schannel_state **state)
{
if (*state) {
talloc_free(*state);
(*state) = NULL;
}
}
/*
create an schannel context state
*/
NTSTATUS schannel_start(struct schannel_state **state,
NTSTATUS schannel_start(TALLOC_CTX *mem_ctx,
struct schannel_state **state,
const uint8_t session_key[16],
BOOL initiator)
{
(*state) = talloc(NULL, struct schannel_state);
(*state) = talloc(mem_ctx, struct schannel_state);
if (!(*state)) {
return NT_STATUS_NO_MEMORY;
}

View File

@ -127,6 +127,7 @@ NTSTATUS schannel_store_session_key(TALLOC_CTX *mem_ctx,
ldb_msg_add_string(ldb, msg, "secureChannelType", sct);
ldb_msg_add_string(ldb, msg, "accountName", creds->account_name);
ldb_msg_add_string(ldb, msg, "computerName", creds->computer_name);
ldb_msg_add_string(ldb, msg, "flatname", creds->domain);
ldb_msg_add_string(ldb, msg, "rid", rid);
ldb_delete(ldb, msg->dn);
@ -155,6 +156,7 @@ NTSTATUS schannel_store_session_key(TALLOC_CTX *mem_ctx,
*/
NTSTATUS schannel_fetch_session_key(TALLOC_CTX *mem_ctx,
const char *computer_name,
const char *domain,
struct creds_CredentialState **creds)
{
struct ldb_context *ldb;
@ -174,7 +176,7 @@ NTSTATUS schannel_fetch_session_key(TALLOC_CTX *mem_ctx,
return NT_STATUS_NO_MEMORY;
}
expr = talloc_asprintf(mem_ctx, "(dn=computerName=%s)", computer_name);
expr = talloc_asprintf(mem_ctx, "(&(computerName=%s)(flatname=%s))", computer_name, domain);
if (expr == NULL) {
talloc_free(ldb);
return NT_STATUS_NO_MEMORY;
@ -217,6 +219,8 @@ NTSTATUS schannel_fetch_session_key(TALLOC_CTX *mem_ctx,
(*creds)->computer_name = talloc_reference(*creds, ldb_msg_find_string(res[0], "computerName", NULL));
(*creds)->domain = talloc_reference(*creds, ldb_msg_find_string(res[0], "flatname", NULL));
(*creds)->rid = ldb_msg_find_uint(res[0], "rid", 0);
talloc_free(ldb);

View File

@ -98,12 +98,13 @@ static NTSTATUS libnet_rpc_connect_standard(struct libnet_context *ctx, TALLOC_C
r->standard.in.server_name);
status = dcerpc_pipe_connect(&r->standard.out.dcerpc_pipe,
binding,
r->standard.in.dcerpc_iface_uuid,
r->standard.in.dcerpc_iface_version,
ctx->user.domain_name,
ctx->user.account_name,
ctx->user.password);
binding,
r->standard.in.dcerpc_iface_uuid,
r->standard.in.dcerpc_iface_version,
lp_netbios_name(),
ctx->user.domain_name,
ctx->user.account_name,
ctx->user.password);
if (!NT_STATUS_IS_OK(status)) {
r->standard.out.error_string = talloc_asprintf(mem_ctx,
"dcerpc_pipe_connect to pipe %s failed with %s\n",

View File

@ -23,12 +23,12 @@ interface rpcecho
/* Sink data to the server */
void echo_SinkData(
[in] uint32 len,
[in,size_is(len)] uint8 data[]
[in,ref,size_is(len)] uint8 *data[]
);
/* Source data from server */
void echo_SourceData(
[in] uint32 len,
[out,size_is(len)] uint8 data[]
[out,ref,size_is(len)] uint8 *data[]
);

View File

@ -15,7 +15,7 @@ interface schannel
*/
typedef struct {
astring domain;
astring account_name;
astring workstation;
} schannel_bind_3;
typedef struct {

View File

@ -143,6 +143,7 @@ done:
*/
NTSTATUS dcerpc_bind_auth_password(struct dcerpc_pipe *p,
const char *uuid, uint_t version,
const char *workstation,
const char *domain,
const char *username,
const char *password,
@ -161,6 +162,13 @@ NTSTATUS dcerpc_bind_auth_password(struct dcerpc_pipe *p,
return status;
}
status = gensec_set_workstation(p->conn->security_state.generic_state, workstation);
if (!NT_STATUS_IS_OK(status)) {
DEBUG(1, ("Failed to start set GENSEC client workstation name to %s: %s\n",
workstation, nt_errstr(status)));
return status;
}
status = gensec_set_domain(p->conn->security_state.generic_state, domain);
if (!NT_STATUS_IS_OK(status)) {
DEBUG(1, ("Failed to start set GENSEC client domain to %s: %s\n",

View File

@ -33,7 +33,6 @@ struct dcerpc_schannel_state {
enum schannel_position state;
struct schannel_state *schannel_state;
struct creds_CredentialState *creds;
char *account_name;
};
/*
@ -104,7 +103,8 @@ static NTSTATUS dcerpc_schannel_update(struct gensec_security *gensec_security,
NTSTATUS status;
struct schannel_bind bind_schannel;
struct schannel_bind_ack bind_schannel_ack;
const char *account_name;
const char *workstation;
const char *domain;
*out = data_blob(NULL, 0);
switch (gensec_security->gensec_role) {
@ -114,7 +114,8 @@ static NTSTATUS dcerpc_schannel_update(struct gensec_security *gensec_security,
return NT_STATUS_OK;
}
status = schannel_start(&dce_schan_state->schannel_state,
status = schannel_start(dce_schan_state,
&dce_schan_state->schannel_state,
dce_schan_state->creds->session_key,
True);
if (!NT_STATUS_IS_OK(status)) {
@ -130,11 +131,11 @@ static NTSTATUS dcerpc_schannel_update(struct gensec_security *gensec_security,
bind_schannel.u.info23.domain = gensec_security->user.domain;
bind_schannel.u.info23.account_name = gensec_security->user.name;
bind_schannel.u.info23.dnsdomain = str_format_nbt_domain(out_mem_ctx, fulldomainname);
bind_schannel.u.info23.workstation = str_format_nbt_domain(out_mem_ctx, gensec_security->user.name);
bind_schannel.u.info23.workstation = str_format_nbt_domain(out_mem_ctx, gensec_get_workstation(gensec_security));
#else
bind_schannel.bind_type = 3;
bind_schannel.u.info3.domain = gensec_security->user.domain;
bind_schannel.u.info3.account_name = gensec_security->user.name;
bind_schannel.u.info3.workstation = gensec_get_workstation(gensec_security);
#endif
status = ndr_push_struct_blob(out, out_mem_ctx, &bind_schannel,
@ -163,27 +164,29 @@ static NTSTATUS dcerpc_schannel_update(struct gensec_security *gensec_security,
}
if (bind_schannel.bind_type == 23) {
account_name = bind_schannel.u.info23.account_name;
workstation = bind_schannel.u.info23.workstation;
domain = bind_schannel.u.info23.domain;
} else {
account_name = bind_schannel.u.info3.account_name;
workstation = bind_schannel.u.info3.workstation;
domain = bind_schannel.u.info3.domain;
}
/* pull the session key for this client */
status = schannel_fetch_session_key(out_mem_ctx, account_name, &dce_schan_state->creds);
status = schannel_fetch_session_key(out_mem_ctx, workstation,
domain, &dce_schan_state->creds);
if (!NT_STATUS_IS_OK(status)) {
DEBUG(3, ("Could not find session key for attempted schannel connection on %s: %s\n",
account_name, nt_errstr(status)));
DEBUG(3, ("Could not find session key for attempted schannel connection from %s: %s\n",
workstation, nt_errstr(status)));
return status;
}
dce_schan_state->account_name = talloc_strdup(dce_schan_state, account_name);
/* start up the schannel server code */
status = schannel_start(&dce_schan_state->schannel_state,
status = schannel_start(dce_schan_state,
&dce_schan_state->schannel_state,
dce_schan_state->creds->session_key, False);
if (!NT_STATUS_IS_OK(status)) {
DEBUG(3, ("Could not initialise schannel state for account %s: %s\n",
account_name, nt_errstr(status)));
DEBUG(3, ("Could not initialise schannel state from client %s: %s\n",
workstation, nt_errstr(status)));
return status;
}
talloc_steal(dce_schan_state, dce_schan_state->schannel_state);
@ -195,8 +198,8 @@ static NTSTATUS dcerpc_schannel_update(struct gensec_security *gensec_security,
status = ndr_push_struct_blob(out, out_mem_ctx, &bind_schannel_ack,
(ndr_push_flags_fn_t)ndr_push_schannel_bind_ack);
if (!NT_STATUS_IS_OK(status)) {
DEBUG(3, ("Could not return schannel bind ack for account %s: %s\n",
account_name, nt_errstr(status)));
DEBUG(3, ("Could not return schannel bind ack for client %s: %s\n",
workstation, nt_errstr(status)));
return status;
}
@ -248,18 +251,6 @@ NTSTATUS dcerpc_schannel_creds(struct gensec_security *gensec_security,
}
/*
end crypto state
*/
static int dcerpc_schannel_destroy(void *ptr)
{
struct dcerpc_schannel_state *dce_schan_state = ptr;
schannel_end(&dce_schan_state->schannel_state);
return 0;
}
static NTSTATUS dcerpc_schannel_start(struct gensec_security *gensec_security)
{
struct dcerpc_schannel_state *dce_schan_state;
@ -272,8 +263,6 @@ static NTSTATUS dcerpc_schannel_start(struct gensec_security *gensec_security)
dce_schan_state->state = DCERPC_SCHANNEL_STATE_START;
gensec_security->private_data = dce_schan_state;
talloc_set_destructor(dce_schan_state, dcerpc_schannel_destroy);
return NT_STATUS_OK;
}
@ -306,6 +295,7 @@ static NTSTATUS dcerpc_schannel_client_start(struct gensec_security *gensec_secu
get a schannel key using a netlogon challenge on a secondary pipe
*/
static NTSTATUS dcerpc_schannel_key(struct dcerpc_pipe *p,
const char *workstation,
const char *domain,
const char *username,
const char *password,
@ -313,13 +303,15 @@ static NTSTATUS dcerpc_schannel_key(struct dcerpc_pipe *p,
struct creds_CredentialState *creds)
{
NTSTATUS status;
struct dcerpc_binding *b;
struct dcerpc_pipe *p2;
struct netr_ServerReqChallenge r;
struct netr_ServerAuthenticate2 a;
struct netr_Credential credentials1, credentials2, credentials3;
struct samr_Password mach_pwd;
const char *workgroup, *workstation;
const char *workgroup;
uint32_t negotiate_flags;
TALLOC_CTX *tmp_ctx;
if (p->conn->flags & DCERPC_SCHANNEL_128) {
negotiate_flags = NETLOGON_NEG_AUTH2_ADS_FLAGS;
@ -327,20 +319,45 @@ static NTSTATUS dcerpc_schannel_key(struct dcerpc_pipe *p,
negotiate_flags = NETLOGON_NEG_AUTH2_FLAGS;
}
workstation = username;
workgroup = domain;
tmp_ctx = talloc_new(NULL);
/*
step 1 - establish a netlogon connection, with no authentication
*/
status = dcerpc_secondary_connection(p, &p2,
DCERPC_NETLOGON_NAME,
DCERPC_NETLOGON_UUID,
DCERPC_NETLOGON_VERSION);
/* Find the original binding string */
status = dcerpc_parse_binding(tmp_ctx, p->conn->binding_string, &b);
if (!NT_STATUS_IS_OK(status)) {
DEBUG(0,("Failed to parse dcerpc binding '%s'\n", p->conn->binding_string));
talloc_free(tmp_ctx);
return status;
}
/* Make binding string for netlogon, not the other pipe */
status = dcerpc_epm_map_binding(tmp_ctx, b, DCERPC_NETLOGON_UUID, DCERPC_NETLOGON_VERSION);
if (!NT_STATUS_IS_OK(status)) {
DEBUG(0,("Failed to map DCERPC/TCP NCACN_NP pipe for '%s' - %s\n",
DCERPC_NETLOGON_UUID, nt_errstr(status)));
talloc_free(p);
return status;
}
status = dcerpc_secondary_connection(p, &p2, b);
if (!NT_STATUS_IS_OK(status)) {
talloc_free(tmp_ctx);
return status;
}
talloc_free(tmp_ctx);
status = dcerpc_bind_auth_none(p2, DCERPC_NETLOGON_UUID,
DCERPC_NETLOGON_VERSION);
if (!NT_STATUS_IS_OK(status)) {
talloc_free(p2);
return status;
}
/*
step 2 - request a netlogon challenge
@ -361,11 +378,13 @@ static NTSTATUS dcerpc_schannel_key(struct dcerpc_pipe *p,
step 3 - authenticate on the netlogon pipe
*/
E_md4hash(password, mach_pwd.hash);
creds_client_init(creds, &credentials1, &credentials2, &mach_pwd, &credentials3,
creds_client_init(creds, &credentials1, &credentials2,
workstation, domain, username,
&mach_pwd, &credentials3,
negotiate_flags);
a.in.server_name = r.in.server_name;
a.in.account_name = talloc_asprintf(p, "%s$", workstation);
a.in.account_name = username;
a.in.secure_channel_type = chan_type;
a.in.computer_name = workstation;
a.in.negotiate_flags = &negotiate_flags;
@ -398,9 +417,6 @@ static NTSTATUS dcerpc_schannel_key(struct dcerpc_pipe *p,
*/
NTSTATUS dcerpc_bind_auth_schannel_withkey(struct dcerpc_pipe *p,
const char *uuid, uint_t version,
const char *domain,
const char *username,
const char *password,
struct creds_CredentialState *creds)
{
NTSTATUS status;
@ -411,17 +427,28 @@ NTSTATUS dcerpc_bind_auth_schannel_withkey(struct dcerpc_pipe *p,
return status;
}
status = gensec_set_username(p->conn->security_state.generic_state, username);
status = gensec_set_workstation(p->conn->security_state.generic_state, creds->computer_name);
if (!NT_STATUS_IS_OK(status)) {
DEBUG(1, ("Failed to set schannel username to %s: %s\n", username, nt_errstr(status)));
DEBUG(1, ("Failed to set schannel workstation to %s: %s\n",
creds->computer_name, nt_errstr(status)));
talloc_free(p->conn->security_state.generic_state);
p->conn->security_state.generic_state = NULL;
return status;
}
status = gensec_set_domain(p->conn->security_state.generic_state, domain);
status = gensec_set_username(p->conn->security_state.generic_state, creds->account_name);
if (!NT_STATUS_IS_OK(status)) {
DEBUG(1, ("Failed to set schannel domain to %s: %s\n", domain, nt_errstr(status)));
DEBUG(1, ("Failed to set schannel username to %s: %s\n",
creds->account_name, nt_errstr(status)));
talloc_free(p->conn->security_state.generic_state);
p->conn->security_state.generic_state = NULL;
return status;
}
status = gensec_set_domain(p->conn->security_state.generic_state, creds->domain);
if (!NT_STATUS_IS_OK(status)) {
DEBUG(1, ("Failed to set schannel domain to %s: %s\n",
creds->domain, nt_errstr(status)));
talloc_free(p->conn->security_state.generic_state);
p->conn->security_state.generic_state = NULL;
return status;
@ -456,6 +483,7 @@ NTSTATUS dcerpc_bind_auth_schannel_withkey(struct dcerpc_pipe *p,
NTSTATUS dcerpc_bind_auth_schannel(struct dcerpc_pipe *p,
const char *uuid, uint_t version,
const char *workstation,
const char *domain,
const char *username,
const char *password)
@ -477,6 +505,7 @@ NTSTATUS dcerpc_bind_auth_schannel(struct dcerpc_pipe *p,
}
status = dcerpc_schannel_key(p, domain,
workstation,
username,
password,
chan_type,
@ -488,9 +517,7 @@ NTSTATUS dcerpc_bind_auth_schannel(struct dcerpc_pipe *p,
return status;
}
return dcerpc_bind_auth_schannel_withkey(p, uuid, version, domain,
username, password,
creds);
return dcerpc_bind_auth_schannel_withkey(p, uuid, version, creds);
}
static BOOL dcerpc_schannel_have_feature(struct gensec_security *gensec_security,

View File

@ -375,7 +375,19 @@ NTSTATUS dcerpc_pipe_open_smb(struct dcerpc_connection *c,
struct smb_private *smb;
NTSTATUS status;
union smb_open io;
char *pipe_name_talloc;
if (!strncasecmp(pipe_name, "/pipe/", 6) ||
!strncasecmp(pipe_name, "\\pipe\\", 6)) {
pipe_name += 6;
}
if (pipe_name[0] != '\\') {
pipe_name_talloc = talloc_asprintf(NULL, "\\%s", pipe_name);
} else {
pipe_name_talloc = talloc_strdup(NULL, pipe_name);
}
io.ntcreatex.level = RAW_OPEN_NTCREATEX;
io.ntcreatex.in.flags = 0;
io.ntcreatex.in.root_fid = 0;
@ -394,10 +406,12 @@ NTSTATUS dcerpc_pipe_open_smb(struct dcerpc_connection *c,
io.ntcreatex.in.create_options = 0;
io.ntcreatex.in.impersonation = NTCREATEX_IMPERSONATION_IMPERSONATION;
io.ntcreatex.in.security_flags = 0;
io.ntcreatex.in.fname = pipe_name;
io.ntcreatex.in.fname = pipe_name_talloc;
status = smb_raw_open(tree, tree, &io);
talloc_free(pipe_name_talloc);
if (!NT_STATUS_IS_OK(status)) {
return status;
}

View File

@ -323,12 +323,18 @@ const char *dcerpc_binding_string(TALLOC_CTX *mem_ctx, const struct dcerpc_bindi
/*
parse a binding string into a dcerpc_binding structure
*/
NTSTATUS dcerpc_parse_binding(TALLOC_CTX *mem_ctx, const char *s, struct dcerpc_binding *b)
NTSTATUS dcerpc_parse_binding(TALLOC_CTX *mem_ctx, const char *s, struct dcerpc_binding **b_out)
{
struct dcerpc_binding *b;
char *options, *type;
char *p;
int i, j, comma_count;
b = talloc(mem_ctx, struct dcerpc_binding);
if (!b) {
return NT_STATUS_NO_MEMORY;
}
p = strchr(s, '@');
if (p && PTR_DIFF(p, s) == 36) { /* 36 is the length of a UUID */
@ -373,14 +379,14 @@ NTSTATUS dcerpc_parse_binding(TALLOC_CTX *mem_ctx, const char *s, struct dcerpc_
p = strchr(s, '[');
if (p) {
b->host = talloc_strndup(mem_ctx, s, PTR_DIFF(p, s));
b->host = talloc_strndup(b, s, PTR_DIFF(p, s));
options = talloc_strdup(mem_ctx, p+1);
if (options[strlen(options)-1] != ']') {
return NT_STATUS_INVALID_PARAMETER;
}
options[strlen(options)-1] = 0;
} else {
b->host = talloc_strdup(mem_ctx, s);
b->host = talloc_strdup(b, s);
options = NULL;
}
@ -393,18 +399,19 @@ NTSTATUS dcerpc_parse_binding(TALLOC_CTX *mem_ctx, const char *s, struct dcerpc_
b->endpoint = NULL;
if (!options) {
*b_out = b;
return NT_STATUS_OK;
}
comma_count = count_chars(options, ',');
b->options = talloc_array(mem_ctx, const char *, comma_count+2);
b->options = talloc_array(b, const char *, comma_count+2);
if (!b->options) {
return NT_STATUS_NO_MEMORY;
}
for (i=0; (p = strchr(options, ',')); i++) {
b->options[i] = talloc_strndup(mem_ctx, options, PTR_DIFF(p, options));
b->options[i] = talloc_strndup(b, options, PTR_DIFF(p, options));
if (!b->options[i]) {
return NT_STATUS_NO_MEMORY;
}
@ -441,6 +448,7 @@ NTSTATUS dcerpc_parse_binding(TALLOC_CTX *mem_ctx, const char *s, struct dcerpc_
if (b->options[0] == NULL)
b->options = NULL;
*b_out = b;
return NT_STATUS_OK;
}
@ -657,9 +665,13 @@ enum dcerpc_transport_t dcerpc_transport_by_tower(struct epm_tower *tower)
return -1;
}
NTSTATUS dcerpc_binding_from_tower(TALLOC_CTX *mem_ctx, struct epm_tower *tower, struct dcerpc_binding *binding)
NTSTATUS dcerpc_binding_from_tower(TALLOC_CTX *mem_ctx, struct epm_tower *tower, struct dcerpc_binding **b_out)
{
NTSTATUS status;
struct dcerpc_binding *binding;
binding = talloc(mem_ctx, struct dcerpc_binding);
NT_STATUS_HAVE_NO_MEMORY(binding);
ZERO_STRUCT(binding->object);
binding->options = NULL;
@ -699,6 +711,7 @@ NTSTATUS dcerpc_binding_from_tower(TALLOC_CTX *mem_ctx, struct epm_tower *tower,
if (tower->num_floors >= 5) {
binding->host = dcerpc_floor_get_rhs_data(mem_ctx, &tower->floors[4]);
}
*b_out = binding;
return NT_STATUS_OK;
}
@ -773,7 +786,7 @@ NTSTATUS dcerpc_binding_build_tower(TALLOC_CTX *mem_ctx, struct dcerpc_binding *
}
NTSTATUS dcerpc_epm_map_binding(TALLOC_CTX *mem_ctx, struct dcerpc_binding *binding,
const char *uuid, uint_t version)
const char *uuid, uint_t version)
{
struct dcerpc_pipe *p;
NTSTATUS status;
@ -781,42 +794,51 @@ NTSTATUS dcerpc_epm_map_binding(TALLOC_CTX *mem_ctx, struct dcerpc_binding *bind
struct policy_handle handle;
struct GUID guid;
struct epm_twr_t twr, *twr_r;
struct dcerpc_binding epmapper_binding;
struct dcerpc_binding *epmapper_binding;
const struct dcerpc_interface_table *table = idl_iface_by_uuid(uuid);
int i;
/* First, check if there is a default endpoint specified in the IDL */
if (table) {
struct dcerpc_binding default_binding;
struct dcerpc_binding *default_binding;
binding->authservice = talloc_strdup(mem_ctx, table->authservices->names[0]);
binding->authservice = talloc_strdup(binding, table->authservices->names[0]);
/* Find one of the default pipes for this interface */
for (i = 0; i < table->endpoints->count; i++) {
status = dcerpc_parse_binding(mem_ctx, table->endpoints->names[i], &default_binding);
if (NT_STATUS_IS_OK(status) && default_binding.transport == binding->transport && default_binding.endpoint) {
binding->endpoint = talloc_strdup(mem_ctx, default_binding.endpoint);
return NT_STATUS_OK;
if (NT_STATUS_IS_OK(status)) {
if (default_binding->transport == binding->transport && default_binding->endpoint) {
binding->endpoint = talloc_reference(binding, default_binding->endpoint);
talloc_free(default_binding);
return NT_STATUS_OK;
} else {
talloc_free(default_binding);
}
}
}
}
epmapper_binding = talloc_zero(mem_ctx, struct dcerpc_binding);
if (!epmapper_binding) {
return NT_STATUS_NO_MEMORY;
}
ZERO_STRUCT(epmapper_binding);
epmapper_binding.transport = binding->transport;
epmapper_binding.host = binding->host;
epmapper_binding.options = NULL;
epmapper_binding.flags = 0;
epmapper_binding.endpoint = NULL;
epmapper_binding.authservice = NULL;
epmapper_binding->transport = binding->transport;
epmapper_binding->host = talloc_reference(epmapper_binding,
binding->host);
epmapper_binding->options = NULL;
epmapper_binding->flags = 0;
epmapper_binding->endpoint = NULL;
epmapper_binding->authservice = NULL;
status = dcerpc_pipe_connect_b(&p,
&epmapper_binding,
DCERPC_EPMAPPER_UUID,
DCERPC_EPMAPPER_VERSION,
NULL, NULL, NULL);
epmapper_binding,
DCERPC_EPMAPPER_UUID,
DCERPC_EPMAPPER_VERSION,
NULL, NULL, NULL, NULL);
if (!NT_STATUS_IS_OK(status)) {
return status;
@ -866,7 +888,7 @@ NTSTATUS dcerpc_epm_map_binding(TALLOC_CTX *mem_ctx, struct dcerpc_binding *bind
return NT_STATUS_PORT_UNREACHABLE;
}
binding->endpoint = dcerpc_floor_get_rhs_data(mem_ctx, &twr_r->tower.floors[3]);
binding->endpoint = talloc_reference(binding, dcerpc_floor_get_rhs_data(mem_ctx, &twr_r->tower.floors[3]));
dcerpc_pipe_close(p);
@ -877,13 +899,14 @@ NTSTATUS dcerpc_epm_map_binding(TALLOC_CTX *mem_ctx, struct dcerpc_binding *bind
/*
perform an authenticated bind if needed
*/
static NTSTATUS dcerpc_pipe_auth(struct dcerpc_pipe *p,
struct dcerpc_binding *binding,
const char *pipe_uuid,
uint32_t pipe_version,
const char *domain,
const char *username,
const char *password)
NTSTATUS dcerpc_pipe_auth(struct dcerpc_pipe *p,
struct dcerpc_binding *binding,
const char *pipe_uuid,
uint32_t pipe_version,
const char *workstation,
const char *domain,
const char *username,
const char *password)
{
NTSTATUS status;
p->conn->flags = binding->flags;
@ -893,7 +916,8 @@ static NTSTATUS dcerpc_pipe_auth(struct dcerpc_pipe *p,
if (username && username[0] && (binding->flags & DCERPC_SCHANNEL_ANY)) {
status = dcerpc_bind_auth_schannel(p, pipe_uuid, pipe_version,
domain, username, password);
domain, workstation,
username, password);
} else if (username && username[0]) {
uint8_t auth_type;
if (binding->flags & DCERPC_AUTH_SPNEGO) {
@ -905,6 +929,7 @@ static NTSTATUS dcerpc_pipe_auth(struct dcerpc_pipe *p,
}
status = dcerpc_bind_auth_password(p, pipe_uuid, pipe_version,
workstation,
domain, username, password,
auth_type,
binding->authservice);
@ -925,6 +950,7 @@ static NTSTATUS dcerpc_pipe_connect_ncacn_np(struct dcerpc_pipe **pp,
struct dcerpc_binding *binding,
const char *pipe_uuid,
uint32_t pipe_version,
const char *workstation,
const char *domain,
const char *username,
const char *password)
@ -957,23 +983,14 @@ static NTSTATUS dcerpc_pipe_connect_ncacn_np(struct dcerpc_pipe **pp,
pipe_name = binding->endpoint;
if (!strncasecmp(pipe_name, "/pipe/", 6) ||
!strncasecmp(pipe_name, "\\pipe\\", 6)) {
pipe_name += 6;
}
if (pipe_name[0] != '\\') {
pipe_name = talloc_asprintf(tmp_ctx, "\\%s", pipe_name);
}
if (!username || !username[0] ||
(binding->flags & DCERPC_SCHANNEL_ANY)) {
status = smbcli_full_connection(p->conn, &cli, lp_netbios_name(),
status = smbcli_full_connection(p->conn, &cli, workstation,
binding->host,
"ipc$", NULL,
"", "", NULL);
} else {
status = smbcli_full_connection(p->conn, &cli, lp_netbios_name(),
status = smbcli_full_connection(p->conn, &cli, workstation,
binding->host,
"ipc$", NULL,
username, domain,
@ -995,12 +1012,6 @@ static NTSTATUS dcerpc_pipe_connect_ncacn_np(struct dcerpc_pipe **pp,
if (!(binding->flags & DCERPC_AUTH_OPTIONS)) {
username = NULL;
}
status = dcerpc_pipe_auth(p, binding, pipe_uuid, pipe_version, domain, username, password);
if (!NT_STATUS_IS_OK(status)) {
talloc_free(p);
return status;
}
(*pp) = p;
talloc_free(tmp_ctx);
@ -1013,10 +1024,7 @@ static NTSTATUS dcerpc_pipe_connect_ncacn_np(struct dcerpc_pipe **pp,
static NTSTATUS dcerpc_pipe_connect_ncalrpc(struct dcerpc_pipe **pp,
struct dcerpc_binding *binding,
const char *pipe_uuid,
uint32_t pipe_version,
const char *domain,
const char *username,
const char *password)
uint32_t pipe_version)
{
NTSTATUS status;
struct dcerpc_pipe *p;
@ -1050,12 +1058,6 @@ static NTSTATUS dcerpc_pipe_connect_ncalrpc(struct dcerpc_pipe **pp,
return status;
}
status = dcerpc_pipe_auth(p, binding, pipe_uuid, pipe_version, domain, username, password);
if (!NT_STATUS_IS_OK(status)) {
talloc_free(p);
return status;
}
(*pp) = p;
talloc_free(tmp_ctx);
@ -1069,10 +1071,7 @@ static NTSTATUS dcerpc_pipe_connect_ncalrpc(struct dcerpc_pipe **pp,
static NTSTATUS dcerpc_pipe_connect_ncacn_unix_stream(struct dcerpc_pipe **pp,
struct dcerpc_binding *binding,
const char *pipe_uuid,
uint32_t pipe_version,
const char *domain,
const char *username,
const char *password)
uint32_t pipe_version)
{
NTSTATUS status;
struct dcerpc_pipe *p;
@ -1097,12 +1096,6 @@ static NTSTATUS dcerpc_pipe_connect_ncacn_unix_stream(struct dcerpc_pipe **pp,
return status;
}
status = dcerpc_pipe_auth(p, binding, pipe_uuid, pipe_version, domain, username, password);
if (!NT_STATUS_IS_OK(status)) {
talloc_free(p);
return status;
}
(*pp) = p;
return status;
@ -1113,10 +1106,7 @@ static NTSTATUS dcerpc_pipe_connect_ncacn_unix_stream(struct dcerpc_pipe **pp,
static NTSTATUS dcerpc_pipe_connect_ncacn_ip_tcp(struct dcerpc_pipe **pp,
struct dcerpc_binding *binding,
const char *pipe_uuid,
uint32_t pipe_version,
const char *domain,
const char *username,
const char *password)
uint32_t pipe_version)
{
NTSTATUS status;
uint32_t port = 0;
@ -1153,12 +1143,6 @@ static NTSTATUS dcerpc_pipe_connect_ncacn_ip_tcp(struct dcerpc_pipe **pp,
return status;
}
status = dcerpc_pipe_auth(p, binding, pipe_uuid, pipe_version, domain, username, password);
if (!NT_STATUS_IS_OK(status)) {
talloc_free(p);
return status;
}
(*pp) = p;
talloc_free(tmp_ctx);
@ -1172,33 +1156,42 @@ NTSTATUS dcerpc_pipe_connect_b(struct dcerpc_pipe **pp,
struct dcerpc_binding *binding,
const char *pipe_uuid,
uint32_t pipe_version,
const char *workstation,
const char *domain,
const char *username,
const char *password)
{
NTSTATUS status = NT_STATUS_INVALID_PARAMETER;
switch (binding->transport) {
case NCACN_NP:
status = dcerpc_pipe_connect_ncacn_np(pp, binding, pipe_uuid, pipe_version,
domain, username, password);
workstation, domain, username, password);
break;
case NCACN_IP_TCP:
status = dcerpc_pipe_connect_ncacn_ip_tcp(pp, binding, pipe_uuid, pipe_version,
domain, username, password);
status = dcerpc_pipe_connect_ncacn_ip_tcp(pp, binding, pipe_uuid, pipe_version);
break;
case NCACN_UNIX_STREAM:
status = dcerpc_pipe_connect_ncacn_unix_stream(pp, binding, pipe_uuid, pipe_version,
domain, username, password);
status = dcerpc_pipe_connect_ncacn_unix_stream(pp, binding, pipe_uuid, pipe_version);
break;
case NCALRPC:
status = dcerpc_pipe_connect_ncalrpc(pp, binding, pipe_uuid, pipe_version,
domain, username, password);
status = dcerpc_pipe_connect_ncalrpc(pp, binding, pipe_uuid, pipe_version);
break;
default:
return NT_STATUS_NOT_SUPPORTED;
}
if (!NT_STATUS_IS_OK(status)) {
return status;
}
status = dcerpc_pipe_auth(*pp, binding, pipe_uuid, pipe_version, workstation, domain, username, password);
if (!NT_STATUS_IS_OK(status)) {
talloc_free(*pp);
*pp = NULL;
return status;
}
return status;
}
@ -1209,15 +1202,19 @@ NTSTATUS dcerpc_pipe_connect(struct dcerpc_pipe **pp,
const char *binding,
const char *pipe_uuid,
uint32_t pipe_version,
const char *workstation,
const char *domain,
const char *username,
const char *password)
{
struct dcerpc_binding b;
struct dcerpc_binding *b;
NTSTATUS status;
TALLOC_CTX *tmp_ctx;
tmp_ctx = talloc_new(NULL);
if (!tmp_ctx) {
return NT_STATUS_NO_MEMORY;
}
status = dcerpc_parse_binding(tmp_ctx, binding, &b);
if (!NT_STATUS_IS_OK(status)) {
@ -1226,9 +1223,10 @@ NTSTATUS dcerpc_pipe_connect(struct dcerpc_pipe **pp,
return status;
}
DEBUG(3,("Using binding %s\n", dcerpc_binding_string(tmp_ctx, &b)));
DEBUG(3,("Using binding %s\n", dcerpc_binding_string(tmp_ctx, b)));
status = dcerpc_pipe_connect_b(pp, &b, pipe_uuid, pipe_version, domain, username, password);
status = dcerpc_pipe_connect_b(pp, b, pipe_uuid, pipe_version, workstation,
domain, username, password);
talloc_free(tmp_ctx);
@ -1243,13 +1241,12 @@ NTSTATUS dcerpc_pipe_connect(struct dcerpc_pipe **pp,
will be on the same SMB connection, but use a new fnum
*/
NTSTATUS dcerpc_secondary_connection(struct dcerpc_pipe *p, struct dcerpc_pipe **p2,
const char *pipe_name,
const char *pipe_uuid,
uint32_t pipe_version)
struct dcerpc_binding *b)
{
struct smbcli_tree *tree;
NTSTATUS status = NT_STATUS_INVALID_PARAMETER;
struct dcerpc_binding b;
(*p2) = dcerpc_pipe_init(p);
if (*p2 == NULL) {
@ -1262,23 +1259,15 @@ NTSTATUS dcerpc_secondary_connection(struct dcerpc_pipe *p, struct dcerpc_pipe *
if (!tree) {
return NT_STATUS_INVALID_PARAMETER;
}
status = dcerpc_pipe_open_smb((*p2)->conn, tree, pipe_name);
status = dcerpc_pipe_open_smb((*p2)->conn, tree, b->endpoint);
break;
case NCACN_IP_TCP:
status = dcerpc_parse_binding(p, p->conn->binding_string, &b);
if (!NT_STATUS_IS_OK(status)) {
return status;
}
status = dcerpc_pipe_open_tcp((*p2)->conn, b.host, atoi(b.endpoint));
status = dcerpc_pipe_open_tcp((*p2)->conn, b->host, atoi(b->endpoint));
break;
case NCALRPC:
status = dcerpc_parse_binding(p, p->conn->binding_string, &b);
if (!NT_STATUS_IS_OK(status)) {
return status;
}
status = dcerpc_pipe_open_pipe((*p2)->conn, b.endpoint);
status = dcerpc_pipe_open_pipe((*p2)->conn, b->endpoint);
break;
default:
@ -1292,12 +1281,6 @@ NTSTATUS dcerpc_secondary_connection(struct dcerpc_pipe *p, struct dcerpc_pipe *
(*p2)->conn->flags = p->conn->flags;
status = dcerpc_bind_auth_none(*p2, pipe_uuid, pipe_version);
if (!NT_STATUS_IS_OK(status)) {
talloc_free(*p2);
return status;
}
return NT_STATUS_OK;
}

View File

@ -180,7 +180,7 @@ static NTSTATUS ipc_open_generic(struct ntvfs_module_context *ntvfs,
{
struct pipe_state *p;
NTSTATUS status;
struct dcerpc_binding ep_description;
struct dcerpc_binding *ep_description;
struct ipc_private *private = ntvfs->private_data;
int fnum;
struct stream_connection *srv_conn = req->smb_conn->connection;
@ -192,6 +192,9 @@ static NTSTATUS ipc_open_generic(struct ntvfs_module_context *ntvfs,
p = talloc(req, struct pipe_state);
NT_STATUS_HAVE_NO_MEMORY(p);
ep_description = talloc(req, struct dcerpc_binding);
NT_STATUS_HAVE_NO_MEMORY(ep_description);
while (fname[0] == '\\') fname++;
p->pipe_name = talloc_asprintf(p, "\\pipe\\%s", fname);
@ -211,15 +214,15 @@ static NTSTATUS ipc_open_generic(struct ntvfs_module_context *ntvfs,
know what interface the user actually wants, just that they want
one of the interfaces attached to this pipe endpoint.
*/
ep_description.transport = NCACN_NP;
ep_description.endpoint = p->pipe_name;
ep_description->transport = NCACN_NP;
ep_description->endpoint = talloc_reference(ep_description, p->pipe_name);
/* The session info is refcount-increased in the
* dcesrv_endpoint_search_connect() function
*/
status = dcesrv_endpoint_search_connect(private->dcesrv,
p,
&ep_description,
ep_description,
req->session->session_info,
srv_conn,
&p->dce_conn);

View File

@ -58,7 +58,7 @@ static struct dcesrv_endpoint *find_endpoint(struct dcesrv_context *dce_ctx,
{
struct dcesrv_endpoint *ep;
for (ep=dce_ctx->endpoint_list; ep; ep=ep->next) {
if (endpoints_match(&ep->ep_description, ep_description)) {
if (endpoints_match(ep->ep_description, ep_description)) {
return ep;
}
}
@ -166,7 +166,7 @@ NTSTATUS dcesrv_interface_register(struct dcesrv_context *dce_ctx,
{
struct dcesrv_endpoint *ep;
struct dcesrv_if_list *ifl;
struct dcerpc_binding binding;
struct dcerpc_binding *binding;
BOOL add_ep = False;
NTSTATUS status;
@ -179,13 +179,13 @@ NTSTATUS dcesrv_interface_register(struct dcesrv_context *dce_ctx,
/* check if this endpoint exists
*/
if ((ep=find_endpoint(dce_ctx, &binding))==NULL) {
if ((ep=find_endpoint(dce_ctx, binding))==NULL) {
ep = talloc(dce_ctx, struct dcesrv_endpoint);
if (!ep) {
return NT_STATUS_NO_MEMORY;
}
ZERO_STRUCTP(ep);
ep->ep_description = binding;
ep->ep_description = talloc_reference(ep, binding);
add_ep = True;
}

View File

@ -212,7 +212,7 @@ struct dcesrv_context {
struct dcesrv_endpoint {
struct dcesrv_endpoint *next, *prev;
/* the type and location of the endpoint */
struct dcerpc_binding ep_description;
struct dcerpc_binding *ep_description;
/* the security descriptor for smb named pipes */
struct security_descriptor *sd;
/* the list of interfaces available on this endpoint */

View File

@ -159,11 +159,11 @@ static NTSTATUS add_socket_rpc_unix(struct dcesrv_context *dce_ctx, struct dcesr
dcesrv_sock->dcesrv_ctx = talloc_reference(dcesrv_sock, dce_ctx);
status = stream_setup_socket(event_ctx, model_ops, &dcesrv_stream_ops,
"unix", e->ep_description.endpoint, &port,
"unix", e->ep_description->endpoint, &port,
dcesrv_sock);
if (!NT_STATUS_IS_OK(status)) {
DEBUG(0,("service_setup_stream_socket(path=%s) failed - %s\n",
e->ep_description.endpoint, nt_errstr(status)));
e->ep_description->endpoint, nt_errstr(status)));
}
return status;
@ -177,14 +177,14 @@ static NTSTATUS add_socket_rpc_ncalrpc(struct dcesrv_context *dce_ctx, struct dc
char *full_path;
NTSTATUS status;
if (!e->ep_description.endpoint) {
if (!e->ep_description->endpoint) {
/* No identifier specified: use DEFAULT.
* DO NOT hardcode this value anywhere else. Rather, specify
* no endpoint and let the epmapper worry about it. */
e->ep_description.endpoint = talloc_strdup(dce_ctx, "DEFAULT");
e->ep_description->endpoint = talloc_strdup(dce_ctx, "DEFAULT");
}
full_path = talloc_asprintf(dce_ctx, "%s/%s", lp_ncalrpc_dir(), e->ep_description.endpoint);
full_path = talloc_asprintf(dce_ctx, "%s/%s", lp_ncalrpc_dir(), e->ep_description->endpoint);
dcesrv_sock = talloc(dce_ctx, struct dcesrv_socket_context);
NT_STATUS_HAVE_NO_MEMORY(dcesrv_sock);
@ -197,7 +197,7 @@ static NTSTATUS add_socket_rpc_ncalrpc(struct dcesrv_context *dce_ctx, struct dc
"unix", full_path, &port, dcesrv_sock);
if (!NT_STATUS_IS_OK(status)) {
DEBUG(0,("service_setup_stream_socket(identifier=%s,path=%s) failed - %s\n",
e->ep_description.endpoint, full_path, nt_errstr(status)));
e->ep_description->endpoint, full_path, nt_errstr(status)));
}
return status;
}
@ -213,8 +213,8 @@ static NTSTATUS add_socket_rpc_tcp_iface(struct dcesrv_context *dce_ctx, struct
uint16_t port = 0;
NTSTATUS status;
if (e->ep_description.endpoint) {
port = atoi(e->ep_description.endpoint);
if (e->ep_description->endpoint) {
port = atoi(e->ep_description->endpoint);
}
dcesrv_sock = talloc(dce_ctx, struct dcesrv_socket_context);
@ -231,8 +231,8 @@ static NTSTATUS add_socket_rpc_tcp_iface(struct dcesrv_context *dce_ctx, struct
address, port, nt_errstr(status)));
}
if (e->ep_description.endpoint == NULL) {
e->ep_description.endpoint = talloc_asprintf(dce_ctx, "%d", port);
if (e->ep_description->endpoint == NULL) {
e->ep_description->endpoint = talloc_asprintf(dce_ctx, "%d", port);
}
return status;
@ -275,7 +275,7 @@ NTSTATUS dcesrv_sock_init(struct dcesrv_context *dce_ctx,
}
for (e=dce_ctx->endpoint_list;e;e=e->next) {
switch (e->ep_description.transport) {
switch (e->ep_description->transport) {
case NCACN_UNIX_STREAM:
status = add_socket_rpc_unix(dce_ctx, e, event_ctx, model_ops);
NT_STATUS_NOT_OK_RETURN(status);

View File

@ -64,7 +64,7 @@ static uint32_t build_ep_list(TALLOC_CTX *mem_ctx,
for (d=endpoint_list; d; d=d->next) {
struct dcesrv_if_list *iface;
struct dcerpc_binding description;
struct dcerpc_binding *description;
for (iface=d->interface_list;iface;iface=iface->next) {
(*eps) = talloc_realloc(mem_ctx,
@ -77,10 +77,10 @@ static uint32_t build_ep_list(TALLOC_CTX *mem_ctx,
(*eps)[total].name = iface->iface.name;
description = d->ep_description;
GUID_from_string(iface->iface.uuid, &description.object);
description.object_version = iface->iface.if_version;
GUID_from_string(iface->iface.uuid, &description->object);
description->object_version = iface->iface.if_version;
status = dcerpc_binding_build_tower(mem_ctx, &description, &(*eps)[total].ep);
status = dcerpc_binding_build_tower(mem_ctx, description, &(*eps)[total].ep);
if (NT_STATUS_IS_ERR(status)) {
DEBUG(1, ("Unable to build tower for %s\n", iface->iface.name));
continue;

View File

@ -230,6 +230,9 @@ static NTSTATUS netr_ServerAuthenticate3(struct dcesrv_call_state *dce_call, TAL
pipe_state->creds->secure_channel_type = r->in.secure_channel_type;
pipe_state->creds->rid = *r->out.rid;
pipe_state->creds->domain = talloc_strdup(pipe_state->creds, lp_workgroup());
/* remember this session key state */
nt_status = schannel_store_session_key(mem_ctx, pipe_state->creds);

View File

@ -43,6 +43,7 @@ static NTSTATUS remote_op_bind(struct dcesrv_call_state *dce_call, const struct
}
status = dcerpc_pipe_connect(&(private->c_pipe), binding, iface->uuid, iface->if_version,
lp_netbios_name(),
lp_workgroup(),
lp_parm_string(-1, "dcerpc_remote", "username"),
lp_parm_string(-1, "dcerpc_remote", "password"));

View File

@ -209,7 +209,7 @@ BOOL torture_userinfo(void)
NTSTATUS status;
const char *binding;
struct dcerpc_pipe *p;
struct dcerpc_binding b;
struct dcerpc_binding *b;
TALLOC_CTX *mem_ctx;
BOOL ret = True;
struct policy_handle h;
@ -236,7 +236,7 @@ BOOL torture_userinfo(void)
ret = False;
goto done;
}
name.string = b.host;
name.string = b->host;
if (!test_opendomain(p, mem_ctx, &h, &name, &sid)) {
ret = False;

View File

@ -25,7 +25,7 @@
static BOOL test_BindingString(TALLOC_CTX *mem_ctx, const char *binding)
{
struct dcerpc_binding b, b2;
struct dcerpc_binding *b, *b2;
const char *s, *s2;
struct epm_tower tower;
NTSTATUS status;
@ -37,7 +37,7 @@ static BOOL test_BindingString(TALLOC_CTX *mem_ctx, const char *binding)
return False;
}
s = dcerpc_binding_string(mem_ctx, &b);
s = dcerpc_binding_string(mem_ctx, b);
if (!s) {
DEBUG(0, ("Error converting binding back to string for '%s'\n", binding));
return False;
@ -49,7 +49,7 @@ static BOOL test_BindingString(TALLOC_CTX *mem_ctx, const char *binding)
}
/* Generate protocol towers */
status = dcerpc_binding_build_tower(mem_ctx, &b, &tower);
status = dcerpc_binding_build_tower(mem_ctx, b, &tower);
if (NT_STATUS_IS_ERR(status)) {
DEBUG(0, ("Error generating protocol tower from '%s': %s\n", binding, nt_errstr(status)));
return False;
@ -65,18 +65,18 @@ static BOOL test_BindingString(TALLOC_CTX *mem_ctx, const char *binding)
/* Compare to a stripped down version of the binding string because
* the protocol tower doesn't contain the extra option data */
b.options = NULL;
b->options = NULL;
b.flags = 0;
b->flags = 0;
s = dcerpc_binding_string(mem_ctx, &b);
s = dcerpc_binding_string(mem_ctx, b);
if (!s) {
DEBUG(0, ("Error converting binding back to string for (stripped down) '%s'\n", binding));
return False;
}
s2 = dcerpc_binding_string(mem_ctx, &b2);
s2 = dcerpc_binding_string(mem_ctx, b2);
if (!s) {
DEBUG(0, ("Error converting binding back to string for '%s'\n", binding));
return False;

View File

@ -37,12 +37,12 @@
BOOL torture_multi_bind(void)
{
struct dcerpc_pipe *p;
const char *workstation = lp_netbios_name();
const char *domain = lp_parm_string(-1, "torture", "userdomain");
const char *username = lp_parm_string(-1, "torture", "username");
const char *password = lp_parm_string(-1, "torture", "password");
const char *pipe_uuid = DCERPC_LSARPC_UUID;
uint32_t pipe_version = DCERPC_LSARPC_VERSION;
struct dcerpc_binding b;
struct dcerpc_binding *binding;
const char *binding_string = lp_parm_string(-1, "torture", "binding");
TALLOC_CTX *mem_ctx;
@ -51,15 +51,13 @@ BOOL torture_multi_bind(void)
mem_ctx = talloc_init("torture_multi_bind");
status = dcerpc_parse_binding(mem_ctx, binding_string, &b);
status = dcerpc_parse_binding(mem_ctx, binding_string, &binding);
if (!NT_STATUS_IS_OK(status)) {
printf("Failed to parse dcerpc binding '%s'\n", binding_string);
talloc_free(mem_ctx);
return False;
}
binding = &b;
status = torture_rpc_connection(&p,
NULL,
pipe_uuid,
@ -69,24 +67,8 @@ BOOL torture_multi_bind(void)
return False;
}
if (username && username[0] && (binding->flags & DCERPC_SCHANNEL_ANY)) {
status = dcerpc_bind_auth_schannel(p, pipe_uuid, pipe_version,
domain, username, password);
} else if (username && username[0]) {
uint8_t auth_type;
if (binding->flags & DCERPC_AUTH_SPNEGO) {
auth_type = DCERPC_AUTH_TYPE_SPNEGO;
} else {
auth_type = DCERPC_AUTH_TYPE_NTLMSSP;
}
status = dcerpc_bind_auth_password(p, pipe_uuid, pipe_version,
domain, username, password,
auth_type,
binding->authservice);
} else {
status = dcerpc_bind_auth_none(p, pipe_uuid, pipe_version);
}
status = dcerpc_pipe_auth(p, binding, pipe_uuid, pipe_version,
workstation, domain, username, password);
if (NT_STATUS_IS_OK(status)) {
printf("(incorrectly) allowed re-bind to uuid %s - %s\n",

View File

@ -213,7 +213,7 @@ static BOOL test_Insert(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx)
{
NTSTATUS status;
struct epm_Insert r;
struct dcerpc_binding bd;
struct dcerpc_binding *bd;
r.in.num_ents = 1;
@ -228,7 +228,7 @@ static BOOL test_Insert(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx)
r.in.entries[0].tower = talloc(mem_ctx, struct epm_twr_t);
status = dcerpc_binding_build_tower(mem_ctx, &bd, &r.in.entries[0].tower->tower);
status = dcerpc_binding_build_tower(mem_ctx, bd, &r.in.entries[0].tower->tower);
if (NT_STATUS_IS_ERR(status)) {
printf("Unable to build tower from binding struct\n");
return False;

View File

@ -181,7 +181,7 @@ BOOL torture_rpc_mgmt(void)
BOOL ret = True;
const char *binding = lp_parm_string(-1, "torture", "binding");
const struct dcerpc_interface_list *l;
struct dcerpc_binding b;
struct dcerpc_binding *b;
mem_ctx = talloc_init("torture_rpc_mgmt");
@ -205,8 +205,8 @@ BOOL torture_rpc_mgmt(void)
printf("\nTesting pipe '%s'\n", l->table->name);
if (b.transport == NCACN_IP_TCP) {
status = dcerpc_epm_map_binding(mem_ctx, &b,
if (b->transport == NCACN_IP_TCP) {
status = dcerpc_epm_map_binding(mem_ctx, b,
l->table->uuid,
l->table->if_version);
if (!NT_STATUS_IS_OK(status)) {
@ -214,10 +214,10 @@ BOOL torture_rpc_mgmt(void)
continue;
}
} else {
b.endpoint = l->table->name;
b->endpoint = talloc_strdup(b, l->table->name);
}
lp_set_cmdline("torture:binding", dcerpc_binding_string(mem_ctx, &b));
lp_set_cmdline("torture:binding", dcerpc_binding_string(mem_ctx, b));
status = torture_rpc_connection(&p,
l->table->name,

View File

@ -76,16 +76,22 @@ static BOOL test_LogonUasLogoff(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx)
BOOL test_SetupCredentials(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
const char *machine_name,
const char *plain_pass,
struct creds_CredentialState *creds)
struct creds_CredentialState **creds_out)
{
NTSTATUS status;
struct netr_ServerReqChallenge r;
struct netr_ServerAuthenticate a;
struct netr_Credential credentials1, credentials2, credentials3;
struct creds_CredentialState *creds;
struct samr_Password mach_password;
printf("Testing ServerReqChallenge\n");
creds = talloc(mem_ctx, struct creds_CredentialState);
if (!creds) {
return False;
}
r.in.server_name = NULL;
r.in.computer_name = machine_name;
r.in.credentials = &credentials1;
@ -108,7 +114,11 @@ BOOL test_SetupCredentials(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
a.in.credentials = &credentials3;
a.out.credentials = &credentials3;
creds_client_init(creds, &credentials1, &credentials2, &mach_password, &credentials3,
creds_client_init(creds, &credentials1, &credentials2,
machine_name,
lp_workgroup(),
a.in.account_name,
&mach_password, &credentials3,
0);
printf("Testing ServerAuthenticate\n");
@ -124,6 +134,7 @@ BOOL test_SetupCredentials(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
return False;
}
*creds_out = creds;
return True;
}
@ -132,16 +143,22 @@ BOOL test_SetupCredentials2(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
const char *machine_name,
const char *plain_pass,
int sec_chan_type,
struct creds_CredentialState *creds)
struct creds_CredentialState **creds_out)
{
NTSTATUS status;
struct netr_ServerReqChallenge r;
struct netr_ServerAuthenticate2 a;
struct netr_Credential credentials1, credentials2, credentials3;
struct creds_CredentialState *creds;
struct samr_Password mach_password;
printf("Testing ServerReqChallenge\n");
creds = talloc(mem_ctx, struct creds_CredentialState);
if (!creds) {
return False;
}
r.in.server_name = NULL;
r.in.computer_name = machine_name;
r.in.credentials = &credentials1;
@ -166,7 +183,11 @@ BOOL test_SetupCredentials2(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
a.in.credentials = &credentials3;
a.out.credentials = &credentials3;
creds_client_init(creds, &credentials1, &credentials2, &mach_password, &credentials3,
creds_client_init(creds, &credentials1, &credentials2,
machine_name,
lp_workgroup(),
a.in.account_name,
&mach_password, &credentials3,
negotiate_flags);
printf("Testing ServerAuthenticate2\n");
@ -184,6 +205,7 @@ BOOL test_SetupCredentials2(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
printf("negotiate_flags=0x%08x\n", negotiate_flags);
*creds_out = creds;
return True;
}
@ -192,17 +214,23 @@ BOOL test_SetupCredentials3(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
uint32_t negotiate_flags,
const char *machine_name,
const char *plain_pass,
struct creds_CredentialState *creds)
struct creds_CredentialState **creds_out)
{
NTSTATUS status;
struct netr_ServerReqChallenge r;
struct netr_ServerAuthenticate3 a;
struct netr_Credential credentials1, credentials2, credentials3;
struct creds_CredentialState *creds;
struct samr_Password mach_password;
uint32_t rid;
printf("Testing ServerReqChallenge\n");
creds = talloc(mem_ctx, struct creds_CredentialState);
if (!creds) {
return False;
}
r.in.server_name = NULL;
r.in.computer_name = machine_name;
r.in.credentials = &credentials1;
@ -228,7 +256,11 @@ BOOL test_SetupCredentials3(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
a.out.negotiate_flags = &negotiate_flags;
a.out.rid = &rid;
creds_client_init(creds, &credentials1, &credentials2, &mach_password, &credentials3,
creds_client_init(creds, &credentials1, &credentials2,
machine_name,
lp_workgroup(),
a.in.account_name,
&mach_password, &credentials3,
negotiate_flags);
printf("Testing ServerAuthenticate3\n");
@ -246,6 +278,7 @@ BOOL test_SetupCredentials3(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
printf("negotiate_flags=0x%08x\n", negotiate_flags);
*creds_out = creds;
return True;
}
@ -257,7 +290,7 @@ static BOOL test_SetPassword(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx)
NTSTATUS status;
struct netr_ServerPasswordSet r;
const char *password;
struct creds_CredentialState creds;
struct creds_CredentialState *creds;
if (!test_SetupCredentials(p, mem_ctx, TEST_MACHINE_NAME,
machine_password, &creds)) {
@ -272,7 +305,7 @@ static BOOL test_SetPassword(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx)
password = "";
E_md4hash(password, r.in.new_password.hash);
creds_des_encrypt(&creds, &r.in.new_password);
creds_des_encrypt(creds, &r.in.new_password);
/* by changing the machine password to ""
* we check if the server uses password restrictions
* for ServerPasswordSet2
@ -281,7 +314,7 @@ static BOOL test_SetPassword(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx)
printf("Testing a second ServerPasswordSet on machine account\n");
printf("Changing machine account password to '%s'\n", password);
creds_client_authenticator(&creds, &r.in.credential);
creds_client_authenticator(creds, &r.in.credential);
status = dcerpc_netr_ServerPasswordSet(p, mem_ctx, &r);
if (!NT_STATUS_IS_OK(status)) {
@ -289,7 +322,7 @@ static BOOL test_SetPassword(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx)
return False;
}
if (!creds_client_check(&creds, &r.out.return_authenticator.cred)) {
if (!creds_client_check(creds, &r.out.return_authenticator.cred)) {
printf("Credential chaining failed\n");
}
@ -303,12 +336,12 @@ static BOOL test_SetPassword(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx)
password = generate_random_str(mem_ctx, 8);
E_md4hash(password, r.in.new_password.hash);
creds_des_encrypt(&creds, &r.in.new_password);
creds_des_encrypt(creds, &r.in.new_password);
printf("Testing ServerPasswordSet on machine account\n");
printf("Changing machine account password to '%s'\n", password);
creds_client_authenticator(&creds, &r.in.credential);
creds_client_authenticator(creds, &r.in.credential);
status = dcerpc_netr_ServerPasswordSet(p, mem_ctx, &r);
if (!NT_STATUS_IS_OK(status)) {
@ -316,7 +349,7 @@ static BOOL test_SetPassword(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx)
return False;
}
if (!creds_client_check(&creds, &r.out.return_authenticator.cred)) {
if (!creds_client_check(creds, &r.out.return_authenticator.cred)) {
printf("Credential chaining failed\n");
}
@ -327,7 +360,7 @@ static BOOL test_SetPassword(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx)
printf("Testing a second ServerPasswordSet on machine account\n");
printf("Changing machine account password to '%s' (same as previous run)\n", password);
creds_client_authenticator(&creds, &r.in.credential);
creds_client_authenticator(creds, &r.in.credential);
status = dcerpc_netr_ServerPasswordSet(p, mem_ctx, &r);
if (!NT_STATUS_IS_OK(status)) {
@ -335,7 +368,7 @@ static BOOL test_SetPassword(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx)
return False;
}
if (!creds_client_check(&creds, &r.out.return_authenticator.cred)) {
if (!creds_client_check(creds, &r.out.return_authenticator.cred)) {
printf("Credential chaining failed\n");
}
@ -357,7 +390,7 @@ static BOOL test_SetPassword2(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx)
NTSTATUS status;
struct netr_ServerPasswordSet2 r;
const char *password;
struct creds_CredentialState creds;
struct creds_CredentialState *creds;
if (!test_SetupCredentials(p, mem_ctx, TEST_MACHINE_NAME,
machine_password, &creds)) {
@ -371,7 +404,7 @@ static BOOL test_SetPassword2(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx)
password = "";
encode_pw_buffer(r.in.new_password.data, password, STR_UNICODE);
creds_arcfour_crypt(&creds, r.in.new_password.data, 516);
creds_arcfour_crypt(creds, r.in.new_password.data, 516);
/* by changing the machine password to ""
* we check if the server uses password restrictions
@ -381,7 +414,7 @@ static BOOL test_SetPassword2(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx)
printf("Testing a second ServerPasswordSet2 on machine account\n");
printf("Changing machine account password to '%s'\n", password);
creds_client_authenticator(&creds, &r.in.credential);
creds_client_authenticator(creds, &r.in.credential);
status = dcerpc_netr_ServerPasswordSet2(p, mem_ctx, &r);
if (!NT_STATUS_IS_OK(status)) {
@ -389,7 +422,7 @@ static BOOL test_SetPassword2(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx)
return False;
}
if (!creds_client_check(&creds, &r.out.return_authenticator.cred)) {
if (!creds_client_check(creds, &r.out.return_authenticator.cred)) {
printf("Credential chaining failed\n");
}
@ -403,12 +436,12 @@ static BOOL test_SetPassword2(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx)
/* now try a random password */
password = generate_random_str(mem_ctx, 8);
encode_pw_buffer(r.in.new_password.data, password, STR_UNICODE);
creds_arcfour_crypt(&creds, r.in.new_password.data, 516);
creds_arcfour_crypt(creds, r.in.new_password.data, 516);
printf("Testing ServerPasswordSet2 on machine account\n");
printf("Changing machine account password to '%s'\n", password);
creds_client_authenticator(&creds, &r.in.credential);
creds_client_authenticator(creds, &r.in.credential);
status = dcerpc_netr_ServerPasswordSet2(p, mem_ctx, &r);
if (!NT_STATUS_IS_OK(status)) {
@ -416,7 +449,7 @@ static BOOL test_SetPassword2(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx)
return False;
}
if (!creds_client_check(&creds, &r.out.return_authenticator.cred)) {
if (!creds_client_check(creds, &r.out.return_authenticator.cred)) {
printf("Credential chaining failed\n");
}
@ -427,7 +460,7 @@ static BOOL test_SetPassword2(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx)
printf("Testing a second ServerPasswordSet2 on machine account\n");
printf("Changing machine account password to '%s' (same as previous run)\n", password);
creds_client_authenticator(&creds, &r.in.credential);
creds_client_authenticator(creds, &r.in.credential);
status = dcerpc_netr_ServerPasswordSet2(p, mem_ctx, &r);
if (!NT_STATUS_IS_OK(status)) {
@ -435,7 +468,7 @@ static BOOL test_SetPassword2(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx)
return False;
}
if (!creds_client_check(&creds, &r.out.return_authenticator.cred)) {
if (!creds_client_check(creds, &r.out.return_authenticator.cred)) {
printf("Credential chaining failed\n");
}
@ -460,7 +493,7 @@ static BOOL test_SamLogon(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx)
struct netr_NetworkInfo ninfo;
const char *username = lp_parm_string(-1, "torture", "username");
const char *password = lp_parm_string(-1, "torture", "password");
struct creds_CredentialState creds;
struct creds_CredentialState *creds;
int i;
BOOL ret = True;
@ -494,7 +527,7 @@ static BOOL test_SamLogon(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx)
for (i=2;i<=3;i++) {
ZERO_STRUCT(auth2);
creds_client_authenticator(&creds, &auth);
creds_client_authenticator(creds, &auth);
r.in.validation_level = i;
@ -506,7 +539,7 @@ static BOOL test_SamLogon(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx)
ret = False;
}
if (!creds_client_check(&creds, &r.out.return_authenticator->cred)) {
if (!creds_client_check(creds, &r.out.return_authenticator->cred)) {
printf("Credential chaining failed\n");
}
}
@ -540,7 +573,7 @@ static BOOL test_DatabaseSync(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx)
{
NTSTATUS status;
struct netr_DatabaseSync r;
struct creds_CredentialState creds;
struct creds_CredentialState *creds;
const uint32_t database_ids[] = {SAM_DATABASE_DOMAIN, SAM_DATABASE_BUILTIN, SAM_DATABASE_PRIVS};
int i;
BOOL ret = True;
@ -561,7 +594,7 @@ static BOOL test_DatabaseSync(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx)
printf("Testing DatabaseSync of id %d\n", r.in.database_id);
do {
creds_client_authenticator(&creds, &r.in.credential);
creds_client_authenticator(creds, &r.in.credential);
status = dcerpc_netr_DatabaseSync(p, mem_ctx, &r);
if (!NT_STATUS_IS_OK(status) &&
@ -571,7 +604,7 @@ static BOOL test_DatabaseSync(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx)
break;
}
if (!creds_client_check(&creds, &r.out.return_authenticator.cred)) {
if (!creds_client_check(creds, &r.out.return_authenticator.cred)) {
printf("Credential chaining failed\n");
}
@ -601,7 +634,7 @@ static BOOL test_DatabaseDeltas(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx)
{
NTSTATUS status;
struct netr_DatabaseDeltas r;
struct creds_CredentialState creds;
struct creds_CredentialState *creds;
const uint32_t database_ids[] = {0, 1, 2};
int i;
BOOL ret = True;
@ -628,7 +661,7 @@ static BOOL test_DatabaseDeltas(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx)
r.in.database_id, r.in.sequence_num);
do {
creds_client_authenticator(&creds, &r.in.credential);
creds_client_authenticator(creds, &r.in.credential);
status = dcerpc_netr_DatabaseDeltas(p, mem_ctx, &r);
if (!NT_STATUS_IS_OK(status) &&
@ -638,7 +671,7 @@ static BOOL test_DatabaseDeltas(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx)
break;
}
if (!creds_client_check(&creds, &r.out.return_authenticator.cred)) {
if (!creds_client_check(creds, &r.out.return_authenticator.cred)) {
printf("Credential chaining failed\n");
}
@ -657,7 +690,7 @@ static BOOL test_AccountDeltas(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx)
{
NTSTATUS status;
struct netr_AccountDeltas r;
struct creds_CredentialState creds;
struct creds_CredentialState *creds;
BOOL ret = True;
if (!test_SetupCredentials(p, mem_ctx, TEST_MACHINE_NAME, machine_password, &creds)) {
@ -667,7 +700,7 @@ static BOOL test_AccountDeltas(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx)
r.in.logon_server = talloc_asprintf(mem_ctx, "\\\\%s", dcerpc_server_name(p));
r.in.computername = TEST_MACHINE_NAME;
ZERO_STRUCT(r.in.return_authenticator);
creds_client_authenticator(&creds, &r.in.credential);
creds_client_authenticator(creds, &r.in.credential);
ZERO_STRUCT(r.in.uas);
r.in.count=10;
r.in.level=0;
@ -692,7 +725,7 @@ static BOOL test_AccountSync(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx)
{
NTSTATUS status;
struct netr_AccountSync r;
struct creds_CredentialState creds;
struct creds_CredentialState *creds;
BOOL ret = True;
if (!test_SetupCredentials(p, mem_ctx, TEST_MACHINE_NAME, machine_password, &creds)) {
@ -702,7 +735,7 @@ static BOOL test_AccountSync(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx)
r.in.logon_server = talloc_asprintf(mem_ctx, "\\\\%s", dcerpc_server_name(p));
r.in.computername = TEST_MACHINE_NAME;
ZERO_STRUCT(r.in.return_authenticator);
creds_client_authenticator(&creds, &r.in.credential);
creds_client_authenticator(creds, &r.in.credential);
ZERO_STRUCT(r.in.recordid);
r.in.reference=0;
r.in.level=0;
@ -886,7 +919,7 @@ static BOOL test_DatabaseSync2(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx)
{
NTSTATUS status;
struct netr_DatabaseSync2 r;
struct creds_CredentialState creds;
struct creds_CredentialState *creds;
const uint32_t database_ids[] = {0, 1, 2};
int i;
BOOL ret = True;
@ -910,7 +943,7 @@ static BOOL test_DatabaseSync2(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx)
printf("Testing DatabaseSync2 of id %d\n", r.in.database_id);
do {
creds_client_authenticator(&creds, &r.in.credential);
creds_client_authenticator(creds, &r.in.credential);
status = dcerpc_netr_DatabaseSync2(p, mem_ctx, &r);
if (!NT_STATUS_IS_OK(status) &&
@ -920,7 +953,7 @@ static BOOL test_DatabaseSync2(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx)
break;
}
if (!creds_client_check(&creds, &r.out.return_authenticator.cred)) {
if (!creds_client_check(creds, &r.out.return_authenticator.cred)) {
printf("Credential chaining failed\n");
}
@ -1082,7 +1115,7 @@ static BOOL test_GetDomainInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx)
struct netr_LogonGetDomainInfo r;
struct netr_DomainQuery1 q1;
struct netr_Authenticator a;
struct creds_CredentialState creds;
struct creds_CredentialState *creds;
if (!test_SetupCredentials3(p, mem_ctx, NETLOGON_NEG_AUTH2_ADS_FLAGS,
TEST_MACHINE_NAME, machine_password, &creds)) {
@ -1091,7 +1124,7 @@ static BOOL test_GetDomainInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx)
ZERO_STRUCT(r);
creds_client_authenticator(&creds, &a);
creds_client_authenticator(creds, &a);
r.in.server_name = talloc_asprintf(mem_ctx, "\\\\%s", dcerpc_server_name(p));
r.in.computer_name = TEST_MACHINE_NAME;
@ -1119,7 +1152,7 @@ static BOOL test_GetDomainInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx)
return False;
}
if (!creds_client_check(&creds, &a.cred)) {
if (!creds_client_check(creds, &a.cred)) {
printf("Credential chaining failed\n");
return False;
}
@ -1143,8 +1176,8 @@ static BOOL test_GetDomainInfo_async(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx)
struct netr_DomainQuery1 q1;
struct netr_Authenticator a;
#define ASYNC_COUNT 100
struct creds_CredentialState creds;
struct creds_CredentialState creds_async[ASYNC_COUNT];
struct creds_CredentialState *creds;
struct creds_CredentialState *creds_async[ASYNC_COUNT];
struct rpc_request *req[ASYNC_COUNT];
int i;
int *async_counter = talloc(mem_ctx, int);
@ -1183,9 +1216,9 @@ static BOOL test_GetDomainInfo_async(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx)
*async_counter = 0;
for (i=0;i<ASYNC_COUNT;i++) {
creds_client_authenticator(&creds, &a);
creds_client_authenticator(creds, &a);
creds_async[i] = creds;
creds_async[i] = talloc_memdup(creds, creds, sizeof(*creds));
req[i] = dcerpc_netr_LogonGetDomainInfo_send(p, mem_ctx, &r);
req[i]->async.callback = async_callback;
@ -1206,7 +1239,7 @@ static BOOL test_GetDomainInfo_async(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx)
break;
}
if (!creds_client_check(&creds_async[i], &a.cred)) {
if (!creds_client_check(creds_async[i], &a.cred)) {
printf("Credential chaining failed at async %d\n", i);
break;
}
@ -1220,6 +1253,7 @@ static BOOL test_GetDomainInfo_async(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx)
static BOOL test_ManyGetDCName(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx)
{
NTSTATUS status;
struct dcerpc_binding *b;
struct dcerpc_pipe *p2;
struct lsa_ObjectAttribute attr;
struct lsa_QosInfo qos;
@ -1240,15 +1274,25 @@ static BOOL test_ManyGetDCName(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx)
printf("Torturing GetDCName\n");
status = dcerpc_secondary_connection(p, &p2,
DCERPC_LSARPC_NAME,
DCERPC_LSARPC_UUID,
DCERPC_LSARPC_VERSION);
status = dcerpc_parse_binding(mem_ctx, p->conn->binding_string, &b);
if (!NT_STATUS_IS_OK(status)) {
printf("Failed to parse dcerpc binding '%s'\n", p->conn->binding_string);
return False;
}
status = dcerpc_secondary_connection(p, &p2, b);
if (!NT_STATUS_IS_OK(status)) {
printf("Failed to create secondary connection\n");
return False;
}
status = dcerpc_bind_auth_none(p2, DCERPC_LSARPC_UUID,
DCERPC_LSARPC_VERSION);
if (!NT_STATUS_IS_OK(status)) {
printf("Failed to create bind on secondary connection\n");
return False;
}
qos.len = 0;
qos.impersonation_level = 2;
qos.context_mode = 1;

View File

@ -28,6 +28,7 @@
#include "lib/crypto/crypto.h"
#define TEST_MACHINE_NAME "samlogontest"
#define TEST_USER_NAME "samlogontestuser"
enum ntlm_break {
BREAK_BOTH,
@ -1067,6 +1068,7 @@ static const struct ntlm_tests {
static BOOL test_SamLogon(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
struct creds_CredentialState *creds,
const char *account_domain, const char *account_name,
const char *plain_pass,
int n_subtests)
{
int i, v, l, f;
@ -1084,7 +1086,7 @@ static BOOL test_SamLogon(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
samlogon_state.mem_ctx = mem_ctx;
samlogon_state.account_name = account_name;
samlogon_state.account_domain = account_domain;
samlogon_state.password = lp_parm_string(-1, "torture", "password");
samlogon_state.password = plain_pass;
samlogon_state.p = p;
samlogon_state.creds = creds;
@ -1149,13 +1151,13 @@ static BOOL test_SamLogon(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
*/
static BOOL test_InteractiveLogon(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
struct creds_CredentialState *creds,
const char *account_domain, const char *account_name)
const char *account_domain, const char *account_name,
const char *plain_pass)
{
NTSTATUS status;
struct netr_LogonSamLogonWithFlags r;
struct netr_Authenticator a, ra;
struct netr_PasswordInfo pinfo;
const char *plain_pass;
ZERO_STRUCT(a);
ZERO_STRUCT(r);
@ -1179,8 +1181,6 @@ static BOOL test_InteractiveLogon(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
pinfo.identity_info.account_name.string = account_name;
pinfo.identity_info.workstation.string = TEST_MACHINE_NAME;
plain_pass = lp_parm_string(-1, "torture", "password");
E_deshash(plain_pass, pinfo.lmpassword.hash);
E_md4hash(plain_pass, pinfo.ntpassword.hash);
@ -1195,13 +1195,13 @@ static BOOL test_InteractiveLogon(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
printf("Testing netr_LogonSamLogonWithFlags (Interactive Logon)\n");
status = dcerpc_netr_LogonSamLogonWithFlags(p, mem_ctx, &r);
if (!NT_STATUS_IS_OK(status)) {
printf("netr_LogonSamLogonWithFlags - %s\n", nt_errstr(status));
if (!r.out.return_authenticator || !creds_client_check(creds, &r.out.return_authenticator->cred)) {
printf("Credential chaining failed\n");
return False;
}
if (!creds_client_check(creds, &r.out.return_authenticator->cred)) {
printf("Credential chaining failed\n");
if (!NT_STATUS_IS_OK(status)) {
printf("netr_LogonSamLogonWithFlags - %s\n", nt_errstr(status));
return False;
}
@ -1214,14 +1214,20 @@ BOOL torture_rpc_samlogon(void)
{
NTSTATUS status;
struct dcerpc_pipe *p;
struct dcerpc_binding b;
TALLOC_CTX *mem_ctx;
struct dcerpc_binding *b;
TALLOC_CTX *mem_ctx = talloc_init("torture_rpc_netlogon");
BOOL ret = True;
void *join_ctx;
struct test_join *join_ctx;
#if 0
struct test_join *user_ctx;
const char *user_password;
#endif
char *test_machine_account;
const char *machine_password;
const char *binding = lp_parm_string(-1, "torture", "binding");
int i;
int ci;
unsigned int credential_flags[] = {
NETLOGON_NEG_AUTH2_FLAGS,
NETLOGON_NEG_ARCFOUR,
@ -1232,17 +1238,88 @@ BOOL torture_rpc_samlogon(void)
struct creds_CredentialState *creds;
mem_ctx = talloc_init("torture_rpc_netlogon");
struct {
const char *domain;
const char *username;
const char *password;
BOOL network_login;
} usercreds[] = {
{
lp_parm_string(-1, "torture", "userdomain"),
lp_parm_string(-1, "torture", "username"),
lp_parm_string(-1, "torture", "password"),
True
},
{
NULL,
talloc_asprintf(mem_ctx,
"%s@%s",
lp_parm_string(-1, "torture", "username"),
lp_parm_string(-1, "torture", "userdomain")),
lp_parm_string(-1, "torture", "password"),
False
},
{
NULL,
talloc_asprintf(mem_ctx,
"%s@%s",
lp_parm_string(-1, "torture", "username"),
lp_realm()),
lp_parm_string(-1, "torture", "password"),
True
},
#if 0
{
lp_parm_string(-1, "torture", "userdomain"),
TEST_USER_NAME,
NULL,
True
},
{
NULL,
talloc_asprintf(mem_ctx,
"%s@%s",
TEST_USER_NAME,
lp_realm()),
NULL,
True
},
{
NULL,
talloc_asprintf(mem_ctx,
"%s@%s",
TEST_USER_NAME,
lp_parm_string(-1, "torture", "userdomain")),
NULL,
False
}
#endif
};
test_machine_account = talloc_asprintf(mem_ctx, "%s$", TEST_MACHINE_NAME);
/* We only need to join as a workstation here, and in future,
* if we wish to test against trusted domains, we must be a
* workstation here */
join_ctx = torture_join_domain(TEST_MACHINE_NAME, lp_workgroup(), ACB_WSTRUST,
&machine_password);
join_ctx = torture_create_testuser(test_machine_account, lp_workgroup(), ACB_WSTRUST,
&machine_password);
if (!join_ctx) {
printf("Failed to join as Workstation\n");
return False;
}
#if 0
user_ctx = torture_create_testuser(TEST_USER_NAME,
lp_parm_string(-1, "torture", "userdomain"),
ACB_NORMAL,
&user_password);
if (!user_ctx) {
printf("Failed to join as Workstation\n");
return False;
}
usercreds[3].password = user_password;
usercreds[4].password = user_password;
usercreds[5].password = user_password;
#endif
status = dcerpc_parse_binding(mem_ctx, binding, &b);
if (!NT_STATUS_IS_OK(status)) {
@ -1254,14 +1331,15 @@ BOOL torture_rpc_samlogon(void)
/* We have to use schannel, otherwise the SamLogonEx fails
* with INTERNAL_ERROR */
b.flags &= ~DCERPC_AUTH_OPTIONS;
b.flags |= DCERPC_SCHANNEL_WORKSTATION | DCERPC_SIGN | DCERPC_SCHANNEL_128;
b->flags &= ~DCERPC_AUTH_OPTIONS;
b->flags |= DCERPC_SCHANNEL_WORKSTATION | DCERPC_SIGN | DCERPC_SCHANNEL_128;
status = dcerpc_pipe_connect_b(&p, &b,
status = dcerpc_pipe_connect_b(&p, b,
DCERPC_NETLOGON_UUID,
DCERPC_NETLOGON_VERSION,
lp_workgroup(),
TEST_MACHINE_NAME,
lp_workgroup(),
test_machine_account,
machine_password);
if (!NT_STATUS_IS_OK(status)) {
@ -1275,91 +1353,46 @@ BOOL torture_rpc_samlogon(void)
goto failed;
}
if (!test_InteractiveLogon(p, mem_ctx, creds,
lp_parm_string(-1, "torture", "userdomain"),
lp_parm_string(-1, "torture", "username"))) {
ret = False;
}
if (!test_SamLogon(p, mem_ctx, creds,
lp_parm_string(-1, "torture", "userdomain"),
lp_parm_string(-1, "torture", "username"),
0)) {
ret = False;
}
if (!test_InteractiveLogon(p, mem_ctx, creds,
NULL,
talloc_asprintf(mem_ctx,
"%s@%s",
lp_parm_string(-1, "torture", "username"),
lp_parm_string(-1, "torture", "userdomain")))) {
ret = False;
}
if (!test_InteractiveLogon(p, mem_ctx, creds,
NULL,
talloc_asprintf(mem_ctx,
"%s@%s",
lp_parm_string(-1, "torture", "username"),
lp_realm()))) {
ret = False;
}
if (!test_SamLogon(p, mem_ctx, creds,
NULL,
talloc_asprintf(mem_ctx,
"%s@%s",
lp_parm_string(-1, "torture", "username"),
lp_realm()),
0)) {
ret = False;
}
if (!test_SamLogon(p, mem_ctx, creds,
NULL,
talloc_asprintf(mem_ctx,
"%s@%s",
lp_parm_string(-1, "torture", "username"),
lp_realm()),
0)) {
ret = False;
for (ci = 0; ci < ARRAY_SIZE(usercreds); ci++) {
if (!test_InteractiveLogon(p, mem_ctx, creds,
usercreds[ci].domain,
usercreds[ci].username,
usercreds[ci].password)) {
ret = False;
}
if (usercreds[ci].network_login) {
if (!test_SamLogon(p, mem_ctx, creds,
usercreds[ci].domain,
usercreds[ci].username,
usercreds[ci].password,
0)) {
ret = False;
}
}
}
for (i=0; i < ARRAY_SIZE(credential_flags); i++) {
if (!test_SetupCredentials2(p, mem_ctx, credential_flags[i],
TEST_MACHINE_NAME, machine_password,
SEC_CHAN_WKSTA, creds)) {
return False;
}
if (!test_InteractiveLogon(p, mem_ctx, creds,
NULL,
talloc_asprintf(mem_ctx,
"%s@%s",
lp_parm_string(-1, "torture", "username"),
lp_parm_string(-1, "torture", "userdomain")))) {
ret = False;
}
if (!test_InteractiveLogon(p, mem_ctx, creds,
NULL,
talloc_asprintf(mem_ctx,
"%s@%s",
lp_parm_string(-1, "torture", "username"),
lp_realm()))) {
ret = False;
}
if (!test_SamLogon(p, mem_ctx, creds,
NULL,
talloc_asprintf(mem_ctx,
"%s@%s",
lp_parm_string(-1, "torture", "username"),
lp_realm()),
1)) {
ret = False;
for (ci = 0; ci < ARRAY_SIZE(usercreds); ci++) {
if (!test_InteractiveLogon(p, mem_ctx, creds,
usercreds[ci].domain,
usercreds[ci].username,
usercreds[ci].password)) {
ret = False;
}
if (usercreds[ci].network_login) {
if (!test_SamLogon(p, mem_ctx, creds,
usercreds[ci].domain,
usercreds[ci].username,
usercreds[ci].password,
1)) {
ret = False;
}
}
}
}
@ -1369,6 +1402,8 @@ failed:
torture_rpc_close(p);
torture_leave_domain(join_ctx);
#if 0
torture_leave_domain(user_ctx);
#endif
return ret;
}

View File

@ -1284,10 +1284,10 @@ BOOL torture_rpc_samsync(void)
struct test_join *join_ctx2;
struct test_join *user_ctx;
const char *machine_password;
const char *machine_password2;
const char *wksta_machine_password;
const char *binding = lp_parm_string(-1, "torture", "binding");
struct dcerpc_binding b;
struct dcerpc_binding b_netlogon_wksta;
struct dcerpc_binding *b;
struct dcerpc_binding *b_netlogon_wksta;
struct samr_Connect c;
struct samr_SetDomainInfo s;
struct policy_handle *domain_policy;
@ -1298,17 +1298,23 @@ BOOL torture_rpc_samsync(void)
struct samsync_state *samsync_state;
char *test_machine_account;
char *test_wksta_machine_account;
mem_ctx = talloc_init("torture_rpc_netlogon");
join_ctx = torture_join_domain(TEST_MACHINE_NAME, lp_workgroup(), ACB_SVRTRUST,
&machine_password);
test_machine_account = talloc_asprintf(mem_ctx, "%s$", TEST_MACHINE_NAME);
join_ctx = torture_create_testuser(test_machine_account, lp_workgroup(), ACB_SVRTRUST,
&machine_password);
if (!join_ctx) {
printf("Failed to join as BDC\n");
return False;
}
join_ctx2 = torture_join_domain(TEST_WKSTA_MACHINE_NAME, lp_workgroup(), ACB_WSTRUST,
&machine_password2);
test_wksta_machine_account = talloc_asprintf(mem_ctx, "%s$", TEST_WKSTA_MACHINE_NAME);
join_ctx2 = torture_create_testuser(test_wksta_machine_account, lp_workgroup(), ACB_WSTRUST,
&wksta_machine_password);
if (!join_ctx2) {
printf("Failed to join as member\n");
return False;
@ -1409,17 +1415,19 @@ BOOL torture_rpc_samsync(void)
goto failed;
}
b.flags &= ~DCERPC_AUTH_OPTIONS;
b.flags |= DCERPC_SCHANNEL_BDC | DCERPC_SIGN;
b->flags &= ~DCERPC_AUTH_OPTIONS;
b->flags |= DCERPC_SCHANNEL_BDC | DCERPC_SIGN;
status = dcerpc_pipe_connect_b(&samsync_state->p, &b,
status = dcerpc_pipe_connect_b(&samsync_state->p, b,
DCERPC_NETLOGON_UUID,
DCERPC_NETLOGON_VERSION,
lp_workgroup(),
TEST_MACHINE_NAME,
lp_workgroup(),
test_machine_account,
machine_password);
if (!NT_STATUS_IS_OK(status)) {
printf("Failed to connect to server as a BDC: %s\n", nt_errstr(status));
ret = False;
goto failed;
}
@ -1438,17 +1446,20 @@ BOOL torture_rpc_samsync(void)
goto failed;
}
b_netlogon_wksta.flags &= ~DCERPC_AUTH_OPTIONS;
b_netlogon_wksta.flags |= DCERPC_SCHANNEL_WORKSTATION | DCERPC_SIGN;
b_netlogon_wksta->flags &= ~DCERPC_AUTH_OPTIONS;
b_netlogon_wksta->flags |= DCERPC_SCHANNEL_WORKSTATION | DCERPC_SIGN;
status = dcerpc_pipe_connect_b(&samsync_state->p_netlogon_wksta, &b_netlogon_wksta,
status = dcerpc_pipe_connect_b(&samsync_state->p_netlogon_wksta,
b_netlogon_wksta,
DCERPC_NETLOGON_UUID,
DCERPC_NETLOGON_VERSION,
lp_workgroup(),
TEST_WKSTA_MACHINE_NAME,
machine_password2);
lp_workgroup(),
test_wksta_machine_account,
wksta_machine_password);
if (!NT_STATUS_IS_OK(status)) {
printf("Failed to connect to server as a Workstation: %s\n", nt_errstr(status));
ret = False;
goto failed;
}

View File

@ -136,7 +136,7 @@ BOOL torture_rpc_scanner(void)
BOOL ret = True;
const struct dcerpc_interface_list *l;
const char *binding = lp_parm_string(-1, "torture", "binding");
struct dcerpc_binding b;
struct dcerpc_binding *b;
mem_ctx = talloc_init("torture_rpc_scanner");
@ -160,8 +160,8 @@ BOOL torture_rpc_scanner(void)
printf("\nTesting pipe '%s'\n", l->table->name);
if (b.transport == NCACN_IP_TCP) {
status = dcerpc_epm_map_binding(mem_ctx, &b,
if (b->transport == NCACN_IP_TCP) {
status = dcerpc_epm_map_binding(mem_ctx, b,
l->table->uuid,
l->table->if_version);
if (!NT_STATUS_IS_OK(status)) {
@ -169,10 +169,10 @@ BOOL torture_rpc_scanner(void)
continue;
}
} else {
b.endpoint = l->table->name;
b->endpoint = talloc_strdup(b, l->table->name);
}
lp_set_cmdline("torture:binding", dcerpc_binding_string(mem_ctx, &b));
lp_set_cmdline("torture:binding", dcerpc_binding_string(mem_ctx, b));
status = torture_rpc_connection(&p,
l->table->name,

View File

@ -93,6 +93,8 @@ static BOOL test_netlogon_ops(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
r.in.logon_level = 2;
r.in.logon.network = &ninfo;
printf("Testing LogonSamLogon with name %s\n", username);
for (i=2;i<3;i++) {
ZERO_STRUCT(auth2);
creds_client_authenticator(creds, &auth);
@ -121,13 +123,14 @@ static BOOL test_schannel(TALLOC_CTX *mem_ctx,
const char *machine_password;
NTSTATUS status;
const char *binding = lp_parm_string(-1, "torture", "binding");
struct dcerpc_binding b;
struct dcerpc_binding *b;
struct dcerpc_pipe *p = NULL;
struct dcerpc_pipe *p_netlogon = NULL;
struct creds_CredentialState *creds;
char *test_machine_account = talloc_asprintf(NULL, "%s$", TEST_MACHINE_NAME);
join_ctx = torture_join_domain(TEST_MACHINE_NAME, lp_workgroup(), acct_flags,
&machine_password);
join_ctx = torture_create_testuser(test_machine_account, lp_workgroup(),
acct_flags, &machine_password);
if (!join_ctx) {
printf("Failed to join domain with acct_flags=0x%x\n", acct_flags);
return False;
@ -139,17 +142,18 @@ static BOOL test_schannel(TALLOC_CTX *mem_ctx,
goto failed;
}
b.flags &= ~DCERPC_AUTH_OPTIONS;
b.flags |= dcerpc_flags;
b->flags &= ~DCERPC_AUTH_OPTIONS;
b->flags |= dcerpc_flags;
status = dcerpc_pipe_connect_b(&p, &b,
status = dcerpc_pipe_connect_b(&p, b,
DCERPC_SAMR_UUID,
DCERPC_SAMR_VERSION,
lp_workgroup(),
TEST_MACHINE_NAME,
lp_workgroup(),
test_machine_account,
machine_password);
if (!NT_STATUS_IS_OK(status)) {
printf("Failed to connect with schannel\n");
printf("Failed to connect with schannel: %s\n", nt_errstr(status));
goto failed;
}
@ -158,27 +162,33 @@ static BOOL test_schannel(TALLOC_CTX *mem_ctx,
goto failed;
}
status = dcerpc_parse_binding(mem_ctx, binding, &b);
status = dcerpc_schannel_creds(p->conn->security_state.generic_state, mem_ctx, &creds);
if (!NT_STATUS_IS_OK(status)) {
printf("Bad binding string %s\n", binding);
goto failed;
}
/* Also test that when we connect to the netlogon pipe, that
* the credentials we setup on the first pipe are valid for
* the second */
b.flags &= ~DCERPC_AUTH_OPTIONS;
b.flags |= dcerpc_flags;
/* Swap the binding details from SAMR to NETLOGON */
status = dcerpc_epm_map_binding(mem_ctx, b, DCERPC_NETLOGON_UUID,
DCERPC_NETLOGON_VERSION);
if (!NT_STATUS_IS_OK(status)) {
goto failed;
}
status = dcerpc_pipe_connect_b(&p_netlogon, &b,
DCERPC_NETLOGON_UUID,
DCERPC_NETLOGON_VERSION,
lp_workgroup(),
TEST_MACHINE_NAME,
machine_password);
status = dcerpc_secondary_connection(p, &p_netlogon,
b);
if (!NT_STATUS_IS_OK(status)) {
goto failed;
}
status = dcerpc_bind_auth_schannel_withkey(p_netlogon,
DCERPC_NETLOGON_UUID,
DCERPC_NETLOGON_VERSION,
creds);
if (!NT_STATUS_IS_OK(status)) {
goto failed;

View File

@ -705,6 +705,7 @@ static BOOL test_SecondaryClosePrinter(struct dcerpc_pipe *p, TALLOC_CTX *mem_ct
struct policy_handle *handle)
{
NTSTATUS status;
struct dcerpc_binding *b;
struct dcerpc_pipe *p2;
BOOL ret = True;
@ -715,15 +716,27 @@ static BOOL test_SecondaryClosePrinter(struct dcerpc_pipe *p, TALLOC_CTX *mem_ct
printf("testing close on secondary pipe\n");
status = dcerpc_secondary_connection(p, &p2,
DCERPC_SPOOLSS_NAME,
DCERPC_SPOOLSS_UUID,
DCERPC_SPOOLSS_VERSION);
status = dcerpc_parse_binding(mem_ctx, p->conn->binding_string, &b);
if (!NT_STATUS_IS_OK(status)) {
printf("Failed to parse dcerpc binding '%s'\n", p->conn->binding_string);
return False;
}
status = dcerpc_secondary_connection(p, &p2, b);
if (!NT_STATUS_IS_OK(status)) {
printf("Failed to create secondary connection\n");
return False;
}
status = dcerpc_bind_auth_none(p2, DCERPC_SPOOLSS_UUID,
DCERPC_SPOOLSS_VERSION);
if (!NT_STATUS_IS_OK(status)) {
printf("Failed to create bind on secondary connection\n");
dcerpc_pipe_close(p2);
return False;
}
if (test_ClosePrinter(p2, mem_ctx, handle)) {
printf("ERROR: Allowed close on secondary connection!\n");
ret = False;

View File

@ -232,7 +232,7 @@ again:
s.in.level = 21;
u.info21.acct_flags = acct_type;
u.info21.fields_present = SAMR_FIELD_ACCT_FLAGS | SAMR_FIELD_COMMENT | SAMR_FIELD_FULL_NAME;
u.info21.fields_present = SAMR_FIELD_ACCT_FLAGS | SAMR_FIELD_DESCRIPTION | SAMR_FIELD_COMMENT | SAMR_FIELD_FULL_NAME;
comment.string = talloc_asprintf(join,
"Tortured by Samba4: %s",
timestring(join, time(NULL)));
@ -242,6 +242,10 @@ again:
timestring(join, time(NULL)));
u.info21.full_name = full_name;
u.info21.description.string = talloc_asprintf(join,
"Samba4 torture account created by host %s: %s",
lp_netbios_name(), timestring(join, time(NULL)));
printf("Resetting ACB flags, force pw change time\n");
status = dcerpc_samr_SetUserInfo(join->p, join, &s);

View File

@ -180,7 +180,7 @@ static NTSTATUS connect_to_pipe(struct dcerpc_pipe **pp,
uint32_t pipe_version)
{
const char *binding = lp_parm_string(-1, "torture", "binding");
struct dcerpc_binding b;
struct dcerpc_binding *b;
NTSTATUS status;
struct dcerpc_pipe *p;
TALLOC_CTX *tmp_ctx;
@ -205,46 +205,23 @@ static NTSTATUS connect_to_pipe(struct dcerpc_pipe **pp,
return status;
}
DEBUG(3,("Using binding %s\n", dcerpc_binding_string(tmp_ctx, &b)));
DEBUG(3,("Using binding %s\n", dcerpc_binding_string(tmp_ctx, b)));
if (b.endpoint == NULL) {
const struct dcerpc_interface_table *table =
idl_iface_by_uuid(pipe_uuid);
struct dcerpc_binding default_binding;
int i;
if (!table) {
DEBUG(0,("Unknown interface endpoint '%s'\n",
pipe_uuid));
talloc_free(tmp_ctx);
return NT_STATUS_INVALID_PARAMETER;
/* Look up identifier using the epmapper */
if (!b->endpoint) {
status = dcerpc_epm_map_binding(tmp_ctx, b, pipe_uuid, pipe_version);
if (!NT_STATUS_IS_OK(status)) {
DEBUG(0,("Failed to map DCERPC/TCP NCACN_NP pipe for '%s' - %s\n",
pipe_uuid, nt_errstr(status)));
talloc_free(p);
return status;
}
/* Find one of the default pipes for this interface */
for (i = 0; i < table->endpoints->count; i++) {
const char * const *names = table->endpoints->names;
status = dcerpc_parse_binding(tmp_ctx, names[i],
&default_binding);
if (NT_STATUS_IS_OK(status) &&
default_binding.transport == NCACN_NP) {
pipe_name = default_binding.endpoint;
break;
}
}
} else {
pipe_name = b.endpoint;
DEBUG(1,("Mapped to DCERPC/NP pipe %s\n", b->endpoint));
}
if (!strncasecmp(pipe_name, "/pipe/", 6) ||
!strncasecmp(pipe_name, "\\pipe\\", 6)) {
pipe_name += 6;
}
pipe_name = b->endpoint;
if (pipe_name[0] != '\\') {
pipe_name = talloc_asprintf(mem_ctx, "\\%s", pipe_name);
}
status = dcerpc_pipe_open_smb(p->conn, tree, pipe_name);
if (!NT_STATUS_IS_OK(status)) {
@ -502,6 +479,9 @@ static NTSTATUS setup_netlogon_creds(struct smbcli_transport *transport,
a.out.credentials = &credentials3;
creds_client_init(creds, &credentials1, &credentials2,
machine_name,
domain,
a.in.account_name,
&mach_password, &credentials3,
negotiate_flags);
@ -1056,7 +1036,6 @@ static BOOL xp_login(const char *dcname, const char *wksname,
status = dcerpc_bind_auth_schannel_withkey(netlogon_schannel_pipe,
DCERPC_NETLOGON_UUID,
DCERPC_NETLOGON_VERSION,
"", "", "",
netlogon_creds);
if (!NT_STATUS_IS_OK(status))

View File

@ -138,6 +138,7 @@ NTSTATUS torture_rpc_connection(struct dcerpc_pipe **p,
}
status = dcerpc_pipe_connect(p, binding, pipe_uuid, pipe_version,
lp_netbios_name(),
lp_parm_string(-1, "torture", "userdomain"),
lp_parm_string(-1, "torture", "username"),
lp_parm_string(-1, "torture", "password"));
@ -154,7 +155,7 @@ NTSTATUS torture_rpc_connection_transport(struct dcerpc_pipe **p,
{
NTSTATUS status;
const char *binding = lp_parm_string(-1, "torture", "binding");
struct dcerpc_binding b;
struct dcerpc_binding *b;
TALLOC_CTX *mem_ctx = talloc_init("torture_rpc_connection_smb");
if (!binding) {
@ -169,9 +170,10 @@ NTSTATUS torture_rpc_connection_transport(struct dcerpc_pipe **p,
return status;
}
b.transport = transport;
b->transport = transport;
status = dcerpc_pipe_connect_b(p, &b, pipe_uuid, pipe_version,
status = dcerpc_pipe_connect_b(p, b, pipe_uuid, pipe_version,
lp_netbios_name(),
lp_parm_string(-1, "torture", "userdomain"),
lp_parm_string(-1, "torture", "username"),
lp_parm_string(-1, "torture", "password"));
@ -2597,7 +2599,7 @@ static void usage(poptContext pc)
static BOOL is_binding_string(const char *binding_string)
{
TALLOC_CTX *mem_ctx = talloc_init("is_binding_string");
struct dcerpc_binding binding_struct;
struct dcerpc_binding *binding_struct;
NTSTATUS status;
status = dcerpc_parse_binding(mem_ctx, binding_string, &binding_struct);

View File

@ -395,7 +395,7 @@ static void manage_gensec_request(enum stdio_helper_mode stdio_helper_mode,
}
if (!NT_STATUS_IS_OK(nt_status)) {
DEBUG(1, ("SPENGO login failed to initialise: %s\n", nt_errstr(nt_status)));
DEBUG(1, ("SPNEGO login failed to initialise: %s\n", nt_errstr(nt_status)));
mux_printf(mux_id, "BH\n");
return;
}