/***********************************************************/
/* 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);
}