dmake: do not set MAKEFLAGS=k
[unleashed/tickless.git] / usr / src / lib / libshare / smb / smb_share_doorclnt.c
blob7f5c19412c773e9970c4fe7677ba118dbd0521f9
1 /*
2 * CDDL HEADER START
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
19 * CDDL HEADER END
23 * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
24 * Copyright 2013 Nexenta Systems, Inc. All rights reserved.
28 * User-space door client for LanMan share management.
31 #include <syslog.h>
32 #include <door.h>
33 #include <fcntl.h>
34 #include <stdarg.h>
35 #include <errno.h>
36 #include <string.h>
37 #include <strings.h>
38 #include <unistd.h>
39 #include <thread.h>
40 #include <synch.h>
42 #include <smbsrv/libsmb.h>
43 #include <smbsrv/smb_share.h>
44 #include <smbsrv/smb.h>
46 #define SMB_SHARE_DOOR_CALL_RETRIES 3
48 static int smb_share_dfd = -1;
49 static uint64_t smb_share_dncall = 0;
50 static mutex_t smb_share_dmtx;
51 static cond_t smb_share_dcv;
53 static int smb_share_door_clnt_open(void);
54 static void smb_share_door_clnt_close(void);
56 void
57 smb_share_door_clnt_init(void)
59 (void) mutex_lock(&smb_share_dmtx);
60 (void) smb_share_door_clnt_open();
61 (void) mutex_unlock(&smb_share_dmtx);
64 void
65 smb_share_door_clnt_fini(void)
67 (void) mutex_lock(&smb_share_dmtx);
68 smb_share_door_clnt_close();
69 (void) mutex_unlock(&smb_share_dmtx);
73 * Open smb_share_door. This is a private call for use by
74 * smb_share_door_clnt_enter() and must be called with smb_share_dmtx held.
76 * Returns the door fd on success. Otherwise, -1.
78 static int
79 smb_share_door_clnt_open(void)
81 const char *door_name;
83 if (smb_share_dfd == -1) {
84 door_name = getenv("SMB_SHARE_DNAME");
85 if (door_name == NULL)
86 door_name = SMB_SHARE_DNAME;
88 if ((smb_share_dfd = open(door_name, O_RDONLY)) < 0)
89 smb_share_dfd = -1;
90 else
91 smb_share_dncall = 0;
94 return (smb_share_dfd);
98 * Close smb_share_door.
99 * Private call that must be called with smb_share_dmtx held.
101 static void
102 smb_share_door_clnt_close(void)
104 if (smb_share_dfd != -1) {
105 while (smb_share_dncall > 0)
106 (void) cond_wait(&smb_share_dcv, &smb_share_dmtx);
108 if (smb_share_dfd != -1) {
109 (void) close(smb_share_dfd);
110 smb_share_dfd = -1;
116 * Entry handler for smb_share_door calls.
118 static door_arg_t *
119 smb_share_door_clnt_enter(void)
121 door_arg_t *arg;
122 char *buf;
124 (void) mutex_lock(&smb_share_dmtx);
126 if (smb_share_door_clnt_open() == -1) {
127 (void) mutex_unlock(&smb_share_dmtx);
128 return (NULL);
131 if ((arg = malloc(sizeof (door_arg_t) + SMB_SHARE_DSIZE)) != NULL) {
132 buf = ((char *)arg) + sizeof (door_arg_t);
133 bzero(arg, sizeof (door_arg_t));
134 arg->data_ptr = buf;
135 arg->rbuf = buf;
136 arg->rsize = SMB_SHARE_DSIZE;
138 ++smb_share_dncall;
141 (void) mutex_unlock(&smb_share_dmtx);
142 return (arg);
146 * Exit handler for smb_share_door calls.
148 static void
149 smb_share_door_clnt_exit(door_arg_t *arg, boolean_t must_close, char *errmsg)
151 if (errmsg)
152 syslog(LOG_DEBUG, "smb_share_door: %s failed", errmsg);
154 (void) mutex_lock(&smb_share_dmtx);
155 free(arg);
156 --smb_share_dncall;
157 (void) cond_signal(&smb_share_dcv);
159 if (must_close)
160 smb_share_door_clnt_close();
162 (void) mutex_unlock(&smb_share_dmtx);
165 static int
166 smb_share_door_call(int fd, door_arg_t *arg)
168 int rc;
169 int i;
171 for (i = 0; i < SMB_SHARE_DOOR_CALL_RETRIES; ++i) {
172 errno = 0;
174 if ((rc = door_call(fd, arg)) == 0)
175 break;
177 if (errno != EAGAIN && errno != EINTR)
178 break;
181 return (rc);
184 static int
185 smb_share_dchk(smb_dr_ctx_t *dec_ctx)
187 int status = smb_dr_get_int32(dec_ctx);
189 if (status != SMB_SHARE_DSUCCESS) {
190 if (status == SMB_SHARE_DERROR)
191 (void) smb_dr_get_uint32(dec_ctx);
192 return (-1);
195 return (0);
198 uint32_t
199 smb_share_list(int offset, smb_shrlist_t *list)
201 door_arg_t *arg;
202 smb_dr_ctx_t *dec_ctx;
203 smb_dr_ctx_t *enc_ctx;
204 uint32_t rc;
206 bzero(list, sizeof (smb_shrlist_t));
208 if ((arg = smb_share_door_clnt_enter()) == NULL)
209 return (NERR_InternalError);
211 enc_ctx = smb_dr_encode_start(arg->data_ptr, SMB_SHARE_DSIZE);
212 smb_dr_put_uint32(enc_ctx, SMB_SHROP_LIST);
213 smb_dr_put_int32(enc_ctx, offset);
215 rc = smb_dr_encode_finish(enc_ctx, (unsigned int *)&arg->data_size);
216 if (rc != 0) {
217 smb_share_door_clnt_exit(arg, B_FALSE, "encode");
218 return (NERR_InternalError);
221 if (smb_share_door_call(smb_share_dfd, arg) < 0) {
222 smb_share_door_clnt_exit(arg, B_TRUE, "door call");
223 return (NERR_InternalError);
226 dec_ctx = smb_dr_decode_start(arg->data_ptr, arg->data_size);
227 if (smb_share_dchk(dec_ctx) != 0) {
228 (void) smb_dr_decode_finish(dec_ctx);
229 smb_share_door_clnt_exit(arg, B_FALSE, "decode");
230 return (NERR_InternalError);
233 (void) smb_dr_get_buf(dec_ctx, (unsigned char *)list,
234 sizeof (smb_shrlist_t));
235 if (smb_dr_decode_finish(dec_ctx) != 0) {
236 smb_share_door_clnt_exit(arg, B_FALSE, "decode");
237 return (NERR_InternalError);
240 smb_share_door_clnt_exit(arg, B_FALSE, NULL);
241 return (NERR_Success);
245 smb_share_count(void)
247 door_arg_t *arg;
248 smb_dr_ctx_t *dec_ctx;
249 smb_dr_ctx_t *enc_ctx;
250 uint32_t num_shares;
251 int rc;
253 if ((arg = smb_share_door_clnt_enter()) == NULL)
254 return (-1);
256 enc_ctx = smb_dr_encode_start(arg->data_ptr, SMB_SHARE_DSIZE);
257 smb_dr_put_uint32(enc_ctx, SMB_SHROP_NUM_SHARES);
259 rc = smb_dr_encode_finish(enc_ctx, (unsigned int *)&arg->data_size);
260 if (rc != 0) {
261 smb_share_door_clnt_exit(arg, B_FALSE, "encode");
262 return (-1);
265 if (smb_share_door_call(smb_share_dfd, arg) < 0) {
266 smb_share_door_clnt_exit(arg, B_TRUE, "door call");
267 return (-1);
270 dec_ctx = smb_dr_decode_start(arg->data_ptr, arg->data_size);
271 if (smb_share_dchk(dec_ctx) != 0) {
272 (void) smb_dr_decode_finish(dec_ctx);
273 smb_share_door_clnt_exit(arg, B_FALSE, "decode");
274 return (-1);
277 num_shares = smb_dr_get_uint32(dec_ctx);
278 if (smb_dr_decode_finish(dec_ctx) != 0) {
279 smb_share_door_clnt_exit(arg, B_FALSE, "decode");
280 return (-1);
283 smb_share_door_clnt_exit(arg, B_FALSE, NULL);
284 return (num_shares);
287 uint32_t
288 smb_share_delete(char *share_name)
290 door_arg_t *arg;
291 smb_dr_ctx_t *dec_ctx;
292 smb_dr_ctx_t *enc_ctx;
293 uint32_t rc;
295 if ((arg = smb_share_door_clnt_enter()) == NULL)
296 return (NERR_InternalError);
298 enc_ctx = smb_dr_encode_start(arg->data_ptr, SMB_SHARE_DSIZE);
299 smb_dr_put_uint32(enc_ctx, SMB_SHROP_DELETE);
300 smb_dr_put_string(enc_ctx, share_name);
302 rc = smb_dr_encode_finish(enc_ctx, (unsigned int *)&arg->data_size);
303 if (rc != 0) {
304 smb_share_door_clnt_exit(arg, B_FALSE, "encode");
305 return (NERR_InternalError);
308 if (smb_share_door_call(smb_share_dfd, arg) < 0) {
309 smb_share_door_clnt_exit(arg, B_TRUE, "door call");
310 return (NERR_InternalError);
313 dec_ctx = smb_dr_decode_start(arg->data_ptr, arg->data_size);
314 if (smb_share_dchk(dec_ctx) != 0) {
315 (void) smb_dr_decode_finish(dec_ctx);
316 smb_share_door_clnt_exit(arg, B_FALSE, "decode");
317 return (NERR_InternalError);
320 rc = smb_dr_get_uint32(dec_ctx);
321 if (smb_dr_decode_finish(dec_ctx) != 0) {
322 smb_share_door_clnt_exit(arg, B_FALSE, "decode");
323 return (NERR_InternalError);
326 smb_share_door_clnt_exit(arg, B_FALSE, NULL);
327 return (rc);
331 uint32_t
332 smb_share_rename(char *from, char *to)
334 door_arg_t *arg;
335 smb_dr_ctx_t *dec_ctx;
336 smb_dr_ctx_t *enc_ctx;
337 uint32_t rc;
339 if ((arg = smb_share_door_clnt_enter()) == NULL)
340 return (NERR_InternalError);
342 enc_ctx = smb_dr_encode_start(arg->data_ptr, SMB_SHARE_DSIZE);
343 smb_dr_put_uint32(enc_ctx, SMB_SHROP_RENAME);
344 smb_dr_put_string(enc_ctx, from);
345 smb_dr_put_string(enc_ctx, to);
347 rc = smb_dr_encode_finish(enc_ctx, (unsigned int *)&arg->data_size);
348 if (rc != 0) {
349 smb_share_door_clnt_exit(arg, B_FALSE, "encode");
350 return (NERR_InternalError);
353 if (smb_share_door_call(smb_share_dfd, arg) < 0) {
354 smb_share_door_clnt_exit(arg, B_TRUE, "door call");
355 return (NERR_InternalError);
358 dec_ctx = smb_dr_decode_start(arg->data_ptr, arg->data_size);
359 if (smb_share_dchk(dec_ctx) != 0) {
360 (void) smb_dr_decode_finish(dec_ctx);
361 smb_share_door_clnt_exit(arg, B_FALSE, "decode");
362 return (NERR_InternalError);
365 rc = smb_dr_get_uint32(dec_ctx);
366 if (smb_dr_decode_finish(dec_ctx) != 0) {
367 smb_share_door_clnt_exit(arg, B_FALSE, "decode");
368 return (NERR_InternalError);
371 smb_share_door_clnt_exit(arg, B_FALSE, NULL);
372 return (rc);
375 uint32_t
376 smb_share_create(smb_share_t *si)
378 door_arg_t *arg;
379 smb_dr_ctx_t *dec_ctx;
380 smb_dr_ctx_t *enc_ctx;
381 uint32_t rc;
383 if ((arg = smb_share_door_clnt_enter()) == NULL)
384 return (NERR_InternalError);
386 enc_ctx = smb_dr_encode_start(arg->data_ptr, SMB_SHARE_DSIZE);
387 smb_dr_put_uint32(enc_ctx, SMB_SHROP_ADD);
388 smb_dr_put_share(enc_ctx, si);
390 rc = smb_dr_encode_finish(enc_ctx, (unsigned int *)&arg->data_size);
391 if (rc != 0) {
392 smb_share_door_clnt_exit(arg, B_FALSE, "encode");
393 return (NERR_InternalError);
396 if (smb_share_door_call(smb_share_dfd, arg) < 0) {
397 smb_share_door_clnt_exit(arg, B_TRUE, "door call");
398 return (NERR_InternalError);
401 dec_ctx = smb_dr_decode_start(arg->data_ptr, arg->data_size);
402 if (smb_share_dchk(dec_ctx) != 0) {
403 (void) smb_dr_decode_finish(dec_ctx);
404 smb_share_door_clnt_exit(arg, B_FALSE, "decode");
405 return (NERR_InternalError);
408 rc = smb_dr_get_uint32(dec_ctx);
409 smb_dr_get_share(dec_ctx, si);
410 if (smb_dr_decode_finish(dec_ctx) != 0) {
411 smb_share_door_clnt_exit(arg, B_FALSE, "decode");
412 return (NERR_InternalError);
415 smb_share_door_clnt_exit(arg, B_FALSE, NULL);
416 return (rc);
419 uint32_t
420 smb_share_modify(smb_share_t *si)
422 door_arg_t *arg;
423 smb_dr_ctx_t *dec_ctx;
424 smb_dr_ctx_t *enc_ctx;
425 uint32_t rc;
427 if ((arg = smb_share_door_clnt_enter()) == NULL)
428 return (NERR_InternalError);
430 enc_ctx = smb_dr_encode_start(arg->data_ptr, SMB_SHARE_DSIZE);
431 smb_dr_put_uint32(enc_ctx, SMB_SHROP_MODIFY);
432 smb_dr_put_share(enc_ctx, si);
434 rc = smb_dr_encode_finish(enc_ctx, (unsigned int *)&arg->data_size);
435 if (rc != 0) {
436 smb_share_door_clnt_exit(arg, B_FALSE, "encode");
437 return (NERR_InternalError);
440 if (smb_share_door_call(smb_share_dfd, arg) < 0) {
441 smb_share_door_clnt_exit(arg, B_TRUE, "door call");
442 return (NERR_InternalError);
445 dec_ctx = smb_dr_decode_start(arg->data_ptr, arg->data_size);
446 if (smb_share_dchk(dec_ctx) != 0) {
447 (void) smb_dr_decode_finish(dec_ctx);
448 smb_share_door_clnt_exit(arg, B_FALSE, "decode");
449 return (NERR_InternalError);
452 rc = smb_dr_get_uint32(dec_ctx);
453 if (smb_dr_decode_finish(dec_ctx) != 0) {
454 smb_share_door_clnt_exit(arg, B_FALSE, "decode");
455 return (NERR_InternalError);
458 smb_share_door_clnt_exit(arg, B_FALSE, NULL);
459 return (rc);