xref: /illumos-gate/usr/src/lib/smbsrv/libsmb/common/smb_doorclnt.c (revision 92a0208178405fef708b0283ffcaa02fbc3468ff)
1 /*
2  * CDDL HEADER START
3  *
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.
7  *
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.
12  *
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]
18  *
19  * CDDL HEADER END
20  */
21 /*
22  * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
23  * Use is subject to license terms.
24  */
25 
26 /*
27  * User-space door client routines for both SMB daemon and CLIs.
28  */
29 
30 #include <syslog.h>
31 #include <door.h>
32 #include <string.h>
33 #include <strings.h>
34 #include <stdlib.h>
35 #include <errno.h>
36 #include <sys/mman.h>
37 #include <smbsrv/libsmb.h>
38 #include <smbsrv/wintypes.h>
39 #include <smbsrv/smb_door_svc.h>
40 #include <smbsrv/smb_common_door.h>
41 
42 #define	SMB_DOOR_CALL_RETRIES		3
43 
44 void
45 smb_dr_clnt_setup(door_arg_t *arg, char *buf, size_t buflen)
46 {
47 	arg->data_ptr = buf;
48 	arg->data_size = buflen;
49 	arg->desc_ptr = NULL;
50 	arg->desc_num = 0;
51 	arg->rbuf = buf;
52 	arg->rsize = buflen;
53 }
54 
55 /*
56  * Free resources allocated for a door call.  If the result buffer provided
57  * by the client is too small, the doorfs will have allocated a new buffer,
58  * which must be unmapped here.
59  *
60  * This function must be called to free both the argument and result door
61  * buffers regardless of the status of the door call.
62  */
63 void
64 smb_dr_clnt_cleanup(door_arg_t *arg)
65 {
66 	if (arg->rbuf && (arg->rbuf != arg->data_ptr))
67 		(void) munmap(arg->rbuf, arg->rsize);
68 
69 	free(arg->data_ptr);
70 }
71 
72 /*
73  * Make a door call to the server function associated with the door
74  * descriptor fd.
75  *
76  * After a successful door call the local door_arg->data_ptr is assigned
77  * to the caller's arg->rbuf so that arg has references to both input and
78  * response buffers, which is required by smb_dr_clnt_free.
79  *
80  * On success, 0 will be returned and the call results can be referenced
81  * via arg->rbuf and arg->rsize.  Otherwise -1 will be returned.
82  */
83 int
84 smb_dr_clnt_call(int fd, door_arg_t *arg)
85 {
86 	door_arg_t door_arg;
87 	int rc;
88 	int i;
89 
90 	if (fd < 0 || arg == NULL)
91 		return (-1);
92 
93 	bcopy(arg, &door_arg, sizeof (door_arg_t));
94 
95 	for (i = 0; i < SMB_DOOR_CALL_RETRIES; ++i) {
96 		errno = 0;
97 
98 		if ((rc = door_call(fd, &door_arg)) == 0)
99 			break;
100 
101 		if (errno != EAGAIN && errno != EINTR)
102 			return (-1);
103 	}
104 
105 	if (rc != 0)
106 		return (-1);
107 
108 	if ((rc = smb_dr_get_res_stat(door_arg.data_ptr, door_arg.rsize)) != 0)
109 		rc = -1;
110 
111 	arg->rbuf = door_arg.data_ptr;
112 	arg->rsize = door_arg.rsize;
113 	return (rc);
114 }
115