summaryrefslogtreecommitdiffstats
path: root/source/librpc
diff options
context:
space:
mode:
authorStefan Metzmacher <metze@samba.org>2005-07-04 15:42:08 +0000
committerStefan Metzmacher <metze@samba.org>2005-07-04 15:42:08 +0000
commit416da2cc13324c7091a9c3be7bb91cea4cbd2e43 (patch)
tree39bc606c5837cc18b17c2cb9959eb433c6c6140d /source/librpc
parent9a44aa24a19b86d7d88cee0f98c404dd9d616371 (diff)
downloadsamba-416da2cc13324c7091a9c3be7bb91cea4cbd2e43.tar.gz
samba-416da2cc13324c7091a9c3be7bb91cea4cbd2e43.tar.xz
samba-416da2cc13324c7091a9c3be7bb91cea4cbd2e43.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
Diffstat (limited to 'source/librpc')
-rw-r--r--source/librpc/config.mk5
-rw-r--r--source/librpc/idl/krb5pac.idl32
-rw-r--r--source/librpc/ndr/libndr.h2
-rw-r--r--source/librpc/ndr/ndr_krb5pac.c143
4 files changed, 168 insertions, 14 deletions
diff --git a/source/librpc/config.mk b/source/librpc/config.mk
index c5c261c63fb..7c93ba9abbe 100644
--- a/source/librpc/config.mk
+++ b/source/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/source/librpc/idl/krb5pac.idl b/source/librpc/idl/krb5pac.idl
index 4de54534784..a0df6f38227 100644
--- a/source/librpc/idl/krb5pac.idl
+++ b/source/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/source/librpc/ndr/libndr.h b/source/librpc/ndr/libndr.h
index 17c06b79da0..328fa7c703f 100644
--- a/source/librpc/ndr/libndr.h
+++ b/source/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/source/librpc/ndr/ndr_krb5pac.c b/source/librpc/ndr/ndr_krb5pac.c
new file mode 100644
index 00000000000..b3c08c642f6
--- /dev/null
+++ b/source/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--;
+}