Print this page
1575 untangle libmlrpc from SMB server
Reviewed by: Matt Barden <matt.barden@nexenta.com>
Reviewed by: Evan Layton <evan.layton@nexenta.com>
Reviewed by: Toomas Soome <tsoome@me.com>
Approved by: Richard Lowe <richlowe@richlowe.net>
NEX-15558 SMB logon fails during 1st second after service start
Reviewed by: Matt Barden <matt.barden@nexenta.com>
Reviewed by: Evan Layton <evan.layton@nexenta.com>
NEX-15558 SMB logon fails during 1st second after service start
Reviewed by: Matt Barden <matt.barden@nexenta.com>
Reviewed by: Evan Layton <evan.layton@nexenta.com>
NEX-2667 Wrong error when join domain with wrong password
Reviewed by: Kevin Crowe <kevin.crowe@nexenta.com>
Reviewed by: Bayard Bell <bayard.bell@nexenta.com>
NEX-2225 Unable to join NexentaStor to 2008 AD
re #12435 rb3958 r10 is added 2 times to panic info
re #12393 rb3935 Kerberos and smbd disagree about who is our AD server
        
*** 19,65 ****
   * CDDL HEADER END
   */
  
  /*
   * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
!  * Copyright 2015 Nexenta Systems, Inc.  All rights reserved.
   */
  
  /*
   * Client NDR RPC interface.
   */
  
  #include <sys/types.h>
  #include <sys/errno.h>
  #include <sys/fcntl.h>
- #include <sys/tzfile.h>
  #include <time.h>
  #include <strings.h>
  #include <assert.h>
  #include <errno.h>
  #include <thread.h>
- #include <unistd.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>
  
- static int ndr_xa_init(ndr_client_t *, ndr_xa_t *);
- static int ndr_xa_exchange(ndr_client_t *, ndr_xa_t *);
- static int ndr_xa_read(ndr_client_t *, ndr_xa_t *);
- static void ndr_xa_preserve(ndr_client_t *, ndr_xa_t *);
- static void ndr_xa_destruct(ndr_client_t *, ndr_xa_t *);
- static void ndr_xa_release(ndr_client_t *);
  
- 
  /*
   * This call must be made to initialize an RPC client structure and bind
   * to the remote service before any RPCs can be exchanged with that service.
   *
   * The mlsvc_handle_t is a wrapper that is used to associate an RPC handle
--- 19,55 ----
   * CDDL HEADER END
   */
  
  /*
   * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
!  * Copyright 2017 Nexenta Systems, Inc.  All rights reserved.
   */
  
  /*
   * Client NDR RPC interface.
   */
  
  #include <sys/types.h>
  #include <sys/errno.h>
  #include <sys/fcntl.h>
  #include <time.h>
  #include <strings.h>
  #include <assert.h>
  #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>
  
  
  /*
   * This call must be made to initialize an RPC client structure and bind
   * to the remote service before any RPCs can be exchanged with that service.
   *
   * The mlsvc_handle_t is a wrapper that is used to associate an RPC handle
*** 69,98 ****
   *
   * 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;
-         srvsvc_server_info_t    svinfo;
          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);
*** 100,122 ****
          /* In case the service was not registered... */
          if ((svc = ndr_svc_lookup_name(service)) == NULL)
                  return (NT_STATUS_INTERNAL_ERROR);
  
          /*
-          * Set the default based on the assumption that most
-          * servers will be Windows 2000 or later.  This used to
-          * try to get the actual server version, but that RPC
-          * is not necessarily allowed anymore, so don't bother.
-          */
-         bzero(&svinfo, sizeof (srvsvc_server_info_t));
-         svinfo.sv_platform_id = SV_PLATFORM_ID_NT;
-         svinfo.sv_version_major = 5;
-         svinfo.sv_version_minor = 0;
-         svinfo.sv_type = SV_TYPE_DEFAULT;
-         svinfo.sv_os = NATIVE_OS_WIN2000;
- 
-         /*
           * Some callers pass this when they want a NULL session.
           * Todo: have callers pass an empty string for that.
           */
          if (strcmp(username, MLSVC_ANON_USER) == 0)
                  username = "";
--- 89,98 ----
*** 134,434 ****
          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;
!         bcopy(&svinfo, &handle->svinfo, sizeof (srvsvc_server_info_t));
! 
!         /*
!          * 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));
  }
  
- /*
-  * Call the RPC function identified by opnum.  The remote service is
-  * identified by the handle, which should have been initialized by
-  * ndr_rpc_bind.
-  *
-  * If the RPC call is successful (returns 0), the caller must call
-  * ndr_rpc_release to release the heap.  Otherwise, we release the
-  * heap here.
-  */
- int
- ndr_rpc_call(mlsvc_handle_t *handle, int opnum, void *params)
- {
-         ndr_client_t *clnt = handle->clnt;
-         int rc;
- 
-         if (ndr_rpc_get_heap(handle) == NULL)
-                 return (-1);
- 
-         rc = ndr_clnt_call(clnt->binding, opnum, params);
- 
-         /*
-          * Always clear the nonull flag to ensure
-          * it is not applied to subsequent calls.
-          */
-         clnt->nonull = B_FALSE;
- 
-         if (NDR_DRC_IS_FAULT(rc)) {
-                 ndr_rpc_release(handle);
-                 return (-1);
-         }
- 
-         return (0);
- }
- 
- /*
-  * Outgoing strings should not be null terminated.
-  */
  void
- ndr_rpc_set_nonull(mlsvc_handle_t *handle)
- {
-         handle->clnt->nonull = B_TRUE;
- }
- 
- /*
-  * Return a reference to the server info.
-  */
- const srvsvc_server_info_t *
- ndr_rpc_server_info(mlsvc_handle_t *handle)
- {
-         return (&handle->svinfo);
- }
- 
- /*
-  * Return the RPC server OS level.
-  */
- uint32_t
- ndr_rpc_server_os(mlsvc_handle_t *handle)
- {
-         return (handle->svinfo.sv_os);
- }
- 
- /*
-  * Get the session key from a bound RPC client handle.
-  *
-  * The key returned is the 16-byte "user session key"
-  * established by the underlying authentication protocol
-  * (either Kerberos or NTLM).  This key is needed for
-  * SAM RPC calls such as SamrSetInformationUser, etc.
-  * See [MS-SAMR] sections: 2.2.3.3, 2.2.7.21, 2.2.7.25.
-  *
-  * Returns zero (success) or an errno.
-  */
- int
- ndr_rpc_get_ssnkey(mlsvc_handle_t *handle,
-         unsigned char *ssn_key, size_t len)
- {
-         ndr_client_t *clnt = handle->clnt;
-         int rc;
- 
-         if (clnt == NULL)
-                 return (EINVAL);
- 
-         rc = smb_fh_getssnkey(clnt->xa_fd, ssn_key, len);
-         return (rc);
- }
- 
- void *
- ndr_rpc_malloc(mlsvc_handle_t *handle, size_t size)
- {
-         ndr_heap_t *heap;
- 
-         if ((heap = ndr_rpc_get_heap(handle)) == NULL)
-                 return (NULL);
- 
-         return (ndr_heap_malloc(heap, size));
- }
- 
- ndr_heap_t *
- ndr_rpc_get_heap(mlsvc_handle_t *handle)
- {
-         ndr_client_t *clnt = handle->clnt;
- 
-         if (clnt->heap == NULL)
-                 clnt->heap = ndr_heap_create();
- 
-         return (clnt->heap);
- }
- 
- /*
-  * Must be called by RPC clients to free the heap after a successful RPC
-  * call, i.e. ndr_rpc_call returned 0.  The caller should take a copy
-  * of any data returned by the RPC prior to calling this function because
-  * returned data is in the heap.
-  */
- void
- ndr_rpc_release(mlsvc_handle_t *handle)
- {
-         ndr_client_t *clnt = handle->clnt;
- 
-         if (clnt->heap_preserved)
-                 ndr_clnt_free_heap(clnt);
-         else
-                 ndr_heap_destroy(clnt->heap);
- 
-         clnt->heap = NULL;
- }
- 
- /*
-  * Returns true if the handle is null.
-  * Otherwise returns false.
-  */
- boolean_t
- ndr_is_null_handle(mlsvc_handle_t *handle)
- {
-         static ndr_hdid_t zero_handle;
- 
-         if (handle == NULL || handle->clnt == NULL)
-                 return (B_TRUE);
- 
-         if (!memcmp(&handle->handle, &zero_handle, sizeof (ndr_hdid_t)))
-                 return (B_TRUE);
- 
-         return (B_FALSE);
- }
- 
- /*
-  * Returns true if the handle is the top level bind handle.
-  * Otherwise returns false.
-  */
- boolean_t
- ndr_is_bind_handle(mlsvc_handle_t *handle)
- {
-         return (handle->clnt->handle == &handle->handle);
- }
- 
- /*
-  * Pass the client reference from parent to child.
-  */
- void
- ndr_inherit_handle(mlsvc_handle_t *child, mlsvc_handle_t *parent)
- {
-         child->clnt = parent->clnt;
-         bcopy(&parent->svinfo, &child->svinfo, sizeof (srvsvc_server_info_t));
- }
- 
- void
  ndr_rpc_status(mlsvc_handle_t *handle, int opnum, DWORD status)
  {
          ndr_service_t *svc;
          char *name = "NDR RPC";
          char *s = "unknown";
--- 110,196 ----
          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)
  {
          ndr_service_t *svc;
          char *name = "NDR RPC";
          char *s = "unknown";
*** 453,648 ****
                  name = svc->name;
          }
  
          smb_tracef("%s[0x%02x]: %s: %s (0x%08x)",
              name, opnum, s, xlate_nt_status(status), status);
