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