Ignore:
Timestamp:
May 27, 2009, 9:09:42 AM (16 years ago)
Author:
Herwig Bauernfeind
Message:

Update 3.2 branch to 3.2.8

File:
1 edited

Legend:

Unmodified
Added
Removed
  • branches/samba-3.2.x/source/smbd/posix_acls.c

    r228 r232  
    31983198        }
    31993199
     3200        /* only allow chown to the current user. This is more secure,
     3201           and also copes with the case where the SID in a take ownership ACL is
     3202           a local SID on the users workstation
     3203        */
     3204        if (uid != current_user.ut.uid) {
     3205                errno = EPERM;
     3206                return -1;
     3207        }
     3208
    32003209        if (SMB_VFS_STAT(conn,fname,&st)) {
    32013210                return -1;
     
    32053214                return -1;
    32063215        }
    3207 
    3208         /* only allow chown to the current user. This is more secure,
    3209            and also copes with the case where the SID in a take ownership ACL is
    3210            a local SID on the users workstation
    3211         */
    3212         uid = current_user.ut.uid;
    32133216
    32143217        become_root();
     
    34383441        mode_t orig_mode = (mode_t)0;
    34393442        NTSTATUS status;
    3440         uid_t orig_uid;
    3441         gid_t orig_gid;
    3442         bool need_chown = False;
     3443        bool set_acl_as_root = false;
     3444        bool acl_set_support = false;
     3445        bool ret = false;
    34433446
    34443447        DEBUG(10,("set_nt_acl: called for file %s\n", fsp->fsp_name ));
     
    34613464        }
    34623465
    3463         /* Save the original elements we check against. */
     3466        /* Save the original element we check against. */
    34643467        orig_mode = sbuf.st_mode;
    3465         orig_uid = sbuf.st_uid;
    3466         orig_gid = sbuf.st_gid;
    34673468
    34683469        /*
     
    34763477
    34773478        /*
    3478          * Do we need to chown ?
     3479         * Do we need to chown ? If so this must be done first as the incoming
     3480         * CREATOR_OWNER acl will be relative to the *new* owner, not the old.
     3481         * Noticed by Simo.
    34793482         */
    34803483
    3481         if (((user != (uid_t)-1) && (orig_uid != user)) || (( grp != (gid_t)-1) && (orig_gid != grp))) {
    3482                 need_chown = True;
    3483         }
    3484 
    3485         if (need_chown && (user == (uid_t)-1 || user == current_user.ut.uid)) {
     3484        if (((user != (uid_t)-1) && (sbuf.st_uid != user)) || (( grp != (gid_t)-1) && (sbuf.st_gid != grp))) {
    34863485
    34873486                DEBUG(3,("set_nt_acl: chown %s. uid = %u, gid = %u.\n",
     
    35083507                } else {
    35093508
    3510                         int ret;
     3509                        int sret;
    35113510
    35123511                        if(fsp->fh->fd == -1)
    3513                                 ret = SMB_VFS_STAT(fsp->conn, fsp->fsp_name, &sbuf);
     3512                                sret = SMB_VFS_STAT(fsp->conn, fsp->fsp_name, &sbuf);
    35143513                        else
    3515                                 ret = SMB_VFS_FSTAT(fsp, &sbuf);
    3516 
    3517                         if(ret != 0)
     3514                                sret = SMB_VFS_FSTAT(fsp, &sbuf);
     3515
     3516                        if(sret != 0)
    35183517                                return map_nt_error_from_unix(errno);
    35193518                }
    35203519
    3521                 /* Save the original elements we check against. */
     3520                /* Save the original element we check against. */
    35223521                orig_mode = sbuf.st_mode;
    3523                 orig_uid = sbuf.st_uid;
    3524                 orig_gid = sbuf.st_gid;
    3525 
    3526                 /* We did chown already, drop the flag */
    3527                 need_chown = False;
     3522
     3523                /* If we successfully chowned, we know we must
     3524                 * be able to set the acl, so do it as root.
     3525                */
     3526                set_acl_as_root = true;
    35283527        }
    35293528
    35303529        create_file_sids(&sbuf, &file_owner_sid, &file_grp_sid);
    3531 
    3532 #if 0
    3533         /* Disable this - prevents ACL inheritance from the ACL editor. JRA. */
    3534 
    3535         /* See here: http://www.codeproject.com/KB/winsdk/accessctrl2.aspx
    3536          * for details and also the log trace in bug #4308. JRA.
    3537          */
    3538 
    3539         if ((security_info_sent & DACL_SECURITY_INFORMATION) &&
    3540                 psd->dacl != NULL &&
    3541                 (psd->type & (SE_DESC_DACL_AUTO_INHERITED|
    3542                               SE_DESC_DACL_AUTO_INHERIT_REQ))==
    3543                         (SE_DESC_DACL_AUTO_INHERITED|
    3544                          SE_DESC_DACL_AUTO_INHERIT_REQ) ) {
    3545                 status = append_parent_acl(fsp, &sbuf, psd, &psd);
    3546                 if (!NT_STATUS_IS_OK(status)) {
    3547                         return status;
    3548                 }
    3549         }
    3550 #endif
    35513530
    35523531        acl_perms = unpack_canon_ace( fsp, &sbuf, &file_owner_sid, &file_grp_sid,
     
    35543533
    35553534        /* Ignore W2K traverse DACL set. */
    3556         if (file_ace_list || dir_ace_list) {
    3557 
    3558                 if (!acl_perms) {
    3559                         DEBUG(3,("set_nt_acl: cannot set permissions\n"));
     3535        if (!file_ace_list && !dir_ace_list) {
     3536                return NT_STATUS_OK;
     3537        }
     3538
     3539        if (!acl_perms) {
     3540                DEBUG(3,("set_nt_acl: cannot set permissions\n"));
     3541                free_canon_ace_list(file_ace_list);
     3542                free_canon_ace_list(dir_ace_list);
     3543                return NT_STATUS_ACCESS_DENIED;
     3544        }
     3545
     3546        /*
     3547         * Only change security if we got a DACL.
     3548         */
     3549
     3550        if(!(security_info_sent & DACL_SECURITY_INFORMATION) || (psd->dacl == NULL)) {
     3551                free_canon_ace_list(file_ace_list);
     3552                free_canon_ace_list(dir_ace_list);
     3553                return NT_STATUS_OK;
     3554        }
     3555
     3556        /*
     3557         * Try using the POSIX ACL set first. Fall back to chmod if
     3558         * we have no ACL support on this filesystem.
     3559         */
     3560
     3561        if (acl_perms && file_ace_list) {
     3562                if (set_acl_as_root) {
     3563                        become_root();
     3564                }
     3565                ret = set_canon_ace_list(fsp, file_ace_list, False, sbuf.st_gid, &acl_set_support);
     3566                if (set_acl_as_root) {
     3567                        unbecome_root();
     3568                }
     3569                if (acl_set_support && ret == false) {
     3570                        DEBUG(3,("set_nt_acl: failed to set file acl on file %s (%s).\n", fsp->fsp_name, strerror(errno) ));
    35603571                        free_canon_ace_list(file_ace_list);
    3561                         free_canon_ace_list(dir_ace_list);
    3562                         return NT_STATUS_ACCESS_DENIED;
    3563                 }
    3564 
    3565                 /*
    3566                  * Only change security if we got a DACL.
    3567                  */
    3568 
    3569                 if((security_info_sent & DACL_SECURITY_INFORMATION) && (psd->dacl != NULL)) {
    3570 
    3571                         bool acl_set_support = False;
    3572                         bool ret = False;
     3572                        free_canon_ace_list(dir_ace_list);
     3573                        return map_nt_error_from_unix(errno);
     3574                }
     3575        }
     3576
     3577        if (acl_perms && acl_set_support && fsp->is_directory) {
     3578                if (dir_ace_list) {
     3579                        if (set_acl_as_root) {
     3580                                become_root();
     3581                        }
     3582                        ret = set_canon_ace_list(fsp, dir_ace_list, True, sbuf.st_gid, &acl_set_support);
     3583                        if (set_acl_as_root) {
     3584                                unbecome_root();
     3585                        }
     3586                        if (ret == false) {
     3587                                DEBUG(3,("set_nt_acl: failed to set default acl on directory %s (%s).\n", fsp->fsp_name, strerror(errno) ));
     3588                                free_canon_ace_list(file_ace_list);
     3589                                free_canon_ace_list(dir_ace_list);
     3590                                return map_nt_error_from_unix(errno);
     3591                        }
     3592                } else {
     3593                        int sret = -1;
    35733594
    35743595                        /*
    3575                          * Try using the POSIX ACL set first. Fall back to chmod if
    3576                          * we have no ACL support on this filesystem.
     3596                         * No default ACL - delete one if it exists.
    35773597                         */
    35783598
    3579                         if (acl_perms && file_ace_list) {
    3580                                 ret = set_canon_ace_list(fsp, file_ace_list, False, sbuf.st_gid, &acl_set_support);
    3581                                 if (acl_set_support && ret == False) {
    3582                                         DEBUG(3,("set_nt_acl: failed to set file acl on file %s (%s).\n", fsp->fsp_name, strerror(errno) ));
     3599                        if (set_acl_as_root) {
     3600                                become_root();
     3601                        }
     3602                        sret = SMB_VFS_SYS_ACL_DELETE_DEF_FILE(conn, fsp->fsp_name);
     3603                        if (set_acl_as_root) {
     3604                                unbecome_root();
     3605                        }
     3606                        if (sret == -1) {
     3607                                if (acl_group_override(conn, sbuf.st_gid, fsp->fsp_name)) {
     3608                                        DEBUG(5,("set_nt_acl: acl group control on and "
     3609                                                "current user in file %s primary group. Override delete_def_acl\n",
     3610                                                fsp->fsp_name ));
     3611
     3612                                        become_root();
     3613                                        sret = SMB_VFS_SYS_ACL_DELETE_DEF_FILE(conn, fsp->fsp_name);
     3614                                        unbecome_root();
     3615                                }
     3616
     3617                                if (sret == -1) {
     3618                                        DEBUG(3,("set_nt_acl: sys_acl_delete_def_file failed (%s)\n", strerror(errno)));
    35833619                                        free_canon_ace_list(file_ace_list);
    3584                                         free_canon_ace_list(dir_ace_list); 
     3620                                        free_canon_ace_list(dir_ace_list);
    35853621                                        return map_nt_error_from_unix(errno);
    35863622                                }
    35873623                        }
    3588 
    3589                         if (acl_perms && acl_set_support && fsp->is_directory) {
    3590                                 if (dir_ace_list) {
    3591                                         if (!set_canon_ace_list(fsp, dir_ace_list, True, sbuf.st_gid, &acl_set_support)) {
    3592                                                 DEBUG(3,("set_nt_acl: failed to set default acl on directory %s (%s).\n", fsp->fsp_name, strerror(errno) ));
    3593                                                 free_canon_ace_list(file_ace_list);
    3594                                                 free_canon_ace_list(dir_ace_list);
    3595                                                 return map_nt_error_from_unix(errno);
    3596                                         }
    3597                                 } else {
    3598 
    3599                                         /*
    3600                                          * No default ACL - delete one if it exists.
    3601                                          */
    3602 
    3603                                         if (SMB_VFS_SYS_ACL_DELETE_DEF_FILE(conn, fsp->fsp_name) == -1) {
    3604                                                 int sret = -1;
    3605 
    3606                                                 if (acl_group_override(conn, sbuf.st_gid, fsp->fsp_name)) {
    3607                                                         DEBUG(5,("set_nt_acl: acl group control on and "
    3608                                                                 "current user in file %s primary group. Override delete_def_acl\n",
    3609                                                                 fsp->fsp_name ));
    3610 
    3611                                                         become_root();
    3612                                                         sret = SMB_VFS_SYS_ACL_DELETE_DEF_FILE(conn, fsp->fsp_name);
    3613                                                         unbecome_root();
    3614                                                 }
    3615 
    3616                                                 if (sret == -1) {
    3617                                                         DEBUG(3,("set_nt_acl: sys_acl_delete_def_file failed (%s)\n", strerror(errno)));
    3618                                                         free_canon_ace_list(file_ace_list);
    3619                                                         free_canon_ace_list(dir_ace_list);
    3620                                                         return map_nt_error_from_unix(errno);
    3621                                                 }
    3622                                         }
     3624                }
     3625        }
     3626
     3627        if (acl_set_support) {
     3628                if (set_acl_as_root) {
     3629                        become_root();
     3630                }
     3631                store_inheritance_attributes(fsp, file_ace_list, dir_ace_list,
     3632                                (psd->type & SE_DESC_DACL_PROTECTED) ? True : False);
     3633                if (set_acl_as_root) {
     3634                        unbecome_root();
     3635                }
     3636        }
     3637
     3638        /*
     3639         * If we cannot set using POSIX ACLs we fall back to checking if we need to chmod.
     3640         */
     3641
     3642        if(!acl_set_support && acl_perms) {
     3643                mode_t posix_perms;
     3644
     3645                if (!convert_canon_ace_to_posix_perms( fsp, file_ace_list, &posix_perms)) {
     3646                        free_canon_ace_list(file_ace_list);
     3647                        free_canon_ace_list(dir_ace_list);
     3648                        DEBUG(3,("set_nt_acl: failed to convert file acl to posix permissions for file %s.\n",
     3649                                fsp->fsp_name ));
     3650                        return NT_STATUS_ACCESS_DENIED;
     3651                }
     3652
     3653                if (orig_mode != posix_perms) {
     3654                        int sret = -1;
     3655
     3656                        DEBUG(3,("set_nt_acl: chmod %s. perms = 0%o.\n",
     3657                                fsp->fsp_name, (unsigned int)posix_perms ));
     3658
     3659                        if (set_acl_as_root) {
     3660                                become_root();
     3661                        }
     3662                        sret = SMB_VFS_CHMOD(conn,fsp->fsp_name, posix_perms);
     3663                        if (set_acl_as_root) {
     3664                                unbecome_root();
     3665                        }
     3666                        if(sret == -1) {
     3667                                if (acl_group_override(conn, sbuf.st_gid, fsp->fsp_name)) {
     3668                                        DEBUG(5,("set_nt_acl: acl group control on and "
     3669                                                "current user in file %s primary group. Override chmod\n",
     3670                                                fsp->fsp_name ));
     3671
     3672                                        become_root();
     3673                                        sret = SMB_VFS_CHMOD(conn,fsp->fsp_name, posix_perms);
     3674                                        unbecome_root();
    36233675                                }
    3624                         }
    3625 
    3626                         if (acl_set_support) {
    3627                                 store_inheritance_attributes(fsp, file_ace_list, dir_ace_list,
    3628                                                 (psd->type & SE_DESC_DACL_PROTECTED) ? True : False);
    3629                         }
    3630 
    3631                         /*
    3632                          * If we cannot set using POSIX ACLs we fall back to checking if we need to chmod.
    3633                          */
    3634 
    3635                         if(!acl_set_support && acl_perms) {
    3636                                 mode_t posix_perms;
    3637 
    3638                                 if (!convert_canon_ace_to_posix_perms( fsp, file_ace_list, &posix_perms)) {
     3676
     3677                                if (sret == -1) {
     3678                                        DEBUG(3,("set_nt_acl: chmod %s, 0%o failed. Error = %s.\n",
     3679                                                fsp->fsp_name, (unsigned int)posix_perms, strerror(errno) ));
    36393680                                        free_canon_ace_list(file_ace_list);
    36403681                                        free_canon_ace_list(dir_ace_list);
    3641                                         DEBUG(3,("set_nt_acl: failed to convert file acl to posix permissions for file %s.\n",
    3642                                                 fsp->fsp_name ));
    3643                                         return NT_STATUS_ACCESS_DENIED;
     3682                                        return map_nt_error_from_unix(errno);
    36443683                                }
    3645 
    3646                                 if (orig_mode != posix_perms) {
    3647 
    3648                                         DEBUG(3,("set_nt_acl: chmod %s. perms = 0%o.\n",
    3649                                                 fsp->fsp_name, (unsigned int)posix_perms ));
    3650 
    3651                                         if(SMB_VFS_CHMOD(conn,fsp->fsp_name, posix_perms) == -1) {
    3652                                                 int sret = -1;
    3653                                                 if (acl_group_override(conn, sbuf.st_gid, fsp->fsp_name)) {
    3654                                                         DEBUG(5,("set_nt_acl: acl group control on and "
    3655                                                                 "current user in file %s primary group. Override chmod\n",
    3656                                                                 fsp->fsp_name ));
    3657 
    3658                                                         become_root();
    3659                                                         sret = SMB_VFS_CHMOD(conn,fsp->fsp_name, posix_perms);
    3660                                                         unbecome_root();
    3661                                                 }
    3662 
    3663                                                 if (sret == -1) {
    3664                                                         DEBUG(3,("set_nt_acl: chmod %s, 0%o failed. Error = %s.\n",
    3665                                                                 fsp->fsp_name, (unsigned int)posix_perms, strerror(errno) ));
    3666                                                         free_canon_ace_list(file_ace_list);
    3667                                                         free_canon_ace_list(dir_ace_list);
    3668                                                         return map_nt_error_from_unix(errno);
    3669                                                 }
    3670                                         }
    3671                                 }
    3672                         }
    3673                 }
    3674 
    3675                 free_canon_ace_list(file_ace_list);
    3676                 free_canon_ace_list(dir_ace_list);
    3677         }
    3678 
    3679         /* Any chown pending? */
    3680         if (need_chown) {
    3681                 DEBUG(3,("set_nt_acl: chown %s. uid = %u, gid = %u.\n",
    3682                          fsp->fsp_name, (unsigned int)user, (unsigned int)grp ));
    3683                
    3684                 if(try_chown( fsp->conn, fsp->fsp_name, user, grp) == -1) {
    3685                         DEBUG(3,("set_nt_acl: chown %s, %u, %u failed. Error = %s.\n",
    3686                                  fsp->fsp_name, (unsigned int)user, (unsigned int)grp, strerror(errno) ));
    3687                         if (errno == EPERM) {
    3688                                 return NT_STATUS_INVALID_OWNER;
    3689                         }
    3690                         return map_nt_error_from_unix(errno);
    3691                 }
    3692         }
    3693        
     3684                        }
     3685                }
     3686        }
     3687
     3688        free_canon_ace_list(file_ace_list);
     3689        free_canon_ace_list(dir_ace_list);
    36943690        return NT_STATUS_OK;
    36953691}
Note: See TracChangeset for help on using the changeset viewer.