Exemplo n.º 1
0
WERROR rpccli_spoolss_enumjobs(struct rpc_pipe_client *cli,
			       TALLOC_CTX *mem_ctx,
			       struct policy_handle *handle,
			       uint32_t firstjob,
			       uint32_t numjobs,
			       uint32_t level,
			       uint32_t offered,
			       uint32_t *count,
			       union spoolss_JobInfo **info)
{
	NTSTATUS status;
	WERROR werror;
	uint32_t needed;
	DATA_BLOB buffer;
	struct dcerpc_binding_handle *b = cli->binding_handle;

	if (offered > 0) {
		buffer = data_blob_talloc_zero(mem_ctx, offered);
		W_ERROR_HAVE_NO_MEMORY(buffer.data);
	}

	status = dcerpc_spoolss_EnumJobs(b, mem_ctx,
					 handle,
					 firstjob,
					 numjobs,
					 level,
					 (offered > 0) ? &buffer : NULL,
					 offered,
					 count,
					 info,
					 &needed,
					 &werror);
	if (!NT_STATUS_IS_OK(status)) {
		return ntstatus_to_werror(status);
	}

	if (W_ERROR_EQUAL(werror, WERR_INSUFFICIENT_BUFFER)) {
		offered = needed;
		buffer = data_blob_talloc_zero(mem_ctx, needed);
		W_ERROR_HAVE_NO_MEMORY(buffer.data);

		status = dcerpc_spoolss_EnumJobs(b, mem_ctx,
						 handle,
						 firstjob,
						 numjobs,
						 level,
						 (offered > 0) ? &buffer : NULL,
						 offered,
						 count,
						 info,
						 &needed,
						 &werror);
	}
	if (!NT_STATUS_IS_OK(status)) {
		return ntstatus_to_werror(status);
	}

	return werror;
}
Exemplo n.º 2
0
WERROR rpccli_spoolss_getprinterdriver2(struct rpc_pipe_client *cli,
					TALLOC_CTX *mem_ctx,
					struct policy_handle *handle,
					const char *architecture,
					uint32_t level,
					uint32_t offered,
					uint32_t client_major_version,
					uint32_t client_minor_version,
					union spoolss_DriverInfo *info,
					uint32_t *server_major_version,
					uint32_t *server_minor_version)
{
	NTSTATUS status;
	WERROR werror;
	uint32_t needed;
	DATA_BLOB buffer;

	if (offered > 0) {
		buffer = data_blob_talloc_zero(mem_ctx, offered);
		W_ERROR_HAVE_NO_MEMORY(buffer.data);
	}

	status = rpccli_spoolss_GetPrinterDriver2(cli, mem_ctx,
						  handle,
						  architecture,
						  level,
						  (offered > 0) ? &buffer : NULL,
						  offered,
						  client_major_version,
						  client_minor_version,
						  info,
						  &needed,
						  server_major_version,
						  server_minor_version,
						  &werror);
	if (W_ERROR_EQUAL(werror, WERR_INSUFFICIENT_BUFFER)) {
		offered = needed;
		buffer = data_blob_talloc_zero(mem_ctx, needed);
		W_ERROR_HAVE_NO_MEMORY(buffer.data);

		status = rpccli_spoolss_GetPrinterDriver2(cli, mem_ctx,
							  handle,
							  architecture,
							  level,
							  &buffer,
							  offered,
							  client_major_version,
							  client_minor_version,
							  info,
							  &needed,
							  server_major_version,
							  server_minor_version,
							  &werror);
	}

	return werror;
}
Exemplo n.º 3
0
WERROR rpccli_spoolss_enumprinterdrivers(struct rpc_pipe_client *cli,
					 TALLOC_CTX *mem_ctx,
					 const char *server,
					 const char *environment,
					 uint32_t level,
					 uint32_t offered,
					 uint32_t *count,
					 union spoolss_DriverInfo **info)
{
	NTSTATUS status;
	WERROR werror;
	uint32_t needed;
	DATA_BLOB buffer;
	struct dcerpc_binding_handle *b = cli->binding_handle;

	if (offered > 0) {
		buffer = data_blob_talloc_zero(mem_ctx, offered);
		W_ERROR_HAVE_NO_MEMORY(buffer.data);
	}

	status = dcerpc_spoolss_EnumPrinterDrivers(b, mem_ctx,
						   server,
						   environment,
						   level,
						   (offered > 0) ? &buffer : NULL,
						   offered,
						   count,
						   info,
						   &needed,
						   &werror);
	if (!NT_STATUS_IS_OK(status)) {
		return ntstatus_to_werror(status);
	}

	if (W_ERROR_EQUAL(werror, WERR_INSUFFICIENT_BUFFER)) {
		offered = needed;
		buffer = data_blob_talloc_zero(mem_ctx, needed);
		W_ERROR_HAVE_NO_MEMORY(buffer.data);

		status = dcerpc_spoolss_EnumPrinterDrivers(b, mem_ctx,
						   server,
						   environment,
						   level,
						   (offered > 0) ? &buffer : NULL,
						   offered,
						   count,
						   info,
						   &needed,
						   &werror);
	}
	if (!NT_STATUS_IS_OK(status)) {
		return ntstatus_to_werror(status);
	}

	return werror;
}
Exemplo n.º 4
0
WERROR rpccli_spoolss_enumprinters(struct rpc_pipe_client *cli,
				   TALLOC_CTX *mem_ctx,
				   uint32_t flags,
				   const char *server,
				   uint32_t level,
				   uint32_t offered,
				   uint32_t *count,
				   union spoolss_PrinterInfo **info)
{
	NTSTATUS status;
	WERROR werror;
	uint32_t needed;
	DATA_BLOB buffer;

	if (offered > 0) {
		buffer = data_blob_talloc_zero(mem_ctx, offered);
		W_ERROR_HAVE_NO_MEMORY(buffer.data);
	}

	status = rpccli_spoolss_EnumPrinters(cli, mem_ctx,
					     flags,
					     server,
					     level,
					     (offered > 0) ? &buffer : NULL,
					     offered,
					     count,
					     info,
					     &needed,
					     &werror);

	if (W_ERROR_EQUAL(werror, WERR_INSUFFICIENT_BUFFER)) {
		offered = needed;
		buffer = data_blob_talloc_zero(mem_ctx, needed);
		W_ERROR_HAVE_NO_MEMORY(buffer.data);

		status = rpccli_spoolss_EnumPrinters(cli, mem_ctx,
						     flags,
						     server,
						     level,
						     (offered > 0) ? &buffer : NULL,
						     offered,
						     count,
						     info,
						     &needed,
						     &werror);
	}

