|
|
80f43a |
/***********************************************************/
|
|
|
80f43a |
/* ntux: native translation und extension */
|
|
|
80f43a |
/* Copyright (C) 2016--2018 Z. Gilboa */
|
|
|
80f43a |
/* Released under GPLv2 and GPLv3; see COPYING.NTUX. */
|
|
|
80f43a |
/***********************************************************/
|
|
|
80f43a |
|
|
|
80f43a |
#include <psxabi/sys_sysapi.h>
|
|
|
80f43a |
#include <psxabi/sys_stat.h>
|
|
|
80f43a |
#include <psxabi/sys_errno.h>
|
|
|
80f43a |
|
|
|
471bb0 |
#include <psxxfi/xfi_base.h>
|
|
|
471bb0 |
#include <psxxfi/xfi_acl.h>
|
|
|
eb0350 |
#include <psxxfi/xfi_fs.h>
|
|
|
80f43a |
#include <psxxfi/xfi_ofd.h>
|
|
|
80f43a |
#include <psxxfi/xfi_unicode.h>
|
|
|
80f43a |
|
|
|
162c96 |
#include <ntapi/nt_object.h>
|
|
|
471bb0 |
#include <ntapi/nt_acl.h>
|
|
|
471bb0 |
#include <ntapi/nt_file.h>
|
|
|
471bb0 |
|
|
|
80f43a |
#include <ntux/ntux.h>
|
|
|
80f43a |
#include "ntux_driver_impl.h"
|
|
|
80f43a |
#include "ntux_nolibc_impl.h"
|
|
|
80f43a |
#include "ntux_errinfo_impl.h"
|
|
|
80f43a |
|
|
|
162c96 |
#define __SID_SYSTEM {1,1,{{0,0,0,0,0,5}},{18}}
|
|
|
162c96 |
#define __SID_ADMINISTRATORS {1,2,{{0,0,0,0,0,5}},{32,544}}
|
|
|
162c96 |
|
|
|
162c96 |
static const nt_sid sid_system = __SID_SYSTEM;
|
|
|
162c96 |
static const nt_sid_os sid_admins = __SID_ADMINISTRATORS;
|
|
|
162c96 |
|
|
|
eb0350 |
static int ntux_cmd_chmod_ret(int fd, struct __ofd * ofd, void * hasync, int ret)
|
|
|
eb0350 |
{
|
|
|
eb0350 |
if (hasync)
|
|
|
471bb0 |
__xfi_close_handle(hasync);
|
|
|
eb0350 |
|
|
|
eb0350 |
if (ofd)
|
|
|
eb0350 |
__xfi_ofd_ref_dec(ofd);
|
|
|
eb0350 |
|
|
|
eb0350 |
if (fd >= 0)
|
|
|
eb0350 |
__sys_close(fd);
|
|
|
eb0350 |
|
|
|
eb0350 |
return ret;
|
|
|
eb0350 |
}
|
|
|
eb0350 |
|
|
|
162c96 |
static nt_sid * ntux_cmd_chmod_sid_from_name(const char * name)
|
|
|
162c96 |
{
|
|
|
162c96 |
if (!strcmp(name,"Administrators"))
|
|
|
162c96 |
return (nt_sid *)&sid_admins;
|
|
|
162c96 |
|
|
|
162c96 |
else if (!strcmp(name,"SYSTEM"))
|
|
|
162c96 |
return (nt_sid *)&sid_system;
|
|
|
162c96 |
|
|
|
162c96 |
else
|
|
|
162c96 |
return 0;
|
|
|
162c96 |
}
|
|
|
162c96 |
|
|
|
80f43a |
int ntux_cmd_chmod(const struct ntux_driver_ctx * dctx, const char * dunit)
|
|
|
80f43a |
{
|
|
|
eb0350 |
intptr_t ret;
|
|
|
eb0350 |
int32_t status;
|
|
|
eb0350 |
int fdout;
|
|
|
eb0350 |
int fdcwd;
|
|
|
eb0350 |
const unsigned char * unit;
|
|
|
eb0350 |
nt_sd * srcsd;
|
|
|
eb0350 |
nt_sd_common_buffer dstsd;
|
|
|
eb0350 |
nt_sd_common_meta meta;
|
|
|
162c96 |
nt_sid * owner;
|
|
|
162c96 |
nt_sid * group;
|
|
|
eb0350 |
uint32_t access_owner;
|
|
|
eb0350 |
uint32_t access_group;
|
|
|
eb0350 |
uint32_t access_other;
|
|
|
eb0350 |
uint32_t access_admin;
|
|
|
0a741d |
uint32_t ace_flags;
|
|
|
162c96 |
uint32_t sec_mask;
|
|
|
eb0350 |
size_t size;
|
|
|
eb0350 |
int fd = -1;
|
|
|
eb0350 |
struct __ofd * ofd = 0;
|
|
|
eb0350 |
void * hasync = 0;
|
|
|
eb0350 |
uint32_t buf[0x300];
|
|
|
eb0350 |
|
|
|
354869 |
/* ACE propagation: +p, -p */
|
|
|
0a741d |
if (!dctx->cctx->strmode)
|
|
|
354869 |
ace_flags = 0;
|
|
|
0a741d |
|
|
|
354869 |
else if (!strcmp(dctx->cctx->strmode,"+p"))
|
|
|
0a741d |
ace_flags = NT_ACE_CONTAINER_INHERIT | NT_ACE_OBJECT_INHERIT;
|
|
|
0a741d |
|
|
|
0a741d |
else if (!strcmp(dctx->cctx->strmode,"-p"))
|
|
|
0a741d |
ace_flags = 0;
|
|
|
0a741d |
|
|
|
0a741d |
else
|
|
|
eb0350 |
return ntux_cmd_chmod_ret(
|
|
|
eb0350 |
0,0,0,
|
|
|
eb0350 |
NTUX_CUSTOM_ERROR(
|
|
|
eb0350 |
dctx,
|
|
|
eb0350 |
NTUX_ERR_FLEE_ERROR));
|
|
|
eb0350 |
|
|
|
162c96 |
/* initial --owner and --group support: Administrators, SYSTEM */
|
|
|
162c96 |
owner = 0;
|
|
|
162c96 |
group = 0;
|
|
|
162c96 |
|
|
|
162c96 |
if (dctx->cctx->owner)
|
|
|
162c96 |
if (!(owner = ntux_cmd_chmod_sid_from_name(dctx->cctx->owner)))
|
|
|
162c96 |
return ntux_cmd_chmod_ret(
|
|
|
162c96 |
0,0,0,
|
|
|
162c96 |
NTUX_CUSTOM_ERROR(
|
|
|
162c96 |
dctx,
|
|
|
162c96 |
NTUX_ERR_NOT_IMPLEMENTED));
|
|
|
162c96 |
|
|
|
162c96 |
if (dctx->cctx->group)
|
|
|
162c96 |
if (!(group = ntux_cmd_chmod_sid_from_name(dctx->cctx->group)))
|
|
|
162c96 |
return ntux_cmd_chmod_ret(
|
|
|
162c96 |
0,0,0,
|
|
|
162c96 |
NTUX_CUSTOM_ERROR(
|
|
|
162c96 |
dctx,
|
|
|
162c96 |
NTUX_ERR_NOT_IMPLEMENTED));
|
|
|
162c96 |
|
|
|
eb0350 |
/* init */
|
|
|
eb0350 |
ntux_driver_set_ectx(
|
|
|
eb0350 |
dctx,0,dunit);
|
|
|
eb0350 |
|
|
|
eb0350 |
unit = (const unsigned char *)dunit;
|
|
|
eb0350 |
|
|
|
eb0350 |
/* fdctx */
|
|
|
eb0350 |
fdout = ntux_driver_fdout(dctx);
|
|
|
eb0350 |
fdcwd = ntux_driver_fdcwd(dctx);
|
|
|
eb0350 |
|
|
|
eb0350 |
/* fd */
|
|
|
eb0350 |
if ((ret = __sys_openat(fdcwd,unit,0,0)) < 0)
|
|
|
eb0350 |
if (ntux_errno_set(dctx,ret))
|
|
|
eb0350 |
return ntux_cmd_chmod_ret(
|
|
|
eb0350 |
0,0,0,
|
|
|
eb0350 |
NTUX_SYSTEM_ERROR(dctx));
|
|
|
eb0350 |
|
|
|
eb0350 |
fd = ret;
|
|
|
eb0350 |
|
|
|
eb0350 |
/* ofd */
|
|
|
eb0350 |
if (!(ofd = __xfi_ofd_ref_inc(fd)))
|
|
|
eb0350 |
return ntux_cmd_chmod_ret(
|
|
|
eb0350 |
fd,0,0,
|
|
|
eb0350 |
NTUX_CUSTOM_ERROR(
|
|
|
eb0350 |
dctx,
|
|
|
eb0350 |
NTUX_ERR_FLOW_ERROR));
|
|
|
eb0350 |
|
|
|
eb0350 |
/* hasync */
|
|
|
162c96 |
sec_mask = NT_SEC_READ_CONTROL;
|
|
|
162c96 |
sec_mask |= NT_SEC_WRITE_DAC;
|
|
|
162c96 |
sec_mask |= owner ? NT_SEC_WRITE_OWNER : 0;
|
|
|
162c96 |
|
|
|
eb0350 |
if ((status = __xfi_fs_open_async(
|
|
|
eb0350 |
&hasync,
|
|
|
eb0350 |
ofd->info.hfile,0,
|
|
|
162c96 |
sec_mask,
|
|
|
eb0350 |
NT_FILE_SHARE_READ
|
|
|
eb0350 |
| NT_FILE_SHARE_WRITE
|
|
|
eb0350 |
| NT_FILE_SHARE_DELETE)))
|
|
|
9325bd |
if (ntux_errno_set(dctx,EACCES))
|
|
|
9325bd |
return ntux_cmd_chmod_ret(
|
|
|
9325bd |
fd,ofd,0,
|
|
|
9325bd |
NTUX_SYSTEM_ERROR(dctx));
|
|
|
eb0350 |
|
|
|
eb0350 |
/* srcsd */
|
|
|
eb0350 |
srcsd = (nt_sd *)buf;
|
|
|
eb0350 |
|
|
|
471bb0 |
if ((status = __xfi_query_security_object(
|
|
|
eb0350 |
hasync,
|
|
|
eb0350 |
NT_OWNER_SECURITY_INFORMATION
|
|
|
eb0350 |
| NT_GROUP_SECURITY_INFORMATION
|
|
|
eb0350 |
| NT_DACL_SECURITY_INFORMATION,
|
|
|
eb0350 |
srcsd,sizeof(buf),&size)))
|
|
|
9325bd |
if (ntux_errno_set(dctx,ENXIO))
|
|
|
9325bd |
return ntux_cmd_chmod_ret(
|
|
|
9325bd |
fd,ofd,hasync,
|
|
|
9325bd |
NTUX_SYSTEM_ERROR(dctx));
|
|
|
eb0350 |
|
|
|
471bb0 |
if ((status = __xfi_acl_init_common_descriptor_meta(
|
|
|
eb0350 |
&meta,srcsd,
|
|
|
eb0350 |
NT_ACL_INIT_COMMON_DESCRIPTION_META_STRICT_MODE)))
|
|
|
9325bd |
if (ntux_errno_set(dctx,EBADF))
|
|
|
9325bd |
return ntux_cmd_chmod_ret(
|
|
|
9325bd |
fd,ofd,hasync,
|
|
|
9325bd |
NTUX_SYSTEM_ERROR(dctx));
|
|
|
eb0350 |
|
|
|
eb0350 |
/* source permissions */
|
|
|
eb0350 |
access_owner = meta.owner_ace ? meta.owner_ace->mask : 0;
|
|
|
eb0350 |
access_group = meta.group_ace ? meta.group_ace->mask : 0;
|
|
|
eb0350 |
access_other = meta.other_ace ? meta.other_ace->mask : 0;
|
|
|
0a741d |
access_admin = meta.admin_ace ? meta.admin_ace->mask : 0;
|
|
|
eb0350 |
|
|
|
354869 |
/* initial --strmode support, retaining previous options as needed */
|
|
|
354869 |
if (!dctx->cctx->strmode) {
|
|
|
354869 |
ace_flags |= meta.owner_ace ? meta.owner_ace->header.ace_flags : 0;
|
|
|
354869 |
ace_flags |= meta.group_ace ? meta.group_ace->header.ace_flags : 0;
|
|
|
354869 |
ace_flags |= meta.other_ace ? meta.other_ace->header.ace_flags : 0;
|
|
|
354869 |
ace_flags |= meta.admin_ace ? meta.admin_ace->header.ace_flags : 0;
|
|
|
354869 |
}
|
|
|
354869 |
|
|
|
eb0350 |
/* updated dacl */
|
|
|
471bb0 |
__xfi_acl_init_common_descriptor(
|
|
|
eb0350 |
&dstsd,
|
|
|
162c96 |
owner ? owner : meta.owner,
|
|
|
162c96 |
group ? group : meta.group,
|
|
|
162c96 |
0,0,
|
|
|
eb0350 |
access_owner,access_group,access_other,
|
|
|
0a741d |
access_admin,meta.system_acc,
|
|
|
0a741d |
ace_flags);
|
|
|
eb0350 |
|
|
|
162c96 |
sec_mask = NT_DACL_SECURITY_INFORMATION;
|
|
|
162c96 |
sec_mask |= owner ? NT_OWNER_SECURITY_INFORMATION : 0;
|
|
|
162c96 |
|
|
|
471bb0 |
if ((status = __xfi_set_security_object(
|
|
|
162c96 |
hasync,sec_mask,&dstsd.sd)))
|
|
|
9325bd |
if (ntux_errno_set(dctx,EPERM))
|
|
|
9325bd |
return ntux_cmd_chmod_ret(
|
|
|
9325bd |
fd,ofd,hasync,
|
|
|
9325bd |
NTUX_SYSTEM_ERROR(dctx));
|
|
|
eb0350 |
|
|
|
eb0350 |
/* changes */
|
|
|
eb0350 |
(void)fdout;
|
|
|
80f43a |
|
|
|
eb0350 |
/* all done */
|
|
|
eb0350 |
return ntux_cmd_chmod_ret(fd,ofd,hasync,0);
|
|
|
80f43a |
}
|