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
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 *
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 /*
23 23 * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
↓ 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
128 104 * server, user, domain. It may return any 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;
440 202 case NT_STATUS_SEVERITY_INFORMATIONAL:
441 203 s = "info";
442 204 break;
443 205 case NT_STATUS_SEVERITY_WARNING:
444 206 s = "warning";
445 207 break;
446 208 case NT_STATUS_SEVERITY_ERROR:
447 209 s = "error";
↓ 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