_PUBLIC_ enum ndr_err_code ndr_pop_dcerpc_sec_verification_trailer( struct ndr_pull *ndr, TALLOC_CTX *mem_ctx, struct dcerpc_sec_verification_trailer **_r) { enum ndr_err_code ndr_err; uint32_t ofs; uint32_t min_ofs = 0; struct dcerpc_sec_verification_trailer *r; DATA_BLOB sub_blob = data_blob_null; struct ndr_pull *sub_ndr = NULL; uint32_t remaining; *_r = NULL; r = talloc_zero(mem_ctx, struct dcerpc_sec_verification_trailer); if (r == NULL) { return NDR_ERR_ALLOC; } if (ndr->data_size < sizeof(DCERPC_SEC_VT_MAGIC)) { /* * we return with r->count = 0 */ *_r = r; return NDR_ERR_SUCCESS; } ofs = ndr->data_size - sizeof(DCERPC_SEC_VT_MAGIC); /* the magic is 4 byte aligned */ ofs &= ~3; if (ofs > DCERPC_SEC_VT_MAX_SIZE) { /* * We just scan the last 1024 bytes. */ min_ofs = ofs - DCERPC_SEC_VT_MAX_SIZE; } else { min_ofs = 0; } while (true) { int ret; ret = memcmp(&ndr->data[ofs], DCERPC_SEC_VT_MAGIC, sizeof(DCERPC_SEC_VT_MAGIC)); if (ret == 0) { sub_blob = data_blob_const(&ndr->data[ofs], ndr->data_size - ofs); break; } if (ofs <= min_ofs) { break; } ofs -= 4; } if (sub_blob.length == 0) { /* * we return with r->count = 0 */ *_r = r; return NDR_ERR_SUCCESS; } sub_ndr = ndr_pull_init_blob(&sub_blob, r); if (sub_ndr == NULL) { TALLOC_FREE(r); return NDR_ERR_ALLOC; } ndr_err = ndr_pull_dcerpc_sec_verification_trailer(sub_ndr, NDR_SCALARS | NDR_BUFFERS, r); if (ndr_err == NDR_ERR_ALLOC) { TALLOC_FREE(r); return NDR_ERR_ALLOC; } if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { goto ignore_error; } remaining = sub_ndr->data_size - sub_ndr->offset; if (remaining > 16) { /* * we expect not more than 16 byte of additional * padding after the verification trailer. */ goto ignore_error; } /* * We assume that we got a real verification trailer. * * We remove it from the available stub data. */ ndr->data_size = ofs; TALLOC_FREE(sub_ndr); *_r = r; return NDR_ERR_SUCCESS; ignore_error: TALLOC_FREE(sub_ndr); /* * just ignore the error, it's likely * that the magic we found belongs to * the stub data. * * we return with r->count = 0 */ ZERO_STRUCTP(r); *_r = r; return NDR_ERR_SUCCESS; }
static bool api_frsrpc_FrsStartPromotionParent(struct pipes_struct *p) { const struct ndr_interface_call *call; struct ndr_pull *pull; struct ndr_push *push; enum ndr_err_code ndr_err; struct frsrpc_FrsStartPromotionParent *r; call = &ndr_table_frsrpc.calls[NDR_FRSRPC_FRSSTARTPROMOTIONPARENT]; r = talloc(talloc_tos(), struct frsrpc_FrsStartPromotionParent); if (r == NULL) { return false; } pull = ndr_pull_init_blob(&p->in_data.data, r); if (pull == NULL) { talloc_free(r); return false; } pull->flags |= LIBNDR_FLAG_REF_ALLOC; if (p->endian) { pull->flags |= LIBNDR_FLAG_BIGENDIAN; } ndr_err = call->ndr_pull(pull, NDR_IN, r); if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { talloc_free(r); return false; } if (DEBUGLEVEL >= 10) { NDR_PRINT_FUNCTION_DEBUG(frsrpc_FrsStartPromotionParent, NDR_IN, r); } ZERO_STRUCT(r->out); r->out.parent_guid = r->in.parent_guid; r->out.result = _frsrpc_FrsStartPromotionParent(p, r); if (p->fault_state) { talloc_free(r); /* Return true here, srv_pipe_hnd.c will take care */ return true; } if (DEBUGLEVEL >= 10) { NDR_PRINT_FUNCTION_DEBUG(frsrpc_FrsStartPromotionParent, NDR_OUT | NDR_SET_VALUES, r); } push = ndr_push_init_ctx(r); if (push == NULL) { talloc_free(r); return false; } /* * carry over the pointer count to the reply in case we are * using full pointer. See NDR specification for full pointers */ push->ptr_count = pull->ptr_count; ndr_err = call->ndr_push(push, NDR_OUT, r); if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { talloc_free(r); return false; } p->out_data.rdata = ndr_push_blob(push); talloc_steal(p->mem_ctx, p->out_data.rdata.data); talloc_free(r); return true; }
static bool api_fss_IsPathSupported(struct pipes_struct *p) { const struct ndr_interface_call *call; struct ndr_pull *pull; struct ndr_push *push; enum ndr_err_code ndr_err; struct fss_IsPathSupported *r; call = &ndr_table_FileServerVssAgent.calls[NDR_FSS_ISPATHSUPPORTED]; r = talloc(talloc_tos(), struct fss_IsPathSupported); if (r == NULL) { return false; } pull = ndr_pull_init_blob(&p->in_data.data, r); if (pull == NULL) { talloc_free(r); return false; } pull->flags |= LIBNDR_FLAG_REF_ALLOC; if (p->endian) { pull->flags |= LIBNDR_FLAG_BIGENDIAN; } ndr_err = call->ndr_pull(pull, NDR_IN, r); if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { talloc_free(r); return false; } if (DEBUGLEVEL >= 10) { NDR_PRINT_FUNCTION_DEBUG(fss_IsPathSupported, NDR_IN, r); } ZERO_STRUCT(r->out); r->out.SupportedByThisProvider = talloc_zero(r, uint32_t); if (r->out.SupportedByThisProvider == NULL) { talloc_free(r); return false; } r->out.OwnerMachineName = talloc_zero(r, const char *); if (r->out.OwnerMachineName == NULL) { talloc_free(r); return false; } r->out.result = _fss_IsPathSupported(p, r); if (p->fault_state) { talloc_free(r); /* Return true here, srv_pipe_hnd.c will take care */ return true; } if (DEBUGLEVEL >= 10) { NDR_PRINT_FUNCTION_DEBUG(fss_IsPathSupported, NDR_OUT | NDR_SET_VALUES, r); } push = ndr_push_init_ctx(r); if (push == NULL) { talloc_free(r); return false; } /* * carry over the pointer count to the reply in case we are * using full pointer. See NDR specification for full pointers */ push->ptr_count = pull->ptr_count; ndr_err = call->ndr_push(push, NDR_OUT, r); if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { talloc_free(r); return false; } p->out_data.rdata = ndr_push_blob(push); talloc_steal(p->mem_ctx, p->out_data.rdata.data); talloc_free(r); return true; }
static bool api_fss_PrepareShadowCopySet(struct pipes_struct *p) { const struct ndr_interface_call *call; struct ndr_pull *pull; struct ndr_push *push; enum ndr_err_code ndr_err; struct fss_PrepareShadowCopySet *r; call = &ndr_table_FileServerVssAgent.calls[NDR_FSS_PREPARESHADOWCOPYSET]; r = talloc(talloc_tos(), struct fss_PrepareShadowCopySet); if (r == NULL) { return false; } pull = ndr_pull_init_blob(&p->in_data.data, r); if (pull == NULL) { talloc_free(r); return false; } pull->flags |= LIBNDR_FLAG_REF_ALLOC; if (p->endian) { pull->flags |= LIBNDR_FLAG_BIGENDIAN; } ndr_err = call->ndr_pull(pull, NDR_IN, r); if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { talloc_free(r); return false; } if (DEBUGLEVEL >= 10) { NDR_PRINT_FUNCTION_DEBUG(fss_PrepareShadowCopySet, NDR_IN, r); } r->out.result = _fss_PrepareShadowCopySet(p, r); if (p->fault_state) { talloc_free(r); /* Return true here, srv_pipe_hnd.c will take care */ return true; } if (DEBUGLEVEL >= 10) { NDR_PRINT_FUNCTION_DEBUG(fss_PrepareShadowCopySet, NDR_OUT | NDR_SET_VALUES, r); } push = ndr_push_init_ctx(r); if (push == NULL) { talloc_free(r); return false; } /* * carry over the pointer count to the reply in case we are * using full pointer. See NDR specification for full pointers */ push->ptr_count = pull->ptr_count; ndr_err = call->ndr_push(push, NDR_OUT, r); if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { talloc_free(r); return false; } p->out_data.rdata = ndr_push_blob(push); talloc_steal(p->mem_ctx, p->out_data.rdata.data); talloc_free(r); return true; }
static bool test_EnumServicesStatus(struct torture_context *tctx, struct dcerpc_pipe *p) { struct svcctl_EnumServicesStatusW r; struct policy_handle h; int i; NTSTATUS status; uint32_t resume_handle = 0; struct ENUM_SERVICE_STATUSW *service = NULL; uint32_t needed = 0; uint32_t services_returned = 0; struct dcerpc_binding_handle *b = p->binding_handle; if (!test_OpenSCManager(b, tctx, &h)) return false; r.in.handle = &h; r.in.type = SERVICE_TYPE_WIN32; r.in.state = SERVICE_STATE_ALL; r.in.offered = 0; r.in.resume_handle = &resume_handle; r.out.service = NULL; r.out.resume_handle = &resume_handle; r.out.services_returned = &services_returned; r.out.needed = &needed; status = dcerpc_svcctl_EnumServicesStatusW_r(b, tctx, &r); torture_assert_ntstatus_ok(tctx, status, "EnumServicesStatus failed!"); if (W_ERROR_EQUAL(r.out.result, WERR_MORE_DATA)) { r.in.offered = needed; r.out.service = talloc_array(tctx, uint8_t, needed); status = dcerpc_svcctl_EnumServicesStatusW_r(b, tctx, &r); torture_assert_ntstatus_ok(tctx, status, "EnumServicesStatus failed!"); torture_assert_werr_ok(tctx, r.out.result, "EnumServicesStatus failed"); } if (services_returned > 0) { enum ndr_err_code ndr_err; DATA_BLOB blob; struct ndr_pull *ndr; blob.length = r.in.offered; blob.data = talloc_steal(tctx, r.out.service); ndr = ndr_pull_init_blob(&blob, tctx); service = talloc_array(tctx, struct ENUM_SERVICE_STATUSW, services_returned); if (!service) { return false; } ndr_err = ndr_pull_ENUM_SERVICE_STATUSW_array( ndr, services_returned, service); if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { return false; } } for(i = 0; i < services_returned; i++) { torture_assert(tctx, service[i].service_name, "Service without name returned!"); printf("%-20s \"%s\", Type: %d, State: %d\n", service[i].service_name, service[i].display_name, service[i].status.type, service[i].status.state); } if (!test_CloseServiceHandle(b, tctx, &h)) return false; return true; }
static bool test_ReadEventLog(struct torture_context *tctx, struct dcerpc_pipe *p) { NTSTATUS status; struct eventlog_ReadEventLogW r; struct eventlog_CloseEventLog cr; struct policy_handle handle; if (!get_policy_handle(tctx, p, &handle)) return false; r.in.offset = 0; r.in.handle = &handle; r.in.flags = EVENTLOG_BACKWARDS_READ|EVENTLOG_SEQUENTIAL_READ; while (1) { DATA_BLOB blob; struct eventlog_Record rec; struct ndr_pull *ndr; /* Read first for number of bytes in record */ r.in.number_of_bytes = 0; r.out.data = NULL; status = dcerpc_eventlog_ReadEventLogW(p, tctx, &r); if (NT_STATUS_EQUAL(r.out.result, NT_STATUS_END_OF_FILE)) { break; } torture_assert_ntstatus_ok(tctx, status, "ReadEventLog failed"); torture_assert_ntstatus_equal(tctx, r.out.result, NT_STATUS_BUFFER_TOO_SMALL, "ReadEventLog failed"); /* Now read the actual record */ r.in.number_of_bytes = *r.out.real_size; r.out.data = talloc_size(tctx, r.in.number_of_bytes); status = dcerpc_eventlog_ReadEventLogW(p, tctx, &r); torture_assert_ntstatus_ok(tctx, status, "ReadEventLog failed"); /* Decode a user-marshalled record */ blob.length = *r.out.sent_size; blob.data = talloc_steal(tctx, r.out.data); ndr = ndr_pull_init_blob(&blob, tctx); status = ndr_pull_eventlog_Record( ndr, NDR_SCALARS|NDR_BUFFERS, &rec); NDR_PRINT_DEBUG(eventlog_Record, &rec); torture_assert_ntstatus_ok(tctx, status, "ReadEventLog failed parsing event log record"); r.in.offset++; } cr.in.handle = cr.out.handle = &handle; torture_assert_ntstatus_ok(tctx, dcerpc_eventlog_CloseEventLog(p, tctx, &cr), "CloseEventLog failed"); return true; }
static bool api_eventlog_GetLogInformation(struct pipes_struct *p) { const struct ndr_interface_call *call; struct ndr_pull *pull; struct ndr_push *push; enum ndr_err_code ndr_err; struct eventlog_GetLogInformation *r; call = &ndr_table_eventlog.calls[NDR_EVENTLOG_GETLOGINFORMATION]; r = talloc(talloc_tos(), struct eventlog_GetLogInformation); if (r == NULL) { return false; } pull = ndr_pull_init_blob(&p->in_data.data, r); if (pull == NULL) { talloc_free(r); return false; } pull->flags |= LIBNDR_FLAG_REF_ALLOC; if (p->endian) { pull->flags |= LIBNDR_FLAG_BIGENDIAN; } ndr_err = call->ndr_pull(pull, NDR_IN, r); if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { talloc_free(r); return false; } if (DEBUGLEVEL >= 10) { NDR_PRINT_FUNCTION_DEBUG(eventlog_GetLogInformation, NDR_IN, r); } ZERO_STRUCT(r->out); r->out.buffer = talloc_zero_array(r, uint8_t, r->in.buf_size); if (r->out.buffer == NULL) { talloc_free(r); return false; } r->out.bytes_needed = talloc_zero(r, uint32_t); if (r->out.bytes_needed == NULL) { talloc_free(r); return false; } r->out.result = _eventlog_GetLogInformation(p, r); if (p->rng_fault_state) { talloc_free(r); /* Return true here, srv_pipe_hnd.c will take care */ return true; } if (DEBUGLEVEL >= 10) { NDR_PRINT_FUNCTION_DEBUG(eventlog_GetLogInformation, NDR_OUT | NDR_SET_VALUES, r); } push = ndr_push_init_ctx(r); if (push == NULL) { talloc_free(r); return false; } /* * carry over the pointer count to the reply in case we are * using full pointer. See NDR specification for full pointers */ push->ptr_count = pull->ptr_count; ndr_err = call->ndr_push(push, NDR_OUT, r); if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { talloc_free(r); return false; } p->out_data.rdata = ndr_push_blob(push); talloc_steal(p->mem_ctx, p->out_data.rdata.data); talloc_free(r); return true; }
static bool api_frstrans_RequestUpdates(struct pipes_struct *p) { const struct ndr_interface_call *call; struct ndr_pull *pull; struct ndr_push *push; enum ndr_err_code ndr_err; struct frstrans_RequestUpdates *r; call = &ndr_table_frstrans.calls[NDR_FRSTRANS_REQUESTUPDATES]; r = talloc(talloc_tos(), struct frstrans_RequestUpdates); if (r == NULL) { return false; } pull = ndr_pull_init_blob(&p->in_data.data, r); if (pull == NULL) { talloc_free(r); return false; } pull->flags |= LIBNDR_FLAG_REF_ALLOC; if (p->endian) { pull->flags |= LIBNDR_FLAG_BIGENDIAN; } ndr_err = call->ndr_pull(pull, NDR_IN, r); if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { talloc_free(r); return false; } if (DEBUGLEVEL >= 10) { NDR_PRINT_FUNCTION_DEBUG(frstrans_RequestUpdates, NDR_IN, r); } ZERO_STRUCT(r->out); r->out.frs_update = talloc_zero_array(r, struct frstrans_Update, r->in.credits_available); if (r->out.frs_update == NULL) { talloc_free(r); return false; } r->out.update_count = talloc_zero(r, uint32_t); if (r->out.update_count == NULL) { talloc_free(r); return false; } r->out.update_status = talloc_zero(r, enum frstrans_UpdateStatus); if (r->out.update_status == NULL) { talloc_free(r); return false; } r->out.gvsn_db_guid = talloc_zero(r, struct GUID); if (r->out.gvsn_db_guid == NULL) { talloc_free(r); return false; } r->out.gvsn_version = talloc_zero(r, uint64_t); if (r->out.gvsn_version == NULL) { talloc_free(r); return false; } r->out.result = _frstrans_RequestUpdates(p, r); if (p->fault_state) { talloc_free(r); /* Return true here, srv_pipe_hnd.c will take care */ return true; } if (DEBUGLEVEL >= 10) { NDR_PRINT_FUNCTION_DEBUG(frstrans_RequestUpdates, NDR_OUT | NDR_SET_VALUES, r); } push = ndr_push_init_ctx(r); if (push == NULL) { talloc_free(r); return false; } /* * carry over the pointer count to the reply in case we are * using full pointer. See NDR specification for full pointers */ push->ptr_count = pull->ptr_count; ndr_err = call->ndr_push(push, NDR_OUT, r); if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { talloc_free(r); return false; } p->out_data.rdata = ndr_push_blob(push); talloc_steal(p->mem_ctx, p->out_data.rdata.data); talloc_free(r); return true; }
static bool api_EfsRpcOpenFileRaw(struct pipes_struct *p) { const struct ndr_interface_call *call; struct ndr_pull *pull; struct ndr_push *push; enum ndr_err_code ndr_err; struct EfsRpcOpenFileRaw *r; call = &ndr_table_efs.calls[NDR_EFSRPCOPENFILERAW]; r = talloc(talloc_tos(), struct EfsRpcOpenFileRaw); if (r == NULL) { return false; } pull = ndr_pull_init_blob(&p->in_data.data, r); if (pull == NULL) { talloc_free(r); return false; } pull->flags |= LIBNDR_FLAG_REF_ALLOC; if (p->endian) { pull->flags |= LIBNDR_FLAG_BIGENDIAN; } ndr_err = call->ndr_pull(pull, NDR_IN, r); if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { talloc_free(r); return false; } if (DEBUGLEVEL >= 10) { NDR_PRINT_FUNCTION_DEBUG(EfsRpcOpenFileRaw, NDR_IN, r); } ZERO_STRUCT(r->out); r->out.pvContext = talloc_zero(r, struct policy_handle); if (r->out.pvContext == NULL) { talloc_free(r); return false; } r->out.result = _EfsRpcOpenFileRaw(p, r); if (p->fault_state) { talloc_free(r); /* Return true here, srv_pipe_hnd.c will take care */ return true; } if (DEBUGLEVEL >= 10) { NDR_PRINT_FUNCTION_DEBUG(EfsRpcOpenFileRaw, NDR_OUT | NDR_SET_VALUES, r); } push = ndr_push_init_ctx(r); if (push == NULL) { talloc_free(r); return false; } /* * carry over the pointer count to the reply in case we are * using full pointer. See NDR specification for full pointers */ push->ptr_count = pull->ptr_count; ndr_err = call->ndr_push(push, NDR_OUT, r); if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { talloc_free(r); return false; } p->out_data.rdata = ndr_push_blob(push); talloc_steal(p->mem_ctx, p->out_data.rdata.data); talloc_free(r); return true; }
static bool api_RemoteActivation(struct pipes_struct *p) { const struct ndr_interface_call *call; struct ndr_pull *pull; struct ndr_push *push; enum ndr_err_code ndr_err; struct RemoteActivation *r; call = &ndr_table_IRemoteActivation.calls[NDR_REMOTEACTIVATION]; r = talloc(talloc_tos(), struct RemoteActivation); if (r == NULL) { return false; } pull = ndr_pull_init_blob(&p->in_data.data, r); if (pull == NULL) { talloc_free(r); return false; } pull->flags |= LIBNDR_FLAG_REF_ALLOC; if (p->endian) { pull->flags |= LIBNDR_FLAG_BIGENDIAN; } ndr_err = call->ndr_pull(pull, NDR_IN, r); if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { talloc_free(r); return false; } if (DEBUGLEVEL >= 10) { NDR_PRINT_FUNCTION_DEBUG(RemoteActivation, NDR_IN, r); } ZERO_STRUCT(r->out); r->out.that = talloc_zero(r, struct ORPCTHAT); if (r->out.that == NULL) { talloc_free(r); return false; } r->out.pOxid = talloc_zero(r, uint64_t); if (r->out.pOxid == NULL) { talloc_free(r); return false; } r->out.pdsaOxidBindings = talloc_zero(r, struct DUALSTRINGARRAY); if (r->out.pdsaOxidBindings == NULL) { talloc_free(r); return false; } r->out.ipidRemUnknown = talloc_zero(r, struct GUID); if (r->out.ipidRemUnknown == NULL) { talloc_free(r); return false; } r->out.AuthnHint = talloc_zero(r, uint32_t); if (r->out.AuthnHint == NULL) { talloc_free(r); return false; } r->out.ServerVersion = talloc_zero(r, struct COMVERSION); if (r->out.ServerVersion == NULL) { talloc_free(r); return false; } r->out.hr = talloc_zero(r, WERROR); if (r->out.hr == NULL) { talloc_free(r); return false; } r->out.ifaces = talloc_zero_array(r, struct MInterfacePointer *, r->in.Interfaces); if (r->out.ifaces == NULL) { talloc_free(r); return false; } r->out.results = talloc_zero_array(r, WERROR, r->in.Interfaces); if (r->out.results == NULL) { talloc_free(r); return false; } r->out.result = _RemoteActivation(p, r); if (p->fault_state) { talloc_free(r); /* Return true here, srv_pipe_hnd.c will take care */ return true; } if (DEBUGLEVEL >= 10) { NDR_PRINT_FUNCTION_DEBUG(RemoteActivation, NDR_OUT | NDR_SET_VALUES, r); } push = ndr_push_init_ctx(r); if (push == NULL) { talloc_free(r); return false; } /* * carry over the pointer count to the reply in case we are * using full pointer. See NDR specification for full pointers */ push->ptr_count = pull->ptr_count; ndr_err = call->ndr_push(push, NDR_OUT, r); if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { talloc_free(r); return false; } p->out_data.rdata = ndr_push_blob(push); talloc_steal(p->mem_ctx, p->out_data.rdata.data); talloc_free(r); return true; }
static struct mapistore_notification_list *mapistore_notification_process_mqueue_notif(TALLOC_CTX *mem_ctx, DATA_BLOB data) { struct mapistore_notification_list *nl; struct mapistore_mgmt_command command; struct ndr_pull *ndr_pull = NULL; ndr_pull = ndr_pull_init_blob(&data, mem_ctx); ndr_pull_mapistore_mgmt_command(ndr_pull, NDR_SCALARS|NDR_BUFFERS, &command); /* verbose */ { struct ndr_print *ndr_print; ndr_print = talloc_zero(mem_ctx, struct ndr_print); ndr_print->print = ndr_print_printf_helper; ndr_print->depth = 1; ndr_print_mapistore_mgmt_command(ndr_print, "command", &command); talloc_free(ndr_print); } if (command.type != MAPISTORE_MGMT_NOTIF) { DEBUG(0, ("[%s:%d]: Invalid command type received: 0x%x\n", __FUNCTION__, __LINE__, command.type)); return NULL; } if (command.command.notification.status != MAPISTORE_MGMT_SEND) { DEBUG(0, ("[%s:%d]: Invalid notification status: 0x%x\n", __FUNCTION__, __LINE__, command.command.notification.status)); return NULL; } nl = talloc_zero(mem_ctx, struct mapistore_notification_list); nl->notification = talloc_zero((TALLOC_CTX *)nl, struct mapistore_notification); /* On newmail notification received, trigger 3 notifications: 1. FolderModifiedNotification (0x3010) 2. MessageObjectCreated (0x8004) 3. FolderModification (0x10) */ switch (command.command.notification.NotificationFlags) { case 0x8004: nl->notification->object_type = MAPISTORE_MESSAGE; nl->notification->event = MAPISTORE_OBJECT_CREATED; nl->notification->parameters.object_parameters.folder_id = command.command.notification.FolderID; nl->notification->parameters.object_parameters.object_id = command.command.notification.MessageID; nl->notification->parameters.object_parameters.tag_count = 24; nl->notification->parameters.object_parameters.tags = talloc_array(nl->notification, enum MAPITAGS, nl->notification->parameters.object_parameters.tag_count); nl->notification->parameters.object_parameters.tags[0] = PR_RCVD_REPRESENTING_ENTRYID; nl->notification->parameters.object_parameters.tags[1] = PR_RCVD_REPRESENTING_ADDRTYPE; nl->notification->parameters.object_parameters.tags[2] = PR_RCVD_REPRESENTING_EMAIL_ADDRESS; nl->notification->parameters.object_parameters.tags[3] = PR_RCVD_REPRESENTING_NAME; nl->notification->parameters.object_parameters.tags[4] = PR_RCVD_REPRESENTING_SEARCH_KEY; nl->notification->parameters.object_parameters.tags[5] = PidTagReceivedRepresentingFlags; nl->notification->parameters.object_parameters.tags[6] = 0x67BA0102; nl->notification->parameters.object_parameters.tags[7] = PR_CONTENT_FILTER_SCL; nl->notification->parameters.object_parameters.tags[8] = PR_LAST_MODIFICATION_TIME; nl->notification->parameters.object_parameters.tags[9] = PR_LAST_MODIFIER_ENTRYID; nl->notification->parameters.object_parameters.tags[10] = PR_LAST_MODIFIER_NAME; nl->notification->parameters.object_parameters.tags[11] = PR_MODIFIER_FLAGS; nl->notification->parameters.object_parameters.tags[12] = 0x67BE0102; nl->notification->parameters.object_parameters.tags[13] = PR_LOCAL_COMMIT_TIME; nl->notification->parameters.object_parameters.tags[14] = PR_RECEIVED_BY_SEARCH_KEY; nl->notification->parameters.object_parameters.tags[15] = PR_RECEIVED_BY_ENTRYID; nl->notification->parameters.object_parameters.tags[16] = PR_RECEIVED_BY_ADDRTYPE; nl->notification->parameters.object_parameters.tags[17] = PR_RECEIVED_BY_EMAIL_ADDRESS; nl->notification->parameters.object_parameters.tags[18] = PR_RECEIVED_BY_NAME; nl->notification->parameters.object_parameters.tags[19] = PidTagReceivedByFlags; nl->notification->parameters.object_parameters.tags[20] = 0x67B90102; nl->notification->parameters.object_parameters.tags[21] = PR_MESSAGE_FLAGS; nl->notification->parameters.object_parameters.tags[22] = PR_MESSAGE_SIZE; nl->notification->parameters.object_parameters.tags[23] = PR_INTERNET_ARTICLE_NUMBER; break; case 0x3010: nl->notification->object_type = MAPISTORE_FOLDER; nl->notification->event = MAPISTORE_OBJECT_MODIFIED; nl->notification->parameters.object_parameters.folder_id = command.command.notification.FolderID; nl->notification->parameters.object_parameters.tag_count = 0x5; nl->notification->parameters.object_parameters.tags = talloc_array(nl->notification, enum MAPITAGS, nl->notification->parameters.object_parameters.tag_count); nl->notification->parameters.object_parameters.tags[0] = PR_CONTENT_COUNT; nl->notification->parameters.object_parameters.tags[1] = PR_CONTENT_UNREAD; nl->notification->parameters.object_parameters.tags[2] = PR_MESSAGE_SIZE; nl->notification->parameters.object_parameters.tags[3] = PR_RECIPIENT_ON_NORMAL_MSG_COUNT; nl->notification->parameters.object_parameters.tags[4] = PR_NORMAL_MESSAGE_SIZE; nl->notification->parameters.object_parameters.message_count = command.command.notification.TotalNumberOfMessages; break; default: DEBUG(3, ("Unsupported Notification Type: 0x%x\n", command.command.notification.NotificationFlags)); break; /* TODO: Finir de faire les notifications FIX dcesrv_exchange_emsmdb.c: fill_notification Faire le test allelouia */ } /* HACK: we only support NewMail notifications for now */ return nl; }
static bool api_BrowserrQueryOtherDomains(struct pipes_struct *p) { const struct ndr_interface_call *call; struct ndr_pull *pull; struct ndr_push *push; enum ndr_err_code ndr_err; struct BrowserrQueryOtherDomains *r; call = &ndr_table_browser.calls[NDR_BROWSERRQUERYOTHERDOMAINS]; r = talloc(talloc_tos(), struct BrowserrQueryOtherDomains); if (r == NULL) { return false; } pull = ndr_pull_init_blob(&p->in_data.data, r); if (pull == NULL) { talloc_free(r); return false; } pull->flags |= LIBNDR_FLAG_REF_ALLOC; if (p->endian) { pull->flags |= LIBNDR_FLAG_BIGENDIAN; } ndr_err = call->ndr_pull(pull, NDR_IN, r); if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { talloc_free(r); return false; } if (DEBUGLEVEL >= 10) { NDR_PRINT_FUNCTION_DEBUG(BrowserrQueryOtherDomains, NDR_IN, r); } ZERO_STRUCT(r->out); r->out.info = r->in.info; r->out.total_entries = talloc_zero(r, uint32_t); if (r->out.total_entries == NULL) { talloc_free(r); return false; } r->out.result = _BrowserrQueryOtherDomains(p, r); if (p->fault_state) { talloc_free(r); /* Return true here, srv_pipe_hnd.c will take care */ return true; } if (DEBUGLEVEL >= 10) { NDR_PRINT_FUNCTION_DEBUG(BrowserrQueryOtherDomains, NDR_OUT | NDR_SET_VALUES, r); } push = ndr_push_init_ctx(r); if (push == NULL) { talloc_free(r); return false; } /* * carry over the pointer count to the reply in case we are * using full pointer. See NDR specification for full pointers */ push->ptr_count = pull->ptr_count; ndr_err = call->ndr_push(push, NDR_OUT, r); if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { talloc_free(r); return false; } p->out_data.rdata = ndr_push_blob(push); talloc_steal(p->mem_ctx, p->out_data.rdata.data); talloc_free(r); return true; }
NTSTATUS cli_do_rpc_ndr(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx, const struct ndr_interface_table *table, uint32 opnum, void *r) { #ifdef AVM_SMALL return NT_STATUS_NO_MEMORY; #else prs_struct q_ps, r_ps; const struct ndr_interface_call *call; struct ndr_pull *pull; DATA_BLOB blob; struct ndr_push *push; NTSTATUS status; enum ndr_err_code ndr_err; SMB_ASSERT(ndr_syntax_id_equal(&table->syntax_id, &cli->abstract_syntax)); SMB_ASSERT(table->num_calls > opnum); call = &table->calls[opnum]; push = ndr_push_init_ctx(mem_ctx); if (!push) { return NT_STATUS_NO_MEMORY; } ndr_err = call->ndr_push(push, NDR_IN, r); if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { return ndr_map_error2ntstatus(ndr_err); } blob = ndr_push_blob(push); if (!prs_init_data_blob(&q_ps, &blob, mem_ctx)) { return NT_STATUS_NO_MEMORY; } talloc_free(push); prs_init_empty( &r_ps, mem_ctx, UNMARSHALL ); status = rpc_api_pipe_req(cli, opnum, &q_ps, &r_ps); prs_mem_free( &q_ps ); if (!NT_STATUS_IS_OK(status)) { prs_mem_free( &r_ps ); return status; } if (!prs_data_blob(&r_ps, &blob, mem_ctx)) { prs_mem_free( &r_ps ); return NT_STATUS_NO_MEMORY; } prs_mem_free( &r_ps ); pull = ndr_pull_init_blob(&blob, mem_ctx); if (pull == NULL) { return NT_STATUS_NO_MEMORY; } /* have the ndr parser alloc memory for us */ pull->flags |= LIBNDR_FLAG_REF_ALLOC; ndr_err = call->ndr_pull(pull, NDR_OUT, r); talloc_free(pull); if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { return ndr_map_error2ntstatus(ndr_err); } return NT_STATUS_OK; #endif }
/** * @brief Pull a dcerpc_auth structure, taking account of any auth * padding in the blob. For request/response packets we pass * the whole data blob, so auth_data_only must be set to false * as the blob contains data+pad+auth and no just pad+auth. * * @param pkt - The ncacn_packet strcuture * @param mem_ctx - The mem_ctx used to allocate dcerpc_auth elements * @param pkt_trailer - The packet trailer data, usually the trailing * auth_info blob, but in the request/response case * this is the stub_and_verifier blob. * @param auth - A preallocated dcerpc_auth *empty* structure * @param auth_length - The length of the auth trail, sum of auth header * lenght and pkt->auth_length * @param auth_data_only - Whether the pkt_trailer includes only the auth_blob * (+ padding) or also other data. * * @return - A NTSTATUS error code. */ NTSTATUS dcerpc_pull_auth_trailer(struct ncacn_packet *pkt, TALLOC_CTX *mem_ctx, DATA_BLOB *pkt_trailer, struct dcerpc_auth *auth, uint32_t *auth_length, bool auth_data_only) { struct ndr_pull *ndr; enum ndr_err_code ndr_err; uint32_t data_and_pad; data_and_pad = pkt_trailer->length - (DCERPC_AUTH_TRAILER_LENGTH + pkt->auth_length); /* paranoia check for pad size. This would be caught anyway by the ndr_pull_advance() a few lines down, but it scared Jeremy enough for him to call me, so we might as well check it now, just to prevent someone posting a bogus YouTube video in the future. */ if (data_and_pad > pkt_trailer->length) { return NT_STATUS_INFO_LENGTH_MISMATCH; } *auth_length = pkt_trailer->length - data_and_pad; ndr = ndr_pull_init_blob(pkt_trailer, mem_ctx); if (!ndr) { return NT_STATUS_NO_MEMORY; } if (!(pkt->drep[0] & DCERPC_DREP_LE)) { ndr->flags |= LIBNDR_FLAG_BIGENDIAN; } ndr_err = ndr_pull_advance(ndr, data_and_pad); if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { talloc_free(ndr); return ndr_map_error2ntstatus(ndr_err); } ndr_err = ndr_pull_dcerpc_auth(ndr, NDR_SCALARS|NDR_BUFFERS, auth); if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { talloc_free(ndr); return ndr_map_error2ntstatus(ndr_err); } if (auth_data_only && data_and_pad != auth->auth_pad_length) { DEBUG(1, (__location__ ": WARNING: pad length mismatch. " "Calculated %u got %u\n", (unsigned)data_and_pad, (unsigned)auth->auth_pad_length)); } DEBUG(6,(__location__ ": auth_pad_length %u\n", (unsigned)auth->auth_pad_length)); talloc_steal(mem_ctx, auth->credentials.data); talloc_free(ndr); return NT_STATUS_OK; }
static bool api_eventlog_ReportEventW(struct pipes_struct *p) { const struct ndr_interface_call *call; struct ndr_pull *pull; struct ndr_push *push; enum ndr_err_code ndr_err; struct eventlog_ReportEventW *r; call = &ndr_table_eventlog.calls[NDR_EVENTLOG_REPORTEVENTW]; r = talloc(talloc_tos(), struct eventlog_ReportEventW); if (r == NULL) { return false; } pull = ndr_pull_init_blob(&p->in_data.data, r); if (pull == NULL) { talloc_free(r); return false; } pull->flags |= LIBNDR_FLAG_REF_ALLOC; if (p->endian) { pull->flags |= LIBNDR_FLAG_BIGENDIAN; } ndr_err = call->ndr_pull(pull, NDR_IN, r); if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { talloc_free(r); return false; } if (DEBUGLEVEL >= 10) { NDR_PRINT_FUNCTION_DEBUG(eventlog_ReportEventW, NDR_IN, r); } ZERO_STRUCT(r->out); r->out.record_number = r->in.record_number; r->out.time_written = r->in.time_written; r->out.result = _eventlog_ReportEventW(p, r); if (p->rng_fault_state) { talloc_free(r); /* Return true here, srv_pipe_hnd.c will take care */ return true; } if (DEBUGLEVEL >= 10) { NDR_PRINT_FUNCTION_DEBUG(eventlog_ReportEventW, NDR_OUT | NDR_SET_VALUES, r); } push = ndr_push_init_ctx(r); if (push == NULL) { talloc_free(r); return false; } /* * carry over the pointer count to the reply in case we are * using full pointer. See NDR specification for full pointers */ push->ptr_count = pull->ptr_count; ndr_err = call->ndr_push(push, NDR_OUT, r); if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { talloc_free(r); return false; } p->out_data.rdata = ndr_push_blob(push); talloc_steal(p->mem_ctx, p->out_data.rdata.data); talloc_free(r); return true; }
static bool api_frstrans_InitializeFileTransferAsync(struct pipes_struct *p) { const struct ndr_interface_call *call; struct ndr_pull *pull; struct ndr_push *push; enum ndr_err_code ndr_err; struct frstrans_InitializeFileTransferAsync *r; call = &ndr_table_frstrans.calls[NDR_FRSTRANS_INITIALIZEFILETRANSFERASYNC]; r = talloc(talloc_tos(), struct frstrans_InitializeFileTransferAsync); if (r == NULL) { return false; } pull = ndr_pull_init_blob(&p->in_data.data, r); if (pull == NULL) { talloc_free(r); return false; } pull->flags |= LIBNDR_FLAG_REF_ALLOC; if (p->endian) { pull->flags |= LIBNDR_FLAG_BIGENDIAN; } ndr_err = call->ndr_pull(pull, NDR_IN, r); if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { talloc_free(r); return false; } if (DEBUGLEVEL >= 10) { NDR_PRINT_FUNCTION_DEBUG(frstrans_InitializeFileTransferAsync, NDR_IN, r); } ZERO_STRUCT(r->out); r->out.frs_update = r->in.frs_update; r->out.staging_policy = r->in.staging_policy; r->out.server_context = talloc_zero(r, struct policy_handle); if (r->out.server_context == NULL) { talloc_free(r); return false; } r->out.rdc_file_info = talloc_zero(r, struct frstrans_RdcFileInfo *); if (r->out.rdc_file_info == NULL) { talloc_free(r); return false; } r->out.data_buffer = talloc_zero_array(r, uint8_t, r->in.buffer_size); if (r->out.data_buffer == NULL) { talloc_free(r); return false; } r->out.size_read = talloc_zero(r, uint32_t); if (r->out.size_read == NULL) { talloc_free(r); return false; } r->out.is_end_of_file = talloc_zero(r, uint32_t); if (r->out.is_end_of_file == NULL) { talloc_free(r); return false; } r->out.result = _frstrans_InitializeFileTransferAsync(p, r); if (p->fault_state) { talloc_free(r); /* Return true here, srv_pipe_hnd.c will take care */ return true; } if (DEBUGLEVEL >= 10) { NDR_PRINT_FUNCTION_DEBUG(frstrans_InitializeFileTransferAsync, NDR_OUT | NDR_SET_VALUES, r); } push = ndr_push_init_ctx(r); if (push == NULL) { talloc_free(r); return false; } /* * carry over the pointer count to the reply in case we are * using full pointer. See NDR specification for full pointers */ push->ptr_count = pull->ptr_count; ndr_err = call->ndr_push(push, NDR_OUT, r); if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { talloc_free(r); return false; } p->out_data.rdata = ndr_push_blob(push); talloc_steal(p->mem_ctx, p->out_data.rdata.data); talloc_free(r); return true; }
static NTSTATUS rpc_service_list_internal(struct net_context *c, const DOM_SID *domain_sid, const char *domain_name, struct cli_state *cli, struct rpc_pipe_client *pipe_hnd, TALLOC_CTX *mem_ctx, int argc, const char **argv ) { struct policy_handle hSCM; struct ENUM_SERVICE_STATUSW *services = NULL; WERROR result = WERR_GENERAL_FAILURE; NTSTATUS status; int i; uint8_t *buffer = NULL; uint32_t buf_size = 0; uint32_t bytes_needed = 0; uint32_t num_services = 0; uint32_t resume_handle = 0; if (argc != 0 ) { d_printf("%s net rpc service list\n", _("Usage:")); return NT_STATUS_OK; } status = rpccli_svcctl_OpenSCManagerW(pipe_hnd, mem_ctx, pipe_hnd->srv_name_slash, NULL, SC_RIGHT_MGR_ENUMERATE_SERVICE, &hSCM, &result); if (!NT_STATUS_IS_OK(status) || !W_ERROR_IS_OK(result)) { d_fprintf(stderr, _("Failed to open Service Control Manager. [%s]\n"), win_errstr(result)); return werror_to_ntstatus(result); } do { status = rpccli_svcctl_EnumServicesStatusW(pipe_hnd, mem_ctx, &hSCM, SERVICE_TYPE_WIN32, SERVICE_STATE_ALL, buffer, buf_size, &bytes_needed, &num_services, &resume_handle, &result); if (NT_STATUS_IS_ERR(status)) { d_fprintf(stderr, _("Failed to enumerate services. [%s]\n"), win_errstr(result)); break; } if (W_ERROR_EQUAL(result, WERR_MORE_DATA) && bytes_needed > 0) { buffer = talloc_array(mem_ctx, uint8_t, bytes_needed); buf_size = bytes_needed; continue; } if ( num_services == 0 ) { d_printf(_("No services returned\n")); break; } { enum ndr_err_code ndr_err; DATA_BLOB blob; struct ndr_pull *ndr; blob.length = buf_size; blob.data = talloc_steal(mem_ctx, buffer); services = talloc_array(mem_ctx, struct ENUM_SERVICE_STATUSW, num_services); if (!services) { status = NT_STATUS_NO_MEMORY; break; } ndr = ndr_pull_init_blob(&blob, mem_ctx, NULL); if (ndr == NULL) { status = NT_STATUS_NO_MEMORY; break; } ndr_err = ndr_pull_ENUM_SERVICE_STATUSW_array( ndr, num_services, services); if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { status = ndr_map_error2ntstatus(ndr_err); break; } for ( i=0; i<num_services; i++ ) { d_printf("%-20s \"%s\"\n", services[i].service_name, services[i].display_name); } } } while (W_ERROR_EQUAL(result, WERR_MORE_DATA)); rpccli_svcctl_CloseServiceHandle(pipe_hnd, mem_ctx, &hSCM, NULL); return status; }
static bool api_FRSTRANS_RAW_GET_FILE_DATA(struct pipes_struct *p) { const struct ndr_interface_call *call; struct ndr_pull *pull; struct ndr_push *push; enum ndr_err_code ndr_err; struct FRSTRANS_RAW_GET_FILE_DATA *r; call = &ndr_table_frstrans.calls[NDR_FRSTRANS_RAW_GET_FILE_DATA]; r = talloc(talloc_tos(), struct FRSTRANS_RAW_GET_FILE_DATA); if (r == NULL) { return false; } pull = ndr_pull_init_blob(&p->in_data.data, r); if (pull == NULL) { talloc_free(r); return false; } pull->flags |= LIBNDR_FLAG_REF_ALLOC; if (p->endian) { pull->flags |= LIBNDR_FLAG_BIGENDIAN; } ndr_err = call->ndr_pull(pull, NDR_IN, r); if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { talloc_free(r); return false; } if (DEBUGLEVEL >= 10) { NDR_PRINT_FUNCTION_DEBUG(FRSTRANS_RAW_GET_FILE_DATA, NDR_IN, r); } _FRSTRANS_RAW_GET_FILE_DATA(p, r); if (p->fault_state) { talloc_free(r); /* Return true here, srv_pipe_hnd.c will take care */ return true; } if (DEBUGLEVEL >= 10) { NDR_PRINT_FUNCTION_DEBUG(FRSTRANS_RAW_GET_FILE_DATA, NDR_OUT | NDR_SET_VALUES, r); } push = ndr_push_init_ctx(r); if (push == NULL) { talloc_free(r); return false; } /* * carry over the pointer count to the reply in case we are * using full pointer. See NDR specification for full pointers */ push->ptr_count = pull->ptr_count; ndr_err = call->ndr_push(push, NDR_OUT, r); if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { talloc_free(r); return false; } p->out_data.rdata = ndr_push_blob(push); talloc_steal(p->mem_ctx, p->out_data.rdata.data); talloc_free(r); return true; }
NTSTATUS cli_do_rpc_ndr(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx, int p_idx, int opnum, void *data, ndr_pull_flags_fn_t pull_fn, ndr_push_flags_fn_t push_fn) { prs_struct q_ps, r_ps; struct ndr_pull *pull; DATA_BLOB blob; struct ndr_push *push; NTSTATUS status; SMB_ASSERT(cli->pipe_idx == p_idx); push = ndr_push_init_ctx(mem_ctx); if (!push) { return NT_STATUS_NO_MEMORY; } status = push_fn(push, NDR_IN, data); if (!NT_STATUS_IS_OK(status)) { return status; } blob = ndr_push_blob(push); if (!prs_init_data_blob(&q_ps, &blob, mem_ctx)) { return NT_STATUS_NO_MEMORY; } talloc_free(push); if (!prs_init( &r_ps, 0, mem_ctx, UNMARSHALL )) { prs_mem_free( &q_ps ); return NT_STATUS_NO_MEMORY; } status = rpc_api_pipe_req(cli, opnum, &q_ps, &r_ps); prs_mem_free( &q_ps ); if (!NT_STATUS_IS_OK(status)) { prs_mem_free( &r_ps ); return status; } if (!prs_data_blob(&r_ps, &blob, mem_ctx)) { prs_mem_free( &r_ps ); return NT_STATUS_NO_MEMORY; } prs_mem_free( &r_ps ); pull = ndr_pull_init_blob(&blob, mem_ctx); if (pull == NULL) { return NT_STATUS_NO_MEMORY; } /* have the ndr parser alloc memory for us */ pull->flags |= LIBNDR_FLAG_REF_ALLOC; status = pull_fn(pull, NDR_OUT, data); talloc_free(pull); if (!NT_STATUS_IS_OK(status)) { return status; } return NT_STATUS_OK; }