	return werror;
}
Exemplo n.º 5
0
NTSTATUS dcerpc_winreg_set_dword(TALLOC_CTX *mem_ctx,
				 struct dcerpc_binding_handle *h,
				 struct policy_handle *key_handle,
				 const char *value,
				 uint32_t data,
				 WERROR *pwerr)
{
	struct winreg_String wvalue;
	DATA_BLOB blob;
	WERROR result = WERR_OK;
	NTSTATUS status;

	ZERO_STRUCT(wvalue);
	wvalue.name = value;
	blob = data_blob_talloc_zero(mem_ctx, 4);
	SIVAL(blob.data, 0, data);

	status = dcerpc_winreg_SetValue(h,
					mem_ctx,
					key_handle,
					wvalue,
					REG_DWORD,
					blob.data,
					blob.length,
					&result);
	if (!NT_STATUS_IS_OK(status)) {
		return status;
	}
	if (!W_ERROR_IS_OK(result)) {
		*pwerr = result;
	}

	return status;
}
Exemplo n.º 6
0
static bool test_GetPrinterDriver2(struct torture_context *tctx,
					struct dcerpc_binding_handle *b,
					struct test_spoolss_win_context *ctx,
					struct policy_handle *handle)
{
	NTSTATUS status;
	struct spoolss_GetPrinterDriver2 gpd2;
	DATA_BLOB blob = data_blob_talloc_zero(tctx, 87424);
	uint32_t needed;
	uint32_t server_major_version;
	uint32_t server_minor_version;

	torture_comment(tctx, "Testing GetPrinterDriver2\n");

	gpd2.in.handle = handle;
	gpd2.in.architecture = "Windows NT x86";
	gpd2.in.level = 101;
	gpd2.in.buffer = &blob;
	gpd2.in.offered = 87424;
	gpd2.in.client_major_version = 3;
	gpd2.in.client_minor_version = 0;
	gpd2.out.needed = &needed;
	gpd2.out.server_major_version = &server_major_version;
	gpd2.out.server_minor_version = &server_minor_version;

	status = dcerpc_spoolss_GetPrinterDriver2_r(b, tctx, &gpd2);
	torture_assert_ntstatus_ok(tctx, status, "GetPrinterDriver2 failed");

	if (ctx->printer_has_driver) {
		torture_assert_werr_ok(tctx, gpd2.out.result,
				"GetPrinterDriver2 failed.");
	}

	return true;
}
Exemplo n.º 7
0
WERROR rpccli_spoolss_getjob(struct rpc_pipe_client *cli,
			     TALLOC_CTX *mem_ctx,
			     struct policy_handle *handle,
			     uint32_t job_id,
			     uint32_t level,
			     uint32_t offered,
			     union spoolss_JobInfo *info)
{
	NTSTATUS status;
	WERROR werror;
	uint32_t needed;
	DATA_BLOB buffer;

	if (offered > 0) {
		buffer = data_blob_talloc_zero(mem_ctx, offered);
		W_ERROR_HAVE_NO_MEMORY(buffer.data);
	}

	status = rpccli_spoolss_GetJob(cli, mem_ctx,
				       handle,
				       job_id,
				       level,
				       (offered > 0) ? &buffer : NULL,
				       offered,
				       info,
				       &needed,
				       &werror);

	if (W_ERROR_EQUAL(werror, WERR_INSUFFICIENT_BUFFER)) {
		offered = needed;
		buffer = data_blob_talloc_zero(mem_ctx, needed);
		W_ERROR_HAVE_NO_MEMORY(buffer.data);

		status = rpccli_spoolss_GetJob(cli, mem_ctx,
					       handle,
					       job_id,
					       level,
					       &buffer,
					       offered,
					       info,
					       &needed,
					       &werror);
	}