- }
- 
- /*
-  * The following functions provide the client callback interface.
-  * If the caller hasn't provided a heap, create one here.
-  */
- static int
- ndr_xa_init(ndr_client_t *clnt, ndr_xa_t *mxa)
- {
-         ndr_stream_t    *recv_nds = &mxa->recv_nds;
-         ndr_stream_t    *send_nds = &mxa->send_nds;
-         ndr_heap_t      *heap = clnt->heap;
-         int             rc;
- 
-         if (heap == NULL) {
-                 if ((heap = ndr_heap_create()) == NULL)
-                         return (-1);
- 
-                 clnt->heap = heap;
-         }
- 
-         mxa->heap = heap;
- 
-         rc = nds_initialize(send_nds, 0, NDR_MODE_CALL_SEND, heap);
-         if (rc == 0)
-                 rc = nds_initialize(recv_nds, NDR_PDU_SIZE_HINT_DEFAULT,
-                     NDR_MODE_RETURN_RECV, heap);
- 
-         if (rc != 0) {
-                 nds_destruct(&mxa->recv_nds);
-                 nds_destruct(&mxa->send_nds);
-                 ndr_heap_destroy(mxa->heap);
-                 mxa->heap = NULL;
-                 clnt->heap = NULL;
-                 return (-1);
-         }
- 
-         if (clnt->nonull)
-                 NDS_SETF(send_nds, NDS_F_NONULL);
- 
-         return (0);
- }
- 
- /*
-  * This is the entry pointy for an RPC client call exchange with
-  * a server, which will result in an smbrdr SmbTransact request.
-  *
-  * SmbTransact should return the number of bytes received, which
-  * we record as the PDU size, or a negative error code.
-  */
- static int
- ndr_xa_exchange(ndr_client_t *clnt, ndr_xa_t *mxa)
- {
-         ndr_stream_t *recv_nds = &mxa->recv_nds;
-         ndr_stream_t *send_nds = &mxa->send_nds;
-         int err, more, nbytes;
- 
-         nbytes = recv_nds->pdu_max_size;
-         err = smb_fh_xactnp(clnt->xa_fd,
-             send_nds->pdu_size, (char *)send_nds->pdu_base_offset,
-             &nbytes, (char *)recv_nds->pdu_base_offset, &more);
-         if (err) {
-                 recv_nds->pdu_size = 0;
-                 return (-1);
-         }
- 
-         recv_nds->pdu_size = nbytes;
-         return (0);
- }
- 
- /*
-  * This entry point will be invoked if the xa-exchange response contained
-  * only the first fragment of a multi-fragment response.  The RPC client
-  * code will then make repeated xa-read requests to obtain the remaining
-  * fragments, which will result in smbrdr SmbReadX requests.
-  *
-  * SmbReadX should return the number of bytes received, in which case we
-  * expand the PDU size to include the received data, or a negative error
-  * code.
-  */
- static int
- ndr_xa_read(ndr_client_t *clnt, ndr_xa_t *mxa)
- {
-         ndr_stream_t *nds = &mxa->recv_nds;
-         int len;
-         int nbytes;
- 
-         if ((len = (nds->pdu_max_size - nds->pdu_size)) < 0)
-                 return (-1);
- 
-         nbytes = smb_fh_read(clnt->xa_fd, 0, len,
-             (char *)nds->pdu_base_offset + nds->pdu_size);
- 
-         if (nbytes < 0)
-                 return (-1);
- 
-         nds->pdu_size += nbytes;
- 
-         if (nds->pdu_size > nds->pdu_max_size) {
-                 nds->pdu_size = nds->pdu_max_size;
-                 return (-1);
-         }
- 
-         return (nbytes);
- }
- 
- /*
-  * Preserve the heap so that the client application has access to data
-  * returned from the server after an RPC call.
-  */
- static void
- ndr_xa_preserve(ndr_client_t *clnt, ndr_xa_t *mxa)
- {
-         assert(clnt->heap == mxa->heap);
- 
-         clnt->heap_preserved = B_TRUE;
-         mxa->heap = NULL;
- }
- 
- /*
-  * Dispose of the transaction streams.  If the heap has not been
-  * preserved, we can destroy it here.
-  */
- static void
- ndr_xa_destruct(ndr_client_t *clnt, ndr_xa_t *mxa)
- {
-         nds_destruct(&mxa->recv_nds);
-         nds_destruct(&mxa->send_nds);
- 
-         if (!clnt->heap_preserved) {
-                 ndr_heap_destroy(mxa->heap);
-                 mxa->heap = NULL;
-                 clnt->heap = NULL;
-         }
- }
- 
- /*
-  * Dispose of a preserved heap.
-  */
- static void
- ndr_xa_release(ndr_client_t *clnt)
- {
-         if (clnt->heap_preserved) {
-                 ndr_heap_destroy(clnt->heap);
-                 clnt->heap = NULL;
-                 clnt->heap_preserved = B_FALSE;
-         }
- }
- 
- 
- /*
-  * Compare the time here with the remote time on the server
-  * and report clock skew.
-  */
- void
- ndr_srvsvc_timecheck(char *server, char *domain)
- {
-         char                    hostname[MAXHOSTNAMELEN];
-         struct timeval          dc_tv;
-         struct tm               dc_tm;
-         struct tm               *tm;
-         time_t                  tnow;
-         time_t                  tdiff;
-         int                     priority;
- 
-         if (srvsvc_net_remote_tod(server, domain, &dc_tv, &dc_tm) < 0) {
-                 syslog(LOG_DEBUG, "srvsvc_net_remote_tod failed");
-                 return;
-         }
- 
-         tnow = time(NULL);
- 
-         if (tnow > dc_tv.tv_sec)
-                 tdiff = (tnow - dc_tv.tv_sec) / SECSPERMIN;
-         else
-                 tdiff = (dc_tv.tv_sec - tnow) / SECSPERMIN;
- 
-         if (tdiff != 0) {
-                 (void) strlcpy(hostname, "localhost", MAXHOSTNAMELEN);
-                 (void) gethostname(hostname, MAXHOSTNAMELEN);
- 
-                 priority = (tdiff > 2) ? LOG_NOTICE : LOG_DEBUG;
-                 syslog(priority, "DC [%s] clock skew detected: %u minutes",
-                     server, tdiff);
- 
-                 tm = gmtime(&dc_tv.tv_sec);
-                 syslog(priority, "%-8s  UTC: %s", server, asctime(tm));
-                 tm = gmtime(&tnow);
-                 syslog(priority, "%-8s  UTC: %s", hostname, asctime(tm));
-         }
  }
--- 215,220 ----