1/*- 2 * Copyright (c) 1999, 2000, 2001 Robert N. M. Watson 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright --- 9 unchanged lines hidden (view full) --- 18 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 19 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 24 * SUCH DAMAGE. 25 * |
26 * $FreeBSD: head/sys/kern/subr_acl_posix1e.c 85582 2001-10-27 05:45:42Z rwatson $ |
27 */ 28/* 29 * Developed by the TrustedBSD Project. 30 * Support for POSIX.1e access control lists. 31 */ 32 33#include <sys/param.h> 34#include <sys/systm.h> --- 8 unchanged lines hidden (view full) --- 43#include <sys/proc.h> 44#include <sys/sysent.h> 45#include <sys/errno.h> 46#include <sys/stat.h> 47#include <sys/acl.h> 48 49MALLOC_DEFINE(M_ACL, "acl", "access control list"); 50 |
51static int vacl_set_acl(struct thread *td, struct vnode *vp, acl_type_t type, |
52 struct acl *aclp); |
53static int vacl_get_acl(struct thread *td, struct vnode *vp, acl_type_t type, |
54 struct acl *aclp); |
55static int vacl_aclcheck(struct thread *td, struct vnode *vp, |
56 acl_type_t type, struct acl *aclp); 57 58/* 59 * Implement a version of vaccess() that understands POSIX.1e ACL semantics. 60 * Return 0 on success, else an errno value. Should be merged into 61 * vaccess() eventually. 62 */ 63int --- 493 unchanged lines hidden (view full) --- 557 * the kernel except by syscall code. Other code should directly 558 * invoke VOP_{SET,GET}ACL. 559 */ 560 561/* 562 * Given a vnode, set its ACL. 563 */ 564static int |
565vacl_set_acl(struct thread *td, struct vnode *vp, acl_type_t type, |
566 struct acl *aclp) 567{ 568 struct acl inkernacl; 569 int error; 570 571 error = copyin(aclp, &inkernacl, sizeof(struct acl)); 572 if (error) 573 return(error); 574 VOP_LEASE(vp, td, td->td_proc->p_ucred, LEASE_WRITE); 575 vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, td); 576 error = VOP_SETACL(vp, type, &inkernacl, td->td_proc->p_ucred, td); 577 VOP_UNLOCK(vp, 0, td); 578 return(error); 579} 580 581/* 582 * Given a vnode, get its ACL. 583 */ 584static int |
585vacl_get_acl(struct thread *td, struct vnode *vp, acl_type_t type, |
586 struct acl *aclp) 587{ 588 struct acl inkernelacl; 589 int error; 590 591 VOP_LEASE(vp, td, td->td_proc->p_ucred, LEASE_WRITE); 592 vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, td); 593 error = VOP_GETACL(vp, type, &inkernelacl, td->td_proc->p_ucred, td); 594 VOP_UNLOCK(vp, 0, td); 595 if (error == 0) 596 error = copyout(&inkernelacl, aclp, sizeof(struct acl)); 597 return (error); 598} 599 600/* 601 * Given a vnode, delete its ACL. 602 */ 603static int |
604vacl_delete(struct thread *td, struct vnode *vp, acl_type_t type) |
605{ 606 int error; 607 608 VOP_LEASE(vp, td, td->td_proc->p_ucred, LEASE_WRITE); 609 vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, td); |
610 error = VOP_SETACL(vp, ACL_TYPE_DEFAULT, 0, td->td_proc->p_ucred, 611 td); |
612 VOP_UNLOCK(vp, 0, td); 613 return (error); 614} 615 616/* 617 * Given a vnode, check whether an ACL is appropriate for it 618 */ 619static int |
620vacl_aclcheck(struct thread *td, struct vnode *vp, acl_type_t type, |
621 struct acl *aclp) 622{ 623 struct acl inkernelacl; 624 int error; 625 626 error = copyin(aclp, &inkernelacl, sizeof(struct acl)); 627 if (error) 628 return(error); |
629 error = VOP_ACLCHECK(vp, type, &inkernelacl, td->td_proc->p_ucred, 630 td); |
631 return (error); 632} 633 634/* 635 * syscalls -- convert the path/fd to a vnode, and call vacl_whatever. 636 * Don't need to lock, as the vacl_ code will get/release any locks 637 * required. 638 */ 639 640/* 641 * Given a file path, get an ACL for it 642 * 643 * MPSAFE 644 */ 645int |
646__acl_get_file(struct thread *td, struct __acl_get_file_args *uap) |
647{ 648 struct nameidata nd; 649 int error; 650 651 mtx_lock(&Giant); |
652 NDINIT(&nd, LOOKUP, FOLLOW, UIO_USERSPACE, SCARG(uap, path), td); 653 error = namei(&nd); 654 if (error == 0) { 655 error = vacl_get_acl(td, nd.ni_vp, SCARG(uap, type), 656 SCARG(uap, aclp)); 657 NDFREE(&nd, 0); 658 } 659 mtx_unlock(&Giant); 660 return (error); 661} 662 663/* 664 * Given a file path, set an ACL for it 665 * 666 * MPSAFE 667 */ 668int |
669__acl_set_file(struct thread *td, struct __acl_set_file_args *uap) |
670{ 671 struct nameidata nd; 672 int error; 673 674 mtx_lock(&Giant); 675 NDINIT(&nd, LOOKUP, FOLLOW, UIO_USERSPACE, SCARG(uap, path), td); 676 error = namei(&nd); 677 if (error == 0) { --- 6 unchanged lines hidden (view full) --- 684} 685 686/* 687 * Given a file descriptor, get an ACL for it 688 * 689 * MPSAFE 690 */ 691int |
692__acl_get_fd(struct thread *td, struct __acl_get_fd_args *uap) |
693{ 694 struct file *fp; 695 int error; 696 697 mtx_lock(&Giant); 698 error = getvnode(td->td_proc->p_fd, SCARG(uap, filedes), &fp); 699 if (error == 0) { 700 error = vacl_get_acl(td, (struct vnode *)fp->f_data, --- 4 unchanged lines hidden (view full) --- 705} 706 707/* 708 * Given a file descriptor, set an ACL for it 709 * 710 * MPSAFE 711 */ 712int |
713__acl_set_fd(struct thread *td, struct __acl_set_fd_args *uap) |
714{ 715 struct file *fp; 716 int error; 717 718 mtx_lock(&Giant); 719 error = getvnode(td->td_proc->p_fd, SCARG(uap, filedes), &fp); 720 if (error == 0) { 721 error = vacl_set_acl(td, (struct vnode *)fp->f_data, --- 4 unchanged lines hidden (view full) --- 726} 727 728/* 729 * Given a file path, delete an ACL from it. 730 * 731 * MPSAFE 732 */ 733int |
734__acl_delete_file(struct thread *td, struct __acl_delete_file_args *uap) |
735{ 736 struct nameidata nd; 737 int error; 738 739 mtx_lock(&Giant); 740 NDINIT(&nd, LOOKUP, FOLLOW, UIO_USERSPACE, SCARG(uap, path), td); 741 error = namei(&nd); 742 if (error == 0) { --- 5 unchanged lines hidden (view full) --- 748} 749 750/* 751 * Given a file path, delete an ACL from it. 752 * 753 * MPSAFE 754 */ 755int |
756__acl_delete_fd(struct thread *td, struct __acl_delete_fd_args *uap) |
757{ 758 struct file *fp; 759 int error; 760 761 mtx_lock(&Giant); 762 error = getvnode(td->td_proc->p_fd, SCARG(uap, filedes), &fp); 763 if (error == 0) { 764 error = vacl_delete(td, (struct vnode *)fp->f_data, --- 4 unchanged lines hidden (view full) --- 769} 770 771/* 772 * Given a file path, check an ACL for it 773 * 774 * MPSAFE 775 */ 776int |
777__acl_aclcheck_file(struct thread *td, struct __acl_aclcheck_file_args *uap) |
778{ 779 struct nameidata nd; 780 int error; 781 782 mtx_lock(&Giant); 783 NDINIT(&nd, LOOKUP, FOLLOW, UIO_USERSPACE, SCARG(uap, path), td); 784 error = namei(&nd); 785 if (error == 0) { --- 6 unchanged lines hidden (view full) --- 792} 793 794/* 795 * Given a file descriptor, check an ACL for it 796 * 797 * MPSAFE 798 */ 799int |
800__acl_aclcheck_fd(struct thread *td, struct __acl_aclcheck_fd_args *uap) |
801{ 802 struct file *fp; 803 int error; 804 805 mtx_lock(&Giant); 806 error = getvnode(td->td_proc->p_fd, SCARG(uap, filedes), &fp); 807 if (error == 0) { 808 error = vacl_aclcheck(td, (struct vnode *)fp->f_data, 809 SCARG(uap, type), SCARG(uap, aclp)); 810 } 811 mtx_unlock(&Giant); 812 return (error); 813} |