diff options
-rw-r--r-- | include/ntux/ntux.h | 2 | ||||
-rw-r--r-- | src/cmds/ntux_cmd_chmod.c | 96 | ||||
-rw-r--r-- | src/output/ntux_output_error.c | 22 |
3 files changed, 111 insertions, 9 deletions
diff --git a/include/ntux/ntux.h b/include/ntux/ntux.h index 1a6cdea..6b00476 100644 --- a/include/ntux/ntux.h +++ b/include/ntux/ntux.h @@ -62,6 +62,8 @@ enum ntux_custom_error { NTUX_ERR_FLEE_ERROR, NTUX_ERR_LDSO_INIT, NTUX_ERR_NOT_IMPLEMENTED, + NTUX_ERR_CONFLICTING_ARGUMENTS, + NTUX_ERR_NON_POSIX_DESCRIPTOR, }; enum ntux_cmd { 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, diff --git a/src/output/ntux_output_error.c b/src/output/ntux_output_error.c index b1a3a96..3324a71 100644 --- a/src/output/ntux_output_error.c +++ b/src/output/ntux_output_error.c @@ -46,6 +46,22 @@ static const char * ntux_output_unit_header(const struct ntux_error_info * erri) return "while querying"; } +static const char * ntux_output_chmod_strerror( + const struct ntux_driver_ctx * dctx, + const struct ntux_error_info * erri) +{ + (void)dctx; + + if (erri->elibcode == NTUX_ERR_CONFLICTING_ARGUMENTS) + return "chmod conflicting arguments: +P cannot be used together with --refobj"; + + else if (erri->elibcode == NTUX_ERR_NON_POSIX_DESCRIPTOR) + return "chmod: cannot amend a referenced non-posix security descriptor"; + + else + return "ntux_output_chmod_strerror(): unhandled custom error"; +} + static const char * ntux_output_strerror( const struct ntux_driver_ctx * dctx, const struct ntux_error_info * erri) @@ -61,6 +77,12 @@ static const char * ntux_output_strerror( if ((erri->eflags & NTUX_ERROR_CUSTOM) && (erri->elibcode == NTUX_ERR_NOT_IMPLEMENTED)) return "status: support for one or more option values is not yet implemented"; + else if ((erri->eflags & NTUX_ERROR_CUSTOM) && (erri->elibcode == NTUX_ERR_CONFLICTING_ARGUMENTS)) + return ntux_output_chmod_strerror(dctx,erri); + + else if ((erri->eflags & NTUX_ERROR_CUSTOM) && (erri->elibcode == NTUX_ERR_NON_POSIX_DESCRIPTOR)) + return ntux_output_chmod_strerror(dctx,erri); + else if (erri->eflags & NTUX_ERROR_CUSTOM) return "flow error: unexpected condition or other"; |