Print this page
NEX-17589 Get "too high" smbd error when copy big file to cifs share
Reviewed by: Joyce McIntosh <joyce.mcintosh@nexenta.com>
Reviewed by: Yuri Pankov <yuri.pankov@nexenta.com>
Reviewed by: Evan Layton <evan.layton@nexenta.com>
Reviewed by: Matt Barden <matt.barden@nexenta.com>
NEX-17795 SMB logon should tolerate idmap problems
Reviewed by: Matt Barden <matt.barden@nexenta.com>
Reviewed by: Joyce McIntosh <joyce.mcintosh@nexenta.com>
Reviewed by: Yuri Pankov <yuri.pankov@nexenta.com>
NEX-4083 Upstream changes from illumos 5917 and 5995
Reviewed by: Matt Barden <matt.barden@nexenta.com>
Reviewed by: Kevin Crowe <kevin.crowe@nexenta.com>
Reviewed by: Yuri Pankov <yuri.pankov@nexenta.com>
NEX-2460 libfksmbd should not link with libsmb

Split Close
Expand all
Collapse all
          --- old/usr/src/lib/smbsrv/libfksmbsrv/common/fksmb_idmap.c
          +++ new/usr/src/lib/smbsrv/libfksmbsrv/common/fksmb_idmap.c
↓ open down ↓ 12 lines elided ↑ open up ↑
  13   13   * When distributing Covered Code, include this CDDL HEADER in each
  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) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
  23      - * Copyright 2014 Nexenta Systems, Inc.  All rights reserved.
       23 + * Copyright 2018 Nexenta Systems, Inc.  All rights reserved.
  24   24   */
  25   25  
  26   26  /*
  27   27   * SMB server interface to idmap
  28   28   * (smb_idmap_get..., smb_idmap_batch_...)
  29   29   *
  30      - * There are three implementations of this interface:
  31      - *      uts/common/fs/smbsrv/smb_idmap.c (smbsrv kmod)
  32      - *      lib/smbsrv/libfksmbsrv/common/fksmb_idmap.c (libfksmbsrv)
  33      - *      lib/smbsrv/libsmb/common/smb_idmap.c (libsmb)
       30 + * There are three implementations of this interface.
       31 + * This is the "fake kernel" version of these routines.  See also:
       32 + * $SRC/lib/smbsrv/libsmb/common/smb_idmap.c
       33 + * $SRC/uts/common/fs/smbsrv/smb_idmap.c
  34   34   *
  35   35   * There are enough differences (relative to the code size)
  36   36   * that it's more trouble than it's worth to merge them.
  37   37   *
  38   38   * This one differs from the others in that it:
  39   39   *      calls idmap interfaces (libidmap)
  40   40   *      uses kmem_... interfaces (libfakekernel)
  41   41   *      uses cmn_err instead of syslog, etc.
       42 + * The code in this variant looks a lot like the one in libsmb.
  42   43   */
  43   44  
  44   45  #include <sys/param.h>
  45   46  #include <sys/types.h>
  46   47  
  47   48  #include <smbsrv/smb_kproto.h>
  48   49  #include <smbsrv/smb_idmap.h>
  49   50  
  50   51  static int smb_idmap_batch_binsid(smb_idmap_batch_t *sib);
  51   52  
↓ open down ↓ 89 lines elided ↑ open up ↑
 141  142  /*
 142  143   * smb_idmap_batch_create
 143  144   *
 144  145   * Creates and initializes the context for batch ID mapping.
 145  146   */
 146  147  idmap_stat
 147  148  smb_idmap_batch_create(smb_idmap_batch_t *sib, uint16_t nmap, int flags)
 148  149  {
 149  150          idmap_stat      stat;
 150  151  
 151      -        if (!sib)
 152      -                return (IDMAP_ERR_ARG);
      152 +        ASSERT(sib != NULL);
 153  153  
 154  154          bzero(sib, sizeof (smb_idmap_batch_t));
 155  155          stat = idmap_get_create(&sib->sib_idmaph);
 156  156  
 157  157          if (stat != IDMAP_SUCCESS) {
 158  158                  smb_idmap_check("idmap_get_create", stat);
 159  159                  return (stat);
 160  160          }
 161  161  
 162  162          sib->sib_flags = flags;
↓ open down ↓ 5 lines elided ↑ open up ↑
 168  168  }
 169  169  
 170  170  /*
 171  171   * smb_idmap_batch_destroy
 172  172   *
 173  173   * Frees the batch ID mapping context.
 174  174   */
 175  175  void
 176  176  smb_idmap_batch_destroy(smb_idmap_batch_t *sib)
 177  177  {
      178 +        char *domsid;
 178  179          int i;
 179  180  
 180      -        if (sib == NULL)
 181      -                return;
      181 +        ASSERT(sib != NULL);
      182 +        ASSERT(sib->sib_maps != NULL);
 182  183  
 183  184          if (sib->sib_idmaph) {
 184  185                  idmap_get_destroy(sib->sib_idmaph);
 185  186                  sib->sib_idmaph = NULL;
 186  187          }
 187  188  
 188      -        if (sib->sib_maps == NULL)
 189      -                return;
 190      -
 191  189          if (sib->sib_flags & SMB_IDMAP_ID2SID) {
 192  190                  /*
 193  191                   * SIDs are allocated only when mapping
 194  192                   * UID/GID to SIDs
 195  193                   */
 196  194                  for (i = 0; i < sib->sib_nmap; i++) {
 197  195                          smb_sid_free(sib->sib_maps[i].sim_sid);
 198  196                          /* from strdup() in libidmap */
 199  197                          free(sib->sib_maps[i].sim_domsid);
 200  198                  }
      199 +        } else if (sib->sib_flags & SMB_IDMAP_SID2ID) {
      200 +                /*
      201 +                 * SID prefixes are allocated only when mapping
      202 +                 * SIDs to UID/GID
      203 +                 */
      204 +                for (i = 0; i < sib->sib_nmap; i++) {
      205 +                        domsid = sib->sib_maps[i].sim_domsid;
      206 +                        if (domsid)
      207 +                                smb_mem_free(domsid);
      208 +                }
 201  209          }
 202  210  
 203  211          if (sib->sib_size && sib->sib_maps) {
 204  212                  kmem_free(sib->sib_maps, sib->sib_size);
 205  213                  sib->sib_maps = NULL;
 206  214          }
 207  215  }
 208  216  
 209  217  /*
 210  218   * smb_idmap_batch_getid
↓ open down ↓ 7 lines elided ↑ open up ↑
 218  226   * if it's unknown it'll be returned in sim->sim_idtype.
 219  227   */
 220  228  idmap_stat
 221  229  smb_idmap_batch_getid(idmap_get_handle_t *idmaph, smb_idmap_t *sim,
 222  230      smb_sid_t *sid, int idtype)
 223  231  {
 224  232          char sidstr[SMB_SID_STRSZ];
 225  233          idmap_stat stat;
 226  234          int flag = 0;
 227  235  
 228      -        if (idmaph == NULL || sim == NULL || sid == NULL)
 229      -                return (IDMAP_ERR_ARG);
      236 +        ASSERT(idmaph != NULL);
      237 +        ASSERT(sim != NULL);
      238 +        ASSERT(sid != NULL);
 230  239  
 231  240          smb_sid_tostr(sid, sidstr);
 232  241          if (smb_sid_splitstr(sidstr, &sim->sim_rid) != 0)
 233  242                  return (IDMAP_ERR_SID);
 234      -        sim->sim_domsid = sidstr;
      243 +        /* Note: Free sim_domsid in smb_idmap_batch_destroy */
      244 +        sim->sim_domsid = smb_mem_strdup(sidstr);
 235  245          sim->sim_idtype = idtype;
 236  246  
 237  247          switch (idtype) {
 238  248          case SMB_IDMAP_USER:
 239  249                  stat = idmap_get_uidbysid(idmaph, sim->sim_domsid,
 240  250                      sim->sim_rid, flag, sim->sim_id, &sim->sim_stat);
 241  251                  smb_idmap_check("idmap_get_uidbysid", stat);
 242  252                  break;
 243  253  
 244  254          case SMB_IDMAP_GROUP:
↓ open down ↓ 7 lines elided ↑ open up ↑
 252  262                      sim->sim_rid, flag, sim->sim_id, &sim->sim_idtype,
 253  263                      &sim->sim_stat);
 254  264                  smb_idmap_check("idmap_get_pidbysid", stat);
 255  265                  break;
 256  266  
 257  267          default:
 258  268                  stat = IDMAP_ERR_ARG;
 259  269                  break;
 260  270          }
 261  271  
 262      -        /* This was copied by idmap_get_Xbysid. */
 263      -        sim->sim_domsid = NULL;
 264      -
 265  272          return (stat);
 266  273  }
 267  274  
 268  275  /*
 269  276   * smb_idmap_batch_getsid
 270  277   *
 271  278   * Queue a request to map the given UID/GID to a SID.
 272  279   *
 273  280   * sim->sim_domsid and sim->sim_rid will contain the mapping
 274  281   * result upon successful process of the batched request.
      282 + * Stash the type for error reporting (caller saves the ID).
      283 + *
 275  284   * NB: sim_domsid allocated by strdup, here or in libidmap
 276  285   */
 277  286  idmap_stat
 278  287  smb_idmap_batch_getsid(idmap_get_handle_t *idmaph, smb_idmap_t *sim,
 279  288      uid_t id, int idtype)
 280  289  {
 281  290          idmap_stat stat;
 282  291          int flag = 0;
 283  292  
 284  293          if (!idmaph || !sim)
 285  294                  return (IDMAP_ERR_ARG);
 286  295  
      296 +        sim->sim_idtype = idtype;
 287  297          switch (idtype) {
 288  298          case SMB_IDMAP_USER:
 289  299                  stat = idmap_get_sidbyuid(idmaph, id, flag,
 290  300                      &sim->sim_domsid, &sim->sim_rid, &sim->sim_stat);
 291  301                  smb_idmap_check("idmap_get_sidbyuid", stat);
 292  302                  break;
 293  303  
 294  304          case SMB_IDMAP_GROUP:
 295  305                  stat = idmap_get_sidbygid(idmaph, id, flag,
 296  306                      &sim->sim_domsid, &sim->sim_rid, &sim->sim_stat);
↓ open down ↓ 18 lines elided ↑ open up ↑
 315  325  
 316  326          case SMB_IDMAP_EVERYONE:
 317  327                  /* Everyone S-1-1-0 */
 318  328                  sim->sim_domsid = strdup(NT_WORLD_AUTH_SIDSTR);
 319  329                  sim->sim_rid = 0;
 320  330                  sim->sim_stat = IDMAP_SUCCESS;
 321  331                  stat = IDMAP_SUCCESS;
 322  332                  break;
 323  333  
 324  334          default:
      335 +                ASSERT(0);
 325  336                  return (IDMAP_ERR_ARG);
 326  337          }
 327  338  
 328  339          return (stat);
 329  340  }
 330  341  
      342 +static void
      343 +smb_idmap_bgm_report(smb_idmap_batch_t *sib, smb_idmap_t *sim)
      344 +{
      345 +
      346 +        if ((sib->sib_flags & SMB_IDMAP_ID2SID) != 0) {
      347 +                /*
      348 +                 * Note: The ID and type we asked idmap to map
      349 +                 * were saved in *sim_id and sim_idtype.
      350 +                 */
      351 +                uint_t id = (sim->sim_id == NULL) ?
      352 +                    0 : (uint_t)*sim->sim_id;
      353 +                cmn_err(CE_WARN, "Can't get SID for "
      354 +                    "ID=%u type=%d, status=%d",
      355 +                    id, sim->sim_idtype, sim->sim_stat);
      356 +        }
      357 +
      358 +        if ((sib->sib_flags & SMB_IDMAP_SID2ID) != 0) {
      359 +                cmn_err(CE_WARN, "Can't get ID for SID %s-%u, status=%d",
      360 +                    sim->sim_domsid, sim->sim_rid, sim->sim_stat);
      361 +        }
      362 +}
      363 +
 331  364  /*
 332  365   * smb_idmap_batch_getmappings
 333  366   *
 334  367   * trigger ID mapping service to get the mappings for queued
 335  368   * requests.
 336  369   *
 337  370   * Checks the result of all the queued requests.
 338  371   */
 339  372  idmap_stat
 340  373  smb_idmap_batch_getmappings(smb_idmap_batch_t *sib)
↓ open down ↓ 5 lines elided ↑ open up ↑
 346  379          if ((stat = idmap_get_mappings(sib->sib_idmaph)) != IDMAP_SUCCESS) {
 347  380                  smb_idmap_check("idmap_get_mappings", stat);
 348  381                  return (stat);
 349  382          }
 350  383  
 351  384          /*
 352  385           * Check the status for all the queued requests
 353  386           */
 354  387          for (i = 0, sim = sib->sib_maps; i < sib->sib_nmap; i++, sim++) {
 355  388                  if (sim->sim_stat != IDMAP_SUCCESS) {
 356      -                        if (sib->sib_flags == SMB_IDMAP_SID2ID) {
 357      -                                cmn_err(CE_NOTE, "[%d] %d (%d)",
 358      -                                    sim->sim_idtype,
 359      -                                    sim->sim_rid,
 360      -                                    sim->sim_stat);
      389 +                        smb_idmap_bgm_report(sib, sim);
      390 +                        if ((sib->sib_flags & SMB_IDMAP_SKIP_ERRS) == 0) {
      391 +                                return (sim->sim_stat);
 361  392                          }
 362      -                        return (sim->sim_stat);
 363  393                  }
 364  394          }
 365  395  
 366  396          if (smb_idmap_batch_binsid(sib) != 0)
 367  397                  stat = IDMAP_ERR_OTHER;
 368  398  
 369  399          return (stat);
 370  400  }
 371  401  
 372  402  /*
↓ open down ↓ 9 lines elided ↑ open up ↑
 382  412          smb_sid_t *sid;
 383  413          smb_idmap_t *sim;
 384  414          int i;
 385  415  
 386  416          if (sib->sib_flags & SMB_IDMAP_SID2ID)
 387  417                  /* This operation is not required */
 388  418                  return (0);
 389  419  
 390  420          sim = sib->sib_maps;
 391  421          for (i = 0; i < sib->sib_nmap; sim++, i++) {
      422 +                ASSERT(sim->sim_domsid != NULL);
 392  423                  if (sim->sim_domsid == NULL)
 393  424                          return (-1);
 394  425  
 395  426                  sid = smb_sid_fromstr(sim->sim_domsid);
 396  427                  if (sid == NULL)
 397  428                          return (-1);
 398  429  
 399  430                  sim->sim_sid = smb_sid_splice(sid, sim->sim_rid);
 400  431                  smb_sid_free(sid);
 401  432          }
 402  433  
 403  434          return (0);
 404  435  }
    
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX