summaryrefslogtreecommitdiff
path: root/source4/librpc
diff options
context:
space:
mode:
authorAndrew Bartlett <abartlet@samba.org>2004-11-11 23:24:30 +0000
committerGerald (Jerry) Carter <jerry@samba.org>2007-10-10 13:05:43 -0500
commitfd5135a63b4c81688c4e2d729380ca954f22286d (patch)
tree7179bf31f404359a702f94ed5db03a1a4732617c /source4/librpc
parent32e368502d80517dd7b00c1c3bc8b042887d9db0 (diff)
downloadsamba-fd5135a63b4c81688c4e2d729380ca954f22286d.tar.gz
samba-fd5135a63b4c81688c4e2d729380ca954f22286d.tar.bz2
samba-fd5135a63b4c81688c4e2d729380ca954f22286d.zip
r3686: The results of some work on the NETLOGON pipe:
Break out the samsync tests from RPC-NETLOGON into a new RPC-SAMSYNC, that will cross-verify all the values. Add support for the way netlogon credentials are shared between the pipe that sets up schannel and the pipe that is encrypted with it. Test this support, by calling both NETLOGON and SAMR operations in the RPC-SCHANNEL test. Move some of the Netlogon NEG flags into the .idl, now we have an idea what a few of them really are. Rename the sam_pwd_hash into a name that has meaning (all other crypto functions were renamed in Samba4 ages ago). Break out NTLMv2 functionality for operation on the NT hash - I intend to do NTLMv2 logins in the samsync test in future, and naturally I only have the hash. Andrew Bartlett (This used to be commit 6e6cc6fb9842113a1b0c7f6904dac709b320a6e5)
Diffstat (limited to 'source4/librpc')
-rw-r--r--source4/librpc/idl/netlogon.idl32
-rw-r--r--source4/librpc/rpc/dcerpc_schannel.c67
2 files changed, 51 insertions, 48 deletions
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 = {