1faa1795aSjb150015 /* 2faa1795aSjb150015 * CDDL HEADER START 3faa1795aSjb150015 * 4faa1795aSjb150015 * The contents of this file are subject to the terms of the 5faa1795aSjb150015 * Common Development and Distribution License (the "License"). 6faa1795aSjb150015 * You may not use this file except in compliance with the License. 7faa1795aSjb150015 * 8faa1795aSjb150015 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9faa1795aSjb150015 * or http://www.opensolaris.org/os/licensing. 10faa1795aSjb150015 * See the License for the specific language governing permissions 11faa1795aSjb150015 * and limitations under the License. 12faa1795aSjb150015 * 13faa1795aSjb150015 * When distributing Covered Code, include this CDDL HEADER in each 14faa1795aSjb150015 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15faa1795aSjb150015 * If applicable, add the following below this CDDL HEADER, with the 16faa1795aSjb150015 * fields enclosed by brackets "[]" replaced with your own identifying 17faa1795aSjb150015 * information: Portions Copyright [yyyy] [name of copyright owner] 18faa1795aSjb150015 * 19faa1795aSjb150015 * CDDL HEADER END 20faa1795aSjb150015 */ 21faa1795aSjb150015 /* 22c5866007SKeyur Desai * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved. 23adc68ba9SPavel Zakharov * Copyright (c) 2017 by Delphix. All rights reserved. 24896d9552SGordon Ross * Copyright 2019 Nexenta by DDN, Inc. All rights reserved. 255d8538b6SGordon Ross * Copyright 2021-2023 RackTop Systems, Inc. 26faa1795aSjb150015 */ 27faa1795aSjb150015 28faa1795aSjb150015 /* 29faa1795aSjb150015 * General Structures Layout 30faa1795aSjb150015 * ------------------------- 31faa1795aSjb150015 * 32faa1795aSjb150015 * This is a simplified diagram showing the relationship between most of the 33faa1795aSjb150015 * main structures. 34faa1795aSjb150015 * 35faa1795aSjb150015 * +-------------------+ 36faa1795aSjb150015 * | SMB_SERVER | 37faa1795aSjb150015 * +-------------------+ 38faa1795aSjb150015 * | 39faa1795aSjb150015 * | 40faa1795aSjb150015 * v 41faa1795aSjb150015 * +-------------------+ +-------------------+ +-------------------+ 42faa1795aSjb150015 * | SESSION |<----->| SESSION |......| SESSION | 43faa1795aSjb150015 * +-------------------+ +-------------------+ +-------------------+ 44faa1795aSjb150015 * | 45faa1795aSjb150015 * | 46faa1795aSjb150015 * v 47faa1795aSjb150015 * +-------------------+ +-------------------+ +-------------------+ 48faa1795aSjb150015 * | USER |<----->| USER |......| USER | 49faa1795aSjb150015 * +-------------------+ +-------------------+ +-------------------+ 50faa1795aSjb150015 * | 51faa1795aSjb150015 * | 52faa1795aSjb150015 * v 53faa1795aSjb150015 * +-------------------+ +-------------------+ +-------------------+ 54faa1795aSjb150015 * | TREE |<----->| TREE |......| TREE | 55faa1795aSjb150015 * +-------------------+ +-------------------+ +-------------------+ 56faa1795aSjb150015 * | | 57faa1795aSjb150015 * | | 58faa1795aSjb150015 * | v 59faa1795aSjb150015 * | +-------+ +-------+ +-------+ 60faa1795aSjb150015 * | | OFILE |<----->| OFILE |......| OFILE | 61faa1795aSjb150015 * | +-------+ +-------+ +-------+ 62faa1795aSjb150015 * | 63faa1795aSjb150015 * | 64faa1795aSjb150015 * v 65faa1795aSjb150015 * +-------+ +------+ +------+ 66faa1795aSjb150015 * | ODIR |<----->| ODIR |......| ODIR | 67faa1795aSjb150015 * +-------+ +------+ +------+ 68faa1795aSjb150015 * 69faa1795aSjb150015 * 70faa1795aSjb150015 * Module Interface Overview 71faa1795aSjb150015 * ------------------------- 72faa1795aSjb150015 * 73faa1795aSjb150015 * 74faa1795aSjb150015 * +===================================+ 75faa1795aSjb150015 * | smbd daemon | 76faa1795aSjb150015 * +===================================+ 77faa1795aSjb150015 * | | ^ 78faa1795aSjb150015 * | | | 79faa1795aSjb150015 * User | | | 80faa1795aSjb150015 * -----------|--------------|----------------|-------------------------------- 81faa1795aSjb150015 * Kernel | | | 82faa1795aSjb150015 * | | | 83faa1795aSjb150015 * | | | 84faa1795aSjb150015 * +=========|==============|================|=================+ 85faa1795aSjb150015 * | v v | | 86faa1795aSjb150015 * | +-----------+ +--------------------+ +------------------+ | 87faa1795aSjb150015 * | | IO | | Kernel Door Server | | User Door Servers| | 88faa1795aSjb150015 * | | Interface | | Interface | | Interface | | 89faa1795aSjb150015 * | +-----------+ +--------------------+ +------------------+ | 90faa1795aSjb150015 * | | | ^ ^ | 91faa1795aSjb150015 * | v v | | | +=========+ 92faa1795aSjb150015 * | +-----------------------------------+ | | | | 93faa1795aSjb150015 * | + SMB Server Management (this file) |<------------------| ZFS | 94faa1795aSjb150015 * | +-----------------------------------+ | | | | 95faa1795aSjb150015 * | | | | Module | 96faa1795aSjb150015 * | +-----------------------------------+ | | | | 97faa1795aSjb150015 * | + SMB Server Internal Layers |------+ | +=========+ 98faa1795aSjb150015 * | +-----------------------------------+ | 99faa1795aSjb150015 * | | 100faa1795aSjb150015 * | | 101faa1795aSjb150015 * +===========================================================+ 102faa1795aSjb150015 * 103faa1795aSjb150015 * 104faa1795aSjb150015 * Server State Machine 105faa1795aSjb150015 * -------------------- 106faa1795aSjb150015 * | 107faa1795aSjb150015 * | T0 108faa1795aSjb150015 * | 109faa1795aSjb150015 * v 110faa1795aSjb150015 * +-----------------------------+ 111faa1795aSjb150015 * | SMB_SERVER_STATE_CREATED | 112faa1795aSjb150015 * +-----------------------------+ 113faa1795aSjb150015 * | 114faa1795aSjb150015 * | T1 115faa1795aSjb150015 * | 116faa1795aSjb150015 * v 117faa1795aSjb150015 * +-----------------------------+ 118faa1795aSjb150015 * | SMB_SERVER_STATE_CONFIGURED | 119faa1795aSjb150015 * +-----------------------------+ 120faa1795aSjb150015 * | 121faa1795aSjb150015 * | T2 122faa1795aSjb150015 * | 123faa1795aSjb150015 * v 124faa1795aSjb150015 * +-----------------------------+ 1259fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States * | SMB_SERVER_STATE_RUNNING / | 1269fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States * | SMB_SERVER_STATE_STOPPING | 127faa1795aSjb150015 * +-----------------------------+ 128faa1795aSjb150015 * | 129faa1795aSjb150015 * | T3 130faa1795aSjb150015 * | 131faa1795aSjb150015 * v 132faa1795aSjb150015 * +-----------------------------+ 133faa1795aSjb150015 * | SMB_SERVER_STATE_DELETING | 134faa1795aSjb150015 * +-----------------------------+ 135faa1795aSjb150015 * | 136faa1795aSjb150015 * | 137faa1795aSjb150015 * | 138faa1795aSjb150015 * v 139faa1795aSjb150015 * 140faa1795aSjb150015 * States 141faa1795aSjb150015 * ------ 142faa1795aSjb150015 * 143faa1795aSjb150015 * SMB_SERVER_STATE_CREATED 144faa1795aSjb150015 * 145faa1795aSjb150015 * This is the state of the server just after creation. 146faa1795aSjb150015 * 147faa1795aSjb150015 * SMB_SERVER_STATE_CONFIGURED 148faa1795aSjb150015 * 149faa1795aSjb150015 * The server has been configured. 150faa1795aSjb150015 * 151faa1795aSjb150015 * SMB_SERVER_STATE_RUNNING 152faa1795aSjb150015 * 153faa1795aSjb150015 * The server has been started. While in this state the threads listening on 1544163af6aSjose borrego * the sockets are started. 155faa1795aSjb150015 * 1564163af6aSjose borrego * When a client establishes a connection the thread listening dispatches 1574163af6aSjose borrego * a task with the new session as an argument. If the dispatch fails the new 1584163af6aSjose borrego * session context is destroyed. 159faa1795aSjb150015 * 160faa1795aSjb150015 * SMB_SERVER_STATE_STOPPING 161faa1795aSjb150015 * 162faa1795aSjb150015 * The threads listening on the NBT and TCP sockets are being terminated. 163faa1795aSjb150015 * 164faa1795aSjb150015 * 165faa1795aSjb150015 * Transitions 166faa1795aSjb150015 * ----------- 167faa1795aSjb150015 * 168faa1795aSjb150015 * Transition T0 169faa1795aSjb150015 * 170faa1795aSjb150015 * The daemon smbd triggers its creation by opening the smbsrv device. If 171faa1795aSjb150015 * the zone where the daemon lives doesn't have an smb server yet it is 172faa1795aSjb150015 * created. 173faa1795aSjb150015 * 174faa1795aSjb150015 * smb_drv_open() --> smb_server_create() 175faa1795aSjb150015 * 176faa1795aSjb150015 * Transition T1 177faa1795aSjb150015 * 178faa1795aSjb150015 * This transition occurs in smb_server_configure(). It is triggered by the 179faa1795aSjb150015 * daemon through an Ioctl. 180faa1795aSjb150015 * 181faa1795aSjb150015 * smb_drv_ioctl(SMB_IOC_CONFIG) --> smb_server_configure() 182faa1795aSjb150015 * 183faa1795aSjb150015 * Transition T2 184faa1795aSjb150015 * 185faa1795aSjb150015 * This transition occurs in smb_server_start(). It is triggered by the 186faa1795aSjb150015 * daemon through an Ioctl. 187faa1795aSjb150015 * 188faa1795aSjb150015 * smb_drv_ioctl(SMB_IOC_START) --> smb_server_start() 189faa1795aSjb150015 * 190faa1795aSjb150015 * Transition T3 191faa1795aSjb150015 * 192faa1795aSjb150015 * This transition occurs in smb_server_delete(). It is triggered by the 193faa1795aSjb150015 * daemon when closing the smbsrv device 194faa1795aSjb150015 * 195faa1795aSjb150015 * smb_drv_close() --> smb_server_delete() 196faa1795aSjb150015 * 197faa1795aSjb150015 * Comments 198faa1795aSjb150015 * -------- 199faa1795aSjb150015 * 200faa1795aSjb150015 * This files assumes that there will one SMB server per zone. For now the 201faa1795aSjb150015 * smb server works only in global zone. There's nothing in this file preventing 202faa1795aSjb150015 * an smb server from being created in a non global zone. That limitation is 203faa1795aSjb150015 * enforced in user space. 204faa1795aSjb150015 */ 205faa1795aSjb150015 206faa1795aSjb150015 #include <sys/cmn_err.h> 207faa1795aSjb150015 #include <sys/priv.h> 208faa1795aSjb150015 #include <sys/zone.h> 2095d8538b6SGordon Ross #include <sys/sysmacros.h> 2105d8538b6SGordon Ross #include <sys/callb.h> 2115d8538b6SGordon Ross #include <sys/class.h> 2125d8538b6SGordon Ross #include <sys/disp.h> 213bbf6f00cSJordan Brown #include <netinet/in.h> 214bbf6f00cSJordan Brown #include <netinet/in_systm.h> 215bbf6f00cSJordan Brown #include <netinet/ip.h> 216bbf6f00cSJordan Brown #include <netinet/ip_icmp.h> 217bbf6f00cSJordan Brown #include <netinet/ip_var.h> 218bbf6f00cSJordan Brown #include <netinet/tcp.h> 219a90cf9f2SGordon Ross #include <smbsrv/smb2_kproto.h> 220bbf6f00cSJordan Brown #include <smbsrv/string.h> 221faa1795aSjb150015 #include <smbsrv/netbios.h> 222faa1795aSjb150015 #include <smbsrv/smb_fsops.h> 2233db3f65cSamw #include <smbsrv/smb_share.h> 2249fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States #include <smbsrv/smb_door.h> 2256537f381Sas200622 #include <smbsrv/smb_kstat.h> 226faa1795aSjb150015 227148c5f43SAlan Wright static void smb_server_kstat_init(smb_server_t *); 228faa1795aSjb150015 static void smb_server_kstat_fini(smb_server_t *); 229faa1795aSjb150015 static void smb_server_timers(smb_thread_t *, void *); 23029bd2886SAlan Wright static void smb_server_store_cfg(smb_server_t *, smb_ioc_cfg_t *); 2319fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States static void smb_server_shutdown(smb_server_t *); 232faa1795aSjb150015 static int smb_server_fsop_start(smb_server_t *); 233faa1795aSjb150015 static void smb_server_fsop_stop(smb_server_t *); 2349fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States static void smb_event_cancel(smb_server_t *, uint32_t); 2359fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States static uint32_t smb_event_alloc_txid(void); 236faa1795aSjb150015 2378d94f651SGordon Ross static void smb_server_disconnect_share(smb_server_t *, const char *); 2388d94f651SGordon Ross static void smb_server_enum_users(smb_server_t *, smb_svcenum_t *); 2398d94f651SGordon Ross static void smb_server_enum_trees(smb_server_t *, smb_svcenum_t *); 2408d94f651SGordon Ross static int smb_server_session_disconnect(smb_server_t *, const char *, 2411fcced4cSJordan Brown const char *); 2428d94f651SGordon Ross static int smb_server_fclose(smb_server_t *, uint32_t); 243148c5f43SAlan Wright static int smb_server_kstat_update(kstat_t *, int); 244cb174861Sjoyce mcintosh static int smb_server_legacy_kstat_update(kstat_t *, int); 2454163af6aSjose borrego static void smb_server_listener_init(smb_server_t *, smb_listener_daemon_t *, 2464163af6aSjose borrego char *, in_port_t, int); 2474163af6aSjose borrego static void smb_server_listener_destroy(smb_listener_daemon_t *); 2484163af6aSjose borrego static int smb_server_listener_start(smb_listener_daemon_t *); 2494163af6aSjose borrego static void smb_server_listener_stop(smb_listener_daemon_t *); 2504163af6aSjose borrego static void smb_server_listener(smb_thread_t *, void *); 2514163af6aSjose borrego static void smb_server_receiver(void *); 2524163af6aSjose borrego static void smb_server_create_session(smb_listener_daemon_t *, ksocket_t); 253811599a4SMatt Barden static void smb_server_destroy_session(smb_session_t *); 25423a9c295SGordon Ross static uint16_t smb_spool_get_fid(smb_server_t *); 25523a9c295SGordon Ross static boolean_t smb_spool_lookup_doc_byfid(smb_server_t *, uint16_t, 25623a9c295SGordon Ross smb_kspooldoc_t *); 2571fcced4cSJordan Brown 2585d8538b6SGordon Ross #ifdef _KERNEL 2595d8538b6SGordon Ross int smb_create_process = 1; 2605d8538b6SGordon Ross static void smb_server_delproc(smb_server_t *); 2615d8538b6SGordon Ross static int smb_server_newproc(smb_server_t *); 2625d8538b6SGordon Ross static void smb_server_proc_main(void *); 2635d8538b6SGordon Ross #endif 2645d8538b6SGordon Ross 265811599a4SMatt Barden /* 266811599a4SMatt Barden * How many "buckets" should our hash tables use? On a "real" server, 267811599a4SMatt Barden * make them much larger than the number of CPUs we're likely to have. 268811599a4SMatt Barden * On "fksmbd" make it smaller so dtrace logs are shorter. 269811599a4SMatt Barden * These must be powers of two. 270811599a4SMatt Barden */ 271811599a4SMatt Barden #ifdef _KERNEL 272811599a4SMatt Barden #define DEFAULT_HASH_NBUCKETS 256 /* real server */ 273811599a4SMatt Barden #else 274811599a4SMatt Barden #define DEFAULT_HASH_NBUCKETS 16 /* for "fksmbd" */ 275811599a4SMatt Barden #endif 276811599a4SMatt Barden uint32_t SMB_OFILE_HASH_NBUCKETS = DEFAULT_HASH_NBUCKETS; 277811599a4SMatt Barden uint32_t SMB_LEASE_HASH_NBUCKETS = DEFAULT_HASH_NBUCKETS; 278811599a4SMatt Barden 2799fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States int smb_event_debug = 0; 2809fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 281faa1795aSjb150015 static smb_llist_t smb_servers; 282faa1795aSjb150015 2837f5d80fdSGordon Ross /* for smb_server_destroy_session() */ 2847f5d80fdSGordon Ross static smb_llist_t smb_server_session_zombies; 2857f5d80fdSGordon Ross 2868622ec45SGordon Ross kmem_cache_t *smb_cache_request; 2878622ec45SGordon Ross kmem_cache_t *smb_cache_session; 2888622ec45SGordon Ross kmem_cache_t *smb_cache_user; 2898622ec45SGordon Ross kmem_cache_t *smb_cache_tree; 2908622ec45SGordon Ross kmem_cache_t *smb_cache_ofile; 2918622ec45SGordon Ross kmem_cache_t *smb_cache_odir; 2928622ec45SGordon Ross kmem_cache_t *smb_cache_opipe; 2938622ec45SGordon Ross kmem_cache_t *smb_cache_event; 2940897f7fbSGordon Ross kmem_cache_t *smb_cache_lock; 2958622ec45SGordon Ross 296faa1795aSjb150015 /* 297faa1795aSjb150015 * ***************************************************************************** 298faa1795aSjb150015 * **************** Functions called from the device interface ***************** 299faa1795aSjb150015 * ***************************************************************************** 300faa1795aSjb150015 * 3011fcced4cSJordan Brown * These functions typically have to determine the relevant smb server 3021fcced4cSJordan Brown * to which the call applies. 303faa1795aSjb150015 */ 304faa1795aSjb150015 305faa1795aSjb150015 /* 306a90cf9f2SGordon Ross * How many zones have an SMB server active? 307a90cf9f2SGordon Ross */ 308a90cf9f2SGordon Ross int 309a90cf9f2SGordon Ross smb_server_get_count(void) 310a90cf9f2SGordon Ross { 311a90cf9f2SGordon Ross return (smb_llist_get_count(&smb_servers)); 312a90cf9f2SGordon Ross } 313a90cf9f2SGordon Ross 314a90cf9f2SGordon Ross /* 3158622ec45SGordon Ross * smb_server_g_init 316faa1795aSjb150015 * 317c8ec8eeaSjose borrego * This function must be called from smb_drv_attach(). 318faa1795aSjb150015 */ 319faa1795aSjb150015 int 3208622ec45SGordon Ross smb_server_g_init(void) 321faa1795aSjb150015 { 3228622ec45SGordon Ross int rc; 323faa1795aSjb150015 3248622ec45SGordon Ross if ((rc = smb_vop_init()) != 0) 3258622ec45SGordon Ross goto errout; 3268622ec45SGordon Ross if ((rc = smb_fem_init()) != 0) 3278622ec45SGordon Ross goto errout; 3288622ec45SGordon Ross 3298622ec45SGordon Ross smb_kshare_g_init(); 3308622ec45SGordon Ross smb_codepage_init(); 3318622ec45SGordon Ross smb_mbc_init(); /* smb_mbc_cache */ 3328622ec45SGordon Ross smb_node_init(); /* smb_node_cache, lists */ 33394047d49SGordon Ross smb2_lease_init(); 3348622ec45SGordon Ross 3358622ec45SGordon Ross smb_cache_request = kmem_cache_create("smb_request_cache", 3368622ec45SGordon Ross sizeof (smb_request_t), 8, NULL, NULL, NULL, NULL, NULL, 0); 3378622ec45SGordon Ross smb_cache_session = kmem_cache_create("smb_session_cache", 3388622ec45SGordon Ross sizeof (smb_session_t), 8, NULL, NULL, NULL, NULL, NULL, 0); 3398622ec45SGordon Ross smb_cache_user = kmem_cache_create("smb_user_cache", 3408622ec45SGordon Ross sizeof (smb_user_t), 8, NULL, NULL, NULL, NULL, NULL, 0); 3418622ec45SGordon Ross smb_cache_tree = kmem_cache_create("smb_tree_cache", 3428622ec45SGordon Ross sizeof (smb_tree_t), 8, NULL, NULL, NULL, NULL, NULL, 0); 3438622ec45SGordon Ross smb_cache_ofile = kmem_cache_create("smb_ofile_cache", 3448622ec45SGordon Ross sizeof (smb_ofile_t), 8, NULL, NULL, NULL, NULL, NULL, 0); 3458622ec45SGordon Ross smb_cache_odir = kmem_cache_create("smb_odir_cache", 3468622ec45SGordon Ross sizeof (smb_odir_t), 8, NULL, NULL, NULL, NULL, NULL, 0); 3478622ec45SGordon Ross smb_cache_opipe = kmem_cache_create("smb_opipe_cache", 3488622ec45SGordon Ross sizeof (smb_opipe_t), 8, NULL, NULL, NULL, NULL, NULL, 0); 3498622ec45SGordon Ross smb_cache_event = kmem_cache_create("smb_event_cache", 3508622ec45SGordon Ross sizeof (smb_event_t), 8, NULL, NULL, NULL, NULL, NULL, 0); 3510897f7fbSGordon Ross smb_cache_lock = kmem_cache_create("smb_lock_cache", 3520897f7fbSGordon Ross sizeof (smb_lock_t), 8, NULL, NULL, NULL, NULL, NULL, 0); 3538622ec45SGordon Ross 3549fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States smb_llist_init(); 355faa1795aSjb150015 smb_llist_constructor(&smb_servers, sizeof (smb_server_t), 356faa1795aSjb150015 offsetof(smb_server_t, sv_lnd)); 3579fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 3587f5d80fdSGordon Ross smb_llist_constructor(&smb_server_session_zombies, 3597f5d80fdSGordon Ross sizeof (smb_session_t), offsetof(smb_session_t, s_lnd)); 3607f5d80fdSGordon Ross 3618622ec45SGordon Ross return (0); 3628622ec45SGordon Ross 3638622ec45SGordon Ross errout: 364faa1795aSjb150015 smb_fem_fini(); 365faa1795aSjb150015 smb_vop_fini(); 366faa1795aSjb150015 return (rc); 367faa1795aSjb150015 } 368faa1795aSjb150015 369faa1795aSjb150015 /* 3708622ec45SGordon Ross * smb_server_g_fini 371faa1795aSjb150015 * 372faa1795aSjb150015 * This function must called from smb_drv_detach(). It will fail if servers 373faa1795aSjb150015 * still exist. 374faa1795aSjb150015 */ 375a90cf9f2SGordon Ross void 3768622ec45SGordon Ross smb_server_g_fini(void) 377faa1795aSjb150015 { 378faa1795aSjb150015 379a90cf9f2SGordon Ross ASSERT(smb_llist_get_count(&smb_servers) == 0); 380a90cf9f2SGordon Ross 3819fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States smb_llist_fini(); 3828622ec45SGordon Ross 3838622ec45SGordon Ross kmem_cache_destroy(smb_cache_request); 3848622ec45SGordon Ross kmem_cache_destroy(smb_cache_session); 3858622ec45SGordon Ross kmem_cache_destroy(smb_cache_user); 3868622ec45SGordon Ross kmem_cache_destroy(smb_cache_tree); 3878622ec45SGordon Ross kmem_cache_destroy(smb_cache_ofile); 3888622ec45SGordon Ross kmem_cache_destroy(smb_cache_odir); 3898622ec45SGordon Ross kmem_cache_destroy(smb_cache_opipe); 3908622ec45SGordon Ross kmem_cache_destroy(smb_cache_event); 3910897f7fbSGordon Ross kmem_cache_destroy(smb_cache_lock); 3928622ec45SGordon Ross 39394047d49SGordon Ross smb2_lease_fini(); 394faa1795aSjb150015 smb_node_fini(); 3952c2961f8Sjose borrego smb_mbc_fini(); 396adc68ba9SPavel Zakharov smb_codepage_fini(); 3978622ec45SGordon Ross smb_kshare_g_fini(); 3988622ec45SGordon Ross 3998622ec45SGordon Ross smb_fem_fini(); 4008622ec45SGordon Ross smb_vop_fini(); 4018622ec45SGordon Ross 402faa1795aSjb150015 smb_llist_destructor(&smb_servers); 403faa1795aSjb150015 } 404faa1795aSjb150015 405faa1795aSjb150015 /* 406faa1795aSjb150015 * smb_server_create 407faa1795aSjb150015 * 4085d8538b6SGordon Ross * Called by driver open 4095d8538b6SGordon Ross * 410faa1795aSjb150015 * This function will fail if there's already a server associated with the 411faa1795aSjb150015 * caller's zone. 4125d8538b6SGordon Ross * 4135d8538b6SGordon Ross * This object is one-to-one with zones, so we could instead 4145d8538b6SGordon Ross * create/destroy this via zone_key_create callbacks. 4155d8538b6SGordon Ross * See smb_server_delete() for destruction. 416faa1795aSjb150015 */ 417faa1795aSjb150015 int 418faa1795aSjb150015 smb_server_create(void) 419faa1795aSjb150015 { 420faa1795aSjb150015 zoneid_t zid; 421faa1795aSjb150015 smb_server_t *sv; 422faa1795aSjb150015 423faa1795aSjb150015 zid = getzoneid(); 424faa1795aSjb150015 425faa1795aSjb150015 smb_llist_enter(&smb_servers, RW_WRITER); 426faa1795aSjb150015 sv = smb_llist_head(&smb_servers); 427faa1795aSjb150015 while (sv) { 4289fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States SMB_SERVER_VALID(sv); 429faa1795aSjb150015 if (sv->sv_zid == zid) { 430faa1795aSjb150015 smb_llist_exit(&smb_servers); 43194fff790SAlan Wright return (EPERM); 432faa1795aSjb150015 } 433faa1795aSjb150015 sv = smb_llist_next(&smb_servers, sv); 434faa1795aSjb150015 } 435faa1795aSjb150015 4368622ec45SGordon Ross sv = kmem_zalloc(sizeof (smb_server_t), KM_SLEEP); 4378622ec45SGordon Ross 4388622ec45SGordon Ross sv->sv_magic = SMB_SERVER_MAGIC; 4398622ec45SGordon Ross sv->sv_state = SMB_SERVER_STATE_CREATED; 4408622ec45SGordon Ross sv->sv_zid = zid; 441b819cea2SGordon Ross sv->sv_pid = ddi_get_pid(); 4425d8538b6SGordon Ross sv->sv_proc_state = SMB_THREAD_STATE_EXITED; 4438622ec45SGordon Ross 4448622ec45SGordon Ross mutex_init(&sv->sv_mutex, NULL, MUTEX_DEFAULT, NULL); 4458622ec45SGordon Ross cv_init(&sv->sv_cv, NULL, CV_DEFAULT, NULL); 4468622ec45SGordon Ross cv_init(&sv->sp_info.sp_cv, NULL, CV_DEFAULT, NULL); 447faa1795aSjb150015 448811599a4SMatt Barden sv->sv_persistid_ht = smb_hash_create(sizeof (smb_ofile_t), 449811599a4SMatt Barden offsetof(smb_ofile_t, f_dh_lnd), SMB_OFILE_HASH_NBUCKETS); 450811599a4SMatt Barden 45194047d49SGordon Ross sv->sv_lease_ht = smb_hash_create(sizeof (smb_lease_t), 45294047d49SGordon Ross offsetof(smb_lease_t, ls_lnd), SMB_LEASE_HASH_NBUCKETS); 45394047d49SGordon Ross 454811599a4SMatt Barden smb_llist_constructor(&sv->sv_session_list, sizeof (smb_session_t), 455811599a4SMatt Barden offsetof(smb_session_t, s_lnd)); 456811599a4SMatt Barden 4579fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States smb_llist_constructor(&sv->sv_event_list, sizeof (smb_event_t), 4589fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States offsetof(smb_event_t, se_lnd)); 4599fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 460cb174861Sjoyce mcintosh smb_llist_constructor(&sv->sp_info.sp_list, sizeof (smb_kspooldoc_t), 461cb174861Sjoyce mcintosh offsetof(smb_kspooldoc_t, sd_lnd)); 462cb174861Sjoyce mcintosh 463cb174861Sjoyce mcintosh smb_llist_constructor(&sv->sp_info.sp_fidlist, 464cb174861Sjoyce mcintosh sizeof (smb_spoolfid_t), offsetof(smb_spoolfid_t, sf_lnd)); 465cb174861Sjoyce mcintosh 466a90cf9f2SGordon Ross sv->sv_disp_stats1 = kmem_zalloc(SMB_COM_NUM * 467a90cf9f2SGordon Ross sizeof (smb_disp_stats_t), KM_SLEEP); 468a90cf9f2SGordon Ross 469a90cf9f2SGordon Ross sv->sv_disp_stats2 = kmem_zalloc(SMB2__NCMDS * 4708622ec45SGordon Ross sizeof (smb_disp_stats_t), KM_SLEEP); 471faa1795aSjb150015 47208344b29SGordon Ross smb_thread_init(&sv->si_thread_timers, "smb_timers", 4735d8538b6SGordon Ross smb_server_timers, sv, smbsrv_timer_pri, sv); 474faa1795aSjb150015 475148c5f43SAlan Wright smb_srqueue_init(&sv->sv_srqueue); 476faa1795aSjb150015 4778622ec45SGordon Ross smb_kdoor_init(sv); 4788622ec45SGordon Ross smb_kshare_init(sv); 479148c5f43SAlan Wright smb_server_kstat_init(sv); 480faa1795aSjb150015 481856399cfSGordon Ross smb_threshold_init(&sv->sv_ssetup_ct, SMB_SSETUP_CMD, 482856399cfSGordon Ross smb_ssetup_threshold, smb_ssetup_timeout); 483856399cfSGordon Ross smb_threshold_init(&sv->sv_tcon_ct, SMB_TCON_CMD, 484856399cfSGordon Ross smb_tcon_threshold, smb_tcon_timeout); 485856399cfSGordon Ross smb_threshold_init(&sv->sv_opipe_ct, SMB_OPIPE_CMD, 486856399cfSGordon Ross smb_opipe_threshold, smb_opipe_timeout); 487856399cfSGordon Ross 488faa1795aSjb150015 smb_llist_insert_tail(&smb_servers, sv); 489faa1795aSjb150015 smb_llist_exit(&smb_servers); 490cb174861Sjoyce mcintosh 491faa1795aSjb150015 return (0); 492faa1795aSjb150015 } 493faa1795aSjb150015 494faa1795aSjb150015 /* 495faa1795aSjb150015 * smb_server_delete 496faa1795aSjb150015 * 4975d8538b6SGordon Ross * Called by driver close 4985d8538b6SGordon Ross * 499faa1795aSjb150015 * This function will delete the server passed in. It will make sure that all 500faa1795aSjb150015 * activity associated that server has ceased before destroying it. 501faa1795aSjb150015 */ 502faa1795aSjb150015 int 5038d94f651SGordon Ross smb_server_delete(smb_server_t *sv) 504faa1795aSjb150015 { 505faa1795aSjb150015 506faa1795aSjb150015 mutex_enter(&sv->sv_mutex); 507faa1795aSjb150015 switch (sv->sv_state) { 508faa1795aSjb150015 case SMB_SERVER_STATE_RUNNING: 5099fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States sv->sv_state = SMB_SERVER_STATE_STOPPING; 510faa1795aSjb150015 mutex_exit(&sv->sv_mutex); 5114163af6aSjose borrego smb_server_shutdown(sv); 512faa1795aSjb150015 mutex_enter(&sv->sv_mutex); 5134163af6aSjose borrego cv_broadcast(&sv->sp_info.sp_cv); 5144163af6aSjose borrego sv->sv_state = SMB_SERVER_STATE_DELETING; 5154163af6aSjose borrego break; 5164163af6aSjose borrego case SMB_SERVER_STATE_STOPPING: 5174163af6aSjose borrego sv->sv_state = SMB_SERVER_STATE_DELETING; 518faa1795aSjb150015 break; 519faa1795aSjb150015 case SMB_SERVER_STATE_CONFIGURED: 520faa1795aSjb150015 case SMB_SERVER_STATE_CREATED: 521faa1795aSjb150015 sv->sv_state = SMB_SERVER_STATE_DELETING; 522faa1795aSjb150015 break; 523faa1795aSjb150015 default: 5249fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States SMB_SERVER_STATE_VALID(sv->sv_state); 525faa1795aSjb150015 mutex_exit(&sv->sv_mutex); 526faa1795aSjb150015 smb_server_release(sv); 527faa1795aSjb150015 return (ENOTTY); 528faa1795aSjb150015 } 529faa1795aSjb150015 530faa1795aSjb150015 ASSERT(sv->sv_state == SMB_SERVER_STATE_DELETING); 531faa1795aSjb150015 532faa1795aSjb150015 sv->sv_refcnt--; 533faa1795aSjb150015 while (sv->sv_refcnt) 534faa1795aSjb150015 cv_wait(&sv->sv_cv, &sv->sv_mutex); 535faa1795aSjb150015 536faa1795aSjb150015 mutex_exit(&sv->sv_mutex); 537faa1795aSjb150015 538faa1795aSjb150015 smb_llist_enter(&smb_servers, RW_WRITER); 539faa1795aSjb150015 smb_llist_remove(&smb_servers, sv); 540faa1795aSjb150015 smb_llist_exit(&smb_servers); 541faa1795aSjb150015 542856399cfSGordon Ross smb_threshold_fini(&sv->sv_ssetup_ct); 543856399cfSGordon Ross smb_threshold_fini(&sv->sv_tcon_ct); 544856399cfSGordon Ross smb_threshold_fini(&sv->sv_opipe_ct); 545856399cfSGordon Ross 5464163af6aSjose borrego smb_server_listener_destroy(&sv->sv_nbt_daemon); 5474163af6aSjose borrego smb_server_listener_destroy(&sv->sv_tcp_daemon); 548faa1795aSjb150015 rw_destroy(&sv->sv_cfg_lock); 549faa1795aSjb150015 smb_server_kstat_fini(sv); 5508622ec45SGordon Ross smb_kshare_fini(sv); 5518622ec45SGordon Ross smb_kdoor_fini(sv); 5529fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States smb_llist_destructor(&sv->sv_event_list); 553811599a4SMatt Barden smb_llist_destructor(&sv->sv_session_list); 5542c1b14e5Sjose borrego 555a90cf9f2SGordon Ross kmem_free(sv->sv_disp_stats1, 5568622ec45SGordon Ross SMB_COM_NUM * sizeof (smb_disp_stats_t)); 557faa1795aSjb150015 558a90cf9f2SGordon Ross kmem_free(sv->sv_disp_stats2, 559a90cf9f2SGordon Ross SMB2__NCMDS * sizeof (smb_disp_stats_t)); 560a90cf9f2SGordon Ross 561148c5f43SAlan Wright smb_srqueue_destroy(&sv->sv_srqueue); 562faa1795aSjb150015 smb_thread_destroy(&sv->si_thread_timers); 5638622ec45SGordon Ross 564faa1795aSjb150015 mutex_destroy(&sv->sv_mutex); 56594047d49SGordon Ross smb_hash_destroy(sv->sv_lease_ht); 566811599a4SMatt Barden smb_hash_destroy(sv->sv_persistid_ht); 567faa1795aSjb150015 cv_destroy(&sv->sv_cv); 568faa1795aSjb150015 sv->sv_magic = 0; 569faa1795aSjb150015 kmem_free(sv, sizeof (smb_server_t)); 570faa1795aSjb150015 571faa1795aSjb150015 return (0); 572faa1795aSjb150015 } 573faa1795aSjb150015 574faa1795aSjb150015 /* 575faa1795aSjb150015 * smb_server_configure 5765d8538b6SGordon Ross * 5775d8538b6SGordon Ross * Called via SMB_IOC_CONFIG, for smbd startup or refresh. 578faa1795aSjb150015 */ 579faa1795aSjb150015 int 58029bd2886SAlan Wright smb_server_configure(smb_ioc_cfg_t *ioc) 581faa1795aSjb150015 { 582faa1795aSjb150015 int rc = 0; 583faa1795aSjb150015 smb_server_t *sv; 584faa1795aSjb150015 5851d443a93SDan McDonald /* 5861d443a93SDan McDonald * Reality check negotiation token length vs. #define'd maximum. 5871d443a93SDan McDonald */ 5881d443a93SDan McDonald if (ioc->negtok_len > SMB_PI_MAX_NEGTOK) 5891d443a93SDan McDonald return (EINVAL); 5901d443a93SDan McDonald 591faa1795aSjb150015 rc = smb_server_lookup(&sv); 592faa1795aSjb150015 if (rc) 593faa1795aSjb150015 return (rc); 594faa1795aSjb150015 595faa1795aSjb150015 mutex_enter(&sv->sv_mutex); 596faa1795aSjb150015 switch (sv->sv_state) { 597faa1795aSjb150015 case SMB_SERVER_STATE_CREATED: 59829bd2886SAlan Wright smb_server_store_cfg(sv, ioc); 599faa1795aSjb150015 sv->sv_state = SMB_SERVER_STATE_CONFIGURED; 600faa1795aSjb150015 break; 601faa1795aSjb150015 602faa1795aSjb150015 case SMB_SERVER_STATE_CONFIGURED: 60329bd2886SAlan Wright smb_server_store_cfg(sv, ioc); 604faa1795aSjb150015 break; 605faa1795aSjb150015 606faa1795aSjb150015 case SMB_SERVER_STATE_RUNNING: 6079fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States case SMB_SERVER_STATE_STOPPING: 608faa1795aSjb150015 rw_enter(&sv->sv_cfg_lock, RW_WRITER); 60929bd2886SAlan Wright smb_server_store_cfg(sv, ioc); 610faa1795aSjb150015 rw_exit(&sv->sv_cfg_lock); 611faa1795aSjb150015 break; 612faa1795aSjb150015 613faa1795aSjb150015 default: 6149fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States SMB_SERVER_STATE_VALID(sv->sv_state); 615faa1795aSjb150015 rc = EFAULT; 616faa1795aSjb150015 break; 617faa1795aSjb150015 } 618faa1795aSjb150015 mutex_exit(&sv->sv_mutex); 619faa1795aSjb150015 620faa1795aSjb150015 smb_server_release(sv); 621faa1795aSjb150015 622faa1795aSjb150015 return (rc); 623faa1795aSjb150015 } 624faa1795aSjb150015 625faa1795aSjb150015 /* 626faa1795aSjb150015 * smb_server_start 6275d8538b6SGordon Ross * 6285d8538b6SGordon Ross * Called via SMB_IOC_START during smbd startup. 6295d8538b6SGordon Ross * Bring up the activities requried for SMB service. 630faa1795aSjb150015 */ 631faa1795aSjb150015 int 63229bd2886SAlan Wright smb_server_start(smb_ioc_start_t *ioc) 633faa1795aSjb150015 { 634faa1795aSjb150015 int rc = 0; 6354163af6aSjose borrego int family; 636faa1795aSjb150015 smb_server_t *sv; 6378d94f651SGordon Ross cred_t *ucr; 6385d8538b6SGordon Ross struct proc *tqproc; 639faa1795aSjb150015 640faa1795aSjb150015 rc = smb_server_lookup(&sv); 641faa1795aSjb150015 if (rc) 642faa1795aSjb150015 return (rc); 643faa1795aSjb150015 644faa1795aSjb150015 mutex_enter(&sv->sv_mutex); 645faa1795aSjb150015 switch (sv->sv_state) { 646faa1795aSjb150015 case SMB_SERVER_STATE_CONFIGURED: 647faa1795aSjb150015 6485d8538b6SGordon Ross #ifdef _KERNEL 6495d8538b6SGordon Ross if (smb_create_process) { 6505d8538b6SGordon Ross rc = smb_server_newproc(sv); 6515d8538b6SGordon Ross if (rc != 0) 6525d8538b6SGordon Ross break; 6535d8538b6SGordon Ross } 6545d8538b6SGordon Ross #endif /* _KERNEL */ 6555d8538b6SGordon Ross 6568622ec45SGordon Ross if ((rc = smb_server_fsop_start(sv)) != 0) 6578622ec45SGordon Ross break; 6588622ec45SGordon Ross 6598d94f651SGordon Ross /* 6608d94f651SGordon Ross * Note: smb_kshare_start needs sv_session. 6618d94f651SGordon Ross */ 6628d94f651SGordon Ross sv->sv_session = smb_session_create(NULL, 0, sv, 0); 6638d94f651SGordon Ross if (sv->sv_session == NULL) { 6648d94f651SGordon Ross rc = ENOMEM; 6658d94f651SGordon Ross break; 6668d94f651SGordon Ross } 6678d94f651SGordon Ross 6688d94f651SGordon Ross /* 6698d94f651SGordon Ross * Create a logon on the server session, 6708d94f651SGordon Ross * used when importing CA shares. 6718d94f651SGordon Ross */ 6728d94f651SGordon Ross sv->sv_rootuser = smb_user_new(sv->sv_session); 6738d94f651SGordon Ross ucr = smb_kcred_create(); 6748d94f651SGordon Ross rc = smb_user_logon(sv->sv_rootuser, ucr, "", "root", 6758d94f651SGordon Ross SMB_USER_FLAG_ADMIN, 0, 0); 6768d94f651SGordon Ross crfree(ucr); 6778d94f651SGordon Ross ucr = NULL; 6788d94f651SGordon Ross if (rc != 0) { 6798d94f651SGordon Ross cmn_err(CE_NOTE, "smb_server_start: " 6808d94f651SGordon Ross "failed to create root user"); 6818d94f651SGordon Ross break; 6828d94f651SGordon Ross } 6838d94f651SGordon Ross 6848622ec45SGordon Ross if ((rc = smb_kshare_start(sv)) != 0) 6858622ec45SGordon Ross break; 6868622ec45SGordon Ross 687b819cea2SGordon Ross /* 688*e515d096SGordon Ross * Create our taskq's (thread pools) 689*e515d096SGordon Ross * 690b819cea2SGordon Ross * NB: the proc passed here has to be a "system" one. 691b819cea2SGordon Ross * Normally that's p0, or the NGZ eqivalent. 692*e515d096SGordon Ross * 693*e515d096SGordon Ross * The notify pool is sized at a quarter the number of 694*e515d096SGordon Ross * worker threads (instead of another config item). 695b819cea2SGordon Ross */ 6965d8538b6SGordon Ross tqproc = (sv->sv_proc_p != NULL) ? 6975d8538b6SGordon Ross sv->sv_proc_p : curzone->zone_zsched; 6985d8538b6SGordon Ross 699*e515d096SGordon Ross sv->sv_notify_pool = taskq_create_proc("smb_notify", 700*e515d096SGordon Ross sv->sv_cfg.skc_maxworkers / 4, smbsrv_notify_pri, 701*e515d096SGordon Ross sv->sv_cfg.skc_maxworkers / 4, INT_MAX, 702*e515d096SGordon Ross tqproc, TASKQ_DYNAMIC); 703*e515d096SGordon Ross 7048622ec45SGordon Ross sv->sv_worker_pool = taskq_create_proc("smb_workers", 70508344b29SGordon Ross sv->sv_cfg.skc_maxworkers, smbsrv_worker_pri, 706faa1795aSjb150015 sv->sv_cfg.skc_maxworkers, INT_MAX, 7075d8538b6SGordon Ross tqproc, TASKQ_DYNAMIC); 708faa1795aSjb150015 7098622ec45SGordon Ross sv->sv_receiver_pool = taskq_create_proc("smb_receivers", 71008344b29SGordon Ross sv->sv_cfg.skc_maxconnections, smbsrv_receive_pri, 7114163af6aSjose borrego sv->sv_cfg.skc_maxconnections, INT_MAX, 7125d8538b6SGordon Ross tqproc, TASKQ_DYNAMIC); 7134163af6aSjose borrego 714*e515d096SGordon Ross if (sv->sv_notify_pool == NULL || 715*e515d096SGordon Ross sv->sv_worker_pool == NULL || 7168d94f651SGordon Ross sv->sv_receiver_pool == NULL) { 717faa1795aSjb150015 rc = ENOMEM; 718faa1795aSjb150015 break; 719faa1795aSjb150015 } 720faa1795aSjb150015 721b819cea2SGordon Ross #ifdef _KERNEL 722faa1795aSjb150015 ASSERT(sv->sv_lmshrd == NULL); 723148c5f43SAlan Wright sv->sv_lmshrd = smb_kshare_door_init(ioc->lmshrd); 724faa1795aSjb150015 if (sv->sv_lmshrd == NULL) 725faa1795aSjb150015 break; 72654026d5aSGordon Ross if ((rc = smb_kdoor_open(sv, ioc->udoor)) != 0) { 7279fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States cmn_err(CE_WARN, "Cannot open smbd door"); 728faa1795aSjb150015 break; 7299fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States } 730b819cea2SGordon Ross #else /* _KERNEL */ 731b819cea2SGordon Ross /* Fake kernel does not use the kshare_door */ 732b819cea2SGordon Ross fksmb_kdoor_open(sv, ioc->udoor_func); 733b819cea2SGordon Ross #endif /* _KERNEL */ 734b819cea2SGordon Ross 73554026d5aSGordon Ross if ((rc = smb_thread_start(&sv->si_thread_timers)) != 0) 7369fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States break; 7374163af6aSjose borrego 7384163af6aSjose borrego family = AF_INET; 7394163af6aSjose borrego smb_server_listener_init(sv, &sv->sv_nbt_daemon, 7404163af6aSjose borrego "smb_nbt_listener", IPPORT_NETBIOS_SSN, family); 7414163af6aSjose borrego if (sv->sv_cfg.skc_ipv6_enable) 7424163af6aSjose borrego family = AF_INET6; 7434163af6aSjose borrego smb_server_listener_init(sv, &sv->sv_tcp_daemon, 7444163af6aSjose borrego "smb_tcp_listener", IPPORT_SMB, family); 7454163af6aSjose borrego rc = smb_server_listener_start(&sv->sv_tcp_daemon); 7464163af6aSjose borrego if (rc != 0) 7474163af6aSjose borrego break; 74883d2dfe6SGordon Ross if (sv->sv_cfg.skc_netbios_enable) 74983d2dfe6SGordon Ross (void) smb_server_listener_start(&sv->sv_nbt_daemon); 7504163af6aSjose borrego 751faa1795aSjb150015 sv->sv_state = SMB_SERVER_STATE_RUNNING; 752148c5f43SAlan Wright sv->sv_start_time = gethrtime(); 753faa1795aSjb150015 mutex_exit(&sv->sv_mutex); 754faa1795aSjb150015 smb_server_release(sv); 7558622ec45SGordon Ross smb_export_start(sv); 756faa1795aSjb150015 return (0); 757faa1795aSjb150015 default: 7589fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States SMB_SERVER_STATE_VALID(sv->sv_state); 759faa1795aSjb150015 mutex_exit(&sv->sv_mutex); 760faa1795aSjb150015 smb_server_release(sv); 761faa1795aSjb150015 return (ENOTTY); 762faa1795aSjb150015 } 763faa1795aSjb150015 764faa1795aSjb150015 mutex_exit(&sv->sv_mutex); 7654163af6aSjose borrego smb_server_shutdown(sv); 766faa1795aSjb150015 smb_server_release(sv); 767faa1795aSjb150015 return (rc); 768faa1795aSjb150015 } 769faa1795aSjb150015 770faa1795aSjb150015 /* 7719fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States * An smbd is shutting down. 7729fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States */ 7739fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States int 7749fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States smb_server_stop(void) 7759fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States { 7769fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States smb_server_t *sv; 7779fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States int rc; 7789fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 7799fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States if ((rc = smb_server_lookup(&sv)) != 0) 7809fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States return (rc); 7819fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 7829fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States mutex_enter(&sv->sv_mutex); 7839fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States switch (sv->sv_state) { 7849fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States case SMB_SERVER_STATE_RUNNING: 7859fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States sv->sv_state = SMB_SERVER_STATE_STOPPING; 7864163af6aSjose borrego mutex_exit(&sv->sv_mutex); 7874163af6aSjose borrego smb_server_shutdown(sv); 7884163af6aSjose borrego mutex_enter(&sv->sv_mutex); 789cb174861Sjoyce mcintosh cv_broadcast(&sv->sp_info.sp_cv); 7909fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States break; 7919fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States default: 7929fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States SMB_SERVER_STATE_VALID(sv->sv_state); 7939fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States break; 7949fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States } 7959fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States mutex_exit(&sv->sv_mutex); 7969fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 7979fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States smb_server_release(sv); 7989fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States return (0); 7999fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States } 8009fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 8019fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States boolean_t 8028622ec45SGordon Ross smb_server_is_stopping(smb_server_t *sv) 8039fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States { 8049fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States boolean_t status; 8059fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 8069fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States SMB_SERVER_VALID(sv); 8079fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 8089fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States mutex_enter(&sv->sv_mutex); 8099fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 8109fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States switch (sv->sv_state) { 8119fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States case SMB_SERVER_STATE_STOPPING: 8129fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States case SMB_SERVER_STATE_DELETING: 8139fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States status = B_TRUE; 8149fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States break; 8159fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States default: 8169fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States status = B_FALSE; 8179fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States break; 8189fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States } 8199fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 8209fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States mutex_exit(&sv->sv_mutex); 8219fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States return (status); 8229fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States } 8239fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 8248622ec45SGordon Ross void 8258622ec45SGordon Ross smb_server_cancel_event(smb_server_t *sv, uint32_t txid) 8269fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States { 8279fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States smb_event_cancel(sv, txid); 8289fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States } 8299fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 8309fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States int 8319fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States smb_server_notify_event(smb_ioc_event_t *ioc) 8329fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States { 8339fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States smb_server_t *sv; 8349fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States int rc; 8359fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 8369fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States if ((rc = smb_server_lookup(&sv)) == 0) { 8379fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States smb_event_notify(sv, ioc->txid); 8389fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States smb_server_release(sv); 8399fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States } 8409fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 8419fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States return (rc); 8429fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States } 8439fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 8449fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States /* 845cb174861Sjoyce mcintosh * smb_server_spooldoc 846cb174861Sjoyce mcintosh * 847cb174861Sjoyce mcintosh * Waits for print file close broadcast. 848cb174861Sjoyce mcintosh * Gets the head of the fid list, 849cb174861Sjoyce mcintosh * then searches the spooldoc list and returns 850cb174861Sjoyce mcintosh * this info via the ioctl to user land. 851cb174861Sjoyce mcintosh * 852cb174861Sjoyce mcintosh * rc - 0 success 853cb174861Sjoyce mcintosh */ 854cb174861Sjoyce mcintosh 855cb174861Sjoyce mcintosh int 856cb174861Sjoyce mcintosh smb_server_spooldoc(smb_ioc_spooldoc_t *ioc) 857cb174861Sjoyce mcintosh { 858cb174861Sjoyce mcintosh smb_server_t *sv; 859cb174861Sjoyce mcintosh int rc; 860cb174861Sjoyce mcintosh smb_kspooldoc_t *spdoc; 861cb174861Sjoyce mcintosh uint16_t fid; 862cb174861Sjoyce mcintosh 86323a9c295SGordon Ross if ((rc = smb_server_lookup(&sv)) != 0) 86423a9c295SGordon Ross return (rc); 86523a9c295SGordon Ross 866b7301bf5SGordon Ross if (sv->sv_cfg.skc_print_enable == 0) { 867b7301bf5SGordon Ross rc = ENOTTY; 868b7301bf5SGordon Ross goto out; 869b7301bf5SGordon Ross } 870b7301bf5SGordon Ross 87123a9c295SGordon Ross mutex_enter(&sv->sv_mutex); 87223a9c295SGordon Ross for (;;) { 873cb174861Sjoyce mcintosh if (sv->sv_state != SMB_SERVER_STATE_RUNNING) { 874cb174861Sjoyce mcintosh rc = ECANCELED; 87523a9c295SGordon Ross break; 87623a9c295SGordon Ross } 87723a9c295SGordon Ross if ((fid = smb_spool_get_fid(sv)) != 0) { 87823a9c295SGordon Ross rc = 0; 87923a9c295SGordon Ross break; 88023a9c295SGordon Ross } 88123a9c295SGordon Ross if (cv_wait_sig(&sv->sp_info.sp_cv, &sv->sv_mutex) == 0) { 88223a9c295SGordon Ross rc = EINTR; 88323a9c295SGordon Ross break; 88423a9c295SGordon Ross } 88523a9c295SGordon Ross } 88623a9c295SGordon Ross mutex_exit(&sv->sv_mutex); 887b7301bf5SGordon Ross if (rc != 0) 888b7301bf5SGordon Ross goto out; 889b7301bf5SGordon Ross 89023a9c295SGordon Ross spdoc = kmem_zalloc(sizeof (*spdoc), KM_SLEEP); 89123a9c295SGordon Ross if (smb_spool_lookup_doc_byfid(sv, fid, spdoc)) { 892cb174861Sjoyce mcintosh ioc->spool_num = spdoc->sd_spool_num; 893cb174861Sjoyce mcintosh ioc->ipaddr = spdoc->sd_ipaddr; 894cb174861Sjoyce mcintosh (void) strlcpy(ioc->path, spdoc->sd_path, 895cb174861Sjoyce mcintosh MAXPATHLEN); 896cb174861Sjoyce mcintosh (void) strlcpy(ioc->username, 897cb174861Sjoyce mcintosh spdoc->sd_username, MAXNAMELEN); 89823a9c295SGordon Ross } else { 89923a9c295SGordon Ross /* Did not find that print job. */ 90023a9c295SGordon Ross rc = EAGAIN; 901cb174861Sjoyce mcintosh } 90223a9c295SGordon Ross kmem_free(spdoc, sizeof (*spdoc)); 90323a9c295SGordon Ross 904b7301bf5SGordon Ross out: 905cb174861Sjoyce mcintosh smb_server_release(sv); 906cb174861Sjoyce mcintosh return (rc); 907cb174861Sjoyce mcintosh } 908cb174861Sjoyce mcintosh 909faa1795aSjb150015 int 91029bd2886SAlan Wright smb_server_set_gmtoff(smb_ioc_gmt_t *ioc) 911faa1795aSjb150015 { 912faa1795aSjb150015 int rc; 913faa1795aSjb150015 smb_server_t *sv; 914faa1795aSjb150015 91508f0d8daSafshin salek ardakani - Sun Microsystems - Irvine United States if ((rc = smb_server_lookup(&sv)) == 0) { 91629bd2886SAlan Wright sv->si_gmtoff = ioc->offset; 917faa1795aSjb150015 smb_server_release(sv); 91808f0d8daSafshin salek ardakani - Sun Microsystems - Irvine United States } 919faa1795aSjb150015 920faa1795aSjb150015 return (rc); 921faa1795aSjb150015 } 922faa1795aSjb150015 92329bd2886SAlan Wright int 9241fcced4cSJordan Brown smb_server_numopen(smb_ioc_opennum_t *ioc) 92529bd2886SAlan Wright { 92629bd2886SAlan Wright smb_server_t *sv; 92729bd2886SAlan Wright int rc; 92829bd2886SAlan Wright 92929bd2886SAlan Wright if ((rc = smb_server_lookup(&sv)) == 0) { 930148c5f43SAlan Wright ioc->open_users = sv->sv_users; 931148c5f43SAlan Wright ioc->open_trees = sv->sv_trees; 932148c5f43SAlan Wright ioc->open_files = sv->sv_files + sv->sv_pipes; 93329bd2886SAlan Wright smb_server_release(sv); 93429bd2886SAlan Wright } 93529bd2886SAlan Wright return (rc); 93629bd2886SAlan Wright } 93729bd2886SAlan Wright 938faa1795aSjb150015 /* 9391fcced4cSJordan Brown * Enumerate objects within the server. The svcenum provides the 9401fcced4cSJordan Brown * enumeration context, i.e. what the caller want to get back. 9411fcced4cSJordan Brown */ 9421fcced4cSJordan Brown int 9431fcced4cSJordan Brown smb_server_enum(smb_ioc_svcenum_t *ioc) 9441fcced4cSJordan Brown { 9451fcced4cSJordan Brown smb_svcenum_t *svcenum = &ioc->svcenum; 9461fcced4cSJordan Brown smb_server_t *sv; 9471fcced4cSJordan Brown int rc; 9481fcced4cSJordan Brown 9491d443a93SDan McDonald /* 9501d443a93SDan McDonald * Reality check that the buffer-length insize the enum doesn't 9511d443a93SDan McDonald * overrun the ioctl's total length. 9521d443a93SDan McDonald */ 9531d443a93SDan McDonald if (svcenum->se_buflen + sizeof (*ioc) > ioc->hdr.len) 9541d443a93SDan McDonald return (EINVAL); 9551d443a93SDan McDonald 9561fcced4cSJordan Brown if ((rc = smb_server_lookup(&sv)) != 0) 9571fcced4cSJordan Brown return (rc); 9581fcced4cSJordan Brown 9591fcced4cSJordan Brown svcenum->se_bavail = svcenum->se_buflen; 9601fcced4cSJordan Brown svcenum->se_bused = 0; 9611fcced4cSJordan Brown svcenum->se_nitems = 0; 9621fcced4cSJordan Brown 9633b13a1efSThomas Keiser switch (svcenum->se_type) { 9643b13a1efSThomas Keiser case SMB_SVCENUM_TYPE_USER: 9658d94f651SGordon Ross smb_server_enum_users(sv, svcenum); 9663b13a1efSThomas Keiser break; 9673b13a1efSThomas Keiser case SMB_SVCENUM_TYPE_TREE: 9683b13a1efSThomas Keiser case SMB_SVCENUM_TYPE_FILE: 9698d94f651SGordon Ross smb_server_enum_trees(sv, svcenum); 9703b13a1efSThomas Keiser break; 9713b13a1efSThomas Keiser default: 9723b13a1efSThomas Keiser rc = EINVAL; 9733b13a1efSThomas Keiser } 9741fcced4cSJordan Brown 9751fcced4cSJordan Brown smb_server_release(sv); 9763b13a1efSThomas Keiser return (rc); 9771fcced4cSJordan Brown } 9781fcced4cSJordan Brown 9791fcced4cSJordan Brown /* 9801fcced4cSJordan Brown * Look for sessions to disconnect by client and user name. 9811fcced4cSJordan Brown */ 9821fcced4cSJordan Brown int 9831fcced4cSJordan Brown smb_server_session_close(smb_ioc_session_t *ioc) 9841fcced4cSJordan Brown { 9851fcced4cSJordan Brown smb_server_t *sv; 986811599a4SMatt Barden int cnt; 9871fcced4cSJordan Brown int rc; 9881fcced4cSJordan Brown 9891fcced4cSJordan Brown if ((rc = smb_server_lookup(&sv)) != 0) 9901fcced4cSJordan Brown return (rc); 9911fcced4cSJordan Brown 9928d94f651SGordon Ross cnt = smb_server_session_disconnect(sv, ioc->client, ioc->username); 9931fcced4cSJordan Brown 9941fcced4cSJordan Brown smb_server_release(sv); 9951fcced4cSJordan Brown 996811599a4SMatt Barden if (cnt == 0) 9971fcced4cSJordan Brown return (ENOENT); 9981fcced4cSJordan Brown return (0); 9991fcced4cSJordan Brown } 10001fcced4cSJordan Brown 10011fcced4cSJordan Brown /* 10021fcced4cSJordan Brown * Close a file by uniqid. 10031fcced4cSJordan Brown */ 10041fcced4cSJordan Brown int 10051fcced4cSJordan Brown smb_server_file_close(smb_ioc_fileid_t *ioc) 10061fcced4cSJordan Brown { 10071fcced4cSJordan Brown uint32_t uniqid = ioc->uniqid; 10081fcced4cSJordan Brown smb_server_t *sv; 10091fcced4cSJordan Brown int rc; 10101fcced4cSJordan Brown 10111fcced4cSJordan Brown if ((rc = smb_server_lookup(&sv)) != 0) 10121fcced4cSJordan Brown return (rc); 10131fcced4cSJordan Brown 10148d94f651SGordon Ross rc = smb_server_fclose(sv, uniqid); 10151fcced4cSJordan Brown 10161fcced4cSJordan Brown smb_server_release(sv); 10171fcced4cSJordan Brown return (rc); 10181fcced4cSJordan Brown } 10191fcced4cSJordan Brown 10201fcced4cSJordan Brown /* 1021faa1795aSjb150015 * These functions determine the relevant smb server to which the call apply. 1022faa1795aSjb150015 */ 1023faa1795aSjb150015 1024faa1795aSjb150015 uint32_t 10258622ec45SGordon Ross smb_server_get_session_count(smb_server_t *sv) 1026faa1795aSjb150015 { 1027faa1795aSjb150015 uint32_t counter = 0; 1028faa1795aSjb150015 1029811599a4SMatt Barden counter = smb_llist_get_count(&sv->sv_session_list); 1030faa1795aSjb150015 1031faa1795aSjb150015 return (counter); 1032faa1795aSjb150015 } 1033faa1795aSjb150015 1034faa1795aSjb150015 /* 10358d94f651SGordon Ross * Gets the smb_node of the specified share path. 10368d94f651SGordon Ross * Node is returned held (caller must rele.) 1037148c5f43SAlan Wright */ 1038148c5f43SAlan Wright int 10398d94f651SGordon Ross smb_server_share_lookup(smb_server_t *sv, const char *shr_path, 10408d94f651SGordon Ross smb_node_t **nodepp) 1041148c5f43SAlan Wright { 1042148c5f43SAlan Wright smb_request_t *sr; 1043148c5f43SAlan Wright smb_node_t *fnode = NULL; 10448d94f651SGordon Ross smb_node_t *dnode = NULL; 1045148c5f43SAlan Wright char last_comp[MAXNAMELEN]; 1046148c5f43SAlan Wright int rc = 0; 1047148c5f43SAlan Wright 1048148c5f43SAlan Wright ASSERT(shr_path); 1049148c5f43SAlan Wright 1050148c5f43SAlan Wright mutex_enter(&sv->sv_mutex); 1051148c5f43SAlan Wright switch (sv->sv_state) { 1052148c5f43SAlan Wright case SMB_SERVER_STATE_RUNNING: 1053148c5f43SAlan Wright break; 1054148c5f43SAlan Wright default: 1055148c5f43SAlan Wright mutex_exit(&sv->sv_mutex); 1056148c5f43SAlan Wright return (ENOTACTIVE); 1057148c5f43SAlan Wright } 1058148c5f43SAlan Wright mutex_exit(&sv->sv_mutex); 1059148c5f43SAlan Wright 1060148c5f43SAlan Wright if ((sr = smb_request_alloc(sv->sv_session, 0)) == NULL) { 1061811599a4SMatt Barden return (ENOTCONN); 1062148c5f43SAlan Wright } 10638622ec45SGordon Ross sr->user_cr = zone_kcred(); 1064148c5f43SAlan Wright 1065148c5f43SAlan Wright rc = smb_pathname_reduce(sr, sr->user_cr, shr_path, 1066148c5f43SAlan Wright NULL, NULL, &dnode, last_comp); 1067148c5f43SAlan Wright 1068148c5f43SAlan Wright if (rc == 0) { 1069148c5f43SAlan Wright rc = smb_fsop_lookup(sr, sr->user_cr, SMB_FOLLOW_LINKS, 1070148c5f43SAlan Wright sv->si_root_smb_node, dnode, last_comp, &fnode); 1071148c5f43SAlan Wright smb_node_release(dnode); 1072148c5f43SAlan Wright } 1073148c5f43SAlan Wright 1074148c5f43SAlan Wright smb_request_free(sr); 1075148c5f43SAlan Wright 1076148c5f43SAlan Wright if (rc != 0) 1077148c5f43SAlan Wright return (rc); 1078148c5f43SAlan Wright 1079148c5f43SAlan Wright ASSERT(fnode->vp && fnode->vp->v_vfsp); 1080148c5f43SAlan Wright 10818d94f651SGordon Ross *nodepp = fnode; 1082148c5f43SAlan Wright 1083148c5f43SAlan Wright return (0); 1084148c5f43SAlan Wright } 1085148c5f43SAlan Wright 1086b819cea2SGordon Ross #ifdef _KERNEL 1087148c5f43SAlan Wright /* 1088148c5f43SAlan Wright * This is a special interface that will be utilized by ZFS to cause a share to 1089148c5f43SAlan Wright * be added/removed. 1090148c5f43SAlan Wright * 1091148c5f43SAlan Wright * arg is either a lmshare_info_t or share_name from userspace. 1092148c5f43SAlan Wright * It will need to be copied into the kernel. It is lmshare_info_t 1093148c5f43SAlan Wright * for add operations and share_name for delete operations. 1094148c5f43SAlan Wright */ 1095148c5f43SAlan Wright int 1096148c5f43SAlan Wright smb_server_share(void *arg, boolean_t add_share) 1097148c5f43SAlan Wright { 1098148c5f43SAlan Wright smb_server_t *sv; 1099148c5f43SAlan Wright int rc; 1100148c5f43SAlan Wright 1101148c5f43SAlan Wright if ((rc = smb_server_lookup(&sv)) == 0) { 1102148c5f43SAlan Wright mutex_enter(&sv->sv_mutex); 1103148c5f43SAlan Wright switch (sv->sv_state) { 1104148c5f43SAlan Wright case SMB_SERVER_STATE_RUNNING: 1105148c5f43SAlan Wright mutex_exit(&sv->sv_mutex); 1106148c5f43SAlan Wright (void) smb_kshare_upcall(sv->sv_lmshrd, arg, add_share); 1107148c5f43SAlan Wright break; 1108148c5f43SAlan Wright default: 1109148c5f43SAlan Wright mutex_exit(&sv->sv_mutex); 1110148c5f43SAlan Wright break; 1111148c5f43SAlan Wright } 1112148c5f43SAlan Wright smb_server_release(sv); 1113148c5f43SAlan Wright } 1114148c5f43SAlan Wright 1115148c5f43SAlan Wright return (rc); 1116148c5f43SAlan Wright } 1117b819cea2SGordon Ross #endif /* _KERNEL */ 1118148c5f43SAlan Wright 1119148c5f43SAlan Wright int 1120148c5f43SAlan Wright smb_server_unshare(const char *sharename) 1121148c5f43SAlan Wright { 1122148c5f43SAlan Wright smb_server_t *sv; 1123148c5f43SAlan Wright int rc; 1124148c5f43SAlan Wright 1125148c5f43SAlan Wright if ((rc = smb_server_lookup(&sv))) 1126148c5f43SAlan Wright return (rc); 1127148c5f43SAlan Wright 1128148c5f43SAlan Wright mutex_enter(&sv->sv_mutex); 1129148c5f43SAlan Wright switch (sv->sv_state) { 1130148c5f43SAlan Wright case SMB_SERVER_STATE_RUNNING: 1131148c5f43SAlan Wright case SMB_SERVER_STATE_STOPPING: 1132148c5f43SAlan Wright break; 1133148c5f43SAlan Wright default: 1134148c5f43SAlan Wright mutex_exit(&sv->sv_mutex); 1135148c5f43SAlan Wright smb_server_release(sv); 1136148c5f43SAlan Wright return (ENOTACTIVE); 1137148c5f43SAlan Wright } 1138148c5f43SAlan Wright mutex_exit(&sv->sv_mutex); 1139148c5f43SAlan Wright 11408d94f651SGordon Ross smb_server_disconnect_share(sv, sharename); 1141148c5f43SAlan Wright 1142148c5f43SAlan Wright smb_server_release(sv); 1143148c5f43SAlan Wright return (0); 1144148c5f43SAlan Wright } 1145148c5f43SAlan Wright 1146148c5f43SAlan Wright /* 11479fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States * Disconnect the specified share. 11489fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States * Typically called when a share has been removed. 1149faa1795aSjb150015 */ 11502c1b14e5Sjose borrego static void 11518d94f651SGordon Ross smb_server_disconnect_share(smb_server_t *sv, const char *sharename) 1152faa1795aSjb150015 { 11538d94f651SGordon Ross smb_llist_t *ll; 11549fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States smb_session_t *session; 11559fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 11568d94f651SGordon Ross ll = &sv->sv_session_list; 11574163af6aSjose borrego smb_llist_enter(ll, RW_READER); 11589fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 11594163af6aSjose borrego session = smb_llist_head(ll); 11609fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States while (session) { 11614163af6aSjose borrego SMB_SESSION_VALID(session); 11629fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States smb_rwx_rwenter(&session->s_lock, RW_READER); 11639fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States switch (session->s_state) { 11649fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States case SMB_SESSION_STATE_NEGOTIATED: 1165811599a4SMatt Barden smb_rwx_rwexit(&session->s_lock); 11669fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States smb_session_disconnect_share(session, sharename); 11679fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States break; 11689fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States default: 1169811599a4SMatt Barden smb_rwx_rwexit(&session->s_lock); 11709fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States break; 11719fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States } 11724163af6aSjose borrego session = smb_llist_next(ll, session); 11739fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States } 11749fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 11754163af6aSjose borrego smb_llist_exit(ll); 1176faa1795aSjb150015 } 1177faa1795aSjb150015 11785d8538b6SGordon Ross #ifdef _KERNEL 11795d8538b6SGordon Ross 11805d8538b6SGordon Ross /* 11815d8538b6SGordon Ross * Create a process to own SMB server threads. 11825d8538b6SGordon Ross */ 11835d8538b6SGordon Ross static int 11845d8538b6SGordon Ross smb_server_newproc(smb_server_t *sv) 11855d8538b6SGordon Ross { 11865d8538b6SGordon Ross int rc; 11875d8538b6SGordon Ross 11885d8538b6SGordon Ross mutex_enter(&sv->sv_proc_lock); 11895d8538b6SGordon Ross if (sv->sv_proc_p != NULL) { 11905d8538b6SGordon Ross /* restart? re-use proc */ 11915d8538b6SGordon Ross rc = 0; 11925d8538b6SGordon Ross goto out; 11935d8538b6SGordon Ross } 11945d8538b6SGordon Ross 11955d8538b6SGordon Ross sv->sv_proc_state = SMB_THREAD_STATE_STARTING; 11965d8538b6SGordon Ross rc = newproc(smb_server_proc_main, (caddr_t)sv, 11975d8538b6SGordon Ross syscid, smbsrv_base_pri, NULL, 0); 11985d8538b6SGordon Ross if (rc != 0) { 11995d8538b6SGordon Ross cmn_err(CE_WARN, "newproc failed, rc=%d", rc); 12005d8538b6SGordon Ross goto out; 12015d8538b6SGordon Ross } 12025d8538b6SGordon Ross 12035d8538b6SGordon Ross /* Rendez-vous with new proc thread. */ 12045d8538b6SGordon Ross while (sv->sv_proc_state == SMB_THREAD_STATE_STARTING) { 12055d8538b6SGordon Ross cv_wait(&sv->sv_proc_cv, &sv->sv_proc_lock); 12065d8538b6SGordon Ross 12075d8538b6SGordon Ross } 12085d8538b6SGordon Ross if (sv->sv_proc_state != SMB_THREAD_STATE_RUNNING) { 12095d8538b6SGordon Ross rc = ESRCH; 12105d8538b6SGordon Ross goto out; 12115d8538b6SGordon Ross } 12125d8538b6SGordon Ross ASSERT(sv->sv_proc_p != NULL); 12135d8538b6SGordon Ross 12145d8538b6SGordon Ross out: 12155d8538b6SGordon Ross mutex_exit(&sv->sv_proc_lock); 12165d8538b6SGordon Ross return (rc); 12175d8538b6SGordon Ross } 12185d8538b6SGordon Ross 12195d8538b6SGordon Ross /* 12205d8538b6SGordon Ross * Main thread for the process we create to own SMB server threads. 12215d8538b6SGordon Ross */ 12225d8538b6SGordon Ross static void 12235d8538b6SGordon Ross smb_server_proc_main(void *arg) 12245d8538b6SGordon Ross { 12255d8538b6SGordon Ross callb_cpr_t cprinfo; 12265d8538b6SGordon Ross smb_server_t *sv = arg; 12275d8538b6SGordon Ross user_t *pu = PTOU(curproc); 12285d8538b6SGordon Ross zoneid_t zid = getzoneid(); 12295d8538b6SGordon Ross 12305d8538b6SGordon Ross ASSERT(curproc != &p0); 12315d8538b6SGordon Ross ASSERT(zid == sv->sv_zid); 12325d8538b6SGordon Ross 12335d8538b6SGordon Ross (void) strlcpy(pu->u_comm, "smbsrv", sizeof (pu->u_comm)); 12345d8538b6SGordon Ross (void) snprintf(pu->u_psargs, sizeof (pu->u_psargs), 12355d8538b6SGordon Ross "smbsrv %d", (int)zid); 12365d8538b6SGordon Ross 12375d8538b6SGordon Ross CALLB_CPR_INIT(&cprinfo, &sv->sv_proc_lock, callb_generic_cpr, 12385d8538b6SGordon Ross pu->u_psargs); 12395d8538b6SGordon Ross 12405d8538b6SGordon Ross mutex_enter(&sv->sv_proc_lock); 12415d8538b6SGordon Ross ASSERT(sv->sv_proc_state == SMB_THREAD_STATE_STARTING); 12425d8538b6SGordon Ross 12435d8538b6SGordon Ross sv->sv_proc_p = curproc; 12445d8538b6SGordon Ross sv->sv_proc_did = curthread->t_did; 12455d8538b6SGordon Ross 12465d8538b6SGordon Ross sv->sv_proc_state = SMB_THREAD_STATE_RUNNING; 12475d8538b6SGordon Ross cv_broadcast(&sv->sv_proc_cv); 12485d8538b6SGordon Ross 12495d8538b6SGordon Ross CALLB_CPR_SAFE_BEGIN(&cprinfo); 12505d8538b6SGordon Ross while (sv->sv_proc_state == SMB_THREAD_STATE_RUNNING) 12515d8538b6SGordon Ross cv_wait(&sv->sv_proc_cv, &sv->sv_proc_lock); 12525d8538b6SGordon Ross CALLB_CPR_SAFE_END(&cprinfo, &sv->sv_proc_lock); 12535d8538b6SGordon Ross 12545d8538b6SGordon Ross ASSERT(sv->sv_proc_state == SMB_THREAD_STATE_EXITING); 12555d8538b6SGordon Ross sv->sv_proc_state = SMB_THREAD_STATE_EXITED; 12565d8538b6SGordon Ross sv->sv_proc_p = NULL; 12575d8538b6SGordon Ross cv_broadcast(&sv->sv_proc_cv); 12585d8538b6SGordon Ross CALLB_CPR_EXIT(&cprinfo); /* mutex_exit sv_proc_lock */ 12595d8538b6SGordon Ross 12605d8538b6SGordon Ross /* Note: lwp_exit() expects p_lock entered. */ 12615d8538b6SGordon Ross mutex_enter(&curproc->p_lock); 12625d8538b6SGordon Ross lwp_exit(); 12635d8538b6SGordon Ross } 12645d8538b6SGordon Ross 12655d8538b6SGordon Ross /* 12665d8538b6SGordon Ross * Delete the server proc (if any) 12675d8538b6SGordon Ross */ 12685d8538b6SGordon Ross static void 12695d8538b6SGordon Ross smb_server_delproc(smb_server_t *sv) 12705d8538b6SGordon Ross { 12715d8538b6SGordon Ross 12725d8538b6SGordon Ross mutex_enter(&sv->sv_proc_lock); 12735d8538b6SGordon Ross 12745d8538b6SGordon Ross if (sv->sv_proc_state != SMB_THREAD_STATE_RUNNING) 12755d8538b6SGordon Ross goto out; 12765d8538b6SGordon Ross ASSERT(sv->sv_proc_p != NULL); 12775d8538b6SGordon Ross 12785d8538b6SGordon Ross sv->sv_proc_state = SMB_THREAD_STATE_EXITING; 12795d8538b6SGordon Ross cv_broadcast(&sv->sv_proc_cv); 12805d8538b6SGordon Ross 12815d8538b6SGordon Ross /* Rendez-vous with proc thread. */ 12825d8538b6SGordon Ross while (sv->sv_proc_state == SMB_THREAD_STATE_EXITING) { 12835d8538b6SGordon Ross cv_wait(&sv->sv_proc_cv, &sv->sv_proc_lock); 12845d8538b6SGordon Ross 12855d8538b6SGordon Ross } 12865d8538b6SGordon Ross if (sv->sv_proc_state != SMB_THREAD_STATE_EXITED) { 12875d8538b6SGordon Ross cmn_err(CE_WARN, "smb_server_delproc, state=%d", 12885d8538b6SGordon Ross sv->sv_proc_state); 12895d8538b6SGordon Ross goto out; 12905d8538b6SGordon Ross } 12915d8538b6SGordon Ross if (sv->sv_proc_did != 0) { 12925d8538b6SGordon Ross thread_join(sv->sv_proc_did); 12935d8538b6SGordon Ross sv->sv_proc_did = 0; 12945d8538b6SGordon Ross } 12955d8538b6SGordon Ross 12965d8538b6SGordon Ross out: 12975d8538b6SGordon Ross mutex_exit(&sv->sv_proc_lock); 12985d8538b6SGordon Ross } 12995d8538b6SGordon Ross 13005d8538b6SGordon Ross #endif /* _KERNEL */ 13015d8538b6SGordon Ross 1302faa1795aSjb150015 /* 1303faa1795aSjb150015 * ***************************************************************************** 1304faa1795aSjb150015 * **************** Functions called from the internal layers ****************** 1305faa1795aSjb150015 * ***************************************************************************** 1306faa1795aSjb150015 * 1307faa1795aSjb150015 * These functions are provided the relevant smb server by the caller. 1308faa1795aSjb150015 */ 1309faa1795aSjb150015 1310faa1795aSjb150015 void 1311faa1795aSjb150015 smb_server_get_cfg(smb_server_t *sv, smb_kmod_cfg_t *cfg) 1312faa1795aSjb150015 { 1313faa1795aSjb150015 rw_enter(&sv->sv_cfg_lock, RW_READER); 1314faa1795aSjb150015 bcopy(&sv->sv_cfg, cfg, sizeof (*cfg)); 1315faa1795aSjb150015 rw_exit(&sv->sv_cfg_lock); 1316faa1795aSjb150015 } 1317faa1795aSjb150015 1318faa1795aSjb150015 /* 1319148c5f43SAlan Wright * 1320148c5f43SAlan Wright */ 1321148c5f43SAlan Wright void 1322148c5f43SAlan Wright smb_server_inc_nbt_sess(smb_server_t *sv) 1323148c5f43SAlan Wright { 1324148c5f43SAlan Wright SMB_SERVER_VALID(sv); 1325148c5f43SAlan Wright atomic_inc_32(&sv->sv_nbt_sess); 1326148c5f43SAlan Wright } 1327148c5f43SAlan Wright 1328148c5f43SAlan Wright void 1329148c5f43SAlan Wright smb_server_dec_nbt_sess(smb_server_t *sv) 1330148c5f43SAlan Wright { 1331148c5f43SAlan Wright SMB_SERVER_VALID(sv); 1332148c5f43SAlan Wright atomic_dec_32(&sv->sv_nbt_sess); 1333148c5f43SAlan Wright } 1334148c5f43SAlan Wright 1335148c5f43SAlan Wright void 1336148c5f43SAlan Wright smb_server_inc_tcp_sess(smb_server_t *sv) 1337148c5f43SAlan Wright { 1338148c5f43SAlan Wright SMB_SERVER_VALID(sv); 1339148c5f43SAlan Wright atomic_inc_32(&sv->sv_tcp_sess); 1340148c5f43SAlan Wright } 1341148c5f43SAlan Wright 1342148c5f43SAlan Wright void 1343148c5f43SAlan Wright smb_server_dec_tcp_sess(smb_server_t *sv) 1344148c5f43SAlan Wright { 1345148c5f43SAlan Wright SMB_SERVER_VALID(sv); 1346148c5f43SAlan Wright atomic_dec_32(&sv->sv_tcp_sess); 1347148c5f43SAlan Wright } 1348148c5f43SAlan Wright 1349148c5f43SAlan Wright void 1350148c5f43SAlan Wright smb_server_inc_users(smb_server_t *sv) 1351148c5f43SAlan Wright { 1352148c5f43SAlan Wright SMB_SERVER_VALID(sv); 1353148c5f43SAlan Wright atomic_inc_32(&sv->sv_users); 1354148c5f43SAlan Wright } 1355148c5f43SAlan Wright 1356148c5f43SAlan Wright void 1357148c5f43SAlan Wright smb_server_dec_users(smb_server_t *sv) 1358148c5f43SAlan Wright { 1359148c5f43SAlan Wright SMB_SERVER_VALID(sv); 1360148c5f43SAlan Wright atomic_dec_32(&sv->sv_users); 1361148c5f43SAlan Wright } 1362148c5f43SAlan Wright 1363148c5f43SAlan Wright void 1364148c5f43SAlan Wright smb_server_inc_trees(smb_server_t *sv) 1365148c5f43SAlan Wright { 1366148c5f43SAlan Wright SMB_SERVER_VALID(sv); 1367148c5f43SAlan Wright atomic_inc_32(&sv->sv_trees); 1368148c5f43SAlan Wright } 1369148c5f43SAlan Wright 1370148c5f43SAlan Wright void 1371148c5f43SAlan Wright smb_server_dec_trees(smb_server_t *sv) 1372148c5f43SAlan Wright { 1373148c5f43SAlan Wright SMB_SERVER_VALID(sv); 1374148c5f43SAlan Wright atomic_dec_32(&sv->sv_trees); 1375148c5f43SAlan Wright } 1376148c5f43SAlan Wright 1377148c5f43SAlan Wright void 1378148c5f43SAlan Wright smb_server_inc_files(smb_server_t *sv) 1379148c5f43SAlan Wright { 1380148c5f43SAlan Wright SMB_SERVER_VALID(sv); 1381148c5f43SAlan Wright atomic_inc_32(&sv->sv_files); 1382148c5f43SAlan Wright } 1383148c5f43SAlan Wright 1384148c5f43SAlan Wright void 1385148c5f43SAlan Wright smb_server_dec_files(smb_server_t *sv) 1386148c5f43SAlan Wright { 1387148c5f43SAlan Wright SMB_SERVER_VALID(sv); 1388148c5f43SAlan Wright atomic_dec_32(&sv->sv_files); 1389148c5f43SAlan Wright } 1390148c5f43SAlan Wright 1391148c5f43SAlan Wright void 1392148c5f43SAlan Wright smb_server_inc_pipes(smb_server_t *sv) 1393148c5f43SAlan Wright { 1394148c5f43SAlan Wright SMB_SERVER_VALID(sv); 1395148c5f43SAlan Wright atomic_inc_32(&sv->sv_pipes); 1396148c5f43SAlan Wright } 1397148c5f43SAlan Wright 1398148c5f43SAlan Wright void 1399148c5f43SAlan Wright smb_server_dec_pipes(smb_server_t *sv) 1400148c5f43SAlan Wright { 1401148c5f43SAlan Wright SMB_SERVER_VALID(sv); 1402148c5f43SAlan Wright atomic_dec_32(&sv->sv_pipes); 1403148c5f43SAlan Wright } 1404148c5f43SAlan Wright 1405148c5f43SAlan Wright void 1406148c5f43SAlan Wright smb_server_add_rxb(smb_server_t *sv, int64_t value) 1407148c5f43SAlan Wright { 1408148c5f43SAlan Wright SMB_SERVER_VALID(sv); 1409148c5f43SAlan Wright atomic_add_64(&sv->sv_rxb, value); 1410148c5f43SAlan Wright } 1411148c5f43SAlan Wright 1412148c5f43SAlan Wright void 1413148c5f43SAlan Wright smb_server_add_txb(smb_server_t *sv, int64_t value) 1414148c5f43SAlan Wright { 1415148c5f43SAlan Wright SMB_SERVER_VALID(sv); 1416148c5f43SAlan Wright atomic_add_64(&sv->sv_txb, value); 1417148c5f43SAlan Wright } 1418148c5f43SAlan Wright 1419148c5f43SAlan Wright void 1420148c5f43SAlan Wright smb_server_inc_req(smb_server_t *sv) 1421148c5f43SAlan Wright { 1422148c5f43SAlan Wright SMB_SERVER_VALID(sv); 1423148c5f43SAlan Wright atomic_inc_64(&sv->sv_nreq); 1424148c5f43SAlan Wright } 1425148c5f43SAlan Wright 1426148c5f43SAlan Wright /* 1427faa1795aSjb150015 * ***************************************************************************** 1428faa1795aSjb150015 * *************************** Static Functions ******************************** 1429faa1795aSjb150015 * ***************************************************************************** 1430faa1795aSjb150015 */ 1431faa1795aSjb150015 1432faa1795aSjb150015 static void 1433faa1795aSjb150015 smb_server_timers(smb_thread_t *thread, void *arg) 1434faa1795aSjb150015 { 1435faa1795aSjb150015 smb_server_t *sv = (smb_server_t *)arg; 1436faa1795aSjb150015 1437faa1795aSjb150015 ASSERT(sv != NULL); 1438faa1795aSjb150015 1439b819cea2SGordon Ross /* 1440811599a4SMatt Barden * This kills old inactive sessions and expired durable 1441811599a4SMatt Barden * handles. The session code expects one call per minute. 1442b819cea2SGordon Ross */ 1443b819cea2SGordon Ross while (smb_thread_continue_timedwait(thread, 60 /* Seconds */)) { 1444811599a4SMatt Barden if (sv->sv_cfg.skc_keepalive != 0) 1445811599a4SMatt Barden smb_session_timers(sv); 1446811599a4SMatt Barden smb2_durable_timers(sv); 1447faa1795aSjb150015 } 1448faa1795aSjb150015 } 1449faa1795aSjb150015 1450faa1795aSjb150015 /* 1451faa1795aSjb150015 * smb_server_kstat_init 1452faa1795aSjb150015 */ 1453148c5f43SAlan Wright static void 1454faa1795aSjb150015 smb_server_kstat_init(smb_server_t *sv) 1455faa1795aSjb150015 { 1456cb174861Sjoyce mcintosh 14578622ec45SGordon Ross sv->sv_ksp = kstat_create_zone(SMBSRV_KSTAT_MODULE, 0, 1458148c5f43SAlan Wright SMBSRV_KSTAT_STATISTICS, SMBSRV_KSTAT_CLASS, KSTAT_TYPE_RAW, 1459148c5f43SAlan Wright sizeof (smbsrv_kstats_t), 0, sv->sv_zid); 1460faa1795aSjb150015 1461148c5f43SAlan Wright if (sv->sv_ksp != NULL) { 1462148c5f43SAlan Wright sv->sv_ksp->ks_update = smb_server_kstat_update; 1463148c5f43SAlan Wright sv->sv_ksp->ks_private = sv; 1464148c5f43SAlan Wright ((smbsrv_kstats_t *)sv->sv_ksp->ks_data)->ks_start_time = 1465148c5f43SAlan Wright sv->sv_start_time; 14668622ec45SGordon Ross smb_dispatch_stats_init(sv); 1467a90cf9f2SGordon Ross smb2_dispatch_stats_init(sv); 1468faa1795aSjb150015 kstat_install(sv->sv_ksp); 1469148c5f43SAlan Wright } else { 1470148c5f43SAlan Wright cmn_err(CE_WARN, "SMB Server: Statistics unavailable"); 1471faa1795aSjb150015 } 1472cb174861Sjoyce mcintosh 14738622ec45SGordon Ross sv->sv_legacy_ksp = kstat_create_zone(SMBSRV_KSTAT_MODULE, 0, 14748622ec45SGordon Ross SMBSRV_KSTAT_NAME, SMBSRV_KSTAT_CLASS, KSTAT_TYPE_NAMED, 14758622ec45SGordon Ross sizeof (smb_server_legacy_kstat_t) / sizeof (kstat_named_t), 14768622ec45SGordon Ross 0, sv->sv_zid); 1477cb174861Sjoyce mcintosh 1478cb174861Sjoyce mcintosh if (sv->sv_legacy_ksp != NULL) { 1479cb174861Sjoyce mcintosh smb_server_legacy_kstat_t *ksd; 1480cb174861Sjoyce mcintosh 1481cb174861Sjoyce mcintosh ksd = sv->sv_legacy_ksp->ks_data; 1482cb174861Sjoyce mcintosh 1483cb174861Sjoyce mcintosh (void) strlcpy(ksd->ls_files.name, "open_files", 1484cb174861Sjoyce mcintosh sizeof (ksd->ls_files.name)); 1485cb174861Sjoyce mcintosh ksd->ls_files.data_type = KSTAT_DATA_UINT32; 1486cb174861Sjoyce mcintosh 1487cb174861Sjoyce mcintosh (void) strlcpy(ksd->ls_trees.name, "connections", 1488cb174861Sjoyce mcintosh sizeof (ksd->ls_trees.name)); 1489cb174861Sjoyce mcintosh ksd->ls_trees.data_type = KSTAT_DATA_UINT32; 1490cb174861Sjoyce mcintosh 1491cb174861Sjoyce mcintosh (void) strlcpy(ksd->ls_users.name, "connections", 1492cb174861Sjoyce mcintosh sizeof (ksd->ls_users.name)); 1493cb174861Sjoyce mcintosh ksd->ls_users.data_type = KSTAT_DATA_UINT32; 1494cb174861Sjoyce mcintosh 1495cb174861Sjoyce mcintosh mutex_init(&sv->sv_legacy_ksmtx, NULL, MUTEX_DEFAULT, NULL); 1496cb174861Sjoyce mcintosh sv->sv_legacy_ksp->ks_lock = &sv->sv_legacy_ksmtx; 1497cb174861Sjoyce mcintosh sv->sv_legacy_ksp->ks_update = smb_server_legacy_kstat_update; 1498cb174861Sjoyce mcintosh kstat_install(sv->sv_legacy_ksp); 1499cb174861Sjoyce mcintosh } 1500faa1795aSjb150015 } 1501faa1795aSjb150015 1502faa1795aSjb150015 /* 1503faa1795aSjb150015 * smb_server_kstat_fini 1504faa1795aSjb150015 */ 1505faa1795aSjb150015 static void 1506faa1795aSjb150015 smb_server_kstat_fini(smb_server_t *sv) 1507faa1795aSjb150015 { 1508cb174861Sjoyce mcintosh if (sv->sv_legacy_ksp != NULL) { 1509cb174861Sjoyce mcintosh kstat_delete(sv->sv_legacy_ksp); 1510cb174861Sjoyce mcintosh mutex_destroy(&sv->sv_legacy_ksmtx); 1511cb174861Sjoyce mcintosh sv->sv_legacy_ksp = NULL; 1512cb174861Sjoyce mcintosh } 1513cb174861Sjoyce mcintosh 1514148c5f43SAlan Wright if (sv->sv_ksp != NULL) { 1515faa1795aSjb150015 kstat_delete(sv->sv_ksp); 1516faa1795aSjb150015 sv->sv_ksp = NULL; 15178622ec45SGordon Ross smb_dispatch_stats_fini(sv); 1518a90cf9f2SGordon Ross smb2_dispatch_stats_fini(sv); 1519faa1795aSjb150015 } 1520faa1795aSjb150015 } 1521faa1795aSjb150015 1522148c5f43SAlan Wright /* 15238365a6eaSGordon Ross * Verify the defines in smb_kstat.h used by ks_reqs1 ks_reqs2 15248365a6eaSGordon Ross */ 15258365a6eaSGordon Ross CTASSERT(SMBSRV_KS_NREQS1 == SMB_COM_NUM); 15268365a6eaSGordon Ross CTASSERT(SMBSRV_KS_NREQS2 == SMB2__NCMDS); 15278365a6eaSGordon Ross 15288365a6eaSGordon Ross /* 1529148c5f43SAlan Wright * smb_server_kstat_update 1530148c5f43SAlan Wright */ 1531faa1795aSjb150015 static int 1532148c5f43SAlan Wright smb_server_kstat_update(kstat_t *ksp, int rw) 1533faa1795aSjb150015 { 1534faa1795aSjb150015 smb_server_t *sv; 1535148c5f43SAlan Wright smbsrv_kstats_t *ksd; 1536faa1795aSjb150015 1537148c5f43SAlan Wright if (rw == KSTAT_READ) { 1538148c5f43SAlan Wright sv = ksp->ks_private; 15399fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States SMB_SERVER_VALID(sv); 1540148c5f43SAlan Wright ksd = (smbsrv_kstats_t *)ksp->ks_data; 1541148c5f43SAlan Wright /* 1542148c5f43SAlan Wright * Counters 1543148c5f43SAlan Wright */ 1544148c5f43SAlan Wright ksd->ks_nbt_sess = sv->sv_nbt_sess; 1545148c5f43SAlan Wright ksd->ks_tcp_sess = sv->sv_tcp_sess; 1546148c5f43SAlan Wright ksd->ks_users = sv->sv_users; 1547148c5f43SAlan Wright ksd->ks_trees = sv->sv_trees; 1548148c5f43SAlan Wright ksd->ks_files = sv->sv_files; 1549148c5f43SAlan Wright ksd->ks_pipes = sv->sv_pipes; 1550148c5f43SAlan Wright /* 1551148c5f43SAlan Wright * Throughput 1552148c5f43SAlan Wright */ 1553148c5f43SAlan Wright ksd->ks_txb = sv->sv_txb; 1554148c5f43SAlan Wright ksd->ks_rxb = sv->sv_rxb; 1555148c5f43SAlan Wright ksd->ks_nreq = sv->sv_nreq; 1556148c5f43SAlan Wright /* 1557148c5f43SAlan Wright * Busyness 1558148c5f43SAlan Wright */ 1559148c5f43SAlan Wright ksd->ks_maxreqs = sv->sv_cfg.skc_maxworkers; 1560148c5f43SAlan Wright smb_srqueue_update(&sv->sv_srqueue, 1561148c5f43SAlan Wright &ksd->ks_utilization); 1562148c5f43SAlan Wright /* 1563148c5f43SAlan Wright * Latency & Throughput of the requests 1564148c5f43SAlan Wright */ 1565a90cf9f2SGordon Ross smb_dispatch_stats_update(sv, ksd->ks_reqs1, 0, SMB_COM_NUM); 1566a90cf9f2SGordon Ross smb2_dispatch_stats_update(sv, ksd->ks_reqs2, 0, SMB2__NCMDS); 1567faa1795aSjb150015 return (0); 1568faa1795aSjb150015 } 1569148c5f43SAlan Wright if (rw == KSTAT_WRITE) 1570148c5f43SAlan Wright return (EACCES); 1571148c5f43SAlan Wright 1572148c5f43SAlan Wright return (EIO); 1573148c5f43SAlan Wright } 1574faa1795aSjb150015 1575cb174861Sjoyce mcintosh static int 1576cb174861Sjoyce mcintosh smb_server_legacy_kstat_update(kstat_t *ksp, int rw) 1577cb174861Sjoyce mcintosh { 1578cb174861Sjoyce mcintosh smb_server_t *sv; 1579cb174861Sjoyce mcintosh smb_server_legacy_kstat_t *ksd; 1580cb174861Sjoyce mcintosh int rc; 1581cb174861Sjoyce mcintosh 1582cb174861Sjoyce mcintosh switch (rw) { 1583cb174861Sjoyce mcintosh case KSTAT_WRITE: 1584cb174861Sjoyce mcintosh rc = EACCES; 1585cb174861Sjoyce mcintosh break; 1586cb174861Sjoyce mcintosh case KSTAT_READ: 1587cb174861Sjoyce mcintosh if (!smb_server_lookup(&sv)) { 1588cb174861Sjoyce mcintosh ASSERT(MUTEX_HELD(ksp->ks_lock)); 1589cb174861Sjoyce mcintosh ASSERT(sv->sv_legacy_ksp == ksp); 1590cb174861Sjoyce mcintosh ksd = (smb_server_legacy_kstat_t *)ksp->ks_data; 1591cb174861Sjoyce mcintosh ksd->ls_files.value.ui32 = sv->sv_files + sv->sv_pipes; 1592cb174861Sjoyce mcintosh ksd->ls_trees.value.ui32 = sv->sv_trees; 1593cb174861Sjoyce mcintosh ksd->ls_users.value.ui32 = sv->sv_users; 1594cb174861Sjoyce mcintosh smb_server_release(sv); 1595cb174861Sjoyce mcintosh rc = 0; 1596cb174861Sjoyce mcintosh break; 1597cb174861Sjoyce mcintosh } 15982d63d7e2SToomas Soome /* FALLTHROUGH */ 1599cb174861Sjoyce mcintosh default: 1600cb174861Sjoyce mcintosh rc = EIO; 1601cb174861Sjoyce mcintosh break; 1602cb174861Sjoyce mcintosh } 1603cb174861Sjoyce mcintosh return (rc); 1604cb174861Sjoyce mcintosh 1605cb174861Sjoyce mcintosh } 1606cb174861Sjoyce mcintosh 160786184067SGordon Ross int smb_server_shutdown_wait1 = 15; /* seconds */ 160886184067SGordon Ross 1609faa1795aSjb150015 /* 16104163af6aSjose borrego * smb_server_shutdown 1611faa1795aSjb150015 */ 1612faa1795aSjb150015 static void 16139fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States smb_server_shutdown(smb_server_t *sv) 1614faa1795aSjb150015 { 1615811599a4SMatt Barden smb_llist_t *sl = &sv->sv_session_list; 1616811599a4SMatt Barden smb_session_t *session; 161786184067SGordon Ross clock_t time0, time1, time2; 1618811599a4SMatt Barden 16199fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States SMB_SERVER_VALID(sv); 1620faa1795aSjb150015 1621856399cfSGordon Ross /* 162286184067SGordon Ross * Stop the listeners first, so we can't get any more 162386184067SGordon Ross * new sessions while we're trying to shut down. 1624856399cfSGordon Ross */ 1625856399cfSGordon Ross smb_server_listener_stop(&sv->sv_nbt_daemon); 1626856399cfSGordon Ross smb_server_listener_stop(&sv->sv_tcp_daemon); 1627856399cfSGordon Ross 162886184067SGordon Ross /* 162986184067SGordon Ross * Disconnect all of the sessions. This causes all the 163086184067SGordon Ross * smb_server_receiver threads to see a disconnect and 163186184067SGordon Ross * begin tear-down (in parallel) in smb_session_cancel. 163286184067SGordon Ross */ 1633811599a4SMatt Barden smb_llist_enter(sl, RW_READER); 1634811599a4SMatt Barden session = smb_llist_head(sl); 1635811599a4SMatt Barden while (session != NULL) { 1636811599a4SMatt Barden smb_session_disconnect(session); 1637811599a4SMatt Barden session = smb_llist_next(sl, session); 1638811599a4SMatt Barden } 1639811599a4SMatt Barden smb_llist_exit(sl); 1640811599a4SMatt Barden 1641856399cfSGordon Ross /* 1642856399cfSGordon Ross * Wake up any threads we might have blocked. 1643856399cfSGordon Ross * Must precede kdoor_close etc. because those will 1644856399cfSGordon Ross * wait for such threads to get out. 1645856399cfSGordon Ross */ 1646856399cfSGordon Ross smb_event_cancel(sv, 0); 1647856399cfSGordon Ross smb_threshold_wake_all(&sv->sv_ssetup_ct); 1648856399cfSGordon Ross smb_threshold_wake_all(&sv->sv_tcon_ct); 1649856399cfSGordon Ross smb_threshold_wake_all(&sv->sv_opipe_ct); 1650856399cfSGordon Ross 1651811599a4SMatt Barden /* 1652811599a4SMatt Barden * Wait for the session list to empty. 1653811599a4SMatt Barden * (cv_signal in smb_server_destroy_session) 1654811599a4SMatt Barden * 165586184067SGordon Ross * We must wait for all the SMB session readers to finish, or 165686184067SGordon Ross * we could proceed here while there might be worker threads 165786184067SGordon Ross * running in any of those sessions. See smb_session_logoff 165886184067SGordon Ross * for timeouts applied to session tear-down. If this takes 165986184067SGordon Ross * longer than expected, make some noise, and fire a dtrace 166086184067SGordon Ross * probe one might use to investigate. 1661811599a4SMatt Barden */ 166286184067SGordon Ross time0 = ddi_get_lbolt(); 166386184067SGordon Ross time1 = SEC_TO_TICK(smb_server_shutdown_wait1) + time0; 1664811599a4SMatt Barden mutex_enter(&sv->sv_mutex); 1665811599a4SMatt Barden while (sv->sv_session_list.ll_count != 0) { 166686184067SGordon Ross if (cv_timedwait(&sv->sv_cv, &sv->sv_mutex, time1) < 0) { 166786184067SGordon Ross cmn_err(CE_NOTE, "!shutdown waited %d seconds" 166886184067SGordon Ross " with %d sessions still remaining", 166986184067SGordon Ross smb_server_shutdown_wait1, 167086184067SGordon Ross sv->sv_session_list.ll_count); 167186184067SGordon Ross DTRACE_PROBE1(max__wait, smb_server_t *, sv); 1672811599a4SMatt Barden break; 1673811599a4SMatt Barden } 1674811599a4SMatt Barden } 167586184067SGordon Ross while (sv->sv_session_list.ll_count != 0) { 167686184067SGordon Ross cv_wait(&sv->sv_cv, &sv->sv_mutex); 167786184067SGordon Ross } 167886184067SGordon Ross mutex_exit(&sv->sv_mutex); 1679811599a4SMatt Barden 168086184067SGordon Ross time2 = ddi_get_lbolt(); 168186184067SGordon Ross if (time2 > time1) { 168286184067SGordon Ross cmn_err(CE_NOTE, "!shutdown waited %d seconds" 168386184067SGordon Ross " for all sessions to finish", 168486184067SGordon Ross (int)TICK_TO_SEC(time2 - time0)); 168586184067SGordon Ross } 1686811599a4SMatt Barden 16878622ec45SGordon Ross smb_kdoor_close(sv); 1688b819cea2SGordon Ross #ifdef _KERNEL 1689148c5f43SAlan Wright smb_kshare_door_fini(sv->sv_lmshrd); 1690b819cea2SGordon Ross #endif /* _KERNEL */ 16910dcb3379Sjb150015 sv->sv_lmshrd = NULL; 1692b819cea2SGordon Ross 16938622ec45SGordon Ross smb_export_stop(sv); 1694811599a4SMatt Barden smb_kshare_stop(sv); 169586184067SGordon Ross smb_thread_stop(&sv->si_thread_timers); 16968d96b23eSAlan Wright 16974846df9bSKevin Crowe /* 1698811599a4SMatt Barden * Both kshare and the oplock break sub-systems may have 1699811599a4SMatt Barden * taskq jobs on the spcial "server" session, until we've 1700811599a4SMatt Barden * closed all ofiles and stopped the kshare exporter. 1701811599a4SMatt Barden * Now it's safe to destroy the server session, but first 1702811599a4SMatt Barden * wait for any requests on it to finish. Note that for 1703811599a4SMatt Barden * normal sessions, this happens in smb_session_cancel, 1704811599a4SMatt Barden * but that's not called for the server session. 17054846df9bSKevin Crowe */ 17068d94f651SGordon Ross if (sv->sv_rootuser != NULL) { 17078d94f651SGordon Ross smb_user_logoff(sv->sv_rootuser); 17088d94f651SGordon Ross smb_user_release(sv->sv_rootuser); 17098d94f651SGordon Ross sv->sv_rootuser = NULL; 17108d94f651SGordon Ross } 1711811599a4SMatt Barden if (sv->sv_session != NULL) { 1712525641e8SGordon Ross smb_session_cancel_requests(sv->sv_session, NULL, NULL); 17134846df9bSKevin Crowe smb_slist_wait_for_empty(&sv->sv_session->s_req_list); 17144846df9bSKevin Crowe 17158d94f651SGordon Ross /* Just in case import left users and trees */ 17168d94f651SGordon Ross smb_session_logoff(sv->sv_session); 17178d94f651SGordon Ross 1718faa1795aSjb150015 smb_session_delete(sv->sv_session); 1719faa1795aSjb150015 sv->sv_session = NULL; 1720faa1795aSjb150015 } 17218d96b23eSAlan Wright 17224163af6aSjose borrego if (sv->sv_receiver_pool != NULL) { 17234163af6aSjose borrego taskq_destroy(sv->sv_receiver_pool); 17244163af6aSjose borrego sv->sv_receiver_pool = NULL; 17254163af6aSjose borrego } 17264163af6aSjose borrego 17274163af6aSjose borrego if (sv->sv_worker_pool != NULL) { 17284163af6aSjose borrego taskq_destroy(sv->sv_worker_pool); 17294163af6aSjose borrego sv->sv_worker_pool = NULL; 17308d96b23eSAlan Wright } 17318622ec45SGordon Ross 1732*e515d096SGordon Ross if (sv->sv_notify_pool != NULL) { 1733*e515d096SGordon Ross taskq_destroy(sv->sv_notify_pool); 1734*e515d096SGordon Ross sv->sv_notify_pool = NULL; 1735*e515d096SGordon Ross } 1736*e515d096SGordon Ross 173786184067SGordon Ross /* 173886184067SGordon Ross * Clean out any durable handles. After this we should 173986184067SGordon Ross * have no ofiles remaining (and no more oplock breaks). 174086184067SGordon Ross */ 174186184067SGordon Ross smb2_dh_shutdown(sv); 174286184067SGordon Ross 17438622ec45SGordon Ross smb_server_fsop_stop(sv); 17445d8538b6SGordon Ross 17455d8538b6SGordon Ross #ifdef _KERNEL 17465d8538b6SGordon Ross if (sv->sv_proc_p != NULL) { 17475d8538b6SGordon Ross smb_server_delproc(sv); 17485d8538b6SGordon Ross } 17495d8538b6SGordon Ross #endif 1750faa1795aSjb150015 } 1751faa1795aSjb150015 17524163af6aSjose borrego /* 17534163af6aSjose borrego * smb_server_listener_init 17544163af6aSjose borrego * 17554163af6aSjose borrego * Initializes listener contexts. 17564163af6aSjose borrego */ 17574163af6aSjose borrego static void 17584163af6aSjose borrego smb_server_listener_init( 1759faa1795aSjb150015 smb_server_t *sv, 1760faa1795aSjb150015 smb_listener_daemon_t *ld, 17614163af6aSjose borrego char *name, 1762faa1795aSjb150015 in_port_t port, 17634163af6aSjose borrego int family) 1764faa1795aSjb150015 { 17654163af6aSjose borrego ASSERT(ld->ld_magic != SMB_LISTENER_MAGIC); 1766faa1795aSjb150015 17674163af6aSjose borrego bzero(ld, sizeof (*ld)); 1768faa1795aSjb150015 17694163af6aSjose borrego ld->ld_sv = sv; 17704163af6aSjose borrego ld->ld_family = family; 17714163af6aSjose borrego ld->ld_port = port; 17724163af6aSjose borrego 17737f667e74Sjose borrego if (family == AF_INET) { 17747f667e74Sjose borrego ld->ld_sin.sin_family = (uint32_t)family; 1775faa1795aSjb150015 ld->ld_sin.sin_port = htons(port); 1776faa1795aSjb150015 ld->ld_sin.sin_addr.s_addr = htonl(INADDR_ANY); 17777f667e74Sjose borrego } else { 17787f667e74Sjose borrego ld->ld_sin6.sin6_family = (uint32_t)family; 17797f667e74Sjose borrego ld->ld_sin6.sin6_port = htons(port); 17807f667e74Sjose borrego (void) memset(&ld->ld_sin6.sin6_addr.s6_addr, 0, 17817f667e74Sjose borrego sizeof (ld->ld_sin6.sin6_addr.s6_addr)); 17827f667e74Sjose borrego } 1783faa1795aSjb150015 178408344b29SGordon Ross smb_thread_init(&ld->ld_thread, name, smb_server_listener, ld, 17855d8538b6SGordon Ross smbsrv_listen_pri, sv); 17864163af6aSjose borrego ld->ld_magic = SMB_LISTENER_MAGIC; 17874163af6aSjose borrego } 17884163af6aSjose borrego 17894163af6aSjose borrego /* 17904163af6aSjose borrego * smb_server_listener_destroy 17914163af6aSjose borrego * 17924163af6aSjose borrego * Destroyes listener contexts. 17934163af6aSjose borrego */ 17944163af6aSjose borrego static void 17954163af6aSjose borrego smb_server_listener_destroy(smb_listener_daemon_t *ld) 17964163af6aSjose borrego { 179783d2dfe6SGordon Ross /* 179883d2dfe6SGordon Ross * Note that if startup fails early, we can legitimately 179983d2dfe6SGordon Ross * get here with an all-zeros object. 180083d2dfe6SGordon Ross */ 180183d2dfe6SGordon Ross if (ld->ld_magic == 0) 180283d2dfe6SGordon Ross return; 180383d2dfe6SGordon Ross 18044163af6aSjose borrego SMB_LISTENER_VALID(ld); 18054163af6aSjose borrego ASSERT(ld->ld_so == NULL); 18064163af6aSjose borrego smb_thread_destroy(&ld->ld_thread); 18074163af6aSjose borrego ld->ld_magic = 0; 18084163af6aSjose borrego } 18094163af6aSjose borrego 18104163af6aSjose borrego /* 18114163af6aSjose borrego * smb_server_listener_start 18124163af6aSjose borrego * 18134163af6aSjose borrego * Starts the listener associated with the context passed in. 18144163af6aSjose borrego * 18154163af6aSjose borrego * Return: 0 Success 18164163af6aSjose borrego * not 0 Failure 18174163af6aSjose borrego */ 18184163af6aSjose borrego static int 18194163af6aSjose borrego smb_server_listener_start(smb_listener_daemon_t *ld) 18204163af6aSjose borrego { 18214163af6aSjose borrego int rc; 18224163af6aSjose borrego uint32_t on; 18234163af6aSjose borrego uint32_t off; 18244163af6aSjose borrego 18254163af6aSjose borrego SMB_LISTENER_VALID(ld); 18264163af6aSjose borrego 18274163af6aSjose borrego if (ld->ld_so != NULL) 18284163af6aSjose borrego return (EINVAL); 18294163af6aSjose borrego 18304163af6aSjose borrego ld->ld_so = smb_socreate(ld->ld_family, SOCK_STREAM, 0); 18319fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States if (ld->ld_so == NULL) { 18324163af6aSjose borrego cmn_err(CE_WARN, "port %d: socket create failed", ld->ld_port); 18339fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States return (ENOMEM); 18349fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States } 18359fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 18369fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States off = 0; 18370f1702c5SYu Xiangning (void) ksocket_setsockopt(ld->ld_so, SOL_SOCKET, 1838fc724630SAlan Wright SO_MAC_EXEMPT, &off, sizeof (off), CRED()); 18399fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 18409fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States on = 1; 1841fc724630SAlan Wright (void) ksocket_setsockopt(ld->ld_so, SOL_SOCKET, 1842fc724630SAlan Wright SO_REUSEADDR, &on, sizeof (on), CRED()); 1843fc724630SAlan Wright 18444163af6aSjose borrego if (ld->ld_family == AF_INET) { 18450f1702c5SYu Xiangning rc = ksocket_bind(ld->ld_so, 18460f1702c5SYu Xiangning (struct sockaddr *)&ld->ld_sin, 18470f1702c5SYu Xiangning sizeof (ld->ld_sin), CRED()); 18487f667e74Sjose borrego } else { 18497f667e74Sjose borrego rc = ksocket_bind(ld->ld_so, 18507f667e74Sjose borrego (struct sockaddr *)&ld->ld_sin6, 18517f667e74Sjose borrego sizeof (ld->ld_sin6), CRED()); 18527f667e74Sjose borrego } 18539fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 18549fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States if (rc != 0) { 18554163af6aSjose borrego cmn_err(CE_WARN, "port %d: bind failed", ld->ld_port); 18569fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States return (rc); 18579fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States } 18589fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 18590f1702c5SYu Xiangning rc = ksocket_listen(ld->ld_so, 20, CRED()); 1860faa1795aSjb150015 if (rc < 0) { 18614163af6aSjose borrego cmn_err(CE_WARN, "port %d: listen failed", ld->ld_port); 1862faa1795aSjb150015 return (rc); 1863faa1795aSjb150015 } 18644163af6aSjose borrego 18654163af6aSjose borrego ksocket_hold(ld->ld_so); 18664163af6aSjose borrego rc = smb_thread_start(&ld->ld_thread); 18674163af6aSjose borrego if (rc != 0) { 18684163af6aSjose borrego ksocket_rele(ld->ld_so); 18694163af6aSjose borrego cmn_err(CE_WARN, "port %d: listener failed to start", 18704163af6aSjose borrego ld->ld_port); 18714163af6aSjose borrego return (rc); 1872faa1795aSjb150015 } 18734163af6aSjose borrego return (0); 18744163af6aSjose borrego } 18754163af6aSjose borrego 18764163af6aSjose borrego /* 18774163af6aSjose borrego * smb_server_listener_stop 18784163af6aSjose borrego * 18794163af6aSjose borrego * Stops the listener associated with the context passed in. 18804163af6aSjose borrego */ 18814163af6aSjose borrego static void 18824163af6aSjose borrego smb_server_listener_stop(smb_listener_daemon_t *ld) 18834163af6aSjose borrego { 18844163af6aSjose borrego SMB_LISTENER_VALID(ld); 18854163af6aSjose borrego 18864163af6aSjose borrego if (ld->ld_so != NULL) { 18874163af6aSjose borrego smb_soshutdown(ld->ld_so); 18884163af6aSjose borrego smb_sodestroy(ld->ld_so); 18894163af6aSjose borrego smb_thread_stop(&ld->ld_thread); 18904163af6aSjose borrego ld->ld_so = NULL; 18914163af6aSjose borrego } 18924163af6aSjose borrego } 18934163af6aSjose borrego 18944163af6aSjose borrego /* 18954163af6aSjose borrego * smb_server_listener 18964163af6aSjose borrego * 18974163af6aSjose borrego * Entry point of the listeners. 18984163af6aSjose borrego */ 18994163af6aSjose borrego static void 19004163af6aSjose borrego smb_server_listener(smb_thread_t *thread, void *arg) 19014163af6aSjose borrego { 19024163af6aSjose borrego _NOTE(ARGUNUSED(thread)) 19034163af6aSjose borrego smb_listener_daemon_t *ld; 19044163af6aSjose borrego ksocket_t s_so; 19054163af6aSjose borrego int on; 19064163af6aSjose borrego int txbuf_size; 19074163af6aSjose borrego 19084163af6aSjose borrego ld = (smb_listener_daemon_t *)arg; 19094163af6aSjose borrego 19104163af6aSjose borrego SMB_LISTENER_VALID(ld); 1911faa1795aSjb150015 1912faa1795aSjb150015 DTRACE_PROBE1(so__wait__accept, struct sonode *, ld->ld_so); 1913faa1795aSjb150015 19149a244c8eSGordon Ross while (smb_thread_continue_nowait(&ld->ld_thread) && 19159a244c8eSGordon Ross ld->ld_sv->sv_state != SMB_SERVER_STATE_STOPPING) { 191641bd8510Skcrowenex int ret = ksocket_accept(ld->ld_so, NULL, NULL, &s_so, CRED()); 191741bd8510Skcrowenex 191841bd8510Skcrowenex switch (ret) { 191941bd8510Skcrowenex case 0: 192041bd8510Skcrowenex break; 192141bd8510Skcrowenex case ECONNABORTED: 192241bd8510Skcrowenex continue; 19239a244c8eSGordon Ross 192441bd8510Skcrowenex case EINTR: 19259a244c8eSGordon Ross case EBADF: 19269a244c8eSGordon Ross case ENOTSOCK: 19279a244c8eSGordon Ross /* These are normal during shutdown. Silence. */ 19289a244c8eSGordon Ross if (ld->ld_sv->sv_state == SMB_SERVER_STATE_STOPPING) 192941bd8510Skcrowenex goto out; 19309a244c8eSGordon Ross /* FALLTHROUGH */ 193141bd8510Skcrowenex default: 193241bd8510Skcrowenex cmn_err(CE_WARN, 19337b072888SToomas Soome "smb_server_listener: ksocket_accept failed (%d)", 193441bd8510Skcrowenex ret); 19359a244c8eSGordon Ross /* avoid a tight CPU-burn loop here */ 19369a244c8eSGordon Ross delay(MSEC_TO_TICK(10)); 19379a244c8eSGordon Ross continue; 193841bd8510Skcrowenex } 193941bd8510Skcrowenex 1940faa1795aSjb150015 DTRACE_PROBE1(so__accept, struct sonode *, s_so); 1941faa1795aSjb150015 19429fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States on = 1; 19439fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States (void) ksocket_setsockopt(s_so, IPPROTO_TCP, TCP_NODELAY, 19449fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States &on, sizeof (on), CRED()); 19459fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 19469fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States on = 1; 19479fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States (void) ksocket_setsockopt(s_so, SOL_SOCKET, SO_KEEPALIVE, 19489fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States &on, sizeof (on), CRED()); 19499fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 19509fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States txbuf_size = 128*1024; 19510f1702c5SYu Xiangning (void) ksocket_setsockopt(s_so, SOL_SOCKET, SO_SNDBUF, 19529fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States (const void *)&txbuf_size, sizeof (txbuf_size), CRED()); 19539fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 1954faa1795aSjb150015 /* 1955faa1795aSjb150015 * Create a session for this connection. 1956faa1795aSjb150015 */ 19574163af6aSjose borrego smb_server_create_session(ld, s_so); 1958faa1795aSjb150015 } 195941bd8510Skcrowenex out: 19604163af6aSjose borrego ksocket_rele(ld->ld_so); 1961faa1795aSjb150015 } 19629fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 19634163af6aSjose borrego /* 19644163af6aSjose borrego * smb_server_receiver 19654163af6aSjose borrego * 19664163af6aSjose borrego * Entry point of the receiver threads. 1967811599a4SMatt Barden * Also does cleanup when socket disconnected. 19684163af6aSjose borrego */ 19699fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States static void 19704163af6aSjose borrego smb_server_receiver(void *arg) 19719fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States { 19724163af6aSjose borrego smb_session_t *session; 1973faa1795aSjb150015 1974811599a4SMatt Barden session = (smb_session_t *)arg; 1975811599a4SMatt Barden 1976811599a4SMatt Barden /* We stay in here until socket disconnect. */ 19774163af6aSjose borrego smb_session_receiver(session); 1978811599a4SMatt Barden 1979811599a4SMatt Barden smb_server_destroy_session(session); 1980faa1795aSjb150015 } 1981faa1795aSjb150015 1982faa1795aSjb150015 /* 1983faa1795aSjb150015 * smb_server_lookup 1984faa1795aSjb150015 * 19858622ec45SGordon Ross * This function finds the server associated with the zone of the 19868622ec45SGordon Ross * caller. Note: requires a fix in the dynamic taskq code: 19878622ec45SGordon Ross * 1501 taskq_create_proc ... TQ_DYNAMIC puts tasks in p0 1988faa1795aSjb150015 */ 19894846df9bSKevin Crowe int 1990faa1795aSjb150015 smb_server_lookup(smb_server_t **psv) 1991faa1795aSjb150015 { 1992faa1795aSjb150015 zoneid_t zid; 1993faa1795aSjb150015 smb_server_t *sv; 1994faa1795aSjb150015 1995faa1795aSjb150015 zid = getzoneid(); 1996faa1795aSjb150015 1997faa1795aSjb150015 smb_llist_enter(&smb_servers, RW_READER); 1998faa1795aSjb150015 sv = smb_llist_head(&smb_servers); 1999faa1795aSjb150015 while (sv) { 20009fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States SMB_SERVER_VALID(sv); 2001faa1795aSjb150015 if (sv->sv_zid == zid) { 2002faa1795aSjb150015 mutex_enter(&sv->sv_mutex); 2003faa1795aSjb150015 if (sv->sv_state != SMB_SERVER_STATE_DELETING) { 2004faa1795aSjb150015 sv->sv_refcnt++; 2005faa1795aSjb150015 mutex_exit(&sv->sv_mutex); 2006faa1795aSjb150015 smb_llist_exit(&smb_servers); 2007faa1795aSjb150015 *psv = sv; 2008faa1795aSjb150015 return (0); 2009faa1795aSjb150015 } 2010faa1795aSjb150015 mutex_exit(&sv->sv_mutex); 2011faa1795aSjb150015 break; 2012faa1795aSjb150015 } 2013faa1795aSjb150015 sv = smb_llist_next(&smb_servers, sv); 2014faa1795aSjb150015 } 2015faa1795aSjb150015 smb_llist_exit(&smb_servers); 2016faa1795aSjb150015 return (EPERM); 2017faa1795aSjb150015 } 2018faa1795aSjb150015 2019faa1795aSjb150015 /* 2020faa1795aSjb150015 * smb_server_release 2021faa1795aSjb150015 * 2022faa1795aSjb150015 * This function decrements the reference count of the server and signals its 2023faa1795aSjb150015 * condition variable if the state of the server is SMB_SERVER_STATE_DELETING. 2024faa1795aSjb150015 */ 20254846df9bSKevin Crowe void 2026faa1795aSjb150015 smb_server_release(smb_server_t *sv) 2027faa1795aSjb150015 { 20289fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States SMB_SERVER_VALID(sv); 2029faa1795aSjb150015 2030faa1795aSjb150015 mutex_enter(&sv->sv_mutex); 2031faa1795aSjb150015 ASSERT(sv->sv_refcnt); 2032faa1795aSjb150015 sv->sv_refcnt--; 2033faa1795aSjb150015 if ((sv->sv_refcnt == 0) && (sv->sv_state == SMB_SERVER_STATE_DELETING)) 2034faa1795aSjb150015 cv_signal(&sv->sv_cv); 2035faa1795aSjb150015 mutex_exit(&sv->sv_mutex); 2036faa1795aSjb150015 } 2037faa1795aSjb150015 20381fcced4cSJordan Brown /* 203997264293SGordon Ross * smb_server_lookup_user 204097264293SGordon Ross * 204197264293SGordon Ross * Find an smb_user by its user_id 204297264293SGordon Ross * Optional ssn_id (if non-zero) restricts search to a specific session. 204397264293SGordon Ross * 204497264293SGordon Ross * Returns smb_user_t * held. Caller must smb_user_rele(user) 204597264293SGordon Ross * Returns NULL if not found. 204697264293SGordon Ross */ 204797264293SGordon Ross smb_user_t * 204897264293SGordon Ross smb_server_lookup_user(smb_server_t *sv, uint64_t ssn_id, uint64_t user_id) 204997264293SGordon Ross { 205097264293SGordon Ross smb_llist_t *slist = &sv->sv_session_list; 205197264293SGordon Ross smb_session_t *sn; 205297264293SGordon Ross smb_user_t *user = NULL; 205397264293SGordon Ross 205497264293SGordon Ross smb_llist_enter(slist, RW_READER); 205597264293SGordon Ross 205697264293SGordon Ross for (sn = smb_llist_head(slist); 205797264293SGordon Ross sn != NULL && user == NULL; 205897264293SGordon Ross sn = smb_llist_next(slist, sn)) { 205997264293SGordon Ross SMB_SESSION_VALID(sn); 206097264293SGordon Ross 206197264293SGordon Ross if (ssn_id != 0 && ssn_id != sn->s_kid) 206297264293SGordon Ross continue; 206397264293SGordon Ross if (sn->s_state != SMB_SESSION_STATE_NEGOTIATED) 206497264293SGordon Ross continue; 206597264293SGordon Ross 206697264293SGordon Ross user = smb_session_lookup_ssnid(sn, user_id); 206797264293SGordon Ross } 206897264293SGordon Ross smb_llist_exit(slist); 206997264293SGordon Ross 207097264293SGordon Ross return (user); 207197264293SGordon Ross } 207297264293SGordon Ross 207397264293SGordon Ross /* 20741fcced4cSJordan Brown * Enumerate the users associated with a session list. 20751fcced4cSJordan Brown */ 20761fcced4cSJordan Brown static void 20778d94f651SGordon Ross smb_server_enum_users(smb_server_t *sv, smb_svcenum_t *svcenum) 2078faa1795aSjb150015 { 20798d94f651SGordon Ross smb_llist_t *ll = &sv->sv_session_list; 20801fcced4cSJordan Brown smb_session_t *sn; 2081faa1795aSjb150015 smb_llist_t *ulist; 20821fcced4cSJordan Brown smb_user_t *user; 208329bd2886SAlan Wright int rc = 0; 2084faa1795aSjb150015 20854163af6aSjose borrego smb_llist_enter(ll, RW_READER); 20864163af6aSjose borrego sn = smb_llist_head(ll); 20871fcced4cSJordan Brown 20881fcced4cSJordan Brown while (sn != NULL) { 20894163af6aSjose borrego SMB_SESSION_VALID(sn); 2090faa1795aSjb150015 ulist = &sn->s_user_list; 2091faa1795aSjb150015 smb_llist_enter(ulist, RW_READER); 2092faa1795aSjb150015 user = smb_llist_head(ulist); 20931fcced4cSJordan Brown 20941fcced4cSJordan Brown while (user != NULL) { 20951fcced4cSJordan Brown if (smb_user_hold(user)) { 20961fcced4cSJordan Brown rc = smb_user_enum(user, svcenum); 20971fcced4cSJordan Brown smb_user_release(user); 20983b13a1efSThomas Keiser if (rc != 0) 20993b13a1efSThomas Keiser break; 2100faa1795aSjb150015 } 21011fcced4cSJordan Brown 2102faa1795aSjb150015 user = smb_llist_next(ulist, user); 2103faa1795aSjb150015 } 21041fcced4cSJordan Brown 21051fcced4cSJordan Brown smb_llist_exit(ulist); 21061fcced4cSJordan Brown 21071fcced4cSJordan Brown if (rc != 0) 21081fcced4cSJordan Brown break; 21091fcced4cSJordan Brown 21104163af6aSjose borrego sn = smb_llist_next(ll, sn); 21111fcced4cSJordan Brown } 21121fcced4cSJordan Brown 21134163af6aSjose borrego smb_llist_exit(ll); 21141fcced4cSJordan Brown } 21151fcced4cSJordan Brown 21161fcced4cSJordan Brown /* 21173b13a1efSThomas Keiser * Enumerate the trees/files associated with a session list. 21183b13a1efSThomas Keiser */ 21193b13a1efSThomas Keiser static void 21208d94f651SGordon Ross smb_server_enum_trees(smb_server_t *sv, smb_svcenum_t *svcenum) 21213b13a1efSThomas Keiser { 21228d94f651SGordon Ross smb_llist_t *ll = &sv->sv_session_list; 21233b13a1efSThomas Keiser smb_session_t *sn; 21243b13a1efSThomas Keiser smb_llist_t *tlist; 21253b13a1efSThomas Keiser smb_tree_t *tree; 21263b13a1efSThomas Keiser int rc = 0; 21273b13a1efSThomas Keiser 21283b13a1efSThomas Keiser smb_llist_enter(ll, RW_READER); 21293b13a1efSThomas Keiser sn = smb_llist_head(ll); 21303b13a1efSThomas Keiser 21313b13a1efSThomas Keiser while (sn != NULL) { 21323b13a1efSThomas Keiser SMB_SESSION_VALID(sn); 21333b13a1efSThomas Keiser tlist = &sn->s_tree_list; 21343b13a1efSThomas Keiser smb_llist_enter(tlist, RW_READER); 21353b13a1efSThomas Keiser tree = smb_llist_head(tlist); 21363b13a1efSThomas Keiser 21373b13a1efSThomas Keiser while (tree != NULL) { 21383b13a1efSThomas Keiser if (smb_tree_hold(tree)) { 21393b13a1efSThomas Keiser rc = smb_tree_enum(tree, svcenum); 21403b13a1efSThomas Keiser smb_tree_release(tree); 21413b13a1efSThomas Keiser if (rc != 0) 21423b13a1efSThomas Keiser break; 21433b13a1efSThomas Keiser } 21443b13a1efSThomas Keiser 21453b13a1efSThomas Keiser tree = smb_llist_next(tlist, tree); 21463b13a1efSThomas Keiser } 21473b13a1efSThomas Keiser 21483b13a1efSThomas Keiser smb_llist_exit(tlist); 21493b13a1efSThomas Keiser 21503b13a1efSThomas Keiser if (rc != 0) 21513b13a1efSThomas Keiser break; 21523b13a1efSThomas Keiser 21533b13a1efSThomas Keiser sn = smb_llist_next(ll, sn); 21543b13a1efSThomas Keiser } 21553b13a1efSThomas Keiser 21563b13a1efSThomas Keiser smb_llist_exit(ll); 21573b13a1efSThomas Keiser } 21583b13a1efSThomas Keiser 21593b13a1efSThomas Keiser /* 21601fcced4cSJordan Brown * Disconnect sessions associated with the specified client and username. 21611fcced4cSJordan Brown * Empty strings are treated as wildcards. 21621fcced4cSJordan Brown */ 21631fcced4cSJordan Brown static int 21648d94f651SGordon Ross smb_server_session_disconnect(smb_server_t *sv, 21651fcced4cSJordan Brown const char *client, const char *name) 21661fcced4cSJordan Brown { 21678d94f651SGordon Ross smb_llist_t *ll = &sv->sv_session_list; 21681fcced4cSJordan Brown smb_session_t *sn; 21691fcced4cSJordan Brown smb_llist_t *ulist; 21701fcced4cSJordan Brown smb_user_t *user; 21711fcced4cSJordan Brown int count = 0; 21721fcced4cSJordan Brown 21734163af6aSjose borrego smb_llist_enter(ll, RW_READER); 21741fcced4cSJordan Brown 2175811599a4SMatt Barden for (sn = smb_llist_head(ll); 2176811599a4SMatt Barden sn != NULL; 2177811599a4SMatt Barden sn = smb_llist_next(ll, sn)) { 21784163af6aSjose borrego SMB_SESSION_VALID(sn); 21791fcced4cSJordan Brown 2180811599a4SMatt Barden if (*client != '\0' && !smb_session_isclient(sn, client)) 21811fcced4cSJordan Brown continue; 21821fcced4cSJordan Brown 21831fcced4cSJordan Brown ulist = &sn->s_user_list; 21841fcced4cSJordan Brown smb_llist_enter(ulist, RW_READER); 21851fcced4cSJordan Brown 2186811599a4SMatt Barden for (user = smb_llist_head(ulist); 2187811599a4SMatt Barden user != NULL; 2188811599a4SMatt Barden user = smb_llist_next(ulist, user)) { 21891fcced4cSJordan Brown 2190811599a4SMatt Barden if (smb_user_hold(user)) { 2191896d9552SGordon Ross 2192896d9552SGordon Ross if (*name == '\0' || 2193896d9552SGordon Ross smb_user_namecmp(user, name)) { 2194811599a4SMatt Barden smb_user_logoff(user); 2195811599a4SMatt Barden count++; 21961fcced4cSJordan Brown } 2197896d9552SGordon Ross 2198896d9552SGordon Ross smb_user_release(user); 2199896d9552SGordon Ross } 22001fcced4cSJordan Brown } 22011fcced4cSJordan Brown 2202faa1795aSjb150015 smb_llist_exit(ulist); 2203faa1795aSjb150015 } 22041fcced4cSJordan Brown 22054163af6aSjose borrego smb_llist_exit(ll); 22061fcced4cSJordan Brown return (count); 22071fcced4cSJordan Brown } 22081fcced4cSJordan Brown 22091fcced4cSJordan Brown /* 22101fcced4cSJordan Brown * Close a file by its unique id. 22111fcced4cSJordan Brown */ 22121fcced4cSJordan Brown static int 22138d94f651SGordon Ross smb_server_fclose(smb_server_t *sv, uint32_t uniqid) 22141fcced4cSJordan Brown { 22158d94f651SGordon Ross smb_llist_t *ll; 22161fcced4cSJordan Brown smb_session_t *sn; 22173b13a1efSThomas Keiser smb_llist_t *tlist; 22183b13a1efSThomas Keiser smb_tree_t *tree; 22191fcced4cSJordan Brown int rc = ENOENT; 22201fcced4cSJordan Brown 22218d94f651SGordon Ross ll = &sv->sv_session_list; 22224163af6aSjose borrego smb_llist_enter(ll, RW_READER); 22234163af6aSjose borrego sn = smb_llist_head(ll); 22241fcced4cSJordan Brown 22251fcced4cSJordan Brown while ((sn != NULL) && (rc == ENOENT)) { 22264163af6aSjose borrego SMB_SESSION_VALID(sn); 22273b13a1efSThomas Keiser tlist = &sn->s_tree_list; 22283b13a1efSThomas Keiser smb_llist_enter(tlist, RW_READER); 22293b13a1efSThomas Keiser tree = smb_llist_head(tlist); 22301fcced4cSJordan Brown 22313b13a1efSThomas Keiser while ((tree != NULL) && (rc == ENOENT)) { 22323b13a1efSThomas Keiser if (smb_tree_hold(tree)) { 22333b13a1efSThomas Keiser rc = smb_tree_fclose(tree, uniqid); 22343b13a1efSThomas Keiser smb_tree_release(tree); 22351fcced4cSJordan Brown } 22361fcced4cSJordan Brown 22373b13a1efSThomas Keiser tree = smb_llist_next(tlist, tree); 22381fcced4cSJordan Brown } 22391fcced4cSJordan Brown 22403b13a1efSThomas Keiser smb_llist_exit(tlist); 22414163af6aSjose borrego sn = smb_llist_next(ll, sn); 22421fcced4cSJordan Brown } 22431fcced4cSJordan Brown 22444163af6aSjose borrego smb_llist_exit(ll); 22451fcced4cSJordan Brown return (rc); 2246faa1795aSjb150015 } 2247faa1795aSjb150015 2248811599a4SMatt Barden /* 2249811599a4SMatt Barden * This is used by SMB2 session setup to logoff a previous session, 2250811599a4SMatt Barden * so it can force a logoff that we haven't noticed yet. 2251811599a4SMatt Barden * This is not called frequently, so we just walk the list of 2252811599a4SMatt Barden * connections searching for the user. 22531baeef30SPrashanth Badari * 22541baeef30SPrashanth Badari * Note that this must wait for any durable handles (ofiles) 22551baeef30SPrashanth Badari * owned by this user to become "orphaned", so that a reconnect 22561baeef30SPrashanth Badari * that may immediately follow can find and use such ofiles. 2257811599a4SMatt Barden */ 2258811599a4SMatt Barden void 2259811599a4SMatt Barden smb_server_logoff_ssnid(smb_request_t *sr, uint64_t ssnid) 2260811599a4SMatt Barden { 2261811599a4SMatt Barden smb_server_t *sv = sr->sr_server; 2262811599a4SMatt Barden smb_llist_t *sess_list; 2263811599a4SMatt Barden smb_session_t *sess; 22641baeef30SPrashanth Badari smb_user_t *user = NULL; 22650c5f22c1SGordon Ross boolean_t do_logoff = B_FALSE; 22661baeef30SPrashanth Badari 22671baeef30SPrashanth Badari SMB_SERVER_VALID(sv); 2268811599a4SMatt Barden 2269811599a4SMatt Barden if (sv->sv_state != SMB_SERVER_STATE_RUNNING) 2270811599a4SMatt Barden return; 2271811599a4SMatt Barden 2272811599a4SMatt Barden sess_list = &sv->sv_session_list; 2273811599a4SMatt Barden smb_llist_enter(sess_list, RW_READER); 2274811599a4SMatt Barden 2275811599a4SMatt Barden for (sess = smb_llist_head(sess_list); 2276811599a4SMatt Barden sess != NULL; 2277811599a4SMatt Barden sess = smb_llist_next(sess_list, sess)) { 2278811599a4SMatt Barden 2279811599a4SMatt Barden SMB_SESSION_VALID(sess); 2280811599a4SMatt Barden 2281811599a4SMatt Barden if (sess->dialect < SMB_VERS_2_BASE) 2282811599a4SMatt Barden continue; 2283811599a4SMatt Barden 22841baeef30SPrashanth Badari switch (sess->s_state) { 22851baeef30SPrashanth Badari case SMB_SESSION_STATE_NEGOTIATED: 22861baeef30SPrashanth Badari case SMB_SESSION_STATE_TERMINATED: 22871baeef30SPrashanth Badari case SMB_SESSION_STATE_DISCONNECTED: 22881baeef30SPrashanth Badari break; 22891baeef30SPrashanth Badari default: 2290811599a4SMatt Barden continue; 2291811599a4SMatt Barden } 2292811599a4SMatt Barden 22931baeef30SPrashanth Badari /* 22941baeef30SPrashanth Badari * Normal situation is to find a LOGGED_ON user. 22951baeef30SPrashanth Badari */ 22961baeef30SPrashanth Badari user = smb_session_lookup_uid_st(sess, ssnid, 0, 22971baeef30SPrashanth Badari SMB_USER_STATE_LOGGED_ON); 22981baeef30SPrashanth Badari if (user != NULL) { 22991baeef30SPrashanth Badari if (smb_is_same_user(user->u_cred, sr->user_cr)) { 23000c5f22c1SGordon Ross do_logoff = B_TRUE; 23011baeef30SPrashanth Badari break; 23021baeef30SPrashanth Badari } 2303811599a4SMatt Barden smb_user_release(user); 23041baeef30SPrashanth Badari user = NULL; 23051baeef30SPrashanth Badari } 2306811599a4SMatt Barden 2307811599a4SMatt Barden /* 23081baeef30SPrashanth Badari * If we raced with disconnect, may find LOGGING_OFF, 23091baeef30SPrashanth Badari * in which case we want to just wait for it. 2310811599a4SMatt Barden */ 23111baeef30SPrashanth Badari user = smb_session_lookup_uid_st(sess, ssnid, 0, 23121baeef30SPrashanth Badari SMB_USER_STATE_LOGGING_OFF); 23131baeef30SPrashanth Badari if (user != NULL) { 23141baeef30SPrashanth Badari if (smb_is_same_user(user->u_cred, sr->user_cr)) 23151baeef30SPrashanth Badari break; 23161baeef30SPrashanth Badari smb_user_release(user); 23171baeef30SPrashanth Badari user = NULL; 23181baeef30SPrashanth Badari } 2319811599a4SMatt Barden } 2320811599a4SMatt Barden 2321811599a4SMatt Barden smb_llist_exit(sess_list); 23221baeef30SPrashanth Badari 23230c5f22c1SGordon Ross /* 23240c5f22c1SGordon Ross * Note that smb_user_logoff() can block for a while if 23250c5f22c1SGordon Ross * smb_session_disconnect_owned_trees, smb_ofile_close_all 23260c5f22c1SGordon Ross * ends up blocked on locks held by running requests. 23270c5f22c1SGordon Ross * Do that while not holding the session list rwlock. 23280c5f22c1SGordon Ross */ 23291baeef30SPrashanth Badari if (user != NULL) { 23300c5f22c1SGordon Ross if (do_logoff) { 23310c5f22c1SGordon Ross /* Treat this as if we lost the connection */ 23320c5f22c1SGordon Ross user->preserve_opens = SMB2_DH_PRESERVE_SOME; 23330c5f22c1SGordon Ross smb_user_logoff(user); 23340c5f22c1SGordon Ross } 23350c5f22c1SGordon Ross 23361baeef30SPrashanth Badari /* 23371baeef30SPrashanth Badari * Wait for durable handles to be orphaned. 23381baeef30SPrashanth Badari * Note: not holding the sess list rwlock. 23391baeef30SPrashanth Badari */ 23401baeef30SPrashanth Badari smb_user_wait_trees(user); 23411baeef30SPrashanth Badari 23421baeef30SPrashanth Badari /* 23431baeef30SPrashanth Badari * Could be doing the last release on a user below, 23441baeef30SPrashanth Badari * which can leave work on the delete queues for 23451baeef30SPrashanth Badari * s_user_list or s_tree_list so flush those. 23461baeef30SPrashanth Badari * Must hold the session list after the user release 23471baeef30SPrashanth Badari * so that the session can't go away while we flush. 23481baeef30SPrashanth Badari */ 23491baeef30SPrashanth Badari smb_llist_enter(sess_list, RW_READER); 23501baeef30SPrashanth Badari 23511baeef30SPrashanth Badari sess = user->u_session; 23521baeef30SPrashanth Badari smb_user_release(user); 23531baeef30SPrashanth Badari 23541baeef30SPrashanth Badari smb_llist_flush(&sess->s_tree_list); 23551baeef30SPrashanth Badari smb_llist_flush(&sess->s_user_list); 23561baeef30SPrashanth Badari 23571baeef30SPrashanth Badari smb_llist_exit(sess_list); 23581baeef30SPrashanth Badari } 2359811599a4SMatt Barden } 2360811599a4SMatt Barden 236112b65585SGordon Ross /* See also: libsmb smb_kmod_setcfg */ 2362faa1795aSjb150015 static void 236329bd2886SAlan Wright smb_server_store_cfg(smb_server_t *sv, smb_ioc_cfg_t *ioc) 2364faa1795aSjb150015 { 236529bd2886SAlan Wright if (ioc->maxconnections == 0) 236629bd2886SAlan Wright ioc->maxconnections = 0xFFFFFFFF; 2367faa1795aSjb150015 23681160dcf7SMatt Barden if (ioc->encrypt == SMB_CONFIG_REQUIRED && 23691160dcf7SMatt Barden ioc->max_protocol < SMB_VERS_3_0) { 23701160dcf7SMatt Barden cmn_err(CE_WARN, "Server set to require encryption; " 23711160dcf7SMatt Barden "forcing max_protocol to 3.0"); 23721160dcf7SMatt Barden ioc->max_protocol = SMB_VERS_3_0; 23731160dcf7SMatt Barden } 237429bd2886SAlan Wright sv->sv_cfg.skc_maxworkers = ioc->maxworkers; 237529bd2886SAlan Wright sv->sv_cfg.skc_maxconnections = ioc->maxconnections; 237629bd2886SAlan Wright sv->sv_cfg.skc_keepalive = ioc->keepalive; 237729bd2886SAlan Wright sv->sv_cfg.skc_restrict_anon = ioc->restrict_anon; 237829bd2886SAlan Wright sv->sv_cfg.skc_signing_enable = ioc->signing_enable; 237929bd2886SAlan Wright sv->sv_cfg.skc_signing_required = ioc->signing_required; 238029bd2886SAlan Wright sv->sv_cfg.skc_oplock_enable = ioc->oplock_enable; 238129bd2886SAlan Wright sv->sv_cfg.skc_sync_enable = ioc->sync_enable; 238229bd2886SAlan Wright sv->sv_cfg.skc_secmode = ioc->secmode; 238312b65585SGordon Ross sv->sv_cfg.skc_netbios_enable = ioc->netbios_enable; 238429bd2886SAlan Wright sv->sv_cfg.skc_ipv6_enable = ioc->ipv6_enable; 2385cb174861Sjoyce mcintosh sv->sv_cfg.skc_print_enable = ioc->print_enable; 23865f1ef25cSAram Hăvărneanu sv->sv_cfg.skc_traverse_mounts = ioc->traverse_mounts; 2387814e0daaSGordon Ross sv->sv_cfg.skc_short_names = ioc->short_names; 2388a90cf9f2SGordon Ross sv->sv_cfg.skc_max_protocol = ioc->max_protocol; 23893e2c0c09SMatt Barden sv->sv_cfg.skc_min_protocol = ioc->min_protocol; 23901160dcf7SMatt Barden sv->sv_cfg.skc_encrypt = ioc->encrypt; 2391b0bb0d63SGordon Ross sv->sv_cfg.skc_encrypt_ciphers = ioc->encrypt_ciphers; 2392148c5f43SAlan Wright sv->sv_cfg.skc_execflags = ioc->exec_flags; 239312b65585SGordon Ross sv->sv_cfg.skc_negtok_len = ioc->negtok_len; 23942cf6b79fSGordon Ross sv->sv_cfg.skc_max_opens = ioc->max_opens; 2395148c5f43SAlan Wright sv->sv_cfg.skc_version = ioc->version; 2396a90cf9f2SGordon Ross sv->sv_cfg.skc_initial_credits = ioc->initial_credits; 2397a90cf9f2SGordon Ross sv->sv_cfg.skc_maximum_credits = ioc->maximum_credits; 2398a90cf9f2SGordon Ross 239912b65585SGordon Ross (void) memcpy(sv->sv_cfg.skc_machine_uuid, ioc->machine_uuid, 240012b65585SGordon Ross sizeof (uuid_t)); 240112b65585SGordon Ross (void) memcpy(sv->sv_cfg.skc_negtok, ioc->negtok, 240212b65585SGordon Ross sizeof (sv->sv_cfg.skc_negtok)); 240312b65585SGordon Ross (void) memcpy(sv->sv_cfg.skc_native_os, ioc->native_os, 240412b65585SGordon Ross sizeof (sv->sv_cfg.skc_native_os)); 240512b65585SGordon Ross (void) memcpy(sv->sv_cfg.skc_native_lm, ioc->native_lm, 240612b65585SGordon Ross sizeof (sv->sv_cfg.skc_native_lm)); 240712b65585SGordon Ross 240829bd2886SAlan Wright (void) strlcpy(sv->sv_cfg.skc_nbdomain, ioc->nbdomain, 240929bd2886SAlan Wright sizeof (sv->sv_cfg.skc_nbdomain)); 241029bd2886SAlan Wright (void) strlcpy(sv->sv_cfg.skc_fqdn, ioc->fqdn, 241129bd2886SAlan Wright sizeof (sv->sv_cfg.skc_fqdn)); 241229bd2886SAlan Wright (void) strlcpy(sv->sv_cfg.skc_hostname, ioc->hostname, 241329bd2886SAlan Wright sizeof (sv->sv_cfg.skc_hostname)); 241429bd2886SAlan Wright (void) strlcpy(sv->sv_cfg.skc_system_comment, ioc->system_comment, 241529bd2886SAlan Wright sizeof (sv->sv_cfg.skc_system_comment)); 2416faa1795aSjb150015 } 2417faa1795aSjb150015 2418faa1795aSjb150015 static int 2419faa1795aSjb150015 smb_server_fsop_start(smb_server_t *sv) 2420faa1795aSjb150015 { 2421faa1795aSjb150015 int error; 2422faa1795aSjb150015 24238622ec45SGordon Ross error = smb_node_root_init(sv, &sv->si_root_smb_node); 2424faa1795aSjb150015 if (error != 0) 2425faa1795aSjb150015 sv->si_root_smb_node = NULL; 2426faa1795aSjb150015 2427faa1795aSjb150015 return (error); 2428faa1795aSjb150015 } 2429faa1795aSjb150015 2430faa1795aSjb150015 static void 2431faa1795aSjb150015 smb_server_fsop_stop(smb_server_t *sv) 2432faa1795aSjb150015 { 2433faa1795aSjb150015 if (sv->si_root_smb_node != NULL) { 2434faa1795aSjb150015 smb_node_release(sv->si_root_smb_node); 2435faa1795aSjb150015 sv->si_root_smb_node = NULL; 2436faa1795aSjb150015 } 2437faa1795aSjb150015 } 24389fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 24399fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States smb_event_t * 24408622ec45SGordon Ross smb_event_create(smb_server_t *sv, int timeout) 24419fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States { 24429fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States smb_event_t *event; 24439fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 24448622ec45SGordon Ross if (smb_server_is_stopping(sv)) 24459fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States return (NULL); 24469fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 24478622ec45SGordon Ross event = kmem_cache_alloc(smb_cache_event, KM_SLEEP); 24489fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 24499fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States bzero(event, sizeof (smb_event_t)); 24509fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States mutex_init(&event->se_mutex, NULL, MUTEX_DEFAULT, NULL); 24519fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States cv_init(&event->se_cv, NULL, CV_DEFAULT, NULL); 24529fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States event->se_magic = SMB_EVENT_MAGIC; 24539fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States event->se_txid = smb_event_alloc_txid(); 24549fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States event->se_server = sv; 2455cb174861Sjoyce mcintosh event->se_timeout = timeout; 24569fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 24579fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States smb_llist_enter(&sv->sv_event_list, RW_WRITER); 24589fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States smb_llist_insert_tail(&sv->sv_event_list, event); 24599fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States smb_llist_exit(&sv->sv_event_list); 24609fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 24619fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States return (event); 24629fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States } 24639fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 24649fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States void 24659fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States smb_event_destroy(smb_event_t *event) 24669fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States { 24679fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States smb_server_t *sv; 24689fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 24699fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States if (event == NULL) 24709fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States return; 24719fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 24729fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States SMB_EVENT_VALID(event); 24739fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States ASSERT(event->se_waittime == 0); 24748622ec45SGordon Ross sv = event->se_server; 24758622ec45SGordon Ross SMB_SERVER_VALID(sv); 24769fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 24779fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States smb_llist_enter(&sv->sv_event_list, RW_WRITER); 24789fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States smb_llist_remove(&sv->sv_event_list, event); 24799fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States smb_llist_exit(&sv->sv_event_list); 24809fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 24819fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States event->se_magic = (uint32_t)~SMB_EVENT_MAGIC; 24829fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States cv_destroy(&event->se_cv); 24839fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States mutex_destroy(&event->se_mutex); 24849fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 24858622ec45SGordon Ross kmem_cache_free(smb_cache_event, event); 24869fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States } 24879fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 24889fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States /* 24899fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States * Get the txid for the specified event. 24909fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States */ 24919fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States uint32_t 24929fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States smb_event_txid(smb_event_t *event) 24939fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States { 24949fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States if (event != NULL) { 24959fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States SMB_EVENT_VALID(event); 24969fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States return (event->se_txid); 24979fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States } 24989fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 24999fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States cmn_err(CE_NOTE, "smb_event_txid failed"); 25009fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States return ((uint32_t)-1); 25019fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States } 25029fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 25039fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States /* 25049fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States * Wait for event notification. 25059fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States */ 25069fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States int 25079fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States smb_event_wait(smb_event_t *event) 25089fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States { 25099fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States int seconds = 1; 25109fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States int ticks; 2511856399cfSGordon Ross int err; 25129fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 25139fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States if (event == NULL) 25149fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States return (EINVAL); 25159fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 25169fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States SMB_EVENT_VALID(event); 25179fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 25189fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States mutex_enter(&event->se_mutex); 25199fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States event->se_waittime = 1; 25209fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States event->se_errno = 0; 25219fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 25229fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States while (!(event->se_notified)) { 2523c5866007SKeyur Desai if (smb_event_debug && ((event->se_waittime % 30) == 0)) 25249fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States cmn_err(CE_NOTE, "smb_event_wait[%d] (%d sec)", 25259fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States event->se_txid, event->se_waittime); 25269fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 25279fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States if (event->se_errno != 0) 25289fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States break; 25299fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 2530cb174861Sjoyce mcintosh if (event->se_waittime > event->se_timeout) { 25319fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States event->se_errno = ETIME; 25329fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States break; 25339fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States } 25349fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 25359fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States ticks = SEC_TO_TICK(seconds); 25369fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States (void) cv_reltimedwait(&event->se_cv, 25379fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States &event->se_mutex, (clock_t)ticks, TR_CLOCK_TICK); 25389fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States ++event->se_waittime; 25399fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States } 25409fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 2541856399cfSGordon Ross err = event->se_errno; 25429fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States event->se_waittime = 0; 25439fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States event->se_notified = B_FALSE; 25449fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States cv_signal(&event->se_cv); 25459fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States mutex_exit(&event->se_mutex); 2546856399cfSGordon Ross return (err); 25479fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States } 25489fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 25499fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States /* 25509fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States * If txid is non-zero, cancel the specified event. 25519fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States * Otherwise, cancel all events. 25529fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States */ 25539fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States static void 25549fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States smb_event_cancel(smb_server_t *sv, uint32_t txid) 25559fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States { 25569fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States smb_event_t *event; 25579fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States smb_llist_t *event_list; 25589fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 25599fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States SMB_SERVER_VALID(sv); 25609fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 25619fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States event_list = &sv->sv_event_list; 25629fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States smb_llist_enter(event_list, RW_WRITER); 25639fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 25649fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States event = smb_llist_head(event_list); 25659fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States while (event) { 25669fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States SMB_EVENT_VALID(event); 25679fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 25689fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States if (txid == 0 || event->se_txid == txid) { 25699fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States mutex_enter(&event->se_mutex); 25709fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States event->se_errno = ECANCELED; 25719fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States event->se_notified = B_TRUE; 25729fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States cv_signal(&event->se_cv); 25739fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States mutex_exit(&event->se_mutex); 25749fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 25759fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States if (txid != 0) 25769fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States break; 25779fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States } 25789fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 25799fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States event = smb_llist_next(event_list, event); 25809fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States } 25819fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 25829fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States smb_llist_exit(event_list); 25839fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States } 25849fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 25859fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States /* 25869fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States * If txid is non-zero, notify the specified event. 25879fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States * Otherwise, notify all events. 25889fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States */ 2589cb174861Sjoyce mcintosh void 25909fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States smb_event_notify(smb_server_t *sv, uint32_t txid) 25919fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States { 25929fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States smb_event_t *event; 25939fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States smb_llist_t *event_list; 25949fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 25959fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States SMB_SERVER_VALID(sv); 25969fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 25979fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States event_list = &sv->sv_event_list; 25989fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States smb_llist_enter(event_list, RW_READER); 25999fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 26009fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States event = smb_llist_head(event_list); 26019fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States while (event) { 26029fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States SMB_EVENT_VALID(event); 26039fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 26049fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States if (txid == 0 || event->se_txid == txid) { 26059fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States mutex_enter(&event->se_mutex); 26069fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States event->se_notified = B_TRUE; 26079fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States cv_signal(&event->se_cv); 26089fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States mutex_exit(&event->se_mutex); 26099fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 26109fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States if (txid != 0) 26119fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States break; 26129fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States } 26139fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 26149fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States event = smb_llist_next(event_list, event); 26159fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States } 26169fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 26179fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States smb_llist_exit(event_list); 26189fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States } 26199fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 26209fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States /* 26219fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States * Allocate a new transaction id (txid). 26229fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States * 26239fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States * 0 or -1 are not assigned because they are used to detect invalid 26249fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States * conditions or to indicate all open id's. 26259fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States */ 26269fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States static uint32_t 26279fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States smb_event_alloc_txid(void) 26289fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States { 26299fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States static kmutex_t txmutex; 26309fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States static uint32_t txid; 26319fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States uint32_t txid_ret; 26329fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 26339fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States mutex_enter(&txmutex); 26349fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 26359fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States if (txid == 0) 26369fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States txid = ddi_get_lbolt() << 11; 26379fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 26389fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States do { 26399fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States ++txid; 26409fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States } while (txid == 0 || txid == (uint32_t)-1); 26419fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 26429fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States txid_ret = txid; 26439fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States mutex_exit(&txmutex); 26449fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 26459fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States return (txid_ret); 26469fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States } 2647cb174861Sjoyce mcintosh 2648cb174861Sjoyce mcintosh /* 2649cb174861Sjoyce mcintosh * Called by the ioctl to find the corresponding 2650cb174861Sjoyce mcintosh * spooldoc node. removes node on success 2651cb174861Sjoyce mcintosh * 2652cb174861Sjoyce mcintosh * Return values 2653cb174861Sjoyce mcintosh * rc 2654cb174861Sjoyce mcintosh * B_FALSE - not found 2655cb174861Sjoyce mcintosh * B_TRUE - found 2656cb174861Sjoyce mcintosh * 2657cb174861Sjoyce mcintosh */ 2658cb174861Sjoyce mcintosh 265923a9c295SGordon Ross static boolean_t 266023a9c295SGordon Ross smb_spool_lookup_doc_byfid(smb_server_t *sv, uint16_t fid, 266123a9c295SGordon Ross smb_kspooldoc_t *spdoc) 2662cb174861Sjoyce mcintosh { 2663cb174861Sjoyce mcintosh smb_kspooldoc_t *sp; 2664cb174861Sjoyce mcintosh smb_llist_t *splist; 2665cb174861Sjoyce mcintosh 2666cb174861Sjoyce mcintosh splist = &sv->sp_info.sp_list; 2667cb174861Sjoyce mcintosh smb_llist_enter(splist, RW_WRITER); 2668cb174861Sjoyce mcintosh sp = smb_llist_head(splist); 2669cb174861Sjoyce mcintosh while (sp != NULL) { 2670cb174861Sjoyce mcintosh /* 2671cb174861Sjoyce mcintosh * check for a matching fid 2672cb174861Sjoyce mcintosh */ 2673cb174861Sjoyce mcintosh if (sp->sd_fid == fid) { 2674cb174861Sjoyce mcintosh *spdoc = *sp; 2675cb174861Sjoyce mcintosh smb_llist_remove(splist, sp); 2676cb174861Sjoyce mcintosh smb_llist_exit(splist); 2677cb174861Sjoyce mcintosh kmem_free(sp, sizeof (smb_kspooldoc_t)); 2678cb174861Sjoyce mcintosh return (B_TRUE); 2679cb174861Sjoyce mcintosh } 2680cb174861Sjoyce mcintosh sp = smb_llist_next(splist, sp); 2681cb174861Sjoyce mcintosh } 2682cb174861Sjoyce mcintosh cmn_err(CE_WARN, "smb_spool_lookup_user_byfid: no fid:%d", fid); 2683cb174861Sjoyce mcintosh smb_llist_exit(splist); 2684cb174861Sjoyce mcintosh return (B_FALSE); 2685cb174861Sjoyce mcintosh } 2686cb174861Sjoyce mcintosh 2687cb174861Sjoyce mcintosh /* 2688cb174861Sjoyce mcintosh * Adds the spool fid to a linked list to be used 2689cb174861Sjoyce mcintosh * as a search key in the spooldoc queue 2690cb174861Sjoyce mcintosh * 2691cb174861Sjoyce mcintosh * Return values 2692cb174861Sjoyce mcintosh * rc non-zero error 2693cb174861Sjoyce mcintosh * rc zero success 2694cb174861Sjoyce mcintosh * 2695cb174861Sjoyce mcintosh */ 2696cb174861Sjoyce mcintosh 269786d7016bSGordon Ross void 269886d7016bSGordon Ross smb_spool_add_fid(smb_server_t *sv, uint16_t fid) 2699cb174861Sjoyce mcintosh { 2700cb174861Sjoyce mcintosh smb_llist_t *fidlist; 2701cb174861Sjoyce mcintosh smb_spoolfid_t *sf; 2702cb174861Sjoyce mcintosh 270386d7016bSGordon Ross if (sv->sv_cfg.skc_print_enable == 0) 270486d7016bSGordon Ross return; 2705cb174861Sjoyce mcintosh 2706cb174861Sjoyce mcintosh sf = kmem_zalloc(sizeof (smb_spoolfid_t), KM_SLEEP); 2707cb174861Sjoyce mcintosh fidlist = &sv->sp_info.sp_fidlist; 2708cb174861Sjoyce mcintosh smb_llist_enter(fidlist, RW_WRITER); 2709cb174861Sjoyce mcintosh sf->sf_fid = fid; 2710cb174861Sjoyce mcintosh smb_llist_insert_tail(fidlist, sf); 2711cb174861Sjoyce mcintosh smb_llist_exit(fidlist); 271286d7016bSGordon Ross cv_broadcast(&sv->sp_info.sp_cv); 2713cb174861Sjoyce mcintosh } 2714cb174861Sjoyce mcintosh 2715cb174861Sjoyce mcintosh /* 2716cb174861Sjoyce mcintosh * Called by the ioctl to get and remove the head of the fid list 2717cb174861Sjoyce mcintosh * 2718cb174861Sjoyce mcintosh * Return values 2719cb174861Sjoyce mcintosh * int fd 2720cb174861Sjoyce mcintosh * greater than 0 success 2721cb174861Sjoyce mcintosh * 0 - error 2722cb174861Sjoyce mcintosh * 2723cb174861Sjoyce mcintosh */ 2724cb174861Sjoyce mcintosh 272523a9c295SGordon Ross static uint16_t 272623a9c295SGordon Ross smb_spool_get_fid(smb_server_t *sv) 2727cb174861Sjoyce mcintosh { 2728cb174861Sjoyce mcintosh smb_spoolfid_t *spfid; 2729cb174861Sjoyce mcintosh smb_llist_t *splist; 2730cb174861Sjoyce mcintosh uint16_t fid; 2731cb174861Sjoyce mcintosh 2732cb174861Sjoyce mcintosh splist = &sv->sp_info.sp_fidlist; 2733cb174861Sjoyce mcintosh smb_llist_enter(splist, RW_WRITER); 2734cb174861Sjoyce mcintosh spfid = smb_llist_head(splist); 2735cb174861Sjoyce mcintosh if (spfid != NULL) { 2736cb174861Sjoyce mcintosh fid = spfid->sf_fid; 2737cb174861Sjoyce mcintosh smb_llist_remove(&sv->sp_info.sp_fidlist, spfid); 2738cb174861Sjoyce mcintosh kmem_free(spfid, sizeof (smb_spoolfid_t)); 2739cb174861Sjoyce mcintosh } else { 2740cb174861Sjoyce mcintosh fid = 0; 2741cb174861Sjoyce mcintosh } 2742cb174861Sjoyce mcintosh smb_llist_exit(splist); 2743cb174861Sjoyce mcintosh return (fid); 2744cb174861Sjoyce mcintosh } 2745cb174861Sjoyce mcintosh 2746cb174861Sjoyce mcintosh /* 2747cb174861Sjoyce mcintosh * Adds the spooldoc to the tail of the spooldoc list 2748cb174861Sjoyce mcintosh * 2749cb174861Sjoyce mcintosh * Return values 2750cb174861Sjoyce mcintosh * rc non-zero error 2751cb174861Sjoyce mcintosh * rc zero success 2752cb174861Sjoyce mcintosh */ 2753cb174861Sjoyce mcintosh int 27548622ec45SGordon Ross smb_spool_add_doc(smb_tree_t *tree, smb_kspooldoc_t *sp) 2755cb174861Sjoyce mcintosh { 2756cb174861Sjoyce mcintosh smb_llist_t *splist; 27578622ec45SGordon Ross smb_server_t *sv = tree->t_server; 2758cb174861Sjoyce mcintosh int rc = 0; 2759cb174861Sjoyce mcintosh 2760cb174861Sjoyce mcintosh splist = &sv->sp_info.sp_list; 2761cb174861Sjoyce mcintosh smb_llist_enter(splist, RW_WRITER); 276223a9c295SGordon Ross sp->sd_spool_num = atomic_inc_32_nv(&sv->sp_info.sp_cnt); 2763cb174861Sjoyce mcintosh smb_llist_insert_tail(splist, sp); 2764cb174861Sjoyce mcintosh smb_llist_exit(splist); 27658622ec45SGordon Ross 2766cb174861Sjoyce mcintosh return (rc); 2767cb174861Sjoyce mcintosh } 27684163af6aSjose borrego 27694163af6aSjose borrego /* 27704163af6aSjose borrego * smb_server_create_session 27714163af6aSjose borrego */ 27724163af6aSjose borrego static void 27734163af6aSjose borrego smb_server_create_session(smb_listener_daemon_t *ld, ksocket_t s_so) 27744163af6aSjose borrego { 2775811599a4SMatt Barden smb_server_t *sv = ld->ld_sv; 277661b20185SGordon Ross smb_session_t *session; 277761b20185SGordon Ross smb_llist_t *sl; 277861b20185SGordon Ross taskqid_t tqid; 277961b20185SGordon Ross clock_t now; 27804163af6aSjose borrego 2781811599a4SMatt Barden session = smb_session_create(s_so, ld->ld_port, sv, 27824163af6aSjose borrego ld->ld_family); 27834163af6aSjose borrego 27848622ec45SGordon Ross if (session == NULL) { 278561b20185SGordon Ross /* This should be rare (create sleeps) */ 27868622ec45SGordon Ross smb_soshutdown(s_so); 27878622ec45SGordon Ross smb_sodestroy(s_so); 27888622ec45SGordon Ross cmn_err(CE_WARN, "SMB Session: alloc failed"); 27898622ec45SGordon Ross return; 27908622ec45SGordon Ross } 27918622ec45SGordon Ross 2792811599a4SMatt Barden sl = &sv->sv_session_list; 2793811599a4SMatt Barden smb_llist_enter(sl, RW_WRITER); 279461b20185SGordon Ross if (smb_llist_get_count(sl) >= sv->sv_cfg.skc_maxconnections) { 279561b20185SGordon Ross /* 279661b20185SGordon Ross * New session not in sv_session_list, so we can just 279761b20185SGordon Ross * delete it directly. 279861b20185SGordon Ross */ 279961b20185SGordon Ross smb_llist_exit(sl); 280061b20185SGordon Ross DTRACE_PROBE1(maxconn, smb_session_t *, session); 280161b20185SGordon Ross smb_soshutdown(session->sock); 280261b20185SGordon Ross smb_session_delete(session); 280361b20185SGordon Ross goto logmaxconn; 280461b20185SGordon Ross } 2805811599a4SMatt Barden smb_llist_insert_tail(sl, session); 2806811599a4SMatt Barden smb_llist_exit(sl); 28074163af6aSjose borrego 28088622ec45SGordon Ross /* 28098622ec45SGordon Ross * These taskq entries must run independently of one another, 28108622ec45SGordon Ross * so TQ_NOQUEUE. TQ_SLEEP (==0) just for clarity. 28118622ec45SGordon Ross */ 2812811599a4SMatt Barden tqid = taskq_dispatch(sv->sv_receiver_pool, 2813811599a4SMatt Barden smb_server_receiver, session, TQ_NOQUEUE | TQ_SLEEP); 28149788d6deSGordon Ross if (tqid != TASKQID_INVALID) { 28159788d6deSGordon Ross /* Success */ 28169788d6deSGordon Ross return; 28179788d6deSGordon Ross } 28189788d6deSGordon Ross 281961b20185SGordon Ross /* 28209788d6deSGordon Ross * Have: tqid == TASKQID_INVALID 282161b20185SGordon Ross * We never entered smb_server_receiver() 28229788d6deSGordon Ross * so need to do its return cleanup 282361b20185SGordon Ross */ 282461b20185SGordon Ross DTRACE_PROBE1(maxconn, smb_session_t *, session); 28254163af6aSjose borrego smb_session_disconnect(session); 282661b20185SGordon Ross smb_session_logoff(session); 2827811599a4SMatt Barden smb_server_destroy_session(session); 282861b20185SGordon Ross 282961b20185SGordon Ross logmaxconn: 283061b20185SGordon Ross /* 283161b20185SGordon Ross * If we hit max_connections, log something so an admin 283261b20185SGordon Ross * can find out why new connections are failing, but 283361b20185SGordon Ross * log this no more than once a minute. 283461b20185SGordon Ross */ 283561b20185SGordon Ross now = ddi_get_lbolt(); 283661b20185SGordon Ross if (now > ld->ld_quiet) { 283761b20185SGordon Ross ld->ld_quiet = now + SEC_TO_TICK(60); 283861b20185SGordon Ross cmn_err(CE_WARN, "SMB can't create session: " 283961b20185SGordon Ross "Would exceed max_connections."); 284061b20185SGordon Ross } 28414163af6aSjose borrego } 28424163af6aSjose borrego 28434163af6aSjose borrego static void 2844811599a4SMatt Barden smb_server_destroy_session(smb_session_t *session) 28454163af6aSjose borrego { 2846811599a4SMatt Barden smb_server_t *sv; 2847811599a4SMatt Barden smb_llist_t *ll; 2848811599a4SMatt Barden uint32_t count; 2849811599a4SMatt Barden 2850811599a4SMatt Barden ASSERT(session->s_server != NULL); 2851811599a4SMatt Barden sv = session->s_server; 2852811599a4SMatt Barden ll = &sv->sv_session_list; 2853811599a4SMatt Barden 2854811599a4SMatt Barden smb_llist_flush(&session->s_tree_list); 2855811599a4SMatt Barden smb_llist_flush(&session->s_user_list); 2856811599a4SMatt Barden 2857811599a4SMatt Barden smb_llist_enter(ll, RW_WRITER); 2858811599a4SMatt Barden smb_llist_remove(ll, session); 2859811599a4SMatt Barden count = ll->ll_count; 2860811599a4SMatt Barden smb_llist_exit(ll); 2861811599a4SMatt Barden 28627f5d80fdSGordon Ross /* 28637f5d80fdSGordon Ross * Normally, the session should have state SHUTDOWN here. 28647f5d80fdSGordon Ross * If the session has any ofiles remaining, eg. due to 28657f5d80fdSGordon Ross * forgotten ofile references or something, the state 28667f5d80fdSGordon Ross * will be _DISCONNECTED or _TERMINATED. Keep such 28677f5d80fdSGordon Ross * sessions in the list of zombies (for debugging). 28687f5d80fdSGordon Ross */ 28697f5d80fdSGordon Ross if (session->s_state == SMB_SESSION_STATE_SHUTDOWN) { 28704163af6aSjose borrego smb_session_delete(session); 28717f5d80fdSGordon Ross } else { 287286184067SGordon Ross cmn_err(CE_NOTE, "!Leaked session: 0x%p", (void *)session); 287386184067SGordon Ross DTRACE_PROBE1(new__zombie, smb_session_t *, session); 28747f5d80fdSGordon Ross smb_llist_enter(&smb_server_session_zombies, RW_WRITER); 28757f5d80fdSGordon Ross smb_llist_insert_head(&smb_server_session_zombies, session); 28767f5d80fdSGordon Ross smb_llist_exit(&smb_server_session_zombies); 28777f5d80fdSGordon Ross } 28787f5d80fdSGordon Ross 2879811599a4SMatt Barden if (count == 0) { 2880811599a4SMatt Barden /* See smb_server_shutdown */ 2881811599a4SMatt Barden cv_signal(&sv->sv_cv); 2882811599a4SMatt Barden } 28834163af6aSjose borrego } 2884