summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrew Bartlett <abartlet@samba.org>2005-10-24 07:11:40 +0000
committerGerald (Jerry) Carter <jerry@samba.org>2007-10-10 13:45:11 -0500
commita0647a89a82e892292c421f5c968de2f28d42366 (patch)
tree0a8bcddc8318b50900c4f84719762f609bb38268
parentca40d0a6fea0dbf2a9962ed125f420bea3ca0269 (diff)
downloadsamba-a0647a89a82e892292c421f5c968de2f28d42366.tar.gz
samba-a0647a89a82e892292c421f5c968de2f28d42366.tar.bz2
samba-a0647a89a82e892292c421f5c968de2f28d42366.zip
r11272: In trying to track down why Win2k3 is again rejecting our PAC, ensure
we can round-trip all the way back to a server_info structure, not just a filled in PAC_DATA. (I was worried about generated fields being incorrect, or some other logical flaw). Andrew Bartlett (This used to be commit 11b1d78cc550c60201d12f8778ca8533712a5b1e)
-rw-r--r--source4/auth/auth.h1
-rw-r--r--source4/auth/auth_sam_reply.c120
-rw-r--r--source4/auth/auth_util.c1
-rw-r--r--source4/auth/kerberos/kerberos_pac.c2
-rw-r--r--source4/torture/auth/pac.c81
5 files changed, 114 insertions, 91 deletions
diff --git a/source4/auth/auth.h b/source4/auth/auth.h
index 0b12328b3c..392703729f 100644
--- a/source4/auth/auth.h
+++ b/source4/auth/auth.h
@@ -94,6 +94,7 @@ struct auth_serversupplied_info
const char *profile_path;
const char *home_directory;
const char *home_drive;
+ const char *logon_server;
NTTIME last_logon;
NTTIME last_logoff;
diff --git a/source4/auth/auth_sam_reply.c b/source4/auth/auth_sam_reply.c
index 85a54979ce..2918dfd499 100644
--- a/source4/auth/auth_sam_reply.c
+++ b/source4/auth/auth_sam_reply.c
@@ -36,6 +36,10 @@ NTSTATUS auth_convert_server_info_sambaseinfo(TALLOC_CTX *mem_ctx,
struct netr_SamBaseInfo *sam = talloc_zero(mem_ctx, struct netr_SamBaseInfo);
NT_STATUS_HAVE_NO_MEMORY(sam);
+ sam->domain_sid = dom_sid_dup(mem_ctx, server_info->account_sid);
+ NT_STATUS_HAVE_NO_MEMORY(sam->domain_sid);
+ sam->domain_sid->num_auths--;
+
sam->last_logon = server_info->last_logon;
sam->last_logoff = server_info->last_logoff;
sam->acct_expiry = server_info->acct_expiry;
@@ -67,8 +71,11 @@ NTSTATUS auth_convert_server_info_sambaseinfo(TALLOC_CTX *mem_ctx,
return NT_STATUS_NO_MEMORY;
for (i=0; i<server_info->n_domain_groups; i++) {
-
struct dom_sid *group_sid = server_info->domain_groups[i];
+ if (!dom_sid_in_domain(sam->domain_sid, group_sid)) {
+ /* We handle this elsewhere */
+ continue;
+ }
sam->groups.rids[sam->groups.count].rid =
group_sid->sub_auths[group_sid->num_auths-1];
@@ -82,13 +89,9 @@ NTSTATUS auth_convert_server_info_sambaseinfo(TALLOC_CTX *mem_ctx,
* as extra sids (PAC doc) but what is
* 0x100? */
sam->acct_flags = server_info->acct_flags;
- sam->logon_server.string = lp_netbios_name();
+ sam->logon_server.string = server_info->logon_server;
sam->domain.string = server_info->domain_name;
- sam->domain_sid = dom_sid_dup(mem_ctx, server_info->account_sid);
- NT_STATUS_HAVE_NO_MEMORY(sam->domain_sid);
- sam->domain_sid->num_auths--;
-
ZERO_STRUCT(sam->unknown);
ZERO_STRUCT(sam->key);
@@ -113,96 +116,37 @@ NTSTATUS auth_convert_server_info_saminfo3(TALLOC_CTX *mem_ctx,
{
struct netr_SamBaseInfo *sam;
struct netr_SamInfo3 *sam3 = talloc_zero(mem_ctx, struct netr_SamInfo3);
+ NTSTATUS status;
+ int i;
NT_STATUS_HAVE_NO_MEMORY(sam3);
- sam = &sam3->base;
-
- sam->domain_sid = dom_sid_dup(mem_ctx, server_info->account_sid);
- NT_STATUS_HAVE_NO_MEMORY(sam->domain_sid);
- sam->domain_sid->num_auths--;
-
- 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 = server_info->account_name;
- sam->full_name.string = server_info->full_name;
- sam->logon_script.string = server_info->logon_script;
- sam->profile_path.string = server_info->profile_path;
- sam->home_directory.string = server_info->home_directory;
- sam->home_drive.string = server_info->home_drive;
-
- sam->logon_count = server_info->logon_count;
- sam->bad_password_count = sam->bad_password_count;
- sam->rid = server_info->account_sid->sub_auths[server_info->account_sid->num_auths-1];
- sam->primary_gid = server_info->primary_group_sid->sub_auths[server_info->primary_group_sid->num_auths-1];
-
- sam->groups.count = 0;
- sam->groups.rids = NULL;
-
- if (server_info->n_domain_groups > 0) {
- int i;
- sam->groups.rids = talloc_array(sam, struct samr_RidWithAttribute,
- server_info->n_domain_groups);
- NT_STATUS_HAVE_NO_MEMORY(sam->groups.rids);
-
- for (i=0; i<server_info->n_domain_groups; i++) {
- struct dom_sid *group_sid = server_info->domain_groups[i];
-
- if (!dom_sid_in_domain(sam->domain_sid, group_sid)) {
- continue;
- }
-
- sam->groups.rids[sam->groups.count].rid = group_sid->sub_auths[group_sid->num_auths-1];
- sam->groups.rids[sam->groups.count].attributes =
- SE_GROUP_MANDATORY | SE_GROUP_ENABLED_BY_DEFAULT | SE_GROUP_ENABLED;
- sam->groups.count += 1;
- }
+ status = auth_convert_server_info_sambaseinfo(mem_ctx, server_info, &sam);
+ if (!NT_STATUS_IS_OK(status)) {
+ return status;
}
-
- sam->user_flags = 0x20; /* TODO: w2k3 uses 0x120. We know 0x20
- * as extra sids (PAC doc) but what is
- * 0x100? */
- sam->acct_flags = server_info->acct_flags;
- sam->logon_server.string = lp_netbios_name();
- sam->domain.string = server_info->domain_name;
-
- ZERO_STRUCT(sam->unknown);
-
- ZERO_STRUCT(sam->key);
- 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));
- }
-
- ZERO_STRUCT(sam->LMSessKey);
- 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));
- }
-
+ sam3->base = *sam;
sam3->sidcount = 0;
sam3->sids = NULL;
-#if 0
- if (server_info->n_domain_groups > 0) {
- int i;
- sam3->sids = talloc_array(sam, struct netr_SidAttr,
- server_info->n_domain_groups);
- NT_STATUS_HAVE_NO_MEMORY(sam3->sids);
- for (i=0; i<server_info->n_domain_groups; i++) {
- if (dom_sid_in_domain(sam->domain_sid, server_info->domain_groups[i])) {
- continue;
- }
- sam3->sids[sam3->sidcount].sid = talloc_reference(sam3->sids,server_info->domain_groups[i]);
- sam3->sids[sam3->sidcount].attribute =
- SE_GROUP_MANDATORY | SE_GROUP_ENABLED_BY_DEFAULT | SE_GROUP_ENABLED;
- sam3->sidcount += 1;
+
+ sam3->sids = talloc_array(sam, struct netr_SidAttr,
+ server_info->n_domain_groups);
+ NT_STATUS_HAVE_NO_MEMORY(sam3->sids);
+
+ for (i=0; i<server_info->n_domain_groups; i++) {
+ if (dom_sid_in_domain(sam->domain_sid, server_info->domain_groups[i])) {
+ continue;
}
+ sam3->sids[sam3->sidcount].sid = talloc_reference(sam3->sids,server_info->domain_groups[i]);
+ sam3->sids[sam3->sidcount].attribute =
+ SE_GROUP_MANDATORY | SE_GROUP_ENABLED_BY_DEFAULT | SE_GROUP_ENABLED;
+ sam3->sidcount += 1;
+ }
+ if (sam3->sidcount) {
+ sam3->base.user_flags |= NETLOGON_EXTRA_SIDS;
+ } else {
+ sam3->sids = NULL;
}
-#endif
*_sam3 = sam3;
return NT_STATUS_OK;
diff --git a/source4/auth/auth_util.c b/source4/auth/auth_util.c
index 70ef5345d7..6ee5e13b11 100644
--- a/source4/auth/auth_util.c
+++ b/source4/auth/auth_util.c
@@ -327,6 +327,7 @@ NTSTATUS make_server_info_netlogon_validation(TALLOC_CTX *mem_ctx,
server_info->profile_path = talloc_reference(server_info, base->profile_path.string);
server_info->home_directory = talloc_reference(server_info, base->home_directory.string);
server_info->home_drive = talloc_reference(server_info, base->home_drive.string);
+ server_info->logon_server = talloc_reference(server_info, base->logon_server.string);
server_info->last_logon = base->last_logon;
server_info->last_logoff = base->last_logoff;
server_info->acct_expiry = base->acct_expiry;
diff --git a/source4/auth/kerberos/kerberos_pac.c b/source4/auth/kerberos/kerberos_pac.c
index dede5e8430..9be9df133a 100644
--- a/source4/auth/kerberos/kerberos_pac.c
+++ b/source4/auth/kerberos/kerberos_pac.c
@@ -487,7 +487,6 @@ static krb5_error_code make_pac_checksum(TALLOC_CTX *mem_ctx,
krb5_error_code ret;
struct PAC_DATA *pac_data = talloc(mem_ctx, struct PAC_DATA);
struct netr_SamInfo3 *sam3;
- struct timeval tv = timeval_current();
union PAC_INFO *u_LOGON_INFO;
struct PAC_LOGON_INFO *LOGON_INFO;
union PAC_INFO *u_LOGON_NAME;
@@ -573,7 +572,6 @@ static krb5_error_code make_pac_checksum(TALLOC_CTX *mem_ctx,
u_LOGON_INFO->logon_info.info = LOGON_INFO;
LOGON_INFO->info3 = *sam3;
- LOGON_INFO->info3.base.last_logon = timeval_to_nttime(&tv);
ret = krb5_unparse_name_norealm(context, client_principal, &name);
if (ret) {
diff --git a/source4/torture/auth/pac.c b/source4/torture/auth/pac.c
index 6f50ae776b..df9e45614e 100644
--- a/source4/torture/auth/pac.c
+++ b/source4/torture/auth/pac.c
@@ -272,7 +272,7 @@ static BOOL torture_pac_saved_check(void)
NTSTATUS nt_status;
TALLOC_CTX *mem_ctx = talloc_named(NULL, 0, "PAC saved check");
DATA_BLOB tmp_blob, validate_blob;
- struct PAC_DATA *pac_data;
+ struct PAC_DATA *pac_data, pac_data2;
struct PAC_LOGON_INFO *logon_info;
union netr_Validation validation;
const char *pac_file, *pac_kdc_key, *pac_member_key;
@@ -526,6 +526,85 @@ static BOOL torture_pac_saved_check(void)
return False;
}
+ ret = kerberos_create_pac(mem_ctx,
+ server_info_out,
+ smb_krb5_context->krb5_context,
+ &krbtgt_keyblock,
+ &server_keyblock,
+ client_principal, authtime,
+ &validate_blob);
+
+ if (ret != 0) {
+ krb5_free_keyblock_contents(smb_krb5_context->krb5_context,
+ &krbtgt_keyblock);
+ krb5_free_keyblock_contents(smb_krb5_context->krb5_context,
+ &server_keyblock);
+ krb5_free_principal(smb_krb5_context->krb5_context, client_principal);
+
+ DEBUG(0, ("(saved test) regnerated PAC create failed\n"));
+ talloc_free(mem_ctx);
+ return False;
+ }
+
+ dump_data(10,validate_blob.data,validate_blob.length);
+
+ /* compare both the length and the data bytes after a
+ * pull/push cycle. This ensures we use the exact same
+ * pointer, padding etc algorithms as win2k3.
+ */
+ if (tmp_blob.length != validate_blob.length) {
+ nt_status = ndr_pull_struct_blob(&validate_blob, mem_ctx, &pac_data2,
+ (ndr_pull_flags_fn_t)ndr_pull_PAC_DATA);
+ if (!NT_STATUS_IS_OK(nt_status)) {
+ DEBUG(0,("can't parse the PAC\n"));
+ return False;
+ }
+
+ NDR_PRINT_DEBUG(PAC_DATA, pac_data);
+
+ NDR_PRINT_DEBUG(PAC_DATA, &pac_data2);
+
+ krb5_free_keyblock_contents(smb_krb5_context->krb5_context,
+ &krbtgt_keyblock);
+ krb5_free_keyblock_contents(smb_krb5_context->krb5_context,
+ &server_keyblock);
+ krb5_free_principal(smb_krb5_context->krb5_context, client_principal);
+
+ DEBUG(0, ("(saved test) PAC regenerate failed: original buffer length[%u] != created buffer length[%u]\n",
+ (unsigned)tmp_blob.length, (unsigned)validate_blob.length));
+ talloc_free(mem_ctx);
+ return False;
+ }
+
+ if (memcmp(tmp_blob.data, validate_blob.data, tmp_blob.length) != 0) {
+ nt_status = ndr_pull_struct_blob(&validate_blob, mem_ctx, &pac_data2,
+ (ndr_pull_flags_fn_t)ndr_pull_PAC_DATA);
+ if (!NT_STATUS_IS_OK(nt_status)) {
+ DEBUG(0,("can't parse the PAC\n"));
+ return False;
+ }
+
+ NDR_PRINT_DEBUG(PAC_DATA, pac_data);
+
+ NDR_PRINT_DEBUG(PAC_DATA, &pac_data2);
+
+ krb5_free_keyblock_contents(smb_krb5_context->krb5_context,
+ &krbtgt_keyblock);
+ krb5_free_keyblock_contents(smb_krb5_context->krb5_context,
+ &server_keyblock);
+ krb5_free_principal(smb_krb5_context->krb5_context, client_principal);
+
+ DEBUG(0, ("(saved test) PAC regenerate failed: length[%u] matches, but data does not\n",
+ (unsigned)tmp_blob.length));
+ DEBUG(0, ("tmp_data:\n"));
+ dump_data(0, tmp_blob.data, tmp_blob.length);
+ DEBUG(0, ("validate_blob:\n"));
+ dump_data(0, validate_blob.data, validate_blob.length);
+
+ talloc_free(mem_ctx);
+ return False;
+ }
+
/* Break the auth time, to ensure we check this vital detail (not setting this caused all the pain in the first place... */
nt_status = kerberos_decode_pac(mem_ctx, &pac_data,
tmp_blob,