Print this page
NEX-13644 File access audit logging
Reviewed by: Gordon Ross <gordon.ross@nexenta.com>
Reviewed by: Roman Strashkin <roman.strashkin@nexenta.com>
Reviewed by: Saso Kiselkov <saso.kiselkov@nexenta.com>
Reviewed by: Rick McNeal <rick.mcneal@nexenta.com>
Reviewed by: Yuri Pankov <yuri.pankov@nexenta.com>


   4  * The contents of this file are subject to the terms of the
   5  * Common Development and Distribution License (the "License").
   6  * You may not use this file except in compliance with the License.
   7  *
   8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
   9  * or http://www.opensolaris.org/os/licensing.
  10  * See the License for the specific language governing permissions
  11  * and limitations under the License.
  12  *
  13  * When distributing Covered Code, include this CDDL HEADER in each
  14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
  15  * If applicable, add the following below this CDDL HEADER, with the
  16  * fields enclosed by brackets "[]" replaced with your own identifying
  17  * information: Portions Copyright [yyyy] [name of copyright owner]
  18  *
  19  * CDDL HEADER END
  20  */
  21 
  22 /*
  23  * Copyright (c) 1992, 2010, Oracle and/or its affiliates. All rights reserved.

  24  */
  25 
  26 /*
  27  * This file contains the audit hook support code for auditing.
  28  */
  29 
  30 #include <sys/types.h>
  31 #include <sys/proc.h>
  32 #include <sys/vnode.h>
  33 #include <sys/vfs.h>
  34 #include <sys/file.h>
  35 #include <sys/user.h>
  36 #include <sys/stropts.h>
  37 #include <sys/systm.h>
  38 #include <sys/pathname.h>
  39 #include <sys/syscall.h>
  40 #include <sys/fcntl.h>
  41 #include <sys/ipc_impl.h>
  42 #include <sys/msg_impl.h>
  43 #include <sys/sem_impl.h>
  44 #include <sys/shm_impl.h>
  45 #include <sys/kmem.h>             /* for KM_SLEEP */
  46 #include <sys/socket.h>
  47 #include <sys/cmn_err.h>  /* snprintf... */
  48 #include <sys/debug.h>
  49 #include <sys/thread.h>
  50 #include <netinet/in.h>
  51 #include <c2/audit.h>             /* needs to be included before user.h */
  52 #include <c2/audit_kernel.h>      /* for M_DONTWAIT */
  53 #include <c2/audit_kevents.h>
  54 #include <c2/audit_record.h>
  55 #include <sys/strsubr.h>
  56 #include <sys/tihdr.h>
  57 #include <sys/tiuser.h>
  58 #include <sys/timod.h>
  59 #include <sys/model.h>            /* for model_t */
  60 #include <sys/disp.h>             /* for servicing_interrupt() */
  61 #include <sys/devpolicy.h>
  62 #include <sys/crypto/ioctladmin.h>
  63 #include <sys/cred_impl.h>

  64 #include <inet/kssl/kssl.h>
  65 #include <net/pfpolicy.h>
  66 
  67 static void add_return_token(caddr_t *, unsigned int scid, int err, int rval);
  68 
  69 static void audit_pathbuild(struct pathname *pnp);
  70 
  71 
  72 /*
  73  * ROUTINE:     AUDIT_SAVEPATH
  74  * PURPOSE:
  75  * CALLBY:      LOOKUPPN
  76  *
  77  * NOTE:        We have reached the end of a path in fs/lookup.c.
  78  *              We get two pieces of information here:
  79  *              the vnode of the last component (vp) and
  80  *              the status of the last access (flag).
  81  * TODO:
  82  * QUESTION:
  83  */


 689         stp = vp->v_stream;
 690 
 691         /* lock stdata from audit_sock */
 692         mutex_enter(&stp->sd_lock);
 693 
 694         /* proceed ONLY if user is being audited */
 695         if (!tad->tad_flag) {
 696                 /*
 697                  * this is so we will not add audit data onto
 698                  * a thread that is not being audited.
 699                  */
 700                 stp->sd_t_audit_data = NULL;
 701                 mutex_exit(&stp->sd_lock);
 702                 return;
 703         }
 704 
 705         stp->sd_t_audit_data = (caddr_t)curthread;
 706         mutex_exit(&stp->sd_lock);
 707 }
 708 













































 709 /*
 710  * ROUTINE:     AUDIT_CLOSEF
 711  * PURPOSE:
 712  * CALLBY:      CLOSEF
 713  * NOTE:
 714  * release per file audit resources when file structure is being released.
 715  *
 716  * IMPORTANT NOTE: Since we generate an audit record here, we may sleep
 717  *      on the audit queue if it becomes full. This means
 718  *      audit_closef can not be called when f_count == 0. Since
 719  *      f_count == 0 indicates the file structure is free, another
 720  *      process could attempt to use the file while we were still
 721  *      asleep waiting on the audit queue. This would cause the
 722  *      per file audit data to be corrupted when we finally do
 723  *      wakeup.
 724  * TODO:
 725  * QUESTION:
 726  */
 727 
 728 void




   4  * The contents of this file are subject to the terms of the
   5  * Common Development and Distribution License (the "License").
   6  * You may not use this file except in compliance with the License.
   7  *
   8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
   9  * or http://www.opensolaris.org/os/licensing.
  10  * See the License for the specific language governing permissions
  11  * and limitations under the License.
  12  *
  13  * When distributing Covered Code, include this CDDL HEADER in each
  14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
  15  * If applicable, add the following below this CDDL HEADER, with the
  16  * fields enclosed by brackets "[]" replaced with your own identifying
  17  * information: Portions Copyright [yyyy] [name of copyright owner]
  18  *
  19  * CDDL HEADER END
  20  */
  21 
  22 /*
  23  * Copyright (c) 1992, 2010, Oracle and/or its affiliates. All rights reserved.
  24  * Copyright 2018 Nexenta Systems, Inc.  All rights reserved.
  25  */
  26 
  27 /*
  28  * This file contains the audit hook support code for auditing.
  29  */
  30 
  31 #include <sys/types.h>
  32 #include <sys/proc.h>
  33 #include <sys/vnode.h>
  34 #include <sys/vfs.h>
  35 #include <sys/file.h>
  36 #include <sys/user.h>
  37 #include <sys/stropts.h>
  38 #include <sys/systm.h>
  39 #include <sys/pathname.h>
  40 #include <sys/syscall.h>
  41 #include <sys/fcntl.h>
  42 #include <sys/ipc_impl.h>
  43 #include <sys/msg_impl.h>
  44 #include <sys/sem_impl.h>
  45 #include <sys/shm_impl.h>
  46 #include <sys/kmem.h>             /* for KM_SLEEP */
  47 #include <sys/socket.h>
  48 #include <sys/cmn_err.h>  /* snprintf... */
  49 #include <sys/debug.h>
  50 #include <sys/thread.h>
  51 #include <netinet/in.h>
  52 #include <c2/audit.h>             /* needs to be included before user.h */
  53 #include <c2/audit_kernel.h>      /* for M_DONTWAIT */
  54 #include <c2/audit_kevents.h>
  55 #include <c2/audit_record.h>
  56 #include <sys/strsubr.h>
  57 #include <sys/tihdr.h>
  58 #include <sys/tiuser.h>
  59 #include <sys/timod.h>
  60 #include <sys/model.h>            /* for model_t */
  61 #include <sys/disp.h>             /* for servicing_interrupt() */
  62 #include <sys/devpolicy.h>
  63 #include <sys/crypto/ioctladmin.h>
  64 #include <sys/cred_impl.h>
  65 #include <sys/sid.h>
  66 #include <inet/kssl/kssl.h>
  67 #include <net/pfpolicy.h>
  68 
  69 static void add_return_token(caddr_t *, unsigned int scid, int err, int rval);
  70 
  71 static void audit_pathbuild(struct pathname *pnp);
  72 
  73 
  74 /*
  75  * ROUTINE:     AUDIT_SAVEPATH
  76  * PURPOSE:
  77  * CALLBY:      LOOKUPPN
  78  *
  79  * NOTE:        We have reached the end of a path in fs/lookup.c.
  80  *              We get two pieces of information here:
  81  *              the vnode of the last component (vp) and
  82  *              the status of the last access (flag).
  83  * TODO:
  84  * QUESTION:
  85  */


 691         stp = vp->v_stream;
 692 
 693         /* lock stdata from audit_sock */
 694         mutex_enter(&stp->sd_lock);
 695 
 696         /* proceed ONLY if user is being audited */
 697         if (!tad->tad_flag) {
 698                 /*
 699                  * this is so we will not add audit data onto
 700                  * a thread that is not being audited.
 701                  */
 702                 stp->sd_t_audit_data = NULL;
 703                 mutex_exit(&stp->sd_lock);
 704                 return;
 705         }
 706 
 707         stp->sd_t_audit_data = (caddr_t)curthread;
 708         mutex_exit(&stp->sd_lock);
 709 }
 710 
 711 /*
 712  * ROUTINE:     AUDIT_SACL
 713  * PURPOSE:     audit ACL-based file accesses
 714  * CALLBY:      SMB, NFS
 715  * NOTE:
 716  *
 717  * IMPORTANT NOTE: Since we generate an audit record here, we may sleep
 718  *      on the audit queue if it becomes full.
 719  * TODO:
 720  * QUESTION:
 721  */
 722 void
 723 audit_sacl(char *path, cred_t *cr, uint32_t desired, boolean_t success,
 724     t_audit_sacl_t *tas)
 725 {
 726         token_t *ad = NULL;
 727         au_kcontext_t   *kctx = GET_KCTX_PZ;
 728         const auditinfo_addr_t *ainfo;
 729         ksid_t *ks;
 730 
 731         /* if auditing not enabled, then don't generate an audit record */
 732         if (((kctx->auk_auditstate) &
 733             ~(AUC_AUDITING | AUC_INIT_AUDIT | AUC_NOSPACE)) != 0)
 734                 return;
 735 
 736         if ((success && (tas->tas_smask & desired) == 0) ||
 737             (!success && (tas->tas_fmask & desired) == 0))
 738                 return;
 739 
 740         ainfo = crgetauinfo(cr);
 741         if (ainfo == NULL)
 742                 return;
 743 
 744         au_write((caddr_t *)&(ad), au_to_path_string(path));
 745         au_write((caddr_t *)&(ad), au_to_access_mask(desired));
 746 
 747         /* Include the SID if it has one, in case the id is ephemeral */
 748         if ((ks = crgetsid(cr, KSID_USER)) != NULL) {
 749                 au_write((caddr_t *)&(ad), au_to_wsid(ks));
 750         }
 751         AUDIT_SETSUBJ((caddr_t *)&(ad), cr, ainfo, kctx);
 752         au_close(kctx, (caddr_t *)&(ad), AU_OK, AUE_SACL,
 753             success ? 0 : PAD_FAILURE, NULL);
 754 }
 755 
 756 /*
 757  * ROUTINE:     AUDIT_CLOSEF
 758  * PURPOSE:
 759  * CALLBY:      CLOSEF
 760  * NOTE:
 761  * release per file audit resources when file structure is being released.
 762  *
 763  * IMPORTANT NOTE: Since we generate an audit record here, we may sleep
 764  *      on the audit queue if it becomes full. This means
 765  *      audit_closef can not be called when f_count == 0. Since
 766  *      f_count == 0 indicates the file structure is free, another
 767  *      process could attempt to use the file while we were still
 768  *      asleep waiting on the audit queue. This would cause the
 769  *      per file audit data to be corrupted when we finally do
 770  *      wakeup.
 771  * TODO:
 772  * QUESTION:
 773  */
 774 
 775 void