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>
NEX-15035 Allow user ACE in ACL to match SID in token extra SIDs (cleanup)
Reviewed by: Yuri Pankov <yuri.pankov@nexenta.com>
Reviewed by: Roman Strashkin <roman.strashkin@nexenta.com>
NEX-15035 Allow user ACE in ACL to match SID in token extra SIDs (cleanup)
Reviewed by: Yuri Pankov <yuri.pankov@nexenta.com>
Reviewed by: Roman Strashkin <roman.strashkin@nexenta.com>
NEX-15035 Allow user ACE in ACL to match SID in token extra SIDs (part 2)
Reviewed by: Evan Layton <evan.layton@nexenta.com>
Reviewed by: Sanjay Nadkarni <sanjay.nadkarni@nexenta.com>
NEX-15035 Allow user ACE in ACL to match SID in token extra SIDs (part 2)
Reviewed by: Evan Layton <evan.layton@nexenta.com>
Reviewed by: Sanjay Nadkarni <sanjay.nadkarni@nexenta.com>
NEX-15035 Allow user ACE in ACL to match SID in token extra SIDs
Reviewed by: Roman Strashkin <roman.strashkin@nexenta.com>
Reviewed by: Sanjay Nadkarni <sanjay.nadkarni@nexenta.com>
NEX-15035 Allow user ACE in ACL to match SID in token extra SIDs
Reviewed by: Roman Strashkin <roman.strashkin@nexenta.com>
Reviewed by: Sanjay Nadkarni <sanjay.nadkarni@nexenta.com>
NEX-10069 ZFS_READONLY is a little too strict
Reviewed by: Sanjay Nadkarni <sanjay.nadkarni@nexenta.com>
Reviewed by: Yuri Pankov <yuri.pankov@nexenta.com>
OS-158 zfs_zaccess_delete() comments do not accurately reflect delete permissions for ACLs
OS-40 zfs issues with inheritance flags during chmod(2) with aclmode=passthrough
OS-139 POSIX write should imply DELETE_CHILD on directories - and some additional considerations (fix lint)
OS-123 aclinherit=restricted masks inherited permissions by group perms (groupmask)
OS-139 POSIX write should imply DELETE_CHILD on directories - and some additional considerations
Fixup merge results
re #12585 rb4049 ZFS++ work port - refactoring to improve separation of open/closed code, bug fixes, performance improvements - open code
re #6815 rb1758 need WORM in nza-kernel (4.0)

Split Close
Expand all
Collapse all
          --- old/usr/src/uts/common/fs/zfs/zfs_acl.c
          +++ new/usr/src/uts/common/fs/zfs/zfs_acl.c
↓ open down ↓ 13 lines elided ↑ open up ↑
  14   14   * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
  15   15   * If applicable, add the following below this CDDL HEADER, with the
  16   16   * fields enclosed by brackets "[]" replaced with your own identifying
  17   17   * information: Portions Copyright [yyyy] [name of copyright owner]
  18   18   *
  19   19   * CDDL HEADER END
  20   20   */
  21   21  /*
  22   22   * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
  23   23   * Copyright (c) 2013 by Delphix. All rights reserved.
  24      - * Copyright 2017 Nexenta Systems, Inc.  All rights reserved.
       24 + * Copyright 2018 Nexenta Systems, Inc.  All rights reserved.
  25   25   */
  26   26  
  27   27  #include <sys/types.h>
  28   28  #include <sys/param.h>
  29   29  #include <sys/time.h>
  30   30  #include <sys/systm.h>
  31   31  #include <sys/sysmacros.h>
  32   32  #include <sys/resource.h>
  33   33  #include <sys/vfs.h>
  34   34  #include <sys/vnode.h>
