wmi-1.3.16 from opsview.com

This commit is contained in:
Are Casilla
2019-02-16 00:16:52 +01:00
parent 163fdd3d1b
commit 17b3af2911
2146 changed files with 678824 additions and 0 deletions
+326
View File
@@ -0,0 +1,326 @@
/*
Unix SMB/CIFS implementation.
rpc interface definitions
Copyright (C) Andrew Tridgell 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 __LIBNDR_H__
#define __LIBNDR_H__
#include "core.h"
#include "lib/talloc/talloc.h"
#include "lib/util/util.h" /* for discard_const */
#include "lib/charset/charset.h"
/*
this provides definitions for the libcli/rpc/ MSRPC library
*/
/*
this is used by the token store/retrieve code
*/
struct ndr_token_list {
struct ndr_token_list *next, *prev;
const void *key;
uint32_t value;
};
/* this is the base structure passed to routines that
parse MSRPC formatted data
note that in Samba4 we use separate routines and structures for
MSRPC marshalling and unmarshalling. Also note that these routines
are being kept deliberately very simple, and are not tied to a
particular transport
*/
struct ndr_pull {
uint32_t flags; /* LIBNDR_FLAG_* */
uint8_t *data;
uint32_t data_size;
uint32_t offset;
uint32_t relative_base_offset;
struct ndr_token_list *relative_base_list;
struct ndr_token_list *relative_list;
struct ndr_token_list *array_size_list;
struct ndr_token_list *array_length_list;
struct ndr_token_list *switch_list;
TALLOC_CTX *current_mem_ctx;
/* this is used to ensure we generate unique reference IDs
between request and reply */
uint32_t ptr_count;
};
struct ndr_pull_save {
uint32_t data_size;
uint32_t offset;
struct ndr_pull_save *next;
};
/* structure passed to functions that generate NDR formatted data */
struct ndr_push {
uint32_t flags; /* LIBNDR_FLAG_* */
uint8_t *data;
uint32_t alloc_size;
uint32_t offset;
uint32_t relative_base_offset;
struct ndr_token_list *relative_base_list;
struct ndr_token_list *switch_list;
struct ndr_token_list *relative_list;
struct ndr_token_list *nbt_string_list;
struct ndr_token_list *full_ptr_list;
/* this is used to ensure we generate unique reference IDs */
uint32_t ptr_count;
};
struct ndr_push_save {
uint32_t offset;
struct ndr_push_save *next;
};
/* structure passed to functions that print IDL structures */
struct ndr_print {
uint32_t flags; /* LIBNDR_FLAG_* */
uint32_t depth;
struct ndr_token_list *switch_list;
void (*print)(struct ndr_print *, const char *, ...) PRINTF_ATTRIBUTE(2,3);
void *private_data;
};
#define LIBNDR_FLAG_BIGENDIAN (1<<0)
#define LIBNDR_FLAG_NOALIGN (1<<1)
#define LIBNDR_FLAG_STR_ASCII (1<<2)
#define LIBNDR_FLAG_STR_LEN4 (1<<3)
#define LIBNDR_FLAG_STR_SIZE4 (1<<4)
#define LIBNDR_FLAG_STR_NOTERM (1<<5)
#define LIBNDR_FLAG_STR_NULLTERM (1<<6)
#define LIBNDR_FLAG_STR_SIZE2 (1<<7)
#define LIBNDR_FLAG_STR_BYTESIZE (1<<8)
#define LIBNDR_FLAG_STR_FIXLEN32 (1<<9)
#define LIBNDR_FLAG_STR_CONFORMANT (1<<10)
#define LIBNDR_FLAG_STR_CHARLEN (1<<11)
#define LIBNDR_FLAG_STR_UTF8 (1<<12)
#define LIBNDR_FLAG_STR_FIXLEN15 (1<<13)
#define LIBNDR_STRING_FLAGS (0x7FFC)
#define LIBNDR_FLAG_REF_ALLOC (1<<20)
#define LIBNDR_FLAG_REMAINING (1<<21)
#define LIBNDR_FLAG_ALIGN2 (1<<22)
#define LIBNDR_FLAG_ALIGN4 (1<<23)
#define LIBNDR_FLAG_ALIGN8 (1<<24)
#define LIBNDR_ALIGN_FLAGS (LIBNDR_FLAG_ALIGN2|LIBNDR_FLAG_ALIGN4|LIBNDR_FLAG_ALIGN8)
#define LIBNDR_PRINT_ARRAY_HEX (1<<25)
#define LIBNDR_PRINT_SET_VALUES (1<<26)
/* used to force a section of IDL to be little-endian */
#define LIBNDR_FLAG_LITTLE_ENDIAN (1<<27)
/* used to check if alignment padding is zero */
#define LIBNDR_FLAG_PAD_CHECK (1<<28)
/* set if an object uuid will be present */
#define LIBNDR_FLAG_OBJECT_PRESENT (1<<30)
/* set to avoid recursion in ndr_size_*() calculation */
#define LIBNDR_FLAG_NO_NDR_SIZE (1<<31)
/* useful macro for debugging */
#define NDR_PRINT_DEBUG(type, p) ndr_print_debug((ndr_print_fn_t)ndr_print_ ##type, #p, p)
#define NDR_PRINT_UNION_DEBUG(type, level, p) ndr_print_union_debug((ndr_print_fn_t)ndr_print_ ##type, #p, level, p)
#define NDR_PRINT_FUNCTION_DEBUG(type, flags, p) ndr_print_function_debug((ndr_print_function_t)ndr_print_ ##type, #type, flags, p)
#define NDR_PRINT_BOTH_DEBUG(type, p) NDR_PRINT_FUNCTION_DEBUG(type, NDR_BOTH, p)
#define NDR_PRINT_OUT_DEBUG(type, p) NDR_PRINT_FUNCTION_DEBUG(type, NDR_OUT, p)
#define NDR_PRINT_IN_DEBUG(type, p) NDR_PRINT_FUNCTION_DEBUG(type, NDR_IN | NDR_SET_VALUES, p)
#define NDR_BE(ndr) (((ndr)->flags & (LIBNDR_FLAG_BIGENDIAN|LIBNDR_FLAG_LITTLE_ENDIAN)) == LIBNDR_FLAG_BIGENDIAN)
enum ndr_err_code {
NDR_ERR_ARRAY_SIZE,
NDR_ERR_BAD_SWITCH,
NDR_ERR_OFFSET,
NDR_ERR_RELATIVE,
NDR_ERR_CHARCNV,
NDR_ERR_LENGTH,
NDR_ERR_SUBCONTEXT,
NDR_ERR_COMPRESSION,
NDR_ERR_STRING,
NDR_ERR_VALIDATE,
NDR_ERR_BUFSIZE,
NDR_ERR_ALLOC,
NDR_ERR_RANGE,
NDR_ERR_TOKEN,
NDR_ERR_IPV4ADDRESS
};
enum ndr_compression_alg {
NDR_COMPRESSION_MSZIP = 2,
NDR_COMPRESSION_XPRESS = 3
};
/*
flags passed to control parse flow
*/
#define NDR_SCALARS 1
#define NDR_BUFFERS 2
/*
flags passed to ndr_print_*()
*/
#define NDR_IN 1
#define NDR_OUT 2
#define NDR_BOTH 3
#define NDR_SET_VALUES 4
#define NDR_PULL_NEED_BYTES(ndr, n) do { \
if ((n) > ndr->data_size || ndr->offset + (n) > ndr->data_size) { \
return ndr_pull_error(ndr, NDR_ERR_BUFSIZE, "Pull bytes %u", (unsigned)n); \
} \
} while(0)
#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) { \
ndr_check_padding(ndr, n); \
} \
ndr->offset = (ndr->offset + (n-1)) & ~(n-1); \
} \
if (ndr->offset > ndr->data_size) { \
return ndr_pull_error(ndr, NDR_ERR_BUFSIZE, "Pull align %u", (unsigned)n); \
} \
} while(0)
#define NDR_PUSH_NEED_BYTES(ndr, n) NDR_CHECK(ndr_push_expand(ndr, ndr->offset+(n)))
#define NDR_PUSH_ALIGN(ndr, n) do { \
if (!(ndr->flags & LIBNDR_FLAG_NOALIGN)) { \
uint32_t _pad = ((ndr->offset + (n-1)) & ~(n-1)) - ndr->offset; \
while (_pad--) NDR_CHECK(ndr_push_uint8(ndr, NDR_SCALARS, 0)); \
} \
} while(0)
/*#define NDR_CHECK_DEBUG*/
#ifndef NDR_CHECK_DEBUG
#define NDR_CHECK_set_shift(n)
/* these are used to make the error checking on each element in libndr
less tedious, hopefully making the code more readable */
#define NDR_CHECK(call) do { NTSTATUS _status; \
_status = call; \
if (!NT_STATUS_IS_OK(_status)) \
return _status; \
} while (0)
#else
#define NDR_CHECK_set_shift(n) NDR_CHECK_shift = (n)
extern int NDR_CHECK_depth;
extern int NDR_CHECK_shift;
/* these are used to make the error checking on each element in libndr
less tedious, hopefully making the code more readable */
#define NDR_CHECK(call) do { NTSTATUS _status; \
DEBUG(9, ("%*s%10.10s: BEG(%08X) %s\n", 2*NDR_CHECK_depth++, "", __location__, ndr->offset+NDR_CHECK_shift, #call)); \
_status = call; \
if (!NT_STATUS_IS_OK(_status)) \
return _status; \
DEBUG(9, ("%*s%10.10s: END(%08X) %s\n", --NDR_CHECK_depth*2, "", __location__, ndr->offset+NDR_CHECK_shift, #call)); \
} while (0)
#endif
#define NDR_PULL_GET_MEM_CTX(ndr) (ndr->current_mem_ctx)
#define NDR_PULL_SET_MEM_CTX(ndr, mem_ctx, flgs) do {\
if ( !(flgs) || (ndr->flags & flgs) ) {\
if (!(mem_ctx)) {\
return ndr_pull_error(ndr, NDR_ERR_ALLOC, "NDR_PULL_SET_MEM_CTX(NULL): %s\n", __location__); \
}\
ndr->current_mem_ctx = discard_const(mem_ctx);\
}\
} while(0)
#define _NDR_PULL_FIX_CURRENT_MEM_CTX(ndr) do {\
if (!ndr->current_mem_ctx) {\
ndr->current_mem_ctx = talloc_new(ndr);\
if (!ndr->current_mem_ctx) {\
return ndr_pull_error(ndr, NDR_ERR_ALLOC, "_NDR_PULL_FIX_CURRENT_MEM_CTX() failed: %s\n", __location__); \
}\
}\
} while(0)
#define NDR_PULL_ALLOC(ndr, s) do { \
_NDR_PULL_FIX_CURRENT_MEM_CTX(ndr);\
(s) = talloc_ptrtype(ndr->current_mem_ctx, (s)); \
if (!(s)) return ndr_pull_error(ndr, NDR_ERR_ALLOC, "Alloc %s failed: %s\n", # s, __location__); \
} while (0)
#define NDR_PULL_ALLOC_N(ndr, s, n) do { \
_NDR_PULL_FIX_CURRENT_MEM_CTX(ndr);\
(s) = talloc_array_ptrtype(ndr->current_mem_ctx, (s), n); \
if (!(s)) return ndr_pull_error(ndr, NDR_ERR_ALLOC, "Alloc %u * %s failed: %s\n", (unsigned)n, # s, __location__); \
} while (0)
#define NDR_PUSH_ALLOC_SIZE(ndr, s, size) do { \
(s) = talloc_size(ndr, size); \
if (!(s)) return ndr_push_error(ndr, NDR_ERR_ALLOC, "push alloc %u failed: %s\n", (unsigned)size, __location__); \
} while (0)
#define NDR_PUSH_ALLOC(ndr, s) do { \
(s) = talloc_ptrtype(ndr, (s)); \
if (!(s)) return ndr_push_error(ndr, NDR_ERR_ALLOC, "push alloc %s failed: %s\n", # s, __location__); \
} while (0)
/* these are used when generic fn pointers are needed for ndr push/pull fns */
typedef NTSTATUS (*ndr_push_flags_fn_t)(struct ndr_push *, int ndr_flags, const void *);
typedef NTSTATUS (*ndr_pull_flags_fn_t)(struct ndr_pull *, int ndr_flags, void *);
typedef void (*ndr_print_fn_t)(struct ndr_print *, const char *, const void *);
typedef void (*ndr_print_function_t)(struct ndr_print *, const char *, int, const void *);
extern const struct dcerpc_syntax_id ndr_transfer_syntax;
extern const struct dcerpc_syntax_id ndr64_transfer_syntax;
#include "librpc/gen_ndr/misc.h"
#include "librpc/ndr/libndr_proto.h"
/* FIXME: Use represent_as instead */
struct dom_sid;
NTSTATUS ndr_push_dom_sid2(struct ndr_push *ndr, int ndr_flags, const struct dom_sid *sid);
NTSTATUS ndr_pull_dom_sid2(struct ndr_pull *ndr, int ndr_flags, struct dom_sid *sid);
void ndr_print_dom_sid2(struct ndr_print *ndr, const char *name, const struct dom_sid *sid);
NTSTATUS ndr_push_dom_sid28(struct ndr_push *ndr, int ndr_flags, const struct dom_sid *sid);
NTSTATUS ndr_pull_dom_sid28(struct ndr_pull *ndr, int ndr_flags, struct dom_sid *sid);
void ndr_print_dom_sid28(struct ndr_print *ndr, const char *name, const struct dom_sid *sid);
size_t ndr_size_dom_sid28(const struct dom_sid *sid, int flags);
struct IWbemClassObject;
NTSTATUS ndr_push_IWbemClassObject(struct ndr_push *ndr, int ndr_flags, const struct IWbemClassObject *r);
NTSTATUS ndr_pull_IWbemClassObject(struct ndr_pull *ndr, int ndr_flags, struct IWbemClassObject *r);
#endif /* __LIBNDR_H__ */
File diff suppressed because it is too large Load Diff
+850
View File
@@ -0,0 +1,850 @@
/*
Unix SMB/CIFS implementation.
routines for marshalling/unmarshalling basic types
Copyright (C) Andrew Tridgell 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"
#include "system/network.h"
#include "librpc/ndr/libndr.h"
#define NDR_SVAL(ndr, ofs) (NDR_BE(ndr)?RSVAL(ndr->data,ofs):SVAL(ndr->data,ofs))
#define NDR_IVAL(ndr, ofs) (NDR_BE(ndr)?RIVAL(ndr->data,ofs):IVAL(ndr->data,ofs))
#define NDR_IVALS(ndr, ofs) (NDR_BE(ndr)?RIVALS(ndr->data,ofs):IVALS(ndr->data,ofs))
#define NDR_SSVAL(ndr, ofs, v) do { if (NDR_BE(ndr)) { RSSVAL(ndr->data,ofs,v); } else SSVAL(ndr->data,ofs,v); } while (0)
#define NDR_SIVAL(ndr, ofs, v) do { if (NDR_BE(ndr)) { RSIVAL(ndr->data,ofs,v); } else SIVAL(ndr->data,ofs,v); } while (0)
#define NDR_SIVALS(ndr, ofs, v) do { if (NDR_BE(ndr)) { RSIVALS(ndr->data,ofs,v); } else SIVALS(ndr->data,ofs,v); } while (0)
/*
check for data leaks from the server by looking for non-zero pad bytes
these could also indicate that real structure elements have been
mistaken for padding in the IDL
*/
_PUBLIC_ void ndr_check_padding(struct ndr_pull *ndr, size_t n)
{
size_t ofs2 = (ndr->offset + (n-1)) & ~(n-1);
int i;
for (i=ndr->offset;i<ofs2;i++) {
if (ndr->data[i] != 0) {
break;
}
}
if (i<ofs2) {
DEBUG(0,("WARNING: Non-zero padding to %d: ", (int)n));
for (i=ndr->offset;i<ofs2;i++) {
DEBUG(0,("%02x ", ndr->data[i]));
}
DEBUG(0,("\n"));
}
}
/*
parse a int8_t
*/
_PUBLIC_ NTSTATUS ndr_pull_int8(struct ndr_pull *ndr, int ndr_flags, int8_t *v)
{
NDR_PULL_NEED_BYTES(ndr, 1);
*v = (int8_t)CVAL(ndr->data, ndr->offset);
ndr->offset += 1;
return NT_STATUS_OK;
}
/*
parse a uint8_t
*/
_PUBLIC_ NTSTATUS ndr_pull_uint8(struct ndr_pull *ndr, int ndr_flags, uint8_t *v)
{
NDR_PULL_NEED_BYTES(ndr, 1);
*v = CVAL(ndr->data, ndr->offset);
ndr->offset += 1;
return NT_STATUS_OK;
}
/*
parse a int16_t
*/
_PUBLIC_ NTSTATUS ndr_pull_int16(struct ndr_pull *ndr, int ndr_flags, int16_t *v)
{
NDR_PULL_ALIGN(ndr, 2);
NDR_PULL_NEED_BYTES(ndr, 2);
*v = (uint16_t)NDR_SVAL(ndr, ndr->offset);
ndr->offset += 2;
return NT_STATUS_OK;
}
/*
parse a uint16_t
*/
_PUBLIC_ NTSTATUS ndr_pull_uint16(struct ndr_pull *ndr, int ndr_flags, uint16_t *v)
{
NDR_PULL_ALIGN(ndr, 2);
NDR_PULL_NEED_BYTES(ndr, 2);
*v = NDR_SVAL(ndr, ndr->offset);
ndr->offset += 2;
return NT_STATUS_OK;
}
/*
parse a int32_t
*/
_PUBLIC_ NTSTATUS ndr_pull_int32(struct ndr_pull *ndr, int ndr_flags, int32_t *v)
{
NDR_PULL_ALIGN(ndr, 4);
NDR_PULL_NEED_BYTES(ndr, 4);
*v = NDR_IVALS(ndr, ndr->offset);
ndr->offset += 4;
return NT_STATUS_OK;
}
/*
parse a uint32_t
*/
_PUBLIC_ NTSTATUS ndr_pull_uint32(struct ndr_pull *ndr, int ndr_flags, uint32_t *v)
{
NDR_PULL_ALIGN(ndr, 4);
NDR_PULL_NEED_BYTES(ndr, 4);
*v = NDR_IVAL(ndr, ndr->offset);
ndr->offset += 4;
return NT_STATUS_OK;
}
/*
parse a pointer referent identifier
*/
_PUBLIC_ NTSTATUS ndr_pull_generic_ptr(struct ndr_pull *ndr, uint32_t *v)
{
NTSTATUS status;
status = ndr_pull_uint32(ndr, NDR_SCALARS, v);
if (NT_STATUS_IS_OK(status) && *v != 0) {
ndr->ptr_count++;
}
return status;
}
/*
parse a ref pointer referent identifier
*/
_PUBLIC_ NTSTATUS ndr_pull_ref_ptr(struct ndr_pull *ndr, uint32_t *v)
{
NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, v));
/* ref pointers always point to data */
*v = 1;
return NT_STATUS_OK;
}
/*
parse a udlong
*/
_PUBLIC_ NTSTATUS ndr_pull_udlong(struct ndr_pull *ndr, int ndr_flags, uint64_t *v)
{
NDR_PULL_ALIGN(ndr, 4);
NDR_PULL_NEED_BYTES(ndr, 8);
*v = NDR_IVAL(ndr, ndr->offset);
*v |= (uint64_t)(NDR_IVAL(ndr, ndr->offset+4)) << 32;
ndr->offset += 8;
return NT_STATUS_OK;
}
/*
parse a udlongr
*/
_PUBLIC_ NTSTATUS ndr_pull_udlongr(struct ndr_pull *ndr, int ndr_flags, uint64_t *v)
{
NDR_PULL_ALIGN(ndr, 4);
NDR_PULL_NEED_BYTES(ndr, 8);
*v = ((uint64_t)NDR_IVAL(ndr, ndr->offset)) << 32;
*v |= NDR_IVAL(ndr, ndr->offset+4);
ndr->offset += 8;
return NT_STATUS_OK;
}
/*
parse a dlong
*/
_PUBLIC_ NTSTATUS ndr_pull_dlong(struct ndr_pull *ndr, int ndr_flags, int64_t *v)
{
return ndr_pull_udlong(ndr, ndr_flags, (uint64_t *)v);
}
/*
parse a hyper
*/
_PUBLIC_ NTSTATUS ndr_pull_hyper(struct ndr_pull *ndr, int ndr_flags, uint64_t *v)
{
NDR_PULL_ALIGN(ndr, 8);
return ndr_pull_udlong(ndr, ndr_flags, v);
}
/*
parse a pointer
*/
_PUBLIC_ NTSTATUS ndr_pull_pointer(struct ndr_pull *ndr, int ndr_flags, void* *v)
{
intptr_t h;
NDR_PULL_ALIGN(ndr, sizeof(h));
NDR_PULL_NEED_BYTES(ndr, sizeof(h));
memcpy(&h, ndr->data+ndr->offset, sizeof(h));
ndr->offset += sizeof(h);
*v = (void *)h;
return NT_STATUS_OK;
}
/*
pull a NTSTATUS
*/
_PUBLIC_ NTSTATUS ndr_pull_NTSTATUS(struct ndr_pull *ndr, int ndr_flags, NTSTATUS *status)
{
uint32_t v;
NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &v));
*status = NT_STATUS(v);
return NT_STATUS_OK;
}
/*
push a NTSTATUS
*/
_PUBLIC_ NTSTATUS ndr_push_NTSTATUS(struct ndr_push *ndr, int ndr_flags, NTSTATUS status)
{
return ndr_push_uint32(ndr, ndr_flags, NT_STATUS_V(status));
}
_PUBLIC_ void ndr_print_NTSTATUS(struct ndr_print *ndr, const char *name, NTSTATUS r)
{
ndr->print(ndr, "%-25s: %s", name, nt_errstr(r));
}
/*
pull a WERROR
*/
_PUBLIC_ NTSTATUS ndr_pull_WERROR(struct ndr_pull *ndr, int ndr_flags, WERROR *status)
{
uint32_t v;
NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &v));
*status = W_ERROR(v);
return NT_STATUS_OK;
}
/*
push a WERROR
*/
_PUBLIC_ NTSTATUS ndr_push_WERROR(struct ndr_push *ndr, int ndr_flags, WERROR status)
{
return ndr_push_uint32(ndr, NDR_SCALARS, W_ERROR_V(status));
}
_PUBLIC_ void ndr_print_WERROR(struct ndr_print *ndr, const char *name, WERROR r)
{
ndr->print(ndr, "%-25s: %s", name, win_errstr(r));
}
/*
parse a set of bytes
*/
_PUBLIC_ NTSTATUS ndr_pull_bytes(struct ndr_pull *ndr, uint8_t *data, uint32_t n)
{
NDR_PULL_NEED_BYTES(ndr, n);
memcpy(data, ndr->data + ndr->offset, n);
ndr->offset += n;
return NT_STATUS_OK;
}
/*
pull an array of uint8
*/
_PUBLIC_ NTSTATUS ndr_pull_array_uint8(struct ndr_pull *ndr, int ndr_flags, uint8_t *data, uint32_t n)
{
if (!(ndr_flags & NDR_SCALARS)) {
return NT_STATUS_OK;
}
return ndr_pull_bytes(ndr, data, n);
}
/*
push a int8_t
*/
_PUBLIC_ NTSTATUS ndr_push_int8(struct ndr_push *ndr, int ndr_flags, int8_t v)
{
NDR_PUSH_NEED_BYTES(ndr, 1);
SCVAL(ndr->data, ndr->offset, (uint8_t)v);
ndr->offset += 1;
return NT_STATUS_OK;
}
/*
push a uint8_t
*/
_PUBLIC_ NTSTATUS ndr_push_uint8(struct ndr_push *ndr, int ndr_flags, uint8_t v)
{
NDR_PUSH_NEED_BYTES(ndr, 1);
SCVAL(ndr->data, ndr->offset, v);
ndr->offset += 1;
return NT_STATUS_OK;
}
/*
push a int16_t
*/
_PUBLIC_ NTSTATUS ndr_push_int16(struct ndr_push *ndr, int ndr_flags, int16_t v)
{
NDR_PUSH_ALIGN(ndr, 2);
NDR_PUSH_NEED_BYTES(ndr, 2);
NDR_SSVAL(ndr, ndr->offset, (uint16_t)v);
ndr->offset += 2;
return NT_STATUS_OK;
}
/*
push a uint16_t
*/
_PUBLIC_ NTSTATUS ndr_push_uint16(struct ndr_push *ndr, int ndr_flags, uint16_t v)
{
NDR_PUSH_ALIGN(ndr, 2);
NDR_PUSH_NEED_BYTES(ndr, 2);
NDR_SSVAL(ndr, ndr->offset, v);
ndr->offset += 2;
return NT_STATUS_OK;
}
/*
push a int32_t
*/
_PUBLIC_ NTSTATUS ndr_push_int32(struct ndr_push *ndr, int ndr_flags, int32_t v)
{
NDR_PUSH_ALIGN(ndr, 4);
NDR_PUSH_NEED_BYTES(ndr, 4);
NDR_SIVALS(ndr, ndr->offset, v);
ndr->offset += 4;
return NT_STATUS_OK;
}
/*
push a uint32_t
*/
_PUBLIC_ NTSTATUS ndr_push_uint32(struct ndr_push *ndr, int ndr_flags, uint32_t v)
{
NDR_PUSH_ALIGN(ndr, 4);
NDR_PUSH_NEED_BYTES(ndr, 4);
NDR_SIVAL(ndr, ndr->offset, v);
ndr->offset += 4;
return NT_STATUS_OK;
}
/*
push a udlong
*/
_PUBLIC_ NTSTATUS ndr_push_udlong(struct ndr_push *ndr, int ndr_flags, uint64_t v)
{
NDR_PUSH_ALIGN(ndr, 4);
NDR_PUSH_NEED_BYTES(ndr, 8);
NDR_SIVAL(ndr, ndr->offset, (v & 0xFFFFFFFF));
NDR_SIVAL(ndr, ndr->offset+4, (v>>32));
ndr->offset += 8;
return NT_STATUS_OK;
}
/*
push a udlongr
*/
_PUBLIC_ NTSTATUS ndr_push_udlongr(struct ndr_push *ndr, int ndr_flags, uint64_t v)
{
NDR_PUSH_ALIGN(ndr, 4);
NDR_PUSH_NEED_BYTES(ndr, 8);
NDR_SIVAL(ndr, ndr->offset, (v>>32));
NDR_SIVAL(ndr, ndr->offset+4, (v & 0xFFFFFFFF));
ndr->offset += 8;
return NT_STATUS_OK;
}
/*
push a dlong
*/
_PUBLIC_ NTSTATUS ndr_push_dlong(struct ndr_push *ndr, int ndr_flags, int64_t v)
{
return ndr_push_udlong(ndr, NDR_SCALARS, (uint64_t)v);
}
/*
push a hyper
*/
_PUBLIC_ NTSTATUS ndr_push_hyper(struct ndr_push *ndr, int ndr_flags, uint64_t v)
{
NDR_PUSH_ALIGN(ndr, 8);
return ndr_push_udlong(ndr, NDR_SCALARS, v);
}
/*
push a pointer
*/
_PUBLIC_ NTSTATUS ndr_push_pointer(struct ndr_push *ndr, int ndr_flags, void* v)
{
intptr_t h = (intptr_t)v;
NDR_PUSH_ALIGN(ndr, sizeof(h));
NDR_PUSH_NEED_BYTES(ndr, sizeof(h));
memcpy(ndr->data+ndr->offset, &h, sizeof(h));
ndr->offset += sizeof(h);
return NT_STATUS_OK;
}
_PUBLIC_ NTSTATUS ndr_push_align(struct ndr_push *ndr, size_t size)
{
NDR_PUSH_ALIGN(ndr, size);
return NT_STATUS_OK;
}
_PUBLIC_ NTSTATUS ndr_pull_align(struct ndr_pull *ndr, size_t size)
{
NDR_PULL_ALIGN(ndr, size);
return NT_STATUS_OK;
}
/*
push some bytes
*/
_PUBLIC_ NTSTATUS ndr_push_bytes(struct ndr_push *ndr, const uint8_t *data, uint32_t n)
{
NDR_PUSH_NEED_BYTES(ndr, n);
memcpy(ndr->data + ndr->offset, data, n);
ndr->offset += n;
return NT_STATUS_OK;
}
/*
push some zero bytes
*/
_PUBLIC_ NTSTATUS ndr_push_zero(struct ndr_push *ndr, uint32_t n)
{
NDR_PUSH_NEED_BYTES(ndr, n);
memset(ndr->data + ndr->offset, 0, n);
ndr->offset += n;
return NT_STATUS_OK;
}
/*
push an array of uint8
*/
_PUBLIC_ NTSTATUS ndr_push_array_uint8(struct ndr_push *ndr, int ndr_flags, const uint8_t *data, uint32_t n)
{
if (!(ndr_flags & NDR_SCALARS)) {
return NT_STATUS_OK;
}
return ndr_push_bytes(ndr, data, n);
}
/*
save the current position
*/
_PUBLIC_ void ndr_push_save(struct ndr_push *ndr, struct ndr_push_save *save)
{
save->offset = ndr->offset;
}
/*
restore the position
*/
_PUBLIC_ void ndr_push_restore(struct ndr_push *ndr, struct ndr_push_save *save)
{
ndr->offset = save->offset;
}
/*
push a unique non-zero value if a pointer is non-NULL, otherwise 0
*/
_PUBLIC_ NTSTATUS ndr_push_unique_ptr(struct ndr_push *ndr, const void *p)
{
uint32_t ptr = 0;
if (p) {
ptr = ndr->ptr_count * 4;
ptr |= 0x00020000;
ndr->ptr_count++;
}
return ndr_push_uint32(ndr, NDR_SCALARS, ptr);
}
/*
push a 'simple' full non-zero value if a pointer is non-NULL, otherwise 0
*/
_PUBLIC_ NTSTATUS ndr_push_full_ptr(struct ndr_push *ndr, const void *p)
{
uint32_t ptr = 0;
if (p) {
/* Check if the pointer already exists and has an id */
ptr = ndr_token_peek(&ndr->full_ptr_list, p);
if (ptr == 0) {
ndr->ptr_count++;
ptr = ndr->ptr_count;
ndr_token_store(ndr, &ndr->full_ptr_list, p, ptr);
}
}
return ndr_push_uint32(ndr, NDR_SCALARS, ptr);
}
/*
push always a 0, if a pointer is NULL it's a fatal error
*/
_PUBLIC_ NTSTATUS ndr_push_ref_ptr(struct ndr_push *ndr)
{
return ndr_push_uint32(ndr, NDR_SCALARS, 0xAEF1AEF1);
}
/*
push a NTTIME
*/
_PUBLIC_ NTSTATUS ndr_push_NTTIME(struct ndr_push *ndr, int ndr_flags, NTTIME t)
{
NDR_CHECK(ndr_push_udlong(ndr, ndr_flags, t));
return NT_STATUS_OK;
}
/*
pull a NTTIME
*/
_PUBLIC_ NTSTATUS ndr_pull_NTTIME(struct ndr_pull *ndr, int ndr_flags, NTTIME *t)
{
NDR_CHECK(ndr_pull_udlong(ndr, ndr_flags, t));
return NT_STATUS_OK;
}
/*
push a NTTIME
*/
_PUBLIC_ NTSTATUS ndr_push_NTTIME_1sec(struct ndr_push *ndr, int ndr_flags, NTTIME t)
{
t /= 10000000;
NDR_CHECK(ndr_push_hyper(ndr, ndr_flags, t));
return NT_STATUS_OK;
}
/*
pull a NTTIME_1sec
*/
_PUBLIC_ NTSTATUS ndr_pull_NTTIME_1sec(struct ndr_pull *ndr, int ndr_flags, NTTIME *t)
{
NDR_CHECK(ndr_pull_hyper(ndr, ndr_flags, t));
(*t) *= 10000000;
return NT_STATUS_OK;
}
/*
pull a NTTIME_hyper
*/
_PUBLIC_ NTSTATUS ndr_pull_NTTIME_hyper(struct ndr_pull *ndr, int ndr_flags, NTTIME *t)
{
NDR_CHECK(ndr_pull_hyper(ndr, ndr_flags, t));
return NT_STATUS_OK;
}
/*
push a NTTIME_hyper
*/
_PUBLIC_ NTSTATUS ndr_push_NTTIME_hyper(struct ndr_push *ndr, int ndr_flags, NTTIME t)
{
NDR_CHECK(ndr_push_hyper(ndr, ndr_flags, t));
return NT_STATUS_OK;
}
/*
push a time_t
*/
_PUBLIC_ NTSTATUS ndr_push_time_t(struct ndr_push *ndr, int ndr_flags, time_t t)
{
return ndr_push_uint32(ndr, ndr_flags, t);
}
/*
pull a time_t
*/
_PUBLIC_ NTSTATUS ndr_pull_time_t(struct ndr_pull *ndr, int ndr_flags, time_t *t)
{
uint32_t tt;
NDR_CHECK(ndr_pull_uint32(ndr, ndr_flags, &tt));
*t = tt;
return NT_STATUS_OK;
}
/*
pull a ipv4address
*/
_PUBLIC_ NTSTATUS ndr_pull_ipv4address(struct ndr_pull *ndr, int ndr_flags, const char **address)
{
struct ipv4_addr in;
NDR_CHECK(ndr_pull_uint32(ndr, ndr_flags, &in.addr));
in.addr = htonl(in.addr);
*address = talloc_strdup(ndr->current_mem_ctx, sys_inet_ntoa(in));
NT_STATUS_HAVE_NO_MEMORY(*address);
return NT_STATUS_OK;
}
/*
push a ipv4address
*/
_PUBLIC_ NTSTATUS ndr_push_ipv4address(struct ndr_push *ndr, int ndr_flags, const char *address)
{
uint32_t addr;
if (!is_ipaddress(address)) {
return ndr_push_error(ndr, NDR_ERR_IPV4ADDRESS,
"Invalid IPv4 address: '%s'",
address);
}
addr = inet_addr(address);
NDR_CHECK(ndr_push_uint32(ndr, ndr_flags, htonl(addr)));
return NT_STATUS_OK;
}
/*
print a ipv4address
*/
_PUBLIC_ void ndr_print_ipv4address(struct ndr_print *ndr, const char *name,
const char *address)
{
ndr->print(ndr, "%-25s: %s", name, address);
}
_PUBLIC_ void ndr_print_struct(struct ndr_print *ndr, const char *name, const char *type)
{
ndr->print(ndr, "%s: struct %s", name, type);
}
_PUBLIC_ void ndr_print_enum(struct ndr_print *ndr, const char *name, const char *type,
const char *val, uint32_t value)
{
if (ndr->flags & LIBNDR_PRINT_ARRAY_HEX) {
ndr->print(ndr, "%-25s: %s (0x%X)", name, val?val:"UNKNOWN_ENUM_VALUE", value);
} else {
ndr->print(ndr, "%-25s: %s (%d)", name, val?val:"UNKNOWN_ENUM_VALUE", value);
}
}
_PUBLIC_ void ndr_print_bitmap_flag(struct ndr_print *ndr, size_t size, const char *flag_name, uint32_t flag, uint32_t value)
{
/* this is an attempt to support multi-bit bitmap masks */
value &= flag;
while (!(flag & 1)) {
flag >>= 1;
value >>= 1;
}
if (flag == 1) {
ndr->print(ndr, " %d: %-25s", value, flag_name);
} else {
ndr->print(ndr, "0x%02x: %-25s (%d)", value, flag_name, value);
}
}
_PUBLIC_ void ndr_print_int8(struct ndr_print *ndr, const char *name, int8_t v)
{
ndr->print(ndr, "%-25s: %d", name, v);
}
_PUBLIC_ void ndr_print_uint8(struct ndr_print *ndr, const char *name, uint8_t v)
{
ndr->print(ndr, "%-25s: 0x%02x (%u)", name, v, v);
}
_PUBLIC_ void ndr_print_int16(struct ndr_print *ndr, const char *name, int16_t v)
{
ndr->print(ndr, "%-25s: %d", name, v);
}
_PUBLIC_ void ndr_print_uint16(struct ndr_print *ndr, const char *name, uint16_t v)
{
ndr->print(ndr, "%-25s: 0x%04x (%u)", name, v, v);
}
_PUBLIC_ void ndr_print_int32(struct ndr_print *ndr, const char *name, int32_t v)
{
ndr->print(ndr, "%-25s: %d", name, v);
}
_PUBLIC_ void ndr_print_uint32(struct ndr_print *ndr, const char *name, uint32_t v)
{
ndr->print(ndr, "%-25s: 0x%08x (%u)", name, v, v);
}
_PUBLIC_ void ndr_print_udlong(struct ndr_print *ndr, const char *name, uint64_t v)
{
ndr->print(ndr, "%-25s: 0x%016llx (%llu)", name, (unsigned long long)v, (unsigned long long)v);
}
_PUBLIC_ void ndr_print_udlongr(struct ndr_print *ndr, const char *name, uint64_t v)
{
ndr_print_udlong(ndr, name, v);
}
_PUBLIC_ void ndr_print_dlong(struct ndr_print *ndr, const char *name, int64_t v)
{
ndr->print(ndr, "%-25s: 0x%016llx (%lld)", name, (unsigned long long)v, (long long)v);
}
_PUBLIC_ void ndr_print_hyper(struct ndr_print *ndr, const char *name, uint64_t v)
{
ndr_print_dlong(ndr, name, v);
}
_PUBLIC_ void ndr_print_pointer(struct ndr_print *ndr, const char *name, void *v)
{
ndr->print(ndr, "%-25s: %p", name, v);
}
_PUBLIC_ void ndr_print_ptr(struct ndr_print *ndr, const char *name, const void *p)
{
if (p) {
ndr->print(ndr, "%-25s: *", name);
} else {
ndr->print(ndr, "%-25s: NULL", name);
}
}
_PUBLIC_ void ndr_print_NTTIME(struct ndr_print *ndr, const char *name, NTTIME t)
{
ndr->print(ndr, "%-25s: %s", name, nt_time_string(ndr, t));
}
_PUBLIC_ void ndr_print_NTTIME_1sec(struct ndr_print *ndr, const char *name, NTTIME t)
{
/* this is a standard NTTIME here
* as it's already converted in the pull/push code
*/
ndr_print_NTTIME(ndr, name, t);
}
_PUBLIC_ void ndr_print_NTTIME_hyper(struct ndr_print *ndr, const char *name, NTTIME t)
{
ndr_print_NTTIME(ndr, name, t);
}
_PUBLIC_ void ndr_print_time_t(struct ndr_print *ndr, const char *name, time_t t)
{
if (t == (time_t)-1 || t == 0) {
ndr->print(ndr, "%-25s: (time_t)%d", name, (int)t);
} else {
ndr->print(ndr, "%-25s: %s", name, timestring(ndr, t));
}
}
_PUBLIC_ void ndr_print_union(struct ndr_print *ndr, const char *name, int level, const char *type)
{
if (ndr->flags & LIBNDR_PRINT_ARRAY_HEX) {
ndr->print(ndr, "%-25s: union %s(case 0x%X)", name, type, level);
} else {
ndr->print(ndr, "%-25s: union %s(case %d)", name, type, level);
}
}
_PUBLIC_ void ndr_print_bad_level(struct ndr_print *ndr, const char *name, uint16_t level)
{
ndr->print(ndr, "UNKNOWN LEVEL %u", level);
}
_PUBLIC_ void ndr_print_array_uint8(struct ndr_print *ndr, const char *name,
const uint8_t *data, uint32_t count)
{
int i;
if (count <= 600 && (ndr->flags & LIBNDR_PRINT_ARRAY_HEX)) {
char s[1202];
for (i=0;i<count;i++) {
snprintf(&s[i*2], 3, "%02x", data[i]);
}
s[i*2] = 0;
ndr->print(ndr, "%-25s: %s", name, s);
return;
}
ndr->print(ndr, "%s: ARRAY(%d)", name, count);
ndr->depth++;
for (i=0;i<count;i++) {
char *idx=NULL;
asprintf(&idx, "[%d]", i);
if (idx) {
ndr_print_uint8(ndr, idx, data[i]);
free(idx);
}
}
ndr->depth--;
}
_PUBLIC_ void ndr_print_DATA_BLOB(struct ndr_print *ndr, const char *name, DATA_BLOB r)
{
ndr->print(ndr, "%-25s: DATA_BLOB length=%u", name, (unsigned)r.length);
if (r.length) {
dump_data(10, r.data, r.length);
}
}
/*
push a DATA_BLOB onto the wire.
*/
_PUBLIC_ NTSTATUS ndr_push_DATA_BLOB(struct ndr_push *ndr, int ndr_flags, DATA_BLOB blob)
{
if (ndr->flags & LIBNDR_ALIGN_FLAGS) {
if (ndr->flags & LIBNDR_FLAG_ALIGN2) {
blob.length = NDR_ALIGN(ndr, 2);
} else if (ndr->flags & LIBNDR_FLAG_ALIGN4) {
blob.length = NDR_ALIGN(ndr, 4);
} else if (ndr->flags & LIBNDR_FLAG_ALIGN8) {
blob.length = NDR_ALIGN(ndr, 8);
}
NDR_PUSH_ALLOC_SIZE(ndr, blob.data, blob.length);
data_blob_clear(&blob);
} else if (!(ndr->flags & LIBNDR_FLAG_REMAINING)) {
NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, blob.length));
}
NDR_CHECK(ndr_push_bytes(ndr, blob.data, blob.length));
return NT_STATUS_OK;
}
/*
pull a DATA_BLOB from the wire.
*/
_PUBLIC_ NTSTATUS ndr_pull_DATA_BLOB(struct ndr_pull *ndr, int ndr_flags, DATA_BLOB *blob)
{
uint32_t length = 0;
if (ndr->flags & LIBNDR_ALIGN_FLAGS) {
if (ndr->flags & LIBNDR_FLAG_ALIGN2) {
length = NDR_ALIGN(ndr, 2);
} else if (ndr->flags & LIBNDR_FLAG_ALIGN4) {
length = NDR_ALIGN(ndr, 4);
} else if (ndr->flags & LIBNDR_FLAG_ALIGN8) {
length = NDR_ALIGN(ndr, 8);
}
if (ndr->data_size - ndr->offset < length) {
length = ndr->data_size - ndr->offset;
}
} else if (ndr->flags & LIBNDR_FLAG_REMAINING) {
length = ndr->data_size - ndr->offset;
} else {
NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &length));
}
NDR_PULL_NEED_BYTES(ndr, length);
*blob = data_blob_talloc(ndr->current_mem_ctx, ndr->data+ndr->offset, length);
ndr->offset += length;
return NT_STATUS_OK;
}
_PUBLIC_ uint32_t ndr_size_DATA_BLOB(int ret, const DATA_BLOB *data, int flags)
{
return ret + data->length;
}
+293
View File
@@ -0,0 +1,293 @@
/*
Unix SMB/CIFS implementation.
libndr compression support
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 "lib/compression/mszip.h"
#include "librpc/ndr/libndr.h"
static NTSTATUS ndr_pull_compression_mszip_chunk(struct ndr_pull *ndrpull,
struct ndr_push *ndrpush,
struct decomp_state *decomp_state)
{
DATA_BLOB comp_chunk;
uint32_t comp_chunk_offset;
uint32_t comp_chunk_size;
DATA_BLOB plain_chunk;
uint32_t plain_chunk_offset;
uint32_t plain_chunk_size;
int ret;
NDR_CHECK(ndr_pull_uint32(ndrpull, NDR_SCALARS, &plain_chunk_size));
if (plain_chunk_size > 0x00008000) {
return ndr_pull_error(ndrpull, NDR_ERR_COMPRESSION, "Bad MSZIP plain chunk size %08X > 0x00008000 (PULL)",
plain_chunk_size);
}
NDR_CHECK(ndr_pull_uint32(ndrpull, NDR_SCALARS, &comp_chunk_size));
DEBUG(10,("MSZIP plain_chunk_size: %08X (%u) comp_chunk_size: %08X (%u)\n",
plain_chunk_size, plain_chunk_size, comp_chunk_size, comp_chunk_size));
comp_chunk_offset = ndrpull->offset;
NDR_CHECK(ndr_pull_advance(ndrpull, comp_chunk_size));
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;
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 ((plain_chunk_size < 0x00008000) || (ndrpull->offset+4 >= ndrpull->data_size)) {
/* this is the last chunk */
return NT_STATUS_OK;
}
return NT_STATUS_MORE_PROCESSING_REQUIRED;
}
static NTSTATUS ndr_pull_compression_mszip(struct ndr_pull *subndr,
struct ndr_pull **_comndr,
ssize_t decompressed_len)
{
NTSTATUS status = NT_STATUS_MORE_PROCESSING_REQUIRED;
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;
ndrpush = ndr_push_init_ctx(subndr);
NT_STATUS_HAVE_NO_MEMORY(ndrpush);
decomp_state = ZIPdecomp_state(subndr);
NT_STATUS_HAVE_NO_MEMORY(decomp_state);
while (NT_STATUS_EQUAL(NT_STATUS_MORE_PROCESSING_REQUIRED, status)) {
status = ndr_pull_compression_mszip_chunk(subndr, ndrpush, decomp_state);
}
NT_STATUS_NOT_OK_RETURN(status);
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);
}
comndr = talloc_zero(subndr, struct ndr_pull);
NT_STATUS_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;
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]);
}
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]);
}
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]);
}
payload_offset = comndr->offset;
NDR_CHECK(ndr_pull_advance(comndr, payload_size));
payload = comndr->data + payload_offset;
comndr->data = payload;
comndr->data_size = payload_size;
comndr->offset = 0;
*_comndr = comndr;
return NT_STATUS_OK;
}
static NTSTATUS 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 NTSTATUS ndr_pull_compression_xpress_chunk(struct ndr_pull *ndrpull,
struct ndr_push *ndrpush)
{
DATA_BLOB comp_chunk;
uint32_t comp_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)",
plain_chunk_size);
}
NDR_CHECK(ndr_pull_uint32(ndrpull, NDR_SCALARS, &comp_chunk_size));
NDR_CHECK(ndr_pull_advance(ndrpull, comp_chunk_size));
comp_chunk.length = comp_chunk_size + 8;
comp_chunk.data = ndrpull->data + comp_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));
if ((plain_chunk_size < 0x00010000) || (ndrpull->offset+4 >= ndrpull->data_size)) {
/* this is the last chunk */
return NT_STATUS_OK;
}
return NT_STATUS_MORE_PROCESSING_REQUIRED;
}
static NTSTATUS ndr_pull_compression_xpress(struct ndr_pull *subndr,
struct ndr_pull **_comndr,
ssize_t decompressed_len)
{
NTSTATUS status = NT_STATUS_MORE_PROCESSING_REQUIRED;
struct ndr_push *ndrpush;
struct ndr_pull *comndr;
DATA_BLOB uncompressed;
ndrpush = ndr_push_init_ctx(subndr);
NT_STATUS_HAVE_NO_MEMORY(ndrpush);
while (NT_STATUS_EQUAL(NT_STATUS_MORE_PROCESSING_REQUIRED, status)) {
status = ndr_pull_compression_xpress_chunk(subndr, ndrpush);
}
NT_STATUS_NOT_OK_RETURN(status);
uncompressed = ndr_push_blob(ndrpush);
comndr = talloc_zero(subndr, struct ndr_pull);
NT_STATUS_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 = comndr;
return NT_STATUS_OK;
}
static NTSTATUS 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
*/
NTSTATUS 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 NT_STATUS_OK;
}
NTSTATUS ndr_pull_compression_end(struct ndr_pull *subndr,
struct ndr_pull *comndr,
enum ndr_compression_alg compression_alg,
ssize_t decompressed_len)
{
return NT_STATUS_OK;
}
/*
push a compressed subcontext
*/
NTSTATUS ndr_push_compression_start(struct ndr_push *subndr,
struct ndr_push **_comndr,
enum ndr_compression_alg compression_alg,
ssize_t decompressed_len)
{
struct ndr_push *comndr;
comndr = ndr_push_init_ctx(subndr);
NT_STATUS_HAVE_NO_MEMORY(comndr);
comndr->flags = subndr->flags;
*_comndr = comndr;
return NT_STATUS_OK;
}
/*
push a compressed subcontext
*/
NTSTATUS ndr_push_compression_end(struct ndr_push *subndr,
struct ndr_push *comndr,
enum ndr_compression_alg compression_alg,
ssize_t decompressed_len)
{
switch (compression_alg) {
case NDR_COMPRESSION_MSZIP:
return ndr_push_compression_mszip(subndr, comndr);
case NDR_COMPRESSION_XPRESS:
return ndr_push_compression_xpress(subndr, comndr);
default:
return ndr_push_error(subndr, NDR_ERR_COMPRESSION, "Bad compression algorithm %d (PUSH)",
compression_alg);
}
return NT_STATUS_OK;
}
+902
View File
@@ -0,0 +1,902 @@
/*
Unix SMB/CIFS implementation.
routines for marshalling/unmarshalling DCOM string arrays
Copyright (C) Jelmer Vernooij 2004
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_dcom.h"
// Just for debugging
#ifdef NDR_CHECK_DEBUG
int NDR_CHECK_depth = 0;
int NDR_CHECK_shift = 0x48;
#endif
int get_CIMTYPE_size(int t)
{
if (t & CIM_FLAG_ARRAY) return 4;
t &= 0x1FF;
switch (t) {
case CIM_SINT8:
case CIM_UINT8:
return 1;
case CIM_SINT16:
case CIM_UINT16:
case CIM_BOOLEAN:
return 2;
case CIM_SINT32:
case CIM_UINT32:
case CIM_REAL32:
case CIM_STRING:
case CIM_DATETIME:
case CIM_REFERENCE:
case CIM_OBJECT:
return 4;
case CIM_SINT64:
case CIM_UINT64:
case CIM_REAL64:
return 8;
default:
DEBUG(0, ("Unknown CIMTYPE size for %04X", t));
return 4;
}
}
NTSTATUS ndr_push_BSTR(struct ndr_push *ndr, int ndr_flags, const BSTR *r)
{
uint32_t len;
uint32_t flags;
NTSTATUS status;
len = strlen(*r);
if (ndr_flags & NDR_SCALARS) {
NDR_CHECK(ndr_push_align(ndr, 4));
NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, 0x72657355));
NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, len));
NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, 2*len));
flags = ndr->flags;
ndr_set_flags(&ndr->flags, LIBNDR_FLAG_STR_NOTERM | LIBNDR_FLAG_STR_SIZE4);
status = ndr_push_string(ndr, NDR_SCALARS, *r);
ndr->flags = flags;
return status;
}
return NT_STATUS_OK;
}
NTSTATUS ndr_pull_BSTR(struct ndr_pull *ndr, int ndr_flags, BSTR *r)
{
return NT_STATUS_NOT_SUPPORTED;
}
void ndr_print_BSTR(struct ndr_print *ndr, const char *name, const BSTR *r)
{
ndr->print(ndr, "%-25s: BSTR(\"%s\")", name, *r);
}
NTSTATUS ndr_push_CIMSTRING(struct ndr_push *ndr, int ndr_flags, const CIMSTRING *r)
{
uint8_t u;
NTSTATUS status;
if (!(ndr_flags & NDR_SCALARS)) return NT_STATUS_OK;
NDR_CHECK(ndr_push_uint8(ndr, NDR_SCALARS, 0));
u = ndr->flags;
ndr->flags |= LIBNDR_FLAG_STR_ASCII | LIBNDR_FLAG_STR_NULLTERM;
status = ndr_push_string(ndr, NDR_SCALARS, *r);
DEBUG(9, ("%08X: Push string: %s\n", ndr->offset, *r));
ndr->flags = u;
return status;
}
NTSTATUS ndr_pull_CIMSTRING(struct ndr_pull *ndr, int ndr_flags, CIMSTRING *r)
{
uint8_t u;
NTSTATUS status;
if (!(ndr_flags & NDR_SCALARS)) return NT_STATUS_OK;
NDR_CHECK(ndr_pull_uint8(ndr, NDR_SCALARS, &u));
switch (u) {
case 0:
u = ndr->flags;
ndr->flags |= LIBNDR_FLAG_STR_ASCII | LIBNDR_FLAG_STR_NULLTERM;
status = ndr_pull_string(ndr, NDR_SCALARS, r);
DEBUG(9, ("%08X: Pull string: %s\n", ndr->offset, *r));
ndr->flags = u;
return status;
case 1:
u = ndr->flags;
ndr->flags |= LIBNDR_FLAG_STR_NULLTERM;
status = ndr_pull_string(ndr, NDR_SCALARS, r);
DEBUG(9, ("%08X: Pull string: %s\n", ndr->offset, *r));
ndr->flags = u;
return status;
default: return NT_STATUS_NOT_SUPPORTED;
}
}
void ndr_print_CIMSTRING(struct ndr_print *ndr, const char *name, const CIMSTRING *r)
{
ndr->print(ndr, "%-25s: \"%s\"", name, *r);
}
NTSTATUS ndr_push_CIMSTRINGS(struct ndr_push *ndr, int ndr_flags, const struct CIMSTRINGS *r)
{
uint32_t ofs_size, ofs, i;
if (!(ndr_flags & NDR_SCALARS)) return NT_STATUS_OK;
ofs_size = ndr->offset;
NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, 0));
for (i = 0; i < r->count; ++i) {
ofs = ndr->offset;
NDR_CHECK(ndr_push_CIMSTRING(ndr, ndr_flags, &r->item[i]));
NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, ndr->offset - ofs));
}
ofs = ndr->offset;
ndr->offset = ofs_size;
NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, ofs - ofs_size));
ndr->offset = ofs;
return NT_STATUS_OK;
}
_PUBLIC_ NTSTATUS ndr_pull_CIMSTRINGS(struct ndr_pull *ndr, int ndr_flags, struct CIMSTRINGS *r)
{
uint32_t endofs;
uint32_t len;
TALLOC_CTX *mem_ctx;
uint32_t u;
if (!(ndr_flags & NDR_SCALARS)) return NT_STATUS_OK;
mem_ctx = ndr->current_mem_ctx;
NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &endofs));
endofs += ndr->offset - sizeof(endofs);
r->count = 0;
len = 5;
r->item = talloc_array(mem_ctx, CIMSTRING, len);
ndr->current_mem_ctx = r->item;
while (ndr->offset < endofs) {
if (r->count >= len) {
len += 3;
r->item = talloc_realloc(mem_ctx, r->item, CIMSTRING, len);
/* update the memory context with the realloc'ed ptr */
ndr->current_mem_ctx = r->item;
}
NDR_CHECK(ndr_pull_CIMSTRING(ndr, ndr_flags, &r->item[r->count]));
NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &u));
++r->count;
}
r->item = talloc_realloc(mem_ctx, r->item, CIMSTRING, r->count);
ndr->current_mem_ctx = mem_ctx;
return NT_STATUS_OK;
}
static const char *qualifier_keys[] = {[1] = "key", [3] = "read", [6] = "provider", [7] = "dynamic", [10] = "CIMTYPE" };
#define arr_sizeof(a) (sizeof(a)/sizeof(a[0]))
static const char *qn_unknown = "Unknown_qualifier_name";
_PUBLIC_ NTSTATUS ndr_push_WbemQualifier(struct ndr_push *ndr, int ndr_flags, const struct WbemQualifier *r)
{
if (ndr_flags & NDR_SCALARS) {
NDR_CHECK(ndr_push_align(ndr, 4));
NDR_CHECK(ndr_push_relative_ptr1(ndr, r->name));
NDR_CHECK(ndr_push_WBEM_FLAVOR_TYPE(ndr, NDR_SCALARS, r->flavors));
NDR_CHECK(ndr_push_CIMTYPE_ENUMERATION(ndr, NDR_SCALARS, r->cimtype));
NDR_CHECK(ndr_push_set_switch_value(ndr, &r->value, r->cimtype & CIM_TYPEMASK));
NDR_CHECK(ndr_push_CIMVAR(ndr, NDR_SCALARS, &r->value));
}
if (ndr_flags & NDR_BUFFERS) {
if (r->name) {
uint32_t ofs;
int32_t i;
for (i = 0; i < arr_sizeof(qualifier_keys); ++i)
if (qualifier_keys[i] && !strcmp(r->name, qualifier_keys[i])) break;
if (i == arr_sizeof(qualifier_keys)) {
if (!strncmp(qn_unknown, r->name, sizeof(qn_unknown) - 1))
i = atoi(r->name + sizeof(qn_unknown) - 1);
else
i = -1;
}
if (i >= 0) {
ofs = ndr->offset;
NDR_CHECK(ndr_token_retrieve(&ndr->relative_list, r->name, &ndr->offset));
NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, 0x80000000 | i));
ndr->offset = ofs;
} else {
NDR_CHECK(ndr_push_relative_ptr2(ndr, r->name));
NDR_CHECK(ndr_push_CIMSTRING(ndr, NDR_SCALARS, &r->name));
}
}
NDR_CHECK(ndr_push_CIMVAR(ndr, NDR_BUFFERS, &r->value));
}
return NT_STATUS_OK;
}
_PUBLIC_ NTSTATUS ndr_pull_WbemQualifier(struct ndr_pull *ndr, int ndr_flags, struct WbemQualifier *r)
{
uint32_t _ptr_name;
TALLOC_CTX *_mem_save_name_0;
if (ndr_flags & NDR_SCALARS) {
NDR_CHECK(ndr_pull_align(ndr, 4));
NDR_CHECK(ndr_pull_generic_ptr(ndr, &_ptr_name));
if (_ptr_name != 0xFFFFFFFF) {
NDR_PULL_ALLOC(ndr, r->name);
NDR_CHECK(ndr_pull_relative_ptr1(ndr, r->name, _ptr_name));
} else {
r->name = NULL;
}
NDR_CHECK(ndr_pull_WBEM_FLAVOR_TYPE(ndr, NDR_SCALARS, &r->flavors));
NDR_CHECK(ndr_pull_CIMTYPE_ENUMERATION(ndr, NDR_SCALARS, &r->cimtype));
NDR_CHECK(ndr_pull_set_switch_value(ndr, &r->value, r->cimtype & CIM_TYPEMASK));
NDR_CHECK(ndr_pull_CIMVAR(ndr, NDR_SCALARS, &r->value));
}
if (ndr_flags & NDR_BUFFERS) {
uint32_t relofs;
relofs = ndr_token_peek(&ndr->relative_list, r->name);
if (relofs & 0x80000000) {
relofs &= 0xFF;
if ((relofs < sizeof(qualifier_keys)/sizeof(qualifier_keys[0])) && qualifier_keys[relofs]) {
r->name = talloc_strdup(ndr->current_mem_ctx, qualifier_keys[relofs]);
} else {
r->name = talloc_asprintf(ndr->current_mem_ctx, "%s%d", qn_unknown, relofs);
}
} else if (r->name) {
struct ndr_pull_save _relative_save;
ndr_pull_save(ndr, &_relative_save);
NDR_CHECK(ndr_pull_relative_ptr2(ndr, r->name));
_mem_save_name_0 = NDR_PULL_GET_MEM_CTX(ndr);
NDR_PULL_SET_MEM_CTX(ndr, r->name, 0);
NDR_CHECK(ndr_pull_CIMSTRING(ndr, NDR_SCALARS, &r->name));
NDR_PULL_SET_MEM_CTX(ndr, _mem_save_name_0, 0);
ndr_pull_restore(ndr, &_relative_save);
}
NDR_CHECK(ndr_pull_CIMVAR(ndr, NDR_BUFFERS, &r->value));
}
return NT_STATUS_OK;
}
NTSTATUS ndr_push_WbemQualifiers(struct ndr_push *ndr, int ndr_flags, const struct WbemQualifiers *r)
{
uint32_t i, ofs, ofs_size;
if (ndr_flags & NDR_SCALARS) {
ofs_size = ndr->offset;
NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, 0));
for (i = 0; i < r->count; ++i)
NDR_CHECK(ndr_push_WbemQualifier(ndr, NDR_SCALARS, r->item[i]));
ofs = ndr->offset;
ndr->offset = ofs_size;
NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, ofs - ofs_size));
ndr->offset = ofs;
}
if (ndr_flags & NDR_BUFFERS) {
for (i = 0; i < r->count; ++i)
NDR_CHECK(ndr_push_WbemQualifier(ndr, NDR_BUFFERS, r->item[i]));
}
return NT_STATUS_OK;
}
NTSTATUS ndr_pull_WbemQualifiers(struct ndr_pull *ndr, int ndr_flags, struct WbemQualifiers *r)
{
uint32_t endofs;
uint32_t len;
TALLOC_CTX *mem_ctx;
mem_ctx = ndr->current_mem_ctx;
if (ndr_flags & NDR_SCALARS) {
NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &endofs));
endofs += ndr->offset - 4;
r->count = 0;
len = 10;
r->item = talloc_array(mem_ctx, struct WbemQualifier*, len);
ndr->current_mem_ctx = r->item;
while (ndr->offset < endofs) {
if (r->count >= len) {
len += 3;
r->item = talloc_realloc(mem_ctx, r->item, struct WbemQualifier*, len);
/* update the memory context with the realloc'ed ptr */
ndr->current_mem_ctx = r->item;
}
NDR_PULL_ALLOC(ndr, r->item[r->count]);
NDR_CHECK(ndr_pull_WbemQualifier(ndr, NDR_SCALARS, r->item[r->count]));
++r->count;
}
r->item = talloc_realloc(mem_ctx, r->item, struct WbemQualifier*, r->count);
}
if (ndr_flags & NDR_BUFFERS) {
uint32_t i;
ndr->current_mem_ctx = r->item;
for (i = 0; i < r->count; ++i) {
NDR_CHECK(ndr_pull_WbemQualifier(ndr, NDR_BUFFERS, r->item[i]));
}
}
ndr->current_mem_ctx = mem_ctx;
return NT_STATUS_OK;
}
NTSTATUS ndr_push_DataWithStack(struct ndr_push *ndr, ndr_push_flags_fn_t fn, const void *r)
{
uint32_t ofs, ofs_size, ofs_ssize;
ofs_size = ndr->offset;
NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, 0));
NDR_CHECK(fn(ndr, NDR_SCALARS, r));
ofs_ssize = ndr->offset;
NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, 0));
ndr->relative_base_offset = ndr->offset;
NDR_CHECK(fn(ndr, NDR_BUFFERS, r));
ofs = ndr->offset;
ndr->offset = ofs_size;
NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, ofs-ofs_size));
ndr->offset = ofs_ssize;
NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, (ofs-ofs_ssize-4) | 0x80000000));
ndr->offset = ofs;
return NT_STATUS_OK;
}
NTSTATUS ndr_pull_DataWithStack(struct ndr_pull *ndr, ndr_pull_flags_fn_t fn, void *r)
{
uint32_t end, size, ssize, ndrend;
end = ndr->offset;
NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &size));
NDR_PULL_NEED_BYTES(ndr, size - 4);
end += size;
ndrend = ndr->data_size;
ndr->data_size = end;
NDR_CHECK(fn(ndr, NDR_SCALARS, r));
NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &ssize));
if (!(ssize & 0x80000000))
return ndr_pull_error(ndr, NDR_ERR_VALIDATE, "ndr_pull_DataWithStack(%08X): Stack size without 31th bit set: 0x%08X", ndr->offset - 4, ssize);
ssize &= 0x7FFFFFFF;
NDR_PULL_NEED_BYTES(ndr, ssize);
ndr->data_size = ndr->offset + ssize;
ndr->relative_base_offset = ndr->offset;
NDR_CHECK(fn(ndr, NDR_BUFFERS, r));
ndr->data_size = ndrend;
ndr->offset = end;
return NT_STATUS_OK;
}
NTSTATUS ndr_push_uint32_flags(struct ndr_push *ndr, int ndr_flags, uint32_t v)
{
if (ndr_flags & NDR_SCALARS)
return ndr_push_uint32(ndr, NDR_SCALARS, v);
return NT_STATUS_OK;
}
NTSTATUS ndr_pull_uint32_flags(struct ndr_pull *ndr, int ndr_flags, uint32_t *v)
{
if (ndr_flags & NDR_SCALARS)
return ndr_pull_uint32(ndr, NDR_SCALARS, v);
return NT_STATUS_OK;
}
void copy_bits(const uint8_t *src, uint32_t bsrc, uint8_t *dst, uint32_t bdst, uint32_t count)
{
uint8_t mask;
src += bsrc >> 3;
bsrc &= 7;
dst += bdst >> 3;
bdst &= 7;
mask = ((1 << count) - 1);
*dst &= ~(mask << bdst);
*dst |= ((*src >> bsrc) & mask) << bdst;
}
#define IS_CIMTYPE_PTR(t) (((t) & CIM_FLAG_ARRAY) || ((t) == CIM_STRING) || ((t) == CIM_DATETIME) || ((t) == CIM_REFERENCE))
NTSTATUS ndr_push_WbemInstance_priv(struct ndr_push *ndr, int ndr_flags, const struct WbemClassObject *r)
{
int i;
if (ndr_flags & NDR_SCALARS) {
uint32_t ofs, vofs;
NDR_CHECK(ndr_push_uint8(ndr, NDR_SCALARS, r->instance->u1_0));
if (r->instance->__CLASS) {
NDR_CHECK(ndr_push_relative_ptr1(ndr, r->instance->__CLASS));
} else {
NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, 0xFFFFFFFF));
}
ofs = ndr->offset;
NDR_PUSH_NEED_BYTES(ndr, r->obj_class->data_size);
for (i = 0; i < r->obj_class->__PROPERTY_COUNT; ++i) {
copy_bits(&r->instance->default_flags[i], 0, ndr->data + ndr->offset, 2*r->obj_class->properties[i].desc->nr, 2);
}
i = 0xFF;
copy_bits((uint8_t *)&i, 0, ndr->data + ndr->offset, 2*r->obj_class->__PROPERTY_COUNT, (8 - 2*r->obj_class->__PROPERTY_COUNT) % 7);
vofs = ofs + ((r->obj_class->__PROPERTY_COUNT + 3) >> 2);
for (i = 0; i < r->obj_class->__PROPERTY_COUNT; ++i) {
NDR_CHECK(ndr_push_set_switch_value(ndr, &r->instance->data[i], r->obj_class->properties[i].desc->cimtype & CIM_TYPEMASK));
ndr->offset = vofs + r->obj_class->properties[i].desc->offset;
NDR_CHECK(ndr_push_CIMVAR(ndr, NDR_SCALARS, &r->instance->data[i]));
}
ndr->offset = ofs + r->obj_class->data_size;
NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, r->instance->u2_4));
NDR_CHECK(ndr_push_uint8(ndr, NDR_SCALARS, r->instance->u3_1));
}
if (ndr_flags & NDR_BUFFERS) {
if (r->instance->__CLASS) {
NDR_CHECK(ndr_push_relative_ptr2(ndr, r->instance->__CLASS));
NDR_CHECK(ndr_push_CIMSTRING(ndr, NDR_SCALARS, &r->instance->__CLASS));
}
for (i = 0; i < r->obj_class->__PROPERTY_COUNT; ++i) {
NDR_CHECK(ndr_push_CIMVAR(ndr, NDR_BUFFERS, &r->instance->data[i]));
}
}
return NT_STATUS_OK;
}
NTSTATUS ndr_pull_WbemInstance_priv(struct ndr_pull *ndr, int ndr_flags, const struct WbemClassObject *r)
{
int i;
if (!r->obj_class) {
DEBUG(1,("ndr_pull_WbemInstance_priv: There is no class for given instance\n"));
return NT_STATUS_NO_SUCH_FILE;
}
ndr_set_flags(&ndr->flags, LIBNDR_FLAG_NOALIGN);
if (ndr_flags & NDR_SCALARS) {
uint32_t ofs, vofs;
uint32_t _ptr___CLASS;
NDR_CHECK(ndr_pull_uint8(ndr, NDR_SCALARS, &r->instance->u1_0));
NDR_CHECK(ndr_pull_generic_ptr(ndr, &_ptr___CLASS));
if (_ptr___CLASS != 0xFFFFFFFF) {
NDR_PULL_ALLOC(ndr, r->instance->__CLASS);
NDR_CHECK(ndr_pull_relative_ptr1(ndr, r->instance->__CLASS, _ptr___CLASS));
} else {
r->instance->__CLASS = NULL;
}
ofs = ndr->offset;
NDR_PULL_NEED_BYTES(ndr, r->obj_class->data_size);
NDR_PULL_ALLOC_N(ndr, r->instance->default_flags, r->obj_class->__PROPERTY_COUNT);
for (i = 0; i < r->obj_class->__PROPERTY_COUNT; ++i) {
r->instance->default_flags[i] = 0;
copy_bits(ndr->data + ndr->offset, 2*r->obj_class->properties[i].desc->nr, &r->instance->default_flags[i], 0, 2);
}
vofs = ofs + ((r->obj_class->__PROPERTY_COUNT + 3) >> 2);
NDR_PULL_ALLOC_N(ndr, r->instance->data, r->obj_class->__PROPERTY_COUNT);
memset(r->instance->data, 0, sizeof(*r->instance->data) * r->obj_class->__PROPERTY_COUNT);
for (i = 0; i < r->obj_class->__PROPERTY_COUNT; ++i) {
NDR_CHECK(ndr_pull_set_switch_value(ndr, &r->instance->data[i], r->obj_class->properties[i].desc->cimtype & CIM_TYPEMASK));
ndr->offset = vofs + r->obj_class->properties[i].desc->offset;
NDR_CHECK(ndr_pull_CIMVAR(ndr, NDR_SCALARS, &r->instance->data[i]));
}
ndr->offset = ofs + r->obj_class->data_size;
NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->instance->u2_4));
NDR_CHECK(ndr_pull_uint8(ndr, NDR_SCALARS, &r->instance->u3_1));
}
if (ndr_flags & NDR_BUFFERS) {
if (r->instance->__CLASS) {
struct ndr_pull_save _relative_save;
ndr_pull_save(ndr, &_relative_save);
NDR_CHECK(ndr_pull_relative_ptr2(ndr, r->instance->__CLASS));
NDR_CHECK(ndr_pull_CIMSTRING(ndr, NDR_SCALARS, &r->instance->__CLASS));
ndr_pull_restore(ndr, &_relative_save);
}
for (i = 0; i < r->obj_class->__PROPERTY_COUNT; ++i) {
NDR_CHECK(ndr_pull_CIMVAR(ndr, NDR_BUFFERS, &r->instance->data[i]));
}
}
return NT_STATUS_OK;
}
void ndr_print_WbemInstance_priv(struct ndr_print *ndr, const char *name, const struct WbemClassObject *r)
{
int i;
ndr_print_array_uint8(ndr, "default_flags", r->instance->default_flags, r->obj_class->__PROPERTY_COUNT);
ndr->print(ndr, "%s: ARRAY(%d)", "data", r->obj_class->__PROPERTY_COUNT);
ndr->depth++;
for (i = 0; i < r->obj_class->__PROPERTY_COUNT; ++i) {
ndr->print(ndr, "%s[%d]", "data", i);
ndr->depth++;
ndr_print_set_switch_value(ndr, &r->instance->data[i], r->obj_class->properties[i].desc->cimtype & CIM_TYPEMASK);
ndr_print_CIMVAR(ndr, r->obj_class->properties[i].name, &r->instance->data[i]);
ndr->depth--;
}
ndr->depth--;
}
NTSTATUS ndr_push_WbemClassObject(struct ndr_push *ndr, int ndr_flags, const struct WbemClassObject *r)
{
ndr_set_flags(&ndr->flags, LIBNDR_FLAG_NOALIGN);
NDR_CHECK(ndr_push_uint8(ndr, NDR_SCALARS, r->flags));
if (r->flags & WCF_CLASS) {
NDR_CHECK(ndr_push_CIMSTRING(ndr, NDR_SCALARS, &r->__SERVER));
NDR_CHECK(ndr_push_CIMSTRING(ndr, NDR_SCALARS, &r->__NAMESPACE));
}
if (r->flags & WCF_DECORATIONS) {
NDR_CHECK(ndr_push_DataWithStack(ndr, (ndr_push_flags_fn_t)ndr_push_WbemClass, r->sup_class));
NDR_CHECK(ndr_push_DataWithStack(ndr, (ndr_push_flags_fn_t)ndr_push_WbemMethods, r->sup_methods));
}
if (r->flags & (WCF_CLASS | WCF_INSTANCE)) {
NDR_CHECK(ndr_push_DataWithStack(ndr, (ndr_push_flags_fn_t)ndr_push_WbemClass, r->obj_class));
}
if (r->flags & WCF_DECORATIONS) {
NDR_CHECK(ndr_push_DataWithStack(ndr, (ndr_push_flags_fn_t)ndr_push_WbemMethods, r->obj_methods));
}
if (r->flags & WCF_INSTANCE) {
NDR_CHECK(ndr_push_DataWithStack(ndr, (ndr_push_flags_fn_t)ndr_push_WbemInstance_priv, r));
}
return NT_STATUS_OK;
}
NTSTATUS ndr_pull_WbemClassObject(struct ndr_pull *ndr, int ndr_flags, struct WbemClassObject *r)
{
TALLOC_CTX *tc;
tc = NDR_PULL_GET_MEM_CTX(ndr);
ndr_set_flags(&ndr->flags, LIBNDR_FLAG_NOALIGN);
NDR_CHECK(ndr_pull_uint8(ndr, NDR_SCALARS, &r->flags));
if (r->flags & WCF_CLASS) {
NDR_CHECK(ndr_pull_CIMSTRING(ndr, NDR_SCALARS, &r->__SERVER));
NDR_CHECK(ndr_pull_CIMSTRING(ndr, NDR_SCALARS, &r->__NAMESPACE));
}
if (r->flags & WCF_DECORATIONS) {
r->sup_class = talloc_zero(r, struct WbemClass);
NDR_PULL_SET_MEM_CTX(ndr, r->sup_class, 0);
NDR_CHECK(ndr_pull_DataWithStack(ndr, (ndr_pull_flags_fn_t)ndr_pull_WbemClass, r->sup_class));
r->sup_methods = talloc_zero(r, struct WbemMethods);
NDR_PULL_SET_MEM_CTX(ndr, r->sup_methods, 0);
NDR_CHECK(ndr_pull_DataWithStack(ndr, (ndr_pull_flags_fn_t)ndr_pull_WbemMethods, r->sup_methods));
NDR_PULL_SET_MEM_CTX(ndr, tc, 0);
} else
r->sup_class = NULL;
if (r->flags & (WCF_CLASS | WCF_INSTANCE)) {
r->obj_class = talloc_zero(r, struct WbemClass);
NDR_PULL_SET_MEM_CTX(ndr, r->obj_class, 0);
NDR_CHECK(ndr_pull_DataWithStack(ndr, (ndr_pull_flags_fn_t)ndr_pull_WbemClass, r->obj_class));
NDR_PULL_SET_MEM_CTX(ndr, tc, 0);
}
if (r->flags & WCF_DECORATIONS) {
r->obj_methods = talloc_zero(r, struct WbemMethods);
NDR_PULL_SET_MEM_CTX(ndr, r->obj_methods, 0);
NDR_CHECK(ndr_pull_DataWithStack(ndr, (ndr_pull_flags_fn_t)ndr_pull_WbemMethods, r->obj_methods));
NDR_PULL_SET_MEM_CTX(ndr, tc, 0);
}
if (r->flags & WCF_INSTANCE) {
r->instance = talloc_zero(r, struct WbemInstance);
NDR_PULL_SET_MEM_CTX(ndr, r->instance, 0);
NDR_CHECK(ndr_pull_DataWithStack(ndr, (ndr_pull_flags_fn_t)ndr_pull_WbemInstance_priv, r));
NDR_PULL_SET_MEM_CTX(ndr, tc, 0);
} else
r->instance = NULL;
return NT_STATUS_OK;
}
NTSTATUS ndr_pull_WbemClassObject_Object(struct ndr_pull *ndr, int ndr_flags, struct WbemClassObject *r)
{
TALLOC_CTX *tc;
tc = NDR_PULL_GET_MEM_CTX(ndr);
ndr_set_flags(&ndr->flags, LIBNDR_FLAG_NOALIGN);
NDR_CHECK(ndr_pull_uint8(ndr, NDR_SCALARS, &r->flags));
if (r->flags & WCF_CLASS) {
NDR_CHECK(ndr_pull_CIMSTRING(ndr, NDR_SCALARS, &r->__SERVER));
NDR_CHECK(ndr_pull_CIMSTRING(ndr, NDR_SCALARS, &r->__NAMESPACE));
}
if (r->flags & WCF_INSTANCE) {
r->instance = talloc_zero(r, struct WbemInstance);
NDR_PULL_SET_MEM_CTX(ndr, r->instance, 0);
NDR_CHECK(ndr_pull_DataWithStack(ndr, (ndr_pull_flags_fn_t)ndr_pull_WbemInstance_priv, r));
NDR_PULL_SET_MEM_CTX(ndr, tc, 0);
} else
r->instance = NULL;
return NT_STATUS_OK;
}
_PUBLIC_ void ndr_print_WbemClassObject(struct ndr_print *ndr, const char *name, const struct WbemClassObject *r)
{
ndr_print_struct(ndr, name, "WbemClassObject");
{
uint32_t _flags_save_STRUCT = ndr->flags;
ndr_set_flags(&ndr->flags, LIBNDR_FLAG_NOALIGN);
ndr->depth++;
ndr_print_WCO_FLAGS(ndr, "flags", r->flags);
if (r->flags & WCF_CLASS) {
ndr_print_ptr(ndr, "__SERVER", r->__SERVER);
ndr->depth++;
ndr_print_CIMSTRING(ndr, "__SERVER", &r->__SERVER);
ndr->depth--;
ndr_print_ptr(ndr, "__NAMESPACE", r->__NAMESPACE);
ndr->depth++;
ndr_print_CIMSTRING(ndr, "__NAMESPACE", &r->__NAMESPACE);
ndr->depth--;
}
if (r->flags & WCF_DECORATIONS) {
ndr_print_ptr(ndr, "sup_class", r->sup_class);
ndr->depth++;
if (r->sup_class) {
ndr_print_WbemClass(ndr, "sup_class", r->sup_class);
}
ndr->depth--;
ndr_print_ptr(ndr, "sup_methods", r->sup_methods);
ndr->depth++;
if (r->sup_methods) {
ndr_print_WbemMethods(ndr, "sup_methods", r->sup_methods);
}
ndr->depth--;
}
if (r->flags & (WCF_CLASS | WCF_INSTANCE)) {
ndr_print_ptr(ndr, "obj_class", r->obj_class);
ndr->depth++;
if (r->obj_class) {
ndr_print_WbemClass(ndr, "obj_class", r->obj_class);
}
ndr->depth--;
}
if (r->flags & WCF_DECORATIONS) {
ndr_print_ptr(ndr, "obj_methods", r->obj_methods);
ndr->depth++;
if (r->obj_methods) {
ndr_print_WbemMethods(ndr, "obj_methods", r->obj_methods);
}
ndr->depth--;
}
if (r->flags & WCF_INSTANCE) {
ndr_print_ptr(ndr, "instance", r->instance);
ndr->depth++;
if (r->instance) {
ndr_print_WbemInstance_priv(ndr, "instance", r);
}
ndr->depth--;
}
ndr->depth--;
ndr->flags = _flags_save_STRUCT;
}
}
_PUBLIC_ NTSTATUS ndr_push_WbemClass(struct ndr_push *ndr, int ndr_flags, const struct WbemClass *r)
{
uint32_t cntr_properties_0;
uint32_t i, ofs, vofs;
{
uint32_t _flags_save_STRUCT = ndr->flags;
ndr_set_flags(&ndr->flags, LIBNDR_FLAG_NOALIGN);
if (ndr_flags & NDR_SCALARS) {
NDR_CHECK(ndr_push_align(ndr, 4));
NDR_CHECK(ndr_push_uint8(ndr, NDR_SCALARS, r->u_0));
if (r->__CLASS) {
NDR_CHECK(ndr_push_relative_ptr1(ndr, r->__CLASS));
} else {
NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, 0xFFFFFFFF));
}
NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, r->data_size));
NDR_CHECK(ndr_push_CIMSTRINGS(ndr, NDR_SCALARS, &r->__DERIVATION));
NDR_CHECK(ndr_push_WbemQualifiers(ndr, NDR_SCALARS, &r->qualifiers));
NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, r->__PROPERTY_COUNT));
for (cntr_properties_0 = 0; cntr_properties_0 < r->__PROPERTY_COUNT; cntr_properties_0++) {
NDR_CHECK(ndr_push_WbemProperty(ndr, NDR_SCALARS, &r->properties[cntr_properties_0]));
}
ofs = ndr->offset;
NDR_PUSH_NEED_BYTES(ndr, r->data_size);
for (i = 0; i < r->__PROPERTY_COUNT; ++i) {
copy_bits(&r->default_flags[i], 0, ndr->data + ndr->offset, 2*r->properties[i].desc->nr, 2);
}
i = 0xFF;
copy_bits((uint8_t *)&i, 0, ndr->data + ndr->offset, 2*r->__PROPERTY_COUNT, (8 - 2*r->__PROPERTY_COUNT) % 7);
vofs = ofs + ((r->__PROPERTY_COUNT + 3) >> 2);
for (i = 0; i < r->__PROPERTY_COUNT; ++i) {
NDR_CHECK(ndr_push_set_switch_value(ndr, &r->default_values[i], r->properties[i].desc->cimtype & CIM_TYPEMASK));
ndr->offset = vofs + r->properties[i].desc->offset;
if ((r->default_flags[i] & DEFAULT_FLAG_EMPTY) && IS_CIMTYPE_PTR(r->properties[i].desc->cimtype & CIM_TYPEMASK)) {
NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, 0xFFFFFFFF));
} else {
NDR_CHECK(ndr_push_CIMVAR(ndr, NDR_SCALARS, &r->default_values[i]));
}
}
ndr->offset = ofs + r->data_size;
}
if (ndr_flags & NDR_BUFFERS) {
if (r->__CLASS) {
NDR_CHECK(ndr_push_relative_ptr2(ndr, r->__CLASS));
NDR_CHECK(ndr_push_CIMSTRING(ndr, NDR_SCALARS, &r->__CLASS));
}
NDR_CHECK(ndr_push_CIMSTRINGS(ndr, NDR_BUFFERS, &r->__DERIVATION));
NDR_CHECK(ndr_push_WbemQualifiers(ndr, NDR_BUFFERS, &r->qualifiers));
for (cntr_properties_0 = 0; cntr_properties_0 < r->__PROPERTY_COUNT; cntr_properties_0++) {
NDR_CHECK(ndr_push_WbemProperty(ndr, NDR_BUFFERS, &r->properties[cntr_properties_0]));
}
for (i = 0; i < r->__PROPERTY_COUNT; ++i) {
if (r->default_flags[i] & DEFAULT_FLAG_EMPTY) continue;
NDR_CHECK(ndr_push_CIMVAR(ndr, NDR_BUFFERS, &r->default_values[i]));
}
}
ndr->flags = _flags_save_STRUCT;
}
return NT_STATUS_OK;
}
_PUBLIC_ NTSTATUS ndr_pull_WbemClass(struct ndr_pull *ndr, int ndr_flags, struct WbemClass *r)
{
uint32_t _ptr___CLASS;
uint32_t cntr_properties_0;
TALLOC_CTX *_mem_save_properties_0;
uint32_t i;
{
uint32_t _flags_save_STRUCT = ndr->flags;
ndr_set_flags(&ndr->flags, LIBNDR_FLAG_NOALIGN);
if (ndr_flags & NDR_SCALARS) {
NDR_CHECK(ndr_pull_align(ndr, 4));
NDR_CHECK(ndr_pull_uint8(ndr, NDR_SCALARS, &r->u_0));
NDR_CHECK(ndr_pull_generic_ptr(ndr, &_ptr___CLASS));
if (_ptr___CLASS != 0xFFFFFFFF) {
NDR_PULL_ALLOC(ndr, r->__CLASS);
NDR_CHECK(ndr_pull_relative_ptr1(ndr, r->__CLASS, _ptr___CLASS));
} else {
r->__CLASS = NULL;
}
NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->data_size));
NDR_CHECK(ndr_pull_CIMSTRINGS(ndr, NDR_SCALARS, &r->__DERIVATION));
NDR_CHECK(ndr_pull_WbemQualifiers(ndr, NDR_SCALARS, &r->qualifiers));
NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->__PROPERTY_COUNT));
NDR_PULL_ALLOC_N(ndr, r->properties, r->__PROPERTY_COUNT);
_mem_save_properties_0 = NDR_PULL_GET_MEM_CTX(ndr);
NDR_PULL_SET_MEM_CTX(ndr, r->properties, 0);
for (cntr_properties_0 = 0; cntr_properties_0 < r->__PROPERTY_COUNT; cntr_properties_0++) {
NDR_CHECK(ndr_pull_WbemProperty(ndr, NDR_SCALARS, &(r->properties)[cntr_properties_0]));
}
NDR_PULL_SET_MEM_CTX(ndr, _mem_save_properties_0, 0);
NDR_PULL_NEED_BYTES(ndr, r->data_size);
NDR_PULL_ALLOC_N(ndr, r->default_flags, r->__PROPERTY_COUNT);
NDR_CHECK(ndr_pull_relative_ptr1(ndr, r->default_flags, ndr->offset));
NDR_PULL_ALLOC_N(ndr, r->default_values, r->__PROPERTY_COUNT);
memset(r->default_values, 0, sizeof(*r->default_values) * r->__PROPERTY_COUNT);
NDR_CHECK(ndr_pull_relative_ptr1(ndr, r->default_values, ndr->offset + ((r->__PROPERTY_COUNT + 3) >> 2)));
ndr->offset += r->data_size;
}
if (ndr_flags & NDR_BUFFERS) {
if (r->__CLASS) {
TALLOC_CTX *_mem_save___CLASS_0;
struct ndr_pull_save _relative_save;
ndr_pull_save(ndr, &_relative_save);
NDR_CHECK(ndr_pull_relative_ptr2(ndr, r->__CLASS));
_mem_save___CLASS_0 = NDR_PULL_GET_MEM_CTX(ndr);
NDR_PULL_SET_MEM_CTX(ndr, r->__CLASS, 0);
NDR_CHECK(ndr_pull_CIMSTRING(ndr, NDR_SCALARS, &r->__CLASS));
NDR_PULL_SET_MEM_CTX(ndr, _mem_save___CLASS_0, 0);
ndr_pull_restore(ndr, &_relative_save);
}
NDR_CHECK(ndr_pull_CIMSTRINGS(ndr, NDR_BUFFERS, &r->__DERIVATION));
NDR_CHECK(ndr_pull_WbemQualifiers(ndr, NDR_BUFFERS, &r->qualifiers));
_mem_save_properties_0 = NDR_PULL_GET_MEM_CTX(ndr);
NDR_PULL_SET_MEM_CTX(ndr, r->properties, 0);
for (cntr_properties_0 = 0; cntr_properties_0 < r->__PROPERTY_COUNT; cntr_properties_0++) {
NDR_CHECK(ndr_pull_WbemProperty(ndr, NDR_BUFFERS, &(r->properties)[cntr_properties_0]));
}
NDR_PULL_SET_MEM_CTX(ndr, _mem_save_properties_0, 0);
{
uint32_t ofs;
NDR_CHECK(ndr_token_retrieve(&ndr->relative_list, r->default_flags, &ofs));
for (i = 0; i < r->__PROPERTY_COUNT; ++i) {
r->default_flags[i] = 0;
copy_bits(ndr->data + ofs, 2*r->properties[i].desc->nr, &r->default_flags[i], 0, 2);
}
}
{
struct ndr_pull_save _relative_save;
uint32_t ofs;
ndr_pull_save(ndr, &_relative_save);
NDR_CHECK(ndr_token_retrieve(&ndr->relative_list, r->default_values, &ofs));
for (i=0; i < r->__PROPERTY_COUNT; ++i) {
if (r->default_flags[i] & DEFAULT_FLAG_EMPTY) continue;
NDR_CHECK(ndr_pull_set_switch_value(ndr, &r->default_values[i], r->properties[i].desc->cimtype & CIM_TYPEMASK));
ndr->offset = ofs + r->properties[i].desc->offset;
NDR_CHECK(ndr_pull_CIMVAR(ndr, NDR_SCALARS|NDR_BUFFERS, &r->default_values[i]));
}
ndr_pull_restore(ndr, &_relative_save);
}
}
ndr->flags = _flags_save_STRUCT;
}
return NT_STATUS_OK;
}
_PUBLIC_ void ndr_print_WbemClass(struct ndr_print *ndr, const char *name, const struct WbemClass *r)
{
uint32_t cntr_properties_0;
uint32_t cntr_default_values_0;
ndr_print_struct(ndr, name, "WbemClass");
{
uint32_t _flags_save_STRUCT = ndr->flags;
ndr_set_flags(&ndr->flags, LIBNDR_FLAG_NOALIGN);
ndr->depth++;
ndr_print_uint8(ndr, "u_0", r->u_0);
ndr_print_ptr(ndr, "__CLASS", r->__CLASS);
ndr->depth++;
if (r->__CLASS) {
ndr_print_CIMSTRING(ndr, "__CLASS", &r->__CLASS);
}
ndr->depth--;
ndr_print_uint32(ndr, "data_size", r->data_size);
ndr_print_CIMSTRINGS(ndr, "__DERIVATION", &r->__DERIVATION);
ndr_print_WbemQualifiers(ndr, "qualifiers", &r->qualifiers);
ndr_print_uint32(ndr, "__PROPERTY_COUNT", r->__PROPERTY_COUNT);
ndr->print(ndr, "%s: ARRAY(%d)", "properties", r->__PROPERTY_COUNT);
ndr->depth++;
for (cntr_properties_0=0;cntr_properties_0<r->__PROPERTY_COUNT;cntr_properties_0++) {
char *idx_0=NULL;
asprintf(&idx_0, "[%d]", cntr_properties_0);
if (idx_0) {
ndr_print_WbemProperty(ndr, "properties", &r->properties[cntr_properties_0]);
free(idx_0);
}
}
ndr->depth--;
ndr_print_array_uint8(ndr, "default_flags", r->default_flags, r->__PROPERTY_COUNT);
ndr->print(ndr, "%s: ARRAY(%d)", "default_values", r->__PROPERTY_COUNT);
ndr->depth++;
for (cntr_default_values_0=0;cntr_default_values_0<r->__PROPERTY_COUNT;cntr_default_values_0++) {
char *idx_0=NULL;
asprintf(&idx_0, "[%d]", cntr_default_values_0);
if (idx_0) {
ndr_print_set_switch_value(ndr, &r->default_values[cntr_default_values_0], r->properties[cntr_default_values_0].desc->cimtype & CIM_TYPEMASK);
ndr_print_CIMVAR(ndr, "default_values", &r->default_values[cntr_default_values_0]);
free(idx_0);
}
}
ndr->depth--;
ndr->depth--;
ndr->flags = _flags_save_STRUCT;
}
}
+64
View File
@@ -0,0 +1,64 @@
/*
Unix SMB/CIFS implementation.
routines for printing some linked list structs in DRSUAPI
Copyright (C) Stefan (metze) 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_drsuapi.h"
#include "librpc/gen_ndr/ndr_misc.h"
void ndr_print_drsuapi_DsReplicaObjectListItem(struct ndr_print *ndr, const char *name,
const struct drsuapi_DsReplicaObjectListItem *r)
{
ndr_print_struct(ndr, name, "drsuapi_DsReplicaObjectListItem");
ndr->depth++;
ndr_print_ptr(ndr, "next_object", r->next_object);
ndr_print_drsuapi_DsReplicaObject(ndr, "object", &r->object);
ndr->depth--;
if (r->next_object) {
ndr_print_drsuapi_DsReplicaObjectListItem(ndr, "next_object", r->next_object);
}
}
void ndr_print_drsuapi_DsReplicaObjectListItemEx(struct ndr_print *ndr, const char *name, const struct drsuapi_DsReplicaObjectListItemEx *r)
{
ndr_print_struct(ndr, name, "drsuapi_DsReplicaObjectListItemEx");
ndr->depth++;
ndr_print_ptr(ndr, "next_object", r->next_object);
ndr_print_drsuapi_DsReplicaObject(ndr, "object", &r->object);
ndr_print_uint32(ndr, "unknown1", r->unknown1);
ndr_print_ptr(ndr, "parent_object_guid", r->parent_object_guid);
ndr->depth++;
if (r->parent_object_guid) {
ndr_print_GUID(ndr, "parent_object_guid", r->parent_object_guid);
}
ndr->depth--;
ndr_print_ptr(ndr, "meta_data_ctr", r->meta_data_ctr);
ndr->depth++;
if (r->meta_data_ctr) {
ndr_print_drsuapi_DsReplicaMetaDataCtr(ndr, "meta_data_ctr", r->meta_data_ctr);
}
ndr->depth--;
ndr->depth--;
if (r->next_object) {
ndr_print_drsuapi_DsReplicaObjectListItemEx(ndr, "next_object", r->next_object);
}
}
+141
View File
@@ -0,0 +1,141 @@
/*
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"
static 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;
}
}
static 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_CHECK(ndr_push_subcontext_start(ndr, &_ndr_info, 0, _subcontext_size_PAC_INFO(r->info,r->type,0)));
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_end(ndr, _ndr_info, 0, _subcontext_size_PAC_INFO(r->info,r->type,0)));
}
}
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;
TALLOC_CTX *_mem_save_info_0;
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_generic_ptr(ndr, &_ptr_info));
if (_ptr_info) {
NDR_PULL_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));
_mem_save_info_0 = NDR_PULL_GET_MEM_CTX(ndr);
NDR_PULL_SET_MEM_CTX(ndr, r->info, 0);
{
struct ndr_pull *_ndr_info;
NDR_CHECK(ndr_pull_subcontext_start(ndr, &_ndr_info, 0, r->_ndr_size));
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_subcontext_end(ndr, _ndr_info, 0, r->_ndr_size));
}
NDR_PULL_SET_MEM_CTX(ndr, _mem_save_info_0, 0);
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--;
}
+41
View File
@@ -0,0 +1,41 @@
/*
Unix SMB/CIFS implementation.
UUID/GUID/policy_handle functions
Copyright (C) Andrew Tridgell 2003.
Copyright (C) Stefan (metze) Metzmacher 2004.
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 "system/network.h"
#include "librpc/ndr/libndr.h"
_PUBLIC_ void ndr_print_ipv4_addr(struct ndr_print *ndr, const char *name, const struct ipv4_addr *_ip)
{
struct ipv4_addr ip;
ip.addr = htonl(_ip->addr);
ndr->print(ndr, "%-25s: %s", name, sys_inet_ntoa(ip));
}
_PUBLIC_ void ndr_print_GUID(struct ndr_print *ndr, const char *name, const struct GUID *guid)
{
ndr->print(ndr, "%-25s: %s", name, GUID_string(ndr, guid));
}
+181
View File
@@ -0,0 +1,181 @@
/*
Unix SMB/CIFS implementation.
routines for marshalling/unmarshalling DCOM string arrays
Copyright (C) Jelmer Vernooij 2004
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_orpc.h"
NTSTATUS ndr_pull_DUALSTRINGARRAY(struct ndr_pull *ndr, int ndr_flags, struct DUALSTRINGARRAY *ar)
{
uint16_t num_entries, security_offset;
uint16_t towerid;
uint32_t towernum = 0, conformant_size;
TALLOC_CTX *mem_ctx = ndr->current_mem_ctx;
if (!(ndr_flags & NDR_SCALARS)) {
return NT_STATUS_OK;
}
NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &conformant_size));
NDR_CHECK(ndr_pull_uint16(ndr, NDR_SCALARS, &num_entries));
NDR_CHECK(ndr_pull_uint16(ndr, NDR_SCALARS, &security_offset));
ar->stringbindings = talloc_array(mem_ctx, struct STRINGBINDING *, num_entries + 1);
ar->stringbindings[0] = NULL;
do {
/* 'Peek' */
NDR_CHECK(ndr_pull_uint16(ndr, NDR_SCALARS, &towerid));
if (towerid > 0) {
ndr->offset -= 2;
ar->stringbindings = talloc_realloc(mem_ctx, ar->stringbindings, struct STRINGBINDING *, towernum+2);
ar->stringbindings[towernum] = talloc(ar->stringbindings, struct STRINGBINDING);
ndr->current_mem_ctx = ar->stringbindings[towernum];
NDR_CHECK(ndr_pull_STRINGBINDING(ndr, ndr_flags, ar->stringbindings[towernum]));
towernum++;
}
} while (towerid != 0);
ar->stringbindings[towernum] = NULL;
towernum = 0;
ar->securitybindings = talloc_array(mem_ctx, struct SECURITYBINDING *, num_entries);
ar->securitybindings[0] = NULL;
do {
/* 'Peek' */
NDR_CHECK(ndr_pull_uint16(ndr, NDR_SCALARS, &towerid));
if (towerid > 0) {
ndr->offset -= 2;
ar->securitybindings = talloc_realloc(mem_ctx, ar->securitybindings, struct SECURITYBINDING *, towernum+2);
ar->securitybindings[towernum] = talloc(ar->securitybindings, struct SECURITYBINDING);
ndr->current_mem_ctx = ar->securitybindings[towernum];
NDR_CHECK(ndr_pull_SECURITYBINDING(ndr, ndr_flags, ar->securitybindings[towernum]));
towernum++;
}
} while (towerid != 0);
ar->securitybindings[towernum] = NULL;
ndr->current_mem_ctx = mem_ctx;
return NT_STATUS_OK;
}
NTSTATUS ndr_push_DUALSTRINGARRAY(struct ndr_push *ndr, int ndr_flags, const struct DUALSTRINGARRAY *ar)
{
return NT_STATUS_NOT_SUPPORTED;
}
/*
print a dom_sid
*/
void ndr_print_DUALSTRINGARRAY(struct ndr_print *ndr, const char *name, const struct DUALSTRINGARRAY *ar)
{
int i;
ndr->print(ndr, "%-25s: DUALSTRINGARRAY", name);
ndr->depth++;
ndr->print(ndr, "STRING BINDINGS");
ndr->depth++;
for (i=0;ar->stringbindings[i];i++) {
char *idx = NULL;
asprintf(&idx, "[%d]", i);
if (idx) {
ndr_print_STRINGBINDING(ndr, idx, ar->stringbindings[i]);
free(idx);
}
}
ndr->depth--;
ndr->print(ndr, "SECURITY BINDINGS");
ndr->depth++;
for (i=0;ar->securitybindings[i];i++) {
char *idx = NULL;
asprintf(&idx, "[%d]", i);
if (idx) {
ndr_print_SECURITYBINDING(ndr, idx, ar->securitybindings[i]);
free(idx);
}
}
ndr->depth--;
}
NTSTATUS ndr_pull_STRINGARRAY(struct ndr_pull *ndr, int ndr_flags, struct STRINGARRAY *ar)
{
uint16_t towerid;
uint32_t towernum = 0;
uint16_t num_entries;
TALLOC_CTX *mem_ctx = ndr->current_mem_ctx;
if (!(ndr_flags & NDR_SCALARS)) {
return NT_STATUS_OK;
}
NDR_CHECK(ndr_pull_uint16(ndr, NDR_SCALARS, &num_entries));
ar->stringbindings = talloc_array(mem_ctx, struct STRINGBINDING *, 1);
ar->stringbindings[0] = NULL;
do {
/* 'Peek' */
NDR_CHECK(ndr_pull_uint16(ndr, NDR_SCALARS, &towerid));
if (towerid > 0) {
ndr->offset -= 2;
ar->stringbindings = talloc_realloc(mem_ctx, ar->stringbindings, struct STRINGBINDING *, towernum+2);
ar->stringbindings[towernum] = talloc(ar->stringbindings, struct STRINGBINDING);
ndr->current_mem_ctx = ar->stringbindings[towernum];
NDR_CHECK(ndr_pull_STRINGBINDING(ndr, ndr_flags, ar->stringbindings[towernum]));
towernum++;
}
} while (towerid != 0);
ar->stringbindings[towernum] = NULL;
towernum = 0;
ndr->current_mem_ctx = mem_ctx;
return NT_STATUS_OK;
}
NTSTATUS ndr_push_STRINGARRAY(struct ndr_push *ndr, int ndr_flags, const struct STRINGARRAY *ar)
{
return NT_STATUS_NOT_SUPPORTED;
}
/*
print a dom_sid
*/
void ndr_print_STRINGARRAY(struct ndr_print *ndr, const char *name, const struct STRINGARRAY *ar)
{
int i;
ndr->print(ndr, "%-25s: STRINGARRAY", name);
ndr->depth++;
for (i=0;ar->stringbindings[i];i++) {
char *idx = NULL;
asprintf(&idx, "[%d]", i);
if (idx) {
ndr_print_STRINGBINDING(ndr, idx, ar->stringbindings[i]);
free(idx);
}
}
ndr->depth--;
}
+204
View File
@@ -0,0 +1,204 @@
/*
Unix SMB/CIFS implementation.
fast routines for getting the wire size of security objects
Copyright (C) Andrew Tridgell 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"
#include "librpc/gen_ndr/ndr_security.h"
#include "libcli/security/security.h"
/*
return the wire size of a dom_sid
*/
size_t ndr_size_dom_sid(const struct dom_sid *sid, int flags)
{
if (!sid) return 0;
return 8 + 4*sid->num_auths;
}
size_t ndr_size_dom_sid28(const struct dom_sid *sid, int flags)
{
struct dom_sid zero_sid;
if (!sid) return 0;
ZERO_STRUCT(zero_sid);
if (memcmp(&zero_sid, sid, sizeof(zero_sid)) == 0) {
return 0;
}
return 8 + 4*sid->num_auths;
}
/*
return the wire size of a security_ace
*/
size_t ndr_size_security_ace(const struct security_ace *ace, int flags)
{
if (!ace) return 0;
return 8 + ndr_size_dom_sid(&ace->trustee, flags);
}
/*
return the wire size of a security_acl
*/
size_t ndr_size_security_acl(const struct security_acl *acl, int flags)
{
size_t ret;
int i;
if (!acl) return 0;
ret = 8;
for (i=0;i<acl->num_aces;i++) {
ret += ndr_size_security_ace(&acl->aces[i], flags);
}
return ret;
}
/*
return the wire size of a security descriptor
*/
size_t ndr_size_security_descriptor(const struct security_descriptor *sd, int flags)
{
size_t ret;
if (!sd) return 0;
ret = 20;
ret += ndr_size_dom_sid(sd->owner_sid, flags);
ret += ndr_size_dom_sid(sd->group_sid, flags);
ret += ndr_size_security_acl(sd->dacl, flags);
ret += ndr_size_security_acl(sd->sacl, flags);
return ret;
}
/*
print a dom_sid
*/
void ndr_print_dom_sid(struct ndr_print *ndr, const char *name, const struct dom_sid *sid)
{
ndr->print(ndr, "%-25s: %s", name, dom_sid_string(ndr, sid));
}
void ndr_print_dom_sid2(struct ndr_print *ndr, const char *name, const struct dom_sid *sid)
{
ndr_print_dom_sid(ndr, name, sid);
}
void ndr_print_dom_sid28(struct ndr_print *ndr, const char *name, const struct dom_sid *sid)
{
ndr_print_dom_sid(ndr, name, sid);
}
/*
parse a dom_sid2 - this is a dom_sid but with an extra copy of the num_auths field
*/
NTSTATUS ndr_pull_dom_sid2(struct ndr_pull *ndr, int ndr_flags, struct dom_sid *sid)
{
uint32_t num_auths;
if (!(ndr_flags & NDR_SCALARS)) {
return NT_STATUS_OK;
}
NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &num_auths));
NDR_CHECK(ndr_pull_dom_sid(ndr, ndr_flags, sid));
if (sid->num_auths != num_auths) {
return ndr_pull_error(ndr, NDR_ERR_ARRAY_SIZE,
"Bad array size %u should exceed %u",
num_auths, sid->num_auths);
}
return NT_STATUS_OK;
}
/*
parse a dom_sid2 - this is a dom_sid but with an extra copy of the num_auths field
*/
NTSTATUS ndr_push_dom_sid2(struct ndr_push *ndr, int ndr_flags, const struct dom_sid *sid)
{
if (!(ndr_flags & NDR_SCALARS)) {
return NT_STATUS_OK;
}
NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, sid->num_auths));
return ndr_push_dom_sid(ndr, ndr_flags, sid);
}
/*
parse a dom_sid28 - this is a dom_sid in a fixed 28 byte buffer, so we need to ensure there are only upto 5 sub_auth
*/
NTSTATUS ndr_pull_dom_sid28(struct ndr_pull *ndr, int ndr_flags, struct dom_sid *sid)
{
NTSTATUS status;
struct ndr_pull *subndr;
if (!(ndr_flags & NDR_SCALARS)) {
return NT_STATUS_OK;
}
subndr = talloc_zero(ndr, struct ndr_pull);
NT_STATUS_HAVE_NO_MEMORY(subndr);
subndr->flags = ndr->flags;
subndr->current_mem_ctx = ndr->current_mem_ctx;
subndr->data = ndr->data + ndr->offset;
subndr->data_size = 28;
subndr->offset = 0;
NDR_CHECK(ndr_pull_advance(ndr, 28));
status = ndr_pull_dom_sid(subndr, ndr_flags, sid);
if (!NT_STATUS_IS_OK(status)) {
/* handle a w2k bug which send random data in the buffer */
ZERO_STRUCTP(sid);
}
return NT_STATUS_OK;
}
/*
push a dom_sid28 - this is a dom_sid in a 28 byte fixed buffer
*/
NTSTATUS ndr_push_dom_sid28(struct ndr_push *ndr, int ndr_flags, const struct dom_sid *sid)
{
uint32_t old_offset;
uint32_t padding;
if (!(ndr_flags & NDR_SCALARS)) {
return NT_STATUS_OK;
}
if (sid->num_auths > 5) {
return ndr_push_error(ndr, NDR_ERR_RANGE,
"dom_sid28 allows only upto 5 sub auth [%u]",
sid->num_auths);
}
old_offset = ndr->offset;
NDR_CHECK(ndr_push_dom_sid(ndr, ndr_flags, sid));
padding = 28 - (ndr->offset - old_offset);
if (padding > 0) {
NDR_CHECK(ndr_push_zero(ndr, padding));
}
return NT_STATUS_OK;
}
+531
View File
@@ -0,0 +1,531 @@
/*
Unix SMB/CIFS implementation.
routines for marshalling/unmarshalling spoolss subcontext buffer structures
Copyright (C) Andrew Tridgell 2003
Copyright (C) Tim Potter 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"
#include "librpc/gen_ndr/ndr_spoolss.h"
#define NDR_SPOOLSS_PUSH_ENUM_IN(fn) do { \
if (!r->in.buffer && r->in.offered != 0) {\
return ndr_push_error(ndr, NDR_ERR_BUFSIZE,\
"SPOOLSS Buffer: r->in.offered[%u] but there's no buffer",\
(unsigned)r->in.offered);\
} else if (r->in.buffer && r->in.buffer->length != r->in.offered) {\
return ndr_push_error(ndr, NDR_ERR_BUFSIZE,\
"SPOOLSS Buffer: r->in.offered[%u] doesn't match length of r->in.buffer[%u]",\
(unsigned)r->in.offered, (unsigned)r->in.buffer->length);\
}\
_r.in.level = r->in.level;\
_r.in.buffer = r->in.buffer;\
_r.in.offered = r->in.offered;\
NDR_CHECK(ndr_push__##fn(ndr, flags, &_r));\
} while(0)
#define NDR_SPOOLSS_PUSH_ENUM_OUT(fn) do { \
struct ndr_push *_ndr_info;\
_r.in.level = r->in.level;\
_r.in.buffer = r->in.buffer;\
_r.in.offered = r->in.offered;\
_r.out.info = NULL;\
_r.out.needed = r->out.needed;\
_r.out.count = r->out.count;\
_r.out.result = r->out.result;\
if (r->out.info && !r->in.buffer) {\
return ndr_push_error(ndr, NDR_ERR_BUFSIZE,\
"SPOOLSS Buffer: r->out.info but there's no r->in.buffer");\
}\
if (r->in.buffer) {\
DATA_BLOB _data_blob_info;\
_ndr_info = ndr_push_init_ctx(ndr);\
if (!_ndr_info) return NT_STATUS_NO_MEMORY;\
_ndr_info->flags= ndr->flags;\
if (r->out.info) {\
struct __##fn __r;\
__r.in.level = r->in.level;\
__r.in.count = r->out.count;\
__r.out.info = r->out.info;\
NDR_CHECK(ndr_push___##fn(_ndr_info, flags, &__r)); \
}\
if (r->in.offered > _ndr_info->offset) {\
uint32_t _padding_len = r->in.offered - _ndr_info->offset;\
NDR_CHECK(ndr_push_zero(_ndr_info, _padding_len));\
} else if (r->in.offered < _ndr_info->offset) {\
return ndr_push_error(ndr, NDR_ERR_BUFSIZE,\
"SPOOLSS Buffer: r->in.offered[%u] doesn't match length of out buffer[%u]!",\
(unsigned)r->in.offered, (unsigned)_ndr_info->offset);\
}\
_data_blob_info = ndr_push_blob(_ndr_info);\
_r.out.info = &_data_blob_info;\
}\
NDR_CHECK(ndr_push__##fn(ndr, flags, &_r));\
} while(0)
#define NDR_SPOOLSS_PUSH_ENUM(fn,in,out) do { \
struct _##fn _r;\
if (flags & NDR_IN) {\
in;\
NDR_SPOOLSS_PUSH_ENUM_IN(fn);\
}\
if (flags & NDR_OUT) {\
out;\
NDR_SPOOLSS_PUSH_ENUM_OUT(fn);\
}\
} while(0)
#define NDR_SPOOLSS_PULL_ENUM_IN(fn) do { \
ZERO_STRUCT(r->out);\
NDR_CHECK(ndr_pull__##fn(ndr, flags, &_r));\
r->in.level = _r.in.level;\
r->in.buffer = _r.in.buffer;\
r->in.offered = _r.in.offered;\
r->out.needed = _r.out.needed;\
if (!r->in.buffer && r->in.offered != 0) {\
return ndr_pull_error(ndr, NDR_ERR_BUFSIZE,\
"SPOOLSS Buffer: r->in.offered[%u] but there's no buffer",\
(unsigned)r->in.offered);\
} else if (r->in.buffer && r->in.buffer->length != r->in.offered) {\
return ndr_pull_error(ndr, NDR_ERR_BUFSIZE,\
"SPOOLSS Buffer: r->in.offered[%u] doesn't match length of r->in.buffer[%u]",\
(unsigned)r->in.offered, (unsigned)r->in.buffer->length);\
}\
} while(0)
#define NDR_SPOOLSS_PULL_ENUM_OUT(fn) do { \
_r.in.level = r->in.level;\
_r.in.buffer = r->in.buffer;\
_r.in.offered = r->in.offered;\
_r.out.needed = r->out.needed;\
NDR_CHECK(ndr_pull__##fn(ndr, flags, &_r));\
r->out.info = NULL;\
r->out.needed = _r.out.needed;\
r->out.count = _r.out.count;\
r->out.result = _r.out.result;\
if (_r.out.info) {\
struct ndr_pull *_ndr_info = ndr_pull_init_blob(_r.out.info, ndr);\
if (!_ndr_info) return NT_STATUS_NO_MEMORY;\
_ndr_info->flags= ndr->flags;\
if (r->in.offered != _ndr_info->data_size) {\
return ndr_pull_error(ndr, NDR_ERR_BUFSIZE,\
"SPOOLSS Buffer: offered[%u] doesn't match length of buffer[%u]",\
(unsigned)r->in.offered, (unsigned)_ndr_info->data_size);\
}\
if (r->out.needed <= _ndr_info->data_size) {\
struct __##fn __r;\
__r.in.level = r->in.level;\
__r.in.count = r->out.count;\
__r.out.info = NULL;\
NDR_CHECK(ndr_pull___##fn(_ndr_info, flags, &__r));\
r->out.info = __r.out.info;\
}\
}\
} while(0)
#define NDR_SPOOLSS_PULL_ENUM(fn,in,out) do { \
struct _##fn _r;\
if (flags & NDR_IN) {\
out;\
NDR_SPOOLSS_PULL_ENUM_IN(fn);\
in;\
}\
if (flags & NDR_OUT) {\
out;\
NDR_SPOOLSS_PULL_ENUM_OUT(fn);\
}\
} while(0)
#define _NDR_CHECK_UINT32(call) do {\
NTSTATUS _status; \
_status = call; \
if (!NT_STATUS_IS_OK(_status)) {\
return 0; \
}\
} while (0)
/* TODO: set _ndr_info->flags correct */
#define NDR_SPOOLSS_SIZE_ENUM(fn) do { \
struct __##fn __r;\
DATA_BLOB _data_blob_info;\
struct ndr_push *_ndr_info = ndr_push_init_ctx(mem_ctx);\
if (!_ndr_info) return 0;\
_ndr_info->flags|=0;\
__r.in.level = level;\
__r.in.count = count;\
__r.out.info = info;\
_NDR_CHECK_UINT32(ndr_push___##fn(_ndr_info, NDR_OUT, &__r)); \
_data_blob_info = ndr_push_blob(_ndr_info);\
return _data_blob_info.length;\
} while(0)
/*
spoolss_EnumPrinters
*/
NTSTATUS ndr_push_spoolss_EnumPrinters(struct ndr_push *ndr, int flags, const struct spoolss_EnumPrinters *r)
{
NDR_SPOOLSS_PUSH_ENUM(spoolss_EnumPrinters,{
_r.in.flags = r->in.flags;
_r.in.server = r->in.server;
},{
_r.in.flags = r->in.flags;
_r.in.server = r->in.server;
});
return NT_STATUS_OK;
}
NTSTATUS ndr_pull_spoolss_EnumPrinters(struct ndr_pull *ndr, int flags, struct spoolss_EnumPrinters *r)
{
NDR_SPOOLSS_PULL_ENUM(spoolss_EnumPrinters,{
r->in.flags = _r.in.flags;
r->in.server = _r.in.server;
},{
_r.in.flags = r->in.flags;
_r.in.server = r->in.server;
});
return NT_STATUS_OK;
}
uint32_t ndr_size_spoolss_EnumPrinters_info(TALLOC_CTX *mem_ctx, uint32_t level, uint32_t count, union spoolss_PrinterInfo *info)
{
NDR_SPOOLSS_SIZE_ENUM(spoolss_EnumPrinters);
}
/*
spoolss_EnumJobs
*/
NTSTATUS ndr_push_spoolss_EnumJobs(struct ndr_push *ndr, int flags, const struct spoolss_EnumJobs *r)
{
NDR_SPOOLSS_PUSH_ENUM(spoolss_EnumJobs,{
_r.in.handle = r->in.handle;
_r.in.firstjob = r->in.firstjob;
_r.in.numjobs = r->in.numjobs;
},{
_r.in.handle = r->in.handle;
_r.in.firstjob = r->in.firstjob;
_r.in.numjobs = r->in.numjobs;
});
return NT_STATUS_OK;
}
NTSTATUS ndr_pull_spoolss_EnumJobs(struct ndr_pull *ndr, int flags, struct spoolss_EnumJobs *r)
{
NDR_SPOOLSS_PULL_ENUM(spoolss_EnumJobs,{
r->in.handle = _r.in.handle;
r->in.firstjob = _r.in.firstjob;
r->in.numjobs = _r.in.numjobs;
},{
_r.in.handle = r->in.handle;
_r.in.firstjob = r->in.firstjob;
_r.in.numjobs = r->in.numjobs;
});
return NT_STATUS_OK;
}
uint32_t ndr_size_spoolss_EnumJobss_info(TALLOC_CTX *mem_ctx, uint32_t level, uint32_t count, union spoolss_JobInfo *info)
{
NDR_SPOOLSS_SIZE_ENUM(spoolss_EnumJobs);
}
/*
spoolss_EnumPrinterDrivers
*/
NTSTATUS ndr_push_spoolss_EnumPrinterDrivers(struct ndr_push *ndr, int flags, const struct spoolss_EnumPrinterDrivers *r)
{
NDR_SPOOLSS_PUSH_ENUM(spoolss_EnumPrinterDrivers,{
_r.in.server = r->in.server;
_r.in.environment = r->in.environment;
},{
_r.in.server = r->in.server;
_r.in.environment = r->in.environment;
});
return NT_STATUS_OK;
}
NTSTATUS ndr_pull_spoolss_EnumPrinterDrivers(struct ndr_pull *ndr, int flags, struct spoolss_EnumPrinterDrivers *r)
{
NDR_SPOOLSS_PULL_ENUM(spoolss_EnumPrinterDrivers,{
r->in.server = _r.in.server;
r->in.environment = _r.in.environment;
},{
_r.in.server = r->in.server;
_r.in.environment = r->in.environment;
});
return NT_STATUS_OK;
}
uint32_t ndr_size_spoolss_EnumPrinterDrivers_info(TALLOC_CTX *mem_ctx, uint32_t level, uint32_t count, union spoolss_DriverInfo *info)
{
NDR_SPOOLSS_SIZE_ENUM(spoolss_EnumPrinterDrivers);
}
/*
spoolss_EnumForms
*/
NTSTATUS ndr_push_spoolss_EnumForms(struct ndr_push *ndr, int flags, const struct spoolss_EnumForms *r)
{
NDR_SPOOLSS_PUSH_ENUM(spoolss_EnumForms,{
_r.in.handle = r->in.handle;
},{
_r.in.handle = r->in.handle;
});
return NT_STATUS_OK;
}
NTSTATUS ndr_pull_spoolss_EnumForms(struct ndr_pull *ndr, int flags, struct spoolss_EnumForms *r)
{
NDR_SPOOLSS_PULL_ENUM(spoolss_EnumForms,{
r->in.handle = _r.in.handle;
},{
_r.in.handle = r->in.handle;
});
return NT_STATUS_OK;
}
uint32_t ndr_size_spoolss_EnumForms_info(TALLOC_CTX *mem_ctx, uint32_t level, uint32_t count, union spoolss_FormInfo *info)
{
NDR_SPOOLSS_SIZE_ENUM(spoolss_EnumForms);
}
/*
spoolss_EnumPorts
*/
NTSTATUS ndr_push_spoolss_EnumPorts(struct ndr_push *ndr, int flags, const struct spoolss_EnumPorts *r)
{
NDR_SPOOLSS_PUSH_ENUM(spoolss_EnumPorts,{
_r.in.servername= r->in.servername;
},{
_r.in.servername= r->in.servername;
});
return NT_STATUS_OK;
}
NTSTATUS ndr_pull_spoolss_EnumPorts(struct ndr_pull *ndr, int flags, struct spoolss_EnumPorts *r)
{
NDR_SPOOLSS_PULL_ENUM(spoolss_EnumPorts,{
r->in.servername= _r.in.servername;
},{
_r.in.servername= r->in.servername;
});
return NT_STATUS_OK;
}
uint32_t ndr_size_spoolss_EnumPorts_info(TALLOC_CTX *mem_ctx, uint32_t level, uint32_t count, union spoolss_PortInfo *info)
{
NDR_SPOOLSS_SIZE_ENUM(spoolss_EnumPorts);
}
/*
spoolss_EnumMonitors
*/
NTSTATUS ndr_push_spoolss_EnumMonitors(struct ndr_push *ndr, int flags, const struct spoolss_EnumMonitors *r)
{
NDR_SPOOLSS_PUSH_ENUM(spoolss_EnumMonitors,{
_r.in.servername= r->in.servername;
},{
_r.in.servername= r->in.servername;
});
return NT_STATUS_OK;
}
NTSTATUS ndr_pull_spoolss_EnumMonitors(struct ndr_pull *ndr, int flags, struct spoolss_EnumMonitors *r)
{
NDR_SPOOLSS_PULL_ENUM(spoolss_EnumMonitors,{
r->in.servername= _r.in.servername;
},{
_r.in.servername= r->in.servername;
});
return NT_STATUS_OK;
}
uint32_t ndr_size_spoolss_EnumMonitors_info(TALLOC_CTX *mem_ctx, uint32_t level, uint32_t count, union spoolss_MonitorInfo *info)
{
NDR_SPOOLSS_SIZE_ENUM(spoolss_EnumMonitors);
}
/*
spoolss_EnumPrintProcessors
*/
NTSTATUS ndr_push_spoolss_EnumPrintProcessors(struct ndr_push *ndr, int flags, const struct spoolss_EnumPrintProcessors *r)
{
NDR_SPOOLSS_PUSH_ENUM(spoolss_EnumPrintProcessors,{
_r.in.servername = r->in.servername;
_r.in.environment = r->in.environment;
},{
_r.in.servername = r->in.servername;
_r.in.environment = r->in.environment;
});
return NT_STATUS_OK;
}
NTSTATUS ndr_pull_spoolss_EnumPrintProcessors(struct ndr_pull *ndr, int flags, struct spoolss_EnumPrintProcessors *r)
{
NDR_SPOOLSS_PULL_ENUM(spoolss_EnumPrintProcessors,{
r->in.servername = _r.in.servername;
r->in.environment = _r.in.environment;
},{
_r.in.servername = r->in.servername;
_r.in.environment = r->in.environment;
});
return NT_STATUS_OK;
}
uint32_t ndr_size_spoolss_EnumPrinterProcessors_info(TALLOC_CTX *mem_ctx, uint32_t level, uint32_t count, union spoolss_PrintProcessorInfo *info)
{
NDR_SPOOLSS_SIZE_ENUM(spoolss_EnumPrintProcessors);
}
/*
spoolss_GetPrinterData
*/
NTSTATUS ndr_push_spoolss_GetPrinterData(struct ndr_push *ndr, int flags, const struct spoolss_GetPrinterData *r)
{
struct _spoolss_GetPrinterData _r;
if (flags & NDR_IN) {
_r.in.handle = r->in.handle;
_r.in.value_name= r->in.value_name;
_r.in.offered = r->in.offered;
NDR_CHECK(ndr_push__spoolss_GetPrinterData(ndr, flags, &_r));
}
if (flags & NDR_OUT) {
struct ndr_push *_ndr_info;\
_r.in.handle = r->in.handle;
_r.in.value_name= r->in.value_name;
_r.in.offered = r->in.offered;
_r.out.type = r->out.type;
_r.out.data = data_blob(NULL, 0);
_r.out.needed = r->out.needed;
_r.out.result = r->out.result;
{
struct __spoolss_GetPrinterData __r;
_ndr_info = ndr_push_init_ctx(ndr);
if (!_ndr_info) return NT_STATUS_NO_MEMORY;
_ndr_info->flags= ndr->flags;
__r.in.type = r->out.type;
__r.out.data = r->out.data;
NDR_CHECK(ndr_push___spoolss_GetPrinterData(_ndr_info, flags, &__r));
if (r->in.offered > _ndr_info->offset) {
uint32_t _padding_len = r->in.offered - _ndr_info->offset;
NDR_CHECK(ndr_push_zero(_ndr_info, _padding_len));
}
_r.out.data = ndr_push_blob(_ndr_info);
}
NDR_CHECK(ndr_push__spoolss_GetPrinterData(ndr, flags, &_r));
}
return NT_STATUS_OK;
}
NTSTATUS ndr_pull_spoolss_GetPrinterData(struct ndr_pull *ndr, int flags, struct spoolss_GetPrinterData *r)
{
struct _spoolss_GetPrinterData _r;
if (flags & NDR_IN) {
ZERO_STRUCT(r->out);
_r.in.handle = r->in.handle;
_r.in.value_name= r->in.value_name;
_r.in.offered = r->in.offered;
_r.out.type = r->out.type;
_r.out.data = data_blob(NULL,0),
_r.out.needed = r->out.needed;
NDR_CHECK(ndr_pull__spoolss_GetPrinterData(ndr, flags, &_r));
r->in.handle = _r.in.handle;
r->in.value_name= _r.in.value_name;
r->in.offered = _r.in.offered;
r->out.needed = _r.out.needed;
}
if (flags & NDR_OUT) {
_r.in.handle = r->in.handle;
_r.in.value_name= r->in.value_name;
_r.in.offered = r->in.offered;
_r.out.type = r->out.type;
_r.out.data = data_blob(NULL,0),
_r.out.needed = r->out.needed;
_r.out.result = r->out.result;
NDR_CHECK(ndr_pull__spoolss_GetPrinterData(ndr, flags, &_r));
r->out.type = _r.out.type;
ZERO_STRUCT(r->out.data);
r->out.needed = _r.out.needed;
r->out.result = _r.out.result;
if (_r.out.data.length != r->in.offered) {
return ndr_pull_error(ndr, NDR_ERR_BUFSIZE,\
"SPOOLSS Buffer: r->in.offered[%u] doesn't match length of out buffer[%u]",\
(unsigned)r->in.offered, (unsigned)_r.out.data.length);\
}
if (_r.out.data.length > 0 && r->out.needed <= _r.out.data.length) {
struct __spoolss_GetPrinterData __r;
struct ndr_pull *_ndr_data = ndr_pull_init_blob(&_r.out.data, ndr);
if (!_ndr_data) return NT_STATUS_NO_MEMORY;
_ndr_data->flags= ndr->flags;
__r.in.type = r->out.type;
__r.out.data = r->out.data;
NDR_CHECK(ndr_pull___spoolss_GetPrinterData(_ndr_data, flags, &__r));
r->out.data = __r.out.data;
} else {
r->out.type = SPOOLSS_PRINTER_DATA_TYPE_NULL;
}
}
return NT_STATUS_OK;
}
/*
spoolss_SetPrinterData
*/
NTSTATUS ndr_push_spoolss_SetPrinterData(struct ndr_push *ndr, int flags, const struct spoolss_SetPrinterData *r)
{
struct _spoolss_SetPrinterData _r;
if (flags & NDR_IN) {
struct ndr_push *_ndr_data;
struct __spoolss_SetPrinterData __r;
DATA_BLOB _data_blob_data;
_ndr_data = ndr_push_init_ctx(ndr);\
if (!_ndr_data) return NT_STATUS_NO_MEMORY;\
_ndr_data->flags= ndr->flags;\
__r.in.type = r->in.type;
__r.out.data = r->in.data;
NDR_CHECK(ndr_push___spoolss_SetPrinterData(_ndr_data, NDR_OUT, &__r));
_data_blob_data = ndr_push_blob(_ndr_data);
_r.in.handle = r->in.handle;
_r.in.value_name= r->in.value_name;
_r.in.type = r->in.type;
_r.in.data = _data_blob_data;
_r.in._offered = _data_blob_data.length;
_r.out.result = r->out.result;
NDR_CHECK(ndr_push__spoolss_SetPrinterData(ndr, flags, &_r));
}
if (flags & NDR_OUT) {
_r.in.handle = r->in.handle;
_r.in.value_name= r->in.value_name;
_r.in.type = r->in.type;
_r.in.data = data_blob(NULL,0),
_r.in._offered = r->in._offered;
_r.out.result = r->out.result;
NDR_CHECK(ndr_push__spoolss_SetPrinterData(ndr, flags, &_r));
}
return NT_STATUS_OK;
}
uint32_t _ndr_size_spoolss_DeviceMode(struct spoolss_DeviceMode *devmode, uint32_t flags)
{
if (!devmode) return 0;
return ndr_size_spoolss_DeviceMode(devmode,flags);
}
+622
View File
@@ -0,0 +1,622 @@
/*
Unix SMB/CIFS implementation.
routines for marshalling/unmarshalling string types
Copyright (C) Andrew Tridgell 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"
#include "librpc/ndr/libndr.h"
/**
pull a general string from the wire
*/
_PUBLIC_ NTSTATUS ndr_pull_string(struct ndr_pull *ndr, int ndr_flags, const char **s)
{
char *as=NULL;
uint32_t len1, ofs, len2;
uint16_t len3;
int ret;
int chset = CH_UTF16;
unsigned byte_mul = 2;
unsigned flags = ndr->flags;
unsigned c_len_term = 0;
if (!(ndr_flags & NDR_SCALARS)) {
return NT_STATUS_OK;
}
if (NDR_BE(ndr)) {
chset = CH_UTF16BE;
}
if (flags & LIBNDR_FLAG_STR_ASCII) {
chset = CH_DOS;
byte_mul = 1;
flags &= ~LIBNDR_FLAG_STR_ASCII;
}
if (flags & LIBNDR_FLAG_STR_UTF8) {
chset = CH_UTF8;
byte_mul = 1;
flags &= ~LIBNDR_FLAG_STR_UTF8;
}
flags &= ~LIBNDR_FLAG_STR_CONFORMANT;
if (flags & LIBNDR_FLAG_STR_CHARLEN) {
c_len_term = 1;
flags &= ~LIBNDR_FLAG_STR_CHARLEN;
}
switch (flags & LIBNDR_STRING_FLAGS) {
case LIBNDR_FLAG_STR_LEN4|LIBNDR_FLAG_STR_SIZE4:
case LIBNDR_FLAG_STR_LEN4|LIBNDR_FLAG_STR_SIZE4|LIBNDR_FLAG_STR_NOTERM:
NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &len1));
NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &ofs));
if (ofs != 0) {
return ndr_pull_error(ndr, NDR_ERR_STRING, "non-zero array offset with string flags 0x%x\n",
ndr->flags & LIBNDR_STRING_FLAGS);
}
NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &len2));
if (len2 > len1) {
return ndr_pull_error(ndr, NDR_ERR_STRING,
"Bad string lengths len1=%u ofs=%u len2=%u\n",
len1, ofs, len2);
}
NDR_PULL_NEED_BYTES(ndr, (len2 + c_len_term)*byte_mul);
if (len2 == 0) {
as = talloc_strdup(ndr->current_mem_ctx, "");
} else {
ret = convert_string_talloc(ndr->current_mem_ctx,
chset, CH_UNIX,
ndr->data+ndr->offset,
(len2 + c_len_term)*byte_mul,
(void **)&as);
if (ret == -1) {
return ndr_pull_error(ndr, NDR_ERR_CHARCNV,
"Bad character conversion");
}
}
NDR_CHECK(ndr_pull_advance(ndr, (len2 + c_len_term)*byte_mul));
if (len1 != len2) {
DEBUG(6,("len1[%u] != len2[%u] '%s'\n", len1, len2, as));
}
/* this is a way of detecting if a string is sent with the wrong
termination */
if (ndr->flags & LIBNDR_FLAG_STR_NOTERM) {
if (strlen(as) < (len2 + c_len_term)) {
DEBUG(6,("short string '%s'\n", as));
}
} else {
if (strlen(as) == (len2 + c_len_term)) {
DEBUG(6,("long string '%s'\n", as));
}
}
*s = as;
break;
case LIBNDR_FLAG_STR_SIZE4:
case LIBNDR_FLAG_STR_SIZE4|LIBNDR_FLAG_STR_NOTERM:
NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &len1));
NDR_PULL_NEED_BYTES(ndr, (len1 + c_len_term)*byte_mul);
if (len1 == 0) {
as = talloc_strdup(ndr->current_mem_ctx, "");
} else {
ret = convert_string_talloc(ndr->current_mem_ctx,
chset, CH_UNIX,
ndr->data+ndr->offset,
(len1 + c_len_term)*byte_mul,
(void **)&as);
if (ret == -1) {
return ndr_pull_error(ndr, NDR_ERR_CHARCNV,
"Bad character conversion");
}
}
NDR_CHECK(ndr_pull_advance(ndr, (len1 + c_len_term)*byte_mul));
/* this is a way of detecting if a string is sent with the wrong
termination */
if (ndr->flags & LIBNDR_FLAG_STR_NOTERM) {
if (strlen(as) < (len1 + c_len_term)) {
DEBUG(6,("short string '%s'\n", as));
}
} else {
if (strlen(as) == (len1 + c_len_term)) {
DEBUG(6,("long string '%s'\n", as));
}
}
*s = as;
break;
case LIBNDR_FLAG_STR_LEN4:
case LIBNDR_FLAG_STR_LEN4|LIBNDR_FLAG_STR_NOTERM:
NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &ofs));
if (ofs != 0) {
return ndr_pull_error(ndr, NDR_ERR_STRING, "non-zero array offset with string flags 0x%x\n",
ndr->flags & LIBNDR_STRING_FLAGS);
}
NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &len1));
NDR_PULL_NEED_BYTES(ndr, (len1 + c_len_term)*byte_mul);
if (len1 == 0) {
as = talloc_strdup(ndr->current_mem_ctx, "");
} else {
ret = convert_string_talloc(ndr->current_mem_ctx,
chset, CH_UNIX,
ndr->data+ndr->offset,
(len1 + c_len_term)*byte_mul,
(void **)&as);
if (ret == -1) {
return ndr_pull_error(ndr, NDR_ERR_CHARCNV,
"Bad character conversion");
}
}
NDR_CHECK(ndr_pull_advance(ndr, (len1 + c_len_term)*byte_mul));
/* this is a way of detecting if a string is sent with the wrong
termination */
if (ndr->flags & LIBNDR_FLAG_STR_NOTERM) {
if (strlen(as) < (len1 + c_len_term)) {
DEBUG(6,("short string '%s'\n", as));
}
} else {
if (strlen(as) == (len1 + c_len_term)) {
DEBUG(6,("long string '%s'\n", as));
}
}
*s = as;
break;
case LIBNDR_FLAG_STR_SIZE2:
case LIBNDR_FLAG_STR_SIZE2|LIBNDR_FLAG_STR_NOTERM:
NDR_CHECK(ndr_pull_uint16(ndr, NDR_SCALARS, &len3));
NDR_PULL_NEED_BYTES(ndr, (len3 + c_len_term)*byte_mul);
if (len3 == 0) {
as = talloc_strdup(ndr->current_mem_ctx, "");
} else {
ret = convert_string_talloc(ndr->current_mem_ctx,
chset, CH_UNIX,
ndr->data+ndr->offset,
(len3 + c_len_term)*byte_mul,
(void **)&as);
if (ret == -1) {
return ndr_pull_error(ndr, NDR_ERR_CHARCNV,
"Bad character conversion");
}
}
NDR_CHECK(ndr_pull_advance(ndr, (len3 + c_len_term)*byte_mul));
/* this is a way of detecting if a string is sent with the wrong
termination */
if (ndr->flags & LIBNDR_FLAG_STR_NOTERM) {
if (strlen(as) < (len3 + c_len_term)) {
DEBUG(6,("short string '%s'\n", as));
}
} else {
if (strlen(as) == (len3 + c_len_term)) {
DEBUG(6,("long string '%s'\n", as));
}
}
*s = as;
break;
case LIBNDR_FLAG_STR_SIZE2|LIBNDR_FLAG_STR_NOTERM|LIBNDR_FLAG_STR_BYTESIZE:
NDR_CHECK(ndr_pull_uint16(ndr, NDR_SCALARS, &len3));
NDR_PULL_NEED_BYTES(ndr, len3);
if (len3 == 0) {
as = talloc_strdup(ndr->current_mem_ctx, "");
} else {
ret = convert_string_talloc(ndr->current_mem_ctx,
chset, CH_UNIX,
ndr->data+ndr->offset,
len3,
(void **)&as);
if (ret == -1) {
return ndr_pull_error(ndr, NDR_ERR_CHARCNV,
"Bad character conversion");
}
}
NDR_CHECK(ndr_pull_advance(ndr, len3));
*s = as;
break;
case LIBNDR_FLAG_STR_NULLTERM:
if (byte_mul == 1) {
len1 = ascii_len_n((const char *)(ndr->data+ndr->offset), ndr->data_size - ndr->offset);
} else {
len1 = utf16_len_n(ndr->data+ndr->offset, ndr->data_size - ndr->offset);
}
ret = convert_string_talloc(ndr->current_mem_ctx,
chset, CH_UNIX,
ndr->data+ndr->offset,
len1,
(void **)&as);
if (ret == -1) {
return ndr_pull_error(ndr, NDR_ERR_CHARCNV,
"Bad character conversion");
}
NDR_CHECK(ndr_pull_advance(ndr, len1));
*s = as;
break;
case LIBNDR_FLAG_STR_FIXLEN15:
case LIBNDR_FLAG_STR_FIXLEN32:
len1 = (flags & LIBNDR_FLAG_STR_FIXLEN32)?32:15;
NDR_PULL_NEED_BYTES(ndr, len1*byte_mul);
ret = convert_string_talloc(ndr->current_mem_ctx,
chset, CH_UNIX,
ndr->data+ndr->offset,
len1*byte_mul,
(void **)&as);
if (ret == -1) {
return ndr_pull_error(ndr, NDR_ERR_CHARCNV,
"Bad character conversion");
}
NDR_CHECK(ndr_pull_advance(ndr, len1*byte_mul));
*s = as;
break;
default:
return ndr_pull_error(ndr, NDR_ERR_STRING, "Bad string flags 0x%x\n",
ndr->flags & LIBNDR_STRING_FLAGS);
}
return NT_STATUS_OK;
}
/**
push a general string onto the wire
*/
_PUBLIC_ NTSTATUS ndr_push_string(struct ndr_push *ndr, int ndr_flags, const char *s)
{
ssize_t s_len, c_len, d_len;
int chset = CH_UTF16;
unsigned flags = ndr->flags;
unsigned byte_mul = 2;
uint8_t *dest = NULL;
if (!(ndr_flags & NDR_SCALARS)) {
return NT_STATUS_OK;
}
if (NDR_BE(ndr)) {
chset = CH_UTF16BE;
}
s_len = s?strlen(s):0;
if (flags & LIBNDR_FLAG_STR_ASCII) {
chset = CH_DOS;
byte_mul = 1;
flags &= ~LIBNDR_FLAG_STR_ASCII;
}
if (flags & LIBNDR_FLAG_STR_UTF8) {
chset = CH_UTF8;
byte_mul = 1;
flags &= ~LIBNDR_FLAG_STR_UTF8;
}
flags &= ~LIBNDR_FLAG_STR_CONFORMANT;
if (!(flags &
(LIBNDR_FLAG_STR_NOTERM |
LIBNDR_FLAG_STR_FIXLEN15 |
LIBNDR_FLAG_STR_FIXLEN32))) {
s_len++;
}
d_len = convert_string_talloc(ndr, CH_UNIX, chset, s, s_len, (void **)&dest);
if (d_len == -1) {
return ndr_push_error(ndr, NDR_ERR_CHARCNV,
"Bad character conversion");
}
if (flags & LIBNDR_FLAG_STR_BYTESIZE) {
c_len = d_len;
flags &= ~LIBNDR_FLAG_STR_BYTESIZE;
} else if (flags & LIBNDR_FLAG_STR_CHARLEN) {
c_len = (d_len / byte_mul)-1;
flags &= ~LIBNDR_FLAG_STR_CHARLEN;
} else {
c_len = d_len / byte_mul;
}
switch ((flags & LIBNDR_STRING_FLAGS) & ~LIBNDR_FLAG_STR_NOTERM) {
case LIBNDR_FLAG_STR_LEN4|LIBNDR_FLAG_STR_SIZE4:
NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, c_len));
NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, 0));
NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, c_len));
NDR_CHECK(ndr_push_bytes(ndr, dest, d_len));
break;
case LIBNDR_FLAG_STR_LEN4:
NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, 0));
NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, c_len));
NDR_CHECK(ndr_push_bytes(ndr, dest, d_len));
break;
case LIBNDR_FLAG_STR_SIZE4:
NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, c_len));
NDR_CHECK(ndr_push_bytes(ndr, dest, d_len));
break;
case LIBNDR_FLAG_STR_SIZE2:
NDR_CHECK(ndr_push_uint16(ndr, NDR_SCALARS, c_len));
NDR_CHECK(ndr_push_bytes(ndr, dest, d_len));
break;
case LIBNDR_FLAG_STR_NULLTERM:
NDR_CHECK(ndr_push_bytes(ndr, dest, d_len));
break;
case LIBNDR_FLAG_STR_FIXLEN15:
case LIBNDR_FLAG_STR_FIXLEN32: {
ssize_t fix_len = (flags & LIBNDR_FLAG_STR_FIXLEN32)?32:15;
uint32_t pad_len = fix_len - d_len;
if (d_len > fix_len) {
return ndr_push_error(ndr, NDR_ERR_CHARCNV,
"Bad character conversion");
}
NDR_CHECK(ndr_push_bytes(ndr, dest, d_len));
if (pad_len != 0) {
NDR_CHECK(ndr_push_zero(ndr, pad_len));
}
break;
}
default:
return ndr_push_error(ndr, NDR_ERR_STRING, "Bad string flags 0x%x\n",
ndr->flags & LIBNDR_STRING_FLAGS);
}
talloc_free(dest);
return NT_STATUS_OK;
}
/**
push a general string onto the wire
*/
_PUBLIC_ size_t ndr_string_array_size(struct ndr_push *ndr, const char *s)
{
size_t c_len;
unsigned flags = ndr->flags;
unsigned byte_mul = 2;
unsigned c_len_term = 1;
if (flags & LIBNDR_FLAG_STR_FIXLEN32) {
return 32;
}
if (flags & LIBNDR_FLAG_STR_FIXLEN15) {
return 15;
}
c_len = s?strlen_m(s):0;
if (flags & (LIBNDR_FLAG_STR_ASCII|LIBNDR_FLAG_STR_UTF8)) {
byte_mul = 1;
}
if (flags & LIBNDR_FLAG_STR_NOTERM) {
c_len_term = 0;
}
c_len = c_len + c_len_term;
if (flags & LIBNDR_FLAG_STR_BYTESIZE) {
c_len = c_len * byte_mul;
}
return c_len;
}
_PUBLIC_ void ndr_print_string(struct ndr_print *ndr, const char *name, const char *s)
{
if (s) {
ndr->print(ndr, "%-25s: '%s'", name, s);
} else {
ndr->print(ndr, "%-25s: NULL", name);
}
}
_PUBLIC_ uint32_t ndr_size_string(int ret, const char * const* string, int flags)
{
/* FIXME: Is this correct for all strings ? */
if(!(*string)) return ret;
return ret+strlen(*string)+1;
}
/**
pull a general string array from the wire
*/
_PUBLIC_ NTSTATUS ndr_pull_string_array(struct ndr_pull *ndr, int ndr_flags, const char ***_a)
{
const char **a = *_a;
uint32_t count;
if (!(ndr_flags & NDR_SCALARS)) {
return NT_STATUS_OK;
}
for (count = 0;; count++) {
TALLOC_CTX *tmp_ctx;
const char *s = NULL;
a = talloc_realloc(ndr->current_mem_ctx, a, const char *, count + 2);
NT_STATUS_HAVE_NO_MEMORY(a);
a[count] = NULL;
a[count+1] = NULL;
tmp_ctx = ndr->current_mem_ctx;
ndr->current_mem_ctx = a;
NDR_CHECK(ndr_pull_string(ndr, ndr_flags, &s));
ndr->current_mem_ctx = tmp_ctx;
if (strcmp("", s)==0) {
a[count] = NULL;
break;
} else {
a[count] = s;
}
}
*_a =a;
return NT_STATUS_OK;
}
/**
push a general string array onto the wire
*/
_PUBLIC_ NTSTATUS ndr_push_string_array(struct ndr_push *ndr, int ndr_flags, const char **a)
{
uint32_t count;
if (!(ndr_flags & NDR_SCALARS)) {
return NT_STATUS_OK;
}
for (count = 0; a && a[count]; count++) {
NDR_CHECK(ndr_push_string(ndr, ndr_flags, a[count]));
}
NDR_CHECK(ndr_push_string(ndr, ndr_flags, ""));
return NT_STATUS_OK;
}
_PUBLIC_ void ndr_print_string_array(struct ndr_print *ndr, const char *name, const char **a)
{
uint32_t count;
uint32_t i;
for (count = 0; a && a[count]; count++) {}
ndr->print(ndr, "%s: ARRAY(%d)", name, count);
ndr->depth++;
for (i=0;i<count;i++) {
char *idx=NULL;
asprintf(&idx, "[%d]", i);
if (idx) {
ndr_print_string(ndr, idx, a[i]);
free(idx);
}
}
ndr->depth--;
}
/**
* Return number of elements in a string including the last (zeroed) element
*/
_PUBLIC_ uint32_t ndr_string_length(const void *_var, uint32_t element_size)
{
uint32_t i;
uint8_t zero[4] = {0,0,0,0};
const char *var = _var;
for (i = 0; memcmp(var+i*element_size,zero,element_size) != 0; i++);
return i+1;
}
_PUBLIC_ NTSTATUS ndr_check_string_terminator(struct ndr_pull *ndr, uint32_t count, uint32_t element_size)
{
uint32_t i;
struct ndr_pull_save save_offset;
ndr_pull_save(ndr, &save_offset);
ndr_pull_advance(ndr, (count - 1) * element_size);
NDR_PULL_NEED_BYTES(ndr, element_size);
for (i = 0; i < element_size; i++) {
if (ndr->data[ndr->offset+i] != 0) {
ndr_pull_restore(ndr, &save_offset);
return ndr_pull_error(ndr, NDR_ERR_ARRAY_SIZE, "String terminator not present or outside string boundaries");
}
}
ndr_pull_restore(ndr, &save_offset);
return NT_STATUS_OK;
}
_PUBLIC_ NTSTATUS ndr_pull_charset(struct ndr_pull *ndr, int ndr_flags, const char **var, uint32_t length, uint8_t byte_mul, charset_t chset)
{
int ret;
if (length == 0) {
*var = talloc_strdup(ndr->current_mem_ctx, "");
return NT_STATUS_OK;
}
if (NDR_BE(ndr) && chset == CH_UTF16) {
chset = CH_UTF16BE;
}
NDR_PULL_NEED_BYTES(ndr, length*byte_mul);
ret = convert_string_talloc(ndr->current_mem_ctx,
chset, CH_UNIX,
ndr->data+ndr->offset,
length*byte_mul,
discard_const_p(void *, var));
if (ret == -1) {
return ndr_pull_error(ndr, NDR_ERR_CHARCNV,
"Bad character conversion");
}
NDR_CHECK(ndr_pull_advance(ndr, length*byte_mul));
return NT_STATUS_OK;
}
_PUBLIC_ NTSTATUS ndr_push_charset(struct ndr_push *ndr, int ndr_flags, const char *var, uint32_t length, uint8_t byte_mul, charset_t chset)
{
ssize_t ret, required;
if (NDR_BE(ndr) && chset == CH_UTF16) {
chset = CH_UTF16BE;
}
required = byte_mul * length;
NDR_PUSH_NEED_BYTES(ndr, required);
ret = convert_string(CH_UNIX, chset,
var, strlen(var),
ndr->data+ndr->offset, required);
if (ret == -1) {
return ndr_push_error(ndr, NDR_ERR_CHARCNV,
"Bad character conversion");
}
/* Make sure the remaining part of the string is filled with zeroes */
if (ret < required) {
memset(ndr->data+ndr->offset+ret, 0, required-ret);
}
ndr->offset += required;
return NT_STATUS_OK;
}
/* Return number of elements in a string in the specified charset */
_PUBLIC_ uint32_t ndr_charset_length(const void *var, charset_t chset)
{
/* FIXME: Treat special chars special here, taking chset into account */
/* Also include 0 byte */
return strlen(var)+1;
}
+150
View File
@@ -0,0 +1,150 @@
/*
Unix SMB/CIFS implementation.
UUID/GUID functions
Copyright (C) Theodore Ts'o 1996, 1997,
Copyright (C) Jim McDonough 2002.
Copyright (C) Andrew Tridgell 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"
/**
build a GUID from a string
*/
_PUBLIC_ NTSTATUS GUID_from_string(const char *s, struct GUID *guid)
{
NTSTATUS status = NT_STATUS_INVALID_PARAMETER;
uint32_t time_low;
uint32_t time_mid, time_hi_and_version;
uint32_t clock_seq[2];
uint32_t node[6];
int i;
if (s == NULL) {
return NT_STATUS_INVALID_PARAMETER;
}
if (11 == sscanf(s, "%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x",
&time_low, &time_mid, &time_hi_and_version,
&clock_seq[0], &clock_seq[1],
&node[0], &node[1], &node[2], &node[3], &node[4], &node[5])) {
status = NT_STATUS_OK;
} else if (11 == sscanf(s, "{%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x}",
&time_low, &time_mid, &time_hi_and_version,
&clock_seq[0], &clock_seq[1],
&node[0], &node[1], &node[2], &node[3], &node[4], &node[5])) {
status = NT_STATUS_OK;
}
if (!NT_STATUS_IS_OK(status)) {
return status;
}
guid->time_low = time_low;
guid->time_mid = time_mid;
guid->time_hi_and_version = time_hi_and_version;
guid->clock_seq[0] = clock_seq[0];
guid->clock_seq[1] = clock_seq[1];
for (i=0;i<6;i++) {
guid->node[i] = node[i];
}
return NT_STATUS_OK;
}
/**
* generate a random GUID
*/
struct GUID GUID_random(void)
{
struct GUID guid;
generate_random_buffer((uint8_t *)&guid, sizeof(guid));
guid.clock_seq[0] = (guid.clock_seq[0] & 0x3F) | 0x80;
guid.time_hi_and_version = (guid.time_hi_and_version & 0x0FFF) | 0x4000;
return guid;
}
/**
* generate an empty GUID
*/
_PUBLIC_ struct GUID GUID_zero(void)
{
struct GUID guid;
ZERO_STRUCT(guid);
return guid;
}
_PUBLIC_ BOOL GUID_all_zero(const struct GUID *u)
{
if (u->time_low != 0 ||
u->time_mid != 0 ||
u->time_hi_and_version != 0 ||
u->clock_seq[0] != 0 ||
u->clock_seq[1] != 0 ||
!all_zero(u->node, 6)) {
return False;
}
return True;
}
_PUBLIC_ BOOL GUID_equal(const struct GUID *u1, const struct GUID *u2)
{
if (u1->time_low != u2->time_low ||
u1->time_mid != u2->time_mid ||
u1->time_hi_and_version != u2->time_hi_and_version ||
u1->clock_seq[0] != u2->clock_seq[0] ||
u1->clock_seq[1] != u2->clock_seq[1] ||
memcmp(u1->node, u2->node, 6) != 0) {
return False;
}
return True;
}
/**
its useful to be able to display these in debugging messages
*/
_PUBLIC_ char *GUID_string(TALLOC_CTX *mem_ctx, const struct GUID *guid)
{
return talloc_asprintf(mem_ctx,
"%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x",
guid->time_low, guid->time_mid,
guid->time_hi_and_version,
guid->clock_seq[0],
guid->clock_seq[1],
guid->node[0], guid->node[1],
guid->node[2], guid->node[3],
guid->node[4], guid->node[5]);
}
_PUBLIC_ char *GUID_string2(TALLOC_CTX *mem_ctx, const struct GUID *guid)
{
char *ret, *s = GUID_string(mem_ctx, guid);
ret = talloc_asprintf(mem_ctx, "{%s}", s);
talloc_free(s);
return ret;
}
_PUBLIC_ BOOL policy_handle_empty(struct policy_handle *h)
{
return (h->handle_type == 0 && GUID_all_zero(&h->uuid));
}