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. 24*8d94f651SGordon Ross * Copyright 2018 Nexenta Systems, Inc. All rights reserved. 25faa1795aSjb150015 */ 26faa1795aSjb150015 27faa1795aSjb150015 /* 28faa1795aSjb150015 * General Structures Layout 29faa1795aSjb150015 * ------------------------- 30faa1795aSjb150015 * 31faa1795aSjb150015 * This is a simplified diagram showing the relationship between most of the 32faa1795aSjb150015 * main structures. 33faa1795aSjb150015 * 34faa1795aSjb150015 * +-------------------+ 35faa1795aSjb150015 * | SMB_SERVER | 36faa1795aSjb150015 * +-------------------+ 37faa1795aSjb150015 * | 38faa1795aSjb150015 * | 39faa1795aSjb150015 * v 40faa1795aSjb150015 * +-------------------+ +-------------------+ +-------------------+ 41faa1795aSjb150015 * | SESSION |<----->| SESSION |......| SESSION | 42faa1795aSjb150015 * +-------------------+ +-------------------+ +-------------------+ 43faa1795aSjb150015 * | 44faa1795aSjb150015 * | 45faa1795aSjb150015 * v 46faa1795aSjb150015 * +-------------------+ +-------------------+ +-------------------+ 47faa1795aSjb150015 * | USER |<----->| USER |......| USER | 48faa1795aSjb150015 * +-------------------+ +-------------------+ +-------------------+ 49faa1795aSjb150015 * | 50faa1795aSjb150015 * | 51faa1795aSjb150015 * v 52faa1795aSjb150015 * +-------------------+ +-------------------+ +-------------------+ 53faa1795aSjb150015 * | TREE |<----->| TREE |......| TREE | 54faa1795aSjb150015 * +-------------------+ +-------------------+ +-------------------+ 55faa1795aSjb150015 * | | 56faa1795aSjb150015 * | | 57faa1795aSjb150015 * | v 58faa1795aSjb150015 * | +-------+ +-------+ +-------+ 59faa1795aSjb150015 * | | OFILE |<----->| OFILE |......| OFILE | 60faa1795aSjb150015 * | +-------+ +-------+ +-------+ 61faa1795aSjb150015 * | 62faa1795aSjb150015 * | 63faa1795aSjb150015 * v 64faa1795aSjb150015 * +-------+ +------+ +------+ 65faa1795aSjb150015 * | ODIR |<----->| ODIR |......| ODIR | 66faa1795aSjb150015 * +-------+ +------+ +------+ 67faa1795aSjb150015 * 68faa1795aSjb150015 * 69faa1795aSjb150015 * Module Interface Overview 70faa1795aSjb150015 * ------------------------- 71faa1795aSjb150015 * 72faa1795aSjb150015 * 73faa1795aSjb150015 * +===================================+ 74faa1795aSjb150015 * | smbd daemon | 75faa1795aSjb150015 * +===================================+ 76faa1795aSjb150015 * | | ^ 77faa1795aSjb150015 * | | | 78faa1795aSjb150015 * User | | | 79faa1795aSjb150015 * -----------|--------------|----------------|-------------------------------- 80faa1795aSjb150015 * Kernel | | | 81faa1795aSjb150015 * | | | 82faa1795aSjb150015 * | | | 83faa1795aSjb150015 * +=========|==============|================|=================+ 84faa1795aSjb150015 * | v v | | 85faa1795aSjb150015 * | +-----------+ +--------------------+ +------------------+ | 86faa1795aSjb150015 * | | IO | | Kernel Door Server | | User Door Servers| | 87faa1795aSjb150015 * | | Interface | | Interface | | Interface | | 88faa1795aSjb150015 * | +-----------+ +--------------------+ +------------------+ | 89faa1795aSjb150015 * | | | ^ ^ | 90faa1795aSjb150015 * | v v | | | +=========+ 91faa1795aSjb150015 * | +-----------------------------------+ | | | | 92faa1795aSjb150015 * | + SMB Server Management (this file) |<------------------| ZFS | 93faa1795aSjb150015 * | +-----------------------------------+ | | | | 94faa1795aSjb150015 * | | | | Module | 95faa1795aSjb150015 * | +-----------------------------------+ | | | | 96faa1795aSjb150015 * | + SMB Server Internal Layers |------+ | +=========+ 97faa1795aSjb150015 * | +-----------------------------------+ | 98faa1795aSjb150015 * | | 99faa1795aSjb150015 * | | 100faa1795aSjb150015 * +===========================================================+ 101faa1795aSjb150015 * 102faa1795aSjb150015 * 103faa1795aSjb150015 * Server State Machine 104faa1795aSjb150015 * -------------------- 105faa1795aSjb150015 * | 106faa1795aSjb150015 * | T0 107faa1795aSjb150015 * | 108faa1795aSjb150015 * v 109faa1795aSjb150015 * +-----------------------------+ 110faa1795aSjb150015 * | SMB_SERVER_STATE_CREATED | 111faa1795aSjb150015 * +-----------------------------+ 112faa1795aSjb150015 * | 113faa1795aSjb150015 * | T1 114faa1795aSjb150015 * | 115faa1795aSjb150015 * v 116faa1795aSjb150015 * +-----------------------------+ 117faa1795aSjb150015 * | SMB_SERVER_STATE_CONFIGURED | 118faa1795aSjb150015 * +-----------------------------+ 119faa1795aSjb150015 * | 120faa1795aSjb150015 * | T2 121faa1795aSjb150015 * | 122faa1795aSjb150015 * v 123faa1795aSjb150015 * +-----------------------------+ 1249fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States * | SMB_SERVER_STATE_RUNNING / | 1259fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States * | SMB_SERVER_STATE_STOPPING | 126faa1795aSjb150015 * +-----------------------------+ 127faa1795aSjb150015 * | 128faa1795aSjb150015 * | T3 129faa1795aSjb150015 * | 130faa1795aSjb150015 * v 131faa1795aSjb150015 * +-----------------------------+ 132faa1795aSjb150015 * | SMB_SERVER_STATE_DELETING | 133faa1795aSjb150015 * +-----------------------------+ 134faa1795aSjb150015 * | 135faa1795aSjb150015 * | 136faa1795aSjb150015 * | 137faa1795aSjb150015 * v 138faa1795aSjb150015 * 139faa1795aSjb150015 * States 140faa1795aSjb150015 * ------ 141faa1795aSjb150015 * 142faa1795aSjb150015 * SMB_SERVER_STATE_CREATED 143faa1795aSjb150015 * 144faa1795aSjb150015 * This is the state of the server just after creation. 145faa1795aSjb150015 * 146faa1795aSjb150015 * SMB_SERVER_STATE_CONFIGURED 147faa1795aSjb150015 * 148faa1795aSjb150015 * The server has been configured. 149faa1795aSjb150015 * 150faa1795aSjb150015 * SMB_SERVER_STATE_RUNNING 151faa1795aSjb150015 * 152faa1795aSjb150015 * The server has been started. While in this state the threads listening on 1534163af6aSjose borrego * the sockets are started. 154faa1795aSjb150015 * 1554163af6aSjose borrego * When a client establishes a connection the thread listening dispatches 1564163af6aSjose borrego * a task with the new session as an argument. If the dispatch fails the new 1574163af6aSjose borrego * session context is destroyed. 158faa1795aSjb150015 * 159faa1795aSjb150015 * SMB_SERVER_STATE_STOPPING 160faa1795aSjb150015 * 161faa1795aSjb150015 * The threads listening on the NBT and TCP sockets are being terminated. 162faa1795aSjb150015 * 163faa1795aSjb150015 * 164faa1795aSjb150015 * Transitions 165faa1795aSjb150015 * ----------- 166faa1795aSjb150015 * 167faa1795aSjb150015 * Transition T0 168faa1795aSjb150015 * 169faa1795aSjb150015 * The daemon smbd triggers its creation by opening the smbsrv device. If 170faa1795aSjb150015 * the zone where the daemon lives doesn't have an smb server yet it is 171faa1795aSjb150015 * created. 172faa1795aSjb150015 * 173faa1795aSjb150015 * smb_drv_open() --> smb_server_create() 174faa1795aSjb150015 * 175faa1795aSjb150015 * Transition T1 176faa1795aSjb150015 * 177faa1795aSjb150015 * This transition occurs in smb_server_configure(). It is triggered by the 178faa1795aSjb150015 * daemon through an Ioctl. 179faa1795aSjb150015 * 180faa1795aSjb150015 * smb_drv_ioctl(SMB_IOC_CONFIG) --> smb_server_configure() 181faa1795aSjb150015 * 182faa1795aSjb150015 * Transition T2 183faa1795aSjb150015 * 184faa1795aSjb150015 * This transition occurs in smb_server_start(). It is triggered by the 185faa1795aSjb150015 * daemon through an Ioctl. 186faa1795aSjb150015 * 187faa1795aSjb150015 * smb_drv_ioctl(SMB_IOC_START) --> smb_server_start() 188faa1795aSjb150015 * 189faa1795aSjb150015 * Transition T3 190faa1795aSjb150015 * 191faa1795aSjb150015 * This transition occurs in smb_server_delete(). It is triggered by the 192faa1795aSjb150015 * daemon when closing the smbsrv device 193faa1795aSjb150015 * 194faa1795aSjb150015 * smb_drv_close() --> smb_server_delete() 195faa1795aSjb150015 * 196faa1795aSjb150015 * Comments 197faa1795aSjb150015 * -------- 198faa1795aSjb150015 * 199faa1795aSjb150015 * This files assumes that there will one SMB server per zone. For now the 200faa1795aSjb150015 * smb server works only in global zone. There's nothing in this file preventing 201faa1795aSjb150015 * an smb server from being created in a non global zone. That limitation is 202faa1795aSjb150015 * enforced in user space. 203faa1795aSjb150015 */ 204faa1795aSjb150015 205faa1795aSjb150015 #include <sys/cmn_err.h> 206faa1795aSjb150015 #include <sys/priv.h> 207faa1795aSjb150015 #include <sys/zone.h> 208bbf6f00cSJordan Brown #include <netinet/in.h> 209bbf6f00cSJordan Brown #include <netinet/in_systm.h> 210bbf6f00cSJordan Brown #include <netinet/ip.h> 211bbf6f00cSJordan Brown #include <netinet/ip_icmp.h> 212bbf6f00cSJordan Brown #include <netinet/ip_var.h> 213bbf6f00cSJordan Brown #include <netinet/tcp.h> 214a90cf9f2SGordon Ross #include <smbsrv/smb2_kproto.h> 215bbf6f00cSJordan Brown #include <smbsrv/string.h> 216faa1795aSjb150015 #include <smbsrv/netbios.h> 217faa1795aSjb150015 #include <smbsrv/smb_fsops.h> 2183db3f65cSamw #include <smbsrv/smb_share.h> 2199fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States #include <smbsrv/smb_door.h> 2206537f381Sas200622 #include <smbsrv/smb_kstat.h> 221faa1795aSjb150015 222148c5f43SAlan Wright static void smb_server_kstat_init(smb_server_t *); 223faa1795aSjb150015 static void smb_server_kstat_fini(smb_server_t *); 224faa1795aSjb150015 static void smb_server_timers(smb_thread_t *, void *); 22529bd2886SAlan Wright static void smb_server_store_cfg(smb_server_t *, smb_ioc_cfg_t *); 2269fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States static void smb_server_shutdown(smb_server_t *); 227faa1795aSjb150015 static int smb_server_fsop_start(smb_server_t *); 228faa1795aSjb150015 static void smb_server_fsop_stop(smb_server_t *); 2299fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States static void smb_event_cancel(smb_server_t *, uint32_t); 2309fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States static uint32_t smb_event_alloc_txid(void); 231faa1795aSjb150015 232*8d94f651SGordon Ross static void smb_server_disconnect_share(smb_server_t *, const char *); 233*8d94f651SGordon Ross static void smb_server_enum_users(smb_server_t *, smb_svcenum_t *); 234*8d94f651SGordon Ross static void smb_server_enum_trees(smb_server_t *, smb_svcenum_t *); 235*8d94f651SGordon Ross static int smb_server_session_disconnect(smb_server_t *, const char *, 2361fcced4cSJordan Brown const char *); 237*8d94f651SGordon Ross static int smb_server_fclose(smb_server_t *, uint32_t); 238148c5f43SAlan Wright static int smb_server_kstat_update(kstat_t *, int); 239cb174861Sjoyce mcintosh static int smb_server_legacy_kstat_update(kstat_t *, int); 2404163af6aSjose borrego static void smb_server_listener_init(smb_server_t *, smb_listener_daemon_t *, 2414163af6aSjose borrego char *, in_port_t, int); 2424163af6aSjose borrego static void smb_server_listener_destroy(smb_listener_daemon_t *); 2434163af6aSjose borrego static int smb_server_listener_start(smb_listener_daemon_t *); 2444163af6aSjose borrego static void smb_server_listener_stop(smb_listener_daemon_t *); 2454163af6aSjose borrego static void smb_server_listener(smb_thread_t *, void *); 2464163af6aSjose borrego static void smb_server_receiver(void *); 2474163af6aSjose borrego static void smb_server_create_session(smb_listener_daemon_t *, ksocket_t); 248811599a4SMatt Barden static void smb_server_destroy_session(smb_session_t *); 24923a9c295SGordon Ross static uint16_t smb_spool_get_fid(smb_server_t *); 25023a9c295SGordon Ross static boolean_t smb_spool_lookup_doc_byfid(smb_server_t *, uint16_t, 25123a9c295SGordon Ross smb_kspooldoc_t *); 2521fcced4cSJordan Brown 253811599a4SMatt Barden /* 254811599a4SMatt Barden * How many "buckets" should our hash tables use? On a "real" server, 255811599a4SMatt Barden * make them much larger than the number of CPUs we're likely to have. 256811599a4SMatt Barden * On "fksmbd" make it smaller so dtrace logs are shorter. 257811599a4SMatt Barden * These must be powers of two. 258811599a4SMatt Barden */ 259811599a4SMatt Barden #ifdef _KERNEL 260811599a4SMatt Barden #define DEFAULT_HASH_NBUCKETS 256 /* real server */ 261811599a4SMatt Barden #else 262811599a4SMatt Barden #define DEFAULT_HASH_NBUCKETS 16 /* for "fksmbd" */ 263811599a4SMatt Barden #endif 264811599a4SMatt Barden uint32_t SMB_OFILE_HASH_NBUCKETS = DEFAULT_HASH_NBUCKETS; 265811599a4SMatt Barden uint32_t SMB_LEASE_HASH_NBUCKETS = DEFAULT_HASH_NBUCKETS; 266811599a4SMatt Barden 2679fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States int smb_event_debug = 0; 2689fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 269faa1795aSjb150015 static smb_llist_t smb_servers; 270faa1795aSjb150015 2718622ec45SGordon Ross kmem_cache_t *smb_cache_request; 2728622ec45SGordon Ross kmem_cache_t *smb_cache_session; 2738622ec45SGordon Ross kmem_cache_t *smb_cache_user; 2748622ec45SGordon Ross kmem_cache_t *smb_cache_tree; 2758622ec45SGordon Ross kmem_cache_t *smb_cache_ofile; 2768622ec45SGordon Ross kmem_cache_t *smb_cache_odir; 2778622ec45SGordon Ross kmem_cache_t *smb_cache_opipe; 2788622ec45SGordon Ross kmem_cache_t *smb_cache_event; 2790897f7fbSGordon Ross kmem_cache_t *smb_cache_lock; 2808622ec45SGordon Ross 281faa1795aSjb150015 /* 282faa1795aSjb150015 * ***************************************************************************** 283faa1795aSjb150015 * **************** Functions called from the device interface ***************** 284faa1795aSjb150015 * ***************************************************************************** 285faa1795aSjb150015 * 2861fcced4cSJordan Brown * These functions typically have to determine the relevant smb server 2871fcced4cSJordan Brown * to which the call applies. 288faa1795aSjb150015 */ 289faa1795aSjb150015 290faa1795aSjb150015 /* 291a90cf9f2SGordon Ross * How many zones have an SMB server active? 292a90cf9f2SGordon Ross */ 293a90cf9f2SGordon Ross int 294a90cf9f2SGordon Ross smb_server_get_count(void) 295a90cf9f2SGordon Ross { 296a90cf9f2SGordon Ross return (smb_llist_get_count(&smb_servers)); 297a90cf9f2SGordon Ross } 298a90cf9f2SGordon Ross 299a90cf9f2SGordon Ross /* 3008622ec45SGordon Ross * smb_server_g_init 301faa1795aSjb150015 * 302c8ec8eeaSjose borrego * This function must be called from smb_drv_attach(). 303faa1795aSjb150015 */ 304faa1795aSjb150015 int 3058622ec45SGordon Ross smb_server_g_init(void) 306faa1795aSjb150015 { 3078622ec45SGordon Ross int rc; 308faa1795aSjb150015 3098622ec45SGordon Ross if ((rc = smb_vop_init()) != 0) 3108622ec45SGordon Ross goto errout; 3118622ec45SGordon Ross if ((rc = smb_fem_init()) != 0) 3128622ec45SGordon Ross goto errout; 3138622ec45SGordon Ross 3148622ec45SGordon Ross smb_kshare_g_init(); 3158622ec45SGordon Ross smb_codepage_init(); 3168622ec45SGordon Ross smb_mbc_init(); /* smb_mbc_cache */ 3178622ec45SGordon Ross smb_node_init(); /* smb_node_cache, lists */ 31894047d49SGordon Ross smb2_lease_init(); 3198622ec45SGordon Ross 3208622ec45SGordon Ross smb_cache_request = kmem_cache_create("smb_request_cache", 3218622ec45SGordon Ross sizeof (smb_request_t), 8, NULL, NULL, NULL, NULL, NULL, 0); 3228622ec45SGordon Ross smb_cache_session = kmem_cache_create("smb_session_cache", 3238622ec45SGordon Ross sizeof (smb_session_t), 8, NULL, NULL, NULL, NULL, NULL, 0); 3248622ec45SGordon Ross smb_cache_user = kmem_cache_create("smb_user_cache", 3258622ec45SGordon Ross sizeof (smb_user_t), 8, NULL, NULL, NULL, NULL, NULL, 0); 3268622ec45SGordon Ross smb_cache_tree = kmem_cache_create("smb_tree_cache", 3278622ec45SGordon Ross sizeof (smb_tree_t), 8, NULL, NULL, NULL, NULL, NULL, 0); 3288622ec45SGordon Ross smb_cache_ofile = kmem_cache_create("smb_ofile_cache", 3298622ec45SGordon Ross sizeof (smb_ofile_t), 8, NULL, NULL, NULL, NULL, NULL, 0); 3308622ec45SGordon Ross smb_cache_odir = kmem_cache_create("smb_odir_cache", 3318622ec45SGordon Ross sizeof (smb_odir_t), 8, NULL, NULL, NULL, NULL, NULL, 0); 3328622ec45SGordon Ross smb_cache_opipe = kmem_cache_create("smb_opipe_cache", 3338622ec45SGordon Ross sizeof (smb_opipe_t), 8, NULL, NULL, NULL, NULL, NULL, 0); 3348622ec45SGordon Ross smb_cache_event = kmem_cache_create("smb_event_cache", 3358622ec45SGordon Ross sizeof (smb_event_t), 8, NULL, NULL, NULL, NULL, NULL, 0); 3360897f7fbSGordon Ross smb_cache_lock = kmem_cache_create("smb_lock_cache", 3370897f7fbSGordon Ross sizeof (smb_lock_t), 8, NULL, NULL, NULL, NULL, NULL, 0); 3388622ec45SGordon Ross 3399fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States smb_llist_init(); 340faa1795aSjb150015 smb_llist_constructor(&smb_servers, sizeof (smb_server_t), 341faa1795aSjb150015 offsetof(smb_server_t, sv_lnd)); 3429fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 3438622ec45SGordon Ross return (0); 3448622ec45SGordon Ross 3458622ec45SGordon Ross errout: 346faa1795aSjb150015 smb_fem_fini(); 347faa1795aSjb150015 smb_vop_fini(); 348faa1795aSjb150015 return (rc); 349faa1795aSjb150015 } 350faa1795aSjb150015 351faa1795aSjb150015 /* 3528622ec45SGordon Ross * smb_server_g_fini 353faa1795aSjb150015 * 354faa1795aSjb150015 * This function must called from smb_drv_detach(). It will fail if servers 355faa1795aSjb150015 * still exist. 356faa1795aSjb150015 */ 357a90cf9f2SGordon Ross void 3588622ec45SGordon Ross smb_server_g_fini(void) 359faa1795aSjb150015 { 360faa1795aSjb150015 361a90cf9f2SGordon Ross ASSERT(smb_llist_get_count(&smb_servers) == 0); 362a90cf9f2SGordon Ross 3639fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States smb_llist_fini(); 3648622ec45SGordon Ross 3658622ec45SGordon Ross kmem_cache_destroy(smb_cache_request); 3668622ec45SGordon Ross kmem_cache_destroy(smb_cache_session); 3678622ec45SGordon Ross kmem_cache_destroy(smb_cache_user); 3688622ec45SGordon Ross kmem_cache_destroy(smb_cache_tree); 3698622ec45SGordon Ross kmem_cache_destroy(smb_cache_ofile); 3708622ec45SGordon Ross kmem_cache_destroy(smb_cache_odir); 3718622ec45SGordon Ross kmem_cache_destroy(smb_cache_opipe); 3728622ec45SGordon Ross kmem_cache_destroy(smb_cache_event); 3730897f7fbSGordon Ross kmem_cache_destroy(smb_cache_lock); 3748622ec45SGordon Ross 37594047d49SGordon Ross smb2_lease_fini(); 376faa1795aSjb150015 smb_node_fini(); 3772c2961f8Sjose borrego smb_mbc_fini(); 378adc68ba9SPavel Zakharov smb_codepage_fini(); 3798622ec45SGordon Ross smb_kshare_g_fini(); 3808622ec45SGordon Ross 3818622ec45SGordon Ross smb_fem_fini(); 3828622ec45SGordon Ross smb_vop_fini(); 3838622ec45SGordon Ross 384faa1795aSjb150015 smb_llist_destructor(&smb_servers); 385faa1795aSjb150015 } 386faa1795aSjb150015 387faa1795aSjb150015 /* 388faa1795aSjb150015 * smb_server_create 389faa1795aSjb150015 * 390faa1795aSjb150015 * This function will fail if there's already a server associated with the 391faa1795aSjb150015 * caller's zone. 392faa1795aSjb150015 */ 393faa1795aSjb150015 int 394faa1795aSjb150015 smb_server_create(void) 395faa1795aSjb150015 { 396faa1795aSjb150015 zoneid_t zid; 397faa1795aSjb150015 smb_server_t *sv; 398faa1795aSjb150015 399faa1795aSjb150015 zid = getzoneid(); 400faa1795aSjb150015 401faa1795aSjb150015 smb_llist_enter(&smb_servers, RW_WRITER); 402faa1795aSjb150015 sv = smb_llist_head(&smb_servers); 403faa1795aSjb150015 while (sv) { 4049fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States SMB_SERVER_VALID(sv); 405faa1795aSjb150015 if (sv->sv_zid == zid) { 406faa1795aSjb150015 smb_llist_exit(&smb_servers); 40794fff790SAlan Wright return (EPERM); 408faa1795aSjb150015 } 409faa1795aSjb150015 sv = smb_llist_next(&smb_servers, sv); 410faa1795aSjb150015 } 411faa1795aSjb150015 4128622ec45SGordon Ross sv = kmem_zalloc(sizeof (smb_server_t), KM_SLEEP); 4138622ec45SGordon Ross 4148622ec45SGordon Ross sv->sv_magic = SMB_SERVER_MAGIC; 4158622ec45SGordon Ross sv->sv_state = SMB_SERVER_STATE_CREATED; 4168622ec45SGordon Ross sv->sv_zid = zid; 417b819cea2SGordon Ross sv->sv_pid = ddi_get_pid(); 4188622ec45SGordon Ross 4198622ec45SGordon Ross mutex_init(&sv->sv_mutex, NULL, MUTEX_DEFAULT, NULL); 4208622ec45SGordon Ross cv_init(&sv->sv_cv, NULL, CV_DEFAULT, NULL); 4218622ec45SGordon Ross cv_init(&sv->sp_info.sp_cv, NULL, CV_DEFAULT, NULL); 422faa1795aSjb150015 423811599a4SMatt Barden sv->sv_persistid_ht = smb_hash_create(sizeof (smb_ofile_t), 424811599a4SMatt Barden offsetof(smb_ofile_t, f_dh_lnd), SMB_OFILE_HASH_NBUCKETS); 425811599a4SMatt Barden 42694047d49SGordon Ross sv->sv_lease_ht = smb_hash_create(sizeof (smb_lease_t), 42794047d49SGordon Ross offsetof(smb_lease_t, ls_lnd), SMB_LEASE_HASH_NBUCKETS); 42894047d49SGordon Ross 429811599a4SMatt Barden smb_llist_constructor(&sv->sv_session_list, sizeof (smb_session_t), 430811599a4SMatt Barden offsetof(smb_session_t, s_lnd)); 431811599a4SMatt Barden 4329fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States smb_llist_constructor(&sv->sv_event_list, sizeof (smb_event_t), 4339fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States offsetof(smb_event_t, se_lnd)); 4349fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 435cb174861Sjoyce mcintosh smb_llist_constructor(&sv->sp_info.sp_list, sizeof (smb_kspooldoc_t), 436cb174861Sjoyce mcintosh offsetof(smb_kspooldoc_t, sd_lnd)); 437cb174861Sjoyce mcintosh 438cb174861Sjoyce mcintosh smb_llist_constructor(&sv->sp_info.sp_fidlist, 439cb174861Sjoyce mcintosh sizeof (smb_spoolfid_t), offsetof(smb_spoolfid_t, sf_lnd)); 440cb174861Sjoyce mcintosh 441a90cf9f2SGordon Ross sv->sv_disp_stats1 = kmem_zalloc(SMB_COM_NUM * 442a90cf9f2SGordon Ross sizeof (smb_disp_stats_t), KM_SLEEP); 443a90cf9f2SGordon Ross 444a90cf9f2SGordon Ross sv->sv_disp_stats2 = kmem_zalloc(SMB2__NCMDS * 4458622ec45SGordon Ross sizeof (smb_disp_stats_t), KM_SLEEP); 446faa1795aSjb150015 44708344b29SGordon Ross smb_thread_init(&sv->si_thread_timers, "smb_timers", 44808344b29SGordon Ross smb_server_timers, sv, smbsrv_timer_pri); 449faa1795aSjb150015 450148c5f43SAlan Wright smb_srqueue_init(&sv->sv_srqueue); 451faa1795aSjb150015 4528622ec45SGordon Ross smb_kdoor_init(sv); 4538622ec45SGordon Ross smb_kshare_init(sv); 454148c5f43SAlan Wright smb_server_kstat_init(sv); 455faa1795aSjb150015 456856399cfSGordon Ross smb_threshold_init(&sv->sv_ssetup_ct, SMB_SSETUP_CMD, 457856399cfSGordon Ross smb_ssetup_threshold, smb_ssetup_timeout); 458856399cfSGordon Ross smb_threshold_init(&sv->sv_tcon_ct, SMB_TCON_CMD, 459856399cfSGordon Ross smb_tcon_threshold, smb_tcon_timeout); 460856399cfSGordon Ross smb_threshold_init(&sv->sv_opipe_ct, SMB_OPIPE_CMD, 461856399cfSGordon Ross smb_opipe_threshold, smb_opipe_timeout); 462856399cfSGordon Ross 463faa1795aSjb150015 smb_llist_insert_tail(&smb_servers, sv); 464faa1795aSjb150015 smb_llist_exit(&smb_servers); 465cb174861Sjoyce mcintosh 466faa1795aSjb150015 return (0); 467faa1795aSjb150015 } 468faa1795aSjb150015 469faa1795aSjb150015 /* 470faa1795aSjb150015 * smb_server_delete 471faa1795aSjb150015 * 472faa1795aSjb150015 * This function will delete the server passed in. It will make sure that all 473faa1795aSjb150015 * activity associated that server has ceased before destroying it. 474faa1795aSjb150015 */ 475faa1795aSjb150015 int 476*8d94f651SGordon Ross smb_server_delete(smb_server_t *sv) 477faa1795aSjb150015 { 478faa1795aSjb150015 479faa1795aSjb150015 mutex_enter(&sv->sv_mutex); 480faa1795aSjb150015 switch (sv->sv_state) { 481faa1795aSjb150015 case SMB_SERVER_STATE_RUNNING: 4829fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States sv->sv_state = SMB_SERVER_STATE_STOPPING; 483faa1795aSjb150015 mutex_exit(&sv->sv_mutex); 4844163af6aSjose borrego smb_server_shutdown(sv); 485faa1795aSjb150015 mutex_enter(&sv->sv_mutex); 4864163af6aSjose borrego cv_broadcast(&sv->sp_info.sp_cv); 4874163af6aSjose borrego sv->sv_state = SMB_SERVER_STATE_DELETING; 4884163af6aSjose borrego break; 4894163af6aSjose borrego case SMB_SERVER_STATE_STOPPING: 4904163af6aSjose borrego sv->sv_state = SMB_SERVER_STATE_DELETING; 491faa1795aSjb150015 break; 492faa1795aSjb150015 case SMB_SERVER_STATE_CONFIGURED: 493faa1795aSjb150015 case SMB_SERVER_STATE_CREATED: 494faa1795aSjb150015 sv->sv_state = SMB_SERVER_STATE_DELETING; 495faa1795aSjb150015 break; 496faa1795aSjb150015 default: 4979fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States SMB_SERVER_STATE_VALID(sv->sv_state); 498faa1795aSjb150015 mutex_exit(&sv->sv_mutex); 499faa1795aSjb150015 smb_server_release(sv); 500faa1795aSjb150015 return (ENOTTY); 501faa1795aSjb150015 } 502faa1795aSjb150015 503faa1795aSjb150015 ASSERT(sv->sv_state == SMB_SERVER_STATE_DELETING); 504faa1795aSjb150015 505faa1795aSjb150015 sv->sv_refcnt--; 506faa1795aSjb150015 while (sv->sv_refcnt) 507faa1795aSjb150015 cv_wait(&sv->sv_cv, &sv->sv_mutex); 508faa1795aSjb150015 509faa1795aSjb150015 mutex_exit(&sv->sv_mutex); 510faa1795aSjb150015 511faa1795aSjb150015 smb_llist_enter(&smb_servers, RW_WRITER); 512faa1795aSjb150015 smb_llist_remove(&smb_servers, sv); 513faa1795aSjb150015 smb_llist_exit(&smb_servers); 514faa1795aSjb150015 515856399cfSGordon Ross smb_threshold_fini(&sv->sv_ssetup_ct); 516856399cfSGordon Ross smb_threshold_fini(&sv->sv_tcon_ct); 517856399cfSGordon Ross smb_threshold_fini(&sv->sv_opipe_ct); 518856399cfSGordon Ross 5194163af6aSjose borrego smb_server_listener_destroy(&sv->sv_nbt_daemon); 5204163af6aSjose borrego smb_server_listener_destroy(&sv->sv_tcp_daemon); 521faa1795aSjb150015 rw_destroy(&sv->sv_cfg_lock); 522faa1795aSjb150015 smb_server_kstat_fini(sv); 5238622ec45SGordon Ross smb_kshare_fini(sv); 5248622ec45SGordon Ross smb_kdoor_fini(sv); 5259fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States smb_llist_destructor(&sv->sv_event_list); 526811599a4SMatt Barden smb_llist_destructor(&sv->sv_session_list); 5272c1b14e5Sjose borrego 528a90cf9f2SGordon Ross kmem_free(sv->sv_disp_stats1, 5298622ec45SGordon Ross SMB_COM_NUM * sizeof (smb_disp_stats_t)); 530faa1795aSjb150015 531a90cf9f2SGordon Ross kmem_free(sv->sv_disp_stats2, 532a90cf9f2SGordon Ross SMB2__NCMDS * sizeof (smb_disp_stats_t)); 533a90cf9f2SGordon Ross 534148c5f43SAlan Wright smb_srqueue_destroy(&sv->sv_srqueue); 535faa1795aSjb150015 smb_thread_destroy(&sv->si_thread_timers); 5368622ec45SGordon Ross 537faa1795aSjb150015 mutex_destroy(&sv->sv_mutex); 53894047d49SGordon Ross smb_hash_destroy(sv->sv_lease_ht); 539811599a4SMatt Barden smb_hash_destroy(sv->sv_persistid_ht); 540faa1795aSjb150015 cv_destroy(&sv->sv_cv); 541faa1795aSjb150015 sv->sv_magic = 0; 542faa1795aSjb150015 kmem_free(sv, sizeof (smb_server_t)); 543faa1795aSjb150015 544faa1795aSjb150015 return (0); 545faa1795aSjb150015 } 546faa1795aSjb150015 547faa1795aSjb150015 /* 548faa1795aSjb150015 * smb_server_configure 549faa1795aSjb150015 */ 550faa1795aSjb150015 int 55129bd2886SAlan Wright smb_server_configure(smb_ioc_cfg_t *ioc) 552faa1795aSjb150015 { 553faa1795aSjb150015 int rc = 0; 554faa1795aSjb150015 smb_server_t *sv; 555faa1795aSjb150015 5561d443a93SDan McDonald /* 5571d443a93SDan McDonald * Reality check negotiation token length vs. #define'd maximum. 5581d443a93SDan McDonald */ 5591d443a93SDan McDonald if (ioc->negtok_len > SMB_PI_MAX_NEGTOK) 5601d443a93SDan McDonald return (EINVAL); 5611d443a93SDan McDonald 562faa1795aSjb150015 rc = smb_server_lookup(&sv); 563faa1795aSjb150015 if (rc) 564faa1795aSjb150015 return (rc); 565faa1795aSjb150015 566faa1795aSjb150015 mutex_enter(&sv->sv_mutex); 567faa1795aSjb150015 switch (sv->sv_state) { 568faa1795aSjb150015 case SMB_SERVER_STATE_CREATED: 56929bd2886SAlan Wright smb_server_store_cfg(sv, ioc); 570faa1795aSjb150015 sv->sv_state = SMB_SERVER_STATE_CONFIGURED; 571faa1795aSjb150015 break; 572faa1795aSjb150015 573faa1795aSjb150015 case SMB_SERVER_STATE_CONFIGURED: 57429bd2886SAlan Wright smb_server_store_cfg(sv, ioc); 575faa1795aSjb150015 break; 576faa1795aSjb150015 577faa1795aSjb150015 case SMB_SERVER_STATE_RUNNING: 5789fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States case SMB_SERVER_STATE_STOPPING: 579faa1795aSjb150015 rw_enter(&sv->sv_cfg_lock, RW_WRITER); 58029bd2886SAlan Wright smb_server_store_cfg(sv, ioc); 581faa1795aSjb150015 rw_exit(&sv->sv_cfg_lock); 582faa1795aSjb150015 break; 583faa1795aSjb150015 584faa1795aSjb150015 default: 5859fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States SMB_SERVER_STATE_VALID(sv->sv_state); 586faa1795aSjb150015 rc = EFAULT; 587faa1795aSjb150015 break; 588faa1795aSjb150015 } 589faa1795aSjb150015 mutex_exit(&sv->sv_mutex); 590faa1795aSjb150015 591faa1795aSjb150015 smb_server_release(sv); 592faa1795aSjb150015 593faa1795aSjb150015 return (rc); 594faa1795aSjb150015 } 595faa1795aSjb150015 596faa1795aSjb150015 /* 597faa1795aSjb150015 * smb_server_start 598faa1795aSjb150015 */ 599faa1795aSjb150015 int 60029bd2886SAlan Wright smb_server_start(smb_ioc_start_t *ioc) 601faa1795aSjb150015 { 602faa1795aSjb150015 int rc = 0; 6034163af6aSjose borrego int family; 604faa1795aSjb150015 smb_server_t *sv; 605*8d94f651SGordon Ross cred_t *ucr; 606faa1795aSjb150015 607faa1795aSjb150015 rc = smb_server_lookup(&sv); 608faa1795aSjb150015 if (rc) 609faa1795aSjb150015 return (rc); 610faa1795aSjb150015 611faa1795aSjb150015 mutex_enter(&sv->sv_mutex); 612faa1795aSjb150015 switch (sv->sv_state) { 613faa1795aSjb150015 case SMB_SERVER_STATE_CONFIGURED: 614faa1795aSjb150015 6158622ec45SGordon Ross if ((rc = smb_server_fsop_start(sv)) != 0) 6168622ec45SGordon Ross break; 6178622ec45SGordon Ross 618*8d94f651SGordon Ross /* 619*8d94f651SGordon Ross * Note: smb_kshare_start needs sv_session. 620*8d94f651SGordon Ross */ 621*8d94f651SGordon Ross sv->sv_session = smb_session_create(NULL, 0, sv, 0); 622*8d94f651SGordon Ross if (sv->sv_session == NULL) { 623*8d94f651SGordon Ross rc = ENOMEM; 624*8d94f651SGordon Ross break; 625*8d94f651SGordon Ross } 626*8d94f651SGordon Ross 627*8d94f651SGordon Ross /* 628*8d94f651SGordon Ross * Create a logon on the server session, 629*8d94f651SGordon Ross * used when importing CA shares. 630*8d94f651SGordon Ross */ 631*8d94f651SGordon Ross sv->sv_rootuser = smb_user_new(sv->sv_session); 632*8d94f651SGordon Ross ucr = smb_kcred_create(); 633*8d94f651SGordon Ross rc = smb_user_logon(sv->sv_rootuser, ucr, "", "root", 634*8d94f651SGordon Ross SMB_USER_FLAG_ADMIN, 0, 0); 635*8d94f651SGordon Ross crfree(ucr); 636*8d94f651SGordon Ross ucr = NULL; 637*8d94f651SGordon Ross if (rc != 0) { 638*8d94f651SGordon Ross cmn_err(CE_NOTE, "smb_server_start: " 639*8d94f651SGordon Ross "failed to create root user"); 640*8d94f651SGordon Ross break; 641*8d94f651SGordon Ross } 642*8d94f651SGordon Ross 6438622ec45SGordon Ross if ((rc = smb_kshare_start(sv)) != 0) 6448622ec45SGordon Ross break; 6458622ec45SGordon Ross 646b819cea2SGordon Ross /* 647b819cea2SGordon Ross * NB: the proc passed here has to be a "system" one. 648b819cea2SGordon Ross * Normally that's p0, or the NGZ eqivalent. 649b819cea2SGordon Ross */ 6508622ec45SGordon Ross sv->sv_worker_pool = taskq_create_proc("smb_workers", 65108344b29SGordon Ross sv->sv_cfg.skc_maxworkers, smbsrv_worker_pri, 652faa1795aSjb150015 sv->sv_cfg.skc_maxworkers, INT_MAX, 6538622ec45SGordon Ross curzone->zone_zsched, TASKQ_DYNAMIC); 654faa1795aSjb150015 6558622ec45SGordon Ross sv->sv_receiver_pool = taskq_create_proc("smb_receivers", 65608344b29SGordon Ross sv->sv_cfg.skc_maxconnections, smbsrv_receive_pri, 6574163af6aSjose borrego sv->sv_cfg.skc_maxconnections, INT_MAX, 6588622ec45SGordon Ross curzone->zone_zsched, TASKQ_DYNAMIC); 6594163af6aSjose borrego 660*8d94f651SGordon Ross if (sv->sv_worker_pool == NULL || 661*8d94f651SGordon Ross sv->sv_receiver_pool == NULL) { 662faa1795aSjb150015 rc = ENOMEM; 663faa1795aSjb150015 break; 664faa1795aSjb150015 } 665faa1795aSjb150015 666b819cea2SGordon Ross #ifdef _KERNEL 667faa1795aSjb150015 ASSERT(sv->sv_lmshrd == NULL); 668148c5f43SAlan Wright sv->sv_lmshrd = smb_kshare_door_init(ioc->lmshrd); 669faa1795aSjb150015 if (sv->sv_lmshrd == NULL) 670faa1795aSjb150015 break; 67154026d5aSGordon Ross if ((rc = smb_kdoor_open(sv, ioc->udoor)) != 0) { 6729fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States cmn_err(CE_WARN, "Cannot open smbd door"); 673faa1795aSjb150015 break; 6749fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States } 675b819cea2SGordon Ross #else /* _KERNEL */ 676b819cea2SGordon Ross /* Fake kernel does not use the kshare_door */ 677b819cea2SGordon Ross fksmb_kdoor_open(sv, ioc->udoor_func); 678b819cea2SGordon Ross #endif /* _KERNEL */ 679b819cea2SGordon Ross 68054026d5aSGordon Ross if ((rc = smb_thread_start(&sv->si_thread_timers)) != 0) 6819fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States break; 6824163af6aSjose borrego 6834163af6aSjose borrego family = AF_INET; 6844163af6aSjose borrego smb_server_listener_init(sv, &sv->sv_nbt_daemon, 6854163af6aSjose borrego "smb_nbt_listener", IPPORT_NETBIOS_SSN, family); 6864163af6aSjose borrego if (sv->sv_cfg.skc_ipv6_enable) 6874163af6aSjose borrego family = AF_INET6; 6884163af6aSjose borrego smb_server_listener_init(sv, &sv->sv_tcp_daemon, 6894163af6aSjose borrego "smb_tcp_listener", IPPORT_SMB, family); 6904163af6aSjose borrego rc = smb_server_listener_start(&sv->sv_tcp_daemon); 6914163af6aSjose borrego if (rc != 0) 6924163af6aSjose borrego break; 69383d2dfe6SGordon Ross if (sv->sv_cfg.skc_netbios_enable) 69483d2dfe6SGordon Ross (void) smb_server_listener_start(&sv->sv_nbt_daemon); 6954163af6aSjose borrego 696faa1795aSjb150015 sv->sv_state = SMB_SERVER_STATE_RUNNING; 697148c5f43SAlan Wright sv->sv_start_time = gethrtime(); 698faa1795aSjb150015 mutex_exit(&sv->sv_mutex); 699faa1795aSjb150015 smb_server_release(sv); 7008622ec45SGordon Ross smb_export_start(sv); 701faa1795aSjb150015 return (0); 702faa1795aSjb150015 default: 7039fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States SMB_SERVER_STATE_VALID(sv->sv_state); 704faa1795aSjb150015 mutex_exit(&sv->sv_mutex); 705faa1795aSjb150015 smb_server_release(sv); 706faa1795aSjb150015 return (ENOTTY); 707faa1795aSjb150015 } 708faa1795aSjb150015 709faa1795aSjb150015 mutex_exit(&sv->sv_mutex); 7104163af6aSjose borrego smb_server_shutdown(sv); 711faa1795aSjb150015 smb_server_release(sv); 712faa1795aSjb150015 return (rc); 713faa1795aSjb150015 } 714faa1795aSjb150015 715faa1795aSjb150015 /* 7169fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States * An smbd is shutting down. 7179fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States */ 7189fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States int 7199fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States smb_server_stop(void) 7209fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States { 7219fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States smb_server_t *sv; 7229fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States int rc; 7239fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 7249fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States if ((rc = smb_server_lookup(&sv)) != 0) 7259fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States return (rc); 7269fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 7279fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States mutex_enter(&sv->sv_mutex); 7289fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States switch (sv->sv_state) { 7299fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States case SMB_SERVER_STATE_RUNNING: 7309fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States sv->sv_state = SMB_SERVER_STATE_STOPPING; 7314163af6aSjose borrego mutex_exit(&sv->sv_mutex); 7324163af6aSjose borrego smb_server_shutdown(sv); 7334163af6aSjose borrego mutex_enter(&sv->sv_mutex); 734cb174861Sjoyce mcintosh cv_broadcast(&sv->sp_info.sp_cv); 7359fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States break; 7369fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States default: 7379fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States SMB_SERVER_STATE_VALID(sv->sv_state); 7389fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States break; 7399fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States } 7409fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States mutex_exit(&sv->sv_mutex); 7419fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 7429fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States smb_server_release(sv); 7439fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States return (0); 7449fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States } 7459fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 7469fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States boolean_t 7478622ec45SGordon Ross smb_server_is_stopping(smb_server_t *sv) 7489fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States { 7499fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States boolean_t status; 7509fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 7519fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States SMB_SERVER_VALID(sv); 7529fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 7539fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States mutex_enter(&sv->sv_mutex); 7549fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 7559fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States switch (sv->sv_state) { 7569fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States case SMB_SERVER_STATE_STOPPING: 7579fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States case SMB_SERVER_STATE_DELETING: 7589fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States status = B_TRUE; 7599fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States break; 7609fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States default: 7619fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States status = B_FALSE; 7629fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States break; 7639fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States } 7649fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 7659fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States mutex_exit(&sv->sv_mutex); 7669fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States return (status); 7679fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States } 7689fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 7698622ec45SGordon Ross void 7708622ec45SGordon Ross smb_server_cancel_event(smb_server_t *sv, uint32_t txid) 7719fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States { 7729fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States smb_event_cancel(sv, txid); 7739fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States } 7749fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 7759fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States int 7769fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States smb_server_notify_event(smb_ioc_event_t *ioc) 7779fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States { 7789fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States smb_server_t *sv; 7799fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States int rc; 7809fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 7819fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States if ((rc = smb_server_lookup(&sv)) == 0) { 7829fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States smb_event_notify(sv, ioc->txid); 7839fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States smb_server_release(sv); 7849fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States } 7859fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 7869fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States return (rc); 7879fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States } 7889fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 7899fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States /* 790cb174861Sjoyce mcintosh * smb_server_spooldoc 791cb174861Sjoyce mcintosh * 792cb174861Sjoyce mcintosh * Waits for print file close broadcast. 793cb174861Sjoyce mcintosh * Gets the head of the fid list, 794cb174861Sjoyce mcintosh * then searches the spooldoc list and returns 795cb174861Sjoyce mcintosh * this info via the ioctl to user land. 796cb174861Sjoyce mcintosh * 797cb174861Sjoyce mcintosh * rc - 0 success 798cb174861Sjoyce mcintosh */ 799cb174861Sjoyce mcintosh 800cb174861Sjoyce mcintosh int 801cb174861Sjoyce mcintosh smb_server_spooldoc(smb_ioc_spooldoc_t *ioc) 802cb174861Sjoyce mcintosh { 803cb174861Sjoyce mcintosh smb_server_t *sv; 804cb174861Sjoyce mcintosh int rc; 805cb174861Sjoyce mcintosh smb_kspooldoc_t *spdoc; 806cb174861Sjoyce mcintosh uint16_t fid; 807cb174861Sjoyce mcintosh 80823a9c295SGordon Ross if ((rc = smb_server_lookup(&sv)) != 0) 80923a9c295SGordon Ross return (rc); 81023a9c295SGordon Ross 811b7301bf5SGordon Ross if (sv->sv_cfg.skc_print_enable == 0) { 812b7301bf5SGordon Ross rc = ENOTTY; 813b7301bf5SGordon Ross goto out; 814b7301bf5SGordon Ross } 815b7301bf5SGordon Ross 81623a9c295SGordon Ross mutex_enter(&sv->sv_mutex); 81723a9c295SGordon Ross for (;;) { 818cb174861Sjoyce mcintosh if (sv->sv_state != SMB_SERVER_STATE_RUNNING) { 819cb174861Sjoyce mcintosh rc = ECANCELED; 82023a9c295SGordon Ross break; 82123a9c295SGordon Ross } 82223a9c295SGordon Ross if ((fid = smb_spool_get_fid(sv)) != 0) { 82323a9c295SGordon Ross rc = 0; 82423a9c295SGordon Ross break; 82523a9c295SGordon Ross } 82623a9c295SGordon Ross if (cv_wait_sig(&sv->sp_info.sp_cv, &sv->sv_mutex) == 0) { 82723a9c295SGordon Ross rc = EINTR; 82823a9c295SGordon Ross break; 82923a9c295SGordon Ross } 83023a9c295SGordon Ross } 83123a9c295SGordon Ross mutex_exit(&sv->sv_mutex); 832b7301bf5SGordon Ross if (rc != 0) 833b7301bf5SGordon Ross goto out; 834b7301bf5SGordon Ross 83523a9c295SGordon Ross spdoc = kmem_zalloc(sizeof (*spdoc), KM_SLEEP); 83623a9c295SGordon Ross if (smb_spool_lookup_doc_byfid(sv, fid, spdoc)) { 837cb174861Sjoyce mcintosh ioc->spool_num = spdoc->sd_spool_num; 838cb174861Sjoyce mcintosh ioc->ipaddr = spdoc->sd_ipaddr; 839cb174861Sjoyce mcintosh (void) strlcpy(ioc->path, spdoc->sd_path, 840cb174861Sjoyce mcintosh MAXPATHLEN); 841cb174861Sjoyce mcintosh (void) strlcpy(ioc->username, 842cb174861Sjoyce mcintosh spdoc->sd_username, MAXNAMELEN); 84323a9c295SGordon Ross } else { 84423a9c295SGordon Ross /* Did not find that print job. */ 84523a9c295SGordon Ross rc = EAGAIN; 846cb174861Sjoyce mcintosh } 84723a9c295SGordon Ross kmem_free(spdoc, sizeof (*spdoc)); 84823a9c295SGordon Ross 849b7301bf5SGordon Ross out: 850cb174861Sjoyce mcintosh smb_server_release(sv); 851cb174861Sjoyce mcintosh return (rc); 852cb174861Sjoyce mcintosh } 853cb174861Sjoyce mcintosh 854faa1795aSjb150015 int 85529bd2886SAlan Wright smb_server_set_gmtoff(smb_ioc_gmt_t *ioc) 856faa1795aSjb150015 { 857faa1795aSjb150015 int rc; 858faa1795aSjb150015 smb_server_t *sv; 859faa1795aSjb150015 86008f0d8daSafshin salek ardakani - Sun Microsystems - Irvine United States if ((rc = smb_server_lookup(&sv)) == 0) { 86129bd2886SAlan Wright sv->si_gmtoff = ioc->offset; 862faa1795aSjb150015 smb_server_release(sv); 86308f0d8daSafshin salek ardakani - Sun Microsystems - Irvine United States } 864faa1795aSjb150015 865faa1795aSjb150015 return (rc); 866faa1795aSjb150015 } 867faa1795aSjb150015 86829bd2886SAlan Wright int 8691fcced4cSJordan Brown smb_server_numopen(smb_ioc_opennum_t *ioc) 87029bd2886SAlan Wright { 87129bd2886SAlan Wright smb_server_t *sv; 87229bd2886SAlan Wright int rc; 87329bd2886SAlan Wright 87429bd2886SAlan Wright if ((rc = smb_server_lookup(&sv)) == 0) { 875148c5f43SAlan Wright ioc->open_users = sv->sv_users; 876148c5f43SAlan Wright ioc->open_trees = sv->sv_trees; 877148c5f43SAlan Wright ioc->open_files = sv->sv_files + sv->sv_pipes; 87829bd2886SAlan Wright smb_server_release(sv); 87929bd2886SAlan Wright } 88029bd2886SAlan Wright return (rc); 88129bd2886SAlan Wright } 88229bd2886SAlan Wright 883faa1795aSjb150015 /* 8841fcced4cSJordan Brown * Enumerate objects within the server. The svcenum provides the 8851fcced4cSJordan Brown * enumeration context, i.e. what the caller want to get back. 8861fcced4cSJordan Brown */ 8871fcced4cSJordan Brown int 8881fcced4cSJordan Brown smb_server_enum(smb_ioc_svcenum_t *ioc) 8891fcced4cSJordan Brown { 8901fcced4cSJordan Brown smb_svcenum_t *svcenum = &ioc->svcenum; 8911fcced4cSJordan Brown smb_server_t *sv; 8921fcced4cSJordan Brown int rc; 8931fcced4cSJordan Brown 8941d443a93SDan McDonald /* 8951d443a93SDan McDonald * Reality check that the buffer-length insize the enum doesn't 8961d443a93SDan McDonald * overrun the ioctl's total length. 8971d443a93SDan McDonald */ 8981d443a93SDan McDonald if (svcenum->se_buflen + sizeof (*ioc) > ioc->hdr.len) 8991d443a93SDan McDonald return (EINVAL); 9001d443a93SDan McDonald 9011fcced4cSJordan Brown if ((rc = smb_server_lookup(&sv)) != 0) 9021fcced4cSJordan Brown return (rc); 9031fcced4cSJordan Brown 9041fcced4cSJordan Brown svcenum->se_bavail = svcenum->se_buflen; 9051fcced4cSJordan Brown svcenum->se_bused = 0; 9061fcced4cSJordan Brown svcenum->se_nitems = 0; 9071fcced4cSJordan Brown 9083b13a1efSThomas Keiser switch (svcenum->se_type) { 9093b13a1efSThomas Keiser case SMB_SVCENUM_TYPE_USER: 910*8d94f651SGordon Ross smb_server_enum_users(sv, svcenum); 9113b13a1efSThomas Keiser break; 9123b13a1efSThomas Keiser case SMB_SVCENUM_TYPE_TREE: 9133b13a1efSThomas Keiser case SMB_SVCENUM_TYPE_FILE: 914*8d94f651SGordon Ross smb_server_enum_trees(sv, svcenum); 9153b13a1efSThomas Keiser break; 9163b13a1efSThomas Keiser default: 9173b13a1efSThomas Keiser rc = EINVAL; 9183b13a1efSThomas Keiser } 9191fcced4cSJordan Brown 9201fcced4cSJordan Brown smb_server_release(sv); 9213b13a1efSThomas Keiser return (rc); 9221fcced4cSJordan Brown } 9231fcced4cSJordan Brown 9241fcced4cSJordan Brown /* 9251fcced4cSJordan Brown * Look for sessions to disconnect by client and user name. 9261fcced4cSJordan Brown */ 9271fcced4cSJordan Brown int 9281fcced4cSJordan Brown smb_server_session_close(smb_ioc_session_t *ioc) 9291fcced4cSJordan Brown { 9301fcced4cSJordan Brown smb_server_t *sv; 931811599a4SMatt Barden int cnt; 9321fcced4cSJordan Brown int rc; 9331fcced4cSJordan Brown 9341fcced4cSJordan Brown if ((rc = smb_server_lookup(&sv)) != 0) 9351fcced4cSJordan Brown return (rc); 9361fcced4cSJordan Brown 937*8d94f651SGordon Ross cnt = smb_server_session_disconnect(sv, ioc->client, ioc->username); 9381fcced4cSJordan Brown 9391fcced4cSJordan Brown smb_server_release(sv); 9401fcced4cSJordan Brown 941811599a4SMatt Barden if (cnt == 0) 9421fcced4cSJordan Brown return (ENOENT); 9431fcced4cSJordan Brown return (0); 9441fcced4cSJordan Brown } 9451fcced4cSJordan Brown 9461fcced4cSJordan Brown /* 9471fcced4cSJordan Brown * Close a file by uniqid. 9481fcced4cSJordan Brown */ 9491fcced4cSJordan Brown int 9501fcced4cSJordan Brown smb_server_file_close(smb_ioc_fileid_t *ioc) 9511fcced4cSJordan Brown { 9521fcced4cSJordan Brown uint32_t uniqid = ioc->uniqid; 9531fcced4cSJordan Brown smb_server_t *sv; 9541fcced4cSJordan Brown int rc; 9551fcced4cSJordan Brown 9561fcced4cSJordan Brown if ((rc = smb_server_lookup(&sv)) != 0) 9571fcced4cSJordan Brown return (rc); 9581fcced4cSJordan Brown 959*8d94f651SGordon Ross rc = smb_server_fclose(sv, uniqid); 9601fcced4cSJordan Brown 9611fcced4cSJordan Brown smb_server_release(sv); 9621fcced4cSJordan Brown return (rc); 9631fcced4cSJordan Brown } 9641fcced4cSJordan Brown 9651fcced4cSJordan Brown /* 966faa1795aSjb150015 * These functions determine the relevant smb server to which the call apply. 967faa1795aSjb150015 */ 968faa1795aSjb150015 969faa1795aSjb150015 uint32_t 9708622ec45SGordon Ross smb_server_get_session_count(smb_server_t *sv) 971faa1795aSjb150015 { 972faa1795aSjb150015 uint32_t counter = 0; 973faa1795aSjb150015 974811599a4SMatt Barden counter = smb_llist_get_count(&sv->sv_session_list); 975faa1795aSjb150015 976faa1795aSjb150015 return (counter); 977faa1795aSjb150015 } 978faa1795aSjb150015 979faa1795aSjb150015 /* 980*8d94f651SGordon Ross * Gets the smb_node of the specified share path. 981*8d94f651SGordon Ross * Node is returned held (caller must rele.) 982148c5f43SAlan Wright */ 983148c5f43SAlan Wright int 984*8d94f651SGordon Ross smb_server_share_lookup(smb_server_t *sv, const char *shr_path, 985*8d94f651SGordon Ross smb_node_t **nodepp) 986148c5f43SAlan Wright { 987148c5f43SAlan Wright smb_request_t *sr; 988148c5f43SAlan Wright smb_node_t *fnode = NULL; 989*8d94f651SGordon Ross smb_node_t *dnode = NULL; 990148c5f43SAlan Wright char last_comp[MAXNAMELEN]; 991148c5f43SAlan Wright int rc = 0; 992148c5f43SAlan Wright 993148c5f43SAlan Wright ASSERT(shr_path); 994148c5f43SAlan Wright 995148c5f43SAlan Wright mutex_enter(&sv->sv_mutex); 996148c5f43SAlan Wright switch (sv->sv_state) { 997148c5f43SAlan Wright case SMB_SERVER_STATE_RUNNING: 998148c5f43SAlan Wright break; 999148c5f43SAlan Wright default: 1000148c5f43SAlan Wright mutex_exit(&sv->sv_mutex); 1001148c5f43SAlan Wright return (ENOTACTIVE); 1002148c5f43SAlan Wright } 1003148c5f43SAlan Wright mutex_exit(&sv->sv_mutex); 1004148c5f43SAlan Wright 1005148c5f43SAlan Wright if ((sr = smb_request_alloc(sv->sv_session, 0)) == NULL) { 1006811599a4SMatt Barden return (ENOTCONN); 1007148c5f43SAlan Wright } 10088622ec45SGordon Ross sr->user_cr = zone_kcred(); 1009148c5f43SAlan Wright 1010148c5f43SAlan Wright rc = smb_pathname_reduce(sr, sr->user_cr, shr_path, 1011148c5f43SAlan Wright NULL, NULL, &dnode, last_comp); 1012148c5f43SAlan Wright 1013148c5f43SAlan Wright if (rc == 0) { 1014148c5f43SAlan Wright rc = smb_fsop_lookup(sr, sr->user_cr, SMB_FOLLOW_LINKS, 1015148c5f43SAlan Wright sv->si_root_smb_node, dnode, last_comp, &fnode); 1016148c5f43SAlan Wright smb_node_release(dnode); 1017148c5f43SAlan Wright } 1018148c5f43SAlan Wright 1019148c5f43SAlan Wright smb_request_free(sr); 1020148c5f43SAlan Wright 1021148c5f43SAlan Wright if (rc != 0) 1022148c5f43SAlan Wright return (rc); 1023148c5f43SAlan Wright 1024148c5f43SAlan Wright ASSERT(fnode->vp && fnode->vp->v_vfsp); 1025148c5f43SAlan Wright 1026*8d94f651SGordon Ross *nodepp = fnode; 1027148c5f43SAlan Wright 1028148c5f43SAlan Wright return (0); 1029148c5f43SAlan Wright } 1030148c5f43SAlan Wright 1031b819cea2SGordon Ross #ifdef _KERNEL 1032148c5f43SAlan Wright /* 1033148c5f43SAlan Wright * This is a special interface that will be utilized by ZFS to cause a share to 1034148c5f43SAlan Wright * be added/removed. 1035148c5f43SAlan Wright * 1036148c5f43SAlan Wright * arg is either a lmshare_info_t or share_name from userspace. 1037148c5f43SAlan Wright * It will need to be copied into the kernel. It is lmshare_info_t 1038148c5f43SAlan Wright * for add operations and share_name for delete operations. 1039148c5f43SAlan Wright */ 1040148c5f43SAlan Wright int 1041148c5f43SAlan Wright smb_server_share(void *arg, boolean_t add_share) 1042148c5f43SAlan Wright { 1043148c5f43SAlan Wright smb_server_t *sv; 1044148c5f43SAlan Wright int rc; 1045148c5f43SAlan Wright 1046148c5f43SAlan Wright if ((rc = smb_server_lookup(&sv)) == 0) { 1047148c5f43SAlan Wright mutex_enter(&sv->sv_mutex); 1048148c5f43SAlan Wright switch (sv->sv_state) { 1049148c5f43SAlan Wright case SMB_SERVER_STATE_RUNNING: 1050148c5f43SAlan Wright mutex_exit(&sv->sv_mutex); 1051148c5f43SAlan Wright (void) smb_kshare_upcall(sv->sv_lmshrd, arg, add_share); 1052148c5f43SAlan Wright break; 1053148c5f43SAlan Wright default: 1054148c5f43SAlan Wright mutex_exit(&sv->sv_mutex); 1055148c5f43SAlan Wright break; 1056148c5f43SAlan Wright } 1057148c5f43SAlan Wright smb_server_release(sv); 1058148c5f43SAlan Wright } 1059148c5f43SAlan Wright 1060148c5f43SAlan Wright return (rc); 1061148c5f43SAlan Wright } 1062b819cea2SGordon Ross #endif /* _KERNEL */ 1063148c5f43SAlan Wright 1064148c5f43SAlan Wright int 1065148c5f43SAlan Wright smb_server_unshare(const char *sharename) 1066148c5f43SAlan Wright { 1067148c5f43SAlan Wright smb_server_t *sv; 1068148c5f43SAlan Wright int rc; 1069148c5f43SAlan Wright 1070148c5f43SAlan Wright if ((rc = smb_server_lookup(&sv))) 1071148c5f43SAlan Wright return (rc); 1072148c5f43SAlan Wright 1073148c5f43SAlan Wright mutex_enter(&sv->sv_mutex); 1074148c5f43SAlan Wright switch (sv->sv_state) { 1075148c5f43SAlan Wright case SMB_SERVER_STATE_RUNNING: 1076148c5f43SAlan Wright case SMB_SERVER_STATE_STOPPING: 1077148c5f43SAlan Wright break; 1078148c5f43SAlan Wright default: 1079148c5f43SAlan Wright mutex_exit(&sv->sv_mutex); 1080148c5f43SAlan Wright smb_server_release(sv); 1081148c5f43SAlan Wright return (ENOTACTIVE); 1082148c5f43SAlan Wright } 1083148c5f43SAlan Wright mutex_exit(&sv->sv_mutex); 1084148c5f43SAlan Wright 1085*8d94f651SGordon Ross smb_server_disconnect_share(sv, sharename); 1086148c5f43SAlan Wright 1087148c5f43SAlan Wright smb_server_release(sv); 1088148c5f43SAlan Wright return (0); 1089148c5f43SAlan Wright } 1090148c5f43SAlan Wright 1091148c5f43SAlan Wright /* 10929fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States * Disconnect the specified share. 10939fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States * Typically called when a share has been removed. 1094faa1795aSjb150015 */ 10952c1b14e5Sjose borrego static void 1096*8d94f651SGordon Ross smb_server_disconnect_share(smb_server_t *sv, const char *sharename) 1097faa1795aSjb150015 { 1098*8d94f651SGordon Ross smb_llist_t *ll; 10999fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States smb_session_t *session; 11009fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 1101*8d94f651SGordon Ross ll = &sv->sv_session_list; 11024163af6aSjose borrego smb_llist_enter(ll, RW_READER); 11039fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 11044163af6aSjose borrego session = smb_llist_head(ll); 11059fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States while (session) { 11064163af6aSjose borrego SMB_SESSION_VALID(session); 11079fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States smb_rwx_rwenter(&session->s_lock, RW_READER); 11089fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States switch (session->s_state) { 11099fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States case SMB_SESSION_STATE_NEGOTIATED: 1110811599a4SMatt Barden smb_rwx_rwexit(&session->s_lock); 11119fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States smb_session_disconnect_share(session, sharename); 11129fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States break; 11139fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States default: 1114811599a4SMatt Barden smb_rwx_rwexit(&session->s_lock); 11159fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States break; 11169fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States } 11174163af6aSjose borrego session = smb_llist_next(ll, session); 11189fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States } 11199fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 11204163af6aSjose borrego smb_llist_exit(ll); 1121faa1795aSjb150015 } 1122faa1795aSjb150015 1123faa1795aSjb150015 /* 1124faa1795aSjb150015 * ***************************************************************************** 1125faa1795aSjb150015 * **************** Functions called from the internal layers ****************** 1126faa1795aSjb150015 * ***************************************************************************** 1127faa1795aSjb150015 * 1128faa1795aSjb150015 * These functions are provided the relevant smb server by the caller. 1129faa1795aSjb150015 */ 1130faa1795aSjb150015 1131faa1795aSjb150015 void 1132faa1795aSjb150015 smb_server_get_cfg(smb_server_t *sv, smb_kmod_cfg_t *cfg) 1133faa1795aSjb150015 { 1134faa1795aSjb150015 rw_enter(&sv->sv_cfg_lock, RW_READER); 1135faa1795aSjb150015 bcopy(&sv->sv_cfg, cfg, sizeof (*cfg)); 1136faa1795aSjb150015 rw_exit(&sv->sv_cfg_lock); 1137faa1795aSjb150015 } 1138faa1795aSjb150015 1139faa1795aSjb150015 /* 1140148c5f43SAlan Wright * 1141148c5f43SAlan Wright */ 1142148c5f43SAlan Wright void 1143148c5f43SAlan Wright smb_server_inc_nbt_sess(smb_server_t *sv) 1144148c5f43SAlan Wright { 1145148c5f43SAlan Wright SMB_SERVER_VALID(sv); 1146148c5f43SAlan Wright atomic_inc_32(&sv->sv_nbt_sess); 1147148c5f43SAlan Wright } 1148148c5f43SAlan Wright 1149148c5f43SAlan Wright void 1150148c5f43SAlan Wright smb_server_dec_nbt_sess(smb_server_t *sv) 1151148c5f43SAlan Wright { 1152148c5f43SAlan Wright SMB_SERVER_VALID(sv); 1153148c5f43SAlan Wright atomic_dec_32(&sv->sv_nbt_sess); 1154148c5f43SAlan Wright } 1155148c5f43SAlan Wright 1156148c5f43SAlan Wright void 1157148c5f43SAlan Wright smb_server_inc_tcp_sess(smb_server_t *sv) 1158148c5f43SAlan Wright { 1159148c5f43SAlan Wright SMB_SERVER_VALID(sv); 1160148c5f43SAlan Wright atomic_inc_32(&sv->sv_tcp_sess); 1161148c5f43SAlan Wright } 1162148c5f43SAlan Wright 1163148c5f43SAlan Wright void 1164148c5f43SAlan Wright smb_server_dec_tcp_sess(smb_server_t *sv) 1165148c5f43SAlan Wright { 1166148c5f43SAlan Wright SMB_SERVER_VALID(sv); 1167148c5f43SAlan Wright atomic_dec_32(&sv->sv_tcp_sess); 1168148c5f43SAlan Wright } 1169148c5f43SAlan Wright 1170148c5f43SAlan Wright void 1171148c5f43SAlan Wright smb_server_inc_users(smb_server_t *sv) 1172148c5f43SAlan Wright { 1173148c5f43SAlan Wright SMB_SERVER_VALID(sv); 1174148c5f43SAlan Wright atomic_inc_32(&sv->sv_users); 1175148c5f43SAlan Wright } 1176148c5f43SAlan Wright 1177148c5f43SAlan Wright void 1178148c5f43SAlan Wright smb_server_dec_users(smb_server_t *sv) 1179148c5f43SAlan Wright { 1180148c5f43SAlan Wright SMB_SERVER_VALID(sv); 1181148c5f43SAlan Wright atomic_dec_32(&sv->sv_users); 1182148c5f43SAlan Wright } 1183148c5f43SAlan Wright 1184148c5f43SAlan Wright void 1185148c5f43SAlan Wright smb_server_inc_trees(smb_server_t *sv) 1186148c5f43SAlan Wright { 1187148c5f43SAlan Wright SMB_SERVER_VALID(sv); 1188148c5f43SAlan Wright atomic_inc_32(&sv->sv_trees); 1189148c5f43SAlan Wright } 1190148c5f43SAlan Wright 1191148c5f43SAlan Wright void 1192148c5f43SAlan Wright smb_server_dec_trees(smb_server_t *sv) 1193148c5f43SAlan Wright { 1194148c5f43SAlan Wright SMB_SERVER_VALID(sv); 1195148c5f43SAlan Wright atomic_dec_32(&sv->sv_trees); 1196148c5f43SAlan Wright } 1197148c5f43SAlan Wright 1198148c5f43SAlan Wright void 1199148c5f43SAlan Wright smb_server_inc_files(smb_server_t *sv) 1200148c5f43SAlan Wright { 1201148c5f43SAlan Wright SMB_SERVER_VALID(sv); 1202148c5f43SAlan Wright atomic_inc_32(&sv->sv_files); 1203148c5f43SAlan Wright } 1204148c5f43SAlan Wright 1205148c5f43SAlan Wright void 1206148c5f43SAlan Wright smb_server_dec_files(smb_server_t *sv) 1207148c5f43SAlan Wright { 1208148c5f43SAlan Wright SMB_SERVER_VALID(sv); 1209148c5f43SAlan Wright atomic_dec_32(&sv->sv_files); 1210148c5f43SAlan Wright } 1211148c5f43SAlan Wright 1212148c5f43SAlan Wright void 1213148c5f43SAlan Wright smb_server_inc_pipes(smb_server_t *sv) 1214148c5f43SAlan Wright { 1215148c5f43SAlan Wright SMB_SERVER_VALID(sv); 1216148c5f43SAlan Wright atomic_inc_32(&sv->sv_pipes); 1217148c5f43SAlan Wright } 1218148c5f43SAlan Wright 1219148c5f43SAlan Wright void 1220148c5f43SAlan Wright smb_server_dec_pipes(smb_server_t *sv) 1221148c5f43SAlan Wright { 1222148c5f43SAlan Wright SMB_SERVER_VALID(sv); 1223148c5f43SAlan Wright atomic_dec_32(&sv->sv_pipes); 1224148c5f43SAlan Wright } 1225148c5f43SAlan Wright 1226148c5f43SAlan Wright void 1227148c5f43SAlan Wright smb_server_add_rxb(smb_server_t *sv, int64_t value) 1228148c5f43SAlan Wright { 1229148c5f43SAlan Wright SMB_SERVER_VALID(sv); 1230148c5f43SAlan Wright atomic_add_64(&sv->sv_rxb, value); 1231148c5f43SAlan Wright } 1232148c5f43SAlan Wright 1233148c5f43SAlan Wright void 1234148c5f43SAlan Wright smb_server_add_txb(smb_server_t *sv, int64_t value) 1235148c5f43SAlan Wright { 1236148c5f43SAlan Wright SMB_SERVER_VALID(sv); 1237148c5f43SAlan Wright atomic_add_64(&sv->sv_txb, value); 1238148c5f43SAlan Wright } 1239148c5f43SAlan Wright 1240148c5f43SAlan Wright void 1241148c5f43SAlan Wright smb_server_inc_req(smb_server_t *sv) 1242148c5f43SAlan Wright { 1243148c5f43SAlan Wright SMB_SERVER_VALID(sv); 1244148c5f43SAlan Wright atomic_inc_64(&sv->sv_nreq); 1245148c5f43SAlan Wright } 1246148c5f43SAlan Wright 1247148c5f43SAlan Wright /* 1248faa1795aSjb150015 * ***************************************************************************** 1249faa1795aSjb150015 * *************************** Static Functions ******************************** 1250faa1795aSjb150015 * ***************************************************************************** 1251faa1795aSjb150015 */ 1252faa1795aSjb150015 1253faa1795aSjb150015 static void 1254faa1795aSjb150015 smb_server_timers(smb_thread_t *thread, void *arg) 1255faa1795aSjb150015 { 1256faa1795aSjb150015 smb_server_t *sv = (smb_server_t *)arg; 1257faa1795aSjb150015 1258faa1795aSjb150015 ASSERT(sv != NULL); 1259faa1795aSjb150015 1260b819cea2SGordon Ross /* 1261811599a4SMatt Barden * This kills old inactive sessions and expired durable 1262811599a4SMatt Barden * handles. The session code expects one call per minute. 1263b819cea2SGordon Ross */ 1264b819cea2SGordon Ross while (smb_thread_continue_timedwait(thread, 60 /* Seconds */)) { 1265811599a4SMatt Barden if (sv->sv_cfg.skc_keepalive != 0) 1266811599a4SMatt Barden smb_session_timers(sv); 1267811599a4SMatt Barden smb2_durable_timers(sv); 1268faa1795aSjb150015 } 1269faa1795aSjb150015 } 1270faa1795aSjb150015 1271faa1795aSjb150015 /* 1272faa1795aSjb150015 * smb_server_kstat_init 1273faa1795aSjb150015 */ 1274148c5f43SAlan Wright static void 1275faa1795aSjb150015 smb_server_kstat_init(smb_server_t *sv) 1276faa1795aSjb150015 { 1277cb174861Sjoyce mcintosh 12788622ec45SGordon Ross sv->sv_ksp = kstat_create_zone(SMBSRV_KSTAT_MODULE, 0, 1279148c5f43SAlan Wright SMBSRV_KSTAT_STATISTICS, SMBSRV_KSTAT_CLASS, KSTAT_TYPE_RAW, 1280148c5f43SAlan Wright sizeof (smbsrv_kstats_t), 0, sv->sv_zid); 1281faa1795aSjb150015 1282148c5f43SAlan Wright if (sv->sv_ksp != NULL) { 1283148c5f43SAlan Wright sv->sv_ksp->ks_update = smb_server_kstat_update; 1284148c5f43SAlan Wright sv->sv_ksp->ks_private = sv; 1285148c5f43SAlan Wright ((smbsrv_kstats_t *)sv->sv_ksp->ks_data)->ks_start_time = 1286148c5f43SAlan Wright sv->sv_start_time; 12878622ec45SGordon Ross smb_dispatch_stats_init(sv); 1288a90cf9f2SGordon Ross smb2_dispatch_stats_init(sv); 1289faa1795aSjb150015 kstat_install(sv->sv_ksp); 1290148c5f43SAlan Wright } else { 1291148c5f43SAlan Wright cmn_err(CE_WARN, "SMB Server: Statistics unavailable"); 1292faa1795aSjb150015 } 1293cb174861Sjoyce mcintosh 12948622ec45SGordon Ross sv->sv_legacy_ksp = kstat_create_zone(SMBSRV_KSTAT_MODULE, 0, 12958622ec45SGordon Ross SMBSRV_KSTAT_NAME, SMBSRV_KSTAT_CLASS, KSTAT_TYPE_NAMED, 12968622ec45SGordon Ross sizeof (smb_server_legacy_kstat_t) / sizeof (kstat_named_t), 12978622ec45SGordon Ross 0, sv->sv_zid); 1298cb174861Sjoyce mcintosh 1299cb174861Sjoyce mcintosh if (sv->sv_legacy_ksp != NULL) { 1300cb174861Sjoyce mcintosh smb_server_legacy_kstat_t *ksd; 1301cb174861Sjoyce mcintosh 1302cb174861Sjoyce mcintosh ksd = sv->sv_legacy_ksp->ks_data; 1303cb174861Sjoyce mcintosh 1304cb174861Sjoyce mcintosh (void) strlcpy(ksd->ls_files.name, "open_files", 1305cb174861Sjoyce mcintosh sizeof (ksd->ls_files.name)); 1306cb174861Sjoyce mcintosh ksd->ls_files.data_type = KSTAT_DATA_UINT32; 1307cb174861Sjoyce mcintosh 1308cb174861Sjoyce mcintosh (void) strlcpy(ksd->ls_trees.name, "connections", 1309cb174861Sjoyce mcintosh sizeof (ksd->ls_trees.name)); 1310cb174861Sjoyce mcintosh ksd->ls_trees.data_type = KSTAT_DATA_UINT32; 1311cb174861Sjoyce mcintosh 1312cb174861Sjoyce mcintosh (void) strlcpy(ksd->ls_users.name, "connections", 1313cb174861Sjoyce mcintosh sizeof (ksd->ls_users.name)); 1314cb174861Sjoyce mcintosh ksd->ls_users.data_type = KSTAT_DATA_UINT32; 1315cb174861Sjoyce mcintosh 1316cb174861Sjoyce mcintosh mutex_init(&sv->sv_legacy_ksmtx, NULL, MUTEX_DEFAULT, NULL); 1317cb174861Sjoyce mcintosh sv->sv_legacy_ksp->ks_lock = &sv->sv_legacy_ksmtx; 1318cb174861Sjoyce mcintosh sv->sv_legacy_ksp->ks_update = smb_server_legacy_kstat_update; 1319cb174861Sjoyce mcintosh kstat_install(sv->sv_legacy_ksp); 1320cb174861Sjoyce mcintosh } 1321faa1795aSjb150015 } 1322faa1795aSjb150015 1323faa1795aSjb150015 /* 1324faa1795aSjb150015 * smb_server_kstat_fini 1325faa1795aSjb150015 */ 1326faa1795aSjb150015 static void 1327faa1795aSjb150015 smb_server_kstat_fini(smb_server_t *sv) 1328faa1795aSjb150015 { 1329cb174861Sjoyce mcintosh if (sv->sv_legacy_ksp != NULL) { 1330cb174861Sjoyce mcintosh kstat_delete(sv->sv_legacy_ksp); 1331cb174861Sjoyce mcintosh mutex_destroy(&sv->sv_legacy_ksmtx); 1332cb174861Sjoyce mcintosh sv->sv_legacy_ksp = NULL; 1333cb174861Sjoyce mcintosh } 1334cb174861Sjoyce mcintosh 1335148c5f43SAlan Wright if (sv->sv_ksp != NULL) { 1336faa1795aSjb150015 kstat_delete(sv->sv_ksp); 1337faa1795aSjb150015 sv->sv_ksp = NULL; 13388622ec45SGordon Ross smb_dispatch_stats_fini(sv); 1339a90cf9f2SGordon Ross smb2_dispatch_stats_fini(sv); 1340faa1795aSjb150015 } 1341faa1795aSjb150015 } 1342faa1795aSjb150015 1343148c5f43SAlan Wright /* 1344148c5f43SAlan Wright * smb_server_kstat_update 1345148c5f43SAlan Wright */ 1346faa1795aSjb150015 static int 1347148c5f43SAlan Wright smb_server_kstat_update(kstat_t *ksp, int rw) 1348faa1795aSjb150015 { 1349faa1795aSjb150015 smb_server_t *sv; 1350148c5f43SAlan Wright smbsrv_kstats_t *ksd; 1351faa1795aSjb150015 1352148c5f43SAlan Wright if (rw == KSTAT_READ) { 1353148c5f43SAlan Wright sv = ksp->ks_private; 13549fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States SMB_SERVER_VALID(sv); 1355148c5f43SAlan Wright ksd = (smbsrv_kstats_t *)ksp->ks_data; 1356148c5f43SAlan Wright /* 1357148c5f43SAlan Wright * Counters 1358148c5f43SAlan Wright */ 1359148c5f43SAlan Wright ksd->ks_nbt_sess = sv->sv_nbt_sess; 1360148c5f43SAlan Wright ksd->ks_tcp_sess = sv->sv_tcp_sess; 1361148c5f43SAlan Wright ksd->ks_users = sv->sv_users; 1362148c5f43SAlan Wright ksd->ks_trees = sv->sv_trees; 1363148c5f43SAlan Wright ksd->ks_files = sv->sv_files; 1364148c5f43SAlan Wright ksd->ks_pipes = sv->sv_pipes; 1365148c5f43SAlan Wright /* 1366148c5f43SAlan Wright * Throughput 1367148c5f43SAlan Wright */ 1368148c5f43SAlan Wright ksd->ks_txb = sv->sv_txb; 1369148c5f43SAlan Wright ksd->ks_rxb = sv->sv_rxb; 1370148c5f43SAlan Wright ksd->ks_nreq = sv->sv_nreq; 1371148c5f43SAlan Wright /* 1372148c5f43SAlan Wright * Busyness 1373148c5f43SAlan Wright */ 1374148c5f43SAlan Wright ksd->ks_maxreqs = sv->sv_cfg.skc_maxworkers; 1375148c5f43SAlan Wright smb_srqueue_update(&sv->sv_srqueue, 1376148c5f43SAlan Wright &ksd->ks_utilization); 1377148c5f43SAlan Wright /* 1378148c5f43SAlan Wright * Latency & Throughput of the requests 1379148c5f43SAlan Wright */ 1380a90cf9f2SGordon Ross smb_dispatch_stats_update(sv, ksd->ks_reqs1, 0, SMB_COM_NUM); 1381a90cf9f2SGordon Ross smb2_dispatch_stats_update(sv, ksd->ks_reqs2, 0, SMB2__NCMDS); 1382faa1795aSjb150015 return (0); 1383faa1795aSjb150015 } 1384148c5f43SAlan Wright if (rw == KSTAT_WRITE) 1385148c5f43SAlan Wright return (EACCES); 1386148c5f43SAlan Wright 1387148c5f43SAlan Wright return (EIO); 1388148c5f43SAlan Wright } 1389faa1795aSjb150015 1390cb174861Sjoyce mcintosh static int 1391cb174861Sjoyce mcintosh smb_server_legacy_kstat_update(kstat_t *ksp, int rw) 1392cb174861Sjoyce mcintosh { 1393cb174861Sjoyce mcintosh smb_server_t *sv; 1394cb174861Sjoyce mcintosh smb_server_legacy_kstat_t *ksd; 1395cb174861Sjoyce mcintosh int rc; 1396cb174861Sjoyce mcintosh 1397cb174861Sjoyce mcintosh switch (rw) { 1398cb174861Sjoyce mcintosh case KSTAT_WRITE: 1399cb174861Sjoyce mcintosh rc = EACCES; 1400cb174861Sjoyce mcintosh break; 1401cb174861Sjoyce mcintosh case KSTAT_READ: 1402cb174861Sjoyce mcintosh if (!smb_server_lookup(&sv)) { 1403cb174861Sjoyce mcintosh ASSERT(MUTEX_HELD(ksp->ks_lock)); 1404cb174861Sjoyce mcintosh ASSERT(sv->sv_legacy_ksp == ksp); 1405cb174861Sjoyce mcintosh ksd = (smb_server_legacy_kstat_t *)ksp->ks_data; 1406cb174861Sjoyce mcintosh ksd->ls_files.value.ui32 = sv->sv_files + sv->sv_pipes; 1407cb174861Sjoyce mcintosh ksd->ls_trees.value.ui32 = sv->sv_trees; 1408cb174861Sjoyce mcintosh ksd->ls_users.value.ui32 = sv->sv_users; 1409cb174861Sjoyce mcintosh smb_server_release(sv); 1410cb174861Sjoyce mcintosh rc = 0; 1411cb174861Sjoyce mcintosh break; 1412cb174861Sjoyce mcintosh } 14132d63d7e2SToomas Soome /* FALLTHROUGH */ 1414cb174861Sjoyce mcintosh default: 1415cb174861Sjoyce mcintosh rc = EIO; 1416cb174861Sjoyce mcintosh break; 1417cb174861Sjoyce mcintosh } 1418cb174861Sjoyce mcintosh return (rc); 1419cb174861Sjoyce mcintosh 1420cb174861Sjoyce mcintosh } 1421cb174861Sjoyce mcintosh 1422faa1795aSjb150015 /* 14234163af6aSjose borrego * smb_server_shutdown 1424faa1795aSjb150015 */ 1425faa1795aSjb150015 static void 14269fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States smb_server_shutdown(smb_server_t *sv) 1427faa1795aSjb150015 { 1428811599a4SMatt Barden smb_llist_t *sl = &sv->sv_session_list; 1429811599a4SMatt Barden smb_session_t *session; 1430811599a4SMatt Barden clock_t time; 1431811599a4SMatt Barden 14329fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States SMB_SERVER_VALID(sv); 1433faa1795aSjb150015 1434856399cfSGordon Ross /* 1435856399cfSGordon Ross * Stop the listeners first, so we don't get any more 1436856399cfSGordon Ross * new work while we're trying to shut down. 1437856399cfSGordon Ross */ 1438856399cfSGordon Ross smb_server_listener_stop(&sv->sv_nbt_daemon); 1439856399cfSGordon Ross smb_server_listener_stop(&sv->sv_tcp_daemon); 1440faa1795aSjb150015 smb_thread_stop(&sv->si_thread_timers); 1441856399cfSGordon Ross 1442811599a4SMatt Barden /* Disconnect all of the sessions */ 1443811599a4SMatt Barden smb_llist_enter(sl, RW_READER); 1444811599a4SMatt Barden session = smb_llist_head(sl); 1445811599a4SMatt Barden while (session != NULL) { 1446811599a4SMatt Barden smb_session_disconnect(session); 1447811599a4SMatt Barden session = smb_llist_next(sl, session); 1448811599a4SMatt Barden } 1449811599a4SMatt Barden smb_llist_exit(sl); 1450811599a4SMatt Barden 1451856399cfSGordon Ross /* 1452856399cfSGordon Ross * Wake up any threads we might have blocked. 1453856399cfSGordon Ross * Must precede kdoor_close etc. because those will 1454856399cfSGordon Ross * wait for such threads to get out. 1455856399cfSGordon Ross */ 1456856399cfSGordon Ross smb_event_cancel(sv, 0); 1457856399cfSGordon Ross smb_threshold_wake_all(&sv->sv_ssetup_ct); 1458856399cfSGordon Ross smb_threshold_wake_all(&sv->sv_tcon_ct); 1459856399cfSGordon Ross smb_threshold_wake_all(&sv->sv_opipe_ct); 1460856399cfSGordon Ross 1461811599a4SMatt Barden /* 1462811599a4SMatt Barden * Wait for the session list to empty. 1463811599a4SMatt Barden * (cv_signal in smb_server_destroy_session) 1464811599a4SMatt Barden * 1465811599a4SMatt Barden * This should not take long, but if there are any leaked 1466811599a4SMatt Barden * references to ofiles, trees, or users, there could be a 1467811599a4SMatt Barden * session hanging around. If that happens, the ll_count 1468811599a4SMatt Barden * never gets to zero and we'll never get the sv_signal. 1469811599a4SMatt Barden * Defend against that problem using timed wait, then 1470811599a4SMatt Barden * complain if we find sessions left over and continue 1471811599a4SMatt Barden * with shutdown in spite of any leaked sessions. 1472811599a4SMatt Barden * That's better than a server that won't reboot. 1473811599a4SMatt Barden */ 1474811599a4SMatt Barden time = SEC_TO_TICK(10) + ddi_get_lbolt(); 1475811599a4SMatt Barden mutex_enter(&sv->sv_mutex); 1476811599a4SMatt Barden while (sv->sv_session_list.ll_count != 0) { 1477811599a4SMatt Barden if (cv_timedwait(&sv->sv_cv, &sv->sv_mutex, time) < 0) 1478811599a4SMatt Barden break; 1479811599a4SMatt Barden } 1480811599a4SMatt Barden mutex_exit(&sv->sv_mutex); 1481811599a4SMatt Barden #ifdef DEBUG 1482811599a4SMatt Barden if (sv->sv_session_list.ll_count != 0) { 1483811599a4SMatt Barden cmn_err(CE_NOTE, "shutdown leaked sessions"); 1484811599a4SMatt Barden debug_enter("shutdown leaked sessions"); 1485811599a4SMatt Barden } 1486811599a4SMatt Barden #endif 1487811599a4SMatt Barden 1488811599a4SMatt Barden /* 1489811599a4SMatt Barden * Clean out any durable handles. After this we should 1490811599a4SMatt Barden * have no ofiles remaining (and no more oplock breaks). 1491811599a4SMatt Barden */ 1492811599a4SMatt Barden smb2_dh_shutdown(sv); 1493811599a4SMatt Barden 14948622ec45SGordon Ross smb_kdoor_close(sv); 1495b819cea2SGordon Ross #ifdef _KERNEL 1496148c5f43SAlan Wright smb_kshare_door_fini(sv->sv_lmshrd); 1497b819cea2SGordon Ross #endif /* _KERNEL */ 14980dcb3379Sjb150015 sv->sv_lmshrd = NULL; 1499b819cea2SGordon Ross 15008622ec45SGordon Ross smb_export_stop(sv); 1501811599a4SMatt Barden smb_kshare_stop(sv); 15028d96b23eSAlan Wright 15034846df9bSKevin Crowe /* 1504811599a4SMatt Barden * Both kshare and the oplock break sub-systems may have 1505811599a4SMatt Barden * taskq jobs on the spcial "server" session, until we've 1506811599a4SMatt Barden * closed all ofiles and stopped the kshare exporter. 1507811599a4SMatt Barden * Now it's safe to destroy the server session, but first 1508811599a4SMatt Barden * wait for any requests on it to finish. Note that for 1509811599a4SMatt Barden * normal sessions, this happens in smb_session_cancel, 1510811599a4SMatt Barden * but that's not called for the server session. 15114846df9bSKevin Crowe */ 1512*8d94f651SGordon Ross if (sv->sv_rootuser != NULL) { 1513*8d94f651SGordon Ross smb_user_logoff(sv->sv_rootuser); 1514*8d94f651SGordon Ross smb_user_release(sv->sv_rootuser); 1515*8d94f651SGordon Ross sv->sv_rootuser = NULL; 1516*8d94f651SGordon Ross } 1517811599a4SMatt Barden if (sv->sv_session != NULL) { 15184846df9bSKevin Crowe smb_slist_wait_for_empty(&sv->sv_session->s_req_list); 15194846df9bSKevin Crowe 1520*8d94f651SGordon Ross /* Just in case import left users and trees */ 1521*8d94f651SGordon Ross smb_session_logoff(sv->sv_session); 1522*8d94f651SGordon Ross 1523faa1795aSjb150015 smb_session_delete(sv->sv_session); 1524faa1795aSjb150015 sv->sv_session = NULL; 1525faa1795aSjb150015 } 15268d96b23eSAlan Wright 15274163af6aSjose borrego if (sv->sv_receiver_pool != NULL) { 15284163af6aSjose borrego taskq_destroy(sv->sv_receiver_pool); 15294163af6aSjose borrego sv->sv_receiver_pool = NULL; 15304163af6aSjose borrego } 15314163af6aSjose borrego 15324163af6aSjose borrego if (sv->sv_worker_pool != NULL) { 15334163af6aSjose borrego taskq_destroy(sv->sv_worker_pool); 15344163af6aSjose borrego sv->sv_worker_pool = NULL; 15358d96b23eSAlan Wright } 15368622ec45SGordon Ross 15378622ec45SGordon Ross smb_server_fsop_stop(sv); 1538faa1795aSjb150015 } 1539faa1795aSjb150015 15404163af6aSjose borrego /* 15414163af6aSjose borrego * smb_server_listener_init 15424163af6aSjose borrego * 15434163af6aSjose borrego * Initializes listener contexts. 15444163af6aSjose borrego */ 15454163af6aSjose borrego static void 15464163af6aSjose borrego smb_server_listener_init( 1547faa1795aSjb150015 smb_server_t *sv, 1548faa1795aSjb150015 smb_listener_daemon_t *ld, 15494163af6aSjose borrego char *name, 1550faa1795aSjb150015 in_port_t port, 15514163af6aSjose borrego int family) 1552faa1795aSjb150015 { 15534163af6aSjose borrego ASSERT(ld->ld_magic != SMB_LISTENER_MAGIC); 1554faa1795aSjb150015 15554163af6aSjose borrego bzero(ld, sizeof (*ld)); 1556faa1795aSjb150015 15574163af6aSjose borrego ld->ld_sv = sv; 15584163af6aSjose borrego ld->ld_family = family; 15594163af6aSjose borrego ld->ld_port = port; 15604163af6aSjose borrego 15617f667e74Sjose borrego if (family == AF_INET) { 15627f667e74Sjose borrego ld->ld_sin.sin_family = (uint32_t)family; 1563faa1795aSjb150015 ld->ld_sin.sin_port = htons(port); 1564faa1795aSjb150015 ld->ld_sin.sin_addr.s_addr = htonl(INADDR_ANY); 15657f667e74Sjose borrego } else { 15667f667e74Sjose borrego ld->ld_sin6.sin6_family = (uint32_t)family; 15677f667e74Sjose borrego ld->ld_sin6.sin6_port = htons(port); 15687f667e74Sjose borrego (void) memset(&ld->ld_sin6.sin6_addr.s6_addr, 0, 15697f667e74Sjose borrego sizeof (ld->ld_sin6.sin6_addr.s6_addr)); 15707f667e74Sjose borrego } 1571faa1795aSjb150015 157208344b29SGordon Ross smb_thread_init(&ld->ld_thread, name, smb_server_listener, ld, 157308344b29SGordon Ross smbsrv_listen_pri); 15744163af6aSjose borrego ld->ld_magic = SMB_LISTENER_MAGIC; 15754163af6aSjose borrego } 15764163af6aSjose borrego 15774163af6aSjose borrego /* 15784163af6aSjose borrego * smb_server_listener_destroy 15794163af6aSjose borrego * 15804163af6aSjose borrego * Destroyes listener contexts. 15814163af6aSjose borrego */ 15824163af6aSjose borrego static void 15834163af6aSjose borrego smb_server_listener_destroy(smb_listener_daemon_t *ld) 15844163af6aSjose borrego { 158583d2dfe6SGordon Ross /* 158683d2dfe6SGordon Ross * Note that if startup fails early, we can legitimately 158783d2dfe6SGordon Ross * get here with an all-zeros object. 158883d2dfe6SGordon Ross */ 158983d2dfe6SGordon Ross if (ld->ld_magic == 0) 159083d2dfe6SGordon Ross return; 159183d2dfe6SGordon Ross 15924163af6aSjose borrego SMB_LISTENER_VALID(ld); 15934163af6aSjose borrego ASSERT(ld->ld_so == NULL); 15944163af6aSjose borrego smb_thread_destroy(&ld->ld_thread); 15954163af6aSjose borrego ld->ld_magic = 0; 15964163af6aSjose borrego } 15974163af6aSjose borrego 15984163af6aSjose borrego /* 15994163af6aSjose borrego * smb_server_listener_start 16004163af6aSjose borrego * 16014163af6aSjose borrego * Starts the listener associated with the context passed in. 16024163af6aSjose borrego * 16034163af6aSjose borrego * Return: 0 Success 16044163af6aSjose borrego * not 0 Failure 16054163af6aSjose borrego */ 16064163af6aSjose borrego static int 16074163af6aSjose borrego smb_server_listener_start(smb_listener_daemon_t *ld) 16084163af6aSjose borrego { 16094163af6aSjose borrego int rc; 16104163af6aSjose borrego uint32_t on; 16114163af6aSjose borrego uint32_t off; 16124163af6aSjose borrego 16134163af6aSjose borrego SMB_LISTENER_VALID(ld); 16144163af6aSjose borrego 16154163af6aSjose borrego if (ld->ld_so != NULL) 16164163af6aSjose borrego return (EINVAL); 16174163af6aSjose borrego 16184163af6aSjose borrego ld->ld_so = smb_socreate(ld->ld_family, SOCK_STREAM, 0); 16199fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States if (ld->ld_so == NULL) { 16204163af6aSjose borrego cmn_err(CE_WARN, "port %d: socket create failed", ld->ld_port); 16219fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States return (ENOMEM); 16229fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States } 16239fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 16249fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States off = 0; 16250f1702c5SYu Xiangning (void) ksocket_setsockopt(ld->ld_so, SOL_SOCKET, 1626fc724630SAlan Wright SO_MAC_EXEMPT, &off, sizeof (off), CRED()); 16279fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 16289fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States on = 1; 1629fc724630SAlan Wright (void) ksocket_setsockopt(ld->ld_so, SOL_SOCKET, 1630fc724630SAlan Wright SO_REUSEADDR, &on, sizeof (on), CRED()); 1631fc724630SAlan Wright 16324163af6aSjose borrego if (ld->ld_family == AF_INET) { 16330f1702c5SYu Xiangning rc = ksocket_bind(ld->ld_so, 16340f1702c5SYu Xiangning (struct sockaddr *)&ld->ld_sin, 16350f1702c5SYu Xiangning sizeof (ld->ld_sin), CRED()); 16367f667e74Sjose borrego } else { 16377f667e74Sjose borrego rc = ksocket_bind(ld->ld_so, 16387f667e74Sjose borrego (struct sockaddr *)&ld->ld_sin6, 16397f667e74Sjose borrego sizeof (ld->ld_sin6), CRED()); 16407f667e74Sjose borrego } 16419fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 16429fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States if (rc != 0) { 16434163af6aSjose borrego cmn_err(CE_WARN, "port %d: bind failed", ld->ld_port); 16449fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States return (rc); 16459fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States } 16469fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 16470f1702c5SYu Xiangning rc = ksocket_listen(ld->ld_so, 20, CRED()); 1648faa1795aSjb150015 if (rc < 0) { 16494163af6aSjose borrego cmn_err(CE_WARN, "port %d: listen failed", ld->ld_port); 1650faa1795aSjb150015 return (rc); 1651faa1795aSjb150015 } 16524163af6aSjose borrego 16534163af6aSjose borrego ksocket_hold(ld->ld_so); 16544163af6aSjose borrego rc = smb_thread_start(&ld->ld_thread); 16554163af6aSjose borrego if (rc != 0) { 16564163af6aSjose borrego ksocket_rele(ld->ld_so); 16574163af6aSjose borrego cmn_err(CE_WARN, "port %d: listener failed to start", 16584163af6aSjose borrego ld->ld_port); 16594163af6aSjose borrego return (rc); 1660faa1795aSjb150015 } 16614163af6aSjose borrego return (0); 16624163af6aSjose borrego } 16634163af6aSjose borrego 16644163af6aSjose borrego /* 16654163af6aSjose borrego * smb_server_listener_stop 16664163af6aSjose borrego * 16674163af6aSjose borrego * Stops the listener associated with the context passed in. 16684163af6aSjose borrego */ 16694163af6aSjose borrego static void 16704163af6aSjose borrego smb_server_listener_stop(smb_listener_daemon_t *ld) 16714163af6aSjose borrego { 16724163af6aSjose borrego SMB_LISTENER_VALID(ld); 16734163af6aSjose borrego 16744163af6aSjose borrego if (ld->ld_so != NULL) { 16754163af6aSjose borrego smb_soshutdown(ld->ld_so); 16764163af6aSjose borrego smb_sodestroy(ld->ld_so); 16774163af6aSjose borrego smb_thread_stop(&ld->ld_thread); 16784163af6aSjose borrego ld->ld_so = NULL; 16794163af6aSjose borrego } 16804163af6aSjose borrego } 16814163af6aSjose borrego 16824163af6aSjose borrego /* 16834163af6aSjose borrego * smb_server_listener 16844163af6aSjose borrego * 16854163af6aSjose borrego * Entry point of the listeners. 16864163af6aSjose borrego */ 16874163af6aSjose borrego static void 16884163af6aSjose borrego smb_server_listener(smb_thread_t *thread, void *arg) 16894163af6aSjose borrego { 16904163af6aSjose borrego _NOTE(ARGUNUSED(thread)) 16914163af6aSjose borrego smb_listener_daemon_t *ld; 16924163af6aSjose borrego ksocket_t s_so; 16934163af6aSjose borrego int on; 16944163af6aSjose borrego int txbuf_size; 16954163af6aSjose borrego 16964163af6aSjose borrego ld = (smb_listener_daemon_t *)arg; 16974163af6aSjose borrego 16984163af6aSjose borrego SMB_LISTENER_VALID(ld); 1699faa1795aSjb150015 1700faa1795aSjb150015 DTRACE_PROBE1(so__wait__accept, struct sonode *, ld->ld_so); 1701faa1795aSjb150015 170241bd8510Skcrowenex for (;;) { 170341bd8510Skcrowenex int ret = ksocket_accept(ld->ld_so, NULL, NULL, &s_so, CRED()); 170441bd8510Skcrowenex 170541bd8510Skcrowenex switch (ret) { 170641bd8510Skcrowenex case 0: 170741bd8510Skcrowenex break; 170841bd8510Skcrowenex case ECONNABORTED: 170941bd8510Skcrowenex continue; 171041bd8510Skcrowenex case EINTR: 171141bd8510Skcrowenex case EBADF: /* libfakekernel */ 171241bd8510Skcrowenex goto out; 171341bd8510Skcrowenex default: 171441bd8510Skcrowenex cmn_err(CE_WARN, 171541bd8510Skcrowenex "smb_server_listener: ksocket_accept(%d)", 171641bd8510Skcrowenex ret); 171741bd8510Skcrowenex goto out; 171841bd8510Skcrowenex } 171941bd8510Skcrowenex 1720faa1795aSjb150015 DTRACE_PROBE1(so__accept, struct sonode *, s_so); 1721faa1795aSjb150015 17229fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States on = 1; 17239fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States (void) ksocket_setsockopt(s_so, IPPROTO_TCP, TCP_NODELAY, 17249fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States &on, sizeof (on), CRED()); 17259fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 17269fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States on = 1; 17279fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States (void) ksocket_setsockopt(s_so, SOL_SOCKET, SO_KEEPALIVE, 17289fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States &on, sizeof (on), CRED()); 17299fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 17309fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States txbuf_size = 128*1024; 17310f1702c5SYu Xiangning (void) ksocket_setsockopt(s_so, SOL_SOCKET, SO_SNDBUF, 17329fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States (const void *)&txbuf_size, sizeof (txbuf_size), CRED()); 17339fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 1734faa1795aSjb150015 /* 1735faa1795aSjb150015 * Create a session for this connection. 1736faa1795aSjb150015 */ 17374163af6aSjose borrego smb_server_create_session(ld, s_so); 1738faa1795aSjb150015 } 173941bd8510Skcrowenex out: 17404163af6aSjose borrego ksocket_rele(ld->ld_so); 1741faa1795aSjb150015 } 17429fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 17434163af6aSjose borrego /* 17444163af6aSjose borrego * smb_server_receiver 17454163af6aSjose borrego * 17464163af6aSjose borrego * Entry point of the receiver threads. 1747811599a4SMatt Barden * Also does cleanup when socket disconnected. 17484163af6aSjose borrego */ 17499fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States static void 17504163af6aSjose borrego smb_server_receiver(void *arg) 17519fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States { 17524163af6aSjose borrego smb_session_t *session; 1753faa1795aSjb150015 1754811599a4SMatt Barden session = (smb_session_t *)arg; 1755811599a4SMatt Barden 1756811599a4SMatt Barden /* We stay in here until socket disconnect. */ 17574163af6aSjose borrego smb_session_receiver(session); 1758811599a4SMatt Barden 1759811599a4SMatt Barden ASSERT(session->s_state == SMB_SESSION_STATE_SHUTDOWN); 1760811599a4SMatt Barden smb_server_destroy_session(session); 1761faa1795aSjb150015 } 1762faa1795aSjb150015 1763faa1795aSjb150015 /* 1764faa1795aSjb150015 * smb_server_lookup 1765faa1795aSjb150015 * 17668622ec45SGordon Ross * This function finds the server associated with the zone of the 17678622ec45SGordon Ross * caller. Note: requires a fix in the dynamic taskq code: 17688622ec45SGordon Ross * 1501 taskq_create_proc ... TQ_DYNAMIC puts tasks in p0 1769faa1795aSjb150015 */ 17704846df9bSKevin Crowe int 1771faa1795aSjb150015 smb_server_lookup(smb_server_t **psv) 1772faa1795aSjb150015 { 1773faa1795aSjb150015 zoneid_t zid; 1774faa1795aSjb150015 smb_server_t *sv; 1775faa1795aSjb150015 1776faa1795aSjb150015 zid = getzoneid(); 1777faa1795aSjb150015 1778faa1795aSjb150015 smb_llist_enter(&smb_servers, RW_READER); 1779faa1795aSjb150015 sv = smb_llist_head(&smb_servers); 1780faa1795aSjb150015 while (sv) { 17819fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States SMB_SERVER_VALID(sv); 1782faa1795aSjb150015 if (sv->sv_zid == zid) { 1783faa1795aSjb150015 mutex_enter(&sv->sv_mutex); 1784faa1795aSjb150015 if (sv->sv_state != SMB_SERVER_STATE_DELETING) { 1785faa1795aSjb150015 sv->sv_refcnt++; 1786faa1795aSjb150015 mutex_exit(&sv->sv_mutex); 1787faa1795aSjb150015 smb_llist_exit(&smb_servers); 1788faa1795aSjb150015 *psv = sv; 1789faa1795aSjb150015 return (0); 1790faa1795aSjb150015 } 1791faa1795aSjb150015 mutex_exit(&sv->sv_mutex); 1792faa1795aSjb150015 break; 1793faa1795aSjb150015 } 1794faa1795aSjb150015 sv = smb_llist_next(&smb_servers, sv); 1795faa1795aSjb150015 } 1796faa1795aSjb150015 smb_llist_exit(&smb_servers); 1797faa1795aSjb150015 return (EPERM); 1798faa1795aSjb150015 } 1799faa1795aSjb150015 1800faa1795aSjb150015 /* 1801faa1795aSjb150015 * smb_server_release 1802faa1795aSjb150015 * 1803faa1795aSjb150015 * This function decrements the reference count of the server and signals its 1804faa1795aSjb150015 * condition variable if the state of the server is SMB_SERVER_STATE_DELETING. 1805faa1795aSjb150015 */ 18064846df9bSKevin Crowe void 1807faa1795aSjb150015 smb_server_release(smb_server_t *sv) 1808faa1795aSjb150015 { 18099fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States SMB_SERVER_VALID(sv); 1810faa1795aSjb150015 1811faa1795aSjb150015 mutex_enter(&sv->sv_mutex); 1812faa1795aSjb150015 ASSERT(sv->sv_refcnt); 1813faa1795aSjb150015 sv->sv_refcnt--; 1814faa1795aSjb150015 if ((sv->sv_refcnt == 0) && (sv->sv_state == SMB_SERVER_STATE_DELETING)) 1815faa1795aSjb150015 cv_signal(&sv->sv_cv); 1816faa1795aSjb150015 mutex_exit(&sv->sv_mutex); 1817faa1795aSjb150015 } 1818faa1795aSjb150015 18191fcced4cSJordan Brown /* 18201fcced4cSJordan Brown * Enumerate the users associated with a session list. 18211fcced4cSJordan Brown */ 18221fcced4cSJordan Brown static void 1823*8d94f651SGordon Ross smb_server_enum_users(smb_server_t *sv, smb_svcenum_t *svcenum) 1824faa1795aSjb150015 { 1825*8d94f651SGordon Ross smb_llist_t *ll = &sv->sv_session_list; 18261fcced4cSJordan Brown smb_session_t *sn; 1827faa1795aSjb150015 smb_llist_t *ulist; 18281fcced4cSJordan Brown smb_user_t *user; 182929bd2886SAlan Wright int rc = 0; 1830faa1795aSjb150015 18314163af6aSjose borrego smb_llist_enter(ll, RW_READER); 18324163af6aSjose borrego sn = smb_llist_head(ll); 18331fcced4cSJordan Brown 18341fcced4cSJordan Brown while (sn != NULL) { 18354163af6aSjose borrego SMB_SESSION_VALID(sn); 1836faa1795aSjb150015 ulist = &sn->s_user_list; 1837faa1795aSjb150015 smb_llist_enter(ulist, RW_READER); 1838faa1795aSjb150015 user = smb_llist_head(ulist); 18391fcced4cSJordan Brown 18401fcced4cSJordan Brown while (user != NULL) { 18411fcced4cSJordan Brown if (smb_user_hold(user)) { 18421fcced4cSJordan Brown rc = smb_user_enum(user, svcenum); 18431fcced4cSJordan Brown smb_user_release(user); 18443b13a1efSThomas Keiser if (rc != 0) 18453b13a1efSThomas Keiser break; 1846faa1795aSjb150015 } 18471fcced4cSJordan Brown 1848faa1795aSjb150015 user = smb_llist_next(ulist, user); 1849faa1795aSjb150015 } 18501fcced4cSJordan Brown 18511fcced4cSJordan Brown smb_llist_exit(ulist); 18521fcced4cSJordan Brown 18531fcced4cSJordan Brown if (rc != 0) 18541fcced4cSJordan Brown break; 18551fcced4cSJordan Brown 18564163af6aSjose borrego sn = smb_llist_next(ll, sn); 18571fcced4cSJordan Brown } 18581fcced4cSJordan Brown 18594163af6aSjose borrego smb_llist_exit(ll); 18601fcced4cSJordan Brown } 18611fcced4cSJordan Brown 18621fcced4cSJordan Brown /* 18633b13a1efSThomas Keiser * Enumerate the trees/files associated with a session list. 18643b13a1efSThomas Keiser */ 18653b13a1efSThomas Keiser static void 1866*8d94f651SGordon Ross smb_server_enum_trees(smb_server_t *sv, smb_svcenum_t *svcenum) 18673b13a1efSThomas Keiser { 1868*8d94f651SGordon Ross smb_llist_t *ll = &sv->sv_session_list; 18693b13a1efSThomas Keiser smb_session_t *sn; 18703b13a1efSThomas Keiser smb_llist_t *tlist; 18713b13a1efSThomas Keiser smb_tree_t *tree; 18723b13a1efSThomas Keiser int rc = 0; 18733b13a1efSThomas Keiser 18743b13a1efSThomas Keiser smb_llist_enter(ll, RW_READER); 18753b13a1efSThomas Keiser sn = smb_llist_head(ll); 18763b13a1efSThomas Keiser 18773b13a1efSThomas Keiser while (sn != NULL) { 18783b13a1efSThomas Keiser SMB_SESSION_VALID(sn); 18793b13a1efSThomas Keiser tlist = &sn->s_tree_list; 18803b13a1efSThomas Keiser smb_llist_enter(tlist, RW_READER); 18813b13a1efSThomas Keiser tree = smb_llist_head(tlist); 18823b13a1efSThomas Keiser 18833b13a1efSThomas Keiser while (tree != NULL) { 18843b13a1efSThomas Keiser if (smb_tree_hold(tree)) { 18853b13a1efSThomas Keiser rc = smb_tree_enum(tree, svcenum); 18863b13a1efSThomas Keiser smb_tree_release(tree); 18873b13a1efSThomas Keiser if (rc != 0) 18883b13a1efSThomas Keiser break; 18893b13a1efSThomas Keiser } 18903b13a1efSThomas Keiser 18913b13a1efSThomas Keiser tree = smb_llist_next(tlist, tree); 18923b13a1efSThomas Keiser } 18933b13a1efSThomas Keiser 18943b13a1efSThomas Keiser smb_llist_exit(tlist); 18953b13a1efSThomas Keiser 18963b13a1efSThomas Keiser if (rc != 0) 18973b13a1efSThomas Keiser break; 18983b13a1efSThomas Keiser 18993b13a1efSThomas Keiser sn = smb_llist_next(ll, sn); 19003b13a1efSThomas Keiser } 19013b13a1efSThomas Keiser 19023b13a1efSThomas Keiser smb_llist_exit(ll); 19033b13a1efSThomas Keiser } 19043b13a1efSThomas Keiser 19053b13a1efSThomas Keiser /* 19061fcced4cSJordan Brown * Disconnect sessions associated with the specified client and username. 19071fcced4cSJordan Brown * Empty strings are treated as wildcards. 19081fcced4cSJordan Brown */ 19091fcced4cSJordan Brown static int 1910*8d94f651SGordon Ross smb_server_session_disconnect(smb_server_t *sv, 19111fcced4cSJordan Brown const char *client, const char *name) 19121fcced4cSJordan Brown { 1913*8d94f651SGordon Ross smb_llist_t *ll = &sv->sv_session_list; 19141fcced4cSJordan Brown smb_session_t *sn; 19151fcced4cSJordan Brown smb_llist_t *ulist; 19161fcced4cSJordan Brown smb_user_t *user; 19171fcced4cSJordan Brown int count = 0; 19181fcced4cSJordan Brown 19194163af6aSjose borrego smb_llist_enter(ll, RW_READER); 19201fcced4cSJordan Brown 1921811599a4SMatt Barden for (sn = smb_llist_head(ll); 1922811599a4SMatt Barden sn != NULL; 1923811599a4SMatt Barden sn = smb_llist_next(ll, sn)) { 19244163af6aSjose borrego SMB_SESSION_VALID(sn); 19251fcced4cSJordan Brown 1926811599a4SMatt Barden if (*client != '\0' && !smb_session_isclient(sn, client)) 19271fcced4cSJordan Brown continue; 19281fcced4cSJordan Brown 19291fcced4cSJordan Brown ulist = &sn->s_user_list; 19301fcced4cSJordan Brown smb_llist_enter(ulist, RW_READER); 19311fcced4cSJordan Brown 1932811599a4SMatt Barden for (user = smb_llist_head(ulist); 1933811599a4SMatt Barden user != NULL; 1934811599a4SMatt Barden user = smb_llist_next(ulist, user)) { 1935811599a4SMatt Barden SMB_USER_VALID(user); 19361fcced4cSJordan Brown 1937811599a4SMatt Barden if (*name != '\0' && !smb_user_namecmp(user, name)) 19381fcced4cSJordan Brown continue; 19391fcced4cSJordan Brown 1940811599a4SMatt Barden if (smb_user_hold(user)) { 1941811599a4SMatt Barden smb_user_logoff(user); 19421fcced4cSJordan Brown smb_user_release(user); 1943811599a4SMatt Barden count++; 19441fcced4cSJordan Brown } 19451fcced4cSJordan Brown } 19461fcced4cSJordan Brown 1947faa1795aSjb150015 smb_llist_exit(ulist); 1948faa1795aSjb150015 } 19491fcced4cSJordan Brown 19504163af6aSjose borrego smb_llist_exit(ll); 19511fcced4cSJordan Brown return (count); 19521fcced4cSJordan Brown } 19531fcced4cSJordan Brown 19541fcced4cSJordan Brown /* 19551fcced4cSJordan Brown * Close a file by its unique id. 19561fcced4cSJordan Brown */ 19571fcced4cSJordan Brown static int 1958*8d94f651SGordon Ross smb_server_fclose(smb_server_t *sv, uint32_t uniqid) 19591fcced4cSJordan Brown { 1960*8d94f651SGordon Ross smb_llist_t *ll; 19611fcced4cSJordan Brown smb_session_t *sn; 19623b13a1efSThomas Keiser smb_llist_t *tlist; 19633b13a1efSThomas Keiser smb_tree_t *tree; 19641fcced4cSJordan Brown int rc = ENOENT; 19651fcced4cSJordan Brown 1966*8d94f651SGordon Ross ll = &sv->sv_session_list; 19674163af6aSjose borrego smb_llist_enter(ll, RW_READER); 19684163af6aSjose borrego sn = smb_llist_head(ll); 19691fcced4cSJordan Brown 19701fcced4cSJordan Brown while ((sn != NULL) && (rc == ENOENT)) { 19714163af6aSjose borrego SMB_SESSION_VALID(sn); 19723b13a1efSThomas Keiser tlist = &sn->s_tree_list; 19733b13a1efSThomas Keiser smb_llist_enter(tlist, RW_READER); 19743b13a1efSThomas Keiser tree = smb_llist_head(tlist); 19751fcced4cSJordan Brown 19763b13a1efSThomas Keiser while ((tree != NULL) && (rc == ENOENT)) { 19773b13a1efSThomas Keiser if (smb_tree_hold(tree)) { 19783b13a1efSThomas Keiser rc = smb_tree_fclose(tree, uniqid); 19793b13a1efSThomas Keiser smb_tree_release(tree); 19801fcced4cSJordan Brown } 19811fcced4cSJordan Brown 19823b13a1efSThomas Keiser tree = smb_llist_next(tlist, tree); 19831fcced4cSJordan Brown } 19841fcced4cSJordan Brown 19853b13a1efSThomas Keiser smb_llist_exit(tlist); 19864163af6aSjose borrego sn = smb_llist_next(ll, sn); 19871fcced4cSJordan Brown } 19881fcced4cSJordan Brown 19894163af6aSjose borrego smb_llist_exit(ll); 19901fcced4cSJordan Brown return (rc); 1991faa1795aSjb150015 } 1992faa1795aSjb150015 1993811599a4SMatt Barden /* 1994811599a4SMatt Barden * This is used by SMB2 session setup to logoff a previous session, 1995811599a4SMatt Barden * so it can force a logoff that we haven't noticed yet. 1996811599a4SMatt Barden * This is not called frequently, so we just walk the list of 1997811599a4SMatt Barden * connections searching for the user. 1998811599a4SMatt Barden */ 1999811599a4SMatt Barden void 2000811599a4SMatt Barden smb_server_logoff_ssnid(smb_request_t *sr, uint64_t ssnid) 2001811599a4SMatt Barden { 2002811599a4SMatt Barden smb_server_t *sv = sr->sr_server; 2003811599a4SMatt Barden smb_llist_t *sess_list; 2004811599a4SMatt Barden smb_session_t *sess; 2005811599a4SMatt Barden 2006811599a4SMatt Barden if (sv->sv_state != SMB_SERVER_STATE_RUNNING) 2007811599a4SMatt Barden return; 2008811599a4SMatt Barden 2009811599a4SMatt Barden sess_list = &sv->sv_session_list; 2010811599a4SMatt Barden smb_llist_enter(sess_list, RW_READER); 2011811599a4SMatt Barden 2012811599a4SMatt Barden for (sess = smb_llist_head(sess_list); 2013811599a4SMatt Barden sess != NULL; 2014811599a4SMatt Barden sess = smb_llist_next(sess_list, sess)) { 2015811599a4SMatt Barden 2016811599a4SMatt Barden smb_user_t *user; 2017811599a4SMatt Barden 2018811599a4SMatt Barden SMB_SESSION_VALID(sess); 2019811599a4SMatt Barden 2020811599a4SMatt Barden if (sess->dialect < SMB_VERS_2_BASE) 2021811599a4SMatt Barden continue; 2022811599a4SMatt Barden 2023811599a4SMatt Barden if (sess->s_state != SMB_SESSION_STATE_NEGOTIATED) 2024811599a4SMatt Barden continue; 2025811599a4SMatt Barden 2026811599a4SMatt Barden user = smb_session_lookup_ssnid(sess, ssnid); 2027811599a4SMatt Barden if (user == NULL) 2028811599a4SMatt Barden continue; 2029811599a4SMatt Barden 2030811599a4SMatt Barden if (!smb_is_same_user(user->u_cred, sr->user_cr)) { 2031811599a4SMatt Barden smb_user_release(user); 2032811599a4SMatt Barden continue; 2033811599a4SMatt Barden } 2034811599a4SMatt Barden 2035811599a4SMatt Barden /* Treat this as if we lost the connection */ 2036811599a4SMatt Barden user->preserve_opens = SMB2_DH_PRESERVE_SOME; 2037811599a4SMatt Barden smb_user_logoff(user); 2038811599a4SMatt Barden smb_user_release(user); 2039811599a4SMatt Barden 2040811599a4SMatt Barden /* 2041811599a4SMatt Barden * The above may have left work on the delete queues 2042811599a4SMatt Barden */ 2043811599a4SMatt Barden smb_llist_flush(&sess->s_tree_list); 2044811599a4SMatt Barden smb_llist_flush(&sess->s_user_list); 2045811599a4SMatt Barden } 2046811599a4SMatt Barden 2047811599a4SMatt Barden smb_llist_exit(sess_list); 2048811599a4SMatt Barden } 2049811599a4SMatt Barden 205012b65585SGordon Ross /* See also: libsmb smb_kmod_setcfg */ 2051faa1795aSjb150015 static void 205229bd2886SAlan Wright smb_server_store_cfg(smb_server_t *sv, smb_ioc_cfg_t *ioc) 2053faa1795aSjb150015 { 205429bd2886SAlan Wright if (ioc->maxconnections == 0) 205529bd2886SAlan Wright ioc->maxconnections = 0xFFFFFFFF; 2056faa1795aSjb150015 20571160dcf7SMatt Barden if (ioc->encrypt == SMB_CONFIG_REQUIRED && 20581160dcf7SMatt Barden ioc->max_protocol < SMB_VERS_3_0) { 20591160dcf7SMatt Barden cmn_err(CE_WARN, "Server set to require encryption; " 20601160dcf7SMatt Barden "forcing max_protocol to 3.0"); 20611160dcf7SMatt Barden ioc->max_protocol = SMB_VERS_3_0; 20621160dcf7SMatt Barden } 20631160dcf7SMatt Barden 206429bd2886SAlan Wright sv->sv_cfg.skc_maxworkers = ioc->maxworkers; 206529bd2886SAlan Wright sv->sv_cfg.skc_maxconnections = ioc->maxconnections; 206629bd2886SAlan Wright sv->sv_cfg.skc_keepalive = ioc->keepalive; 206729bd2886SAlan Wright sv->sv_cfg.skc_restrict_anon = ioc->restrict_anon; 206829bd2886SAlan Wright sv->sv_cfg.skc_signing_enable = ioc->signing_enable; 206929bd2886SAlan Wright sv->sv_cfg.skc_signing_required = ioc->signing_required; 207029bd2886SAlan Wright sv->sv_cfg.skc_oplock_enable = ioc->oplock_enable; 207129bd2886SAlan Wright sv->sv_cfg.skc_sync_enable = ioc->sync_enable; 207229bd2886SAlan Wright sv->sv_cfg.skc_secmode = ioc->secmode; 207312b65585SGordon Ross sv->sv_cfg.skc_netbios_enable = ioc->netbios_enable; 207429bd2886SAlan Wright sv->sv_cfg.skc_ipv6_enable = ioc->ipv6_enable; 2075cb174861Sjoyce mcintosh sv->sv_cfg.skc_print_enable = ioc->print_enable; 20765f1ef25cSAram Hăvărneanu sv->sv_cfg.skc_traverse_mounts = ioc->traverse_mounts; 2077a90cf9f2SGordon Ross sv->sv_cfg.skc_max_protocol = ioc->max_protocol; 20783e2c0c09SMatt Barden sv->sv_cfg.skc_min_protocol = ioc->min_protocol; 20791160dcf7SMatt Barden sv->sv_cfg.skc_encrypt = ioc->encrypt; 2080148c5f43SAlan Wright sv->sv_cfg.skc_execflags = ioc->exec_flags; 208112b65585SGordon Ross sv->sv_cfg.skc_negtok_len = ioc->negtok_len; 2082148c5f43SAlan Wright sv->sv_cfg.skc_version = ioc->version; 2083a90cf9f2SGordon Ross sv->sv_cfg.skc_initial_credits = ioc->initial_credits; 2084a90cf9f2SGordon Ross sv->sv_cfg.skc_maximum_credits = ioc->maximum_credits; 2085a90cf9f2SGordon Ross 208612b65585SGordon Ross (void) memcpy(sv->sv_cfg.skc_machine_uuid, ioc->machine_uuid, 208712b65585SGordon Ross sizeof (uuid_t)); 208812b65585SGordon Ross (void) memcpy(sv->sv_cfg.skc_negtok, ioc->negtok, 208912b65585SGordon Ross sizeof (sv->sv_cfg.skc_negtok)); 209012b65585SGordon Ross (void) memcpy(sv->sv_cfg.skc_native_os, ioc->native_os, 209112b65585SGordon Ross sizeof (sv->sv_cfg.skc_native_os)); 209212b65585SGordon Ross (void) memcpy(sv->sv_cfg.skc_native_lm, ioc->native_lm, 209312b65585SGordon Ross sizeof (sv->sv_cfg.skc_native_lm)); 209412b65585SGordon Ross 209529bd2886SAlan Wright (void) strlcpy(sv->sv_cfg.skc_nbdomain, ioc->nbdomain, 209629bd2886SAlan Wright sizeof (sv->sv_cfg.skc_nbdomain)); 209729bd2886SAlan Wright (void) strlcpy(sv->sv_cfg.skc_fqdn, ioc->fqdn, 209829bd2886SAlan Wright sizeof (sv->sv_cfg.skc_fqdn)); 209929bd2886SAlan Wright (void) strlcpy(sv->sv_cfg.skc_hostname, ioc->hostname, 210029bd2886SAlan Wright sizeof (sv->sv_cfg.skc_hostname)); 210129bd2886SAlan Wright (void) strlcpy(sv->sv_cfg.skc_system_comment, ioc->system_comment, 210229bd2886SAlan Wright sizeof (sv->sv_cfg.skc_system_comment)); 2103faa1795aSjb150015 } 2104faa1795aSjb150015 2105faa1795aSjb150015 static int 2106faa1795aSjb150015 smb_server_fsop_start(smb_server_t *sv) 2107faa1795aSjb150015 { 2108faa1795aSjb150015 int error; 2109faa1795aSjb150015 21108622ec45SGordon Ross error = smb_node_root_init(sv, &sv->si_root_smb_node); 2111faa1795aSjb150015 if (error != 0) 2112faa1795aSjb150015 sv->si_root_smb_node = NULL; 2113faa1795aSjb150015 2114faa1795aSjb150015 return (error); 2115faa1795aSjb150015 } 2116faa1795aSjb150015 2117faa1795aSjb150015 static void 2118faa1795aSjb150015 smb_server_fsop_stop(smb_server_t *sv) 2119faa1795aSjb150015 { 2120faa1795aSjb150015 if (sv->si_root_smb_node != NULL) { 2121faa1795aSjb150015 smb_node_release(sv->si_root_smb_node); 2122faa1795aSjb150015 sv->si_root_smb_node = NULL; 2123faa1795aSjb150015 } 2124faa1795aSjb150015 } 21259fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 21269fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States smb_event_t * 21278622ec45SGordon Ross smb_event_create(smb_server_t *sv, int timeout) 21289fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States { 21299fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States smb_event_t *event; 21309fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 21318622ec45SGordon Ross if (smb_server_is_stopping(sv)) 21329fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States return (NULL); 21339fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 21348622ec45SGordon Ross event = kmem_cache_alloc(smb_cache_event, KM_SLEEP); 21359fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 21369fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States bzero(event, sizeof (smb_event_t)); 21379fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States mutex_init(&event->se_mutex, NULL, MUTEX_DEFAULT, NULL); 21389fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States cv_init(&event->se_cv, NULL, CV_DEFAULT, NULL); 21399fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States event->se_magic = SMB_EVENT_MAGIC; 21409fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States event->se_txid = smb_event_alloc_txid(); 21419fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States event->se_server = sv; 2142cb174861Sjoyce mcintosh event->se_timeout = timeout; 21439fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 21449fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States smb_llist_enter(&sv->sv_event_list, RW_WRITER); 21459fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States smb_llist_insert_tail(&sv->sv_event_list, event); 21469fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States smb_llist_exit(&sv->sv_event_list); 21479fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 21489fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States return (event); 21499fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States } 21509fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 21519fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States void 21529fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States smb_event_destroy(smb_event_t *event) 21539fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States { 21549fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States smb_server_t *sv; 21559fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 21569fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States if (event == NULL) 21579fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States return; 21589fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 21599fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States SMB_EVENT_VALID(event); 21609fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States ASSERT(event->se_waittime == 0); 21618622ec45SGordon Ross sv = event->se_server; 21628622ec45SGordon Ross SMB_SERVER_VALID(sv); 21639fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 21649fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States smb_llist_enter(&sv->sv_event_list, RW_WRITER); 21659fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States smb_llist_remove(&sv->sv_event_list, event); 21669fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States smb_llist_exit(&sv->sv_event_list); 21679fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 21689fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States event->se_magic = (uint32_t)~SMB_EVENT_MAGIC; 21699fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States cv_destroy(&event->se_cv); 21709fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States mutex_destroy(&event->se_mutex); 21719fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 21728622ec45SGordon Ross kmem_cache_free(smb_cache_event, event); 21739fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States } 21749fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 21759fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States /* 21769fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States * Get the txid for the specified event. 21779fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States */ 21789fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States uint32_t 21799fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States smb_event_txid(smb_event_t *event) 21809fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States { 21819fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States if (event != NULL) { 21829fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States SMB_EVENT_VALID(event); 21839fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States return (event->se_txid); 21849fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States } 21859fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 21869fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States cmn_err(CE_NOTE, "smb_event_txid failed"); 21879fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States return ((uint32_t)-1); 21889fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States } 21899fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 21909fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States /* 21919fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States * Wait for event notification. 21929fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States */ 21939fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States int 21949fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States smb_event_wait(smb_event_t *event) 21959fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States { 21969fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States int seconds = 1; 21979fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States int ticks; 2198856399cfSGordon Ross int err; 21999fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 22009fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States if (event == NULL) 22019fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States return (EINVAL); 22029fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 22039fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States SMB_EVENT_VALID(event); 22049fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 22059fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States mutex_enter(&event->se_mutex); 22069fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States event->se_waittime = 1; 22079fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States event->se_errno = 0; 22089fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 22099fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States while (!(event->se_notified)) { 2210c5866007SKeyur Desai if (smb_event_debug && ((event->se_waittime % 30) == 0)) 22119fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States cmn_err(CE_NOTE, "smb_event_wait[%d] (%d sec)", 22129fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States event->se_txid, event->se_waittime); 22139fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 22149fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States if (event->se_errno != 0) 22159fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States break; 22169fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 2217cb174861Sjoyce mcintosh if (event->se_waittime > event->se_timeout) { 22189fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States event->se_errno = ETIME; 22199fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States break; 22209fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States } 22219fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 22229fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States ticks = SEC_TO_TICK(seconds); 22239fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States (void) cv_reltimedwait(&event->se_cv, 22249fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States &event->se_mutex, (clock_t)ticks, TR_CLOCK_TICK); 22259fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States ++event->se_waittime; 22269fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States } 22279fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 2228856399cfSGordon Ross err = event->se_errno; 22299fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States event->se_waittime = 0; 22309fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States event->se_notified = B_FALSE; 22319fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States cv_signal(&event->se_cv); 22329fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States mutex_exit(&event->se_mutex); 2233856399cfSGordon Ross return (err); 22349fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States } 22359fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 22369fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States /* 22379fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States * If txid is non-zero, cancel the specified event. 22389fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States * Otherwise, cancel all events. 22399fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States */ 22409fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States static void 22419fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States smb_event_cancel(smb_server_t *sv, uint32_t txid) 22429fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States { 22439fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States smb_event_t *event; 22449fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States smb_llist_t *event_list; 22459fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 22469fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States SMB_SERVER_VALID(sv); 22479fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 22489fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States event_list = &sv->sv_event_list; 22499fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States smb_llist_enter(event_list, RW_WRITER); 22509fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 22519fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States event = smb_llist_head(event_list); 22529fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States while (event) { 22539fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States SMB_EVENT_VALID(event); 22549fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 22559fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States if (txid == 0 || event->se_txid == txid) { 22569fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States mutex_enter(&event->se_mutex); 22579fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States event->se_errno = ECANCELED; 22589fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States event->se_notified = B_TRUE; 22599fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States cv_signal(&event->se_cv); 22609fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States mutex_exit(&event->se_mutex); 22619fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 22629fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States if (txid != 0) 22639fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States break; 22649fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States } 22659fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 22669fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States event = smb_llist_next(event_list, event); 22679fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States } 22689fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 22699fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States smb_llist_exit(event_list); 22709fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States } 22719fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 22729fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States /* 22739fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States * If txid is non-zero, notify the specified event. 22749fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States * Otherwise, notify all events. 22759fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States */ 2276cb174861Sjoyce mcintosh void 22779fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States smb_event_notify(smb_server_t *sv, uint32_t txid) 22789fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States { 22799fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States smb_event_t *event; 22809fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States smb_llist_t *event_list; 22819fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 22829fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States SMB_SERVER_VALID(sv); 22839fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 22849fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States event_list = &sv->sv_event_list; 22859fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States smb_llist_enter(event_list, RW_READER); 22869fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 22879fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States event = smb_llist_head(event_list); 22889fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States while (event) { 22899fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States SMB_EVENT_VALID(event); 22909fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 22919fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States if (txid == 0 || event->se_txid == txid) { 22929fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States mutex_enter(&event->se_mutex); 22939fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States event->se_notified = B_TRUE; 22949fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States cv_signal(&event->se_cv); 22959fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States mutex_exit(&event->se_mutex); 22969fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 22979fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States if (txid != 0) 22989fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States break; 22999fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States } 23009fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 23019fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States event = smb_llist_next(event_list, event); 23029fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States } 23039fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 23049fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States smb_llist_exit(event_list); 23059fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States } 23069fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 23079fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States /* 23089fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States * Allocate a new transaction id (txid). 23099fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States * 23109fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States * 0 or -1 are not assigned because they are used to detect invalid 23119fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States * conditions or to indicate all open id's. 23129fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States */ 23139fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States static uint32_t 23149fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States smb_event_alloc_txid(void) 23159fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States { 23169fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States static kmutex_t txmutex; 23179fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States static uint32_t txid; 23189fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States uint32_t txid_ret; 23199fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 23209fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States mutex_enter(&txmutex); 23219fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 23229fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States if (txid == 0) 23239fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States txid = ddi_get_lbolt() << 11; 23249fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 23259fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States do { 23269fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States ++txid; 23279fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States } while (txid == 0 || txid == (uint32_t)-1); 23289fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 23299fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States txid_ret = txid; 23309fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States mutex_exit(&txmutex); 23319fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 23329fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States return (txid_ret); 23339fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States } 2334cb174861Sjoyce mcintosh 2335cb174861Sjoyce mcintosh /* 2336cb174861Sjoyce mcintosh * Called by the ioctl to find the corresponding 2337cb174861Sjoyce mcintosh * spooldoc node. removes node on success 2338cb174861Sjoyce mcintosh * 2339cb174861Sjoyce mcintosh * Return values 2340cb174861Sjoyce mcintosh * rc 2341cb174861Sjoyce mcintosh * B_FALSE - not found 2342cb174861Sjoyce mcintosh * B_TRUE - found 2343cb174861Sjoyce mcintosh * 2344cb174861Sjoyce mcintosh */ 2345cb174861Sjoyce mcintosh 234623a9c295SGordon Ross static boolean_t 234723a9c295SGordon Ross smb_spool_lookup_doc_byfid(smb_server_t *sv, uint16_t fid, 234823a9c295SGordon Ross smb_kspooldoc_t *spdoc) 2349cb174861Sjoyce mcintosh { 2350cb174861Sjoyce mcintosh smb_kspooldoc_t *sp; 2351cb174861Sjoyce mcintosh smb_llist_t *splist; 2352cb174861Sjoyce mcintosh 2353cb174861Sjoyce mcintosh splist = &sv->sp_info.sp_list; 2354cb174861Sjoyce mcintosh smb_llist_enter(splist, RW_WRITER); 2355cb174861Sjoyce mcintosh sp = smb_llist_head(splist); 2356cb174861Sjoyce mcintosh while (sp != NULL) { 2357cb174861Sjoyce mcintosh /* 2358cb174861Sjoyce mcintosh * check for a matching fid 2359cb174861Sjoyce mcintosh */ 2360cb174861Sjoyce mcintosh if (sp->sd_fid == fid) { 2361cb174861Sjoyce mcintosh *spdoc = *sp; 2362cb174861Sjoyce mcintosh smb_llist_remove(splist, sp); 2363cb174861Sjoyce mcintosh smb_llist_exit(splist); 2364cb174861Sjoyce mcintosh kmem_free(sp, sizeof (smb_kspooldoc_t)); 2365cb174861Sjoyce mcintosh return (B_TRUE); 2366cb174861Sjoyce mcintosh } 2367cb174861Sjoyce mcintosh sp = smb_llist_next(splist, sp); 2368cb174861Sjoyce mcintosh } 2369cb174861Sjoyce mcintosh cmn_err(CE_WARN, "smb_spool_lookup_user_byfid: no fid:%d", fid); 2370cb174861Sjoyce mcintosh smb_llist_exit(splist); 2371cb174861Sjoyce mcintosh return (B_FALSE); 2372cb174861Sjoyce mcintosh } 2373cb174861Sjoyce mcintosh 2374cb174861Sjoyce mcintosh /* 2375cb174861Sjoyce mcintosh * Adds the spool fid to a linked list to be used 2376cb174861Sjoyce mcintosh * as a search key in the spooldoc queue 2377cb174861Sjoyce mcintosh * 2378cb174861Sjoyce mcintosh * Return values 2379cb174861Sjoyce mcintosh * rc non-zero error 2380cb174861Sjoyce mcintosh * rc zero success 2381cb174861Sjoyce mcintosh * 2382cb174861Sjoyce mcintosh */ 2383cb174861Sjoyce mcintosh 238486d7016bSGordon Ross void 238586d7016bSGordon Ross smb_spool_add_fid(smb_server_t *sv, uint16_t fid) 2386cb174861Sjoyce mcintosh { 2387cb174861Sjoyce mcintosh smb_llist_t *fidlist; 2388cb174861Sjoyce mcintosh smb_spoolfid_t *sf; 2389cb174861Sjoyce mcintosh 239086d7016bSGordon Ross if (sv->sv_cfg.skc_print_enable == 0) 239186d7016bSGordon Ross return; 2392cb174861Sjoyce mcintosh 2393cb174861Sjoyce mcintosh sf = kmem_zalloc(sizeof (smb_spoolfid_t), KM_SLEEP); 2394cb174861Sjoyce mcintosh fidlist = &sv->sp_info.sp_fidlist; 2395cb174861Sjoyce mcintosh smb_llist_enter(fidlist, RW_WRITER); 2396cb174861Sjoyce mcintosh sf->sf_fid = fid; 2397cb174861Sjoyce mcintosh smb_llist_insert_tail(fidlist, sf); 2398cb174861Sjoyce mcintosh smb_llist_exit(fidlist); 239986d7016bSGordon Ross cv_broadcast(&sv->sp_info.sp_cv); 2400cb174861Sjoyce mcintosh } 2401cb174861Sjoyce mcintosh 2402cb174861Sjoyce mcintosh /* 2403cb174861Sjoyce mcintosh * Called by the ioctl to get and remove the head of the fid list 2404cb174861Sjoyce mcintosh * 2405cb174861Sjoyce mcintosh * Return values 2406cb174861Sjoyce mcintosh * int fd 2407cb174861Sjoyce mcintosh * greater than 0 success 2408cb174861Sjoyce mcintosh * 0 - error 2409cb174861Sjoyce mcintosh * 2410cb174861Sjoyce mcintosh */ 2411cb174861Sjoyce mcintosh 241223a9c295SGordon Ross static uint16_t 241323a9c295SGordon Ross smb_spool_get_fid(smb_server_t *sv) 2414cb174861Sjoyce mcintosh { 2415cb174861Sjoyce mcintosh smb_spoolfid_t *spfid; 2416cb174861Sjoyce mcintosh smb_llist_t *splist; 2417cb174861Sjoyce mcintosh uint16_t fid; 2418cb174861Sjoyce mcintosh 2419cb174861Sjoyce mcintosh splist = &sv->sp_info.sp_fidlist; 2420cb174861Sjoyce mcintosh smb_llist_enter(splist, RW_WRITER); 2421cb174861Sjoyce mcintosh spfid = smb_llist_head(splist); 2422cb174861Sjoyce mcintosh if (spfid != NULL) { 2423cb174861Sjoyce mcintosh fid = spfid->sf_fid; 2424cb174861Sjoyce mcintosh smb_llist_remove(&sv->sp_info.sp_fidlist, spfid); 2425cb174861Sjoyce mcintosh kmem_free(spfid, sizeof (smb_spoolfid_t)); 2426cb174861Sjoyce mcintosh } else { 2427cb174861Sjoyce mcintosh fid = 0; 2428cb174861Sjoyce mcintosh } 2429cb174861Sjoyce mcintosh smb_llist_exit(splist); 2430cb174861Sjoyce mcintosh return (fid); 2431cb174861Sjoyce mcintosh } 2432cb174861Sjoyce mcintosh 2433cb174861Sjoyce mcintosh /* 2434cb174861Sjoyce mcintosh * Adds the spooldoc to the tail of the spooldoc list 2435cb174861Sjoyce mcintosh * 2436cb174861Sjoyce mcintosh * Return values 2437cb174861Sjoyce mcintosh * rc non-zero error 2438cb174861Sjoyce mcintosh * rc zero success 2439cb174861Sjoyce mcintosh */ 2440cb174861Sjoyce mcintosh int 24418622ec45SGordon Ross smb_spool_add_doc(smb_tree_t *tree, smb_kspooldoc_t *sp) 2442cb174861Sjoyce mcintosh { 2443cb174861Sjoyce mcintosh smb_llist_t *splist; 24448622ec45SGordon Ross smb_server_t *sv = tree->t_server; 2445cb174861Sjoyce mcintosh int rc = 0; 2446cb174861Sjoyce mcintosh 2447cb174861Sjoyce mcintosh splist = &sv->sp_info.sp_list; 2448cb174861Sjoyce mcintosh smb_llist_enter(splist, RW_WRITER); 244923a9c295SGordon Ross sp->sd_spool_num = atomic_inc_32_nv(&sv->sp_info.sp_cnt); 2450cb174861Sjoyce mcintosh smb_llist_insert_tail(splist, sp); 2451cb174861Sjoyce mcintosh smb_llist_exit(splist); 24528622ec45SGordon Ross 2453cb174861Sjoyce mcintosh return (rc); 2454cb174861Sjoyce mcintosh } 24554163af6aSjose borrego 24564163af6aSjose borrego /* 24574163af6aSjose borrego * smb_server_create_session 24584163af6aSjose borrego */ 24594163af6aSjose borrego static void 24604163af6aSjose borrego smb_server_create_session(smb_listener_daemon_t *ld, ksocket_t s_so) 24614163af6aSjose borrego { 24624163af6aSjose borrego smb_session_t *session; 24638622ec45SGordon Ross taskqid_t tqid; 2464811599a4SMatt Barden smb_llist_t *sl; 2465811599a4SMatt Barden smb_server_t *sv = ld->ld_sv; 24664163af6aSjose borrego 2467811599a4SMatt Barden session = smb_session_create(s_so, ld->ld_port, sv, 24684163af6aSjose borrego ld->ld_family); 24694163af6aSjose borrego 24708622ec45SGordon Ross if (session == NULL) { 24718622ec45SGordon Ross smb_soshutdown(s_so); 24728622ec45SGordon Ross smb_sodestroy(s_so); 24738622ec45SGordon Ross cmn_err(CE_WARN, "SMB Session: alloc failed"); 24748622ec45SGordon Ross return; 24758622ec45SGordon Ross } 24768622ec45SGordon Ross 2477811599a4SMatt Barden sl = &sv->sv_session_list; 2478811599a4SMatt Barden smb_llist_enter(sl, RW_WRITER); 2479811599a4SMatt Barden smb_llist_insert_tail(sl, session); 2480811599a4SMatt Barden smb_llist_exit(sl); 24814163af6aSjose borrego 24828622ec45SGordon Ross /* 24838622ec45SGordon Ross * These taskq entries must run independently of one another, 24848622ec45SGordon Ross * so TQ_NOQUEUE. TQ_SLEEP (==0) just for clarity. 24858622ec45SGordon Ross */ 2486811599a4SMatt Barden tqid = taskq_dispatch(sv->sv_receiver_pool, 2487811599a4SMatt Barden smb_server_receiver, session, TQ_NOQUEUE | TQ_SLEEP); 2488fc8ae2ecSToomas Soome if (tqid == TASKQID_INVALID) { 24894163af6aSjose borrego smb_session_disconnect(session); 2490811599a4SMatt Barden smb_server_destroy_session(session); 24918622ec45SGordon Ross cmn_err(CE_WARN, "SMB Session: taskq_dispatch failed"); 24928622ec45SGordon Ross return; 24934163af6aSjose borrego } 24948622ec45SGordon Ross /* handy for debugging */ 24958622ec45SGordon Ross session->s_receiver_tqid = tqid; 24964163af6aSjose borrego } 24974163af6aSjose borrego 24984163af6aSjose borrego static void 2499811599a4SMatt Barden smb_server_destroy_session(smb_session_t *session) 25004163af6aSjose borrego { 2501811599a4SMatt Barden smb_server_t *sv; 2502811599a4SMatt Barden smb_llist_t *ll; 2503811599a4SMatt Barden uint32_t count; 2504811599a4SMatt Barden 2505811599a4SMatt Barden ASSERT(session->s_server != NULL); 2506811599a4SMatt Barden sv = session->s_server; 2507811599a4SMatt Barden ll = &sv->sv_session_list; 2508811599a4SMatt Barden 2509811599a4SMatt Barden smb_llist_flush(&session->s_tree_list); 2510811599a4SMatt Barden smb_llist_flush(&session->s_user_list); 2511811599a4SMatt Barden 2512811599a4SMatt Barden /* 2513811599a4SMatt Barden * The user and tree lists should be empty now. 2514811599a4SMatt Barden */ 2515811599a4SMatt Barden #ifdef DEBUG 2516811599a4SMatt Barden if (session->s_user_list.ll_count != 0) { 2517811599a4SMatt Barden cmn_err(CE_WARN, "user list not empty?"); 2518811599a4SMatt Barden debug_enter("s_user_list"); 2519811599a4SMatt Barden } 2520811599a4SMatt Barden if (session->s_tree_list.ll_count != 0) { 2521811599a4SMatt Barden cmn_err(CE_WARN, "tree list not empty?"); 2522811599a4SMatt Barden debug_enter("s_tree_list"); 2523811599a4SMatt Barden } 2524811599a4SMatt Barden #endif 2525811599a4SMatt Barden 2526811599a4SMatt Barden smb_llist_enter(ll, RW_WRITER); 2527811599a4SMatt Barden smb_llist_remove(ll, session); 2528811599a4SMatt Barden count = ll->ll_count; 2529811599a4SMatt Barden smb_llist_exit(ll); 2530811599a4SMatt Barden 25314163af6aSjose borrego smb_session_delete(session); 2532811599a4SMatt Barden if (count == 0) { 2533811599a4SMatt Barden /* See smb_server_shutdown */ 2534811599a4SMatt Barden cv_signal(&sv->sv_cv); 2535811599a4SMatt Barden } 25364163af6aSjose borrego } 2537