Changeset 312 for branches/samba-3.0/source/smbd/posix_acls.c
- Timestamp:
- Aug 5, 2009, 6:34:45 PM (16 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
branches/samba-3.0/source/smbd/posix_acls.c
r286 r312 3098 3098 } 3099 3099 3100 /* only allow chown to the current user. This is more secure, 3101 and also copes with the case where the SID in a take ownership ACL is 3102 a local SID on the users workstation 3103 */ 3104 if (uid != current_user.ut.uid) { 3105 errno = EPERM; 3106 return -1; 3107 } 3108 3100 3109 if (SMB_VFS_STAT(conn,fname,&st)) { 3101 3110 return -1; … … 3105 3114 return -1; 3106 3115 } 3107 3108 /* only allow chown to the current user. This is more secure,3109 and also copes with the case where the SID in a take ownership ACL is3110 a local SID on the users workstation3111 */3112 uid = current_user.ut.uid;3113 3116 3114 3117 become_root(); … … 3339 3342 BOOL acl_perms = False; 3340 3343 mode_t orig_mode = (mode_t)0; 3341 uid_t orig_uid;3342 gid_t orig_gid;3343 BOOL need_chown = False;3344 BOOL set_acl_as_root = false; 3345 BOOL acl_set_support = false; 3346 BOOL ret = false; 3344 3347 3345 3348 DEBUG(10,("set_nt_acl: called for file %s\n", fsp->fsp_name )); … … 3364 3367 /* Save the original elements we check against. */ 3365 3368 orig_mode = sbuf.st_mode; 3366 orig_uid = sbuf.st_uid;3367 orig_gid = sbuf.st_gid;3368 3369 3369 3370 /* … … 3379 3380 */ 3380 3381 3381 if (((user != (uid_t)-1) && (orig_uid != user)) || (( grp != (gid_t)-1) && (orig_gid != grp))) { 3382 need_chown = True; 3383 } 3384 3385 /* 3386 * Chown before setting ACL only if we don't change the user, or 3387 * if we change to the current user, but not if we want to give away 3388 * the file. 3389 */ 3390 3391 if (need_chown && (user == (uid_t)-1 || user == current_user.ut.uid)) { 3382 if (((user != (uid_t)-1) && (sbuf.st_uid != user)) || (( grp != (gid_t)-1) && (sbuf.st_gid != grp))) { 3392 3383 3393 3384 DEBUG(3,("set_nt_acl: chown %s. uid = %u, gid = %u.\n", … … 3411 3402 } else { 3412 3403 3413 int ret;3404 int sret; 3414 3405 3415 3406 if(fsp->fh->fd == -1) 3416 ret = SMB_VFS_STAT(fsp->conn, fsp->fsp_name, &sbuf);3407 sret = SMB_VFS_STAT(fsp->conn, fsp->fsp_name, &sbuf); 3417 3408 else 3418 ret = SMB_VFS_FSTAT(fsp,fsp->fh->fd,&sbuf);3419 3420 if( ret != 0)3409 sret = SMB_VFS_FSTAT(fsp,fsp->fh->fd,&sbuf); 3410 3411 if(sret != 0) 3421 3412 return False; 3422 3413 } … … 3424 3415 /* Save the original elements we check against. */ 3425 3416 orig_mode = sbuf.st_mode; 3426 orig_uid = sbuf.st_uid; 3427 orig_gid = sbuf.st_gid;3428 3429 /* We did it, don't try again*/3430 need_chown = False;3417 3418 /* If we successfully chowned, we know we must 3419 * be able to set the acl, so do it as root. 3420 */ 3421 set_acl_as_root = true; 3431 3422 } 3432 3423 3433 3424 create_file_sids(&sbuf, &file_owner_sid, &file_grp_sid); 3434 3435 #if 03436 /* Disable this - prevents ACL inheritance from the ACL editor. JRA. */3437 3438 /* See here: http://www.codeproject.com/KB/winsdk/accessctrl2.aspx3439 * for details and also the log trace in bug #4308. JRA.3440 */3441 3442 if ((security_info_sent & DACL_SECURITY_INFORMATION) &&3443 psd->dacl != NULL &&3444 (psd->type & (SE_DESC_DACL_AUTO_INHERITED|3445 SE_DESC_DACL_AUTO_INHERIT_REQ))==3446 (SE_DESC_DACL_AUTO_INHERITED|3447 SE_DESC_DACL_AUTO_INHERIT_REQ) ) {3448 NTSTATUS status = append_parent_acl(fsp, &sbuf, psd, &psd);3449 if (!NT_STATUS_IS_OK(status)) {3450 return False;3451 }3452 }3453 #endif3454 3425 3455 3426 acl_perms = unpack_canon_ace( fsp, &sbuf, &file_owner_sid, &file_grp_sid, … … 3457 3428 3458 3429 /* Ignore W2K traverse DACL set. */ 3459 if (file_ace_list || dir_ace_list) { 3460 3461 if (!acl_perms) { 3462 DEBUG(3,("set_nt_acl: cannot set permissions\n")); 3430 if (!file_ace_list && !dir_ace_list) { 3431 return True; 3432 } 3433 3434 if (!acl_perms) { 3435 DEBUG(3,("set_nt_acl: cannot set permissions\n")); 3436 free_canon_ace_list(file_ace_list); 3437 free_canon_ace_list(dir_ace_list); 3438 return False; 3439 } 3440 3441 /* 3442 * Only change security if we got a DACL. 3443 */ 3444 3445 if(!(security_info_sent & DACL_SECURITY_INFORMATION) || (psd->dacl == NULL)) { 3446 free_canon_ace_list(file_ace_list); 3447 free_canon_ace_list(dir_ace_list); 3448 return True; 3449 } 3450 3451 /* 3452 * Try using the POSIX ACL set first. Fall back to chmod if 3453 * we have no ACL support on this filesystem. 3454 */ 3455 3456 if (acl_perms && file_ace_list) { 3457 if (set_acl_as_root) { 3458 become_root(); 3459 } 3460 ret = set_canon_ace_list(fsp, file_ace_list, False, sbuf.st_gid, &acl_set_support); 3461 if (set_acl_as_root) { 3462 unbecome_root(); 3463 } 3464 if (acl_set_support && ret == False) { 3465 DEBUG(3,("set_nt_acl: failed to set file acl on file %s (%s).\n", fsp->fsp_name, strerror(errno) )); 3463 3466 free_canon_ace_list(file_ace_list); 3464 free_canon_ace_list(dir_ace_list); 3467 free_canon_ace_list(dir_ace_list); 3465 3468 return False; 3466 3469 } 3467 3468 /* 3469 * Only change security if we got a DACL. 3470 */ 3471 3472 if((security_info_sent & DACL_SECURITY_INFORMATION) && (psd->dacl != NULL)) { 3473 3474 BOOL acl_set_support = False; 3475 BOOL ret = False; 3470 } 3471 3472 if (acl_perms && acl_set_support && fsp->is_directory) { 3473 if (dir_ace_list) { 3474 if (set_acl_as_root) { 3475 become_root(); 3476 } 3477 ret = set_canon_ace_list(fsp, dir_ace_list, True, sbuf.st_gid, &acl_set_support); 3478 if (set_acl_as_root) { 3479 unbecome_root(); 3480 } 3481 if (ret == False) { 3482 DEBUG(3,("set_nt_acl: failed to set default acl on directory %s (%s).\n", fsp->fsp_name, strerror(errno) )); 3483 free_canon_ace_list(file_ace_list); 3484 free_canon_ace_list(dir_ace_list); 3485 return False; 3486 } 3487 } else { 3488 3489 int sret = -1; 3476 3490 3477 3491 /* 3478 * Try using the POSIX ACL set first. Fall back to chmod if 3479 * we have no ACL support on this filesystem. 3492 * No default ACL - delete one if it exists. 3480 3493 */ 3481 3494 3482 if (acl_perms && file_ace_list) { 3483 ret = set_canon_ace_list(fsp, file_ace_list, False, sbuf.st_gid, &acl_set_support); 3484 if (acl_set_support && ret == False) { 3485 DEBUG(3,("set_nt_acl: failed to set file acl on file %s (%s).\n", fsp->fsp_name, strerror(errno) )); 3495 if (set_acl_as_root) { 3496 become_root(); 3497 } 3498 sret = SMB_VFS_SYS_ACL_DELETE_DEF_FILE(conn, fsp->fsp_name); 3499 if (set_acl_as_root) { 3500 unbecome_root(); 3501 } 3502 3503 if (sret == -1) { 3504 if (acl_group_override(conn, sbuf.st_gid, fsp->fsp_name)) { 3505 DEBUG(5,("set_nt_acl: acl group control on and " 3506 "current user in file %s primary group. Override delete_def_acl\n", 3507 fsp->fsp_name )); 3508 3509 become_root(); 3510 sret = SMB_VFS_SYS_ACL_DELETE_DEF_FILE(conn, fsp->fsp_name); 3511 unbecome_root(); 3512 } 3513 3514 if (sret == -1) { 3515 DEBUG(3,("set_nt_acl: sys_acl_delete_def_file failed (%s)\n", strerror(errno))); 3486 3516 free_canon_ace_list(file_ace_list); 3487 free_canon_ace_list(dir_ace_list); 3517 free_canon_ace_list(dir_ace_list); 3488 3518 return False; 3489 3519 } 3490 3520 } 3491 3492 if (acl_perms && acl_set_support && fsp->is_directory) { 3493 if (dir_ace_list) { 3494 if (!set_canon_ace_list(fsp, dir_ace_list, True, sbuf.st_gid, &acl_set_support)) { 3495 DEBUG(3,("set_nt_acl: failed to set default acl on directory %s (%s).\n", fsp->fsp_name, strerror(errno) )); 3496 free_canon_ace_list(file_ace_list); 3497 free_canon_ace_list(dir_ace_list); 3498 return False; 3499 } 3500 } else { 3501 3502 /* 3503 * No default ACL - delete one if it exists. 3504 */ 3505 3506 if (SMB_VFS_SYS_ACL_DELETE_DEF_FILE(conn, fsp->fsp_name) == -1) { 3507 int sret = -1; 3508 3509 if (acl_group_override(conn, sbuf.st_gid, fsp->fsp_name)) { 3510 DEBUG(5,("set_nt_acl: acl group control on and " 3511 "current user in file %s primary group. Override delete_def_acl\n", 3512 fsp->fsp_name )); 3513 3514 become_root(); 3515 sret = SMB_VFS_SYS_ACL_DELETE_DEF_FILE(conn, fsp->fsp_name); 3516 unbecome_root(); 3517 } 3518 3519 if (sret == -1) { 3520 DEBUG(3,("set_nt_acl: sys_acl_delete_def_file failed (%s)\n", strerror(errno))); 3521 free_canon_ace_list(file_ace_list); 3522 free_canon_ace_list(dir_ace_list); 3523 return False; 3524 } 3525 } 3521 } 3522 } 3523 3524 if (acl_set_support) { 3525 if (set_acl_as_root) { 3526 become_root(); 3527 } 3528 store_inheritance_attributes(fsp, file_ace_list, dir_ace_list, 3529 (psd->type & SE_DESC_DACL_PROTECTED) ? True : False); 3530 if (set_acl_as_root) { 3531 unbecome_root(); 3532 } 3533 } 3534 3535 /* 3536 * If we cannot set using POSIX ACLs we fall back to checking if we need to chmod. 3537 */ 3538 3539 if(!acl_set_support && acl_perms) { 3540 mode_t posix_perms; 3541 3542 if (!convert_canon_ace_to_posix_perms( fsp, file_ace_list, &posix_perms)) { 3543 free_canon_ace_list(file_ace_list); 3544 free_canon_ace_list(dir_ace_list); 3545 DEBUG(3,("set_nt_acl: failed to convert file acl to posix permissions for file %s.\n", 3546 fsp->fsp_name )); 3547 return False; 3548 } 3549 3550 if (orig_mode != posix_perms) { 3551 int sret = -1; 3552 3553 DEBUG(3,("set_nt_acl: chmod %s. perms = 0%o.\n", 3554 fsp->fsp_name, (unsigned int)posix_perms )); 3555 3556 if (set_acl_as_root) { 3557 become_root(); 3558 } 3559 sret = SMB_VFS_CHMOD(conn,fsp->fsp_name, posix_perms); 3560 if (set_acl_as_root) { 3561 unbecome_root(); 3562 } 3563 if(sret == -1) { 3564 if (acl_group_override(conn, sbuf.st_gid, fsp->fsp_name)) { 3565 DEBUG(5,("set_nt_acl: acl group control on and " 3566 "current user in file %s primary group. Override chmod\n", 3567 fsp->fsp_name )); 3568 3569 become_root(); 3570 sret = SMB_VFS_CHMOD(conn,fsp->fsp_name, posix_perms); 3571 unbecome_root(); 3526 3572 } 3527 } 3528 3529 if (acl_set_support) { 3530 store_inheritance_attributes(fsp, file_ace_list, dir_ace_list, 3531 (psd->type & SE_DESC_DACL_PROTECTED) ? True : False); 3532 } 3533 3534 /* 3535 * If we cannot set using POSIX ACLs we fall back to checking if we need to chmod. 3536 */ 3537 3538 if(!acl_set_support && acl_perms) { 3539 mode_t posix_perms; 3540 3541 if (!convert_canon_ace_to_posix_perms( fsp, file_ace_list, &posix_perms)) { 3573 3574 if (sret == -1) { 3575 DEBUG(3,("set_nt_acl: chmod %s, 0%o failed. Error = %s.\n", 3576 fsp->fsp_name, (unsigned int)posix_perms, strerror(errno) )); 3542 3577 free_canon_ace_list(file_ace_list); 3543 3578 free_canon_ace_list(dir_ace_list); 3544 DEBUG(3,("set_nt_acl: failed to convert file acl to posix permissions for file %s.\n",3545 fsp->fsp_name ));3546 3579 return False; 3547 3580 } 3548 3549 if (orig_mode != posix_perms) { 3550 3551 DEBUG(3,("set_nt_acl: chmod %s. perms = 0%o.\n", 3552 fsp->fsp_name, (unsigned int)posix_perms )); 3553 3554 if(SMB_VFS_CHMOD(conn,fsp->fsp_name, posix_perms) == -1) { 3555 int sret = -1; 3556 if (acl_group_override(conn, sbuf.st_gid, fsp->fsp_name)) { 3557 DEBUG(5,("set_nt_acl: acl group control on and " 3558 "current user in file %s primary group. Override chmod\n", 3559 fsp->fsp_name )); 3560 3561 become_root(); 3562 sret = SMB_VFS_CHMOD(conn,fsp->fsp_name, posix_perms); 3563 unbecome_root(); 3564 } 3565 3566 if (sret == -1) { 3567 DEBUG(3,("set_nt_acl: chmod %s, 0%o failed. Error = %s.\n", 3568 fsp->fsp_name, (unsigned int)posix_perms, strerror(errno) )); 3569 free_canon_ace_list(file_ace_list); 3570 free_canon_ace_list(dir_ace_list); 3571 return False; 3572 } 3573 } 3574 } 3575 } 3576 } 3577 3578 free_canon_ace_list(file_ace_list); 3579 free_canon_ace_list(dir_ace_list); 3580 } 3581 3582 /* Any chown pending? */ 3583 if (need_chown) { 3584 3585 DEBUG(3,("set_nt_acl: chown %s. uid = %u, gid = %u.\n", 3586 fsp->fsp_name, (unsigned int)user, (unsigned int)grp )); 3587 3588 if(try_chown( fsp->conn, fsp->fsp_name, user, grp) == -1) { 3589 DEBUG(3,("set_nt_acl: chown %s, %u, %u failed. Error = %s.\n", 3590 fsp->fsp_name, (unsigned int)user, (unsigned int)grp, strerror(errno) )); 3591 return False; 3592 } 3593 } 3594 3581 } 3582 } 3583 } 3584 3585 free_canon_ace_list(file_ace_list); 3586 free_canon_ace_list(dir_ace_list); 3595 3587 return True; 3596 3588 } … … 3969 3961 SMB_ACL_T def_acl = NULL; 3970 3962 3971 if (num_def_acls && !S_ISDIR(psbuf->st_mode)) { 3972 DEBUG(5,("set_unix_posix_default_acl: Can't set default ACL on non-directory file %s\n", fname )); 3973 errno = EISDIR; 3974 return False; 3963 if (!S_ISDIR(psbuf->st_mode)) { 3964 if (num_def_acls) { 3965 DEBUG(5,("set_unix_posix_default_acl: Can't set default ACL on non-directory file %s\n", fname )); 3966 errno = EISDIR; 3967 return false; 3968 } else { 3969 return true; 3970 } 3975 3971 } 3976 3972
Note:
See TracChangeset
for help on using the changeset viewer.