Example #1
0
WERROR NetJoinDomain_r(struct libnetapi_ctx *ctx,
		       struct NetJoinDomain *r)
{
	struct rpc_pipe_client *pipe_cli = NULL;
	struct wkssvc_PasswordBuffer *encrypted_password = NULL;
	NTSTATUS status;
	WERROR werr;
	unsigned int old_timeout = 0;
	struct dcerpc_binding_handle *b;
	DATA_BLOB session_key;

	if (IS_DC) {
		return WERR_NERR_SETUPDOMAINCONTROLLER;
	}

	werr = libnetapi_open_pipe(ctx, r->in.server,
				   &ndr_table_wkssvc,
				   &pipe_cli);
	if (!W_ERROR_IS_OK(werr)) {
		goto done;
	}

	b = pipe_cli->binding_handle;

	if (r->in.password) {

		status = cli_get_session_key(talloc_tos(), pipe_cli, &session_key);
		if (!NT_STATUS_IS_OK(status)) {
			werr = ntstatus_to_werror(status);
			goto done;
		}

		encode_wkssvc_join_password_buffer(ctx,
						   r->in.password,
						   &session_key,
						   &encrypted_password);
	}

	old_timeout = rpccli_set_timeout(pipe_cli, 600000);

	status = dcerpc_wkssvc_NetrJoinDomain2(b, talloc_tos(),
					       r->in.server,
					       r->in.domain,
					       r->in.account_ou,
					       r->in.account,
					       encrypted_password,
					       r->in.join_flags,
					       &werr);
	if (!NT_STATUS_IS_OK(status)) {
		werr = ntstatus_to_werror(status);
		goto done;
	}

 done:
	if (pipe_cli && old_timeout) {
		rpccli_set_timeout(pipe_cli, old_timeout);
	}

	return werr;
}
Example #2
0
static NTSTATUS cmd_lsa_retrieve_private_data(struct rpc_pipe_client *cli,
					      TALLOC_CTX *mem_ctx, int argc,
					      const char **argv)
{
	NTSTATUS status;
	struct policy_handle handle;
	struct lsa_String name;
	struct lsa_DATA_BUF *val;
	DATA_BLOB session_key;
	DATA_BLOB blob = data_blob_null;
	char *secret;

	if (argc < 2) {
		printf("Usage: %s name\n", argv[0]);
		return NT_STATUS_OK;
	}

	status = rpccli_lsa_open_policy2(cli, mem_ctx,
					 true,
					 SEC_FLAG_MAXIMUM_ALLOWED,
					 &handle);
	if (!NT_STATUS_IS_OK(status)) {
		return status;
	}

	init_lsa_String(&name, argv[1]);

	ZERO_STRUCT(val);

	status = rpccli_lsa_RetrievePrivateData(cli, mem_ctx,
						&handle,
						&name,
						&val);
	if (!NT_STATUS_IS_OK(status)) {
		goto done;
	}

	status = cli_get_session_key(mem_ctx, cli, &session_key);
	if (!NT_STATUS_IS_OK(status)) {
		goto done;
	}

	if (val) {
		blob = data_blob_const(val->data, val->length);
	}

	secret = sess_decrypt_string(mem_ctx, &blob, &session_key);
	if (secret) {
		d_printf("secret: %s\n", secret);
	}

 done:
	if (is_valid_policy_hnd(&handle)) {
		rpccli_lsa_Close(cli, mem_ctx, &handle);
	}

	return status;
}
Example #3
0
static NTSTATUS cmd_lsa_store_private_data(struct rpc_pipe_client *cli,
					   TALLOC_CTX *mem_ctx, int argc,
					   const char **argv)
{
	NTSTATUS status;
	struct policy_handle handle;
	struct lsa_String name;
	struct lsa_DATA_BUF val;
	DATA_BLOB session_key;
	DATA_BLOB enc_key;

	if (argc < 3) {
		printf("Usage: %s name secret\n", argv[0]);
		return NT_STATUS_OK;
	}

	status = rpccli_lsa_open_policy2(cli, mem_ctx,
					 true,
					 SEC_FLAG_MAXIMUM_ALLOWED,
					 &handle);
	if (!NT_STATUS_IS_OK(status)) {
		return status;
	}

	init_lsa_String(&name, argv[1]);

	ZERO_STRUCT(val);

	status = cli_get_session_key(mem_ctx, cli, &session_key);
	if (!NT_STATUS_IS_OK(status)) {
		goto done;
	}

	enc_key = sess_encrypt_string(argv[2], &session_key);

	val.length = enc_key.length;
	val.size = enc_key.length;
	val.data = enc_key.data;

	status = rpccli_lsa_StorePrivateData(cli, mem_ctx,
					     &handle,
					     &name,
					     &val);
	if (!NT_STATUS_IS_OK(status)) {
		goto done;
	}

 done:
	if (is_valid_policy_hnd(&handle)) {
		rpccli_lsa_Close(cli, mem_ctx, &handle);
	}

	return status;
}
Example #4
0
WERROR NetGetJoinableOUs_r(struct libnetapi_ctx *ctx,
			   struct NetGetJoinableOUs *r)
{
	struct rpc_pipe_client *pipe_cli = NULL;
	struct wkssvc_PasswordBuffer *encrypted_password = NULL;
	NTSTATUS status;
	WERROR werr;
	struct dcerpc_binding_handle *b;
	DATA_BLOB session_key;

	werr = libnetapi_open_pipe(ctx, r->in.server_name,
				   &ndr_table_wkssvc,
				   &pipe_cli);
	if (!W_ERROR_IS_OK(werr)) {
		goto done;
	}

	b = pipe_cli->binding_handle;

	if (r->in.password) {

		status = cli_get_session_key(talloc_tos(), pipe_cli, &session_key);
		if (!NT_STATUS_IS_OK(status)) {
			werr = ntstatus_to_werror(status);
			goto done;
		}

		encode_wkssvc_join_password_buffer(ctx,
						   r->in.password,
						   &session_key,
						   &encrypted_password);
	}

	status = dcerpc_wkssvc_NetrGetJoinableOus2(b, talloc_tos(),
						   r->in.server_name,
						   r->in.domain,
						   r->in.account,
						   encrypted_password,
						   r->out.ou_count,
						   r->out.ous,
						   &werr);
	if (!NT_STATUS_IS_OK(status)) {
		werr = ntstatus_to_werror(status);
		goto done;
	}

 done:
	return werr;
}
Example #5
0
static NTSTATUS cmd_lsa_query_secret(struct rpc_pipe_client *cli,
				     TALLOC_CTX *mem_ctx, int argc,
				     const char **argv)
{
	NTSTATUS status;
	struct policy_handle handle, sec_handle;
	struct lsa_String name;
	struct lsa_DATA_BUF_PTR new_val;
	NTTIME new_mtime = 0;
	struct lsa_DATA_BUF_PTR old_val;
	NTTIME old_mtime = 0;
	DATA_BLOB session_key;
	DATA_BLOB new_blob = data_blob_null;
	DATA_BLOB old_blob = data_blob_null;
	char *new_secret, *old_secret;

	if (argc < 2) {
		printf("Usage: %s name\n", argv[0]);
		return NT_STATUS_OK;
	}

	status = rpccli_lsa_open_policy2(cli, mem_ctx,
					 true,
					 SEC_FLAG_MAXIMUM_ALLOWED,
					 &handle);
	if (!NT_STATUS_IS_OK(status)) {
		return status;
	}

	init_lsa_String(&name, argv[1]);

	status = rpccli_lsa_OpenSecret(cli, mem_ctx,
				       &handle,
				       name,
				       SEC_FLAG_MAXIMUM_ALLOWED,
				       &sec_handle);
	if (!NT_STATUS_IS_OK(status)) {
		goto done;
	}

	ZERO_STRUCT(new_val);
	ZERO_STRUCT(old_val);

	status = rpccli_lsa_QuerySecret(cli, mem_ctx,
					&sec_handle,
					&new_val,
					&new_mtime,
					&old_val,
					&old_mtime);
	if (!NT_STATUS_IS_OK(status)) {
		goto done;
	}

	status = cli_get_session_key(mem_ctx, cli, &session_key);
	if (!NT_STATUS_IS_OK(status)) {
		goto done;
	}

	if (new_val.buf) {
		new_blob = data_blob_const(new_val.buf->data, new_val.buf->length);
	}
	if (old_val.buf) {
		old_blob = data_blob_const(old_val.buf->data, old_val.buf->length);
	}

	new_secret = sess_decrypt_string(mem_ctx, &new_blob, &session_key);
	old_secret = sess_decrypt_string(mem_ctx, &old_blob, &session_key);
	if (new_secret) {
		d_printf("new secret: %s\n", new_secret);
	}
	if (old_secret) {
		d_printf("old secret: %s\n", old_secret);
	}

 done:
	if (is_valid_policy_hnd(&sec_handle)) {
		rpccli_lsa_Close(cli, mem_ctx, &sec_handle);
	}
	if (is_valid_policy_hnd(&handle)) {
		rpccli_lsa_Close(cli, mem_ctx, &handle);
	}

	return status;
}
Example #6
0
static WERROR cmd_drsuapi_getncchanges(struct rpc_pipe_client *cli,
				       TALLOC_CTX *mem_ctx, int argc,
				       const char **argv)
{
	NTSTATUS status;
	WERROR werr;

	struct policy_handle bind_handle;
	struct dcerpc_binding_handle *b = cli->binding_handle;

	struct GUID bind_guid;
	struct drsuapi_DsBindInfoCtr bind_info;
	struct drsuapi_DsBindInfo28 info28;

	const char *nc_dn = NULL;

	DATA_BLOB session_key;

	uint32_t level = 8;
	bool single = false;
	uint32_t level_out = 0;
	union drsuapi_DsGetNCChangesRequest req;
	union drsuapi_DsGetNCChangesCtr ctr;
	struct drsuapi_DsReplicaObjectIdentifier nc;

	struct drsuapi_DsGetNCChangesCtr1 *ctr1 = NULL;
	struct drsuapi_DsGetNCChangesCtr6 *ctr6 = NULL;
	uint32_t out_level = 0;
	int y;

	uint32_t supported_extensions = 0;
	uint32_t replica_flags	= DRSUAPI_DRS_WRIT_REP |
				  DRSUAPI_DRS_INIT_SYNC |
				  DRSUAPI_DRS_PER_SYNC |
				  DRSUAPI_DRS_GET_ANC |
				  DRSUAPI_DRS_NEVER_SYNCED;

	if (argc > 3) {
		printf("usage: %s [naming_context_or_object_dn [single]]\n", argv[0]);
		return WERR_OK;
	}

	if (argc >= 2) {
		nc_dn = argv[1];
	}

	if (argc == 3) {
		if (strequal(argv[2], "single")) {
			single = true;
		} else {
			printf("warning: ignoring unknown argument '%s'\n",
			       argv[2]);
		}
	}

	ZERO_STRUCT(info28);

	ZERO_STRUCT(req);

	GUID_from_string(DRSUAPI_DS_BIND_GUID, &bind_guid);

	info28.supported_extensions	|= DRSUAPI_SUPPORTED_EXTENSION_BASE;
	info28.supported_extensions	|= DRSUAPI_SUPPORTED_EXTENSION_ASYNC_REPLICATION;
	info28.supported_extensions	|= DRSUAPI_SUPPORTED_EXTENSION_REMOVEAPI;
	info28.supported_extensions	|= DRSUAPI_SUPPORTED_EXTENSION_MOVEREQ_V2;
	info28.supported_extensions	|= DRSUAPI_SUPPORTED_EXTENSION_GETCHG_COMPRESS;
	info28.supported_extensions	|= DRSUAPI_SUPPORTED_EXTENSION_DCINFO_V1;
	info28.supported_extensions	|= DRSUAPI_SUPPORTED_EXTENSION_RESTORE_USN_OPTIMIZATION;
	info28.supported_extensions	|= DRSUAPI_SUPPORTED_EXTENSION_KCC_EXECUTE;
	info28.supported_extensions	|= DRSUAPI_SUPPORTED_EXTENSION_ADDENTRY_V2;
	info28.supported_extensions	|= DRSUAPI_SUPPORTED_EXTENSION_LINKED_VALUE_REPLICATION;
	info28.supported_extensions	|= DRSUAPI_SUPPORTED_EXTENSION_DCINFO_V2;
	info28.supported_extensions	|= DRSUAPI_SUPPORTED_EXTENSION_INSTANCE_TYPE_NOT_REQ_ON_MOD;
	info28.supported_extensions	|= DRSUAPI_SUPPORTED_EXTENSION_CRYPTO_BIND;
	info28.supported_extensions	|= DRSUAPI_SUPPORTED_EXTENSION_GET_REPL_INFO;
	info28.supported_extensions	|= DRSUAPI_SUPPORTED_EXTENSION_STRONG_ENCRYPTION;
	info28.supported_extensions	|= DRSUAPI_SUPPORTED_EXTENSION_DCINFO_V01;
	info28.supported_extensions	|= DRSUAPI_SUPPORTED_EXTENSION_TRANSITIVE_MEMBERSHIP;
	info28.supported_extensions	|= DRSUAPI_SUPPORTED_EXTENSION_ADD_SID_HISTORY;
	info28.supported_extensions	|= DRSUAPI_SUPPORTED_EXTENSION_POST_BETA3;
	info28.supported_extensions	|= DRSUAPI_SUPPORTED_EXTENSION_GET_MEMBERSHIPS2;
	info28.supported_extensions	|= DRSUAPI_SUPPORTED_EXTENSION_GETCHGREQ_V6;
	info28.supported_extensions	|= DRSUAPI_SUPPORTED_EXTENSION_NONDOMAIN_NCS;
	info28.supported_extensions	|= DRSUAPI_SUPPORTED_EXTENSION_GETCHGREQ_V8;
	info28.supported_extensions	|= DRSUAPI_SUPPORTED_EXTENSION_GETCHGREPLY_V5;
	info28.supported_extensions	|= DRSUAPI_SUPPORTED_EXTENSION_GETCHGREPLY_V6;
	info28.supported_extensions	|= DRSUAPI_SUPPORTED_EXTENSION_ADDENTRYREPLY_V3;
	info28.supported_extensions	|= DRSUAPI_SUPPORTED_EXTENSION_GETCHGREPLY_V7;
	info28.supported_extensions	|= DRSUAPI_SUPPORTED_EXTENSION_VERIFY_OBJECT;
	info28.site_guid		= GUID_zero();
	info28.pid			= 0;
	info28.repl_epoch		= 0;

	bind_info.length = 28;
	bind_info.info.info28 = info28;

	status = dcerpc_drsuapi_DsBind(b, mem_ctx,
				       &bind_guid,
				       &bind_info,
				       &bind_handle,
				       &werr);

	if (!NT_STATUS_IS_OK(status)) {
		return ntstatus_to_werror(status);
	}

	if (!W_ERROR_IS_OK(werr)) {
		return werr;
	}

	if (bind_info.length == 24) {
		supported_extensions = bind_info.info.info24.supported_extensions;
	} else if (bind_info.length == 28) {
		supported_extensions = bind_info.info.info28.supported_extensions;
	} else if (bind_info.length == 32) {
		supported_extensions = bind_info.info.info32.supported_extensions;
	} else if (bind_info.length == 48) {
		supported_extensions = bind_info.info.info48.supported_extensions;
	} else if (bind_info.length == 52) {
		supported_extensions = bind_info.info.info52.supported_extensions;
	}

	if (!nc_dn) {

		union drsuapi_DsNameCtr crack_ctr;
		const char *name;

		name = talloc_asprintf(mem_ctx, "%s\\", lp_workgroup());
		W_ERROR_HAVE_NO_MEMORY(name);

		werr = cracknames(cli, mem_ctx,
				  &bind_handle,
				  DRSUAPI_DS_NAME_FORMAT_UNKNOWN,
				  DRSUAPI_DS_NAME_FORMAT_FQDN_1779,
				  1,
				  &name,
				  &crack_ctr);
		if (!W_ERROR_IS_OK(werr)) {
			return werr;
		}

		if (crack_ctr.ctr1->count != 1) {
			return WERR_NO_SUCH_DOMAIN;
		}

		if (crack_ctr.ctr1->array[0].status != DRSUAPI_DS_NAME_STATUS_OK) {
			return WERR_NO_SUCH_DOMAIN;
		}

		nc_dn = talloc_strdup(mem_ctx, crack_ctr.ctr1->array[0].result_name);
		W_ERROR_HAVE_NO_MEMORY(nc_dn);

		printf("using: %s\n", nc_dn);
	}

	nc.dn = nc_dn;
	nc.guid = GUID_zero();
	nc.sid = (struct dom_sid) {0};

	if (supported_extensions & DRSUAPI_SUPPORTED_EXTENSION_GETCHGREQ_V8) {
		level = 8;
		req.req8.naming_context		= &nc;
		req.req8.replica_flags		= replica_flags;
		req.req8.max_object_count	= 402;
		req.req8.max_ndr_size		= 402116;
		if (single) {
			req.req8.extended_op	= DRSUAPI_EXOP_REPL_OBJ;
		}
	} else {
		level = 5;
		req.req5.naming_context		= &nc;
		req.req5.replica_flags		= replica_flags;
		req.req5.max_object_count	= 402;
		req.req5.max_ndr_size		= 402116;
		if (single) {
			req.req5.extended_op	= DRSUAPI_EXOP_REPL_OBJ;
		}
	}

	for (y=0; ;y++) {

		if (level == 8) {
			DEBUG(1,("start[%d] tmp_higest_usn: %llu , highest_usn: %llu\n",y,
				(long long)req.req8.highwatermark.tmp_highest_usn,
				(long long)req.req8.highwatermark.highest_usn));
		}

		status = dcerpc_drsuapi_DsGetNCChanges(b, mem_ctx,
						       &bind_handle,
						       level,
						       &req,
						       &level_out,
						       &ctr,
						       &werr);
		if (!NT_STATUS_IS_OK(status)) {
			werr = ntstatus_to_werror(status);
			printf("Failed to get NC Changes: %s",
				get_friendly_nt_error_msg(status));
			goto out;
		}

		if (!W_ERROR_IS_OK(werr)) {
			printf("Failed to get NC Changes: %s",
				get_friendly_werror_msg(werr));
			goto out;
		}

		if (level_out == 1) {
			out_level = 1;
			ctr1 = &ctr.ctr1;
		} else if (level_out == 2 && ctr.ctr2.mszip1.ts) {
			out_level = 1;
			ctr1 = &ctr.ctr2.mszip1.ts->ctr1;
		}

		status = cli_get_session_key(mem_ctx, cli, &session_key);
		if (!NT_STATUS_IS_OK(status)) {
			printf("Failed to get Session Key: %s",
				nt_errstr(status));
			return ntstatus_to_werror(status);
		}

		if (out_level == 1) {
			DEBUG(1,("end[%d] tmp_highest_usn: %llu , highest_usn: %llu\n",y,
				(long long)ctr1->new_highwatermark.tmp_highest_usn,
				(long long)ctr1->new_highwatermark.highest_usn));
#if 0
			libnet_dssync_decrypt_attributes(mem_ctx,
							 &session_key,
							 ctr1->first_object);
#endif
			if (ctr1->more_data) {
				req.req5.highwatermark = ctr1->new_highwatermark;
				continue;
			}
		}

		if (level_out == 6) {
			out_level = 6;
			ctr6 = &ctr.ctr6;
		} else if (level_out == 7
			   && ctr.ctr7.level == 6
			   && ctr.ctr7.type == DRSUAPI_COMPRESSION_TYPE_MSZIP
			   && ctr.ctr7.ctr.mszip6.ts) {
			out_level = 6;
			ctr6 = &ctr.ctr7.ctr.mszip6.ts->ctr6;
		} else if (level_out == 7
			   && ctr.ctr7.level == 6
			   && ctr.ctr7.type == DRSUAPI_COMPRESSION_TYPE_XPRESS
			   && ctr.ctr7.ctr.xpress6.ts) {
			out_level = 6;
			ctr6 = &ctr.ctr7.ctr.xpress6.ts->ctr6;
		}

		if (out_level == 6) {
			DEBUG(1,("end[%d] tmp_highest_usn: %llu , highest_usn: %llu\n",y,
				(long long)ctr6->new_highwatermark.tmp_highest_usn,
				(long long)ctr6->new_highwatermark.highest_usn));
#if 0
			libnet_dssync_decrypt_attributes(mem_ctx,
							 &session_key,
							 ctr6->first_object);
#endif
			if (ctr6->more_data) {
				req.req8.highwatermark = ctr6->new_highwatermark;
				continue;
			}
		}

		break;
	}

 out:
	return werr;
}

/* List of commands exported by this module */

struct cmd_set drsuapi_commands[] = {

	{ "DRSUAPI" },
	{ "dscracknames", RPC_RTYPE_WERROR, NULL, cmd_drsuapi_cracknames, &ndr_table_drsuapi, NULL, "Crack Name", "" },
	{ "dsgetdcinfo", RPC_RTYPE_WERROR, NULL, cmd_drsuapi_getdcinfo, &ndr_table_drsuapi, NULL, "Get Domain Controller Info", "" },
	{ "dsgetncchanges", RPC_RTYPE_WERROR, NULL, cmd_drsuapi_getncchanges, &ndr_table_drsuapi, NULL, "Get NC Changes", "" },
	{ "dswriteaccountspn", RPC_RTYPE_WERROR, NULL, cmd_drsuapi_writeaccountspn, &ndr_table_drsuapi, NULL, "Write Account SPN", "" },
	{ NULL }
};
static NTSTATUS connect_and_get_info(TALLOC_CTX *mem_ctx,
				     struct net_context *net_ctx,
				     struct cli_state **cli,
				     struct rpc_pipe_client **pipe_hnd,
				     struct policy_handle *pol_hnd,
				     struct dom_data *dom_data,
				     DATA_BLOB *session_key)
{
	NTSTATUS status;
	NTSTATUS result;

	status = net_make_ipc_connection_ex(net_ctx, NULL, NULL, NULL,
					    NET_FLAGS_PDC, cli);
	if (!NT_STATUS_IS_OK(status)) {
		DEBUG(0, ("Failed to connect to [%s] with error [%s]\n",
			  net_ctx->opt_host, nt_errstr(status)));
		return status;
	}

	status = cli_rpc_pipe_open_noauth(*cli, &ndr_table_lsarpc.syntax_id, pipe_hnd);
	if (!NT_STATUS_IS_OK(status)) {
		DEBUG(0, ("Failed to initialise lsa pipe with error [%s]\n",
			  nt_errstr(status)));
		return status;
	}

	status = dcerpc_lsa_open_policy2((*pipe_hnd)->binding_handle,
					 mem_ctx,
					 (*pipe_hnd)->srv_name_slash,
					 false,
					 (LSA_POLICY_VIEW_LOCAL_INFORMATION |
					  LSA_POLICY_TRUST_ADMIN |
					  LSA_POLICY_CREATE_SECRET),
					 pol_hnd,
					 &result);
	if (!NT_STATUS_IS_OK(status)) {
		DEBUG(0, ("Failed to open policy handle with error [%s]\n",
			  nt_errstr(status)));
		return status;
	}
	if (!NT_STATUS_IS_OK(result)) {
		DEBUG(0, ("lsa_open_policy2 with error [%s]\n",
			  nt_errstr(result)));
		return result;
	}

	status = get_domain_info(mem_ctx, (*pipe_hnd)->binding_handle,
				 pol_hnd, dom_data);
	if (!NT_STATUS_IS_OK(status)) {
		DEBUG(0, ("get_domain_info failed with error [%s].\n",
			  nt_errstr(status)));
		return status;
	}

	status = cli_get_session_key(mem_ctx, *pipe_hnd, session_key);
	if (!NT_STATUS_IS_OK(status)) {
		DEBUG(0,("Error getting session_key of LSA pipe. Error was %s\n",
			nt_errstr(status)));
		return status;
	}

	return NT_STATUS_OK;
}