	return werror;
}
Exemplo n.º 8
0
/*
  set password via encrypted NT and LM hash buffers
*/
NTSTATUS samr_set_password_buffers(struct dcesrv_call_state *dce_call,
				   struct ldb_context *sam_ctx,
				   struct ldb_dn *account_dn,
				   struct ldb_dn *domain_dn,
				   TALLOC_CTX *mem_ctx,
				   const uint8_t *lm_pwd_hash,
				   const uint8_t *nt_pwd_hash)
{
	struct samr_Password *d_lm_pwd_hash = NULL, *d_nt_pwd_hash = NULL;
	DATA_BLOB session_key = data_blob(NULL, 0);
	DATA_BLOB in, out;
	NTSTATUS nt_status = NT_STATUS_OK;

	nt_status = dcesrv_fetch_session_key(dce_call->conn, &session_key);
	if (!NT_STATUS_IS_OK(nt_status)) {
		return nt_status;
	}

	if (lm_pwd_hash != NULL) {
		in = data_blob_const(lm_pwd_hash, 16);
		out = data_blob_talloc_zero(mem_ctx, 16);

		sess_crypt_blob(&out, &in, &session_key, false);

		d_lm_pwd_hash = (struct samr_Password *) out.data;
	}
	if (nt_pwd_hash != NULL) {
		in = data_blob_const(nt_pwd_hash, 16);
		out = data_blob_talloc_zero(mem_ctx, 16);

		sess_crypt_blob(&out, &in, &session_key, false);

		d_nt_pwd_hash = (struct samr_Password *) out.data;
	}

	if ((d_lm_pwd_hash != NULL) || (d_nt_pwd_hash != NULL)) {
		nt_status = samdb_set_password(sam_ctx, mem_ctx, account_dn,
					       domain_dn, NULL,
					       d_lm_pwd_hash, d_nt_pwd_hash,
					       NULL, NULL, /* this is a password set */
					       NULL, NULL);
	}

	return nt_status;
}
Exemplo n.º 9
0
static bool test_zero(struct torture_context *tctx)
{
	int i;
	DATA_BLOB z = data_blob_talloc_zero(tctx, 4);
	torture_assert_int_equal(tctx, z.length, 4, "length");
	for (i = 0; i < z.length; i++)
		torture_assert_int_equal(tctx, z.data[i], 0, "contents");
	data_blob_free(&z);
	return true;
}
Exemplo n.º 10
0
static bool test_EnumPrinters_findone(struct torture_context *tctx,
                                      struct dcerpc_pipe *p,
                                      const char **printername)
{
    struct spoolss_EnumPrinters r;
    uint32_t count;
    union spoolss_PrinterInfo *info;
    uint32_t needed;
    int i;
    struct dcerpc_binding_handle *b = p->binding_handle;

    *printername = NULL;

    r.in.flags = PRINTER_ENUM_LOCAL;
    r.in.server = NULL;
    r.in.level = 1;
    r.in.buffer = NULL;
    r.in.offered = 0;
    r.out.count = &count;
    r.out.info = &info;
    r.out.needed = &needed;

    torture_assert_ntstatus_ok(tctx,
                               dcerpc_spoolss_EnumPrinters_r(b, tctx, &r),
                               "failed to enum printers");

    if (W_ERROR_EQUAL(r.out.result, WERR_INSUFFICIENT_BUFFER)) {
        DATA_BLOB blob = data_blob_talloc_zero(tctx, needed);
        r.in.buffer = &blob;
        r.in.offered = needed;

        torture_assert_ntstatus_ok(tctx,
                                   dcerpc_spoolss_EnumPrinters_r(b, tctx, &r),
                                   "failed to enum printers");
    }

    torture_assert_werr_ok(tctx, r.out.result,
                           "failed to enum printers");

    for (i=0; i < count; i++) {

        if (count > 1 && strequal(info[i].info1.name, "Microsoft XPS Document Writer")) {
            continue;
        }

        torture_comment(tctx, "testing printer: %s\n",
                        info[i].info1.name);

        *printername = talloc_strdup(tctx, info[i].info1.name);

        break;
    }

    return true;
}
Exemplo n.º 11
0
static bool test_GetPrinter(struct torture_context *tctx,
				struct dcerpc_binding_handle *b,
				struct policy_handle *handle,
				struct test_spoolss_win_context *ctx,
				uint32_t level,
				uint32_t initial_blob_size)
{
	NTSTATUS status;
	struct spoolss_GetPrinter gp;
	DATA_BLOB blob = data_blob_talloc_zero(ctx, initial_blob_size);
	uint32_t needed;

	torture_comment(tctx, "Test GetPrinter level %d\n", level);

	gp.in.handle = handle;
	gp.in.level = level;
	gp.in.buffer = (initial_blob_size == 0)?NULL:&blob;
	gp.in.offered = initial_blob_size;
	gp.out.needed = &needed;

	status = dcerpc_spoolss_GetPrinter_r(b, tctx, &gp);
	torture_assert_ntstatus_ok(tctx, status, "GetPrinter failed");

	if (W_ERROR_EQUAL(gp.out.result, WERR_INSUFFICIENT_BUFFER)) {
		blob = data_blob_talloc_zero(ctx, needed);
		gp.in.buffer = &blob;
		gp.in.offered = needed;
		status = dcerpc_spoolss_GetPrinter_r(b, tctx, &gp);
		torture_assert_ntstatus_ok(tctx, status, "GetPrinter failed");
	}

	torture_assert_werr_ok(tctx, gp.out.result, "GetPrinter failed");

	ctx->current_info = gp.out.info;

	if (level == 2 && gp.out.info) {
		ctx->printer_has_driver = gp.out.info->info2.drivername &&
					  strlen(gp.out.info->info2.drivername);
	}

	return true;
}
Exemplo n.º 12
0
static bool test_EnumPrinters(struct torture_context *tctx,
				struct dcerpc_pipe *p,
				struct test_spoolss_win_context *ctx,
				uint32_t initial_blob_size)
{
	NTSTATUS status;
	struct spoolss_EnumPrinters ep;
	DATA_BLOB blob = data_blob_talloc_zero(ctx, initial_blob_size);
	uint32_t needed;
	uint32_t count;
	union spoolss_PrinterInfo *info;
	struct dcerpc_binding_handle *b = p->binding_handle;

	ep.in.flags = PRINTER_ENUM_NAME;
	ep.in.server = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
	ep.in.level = 2;
	ep.in.buffer = &blob;
	ep.in.offered = initial_blob_size;
	ep.out.needed = &needed;
	ep.out.count = &count;
	ep.out.info = &info;

	status = dcerpc_spoolss_EnumPrinters_r(b, ctx, &ep);
	torture_assert_ntstatus_ok(tctx, status, "EnumPrinters failed.");

	if (W_ERROR_EQUAL(ep.out.result, WERR_INSUFFICIENT_BUFFER)) {
		blob = data_blob_talloc_zero(ctx, needed);
		ep.in.buffer = &blob;
		ep.in.offered = needed;
		status = dcerpc_spoolss_EnumPrinters_r(b, ctx, &ep);
		torture_assert_ntstatus_ok(tctx, status,"EnumPrinters failed.");
	}

	torture_assert_werr_ok(tctx, ep.out.result, "EnumPrinters failed.");

	ctx->printer_count = count;
	ctx->printer_info = info;

	torture_comment(tctx, "Found %d printer(s).\n", ctx->printer_count);

	return true;
}
Exemplo n.º 13
0
static bool test_EnumForms(struct torture_context *tctx,
				struct dcerpc_binding_handle *b,
				struct policy_handle *handle,
				uint32_t initial_blob_size)
{
	NTSTATUS status;
	struct spoolss_EnumForms ef;
	DATA_BLOB blob = data_blob_talloc_zero(tctx, initial_blob_size);
	uint32_t needed;
	uint32_t count;
	union spoolss_FormInfo *info;

	torture_comment(tctx, "Testing EnumForms\n");

	ef.in.handle = handle;
	ef.in.level = 1;
	ef.in.buffer = (initial_blob_size == 0)?NULL:&blob;
	ef.in.offered = initial_blob_size;
	ef.out.needed = &needed;
	ef.out.count = &count;
	ef.out.info = &info;

	status = dcerpc_spoolss_EnumForms_r(b, tctx, &ef);
	torture_assert_ntstatus_ok(tctx, status, "EnumForms failed");

	if (W_ERROR_EQUAL(ef.out.result, WERR_INSUFFICIENT_BUFFER)) {
		blob = data_blob_talloc_zero(tctx, needed);
		ef.in.buffer = &blob;
		ef.in.offered = needed;
		status = dcerpc_spoolss_EnumForms_r(b, tctx, &ef);
		torture_assert_ntstatus_ok(tctx, status, "EnumForms failed");
	}

	torture_assert_werr_ok(tctx, ef.out.result, "EnumForms failed");

	return true;
}
Exemplo n.º 14
0
static bool test_EnumJobs(struct torture_context *tctx,
				struct dcerpc_binding_handle *b,
				struct policy_handle *handle)
{
	NTSTATUS status;
	struct spoolss_EnumJobs ej;
	DATA_BLOB blob = data_blob_talloc_zero(tctx, 1024);
	uint32_t needed;
	uint32_t count;
	union spoolss_JobInfo *info;

	torture_comment(tctx, "Test EnumJobs\n");

	ZERO_STRUCT(ej);
	ej.in.handle = handle;
	ej.in.firstjob = 0;
	ej.in.numjobs = 0;
	ej.in.level = 2;
	ej.in.buffer = &blob;
	ej.in.offered = 1024;
	ej.out.needed = &needed;
	ej.out.count = &count;
	ej.out.info = &info;

	status = dcerpc_spoolss_EnumJobs_r(b, tctx, &ej);
	torture_assert_ntstatus_ok(tctx, status, "EnumJobs failed");
	if (W_ERROR_EQUAL(ej.out.result, WERR_INSUFFICIENT_BUFFER)) {
		blob = data_blob_talloc_zero(tctx, needed);
		ej.in.offered = needed;
		ej.in.buffer = &blob;
		status = dcerpc_spoolss_EnumJobs_r(b, tctx, &ej);
		torture_assert_ntstatus_ok(tctx, status, "EnumJobs failed");
	}
	torture_assert_werr_ok(tctx, ej.out.result, "EnumJobs failed");

