Blame src/cmds/ntux_cmd_aceit.c

dcb685
/***********************************************************/
dcb685
/*  ntux: native translation und extension                 */
dcb685
/*  Copyright (C) 2016--2022  SysDeer Technologies, LLC    */
dcb685
/*  Released under GPLv2 and GPLv3; see COPYING.NTUX.      */
dcb685
/***********************************************************/
dcb685
dcb685
#include <psxabi/sys_sysapi.h>
dcb685
#include <psxabi/sys_stat.h>
dcb685
#include <psxabi/sys_errno.h>
dcb685
dcb685
#include <psxxfi/xfi_base.h>
dcb685
#include <psxxfi/xfi_acl.h>
dcb685
#include <psxxfi/xfi_fs.h>
dcb685
#include <psxxfi/xfi_ofd.h>
dcb685
#include <psxxfi/xfi_unicode.h>
dcb685
dcb685
#include <ntapi/nt_object.h>
dcb685
#include <ntapi/nt_acl.h>
dcb685
#include <ntapi/nt_file.h>
dcb685
dcb685
#include <ntux/ntux.h>
dcb685
#include "ntux_driver_impl.h"
dcb685
#include "ntux_nolibc_impl.h"
dcb685
#include "ntux_errinfo_impl.h"
dcb685
dcb685
dcb685
struct ntux_ace_any {
dcb685
        nt_ace_header   header;
dcb685
        uint32_t        mask;
dcb685
        uint32_t        sid_start;
dcb685
};
dcb685
dcb685
dcb685
struct ntux_sid_any {
dcb685
        unsigned char                   revision;
dcb685
        unsigned char                   sub_authority_count;
dcb685
        nt_sid_identifier_authority     identifier_authority;
dcb685
        uint32_t                        sub_authority[];
dcb685
};
dcb685
dcb685
dcb685
static int ntux_cmd_aceit_ret(int fd, struct __ofd * ofd, void * hasync, int ret)
dcb685
{
dcb685
	if (hasync)
dcb685
		__xfi_close_handle(hasync);
dcb685
dcb685
	if (ofd)
dcb685
		__xfi_ofd_ref_dec(ofd);
dcb685
dcb685
	if (fd >= 0)
dcb685
		__sys_close(fd);
dcb685
dcb685
	return ret;
dcb685
}
dcb685
dcb685
dcb685
static int ntux_cmd_aceit_dump_acl(nt_acl * acl, const char * acldesc, int fdout)
dcb685
{
dcb685
	int                     idx;
dcb685
	int                     saidx;
dcb685
	size_t                  addr;
dcb685
	struct ntux_sid_any *   sid;
dcb685
	struct ntux_ace_any *   ace;
dcb685
	char                    comma[2];
dcb685
dcb685
	ntux_dprintf(
dcb685
		fdout,
dcb685
		"  ::sd::%s = {\n"
dcb685
		"    .revision = 0x%x,\n"
dcb685
		"    .sbz_1st = 0x%x,\n"
dcb685
		"    .acl_size = 0x%x,\n"
dcb685
		"    .ace_count = 0x%x,\n"
dcb685
		"    .sbz_2nd = 0x%x\n",
dcb685
		acldesc,
dcb685
		acl->acl_revision,
dcb685
		acl->sbz_1st,
dcb685
		acl->acl_size,
dcb685
		acl->ace_count,
dcb685
		acl->sbz_2nd);
dcb685
dcb685
	addr  = (size_t)acl;
dcb685
	addr += sizeof(*acl);
dcb685
dcb685
	for (idx=0; idx<acl->ace_count; idx++) {
dcb685
		ace = (struct ntux_ace_any *)addr;
dcb685
dcb685
		ntux_dprintf(
dcb685
			fdout,
dcb685
			"    ::sd::%s::ace[%d] = {\n"
dcb685
			"      .ace_type = 0x%x,\n"
dcb685
			"      .ace_flags = 0x%x,\n"
dcb685
			"      .ace_size = 0x%x,\n"
dcb685
			"      .mask = 0x%x,\n",
dcb685
			acldesc,idx,
dcb685
			ace->header.ace_type,
dcb685
			ace->header.ace_flags,
dcb685
			ace->header.ace_size,
dcb685
			ace->mask);
dcb685
dcb685
		sid = (struct ntux_sid_any *)&ace->sid_start;
dcb685
dcb685
		ntux_dprintf(fdout,
dcb685
		"      .sid = {\n"
dcb685
		"        .revision = 0x%x,\n"
dcb685
		"        .sub_authority_count = 0x%x,\n"
dcb685
		"        .identifier_authority = {%u,%u,%u,%u,%u,%u}\n"
dcb685
		"        .sub_authority = {",
dcb685
		sid->revision,
dcb685
		sid->sub_authority_count,
dcb685
		sid->identifier_authority.value[0],
dcb685
		sid->identifier_authority.value[1],
dcb685
		sid->identifier_authority.value[2],
dcb685
		sid->identifier_authority.value[3],
dcb685
		sid->identifier_authority.value[4],
dcb685
		sid->identifier_authority.value[5]);
dcb685
dcb685
		comma[0] = '\0';
dcb685
		comma[1] = 0;
dcb685
dcb685
		for (saidx=0; saidx<sid->sub_authority_count; saidx++) {
dcb685
			ntux_dprintf(fdout,"%s%u",comma,sid->sub_authority[saidx]);
dcb685
			comma[0] = ',';
dcb685
		}
dcb685
dcb685
		ntux_dprintf(fdout,"}\n");
dcb685
		ntux_dprintf(fdout,"      }\n");
dcb685
		ntux_dprintf(fdout,"    }\n");
dcb685
dcb685
		addr += ace->header.ace_size;
dcb685
	}
dcb685
dcb685
	ntux_dprintf(fdout,"  }\n");
dcb685
dcb685
(void)saidx;
dcb685
	return 0;
dcb685
}
dcb685
dcb685
dcb685
static int ntux_cmd_aceit_dump(const char * dunit, nt_sd * sd, int fdout)
dcb685
{
dcb685
	int             ret;
dcb685
	size_t          addr;
dcb685
	nt_acl *        sacl;
dcb685
	nt_acl *        dacl;
dcb685
dcb685
	ntux_dprintf(
dcb685
		fdout,
dcb685
		"%s::sd = {\n"
dcb685
		"  .revision = 0x%x,\n"
dcb685
		"  .sbz_1st = 0x%x,\n"
dcb685
		"  .control = 0x%x,\n"
dcb685
		"  .offset_owner = 0x%x,\n"
dcb685
		"  .offset_group = 0x%x,\n"
dcb685
		"  .offset_sacl = 0x%x,\n"
dcb685
		"  .offset_dacl = 0x%x\n",
dcb685
		dunit,
dcb685
		sd->revision,
dcb685
		sd->sbz_1st,
dcb685
		sd->control,
dcb685
		sd->offset_owner,
dcb685
		sd->offset_group,
dcb685
		sd->offset_sacl,
dcb685
		sd->offset_dacl);
dcb685
dcb685
	if (sd->offset_sacl) {
dcb685
		addr  = (size_t)sd;
dcb685
		addr += sd->offset_sacl;
dcb685
		sacl  = (nt_acl *)addr;
dcb685
dcb685
		if ((ret = ntux_cmd_aceit_dump_acl(sacl,"sacl",fdout)))
dcb685
			return ret;
dcb685
	}
dcb685
dcb685
	if (sd->offset_dacl) {
dcb685
		addr  = (size_t)sd;
dcb685
		addr += sd->offset_dacl;
dcb685
		dacl  = (nt_acl *)addr;
dcb685
dcb685
		if ((ret = ntux_cmd_aceit_dump_acl(dacl,"dacl",fdout)))
dcb685
			return ret;
dcb685
	}
dcb685
dcb685
	ntux_dprintf(fdout,"}\n");
dcb685
dcb685
	return 0;
dcb685
}
dcb685
dcb685
dcb685
int ntux_cmd_aceit(const struct ntux_driver_ctx * dctx, const char * dunit)
dcb685
{
dcb685
	intptr_t		ret;
dcb685
	int32_t			status;
dcb685
	int			fdout;
dcb685
	int			fdcwd;
dcb685
	const unsigned char *	unit;
dcb685
	nt_sd *			srcsd;
dcb685
	size_t			size;
dcb685
	int			fd      = -1;
dcb685
	struct __ofd *		ofd     = 0;
dcb685
	void *			hasync  = 0;
dcb685
	uint32_t		buf[0x300];
dcb685
dcb685
	/* init */
dcb685
	ntux_driver_set_ectx(
dcb685
		dctx,0,dunit);
dcb685
dcb685
	unit = (const unsigned char *)dunit;
dcb685
dcb685
	/* fdctx */
dcb685
	fdout = ntux_driver_fdout(dctx);
dcb685
	fdcwd = ntux_driver_fdcwd(dctx);
dcb685
dcb685
	/* fd */
dcb685
	if ((ret = __sys_openat(fdcwd,unit,0,0)) < 0)
dcb685
		if (ntux_errno_set(dctx,ret))
dcb685
			return ntux_cmd_aceit_ret(
dcb685
				0,0,0,
dcb685
				NTUX_SYSTEM_ERROR(dctx));
dcb685
dcb685
	fd = ret;
dcb685
dcb685
	/* ofd */
dcb685
	if (!(ofd = __xfi_ofd_ref_inc(fd)))
dcb685
		return ntux_cmd_aceit_ret(
dcb685
			fd,0,0,
dcb685
			NTUX_CUSTOM_ERROR(
dcb685
				dctx,
dcb685
				NTUX_ERR_FLOW_ERROR));
dcb685
dcb685
	/* hasync */
dcb685
	if ((status = __xfi_fs_open_async(
dcb685
			&hasync,
dcb685
			ofd->info.hfile,0,
dcb685
			NT_SEC_READ_CONTROL,
dcb685
			NT_FILE_SHARE_READ
dcb685
				| NT_FILE_SHARE_WRITE
dcb685
				| NT_FILE_SHARE_DELETE)))
dcb685
		if (ntux_errno_set(dctx,EACCES))
dcb685
			return ntux_cmd_aceit_ret(
dcb685
				fd,ofd,0,
dcb685
				NTUX_SYSTEM_ERROR(dctx));
dcb685
dcb685
	/* srcsd */
dcb685
	srcsd = (nt_sd *)buf;
dcb685
dcb685
	if ((status = __xfi_query_security_object(
dcb685
			hasync,
dcb685
			NT_OWNER_SECURITY_INFORMATION
dcb685
				| NT_GROUP_SECURITY_INFORMATION
dcb685
				| NT_DACL_SECURITY_INFORMATION,
dcb685
			srcsd,sizeof(buf),&size)))
dcb685
		if (ntux_errno_set(dctx,ENXIO))
dcb685
			return ntux_cmd_aceit_ret(
dcb685
				fd,ofd,hasync,
dcb685
				NTUX_SYSTEM_ERROR(dctx));
dcb685
dcb685
	/* dump */
dcb685
	if (dctx->cctx->drvflags & NTUX_DRIVER_DUMP)
dcb685
		if ((ntux_cmd_aceit_dump(dunit,srcsd,fdout)))
dcb685
			return ntux_cmd_aceit_ret(
dcb685
				fd,ofd,hasync,
dcb685
				NTUX_SYSTEM_ERROR(dctx));
dcb685
dcb685
	/* all done */
dcb685
	return ntux_cmd_aceit_ret(fd,ofd,hasync,0);
dcb685
}