/*********************************************************/
/* toksvc: a framework-native token broker service */
/* Copyright (C) 2020 Z. Gilboa */
/* Released under GPLv2 and GPLv3; see COPYING.TOKSVC. */
/*********************************************************/
#include <psxtypes/psxtypes.h>
#include <ntapi/ntapi.h>
#include <toksvc/toksvc.h>
#include "toksvc_driver_impl.h"
#include "toksvc_daemon_impl.h"
int32_t toks_get_server_snapshot(
struct toks_driver_ctx * dctx,
struct toks_server_snapshot ** snapshot)
{
int32_t status;
void * hport;
void * hfile;
void * hsection;
void * addr;
size_t size;
nt_oa oa;
nt_large_integer ssize;
nt_sd_common_buffer sd;
struct _nt_tty_port_msg msg;
struct toks_server_snapshot * ctx;
struct toks_service_info * svcinfo;
uint32_t access_owner;
uint32_t access_group;
uint32_t access_other;
uint32_t access_admin;
hport = toks_get_driver_hservice(dctx);
ntapi->tt_aligned_block_memset(
&msg,0,sizeof(msg));
msg.header.msg_type = NT_LPC_NEW_MESSAGE;
msg.header.data_size = sizeof(msg.ttyinfo) + sizeof(msg.svcdata);
msg.header.msg_size = sizeof(msg);
msg.ttyinfo.opcode = TOKS_DAEMON_IOCTL;
msg.ttyinfo.opdata = TOKS_IOCTL_GET_TOKEN_INFO;
if ((status = ntapi->zw_request_wait_reply_port(hport,&msg,&msg)))
return status;
else if (msg.ttyinfo.status)
return msg.ttyinfo.status;
/* token info */
hfile = msg.ttyinfo.exarg;
/* snapshot context */
if (!(addr = toks_calloc(1,sizeof(*ctx)))) {
ntapi->zw_close(hfile);
return NT_STATUS_MEMORY_NOT_ALLOCATED;
}
ctx = (struct toks_server_snapshot *)addr;
svcinfo = (struct toks_service_info *)addr;
/* uuid */
svcinfo->uuid.data1 = (msg.svcdata.meta[0]);
svcinfo->uuid.data2 = (msg.svcdata.meta[1] & 0xffff);
svcinfo->uuid.data3 = (msg.svcdata.meta[1] >> 16);
svcinfo->uuid.data4[0] = (msg.svcdata.meta[2] & 0xff);
svcinfo->uuid.data4[1] = (msg.svcdata.meta[2] & 0xff00) >> 8;
svcinfo->uuid.data4[2] = (msg.svcdata.meta[2] & 0xff0000) >> 16;
svcinfo->uuid.data4[3] = (msg.svcdata.meta[2] & 0xff000000) >> 24;
svcinfo->uuid.data4[4] = (msg.svcdata.meta[3] & 0xff);
svcinfo->uuid.data4[5] = (msg.svcdata.meta[3] & 0xff00) >> 8;
svcinfo->uuid.data4[6] = (msg.svcdata.meta[3] & 0xff0000) >> 16;
svcinfo->uuid.data4[7] = (msg.svcdata.meta[3] & 0xff000000) >> 24;
/* syspid, systid */
svcinfo->syspid = msg.svcdata.data[0];
svcinfo->systid = msg.svcdata.data[1];
/* ctrlpid, csyspid */
svcinfo->ctrlpid = msg.svcdata.data[2];
svcinfo->csyspid = msg.svcdata.data[3];
/* allocated, available, pending */
svcinfo->allocated = msg.svcdata.data[4];
svcinfo->available = msg.svcdata.data[5];
svcinfo->pending = msg.svcdata.data[6];
/* used, free */
svcinfo->tused = msg.svcdata.data[7];
svcinfo->tfree = msg.svcdata.data[8];
/* sd */
access_owner = NT_GENERIC_READ;
access_group = NT_SEC_READ_CONTROL | NT_FILE_READ_ATTRIBUTES;
access_other = NT_SEC_READ_CONTROL | NT_FILE_READ_ATTRIBUTES;
access_owner |= NT_SEC_STANDARD_RIGHTS_ALL;
access_admin = access_owner;
ntapi->acl_init_common_descriptor(
&sd,0,0,0,0,
access_owner,access_group,access_other,
access_admin,access_owner,
0);
/* section */
oa.len = sizeof(oa);
oa.root_dir = 0;
oa.obj_name = 0;
oa.obj_attr = 0;
oa.sec_desc = &sd.sd;
oa.sec_qos = 0;
addr = 0;
ssize.quad = 0;
size = __offsetof(struct toks_token_ctx,tokens);
size += svcinfo->tused * sizeof(struct toks_token_info);
status = ntapi->zw_create_section(
&hsection,
NT_SECTION_QUERY|NT_SECTION_MAP_READ,
&oa,&ssize,
NT_PAGE_READONLY,
NT_SEC_COMMIT,
hfile);
if (status) {
ntapi->zw_close(hfile);
toks_free(ctx);
return status;
};
/* section mapping */
status = ntapi->zw_map_view_of_section(
hsection,
NT_CURRENT_PROCESS_HANDLE,
&addr,0,0,0,
&size,NT_VIEW_UNMAP,
0,NT_PAGE_READONLY);
ntapi->zw_close(hfile);
ntapi->zw_close(hsection);
if (status) {
toks_free(ctx);
return status;
};
/* all done */
ctx->tokctx = addr;
*snapshot = ctx;
return NT_STATUS_SUCCESS;
}
void toks_free_server_snapshot(struct toks_server_snapshot * snapshot)
{
ntapi->zw_unmap_view_of_section(
NT_CURRENT_PROCESS_HANDLE,
(void *)snapshot->tokctx);
toks_free(snapshot);
}