	return true;
}
Exemplo n.º 15
0
bool setup_fault_pdu(struct pipes_struct *p, NTSTATUS fault_status)
{
	NTSTATUS status;
	union dcerpc_payload u;

	/* Free any memory in the current return data buffer. */
	pipe_init_outgoing_data(p);

	/*
	 * Initialize a fault header.
	 */

	ZERO_STRUCT(u);

	u.fault.status		= NT_STATUS_V(fault_status);
	u.fault._pad		= data_blob_talloc_zero(p->mem_ctx, 4);

	/*
	 * Marshall directly into the outgoing PDU space. We
	 * must do this as we need to set to the bind response
	 * header and are never sending more than one PDU here.
	 */

	status = dcerpc_push_ncacn_packet(p->mem_ctx,
					  DCERPC_PKT_FAULT,
					  DCERPC_PFC_FLAG_FIRST |
					   DCERPC_PFC_FLAG_LAST |
					   DCERPC_PFC_FLAG_DID_NOT_EXECUTE,
					  0,
					  p->call_id,
					  &u,
					  &p->out_data.frag);
	if (!NT_STATUS_IS_OK(status)) {
		return False;
	}

	p->out_data.data_sent_length = 0;
	p->out_data.current_pdu_sent = 0;

	return True;
}
Exemplo n.º 16
0
/*
  fill in the cldap netlogon union for a given version
*/
NTSTATUS fill_netlogon_samlogon_response(struct ldb_context *sam_ctx,
					 TALLOC_CTX *mem_ctx,
					 const char *domain,
					 const char *netbios_domain,
					 struct dom_sid *domain_sid,
					 const char *domain_guid,
					 const char *user,
					 uint32_t acct_control,
					 const char *src_address,
					 uint32_t version,
					 struct loadparm_context *lp_ctx,
					 struct netlogon_samlogon_response *netlogon,
					 bool fill_on_blank_request)
{
	const char *dom_attrs[] = {"objectGUID", NULL};
	const char *none_attrs[] = {NULL};
	struct ldb_result *dom_res = NULL, *user_res = NULL;
	int ret;
	const char **services = lpcfg_server_services(lp_ctx);
	uint32_t server_type;
	const char *pdc_name;
	struct GUID domain_uuid;
	const char *dns_domain;
	const char *forest_domain;
	const char *pdc_dns_name;
	const char *flatname;
	const char *server_site;
	const char *client_site;
	const char *pdc_ip;
	struct ldb_dn *domain_dn = NULL;
	struct interface *ifaces;
	bool user_known, am_rodc;
	NTSTATUS status;

	/* the domain parameter could have an optional trailing "." */
	if (domain && domain[strlen(domain)-1] == '.') {
		domain = talloc_strndup(mem_ctx, domain, strlen(domain)-1);
		NT_STATUS_HAVE_NO_MEMORY(domain);
	}

	/* Lookup using long or short domainname */
	if (domain && (strcasecmp_m(domain, lpcfg_dnsdomain(lp_ctx)) == 0)) {
		domain_dn = ldb_get_default_basedn(sam_ctx);
	}
	if (netbios_domain && (strcasecmp_m(netbios_domain, lpcfg_sam_name(lp_ctx)) == 0)) {
		domain_dn = ldb_get_default_basedn(sam_ctx);
	}
	if (domain_dn) {
		const char *domain_identifier = domain != NULL ? domain
							: netbios_domain;
		ret = ldb_search(sam_ctx, mem_ctx, &dom_res,
				 domain_dn, LDB_SCOPE_BASE, dom_attrs,
				 "objectClass=domain");
		if (ret != LDB_SUCCESS) {
			DEBUG(2,("Error finding domain '%s'/'%s' in sam: %s\n",
				 domain_identifier,
				 ldb_dn_get_linearized(domain_dn),
				 ldb_errstring(sam_ctx)));
			return NT_STATUS_NO_SUCH_DOMAIN;
		}
		if (dom_res->count != 1) {
			DEBUG(2,("Error finding domain '%s'/'%s' in sam\n",
				 domain_identifier,
				 ldb_dn_get_linearized(domain_dn)));
			return NT_STATUS_NO_SUCH_DOMAIN;
		}
	}

	/* Lookup using GUID or SID */
	if ((dom_res == NULL) && (domain_guid || domain_sid)) {
		if (domain_guid) {
			struct GUID binary_guid;
			struct ldb_val guid_val;

			/* By this means, we ensure we don't have funny stuff in the GUID */

			status = GUID_from_string(domain_guid, &binary_guid);
			if (!NT_STATUS_IS_OK(status)) {
				return status;
			}

			/* And this gets the result into the binary format we want anyway */
			status = GUID_to_ndr_blob(&binary_guid, mem_ctx, &guid_val);
			if (!NT_STATUS_IS_OK(status)) {
				return status;
			}
			ret = ldb_search(sam_ctx, mem_ctx, &dom_res,
						 NULL, LDB_SCOPE_SUBTREE, 
						 dom_attrs, 
						 "(&(objectCategory=DomainDNS)(objectGUID=%s))", 
						 ldb_binary_encode(mem_ctx, guid_val));
		} else { /* domain_sid case */
			ret = ldb_search(sam_ctx, mem_ctx, &dom_res,
					 NULL, LDB_SCOPE_SUBTREE,
					 dom_attrs,
					 "(&(objectCategory=DomainDNS)(objectSid=%s))",
					 dom_sid_string(mem_ctx, domain_sid));
		}
		
		if (ret != LDB_SUCCESS) {
			DEBUG(2,("Unable to find a correct reference to GUID '%s' or SID '%s' in sam: %s\n",
				 domain_guid, dom_sid_string(mem_ctx, domain_sid),
				 ldb_errstring(sam_ctx)));
			return NT_STATUS_NO_SUCH_DOMAIN;
		} else if (dom_res->count == 1) {
			/* Ok, now just check it is our domain */
			if (ldb_dn_compare(ldb_get_default_basedn(sam_ctx),
					   dom_res->msgs[0]->dn) != 0) {
				DEBUG(2,("The GUID '%s' or SID '%s' doesn't identify our domain\n",
					 domain_guid,
					 dom_sid_string(mem_ctx, domain_sid)));
				return NT_STATUS_NO_SUCH_DOMAIN;
			}
		} else {
			DEBUG(2,("Unable to find a correct reference to GUID '%s' or SID '%s' in sam\n",
				 domain_guid, dom_sid_string(mem_ctx, domain_sid)));
			return NT_STATUS_NO_SUCH_DOMAIN;
		}
	}

	if (dom_res == NULL && fill_on_blank_request) {
		/* blank inputs gives our domain - tested against
		   w2k8r2. Without this ADUC on Win7 won't start */
		domain_dn = ldb_get_default_basedn(sam_ctx);
		ret = ldb_search(sam_ctx, mem_ctx, &dom_res,
				 domain_dn, LDB_SCOPE_BASE, dom_attrs,
				 "objectClass=domain");
		if (ret != LDB_SUCCESS) {
			DEBUG(2,("Error finding domain '%s'/'%s' in sam: %s\n",
				 lpcfg_dnsdomain(lp_ctx),
				 ldb_dn_get_linearized(domain_dn),
				 ldb_errstring(sam_ctx)));
			return NT_STATUS_NO_SUCH_DOMAIN;
		}
	}

        if (dom_res == NULL) {
		DEBUG(2,(__location__ ": Unable to get domain information with no inputs\n"));
		return NT_STATUS_NO_SUCH_DOMAIN;
	}

	/* work around different inputs for not-specified users */
	if (!user) {
		user = "";
	}

	/* Enquire about any valid username with just a CLDAP packet -
	 * if kerberos didn't also do this, the security folks would
	 * scream... */
	if (user[0]) {							\
		/* Only allow some bits to be enquired:  [MS-ATDS] 7.3.3.2 */
		if (acct_control == (uint32_t)-1) {
			acct_control = 0;
		}
		acct_control = acct_control & (ACB_TEMPDUP | ACB_NORMAL | ACB_DOMTRUST | ACB_WSTRUST | ACB_SVRTRUST);

		/* We must exclude disabled accounts, but otherwise do the bitwise match the client asked for */
		ret = ldb_search(sam_ctx, mem_ctx, &user_res,
					 dom_res->msgs[0]->dn, LDB_SCOPE_SUBTREE, 
					 none_attrs, 
					 "(&(objectClass=user)(samAccountName=%s)"
					 "(!(userAccountControl:" LDB_OID_COMPARATOR_AND ":=%u))"
					 "(userAccountControl:" LDB_OID_COMPARATOR_OR ":=%u))", 
					 ldb_binary_encode_string(mem_ctx, user),
					 UF_ACCOUNTDISABLE, ds_acb2uf(acct_control));
		if (ret != LDB_SUCCESS) {
			DEBUG(2,("Unable to find reference to user '%s' with ACB 0x%8x under %s: %s\n",
				 user, acct_control, ldb_dn_get_linearized(dom_res->msgs[0]->dn),
				 ldb_errstring(sam_ctx)));
			return NT_STATUS_NO_SUCH_USER;
		} else if (user_res->count == 1) {
			user_known = true;
		} else {
			user_known = false;
		}

	} else {
		user_known = true;
	}
		
	server_type      = 
		DS_SERVER_DS | DS_SERVER_TIMESERV |
		DS_SERVER_GOOD_TIMESERV;

	if (samdb_is_pdc(sam_ctx)) {
		server_type |= DS_SERVER_PDC;
	}

	if (dsdb_functional_level(sam_ctx) >= DS_DOMAIN_FUNCTION_2008) {
		server_type |= DS_SERVER_FULL_SECRET_DOMAIN_6;
	}

	if (samdb_is_gc(sam_ctx)) {
		server_type |= DS_SERVER_GC;
	}

	if (str_list_check(services, "ldap")) {
		server_type |= DS_SERVER_LDAP;
	}

	if (str_list_check(services, "kdc")) {
		server_type |= DS_SERVER_KDC;
	}

	if (samdb_rodc(sam_ctx, &am_rodc) == LDB_SUCCESS && !am_rodc) {
		server_type |= DS_SERVER_WRITABLE;
	}

	pdc_name         = talloc_asprintf(mem_ctx, "\\\\%s",
					   lpcfg_netbios_name(lp_ctx));
	NT_STATUS_HAVE_NO_MEMORY(pdc_name);
	domain_uuid      = samdb_result_guid(dom_res->msgs[0], "objectGUID");
	dns_domain       = lpcfg_dnsdomain(lp_ctx);
	forest_domain    = samdb_forest_name(sam_ctx, mem_ctx);
	NT_STATUS_HAVE_NO_MEMORY(forest_domain);
	pdc_dns_name     = talloc_asprintf(mem_ctx, "%s.%s", 
					   strlower_talloc(mem_ctx, 
							   lpcfg_netbios_name(lp_ctx)),
					   dns_domain);
	NT_STATUS_HAVE_NO_MEMORY(pdc_dns_name);
	flatname         = lpcfg_workgroup(lp_ctx);

	server_site      = samdb_server_site_name(sam_ctx, mem_ctx);
	NT_STATUS_HAVE_NO_MEMORY(server_site);
	client_site      = samdb_client_site_name(sam_ctx, mem_ctx,
						  src_address, NULL);
	NT_STATUS_HAVE_NO_MEMORY(client_site);
	if (strcasecmp(server_site, client_site) == 0) {
		server_type |= DS_SERVER_CLOSEST;
	}

	load_interface_list(mem_ctx, lp_ctx, &ifaces);
	if (src_address) {
		pdc_ip = iface_list_best_ip(ifaces, src_address);
	} else {
		pdc_ip = iface_list_first_v4(ifaces);
	}
	if (pdc_ip == NULL || !is_ipaddress_v4(pdc_ip)) {
		/* this matches windows behaviour */
		pdc_ip = "127.0.0.1";
	}

	ZERO_STRUCTP(netlogon);

	/* check if either of these bits is present */
	if (version & (NETLOGON_NT_VERSION_5EX|NETLOGON_NT_VERSION_5EX_WITH_IP)) {
		uint32_t extra_flags = 0;
		netlogon->ntver = NETLOGON_NT_VERSION_5EX;

		/* could check if the user exists */
		if (user_known) {
			netlogon->data.nt5_ex.command      = LOGON_SAM_LOGON_RESPONSE_EX;
		} else {
			netlogon->data.nt5_ex.command      = LOGON_SAM_LOGON_USER_UNKNOWN_EX;
		}
		netlogon->data.nt5_ex.pdc_name     = pdc_name;
		netlogon->data.nt5_ex.user_name    = user;
		netlogon->data.nt5_ex.domain_name  = flatname;
		netlogon->data.nt5_ex.domain_uuid  = domain_uuid;
		netlogon->data.nt5_ex.forest       = forest_domain;
		netlogon->data.nt5_ex.dns_domain   = dns_domain;
		netlogon->data.nt5_ex.pdc_dns_name = pdc_dns_name;
		netlogon->data.nt5_ex.server_site  = server_site;
		netlogon->data.nt5_ex.client_site  = client_site;
		if (version & NETLOGON_NT_VERSION_5EX_WITH_IP) {
			/* note that this is always a IPV4 address */
			extra_flags = NETLOGON_NT_VERSION_5EX_WITH_IP;
			netlogon->data.nt5_ex.sockaddr.sockaddr_family    = 2;
			netlogon->data.nt5_ex.sockaddr.pdc_ip       = pdc_ip;
			netlogon->data.nt5_ex.sockaddr.remaining = data_blob_talloc_zero(mem_ctx, 8);
		}
		netlogon->data.nt5_ex.server_type  = server_type;
		netlogon->data.nt5_ex.nt_version   = NETLOGON_NT_VERSION_1|NETLOGON_NT_VERSION_5EX|extra_flags;
		netlogon->data.nt5_ex.lmnt_token   = 0xFFFF;
		netlogon->data.nt5_ex.lm20_token   = 0xFFFF;

	} else if (version & NETLOGON_NT_VERSION_5) {
		netlogon->ntver = NETLOGON_NT_VERSION_5;

		/* could check if the user exists */
		if (user_known) {
			netlogon->data.nt5.command      = LOGON_SAM_LOGON_RESPONSE;
		} else {
			netlogon->data.nt5.command      = LOGON_SAM_LOGON_USER_UNKNOWN;
		}
		netlogon->data.nt5.pdc_name     = pdc_name;
		netlogon->data.nt5.user_name    = user;
		netlogon->data.nt5.domain_name  = flatname;
		netlogon->data.nt5.domain_uuid  = domain_uuid;
		netlogon->data.nt5.forest       = forest_domain;
		netlogon->data.nt5.dns_domain   = dns_domain;
		netlogon->data.nt5.pdc_dns_name = pdc_dns_name;
		netlogon->data.nt5.pdc_ip       = pdc_ip;
		netlogon->data.nt5.server_type  = server_type;
		netlogon->data.nt5.nt_version   = NETLOGON_NT_VERSION_1|NETLOGON_NT_VERSION_5;
		netlogon->data.nt5.lmnt_token   = 0xFFFF;
		netlogon->data.nt5.lm20_token   = 0xFFFF;

	} else /* (version & NETLOGON_NT_VERSION_1) and all other cases */ {
		netlogon->ntver = NETLOGON_NT_VERSION_1;
		/* could check if the user exists */
		if (user_known) {
			netlogon->data.nt4.command      = LOGON_SAM_LOGON_RESPONSE;
		} else {
			netlogon->data.nt4.command      = LOGON_SAM_LOGON_USER_UNKNOWN;
		}
		netlogon->data.nt4.pdc_name    = pdc_name;
		netlogon->data.nt4.user_name   = user;
		netlogon->data.nt4.domain_name = flatname;
		netlogon->data.nt4.nt_version  = NETLOGON_NT_VERSION_1;
		netlogon->data.nt4.lmnt_token  = 0xFFFF;
		netlogon->data.nt4.lm20_token  = 0xFFFF;
	}

	return NT_STATUS_OK;
}
Exemplo n.º 17
0
/*
 * @brief Load the keys into the encrypted secrets module context.
 *
 * @param module the current ldb module
 * @param data the private data for the current module
 *
 * Currently the keys are stored in a binary file in the same directory
 * as the database.
 *
 * @return an LDB result code.
 *
 */
