|
|
2a7aec |
/*********************************************************/
|
|
|
2a7aec |
/* toksvc: a framework-native token broker service */
|
|
|
d91fa0 |
/* Copyright (C) 2020 SysDeer Technologies, LLC */
|
|
|
2a7aec |
/* Released under GPLv2 and GPLv3; see COPYING.TOKSVC. */
|
|
|
2a7aec |
/*********************************************************/
|
|
|
2a7aec |
|
|
|
2a7aec |
#include <psxtypes/psxtypes.h>
|
|
|
2a7aec |
#include <ntapi/ntapi.h>
|
|
|
2a7aec |
|
|
|
2a7aec |
#include <toksvc/toksvc.h>
|
|
|
2a7aec |
#include "toksvc_driver_impl.h"
|
|
|
2a7aec |
|
|
|
2eea44 |
static const uint32_t toks_sd_access_bits[8] = {
|
|
|
2eea44 |
0,
|
|
|
2eea44 |
NT_GENERIC_EXECUTE,
|
|
|
2eea44 |
NT_GENERIC_WRITE,
|
|
|
2eea44 |
NT_GENERIC_WRITE | NT_GENERIC_EXECUTE,
|
|
|
2eea44 |
NT_GENERIC_READ,
|
|
|
2eea44 |
NT_GENERIC_READ | NT_GENERIC_EXECUTE ,
|
|
|
2eea44 |
NT_GENERIC_READ | NT_GENERIC_WRITE,
|
|
|
2eea44 |
NT_GENERIC_READ | NT_GENERIC_WRITE | NT_GENERIC_EXECUTE
|
|
|
2eea44 |
};
|
|
|
2eea44 |
|
|
|
2eea44 |
static nt_sd * toks_fsfile_sd(
|
|
|
2eea44 |
nt_sd_common_buffer * sd,
|
|
|
2eea44 |
uint32_t mode)
|
|
|
2eea44 |
{
|
|
|
2eea44 |
uint32_t access_owner;
|
|
|
2eea44 |
uint32_t access_group;
|
|
|
2eea44 |
uint32_t access_other;
|
|
|
2eea44 |
uint32_t access_admin;
|
|
|
2eea44 |
nt_sid * admin_sid;
|
|
|
2eea44 |
|
|
|
2eea44 |
access_owner = (((mode & 0700) >> 6) == 7)
|
|
|
2eea44 |
? NT_GENERIC_ALL | NT_SEC_SPECIFIC_RIGHTS_ALL
|
|
|
2eea44 |
: toks_sd_access_bits[(mode & 0700) >> 6]
|
|
|
2eea44 |
| NT_SEC_STANDARD_RIGHTS_ALL;
|
|
|
2eea44 |
|
|
|
2eea44 |
access_group = toks_sd_access_bits[(mode & 0070) >> 3];
|
|
|
2eea44 |
access_group |= NT_SEC_READ_CONTROL|NT_FILE_READ_ATTRIBUTES;
|
|
|
2eea44 |
|
|
|
2eea44 |
access_other = toks_sd_access_bits[(mode & 0007) >> 0];
|
|
|
2eea44 |
access_other |= NT_SEC_READ_CONTROL|NT_FILE_READ_ATTRIBUTES;
|
|
|
2eea44 |
|
|
|
2eea44 |
admin_sid = 0;
|
|
|
2eea44 |
access_admin = access_owner;
|
|
|
2eea44 |
|
|
|
2eea44 |
ntapi->acl_init_common_descriptor(
|
|
|
2eea44 |
sd,0,0,
|
|
|
2eea44 |
0,admin_sid,
|
|
|
2eea44 |
access_owner,access_group,access_other,
|
|
|
2eea44 |
access_admin,access_owner,
|
|
|
2eea44 |
0);
|
|
|
2eea44 |
|
|
|
2eea44 |
return &sd->sd;
|
|
|
2eea44 |
}
|
|
|
2eea44 |
|
|
|
2a7aec |
static int32_t toks_open(
|
|
|
2a7aec |
void ** hfile,
|
|
|
2a7aec |
void * hat,
|
|
|
2a7aec |
const char * arg,
|
|
|
039b11 |
nt_sd * sd,
|
|
|
039b11 |
uint32_t attr,
|
|
|
2a7aec |
uint32_t options,
|
|
|
039b11 |
uint32_t disposition,
|
|
|
2a7aec |
bool fprivate)
|
|
|
2a7aec |
{
|
|
|
2a7aec |
int32_t status;
|
|
|
2a7aec |
nt_oa oa;
|
|
|
2a7aec |
nt_iosb iosb;
|
|
|
2a7aec |
nt_unicode_string path;
|
|
|
2a7aec |
nt_unicode_conversion_params_utf8_to_utf16 params = {0,0,0,0,0,0,0,0,0};
|
|
|
2a7aec |
wchar16_t buffer[4096];
|
|
|
2a7aec |
wchar16_t * wch;
|
|
|
df6163 |
wchar16_t * mark;
|
|
|
df6163 |
wchar16_t * cap;
|
|
|
df6163 |
uint16_t nbytes;
|
|
|
039b11 |
uint32_t access;
|
|
|
039b11 |
nt_large_integer alloc_size;
|
|
|
2a7aec |
|
|
|
2a7aec |
/* utf-8 --> utf-16 */
|
|
|
2a7aec |
params.src = (const unsigned char *)arg;
|
|
|
2a7aec |
params.src_size_in_bytes= ntapi->tt_string_null_offset_multibyte(arg);
|
|
|
2a7aec |
params.dst = buffer;
|
|
|
2a7aec |
params.dst_size_in_bytes= sizeof(buffer);
|
|
|
2a7aec |
|
|
|
2a7aec |
if ((status = ntapi->uc_convert_unicode_stream_utf8_to_utf16(¶ms)))
|
|
|
2a7aec |
return status;
|
|
|
2a7aec |
|
|
|
2a7aec |
/* convenience */
|
|
|
df6163 |
if ((mark = buffer) && (nbytes = params.bytes_written)) {
|
|
|
df6163 |
if (mark[0] == '/') {
|
|
|
df6163 |
mark++;
|
|
|
df6163 |
nbytes -= sizeof(uint16_t);
|
|
|
df6163 |
} else if (mark[0] == '\\') {
|
|
|
df6163 |
hat = 0;
|
|
|
df6163 |
}
|
|
|
df6163 |
}
|
|
|
df6163 |
|
|
|
df6163 |
for (wch=mark,cap=&wch[nbytes/sizeof(uint16_t)]; wch
|
|
|
2a7aec |
if (*wch == '/')
|
|
|
2a7aec |
*wch = '\\';
|
|
|
2a7aec |
|
|
|
2a7aec |
/* path */
|
|
|
2a7aec |
path.maxlen = 0;
|
|
|
df6163 |
path.strlen = nbytes;
|
|
|
df6163 |
path.buffer = mark;
|
|
|
2a7aec |
|
|
|
2a7aec |
/* oa */
|
|
|
2a7aec |
oa.len = sizeof(nt_oa);
|
|
|
df6163 |
oa.root_dir = hat;
|
|
|
2a7aec |
oa.obj_name = &pat;;
|
|
|
2a7aec |
oa.obj_attr = fprivate ? 0 : NT_OBJ_INHERIT;
|
|
|
039b11 |
oa.sec_desc = sd;
|
|
|
2a7aec |
oa.sec_qos = 0;
|
|
|
2a7aec |
|
|
|
039b11 |
/* alloc_size (always zero) */
|
|
|
039b11 |
alloc_size.quad = 0;
|
|
|
039b11 |
|
|
|
039b11 |
/* access */
|
|
|
039b11 |
access = NT_SEC_SYNCHRONIZE | NT_FILE_READ_ATTRIBUTES | NT_FILE_READ_DATA;
|
|
|
039b11 |
access |= (disposition == NT_FILE_OPEN_IF) ? NT_FILE_WRITE_DATA : 0;
|
|
|
039b11 |
|
|
|
039b11 |
/* open/create */
|
|
|
039b11 |
return ntapi->zw_create_file(
|
|
|
2a7aec |
hfile,
|
|
|
039b11 |
access,&oa,&iosb,&alloc_size,attr,
|
|
|
2a7aec |
NT_FILE_SHARE_READ | NT_FILE_SHARE_WRITE | NT_FILE_SHARE_DELETE,
|
|
|
039b11 |
disposition,
|
|
|
039b11 |
options | NT_FILE_SYNCHRONOUS_IO_ALERT,
|
|
|
039b11 |
0,0);
|
|
|
2a7aec |
}
|
|
|
2a7aec |
|
|
|
2a7aec |
static int32_t toks_open_volume(
|
|
|
2a7aec |
void ** hfile,
|
|
|
2a7aec |
void * hat,
|
|
|
2a7aec |
const char * arg,
|
|
|
039b11 |
nt_sd * sd,
|
|
|
039b11 |
uint32_t attr,
|
|
|
2a7aec |
uint32_t options,
|
|
|
039b11 |
uint32_t disposition,
|
|
|
2a7aec |
bool fprivate)
|
|
|
2a7aec |
{
|
|
|
2a7aec |
int32_t status;
|
|
|
2a7aec |
void * hvolume = 0;
|
|
|
2a7aec |
wchar16_t drive = arg[0];
|
|
|
2a7aec |
|
|
|
2a7aec |
if ((arg[1]==':') && ((arg[2]=='\\') || (arg[2]=='/'))) {
|
|
|
2a7aec |
if ((status = ntapi->tt_get_dos_drive_root_handle(
|
|
|
2a7aec |
&hvolume,drive)))
|
|
|
2a7aec |
return status;
|
|
|
2a7aec |
|
|
|
2a7aec |
hat = hvolume;
|
|
|
2a7aec |
arg = &arg[3];
|
|
|
2a7aec |
}
|
|
|
2a7aec |
|
|
|
2a7aec |
status = toks_open(
|
|
|
039b11 |
hfile,hat,arg,sd,attr,
|
|
|
039b11 |
options,disposition,
|
|
|
039b11 |
fprivate);
|
|
|
2a7aec |
|
|
|
2a7aec |
if (hvolume)
|
|
|
2a7aec |
ntapi->zw_close(hvolume);
|
|
|
2a7aec |
|
|
|
2a7aec |
return status;
|
|
|
2a7aec |
}
|
|
|
2a7aec |
|
|
|
2a7aec |
int32_t toks_open_file(void ** hfile, void * hat, const char * arg, bool fprivate)
|
|
|
2a7aec |
{
|
|
|
039b11 |
return toks_open_volume(
|
|
|
039b11 |
hfile,hat,arg,0,
|
|
|
039b11 |
NT_FILE_ATTRIBUTE_NORMAL,
|
|
|
039b11 |
NT_FILE_NON_DIRECTORY_FILE,
|
|
|
039b11 |
NT_FILE_OPEN,
|
|
|
039b11 |
fprivate);
|
|
|
2a7aec |
}
|
|
|
2a7aec |
|
|
|
2eea44 |
int32_t toks_open_log_file(void ** hfile, void * hat, const char * arg, bool fprivate)
|
|
|
2eea44 |
{
|
|
|
2eea44 |
int32_t status;
|
|
|
2eea44 |
nt_iosb iosb;
|
|
|
2eea44 |
nt_fsi fsi;
|
|
|
2eea44 |
nt_fpi fpi;
|
|
|
2eea44 |
nt_sd_common_buffer sd;
|
|
|
2eea44 |
|
|
|
2eea44 |
if ((status = toks_open_volume(
|
|
|
2eea44 |
hfile,hat,arg,
|
|
|
2eea44 |
toks_fsfile_sd(&sd,0644),
|
|
|
2eea44 |
NT_FILE_ATTRIBUTE_NORMAL,
|
|
|
2eea44 |
NT_FILE_NON_DIRECTORY_FILE,
|
|
|
2eea44 |
NT_FILE_OPEN_IF,
|
|
|
2eea44 |
fprivate)))
|
|
|
2eea44 |
return status;
|
|
|
2eea44 |
|
|
|
2eea44 |
status = ntapi->zw_query_information_file(
|
|
|
2eea44 |
*hfile,&iosb,
|
|
|
2eea44 |
&fsi,sizeof(fsi),
|
|
|
2eea44 |
NT_FILE_STANDARD_INFORMATION);
|
|
|
2eea44 |
|
|
|
2eea44 |
if (status) {
|
|
|
2eea44 |
ntapi->zw_close(*hfile);
|
|
|
2eea44 |
return status;
|
|
|
2eea44 |
}
|
|
|
2eea44 |
|
|
|
2eea44 |
fpi.current_byte_offset.quad = fsi.end_of_file.quad;
|
|
|
2eea44 |
|
|
|
2eea44 |
status = ntapi->zw_set_information_file(
|
|
|
2eea44 |
*hfile,&iosb,
|
|
|
2eea44 |
&fpi,sizeof(fpi),
|
|
|
2eea44 |
NT_FILE_POSITION_INFORMATION);
|
|
|
2eea44 |
|
|
|
2eea44 |
if (status) {
|
|
|
2eea44 |
ntapi->zw_close(*hfile);
|
|
|
2eea44 |
return status;
|
|
|
2eea44 |
}
|
|
|
2eea44 |
|
|
|
2eea44 |
return NT_STATUS_SUCCESS;
|
|
|
2eea44 |
}
|
|
|
2eea44 |
|
|
|
2a7aec |
int32_t toks_open_dir(void ** hfile, void * hat, const char * arg, bool fprivate)
|
|
|
2a7aec |
{
|
|
|
039b11 |
return toks_open_volume(
|
|
|
039b11 |
hfile,hat,arg,0,
|
|
|
039b11 |
NT_FILE_ATTRIBUTE_DIRECTORY,
|
|
|
039b11 |
NT_FILE_DIRECTORY_FILE,
|
|
|
039b11 |
NT_FILE_OPEN,
|
|
|
039b11 |
fprivate);
|
|
|
2a7aec |
}
|