Print this page
1575 untangle libmlrpc ... (smbsrv)
*** 37,52 ****
#include <errno.h>
#include <thread.h>
#include <syslog.h>
#include <synch.h>
#include <netsmb/smbfs_api.h>
#include <smbsrv/libsmb.h>
- #include <smbsrv/libsmbns.h>
- #include <smbsrv/libmlrpc.h>
#include <smbsrv/libmlsvc.h>
- #include <smbsrv/ndl/srvsvc.ndl>
#include <libsmbrdr.h>
#include <mlsvc.h>
/*
--- 37,51 ----
#include <errno.h>
#include <thread.h>
#include <syslog.h>
#include <synch.h>
+ #include <libmlrpc/libmlrpc.h>
#include <netsmb/smbfs_api.h>
+
#include <smbsrv/libsmb.h>
#include <smbsrv/libmlsvc.h>
#include <libsmbrdr.h>
#include <mlsvc.h>
/*
*** 60,88 ****
*
* The client points to this top-level handle so that we know when to
* unbind and teardown the connection. As each handle is initialized it
* will inherit a reference to the client context.
*
! * Returns 0 or an NT_STATUS:
* NT_STATUS_BAD_NETWORK_PATH (get server addr)
* NT_STATUS_NETWORK_ACCESS_DENIED (connect, auth)
! * NT_STATUS_BAD_NETWORK_NAME (tcon, open)
* NT_STATUS_ACCESS_DENIED (open pipe)
* NT_STATUS_INVALID_PARAMETER (rpc bind)
- *
* NT_STATUS_INTERNAL_ERROR (bad args etc)
* NT_STATUS_NO_MEMORY
*/
DWORD
ndr_rpc_bind(mlsvc_handle_t *handle, char *server, char *domain,
char *username, const char *service)
{
struct smb_ctx *ctx = NULL;
- ndr_client_t *clnt = NULL;
ndr_service_t *svc;
DWORD status;
- int fd = -1;
int rc;
if (handle == NULL || server == NULL || server[0] == '\0' ||
domain == NULL || username == NULL)
return (NT_STATUS_INTERNAL_ERROR);
--- 59,87 ----
*
* The client points to this top-level handle so that we know when to
* unbind and teardown the connection. As each handle is initialized it
* will inherit a reference to the client context.
*
! * Returns 0 or an NT_STATUS: (failed in...)
! *
* NT_STATUS_BAD_NETWORK_PATH (get server addr)
* NT_STATUS_NETWORK_ACCESS_DENIED (connect, auth)
! * NT_STATUS_BAD_NETWORK_NAME (tcon)
! * RPC_NT_SERVER_TOO_BUSY (open pipe)
! * RPC_NT_SERVER_UNAVAILABLE (open pipe)
* NT_STATUS_ACCESS_DENIED (open pipe)
* NT_STATUS_INVALID_PARAMETER (rpc bind)
* NT_STATUS_INTERNAL_ERROR (bad args etc)
* NT_STATUS_NO_MEMORY
*/
DWORD
ndr_rpc_bind(mlsvc_handle_t *handle, char *server, char *domain,
char *username, const char *service)
{
struct smb_ctx *ctx = NULL;
ndr_service_t *svc;
DWORD status;
int rc;
if (handle == NULL || server == NULL || server[0] == '\0' ||
domain == NULL || username == NULL)
return (NT_STATUS_INTERNAL_ERROR);
*** 111,241 ****
if (status != NT_STATUS_SUCCESS) {
syslog(LOG_ERR, "ndr_rpc_bind: smbrdr_ctx_new"
"(Srv=%s Dom=%s User=%s), %s (0x%x)",
server, domain, username,
xlate_nt_status(status), status);
- /* Tell the DC Locator this DC failed. */
- smb_ddiscover_bad_dc(server);
- goto errout;
- }
-
/*
! * Open the named pipe.
*/
! fd = smb_fh_open(ctx, svc->endpoint, O_RDWR);
! if (fd < 0) {
! rc = errno;
! syslog(LOG_DEBUG, "ndr_rpc_bind: "
! "smb_fh_open (%s) err=%d",
! svc->endpoint, rc);
! switch (rc) {
! case EACCES:
! status = NT_STATUS_ACCESS_DENIED;
! break;
default:
- status = NT_STATUS_BAD_NETWORK_NAME;
break;
}
! goto errout;
}
/*
* Setup the RPC client handle.
*/
! if ((clnt = malloc(sizeof (ndr_client_t))) == NULL) {
! status = NT_STATUS_NO_MEMORY;
! goto errout;
}
- bzero(clnt, sizeof (ndr_client_t));
-
- clnt->handle = &handle->handle;
- clnt->xa_init = ndr_xa_init;
- clnt->xa_exchange = ndr_xa_exchange;
- clnt->xa_read = ndr_xa_read;
- clnt->xa_preserve = ndr_xa_preserve;
- clnt->xa_destruct = ndr_xa_destruct;
- clnt->xa_release = ndr_xa_release;
- clnt->xa_private = ctx;
- clnt->xa_fd = fd;
-
- ndr_svc_binding_pool_init(&clnt->binding_list,
- clnt->binding_pool, NDR_N_BINDING_POOL);
-
- if ((clnt->heap = ndr_heap_create()) == NULL) {
- status = NT_STATUS_NO_MEMORY;
- goto errout;
}
/*
! * Fill in the caller's handle.
*/
! bzero(&handle->handle, sizeof (ndr_hdid_t));
! handle->clnt = clnt;
!
! /*
! * Do the OtW RPC bind.
! */
! rc = ndr_clnt_bind(clnt, service, &clnt->binding);
! switch (rc) {
! case NDR_DRC_FAULT_OUT_OF_MEMORY:
! status = NT_STATUS_NO_MEMORY;
break;
- case NDR_DRC_FAULT_API_SERVICE_INVALID: /* not registered */
- status = NT_STATUS_INTERNAL_ERROR;
- break;
default:
- if (NDR_DRC_IS_FAULT(rc)) {
- status = NT_STATUS_INVALID_PARAMETER;
break;
}
! /* FALLTHROUGH */
! case NDR_DRC_OK:
! return (NT_STATUS_SUCCESS);
! }
!
! syslog(LOG_DEBUG, "ndr_rpc_bind: "
! "ndr_clnt_bind, %s (0x%x)",
! xlate_nt_status(status), status);
!
! errout:
! handle->clnt = NULL;
! if (clnt != NULL) {
! ndr_heap_destroy(clnt->heap);
! free(clnt);
! }
if (ctx != NULL) {
- if (fd != -1)
- (void) smb_fh_close(fd);
smbrdr_ctx_free(ctx);
}
return (status);
}
/*
! * Unbind and close the pipe to an RPC service.
*
! * If the heap has been preserved we need to go through an xa release.
! * The heap is preserved during an RPC call because that's where data
! * returned from the server is stored.
! *
! * Otherwise we destroy the heap directly.
*/
void
ndr_rpc_unbind(mlsvc_handle_t *handle)
{
! ndr_client_t *clnt = handle->clnt;
! struct smb_ctx *ctx = clnt->xa_private;
! if (clnt->heap_preserved)
! ndr_clnt_free_heap(clnt);
! else
! ndr_heap_destroy(clnt->heap);
!
! (void) smb_fh_close(clnt->xa_fd);
smbrdr_ctx_free(ctx);
! free(clnt);
bzero(handle, sizeof (mlsvc_handle_t));
}
void
ndr_rpc_status(mlsvc_handle_t *handle, int opnum, DWORD status)
--- 110,192 ----
if (status != NT_STATUS_SUCCESS) {
syslog(LOG_ERR, "ndr_rpc_bind: smbrdr_ctx_new"
"(Srv=%s Dom=%s User=%s), %s (0x%x)",
server, domain, username,
xlate_nt_status(status), status);
/*
! * If the error is one where changing to a new DC
! * might help, try looking for a different DC.
*/
! switch (status) {
! case NT_STATUS_BAD_NETWORK_PATH:
! case NT_STATUS_BAD_NETWORK_NAME:
! /* Look for a new DC */
! smb_ddiscover_bad_dc(server);
default:
break;
}
! return (status);
}
/*
* Setup the RPC client handle.
*/
! rc = mlrpc_clh_create(handle, ctx);
! if (rc != 0) {
! syslog(LOG_ERR, "ndr_rpc_bind: mlrpc_clh_create: rc=%d", rc);
! smbrdr_ctx_free(ctx);
! switch (rc) {
! case ENOMEM:
! return (NT_STATUS_NO_MEMORY);
! case EINVAL:
! return (NT_STATUS_INVALID_PARAMETER);
! default:
! return (NT_STATUS_INTERNAL_ERROR);
}
}
/*
! * This does the pipe open and OtW RPC bind.
! * Handles pipe open retries.
*/
! status = mlrpc_clh_bind(handle, svc);
! if (status != 0) {
! syslog(LOG_DEBUG, "ndr_rpc_bind: "
! "mlrpc_clh_bind, %s (0x%x)",
! xlate_nt_status(status), status);
! switch (status) {
! case RPC_NT_SERVER_TOO_BUSY:
! /* Look for a new DC */
! smb_ddiscover_bad_dc(server);
break;
default:
break;
}
! ctx = mlrpc_clh_free(handle);
if (ctx != NULL) {
smbrdr_ctx_free(ctx);
}
+ }
return (status);
}
/*
! * Unbind and close the pipe to an RPC service
! * and cleanup the smb_ctx.
*
! * The heap may or may not be destroyed (see mlrpc_clh_free)
*/
void
ndr_rpc_unbind(mlsvc_handle_t *handle)
{
! struct smb_ctx *ctx;
! ctx = mlrpc_clh_free(handle);
! if (ctx != NULL)
smbrdr_ctx_free(ctx);
!
bzero(handle, sizeof (mlsvc_handle_t));
}
void
ndr_rpc_status(mlsvc_handle_t *handle, int opnum, DWORD status)