From 77e95b40e95352ca90bd26cf626345f06eb808a9 Mon Sep 17 00:00:00 2001 From: =?utf8?q?G=C3=BCnther=20Deschner?= Date: Fri, 16 Jul 2010 04:06:48 +0200 Subject: [PATCH] s4-trusts: fix trustDomainPasswords drsblobs IDL and server side support. Also remove bogus trustCurrentPasswords struct which we just had because our IDL was incorrect. Guenther (cherry picked from commit e2f15d2a25302ee529006b2d1d6b99993c7102e8) --- librpc/idl/drsblobs.idl | 34 ++++---- librpc/ndr/ndr_drsblobs.c | 157 ++++++++---------------------------- librpc/ndr/ndr_drsblobs.h | 4 - source4/kdc/db-glue.c | 14 ++-- source4/rpc_server/lsa/dcesrv_lsa.c | 54 +++---------- 5 files changed, 69 insertions(+), 194 deletions(-) diff --git a/librpc/idl/drsblobs.idl b/librpc/idl/drsblobs.idl index 1b4649cff9f..d16027055b3 100644 --- a/librpc/idl/drsblobs.idl +++ b/librpc/idl/drsblobs.idl @@ -468,39 +468,37 @@ interface drsblobs { typedef [public] struct { NTTIME LastUpdateTime; lsa_TrustAuthType AuthType; - [switch_is(AuthType)] AuthInfo AuthInfo; [flag(NDR_ALIGN4)] DATA_BLOB _pad; } AuthenticationInformation; - typedef [nopull,nopush,noprint] struct { - /* sizeis here is bogus, but this is here just for the structure */ - [size_is(1)] AuthenticationInformation array[]; + /* count is not on the wire */ + typedef [public,nopull,nopush,gensize] struct { + uint32 count; + AuthenticationInformation array[count]; } AuthenticationInformationArray; - /* This is nopull,nopush because we pass count down to the - * manual parser of AuthenticationInformationArray */ - typedef [public,nopull,nopush,noprint,gensize] struct { + /* we cannot use [relative] pointers here because Windows expects the + * previous_offset to match the total size of the struct in case + * the previous array is empty, see MS-LSAD 2.2.7.16 - gd */ + typedef [public,gensize,nopush] struct { uint32 count; - [relative] AuthenticationInformationArray *current; - [relative] AuthenticationInformationArray *previous; + [value((count > 0) ? 12 : 0)] uint32 current_offset; + [value((count > 0) ? 12 + ndr_size_AuthenticationInformationArray(¤t, ndr->flags) : 0)] uint32 previous_offset; + [subcontext(0),subcontext_size((previous_offset)-(current_offset))] AuthenticationInformationArray current; + [subcontext(0)] [flag(NDR_REMAINING)] AuthenticationInformationArray previous; } trustAuthInOutBlob; [nopython] void decode_trustAuthInOut( [in] trustAuthInOutBlob blob ); - typedef [public,gensize] struct { - uint32 count; - [relative] AuthenticationInformation *current[count]; - } trustCurrentPasswords; - typedef [public,nopull] struct { uint8 confounder[512]; - [subcontext(0),subcontext_size(outgoing_size)] trustCurrentPasswords outgoing; - [subcontext(0),subcontext_size(incoming_size)] trustCurrentPasswords incoming; - [value(ndr_size_trustCurrentPasswords(&outgoing, ndr->flags))] uint32 outgoing_size; - [value(ndr_size_trustCurrentPasswords(&incoming, ndr->flags))] uint32 incoming_size; + [subcontext(0),subcontext_size(outgoing_size)] trustAuthInOutBlob outgoing; + [subcontext(0),subcontext_size(incoming_size)] trustAuthInOutBlob incoming; + [value(ndr_size_trustAuthInOutBlob(&outgoing, ndr->flags))] uint32 outgoing_size; + [value(ndr_size_trustAuthInOutBlob(&incoming, ndr->flags))] uint32 incoming_size; } trustDomainPasswords; [nopython] void decode_trustDomainPasswords( diff --git a/librpc/ndr/ndr_drsblobs.c b/librpc/ndr/ndr_drsblobs.c index 9b55c5d5e1e..51880bb46f7 100644 --- a/librpc/ndr/ndr_drsblobs.c +++ b/librpc/ndr/ndr_drsblobs.c @@ -4,6 +4,7 @@ Manually parsed structures found in the DRS protocol Copyright (C) Andrew Bartlett 2008 + Copyright (C) Guenther Deschner 2010 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 @@ -23,161 +24,71 @@ #include "librpc/gen_ndr/ndr_drsblobs.h" #include "../lib/util/asn1.h" -/* parser auto-generated by pidl, then hand-modified by abartlet */ - -/* Modified to have 'count' specified */ -static enum ndr_err_code ndr_push_AuthenticationInformationArray_with_count(struct ndr_push *ndr, int ndr_flags, int count, - const struct AuthenticationInformationArray *r) +_PUBLIC_ enum ndr_err_code ndr_push_AuthenticationInformationArray(struct ndr_push *ndr, int ndr_flags, const struct AuthenticationInformationArray *r) { uint32_t cntr_array_0; if (ndr_flags & NDR_SCALARS) { NDR_CHECK(ndr_push_align(ndr, 4)); - for (cntr_array_0 = 0; cntr_array_0 < count; cntr_array_0++) { + for (cntr_array_0 = 0; cntr_array_0 < r->count; cntr_array_0++) { NDR_CHECK(ndr_push_AuthenticationInformation(ndr, NDR_SCALARS, &r->array[cntr_array_0])); } + NDR_CHECK(ndr_push_trailer_align(ndr, 4)); } if (ndr_flags & NDR_BUFFERS) { - for (cntr_array_0 = 0; cntr_array_0 < count; cntr_array_0++) { - NDR_CHECK(ndr_push_AuthenticationInformation(ndr, NDR_BUFFERS, &r->array[cntr_array_0])); - } } return NDR_ERR_SUCCESS; } -/* Modified to have 'count' specified, and to allocate the array */ -static enum ndr_err_code ndr_pull_AuthenticationInformationArray_with_count(struct ndr_pull *ndr, int ndr_flags, int count, struct AuthenticationInformationArray *r) +_PUBLIC_ enum ndr_err_code ndr_pull_AuthenticationInformationArray(struct ndr_pull *ndr, int ndr_flags, struct AuthenticationInformationArray *r) { - uint32_t cntr_array_0; - TALLOC_CTX *_mem_save_array_0; if (ndr_flags & NDR_SCALARS) { - NDR_CHECK(ndr_pull_align(ndr, 4)); - NDR_PULL_ALLOC_N(ndr, r->array, count); - _mem_save_array_0 = NDR_PULL_GET_MEM_CTX(ndr); - NDR_PULL_SET_MEM_CTX(ndr, r->array, 0); - for (cntr_array_0 = 0; cntr_array_0 < count; cntr_array_0++) { - NDR_CHECK(ndr_pull_AuthenticationInformation(ndr, NDR_SCALARS, &r->array[cntr_array_0])); + r->count = 0; + NDR_PULL_ALLOC_N(ndr, r->array, r->count); + /* entry is at least 16 bytes large */ + while (ndr->offset + 16 <= ndr->data_size) { + r->array = talloc_realloc(ndr, r->array, struct AuthenticationInformation, r->count + 1); + NDR_ERR_HAVE_NO_MEMORY(r->array); + NDR_CHECK(ndr_pull_AuthenticationInformation(ndr, NDR_SCALARS, &r->array[r->count])); + r->count++; } - NDR_PULL_SET_MEM_CTX(ndr, _mem_save_array_0, 0); + NDR_CHECK(ndr_pull_trailer_align(ndr, 4)); } if (ndr_flags & NDR_BUFFERS) { - for (cntr_array_0 = 0; cntr_array_0 < count; cntr_array_0++) { - NDR_CHECK(ndr_pull_AuthenticationInformation(ndr, NDR_BUFFERS, &r->array[cntr_array_0])); - } } return NDR_ERR_SUCCESS; } -/* Modified to have 'count' specified */ -_PUBLIC_ void ndr_print_AuthenticationInformationArray_with_count(struct ndr_print *ndr, const char *name, int count, const struct AuthenticationInformationArray *r) -{ - uint32_t cntr_array_0; - ndr_print_struct(ndr, name, "AuthenticationInformationArray"); - ndr->depth++; - ndr->print(ndr, "%s: ARRAY(%d)", "array", (int)1); - ndr->depth++; - for (cntr_array_0=0;cntr_array_0array[cntr_array_0]); - free(idx_0); - } - } - ndr->depth--; - ndr->depth--; -} - -/* Modified to call AuthenticationInformationArray with 'count' specified */ _PUBLIC_ enum ndr_err_code ndr_push_trustAuthInOutBlob(struct ndr_push *ndr, int ndr_flags, const struct trustAuthInOutBlob *r) { if (ndr_flags & NDR_SCALARS) { NDR_CHECK(ndr_push_align(ndr, 4)); NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, r->count)); - NDR_CHECK(ndr_push_relative_ptr1(ndr, r->current)); - NDR_CHECK(ndr_push_relative_ptr1(ndr, r->previous)); - } - if (ndr_flags & NDR_BUFFERS) { - if (r->current) { - NDR_CHECK(ndr_push_relative_ptr2_start(ndr, r->current)); - NDR_CHECK(ndr_push_AuthenticationInformationArray_with_count(ndr, NDR_SCALARS|NDR_BUFFERS, r->count, r->current)); - NDR_CHECK(ndr_push_relative_ptr2_end(ndr, r->current)); - } - if (r->previous) { - NDR_CHECK(ndr_push_relative_ptr2_start(ndr, r->previous)); - NDR_CHECK(ndr_push_AuthenticationInformationArray_with_count(ndr, NDR_SCALARS|NDR_BUFFERS, r->count, r->previous)); - NDR_CHECK(ndr_push_relative_ptr2_end(ndr, r->previous)); - } - } - return NDR_ERR_SUCCESS; -} - -_PUBLIC_ enum ndr_err_code ndr_pull_trustAuthInOutBlob(struct ndr_pull *ndr, int ndr_flags, struct trustAuthInOutBlob *r) -{ - uint32_t _ptr_current; - TALLOC_CTX *_mem_save_current_0; - uint32_t _ptr_previous; - TALLOC_CTX *_mem_save_previous_0; - if (ndr_flags & NDR_SCALARS) { - NDR_CHECK(ndr_pull_align(ndr, 4)); - NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->count)); - NDR_CHECK(ndr_pull_generic_ptr(ndr, &_ptr_current)); - if (_ptr_current) { - NDR_PULL_ALLOC(ndr, r->current); - NDR_CHECK(ndr_pull_relative_ptr1(ndr, r->current, _ptr_current)); - } else { - r->current = NULL; + NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, (r->count > 0)?12:0)); + NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, (r->count > 0)?12 + ndr_size_AuthenticationInformationArray(&r->current, ndr_flags):0)); + { + struct ndr_push *_ndr_current; + NDR_CHECK(ndr_push_subcontext_start(ndr, &_ndr_current, 0, ((r->count > 0)?12 + ndr_size_AuthenticationInformationArray(&r->current, ndr_flags):0) - ((r->count > 0)?12:0))); + NDR_CHECK(ndr_push_AuthenticationInformationArray(_ndr_current, NDR_SCALARS, &r->current)); + NDR_CHECK(ndr_push_subcontext_end(ndr, _ndr_current, 0, ((r->count > 0)?12 + ndr_size_AuthenticationInformationArray(&r->current, ndr_flags):0) - ((r->count > 0)?12:0))); } - NDR_CHECK(ndr_pull_generic_ptr(ndr, &_ptr_previous)); - if (_ptr_previous) { - NDR_PULL_ALLOC(ndr, r->previous); - NDR_CHECK(ndr_pull_relative_ptr1(ndr, r->previous, _ptr_previous)); - } else { - r->previous = NULL; + { + uint32_t _flags_save_AuthenticationInformationArray = ndr->flags; + ndr_set_flags(&ndr->flags, LIBNDR_FLAG_REMAINING); + { + struct ndr_push *_ndr_previous; + NDR_CHECK(ndr_push_subcontext_start(ndr, &_ndr_previous, 0, -1)); + NDR_CHECK(ndr_push_AuthenticationInformationArray(_ndr_previous, NDR_SCALARS, &r->previous)); + NDR_CHECK(ndr_push_subcontext_end(ndr, _ndr_previous, 0, -1)); + } + ndr->flags = _flags_save_AuthenticationInformationArray; } + NDR_CHECK(ndr_push_trailer_align(ndr, 4)); } if (ndr_flags & NDR_BUFFERS) { - if (r->current) { - uint32_t _relative_save_offset; - _relative_save_offset = ndr->offset; - NDR_CHECK(ndr_pull_relative_ptr2(ndr, r->current)); - _mem_save_current_0 = NDR_PULL_GET_MEM_CTX(ndr); - NDR_PULL_SET_MEM_CTX(ndr, r->current, 0); - NDR_CHECK(ndr_pull_AuthenticationInformationArray_with_count(ndr, NDR_SCALARS|NDR_BUFFERS, r->count, r->current)); - NDR_PULL_SET_MEM_CTX(ndr, _mem_save_current_0, 0); - ndr->offset = _relative_save_offset; - } - if (r->previous) { - uint32_t _relative_save_offset; - _relative_save_offset = ndr->offset; - NDR_CHECK(ndr_pull_relative_ptr2(ndr, r->previous)); - _mem_save_previous_0 = NDR_PULL_GET_MEM_CTX(ndr); - NDR_PULL_SET_MEM_CTX(ndr, r->previous, 0); - NDR_CHECK(ndr_pull_AuthenticationInformationArray_with_count(ndr, NDR_SCALARS|NDR_BUFFERS, r->count, r->previous)); - NDR_PULL_SET_MEM_CTX(ndr, _mem_save_previous_0, 0); - ndr->offset = _relative_save_offset; - } } return NDR_ERR_SUCCESS; } -_PUBLIC_ void ndr_print_trustAuthInOutBlob(struct ndr_print *ndr, const char *name, const struct trustAuthInOutBlob *r) -{ - ndr_print_struct(ndr, name, "trustAuthInOutBlob"); - ndr->depth++; - ndr_print_uint32(ndr, "count", r->count); - ndr_print_ptr(ndr, "current", r->current); - ndr->depth++; - if (r->current) { - ndr_print_AuthenticationInformationArray_with_count(ndr, "current", r->count, r->current); - } - ndr->depth--; - ndr_print_ptr(ndr, "previous", r->previous); - ndr->depth++; - if (r->previous) { - ndr_print_AuthenticationInformationArray_with_count(ndr, "previous", r->count, r->previous); - } - ndr->depth--; - ndr->depth--; -} _PUBLIC_ enum ndr_err_code ndr_pull_trustDomainPasswords(struct ndr_pull *ndr, int ndr_flags, struct trustDomainPasswords *r) { @@ -197,13 +108,13 @@ _PUBLIC_ enum ndr_err_code ndr_pull_trustDomainPasswords(struct ndr_pull *ndr, i { struct ndr_pull *_ndr_outgoing; NDR_CHECK(ndr_pull_subcontext_start(ndr, &_ndr_outgoing, 0, r->outgoing_size)); - NDR_CHECK(ndr_pull_trustCurrentPasswords(_ndr_outgoing, NDR_SCALARS|NDR_BUFFERS, &r->outgoing)); + NDR_CHECK(ndr_pull_trustAuthInOutBlob(_ndr_outgoing, NDR_SCALARS|NDR_BUFFERS, &r->outgoing)); NDR_CHECK(ndr_pull_subcontext_end(ndr, _ndr_outgoing, 0, r->outgoing_size)); } { struct ndr_pull *_ndr_incoming; NDR_CHECK(ndr_pull_subcontext_start(ndr, &_ndr_incoming, 0, r->incoming_size)); - NDR_CHECK(ndr_pull_trustCurrentPasswords(_ndr_incoming, NDR_SCALARS|NDR_BUFFERS, &r->incoming)); + NDR_CHECK(ndr_pull_trustAuthInOutBlob(_ndr_incoming, NDR_SCALARS|NDR_BUFFERS, &r->incoming)); NDR_CHECK(ndr_pull_subcontext_end(ndr, _ndr_incoming, 0, r->incoming_size)); } NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->outgoing_size)); diff --git a/librpc/ndr/ndr_drsblobs.h b/librpc/ndr/ndr_drsblobs.h index 255bba61178..eb7993c3142 100644 --- a/librpc/ndr/ndr_drsblobs.h +++ b/librpc/ndr/ndr_drsblobs.h @@ -19,9 +19,5 @@ along with this program. If not, see . */ -_PUBLIC_ void ndr_print_AuthenticationInformationArray_with_count(struct ndr_print *ndr, const char *name, int count, const struct AuthenticationInformationArray *r); -_PUBLIC_ enum ndr_err_code ndr_push_trustAuthInOutBlob(struct ndr_push *ndr, int ndr_flags, const struct trustAuthInOutBlob *r); -_PUBLIC_ enum ndr_err_code ndr_pull_trustAuthInOutBlob(struct ndr_pull *ndr, int ndr_flags, struct trustAuthInOutBlob *r); -_PUBLIC_ void ndr_print_trustAuthInOutBlob(struct ndr_print *ndr, const char *name, const struct trustAuthInOutBlob *r); _PUBLIC_ enum ndr_err_code ndr_pull_trustDomainPasswords(struct ndr_pull *ndr, int ndr_flags, struct trustDomainPasswords *r); _PUBLIC_ void ndr_print_drsuapi_MSPrefixMap_Entry(struct ndr_print *ndr, const char *name, const struct drsuapi_MSPrefixMap_Entry *r); diff --git a/source4/kdc/db-glue.c b/source4/kdc/db-glue.c index c8bbea75317..8e311b439b0 100644 --- a/source4/kdc/db-glue.c +++ b/source4/kdc/db-glue.c @@ -834,15 +834,15 @@ static krb5_error_code samba_kdc_trust_message2entry(krb5_context context, entry_ex->entry.kvno = -1; for (i=0; i < password_blob.count; i++) { - if (password_blob.current->array[i].AuthType == TRUST_AUTH_TYPE_VERSION) { - entry_ex->entry.kvno = password_blob.current->array[i].AuthInfo.version.version; + if (password_blob.current.array[i].AuthType == TRUST_AUTH_TYPE_VERSION) { + entry_ex->entry.kvno = password_blob.current.array[i].AuthInfo.version.version; } } for (i=0; i < password_blob.count; i++) { - if (password_blob.current->array[i].AuthType == TRUST_AUTH_TYPE_CLEAR) { - password_utf16 = data_blob_const(password_blob.current->array[i].AuthInfo.clear.password, - password_blob.current->array[i].AuthInfo.clear.size); + if (password_blob.current.array[i].AuthType == TRUST_AUTH_TYPE_CLEAR) { + password_utf16 = data_blob_const(password_blob.current.array[i].AuthInfo.clear.password, + password_blob.current.array[i].AuthInfo.clear.size); /* In the future, generate all sorts of * hashes, but for now we can't safely convert * the random strings windows uses into @@ -851,8 +851,8 @@ static krb5_error_code samba_kdc_trust_message2entry(krb5_context context, /* but as it is utf16 already, we can get the NT password/arcfour-hmac-md5 key */ mdfour(password_hash.hash, password_utf16.data, password_utf16.length); break; - } else if (password_blob.current->array[i].AuthType == TRUST_AUTH_TYPE_NT4OWF) { - password_hash = password_blob.current->array[i].AuthInfo.nt4owf.password; + } else if (password_blob.current.array[i].AuthType == TRUST_AUTH_TYPE_NT4OWF) { + password_hash = password_blob.current.array[i].AuthInfo.nt4owf.password; break; } } diff --git a/source4/rpc_server/lsa/dcesrv_lsa.c b/source4/rpc_server/lsa/dcesrv_lsa.c index 37e807bfe9a..f56d49a1503 100644 --- a/source4/rpc_server/lsa/dcesrv_lsa.c +++ b/source4/rpc_server/lsa/dcesrv_lsa.c @@ -761,43 +761,13 @@ static NTSTATUS get_trustdom_auth_blob(struct dcesrv_call_state *dce_call, static NTSTATUS get_trustauth_inout_blob(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, - struct trustCurrentPasswords *iopw, + struct trustAuthInOutBlob *iopw, DATA_BLOB *trustauth_blob) { - uint32_t i; - struct trustAuthInOutBlob ioblob; enum ndr_err_code ndr_err; - ioblob.count = iopw->count; - ioblob.current = talloc(mem_ctx, - struct AuthenticationInformationArray); - if (!ioblob.current) { - return NT_STATUS_NO_MEMORY; - } - - ioblob.current->array = *iopw->current; - if (!ioblob.current->array) { - return NT_STATUS_NO_MEMORY; - } - - ioblob.previous = talloc(mem_ctx, - struct AuthenticationInformationArray); - if (!ioblob.previous) { - return NT_STATUS_NO_MEMORY; - } - ioblob.previous->array = talloc_array(mem_ctx, - struct AuthenticationInformation, - ioblob.count); - if (!ioblob.previous->array) { - return NT_STATUS_NO_MEMORY; - } - - for (i = 0; i < ioblob.count; i++) { - ioblob.previous->array[i].LastUpdateTime = 0; - ioblob.previous->array[i].AuthType = 0; - } ndr_err = ndr_push_struct_blob(trustauth_blob, mem_ctx, - &ioblob, + iopw, (ndr_push_flags_fn_t)ndr_push_trustAuthInOutBlob); if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { return NT_STATUS_INVALID_PARAMETER; @@ -810,7 +780,7 @@ static NTSTATUS add_trust_user(TALLOC_CTX *mem_ctx, struct ldb_context *sam_ldb, struct ldb_dn *base_dn, const char *netbios_name, - struct trustCurrentPasswords *in, + struct trustAuthInOutBlob *in, struct ldb_dn **user_dn) { struct ldb_message *msg; @@ -851,16 +821,16 @@ static NTSTATUS add_trust_user(TALLOC_CTX *mem_ctx, for (i = 0; i < in->count; i++) { const char *attribute; struct ldb_val v; - switch (in->current[i]->AuthType) { + switch (in->current.array[i].AuthType) { case TRUST_AUTH_TYPE_NT4OWF: attribute = "unicodePwd"; - v.data = (uint8_t *)&in->current[i]->AuthInfo.nt4owf.password; + v.data = (uint8_t *)&in->current.array[i].AuthInfo.nt4owf.password; v.length = 16; break; case TRUST_AUTH_TYPE_CLEAR: attribute = "clearTextPassword"; - v.data = in->current[i]->AuthInfo.clear.password; - v.length = in->current[i]->AuthInfo.clear.size; + v.data = in->current.array[i].AuthInfo.clear.password; + v.length = in->current.array[i].AuthInfo.clear.size; break; default: continue; @@ -1504,7 +1474,7 @@ static NTSTATUS update_trust_user(TALLOC_CTX *mem_ctx, struct ldb_dn *base_dn, bool delete_user, const char *netbios_name, - struct trustCurrentPasswords *in) + struct trustAuthInOutBlob *in) { const char *attrs[] = { "userAccountControl", NULL }; struct ldb_message **msgs; @@ -1563,16 +1533,16 @@ static NTSTATUS update_trust_user(TALLOC_CTX *mem_ctx, for (i = 0; i < in->count; i++) { const char *attribute; struct ldb_val v; - switch (in->current[i]->AuthType) { + switch (in->current.array[i].AuthType) { case TRUST_AUTH_TYPE_NT4OWF: attribute = "unicodePwd"; - v.data = (uint8_t *)&in->current[i]->AuthInfo.nt4owf.password; + v.data = (uint8_t *)&in->current.array[i].AuthInfo.nt4owf.password; v.length = 16; break; case TRUST_AUTH_TYPE_CLEAR: attribute = "clearTextPassword"; - v.data = in->current[i]->AuthInfo.clear.password; - v.length = in->current[i]->AuthInfo.clear.size; + v.data = in->current.array[i].AuthInfo.clear.password; + v.length = in->current.array[i].AuthInfo.clear.size; break; default: continue; -- 2.11.4.GIT