|
|
80f43a |
/***********************************************************/
|
|
|
80f43a |
/* ntux: native translation und extension */
|
|
|
14ffae |
/* Copyright (C) 2016--2021 SysDeer Technologies, LLC */
|
|
|
80f43a |
/* Released under GPLv2 and GPLv3; see COPYING.NTUX. */
|
|
|
80f43a |
/***********************************************************/
|
|
|
80f43a |
|
|
|
80f43a |
#include <psxabi/sys_sysapi.h>
|
|
|
80f43a |
#include <psxabi/sys_stat.h>
|
|
|
1e08b3 |
#include <psxabi/sys_path.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>
|
|
|
1e08b3 |
#include <psxxfi/xfi_path.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"
|
|
|
03b277 |
#include "nolibc/stdbool.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 |
|
|
|
03b277 |
#define NTUX_OPT_MODE_NEUTRAL (0)
|
|
|
03b277 |
#define NTUX_OPT_MODE_EQUAL (1)
|
|
|
03b277 |
#define NTUX_OPT_MODE_PLUS (2)
|
|
|
03b277 |
#define NTUX_OPT_MODE_MINUS (3)
|
|
|
03b277 |
|
|
|
1e08b3 |
#define NTUX_BUF_SIZE_64K (64*1024)
|
|
|
1e08b3 |
|
|
|
162c96 |
static const nt_sid sid_system = __SID_SYSTEM;
|
|
|
162c96 |
static const nt_sid_os sid_admins = __SID_ADMINISTRATORS;
|
|
|
162c96 |
|
|
|
1e08b3 |
struct ntux_sd_buffer {
|
|
|
1e08b3 |
nt_sd_common_buffer sd;
|
|
|
1e08b3 |
uint32_t exbuf[512];
|
|
|
1e08b3 |
};
|
|
|
1e08b3 |
|
|
|
1e08b3 |
struct ntux_ace_any {
|
|
|
1e08b3 |
nt_ace_header header;
|
|
|
1e08b3 |
uint32_t mask;
|
|
|
1e08b3 |
uint32_t sid_start;
|
|
|
1e08b3 |
};
|
|
|
1e08b3 |
|
|
|
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;
|
|
|
1e08b3 |
int finherit;
|
|
|
03b277 |
int optmode;
|
|
|
03b277 |
const char * strmode;
|
|
|
03b277 |
const char * chmode;
|
|
|
980d09 |
const unsigned char * refobj;
|
|
|
eb0350 |
const unsigned char * unit;
|
|
|
1e08b3 |
char * ch;
|
|
|
1e08b3 |
struct ntux_sd_buffer sdbuf;
|
|
|
1e08b3 |
struct ntux_sd_buffer srcsd;
|
|
|
1e08b3 |
struct ntux_sd_buffer cntsd;
|
|
|
1e08b3 |
nt_sd_common_buffer * dstsd;
|
|
|
eb0350 |
nt_sd_common_meta meta;
|
|
|
162c96 |
nt_sid * owner;
|
|
|
162c96 |
nt_sid * group;
|
|
|
1e08b3 |
nt_acl * dacl;
|
|
|
1e08b3 |
struct ntux_ace_any * srcace;
|
|
|
1e08b3 |
struct ntux_ace_any * dstace;
|
|
|
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;
|
|
|
1e08b3 |
size_t addr;
|
|
|
1e08b3 |
size_t aceaddr;
|
|
|
1e08b3 |
size_t cntbufsize;
|
|
|
1e08b3 |
char * cntpath_utf8;
|
|
|
1e08b3 |
wchar16_t * cntpath_utf16;
|
|
|
1e08b3 |
int exacefilter;
|
|
|
1e08b3 |
size_t exacesize;
|
|
|
1e08b3 |
int exacecount;
|
|
|
1e08b3 |
int idx;
|
|
|
eb0350 |
int fd = -1;
|
|
|
980d09 |
int reffd = -1;
|
|
|
1e08b3 |
int cntfd = -1;
|
|
|
eb0350 |
struct __ofd * ofd = 0;
|
|
|
980d09 |
struct __ofd * refofd = 0;
|
|
|
1e08b3 |
struct __ofd * cntofd = 0;
|
|
|
1e08b3 |
void * cntbuf = 0;
|
|
|
eb0350 |
void * hasync = 0;
|
|
|
1e08b3 |
char dummy = 0;
|
|
|
03b277 |
|
|
|
03b277 |
/* strmode */
|
|
|
1e08b3 |
strmode = dctx->cctx->strmode ? dctx->cctx->strmode : &dummy;
|
|
|
03b277 |
optmode = NTUX_OPT_MODE_NEUTRAL;
|
|
|
1e08b3 |
finherit = false;
|
|
|
03b277 |
ace_flags = 0;
|
|
|
03b277 |
|
|
|
03b277 |
for (chmode=strmode; *chmode; chmode++) {
|
|
|
03b277 |
switch (*chmode) {
|
|
|
03b277 |
case '=':
|
|
|
03b277 |
optmode = NTUX_OPT_MODE_EQUAL;
|
|
|
1e08b3 |
finherit = 0;
|
|
|
03b277 |
ace_flags = 0;
|
|
|
03b277 |
break;
|
|
|
03b277 |
|
|
|
03b277 |
case '+':
|
|
|
03b277 |
optmode = NTUX_OPT_MODE_PLUS;
|
|
|
03b277 |
break;
|
|
|
03b277 |
|
|
|
03b277 |
case '-':
|
|
|
03b277 |
optmode = NTUX_OPT_MODE_MINUS;
|
|
|
03b277 |
break;
|
|
|
03b277 |
|
|
|
03b277 |
case 'p':
|
|
|
03b277 |
switch (optmode) {
|
|
|
03b277 |
case NTUX_OPT_MODE_EQUAL:
|
|
|
03b277 |
case NTUX_OPT_MODE_PLUS:
|
|
|
03b277 |
ace_flags = NT_ACE_CONTAINER_INHERIT | NT_ACE_OBJECT_INHERIT;
|
|
|
03b277 |
break;
|
|
|
03b277 |
|
|
|
03b277 |
case NTUX_OPT_MODE_MINUS:
|
|
|
03b277 |
ace_flags = 0;
|
|
|
03b277 |
break;
|
|
|
03b277 |
|
|
|
03b277 |
default:
|
|
|
03b277 |
return ntux_cmd_chmod_ret(
|
|
|
03b277 |
0,0,0,
|
|
|
03b277 |
NTUX_CUSTOM_ERROR(
|
|
|
03b277 |
dctx,
|
|
|
03b277 |
NTUX_ERR_FLEE_ERROR));
|
|
|
03b277 |
}
|
|
|
03b277 |
|
|
|
03b277 |
break;
|
|
|
03b277 |
|
|
|
1e08b3 |
case 'P':
|
|
|
1e08b3 |
switch (optmode) {
|
|
|
1e08b3 |
case NTUX_OPT_MODE_EQUAL:
|
|
|
1e08b3 |
case NTUX_OPT_MODE_PLUS:
|
|
|
1e08b3 |
finherit = true;
|
|
|
1e08b3 |
break;
|
|
|
1e08b3 |
|
|
|
1e08b3 |
case NTUX_OPT_MODE_MINUS:
|
|
|
1e08b3 |
finherit = false;
|
|
|
1e08b3 |
break;
|
|
|
1e08b3 |
|
|
|
1e08b3 |
default:
|
|
|
1e08b3 |
return ntux_cmd_chmod_ret(
|
|
|
1e08b3 |
0,0,0,
|
|
|
1e08b3 |
NTUX_CUSTOM_ERROR(
|
|
|
1e08b3 |
dctx,
|
|
|
1e08b3 |
NTUX_ERR_FLEE_ERROR));
|
|
|
1e08b3 |
}
|
|
|
1e08b3 |
|
|
|
1e08b3 |
break;
|
|
|
1e08b3 |
|
|
|
03b277 |
default:
|
|
|
03b277 |
return ntux_cmd_chmod_ret(
|
|
|
03b277 |
0,0,0,
|
|
|
03b277 |
NTUX_CUSTOM_ERROR(
|
|
|
03b277 |
dctx,
|
|
|
03b277 |
NTUX_ERR_FLEE_ERROR));
|
|
|
03b277 |
}
|
|
|
03b277 |
}
|
|
|
eb0350 |
|
|
|
980d09 |
/* conflicting arguments? */
|
|
|
980d09 |
if (finherit && dctx->cctx->refobj)
|
|
|
980d09 |
return ntux_cmd_chmod_ret(
|
|
|
980d09 |
0,0,0,
|
|
|
980d09 |
NTUX_CUSTOM_ERROR(
|
|
|
980d09 |
dctx,
|
|
|
980d09 |
NTUX_ERR_CONFLICTING_ARGUMENTS));
|
|
|
980d09 |
|
|
|
980d09 |
|
|
|
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 |
|
|
|
980d09 |
|
|
|
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 |
|
|
|
980d09 |
/* refofd */
|
|
|
980d09 |
if ((refobj = (const unsigned char *)dctx->cctx->refobj)) {
|
|
|
980d09 |
ntux_driver_set_ectx(
|
|
|
980d09 |
dctx,0,dctx->cctx->refobj);
|
|
|
980d09 |
|
|
|
980d09 |
if ((ret = __sys_openat(fdcwd,refobj,0,0)) < 0)
|
|
|
980d09 |
if (ntux_errno_set(dctx,ret))
|
|
|
980d09 |
return ntux_cmd_chmod_ret(
|
|
|
980d09 |
0,0,0,
|
|
|
980d09 |
NTUX_SYSTEM_ERROR(dctx));
|
|
|
980d09 |
|
|
|
980d09 |
reffd = ret;
|
|
|
980d09 |
|
|
|
980d09 |
if (!(refofd = __xfi_ofd_ref_inc(reffd))) {
|
|
|
980d09 |
__sys_close(reffd);
|
|
|
980d09 |
|
|
|
980d09 |
return ntux_cmd_chmod_ret(
|
|
|
980d09 |
fd,0,0,
|
|
|
980d09 |
NTUX_CUSTOM_ERROR(
|
|
|
980d09 |
dctx,
|
|
|
980d09 |
NTUX_ERR_FLOW_ERROR));
|
|
|
980d09 |
}
|
|
|
980d09 |
|
|
|
980d09 |
ntux_driver_set_ectx(
|
|
|
980d09 |
dctx,0,dunit);
|
|
|
980d09 |
}
|
|
|
980d09 |
|
|
|
eb0350 |
/* srcsd */
|
|
|
980d09 |
status = __xfi_query_security_object(
|
|
|
980d09 |
refobj ? refofd->info.hfile : hasync,
|
|
|
980d09 |
NT_OWNER_SECURITY_INFORMATION
|
|
|
980d09 |
| NT_GROUP_SECURITY_INFORMATION
|
|
|
980d09 |
| NT_DACL_SECURITY_INFORMATION,
|
|
|
980d09 |
&srcsd.sd.sd,sizeof(srcsd),&size);
|
|
|
980d09 |
|
|
|
980d09 |
if (refofd) {
|
|
|
980d09 |
__xfi_ofd_ref_dec(refofd);
|
|
|
980d09 |
__sys_close(reffd);
|
|
|
980d09 |
}
|
|
|
980d09 |
|
|
|
980d09 |
if (status)
|
|
|
9325bd |
if (ntux_errno_set(dctx,ENXIO))
|
|
|
9325bd |
return ntux_cmd_chmod_ret(
|
|
|
9325bd |
fd,ofd,hasync,
|
|
|
9325bd |
NTUX_SYSTEM_ERROR(dctx));
|
|
|
eb0350 |
|
|
|
980d09 |
status = __xfi_acl_init_common_descriptor_meta(
|
|
|
980d09 |
&meta,&srcsd.sd.sd,
|
|
|
980d09 |
NT_ACL_INIT_COMMON_DESCRIPTION_META_STRICT_MODE);
|
|
|
980d09 |
|
|
|
980d09 |
/* sd copy based on a non-posix object? */
|
|
|
980d09 |
if (status && refobj) {
|
|
|
980d09 |
ntux_driver_set_ectx(
|
|
|
980d09 |
dctx,0,dctx->cctx->refobj);
|
|
|
980d09 |
|
|
|
980d09 |
if (dctx->cctx->strmode
|
|
|
980d09 |
|| dctx->cctx->owner
|
|
|
980d09 |
|| dctx->cctx->group)
|
|
|
980d09 |
return ntux_cmd_chmod_ret(
|
|
|
980d09 |
0,0,0,
|
|
|
980d09 |
NTUX_CUSTOM_ERROR(
|
|
|
980d09 |
dctx,
|
|
|
980d09 |
NTUX_ERR_NON_POSIX_DESCRIPTOR));
|
|
|
980d09 |
|
|
|
980d09 |
ntux_driver_set_ectx(
|
|
|
980d09 |
dctx,0,dunit);
|
|
|
980d09 |
|
|
|
980d09 |
sec_mask = NT_DACL_SECURITY_INFORMATION;
|
|
|
980d09 |
|
|
|
980d09 |
if ((status = __xfi_set_security_object(
|
|
|
980d09 |
hasync,sec_mask,&srcsd.sd.sd)))
|
|
|
980d09 |
if (ntux_errno_set(dctx,EPERM))
|
|
|
980d09 |
return ntux_cmd_chmod_ret(
|
|
|
980d09 |
fd,ofd,hasync,
|
|
|
980d09 |
NTUX_SYSTEM_ERROR(dctx));
|
|
|
980d09 |
|
|
|
980d09 |
return ntux_cmd_chmod_ret(fd,ofd,hasync,0);
|
|
|
980d09 |
}
|
|
|
980d09 |
|
|
|
980d09 |
if (status)
|
|
|
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 */
|
|
|
1e08b3 |
dstsd = &sdbuf.sd;
|
|
|
1e08b3 |
|
|
|
471bb0 |
__xfi_acl_init_common_descriptor(
|
|
|
1e08b3 |
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 |
|
|
|
1e08b3 |
if ((dstsd->sd.offset_dacl < dstsd->sd.offset_owner)
|
|
|
1e08b3 |
|| (dstsd->sd.offset_dacl < dstsd->sd.offset_group)
|
|
|
1e08b3 |
|| (dstsd->sd.offset_dacl < dstsd->sd.offset_sacl))
|
|
|
1e08b3 |
return ntux_cmd_chmod_ret(
|
|
|
1e08b3 |
fd,0,0,
|
|
|
1e08b3 |
NTUX_CUSTOM_ERROR(
|
|
|
1e08b3 |
dctx,
|
|
|
1e08b3 |
NTUX_ERR_FLOW_ERROR));
|
|
|
1e08b3 |
|
|
|
1e08b3 |
/* inherited ace's */
|
|
|
1e08b3 |
if (finherit) {
|
|
|
1e08b3 |
dstsd->sd.control = NT_SE_SELF_RELATIVE
|
|
|
1e08b3 |
| NT_SE_DACL_AUTO_INHERIT_REQ
|
|
|
1e08b3 |
| NT_SE_DACL_AUTO_INHERITED
|
|
|
1e08b3 |
| NT_SE_DACL_PRESENT;
|
|
|
1e08b3 |
|
|
|
1e08b3 |
/* cntofd */
|
|
|
1e08b3 |
cntbuf = 0; cntbufsize = NTUX_BUF_SIZE_64K;
|
|
|
1e08b3 |
|
|
|
1e08b3 |
if (__xfi_allocate_virtual_memory(
|
|
|
1e08b3 |
NT_CURRENT_PROCESS_HANDLE,
|
|
|
1e08b3 |
&cntbuf,
|
|
|
1e08b3 |
0,
|
|
|
1e08b3 |
&cntbufsize,
|
|
|
1e08b3 |
NT_MEM_COMMIT,
|
|
|
1e08b3 |
NT_PAGE_READWRITE))
|
|
|
1e08b3 |
return ntux_cmd_chmod_ret(
|
|
|
1e08b3 |
fd,ofd,hasync,
|
|
|
1e08b3 |
NTUX_SYSTEM_ERROR(dctx));
|
|
|
1e08b3 |
|
|
|
1e08b3 |
if (__xfi_ofd_is_dir(ofd)) {
|
|
|
1e08b3 |
cntpath_utf16 = (wchar16_t *)cntbuf;
|
|
|
1e08b3 |
|
|
|
1e08b3 |
__xfi_path_conv_ofdat_utf16(
|
|
|
1e08b3 |
ofd,
|
|
|
1e08b3 |
(const wchar16_t[]){'.','.','/',0},
|
|
|
1e08b3 |
PSX_PATH_SYNTAX_ANY,
|
|
|
1e08b3 |
4*sizeof(wchar16_t),
|
|
|
1e08b3 |
cntpath_utf16,
|
|
|
1e08b3 |
PSX_PATH_SYNTAX_POSIX_STRICT,
|
|
|
1e08b3 |
cntbufsize,
|
|
|
1e08b3 |
0,0,PSX_PATH_CONV_RESOLVE_ELEMENT,
|
|
|
1e08b3 |
&cntofd);
|
|
|
1e08b3 |
} else {
|
|
|
1e08b3 |
cntpath_utf8 = cntbuf;
|
|
|
1e08b3 |
|
|
|
1e08b3 |
status = __xfi_path_conv_utf8(
|
|
|
1e08b3 |
fdcwd,
|
|
|
1e08b3 |
unit,
|
|
|
1e08b3 |
PSX_PATH_SYNTAX_POSIX_STRICT,
|
|
|
1e08b3 |
ntux_strlen((const char *)unit),
|
|
|
1e08b3 |
cntpath_utf8,
|
|
|
1e08b3 |
PSX_PATH_SYNTAX_POSIX_STRICT,
|
|
|
1e08b3 |
cntbufsize,
|
|
|
1e08b3 |
0,0,PSX_PATH_CONV_RESOLVE_ELEMENT,
|
|
|
1e08b3 |
0);
|
|
|
1e08b3 |
|
|
|
1e08b3 |
if (status) {
|
|
|
1e08b3 |
__xfi_free_virtual_memory(
|
|
|
1e08b3 |
NT_CURRENT_PROCESS_HANDLE,
|
|
|
1e08b3 |
&cntbuf,
|
|
|
1e08b3 |
&cntbufsize,
|
|
|
1e08b3 |
NT_MEM_RELEASE);
|
|
|
1e08b3 |
|
|
|
1e08b3 |
return ntux_cmd_chmod_ret(
|
|
|
1e08b3 |
fd,ofd,hasync,
|
|
|
1e08b3 |
NTUX_CUSTOM_ERROR(
|
|
|
1e08b3 |
dctx,
|
|
|
1e08b3 |
NTUX_ERR_FLOW_ERROR));
|
|
|
1e08b3 |
}
|
|
|
1e08b3 |
|
|
|
1e08b3 |
if ((cntpath_utf8[0] == '/') && cntpath_utf8[1]) {
|
|
|
1e08b3 |
for (ch=cntpath_utf8; *ch; ch++)
|
|
|
1e08b3 |
(void)0;
|
|
|
1e08b3 |
|
|
|
1e08b3 |
/* guard against an internal error */
|
|
|
1e08b3 |
if (ch[-1] != '/') {
|
|
|
1e08b3 |
for (--ch; *ch != '/'; ch--)
|
|
|
1e08b3 |
(void)0;
|
|
|
1e08b3 |
|
|
|
1e08b3 |
*ch = 0;
|
|
|
1e08b3 |
|
|
|
1e08b3 |
cntfd = __sys_openat(
|
|
|
1e08b3 |
fdcwd,
|
|
|
1e08b3 |
(const unsigned char *)cntpath_utf8,
|
|
|
1e08b3 |
0,0);
|
|
|
1e08b3 |
|
|
|
1e08b3 |
if (cntfd >= 0)
|
|
|
1e08b3 |
if (!(cntofd = __xfi_ofd_ref_inc(cntfd)))
|
|
|
1e08b3 |
__sys_close(cntfd);
|
|
|
1e08b3 |
}
|
|
|
1e08b3 |
}
|
|
|
1e08b3 |
}
|
|
|
1e08b3 |
|
|
|
1e08b3 |
__xfi_free_virtual_memory(
|
|
|
1e08b3 |
NT_CURRENT_PROCESS_HANDLE,
|
|
|
1e08b3 |
&cntbuf,
|
|
|
1e08b3 |
&cntbufsize,
|
|
|
1e08b3 |
NT_MEM_RELEASE);
|
|
|
1e08b3 |
|
|
|
1e08b3 |
if (!cntofd)
|
|
|
1e08b3 |
return ntux_cmd_chmod_ret(
|
|
|
1e08b3 |
fd,ofd,hasync,
|
|
|
1e08b3 |
NTUX_CUSTOM_ERROR(
|
|
|
1e08b3 |
dctx,
|
|
|
1e08b3 |
NTUX_ERR_FLOW_ERROR));
|
|
|
1e08b3 |
|
|
|
1e08b3 |
status = __xfi_query_security_object(
|
|
|
1e08b3 |
cntofd->info.hfile,
|
|
|
1e08b3 |
NT_OWNER_SECURITY_INFORMATION
|
|
|
1e08b3 |
| NT_GROUP_SECURITY_INFORMATION
|
|
|
1e08b3 |
| NT_DACL_SECURITY_INFORMATION,
|
|
|
1e08b3 |
&cntsd.sd.sd,sizeof(cntsd),&size);
|
|
|
1e08b3 |
|
|
|
1e08b3 |
if (status) {
|
|
|
1e08b3 |
__xfi_ofd_ref_dec(cntofd);
|
|
|
1e08b3 |
__sys_close(cntfd);
|
|
|
1e08b3 |
|
|
|
1e08b3 |
return ntux_cmd_chmod_ret(
|
|
|
1e08b3 |
fd,ofd,hasync,
|
|
|
1e08b3 |
NTUX_SYSTEM_ERROR(dctx));
|
|
|
1e08b3 |
}
|
|
|
1e08b3 |
|
|
|
1e08b3 |
/* exacefilter */
|
|
|
1e08b3 |
exacefilter = __xfi_ofd_is_dir(ofd)
|
|
|
1e08b3 |
? NT_ACE_CONTAINER_INHERIT
|
|
|
1e08b3 |
: NT_ACE_OBJECT_INHERIT;
|
|
|
1e08b3 |
|
|
|
1e08b3 |
/* exacecount, exacesize */
|
|
|
1e08b3 |
if (cntsd.sd.sd.offset_dacl) {
|
|
|
1e08b3 |
addr = (size_t)&cntsd.sd.sd;
|
|
|
1e08b3 |
addr += cntsd.sd.sd.offset_dacl;
|
|
|
1e08b3 |
dacl = (nt_acl *)addr;
|
|
|
1e08b3 |
|
|
|
1e08b3 |
addr += sizeof(*dacl);
|
|
|
1e08b3 |
|
|
|
1e08b3 |
exacecount = 0;
|
|
|
1e08b3 |
exacesize = 0;
|
|
|
1e08b3 |
|
|
|
1e08b3 |
for (idx=0; idx<dacl->ace_count; idx++) {
|
|
|
1e08b3 |
srcace = (struct ntux_ace_any *)addr;
|
|
|
1e08b3 |
|
|
|
1e08b3 |
if (srcace->header.ace_flags & exacefilter) {
|
|
|
1e08b3 |
exacecount++;
|
|
|
1e08b3 |
exacesize += srcace->header.ace_size;
|
|
|
1e08b3 |
}
|
|
|
1e08b3 |
|
|
|
1e08b3 |
addr += srcace->header.ace_size;
|
|
|
1e08b3 |
}
|
|
|
1e08b3 |
|
|
|
1e08b3 |
|
|
|
1e08b3 |
/* dstsd::dacl */
|
|
|
1e08b3 |
addr = (size_t)dstsd;
|
|
|
1e08b3 |
addr += dstsd->sd.offset_dacl;
|
|
|
1e08b3 |
dacl = (nt_acl *)addr;
|
|
|
1e08b3 |
|
|
|
1e08b3 |
if (dstsd->sd.offset_dacl + dacl->acl_size + exacesize > sizeof(sdbuf)) {
|
|
|
1e08b3 |
__xfi_ofd_ref_dec(cntofd);
|
|
|
1e08b3 |
__sys_close(cntfd);
|
|
|
1e08b3 |
|
|
|
1e08b3 |
return ntux_cmd_chmod_ret(
|
|
|
1e08b3 |
fd,ofd,hasync,
|
|
|
1e08b3 |
NTUX_BUFFER_ERROR(dctx));
|
|
|
1e08b3 |
}
|
|
|
1e08b3 |
|
|
|
1e08b3 |
dacl->acl_size += exacesize;
|
|
|
1e08b3 |
dacl->ace_count += exacecount;
|
|
|
1e08b3 |
|
|
|
1e08b3 |
/* pointer to dstsd's next ace */
|
|
|
1e08b3 |
aceaddr = addr;
|
|
|
1e08b3 |
aceaddr += sizeof(*dacl);
|
|
|
1e08b3 |
|
|
|
1e08b3 |
for (idx=0; idx<dacl->ace_count; idx++) {
|
|
|
1e08b3 |
dstace = (struct ntux_ace_any *)aceaddr;
|
|
|
1e08b3 |
aceaddr += dstace->header.ace_size;
|
|
|
1e08b3 |
}
|
|
|
1e08b3 |
|
|
|
1e08b3 |
dstace = (struct ntux_ace_any *)aceaddr;
|
|
|
1e08b3 |
|
|
|
1e08b3 |
/* copy container's ace's according to filter */
|
|
|
1e08b3 |
addr = (size_t)&cntsd.sd.sd;
|
|
|
1e08b3 |
addr += cntsd.sd.sd.offset_dacl;
|
|
|
1e08b3 |
dacl = (nt_acl *)addr;
|
|
|
1e08b3 |
addr += sizeof(*dacl);
|
|
|
1e08b3 |
|
|
|
1e08b3 |
for (idx=0; idx<dacl->ace_count; idx++) {
|
|
|
1e08b3 |
srcace = (struct ntux_ace_any *)addr;
|
|
|
1e08b3 |
|
|
|
1e08b3 |
if (srcace->header.ace_flags & exacefilter) {
|
|
|
1e08b3 |
ntux_memcpy(dstace,srcace,srcace->header.ace_size);
|
|
|
076f4d |
dstace->header.ace_flags = NT_ACE_INHERITED | ace_flags;
|
|
|
1e08b3 |
|
|
|
1e08b3 |
aceaddr += srcace->header.ace_size;
|
|
|
1e08b3 |
dstace = (struct ntux_ace_any *)aceaddr;
|
|
|
1e08b3 |
}
|
|
|
1e08b3 |
|
|
|
1e08b3 |
addr += srcace->header.ace_size;
|
|
|
1e08b3 |
}
|
|
|
1e08b3 |
}
|
|
|
1e08b3 |
}
|
|
|
1e08b3 |
|
|
|
1e08b3 |
/* finalize */
|
|
|
162c96 |
sec_mask = NT_DACL_SECURITY_INFORMATION;
|
|
|
162c96 |
sec_mask |= owner ? NT_OWNER_SECURITY_INFORMATION : 0;
|
|
|
162c96 |
|
|
|
471bb0 |
if ((status = __xfi_set_security_object(
|
|
|
1e08b3 |
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 |
|
|
|
1e08b3 |
/* cntofd */
|
|
|
1e08b3 |
if (cntofd) {
|
|
|
1e08b3 |
__xfi_ofd_ref_dec(cntofd);
|
|
|
1e08b3 |
__sys_close(cntfd);
|
|
|
1e08b3 |
}
|
|
|
1e08b3 |
|
|
|
eb0350 |
/* all done */
|
|
|
eb0350 |
return ntux_cmd_chmod_ret(fd,ofd,hasync,0);
|
|
|
80f43a |
}
|