Print this page
1575 untangle libmlrpc ... (smbsrv)
1575 untangle libmlrpc ... (libmlrpc)
1575 untangle libmlrpc ... pre2:
 Get rid of ndr_rpc_server_{info,os}
1575 untangle libmlrpc ... pre1:
 Move srvsvc_timecheck where it belongs

Split Close
Expand all
Collapse all
          --- old/usr/src/lib/smbsrv/libmlsvc/common/mlsvc_client.c
          +++ new/usr/src/lib/smbsrv/libmlsvc/common/mlsvc_client.c
↓ open down ↓ 23 lines elided ↑ open up ↑
  24   24   * Copyright 2015 Nexenta Systems, Inc.  All rights reserved.
  25   25   */
  26   26  
  27   27  /*
  28   28   * Client NDR RPC interface.
  29   29   */
  30   30  
  31   31  #include <sys/types.h>
  32   32  #include <sys/errno.h>
  33   33  #include <sys/fcntl.h>
  34      -#include <sys/tzfile.h>
  35   34  #include <time.h>
  36   35  #include <strings.h>
  37   36  #include <assert.h>
  38   37  #include <errno.h>
  39   38  #include <thread.h>
  40      -#include <unistd.h>
  41   39  #include <syslog.h>
  42   40  #include <synch.h>
  43   41  
       42 +#include <libmlrpc/libmlrpc.h>
  44   43  #include <netsmb/smbfs_api.h>
       44 +
  45   45  #include <smbsrv/libsmb.h>
  46      -#include <smbsrv/libsmbns.h>
  47      -#include <smbsrv/libmlrpc.h>
  48   46  #include <smbsrv/libmlsvc.h>
  49      -#include <smbsrv/ndl/srvsvc.ndl>
  50   47  #include <libsmbrdr.h>
  51   48  #include <mlsvc.h>
  52   49  
  53      -static int ndr_xa_init(ndr_client_t *, ndr_xa_t *);
  54      -static int ndr_xa_exchange(ndr_client_t *, ndr_xa_t *);
  55      -static int ndr_xa_read(ndr_client_t *, ndr_xa_t *);
  56      -static void ndr_xa_preserve(ndr_client_t *, ndr_xa_t *);
  57      -static void ndr_xa_destruct(ndr_client_t *, ndr_xa_t *);
  58      -static void ndr_xa_release(ndr_client_t *);
  59   50  
  60      -
  61   51  /*
  62   52   * This call must be made to initialize an RPC client structure and bind
  63   53   * to the remote service before any RPCs can be exchanged with that service.
  64   54   *
  65   55   * The mlsvc_handle_t is a wrapper that is used to associate an RPC handle
  66   56   * with the client context for an instance of the interface.  The handle
  67   57   * is zeroed to ensure that it doesn't look like a valid handle -
  68   58   * handle content is provided by the remove service.
  69   59   *
  70   60   * The client points to this top-level handle so that we know when to
  71   61   * unbind and teardown the connection.  As each handle is initialized it
  72   62   * will inherit a reference to the client context.
  73   63   *
  74      - * Returns 0 or an NT_STATUS:
       64 + * Returns 0 or an NT_STATUS:           (failed in...)
       65 + *
  75   66   *      NT_STATUS_BAD_NETWORK_PATH      (get server addr)
  76   67   *      NT_STATUS_NETWORK_ACCESS_DENIED (connect, auth)
  77      - *      NT_STATUS_BAD_NETWORK_NAME      (tcon, open)
       68 + *      NT_STATUS_BAD_NETWORK_NAME      (tcon)
       69 + *      RPC_NT_SERVER_TOO_BUSY          (open pipe)
       70 + *      RPC_NT_SERVER_UNAVAILABLE       (open pipe)
  78   71   *      NT_STATUS_ACCESS_DENIED         (open pipe)
  79   72   *      NT_STATUS_INVALID_PARAMETER     (rpc bind)
  80      - *
  81   73   *      NT_STATUS_INTERNAL_ERROR        (bad args etc)
  82   74   *      NT_STATUS_NO_MEMORY
  83   75   */
  84   76  DWORD
  85   77  ndr_rpc_bind(mlsvc_handle_t *handle, char *server, char *domain,
  86   78      char *username, const char *service)
  87   79  {
  88   80          struct smb_ctx          *ctx = NULL;
  89      -        ndr_client_t            *clnt = NULL;
  90   81          ndr_service_t           *svc;
  91      -        srvsvc_server_info_t    svinfo;
  92   82          DWORD                   status;
  93      -        int                     fd = -1;
  94   83          int                     rc;
  95   84  
  96   85          if (handle == NULL || server == NULL || server[0] == '\0' ||
  97   86              domain == NULL || username == NULL)
  98   87                  return (NT_STATUS_INTERNAL_ERROR);
  99   88  
 100   89          /* In case the service was not registered... */
 101   90          if ((svc = ndr_svc_lookup_name(service)) == NULL)
 102   91                  return (NT_STATUS_INTERNAL_ERROR);
 103   92  
 104   93          /*
 105      -         * Set the default based on the assumption that most
 106      -         * servers will be Windows 2000 or later.  This used to
 107      -         * try to get the actual server version, but that RPC
 108      -         * is not necessarily allowed anymore, so don't bother.
 109      -         */
 110      -        bzero(&svinfo, sizeof (srvsvc_server_info_t));
 111      -        svinfo.sv_platform_id = SV_PLATFORM_ID_NT;
 112      -        svinfo.sv_version_major = 5;
 113      -        svinfo.sv_version_minor = 0;
 114      -        svinfo.sv_type = SV_TYPE_DEFAULT;
 115      -        svinfo.sv_os = NATIVE_OS_WIN2000;
 116      -
 117      -        /*
 118   94           * Some callers pass this when they want a NULL session.
 119   95           * Todo: have callers pass an empty string for that.
 120   96           */
 121   97          if (strcmp(username, MLSVC_ANON_USER) == 0)
 122   98                  username = "";
 123   99  
 124  100          /*
 125  101           * Setup smbfs library handle, authenticate, connect to
 126  102           * the IPC$ share.  This will reuse an existing connection
 127  103           * if the driver already has one for this combination of
↓ open down ↓ 1 lines elided ↑ open up ↑
 129  105           *      NT_STATUS_BAD_NETWORK_PATH      (get server addr)
 130  106           *      NT_STATUS_NETWORK_ACCESS_DENIED (connect, auth)
 131  107           *      NT_STATUS_BAD_NETWORK_NAME      (tcon)
 132  108           */
 133  109          status = smbrdr_ctx_new(&ctx, server, domain, username);
 134  110          if (status != NT_STATUS_SUCCESS) {
 135  111                  syslog(LOG_ERR, "ndr_rpc_bind: smbrdr_ctx_new"
 136  112                      "(Srv=%s Dom=%s User=%s), %s (0x%x)",
 137  113                      server, domain, username,
 138  114                      xlate_nt_status(status), status);
 139      -                /* Tell the DC Locator this DC failed. */
 140      -                smb_ddiscover_bad_dc(server);
 141      -                goto errout;
 142      -        }
 143      -
 144      -        /*
 145      -         * Open the named pipe.
 146      -         */
 147      -        fd = smb_fh_open(ctx, svc->endpoint, O_RDWR);
 148      -        if (fd < 0) {
 149      -                rc = errno;
 150      -                syslog(LOG_DEBUG, "ndr_rpc_bind: "
 151      -                    "smb_fh_open (%s) err=%d",
 152      -                    svc->endpoint, rc);
 153      -                switch (rc) {
 154      -                case EACCES:
 155      -                        status = NT_STATUS_ACCESS_DENIED;
 156      -                        break;
      115 +                /*
      116 +                 * If the error is one where changing to a new DC
      117 +                 * might help, try looking for a different DC.
      118 +                 */
      119 +                switch (status) {
      120 +                case NT_STATUS_BAD_NETWORK_PATH:
      121 +                case NT_STATUS_BAD_NETWORK_NAME:
      122 +                        /* Look for a new DC */
      123 +                        smb_ddiscover_bad_dc(server);
 157  124                  default:
 158      -                        status = NT_STATUS_BAD_NETWORK_NAME;
 159  125                          break;
 160  126                  }
 161      -                goto errout;
      127 +                return (status);
 162  128          }
 163  129  
 164  130          /*
 165  131           * Setup the RPC client handle.
 166  132           */
 167      -        if ((clnt = malloc(sizeof (ndr_client_t))) == NULL) {
 168      -                status = NT_STATUS_NO_MEMORY;
 169      -                goto errout;
      133 +        rc = mlrpc_clh_create(handle, ctx);
      134 +        if (rc != 0) {
      135 +                syslog(LOG_ERR, "ndr_rpc_bind: mlrpc_clh_create: rc=%d", rc);
      136 +                smbrdr_ctx_free(ctx);
      137 +                switch (rc) {
      138 +                case ENOMEM:
      139 +                        return (NT_STATUS_NO_MEMORY);
      140 +                case EINVAL:
      141 +                        return (NT_STATUS_INVALID_PARAMETER);
      142 +                default:
      143 +                        return (NT_STATUS_INTERNAL_ERROR);
      144 +                }
 170  145          }
 171      -        bzero(clnt, sizeof (ndr_client_t));
 172  146  
 173      -        clnt->handle = &handle->handle;
 174      -        clnt->xa_init = ndr_xa_init;
 175      -        clnt->xa_exchange = ndr_xa_exchange;
 176      -        clnt->xa_read = ndr_xa_read;
 177      -        clnt->xa_preserve = ndr_xa_preserve;
 178      -        clnt->xa_destruct = ndr_xa_destruct;
 179      -        clnt->xa_release = ndr_xa_release;
 180      -        clnt->xa_private = ctx;
 181      -        clnt->xa_fd = fd;
 182      -
 183      -        ndr_svc_binding_pool_init(&clnt->binding_list,
 184      -            clnt->binding_pool, NDR_N_BINDING_POOL);
 185      -
 186      -        if ((clnt->heap = ndr_heap_create()) == NULL) {
 187      -                status = NT_STATUS_NO_MEMORY;
 188      -                goto errout;
 189      -        }
 190      -
 191  147          /*
 192      -         * Fill in the caller's handle.
      148 +         * This does the pipe open and OtW RPC bind.
      149 +         * Handles pipe open retries.
 193  150           */
 194      -        bzero(&handle->handle, sizeof (ndr_hdid_t));
 195      -        handle->clnt = clnt;
 196      -        bcopy(&svinfo, &handle->svinfo, sizeof (srvsvc_server_info_t));
 197      -
 198      -        /*
 199      -         * Do the OtW RPC bind.
 200      -         */
 201      -        rc = ndr_clnt_bind(clnt, service, &clnt->binding);
 202      -        switch (rc) {
 203      -        case NDR_DRC_FAULT_OUT_OF_MEMORY:
 204      -                status = NT_STATUS_NO_MEMORY;
 205      -                break;
 206      -        case NDR_DRC_FAULT_API_SERVICE_INVALID: /* not registered */
 207      -                status = NT_STATUS_INTERNAL_ERROR;
 208      -                break;
 209      -        default:
 210      -                if (NDR_DRC_IS_FAULT(rc)) {
 211      -                        status = NT_STATUS_INVALID_PARAMETER;
      151 +        status = mlrpc_clh_bind(handle, svc);
      152 +        if (status != 0) {
      153 +                syslog(LOG_DEBUG, "ndr_rpc_bind: "
      154 +                    "mlrpc_clh_bind, %s (0x%x)",
      155 +                    xlate_nt_status(status), status);
      156 +                switch (status) {
      157 +                case RPC_NT_SERVER_TOO_BUSY:
      158 +                        /* Look for a new DC */
      159 +                        smb_ddiscover_bad_dc(server);
 212  160                          break;
      161 +                default:
      162 +                        break;
 213  163                  }
 214      -                /* FALLTHROUGH */
 215      -        case NDR_DRC_OK:
 216      -                return (NT_STATUS_SUCCESS);
      164 +                ctx = mlrpc_clh_free(handle);
      165 +                if (ctx != NULL) {
      166 +                        smbrdr_ctx_free(ctx);
      167 +                }
 217  168          }
 218  169  
 219      -        syslog(LOG_DEBUG, "ndr_rpc_bind: "
 220      -            "ndr_clnt_bind, %s (0x%x)",
 221      -            xlate_nt_status(status), status);
 222      -
 223      -errout:
 224      -        handle->clnt = NULL;
 225      -        if (clnt != NULL) {
 226      -                ndr_heap_destroy(clnt->heap);
 227      -                free(clnt);
 228      -        }
 229      -        if (ctx != NULL) {
 230      -                if (fd != -1)
 231      -                        (void) smb_fh_close(fd);
 232      -                smbrdr_ctx_free(ctx);
 233      -        }
 234      -
 235  170          return (status);
 236  171  }
 237  172  
 238  173  /*
 239      - * Unbind and close the pipe to an RPC service.
      174 + * Unbind and close the pipe to an RPC service
      175 + * and cleanup the smb_ctx.
 240  176   *
 241      - * If the heap has been preserved we need to go through an xa release.
 242      - * The heap is preserved during an RPC call because that's where data
 243      - * returned from the server is stored.
 244      - *
 245      - * Otherwise we destroy the heap directly.
      177 + * The heap may or may not be destroyed (see mlrpc_clh_free)
 246  178   */
 247  179  void
 248  180  ndr_rpc_unbind(mlsvc_handle_t *handle)
 249  181  {
 250      -        ndr_client_t *clnt = handle->clnt;
 251      -        struct smb_ctx *ctx = clnt->xa_private;
      182 +        struct smb_ctx *ctx;
 252  183  
 253      -        if (clnt->heap_preserved)
 254      -                ndr_clnt_free_heap(clnt);
 255      -        else
 256      -                ndr_heap_destroy(clnt->heap);
      184 +        ctx = mlrpc_clh_free(handle);
      185 +        if (ctx != NULL)
      186 +                smbrdr_ctx_free(ctx);
 257  187  
 258      -        (void) smb_fh_close(clnt->xa_fd);
 259      -        smbrdr_ctx_free(ctx);
 260      -        free(clnt);
 261  188          bzero(handle, sizeof (mlsvc_handle_t));
 262  189  }
 263  190  
 264      -/*
 265      - * Call the RPC function identified by opnum.  The remote service is
 266      - * identified by the handle, which should have been initialized by
 267      - * ndr_rpc_bind.
 268      - *
 269      - * If the RPC call is successful (returns 0), the caller must call
 270      - * ndr_rpc_release to release the heap.  Otherwise, we release the
 271      - * heap here.
 272      - */
 273      -int
 274      -ndr_rpc_call(mlsvc_handle_t *handle, int opnum, void *params)
 275      -{
 276      -        ndr_client_t *clnt = handle->clnt;
 277      -        int rc;
 278      -
 279      -        if (ndr_rpc_get_heap(handle) == NULL)
 280      -                return (-1);
 281      -
 282      -        rc = ndr_clnt_call(clnt->binding, opnum, params);
 283      -
 284      -        /*
 285      -         * Always clear the nonull flag to ensure
 286      -         * it is not applied to subsequent calls.
 287      -         */
 288      -        clnt->nonull = B_FALSE;
 289      -
 290      -        if (NDR_DRC_IS_FAULT(rc)) {
 291      -                ndr_rpc_release(handle);
 292      -                return (-1);
 293      -        }
 294      -
 295      -        return (0);
 296      -}
 297      -
 298      -/*
 299      - * Outgoing strings should not be null terminated.
 300      - */
 301  191  void
 302      -ndr_rpc_set_nonull(mlsvc_handle_t *handle)
 303      -{
 304      -        handle->clnt->nonull = B_TRUE;
 305      -}
 306      -
 307      -/*
 308      - * Return a reference to the server info.
 309      - */
 310      -const srvsvc_server_info_t *
 311      -ndr_rpc_server_info(mlsvc_handle_t *handle)
 312      -{
 313      -        return (&handle->svinfo);
 314      -}
 315      -
 316      -/*
 317      - * Return the RPC server OS level.
 318      - */
 319      -uint32_t
 320      -ndr_rpc_server_os(mlsvc_handle_t *handle)
 321      -{
 322      -        return (handle->svinfo.sv_os);
 323      -}
 324      -
 325      -/*
 326      - * Get the session key from a bound RPC client handle.
 327      - *
 328      - * The key returned is the 16-byte "user session key"
 329      - * established by the underlying authentication protocol
 330      - * (either Kerberos or NTLM).  This key is needed for
 331      - * SAM RPC calls such as SamrSetInformationUser, etc.
 332      - * See [MS-SAMR] sections: 2.2.3.3, 2.2.7.21, 2.2.7.25.
 333      - *
 334      - * Returns zero (success) or an errno.
 335      - */
 336      -int
 337      -ndr_rpc_get_ssnkey(mlsvc_handle_t *handle,
 338      -        unsigned char *ssn_key, size_t len)
 339      -{
 340      -        ndr_client_t *clnt = handle->clnt;
 341      -        int rc;
 342      -
 343      -        if (clnt == NULL)
 344      -                return (EINVAL);
 345      -
 346      -        rc = smb_fh_getssnkey(clnt->xa_fd, ssn_key, len);
 347      -        return (rc);
 348      -}
 349      -
 350      -void *
 351      -ndr_rpc_malloc(mlsvc_handle_t *handle, size_t size)
 352      -{
 353      -        ndr_heap_t *heap;
 354      -
 355      -        if ((heap = ndr_rpc_get_heap(handle)) == NULL)
 356      -                return (NULL);
 357      -
 358      -        return (ndr_heap_malloc(heap, size));
 359      -}
 360      -
 361      -ndr_heap_t *
 362      -ndr_rpc_get_heap(mlsvc_handle_t *handle)
 363      -{
 364      -        ndr_client_t *clnt = handle->clnt;
 365      -
 366      -        if (clnt->heap == NULL)
 367      -                clnt->heap = ndr_heap_create();
 368      -
 369      -        return (clnt->heap);
 370      -}
 371      -
 372      -/*
 373      - * Must be called by RPC clients to free the heap after a successful RPC
 374      - * call, i.e. ndr_rpc_call returned 0.  The caller should take a copy
 375      - * of any data returned by the RPC prior to calling this function because
 376      - * returned data is in the heap.
 377      - */
 378      -void
 379      -ndr_rpc_release(mlsvc_handle_t *handle)
 380      -{
 381      -        ndr_client_t *clnt = handle->clnt;
 382      -
 383      -        if (clnt->heap_preserved)
 384      -                ndr_clnt_free_heap(clnt);
 385      -        else
 386      -                ndr_heap_destroy(clnt->heap);
 387      -
 388      -        clnt->heap = NULL;
 389      -}
 390      -
 391      -/*
 392      - * Returns true if the handle is null.
 393      - * Otherwise returns false.
 394      - */
 395      -boolean_t
 396      -ndr_is_null_handle(mlsvc_handle_t *handle)
 397      -{
 398      -        static ndr_hdid_t zero_handle;
 399      -
 400      -        if (handle == NULL || handle->clnt == NULL)
 401      -                return (B_TRUE);
 402      -
 403      -        if (!memcmp(&handle->handle, &zero_handle, sizeof (ndr_hdid_t)))
 404      -                return (B_TRUE);
 405      -
 406      -        return (B_FALSE);
 407      -}
 408      -
 409      -/*
 410      - * Returns true if the handle is the top level bind handle.
 411      - * Otherwise returns false.
 412      - */
 413      -boolean_t
 414      -ndr_is_bind_handle(mlsvc_handle_t *handle)
 415      -{
 416      -        return (handle->clnt->handle == &handle->handle);
 417      -}
 418      -
 419      -/*
 420      - * Pass the client reference from parent to child.
 421      - */
 422      -void
 423      -ndr_inherit_handle(mlsvc_handle_t *child, mlsvc_handle_t *parent)
 424      -{
 425      -        child->clnt = parent->clnt;
 426      -        bcopy(&parent->svinfo, &child->svinfo, sizeof (srvsvc_server_info_t));
 427      -}
 428      -
 429      -void
 430  192  ndr_rpc_status(mlsvc_handle_t *handle, int opnum, DWORD status)
 431  193  {
 432  194          ndr_service_t *svc;
 433  195          char *name = "NDR RPC";
 434  196          char *s = "unknown";
 435  197  
 436  198          switch (NT_SC_SEVERITY(status)) {
 437  199          case NT_STATUS_SEVERITY_SUCCESS:
 438  200                  s = "success";
 439  201                  break;
↓ open down ↓ 8 lines elided ↑ open up ↑
 448  210                  break;
 449  211          }
 450  212  
 451  213          if (handle) {
 452  214                  svc = handle->clnt->binding->service;
 453  215                  name = svc->name;
 454  216          }
 455  217  
 456  218          smb_tracef("%s[0x%02x]: %s: %s (0x%08x)",
 457  219              name, opnum, s, xlate_nt_status(status), status);
 458      -}
 459      -
 460      -/*
 461      - * The following functions provide the client callback interface.
 462      - * If the caller hasn't provided a heap, create one here.
 463      - */
 464      -static int
 465      -ndr_xa_init(ndr_client_t *clnt, ndr_xa_t *mxa)
 466      -{
 467      -        ndr_stream_t    *recv_nds = &mxa->recv_nds;
 468      -        ndr_stream_t    *send_nds = &mxa->send_nds;
 469      -        ndr_heap_t      *heap = clnt->heap;
 470      -        int             rc;
 471      -
 472      -        if (heap == NULL) {
 473      -                if ((heap = ndr_heap_create()) == NULL)
 474      -                        return (-1);
 475      -
 476      -                clnt->heap = heap;
 477      -        }
 478      -
 479      -        mxa->heap = heap;
 480      -
 481      -        rc = nds_initialize(send_nds, 0, NDR_MODE_CALL_SEND, heap);
 482      -        if (rc == 0)
 483      -                rc = nds_initialize(recv_nds, NDR_PDU_SIZE_HINT_DEFAULT,
 484      -                    NDR_MODE_RETURN_RECV, heap);
 485      -
 486      -        if (rc != 0) {
 487      -                nds_destruct(&mxa->recv_nds);
 488      -                nds_destruct(&mxa->send_nds);
 489      -                ndr_heap_destroy(mxa->heap);
 490      -                mxa->heap = NULL;
 491      -                clnt->heap = NULL;
 492      -                return (-1);
 493      -        }
 494      -
 495      -        if (clnt->nonull)
 496      -                NDS_SETF(send_nds, NDS_F_NONULL);
 497      -
 498      -        return (0);
 499      -}
 500      -
 501      -/*
 502      - * This is the entry pointy for an RPC client call exchange with
 503      - * a server, which will result in an smbrdr SmbTransact request.
 504      - *
 505      - * SmbTransact should return the number of bytes received, which
 506      - * we record as the PDU size, or a negative error code.
 507      - */
 508      -static int
 509      -ndr_xa_exchange(ndr_client_t *clnt, ndr_xa_t *mxa)
 510      -{
 511      -        ndr_stream_t *recv_nds = &mxa->recv_nds;
 512      -        ndr_stream_t *send_nds = &mxa->send_nds;
 513      -        int err, more, nbytes;
 514      -
 515      -        nbytes = recv_nds->pdu_max_size;
 516      -        err = smb_fh_xactnp(clnt->xa_fd,
 517      -            send_nds->pdu_size, (char *)send_nds->pdu_base_offset,
 518      -            &nbytes, (char *)recv_nds->pdu_base_offset, &more);
 519      -        if (err) {
 520      -                recv_nds->pdu_size = 0;
 521      -                return (-1);
 522      -        }
 523      -
 524      -        recv_nds->pdu_size = nbytes;
 525      -        return (0);
 526      -}
 527      -
 528      -/*
 529      - * This entry point will be invoked if the xa-exchange response contained
 530      - * only the first fragment of a multi-fragment response.  The RPC client
 531      - * code will then make repeated xa-read requests to obtain the remaining
 532      - * fragments, which will result in smbrdr SmbReadX requests.
 533      - *
 534      - * SmbReadX should return the number of bytes received, in which case we
 535      - * expand the PDU size to include the received data, or a negative error
 536      - * code.
 537      - */
 538      -static int
 539      -ndr_xa_read(ndr_client_t *clnt, ndr_xa_t *mxa)
 540      -{
 541      -        ndr_stream_t *nds = &mxa->recv_nds;
 542      -        int len;
 543      -        int nbytes;
 544      -
 545      -        if ((len = (nds->pdu_max_size - nds->pdu_size)) < 0)
 546      -                return (-1);
 547      -
 548      -        nbytes = smb_fh_read(clnt->xa_fd, 0, len,
 549      -            (char *)nds->pdu_base_offset + nds->pdu_size);
 550      -
 551      -        if (nbytes < 0)
 552      -                return (-1);
 553      -
 554      -        nds->pdu_size += nbytes;
 555      -
 556      -        if (nds->pdu_size > nds->pdu_max_size) {
 557      -                nds->pdu_size = nds->pdu_max_size;
 558      -                return (-1);
 559      -        }
 560      -
 561      -        return (nbytes);
 562      -}
 563      -
 564      -/*
 565      - * Preserve the heap so that the client application has access to data
 566      - * returned from the server after an RPC call.
 567      - */
 568      -static void
 569      -ndr_xa_preserve(ndr_client_t *clnt, ndr_xa_t *mxa)
 570      -{
 571      -        assert(clnt->heap == mxa->heap);
 572      -
 573      -        clnt->heap_preserved = B_TRUE;
 574      -        mxa->heap = NULL;
 575      -}
 576      -
 577      -/*
 578      - * Dispose of the transaction streams.  If the heap has not been
 579      - * preserved, we can destroy it here.
 580      - */
 581      -static void
 582      -ndr_xa_destruct(ndr_client_t *clnt, ndr_xa_t *mxa)
 583      -{
 584      -        nds_destruct(&mxa->recv_nds);
 585      -        nds_destruct(&mxa->send_nds);
 586      -
 587      -        if (!clnt->heap_preserved) {
 588      -                ndr_heap_destroy(mxa->heap);
 589      -                mxa->heap = NULL;
 590      -                clnt->heap = NULL;
 591      -        }
 592      -}
 593      -
 594      -/*
 595      - * Dispose of a preserved heap.
 596      - */
 597      -static void
 598      -ndr_xa_release(ndr_client_t *clnt)
 599      -{
 600      -        if (clnt->heap_preserved) {
 601      -                ndr_heap_destroy(clnt->heap);
 602      -                clnt->heap = NULL;
 603      -                clnt->heap_preserved = B_FALSE;
 604      -        }
 605      -}
 606      -
 607      -
 608      -/*
 609      - * Compare the time here with the remote time on the server
 610      - * and report clock skew.
 611      - */
 612      -void
 613      -ndr_srvsvc_timecheck(char *server, char *domain)
 614      -{
 615      -        char                    hostname[MAXHOSTNAMELEN];
 616      -        struct timeval          dc_tv;
 617      -        struct tm               dc_tm;
 618      -        struct tm               *tm;
 619      -        time_t                  tnow;
 620      -        time_t                  tdiff;
 621      -        int                     priority;
 622      -
 623      -        if (srvsvc_net_remote_tod(server, domain, &dc_tv, &dc_tm) < 0) {
 624      -                syslog(LOG_DEBUG, "srvsvc_net_remote_tod failed");
 625      -                return;
 626      -        }
 627      -
 628      -        tnow = time(NULL);
 629      -
 630      -        if (tnow > dc_tv.tv_sec)
 631      -                tdiff = (tnow - dc_tv.tv_sec) / SECSPERMIN;
 632      -        else
 633      -                tdiff = (dc_tv.tv_sec - tnow) / SECSPERMIN;
 634      -
 635      -        if (tdiff != 0) {
 636      -                (void) strlcpy(hostname, "localhost", MAXHOSTNAMELEN);
 637      -                (void) gethostname(hostname, MAXHOSTNAMELEN);
 638      -
 639      -                priority = (tdiff > 2) ? LOG_NOTICE : LOG_DEBUG;
 640      -                syslog(priority, "DC [%s] clock skew detected: %u minutes",
 641      -                    server, tdiff);
 642      -
 643      -                tm = gmtime(&dc_tv.tv_sec);
 644      -                syslog(priority, "%-8s  UTC: %s", server, asctime(tm));
 645      -                tm = gmtime(&tnow);
 646      -                syslog(priority, "%-8s  UTC: %s", hostname, asctime(tm));
 647      -        }
 648  220  }
    
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX