15331Samw /* 25331Samw * CDDL HEADER START 35331Samw * 45331Samw * The contents of this file are subject to the terms of the 55331Samw * Common Development and Distribution License (the "License"). 65331Samw * You may not use this file except in compliance with the License. 75331Samw * 85331Samw * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 95331Samw * or http://www.opensolaris.org/os/licensing. 105331Samw * See the License for the specific language governing permissions 115331Samw * and limitations under the License. 125331Samw * 135331Samw * When distributing Covered Code, include this CDDL HEADER in each 145331Samw * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 155331Samw * If applicable, add the following below this CDDL HEADER, with the 165331Samw * fields enclosed by brackets "[]" replaced with your own identifying 175331Samw * information: Portions Copyright [yyyy] [name of copyright owner] 185331Samw * 195331Samw * CDDL HEADER END 205331Samw */ 215331Samw /* 22*5772Sas200622 * Copyright 2008 Sun Microsystems, Inc. All rights reserved. 235331Samw * Use is subject to license terms. 245331Samw * 255331Samw * 265331Samw * Dispatching SMB requests. 275331Samw */ 285331Samw 295331Samw #pragma ident "%Z%%M% %I% %E% SMI" 305331Samw 315331Samw /* 325331Samw * ALMOST EVERYTHING YOU NEED TO KNOW ABOUT A SERVER MESSAGE BLOCK 335331Samw * 345331Samw * Request 355331Samw * Header 365331Samw * Magic 0xFF 'S' 'M' 'B' 375331Samw * smb_com a byte, the "first" command 385331Samw * Error a 4-byte union, ignored in a request 395331Samw * smb_flg a one byte set of eight flags 405331Samw * smb_flg2 a two byte set of 16 flags 415331Samw * . twelve reserved bytes, have a role 425331Samw * in connectionless transports (IPX, UDP?) 435331Samw * smb_tid a 16-bit tree ID, a mount point sorta, 445331Samw * 0xFFFF is this command does not have 455331Samw * or require a tree context 465331Samw * smb_pid a 16-bit process ID 475331Samw * smb_uid a 16-bit user ID, specific to this "session" 485331Samw * and mapped to a system (bona-fide) UID 495331Samw * smb_mid a 16-bit multiplex ID, used to differentiate 505331Samw * multiple simultaneous requests from the same 515331Samw * process (pid) (ref RPC "xid") 525331Samw * 535331Samw * Chained (AndX) commands (0 or more) 545331Samw * smb_wct a byte, number of 16-bit words containing 555331Samw * command parameters, min 2 for chained command 565331Samw * andx_com a byte, the "next" command, 0xFF for none 575331Samw * . an unused byte 585331Samw * andx_off a 16-bit offset, byte displacement from &Magic 595331Samw * to the smb_wct field of the "next" command, 605331Samw * ignore if andx_com is 0xFF, s/b 0 if no next 615331Samw * smb_vwv[] 0 or more 16-bit (sorta) parameters for 625331Samw * "this" command (i.e. smb_com if this is the 635331Samw * first parameters, or the andx_com of the just 645331Samw * previous block. 655331Samw * smb_bcc a 16-bit count of smb_data[] bytes 665331Samw * smb_data[] 0 or more bytes, format specific to commands 675331Samw * padding[] Optional padding 685331Samw * 695331Samw * Last command 705331Samw * smb_wct a byte, number of 16-bit words containing 715331Samw * command parameters, min 0 for chained command 725331Samw * smb_vwv[] 0 or more 16-bit (sorta) parameters for 735331Samw * "this" command (i.e. smb_com if this is the 745331Samw * first parameters, or the andx_com of the just 755331Samw * previous block. 765331Samw * smb_bcc a 16-bit count of smb_data[] bytes 775331Samw * smb_data[] 0 or more bytes, format specific to commands 785331Samw * 795331Samw * Reply 805331Samw * Header 815331Samw * Magic 0xFF 'S' 'M' 'B' 825331Samw * smb_com a byte, the "first" command, corresponds 835331Samw * to request 845331Samw * Error a 4-byte union, coding depends on dialect in use 855331Samw * for "DOS" errors 865331Samw * a byte for error class 875331Samw * an unused byte 885331Samw * a 16-bit word for error code 895331Samw * for "NT" errors 905331Samw * a 32-bit error code which 915331Samw * is a packed class and specifier 925331Samw * for "OS/2" errors 935331Samw * I don't know 945331Samw * The error information is specific to the 955331Samw * last command in the reply chain. 965331Samw * smb_flg a one byte set of eight flags, 0x80 bit set 975331Samw * indicating this message is a reply 985331Samw * smb_flg2 a two byte set of 16 flags 995331Samw * . twelve reserved bytes, have a role 1005331Samw * in connectionless transports (IPX, UDP?) 1015331Samw * smb_tid a 16-bit tree ID, a mount point sorta, 1025331Samw * should be the same as the request 1035331Samw * smb_pid a 16-bit process ID, MUST BE the same as request 1045331Samw * smb_uid a 16-bit user ID, specific to this "session" 1055331Samw * and mapped to a system (bona-fide) UID, 1065331Samw * should be the same as request 1075331Samw * smb_mid a 16-bit multiplex ID, used to differentiate 1085331Samw * multiple simultaneous requests from the same 1095331Samw * process (pid) (ref RPC "xid"), MUST BE the 1105331Samw * same as request 1115331Samw * padding[] Optional padding 1125331Samw * 1135331Samw * Chained (AndX) commands (0 or more) 1145331Samw * smb_wct a byte, number of 16-bit words containing 1155331Samw * command parameters, min 2 for chained command, 1165331Samw * andx_com a byte, the "next" command, 0xFF for none, 1175331Samw * corresponds to request, if this is the chained 1185331Samw * command that had an error set to 0xFF 1195331Samw * . an unused byte 1205331Samw * andx_off a 16-bit offset, byte displacement from &Magic 1215331Samw * to the smb_wct field of the "next" command, 1225331Samw * ignore if andx_com is 0xFF, s/b 0 if no next 1235331Samw * smb_vwv[] 0 or more 16-bit (sorta) parameters for 1245331Samw * "this" command (i.e. smb_com if this is the 1255331Samw * first parameters, or the andx_com of the just 1265331Samw * previous block. Empty if an error. 1275331Samw * smb_bcc a 16-bit count of smb_data[] bytes 1285331Samw * smb_data[] 0 or more bytes, format specific to commands 1295331Samw * empty if an error. 1305331Samw * 1315331Samw * Last command 1325331Samw * smb_wct a byte, number of 16-bit words containing 1335331Samw * command parameters, min 0 for chained command 1345331Samw * smb_vwv[] 0 or more 16-bit (sorta) parameters for 1355331Samw * "this" command (i.e. smb_com if this is the 1365331Samw * first parameters, or the andx_com of the just 1375331Samw * previous block, empty if an error. 1385331Samw * smb_bcc a 16-bit count of smb_data[] bytes 1395331Samw * smb_data[] 0 or more bytes, format specific to commands, 1405331Samw * empty if an error. 1415331Samw */ 1425331Samw 1435331Samw #include <smbsrv/smb_incl.h> 1445331Samw #include <sys/sdt.h> 1455331Samw 1465331Samw #define SMB_ALL_DISPATCH_STAT_INCR(stat) atomic_inc_64(&stat); 1475331Samw 1485331Samw static kstat_t *smb_dispatch_ksp = NULL; 1495331Samw static kstat_named_t *smb_dispatch_kstat_data = NULL; 1505331Samw static int smb_dispatch_kstat_size = 0; 1515331Samw 1525331Samw static int is_andx_com(unsigned char); 1535331Samw 1545331Samw extern void smbsr_decode_error(struct smb_request *sr); 1555331Samw extern void smbsr_encode_error(struct smb_request *sr); 1565331Samw extern void smbsr_check_result(struct smb_request *sr, int wct, int bcc); 1575331Samw 1585331Samw extern int smb_com_cancel_forward(struct smb_request *); 1595331Samw extern int smb_com_check_directory(struct smb_request *); 1605331Samw extern int smb_com_close(struct smb_request *); 1615331Samw extern int smb_com_close_and_tree_disconnect(struct smb_request *); 1625331Samw extern int smb_com_close_print_file(struct smb_request *); 1635331Samw extern int smb_com_copy(struct smb_request *); 1645331Samw extern int smb_com_create(struct smb_request *); 1655331Samw extern int smb_com_create_directory(struct smb_request *); 1665331Samw extern int smb_com_create_new(struct smb_request *); 1675331Samw extern int smb_com_create_temporary(struct smb_request *); 1685331Samw extern int smb_com_delete(struct smb_request *); 1695331Samw extern int smb_com_delete_directory(struct smb_request *); 1705331Samw extern int smb_com_echo(struct smb_request *); 1715331Samw extern int smb_com_find(struct smb_request *); 1725331Samw extern int smb_com_find_close(struct smb_request *); 1735331Samw extern int smb_com_find_close2(struct smb_request *); 1745331Samw extern int smb_com_find_notify_close(struct smb_request *); 1755331Samw extern int smb_com_find_unique(struct smb_request *); 1765331Samw extern int smb_com_flush(struct smb_request *); 1775331Samw extern int smb_com_forward_user_name(struct smb_request *); 1785331Samw extern int smb_com_get_machine_name(struct smb_request *); 1795331Samw extern int smb_com_get_print_queue(struct smb_request *); 1805331Samw extern int smb_com_invalid_command(struct smb_request *); 1815331Samw extern int smb_com_ioctl(struct smb_request *); 1825331Samw extern int smb_com_ioctl_secondary(struct smb_request *); 1835331Samw extern int smb_com_lock_and_read(struct smb_request *); 1845331Samw extern int smb_com_lock_byte_range(struct smb_request *); 1855331Samw extern int smb_com_locking_andx(struct smb_request *); 1865331Samw extern int smb_com_logoff_andx(struct smb_request *); 1875331Samw extern int smb_com_move(struct smb_request *); 1885331Samw extern int smb_com_negotiate(struct smb_request *); 1895331Samw extern int smb_com_nt_cancel(struct smb_request *); 1905331Samw extern int smb_com_nt_create_andx(struct smb_request *); 1915331Samw extern int smb_com_nt_transact(struct smb_request *); 1925331Samw extern int smb_com_nt_transact_secondary(struct smb_request *); 1935331Samw extern int smb_com_open(struct smb_request *); 1945331Samw extern int smb_com_open_andx(struct smb_request *); 1955331Samw extern int smb_com_open_print_file(struct smb_request *); 1965331Samw extern int smb_com_process_exit(struct smb_request *); 1975331Samw extern int smb_com_query_information(struct smb_request *); 1985331Samw extern int smb_com_query_information2(struct smb_request *); 1995331Samw extern int smb_com_query_information_disk(struct smb_request *); 2005331Samw extern int smb_com_read(struct smb_request *); 2015331Samw extern int smb_com_read_andx(struct smb_request *); 2025331Samw extern int smb_com_read_mpx(struct smb_request *); 2035331Samw extern int smb_com_read_mpx_secondary(struct smb_request *); 2045331Samw extern int smb_com_read_raw(struct smb_request *); 2055331Samw extern int smb_com_rename(struct smb_request *); 2065331Samw extern int smb_com_search(struct smb_request *); 2075331Samw extern int smb_com_seek(struct smb_request *); 2085331Samw extern int smb_com_send_broadcast_message(struct smb_request *); 2095331Samw extern int smb_com_send_end_mb_message(struct smb_request *); 2105331Samw extern int smb_com_send_single_message(struct smb_request *); 2115331Samw extern int smb_com_send_start_mb_message(struct smb_request *); 2125331Samw extern int smb_com_send_text_mb_message(struct smb_request *); 2135331Samw extern int smb_com_session_setup_andx(struct smb_request *); 2145331Samw extern int smb_com_set_information(struct smb_request *); 2155331Samw extern int smb_com_set_information2(struct smb_request *); 2165331Samw extern int smb_com_transaction(struct smb_request *); 2175331Samw extern int smb_com_transaction2(struct smb_request *); 2185331Samw extern int smb_com_transaction2_secondary(struct smb_request *); 2195331Samw extern int smb_com_transaction_secondary(struct smb_request *); 2205331Samw extern int smb_com_tree_connect(struct smb_request *); 2215331Samw extern int smb_com_tree_connect_andx(struct smb_request *); 2225331Samw extern int smb_com_tree_disconnect(struct smb_request *); 2235331Samw extern int smb_com_unlock_byte_range(struct smb_request *); 2245331Samw extern int smb_com_write(struct smb_request *); 2255331Samw extern int smb_com_write_and_close(struct smb_request *); 2265331Samw extern int smb_com_write_and_unlock(struct smb_request *); 2275331Samw extern int smb_com_write_andx(struct smb_request *); 2285331Samw extern int smb_com_write_complete(struct smb_request *); 2295331Samw extern int smb_com_write_mpx(struct smb_request *); 2305331Samw extern int smb_com_write_mpx_secondary(struct smb_request *); 2315331Samw extern int smb_com_write_print_file(struct smb_request *); 2325331Samw extern int smb_com_write_raw(struct smb_request *); 2335331Samw 2345331Samw static smb_dispatch_table_t dispatch[256] = { 2355331Samw { smb_com_create_directory, /* 0x00 000 */ 2365331Samw PC_NETWORK_PROGRAM_1_0, SDDF_NO_FLAGS, 2375331Samw RW_READER, 2385331Samw { "SmbCreateDirectory", KSTAT_DATA_UINT64 } }, 2395331Samw { smb_com_delete_directory, /* 0x01 001 */ 2405331Samw PC_NETWORK_PROGRAM_1_0, SDDF_NO_FLAGS, 2415331Samw RW_READER, 2425331Samw { "SmbDeleteDirectory", KSTAT_DATA_UINT64 } }, 2435331Samw { smb_com_open, /* 0x02 002 */ 2445331Samw PC_NETWORK_PROGRAM_1_0, SDDF_NO_FLAGS, 2455331Samw RW_READER, 2465331Samw { "SmbOpen", KSTAT_DATA_UINT64 } }, 2475331Samw { smb_com_create, /* 0x03 003 */ 2485331Samw PC_NETWORK_PROGRAM_1_0, SDDF_NO_FLAGS, 2495331Samw RW_READER, 2505331Samw { "SmbCreate", KSTAT_DATA_UINT64 } }, 2515331Samw { smb_com_close, /* 0x04 004 */ 2525331Samw PC_NETWORK_PROGRAM_1_0, SDDF_NO_FLAGS, 2535331Samw RW_READER, 2545331Samw { "SmbClose", KSTAT_DATA_UINT64 } }, 2555331Samw { smb_com_flush, /* 0x05 005 */ 2565331Samw PC_NETWORK_PROGRAM_1_0, SDDF_NO_FLAGS, 2575331Samw RW_READER, 2585331Samw { "SmbFlush", KSTAT_DATA_UINT64 } }, 2595331Samw { smb_com_delete, /* 0x06 006 */ 2605331Samw PC_NETWORK_PROGRAM_1_0, SDDF_NO_FLAGS, 2615331Samw RW_READER, 2625331Samw { "SmbDelete", KSTAT_DATA_UINT64 } }, 2635331Samw { smb_com_rename, /* 0x07 007 */ 2645331Samw PC_NETWORK_PROGRAM_1_0, SDDF_NO_FLAGS, 2655331Samw RW_READER, 2665331Samw { "SmbRename", KSTAT_DATA_UINT64 } }, 2675331Samw { smb_com_query_information, /* 0x08 008 */ 2685331Samw PC_NETWORK_PROGRAM_1_0, SDDF_NO_FLAGS, 2695331Samw RW_READER, 2705331Samw { "SmbQueryInformation", KSTAT_DATA_UINT64 } }, 2715331Samw { smb_com_set_information, /* 0x09 009 */ 2725331Samw PC_NETWORK_PROGRAM_1_0, SDDF_NO_FLAGS, 2735331Samw RW_READER, 2745331Samw { "SmbSetInformation", KSTAT_DATA_UINT64 } }, 2755331Samw { smb_com_read, /* 0x0A 010 */ 2765331Samw PC_NETWORK_PROGRAM_1_0, SDDF_SUPPRESS_SHOW, 2775331Samw RW_READER, 2785331Samw { "SmbRead", KSTAT_DATA_UINT64 } }, 2795331Samw { smb_com_write, /* 0x0B 011 */ 2805331Samw PC_NETWORK_PROGRAM_1_0, SDDF_SUPPRESS_SHOW, 2815331Samw RW_READER, 2825331Samw { "SmbWrite", KSTAT_DATA_UINT64 } }, 2835331Samw { smb_com_lock_byte_range, /* 0x0C 012 */ 2845331Samw PC_NETWORK_PROGRAM_1_0, SDDF_NO_FLAGS, 2855331Samw RW_READER, 2865331Samw { "SmbLockByteRange", KSTAT_DATA_UINT64 } }, 2875331Samw { smb_com_unlock_byte_range, /* 0x0D 013 */ 2885331Samw PC_NETWORK_PROGRAM_1_0, SDDF_NO_FLAGS, 2895331Samw RW_READER, 2905331Samw { "SmbUnlockByteRange", KSTAT_DATA_UINT64 } }, 2915331Samw { smb_com_create_temporary, /* 0x0E 014 */ 2925331Samw PC_NETWORK_PROGRAM_1_0, SDDF_NO_FLAGS, 2935331Samw RW_READER, 2945331Samw { "SmbCreateTemporary", KSTAT_DATA_UINT64 } }, 2955331Samw { smb_com_create_new, /* 0x0F 015 */ 2965331Samw PC_NETWORK_PROGRAM_1_0, SDDF_NO_FLAGS, 2975331Samw RW_READER, 2985331Samw { "SmbCreateNew", KSTAT_DATA_UINT64 } }, 2995331Samw { smb_com_check_directory, /* 0x10 016 */ 3005331Samw PC_NETWORK_PROGRAM_1_0, SDDF_NO_FLAGS, 3015331Samw RW_READER, 3025331Samw { "SmbCheckDirectory", KSTAT_DATA_UINT64 } }, 3035331Samw { smb_com_process_exit, /* 0x11 017 */ 3045331Samw PC_NETWORK_PROGRAM_1_0, SDDF_SUPPRESS_TID | SDDF_SUPPRESS_UID, 3055331Samw RW_READER, 3065331Samw { "SmbProcessExit", KSTAT_DATA_UINT64 } }, 3075331Samw { smb_com_seek, /* 0x12 018 */ 3085331Samw PC_NETWORK_PROGRAM_1_0, SDDF_NO_FLAGS, 3095331Samw RW_READER, 3105331Samw { "SmbSeek", KSTAT_DATA_UINT64 } }, 3115331Samw { smb_com_lock_and_read, /* 0x13 019 */ 3125331Samw LANMAN1_0, SDDF_SUPPRESS_SHOW, 3135331Samw RW_READER, 3145331Samw { "SmbLockAndRead", KSTAT_DATA_UINT64 } }, 3155331Samw { smb_com_write_and_unlock, /* 0x14 020 */ 3165331Samw LANMAN1_0, SDDF_SUPPRESS_SHOW, 3175331Samw RW_READER, 3185331Samw { "SmbWriteAndUnlock", KSTAT_DATA_UINT64 } }, 3195331Samw { 0, 0, 0, RW_READER, 0 }, /* 0x15 021 */ 3205331Samw { 0, 0, 0, RW_READER, 0 }, /* 0x16 022 */ 3215331Samw { 0, 0, 0, RW_READER, 0 }, /* 0x17 023 */ 3225331Samw { 0, 0, 0, RW_READER, 0 }, /* 0x18 024 */ 3235331Samw { 0, 0, 0, RW_READER, 0 }, /* 0x19 025 */ 3245331Samw { smb_com_read_raw, /* 0x1A 026 */ 3255331Samw LANMAN1_0, SDDF_SUPPRESS_SHOW, 3265331Samw RW_WRITER, 3275331Samw { "SmbReadRaw", KSTAT_DATA_UINT64 } }, 3285331Samw { smb_com_read_mpx, /* 0x1B 027 */ 3295331Samw LANMAN1_0, SDDF_SUPPRESS_SHOW, 3305331Samw RW_READER, 3315331Samw { "SmbReadMpx", KSTAT_DATA_UINT64 } }, 3325331Samw { smb_com_read_mpx_secondary, /* 0x1C 028 */ 3335331Samw LANMAN1_0, SDDF_SUPPRESS_SHOW, 3345331Samw RW_READER, 3355331Samw { "SmbReadMpxSecondary", KSTAT_DATA_UINT64 } }, 3365331Samw { smb_com_write_raw, /* 0x1D 029 */ 3375331Samw LANMAN1_0, SDDF_SUPPRESS_SHOW | SDDF_SUPPRESS_UNLEASH, 3385331Samw RW_WRITER, 3395331Samw { "SmbWriteRaw", KSTAT_DATA_UINT64 } }, 3405331Samw { smb_com_write_mpx, /* 0x1E 030 */ 3415331Samw LANMAN1_0, SDDF_SUPPRESS_SHOW, 3425331Samw RW_READER, 3435331Samw { "SmbWriteMpx", KSTAT_DATA_UINT64 } }, 3445331Samw { smb_com_write_mpx_secondary, /* 0x1F 031 */ 3455331Samw LANMAN1_0, SDDF_SUPPRESS_SHOW, 3465331Samw RW_READER, 3475331Samw { "SmbWriteMpxSecondary", KSTAT_DATA_UINT64 } }, 3485331Samw { smb_com_write_complete, /* 0x20 032 */ 3495331Samw LANMAN1_0, SDDF_SUPPRESS_SHOW, 3505331Samw RW_READER, 3515331Samw { "SmbWriteComplete", KSTAT_DATA_UINT64 } }, 3525331Samw { 0, 0, 0, 0, 0 }, /* 0x21 033 */ 3535331Samw { smb_com_set_information2, /* 0x22 034 */ 3545331Samw LANMAN1_0, SDDF_NO_FLAGS, 3555331Samw RW_READER, 3565331Samw { "SmbSetInformation2", KSTAT_DATA_UINT64 } }, 3575331Samw { smb_com_query_information2, /* 0x23 035 */ 3585331Samw LANMAN1_0, SDDF_NO_FLAGS, 3595331Samw RW_READER, 3605331Samw { "SmbQueryInformation2", KSTAT_DATA_UINT64 } }, 3615331Samw { smb_com_locking_andx, /* 0x24 036 */ 3625331Samw LANMAN1_0, SDDF_NO_FLAGS, 3635331Samw RW_READER, 3645331Samw { "SmbLockingX", KSTAT_DATA_UINT64 } }, 3655331Samw { smb_com_transaction, /* 0x25 037 */ 3665331Samw LANMAN1_0, SDDF_NO_FLAGS, 3675331Samw RW_READER, 3685331Samw { "SmbTransaction", KSTAT_DATA_UINT64 } }, 3695331Samw { smb_com_transaction_secondary, /* 0x26 038 */ 3705331Samw LANMAN1_0, SDDF_NO_FLAGS, 3715331Samw RW_READER, 3725331Samw { "SmbTransactionSecondary", KSTAT_DATA_UINT64 } }, 3735331Samw { smb_com_ioctl, /* 0x27 039 */ 3745331Samw LANMAN1_0, SDDF_NO_FLAGS, 3755331Samw RW_READER, 3765331Samw { "SmbIoctl", KSTAT_DATA_UINT64 } }, 3775331Samw { smb_com_ioctl_secondary, /* 0x28 040 */ 3785331Samw LANMAN1_0, SDDF_NO_FLAGS, 3795331Samw RW_READER, 3805331Samw { "SmbIoctlSecondary", KSTAT_DATA_UINT64 } }, 3815331Samw { smb_com_copy, /* 0x29 041 */ 3825331Samw LANMAN1_0, SDDF_NO_FLAGS, 3835331Samw RW_READER, 3845331Samw { "SmbCopy", KSTAT_DATA_UINT64 } }, 3855331Samw { smb_com_move, /* 0x2A 042 */ 3865331Samw LANMAN1_0, SDDF_NO_FLAGS, 3875331Samw RW_READER, 3885331Samw { "SmbMove", KSTAT_DATA_UINT64 } }, 3895331Samw { smb_com_echo, /* 0x2B 043 */ 3905331Samw LANMAN1_0, SDDF_SUPPRESS_TID | SDDF_SUPPRESS_UID, 3915331Samw RW_READER, 3925331Samw { "SmbEcho", KSTAT_DATA_UINT64 } }, 3935331Samw { smb_com_write_and_close, /* 0x2C 044 */ 3945331Samw LANMAN1_0, SDDF_SUPPRESS_SHOW, 3955331Samw RW_READER, 3965331Samw { "SmbWriteAndClose", KSTAT_DATA_UINT64 } }, 3975331Samw { smb_com_open_andx, /* 0x2D 045 */ 3985331Samw LANMAN1_0, SDDF_NO_FLAGS, 3995331Samw RW_READER, 4005331Samw { "SmbOpenX", KSTAT_DATA_UINT64 } }, 4015331Samw { smb_com_read_andx, /* 0x2E 046 */ 4025331Samw LANMAN1_0, SDDF_SUPPRESS_SHOW, 4035331Samw RW_READER, 4045331Samw { "SmbReadX", KSTAT_DATA_UINT64 } }, 4055331Samw { smb_com_write_andx, /* 0x2F 047 */ 4065331Samw LANMAN1_0, SDDF_SUPPRESS_SHOW, 4075331Samw RW_READER, 4085331Samw { "SmbWriteX", KSTAT_DATA_UINT64 } }, 4095331Samw { 0, 0, 0, 0, 0 }, /* 0x30 048 */ 4105331Samw { smb_com_close_and_tree_disconnect, /* 0x31 049 */ 4115331Samw LANMAN1_0, SDDF_NO_FLAGS, 4125331Samw RW_READER, 4135331Samw { "SmbCloseAndTreeDisconnect", KSTAT_DATA_UINT64 } }, 4145331Samw { smb_com_transaction2, /* 0x32 050 */ 4155331Samw LM1_2X002, SDDF_NO_FLAGS, 4165331Samw RW_READER, 4175331Samw { "SmbTransaction2", KSTAT_DATA_UINT64 } }, 4185331Samw { smb_com_transaction2_secondary, /* 0x33 051 */ 4195331Samw LM1_2X002, SDDF_NO_FLAGS, 4205331Samw RW_READER, 4215331Samw { "SmbTransaction2Secondary", KSTAT_DATA_UINT64 } }, 4225331Samw { smb_com_find_close2, /* 0x34 052 */ 4235331Samw LM1_2X002, SDDF_NO_FLAGS, 4245331Samw RW_READER, 4255331Samw { "SmbFindClose2", KSTAT_DATA_UINT64 } }, 4265331Samw { smb_com_find_notify_close, /* 0x35 053 */ 4275331Samw LM1_2X002, SDDF_NO_FLAGS, 4285331Samw RW_READER, 4295331Samw { "SmbFindNotifyClose", KSTAT_DATA_UINT64 } }, 4305331Samw { 0, 0, 0, RW_READER, 0 }, /* 0x36 054 */ 4315331Samw { 0, 0, 0, RW_READER, 0 }, /* 0x37 055 */ 4325331Samw { 0, 0, 0, RW_READER, 0 }, /* 0x38 056 */ 4335331Samw { 0, 0, 0, RW_READER, 0 }, /* 0x39 057 */ 4345331Samw { 0, 0, 0, RW_READER, 0 }, /* 0x3A 058 */ 4355331Samw { 0, 0, 0, RW_READER, 0 }, /* 0x3B 059 */ 4365331Samw { 0, 0, 0, RW_READER, 0 }, /* 0x3C 060 */ 4375331Samw { 0, 0, 0, RW_READER, 0 }, /* 0x3D 061 */ 4385331Samw { 0, 0, 0, RW_READER, 0 }, /* 0x3E 062 */ 4395331Samw { 0, 0, 0, RW_READER, 0 }, /* 0x3F 063 */ 4405331Samw { 0, 0, 0, RW_READER, 0 }, /* 0x40 064 */ 4415331Samw { 0, 0, 0, RW_READER, 0 }, /* 0x41 065 */ 4425331Samw { 0, 0, 0, RW_READER, 0 }, /* 0x42 066 */ 4435331Samw { 0, 0, 0, RW_READER, 0 }, /* 0x43 067 */ 4445331Samw { 0, 0, 0, RW_READER, 0 }, /* 0x44 068 */ 4455331Samw { 0, 0, 0, RW_READER, 0 }, /* 0x45 069 */ 4465331Samw { 0, 0, 0, RW_READER, 0 }, /* 0x46 070 */ 4475331Samw { 0, 0, 0, RW_READER, 0 }, /* 0x47 071 */ 4485331Samw { 0, 0, 0, RW_READER, 0 }, /* 0x48 072 */ 4495331Samw { 0, 0, 0, RW_READER, 0 }, /* 0x49 073 */ 4505331Samw { 0, 0, 0, RW_READER, 0 }, /* 0x4A 074 */ 4515331Samw { 0, 0, 0, RW_READER, 0 }, /* 0x4B 075 */ 4525331Samw { 0, 0, 0, RW_READER, 0 }, /* 0x4C 076 */ 4535331Samw { 0, 0, 0, RW_READER, 0 }, /* 0x4D 077 */ 4545331Samw { 0, 0, 0, RW_READER, 0 }, /* 0x4E 078 */ 4555331Samw { 0, 0, 0, RW_READER, 0 }, /* 0x4F 079 */ 4565331Samw { 0, 0, 0, RW_READER, 0 }, /* 0x50 080 */ 4575331Samw { 0, 0, 0, RW_READER, 0 }, /* 0x51 081 */ 4585331Samw { 0, 0, 0, RW_READER, 0 }, /* 0x52 082 */ 4595331Samw { 0, 0, 0, RW_READER, 0 }, /* 0x53 083 */ 4605331Samw { 0, 0, 0, RW_READER, 0 }, /* 0x54 084 */ 4615331Samw { 0, 0, 0, RW_READER, 0 }, /* 0x55 085 */ 4625331Samw { 0, 0, 0, RW_READER, 0 }, /* 0x56 086 */ 4635331Samw { 0, 0, 0, RW_READER, 0 }, /* 0x57 087 */ 4645331Samw { 0, 0, 0, RW_READER, 0 }, /* 0x58 088 */ 4655331Samw { 0, 0, 0, RW_READER, 0 }, /* 0x59 089 */ 4665331Samw { 0, 0, 0, RW_READER, 0 }, /* 0x5A 090 */ 4675331Samw { 0, 0, 0, RW_READER, 0 }, /* 0x5B 091 */ 4685331Samw { 0, 0, 0, RW_READER, 0 }, /* 0x5C 092 */ 4695331Samw { 0, 0, 0, RW_READER, 0 }, /* 0x5D 093 */ 4705331Samw { 0, 0, 0, RW_READER, 0 }, /* 0x5E 094 */ 4715331Samw { 0, 0, 0, RW_READER, 0 }, /* 0x5F 095 */ 4725331Samw { 0, 0, 0, RW_READER, 0 }, /* 0x60 096 */ 4735331Samw { 0, 0, 0, RW_READER, 0 }, /* 0x61 097 */ 4745331Samw { 0, 0, 0, RW_READER, 0 }, /* 0x62 098 */ 4755331Samw { 0, 0, 0, RW_READER, 0 }, /* 0x63 099 */ 4765331Samw { 0, 0, 0, RW_READER, 0 }, /* 0x64 100 */ 4775331Samw { 0, 0, 0, RW_READER, 0 }, /* 0x65 101 */ 4785331Samw { 0, 0, 0, RW_READER, 0 }, /* 0x66 102 */ 4795331Samw { 0, 0, 0, RW_READER, 0 }, /* 0x67 103 */ 4805331Samw { 0, 0, 0, RW_READER, 0 }, /* 0x68 104 */ 4815331Samw { 0, 0, 0, RW_READER, 0 }, /* 0x69 105 */ 4825331Samw { 0, 0, 0, RW_READER, 0 }, /* 0x6A 106 */ 4835331Samw { 0, 0, 0, RW_READER, 0 }, /* 0x6B 107 */ 4845331Samw { 0, 0, 0, RW_READER, 0 }, /* 0x6C 108 */ 4855331Samw { 0, 0, 0, RW_READER, 0 }, /* 0x6D 109 */ 4865331Samw { 0, 0, 0, RW_READER, 0 }, /* 0x6E 110 */ 4875331Samw { 0, 0, 0, RW_READER, 0 }, /* 0x6F 111 */ 4885331Samw { smb_com_tree_connect, /* 0x70 112 */ 4895331Samw PC_NETWORK_PROGRAM_1_0, SDDF_SUPPRESS_TID, 4905331Samw RW_READER, 4915331Samw { "SmbTreeConnect", KSTAT_DATA_UINT64 } }, 4925331Samw { smb_com_tree_disconnect, /* 0x71 113 */ 4935331Samw PC_NETWORK_PROGRAM_1_0, SDDF_SUPPRESS_TID | SDDF_SUPPRESS_UID, 4945331Samw RW_READER, 4955331Samw { "SmbTreeDisconnect", KSTAT_DATA_UINT64 } }, 4965331Samw { smb_com_negotiate, /* 0x72 114 */ 4975331Samw PC_NETWORK_PROGRAM_1_0, SDDF_SUPPRESS_TID | SDDF_SUPPRESS_UID, 4985331Samw RW_WRITER, 4995331Samw { "SmbNegotiate", KSTAT_DATA_UINT64 } }, 5005331Samw { smb_com_session_setup_andx, /* 0x73 115 */ 5015331Samw LANMAN1_0, SDDF_SUPPRESS_TID | SDDF_SUPPRESS_UID, 5025331Samw RW_READER, 5035331Samw { "SmbSessionSetupX", KSTAT_DATA_UINT64 } }, 5045331Samw { smb_com_logoff_andx, /* 0x74 116 */ 5055331Samw LM1_2X002, SDDF_SUPPRESS_TID, 5065331Samw RW_READER, 5075331Samw { "SmbLogoffX", KSTAT_DATA_UINT64 } }, 5085331Samw { smb_com_tree_connect_andx, /* 0x75 117 */ 5095331Samw LANMAN1_0, SDDF_SUPPRESS_TID, 5105331Samw RW_READER, 5115331Samw { "SmbTreeConnectX", KSTAT_DATA_UINT64 } }, 5125331Samw { 0, 0, 0, RW_READER, 0 }, /* 0x76 118 */ 5135331Samw { 0, 0, 0, RW_READER, 0 }, /* 0x77 119 */ 5145331Samw { 0, 0, 0, RW_READER, 0 }, /* 0x78 120 */ 5155331Samw { 0, 0, 0, RW_READER, 0 }, /* 0x79 121 */ 5165331Samw { 0, 0, 0, RW_READER, 0 }, /* 0x7A 122 */ 5175331Samw { 0, 0, 0, RW_READER, 0 }, /* 0x7B 123 */ 5185331Samw { 0, 0, 0, RW_READER, 0 }, /* 0x7C 124 */ 5195331Samw { 0, 0, 0, RW_READER, 0 }, /* 0x7D 125 */ 5205331Samw { 0, 0, 0, RW_READER, 0 }, /* 0x7E 126 */ 5215331Samw { 0, 0, 0, RW_READER, 0 }, /* 0x7F 127 */ 5225331Samw { smb_com_query_information_disk, /* 0x80 128 */ 5235331Samw PC_NETWORK_PROGRAM_1_0, SDDF_NO_FLAGS, 5245331Samw RW_READER, 5255331Samw { "SmbQueryInformationDisk", KSTAT_DATA_UINT64 } }, 5265331Samw { smb_com_search, /* 0x81 129 */ 5275331Samw PC_NETWORK_PROGRAM_1_0, SDDF_NO_FLAGS, 5285331Samw RW_READER, 5295331Samw { "SmbSearch", KSTAT_DATA_UINT64 } }, 5305331Samw { smb_com_find, /* 0x82 130 */ 5315331Samw LANMAN1_0, SDDF_NO_FLAGS, 5325331Samw RW_READER, 5335331Samw { "SmbFind", KSTAT_DATA_UINT64 } }, 5345331Samw { smb_com_find_unique, /* 0x83 131 */ 5355331Samw LANMAN1_0, SDDF_NO_FLAGS, 5365331Samw RW_READER, 5375331Samw { "SmbFindUnique", KSTAT_DATA_UINT64 } }, 5385331Samw { smb_com_find_close, /* 0x84 132 */ 5395331Samw LANMAN1_0, SDDF_NO_FLAGS, 5405331Samw RW_READER, 5415331Samw { "SmbFindClose", KSTAT_DATA_UINT64 } }, 5425331Samw { 0, 0, 0, RW_READER, 0 }, /* 0x85 133 */ 5435331Samw { 0, 0, 0, RW_READER, 0 }, /* 0x86 134 */ 5445331Samw { 0, 0, 0, RW_READER, 0 }, /* 0x87 135 */ 5455331Samw { 0, 0, 0, RW_READER, 0 }, /* 0x88 136 */ 5465331Samw { 0, 0, 0, RW_READER, 0 }, /* 0x89 137 */ 5475331Samw { 0, 0, 0, RW_READER, 0 }, /* 0x8A 138 */ 5485331Samw { 0, 0, 0, RW_READER, 0 }, /* 0x8B 139 */ 5495331Samw { 0, 0, 0, RW_READER, 0 }, /* 0x8C 140 */ 5505331Samw { 0, 0, 0, RW_READER, 0 }, /* 0x8D 141 */ 5515331Samw { 0, 0, 0, RW_READER, 0 }, /* 0x8E 142 */ 5525331Samw { 0, 0, 0, RW_READER, 0 }, /* 0x8F 143 */ 5535331Samw { 0, 0, 0, RW_READER, 0 }, /* 0x90 144 */ 5545331Samw { 0, 0, 0, RW_READER, 0 }, /* 0x91 145 */ 5555331Samw { 0, 0, 0, RW_READER, 0 }, /* 0x92 146 */ 5565331Samw { 0, 0, 0, RW_READER, 0 }, /* 0x93 147 */ 5575331Samw { 0, 0, 0, RW_READER, 0 }, /* 0x94 148 */ 5585331Samw { 0, 0, 0, RW_READER, 0 }, /* 0x95 149 */ 5595331Samw { 0, 0, 0, RW_READER, 0 }, /* 0x96 150 */ 5605331Samw { 0, 0, 0, RW_READER, 0 }, /* 0x97 151 */ 5615331Samw { 0, 0, 0, RW_READER, 0 }, /* 0x98 152 */ 5625331Samw { 0, 0, 0, RW_READER, 0 }, /* 0x99 153 */ 5635331Samw { 0, 0, 0, RW_READER, 0 }, /* 0x9A 154 */ 5645331Samw { 0, 0, 0, RW_READER, 0 }, /* 0x9B 155 */ 5655331Samw { 0, 0, 0, RW_READER, 0 }, /* 0x9C 156 */ 5665331Samw { 0, 0, 0, RW_READER, 0 }, /* 0x9D 157 */ 5675331Samw { 0, 0, 0, RW_READER, 0 }, /* 0x9E 158 */ 5685331Samw { 0, 0, 0, RW_READER, 0 }, /* 0x9F 159 */ 5695331Samw { smb_com_nt_transact, /* 0xA0 160 */ 5705331Samw NT_LM_0_12, SDDF_NO_FLAGS, 5715331Samw RW_READER, 5725331Samw { "SmbNtTransact", KSTAT_DATA_UINT64 } }, 5735331Samw { smb_com_nt_transact_secondary, /* 0xA1 161 */ 5745331Samw NT_LM_0_12, SDDF_NO_FLAGS, 5755331Samw RW_READER, 5765331Samw { "SmbNtTransactSecondary", KSTAT_DATA_UINT64 } }, 5775331Samw { smb_com_nt_create_andx, /* 0xA2 162 */ 5785331Samw NT_LM_0_12, SDDF_NO_FLAGS, 5795331Samw RW_READER, 5805331Samw { "SmbNtCreateX", KSTAT_DATA_UINT64 } }, 5815331Samw { 0, 0, 0, 0, 0 }, /* 0xA3 163 */ 5825331Samw { smb_com_nt_cancel, /* 0xA4 164 */ 5835331Samw NT_LM_0_12, SDDF_NO_FLAGS, 5845331Samw RW_READER, 5855331Samw { "SmbNtCancel", KSTAT_DATA_UINT64 } }, 5865331Samw { 0, 0, 0, RW_READER, 0 }, /* 0xA5 165 */ 5875331Samw { 0, 0, 0, RW_READER, 0 }, /* 0xA6 166 */ 5885331Samw { 0, 0, 0, RW_READER, 0 }, /* 0xA7 167 */ 5895331Samw { 0, 0, 0, RW_READER, 0 }, /* 0xA8 168 */ 5905331Samw { 0, 0, 0, RW_READER, 0 }, /* 0xA9 169 */ 5915331Samw { 0, 0, 0, RW_READER, 0 }, /* 0xAA 170 */ 5925331Samw { 0, 0, 0, RW_READER, 0 }, /* 0xAB 171 */ 5935331Samw { 0, 0, 0, RW_READER, 0 }, /* 0xAC 172 */ 5945331Samw { 0, 0, 0, RW_READER, 0 }, /* 0xAD 173 */ 5955331Samw { 0, 0, 0, RW_READER, 0 }, /* 0xAE 174 */ 5965331Samw { 0, 0, 0, RW_READER, 0 }, /* 0xAF 175 */ 5975331Samw { 0, 0, 0, RW_READER, 0 }, /* 0xB0 176 */ 5985331Samw { 0, 0, 0, RW_READER, 0 }, /* 0xB1 177 */ 5995331Samw { 0, 0, 0, RW_READER, 0 }, /* 0xB2 178 */ 6005331Samw { 0, 0, 0, RW_READER, 0 }, /* 0xB3 179 */ 6015331Samw { 0, 0, 0, RW_READER, 0 }, /* 0xB4 180 */ 6025331Samw { 0, 0, 0, RW_READER, 0 }, /* 0xB5 181 */ 6035331Samw { 0, 0, 0, RW_READER, 0 }, /* 0xB6 182 */ 6045331Samw { 0, 0, 0, RW_READER, 0 }, /* 0xB7 183 */ 6055331Samw { 0, 0, 0, RW_READER, 0 }, /* 0xB8 184 */ 6065331Samw { 0, 0, 0, RW_READER, 0 }, /* 0xB9 185 */ 6075331Samw { 0, 0, 0, RW_READER, 0 }, /* 0xBA 186 */ 6085331Samw { 0, 0, 0, RW_READER, 0 }, /* 0xBB 187 */ 6095331Samw { 0, 0, 0, RW_READER, 0 }, /* 0xBC 188 */ 6105331Samw { 0, 0, 0, RW_READER, 0 }, /* 0xBD 189 */ 6115331Samw { 0, 0, 0, RW_READER, 0 }, /* 0xBE 190 */ 6125331Samw { 0, 0, 0, RW_READER, 0 }, /* 0xBF 191 */ 6135331Samw { smb_com_open_print_file, /* 0xC0 192 */ 6145331Samw PC_NETWORK_PROGRAM_1_0, SDDF_NO_FLAGS, 6155331Samw RW_READER, 6165331Samw { "SmbOpenPrintFile", KSTAT_DATA_UINT64 } }, 6175331Samw { smb_com_write_print_file, /* 0xC1 193 */ 6185331Samw PC_NETWORK_PROGRAM_1_0, SDDF_SUPPRESS_SHOW, 6195331Samw RW_READER, 6205331Samw { "SmbWritePrintFile", KSTAT_DATA_UINT64 } }, 6215331Samw { smb_com_close_print_file, /* 0xC2 194 */ 6225331Samw PC_NETWORK_PROGRAM_1_0, SDDF_NO_FLAGS, 6235331Samw RW_READER, 6245331Samw { "SmbClosePrintFile", KSTAT_DATA_UINT64 } }, 6255331Samw { smb_com_get_print_queue, /* 0xC3 195 */ 6265331Samw PC_NETWORK_PROGRAM_1_0, SDDF_NO_FLAGS, 6275331Samw RW_READER, 6285331Samw { "SmbGetPrintQueue", KSTAT_DATA_UINT64 } }, 6295331Samw { 0, 0, 0, RW_READER, 0 }, /* 0xC4 196 */ 6305331Samw { 0, 0, 0, RW_READER, 0 }, /* 0xC5 197 */ 6315331Samw { 0, 0, 0, RW_READER, 0 }, /* 0xC6 198 */ 6325331Samw { 0, 0, 0, RW_READER, 0 }, /* 0xC7 199 */ 6335331Samw { 0, 0, 0, RW_READER, 0 }, /* 0xC8 200 */ 6345331Samw { 0, 0, 0, RW_READER, 0 }, /* 0xC9 201 */ 6355331Samw { 0, 0, 0, RW_READER, 0 }, /* 0xCA 202 */ 6365331Samw { 0, 0, 0, RW_READER, 0 }, /* 0xCB 203 */ 6375331Samw { 0, 0, 0, RW_READER, 0 }, /* 0xCC 204 */ 6385331Samw { 0, 0, 0, RW_READER, 0 }, /* 0xCD 205 */ 6395331Samw { 0, 0, 0, RW_READER, 0 }, /* 0xCE 206 */ 6405331Samw { 0, 0, 0, RW_READER, 0 }, /* 0xCF 207 */ 6415331Samw { smb_com_send_single_message, /* 0xD0 208 */ 6425331Samw PC_NETWORK_PROGRAM_1_0, SDDF_NO_FLAGS, 6435331Samw RW_READER, 6445331Samw { "SmbSendSingleMessage", KSTAT_DATA_UINT64 } }, 6455331Samw { smb_com_send_broadcast_message, /* 0xD1 209 */ 6465331Samw PC_NETWORK_PROGRAM_1_0, SDDF_NO_FLAGS, 6475331Samw RW_READER, 6485331Samw { "SmbSendBroadcastMessage", KSTAT_DATA_UINT64 } }, 6495331Samw { smb_com_forward_user_name, /* 0xD2 210 */ 6505331Samw PC_NETWORK_PROGRAM_1_0, SDDF_NO_FLAGS, 6515331Samw RW_READER, 6525331Samw { "SmbForwardUserName", KSTAT_DATA_UINT64 } }, 6535331Samw { smb_com_cancel_forward, /* 0xD3 211 */ 6545331Samw PC_NETWORK_PROGRAM_1_0, SDDF_NO_FLAGS, 6555331Samw RW_READER, 6565331Samw { "SmbCancelForward", KSTAT_DATA_UINT64 } }, 6575331Samw { smb_com_get_machine_name, /* 0xD4 212 */ 6585331Samw PC_NETWORK_PROGRAM_1_0, SDDF_NO_FLAGS, 6595331Samw RW_READER, 6605331Samw { "SmbGetMachineName", KSTAT_DATA_UINT64 } }, 6615331Samw { smb_com_send_start_mb_message, /* 0xD5 213 */ 6625331Samw PC_NETWORK_PROGRAM_1_0, SDDF_NO_FLAGS, 6635331Samw RW_READER, 6645331Samw { "SmbSendStartMbMessage", KSTAT_DATA_UINT64 } }, 6655331Samw { smb_com_send_end_mb_message, /* 0xD6 214 */ 6665331Samw PC_NETWORK_PROGRAM_1_0, SDDF_NO_FLAGS, 6675331Samw RW_READER, 6685331Samw { "SmbSendEndMbMessage", KSTAT_DATA_UINT64 } }, 6695331Samw { smb_com_send_text_mb_message, /* 0xD7 215 */ 6705331Samw PC_NETWORK_PROGRAM_1_0, SDDF_NO_FLAGS, 6715331Samw RW_READER, 6725331Samw { "SmbSendTextMbMessage", KSTAT_DATA_UINT64 } }, 6735331Samw { 0, 0, 0, RW_READER, 0 }, /* 0xD8 216 */ 6745331Samw { 0, 0, 0, RW_READER, 0 }, /* 0xD9 217 */ 6755331Samw { 0, 0, 0, RW_READER, 0 }, /* 0xDA 218 */ 6765331Samw { 0, 0, 0, RW_READER, 0 }, /* 0xDB 219 */ 6775331Samw { 0, 0, 0, RW_READER, 0 }, /* 0xDC 220 */ 6785331Samw { 0, 0, 0, RW_READER, 0 }, /* 0xDD 221 */ 6795331Samw { 0, 0, 0, RW_READER, 0 }, /* 0xDE 222 */ 6805331Samw { 0, 0, 0, RW_READER, 0 }, /* 0xDF 223 */ 6815331Samw { 0, 0, 0, RW_READER, 0 }, /* 0xE0 224 */ 6825331Samw { 0, 0, 0, RW_READER, 0 }, /* 0xE1 225 */ 6835331Samw { 0, 0, 0, RW_READER, 0 }, /* 0xE2 226 */ 6845331Samw { 0, 0, 0, RW_READER, 0 }, /* 0xE3 227 */ 6855331Samw { 0, 0, 0, RW_READER, 0 }, /* 0xE4 228 */ 6865331Samw { 0, 0, 0, RW_READER, 0 }, /* 0xE5 229 */ 6875331Samw { 0, 0, 0, RW_READER, 0 }, /* 0xE6 230 */ 6885331Samw { 0, 0, 0, RW_READER, 0 }, /* 0xE7 231 */ 6895331Samw { 0, 0, 0, RW_READER, 0 }, /* 0xE8 232 */ 6905331Samw { 0, 0, 0, RW_READER, 0 }, /* 0xE9 233 */ 6915331Samw { 0, 0, 0, RW_READER, 0 }, /* 0xEA 234 */ 6925331Samw { 0, 0, 0, RW_READER, 0 }, /* 0xEB 235 */ 6935331Samw { 0, 0, 0, RW_READER, 0 }, /* 0xEC 236 */ 6945331Samw { 0, 0, 0, RW_READER, 0 }, /* 0xED 237 */ 6955331Samw { 0, 0, 0, RW_READER, 0 }, /* 0xEE 238 */ 6965331Samw { 0, 0, 0, RW_READER, 0 }, /* 0xEF 239 */ 6975331Samw { 0, 0, 0, RW_READER, 0 }, /* 0xF0 240 */ 6985331Samw { 0, 0, 0, RW_READER, 0 }, /* 0xF1 241 */ 6995331Samw { 0, 0, 0, RW_READER, 0 }, /* 0xF2 242 */ 7005331Samw { 0, 0, 0, RW_READER, 0 }, /* 0xF3 243 */ 7015331Samw { 0, 0, 0, RW_READER, 0 }, /* 0xF4 244 */ 7025331Samw { 0, 0, 0, RW_READER, 0 }, /* 0xF5 245 */ 7035331Samw { 0, 0, 0, RW_READER, 0 }, /* 0xF6 246 */ 7045331Samw { 0, 0, 0, RW_READER, 0 }, /* 0xF7 247 */ 7055331Samw { 0, 0, 0, RW_READER, 0 }, /* 0xF8 248 */ 7065331Samw { 0, 0, 0, RW_READER, 0 }, /* 0xF9 249 */ 7075331Samw { 0, 0, 0, RW_READER, 0 }, /* 0xFA 250 */ 7085331Samw { 0, 0, 0, RW_READER, 0 }, /* 0xFB 251 */ 7095331Samw { 0, 0, 0, RW_READER, 0 }, /* 0xFC 252 */ 7105331Samw { 0, 0, 0, RW_READER, 0 }, /* 0xFD 253 */ 7115331Samw { smb_com_invalid_command, /* 0xFE 254 */ 7125331Samw LANMAN1_0, SDDF_NO_FLAGS, 7135331Samw RW_READER, 7145331Samw { "SmbInvalidCommand", KSTAT_DATA_UINT64 } }, 7155331Samw { 0, 0, 0, RW_READER, 0 } /* 0xFF 255 */ 7165331Samw }; 7175331Samw 7185331Samw int smb_watch = -1; 7195331Samw int smb_emit_sending = 0; 7205331Samw 7215331Samw /* 7225331Samw * smbsr_cleanup 7235331Samw * 7245331Samw * If any user/tree/file is used by given request then 7255331Samw * the reference count for that resource has been incremented. 7265331Samw * This function decrements the reference count and close 7275331Samw * the resource if it's needed. 7285331Samw */ 7295331Samw 7305331Samw void 7315331Samw smbsr_cleanup(struct smb_request *sr) 7325331Samw { 7335331Samw ASSERT((sr->sr_state != SMB_REQ_STATE_CLEANED_UP) && 7345331Samw (sr->sr_state != SMB_REQ_STATE_COMPLETED)); 7355331Samw 7365331Samw if (sr->fid_ofile) 7375331Samw smbsr_disconnect_file(sr); 7385331Samw 7395331Samw if (sr->sid_odir) 7405331Samw smbsr_disconnect_dir(sr); 7415331Samw 7425331Samw if (sr->tid_tree) { 7435331Samw smb_tree_release(sr->tid_tree); 7445331Samw sr->tid_tree = NULL; 7455331Samw } 7465331Samw 7475331Samw if (sr->uid_user) { 7485331Samw smb_user_release(sr->uid_user); 7495331Samw sr->uid_user = NULL; 7505331Samw } 7515331Samw 7525331Samw if (sr->r_xa) { 7535331Samw if (sr->r_xa->xa_flags & SMB_XA_FLAG_COMPLETE) 7545331Samw smb_xa_close(sr->r_xa); 7555331Samw smb_xa_rele(sr->session, sr->r_xa); 7565331Samw sr->r_xa = NULL; 7575331Samw } 7585331Samw 7595331Samw /* 7605331Samw * Mark this request so we know that we've already cleaned it up. 7615331Samw * A request should only get cleaned up once so multiple calls to 7625331Samw * smbsr_cleanup for the same request indicate a bug. 7635331Samw */ 7645331Samw mutex_enter(&sr->sr_mutex); 7655331Samw if (sr->sr_state != SMB_REQ_STATE_CANCELED) 7665331Samw sr->sr_state = SMB_REQ_STATE_CLEANED_UP; 7675331Samw mutex_exit(&sr->sr_mutex); 7685331Samw } 7695331Samw 7705331Samw int 7715331Samw smb_dispatch_request(struct smb_request *sr) 7725331Samw { 7735331Samw int rc; 7745331Samw smb_dispatch_table_t *sdd; 775*5772Sas200622 smb_error_t err; 7765331Samw 7775331Samw ASSERT(sr->tid_tree == 0); 7785331Samw ASSERT(sr->uid_user == 0); 7795331Samw ASSERT(sr->fid_ofile == 0); 7805331Samw ASSERT(sr->sid_odir == 0); 7815331Samw sr->smb_fid = (uint16_t)-1; 7825331Samw sr->smb_sid = (uint16_t)-1; 7835331Samw 7845331Samw /* temporary until we identify a user */ 7855331Samw sr->user_cr = kcred; 7865331Samw sr->orig_request_hdr = sr->command.chain_offset; 7875331Samw 7885331Samw /* If this connection is shutting down just kill request */ 7895331Samw if (smb_decode_mbc(&sr->command, SMB_HEADER_ED_FMT, 7905331Samw &sr->smb_com, 7915331Samw &sr->smb_rcls, 7925331Samw &sr->smb_reh, 7935331Samw &sr->smb_err, 7945331Samw &sr->smb_flg, 7955331Samw &sr->smb_flg2, 7965331Samw &sr->smb_pid_high, 7975331Samw sr->smb_sig, 7985331Samw &sr->smb_tid, 7995331Samw &sr->smb_pid, 8005331Samw &sr->smb_uid, 8015331Samw &sr->smb_mid) != 0) { 8025331Samw return (-1); 8035331Samw } 8045331Samw 8055331Samw /* 8065331Samw * The reply "header" is filled in now even though 8075331Samw * it most likely will be rewritten under reply_ready: 8085331Samw * below. Could just reserve the space. But this 8095331Samw * (for now) is convenient incase the dialect dispatcher 8105331Samw * has to send a special reply (like TRANSACT). 8115331Samw * 8125331Samw * Ensure that the 32-bit error code flag is turned off. 8135331Samw * Clients seem to set it in transact requests and they may 8145331Samw * get confused if we return success or a 16-bit SMB code. 8155331Samw */ 8165331Samw sr->smb_rcls = 0; 8175331Samw sr->smb_reh = 0; 8185331Samw sr->smb_err = 0; 8195331Samw sr->smb_flg2 &= ~SMB_FLAGS2_NT_STATUS; 8205331Samw 8215331Samw (void) smb_encode_mbc(&sr->reply, SMB_HEADER_ED_FMT, 8225331Samw sr->smb_com, 8235331Samw sr->smb_rcls, 8245331Samw sr->smb_reh, 8255331Samw sr->smb_err, 8265331Samw sr->smb_flg, 8275331Samw sr->smb_flg2, 8285331Samw sr->smb_pid_high, 8295331Samw sr->smb_sig, 8305331Samw sr->smb_tid, 8315331Samw sr->smb_pid, 8325331Samw sr->smb_uid, 8335331Samw sr->smb_mid); 8345331Samw sr->first_smb_com = sr->smb_com; 8355331Samw 8365331Samw /* 837*5772Sas200622 * Verify SMB signature if signing is enabled, dialect is NT LM 0.12, 8385331Samw * signing was negotiated and authentication has occurred. 8395331Samw */ 8405331Samw if (sr->session->signing.flags & SMB_SIGNING_ENABLED) { 8415331Samw if (smb_sign_check_request(sr) != 0) { 842*5772Sas200622 err.severity = ERROR_SEVERITY_ERROR; 843*5772Sas200622 err.status = NT_STATUS_ACCESS_DENIED; 844*5772Sas200622 err.errcls = ERRDOS; 845*5772Sas200622 err.errcode = ERROR_ACCESS_DENIED; 846*5772Sas200622 smbsr_set_error(sr, &err); 8475331Samw rc = -1; 8485331Samw smb_rwx_rwenter(&sr->session->s_lock, RW_READER); 8495331Samw goto reply_error; 8505331Samw } 8515331Samw } 8525331Samw 8535331Samw andx_more: 8545331Samw sdd = &dispatch[sr->smb_com]; 8555331Samw 8565331Samw smb_rwx_rwenter(&sr->session->s_lock, sdd->sdt_slock_mode); 8575331Samw 8585331Samw if (smb_decode_mbc(&sr->command, "b", &sr->smb_wct) != 0) { 8595331Samw rc = -3; 8605331Samw goto cant_decode; 8615331Samw } 8625331Samw 8635331Samw (void) MBC_SHADOW_CHAIN(&sr->smb_vwv, &sr->command, 8645331Samw sr->command.chain_offset, sr->smb_wct * 2); 8655331Samw 8665331Samw if (smb_decode_mbc(&sr->command, "#.w", 8675331Samw sr->smb_wct*2, &sr->smb_bcc) != 0) { 8685331Samw rc = -5; 8695331Samw goto cant_decode; 8705331Samw } 8715331Samw 8725331Samw (void) MBC_SHADOW_CHAIN(&sr->smb_data, &sr->command, 8735331Samw sr->command.chain_offset, sr->smb_bcc); 8745331Samw 8755331Samw sr->command.chain_offset += sr->smb_bcc; 8765331Samw if (sr->command.chain_offset > sr->command.max_bytes) { 8775331Samw rc = -6; 8785331Samw goto cant_decode; 8795331Samw } 8805331Samw 8815331Samw /* Store pointers for later */ 8825331Samw sr->cur_reply_offset = sr->reply.chain_offset; 8835331Samw 8845331Samw if (is_andx_com(sr->smb_com)) { 8855331Samw /* Peek ahead and don't disturb vwv */ 8865331Samw if (smb_peek_mbc(&sr->smb_vwv, sr->smb_vwv.chain_offset, "b.w", 8875331Samw &sr->andx_com, &sr->andx_off) < 0) { 8885331Samw rc = -7; 8895331Samw goto cant_decode; 8905331Samw } 8915331Samw } else { 8925331Samw sr->andx_com = (unsigned char)-1; 8935331Samw } 8945331Samw 8955331Samw mutex_enter(&sr->sr_mutex); 8965331Samw switch (sr->sr_state) { 8975331Samw case SMB_REQ_STATE_SUBMITTED: 8985331Samw case SMB_REQ_STATE_CLEANED_UP: 8995331Samw sr->sr_state = SMB_REQ_STATE_ACTIVE; 9005331Samw break; 9015331Samw case SMB_REQ_STATE_CANCELED: 9025331Samw break; 9035331Samw default: 9045331Samw ASSERT(0); 9055331Samw break; 9065331Samw } 9075331Samw mutex_exit(&sr->sr_mutex); 9085331Samw 9095331Samw if (sdd->sdt_function) { 9105331Samw 9115331Samw if ((rc = setjmp(&sr->exjb))) { 9125331Samw /* 9135331Samw * Handle any errors from raw write. 9145331Samw */ 9155331Samw if (sr->session->s_state == 9165331Samw SMB_SESSION_STATE_WRITE_RAW_ACTIVE) { 9175331Samw /* 9185331Samw * Set state so that the netbios session 9195331Samw * daemon will start accepting data again. 9205331Samw */ 9215331Samw sr->session->s_write_raw_status = 0; 9225331Samw sr->session->s_state = 9235331Samw SMB_SESSION_STATE_NEGOTIATED; 9245331Samw } 9255331Samw 9265331Samw /* 9275331Samw * We should never have sr->sr_keep set here 9285331Samw * since this is the error path. 9295331Samw */ 9305331Samw ASSERT(sr->sr_keep == 0); 9315331Samw 9325331Samw smbsr_cleanup(sr); 9335331Samw 9345331Samw if (sr->smb_com == smb_watch) { 9355331Samw smb_emit_sending = 1; 9365331Samw } 9375331Samw if (rc < 0) { 9385331Samw rc -= 1000; 9395331Samw goto cant_decode; 9405331Samw } 9415331Samw goto reply_error; 9425331Samw } 9435331Samw 9445331Samw /* 9455331Samw * Setup UID and TID information (if required). Both functions 9465331Samw * will set the sr credentials. In domain mode, the user and 9475331Samw * tree credentials should be the same. In share mode, the 9485331Samw * tree credentials (defined in the share definition) should 9495331Samw * override the user credentials. 9505331Samw */ 9515331Samw if (!(sdd->sdt_flags & SDDF_SUPPRESS_UID)) { 9525331Samw sr->uid_user = smb_user_lookup_by_uid(sr->session, 9535331Samw &sr->user_cr, sr->smb_uid); 9545331Samw if (sr->uid_user == NULL) { 955*5772Sas200622 smbsr_error(sr, 0, ERRSRV, ERRbaduid); 9565331Samw /* NOTREACHED */ 9575331Samw } 9585331Samw if (!(sdd->sdt_flags & SDDF_SUPPRESS_TID)) { 9595331Samw sr->tid_tree = smb_tree_lookup_by_tid( 9605331Samw sr->uid_user, sr->smb_tid); 9615331Samw if (sr->tid_tree == NULL) { 962*5772Sas200622 smbsr_error(sr, 0, ERRSRV, ERRinvnid); 9635331Samw /* NOTREACHED */ 9645331Samw } 9655331Samw } 9665331Samw } 9675331Samw 9685331Samw /* 9695331Samw * If the command is not a read raw request we can set the 9705331Samw * state of the session back to SMB_SESSION_STATE_NEGOTIATED 9715331Samw * (if the current state is SMB_SESSION_STATE_OPLOCK_BREAKING). 9725331Samw * Otherwise we let the read raw handler to deal with it. 9735331Samw */ 9745331Samw if ((sr->session->s_state == 9755331Samw SMB_SESSION_STATE_OPLOCK_BREAKING) && 9765331Samw (sr->smb_com != SMB_COM_READ_RAW)) { 9775331Samw krw_t mode; 9785331Samw /* 9795331Samw * The lock may have to be upgraded because, at this 9805331Samw * point, we don't know how it was entered. We just 9815331Samw * know that it has to be entered in writer mode here. 9825331Samw * Whatever mode was used to enter the lock, it will 9835331Samw * be restored. 9845331Samw */ 9855331Samw mode = smb_rwx_rwupgrade(&sr->session->s_lock); 9865331Samw if (sr->session->s_state == 9875331Samw SMB_SESSION_STATE_OPLOCK_BREAKING) { 9885331Samw sr->session->s_state = 9895331Samw SMB_SESSION_STATE_NEGOTIATED; 9905331Samw } 9915331Samw smb_rwx_rwdowngrade(&sr->session->s_lock, mode); 9925331Samw } 9935331Samw 9945331Samw DTRACE_PROBE1(smb__dispatch__com, struct smb_request_t *, sr); 9955331Samw 9965331Samw /* 9975331Samw * Increment method invocation count. This value is exposed 9985331Samw * via kstats, and it represents a count of all the dispatched 9995331Samw * requests, including the ones that have a return value, other 10005331Samw * than SDRC_NORMAL_REPLY. 10015331Samw */ 10025331Samw SMB_ALL_DISPATCH_STAT_INCR(sdd->sdt_dispatch_stats.value.ui64); 10035331Samw 10045331Samw rc = (*sdd->sdt_function)(sr); 10055331Samw 10065331Samw /* 10075331Samw * Only call smbsr_cleanup if smb->sr_keep is not set. The 10085331Samw * smb_nt_transact_notify_change function will set 10095331Samw * smb->sr_keep if it retains control of the request when 10105331Samw * it returns. In that case the notify change code 10115331Samw * will call smbsr_cleanup later when the request is finally 10125331Samw * completed. 10135331Samw */ 10145331Samw if (sr->sr_keep == 0) 10155331Samw smbsr_cleanup(sr); 10165331Samw } else { 10175331Samw rc = SDRC_UNIMPLEMENTED; /* Unknown? */ 10185331Samw } 10195331Samw 10205331Samw if (rc != SDRC_NORMAL_REPLY) { /* normal case special & fast */ 10215331Samw switch (rc) { 10225331Samw case SDRC_NORMAL_REPLY: 10235331Samw break; 10245331Samw 10255331Samw case SDRC_ERROR_REPLY: 10265331Samw goto reply_error; 10275331Samw 10285331Samw case SDRC_DROP_VC: 10295331Samw switch (sr->session->s_state) { 10305331Samw case SMB_SESSION_STATE_DISCONNECTED: 10315331Samw case SMB_SESSION_STATE_TERMINATED: 10325331Samw break; 10335331Samw default: 10345331Samw smb_soshutdown(sr->session->sock); 10355331Samw break; 10365331Samw } 10375331Samw goto reply_error; 10385331Samw 10395331Samw case SDRC_NO_REPLY: 10405331Samw /* tricky. */ 10415331Samw smb_rwx_rwexit(&sr->session->s_lock); 10425331Samw return (0); 10435331Samw 10445331Samw case SDRC_UNIMPLEMENTED: 10455331Samw sr->smb_rcls = ERRDOS; 10465331Samw sr->smb_err = ERRbadfunc; 10475331Samw goto reply_error; 10485331Samw 10495331Samw default: 10505331Samw sr->smb_rcls = ERRDOS; 10515331Samw sr->smb_err = ERRerror; /* need better */ 10525331Samw goto reply_error; 10535331Samw } 10545331Samw } 10555331Samw 10565331Samw if (sr->andx_com == 0xff) 10575331Samw goto reply_ready; 10585331Samw 10595331Samw /* have to back-patch the AndXCommand and AndXOffset */ 10605331Samw sr->andx_prev_wct = sr->cur_reply_offset; 10615331Samw (void) smb_poke_mbc(&sr->reply, sr->andx_prev_wct + 1, "b.w", 10625331Samw sr->andx_com, MBC_LENGTH(&sr->reply)); 10635331Samw 10645331Samw smb_rwx_rwexit(&sr->session->s_lock); 10655331Samw 10665331Samw /* now it gets interesting */ 10675331Samw sr->command.chain_offset = sr->orig_request_hdr + sr->andx_off; 10685331Samw 10695331Samw sr->smb_com = sr->andx_com; 10705331Samw 10715331Samw goto andx_more; 10725331Samw 10735331Samw reply_ready: 10745331Samw 10755331Samw if (SMB_TREE_CASE_INSENSITIVE(sr)) { 10765331Samw sr->smb_flg |= SMB_FLAGS_CASE_INSENSITIVE; 10775331Samw } else { 10785331Samw sr->smb_flg &= ~SMB_FLAGS_CASE_INSENSITIVE; 10795331Samw } 10805331Samw 10815331Samw (void) smb_poke_mbc(&sr->reply, 0, SMB_HEADER_ED_FMT, 10825331Samw sr->first_smb_com, 10835331Samw sr->smb_rcls, 10845331Samw sr->smb_reh, 10855331Samw sr->smb_err, 10865331Samw sr->smb_flg | SMB_FLAGS_REPLY, 10875331Samw sr->smb_flg2, 10885331Samw sr->smb_pid_high, 10895331Samw sr->smb_sig, 10905331Samw sr->smb_tid, 10915331Samw sr->smb_pid, 10925331Samw sr->smb_uid, 10935331Samw sr->smb_mid); 10945331Samw 10955331Samw if (sr->session->signing.flags & SMB_SIGNING_ENABLED) 10965331Samw smb_sign_reply(sr, NULL); 10975331Samw 10985331Samw if ((rc = smb_session_send(sr->session, 0, &sr->reply)) == 0) 10995331Samw sr->reply.chain = 0; 11005331Samw 11015331Samw smb_rwx_rwexit(&sr->session->s_lock); 11025331Samw 11035331Samw return (rc); 11045331Samw 11055331Samw cant_decode: 11065331Samw reply_error: 11075331Samw sr->reply.chain_offset = sr->cur_reply_offset; 11085331Samw (void) smb_encode_mbc(&sr->reply, "bw", 0, 0); 11095331Samw 11105331Samw sr->smb_wct = 0; 11115331Samw sr->smb_bcc = 0; 11125331Samw 11135331Samw if (sr->smb_rcls == 0) { 11145331Samw sr->smb_rcls = ERRSRV; 11155331Samw sr->smb_err = ERRerror; 11165331Samw } 11175331Samw goto reply_ready; 11185331Samw } 11195331Samw 11205331Samw 11215331Samw void 11225331Samw smbsr_encode_result(struct smb_request *sr, int wct, 11235331Samw int bcc, char *fmt, ...) 11245331Samw { 11255331Samw va_list ap; 11265331Samw 11275331Samw if (MBC_LENGTH(&sr->reply) != sr->cur_reply_offset) { 11285331Samw smbsr_encode_error(sr); 11295331Samw } 11305331Samw 11315331Samw va_start(ap, fmt); 11325331Samw (void) smb_mbc_encode(&sr->reply, fmt, ap); 11335331Samw va_end(ap); 11345331Samw 11355331Samw sr->smb_wct = (unsigned char)wct; 11365331Samw sr->smb_bcc = (uint16_t)bcc; 11375331Samw 11385331Samw smbsr_check_result(sr, wct, bcc); 11395331Samw } 11405331Samw 11415331Samw void 11425331Samw smbsr_check_result(struct smb_request *sr, int wct, int bcc) 11435331Samw { 11445331Samw int offset = sr->cur_reply_offset; 11455331Samw int total_bytes; 11465331Samw unsigned char temp, temp1; 11475331Samw struct mbuf *m; 11485331Samw 11495331Samw total_bytes = 0; 11505331Samw m = sr->reply.chain; 11515331Samw while (m != 0) { 11525331Samw total_bytes += m->m_len; 11535331Samw m = m->m_next; 11545331Samw } 11555331Samw 11565331Samw if ((offset + 3) > total_bytes) { 11575331Samw smbsr_encode_error(sr); 11585331Samw /* NOTREACHED */ 11595331Samw } 11605331Samw 11615331Samw (void) smb_peek_mbc(&sr->reply, offset, "b", &temp); 11625331Samw if (temp != wct) { 11635331Samw smbsr_encode_error(sr); 11645331Samw /* NOTREACHED */ 11655331Samw } 11665331Samw 11675331Samw if ((offset + (wct * 2 + 1)) > total_bytes) { 11685331Samw smbsr_encode_error(sr); 11695331Samw /* NOTREACHED */ 11705331Samw } 11715331Samw 11725331Samw /* reply wct & vwv seem ok, consider data now */ 11735331Samw offset += wct * 2 + 1; 11745331Samw 11755331Samw if ((offset + 2) > total_bytes) { 11765331Samw smbsr_encode_error(sr); 11775331Samw } 11785331Samw 11795331Samw (void) smb_peek_mbc(&sr->reply, offset, "bb", &temp, &temp1); 11805331Samw if (bcc == VAR_BCC) { 11815331Samw if ((temp != 0xFF) || (temp1 != 0xFF)) { 11825331Samw smbsr_encode_error(sr); 11835331Samw /* NOTREACHED */ 11845331Samw } else { 11855331Samw bcc = (total_bytes - offset) - 2; 11865331Samw (void) smb_poke_mbc(&sr->reply, offset, "bb", 11875331Samw bcc, bcc >> 8); 11885331Samw } 11895331Samw } else { 11905331Samw if ((temp != (bcc&0xFF)) || (temp1 != ((bcc>>8)&0xFF))) { 11915331Samw smbsr_encode_error(sr); 11925331Samw } 11935331Samw } 11945331Samw 11955331Samw offset += bcc + 2; 11965331Samw 11975331Samw if (offset != total_bytes) { 11985331Samw smbsr_encode_error(sr); 11995331Samw } 12005331Samw 12015331Samw sr->smb_wct = (unsigned char)wct; 12025331Samw sr->smb_bcc = (uint16_t)bcc; 12035331Samw } 12045331Samw 12055331Samw int 12065331Samw smbsr_decode_vwv(struct smb_request *sr, char *fmt, ...) 12075331Samw { 12085331Samw int rc; 12095331Samw va_list ap; 12105331Samw 12115331Samw va_start(ap, fmt); 12125331Samw rc = smb_mbc_decode(&sr->smb_vwv, fmt, ap); 12135331Samw va_end(ap); 12145331Samw 12155331Samw return (rc); 12165331Samw } 12175331Samw 12185331Samw int 12195331Samw smbsr_decode_data(struct smb_request *sr, char *fmt, ...) 12205331Samw { 12215331Samw int r; 12225331Samw va_list ap; 12235331Samw va_start(ap, fmt); 12245331Samw r = smb_mbc_decode(&sr->smb_data, fmt, ap); 12255331Samw va_end(ap); 12265331Samw return (r); 12275331Samw } 12285331Samw 12295331Samw void 12305331Samw smbsr_send_reply(struct smb_request *sr) 12315331Samw { 12325331Samw (void) smb_poke_mbc(&sr->reply, 0, SMB_HEADER_ED_FMT, 12335331Samw sr->first_smb_com, 12345331Samw sr->smb_rcls, 12355331Samw sr->smb_reh, 12365331Samw sr->smb_err, 12375331Samw sr->smb_flg | SMB_FLAGS_REPLY, 12385331Samw sr->smb_flg2, 12395331Samw sr->smb_pid_high, 12405331Samw sr->smb_sig, 12415331Samw sr->smb_tid, 12425331Samw sr->smb_pid, 12435331Samw sr->smb_uid, 12445331Samw sr->smb_mid); 12455331Samw 12465331Samw if (sr->session->signing.flags & SMB_SIGNING_ENABLED) 12475331Samw smb_sign_reply(sr, NULL); 12485331Samw 12495331Samw (void) smb_session_send(sr->session, 0, &sr->reply); 12505331Samw } 12515331Samw 12525331Samw 12535331Samw void 12545331Samw smbsr_decode_error(struct smb_request *sr) 12555331Samw { 12565331Samw longjmp(&sr->exjb); 12575331Samw } 12585331Samw 12595331Samw void 12605331Samw smbsr_encode_error(struct smb_request *sr) 12615331Samw { 12625331Samw longjmp(&sr->exjb); 12635331Samw } 12645331Samw 12655331Samw void 12665331Samw smbsr_encode_empty_result(struct smb_request *sr) 12675331Samw { 12685331Samw smbsr_encode_result(sr, 0, 0, "bw", 0, 0); 12695331Samw } 12705331Samw 12715331Samw /* 1272*5772Sas200622 * Map errno values to SMB and NT status values. 1273*5772Sas200622 * Note: ESRCH is a special case to handle a streams lookup failure. 12745331Samw */ 12755331Samw static struct { 1276*5772Sas200622 int errnum; 1277*5772Sas200622 int errcls; 1278*5772Sas200622 int errcode; 1279*5772Sas200622 DWORD status32; 1280*5772Sas200622 } smb_errno_map[] = { 12815331Samw { ENOSPC, ERRDOS, ERROR_DISK_FULL, NT_STATUS_DISK_FULL }, 12825331Samw { EDQUOT, ERRDOS, ERROR_DISK_FULL, NT_STATUS_DISK_FULL }, 12835331Samw { EPERM, ERRSRV, ERRaccess, NT_STATUS_ACCESS_DENIED }, 12845331Samw { ENOTDIR, ERRDOS, ERRbadpath, NT_STATUS_OBJECT_PATH_NOT_FOUND }, 12855331Samw { EISDIR, ERRDOS, ERRbadpath, NT_STATUS_FILE_IS_A_DIRECTORY }, 12865331Samw { ENOENT, ERRDOS, ERRbadfile, NT_STATUS_NO_SUCH_FILE }, 12875331Samw { ENOTEMPTY, ERRDOS, ERROR_DIR_NOT_EMPTY, 12885331Samw NT_STATUS_DIRECTORY_NOT_EMPTY }, 12895331Samw { EACCES, ERRDOS, ERRnoaccess, NT_STATUS_ACCESS_DENIED }, 12905331Samw { ENOMEM, ERRDOS, ERRnomem, NT_STATUS_NO_MEMORY }, 12915331Samw { EIO, ERRHRD, ERRgeneral, NT_STATUS_IO_DEVICE_ERROR }, 12925331Samw { EXDEV, ERRSRV, ERRdiffdevice, NT_STATUS_NOT_SAME_DEVICE }, 12935331Samw { EROFS, ERRHRD, ERRnowrite, NT_STATUS_ACCESS_DENIED }, 12945331Samw { ESTALE, ERRDOS, ERRbadfid, NT_STATUS_INVALID_HANDLE}, 12955331Samw { EBADF, ERRDOS, ERRbadfid, NT_STATUS_INVALID_HANDLE}, 12965331Samw { EEXIST, ERRDOS, ERRfilexists, NT_STATUS_OBJECT_NAME_COLLISION}, 12975331Samw { ENXIO, ERRSRV, ERRinvdevice, NT_STATUS_BAD_DEVICE_TYPE}, 12985331Samw { ESRCH, ERRDOS, ERROR_FILE_NOT_FOUND, 12995331Samw NT_STATUS_OBJECT_NAME_NOT_FOUND }, 13005331Samw /* 13015331Samw * It's not clear why smb_read_common effectively returns 13025331Samw * ERRnoaccess if a range lock prevents access and smb_write_common 13035331Samw * effectively returns ERRaccess. This table entry is used by 13045331Samw * smb_read_common and preserves the behavior that was there before. 13055331Samw */ 13065331Samw { ERANGE, ERRDOS, ERRnoaccess, NT_STATUS_FILE_LOCK_CONFLICT } 13075331Samw }; 13085331Samw 13095331Samw void 1310*5772Sas200622 smbsr_map_errno(int errnum, smb_error_t *err) 13115331Samw { 13125331Samw int i; 13135331Samw 1314*5772Sas200622 for (i = 0; i < sizeof (smb_errno_map)/sizeof (smb_errno_map[0]); ++i) { 1315*5772Sas200622 if (smb_errno_map[i].errnum == errnum) { 1316*5772Sas200622 err->severity = ERROR_SEVERITY_ERROR; 1317*5772Sas200622 err->status = smb_errno_map[i].status32; 1318*5772Sas200622 err->errcls = smb_errno_map[i].errcls; 1319*5772Sas200622 err->errcode = smb_errno_map[i].errcode; 1320*5772Sas200622 return; 13215331Samw } 13225331Samw } 13235331Samw 1324*5772Sas200622 err->severity = ERROR_SEVERITY_ERROR; 1325*5772Sas200622 err->status = NT_STATUS_INTERNAL_ERROR; 1326*5772Sas200622 err->errcls = ERRDOS; 1327*5772Sas200622 err->errcode = ERROR_INTERNAL_ERROR; 13285331Samw } 13295331Samw 13305331Samw void 1331*5772Sas200622 smbsr_errno(struct smb_request *sr, int errnum) 1332*5772Sas200622 { 1333*5772Sas200622 smb_error_t err; 1334*5772Sas200622 1335*5772Sas200622 smbsr_map_errno(errnum, &err); 1336*5772Sas200622 smbsr_set_error(sr, &err); 1337*5772Sas200622 longjmp(&sr->exjb); 1338*5772Sas200622 /* NOTREACHED */ 1339*5772Sas200622 } 1340*5772Sas200622 1341*5772Sas200622 /* 1342*5772Sas200622 * Report a request processing warning. 1343*5772Sas200622 */ 1344*5772Sas200622 void 1345*5772Sas200622 smbsr_warn(smb_request_t *sr, DWORD status, uint16_t errcls, uint16_t errcode) 1346*5772Sas200622 { 1347*5772Sas200622 smb_error_t err; 1348*5772Sas200622 1349*5772Sas200622 err.severity = ERROR_SEVERITY_WARNING; 1350*5772Sas200622 err.status = status; 1351*5772Sas200622 err.errcls = errcls; 1352*5772Sas200622 err.errcode = errcode; 1353*5772Sas200622 1354*5772Sas200622 smbsr_set_error(sr, &err); 1355*5772Sas200622 } 1356*5772Sas200622 1357*5772Sas200622 /* 1358*5772Sas200622 * Report a request processing error. This function will not return. 1359*5772Sas200622 */ 1360*5772Sas200622 void 1361*5772Sas200622 smbsr_error(smb_request_t *sr, DWORD status, uint16_t errcls, uint16_t errcode) 13625331Samw { 1363*5772Sas200622 smb_error_t err; 1364*5772Sas200622 1365*5772Sas200622 err.severity = ERROR_SEVERITY_ERROR; 1366*5772Sas200622 err.status = status; 1367*5772Sas200622 err.errcls = errcls; 1368*5772Sas200622 err.errcode = errcode; 1369*5772Sas200622 1370*5772Sas200622 smbsr_set_error(sr, &err); 1371*5772Sas200622 longjmp(&sr->exjb); 1372*5772Sas200622 /* NOTREACHED */ 1373*5772Sas200622 } 1374*5772Sas200622 1375*5772Sas200622 /* 1376*5772Sas200622 * Setup a request processing error. This function can be used to 1377*5772Sas200622 * report 32-bit status codes or DOS errors. Set the status code 1378*5772Sas200622 * to 0 (NT_STATUS_SUCCESS) to explicitly report a DOS error, 1379*5772Sas200622 * regardless of the client capabilities. 1380*5772Sas200622 * 1381*5772Sas200622 * If status is non-zero and the client supports 32-bit status 1382*5772Sas200622 * codes, report the status. Otherwise, report the DOS error. 1383*5772Sas200622 */ 1384*5772Sas200622 void 1385*5772Sas200622 smbsr_set_error(smb_request_t *sr, smb_error_t *err) 1386*5772Sas200622 { 1387*5772Sas200622 uint32_t status; 1388*5772Sas200622 uint32_t severity; 1389*5772Sas200622 uint32_t capabilities; 1390*5772Sas200622 1391*5772Sas200622 ASSERT(sr); 1392*5772Sas200622 ASSERT(err); 1393*5772Sas200622 1394*5772Sas200622 status = err->status; 1395*5772Sas200622 severity = (err->severity == 0) ? ERROR_SEVERITY_ERROR : err->severity; 1396*5772Sas200622 capabilities = sr->session->capabilities; 1397*5772Sas200622 1398*5772Sas200622 if ((err->errcls == 0) && (err->errcode == 0)) { 1399*5772Sas200622 capabilities |= CAP_STATUS32; 1400*5772Sas200622 if (status == 0) 1401*5772Sas200622 status = NT_STATUS_INTERNAL_ERROR; 1402*5772Sas200622 } 1403*5772Sas200622 1404*5772Sas200622 if ((capabilities & CAP_STATUS32) && (status != 0)) { 1405*5772Sas200622 status |= severity; 1406*5772Sas200622 sr->smb_rcls = status & 0xff; 1407*5772Sas200622 sr->smb_reh = (status >> 8) & 0xff; 1408*5772Sas200622 sr->smb_err = status >> 16; 1409*5772Sas200622 sr->smb_flg2 |= SMB_FLAGS2_NT_STATUS; 1410*5772Sas200622 } else { 1411*5772Sas200622 if ((err->errcls == 0) || (err->errcode == 0)) { 1412*5772Sas200622 sr->smb_rcls = ERRSRV; 1413*5772Sas200622 sr->smb_err = ERRerror; 1414*5772Sas200622 } else { 1415*5772Sas200622 sr->smb_rcls = (uint8_t)err->errcls; 1416*5772Sas200622 sr->smb_err = (uint16_t)err->errcode; 14175331Samw } 14185331Samw } 14195331Samw } 14205331Samw 14215331Samw smb_xa_t * 14225331Samw smbsr_lookup_xa(smb_request_t *sr) 14235331Samw { 14245331Samw ASSERT(sr->r_xa == 0); 14255331Samw 14265331Samw sr->r_xa = smb_xa_find(sr->session, sr->smb_pid, sr->smb_mid); 14275331Samw return (sr->r_xa); 14285331Samw } 14295331Samw 14305331Samw void 14315331Samw smbsr_disconnect_file(smb_request_t *sr) 14325331Samw { 14335331Samw smb_ofile_t *of = sr->fid_ofile; 14345331Samw 14355331Samw sr->fid_ofile = NULL; 14365331Samw (void) smb_ofile_release(of); 14375331Samw } 14385331Samw 14395331Samw void 14405331Samw smbsr_disconnect_dir(smb_request_t *sr) 14415331Samw { 14425331Samw smb_odir_t *od = sr->sid_odir; 14435331Samw 14445331Samw sr->sid_odir = NULL; 14455331Samw smb_odir_release(od); 14465331Samw } 14475331Samw 14485331Samw static int 14495331Samw is_andx_com(unsigned char com) 14505331Samw { 14515331Samw switch (com) { 14525331Samw case SMB_COM_LOCKING_ANDX: 14535331Samw case SMB_COM_OPEN_ANDX: 14545331Samw case SMB_COM_READ_ANDX: 14555331Samw case SMB_COM_WRITE_ANDX: 14565331Samw case SMB_COM_SESSION_SETUP_ANDX: 14575331Samw case SMB_COM_LOGOFF_ANDX: 14585331Samw case SMB_COM_TREE_CONNECT_ANDX: 14595331Samw case SMB_COM_NT_CREATE_ANDX: 14605331Samw return (1); 14615331Samw } 14625331Samw return (0); 14635331Samw } 14645331Samw 14655331Samw /* 14665331Samw * Invalid command stub. 14675331Samw */ 14685331Samw /*ARGSUSED*/ 14695331Samw int 14705331Samw smb_com_invalid_command(struct smb_request *sr) 14715331Samw { 14725331Samw return (SDRC_UNIMPLEMENTED); 14735331Samw } 14745331Samw 14755331Samw /* 14765331Samw * smb_kstat_update_dispatch 14775331Samw * 14785331Samw * This callback function updates the smb_dispatch_kstat_data when kstat 14795331Samw * command is invoked. 14805331Samw */ 14815331Samw /*ARGSUSED*/ 14825331Samw static int 14835331Samw smb_kstat_update_dispatch(kstat_t *ksp, int rw) 14845331Samw { 14855331Samw int i = 0, j = 0; 14865331Samw 14875331Samw if (rw == KSTAT_WRITE) { 14885331Samw return (EACCES); 14895331Samw } else { 14905331Samw for (i = 0; i < 256; i++) { 14915331Samw if (dispatch[i].sdt_function) { 14925331Samw (void) memcpy(&smb_dispatch_kstat_data[j], 14935331Samw &(dispatch[i].sdt_dispatch_stats), 14945331Samw sizeof (kstat_named_t)); 14955331Samw j++; 14965331Samw } 14975331Samw } 14985331Samw } 14995331Samw return (0); 15005331Samw } 15015331Samw 15025331Samw /* 15035331Samw * smb_initialize_dispatch_kstat 15045331Samw * 15055331Samw * Initialize dispatch kstats. 15065331Samw */ 15075331Samw void 15085331Samw smb_initialize_dispatch_kstat() 15095331Samw { 15105331Samw int i = 0, alloc_size = 0; 15115331Samw 15125331Samw for (i = 0; i < 256; i++) { 15135331Samw if (dispatch[i].sdt_function) 15145331Samw smb_dispatch_kstat_size++; 15155331Samw } 15165331Samw 15175331Samw alloc_size = smb_dispatch_kstat_size * sizeof (kstat_named_t); 15185331Samw smb_dispatch_kstat_data = (kstat_named_t *) 15195331Samw kmem_zalloc(alloc_size, KM_SLEEP); 15205331Samw 15215331Samw smb_dispatch_ksp = kstat_create("smb", 0, "smb_dispatch_all", "misc", 15225331Samw KSTAT_TYPE_NAMED, alloc_size/sizeof (kstat_named_t), 15235331Samw KSTAT_FLAG_VIRTUAL | KSTAT_FLAG_WRITABLE); 15245331Samw if (smb_dispatch_ksp) { 15255331Samw smb_dispatch_ksp->ks_data = smb_dispatch_kstat_data; 15265331Samw smb_dispatch_ksp->ks_update = smb_kstat_update_dispatch; 15275331Samw kstat_install(smb_dispatch_ksp); 15285331Samw } 15295331Samw } 15305331Samw 15315331Samw /* 15325331Samw * smb_remove_dispatch_kstat 15335331Samw * 15345331Samw * Remove dispatch kstats. 15355331Samw */ 15365331Samw void 15375331Samw smb_remove_dispatch_kstat() 15385331Samw { 15395331Samw if (smb_dispatch_kstat_data != NULL) 15405331Samw kmem_free(smb_dispatch_kstat_data, 15415331Samw smb_dispatch_kstat_size * sizeof (kstat_named_t)); 15425331Samw 15435331Samw if (smb_dispatch_ksp != NULL) { 15445331Samw kstat_delete(smb_dispatch_ksp); 15455331Samw smb_dispatch_ksp = NULL; 15465331Samw } 15475331Samw } 1548