Print this page
1575 untangle libmlrpc ... (smbsrv)
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.
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>
↓ open down ↓ |
31 lines elided |
↑ open up ↑ |
32 32 #include <sys/errno.h>
33 33 #include <sys/fcntl.h>
34 34 #include <time.h>
35 35 #include <strings.h>
36 36 #include <assert.h>
37 37 #include <errno.h>
38 38 #include <thread.h>
39 39 #include <syslog.h>
40 40 #include <synch.h>
41 41
42 +#include <libmlrpc/libmlrpc.h>
42 43 #include <netsmb/smbfs_api.h>
44 +
43 45 #include <smbsrv/libsmb.h>
44 -#include <smbsrv/libsmbns.h>
45 -#include <smbsrv/libmlrpc.h>
46 46 #include <smbsrv/libmlsvc.h>
47 -#include <smbsrv/ndl/srvsvc.ndl>
48 47 #include <libsmbrdr.h>
49 48 #include <mlsvc.h>
50 49
51 50
52 51 /*
53 52 * This call must be made to initialize an RPC client structure and bind
54 53 * to the remote service before any RPCs can be exchanged with that service.
55 54 *
56 55 * The mlsvc_handle_t is a wrapper that is used to associate an RPC handle
57 56 * with the client context for an instance of the interface. The handle
58 57 * is zeroed to ensure that it doesn't look like a valid handle -
59 58 * handle content is provided by the remove service.
60 59 *
61 60 * The client points to this top-level handle so that we know when to
62 61 * unbind and teardown the connection. As each handle is initialized it
63 62 * will inherit a reference to the client context.
64 63 *
65 - * Returns 0 or an NT_STATUS:
64 + * Returns 0 or an NT_STATUS: (failed in...)
65 + *
66 66 * NT_STATUS_BAD_NETWORK_PATH (get server addr)
67 67 * NT_STATUS_NETWORK_ACCESS_DENIED (connect, auth)
68 - * 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)
69 71 * NT_STATUS_ACCESS_DENIED (open pipe)
70 72 * NT_STATUS_INVALID_PARAMETER (rpc bind)
71 - *
72 73 * NT_STATUS_INTERNAL_ERROR (bad args etc)
73 74 * NT_STATUS_NO_MEMORY
74 75 */
75 76 DWORD
76 77 ndr_rpc_bind(mlsvc_handle_t *handle, char *server, char *domain,
77 78 char *username, const char *service)
78 79 {
79 80 struct smb_ctx *ctx = NULL;
80 - ndr_client_t *clnt = NULL;
81 81 ndr_service_t *svc;
82 82 DWORD status;
83 - int fd = -1;
84 83 int rc;
85 84
86 85 if (handle == NULL || server == NULL || server[0] == '\0' ||
87 86 domain == NULL || username == NULL)
88 87 return (NT_STATUS_INTERNAL_ERROR);
89 88
90 89 /* In case the service was not registered... */
91 90 if ((svc = ndr_svc_lookup_name(service)) == NULL)
92 91 return (NT_STATUS_INTERNAL_ERROR);
93 92
94 93 /*
95 94 * Some callers pass this when they want a NULL session.
96 95 * Todo: have callers pass an empty string for that.
97 96 */
98 97 if (strcmp(username, MLSVC_ANON_USER) == 0)
99 98 username = "";
100 99
101 100 /*
102 101 * Setup smbfs library handle, authenticate, connect to
103 102 * the IPC$ share. This will reuse an existing connection
104 103 * if the driver already has one for this combination of
105 104 * server, user, domain. It may return any of:
↓ open down ↓ |
12 lines elided |
↑ open up ↑ |
106 105 * NT_STATUS_BAD_NETWORK_PATH (get server addr)
107 106 * NT_STATUS_NETWORK_ACCESS_DENIED (connect, auth)
108 107 * NT_STATUS_BAD_NETWORK_NAME (tcon)
109 108 */
110 109 status = smbrdr_ctx_new(&ctx, server, domain, username);
111 110 if (status != NT_STATUS_SUCCESS) {
112 111 syslog(LOG_ERR, "ndr_rpc_bind: smbrdr_ctx_new"
113 112 "(Srv=%s Dom=%s User=%s), %s (0x%x)",
114 113 server, domain, username,
115 114 xlate_nt_status(status), status);
116 - /* Tell the DC Locator this DC failed. */
117 - smb_ddiscover_bad_dc(server);
118 - goto errout;
119 - }
120 -
121 - /*
122 - * Open the named pipe.
123 - */
124 - fd = smb_fh_open(ctx, svc->endpoint, O_RDWR);
125 - if (fd < 0) {
126 - rc = errno;
127 - syslog(LOG_DEBUG, "ndr_rpc_bind: "
128 - "smb_fh_open (%s) err=%d",
129 - svc->endpoint, rc);
130 - switch (rc) {
131 - case EACCES:
132 - status = NT_STATUS_ACCESS_DENIED;
133 - 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);
134 124 default:
135 - status = NT_STATUS_BAD_NETWORK_NAME;
136 125 break;
137 126 }
138 - goto errout;
127 + return (status);
139 128 }
140 129
141 130 /*
142 131 * Setup the RPC client handle.
143 132 */
144 - if ((clnt = malloc(sizeof (ndr_client_t))) == NULL) {
145 - status = NT_STATUS_NO_MEMORY;
146 - 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 + }
147 145 }
148 - bzero(clnt, sizeof (ndr_client_t));
149 146
150 - clnt->handle = &handle->handle;
151 - clnt->xa_init = ndr_xa_init;
152 - clnt->xa_exchange = ndr_xa_exchange;
153 - clnt->xa_read = ndr_xa_read;
154 - clnt->xa_preserve = ndr_xa_preserve;
155 - clnt->xa_destruct = ndr_xa_destruct;
156 - clnt->xa_release = ndr_xa_release;
157 - clnt->xa_private = ctx;
158 - clnt->xa_fd = fd;
159 -
160 - ndr_svc_binding_pool_init(&clnt->binding_list,
161 - clnt->binding_pool, NDR_N_BINDING_POOL);
162 -
163 - if ((clnt->heap = ndr_heap_create()) == NULL) {
164 - status = NT_STATUS_NO_MEMORY;
165 - goto errout;
166 - }
167 -
168 147 /*
169 - * Fill in the caller's handle.
148 + * This does the pipe open and OtW RPC bind.
149 + * Handles pipe open retries.
170 150 */
171 - bzero(&handle->handle, sizeof (ndr_hdid_t));
172 - handle->clnt = clnt;
173 -
174 - /*
175 - * Do the OtW RPC bind.
176 - */
177 - rc = ndr_clnt_bind(clnt, service, &clnt->binding);
178 - switch (rc) {
179 - case NDR_DRC_FAULT_OUT_OF_MEMORY:
180 - status = NT_STATUS_NO_MEMORY;
181 - break;
182 - case NDR_DRC_FAULT_API_SERVICE_INVALID: /* not registered */
183 - status = NT_STATUS_INTERNAL_ERROR;
184 - break;
185 - default:
186 - if (NDR_DRC_IS_FAULT(rc)) {
187 - 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);
188 160 break;
161 + default:
162 + break;
189 163 }
190 - /* FALLTHROUGH */
191 - case NDR_DRC_OK:
192 - return (NT_STATUS_SUCCESS);
164 + ctx = mlrpc_clh_free(handle);
165 + if (ctx != NULL) {
166 + smbrdr_ctx_free(ctx);
167 + }
193 168 }
194 169
195 - syslog(LOG_DEBUG, "ndr_rpc_bind: "
196 - "ndr_clnt_bind, %s (0x%x)",
197 - xlate_nt_status(status), status);
198 -
199 -errout:
200 - handle->clnt = NULL;
201 - if (clnt != NULL) {
202 - ndr_heap_destroy(clnt->heap);
203 - free(clnt);
204 - }
205 - if (ctx != NULL) {
206 - if (fd != -1)
207 - (void) smb_fh_close(fd);
208 - smbrdr_ctx_free(ctx);
209 - }
210 -
211 170 return (status);
212 171 }
213 172
214 173 /*
215 - * 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.
216 176 *
217 - * If the heap has been preserved we need to go through an xa release.
218 - * The heap is preserved during an RPC call because that's where data
219 - * returned from the server is stored.
220 - *
221 - * Otherwise we destroy the heap directly.
177 + * The heap may or may not be destroyed (see mlrpc_clh_free)
222 178 */
223 179 void
224 180 ndr_rpc_unbind(mlsvc_handle_t *handle)
225 181 {
226 - ndr_client_t *clnt = handle->clnt;
227 - struct smb_ctx *ctx = clnt->xa_private;
182 + struct smb_ctx *ctx;
228 183
229 - if (clnt->heap_preserved)
230 - ndr_clnt_free_heap(clnt);
231 - else
232 - ndr_heap_destroy(clnt->heap);
184 + ctx = mlrpc_clh_free(handle);
185 + if (ctx != NULL)
186 + smbrdr_ctx_free(ctx);
233 187
234 - (void) smb_fh_close(clnt->xa_fd);
235 - smbrdr_ctx_free(ctx);
236 - free(clnt);
237 188 bzero(handle, sizeof (mlsvc_handle_t));
238 189 }
239 190
240 191 void
241 192 ndr_rpc_status(mlsvc_handle_t *handle, int opnum, DWORD status)
242 193 {
243 194 ndr_service_t *svc;
244 195 char *name = "NDR RPC";
245 196 char *s = "unknown";
246 197
247 198 switch (NT_SC_SEVERITY(status)) {
248 199 case NT_STATUS_SEVERITY_SUCCESS:
249 200 s = "success";
250 201 break;
251 202 case NT_STATUS_SEVERITY_INFORMATIONAL:
252 203 s = "info";
253 204 break;
254 205 case NT_STATUS_SEVERITY_WARNING:
255 206 s = "warning";
256 207 break;
257 208 case NT_STATUS_SEVERITY_ERROR:
258 209 s = "error";
259 210 break;
260 211 }
261 212
262 213 if (handle) {
263 214 svc = handle->clnt->binding->service;
264 215 name = svc->name;
265 216 }
266 217
267 218 smb_tracef("%s[0x%02x]: %s: %s (0x%08x)",
268 219 name, opnum, s, xlate_nt_status(status), status);
269 220 }
↓ open down ↓ |
23 lines elided |
↑ open up ↑ |
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX