summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--source3/Makefile.in2
-rw-r--r--source3/include/authdata.h131
-rw-r--r--source3/include/ntdomain.h4
-rw-r--r--source3/libads/authdata.c495
-rw-r--r--source3/libads/kerberos_verify.c6
5 files changed, 636 insertions, 2 deletions
diff --git a/source3/Makefile.in b/source3/Makefile.in
index 33c687fa96..fc18fc2ff2 100644
--- a/source3/Makefile.in
+++ b/source3/Makefile.in
@@ -195,7 +195,7 @@ LIBADS_OBJ = libads/ldap.o libads/ldap_printer.o libads/sasl.o \
libads/krb5_setpw.o libads/ldap_user.o \
libads/ads_struct.o libads/ads_status.o \
libads/disp_sec.o libads/ads_utils.o libads/ldap_utils.o \
- libads/ads_ldap.o
+ libads/ads_ldap.o libads/authdata.o
LIBADS_SERVER_OBJ = libads/util.o libads/kerberos_verify.o
diff --git a/source3/include/authdata.h b/source3/include/authdata.h
new file mode 100644
index 0000000000..dc9f217549
--- /dev/null
+++ b/source3/include/authdata.h
@@ -0,0 +1,131 @@
+/*
+ Unix SMB/CIFS implementation.
+ Kerberos authorization data
+ Copyright (C) Jim McDonough 2003
+
+
+ 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.
+*/
+
+#ifndef _AUTHDATA_H
+#define _AUTHDATA_H
+
+#include "rpc_misc.h"
+
+#define PAC_TYPE_LOGON_INFO 1
+#define PAC_TYPE_SERVER_CHECKSUM 6
+#define PAC_TYPE_PRIVSVR_CHECKSUM 7
+
+typedef struct pac_signature_data {
+ uint32 type;
+ uint8 *signature;
+} PAC_SIGNATURE_DATA;
+
+typedef struct krb_sid_and_attrs {
+ uint32 sid_ptr;
+ uint32 attrs;
+ DOM_SID2 *sid;
+} KRB_SID_AND_ATTRS;
+
+typedef struct krb_sid_and_attr_array {
+ uint32 count;
+ KRB_SID_AND_ATTRS *krb_sid_and_attrs;
+} KRB_SID_AND_ATTR_ARRAY;
+
+
+/* This is awfully similar to a samr_user_info_23, but not identical.
+ Many of the field names have been swiped from there, because it is
+ so similar that they are likely the same, but many have been verified.
+ Some are in a different order, though... */
+typedef struct pac_logon_info {
+ NTTIME logon_time; /* logon time */
+ NTTIME logoff_time; /* logoff time */
+ NTTIME kickoff_time; /* kickoff time */
+ NTTIME pass_last_set_time; /* password last set time */
+ NTTIME pass_can_change_time; /* password can change time */
+ NTTIME pass_must_change_time; /* password must change time */
+
+ UNIHDR hdr_user_name; /* user name unicode string header */
+ UNIHDR hdr_full_name; /* user's full name unicode string header */
+ UNIHDR hdr_logon_script; /* these last 4 appear to be in a different */
+ UNIHDR hdr_profile_path; /* order than in the info23 */
+ UNIHDR hdr_home_dir;
+ UNIHDR hdr_dir_drive;
+
+ uint16 logon_count; /* number of times user has logged onto domain */
+ uint16 reserved12;
+
+ uint32 user_rid;
+ uint32 group_rid;
+ uint32 group_count;
+ uint32 group_membership_ptr;
+ uint32 user_flags;
+
+ uint32 reserved13[4];
+ UNIHDR hdr_dom_controller;
+ UNIHDR hdr_dom_name;
+
+ uint32 ptr_dom_sid;
+
+ uint32 reserved16[2];
+ uint32 reserved17; /* looks like it may be acb_info */
+ uint32 reserved18[7];
+
+ uint32 sid_count;
+ uint32 ptr_extra_sids;
+
+ uint32 ptr_res_group_dom_sid;
+ uint32 res_group_count;
+ uint32 ptr_res_group_sids;
+
+ UNISTR2 uni_user_name; /* user name unicode string header */
+ UNISTR2 uni_full_name; /* user's full name unicode string header */
+ UNISTR2 uni_logon_script; /* these last 4 appear to be in a different*/
+ UNISTR2 uni_profile_path; /* order than in the info23 */
+ UNISTR2 uni_home_dir;
+ UNISTR2 uni_dir_drive;
+ UNISTR2 uni_dom_controller;
+ UNISTR2 uni_dom_name;
+ DOM_SID2 dom_sid;
+ KRB_SID_AND_ATTR_ARRAY extra_sids;
+
+} PAC_LOGON_INFO;
+
+typedef struct pac_info_ctr
+{
+ union
+ {
+ PAC_LOGON_INFO *logon_info;
+ PAC_SIGNATURE_DATA *srv_cksum;
+ PAC_SIGNATURE_DATA *privsrv_cksum;
+ } pac;
+} PAC_INFO_CTR;
+
+typedef struct pac_info_hdr {
+ uint32 type;
+ uint32 size;
+ uint32 offset;
+ uint32 offsethi;
+ PAC_INFO_CTR *ctr;
+} PAC_INFO_HDR;
+
+typedef struct pac_data {
+ uint32 num_buffers;
+ uint32 version;
+ PAC_INFO_HDR *pac_info_hdr_ptr;
+} PAC_DATA;
+
+
+#endif
diff --git a/source3/include/ntdomain.h b/source3/include/ntdomain.h
index d02195b378..9216640c03 100644
--- a/source3/include/ntdomain.h
+++ b/source3/include/ntdomain.h
@@ -372,6 +372,9 @@ struct acct_info
/* security descriptor structures */
#include "rpc_secdes.h"
+/* pac */
+#include "authdata.h"
+
/* different dce/rpc pipes */
#include "rpc_lsa.h"
#include "rpc_netlogon.h"
@@ -382,5 +385,4 @@ struct acct_info
#include "rpc_spoolss.h"
#include "rpc_dfs.h"
#include "rpc_ds.h"
-
#endif /* _NT_DOMAIN_H */
diff --git a/source3/libads/authdata.c b/source3/libads/authdata.c
new file mode 100644
index 0000000000..3d25aec205
--- /dev/null
+++ b/source3/libads/authdata.c
@@ -0,0 +1,495 @@
+/*
+ Unix SMB/CIFS implementation.
+ kerberos authorization data (PAC) utility library
+ Copyright (C) Jim McDonough 2003
+
+ 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"
+
+#ifdef HAVE_KRB5
+
+static DATA_BLOB unwrap_pac(DATA_BLOB *auth_data)
+{
+ DATA_BLOB pac_contents;
+ ASN1_DATA data;
+ int data_type;
+
+ asn1_load(&data, *auth_data);
+ asn1_start_tag(&data, ASN1_SEQUENCE(0));
+ asn1_start_tag(&data, ASN1_SEQUENCE(0));
+ asn1_start_tag(&data, ASN1_CONTEXT(0));
+ asn1_read_Integer(&data, &data_type);
+ asn1_end_tag(&data);
+ asn1_start_tag(&data, ASN1_CONTEXT(1));
+ asn1_read_OctetString(&data, &pac_contents);
+ asn1_end_tag(&data);
+ asn1_end_tag(&data);
+ asn1_end_tag(&data);
+ return pac_contents;
+}
+
+static BOOL pac_io_krb_sids(const char *desc, KRB_SID_AND_ATTRS *sid_and_attr,
+ prs_struct *ps, int depth)
+{
+ if (NULL == sid_and_attr)
+ return False;
+
+ prs_debug(ps, depth, desc, "pac_io_krb_sids");
+ depth++;
+
+ if (UNMARSHALLING(ps)) {
+ sid_and_attr->sid =
+ (DOM_SID2 * ) prs_alloc_mem(ps, sizeof(DOM_SID2));
+ if (!sid_and_attr->sid) {
+ DEBUG(3, ("No memory available\n"));
+ return False;
+ }
+ }
+
+ if(!smb_io_dom_sid2("sid", sid_and_attr->sid, ps, depth))
+ return False;
+
+ return True;
+}
+
+
+static BOOL pac_io_krb_attrs(const char *desc, KRB_SID_AND_ATTRS *sid_and_attr,
+ prs_struct *ps, int depth)
+{
+ if (NULL == sid_and_attr)
+ return False;
+
+ prs_debug(ps, depth, desc, "pac_io_krb_attrs");
+ depth++;
+
+ if (!prs_uint32("sid_ptr", ps, depth, &sid_and_attr->sid_ptr))
+ return False;
+ if (!prs_uint32("attrs", ps, depth, &sid_and_attr->attrs))
+ return False;
+
+ return True;
+}
+
+static BOOL pac_io_krb_sid_and_attr_array(const char *desc,
+ KRB_SID_AND_ATTR_ARRAY *array,
+ uint32 num,
+ prs_struct *ps, int depth)
+{
+ int i;
+
+ if (NULL == array)
+ return False;
+
+ prs_debug(ps, depth, desc, "pac_io_krb_sid_and_attr_array");
+ depth++;
+
+
+ if (!prs_uint32("count", ps, depth, &array->count))
+ return False;
+
+ if (UNMARSHALLING(ps)) {
+ array->krb_sid_and_attrs = (KRB_SID_AND_ATTRS *)
+ prs_alloc_mem(ps, sizeof(KRB_SID_AND_ATTRS) * num);
+ if (!array->krb_sid_and_attrs) {
+ DEBUG(3, ("No memory available\n"));
+ return False;
+ }
+ }
+
+ for (i=0; i<num; i++) {
+ if (!pac_io_krb_attrs(desc,
+ &array->krb_sid_and_attrs[i],
+ ps, depth))
+ return False;
+
+ }
+ for (i=0; i<num; i++) {
+ if (!pac_io_krb_sids(desc,
+ &array->krb_sid_and_attrs[i],
+ ps, depth))
+ return False;
+
+ }
+
+ return True;
+
+}
+
+static BOOL pac_io_pac_logon_info(const char *desc, PAC_LOGON_INFO *info,
+ prs_struct *ps, int depth)
+{
+ uint32 garbage;
+ if (NULL == info)
+ return False;
+
+ prs_debug(ps, depth, desc, "pac_io_pac_logon_info");
+ depth++;
+
+ if (!prs_uint32("unknown", ps, depth, &garbage))
+ return False;
+ if (!prs_uint32("unknown", ps, depth, &garbage))
+ return False;
+ if (!prs_uint32("bufferlen", ps, depth, &garbage))
+ return False;
+ if (!prs_uint32("bufferlenhi", ps, depth, &garbage))
+ return False;
+ if (!prs_uint32("pointer", ps, depth, &garbage))
+ return False;
+
+ if (!smb_io_time("logon_time", &info->logon_time, ps, depth))
+ return False;
+ if (!smb_io_time("logoff_time", &info->logoff_time, ps, depth))
+ return False;
+ if (!smb_io_time("kickoff_time", &info->kickoff_time, ps, depth))
+ return False;
+ if (!smb_io_time("pass_last_set_time", &info->pass_last_set_time,
+ ps, depth))
+ return False;
+ if (!smb_io_time("pass_can_change_time", &info->pass_can_change_time,
+ ps, depth))
+ return False;
+ if (!smb_io_time("pass_must_change_time", &info->pass_must_change_time,
+ ps, depth))
+ return False;
+
+ if (!smb_io_unihdr("hdr_user_name", &info->hdr_user_name, ps, depth))
+ return False;
+ if (!smb_io_unihdr("hdr_full_name", &info->hdr_full_name, ps, depth))
+ return False;
+ if (!smb_io_unihdr("hdr_logon_script", &info->hdr_logon_script,
+ ps, depth))
+ return False;
+ if (!smb_io_unihdr("hdr_profile_path", &info->hdr_profile_path,
+ ps, depth))
+ return False;
+ if (!smb_io_unihdr("hdr_home_dir", &info->hdr_home_dir, ps, depth))
+ return False;
+ if (!smb_io_unihdr("hdr_dir_drive", &info->hdr_dir_drive, ps, depth))
+ return False;
+
+ if (!prs_uint16("logon_count", ps, depth, &info->logon_count))
+ return False;
+ if (!prs_uint16("reserved12", ps, depth, &info->reserved12))
+ return False;
+ if (!prs_uint32("user_rid", ps, depth, &info->user_rid))
+ return False;
+ if (!prs_uint32("group_rid", ps, depth, &info->group_rid))
+ return False;
+ if (!prs_uint32("group_count", ps, depth, &info->group_count))
+ return False;
+ /* I haven't seen this contain anything yet, but when it does
+ we will have to make sure we decode the contents in the middle
+ all the unistr2s ... */
+ if (!prs_uint32("group_mem_ptr", ps, depth,
+ &info->group_membership_ptr))
+ return False;
+ if (!prs_uint32("user_flags", ps, depth, &info->user_flags))
+ return False;
+
+ if (!prs_uint32("reserved13.0", ps, depth, &info->reserved13[0]))
+ return False;
+ if (!prs_uint32("reserved13.1", ps, depth, &info->reserved13[1]))
+ return False;
+ if (!prs_uint32("reserved13.2", ps, depth, &info->reserved13[2]))
+ return False;
+ if (!prs_uint32("reserved13.3", ps, depth, &info->reserved13[3]))
+ return False;
+
+ if (!smb_io_unihdr("hdr_dom_controller",
+ &info->hdr_dom_controller, ps, depth))
+ return False;
+ if (!smb_io_unihdr("hdr_dom_name", &info->hdr_dom_name, ps, depth))
+ return False;
+
+ /* this should be followed, but just get ptr for now */
+ if (!prs_uint32("ptr_dom_sid", ps, depth, &info->ptr_dom_sid))
+ return False;
+
+ if (!prs_uint32("reserved16.0", ps, depth, &info->reserved16[0]))
+ return False;
+ if (!prs_uint32("reserved16.1", ps, depth, &info->reserved16[1]))
+ return False;
+
+ /* might be acb_info */
+ if (!prs_uint32("reserved17", ps, depth, &info->reserved17))
+ return False;
+
+
+ if (!prs_uint32("reserved18.0", ps, depth, &info->reserved18[0]))
+ return False;
+ if (!prs_uint32("reserved18.1", ps, depth, &info->reserved18[1]))
+ return False;
+ if (!prs_uint32("reserved18.2", ps, depth, &info->reserved18[2]))
+ return False;
+ if (!prs_uint32("reserved18.3", ps, depth, &info->reserved18[3]))
+ return False;
+ if (!prs_uint32("reserved18.4", ps, depth, &info->reserved18[4]))
+ return False;
+ if (!prs_uint32("reserved18.5", ps, depth, &info->reserved18[5]))
+ return False;
+ if (!prs_uint32("reserved18.6", ps, depth, &info->reserved18[6]))
+ return False;
+
+ if (!prs_uint32("sid_count", ps, depth, &info->sid_count))
+ return False;
+ if (!prs_uint32("ptr_extra_sids", ps, depth, &info->ptr_extra_sids))
+ return False;
+ if (!prs_uint32("ptr_res_group_dom_sid", ps, depth,
+ &info->ptr_res_group_dom_sid))
+ return False;
+ if (!prs_uint32("res_group_count", ps, depth, &info->res_group_count))
+ return False;
+ if (!prs_uint32("ptr_res_group_sids", ps, depth,
+ &info->ptr_res_group_sids))
+ return False;
+
+ if(!smb_io_unistr2("uni_user_name", &info->uni_user_name,
+ info->hdr_user_name.buffer, ps, depth))
+ return False;
+ if(!smb_io_unistr2("uni_full_name", &info->uni_full_name,
+ info->hdr_full_name.buffer, ps, depth))
+ return False;
+ if(!smb_io_unistr2("uni_logon_script", &info->uni_logon_script,
+ info->hdr_logon_script.buffer, ps, depth))
+ return False;
+ if(!smb_io_unistr2("uni_profile_path", &info->uni_profile_path,
+ info->hdr_profile_path.buffer, ps, depth))
+ return False;
+ if(!smb_io_unistr2("uni_home_dir", &info->uni_home_dir,
+ info->hdr_home_dir.buffer, ps, depth))
+ return False;
+ if(!smb_io_unistr2("uni_dir_drive", &info->uni_dir_drive,
+ info->hdr_dir_drive.buffer, ps, depth))
+ return False;
+
+ /* the group membership list will need to be handled here */
+
+ if(!smb_io_unistr2("uni_dom_controller", &info->uni_dom_controller,
+ info->hdr_dom_controller.buffer, ps, depth))
+ return False;
+ if(!smb_io_unistr2("uni_dom_name", &info->uni_dom_name,
+ info->hdr_dom_name.buffer, ps, depth))
+ return False;
+
+ if(info->ptr_dom_sid)
+ if(!smb_io_dom_sid2("dom_sid", &info->dom_sid, ps, depth))
+ return False;
+
+
+ if (info->sid_count && info->ptr_extra_sids) {
+ if (!pac_io_krb_sid_and_attr_array("extra_sids",
+ &info->extra_sids,
+ info->sid_count,
+ ps, depth))
+ return False;
+ }
+
+
+ return True;
+}
+
+
+static BOOL pac_io_pac_signature_data(const char *desc,
+ PAC_SIGNATURE_DATA *data, uint32 length,
+ prs_struct *ps, int depth)
+{
+ uint32 siglen = length - sizeof(uint32);
+ if (NULL == data)
+ return False;
+
+ prs_debug(ps, depth, desc, "pac_io_pac_signature_data");
+ depth++;
+
+ if (!prs_uint32("type", ps, depth, &data->type))
+ return False;
+ if (UNMARSHALLING(ps)) {
+ data->signature = prs_alloc_mem(ps, siglen);
+ if (!data->signature) {
+ DEBUG(3, ("No memory available\n"));
+ return False;
+ }
+ }
+ if (!prs_uint8s(False, "signature", ps, depth, data->signature,siglen))
+ return False;
+
+ return True;
+}
+
+static BOOL pac_io_pac_info_hdr_ctr(const char *desc, PAC_INFO_HDR *hdr,
+ prs_struct *ps, int depth)
+{
+ if (NULL == hdr)
+ return False;
+
+ prs_debug(ps, depth, desc, "pac_io_pac_info_hdr_ctr");
+ depth++;
+
+ if (!prs_align(ps))
+ return False;
+
+ if (hdr->offset != prs_offset(ps)) {
+ DEBUG(5, ("offset in header(x%x) and data(x%x) do not match\n",
+ hdr->offset, prs_offset(ps)));
+ prs_set_offset(ps, hdr->offset);
+ }
+
+ if (UNMARSHALLING(ps) && hdr->size > 0) {
+ hdr->ctr = (PAC_INFO_CTR *)
+ prs_alloc_mem(ps, sizeof(PAC_INFO_CTR));
+ if (!hdr->ctr) {
+ DEBUG(3, ("No memory available\n"));
+ return False;
+ }
+ }
+
+ switch(hdr->type) {
+ case PAC_TYPE_LOGON_INFO:
+ DEBUG(5, ("PAC_TYPE_LOGON_INFO\n"));
+ if (UNMARSHALLING(ps))
+ hdr->ctr->pac.logon_info = (PAC_LOGON_INFO *)
+ prs_alloc_mem(ps, sizeof(PAC_LOGON_INFO));
+ if (!hdr->ctr->pac.logon_info) {
+ DEBUG(3, ("No memory available\n"));
+ return False;
+ }
+ if (!pac_io_pac_logon_info(desc, hdr->ctr->pac.logon_info,
+ ps, depth))
+ return False;
+ break;
+
+ case PAC_TYPE_SERVER_CHECKSUM:
+ DEBUG(5, ("PAC_TYPE_SERVER_CHECKSUM\n"));
+ if (UNMARSHALLING(ps))
+ hdr->ctr->pac.srv_cksum = (PAC_SIGNATURE_DATA *)
+ prs_alloc_mem(ps, sizeof(PAC_SIGNATURE_DATA));
+ if (!hdr->ctr->pac.srv_cksum) {
+ DEBUG(3, ("No memory available\n"));
+ return False;
+ }
+ if (!pac_io_pac_signature_data(desc, hdr->ctr->pac.srv_cksum,
+ hdr->size, ps, depth))
+ return False;
+ break;
+
+ case PAC_TYPE_PRIVSVR_CHECKSUM:
+ DEBUG(5, ("PAC_TYPE_PRIVSVR_CHECKSUM\n"));
+ if (UNMARSHALLING(ps))
+ hdr->ctr->pac.privsrv_cksum = (PAC_SIGNATURE_DATA *)
+ prs_alloc_mem(ps, sizeof(PAC_SIGNATURE_DATA));
+ if (!hdr->ctr->pac.privsrv_cksum) {
+ DEBUG(3, ("No memory available\n"));
+ return False;
+ }
+ if (!pac_io_pac_signature_data(desc,
+ hdr->ctr->pac.privsrv_cksum,
+ hdr->size, ps, depth))
+ return False;
+ break;
+
+ default:
+ /* dont' know, so we need to skip it */
+ DEBUG(3, ("unknown PAC type %d\n", hdr->type));
+ prs_set_offset(ps, prs_offset(ps) + hdr->size);
+ }
+
+ return True;
+}
+
+static BOOL pac_io_pac_info_hdr(const char *desc, PAC_INFO_HDR *hdr,
+ prs_struct *ps, int depth)
+{
+ if (NULL == hdr)
+ return False;
+
+ prs_debug(ps, depth, desc, "pac_io_pac_info_hdr");
+ depth++;
+
+ if (!prs_align(ps))
+ return False;
+ if (!prs_uint32("type", ps, depth, &hdr->type))
+ return False;
+ if (!prs_uint32("size", ps, depth, &hdr->size))
+ return False;
+ if (!prs_uint32("offset", ps, depth, &hdr->offset))
+ return False;
+ if (!prs_uint32("offsethi", ps, depth, &hdr->offsethi))
+ return False;
+
+ return True;
+}
+
+static BOOL pac_io_pac_data(const char *desc, PAC_DATA *data,
+ prs_struct *ps, int depth)
+{
+ int i;
+
+ if (NULL == data)
+ return False;
+
+ prs_debug(ps, depth, desc, "pac_io_pac_data");
+ depth++;
+
+ if (!prs_align(ps))
+ return False;
+ if (!prs_uint32("num_buffers", ps, depth, &data->num_buffers))
+ return False;
+ if (!prs_uint32("version", ps, depth, &data->version))
+ return False;
+
+ if (UNMARSHALLING(ps) && data->num_buffers > 0) {
+ if ((data->pac_info_hdr_ptr = (PAC_INFO_HDR *)
+ prs_alloc_mem(ps, sizeof(PAC_INFO_HDR) *
+ data->num_buffers)) == NULL) {
+ return False;
+ }
+ }
+
+ for (i=0; i<data->num_buffers; i++) {
+ if (!pac_io_pac_info_hdr(desc, &data->pac_info_hdr_ptr[i], ps,
+ depth))
+ return False;
+ }
+
+ for (i=0; i<data->num_buffers; i++) {
+ if (!pac_io_pac_info_hdr_ctr(desc, &data->pac_info_hdr_ptr[i],
+ ps, depth))
+ return False;
+ }
+
+ return True;
+}
+
+PAC_DATA *decode_pac_data(DATA_BLOB *auth_data, TALLOC_CTX *ctx)
+{
+ DATA_BLOB pac_data_blob = unwrap_pac(auth_data);
+ prs_struct ps;
+ PAC_DATA *pac_data;
+
+ DEBUG(5,("dump_pac_data\n"));
+ prs_init(&ps, pac_data_blob.length, ctx, UNMARSHALL);
+ prs_copy_data_in(&ps, pac_data_blob.data, pac_data_blob.length);
+ prs_set_offset(&ps, 0);
+
+ pac_data = (PAC_DATA *) talloc_zero(ctx, sizeof(PAC_DATA));
+ pac_io_pac_data("pac data", pac_data, &ps, 0);
+
+ prs_mem_free(&ps);
+
+ return pac_data;
+}
+
+#endif
diff --git a/source3/libads/kerberos_verify.c b/source3/libads/kerberos_verify.c
index 4d9a1bf765..56ec33b0a6 100644
--- a/source3/libads/kerberos_verify.c
+++ b/source3/libads/kerberos_verify.c
@@ -148,6 +148,12 @@ NTSTATUS ads_verify_ticket(ADS_STRUCT *ads, const DATA_BLOB *ticket,
get_auth_data_from_tkt(auth_data, tkt);
+ {
+ TALLOC_CTX *ctx = talloc_init("pac data");
+ decode_pac_data(auth_data);
+ talloc_destroy(ctx);
+ }
+
#if 0
if (tkt->enc_part2) {
file_save("/tmp/authdata.dat",