mirror of
https://github.com/samba-team/samba.git
synced 2024-12-23 17:34:34 +03:00
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 commit is contained in:
parent
5fcaa21d67
commit
0eee179415
@ -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,
|
||||
|
@ -89,6 +89,8 @@ struct epm_tower;
|
||||
|
||||
struct drsuapi_DsCrackNames;
|
||||
|
||||
struct PAC_BUFFER;
|
||||
|
||||
struct samr_ChangePasswordUser;
|
||||
struct samr_OemChangePasswordUser2;
|
||||
struct samr_ChangePasswordUser3;
|
||||
|
@ -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
|
||||
|
@ -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 [nodiscriminant,gensize] union {
|
||||
[case(PAC_TYPE_LOGON_INFO)] PAC_LOGON_INFO logon_info;
|
||||
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 [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 {
|
||||
|
@ -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) { \
|
||||
|
143
source/librpc/ndr/ndr_krb5pac.c
Normal file
143
source/librpc/ndr/ndr_krb5pac.c
Normal file
@ -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--;
|
||||
}
|
@ -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;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user