| |
| |
| |
| |
| |
| |
| #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]; |
| |
| |
| ntux_driver_set_ectx( |
| dctx,0,dunit); |
| |
| unit = (const unsigned char *)dunit; |
| |
| |
| fdout = ntux_driver_fdout(dctx); |
| fdcwd = ntux_driver_fdcwd(dctx); |
| |
| |
| 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; |
| |
| |
| if (!(ofd = __xfi_ofd_ref_inc(fd))) |
| return ntux_cmd_aceit_ret( |
| fd,0,0, |
| NTUX_CUSTOM_ERROR( |
| dctx, |
| NTUX_ERR_FLOW_ERROR)); |
| |
| |
| 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 = (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)); |
| |
| |
| 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)); |
| |
| |
| return ntux_cmd_aceit_ret(fd,ofd,hasync,0); |
| } |