static int load_keys(struct ldb_module *module, struct es_data *data)
{

	const char *key_dir  = NULL;
	const char *key_path = NULL;

	struct ldb_context *ldb = NULL;
	FILE *fp = NULL;
	const int key_size = 16;
	int read;
	DATA_BLOB key = data_blob_null;

	TALLOC_CTX *frame = talloc_stackframe();

	ldb = ldb_module_get_ctx(module);
	key_dir = get_key_directory(frame, ldb);
	if (key_dir == NULL) {
		TALLOC_FREE(frame);
		return LDB_ERR_OPERATIONS_ERROR;
	}

	key_path = talloc_asprintf(frame, "%s/%s", key_dir, SECRETS_KEY_FILE);
	if (key_path == NULL) {
		TALLOC_FREE(frame);
		return ldb_oom(ldb);
	}


	key = data_blob_talloc_zero(module, key_size);
	key.length = key_size;

	fp = fopen(key_path, "rb");
	if (fp == NULL) {
		TALLOC_FREE(frame);
		data_blob_free(&key);
		if (errno == ENOENT) {
			ldb_debug(ldb,
				  LDB_DEBUG_WARNING,
				  "No encrypted secrets key file. "
				  "Secret attributes will not be encrypted or "
				  "decrypted\n");
			data->encrypt_secrets = false;
			return LDB_SUCCESS;
		} else {
			log_error(ldb,
				  errno,
				  "Opening encrypted_secrets key file\n");
			return LDB_ERR_OPERATIONS_ERROR;
		}
	}

	read = fread(key.data, 1, key.length, fp);
	fclose(fp);
	if (read == 0) {
		TALLOC_FREE(frame);
		ldb_debug(ldb,
			  LDB_DEBUG_WARNING,
			  "Zero length encrypted secrets key file. "
			  "Secret attributes will not be encrypted or "
			  "decrypted\n");
		data->encrypt_secrets = false;
		return LDB_SUCCESS;
	}
	if (read != key.length) {
		TALLOC_FREE(frame);
		if (errno) {
			log_error(ldb,
				  errno,
				  "Reading encrypted_secrets key file\n");
		} else {
			ldb_debug(ldb,
				  LDB_DEBUG_ERROR,
				  "Invalid encrypted_secrets key file, "
				  "only %d bytes read should be %d bytes\n",
				  read,
				  key_size);
		}
		return LDB_ERR_OPERATIONS_ERROR;
	}

	data->keys[0] = key;
	data->encrypt_secrets = true;
#ifdef BUILD_WITH_GNUTLS_AEAD
	data->encryption_algorithm = GNUTLS_CIPHER_AES_128_GCM;
#endif
	TALLOC_FREE(frame);

	return LDB_SUCCESS;

}
static bool fdpass2_parent(pid_t child_pid, int ready_fd)
{
	struct tevent_context *ev = NULL;
	struct messaging_context *msg_ctx = NULL;
	bool retval = false;
	int up_pipe[2];
	int down_pipe[2];
	int pass_fds[2] = { 0 };
	int ret;
	NTSTATUS status;
	struct server_id dst;
	TALLOC_CTX *frame = talloc_stackframe();
	uint8_t c1 = 1, c2, c;
	ssize_t bytes;
	struct iovec iov;
	DATA_BLOB blob;
	struct tevent_fd *child_done_fde;
	struct child_done_state child_state;

	ev = samba_tevent_context_init(frame);
	if (ev == NULL) {
		fprintf(stderr, "parent: tevent_context_init failed\n");
		goto done;
	}

	msg_ctx = messaging_init(ev, ev);
	if (msg_ctx == NULL) {
		fprintf(stderr, "parent: messaging_init failed\n");
		goto done;
	}

	/* wait util the child is ready to receive messages */
	bytes = read(ready_fd, &c, 1);
	if (bytes != 1) {
		perror("parent: read from ready_fd failed");
		goto done;
	}

	ret = pipe(up_pipe);
	if (ret != 0) {
		perror("parent: pipe failed for up_pipe");
		goto done;
	}

	ret = pipe(down_pipe);
	if (ret != 0) {
		perror("parent: pipe failed for down_pipe");
		goto done;
	}

	child_state.fd = ready_fd;
	child_state.done = false;

	child_done_fde = tevent_add_fd(ev, ev, ready_fd, TEVENT_FD_READ,
				       child_done_cb, &child_state);
	if (child_done_fde == NULL) {
		fprintf(stderr,
			"parent: failed tevent_add_fd for child done\n");
		goto done;
	}

	pass_fds[0] = up_pipe[0];
	pass_fds[1] = down_pipe[1];

	dst = messaging_server_id(msg_ctx);
	dst.pid = child_pid;

	/*
	 * Send a certain payload with the fds, to test to test
	 * that fd-passing works when we have fragmentation and
	 * re-assembly of the datagrams.
	 */
	blob = data_blob_talloc_zero(frame, 1000*1000);
	iov.iov_base = blob.data;
	iov.iov_len  = blob.length;

	status = messaging_send_iov(msg_ctx, dst, MSG_TORTURE_FDPASS2, &iov, 1,
				    pass_fds, 2);
	if (!NT_STATUS_IS_OK(status)) {
		fprintf(stderr, "parent: messaging_send_iov failed: %s\n",
			nt_errstr(status));
		goto done;
	}

	printf("parent: waiting for child to confirm\n");

	while (!child_state.done) {
		ret = tevent_loop_once(ev);
		if (ret != 0) {
			fprintf(stderr, "parent: tevent_loop_once failed\n");
			goto done;
		}
	}

	printf("parent: child confirmed\n");

	close(up_pipe[0]);
	close(down_pipe[1]);

	bytes = write(up_pipe[1], &c1, 1);
	if (bytes != 1) {
		perror("parent: write to up pipe failed");
		goto done;
	}

	bytes = read(down_pipe[0], &c2, 1);
	if (bytes != 1) {
		perror("parent: read from down pipe failed");
		goto done;
	}

	if (c1 != c2) {
		fprintf(stderr, "parent: c1[%d] != c2[%d]\n", c1, c2);
		goto done;
	}

	ret = waitpid(child_pid, NULL, 0);
	if (ret == -1) {
		perror("parent: waitpid failed");
		goto done;
	}

	retval = true;

done:
	TALLOC_FREE(frame);
	return retval;
}
Exemplo n.º 19
0
NTSTATUS netsec_outgoing_packet(struct schannel_state *state,
				TALLOC_CTX *mem_ctx,
				bool do_seal,
				uint8_t *data, size_t length,
				DATA_BLOB *sig)
{
	uint32_t min_sig_size = 0;
	uint32_t used_sig_size = 0;
	uint8_t header[8];
	uint8_t checksum[32];
	uint32_t checksum_length = sizeof(checksum_length);
	uint8_t _confounder[8];
	uint8_t *confounder = NULL;
	uint32_t confounder_ofs = 0;
	uint8_t seq_num[8];

	netsec_offset_and_sizes(state,
				do_seal,
				&min_sig_size,
				&used_sig_size,
				&checksum_length,
				&confounder_ofs);

	RSIVAL(seq_num, 0, state->seq_num);
	SIVAL(seq_num, 4, state->initiator?0x80:0);

	if (do_seal) {
		confounder = _confounder;
		generate_random_buffer(confounder, 8);
	} else {
		confounder = NULL;
	}

	netsec_do_sign(state, confounder,
		       data, length,
		       header, checksum);

	if (do_seal) {
		netsec_do_seal(state, seq_num,
			       confounder,
			       data, length,
			       true);
	}

	netsec_do_seq_num(state, checksum, checksum_length, seq_num);

	(*sig) = data_blob_talloc_zero(mem_ctx, used_sig_size);

	memcpy(sig->data, header, 8);
	memcpy(sig->data+8, seq_num, 8);
	memcpy(sig->data+16, checksum, checksum_length);

	if (confounder) {
		memcpy(sig->data+confounder_ofs, confounder, 8);
	}

	dump_data_pw("signature:", sig->data+ 0, 8);
	dump_data_pw("seq_num  :", sig->data+ 8, 8);
	dump_data_pw("digest   :", sig->data+16, checksum_length);
	dump_data_pw("confound :", sig->data+confounder_ofs, 8);

	return NT_STATUS_OK;
}
Exemplo n.º 20
0
NTSTATUS dcerpc_binding_build_tower(TALLOC_CTX *mem_ctx, struct dcerpc_binding *binding, struct epm_tower *tower)
{
	const enum epm_protocol *protseq = NULL;
	int num_protocols = -1, i;
	NTSTATUS status;
	
	/* Find transport */
	for (i=0;i<ARRAY_SIZE(transports);i++) {
		if (transports[i].transport == binding->transport) {
			protseq = transports[i].protseq;
			num_protocols = transports[i].num_protocols;
			break;
		}
	}

	if (num_protocols == -1) {
		DEBUG(0, ("Unable to find transport with id '%d'\n", binding->transport));
		return NT_STATUS_UNSUCCESSFUL;
	}

	tower->num_floors = 2 + num_protocols;
	tower->floors = talloc_array(mem_ctx, struct epm_floor, tower->num_floors);

	/* Floor 0 */
	tower->floors[0].lhs.protocol = EPM_PROTOCOL_UUID;

	tower->floors[0].lhs.lhs_data = dcerpc_floor_pack_lhs_data(mem_ctx, &binding->object);

	tower->floors[0].rhs.uuid.unknown = data_blob_talloc_zero(mem_ctx, 2);
	
	/* Floor 1 */
	tower->floors[1].lhs.protocol = EPM_PROTOCOL_UUID;

	tower->floors[1].lhs.lhs_data = dcerpc_floor_pack_lhs_data(mem_ctx, 
								&ndr_transfer_syntax);
	
	tower->floors[1].rhs.uuid.unknown = data_blob_talloc_zero(mem_ctx, 2);
	
	/* Floor 2 to num_protocols */
	for (i = 0; i < num_protocols; i++) {
		tower->floors[2 + i].lhs.protocol = protseq[i];
		tower->floors[2 + i].lhs.lhs_data = data_blob_talloc(mem_ctx, NULL, 0);
		ZERO_STRUCT(tower->floors[2 + i].rhs);
		dcerpc_floor_set_rhs_data(mem_ctx, &tower->floors[2 + i], "");
	}

	/* The 4th floor contains the endpoint */
	if (num_protocols >= 2 && binding->endpoint) {
		status = dcerpc_floor_set_rhs_data(mem_ctx, &tower->floors[3], binding->endpoint);
		if (NT_STATUS_IS_ERR(status)) {
			return status;
		}
	}
	
	/* The 5th contains the network address */
	if (num_protocols >= 3 && binding->host) {
		if (is_ipaddress(binding->host)) {
			status = dcerpc_floor_set_rhs_data(mem_ctx, &tower->floors[4], 
							   binding->host);
		} else {
			/* note that we don't attempt to resolve the
			   name here - when we get a hostname here we
			   are in the client code, and want to put in
			   a wildcard all-zeros IP for the server to
			   fill in */
			status = dcerpc_floor_set_rhs_data(mem_ctx, &tower->floors[4], 
							   "0.0.0.0");
		}
		if (NT_STATUS_IS_ERR(status)) {
			return status;
		}
	}

	return NT_STATUS_OK;
}
Exemplo n.º 21
0
/*
  send a create request
*/
struct smb2_request *smb2_create_send(struct smb2_tree *tree, struct smb2_create *io)
{
	struct smb2_request *req;
	NTSTATUS status;
	DATA_BLOB blob;
	struct smb2_create_blobs blobs;
	int i;

