16139Sjb150015 /* 26139Sjb150015 * CDDL HEADER START 36139Sjb150015 * 46139Sjb150015 * The contents of this file are subject to the terms of the 56139Sjb150015 * Common Development and Distribution License (the "License"). 66139Sjb150015 * You may not use this file except in compliance with the License. 76139Sjb150015 * 86139Sjb150015 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 96139Sjb150015 * or http://www.opensolaris.org/os/licensing. 106139Sjb150015 * See the License for the specific language governing permissions 116139Sjb150015 * and limitations under the License. 126139Sjb150015 * 136139Sjb150015 * When distributing Covered Code, include this CDDL HEADER in each 146139Sjb150015 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 156139Sjb150015 * If applicable, add the following below this CDDL HEADER, with the 166139Sjb150015 * fields enclosed by brackets "[]" replaced with your own identifying 176139Sjb150015 * information: Portions Copyright [yyyy] [name of copyright owner] 186139Sjb150015 * 196139Sjb150015 * CDDL HEADER END 206139Sjb150015 */ 216139Sjb150015 /* 2212065SKeyur.Desai@Sun.COM * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved. 236139Sjb150015 */ 246139Sjb150015 256139Sjb150015 /* 266139Sjb150015 * General Structures Layout 276139Sjb150015 * ------------------------- 286139Sjb150015 * 296139Sjb150015 * This is a simplified diagram showing the relationship between most of the 306139Sjb150015 * main structures. 316139Sjb150015 * 326139Sjb150015 * +-------------------+ 336139Sjb150015 * | SMB_SERVER | 346139Sjb150015 * +-------------------+ 356139Sjb150015 * | 366139Sjb150015 * | 376139Sjb150015 * v 386139Sjb150015 * +-------------------+ +-------------------+ +-------------------+ 396139Sjb150015 * | SESSION |<----->| SESSION |......| SESSION | 406139Sjb150015 * +-------------------+ +-------------------+ +-------------------+ 416139Sjb150015 * | 426139Sjb150015 * | 436139Sjb150015 * v 446139Sjb150015 * +-------------------+ +-------------------+ +-------------------+ 456139Sjb150015 * | USER |<----->| USER |......| USER | 466139Sjb150015 * +-------------------+ +-------------------+ +-------------------+ 476139Sjb150015 * | 486139Sjb150015 * | 496139Sjb150015 * v 506139Sjb150015 * +-------------------+ +-------------------+ +-------------------+ 516139Sjb150015 * | TREE |<----->| TREE |......| TREE | 526139Sjb150015 * +-------------------+ +-------------------+ +-------------------+ 536139Sjb150015 * | | 546139Sjb150015 * | | 556139Sjb150015 * | v 566139Sjb150015 * | +-------+ +-------+ +-------+ 576139Sjb150015 * | | OFILE |<----->| OFILE |......| OFILE | 586139Sjb150015 * | +-------+ +-------+ +-------+ 596139Sjb150015 * | 606139Sjb150015 * | 616139Sjb150015 * v 626139Sjb150015 * +-------+ +------+ +------+ 636139Sjb150015 * | ODIR |<----->| ODIR |......| ODIR | 646139Sjb150015 * +-------+ +------+ +------+ 656139Sjb150015 * 666139Sjb150015 * 676139Sjb150015 * Module Interface Overview 686139Sjb150015 * ------------------------- 696139Sjb150015 * 706139Sjb150015 * 716139Sjb150015 * +===================================+ 726139Sjb150015 * | smbd daemon | 736139Sjb150015 * +===================================+ 746139Sjb150015 * | | ^ 756139Sjb150015 * | | | 766139Sjb150015 * User | | | 776139Sjb150015 * -----------|--------------|----------------|-------------------------------- 786139Sjb150015 * Kernel | | | 796139Sjb150015 * | | | 806139Sjb150015 * | | | 816139Sjb150015 * +=========|==============|================|=================+ 826139Sjb150015 * | v v | | 836139Sjb150015 * | +-----------+ +--------------------+ +------------------+ | 846139Sjb150015 * | | IO | | Kernel Door Server | | User Door Servers| | 856139Sjb150015 * | | Interface | | Interface | | Interface | | 866139Sjb150015 * | +-----------+ +--------------------+ +------------------+ | 876139Sjb150015 * | | | ^ ^ | 886139Sjb150015 * | v v | | | +=========+ 896139Sjb150015 * | +-----------------------------------+ | | | | 906139Sjb150015 * | + SMB Server Management (this file) |<------------------| ZFS | 916139Sjb150015 * | +-----------------------------------+ | | | | 926139Sjb150015 * | | | | Module | 936139Sjb150015 * | +-----------------------------------+ | | | | 946139Sjb150015 * | + SMB Server Internal Layers |------+ | +=========+ 956139Sjb150015 * | +-----------------------------------+ | 966139Sjb150015 * | | 976139Sjb150015 * | | 986139Sjb150015 * +===========================================================+ 996139Sjb150015 * 1006139Sjb150015 * 1016139Sjb150015 * Server State Machine 1026139Sjb150015 * -------------------- 1036139Sjb150015 * | 1046139Sjb150015 * | T0 1056139Sjb150015 * | 1066139Sjb150015 * v 1076139Sjb150015 * +-----------------------------+ 1086139Sjb150015 * | SMB_SERVER_STATE_CREATED | 1096139Sjb150015 * +-----------------------------+ 1106139Sjb150015 * | 1116139Sjb150015 * | T1 1126139Sjb150015 * | 1136139Sjb150015 * v 1146139Sjb150015 * +-----------------------------+ 1156139Sjb150015 * | SMB_SERVER_STATE_CONFIGURED | 1166139Sjb150015 * +-----------------------------+ 1176139Sjb150015 * | 1186139Sjb150015 * | T2 1196139Sjb150015 * | 1206139Sjb150015 * v 1216139Sjb150015 * +-----------------------------+ 12211963SAfshin.Ardakani@Sun.COM * | SMB_SERVER_STATE_RUNNING / | 12311963SAfshin.Ardakani@Sun.COM * | SMB_SERVER_STATE_STOPPING | 1246139Sjb150015 * +-----------------------------+ 1256139Sjb150015 * | 1266139Sjb150015 * | T3 1276139Sjb150015 * | 1286139Sjb150015 * v 1296139Sjb150015 * +-----------------------------+ 1306139Sjb150015 * | SMB_SERVER_STATE_DELETING | 1316139Sjb150015 * +-----------------------------+ 1326139Sjb150015 * | 1336139Sjb150015 * | 1346139Sjb150015 * | 1356139Sjb150015 * v 1366139Sjb150015 * 1376139Sjb150015 * States 1386139Sjb150015 * ------ 1396139Sjb150015 * 1406139Sjb150015 * SMB_SERVER_STATE_CREATED 1416139Sjb150015 * 1426139Sjb150015 * This is the state of the server just after creation. 1436139Sjb150015 * 1446139Sjb150015 * SMB_SERVER_STATE_CONFIGURED 1456139Sjb150015 * 1466139Sjb150015 * The server has been configured. 1476139Sjb150015 * 1486139Sjb150015 * SMB_SERVER_STATE_RUNNING 1496139Sjb150015 * 1506139Sjb150015 * The server has been started. While in this state the threads listening on 1516139Sjb150015 * the sockets car be started. The smbd daemon does so through an Ioctl: 1526139Sjb150015 * 1536139Sjb150015 * smb_drv_ioctl(SMB_IOC_NBT_LISTEN) --> smb_server_nbt_listen() 1546139Sjb150015 * smb_drv_ioctl(SMB_IOC_TCP_LISTEN) --> smb_server_nbt_listen() 1556139Sjb150015 * 1566139Sjb150015 * When a client establishes a connection the thread listening leaves 1576139Sjb150015 * temporarily the kernel. While in user space it creates a thread for the 1586139Sjb150015 * new session. It then returns to kernel with the result of the thread 1596139Sjb150015 * creation. If the creation failed the new session context is destroyed 1606139Sjb150015 * before returning listening. 1616139Sjb150015 * 1626139Sjb150015 * The new created thread enters the kernel though an Ioctl: 1636139Sjb150015 * 1646139Sjb150015 * smb_drv_ioctl(SMB_IOC_NBT_RECEIVE) --> smb_server_nbt_receive() 1656139Sjb150015 * smb_drv_ioctl(SMB_IOC_TCP_RECEIVE) --> smb_server_tcp_receive() 1666139Sjb150015 * 1676139Sjb150015 * SMB_SERVER_STATE_STOPPING 1686139Sjb150015 * 1696139Sjb150015 * The threads listening on the NBT and TCP sockets are being terminated. 1706139Sjb150015 * 1716139Sjb150015 * 1726139Sjb150015 * Transitions 1736139Sjb150015 * ----------- 1746139Sjb150015 * 1756139Sjb150015 * Transition T0 1766139Sjb150015 * 1776139Sjb150015 * The daemon smbd triggers its creation by opening the smbsrv device. If 1786139Sjb150015 * the zone where the daemon lives doesn't have an smb server yet it is 1796139Sjb150015 * created. 1806139Sjb150015 * 1816139Sjb150015 * smb_drv_open() --> smb_server_create() 1826139Sjb150015 * 1836139Sjb150015 * Transition T1 1846139Sjb150015 * 1856139Sjb150015 * This transition occurs in smb_server_configure(). It is triggered by the 1866139Sjb150015 * daemon through an Ioctl. 1876139Sjb150015 * 1886139Sjb150015 * smb_drv_ioctl(SMB_IOC_CONFIG) --> smb_server_configure() 1896139Sjb150015 * 1906139Sjb150015 * Transition T2 1916139Sjb150015 * 1926139Sjb150015 * This transition occurs in smb_server_start(). It is triggered by the 1936139Sjb150015 * daemon through an Ioctl. 1946139Sjb150015 * 1956139Sjb150015 * smb_drv_ioctl(SMB_IOC_START) --> smb_server_start() 1966139Sjb150015 * 1976139Sjb150015 * Transition T3 1986139Sjb150015 * 1996139Sjb150015 * This transition occurs in smb_server_delete(). It is triggered by the 2006139Sjb150015 * daemon when closing the smbsrv device 2016139Sjb150015 * 2026139Sjb150015 * smb_drv_close() --> smb_server_delete() 2036139Sjb150015 * 2046139Sjb150015 * Comments 2056139Sjb150015 * -------- 2066139Sjb150015 * 2076139Sjb150015 * This files assumes that there will one SMB server per zone. For now the 2086139Sjb150015 * smb server works only in global zone. There's nothing in this file preventing 2096139Sjb150015 * an smb server from being created in a non global zone. That limitation is 2106139Sjb150015 * enforced in user space. 2116139Sjb150015 */ 2126139Sjb150015 2136139Sjb150015 #include <sys/strsubr.h> 2146139Sjb150015 #include <sys/cmn_err.h> 2156139Sjb150015 #include <sys/priv.h> 2166139Sjb150015 #include <sys/socketvar.h> 2176139Sjb150015 #include <sys/zone.h> 21810966SJordan.Brown@Sun.COM #include <netinet/in.h> 21910966SJordan.Brown@Sun.COM #include <netinet/in_systm.h> 22010966SJordan.Brown@Sun.COM #include <netinet/ip.h> 22110966SJordan.Brown@Sun.COM #include <netinet/ip_icmp.h> 22210966SJordan.Brown@Sun.COM #include <netinet/ip_var.h> 22310966SJordan.Brown@Sun.COM #include <netinet/tcp.h> 2246139Sjb150015 #include <smbsrv/smb_kproto.h> 22510966SJordan.Brown@Sun.COM #include <smbsrv/string.h> 2266139Sjb150015 #include <smbsrv/netbios.h> 2276139Sjb150015 #include <smbsrv/smb_fsops.h> 2287052Samw #include <smbsrv/smb_share.h> 22911963SAfshin.Ardakani@Sun.COM #include <smbsrv/smb_door.h> 2306432Sas200622 #include <smbsrv/smb_kstat.h> 2316139Sjb150015 2326139Sjb150015 extern void smb_reply_notify_change_request(smb_request_t *); 2336139Sjb150015 23412508Samw@Sun.COM static void smb_server_kstat_init(smb_server_t *); 2356139Sjb150015 static void smb_server_kstat_fini(smb_server_t *); 2366139Sjb150015 static void smb_server_timers(smb_thread_t *, void *); 2376139Sjb150015 static int smb_server_listen(smb_server_t *, smb_listener_daemon_t *, 2388670SJose.Borrego@Sun.COM in_port_t, int, int); 23911963SAfshin.Ardakani@Sun.COM static void smb_server_listen_fini(smb_listener_daemon_t *); 24011963SAfshin.Ardakani@Sun.COM static kt_did_t smb_server_listener_tid(smb_listener_daemon_t *); 2416139Sjb150015 static int smb_server_lookup(smb_server_t **); 2426139Sjb150015 static void smb_server_release(smb_server_t *); 2439832Samw@Sun.COM static void smb_server_store_cfg(smb_server_t *, smb_ioc_cfg_t *); 24411963SAfshin.Ardakani@Sun.COM static void smb_server_shutdown(smb_server_t *); 2456139Sjb150015 static int smb_server_fsop_start(smb_server_t *); 2466139Sjb150015 static void smb_server_fsop_stop(smb_server_t *); 24711963SAfshin.Ardakani@Sun.COM static void smb_server_signal_listeners(smb_server_t *); 24811963SAfshin.Ardakani@Sun.COM static void smb_event_cancel(smb_server_t *, uint32_t); 24911963SAfshin.Ardakani@Sun.COM static uint32_t smb_event_alloc_txid(void); 2506139Sjb150015 25111963SAfshin.Ardakani@Sun.COM static void smb_server_disconnect_share(smb_session_list_t *, const char *); 25210122SJordan.Brown@Sun.COM static void smb_server_enum_private(smb_session_list_t *, smb_svcenum_t *); 25310122SJordan.Brown@Sun.COM static int smb_server_sesion_disconnect(smb_session_list_t *, const char *, 25410122SJordan.Brown@Sun.COM const char *); 25510122SJordan.Brown@Sun.COM static int smb_server_fclose(smb_session_list_t *, uint32_t); 25612508Samw@Sun.COM static int smb_server_kstat_update(kstat_t *, int); 257*12890SJoyce.McIntosh@Sun.COM static int smb_server_legacy_kstat_update(kstat_t *, int); 25810122SJordan.Brown@Sun.COM 25911963SAfshin.Ardakani@Sun.COM int smb_event_debug = 0; 26011963SAfshin.Ardakani@Sun.COM 2616139Sjb150015 static smb_llist_t smb_servers; 2626139Sjb150015 2636139Sjb150015 /* 2646139Sjb150015 * ***************************************************************************** 2656139Sjb150015 * **************** Functions called from the device interface ***************** 2666139Sjb150015 * ***************************************************************************** 2676139Sjb150015 * 26810122SJordan.Brown@Sun.COM * These functions typically have to determine the relevant smb server 26910122SJordan.Brown@Sun.COM * to which the call applies. 2706139Sjb150015 */ 2716139Sjb150015 2726139Sjb150015 /* 2736139Sjb150015 * smb_server_svc_init 2746139Sjb150015 * 2757348SJose.Borrego@Sun.COM * This function must be called from smb_drv_attach(). 2766139Sjb150015 */ 2776139Sjb150015 int 2786139Sjb150015 smb_server_svc_init(void) 2796139Sjb150015 { 2806139Sjb150015 int rc = 0; 2816139Sjb150015 2826139Sjb150015 while (rc == 0) { 2838934SJose.Borrego@Sun.COM if (rc = smb_mbc_init()) 2848934SJose.Borrego@Sun.COM continue; 2856139Sjb150015 if (rc = smb_vop_init()) 2866139Sjb150015 continue; 2876139Sjb150015 if (rc = smb_node_init()) 2886496Sjb150015 continue; 289*12890SJoyce.McIntosh@Sun.COM if (rc = smb_oplock_init()) 290*12890SJoyce.McIntosh@Sun.COM continue; 2916139Sjb150015 if (rc = smb_fem_init()) 2926496Sjb150015 continue; 2936139Sjb150015 if (rc = smb_notify_init()) 2946496Sjb150015 continue; 2956496Sjb150015 if (rc = smb_net_init()) 2966496Sjb150015 continue; 29711963SAfshin.Ardakani@Sun.COM smb_llist_init(); 2986139Sjb150015 smb_llist_constructor(&smb_servers, sizeof (smb_server_t), 2996139Sjb150015 offsetof(smb_server_t, sv_lnd)); 3006139Sjb150015 return (0); 3016139Sjb150015 } 30211963SAfshin.Ardakani@Sun.COM 30311963SAfshin.Ardakani@Sun.COM smb_llist_fini(); 3046496Sjb150015 smb_net_fini(); 3056139Sjb150015 smb_notify_fini(); 3066139Sjb150015 smb_fem_fini(); 3076139Sjb150015 smb_node_fini(); 3086139Sjb150015 smb_vop_fini(); 3098934SJose.Borrego@Sun.COM smb_mbc_fini(); 3106139Sjb150015 return (rc); 3116139Sjb150015 } 3126139Sjb150015 3136139Sjb150015 /* 3146139Sjb150015 * smb_server_svc_fini 3156139Sjb150015 * 3166139Sjb150015 * This function must called from smb_drv_detach(). It will fail if servers 3176139Sjb150015 * still exist. 3186139Sjb150015 */ 3196139Sjb150015 int 3206139Sjb150015 smb_server_svc_fini(void) 3216139Sjb150015 { 3226139Sjb150015 int rc = EBUSY; 3236139Sjb150015 3246139Sjb150015 if (smb_llist_get_count(&smb_servers) == 0) { 32511963SAfshin.Ardakani@Sun.COM smb_llist_fini(); 3266496Sjb150015 smb_net_fini(); 3276139Sjb150015 smb_notify_fini(); 3286139Sjb150015 smb_fem_fini(); 3296139Sjb150015 smb_node_fini(); 330*12890SJoyce.McIntosh@Sun.COM smb_oplock_fini(); 3316139Sjb150015 smb_vop_fini(); 3328934SJose.Borrego@Sun.COM smb_mbc_fini(); 3336139Sjb150015 smb_llist_destructor(&smb_servers); 3346139Sjb150015 rc = 0; 3356139Sjb150015 } 3366139Sjb150015 return (rc); 3376139Sjb150015 } 3386139Sjb150015 3396139Sjb150015 /* 3406139Sjb150015 * smb_server_create 3416139Sjb150015 * 3426139Sjb150015 * This function will fail if there's already a server associated with the 3436139Sjb150015 * caller's zone. 3446139Sjb150015 */ 3456139Sjb150015 int 3466139Sjb150015 smb_server_create(void) 3476139Sjb150015 { 3486139Sjb150015 zoneid_t zid; 3496139Sjb150015 smb_server_t *sv; 3506139Sjb150015 3516139Sjb150015 zid = getzoneid(); 3526139Sjb150015 3536139Sjb150015 smb_llist_enter(&smb_servers, RW_WRITER); 3546139Sjb150015 sv = smb_llist_head(&smb_servers); 3556139Sjb150015 while (sv) { 35611963SAfshin.Ardakani@Sun.COM SMB_SERVER_VALID(sv); 3576139Sjb150015 if (sv->sv_zid == zid) { 3586139Sjb150015 smb_llist_exit(&smb_servers); 3598167Samw@Sun.COM return (EPERM); 3606139Sjb150015 } 3616139Sjb150015 sv = smb_llist_next(&smb_servers, sv); 3626139Sjb150015 } 3636139Sjb150015 3646139Sjb150015 sv = kmem_zalloc(sizeof (smb_server_t), KM_NOSLEEP); 3656139Sjb150015 if (sv == NULL) { 3666139Sjb150015 smb_llist_exit(&smb_servers); 3676139Sjb150015 return (ENOMEM); 3686139Sjb150015 } 3696139Sjb150015 37011963SAfshin.Ardakani@Sun.COM smb_llist_constructor(&sv->sv_opipe_list, sizeof (smb_opipe_t), 37111963SAfshin.Ardakani@Sun.COM offsetof(smb_opipe_t, p_lnd)); 37211963SAfshin.Ardakani@Sun.COM 37311963SAfshin.Ardakani@Sun.COM smb_llist_constructor(&sv->sv_event_list, sizeof (smb_event_t), 37411963SAfshin.Ardakani@Sun.COM offsetof(smb_event_t, se_lnd)); 37511963SAfshin.Ardakani@Sun.COM 376*12890SJoyce.McIntosh@Sun.COM smb_llist_constructor(&sv->sp_info.sp_list, sizeof (smb_kspooldoc_t), 377*12890SJoyce.McIntosh@Sun.COM offsetof(smb_kspooldoc_t, sd_lnd)); 378*12890SJoyce.McIntosh@Sun.COM 379*12890SJoyce.McIntosh@Sun.COM smb_llist_constructor(&sv->sp_info.sp_fidlist, 380*12890SJoyce.McIntosh@Sun.COM sizeof (smb_spoolfid_t), offsetof(smb_spoolfid_t, sf_lnd)); 381*12890SJoyce.McIntosh@Sun.COM 3826139Sjb150015 smb_session_list_constructor(&sv->sv_nbt_daemon.ld_session_list); 3836139Sjb150015 smb_session_list_constructor(&sv->sv_tcp_daemon.ld_session_list); 3846139Sjb150015 3856139Sjb150015 sv->si_cache_request = kmem_cache_create("smb_request_cache", 3866139Sjb150015 sizeof (smb_request_t), 8, NULL, NULL, NULL, NULL, NULL, 0); 3876139Sjb150015 sv->si_cache_session = kmem_cache_create("smb_session_cache", 3886139Sjb150015 sizeof (smb_session_t), 8, NULL, NULL, NULL, NULL, NULL, 0); 3896139Sjb150015 sv->si_cache_user = kmem_cache_create("smb_user_cache", 3906139Sjb150015 sizeof (smb_user_t), 8, NULL, NULL, NULL, NULL, NULL, 0); 3916139Sjb150015 sv->si_cache_tree = kmem_cache_create("smb_tree_cache", 3926139Sjb150015 sizeof (smb_tree_t), 8, NULL, NULL, NULL, NULL, NULL, 0); 3936139Sjb150015 sv->si_cache_ofile = kmem_cache_create("smb_ofile_cache", 3946139Sjb150015 sizeof (smb_ofile_t), 8, NULL, NULL, NULL, NULL, NULL, 0); 3956139Sjb150015 sv->si_cache_odir = kmem_cache_create("smb_odir_cache", 3966139Sjb150015 sizeof (smb_odir_t), 8, NULL, NULL, NULL, NULL, NULL, 0); 39711963SAfshin.Ardakani@Sun.COM sv->si_cache_opipe = kmem_cache_create("smb_opipe_cache", 39811963SAfshin.Ardakani@Sun.COM sizeof (smb_opipe_t), 8, NULL, NULL, NULL, NULL, NULL, 0); 39911963SAfshin.Ardakani@Sun.COM sv->si_cache_event = kmem_cache_create("smb_event_cache", 40011963SAfshin.Ardakani@Sun.COM sizeof (smb_event_t), 8, NULL, NULL, NULL, NULL, NULL, 0); 4016139Sjb150015 4026139Sjb150015 smb_thread_init(&sv->si_thread_timers, 4036139Sjb150015 "smb_timers", smb_server_timers, sv, 4046139Sjb150015 NULL, NULL); 4056139Sjb150015 4066432Sas200622 sv->sv_pid = curproc->p_pid; 40712508Samw@Sun.COM smb_srqueue_init(&sv->sv_srqueue); 4086139Sjb150015 40911963SAfshin.Ardakani@Sun.COM smb_kdoor_init(); 4107052Samw smb_opipe_door_init(); 41112508Samw@Sun.COM smb_server_kstat_init(sv); 4126139Sjb150015 4136139Sjb150015 mutex_init(&sv->sv_mutex, NULL, MUTEX_DEFAULT, NULL); 414*12890SJoyce.McIntosh@Sun.COM mutex_init(&sv->sp_info.sp_mutex, NULL, MUTEX_DEFAULT, NULL); 4156139Sjb150015 cv_init(&sv->sv_cv, NULL, CV_DEFAULT, NULL); 416*12890SJoyce.McIntosh@Sun.COM cv_init(&sv->sp_info.sp_cv, NULL, CV_DEFAULT, NULL); 417*12890SJoyce.McIntosh@Sun.COM 4186139Sjb150015 sv->sv_state = SMB_SERVER_STATE_CREATED; 4196139Sjb150015 sv->sv_magic = SMB_SERVER_MAGIC; 4206139Sjb150015 sv->sv_zid = zid; 4216139Sjb150015 4226139Sjb150015 smb_llist_insert_tail(&smb_servers, sv); 4236139Sjb150015 smb_llist_exit(&smb_servers); 424*12890SJoyce.McIntosh@Sun.COM 425*12890SJoyce.McIntosh@Sun.COM smb_threshold_init(&sv->sv_ssetup_ct, SMB_SSETUP_CMD, 426*12890SJoyce.McIntosh@Sun.COM smb_ssetup_threshold, smb_ssetup_timeout); 427*12890SJoyce.McIntosh@Sun.COM smb_threshold_init(&sv->sv_tcon_ct, SMB_TCON_CMD, smb_tcon_threshold, 428*12890SJoyce.McIntosh@Sun.COM smb_tcon_timeout); 429*12890SJoyce.McIntosh@Sun.COM smb_threshold_init(&sv->sv_opipe_ct, SMB_OPIPE_CMD, smb_opipe_threshold, 430*12890SJoyce.McIntosh@Sun.COM smb_opipe_timeout); 431*12890SJoyce.McIntosh@Sun.COM 4326139Sjb150015 return (0); 4336139Sjb150015 } 4346139Sjb150015 4356139Sjb150015 /* 4366139Sjb150015 * smb_server_delete 4376139Sjb150015 * 4386139Sjb150015 * This function will delete the server passed in. It will make sure that all 4396139Sjb150015 * activity associated that server has ceased before destroying it. 4406139Sjb150015 */ 4416139Sjb150015 int 4426139Sjb150015 smb_server_delete(void) 4436139Sjb150015 { 4446139Sjb150015 smb_server_t *sv; 44511963SAfshin.Ardakani@Sun.COM kt_did_t nbt_tid; 44611963SAfshin.Ardakani@Sun.COM kt_did_t tcp_tid; 4476139Sjb150015 int rc; 4486139Sjb150015 4496139Sjb150015 rc = smb_server_lookup(&sv); 4506139Sjb150015 if (rc != 0) 4516139Sjb150015 return (rc); 4526139Sjb150015 453*12890SJoyce.McIntosh@Sun.COM smb_threshold_fini(&sv->sv_ssetup_ct); 454*12890SJoyce.McIntosh@Sun.COM smb_threshold_fini(&sv->sv_tcon_ct); 455*12890SJoyce.McIntosh@Sun.COM smb_threshold_fini(&sv->sv_opipe_ct); 456*12890SJoyce.McIntosh@Sun.COM 4576139Sjb150015 mutex_enter(&sv->sv_mutex); 4586139Sjb150015 switch (sv->sv_state) { 4596139Sjb150015 case SMB_SERVER_STATE_RUNNING: 46011963SAfshin.Ardakani@Sun.COM case SMB_SERVER_STATE_STOPPING: 46111963SAfshin.Ardakani@Sun.COM sv->sv_state = SMB_SERVER_STATE_STOPPING; 46211963SAfshin.Ardakani@Sun.COM smb_server_signal_listeners(sv); 46311963SAfshin.Ardakani@Sun.COM nbt_tid = smb_server_listener_tid(&sv->sv_nbt_daemon); 46411963SAfshin.Ardakani@Sun.COM tcp_tid = smb_server_listener_tid(&sv->sv_tcp_daemon); 465*12890SJoyce.McIntosh@Sun.COM cv_broadcast(&sv->sp_info.sp_cv); 4666139Sjb150015 4676139Sjb150015 sv->sv_state = SMB_SERVER_STATE_DELETING; 4686139Sjb150015 mutex_exit(&sv->sv_mutex); 46911963SAfshin.Ardakani@Sun.COM 47011963SAfshin.Ardakani@Sun.COM if (nbt_tid != 0) 47111963SAfshin.Ardakani@Sun.COM thread_join(nbt_tid); 47211963SAfshin.Ardakani@Sun.COM if (tcp_tid != 0) 47311963SAfshin.Ardakani@Sun.COM thread_join(tcp_tid); 47411963SAfshin.Ardakani@Sun.COM 47511963SAfshin.Ardakani@Sun.COM smb_server_listen_fini(&sv->sv_nbt_daemon); 47611963SAfshin.Ardakani@Sun.COM smb_server_listen_fini(&sv->sv_tcp_daemon); 4776139Sjb150015 mutex_enter(&sv->sv_mutex); 4786139Sjb150015 break; 4796139Sjb150015 case SMB_SERVER_STATE_CONFIGURED: 4806139Sjb150015 case SMB_SERVER_STATE_CREATED: 4816139Sjb150015 sv->sv_state = SMB_SERVER_STATE_DELETING; 4826139Sjb150015 break; 4836139Sjb150015 default: 48411963SAfshin.Ardakani@Sun.COM SMB_SERVER_STATE_VALID(sv->sv_state); 4856139Sjb150015 mutex_exit(&sv->sv_mutex); 4866139Sjb150015 smb_server_release(sv); 4876139Sjb150015 return (ENOTTY); 4886139Sjb150015 } 4896139Sjb150015 4906139Sjb150015 ASSERT(sv->sv_state == SMB_SERVER_STATE_DELETING); 4916139Sjb150015 4926139Sjb150015 sv->sv_refcnt--; 4936139Sjb150015 while (sv->sv_refcnt) 4946139Sjb150015 cv_wait(&sv->sv_cv, &sv->sv_mutex); 4956139Sjb150015 4966139Sjb150015 mutex_exit(&sv->sv_mutex); 4976139Sjb150015 4986139Sjb150015 smb_llist_enter(&smb_servers, RW_WRITER); 4996139Sjb150015 smb_llist_remove(&smb_servers, sv); 5006139Sjb150015 smb_llist_exit(&smb_servers); 5016139Sjb150015 50211963SAfshin.Ardakani@Sun.COM smb_server_shutdown(sv); 5036139Sjb150015 rw_destroy(&sv->sv_cfg_lock); 5047052Samw smb_opipe_door_fini(); 50511963SAfshin.Ardakani@Sun.COM smb_kdoor_fini(); 5066139Sjb150015 smb_server_kstat_fini(sv); 50711963SAfshin.Ardakani@Sun.COM smb_llist_destructor(&sv->sv_opipe_list); 50811963SAfshin.Ardakani@Sun.COM smb_llist_destructor(&sv->sv_event_list); 5097619SJose.Borrego@Sun.COM 5106139Sjb150015 kmem_cache_destroy(sv->si_cache_request); 5116139Sjb150015 kmem_cache_destroy(sv->si_cache_session); 5126139Sjb150015 kmem_cache_destroy(sv->si_cache_user); 5136139Sjb150015 kmem_cache_destroy(sv->si_cache_tree); 5146139Sjb150015 kmem_cache_destroy(sv->si_cache_ofile); 5156139Sjb150015 kmem_cache_destroy(sv->si_cache_odir); 51611963SAfshin.Ardakani@Sun.COM kmem_cache_destroy(sv->si_cache_opipe); 51711963SAfshin.Ardakani@Sun.COM kmem_cache_destroy(sv->si_cache_event); 5186139Sjb150015 51912508Samw@Sun.COM smb_srqueue_destroy(&sv->sv_srqueue); 52012508Samw@Sun.COM 5216139Sjb150015 smb_thread_destroy(&sv->si_thread_timers); 5226139Sjb150015 mutex_destroy(&sv->sv_mutex); 5236139Sjb150015 cv_destroy(&sv->sv_cv); 5246139Sjb150015 sv->sv_magic = 0; 5256139Sjb150015 kmem_free(sv, sizeof (smb_server_t)); 5266139Sjb150015 5276139Sjb150015 return (0); 5286139Sjb150015 } 5296139Sjb150015 5306139Sjb150015 /* 5316139Sjb150015 * smb_server_configure 5326139Sjb150015 */ 5336139Sjb150015 int 5349832Samw@Sun.COM smb_server_configure(smb_ioc_cfg_t *ioc) 5356139Sjb150015 { 5366139Sjb150015 int rc = 0; 5376139Sjb150015 smb_server_t *sv; 5386139Sjb150015 5396139Sjb150015 rc = smb_server_lookup(&sv); 5406139Sjb150015 if (rc) 5416139Sjb150015 return (rc); 5426139Sjb150015 5436139Sjb150015 mutex_enter(&sv->sv_mutex); 5446139Sjb150015 switch (sv->sv_state) { 5456139Sjb150015 case SMB_SERVER_STATE_CREATED: 5469832Samw@Sun.COM smb_server_store_cfg(sv, ioc); 5476139Sjb150015 sv->sv_state = SMB_SERVER_STATE_CONFIGURED; 5486139Sjb150015 break; 5496139Sjb150015 5506139Sjb150015 case SMB_SERVER_STATE_CONFIGURED: 5519832Samw@Sun.COM smb_server_store_cfg(sv, ioc); 5526139Sjb150015 break; 5536139Sjb150015 5546139Sjb150015 case SMB_SERVER_STATE_RUNNING: 55511963SAfshin.Ardakani@Sun.COM case SMB_SERVER_STATE_STOPPING: 5566139Sjb150015 rw_enter(&sv->sv_cfg_lock, RW_WRITER); 5579832Samw@Sun.COM smb_server_store_cfg(sv, ioc); 5586139Sjb150015 rw_exit(&sv->sv_cfg_lock); 5596139Sjb150015 break; 5606139Sjb150015 5616139Sjb150015 default: 56211963SAfshin.Ardakani@Sun.COM SMB_SERVER_STATE_VALID(sv->sv_state); 5636139Sjb150015 rc = EFAULT; 5646139Sjb150015 break; 5656139Sjb150015 } 5666139Sjb150015 mutex_exit(&sv->sv_mutex); 5676139Sjb150015 5686139Sjb150015 smb_server_release(sv); 5696139Sjb150015 5706139Sjb150015 return (rc); 5716139Sjb150015 } 5726139Sjb150015 5736139Sjb150015 /* 5746139Sjb150015 * smb_server_start 5756139Sjb150015 */ 5766139Sjb150015 int 5779832Samw@Sun.COM smb_server_start(smb_ioc_start_t *ioc) 5786139Sjb150015 { 5796139Sjb150015 int rc = 0; 5806139Sjb150015 smb_server_t *sv; 5816139Sjb150015 5826139Sjb150015 rc = smb_server_lookup(&sv); 5836139Sjb150015 if (rc) 5846139Sjb150015 return (rc); 5856139Sjb150015 5866139Sjb150015 mutex_enter(&sv->sv_mutex); 5876139Sjb150015 switch (sv->sv_state) { 5886139Sjb150015 case SMB_SERVER_STATE_CONFIGURED: 58910966SJordan.Brown@Sun.COM smb_codepage_init(); 5906139Sjb150015 5916139Sjb150015 sv->sv_thread_pool = taskq_create("smb_workers", 5926139Sjb150015 sv->sv_cfg.skc_maxworkers, SMB_WORKER_PRIORITY, 5936139Sjb150015 sv->sv_cfg.skc_maxworkers, INT_MAX, 5946139Sjb150015 TASKQ_DYNAMIC|TASKQ_PREPOPULATE); 5956139Sjb150015 5968670SJose.Borrego@Sun.COM sv->sv_session = smb_session_create(NULL, 0, sv, 0); 5977588Samw@Sun.COM 5987588Samw@Sun.COM if (sv->sv_thread_pool == NULL || sv->sv_session == NULL) { 5996139Sjb150015 rc = ENOMEM; 6006139Sjb150015 break; 6016139Sjb150015 } 6026139Sjb150015 6036139Sjb150015 if (rc = smb_server_fsop_start(sv)) 6046139Sjb150015 break; 6056139Sjb150015 ASSERT(sv->sv_lmshrd == NULL); 60612508Samw@Sun.COM sv->sv_lmshrd = smb_kshare_door_init(ioc->lmshrd); 6076139Sjb150015 if (sv->sv_lmshrd == NULL) 6086139Sjb150015 break; 60911963SAfshin.Ardakani@Sun.COM if (rc = smb_kdoor_open(ioc->udoor)) { 61011963SAfshin.Ardakani@Sun.COM cmn_err(CE_WARN, "Cannot open smbd door"); 6116139Sjb150015 break; 61211963SAfshin.Ardakani@Sun.COM } 61311963SAfshin.Ardakani@Sun.COM if (rc = smb_opipe_door_open(ioc->opipe)) { 61411963SAfshin.Ardakani@Sun.COM cmn_err(CE_WARN, "Cannot open opipe door"); 61511963SAfshin.Ardakani@Sun.COM break; 61611963SAfshin.Ardakani@Sun.COM } 6176139Sjb150015 if (rc = smb_thread_start(&sv->si_thread_timers)) 6186139Sjb150015 break; 6196139Sjb150015 sv->sv_state = SMB_SERVER_STATE_RUNNING; 62012508Samw@Sun.COM sv->sv_start_time = gethrtime(); 6216139Sjb150015 mutex_exit(&sv->sv_mutex); 6226139Sjb150015 smb_server_release(sv); 62312508Samw@Sun.COM 62412508Samw@Sun.COM smb_export_start(); 6256139Sjb150015 return (0); 6266139Sjb150015 default: 62711963SAfshin.Ardakani@Sun.COM SMB_SERVER_STATE_VALID(sv->sv_state); 6286139Sjb150015 mutex_exit(&sv->sv_mutex); 6296139Sjb150015 smb_server_release(sv); 6306139Sjb150015 return (ENOTTY); 6316139Sjb150015 } 6326139Sjb150015 63311963SAfshin.Ardakani@Sun.COM smb_server_shutdown(sv); 6346139Sjb150015 mutex_exit(&sv->sv_mutex); 6356139Sjb150015 smb_server_release(sv); 6366139Sjb150015 return (rc); 6376139Sjb150015 } 6386139Sjb150015 6396139Sjb150015 /* 64011963SAfshin.Ardakani@Sun.COM * An smbd is shutting down. 64111963SAfshin.Ardakani@Sun.COM */ 64211963SAfshin.Ardakani@Sun.COM int 64311963SAfshin.Ardakani@Sun.COM smb_server_stop(void) 64411963SAfshin.Ardakani@Sun.COM { 64511963SAfshin.Ardakani@Sun.COM smb_server_t *sv; 64611963SAfshin.Ardakani@Sun.COM int rc; 64711963SAfshin.Ardakani@Sun.COM 64811963SAfshin.Ardakani@Sun.COM if ((rc = smb_server_lookup(&sv)) != 0) 64911963SAfshin.Ardakani@Sun.COM return (rc); 65011963SAfshin.Ardakani@Sun.COM 65111963SAfshin.Ardakani@Sun.COM mutex_enter(&sv->sv_mutex); 65211963SAfshin.Ardakani@Sun.COM switch (sv->sv_state) { 65311963SAfshin.Ardakani@Sun.COM case SMB_SERVER_STATE_RUNNING: 65411963SAfshin.Ardakani@Sun.COM sv->sv_state = SMB_SERVER_STATE_STOPPING; 65511963SAfshin.Ardakani@Sun.COM smb_server_signal_listeners(sv); 656*12890SJoyce.McIntosh@Sun.COM cv_broadcast(&sv->sp_info.sp_cv); 65711963SAfshin.Ardakani@Sun.COM break; 65811963SAfshin.Ardakani@Sun.COM default: 65911963SAfshin.Ardakani@Sun.COM SMB_SERVER_STATE_VALID(sv->sv_state); 66011963SAfshin.Ardakani@Sun.COM break; 66111963SAfshin.Ardakani@Sun.COM } 66211963SAfshin.Ardakani@Sun.COM mutex_exit(&sv->sv_mutex); 66311963SAfshin.Ardakani@Sun.COM 66411963SAfshin.Ardakani@Sun.COM smb_server_release(sv); 66511963SAfshin.Ardakani@Sun.COM return (0); 66611963SAfshin.Ardakani@Sun.COM } 66711963SAfshin.Ardakani@Sun.COM 66811963SAfshin.Ardakani@Sun.COM boolean_t 66911963SAfshin.Ardakani@Sun.COM smb_server_is_stopping(void) 67011963SAfshin.Ardakani@Sun.COM { 67112508Samw@Sun.COM smb_server_t *sv; 67211963SAfshin.Ardakani@Sun.COM boolean_t status; 67311963SAfshin.Ardakani@Sun.COM 67411963SAfshin.Ardakani@Sun.COM if (smb_server_lookup(&sv) != 0) 67511963SAfshin.Ardakani@Sun.COM return (B_TRUE); 67611963SAfshin.Ardakani@Sun.COM 67711963SAfshin.Ardakani@Sun.COM SMB_SERVER_VALID(sv); 67811963SAfshin.Ardakani@Sun.COM 67911963SAfshin.Ardakani@Sun.COM mutex_enter(&sv->sv_mutex); 68011963SAfshin.Ardakani@Sun.COM 68111963SAfshin.Ardakani@Sun.COM switch (sv->sv_state) { 68211963SAfshin.Ardakani@Sun.COM case SMB_SERVER_STATE_STOPPING: 68311963SAfshin.Ardakani@Sun.COM case SMB_SERVER_STATE_DELETING: 68411963SAfshin.Ardakani@Sun.COM status = B_TRUE; 68511963SAfshin.Ardakani@Sun.COM break; 68611963SAfshin.Ardakani@Sun.COM default: 68711963SAfshin.Ardakani@Sun.COM status = B_FALSE; 68811963SAfshin.Ardakani@Sun.COM break; 68911963SAfshin.Ardakani@Sun.COM } 69011963SAfshin.Ardakani@Sun.COM 69111963SAfshin.Ardakani@Sun.COM mutex_exit(&sv->sv_mutex); 69211963SAfshin.Ardakani@Sun.COM smb_server_release(sv); 69311963SAfshin.Ardakani@Sun.COM return (status); 69411963SAfshin.Ardakani@Sun.COM } 69511963SAfshin.Ardakani@Sun.COM 69611963SAfshin.Ardakani@Sun.COM int 69711963SAfshin.Ardakani@Sun.COM smb_server_cancel_event(uint32_t txid) 69811963SAfshin.Ardakani@Sun.COM { 69911963SAfshin.Ardakani@Sun.COM smb_server_t *sv; 70011963SAfshin.Ardakani@Sun.COM int rc; 70111963SAfshin.Ardakani@Sun.COM 70211963SAfshin.Ardakani@Sun.COM if ((rc = smb_server_lookup(&sv)) == 0) { 70311963SAfshin.Ardakani@Sun.COM smb_event_cancel(sv, txid); 70411963SAfshin.Ardakani@Sun.COM smb_server_release(sv); 70511963SAfshin.Ardakani@Sun.COM } 70611963SAfshin.Ardakani@Sun.COM 70711963SAfshin.Ardakani@Sun.COM return (rc); 70811963SAfshin.Ardakani@Sun.COM } 70911963SAfshin.Ardakani@Sun.COM 71011963SAfshin.Ardakani@Sun.COM int 71111963SAfshin.Ardakani@Sun.COM smb_server_notify_event(smb_ioc_event_t *ioc) 71211963SAfshin.Ardakani@Sun.COM { 71311963SAfshin.Ardakani@Sun.COM smb_server_t *sv; 71411963SAfshin.Ardakani@Sun.COM int rc; 71511963SAfshin.Ardakani@Sun.COM 71611963SAfshin.Ardakani@Sun.COM if ((rc = smb_server_lookup(&sv)) == 0) { 71711963SAfshin.Ardakani@Sun.COM smb_event_notify(sv, ioc->txid); 71811963SAfshin.Ardakani@Sun.COM smb_server_release(sv); 71911963SAfshin.Ardakani@Sun.COM } 72011963SAfshin.Ardakani@Sun.COM 72111963SAfshin.Ardakani@Sun.COM return (rc); 72211963SAfshin.Ardakani@Sun.COM } 72311963SAfshin.Ardakani@Sun.COM 72411963SAfshin.Ardakani@Sun.COM /* 72511963SAfshin.Ardakani@Sun.COM * SMB-over-NetBIOS (port 139) 7266139Sjb150015 * 72711963SAfshin.Ardakani@Sun.COM * Traditional SMB service over NetBIOS, which requires that a NetBIOS 72811963SAfshin.Ardakani@Sun.COM * session be established. 7296139Sjb150015 */ 7306139Sjb150015 int 7319832Samw@Sun.COM smb_server_nbt_listen(smb_ioc_listen_t *ioc) 7326139Sjb150015 { 7336139Sjb150015 smb_server_t *sv; 7346139Sjb150015 int rc; 7356139Sjb150015 7366139Sjb150015 rc = smb_server_lookup(&sv); 7376139Sjb150015 if (rc) 7386139Sjb150015 return (rc); 7396139Sjb150015 7406139Sjb150015 mutex_enter(&sv->sv_mutex); 7416139Sjb150015 switch (sv->sv_state) { 7426139Sjb150015 case SMB_SERVER_STATE_RUNNING: 7436139Sjb150015 if ((sv->sv_nbt_daemon.ld_kth != NULL) && 7446139Sjb150015 (sv->sv_nbt_daemon.ld_kth != curthread)) { 7456139Sjb150015 mutex_exit(&sv->sv_mutex); 7469422SAfshin.Ardakani@Sun.COM smb_server_release(sv); 7476139Sjb150015 return (EACCES); 7486139Sjb150015 } else { 7496139Sjb150015 sv->sv_nbt_daemon.ld_kth = curthread; 7506139Sjb150015 sv->sv_nbt_daemon.ld_ktdid = curthread->t_did; 7516139Sjb150015 } 7526139Sjb150015 break; 75311963SAfshin.Ardakani@Sun.COM case SMB_SERVER_STATE_STOPPING: 75411963SAfshin.Ardakani@Sun.COM mutex_exit(&sv->sv_mutex); 75511963SAfshin.Ardakani@Sun.COM smb_server_release(sv); 75611963SAfshin.Ardakani@Sun.COM return (ECANCELED); 7576139Sjb150015 default: 75811963SAfshin.Ardakani@Sun.COM SMB_SERVER_STATE_VALID(sv->sv_state); 7596139Sjb150015 mutex_exit(&sv->sv_mutex); 7606139Sjb150015 smb_server_release(sv); 7616139Sjb150015 return (EFAULT); 7626139Sjb150015 } 7636139Sjb150015 mutex_exit(&sv->sv_mutex); 7646139Sjb150015 7658670SJose.Borrego@Sun.COM /* 7668670SJose.Borrego@Sun.COM * netbios must be ipv4 7678670SJose.Borrego@Sun.COM */ 76810717Samw@Sun.COM rc = smb_server_listen(sv, &sv->sv_nbt_daemon, IPPORT_NETBIOS_SSN, 7699832Samw@Sun.COM AF_INET, ioc->error); 7706139Sjb150015 77111963SAfshin.Ardakani@Sun.COM mutex_enter(&sv->sv_mutex); 77211963SAfshin.Ardakani@Sun.COM sv->sv_nbt_daemon.ld_kth = NULL; 77311963SAfshin.Ardakani@Sun.COM mutex_exit(&sv->sv_mutex); 7746139Sjb150015 7756139Sjb150015 smb_server_release(sv); 7766139Sjb150015 return (rc); 7776139Sjb150015 } 7786139Sjb150015 77911963SAfshin.Ardakani@Sun.COM /* 78011963SAfshin.Ardakani@Sun.COM * SMB-over-TCP (port 445) 78111963SAfshin.Ardakani@Sun.COM */ 7826139Sjb150015 int 7839832Samw@Sun.COM smb_server_tcp_listen(smb_ioc_listen_t *ioc) 7846139Sjb150015 { 7856139Sjb150015 smb_server_t *sv; 7866139Sjb150015 int rc; 7876139Sjb150015 7886139Sjb150015 rc = smb_server_lookup(&sv); 7896139Sjb150015 if (rc) 7906139Sjb150015 return (rc); 7916139Sjb150015 7926139Sjb150015 mutex_enter(&sv->sv_mutex); 7936139Sjb150015 switch (sv->sv_state) { 7946139Sjb150015 case SMB_SERVER_STATE_RUNNING: 79511963SAfshin.Ardakani@Sun.COM if ((sv->sv_tcp_daemon.ld_kth != NULL) && 7966139Sjb150015 (sv->sv_tcp_daemon.ld_kth != curthread)) { 7976139Sjb150015 mutex_exit(&sv->sv_mutex); 7989422SAfshin.Ardakani@Sun.COM smb_server_release(sv); 7996139Sjb150015 return (EACCES); 8006139Sjb150015 } else { 8016139Sjb150015 sv->sv_tcp_daemon.ld_kth = curthread; 8026139Sjb150015 sv->sv_tcp_daemon.ld_ktdid = curthread->t_did; 8036139Sjb150015 } 8046139Sjb150015 break; 80511963SAfshin.Ardakani@Sun.COM case SMB_SERVER_STATE_STOPPING: 80611963SAfshin.Ardakani@Sun.COM mutex_exit(&sv->sv_mutex); 80711963SAfshin.Ardakani@Sun.COM smb_server_release(sv); 80811963SAfshin.Ardakani@Sun.COM return (ECANCELED); 8096139Sjb150015 default: 81011963SAfshin.Ardakani@Sun.COM SMB_SERVER_STATE_VALID(sv->sv_state); 8116139Sjb150015 mutex_exit(&sv->sv_mutex); 8129422SAfshin.Ardakani@Sun.COM smb_server_release(sv); 8136139Sjb150015 return (EFAULT); 8146139Sjb150015 } 8156139Sjb150015 mutex_exit(&sv->sv_mutex); 8166139Sjb150015 8178670SJose.Borrego@Sun.COM if (sv->sv_cfg.skc_ipv6_enable) 8188670SJose.Borrego@Sun.COM rc = smb_server_listen(sv, &sv->sv_tcp_daemon, 81910717Samw@Sun.COM IPPORT_SMB, AF_INET6, ioc->error); 8208670SJose.Borrego@Sun.COM else 8218670SJose.Borrego@Sun.COM rc = smb_server_listen(sv, &sv->sv_tcp_daemon, 82210717Samw@Sun.COM IPPORT_SMB, AF_INET, ioc->error); 82311963SAfshin.Ardakani@Sun.COM 82411963SAfshin.Ardakani@Sun.COM mutex_enter(&sv->sv_mutex); 82511963SAfshin.Ardakani@Sun.COM sv->sv_tcp_daemon.ld_kth = NULL; 82611963SAfshin.Ardakani@Sun.COM mutex_exit(&sv->sv_mutex); 8276139Sjb150015 8286139Sjb150015 smb_server_release(sv); 8296139Sjb150015 return (rc); 8306139Sjb150015 } 8316139Sjb150015 8326139Sjb150015 /* 8336139Sjb150015 * smb_server_nbt_receive 8346139Sjb150015 */ 8356139Sjb150015 int 8366139Sjb150015 smb_server_nbt_receive(void) 8376139Sjb150015 { 8386139Sjb150015 int rc; 8396139Sjb150015 smb_server_t *sv; 8406139Sjb150015 8419422SAfshin.Ardakani@Sun.COM if ((rc = smb_server_lookup(&sv)) == 0) { 8429422SAfshin.Ardakani@Sun.COM rc = smb_session_daemon(&sv->sv_nbt_daemon.ld_session_list); 8439422SAfshin.Ardakani@Sun.COM smb_server_release(sv); 8449422SAfshin.Ardakani@Sun.COM } 8456139Sjb150015 8466139Sjb150015 return (rc); 8476139Sjb150015 } 8486139Sjb150015 8496139Sjb150015 /* 8506139Sjb150015 * smb_server_tcp_receive 8516139Sjb150015 */ 8526139Sjb150015 int 8536139Sjb150015 smb_server_tcp_receive(void) 8546139Sjb150015 { 8556139Sjb150015 int rc; 8566139Sjb150015 smb_server_t *sv; 8576139Sjb150015 8589422SAfshin.Ardakani@Sun.COM if ((rc = smb_server_lookup(&sv)) == 0) { 8599422SAfshin.Ardakani@Sun.COM rc = smb_session_daemon(&sv->sv_tcp_daemon.ld_session_list); 8609422SAfshin.Ardakani@Sun.COM smb_server_release(sv); 8619422SAfshin.Ardakani@Sun.COM } 8626139Sjb150015 8636139Sjb150015 return (rc); 8646139Sjb150015 } 8656139Sjb150015 866*12890SJoyce.McIntosh@Sun.COM /* 867*12890SJoyce.McIntosh@Sun.COM * smb_server_spooldoc 868*12890SJoyce.McIntosh@Sun.COM * 869*12890SJoyce.McIntosh@Sun.COM * Waits for print file close broadcast. 870*12890SJoyce.McIntosh@Sun.COM * Gets the head of the fid list, 871*12890SJoyce.McIntosh@Sun.COM * then searches the spooldoc list and returns 872*12890SJoyce.McIntosh@Sun.COM * this info via the ioctl to user land. 873*12890SJoyce.McIntosh@Sun.COM * 874*12890SJoyce.McIntosh@Sun.COM * rc - 0 success 875*12890SJoyce.McIntosh@Sun.COM */ 876*12890SJoyce.McIntosh@Sun.COM 877*12890SJoyce.McIntosh@Sun.COM int 878*12890SJoyce.McIntosh@Sun.COM smb_server_spooldoc(smb_ioc_spooldoc_t *ioc) 879*12890SJoyce.McIntosh@Sun.COM { 880*12890SJoyce.McIntosh@Sun.COM smb_server_t *sv; 881*12890SJoyce.McIntosh@Sun.COM int rc; 882*12890SJoyce.McIntosh@Sun.COM smb_kspooldoc_t *spdoc; 883*12890SJoyce.McIntosh@Sun.COM uint16_t fid; 884*12890SJoyce.McIntosh@Sun.COM 885*12890SJoyce.McIntosh@Sun.COM if ((rc = smb_server_lookup(&sv)) == 0) { 886*12890SJoyce.McIntosh@Sun.COM if (sv->sv_state != SMB_SERVER_STATE_RUNNING) { 887*12890SJoyce.McIntosh@Sun.COM smb_server_release(sv); 888*12890SJoyce.McIntosh@Sun.COM return (ECANCELED); 889*12890SJoyce.McIntosh@Sun.COM } 890*12890SJoyce.McIntosh@Sun.COM mutex_enter(&sv->sp_info.sp_mutex); 891*12890SJoyce.McIntosh@Sun.COM spdoc = kmem_zalloc(sizeof (smb_kspooldoc_t), KM_SLEEP); 892*12890SJoyce.McIntosh@Sun.COM cv_wait(&sv->sp_info.sp_cv, &sv->sp_info.sp_mutex); 893*12890SJoyce.McIntosh@Sun.COM if (sv->sv_state != SMB_SERVER_STATE_RUNNING) 894*12890SJoyce.McIntosh@Sun.COM rc = ECANCELED; 895*12890SJoyce.McIntosh@Sun.COM else { 896*12890SJoyce.McIntosh@Sun.COM fid = smb_spool_get_fid(); 897*12890SJoyce.McIntosh@Sun.COM atomic_inc_32(&sv->sp_info.sp_cnt); 898*12890SJoyce.McIntosh@Sun.COM if (smb_spool_lookup_doc_byfid(fid, spdoc)) { 899*12890SJoyce.McIntosh@Sun.COM ioc->spool_num = spdoc->sd_spool_num; 900*12890SJoyce.McIntosh@Sun.COM ioc->ipaddr = spdoc->sd_ipaddr; 901*12890SJoyce.McIntosh@Sun.COM (void) strlcpy(ioc->path, spdoc->sd_path, 902*12890SJoyce.McIntosh@Sun.COM MAXPATHLEN); 903*12890SJoyce.McIntosh@Sun.COM (void) strlcpy(ioc->username, 904*12890SJoyce.McIntosh@Sun.COM spdoc->sd_username, MAXNAMELEN); 905*12890SJoyce.McIntosh@Sun.COM } 906*12890SJoyce.McIntosh@Sun.COM } 907*12890SJoyce.McIntosh@Sun.COM kmem_free(spdoc, sizeof (smb_kspooldoc_t)); 908*12890SJoyce.McIntosh@Sun.COM mutex_exit(&sv->sp_info.sp_mutex); 909*12890SJoyce.McIntosh@Sun.COM smb_server_release(sv); 910*12890SJoyce.McIntosh@Sun.COM } 911*12890SJoyce.McIntosh@Sun.COM return (rc); 912*12890SJoyce.McIntosh@Sun.COM } 913*12890SJoyce.McIntosh@Sun.COM 9146139Sjb150015 int 9159832Samw@Sun.COM smb_server_set_gmtoff(smb_ioc_gmt_t *ioc) 9166139Sjb150015 { 9176139Sjb150015 int rc; 9186139Sjb150015 smb_server_t *sv; 9196139Sjb150015 9209422SAfshin.Ardakani@Sun.COM if ((rc = smb_server_lookup(&sv)) == 0) { 9219832Samw@Sun.COM sv->si_gmtoff = ioc->offset; 9229422SAfshin.Ardakani@Sun.COM smb_server_release(sv); 9239422SAfshin.Ardakani@Sun.COM } 9246139Sjb150015 9256139Sjb150015 return (rc); 9266139Sjb150015 } 9276139Sjb150015 9289832Samw@Sun.COM int 92910122SJordan.Brown@Sun.COM smb_server_numopen(smb_ioc_opennum_t *ioc) 9309832Samw@Sun.COM { 9319832Samw@Sun.COM smb_server_t *sv; 9329832Samw@Sun.COM int rc; 9339832Samw@Sun.COM 9349832Samw@Sun.COM if ((rc = smb_server_lookup(&sv)) == 0) { 93512508Samw@Sun.COM ioc->open_users = sv->sv_users; 93612508Samw@Sun.COM ioc->open_trees = sv->sv_trees; 93712508Samw@Sun.COM ioc->open_files = sv->sv_files + sv->sv_pipes; 9389832Samw@Sun.COM smb_server_release(sv); 9399832Samw@Sun.COM } 9409832Samw@Sun.COM return (rc); 9419832Samw@Sun.COM } 9429832Samw@Sun.COM 9436139Sjb150015 /* 94410122SJordan.Brown@Sun.COM * Enumerate objects within the server. The svcenum provides the 94510122SJordan.Brown@Sun.COM * enumeration context, i.e. what the caller want to get back. 94610122SJordan.Brown@Sun.COM */ 94710122SJordan.Brown@Sun.COM int 94810122SJordan.Brown@Sun.COM smb_server_enum(smb_ioc_svcenum_t *ioc) 94910122SJordan.Brown@Sun.COM { 95010122SJordan.Brown@Sun.COM smb_svcenum_t *svcenum = &ioc->svcenum; 95110122SJordan.Brown@Sun.COM smb_server_t *sv; 95210122SJordan.Brown@Sun.COM smb_session_list_t *se; 95310122SJordan.Brown@Sun.COM int rc; 95410122SJordan.Brown@Sun.COM 95510122SJordan.Brown@Sun.COM switch (svcenum->se_type) { 95610122SJordan.Brown@Sun.COM case SMB_SVCENUM_TYPE_USER: 95710122SJordan.Brown@Sun.COM case SMB_SVCENUM_TYPE_TREE: 95810122SJordan.Brown@Sun.COM case SMB_SVCENUM_TYPE_FILE: 95910122SJordan.Brown@Sun.COM break; 96010122SJordan.Brown@Sun.COM default: 96110122SJordan.Brown@Sun.COM return (EINVAL); 96210122SJordan.Brown@Sun.COM } 96310122SJordan.Brown@Sun.COM 96410122SJordan.Brown@Sun.COM if ((rc = smb_server_lookup(&sv)) != 0) 96510122SJordan.Brown@Sun.COM return (rc); 96610122SJordan.Brown@Sun.COM 96710122SJordan.Brown@Sun.COM svcenum->se_bavail = svcenum->se_buflen; 96810122SJordan.Brown@Sun.COM svcenum->se_bused = 0; 96910122SJordan.Brown@Sun.COM svcenum->se_nitems = 0; 97010122SJordan.Brown@Sun.COM 97110122SJordan.Brown@Sun.COM se = &sv->sv_nbt_daemon.ld_session_list; 97210122SJordan.Brown@Sun.COM smb_server_enum_private(se, svcenum); 97310122SJordan.Brown@Sun.COM 97410122SJordan.Brown@Sun.COM se = &sv->sv_tcp_daemon.ld_session_list; 97510122SJordan.Brown@Sun.COM smb_server_enum_private(se, svcenum); 97610122SJordan.Brown@Sun.COM 97710122SJordan.Brown@Sun.COM smb_server_release(sv); 97810122SJordan.Brown@Sun.COM return (0); 97910122SJordan.Brown@Sun.COM } 98010122SJordan.Brown@Sun.COM 98110122SJordan.Brown@Sun.COM /* 98210122SJordan.Brown@Sun.COM * Look for sessions to disconnect by client and user name. 98310122SJordan.Brown@Sun.COM */ 98410122SJordan.Brown@Sun.COM int 98510122SJordan.Brown@Sun.COM smb_server_session_close(smb_ioc_session_t *ioc) 98610122SJordan.Brown@Sun.COM { 98710122SJordan.Brown@Sun.COM smb_session_list_t *se; 98810122SJordan.Brown@Sun.COM smb_server_t *sv; 98910122SJordan.Brown@Sun.COM int nbt_cnt; 99010122SJordan.Brown@Sun.COM int tcp_cnt; 99110122SJordan.Brown@Sun.COM int rc; 99210122SJordan.Brown@Sun.COM 99310122SJordan.Brown@Sun.COM if ((rc = smb_server_lookup(&sv)) != 0) 99410122SJordan.Brown@Sun.COM return (rc); 99510122SJordan.Brown@Sun.COM 99610122SJordan.Brown@Sun.COM se = &sv->sv_nbt_daemon.ld_session_list; 99710122SJordan.Brown@Sun.COM nbt_cnt = smb_server_sesion_disconnect(se, ioc->client, ioc->username); 99810122SJordan.Brown@Sun.COM 99910122SJordan.Brown@Sun.COM se = &sv->sv_tcp_daemon.ld_session_list; 100010122SJordan.Brown@Sun.COM tcp_cnt = smb_server_sesion_disconnect(se, ioc->client, ioc->username); 100110122SJordan.Brown@Sun.COM 100210122SJordan.Brown@Sun.COM smb_server_release(sv); 100310122SJordan.Brown@Sun.COM 100410122SJordan.Brown@Sun.COM if ((nbt_cnt == 0) && (tcp_cnt == 0)) 100510122SJordan.Brown@Sun.COM return (ENOENT); 100610122SJordan.Brown@Sun.COM return (0); 100710122SJordan.Brown@Sun.COM } 100810122SJordan.Brown@Sun.COM 100910122SJordan.Brown@Sun.COM /* 101010122SJordan.Brown@Sun.COM * Close a file by uniqid. 101110122SJordan.Brown@Sun.COM */ 101210122SJordan.Brown@Sun.COM int 101310122SJordan.Brown@Sun.COM smb_server_file_close(smb_ioc_fileid_t *ioc) 101410122SJordan.Brown@Sun.COM { 101510122SJordan.Brown@Sun.COM uint32_t uniqid = ioc->uniqid; 101610122SJordan.Brown@Sun.COM smb_session_list_t *se; 101710122SJordan.Brown@Sun.COM smb_server_t *sv; 101810122SJordan.Brown@Sun.COM int rc; 101910122SJordan.Brown@Sun.COM 102010122SJordan.Brown@Sun.COM if ((rc = smb_server_lookup(&sv)) != 0) 102110122SJordan.Brown@Sun.COM return (rc); 102210122SJordan.Brown@Sun.COM 102310122SJordan.Brown@Sun.COM se = &sv->sv_nbt_daemon.ld_session_list; 102410122SJordan.Brown@Sun.COM rc = smb_server_fclose(se, uniqid); 102510122SJordan.Brown@Sun.COM 102610122SJordan.Brown@Sun.COM if (rc == ENOENT) { 102710122SJordan.Brown@Sun.COM se = &sv->sv_tcp_daemon.ld_session_list; 102810122SJordan.Brown@Sun.COM rc = smb_server_fclose(se, uniqid); 102910122SJordan.Brown@Sun.COM } 103010122SJordan.Brown@Sun.COM 103110122SJordan.Brown@Sun.COM smb_server_release(sv); 103210122SJordan.Brown@Sun.COM return (rc); 103310122SJordan.Brown@Sun.COM } 103410122SJordan.Brown@Sun.COM 103510122SJordan.Brown@Sun.COM /* 10366139Sjb150015 * These functions determine the relevant smb server to which the call apply. 10376139Sjb150015 */ 10386139Sjb150015 10396139Sjb150015 uint32_t 10406139Sjb150015 smb_server_get_session_count(void) 10416139Sjb150015 { 10426139Sjb150015 smb_server_t *sv; 10436139Sjb150015 uint32_t counter = 0; 10446139Sjb150015 10456139Sjb150015 if (smb_server_lookup(&sv)) 10466139Sjb150015 return (0); 10476139Sjb150015 10486139Sjb150015 rw_enter(&sv->sv_nbt_daemon.ld_session_list.se_lock, RW_READER); 10496139Sjb150015 counter = sv->sv_nbt_daemon.ld_session_list.se_act.count; 10506139Sjb150015 rw_exit(&sv->sv_nbt_daemon.ld_session_list.se_lock); 10516139Sjb150015 rw_enter(&sv->sv_tcp_daemon.ld_session_list.se_lock, RW_READER); 10526139Sjb150015 counter += sv->sv_tcp_daemon.ld_session_list.se_act.count; 10536139Sjb150015 rw_exit(&sv->sv_tcp_daemon.ld_session_list.se_lock); 10546139Sjb150015 10556139Sjb150015 smb_server_release(sv); 10566139Sjb150015 10576139Sjb150015 return (counter); 10586139Sjb150015 } 10596139Sjb150015 10606139Sjb150015 /* 106112508Samw@Sun.COM * Gets the vnode of the specified share path. 106212508Samw@Sun.COM * 106312508Samw@Sun.COM * A hold on the returned vnode pointer is taken so the caller 106412508Samw@Sun.COM * must call VN_RELE. 106512508Samw@Sun.COM */ 106612508Samw@Sun.COM int 106712508Samw@Sun.COM smb_server_sharevp(const char *shr_path, vnode_t **vp) 106812508Samw@Sun.COM { 106912508Samw@Sun.COM smb_server_t *sv; 107012508Samw@Sun.COM smb_request_t *sr; 107112508Samw@Sun.COM smb_node_t *fnode = NULL; 107212508Samw@Sun.COM smb_node_t *dnode; 107312508Samw@Sun.COM char last_comp[MAXNAMELEN]; 107412508Samw@Sun.COM int rc = 0; 107512508Samw@Sun.COM 107612508Samw@Sun.COM ASSERT(shr_path); 107712508Samw@Sun.COM 107812508Samw@Sun.COM if ((rc = smb_server_lookup(&sv))) 107912508Samw@Sun.COM return (rc); 108012508Samw@Sun.COM 108112508Samw@Sun.COM mutex_enter(&sv->sv_mutex); 108212508Samw@Sun.COM switch (sv->sv_state) { 108312508Samw@Sun.COM case SMB_SERVER_STATE_RUNNING: 108412508Samw@Sun.COM break; 108512508Samw@Sun.COM default: 108612508Samw@Sun.COM mutex_exit(&sv->sv_mutex); 108712508Samw@Sun.COM smb_server_release(sv); 108812508Samw@Sun.COM return (ENOTACTIVE); 108912508Samw@Sun.COM } 109012508Samw@Sun.COM mutex_exit(&sv->sv_mutex); 109112508Samw@Sun.COM 109212508Samw@Sun.COM if ((sr = smb_request_alloc(sv->sv_session, 0)) == NULL) { 109312508Samw@Sun.COM smb_server_release(sv); 109412508Samw@Sun.COM return (ENOMEM); 109512508Samw@Sun.COM } 109612508Samw@Sun.COM sr->user_cr = kcred; 109712508Samw@Sun.COM 109812508Samw@Sun.COM rc = smb_pathname_reduce(sr, sr->user_cr, shr_path, 109912508Samw@Sun.COM NULL, NULL, &dnode, last_comp); 110012508Samw@Sun.COM 110112508Samw@Sun.COM if (rc == 0) { 110212508Samw@Sun.COM rc = smb_fsop_lookup(sr, sr->user_cr, SMB_FOLLOW_LINKS, 110312508Samw@Sun.COM sv->si_root_smb_node, dnode, last_comp, &fnode); 110412508Samw@Sun.COM smb_node_release(dnode); 110512508Samw@Sun.COM } 110612508Samw@Sun.COM 110712508Samw@Sun.COM smb_request_free(sr); 110812508Samw@Sun.COM smb_server_release(sv); 110912508Samw@Sun.COM 111012508Samw@Sun.COM if (rc != 0) 111112508Samw@Sun.COM return (rc); 111212508Samw@Sun.COM 111312508Samw@Sun.COM ASSERT(fnode->vp && fnode->vp->v_vfsp); 111412508Samw@Sun.COM 111512508Samw@Sun.COM VN_HOLD(fnode->vp); 111612508Samw@Sun.COM *vp = fnode->vp; 111712508Samw@Sun.COM 111812508Samw@Sun.COM smb_node_release(fnode); 111912508Samw@Sun.COM 112012508Samw@Sun.COM return (0); 112112508Samw@Sun.COM } 112212508Samw@Sun.COM 112312508Samw@Sun.COM 112412508Samw@Sun.COM /* 112512508Samw@Sun.COM * This is a special interface that will be utilized by ZFS to cause a share to 112612508Samw@Sun.COM * be added/removed. 112712508Samw@Sun.COM * 112812508Samw@Sun.COM * arg is either a lmshare_info_t or share_name from userspace. 112912508Samw@Sun.COM * It will need to be copied into the kernel. It is lmshare_info_t 113012508Samw@Sun.COM * for add operations and share_name for delete operations. 113112508Samw@Sun.COM */ 113212508Samw@Sun.COM int 113312508Samw@Sun.COM smb_server_share(void *arg, boolean_t add_share) 113412508Samw@Sun.COM { 113512508Samw@Sun.COM smb_server_t *sv; 113612508Samw@Sun.COM int rc; 113712508Samw@Sun.COM 113812508Samw@Sun.COM if ((rc = smb_server_lookup(&sv)) == 0) { 113912508Samw@Sun.COM mutex_enter(&sv->sv_mutex); 114012508Samw@Sun.COM switch (sv->sv_state) { 114112508Samw@Sun.COM case SMB_SERVER_STATE_RUNNING: 114212508Samw@Sun.COM mutex_exit(&sv->sv_mutex); 114312508Samw@Sun.COM (void) smb_kshare_upcall(sv->sv_lmshrd, arg, add_share); 114412508Samw@Sun.COM break; 114512508Samw@Sun.COM default: 114612508Samw@Sun.COM mutex_exit(&sv->sv_mutex); 114712508Samw@Sun.COM break; 114812508Samw@Sun.COM } 114912508Samw@Sun.COM smb_server_release(sv); 115012508Samw@Sun.COM } 115112508Samw@Sun.COM 115212508Samw@Sun.COM return (rc); 115312508Samw@Sun.COM } 115412508Samw@Sun.COM 115512508Samw@Sun.COM int 115612508Samw@Sun.COM smb_server_unshare(const char *sharename) 115712508Samw@Sun.COM { 115812508Samw@Sun.COM smb_server_t *sv; 115912508Samw@Sun.COM smb_session_list_t *slist; 116012508Samw@Sun.COM int rc; 116112508Samw@Sun.COM 116212508Samw@Sun.COM if ((rc = smb_server_lookup(&sv))) 116312508Samw@Sun.COM return (rc); 116412508Samw@Sun.COM 116512508Samw@Sun.COM mutex_enter(&sv->sv_mutex); 116612508Samw@Sun.COM switch (sv->sv_state) { 116712508Samw@Sun.COM case SMB_SERVER_STATE_RUNNING: 116812508Samw@Sun.COM case SMB_SERVER_STATE_STOPPING: 116912508Samw@Sun.COM break; 117012508Samw@Sun.COM default: 117112508Samw@Sun.COM mutex_exit(&sv->sv_mutex); 117212508Samw@Sun.COM smb_server_release(sv); 117312508Samw@Sun.COM return (ENOTACTIVE); 117412508Samw@Sun.COM } 117512508Samw@Sun.COM mutex_exit(&sv->sv_mutex); 117612508Samw@Sun.COM 117712508Samw@Sun.COM slist = &sv->sv_nbt_daemon.ld_session_list; 117812508Samw@Sun.COM smb_server_disconnect_share(slist, sharename); 117912508Samw@Sun.COM 118012508Samw@Sun.COM slist = &sv->sv_tcp_daemon.ld_session_list; 118112508Samw@Sun.COM smb_server_disconnect_share(slist, sharename); 118212508Samw@Sun.COM 118312508Samw@Sun.COM smb_server_release(sv); 118412508Samw@Sun.COM return (0); 118512508Samw@Sun.COM } 118612508Samw@Sun.COM 118712508Samw@Sun.COM /* 118811963SAfshin.Ardakani@Sun.COM * Disconnect the specified share. 118911963SAfshin.Ardakani@Sun.COM * Typically called when a share has been removed. 11906139Sjb150015 */ 11917619SJose.Borrego@Sun.COM static void 119211963SAfshin.Ardakani@Sun.COM smb_server_disconnect_share(smb_session_list_t *slist, const char *sharename) 11936139Sjb150015 { 119411963SAfshin.Ardakani@Sun.COM smb_session_t *session; 119511963SAfshin.Ardakani@Sun.COM 119611963SAfshin.Ardakani@Sun.COM rw_enter(&slist->se_lock, RW_READER); 119711963SAfshin.Ardakani@Sun.COM 119811963SAfshin.Ardakani@Sun.COM session = list_head(&slist->se_act.lst); 119911963SAfshin.Ardakani@Sun.COM while (session) { 120011963SAfshin.Ardakani@Sun.COM ASSERT(session->s_magic == SMB_SESSION_MAGIC); 120111963SAfshin.Ardakani@Sun.COM smb_rwx_rwenter(&session->s_lock, RW_READER); 120211963SAfshin.Ardakani@Sun.COM switch (session->s_state) { 120311963SAfshin.Ardakani@Sun.COM case SMB_SESSION_STATE_NEGOTIATED: 120411963SAfshin.Ardakani@Sun.COM case SMB_SESSION_STATE_OPLOCK_BREAKING: 120511963SAfshin.Ardakani@Sun.COM case SMB_SESSION_STATE_WRITE_RAW_ACTIVE: 120611963SAfshin.Ardakani@Sun.COM smb_session_disconnect_share(session, sharename); 120711963SAfshin.Ardakani@Sun.COM break; 120811963SAfshin.Ardakani@Sun.COM default: 120911963SAfshin.Ardakani@Sun.COM break; 121011963SAfshin.Ardakani@Sun.COM } 121111963SAfshin.Ardakani@Sun.COM smb_rwx_rwexit(&session->s_lock); 121211963SAfshin.Ardakani@Sun.COM session = list_next(&slist->se_act.lst, session); 121311963SAfshin.Ardakani@Sun.COM } 121411963SAfshin.Ardakani@Sun.COM 121511963SAfshin.Ardakani@Sun.COM rw_exit(&slist->se_lock); 12166139Sjb150015 } 12176139Sjb150015 12186139Sjb150015 /* 12196139Sjb150015 * ***************************************************************************** 12206139Sjb150015 * **************** Functions called from the internal layers ****************** 12216139Sjb150015 * ***************************************************************************** 12226139Sjb150015 * 12236139Sjb150015 * These functions are provided the relevant smb server by the caller. 12246139Sjb150015 */ 12256139Sjb150015 12266139Sjb150015 void 12276139Sjb150015 smb_server_reconnection_check(smb_server_t *sv, smb_session_t *session) 12286139Sjb150015 { 12296139Sjb150015 ASSERT(sv == session->s_server); 12306139Sjb150015 12316139Sjb150015 smb_session_reconnection_check(&sv->sv_nbt_daemon.ld_session_list, 12326139Sjb150015 session); 12336139Sjb150015 smb_session_reconnection_check(&sv->sv_tcp_daemon.ld_session_list, 12346139Sjb150015 session); 12356139Sjb150015 } 12366139Sjb150015 12376139Sjb150015 void 12386139Sjb150015 smb_server_get_cfg(smb_server_t *sv, smb_kmod_cfg_t *cfg) 12396139Sjb150015 { 12406139Sjb150015 rw_enter(&sv->sv_cfg_lock, RW_READER); 12416139Sjb150015 bcopy(&sv->sv_cfg, cfg, sizeof (*cfg)); 12426139Sjb150015 rw_exit(&sv->sv_cfg_lock); 12436139Sjb150015 } 12446139Sjb150015 12456139Sjb150015 /* 124612508Samw@Sun.COM * 124712508Samw@Sun.COM */ 124812508Samw@Sun.COM void 124912508Samw@Sun.COM smb_server_inc_nbt_sess(smb_server_t *sv) 125012508Samw@Sun.COM { 125112508Samw@Sun.COM SMB_SERVER_VALID(sv); 125212508Samw@Sun.COM atomic_inc_32(&sv->sv_nbt_sess); 125312508Samw@Sun.COM } 125412508Samw@Sun.COM 125512508Samw@Sun.COM void 125612508Samw@Sun.COM smb_server_dec_nbt_sess(smb_server_t *sv) 125712508Samw@Sun.COM { 125812508Samw@Sun.COM SMB_SERVER_VALID(sv); 125912508Samw@Sun.COM atomic_dec_32(&sv->sv_nbt_sess); 126012508Samw@Sun.COM } 126112508Samw@Sun.COM 126212508Samw@Sun.COM void 126312508Samw@Sun.COM smb_server_inc_tcp_sess(smb_server_t *sv) 126412508Samw@Sun.COM { 126512508Samw@Sun.COM SMB_SERVER_VALID(sv); 126612508Samw@Sun.COM atomic_inc_32(&sv->sv_tcp_sess); 126712508Samw@Sun.COM } 126812508Samw@Sun.COM 126912508Samw@Sun.COM void 127012508Samw@Sun.COM smb_server_dec_tcp_sess(smb_server_t *sv) 127112508Samw@Sun.COM { 127212508Samw@Sun.COM SMB_SERVER_VALID(sv); 127312508Samw@Sun.COM atomic_dec_32(&sv->sv_tcp_sess); 127412508Samw@Sun.COM } 127512508Samw@Sun.COM 127612508Samw@Sun.COM void 127712508Samw@Sun.COM smb_server_inc_users(smb_server_t *sv) 127812508Samw@Sun.COM { 127912508Samw@Sun.COM SMB_SERVER_VALID(sv); 128012508Samw@Sun.COM atomic_inc_32(&sv->sv_users); 128112508Samw@Sun.COM } 128212508Samw@Sun.COM 128312508Samw@Sun.COM void 128412508Samw@Sun.COM smb_server_dec_users(smb_server_t *sv) 128512508Samw@Sun.COM { 128612508Samw@Sun.COM SMB_SERVER_VALID(sv); 128712508Samw@Sun.COM atomic_dec_32(&sv->sv_users); 128812508Samw@Sun.COM } 128912508Samw@Sun.COM 129012508Samw@Sun.COM void 129112508Samw@Sun.COM smb_server_inc_trees(smb_server_t *sv) 129212508Samw@Sun.COM { 129312508Samw@Sun.COM SMB_SERVER_VALID(sv); 129412508Samw@Sun.COM atomic_inc_32(&sv->sv_trees); 129512508Samw@Sun.COM } 129612508Samw@Sun.COM 129712508Samw@Sun.COM void 129812508Samw@Sun.COM smb_server_dec_trees(smb_server_t *sv) 129912508Samw@Sun.COM { 130012508Samw@Sun.COM SMB_SERVER_VALID(sv); 130112508Samw@Sun.COM atomic_dec_32(&sv->sv_trees); 130212508Samw@Sun.COM } 130312508Samw@Sun.COM 130412508Samw@Sun.COM void 130512508Samw@Sun.COM smb_server_inc_files(smb_server_t *sv) 130612508Samw@Sun.COM { 130712508Samw@Sun.COM SMB_SERVER_VALID(sv); 130812508Samw@Sun.COM atomic_inc_32(&sv->sv_files); 130912508Samw@Sun.COM } 131012508Samw@Sun.COM 131112508Samw@Sun.COM void 131212508Samw@Sun.COM smb_server_dec_files(smb_server_t *sv) 131312508Samw@Sun.COM { 131412508Samw@Sun.COM SMB_SERVER_VALID(sv); 131512508Samw@Sun.COM atomic_dec_32(&sv->sv_files); 131612508Samw@Sun.COM } 131712508Samw@Sun.COM 131812508Samw@Sun.COM void 131912508Samw@Sun.COM smb_server_inc_pipes(smb_server_t *sv) 132012508Samw@Sun.COM { 132112508Samw@Sun.COM SMB_SERVER_VALID(sv); 132212508Samw@Sun.COM atomic_inc_32(&sv->sv_pipes); 132312508Samw@Sun.COM } 132412508Samw@Sun.COM 132512508Samw@Sun.COM void 132612508Samw@Sun.COM smb_server_dec_pipes(smb_server_t *sv) 132712508Samw@Sun.COM { 132812508Samw@Sun.COM SMB_SERVER_VALID(sv); 132912508Samw@Sun.COM atomic_dec_32(&sv->sv_pipes); 133012508Samw@Sun.COM } 133112508Samw@Sun.COM 133212508Samw@Sun.COM void 133312508Samw@Sun.COM smb_server_add_rxb(smb_server_t *sv, int64_t value) 133412508Samw@Sun.COM { 133512508Samw@Sun.COM SMB_SERVER_VALID(sv); 133612508Samw@Sun.COM atomic_add_64(&sv->sv_rxb, value); 133712508Samw@Sun.COM } 133812508Samw@Sun.COM 133912508Samw@Sun.COM void 134012508Samw@Sun.COM smb_server_add_txb(smb_server_t *sv, int64_t value) 134112508Samw@Sun.COM { 134212508Samw@Sun.COM SMB_SERVER_VALID(sv); 134312508Samw@Sun.COM atomic_add_64(&sv->sv_txb, value); 134412508Samw@Sun.COM } 134512508Samw@Sun.COM 134612508Samw@Sun.COM void 134712508Samw@Sun.COM smb_server_inc_req(smb_server_t *sv) 134812508Samw@Sun.COM { 134912508Samw@Sun.COM SMB_SERVER_VALID(sv); 135012508Samw@Sun.COM atomic_inc_64(&sv->sv_nreq); 135112508Samw@Sun.COM } 135212508Samw@Sun.COM 135312508Samw@Sun.COM /* 13546139Sjb150015 * ***************************************************************************** 13556139Sjb150015 * *************************** Static Functions ******************************** 13566139Sjb150015 * ***************************************************************************** 13576139Sjb150015 */ 13586139Sjb150015 13596139Sjb150015 static void 13606139Sjb150015 smb_server_timers(smb_thread_t *thread, void *arg) 13616139Sjb150015 { 13626139Sjb150015 smb_server_t *sv = (smb_server_t *)arg; 13636139Sjb150015 13646139Sjb150015 ASSERT(sv != NULL); 13656139Sjb150015 13666139Sjb150015 while (smb_thread_continue_timedwait(thread, 1 /* Seconds */)) { 13676139Sjb150015 smb_session_timers(&sv->sv_nbt_daemon.ld_session_list); 13686139Sjb150015 smb_session_timers(&sv->sv_tcp_daemon.ld_session_list); 13696139Sjb150015 } 13706139Sjb150015 } 13716139Sjb150015 13726139Sjb150015 /* 13736139Sjb150015 * smb_server_kstat_init 13746139Sjb150015 */ 137512508Samw@Sun.COM static void 13766139Sjb150015 smb_server_kstat_init(smb_server_t *sv) 13776139Sjb150015 { 1378*12890SJoyce.McIntosh@Sun.COM char name[KSTAT_STRLEN]; 1379*12890SJoyce.McIntosh@Sun.COM 138012508Samw@Sun.COM sv->sv_ksp = kstat_create_zone(SMBSRV_KSTAT_MODULE, sv->sv_zid, 138112508Samw@Sun.COM SMBSRV_KSTAT_STATISTICS, SMBSRV_KSTAT_CLASS, KSTAT_TYPE_RAW, 138212508Samw@Sun.COM sizeof (smbsrv_kstats_t), 0, sv->sv_zid); 13836139Sjb150015 138412508Samw@Sun.COM if (sv->sv_ksp != NULL) { 138512508Samw@Sun.COM sv->sv_ksp->ks_update = smb_server_kstat_update; 138612508Samw@Sun.COM sv->sv_ksp->ks_private = sv; 138712508Samw@Sun.COM ((smbsrv_kstats_t *)sv->sv_ksp->ks_data)->ks_start_time = 138812508Samw@Sun.COM sv->sv_start_time; 138912508Samw@Sun.COM smb_dispatch_stats_init( 139012508Samw@Sun.COM ((smbsrv_kstats_t *)sv->sv_ksp->ks_data)->ks_reqs); 13916139Sjb150015 kstat_install(sv->sv_ksp); 139212508Samw@Sun.COM } else { 139312508Samw@Sun.COM cmn_err(CE_WARN, "SMB Server: Statistics unavailable"); 13946139Sjb150015 } 1395*12890SJoyce.McIntosh@Sun.COM 1396*12890SJoyce.McIntosh@Sun.COM (void) snprintf(name, sizeof (name), "%s%d", 1397*12890SJoyce.McIntosh@Sun.COM SMBSRV_KSTAT_NAME, sv->sv_zid); 1398*12890SJoyce.McIntosh@Sun.COM 1399*12890SJoyce.McIntosh@Sun.COM sv->sv_legacy_ksp = kstat_create(SMBSRV_KSTAT_MODULE, sv->sv_zid, 1400*12890SJoyce.McIntosh@Sun.COM name, SMBSRV_KSTAT_CLASS, KSTAT_TYPE_NAMED, 1401*12890SJoyce.McIntosh@Sun.COM sizeof (smb_server_legacy_kstat_t) / sizeof (kstat_named_t), 0); 1402*12890SJoyce.McIntosh@Sun.COM 1403*12890SJoyce.McIntosh@Sun.COM if (sv->sv_legacy_ksp != NULL) { 1404*12890SJoyce.McIntosh@Sun.COM smb_server_legacy_kstat_t *ksd; 1405*12890SJoyce.McIntosh@Sun.COM 1406*12890SJoyce.McIntosh@Sun.COM ksd = sv->sv_legacy_ksp->ks_data; 1407*12890SJoyce.McIntosh@Sun.COM 1408*12890SJoyce.McIntosh@Sun.COM (void) strlcpy(ksd->ls_files.name, "open_files", 1409*12890SJoyce.McIntosh@Sun.COM sizeof (ksd->ls_files.name)); 1410*12890SJoyce.McIntosh@Sun.COM ksd->ls_files.data_type = KSTAT_DATA_UINT32; 1411*12890SJoyce.McIntosh@Sun.COM 1412*12890SJoyce.McIntosh@Sun.COM (void) strlcpy(ksd->ls_trees.name, "connections", 1413*12890SJoyce.McIntosh@Sun.COM sizeof (ksd->ls_trees.name)); 1414*12890SJoyce.McIntosh@Sun.COM ksd->ls_trees.data_type = KSTAT_DATA_UINT32; 1415*12890SJoyce.McIntosh@Sun.COM 1416*12890SJoyce.McIntosh@Sun.COM (void) strlcpy(ksd->ls_users.name, "connections", 1417*12890SJoyce.McIntosh@Sun.COM sizeof (ksd->ls_users.name)); 1418*12890SJoyce.McIntosh@Sun.COM ksd->ls_users.data_type = KSTAT_DATA_UINT32; 1419*12890SJoyce.McIntosh@Sun.COM 1420*12890SJoyce.McIntosh@Sun.COM mutex_init(&sv->sv_legacy_ksmtx, NULL, MUTEX_DEFAULT, NULL); 1421*12890SJoyce.McIntosh@Sun.COM sv->sv_legacy_ksp->ks_lock = &sv->sv_legacy_ksmtx; 1422*12890SJoyce.McIntosh@Sun.COM sv->sv_legacy_ksp->ks_update = smb_server_legacy_kstat_update; 1423*12890SJoyce.McIntosh@Sun.COM kstat_install(sv->sv_legacy_ksp); 1424*12890SJoyce.McIntosh@Sun.COM } 14256139Sjb150015 } 14266139Sjb150015 14276139Sjb150015 /* 14286139Sjb150015 * smb_server_kstat_fini 14296139Sjb150015 */ 14306139Sjb150015 static void 14316139Sjb150015 smb_server_kstat_fini(smb_server_t *sv) 14326139Sjb150015 { 1433*12890SJoyce.McIntosh@Sun.COM if (sv->sv_legacy_ksp != NULL) { 1434*12890SJoyce.McIntosh@Sun.COM kstat_delete(sv->sv_legacy_ksp); 1435*12890SJoyce.McIntosh@Sun.COM mutex_destroy(&sv->sv_legacy_ksmtx); 1436*12890SJoyce.McIntosh@Sun.COM sv->sv_legacy_ksp = NULL; 1437*12890SJoyce.McIntosh@Sun.COM } 1438*12890SJoyce.McIntosh@Sun.COM 143912508Samw@Sun.COM if (sv->sv_ksp != NULL) { 14406139Sjb150015 kstat_delete(sv->sv_ksp); 14416139Sjb150015 sv->sv_ksp = NULL; 144212508Samw@Sun.COM smb_dispatch_stats_fini(); 14436139Sjb150015 } 14446139Sjb150015 } 14456139Sjb150015 144612508Samw@Sun.COM /* 144712508Samw@Sun.COM * smb_server_kstat_update 144812508Samw@Sun.COM */ 14496139Sjb150015 static int 145012508Samw@Sun.COM smb_server_kstat_update(kstat_t *ksp, int rw) 14516139Sjb150015 { 14526139Sjb150015 smb_server_t *sv; 145312508Samw@Sun.COM smbsrv_kstats_t *ksd; 14546139Sjb150015 145512508Samw@Sun.COM if (rw == KSTAT_READ) { 145612508Samw@Sun.COM sv = ksp->ks_private; 145711963SAfshin.Ardakani@Sun.COM SMB_SERVER_VALID(sv); 145812508Samw@Sun.COM ksd = (smbsrv_kstats_t *)ksp->ks_data; 145912508Samw@Sun.COM /* 146012508Samw@Sun.COM * Counters 146112508Samw@Sun.COM */ 146212508Samw@Sun.COM ksd->ks_nbt_sess = sv->sv_nbt_sess; 146312508Samw@Sun.COM ksd->ks_tcp_sess = sv->sv_tcp_sess; 146412508Samw@Sun.COM ksd->ks_users = sv->sv_users; 146512508Samw@Sun.COM ksd->ks_trees = sv->sv_trees; 146612508Samw@Sun.COM ksd->ks_files = sv->sv_files; 146712508Samw@Sun.COM ksd->ks_pipes = sv->sv_pipes; 146812508Samw@Sun.COM /* 146912508Samw@Sun.COM * Throughput 147012508Samw@Sun.COM */ 147112508Samw@Sun.COM ksd->ks_txb = sv->sv_txb; 147212508Samw@Sun.COM ksd->ks_rxb = sv->sv_rxb; 147312508Samw@Sun.COM ksd->ks_nreq = sv->sv_nreq; 147412508Samw@Sun.COM /* 147512508Samw@Sun.COM * Busyness 147612508Samw@Sun.COM */ 147712508Samw@Sun.COM ksd->ks_maxreqs = sv->sv_cfg.skc_maxworkers; 147812508Samw@Sun.COM smb_srqueue_update(&sv->sv_srqueue, 147912508Samw@Sun.COM &ksd->ks_utilization); 148012508Samw@Sun.COM /* 148112508Samw@Sun.COM * Latency & Throughput of the requests 148212508Samw@Sun.COM */ 148312508Samw@Sun.COM smb_dispatch_stats_update(ksd->ks_reqs, 0, SMB_COM_NUM); 148412508Samw@Sun.COM return (0); 148512508Samw@Sun.COM } 148612508Samw@Sun.COM if (rw == KSTAT_WRITE) 148712508Samw@Sun.COM return (EACCES); 14886139Sjb150015 148912508Samw@Sun.COM return (EIO); 14906139Sjb150015 } 14916139Sjb150015 1492*12890SJoyce.McIntosh@Sun.COM static int 1493*12890SJoyce.McIntosh@Sun.COM smb_server_legacy_kstat_update(kstat_t *ksp, int rw) 1494*12890SJoyce.McIntosh@Sun.COM { 1495*12890SJoyce.McIntosh@Sun.COM smb_server_t *sv; 1496*12890SJoyce.McIntosh@Sun.COM smb_server_legacy_kstat_t *ksd; 1497*12890SJoyce.McIntosh@Sun.COM int rc; 1498*12890SJoyce.McIntosh@Sun.COM 1499*12890SJoyce.McIntosh@Sun.COM switch (rw) { 1500*12890SJoyce.McIntosh@Sun.COM case KSTAT_WRITE: 1501*12890SJoyce.McIntosh@Sun.COM rc = EACCES; 1502*12890SJoyce.McIntosh@Sun.COM break; 1503*12890SJoyce.McIntosh@Sun.COM case KSTAT_READ: 1504*12890SJoyce.McIntosh@Sun.COM if (!smb_server_lookup(&sv)) { 1505*12890SJoyce.McIntosh@Sun.COM ASSERT(MUTEX_HELD(ksp->ks_lock)); 1506*12890SJoyce.McIntosh@Sun.COM ASSERT(sv->sv_legacy_ksp == ksp); 1507*12890SJoyce.McIntosh@Sun.COM ksd = (smb_server_legacy_kstat_t *)ksp->ks_data; 1508*12890SJoyce.McIntosh@Sun.COM ksd->ls_files.value.ui32 = sv->sv_files + sv->sv_pipes; 1509*12890SJoyce.McIntosh@Sun.COM ksd->ls_trees.value.ui32 = sv->sv_trees; 1510*12890SJoyce.McIntosh@Sun.COM ksd->ls_users.value.ui32 = sv->sv_users; 1511*12890SJoyce.McIntosh@Sun.COM smb_server_release(sv); 1512*12890SJoyce.McIntosh@Sun.COM rc = 0; 1513*12890SJoyce.McIntosh@Sun.COM break; 1514*12890SJoyce.McIntosh@Sun.COM } 1515*12890SJoyce.McIntosh@Sun.COM _NOTE(FALLTHRU) 1516*12890SJoyce.McIntosh@Sun.COM default: 1517*12890SJoyce.McIntosh@Sun.COM rc = EIO; 1518*12890SJoyce.McIntosh@Sun.COM break; 1519*12890SJoyce.McIntosh@Sun.COM } 1520*12890SJoyce.McIntosh@Sun.COM return (rc); 1521*12890SJoyce.McIntosh@Sun.COM 1522*12890SJoyce.McIntosh@Sun.COM } 1523*12890SJoyce.McIntosh@Sun.COM 15246139Sjb150015 /* 15256139Sjb150015 * The mutex of the server must have been entered before calling this function. 15266139Sjb150015 */ 15276139Sjb150015 static void 152811963SAfshin.Ardakani@Sun.COM smb_server_shutdown(smb_server_t *sv) 15296139Sjb150015 { 153011963SAfshin.Ardakani@Sun.COM SMB_SERVER_VALID(sv); 15316139Sjb150015 15327052Samw smb_opipe_door_close(); 15336139Sjb150015 smb_thread_stop(&sv->si_thread_timers); 153411963SAfshin.Ardakani@Sun.COM smb_kdoor_close(); 153512508Samw@Sun.COM smb_kshare_door_fini(sv->sv_lmshrd); 15366849Sjb150015 sv->sv_lmshrd = NULL; 153712508Samw@Sun.COM smb_export_stop(); 15386139Sjb150015 smb_server_fsop_stop(sv); 15397588Samw@Sun.COM 15406139Sjb150015 if (sv->sv_session) { 15416139Sjb150015 smb_session_delete(sv->sv_session); 15426139Sjb150015 sv->sv_session = NULL; 15436139Sjb150015 } 15447588Samw@Sun.COM 15457588Samw@Sun.COM if (sv->sv_thread_pool) { 15467588Samw@Sun.COM taskq_destroy(sv->sv_thread_pool); 15477588Samw@Sun.COM sv->sv_thread_pool = NULL; 15487588Samw@Sun.COM } 15496139Sjb150015 } 15506139Sjb150015 15516139Sjb150015 static int 15526139Sjb150015 smb_server_listen( 15536139Sjb150015 smb_server_t *sv, 15546139Sjb150015 smb_listener_daemon_t *ld, 15556139Sjb150015 in_port_t port, 15568670SJose.Borrego@Sun.COM int family, 15576139Sjb150015 int pthread_create_error) 15586139Sjb150015 { 155911963SAfshin.Ardakani@Sun.COM int rc = 0; 15608348SEric.Yu@Sun.COM ksocket_t s_so; 156111963SAfshin.Ardakani@Sun.COM uint32_t on; 156211963SAfshin.Ardakani@Sun.COM uint32_t off; 156311963SAfshin.Ardakani@Sun.COM uint32_t txbuf_size; 15646139Sjb150015 smb_session_t *session; 15656139Sjb150015 15666139Sjb150015 if (pthread_create_error) { 15676139Sjb150015 /* 15686139Sjb150015 * Delete the last session created. The user space thread 15696139Sjb150015 * creation failed. 15706139Sjb150015 */ 15716139Sjb150015 smb_session_list_delete_tail(&ld->ld_session_list); 15726139Sjb150015 } 15736139Sjb150015 15746139Sjb150015 if (ld->ld_so == NULL) { 15756139Sjb150015 /* First time listener */ 15768670SJose.Borrego@Sun.COM if (family == AF_INET) { 15778670SJose.Borrego@Sun.COM ld->ld_sin.sin_family = (uint32_t)family; 15788670SJose.Borrego@Sun.COM ld->ld_sin.sin_port = htons(port); 15798670SJose.Borrego@Sun.COM ld->ld_sin.sin_addr.s_addr = htonl(INADDR_ANY); 15808670SJose.Borrego@Sun.COM } else { 15818670SJose.Borrego@Sun.COM ld->ld_sin6.sin6_family = (uint32_t)family; 15828670SJose.Borrego@Sun.COM ld->ld_sin6.sin6_port = htons(port); 15838670SJose.Borrego@Sun.COM (void) memset(&ld->ld_sin6.sin6_addr.s6_addr, 0, 15848670SJose.Borrego@Sun.COM sizeof (ld->ld_sin6.sin6_addr.s6_addr)); 15858670SJose.Borrego@Sun.COM } 158611963SAfshin.Ardakani@Sun.COM 15878670SJose.Borrego@Sun.COM ld->ld_so = smb_socreate(family, SOCK_STREAM, 0); 158811963SAfshin.Ardakani@Sun.COM if (ld->ld_so == NULL) { 158911963SAfshin.Ardakani@Sun.COM cmn_err(CE_WARN, "port %d: socket create failed", port); 159011963SAfshin.Ardakani@Sun.COM return (ENOMEM); 159111963SAfshin.Ardakani@Sun.COM } 15926139Sjb150015 159311963SAfshin.Ardakani@Sun.COM off = 0; 159411963SAfshin.Ardakani@Sun.COM (void) ksocket_setsockopt(ld->ld_so, SOL_SOCKET, 159511963SAfshin.Ardakani@Sun.COM SO_MAC_EXEMPT, &off, sizeof (off), CRED()); 159611963SAfshin.Ardakani@Sun.COM 159711963SAfshin.Ardakani@Sun.COM on = 1; 159811963SAfshin.Ardakani@Sun.COM (void) ksocket_setsockopt(ld->ld_so, SOL_SOCKET, 159911963SAfshin.Ardakani@Sun.COM SO_REUSEADDR, &on, sizeof (on), CRED()); 16009021Samw@Sun.COM 160111963SAfshin.Ardakani@Sun.COM if (family == AF_INET) { 160211963SAfshin.Ardakani@Sun.COM rc = ksocket_bind(ld->ld_so, 160311963SAfshin.Ardakani@Sun.COM (struct sockaddr *)&ld->ld_sin, 160411963SAfshin.Ardakani@Sun.COM sizeof (ld->ld_sin), CRED()); 16056139Sjb150015 } else { 160611963SAfshin.Ardakani@Sun.COM rc = ksocket_bind(ld->ld_so, 160711963SAfshin.Ardakani@Sun.COM (struct sockaddr *)&ld->ld_sin6, 160811963SAfshin.Ardakani@Sun.COM sizeof (ld->ld_sin6), CRED()); 160911963SAfshin.Ardakani@Sun.COM } 161011963SAfshin.Ardakani@Sun.COM 161111963SAfshin.Ardakani@Sun.COM if (rc != 0) { 161211963SAfshin.Ardakani@Sun.COM cmn_err(CE_WARN, "port %d: bind failed (%d)", port, rc); 161311963SAfshin.Ardakani@Sun.COM smb_server_listen_fini(ld); 161411963SAfshin.Ardakani@Sun.COM return (rc); 161511963SAfshin.Ardakani@Sun.COM } 161611963SAfshin.Ardakani@Sun.COM 161711963SAfshin.Ardakani@Sun.COM rc = ksocket_listen(ld->ld_so, 20, CRED()); 161811963SAfshin.Ardakani@Sun.COM if (rc < 0) { 161911963SAfshin.Ardakani@Sun.COM cmn_err(CE_WARN, "port %d: listen failed", port); 162011963SAfshin.Ardakani@Sun.COM smb_server_listen_fini(ld); 162111963SAfshin.Ardakani@Sun.COM return (rc); 16226139Sjb150015 } 16236139Sjb150015 } 16246139Sjb150015 16256139Sjb150015 DTRACE_PROBE1(so__wait__accept, struct sonode *, ld->ld_so); 16266139Sjb150015 16276139Sjb150015 for (;;) { 162811963SAfshin.Ardakani@Sun.COM if (smb_server_is_stopping()) { 162911963SAfshin.Ardakani@Sun.COM rc = ECANCELED; 163011963SAfshin.Ardakani@Sun.COM break; 163111963SAfshin.Ardakani@Sun.COM } 163211963SAfshin.Ardakani@Sun.COM 16338348SEric.Yu@Sun.COM rc = ksocket_accept(ld->ld_so, NULL, NULL, &s_so, CRED()); 163411963SAfshin.Ardakani@Sun.COM if (rc != 0) 163511963SAfshin.Ardakani@Sun.COM break; 163611963SAfshin.Ardakani@Sun.COM 163711963SAfshin.Ardakani@Sun.COM if (smb_server_is_stopping()) { 163811963SAfshin.Ardakani@Sun.COM smb_soshutdown(s_so); 163911963SAfshin.Ardakani@Sun.COM smb_sodestroy(s_so); 164011963SAfshin.Ardakani@Sun.COM rc = ECANCELED; 164111963SAfshin.Ardakani@Sun.COM break; 164211963SAfshin.Ardakani@Sun.COM } 16436139Sjb150015 164411963SAfshin.Ardakani@Sun.COM DTRACE_PROBE1(so__accept, struct sonode *, s_so); 164511963SAfshin.Ardakani@Sun.COM 164611963SAfshin.Ardakani@Sun.COM on = 1; 164711963SAfshin.Ardakani@Sun.COM (void) ksocket_setsockopt(s_so, IPPROTO_TCP, TCP_NODELAY, 164811963SAfshin.Ardakani@Sun.COM &on, sizeof (on), CRED()); 164911963SAfshin.Ardakani@Sun.COM 165011963SAfshin.Ardakani@Sun.COM on = 1; 165111963SAfshin.Ardakani@Sun.COM (void) ksocket_setsockopt(s_so, SOL_SOCKET, SO_KEEPALIVE, 165211963SAfshin.Ardakani@Sun.COM &on, sizeof (on), CRED()); 16536139Sjb150015 165411963SAfshin.Ardakani@Sun.COM txbuf_size = 128*1024; 165511963SAfshin.Ardakani@Sun.COM (void) ksocket_setsockopt(s_so, SOL_SOCKET, SO_SNDBUF, 165611963SAfshin.Ardakani@Sun.COM (const void *)&txbuf_size, sizeof (txbuf_size), CRED()); 165711963SAfshin.Ardakani@Sun.COM 165811963SAfshin.Ardakani@Sun.COM /* 165911963SAfshin.Ardakani@Sun.COM * Create a session for this connection. 166011963SAfshin.Ardakani@Sun.COM */ 166111963SAfshin.Ardakani@Sun.COM session = smb_session_create(s_so, port, sv, family); 166211963SAfshin.Ardakani@Sun.COM if (session) { 166311963SAfshin.Ardakani@Sun.COM smb_session_list_append(&ld->ld_session_list, session); 166411963SAfshin.Ardakani@Sun.COM rc = 0; 166511963SAfshin.Ardakani@Sun.COM break; 166611963SAfshin.Ardakani@Sun.COM } else { 166711963SAfshin.Ardakani@Sun.COM smb_soshutdown(s_so); 166811963SAfshin.Ardakani@Sun.COM smb_sodestroy(s_so); 16696139Sjb150015 } 167011963SAfshin.Ardakani@Sun.COM } 167111963SAfshin.Ardakani@Sun.COM 167211963SAfshin.Ardakani@Sun.COM if (rc != 0) 167311963SAfshin.Ardakani@Sun.COM smb_server_listen_fini(ld); 167411963SAfshin.Ardakani@Sun.COM 167511963SAfshin.Ardakani@Sun.COM return (rc); 167611963SAfshin.Ardakani@Sun.COM } 167711963SAfshin.Ardakani@Sun.COM 167811963SAfshin.Ardakani@Sun.COM static void 167911963SAfshin.Ardakani@Sun.COM smb_server_listen_fini(smb_listener_daemon_t *ld) 168011963SAfshin.Ardakani@Sun.COM { 168111963SAfshin.Ardakani@Sun.COM if (ld->ld_so != NULL) { 16826139Sjb150015 smb_session_list_signal(&ld->ld_session_list); 16836139Sjb150015 smb_soshutdown(ld->ld_so); 16846139Sjb150015 smb_sodestroy(ld->ld_so); 16856139Sjb150015 ld->ld_so = NULL; 168611963SAfshin.Ardakani@Sun.COM } 168711963SAfshin.Ardakani@Sun.COM } 168811963SAfshin.Ardakani@Sun.COM 168911963SAfshin.Ardakani@Sun.COM static kt_did_t 169011963SAfshin.Ardakani@Sun.COM smb_server_listener_tid(smb_listener_daemon_t *ld) 169111963SAfshin.Ardakani@Sun.COM { 1692*12890SJoyce.McIntosh@Sun.COM kt_did_t tid = 0; 169311963SAfshin.Ardakani@Sun.COM 169411963SAfshin.Ardakani@Sun.COM if (ld->ld_ktdid != 0) { 169511963SAfshin.Ardakani@Sun.COM tid = ld->ld_ktdid; 169611963SAfshin.Ardakani@Sun.COM ld->ld_ktdid = 0; 16976139Sjb150015 } 16986139Sjb150015 169911963SAfshin.Ardakani@Sun.COM return (tid); 17006139Sjb150015 } 17016139Sjb150015 17026139Sjb150015 /* 17036139Sjb150015 * smb_server_lookup 17046139Sjb150015 * 17056139Sjb150015 * This function tries to find the server associated with the zone of the 17066139Sjb150015 * caller. 17076139Sjb150015 */ 17086139Sjb150015 static int 17096139Sjb150015 smb_server_lookup(smb_server_t **psv) 17106139Sjb150015 { 17116139Sjb150015 zoneid_t zid; 17126139Sjb150015 smb_server_t *sv; 17136139Sjb150015 17146139Sjb150015 zid = getzoneid(); 17156139Sjb150015 17166139Sjb150015 smb_llist_enter(&smb_servers, RW_READER); 17176139Sjb150015 sv = smb_llist_head(&smb_servers); 17186139Sjb150015 while (sv) { 171911963SAfshin.Ardakani@Sun.COM SMB_SERVER_VALID(sv); 17206139Sjb150015 if (sv->sv_zid == zid) { 17216139Sjb150015 mutex_enter(&sv->sv_mutex); 17226139Sjb150015 if (sv->sv_state != SMB_SERVER_STATE_DELETING) { 17236139Sjb150015 sv->sv_refcnt++; 17246139Sjb150015 mutex_exit(&sv->sv_mutex); 17256139Sjb150015 smb_llist_exit(&smb_servers); 17266139Sjb150015 *psv = sv; 17276139Sjb150015 return (0); 17286139Sjb150015 } 17296139Sjb150015 mutex_exit(&sv->sv_mutex); 17306139Sjb150015 break; 17316139Sjb150015 } 17326139Sjb150015 sv = smb_llist_next(&smb_servers, sv); 17336139Sjb150015 } 17346139Sjb150015 smb_llist_exit(&smb_servers); 17356139Sjb150015 return (EPERM); 17366139Sjb150015 } 17376139Sjb150015 17386139Sjb150015 /* 17396139Sjb150015 * smb_server_release 17406139Sjb150015 * 17416139Sjb150015 * This function decrements the reference count of the server and signals its 17426139Sjb150015 * condition variable if the state of the server is SMB_SERVER_STATE_DELETING. 17436139Sjb150015 */ 17446139Sjb150015 static void 17456139Sjb150015 smb_server_release(smb_server_t *sv) 17466139Sjb150015 { 174711963SAfshin.Ardakani@Sun.COM SMB_SERVER_VALID(sv); 17486139Sjb150015 17496139Sjb150015 mutex_enter(&sv->sv_mutex); 17506139Sjb150015 ASSERT(sv->sv_refcnt); 17516139Sjb150015 sv->sv_refcnt--; 17526139Sjb150015 if ((sv->sv_refcnt == 0) && (sv->sv_state == SMB_SERVER_STATE_DELETING)) 17536139Sjb150015 cv_signal(&sv->sv_cv); 17546139Sjb150015 mutex_exit(&sv->sv_mutex); 17556139Sjb150015 } 17566139Sjb150015 175710122SJordan.Brown@Sun.COM /* 175810122SJordan.Brown@Sun.COM * Enumerate the users associated with a session list. 175910122SJordan.Brown@Sun.COM */ 176010122SJordan.Brown@Sun.COM static void 176110122SJordan.Brown@Sun.COM smb_server_enum_private(smb_session_list_t *se, smb_svcenum_t *svcenum) 17626139Sjb150015 { 176310122SJordan.Brown@Sun.COM smb_session_t *sn; 176410122SJordan.Brown@Sun.COM smb_llist_t *ulist; 176510122SJordan.Brown@Sun.COM smb_user_t *user; 176610122SJordan.Brown@Sun.COM int rc = 0; 17676139Sjb150015 17686139Sjb150015 rw_enter(&se->se_lock, RW_READER); 17696139Sjb150015 sn = list_head(&se->se_act.lst); 177010122SJordan.Brown@Sun.COM 177110122SJordan.Brown@Sun.COM while (sn != NULL) { 17726139Sjb150015 ASSERT(sn->s_magic == SMB_SESSION_MAGIC); 17736139Sjb150015 ulist = &sn->s_user_list; 17746139Sjb150015 smb_llist_enter(ulist, RW_READER); 17756139Sjb150015 user = smb_llist_head(ulist); 177610122SJordan.Brown@Sun.COM 177710122SJordan.Brown@Sun.COM while (user != NULL) { 177810122SJordan.Brown@Sun.COM if (smb_user_hold(user)) { 177910122SJordan.Brown@Sun.COM rc = smb_user_enum(user, svcenum); 178010122SJordan.Brown@Sun.COM smb_user_release(user); 178110122SJordan.Brown@Sun.COM } 178210122SJordan.Brown@Sun.COM 178310122SJordan.Brown@Sun.COM user = smb_llist_next(ulist, user); 178410122SJordan.Brown@Sun.COM } 178510122SJordan.Brown@Sun.COM 178610122SJordan.Brown@Sun.COM smb_llist_exit(ulist); 178710122SJordan.Brown@Sun.COM 178810122SJordan.Brown@Sun.COM if (rc != 0) 178910122SJordan.Brown@Sun.COM break; 179010122SJordan.Brown@Sun.COM 179110122SJordan.Brown@Sun.COM sn = list_next(&se->se_act.lst, sn); 179210122SJordan.Brown@Sun.COM } 179310122SJordan.Brown@Sun.COM 179410122SJordan.Brown@Sun.COM rw_exit(&se->se_lock); 179510122SJordan.Brown@Sun.COM } 179610122SJordan.Brown@Sun.COM 179710122SJordan.Brown@Sun.COM /* 179810122SJordan.Brown@Sun.COM * Disconnect sessions associated with the specified client and username. 179910122SJordan.Brown@Sun.COM * Empty strings are treated as wildcards. 180010122SJordan.Brown@Sun.COM */ 180110122SJordan.Brown@Sun.COM static int 180210122SJordan.Brown@Sun.COM smb_server_sesion_disconnect(smb_session_list_t *se, 180310122SJordan.Brown@Sun.COM const char *client, const char *name) 180410122SJordan.Brown@Sun.COM { 180510122SJordan.Brown@Sun.COM smb_session_t *sn; 180610122SJordan.Brown@Sun.COM smb_llist_t *ulist; 180710122SJordan.Brown@Sun.COM smb_user_t *user; 180810122SJordan.Brown@Sun.COM boolean_t match; 180910122SJordan.Brown@Sun.COM int count = 0; 181010122SJordan.Brown@Sun.COM 181110122SJordan.Brown@Sun.COM rw_enter(&se->se_lock, RW_READER); 181210122SJordan.Brown@Sun.COM sn = list_head(&se->se_act.lst); 181310122SJordan.Brown@Sun.COM 181410122SJordan.Brown@Sun.COM while (sn != NULL) { 181510122SJordan.Brown@Sun.COM ASSERT(sn->s_magic == SMB_SESSION_MAGIC); 181610122SJordan.Brown@Sun.COM 181710122SJordan.Brown@Sun.COM if ((*client != '\0') && (!smb_session_isclient(sn, client))) { 181810122SJordan.Brown@Sun.COM sn = list_next(&se->se_act.lst, sn); 181910122SJordan.Brown@Sun.COM continue; 182010122SJordan.Brown@Sun.COM } 182110122SJordan.Brown@Sun.COM 182210122SJordan.Brown@Sun.COM ulist = &sn->s_user_list; 182310122SJordan.Brown@Sun.COM smb_llist_enter(ulist, RW_READER); 182410122SJordan.Brown@Sun.COM user = smb_llist_head(ulist); 182510122SJordan.Brown@Sun.COM 182610122SJordan.Brown@Sun.COM while (user != NULL) { 182710122SJordan.Brown@Sun.COM if (smb_user_hold(user)) { 182810122SJordan.Brown@Sun.COM match = (*name == '\0'); 182910122SJordan.Brown@Sun.COM if (!match) 183010122SJordan.Brown@Sun.COM match = smb_user_namecmp(user, name); 183110122SJordan.Brown@Sun.COM 183210122SJordan.Brown@Sun.COM if (match) { 183310122SJordan.Brown@Sun.COM smb_llist_exit(ulist); 183410122SJordan.Brown@Sun.COM smb_user_logoff(user); 183510122SJordan.Brown@Sun.COM ++count; 183610122SJordan.Brown@Sun.COM smb_user_release(user); 183710122SJordan.Brown@Sun.COM smb_llist_enter(ulist, RW_READER); 183810122SJordan.Brown@Sun.COM user = smb_llist_head(ulist); 183910122SJordan.Brown@Sun.COM continue; 18406139Sjb150015 } 184110122SJordan.Brown@Sun.COM 184210122SJordan.Brown@Sun.COM smb_user_release(user); 18436139Sjb150015 } 184410122SJordan.Brown@Sun.COM 18456139Sjb150015 user = smb_llist_next(ulist, user); 18466139Sjb150015 } 184710122SJordan.Brown@Sun.COM 18486139Sjb150015 smb_llist_exit(ulist); 18497961SNatalie.Li@Sun.COM sn = list_next(&se->se_act.lst, sn); 18506139Sjb150015 } 185110122SJordan.Brown@Sun.COM 18526139Sjb150015 rw_exit(&se->se_lock); 185310122SJordan.Brown@Sun.COM return (count); 185410122SJordan.Brown@Sun.COM } 185510122SJordan.Brown@Sun.COM 185610122SJordan.Brown@Sun.COM /* 185710122SJordan.Brown@Sun.COM * Close a file by its unique id. 185810122SJordan.Brown@Sun.COM */ 185910122SJordan.Brown@Sun.COM static int 186010122SJordan.Brown@Sun.COM smb_server_fclose(smb_session_list_t *se, uint32_t uniqid) 186110122SJordan.Brown@Sun.COM { 186210122SJordan.Brown@Sun.COM smb_session_t *sn; 186310122SJordan.Brown@Sun.COM smb_llist_t *ulist; 186410122SJordan.Brown@Sun.COM smb_user_t *user; 186510122SJordan.Brown@Sun.COM int rc = ENOENT; 186610122SJordan.Brown@Sun.COM 186710122SJordan.Brown@Sun.COM rw_enter(&se->se_lock, RW_READER); 186810122SJordan.Brown@Sun.COM sn = list_head(&se->se_act.lst); 186910122SJordan.Brown@Sun.COM 187010122SJordan.Brown@Sun.COM while ((sn != NULL) && (rc == ENOENT)) { 187110122SJordan.Brown@Sun.COM ASSERT(sn->s_magic == SMB_SESSION_MAGIC); 187210122SJordan.Brown@Sun.COM ulist = &sn->s_user_list; 187310122SJordan.Brown@Sun.COM smb_llist_enter(ulist, RW_READER); 187410122SJordan.Brown@Sun.COM user = smb_llist_head(ulist); 187510122SJordan.Brown@Sun.COM 187610122SJordan.Brown@Sun.COM while ((user != NULL) && (rc == ENOENT)) { 187710122SJordan.Brown@Sun.COM if (smb_user_hold(user)) { 187810122SJordan.Brown@Sun.COM rc = smb_user_fclose(user, uniqid); 187910122SJordan.Brown@Sun.COM smb_user_release(user); 188010122SJordan.Brown@Sun.COM } 188110122SJordan.Brown@Sun.COM 188210122SJordan.Brown@Sun.COM user = smb_llist_next(ulist, user); 188310122SJordan.Brown@Sun.COM } 188410122SJordan.Brown@Sun.COM 188510122SJordan.Brown@Sun.COM smb_llist_exit(ulist); 188610122SJordan.Brown@Sun.COM sn = list_next(&se->se_act.lst, sn); 188710122SJordan.Brown@Sun.COM } 188810122SJordan.Brown@Sun.COM 188910122SJordan.Brown@Sun.COM rw_exit(&se->se_lock); 189010122SJordan.Brown@Sun.COM return (rc); 18916139Sjb150015 } 18926139Sjb150015 18936139Sjb150015 static void 18949832Samw@Sun.COM smb_server_store_cfg(smb_server_t *sv, smb_ioc_cfg_t *ioc) 18956139Sjb150015 { 18969832Samw@Sun.COM if (ioc->maxconnections == 0) 18979832Samw@Sun.COM ioc->maxconnections = 0xFFFFFFFF; 18986139Sjb150015 18996139Sjb150015 smb_session_correct_keep_alive_values( 19009832Samw@Sun.COM &sv->sv_nbt_daemon.ld_session_list, ioc->keepalive); 19016139Sjb150015 smb_session_correct_keep_alive_values( 19029832Samw@Sun.COM &sv->sv_tcp_daemon.ld_session_list, ioc->keepalive); 19036139Sjb150015 19049832Samw@Sun.COM sv->sv_cfg.skc_maxworkers = ioc->maxworkers; 19059832Samw@Sun.COM sv->sv_cfg.skc_maxconnections = ioc->maxconnections; 19069832Samw@Sun.COM sv->sv_cfg.skc_keepalive = ioc->keepalive; 19079832Samw@Sun.COM sv->sv_cfg.skc_restrict_anon = ioc->restrict_anon; 19089832Samw@Sun.COM sv->sv_cfg.skc_signing_enable = ioc->signing_enable; 19099832Samw@Sun.COM sv->sv_cfg.skc_signing_required = ioc->signing_required; 19109832Samw@Sun.COM sv->sv_cfg.skc_oplock_enable = ioc->oplock_enable; 19119832Samw@Sun.COM sv->sv_cfg.skc_sync_enable = ioc->sync_enable; 19129832Samw@Sun.COM sv->sv_cfg.skc_secmode = ioc->secmode; 19139832Samw@Sun.COM sv->sv_cfg.skc_ipv6_enable = ioc->ipv6_enable; 1914*12890SJoyce.McIntosh@Sun.COM sv->sv_cfg.skc_print_enable = ioc->print_enable; 191512508Samw@Sun.COM sv->sv_cfg.skc_execflags = ioc->exec_flags; 191612508Samw@Sun.COM sv->sv_cfg.skc_version = ioc->version; 19179832Samw@Sun.COM (void) strlcpy(sv->sv_cfg.skc_nbdomain, ioc->nbdomain, 19189832Samw@Sun.COM sizeof (sv->sv_cfg.skc_nbdomain)); 19199832Samw@Sun.COM (void) strlcpy(sv->sv_cfg.skc_fqdn, ioc->fqdn, 19209832Samw@Sun.COM sizeof (sv->sv_cfg.skc_fqdn)); 19219832Samw@Sun.COM (void) strlcpy(sv->sv_cfg.skc_hostname, ioc->hostname, 19229832Samw@Sun.COM sizeof (sv->sv_cfg.skc_hostname)); 19239832Samw@Sun.COM (void) strlcpy(sv->sv_cfg.skc_system_comment, ioc->system_comment, 19249832Samw@Sun.COM sizeof (sv->sv_cfg.skc_system_comment)); 19256139Sjb150015 } 19266139Sjb150015 19276139Sjb150015 static int 19286139Sjb150015 smb_server_fsop_start(smb_server_t *sv) 19296139Sjb150015 { 19306139Sjb150015 int error; 19316139Sjb150015 19326139Sjb150015 error = smb_node_root_init(rootdir, sv, &sv->si_root_smb_node); 19336139Sjb150015 if (error != 0) 19346139Sjb150015 sv->si_root_smb_node = NULL; 19356139Sjb150015 19366139Sjb150015 return (error); 19376139Sjb150015 } 19386139Sjb150015 19396139Sjb150015 static void 19406139Sjb150015 smb_server_fsop_stop(smb_server_t *sv) 19416139Sjb150015 { 19426139Sjb150015 if (sv->si_root_smb_node != NULL) { 19436139Sjb150015 smb_node_release(sv->si_root_smb_node); 19446139Sjb150015 sv->si_root_smb_node = NULL; 19456139Sjb150015 } 19466139Sjb150015 } 194711963SAfshin.Ardakani@Sun.COM 194811963SAfshin.Ardakani@Sun.COM static void 194911963SAfshin.Ardakani@Sun.COM smb_server_signal_listeners(smb_server_t *sv) 195011963SAfshin.Ardakani@Sun.COM { 195111963SAfshin.Ardakani@Sun.COM SMB_SERVER_VALID(sv); 195211963SAfshin.Ardakani@Sun.COM ASSERT(sv->sv_state == SMB_SERVER_STATE_STOPPING); 195311963SAfshin.Ardakani@Sun.COM ASSERT(MUTEX_HELD(&sv->sv_mutex)); 195411963SAfshin.Ardakani@Sun.COM 195511963SAfshin.Ardakani@Sun.COM smb_event_cancel(sv, 0); 195611963SAfshin.Ardakani@Sun.COM 195711963SAfshin.Ardakani@Sun.COM if (sv->sv_nbt_daemon.ld_kth != NULL) { 195811963SAfshin.Ardakani@Sun.COM tsignal(sv->sv_nbt_daemon.ld_kth, SIGINT); 195911963SAfshin.Ardakani@Sun.COM sv->sv_nbt_daemon.ld_kth = NULL; 196011963SAfshin.Ardakani@Sun.COM } 196111963SAfshin.Ardakani@Sun.COM 196211963SAfshin.Ardakani@Sun.COM if (sv->sv_tcp_daemon.ld_kth != NULL) { 196311963SAfshin.Ardakani@Sun.COM tsignal(sv->sv_tcp_daemon.ld_kth, SIGINT); 196411963SAfshin.Ardakani@Sun.COM sv->sv_tcp_daemon.ld_kth = NULL; 196511963SAfshin.Ardakani@Sun.COM } 196611963SAfshin.Ardakani@Sun.COM } 196711963SAfshin.Ardakani@Sun.COM 196811963SAfshin.Ardakani@Sun.COM smb_event_t * 1969*12890SJoyce.McIntosh@Sun.COM smb_event_create(int timeout) 197011963SAfshin.Ardakani@Sun.COM { 197111963SAfshin.Ardakani@Sun.COM smb_server_t *sv; 197211963SAfshin.Ardakani@Sun.COM smb_event_t *event; 197311963SAfshin.Ardakani@Sun.COM 197411963SAfshin.Ardakani@Sun.COM if (smb_server_is_stopping()) 197511963SAfshin.Ardakani@Sun.COM return (NULL); 197611963SAfshin.Ardakani@Sun.COM 197711963SAfshin.Ardakani@Sun.COM if (smb_server_lookup(&sv) != 0) { 197811963SAfshin.Ardakani@Sun.COM cmn_err(CE_NOTE, "smb_event_create failed"); 197911963SAfshin.Ardakani@Sun.COM return (NULL); 198011963SAfshin.Ardakani@Sun.COM } 198111963SAfshin.Ardakani@Sun.COM 198211963SAfshin.Ardakani@Sun.COM event = kmem_cache_alloc(sv->si_cache_event, KM_SLEEP); 198311963SAfshin.Ardakani@Sun.COM 198411963SAfshin.Ardakani@Sun.COM bzero(event, sizeof (smb_event_t)); 198511963SAfshin.Ardakani@Sun.COM mutex_init(&event->se_mutex, NULL, MUTEX_DEFAULT, NULL); 198611963SAfshin.Ardakani@Sun.COM cv_init(&event->se_cv, NULL, CV_DEFAULT, NULL); 198711963SAfshin.Ardakani@Sun.COM event->se_magic = SMB_EVENT_MAGIC; 198811963SAfshin.Ardakani@Sun.COM event->se_txid = smb_event_alloc_txid(); 198911963SAfshin.Ardakani@Sun.COM event->se_server = sv; 1990*12890SJoyce.McIntosh@Sun.COM event->se_timeout = timeout; 199111963SAfshin.Ardakani@Sun.COM 199211963SAfshin.Ardakani@Sun.COM smb_llist_enter(&sv->sv_event_list, RW_WRITER); 199311963SAfshin.Ardakani@Sun.COM smb_llist_insert_tail(&sv->sv_event_list, event); 199411963SAfshin.Ardakani@Sun.COM smb_llist_exit(&sv->sv_event_list); 199511963SAfshin.Ardakani@Sun.COM 199611963SAfshin.Ardakani@Sun.COM smb_server_release(sv); 199711963SAfshin.Ardakani@Sun.COM return (event); 199811963SAfshin.Ardakani@Sun.COM } 199911963SAfshin.Ardakani@Sun.COM 200011963SAfshin.Ardakani@Sun.COM void 200111963SAfshin.Ardakani@Sun.COM smb_event_destroy(smb_event_t *event) 200211963SAfshin.Ardakani@Sun.COM { 200311963SAfshin.Ardakani@Sun.COM smb_server_t *sv; 200411963SAfshin.Ardakani@Sun.COM 200511963SAfshin.Ardakani@Sun.COM if (event == NULL) 200611963SAfshin.Ardakani@Sun.COM return; 200711963SAfshin.Ardakani@Sun.COM 200811963SAfshin.Ardakani@Sun.COM SMB_EVENT_VALID(event); 200911963SAfshin.Ardakani@Sun.COM ASSERT(event->se_waittime == 0); 201011963SAfshin.Ardakani@Sun.COM 201111963SAfshin.Ardakani@Sun.COM if (smb_server_lookup(&sv) != 0) 201211963SAfshin.Ardakani@Sun.COM return; 201311963SAfshin.Ardakani@Sun.COM 201411963SAfshin.Ardakani@Sun.COM smb_llist_enter(&sv->sv_event_list, RW_WRITER); 201511963SAfshin.Ardakani@Sun.COM smb_llist_remove(&sv->sv_event_list, event); 201611963SAfshin.Ardakani@Sun.COM smb_llist_exit(&sv->sv_event_list); 201711963SAfshin.Ardakani@Sun.COM 201811963SAfshin.Ardakani@Sun.COM event->se_magic = (uint32_t)~SMB_EVENT_MAGIC; 201911963SAfshin.Ardakani@Sun.COM cv_destroy(&event->se_cv); 202011963SAfshin.Ardakani@Sun.COM mutex_destroy(&event->se_mutex); 202111963SAfshin.Ardakani@Sun.COM 202211963SAfshin.Ardakani@Sun.COM kmem_cache_free(sv->si_cache_event, event); 202311963SAfshin.Ardakani@Sun.COM smb_server_release(sv); 202411963SAfshin.Ardakani@Sun.COM } 202511963SAfshin.Ardakani@Sun.COM 202611963SAfshin.Ardakani@Sun.COM /* 202711963SAfshin.Ardakani@Sun.COM * Get the txid for the specified event. 202811963SAfshin.Ardakani@Sun.COM */ 202911963SAfshin.Ardakani@Sun.COM uint32_t 203011963SAfshin.Ardakani@Sun.COM smb_event_txid(smb_event_t *event) 203111963SAfshin.Ardakani@Sun.COM { 203211963SAfshin.Ardakani@Sun.COM if (event != NULL) { 203311963SAfshin.Ardakani@Sun.COM SMB_EVENT_VALID(event); 203411963SAfshin.Ardakani@Sun.COM return (event->se_txid); 203511963SAfshin.Ardakani@Sun.COM } 203611963SAfshin.Ardakani@Sun.COM 203711963SAfshin.Ardakani@Sun.COM cmn_err(CE_NOTE, "smb_event_txid failed"); 203811963SAfshin.Ardakani@Sun.COM return ((uint32_t)-1); 203911963SAfshin.Ardakani@Sun.COM } 204011963SAfshin.Ardakani@Sun.COM 204111963SAfshin.Ardakani@Sun.COM /* 204211963SAfshin.Ardakani@Sun.COM * Wait for event notification. 204311963SAfshin.Ardakani@Sun.COM */ 204411963SAfshin.Ardakani@Sun.COM int 204511963SAfshin.Ardakani@Sun.COM smb_event_wait(smb_event_t *event) 204611963SAfshin.Ardakani@Sun.COM { 204711963SAfshin.Ardakani@Sun.COM int seconds = 1; 204811963SAfshin.Ardakani@Sun.COM int ticks; 204911963SAfshin.Ardakani@Sun.COM 205011963SAfshin.Ardakani@Sun.COM if (event == NULL) 205111963SAfshin.Ardakani@Sun.COM return (EINVAL); 205211963SAfshin.Ardakani@Sun.COM 205311963SAfshin.Ardakani@Sun.COM SMB_EVENT_VALID(event); 205411963SAfshin.Ardakani@Sun.COM 205511963SAfshin.Ardakani@Sun.COM mutex_enter(&event->se_mutex); 205611963SAfshin.Ardakani@Sun.COM event->se_waittime = 1; 205711963SAfshin.Ardakani@Sun.COM event->se_errno = 0; 205811963SAfshin.Ardakani@Sun.COM 205911963SAfshin.Ardakani@Sun.COM while (!(event->se_notified)) { 206012065SKeyur.Desai@Sun.COM if (smb_event_debug && ((event->se_waittime % 30) == 0)) 206111963SAfshin.Ardakani@Sun.COM cmn_err(CE_NOTE, "smb_event_wait[%d] (%d sec)", 206211963SAfshin.Ardakani@Sun.COM event->se_txid, event->se_waittime); 206311963SAfshin.Ardakani@Sun.COM 206411963SAfshin.Ardakani@Sun.COM if (event->se_errno != 0) 206511963SAfshin.Ardakani@Sun.COM break; 206611963SAfshin.Ardakani@Sun.COM 2067*12890SJoyce.McIntosh@Sun.COM if (event->se_waittime > event->se_timeout) { 206811963SAfshin.Ardakani@Sun.COM event->se_errno = ETIME; 206911963SAfshin.Ardakani@Sun.COM break; 207011963SAfshin.Ardakani@Sun.COM } 207111963SAfshin.Ardakani@Sun.COM 207211963SAfshin.Ardakani@Sun.COM ticks = SEC_TO_TICK(seconds); 207311963SAfshin.Ardakani@Sun.COM (void) cv_reltimedwait(&event->se_cv, 207411963SAfshin.Ardakani@Sun.COM &event->se_mutex, (clock_t)ticks, TR_CLOCK_TICK); 207511963SAfshin.Ardakani@Sun.COM ++event->se_waittime; 207611963SAfshin.Ardakani@Sun.COM } 207711963SAfshin.Ardakani@Sun.COM 207811963SAfshin.Ardakani@Sun.COM event->se_waittime = 0; 207911963SAfshin.Ardakani@Sun.COM event->se_notified = B_FALSE; 208011963SAfshin.Ardakani@Sun.COM cv_signal(&event->se_cv); 208111963SAfshin.Ardakani@Sun.COM mutex_exit(&event->se_mutex); 208211963SAfshin.Ardakani@Sun.COM return (event->se_errno); 208311963SAfshin.Ardakani@Sun.COM } 208411963SAfshin.Ardakani@Sun.COM 208511963SAfshin.Ardakani@Sun.COM /* 208611963SAfshin.Ardakani@Sun.COM * If txid is non-zero, cancel the specified event. 208711963SAfshin.Ardakani@Sun.COM * Otherwise, cancel all events. 208811963SAfshin.Ardakani@Sun.COM */ 208911963SAfshin.Ardakani@Sun.COM static void 209011963SAfshin.Ardakani@Sun.COM smb_event_cancel(smb_server_t *sv, uint32_t txid) 209111963SAfshin.Ardakani@Sun.COM { 209211963SAfshin.Ardakani@Sun.COM smb_event_t *event; 209311963SAfshin.Ardakani@Sun.COM smb_llist_t *event_list; 209411963SAfshin.Ardakani@Sun.COM 209511963SAfshin.Ardakani@Sun.COM SMB_SERVER_VALID(sv); 209611963SAfshin.Ardakani@Sun.COM 209711963SAfshin.Ardakani@Sun.COM event_list = &sv->sv_event_list; 209811963SAfshin.Ardakani@Sun.COM smb_llist_enter(event_list, RW_WRITER); 209911963SAfshin.Ardakani@Sun.COM 210011963SAfshin.Ardakani@Sun.COM event = smb_llist_head(event_list); 210111963SAfshin.Ardakani@Sun.COM while (event) { 210211963SAfshin.Ardakani@Sun.COM SMB_EVENT_VALID(event); 210311963SAfshin.Ardakani@Sun.COM 210411963SAfshin.Ardakani@Sun.COM if (txid == 0 || event->se_txid == txid) { 210511963SAfshin.Ardakani@Sun.COM mutex_enter(&event->se_mutex); 210611963SAfshin.Ardakani@Sun.COM event->se_errno = ECANCELED; 210711963SAfshin.Ardakani@Sun.COM event->se_notified = B_TRUE; 210811963SAfshin.Ardakani@Sun.COM cv_signal(&event->se_cv); 210911963SAfshin.Ardakani@Sun.COM mutex_exit(&event->se_mutex); 211011963SAfshin.Ardakani@Sun.COM 211111963SAfshin.Ardakani@Sun.COM if (txid != 0) 211211963SAfshin.Ardakani@Sun.COM break; 211311963SAfshin.Ardakani@Sun.COM } 211411963SAfshin.Ardakani@Sun.COM 211511963SAfshin.Ardakani@Sun.COM event = smb_llist_next(event_list, event); 211611963SAfshin.Ardakani@Sun.COM } 211711963SAfshin.Ardakani@Sun.COM 211811963SAfshin.Ardakani@Sun.COM smb_llist_exit(event_list); 211911963SAfshin.Ardakani@Sun.COM } 212011963SAfshin.Ardakani@Sun.COM 212111963SAfshin.Ardakani@Sun.COM /* 212211963SAfshin.Ardakani@Sun.COM * If txid is non-zero, notify the specified event. 212311963SAfshin.Ardakani@Sun.COM * Otherwise, notify all events. 212411963SAfshin.Ardakani@Sun.COM */ 2125*12890SJoyce.McIntosh@Sun.COM void 212611963SAfshin.Ardakani@Sun.COM smb_event_notify(smb_server_t *sv, uint32_t txid) 212711963SAfshin.Ardakani@Sun.COM { 212811963SAfshin.Ardakani@Sun.COM smb_event_t *event; 212911963SAfshin.Ardakani@Sun.COM smb_llist_t *event_list; 213011963SAfshin.Ardakani@Sun.COM 213111963SAfshin.Ardakani@Sun.COM SMB_SERVER_VALID(sv); 213211963SAfshin.Ardakani@Sun.COM 213311963SAfshin.Ardakani@Sun.COM event_list = &sv->sv_event_list; 213411963SAfshin.Ardakani@Sun.COM smb_llist_enter(event_list, RW_READER); 213511963SAfshin.Ardakani@Sun.COM 213611963SAfshin.Ardakani@Sun.COM event = smb_llist_head(event_list); 213711963SAfshin.Ardakani@Sun.COM while (event) { 213811963SAfshin.Ardakani@Sun.COM SMB_EVENT_VALID(event); 213911963SAfshin.Ardakani@Sun.COM 214011963SAfshin.Ardakani@Sun.COM if (txid == 0 || event->se_txid == txid) { 214111963SAfshin.Ardakani@Sun.COM mutex_enter(&event->se_mutex); 214211963SAfshin.Ardakani@Sun.COM event->se_notified = B_TRUE; 214311963SAfshin.Ardakani@Sun.COM cv_signal(&event->se_cv); 214411963SAfshin.Ardakani@Sun.COM mutex_exit(&event->se_mutex); 214511963SAfshin.Ardakani@Sun.COM 214611963SAfshin.Ardakani@Sun.COM if (txid != 0) 214711963SAfshin.Ardakani@Sun.COM break; 214811963SAfshin.Ardakani@Sun.COM } 214911963SAfshin.Ardakani@Sun.COM 215011963SAfshin.Ardakani@Sun.COM event = smb_llist_next(event_list, event); 215111963SAfshin.Ardakani@Sun.COM } 215211963SAfshin.Ardakani@Sun.COM 215311963SAfshin.Ardakani@Sun.COM smb_llist_exit(event_list); 215411963SAfshin.Ardakani@Sun.COM } 215511963SAfshin.Ardakani@Sun.COM 215611963SAfshin.Ardakani@Sun.COM /* 215711963SAfshin.Ardakani@Sun.COM * Allocate a new transaction id (txid). 215811963SAfshin.Ardakani@Sun.COM * 215911963SAfshin.Ardakani@Sun.COM * 0 or -1 are not assigned because they are used to detect invalid 216011963SAfshin.Ardakani@Sun.COM * conditions or to indicate all open id's. 216111963SAfshin.Ardakani@Sun.COM */ 216211963SAfshin.Ardakani@Sun.COM static uint32_t 216311963SAfshin.Ardakani@Sun.COM smb_event_alloc_txid(void) 216411963SAfshin.Ardakani@Sun.COM { 216511963SAfshin.Ardakani@Sun.COM static kmutex_t txmutex; 216611963SAfshin.Ardakani@Sun.COM static uint32_t txid; 216711963SAfshin.Ardakani@Sun.COM uint32_t txid_ret; 216811963SAfshin.Ardakani@Sun.COM 216911963SAfshin.Ardakani@Sun.COM mutex_enter(&txmutex); 217011963SAfshin.Ardakani@Sun.COM 217111963SAfshin.Ardakani@Sun.COM if (txid == 0) 217211963SAfshin.Ardakani@Sun.COM txid = ddi_get_lbolt() << 11; 217311963SAfshin.Ardakani@Sun.COM 217411963SAfshin.Ardakani@Sun.COM do { 217511963SAfshin.Ardakani@Sun.COM ++txid; 217611963SAfshin.Ardakani@Sun.COM } while (txid == 0 || txid == (uint32_t)-1); 217711963SAfshin.Ardakani@Sun.COM 217811963SAfshin.Ardakani@Sun.COM txid_ret = txid; 217911963SAfshin.Ardakani@Sun.COM mutex_exit(&txmutex); 218011963SAfshin.Ardakani@Sun.COM 218111963SAfshin.Ardakani@Sun.COM return (txid_ret); 218211963SAfshin.Ardakani@Sun.COM } 2183*12890SJoyce.McIntosh@Sun.COM 2184*12890SJoyce.McIntosh@Sun.COM /* 2185*12890SJoyce.McIntosh@Sun.COM * Called by the ioctl to find the corresponding 2186*12890SJoyce.McIntosh@Sun.COM * spooldoc node. removes node on success 2187*12890SJoyce.McIntosh@Sun.COM * 2188*12890SJoyce.McIntosh@Sun.COM * Return values 2189*12890SJoyce.McIntosh@Sun.COM * rc 2190*12890SJoyce.McIntosh@Sun.COM * B_FALSE - not found 2191*12890SJoyce.McIntosh@Sun.COM * B_TRUE - found 2192*12890SJoyce.McIntosh@Sun.COM * 2193*12890SJoyce.McIntosh@Sun.COM */ 2194*12890SJoyce.McIntosh@Sun.COM 2195*12890SJoyce.McIntosh@Sun.COM boolean_t 2196*12890SJoyce.McIntosh@Sun.COM smb_spool_lookup_doc_byfid(uint16_t fid, smb_kspooldoc_t *spdoc) 2197*12890SJoyce.McIntosh@Sun.COM { 2198*12890SJoyce.McIntosh@Sun.COM smb_kspooldoc_t *sp; 2199*12890SJoyce.McIntosh@Sun.COM smb_llist_t *splist; 2200*12890SJoyce.McIntosh@Sun.COM smb_server_t *sv; 2201*12890SJoyce.McIntosh@Sun.COM int rc; 2202*12890SJoyce.McIntosh@Sun.COM 2203*12890SJoyce.McIntosh@Sun.COM rc = smb_server_lookup(&sv); 2204*12890SJoyce.McIntosh@Sun.COM if (rc) 2205*12890SJoyce.McIntosh@Sun.COM return (B_FALSE); 2206*12890SJoyce.McIntosh@Sun.COM 2207*12890SJoyce.McIntosh@Sun.COM splist = &sv->sp_info.sp_list; 2208*12890SJoyce.McIntosh@Sun.COM smb_llist_enter(splist, RW_WRITER); 2209*12890SJoyce.McIntosh@Sun.COM sp = smb_llist_head(splist); 2210*12890SJoyce.McIntosh@Sun.COM while (sp != NULL) { 2211*12890SJoyce.McIntosh@Sun.COM /* 2212*12890SJoyce.McIntosh@Sun.COM * check for a matching fid 2213*12890SJoyce.McIntosh@Sun.COM */ 2214*12890SJoyce.McIntosh@Sun.COM if (sp->sd_fid == fid) { 2215*12890SJoyce.McIntosh@Sun.COM *spdoc = *sp; 2216*12890SJoyce.McIntosh@Sun.COM smb_llist_remove(splist, sp); 2217*12890SJoyce.McIntosh@Sun.COM smb_llist_exit(splist); 2218*12890SJoyce.McIntosh@Sun.COM kmem_free(sp, sizeof (smb_kspooldoc_t)); 2219*12890SJoyce.McIntosh@Sun.COM smb_server_release(sv); 2220*12890SJoyce.McIntosh@Sun.COM return (B_TRUE); 2221*12890SJoyce.McIntosh@Sun.COM } 2222*12890SJoyce.McIntosh@Sun.COM sp = smb_llist_next(splist, sp); 2223*12890SJoyce.McIntosh@Sun.COM } 2224*12890SJoyce.McIntosh@Sun.COM cmn_err(CE_WARN, "smb_spool_lookup_user_byfid: no fid:%d", fid); 2225*12890SJoyce.McIntosh@Sun.COM smb_llist_exit(splist); 2226*12890SJoyce.McIntosh@Sun.COM smb_server_release(sv); 2227*12890SJoyce.McIntosh@Sun.COM return (B_FALSE); 2228*12890SJoyce.McIntosh@Sun.COM } 2229*12890SJoyce.McIntosh@Sun.COM 2230*12890SJoyce.McIntosh@Sun.COM /* 2231*12890SJoyce.McIntosh@Sun.COM * Adds the spool fid to a linked list to be used 2232*12890SJoyce.McIntosh@Sun.COM * as a search key in the spooldoc queue 2233*12890SJoyce.McIntosh@Sun.COM * 2234*12890SJoyce.McIntosh@Sun.COM * Return values 2235*12890SJoyce.McIntosh@Sun.COM * rc non-zero error 2236*12890SJoyce.McIntosh@Sun.COM * rc zero success 2237*12890SJoyce.McIntosh@Sun.COM * 2238*12890SJoyce.McIntosh@Sun.COM */ 2239*12890SJoyce.McIntosh@Sun.COM 2240*12890SJoyce.McIntosh@Sun.COM int 2241*12890SJoyce.McIntosh@Sun.COM smb_spool_add_fid(uint16_t fid) 2242*12890SJoyce.McIntosh@Sun.COM { 2243*12890SJoyce.McIntosh@Sun.COM smb_llist_t *fidlist; 2244*12890SJoyce.McIntosh@Sun.COM smb_server_t *sv; 2245*12890SJoyce.McIntosh@Sun.COM smb_spoolfid_t *sf; 2246*12890SJoyce.McIntosh@Sun.COM int rc = 0; 2247*12890SJoyce.McIntosh@Sun.COM 2248*12890SJoyce.McIntosh@Sun.COM rc = smb_server_lookup(&sv); 2249*12890SJoyce.McIntosh@Sun.COM if (rc) 2250*12890SJoyce.McIntosh@Sun.COM return (rc); 2251*12890SJoyce.McIntosh@Sun.COM 2252*12890SJoyce.McIntosh@Sun.COM sf = kmem_zalloc(sizeof (smb_spoolfid_t), KM_SLEEP); 2253*12890SJoyce.McIntosh@Sun.COM fidlist = &sv->sp_info.sp_fidlist; 2254*12890SJoyce.McIntosh@Sun.COM smb_llist_enter(fidlist, RW_WRITER); 2255*12890SJoyce.McIntosh@Sun.COM sf->sf_fid = fid; 2256*12890SJoyce.McIntosh@Sun.COM smb_llist_insert_tail(fidlist, sf); 2257*12890SJoyce.McIntosh@Sun.COM smb_llist_exit(fidlist); 2258*12890SJoyce.McIntosh@Sun.COM smb_server_release(sv); 2259*12890SJoyce.McIntosh@Sun.COM return (rc); 2260*12890SJoyce.McIntosh@Sun.COM } 2261*12890SJoyce.McIntosh@Sun.COM 2262*12890SJoyce.McIntosh@Sun.COM /* 2263*12890SJoyce.McIntosh@Sun.COM * Called by the ioctl to get and remove the head of the fid list 2264*12890SJoyce.McIntosh@Sun.COM * 2265*12890SJoyce.McIntosh@Sun.COM * Return values 2266*12890SJoyce.McIntosh@Sun.COM * int fd 2267*12890SJoyce.McIntosh@Sun.COM * greater than 0 success 2268*12890SJoyce.McIntosh@Sun.COM * 0 - error 2269*12890SJoyce.McIntosh@Sun.COM * 2270*12890SJoyce.McIntosh@Sun.COM */ 2271*12890SJoyce.McIntosh@Sun.COM 2272*12890SJoyce.McIntosh@Sun.COM uint16_t 2273*12890SJoyce.McIntosh@Sun.COM smb_spool_get_fid() 2274*12890SJoyce.McIntosh@Sun.COM { 2275*12890SJoyce.McIntosh@Sun.COM smb_spoolfid_t *spfid; 2276*12890SJoyce.McIntosh@Sun.COM smb_llist_t *splist; 2277*12890SJoyce.McIntosh@Sun.COM smb_server_t *sv; 2278*12890SJoyce.McIntosh@Sun.COM int rc = 0; 2279*12890SJoyce.McIntosh@Sun.COM uint16_t fid; 2280*12890SJoyce.McIntosh@Sun.COM 2281*12890SJoyce.McIntosh@Sun.COM rc = smb_server_lookup(&sv); 2282*12890SJoyce.McIntosh@Sun.COM if (rc) 2283*12890SJoyce.McIntosh@Sun.COM return (0); 2284*12890SJoyce.McIntosh@Sun.COM 2285*12890SJoyce.McIntosh@Sun.COM splist = &sv->sp_info.sp_fidlist; 2286*12890SJoyce.McIntosh@Sun.COM smb_llist_enter(splist, RW_WRITER); 2287*12890SJoyce.McIntosh@Sun.COM spfid = smb_llist_head(splist); 2288*12890SJoyce.McIntosh@Sun.COM if (spfid != NULL) { 2289*12890SJoyce.McIntosh@Sun.COM fid = spfid->sf_fid; 2290*12890SJoyce.McIntosh@Sun.COM smb_llist_remove(&sv->sp_info.sp_fidlist, spfid); 2291*12890SJoyce.McIntosh@Sun.COM kmem_free(spfid, sizeof (smb_spoolfid_t)); 2292*12890SJoyce.McIntosh@Sun.COM } else { 2293*12890SJoyce.McIntosh@Sun.COM fid = 0; 2294*12890SJoyce.McIntosh@Sun.COM } 2295*12890SJoyce.McIntosh@Sun.COM smb_llist_exit(splist); 2296*12890SJoyce.McIntosh@Sun.COM smb_server_release(sv); 2297*12890SJoyce.McIntosh@Sun.COM return (fid); 2298*12890SJoyce.McIntosh@Sun.COM } 2299*12890SJoyce.McIntosh@Sun.COM 2300*12890SJoyce.McIntosh@Sun.COM /* 2301*12890SJoyce.McIntosh@Sun.COM * Adds the spooldoc to the tail of the spooldoc list 2302*12890SJoyce.McIntosh@Sun.COM * 2303*12890SJoyce.McIntosh@Sun.COM * Return values 2304*12890SJoyce.McIntosh@Sun.COM * rc non-zero error 2305*12890SJoyce.McIntosh@Sun.COM * rc zero success 2306*12890SJoyce.McIntosh@Sun.COM */ 2307*12890SJoyce.McIntosh@Sun.COM int 2308*12890SJoyce.McIntosh@Sun.COM smb_spool_add_doc(smb_kspooldoc_t *sp) 2309*12890SJoyce.McIntosh@Sun.COM { 2310*12890SJoyce.McIntosh@Sun.COM smb_llist_t *splist; 2311*12890SJoyce.McIntosh@Sun.COM smb_server_t *sv; 2312*12890SJoyce.McIntosh@Sun.COM int rc = 0; 2313*12890SJoyce.McIntosh@Sun.COM 2314*12890SJoyce.McIntosh@Sun.COM rc = smb_server_lookup(&sv); 2315*12890SJoyce.McIntosh@Sun.COM if (rc) 2316*12890SJoyce.McIntosh@Sun.COM return (rc); 2317*12890SJoyce.McIntosh@Sun.COM 2318*12890SJoyce.McIntosh@Sun.COM splist = &sv->sp_info.sp_list; 2319*12890SJoyce.McIntosh@Sun.COM smb_llist_enter(splist, RW_WRITER); 2320*12890SJoyce.McIntosh@Sun.COM sp->sd_spool_num = sv->sp_info.sp_cnt; 2321*12890SJoyce.McIntosh@Sun.COM smb_llist_insert_tail(splist, sp); 2322*12890SJoyce.McIntosh@Sun.COM smb_llist_exit(splist); 2323*12890SJoyce.McIntosh@Sun.COM smb_server_release(sv); 2324*12890SJoyce.McIntosh@Sun.COM return (rc); 2325*12890SJoyce.McIntosh@Sun.COM } 2326