diff options
Diffstat (limited to 'src/cmds')
-rw-r--r-- | src/cmds/ntux_cmd_chmod.c | 96 |
1 files changed, 87 insertions, 9 deletions
diff --git a/src/cmds/ntux_cmd_chmod.c b/src/cmds/ntux_cmd_chmod.c index a0fec1d..ab06dab 100644 --- a/src/cmds/ntux_cmd_chmod.c +++ b/src/cmds/ntux_cmd_chmod.c @@ -86,6 +86,7 @@ int ntux_cmd_chmod(const struct ntux_driver_ctx * dctx, const char * dunit) int optmode; const char * strmode; const char * chmode; + const unsigned char * refobj; const unsigned char * unit; char * ch; struct ntux_sd_buffer sdbuf; @@ -115,8 +116,10 @@ int ntux_cmd_chmod(const struct ntux_driver_ctx * dctx, const char * dunit) int exacecount; int idx; int fd = -1; + int reffd = -1; int cntfd = -1; struct __ofd * ofd = 0; + struct __ofd * refofd = 0; struct __ofd * cntofd = 0; void * cntbuf = 0; void * hasync = 0; @@ -195,6 +198,15 @@ int ntux_cmd_chmod(const struct ntux_driver_ctx * dctx, const char * dunit) } } + /* conflicting arguments? */ + if (finherit && dctx->cctx->refobj) + return ntux_cmd_chmod_ret( + 0,0,0, + NTUX_CUSTOM_ERROR( + dctx, + NTUX_ERR_CONFLICTING_ARGUMENTS)); + + /* initial --owner and --group support: Administrators, SYSTEM */ owner = 0; group = 0; @@ -242,6 +254,7 @@ int ntux_cmd_chmod(const struct ntux_driver_ctx * dctx, const char * dunit) dctx, NTUX_ERR_FLOW_ERROR)); + /* hasync */ sec_mask = NT_SEC_READ_CONTROL; sec_mask |= NT_SEC_WRITE_DAC; @@ -259,21 +272,86 @@ int ntux_cmd_chmod(const struct ntux_driver_ctx * dctx, const char * dunit) fd,ofd,0, NTUX_SYSTEM_ERROR(dctx)); + /* refofd */ + if ((refobj = (const unsigned char *)dctx->cctx->refobj)) { + ntux_driver_set_ectx( + dctx,0,dctx->cctx->refobj); + + if ((ret = __sys_openat(fdcwd,refobj,0,0)) < 0) + if (ntux_errno_set(dctx,ret)) + return ntux_cmd_chmod_ret( + 0,0,0, + NTUX_SYSTEM_ERROR(dctx)); + + reffd = ret; + + if (!(refofd = __xfi_ofd_ref_inc(reffd))) { + __sys_close(reffd); + + return ntux_cmd_chmod_ret( + fd,0,0, + NTUX_CUSTOM_ERROR( + dctx, + NTUX_ERR_FLOW_ERROR)); + } + + ntux_driver_set_ectx( + dctx,0,dunit); + } + /* srcsd */ - if ((status = __xfi_query_security_object( - hasync, - NT_OWNER_SECURITY_INFORMATION - | NT_GROUP_SECURITY_INFORMATION - | NT_DACL_SECURITY_INFORMATION, - &srcsd.sd.sd,sizeof(srcsd),&size))) + status = __xfi_query_security_object( + refobj ? refofd->info.hfile : hasync, + NT_OWNER_SECURITY_INFORMATION + | NT_GROUP_SECURITY_INFORMATION + | NT_DACL_SECURITY_INFORMATION, + &srcsd.sd.sd,sizeof(srcsd),&size); + + if (refofd) { + __xfi_ofd_ref_dec(refofd); + __sys_close(reffd); + } + + if (status) if (ntux_errno_set(dctx,ENXIO)) return ntux_cmd_chmod_ret( fd,ofd,hasync, NTUX_SYSTEM_ERROR(dctx)); - if ((status = __xfi_acl_init_common_descriptor_meta( - &meta,&srcsd.sd.sd, - NT_ACL_INIT_COMMON_DESCRIPTION_META_STRICT_MODE))) + status = __xfi_acl_init_common_descriptor_meta( + &meta,&srcsd.sd.sd, + NT_ACL_INIT_COMMON_DESCRIPTION_META_STRICT_MODE); + + /* sd copy based on a non-posix object? */ + if (status && refobj) { + ntux_driver_set_ectx( + dctx,0,dctx->cctx->refobj); + + if (dctx->cctx->strmode + || dctx->cctx->owner + || dctx->cctx->group) + return ntux_cmd_chmod_ret( + 0,0,0, + NTUX_CUSTOM_ERROR( + dctx, + NTUX_ERR_NON_POSIX_DESCRIPTOR)); + + ntux_driver_set_ectx( + dctx,0,dunit); + + sec_mask = NT_DACL_SECURITY_INFORMATION; + + if ((status = __xfi_set_security_object( + hasync,sec_mask,&srcsd.sd.sd))) + if (ntux_errno_set(dctx,EPERM)) + return ntux_cmd_chmod_ret( + fd,ofd,hasync, + NTUX_SYSTEM_ERROR(dctx)); + + return ntux_cmd_chmod_ret(fd,ofd,hasync,0); + } + + if (status) if (ntux_errno_set(dctx,EBADF)) return ntux_cmd_chmod_ret( fd,ofd,hasync, |