15331Samw /*
25331Samw * CDDL HEADER START
35331Samw *
45331Samw * The contents of this file are subject to the terms of the
55331Samw * Common Development and Distribution License (the "License").
65331Samw * You may not use this file except in compliance with the License.
75331Samw *
85331Samw * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
95331Samw * or http://www.opensolaris.org/os/licensing.
105331Samw * See the License for the specific language governing permissions
115331Samw * and limitations under the License.
125331Samw *
135331Samw * When distributing Covered Code, include this CDDL HEADER in each
145331Samw * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
155331Samw * If applicable, add the following below this CDDL HEADER, with the
165331Samw * fields enclosed by brackets "[]" replaced with your own identifying
175331Samw * information: Portions Copyright [yyyy] [name of copyright owner]
185331Samw *
195331Samw * CDDL HEADER END
205331Samw */
215331Samw /*
22*12065SKeyur.Desai@Sun.COM * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
235331Samw */
245331Samw
255331Samw /*
265331Samw * LanMan share door server
275331Samw */
285331Samw
295331Samw #include <door.h>
305331Samw #include <unistd.h>
315331Samw #include <sys/types.h>
325331Samw #include <sys/stat.h>
335331Samw #include <fcntl.h>
345331Samw #include <errno.h>
355331Samw #include <syslog.h>
365331Samw #include <string.h>
376771Sjb150015 #include <strings.h>
385331Samw #include <pthread.h>
395331Samw #include <smbsrv/libsmb.h>
407052Samw #include <smbsrv/smb_share.h>
415331Samw #include <smbsrv/smbinfo.h>
4211963SAfshin.Ardakani@Sun.COM #include "smbd.h"
435331Samw
447052Samw #define SMB_SHARE_DSRV_VERSION 1
457052Samw #define SMB_SHARE_DSRV_COOKIE ((void*)(0xdeadbeef^SMB_SHARE_DSRV_VERSION))
467052Samw
476771Sjb150015 static int smb_share_dsrv_fd = -1;
486771Sjb150015 static pthread_mutex_t smb_share_dsrv_mtx = PTHREAD_MUTEX_INITIALIZER;
4911963SAfshin.Ardakani@Sun.COM static smbd_door_t smb_share_sdh;
505331Samw
5111963SAfshin.Ardakani@Sun.COM static void smbd_share_dispatch(void *, char *, size_t, door_desc_t *, uint_t);
525331Samw
535331Samw /*
545331Samw * Start the LanMan share door service.
555331Samw * Returns 0 on success. Otherwise, -1.
565331Samw */
575331Samw int
smbd_share_start(void)5811963SAfshin.Ardakani@Sun.COM smbd_share_start(void)
595331Samw {
606139Sjb150015 int newfd;
615331Samw
626771Sjb150015 (void) pthread_mutex_lock(&smb_share_dsrv_mtx);
635331Samw
646771Sjb150015 if (smb_share_dsrv_fd != -1) {
6511963SAfshin.Ardakani@Sun.COM syslog(LOG_ERR, "smbd_share_start: duplicate");
666771Sjb150015 (void) pthread_mutex_unlock(&smb_share_dsrv_mtx);
676771Sjb150015 return (smb_share_dsrv_fd);
685331Samw }
695331Samw
7011963SAfshin.Ardakani@Sun.COM smbd_door_init(&smb_share_sdh, "share");
7111963SAfshin.Ardakani@Sun.COM
7211963SAfshin.Ardakani@Sun.COM if ((smb_share_dsrv_fd = door_create(smbd_share_dispatch,
737052Samw SMB_SHARE_DSRV_COOKIE, (DOOR_UNREF | DOOR_REFUSE_DESC))) < 0) {
7411963SAfshin.Ardakani@Sun.COM syslog(LOG_ERR, "smbd_share_start: door_create: %s",
755331Samw strerror(errno));
766771Sjb150015 (void) pthread_mutex_unlock(&smb_share_dsrv_mtx);
775331Samw return (-1);
785331Samw }
795331Samw
807052Samw (void) unlink(SMB_SHARE_DNAME);
815331Samw
827052Samw if ((newfd = creat(SMB_SHARE_DNAME, 0644)) < 0) {
8311963SAfshin.Ardakani@Sun.COM syslog(LOG_ERR, "smbd_share_start: open: %s",
845331Samw strerror(errno));
856771Sjb150015 (void) door_revoke(smb_share_dsrv_fd);
866771Sjb150015 smb_share_dsrv_fd = -1;
876771Sjb150015 (void) pthread_mutex_unlock(&smb_share_dsrv_mtx);
885331Samw return (-1);
895331Samw }
905331Samw
915331Samw (void) close(newfd);
927052Samw (void) fdetach(SMB_SHARE_DNAME);
935331Samw
947052Samw if (fattach(smb_share_dsrv_fd, SMB_SHARE_DNAME) < 0) {
9511963SAfshin.Ardakani@Sun.COM syslog(LOG_ERR, "smbd_share_start: fattach: %s",
965331Samw strerror(errno));
976771Sjb150015 (void) door_revoke(smb_share_dsrv_fd);
986771Sjb150015 smb_share_dsrv_fd = -1;
996771Sjb150015 (void) pthread_mutex_unlock(&smb_share_dsrv_mtx);
1005331Samw return (-1);
1015331Samw }
1025331Samw
1036771Sjb150015 (void) pthread_mutex_unlock(&smb_share_dsrv_mtx);
1046771Sjb150015 return (smb_share_dsrv_fd);
1055331Samw }
1065331Samw
1075331Samw /*
1085331Samw * Stop the LanMan share door service.
1095331Samw */
1105331Samw void
smbd_share_stop(void)11111963SAfshin.Ardakani@Sun.COM smbd_share_stop(void)
1125331Samw {
1136771Sjb150015 (void) pthread_mutex_lock(&smb_share_dsrv_mtx);
1145331Samw
11511963SAfshin.Ardakani@Sun.COM smbd_door_fini(&smb_share_sdh);
11611963SAfshin.Ardakani@Sun.COM
1176771Sjb150015 if (smb_share_dsrv_fd != -1) {
1187052Samw (void) fdetach(SMB_SHARE_DNAME);
1196771Sjb150015 (void) door_revoke(smb_share_dsrv_fd);
1206771Sjb150015 smb_share_dsrv_fd = -1;
1215331Samw }
1225331Samw
1236771Sjb150015 (void) pthread_mutex_unlock(&smb_share_dsrv_mtx);
1245331Samw }
1255331Samw
1265331Samw /*
1275331Samw * This function with which the LMSHARE door is associated
1285331Samw * will invoke the appropriate CIFS share management function
1295331Samw * based on the request type of the door call.
1305331Samw */
1315331Samw /*ARGSUSED*/
1326771Sjb150015 static void
smbd_share_dispatch(void * cookie,char * ptr,size_t size,door_desc_t * dp,uint_t n_desc)13311963SAfshin.Ardakani@Sun.COM smbd_share_dispatch(void *cookie, char *ptr, size_t size, door_desc_t *dp,
1345331Samw uint_t n_desc)
1355331Samw {
1367052Samw uint32_t rc;
1377052Samw int req_type;
1387052Samw char buf[SMB_SHARE_DSIZE];
1395331Samw unsigned int used;
1406771Sjb150015 smb_dr_ctx_t *dec_ctx;
1416771Sjb150015 smb_dr_ctx_t *enc_ctx;
1425331Samw unsigned int dec_status;
1435331Samw unsigned int enc_status;
1445331Samw char *sharename, *sharename2;
1457052Samw smb_share_t lmshr_info;
1467052Samw smb_shrlist_t lmshr_list;
1475331Samw int offset;
1485331Samw
14911963SAfshin.Ardakani@Sun.COM smbd_door_enter(&smb_share_sdh);
15011963SAfshin.Ardakani@Sun.COM
1517052Samw if ((cookie != SMB_SHARE_DSRV_COOKIE) || (ptr == NULL) ||
1526771Sjb150015 (size < sizeof (uint32_t))) {
15311963SAfshin.Ardakani@Sun.COM smbd_door_return(&smb_share_sdh, NULL, 0, NULL, 0);
1546771Sjb150015 }
1556771Sjb150015
1566771Sjb150015 dec_ctx = smb_dr_decode_start(ptr, size);
1576771Sjb150015 enc_ctx = smb_dr_encode_start(buf, sizeof (buf));
1585331Samw req_type = smb_dr_get_uint32(dec_ctx);
1595331Samw
1605331Samw switch (req_type) {
1617052Samw case SMB_SHROP_NUM_SHARES:
1625331Samw if ((dec_status = smb_dr_decode_finish(dec_ctx)) != 0)
1635331Samw goto decode_error;
1645331Samw
1657052Samw rc = smb_shr_count();
1667052Samw smb_dr_put_int32(enc_ctx, SMB_SHARE_DSUCCESS);
1675331Samw smb_dr_put_uint32(enc_ctx, rc);
1685331Samw break;
1695331Samw
1707052Samw case SMB_SHROP_DELETE:
1715331Samw sharename = smb_dr_get_string(dec_ctx);
1725331Samw
1735331Samw if ((dec_status = smb_dr_decode_finish(dec_ctx)) != 0) {
1745331Samw smb_dr_free_string(sharename);
1755331Samw goto decode_error;
1765331Samw }
1775331Samw
1787961SNatalie.Li@Sun.COM rc = smb_shr_remove(sharename);
1797052Samw smb_dr_put_int32(enc_ctx, SMB_SHARE_DSUCCESS);
1805331Samw smb_dr_put_uint32(enc_ctx, rc);
1815331Samw smb_dr_free_string(sharename);
1825331Samw break;
1835331Samw
1847052Samw case SMB_SHROP_RENAME:
1855331Samw sharename = smb_dr_get_string(dec_ctx);
1865331Samw sharename2 = smb_dr_get_string(dec_ctx);
1875331Samw
1885331Samw if ((dec_status = smb_dr_decode_finish(dec_ctx)) != 0) {
1895331Samw smb_dr_free_string(sharename);
1905331Samw smb_dr_free_string(sharename2);
1915331Samw goto decode_error;
1925331Samw }
1935331Samw
1947348SJose.Borrego@Sun.COM rc = smb_shr_rename(sharename, sharename2);
1957052Samw smb_dr_put_int32(enc_ctx, SMB_SHARE_DSUCCESS);
1965331Samw smb_dr_put_uint32(enc_ctx, rc);
1975331Samw smb_dr_free_string(sharename);
1985331Samw smb_dr_free_string(sharename2);
1995331Samw break;
2005331Samw
2017052Samw case SMB_SHROP_ADD:
2027052Samw smb_dr_get_share(dec_ctx, &lmshr_info);
2035331Samw if ((dec_status = smb_dr_decode_finish(dec_ctx)) != 0)
2045331Samw goto decode_error;
2055331Samw
2067961SNatalie.Li@Sun.COM rc = smb_shr_add(&lmshr_info);
2077052Samw smb_dr_put_int32(enc_ctx, SMB_SHARE_DSUCCESS);
2087052Samw smb_dr_put_uint32(enc_ctx, rc);
2097052Samw smb_dr_put_share(enc_ctx, &lmshr_info);
2107052Samw break;
2117052Samw
2127348SJose.Borrego@Sun.COM case SMB_SHROP_MODIFY:
2137961SNatalie.Li@Sun.COM smb_dr_get_share(dec_ctx, &lmshr_info);
2147348SJose.Borrego@Sun.COM if ((dec_status = smb_dr_decode_finish(dec_ctx)) != 0) {
2157052Samw goto decode_error;
2167348SJose.Borrego@Sun.COM }
2177052Samw
2187961SNatalie.Li@Sun.COM rc = smb_shr_modify(&lmshr_info);
2197052Samw smb_dr_put_int32(enc_ctx, SMB_SHARE_DSUCCESS);
2205331Samw smb_dr_put_uint32(enc_ctx, rc);
2217348SJose.Borrego@Sun.COM
2225331Samw break;
2235331Samw
2247052Samw case SMB_SHROP_LIST:
2255331Samw offset = smb_dr_get_int32(dec_ctx);
2265331Samw if ((dec_status = smb_dr_decode_finish(dec_ctx)) != 0)
2275331Samw goto decode_error;
2285331Samw
2297052Samw smb_shr_list(offset, &lmshr_list);
2307052Samw smb_dr_put_int32(enc_ctx, SMB_SHARE_DSUCCESS);
2317348SJose.Borrego@Sun.COM smb_dr_put_buf(enc_ctx, (unsigned char *)&lmshr_list,
2327348SJose.Borrego@Sun.COM sizeof (smb_shrlist_t));
2335331Samw break;
2345331Samw
2355331Samw default:
2365967Scp160787 dec_status = smb_dr_decode_finish(dec_ctx);
2375331Samw goto decode_error;
2385331Samw }
2395331Samw
2406771Sjb150015 if ((enc_status = smb_dr_encode_finish(enc_ctx, &used)) != 0) {
2416771Sjb150015 enc_ctx = smb_dr_encode_start(buf, sizeof (buf));
2427052Samw smb_dr_put_int32(enc_ctx, SMB_SHARE_DERROR);
2436771Sjb150015 smb_dr_put_uint32(enc_ctx, enc_status);
2446771Sjb150015 (void) smb_dr_encode_finish(enc_ctx, &used);
2456771Sjb150015 }
2465331Samw
24711963SAfshin.Ardakani@Sun.COM smbd_door_return(&smb_share_sdh, buf, used, NULL, 0);
2485331Samw return;
2495331Samw
2505331Samw decode_error:
2517052Samw smb_dr_put_int32(enc_ctx, SMB_SHARE_DERROR);
2525331Samw smb_dr_put_uint32(enc_ctx, dec_status);
2535331Samw (void) smb_dr_encode_finish(enc_ctx, &used);
25411963SAfshin.Ardakani@Sun.COM smbd_door_return(&smb_share_sdh, buf, used, NULL, 0);
2555331Samw }
256