diff options
Diffstat (limited to 'source4')
-rw-r--r-- | source4/librpc/config.mk | 2 | ||||
-rw-r--r-- | source4/librpc/idl/drsuapi.idl | 9 | ||||
-rw-r--r-- | source4/librpc/ndr/ndr_drsuapi.c | 106 | ||||
-rw-r--r-- | source4/librpc/ndr/ndr_drsuapi.h | 36 |
4 files changed, 148 insertions, 5 deletions
diff --git a/source4/librpc/config.mk b/source4/librpc/config.mk index 8dbf11b0c4..50bab003eb 100644 --- a/source4/librpc/config.mk +++ b/source4/librpc/config.mk @@ -114,7 +114,7 @@ PUBLIC_DEPENDENCIES = LIBNDR VERSION = 0.0.1 SO_VERSION = 0 OBJ_FILES = gen_ndr/ndr_drsuapi.o ndr/ndr_drsuapi.o -PUBLIC_DEPENDENCIES = LIBNDR NDR_COMPRESSION NDR_SECURITY NDR_SAMR +PUBLIC_DEPENDENCIES = LIBNDR NDR_COMPRESSION NDR_SECURITY NDR_SAMR ASN1_UTIL [LIBRARY::NDR_DRSBLOBS] VERSION = 0.0.1 diff --git a/source4/librpc/idl/drsuapi.idl b/source4/librpc/idl/drsuapi.idl index cc2787523c..119e0b1b3e 100644 --- a/source4/librpc/idl/drsuapi.idl +++ b/source4/librpc/idl/drsuapi.idl @@ -8,8 +8,9 @@ import "security.idl", "misc.idl", "samr.idl"; endpoint("ncacn_np:[\\pipe\\lsass]","ncacn_np:[\\pipe\\protected_storage]", "ncacn_ip_tcp:", "ncalrpc:"), authservice("ldap"), helpstring("Active Directory Replication"), + helper("librpc/ndr/ndr_drsuapi.h"), pointer_default(unique) -] +] interface drsuapi { declare bitmap samr_GroupAttrs; @@ -325,9 +326,9 @@ interface drsuapi * * 2.5.5.17 => dom_sid */ - typedef [flag(NDR_PAHEX)] struct { - [range(0,10000)] uint32 length; - [size_is(length)] uint8 *data; + typedef [nopush,nopull] struct { + [range(0,10000),value(ndr_size_drsuapi_DsReplicaOID_oid(r->oid, 0))] uint32 __ndr_size; + [size_is(__ndr_size),charset(DOS)] uint8 *oid; /* it's encoded with asn1_write_OID_String() */ } drsuapi_DsReplicaOID; typedef struct { diff --git a/source4/librpc/ndr/ndr_drsuapi.c b/source4/librpc/ndr/ndr_drsuapi.c index 614d567e03..37c78a2c80 100644 --- a/source4/librpc/ndr/ndr_drsuapi.c +++ b/source4/librpc/ndr/ndr_drsuapi.c @@ -24,6 +24,7 @@ #include "includes.h" #include "librpc/gen_ndr/ndr_drsuapi.h" #include "librpc/gen_ndr/ndr_misc.h" +#include "libcli/util/asn_1.h" void ndr_print_drsuapi_DsReplicaObjectListItem(struct ndr_print *ndr, const char *name, const struct drsuapi_DsReplicaObjectListItem *r) @@ -62,3 +63,108 @@ void ndr_print_drsuapi_DsReplicaObjectListItemEx(struct ndr_print *ndr, const ch ndr_print_drsuapi_DsReplicaObjectListItemEx(ndr, "next_object", r->next_object); } } + +#define _ASN1_PUSH_CHECK(call) do { \ + BOOL _status; \ + _status = call; \ + if (_status != True) { \ + return ndr_push_error(ndr, NDR_ERR_SUBCONTEXT, "ASN.1 Error: %s\n", __location__); \ + } \ +} while (0) + +#define _ASN1_PULL_CHECK(call) do { \ + BOOL _status; \ + _status = call; \ + if (_status != True) { \ + return ndr_pull_error(ndr, NDR_ERR_SUBCONTEXT, "ASN.1 Error: %s\n", __location__); \ + } \ +} while (0) + +NTSTATUS ndr_push_drsuapi_DsReplicaOID(struct ndr_push *ndr, int ndr_flags, const struct drsuapi_DsReplicaOID *r) +{ + if (ndr_flags & NDR_SCALARS) { + NDR_CHECK(ndr_push_align(ndr, 4)); + NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, ndr_size_drsuapi_DsReplicaOID_oid(r->oid, 0))); + NDR_CHECK(ndr_push_unique_ptr(ndr, r->oid)); + } + if (ndr_flags & NDR_BUFFERS) { + if (r->oid) { + struct asn1_data _asn1; + + ZERO_STRUCT(_asn1); + _ASN1_PUSH_CHECK(asn1_write_OID_String(&_asn1, r->oid)); + talloc_steal(ndr, _asn1.data); + + NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, _asn1.ofs)); + NDR_CHECK(ndr_push_array_uint8(ndr, NDR_SCALARS, _asn1.data, _asn1.ofs)); + asn1_free(&_asn1); + } + } + return NT_STATUS_OK; +} + +NTSTATUS ndr_pull_drsuapi_DsReplicaOID(struct ndr_pull *ndr, int ndr_flags, struct drsuapi_DsReplicaOID *r) +{ + uint32_t _ptr_oid; + TALLOC_CTX *_mem_save_oid_0; + if (ndr_flags & NDR_SCALARS) { + NDR_CHECK(ndr_pull_align(ndr, 4)); + NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->__ndr_size)); + if (r->__ndr_size < 0 || r->__ndr_size > 10000) { + return ndr_pull_error(ndr, NDR_ERR_RANGE, "value out of range"); + } + NDR_CHECK(ndr_pull_generic_ptr(ndr, &_ptr_oid)); + if (_ptr_oid) { + NDR_PULL_ALLOC(ndr, r->oid); + } else { + r->oid = NULL; + } + } + if (ndr_flags & NDR_BUFFERS) { + if (r->oid) { + DATA_BLOB _oid_array; + const char *_oid; + struct asn1_data _asn1; + + ZERO_STRUCT(_asn1); + + _mem_save_oid_0 = NDR_PULL_GET_MEM_CTX(ndr); + NDR_PULL_SET_MEM_CTX(ndr, ndr, 0); + NDR_CHECK(ndr_pull_array_size(ndr, &r->oid)); + _oid_array.length = ndr_get_array_size(ndr, &r->oid); + NDR_PULL_ALLOC_N(ndr, _oid_array.data, _oid_array.length); + NDR_CHECK(ndr_pull_array_uint8(ndr, NDR_SCALARS, _oid_array.data, _oid_array.length)); + NDR_PULL_SET_MEM_CTX(ndr, _mem_save_oid_0, 0); + + _ASN1_PULL_CHECK(asn1_load(&_asn1, _oid_array)); + talloc_steal(ndr, _asn1.data); + data_blob_free(&_oid_array); + _ASN1_PULL_CHECK(asn1_start_fake_tag(&_asn1)); + _ASN1_PULL_CHECK(asn1_read_OID_String(&_asn1, &_oid)); + talloc_steal(r->oid, _oid); + r->oid = _oid; + _ASN1_PULL_CHECK(asn1_end_tag(&_asn1)); + asn1_free(&_asn1); + } + if (r->oid) { + NDR_CHECK(ndr_check_array_size(ndr, (void*)&r->oid, r->__ndr_size)); + } + } + return NT_STATUS_OK; +} + +size_t ndr_size_drsuapi_DsReplicaOID_oid(const char *oid, int flags) +{ + struct asn1_data _asn1; + size_t ret = 0; + + if (!oid) return 0; + + ZERO_STRUCT(_asn1); + if (asn1_write_OID_String(&_asn1, oid)) { + ret = _asn1.ofs; + } + + asn1_free(&_asn1); + return ret; +} diff --git a/source4/librpc/ndr/ndr_drsuapi.h b/source4/librpc/ndr/ndr_drsuapi.h new file mode 100644 index 0000000000..05cb257063 --- /dev/null +++ b/source4/librpc/ndr/ndr_drsuapi.h @@ -0,0 +1,36 @@ +/* + Unix SMB/CIFS implementation. + + routines for printing some linked list structs in DRSUAPI + + Copyright (C) Stefan (metze) Metzmacher 2005-2006 + + 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 _LIBRPC_NDR_NDR_DRSUAPI_H +#define _LIBRPC_NDR_NDR_DRSUAPI_H + +void ndr_print_drsuapi_DsReplicaObjectListItem(struct ndr_print *ndr, const char *name, + const struct drsuapi_DsReplicaObjectListItem *r); + +void ndr_print_drsuapi_DsReplicaObjectListItemEx(struct ndr_print *ndr, const char *name, + const struct drsuapi_DsReplicaObjectListItemEx *r); + +NTSTATUS ndr_push_drsuapi_DsReplicaOID(struct ndr_push *ndr, int ndr_flags, const struct drsuapi_DsReplicaOID *r); +NTSTATUS ndr_pull_drsuapi_DsReplicaOID(struct ndr_pull *ndr, int ndr_flags, struct drsuapi_DsReplicaOID *r); +size_t ndr_size_drsuapi_DsReplicaOID_oid(const char *oid, int flags); + +#endif /* _LIBRPC_NDR_NDR_DRSUAPI_H */ |