	ZERO_STRUCT(blobs);

	req = smb2_request_init_tree(tree, SMB2_OP_CREATE, 0x38, true, 0);
	if (req == NULL) return NULL;

	SCVAL(req->out.body, 0x02, io->in.security_flags);
	SCVAL(req->out.body, 0x03, io->in.oplock_level);
	SIVAL(req->out.body, 0x04, io->in.impersonation_level);
	SBVAL(req->out.body, 0x08, io->in.create_flags);
	SBVAL(req->out.body, 0x10, io->in.reserved);
	SIVAL(req->out.body, 0x18, io->in.desired_access);
	SIVAL(req->out.body, 0x1C, io->in.file_attributes);
	SIVAL(req->out.body, 0x20, io->in.share_access);
	SIVAL(req->out.body, 0x24, io->in.create_disposition);
	SIVAL(req->out.body, 0x28, io->in.create_options);

	status = smb2_push_o16s16_string(&req->out, 0x2C, io->in.fname);
	if (!NT_STATUS_IS_OK(status)) {
		talloc_free(req);
		return NULL;
	}

	/* now add all the optional blobs */
	if (io->in.eas.num_eas != 0) {
		DATA_BLOB b = data_blob_talloc(req, NULL, 
					       ea_list_size_chained(io->in.eas.num_eas, io->in.eas.eas, 4));
		ea_put_list_chained(b.data, io->in.eas.num_eas, io->in.eas.eas, 4);
		status = smb2_create_blob_add(req, &blobs,
					      SMB2_CREATE_TAG_EXTA, b);
		if (!NT_STATUS_IS_OK(status)) {
			talloc_free(req);
			return NULL;
		}
		data_blob_free(&b);
	}

	/* an empty MxAc tag seems to be used to ask the server to
	   return the maximum access mask allowed on the file */
	if (io->in.query_maximal_access) {
		/* TODO: MS-SMB2 2.2.13.2.5 says this can contain a timestamp? What to do
		   with that if it doesn't match? */
		status = smb2_create_blob_add(req, &blobs,
					      SMB2_CREATE_TAG_MXAC, data_blob(NULL, 0));
		if (!NT_STATUS_IS_OK(status)) {
			talloc_free(req);
			return NULL;
		}
	}

	if (io->in.alloc_size != 0) {
		uint8_t data[8];
		SBVAL(data, 0, io->in.alloc_size);
		status = smb2_create_blob_add(req, &blobs,
					      SMB2_CREATE_TAG_ALSI, data_blob_const(data, 8));
		if (!NT_STATUS_IS_OK(status)) {
			talloc_free(req);
			return NULL;
		}
	}

	if (io->in.durable_open) {
		status = smb2_create_blob_add(req, &blobs,
					      SMB2_CREATE_TAG_DHNQ, data_blob_talloc_zero(req, 16));
		if (!NT_STATUS_IS_OK(status)) {
			talloc_free(req);
			return NULL;
		}
	}

	if (io->in.durable_handle) {
		uint8_t data[16];
		smb2_push_handle(data, io->in.durable_handle);
		status = smb2_create_blob_add(req, &blobs,
					      SMB2_CREATE_TAG_DHNC, data_blob_const(data, 16));
		if (!NT_STATUS_IS_OK(status)) {
			talloc_free(req);
			return NULL;
		}
	}

