summaryrefslogtreecommitdiff
path: root/source3/smbd/posix_acls.c
diff options
context:
space:
mode:
authorJeremy Allison <jra@samba.org>2001-03-23 00:54:55 +0000
committerJeremy Allison <jra@samba.org>2001-03-23 00:54:55 +0000
commit81afba28c3fecb5471e1ff03a0b3dda5126f5aa6 (patch)
tree56d0a83fe7d4baae1373e32d45b53e340bc50a68 /source3/smbd/posix_acls.c
parent0053bd8b80cc08d65948c97f8ab0b4e2b829f083 (diff)
downloadsamba-81afba28c3fecb5471e1ff03a0b3dda5126f5aa6.tar.gz
samba-81afba28c3fecb5471e1ff03a0b3dda5126f5aa6.tar.bz2
samba-81afba28c3fecb5471e1ff03a0b3dda5126f5aa6.zip
Sync up with 2.2 ACL code.
Jeremy. (This used to be commit 5b9a88c2d0da3479f91131f66ff741e88f9760ee)
Diffstat (limited to 'source3/smbd/posix_acls.c')
-rw-r--r--source3/smbd/posix_acls.c132
1 files changed, 84 insertions, 48 deletions
diff --git a/source3/smbd/posix_acls.c b/source3/smbd/posix_acls.c
index 22d1038fcc..ddf4d06b0e 100644
--- a/source3/smbd/posix_acls.c
+++ b/source3/smbd/posix_acls.c
@@ -108,21 +108,21 @@ static void create_file_sids(SMB_STRUCT_STAT *psbuf, DOM_SID *powner_sid, DOM_SI
Print out a canon ace.
****************************************************************************/
-static void print_canon_ace(canon_ace *ace, int num)
+static void print_canon_ace(canon_ace *pace, int num)
{
fstring str;
- dbgtext( "canon_ace index %d. Type = %s ", num, ace->attr == ALLOW_ACE ? "allow" : "deny" );
- dbgtext( "SID = %s ", sid_to_string( str, &ace->sid));
- if (ace->owner_type == UID_ACE) {
- struct passwd *pass = sys_getpwuid(ace->unix_ug.uid);
- dbgtext( "uid %u (%s) ", (unsigned int)ace->unix_ug.uid, pass ? pass->pw_name : "UNKNOWN");
- } else if (ace->owner_type == GID_ACE) {
- struct group *grp = getgrgid(ace->unix_ug.gid);
- dbgtext( "gid %u (%s) ", (unsigned int)ace->unix_ug.gid, grp ? grp->gr_name : "UNKNOWN");
+ dbgtext( "canon_ace index %d. Type = %s ", num, pace->attr == ALLOW_ACE ? "allow" : "deny" );
+ dbgtext( "SID = %s ", sid_to_string( str, &pace->sid));
+ if (pace->owner_type == UID_ACE) {
+ struct passwd *pass = sys_getpwuid(pace->unix_ug.uid);
+ dbgtext( "uid %u (%s) ", (unsigned int)pace->unix_ug.uid, pass ? pass->pw_name : "UNKNOWN");
+ } else if (pace->owner_type == GID_ACE) {
+ struct group *grp = getgrgid(pace->unix_ug.gid);
+ dbgtext( "gid %u (%s) ", (unsigned int)pace->unix_ug.gid, grp ? grp->gr_name : "UNKNOWN");
} else
dbgtext( "other ");
- switch (ace->type) {
+ switch (pace->type) {
case SMB_ACL_USER:
dbgtext( "SMB_ACL_USER ");
break;
@@ -140,9 +140,24 @@ static void print_canon_ace(canon_ace *ace, int num)
break;
}
dbgtext( "perms ");
- dbgtext( "%c", ace->perms & S_IRUSR ? 'r' : '-');
- dbgtext( "%c", ace->perms & S_IWUSR ? 'w' : '-');
- dbgtext( "%c\n", ace->perms & S_IXUSR ? 'x' : '-');
+ dbgtext( "%c", pace->perms & S_IRUSR ? 'r' : '-');
+ dbgtext( "%c", pace->perms & S_IWUSR ? 'w' : '-');
+ dbgtext( "%c\n", pace->perms & S_IXUSR ? 'x' : '-');
+}
+
+/****************************************************************************
+ Print out a canon ace list.
+****************************************************************************/
+
+static void print_canon_ace_list(const char *name, canon_ace *ace_list)
+{
+ int count = 0;
+
+ if( DEBUGLVL( 10 )) {
+ dbgtext( "print_canon_ace_list: %s\n", name );
+ for (;ace_list; ace_list = ace_list->next, count++)
+ print_canon_ace(ace_list, count );
+ }
}
/****************************************************************************
@@ -212,7 +227,8 @@ static void merge_aces( canon_ace **pp_list_head )
* we've put on the ACL, we know the deny must be the first one.
*/
- if ((curr_ace_outer->attr == DENY_ACE) && (curr_ace->attr == ALLOW_ACE)) {
+ if (sid_equal(&curr_ace->sid, &curr_ace_outer->sid) &&
+ (curr_ace_outer->attr == DENY_ACE) && (curr_ace->attr == ALLOW_ACE)) {
if( DEBUGLVL( 10 )) {
dbgtext("merge_aces: Masking ACE's\n");
@@ -280,8 +296,13 @@ static SEC_ACCESS map_canon_ace_perms(int *pacl_type, DOM_SID *powner_sid, canon
nt_mask = UNIX_ACCESS_NONE;
} else {
/* Not owner, no access. */
- *pacl_type = SEC_ACE_TYPE_ACCESS_DENIED;
- nt_mask = GENERIC_ALL_ACCESS;
+ if (ace->type == SMB_ACL_USER) {
+ /* user objects can be deny entries. */
+ *pacl_type = SEC_ACE_TYPE_ACCESS_DENIED;
+ nt_mask = GENERIC_ALL_ACCESS;
+ }
+ else
+ nt_mask = UNIX_ACCESS_NONE;
}
} else {
nt_mask |= ((ace->perms & S_IRUSR) ? UNIX_ACCESS_R : 0 );
@@ -467,7 +488,8 @@ static BOOL ensure_canon_entry_valid(canon_ace **pp_ace,
pace->owner_type = UID_ACE;
pace->unix_ug.uid = pst->st_uid;
pace->sid = *pfile_owner_sid;
- pace->perms = default_acl ? get_default_ace_mode(fsp, S_IRUSR): 0;
+ /* Ensure owner has read access. */
+ pace->perms = default_acl ? get_default_ace_mode(fsp, S_IRUSR): S_IRUSR;
pace->attr = ALLOW_ACE;
DLIST_ADD(*pp_ace, pace);
@@ -766,7 +788,7 @@ static BOOL uid_entry_in_group( canon_ace *uid_ace, canon_ace *group_ace )
if (!(pass = sys_getpwuid(uid_ace->unix_ug.uid)))
return False;
- if (!(gptr = getgrgid(uid_ace->unix_ug.gid)))
+ if (!(gptr = getgrgid(group_ace->unix_ug.gid)))
return False;
/*
@@ -1059,8 +1081,6 @@ static BOOL unpack_canon_ace(files_struct *fsp,
{
canon_ace *file_ace = NULL;
canon_ace *dir_ace = NULL;
- canon_ace *current_ace = NULL;
- int i;
*ppfile_ace = NULL;
*ppdir_ace = NULL;
@@ -1085,6 +1105,11 @@ static BOOL unpack_canon_ace(files_struct *fsp,
&file_ace, &dir_ace, psd->dacl))
return False;
+ if ((file_ace == NULL) && (dir_ace == NULL)) {
+ /* W2K traverse DACL set - ignore. */
+ return True;
+ }
+
/*
* Go through the canon_ace list and merge entries
* belonging to identical users of identical allow or deny type.
@@ -1092,7 +1117,10 @@ static BOOL unpack_canon_ace(files_struct *fsp,
* all allow entries (we have mandated this before accepting this acl).
*/
+ print_canon_ace_list( "file ace - before merge", file_ace);
merge_aces( &file_ace );
+
+ print_canon_ace_list( "dir ace - before merge", dir_ace);
merge_aces( &dir_ace );
/*
@@ -1100,7 +1128,10 @@ static BOOL unpack_canon_ace(files_struct *fsp,
* process DENY entries by masking the allow entries.
*/
+ print_canon_ace_list( "file ace - before deny", file_ace);
process_deny_list( &file_ace);
+
+ print_canon_ace_list( "dir ace - before deny", dir_ace);
process_deny_list( &dir_ace);
/*
@@ -1109,29 +1140,24 @@ static BOOL unpack_canon_ace(files_struct *fsp,
* and optionally a mask entry. Ensure this is the case.
*/
+ print_canon_ace_list( "file ace - before valid", file_ace);
+
if (!ensure_canon_entry_valid(&file_ace, fsp, pfile_owner_sid, pfile_grp_sid, pst, False)) {
free_canon_ace_list(file_ace);
free_canon_ace_list(dir_ace);
return False;
}
- if (!ensure_canon_entry_valid(&dir_ace, fsp, pfile_owner_sid, pfile_grp_sid, pst, True)) {
+ print_canon_ace_list( "dir ace - before valid", dir_ace);
+
+ if (dir_ace && !ensure_canon_entry_valid(&dir_ace, fsp, pfile_owner_sid, pfile_grp_sid, pst, True)) {
free_canon_ace_list(file_ace);
free_canon_ace_list(dir_ace);
return False;
}
- if( DEBUGLVL( 10 )) {
- dbgtext("unpack_canon_ace: File ACL:\n");
- for (i = 0, current_ace = file_ace; current_ace; current_ace = current_ace->next, i++ ) {
- print_canon_ace( current_ace, i);
- }
-
- dbgtext("unpack_canon_ace: Directory ACL:\n");
- for (i = 0, current_ace = dir_ace; current_ace; current_ace = current_ace->next, i++ ) {
- print_canon_ace( current_ace, i);
- }
- }
+ print_canon_ace_list( "file ace - return", file_ace);
+ print_canon_ace_list( "dir ace - return", dir_ace);
*ppfile_ace = file_ace;
*ppdir_ace = dir_ace;
@@ -1486,7 +1512,7 @@ static canon_ace *canonicalise_acl( files_struct *fsp, SMB_ACL_T posix_acl, SMB_
ZERO_STRUCTP(ace);
ace->type = tagtype;
ace->perms = convert_permset_to_mode_t(permset);
- ace->attr = ace->perms ? ALLOW_ACE : DENY_ACE;
+ ace->attr = ALLOW_ACE;
ace->sid = sid;
ace->unix_ug = unix_ug;
ace->owner_type = owner_type;
@@ -1505,6 +1531,8 @@ static canon_ace *canonicalise_acl( files_struct *fsp, SMB_ACL_T posix_acl, SMB_
DLIST_ADD(list_head, ace);
}
+ arrange_posix_perms(fsp->fsp_name,&list_head );
+
/*
* Now go through the list, masking the permissions with the
* acl_mask. Ensure all DENY Entries are at the start of the list.
@@ -1528,21 +1556,7 @@ static canon_ace *canonicalise_acl( files_struct *fsp, SMB_ACL_T posix_acl, SMB_
}
}
- arrange_posix_perms(fsp->fsp_name,&list_head );
-
- if( DEBUGLVL( 10 ) ) {
- char *acl_text = sys_acl_to_text( posix_acl, NULL);
-
- dbgtext("canonicalize_acl: processed acl %s\n", acl_text == NULL ? "NULL" : acl_text );
- if (acl_text)
- sys_acl_free_text(acl_text);
-
- dbgtext("canonicalize_acl: ace entries after arrange :\n");
-
- for ( ace_count = 0, ace = list_head; ace; ace = next_ace, ace_count++) {
- print_canon_ace(ace, ace_count);
- }
- }
+ print_canon_ace_list( "canonicalize_acl: ace entries after arrange", list_head );
return list_head;
@@ -1784,6 +1798,16 @@ posix perms.\n", fsp->fsp_name ));
return True;
}
+static int nt_ace_comp( SEC_ACE *a1, SEC_ACE *a2)
+{
+ if (a1->type == a2->type)
+ return 0;
+
+ if (a1->type == SEC_ACE_TYPE_ACCESS_DENIED && a2->type == SEC_ACE_TYPE_ACCESS_ALLOWED)
+ return -1;
+ return 1;
+}
+
/****************************************************************************
Reply to query a security descriptor from an fsp. If it succeeds it allocates
the space for the return elements and returns the size needed to return the
@@ -1899,6 +1923,13 @@ size_t get_nt_acl(files_struct *fsp, SEC_DESC **ppdesc)
init_sec_ace(&nt_ace_list[num_aces++], &ace->sid, nt_acl_type, acc,
SEC_ACE_FLAG_OBJECT_INHERIT|SEC_ACE_FLAG_CONTAINER_INHERIT|SEC_ACE_FLAG_INHERIT_ONLY);
}
+
+ /*
+ * Sort to force deny entries to the front.
+ */
+
+ if (num_acls + num_dir_acls)
+ qsort( nt_ace_list, num_acls + num_dir_acls, sizeof(nt_ace_list[0]), QSORT_CAST nt_ace_comp);
}
if (num_acls) {
@@ -2011,6 +2042,11 @@ BOOL set_nt_acl(files_struct *fsp, uint32 security_info_sent, SEC_DESC *psd)
acl_perms = unpack_canon_ace( fsp, &sbuf, &file_owner_sid, &file_grp_sid,
&file_ace_list, &dir_ace_list, security_info_sent, psd);
+ if ((file_ace_list == NULL) && (dir_ace_list == NULL)) {
+ /* W2K traverse DACL set - ignore. */
+ return True;
+ }
+
if (!acl_perms) {
DEBUG(3,("set_nt_acl: cannot set permissions\n"));
free_canon_ace_list(file_ace_list);