1faa1795aSjb150015 /* 2faa1795aSjb150015 * CDDL HEADER START 3faa1795aSjb150015 * 4faa1795aSjb150015 * The contents of this file are subject to the terms of the 5faa1795aSjb150015 * Common Development and Distribution License (the "License"). 6faa1795aSjb150015 * You may not use this file except in compliance with the License. 7faa1795aSjb150015 * 8faa1795aSjb150015 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9faa1795aSjb150015 * or http://www.opensolaris.org/os/licensing. 10faa1795aSjb150015 * See the License for the specific language governing permissions 11faa1795aSjb150015 * and limitations under the License. 12faa1795aSjb150015 * 13faa1795aSjb150015 * When distributing Covered Code, include this CDDL HEADER in each 14faa1795aSjb150015 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15faa1795aSjb150015 * If applicable, add the following below this CDDL HEADER, with the 16faa1795aSjb150015 * fields enclosed by brackets "[]" replaced with your own identifying 17faa1795aSjb150015 * information: Portions Copyright [yyyy] [name of copyright owner] 18faa1795aSjb150015 * 19faa1795aSjb150015 * CDDL HEADER END 20faa1795aSjb150015 */ 21faa1795aSjb150015 /* 22c5866007SKeyur Desai * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved. 23adc68ba9SPavel Zakharov * Copyright (c) 2017 by Delphix. All rights reserved. 24896d9552SGordon Ross * Copyright 2019 Nexenta by DDN, Inc. All rights reserved. 2561b20185SGordon Ross * Copyright 2022 RackTop Systems, Inc. 26faa1795aSjb150015 */ 27faa1795aSjb150015 28faa1795aSjb150015 /* 29faa1795aSjb150015 * General Structures Layout 30faa1795aSjb150015 * ------------------------- 31faa1795aSjb150015 * 32faa1795aSjb150015 * This is a simplified diagram showing the relationship between most of the 33faa1795aSjb150015 * main structures. 34faa1795aSjb150015 * 35faa1795aSjb150015 * +-------------------+ 36faa1795aSjb150015 * | SMB_SERVER | 37faa1795aSjb150015 * +-------------------+ 38faa1795aSjb150015 * | 39faa1795aSjb150015 * | 40faa1795aSjb150015 * v 41faa1795aSjb150015 * +-------------------+ +-------------------+ +-------------------+ 42faa1795aSjb150015 * | SESSION |<----->| SESSION |......| SESSION | 43faa1795aSjb150015 * +-------------------+ +-------------------+ +-------------------+ 44faa1795aSjb150015 * | 45faa1795aSjb150015 * | 46faa1795aSjb150015 * v 47faa1795aSjb150015 * +-------------------+ +-------------------+ +-------------------+ 48faa1795aSjb150015 * | USER |<----->| USER |......| USER | 49faa1795aSjb150015 * +-------------------+ +-------------------+ +-------------------+ 50faa1795aSjb150015 * | 51faa1795aSjb150015 * | 52faa1795aSjb150015 * v 53faa1795aSjb150015 * +-------------------+ +-------------------+ +-------------------+ 54faa1795aSjb150015 * | TREE |<----->| TREE |......| TREE | 55faa1795aSjb150015 * +-------------------+ +-------------------+ +-------------------+ 56faa1795aSjb150015 * | | 57faa1795aSjb150015 * | | 58faa1795aSjb150015 * | v 59faa1795aSjb150015 * | +-------+ +-------+ +-------+ 60faa1795aSjb150015 * | | OFILE |<----->| OFILE |......| OFILE | 61faa1795aSjb150015 * | +-------+ +-------+ +-------+ 62faa1795aSjb150015 * | 63faa1795aSjb150015 * | 64faa1795aSjb150015 * v 65faa1795aSjb150015 * +-------+ +------+ +------+ 66faa1795aSjb150015 * | ODIR |<----->| ODIR |......| ODIR | 67faa1795aSjb150015 * +-------+ +------+ +------+ 68faa1795aSjb150015 * 69faa1795aSjb150015 * 70faa1795aSjb150015 * Module Interface Overview 71faa1795aSjb150015 * ------------------------- 72faa1795aSjb150015 * 73faa1795aSjb150015 * 74faa1795aSjb150015 * +===================================+ 75faa1795aSjb150015 * | smbd daemon | 76faa1795aSjb150015 * +===================================+ 77faa1795aSjb150015 * | | ^ 78faa1795aSjb150015 * | | | 79faa1795aSjb150015 * User | | | 80faa1795aSjb150015 * -----------|--------------|----------------|-------------------------------- 81faa1795aSjb150015 * Kernel | | | 82faa1795aSjb150015 * | | | 83faa1795aSjb150015 * | | | 84faa1795aSjb150015 * +=========|==============|================|=================+ 85faa1795aSjb150015 * | v v | | 86faa1795aSjb150015 * | +-----------+ +--------------------+ +------------------+ | 87faa1795aSjb150015 * | | IO | | Kernel Door Server | | User Door Servers| | 88faa1795aSjb150015 * | | Interface | | Interface | | Interface | | 89faa1795aSjb150015 * | +-----------+ +--------------------+ +------------------+ | 90faa1795aSjb150015 * | | | ^ ^ | 91faa1795aSjb150015 * | v v | | | +=========+ 92faa1795aSjb150015 * | +-----------------------------------+ | | | | 93faa1795aSjb150015 * | + SMB Server Management (this file) |<------------------| ZFS | 94faa1795aSjb150015 * | +-----------------------------------+ | | | | 95faa1795aSjb150015 * | | | | Module | 96faa1795aSjb150015 * | +-----------------------------------+ | | | | 97faa1795aSjb150015 * | + SMB Server Internal Layers |------+ | +=========+ 98faa1795aSjb150015 * | +-----------------------------------+ | 99faa1795aSjb150015 * | | 100faa1795aSjb150015 * | | 101faa1795aSjb150015 * +===========================================================+ 102faa1795aSjb150015 * 103faa1795aSjb150015 * 104faa1795aSjb150015 * Server State Machine 105faa1795aSjb150015 * -------------------- 106faa1795aSjb150015 * | 107faa1795aSjb150015 * | T0 108faa1795aSjb150015 * | 109faa1795aSjb150015 * v 110faa1795aSjb150015 * +-----------------------------+ 111faa1795aSjb150015 * | SMB_SERVER_STATE_CREATED | 112faa1795aSjb150015 * +-----------------------------+ 113faa1795aSjb150015 * | 114faa1795aSjb150015 * | T1 115faa1795aSjb150015 * | 116faa1795aSjb150015 * v 117faa1795aSjb150015 * +-----------------------------+ 118faa1795aSjb150015 * | SMB_SERVER_STATE_CONFIGURED | 119faa1795aSjb150015 * +-----------------------------+ 120faa1795aSjb150015 * | 121faa1795aSjb150015 * | T2 122faa1795aSjb150015 * | 123faa1795aSjb150015 * v 124faa1795aSjb150015 * +-----------------------------+ 1259fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States * | SMB_SERVER_STATE_RUNNING / | 1269fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States * | SMB_SERVER_STATE_STOPPING | 127faa1795aSjb150015 * +-----------------------------+ 128faa1795aSjb150015 * | 129faa1795aSjb150015 * | T3 130faa1795aSjb150015 * | 131faa1795aSjb150015 * v 132faa1795aSjb150015 * +-----------------------------+ 133faa1795aSjb150015 * | SMB_SERVER_STATE_DELETING | 134faa1795aSjb150015 * +-----------------------------+ 135faa1795aSjb150015 * | 136faa1795aSjb150015 * | 137faa1795aSjb150015 * | 138faa1795aSjb150015 * v 139faa1795aSjb150015 * 140faa1795aSjb150015 * States 141faa1795aSjb150015 * ------ 142faa1795aSjb150015 * 143faa1795aSjb150015 * SMB_SERVER_STATE_CREATED 144faa1795aSjb150015 * 145faa1795aSjb150015 * This is the state of the server just after creation. 146faa1795aSjb150015 * 147faa1795aSjb150015 * SMB_SERVER_STATE_CONFIGURED 148faa1795aSjb150015 * 149faa1795aSjb150015 * The server has been configured. 150faa1795aSjb150015 * 151faa1795aSjb150015 * SMB_SERVER_STATE_RUNNING 152faa1795aSjb150015 * 153faa1795aSjb150015 * The server has been started. While in this state the threads listening on 1544163af6aSjose borrego * the sockets are started. 155faa1795aSjb150015 * 1564163af6aSjose borrego * When a client establishes a connection the thread listening dispatches 1574163af6aSjose borrego * a task with the new session as an argument. If the dispatch fails the new 1584163af6aSjose borrego * session context is destroyed. 159faa1795aSjb150015 * 160faa1795aSjb150015 * SMB_SERVER_STATE_STOPPING 161faa1795aSjb150015 * 162faa1795aSjb150015 * The threads listening on the NBT and TCP sockets are being terminated. 163faa1795aSjb150015 * 164faa1795aSjb150015 * 165faa1795aSjb150015 * Transitions 166faa1795aSjb150015 * ----------- 167faa1795aSjb150015 * 168faa1795aSjb150015 * Transition T0 169faa1795aSjb150015 * 170faa1795aSjb150015 * The daemon smbd triggers its creation by opening the smbsrv device. If 171faa1795aSjb150015 * the zone where the daemon lives doesn't have an smb server yet it is 172faa1795aSjb150015 * created. 173faa1795aSjb150015 * 174faa1795aSjb150015 * smb_drv_open() --> smb_server_create() 175faa1795aSjb150015 * 176faa1795aSjb150015 * Transition T1 177faa1795aSjb150015 * 178faa1795aSjb150015 * This transition occurs in smb_server_configure(). It is triggered by the 179faa1795aSjb150015 * daemon through an Ioctl. 180faa1795aSjb150015 * 181faa1795aSjb150015 * smb_drv_ioctl(SMB_IOC_CONFIG) --> smb_server_configure() 182faa1795aSjb150015 * 183faa1795aSjb150015 * Transition T2 184faa1795aSjb150015 * 185faa1795aSjb150015 * This transition occurs in smb_server_start(). It is triggered by the 186faa1795aSjb150015 * daemon through an Ioctl. 187faa1795aSjb150015 * 188faa1795aSjb150015 * smb_drv_ioctl(SMB_IOC_START) --> smb_server_start() 189faa1795aSjb150015 * 190faa1795aSjb150015 * Transition T3 191faa1795aSjb150015 * 192faa1795aSjb150015 * This transition occurs in smb_server_delete(). It is triggered by the 193faa1795aSjb150015 * daemon when closing the smbsrv device 194faa1795aSjb150015 * 195faa1795aSjb150015 * smb_drv_close() --> smb_server_delete() 196faa1795aSjb150015 * 197faa1795aSjb150015 * Comments 198faa1795aSjb150015 * -------- 199faa1795aSjb150015 * 200faa1795aSjb150015 * This files assumes that there will one SMB server per zone. For now the 201faa1795aSjb150015 * smb server works only in global zone. There's nothing in this file preventing 202faa1795aSjb150015 * an smb server from being created in a non global zone. That limitation is 203faa1795aSjb150015 * enforced in user space. 204faa1795aSjb150015 */ 205faa1795aSjb150015 206faa1795aSjb150015 #include <sys/cmn_err.h> 207faa1795aSjb150015 #include <sys/priv.h> 208faa1795aSjb150015 #include <sys/zone.h> 209bbf6f00cSJordan Brown #include <netinet/in.h> 210bbf6f00cSJordan Brown #include <netinet/in_systm.h> 211bbf6f00cSJordan Brown #include <netinet/ip.h> 212bbf6f00cSJordan Brown #include <netinet/ip_icmp.h> 213bbf6f00cSJordan Brown #include <netinet/ip_var.h> 214bbf6f00cSJordan Brown #include <netinet/tcp.h> 215a90cf9f2SGordon Ross #include <smbsrv/smb2_kproto.h> 216bbf6f00cSJordan Brown #include <smbsrv/string.h> 217faa1795aSjb150015 #include <smbsrv/netbios.h> 218faa1795aSjb150015 #include <smbsrv/smb_fsops.h> 2193db3f65cSamw #include <smbsrv/smb_share.h> 2209fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States #include <smbsrv/smb_door.h> 2216537f381Sas200622 #include <smbsrv/smb_kstat.h> 222faa1795aSjb150015 223148c5f43SAlan Wright static void smb_server_kstat_init(smb_server_t *); 224faa1795aSjb150015 static void smb_server_kstat_fini(smb_server_t *); 225faa1795aSjb150015 static void smb_server_timers(smb_thread_t *, void *); 22629bd2886SAlan Wright static void smb_server_store_cfg(smb_server_t *, smb_ioc_cfg_t *); 2279fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States static void smb_server_shutdown(smb_server_t *); 228faa1795aSjb150015 static int smb_server_fsop_start(smb_server_t *); 229faa1795aSjb150015 static void smb_server_fsop_stop(smb_server_t *); 2309fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States static void smb_event_cancel(smb_server_t *, uint32_t); 2319fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States static uint32_t smb_event_alloc_txid(void); 232faa1795aSjb150015 2338d94f651SGordon Ross static void smb_server_disconnect_share(smb_server_t *, const char *); 2348d94f651SGordon Ross static void smb_server_enum_users(smb_server_t *, smb_svcenum_t *); 2358d94f651SGordon Ross static void smb_server_enum_trees(smb_server_t *, smb_svcenum_t *); 2368d94f651SGordon Ross static int smb_server_session_disconnect(smb_server_t *, const char *, 2371fcced4cSJordan Brown const char *); 2388d94f651SGordon Ross static int smb_server_fclose(smb_server_t *, uint32_t); 239148c5f43SAlan Wright static int smb_server_kstat_update(kstat_t *, int); 240cb174861Sjoyce mcintosh static int smb_server_legacy_kstat_update(kstat_t *, int); 2414163af6aSjose borrego static void smb_server_listener_init(smb_server_t *, smb_listener_daemon_t *, 2424163af6aSjose borrego char *, in_port_t, int); 2434163af6aSjose borrego static void smb_server_listener_destroy(smb_listener_daemon_t *); 2444163af6aSjose borrego static int smb_server_listener_start(smb_listener_daemon_t *); 2454163af6aSjose borrego static void smb_server_listener_stop(smb_listener_daemon_t *); 2464163af6aSjose borrego static void smb_server_listener(smb_thread_t *, void *); 2474163af6aSjose borrego static void smb_server_receiver(void *); 2484163af6aSjose borrego static void smb_server_create_session(smb_listener_daemon_t *, ksocket_t); 249811599a4SMatt Barden static void smb_server_destroy_session(smb_session_t *); 25023a9c295SGordon Ross static uint16_t smb_spool_get_fid(smb_server_t *); 25123a9c295SGordon Ross static boolean_t smb_spool_lookup_doc_byfid(smb_server_t *, uint16_t, 25223a9c295SGordon Ross smb_kspooldoc_t *); 2531fcced4cSJordan Brown 254811599a4SMatt Barden /* 255811599a4SMatt Barden * How many "buckets" should our hash tables use? On a "real" server, 256811599a4SMatt Barden * make them much larger than the number of CPUs we're likely to have. 257811599a4SMatt Barden * On "fksmbd" make it smaller so dtrace logs are shorter. 258811599a4SMatt Barden * These must be powers of two. 259811599a4SMatt Barden */ 260811599a4SMatt Barden #ifdef _KERNEL 261811599a4SMatt Barden #define DEFAULT_HASH_NBUCKETS 256 /* real server */ 262811599a4SMatt Barden #else 263811599a4SMatt Barden #define DEFAULT_HASH_NBUCKETS 16 /* for "fksmbd" */ 264811599a4SMatt Barden #endif 265811599a4SMatt Barden uint32_t SMB_OFILE_HASH_NBUCKETS = DEFAULT_HASH_NBUCKETS; 266811599a4SMatt Barden uint32_t SMB_LEASE_HASH_NBUCKETS = DEFAULT_HASH_NBUCKETS; 267811599a4SMatt Barden 2689fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States int smb_event_debug = 0; 2699fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 270faa1795aSjb150015 static smb_llist_t smb_servers; 271faa1795aSjb150015 272*7f5d80fdSGordon Ross /* for smb_server_destroy_session() */ 273*7f5d80fdSGordon Ross static smb_llist_t smb_server_session_zombies; 274*7f5d80fdSGordon Ross 2758622ec45SGordon Ross kmem_cache_t *smb_cache_request; 2768622ec45SGordon Ross kmem_cache_t *smb_cache_session; 2778622ec45SGordon Ross kmem_cache_t *smb_cache_user; 2788622ec45SGordon Ross kmem_cache_t *smb_cache_tree; 2798622ec45SGordon Ross kmem_cache_t *smb_cache_ofile; 2808622ec45SGordon Ross kmem_cache_t *smb_cache_odir; 2818622ec45SGordon Ross kmem_cache_t *smb_cache_opipe; 2828622ec45SGordon Ross kmem_cache_t *smb_cache_event; 2830897f7fbSGordon Ross kmem_cache_t *smb_cache_lock; 2848622ec45SGordon Ross 285faa1795aSjb150015 /* 286faa1795aSjb150015 * ***************************************************************************** 287faa1795aSjb150015 * **************** Functions called from the device interface ***************** 288faa1795aSjb150015 * ***************************************************************************** 289faa1795aSjb150015 * 2901fcced4cSJordan Brown * These functions typically have to determine the relevant smb server 2911fcced4cSJordan Brown * to which the call applies. 292faa1795aSjb150015 */ 293faa1795aSjb150015 294faa1795aSjb150015 /* 295a90cf9f2SGordon Ross * How many zones have an SMB server active? 296a90cf9f2SGordon Ross */ 297a90cf9f2SGordon Ross int 298a90cf9f2SGordon Ross smb_server_get_count(void) 299a90cf9f2SGordon Ross { 300a90cf9f2SGordon Ross return (smb_llist_get_count(&smb_servers)); 301a90cf9f2SGordon Ross } 302a90cf9f2SGordon Ross 303a90cf9f2SGordon Ross /* 3048622ec45SGordon Ross * smb_server_g_init 305faa1795aSjb150015 * 306c8ec8eeaSjose borrego * This function must be called from smb_drv_attach(). 307faa1795aSjb150015 */ 308faa1795aSjb150015 int 3098622ec45SGordon Ross smb_server_g_init(void) 310faa1795aSjb150015 { 3118622ec45SGordon Ross int rc; 312faa1795aSjb150015 3138622ec45SGordon Ross if ((rc = smb_vop_init()) != 0) 3148622ec45SGordon Ross goto errout; 3158622ec45SGordon Ross if ((rc = smb_fem_init()) != 0) 3168622ec45SGordon Ross goto errout; 3178622ec45SGordon Ross 3188622ec45SGordon Ross smb_kshare_g_init(); 3198622ec45SGordon Ross smb_codepage_init(); 3208622ec45SGordon Ross smb_mbc_init(); /* smb_mbc_cache */ 3218622ec45SGordon Ross smb_node_init(); /* smb_node_cache, lists */ 32294047d49SGordon Ross smb2_lease_init(); 3238622ec45SGordon Ross 3248622ec45SGordon Ross smb_cache_request = kmem_cache_create("smb_request_cache", 3258622ec45SGordon Ross sizeof (smb_request_t), 8, NULL, NULL, NULL, NULL, NULL, 0); 3268622ec45SGordon Ross smb_cache_session = kmem_cache_create("smb_session_cache", 3278622ec45SGordon Ross sizeof (smb_session_t), 8, NULL, NULL, NULL, NULL, NULL, 0); 3288622ec45SGordon Ross smb_cache_user = kmem_cache_create("smb_user_cache", 3298622ec45SGordon Ross sizeof (smb_user_t), 8, NULL, NULL, NULL, NULL, NULL, 0); 3308622ec45SGordon Ross smb_cache_tree = kmem_cache_create("smb_tree_cache", 3318622ec45SGordon Ross sizeof (smb_tree_t), 8, NULL, NULL, NULL, NULL, NULL, 0); 3328622ec45SGordon Ross smb_cache_ofile = kmem_cache_create("smb_ofile_cache", 3338622ec45SGordon Ross sizeof (smb_ofile_t), 8, NULL, NULL, NULL, NULL, NULL, 0); 3348622ec45SGordon Ross smb_cache_odir = kmem_cache_create("smb_odir_cache", 3358622ec45SGordon Ross sizeof (smb_odir_t), 8, NULL, NULL, NULL, NULL, NULL, 0); 3368622ec45SGordon Ross smb_cache_opipe = kmem_cache_create("smb_opipe_cache", 3378622ec45SGordon Ross sizeof (smb_opipe_t), 8, NULL, NULL, NULL, NULL, NULL, 0); 3388622ec45SGordon Ross smb_cache_event = kmem_cache_create("smb_event_cache", 3398622ec45SGordon Ross sizeof (smb_event_t), 8, NULL, NULL, NULL, NULL, NULL, 0); 3400897f7fbSGordon Ross smb_cache_lock = kmem_cache_create("smb_lock_cache", 3410897f7fbSGordon Ross sizeof (smb_lock_t), 8, NULL, NULL, NULL, NULL, NULL, 0); 3428622ec45SGordon Ross 3439fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States smb_llist_init(); 344faa1795aSjb150015 smb_llist_constructor(&smb_servers, sizeof (smb_server_t), 345faa1795aSjb150015 offsetof(smb_server_t, sv_lnd)); 3469fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 347*7f5d80fdSGordon Ross smb_llist_constructor(&smb_server_session_zombies, 348*7f5d80fdSGordon Ross sizeof (smb_session_t), offsetof(smb_session_t, s_lnd)); 349*7f5d80fdSGordon Ross 3508622ec45SGordon Ross return (0); 3518622ec45SGordon Ross 3528622ec45SGordon Ross errout: 353faa1795aSjb150015 smb_fem_fini(); 354faa1795aSjb150015 smb_vop_fini(); 355faa1795aSjb150015 return (rc); 356faa1795aSjb150015 } 357faa1795aSjb150015 358faa1795aSjb150015 /* 3598622ec45SGordon Ross * smb_server_g_fini 360faa1795aSjb150015 * 361faa1795aSjb150015 * This function must called from smb_drv_detach(). It will fail if servers 362faa1795aSjb150015 * still exist. 363faa1795aSjb150015 */ 364a90cf9f2SGordon Ross void 3658622ec45SGordon Ross smb_server_g_fini(void) 366faa1795aSjb150015 { 367faa1795aSjb150015 368a90cf9f2SGordon Ross ASSERT(smb_llist_get_count(&smb_servers) == 0); 369a90cf9f2SGordon Ross 3709fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States smb_llist_fini(); 3718622ec45SGordon Ross 3728622ec45SGordon Ross kmem_cache_destroy(smb_cache_request); 3738622ec45SGordon Ross kmem_cache_destroy(smb_cache_session); 3748622ec45SGordon Ross kmem_cache_destroy(smb_cache_user); 3758622ec45SGordon Ross kmem_cache_destroy(smb_cache_tree); 3768622ec45SGordon Ross kmem_cache_destroy(smb_cache_ofile); 3778622ec45SGordon Ross kmem_cache_destroy(smb_cache_odir); 3788622ec45SGordon Ross kmem_cache_destroy(smb_cache_opipe); 3798622ec45SGordon Ross kmem_cache_destroy(smb_cache_event); 3800897f7fbSGordon Ross kmem_cache_destroy(smb_cache_lock); 3818622ec45SGordon Ross 38294047d49SGordon Ross smb2_lease_fini(); 383faa1795aSjb150015 smb_node_fini(); 3842c2961f8Sjose borrego smb_mbc_fini(); 385adc68ba9SPavel Zakharov smb_codepage_fini(); 3868622ec45SGordon Ross smb_kshare_g_fini(); 3878622ec45SGordon Ross 3888622ec45SGordon Ross smb_fem_fini(); 3898622ec45SGordon Ross smb_vop_fini(); 3908622ec45SGordon Ross 391faa1795aSjb150015 smb_llist_destructor(&smb_servers); 392faa1795aSjb150015 } 393faa1795aSjb150015 394faa1795aSjb150015 /* 395faa1795aSjb150015 * smb_server_create 396faa1795aSjb150015 * 397faa1795aSjb150015 * This function will fail if there's already a server associated with the 398faa1795aSjb150015 * caller's zone. 399faa1795aSjb150015 */ 400faa1795aSjb150015 int 401faa1795aSjb150015 smb_server_create(void) 402faa1795aSjb150015 { 403faa1795aSjb150015 zoneid_t zid; 404faa1795aSjb150015 smb_server_t *sv; 405faa1795aSjb150015 406faa1795aSjb150015 zid = getzoneid(); 407faa1795aSjb150015 408faa1795aSjb150015 smb_llist_enter(&smb_servers, RW_WRITER); 409faa1795aSjb150015 sv = smb_llist_head(&smb_servers); 410faa1795aSjb150015 while (sv) { 4119fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States SMB_SERVER_VALID(sv); 412faa1795aSjb150015 if (sv->sv_zid == zid) { 413faa1795aSjb150015 smb_llist_exit(&smb_servers); 41494fff790SAlan Wright return (EPERM); 415faa1795aSjb150015 } 416faa1795aSjb150015 sv = smb_llist_next(&smb_servers, sv); 417faa1795aSjb150015 } 418faa1795aSjb150015 4198622ec45SGordon Ross sv = kmem_zalloc(sizeof (smb_server_t), KM_SLEEP); 4208622ec45SGordon Ross 4218622ec45SGordon Ross sv->sv_magic = SMB_SERVER_MAGIC; 4228622ec45SGordon Ross sv->sv_state = SMB_SERVER_STATE_CREATED; 4238622ec45SGordon Ross sv->sv_zid = zid; 424b819cea2SGordon Ross sv->sv_pid = ddi_get_pid(); 4258622ec45SGordon Ross 4268622ec45SGordon Ross mutex_init(&sv->sv_mutex, NULL, MUTEX_DEFAULT, NULL); 4278622ec45SGordon Ross cv_init(&sv->sv_cv, NULL, CV_DEFAULT, NULL); 4288622ec45SGordon Ross cv_init(&sv->sp_info.sp_cv, NULL, CV_DEFAULT, NULL); 429faa1795aSjb150015 430811599a4SMatt Barden sv->sv_persistid_ht = smb_hash_create(sizeof (smb_ofile_t), 431811599a4SMatt Barden offsetof(smb_ofile_t, f_dh_lnd), SMB_OFILE_HASH_NBUCKETS); 432811599a4SMatt Barden 43394047d49SGordon Ross sv->sv_lease_ht = smb_hash_create(sizeof (smb_lease_t), 43494047d49SGordon Ross offsetof(smb_lease_t, ls_lnd), SMB_LEASE_HASH_NBUCKETS); 43594047d49SGordon Ross 436811599a4SMatt Barden smb_llist_constructor(&sv->sv_session_list, sizeof (smb_session_t), 437811599a4SMatt Barden offsetof(smb_session_t, s_lnd)); 438811599a4SMatt Barden 4399fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States smb_llist_constructor(&sv->sv_event_list, sizeof (smb_event_t), 4409fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States offsetof(smb_event_t, se_lnd)); 4419fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 442cb174861Sjoyce mcintosh smb_llist_constructor(&sv->sp_info.sp_list, sizeof (smb_kspooldoc_t), 443cb174861Sjoyce mcintosh offsetof(smb_kspooldoc_t, sd_lnd)); 444cb174861Sjoyce mcintosh 445cb174861Sjoyce mcintosh smb_llist_constructor(&sv->sp_info.sp_fidlist, 446cb174861Sjoyce mcintosh sizeof (smb_spoolfid_t), offsetof(smb_spoolfid_t, sf_lnd)); 447cb174861Sjoyce mcintosh 448a90cf9f2SGordon Ross sv->sv_disp_stats1 = kmem_zalloc(SMB_COM_NUM * 449a90cf9f2SGordon Ross sizeof (smb_disp_stats_t), KM_SLEEP); 450a90cf9f2SGordon Ross 451a90cf9f2SGordon Ross sv->sv_disp_stats2 = kmem_zalloc(SMB2__NCMDS * 4528622ec45SGordon Ross sizeof (smb_disp_stats_t), KM_SLEEP); 453faa1795aSjb150015 45408344b29SGordon Ross smb_thread_init(&sv->si_thread_timers, "smb_timers", 45508344b29SGordon Ross smb_server_timers, sv, smbsrv_timer_pri); 456faa1795aSjb150015 457148c5f43SAlan Wright smb_srqueue_init(&sv->sv_srqueue); 458faa1795aSjb150015 4598622ec45SGordon Ross smb_kdoor_init(sv); 4608622ec45SGordon Ross smb_kshare_init(sv); 461148c5f43SAlan Wright smb_server_kstat_init(sv); 462faa1795aSjb150015 463856399cfSGordon Ross smb_threshold_init(&sv->sv_ssetup_ct, SMB_SSETUP_CMD, 464856399cfSGordon Ross smb_ssetup_threshold, smb_ssetup_timeout); 465856399cfSGordon Ross smb_threshold_init(&sv->sv_tcon_ct, SMB_TCON_CMD, 466856399cfSGordon Ross smb_tcon_threshold, smb_tcon_timeout); 467856399cfSGordon Ross smb_threshold_init(&sv->sv_opipe_ct, SMB_OPIPE_CMD, 468856399cfSGordon Ross smb_opipe_threshold, smb_opipe_timeout); 469856399cfSGordon Ross 470faa1795aSjb150015 smb_llist_insert_tail(&smb_servers, sv); 471faa1795aSjb150015 smb_llist_exit(&smb_servers); 472cb174861Sjoyce mcintosh 473faa1795aSjb150015 return (0); 474faa1795aSjb150015 } 475faa1795aSjb150015 476faa1795aSjb150015 /* 477faa1795aSjb150015 * smb_server_delete 478faa1795aSjb150015 * 479faa1795aSjb150015 * This function will delete the server passed in. It will make sure that all 480faa1795aSjb150015 * activity associated that server has ceased before destroying it. 481faa1795aSjb150015 */ 482faa1795aSjb150015 int 4838d94f651SGordon Ross smb_server_delete(smb_server_t *sv) 484faa1795aSjb150015 { 485faa1795aSjb150015 486faa1795aSjb150015 mutex_enter(&sv->sv_mutex); 487faa1795aSjb150015 switch (sv->sv_state) { 488faa1795aSjb150015 case SMB_SERVER_STATE_RUNNING: 4899fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States sv->sv_state = SMB_SERVER_STATE_STOPPING; 490faa1795aSjb150015 mutex_exit(&sv->sv_mutex); 4914163af6aSjose borrego smb_server_shutdown(sv); 492faa1795aSjb150015 mutex_enter(&sv->sv_mutex); 4934163af6aSjose borrego cv_broadcast(&sv->sp_info.sp_cv); 4944163af6aSjose borrego sv->sv_state = SMB_SERVER_STATE_DELETING; 4954163af6aSjose borrego break; 4964163af6aSjose borrego case SMB_SERVER_STATE_STOPPING: 4974163af6aSjose borrego sv->sv_state = SMB_SERVER_STATE_DELETING; 498faa1795aSjb150015 break; 499faa1795aSjb150015 case SMB_SERVER_STATE_CONFIGURED: 500faa1795aSjb150015 case SMB_SERVER_STATE_CREATED: 501faa1795aSjb150015 sv->sv_state = SMB_SERVER_STATE_DELETING; 502faa1795aSjb150015 break; 503faa1795aSjb150015 default: 5049fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States SMB_SERVER_STATE_VALID(sv->sv_state); 505faa1795aSjb150015 mutex_exit(&sv->sv_mutex); 506faa1795aSjb150015 smb_server_release(sv); 507faa1795aSjb150015 return (ENOTTY); 508faa1795aSjb150015 } 509faa1795aSjb150015 510faa1795aSjb150015 ASSERT(sv->sv_state == SMB_SERVER_STATE_DELETING); 511faa1795aSjb150015 512faa1795aSjb150015 sv->sv_refcnt--; 513faa1795aSjb150015 while (sv->sv_refcnt) 514faa1795aSjb150015 cv_wait(&sv->sv_cv, &sv->sv_mutex); 515faa1795aSjb150015 516faa1795aSjb150015 mutex_exit(&sv->sv_mutex); 517faa1795aSjb150015 518faa1795aSjb150015 smb_llist_enter(&smb_servers, RW_WRITER); 519faa1795aSjb150015 smb_llist_remove(&smb_servers, sv); 520faa1795aSjb150015 smb_llist_exit(&smb_servers); 521faa1795aSjb150015 522856399cfSGordon Ross smb_threshold_fini(&sv->sv_ssetup_ct); 523856399cfSGordon Ross smb_threshold_fini(&sv->sv_tcon_ct); 524856399cfSGordon Ross smb_threshold_fini(&sv->sv_opipe_ct); 525856399cfSGordon Ross 5264163af6aSjose borrego smb_server_listener_destroy(&sv->sv_nbt_daemon); 5274163af6aSjose borrego smb_server_listener_destroy(&sv->sv_tcp_daemon); 528faa1795aSjb150015 rw_destroy(&sv->sv_cfg_lock); 529faa1795aSjb150015 smb_server_kstat_fini(sv); 5308622ec45SGordon Ross smb_kshare_fini(sv); 5318622ec45SGordon Ross smb_kdoor_fini(sv); 5329fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States smb_llist_destructor(&sv->sv_event_list); 533811599a4SMatt Barden smb_llist_destructor(&sv->sv_session_list); 5342c1b14e5Sjose borrego 535a90cf9f2SGordon Ross kmem_free(sv->sv_disp_stats1, 5368622ec45SGordon Ross SMB_COM_NUM * sizeof (smb_disp_stats_t)); 537faa1795aSjb150015 538a90cf9f2SGordon Ross kmem_free(sv->sv_disp_stats2, 539a90cf9f2SGordon Ross SMB2__NCMDS * sizeof (smb_disp_stats_t)); 540a90cf9f2SGordon Ross 541148c5f43SAlan Wright smb_srqueue_destroy(&sv->sv_srqueue); 542faa1795aSjb150015 smb_thread_destroy(&sv->si_thread_timers); 5438622ec45SGordon Ross 544faa1795aSjb150015 mutex_destroy(&sv->sv_mutex); 54594047d49SGordon Ross smb_hash_destroy(sv->sv_lease_ht); 546811599a4SMatt Barden smb_hash_destroy(sv->sv_persistid_ht); 547faa1795aSjb150015 cv_destroy(&sv->sv_cv); 548faa1795aSjb150015 sv->sv_magic = 0; 549faa1795aSjb150015 kmem_free(sv, sizeof (smb_server_t)); 550faa1795aSjb150015 551faa1795aSjb150015 return (0); 552faa1795aSjb150015 } 553faa1795aSjb150015 554faa1795aSjb150015 /* 555faa1795aSjb150015 * smb_server_configure 556faa1795aSjb150015 */ 557faa1795aSjb150015 int 55829bd2886SAlan Wright smb_server_configure(smb_ioc_cfg_t *ioc) 559faa1795aSjb150015 { 560faa1795aSjb150015 int rc = 0; 561faa1795aSjb150015 smb_server_t *sv; 562faa1795aSjb150015 5631d443a93SDan McDonald /* 5641d443a93SDan McDonald * Reality check negotiation token length vs. #define'd maximum. 5651d443a93SDan McDonald */ 5661d443a93SDan McDonald if (ioc->negtok_len > SMB_PI_MAX_NEGTOK) 5671d443a93SDan McDonald return (EINVAL); 5681d443a93SDan McDonald 569faa1795aSjb150015 rc = smb_server_lookup(&sv); 570faa1795aSjb150015 if (rc) 571faa1795aSjb150015 return (rc); 572faa1795aSjb150015 573faa1795aSjb150015 mutex_enter(&sv->sv_mutex); 574faa1795aSjb150015 switch (sv->sv_state) { 575faa1795aSjb150015 case SMB_SERVER_STATE_CREATED: 57629bd2886SAlan Wright smb_server_store_cfg(sv, ioc); 577faa1795aSjb150015 sv->sv_state = SMB_SERVER_STATE_CONFIGURED; 578faa1795aSjb150015 break; 579faa1795aSjb150015 580faa1795aSjb150015 case SMB_SERVER_STATE_CONFIGURED: 58129bd2886SAlan Wright smb_server_store_cfg(sv, ioc); 582faa1795aSjb150015 break; 583faa1795aSjb150015 584faa1795aSjb150015 case SMB_SERVER_STATE_RUNNING: 5859fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States case SMB_SERVER_STATE_STOPPING: 586faa1795aSjb150015 rw_enter(&sv->sv_cfg_lock, RW_WRITER); 58729bd2886SAlan Wright smb_server_store_cfg(sv, ioc); 588faa1795aSjb150015 rw_exit(&sv->sv_cfg_lock); 589faa1795aSjb150015 break; 590faa1795aSjb150015 591faa1795aSjb150015 default: 5929fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States SMB_SERVER_STATE_VALID(sv->sv_state); 593faa1795aSjb150015 rc = EFAULT; 594faa1795aSjb150015 break; 595faa1795aSjb150015 } 596faa1795aSjb150015 mutex_exit(&sv->sv_mutex); 597faa1795aSjb150015 598faa1795aSjb150015 smb_server_release(sv); 599faa1795aSjb150015 600faa1795aSjb150015 return (rc); 601faa1795aSjb150015 } 602faa1795aSjb150015 603faa1795aSjb150015 /* 604faa1795aSjb150015 * smb_server_start 605faa1795aSjb150015 */ 606faa1795aSjb150015 int 60729bd2886SAlan Wright smb_server_start(smb_ioc_start_t *ioc) 608faa1795aSjb150015 { 609faa1795aSjb150015 int rc = 0; 6104163af6aSjose borrego int family; 611faa1795aSjb150015 smb_server_t *sv; 6128d94f651SGordon Ross cred_t *ucr; 613faa1795aSjb150015 614faa1795aSjb150015 rc = smb_server_lookup(&sv); 615faa1795aSjb150015 if (rc) 616faa1795aSjb150015 return (rc); 617faa1795aSjb150015 618faa1795aSjb150015 mutex_enter(&sv->sv_mutex); 619faa1795aSjb150015 switch (sv->sv_state) { 620faa1795aSjb150015 case SMB_SERVER_STATE_CONFIGURED: 621faa1795aSjb150015 6228622ec45SGordon Ross if ((rc = smb_server_fsop_start(sv)) != 0) 6238622ec45SGordon Ross break; 6248622ec45SGordon Ross 6258d94f651SGordon Ross /* 6268d94f651SGordon Ross * Note: smb_kshare_start needs sv_session. 6278d94f651SGordon Ross */ 6288d94f651SGordon Ross sv->sv_session = smb_session_create(NULL, 0, sv, 0); 6298d94f651SGordon Ross if (sv->sv_session == NULL) { 6308d94f651SGordon Ross rc = ENOMEM; 6318d94f651SGordon Ross break; 6328d94f651SGordon Ross } 6338d94f651SGordon Ross 6348d94f651SGordon Ross /* 6358d94f651SGordon Ross * Create a logon on the server session, 6368d94f651SGordon Ross * used when importing CA shares. 6378d94f651SGordon Ross */ 6388d94f651SGordon Ross sv->sv_rootuser = smb_user_new(sv->sv_session); 6398d94f651SGordon Ross ucr = smb_kcred_create(); 6408d94f651SGordon Ross rc = smb_user_logon(sv->sv_rootuser, ucr, "", "root", 6418d94f651SGordon Ross SMB_USER_FLAG_ADMIN, 0, 0); 6428d94f651SGordon Ross crfree(ucr); 6438d94f651SGordon Ross ucr = NULL; 6448d94f651SGordon Ross if (rc != 0) { 6458d94f651SGordon Ross cmn_err(CE_NOTE, "smb_server_start: " 6468d94f651SGordon Ross "failed to create root user"); 6478d94f651SGordon Ross break; 6488d94f651SGordon Ross } 6498d94f651SGordon Ross 6508622ec45SGordon Ross if ((rc = smb_kshare_start(sv)) != 0) 6518622ec45SGordon Ross break; 6528622ec45SGordon Ross 653b819cea2SGordon Ross /* 654b819cea2SGordon Ross * NB: the proc passed here has to be a "system" one. 655b819cea2SGordon Ross * Normally that's p0, or the NGZ eqivalent. 656b819cea2SGordon Ross */ 6578622ec45SGordon Ross sv->sv_worker_pool = taskq_create_proc("smb_workers", 65808344b29SGordon Ross sv->sv_cfg.skc_maxworkers, smbsrv_worker_pri, 659faa1795aSjb150015 sv->sv_cfg.skc_maxworkers, INT_MAX, 6608622ec45SGordon Ross curzone->zone_zsched, TASKQ_DYNAMIC); 661faa1795aSjb150015 6628622ec45SGordon Ross sv->sv_receiver_pool = taskq_create_proc("smb_receivers", 66308344b29SGordon Ross sv->sv_cfg.skc_maxconnections, smbsrv_receive_pri, 6644163af6aSjose borrego sv->sv_cfg.skc_maxconnections, INT_MAX, 6658622ec45SGordon Ross curzone->zone_zsched, TASKQ_DYNAMIC); 6664163af6aSjose borrego 6678d94f651SGordon Ross if (sv->sv_worker_pool == NULL || 6688d94f651SGordon Ross sv->sv_receiver_pool == NULL) { 669faa1795aSjb150015 rc = ENOMEM; 670faa1795aSjb150015 break; 671faa1795aSjb150015 } 672faa1795aSjb150015 673b819cea2SGordon Ross #ifdef _KERNEL 674faa1795aSjb150015 ASSERT(sv->sv_lmshrd == NULL); 675148c5f43SAlan Wright sv->sv_lmshrd = smb_kshare_door_init(ioc->lmshrd); 676faa1795aSjb150015 if (sv->sv_lmshrd == NULL) 677faa1795aSjb150015 break; 67854026d5aSGordon Ross if ((rc = smb_kdoor_open(sv, ioc->udoor)) != 0) { 6799fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States cmn_err(CE_WARN, "Cannot open smbd door"); 680faa1795aSjb150015 break; 6819fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States } 682b819cea2SGordon Ross #else /* _KERNEL */ 683b819cea2SGordon Ross /* Fake kernel does not use the kshare_door */ 684b819cea2SGordon Ross fksmb_kdoor_open(sv, ioc->udoor_func); 685b819cea2SGordon Ross #endif /* _KERNEL */ 686b819cea2SGordon Ross 68754026d5aSGordon Ross if ((rc = smb_thread_start(&sv->si_thread_timers)) != 0) 6889fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States break; 6894163af6aSjose borrego 6904163af6aSjose borrego family = AF_INET; 6914163af6aSjose borrego smb_server_listener_init(sv, &sv->sv_nbt_daemon, 6924163af6aSjose borrego "smb_nbt_listener", IPPORT_NETBIOS_SSN, family); 6934163af6aSjose borrego if (sv->sv_cfg.skc_ipv6_enable) 6944163af6aSjose borrego family = AF_INET6; 6954163af6aSjose borrego smb_server_listener_init(sv, &sv->sv_tcp_daemon, 6964163af6aSjose borrego "smb_tcp_listener", IPPORT_SMB, family); 6974163af6aSjose borrego rc = smb_server_listener_start(&sv->sv_tcp_daemon); 6984163af6aSjose borrego if (rc != 0) 6994163af6aSjose borrego break; 70083d2dfe6SGordon Ross if (sv->sv_cfg.skc_netbios_enable) 70183d2dfe6SGordon Ross (void) smb_server_listener_start(&sv->sv_nbt_daemon); 7024163af6aSjose borrego 703faa1795aSjb150015 sv->sv_state = SMB_SERVER_STATE_RUNNING; 704148c5f43SAlan Wright sv->sv_start_time = gethrtime(); 705faa1795aSjb150015 mutex_exit(&sv->sv_mutex); 706faa1795aSjb150015 smb_server_release(sv); 7078622ec45SGordon Ross smb_export_start(sv); 708faa1795aSjb150015 return (0); 709faa1795aSjb150015 default: 7109fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States SMB_SERVER_STATE_VALID(sv->sv_state); 711faa1795aSjb150015 mutex_exit(&sv->sv_mutex); 712faa1795aSjb150015 smb_server_release(sv); 713faa1795aSjb150015 return (ENOTTY); 714faa1795aSjb150015 } 715faa1795aSjb150015 716faa1795aSjb150015 mutex_exit(&sv->sv_mutex); 7174163af6aSjose borrego smb_server_shutdown(sv); 718faa1795aSjb150015 smb_server_release(sv); 719faa1795aSjb150015 return (rc); 720faa1795aSjb150015 } 721faa1795aSjb150015 722faa1795aSjb150015 /* 7239fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States * An smbd is shutting down. 7249fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States */ 7259fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States int 7269fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States smb_server_stop(void) 7279fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States { 7289fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States smb_server_t *sv; 7299fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States int rc; 7309fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 7319fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States if ((rc = smb_server_lookup(&sv)) != 0) 7329fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States return (rc); 7339fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 7349fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States mutex_enter(&sv->sv_mutex); 7359fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States switch (sv->sv_state) { 7369fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States case SMB_SERVER_STATE_RUNNING: 7379fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States sv->sv_state = SMB_SERVER_STATE_STOPPING; 7384163af6aSjose borrego mutex_exit(&sv->sv_mutex); 7394163af6aSjose borrego smb_server_shutdown(sv); 7404163af6aSjose borrego mutex_enter(&sv->sv_mutex); 741cb174861Sjoyce mcintosh cv_broadcast(&sv->sp_info.sp_cv); 7429fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States break; 7439fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States default: 7449fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States SMB_SERVER_STATE_VALID(sv->sv_state); 7459fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States break; 7469fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States } 7479fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States mutex_exit(&sv->sv_mutex); 7489fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 7499fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States smb_server_release(sv); 7509fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States return (0); 7519fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States } 7529fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 7539fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States boolean_t 7548622ec45SGordon Ross smb_server_is_stopping(smb_server_t *sv) 7559fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States { 7569fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States boolean_t status; 7579fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 7589fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States SMB_SERVER_VALID(sv); 7599fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 7609fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States mutex_enter(&sv->sv_mutex); 7619fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 7629fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States switch (sv->sv_state) { 7639fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States case SMB_SERVER_STATE_STOPPING: 7649fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States case SMB_SERVER_STATE_DELETING: 7659fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States status = B_TRUE; 7669fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States break; 7679fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States default: 7689fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States status = B_FALSE; 7699fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States break; 7709fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States } 7719fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 7729fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States mutex_exit(&sv->sv_mutex); 7739fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States return (status); 7749fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States } 7759fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 7768622ec45SGordon Ross void 7778622ec45SGordon Ross smb_server_cancel_event(smb_server_t *sv, uint32_t txid) 7789fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States { 7799fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States smb_event_cancel(sv, txid); 7809fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States } 7819fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 7829fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States int 7839fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States smb_server_notify_event(smb_ioc_event_t *ioc) 7849fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States { 7859fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States smb_server_t *sv; 7869fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States int rc; 7879fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 7889fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States if ((rc = smb_server_lookup(&sv)) == 0) { 7899fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States smb_event_notify(sv, ioc->txid); 7909fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States smb_server_release(sv); 7919fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States } 7929fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 7939fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States return (rc); 7949fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States } 7959fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 7969fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States /* 797cb174861Sjoyce mcintosh * smb_server_spooldoc 798cb174861Sjoyce mcintosh * 799cb174861Sjoyce mcintosh * Waits for print file close broadcast. 800cb174861Sjoyce mcintosh * Gets the head of the fid list, 801cb174861Sjoyce mcintosh * then searches the spooldoc list and returns 802cb174861Sjoyce mcintosh * this info via the ioctl to user land. 803cb174861Sjoyce mcintosh * 804cb174861Sjoyce mcintosh * rc - 0 success 805cb174861Sjoyce mcintosh */ 806cb174861Sjoyce mcintosh 807cb174861Sjoyce mcintosh int 808cb174861Sjoyce mcintosh smb_server_spooldoc(smb_ioc_spooldoc_t *ioc) 809cb174861Sjoyce mcintosh { 810cb174861Sjoyce mcintosh smb_server_t *sv; 811cb174861Sjoyce mcintosh int rc; 812cb174861Sjoyce mcintosh smb_kspooldoc_t *spdoc; 813cb174861Sjoyce mcintosh uint16_t fid; 814cb174861Sjoyce mcintosh 81523a9c295SGordon Ross if ((rc = smb_server_lookup(&sv)) != 0) 81623a9c295SGordon Ross return (rc); 81723a9c295SGordon Ross 818b7301bf5SGordon Ross if (sv->sv_cfg.skc_print_enable == 0) { 819b7301bf5SGordon Ross rc = ENOTTY; 820b7301bf5SGordon Ross goto out; 821b7301bf5SGordon Ross } 822b7301bf5SGordon Ross 82323a9c295SGordon Ross mutex_enter(&sv->sv_mutex); 82423a9c295SGordon Ross for (;;) { 825cb174861Sjoyce mcintosh if (sv->sv_state != SMB_SERVER_STATE_RUNNING) { 826cb174861Sjoyce mcintosh rc = ECANCELED; 82723a9c295SGordon Ross break; 82823a9c295SGordon Ross } 82923a9c295SGordon Ross if ((fid = smb_spool_get_fid(sv)) != 0) { 83023a9c295SGordon Ross rc = 0; 83123a9c295SGordon Ross break; 83223a9c295SGordon Ross } 83323a9c295SGordon Ross if (cv_wait_sig(&sv->sp_info.sp_cv, &sv->sv_mutex) == 0) { 83423a9c295SGordon Ross rc = EINTR; 83523a9c295SGordon Ross break; 83623a9c295SGordon Ross } 83723a9c295SGordon Ross } 83823a9c295SGordon Ross mutex_exit(&sv->sv_mutex); 839b7301bf5SGordon Ross if (rc != 0) 840b7301bf5SGordon Ross goto out; 841b7301bf5SGordon Ross 84223a9c295SGordon Ross spdoc = kmem_zalloc(sizeof (*spdoc), KM_SLEEP); 84323a9c295SGordon Ross if (smb_spool_lookup_doc_byfid(sv, fid, spdoc)) { 844cb174861Sjoyce mcintosh ioc->spool_num = spdoc->sd_spool_num; 845cb174861Sjoyce mcintosh ioc->ipaddr = spdoc->sd_ipaddr; 846cb174861Sjoyce mcintosh (void) strlcpy(ioc->path, spdoc->sd_path, 847cb174861Sjoyce mcintosh MAXPATHLEN); 848cb174861Sjoyce mcintosh (void) strlcpy(ioc->username, 849cb174861Sjoyce mcintosh spdoc->sd_username, MAXNAMELEN); 85023a9c295SGordon Ross } else { 85123a9c295SGordon Ross /* Did not find that print job. */ 85223a9c295SGordon Ross rc = EAGAIN; 853cb174861Sjoyce mcintosh } 85423a9c295SGordon Ross kmem_free(spdoc, sizeof (*spdoc)); 85523a9c295SGordon Ross 856b7301bf5SGordon Ross out: 857cb174861Sjoyce mcintosh smb_server_release(sv); 858cb174861Sjoyce mcintosh return (rc); 859cb174861Sjoyce mcintosh } 860cb174861Sjoyce mcintosh 861faa1795aSjb150015 int 86229bd2886SAlan Wright smb_server_set_gmtoff(smb_ioc_gmt_t *ioc) 863faa1795aSjb150015 { 864faa1795aSjb150015 int rc; 865faa1795aSjb150015 smb_server_t *sv; 866faa1795aSjb150015 86708f0d8daSafshin salek ardakani - Sun Microsystems - Irvine United States if ((rc = smb_server_lookup(&sv)) == 0) { 86829bd2886SAlan Wright sv->si_gmtoff = ioc->offset; 869faa1795aSjb150015 smb_server_release(sv); 87008f0d8daSafshin salek ardakani - Sun Microsystems - Irvine United States } 871faa1795aSjb150015 872faa1795aSjb150015 return (rc); 873faa1795aSjb150015 } 874faa1795aSjb150015 87529bd2886SAlan Wright int 8761fcced4cSJordan Brown smb_server_numopen(smb_ioc_opennum_t *ioc) 87729bd2886SAlan Wright { 87829bd2886SAlan Wright smb_server_t *sv; 87929bd2886SAlan Wright int rc; 88029bd2886SAlan Wright 88129bd2886SAlan Wright if ((rc = smb_server_lookup(&sv)) == 0) { 882148c5f43SAlan Wright ioc->open_users = sv->sv_users; 883148c5f43SAlan Wright ioc->open_trees = sv->sv_trees; 884148c5f43SAlan Wright ioc->open_files = sv->sv_files + sv->sv_pipes; 88529bd2886SAlan Wright smb_server_release(sv); 88629bd2886SAlan Wright } 88729bd2886SAlan Wright return (rc); 88829bd2886SAlan Wright } 88929bd2886SAlan Wright 890faa1795aSjb150015 /* 8911fcced4cSJordan Brown * Enumerate objects within the server. The svcenum provides the 8921fcced4cSJordan Brown * enumeration context, i.e. what the caller want to get back. 8931fcced4cSJordan Brown */ 8941fcced4cSJordan Brown int 8951fcced4cSJordan Brown smb_server_enum(smb_ioc_svcenum_t *ioc) 8961fcced4cSJordan Brown { 8971fcced4cSJordan Brown smb_svcenum_t *svcenum = &ioc->svcenum; 8981fcced4cSJordan Brown smb_server_t *sv; 8991fcced4cSJordan Brown int rc; 9001fcced4cSJordan Brown 9011d443a93SDan McDonald /* 9021d443a93SDan McDonald * Reality check that the buffer-length insize the enum doesn't 9031d443a93SDan McDonald * overrun the ioctl's total length. 9041d443a93SDan McDonald */ 9051d443a93SDan McDonald if (svcenum->se_buflen + sizeof (*ioc) > ioc->hdr.len) 9061d443a93SDan McDonald return (EINVAL); 9071d443a93SDan McDonald 9081fcced4cSJordan Brown if ((rc = smb_server_lookup(&sv)) != 0) 9091fcced4cSJordan Brown return (rc); 9101fcced4cSJordan Brown 9111fcced4cSJordan Brown svcenum->se_bavail = svcenum->se_buflen; 9121fcced4cSJordan Brown svcenum->se_bused = 0; 9131fcced4cSJordan Brown svcenum->se_nitems = 0; 9141fcced4cSJordan Brown 9153b13a1efSThomas Keiser switch (svcenum->se_type) { 9163b13a1efSThomas Keiser case SMB_SVCENUM_TYPE_USER: 9178d94f651SGordon Ross smb_server_enum_users(sv, svcenum); 9183b13a1efSThomas Keiser break; 9193b13a1efSThomas Keiser case SMB_SVCENUM_TYPE_TREE: 9203b13a1efSThomas Keiser case SMB_SVCENUM_TYPE_FILE: 9218d94f651SGordon Ross smb_server_enum_trees(sv, svcenum); 9223b13a1efSThomas Keiser break; 9233b13a1efSThomas Keiser default: 9243b13a1efSThomas Keiser rc = EINVAL; 9253b13a1efSThomas Keiser } 9261fcced4cSJordan Brown 9271fcced4cSJordan Brown smb_server_release(sv); 9283b13a1efSThomas Keiser return (rc); 9291fcced4cSJordan Brown } 9301fcced4cSJordan Brown 9311fcced4cSJordan Brown /* 9321fcced4cSJordan Brown * Look for sessions to disconnect by client and user name. 9331fcced4cSJordan Brown */ 9341fcced4cSJordan Brown int 9351fcced4cSJordan Brown smb_server_session_close(smb_ioc_session_t *ioc) 9361fcced4cSJordan Brown { 9371fcced4cSJordan Brown smb_server_t *sv; 938811599a4SMatt Barden int cnt; 9391fcced4cSJordan Brown int rc; 9401fcced4cSJordan Brown 9411fcced4cSJordan Brown if ((rc = smb_server_lookup(&sv)) != 0) 9421fcced4cSJordan Brown return (rc); 9431fcced4cSJordan Brown 9448d94f651SGordon Ross cnt = smb_server_session_disconnect(sv, ioc->client, ioc->username); 9451fcced4cSJordan Brown 9461fcced4cSJordan Brown smb_server_release(sv); 9471fcced4cSJordan Brown 948811599a4SMatt Barden if (cnt == 0) 9491fcced4cSJordan Brown return (ENOENT); 9501fcced4cSJordan Brown return (0); 9511fcced4cSJordan Brown } 9521fcced4cSJordan Brown 9531fcced4cSJordan Brown /* 9541fcced4cSJordan Brown * Close a file by uniqid. 9551fcced4cSJordan Brown */ 9561fcced4cSJordan Brown int 9571fcced4cSJordan Brown smb_server_file_close(smb_ioc_fileid_t *ioc) 9581fcced4cSJordan Brown { 9591fcced4cSJordan Brown uint32_t uniqid = ioc->uniqid; 9601fcced4cSJordan Brown smb_server_t *sv; 9611fcced4cSJordan Brown int rc; 9621fcced4cSJordan Brown 9631fcced4cSJordan Brown if ((rc = smb_server_lookup(&sv)) != 0) 9641fcced4cSJordan Brown return (rc); 9651fcced4cSJordan Brown 9668d94f651SGordon Ross rc = smb_server_fclose(sv, uniqid); 9671fcced4cSJordan Brown 9681fcced4cSJordan Brown smb_server_release(sv); 9691fcced4cSJordan Brown return (rc); 9701fcced4cSJordan Brown } 9711fcced4cSJordan Brown 9721fcced4cSJordan Brown /* 973faa1795aSjb150015 * These functions determine the relevant smb server to which the call apply. 974faa1795aSjb150015 */ 975faa1795aSjb150015 976faa1795aSjb150015 uint32_t 9778622ec45SGordon Ross smb_server_get_session_count(smb_server_t *sv) 978faa1795aSjb150015 { 979faa1795aSjb150015 uint32_t counter = 0; 980faa1795aSjb150015 981811599a4SMatt Barden counter = smb_llist_get_count(&sv->sv_session_list); 982faa1795aSjb150015 983faa1795aSjb150015 return (counter); 984faa1795aSjb150015 } 985faa1795aSjb150015 986faa1795aSjb150015 /* 9878d94f651SGordon Ross * Gets the smb_node of the specified share path. 9888d94f651SGordon Ross * Node is returned held (caller must rele.) 989148c5f43SAlan Wright */ 990148c5f43SAlan Wright int 9918d94f651SGordon Ross smb_server_share_lookup(smb_server_t *sv, const char *shr_path, 9928d94f651SGordon Ross smb_node_t **nodepp) 993148c5f43SAlan Wright { 994148c5f43SAlan Wright smb_request_t *sr; 995148c5f43SAlan Wright smb_node_t *fnode = NULL; 9968d94f651SGordon Ross smb_node_t *dnode = NULL; 997148c5f43SAlan Wright char last_comp[MAXNAMELEN]; 998148c5f43SAlan Wright int rc = 0; 999148c5f43SAlan Wright 1000148c5f43SAlan Wright ASSERT(shr_path); 1001148c5f43SAlan Wright 1002148c5f43SAlan Wright mutex_enter(&sv->sv_mutex); 1003148c5f43SAlan Wright switch (sv->sv_state) { 1004148c5f43SAlan Wright case SMB_SERVER_STATE_RUNNING: 1005148c5f43SAlan Wright break; 1006148c5f43SAlan Wright default: 1007148c5f43SAlan Wright mutex_exit(&sv->sv_mutex); 1008148c5f43SAlan Wright return (ENOTACTIVE); 1009148c5f43SAlan Wright } 1010148c5f43SAlan Wright mutex_exit(&sv->sv_mutex); 1011148c5f43SAlan Wright 1012148c5f43SAlan Wright if ((sr = smb_request_alloc(sv->sv_session, 0)) == NULL) { 1013811599a4SMatt Barden return (ENOTCONN); 1014148c5f43SAlan Wright } 10158622ec45SGordon Ross sr->user_cr = zone_kcred(); 1016148c5f43SAlan Wright 1017148c5f43SAlan Wright rc = smb_pathname_reduce(sr, sr->user_cr, shr_path, 1018148c5f43SAlan Wright NULL, NULL, &dnode, last_comp); 1019148c5f43SAlan Wright 1020148c5f43SAlan Wright if (rc == 0) { 1021148c5f43SAlan Wright rc = smb_fsop_lookup(sr, sr->user_cr, SMB_FOLLOW_LINKS, 1022148c5f43SAlan Wright sv->si_root_smb_node, dnode, last_comp, &fnode); 1023148c5f43SAlan Wright smb_node_release(dnode); 1024148c5f43SAlan Wright } 1025148c5f43SAlan Wright 1026148c5f43SAlan Wright smb_request_free(sr); 1027148c5f43SAlan Wright 1028148c5f43SAlan Wright if (rc != 0) 1029148c5f43SAlan Wright return (rc); 1030148c5f43SAlan Wright 1031148c5f43SAlan Wright ASSERT(fnode->vp && fnode->vp->v_vfsp); 1032148c5f43SAlan Wright 10338d94f651SGordon Ross *nodepp = fnode; 1034148c5f43SAlan Wright 1035148c5f43SAlan Wright return (0); 1036148c5f43SAlan Wright } 1037148c5f43SAlan Wright 1038b819cea2SGordon Ross #ifdef _KERNEL 1039148c5f43SAlan Wright /* 1040148c5f43SAlan Wright * This is a special interface that will be utilized by ZFS to cause a share to 1041148c5f43SAlan Wright * be added/removed. 1042148c5f43SAlan Wright * 1043148c5f43SAlan Wright * arg is either a lmshare_info_t or share_name from userspace. 1044148c5f43SAlan Wright * It will need to be copied into the kernel. It is lmshare_info_t 1045148c5f43SAlan Wright * for add operations and share_name for delete operations. 1046148c5f43SAlan Wright */ 1047148c5f43SAlan Wright int 1048148c5f43SAlan Wright smb_server_share(void *arg, boolean_t add_share) 1049148c5f43SAlan Wright { 1050148c5f43SAlan Wright smb_server_t *sv; 1051148c5f43SAlan Wright int rc; 1052148c5f43SAlan Wright 1053148c5f43SAlan Wright if ((rc = smb_server_lookup(&sv)) == 0) { 1054148c5f43SAlan Wright mutex_enter(&sv->sv_mutex); 1055148c5f43SAlan Wright switch (sv->sv_state) { 1056148c5f43SAlan Wright case SMB_SERVER_STATE_RUNNING: 1057148c5f43SAlan Wright mutex_exit(&sv->sv_mutex); 1058148c5f43SAlan Wright (void) smb_kshare_upcall(sv->sv_lmshrd, arg, add_share); 1059148c5f43SAlan Wright break; 1060148c5f43SAlan Wright default: 1061148c5f43SAlan Wright mutex_exit(&sv->sv_mutex); 1062148c5f43SAlan Wright break; 1063148c5f43SAlan Wright } 1064148c5f43SAlan Wright smb_server_release(sv); 1065148c5f43SAlan Wright } 1066148c5f43SAlan Wright 1067148c5f43SAlan Wright return (rc); 1068148c5f43SAlan Wright } 1069b819cea2SGordon Ross #endif /* _KERNEL */ 1070148c5f43SAlan Wright 1071148c5f43SAlan Wright int 1072148c5f43SAlan Wright smb_server_unshare(const char *sharename) 1073148c5f43SAlan Wright { 1074148c5f43SAlan Wright smb_server_t *sv; 1075148c5f43SAlan Wright int rc; 1076148c5f43SAlan Wright 1077148c5f43SAlan Wright if ((rc = smb_server_lookup(&sv))) 1078148c5f43SAlan Wright return (rc); 1079148c5f43SAlan Wright 1080148c5f43SAlan Wright mutex_enter(&sv->sv_mutex); 1081148c5f43SAlan Wright switch (sv->sv_state) { 1082148c5f43SAlan Wright case SMB_SERVER_STATE_RUNNING: 1083148c5f43SAlan Wright case SMB_SERVER_STATE_STOPPING: 1084148c5f43SAlan Wright break; 1085148c5f43SAlan Wright default: 1086148c5f43SAlan Wright mutex_exit(&sv->sv_mutex); 1087148c5f43SAlan Wright smb_server_release(sv); 1088148c5f43SAlan Wright return (ENOTACTIVE); 1089148c5f43SAlan Wright } 1090148c5f43SAlan Wright mutex_exit(&sv->sv_mutex); 1091148c5f43SAlan Wright 10928d94f651SGordon Ross smb_server_disconnect_share(sv, sharename); 1093148c5f43SAlan Wright 1094148c5f43SAlan Wright smb_server_release(sv); 1095148c5f43SAlan Wright return (0); 1096148c5f43SAlan Wright } 1097148c5f43SAlan Wright 1098148c5f43SAlan Wright /* 10999fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States * Disconnect the specified share. 11009fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States * Typically called when a share has been removed. 1101faa1795aSjb150015 */ 11022c1b14e5Sjose borrego static void 11038d94f651SGordon Ross smb_server_disconnect_share(smb_server_t *sv, const char *sharename) 1104faa1795aSjb150015 { 11058d94f651SGordon Ross smb_llist_t *ll; 11069fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States smb_session_t *session; 11079fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 11088d94f651SGordon Ross ll = &sv->sv_session_list; 11094163af6aSjose borrego smb_llist_enter(ll, RW_READER); 11109fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 11114163af6aSjose borrego session = smb_llist_head(ll); 11129fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States while (session) { 11134163af6aSjose borrego SMB_SESSION_VALID(session); 11149fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States smb_rwx_rwenter(&session->s_lock, RW_READER); 11159fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States switch (session->s_state) { 11169fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States case SMB_SESSION_STATE_NEGOTIATED: 1117811599a4SMatt Barden smb_rwx_rwexit(&session->s_lock); 11189fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States smb_session_disconnect_share(session, sharename); 11199fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States break; 11209fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States default: 1121811599a4SMatt Barden smb_rwx_rwexit(&session->s_lock); 11229fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States break; 11239fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States } 11244163af6aSjose borrego session = smb_llist_next(ll, session); 11259fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States } 11269fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 11274163af6aSjose borrego smb_llist_exit(ll); 1128faa1795aSjb150015 } 1129faa1795aSjb150015 1130faa1795aSjb150015 /* 1131faa1795aSjb150015 * ***************************************************************************** 1132faa1795aSjb150015 * **************** Functions called from the internal layers ****************** 1133faa1795aSjb150015 * ***************************************************************************** 1134faa1795aSjb150015 * 1135faa1795aSjb150015 * These functions are provided the relevant smb server by the caller. 1136faa1795aSjb150015 */ 1137faa1795aSjb150015 1138faa1795aSjb150015 void 1139faa1795aSjb150015 smb_server_get_cfg(smb_server_t *sv, smb_kmod_cfg_t *cfg) 1140faa1795aSjb150015 { 1141faa1795aSjb150015 rw_enter(&sv->sv_cfg_lock, RW_READER); 1142faa1795aSjb150015 bcopy(&sv->sv_cfg, cfg, sizeof (*cfg)); 1143faa1795aSjb150015 rw_exit(&sv->sv_cfg_lock); 1144faa1795aSjb150015 } 1145faa1795aSjb150015 1146faa1795aSjb150015 /* 1147148c5f43SAlan Wright * 1148148c5f43SAlan Wright */ 1149148c5f43SAlan Wright void 1150148c5f43SAlan Wright smb_server_inc_nbt_sess(smb_server_t *sv) 1151148c5f43SAlan Wright { 1152148c5f43SAlan Wright SMB_SERVER_VALID(sv); 1153148c5f43SAlan Wright atomic_inc_32(&sv->sv_nbt_sess); 1154148c5f43SAlan Wright } 1155148c5f43SAlan Wright 1156148c5f43SAlan Wright void 1157148c5f43SAlan Wright smb_server_dec_nbt_sess(smb_server_t *sv) 1158148c5f43SAlan Wright { 1159148c5f43SAlan Wright SMB_SERVER_VALID(sv); 1160148c5f43SAlan Wright atomic_dec_32(&sv->sv_nbt_sess); 1161148c5f43SAlan Wright } 1162148c5f43SAlan Wright 1163148c5f43SAlan Wright void 1164148c5f43SAlan Wright smb_server_inc_tcp_sess(smb_server_t *sv) 1165148c5f43SAlan Wright { 1166148c5f43SAlan Wright SMB_SERVER_VALID(sv); 1167148c5f43SAlan Wright atomic_inc_32(&sv->sv_tcp_sess); 1168148c5f43SAlan Wright } 1169148c5f43SAlan Wright 1170148c5f43SAlan Wright void 1171148c5f43SAlan Wright smb_server_dec_tcp_sess(smb_server_t *sv) 1172148c5f43SAlan Wright { 1173148c5f43SAlan Wright SMB_SERVER_VALID(sv); 1174148c5f43SAlan Wright atomic_dec_32(&sv->sv_tcp_sess); 1175148c5f43SAlan Wright } 1176148c5f43SAlan Wright 1177148c5f43SAlan Wright void 1178148c5f43SAlan Wright smb_server_inc_users(smb_server_t *sv) 1179148c5f43SAlan Wright { 1180148c5f43SAlan Wright SMB_SERVER_VALID(sv); 1181148c5f43SAlan Wright atomic_inc_32(&sv->sv_users); 1182148c5f43SAlan Wright } 1183148c5f43SAlan Wright 1184148c5f43SAlan Wright void 1185148c5f43SAlan Wright smb_server_dec_users(smb_server_t *sv) 1186148c5f43SAlan Wright { 1187148c5f43SAlan Wright SMB_SERVER_VALID(sv); 1188148c5f43SAlan Wright atomic_dec_32(&sv->sv_users); 1189148c5f43SAlan Wright } 1190148c5f43SAlan Wright 1191148c5f43SAlan Wright void 1192148c5f43SAlan Wright smb_server_inc_trees(smb_server_t *sv) 1193148c5f43SAlan Wright { 1194148c5f43SAlan Wright SMB_SERVER_VALID(sv); 1195148c5f43SAlan Wright atomic_inc_32(&sv->sv_trees); 1196148c5f43SAlan Wright } 1197148c5f43SAlan Wright 1198148c5f43SAlan Wright void 1199148c5f43SAlan Wright smb_server_dec_trees(smb_server_t *sv) 1200148c5f43SAlan Wright { 1201148c5f43SAlan Wright SMB_SERVER_VALID(sv); 1202148c5f43SAlan Wright atomic_dec_32(&sv->sv_trees); 1203148c5f43SAlan Wright } 1204148c5f43SAlan Wright 1205148c5f43SAlan Wright void 1206148c5f43SAlan Wright smb_server_inc_files(smb_server_t *sv) 1207148c5f43SAlan Wright { 1208148c5f43SAlan Wright SMB_SERVER_VALID(sv); 1209148c5f43SAlan Wright atomic_inc_32(&sv->sv_files); 1210148c5f43SAlan Wright } 1211148c5f43SAlan Wright 1212148c5f43SAlan Wright void 1213148c5f43SAlan Wright smb_server_dec_files(smb_server_t *sv) 1214148c5f43SAlan Wright { 1215148c5f43SAlan Wright SMB_SERVER_VALID(sv); 1216148c5f43SAlan Wright atomic_dec_32(&sv->sv_files); 1217148c5f43SAlan Wright } 1218148c5f43SAlan Wright 1219148c5f43SAlan Wright void 1220148c5f43SAlan Wright smb_server_inc_pipes(smb_server_t *sv) 1221148c5f43SAlan Wright { 1222148c5f43SAlan Wright SMB_SERVER_VALID(sv); 1223148c5f43SAlan Wright atomic_inc_32(&sv->sv_pipes); 1224148c5f43SAlan Wright } 1225148c5f43SAlan Wright 1226148c5f43SAlan Wright void 1227148c5f43SAlan Wright smb_server_dec_pipes(smb_server_t *sv) 1228148c5f43SAlan Wright { 1229148c5f43SAlan Wright SMB_SERVER_VALID(sv); 1230148c5f43SAlan Wright atomic_dec_32(&sv->sv_pipes); 1231148c5f43SAlan Wright } 1232148c5f43SAlan Wright 1233148c5f43SAlan Wright void 1234148c5f43SAlan Wright smb_server_add_rxb(smb_server_t *sv, int64_t value) 1235148c5f43SAlan Wright { 1236148c5f43SAlan Wright SMB_SERVER_VALID(sv); 1237148c5f43SAlan Wright atomic_add_64(&sv->sv_rxb, value); 1238148c5f43SAlan Wright } 1239148c5f43SAlan Wright 1240148c5f43SAlan Wright void 1241148c5f43SAlan Wright smb_server_add_txb(smb_server_t *sv, int64_t value) 1242148c5f43SAlan Wright { 1243148c5f43SAlan Wright SMB_SERVER_VALID(sv); 1244148c5f43SAlan Wright atomic_add_64(&sv->sv_txb, value); 1245148c5f43SAlan Wright } 1246148c5f43SAlan Wright 1247148c5f43SAlan Wright void 1248148c5f43SAlan Wright smb_server_inc_req(smb_server_t *sv) 1249148c5f43SAlan Wright { 1250148c5f43SAlan Wright SMB_SERVER_VALID(sv); 1251148c5f43SAlan Wright atomic_inc_64(&sv->sv_nreq); 1252148c5f43SAlan Wright } 1253148c5f43SAlan Wright 1254148c5f43SAlan Wright /* 1255faa1795aSjb150015 * ***************************************************************************** 1256faa1795aSjb150015 * *************************** Static Functions ******************************** 1257faa1795aSjb150015 * ***************************************************************************** 1258faa1795aSjb150015 */ 1259faa1795aSjb150015 1260faa1795aSjb150015 static void 1261faa1795aSjb150015 smb_server_timers(smb_thread_t *thread, void *arg) 1262faa1795aSjb150015 { 1263faa1795aSjb150015 smb_server_t *sv = (smb_server_t *)arg; 1264faa1795aSjb150015 1265faa1795aSjb150015 ASSERT(sv != NULL); 1266faa1795aSjb150015 1267b819cea2SGordon Ross /* 1268811599a4SMatt Barden * This kills old inactive sessions and expired durable 1269811599a4SMatt Barden * handles. The session code expects one call per minute. 1270b819cea2SGordon Ross */ 1271b819cea2SGordon Ross while (smb_thread_continue_timedwait(thread, 60 /* Seconds */)) { 1272811599a4SMatt Barden if (sv->sv_cfg.skc_keepalive != 0) 1273811599a4SMatt Barden smb_session_timers(sv); 1274811599a4SMatt Barden smb2_durable_timers(sv); 1275faa1795aSjb150015 } 1276faa1795aSjb150015 } 1277faa1795aSjb150015 1278faa1795aSjb150015 /* 1279faa1795aSjb150015 * smb_server_kstat_init 1280faa1795aSjb150015 */ 1281148c5f43SAlan Wright static void 1282faa1795aSjb150015 smb_server_kstat_init(smb_server_t *sv) 1283faa1795aSjb150015 { 1284cb174861Sjoyce mcintosh 12858622ec45SGordon Ross sv->sv_ksp = kstat_create_zone(SMBSRV_KSTAT_MODULE, 0, 1286148c5f43SAlan Wright SMBSRV_KSTAT_STATISTICS, SMBSRV_KSTAT_CLASS, KSTAT_TYPE_RAW, 1287148c5f43SAlan Wright sizeof (smbsrv_kstats_t), 0, sv->sv_zid); 1288faa1795aSjb150015 1289148c5f43SAlan Wright if (sv->sv_ksp != NULL) { 1290148c5f43SAlan Wright sv->sv_ksp->ks_update = smb_server_kstat_update; 1291148c5f43SAlan Wright sv->sv_ksp->ks_private = sv; 1292148c5f43SAlan Wright ((smbsrv_kstats_t *)sv->sv_ksp->ks_data)->ks_start_time = 1293148c5f43SAlan Wright sv->sv_start_time; 12948622ec45SGordon Ross smb_dispatch_stats_init(sv); 1295a90cf9f2SGordon Ross smb2_dispatch_stats_init(sv); 1296faa1795aSjb150015 kstat_install(sv->sv_ksp); 1297148c5f43SAlan Wright } else { 1298148c5f43SAlan Wright cmn_err(CE_WARN, "SMB Server: Statistics unavailable"); 1299faa1795aSjb150015 } 1300cb174861Sjoyce mcintosh 13018622ec45SGordon Ross sv->sv_legacy_ksp = kstat_create_zone(SMBSRV_KSTAT_MODULE, 0, 13028622ec45SGordon Ross SMBSRV_KSTAT_NAME, SMBSRV_KSTAT_CLASS, KSTAT_TYPE_NAMED, 13038622ec45SGordon Ross sizeof (smb_server_legacy_kstat_t) / sizeof (kstat_named_t), 13048622ec45SGordon Ross 0, sv->sv_zid); 1305cb174861Sjoyce mcintosh 1306cb174861Sjoyce mcintosh if (sv->sv_legacy_ksp != NULL) { 1307cb174861Sjoyce mcintosh smb_server_legacy_kstat_t *ksd; 1308cb174861Sjoyce mcintosh 1309cb174861Sjoyce mcintosh ksd = sv->sv_legacy_ksp->ks_data; 1310cb174861Sjoyce mcintosh 1311cb174861Sjoyce mcintosh (void) strlcpy(ksd->ls_files.name, "open_files", 1312cb174861Sjoyce mcintosh sizeof (ksd->ls_files.name)); 1313cb174861Sjoyce mcintosh ksd->ls_files.data_type = KSTAT_DATA_UINT32; 1314cb174861Sjoyce mcintosh 1315cb174861Sjoyce mcintosh (void) strlcpy(ksd->ls_trees.name, "connections", 1316cb174861Sjoyce mcintosh sizeof (ksd->ls_trees.name)); 1317cb174861Sjoyce mcintosh ksd->ls_trees.data_type = KSTAT_DATA_UINT32; 1318cb174861Sjoyce mcintosh 1319cb174861Sjoyce mcintosh (void) strlcpy(ksd->ls_users.name, "connections", 1320cb174861Sjoyce mcintosh sizeof (ksd->ls_users.name)); 1321cb174861Sjoyce mcintosh ksd->ls_users.data_type = KSTAT_DATA_UINT32; 1322cb174861Sjoyce mcintosh 1323cb174861Sjoyce mcintosh mutex_init(&sv->sv_legacy_ksmtx, NULL, MUTEX_DEFAULT, NULL); 1324cb174861Sjoyce mcintosh sv->sv_legacy_ksp->ks_lock = &sv->sv_legacy_ksmtx; 1325cb174861Sjoyce mcintosh sv->sv_legacy_ksp->ks_update = smb_server_legacy_kstat_update; 1326cb174861Sjoyce mcintosh kstat_install(sv->sv_legacy_ksp); 1327cb174861Sjoyce mcintosh } 1328faa1795aSjb150015 } 1329faa1795aSjb150015 1330faa1795aSjb150015 /* 1331faa1795aSjb150015 * smb_server_kstat_fini 1332faa1795aSjb150015 */ 1333faa1795aSjb150015 static void 1334faa1795aSjb150015 smb_server_kstat_fini(smb_server_t *sv) 1335faa1795aSjb150015 { 1336cb174861Sjoyce mcintosh if (sv->sv_legacy_ksp != NULL) { 1337cb174861Sjoyce mcintosh kstat_delete(sv->sv_legacy_ksp); 1338cb174861Sjoyce mcintosh mutex_destroy(&sv->sv_legacy_ksmtx); 1339cb174861Sjoyce mcintosh sv->sv_legacy_ksp = NULL; 1340cb174861Sjoyce mcintosh } 1341cb174861Sjoyce mcintosh 1342148c5f43SAlan Wright if (sv->sv_ksp != NULL) { 1343faa1795aSjb150015 kstat_delete(sv->sv_ksp); 1344faa1795aSjb150015 sv->sv_ksp = NULL; 13458622ec45SGordon Ross smb_dispatch_stats_fini(sv); 1346a90cf9f2SGordon Ross smb2_dispatch_stats_fini(sv); 1347faa1795aSjb150015 } 1348faa1795aSjb150015 } 1349faa1795aSjb150015 1350148c5f43SAlan Wright /* 1351148c5f43SAlan Wright * smb_server_kstat_update 1352148c5f43SAlan Wright */ 1353faa1795aSjb150015 static int 1354148c5f43SAlan Wright smb_server_kstat_update(kstat_t *ksp, int rw) 1355faa1795aSjb150015 { 1356faa1795aSjb150015 smb_server_t *sv; 1357148c5f43SAlan Wright smbsrv_kstats_t *ksd; 1358faa1795aSjb150015 1359148c5f43SAlan Wright if (rw == KSTAT_READ) { 1360148c5f43SAlan Wright sv = ksp->ks_private; 13619fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States SMB_SERVER_VALID(sv); 1362148c5f43SAlan Wright ksd = (smbsrv_kstats_t *)ksp->ks_data; 1363148c5f43SAlan Wright /* 1364148c5f43SAlan Wright * Counters 1365148c5f43SAlan Wright */ 1366148c5f43SAlan Wright ksd->ks_nbt_sess = sv->sv_nbt_sess; 1367148c5f43SAlan Wright ksd->ks_tcp_sess = sv->sv_tcp_sess; 1368148c5f43SAlan Wright ksd->ks_users = sv->sv_users; 1369148c5f43SAlan Wright ksd->ks_trees = sv->sv_trees; 1370148c5f43SAlan Wright ksd->ks_files = sv->sv_files; 1371148c5f43SAlan Wright ksd->ks_pipes = sv->sv_pipes; 1372148c5f43SAlan Wright /* 1373148c5f43SAlan Wright * Throughput 1374148c5f43SAlan Wright */ 1375148c5f43SAlan Wright ksd->ks_txb = sv->sv_txb; 1376148c5f43SAlan Wright ksd->ks_rxb = sv->sv_rxb; 1377148c5f43SAlan Wright ksd->ks_nreq = sv->sv_nreq; 1378148c5f43SAlan Wright /* 1379148c5f43SAlan Wright * Busyness 1380148c5f43SAlan Wright */ 1381148c5f43SAlan Wright ksd->ks_maxreqs = sv->sv_cfg.skc_maxworkers; 1382148c5f43SAlan Wright smb_srqueue_update(&sv->sv_srqueue, 1383148c5f43SAlan Wright &ksd->ks_utilization); 1384148c5f43SAlan Wright /* 1385148c5f43SAlan Wright * Latency & Throughput of the requests 1386148c5f43SAlan Wright */ 1387a90cf9f2SGordon Ross smb_dispatch_stats_update(sv, ksd->ks_reqs1, 0, SMB_COM_NUM); 1388a90cf9f2SGordon Ross smb2_dispatch_stats_update(sv, ksd->ks_reqs2, 0, SMB2__NCMDS); 1389faa1795aSjb150015 return (0); 1390faa1795aSjb150015 } 1391148c5f43SAlan Wright if (rw == KSTAT_WRITE) 1392148c5f43SAlan Wright return (EACCES); 1393148c5f43SAlan Wright 1394148c5f43SAlan Wright return (EIO); 1395148c5f43SAlan Wright } 1396faa1795aSjb150015 1397cb174861Sjoyce mcintosh static int 1398cb174861Sjoyce mcintosh smb_server_legacy_kstat_update(kstat_t *ksp, int rw) 1399cb174861Sjoyce mcintosh { 1400cb174861Sjoyce mcintosh smb_server_t *sv; 1401cb174861Sjoyce mcintosh smb_server_legacy_kstat_t *ksd; 1402cb174861Sjoyce mcintosh int rc; 1403cb174861Sjoyce mcintosh 1404cb174861Sjoyce mcintosh switch (rw) { 1405cb174861Sjoyce mcintosh case KSTAT_WRITE: 1406cb174861Sjoyce mcintosh rc = EACCES; 1407cb174861Sjoyce mcintosh break; 1408cb174861Sjoyce mcintosh case KSTAT_READ: 1409cb174861Sjoyce mcintosh if (!smb_server_lookup(&sv)) { 1410cb174861Sjoyce mcintosh ASSERT(MUTEX_HELD(ksp->ks_lock)); 1411cb174861Sjoyce mcintosh ASSERT(sv->sv_legacy_ksp == ksp); 1412cb174861Sjoyce mcintosh ksd = (smb_server_legacy_kstat_t *)ksp->ks_data; 1413cb174861Sjoyce mcintosh ksd->ls_files.value.ui32 = sv->sv_files + sv->sv_pipes; 1414cb174861Sjoyce mcintosh ksd->ls_trees.value.ui32 = sv->sv_trees; 1415cb174861Sjoyce mcintosh ksd->ls_users.value.ui32 = sv->sv_users; 1416cb174861Sjoyce mcintosh smb_server_release(sv); 1417cb174861Sjoyce mcintosh rc = 0; 1418cb174861Sjoyce mcintosh break; 1419cb174861Sjoyce mcintosh } 14202d63d7e2SToomas Soome /* FALLTHROUGH */ 1421cb174861Sjoyce mcintosh default: 1422cb174861Sjoyce mcintosh rc = EIO; 1423cb174861Sjoyce mcintosh break; 1424cb174861Sjoyce mcintosh } 1425cb174861Sjoyce mcintosh return (rc); 1426cb174861Sjoyce mcintosh 1427cb174861Sjoyce mcintosh } 1428cb174861Sjoyce mcintosh 1429faa1795aSjb150015 /* 14304163af6aSjose borrego * smb_server_shutdown 1431faa1795aSjb150015 */ 1432faa1795aSjb150015 static void 14339fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States smb_server_shutdown(smb_server_t *sv) 1434faa1795aSjb150015 { 1435811599a4SMatt Barden smb_llist_t *sl = &sv->sv_session_list; 1436811599a4SMatt Barden smb_session_t *session; 1437811599a4SMatt Barden clock_t time; 1438811599a4SMatt Barden 14399fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States SMB_SERVER_VALID(sv); 1440faa1795aSjb150015 1441856399cfSGordon Ross /* 1442856399cfSGordon Ross * Stop the listeners first, so we don't get any more 1443856399cfSGordon Ross * new work while we're trying to shut down. 1444856399cfSGordon Ross */ 1445856399cfSGordon Ross smb_server_listener_stop(&sv->sv_nbt_daemon); 1446856399cfSGordon Ross smb_server_listener_stop(&sv->sv_tcp_daemon); 1447faa1795aSjb150015 smb_thread_stop(&sv->si_thread_timers); 1448856399cfSGordon Ross 1449811599a4SMatt Barden /* Disconnect all of the sessions */ 1450811599a4SMatt Barden smb_llist_enter(sl, RW_READER); 1451811599a4SMatt Barden session = smb_llist_head(sl); 1452811599a4SMatt Barden while (session != NULL) { 1453811599a4SMatt Barden smb_session_disconnect(session); 1454811599a4SMatt Barden session = smb_llist_next(sl, session); 1455811599a4SMatt Barden } 1456811599a4SMatt Barden smb_llist_exit(sl); 1457811599a4SMatt Barden 1458856399cfSGordon Ross /* 1459856399cfSGordon Ross * Wake up any threads we might have blocked. 1460856399cfSGordon Ross * Must precede kdoor_close etc. because those will 1461856399cfSGordon Ross * wait for such threads to get out. 1462856399cfSGordon Ross */ 1463856399cfSGordon Ross smb_event_cancel(sv, 0); 1464856399cfSGordon Ross smb_threshold_wake_all(&sv->sv_ssetup_ct); 1465856399cfSGordon Ross smb_threshold_wake_all(&sv->sv_tcon_ct); 1466856399cfSGordon Ross smb_threshold_wake_all(&sv->sv_opipe_ct); 1467856399cfSGordon Ross 1468811599a4SMatt Barden /* 1469811599a4SMatt Barden * Wait for the session list to empty. 1470811599a4SMatt Barden * (cv_signal in smb_server_destroy_session) 1471811599a4SMatt Barden * 1472811599a4SMatt Barden * This should not take long, but if there are any leaked 1473811599a4SMatt Barden * references to ofiles, trees, or users, there could be a 1474811599a4SMatt Barden * session hanging around. If that happens, the ll_count 1475811599a4SMatt Barden * never gets to zero and we'll never get the sv_signal. 1476811599a4SMatt Barden * Defend against that problem using timed wait, then 1477811599a4SMatt Barden * complain if we find sessions left over and continue 1478811599a4SMatt Barden * with shutdown in spite of any leaked sessions. 1479811599a4SMatt Barden * That's better than a server that won't reboot. 1480811599a4SMatt Barden */ 1481*7f5d80fdSGordon Ross time = SEC_TO_TICK(5) + ddi_get_lbolt(); 1482811599a4SMatt Barden mutex_enter(&sv->sv_mutex); 1483811599a4SMatt Barden while (sv->sv_session_list.ll_count != 0) { 1484811599a4SMatt Barden if (cv_timedwait(&sv->sv_cv, &sv->sv_mutex, time) < 0) 1485811599a4SMatt Barden break; 1486811599a4SMatt Barden } 1487811599a4SMatt Barden mutex_exit(&sv->sv_mutex); 1488811599a4SMatt Barden #ifdef DEBUG 1489811599a4SMatt Barden if (sv->sv_session_list.ll_count != 0) { 1490811599a4SMatt Barden cmn_err(CE_NOTE, "shutdown leaked sessions"); 1491811599a4SMatt Barden debug_enter("shutdown leaked sessions"); 1492811599a4SMatt Barden } 1493811599a4SMatt Barden #endif 1494811599a4SMatt Barden 1495811599a4SMatt Barden /* 1496811599a4SMatt Barden * Clean out any durable handles. After this we should 1497811599a4SMatt Barden * have no ofiles remaining (and no more oplock breaks). 1498811599a4SMatt Barden */ 1499811599a4SMatt Barden smb2_dh_shutdown(sv); 1500811599a4SMatt Barden 15018622ec45SGordon Ross smb_kdoor_close(sv); 1502b819cea2SGordon Ross #ifdef _KERNEL 1503148c5f43SAlan Wright smb_kshare_door_fini(sv->sv_lmshrd); 1504b819cea2SGordon Ross #endif /* _KERNEL */ 15050dcb3379Sjb150015 sv->sv_lmshrd = NULL; 1506b819cea2SGordon Ross 15078622ec45SGordon Ross smb_export_stop(sv); 1508811599a4SMatt Barden smb_kshare_stop(sv); 15098d96b23eSAlan Wright 15104846df9bSKevin Crowe /* 1511811599a4SMatt Barden * Both kshare and the oplock break sub-systems may have 1512811599a4SMatt Barden * taskq jobs on the spcial "server" session, until we've 1513811599a4SMatt Barden * closed all ofiles and stopped the kshare exporter. 1514811599a4SMatt Barden * Now it's safe to destroy the server session, but first 1515811599a4SMatt Barden * wait for any requests on it to finish. Note that for 1516811599a4SMatt Barden * normal sessions, this happens in smb_session_cancel, 1517811599a4SMatt Barden * but that's not called for the server session. 15184846df9bSKevin Crowe */ 15198d94f651SGordon Ross if (sv->sv_rootuser != NULL) { 15208d94f651SGordon Ross smb_user_logoff(sv->sv_rootuser); 15218d94f651SGordon Ross smb_user_release(sv->sv_rootuser); 15228d94f651SGordon Ross sv->sv_rootuser = NULL; 15238d94f651SGordon Ross } 1524811599a4SMatt Barden if (sv->sv_session != NULL) { 1525525641e8SGordon Ross smb_session_cancel_requests(sv->sv_session, NULL, NULL); 15264846df9bSKevin Crowe smb_slist_wait_for_empty(&sv->sv_session->s_req_list); 15274846df9bSKevin Crowe 15288d94f651SGordon Ross /* Just in case import left users and trees */ 15298d94f651SGordon Ross smb_session_logoff(sv->sv_session); 15308d94f651SGordon Ross 1531faa1795aSjb150015 smb_session_delete(sv->sv_session); 1532faa1795aSjb150015 sv->sv_session = NULL; 1533faa1795aSjb150015 } 15348d96b23eSAlan Wright 15354163af6aSjose borrego if (sv->sv_receiver_pool != NULL) { 15364163af6aSjose borrego taskq_destroy(sv->sv_receiver_pool); 15374163af6aSjose borrego sv->sv_receiver_pool = NULL; 15384163af6aSjose borrego } 15394163af6aSjose borrego 15404163af6aSjose borrego if (sv->sv_worker_pool != NULL) { 15414163af6aSjose borrego taskq_destroy(sv->sv_worker_pool); 15424163af6aSjose borrego sv->sv_worker_pool = NULL; 15438d96b23eSAlan Wright } 15448622ec45SGordon Ross 15458622ec45SGordon Ross smb_server_fsop_stop(sv); 1546faa1795aSjb150015 } 1547faa1795aSjb150015 15484163af6aSjose borrego /* 15494163af6aSjose borrego * smb_server_listener_init 15504163af6aSjose borrego * 15514163af6aSjose borrego * Initializes listener contexts. 15524163af6aSjose borrego */ 15534163af6aSjose borrego static void 15544163af6aSjose borrego smb_server_listener_init( 1555faa1795aSjb150015 smb_server_t *sv, 1556faa1795aSjb150015 smb_listener_daemon_t *ld, 15574163af6aSjose borrego char *name, 1558faa1795aSjb150015 in_port_t port, 15594163af6aSjose borrego int family) 1560faa1795aSjb150015 { 15614163af6aSjose borrego ASSERT(ld->ld_magic != SMB_LISTENER_MAGIC); 1562faa1795aSjb150015 15634163af6aSjose borrego bzero(ld, sizeof (*ld)); 1564faa1795aSjb150015 15654163af6aSjose borrego ld->ld_sv = sv; 15664163af6aSjose borrego ld->ld_family = family; 15674163af6aSjose borrego ld->ld_port = port; 15684163af6aSjose borrego 15697f667e74Sjose borrego if (family == AF_INET) { 15707f667e74Sjose borrego ld->ld_sin.sin_family = (uint32_t)family; 1571faa1795aSjb150015 ld->ld_sin.sin_port = htons(port); 1572faa1795aSjb150015 ld->ld_sin.sin_addr.s_addr = htonl(INADDR_ANY); 15737f667e74Sjose borrego } else { 15747f667e74Sjose borrego ld->ld_sin6.sin6_family = (uint32_t)family; 15757f667e74Sjose borrego ld->ld_sin6.sin6_port = htons(port); 15767f667e74Sjose borrego (void) memset(&ld->ld_sin6.sin6_addr.s6_addr, 0, 15777f667e74Sjose borrego sizeof (ld->ld_sin6.sin6_addr.s6_addr)); 15787f667e74Sjose borrego } 1579faa1795aSjb150015 158008344b29SGordon Ross smb_thread_init(&ld->ld_thread, name, smb_server_listener, ld, 158108344b29SGordon Ross smbsrv_listen_pri); 15824163af6aSjose borrego ld->ld_magic = SMB_LISTENER_MAGIC; 15834163af6aSjose borrego } 15844163af6aSjose borrego 15854163af6aSjose borrego /* 15864163af6aSjose borrego * smb_server_listener_destroy 15874163af6aSjose borrego * 15884163af6aSjose borrego * Destroyes listener contexts. 15894163af6aSjose borrego */ 15904163af6aSjose borrego static void 15914163af6aSjose borrego smb_server_listener_destroy(smb_listener_daemon_t *ld) 15924163af6aSjose borrego { 159383d2dfe6SGordon Ross /* 159483d2dfe6SGordon Ross * Note that if startup fails early, we can legitimately 159583d2dfe6SGordon Ross * get here with an all-zeros object. 159683d2dfe6SGordon Ross */ 159783d2dfe6SGordon Ross if (ld->ld_magic == 0) 159883d2dfe6SGordon Ross return; 159983d2dfe6SGordon Ross 16004163af6aSjose borrego SMB_LISTENER_VALID(ld); 16014163af6aSjose borrego ASSERT(ld->ld_so == NULL); 16024163af6aSjose borrego smb_thread_destroy(&ld->ld_thread); 16034163af6aSjose borrego ld->ld_magic = 0; 16044163af6aSjose borrego } 16054163af6aSjose borrego 16064163af6aSjose borrego /* 16074163af6aSjose borrego * smb_server_listener_start 16084163af6aSjose borrego * 16094163af6aSjose borrego * Starts the listener associated with the context passed in. 16104163af6aSjose borrego * 16114163af6aSjose borrego * Return: 0 Success 16124163af6aSjose borrego * not 0 Failure 16134163af6aSjose borrego */ 16144163af6aSjose borrego static int 16154163af6aSjose borrego smb_server_listener_start(smb_listener_daemon_t *ld) 16164163af6aSjose borrego { 16174163af6aSjose borrego int rc; 16184163af6aSjose borrego uint32_t on; 16194163af6aSjose borrego uint32_t off; 16204163af6aSjose borrego 16214163af6aSjose borrego SMB_LISTENER_VALID(ld); 16224163af6aSjose borrego 16234163af6aSjose borrego if (ld->ld_so != NULL) 16244163af6aSjose borrego return (EINVAL); 16254163af6aSjose borrego 16264163af6aSjose borrego ld->ld_so = smb_socreate(ld->ld_family, SOCK_STREAM, 0); 16279fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States if (ld->ld_so == NULL) { 16284163af6aSjose borrego cmn_err(CE_WARN, "port %d: socket create failed", ld->ld_port); 16299fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States return (ENOMEM); 16309fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States } 16319fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 16329fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States off = 0; 16330f1702c5SYu Xiangning (void) ksocket_setsockopt(ld->ld_so, SOL_SOCKET, 1634fc724630SAlan Wright SO_MAC_EXEMPT, &off, sizeof (off), CRED()); 16359fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 16369fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States on = 1; 1637fc724630SAlan Wright (void) ksocket_setsockopt(ld->ld_so, SOL_SOCKET, 1638fc724630SAlan Wright SO_REUSEADDR, &on, sizeof (on), CRED()); 1639fc724630SAlan Wright 16404163af6aSjose borrego if (ld->ld_family == AF_INET) { 16410f1702c5SYu Xiangning rc = ksocket_bind(ld->ld_so, 16420f1702c5SYu Xiangning (struct sockaddr *)&ld->ld_sin, 16430f1702c5SYu Xiangning sizeof (ld->ld_sin), CRED()); 16447f667e74Sjose borrego } else { 16457f667e74Sjose borrego rc = ksocket_bind(ld->ld_so, 16467f667e74Sjose borrego (struct sockaddr *)&ld->ld_sin6, 16477f667e74Sjose borrego sizeof (ld->ld_sin6), CRED()); 16487f667e74Sjose borrego } 16499fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 16509fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States if (rc != 0) { 16514163af6aSjose borrego cmn_err(CE_WARN, "port %d: bind failed", ld->ld_port); 16529fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States return (rc); 16539fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States } 16549fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 16550f1702c5SYu Xiangning rc = ksocket_listen(ld->ld_so, 20, CRED()); 1656faa1795aSjb150015 if (rc < 0) { 16574163af6aSjose borrego cmn_err(CE_WARN, "port %d: listen failed", ld->ld_port); 1658faa1795aSjb150015 return (rc); 1659faa1795aSjb150015 } 16604163af6aSjose borrego 16614163af6aSjose borrego ksocket_hold(ld->ld_so); 16624163af6aSjose borrego rc = smb_thread_start(&ld->ld_thread); 16634163af6aSjose borrego if (rc != 0) { 16644163af6aSjose borrego ksocket_rele(ld->ld_so); 16654163af6aSjose borrego cmn_err(CE_WARN, "port %d: listener failed to start", 16664163af6aSjose borrego ld->ld_port); 16674163af6aSjose borrego return (rc); 1668faa1795aSjb150015 } 16694163af6aSjose borrego return (0); 16704163af6aSjose borrego } 16714163af6aSjose borrego 16724163af6aSjose borrego /* 16734163af6aSjose borrego * smb_server_listener_stop 16744163af6aSjose borrego * 16754163af6aSjose borrego * Stops the listener associated with the context passed in. 16764163af6aSjose borrego */ 16774163af6aSjose borrego static void 16784163af6aSjose borrego smb_server_listener_stop(smb_listener_daemon_t *ld) 16794163af6aSjose borrego { 16804163af6aSjose borrego SMB_LISTENER_VALID(ld); 16814163af6aSjose borrego 16824163af6aSjose borrego if (ld->ld_so != NULL) { 16834163af6aSjose borrego smb_soshutdown(ld->ld_so); 16844163af6aSjose borrego smb_sodestroy(ld->ld_so); 16854163af6aSjose borrego smb_thread_stop(&ld->ld_thread); 16864163af6aSjose borrego ld->ld_so = NULL; 16874163af6aSjose borrego } 16884163af6aSjose borrego } 16894163af6aSjose borrego 16904163af6aSjose borrego /* 16914163af6aSjose borrego * smb_server_listener 16924163af6aSjose borrego * 16934163af6aSjose borrego * Entry point of the listeners. 16944163af6aSjose borrego */ 16954163af6aSjose borrego static void 16964163af6aSjose borrego smb_server_listener(smb_thread_t *thread, void *arg) 16974163af6aSjose borrego { 16984163af6aSjose borrego _NOTE(ARGUNUSED(thread)) 16994163af6aSjose borrego smb_listener_daemon_t *ld; 17004163af6aSjose borrego ksocket_t s_so; 17014163af6aSjose borrego int on; 17024163af6aSjose borrego int txbuf_size; 17034163af6aSjose borrego 17044163af6aSjose borrego ld = (smb_listener_daemon_t *)arg; 17054163af6aSjose borrego 17064163af6aSjose borrego SMB_LISTENER_VALID(ld); 1707faa1795aSjb150015 1708faa1795aSjb150015 DTRACE_PROBE1(so__wait__accept, struct sonode *, ld->ld_so); 1709faa1795aSjb150015 171041bd8510Skcrowenex for (;;) { 171141bd8510Skcrowenex int ret = ksocket_accept(ld->ld_so, NULL, NULL, &s_so, CRED()); 171241bd8510Skcrowenex 171341bd8510Skcrowenex switch (ret) { 171441bd8510Skcrowenex case 0: 171541bd8510Skcrowenex break; 171641bd8510Skcrowenex case ECONNABORTED: 171741bd8510Skcrowenex continue; 171841bd8510Skcrowenex case EINTR: 171941bd8510Skcrowenex case EBADF: /* libfakekernel */ 172041bd8510Skcrowenex goto out; 172141bd8510Skcrowenex default: 172241bd8510Skcrowenex cmn_err(CE_WARN, 172341bd8510Skcrowenex "smb_server_listener: ksocket_accept(%d)", 172441bd8510Skcrowenex ret); 172541bd8510Skcrowenex goto out; 172641bd8510Skcrowenex } 172741bd8510Skcrowenex 1728faa1795aSjb150015 DTRACE_PROBE1(so__accept, struct sonode *, s_so); 1729faa1795aSjb150015 17309fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States on = 1; 17319fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States (void) ksocket_setsockopt(s_so, IPPROTO_TCP, TCP_NODELAY, 17329fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States &on, sizeof (on), CRED()); 17339fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 17349fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States on = 1; 17359fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States (void) ksocket_setsockopt(s_so, SOL_SOCKET, SO_KEEPALIVE, 17369fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States &on, sizeof (on), CRED()); 17379fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 17389fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States txbuf_size = 128*1024; 17390f1702c5SYu Xiangning (void) ksocket_setsockopt(s_so, SOL_SOCKET, SO_SNDBUF, 17409fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States (const void *)&txbuf_size, sizeof (txbuf_size), CRED()); 17419fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 1742faa1795aSjb150015 /* 1743faa1795aSjb150015 * Create a session for this connection. 1744faa1795aSjb150015 */ 17454163af6aSjose borrego smb_server_create_session(ld, s_so); 1746faa1795aSjb150015 } 174741bd8510Skcrowenex out: 17484163af6aSjose borrego ksocket_rele(ld->ld_so); 1749faa1795aSjb150015 } 17509fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 17514163af6aSjose borrego /* 17524163af6aSjose borrego * smb_server_receiver 17534163af6aSjose borrego * 17544163af6aSjose borrego * Entry point of the receiver threads. 1755811599a4SMatt Barden * Also does cleanup when socket disconnected. 17564163af6aSjose borrego */ 17579fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States static void 17584163af6aSjose borrego smb_server_receiver(void *arg) 17599fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States { 17604163af6aSjose borrego smb_session_t *session; 1761faa1795aSjb150015 1762811599a4SMatt Barden session = (smb_session_t *)arg; 1763811599a4SMatt Barden 1764811599a4SMatt Barden /* We stay in here until socket disconnect. */ 17654163af6aSjose borrego smb_session_receiver(session); 1766811599a4SMatt Barden 1767811599a4SMatt Barden smb_server_destroy_session(session); 1768faa1795aSjb150015 } 1769faa1795aSjb150015 1770faa1795aSjb150015 /* 1771faa1795aSjb150015 * smb_server_lookup 1772faa1795aSjb150015 * 17738622ec45SGordon Ross * This function finds the server associated with the zone of the 17748622ec45SGordon Ross * caller. Note: requires a fix in the dynamic taskq code: 17758622ec45SGordon Ross * 1501 taskq_create_proc ... TQ_DYNAMIC puts tasks in p0 1776faa1795aSjb150015 */ 17774846df9bSKevin Crowe int 1778faa1795aSjb150015 smb_server_lookup(smb_server_t **psv) 1779faa1795aSjb150015 { 1780faa1795aSjb150015 zoneid_t zid; 1781faa1795aSjb150015 smb_server_t *sv; 1782faa1795aSjb150015 1783faa1795aSjb150015 zid = getzoneid(); 1784faa1795aSjb150015 1785faa1795aSjb150015 smb_llist_enter(&smb_servers, RW_READER); 1786faa1795aSjb150015 sv = smb_llist_head(&smb_servers); 1787faa1795aSjb150015 while (sv) { 17889fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States SMB_SERVER_VALID(sv); 1789faa1795aSjb150015 if (sv->sv_zid == zid) { 1790faa1795aSjb150015 mutex_enter(&sv->sv_mutex); 1791faa1795aSjb150015 if (sv->sv_state != SMB_SERVER_STATE_DELETING) { 1792faa1795aSjb150015 sv->sv_refcnt++; 1793faa1795aSjb150015 mutex_exit(&sv->sv_mutex); 1794faa1795aSjb150015 smb_llist_exit(&smb_servers); 1795faa1795aSjb150015 *psv = sv; 1796faa1795aSjb150015 return (0); 1797faa1795aSjb150015 } 1798faa1795aSjb150015 mutex_exit(&sv->sv_mutex); 1799faa1795aSjb150015 break; 1800faa1795aSjb150015 } 1801faa1795aSjb150015 sv = smb_llist_next(&smb_servers, sv); 1802faa1795aSjb150015 } 1803faa1795aSjb150015 smb_llist_exit(&smb_servers); 1804faa1795aSjb150015 return (EPERM); 1805faa1795aSjb150015 } 1806faa1795aSjb150015 1807faa1795aSjb150015 /* 1808faa1795aSjb150015 * smb_server_release 1809faa1795aSjb150015 * 1810faa1795aSjb150015 * This function decrements the reference count of the server and signals its 1811faa1795aSjb150015 * condition variable if the state of the server is SMB_SERVER_STATE_DELETING. 1812faa1795aSjb150015 */ 18134846df9bSKevin Crowe void 1814faa1795aSjb150015 smb_server_release(smb_server_t *sv) 1815faa1795aSjb150015 { 18169fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States SMB_SERVER_VALID(sv); 1817faa1795aSjb150015 1818faa1795aSjb150015 mutex_enter(&sv->sv_mutex); 1819faa1795aSjb150015 ASSERT(sv->sv_refcnt); 1820faa1795aSjb150015 sv->sv_refcnt--; 1821faa1795aSjb150015 if ((sv->sv_refcnt == 0) && (sv->sv_state == SMB_SERVER_STATE_DELETING)) 1822faa1795aSjb150015 cv_signal(&sv->sv_cv); 1823faa1795aSjb150015 mutex_exit(&sv->sv_mutex); 1824faa1795aSjb150015 } 1825faa1795aSjb150015 18261fcced4cSJordan Brown /* 18271fcced4cSJordan Brown * Enumerate the users associated with a session list. 18281fcced4cSJordan Brown */ 18291fcced4cSJordan Brown static void 18308d94f651SGordon Ross smb_server_enum_users(smb_server_t *sv, smb_svcenum_t *svcenum) 1831faa1795aSjb150015 { 18328d94f651SGordon Ross smb_llist_t *ll = &sv->sv_session_list; 18331fcced4cSJordan Brown smb_session_t *sn; 1834faa1795aSjb150015 smb_llist_t *ulist; 18351fcced4cSJordan Brown smb_user_t *user; 183629bd2886SAlan Wright int rc = 0; 1837faa1795aSjb150015 18384163af6aSjose borrego smb_llist_enter(ll, RW_READER); 18394163af6aSjose borrego sn = smb_llist_head(ll); 18401fcced4cSJordan Brown 18411fcced4cSJordan Brown while (sn != NULL) { 18424163af6aSjose borrego SMB_SESSION_VALID(sn); 1843faa1795aSjb150015 ulist = &sn->s_user_list; 1844faa1795aSjb150015 smb_llist_enter(ulist, RW_READER); 1845faa1795aSjb150015 user = smb_llist_head(ulist); 18461fcced4cSJordan Brown 18471fcced4cSJordan Brown while (user != NULL) { 18481fcced4cSJordan Brown if (smb_user_hold(user)) { 18491fcced4cSJordan Brown rc = smb_user_enum(user, svcenum); 18501fcced4cSJordan Brown smb_user_release(user); 18513b13a1efSThomas Keiser if (rc != 0) 18523b13a1efSThomas Keiser break; 1853faa1795aSjb150015 } 18541fcced4cSJordan Brown 1855faa1795aSjb150015 user = smb_llist_next(ulist, user); 1856faa1795aSjb150015 } 18571fcced4cSJordan Brown 18581fcced4cSJordan Brown smb_llist_exit(ulist); 18591fcced4cSJordan Brown 18601fcced4cSJordan Brown if (rc != 0) 18611fcced4cSJordan Brown break; 18621fcced4cSJordan Brown 18634163af6aSjose borrego sn = smb_llist_next(ll, sn); 18641fcced4cSJordan Brown } 18651fcced4cSJordan Brown 18664163af6aSjose borrego smb_llist_exit(ll); 18671fcced4cSJordan Brown } 18681fcced4cSJordan Brown 18691fcced4cSJordan Brown /* 18703b13a1efSThomas Keiser * Enumerate the trees/files associated with a session list. 18713b13a1efSThomas Keiser */ 18723b13a1efSThomas Keiser static void 18738d94f651SGordon Ross smb_server_enum_trees(smb_server_t *sv, smb_svcenum_t *svcenum) 18743b13a1efSThomas Keiser { 18758d94f651SGordon Ross smb_llist_t *ll = &sv->sv_session_list; 18763b13a1efSThomas Keiser smb_session_t *sn; 18773b13a1efSThomas Keiser smb_llist_t *tlist; 18783b13a1efSThomas Keiser smb_tree_t *tree; 18793b13a1efSThomas Keiser int rc = 0; 18803b13a1efSThomas Keiser 18813b13a1efSThomas Keiser smb_llist_enter(ll, RW_READER); 18823b13a1efSThomas Keiser sn = smb_llist_head(ll); 18833b13a1efSThomas Keiser 18843b13a1efSThomas Keiser while (sn != NULL) { 18853b13a1efSThomas Keiser SMB_SESSION_VALID(sn); 18863b13a1efSThomas Keiser tlist = &sn->s_tree_list; 18873b13a1efSThomas Keiser smb_llist_enter(tlist, RW_READER); 18883b13a1efSThomas Keiser tree = smb_llist_head(tlist); 18893b13a1efSThomas Keiser 18903b13a1efSThomas Keiser while (tree != NULL) { 18913b13a1efSThomas Keiser if (smb_tree_hold(tree)) { 18923b13a1efSThomas Keiser rc = smb_tree_enum(tree, svcenum); 18933b13a1efSThomas Keiser smb_tree_release(tree); 18943b13a1efSThomas Keiser if (rc != 0) 18953b13a1efSThomas Keiser break; 18963b13a1efSThomas Keiser } 18973b13a1efSThomas Keiser 18983b13a1efSThomas Keiser tree = smb_llist_next(tlist, tree); 18993b13a1efSThomas Keiser } 19003b13a1efSThomas Keiser 19013b13a1efSThomas Keiser smb_llist_exit(tlist); 19023b13a1efSThomas Keiser 19033b13a1efSThomas Keiser if (rc != 0) 19043b13a1efSThomas Keiser break; 19053b13a1efSThomas Keiser 19063b13a1efSThomas Keiser sn = smb_llist_next(ll, sn); 19073b13a1efSThomas Keiser } 19083b13a1efSThomas Keiser 19093b13a1efSThomas Keiser smb_llist_exit(ll); 19103b13a1efSThomas Keiser } 19113b13a1efSThomas Keiser 19123b13a1efSThomas Keiser /* 19131fcced4cSJordan Brown * Disconnect sessions associated with the specified client and username. 19141fcced4cSJordan Brown * Empty strings are treated as wildcards. 19151fcced4cSJordan Brown */ 19161fcced4cSJordan Brown static int 19178d94f651SGordon Ross smb_server_session_disconnect(smb_server_t *sv, 19181fcced4cSJordan Brown const char *client, const char *name) 19191fcced4cSJordan Brown { 19208d94f651SGordon Ross smb_llist_t *ll = &sv->sv_session_list; 19211fcced4cSJordan Brown smb_session_t *sn; 19221fcced4cSJordan Brown smb_llist_t *ulist; 19231fcced4cSJordan Brown smb_user_t *user; 19241fcced4cSJordan Brown int count = 0; 19251fcced4cSJordan Brown 19264163af6aSjose borrego smb_llist_enter(ll, RW_READER); 19271fcced4cSJordan Brown 1928811599a4SMatt Barden for (sn = smb_llist_head(ll); 1929811599a4SMatt Barden sn != NULL; 1930811599a4SMatt Barden sn = smb_llist_next(ll, sn)) { 19314163af6aSjose borrego SMB_SESSION_VALID(sn); 19321fcced4cSJordan Brown 1933811599a4SMatt Barden if (*client != '\0' && !smb_session_isclient(sn, client)) 19341fcced4cSJordan Brown continue; 19351fcced4cSJordan Brown 19361fcced4cSJordan Brown ulist = &sn->s_user_list; 19371fcced4cSJordan Brown smb_llist_enter(ulist, RW_READER); 19381fcced4cSJordan Brown 1939811599a4SMatt Barden for (user = smb_llist_head(ulist); 1940811599a4SMatt Barden user != NULL; 1941811599a4SMatt Barden user = smb_llist_next(ulist, user)) { 19421fcced4cSJordan Brown 1943811599a4SMatt Barden if (smb_user_hold(user)) { 1944896d9552SGordon Ross 1945896d9552SGordon Ross if (*name == '\0' || 1946896d9552SGordon Ross smb_user_namecmp(user, name)) { 1947811599a4SMatt Barden smb_user_logoff(user); 1948811599a4SMatt Barden count++; 19491fcced4cSJordan Brown } 1950896d9552SGordon Ross 1951896d9552SGordon Ross smb_user_release(user); 1952896d9552SGordon Ross } 19531fcced4cSJordan Brown } 19541fcced4cSJordan Brown 1955faa1795aSjb150015 smb_llist_exit(ulist); 1956faa1795aSjb150015 } 19571fcced4cSJordan Brown 19584163af6aSjose borrego smb_llist_exit(ll); 19591fcced4cSJordan Brown return (count); 19601fcced4cSJordan Brown } 19611fcced4cSJordan Brown 19621fcced4cSJordan Brown /* 19631fcced4cSJordan Brown * Close a file by its unique id. 19641fcced4cSJordan Brown */ 19651fcced4cSJordan Brown static int 19668d94f651SGordon Ross smb_server_fclose(smb_server_t *sv, uint32_t uniqid) 19671fcced4cSJordan Brown { 19688d94f651SGordon Ross smb_llist_t *ll; 19691fcced4cSJordan Brown smb_session_t *sn; 19703b13a1efSThomas Keiser smb_llist_t *tlist; 19713b13a1efSThomas Keiser smb_tree_t *tree; 19721fcced4cSJordan Brown int rc = ENOENT; 19731fcced4cSJordan Brown 19748d94f651SGordon Ross ll = &sv->sv_session_list; 19754163af6aSjose borrego smb_llist_enter(ll, RW_READER); 19764163af6aSjose borrego sn = smb_llist_head(ll); 19771fcced4cSJordan Brown 19781fcced4cSJordan Brown while ((sn != NULL) && (rc == ENOENT)) { 19794163af6aSjose borrego SMB_SESSION_VALID(sn); 19803b13a1efSThomas Keiser tlist = &sn->s_tree_list; 19813b13a1efSThomas Keiser smb_llist_enter(tlist, RW_READER); 19823b13a1efSThomas Keiser tree = smb_llist_head(tlist); 19831fcced4cSJordan Brown 19843b13a1efSThomas Keiser while ((tree != NULL) && (rc == ENOENT)) { 19853b13a1efSThomas Keiser if (smb_tree_hold(tree)) { 19863b13a1efSThomas Keiser rc = smb_tree_fclose(tree, uniqid); 19873b13a1efSThomas Keiser smb_tree_release(tree); 19881fcced4cSJordan Brown } 19891fcced4cSJordan Brown 19903b13a1efSThomas Keiser tree = smb_llist_next(tlist, tree); 19911fcced4cSJordan Brown } 19921fcced4cSJordan Brown 19933b13a1efSThomas Keiser smb_llist_exit(tlist); 19944163af6aSjose borrego sn = smb_llist_next(ll, sn); 19951fcced4cSJordan Brown } 19961fcced4cSJordan Brown 19974163af6aSjose borrego smb_llist_exit(ll); 19981fcced4cSJordan Brown return (rc); 1999faa1795aSjb150015 } 2000faa1795aSjb150015 2001811599a4SMatt Barden /* 2002811599a4SMatt Barden * This is used by SMB2 session setup to logoff a previous session, 2003811599a4SMatt Barden * so it can force a logoff that we haven't noticed yet. 2004811599a4SMatt Barden * This is not called frequently, so we just walk the list of 2005811599a4SMatt Barden * connections searching for the user. 20061baeef30SPrashanth Badari * 20071baeef30SPrashanth Badari * Note that this must wait for any durable handles (ofiles) 20081baeef30SPrashanth Badari * owned by this user to become "orphaned", so that a reconnect 20091baeef30SPrashanth Badari * that may immediately follow can find and use such ofiles. 2010811599a4SMatt Barden */ 2011811599a4SMatt Barden void 2012811599a4SMatt Barden smb_server_logoff_ssnid(smb_request_t *sr, uint64_t ssnid) 2013811599a4SMatt Barden { 2014811599a4SMatt Barden smb_server_t *sv = sr->sr_server; 2015811599a4SMatt Barden smb_llist_t *sess_list; 2016811599a4SMatt Barden smb_session_t *sess; 20171baeef30SPrashanth Badari smb_user_t *user = NULL; 20181baeef30SPrashanth Badari 20191baeef30SPrashanth Badari SMB_SERVER_VALID(sv); 2020811599a4SMatt Barden 2021811599a4SMatt Barden if (sv->sv_state != SMB_SERVER_STATE_RUNNING) 2022811599a4SMatt Barden return; 2023811599a4SMatt Barden 2024811599a4SMatt Barden sess_list = &sv->sv_session_list; 2025811599a4SMatt Barden smb_llist_enter(sess_list, RW_READER); 2026811599a4SMatt Barden 2027811599a4SMatt Barden for (sess = smb_llist_head(sess_list); 2028811599a4SMatt Barden sess != NULL; 2029811599a4SMatt Barden sess = smb_llist_next(sess_list, sess)) { 2030811599a4SMatt Barden 2031811599a4SMatt Barden SMB_SESSION_VALID(sess); 2032811599a4SMatt Barden 2033811599a4SMatt Barden if (sess->dialect < SMB_VERS_2_BASE) 2034811599a4SMatt Barden continue; 2035811599a4SMatt Barden 20361baeef30SPrashanth Badari switch (sess->s_state) { 20371baeef30SPrashanth Badari case SMB_SESSION_STATE_NEGOTIATED: 20381baeef30SPrashanth Badari case SMB_SESSION_STATE_TERMINATED: 20391baeef30SPrashanth Badari case SMB_SESSION_STATE_DISCONNECTED: 20401baeef30SPrashanth Badari break; 20411baeef30SPrashanth Badari default: 2042811599a4SMatt Barden continue; 2043811599a4SMatt Barden } 2044811599a4SMatt Barden 20451baeef30SPrashanth Badari /* 20461baeef30SPrashanth Badari * Normal situation is to find a LOGGED_ON user. 20471baeef30SPrashanth Badari */ 20481baeef30SPrashanth Badari user = smb_session_lookup_uid_st(sess, ssnid, 0, 20491baeef30SPrashanth Badari SMB_USER_STATE_LOGGED_ON); 20501baeef30SPrashanth Badari if (user != NULL) { 20511baeef30SPrashanth Badari 20521baeef30SPrashanth Badari if (smb_is_same_user(user->u_cred, sr->user_cr)) { 2053811599a4SMatt Barden /* Treat this as if we lost the connection */ 2054811599a4SMatt Barden user->preserve_opens = SMB2_DH_PRESERVE_SOME; 2055811599a4SMatt Barden smb_user_logoff(user); 20561baeef30SPrashanth Badari break; 20571baeef30SPrashanth Badari } 2058811599a4SMatt Barden smb_user_release(user); 20591baeef30SPrashanth Badari user = NULL; 20601baeef30SPrashanth Badari } 2061811599a4SMatt Barden 2062811599a4SMatt Barden /* 20631baeef30SPrashanth Badari * If we raced with disconnect, may find LOGGING_OFF, 20641baeef30SPrashanth Badari * in which case we want to just wait for it. 2065811599a4SMatt Barden */ 20661baeef30SPrashanth Badari user = smb_session_lookup_uid_st(sess, ssnid, 0, 20671baeef30SPrashanth Badari SMB_USER_STATE_LOGGING_OFF); 20681baeef30SPrashanth Badari if (user != NULL) { 20691baeef30SPrashanth Badari if (smb_is_same_user(user->u_cred, sr->user_cr)) 20701baeef30SPrashanth Badari break; 20711baeef30SPrashanth Badari smb_user_release(user); 20721baeef30SPrashanth Badari user = NULL; 20731baeef30SPrashanth Badari } 2074811599a4SMatt Barden } 2075811599a4SMatt Barden 2076811599a4SMatt Barden smb_llist_exit(sess_list); 20771baeef30SPrashanth Badari 20781baeef30SPrashanth Badari if (user != NULL) { 20791baeef30SPrashanth Badari /* 20801baeef30SPrashanth Badari * Wait for durable handles to be orphaned. 20811baeef30SPrashanth Badari * Note: not holding the sess list rwlock. 20821baeef30SPrashanth Badari */ 20831baeef30SPrashanth Badari smb_user_wait_trees(user); 20841baeef30SPrashanth Badari 20851baeef30SPrashanth Badari /* 20861baeef30SPrashanth Badari * Could be doing the last release on a user below, 20871baeef30SPrashanth Badari * which can leave work on the delete queues for 20881baeef30SPrashanth Badari * s_user_list or s_tree_list so flush those. 20891baeef30SPrashanth Badari * Must hold the session list after the user release 20901baeef30SPrashanth Badari * so that the session can't go away while we flush. 20911baeef30SPrashanth Badari */ 20921baeef30SPrashanth Badari smb_llist_enter(sess_list, RW_READER); 20931baeef30SPrashanth Badari 20941baeef30SPrashanth Badari sess = user->u_session; 20951baeef30SPrashanth Badari smb_user_release(user); 20961baeef30SPrashanth Badari 20971baeef30SPrashanth Badari smb_llist_flush(&sess->s_tree_list); 20981baeef30SPrashanth Badari smb_llist_flush(&sess->s_user_list); 20991baeef30SPrashanth Badari 21001baeef30SPrashanth Badari smb_llist_exit(sess_list); 21011baeef30SPrashanth Badari } 2102811599a4SMatt Barden } 2103811599a4SMatt Barden 210412b65585SGordon Ross /* See also: libsmb smb_kmod_setcfg */ 2105faa1795aSjb150015 static void 210629bd2886SAlan Wright smb_server_store_cfg(smb_server_t *sv, smb_ioc_cfg_t *ioc) 2107faa1795aSjb150015 { 210829bd2886SAlan Wright if (ioc->maxconnections == 0) 210929bd2886SAlan Wright ioc->maxconnections = 0xFFFFFFFF; 2110faa1795aSjb150015 21111160dcf7SMatt Barden if (ioc->encrypt == SMB_CONFIG_REQUIRED && 21121160dcf7SMatt Barden ioc->max_protocol < SMB_VERS_3_0) { 21131160dcf7SMatt Barden cmn_err(CE_WARN, "Server set to require encryption; " 21141160dcf7SMatt Barden "forcing max_protocol to 3.0"); 21151160dcf7SMatt Barden ioc->max_protocol = SMB_VERS_3_0; 21161160dcf7SMatt Barden } 21171160dcf7SMatt Barden 211829bd2886SAlan Wright sv->sv_cfg.skc_maxworkers = ioc->maxworkers; 211929bd2886SAlan Wright sv->sv_cfg.skc_maxconnections = ioc->maxconnections; 212029bd2886SAlan Wright sv->sv_cfg.skc_keepalive = ioc->keepalive; 212129bd2886SAlan Wright sv->sv_cfg.skc_restrict_anon = ioc->restrict_anon; 212229bd2886SAlan Wright sv->sv_cfg.skc_signing_enable = ioc->signing_enable; 212329bd2886SAlan Wright sv->sv_cfg.skc_signing_required = ioc->signing_required; 212429bd2886SAlan Wright sv->sv_cfg.skc_oplock_enable = ioc->oplock_enable; 212529bd2886SAlan Wright sv->sv_cfg.skc_sync_enable = ioc->sync_enable; 212629bd2886SAlan Wright sv->sv_cfg.skc_secmode = ioc->secmode; 212712b65585SGordon Ross sv->sv_cfg.skc_netbios_enable = ioc->netbios_enable; 212829bd2886SAlan Wright sv->sv_cfg.skc_ipv6_enable = ioc->ipv6_enable; 2129cb174861Sjoyce mcintosh sv->sv_cfg.skc_print_enable = ioc->print_enable; 21305f1ef25cSAram Hăvărneanu sv->sv_cfg.skc_traverse_mounts = ioc->traverse_mounts; 2131814e0daaSGordon Ross sv->sv_cfg.skc_short_names = ioc->short_names; 2132a90cf9f2SGordon Ross sv->sv_cfg.skc_max_protocol = ioc->max_protocol; 21333e2c0c09SMatt Barden sv->sv_cfg.skc_min_protocol = ioc->min_protocol; 21341160dcf7SMatt Barden sv->sv_cfg.skc_encrypt = ioc->encrypt; 21354e065a9fSAlexander Stetsenko sv->sv_cfg.skc_encrypt_cipher = ioc->encrypt_cipher; 2136148c5f43SAlan Wright sv->sv_cfg.skc_execflags = ioc->exec_flags; 213712b65585SGordon Ross sv->sv_cfg.skc_negtok_len = ioc->negtok_len; 2138148c5f43SAlan Wright sv->sv_cfg.skc_version = ioc->version; 2139a90cf9f2SGordon Ross sv->sv_cfg.skc_initial_credits = ioc->initial_credits; 2140a90cf9f2SGordon Ross sv->sv_cfg.skc_maximum_credits = ioc->maximum_credits; 2141a90cf9f2SGordon Ross 214212b65585SGordon Ross (void) memcpy(sv->sv_cfg.skc_machine_uuid, ioc->machine_uuid, 214312b65585SGordon Ross sizeof (uuid_t)); 214412b65585SGordon Ross (void) memcpy(sv->sv_cfg.skc_negtok, ioc->negtok, 214512b65585SGordon Ross sizeof (sv->sv_cfg.skc_negtok)); 214612b65585SGordon Ross (void) memcpy(sv->sv_cfg.skc_native_os, ioc->native_os, 214712b65585SGordon Ross sizeof (sv->sv_cfg.skc_native_os)); 214812b65585SGordon Ross (void) memcpy(sv->sv_cfg.skc_native_lm, ioc->native_lm, 214912b65585SGordon Ross sizeof (sv->sv_cfg.skc_native_lm)); 215012b65585SGordon Ross 215129bd2886SAlan Wright (void) strlcpy(sv->sv_cfg.skc_nbdomain, ioc->nbdomain, 215229bd2886SAlan Wright sizeof (sv->sv_cfg.skc_nbdomain)); 215329bd2886SAlan Wright (void) strlcpy(sv->sv_cfg.skc_fqdn, ioc->fqdn, 215429bd2886SAlan Wright sizeof (sv->sv_cfg.skc_fqdn)); 215529bd2886SAlan Wright (void) strlcpy(sv->sv_cfg.skc_hostname, ioc->hostname, 215629bd2886SAlan Wright sizeof (sv->sv_cfg.skc_hostname)); 215729bd2886SAlan Wright (void) strlcpy(sv->sv_cfg.skc_system_comment, ioc->system_comment, 215829bd2886SAlan Wright sizeof (sv->sv_cfg.skc_system_comment)); 2159faa1795aSjb150015 } 2160faa1795aSjb150015 2161faa1795aSjb150015 static int 2162faa1795aSjb150015 smb_server_fsop_start(smb_server_t *sv) 2163faa1795aSjb150015 { 2164faa1795aSjb150015 int error; 2165faa1795aSjb150015 21668622ec45SGordon Ross error = smb_node_root_init(sv, &sv->si_root_smb_node); 2167faa1795aSjb150015 if (error != 0) 2168faa1795aSjb150015 sv->si_root_smb_node = NULL; 2169faa1795aSjb150015 2170faa1795aSjb150015 return (error); 2171faa1795aSjb150015 } 2172faa1795aSjb150015 2173faa1795aSjb150015 static void 2174faa1795aSjb150015 smb_server_fsop_stop(smb_server_t *sv) 2175faa1795aSjb150015 { 2176faa1795aSjb150015 if (sv->si_root_smb_node != NULL) { 2177faa1795aSjb150015 smb_node_release(sv->si_root_smb_node); 2178faa1795aSjb150015 sv->si_root_smb_node = NULL; 2179faa1795aSjb150015 } 2180faa1795aSjb150015 } 21819fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 21829fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States smb_event_t * 21838622ec45SGordon Ross smb_event_create(smb_server_t *sv, int timeout) 21849fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States { 21859fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States smb_event_t *event; 21869fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 21878622ec45SGordon Ross if (smb_server_is_stopping(sv)) 21889fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States return (NULL); 21899fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 21908622ec45SGordon Ross event = kmem_cache_alloc(smb_cache_event, KM_SLEEP); 21919fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 21929fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States bzero(event, sizeof (smb_event_t)); 21939fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States mutex_init(&event->se_mutex, NULL, MUTEX_DEFAULT, NULL); 21949fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States cv_init(&event->se_cv, NULL, CV_DEFAULT, NULL); 21959fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States event->se_magic = SMB_EVENT_MAGIC; 21969fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States event->se_txid = smb_event_alloc_txid(); 21979fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States event->se_server = sv; 2198cb174861Sjoyce mcintosh event->se_timeout = timeout; 21999fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 22009fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States smb_llist_enter(&sv->sv_event_list, RW_WRITER); 22019fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States smb_llist_insert_tail(&sv->sv_event_list, event); 22029fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States smb_llist_exit(&sv->sv_event_list); 22039fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 22049fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States return (event); 22059fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States } 22069fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 22079fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States void 22089fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States smb_event_destroy(smb_event_t *event) 22099fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States { 22109fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States smb_server_t *sv; 22119fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 22129fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States if (event == NULL) 22139fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States return; 22149fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 22159fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States SMB_EVENT_VALID(event); 22169fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States ASSERT(event->se_waittime == 0); 22178622ec45SGordon Ross sv = event->se_server; 22188622ec45SGordon Ross SMB_SERVER_VALID(sv); 22199fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 22209fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States smb_llist_enter(&sv->sv_event_list, RW_WRITER); 22219fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States smb_llist_remove(&sv->sv_event_list, event); 22229fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States smb_llist_exit(&sv->sv_event_list); 22239fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 22249fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States event->se_magic = (uint32_t)~SMB_EVENT_MAGIC; 22259fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States cv_destroy(&event->se_cv); 22269fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States mutex_destroy(&event->se_mutex); 22279fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 22288622ec45SGordon Ross kmem_cache_free(smb_cache_event, event); 22299fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States } 22309fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 22319fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States /* 22329fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States * Get the txid for the specified event. 22339fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States */ 22349fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States uint32_t 22359fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States smb_event_txid(smb_event_t *event) 22369fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States { 22379fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States if (event != NULL) { 22389fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States SMB_EVENT_VALID(event); 22399fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States return (event->se_txid); 22409fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States } 22419fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 22429fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States cmn_err(CE_NOTE, "smb_event_txid failed"); 22439fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States return ((uint32_t)-1); 22449fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States } 22459fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 22469fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States /* 22479fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States * Wait for event notification. 22489fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States */ 22499fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States int 22509fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States smb_event_wait(smb_event_t *event) 22519fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States { 22529fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States int seconds = 1; 22539fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States int ticks; 2254856399cfSGordon Ross int err; 22559fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 22569fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States if (event == NULL) 22579fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States return (EINVAL); 22589fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 22599fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States SMB_EVENT_VALID(event); 22609fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 22619fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States mutex_enter(&event->se_mutex); 22629fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States event->se_waittime = 1; 22639fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States event->se_errno = 0; 22649fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 22659fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States while (!(event->se_notified)) { 2266c5866007SKeyur Desai if (smb_event_debug && ((event->se_waittime % 30) == 0)) 22679fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States cmn_err(CE_NOTE, "smb_event_wait[%d] (%d sec)", 22689fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States event->se_txid, event->se_waittime); 22699fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 22709fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States if (event->se_errno != 0) 22719fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States break; 22729fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 2273cb174861Sjoyce mcintosh if (event->se_waittime > event->se_timeout) { 22749fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States event->se_errno = ETIME; 22759fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States break; 22769fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States } 22779fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 22789fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States ticks = SEC_TO_TICK(seconds); 22799fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States (void) cv_reltimedwait(&event->se_cv, 22809fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States &event->se_mutex, (clock_t)ticks, TR_CLOCK_TICK); 22819fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States ++event->se_waittime; 22829fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States } 22839fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 2284856399cfSGordon Ross err = event->se_errno; 22859fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States event->se_waittime = 0; 22869fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States event->se_notified = B_FALSE; 22879fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States cv_signal(&event->se_cv); 22889fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States mutex_exit(&event->se_mutex); 2289856399cfSGordon Ross return (err); 22909fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States } 22919fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 22929fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States /* 22939fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States * If txid is non-zero, cancel the specified event. 22949fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States * Otherwise, cancel all events. 22959fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States */ 22969fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States static void 22979fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States smb_event_cancel(smb_server_t *sv, uint32_t txid) 22989fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States { 22999fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States smb_event_t *event; 23009fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States smb_llist_t *event_list; 23019fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 23029fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States SMB_SERVER_VALID(sv); 23039fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 23049fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States event_list = &sv->sv_event_list; 23059fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States smb_llist_enter(event_list, RW_WRITER); 23069fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 23079fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States event = smb_llist_head(event_list); 23089fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States while (event) { 23099fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States SMB_EVENT_VALID(event); 23109fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 23119fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States if (txid == 0 || event->se_txid == txid) { 23129fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States mutex_enter(&event->se_mutex); 23139fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States event->se_errno = ECANCELED; 23149fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States event->se_notified = B_TRUE; 23159fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States cv_signal(&event->se_cv); 23169fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States mutex_exit(&event->se_mutex); 23179fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 23189fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States if (txid != 0) 23199fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States break; 23209fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States } 23219fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 23229fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States event = smb_llist_next(event_list, event); 23239fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States } 23249fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 23259fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States smb_llist_exit(event_list); 23269fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States } 23279fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 23289fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States /* 23299fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States * If txid is non-zero, notify the specified event. 23309fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States * Otherwise, notify all events. 23319fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States */ 2332cb174861Sjoyce mcintosh void 23339fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States smb_event_notify(smb_server_t *sv, uint32_t txid) 23349fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States { 23359fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States smb_event_t *event; 23369fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States smb_llist_t *event_list; 23379fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 23389fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States SMB_SERVER_VALID(sv); 23399fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 23409fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States event_list = &sv->sv_event_list; 23419fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States smb_llist_enter(event_list, RW_READER); 23429fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 23439fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States event = smb_llist_head(event_list); 23449fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States while (event) { 23459fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States SMB_EVENT_VALID(event); 23469fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 23479fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States if (txid == 0 || event->se_txid == txid) { 23489fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States mutex_enter(&event->se_mutex); 23499fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States event->se_notified = B_TRUE; 23509fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States cv_signal(&event->se_cv); 23519fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States mutex_exit(&event->se_mutex); 23529fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 23539fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States if (txid != 0) 23549fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States break; 23559fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States } 23569fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 23579fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States event = smb_llist_next(event_list, event); 23589fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States } 23599fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 23609fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States smb_llist_exit(event_list); 23619fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States } 23629fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 23639fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States /* 23649fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States * Allocate a new transaction id (txid). 23659fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States * 23669fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States * 0 or -1 are not assigned because they are used to detect invalid 23679fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States * conditions or to indicate all open id's. 23689fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States */ 23699fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States static uint32_t 23709fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States smb_event_alloc_txid(void) 23719fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States { 23729fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States static kmutex_t txmutex; 23739fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States static uint32_t txid; 23749fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States uint32_t txid_ret; 23759fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 23769fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States mutex_enter(&txmutex); 23779fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 23789fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States if (txid == 0) 23799fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States txid = ddi_get_lbolt() << 11; 23809fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 23819fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States do { 23829fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States ++txid; 23839fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States } while (txid == 0 || txid == (uint32_t)-1); 23849fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 23859fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States txid_ret = txid; 23869fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States mutex_exit(&txmutex); 23879fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 23889fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States return (txid_ret); 23899fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States } 2390cb174861Sjoyce mcintosh 2391cb174861Sjoyce mcintosh /* 2392cb174861Sjoyce mcintosh * Called by the ioctl to find the corresponding 2393cb174861Sjoyce mcintosh * spooldoc node. removes node on success 2394cb174861Sjoyce mcintosh * 2395cb174861Sjoyce mcintosh * Return values 2396cb174861Sjoyce mcintosh * rc 2397cb174861Sjoyce mcintosh * B_FALSE - not found 2398cb174861Sjoyce mcintosh * B_TRUE - found 2399cb174861Sjoyce mcintosh * 2400cb174861Sjoyce mcintosh */ 2401cb174861Sjoyce mcintosh 240223a9c295SGordon Ross static boolean_t 240323a9c295SGordon Ross smb_spool_lookup_doc_byfid(smb_server_t *sv, uint16_t fid, 240423a9c295SGordon Ross smb_kspooldoc_t *spdoc) 2405cb174861Sjoyce mcintosh { 2406cb174861Sjoyce mcintosh smb_kspooldoc_t *sp; 2407cb174861Sjoyce mcintosh smb_llist_t *splist; 2408cb174861Sjoyce mcintosh 2409cb174861Sjoyce mcintosh splist = &sv->sp_info.sp_list; 2410cb174861Sjoyce mcintosh smb_llist_enter(splist, RW_WRITER); 2411cb174861Sjoyce mcintosh sp = smb_llist_head(splist); 2412cb174861Sjoyce mcintosh while (sp != NULL) { 2413cb174861Sjoyce mcintosh /* 2414cb174861Sjoyce mcintosh * check for a matching fid 2415cb174861Sjoyce mcintosh */ 2416cb174861Sjoyce mcintosh if (sp->sd_fid == fid) { 2417cb174861Sjoyce mcintosh *spdoc = *sp; 2418cb174861Sjoyce mcintosh smb_llist_remove(splist, sp); 2419cb174861Sjoyce mcintosh smb_llist_exit(splist); 2420cb174861Sjoyce mcintosh kmem_free(sp, sizeof (smb_kspooldoc_t)); 2421cb174861Sjoyce mcintosh return (B_TRUE); 2422cb174861Sjoyce mcintosh } 2423cb174861Sjoyce mcintosh sp = smb_llist_next(splist, sp); 2424cb174861Sjoyce mcintosh } 2425cb174861Sjoyce mcintosh cmn_err(CE_WARN, "smb_spool_lookup_user_byfid: no fid:%d", fid); 2426cb174861Sjoyce mcintosh smb_llist_exit(splist); 2427cb174861Sjoyce mcintosh return (B_FALSE); 2428cb174861Sjoyce mcintosh } 2429cb174861Sjoyce mcintosh 2430cb174861Sjoyce mcintosh /* 2431cb174861Sjoyce mcintosh * Adds the spool fid to a linked list to be used 2432cb174861Sjoyce mcintosh * as a search key in the spooldoc queue 2433cb174861Sjoyce mcintosh * 2434cb174861Sjoyce mcintosh * Return values 2435cb174861Sjoyce mcintosh * rc non-zero error 2436cb174861Sjoyce mcintosh * rc zero success 2437cb174861Sjoyce mcintosh * 2438cb174861Sjoyce mcintosh */ 2439cb174861Sjoyce mcintosh 244086d7016bSGordon Ross void 244186d7016bSGordon Ross smb_spool_add_fid(smb_server_t *sv, uint16_t fid) 2442cb174861Sjoyce mcintosh { 2443cb174861Sjoyce mcintosh smb_llist_t *fidlist; 2444cb174861Sjoyce mcintosh smb_spoolfid_t *sf; 2445cb174861Sjoyce mcintosh 244686d7016bSGordon Ross if (sv->sv_cfg.skc_print_enable == 0) 244786d7016bSGordon Ross return; 2448cb174861Sjoyce mcintosh 2449cb174861Sjoyce mcintosh sf = kmem_zalloc(sizeof (smb_spoolfid_t), KM_SLEEP); 2450cb174861Sjoyce mcintosh fidlist = &sv->sp_info.sp_fidlist; 2451cb174861Sjoyce mcintosh smb_llist_enter(fidlist, RW_WRITER); 2452cb174861Sjoyce mcintosh sf->sf_fid = fid; 2453cb174861Sjoyce mcintosh smb_llist_insert_tail(fidlist, sf); 2454cb174861Sjoyce mcintosh smb_llist_exit(fidlist); 245586d7016bSGordon Ross cv_broadcast(&sv->sp_info.sp_cv); 2456cb174861Sjoyce mcintosh } 2457cb174861Sjoyce mcintosh 2458cb174861Sjoyce mcintosh /* 2459cb174861Sjoyce mcintosh * Called by the ioctl to get and remove the head of the fid list 2460cb174861Sjoyce mcintosh * 2461cb174861Sjoyce mcintosh * Return values 2462cb174861Sjoyce mcintosh * int fd 2463cb174861Sjoyce mcintosh * greater than 0 success 2464cb174861Sjoyce mcintosh * 0 - error 2465cb174861Sjoyce mcintosh * 2466cb174861Sjoyce mcintosh */ 2467cb174861Sjoyce mcintosh 246823a9c295SGordon Ross static uint16_t 246923a9c295SGordon Ross smb_spool_get_fid(smb_server_t *sv) 2470cb174861Sjoyce mcintosh { 2471cb174861Sjoyce mcintosh smb_spoolfid_t *spfid; 2472cb174861Sjoyce mcintosh smb_llist_t *splist; 2473cb174861Sjoyce mcintosh uint16_t fid; 2474cb174861Sjoyce mcintosh 2475cb174861Sjoyce mcintosh splist = &sv->sp_info.sp_fidlist; 2476cb174861Sjoyce mcintosh smb_llist_enter(splist, RW_WRITER); 2477cb174861Sjoyce mcintosh spfid = smb_llist_head(splist); 2478cb174861Sjoyce mcintosh if (spfid != NULL) { 2479cb174861Sjoyce mcintosh fid = spfid->sf_fid; 2480cb174861Sjoyce mcintosh smb_llist_remove(&sv->sp_info.sp_fidlist, spfid); 2481cb174861Sjoyce mcintosh kmem_free(spfid, sizeof (smb_spoolfid_t)); 2482cb174861Sjoyce mcintosh } else { 2483cb174861Sjoyce mcintosh fid = 0; 2484cb174861Sjoyce mcintosh } 2485cb174861Sjoyce mcintosh smb_llist_exit(splist); 2486cb174861Sjoyce mcintosh return (fid); 2487cb174861Sjoyce mcintosh } 2488cb174861Sjoyce mcintosh 2489cb174861Sjoyce mcintosh /* 2490cb174861Sjoyce mcintosh * Adds the spooldoc to the tail of the spooldoc list 2491cb174861Sjoyce mcintosh * 2492cb174861Sjoyce mcintosh * Return values 2493cb174861Sjoyce mcintosh * rc non-zero error 2494cb174861Sjoyce mcintosh * rc zero success 2495cb174861Sjoyce mcintosh */ 2496cb174861Sjoyce mcintosh int 24978622ec45SGordon Ross smb_spool_add_doc(smb_tree_t *tree, smb_kspooldoc_t *sp) 2498cb174861Sjoyce mcintosh { 2499cb174861Sjoyce mcintosh smb_llist_t *splist; 25008622ec45SGordon Ross smb_server_t *sv = tree->t_server; 2501cb174861Sjoyce mcintosh int rc = 0; 2502cb174861Sjoyce mcintosh 2503cb174861Sjoyce mcintosh splist = &sv->sp_info.sp_list; 2504cb174861Sjoyce mcintosh smb_llist_enter(splist, RW_WRITER); 250523a9c295SGordon Ross sp->sd_spool_num = atomic_inc_32_nv(&sv->sp_info.sp_cnt); 2506cb174861Sjoyce mcintosh smb_llist_insert_tail(splist, sp); 2507cb174861Sjoyce mcintosh smb_llist_exit(splist); 25088622ec45SGordon Ross 2509cb174861Sjoyce mcintosh return (rc); 2510cb174861Sjoyce mcintosh } 25114163af6aSjose borrego 25124163af6aSjose borrego /* 25134163af6aSjose borrego * smb_server_create_session 25144163af6aSjose borrego */ 25154163af6aSjose borrego static void 25164163af6aSjose borrego smb_server_create_session(smb_listener_daemon_t *ld, ksocket_t s_so) 25174163af6aSjose borrego { 2518811599a4SMatt Barden smb_server_t *sv = ld->ld_sv; 251961b20185SGordon Ross smb_session_t *session; 252061b20185SGordon Ross smb_llist_t *sl; 252161b20185SGordon Ross taskqid_t tqid; 252261b20185SGordon Ross clock_t now; 25234163af6aSjose borrego 2524811599a4SMatt Barden session = smb_session_create(s_so, ld->ld_port, sv, 25254163af6aSjose borrego ld->ld_family); 25264163af6aSjose borrego 25278622ec45SGordon Ross if (session == NULL) { 252861b20185SGordon Ross /* This should be rare (create sleeps) */ 25298622ec45SGordon Ross smb_soshutdown(s_so); 25308622ec45SGordon Ross smb_sodestroy(s_so); 25318622ec45SGordon Ross cmn_err(CE_WARN, "SMB Session: alloc failed"); 25328622ec45SGordon Ross return; 25338622ec45SGordon Ross } 25348622ec45SGordon Ross 2535811599a4SMatt Barden sl = &sv->sv_session_list; 2536811599a4SMatt Barden smb_llist_enter(sl, RW_WRITER); 253761b20185SGordon Ross if (smb_llist_get_count(sl) >= sv->sv_cfg.skc_maxconnections) { 253861b20185SGordon Ross /* 253961b20185SGordon Ross * New session not in sv_session_list, so we can just 254061b20185SGordon Ross * delete it directly. 254161b20185SGordon Ross */ 254261b20185SGordon Ross smb_llist_exit(sl); 254361b20185SGordon Ross DTRACE_PROBE1(maxconn, smb_session_t *, session); 254461b20185SGordon Ross smb_soshutdown(session->sock); 254561b20185SGordon Ross smb_session_delete(session); 254661b20185SGordon Ross goto logmaxconn; 254761b20185SGordon Ross } 2548811599a4SMatt Barden smb_llist_insert_tail(sl, session); 2549811599a4SMatt Barden smb_llist_exit(sl); 25504163af6aSjose borrego 25518622ec45SGordon Ross /* 25528622ec45SGordon Ross * These taskq entries must run independently of one another, 25538622ec45SGordon Ross * so TQ_NOQUEUE. TQ_SLEEP (==0) just for clarity. 25548622ec45SGordon Ross */ 2555811599a4SMatt Barden tqid = taskq_dispatch(sv->sv_receiver_pool, 2556811599a4SMatt Barden smb_server_receiver, session, TQ_NOQUEUE | TQ_SLEEP); 2557fc8ae2ecSToomas Soome if (tqid == TASKQID_INVALID) { 255861b20185SGordon Ross /* 255961b20185SGordon Ross * We never entered smb_server_receiver() 256061b20185SGordon Ross * so need to do it's return cleanup 256161b20185SGordon Ross */ 256261b20185SGordon Ross DTRACE_PROBE1(maxconn, smb_session_t *, session); 25634163af6aSjose borrego smb_session_disconnect(session); 256461b20185SGordon Ross smb_session_logoff(session); 2565811599a4SMatt Barden smb_server_destroy_session(session); 256661b20185SGordon Ross goto logmaxconn; 25674163af6aSjose borrego } 256861b20185SGordon Ross 256961b20185SGordon Ross /* Success */ 25708622ec45SGordon Ross session->s_receiver_tqid = tqid; 257161b20185SGordon Ross return; 257261b20185SGordon Ross 257361b20185SGordon Ross logmaxconn: 257461b20185SGordon Ross /* 257561b20185SGordon Ross * If we hit max_connections, log something so an admin 257661b20185SGordon Ross * can find out why new connections are failing, but 257761b20185SGordon Ross * log this no more than once a minute. 257861b20185SGordon Ross */ 257961b20185SGordon Ross now = ddi_get_lbolt(); 258061b20185SGordon Ross if (now > ld->ld_quiet) { 258161b20185SGordon Ross ld->ld_quiet = now + SEC_TO_TICK(60); 258261b20185SGordon Ross cmn_err(CE_WARN, "SMB can't create session: " 258361b20185SGordon Ross "Would exceed max_connections."); 258461b20185SGordon Ross } 25854163af6aSjose borrego } 25864163af6aSjose borrego 25874163af6aSjose borrego static void 2588811599a4SMatt Barden smb_server_destroy_session(smb_session_t *session) 25894163af6aSjose borrego { 2590811599a4SMatt Barden smb_server_t *sv; 2591811599a4SMatt Barden smb_llist_t *ll; 2592811599a4SMatt Barden uint32_t count; 2593811599a4SMatt Barden 2594811599a4SMatt Barden ASSERT(session->s_server != NULL); 2595811599a4SMatt Barden sv = session->s_server; 2596811599a4SMatt Barden ll = &sv->sv_session_list; 2597811599a4SMatt Barden 2598811599a4SMatt Barden smb_llist_flush(&session->s_tree_list); 2599811599a4SMatt Barden smb_llist_flush(&session->s_user_list); 2600811599a4SMatt Barden 2601811599a4SMatt Barden /* 2602811599a4SMatt Barden * The user and tree lists should be empty now. 2603811599a4SMatt Barden */ 2604811599a4SMatt Barden #ifdef DEBUG 2605811599a4SMatt Barden if (session->s_user_list.ll_count != 0) { 2606811599a4SMatt Barden cmn_err(CE_WARN, "user list not empty?"); 2607811599a4SMatt Barden debug_enter("s_user_list"); 2608811599a4SMatt Barden } 2609811599a4SMatt Barden if (session->s_tree_list.ll_count != 0) { 2610811599a4SMatt Barden cmn_err(CE_WARN, "tree list not empty?"); 2611811599a4SMatt Barden debug_enter("s_tree_list"); 2612811599a4SMatt Barden } 2613811599a4SMatt Barden #endif 2614811599a4SMatt Barden 2615811599a4SMatt Barden smb_llist_enter(ll, RW_WRITER); 2616811599a4SMatt Barden smb_llist_remove(ll, session); 2617811599a4SMatt Barden count = ll->ll_count; 2618811599a4SMatt Barden smb_llist_exit(ll); 2619811599a4SMatt Barden 2620*7f5d80fdSGordon Ross /* 2621*7f5d80fdSGordon Ross * Normally, the session should have state SHUTDOWN here. 2622*7f5d80fdSGordon Ross * If the session has any ofiles remaining, eg. due to 2623*7f5d80fdSGordon Ross * forgotten ofile references or something, the state 2624*7f5d80fdSGordon Ross * will be _DISCONNECTED or _TERMINATED. Keep such 2625*7f5d80fdSGordon Ross * sessions in the list of zombies (for debugging). 2626*7f5d80fdSGordon Ross */ 2627*7f5d80fdSGordon Ross if (session->s_state == SMB_SESSION_STATE_SHUTDOWN) { 26284163af6aSjose borrego smb_session_delete(session); 2629*7f5d80fdSGordon Ross } else { 2630*7f5d80fdSGordon Ross #ifdef DEBUG 2631*7f5d80fdSGordon Ross cmn_err(CE_NOTE, "Leaked session: 0x%p", (void *)session); 2632*7f5d80fdSGordon Ross debug_enter("leaked session"); 2633*7f5d80fdSGordon Ross #endif 2634*7f5d80fdSGordon Ross smb_llist_enter(&smb_server_session_zombies, RW_WRITER); 2635*7f5d80fdSGordon Ross smb_llist_insert_head(&smb_server_session_zombies, session); 2636*7f5d80fdSGordon Ross smb_llist_exit(&smb_server_session_zombies); 2637*7f5d80fdSGordon Ross } 2638*7f5d80fdSGordon Ross 2639811599a4SMatt Barden if (count == 0) { 2640811599a4SMatt Barden /* See smb_server_shutdown */ 2641811599a4SMatt Barden cv_signal(&sv->sv_cv); 2642811599a4SMatt Barden } 26434163af6aSjose borrego } 2644