xref: /onnv-gate/usr/src/cmd/smbsrv/smbd/smbd_share_doorsvc.c (revision 12508:edb7861a1533)
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