	if (io->in.timewarp) {
		uint8_t data[8];
		SBVAL(data, 0, io->in.timewarp);		
		status = smb2_create_blob_add(req, &blobs,
					      SMB2_CREATE_TAG_TWRP, data_blob_const(data, 8));
		if (!NT_STATUS_IS_OK(status)) {
			talloc_free(req);
			return NULL;
		}
	}

	if (io->in.sec_desc) {
		enum ndr_err_code ndr_err;
		DATA_BLOB sd_blob;
		ndr_err = ndr_push_struct_blob(&sd_blob, req, io->in.sec_desc,
					       (ndr_push_flags_fn_t)ndr_push_security_descriptor);
		if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
			talloc_free(req);
			return NULL;
		}
		status = smb2_create_blob_add(req, &blobs,
					      SMB2_CREATE_TAG_SECD, sd_blob);
		if (!NT_STATUS_IS_OK(status)) {
			talloc_free(req);
			return NULL;
		}
	}

	if (io->in.query_on_disk_id) {
		status = smb2_create_blob_add(req, &blobs,
					      SMB2_CREATE_TAG_QFID, data_blob(NULL, 0));
		if (!NT_STATUS_IS_OK(status)) {
			talloc_free(req);
			return NULL;
		}
	}

	if (io->in.lease_request) {
		uint8_t data[32];

		memcpy(&data[0], &io->in.lease_request->lease_key, 16);
		SIVAL(data, 16, io->in.lease_request->lease_state);
		SIVAL(data, 20, io->in.lease_request->lease_flags);
		SBVAL(data, 24, io->in.lease_request->lease_duration);

		status = smb2_create_blob_add(req, &blobs,
					      SMB2_CREATE_TAG_RQLS,
					      data_blob_const(data, 32));
		if (!NT_STATUS_IS_OK(status)) {
			talloc_free(req);
			return NULL;
		}
	}

	/* and any custom blobs */
	for (i=0;i<io->in.blobs.num_blobs;i++) {
		status = smb2_create_blob_add(req, &blobs,
					      io->in.blobs.blobs[i].tag, 
					      io->in.blobs.blobs[i].data);
		if (!NT_STATUS_IS_OK(status)) {
			talloc_free(req);
			return NULL;
		}
	}


	status = smb2_create_blob_push(req, &blob, blobs);
	if (!NT_STATUS_IS_OK(status)) {
		talloc_free(req);
		return NULL;
	}

	status = smb2_push_o32s32_blob(&req->out, 0x30, blob);
	if (!NT_STATUS_IS_OK(status)) {
		talloc_free(req);
		return NULL;
	}

	data_blob_free(&blob);

	smb2_transport_send(req);

	return req;
}
Exemplo n.º 22
0
NTSTATUS dcerpc_winreg_query_dword(TALLOC_CTX *mem_ctx,
				   struct dcerpc_binding_handle *h,
				   struct policy_handle *key_handle,
				   const char *value,
				   uint32_t *data,
				   WERROR *pwerr)
{
	struct winreg_String wvalue;
	enum winreg_Type type = REG_NONE;
	uint32_t value_len = 0;
	uint32_t data_size = 0;
	WERROR result = WERR_OK;
	NTSTATUS status;
	DATA_BLOB blob;

	wvalue.name = value;

	status = dcerpc_winreg_QueryValue(h,
					  mem_ctx,
					  key_handle,
					  &wvalue,
					  &type,
					  NULL,
					  &data_size,
					  &value_len,
					  &result);
	if (!NT_STATUS_IS_OK(status)) {
		return status;
	}
	if (!W_ERROR_IS_OK(result)) {
		*pwerr = result;
		return status;
	}

	if (type != REG_DWORD) {
		*pwerr = WERR_INVALID_DATATYPE;
		return status;
	}

	if (data_size != 4) {
		*pwerr = WERR_INVALID_DATA;
		return status;
	}

	blob = data_blob_talloc_zero(mem_ctx, data_size);
	if (blob.data == NULL) {
		*pwerr = WERR_NOMEM;
		return status;
	}
	value_len = 0;

	status = dcerpc_winreg_QueryValue(h,
					  mem_ctx,
					  key_handle,
					  &wvalue,
					  &type,
					  blob.data,
					  &data_size,
					  &value_len,
					  &result);
	if (!NT_STATUS_IS_OK(status)) {
		return status;
	}
	if (!W_ERROR_IS_OK(result)) {
		*pwerr = result;
		return status;
	}

	if (data) {
		*data = IVAL(blob.data, 0);
	}

	return status;
}