Changeset 232 for branches/samba-3.2.x/source/smbd/posix_acls.c
- Timestamp:
- May 27, 2009, 9:09:42 AM (16 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
branches/samba-3.2.x/source/smbd/posix_acls.c
r228 r232 3198 3198 } 3199 3199 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 3200 3209 if (SMB_VFS_STAT(conn,fname,&st)) { 3201 3210 return -1; … … 3205 3214 return -1; 3206 3215 } 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 is3210 a local SID on the users workstation3211 */3212 uid = current_user.ut.uid;3213 3216 3214 3217 become_root(); … … 3438 3441 mode_t orig_mode = (mode_t)0; 3439 3442 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; 3443 3446 3444 3447 DEBUG(10,("set_nt_acl: called for file %s\n", fsp->fsp_name )); … … 3461 3464 } 3462 3465 3463 /* Save the original element swe check against. */3466 /* Save the original element we check against. */ 3464 3467 orig_mode = sbuf.st_mode; 3465 orig_uid = sbuf.st_uid;3466 orig_gid = sbuf.st_gid;3467 3468 3468 3469 /* … … 3476 3477 3477 3478 /* 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. 3479 3482 */ 3480 3483 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))) { 3486 3485 3487 3486 DEBUG(3,("set_nt_acl: chown %s. uid = %u, gid = %u.\n", … … 3508 3507 } else { 3509 3508 3510 int ret;3509 int sret; 3511 3510 3512 3511 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); 3514 3513 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) 3518 3517 return map_nt_error_from_unix(errno); 3519 3518 } 3520 3519 3521 /* Save the original element swe check against. */3520 /* Save the original element we check against. */ 3522 3521 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; 3528 3527 } 3529 3528 3530 3529 create_file_sids(&sbuf, &file_owner_sid, &file_grp_sid); 3531 3532 #if 03533 /* Disable this - prevents ACL inheritance from the ACL editor. JRA. */3534 3535 /* See here: http://www.codeproject.com/KB/winsdk/accessctrl2.aspx3536 * 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 #endif3551 3530 3552 3531 acl_perms = unpack_canon_ace( fsp, &sbuf, &file_owner_sid, &file_grp_sid, … … 3554 3533 3555 3534 /* 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) )); 3560 3571 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; 3573 3594 3574 3595 /* 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. 3577 3597 */ 3578 3598 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))); 3583 3619 free_canon_ace_list(file_ace_list); 3584 free_canon_ace_list(dir_ace_list); 3620 free_canon_ace_list(dir_ace_list); 3585 3621 return map_nt_error_from_unix(errno); 3586 3622 } 3587 3623 } 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(); 3623 3675 } 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) )); 3639 3680 free_canon_ace_list(file_ace_list); 3640 3681 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); 3644 3683 } 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); 3694 3690 return NT_STATUS_OK; 3695 3691 }
Note:
See TracChangeset
for help on using the changeset viewer.