summaryrefslogtreecommitdiff
path: root/source3/modules/nfs4_acls.c
diff options
context:
space:
mode:
Diffstat (limited to 'source3/modules/nfs4_acls.c')
-rw-r--r--source3/modules/nfs4_acls.c84
1 files changed, 37 insertions, 47 deletions
diff --git a/source3/modules/nfs4_acls.c b/source3/modules/nfs4_acls.c
index f411176590..556dad6b5e 100644
--- a/source3/modules/nfs4_acls.c
+++ b/source3/modules/nfs4_acls.c
@@ -698,9 +698,10 @@ NTSTATUS smb_set_nt_acl_nfs4(files_struct *fsp,
bool result;
SMB_STRUCT_STAT sbuf;
- bool need_chown = False;
+ bool set_acl_as_root = false;
uid_t newUID = (uid_t)-1;
gid_t newGID = (gid_t)-1;
+ int saved_errno;
DEBUG(10, ("smb_set_nt_acl_nfs4 invoked for %s\n", fsp->fsp_name));
@@ -728,59 +729,48 @@ NTSTATUS smb_set_nt_acl_nfs4(files_struct *fsp,
}
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 == fsp->conn->server_info->utok.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 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->conn, fsp->fsp_name, &sbuf))
- return map_nt_error_from_unix(errno);
- 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 */
+ 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 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->conn, fsp->fsp_name, &sbuf))
+ return map_nt_error_from_unix(errno);
+
+ /* If we successfully chowned, we know we must
+ * be able to set the acl, so do it as root.
+ */
+ set_acl_as_root = true;
}
}
- if ((security_info_sent & DACL_SECURITY_INFORMATION)!=0 && psd->dacl!=NULL)
- {
- acl = smbacl4_win2nfs4(fsp->fsp_name, psd->dacl, &params, sbuf.st_uid, sbuf.st_gid);
- if (!acl)
- return map_nt_error_from_unix(errno);
+ if (!(security_info_sent & DACL_SECURITY_INFORMATION) || psd->dacl ==NULL) {
+ DEBUG(10, ("no dacl found; security_info_sent = 0x%x\n", security_info_sent));
+ return NT_STATUS_OK;
+ }
- smbacl4_dump_nfs4acl(10, acl);
+ acl = smbacl4_win2nfs4(fsp->fsp_name, psd->dacl, &params, sbuf.st_uid, sbuf.st_gid);
+ if (!acl)
+ return map_nt_error_from_unix(errno);
- result = set_nfs4_native(fsp, acl);
- if (result!=True)
- {
- DEBUG(10, ("set_nfs4_native failed with %s\n", strerror(errno)));
- return map_nt_error_from_unix(errno);
- }
- } else
- DEBUG(10, ("no dacl found; security_info_sent = 0x%x\n", security_info_sent));
+ smbacl4_dump_nfs4acl(10, acl);
- /* 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 map_nt_error_from_unix(errno);
- }
- DEBUG(10,("chown#2 %s, %u, %u succeeded.\n",
- fsp->fsp_name, (unsigned int)newUID, (unsigned int)newGID));
+ if (set_acl_as_root) {
+ become_root();
+ }
+ result = set_nfs4_native(fsp, acl);
+ saved_errno = errno;
+ if (set_acl_as_root) {
+ unbecome_root();
+ }
+ if (result!=True) {
+ errno = saved_errno;
+ DEBUG(10, ("set_nfs4_native failed with %s\n", strerror(errno)));
+ return map_nt_error_from_unix(errno);
}
DEBUG(10, ("smb_set_nt_acl_nfs4 succeeded\n"));