summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--source4/libcli/auth/credentials.h6
-rw-r--r--source4/libcli/auth/gensec.h1
-rw-r--r--source4/libcli/util/smbdes.c2
-rw-r--r--source4/libcli/util/smbencrypt.c25
-rw-r--r--source4/librpc/idl/netlogon.idl32
-rw-r--r--source4/librpc/rpc/dcerpc_schannel.c67
-rw-r--r--source4/rpc_server/netlogon/schannel_state.c11
-rw-r--r--source4/torture/config.mk1
-rw-r--r--source4/torture/rpc/netlogon.c76
-rw-r--r--source4/torture/rpc/schannel.c98
-rw-r--r--source4/torture/rpc/xplogin.c15
-rw-r--r--source4/torture/torture.c1
12 files changed, 260 insertions, 75 deletions
diff --git a/source4/libcli/auth/credentials.h b/source4/libcli/auth/credentials.h
index a6e119e1ad..30114fe7fa 100644
--- a/source4/libcli/auth/credentials.h
+++ b/source4/libcli/auth/credentials.h
@@ -36,12 +36,6 @@ struct creds_CredentialState {
to NT4. Actually, anything other than 1ff would seem to do... */
#define NETLOGON_NEG_AUTH2_FLAGS 0x000701ff
-
-#define NETLOGON_NEG_ARCFOUR 0x00000004
-#define NETLOGON_NEG_128BIT 0x00004000
-
-#define NETLOGON_NEG_SCHANNEL 0x40000000
-
/* these are the flags that ADS clients use */
#define NETLOGON_NEG_AUTH2_ADS_FLAGS (0x200fbffb | NETLOGON_NEG_ARCFOUR | NETLOGON_NEG_128BIT | NETLOGON_NEG_SCHANNEL)
diff --git a/source4/libcli/auth/gensec.h b/source4/libcli/auth/gensec.h
index b2c685332b..23d9861cb7 100644
--- a/source4/libcli/auth/gensec.h
+++ b/source4/libcli/auth/gensec.h
@@ -28,7 +28,6 @@ struct gensec_user {
const char *realm;
const char *name;
const char *password;
- char schan_session_key[16];
};
struct gensec_target {
const char *principal;
diff --git a/source4/libcli/util/smbdes.c b/source4/libcli/util/smbdes.c
index a7c8f760ea..4e4222b9e6 100644
--- a/source4/libcli/util/smbdes.c
+++ b/source4/libcli/util/smbdes.c
@@ -439,7 +439,7 @@ void arcfour_crypt(uint8_t *data, const uint8_t keystr[16], int len)
/* Decode a sam password hash into a password. The password hash is the
same method used to store passwords in the NT registry. The DES key
used is based on the RID of the user. */
-void sam_pwd_hash(uint_t rid, const uint8_t *in, uint8_t *out, int forw)
+void sam_rid_crypt(uint_t rid, const uint8_t *in, uint8_t *out, int forw)
{
uint8_t s[14];
diff --git a/source4/libcli/util/smbencrypt.c b/source4/libcli/util/smbencrypt.c
index d327b53f9d..dac8674f03 100644
--- a/source4/libcli/util/smbencrypt.c
+++ b/source4/libcli/util/smbencrypt.c
@@ -374,15 +374,13 @@ static DATA_BLOB LMv2_generate_response(const uint8_t ntlm_v2_hash[16],
return final_response;
}
-BOOL SMBNTLMv2encrypt(const char *user, const char *domain, const char *password,
- const DATA_BLOB *server_chal,
- const DATA_BLOB *names_blob,
- DATA_BLOB *lm_response, DATA_BLOB *nt_response,
- DATA_BLOB *lm_session_key, DATA_BLOB *user_session_key)
+BOOL SMBNTLMv2encrypt_hash(const char *user, const char *domain, const char nt_hash[16],
+ const DATA_BLOB *server_chal,
+ const DATA_BLOB *names_blob,
+ DATA_BLOB *lm_response, DATA_BLOB *nt_response,
+ DATA_BLOB *lm_session_key, DATA_BLOB *user_session_key)
{
- uint8_t nt_hash[16];
uint8_t ntlm_v2_hash[16];
- E_md4hash(password, nt_hash);
/* We don't use the NT# directly. Instead we use it mashed up with
the username and domain.
@@ -420,6 +418,19 @@ BOOL SMBNTLMv2encrypt(const char *user, const char *domain, const char *password
return True;
}
+BOOL SMBNTLMv2encrypt(const char *user, const char *domain, const char *password,
+ const DATA_BLOB *server_chal,
+ const DATA_BLOB *names_blob,
+ DATA_BLOB *lm_response, DATA_BLOB *nt_response,
+ DATA_BLOB *lm_session_key, DATA_BLOB *user_session_key)
+{
+ uint8_t nt_hash[16];
+ E_md4hash(password, nt_hash);
+
+ return SMBNTLMv2encrypt_hash(user, domain, nt_hash, server_chal, names_blob,
+ lm_response, nt_response, lm_session_key, user_session_key);
+}
+
/***********************************************************
encode a password buffer with a unicode password. The buffer
is filled with random data to make it harder to attack.
diff --git a/source4/librpc/idl/netlogon.idl b/source4/librpc/idl/netlogon.idl
index f6677d9621..f55049d30e 100644
--- a/source4/librpc/idl/netlogon.idl
+++ b/source4/librpc/idl/netlogon.idl
@@ -285,6 +285,11 @@ interface netlogon
/*****************/
/* Function 0x07 */
+ /* SAM database types */
+ const int SAM_DATABASE_DOMAIN = 0x00; /* Domain users and groups */
+ const int SAM_DATABASE_BUILTIN = 0x01; /* BUILTIN users and groups */
+ const int SAM_DATABASE_PRIVS = 0x02; /* Privileges */
+
typedef struct {
unistr *account_name;
netr_String unknown1;
@@ -313,19 +318,19 @@ interface netlogon
netr_String logon_script;
netr_String description;
netr_String workstations;
- NTTIME LastLogon;
- NTTIME LastLogoff;
+ NTTIME last_logon;
+ NTTIME last_logoff;
samr_LogonHours logon_hours;
uint16 bad_pw_count;
uint16 logon_count;
- NTTIME PwLastSet;
- NTTIME AccountExpires;
- uint32 AccountControl;
- samr_Password lmpw;
- samr_Password ntpw;
- bool8 NTPwPresent;
- bool8 LMPwPresent;
- bool8 PwExpired;
+ NTTIME last_password_change;
+ NTTIME acct_expiry;
+ uint32 acct_flags;
+ samr_Password lmpassword;
+ samr_Password ntpassword;
+ bool8 ntpassword_present;
+ bool8 lmpassword_present;
+ bool8 password_expired;
netr_String UserComment;
netr_String Parameters;
uint16 CountryCode;
@@ -778,6 +783,13 @@ interface netlogon
);
+ /* If this flag is not set, then the passwords and LM session keys are
+ * encrypted with DES calls. (And the user session key is
+ * unencrypted) */
+ const int NETLOGON_NEG_ARCFOUR = 0x00000004;
+ const int NETLOGON_NEG_128BIT = 0x00004000;
+ const int NETLOGON_NEG_SCHANNEL = 0x40000000;
+
/*****************/
/* Function 0x0F */
diff --git a/source4/librpc/rpc/dcerpc_schannel.c b/source4/librpc/rpc/dcerpc_schannel.c
index c0db63e8b8..1e1bdb8227 100644
--- a/source4/librpc/rpc/dcerpc_schannel.c
+++ b/source4/librpc/rpc/dcerpc_schannel.c
@@ -32,7 +32,7 @@ enum schannel_position {
struct dcerpc_schannel_state {
enum schannel_position state;
struct schannel_state *schannel_state;
- struct creds_CredentialState creds;
+ struct creds_CredentialState *creds;
char *account_name;
};
@@ -41,7 +41,7 @@ static NTSTATUS dcerpc_schannel_key(struct dcerpc_pipe *p,
const char *username,
const char *password,
int chan_type,
- uint8_t new_session_key[16]);
+ struct creds_CredentialState *creds);
/*
wrappers for the schannel_*() functions
@@ -121,6 +121,15 @@ static NTSTATUS dcerpc_schannel_update(struct gensec_security *gensec_security,
return NT_STATUS_OK;
}
+ status = schannel_start(&dce_schan_state->schannel_state,
+ dce_schan_state->creds->session_key,
+ True);
+ if (!NT_STATUS_IS_OK(status)) {
+ DEBUG(1, ("Failed to start schannel client\n"));
+ return status;
+ }
+ talloc_steal(dce_schan_state, dce_schan_state->schannel_state);
+
bind_schannel.unknown1 = 0;
#if 0
/* to support this we'd need to have access to the full domain name */
@@ -178,7 +187,7 @@ static NTSTATUS dcerpc_schannel_update(struct gensec_security *gensec_security,
/* start up the schannel server code */
status = schannel_start(&dce_schan_state->schannel_state,
- dce_schan_state->creds.session_key, False);
+ 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)));
@@ -249,12 +258,7 @@ NTSTATUS dcerpc_schannel_creds(struct gensec_security *gensec_security,
{
struct dcerpc_schannel_state *dce_schan_state = gensec_security->private_data;
- *creds = talloc_p(mem_ctx, struct creds_CredentialState);
- if (!*creds) {
- return NT_STATUS_NO_MEMORY;
- }
-
- **creds = dce_schan_state->creds;
+ *creds = dce_schan_state->creds;
return NT_STATUS_OK;
}
@@ -277,38 +281,23 @@ static NTSTATUS dcerpc_schannel_start(struct gensec_security *gensec_security)
static NTSTATUS dcerpc_schannel_server_start(struct gensec_security *gensec_security)
{
NTSTATUS status;
- struct dcerpc_schannel_state *dce_schan_state;
status = dcerpc_schannel_start(gensec_security);
-
- dce_schan_state = gensec_security->private_data;
- dce_schan_state->schannel_state = NULL;
-
if (!NT_STATUS_IS_OK(status)) {
return status;
}
+
return NT_STATUS_OK;
}
static NTSTATUS dcerpc_schannel_client_start(struct gensec_security *gensec_security)
{
NTSTATUS status;
- struct dcerpc_schannel_state *dce_schan_state;
status = dcerpc_schannel_start(gensec_security);
if (!NT_STATUS_IS_OK(status)) {
return status;
}
- dce_schan_state = gensec_security->private_data;
-
- status = schannel_start(&dce_schan_state->schannel_state,
- gensec_security->user.schan_session_key,
- True);
- if (!NT_STATUS_IS_OK(status)) {
- DEBUG(1, ("Failed to start schannel client\n"));
- return status;
- }
- talloc_steal(dce_schan_state, dce_schan_state->schannel_state);
return NT_STATUS_OK;
}
@@ -336,7 +325,7 @@ static NTSTATUS dcerpc_schannel_key(struct dcerpc_pipe *p,
const char *username,
const char *password,
int chan_type,
- uint8_t new_session_key[16])
+ struct creds_CredentialState *creds)
{
NTSTATUS status;
struct dcerpc_pipe *p2;
@@ -344,7 +333,6 @@ static NTSTATUS dcerpc_schannel_key(struct dcerpc_pipe *p,
struct netr_ServerAuthenticate2 a;
struct netr_Credential credentials1, credentials2, credentials3;
struct samr_Password mach_pwd;
- struct creds_CredentialState creds;
const char *workgroup, *workstation;
uint32_t negotiate_flags;
@@ -388,7 +376,7 @@ 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, &mach_pwd, &credentials3,
negotiate_flags);
a.in.server_name = r.in.server_name;
@@ -405,7 +393,7 @@ static NTSTATUS dcerpc_schannel_key(struct dcerpc_pipe *p,
return status;
}
- if (!creds_client_check(&creds, a.out.credentials)) {
+ if (!creds_client_check(creds, a.out.credentials)) {
return NT_STATUS_UNSUCCESSFUL;
}
@@ -416,8 +404,6 @@ static NTSTATUS dcerpc_schannel_key(struct dcerpc_pipe *p,
*/
dcerpc_pipe_close(p2);
- memcpy(new_session_key, creds.session_key, 16);
-
return NT_STATUS_OK;
}
@@ -430,18 +416,16 @@ NTSTATUS dcerpc_bind_auth_schannel_withkey(struct dcerpc_pipe *p,
const char *domain,
const char *username,
const char *password,
- uint8_t session_key[16])
+ struct creds_CredentialState *creds)
{
NTSTATUS status;
+ struct dcerpc_schannel_state *dce_schan_state;
status = gensec_client_start(p, &p->security_state.generic_state);
if (!NT_STATUS_IS_OK(status)) {
return status;
}
- memcpy(p->security_state.generic_state->user.schan_session_key,
- session_key, 16);
-
status = gensec_set_username(p->security_state.generic_state, username);
if (!NT_STATUS_IS_OK(status)) {
DEBUG(1, ("Failed to set schannel username to %s: %s\n", username, nt_errstr(status)));
@@ -464,6 +448,9 @@ NTSTATUS dcerpc_bind_auth_schannel_withkey(struct dcerpc_pipe *p,
return status;
}
+ dce_schan_state = p->security_state.generic_state->private_data;
+ dce_schan_state->creds = talloc_reference(dce_schan_state, creds);
+
status = dcerpc_bind_auth3(p, DCERPC_AUTH_TYPE_SCHANNEL, dcerpc_auth_level(p),
uuid, version);
@@ -484,7 +471,11 @@ NTSTATUS dcerpc_bind_auth_schannel(struct dcerpc_pipe *p,
{
NTSTATUS status;
int chan_type = 0;
- uint8_t new_session_key[16];
+ struct creds_CredentialState *creds;
+ creds = talloc_p(p, struct creds_CredentialState);
+ if (!creds) {
+ return NT_STATUS_NO_MEMORY;
+ }
if (p->flags & DCERPC_SCHANNEL_BDC) {
chan_type = SEC_CHAN_BDC;
@@ -498,7 +489,7 @@ NTSTATUS dcerpc_bind_auth_schannel(struct dcerpc_pipe *p,
username,
password,
chan_type,
- new_session_key);
+ creds);
if (!NT_STATUS_IS_OK(status)) {
DEBUG(1, ("Failed to fetch schannel session key: %s\n",
@@ -508,7 +499,7 @@ NTSTATUS dcerpc_bind_auth_schannel(struct dcerpc_pipe *p,
return dcerpc_bind_auth_schannel_withkey(p, uuid, version, domain,
username, password,
- new_session_key);
+ creds);
}
static const struct gensec_security_ops gensec_dcerpc_schannel_security_ops = {
diff --git a/source4/rpc_server/netlogon/schannel_state.c b/source4/rpc_server/netlogon/schannel_state.c
index 8797ffa120..61e755bc0f 100644
--- a/source4/rpc_server/netlogon/schannel_state.c
+++ b/source4/rpc_server/netlogon/schannel_state.c
@@ -120,7 +120,7 @@ NTSTATUS schannel_store_session_key(TALLOC_CTX *mem_ctx,
*/
NTSTATUS schannel_fetch_session_key(TALLOC_CTX *mem_ctx,
const char *computer_name,
- struct creds_CredentialState *creds)
+ struct creds_CredentialState **creds)
{
struct ldb_wrap *ldb;
time_t expiry;
@@ -129,7 +129,10 @@ NTSTATUS schannel_fetch_session_key(TALLOC_CTX *mem_ctx,
const struct ldb_val *val;
char *expr=NULL;
- ZERO_STRUCTP(creds);
+ *creds = talloc_zero_p(mem_ctx, struct creds_CredentialState);
+ if (!*creds) {
+ return NT_STATUS_NO_MEMORY;
+ }
ldb = schannel_db_connect(mem_ctx);
if (ldb == NULL) {
@@ -161,7 +164,7 @@ NTSTATUS schannel_fetch_session_key(TALLOC_CTX *mem_ctx,
return NT_STATUS_INVALID_HANDLE;
}
- memcpy(creds->session_key, val->data, 16);
+ memcpy((*creds)->session_key, val->data, 16);
val = ldb_msg_find_ldb_val(res[0], "seed");
if (val == NULL || val->length != 8) {
@@ -169,7 +172,7 @@ NTSTATUS schannel_fetch_session_key(TALLOC_CTX *mem_ctx,
return NT_STATUS_INVALID_HANDLE;
}
- memcpy(creds->seed.data, val->data, 8);
+ memcpy((*creds)->seed.data, val->data, 8);
talloc_free(ldb);
diff --git a/source4/torture/config.mk b/source4/torture/config.mk
index cef76baac4..d939175bb3 100644
--- a/source4/torture/config.mk
+++ b/source4/torture/config.mk
@@ -90,6 +90,7 @@ ADD_OBJ_FILES = \
torture/rpc/schannel.o \
torture/rpc/netlogon.o \
torture/rpc/samlogon.o \
+ torture/rpc/samsync.o \
torture/rpc/bind.o
REQUIRED_SUBSYSTEMS = \
LIBSMB
diff --git a/source4/torture/rpc/netlogon.c b/source4/torture/rpc/netlogon.c
index fe64727d79..9c87106550 100644
--- a/source4/torture/rpc/netlogon.c
+++ b/source4/torture/rpc/netlogon.c
@@ -316,6 +316,72 @@ static BOOL test_SetPassword(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx)
return True;
}
+/*
+ try a netlogon SamLogon
+*/
+static BOOL test_SamLogon(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx)
+{
+ NTSTATUS status;
+ struct netr_LogonSamLogon r;
+ struct netr_Authenticator auth, auth2;
+ 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;
+
+ int i;
+ BOOL ret = True;
+
+ if (!test_SetupCredentials(p, mem_ctx, TEST_MACHINE_NAME,
+ machine_password, &creds)) {
+ return False;
+ }
+
+ ninfo.identity_info.domain_name.string = lp_workgroup();
+ ninfo.identity_info.parameter_control = 0;
+ ninfo.identity_info.logon_id_low = 0;
+ ninfo.identity_info.logon_id_high = 0;
+ ninfo.identity_info.account_name.string = username;
+ ninfo.identity_info.workstation.string = TEST_MACHINE_NAME;
+ generate_random_buffer(ninfo.challenge,
+ sizeof(ninfo.challenge));
+ ninfo.nt.length = 24;
+ ninfo.nt.data = talloc(mem_ctx, 24);
+ SMBNTencrypt(password, ninfo.challenge, ninfo.nt.data);
+ ninfo.lm.length = 24;
+ ninfo.lm.data = talloc(mem_ctx, 24);
+ SMBencrypt(password, ninfo.challenge, ninfo.lm.data);
+
+ r.in.server_name = talloc_asprintf(mem_ctx, "\\\\%s", dcerpc_server_name(p));
+ r.in.workstation = TEST_MACHINE_NAME;
+ r.in.credential = &auth;
+ r.in.return_authenticator = &auth2;
+ r.in.logon_level = 2;
+ r.in.logon.network = &ninfo;
+
+ for (i=2;i<=3;i++) {
+ ZERO_STRUCT(auth2);
+ creds_client_authenticator(&creds, &auth);
+
+ r.in.validation_level = i;
+
+ printf("Testing SamLogon with validation level %d\n", i);
+
+ status = dcerpc_netr_LogonSamLogon(p, mem_ctx, &r);
+ if (!NT_STATUS_IS_OK(status)) {
+ printf("LogonSamLogon - %s\n", nt_errstr(status));
+ ret = False;
+ }
+
+ if (!creds_client_check(&creds, &r.out.return_authenticator->cred)) {
+ printf("Credential chaining failed\n");
+ }
+ }
+
+ return ret;
+}
+
+
/* we remember the sequence numbers so we can easily do a DatabaseDelta */
static uint64_t sequence_nums[3];
@@ -328,7 +394,7 @@ static BOOL test_DatabaseSync(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx)
NTSTATUS status;
struct netr_DatabaseSync r;
struct creds_CredentialState creds;
- const uint32_t database_ids[] = {0, 1, 2};
+ const uint32_t database_ids[] = {SAM_DATABASE_DOMAIN, SAM_DATABASE_BUILTIN, SAM_DATABASE_PRIVS};
int i;
BOOL ret = True;
@@ -366,7 +432,7 @@ static BOOL test_DatabaseSync(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx)
if (r.out.delta_enum_array &&
r.out.delta_enum_array->num_deltas > 0 &&
- r.out.delta_enum_array->delta_enum[0].delta_type == 1 &&
+ r.out.delta_enum_array->delta_enum[0].delta_type == NETR_DELTA_DOMAIN &&
r.out.delta_enum_array->delta_enum[0].delta_union.domain) {
sequence_nums[r.in.database_id] =
r.out.delta_enum_array->delta_enum[0].delta_union.domain->sequence_num;
@@ -969,7 +1035,7 @@ BOOL torture_rpc_netlogon(void)
struct dcerpc_pipe *p;
TALLOC_CTX *mem_ctx;
BOOL ret = True;
- void *join_ctx;
+ struct test_join *join_ctx;
mem_ctx = talloc_init("torture_rpc_netlogon");
@@ -996,6 +1062,10 @@ BOOL torture_rpc_netlogon(void)
ret = False;
}
+ if (!test_SamLogon(p, mem_ctx)) {
+ ret = False;
+ }
+
if (!test_SetPassword(p, mem_ctx)) {
ret = False;
}
diff --git a/source4/torture/rpc/schannel.c b/source4/torture/rpc/schannel.c
index 323adde534..7a9786fa2d 100644
--- a/source4/torture/rpc/schannel.c
+++ b/source4/torture/rpc/schannel.c
@@ -53,6 +53,63 @@ static BOOL test_samr_ops(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx)
return True;
}
+
+/*
+ try a netlogon SamLogon
+*/
+static BOOL test_netlogon_ops(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx,
+ struct creds_CredentialState *creds)
+{
+ NTSTATUS status;
+ struct netr_LogonSamLogon r;
+ struct netr_Authenticator auth, auth2;
+ struct netr_NetworkInfo ninfo;
+ const char *username = lp_parm_string(-1, "torture", "username");
+ const char *password = lp_parm_string(-1, "torture", "password");
+
+ int i;
+ BOOL ret = True;
+
+ ninfo.identity_info.domain_name.string = lp_workgroup();
+ ninfo.identity_info.parameter_control = 0;
+ ninfo.identity_info.logon_id_low = 0;
+ ninfo.identity_info.logon_id_high = 0;
+ ninfo.identity_info.account_name.string = username;
+ ninfo.identity_info.workstation.string = TEST_MACHINE_NAME;
+ generate_random_buffer(ninfo.challenge,
+ sizeof(ninfo.challenge));
+ ninfo.nt.length = 24;
+ ninfo.nt.data = talloc(mem_ctx, 24);
+ SMBNTencrypt(password, ninfo.challenge, ninfo.nt.data);
+ ninfo.lm.length = 24;
+ ninfo.lm.data = talloc(mem_ctx, 24);
+ SMBencrypt(password, ninfo.challenge, ninfo.lm.data);
+
+
+ r.in.server_name = talloc_asprintf(mem_ctx, "\\\\%s", dcerpc_server_name(p));
+ r.in.workstation = TEST_MACHINE_NAME;
+ r.in.credential = &auth;
+ r.in.return_authenticator = &auth2;
+ r.in.logon_level = 2;
+ r.in.logon.network = &ninfo;
+
+ for (i=2;i<3;i++) {
+ ZERO_STRUCT(auth2);
+ creds_client_authenticator(creds, &auth);
+
+ r.in.validation_level = i;
+
+ status = dcerpc_netr_LogonSamLogon(p, mem_ctx, &r);
+
+ if (!creds_client_check(creds, &r.out.return_authenticator->cred)) {
+ printf("Credential chaining failed\n");
+ ret = False;
+ }
+
+ }
+ return ret;
+}
+
/*
test a schannel connection with the given flags
*/
@@ -66,6 +123,8 @@ static BOOL test_schannel(TALLOC_CTX *mem_ctx,
const char *binding = lp_parm_string(-1, "torture", "binding");
struct dcerpc_binding b;
struct dcerpc_pipe *p;
+ struct dcerpc_pipe *p_netlogon;
+ struct creds_CredentialState *creds;
join_ctx = torture_join_domain(TEST_MACHINE_NAME, lp_workgroup(), acct_flags,
&machine_password);
@@ -99,12 +158,51 @@ static BOOL test_schannel(TALLOC_CTX *mem_ctx,
goto failed;
}
+
+ status = dcerpc_parse_binding(mem_ctx, binding, &b);
+ 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;
+
+ status = dcerpc_pipe_connect_b(&p_netlogon, &b,
+ DCERPC_NETLOGON_UUID,
+ DCERPC_NETLOGON_VERSION,
+ lp_workgroup(),
+ TEST_MACHINE_NAME,
+ machine_password);
+
+ if (!NT_STATUS_IS_OK(status)) {
+ goto failed;
+ }
+
+ status = dcerpc_schannel_creds(p_netlogon->security_state.generic_state, mem_ctx, &creds);
+ if (!NT_STATUS_IS_OK(status)) {
+ goto failed;
+ }
+
+ /* do a couple of logins */
+ if (!test_netlogon_ops(p_netlogon, mem_ctx, creds)) {
+ printf("Failed to process schannel secured ops\n");
+ goto failed;
+ }
+
torture_leave_domain(join_ctx);
+ dcerpc_pipe_close(p_netlogon);
dcerpc_pipe_close(p);
return True;
failed:
torture_leave_domain(join_ctx);
+ dcerpc_pipe_close(p_netlogon);
dcerpc_pipe_close(p);
return False;
}
diff --git a/source4/torture/rpc/xplogin.c b/source4/torture/rpc/xplogin.c
index a3cca7003c..e0bb706255 100644
--- a/source4/torture/rpc/xplogin.c
+++ b/source4/torture/rpc/xplogin.c
@@ -1021,7 +1021,7 @@ static BOOL xp_login(const char *dcname, const char *wksname,
struct smbcli_transport *transport;
struct dcerpc_pipe *netlogon_pipe;
- struct creds_CredentialState netlogon_creds;
+ struct creds_CredentialState *netlogon_creds;
struct dcerpc_pipe *netlogon_schannel_pipe;
@@ -1032,13 +1032,18 @@ static BOOL xp_login(const char *dcname, const char *wksname,
if (mem_ctx == NULL)
return False;
+ netlogon_creds = talloc_p(mem_ctx, struct creds_CredentialState);
+ if (!netlogon_creds) {
+ return False;
+ }
+
if (!NT_STATUS_IS_OK(after_negprot(&transport, dcname, 139,
wksname)))
return False;
if (!NT_STATUS_IS_OK(setup_netlogon_creds(transport, &netlogon_pipe,
wksname, domain, wkspwd,
- &netlogon_creds)))
+ netlogon_creds)))
return False;
if (!NT_STATUS_IS_OK(test_enumtrusts(transport)))
@@ -1063,13 +1068,13 @@ static BOOL xp_login(const char *dcname, const char *wksname,
DCERPC_NETLOGON_UUID,
DCERPC_NETLOGON_VERSION,
"", "", "",
- netlogon_creds.session_key);
+ netlogon_creds);
if (!NT_STATUS_IS_OK(status))
return False;
status = torture_samlogon(netlogon_schannel_pipe,
- &netlogon_creds, wksname, domain,
+ netlogon_creds, wksname, domain,
user1name, user1pw);
if (!NT_STATUS_IS_OK(status))
@@ -1078,7 +1083,7 @@ static BOOL xp_login(const char *dcname, const char *wksname,
talloc_free(netlogon_pipe);
status = torture_samlogon(netlogon_schannel_pipe,
- &netlogon_creds, wksname, domain,
+ netlogon_creds, wksname, domain,
user2name, user2pw);
if (!NT_STATUS_IS_OK(status))
diff --git a/source4/torture/torture.c b/source4/torture/torture.c
index 975b83e6ad..4db4662f6c 100644
--- a/source4/torture/torture.c
+++ b/source4/torture/torture.c
@@ -2439,6 +2439,7 @@ static struct {
{"RPC-SAMR", torture_rpc_samr, 0},
{"RPC-NETLOGON", torture_rpc_netlogon, 0},
{"RPC-SAMLOGON", torture_rpc_samlogon, 0},
+ {"RPC-SAMSYNC", torture_rpc_samsync, 0},
{"RPC-SCHANNEL", torture_rpc_schannel, 0},
{"RPC-WKSSVC", torture_rpc_wkssvc, 0},
{"RPC-SRVSVC", torture_rpc_srvsvc, 0},