↓ open down ↓ 12 lines elided ↑ open up ↑
  47   47  #include <sys/zfs_fuid.h>
  48   48  #include <sys/zfs_acl.h>
  49   49  #include <sys/zfs_dir.h>
  50   50  #include <sys/zfs_vfsops.h>
  51   51  #include <sys/dmu.h>
  52   52  #include <sys/dnode.h>
  53   53  #include <sys/zap.h>
  54   54  #include <sys/sa.h>
  55   55  #include "fs/fs_subr.h"
  56   56  #include <acl/acl_common.h>
       57 +#include <c2/audit.h>
       58 +#include <c2/audit_kernel.h>
  57   59  
  58   60  #define ALLOW   ACE_ACCESS_ALLOWED_ACE_TYPE
  59   61  #define DENY    ACE_ACCESS_DENIED_ACE_TYPE
  60   62  #define MAX_ACE_TYPE    ACE_SYSTEM_ALARM_CALLBACK_OBJECT_ACE_TYPE
  61   63  #define MIN_ACE_TYPE    ALLOW
  62   64  
  63   65  #define OWNING_GROUP            (ACE_GROUP|ACE_IDENTIFIER_GROUP)
  64   66  #define EVERYONE_ALLOW_MASK (ACE_READ_ACL|ACE_READ_ATTRIBUTES | \
  65   67      ACE_READ_NAMED_ATTRS|ACE_SYNCHRONIZE)
  66   68  #define EVERYONE_DENY_MASK (ACE_WRITE_ACL|ACE_WRITE_OWNER | \
