Print this page
1575 untangle libmlrpc ... (libmlrpc)

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 ↓ 40 lines elided ↑ open up ↑
  41   41  
  42   42  #include <netsmb/smbfs_api.h>
  43   43  #include <smbsrv/libsmb.h>
  44   44  #include <smbsrv/libsmbns.h>
  45   45  #include <smbsrv/libmlrpc.h>
  46   46  #include <smbsrv/libmlsvc.h>
  47   47  #include <smbsrv/ndl/srvsvc.ndl>
  48   48  #include <libsmbrdr.h>
  49   49  #include <mlsvc.h>
  50   50  
  51      -static int ndr_xa_init(ndr_client_t *, ndr_xa_t *);
  52      -static int ndr_xa_exchange(ndr_client_t *, ndr_xa_t *);
  53      -static int ndr_xa_read(ndr_client_t *, ndr_xa_t *);
  54      -static void ndr_xa_preserve(ndr_client_t *, ndr_xa_t *);
  55      -static void ndr_xa_destruct(ndr_client_t *, ndr_xa_t *);
  56      -static void ndr_xa_release(ndr_client_t *);
  57   51  
  58      -
  59   52  /*
  60   53   * This call must be made to initialize an RPC client structure and bind
  61   54   * to the remote service before any RPCs can be exchanged with that service.
  62   55   *
  63   56   * The mlsvc_handle_t is a wrapper that is used to associate an RPC handle
  64   57   * with the client context for an instance of the interface.  The handle
  65   58   * is zeroed to ensure that it doesn't look like a valid handle -
  66   59   * handle content is provided by the remove service.
  67   60   *
  68   61   * The client points to this top-level handle so that we know when to
↓ open down ↓ 168 lines elided ↑ open up ↑
 237  230                  ndr_clnt_free_heap(clnt);
 238  231          else
 239  232                  ndr_heap_destroy(clnt->heap);
 240  233  
 241  234          (void) smb_fh_close(clnt->xa_fd);
 242  235          smbrdr_ctx_free(ctx);
 243  236          free(clnt);
 244  237          bzero(handle, sizeof (mlsvc_handle_t));
 245  238  }
 246  239  
 247      -/*
 248      - * Call the RPC function identified by opnum.  The remote service is
 249      - * identified by the handle, which should have been initialized by
 250      - * ndr_rpc_bind.
 251      - *
 252      - * If the RPC call is successful (returns 0), the caller must call
 253      - * ndr_rpc_release to release the heap.  Otherwise, we release the
 254      - * heap here.
 255      - */
 256      -int
 257      -ndr_rpc_call(mlsvc_handle_t *handle, int opnum, void *params)
 258      -{
 259      -        ndr_client_t *clnt = handle->clnt;
 260      -        int rc;
 261      -
 262      -        if (ndr_rpc_get_heap(handle) == NULL)
 263      -                return (-1);
 264      -
 265      -        rc = ndr_clnt_call(clnt->binding, opnum, params);
 266      -
 267      -        /*
 268      -         * Always clear the nonull flag to ensure
 269      -         * it is not applied to subsequent calls.
 270      -         */
 271      -        clnt->nonull = B_FALSE;
 272      -
 273      -        if (NDR_DRC_IS_FAULT(rc)) {
 274      -                ndr_rpc_release(handle);
 275      -                return (-1);
 276      -        }
 277      -
 278      -        return (0);
 279      -}
 280      -
 281      -/*
 282      - * Outgoing strings should not be null terminated.
 283      - */
 284  240  void
 285      -ndr_rpc_set_nonull(mlsvc_handle_t *handle)
 286      -{
 287      -        handle->clnt->nonull = B_TRUE;
 288      -}
 289      -
 290      -/*
 291      - * Get the session key from a bound RPC client handle.
 292      - *
 293      - * The key returned is the 16-byte "user session key"
 294      - * established by the underlying authentication protocol
 295      - * (either Kerberos or NTLM).  This key is needed for
 296      - * SAM RPC calls such as SamrSetInformationUser, etc.
 297      - * See [MS-SAMR] sections: 2.2.3.3, 2.2.7.21, 2.2.7.25.
 298      - *
 299      - * Returns zero (success) or an errno.
 300      - */
 301      -int
 302      -ndr_rpc_get_ssnkey(mlsvc_handle_t *handle,
 303      -        unsigned char *ssn_key, size_t len)
 304      -{
 305      -        ndr_client_t *clnt = handle->clnt;
 306      -        int rc;
 307      -
 308      -        if (clnt == NULL)
 309      -                return (EINVAL);
 310      -
 311      -        rc = smb_fh_getssnkey(clnt->xa_fd, ssn_key, len);
 312      -        return (rc);
 313      -}
 314      -
 315      -void *
 316      -ndr_rpc_malloc(mlsvc_handle_t *handle, size_t size)
 317      -{
 318      -        ndr_heap_t *heap;
 319      -
 320      -        if ((heap = ndr_rpc_get_heap(handle)) == NULL)
 321      -                return (NULL);
 322      -
 323      -        return (ndr_heap_malloc(heap, size));
 324      -}
 325      -
 326      -ndr_heap_t *
 327      -ndr_rpc_get_heap(mlsvc_handle_t *handle)
 328      -{
 329      -        ndr_client_t *clnt = handle->clnt;
 330      -
 331      -        if (clnt->heap == NULL)
 332      -                clnt->heap = ndr_heap_create();
 333      -
 334      -        return (clnt->heap);
 335      -}
 336      -
 337      -/*
 338      - * Must be called by RPC clients to free the heap after a successful RPC
 339      - * call, i.e. ndr_rpc_call returned 0.  The caller should take a copy
 340      - * of any data returned by the RPC prior to calling this function because
 341      - * returned data is in the heap.
 342      - */
 343      -void
 344      -ndr_rpc_release(mlsvc_handle_t *handle)
 345      -{
 346      -        ndr_client_t *clnt = handle->clnt;
 347      -
 348      -        if (clnt->heap_preserved)
 349      -                ndr_clnt_free_heap(clnt);
 350      -        else
 351      -                ndr_heap_destroy(clnt->heap);
 352      -
 353      -        clnt->heap = NULL;
 354      -}
 355      -
 356      -/*
 357      - * Returns true if the handle is null.
 358      - * Otherwise returns false.
 359      - */
 360      -boolean_t
 361      -ndr_is_null_handle(mlsvc_handle_t *handle)
 362      -{
 363      -        static ndr_hdid_t zero_handle;
 364      -
 365      -        if (handle == NULL || handle->clnt == NULL)
 366      -                return (B_TRUE);
 367      -
 368      -        if (!memcmp(&handle->handle, &zero_handle, sizeof (ndr_hdid_t)))
 369      -                return (B_TRUE);
 370      -
 371      -        return (B_FALSE);
 372      -}
 373      -
 374      -/*
 375      - * Returns true if the handle is the top level bind handle.
 376      - * Otherwise returns false.
 377      - */
 378      -boolean_t
 379      -ndr_is_bind_handle(mlsvc_handle_t *handle)
 380      -{
 381      -        return (handle->clnt->handle == &handle->handle);
 382      -}
 383      -
 384      -/*
 385      - * Pass the client reference from parent to child.
 386      - */
 387      -void
 388      -ndr_inherit_handle(mlsvc_handle_t *child, mlsvc_handle_t *parent)
 389      -{
 390      -        child->clnt = parent->clnt;
 391      -}
 392      -
 393      -void
 394  241  ndr_rpc_status(mlsvc_handle_t *handle, int opnum, DWORD status)
 395  242  {
 396  243          ndr_service_t *svc;
 397  244          char *name = "NDR RPC";
 398  245          char *s = "unknown";
 399  246  
 400  247          switch (NT_SC_SEVERITY(status)) {
 401  248          case NT_STATUS_SEVERITY_SUCCESS:
 402  249                  s = "success";
 403  250                  break;
↓ open down ↓ 8 lines elided ↑ open up ↑
 412  259                  break;
 413  260          }
 414  261  
 415  262          if (handle) {
 416  263                  svc = handle->clnt->binding->service;
 417  264                  name = svc->name;
 418  265          }
 419  266  
 420  267          smb_tracef("%s[0x%02x]: %s: %s (0x%08x)",
 421  268              name, opnum, s, xlate_nt_status(status), status);
 422      -}
 423      -
 424      -/*
 425      - * The following functions provide the client callback interface.
 426      - * If the caller hasn't provided a heap, create one here.
 427      - */
 428      -static int
 429      -ndr_xa_init(ndr_client_t *clnt, ndr_xa_t *mxa)
 430      -{
 431      -        ndr_stream_t    *recv_nds = &mxa->recv_nds;
 432      -        ndr_stream_t    *send_nds = &mxa->send_nds;
 433      -        ndr_heap_t      *heap = clnt->heap;
 434      -        int             rc;
 435      -
 436      -        if (heap == NULL) {
 437      -                if ((heap = ndr_heap_create()) == NULL)
 438      -                        return (-1);
 439      -
 440      -                clnt->heap = heap;
 441      -        }
 442      -
 443      -        mxa->heap = heap;
 444      -
 445      -        rc = nds_initialize(send_nds, 0, NDR_MODE_CALL_SEND, heap);
 446      -        if (rc == 0)
 447      -                rc = nds_initialize(recv_nds, NDR_PDU_SIZE_HINT_DEFAULT,
 448      -                    NDR_MODE_RETURN_RECV, heap);
 449      -
 450      -        if (rc != 0) {
 451      -                nds_destruct(&mxa->recv_nds);
 452      -                nds_destruct(&mxa->send_nds);
 453      -                ndr_heap_destroy(mxa->heap);
 454      -                mxa->heap = NULL;
 455      -                clnt->heap = NULL;
 456      -                return (-1);
 457      -        }
 458      -
 459      -        if (clnt->nonull)
 460      -                NDS_SETF(send_nds, NDS_F_NONULL);
 461      -
 462      -        return (0);
 463      -}
 464      -
 465      -/*
 466      - * This is the entry pointy for an RPC client call exchange with
 467      - * a server, which will result in an smbrdr SmbTransact request.
 468      - *
 469      - * SmbTransact should return the number of bytes received, which
 470      - * we record as the PDU size, or a negative error code.
 471      - */
 472      -static int
 473      -ndr_xa_exchange(ndr_client_t *clnt, ndr_xa_t *mxa)
 474      -{
 475      -        ndr_stream_t *recv_nds = &mxa->recv_nds;
 476      -        ndr_stream_t *send_nds = &mxa->send_nds;
 477      -        int err, more, nbytes;
 478      -
 479      -        nbytes = recv_nds->pdu_max_size;
 480      -        err = smb_fh_xactnp(clnt->xa_fd,
 481      -            send_nds->pdu_size, (char *)send_nds->pdu_base_offset,
 482      -            &nbytes, (char *)recv_nds->pdu_base_offset, &more);
 483      -        if (err) {
 484      -                recv_nds->pdu_size = 0;
 485      -                return (-1);
 486      -        }
 487      -
 488      -        recv_nds->pdu_size = nbytes;
 489      -        return (0);
 490      -}
 491      -
 492      -/*
 493      - * This entry point will be invoked if the xa-exchange response contained
 494      - * only the first fragment of a multi-fragment response.  The RPC client
 495      - * code will then make repeated xa-read requests to obtain the remaining
 496      - * fragments, which will result in smbrdr SmbReadX requests.
 497      - *
 498      - * SmbReadX should return the number of bytes received, in which case we
 499      - * expand the PDU size to include the received data, or a negative error
 500      - * code.
 501      - */
 502      -static int
 503      -ndr_xa_read(ndr_client_t *clnt, ndr_xa_t *mxa)
 504      -{
 505      -        ndr_stream_t *nds = &mxa->recv_nds;
 506      -        int len;
 507      -        int nbytes;
 508      -
 509      -        if ((len = (nds->pdu_max_size - nds->pdu_size)) < 0)
 510      -                return (-1);
 511      -
 512      -        nbytes = smb_fh_read(clnt->xa_fd, 0, len,
 513      -            (char *)nds->pdu_base_offset + nds->pdu_size);
 514      -
 515      -        if (nbytes < 0)
 516      -                return (-1);
 517      -
 518      -        nds->pdu_size += nbytes;
 519      -
 520      -        if (nds->pdu_size > nds->pdu_max_size) {
 521      -                nds->pdu_size = nds->pdu_max_size;
 522      -                return (-1);
 523      -        }
 524      -
 525      -        return (nbytes);
 526      -}
 527      -
 528      -/*
 529      - * Preserve the heap so that the client application has access to data
 530      - * returned from the server after an RPC call.
 531      - */
 532      -static void
 533      -ndr_xa_preserve(ndr_client_t *clnt, ndr_xa_t *mxa)
 534      -{
 535      -        assert(clnt->heap == mxa->heap);
 536      -
 537      -        clnt->heap_preserved = B_TRUE;
 538      -        mxa->heap = NULL;
 539      -}
 540      -
 541      -/*
 542      - * Dispose of the transaction streams.  If the heap has not been
 543      - * preserved, we can destroy it here.
 544      - */
 545      -static void
 546      -ndr_xa_destruct(ndr_client_t *clnt, ndr_xa_t *mxa)
 547      -{
 548      -        nds_destruct(&mxa->recv_nds);
 549      -        nds_destruct(&mxa->send_nds);
 550      -
 551      -        if (!clnt->heap_preserved) {
 552      -                ndr_heap_destroy(mxa->heap);
 553      -                mxa->heap = NULL;
 554      -                clnt->heap = NULL;
 555      -        }
 556      -}
 557      -
 558      -/*
 559      - * Dispose of a preserved heap.
 560      - */
 561      -static void
 562      -ndr_xa_release(ndr_client_t *clnt)
 563      -{
 564      -        if (clnt->heap_preserved) {
 565      -                ndr_heap_destroy(clnt->heap);
 566      -                clnt->heap = NULL;
 567      -                clnt->heap_preserved = B_FALSE;
 568      -        }
 569  269  }
    
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX