summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--source3/smbd/open.c7
-rw-r--r--source3/smbd/posix_acls.c58
2 files changed, 54 insertions, 11 deletions
diff --git a/source3/smbd/open.c b/source3/smbd/open.c
index 77962562e3..3665e7d20f 100644
--- a/source3/smbd/open.c
+++ b/source3/smbd/open.c
@@ -192,6 +192,13 @@ static BOOL open_file(files_struct *fsp,connection_struct *conn,
BOOLSTR(fsp->can_read), BOOLSTR(fsp->can_write),
conn->num_files_open + 1));
+ /*
+ * Take care of inherited ACLs on created files. JRA.
+ */
+
+ if ((flags & O_CREAT) && (conn->vfs_ops.fchmod_acl != NULL))
+ conn->vfs_ops.fchmod_acl(fsp, fsp->fd, mode);
+
return True;
}
diff --git a/source3/smbd/posix_acls.c b/source3/smbd/posix_acls.c
index 2bd0065d58..ed8c0a94c9 100644
--- a/source3/smbd/posix_acls.c
+++ b/source3/smbd/posix_acls.c
@@ -1247,7 +1247,7 @@ static BOOL set_canon_ace_list(files_struct *fsp, canon_ace *the_ace, BOOL defau
*/
if(default_ace || fsp->is_directory || fsp->fd == -1) {
- if (sys_acl_set_file(fsp->fsp_name, the_acl_type, the_acl) == -1) {
+ if (sys_acl_set_file(dos_to_unix(fsp->fsp_name,False), the_acl_type, the_acl) == -1) {
DEBUG(0,("set_canon_ace_list: sys_acl_set_file type %s failed for file %s (%s).\n",
the_acl_type == SMB_ACL_TYPE_DEFAULT ? "directory default" : "file",
fsp->fsp_name, strerror(errno) ));
@@ -1587,12 +1587,14 @@ static int chmod_acl_internals( SMB_ACL_T posix_acl, mode_t mode)
SMB_ACL_ENTRY_T entry;
int num_entries = 0;
-#if 1
- return -1;
-#else
while ( sys_acl_get_entry(posix_acl, entry_id, &entry) == 1) {
SMB_ACL_TAG_T tagtype;
SMB_ACL_PERMSET_T permset;
+ mode_t perms;
+
+ /* get_next... */
+ if (entry_id == SMB_ACL_FIRST_ENTRY)
+ entry_id = SMB_ACL_NEXT_ENTRY;
if (sys_acl_get_tag_type(entry, &tagtype) == -1)
return -1;
@@ -1604,21 +1606,37 @@ static int chmod_acl_internals( SMB_ACL_T posix_acl, mode_t mode)
switch(tagtype) {
case SMB_ACL_USER_OBJ:
+ perms = unix_perms_to_acl_perms(mode, S_IRUSR, S_IWUSR, S_IXUSR);
break;
- case SMB_ACL_USER:
- break;
case SMB_ACL_GROUP_OBJ:
- break;
- case SMB_ACL_GROUP:
+ perms = unix_perms_to_acl_perms(mode, S_IRGRP, S_IWGRP, S_IXGRP);
break;
case SMB_ACL_MASK:
+ perms = S_IRUSR|S_IWUSR|S_IXUSR;
break;
case SMB_ACL_OTHER:
+ perms = unix_perms_to_acl_perms(mode, S_IROTH, S_IWOTH, S_IXOTH);
break;
+ default:
+ continue;
}
+ if (map_acl_perms_to_permset(perms, &permset) == -1)
+ return -1;
+
+ if (sys_acl_set_permset(entry, permset) == -1)
+ return -1;
}
-#endif
+
+ /*
+ * If this is a simple 3 element ACL then it's a standard
+ * UNIX permission set. Just use chmod...
+ */
+
+ if (num_entries == 3)
+ return -1;
+
+ return 0;
}
/****************************************************************************
@@ -1630,11 +1648,20 @@ static int chmod_acl_internals( SMB_ACL_T posix_acl, mode_t mode)
int chmod_acl(char *name, mode_t mode)
{
SMB_ACL_T posix_acl = NULL;
+ int ret = -1;
if ((posix_acl = sys_acl_get_file(name, SMB_ACL_TYPE_ACCESS)) == NULL)
return -1;
- return chmod_acl_internals(posix_acl, mode);
+ if ((ret = chmod_acl_internals(posix_acl, mode)) == -1)
+ goto done;
+
+ ret = sys_acl_set_file(name, SMB_ACL_TYPE_ACCESS, posix_acl);
+
+ done:
+
+ sys_acl_free_acl(posix_acl);
+ return ret;
}
/****************************************************************************
@@ -1645,11 +1672,20 @@ int chmod_acl(char *name, mode_t mode)
int fchmod_acl(int fd, mode_t mode)
{
SMB_ACL_T posix_acl = NULL;
+ int ret = -1;
if ((posix_acl = sys_acl_get_fd(fd)) == NULL)
return -1;
- return chmod_acl_internals(posix_acl, mode);
+ if ((ret = chmod_acl_internals(posix_acl, mode)) == -1)
+ goto done;
+
+ ret = sys_acl_set_fd(fd, posix_acl);
+
+ done:
+
+ sys_acl_free_acl(posix_acl);
+ return ret;
}
#undef OLD_NTDOMAIN