summaryrefslogtreecommitdiff
path: root/source4/librpc
diff options
context:
space:
mode:
authorAndrew Bartlett <abartlet@samba.org>2008-08-26 16:26:08 +1000
committerAndrew Bartlett <abartlet@samba.org>2008-08-26 16:26:08 +1000
commitf08786686c0bf2440e35ce29b8e0b1a2f116fe3a (patch)
treefd7ac6f7cd8528c550952731347f03397c70df77 /source4/librpc
parentb5a3f45f645204bcc3d6caa47993b7839c8e4c99 (diff)
parent4eba234a7352094e1640e8ff9d80a20f8d4705a3 (diff)
downloadsamba-f08786686c0bf2440e35ce29b8e0b1a2f116fe3a.tar.gz
samba-f08786686c0bf2440e35ce29b8e0b1a2f116fe3a.tar.bz2
samba-f08786686c0bf2440e35ce29b8e0b1a2f116fe3a.zip
Merge branch 'v4-0-test' of ssh://git.samba.org/data/git/samba into pac-verify
(This used to be commit b706708210a05d6f10474a3cd2bbc550704d4356)
Diffstat (limited to 'source4/librpc')
-rw-r--r--source4/librpc/config.mk5
-rw-r--r--source4/librpc/idl/dcerpc.idl3
-rw-r--r--source4/librpc/idl/drsblobs.idl33
-rw-r--r--source4/librpc/idl/drsuapi.idl24
-rw-r--r--source4/librpc/idl/krb5pac.idl12
-rw-r--r--source4/librpc/idl/lsa.idl111
-rw-r--r--source4/librpc/idl/nbt.idl8
-rw-r--r--source4/librpc/idl/security.idl8
-rw-r--r--source4/librpc/ndr/ndr.c115
-rw-r--r--source4/librpc/ndr/ndr_compression.c377
-rw-r--r--source4/librpc/ndr/ndr_drsuapi.c173
-rw-r--r--source4/librpc/rpc/dcerpc.c17
12 files changed, 695 insertions, 191 deletions
diff --git a/source4/librpc/config.mk b/source4/librpc/config.mk
index d87683dd6f..b68d5e6a69 100644
--- a/source4/librpc/config.mk
+++ b/source4/librpc/config.mk
@@ -43,7 +43,8 @@ MANPAGES += $(librpcsrcdir)/tools/ndrdump.1
################################################
# Start SUBSYSTEM NDR_COMPRESSION
[SUBSYSTEM::NDR_COMPRESSION]
-PUBLIC_DEPENDENCIES = LIBCOMPRESSION LIBSAMBA-ERRORS LIBNDR
+PRIVATE_DEPENDENCIES = ZLIB LZXPRESS
+PUBLIC_DEPENDENCIES = LIBSAMBA-ERRORS LIBNDR
# End SUBSYSTEM NDR_COMPRESSION
################################################
@@ -133,7 +134,7 @@ PUBLIC_DEPENDENCIES = LIBNDR NDR_COMPRESSION NDR_SECURITY NDR_SAMR ASN1_UTIL
NDR_DRSUAPI_OBJ_FILES = $(gen_ndrsrcdir)/ndr_drsuapi.o $(ndrsrcdir)/ndr_drsuapi.o
[SUBSYSTEM::NDR_DRSBLOBS]
-PUBLIC_DEPENDENCIES = LIBNDR NDR_MISC NDR_DRSUAPI
+PUBLIC_DEPENDENCIES = LIBNDR NDR_MISC NDR_DRSUAPI LIBCLI_DRSBLOBS
NDR_DRSBLOBS_OBJ_FILES = $(gen_ndrsrcdir)/ndr_drsblobs.o
diff --git a/source4/librpc/idl/dcerpc.idl b/source4/librpc/idl/dcerpc.idl
index e54bc2c29f..1c6574b11b 100644
--- a/source4/librpc/idl/dcerpc.idl
+++ b/source4/librpc/idl/dcerpc.idl
@@ -30,7 +30,6 @@ interface dcerpc
} dcerpc_bind;
const uint8 DCERPC_REQUEST_LENGTH = 24;
- const uint8 DCERPC_MAX_SIGN_SIZE = 64;
typedef struct {
} dcerpc_empty;
@@ -154,6 +153,8 @@ interface dcerpc
[flag(NDR_REMAINING)] DATA_BLOB credentials;
} dcerpc_auth;
+ const uint8 DCERPC_AUTH_TRAILER_LENGTH = 8;
+
typedef [public] struct {
uint32 _pad;
[flag(NDR_REMAINING)] DATA_BLOB auth_info;
diff --git a/source4/librpc/idl/drsblobs.idl b/source4/librpc/idl/drsblobs.idl
index b0cddfcdf9..eb85989eda 100644
--- a/source4/librpc/idl/drsblobs.idl
+++ b/source4/librpc/idl/drsblobs.idl
@@ -401,7 +401,7 @@ interface drsblobs {
[case(TRUST_AUTH_TYPE_VERSION)] AuthInfoVersion version;
} AuthInfo;
- typedef struct {
+ typedef [public] struct {
NTTIME LastUpdateTime;
trustAuthType AuthType;
@@ -422,32 +422,15 @@ interface drsblobs {
[flag(NDR_ALIGN4)] DATA_BLOB _pad;
} AuthenticationInformation;
- typedef struct {
- AuthenticationInformation info[1];
- } AuthenticationInformation1;
-
- typedef struct {
- AuthenticationInformation info[2];
- } AuthenticationInformation2;
-
- typedef struct {
- [relative] AuthenticationInformation1 *current;
- [relative] AuthenticationInformation1 *previous;
- } AuthenticationInformationCtr1;
-
- typedef struct {
- [relative] AuthenticationInformation2 *current;
- [relative] AuthenticationInformation2 *previous;
- } AuthenticationInformationCtr2;
+ typedef [nopull,nopush,noprint] struct {
+ /* sizeis here is bogus, but this is here just for the structure */
+ [size_is(1)] AuthenticationInformation array[];
+ } AuthenticationInformationArray;
- typedef [nodiscriminant] union {
- [case(1)] AuthenticationInformationCtr1 info1;
- [case(2)] AuthenticationInformationCtr2 info2;
- } AuthenticationInformationCtr;
-
- typedef [public] struct {
+ typedef [public,nopull,nopush,noprint] struct {
uint32 count;
- [switch_is(count)] AuthenticationInformationCtr auth;
+ [relative] AuthenticationInformationArray *current;
+ [relative] AuthenticationInformationArray *previous;
} trustAuthInOutBlob;
void decode_trustAuthInOut(
diff --git a/source4/librpc/idl/drsuapi.idl b/source4/librpc/idl/drsuapi.idl
index 88d2126d0b..cc76599be6 100644
--- a/source4/librpc/idl/drsuapi.idl
+++ b/source4/librpc/idl/drsuapi.idl
@@ -617,36 +617,44 @@ interface drsuapi
WERROR drs_error;
} drsuapi_DsGetNCChangesCtr6;
- typedef struct {
+ typedef [public] struct {
+ [subcontext(0xFFFFFC01)] drsuapi_DsGetNCChangesCtr1 ctr1;
+ } drsuapi_DsGetNCChangesCtr1TS;
+
+ typedef [public] struct {
+ [subcontext(0xFFFFFC01)] drsuapi_DsGetNCChangesCtr6 ctr6;
+ } drsuapi_DsGetNCChangesCtr6TS;
+
+ typedef [nopush] struct {
uint32 decompressed_length;
uint32 compressed_length;
[subcontext(4),subcontext_size(compressed_length),
compression(NDR_COMPRESSION_MSZIP,compressed_length,decompressed_length)]
- drsuapi_DsGetNCChangesCtr1 *ctr1;
+ drsuapi_DsGetNCChangesCtr1TS *ts;
} drsuapi_DsGetNCChangesMSZIPCtr1;
- typedef struct {
+ typedef [nopush] struct {
uint32 decompressed_length;
uint32 compressed_length;
[subcontext(4),subcontext_size(compressed_length),
compression(NDR_COMPRESSION_MSZIP,compressed_length,decompressed_length)]
- drsuapi_DsGetNCChangesCtr6 *ctr6;
+ drsuapi_DsGetNCChangesCtr6TS *ts;
} drsuapi_DsGetNCChangesMSZIPCtr6;
- typedef struct {
+ typedef [nopush] struct {
uint32 decompressed_length;
uint32 compressed_length;
[subcontext(4),subcontext_size(compressed_length),
compression(NDR_COMPRESSION_XPRESS,compressed_length,decompressed_length)]
- drsuapi_DsGetNCChangesCtr1 *ctr1;
+ drsuapi_DsGetNCChangesCtr1TS *ts;
} drsuapi_DsGetNCChangesXPRESSCtr1;
- typedef struct {
+ typedef [nopush] struct {
uint32 decompressed_length;
uint32 compressed_length;
[subcontext(4),subcontext_size(compressed_length),
compression(NDR_COMPRESSION_XPRESS,compressed_length,decompressed_length)]
- drsuapi_DsGetNCChangesCtr6 *ctr6;
+ drsuapi_DsGetNCChangesCtr6TS *ts;
} drsuapi_DsGetNCChangesXPRESSCtr6;
typedef [enum16bit] enum {
diff --git a/source4/librpc/idl/krb5pac.idl b/source4/librpc/idl/krb5pac.idl
index 3505fc895c..ca0efaed3e 100644
--- a/source4/librpc/idl/krb5pac.idl
+++ b/source4/librpc/idl/krb5pac.idl
@@ -45,10 +45,6 @@ interface krb5pac
} PAC_UNKNOWN_12;
typedef [public] struct {
- [value(0x00081001)] uint32 unknown1;
- [value(0xCCCCCCCC)] uint32 unknown2;
- [value(NDR_ROUND(ndr_size_PAC_LOGON_INFO(info, ndr->flags)+4,8))] uint32 _ndr_size;
- [value(0x00000000)] uint32 unknown3;
PAC_LOGON_INFO *info;
} PAC_LOGON_INFO_CTR;
@@ -66,11 +62,15 @@ interface krb5pac
} DATA_BLOB_REM;
typedef [public,nodiscriminant,gensize] union {
- [case(PAC_TYPE_LOGON_INFO)] PAC_LOGON_INFO_CTR logon_info;
+ [case(PAC_TYPE_LOGON_INFO)][subcontext(0xFFFFFC01)] 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;
- [case(PAC_TYPE_UNKNOWN_12)] [subcontext(0)] DATA_BLOB_REM unknown;
+ /* when new PAC info types are added they are supposed to be done
+ in such a way that they are backwards compatible with existing
+ servers. This makes it safe to just use a [default] for
+ unknown types, which lets us ignore the data */
+ [default] [subcontext(0)] DATA_BLOB_REM unknown;
/* [case(PAC_TYPE_UNKNOWN_12)] PAC_UNKNOWN_12 unknown; */
} PAC_INFO;
diff --git a/source4/librpc/idl/lsa.idl b/source4/librpc/idl/lsa.idl
index 93cfdee201..408956b3fa 100644
--- a/source4/librpc/idl/lsa.idl
+++ b/source4/librpc/idl/lsa.idl
@@ -14,6 +14,7 @@ import "misc.idl", "security.idl";
] interface lsarpc
{
typedef bitmap security_secinfo security_secinfo;
+ typedef bitmap kerb_EncTypes kerb_EncTypes;
typedef [public,noejs] struct {
[value(2*strlen_m(string))] uint16 length;
@@ -507,22 +508,53 @@ import "misc.idl", "security.idl";
} lsa_DATA_BUF2;
typedef enum {
- LSA_TRUSTED_DOMAIN_INFO_NAME = 1,
- LSA_TRUSTED_DOMAIN_INFO_CONTROLLERS_INFO = 2,
- LSA_TRUSTED_DOMAIN_INFO_POSIX_OFFSET = 3,
- LSA_TRUSTED_DOMAIN_INFO_PASSWORD = 4,
- LSA_TRUSTED_DOMAIN_INFO_BASIC = 5,
- LSA_TRUSTED_DOMAIN_INFO_INFO_EX = 6,
- LSA_TRUSTED_DOMAIN_INFO_AUTH_INFO = 7,
- LSA_TRUSTED_DOMAIN_INFO_FULL_INFO = 8,
- LSA_TRUSTED_DOMAIN_INFO_11 = 11,
- LSA_TRUSTED_DOMAIN_INFO_INFO_ALL = 12
+ LSA_TRUSTED_DOMAIN_INFO_NAME = 1,
+ LSA_TRUSTED_DOMAIN_INFO_CONTROLLERS = 2,
+ LSA_TRUSTED_DOMAIN_INFO_POSIX_OFFSET = 3,
+ LSA_TRUSTED_DOMAIN_INFO_PASSWORD = 4,
+ LSA_TRUSTED_DOMAIN_INFO_BASIC = 5,
+ LSA_TRUSTED_DOMAIN_INFO_INFO_EX = 6,
+ LSA_TRUSTED_DOMAIN_INFO_AUTH_INFO = 7,
+ LSA_TRUSTED_DOMAIN_INFO_FULL_INFO = 8,
+ LSA_TRUSTED_DOMAIN_INFO_AUTH_INFO_INTERNAL = 9,
+ LSA_TRUSTED_DOMAIN_INFO_FULL_INFO_INTERNAL = 10,
+ LSA_TRUSTED_DOMAIN_INFO_INFO_EX2_INTERNAL = 11,
+ LSA_TRUSTED_DOMAIN_INFO_FULL_INFO_2_INTERNAL = 12,
+ LSA_TRUSTED_DOMAIN_SUPPORTED_ENCRTYPION_TYPES = 13
} lsa_TrustDomInfoEnum;
+ typedef [public,bitmap32bit] bitmap {
+ LSA_TRUST_DIRECTION_INBOUND = 0x00000001,
+ LSA_TRUST_DIRECTION_OUTBOUND = 0x00000002
+ } lsa_TrustDirection;
+
+ typedef [v1_enum] enum {
+ LSA_TRUST_TYPE_DOWNLEVEL = 0x00000001,
+ LSA_TRUST_TYPE_UPLEVEL = 0x00000002,
+ LSA_TRUST_TYPE_MIT = 0x00000003
+ } lsa_TrustType;
+
+ typedef [public,bitmap32bit] bitmap {
+ LSA_TRUST_ATTRIBUTE_NON_TRANSITIVE = 0x00000001,
+ LSA_TRUST_ATTRIBUTE_UPLEVEL_ONLY = 0x00000002,
+ LSA_TRUST_ATTRIBUTE_QUARANTINED_DOMAIN = 0x00000004,
+ LSA_TRUST_ATTRIBUTE_FOREST_TRANSITIVE = 0x00000008,
+ LSA_TRUST_ATTRIBUTE_CROSS_ORGANIZATION = 0x00000010,
+ LSA_TRUST_ATTRIBUTE_WITHIN_FOREST = 0x00000020,
+ LSA_TRUST_ATTRIBUTE_TREAT_AS_EXTERNAL = 0x00000040,
+ LSA_TRUST_ATTRIBUTE_USES_RC4_ENCRYPTION = 0x00000080
+ } lsa_TrustAttributes;
+
typedef struct {
lsa_StringLarge netbios_name;
} lsa_TrustDomainInfoName;
+
+ typedef struct {
+ uint32 entries;
+ [size_is(entries)] lsa_StringLarge *netbios_names;
+ } lsa_TrustDomainInfoControllers;
+
typedef struct {
uint32 posix_offset;
} lsa_TrustDomainInfoPosixOffset;
@@ -540,10 +572,10 @@ import "misc.idl", "security.idl";
typedef struct {
lsa_StringLarge domain_name;
lsa_StringLarge netbios_name;
- dom_sid2 *sid;
- uint32 trust_direction;
- uint32 trust_type;
- uint32 trust_attributes;
+ dom_sid2 *sid;
+ lsa_TrustDirection trust_direction;
+ lsa_TrustType trust_type;
+ lsa_TrustAttributes trust_attributes;
} lsa_TrustDomainInfoInfoEx;
typedef struct {
@@ -570,25 +602,46 @@ import "misc.idl", "security.idl";
typedef struct {
lsa_TrustDomainInfoInfoEx info_ex;
lsa_DATA_BUF2 data1;
- } lsa_TrustDomainInfo11;
+ } lsa_TrustDomainInfoInfoEx2Internal;
typedef struct {
lsa_TrustDomainInfoInfoEx info_ex;
lsa_DATA_BUF2 data1;
lsa_TrustDomainInfoPosixOffset posix_offset;
lsa_TrustDomainInfoAuthInfo auth_info;
- } lsa_TrustDomainInfoInfoAll;
+ } lsa_TrustDomainInfoInfo2Internal;
+
+ typedef struct {
+ kerb_EncTypes enc_types;
+ } lsa_TrustDomainInfoSupportedEncTypes;
typedef [switch_type(lsa_TrustDomInfoEnum)] union {
- [case(LSA_TRUSTED_DOMAIN_INFO_NAME)] lsa_TrustDomainInfoName name;
- [case(LSA_TRUSTED_DOMAIN_INFO_POSIX_OFFSET)] lsa_TrustDomainInfoPosixOffset posix_offset;
- [case(LSA_TRUSTED_DOMAIN_INFO_PASSWORD)] lsa_TrustDomainInfoPassword password;
- [case(LSA_TRUSTED_DOMAIN_INFO_BASIC)] lsa_TrustDomainInfoBasic info_basic;
- [case(LSA_TRUSTED_DOMAIN_INFO_INFO_EX)] lsa_TrustDomainInfoInfoEx info_ex;
- [case(LSA_TRUSTED_DOMAIN_INFO_AUTH_INFO)] lsa_TrustDomainInfoAuthInfo auth_info;
- [case(LSA_TRUSTED_DOMAIN_INFO_FULL_INFO)] lsa_TrustDomainInfoFullInfo full_info;
- [case(LSA_TRUSTED_DOMAIN_INFO_11)] lsa_TrustDomainInfo11 info11;
- [case(LSA_TRUSTED_DOMAIN_INFO_INFO_ALL)] lsa_TrustDomainInfoInfoAll info_all;
+ [case(LSA_TRUSTED_DOMAIN_INFO_NAME)]
+ lsa_TrustDomainInfoName name;
+ [case(LSA_TRUSTED_DOMAIN_INFO_CONTROLLERS)]
+ lsa_TrustDomainInfoControllers controllers;
+ [case(LSA_TRUSTED_DOMAIN_INFO_POSIX_OFFSET)]
+ lsa_TrustDomainInfoPosixOffset posix_offset;
+ [case(LSA_TRUSTED_DOMAIN_INFO_PASSWORD)]
+ lsa_TrustDomainInfoPassword password;
+ [case(LSA_TRUSTED_DOMAIN_INFO_BASIC)]
+ lsa_TrustDomainInfoBasic info_basic;
+ [case(LSA_TRUSTED_DOMAIN_INFO_INFO_EX)]
+ lsa_TrustDomainInfoInfoEx info_ex;
+ [case(LSA_TRUSTED_DOMAIN_INFO_AUTH_INFO)]
+ lsa_TrustDomainInfoAuthInfo auth_info;
+ [case(LSA_TRUSTED_DOMAIN_INFO_FULL_INFO)]
+ lsa_TrustDomainInfoFullInfo full_info;
+ [case(LSA_TRUSTED_DOMAIN_INFO_AUTH_INFO_INTERNAL)]
+ lsa_TrustDomainInfoAuthInfo auth_info_internal;
+ [case(LSA_TRUSTED_DOMAIN_INFO_FULL_INFO_INTERNAL)]
+ lsa_TrustDomainInfoFullInfo full_info_internal;
+ [case(LSA_TRUSTED_DOMAIN_INFO_INFO_EX2_INTERNAL)]
+ lsa_TrustDomainInfoInfoEx2Internal info_ex2_internal;
+ [case(LSA_TRUSTED_DOMAIN_INFO_FULL_INFO_2_INTERNAL)]
+ lsa_TrustDomainInfoInfo2Internal info2_internal;
+ [case(LSA_TRUSTED_DOMAIN_SUPPORTED_ENCRTYPION_TYPES)]
+ lsa_TrustDomainInfoSupportedEncTypes enc_types;
} lsa_TrustedDomainInfo;
/* Function: 0x1a */
@@ -658,8 +711,12 @@ import "misc.idl", "security.idl";
[in] uint16 unknown
);
- /* Function: 0x22 */
- [todo] NTSTATUS lsa_DeleteObject();
+ /*******************/
+ /* Function: 0x22 */
+ NTSTATUS lsa_DeleteObject (
+ [in,out] policy_handle *handle
+ );
+
/*******************/
diff --git a/source4/librpc/idl/nbt.idl b/source4/librpc/idl/nbt.idl
index a6d0245455..63be489e0d 100644
--- a/source4/librpc/idl/nbt.idl
+++ b/source4/librpc/idl/nbt.idl
@@ -353,7 +353,13 @@ interface nbt
NBT_SERVER_TIMESERV = 0x00000040,
NBT_SERVER_CLOSEST = 0x00000080,
NBT_SERVER_WRITABLE = 0x00000100,
- NBT_SERVER_GOOD_TIMESERV = 0x00000200
+ NBT_SERVER_GOOD_TIMESERV = 0x00000200,
+ NBT_SERVER_NDNC = 0x00000400,
+ NBT_SERVER_SEL_SEC_DOM_6 = 0x00000800,
+ NBT_SERVER_FUL_SEC_DOM_6 = 0x00001000,
+ NBT_SERVER_DS_DNS_CONTR = 0x04000000,
+ NBT_SERVER_DS_DNS_DOMAIN = 0x02000000,
+ NBT_SERVER_DS_DNS_FOREST = 0x01000000
} nbt_server_type;
typedef [bitmap32bit,public] bitmap {
diff --git a/source4/librpc/idl/security.idl b/source4/librpc/idl/security.idl
index f8e9e9e110..80efe46453 100644
--- a/source4/librpc/idl/security.idl
+++ b/source4/librpc/idl/security.idl
@@ -386,4 +386,12 @@ interface security
SECINFO_PROTECTED_SACL = 0x40000000,
SECINFO_PROTECTED_DACL = 0x80000000
} security_secinfo;
+
+ typedef [public,bitmap32bit] bitmap {
+ KERB_ENCTYPE_DES_CBC_CRC = 0x00000001,
+ KERB_ENCTYPE_DES_CBC_MD5 = 0x00000002,
+ KERB_ENCTYPE_RC4_HMAC_MD5 = 0x00000004,
+ KERB_ENCTYPE_AES128_CTS_HMAC_SHA1_96 = 0x00000008,
+ KERB_ENCTYPE_AES256_CTS_HMAC_SHA1_96 = 0x00000010
+ } kerb_EncTypes;
}
diff --git a/source4/librpc/ndr/ndr.c b/source4/librpc/ndr/ndr.c
index 40852456bc..c5e4c44794 100644
--- a/source4/librpc/ndr/ndr.c
+++ b/source4/librpc/ndr/ndr.c
@@ -394,6 +394,8 @@ _PUBLIC_ enum ndr_err_code ndr_pull_subcontext_start(struct ndr_pull *ndr,
{
struct ndr_pull *subndr;
uint32_t r_content_size;
+ bool force_le = false;
+ bool force_be = false;
switch (header_size) {
case 0: {
@@ -426,6 +428,74 @@ _PUBLIC_ enum ndr_err_code ndr_pull_subcontext_start(struct ndr_pull *ndr,
r_content_size = content_size;
break;
}
+ case 0xFFFFFC01: {
+ /*
+ * Common Type Header for the Serialization Stream
+ * See [MS-RPCE] 2.2.6 Type Serialization Version 1
+ */
+ uint8_t version;
+ uint8_t drep;
+ uint16_t hdrlen;
+ uint32_t filler;
+ uint32_t content_size;
+ uint32_t reserved;
+
+ /* version */
+ NDR_CHECK(ndr_pull_uint8(ndr, NDR_SCALARS, &version));
+
+ if (version != 1) {
+ return ndr_pull_error(ndr, NDR_ERR_SUBCONTEXT,
+ "Bad subcontext (PULL) Common Type Header version %d != 1",
+ (int)version);
+ }
+
+ /*
+ * 0x10 little endian
+ * 0x00 big endian
+ */
+ NDR_CHECK(ndr_pull_uint8(ndr, NDR_SCALARS, &drep));
+ if (drep == 0x10) {
+ force_le = true;
+ } else if (drep == 0x00) {
+ force_be = true;
+ } else {
+ return ndr_pull_error(ndr, NDR_ERR_SUBCONTEXT,
+ "Bad subcontext (PULL) Common Type Header invalid drep 0x%02X",
+ (unsigned int)drep);
+ }
+
+ /* length of the "Private Header for Constructed Type" */
+ NDR_CHECK(ndr_pull_uint16(ndr, NDR_SCALARS, &hdrlen));
+ if (hdrlen != 8) {
+ return ndr_pull_error(ndr, NDR_ERR_SUBCONTEXT,
+ "Bad subcontext (PULL) Common Type Header length %d != 8",
+ (int)hdrlen);
+ }
+
+ /* filler should be ignored */
+ NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &filler));
+
+ /*
+ * Private Header for Constructed Type
+ */
+ /* length - will be updated latter */
+ NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &content_size));
+ if (size_is >= 0 && size_is != content_size) {
+ return ndr_pull_error(ndr, NDR_ERR_SUBCONTEXT, "Bad subcontext (PULL) size_is(%d) mismatch content_size %d",
+ (int)size_is, (int)content_size);
+ }
+ /* the content size must be a multiple of 8 */
+ if ((content_size % 8) != 0) {
+ return ndr_pull_error(ndr, NDR_ERR_SUBCONTEXT,
+ "Bad subcontext (PULL) size_is(%d) not padded to 8 content_size %d",
+ (int)size_is, (int)content_size);
+ }
+ r_content_size = content_size;
+
+ /* reserved */
+ NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &reserved));
+ break;
+ }
default:
return ndr_pull_error(ndr, NDR_ERR_SUBCONTEXT, "Bad subcontext (PULL) header_size %d",
(int)header_size);
@@ -443,6 +513,12 @@ _PUBLIC_ enum ndr_err_code ndr_pull_subcontext_start(struct ndr_pull *ndr,
subndr->data_size = r_content_size;
subndr->iconv_convenience = talloc_reference(subndr, ndr->iconv_convenience);
+ if (force_le) {
+ ndr_set_flags(&ndr->flags, LIBNDR_FLAG_LITTLE_ENDIAN);
+ } else if (force_be) {
+ ndr_set_flags(&ndr->flags, LIBNDR_FLAG_BIGENDIAN);
+ }
+
*_subndr = subndr;
return NDR_ERR_SUCCESS;
}
@@ -487,8 +563,10 @@ _PUBLIC_ enum ndr_err_code ndr_push_subcontext_end(struct ndr_push *ndr,
size_t header_size,
ssize_t size_is)
{
+ ssize_t padding_len;
+
if (size_is >= 0) {
- ssize_t padding_len = size_is - subndr->offset;
+ padding_len = size_is - subndr->offset;
if (padding_len > 0) {
NDR_CHECK(ndr_push_zero(subndr, padding_len));
} else if (padding_len < 0) {
@@ -509,6 +587,41 @@ _PUBLIC_ enum ndr_err_code ndr_push_subcontext_end(struct ndr_push *ndr,
NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, subndr->offset));
break;
+ case 0xFFFFFC01:
+ /*
+ * Common Type Header for the Serialization Stream
+ * See [MS-RPCE] 2.2.6 Type Serialization Version 1
+ */
+ padding_len = NDR_ROUND(subndr->offset, 8) - subndr->offset;
+ if (padding_len > 0) {
+ NDR_CHECK(ndr_push_zero(subndr, padding_len));
+ }
+
+ /* version */
+ NDR_CHECK(ndr_push_uint8(ndr, NDR_SCALARS, 1));
+
+ /*
+ * 0x10 little endian
+ * 0x00 big endian
+ */
+ NDR_CHECK(ndr_push_uint8(ndr, NDR_SCALARS, NDR_BE(ndr)?0x00:0x10));
+
+ /* length of the "Private Header for Constructed Type" */
+ NDR_CHECK(ndr_push_uint16(ndr, NDR_SCALARS, 8));
+
+ /* filler */
+ NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, 0xCCCCCCCC));
+
+ /*
+ * Private Header for Constructed Type
+ */
+ /* length - will be updated latter */
+ NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, subndr->offset));
+
+ /* reserved */
+ NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, 0));
+ break;
+
default:
return ndr_push_error(ndr, NDR_ERR_SUBCONTEXT, "Bad subcontext header size %d",
(int)header_size);
diff --git a/source4/librpc/ndr/ndr_compression.c b/source4/librpc/ndr/ndr_compression.c
index 86a5a2560e..37f95bb1b6 100644
--- a/source4/librpc/ndr/ndr_compression.c
+++ b/source4/librpc/ndr/ndr_compression.c
@@ -4,6 +4,7 @@
libndr compression support
Copyright (C) Stefan Metzmacher 2005
+ Copyright (C) Matthieu Suiche 2008
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
@@ -20,13 +21,24 @@
*/
#include "includes.h"
-#include "lib/compression/mszip.h"
+#include "lib/compression/lzxpress.h"
#include "librpc/ndr/libndr.h"
#include "librpc/ndr/ndr_compression.h"
+#include <zlib.h>
+
+static voidpf ndr_zlib_alloc(voidpf opaque, uInt items, uInt size)
+{
+ return talloc_zero_size(opaque, items * size);
+}
+
+static void ndr_zlib_free(voidpf opaque, voidpf address)
+{
+ talloc_free(address);
+}
static enum ndr_err_code ndr_pull_compression_mszip_chunk(struct ndr_pull *ndrpull,
struct ndr_push *ndrpush,
- struct decomp_state *decomp_state,
+ z_stream *z,
bool *last)
{
DATA_BLOB comp_chunk;
@@ -35,7 +47,7 @@ static enum ndr_err_code ndr_pull_compression_mszip_chunk(struct ndr_pull *ndrpu
DATA_BLOB plain_chunk;
uint32_t plain_chunk_offset;
uint32_t plain_chunk_size;
- int ret;
+ int z_ret;
NDR_CHECK(ndr_pull_uint32(ndrpull, NDR_SCALARS, &plain_chunk_size));
if (plain_chunk_size > 0x00008000) {
@@ -58,10 +70,71 @@ static enum ndr_err_code ndr_pull_compression_mszip_chunk(struct ndr_pull *ndrpu
plain_chunk.length = plain_chunk_size;
plain_chunk.data = ndrpush->data + plain_chunk_offset;
- ret = ZIPdecompress(decomp_state, &comp_chunk, &plain_chunk);
- if (ret != DECR_OK) {
- return ndr_pull_error(ndrpull, NDR_ERR_COMPRESSION, "Bad ZIPdecompress() error %d (PULL)",
- ret);
+ if (comp_chunk.length < 2) {
+ return ndr_pull_error(ndrpull, NDR_ERR_COMPRESSION,
+ "Bad MSZIP comp chunk size %u < 2 (PULL)",
+ (unsigned int)comp_chunk.length);
+ }
+ /* CK = Chris Kirmse, official Microsoft purloiner */
+ if (comp_chunk.data[0] != 'C' ||
+ comp_chunk.data[1] != 'K') {
+ return ndr_pull_error(ndrpull, NDR_ERR_COMPRESSION,
+ "Bad MSZIP invalid prefix [%c%c] != [CK]",
+ comp_chunk.data[0], comp_chunk.data[1]);
+ }
+
+ z->next_in = comp_chunk.data + 2;
+ z->avail_in = comp_chunk.length -2;
+ z->total_in = 0;
+
+ z->next_out = plain_chunk.data;
+ z->avail_out = plain_chunk.length;
+ z->total_out = 0;
+
+ if (!z->opaque) {
+ /* the first time we need to intialize completely */
+ z->zalloc = ndr_zlib_alloc;
+ z->zfree = ndr_zlib_free;
+ z->opaque = ndrpull;
+
+ z_ret = inflateInit2(z, -15);
+ if (z_ret != Z_OK) {
+ return ndr_pull_error(ndrpull, NDR_ERR_COMPRESSION,
+ "Bad inflateInit2 error %s(%d) (PULL)",
+ zError(z_ret), z_ret);
+
+ }
+ } else {
+ z_ret = inflateReset2(z, Z_RESET_KEEP_WINDOW);
+ if (z_ret != Z_OK) {
+ return ndr_pull_error(ndrpull, NDR_ERR_COMPRESSION,
+ "Bad inflateReset2 error %s(%d) (PULL)",
+ zError(z_ret), z_ret);
+ }
+ }
+
+ /* call inflate untill we get Z_STREAM_END or an error */
+ while (true) {
+ z_ret = inflate(z, Z_BLOCK);
+ if (z_ret != Z_OK) break;
+ }
+
+ if (z_ret != Z_STREAM_END) {
+ return ndr_pull_error(ndrpull, NDR_ERR_COMPRESSION,
+ "Bad inflate(Z_BLOCK) error %s(%d) (PULL)",
+ zError(z_ret), z_ret);
+ }
+
+ if (z->avail_in) {
+ return ndr_pull_error(ndrpull, NDR_ERR_COMPRESSION,
+ "MSZIP not all avail_in[%u] bytes consumed (PULL)",
+ z->avail_in);
+ }
+
+ if (z->avail_out) {
+ return ndr_pull_error(ndrpull, NDR_ERR_COMPRESSION,
+ "MSZIP not all avail_out[%u] bytes consumed (PULL)",
+ z->avail_out);
}
if ((plain_chunk_size < 0x00008000) || (ndrpull->offset+4 >= ndrpull->data_size)) {
@@ -72,98 +145,122 @@ static enum ndr_err_code ndr_pull_compression_mszip_chunk(struct ndr_pull *ndrpu
return NDR_ERR_SUCCESS;
}
-static enum ndr_err_code ndr_pull_compression_mszip(struct ndr_pull *subndr,
- struct ndr_pull **_comndr,
- ssize_t decompressed_len)
+static enum ndr_err_code ndr_push_compression_mszip_chunk(struct ndr_push *ndrpush,
+ struct ndr_pull *ndrpull,
+ z_stream *z,
+ bool *last)
{
- struct ndr_push *ndrpush;
- struct ndr_pull *comndr;
- DATA_BLOB uncompressed;
- uint32_t payload_header[4];
- uint32_t payload_size;
- uint32_t payload_offset;
- uint8_t *payload;
- struct decomp_state *decomp_state;
- bool last = false;
+ DATA_BLOB comp_chunk;
+ uint32_t comp_chunk_size;
+ uint32_t comp_chunk_size_offset;
+ DATA_BLOB plain_chunk;
+ uint32_t plain_chunk_size;
+ uint32_t plain_chunk_offset;
+ uint32_t max_plain_size = 0x00008000;
+ uint32_t max_comp_size = 0x00008000 + 2 + 12 /*TODO: what value do we really need here?*/;
+ uint32_t tmp_offset;
+ int z_ret;
- ndrpush = ndr_push_init_ctx(subndr, subndr->iconv_convenience);
- NDR_ERR_HAVE_NO_MEMORY(ndrpush);
+ plain_chunk_size = MIN(max_plain_size, ndrpull->data_size - ndrpull->offset);
+ plain_chunk_offset = ndrpull->offset;
+ NDR_CHECK(ndr_pull_advance(ndrpull, plain_chunk_size));
- decomp_state = ZIPdecomp_state(subndr);
- NDR_ERR_HAVE_NO_MEMORY(decomp_state);
+ plain_chunk.data = ndrpull->data + plain_chunk_offset;
+ plain_chunk.length = plain_chunk_size;
- while (!last) {
- NDR_CHECK(ndr_pull_compression_mszip_chunk(subndr, ndrpush, decomp_state, &last));
+ if (plain_chunk_size < max_plain_size) {
+ *last = true;
}
- uncompressed = ndr_push_blob(ndrpush);
-
- if (uncompressed.length != decompressed_len) {
- return ndr_pull_error(subndr, NDR_ERR_COMPRESSION, "Bad MSZIP uncompressed_len [%u] != [%d] (PULL)",
- (int)uncompressed.length, (int)decompressed_len);
+ NDR_CHECK(ndr_push_uint32(ndrpush, NDR_SCALARS, plain_chunk_size));
+ comp_chunk_size_offset = ndrpush->offset;
+ NDR_CHECK(ndr_push_uint32(ndrpush, NDR_SCALARS, 0xFEFEFEFE));
+
+ NDR_CHECK(ndr_push_expand(ndrpush, max_comp_size));
+
+ comp_chunk.data = ndrpush->data + ndrpush->offset;
+ comp_chunk.length = max_comp_size;
+
+ /* CK = Chris Kirmse, official Microsoft purloiner */
+ comp_chunk.data[0] = 'C';
+ comp_chunk.data[1] = 'K';
+
+ z->next_in = plain_chunk.data;
+ z->avail_in = plain_chunk.length;
+ z->total_in = 0;
+
+ z->next_out = comp_chunk.data + 2;
+ z->avail_out = comp_chunk.length - 2;
+ z->total_out = 0;
+
+ if (!z->opaque) {
+ /* the first time we need to intialize completely */
+ z->zalloc = ndr_zlib_alloc;
+ z->zfree = ndr_zlib_free;
+ z->opaque = ndrpull;
+
+ /* TODO: find how to trigger the same parameters windows uses */
+ z_ret = deflateInit2(z,
+ Z_DEFAULT_COMPRESSION,
+ Z_DEFLATED,
+ -15,
+ 9,
+ Z_DEFAULT_STRATEGY);
+ if (z_ret != Z_OK) {
+ return ndr_push_error(ndrpush, NDR_ERR_COMPRESSION,
+ "Bad deflateInit2 error %s(%d) (PUSH)",
+ zError(z_ret), z_ret);
+
+ }
+ } else {
+ /* TODO: keep the window */
+ z_ret = deflateReset(z);
+ if (z_ret != Z_OK) {
+ return ndr_push_error(ndrpush, NDR_ERR_COMPRESSION,
+ "Bad delateReset2 error %s(%d) (PUSH)",
+ zError(z_ret), z_ret);
+ }
}
- comndr = talloc_zero(subndr, struct ndr_pull);
- NDR_ERR_HAVE_NO_MEMORY(comndr);
- comndr->flags = subndr->flags;
- comndr->current_mem_ctx = subndr->current_mem_ctx;
-
- comndr->data = uncompressed.data;
- comndr->data_size = uncompressed.length;
- comndr->offset = 0;
-
- comndr->iconv_convenience = talloc_reference(comndr, subndr->iconv_convenience);
-
- NDR_CHECK(ndr_pull_uint32(comndr, NDR_SCALARS, &payload_header[0]));
- NDR_CHECK(ndr_pull_uint32(comndr, NDR_SCALARS, &payload_header[1]));
- NDR_CHECK(ndr_pull_uint32(comndr, NDR_SCALARS, &payload_header[2]));
- NDR_CHECK(ndr_pull_uint32(comndr, NDR_SCALARS, &payload_header[3]));
-
- if (payload_header[0] != 0x00081001) {
- return ndr_pull_error(subndr, NDR_ERR_COMPRESSION, "Bad MSZIP payload_header[0] [0x%08X] != [0x00081001] (PULL)",
- payload_header[0]);
+ /* call deflate untill we get Z_STREAM_END or an error */
+ while (true) {
+ z_ret = deflate(z, Z_FINISH);
+ if (z_ret != Z_OK) break;
}
- if (payload_header[1] != 0xCCCCCCCC) {
- return ndr_pull_error(subndr, NDR_ERR_COMPRESSION, "Bad MSZIP payload_header[1] [0x%08X] != [0xCCCCCCCC] (PULL)",
- payload_header[1]);
+ if (z_ret != Z_STREAM_END) {
+ return ndr_push_error(ndrpush, NDR_ERR_COMPRESSION,
+ "Bad delate(Z_BLOCK) error %s(%d) (PUSH)",
+ zError(z_ret), z_ret);
}
- payload_size = payload_header[2];
-
- if (payload_header[3] != 0x00000000) {
- return ndr_pull_error(subndr, NDR_ERR_COMPRESSION, "Bad MSZIP payload_header[3] [0x%08X] != [0x00000000] (PULL)",
- payload_header[3]);
+ if (z->avail_in) {
+ return ndr_push_error(ndrpush, NDR_ERR_COMPRESSION,
+ "MSZIP not all avail_in[%u] bytes consumed (PUSH)",
+ z->avail_in);
}
- payload_offset = comndr->offset;
- NDR_CHECK(ndr_pull_advance(comndr, payload_size));
- payload = comndr->data + payload_offset;
+ comp_chunk_size = 2 + z->total_out;
- comndr->data = payload;
- comndr->data_size = payload_size;
- comndr->offset = 0;
+ tmp_offset = ndrpush->offset;
+ ndrpush->offset = comp_chunk_size_offset;
+ NDR_CHECK(ndr_push_uint32(ndrpush, NDR_SCALARS, comp_chunk_size));
+ ndrpush->offset = tmp_offset;
- *_comndr = comndr;
+ ndrpush->offset += comp_chunk_size;
return NDR_ERR_SUCCESS;
}
-static enum ndr_err_code ndr_push_compression_mszip(struct ndr_push *subndr,
- struct ndr_push *comndr)
-{
- return ndr_push_error(subndr, NDR_ERR_COMPRESSION, "Sorry MSZIP compression is not supported yet (PUSH)");
-}
-
static enum ndr_err_code ndr_pull_compression_xpress_chunk(struct ndr_pull *ndrpull,
struct ndr_push *ndrpush,
bool *last)
{
DATA_BLOB comp_chunk;
+ DATA_BLOB plain_chunk;
uint32_t comp_chunk_offset;
+ uint32_t plain_chunk_offset;
uint32_t comp_chunk_size;
uint32_t plain_chunk_size;
- comp_chunk_offset = ndrpull->offset;
-
NDR_CHECK(ndr_pull_uint32(ndrpull, NDR_SCALARS, &plain_chunk_size));
if (plain_chunk_size > 0x00010000) {
return ndr_pull_error(ndrpull, NDR_ERR_COMPRESSION, "Bad XPRESS plain chunk size %08X > 0x00010000 (PULL)",
@@ -172,15 +269,21 @@ static enum ndr_err_code ndr_pull_compression_xpress_chunk(struct ndr_pull *ndrp
NDR_CHECK(ndr_pull_uint32(ndrpull, NDR_SCALARS, &comp_chunk_size));
+ comp_chunk_offset = ndrpull->offset;
NDR_CHECK(ndr_pull_advance(ndrpull, comp_chunk_size));
- comp_chunk.length = comp_chunk_size + 8;
+ comp_chunk.length = comp_chunk_size;
comp_chunk.data = ndrpull->data + comp_chunk_offset;
+ plain_chunk_offset = ndrpush->offset;
+ NDR_CHECK(ndr_push_zero(ndrpush, plain_chunk_size));
+ plain_chunk.length = plain_chunk_size;
+ plain_chunk.data = ndrpush->data + plain_chunk_offset;
+
DEBUG(10,("XPRESS plain_chunk_size: %08X (%u) comp_chunk_size: %08X (%u)\n",
plain_chunk_size, plain_chunk_size, comp_chunk_size, comp_chunk_size));
- /* For now, we just copy over the compressed blob */
- NDR_CHECK(ndr_push_bytes(ndrpush, comp_chunk.data, comp_chunk.length));
+ /* Uncompressing the buffer using LZ Xpress algorithm */
+ lzxpress_decompress(&comp_chunk, &plain_chunk);
if ((plain_chunk_size < 0x00010000) || (ndrpull->offset+4 >= ndrpull->data_size)) {
/* this is the last chunk */
@@ -190,23 +293,58 @@ static enum ndr_err_code ndr_pull_compression_xpress_chunk(struct ndr_pull *ndrp
return NDR_ERR_SUCCESS;
}
-static enum ndr_err_code ndr_pull_compression_xpress(struct ndr_pull *subndr,
- struct ndr_pull **_comndr,
- ssize_t decompressed_len)
+static enum ndr_err_code ndr_push_compression_xpress_chunk(struct ndr_push *ndrpush,
+ struct ndr_pull *ndrpull,
+ bool *last)
+{
+ return ndr_push_error(ndrpush, NDR_ERR_COMPRESSION, "XPRESS compression is not supported yet (PUSH)");
+}
+
+/*
+ handle compressed subcontext buffers, which in midl land are user-marshalled, but
+ we use magic in pidl to make them easier to cope with
+*/
+enum ndr_err_code ndr_pull_compression_start(struct ndr_pull *subndr,
+ struct ndr_pull **_comndr,
+ enum ndr_compression_alg compression_alg,
+ ssize_t decompressed_len)
{
struct ndr_push *ndrpush;
struct ndr_pull *comndr;
DATA_BLOB uncompressed;
bool last = false;
+ z_stream z;
ndrpush = ndr_push_init_ctx(subndr, subndr->iconv_convenience);
NDR_ERR_HAVE_NO_MEMORY(ndrpush);
- while (!last) {
- NDR_CHECK(ndr_pull_compression_xpress_chunk(subndr, ndrpush, &last));
+ switch (compression_alg) {
+ case NDR_COMPRESSION_MSZIP:
+ ZERO_STRUCT(z);
+ while (!last) {
+ NDR_CHECK(ndr_pull_compression_mszip_chunk(subndr, ndrpush, &z, &last));
+ }
+ break;
+
+ case NDR_COMPRESSION_XPRESS:
+ while (!last) {
+ NDR_CHECK(ndr_pull_compression_xpress_chunk(subndr, ndrpush, &last));
+ }
+ break;
+
+ default:
+ return ndr_pull_error(subndr, NDR_ERR_COMPRESSION, "Bad compression algorithm %d (PULL)",
+ compression_alg);
}
uncompressed = ndr_push_blob(ndrpush);
+ if (uncompressed.length != decompressed_len) {
+ return ndr_pull_error(subndr, NDR_ERR_COMPRESSION,
+ "Bad uncompressed_len [%u] != [%u](0x%08X) (PULL)",
+ (int)uncompressed.length,
+ (int)decompressed_len,
+ (int)decompressed_len);
+ }
comndr = talloc_zero(subndr, struct ndr_pull);
NDR_ERR_HAVE_NO_MEMORY(comndr);
@@ -223,33 +361,6 @@ static enum ndr_err_code ndr_pull_compression_xpress(struct ndr_pull *subndr,
return NDR_ERR_SUCCESS;
}
-static enum ndr_err_code ndr_push_compression_xpress(struct ndr_push *subndr,
- struct ndr_push *comndr)
-{
- return ndr_push_error(subndr, NDR_ERR_COMPRESSION, "XPRESS compression is not supported yet (PUSH)");
-}
-
-/*
- handle compressed subcontext buffers, which in midl land are user-marshalled, but
- we use magic in pidl to make them easier to cope with
-*/
-enum ndr_err_code ndr_pull_compression_start(struct ndr_pull *subndr,
- struct ndr_pull **_comndr,
- enum ndr_compression_alg compression_alg,
- ssize_t decompressed_len)
-{
- switch (compression_alg) {
- case NDR_COMPRESSION_MSZIP:
- return ndr_pull_compression_mszip(subndr, _comndr, decompressed_len);
- case NDR_COMPRESSION_XPRESS:
- return ndr_pull_compression_xpress(subndr, _comndr, decompressed_len);
- default:
- return ndr_pull_error(subndr, NDR_ERR_COMPRESSION, "Bad compression algorithm %d (PULL)",
- compression_alg);
- }
- return NDR_ERR_SUCCESS;
-}
-
enum ndr_err_code ndr_pull_compression_end(struct ndr_pull *subndr,
struct ndr_pull *comndr,
enum ndr_compression_alg compression_alg,
@@ -262,17 +373,27 @@ enum ndr_err_code ndr_pull_compression_end(struct ndr_pull *subndr,
push a compressed subcontext
*/
enum ndr_err_code ndr_push_compression_start(struct ndr_push *subndr,
- struct ndr_push **_comndr,
+ struct ndr_push **_uncomndr,
enum ndr_compression_alg compression_alg,
ssize_t decompressed_len)
{
- struct ndr_push *comndr;
+ struct ndr_push *uncomndr;
- comndr = ndr_push_init_ctx(subndr, subndr->iconv_convenience);
- NDR_ERR_HAVE_NO_MEMORY(comndr);
- comndr->flags = subndr->flags;
+ switch (compression_alg) {
+ case NDR_COMPRESSION_MSZIP:
+ case NDR_COMPRESSION_XPRESS:
+ break;
+ default:
+ return ndr_push_error(subndr, NDR_ERR_COMPRESSION,
+ "Bad compression algorithm %d (PUSH)",
+ compression_alg);
+ }
- *_comndr = comndr;
+ uncomndr = ndr_push_init_ctx(subndr, subndr->iconv_convenience);
+ NDR_ERR_HAVE_NO_MEMORY(uncomndr);
+ uncomndr->flags = subndr->flags;
+
+ *_uncomndr = uncomndr;
return NDR_ERR_SUCCESS;
}
@@ -280,18 +401,42 @@ enum ndr_err_code ndr_push_compression_start(struct ndr_push *subndr,
push a compressed subcontext
*/
enum ndr_err_code ndr_push_compression_end(struct ndr_push *subndr,
- struct ndr_push *comndr,
+ struct ndr_push *uncomndr,
enum ndr_compression_alg compression_alg,
ssize_t decompressed_len)
{
+ struct ndr_pull *ndrpull;
+ bool last = false;
+ z_stream z;
+
+ ndrpull = talloc_zero(uncomndr, struct ndr_pull);
+ NDR_ERR_HAVE_NO_MEMORY(ndrpull);
+ ndrpull->flags = uncomndr->flags;
+ ndrpull->data = uncomndr->data;
+ ndrpull->data_size = uncomndr->offset;
+ ndrpull->offset = 0;
+
+ ndrpull->iconv_convenience = talloc_reference(ndrpull, subndr->iconv_convenience);
+
switch (compression_alg) {
case NDR_COMPRESSION_MSZIP:
- return ndr_push_compression_mszip(subndr, comndr);
+ ZERO_STRUCT(z);
+ while (!last) {
+ NDR_CHECK(ndr_push_compression_mszip_chunk(subndr, ndrpull, &z, &last));
+ }
+ break;
+
case NDR_COMPRESSION_XPRESS:
- return ndr_push_compression_xpress(subndr, comndr);
+ while (!last) {
+ NDR_CHECK(ndr_push_compression_xpress_chunk(subndr, ndrpull, &last));
+ }
+ break;
+
default:
return ndr_push_error(subndr, NDR_ERR_COMPRESSION, "Bad compression algorithm %d (PUSH)",
compression_alg);
}
+
+ talloc_free(uncomndr);
return NDR_ERR_SUCCESS;
}
diff --git a/source4/librpc/ndr/ndr_drsuapi.c b/source4/librpc/ndr/ndr_drsuapi.c
index 1b6be9ed8e..e77ab54071 100644
--- a/source4/librpc/ndr/ndr_drsuapi.c
+++ b/source4/librpc/ndr/ndr_drsuapi.c
@@ -24,6 +24,7 @@
#include "librpc/gen_ndr/ndr_drsuapi.h"
#include "librpc/gen_ndr/ndr_misc.h"
#include "lib/util/asn1.h"
+#include "librpc/ndr/ndr_compression.h"
void ndr_print_drsuapi_DsReplicaObjectListItem(struct ndr_print *ndr, const char *name,
const struct drsuapi_DsReplicaObjectListItem *r)
@@ -176,3 +177,175 @@ size_t ndr_size_drsuapi_DsReplicaOID_oid(const char *oid, int flags)
data_blob_free(&_blob);
return ret;
}
+
+enum ndr_err_code ndr_push_drsuapi_DsGetNCChangesMSZIPCtr1(struct ndr_push *ndr, int ndr_flags, const struct drsuapi_DsGetNCChangesMSZIPCtr1 *r)
+{
+ if (ndr_flags & NDR_SCALARS) {
+ uint32_t decompressed_length = 0;
+ uint32_t compressed_length = 0;
+ if (r->ts) {
+ {
+ struct ndr_push *_ndr_ts;
+ NDR_CHECK(ndr_push_subcontext_start(ndr, &_ndr_ts, 4, -1));
+ {
+ struct ndr_push *_ndr_ts_compressed;
+ NDR_CHECK(ndr_push_compression_start(_ndr_ts, &_ndr_ts_compressed, NDR_COMPRESSION_MSZIP, -1));
+ NDR_CHECK(ndr_push_drsuapi_DsGetNCChangesCtr1TS(_ndr_ts_compressed, NDR_SCALARS|NDR_BUFFERS, r->ts));
+ decompressed_length = _ndr_ts_compressed->offset;
+ NDR_CHECK(ndr_push_compression_end(_ndr_ts, _ndr_ts_compressed, NDR_COMPRESSION_MSZIP, -1));
+ }
+ compressed_length = _ndr_ts->offset;
+ talloc_free(_ndr_ts);
+ }
+ }
+ NDR_CHECK(ndr_push_align(ndr, 4));
+ NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, decompressed_length));
+ NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, compressed_length));
+ NDR_CHECK(ndr_push_unique_ptr(ndr, r->ts));
+ }
+ if (ndr_flags & NDR_BUFFERS) {
+ if (r->ts) {
+ {
+ struct ndr_push *_ndr_ts;
+ NDR_CHECK(ndr_push_subcontext_start(ndr, &_ndr_ts, 4, -1));
+ {
+ struct ndr_push *_ndr_ts_compressed;
+ NDR_CHECK(ndr_push_compression_start(_ndr_ts, &_ndr_ts_compressed, NDR_COMPRESSION_MSZIP, -1));
+ NDR_CHECK(ndr_push_drsuapi_DsGetNCChangesCtr1TS(_ndr_ts_compressed, NDR_SCALARS|NDR_BUFFERS, r->ts));
+ NDR_CHECK(ndr_push_compression_end(_ndr_ts, _ndr_ts_compressed, NDR_COMPRESSION_MSZIP, -1));
+ }
+ NDR_CHECK(ndr_push_subcontext_end(ndr, _ndr_ts, 4, -1));
+ }
+ }
+ }
+ return NDR_ERR_SUCCESS;
+}
+
+enum ndr_err_code ndr_push_drsuapi_DsGetNCChangesMSZIPCtr6(struct ndr_push *ndr, int ndr_flags, const struct drsuapi_DsGetNCChangesMSZIPCtr6 *r)
+{
+ if (ndr_flags & NDR_SCALARS) {
+ uint32_t decompressed_length = 0;
+ uint32_t compressed_length = 0;
+ if (r->ts) {
+ {
+ struct ndr_push *_ndr_ts;
+ NDR_CHECK(ndr_push_subcontext_start(ndr, &_ndr_ts, 4, -1));
+ {
+ struct ndr_push *_ndr_ts_compressed;
+ NDR_CHECK(ndr_push_compression_start(_ndr_ts, &_ndr_ts_compressed, NDR_COMPRESSION_MSZIP, -1));
+ NDR_CHECK(ndr_push_drsuapi_DsGetNCChangesCtr6TS(_ndr_ts_compressed, NDR_SCALARS|NDR_BUFFERS, r->ts));
+ decompressed_length = _ndr_ts_compressed->offset;
+ NDR_CHECK(ndr_push_compression_end(_ndr_ts, _ndr_ts_compressed, NDR_COMPRESSION_MSZIP, -1));
+ }
+ compressed_length = _ndr_ts->offset;
+ talloc_free(_ndr_ts);
+ }
+ }
+ NDR_CHECK(ndr_push_align(ndr, 4));
+ NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, decompressed_length));
+ NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, compressed_length));
+ NDR_CHECK(ndr_push_unique_ptr(ndr, r->ts));
+ }
+ if (ndr_flags & NDR_BUFFERS) {
+ if (r->ts) {
+ {
+ struct ndr_push *_ndr_ts;
+ NDR_CHECK(ndr_push_subcontext_start(ndr, &_ndr_ts, 4, -1));
+ {
+ struct ndr_push *_ndr_ts_compressed;
+ NDR_CHECK(ndr_push_compression_start(_ndr_ts, &_ndr_ts_compressed, NDR_COMPRESSION_MSZIP, -1));
+ NDR_CHECK(ndr_push_drsuapi_DsGetNCChangesCtr6TS(_ndr_ts_compressed, NDR_SCALARS|NDR_BUFFERS, r->ts));
+ NDR_CHECK(ndr_push_compression_end(_ndr_ts, _ndr_ts_compressed, NDR_COMPRESSION_MSZIP, -1));
+ }
+ NDR_CHECK(ndr_push_subcontext_end(ndr, _ndr_ts, 4, -1));
+ }
+ }
+ }
+ return NDR_ERR_SUCCESS;
+}
+
+enum ndr_err_code ndr_push_drsuapi_DsGetNCChangesXPRESSCtr1(struct ndr_push *ndr, int ndr_flags, const struct drsuapi_DsGetNCChangesXPRESSCtr1 *r)
+{
+ if (ndr_flags & NDR_SCALARS) {
+ uint32_t decompressed_length = 0;
+ uint32_t compressed_length = 0;
+ if (r->ts) {
+ {
+ struct ndr_push *_ndr_ts;
+ NDR_CHECK(ndr_push_subcontext_start(ndr, &_ndr_ts, 4, -1));
+ {
+ struct ndr_push *_ndr_ts_compressed;
+ NDR_CHECK(ndr_push_compression_start(_ndr_ts, &_ndr_ts_compressed, NDR_COMPRESSION_XPRESS, -1));
+ NDR_CHECK(ndr_push_drsuapi_DsGetNCChangesCtr1TS(_ndr_ts_compressed, NDR_SCALARS|NDR_BUFFERS, r->ts));
+ decompressed_length = _ndr_ts_compressed->offset;
+ NDR_CHECK(ndr_push_compression_end(_ndr_ts, _ndr_ts_compressed, NDR_COMPRESSION_XPRESS, -1));
+ }
+ compressed_length = _ndr_ts->offset;
+ talloc_free(_ndr_ts);
+ }
+ }
+ NDR_CHECK(ndr_push_align(ndr, 4));
+ NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, decompressed_length));
+ NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, compressed_length));
+ NDR_CHECK(ndr_push_unique_ptr(ndr, r->ts));
+ }
+ if (ndr_flags & NDR_BUFFERS) {
+ if (r->ts) {
+ {
+ struct ndr_push *_ndr_ts;
+ NDR_CHECK(ndr_push_subcontext_start(ndr, &_ndr_ts, 4, -1));
+ {
+ struct ndr_push *_ndr_ts_compressed;
+ NDR_CHECK(ndr_push_compression_start(_ndr_ts, &_ndr_ts_compressed, NDR_COMPRESSION_XPRESS, -1));
+ NDR_CHECK(ndr_push_drsuapi_DsGetNCChangesCtr1TS(_ndr_ts_compressed, NDR_SCALARS|NDR_BUFFERS, r->ts));
+ NDR_CHECK(ndr_push_compression_end(_ndr_ts, _ndr_ts_compressed, NDR_COMPRESSION_XPRESS, -1));
+ }
+ NDR_CHECK(ndr_push_subcontext_end(ndr, _ndr_ts, 4, -1));
+ }
+ }
+ }
+ return NDR_ERR_SUCCESS;
+}
+
+enum ndr_err_code ndr_push_drsuapi_DsGetNCChangesXPRESSCtr6(struct ndr_push *ndr, int ndr_flags, const struct drsuapi_DsGetNCChangesXPRESSCtr6 *r)
+{
+ if (ndr_flags & NDR_SCALARS) {
+ uint32_t decompressed_length = 0;
+ uint32_t compressed_length = 0;
+ if (r->ts) {
+ {
+ struct ndr_push *_ndr_ts;
+ NDR_CHECK(ndr_push_subcontext_start(ndr, &_ndr_ts, 4, -1));
+ {
+ struct ndr_push *_ndr_ts_compressed;
+ NDR_CHECK(ndr_push_compression_start(_ndr_ts, &_ndr_ts_compressed, NDR_COMPRESSION_XPRESS, -1));
+ NDR_CHECK(ndr_push_drsuapi_DsGetNCChangesCtr6TS(_ndr_ts_compressed, NDR_SCALARS|NDR_BUFFERS, r->ts));
+ decompressed_length = _ndr_ts_compressed->offset;
+ NDR_CHECK(ndr_push_compression_end(_ndr_ts, _ndr_ts_compressed, NDR_COMPRESSION_XPRESS, -1));
+ }
+ compressed_length = _ndr_ts->offset;
+ talloc_free(_ndr_ts);
+ }
+ }
+ NDR_CHECK(ndr_push_align(ndr, 4));
+ NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, decompressed_length));
+ NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, compressed_length));
+ NDR_CHECK(ndr_push_unique_ptr(ndr, r->ts));
+ }
+ if (ndr_flags & NDR_BUFFERS) {
+ if (r->ts) {
+ {
+ struct ndr_push *_ndr_ts;
+ NDR_CHECK(ndr_push_subcontext_start(ndr, &_ndr_ts, 4, -1));
+ {
+ struct ndr_push *_ndr_ts_compressed;
+ NDR_CHECK(ndr_push_compression_start(_ndr_ts, &_ndr_ts_compressed, NDR_COMPRESSION_XPRESS, -1));
+ NDR_CHECK(ndr_push_drsuapi_DsGetNCChangesCtr6TS(_ndr_ts_compressed, NDR_SCALARS|NDR_BUFFERS, r->ts));
+ NDR_CHECK(ndr_push_compression_end(_ndr_ts, _ndr_ts_compressed, NDR_COMPRESSION_XPRESS, -1));
+ }
+ NDR_CHECK(ndr_push_subcontext_end(ndr, _ndr_ts, 4, -1));
+ }
+ }
+ }
+ return NDR_ERR_SUCCESS;
+}
diff --git a/source4/librpc/rpc/dcerpc.c b/source4/librpc/rpc/dcerpc.c
index a6c7e0020d..28b5cd65a9 100644
--- a/source4/librpc/rpc/dcerpc.c
+++ b/source4/librpc/rpc/dcerpc.c
@@ -334,6 +334,7 @@ static NTSTATUS ncacn_pull_request_auth(struct dcerpc_connection *c, TALLOC_CTX
*/
static NTSTATUS ncacn_push_request_sign(struct dcerpc_connection *c,
DATA_BLOB *blob, TALLOC_CTX *mem_ctx,
+ size_t sig_size,
struct ncacn_packet *pkt)
{
NTSTATUS status;
@@ -384,8 +385,7 @@ static NTSTATUS ncacn_push_request_sign(struct dcerpc_connection *c,
* GENSEC mech does AEAD signing of the packet
* headers */
c->security_state.auth_info->credentials
- = data_blob_talloc(mem_ctx, NULL, gensec_sig_size(c->security_state.generic_state,
- payload_length));
+ = data_blob_talloc(mem_ctx, NULL, sig_size);
data_blob_clear(&c->security_state.auth_info->credentials);
break;
@@ -1042,6 +1042,7 @@ static void dcerpc_ship_next_request(struct dcerpc_connection *c)
DATA_BLOB blob;
uint32_t remaining, chunk_size;
bool first_packet = true;
+ size_t sig_size = 0;
req = c->request_queue;
if (req == NULL) {
@@ -1065,7 +1066,15 @@ static void dcerpc_ship_next_request(struct dcerpc_connection *c)
/* we can write a full max_recv_frag size, minus the dcerpc
request header size */
- chunk_size = p->conn->srv_max_recv_frag - (DCERPC_MAX_SIGN_SIZE+DCERPC_REQUEST_LENGTH);
+ chunk_size = p->conn->srv_max_recv_frag;
+ chunk_size -= DCERPC_REQUEST_LENGTH;
+ if (c->security_state.generic_state) {
+ chunk_size -= DCERPC_AUTH_TRAILER_LENGTH;
+ sig_size = gensec_sig_size(c->security_state.generic_state,
+ p->conn->srv_max_recv_frag);
+ chunk_size -= sig_size;
+ chunk_size -= (chunk_size % 16);
+ }
pkt.ptype = DCERPC_PKT_REQUEST;
pkt.call_id = req->call_id;
@@ -1101,7 +1110,7 @@ static void dcerpc_ship_next_request(struct dcerpc_connection *c)
(stub_data->length - remaining);
pkt.u.request.stub_and_verifier.length = chunk;
- req->status = ncacn_push_request_sign(p->conn, &blob, req, &pkt);
+ req->status = ncacn_push_request_sign(p->conn, &blob, req, sig_size, &pkt);
if (!NT_STATUS_IS_OK(req->status)) {
req->state = RPC_REQUEST_DONE;
DLIST_REMOVE(p->conn->pending, req);