Deleted Added
full compact
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 83366 2001-09-12 08:38:13Z julian $
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,
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,
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,
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,
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,
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)
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, 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
619vacl_aclcheck( struct thread *td, struct vnode *vp, acl_type_t type,
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);
628 error = VOP_ACLCHECK(vp, type, &inkernelacl, td->td_proc->p_ucred, td);
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
644__acl_get_file( struct thread *td, struct __acl_get_file_args *uap)
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);
650 /* what flags are required here -- possible not LOCKLEAF? */
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
668__acl_set_file( struct thread *td, struct __acl_set_file_args *uap)
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
691__acl_get_fd( struct thread *td, struct __acl_get_fd_args *uap)
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
712__acl_set_fd( struct thread *td, struct __acl_set_fd_args *uap)
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
733__acl_delete_file( struct thread *td, struct __acl_delete_file_args *uap)
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
755__acl_delete_fd( struct thread *td, struct __acl_delete_fd_args *uap)
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
776__acl_aclcheck_file( struct thread *td, struct __acl_aclcheck_file_args *uap)
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
799__acl_aclcheck_fd( struct thread *td, struct __acl_aclcheck_fd_args *uap)
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}