Fix bug 7716 - acl_xattr and acl_tdb modules don't store unmodified copies of securit...
[mat/samba.git] / source3 / smbd / posix_acls.c
index 36d18b013c01cb4f72d7adacd444265674390962..4ceb0f0452b3a3b54c8353d15f5da9f3305029be 100644 (file)
@@ -20,6 +20,7 @@
 */
 
 #include "includes.h"
+#include "../libcli/security/dom_sid.h"
 
 extern const struct generic_mapping file_generic_mapping;
 
@@ -944,10 +945,10 @@ static void merge_aces( canon_ace **pp_list_head, bool dir_acl)
                         * ensure the POSIX ACL types are the same. */
 
                        if (!dir_acl) {
-                               can_merge = (sid_equal(&curr_ace->trustee, &curr_ace_outer->trustee) &&
+                               can_merge = (dom_sid_equal(&curr_ace->trustee, &curr_ace_outer->trustee) &&
                                                (curr_ace->attr == curr_ace_outer->attr));
                        } else {
-                               can_merge = (sid_equal(&curr_ace->trustee, &curr_ace_outer->trustee) &&
+                               can_merge = (dom_sid_equal(&curr_ace->trustee, &curr_ace_outer->trustee) &&
                                                (curr_ace->type == curr_ace_outer->type) &&
                                                (curr_ace->attr == curr_ace_outer->attr));
                        }
@@ -996,7 +997,7 @@ static void merge_aces( canon_ace **pp_list_head, bool dir_acl)
                         * we've put on the ACL, we know the deny must be the first one.
                         */
 
-                       if (sid_equal(&curr_ace->trustee, &curr_ace_outer->trustee) &&
+                       if (dom_sid_equal(&curr_ace->trustee, &curr_ace_outer->trustee) &&
                                (curr_ace_outer->attr == DENY_ACE) && (curr_ace->attr == ALLOW_ACE)) {
 
                                if( DEBUGLVL( 10 )) {
@@ -1197,7 +1198,7 @@ NTSTATUS unpack_nt_owners(struct connection_struct *conn,
         * This may be a group chown only set.
         */
 
-       if (security_info_sent & OWNER_SECURITY_INFORMATION) {
+       if (security_info_sent & SECINFO_OWNER) {
                sid_copy(&owner_sid, psd->owner_sid);
                if (!sid_to_uid(&owner_sid, puser)) {
                        if (lp_force_unknown_acl_user(SNUM(conn))) {
@@ -1220,7 +1221,7 @@ NTSTATUS unpack_nt_owners(struct connection_struct *conn,
         * This may be an owner chown only set.
         */
 
-       if (security_info_sent & GROUP_SECURITY_INFORMATION) {
+       if (security_info_sent & SECINFO_GROUP) {
                sid_copy(&grp_sid, psd->group_sid);
                if (!sid_to_gid( &grp_sid, pgrp)) {
                        if (lp_force_unknown_acl_user(SNUM(conn))) {
@@ -1297,7 +1298,7 @@ static bool uid_entry_in_group(connection_struct *conn, canon_ace *uid_ace, cano
 
        /* "Everyone" always matches every uid. */
 
-       if (sid_equal(&group_ace->trustee, &global_sid_World))
+       if (dom_sid_equal(&group_ace->trustee, &global_sid_World))
                return True;
 
        /*
@@ -1513,12 +1514,12 @@ static void check_owning_objs(canon_ace *ace, struct dom_sid *pfile_owner_sid, s
 
        for (i=0, current_ace = ace; i < entries; i++, current_ace = current_ace->next) {
                if (!got_user_obj && current_ace->owner_type == UID_ACE &&
-                               sid_equal(&current_ace->trustee, pfile_owner_sid)) {
+                               dom_sid_equal(&current_ace->trustee, pfile_owner_sid)) {
                        current_ace->type = SMB_ACL_USER_OBJ;
                        got_user_obj = True;
                }
                if (!got_group_obj && current_ace->owner_type == GID_ACE &&
-                               sid_equal(&current_ace->trustee, pfile_grp_sid)) {
+                               dom_sid_equal(&current_ace->trustee, pfile_grp_sid)) {
                        current_ace->type = SMB_ACL_GROUP_OBJ;
                        got_group_obj = True;
                }
@@ -1549,7 +1550,7 @@ static bool dup_owning_ace(canon_ace *dir_ace, canon_ace *ace)
        */
 
        if (ace->type == SMB_ACL_USER_OBJ &&
-                       !(sid_equal(&ace->trustee, &global_sid_Creator_Owner))) {
+                       !(dom_sid_equal(&ace->trustee, &global_sid_Creator_Owner))) {
                canon_ace *dup_ace = dup_canon_ace(ace);
 
                if (dup_ace == NULL) {
@@ -1560,7 +1561,7 @@ static bool dup_owning_ace(canon_ace *dir_ace, canon_ace *ace)
        }
 
        if (ace->type == SMB_ACL_GROUP_OBJ &&
-                       !(sid_equal(&ace->trustee, &global_sid_Creator_Group))) {
+                       !(dom_sid_equal(&ace->trustee, &global_sid_Creator_Group))) {
                canon_ace *dup_ace = dup_canon_ace(ace);
 
                if (dup_ace == NULL) {
@@ -1646,7 +1647,7 @@ static bool create_canon_ace_lists(files_struct *fsp,
                        if (psa1->access_mask != psa2->access_mask)
                                continue;
 
-                       if (!sid_equal(&psa1->trustee, &psa2->trustee))
+                       if (!dom_sid_equal(&psa1->trustee, &psa2->trustee))
                                continue;
 
                        /*
@@ -1672,7 +1673,7 @@ static bool create_canon_ace_lists(files_struct *fsp,
                struct security_ace *psa = &dacl->aces[i];
 
                /*
-                * Create a cannon_ace entry representing this NT DACL ACE.
+                * Create a canon_ace entry representing this NT DACL ACE.
                 */
 
                if ((current_ace = SMB_MALLOC_P(canon_ace)) == NULL) {
@@ -1692,11 +1693,11 @@ static bool create_canon_ace_lists(files_struct *fsp,
                 * Note what kind of a POSIX ACL this should map to.
                 */
 
-               if( sid_equal(&current_ace->trustee, &global_sid_World)) {
+               if( dom_sid_equal(&current_ace->trustee, &global_sid_World)) {
                        current_ace->owner_type = WORLD_ACE;
                        current_ace->unix_ug.world = -1;
                        current_ace->type = SMB_ACL_OTHER;
-               } else if (sid_equal(&current_ace->trustee, &global_sid_Creator_Owner)) {
+               } else if (dom_sid_equal(&current_ace->trustee, &global_sid_Creator_Owner)) {
                        current_ace->owner_type = UID_ACE;
                        current_ace->unix_ug.uid = pst->st_ex_uid;
                        current_ace->type = SMB_ACL_USER_OBJ;
@@ -1709,7 +1710,7 @@ static bool create_canon_ace_lists(files_struct *fsp,
 
                        psa->flags |= SEC_ACE_FLAG_INHERIT_ONLY;
 
-               } else if (sid_equal(&current_ace->trustee, &global_sid_Creator_Group)) {
+               } else if (dom_sid_equal(&current_ace->trustee, &global_sid_Creator_Group)) {
                        current_ace->owner_type = GID_ACE;
                        current_ace->unix_ug.gid = pst->st_ex_gid;
                        current_ace->type = SMB_ACL_GROUP_OBJ;
@@ -2085,7 +2086,7 @@ static void process_deny_list(connection_struct *conn, canon_ace **pp_ace_list )
                        continue;
                }
 
-               if (!sid_equal(&curr_ace->trustee, &global_sid_World))
+               if (!dom_sid_equal(&curr_ace->trustee, &global_sid_World))
                        continue;
 
                /* JRATEST - assert. */
@@ -2337,7 +2338,7 @@ static bool unpack_canon_ace(files_struct *fsp,
         * If no DACL then this is a chown only security descriptor.
         */
 
-       if(!(security_info_sent & DACL_SECURITY_INFORMATION) || !psd->dacl)
+       if(!(security_info_sent & SECINFO_DACL) || !psd->dacl)
                return True;
 
        /*
@@ -3080,7 +3081,7 @@ static size_t merge_default_aces( struct security_ace *nt_ace_list, size_t num_a
                        if ((nt_ace_list[i].type == nt_ace_list[j].type) &&
                                (nt_ace_list[i].size == nt_ace_list[j].size) &&
                                (nt_ace_list[i].access_mask == nt_ace_list[j].access_mask) &&
-                               sid_equal(&nt_ace_list[i].trustee, &nt_ace_list[j].trustee) &&
+                               dom_sid_equal(&nt_ace_list[i].trustee, &nt_ace_list[j].trustee) &&
                                (i_inh == j_inh) &&
                                (i_flags_ni == 0) &&
                                (j_flags_ni == (SEC_ACE_FLAG_OBJECT_INHERIT|
@@ -3144,7 +3145,7 @@ static void add_or_replace_ace(struct security_ace *nt_ace_list, size_t *num_ace
 
        /* first search for a duplicate */
        for (i = 0; i < *num_aces; i++) {
-               if (sid_equal(&nt_ace_list[i].trustee, sid) &&
+               if (dom_sid_equal(&nt_ace_list[i].trustee, sid) &&
                    (nt_ace_list[i].flags == flags)) break;
        }
 
@@ -3206,7 +3207,7 @@ static NTSTATUS posix_get_nt_acl_common(struct connection_struct *conn,
                num_profile_acls = 3;
        }
 
-       if ((security_info & DACL_SECURITY_INFORMATION) && !(security_info & PROTECTED_DACL_SECURITY_INFORMATION)) {
+       if ((security_info & SECINFO_DACL) && !(security_info & SECINFO_PROTECTED_DACL)) {
 
                /*
                 * In the optimum case Creator Owner and Creator Group would be used for
@@ -3367,7 +3368,7 @@ static NTSTATUS posix_get_nt_acl_common(struct connection_struct *conn,
 
                        if (lp_profile_acls(SNUM(conn))) {
                                for (i = 0; i < num_aces; i++) {
-                                       if (sid_equal(&nt_ace_list[i].trustee, &owner_sid)) {
+                                       if (dom_sid_equal(&nt_ace_list[i].trustee, &owner_sid)) {
                                                add_or_replace_ace(nt_ace_list, &num_aces,
                                                                   &orig_owner_sid,
                                                                   nt_ace_list[i].type,
@@ -3385,11 +3386,11 @@ static NTSTATUS posix_get_nt_acl_common(struct connection_struct *conn,
                                goto done;
                        }
                }
-       } /* security_info & DACL_SECURITY_INFORMATION */
+       } /* security_info & SECINFO_DACL */
 
        psd = make_standard_sec_desc( talloc_tos(),
-                       (security_info & OWNER_SECURITY_INFORMATION) ? &owner_sid : NULL,
-                       (security_info & GROUP_SECURITY_INFORMATION) ? &group_sid : NULL,
+                       (security_info & SECINFO_OWNER) ? &owner_sid : NULL,
+                       (security_info & SECINFO_GROUP) ? &group_sid : NULL,
                        psa,
                        &sd_size);
 
@@ -3547,10 +3548,8 @@ int try_chown(connection_struct *conn, struct smb_filename *smb_fname,
        /* Case (2) / (3) */
        if (lp_enable_privileges()) {
 
-               bool has_take_ownership_priv = user_has_privileges(get_current_nttok(conn),
-                                                             &se_take_ownership);
-               bool has_restore_priv = user_has_privileges(get_current_nttok(conn),
-                                                      &se_restore);
+               bool has_take_ownership_priv = security_token_has_privilege(get_current_nttok(conn), SEC_PRIV_TAKE_OWNERSHIP);
+               bool has_restore_priv = security_token_has_privilege(get_current_nttok(conn), SEC_PRIV_RESTORE);
 
                /* Case (2) */
                if ( ( has_take_ownership_priv && ( uid == get_current_uid(conn) ) ) ||
@@ -3682,7 +3681,7 @@ NTSTATUS append_parent_acl(files_struct *fsp,
        }
 
        status = SMB_VFS_GET_NT_ACL(parent_fsp->conn, smb_dname->base_name,
-                                   DACL_SECURITY_INFORMATION, &parent_sd );
+                                   SECINFO_DACL, &parent_sd );
 
        close_file(NULL, parent_fsp, NORMAL_CLOSE);
        TALLOC_FREE(smb_dname);
@@ -3758,7 +3757,7 @@ NTSTATUS append_parent_acl(files_struct *fsp,
                         * same SID. This is order N^2. Ouch :-(. JRA. */
                        unsigned int k;
                        for (k = 0; k < psd->dacl->num_aces; k++) {
-                               if (sid_equal(&psd->dacl->aces[k].trustee,
+                               if (dom_sid_equal(&psd->dacl->aces[k].trustee,
                                                &se->trustee)) {
                                        break;
                                }
@@ -3825,9 +3824,11 @@ NTSTATUS append_parent_acl(files_struct *fsp,
  Reply to set a security descriptor on an fsp. security_info_sent is the
  description of the following NT ACL.
  This should be the only external function needed for the UNIX style set ACL.
+ We make a copy of psd_orig as internal functions modify the elements inside
+ it, even though it's a const pointer.
 ****************************************************************************/
 
-NTSTATUS set_nt_acl(files_struct *fsp, uint32 security_info_sent, const struct security_descriptor *psd)
+NTSTATUS set_nt_acl(files_struct *fsp, uint32 security_info_sent, const struct security_descriptor *psd_orig)
 {
        connection_struct *conn = fsp->conn;
        uid_t user = (uid_t)-1;
@@ -3842,6 +3843,7 @@ NTSTATUS set_nt_acl(files_struct *fsp, uint32 security_info_sent, const struct s
        bool set_acl_as_root = false;
        bool acl_set_support = false;
        bool ret = false;
+       struct security_descriptor *psd = NULL;
 
        DEBUG(10,("set_nt_acl: called for file %s\n",
                  fsp_str_dbg(fsp)));
@@ -3851,6 +3853,15 @@ NTSTATUS set_nt_acl(files_struct *fsp, uint32 security_info_sent, const struct s
                return NT_STATUS_MEDIA_WRITE_PROTECTED;
        }
 
+       if (!psd_orig) {
+               return NT_STATUS_INVALID_PARAMETER;
+       }
+
+       psd = dup_sec_desc(talloc_tos(), psd_orig);
+       if (!psd) {
+               return NT_STATUS_NO_MEMORY;
+       }
+
        /*
         * Get the current state of the file.
         */
@@ -3937,7 +3948,7 @@ NTSTATUS set_nt_acl(files_struct *fsp, uint32 security_info_sent, const struct s
         * Only change security if we got a DACL.
         */
 
-       if(!(security_info_sent & DACL_SECURITY_INFORMATION) || (psd->dacl == NULL)) {
+       if(!(security_info_sent & SECINFO_DACL) || (psd->dacl == NULL)) {
                free_canon_ace_list(file_ace_list);
                free_canon_ace_list(dir_ace_list);
                return NT_STATUS_OK;
@@ -4747,7 +4758,7 @@ struct security_descriptor *get_nt_acl_no_snum( TALLOC_CTX *ctx, const char *fna
                return NULL;
        }
 
-       if (!NT_STATUS_IS_OK(SMB_VFS_FGET_NT_ACL( &finfo, DACL_SECURITY_INFORMATION, &psd))) {
+       if (!NT_STATUS_IS_OK(SMB_VFS_FGET_NT_ACL( &finfo, SECINFO_DACL, &psd))) {
                DEBUG(0,("get_nt_acl_no_snum: get_nt_acl returned zero.\n"));
                TALLOC_FREE(finfo.fsp_name);
                conn_free(conn);