|
|
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 |
}
|