summaryrefslogtreecommitdiff
path: root/source4
diff options
context:
space:
mode:
authorStefan Metzmacher <metze@samba.org>2005-07-04 15:42:08 +0000
committerGerald (Jerry) Carter <jerry@samba.org>2007-10-10 13:19:13 -0500
commit148235a00948d572e863db277704c34fee56ebf4 (patch)
tree9b802d3466b1db98b129ac194d144653b939b621 /source4
parent8f9e87d858ae1cf2209cfd8332ad54a750252e24 (diff)
downloadsamba-148235a00948d572e863db277704c34fee56ebf4.tar.gz
samba-148235a00948d572e863db277704c34fee56ebf4.tar.bz2
samba-148235a00948d572e863db277704c34fee56ebf4.zip
r8148: - make the PAC generation code a bit more readable and add some outof memory checks
- move to handmodified pull/push code for PAC_BUFFER to get the _ndr_size field and the subcontext size right - after looking closely to the sample w2k3 PAC in our torture test (and some more in my archive) I found out that the first uint32 before the netr_SamInfo3 was also a pointer, (and we passed a NULL pointer there before, so I think that was the reason why the windows clients doesn't want our PAC) w2k3 uses this for unique pointers: ptr = ndr->ptr_count * 4; ptr |= 0x00020000; ndr->ptr_count; - do one more pull/push round with the sample PAC metze (This used to be commit 0eee17941595e9842a264bf89ac73ca66cea7ed5)
Diffstat (limited to 'source4')
-rw-r--r--source4/auth/kerberos/kerberos_pac.c143
-rw-r--r--source4/include/structs.h2
-rw-r--r--source4/librpc/config.mk5
-rw-r--r--source4/librpc/idl/krb5pac.idl32
-rw-r--r--source4/librpc/ndr/libndr.h2
-rw-r--r--source4/librpc/ndr/ndr_krb5pac.c143
-rw-r--r--source4/torture/auth/pac.c28
7 files changed, 277 insertions, 78 deletions
diff --git a/source4/auth/kerberos/kerberos_pac.c b/source4/auth/kerberos/kerberos_pac.c
index 312013fdb9..760de8c6c6 100644
--- a/source4/auth/kerberos/kerberos_pac.c
+++ b/source4/auth/kerberos/kerberos_pac.c
@@ -111,7 +111,7 @@ static NTSTATUS check_pac_checksum(TALLOC_CTX *mem_ctx,
if (!pac_data.buffers[i].info) {
break;
}
- logon_info = &pac_data.buffers[i].info->logon_info;
+ logon_info = pac_data.buffers[i].info->logon_info.i;
break;
case PAC_TYPE_SRV_CHECKSUM:
if (!pac_data.buffers[i].info) {
@@ -230,9 +230,17 @@ static krb5_error_code make_pac_checksum(TALLOC_CTX *mem_ctx,
struct PAC_DATA *pac_data = talloc(mem_ctx, struct PAC_DATA);
struct netr_SamBaseInfo *sam;
struct timeval tv = timeval_current();
+ union PAC_INFO *u_LOGON_INFO;
+ struct PAC_LOGON_INFO *LOGON_INFO;
+ union PAC_INFO *u_LOGON_NAME;
+ struct PAC_LOGON_NAME *LOGON_NAME;
+ union PAC_INFO *u_KDC_CHECKSUM;
+ struct PAC_SIGNATURE_DATA *KDC_CHECKSUM;
+ union PAC_INFO *u_SRV_CHECKSUM;
+ struct PAC_SIGNATURE_DATA *SRV_CHECKSUM;
enum {
- PAC_BUF_LOGON_TYPE = 0,
+ PAC_BUF_LOGON_INFO = 0,
PAC_BUF_LOGON_NAME = 1,
PAC_BUF_KDC_CHECKSUM = 2,
PAC_BUF_SRV_CHECKSUM = 3,
@@ -249,52 +257,78 @@ static krb5_error_code make_pac_checksum(TALLOC_CTX *mem_ctx,
pac_data->buffers = talloc_array(pac_data,
struct PAC_BUFFER,
pac_data->num_buffers);
-
if (!pac_data->buffers) {
talloc_free(pac_data);
return ENOMEM;
}
- pac_data->buffers[PAC_BUF_LOGON_TYPE].type = PAC_TYPE_LOGON_INFO;
- pac_data->buffers[PAC_BUF_LOGON_TYPE].info = talloc_zero(pac_data->buffers,
- union PAC_INFO);
+ /* LOGON_INFO */
+ u_LOGON_INFO = talloc_zero(pac_data->buffers, union PAC_INFO);
+ if (!u_LOGON_INFO) {
+ talloc_free(pac_data);
+ return ENOMEM;
+ }
+ pac_data->buffers[PAC_BUF_LOGON_INFO].type = PAC_TYPE_LOGON_INFO;
+ pac_data->buffers[PAC_BUF_LOGON_INFO].info = u_LOGON_INFO;
- nt_status = auth_convert_server_info_sambaseinfo(pac_data->buffers[0].info,
- server_info, &sam);
+ /* LOGON_NAME */
+ u_LOGON_NAME = talloc_zero(pac_data->buffers, union PAC_INFO);
+ if (!u_LOGON_NAME) {
+ talloc_free(pac_data);
+ return ENOMEM;
+ }
+ pac_data->buffers[PAC_BUF_LOGON_NAME].type = PAC_TYPE_LOGON_NAME;
+ pac_data->buffers[PAC_BUF_LOGON_NAME].info = u_LOGON_NAME;
+ LOGON_NAME = &u_LOGON_NAME->logon_name;
+
+ /* KDC_CHECKSUM */
+ u_KDC_CHECKSUM = talloc_zero(pac_data->buffers, union PAC_INFO);
+ if (!u_KDC_CHECKSUM) {
+ talloc_free(pac_data);
+ return ENOMEM;
+ }
+ pac_data->buffers[PAC_BUF_KDC_CHECKSUM].type = PAC_TYPE_KDC_CHECKSUM;
+ pac_data->buffers[PAC_BUF_KDC_CHECKSUM].info = u_KDC_CHECKSUM;
+ KDC_CHECKSUM = &u_KDC_CHECKSUM->kdc_cksum;
+
+ /* SRV_CHECKSUM */
+ u_SRV_CHECKSUM = talloc_zero(pac_data->buffers, union PAC_INFO);
+ if (!u_SRV_CHECKSUM) {
+ talloc_free(pac_data);
+ return ENOMEM;
+ }
+ pac_data->buffers[PAC_BUF_SRV_CHECKSUM].type = PAC_TYPE_SRV_CHECKSUM;
+ pac_data->buffers[PAC_BUF_SRV_CHECKSUM].info = u_SRV_CHECKSUM;
+ SRV_CHECKSUM = &u_SRV_CHECKSUM->srv_cksum;
+
+ /* now the real work begins... */
+
+ LOGON_INFO = talloc_zero(u_LOGON_INFO, struct PAC_LOGON_INFO);
+ if (!LOGON_INFO) {
+ talloc_free(pac_data);
+ return ENOMEM;
+ }
+ nt_status = auth_convert_server_info_sambaseinfo(LOGON_INFO, server_info, &sam);
if (!NT_STATUS_IS_OK(nt_status)) {
DEBUG(1, ("Getting Samba info failed: %s\n", nt_errstr(nt_status)));
talloc_free(pac_data);
return EINVAL;
}
- pac_data->buffers[PAC_BUF_LOGON_TYPE].info->logon_info.info3.base = *sam;
- pac_data->buffers[PAC_BUF_LOGON_TYPE].size
- = ndr_size_PAC_INFO(pac_data->buffers[PAC_BUF_LOGON_TYPE].info,
- pac_data->buffers[PAC_BUF_LOGON_TYPE].type,
- 0);
- pac_data->buffers[PAC_BUF_LOGON_TYPE]._pad = 0;
-
- pac_data->buffers[PAC_BUF_LOGON_NAME].type = PAC_TYPE_LOGON_NAME;
- pac_data->buffers[PAC_BUF_LOGON_NAME].info = talloc_zero(pac_data->buffers,
- union PAC_INFO);
- pac_data->buffers[PAC_BUF_LOGON_NAME].info->logon_name.account_name
- = server_info->account_name;
- pac_data->buffers[PAC_BUF_LOGON_NAME].info->logon_name.logon_time
- = timeval_to_nttime(&tv);
- pac_data->buffers[PAC_BUF_LOGON_NAME].size
- = ndr_size_PAC_INFO(pac_data->buffers[PAC_BUF_LOGON_NAME].info,
- pac_data->buffers[PAC_BUF_LOGON_NAME].type,
- 0);
- pac_data->buffers[PAC_BUF_LOGON_NAME]._pad = 0;
+ u_LOGON_INFO->logon_info.unknown[0] = 0x00081001;
+ u_LOGON_INFO->logon_info.unknown[1] = 0xCCCCCCCC;
+ u_LOGON_INFO->logon_info.unknown[2] = 0x000001C8;
+ u_LOGON_INFO->logon_info.unknown[3] = 0x00000000;
+ u_LOGON_INFO->logon_info.i = LOGON_INFO;
+ LOGON_INFO->info3.base = *sam;
+
+ LOGON_NAME->account_name = server_info->account_name;
+ LOGON_NAME->logon_time = timeval_to_nttime(&tv);
+
- pac_data->buffers[PAC_BUF_KDC_CHECKSUM].type = PAC_TYPE_KDC_CHECKSUM;
- pac_data->buffers[PAC_BUF_KDC_CHECKSUM].info = talloc_zero(pac_data->buffers,
- union PAC_INFO);
/* First, just get the keytypes filled in (and lengths right, eventually) */
- ret = make_pac_checksum(mem_ctx, zero_blob,
- &pac_data->buffers[PAC_BUF_KDC_CHECKSUM].info->kdc_cksum,
- context, krbtgt_keyblock);
+ ret = make_pac_checksum(mem_ctx, zero_blob, KDC_CHECKSUM, context, krbtgt_keyblock);
if (ret) {
DEBUG(2, ("making krbtgt PAC checksum failed: %s\n",
smb_get_krb5_error_message(context, ret, mem_ctx)));
@@ -302,19 +336,7 @@ static krb5_error_code make_pac_checksum(TALLOC_CTX *mem_ctx,
return ret;
}
- pac_data->buffers[PAC_BUF_KDC_CHECKSUM].size
- = ndr_size_PAC_INFO(pac_data->buffers[PAC_BUF_KDC_CHECKSUM].info,
- pac_data->buffers[PAC_BUF_KDC_CHECKSUM].type,
- 0);
- pac_data->buffers[PAC_BUF_KDC_CHECKSUM]._pad = 0;
-
-
- pac_data->buffers[PAC_BUF_SRV_CHECKSUM].type = PAC_TYPE_SRV_CHECKSUM;
- pac_data->buffers[PAC_BUF_SRV_CHECKSUM].info = talloc_zero(pac_data->buffers,
- union PAC_INFO);
- ret = make_pac_checksum(mem_ctx, zero_blob,
- &pac_data->buffers[PAC_BUF_SRV_CHECKSUM].info->srv_cksum,
- context, server_keyblock);
+ ret = make_pac_checksum(mem_ctx, zero_blob, SRV_CHECKSUM, context, server_keyblock);
if (ret) {
DEBUG(2, ("making server PAC checksum failed: %s\n",
smb_get_krb5_error_message(context, ret, mem_ctx)));
@@ -322,16 +344,10 @@ static krb5_error_code make_pac_checksum(TALLOC_CTX *mem_ctx,
return ret;
}
- pac_data->buffers[PAC_BUF_SRV_CHECKSUM].size
- = ndr_size_PAC_INFO(pac_data->buffers[PAC_BUF_SRV_CHECKSUM].info,
- pac_data->buffers[PAC_BUF_SRV_CHECKSUM].type,
- 0);
- pac_data->buffers[PAC_BUF_SRV_CHECKSUM]._pad = 0;
-
/* But wipe out the actual signatures */
- ZERO_STRUCT(pac_data->buffers[PAC_BUF_KDC_CHECKSUM].info->kdc_cksum.signature);
- ZERO_STRUCT(pac_data->buffers[PAC_BUF_SRV_CHECKSUM].info->srv_cksum.signature);
-
+ ZERO_STRUCT(KDC_CHECKSUM->signature);
+ ZERO_STRUCT(SRV_CHECKSUM->signature);
+
nt_status = ndr_push_struct_blob(&tmp_blob, mem_ctx, pac_data,
(ndr_push_flags_fn_t)ndr_push_PAC_DATA);
if (!NT_STATUS_IS_OK(nt_status)) {
@@ -341,12 +357,11 @@ static krb5_error_code make_pac_checksum(TALLOC_CTX *mem_ctx,
}
/* Then sign the result of the previous push, where the sig was zero'ed out */
- ret = make_pac_checksum(mem_ctx, tmp_blob, &pac_data->buffers[3].info->srv_cksum,
+ ret = make_pac_checksum(mem_ctx, tmp_blob, SRV_CHECKSUM,
context, server_keyblock);
/* Push the Server checksum out */
- nt_status = ndr_push_struct_blob(&server_checksum_blob, mem_ctx,
- &pac_data->buffers[PAC_BUF_SRV_CHECKSUM].info->srv_cksum,
+ nt_status = ndr_push_struct_blob(&server_checksum_blob, mem_ctx, SRV_CHECKSUM,
(ndr_push_flags_fn_t)ndr_push_PAC_SIGNATURE_DATA);
if (!NT_STATUS_IS_OK(nt_status)) {
DEBUG(1, ("PAC_SIGNATURE push failed: %s\n", nt_errstr(nt_status)));
@@ -354,10 +369,14 @@ static krb5_error_code make_pac_checksum(TALLOC_CTX *mem_ctx,
return EINVAL;
}
- /* Then sign the result of the previous push, where the sig was zero'ed out */
- ret = make_pac_checksum(mem_ctx, server_checksum_blob,
- &pac_data->buffers[PAC_BUF_KDC_CHECKSUM].info->kdc_cksum,
- context, krbtgt_keyblock);
+ /* Then sign Server checksum */
+ ret = make_pac_checksum(mem_ctx, server_checksum_blob, KDC_CHECKSUM, context, krbtgt_keyblock);
+ if (ret) {
+ DEBUG(2, ("making krbtgt PAC checksum failed: %s\n",
+ smb_get_krb5_error_message(context, ret, mem_ctx)));
+ talloc_free(pac_data);
+ return ret;
+ }
/* And push it out again, this time to the world. This relies on determanistic pointer values */
nt_status = ndr_push_struct_blob(&tmp_blob, mem_ctx, pac_data,
diff --git a/source4/include/structs.h b/source4/include/structs.h
index c3c4bc9a1e..e9c8c69fd7 100644
--- a/source4/include/structs.h
+++ b/source4/include/structs.h
@@ -89,6 +89,8 @@ struct epm_tower;
struct drsuapi_DsCrackNames;
+struct PAC_BUFFER;
+
struct samr_ChangePasswordUser;
struct samr_OemChangePasswordUser2;
struct samr_ChangePasswordUser3;
diff --git a/source4/librpc/config.mk b/source4/librpc/config.mk
index c5c261c63f..7c93ba9abb 100644
--- a/source4/librpc/config.mk
+++ b/source4/librpc/config.mk
@@ -308,7 +308,10 @@ REQUIRED_SUBSYSTEMS = NDR_RAW
INIT_FUNCTION = dcerpc_krb5pac_init
INIT_OBJ_FILES = librpc/gen_ndr/ndr_krb5pac.o
NOPROTO = YES
-REQUIRED_SUBSYSTEMS = NDR_RAW
+REQUIRED_SUBSYSTEMS = NDR_RAW NDR_KRB5PAC_UTIL
+
+[SUBSYSTEM::NDR_KRB5PAC_UTIL]
+INIT_OBJ_FILES = librpc/ndr/ndr_krb5pac.o
[SUBSYSTEM::NDR_XATTR]
INIT_FUNCTION = dcerpc_xattr_init
diff --git a/source4/librpc/idl/krb5pac.idl b/source4/librpc/idl/krb5pac.idl
index 4de5453478..a0df6f3822 100644
--- a/source4/librpc/idl/krb5pac.idl
+++ b/source4/librpc/idl/krb5pac.idl
@@ -5,7 +5,7 @@
#include "idl_types.h"
[
- uuid("46746756-7567-7567-5677-756756756756"),
+ uuid("1-2-3-4"),
version(0.0),
pointer_default(unique),
pointer_default_top(unique),
@@ -24,29 +24,35 @@ interface krb5pac
} PAC_SIGNATURE_DATA;
typedef struct {
- uint32 unknown[5];
netr_SamInfo3 info3;
dom_sid2 *res_group_dom_sid;
samr_RidWithAttributeArray res_groups;
} PAC_LOGON_INFO;
- const uint8 PAC_TYPE_LOGON_INFO = 1;
- const uint8 PAC_TYPE_SRV_CHECKSUM = 6;
- const uint8 PAC_TYPE_KDC_CHECKSUM = 7;
- const uint8 PAC_TYPE_LOGON_NAME = 10;
+ typedef struct {
+ uint32 unknown[4];
+ PAC_LOGON_INFO *i;
+ } PAC_LOGON_INFO_CTR;
+
+ typedef [public,v1_enum] enum {
+ PAC_TYPE_LOGON_INFO = 1,
+ PAC_TYPE_SRV_CHECKSUM = 6,
+ PAC_TYPE_KDC_CHECKSUM = 7,
+ PAC_TYPE_LOGON_NAME = 10
+ } PAC_TYPE;
- typedef [nodiscriminant,gensize] union {
- [case(PAC_TYPE_LOGON_INFO)] PAC_LOGON_INFO logon_info;
+ typedef [public,nodiscriminant,gensize] union {
+ [case(PAC_TYPE_LOGON_INFO)] PAC_LOGON_INFO_CTR logon_info;
[case(PAC_TYPE_SRV_CHECKSUM)] PAC_SIGNATURE_DATA srv_cksum;
[case(PAC_TYPE_KDC_CHECKSUM)] PAC_SIGNATURE_DATA kdc_cksum;
[case(PAC_TYPE_LOGON_NAME)] PAC_LOGON_NAME logon_name;
} PAC_INFO;
- typedef struct {
- uint32 type;
- uint32 size;
- [relative,switch_is(type),subcontext(0),subcontext_size(size),pad8] PAC_INFO *info;
- uint32 _pad; /* Top half of a 64 bit pointer? */
+ typedef [public,nopush,nopull,noprint] struct {
+ PAC_TYPE type;
+ [value(_ndr_size_PAC_INFO(info, type, 0))] uint32 _ndr_size;
+ [relative,switch_is(type),subcontext(0),subcontext_size(_subcontext_size_PAC_INFO(r, ndr->flags)),flag(NDR_ALIGN8)] PAC_INFO *info;
+ [value(0)] uint32 _pad; /* Top half of a 64 bit pointer? */
} PAC_BUFFER;
typedef [public] struct {
diff --git a/source4/librpc/ndr/libndr.h b/source4/librpc/ndr/libndr.h
index 17c06b79da..328fa7c703 100644
--- a/source4/librpc/ndr/libndr.h
+++ b/source4/librpc/ndr/libndr.h
@@ -191,6 +191,8 @@ enum ndr_compression_alg {
#define NDR_ALIGN(ndr, n) ndr_align_size(ndr->offset, n)
+#define NDR_ROUND(size, n) (((size)+((n)-1)) & ~((n)-1))
+
#define NDR_PULL_ALIGN(ndr, n) do { \
if (!(ndr->flags & LIBNDR_FLAG_NOALIGN)) { \
if (ndr->flags & LIBNDR_FLAG_PAD_CHECK) { \
diff --git a/source4/librpc/ndr/ndr_krb5pac.c b/source4/librpc/ndr/ndr_krb5pac.c
new file mode 100644
index 0000000000..b3c08c642f
--- /dev/null
+++ b/source4/librpc/ndr/ndr_krb5pac.c
@@ -0,0 +1,143 @@
+/*
+ Unix SMB/CIFS implementation.
+
+ routines for marshalling/unmarshalling spoolss subcontext buffer structures
+
+ Copyright (C) Stefan Metzmacher 2005
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+
+#include "includes.h"
+#include "librpc/gen_ndr/ndr_krb5pac.h"
+
+size_t _ndr_size_PAC_INFO(const union PAC_INFO *r, uint32_t level, int flags)
+{
+ size_t s = ndr_size_PAC_INFO(r, level, flags);
+ switch (level) {
+ case PAC_TYPE_LOGON_INFO:
+ return NDR_ROUND(s,8);
+ default:
+ return s;
+ }
+}
+
+size_t _subcontext_size_PAC_INFO(const union PAC_INFO *r, uint32_t level, int flags)
+{
+ size_t s = ndr_size_PAC_INFO(r, level, flags);
+ return NDR_ROUND(s,8);
+}
+
+NTSTATUS ndr_push_PAC_BUFFER(struct ndr_push *ndr, int ndr_flags, const struct PAC_BUFFER *r)
+{
+ if (ndr_flags & NDR_SCALARS) {
+ NDR_CHECK(ndr_push_align(ndr, 4));
+ NDR_CHECK(ndr_push_PAC_TYPE(ndr, NDR_SCALARS, r->type));
+ NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, _ndr_size_PAC_INFO(r->info,r->type,0)));
+ {
+ uint32_t _flags_save_PAC_INFO = ndr->flags;
+ ndr_set_flags(&ndr->flags, LIBNDR_FLAG_ALIGN8);
+ NDR_CHECK(ndr_push_relative_ptr1(ndr, r->info));
+ ndr->flags = _flags_save_PAC_INFO;
+ }
+ NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, 0));
+ }
+ if (ndr_flags & NDR_BUFFERS) {
+ {
+ uint32_t _flags_save_PAC_INFO = ndr->flags;
+ ndr_set_flags(&ndr->flags, LIBNDR_FLAG_ALIGN8);
+ if (r->info) {
+ NDR_CHECK(ndr_push_relative_ptr2(ndr, r->info));
+ {
+ struct ndr_push *_ndr_info;
+
+ _ndr_info = ndr_push_init_ctx(ndr);
+ if (!_ndr_info) return NT_STATUS_NO_MEMORY;
+ _ndr_info->flags = ndr->flags;
+
+ NDR_CHECK(ndr_push_set_switch_value(_ndr_info, r->info, r->type));
+ NDR_CHECK(ndr_push_PAC_INFO(_ndr_info, NDR_SCALARS|NDR_BUFFERS, r->info));
+ NDR_CHECK(ndr_push_subcontext_header(ndr, 0, _subcontext_size_PAC_INFO(r->info,r->type,0), _ndr_info));
+ NDR_CHECK(ndr_push_bytes(ndr, _ndr_info->data, _ndr_info->offset));
+ }
+ }
+ ndr->flags = _flags_save_PAC_INFO;
+ }
+ }
+ return NT_STATUS_OK;
+}
+
+NTSTATUS ndr_pull_PAC_BUFFER(struct ndr_pull *ndr, int ndr_flags, struct PAC_BUFFER *r)
+{
+ uint32_t _ptr_info;
+ if (ndr_flags & NDR_SCALARS) {
+ NDR_CHECK(ndr_pull_align(ndr, 4));
+ NDR_CHECK(ndr_pull_PAC_TYPE(ndr, NDR_SCALARS, &r->type));
+ NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->_ndr_size));
+ {
+ uint32_t _flags_save_PAC_INFO = ndr->flags;
+ ndr_set_flags(&ndr->flags, LIBNDR_FLAG_ALIGN8);
+ NDR_CHECK(ndr_pull_unique_ptr(ndr, &_ptr_info));
+ if (_ptr_info) {
+ NDR_ALLOC(ndr, r->info);
+ NDR_CHECK(ndr_pull_relative_ptr1(ndr, r->info, _ptr_info));
+ } else {
+ r->info = NULL;
+ }
+ ndr->flags = _flags_save_PAC_INFO;
+ }
+ NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->_pad));
+ }
+ if (ndr_flags & NDR_BUFFERS) {
+ {
+ uint32_t _flags_save_PAC_INFO = ndr->flags;
+ ndr_set_flags(&ndr->flags, LIBNDR_FLAG_ALIGN8);
+ if (r->info) {
+ struct ndr_pull_save _relative_save;
+ ndr_pull_save(ndr, &_relative_save);
+ NDR_CHECK(ndr_pull_relative_ptr2(ndr, r->info));
+ {
+ struct ndr_pull *_ndr_info;
+ NDR_ALLOC(ndr, _ndr_info);
+ NDR_CHECK(ndr_pull_subcontext_header(ndr, 0, r->_ndr_size, _ndr_info));
+ NDR_CHECK(ndr_pull_set_switch_value(_ndr_info, r->info, r->type));
+ NDR_CHECK(ndr_pull_PAC_INFO(_ndr_info, NDR_SCALARS|NDR_BUFFERS, r->info));
+ NDR_CHECK(ndr_pull_advance(ndr, r->_ndr_size));
+ }
+ ndr_pull_restore(ndr, &_relative_save);
+ }
+ ndr->flags = _flags_save_PAC_INFO;
+ }
+ }
+ return NT_STATUS_OK;
+}
+
+void ndr_print_PAC_BUFFER(struct ndr_print *ndr, const char *name, const struct PAC_BUFFER *r)
+{
+ ndr_print_struct(ndr, name, "PAC_BUFFER");
+ ndr->depth++;
+ ndr_print_PAC_TYPE(ndr, "type", r->type);
+ ndr_print_uint32(ndr, "_ndr_size", (ndr->flags & LIBNDR_PRINT_SET_VALUES)?_ndr_size_PAC_INFO(r->info,r->type,0):r->_ndr_size);
+ ndr_print_ptr(ndr, "info", r->info);
+ ndr->depth++;
+ if (r->info) {
+ ndr_print_set_switch_value(ndr, r->info, r->type);
+ ndr_print_PAC_INFO(ndr, "info", r->info);
+ }
+ ndr->depth--;
+ ndr_print_uint32(ndr, "_pad", r->_pad);
+ ndr->depth--;
+}
diff --git a/source4/torture/auth/pac.c b/source4/torture/auth/pac.c
index 00196b493f..51f33781fa 100644
--- a/source4/torture/auth/pac.c
+++ b/source4/torture/auth/pac.c
@@ -118,7 +118,9 @@ static BOOL torture_pac_self_check(void)
talloc_free(mem_ctx);
return False;
}
-
+
+ /* dump_data(0,tmp_blob.data,tmp_blob.length); */
+
/* Now check that we can read it back */
nt_status = kerberos_decode_pac(mem_ctx, &pac_info,
tmp_blob,
@@ -190,8 +192,9 @@ 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;
+ DATA_BLOB tmp_blob, validate_blob;
struct PAC_LOGON_INFO *pac_info;
+ struct PAC_DATA pac_data;
krb5_keyblock server_keyblock;
uint8_t server_bytes[16];
@@ -225,6 +228,10 @@ static BOOL torture_pac_saved_check(void)
tmp_blob = data_blob_const(saved_pac, sizeof(saved_pac));
+ /*tmp_blob.data = file_load(lp_parm_string(-1,"torture","pac_file"), &tmp_blob.length);*/
+
+ /*dump_data(0,tmp_blob.data,tmp_blob.length);*/
+
/* Decode and verify the signaure on the PAC */
nt_status = kerberos_decode_pac(mem_ctx, &pac_info,
tmp_blob,
@@ -239,6 +246,23 @@ static BOOL torture_pac_saved_check(void)
talloc_free(mem_ctx);
return False;
}
+
+ nt_status = ndr_pull_struct_blob(&tmp_blob, mem_ctx, &pac_data,
+ (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;
+ }
+
+ nt_status = ndr_push_struct_blob(&validate_blob, mem_ctx, &pac_data,
+ (ndr_push_flags_fn_t)ndr_push_PAC_DATA);
+ if (!NT_STATUS_IS_OK(nt_status)) {
+ DEBUG(0, ("PAC push failed: %s\n", nt_errstr(nt_status)));
+ return False;
+ }
+
+ /* dump_data(0,validate_blob.data,validate_blob.length); */
+
talloc_free(mem_ctx);
return True;
}