summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--source4/libcli/util/dom_sid.c33
-rw-r--r--source4/librpc/idl/netlogon.idl26
-rw-r--r--source4/rpc_server/netlogon/dcerpc_netlogon.c185
-rw-r--r--source4/torture/rpc/netlogon.c56
4 files changed, 217 insertions, 83 deletions
diff --git a/source4/libcli/util/dom_sid.c b/source4/libcli/util/dom_sid.c
index cdf89ccf96..9b8b45e302 100644
--- a/source4/libcli/util/dom_sid.c
+++ b/source4/libcli/util/dom_sid.c
@@ -89,3 +89,36 @@ struct dom_sid *dom_sid_parse_talloc(TALLOC_CTX *mem_ctx, const char *sidstr)
return ret;
}
+/*
+ convert a string to a dom_sid, returning a talloc'd dom_sid
+*/
+struct dom_sid *dom_sid_dup(TALLOC_CTX *mem_ctx, struct dom_sid *dom_sid)
+{
+ struct dom_sid *ret;
+ int i;
+ ret = talloc_p(mem_ctx, struct dom_sid);
+ if (!ret) {
+ return NULL;
+ }
+
+ ret->sub_auths = talloc_array_p(mem_ctx, uint32_t, dom_sid->num_auths);
+ if (!ret->sub_auths) {
+ return NULL;
+ }
+
+ ret->sid_rev_num = dom_sid->sid_rev_num;
+ ret->id_auth[0] = dom_sid->id_auth[0];
+ ret->id_auth[1] = dom_sid->id_auth[1];
+ ret->id_auth[2] = dom_sid->id_auth[2];
+ ret->id_auth[3] = dom_sid->id_auth[3];
+ ret->id_auth[4] = dom_sid->id_auth[4];
+ ret->id_auth[5] = dom_sid->id_auth[5];
+ ret->num_auths = dom_sid->num_auths;
+
+ for (i=0;i<dom_sid->num_auths;i++) {
+ ret->sub_auths[i] = dom_sid->sub_auths[i];
+ }
+
+ return ret;
+}
+
diff --git a/source4/librpc/idl/netlogon.idl b/source4/librpc/idl/netlogon.idl
index a3e1e804dc..48154dc001 100644
--- a/source4/librpc/idl/netlogon.idl
+++ b/source4/librpc/idl/netlogon.idl
@@ -171,8 +171,14 @@ interface netlogon
dom_sid2 *domain_sid;
netr_LMSessionKey LMSessKey;
uint32 AccountControl;
- uint32 expansionroom[7];
- } netr_SamInfo;
+ uint32 unknown1;
+ uint32 unknown2;
+ uint32 unknown3;
+ uint32 unknown4;
+ uint32 unknown5;
+ uint32 unknown6;
+ uint32 unknown7;
+ } netr_SamInfo2;
typedef struct {
dom_sid2 *sid;
@@ -205,10 +211,16 @@ interface netlogon
dom_sid2 *domain_sid;
netr_LMSessionKey LMSessKey;
uint32 AccountControl;
- uint32 expansionroom[7];
+ uint32 unknown1;
+ uint32 unknown2;
+ uint32 unknown3;
+ uint32 unknown4;
+ uint32 unknown5;
+ uint32 unknown6;
+ uint32 unknown7;
uint32 sidcount;
[size_is(sidcount)] netr_SidAttr *sids;
- } netr_SamInfo2;
+ } netr_SamInfo3;
typedef struct {
uint32 pac_size;
@@ -227,8 +239,8 @@ interface netlogon
} netr_PacInfo;
typedef union {
- [case(2)] netr_SamInfo *sam;
- [case(3)] netr_SamInfo2 *sam2;
+ [case(2)] netr_SamInfo2 *sam2;
+ [case(3)] netr_SamInfo3 *sam3;
[case(4)] netr_PacInfo *pac;
[case(5)] netr_PacInfo *pac2;
} netr_Validation;
@@ -237,7 +249,7 @@ interface netlogon
[in] unistr *server_name,
[in] unistr *workstation,
[in] netr_Authenticator *credential,
- [in][out] netr_Authenticator *authenticator,
+ [in][out] netr_Authenticator *return_authenticator,
[in] uint16 logon_level,
[in] [switch_is(logon_level)] netr_LogonLevel logon,
[in] uint16 validation_level,
diff --git a/source4/rpc_server/netlogon/dcerpc_netlogon.c b/source4/rpc_server/netlogon/dcerpc_netlogon.c
index bfc5e3b759..933f28d84a 100644
--- a/source4/rpc_server/netlogon/dcerpc_netlogon.c
+++ b/source4/rpc_server/netlogon/dcerpc_netlogon.c
@@ -228,7 +228,6 @@ static NTSTATUS netr_ServerAuthenticate3(struct dcesrv_call_state *dce_call, TAL
return nt_status;
}
-
static NTSTATUS netr_ServerAuthenticate(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
struct netr_ServerAuthenticate *r)
{
@@ -302,12 +301,12 @@ static NTSTATUS netr_ServerPasswordSet(struct dcesrv_call_state *dce_call, TALLO
const char **domain_attrs = attrs;
ZERO_STRUCT(mod);
- if (!netr_creds_server_step_check(pipe_state, &r->in.credential, &r->out.return_authenticator)) {
+ if (!pipe_state) {
+ DEBUG(1, ("No challenge requested by client, cannot authenticate\n"));
return NT_STATUS_ACCESS_DENIED;
}
- if (!pipe_state) {
- DEBUG(1, ("No challenge requested by client, cannot authenticate\n"));
+ if (!netr_creds_server_step_check(pipe_state, &r->in.credential, &r->out.return_authenticator)) {
return NT_STATUS_ACCESS_DENIED;
}
@@ -426,8 +425,6 @@ static WERROR netr_LogonUasLogoff(struct dcesrv_call_state *dce_call, TALLOC_CTX
*/
-#if 0
-
static NTSTATUS netr_LogonSamLogon(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
struct netr_LogonSamLogon *r)
{
@@ -438,8 +435,24 @@ static NTSTATUS netr_LogonSamLogon(struct dcesrv_call_state *dce_call, TALLOC_CT
struct auth_serversupplied_info *server_info;
NTSTATUS nt_status;
const uint8_t *chal;
+ static const char zeros[16];
+ struct netr_SamInfo2 *sam2;
+ struct netr_SamInfo3 *sam;
-
+ if (!pipe_state) {
+ DEBUG(1, ("No challenge requested by client, cannot authenticate\n"));
+ return NT_STATUS_ACCESS_DENIED;
+ }
+
+ r->out.return_authenticator = talloc_p(mem_ctx, struct netr_Authenticator);
+ if (!r->out.return_authenticator) {
+ return NT_STATUS_NO_MEMORY;
+ }
+
+ if (!netr_creds_server_step_check(pipe_state, r->in.credential, r->out.return_authenticator)) {
+ return NT_STATUS_ACCESS_DENIED;
+ }
+
switch (r->in.logon_level) {
case 1:
case 3:
@@ -476,8 +489,8 @@ static NTSTATUS netr_LogonSamLogon(struct dcesrv_call_state *dce_call, TALLOC_CT
r->in.logon.network->identity_info.account_name.string,
r->in.logon.network->identity_info.domain_name.string,
r->in.logon.network->identity_info.workstation.string,
- r->in.logon.network->nt.data, r->in.logon.network->nt.length,
- r->in.logon.network->lm.data, r->in.logon.network->lm.length);
+ r->in.logon.network->lm.data, r->in.logon.network->lm.length,
+ r->in.logon.network->nt.data, r->in.logon.network->nt.length);
break;
default:
free_auth_context(&auth_context);
@@ -498,48 +511,127 @@ static NTSTATUS netr_LogonSamLogon(struct dcesrv_call_state *dce_call, TALLOC_CT
}
free_auth_context(&auth_context);
+ sam = talloc_p(mem_ctx, struct netr_SamInfo3);
+
+ sam->last_logon = server_info->last_logon;
+ sam->last_logoff = server_info->last_logoff;
+ sam->acct_expiry = server_info->acct_expiry;
+ sam->last_password_change = server_info->last_password_change;
+ sam->allow_password_change = server_info->allow_password_change;
+ sam->force_password_change = server_info->force_password_change;
+
+ sam->account_name.string = talloc_strdup(mem_ctx, server_info->account_name);
+ sam->full_name.string = talloc_strdup(mem_ctx, server_info->full_name);
+ sam->logon_script.string = talloc_strdup(mem_ctx, server_info->account_name);
+ sam->profile_path.string = talloc_strdup(mem_ctx, server_info->profile_path);
+ sam->home_directory.string = talloc_strdup(mem_ctx, server_info->home_directory);
+ sam->home_drive.string = talloc_strdup(mem_ctx, server_info->home_drive);
+
+ sam->logon_count = server_info->logon_count;
+ sam->bad_password_count = sam->bad_password_count;
+ sam->rid = server_info->user_sid->sub_auths[server_info->user_sid->num_auths-1];
+ sam->primary_gid = server_info->primary_group_sid->sub_auths[server_info->primary_group_sid->num_auths-1];
+ sam->group_count = 0;
+ sam->groupids = NULL;
+
+ sam->acct_flags = server_info->acct_flags;
+
+ sam->logon_server.string = lp_netbios_name();
+
+ sam->domain.string = talloc_strdup(mem_ctx, server_info->domain);
+
+ sam->domain_sid = dom_sid_dup(mem_ctx, server_info->user_sid);
+ sam->domain_sid->num_auths--;
+
+ sam->sidcount = 0;
+ sam->sids = NULL;
+
+ if (server_info->user_session_key.length == sizeof(sam->key.key)) {
+ memcpy(sam->key.key, server_info->user_session_key.data, sizeof(sam->key.key));
+ } else {
+ ZERO_STRUCT(sam->key.key);
+ }
+
+ if (memcmp(sam->key.key, zeros,
+ sizeof(sam->key.key)) != 0) {
+ /* Don't crypt an all-zero key, it would give away the NETLOGON pipe session key */
+ creds_arcfour_crypt(pipe_state->creds,
+ sam->key.key,
+ sizeof(sam->key.key));
+ }
+
+ if (server_info->lm_session_key.length == sizeof(sam->LMSessKey.key)) {
+ memcpy(sam->LMSessKey.key, server_info->lm_session_key.data,
+ sizeof(sam->LMSessKey.key));
+ } else {
+ ZERO_STRUCT(sam->LMSessKey.key);
+ }
+
+ if (memcmp(sam->LMSessKey.key, zeros,
+ sizeof(sam->LMSessKey.key)) != 0) {
+ creds_arcfour_crypt(pipe_state->creds,
+ sam->LMSessKey.key,
+ sizeof(sam->LMSessKey.key));
+ }
+
switch (r->in.validation_level) {
case 2:
{
- struct netr_SamInfo *sam;
- sam = talloc_p(mem_ctx, struct netr_SamInfo);
- r->out.validation.sam = sam;
-
- sam->last_logon = server_info->last_logon;
- sam->last_logoff = server_info->last_logoff;
- sam->acct_expiry = server_info->acct_expiry;
- sam->last_password_change = server_info->last_password_change;
- sam->allow_password_change = server_info->allow_password_change;
- sam->force_password_change = server_info->force_password_change;
-
- sam->account_name.string = talloc_strdup(mem_ctx, server_info->account_name);
- sam->full_name.string = talloc_strdup(mem_ctx, server_info->full_name);
- sam->logon_script.string = talloc_strdup(mem_ctx, server_info->account_name);
- sam->profile_path.string = talloc_strdup(mem_ctx, server_info->profile_path);
- sam->home_directory.string = talloc_strdup(mem_ctx, server_info->home_directory);
- sam->home_drive.string = talloc_strdup(mem_ctx, server_info->home_drive);
-
- sam->logon_count = server_info->logon_count;
- sam->bad_password_count = sam->bad_password_count;
- sam->rid = server_info->user_sid->sub_auths[server_info->user_sid->num_auths-1];
- sam->primary_gid = server_info->primary_group_sid->sub_auths[server_info->primary_group_sid->num_auths-1];
- sam->group_count = 0;
- sam->groupids = NULL;
-
- sam->acct_flags = server_info->acct_flags;
-
- sam->domain.string = talloc_strdup(mem_ctx, server_info->domain);
-
- /* need to finish */
+ sam2 = talloc_p(mem_ctx, struct netr_SamInfo2);
+ r->out.validation.sam2 = sam2;
+ sam2->last_logon = sam->last_logon;
+ sam2->last_logoff = sam->last_logoff;
+ sam2->acct_expiry = sam->acct_expiry;
+
+ sam2->last_password_change = sam->last_password_change;
+ sam2->allow_password_change = sam->allow_password_change;
+
+ sam2->force_password_change = sam->force_password_change;
+
+
+ sam2->account_name = sam->account_name;
+ sam2->full_name = sam->full_name;
+ sam2->logon_script = sam->logon_script;
+ sam2->profile_path = sam->profile_path;
+ sam2->home_directory = sam->home_directory;
+ sam2->home_drive = sam->home_drive;
+
+ sam2->logon_count = sam->logon_count;
+ sam2->bad_password_count = sam->bad_password_count;
+ sam2->rid = sam->rid;
+ sam2->primary_gid = sam->primary_gid;
+ sam2->group_count = sam->group_count;
+ sam2->groupids = sam->groupids;
+
+ sam2->acct_flags = sam->acct_flags;
+
+ sam2->key = sam->key;
+
+ sam2->logon_server = sam->logon_server;
+
+ sam2->domain = sam->domain;
+
+ sam2->domain_sid = sam->domain_sid;
+
+ sam2->LMSessKey = sam->LMSessKey;
+
+ sam2->AccountControl = sam->AccountControl;
+
+ /* can we implicit memcpy an array? */
+
+ sam2->unknown1 = sam->unknown1;
+ sam2->unknown2 = sam->unknown2;
+ sam2->unknown3 = sam->unknown3;
+ sam2->unknown4 = sam->unknown4;
+ sam2->unknown5 = sam->unknown5;
+ sam2->unknown6 = sam->unknown6;
+ sam2->unknown7 = sam->unknown7;
break;
}
case 3:
{
- struct netr_SamInfo2 *sam;
- sam = talloc_p(mem_ctx, struct netr_SamInfo2);
- r->out.validation.sam2 = sam;
-
+ r->out.validation.sam3 = sam;
break;
}
default:
@@ -550,13 +642,6 @@ static NTSTATUS netr_LogonSamLogon(struct dcesrv_call_state *dce_call, TALLOC_CT
return NT_STATUS_OK;
}
-#else
-static NTSTATUS netr_LogonSamLogon(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
- struct netr_LogonSamLogon *r)
-{
- DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
-}
-#endif
/*
netr_LogonSamLogoff
diff --git a/source4/torture/rpc/netlogon.c b/source4/torture/rpc/netlogon.c
index a0b49d91eb..a336ef7acb 100644
--- a/source4/torture/rpc/netlogon.c
+++ b/source4/torture/rpc/netlogon.c
@@ -355,7 +355,7 @@ static NTSTATUS check_samlogon(struct samlogon_state *samlogon_state,
ZERO_STRUCT(samlogon_state->auth2);
creds_client_authenticator(&samlogon_state->creds, &samlogon_state->auth);
- r->out.authenticator = NULL;
+ r->out.return_authenticator = NULL;
status = dcerpc_netr_LogonSamLogon(samlogon_state->p, samlogon_state->mem_ctx, r);
if (!NT_STATUS_IS_OK(status)) {
if (error_string) {
@@ -363,8 +363,8 @@ static NTSTATUS check_samlogon(struct samlogon_state *samlogon_state,
}
}
- if (!r->out.authenticator ||
- !creds_client_check(&samlogon_state->creds, &r->out.authenticator->cred)) {
+ if (!r->out.return_authenticator ||
+ !creds_client_check(&samlogon_state->creds, &r->out.return_authenticator->cred)) {
printf("Credential chaining failed\n");
}
@@ -377,30 +377,19 @@ static NTSTATUS check_samlogon(struct samlogon_state *samlogon_state,
if (r->in.validation_level == 2) {
static const char zeros[16];
- if (memcmp(r->out.validation.sam->LMSessKey.key, zeros,
- sizeof(r->out.validation.sam->LMSessKey.key)) != 0) {
+ if (memcmp(r->out.validation.sam2->key.key, zeros,
+ sizeof(r->out.validation.sam2->key.key)) != 0) {
creds_arcfour_crypt(&samlogon_state->creds,
- r->out.validation.sam->LMSessKey.key,
- sizeof(r->out.validation.sam->LMSessKey.key));
- }
-
- if (lm_key) {
- memcpy(lm_key, r->out.validation.sam->LMSessKey.key, 8);
- }
-
- if (memcmp(r->out.validation.sam->key.key, zeros, sizeof(r->out.validation.sam->key.key)) != 0) {
- creds_arcfour_crypt(&samlogon_state->creds,
- r->out.validation.sam->key.key,
- sizeof(r->out.validation.sam->key.key));
+ r->out.validation.sam2->key.key,
+ sizeof(r->out.validation.sam2->key.key));
}
if (user_session_key) {
- memcpy(user_session_key, r->out.validation.sam->key.key, 16);
+ memcpy(user_session_key, r->out.validation.sam2->key.key, 16);
}
- } else if (r->in.validation_level == 3) {
- static const char zeros[16];
- if (memcmp(r->out.validation.sam2->LMSessKey.key, zeros, sizeof(r->out.validation.sam2->LMSessKey.key)) != 0) {
+ if (memcmp(r->out.validation.sam2->LMSessKey.key, zeros,
+ sizeof(r->out.validation.sam2->LMSessKey.key)) != 0) {
creds_arcfour_crypt(&samlogon_state->creds,
r->out.validation.sam2->LMSessKey.key,
sizeof(r->out.validation.sam2->LMSessKey.key));
@@ -410,15 +399,30 @@ static NTSTATUS check_samlogon(struct samlogon_state *samlogon_state,
memcpy(lm_key, r->out.validation.sam2->LMSessKey.key, 8);
}
- if (memcmp(r->out.validation.sam2->key.key, zeros, sizeof(r->out.validation.sam2->key.key)) != 0) {
+ } else if (r->in.validation_level == 3) {
+ static const char zeros[16];
+ if (memcmp(r->out.validation.sam3->key.key, zeros,
+ sizeof(r->out.validation.sam3->key.key)) != 0) {
creds_arcfour_crypt(&samlogon_state->creds,
- r->out.validation.sam2->key.key,
- sizeof(r->out.validation.sam2->key.key));
+ r->out.validation.sam3->key.key,
+ sizeof(r->out.validation.sam3->key.key));
}
if (user_session_key) {
- memcpy(user_session_key, r->out.validation.sam2->key.key, 16);
+ memcpy(user_session_key, r->out.validation.sam3->key.key, 16);
}
+
+ if (memcmp(r->out.validation.sam3->LMSessKey.key, zeros,
+ sizeof(r->out.validation.sam3->LMSessKey.key)) != 0) {
+ creds_arcfour_crypt(&samlogon_state->creds,
+ r->out.validation.sam3->LMSessKey.key,
+ sizeof(r->out.validation.sam3->LMSessKey.key));
+ }
+
+ if (lm_key) {
+ memcpy(lm_key, r->out.validation.sam3->LMSessKey.key, 8);
+ }
+
}
}
@@ -912,7 +916,7 @@ static BOOL test_SamLogon(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx)
samlogon_state.r.in.server_name = talloc_asprintf(mem_ctx, "\\\\%s", dcerpc_server_name(p));
samlogon_state.r.in.workstation = TEST_MACHINE_NAME;
samlogon_state.r.in.credential = &samlogon_state.auth;
- samlogon_state.r.in.authenticator = &samlogon_state.auth2;
+ samlogon_state.r.in.return_authenticator = &samlogon_state.auth2;
for (i=2;i<=3;i++) {
samlogon_state.r.in.validation_level = i;