예제 #1
0
_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;
}
예제 #2
0
파일: srv_frsrpc.c 프로젝트: ebrainte/Samba
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;
}
예제 #3
0
파일: srv_fsrvp.c 프로젝트: ebrainte/Samba
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;
}
예제 #4
0
파일: srv_fsrvp.c 프로젝트: ebrainte/Samba
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;
}
예제 #5
0
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;
}
예제 #6
0
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;
}
예제 #7
0
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;
}
예제 #8
0
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;
}
예제 #9
0
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;
}
예제 #10
0
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;
}
예제 #12
0
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;
}
예제 #13
0
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
}
예제 #14
0
/**
* @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;
}
예제 #15
0
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;
}
예제 #16
0
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;
}
예제 #17
0
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;
}
예제 #18
0
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;
}
예제 #19
0
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;
}