/** push a general string array onto the wire */ 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_ enum ndr_err_code ndr_push_TRUSTED_DOM_PASS(struct ndr_push *ndr, int ndr_flags, const struct TRUSTED_DOM_PASS *r) { { 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_uint32(ndr, NDR_SCALARS, strlen_m_term(r->uni_name))); NDR_CHECK(ndr_push_charset(ndr, NDR_SCALARS, r->uni_name, 32, sizeof(uint16_t), CH_UTF16)); NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, strlen(r->pass))); { uint32_t _flags_save_string = ndr->flags; ndr_set_flags(&ndr->flags, LIBNDR_FLAG_STR_ASCII|LIBNDR_FLAG_STR_NULLTERM); NDR_CHECK(ndr_push_string(ndr, NDR_SCALARS, r->pass)); ndr->flags = _flags_save_string; } NDR_CHECK(ndr_push_time_t(ndr, NDR_SCALARS, r->mod_time)); NDR_CHECK(ndr_push_dom_sid(ndr, NDR_SCALARS, &r->domain_sid)); NDR_CHECK(ndr_push_trailer_align(ndr, 4)); } if (ndr_flags & NDR_BUFFERS) { } ndr->flags = _flags_save_STRUCT; } return NDR_ERR_SUCCESS; }
_PUBLIC_ enum ndr_err_code ndr_push_xattr_DOSATTRIB(struct ndr_push *ndr, int ndr_flags, const struct xattr_DOSATTRIB *r) { if (ndr_flags & NDR_SCALARS) { char *attrib_hex = NULL; attrib_hex = ndr_compat_xattr_attrib_hex(ndr, r); NDR_ERR_HAVE_NO_MEMORY(attrib_hex); NDR_CHECK(ndr_push_align(ndr, 4)); { uint32_t _flags_save_string = ndr->flags; ndr_set_flags(&ndr->flags, LIBNDR_FLAG_STR_ASCII|LIBNDR_FLAG_STR_NULLTERM); NDR_CHECK(ndr_push_string(ndr, NDR_SCALARS, attrib_hex)); ndr->flags = _flags_save_string; } if (r->version == 0xFFFF) { return NDR_ERR_SUCCESS; } NDR_CHECK(ndr_push_uint16(ndr, NDR_SCALARS, r->version)); NDR_CHECK(ndr_push_set_switch_value(ndr, &r->info, r->version)); NDR_CHECK(ndr_push_xattr_DosInfo(ndr, NDR_SCALARS, &r->info)); } if (ndr_flags & NDR_BUFFERS) { } return NDR_ERR_SUCCESS; }
/* Manually modified to handle the dom_sid being optional based on if it is present or all zero */ enum ndr_err_code ndr_push_NETLOGON_SAM_LOGON_REQUEST(struct ndr_push *ndr, int ndr_flags, const struct NETLOGON_SAM_LOGON_REQUEST *r) { if (ndr_flags & NDR_SCALARS) { NDR_CHECK(ndr_push_align(ndr, 4)); NDR_CHECK(ndr_push_uint16(ndr, NDR_SCALARS, r->request_count)); { uint32_t _flags_save_string = ndr->flags; ndr_set_flags(&ndr->flags, LIBNDR_FLAG_STR_NULLTERM); NDR_CHECK(ndr_push_string(ndr, NDR_SCALARS, r->computer_name)); ndr->flags = _flags_save_string; } { uint32_t _flags_save_string = ndr->flags; ndr_set_flags(&ndr->flags, LIBNDR_FLAG_STR_NULLTERM); NDR_CHECK(ndr_push_string(ndr, NDR_SCALARS, r->user_name)); ndr->flags = _flags_save_string; } { uint32_t _flags_save_string = ndr->flags; ndr_set_flags(&ndr->flags, LIBNDR_FLAG_STR_ASCII|LIBNDR_FLAG_STR_NULLTERM); NDR_CHECK(ndr_push_string(ndr, NDR_SCALARS, r->mailslot_name)); ndr->flags = _flags_save_string; } NDR_CHECK(ndr_push_samr_AcctFlags(ndr, NDR_SCALARS, r->acct_control)); NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, ndr_size_dom_sid0(&r->sid, ndr->flags))); if (ndr_size_dom_sid0(&r->sid, ndr->flags)) { struct ndr_push *_ndr_sid; uint32_t _flags_save_DATA_BLOB = ndr->flags; ndr_set_flags(&ndr->flags, LIBNDR_FLAG_ALIGN4); NDR_CHECK(ndr_push_DATA_BLOB(ndr, NDR_SCALARS, r->_pad)); ndr->flags = _flags_save_DATA_BLOB; NDR_CHECK(ndr_push_subcontext_start(ndr, &_ndr_sid, 0, ndr_size_dom_sid0(&r->sid, ndr->flags))); NDR_CHECK(ndr_push_dom_sid0(_ndr_sid, NDR_SCALARS|NDR_BUFFERS, &r->sid)); NDR_CHECK(ndr_push_subcontext_end(ndr, _ndr_sid, 0, ndr_size_dom_sid0(&r->sid, ndr->flags))); } NDR_CHECK(ndr_push_netlogon_nt_version_flags(ndr, NDR_SCALARS, r->nt_version)); NDR_CHECK(ndr_push_uint16(ndr, NDR_SCALARS, r->lmnt_token)); NDR_CHECK(ndr_push_uint16(ndr, NDR_SCALARS, r->lm20_token)); } if (ndr_flags & NDR_BUFFERS) { } return NDR_ERR_SUCCESS; }
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; }
_PUBLIC_ enum ndr_err_code ndr_push_tdb_xattr(struct ndr_push *ndr, int ndr_flags, const struct tdb_xattr *r) { if (ndr_flags & NDR_SCALARS) { NDR_CHECK(ndr_push_align(ndr, 4)); { uint32_t _flags_save_string = ndr->flags; ndr_set_flags(&ndr->flags, LIBNDR_FLAG_STR_UTF8|LIBNDR_FLAG_STR_NULLTERM); NDR_CHECK(ndr_push_string(ndr, NDR_SCALARS, r->name)); ndr->flags = _flags_save_string; } NDR_CHECK(ndr_push_DATA_BLOB(ndr, NDR_SCALARS, r->value)); } if (ndr_flags & NDR_BUFFERS) { } return NDR_ERR_SUCCESS; }
_PUBLIC_ enum ndr_err_code ndr_push_notify_event(struct ndr_push *ndr, int ndr_flags, const struct notify_event *r) { if (ndr_flags & NDR_SCALARS) { NDR_CHECK(ndr_push_align(ndr, 8)); NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, r->action)); { uint32_t _flags_save_string = ndr->flags; ndr_set_flags(&ndr->flags, LIBNDR_FLAG_STR_UTF8|LIBNDR_FLAG_STR_NULLTERM); NDR_CHECK(ndr_push_string(ndr, NDR_SCALARS, r->path)); ndr->flags = _flags_save_string; } NDR_CHECK(ndr_push_pointer(ndr, NDR_SCALARS, r->private_data)); } if (ndr_flags & NDR_BUFFERS) { } return NDR_ERR_SUCCESS; }
static enum ndr_err_code ndr_push_xattr_DosStream(struct ndr_push *ndr, int ndr_flags, const struct xattr_DosStream *r) { if (ndr_flags & NDR_SCALARS) { NDR_CHECK(ndr_push_align(ndr, 4)); NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, r->flags)); NDR_CHECK(ndr_push_udlong(ndr, NDR_SCALARS, r->size)); NDR_CHECK(ndr_push_udlong(ndr, NDR_SCALARS, r->alloc_size)); { uint32_t _flags_save_string = ndr->flags; ndr_set_flags(&ndr->flags, LIBNDR_FLAG_STR_UTF8|LIBNDR_FLAG_STR_NULLTERM); NDR_CHECK(ndr_push_string(ndr, NDR_SCALARS, r->name)); ndr->flags = _flags_save_string; } } if (ndr_flags & NDR_BUFFERS) { } return NDR_ERR_SUCCESS; }
enum ndr_err_code ndr_push_BSTR(struct ndr_push *ndr, int ndr_flags, const struct BSTR *r) { uint32_t len; uint32_t flags; enum ndr_err_code status; len = strlen(r->data); 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->data); ndr->flags = flags; return status; } return NDR_ERR_SUCCESS; }
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; }
_PUBLIC_ enum ndr_err_code ndr_push_notify_entry(struct ndr_push *ndr, int ndr_flags, const struct notify_entry *r) { if (ndr_flags & NDR_SCALARS) { NDR_CHECK(ndr_push_align(ndr, 8)); NDR_CHECK(ndr_push_server_id(ndr, NDR_SCALARS, &r->server)); NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, r->filter)); NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, r->subdir_filter)); NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, r->dir_fd)); NDR_CHECK(ndr_push_file_id(ndr, NDR_SCALARS, &r->dir_id)); { uint32_t _flags_save_string = ndr->flags; ndr_set_flags(&ndr->flags, LIBNDR_FLAG_STR_UTF8|LIBNDR_FLAG_STR_NULLTERM); NDR_CHECK(ndr_push_string(ndr, NDR_SCALARS, r->path)); ndr->flags = _flags_save_string; } NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, r->path_len)); NDR_CHECK(ndr_push_pointer(ndr, NDR_SCALARS, r->private_data)); NDR_CHECK(ndr_push_trailer_align(ndr, 8)); } if (ndr_flags & NDR_BUFFERS) { } return NDR_ERR_SUCCESS; }
_PUBLIC_ enum ndr_err_code ndr_push_winreg_Data(struct ndr_push *ndr, int ndr_flags, const union winreg_Data *r) { { uint32_t _flags_save_UNION = ndr->flags; ndr_set_flags(&ndr->flags, LIBNDR_FLAG_LITTLE_ENDIAN); if (ndr_flags & NDR_SCALARS) { int level = ndr_push_get_switch_value(ndr, r); NDR_CHECK(ndr_push_union_align(ndr, 4)); switch (level) { case REG_NONE: { break; } case REG_SZ: { { uint32_t _flags_save_string = ndr->flags; ndr_set_flags(&ndr->flags, LIBNDR_FLAG_STR_NULLTERM); NDR_CHECK(ndr_push_string(ndr, NDR_SCALARS, r->string)); ndr->flags = _flags_save_string; } break; } case REG_EXPAND_SZ: { { uint32_t _flags_save_string = ndr->flags; ndr_set_flags(&ndr->flags, LIBNDR_FLAG_STR_NULLTERM); NDR_CHECK(ndr_push_string(ndr, NDR_SCALARS, r->string)); ndr->flags = _flags_save_string; } break; } case REG_BINARY: { { uint32_t _flags_save_DATA_BLOB = ndr->flags; ndr_set_flags(&ndr->flags, LIBNDR_FLAG_REMAINING); NDR_CHECK(ndr_push_DATA_BLOB(ndr, NDR_SCALARS, r->binary)); ndr->flags = _flags_save_DATA_BLOB; } break; } case REG_DWORD: { NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, r->value)); break; } case REG_DWORD_BIG_ENDIAN: { { uint32_t _flags_save_uint32 = ndr->flags; ndr_set_flags(&ndr->flags, LIBNDR_FLAG_BIGENDIAN); NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, r->value)); ndr->flags = _flags_save_uint32; } break; } case REG_MULTI_SZ: { { uint32_t _flags_save_string_array = ndr->flags; ndr_set_flags(&ndr->flags, LIBNDR_FLAG_STR_NULLTERM); NDR_CHECK(ndr_push_string_array(ndr, NDR_SCALARS, r->string_array)); ndr->flags = _flags_save_string_array; } break; } default: { { uint32_t _flags_save_DATA_BLOB = ndr->flags; ndr_set_flags(&ndr->flags, LIBNDR_FLAG_REMAINING); NDR_CHECK(ndr_push_DATA_BLOB(ndr, NDR_SCALARS, r->data)); ndr->flags = _flags_save_DATA_BLOB; } break; } } } if (ndr_flags & NDR_BUFFERS) { int level = ndr_push_get_switch_value(ndr, r); switch (level) { case REG_NONE: break; case REG_SZ: break; case REG_EXPAND_SZ: break; case REG_BINARY: break; case REG_DWORD: break; case REG_DWORD_BIG_ENDIAN: break; case REG_MULTI_SZ: break; default: break; } } ndr->flags = _flags_save_UNION; } return NDR_ERR_SUCCESS; }
/** \details Add a property value to a DATA blob. This convenient function should be used when creating a GetPropertiesSpecific reply response blob. \param mem_ctx pointer to the memory context \param property the property tag which value is meant to be appended to the blob \param value generic pointer on the property value \param blob the data blob the function uses to return the blob \param layout whether values should be prefixed by a layout \param flagged define if the properties are flagged or not \note blob.length must be set to 0 before this function is called the first time. Also the function only supports a limited set of property types at the moment. \return 0 on success; */ _PUBLIC_ int libmapiserver_push_property(TALLOC_CTX *mem_ctx, uint32_t property, const void *value, DATA_BLOB *blob, uint8_t layout, uint8_t flagged, uint8_t untyped) { struct ndr_push *ndr; struct SBinary_short bin; struct BinaryArray_r *bin_array; uint32_t i; ndr = ndr_push_init_ctx(mem_ctx); ndr_set_flags(&ndr->flags, LIBNDR_FLAG_NOALIGN); ndr->offset = 0; if (blob->length) { talloc_free(ndr->data); ndr->data = blob->data; ndr->offset = blob->length; } /* Step 1. Is the property typed */ if (untyped) { ndr_push_uint16(ndr, NDR_SCALARS, property & 0xFFFF); } /* Step 2. Is the property flagged */ if (flagged) { switch (property & 0xFFFF) { case PT_ERROR: switch (layout) { case 0x1: ndr_push_uint8(ndr, NDR_SCALARS, layout); goto end; case PT_ERROR: ndr_push_uint8(ndr, NDR_SCALARS, PT_ERROR); break; } break; default: ndr_push_uint8(ndr, NDR_SCALARS, 0x0); break; } } else { /* Step 3. Set the layout */ if (layout) { switch (property & 0xFFFF) { case PT_ERROR: ndr_push_uint8(ndr, NDR_SCALARS, PT_ERROR); break; default: ndr_push_uint8(ndr, NDR_SCALARS, 0x0); } } } /* Step 3. Push property data if supported */ switch (property & 0xFFFF) { case PT_I2: ndr_push_uint16(ndr, NDR_SCALARS, *(uint16_t *) value); break; case PT_LONG: case PT_ERROR: case PT_OBJECT: ndr_push_uint32(ndr, NDR_SCALARS, *(uint32_t *) value); break; case PT_DOUBLE: ndr_push_double(ndr, NDR_SCALARS, *(double *) value); break; case PT_I8: ndr_push_dlong(ndr, NDR_SCALARS, *(uint64_t *) value); break; case PT_BOOLEAN: ndr_push_uint8(ndr, NDR_SCALARS, *(uint8_t *) value); break; case PT_STRING8: ndr_set_flags(&ndr->flags, LIBNDR_FLAG_STR_NULLTERM|LIBNDR_FLAG_STR_ASCII); ndr_push_string(ndr, NDR_SCALARS, (char *) value); break; case PT_UNICODE: ndr_set_flags(&ndr->flags, LIBNDR_FLAG_STR_NULLTERM); ndr_push_string(ndr, NDR_SCALARS, (char *) value); break; case PT_BINARY: case PT_SVREID: /* PropertyRow expect a 16 bit header for BLOB in RopQueryRows and RopGetPropertiesSpecific */ bin.cb = ((struct Binary_r *) value)->cb; bin.lpb = ((struct Binary_r *) value)->lpb; ndr_push_SBinary_short(ndr, NDR_SCALARS, &bin); break; case PT_CLSID: ndr_push_GUID(ndr, NDR_SCALARS, (struct GUID *) value); break; case PT_SYSTIME: ndr_push_FILETIME(ndr, NDR_SCALARS, (struct FILETIME *) value); break; case PT_MV_LONG: ndr_push_mapi_MV_LONG_STRUCT(ndr, NDR_SCALARS, (struct mapi_MV_LONG_STRUCT *) value); break; case PT_MV_UNICODE: ndr_push_mapi_SLPSTRArrayW(ndr, NDR_SCALARS, (struct mapi_SLPSTRArrayW *) value); break; case PT_MV_BINARY: bin_array = (struct BinaryArray_r *) value; ndr_push_uint32(ndr, NDR_SCALARS, bin_array->cValues); for (i = 0; i < bin_array->cValues; i++) { bin.cb = bin_array->lpbin[i].cb; bin.lpb = bin_array->lpbin[i].lpb; ndr_push_SBinary_short(ndr, NDR_SCALARS, &bin); } break; default: if (property != 0) { OC_DEBUG(5, "unsupported type: %.4x", (property & 0xffff)); abort(); } break; } end: /* Step 4. Steal ndr context */ blob->data = ndr->data; talloc_steal(mem_ctx, blob->data); blob->length = ndr->offset; talloc_free(ndr); return 0; }