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]
22 * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
23 * Copyright 2013 Nexenta Systems, Inc. All rights reserved.
27 * LanMan share door server
32 #include <sys/types.h>
40 #include <smbsrv/libsmb.h>
41 #include <smbsrv/smb_share.h>
42 #include <smbsrv/smbinfo.h>
45 #define SMB_SHARE_DSRV_VERSION 1
46 #define SMB_SHARE_DSRV_COOKIE ((void*)(0xdeadbeef^SMB_SHARE_DSRV_VERSION))
48 static int smb_share_dsrv_fd
= -1;
49 static pthread_mutex_t smb_share_dsrv_mtx
= PTHREAD_MUTEX_INITIALIZER
;
50 static smbd_door_t smb_share_sdh
;
52 static void smbd_share_dispatch(void *, char *, size_t, door_desc_t
*, uint_t
);
55 * Start the LanMan share door service.
56 * Returns 0 on success. Otherwise, -1.
59 smbd_share_start(void)
62 const char *door_name
;
64 (void) pthread_mutex_lock(&smb_share_dsrv_mtx
);
66 if (smb_share_dsrv_fd
!= -1) {
67 syslog(LOG_ERR
, "smbd_share_start: duplicate");
68 (void) pthread_mutex_unlock(&smb_share_dsrv_mtx
);
69 return (smb_share_dsrv_fd
);
72 smbd_door_init(&smb_share_sdh
, "share");
74 if ((smb_share_dsrv_fd
= door_create(smbd_share_dispatch
,
75 SMB_SHARE_DSRV_COOKIE
, (DOOR_UNREF
| DOOR_REFUSE_DESC
))) < 0) {
76 syslog(LOG_ERR
, "smbd_share_start: door_create: %s",
78 (void) pthread_mutex_unlock(&smb_share_dsrv_mtx
);
82 door_name
= getenv("SMB_SHARE_DNAME");
83 if (door_name
== NULL
)
84 door_name
= SMB_SHARE_DNAME
;
86 (void) unlink(door_name
);
88 if ((newfd
= creat(door_name
, 0644)) < 0) {
89 syslog(LOG_ERR
, "smbd_share_start: open: %s",
91 (void) door_revoke(smb_share_dsrv_fd
);
92 smb_share_dsrv_fd
= -1;
93 (void) pthread_mutex_unlock(&smb_share_dsrv_mtx
);
98 (void) fdetach(door_name
);
100 if (fattach(smb_share_dsrv_fd
, door_name
) < 0) {
101 syslog(LOG_ERR
, "smbd_share_start: fattach: %s",
103 (void) door_revoke(smb_share_dsrv_fd
);
104 smb_share_dsrv_fd
= -1;
105 (void) pthread_mutex_unlock(&smb_share_dsrv_mtx
);
109 (void) pthread_mutex_unlock(&smb_share_dsrv_mtx
);
110 return (smb_share_dsrv_fd
);
114 * Stop the LanMan share door service.
117 smbd_share_stop(void)
119 (void) pthread_mutex_lock(&smb_share_dsrv_mtx
);
121 smbd_door_fini(&smb_share_sdh
);
123 if (smb_share_dsrv_fd
!= -1) {
124 const char *door_name
;
126 door_name
= getenv("SMB_SHARE_DNAME");
127 if (door_name
== NULL
)
128 door_name
= SMB_SHARE_DNAME
;
129 (void) fdetach(door_name
);
130 (void) door_revoke(smb_share_dsrv_fd
);
131 smb_share_dsrv_fd
= -1;
134 (void) pthread_mutex_unlock(&smb_share_dsrv_mtx
);
138 * This function with which the LMSHARE door is associated
139 * will invoke the appropriate CIFS share management function
140 * based on the request type of the door call.
144 smbd_share_dispatch(void *cookie
, char *ptr
, size_t size
, door_desc_t
*dp
,
149 char buf
[SMB_SHARE_DSIZE
];
151 smb_dr_ctx_t
*dec_ctx
;
152 smb_dr_ctx_t
*enc_ctx
;
153 unsigned int dec_status
;
154 unsigned int enc_status
;
155 char *sharename
, *sharename2
;
156 smb_share_t lmshr_info
;
157 smb_shrlist_t lmshr_list
;
160 smbd_door_enter(&smb_share_sdh
);
162 if ((cookie
!= SMB_SHARE_DSRV_COOKIE
) || (ptr
== NULL
) ||
163 (size
< sizeof (uint32_t))) {
164 smbd_door_return(&smb_share_sdh
, NULL
, 0, NULL
, 0);
167 dec_ctx
= smb_dr_decode_start(ptr
, size
);
168 enc_ctx
= smb_dr_encode_start(buf
, sizeof (buf
));
169 req_type
= smb_dr_get_uint32(dec_ctx
);
172 case SMB_SHROP_NUM_SHARES
:
173 if ((dec_status
= smb_dr_decode_finish(dec_ctx
)) != 0)
176 rc
= smb_shr_count();
177 smb_dr_put_int32(enc_ctx
, SMB_SHARE_DSUCCESS
);
178 smb_dr_put_uint32(enc_ctx
, rc
);
181 case SMB_SHROP_DELETE
:
182 sharename
= smb_dr_get_string(dec_ctx
);
184 if ((dec_status
= smb_dr_decode_finish(dec_ctx
)) != 0) {
185 smb_dr_free_string(sharename
);
189 rc
= smb_shr_remove(sharename
);
190 smb_dr_put_int32(enc_ctx
, SMB_SHARE_DSUCCESS
);
191 smb_dr_put_uint32(enc_ctx
, rc
);
192 smb_dr_free_string(sharename
);
195 case SMB_SHROP_RENAME
:
196 sharename
= smb_dr_get_string(dec_ctx
);
197 sharename2
= smb_dr_get_string(dec_ctx
);
199 if ((dec_status
= smb_dr_decode_finish(dec_ctx
)) != 0) {
200 smb_dr_free_string(sharename
);
201 smb_dr_free_string(sharename2
);
205 rc
= smb_shr_rename(sharename
, sharename2
);
206 smb_dr_put_int32(enc_ctx
, SMB_SHARE_DSUCCESS
);
207 smb_dr_put_uint32(enc_ctx
, rc
);
208 smb_dr_free_string(sharename
);
209 smb_dr_free_string(sharename2
);
213 smb_dr_get_share(dec_ctx
, &lmshr_info
);
214 if ((dec_status
= smb_dr_decode_finish(dec_ctx
)) != 0)
217 rc
= smb_shr_add(&lmshr_info
);
218 smb_dr_put_int32(enc_ctx
, SMB_SHARE_DSUCCESS
);
219 smb_dr_put_uint32(enc_ctx
, rc
);
220 smb_dr_put_share(enc_ctx
, &lmshr_info
);
223 case SMB_SHROP_MODIFY
:
224 smb_dr_get_share(dec_ctx
, &lmshr_info
);
225 if ((dec_status
= smb_dr_decode_finish(dec_ctx
)) != 0) {
229 rc
= smb_shr_modify(&lmshr_info
);
230 smb_dr_put_int32(enc_ctx
, SMB_SHARE_DSUCCESS
);
231 smb_dr_put_uint32(enc_ctx
, rc
);
236 offset
= smb_dr_get_int32(dec_ctx
);
237 if ((dec_status
= smb_dr_decode_finish(dec_ctx
)) != 0)
240 smb_shr_list(offset
, &lmshr_list
);
241 smb_dr_put_int32(enc_ctx
, SMB_SHARE_DSUCCESS
);
242 smb_dr_put_buf(enc_ctx
, (unsigned char *)&lmshr_list
,
243 sizeof (smb_shrlist_t
));
247 dec_status
= smb_dr_decode_finish(dec_ctx
);
251 if ((enc_status
= smb_dr_encode_finish(enc_ctx
, &used
)) != 0) {
252 enc_ctx
= smb_dr_encode_start(buf
, sizeof (buf
));
253 smb_dr_put_int32(enc_ctx
, SMB_SHARE_DERROR
);
254 smb_dr_put_uint32(enc_ctx
, enc_status
);
255 (void) smb_dr_encode_finish(enc_ctx
, &used
);
258 smbd_door_return(&smb_share_sdh
, buf
, used
, NULL
, 0);
262 smb_dr_put_int32(enc_ctx
, SMB_SHARE_DERROR
);
263 smb_dr_put_uint32(enc_ctx
, dec_status
);
264 (void) smb_dr_encode_finish(enc_ctx
, &used
);
265 smbd_door_return(&smb_share_sdh
, buf
, used
, NULL
, 0);