Fix the overwriting of errno before use in a DEBUG statement and use the return value...
[samba.git] / source3 / modules / onefs_acl.c
index 6f23d608d46da0a298f3bc1d0152e1cb8c22405e..749ddec3da748bfc4cd9d62941b91ff7028f44b0 100644 (file)
@@ -20,6 +20,7 @@
  */
 
 #include "includes.h"
+#include "smbd/smbd.h"
 #include "onefs.h"
 #include "onefs_config.h"
 
@@ -38,20 +39,20 @@ const struct enum_list enum_onefs_acl_wire_format[] = {
  * Turn SID into UID/GID and setup a struct ifs_identity
  */
 static bool
-onefs_sid_to_identity(const DOM_SID *sid, struct ifs_identity *id,
+onefs_sid_to_identity(const struct dom_sid *sid, struct ifs_identity *id,
     bool is_group)
 {
        enum ifs_identity_type type = IFS_ID_TYPE_LAST+1;
        uid_t uid = 0;
        gid_t gid = 0;
 
-       if (!sid || sid_equal(sid, &global_sid_NULL))
+       if (!sid || dom_sid_equal(sid, &global_sid_NULL))
                type = IFS_ID_TYPE_NULL;
-       else if (sid_equal(sid, &global_sid_World))
+       else if (dom_sid_equal(sid, &global_sid_World))
                type = IFS_ID_TYPE_EVERYONE;
-       else if (sid_equal(sid, &global_sid_Creator_Owner))
+       else if (dom_sid_equal(sid, &global_sid_Creator_Owner))
                type = IFS_ID_TYPE_CREATOR_OWNER;
-       else if (sid_equal(sid, &global_sid_Creator_Group))
+       else if (dom_sid_equal(sid, &global_sid_Creator_Group))
                type = IFS_ID_TYPE_CREATOR_GROUP;
        else if (is_group) {
                if (!sid_to_gid(sid, &gid))
@@ -80,7 +81,7 @@ onefs_sid_to_identity(const DOM_SID *sid, struct ifs_identity *id,
  * Turn struct ifs_identity into SID
  */
 static bool
-onefs_identity_to_sid(struct ifs_identity *id, DOM_SID *sid)
+onefs_identity_to_sid(struct ifs_identity *id, struct dom_sid *sid)
 {
        if (!id || !sid)
                return false;
@@ -116,10 +117,10 @@ onefs_identity_to_sid(struct ifs_identity *id, DOM_SID *sid)
 }
 
 static bool
-onefs_og_to_identity(DOM_SID *sid, struct ifs_identity * ident,
+onefs_og_to_identity(struct dom_sid *sid, struct ifs_identity * ident,
     bool is_group, int snum)
 {
-       const DOM_SID *b_admin_sid = &global_sid_Builtin_Administrators;
+       const struct dom_sid *b_admin_sid = &global_sid_Builtin_Administrators;
 
        if (!onefs_sid_to_identity(sid, ident, is_group)) {
                if (!lp_parm_bool(snum, PARM_ONEFS_TYPE,
@@ -140,10 +141,10 @@ onefs_og_to_identity(DOM_SID *sid, struct ifs_identity * ident,
 }
 
 static bool
-sid_in_ignore_list(DOM_SID * sid, int snum)
+sid_in_ignore_list(struct dom_sid * sid, int snum)
 {
        const char ** sid_list = NULL;
-       DOM_SID match;
+       struct dom_sid match;
 
        sid_list = lp_parm_string_list(snum, PARM_ONEFS_TYPE,
            PARM_UNMAPPABLE_SIDS_IGNORE_LIST,
@@ -155,7 +156,7 @@ sid_in_ignore_list(DOM_SID * sid, int snum)
 
        while (*sid_list) {
                if (string_to_sid(&match, *sid_list))
-                       if (sid_equal(sid, &match))
+                       if (dom_sid_equal(sid, &match))
                                return true;
                sid_list++;
        }
@@ -167,7 +168,7 @@ sid_in_ignore_list(DOM_SID * sid, int snum)
  * Convert a trustee to a struct identity
  */
 static bool
-onefs_samba_ace_to_ace(SEC_ACE * samba_ace, struct ifs_ace * ace,
+onefs_samba_ace_to_ace(struct security_ace * samba_ace, struct ifs_ace * ace,
     bool *mapped, int snum)
 {
        struct ifs_identity ident = {.type=IFS_ID_TYPE_LAST, .id.uid=0};
@@ -232,15 +233,15 @@ onefs_samba_ace_to_ace(SEC_ACE * samba_ace, struct ifs_ace * ace,
 }
 
 /**
- * Convert a SEC_ACL to a struct ifs_security_acl
+ * Convert a struct security_acl to a struct ifs_security_acl
  */
 static bool
-onefs_samba_acl_to_acl(SEC_ACL *samba_acl, struct ifs_security_acl **acl,
+onefs_samba_acl_to_acl(struct security_acl *samba_acl, struct ifs_security_acl **acl,
     bool * ignore_aces, int snum)
 {
        int num_aces = 0;
        struct ifs_ace *aces = NULL;
-       SEC_ACE *samba_aces;
+       struct security_ace *samba_aces;
        bool mapped;
        int i, j;
 
@@ -287,13 +288,13 @@ err_free:
 }
 
 /**
- * Convert a struct ifs_security_acl to a SEC_ACL
+ * Convert a struct ifs_security_acl to a struct security_acl
  */
 static bool
-onefs_acl_to_samba_acl(struct ifs_security_acl *acl, SEC_ACL **samba_acl)
+onefs_acl_to_samba_acl(struct ifs_security_acl *acl, struct security_acl **samba_acl)
 {
-       SEC_ACE *samba_aces = NULL;
-       SEC_ACL *tmp_samba_acl = NULL;
+       struct security_ace *samba_aces = NULL;
+       struct security_acl *tmp_samba_acl = NULL;
        int i, num_aces = 0;
 
        if (!samba_acl)
@@ -313,17 +314,17 @@ onefs_acl_to_samba_acl(struct ifs_security_acl *acl, SEC_ACL **samba_acl)
 
        /* Allocate the ace list. */
        if (num_aces > 0) {
-               if ((samba_aces = SMB_MALLOC_ARRAY(SEC_ACE, num_aces)) == NULL)
+               if ((samba_aces = SMB_MALLOC_ARRAY(struct security_ace, num_aces)) == NULL)
                {
                        DEBUG(0, ("Unable to malloc space for %d aces.\n",
                            num_aces));
                        return false;
                }
-               memset(samba_aces, '\0', (num_aces) * sizeof(SEC_ACE));
+               memset(samba_aces, '\0', (num_aces) * sizeof(struct security_ace));
        }
 
        for (i = 0; i < num_aces; i++) {
-               DOM_SID sid;
+               struct dom_sid sid;
 
                if (!onefs_identity_to_sid(&acl->aces[i].trustee, &sid))
                        goto err_free;
@@ -393,10 +394,10 @@ onefs_canon_acl(files_struct *fsp, struct ifs_security_descriptor *sd)
                if (error)
                        return false;
 
-               if ((sbuf.st_flags & SF_HASNTFSACL) != 0) {
+               if ((sbuf.st_ex_flags & SF_HASNTFSACL) != 0) {
                        DEBUG(10, ("Did not canonicalize ACLs because a "
-                           "Windows ACL set was found for file %s\n",
-                           fsp->fsp_name));
+                                  "Windows ACL set was found for file %s\n",
+                                  fsp_str_dbg(fsp)));
                        return true;
                }
                break;
@@ -417,26 +418,30 @@ onefs_canon_acl(files_struct *fsp, struct ifs_security_descriptor *sd)
         * By walking down the list 3 separate times, we can avoid the need
         * to create multiple temp buffers and extra copies.
         */
-       for (cur = 0; cur < sd->dacl->num_aces; cur++)  {
-               if (sd->dacl->aces[cur].flags & IFS_ACE_FLAG_INHERITED_ACE)
-                       new_aces[new_aces_count++] = sd->dacl->aces[cur];
-       }
 
+       /* Explict deny aces first */
        for (cur = 0; cur < sd->dacl->num_aces; cur++)  {
                if (!(sd->dacl->aces[cur].flags & IFS_ACE_FLAG_INHERITED_ACE) &&
                    (sd->dacl->aces[cur].type == IFS_ACE_TYPE_ACCESS_DENIED))
                        new_aces[new_aces_count++] = sd->dacl->aces[cur];
        }
 
+       /* Explict allow aces second */
        for (cur = 0; cur < sd->dacl->num_aces; cur++)  {
                if (!(sd->dacl->aces[cur].flags & IFS_ACE_FLAG_INHERITED_ACE) &&
                    !(sd->dacl->aces[cur].type == IFS_ACE_TYPE_ACCESS_DENIED))
                        new_aces[new_aces_count++] = sd->dacl->aces[cur];
        }
 
+       /* Inherited deny/allow aces third */
+       for (cur = 0; cur < sd->dacl->num_aces; cur++)  {
+               if ((sd->dacl->aces[cur].flags & IFS_ACE_FLAG_INHERITED_ACE))
+                       new_aces[new_aces_count++] = sd->dacl->aces[cur];
+       }
+
        SMB_ASSERT(new_aces_count == sd->dacl->num_aces);
        DEBUG(10, ("Performed canonicalization of ACLs for file %s\n",
-           fsp->fsp_name));
+                  fsp_str_dbg(fsp)));
 
        /*
         * At this point you would think we could just do this:
@@ -535,20 +540,21 @@ static bool add_sfs_aces(files_struct *fsp, struct ifs_security_descriptor *sd)
        if (error) {
                DEBUG(0, ("Failed to stat %s in simple files sharing "
                          "compatibility mode. errno=%d\n",
-                         fsp->fsp_name, errno));
+                         fsp_str_dbg(fsp), errno));
                return false;
        }
 
        /* Only continue if this is a synthetic ACL and a directory. */
-       if (S_ISDIR(sbuf.st_mode) && (sbuf.st_flags & SF_HASNTFSACL) == 0) {
+       if (S_ISDIR(sbuf.st_ex_mode) &&
+           (sbuf.st_ex_flags & SF_HASNTFSACL) == 0) {
                struct ifs_ace new_aces[6];
                struct ifs_ace *old_aces;
                int i, num_aces_to_add = 0;
                mode_t file_mode = 0, dir_mode = 0;
 
                /* Use existing samba logic to derive the mode bits. */
-               file_mode = unix_mode(fsp->conn, 0, fsp->fsp_name, false);
-               dir_mode = unix_mode(fsp->conn, aDIR, fsp->fsp_name, false);
+               file_mode = unix_mode(fsp->conn, 0, fsp->fsp_name, NULL);
+               dir_mode = unix_mode(fsp->conn, FILE_ATTRIBUTE_DIRECTORY, fsp->fsp_name, NULL);
 
                /* Initialize ACEs. */
                new_aces[0] = onefs_init_ace(fsp->conn, file_mode, false, USR);
@@ -599,16 +605,16 @@ static bool add_sfs_aces(files_struct *fsp, struct ifs_security_descriptor *sd)
  */
 NTSTATUS
 onefs_fget_nt_acl(vfs_handle_struct *handle, files_struct *fsp,
-                 uint32 security_info, SEC_DESC **ppdesc)
+                 uint32 security_info, struct security_descriptor **ppdesc)
 {
        int error;
        uint32_t sd_size = 0;
        size_t size = 0;
        struct ifs_security_descriptor *sd = NULL;
-       DOM_SID owner_sid, group_sid;
-       DOM_SID *ownerp, *groupp;
-       SEC_ACL *dacl, *sacl;
-       SEC_DESC *pdesc;
+       struct dom_sid owner_sid, group_sid;
+       struct dom_sid *ownerp, *groupp;
+       struct security_acl *dacl, *sacl;
+       struct security_descriptor *pdesc;
        bool alloced = false;
        bool new_aces_alloced = false;
        bool fopened = false;
@@ -619,18 +625,18 @@ onefs_fget_nt_acl(vfs_handle_struct *handle, files_struct *fsp,
        *ppdesc = NULL;
 
        DEBUG(5, ("Getting sd for file %s. security_info=%u\n",
-           fsp->fsp_name, security_info));
+                 fsp_str_dbg(fsp), security_info));
 
        if (lp_parm_bool(SNUM(fsp->conn), PARM_ONEFS_TYPE,
                PARM_IGNORE_SACLS, PARM_IGNORE_SACLS_DEFAULT)) {
-               DEBUG(5, ("Ignoring SACL on %s.\n", fsp->fsp_name));
-               security_info &= ~SACL_SECURITY_INFORMATION;
+               DEBUG(5, ("Ignoring SACL on %s.\n", fsp_str_dbg(fsp)));
+               security_info &= ~SECINFO_SACL;
        }
 
        if (fsp->fh->fd == -1) {
                if ((fsp->fh->fd = onefs_sys_create_file(handle->conn,
                                                         -1,
-                                                        fsp->fsp_name,
+                                                        fsp->fsp_name->base_name,
                                                         0,
                                                         0,
                                                         0,
@@ -643,7 +649,7 @@ onefs_fget_nt_acl(vfs_handle_struct *handle, files_struct *fsp,
                                                         0,
                                                         NULL)) == -1) {
                        DEBUG(0, ("Error opening file %s. errno=%d (%s)\n",
-                                 fsp->fsp_name, errno, strerror(errno)));
+                                 fsp_str_dbg(fsp), errno, strerror(errno)));
                        status = map_nt_error_from_unix(errno);
                        goto out;
                }
@@ -700,7 +706,7 @@ onefs_fget_nt_acl(vfs_handle_struct *handle, files_struct *fsp,
        sacl = NULL;
 
        /* Copy owner into ppdesc */
-       if (security_info & OWNER_SECURITY_INFORMATION) {
+       if (security_info & SECINFO_OWNER) {
                if (!onefs_identity_to_sid(sd->owner, &owner_sid)) {
                        status = NT_STATUS_INVALID_PARAMETER;
                        goto out;
@@ -710,7 +716,7 @@ onefs_fget_nt_acl(vfs_handle_struct *handle, files_struct *fsp,
        }
 
        /* Copy group into ppdesc */
-       if (security_info & GROUP_SECURITY_INFORMATION) {
+       if (security_info & SECINFO_GROUP) {
                if (!onefs_identity_to_sid(sd->group, &group_sid)) {
                        status = NT_STATUS_INVALID_PARAMETER;
                        goto out;
@@ -720,7 +726,7 @@ onefs_fget_nt_acl(vfs_handle_struct *handle, files_struct *fsp,
        }
 
        /* Copy DACL into ppdesc */
-       if (security_info & DACL_SECURITY_INFORMATION) {
+       if (security_info & SECINFO_DACL) {
                if (!onefs_acl_to_samba_acl(sd->dacl, &dacl)) {
                        status = NT_STATUS_INVALID_PARAMETER;
                        goto out;
@@ -728,7 +734,7 @@ onefs_fget_nt_acl(vfs_handle_struct *handle, files_struct *fsp,
        }
 
        /* Copy SACL into ppdesc */
-       if (security_info & SACL_SECURITY_INFORMATION) {
+       if (security_info & SECINFO_SACL) {
                if (!onefs_acl_to_samba_acl(sd->sacl, &sacl)) {
                        status = NT_STATUS_INVALID_PARAMETER;
                        goto out;
@@ -785,10 +791,11 @@ out:
  */
 NTSTATUS
 onefs_get_nt_acl(vfs_handle_struct *handle, const char* name,
-                uint32 security_info, SEC_DESC **ppdesc)
+                uint32 security_info, struct security_descriptor **ppdesc)
 {
        files_struct finfo;
        struct fd_handle fh;
+       NTSTATUS status;
 
        ZERO_STRUCT(finfo);
        ZERO_STRUCT(fh);
@@ -797,21 +804,30 @@ onefs_get_nt_acl(vfs_handle_struct *handle, const char* name,
        finfo.conn = handle->conn;
        finfo.fh = &fh;
        finfo.fh->fd = -1;
-       finfo.fsp_name = CONST_DISCARD(char *, name);
+       status = create_synthetic_smb_fname(talloc_tos(), name, NULL, NULL,
+                                           &finfo.fsp_name);
+       if (!NT_STATUS_IS_OK(status)) {
+               return status;
+       }
+
+       status = onefs_fget_nt_acl(handle, &finfo, security_info, ppdesc);
 
-       return onefs_fget_nt_acl(handle, &finfo, security_info, ppdesc);
+       TALLOC_FREE(finfo.fsp_name);
+       return status;
 }
 
 /**
  * Isilon-specific function for setting up an ifs_security_descriptor, given a
- * samba SEC_DESC.
+ * samba struct security_descriptor
  *
  * @param[out] sd ifs_security_descriptor to fill in
  *
  * @return NTSTATUS_OK if successful
  */
-NTSTATUS onefs_samba_sd_to_sd(uint32 security_info_sent, SEC_DESC *psd,
-                             struct ifs_security_descriptor *sd, int snum)
+NTSTATUS onefs_samba_sd_to_sd(uint32_t security_info_sent,
+                             const struct security_descriptor *psd,
+                             struct ifs_security_descriptor *sd, int snum,
+                             uint32_t *security_info_effective)
 {
        struct ifs_security_acl *daclp, *saclp;
        struct ifs_identity owner, group, *ownerp, *groupp;
@@ -822,10 +838,12 @@ NTSTATUS onefs_samba_sd_to_sd(uint32 security_info_sent, SEC_DESC *psd,
        daclp = NULL;
        saclp = NULL;
 
+       *security_info_effective = security_info_sent;
+
        /* Setup owner */
-       if (security_info_sent & OWNER_SECURITY_INFORMATION) {
+       if (security_info_sent & SECINFO_OWNER) {
                if (!onefs_og_to_identity(psd->owner_sid, &owner, false, snum))
-                       return NT_STATUS_UNSUCCESSFUL;
+                       return NT_STATUS_ACCESS_DENIED;
 
                SMB_ASSERT(owner.id.uid >= 0);
 
@@ -833,9 +851,9 @@ NTSTATUS onefs_samba_sd_to_sd(uint32 security_info_sent, SEC_DESC *psd,
        }
 
        /* Setup group */
-       if (security_info_sent & GROUP_SECURITY_INFORMATION) {
+       if (security_info_sent & SECINFO_GROUP) {
                if (!onefs_og_to_identity(psd->group_sid, &group, true, snum))
-                       return NT_STATUS_UNSUCCESSFUL;
+                       return NT_STATUS_ACCESS_DENIED;
 
                SMB_ASSERT(group.id.gid >= 0);
 
@@ -843,31 +861,31 @@ NTSTATUS onefs_samba_sd_to_sd(uint32 security_info_sent, SEC_DESC *psd,
        }
 
        /* Setup DACL */
-       if ((security_info_sent & DACL_SECURITY_INFORMATION) && (psd->dacl)) {
+       if ((security_info_sent & SECINFO_DACL) && (psd->dacl)) {
                if (!onefs_samba_acl_to_acl(psd->dacl, &daclp, &ignore_aces,
                        snum))
-                       return NT_STATUS_UNSUCCESSFUL;
+                       return NT_STATUS_ACCESS_DENIED;
 
                if (ignore_aces == true)
-                       security_info_sent &= ~DACL_SECURITY_INFORMATION;
+                       *security_info_effective &= ~SECINFO_DACL;
        }
 
        /* Setup SACL */
-       if (security_info_sent & SACL_SECURITY_INFORMATION) {
+       if (security_info_sent & SECINFO_SACL) {
 
                if (lp_parm_bool(snum, PARM_ONEFS_TYPE,
                            PARM_IGNORE_SACLS, PARM_IGNORE_SACLS_DEFAULT)) {
-                       DEBUG(5, ("Ignoring SACLs.\n"));
-                       security_info_sent &= ~SACL_SECURITY_INFORMATION;
+                       DEBUG(5, ("Ignoring SACL.\n"));
+                       *security_info_effective &= ~SECINFO_SACL;
                } else {
                        if (psd->sacl) {
                                if (!onefs_samba_acl_to_acl(psd->sacl,
                                        &saclp, &ignore_aces, snum))
-                                       return NT_STATUS_UNSUCCESSFUL;
+                                       return NT_STATUS_ACCESS_DENIED;
 
                                if (ignore_aces == true) {
-                                       security_info_sent &=
-                                           ~SACL_SECURITY_INFORMATION;
+                                       *security_info_effective &=
+                                           ~SECINFO_SACL;
                                }
                        }
                }
@@ -877,7 +895,10 @@ NTSTATUS onefs_samba_sd_to_sd(uint32 security_info_sent, SEC_DESC *psd,
        DEBUG(5,("Setting up SD\n"));
        if (aclu_initialize_sd(sd, psd->type, ownerp, groupp,
                (daclp ? &daclp : NULL), (saclp ? &saclp : NULL), false))
-               return NT_STATUS_UNSUCCESSFUL;
+               return NT_STATUS_ACCESS_DENIED;
+
+       DEBUG(10, ("sec_info_sent: 0x%x, sec_info_effective: 0x%x.\n",
+                  security_info_sent, *security_info_effective));
 
        return NT_STATUS_OK;
 }
@@ -890,19 +911,20 @@ NTSTATUS onefs_samba_sd_to_sd(uint32 security_info_sent, SEC_DESC *psd,
  */
 NTSTATUS
 onefs_fset_nt_acl(vfs_handle_struct *handle, files_struct *fsp,
-                 uint32 security_info_sent, SEC_DESC *psd)
+                 uint32_t sec_info_sent, const struct security_descriptor *psd)
 {
        struct ifs_security_descriptor sd = {};
        int fd = -1;
        bool fopened = false;
        NTSTATUS status;
+       uint32_t sec_info_effective = 0;
 
        START_PROFILE(syscall_set_sd);
 
-       DEBUG(5,("Setting SD on file %s.\n", fsp->fsp_name ));
+       DEBUG(5,("Setting SD on file %s.\n", fsp_str_dbg(fsp)));
 
-       status = onefs_samba_sd_to_sd(security_info_sent, psd, &sd,
-                                     SNUM(handle->conn));
+       status = onefs_samba_sd_to_sd(sec_info_sent, psd, &sd,
+                                     SNUM(handle->conn), &sec_info_effective);
 
        if (!NT_STATUS_IS_OK(status)) {
                DEBUG(3, ("SD initialization failure: %s\n", nt_errstr(status)));
@@ -911,9 +933,10 @@ onefs_fset_nt_acl(vfs_handle_struct *handle, files_struct *fsp,
 
        fd = fsp->fh->fd;
        if (fd == -1) {
+               DEBUG(10,("Reopening file %s.\n", fsp_str_dbg(fsp)));
                if ((fd = onefs_sys_create_file(handle->conn,
                                                -1,
-                                               fsp->fsp_name,
+                                               fsp->fsp_name->base_name,
                                                0,
                                                0,
                                                0,
@@ -926,7 +949,7 @@ onefs_fset_nt_acl(vfs_handle_struct *handle, files_struct *fsp,
                                                0,
                                                NULL)) == -1) {
                        DEBUG(0, ("Error opening file %s. errno=%d (%s)\n",
-                                 fsp->fsp_name, errno, strerror(errno)));
+                                 fsp_str_dbg(fsp), errno, strerror(errno)));
                        status = map_nt_error_from_unix(errno);
                        goto out;
                }
@@ -934,8 +957,9 @@ onefs_fset_nt_acl(vfs_handle_struct *handle, files_struct *fsp,
        }
 
         errno = 0;
-       if (ifs_set_security_descriptor(fd, security_info_sent, &sd)) {
-               DEBUG(0, ("Error setting security descriptor = %d\n", errno));
+       if (ifs_set_security_descriptor(fd, sec_info_effective, &sd)) {
+               DEBUG(0, ("Error setting security descriptor = %s\n",
+                         strerror(errno)));
                status = map_nt_error_from_unix(errno);
                goto out;
        }