|
|
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 |
|
|
|
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 |
|
|
|
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 |
|
|
|
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;
|
|
|
eb0350 |
uint32_t access_owner;
|
|
|
eb0350 |
uint32_t access_group;
|
|
|
eb0350 |
uint32_t access_other;
|
|
|
eb0350 |
uint32_t access_admin;
|
|
|
eb0350 |
size_t size;
|
|
|
eb0350 |
int fd = -1;
|
|
|
eb0350 |
struct __ofd * ofd = 0;
|
|
|
eb0350 |
void * hasync = 0;
|
|
|
eb0350 |
uint32_t buf[0x300];
|
|
|
eb0350 |
|
|
|
eb0350 |
/* initial version: only support m+p */
|
|
|
eb0350 |
if (!dctx->cctx->strmode || strcmp(dctx->cctx->strmode,"m+p"))
|
|
|
eb0350 |
return ntux_cmd_chmod_ret(
|
|
|
eb0350 |
0,0,0,
|
|
|
eb0350 |
NTUX_CUSTOM_ERROR(
|
|
|
eb0350 |
dctx,
|
|
|
eb0350 |
NTUX_ERR_FLEE_ERROR));
|
|
|
eb0350 |
|
|
|
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 */
|
|
|
eb0350 |
if ((status = __xfi_fs_open_async(
|
|
|
eb0350 |
&hasync,
|
|
|
eb0350 |
ofd->info.hfile,0,
|
|
|
eb0350 |
NT_SEC_READ_CONTROL
|
|
|
eb0350 |
| NT_SEC_WRITE_DAC,
|
|
|
eb0350 |
NT_FILE_SHARE_READ
|
|
|
eb0350 |
| NT_FILE_SHARE_WRITE
|
|
|
eb0350 |
| NT_FILE_SHARE_DELETE)))
|
|
|
eb0350 |
return ntux_cmd_chmod_ret(
|
|
|
eb0350 |
fd,ofd,0,
|
|
|
eb0350 |
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)))
|
|
|
eb0350 |
return ntux_cmd_chmod_ret(
|
|
|
eb0350 |
fd,ofd,hasync,
|
|
|
eb0350 |
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)))
|
|
|
eb0350 |
return ntux_cmd_chmod_ret(
|
|
|
eb0350 |
fd,ofd,hasync,
|
|
|
eb0350 |
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;
|
|
|
eb0350 |
|
|
|
eb0350 |
/* initial version: only support m+p */
|
|
|
eb0350 |
access_admin = access_owner | NT_SEC_WRITE_DAC;
|
|
|
eb0350 |
|
|
|
eb0350 |
/* updated dacl */
|
|
|
471bb0 |
__xfi_acl_init_common_descriptor(
|
|
|
eb0350 |
&dstsd,
|
|
|
eb0350 |
meta.owner,meta.group,0,0,
|
|
|
eb0350 |
access_owner,access_group,access_other,
|
|
|
eb0350 |
access_admin,meta.system_acc);
|
|
|
eb0350 |
|
|
|
471bb0 |
if ((status = __xfi_set_security_object(
|
|
|
eb0350 |
hasync,
|
|
|
eb0350 |
NT_DACL_SECURITY_INFORMATION,
|
|
|
eb0350 |
&dstsd.sd)))
|
|
|
eb0350 |
return ntux_cmd_chmod_ret(
|
|
|
eb0350 |
fd,ofd,hasync,
|
|
|
eb0350 |
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 |
}
|