From a0ac7a7f4c0290787cdadb5866272cee2bd61b8a Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Tue, 26 Jun 2007 22:49:10 +0000 Subject: r23620: Convert set_nt_acl to return NTSTATUS. Also fix the chown return to correctly return NT_STATUS_INVALID_OWNER if it should be disallowed. Matches better what W2K3R3 does. NFSv4 ACL module owners, please examine these changes. Jeremy. (This used to be commit fc6899a5506b272f8cd5f5837ca13300b4e69a5f) --- examples/VFS/skel_opaque.c | 8 ++-- examples/VFS/skel_transparent.c | 4 +- source3/include/vfs.h | 5 ++- source3/modules/nfs4_acls.c | 65 ++++++++++------------------ source3/modules/vfs_afsacl.c | 8 ++-- source3/modules/vfs_aixacl2.c | 10 ++--- source3/modules/vfs_cap.c | 2 +- source3/modules/vfs_catia.c | 2 +- source3/modules/vfs_default.c | 8 ++-- source3/modules/vfs_full_audit.c | 16 +++---- source3/modules/vfs_gpfs.c | 10 ++--- source3/modules/vfs_zfsacl.c | 6 +-- source3/rpc_server/srv_srvsvc_nt.c | 5 +-- source3/smbd/nttrans.c | 12 ++--- source3/smbd/posix_acls.c | 89 ++++++++++++++------------------------ 15 files changed, 100 insertions(+), 150 deletions(-) diff --git a/examples/VFS/skel_opaque.c b/examples/VFS/skel_opaque.c index 6204ef47f4..1ba6a9b13b 100644 --- a/examples/VFS/skel_opaque.c +++ b/examples/VFS/skel_opaque.c @@ -295,18 +295,18 @@ static size_t skel_get_nt_acl(vfs_handle_struct *handle, files_struct *fsp, return 0; } -static BOOL skel_fset_nt_acl(vfs_handle_struct *handle, files_struct *fsp, int +static NTSTATUS skel_fset_nt_acl(vfs_handle_struct *handle, files_struct *fsp, int fd, uint32 security_info_sent, SEC_DESC *psd) { errno = ENOSYS; - return False; + return NT_STATUS_NOT_IMPLEMENTED; } -static BOOL skel_set_nt_acl(vfs_handle_struct *handle, files_struct *fsp, const +static NTSTATUS skel_set_nt_acl(vfs_handle_struct *handle, files_struct *fsp, const char *name, uint32 security_info_sent, SEC_DESC *psd) { errno = ENOSYS; - return False; + return NT_STATUS_NOT_IMPLEMENTED; } static int skel_chmod_acl(vfs_handle_struct *handle, const char *name, mode_t mode) diff --git a/examples/VFS/skel_transparent.c b/examples/VFS/skel_transparent.c index a422b7ce00..746fa31736 100644 --- a/examples/VFS/skel_transparent.c +++ b/examples/VFS/skel_transparent.c @@ -286,13 +286,13 @@ static size_t skel_get_nt_acl(vfs_handle_struct *handle, files_struct *fsp, return SMB_VFS_NEXT_GET_NT_ACL(handle, fsp, name, security_info, ppdesc); } -static BOOL skel_fset_nt_acl(vfs_handle_struct *handle, files_struct *fsp, +static NTSTATUS skel_fset_nt_acl(vfs_handle_struct *handle, files_struct *fsp, int fd, uint32 security_info_sent, SEC_DESC *psd) { return SMB_VFS_NEXT_FSET_NT_ACL(handle, fsp, fd, security_info_sent, psd); } -static BOOL skel_set_nt_acl(vfs_handle_struct *handle, files_struct *fsp, +static NTSTATUS skel_set_nt_acl(vfs_handle_struct *handle, files_struct *fsp, const char *name, uint32 security_info_sent, SEC_DESC *psd) { return SMB_VFS_NEXT_SET_NT_ACL(handle, fsp, name, security_info_sent, psd); diff --git a/source3/include/vfs.h b/source3/include/vfs.h index eac9eced16..d968ba9d82 100644 --- a/source3/include/vfs.h +++ b/source3/include/vfs.h @@ -71,6 +71,7 @@ * timestamp resolition. JRA. */ /* Changed to version21 to add chflags operation -- jpeach */ /* Changed to version22 to add lchown operation -- jra */ +/* Leave at 22 - not yet released. But change set_nt_acl to return an NTSTATUS. jra. */ #define SMB_VFS_INTERFACE_VERSION 22 @@ -300,8 +301,8 @@ struct vfs_ops { size_t (*fget_nt_acl)(struct vfs_handle_struct *handle, struct files_struct *fsp, int fd, uint32 security_info, struct security_descriptor **ppdesc); size_t (*get_nt_acl)(struct vfs_handle_struct *handle, struct files_struct *fsp, const char *name, uint32 security_info, struct security_descriptor **ppdesc); - BOOL (*fset_nt_acl)(struct vfs_handle_struct *handle, struct files_struct *fsp, int fd, uint32 security_info_sent, struct security_descriptor *psd); - BOOL (*set_nt_acl)(struct vfs_handle_struct *handle, struct files_struct *fsp, const char *name, uint32 security_info_sent, struct security_descriptor *psd); + NTSTATUS (*fset_nt_acl)(struct vfs_handle_struct *handle, struct files_struct *fsp, int fd, uint32 security_info_sent, struct security_descriptor *psd); + NTSTATUS (*set_nt_acl)(struct vfs_handle_struct *handle, struct files_struct *fsp, const char *name, uint32 security_info_sent, struct security_descriptor *psd); /* POSIX ACL operations. */ diff --git a/source3/modules/nfs4_acls.c b/source3/modules/nfs4_acls.c index 1da8d1b7a3..30c209dd93 100644 --- a/source3/modules/nfs4_acls.c +++ b/source3/modules/nfs4_acls.c @@ -42,7 +42,7 @@ typedef struct _SMB_ACL4_INT_T extern struct current_user current_user; extern int try_chown(connection_struct *conn, const char *fname, uid_t uid, gid_t gid); -extern BOOL unpack_nt_owners(int snum, uid_t *puser, gid_t *pgrp, +extern NTSTATUS unpack_nt_owners(int snum, uid_t *puser, gid_t *pgrp, uint32 security_info_sent, SEC_DESC *psd); static SMB_ACL4_INT_T *get_validated_aclint(SMB4ACL_T *acl) @@ -559,7 +559,7 @@ static SMB4ACL_T *smbacl4_win2nfs4( return acl; } -BOOL smb_set_nt_acl_nfs4(files_struct *fsp, +NTSTATUS smb_set_nt_acl_nfs4(files_struct *fsp, uint32 security_info_sent, SEC_DESC *psd, set_nfs4acl_native_fn_t set_nfs4_native) @@ -569,7 +569,6 @@ BOOL smb_set_nt_acl_nfs4(files_struct *fsp, BOOL result; SMB_STRUCT_STAT sbuf; - BOOL need_chown = False; uid_t newUID = (uid_t)-1; gid_t newGID = (gid_t)-1; @@ -580,43 +579,37 @@ BOOL smb_set_nt_acl_nfs4(files_struct *fsp, { DEBUG(9, ("security_info_sent (0x%x) ignored\n", security_info_sent)); - return True; /* won't show error - later to be refined... */ + return NT_STATUS_OK; /* won't show error - later to be refined... */ } /* Special behaviours */ if (smbacl4_get_vfs_params(SMBACL4_PARAM_TYPE_NAME, fsp, ¶ms)) - return False; + return NT_STATUS_NO_MEMORY; if (smbacl4_GetFileOwner(fsp, &sbuf)) - return False; + return map_nt_error_from_unix(errno); if (params.do_chown) { /* chown logic is a copy/paste from posix_acl.c:set_nt_acl */ - if (!unpack_nt_owners(SNUM(fsp->conn), &newUID, &newGID, security_info_sent, psd)) - { + NTSTATUS status = unpack_nt_owners(SNUM(fsp->conn), &newUID, &newGID, security_info_sent, psd); + if (!NT_STATUS_IS_OK(status)) { DEBUG(8, ("unpack_nt_owners failed")); - return False; + return status; } if (((newUID != (uid_t)-1) && (sbuf.st_uid != newUID)) || - ((newGID != (gid_t)-1) && (sbuf.st_gid != newGID))) { - need_chown = True; - } - if (need_chown) { - if ((newUID == (uid_t)-1 || newUID == current_user.ut.uid)) { - if(try_chown(fsp->conn, fsp->fsp_name, newUID, newGID)) { - DEBUG(3,("chown %s, %u, %u failed. Error = %s.\n", - fsp->fsp_name, (unsigned int)newUID, (unsigned int)newGID, strerror(errno) )); - return False; + ((newGID != (gid_t)-1) && (sbuf.st_gid != newGID))) { + if(try_chown(fsp->conn, fsp->fsp_name, newUID, newGID)) { + DEBUG(3,("chown %s, %u, %u failed. Error = %s.\n", + fsp->fsp_name, (unsigned int)newUID, (unsigned int)newGID, strerror(errno) )); + if (errno == EPERM) { + return NT_STATUS_INVALID_OWNER; } - DEBUG(10,("chown %s, %u, %u succeeded.\n", - fsp->fsp_name, (unsigned int)newUID, (unsigned int)newGID)); - if (smbacl4_GetFileOwner(fsp, &sbuf)) - return False; - need_chown = False; - } else { /* chown is needed, but _after_ changing acl */ - sbuf.st_uid = newUID; /* OWNER@ in case of e_special */ - sbuf.st_gid = newGID; /* GROUP@ in case of e_special */ + return map_nt_error_from_unix(errno); } + DEBUG(10,("chown %s, %u, %u succeeded.\n", + fsp->fsp_name, (unsigned int)newUID, (unsigned int)newGID)); + if (smbacl4_GetFileOwner(fsp, &sbuf)) + return map_nt_error_from_unix(errno); } } @@ -624,7 +617,7 @@ BOOL smb_set_nt_acl_nfs4(files_struct *fsp, { acl = smbacl4_win2nfs4(psd->dacl, ¶ms, sbuf.st_uid, sbuf.st_gid); if (!acl) - return False; + return map_nt_error_from_unix(errno); smbacl4_dump_nfs4acl(10, acl); @@ -632,25 +625,11 @@ BOOL smb_set_nt_acl_nfs4(files_struct *fsp, if (result!=True) { DEBUG(10, ("set_nfs4_native failed with %s\n", strerror(errno))); - return False; + return map_nt_error_from_unix(errno); } } else DEBUG(10, ("no dacl found; security_info_sent = 0x%x\n", security_info_sent)); - /* Any chown pending? */ - if (need_chown) { - DEBUG(3,("chown#2 %s. uid = %u, gid = %u.\n", - fsp->fsp_name, (unsigned int)newUID, (unsigned int)newGID)); - if (try_chown(fsp->conn, fsp->fsp_name, newUID, newGID)) { - DEBUG(2,("chown#2 %s, %u, %u failed. Error = %s.\n", - fsp->fsp_name, (unsigned int)newUID, (unsigned int)newGID, - strerror(errno))); - return False; - } - DEBUG(10,("chown#2 %s, %u, %u succeeded.\n", - fsp->fsp_name, (unsigned int)newUID, (unsigned int)newGID)); - } - DEBUG(10, ("smb_set_nt_acl_nfs4 succeeded\n")); - return True; + return NT_STATUS_OK; } diff --git a/source3/modules/vfs_afsacl.c b/source3/modules/vfs_afsacl.c index 47e8ec5aef..2f472df28c 100644 --- a/source3/modules/vfs_afsacl.c +++ b/source3/modules/vfs_afsacl.c @@ -883,7 +883,7 @@ static void merge_unknown_aces(struct afs_acl *src, struct afs_acl *dst) } } -static BOOL afs_set_nt_acl(vfs_handle_struct *handle, files_struct *fsp, +static NTSTATUS afs_set_nt_acl(vfs_handle_struct *handle, files_struct *fsp, uint32 security_info_sent, struct security_descriptor *psd) { @@ -980,7 +980,7 @@ static BOOL afs_set_nt_acl(vfs_handle_struct *handle, files_struct *fsp, free_afs_acl(&old_afs_acl); free_afs_acl(&new_afs_acl); - return (ret == 0); + return (ret == 0) ? NT_STATUS_OK : NT_STATUS_ACCESS_DENIED; } static size_t afsacl_fget_nt_acl(struct vfs_handle_struct *handle, @@ -998,7 +998,7 @@ static size_t afsacl_get_nt_acl(struct vfs_handle_struct *handle, return afs_get_nt_acl(fsp, security_info, ppdesc); } -BOOL afsacl_fset_nt_acl(vfs_handle_struct *handle, +NTSTATUS afsacl_fset_nt_acl(vfs_handle_struct *handle, files_struct *fsp, int fd, uint32 security_info_sent, SEC_DESC *psd) @@ -1006,7 +1006,7 @@ BOOL afsacl_fset_nt_acl(vfs_handle_struct *handle, return afs_set_nt_acl(handle, fsp, security_info_sent, psd); } -BOOL afsacl_set_nt_acl(vfs_handle_struct *handle, +NTSTATUS afsacl_set_nt_acl(vfs_handle_struct *handle, files_struct *fsp, const char *name, uint32 security_info_sent, SEC_DESC *psd) diff --git a/source3/modules/vfs_aixacl2.c b/source3/modules/vfs_aixacl2.c index f1e116ec19..0ec2e6a5b3 100644 --- a/source3/modules/vfs_aixacl2.c +++ b/source3/modules/vfs_aixacl2.c @@ -366,10 +366,10 @@ static BOOL aixjfs2_process_smbacl(files_struct *fsp, SMB4ACL_T *smbacl) return True; } -static BOOL aixjfs2_set_nt_acl_common(files_struct *fsp, uint32 security_info_sent, SEC_DESC *psd) +static NTSTATUS aixjfs2_set_nt_acl_common(files_struct *fsp, uint32 security_info_sent, SEC_DESC *psd) { acl_type_t acl_type_info; - BOOL result = False; + NTSTATUS result = NT_STATUS_ACCESS_DENIED; int rc; rc = aixjfs2_query_acl_support( @@ -385,17 +385,17 @@ static BOOL aixjfs2_set_nt_acl_common(files_struct *fsp, uint32 security_info_se } else if (rc==1) { /* assume POSIX ACL - by default... */ result = set_nt_acl(fsp, security_info_sent, psd); } else - result = False; /* query failed */ + result = map_nt_error_from_unix(errno); /* query failed */ return result; } -BOOL aixjfs2_fset_nt_acl(vfs_handle_struct *handle, files_struct *fsp, int fd, uint32 security_info_sent, SEC_DESC *psd) +NTSTATUS aixjfs2_fset_nt_acl(vfs_handle_struct *handle, files_struct *fsp, int fd, uint32 security_info_sent, SEC_DESC *psd) { return aixjfs2_set_nt_acl_common(fsp, security_info_sent, psd); } -BOOL aixjfs2_set_nt_acl(vfs_handle_struct *handle, files_struct *fsp, const char *name, uint32 security_info_sent, SEC_DESC *psd) +NTSTATUS aixjfs2_set_nt_acl(vfs_handle_struct *handle, files_struct *fsp, const char *name, uint32 security_info_sent, SEC_DESC *psd) { return aixjfs2_set_nt_acl_common(fsp, security_info_sent, psd); } diff --git a/source3/modules/vfs_cap.c b/source3/modules/vfs_cap.c index ab99031e4d..04dbec95b6 100644 --- a/source3/modules/vfs_cap.c +++ b/source3/modules/vfs_cap.c @@ -184,7 +184,7 @@ static char *cap_realpath(vfs_handle_struct *handle, const char *path, char *res return SMB_VFS_NEXT_REALPATH(handle, path, resolved_path); } -static BOOL cap_set_nt_acl(vfs_handle_struct *handle, files_struct *fsp, const char *name, uint32 security_info_sent, struct security_descriptor *psd) +static NTSTATUS cap_set_nt_acl(vfs_handle_struct *handle, files_struct *fsp, const char *name, uint32 security_info_sent, struct security_descriptor *psd) { pstring capname; capencode(capname, name); diff --git a/source3/modules/vfs_catia.c b/source3/modules/vfs_catia.c index a32bd59d5c..a4a2f8f7bd 100644 --- a/source3/modules/vfs_catia.c +++ b/source3/modules/vfs_catia.c @@ -238,7 +238,7 @@ static size_t catia_get_nt_acl(vfs_handle_struct *handle, files_struct *fsp, ppdesc); } -static BOOL catia_set_nt_acl(vfs_handle_struct *handle, files_struct *fsp, +static NTSTATUS catia_set_nt_acl(vfs_handle_struct *handle, files_struct *fsp, const char *name, uint32 security_info_sent, struct security_descriptor_info *psd) { diff --git a/source3/modules/vfs_default.c b/source3/modules/vfs_default.c index 28fe4d4ea7..930b7c8507 100644 --- a/source3/modules/vfs_default.c +++ b/source3/modules/vfs_default.c @@ -947,9 +947,9 @@ static size_t vfswrap_get_nt_acl(vfs_handle_struct *handle, files_struct *fsp, c return result; } -static BOOL vfswrap_fset_nt_acl(vfs_handle_struct *handle, files_struct *fsp, int fd, uint32 security_info_sent, SEC_DESC *psd) +static NTSTATUS vfswrap_fset_nt_acl(vfs_handle_struct *handle, files_struct *fsp, int fd, uint32 security_info_sent, SEC_DESC *psd) { - BOOL result; + NTSTATUS result; START_PROFILE(fset_nt_acl); result = set_nt_acl(fsp, security_info_sent, psd); @@ -957,9 +957,9 @@ static BOOL vfswrap_fset_nt_acl(vfs_handle_struct *handle, files_struct *fsp, in return result; } -static BOOL vfswrap_set_nt_acl(vfs_handle_struct *handle, files_struct *fsp, const char *name, uint32 security_info_sent, SEC_DESC *psd) +static NTSTATUS vfswrap_set_nt_acl(vfs_handle_struct *handle, files_struct *fsp, const char *name, uint32 security_info_sent, SEC_DESC *psd) { - BOOL result; + NTSTATUS result; START_PROFILE(set_nt_acl); result = set_nt_acl(fsp, security_info_sent, psd); diff --git a/source3/modules/vfs_full_audit.c b/source3/modules/vfs_full_audit.c index cd434f1951..e76cb9fc23 100644 --- a/source3/modules/vfs_full_audit.c +++ b/source3/modules/vfs_full_audit.c @@ -191,10 +191,10 @@ static size_t smb_full_audit_fget_nt_acl(vfs_handle_struct *handle, files_struct static size_t smb_full_audit_get_nt_acl(vfs_handle_struct *handle, files_struct *fsp, const char *name, uint32 security_info, SEC_DESC **ppdesc); -static BOOL smb_full_audit_fset_nt_acl(vfs_handle_struct *handle, files_struct *fsp, +static NTSTATUS smb_full_audit_fset_nt_acl(vfs_handle_struct *handle, files_struct *fsp, int fd, uint32 security_info_sent, SEC_DESC *psd); -static BOOL smb_full_audit_set_nt_acl(vfs_handle_struct *handle, files_struct *fsp, +static NTSTATUS smb_full_audit_set_nt_acl(vfs_handle_struct *handle, files_struct *fsp, const char *name, uint32 security_info_sent, SEC_DESC *psd); static int smb_full_audit_chmod_acl(vfs_handle_struct *handle, @@ -1497,30 +1497,30 @@ static size_t smb_full_audit_get_nt_acl(vfs_handle_struct *handle, files_struct return result; } -static BOOL smb_full_audit_fset_nt_acl(vfs_handle_struct *handle, files_struct *fsp, +static NTSTATUS smb_full_audit_fset_nt_acl(vfs_handle_struct *handle, files_struct *fsp, int fd, uint32 security_info_sent, SEC_DESC *psd) { - BOOL result; + NTSTATUS result; result = SMB_VFS_NEXT_FSET_NT_ACL(handle, fsp, fd, security_info_sent, psd); - do_log(SMB_VFS_OP_FSET_NT_ACL, result, handle, "%s", fsp->fsp_name); + do_log(SMB_VFS_OP_FSET_NT_ACL, NT_STATUS_IS_OK(result), handle, "%s", fsp->fsp_name); return result; } -static BOOL smb_full_audit_set_nt_acl(vfs_handle_struct *handle, files_struct *fsp, +static NTSTATUS smb_full_audit_set_nt_acl(vfs_handle_struct *handle, files_struct *fsp, const char *name, uint32 security_info_sent, SEC_DESC *psd) { - BOOL result; + NTSTATUS result; result = SMB_VFS_NEXT_SET_NT_ACL(handle, fsp, name, security_info_sent, psd); - do_log(SMB_VFS_OP_SET_NT_ACL, result, handle, "%s", fsp->fsp_name); + do_log(SMB_VFS_OP_SET_NT_ACL, NT_STATUS_IS_OK(result), handle, "%s", fsp->fsp_name); return result; } diff --git a/source3/modules/vfs_gpfs.c b/source3/modules/vfs_gpfs.c index 3795a5d4a6..9c9503e772 100644 --- a/source3/modules/vfs_gpfs.c +++ b/source3/modules/vfs_gpfs.c @@ -334,14 +334,14 @@ static BOOL gpfsacl_process_smbacl(files_struct *fsp, SMB4ACL_T *smbacl) return True; } -static BOOL gpfsacl_set_nt_acl_internal(files_struct *fsp, uint32 security_info_sent, SEC_DESC *psd) +static NTSTATUS gpfsacl_set_nt_acl_internal(files_struct *fsp, uint32 security_info_sent, SEC_DESC *psd) { struct gpfs_acl *acl; - BOOL result = False; + NTSTATUS result = NT_STATUS_ACCESS_DENIED; acl = gpfs_getacl_alloc(fsp->fsp_name, GPFS_ACL_TYPE_ACCESS); if (acl == NULL) - return False; + return result; if (acl->acl_version&GPFS_ACL_VERSION_NFS4) { @@ -355,12 +355,12 @@ static BOOL gpfsacl_set_nt_acl_internal(files_struct *fsp, uint32 security_info_ return result; } -static BOOL gpfsacl_fset_nt_acl(vfs_handle_struct *handle, files_struct *fsp, int fd, uint32 security_info_sent, SEC_DESC *psd) +static NTSTATUS gpfsacl_fset_nt_acl(vfs_handle_struct *handle, files_struct *fsp, int fd, uint32 security_info_sent, SEC_DESC *psd) { return gpfsacl_set_nt_acl_internal(fsp, security_info_sent, psd); } -static BOOL gpfsacl_set_nt_acl(vfs_handle_struct *handle, files_struct *fsp, char *name, uint32 security_info_sent, SEC_DESC *psd) +static NTSTATUS gpfsacl_set_nt_acl(vfs_handle_struct *handle, files_struct *fsp, char *name, uint32 security_info_sent, SEC_DESC *psd) { return gpfsacl_set_nt_acl_internal(fsp, security_info_sent, psd); } diff --git a/source3/modules/vfs_zfsacl.c b/source3/modules/vfs_zfsacl.c index 79602c2221..a68258cfdb 100644 --- a/source3/modules/vfs_zfsacl.c +++ b/source3/modules/vfs_zfsacl.c @@ -125,7 +125,7 @@ static BOOL zfs_process_smbacl(files_struct *fsp, SMB4ACL_T *smbacl) * set the local file's acls obtaining it in NT form * using the NFSv4 format conversion */ -static BOOL zfs_set_nt_acl(vfs_handle_struct *handle, files_struct *fsp, +static NTSTATUS zfs_set_nt_acl(vfs_handle_struct *handle, files_struct *fsp, uint32 security_info_sent, struct security_descriptor *psd) { @@ -149,7 +149,7 @@ static size_t zfsacl_get_nt_acl(struct vfs_handle_struct *handle, return zfs_get_nt_acl(fsp, security_info, ppdesc); } -static BOOL zfsacl_fset_nt_acl(vfs_handle_struct *handle, +static NTSTATUS zfsacl_fset_nt_acl(vfs_handle_struct *handle, files_struct *fsp, int fd, uint32 security_info_sent, SEC_DESC *psd) @@ -157,7 +157,7 @@ static BOOL zfsacl_fset_nt_acl(vfs_handle_struct *handle, return zfs_set_nt_acl(handle, fsp, security_info_sent, psd); } -static BOOL zfsacl_set_nt_acl(vfs_handle_struct *handle, +static NTSTATUS zfsacl_set_nt_acl(vfs_handle_struct *handle, files_struct *fsp, const char *name, uint32 security_info_sent, SEC_DESC *psd) diff --git a/source3/rpc_server/srv_srvsvc_nt.c b/source3/rpc_server/srv_srvsvc_nt.c index 7132f92c93..0573599a81 100644 --- a/source3/rpc_server/srv_srvsvc_nt.c +++ b/source3/rpc_server/srv_srvsvc_nt.c @@ -2147,7 +2147,6 @@ error_exit: WERROR _srvsvc_NetSetFileSecurity(pipes_struct *p, struct srvsvc_NetSetFileSecurity *r) { - BOOL ret; DATA_BLOB null_pw; files_struct *fsp = NULL; SMB_STRUCT_STAT st; @@ -2215,9 +2214,9 @@ WERROR _srvsvc_NetSetFileSecurity(pipes_struct *p, struct srvsvc_NetSetFileSecur } } - ret = SMB_VFS_SET_NT_ACL(fsp, fsp->fsp_name, r->in.securityinformation, r->in.sd_buf.sd); + nt_status = SMB_VFS_SET_NT_ACL(fsp, fsp->fsp_name, r->in.securityinformation, r->in.sd_buf.sd); - if (ret == False) { + if (!NT_STATUS_IS_OK(nt_status)) { DEBUG(3,("_srv_net_file_set_secdesc: Unable to set NT ACL on file %s\n", r->in.file)); status = WERR_ACCESS_DENIED; goto error_exit; diff --git a/source3/smbd/nttrans.c b/source3/smbd/nttrans.c index 965da90a64..c13e35698b 100644 --- a/source3/smbd/nttrans.c +++ b/source3/smbd/nttrans.c @@ -1062,7 +1062,7 @@ static NTSTATUS set_sd(files_struct *fsp, char *data, uint32 sd_len, uint32 secu prs_struct pd; SEC_DESC *psd = NULL; TALLOC_CTX *mem_ctx; - BOOL ret; + NTSTATUS status; if (sd_len == 0 || !lp_nt_acl_support(SNUM(fsp->conn))) { return NT_STATUS_OK; @@ -1112,16 +1112,10 @@ static NTSTATUS set_sd(files_struct *fsp, char *data, uint32 sd_len, uint32 secu security_info_sent &= ~DACL_SECURITY_INFORMATION; } - ret = SMB_VFS_FSET_NT_ACL( fsp, fsp->fh->fd, security_info_sent, psd); - - if (!ret) { - talloc_destroy(mem_ctx); - return NT_STATUS_ACCESS_DENIED; - } + status = SMB_VFS_FSET_NT_ACL( fsp, fsp->fh->fd, security_info_sent, psd); talloc_destroy(mem_ctx); - - return NT_STATUS_OK; + return status; } /**************************************************************************** diff --git a/source3/smbd/posix_acls.c b/source3/smbd/posix_acls.c index 7eda998547..8db48ea664 100644 --- a/source3/smbd/posix_acls.c +++ b/source3/smbd/posix_acls.c @@ -923,7 +923,7 @@ static mode_t map_nt_perms( uint32 *mask, int type) Unpack a SEC_DESC into a UNIX owner and group. ****************************************************************************/ -BOOL unpack_nt_owners(int snum, uid_t *puser, gid_t *pgrp, uint32 security_info_sent, SEC_DESC *psd) +NTSTATUS unpack_nt_owners(int snum, uid_t *puser, gid_t *pgrp, uint32 security_info_sent, SEC_DESC *psd) { DOM_SID owner_sid; DOM_SID grp_sid; @@ -933,7 +933,7 @@ BOOL unpack_nt_owners(int snum, uid_t *puser, gid_t *pgrp, uint32 security_info_ if(security_info_sent == 0) { DEBUG(0,("unpack_nt_owners: no security info sent !\n")); - return True; + return NT_STATUS_OK; } /* @@ -961,9 +961,11 @@ BOOL unpack_nt_owners(int snum, uid_t *puser, gid_t *pgrp, uint32 security_info_ DEBUG(3,("unpack_nt_owners: unable to validate" " owner sid for %s\n", sid_string_static(&owner_sid))); - return False; + return NT_STATUS_INVALID_OWNER; } } + DEBUG(3,("unpack_nt_owners: owner sid mapped to uid %u\n", + (unsigned int)*puser )); } /* @@ -981,14 +983,16 @@ BOOL unpack_nt_owners(int snum, uid_t *puser, gid_t *pgrp, uint32 security_info_ } else { DEBUG(3,("unpack_nt_owners: unable to validate" " group sid.\n")); - return False; + return NT_STATUS_INVALID_OWNER; } } - } + DEBUG(3,("unpack_nt_owners: group sid mapped to gid %u\n", + (unsigned int)*pgrp)); + } DEBUG(5,("unpack_nt_owners: owner_sids validated.\n")); - return True; + return NT_STATUS_OK; } /**************************************************************************** @@ -3049,6 +3053,7 @@ int try_chown(connection_struct *conn, const char *fname, uid_t uid, gid_t gid) /* Case (4). */ if (!lp_dos_filemode(SNUM(conn))) { + errno = EPERM; return -1; } @@ -3082,7 +3087,7 @@ int try_chown(connection_struct *conn, const char *fname, uid_t uid, gid_t gid) This should be the only external function needed for the UNIX style set ACL. ****************************************************************************/ -BOOL set_nt_acl(files_struct *fsp, uint32 security_info_sent, SEC_DESC *psd) +NTSTATUS set_nt_acl(files_struct *fsp, uint32 security_info_sent, SEC_DESC *psd) { connection_struct *conn = fsp->conn; uid_t user = (uid_t)-1; @@ -3094,15 +3099,13 @@ BOOL set_nt_acl(files_struct *fsp, uint32 security_info_sent, SEC_DESC *psd) canon_ace *dir_ace_list = NULL; BOOL acl_perms = False; mode_t orig_mode = (mode_t)0; - uid_t orig_uid; - gid_t orig_gid; - BOOL need_chown = False; + NTSTATUS status; DEBUG(10,("set_nt_acl: called for file %s\n", fsp->fsp_name )); if (!CAN_WRITE(conn)) { DEBUG(10,("set acl rejected on read-only share\n")); - return False; + return NT_STATUS_MEDIA_WRITE_PROTECTED; } /* @@ -3111,40 +3114,29 @@ BOOL set_nt_acl(files_struct *fsp, uint32 security_info_sent, SEC_DESC *psd) if(fsp->is_directory || fsp->fh->fd == -1) { if(SMB_VFS_STAT(fsp->conn,fsp->fsp_name, &sbuf) != 0) - return False; + return map_nt_error_from_unix(errno); } else { if(SMB_VFS_FSTAT(fsp,fsp->fh->fd,&sbuf) != 0) - return False; + return map_nt_error_from_unix(errno); } /* Save the original elements we check against. */ orig_mode = sbuf.st_mode; - orig_uid = sbuf.st_uid; - orig_gid = sbuf.st_gid; /* * Unpack the user/group/world id's. */ - if (!unpack_nt_owners( SNUM(conn), &user, &grp, security_info_sent, psd)) { - return False; + status = unpack_nt_owners( SNUM(conn), &user, &grp, security_info_sent, psd); + if (!NT_STATUS_IS_OK(status)) { + return status; } /* * Do we need to chown ? */ - if (((user != (uid_t)-1) && (orig_uid != user)) || (( grp != (gid_t)-1) && (orig_gid != grp))) { - need_chown = True; - } - - /* - * Chown before setting ACL only if we don't change the user, or - * if we change to the current user, but not if we want to give away - * the file. - */ - - if (need_chown && (user == (uid_t)-1 || user == current_user.ut.uid)) { + if (((user != (uid_t)-1) && (sbuf.st_uid != user)) || (( grp != (gid_t)-1) && (sbuf.st_gid != grp))) { DEBUG(3,("set_nt_acl: chown %s. uid = %u, gid = %u.\n", fsp->fsp_name, (unsigned int)user, (unsigned int)grp )); @@ -3152,7 +3144,10 @@ BOOL set_nt_acl(files_struct *fsp, uint32 security_info_sent, SEC_DESC *psd) if(try_chown( fsp->conn, fsp->fsp_name, user, grp) == -1) { DEBUG(3,("set_nt_acl: chown %s, %u, %u failed. Error = %s.\n", fsp->fsp_name, (unsigned int)user, (unsigned int)grp, strerror(errno) )); - return False; + if (errno == EPERM) { + return NT_STATUS_INVALID_OWNER; + } + return map_nt_error_from_unix(errno); } /* @@ -3162,7 +3157,7 @@ BOOL set_nt_acl(files_struct *fsp, uint32 security_info_sent, SEC_DESC *psd) if(fsp->is_directory) { if(SMB_VFS_STAT(fsp->conn, fsp->fsp_name, &sbuf) != 0) { - return False; + return map_nt_error_from_unix(errno); } } else { @@ -3174,16 +3169,11 @@ BOOL set_nt_acl(files_struct *fsp, uint32 security_info_sent, SEC_DESC *psd) ret = SMB_VFS_FSTAT(fsp,fsp->fh->fd,&sbuf); if(ret != 0) - return False; + return map_nt_error_from_unix(errno); } /* Save the original elements we check against. */ orig_mode = sbuf.st_mode; - orig_uid = sbuf.st_uid; - orig_gid = sbuf.st_gid; - - /* We did it, don't try again */ - need_chown = False; } create_file_sids(&sbuf, &file_owner_sid, &file_grp_sid); @@ -3198,7 +3188,7 @@ BOOL set_nt_acl(files_struct *fsp, uint32 security_info_sent, SEC_DESC *psd) DEBUG(3,("set_nt_acl: cannot set permissions\n")); free_canon_ace_list(file_ace_list); free_canon_ace_list(dir_ace_list); - return False; + return NT_STATUS_ACCESS_DENIED; } /* @@ -3221,7 +3211,7 @@ BOOL set_nt_acl(files_struct *fsp, uint32 security_info_sent, SEC_DESC *psd) DEBUG(3,("set_nt_acl: failed to set file acl on file %s (%s).\n", fsp->fsp_name, strerror(errno) )); free_canon_ace_list(file_ace_list); free_canon_ace_list(dir_ace_list); - return False; + return map_nt_error_from_unix(errno); } } @@ -3231,7 +3221,7 @@ BOOL set_nt_acl(files_struct *fsp, uint32 security_info_sent, SEC_DESC *psd) DEBUG(3,("set_nt_acl: failed to set default acl on directory %s (%s).\n", fsp->fsp_name, strerror(errno) )); free_canon_ace_list(file_ace_list); free_canon_ace_list(dir_ace_list); - return False; + return map_nt_error_from_unix(errno); } } else { @@ -3256,7 +3246,7 @@ BOOL set_nt_acl(files_struct *fsp, uint32 security_info_sent, SEC_DESC *psd) DEBUG(3,("set_nt_acl: sys_acl_delete_def_file failed (%s)\n", strerror(errno))); free_canon_ace_list(file_ace_list); free_canon_ace_list(dir_ace_list); - return False; + return map_nt_error_from_unix(errno); } } } @@ -3279,7 +3269,7 @@ BOOL set_nt_acl(files_struct *fsp, uint32 security_info_sent, SEC_DESC *psd) free_canon_ace_list(dir_ace_list); DEBUG(3,("set_nt_acl: failed to convert file acl to posix permissions for file %s.\n", fsp->fsp_name )); - return False; + return NT_STATUS_ACCESS_DENIED; } if (orig_mode != posix_perms) { @@ -3304,7 +3294,7 @@ BOOL set_nt_acl(files_struct *fsp, uint32 security_info_sent, SEC_DESC *psd) fsp->fsp_name, (unsigned int)posix_perms, strerror(errno) )); free_canon_ace_list(file_ace_list); free_canon_ace_list(dir_ace_list); - return False; + return map_nt_error_from_unix(errno); } } } @@ -3315,20 +3305,7 @@ BOOL set_nt_acl(files_struct *fsp, uint32 security_info_sent, SEC_DESC *psd) free_canon_ace_list(dir_ace_list); } - /* Any chown pending? */ - if (need_chown) { - - DEBUG(3,("set_nt_acl: chown %s. uid = %u, gid = %u.\n", - fsp->fsp_name, (unsigned int)user, (unsigned int)grp )); - - if(try_chown( fsp->conn, fsp->fsp_name, user, grp) == -1) { - DEBUG(3,("set_nt_acl: chown %s, %u, %u failed. Error = %s.\n", - fsp->fsp_name, (unsigned int)user, (unsigned int)grp, strerror(errno) )); - return False; - } - } - - return True; + return NT_STATUS_OK; } /**************************************************************************** -- cgit