↓ open down ↓ 1114 lines elided ↑ open up ↑
1181 1183  zfs_aclset_common(znode_t *zp, zfs_acl_t *aclp, cred_t *cr, dmu_tx_t *tx)
1182 1184  {
1183 1185          int                     error;
1184 1186          zfsvfs_t                *zfsvfs = zp->z_zfsvfs;
1185 1187          dmu_object_type_t       otype;
1186 1188          zfs_acl_locator_cb_t    locate = { 0 };
1187 1189          uint64_t                mode;
1188 1190          sa_bulk_attr_t          bulk[5];
1189 1191          uint64_t                ctime[2];
1190 1192          int                     count = 0;
1191      -        zfs_acl_phys_t          acl_phys;
1192 1193  
1193 1194          mode = zp->z_mode;
1194 1195  
1195 1196          mode = zfs_mode_compute(mode, aclp, &zp->z_pflags,
1196 1197              zp->z_uid, zp->z_gid);
1197 1198  
1198 1199          zp->z_mode = mode;
1199 1200          SA_ADD_BULK_ATTR(bulk, count, SA_ZPL_MODE(zfsvfs), NULL,
1200 1201              &mode, sizeof (mode));
1201 1202          SA_ADD_BULK_ATTR(bulk, count, SA_ZPL_FLAGS(zfsvfs), NULL,
↓ open down ↓ 26 lines elided ↑ open up ↑
1228 1229  
1229 1230          if (zp->z_is_sa) { /* the easy case, just update the ACL attribute */
1230 1231                  locate.cb_aclp = aclp;
1231 1232                  SA_ADD_BULK_ATTR(bulk, count, SA_ZPL_DACL_ACES(zfsvfs),
1232 1233                      zfs_acl_data_locator, &locate, aclp->z_acl_bytes);
1233 1234                  SA_ADD_BULK_ATTR(bulk, count, SA_ZPL_DACL_COUNT(zfsvfs),
1234 1235                      NULL, &aclp->z_acl_count, sizeof (uint64_t));
1235 1236          } else { /* Painful legacy way */
1236 1237                  zfs_acl_node_t *aclnode;
1237 1238                  uint64_t off = 0;
     1239 +                zfs_acl_phys_t acl_phys;
1238 1240                  uint64_t aoid;
1239 1241  
1240 1242                  if ((error = sa_lookup(zp->z_sa_hdl, SA_ZPL_ZNODE_ACL(zfsvfs),
1241 1243                      &acl_phys, sizeof (acl_phys))) != 0)
1242 1244                          return (error);
1243 1245  
1244 1246                  aoid = acl_phys.z_acl_extern_obj;
1245 1247  
1246 1248                  if (aclp->z_acl_bytes > ZFS_ACE_SPACE) {
1247 1249                          /*
↓ open down ↓ 82 lines elided ↑ open up ↑
1330 1332  }
1331 1333  
1332 1334  static void
1333 1335  zfs_acl_chmod(vtype_t vtype, uint64_t mode, boolean_t split, boolean_t trim,
1334 1336      zfs_acl_t *aclp)
1335 1337  {
1336 1338          void            *acep = NULL;
1337 1339          uint64_t        who;
1338 1340          int             new_count, new_bytes;
1339 1341          int             ace_size;
1340      -        int             entry_type;
     1342 +        int             entry_type;
1341 1343          uint16_t        iflags, type;
1342 1344          uint32_t        access_mask;
1343 1345          zfs_acl_node_t  *newnode;
1344      -        size_t          abstract_size = aclp->z_ops.ace_abstract_size();
1345      -        void            *zacep;
     1346 +        size_t          abstract_size = aclp->z_ops.ace_abstract_size();
     1347 +        void            *zacep;
1346 1348          boolean_t       isdir;
1347 1349          trivial_acl_t   masks;
1348 1350  
1349 1351          new_count = new_bytes = 0;
1350 1352  
1351 1353          isdir = (vtype == VDIR);
1352 1354  
1353 1355          acl_trivial_access_masks((mode_t)mode, isdir, &masks);
1354 1356  
1355 1357          newnode = zfs_acl_node_alloc((abstract_size * 6) + aclp->z_acl_bytes);
↓ open down ↓ 720 lines elided ↑ open up ↑
2076 2078   *
2077 2079   * A secondary usage of the function is to determine if any of the
2078 2080   * AoI are granted.  If an ACE grants any access in
2079 2081   * the working_mode, we immediately short circuit out of the function.
2080 2082   * This mode is chosen by setting anyaccess to B_TRUE.  The
2081 2083   * working_mode is not a denied access mask upon exit if the function
2082 2084   * is used in this manner.
2083 2085   */
2084 2086  static int
2085 2087  zfs_zaccess_aces_check(znode_t *zp, uint32_t *working_mode,
2086      -    boolean_t anyaccess, cred_t *cr)
     2088 +    boolean_t anyaccess, cred_t *cr, boolean_t audit)
2087 2089  {
2088 2090          zfsvfs_t        *zfsvfs = zp->z_zfsvfs;
2089 2091          zfs_acl_t       *aclp;
2090 2092          int             error;
2091      -        uid_t           uid = crgetuid(cr);
2092      -        uint64_t        who;
     2093 +        uint64_t        who;            /* FUID from the ACE */
2093 2094          uint16_t        type, iflags;
2094 2095          uint16_t        entry_type;
2095 2096          uint32_t        access_mask;
2096 2097          uint32_t        deny_mask = 0;
     2098 +        uint32_t        sys_smask = 0;
     2099 +        uint32_t        sys_fmask = 0;
2097 2100          zfs_ace_hdr_t   *acep = NULL;
2098      -        boolean_t       checkit;
2099      -        uid_t           gowner;
2100      -        uid_t           fowner;
     2101 +        boolean_t       checkit;        /* ACE ID matches */
     2102 +        t_audit_data_t *tad;
2101 2103  
2102      -        zfs_fuid_map_ids(zp, cr, &fowner, &gowner);
2103      -
2104 2104          mutex_enter(&zp->z_acl_lock);
2105 2105  
2106 2106          error = zfs_acl_node_read(zp, B_FALSE, &aclp, B_FALSE);
2107 2107          if (error != 0) {
2108 2108                  mutex_exit(&zp->z_acl_lock);
2109 2109                  return (error);
2110 2110          }
2111 2111  
2112 2112          ASSERT(zp->z_acl_cached);
2113 2113  
↓ open down ↓ 2 lines elided ↑ open up ↑
2116 2116                  uint32_t mask_matched;
2117 2117  
2118 2118                  if (!zfs_acl_valid_ace_type(type, iflags))
2119 2119                          continue;
2120 2120  
2121 2121                  if (ZTOV(zp)->v_type == VDIR && (iflags & ACE_INHERIT_ONLY_ACE))
2122 2122                          continue;
2123 2123  
2124 2124                  /* Skip ACE if it does not affect any AoI */
2125 2125                  mask_matched = (access_mask & *working_mode);
2126      -                if (!mask_matched)
     2126 +                if ((type == DENY || type == ALLOW) && !mask_matched)
2127 2127                          continue;
     2128 +                if (!audit && type != DENY && type != ALLOW)
     2129 +                        continue;
2128 2130  
2129 2131                  entry_type = (iflags & ACE_TYPE_FLAGS);
2130 2132  
2131 2133                  checkit = B_FALSE;
2132 2134  
2133 2135                  switch (entry_type) {
2134 2136                  case ACE_OWNER:
2135      -                        if (uid == fowner)
2136      -                                checkit = B_TRUE;
     2137 +                        who = zp->z_uid;
     2138 +                        /*FALLTHROUGH*/
     2139 +                case 0: /* USER Entry */
     2140 +                        checkit = zfs_user_in_cred(zfsvfs, who, cr);
2137 2141                          break;
2138 2142                  case OWNING_GROUP:
2139      -                        who = gowner;
     2143 +                        who = zp->z_gid;
2140 2144                          /*FALLTHROUGH*/
2141 2145                  case ACE_IDENTIFIER_GROUP:
2142 2146                          checkit = zfs_groupmember(zfsvfs, who, cr);
2143 2147                          break;
2144 2148                  case ACE_EVERYONE:
2145 2149                          checkit = B_TRUE;
2146 2150                          break;
2147 2151  
2148      -                /* USER Entry */
2149 2152                  default:
2150      -                        if (entry_type == 0) {
2151      -                                uid_t newid;
2152      -
2153      -                                newid = zfs_fuid_map_id(zfsvfs, who, cr,
2154      -                                    ZFS_ACE_USER);
2155      -                                if (newid != IDMAP_WK_CREATOR_OWNER_UID &&
2156      -                                    uid == newid)
2157      -                                        checkit = B_TRUE;
2158      -                                break;
2159      -                        } else {
2160      -                                mutex_exit(&zp->z_acl_lock);
2161      -                                return (SET_ERROR(EIO));
2162      -                        }
     2153 +                        /*
     2154 +                         * The zfs_acl_valid_ace_type check above
     2155 +                         * should make this case impossible.
     2156 +                         */
     2157 +                        mutex_exit(&zp->z_acl_lock);
     2158 +                        return (SET_ERROR(EIO));
2163 2159                  }
2164 2160  
2165 2161                  if (checkit) {
2166      -                        if (type == DENY) {
     2162 +                        switch (type) {
     2163 +                        case DENY:
2167 2164                                  DTRACE_PROBE3(zfs__ace__denies,
2168 2165                                      znode_t *, zp,
2169 2166                                      zfs_ace_hdr_t *, acep,
2170 2167                                      uint32_t, mask_matched);
2171 2168                                  deny_mask |= mask_matched;
2172      -                        } else {
     2169 +                                *working_mode &= ~mask_matched;
     2170 +                                break;
     2171 +                        case ACE_SYSTEM_AUDIT_ACE_TYPE:
     2172 +                        case ACE_SYSTEM_ALARM_ACE_TYPE:
     2173 +                                DTRACE_PROBE3(zfs__ace__audit,
     2174 +                                    znode_t *, zp,
     2175 +                                    zfs_ace_hdr_t *, acep,
     2176 +                                    uint32_t, access_mask);
     2177 +                                if ((iflags &
     2178 +                                    ACE_SUCCESSFUL_ACCESS_ACE_FLAG) != 0)
     2179 +                                        sys_smask |= access_mask;
     2180 +                                if ((iflags & ACE_FAILED_ACCESS_ACE_FLAG) != 0)
     2181 +                                        sys_fmask |= access_mask;
     2182 +                                break;
     2183 +                        case ALLOW:
     2184 +                        default:
2173 2185                                  DTRACE_PROBE3(zfs__ace__allows,
2174 2186                                      znode_t *, zp,
2175 2187                                      zfs_ace_hdr_t *, acep,
2176 2188                                      uint32_t, mask_matched);
2177 2189                                  if (anyaccess) {
2178 2190                                          mutex_exit(&zp->z_acl_lock);
2179 2191                                          return (0);
2180 2192                                  }
     2193 +                                *working_mode &= ~mask_matched;
     2194 +                                break;
2181 2195                          }
2182      -                        *working_mode &= ~mask_matched;
2183 2196                  }
2184 2197  
2185      -                /* Are we done? */
2186      -                if (*working_mode == 0)
     2198 +                /*
     2199 +                 * Are we done? If auditing, process the entire list
     2200 +                 * to gather all audit ACEs
     2201 +                 */
     2202 +                if (!audit && *working_mode == 0)
2187 2203                          break;
2188 2204          }
2189 2205  
2190 2206          mutex_exit(&zp->z_acl_lock);
2191 2207  
     2208 +        if (audit) {
     2209 +                tad = T2A(curthread);
     2210 +                tad->tad_sacl_mask.tas_smask = sys_smask;
     2211 +                tad->tad_sacl_mask.tas_fmask = sys_fmask;
     2212 +        }
     2213 +
2192 2214          /* Put the found 'denies' back on the working mode */
2193 2215          if (deny_mask) {
2194 2216                  *working_mode |= deny_mask;
2195 2217                  return (SET_ERROR(EACCES));
2196 2218          } else if (*working_mode) {
2197 2219                  return (-1);
2198 2220          }
2199 2221  
2200 2222          return (0);
2201 2223  }
2202 2224  
2203 2225  /*
2204 2226   * Return true if any access whatsoever granted, we don't actually
2205 2227   * care what access is granted.
2206 2228   */
2207 2229  boolean_t
2208 2230  zfs_has_access(znode_t *zp, cred_t *cr)
2209 2231  {
2210 2232          uint32_t have = ACE_ALL_PERMS;
2211 2233  
2212      -        if (zfs_zaccess_aces_check(zp, &have, B_TRUE, cr) != 0) {
     2234 +        if (zfs_zaccess_aces_check(zp, &have, B_TRUE, cr, B_FALSE) != 0) {
2213 2235                  uid_t owner;
2214 2236  
2215 2237                  owner = zfs_fuid_map_id(zp->z_zfsvfs, zp->z_uid, cr, ZFS_OWNER);
2216 2238                  return (secpolicy_vnode_any_access(cr, ZTOV(zp), owner) == 0);
2217 2239          }
2218 2240          return (B_TRUE);
2219 2241  }
2220 2242  
2221 2243  static int
2222 2244  zfs_zaccess_common(znode_t *zp, uint32_t v4_mode, uint32_t *working_mode,
2223 2245      boolean_t *check_privs, boolean_t skipaclchk, cred_t *cr)
2224 2246  {
2225 2247          zfsvfs_t *zfsvfs = zp->z_zfsvfs;
2226 2248          int err;
     2249 +        boolean_t audit = B_FALSE;
2227 2250  
2228 2251          *working_mode = v4_mode;
2229 2252          *check_privs = B_TRUE;
2230 2253  
2231 2254          /*
2232 2255           * Short circuit empty requests
2233 2256           */
2234 2257          if (v4_mode == 0 || zfsvfs->z_replay) {
2235 2258                  *working_mode = 0;
2236 2259                  return (0);
↓ open down ↓ 25 lines elided ↑ open up ↑
2262 2285           * Therefore ZFS_READONLY is ignored in the dataset check
2263 2286           * above, and checked here as if part of the ACL check.
2264 2287           * Also note: DOS R/O is ignored for directories.
2265 2288           */
2266 2289          if ((v4_mode & WRITE_MASK_DATA) &&
2267 2290              (ZTOV(zp)->v_type != VDIR) &&
2268 2291              (zp->z_pflags & ZFS_READONLY)) {
2269 2292                  return (SET_ERROR(EPERM));
2270 2293          }
2271 2294  
2272      -        return (zfs_zaccess_aces_check(zp, working_mode, B_FALSE, cr));
     2295 +        if (cr != zone_kcred() && AU_ZONE_AUDITING(NULL)) {
     2296 +                t_audit_data_t *tad = T2A(curthread);
     2297 +                if (tad->tad_sacl_ctrl != SACL_AUDIT_NONE &&
     2298 +                    auditev(AUE_SACL, cr) != 0) {
     2299 +                        audit = B_TRUE;
     2300 +                        tad->tad_sacl_ctrl = SACL_AUDIT_NONE;
     2301 +                }
     2302 +        }
     2303 +
     2304 +        return (zfs_zaccess_aces_check(zp, working_mode, B_FALSE, cr, audit));
2273 2305  }
2274 2306  
2275 2307  static int
2276 2308  zfs_zaccess_append(znode_t *zp, uint32_t *working_mode, boolean_t *check_privs,
2277 2309      cred_t *cr)
2278 2310  {
2279 2311          if (*working_mode != ACE_WRITE_DATA)
2280 2312                  return (SET_ERROR(EACCES));
2281 2313  
2282 2314          return (zfs_zaccess_common(zp, ACE_APPEND_DATA, working_mode,
↓ open down ↓ 152 lines elided ↑ open up ↑
2435 2467                      needed_bits, needed_bits));
2436 2468          }
2437 2469  
2438 2470          if (error && !check_privs) {
2439 2471                  if (is_attr)
2440 2472                          VN_RELE(ZTOV(xzp));
2441 2473                  return (error);
2442 2474          }
2443 2475  
2444 2476          if (error && (flags & V_APPEND)) {
     2477 +                /*
     2478 +                 * If zfs_zaccess_common checked aces, then we won't audit here.
     2479 +                 * Otherwise, we'll try and get audit masks here.
     2480 +                 */
2445 2481                  error = zfs_zaccess_append(zp, &working_mode, &check_privs, cr);
2446 2482          }
2447 2483  
2448 2484          if (error && check_privs) {
2449 2485                  mode_t          checkmode = 0;
2450 2486  
2451 2487                  /*
2452 2488                   * First check for implicit owner permission on
2453 2489                   * read_acl/read_attributes
2454 2490                   */
↓ open down ↓ 146 lines elided ↑ open up ↑
2601 2637   */
2602 2638  int
2603 2639  zfs_zaccess_delete(znode_t *dzp, znode_t *zp, cred_t *cr)
2604 2640  {
2605 2641          uint32_t wanted_dirperms;
2606 2642          uint32_t dzp_working_mode = 0;
2607 2643          uint32_t zp_working_mode = 0;
2608 2644          int dzp_error, zp_error;
2609 2645          boolean_t dzpcheck_privs;
2610 2646          boolean_t zpcheck_privs;
     2647 +        t_audit_data_t *tad;
2611 2648  
2612 2649          if (zp->z_pflags & (ZFS_IMMUTABLE | ZFS_NOUNLINK))
2613 2650                  return (SET_ERROR(EPERM));
2614 2651  
2615 2652          /*
2616 2653           * Case 1:
2617 2654           * If target object grants ACE_DELETE then we are done.  This is
2618 2655           * indicated by a return value of 0.  For this case we don't worry
2619 2656           * about the sticky bit because sticky only applies to the parent
2620 2657           * directory and this is the child access result.
↓ open down ↓ 20 lines elided ↑ open up ↑
2641 2678          /*
2642 2679           * Case 2:
2643 2680           * If the containing directory grants ACE_DELETE_CHILD,
2644 2681           * or we're in backward compatibility mode and the
2645 2682           * containing directory has ACE_WRITE_DATA, allow.
2646 2683           * Case 2b is handled with wanted_dirperms.
2647 2684           */
2648 2685          wanted_dirperms = ACE_DELETE_CHILD;
2649 2686          if (zfs_write_implies_delete_child)
2650 2687                  wanted_dirperms |= ACE_WRITE_DATA;
     2688 +        /* never audit the parent directory access check */
     2689 +        if (AU_ZONE_AUDITING(NULL)) {
     2690 +                tad = T2A(curthread);
     2691 +                tad->tad_sacl_ctrl = SACL_AUDIT_NONE;
     2692 +        }
2651 2693          dzp_error = zfs_zaccess_common(dzp, wanted_dirperms,
2652 2694              &dzp_working_mode, &dzpcheck_privs, B_FALSE, cr);
2653 2695          if (dzp_error == EACCES) {
2654 2696                  /* We hit a DENY ACE. */
2655 2697                  if (!dzpcheck_privs)
2656 2698                          return (SET_ERROR(dzp_error));
2657 2699                  return (secpolicy_vnode_remove(cr));
2658 2700          }
2659 2701  
2660 2702          /*
↓ open down ↓ 66 lines elided ↑ open up ↑
2727 2769           */
2728 2770          return (zfs_sticky_remove_access(dzp, zp, cr));
2729 2771  }
2730 2772  
2731 2773  int
2732 2774  zfs_zaccess_rename(znode_t *sdzp, znode_t *szp, znode_t *tdzp,
2733 2775      znode_t *tzp, cred_t *cr)
2734 2776  {
2735 2777          int add_perm;
2736 2778          int error;
     2779 +        t_audit_data_t *tad;
     2780 +        sacl_audit_ctrl_t do_audit;
2737 2781  
2738 2782          if (szp->z_pflags & ZFS_AV_QUARANTINED)
2739 2783                  return (SET_ERROR(EACCES));
2740 2784  
2741 2785          add_perm = (ZTOV(szp)->v_type == VDIR) ?
2742 2786              ACE_ADD_SUBDIRECTORY : ACE_ADD_FILE;
2743 2787  
     2788 +        if (AU_ZONE_AUDITING(NULL)) {
     2789 +                tad = T2A(curthread);
     2790 +                do_audit = tad->tad_sacl_ctrl;
     2791 +        } else {
     2792 +                tad = NULL;
     2793 +                do_audit = SACL_AUDIT_NONE;
     2794 +        }
     2795 +
2744 2796          /*
2745 2797           * Rename permissions are combination of delete permission +
2746 2798           * add file/subdir permission.
2747 2799           */
2748 2800  
2749 2801          /*
2750 2802           * first make sure we do the delete portion.
2751 2803           *
2752 2804           * If that succeeds then check for add_file/add_subdir permissions
2753 2805           */
2754 2806  
2755      -        if (error = zfs_zaccess_delete(sdzp, szp, cr))
     2807 +        if (do_audit == SACL_AUDIT_NO_SRC)
     2808 +                tad->tad_sacl_ctrl = SACL_AUDIT_NONE;
     2809 +        error = zfs_zaccess_delete(sdzp, szp, cr);
     2810 +
     2811 +        if (do_audit == SACL_AUDIT_ALL) {
     2812 +                tad->tad_sacl_mask_src = tad->tad_sacl_mask;
     2813 +                tad->tad_sacl_mask.tas_smask = 0;
     2814 +                tad->tad_sacl_mask.tas_fmask = 0;
     2815 +        }
     2816 +        if (error != 0)
2756 2817                  return (error);
2757 2818  
     2819 +        if (do_audit != SACL_AUDIT_NONE)
     2820 +                tad->tad_sacl_ctrl = do_audit;
     2821 +
2758 2822          /*
2759 2823           * If we have a tzp, see if we can delete it?
2760 2824           */
2761 2825          if (tzp) {
2762      -                if (error = zfs_zaccess_delete(tdzp, tzp, cr))
     2826 +                error = zfs_zaccess_delete(tdzp, tzp, cr);
     2827 +                if (do_audit != SACL_AUDIT_NONE) {
     2828 +                        tad->tad_sacl_mask_dest = tad->tad_sacl_mask;
     2829 +                        tad->tad_sacl_mask.tas_smask = 0;
     2830 +                        tad->tad_sacl_mask.tas_fmask = 0;
     2831 +                }
     2832 +                if (error != 0)
2763 2833                          return (error);
     2834 +                if (do_audit != SACL_AUDIT_NONE)
     2835 +                        tad->tad_sacl_ctrl = do_audit;
2764 2836          }
2765 2837  
2766 2838          /*
2767 2839           * Now check for add permissions
2768 2840           */
2769 2841          error = zfs_zaccess(tdzp, add_perm, 0, B_FALSE, cr);
2770 2842  
     2843 +        /* do_audit: leave directory audit info in sacl_mask. */
     2844 +
2771 2845          return (error);
2772 2846  }
    
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX