Print this page
    
NEX-19057 All zfs/nfs/smb threads in door calls to idle idmap
Reviewed by: Matt Barden <matt.barden@nexenta.com>
Reviewed by: Yuri Pankov <yuri.pankov@nexenta.com>
Reviewed by: Roman Strashkin <roman.strashkin@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-2225 Unable to join NexentaStor to 2008 AD
NEX-2286 smbadm join error messages are uninformative
NEX-1638 Updated DC Locator
 Includes work by: matt.barden@nexenta.com, kevin.crowe@nexenta.com
SMB-149 mount.cifs RedHat\Centos 6 doesn't work with default security options (fix lint)
SMB-149 mount.cifs RedHat\Centos 6 doesn't work with default security options
SMB-136 Snapshots not visible in Windows previous versions
SMB-39 Use AF_UNIX pipes for RPC
SMB-50 User-mode SMB server
 Includes work by these authors:
 Thomas Keiser <thomas.keiser@nexenta.com>
 Albert Lee <trisk@nexenta.com>
    
      
        | Split | 
	Close | 
      
      | Expand all | 
      | Collapse all | 
    
    
          --- old/usr/src/cmd/smbsrv/smbd/smbd_doorsvc.c
          +++ new/usr/src/cmd/smbsrv/smbd/smbd_doorsvc.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   *
  
    | 
      ↓ 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 2019 Nexenta Systems, Inc.  All rights reserved.
  24   24   */
  25   25  
  26   26  #include <sys/list.h>
  27   27  #include <assert.h>
  28   28  #include <alloca.h>
  29   29  #include <door.h>
  30   30  #include <errno.h>
  31   31  #include <syslog.h>
  32   32  #include <unistd.h>
  33   33  #include <stdio.h>
  34   34  #include <synch.h>
  35   35  #include <string.h>
  36   36  #include <stdlib.h>
  37   37  #include <sys/stat.h>
  38   38  #include <fcntl.h>
  39   39  #include <pthread.h>
  40   40  #include <strings.h>
  41   41  #include <note.h>
  42   42  #include <smbsrv/smb_door.h>
  43   43  #include <smbsrv/smb_xdr.h>
  44   44  #include <smbsrv/smb_token.h>
  45   45  #include <smbsrv/libmlsvc.h>
  46   46  #include <smbsrv/libsmbns.h>
  47   47  #include "smbd.h"
  48   48  
  49   49  /*
  50   50   * The list contains asynchronous requests that have been initiated
  51   51   * but have not yet been collected (via smbd_dop_async_response).
  52   52   */
  53   53  typedef struct smbd_doorsvc {
  54   54          mutex_t         sd_mutex;
  55   55          cond_t          sd_cv;
  56   56          list_t          sd_async_list;
  57   57          uint32_t        sd_async_count;
  58   58  } smbd_doorsvc_t;
  59   59  
  60   60  static int smbd_dop_null(smbd_arg_t *);
  61   61  static int smbd_dop_async_response(smbd_arg_t *);
  62   62  static int smbd_dop_user_auth_logon(smbd_arg_t *);
  63   63  static int smbd_dop_user_nonauth_logon(smbd_arg_t *);
  64   64  static int smbd_dop_user_auth_logoff(smbd_arg_t *);
  65   65  static int smbd_dop_lookup_sid(smbd_arg_t *);
  66   66  static int smbd_dop_lookup_name(smbd_arg_t *);
  67   67  static int smbd_dop_join(smbd_arg_t *);
  68   68  static int smbd_dop_get_dcinfo(smbd_arg_t *);
  69   69  static int smbd_dop_vss_get_count(smbd_arg_t *);
  70   70  static int smbd_dop_vss_get_snapshots(smbd_arg_t *);
  71   71  static int smbd_dop_vss_map_gmttoken(smbd_arg_t *);
  72   72  static int smbd_dop_ads_find_host(smbd_arg_t *);
  73   73  static int smbd_dop_quota_query(smbd_arg_t *);
  74   74  static int smbd_dop_quota_set(smbd_arg_t *);
  75   75  static int smbd_dop_dfs_get_referrals(smbd_arg_t *);
  76   76  static int smbd_dop_shr_hostaccess(smbd_arg_t *);
  77   77  static int smbd_dop_shr_exec(smbd_arg_t *);
  78   78  static int smbd_dop_notify_dc_changed(smbd_arg_t *);
  79   79  
  80   80  typedef int (*smbd_dop_t)(smbd_arg_t *);
  81   81  
  82   82  typedef struct smbd_doorop {
  83   83          smb_dopcode_t   opcode;
  84   84          smbd_dop_t      op;
  85   85  } smbd_doorop_t;
  86   86  
  87   87  smbd_doorop_t smbd_doorops[] = {
  88   88          { SMB_DR_NULL,                  smbd_dop_null },
  89   89          { SMB_DR_ASYNC_RESPONSE,        smbd_dop_async_response },
  90   90          { SMB_DR_USER_AUTH_LOGON,       smbd_dop_user_auth_logon },
  91   91          { SMB_DR_USER_NONAUTH_LOGON,    smbd_dop_user_nonauth_logon },
  92   92          { SMB_DR_USER_AUTH_LOGOFF,      smbd_dop_user_auth_logoff },
  93   93          { SMB_DR_LOOKUP_SID,            smbd_dop_lookup_sid },
  94   94          { SMB_DR_LOOKUP_NAME,           smbd_dop_lookup_name },
  95   95          { SMB_DR_JOIN,                  smbd_dop_join },
  
    | 
      ↓ open down ↓ | 
    62 lines elided | 
    
      ↑ open up ↑ | 
  
  96   96          { SMB_DR_GET_DCINFO,            smbd_dop_get_dcinfo },
  97   97          { SMB_DR_VSS_GET_COUNT,         smbd_dop_vss_get_count },
  98   98          { SMB_DR_VSS_GET_SNAPSHOTS,     smbd_dop_vss_get_snapshots },
  99   99          { SMB_DR_VSS_MAP_GMTTOKEN,      smbd_dop_vss_map_gmttoken },
 100  100          { SMB_DR_ADS_FIND_HOST,         smbd_dop_ads_find_host },
 101  101          { SMB_DR_QUOTA_QUERY,           smbd_dop_quota_query },
 102  102          { SMB_DR_QUOTA_SET,             smbd_dop_quota_set },
 103  103          { SMB_DR_DFS_GET_REFERRALS,     smbd_dop_dfs_get_referrals },
 104  104          { SMB_DR_SHR_HOSTACCESS,        smbd_dop_shr_hostaccess },
 105  105          { SMB_DR_SHR_EXEC,              smbd_dop_shr_exec },
 106      -        { SMB_DR_NOTIFY_DC_CHANGED,     smbd_dop_notify_dc_changed }
      106 +        { SMB_DR_NOTIFY_DC_CHANGED,     smbd_dop_notify_dc_changed },
      107 +        { SMB_DR_LOOKUP_LSID,           smbd_dop_lookup_sid },
      108 +        { SMB_DR_LOOKUP_LNAME,          smbd_dop_lookup_name }
 107  109  };
 108  110  
 109  111  static int smbd_ndoorop = (sizeof (smbd_doorops) / sizeof (smbd_doorops[0]));
 110  112  
 111  113  static smbd_doorsvc_t smbd_doorsvc;
 112  114  static int smbd_door_fd = -1;
 113  115  static int smbd_door_cookie = 0x534D4244;       /* SMBD */
 114  116  static smbd_door_t smbd_door_sdh;
 115  117  static char *smbd_door_name = NULL;
 116  118  
 117  119  static void smbd_door_dispatch(void *, char *, size_t, door_desc_t *, uint_t);
 118  120  static int smbd_door_dispatch_async(smbd_arg_t *);
 119  121  static void smbd_door_release_async(smbd_arg_t *);
 120  122  
 121  123  /*
 122  124   * Start the smbd door service.  Create and bind to a door.
 123  125   * Returns 0 on success. Otherwise, -1.
 124  126   */
 125  127  int
 126  128  smbd_door_start(void)
 127  129  {
 128  130          int     newfd;
 129  131  
 130  132          (void) mutex_lock(&smbd_doorsvc.sd_mutex);
 131  133  
 132  134          if (smbd_door_fd != -1) {
 133  135                  (void) fprintf(stderr, "smb_doorsrv_start: already started");
 134  136                  (void) mutex_unlock(&smbd_doorsvc.sd_mutex);
 135  137                  return (-1);
 136  138          }
 137  139  
 138  140          smbd_door_name = getenv("SMBD_DOOR_NAME");
 139  141          if (smbd_door_name == NULL)
 140  142                  smbd_door_name = SMBD_DOOR_NAME;
 141  143  
 142  144          smbd_door_init(&smbd_door_sdh, "doorsrv");
 143  145  
 144  146          list_create(&smbd_doorsvc.sd_async_list, sizeof (smbd_arg_t),
 145  147              offsetof(smbd_arg_t, lnd));
 146  148          smbd_doorsvc.sd_async_count = 0;
 147  149  
 148  150          if ((smbd_door_fd = door_create(smbd_door_dispatch,
 149  151              &smbd_door_cookie, DOOR_UNREF)) < 0) {
 150  152                  (void) fprintf(stderr, "smb_doorsrv_start: door_create: %s",
 151  153                      strerror(errno));
 152  154                  smbd_door_fd = -1;
 153  155                  (void) mutex_unlock(&smbd_doorsvc.sd_mutex);
 154  156                  return (-1);
 155  157          }
 156  158  
 157  159          (void) unlink(smbd_door_name);
 158  160  
 159  161          if ((newfd = creat(smbd_door_name, 0644)) < 0) {
 160  162                  (void) fprintf(stderr, "smb_doorsrv_start: open: %s",
 161  163                      strerror(errno));
 162  164                  (void) door_revoke(smbd_door_fd);
 163  165                  smbd_door_fd = -1;
 164  166                  (void) mutex_unlock(&smbd_doorsvc.sd_mutex);
 165  167                  return (-1);
 166  168          }
 167  169  
 168  170          (void) close(newfd);
 169  171          (void) fdetach(smbd_door_name);
 170  172  
 171  173          if (fattach(smbd_door_fd, smbd_door_name) < 0) {
 172  174                  (void) fprintf(stderr, "smb_doorsrv_start: fattach: %s",
 173  175                      strerror(errno));
 174  176                  (void) door_revoke(smbd_door_fd);
 175  177                  smbd_door_fd = -1;
 176  178                  (void) mutex_unlock(&smbd_doorsvc.sd_mutex);
 177  179                  return (-1);
 178  180          }
 179  181  
 180  182          (void) mutex_unlock(&smbd_doorsvc.sd_mutex);
 181  183          return (smbd_door_fd);
 182  184  }
 183  185  
 184  186  /*
 185  187   * Stop the smbd door service.
 186  188   */
 187  189  void
 188  190  smbd_door_stop(void)
 189  191  {
 190  192          (void) mutex_lock(&smbd_doorsvc.sd_mutex);
 191  193  
 192  194          smbd_door_fini(&smbd_door_sdh);
 193  195  
 194  196          if (smbd_door_name)
 195  197                  (void) fdetach(smbd_door_name);
 196  198  
 197  199          if (smbd_door_fd != -1) {
 198  200                  (void) door_revoke(smbd_door_fd);
 199  201                  smbd_door_fd = -1;
 200  202          }
 201  203  
 202  204          (void) mutex_unlock(&smbd_doorsvc.sd_mutex);
 203  205  }
 204  206  
 205  207  /*ARGSUSED*/
 206  208  static void
 207  209  smbd_door_dispatch(void *cookie, char *argp, size_t arg_size, door_desc_t *dp,
 208  210      uint_t n_desc)
 209  211  {
 210  212          smbd_arg_t      dop_arg;
 211  213          smb_doorhdr_t   *hdr;
 212  214          size_t          hdr_size;
 213  215          char            *rbuf = NULL;
 214  216  
 215  217          smbd_door_enter(&smbd_door_sdh);
 216  218  
 217  219          if (!smbd_online())
 218  220                  smbd_door_return(&smbd_door_sdh, NULL, 0, NULL, 0);
 219  221  
 220  222          bzero(&dop_arg, sizeof (smbd_arg_t));
 221  223          hdr = &dop_arg.hdr;
 222  224          hdr_size = xdr_sizeof(smb_doorhdr_xdr, hdr);
 223  225  
 224  226          if ((cookie != &smbd_door_cookie) || (argp == NULL) ||
 225  227              (arg_size < hdr_size)) {
 226  228                  smbd_door_return(&smbd_door_sdh, NULL, 0, NULL, 0);
 227  229          }
 228  230  
 229  231          if (smb_doorhdr_decode(hdr, (uint8_t *)argp, hdr_size) == -1) {
 230  232                  syslog(LOG_DEBUG, "smbd_door_dispatch: header decode failed");
 231  233                  smbd_door_return(&smbd_door_sdh, NULL, 0, NULL, 0);
 232  234          }
 233  235  
 234  236          if ((hdr->dh_magic != SMB_DOOR_HDR_MAGIC) || (hdr->dh_txid == 0)) {
 235  237                  syslog(LOG_DEBUG, "smbd_door_dispatch: invalid header");
 236  238                  smbd_door_return(&smbd_door_sdh, NULL, 0, NULL, 0);
 237  239          }
 238  240  
 239  241          dop_arg.opname = smb_doorhdr_opname(hdr->dh_op);
 240  242          dop_arg.data = argp + hdr_size;
 241  243          dop_arg.datalen = hdr->dh_datalen;
 242  244  
 243  245          if (hdr->dh_op == SMB_DR_ASYNC_RESPONSE) {
 244  246                  /*
 245  247                   * ASYNC_RESPONSE is used to collect the response
 246  248                   * to an async call; it cannot be an async call.
 247  249                   */
 248  250                  hdr->dh_flags &= ~SMB_DF_ASYNC;
 249  251          }
 250  252  
 251  253          if (hdr->dh_flags & SMB_DF_ASYNC) {
 252  254                  if (smbd_door_dispatch_async(&dop_arg) == 0)
 253  255                          hdr->dh_door_rc = SMB_DOP_SUCCESS;
 254  256                  else
 255  257                          hdr->dh_door_rc = SMB_DOP_NOT_CALLED;
 256  258          } else {
 257  259                  (void) smbd_door_dispatch_op(&dop_arg);
 258  260          }
 259  261  
 260  262          if ((rbuf = (char *)alloca(dop_arg.rsize + hdr_size)) == NULL) {
 261  263                  errno = ENOMEM;
 262  264                  syslog(LOG_DEBUG, "smbd_door_dispatch[%s]: alloca %m",
 263  265                      dop_arg.opname);
 264  266                  smbd_door_return(&smbd_door_sdh, NULL, 0, NULL, 0);
 265  267          }
 266  268  
 267  269          if (dop_arg.rbuf != NULL) {
 268  270                  (void) memcpy(rbuf + hdr_size, dop_arg.rbuf, dop_arg.rsize);
 269  271                  free(dop_arg.rbuf);
 270  272          }
 271  273  
 272  274          hdr->dh_datalen = dop_arg.rsize;
 273  275          (void) smb_doorhdr_encode(hdr, (uint8_t *)rbuf, hdr_size);
 274  276          dop_arg.rsize += hdr_size;
 275  277  
 276  278          smbd_door_return(&smbd_door_sdh, rbuf, dop_arg.rsize, NULL, 0);
 277  279          /*NOTREACHED*/
 278  280  }
 279  281  
 280  282  /*
 281  283   * Launch a thread to process an asynchronous door call.
 282  284   */
 283  285  static int
 284  286  smbd_door_dispatch_async(smbd_arg_t *req_arg)
 285  287  {
 286  288          smbd_arg_t      *arg = NULL;
 287  289          char            *data = NULL;
 288  290          pthread_attr_t  attr;
 289  291          pthread_t       tid;
 290  292          int             rc;
 291  293  
 292  294          if ((req_arg->hdr.dh_flags & SMB_DF_ASYNC) == 0) {
 293  295                  errno = EINVAL;
 294  296                  return (-1);
 295  297          }
 296  298  
 297  299          if ((arg = malloc(sizeof (smbd_arg_t))) == NULL) {
 298  300                  syslog(LOG_DEBUG, "smbd_door_dispatch_async[%s]: %m",
 299  301                      req_arg->opname);
 300  302                  return (-1);
 301  303          }
 302  304  
 303  305          (void) memcpy(arg, req_arg, sizeof (smbd_arg_t));
 304  306          arg->data = NULL;
 305  307  
 306  308          if (req_arg->datalen != 0) {
 307  309                  if ((data = malloc(req_arg->datalen)) == NULL) {
 308  310                          free(arg);
 309  311                          syslog(LOG_DEBUG, "smbd_door_dispatch_async[%s]: %m",
 310  312                              req_arg->opname);
 311  313                          return (-1);
 312  314                  }
 313  315  
 314  316                  (void) memcpy(data, req_arg->data, req_arg->datalen);
 315  317                  arg->data = data;
 316  318          }
 317  319  
 318  320          (void) mutex_lock(&smbd_doorsvc.sd_mutex);
 319  321          arg->magic = SMBD_ARG_MAGIC;
 320  322          list_insert_tail(&smbd_doorsvc.sd_async_list, arg);
 321  323          ++smbd_doorsvc.sd_async_count;
 322  324          (void) mutex_unlock(&smbd_doorsvc.sd_mutex);
 323  325  
 324  326          (void) pthread_attr_init(&attr);
 325  327          (void) pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
 326  328          rc = pthread_create(&tid, &attr, smbd_door_dispatch_op, arg);
 327  329          (void) pthread_attr_destroy(&attr);
 328  330  
 329  331          if (rc != 0) {
 330  332                  (void) mutex_lock(&smbd_doorsvc.sd_mutex);
 331  333                  smbd_door_release_async(arg);
 332  334                  (void) mutex_unlock(&smbd_doorsvc.sd_mutex);
 333  335          }
 334  336  
 335  337          return (rc);
 336  338  }
 337  339  
 338  340  /*
 339  341   * Remove an entry from the async response pending list and free
 340  342   * the arg and associated data.
 341  343   *
 342  344   * Must only be called while holding the smbd_doorsvc mutex.
 343  345   */
 344  346  static void
 345  347  smbd_door_release_async(smbd_arg_t *arg)
 346  348  {
 347  349          if (arg != NULL) {
 348  350                  assert(arg->magic == SMBD_ARG_MAGIC);
 349  351                  arg->magic = (uint32_t)~SMBD_ARG_MAGIC;
 350  352  
 351  353                  list_remove(&smbd_doorsvc.sd_async_list, arg);
 352  354                  --smbd_doorsvc.sd_async_count;
 353  355                  free(arg->data);
 354  356                  arg->data = NULL;
 355  357                  free(arg);
 356  358          }
 357  359  }
 358  360  
 359  361  /*
 360  362   * All door calls are processed here: synchronous or asynchronous:
 361  363   * - synchronous calls are invoked by direct function call
 362  364   * - asynchronous calls are invoked from a launched thread
 363  365   *
 364  366   * If the kernel has attempted to collect a response before the op
 365  367   * has completed, the arg will have been marked as response_abort
 366  368   * and we can discard the response data and release the arg.
 367  369   *
 368  370   * We send a notification when asynchronous (ASYNC) door calls
 369  371   * from the kernel (SYSSPACE) have completed.
 370  372   */
 371  373  void *
 372  374  smbd_door_dispatch_op(void *thread_arg)
 373  375  {
 374  376          smbd_arg_t      *arg = (smbd_arg_t *)thread_arg;
 375  377          smbd_doorop_t   *doorop;
 376  378          smb_doorhdr_t   *hdr;
 377  379          int             i;
 378  380  
 379  381          if ((!smbd_online()) || arg == NULL)
 380  382                  return (NULL);
 381  383  
 382  384          hdr = &arg->hdr;
 383  385          arg->opname = smb_doorhdr_opname(hdr->dh_op);
 384  386  
 385  387          for (i = 0; i < smbd_ndoorop; ++i) {
 386  388                  doorop = &smbd_doorops[i];
 387  389  
 388  390                  if (hdr->dh_op == doorop->opcode) {
 389  391                          hdr->dh_door_rc = doorop->op(arg);
 390  392                          hdr->dh_status = arg->status;
 391  393  
 392  394                          if ((hdr->dh_flags & SMB_DF_SYSSPACE) &&
 393  395                              (hdr->dh_flags & SMB_DF_ASYNC)) {
 394  396                                  assert(hdr->dh_op != SMB_DR_ASYNC_RESPONSE);
 395  397  
 396  398                                  (void) mutex_lock(&smbd_doorsvc.sd_mutex);
 397  399                                  if (arg->response_abort) {
 398  400                                          free(arg->rbuf);
 399  401                                          arg->rbuf = NULL;
 400  402                                          smbd_door_release_async(arg);
 401  403                                  } else {
 402  404                                          arg->response_ready = B_TRUE;
 403  405                                  }
 404  406                                  (void) mutex_unlock(&smbd_doorsvc.sd_mutex);
 405  407  
 406  408                                  (void) smb_kmod_event_notify(hdr->dh_txid);
 407  409                          }
 408  410  
 409  411                          return (NULL);
 410  412                  }
 411  413          }
 412  414  
 413  415          syslog(LOG_ERR, "smbd_door_dispatch_op[%s]: invalid op %u",
 414  416              arg->opname, hdr->dh_op);
 415  417          return (NULL);
 416  418  }
 417  419  
 418  420  /*
 419  421   * Wrapper for door_return.  smbd_door_enter() increments a reference count
 420  422   * when a door call is dispatched and smbd_door_return() decrements the
 421  423   * reference count when it completes.
 422  424   *
 423  425   * The reference counting is used in smbd_door_fini() to wait for active
 424  426   * calls to complete before closing the door.
 425  427   */
 426  428  void
 427  429  smbd_door_init(smbd_door_t *sdh, const char *name)
 428  430  {
 429  431          (void) strlcpy(sdh->sd_name, name, sizeof (sdh->sd_name));
 430  432  }
 431  433  
 432  434  void
 433  435  smbd_door_enter(smbd_door_t *sdh)
 434  436  {
 435  437          (void) mutex_lock(&sdh->sd_mutex);
 436  438          ++sdh->sd_ncalls;
 437  439          (void) mutex_unlock(&sdh->sd_mutex);
 438  440  }
 439  441  
 440  442  /*
 441  443   * We have two calls to door_return because the first call (with data)
 442  444   * can fail, which can leave the door call blocked here.  The second
 443  445   * call (with NULL) is guaranteed to unblock and return to the caller.
 444  446   */
 445  447  void
 446  448  smbd_door_return(smbd_door_t *sdh, char *data_ptr, size_t data_size,
 447  449      door_desc_t *desc_ptr, uint_t num_desc)
 448  450  {
 449  451          (void) mutex_lock(&sdh->sd_mutex);
 450  452  
 451  453          if (sdh->sd_ncalls == 0)
 452  454                  syslog(LOG_ERR, "smbd_door_return[%s]: unexpected count=0",
 453  455                      sdh->sd_name);
 454  456          else
 455  457                  --sdh->sd_ncalls;
 456  458  
 457  459          (void) cond_broadcast(&sdh->sd_cv);
 458  460          (void) mutex_unlock(&sdh->sd_mutex);
 459  461  
 460  462          (void) door_return(data_ptr, data_size, desc_ptr, num_desc);
 461  463          (void) door_return(NULL, 0, NULL, 0);
 462  464          /* NOTREACHED */
 463  465  }
 464  466  
 465  467  /*
 466  468   * A door service is about to terminate.
 467  469   * Give active requests a small grace period to complete.
 468  470   */
 469  471  void
 470  472  smbd_door_fini(smbd_door_t *sdh)
 471  473  {
 472  474          timestruc_t     delay;
 473  475          int             rc = 0;
 474  476  
 475  477          (void) mutex_lock(&sdh->sd_mutex);
 476  478  
 477  479          while (rc != ETIME && sdh->sd_ncalls != 0) {
 478  480                  delay.tv_sec = 1;
 479  481                  delay.tv_nsec = 0;
 480  482                  rc = cond_reltimedwait(&sdh->sd_cv, &sdh->sd_mutex, &delay);
 481  483          }
 482  484  
 483  485          if (sdh->sd_ncalls != 0)
 484  486                  syslog(LOG_NOTICE, "smbd_door_fini[%s]: %d remaining",
 485  487                      sdh->sd_name, sdh->sd_ncalls);
 486  488  
 487  489          (void) mutex_unlock(&sdh->sd_mutex);
 488  490  }
 489  491  
 490  492  /*
 491  493   * Null door operation: always returns success.
 492  494   * Assumes no request or response data.
 493  495   */
 494  496  /*ARGSUSED*/
 495  497  static int
 496  498  smbd_dop_null(smbd_arg_t *arg)
 497  499  {
 498  500          return (SMB_DOP_SUCCESS);
 499  501  }
 500  502  
 501  503  /*
 502  504   * Async response handler: setup the rbuf and rsize for the specified
 503  505   * transaction.  This function is used by the kernel to collect the
 504  506   * response half of an asynchronous door call.
 505  507   *
 506  508   * If a door client attempts to collect a response before the op has
 507  509   * completed (!response_ready), mark the arg as response_abort and
 508  510   * set an error.  The response will be discarded when the op completes.
 509  511   */
 510  512  static int
 511  513  smbd_dop_async_response(smbd_arg_t *rsp_arg)
 512  514  {
 513  515          list_t          *arg_list = &smbd_doorsvc.sd_async_list;
 514  516          smbd_arg_t      *arg;
 515  517  
 516  518          (void) mutex_lock(&smbd_doorsvc.sd_mutex);
 517  519          arg = list_head(arg_list);
 518  520  
 519  521          while (arg != NULL) {
 520  522                  assert(arg->magic == SMBD_ARG_MAGIC);
 521  523  
 522  524                  if (arg->hdr.dh_txid == rsp_arg->hdr.dh_txid) {
 523  525                          if (!arg->response_ready) {
 524  526                                  arg->response_abort = B_TRUE;
 525  527                                  rsp_arg->hdr.dh_door_rc = SMB_DOP_NOT_CALLED;
 526  528                                  syslog(LOG_NOTICE, "doorsvc[%s]: %u not ready",
 527  529                                      arg->opname, arg->hdr.dh_txid);
 528  530                                  break;
 529  531                          }
 530  532  
 531  533                          rsp_arg->rbuf = arg->rbuf;
 532  534                          rsp_arg->rsize = arg->rsize;
 533  535                          arg->rbuf = NULL;
 534  536                          arg->rsize = 0;
 535  537                          smbd_door_release_async(arg);
 536  538                          break;
 537  539                  }
 538  540  
 539  541                  arg = list_next(arg_list, arg);
 540  542          }
 541  543  
 542  544          (void) mutex_unlock(&smbd_doorsvc.sd_mutex);
 543  545          return (SMB_DOP_SUCCESS);
 544  546  }
 545  547  
 546  548  static int
 547  549  smbd_dop_user_nonauth_logon(smbd_arg_t *arg)
 548  550  {
 549  551          uint32_t        sid = 0;
 550  552  
 551  553          if (smb_common_decode(arg->data, arg->datalen,
 552  554              xdr_uint32_t, &sid) != 0)
 553  555                  return (SMB_DOP_DECODE_ERROR);
 554  556  
 555  557          smbd_user_nonauth_logon(sid);
 556  558          return (SMB_DOP_SUCCESS);
 557  559  }
 558  560  
 559  561  static int
 560  562  smbd_dop_user_auth_logoff(smbd_arg_t *arg)
 561  563  {
 562  564          uint32_t        sid = 0;
 563  565  
 564  566          if (smb_common_decode(arg->data, arg->datalen,
 565  567              xdr_uint32_t, &sid) != 0)
 566  568                  return (SMB_DOP_DECODE_ERROR);
 567  569  
 568  570          smbd_user_auth_logoff(sid);
 569  571          return (SMB_DOP_SUCCESS);
 570  572  }
 571  573  
 572  574  /*
 573  575   * Obtains an access token on successful user authentication.
  
    | 
      ↓ open down ↓ | 
    457 lines elided | 
    
      ↑ open up ↑ | 
  
 574  576   */
 575  577  static int
 576  578  smbd_dop_user_auth_logon(smbd_arg_t *arg)
 577  579  {
 578  580          _NOTE(ARGUNUSED(arg))
 579  581  
 580  582          /* No longer used */
 581  583          return (SMB_DOP_EMPTYBUF);
 582  584  }
 583  585  
      586 +/*
      587 + * SMB_DR_LOOKUP_NAME,
      588 + * SMB_DR_LOOKUP_LNAME (local-only, for idmap)
      589 + */
 584  590  static int
 585  591  smbd_dop_lookup_name(smbd_arg_t *arg)
 586  592  {
 587  593          smb_domain_t    dinfo;
 588  594          smb_account_t   ainfo;
 589  595          lsa_account_t   acct;
 590  596          char            buf[MAXNAMELEN];
 591  597  
 592  598          bzero(&acct, sizeof (lsa_account_t));
 593  599  
 594  600          if (smb_common_decode(arg->data, arg->datalen,
 595  601              lsa_account_xdr, &acct) != 0)
 596  602                  return (SMB_DOP_DECODE_ERROR);
  
    | 
      ↓ open down ↓ | 
    3 lines elided | 
    
      ↑ open up ↑ | 
  
 597  603  
 598  604          if (*acct.a_domain == '\0')
 599  605                  (void) snprintf(buf, MAXNAMELEN, "%s", acct.a_name);
 600  606          else if (strchr(acct.a_domain, '.') != NULL)
 601  607                  (void) snprintf(buf, MAXNAMELEN, "%s@%s", acct.a_name,
 602  608                      acct.a_domain);
 603  609          else
 604  610                  (void) snprintf(buf, MAXNAMELEN, "%s\\%s", acct.a_domain,
 605  611                      acct.a_name);
 606  612  
 607      -        acct.a_status = lsa_lookup_name(buf, acct.a_sidtype, &ainfo);
      613 +        switch (arg->hdr.dh_op) {
      614 +        case SMB_DR_LOOKUP_NAME:
      615 +                acct.a_status = lsa_lookup_name(buf, acct.a_sidtype, &ainfo);
      616 +                break;
      617 +
      618 +        case SMB_DR_LOOKUP_LNAME:
      619 +                /*
      620 +                 * Basically for idmap.  Don't call out to AD.
      621 +                 */
      622 +                acct.a_status = lsa_lookup_lname(buf, acct.a_sidtype, &ainfo);
      623 +                break;
      624 +
      625 +        default:
      626 +                assert(!"arg->hdr.dh_op");
      627 +                acct.a_status = NT_STATUS_INTERNAL_ERROR;
      628 +                break;
      629 +        }
      630 +
 608  631          if (acct.a_status == NT_STATUS_SUCCESS) {
 609  632                  acct.a_sidtype = ainfo.a_type;
 610  633                  smb_sid_tostr(ainfo.a_sid, acct.a_sid);
 611  634                  (void) strlcpy(acct.a_name, ainfo.a_name, MAXNAMELEN);
 612  635  
 613  636                  if (smb_domain_lookup_name(ainfo.a_domain, &dinfo))
 614  637                          (void) strlcpy(acct.a_domain, dinfo.di_fqname,
 615  638                              MAXNAMELEN);
 616  639                  else
 617  640                          (void) strlcpy(acct.a_domain, ainfo.a_domain,
 618  641                              MAXNAMELEN);
  
    | 
      ↓ open down ↓ | 
    1 lines elided | 
    
      ↑ open up ↑ | 
  
 619  642                  smb_account_free(&ainfo);
 620  643          }
 621  644  
 622  645          arg->rbuf = smb_common_encode(&acct, lsa_account_xdr, &arg->rsize);
 623  646  
 624  647          if (arg->rbuf == NULL)
 625  648                  return (SMB_DOP_ENCODE_ERROR);
 626  649          return (SMB_DOP_SUCCESS);
 627  650  }
 628  651  
      652 +/*
      653 + * SMB_DR_LOOKUP_SID,
      654 + * SMB_DR_LOOKUP_LSID (local-only, for idmap)
      655 + */
 629  656  static int
 630  657  smbd_dop_lookup_sid(smbd_arg_t *arg)
 631  658  {
 632  659          smb_domain_t    dinfo;
 633  660          smb_account_t   ainfo;
 634  661          lsa_account_t   acct;
 635  662          smb_sid_t       *sid;
 636  663  
 637  664          bzero(&acct, sizeof (lsa_account_t));
 638  665  
 639  666          if (smb_common_decode(arg->data, arg->datalen,
 640  667              lsa_account_xdr, &acct) != 0)
 641  668                  return (SMB_DOP_DECODE_ERROR);
 642  669  
 643  670          sid = smb_sid_fromstr(acct.a_sid);
 644      -        acct.a_status = lsa_lookup_sid(sid, &ainfo);
      671 +
      672 +        switch (arg->hdr.dh_op) {
      673 +        case SMB_DR_LOOKUP_SID:
      674 +                acct.a_status = lsa_lookup_sid(sid, &ainfo);
      675 +                break;
      676 +
      677 +        case SMB_DR_LOOKUP_LSID:
      678 +                /*
      679 +                 * Basically for idmap.  Don't call out to AD.
      680 +                 */
      681 +                acct.a_status = lsa_lookup_lsid(sid, &ainfo);
      682 +                break;
      683 +
      684 +        default:
      685 +                assert(!"arg->hdr.dh_op");
      686 +                acct.a_status = NT_STATUS_INTERNAL_ERROR;
      687 +                break;
      688 +        }
      689 +
 645  690          smb_sid_free(sid);
 646  691  
 647  692          if (acct.a_status == NT_STATUS_SUCCESS) {
 648  693                  acct.a_sidtype = ainfo.a_type;
 649  694                  smb_sid_tostr(ainfo.a_sid, acct.a_sid);
 650  695                  (void) strlcpy(acct.a_name, ainfo.a_name, MAXNAMELEN);
 651  696  
 652  697                  if (smb_domain_lookup_name(ainfo.a_domain, &dinfo))
 653  698                          (void) strlcpy(acct.a_domain, dinfo.di_fqname,
 654  699                              MAXNAMELEN);
 655  700                  else
 656  701                          (void) strlcpy(acct.a_domain, ainfo.a_domain,
 657  702                              MAXNAMELEN);
 658  703  
 659  704                  smb_account_free(&ainfo);
 660  705          }
 661  706  
 662  707          arg->rbuf = smb_common_encode(&acct, lsa_account_xdr, &arg->rsize);
 663  708  
 664  709          if (arg->rbuf == NULL)
 665  710                  return (SMB_DOP_ENCODE_ERROR);
 666  711          return (SMB_DOP_SUCCESS);
 667  712  }
 668  713  
 669  714  static int
 670  715  smbd_dop_join(smbd_arg_t *arg)
 671  716  {
 672  717          smb_joininfo_t  jdi;
 673  718          smb_joinres_t   jdres;
 674  719  
 675  720          bzero(&jdi, sizeof (smb_joininfo_t));
 676  721          bzero(&jdres, sizeof (smb_joinres_t));
 677  722  
 678  723          if (smb_common_decode(arg->data, arg->datalen,
 679  724              smb_joininfo_xdr, &jdi) != 0)
 680  725                  return (SMB_DOP_DECODE_ERROR);
 681  726  
 682  727          smbd_join(&jdi, &jdres);
 683  728  
 684  729          arg->rbuf = smb_common_encode(&jdres, smb_joinres_xdr, &arg->rsize);
 685  730  
 686  731          if (arg->rbuf == NULL)
 687  732                  return (SMB_DOP_ENCODE_ERROR);
 688  733          return (SMB_DOP_SUCCESS);
 689  734  }
 690  735  
 691  736  static int
 692  737  smbd_dop_get_dcinfo(smbd_arg_t *arg)
 693  738  {
 694  739          smb_domainex_t  dxi;
 695  740  
 696  741          if (!smb_domain_getinfo(&dxi))
 697  742                  return (SMB_DOP_EMPTYBUF);
 698  743  
 699  744          arg->rbuf = smb_string_encode(dxi.d_dci.dc_name, &arg->rsize);
 700  745  
 701  746          if (arg->rbuf == NULL)
 702  747                  return (SMB_DOP_ENCODE_ERROR);
 703  748          return (SMB_DOP_SUCCESS);
 704  749  }
 705  750  
 706  751  /*
 707  752   * Return the number of snapshots for a dataset
 708  753   */
 709  754  static int
 710  755  smbd_dop_vss_get_count(smbd_arg_t *arg)
 711  756  {
 712  757          smb_string_t    path;
 713  758          uint32_t        count;
 714  759  
 715  760          bzero(&path, sizeof (smb_string_t));
 716  761          arg->rbuf = NULL;
 717  762  
 718  763          if (smb_string_decode(&path, arg->data, arg->datalen) != 0)
 719  764                  return (SMB_DOP_DECODE_ERROR);
 720  765  
 721  766          if (smbd_vss_get_count(path.buf, &count) == 0)
 722  767                  arg->rbuf = smb_common_encode(&count, xdr_uint32_t,
 723  768                      &arg->rsize);
 724  769  
 725  770          xdr_free(smb_string_xdr, (char *)&path);
 726  771  
 727  772          if (arg->rbuf == NULL)
 728  773                  return (SMB_DOP_ENCODE_ERROR);
 729  774          return (SMB_DOP_SUCCESS);
 730  775  }
 731  776  
 732  777  /*
 733  778   * Return the count and list of snapshots.
 734  779   * The list is in @GMT token format.
 735  780   */
 736  781  static int
 737  782  smbd_dop_vss_get_snapshots(smbd_arg_t *arg)
 738  783  {
 739  784          char                            **gmtp;
 740  785          smb_gmttoken_query_t            request;
 741  786          smb_gmttoken_response_t         reply;
 742  787          uint_t                          i;
 743  788  
 744  789          bzero(&request, sizeof (smb_gmttoken_query_t));
 745  790          bzero(&reply, sizeof (smb_gmttoken_response_t));
 746  791  
 747  792          if (smb_common_decode(arg->data, arg->datalen,
 748  793              smb_gmttoken_query_xdr, &request) != 0)
 749  794                  return (SMB_DOP_DECODE_ERROR);
 750  795  
 751  796          reply.gtr_gmttokens.gtr_gmttokens_val = malloc(request.gtq_count *
 752  797              sizeof (char *));
 753  798          bzero(reply.gtr_gmttokens.gtr_gmttokens_val, request.gtq_count *
 754  799              sizeof (char *));
 755  800  
 756  801          if (reply.gtr_gmttokens.gtr_gmttokens_val == NULL) {
 757  802                  xdr_free(smb_gmttoken_query_xdr, (char *)&request);
 758  803                  return (SMB_DOP_EMPTYBUF);
 759  804          }
 760  805  
 761  806          smbd_vss_get_snapshots(request.gtq_path, request.gtq_count,
 762  807              &reply.gtr_count,
 763  808              &reply.gtr_gmttokens.gtr_gmttokens_len,
 764  809              reply.gtr_gmttokens.gtr_gmttokens_val);
 765  810  
 766  811          arg->rbuf = smb_common_encode(&reply, smb_gmttoken_response_xdr,
 767  812              &arg->rsize);
 768  813          if (arg->rbuf == NULL) {
 769  814                  xdr_free(smb_gmttoken_query_xdr, (char *)&request);
 770  815                  return (SMB_DOP_ENCODE_ERROR);
 771  816          }
 772  817  
 773  818          for (i = 0, gmtp = reply.gtr_gmttokens.gtr_gmttokens_val;
 774  819              (i < request.gtq_count); i++) {
 775  820                  if (*gmtp)
 776  821                          free(*gmtp);
 777  822                  gmtp++;
 778  823          }
 779  824  
 780  825          free(reply.gtr_gmttokens.gtr_gmttokens_val);
 781  826          xdr_free(smb_gmttoken_query_xdr, (char *)&request);
 782  827          return (SMB_DOP_SUCCESS);
 783  828  }
 784  829  
 785  830  /*
 786  831   * Return the name of the snapshot that matches the dataset path
 787  832   * and @GMT token.
 788  833   */
 789  834  static int
 790  835  smbd_dop_vss_map_gmttoken(smbd_arg_t *arg)
 791  836  {
 792  837          char                    *snapname;
 793  838          smb_gmttoken_snapname_t request;
 794  839  
 795  840          bzero(&request, sizeof (smb_gmttoken_snapname_t));
 796  841  
 797  842          if (smb_common_decode(arg->data, arg->datalen,
 798  843              smb_gmttoken_snapname_xdr, &request) != 0) {
 799  844                  xdr_free(smb_gmttoken_snapname_xdr, (char *)&request);
 800  845                  return (SMB_DOP_DECODE_ERROR);
 801  846          }
 802  847  
 803  848          if ((snapname = malloc(MAXPATHLEN)) == NULL) {
 804  849                  xdr_free(smb_gmttoken_snapname_xdr, (char *)&request);
 805  850                  return (NULL);
 806  851          }
 807  852  
 808  853          if ((smbd_vss_map_gmttoken(request.gts_path, request.gts_gmttoken,
 809  854              request.gts_toktime, snapname) != 0)) {
 810  855                  *snapname = '\0';
 811  856          }
 812  857  
 813  858          arg->rbuf = smb_string_encode(snapname, &arg->rsize);
 814  859          xdr_free(smb_gmttoken_snapname_xdr, (char *)&request);
 815  860          free(snapname);
 816  861  
 817  862          if (arg->rbuf == NULL)
 818  863                  return (SMB_DOP_ENCODE_ERROR);
 819  864          return (SMB_DOP_SUCCESS);
 820  865  }
 821  866  
 822  867  static int
 823  868  smbd_dop_ads_find_host(smbd_arg_t *arg)
 824  869  {
 825  870          smb_ads_host_info_t     *hinfo = NULL;
 826  871          char                    *hostname = "";
 827  872          smb_string_t            fqdn;
 828  873  
 829  874          bzero(&fqdn, sizeof (smb_string_t));
 830  875  
 831  876          if (smb_string_decode(&fqdn, arg->data, arg->datalen) != 0)
 832  877                  return (SMB_DOP_DECODE_ERROR);
 833  878  
 834  879          if ((hinfo = smb_ads_find_host(fqdn.buf)) != NULL)
 835  880                  hostname = hinfo->name;
 836  881  
 837  882          xdr_free(smb_string_xdr, (char *)&fqdn);
 838  883  
 839  884          arg->rbuf = smb_string_encode(hostname, &arg->rsize);
 840  885          free(hinfo);
 841  886  
 842  887          if (arg->rbuf == NULL)
 843  888                  return (SMB_DOP_ENCODE_ERROR);
 844  889          return (SMB_DOP_SUCCESS);
 845  890  }
 846  891  
 847  892  /*
 848  893   * Query the list of user/group quota entries for a given filesystem.
 849  894   */
 850  895  static int
 851  896  smbd_dop_quota_query(smbd_arg_t *arg)
 852  897  {
 853  898          smb_quota_query_t       request;
 854  899          smb_quota_response_t    reply;
 855  900          uint32_t                status;
 856  901  
 857  902          bzero(&request, sizeof (smb_quota_query_t));
 858  903          bzero(&reply, sizeof (smb_quota_response_t));
 859  904  
 860  905          if (smb_common_decode(arg->data, arg->datalen,
 861  906              smb_quota_query_xdr, &request) != 0)
 862  907                  return (SMB_DOP_DECODE_ERROR);
 863  908  
 864  909          status = smb_quota_query(&request, &reply);
 865  910          reply.qr_status = status;
 866  911  
 867  912          arg->rbuf = smb_common_encode(&reply, smb_quota_response_xdr,
 868  913              &arg->rsize);
 869  914  
 870  915          xdr_free(smb_quota_query_xdr, (char *)&request);
 871  916          smb_quota_free(&reply);
 872  917  
 873  918          if (arg->rbuf == NULL)
 874  919                  return (SMB_DOP_ENCODE_ERROR);
 875  920          return (SMB_DOP_SUCCESS);
 876  921  }
 877  922  
 878  923  /*
 879  924   * Set a list of user/group quota entries for a given filesystem.
 880  925   */
 881  926  static int
 882  927  smbd_dop_quota_set(smbd_arg_t *arg)
 883  928  {
 884  929          smb_quota_set_t request;
 885  930          uint32_t        status = 0;
 886  931  
 887  932          bzero(&request, sizeof (smb_quota_set_t));
 888  933  
 889  934          if (smb_common_decode(arg->data, arg->datalen,
 890  935              smb_quota_set_xdr, &request) != 0)
 891  936                  return (SMB_DOP_DECODE_ERROR);
 892  937  
 893  938          status = smb_quota_set(&request);
 894  939  
 895  940          arg->rbuf = smb_common_encode(&status, xdr_uint32_t, &arg->rsize);
 896  941          xdr_free(smb_quota_set_xdr, (char *)&request);
 897  942  
 898  943          if (arg->rbuf == NULL)
 899  944                  return (SMB_DOP_ENCODE_ERROR);
 900  945          return (SMB_DOP_SUCCESS);
 901  946  }
 902  947  
 903  948  static int
 904  949  smbd_dop_dfs_get_referrals(smbd_arg_t *arg)
 905  950  {
 906  951          dfs_referral_query_t    request;
 907  952          dfs_referral_response_t reply;
 908  953  
 909  954          bzero(&request, sizeof (request));
 910  955          bzero(&reply, sizeof (reply));
 911  956  
 912  957          if (smb_common_decode(arg->data, arg->datalen,
 913  958              dfs_referral_query_xdr, &request) != 0)
 914  959                  return (SMB_DOP_DECODE_ERROR);
 915  960  
 916  961          reply.rp_status = dfs_get_referrals((const char *)request.rq_path,
 917  962              request.rq_type, &reply.rp_referrals);
 918  963  
 919  964          if (reply.rp_status != ERROR_SUCCESS)
 920  965                  bzero(&reply.rp_referrals, sizeof (dfs_info_t));
 921  966  
 922  967          arg->rbuf = smb_common_encode(&reply, dfs_referral_response_xdr,
 923  968              &arg->rsize);
 924  969  
 925  970          if (reply.rp_status == ERROR_SUCCESS)
 926  971                  dfs_info_free(&reply.rp_referrals);
 927  972  
 928  973          xdr_free(dfs_referral_query_xdr, (char *)&request);
 929  974  
 930  975          if (arg->rbuf == NULL)
 931  976                  return (SMB_DOP_ENCODE_ERROR);
 932  977          return (SMB_DOP_SUCCESS);
 933  978  }
 934  979  
 935  980  static int
 936  981  smbd_dop_shr_hostaccess(smbd_arg_t *arg)
 937  982  {
 938  983          smb_shr_hostaccess_query_t request;
 939  984          uint32_t reply;
 940  985  
 941  986          bzero(&request, sizeof (request));
 942  987          bzero(&reply, sizeof (reply));
 943  988  
 944  989          if (smb_common_decode(arg->data, arg->datalen,
 945  990              smb_shr_hostaccess_query_xdr, &request) != 0)
 946  991                  return (SMB_DOP_DECODE_ERROR);
 947  992  
 948  993          reply = smb_shr_hostaccess(&request.shq_ipaddr, request.shq_none,
 949  994              request.shq_ro, request.shq_rw, request.shq_flag);
 950  995  
 951  996          arg->rbuf = smb_common_encode(&reply, xdr_uint32_t, &arg->rsize);
 952  997  
 953  998          xdr_free(smb_shr_hostaccess_query_xdr, (char *)&request);
 954  999  
 955 1000          if (arg->rbuf == NULL)
 956 1001                  return (SMB_DOP_ENCODE_ERROR);
 957 1002          return (SMB_DOP_SUCCESS);
 958 1003  }
 959 1004  
 960 1005  static int
 961 1006  smbd_dop_shr_exec(smbd_arg_t *arg)
 962 1007  {
 963 1008          smb_shr_execinfo_t request;
 964 1009          int reply;
 965 1010  
 966 1011          bzero(&request, sizeof (request));
 967 1012          bzero(&reply, sizeof (reply));
 968 1013  
 969 1014          if (smb_common_decode(arg->data, arg->datalen,
 970 1015              smb_shr_execinfo_xdr, &request) != 0)
 971 1016                  return (SMB_DOP_DECODE_ERROR);
 972 1017  
 973 1018          reply = smb_shr_exec(&request);
 974 1019  
 975 1020          if (reply != 0)
 976 1021                  syslog(LOG_NOTICE, "Failed to execute %s command",
 977 1022                      (request.e_type == SMB_EXEC_MAP) ? "map" : "unmap");
 978 1023  
 979 1024          arg->rbuf = smb_common_encode(&reply, xdr_int, &arg->rsize);
 980 1025  
 981 1026          xdr_free(smb_shr_execinfo_xdr, (char *)&request);
 982 1027  
 983 1028          if (arg->rbuf == NULL)
 984 1029                  return (SMB_DOP_ENCODE_ERROR);
 985 1030          return (SMB_DOP_SUCCESS);
 986 1031  }
 987 1032  
 988 1033  /* ARGSUSED */
 989 1034  static int
 990 1035  smbd_dop_notify_dc_changed(smbd_arg_t *arg)
 991 1036  {
 992 1037  
 993 1038          smbd_dc_monitor_refresh();
 994 1039  
 995 1040          return (SMB_DOP_SUCCESS);
 996 1041  }
  
    | 
      ↓ open down ↓ | 
    342 lines elided | 
    
      ↑ open up ↑ | 
  
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX