static NTSTATUS dcesrv_lsa_OpenSecret(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
			       struct lsa_OpenSecret *r)
{
	struct auth_session_info *session_info =
		dcesrv_call_session_info(dce_call);
	struct dcesrv_handle *policy_handle;
	struct lsa_policy_state *policy_state;
	struct lsa_secret_state *secret_state;
	struct dcesrv_handle *handle;
	struct ldb_message **msgs;
	const char *attrs[] = {
		NULL
	};
	const char *name;
	int ret;

	DCESRV_PULL_HANDLE(policy_handle, r->in.handle, LSA_HANDLE_POLICY);
	ZERO_STRUCTP(r->out.sec_handle);
	policy_state = policy_handle->data;

	if (!r->in.name.string) {
		return NT_STATUS_INVALID_PARAMETER;
	}

	switch (security_session_user_level(session_info, NULL))
	{
	case SECURITY_SYSTEM:
	case SECURITY_ADMINISTRATOR:
		break;
	default:
		/* Users and annonymous are not allowed to access secrets */
		return NT_STATUS_ACCESS_DENIED;
	}

	secret_state = talloc(mem_ctx, struct lsa_secret_state);
	if (!secret_state) {
		return NT_STATUS_NO_MEMORY;
	}
	secret_state->policy = policy_state;

	if (strncmp("G$", r->in.name.string, 2) == 0) {
		name = &r->in.name.string[2];
		/*
		 * We need to connect to the database as system, as this is
		 * one of the rare RPC calls that must read the secrets
		 * (and this is denied otherwise)
		 *
		 * We also save the current remote session details so they can
		 * used by the audit logging module. This allows the audit
		 * logging to report the remote users details, rather than the
		 * system users details.
		 */
		secret_state->sam_ldb =
			dcesrv_samdb_connect_as_system(secret_state, dce_call);
		NT_STATUS_HAVE_NO_MEMORY(secret_state->sam_ldb);
		secret_state->global = true;

		if (strlen(name) < 1) {
			return NT_STATUS_INVALID_PARAMETER;
		}

		/* search for the secret record */
		ret = gendb_search(secret_state->sam_ldb,
				   mem_ctx, policy_state->system_dn, &msgs, attrs,
				   "(&(cn=%s Secret)(objectclass=secret))",
				   ldb_binary_encode_string(mem_ctx, name));
		if (ret == 0) {
			return NT_STATUS_OBJECT_NAME_NOT_FOUND;
		}

		if (ret != 1) {
			DEBUG(0,("Found %d records matching DN %s\n", ret,
				 ldb_dn_get_linearized(policy_state->system_dn)));
			return NT_STATUS_INTERNAL_DB_CORRUPTION;
		}
	} else {
		secret_state->global = false;
		secret_state->sam_ldb = secrets_db_connect(secret_state,
					dce_call->conn->dce_ctx->lp_ctx);
		NT_STATUS_HAVE_NO_MEMORY(secret_state->sam_ldb);

		name = r->in.name.string;
		if (strlen(name) < 1) {
			return NT_STATUS_INVALID_PARAMETER;
		}

		/* search for the secret record */
		ret = gendb_search(secret_state->sam_ldb, mem_ctx,
				   ldb_dn_new(mem_ctx, secret_state->sam_ldb, "cn=LSA Secrets"),
				   &msgs, attrs,
				   "(&(cn=%s)(objectclass=secret))",
				   ldb_binary_encode_string(mem_ctx, name));
		if (ret == 0) {
			return NT_STATUS_OBJECT_NAME_NOT_FOUND;
		}

		if (ret != 1) {
			DEBUG(0,("Found %d records matching CN=%s\n",
				 ret, ldb_binary_encode_string(mem_ctx, name)));
			return NT_STATUS_INTERNAL_DB_CORRUPTION;
		}
	}

	secret_state->secret_dn = talloc_reference(secret_state, msgs[0]->dn);

	handle = dcesrv_handle_create(dce_call, LSA_HANDLE_SECRET);
	if (!handle) {
		return NT_STATUS_NO_MEMORY;
	}

	handle->data = talloc_steal(handle, secret_state);

	secret_state->access_mask = r->in.access_mask;
	secret_state->policy = talloc_reference(secret_state, policy_state);

	*r->out.sec_handle = handle->wire_handle;

	return NT_STATUS_OK;
}
static NTSTATUS dcesrv_lsa_OpenSecret(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
			       struct lsa_OpenSecret *r)
{
	struct auth_session_info *session_info =
		dcesrv_call_session_info(dce_call);
	struct dcesrv_handle *policy_handle;
	struct lsa_policy_state *policy_state;
	struct lsa_secret_state *secret_state;
	struct dcesrv_handle *handle;
	struct ldb_message **msgs;
	const char *attrs[] = {
		NULL
	};
	const char *name;
	int ret;

	DCESRV_PULL_HANDLE(policy_handle, r->in.handle, LSA_HANDLE_POLICY);
	ZERO_STRUCTP(r->out.sec_handle);
	policy_state = policy_handle->data;

	if (!r->in.name.string) {
		return NT_STATUS_INVALID_PARAMETER;
	}

	switch (security_session_user_level(session_info, NULL))
	{
	case SECURITY_SYSTEM:
	case SECURITY_ADMINISTRATOR:
		break;
	default:
		 
		return NT_STATUS_ACCESS_DENIED;
	}

	secret_state = talloc(mem_ctx, struct lsa_secret_state);
	if (!secret_state) {
		return NT_STATUS_NO_MEMORY;
	}
	secret_state->policy = policy_state;

	if (strncmp("G$", r->in.name.string, 2) == 0) {
		name = &r->in.name.string[2];
		 
		secret_state->sam_ldb =
			dcesrv_samdb_connect_as_system(secret_state, dce_call);
		NT_STATUS_HAVE_NO_MEMORY(secret_state->sam_ldb);
		secret_state->global = true;

		if (strlen(name) < 1) {
			return NT_STATUS_INVALID_PARAMETER;
		}

		 
		ret = gendb_search(secret_state->sam_ldb,
				   mem_ctx, policy_state->system_dn, &msgs, attrs,
				   "(&(cn=%s Secret)(objectclass=secret))",
				   ldb_binary_encode_string(mem_ctx, name));
		if (ret == 0) {
			return NT_STATUS_OBJECT_NAME_NOT_FOUND;
		}

		if (ret != 1) {
			DEBUG(0,("Found %d records matching DN %s\n", ret,
				 ldb_dn_get_linearized(policy_state->system_dn)));
			return NT_STATUS_INTERNAL_DB_CORRUPTION;
		}
	} else {
		secret_state->global = false;
		secret_state->sam_ldb = secrets_db_connect(secret_state,
					dce_call->conn->dce_ctx->lp_ctx);
		NT_STATUS_HAVE_NO_MEMORY(secret_state->sam_ldb);

		name = r->in.name.string;
		if (strlen(name) < 1) {
			return NT_STATUS_INVALID_PARAMETER;
		}

		 
		ret = gendb_search(secret_state->sam_ldb, mem_ctx,
				   ldb_dn_new(mem_ctx, secret_state->sam_ldb, "cn=LSA Secrets"),
				   &msgs, attrs,
				   "(&(cn=%s)(objectclass=secret))",
				   ldb_binary_encode_string(mem_ctx, name));
		if (ret == 0) {
			return NT_STATUS_OBJECT_NAME_NOT_FOUND;
		}

		if (ret != 1) {
			DEBUG(0,("Found %d records matching CN=%s\n",
				 ret, ldb_binary_encode_string(mem_ctx, name)));
			return NT_STATUS_INTERNAL_DB_CORRUPTION;
		}
	}

	secret_state->secret_dn = talloc_reference(secret_state, msgs[0]->dn);

	handle = dcesrv_handle_create(dce_call, LSA_HANDLE_SECRET);
	if (!handle) {
		return NT_STATUS_NO_MEMORY;
	}

	handle->data = talloc_steal(handle, secret_state);

	secret_state->access_mask = r->in.access_mask;
	secret_state->policy = talloc_reference(secret_state, policy_state);

	*r->out.sec_handle = handle->wire_handle;

	return NT_STATUS_OK;
}