Blame src/internal/toksvc_open_impl.c

2a7aec
/*********************************************************/
2a7aec
/*  toksvc: a framework-native token broker service      */
2a7aec
/*  Copyright (C) 2020  Z. Gilboa                        */
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(&params)))
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
}