Print this page
    
NEX-16818 Add fksmbcl development tool
NEX-17264 SMB client test tp_smbutil_013 fails after NEX-14666
Reviewed by: Evan Layton <evan.layton@nexenta.com>
Reviewed by: Matt Barden <matt.barden@nexenta.com>
and: (fix ref leaks)
    
      
        | Split | 
	Close | 
      
      | Expand all | 
      | Collapse all | 
    
    
          --- old/usr/src/common/smbclnt/smbfs_ntacl.c
          +++ new/usr/src/common/smbclnt/smbfs_ntacl.c
   1    1  /*
   2    2   * CDDL HEADER START
   3    3   *
   4    4   * The contents of this file are subject to the terms of the
   5    5   * Common Development and Distribution License (the "License").
   6    6   * You may not use this file except in compliance with the License.
   7    7   *
   8    8   * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
   9    9   * or http://www.opensolaris.org/os/licensing.
  10   10   * See the License for the specific language governing permissions
  11   11   * and limitations under the License.
  12   12   *
  13   13   * When distributing Covered Code, include this CDDL HEADER in each
  
    | 
      ↓ 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  /*
  23   23   * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
       24 + * Copyright 2017 Nexenta Systems, Inc.  All rights reserved.
  24   25   */
  25   26  
  26   27  /*
  27   28   * ACL conversion support for smbfs
  28   29   * (To/from NT/ZFS-style ACLs.)
  29   30   */
  30   31  
  31   32  #include <sys/types.h>
  32   33  #include <sys/errno.h>
  33   34  #include <sys/acl.h>
  34   35  #include <sys/byteorder.h>
  35   36  
  36      -#ifdef _KERNEL
       37 +#if defined(_KERNEL) || defined(_FAKE_KERNEL)
  37   38  
  38   39  #include <sys/cred.h>
  39   40  #include <sys/cmn_err.h>
  40   41  #include <sys/kmem.h>
  41   42  #include <sys/sunddi.h>
  42   43  #include <sys/vnode.h>
  43   44  #include <sys/vfs.h>
  44   45  
  45      -#include <sys/kidmap.h>
  46      -
  47   46  #else   /* _KERNEL */
  48   47  
  49   48  #include <stdio.h>
  50   49  #include <stdlib.h>
  51   50  #include <strings.h>
  52   51  
  53      -#include <idmap.h>
       52 +#endif  /* _KERNEL */
  54   53  
       54 +#ifdef _KERNEL
       55 +#include <sys/kidmap.h>
       56 +#else   /* _KERNEL */
       57 +#include <idmap.h>
  55   58  #endif  /* _KERNEL */
  56   59  
  57   60  #include <netsmb/mchain.h>
  58   61  #include <netsmb/smb.h>
  59   62  #include "smbfs_ntacl.h"
  60   63  
  61   64  #define NT_SD_REVISION  1
  62   65  #define NT_ACL_REVISION 2
  63   66  
  64      -#ifdef _KERNEL
       67 +#if defined(_KERNEL) || defined(_FAKE_KERNEL)
  65   68  #define MALLOC(size) kmem_alloc(size, KM_SLEEP)
  66   69  #define FREESZ(p, sz) kmem_free(p, sz)
  67   70  #else   /* _KERNEL */
  68   71  #define MALLOC(size) malloc(size)
  69   72  /*
  70   73   * Define FREESZ() as inline function so the compiler will not
  71   74   * trigger variable set but not used warning for sz in calling function.
  72   75   */
  73   76  /* ARGSUSED */
  74   77  static inline void
  75   78  FREESZ(void *p, size_t sz __unused)
  76   79  {
  77   80          free(p);
  78   81  }
  79   82  #endif  /* _KERNEL */
  80   83  
  81   84  #define ERRCHK(expr)    if ((error = expr) != 0) goto errout
  82   85  
  83   86  /*
  84   87   * Security IDentifier (SID)
  85   88   */
  86   89  static void
  87   90  ifree_sid(i_ntsid_t *sid)
  88   91  {
  89   92          size_t sz;
  90   93  
  91   94          if (sid == NULL)
  92   95                  return;
  93   96  
  94   97          sz = I_SID_SIZE(sid->sid_subauthcount);
  95   98          FREESZ(sid, sz);
  96   99  }
  97  100  
  98  101  static int
  99  102  md_get_sid(mdchain_t *mdp, i_ntsid_t **sidp)
 100  103  {
 101  104          i_ntsid_t *sid = NULL;
 102  105          uint8_t revision, subauthcount;
 103  106          uint32_t *subauthp;
 104  107          size_t sidsz;
 105  108          int error, i;
 106  109  
 107  110          if ((error = md_get_uint8(mdp, &revision)) != 0)
 108  111                  return (error);
 109  112          if ((error = md_get_uint8(mdp, &subauthcount)) != 0)
 110  113                  return (error);
 111  114  
 112  115          sidsz = I_SID_SIZE(subauthcount);
 113  116  
 114  117          if ((sid = MALLOC(sidsz)) == NULL)
 115  118                  return (ENOMEM);
 116  119  
 117  120          bzero(sid, sidsz);
 118  121          sid->sid_revision = revision;
 119  122          sid->sid_subauthcount = subauthcount;
 120  123          ERRCHK(md_get_mem(mdp, sid->sid_authority, 6, MB_MSYSTEM));
 121  124  
 122  125          subauthp = &sid->sid_subauthvec[0];
 123  126          for (i = 0; i < subauthcount; i++) {
 124  127                  ERRCHK(md_get_uint32le(mdp, subauthp));
 125  128                  subauthp++;
 126  129          }
 127  130  
 128  131          /* Success! */
 129  132          *sidp = sid;
 130  133          return (0);
 131  134  
 132  135  errout:
 133  136          ifree_sid(sid);
 134  137          return (error);
 135  138  }
 136  139  
 137  140  static int
 138  141  mb_put_sid(mbchain_t *mbp, i_ntsid_t *sid)
 139  142  {
 140  143          uint32_t *subauthp;
 141  144          int error, i;
 142  145  
 143  146          if (sid == NULL)
 144  147                  return (EINVAL);
 145  148  
 146  149          ERRCHK(mb_put_uint8(mbp, sid->sid_revision));
 147  150          ERRCHK(mb_put_uint8(mbp, sid->sid_subauthcount));
 148  151          ERRCHK(mb_put_mem(mbp, sid->sid_authority, 6, MB_MSYSTEM));
 149  152  
 150  153          subauthp = &sid->sid_subauthvec[0];
 151  154          for (i = 0; i < sid->sid_subauthcount; i++) {
 152  155                  ERRCHK(mb_put_uint32le(mbp, *subauthp));
 153  156                  subauthp++;
 154  157          }
 155  158  
 156  159          /* Success! */
 157  160          return (0);
 158  161  
 159  162  errout:
 160  163          return (error);
 161  164  }
 162  165  
 163  166  
 164  167  /*
 165  168   * Access Control Entry (ACE)
 166  169   */
 167  170  static void
 168  171  ifree_ace(i_ntace_t *ace)
 169  172  {
 170  173  
 171  174          if (ace == NULL)
 172  175                  return;
 173  176  
 174  177          switch (ace->ace_hdr.ace_type) {
 175  178          case ACCESS_ALLOWED_ACE_TYPE:
 176  179          case ACCESS_DENIED_ACE_TYPE:
 177  180          case SYSTEM_AUDIT_ACE_TYPE:
 178  181          case SYSTEM_ALARM_ACE_TYPE:
 179  182                  ifree_sid(ace->ace_v2.ace_sid);
 180  183                  FREESZ(ace, sizeof (i_ntace_v2_t));
 181  184                  break;
 182  185          /* other types todo */
 183  186          default:
 184  187                  break;
 185  188          }
 186  189  }
 187  190  
 188  191  static int
 189  192  md_get_ace(mdchain_t *mdp, i_ntace_t **acep)
 190  193  {
 191  194          mdchain_t tmp_md;
 192  195          i_ntace_hdr_t ace_hdr;
 193  196          i_ntace_t *ace = NULL;
 194  197          uint16_t alloc_size;
 195  198          int error;
 196  199  
 197  200          /*
 198  201           * The ACE is realy variable length,
 199  202           * with format determined by the type.
 200  203           *
 201  204           * There may also be padding after it, so
 202  205           * decode it using a copy of the mdchain,
 203  206           * and then consume the specified length.
 204  207           */
 205  208          tmp_md = *mdp;
 206  209  
 207  210          /* Fixed-size ACE header */
 208  211          ERRCHK(md_get_uint8(&tmp_md, &ace_hdr.ace_type));
 209  212          ERRCHK(md_get_uint8(&tmp_md, &ace_hdr.ace_flags));
 210  213          ERRCHK(md_get_uint16le(&tmp_md, &ace_hdr.ace_size));
 211  214  
 212  215          switch (ace_hdr.ace_type) {
 213  216          case ACCESS_ALLOWED_ACE_TYPE:
 214  217          case ACCESS_DENIED_ACE_TYPE:
 215  218          case SYSTEM_AUDIT_ACE_TYPE:
 216  219          case SYSTEM_ALARM_ACE_TYPE:
 217  220                  alloc_size = sizeof (i_ntace_v2_t);
 218  221                  if ((ace = MALLOC(alloc_size)) == NULL)
 219  222                          return (ENOMEM);
 220  223                  bzero(ace, alloc_size);
 221  224                  /* ACE header */
 222  225                  ace->ace_hdr.ace_type = ace_hdr.ace_type;
 223  226                  ace->ace_hdr.ace_flags = ace_hdr.ace_flags;
 224  227                  ace->ace_hdr.ace_size = alloc_size;
 225  228                  /* Type-specific data. */
 226  229                  ERRCHK(md_get_uint32le(&tmp_md, &ace->ace_v2.ace_rights));
 227  230                  ERRCHK(md_get_sid(&tmp_md, &ace->ace_v2.ace_sid));
 228  231                  break;
 229  232  
 230  233          /* other types todo */
 231  234          default:
 232  235                  error = EIO;
 233  236                  goto errout;
 234  237          }
 235  238  
 236  239          /* Now actually consume ace_hdr.ace_size */
 237  240          ERRCHK(md_get_mem(mdp, NULL, ace_hdr.ace_size, MB_MSYSTEM));
 238  241  
 239  242          /* Success! */
 240  243          *acep = ace;
 241  244          return (0);
 242  245  
 243  246  errout:
 244  247          ifree_ace(ace);
 245  248          return (error);
 246  249  }
 247  250  
 248  251  static int
 249  252  mb_put_ace(mbchain_t *mbp, i_ntace_t *ace)
 250  253  {
 251  254          int cnt0, error;
 252  255          uint16_t ace_len, *ace_len_p;
 253  256  
 254  257          if (ace == NULL)
 255  258                  return (EINVAL);
 256  259  
 257  260          cnt0 = mbp->mb_count;
 258  261  
 259  262          /*
 260  263           * Put the (fixed-size) ACE header
 261  264           * Will fill in the length later.
 262  265           */
 263  266          ERRCHK(mb_put_uint8(mbp, ace->ace_hdr.ace_type));
 264  267          ERRCHK(mb_put_uint8(mbp, ace->ace_hdr.ace_flags));
 265  268          ace_len_p = mb_reserve(mbp, sizeof (*ace_len_p));
 266  269          if (ace_len_p == NULL) {
 267  270                  error = ENOMEM;
 268  271                  goto errout;
 269  272          }
 270  273  
 271  274          switch (ace->ace_hdr.ace_type) {
 272  275          case ACCESS_ALLOWED_ACE_TYPE:
 273  276          case ACCESS_DENIED_ACE_TYPE:
 274  277          case SYSTEM_AUDIT_ACE_TYPE:
 275  278          case SYSTEM_ALARM_ACE_TYPE:
 276  279                  /* Put type-specific data. */
 277  280                  ERRCHK(mb_put_uint32le(mbp, ace->ace_v2.ace_rights));
 278  281                  ERRCHK(mb_put_sid(mbp, ace->ace_v2.ace_sid));
 279  282                  break;
 280  283  
 281  284          /* other types todo */
 282  285          default:
 283  286                  error = EIO;
 284  287                  goto errout;
 285  288          }
 286  289  
 287  290          /* Fill in the (OtW) ACE length. */
 288  291          ace_len = mbp->mb_count - cnt0;
 289  292          *ace_len_p = htoles(ace_len);
 290  293  
 291  294          /* Success! */
 292  295          return (0);
 293  296  
 294  297  errout:
 295  298          return (error);
 296  299  }
 297  300  
 298  301  
 299  302  /*
 300  303   * Access Control List (ACL)
 301  304   */
 302  305  
 303  306  /* Not an OTW structure, so size can be at our convenience. */
 304  307  #define I_ACL_SIZE(cnt) (sizeof (i_ntacl_t) + (cnt) * sizeof (void *))
 305  308  
 306  309  static void
 307  310  ifree_acl(i_ntacl_t *acl)
 308  311  {
 309  312          i_ntace_t **acep;
 310  313          size_t sz;
 311  314          int i;
 312  315  
 313  316          if (acl == NULL)
 314  317                  return;
 315  318  
 316  319          acep = &acl->acl_acevec[0];
 317  320          for (i = 0; i < acl->acl_acecount; i++) {
 318  321                  ifree_ace(*acep);
 319  322                  acep++;
 320  323          }
 321  324          sz = I_ACL_SIZE(acl->acl_acecount);
 322  325          FREESZ(acl, sz);
 323  326  }
 324  327  
 325  328  static int
 326  329  md_get_acl(mdchain_t *mdp, i_ntacl_t **aclp)
 327  330  {
 328  331          i_ntacl_t *acl = NULL;
 329  332          i_ntace_t **acep;
 330  333          uint8_t revision;
 331  334          uint16_t acl_len, acecount;
 332  335          size_t aclsz;
 333  336          int i, error;
 334  337  
 335  338          if ((error = md_get_uint8(mdp, &revision)) != 0)
 336  339                  return (error);
 337  340          if ((error = md_get_uint8(mdp, NULL)) != 0) /* pad1 */
 338  341                  return (error);
 339  342          if ((error = md_get_uint16le(mdp, &acl_len)) != 0)
 340  343                  return (error);
 341  344          if ((error = md_get_uint16le(mdp, &acecount)) != 0)
 342  345                  return (error);
 343  346          if ((error = md_get_uint16le(mdp, NULL)) != 0) /* pad2 */
 344  347                  return (error);
 345  348  
 346  349          aclsz = I_ACL_SIZE(acecount);
 347  350          if ((acl = MALLOC(aclsz)) == NULL)
 348  351                  return (ENOMEM);
 349  352          bzero(acl, aclsz);
 350  353          acl->acl_revision = revision;
 351  354          acl->acl_acecount = acecount;
 352  355  
 353  356          acep = &acl->acl_acevec[0];
 354  357          for (i = 0; i < acl->acl_acecount; i++) {
 355  358                  ERRCHK(md_get_ace(mdp, acep));
 356  359                  acep++;
 357  360          }
 358  361          /*
 359  362           * There may be more data here, but
 360  363           * the caller takes care of that.
 361  364           */
 362  365  
 363  366          /* Success! */
 364  367          *aclp = acl;
 365  368          return (0);
 366  369  
 367  370  errout:
 368  371          ifree_acl(acl);
 369  372          return (error);
 370  373  }
 371  374  
 372  375  static int
 373  376  mb_put_acl(mbchain_t *mbp, i_ntacl_t *acl)
 374  377  {
 375  378          i_ntace_t **acep;
 376  379          uint16_t acl_len, *acl_len_p;
 377  380          int i, cnt0, error;
 378  381  
 379  382          cnt0 = mbp->mb_count;
 380  383  
 381  384          ERRCHK(mb_put_uint8(mbp, acl->acl_revision));
 382  385          ERRCHK(mb_put_uint8(mbp, 0)); /* pad1 */
 383  386          acl_len_p = mb_reserve(mbp, sizeof (*acl_len_p));
 384  387          if (acl_len_p == NULL) {
 385  388                  error = ENOMEM;
 386  389                  goto errout;
 387  390          }
 388  391          ERRCHK(mb_put_uint16le(mbp, acl->acl_acecount));
 389  392          ERRCHK(mb_put_uint16le(mbp, 0)); /* pad2 */
 390  393  
 391  394          acep = &acl->acl_acevec[0];
 392  395          for (i = 0; i < acl->acl_acecount; i++) {
 393  396                  ERRCHK(mb_put_ace(mbp, *acep));
 394  397                  acep++;
 395  398          }
 396  399  
 397  400          /* Fill in acl_len_p */
 398  401          acl_len = mbp->mb_count - cnt0;
 399  402          *acl_len_p = htoles(acl_len);
 400  403  
 401  404          /* Success! */
 402  405          return (0);
 403  406  
 404  407  errout:
 405  408          return (error);
 406  409  }
 407  410  
 408  411  
 409  412  /*
 410  413   * Security Descriptor
 411  414   */
 412  415  void
 413  416  smbfs_acl_free_sd(i_ntsd_t *sd)
 414  417  {
 415  418  
 416  419          if (sd == NULL)
 417  420                  return;
 418  421  
 419  422          ifree_sid(sd->sd_owner);
 420  423          ifree_sid(sd->sd_group);
 421  424          ifree_acl(sd->sd_sacl);
 422  425          ifree_acl(sd->sd_dacl);
 423  426  
 424  427          FREESZ(sd, sizeof (*sd));
 425  428  }
 426  429  
 427  430  /*
 428  431   * Import a raw SD (mb chain) into "internal" form.
 429  432   * (like "absolute" form per. NT docs)
 430  433   * Returns allocated data in sdp
 431  434   *
 432  435   * Note: does NOT consume all the mdp data, so the
 433  436   * caller has to take care of that if necessary.
 434  437   */
 435  438  int
 436  439  md_get_ntsd(mdchain_t *mdp, i_ntsd_t **sdp)
 437  440  {
 438  441          i_ntsd_t *sd = NULL;
 439  442          mdchain_t top_md, tmp_md;
 440  443          uint32_t owneroff, groupoff, sacloff, dacloff;
 441  444          int error;
 442  445  
 443  446          if ((sd = MALLOC(sizeof (*sd))) == NULL)
 444  447                  return (ENOMEM);
 445  448          bzero(sd, sizeof (*sd));
 446  449  
 447  450          /*
 448  451           * Offsets below are relative to this point,
 449  452           * so save the mdp state for use below.
 450  453           */
 451  454          top_md = *mdp;
 452  455  
 453  456          ERRCHK(md_get_uint8(mdp, &sd->sd_revision));
 454  457          ERRCHK(md_get_uint8(mdp, &sd->sd_rmctl));
 455  458          ERRCHK(md_get_uint16le(mdp, &sd->sd_flags));
 456  459          ERRCHK(md_get_uint32le(mdp, &owneroff));
 457  460          ERRCHK(md_get_uint32le(mdp, &groupoff));
 458  461          ERRCHK(md_get_uint32le(mdp, &sacloff));
 459  462          ERRCHK(md_get_uint32le(mdp, &dacloff));
 460  463  
 461  464          /*
 462  465           * The SD is "self-relative" on the wire,
 463  466           * but not after this decodes it.
 464  467           */
 465  468          sd->sd_flags &= ~SD_SELF_RELATIVE;
 466  469  
 467  470          /*
 468  471           * For each section make a temporary copy of the
 469  472           * top_md state, advance to the given offset, and
 470  473           * pass that to the lower md_get_xxx functions.
 471  474           * These could be marshalled in any order, but
 472  475           * are normally found in the order shown here.
 473  476           */
 474  477          if (sacloff) {
 475  478                  tmp_md = top_md;
 476  479                  md_get_mem(&tmp_md, NULL, sacloff, MB_MSYSTEM);
 477  480                  ERRCHK(md_get_acl(&tmp_md, &sd->sd_sacl));
 478  481          }
 479  482          if (dacloff) {
 480  483                  tmp_md = top_md;
 481  484                  md_get_mem(&tmp_md, NULL, dacloff, MB_MSYSTEM);
 482  485                  ERRCHK(md_get_acl(&tmp_md, &sd->sd_dacl));
 483  486          }
 484  487          if (owneroff) {
 485  488                  tmp_md = top_md;
 486  489                  md_get_mem(&tmp_md, NULL, owneroff, MB_MSYSTEM);
 487  490                  ERRCHK(md_get_sid(&tmp_md, &sd->sd_owner));
 488  491          }
 489  492          if (groupoff) {
 490  493                  tmp_md = top_md;
 491  494                  md_get_mem(&tmp_md, NULL, groupoff, MB_MSYSTEM);
 492  495                  ERRCHK(md_get_sid(&tmp_md, &sd->sd_group));
 493  496          }
 494  497  
 495  498          /* Success! */
 496  499          *sdp = sd;
 497  500          return (0);
 498  501  
 499  502  errout:
 500  503          smbfs_acl_free_sd(sd);
 501  504          return (error);
 502  505  }
 503  506  
 504  507  /*
 505  508   * Export an "internal" SD into an raw SD (mb chain).
 506  509   * (a.k.a "self-relative" form per. NT docs)
 507  510   * Returns allocated mbchain in mbp.
 508  511   */
 509  512  int
 510  513  mb_put_ntsd(mbchain_t *mbp, i_ntsd_t *sd)
 511  514  {
 512  515          uint32_t *owneroffp, *groupoffp, *sacloffp, *dacloffp;
 513  516          uint32_t owneroff, groupoff, sacloff, dacloff;
 514  517          uint16_t flags;
 515  518          int cnt0, error;
 516  519  
 517  520          cnt0 = mbp->mb_count;
 518  521          owneroff = groupoff = sacloff = dacloff = 0;
 519  522  
 520  523          /* The SD is "self-relative" on the wire. */
 521  524          flags = sd->sd_flags | SD_SELF_RELATIVE;
 522  525  
 523  526          ERRCHK(mb_put_uint8(mbp, sd->sd_revision));
 524  527          ERRCHK(mb_put_uint8(mbp, sd->sd_rmctl));
 525  528          ERRCHK(mb_put_uint16le(mbp, flags));
 526  529  
 527  530          owneroffp = mb_reserve(mbp, sizeof (*owneroffp));
 528  531          groupoffp = mb_reserve(mbp, sizeof (*groupoffp));
 529  532          sacloffp  = mb_reserve(mbp, sizeof (*sacloffp));
 530  533          dacloffp  = mb_reserve(mbp, sizeof (*dacloffp));
 531  534          if (owneroffp == NULL || groupoffp == NULL ||
 532  535              sacloffp == NULL || dacloffp == NULL) {
 533  536                  error = ENOMEM;
 534  537                  goto errout;
 535  538          }
 536  539  
 537  540          /*
 538  541           * These could be marshalled in any order, but
 539  542           * are normally found in the order shown here.
 540  543           */
 541  544          if (sd->sd_sacl) {
 542  545                  sacloff = mbp->mb_count - cnt0;
 543  546                  ERRCHK(mb_put_acl(mbp, sd->sd_sacl));
 544  547          }
 545  548          if (sd->sd_dacl) {
 546  549                  dacloff = mbp->mb_count - cnt0;
 547  550                  ERRCHK(mb_put_acl(mbp, sd->sd_dacl));
 548  551          }
 549  552          if (sd->sd_owner) {
 550  553                  owneroff = mbp->mb_count - cnt0;
 551  554                  ERRCHK(mb_put_sid(mbp, sd->sd_owner));
 552  555          }
 553  556          if (sd->sd_group) {
 554  557                  groupoff = mbp->mb_count - cnt0;
 555  558                  ERRCHK(mb_put_sid(mbp, sd->sd_group));
 556  559          }
 557  560  
 558  561          /* Fill in the offsets */
 559  562          *owneroffp = htolel(owneroff);
 560  563          *groupoffp = htolel(groupoff);
 561  564          *sacloffp  = htolel(sacloff);
 562  565          *dacloffp  = htolel(dacloff);
 563  566  
 564  567          /* Success! */
 565  568          return (0);
 566  569  
 567  570  errout:
 568  571          return (error);
 569  572  }
 570  573  
 571  574  /*
 572  575   * ================================================================
 573  576   * Support for ACL fetch, including conversions
 574  577   * from Windows ACLs to NFSv4-style ACLs.
 575  578   * ================================================================
 576  579   */
 577  580  
 578  581  #define GENERIC_RIGHTS_MASK \
 579  582          (GENERIC_RIGHT_READ_ACCESS | GENERIC_RIGHT_WRITE_ACCESS |\
 580  583          GENERIC_RIGHT_EXECUTE_ACCESS | GENERIC_RIGHT_ALL_ACCESS)
 581  584  
 582  585  /*
 583  586   * Table for converting NT GENERIC_RIGHT_... to specific rights
 584  587   * appropriate for objects of type file.
 585  588   */
 586  589  struct gen2fsr {
 587  590          uint32_t        gf_generic;
 588  591          uint32_t        gf_specific;
 589  592  };
 590  593  static const struct gen2fsr
 591  594  smbfs_gen2fsr[] = {
 592  595          {
 593  596                  GENERIC_RIGHT_READ_ACCESS,
 594  597                  STD_RIGHT_SYNCHRONIZE_ACCESS |
 595  598                  STD_RIGHT_READ_CONTROL_ACCESS |
 596  599                  SA_RIGHT_FILE_READ_ATTRIBUTES |
 597  600                  SA_RIGHT_FILE_READ_EA |
 598  601                  SA_RIGHT_FILE_READ_DATA },
 599  602          {
 600  603                  GENERIC_RIGHT_WRITE_ACCESS,
 601  604                  STD_RIGHT_SYNCHRONIZE_ACCESS |
 602  605                  STD_RIGHT_READ_CONTROL_ACCESS |
 603  606                  SA_RIGHT_FILE_WRITE_ATTRIBUTES |
 604  607                  SA_RIGHT_FILE_WRITE_EA |
 605  608                  SA_RIGHT_FILE_APPEND_DATA |
 606  609                  SA_RIGHT_FILE_WRITE_DATA },
 607  610          {
 608  611                  GENERIC_RIGHT_EXECUTE_ACCESS,
 609  612                  STD_RIGHT_SYNCHRONIZE_ACCESS |
 610  613                  STD_RIGHT_READ_CONTROL_ACCESS |
 611  614                  SA_RIGHT_FILE_READ_ATTRIBUTES |
 612  615                  SA_RIGHT_FILE_EXECUTE },
 613  616          {
 614  617                  GENERIC_RIGHT_ALL_ACCESS,
 615  618                  STD_RIGHT_SYNCHRONIZE_ACCESS |
 616  619                  STD_RIGHT_WRITE_OWNER_ACCESS |
 617  620                  STD_RIGHT_WRITE_DAC_ACCESS |
 618  621                  STD_RIGHT_READ_CONTROL_ACCESS |
 619  622                  STD_RIGHT_DELETE_ACCESS |
 620  623                  SA_RIGHT_FILE_ALL_ACCESS },
 621  624          { 0, 0 }
 622  625  };
 623  626  
 624  627  /*
 625  628   * Table for translating ZFS ACE flags to NT ACE flags.
 626  629   * The low four bits are the same, but not others.
 627  630   */
 628  631  struct zaf2naf {
 629  632          uint16_t        za_flag;
 630  633          uint8_t         na_flag;
 631  634  };
 632  635  static const struct zaf2naf
 633  636  smbfs_zaf2naf[] = {
 634  637          { ACE_FILE_INHERIT_ACE,         OBJECT_INHERIT_ACE_FLAG },
 635  638          { ACE_DIRECTORY_INHERIT_ACE,    CONTAINER_INHERIT_ACE_FLAG },
 636  639          { ACE_NO_PROPAGATE_INHERIT_ACE, NO_PROPAGATE_INHERIT_ACE_FLAG },
 637  640          { ACE_INHERIT_ONLY_ACE,         INHERIT_ONLY_ACE_FLAG },
 638  641          { ACE_INHERITED_ACE,            INHERITED_ACE_FLAG },
 639  642          { ACE_SUCCESSFUL_ACCESS_ACE_FLAG, SUCCESSFUL_ACCESS_ACE_FLAG },
 640  643          { ACE_FAILED_ACCESS_ACE_FLAG,   FAILED_ACCESS_ACE_FLAG },
 641  644          { 0, 0 }
 642  645  };
 643  646  
 644  647  /*
 645  648   * Convert an NT SID to a string. Optionally return the
 646  649   * last sub-authority (or "relative ID" -- RID) in *ridp
 647  650   * and truncate the output string after the domain part.
 648  651   * If ridp==NULL, the output string is the whole SID,
 649  652   * including both the domain and RID.
 650  653   *
 651  654   * Return length written, or -1 on error.
 652  655   */
 653  656  int
 654  657  smbfs_sid2str(i_ntsid_t *sid,
 655  658          char *obuf, size_t osz, uint32_t *ridp)
 656  659  {
 657  660          char *s = obuf;
 658  661          uint64_t auth = 0;
 659  662          uint_t i, n;
 660  663          uint32_t subs, *ip;
 661  664  
 662  665          n = snprintf(s, osz, "S-%u", sid->sid_revision);
 663  666          if (n > osz)
 664  667                  return (-1);
 665  668          s += n; osz -= n;
 666  669  
 667  670          for (i = 0; i < 6; i++)
 668  671                  auth = (auth << 8) | sid->sid_authority[i];
 669  672          n = snprintf(s, osz, "-%llu", (u_longlong_t)auth);
 670  673          if (n > osz)
 671  674                  return (-1);
 672  675          s += n; osz -= n;
 673  676  
 674  677          subs = sid->sid_subauthcount;
 675  678          if (subs < 1 || subs > 15)
 676  679                  return (-1);
 677  680          if (ridp)
 678  681                  subs--;
 679  682  
 680  683          ip = &sid->sid_subauthvec[0];
 681  684          for (; subs; subs--, ip++) {
 682  685                  n = snprintf(s, osz, "-%u", *ip);
 683  686                  if (n > osz)
 684  687                          return (-1);
 685  688                  s += n; osz -= n;
 686  689          }
 687  690          if (ridp)
 688  691                  *ridp = *ip;
 689  692  
 690  693          /* LINTED E_PTRDIFF_OVERFLOW */
 691  694          return (s - obuf);
 692  695  }
 693  696  
 694  697  /*
 695  698   * Our interface to the idmap service.
 696  699   *
 697  700   * The idmap API is _almost_ the same between
 698  701   * kernel and user-level.  But not quite...
 699  702   * Hope this improves readability below.
 700  703   */
 701  704  #ifdef  _KERNEL
 702  705  
 703  706  #define I_getuidbysid(GH, SPP, RID, UIDP, SP) \
 704  707          kidmap_batch_getuidbysid(GH, SPP, RID, UIDP, SP)
 705  708  
 706  709  #define I_getgidbysid(GH, SPP, RID, GIDP, SP) \
 707  710          kidmap_batch_getgidbysid(GH, SPP, RID, GIDP, SP)
 708  711  
 709  712  #define I_getpidbysid(GH, SPP, RID, PIDP, ISUP, SP) \
 710  713          kidmap_batch_getpidbysid(GH, SPP, RID, PIDP, ISUP, SP)
 711  714  
 712  715  #define I_getmappings kidmap_get_mappings
 713  716  
 714  717  #else /* _KERNEL */
 715  718  
 716  719  #define I_getuidbysid(GH, SPP, RID, UIDP, SP) \
 717  720          idmap_get_uidbysid(GH, SPP, RID, 0, UIDP, SP)
 718  721  
 719  722  #define I_getgidbysid(GH, SPP, RID, GIDP, SP) \
 720  723          idmap_get_gidbysid(GH, SPP, RID, 0, GIDP, SP)
 721  724  
 722  725  #define I_getpidbysid(GH, SPP, RID, PIDP, ISUP, SP) \
 723  726          idmap_get_pidbysid(GH, SPP, RID, 0, PIDP, ISUP, SP)
 724  727  
 725  728  #define I_getmappings idmap_get_mappings
 726  729  
 727  730  #endif /* _KERNEL */
 728  731  
 729  732  
 730  733  /*
 731  734   * The idmap request types, chosen so they also
 732  735   * match the values returned in mi_isuser.
 733  736   */
 734  737  #define IDM_TYPE_ANY    -1
 735  738  #define IDM_TYPE_GROUP  0
 736  739  #define IDM_TYPE_USER   1
 737  740  
 738  741  /*
 739  742   * A sentinel value for mi_isuser (below) to indicate
 740  743   * that the SID is the well-known "Everyone" (S-1-1-0).
 741  744   * The idmap library only uses -1, 0, 1, so this value
 742  745   * is arbitrary but must not overlap w/ idmap values.
 743  746   * XXX: Could use a way for idmap to tell us when
 744  747   * it recognizes this well-known SID.
 745  748   */
 746  749  #define IDM_EVERYONE    11
 747  750  
 748  751  struct mapinfo2uid {
 749  752          uid_t   mi_uid; /* or gid, or pid */
 750  753          int     mi_isuser; /* IDM_TYPE */
 751  754          idmap_stat mi_status;
 752  755  };
 753  756  
 754  757  /*
 755  758   * Build an idmap request.  Cleanup is
 756  759   * handled by the caller (error or not)
 757  760   */
 758  761  static int
 759  762  mkrq_idmap_sid2ux(
 760  763          idmap_get_handle_t *idmap_gh,
 761  764          struct mapinfo2uid *mip,
 762  765          i_ntsid_t *sid,
 763  766          int req_type)
 764  767  {
 765  768          char strbuf[256];
 766  769          char *sid_prefix;
 767  770          uint32_t        rid;
 768  771          idmap_stat      idms;
 769  772  
 770  773          if (smbfs_sid2str(sid, strbuf, sizeof (strbuf), &rid) < 0)
 771  774                  return (EINVAL);
 772  775          sid_prefix = strbuf;
 773  776  
 774  777          /*
 775  778           * Give the "Everyone" group special treatment.
 776  779           */
 777  780          if (strcmp(sid_prefix, "S-1-1") == 0 && rid == 0) {
 778  781                  /* This is "Everyone" */
 779  782                  mip->mi_uid = (uid_t)-1;
 780  783                  mip->mi_isuser = IDM_EVERYONE;
 781  784                  mip->mi_status = 0;
 782  785                  return (0);
 783  786          }
 784  787  
 785  788          switch (req_type) {
 786  789  
 787  790          case IDM_TYPE_USER:
 788  791                  mip->mi_isuser = req_type;
 789  792                  idms = I_getuidbysid(idmap_gh, sid_prefix, rid,
 790  793                      &mip->mi_uid, &mip->mi_status);
 791  794                  break;
 792  795  
 793  796          case IDM_TYPE_GROUP:
 794  797                  mip->mi_isuser = req_type;
 795  798                  idms = I_getgidbysid(idmap_gh, sid_prefix, rid,
 796  799                      &mip->mi_uid, &mip->mi_status);
 797  800                  break;
 798  801  
 799  802          case IDM_TYPE_ANY:
 800  803                  idms = I_getpidbysid(idmap_gh, sid_prefix, rid,
 801  804                      &mip->mi_uid, &mip->mi_isuser, &mip->mi_status);
 802  805                  break;
 803  806  
 804  807          default:
 805  808                  idms = IDMAP_ERR_OTHER;
 806  809                  break;
 807  810          }
 808  811  
 809  812          if (idms != IDMAP_SUCCESS)
 810  813                  return (EINVAL);
 811  814  
 812  815          return (0);
 813  816  }
 814  817  
 815  818  /*
 816  819   * Convert an NT ACE to a ZFS ACE.
 817  820   * ACE type was already validated.
 818  821   */
 819  822  static void
 820  823  ntace2zace(ace_t *zacep, i_ntace_t *ntace, struct mapinfo2uid *mip)
 821  824  {
 822  825          const struct zaf2naf *znaf;
 823  826          uid_t zwho;
 824  827          uint32_t zamask;
 825  828          uint16_t zflags;
 826  829  
 827  830          /*
 828  831           * Set the "ID type" flags in the ZFS ace flags.
 829  832           */
 830  833          zflags = 0;
 831  834          switch (mip->mi_isuser) {
 832  835          case IDM_EVERYONE:
 833  836                  zflags = ACE_EVERYONE;
 834  837                  zwho = (uid_t)-1;
 835  838                  break;
 836  839  
 837  840          case IDM_TYPE_GROUP: /* it's a GID */
 838  841                  zflags = ACE_IDENTIFIER_GROUP;
 839  842                  zwho = mip->mi_uid;
 840  843                  break;
 841  844  
 842  845          default:
 843  846          case IDM_TYPE_USER: /* it's a UID */
 844  847                  zflags = 0;
 845  848                  zwho = mip->mi_uid;
 846  849                  break;
 847  850          }
 848  851  
 849  852          /*
 850  853           * Translate NT ACE flags to ZFS ACE flags.
 851  854           */
 852  855          for (znaf = smbfs_zaf2naf; znaf->za_flag; znaf++)
 853  856                  if (ntace->ace_hdr.ace_flags & znaf->na_flag)
 854  857                          zflags |= znaf->za_flag;
 855  858  
 856  859          /*
 857  860           * The "normal" access mask bits are the same, but
 858  861           * if the ACE has any GENERIC_RIGHT_... convert those
 859  862           * to specific rights.  GENERIC bits are rarely seen,
 860  863           * but reportedly can happen with inherit-only ACEs.
 861  864           */
 862  865          zamask = ntace->ace_v2.ace_rights & ACE_ALL_PERMS;
 863  866          if (ntace->ace_v2.ace_rights & GENERIC_RIGHTS_MASK) {
 864  867                  const struct gen2fsr *gf;
 865  868                  for (gf = smbfs_gen2fsr; gf->gf_generic; gf++)
 866  869                          if (ntace->ace_v2.ace_rights & gf->gf_generic)
 867  870                                  zamask |= gf->gf_specific;
 868  871          }
 869  872  
 870  873          /*
 871  874           * Fill in the ZFS-style ACE
 872  875           */
 873  876          zacep->a_who = zwho;
 874  877          zacep->a_access_mask = zamask;
 875  878          zacep->a_flags = zflags;
 876  879          zacep->a_type = ntace->ace_hdr.ace_type;
 877  880  }
 878  881  
 879  882  /*
  
    | 
      ↓ open down ↓ | 
    805 lines elided | 
    
      ↑ open up ↑ | 
  
 880  883   * Convert an internal SD to a ZFS-style ACL.
 881  884   * Note optional args: vsa/acl, uidp, gidp.
 882  885   *
 883  886   * This makes two passes over the SD, the first building a
 884  887   * "batch" request for idmap with results in mapinfo, the
 885  888   * second building a ZFS-style ACL using the idmap results.
 886  889   */
 887  890  int
 888  891  smbfs_acl_sd2zfs(
 889  892          i_ntsd_t *sd,
 890      -#ifdef  _KERNEL
      893 +#if defined(_KERNEL) || defined(_FAKE_KERNEL)
 891  894          vsecattr_t *acl_info,
 892  895  #else /* _KERNEL */
 893  896          acl_t *acl_info,
 894  897  #endif /* _KERNEL */
 895  898          uid_t *uidp, gid_t *gidp)
 896  899  {
 897  900          struct mapinfo2uid *mip, *mapinfo = NULL;
 898  901          int error, i, mapcnt, zacecnt, zacl_size;
 899  902          ace_t *zacep0, *zacep;
 900  903          uid_t own_uid = (uid_t)-1;
 901  904          gid_t own_gid = (gid_t)-1;
 902  905          i_ntacl_t *ntacl;
 903  906          i_ntace_t **ntacep;
 904  907          idmap_get_handle_t *idmap_gh = NULL;
 905  908          idmap_stat      idms;
 906  909  
 907  910          /*
 908  911           * sanity checks
 909  912           */
 910  913          if (acl_info) {
 911      -#ifndef _KERNEL
      914 +#if !defined(_KERNEL) && !defined(_FAKE_KERNEL)
 912  915                  if (acl_info->acl_type != ACE_T ||
 913  916                      acl_info->acl_aclp != NULL ||
 914  917                      acl_info->acl_entry_size != sizeof (ace_t))
 915  918                          return (EINVAL);
 916      -#endif /* _KERNEL */
      919 +#endif /* !_KERNEL */
 917  920                  if ((sd->sd_flags & SD_DACL_PRESENT) == 0)
 918  921                          return (EINVAL);
 919  922          }
 920  923  
 921  924          /*
 922  925           * How many SID mappings will we need?
 923  926           */
 924  927          mapcnt = 0;
 925  928          if (sd->sd_owner)
 926  929                  mapcnt++;
 927  930          if (sd->sd_group)
 928  931                  mapcnt++;
 929  932          if ((sd->sd_flags & SD_SACL_PRESENT) &&
 930  933              (sd->sd_sacl != NULL))
 931  934                  mapcnt += sd->sd_sacl->acl_acecount;
 932  935          if ((sd->sd_flags & SD_DACL_PRESENT) &&
 933  936              (sd->sd_dacl != NULL))
 934  937                  mapcnt += sd->sd_dacl->acl_acecount;
 935  938          if (mapcnt == 0) {
 936  939                  /*
 937  940                   * We have a NULL DACL, SACL, and don't
 938  941                   * have an owner or group, so there's no
 939  942                   * idmap work to do.  This is very rare,
 940  943                   * so rather than complicate things below,
 941  944                   * pretend we need one mapping slot.
 942  945                   */
 943  946                  mapcnt = 1;
 944  947          }
 945  948  
 946  949          mapinfo = MALLOC(mapcnt * sizeof (*mapinfo));
 947  950          if (mapinfo == NULL) {
 948  951                  error = ENOMEM;
 949  952                  goto errout;
 950  953          }
 951  954          bzero(mapinfo, mapcnt * sizeof (*mapinfo));
 952  955  
 953  956  
 954  957          /*
 955  958           * Get an imap "batch" request handle.
 956  959           */
 957  960  #ifdef  _KERNEL
 958  961          idmap_gh = kidmap_get_create(curproc->p_zone);
 959  962  #else /* _KERNEL */
 960  963          idms = idmap_get_create(&idmap_gh);
 961  964          if (idms != IDMAP_SUCCESS) {
 962  965                  error = ENOTACTIVE;
 963  966                  goto errout;
 964  967          }
 965  968  #endif /* _KERNEL */
 966  969  
 967  970          /*
 968  971           * Build our request to the idmap deamon,
 969  972           * getting Unix IDs for every SID.
 970  973           */
 971  974          mip = mapinfo;
 972  975          if (sd->sd_owner) {
 973  976                  error = mkrq_idmap_sid2ux(idmap_gh, mip,
 974  977                      sd->sd_owner, IDM_TYPE_USER);
 975  978                  if (error)
 976  979                          goto errout;
 977  980                  mip++;
 978  981          }
 979  982          if (sd->sd_group) {
 980  983                  error = mkrq_idmap_sid2ux(idmap_gh, mip,
 981  984                      sd->sd_group, IDM_TYPE_GROUP);
 982  985                  if (error)
 983  986                          goto errout;
 984  987                  mip++;
 985  988          }
 986  989          if ((sd->sd_flags & SD_SACL_PRESENT) &&
 987  990              (sd->sd_sacl != NULL)) {
 988  991                  ntacl = sd->sd_sacl;
 989  992                  ntacep = &ntacl->acl_acevec[0];
 990  993                  for (i = 0; i < ntacl->acl_acecount; i++) {
 991  994                          error = mkrq_idmap_sid2ux(idmap_gh, mip,
 992  995                              (*ntacep)->ace_v2.ace_sid, IDM_TYPE_ANY);
 993  996                          if (error)
 994  997                                  goto errout;
 995  998                          ntacep++;
 996  999                          mip++;
 997 1000                  }
 998 1001          }
 999 1002          if ((sd->sd_flags & SD_DACL_PRESENT) &&
1000 1003              (sd->sd_dacl != NULL)) {
1001 1004                  ntacl = sd->sd_dacl;
1002 1005                  ntacep = &ntacl->acl_acevec[0];
1003 1006                  for (i = 0; i < ntacl->acl_acecount; i++) {
1004 1007                          error = mkrq_idmap_sid2ux(idmap_gh, mip,
1005 1008                              (*ntacep)->ace_v2.ace_sid, IDM_TYPE_ANY);
1006 1009                          if (error)
1007 1010                                  goto errout;
1008 1011                          ntacep++;
1009 1012                          mip++;
1010 1013                  }
1011 1014          }
1012 1015  
1013 1016          if (mip != mapinfo) {
1014 1017                  idms = I_getmappings(idmap_gh);
1015 1018                  if (idms != IDMAP_SUCCESS) {
1016 1019                          /* creative error choice */
1017 1020                          error = EIDRM;
1018 1021                          goto errout;
1019 1022                  }
1020 1023          }
1021 1024  
1022 1025          /*
1023 1026           * With any luck, we now have Unix user/group IDs
1024 1027           * for every Windows SID in the security descriptor.
1025 1028           * The remaining work is just format conversion.
1026 1029           */
1027 1030          mip = mapinfo;
1028 1031          if (sd->sd_owner) {
1029 1032                  own_uid = mip->mi_uid;
1030 1033                  mip++;
1031 1034          }
1032 1035          if (sd->sd_group) {
1033 1036                  own_gid = mip->mi_uid;
1034 1037                  mip++;
1035 1038          }
1036 1039  
1037 1040          if (uidp)
1038 1041                  *uidp = own_uid;
1039 1042          if (gidp)
1040 1043                  *gidp = own_gid;
1041 1044  
1042 1045          if (acl_info == NULL) {
1043 1046                  /* Caller only wanted uid/gid */
1044 1047                  goto done;
1045 1048          }
1046 1049  
1047 1050          /*
1048 1051           * Build the ZFS-style ACL
1049 1052           * First, allocate the most ZFS ACEs we'll need.
1050 1053           */
1051 1054          zacecnt = 0;
1052 1055          if ((sd->sd_flags & SD_SACL_PRESENT) &&
1053 1056              (sd->sd_sacl != NULL))
1054 1057                  zacecnt += sd->sd_sacl->acl_acecount;
1055 1058  
1056 1059          /* NB, have: (sd->sd_flags & SD_DACL_PRESENT) */
1057 1060          if ((sd->sd_dacl != NULL) &&
1058 1061              (sd->sd_dacl->acl_acecount > 0)) {
1059 1062                  zacecnt += sd->sd_dacl->acl_acecount;
1060 1063          } else {
1061 1064                  /*
1062 1065                   * DACL is NULL or empty. Either way,
1063 1066                   * we'll need to add a ZFS ACE below.
1064 1067                   */
1065 1068                  zacecnt++;
1066 1069          }
1067 1070          zacl_size = zacecnt * sizeof (ace_t);
1068 1071          zacep0 = MALLOC(zacl_size);
1069 1072          if (zacep0 == NULL) {
1070 1073                  error = ENOMEM;
1071 1074                  goto errout;
1072 1075          }
1073 1076          zacep = zacep0;
1074 1077  
1075 1078          if ((sd->sd_flags & SD_SACL_PRESENT) &&
1076 1079              (sd->sd_sacl != NULL)) {
1077 1080                  ntacl = sd->sd_sacl;
1078 1081                  ntacep = &ntacl->acl_acevec[0];
1079 1082                  for (i = 0; i < ntacl->acl_acecount; i++) {
1080 1083                          ntace2zace(zacep, *ntacep, mip);
1081 1084                          zacep++;
1082 1085                          ntacep++;
1083 1086                          mip++;
1084 1087                  }
1085 1088          }
1086 1089  
1087 1090          /* NB, have: (sd->sd_flags & SD_DACL_PRESENT) */
1088 1091          if (sd->sd_dacl != NULL) {
1089 1092                  ntacl = sd->sd_dacl;
1090 1093                  ntacep = &ntacl->acl_acevec[0];
1091 1094                  for (i = 0; i < ntacl->acl_acecount; i++) {
1092 1095                          ntace2zace(zacep, *ntacep, mip);
1093 1096                          zacep++;
1094 1097                          ntacep++;
1095 1098                          mip++;
1096 1099                  }
1097 1100          }
1098 1101          if (sd->sd_dacl == NULL) {
1099 1102                  /*
1100 1103                   * The SD has a NULL DACL.  That means
1101 1104                   * everyone@, full-control
1102 1105                   */
1103 1106                  zacep->a_who = (uid_t)-1;
1104 1107                  zacep->a_access_mask = ACE_ALL_PERMS;
1105 1108                  zacep->a_flags = ACE_EVERYONE;
1106 1109                  zacep->a_type = ACCESS_ALLOWED_ACE_TYPE;
1107 1110          } else if (sd->sd_dacl->acl_acecount == 0) {
1108 1111                  /*
1109 1112                   * The SD has an Empty DACL.  We need
  
    | 
      ↓ open down ↓ | 
    183 lines elided | 
    
      ↑ open up ↑ | 
  
1110 1113                   * at least one ACE, so add one giving
1111 1114                   * the owner the usual implied access.
1112 1115                   */
1113 1116                  zacep->a_who = (uid_t)-1;
1114 1117                  zacep->a_access_mask = ACE_READ_ATTRIBUTES | \
1115 1118                      ACE_READ_ACL | ACE_WRITE_ACL;
1116 1119                  zacep->a_flags = ACE_OWNER;
1117 1120                  zacep->a_type = ACCESS_ALLOWED_ACE_TYPE;
1118 1121          }
1119 1122  
1120      -#ifdef _KERNEL
     1123 +#if defined(_KERNEL) || defined(_FAKE_KERNEL)
1121 1124          acl_info->vsa_aclcnt = zacecnt;
1122 1125          acl_info->vsa_aclentp = zacep0;
1123 1126          acl_info->vsa_aclentsz = zacl_size;
1124 1127  #else   /* _KERNEL */
1125 1128          acl_info->acl_cnt = zacecnt;
1126 1129          acl_info->acl_aclp = zacep0;
1127 1130  #endif  /* _KERNEL */
1128 1131  
1129 1132  done:
1130 1133          error = 0;
1131 1134  
1132 1135  errout:
1133 1136          if (mapinfo != NULL)
1134 1137                  FREESZ(mapinfo, mapcnt * sizeof (*mapinfo));
1135 1138  #ifdef  _KERNEL
1136 1139          if (idmap_gh != NULL)
1137 1140                  kidmap_get_destroy(idmap_gh);
1138 1141  #else /* _KERNEL */
1139 1142          if (idmap_gh != NULL)
1140 1143                  idmap_get_destroy(idmap_gh);
1141 1144  #endif /* _KERNEL */
1142 1145  
1143 1146          return (error);
1144 1147  }
1145 1148  
1146 1149  
1147 1150  /*
1148 1151   * ================================================================
1149 1152   * Support for ACL store, including conversions
1150 1153   * from NFSv4-style ACLs to Windows ACLs.
1151 1154   * ================================================================
1152 1155   */
1153 1156  
1154 1157  /*
1155 1158   * Convert a "sid-prefix" string plus RID into an NT SID.
1156 1159   *
1157 1160   * If successful, sets *osid and returns zero,
1158 1161   * otherwise returns an errno value.
1159 1162   */
1160 1163  int
1161 1164  smbfs_str2sid(const char *sid_prefix, uint32_t *ridp, i_ntsid_t **osidp)
1162 1165  {
1163 1166          i_ntsid_t *sid = NULL;
1164 1167          u_longlong_t auth = 0;
1165 1168          ulong_t sa;
1166 1169          uint8_t sacnt;
1167 1170          const char *p;
1168 1171          char *np;
1169 1172          size_t size;
1170 1173          int i;
1171 1174          int err;
1172 1175  
1173 1176          if (sid_prefix == NULL)
1174 1177                  return (EINVAL);
1175 1178  
1176 1179          p = sid_prefix;
1177 1180          if (strncmp(p, "S-1-", 4) != 0)
1178 1181                  return (EINVAL);
1179 1182          p += 4;
1180 1183  
1181 1184          /* Parse the "authority" */
1182 1185  #ifdef  _KERNEL
1183 1186          err = ddi_strtoull(p, &np, 10, &auth);
1184 1187          if (err != 0)
1185 1188                  return (err);
1186 1189  #else   /* _KERNEL */
1187 1190          auth = strtoull(p, &np, 10);
1188 1191          if (p == np)
1189 1192                  return (EINVAL);
1190 1193  #endif  /* _KERNEL */
1191 1194  
1192 1195          /*
1193 1196           * Count the sub-authorities.  Here, np points to
1194 1197           * the "-" before the first sub-authority.
1195 1198           */
1196 1199          sacnt = 0;
1197 1200          for (p = np; *p; p++) {
1198 1201                  if (*p == '-')
1199 1202                          sacnt++;
1200 1203          }
1201 1204          if (ridp != NULL)
1202 1205                  sacnt++;
1203 1206  
1204 1207          /* Allocate the internal SID. */
1205 1208          size = I_SID_SIZE(sacnt);
1206 1209          sid = MALLOC(size);
1207 1210          if (sid == NULL)
1208 1211                  return (ENOMEM);
1209 1212          bzero(sid, size);
1210 1213  
1211 1214          /* Fill it in. */
1212 1215          sid->sid_revision = 1;
1213 1216          sid->sid_subauthcount = sacnt;
1214 1217          for (i = 5; i >= 0; i--) {
1215 1218                  sid->sid_authority[i] = auth & 0xFF;
1216 1219                  auth = auth >> 8;
1217 1220          }
1218 1221  
  
    | 
      ↓ open down ↓ | 
    88 lines elided | 
    
      ↑ open up ↑ | 
  
1219 1222          err = EINVAL;
1220 1223          if (ridp != NULL)
1221 1224                  sacnt--; /* Last SA not from string */
1222 1225          p = np;
1223 1226          for (i = 0; i < sacnt; i++) {
1224 1227                  if (*p != '-') {
1225 1228                          err = EINVAL;
1226 1229                          goto out;
1227 1230                  }
1228 1231                  p++;
1229      -#ifdef  _KERNEL
     1232 +#if defined(_KERNEL) || defined(_FAKE_KERNEL)
1230 1233                  err = ddi_strtoul(p, &np, 10, &sa);
1231 1234                  if (err != 0)
1232 1235                          goto out;
1233 1236  #else   /* _KERNEL */
1234 1237                  sa = strtoul(p, &np, 10);
1235 1238                  if (p == np) {
1236 1239                          err = EINVAL;
1237 1240                          goto out;
1238 1241                  }
1239 1242  #endif  /* _KERNEL */
1240 1243                  sid->sid_subauthvec[i] = (uint32_t)sa;
1241 1244                  p = np;
1242 1245          }
1243 1246          if (*p != '\0')
1244 1247                  goto out;
1245 1248          if (ridp != NULL)
1246 1249                  sid->sid_subauthvec[i] = *ridp;
1247 1250          err = 0;
1248 1251  
1249 1252  out:
1250 1253          if (err)
1251 1254                  FREESZ(sid, size);
1252 1255          else
1253 1256                  *osidp = sid;
1254 1257  
1255 1258          return (err);
1256 1259  }
1257 1260  
1258 1261  /*
1259 1262   * The idmap API is _almost_ the same between
1260 1263   * kernel and user-level.  But not quite...
1261 1264   * Hope this improves readability below.
1262 1265   */
1263 1266  #ifdef  _KERNEL
1264 1267  
1265 1268  #define I_getsidbyuid(GH, UID, SPP, RP, ST) \
1266 1269          kidmap_batch_getsidbyuid(GH, UID, SPP, RP, ST)
1267 1270  
1268 1271  #define I_getsidbygid(GH, GID, SPP, RP, ST) \
1269 1272          kidmap_batch_getsidbygid(GH, GID, SPP, RP, ST)
1270 1273  
1271 1274  #else /* _KERNEL */
1272 1275  
1273 1276  #define I_getsidbyuid(GH, UID, SPP, RP, ST) \
1274 1277          idmap_get_sidbyuid(GH, UID, 0, SPP, RP, ST)
1275 1278  
1276 1279  #define I_getsidbygid(GH, GID, SPP, RP, ST) \
1277 1280          idmap_get_sidbygid(GH, GID, 0, SPP, RP, ST)
1278 1281  
1279 1282  #endif /* _KERNEL */
1280 1283  
1281 1284  struct mapinfo2sid {
1282 1285          /* Yet another kernel vs. user difference. */
1283 1286  #ifdef  _KERNEL
1284 1287          const char *mi_dsid;    /* domain SID */
1285 1288  #else /* _KERNEL */
1286 1289          char *mi_dsid;
1287 1290  #endif /* _KERNEL */
1288 1291          uint32_t mi_rid;        /* relative ID */
1289 1292          idmap_stat mi_status;
1290 1293  };
1291 1294  
1292 1295  /*
1293 1296   * Build an idmap request.  Cleanup is
1294 1297   * handled by the caller (error or not)
1295 1298   */
1296 1299  static int
1297 1300  mkrq_idmap_ux2sid(
1298 1301          idmap_get_handle_t *idmap_gh,
1299 1302          struct mapinfo2sid *mip,
1300 1303          uid_t   uid, /* or gid */
1301 1304          int req_type)
1302 1305  {
1303 1306          idmap_stat      idms;
1304 1307  
1305 1308          switch (req_type) {
1306 1309  
1307 1310          case IDM_TYPE_USER:
1308 1311                  if (uid == (uid_t)-1)
1309 1312                          return (EINVAL);
1310 1313                  idms = I_getsidbyuid(idmap_gh, uid,
1311 1314                      &mip->mi_dsid, &mip->mi_rid, &mip->mi_status);
1312 1315                  break;
1313 1316  
1314 1317          case IDM_TYPE_GROUP:
1315 1318                  if (uid == (uid_t)-1)
1316 1319                          return (EINVAL);
1317 1320                  idms = I_getsidbygid(idmap_gh, uid,
1318 1321                      &mip->mi_dsid, &mip->mi_rid, &mip->mi_status);
1319 1322                  break;
1320 1323  
1321 1324          case IDM_EVERYONE:
1322 1325                  mip->mi_dsid = "S-1-1";
1323 1326                  mip->mi_rid = 0;
1324 1327                  mip->mi_status = 0;
1325 1328                  idms = IDMAP_SUCCESS;
1326 1329                  break;
1327 1330  
1328 1331          default:
1329 1332                  idms = IDMAP_ERR_OTHER;
1330 1333                  break;
1331 1334          }
1332 1335  
1333 1336          if (idms != IDMAP_SUCCESS)
1334 1337                  return (EINVAL);
1335 1338  
1336 1339          return (0);
1337 1340  }
1338 1341  
1339 1342  /*
1340 1343   * Convert a ZFS ACE to an NT ACE.
1341 1344   * ACE type was already validated.
1342 1345   */
1343 1346  static int
1344 1347  zace2ntace(i_ntace_t **ntacep, ace_t *zacep, struct mapinfo2sid *mip)
1345 1348  {
1346 1349          const struct zaf2naf *znaf;
1347 1350          uint8_t aflags;
1348 1351          uint16_t alloc_size;
1349 1352          uint32_t rights;
1350 1353          i_ntace_t *ntace = NULL;
1351 1354          i_ntsid_t *sid = NULL;
1352 1355          int error;
1353 1356  
1354 1357          if (mip->mi_dsid == NULL || mip->mi_status != 0) {
1355 1358                  return (EINVAL);
1356 1359          }
1357 1360  
1358 1361          /*
1359 1362           * Translate ZFS ACE flags to NT ACE flags.
1360 1363           */
1361 1364          aflags = 0;
1362 1365          for (znaf = smbfs_zaf2naf; znaf->za_flag; znaf++)
1363 1366                  if (zacep->a_flags & znaf->za_flag)
1364 1367                          aflags |= znaf->na_flag;
1365 1368  
1366 1369          /*
1367 1370           * The access rights bits are OK as-is.
1368 1371           */
1369 1372          rights = zacep->a_access_mask;
1370 1373  
1371 1374          /*
1372 1375           * Make sure we can get the SID.
1373 1376           * Note: allocates sid.
1374 1377           */
1375 1378          error = smbfs_str2sid(mip->mi_dsid, &mip->mi_rid, &sid);
1376 1379          if (error)
1377 1380                  return (error);
1378 1381  
1379 1382          /*
1380 1383           * Allocate the NT ACE and fill it in.
1381 1384           */
1382 1385          alloc_size = sizeof (i_ntace_v2_t);
1383 1386          if ((ntace = MALLOC(alloc_size)) == NULL) {
1384 1387                  ifree_sid(sid);
1385 1388                  return (ENOMEM);
1386 1389          }
1387 1390          bzero(ntace, alloc_size);
1388 1391  
1389 1392          ntace->ace_hdr.ace_type = zacep->a_type;
1390 1393          ntace->ace_hdr.ace_flags = aflags;
1391 1394          ntace->ace_hdr.ace_size = alloc_size;
1392 1395          ntace->ace_v2.ace_rights = rights;
1393 1396          ntace->ace_v2.ace_sid = sid;
1394 1397  
1395 1398          *ntacep = ntace;
1396 1399          return (0);
1397 1400  }
1398 1401  
1399 1402  /*
1400 1403   * Convert a ZFS-style ACL to an internal SD.
1401 1404   * Set owner/group too if selector indicates.
  
    | 
      ↓ open down ↓ | 
    162 lines elided | 
    
      ↑ open up ↑ | 
  
1402 1405   * Always need to pass uid+gid, either the new
1403 1406   * (when setting them) or existing, so that any
1404 1407   * owner@ or group@ ACEs can be translated.
1405 1408   *
1406 1409   * This makes two passes over the ZFS ACL.  The first builds a
1407 1410   * "batch" request for idmap with results in mapinfo, and the
1408 1411   * second builds the NT SD using the idmap SID results.
1409 1412   */
1410 1413  int
1411 1414  smbfs_acl_zfs2sd(
1412      -#ifdef  _KERNEL
     1415 +#if defined(_KERNEL) || defined(_FAKE_KERNEL)
1413 1416          vsecattr_t *acl_info,
1414 1417  #else /* _KERNEL */
1415 1418          acl_t *acl_info,
1416 1419  #endif /* _KERNEL */
1417 1420          uid_t own_uid,
1418 1421          gid_t own_gid,
1419 1422          uint32_t selector,
1420 1423          i_ntsd_t **sdp)
1421 1424  {
1422 1425          struct mapinfo2sid *mip, *mip_acl, *mapinfo = NULL;
1423 1426          int aclsz, error, i, mapcnt;
1424 1427          int dacl_acecnt = 0;
1425 1428          int sacl_acecnt = 0;
1426 1429          int zacecnt = 0;
1427 1430          ace_t *zacevec = NULL;
1428 1431          ace_t *zacep;
1429 1432          i_ntsd_t *sd = NULL;
1430 1433          i_ntacl_t *acl = NULL;
1431 1434          i_ntace_t **acep = NULL;
1432 1435          idmap_get_handle_t *idmap_gh = NULL;
1433 1436          idmap_stat      idms;
1434 1437  
1435 1438          /*
1436 1439           * First, get all the UID+GID to SID mappings.
1437 1440           * How many?  Also sanity checks.
1438 1441           */
1439 1442          mapcnt = 0;
1440 1443          if (selector & OWNER_SECURITY_INFORMATION) {
1441 1444                  if (own_uid == (uid_t)-1)
1442 1445                          return (EINVAL);
1443 1446                  mapcnt++;
1444 1447          }
1445 1448          if (selector & GROUP_SECURITY_INFORMATION) {
1446 1449                  if (own_gid == (gid_t)-1)
1447 1450                          return (EINVAL);
  
    | 
      ↓ open down ↓ | 
    25 lines elided | 
    
      ↑ open up ↑ | 
  
1448 1451                  mapcnt++;
1449 1452          }
1450 1453          if (selector & (DACL_SECURITY_INFORMATION |
1451 1454              SACL_SECURITY_INFORMATION)) {
1452 1455                  if (acl_info == NULL)
1453 1456                          return (EINVAL);
1454 1457                  if (own_uid == (uid_t)-1)
1455 1458                          return (EINVAL);
1456 1459                  if (own_gid == (gid_t)-1)
1457 1460                          return (EINVAL);
1458      -#ifdef  _KERNEL
     1461 +#if defined(_KERNEL) || defined(_FAKE_KERNEL)
1459 1462                  if ((acl_info->vsa_mask & VSA_ACE) == 0)
1460 1463                          return (EINVAL);
1461 1464                  zacecnt = acl_info->vsa_aclcnt;
1462 1465                  zacevec = acl_info->vsa_aclentp;
1463 1466  #else   /* _KERNEL */
1464 1467                  if (acl_info->acl_type != ACE_T ||
1465 1468                      acl_info->acl_entry_size != sizeof (ace_t))
1466 1469                          return (EINVAL);
1467 1470                  zacecnt = acl_info->acl_cnt;
1468 1471                  zacevec = acl_info->acl_aclp;
1469 1472  #endif  /* _KERNEL */
1470 1473                  if (zacecnt == 0 || zacevec == NULL)
1471 1474                          return (EINVAL);
1472 1475                  mapcnt += zacecnt;
1473 1476          }
1474 1477          if (mapcnt == 0)
1475 1478                  return (EINVAL);
1476 1479          mapinfo = MALLOC(mapcnt * sizeof (*mapinfo));
1477 1480          if (mapinfo == NULL)
1478 1481                  return (ENOMEM);
1479 1482          bzero(mapinfo, mapcnt * sizeof (*mapinfo));
1480 1483          /* no more returns until errout */
1481 1484  
1482 1485          /*
1483 1486           * Get an imap "batch" request handle.
1484 1487           */
1485 1488  #ifdef  _KERNEL
1486 1489          idmap_gh = kidmap_get_create(curproc->p_zone);
1487 1490  #else /* _KERNEL */
1488 1491          idms = idmap_get_create(&idmap_gh);
1489 1492          if (idms != IDMAP_SUCCESS) {
1490 1493                  error = ENOTACTIVE;
1491 1494                  goto errout;
1492 1495          }
1493 1496  #endif /* _KERNEL */
1494 1497  
1495 1498          /*
1496 1499           * Build our request to the idmap deamon,
1497 1500           * getting SIDs for every Unix UID/GID.
1498 1501           * Also count DACL and SACL ACEs here.
1499 1502           */
1500 1503          mip = mapinfo;
1501 1504          if (selector & OWNER_SECURITY_INFORMATION) {
1502 1505                  error = mkrq_idmap_ux2sid(idmap_gh, mip,
1503 1506                      own_uid, IDM_TYPE_USER);
1504 1507                  if (error)
1505 1508                          goto errout;
1506 1509                  mip++;
1507 1510          }
1508 1511          if (selector & GROUP_SECURITY_INFORMATION) {
1509 1512                  error = mkrq_idmap_ux2sid(idmap_gh, mip,
1510 1513                      own_gid, IDM_TYPE_GROUP);
1511 1514                  if (error)
1512 1515                          goto errout;
1513 1516                  mip++;
1514 1517          }
1515 1518          if (selector & (DACL_SECURITY_INFORMATION |
1516 1519              SACL_SECURITY_INFORMATION)) {
1517 1520                  int rqtype;
1518 1521                  uid_t uid;
1519 1522  
1520 1523                  zacep = zacevec;
1521 1524                  for (i = 0; i < zacecnt; i++) {
1522 1525  
1523 1526                          switch (zacep->a_type) {
1524 1527                          case ACE_ACCESS_ALLOWED_ACE_TYPE:
1525 1528                          case ACE_ACCESS_DENIED_ACE_TYPE:
1526 1529                                  dacl_acecnt++;
1527 1530                                  break;
1528 1531                          case ACE_SYSTEM_AUDIT_ACE_TYPE:
1529 1532                          case ACE_SYSTEM_ALARM_ACE_TYPE:
1530 1533                                  sacl_acecnt++;
1531 1534                                  break;
1532 1535                          /* other types todo */
1533 1536                          }
1534 1537  
1535 1538                          if (zacep->a_flags & ACE_EVERYONE) {
1536 1539                                  rqtype = IDM_EVERYONE;
1537 1540                                  uid = (uid_t)-1;
1538 1541                          } else if (zacep->a_flags & ACE_GROUP) {
1539 1542                                  /* owning group (a_who = -1) */
1540 1543                                  rqtype = IDM_TYPE_GROUP;
1541 1544                                  uid = (uid_t)own_gid;
1542 1545                          } else if (zacep->a_flags & ACE_OWNER) {
1543 1546                                  /* owning user (a_who = -1) */
1544 1547                                  rqtype = IDM_TYPE_USER;
1545 1548                                  uid = (uid_t)own_uid;
1546 1549                          } else if (zacep->a_flags & ACE_IDENTIFIER_GROUP) {
1547 1550                                  /* regular group */
1548 1551                                  rqtype = IDM_TYPE_GROUP;
1549 1552                                  uid = zacep->a_who;
1550 1553                          } else {
1551 1554                                  rqtype = IDM_TYPE_USER;
1552 1555                                  uid = zacep->a_who;
1553 1556                          }
1554 1557  
1555 1558                          error = mkrq_idmap_ux2sid(idmap_gh, mip, uid, rqtype);
1556 1559                          if (error)
1557 1560                                  goto errout;
1558 1561                          zacep++;
1559 1562                          mip++;
1560 1563                  }
1561 1564          }
1562 1565  
1563 1566          idms = I_getmappings(idmap_gh);
1564 1567          if (idms != IDMAP_SUCCESS) {
1565 1568                  /* creative error choice */
1566 1569                  error = EIDRM;
1567 1570                  goto errout;
1568 1571          }
1569 1572  
1570 1573          /*
1571 1574           * With any luck, we now have a Windows SID for
1572 1575           * every Unix UID or GID in the NFS/ZFS ACL.
1573 1576           * The remaining work is just format conversion,
1574 1577           * memory allocation, etc.
1575 1578           */
1576 1579          if ((sd = MALLOC(sizeof (*sd))) == NULL) {
1577 1580                  error = ENOMEM;
1578 1581                  goto errout;
1579 1582          }
1580 1583          bzero(sd, sizeof (*sd));
1581 1584          sd->sd_revision = NT_SD_REVISION;
1582 1585  
1583 1586          mip = mapinfo;
1584 1587          if (selector & OWNER_SECURITY_INFORMATION) {
1585 1588                  error = smbfs_str2sid(mip->mi_dsid, &mip->mi_rid,
1586 1589                      &sd->sd_owner);
1587 1590                  mip++;
1588 1591          }
1589 1592          if (selector & GROUP_SECURITY_INFORMATION) {
1590 1593                  error = smbfs_str2sid(mip->mi_dsid, &mip->mi_rid,
1591 1594                      &sd->sd_group);
1592 1595                  mip++;
1593 1596          }
1594 1597  
1595 1598          /*
1596 1599           * If setting both DACL and SACL, we will
1597 1600           * make two passes starting here in mapinfo.
1598 1601           */
1599 1602          mip_acl = mip;
1600 1603  
1601 1604          if (selector & DACL_SECURITY_INFORMATION) {
1602 1605                  /*
1603 1606                   * Caller wants to set the DACL.
1604 1607                   */
1605 1608                  aclsz = I_ACL_SIZE(dacl_acecnt);
1606 1609                  if ((acl = MALLOC(aclsz)) == NULL) {
1607 1610                          error = ENOMEM;
1608 1611                          goto errout;
1609 1612                  }
1610 1613                  bzero(acl, aclsz);
1611 1614  
1612 1615                  acl->acl_revision = NT_ACL_REVISION;
1613 1616                  acl->acl_acecount = (uint16_t)dacl_acecnt;
1614 1617                  acep = &acl->acl_acevec[0];
1615 1618  
1616 1619                  /* 1st pass - scan for DACL ACE types. */
1617 1620                  mip = mip_acl;
1618 1621                  zacep = zacevec;
1619 1622                  for (i = 0; i < zacecnt; i++) {
1620 1623  
1621 1624                          switch (zacep->a_type) {
1622 1625                          case ACE_ACCESS_ALLOWED_ACE_TYPE:
1623 1626                          case ACE_ACCESS_DENIED_ACE_TYPE:
1624 1627                                  error = zace2ntace(acep, zacep, mip);
1625 1628                                  if (error != 0)
1626 1629                                          goto errout;
1627 1630                                  acep++;
1628 1631                                  break;
1629 1632  
1630 1633                          case ACE_SYSTEM_AUDIT_ACE_TYPE:
1631 1634                          case ACE_SYSTEM_ALARM_ACE_TYPE:
1632 1635                                  break;
1633 1636                          /* other types todo */
1634 1637                          }
1635 1638                          zacep++;
1636 1639                          mip++;
1637 1640                  }
1638 1641                  sd->sd_dacl = acl;
1639 1642                  acl = NULL;
1640 1643                  sd->sd_flags |= SD_DACL_PRESENT;
1641 1644          }
1642 1645  
1643 1646          if (selector & SACL_SECURITY_INFORMATION) {
1644 1647                  /*
1645 1648                   * Caller wants to set the SACL.
1646 1649                   */
1647 1650                  aclsz = I_ACL_SIZE(sacl_acecnt);
1648 1651                  if ((acl = MALLOC(aclsz)) == NULL) {
1649 1652                          error = ENOMEM;
1650 1653                          goto errout;
1651 1654                  }
1652 1655                  bzero(acl, aclsz);
1653 1656  
1654 1657                  acl->acl_revision = NT_ACL_REVISION;
1655 1658                  acl->acl_acecount = (uint16_t)sacl_acecnt;
1656 1659                  acep = &acl->acl_acevec[0];
1657 1660  
1658 1661                  /* 2nd pass - scan for SACL ACE types. */
1659 1662                  mip = mip_acl;
1660 1663                  zacep = zacevec;
1661 1664                  for (i = 0; i < zacecnt; i++) {
1662 1665  
1663 1666                          switch (zacep->a_type) {
1664 1667                          case ACE_ACCESS_ALLOWED_ACE_TYPE:
1665 1668                          case ACE_ACCESS_DENIED_ACE_TYPE:
1666 1669                                  break;
1667 1670  
1668 1671                          case ACE_SYSTEM_AUDIT_ACE_TYPE:
1669 1672                          case ACE_SYSTEM_ALARM_ACE_TYPE:
1670 1673                                  error = zace2ntace(acep, zacep, mip);
1671 1674                                  if (error != 0)
1672 1675                                          goto errout;
1673 1676                                  acep++;
1674 1677                                  break;
1675 1678                          /* other types todo */
1676 1679                          }
1677 1680                          zacep++;
1678 1681                          mip++;
1679 1682                  }
1680 1683                  sd->sd_sacl = acl;
1681 1684                  acl = NULL;
1682 1685                  sd->sd_flags |= SD_SACL_PRESENT;
1683 1686          }
1684 1687  
1685 1688          *sdp = sd;
1686 1689          error = 0;
1687 1690  
1688 1691  errout:
1689 1692          if (error != 0) {
1690 1693                  if (acl != NULL)
1691 1694                          ifree_acl(acl);
1692 1695                  if (sd != NULL)
1693 1696                          smbfs_acl_free_sd(sd);
1694 1697          }
1695 1698          if (mapinfo != NULL)
1696 1699                  FREESZ(mapinfo, mapcnt * sizeof (*mapinfo));
1697 1700  #ifdef  _KERNEL
1698 1701          if (idmap_gh != NULL)
1699 1702                  kidmap_get_destroy(idmap_gh);
1700 1703  #else /* _KERNEL */
1701 1704          if (idmap_gh != NULL)
1702 1705                  idmap_get_destroy(idmap_gh);
1703 1706  #endif /* _KERNEL */
1704 1707  
1705 1708          return (error);
1706 1709  }
  
    | 
      ↓ open down ↓ | 
    238 lines elided | 
    
      ↑ open up ↑ | 
  
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX