summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--include/ntux/ntux.h2
-rw-r--r--src/cmds/ntux_cmd_chmod.c96
-rw-r--r--src/output/ntux_output_error.c22
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";