summaryrefslogtreecommitdiffhomepage
path: root/src/cmds/ntux_cmd_aceit.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/cmds/ntux_cmd_aceit.c')
-rw-r--r--src/cmds/ntux_cmd_aceit.c266
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);
+}