1 /* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License (the "License"). 6 * You may not use this file except in compliance with the License. 7 * 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9 * or http://www.opensolaris.org/os/licensing. 10 * See the License for the specific language governing permissions 11 * and limitations under the License. 12 * 13 * When distributing Covered Code, include this CDDL HEADER in each 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15 * If applicable, add the following below this CDDL HEADER, with the 16 * fields enclosed by brackets "[]" replaced with your own identifying 17 * information: Portions Copyright [yyyy] [name of copyright owner] 18 * 19 * CDDL HEADER END 20 */ 21 /* 22 * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved. 23 */ 24 25 #include <mdb/mdb_modapi.h> 26 #include <mdb/mdb_ks.h> 27 #include <sys/thread.h> 28 #include <sys/taskq_impl.h> 29 #include <smbsrv/smb_vops.h> 30 #include <smbsrv/smb.h> 31 #include <smbsrv/smb_ktypes.h> 32 33 #define SMB_DCMD_INDENT 2 34 #define ACE_TYPE_TABLEN (ACE_ALL_TYPES + 1) 35 #define ACE_TYPE_ENTRY(_v_) {_v_, #_v_} 36 #define SMB_COM_ENTRY(_v_, _x_) {#_v_, _x_} 37 38 #define SMB_MDB_MAX_OPTS 9 39 40 #define SMB_OPT_SERVER 0x00000001 41 #define SMB_OPT_SESSION 0x00000002 42 #define SMB_OPT_REQUEST 0x00000004 43 #define SMB_OPT_USER 0x00000008 44 #define SMB_OPT_TREE 0x00000010 45 #define SMB_OPT_OFILE 0x00000020 46 #define SMB_OPT_ODIR 0x00000040 47 #define SMB_OPT_WALK 0x00000100 48 #define SMB_OPT_VERBOSE 0x00000200 49 #define SMB_OPT_ALL_OBJ 0x000000FF 50 51 /* 52 * Structure associating an ACE type to a string. 53 */ 54 typedef struct { 55 uint8_t ace_type_value; 56 const char *ace_type_sting; 57 } ace_type_entry_t; 58 59 /* 60 * Structure containing strings describing an SMB command. 61 */ 62 typedef struct { 63 const char *smb_com; 64 const char *smb_andx; 65 } smb_com_entry_t; 66 67 /* 68 * Structure describing an object to be expanded (displayed). 69 */ 70 typedef struct { 71 uint_t ex_mask; 72 size_t ex_offset; 73 const char *ex_dcmd; 74 const char *ex_name; 75 } smb_exp_t; 76 77 /* 78 * List of supported options. Ther order has the match the bits SMB_OPT_xxx. 79 */ 80 typedef struct smb_mdb_opts { 81 char *o_name; 82 uint32_t o_value; 83 } smb_mdb_opts_t; 84 85 static smb_mdb_opts_t smb_opts[SMB_MDB_MAX_OPTS] = 86 { 87 { "-s", SMB_OPT_SERVER }, 88 { "-e", SMB_OPT_SESSION }, 89 { "-r", SMB_OPT_REQUEST }, 90 { "-u", SMB_OPT_USER }, 91 { "-t", SMB_OPT_TREE }, 92 { "-f", SMB_OPT_OFILE }, 93 { "-d", SMB_OPT_ODIR }, 94 { "-w", SMB_OPT_WALK }, 95 { "-v", SMB_OPT_VERBOSE } 96 }; 97 98 static smb_com_entry_t smb_com[256] = 99 { 100 SMB_COM_ENTRY(SMB_COM_CREATE_DIRECTORY, "No"), 101 SMB_COM_ENTRY(SMB_COM_DELETE_DIRECTORY, "No"), 102 SMB_COM_ENTRY(SMB_COM_OPEN, "No"), 103 SMB_COM_ENTRY(SMB_COM_CREATE, "No"), 104 SMB_COM_ENTRY(SMB_COM_CLOSE, "No"), 105 SMB_COM_ENTRY(SMB_COM_FLUSH, "No"), 106 SMB_COM_ENTRY(SMB_COM_DELETE, "No"), 107 SMB_COM_ENTRY(SMB_COM_RENAME, "No"), 108 SMB_COM_ENTRY(SMB_COM_QUERY_INFORMATION, "No"), 109 SMB_COM_ENTRY(SMB_COM_SET_INFORMATION, "No"), 110 SMB_COM_ENTRY(SMB_COM_READ, "No"), 111 SMB_COM_ENTRY(SMB_COM_WRITE, "No"), 112 SMB_COM_ENTRY(SMB_COM_LOCK_BYTE_RANGE, "No"), 113 SMB_COM_ENTRY(SMB_COM_UNLOCK_BYTE_RANGE, "No"), 114 SMB_COM_ENTRY(SMB_COM_CREATE_TEMPORARY, "No"), 115 SMB_COM_ENTRY(SMB_COM_CREATE_NEW, "No"), 116 SMB_COM_ENTRY(SMB_COM_CHECK_DIRECTORY, "No"), 117 SMB_COM_ENTRY(SMB_COM_PROCESS_EXIT, "No"), 118 SMB_COM_ENTRY(SMB_COM_SEEK, "No"), 119 SMB_COM_ENTRY(SMB_COM_LOCK_AND_READ, "No"), 120 SMB_COM_ENTRY(SMB_COM_WRITE_AND_UNLOCK, "No"), 121 SMB_COM_ENTRY(0x15, "?"), 122 SMB_COM_ENTRY(0x16, "?"), 123 SMB_COM_ENTRY(0x17, "?"), 124 SMB_COM_ENTRY(0x18, "?"), 125 SMB_COM_ENTRY(0x19, "?"), 126 SMB_COM_ENTRY(SMB_COM_READ_RAW, "No"), 127 SMB_COM_ENTRY(SMB_COM_READ_MPX, "No"), 128 SMB_COM_ENTRY(SMB_COM_READ_MPX_SECONDARY, "No"), 129 SMB_COM_ENTRY(SMB_COM_WRITE_RAW, "No"), 130 SMB_COM_ENTRY(SMB_COM_WRITE_MPX, "No"), 131 SMB_COM_ENTRY(SMB_COM_WRITE_MPX_SECONDARY, "No"), 132 SMB_COM_ENTRY(SMB_COM_WRITE_COMPLETE, "No"), 133 SMB_COM_ENTRY(SMB_COM_QUERY_SERVER, "No"), 134 SMB_COM_ENTRY(SMB_COM_SET_INFORMATION2, "No"), 135 SMB_COM_ENTRY(SMB_COM_QUERY_INFORMATION2, "No"), 136 SMB_COM_ENTRY(SMB_COM_LOCKING_ANDX, "No"), 137 SMB_COM_ENTRY(SMB_COM_TRANSACTION, "No"), 138 SMB_COM_ENTRY(SMB_COM_TRANSACTION_SECONDARY, "No"), 139 SMB_COM_ENTRY(SMB_COM_IOCTL, "No"), 140 SMB_COM_ENTRY(SMB_COM_IOCTL_SECONDARY, "No"), 141 SMB_COM_ENTRY(SMB_COM_COPY, "No"), 142 SMB_COM_ENTRY(SMB_COM_MOVE, "No"), 143 SMB_COM_ENTRY(SMB_COM_ECHO, "No"), 144 SMB_COM_ENTRY(SMB_COM_WRITE_AND_CLOSE, "No"), 145 SMB_COM_ENTRY(SMB_COM_OPEN_ANDX, "No"), 146 SMB_COM_ENTRY(SMB_COM_READ_ANDX, "No"), 147 SMB_COM_ENTRY(SMB_COM_WRITE_ANDX, "No"), 148 SMB_COM_ENTRY(SMB_COM_NEW_FILE_SIZE, "No"), 149 SMB_COM_ENTRY(SMB_COM_CLOSE_AND_TREE_DISC, "No"), 150 SMB_COM_ENTRY(SMB_COM_TRANSACTION2, "No"), 151 SMB_COM_ENTRY(SMB_COM_TRANSACTION2_SECONDARY, "No"), 152 SMB_COM_ENTRY(SMB_COM_FIND_CLOSE2, "No"), 153 SMB_COM_ENTRY(SMB_COM_FIND_NOTIFY_CLOSE, "No"), 154 SMB_COM_ENTRY(0x36, "?"), 155 SMB_COM_ENTRY(0x37, "?"), 156 SMB_COM_ENTRY(0x38, "?"), 157 SMB_COM_ENTRY(0x39, "?"), 158 SMB_COM_ENTRY(0x3A, "?"), 159 SMB_COM_ENTRY(0x3B, "?"), 160 SMB_COM_ENTRY(0x3C, "?"), 161 SMB_COM_ENTRY(0x3D, "?"), 162 SMB_COM_ENTRY(0x3E, "?"), 163 SMB_COM_ENTRY(0x3F, "?"), 164 SMB_COM_ENTRY(0x40, "?"), 165 SMB_COM_ENTRY(0x41, "?"), 166 SMB_COM_ENTRY(0x42, "?"), 167 SMB_COM_ENTRY(0x43, "?"), 168 SMB_COM_ENTRY(0x44, "?"), 169 SMB_COM_ENTRY(0x45, "?"), 170 SMB_COM_ENTRY(0x46, "?"), 171 SMB_COM_ENTRY(0x47, "?"), 172 SMB_COM_ENTRY(0x48, "?"), 173 SMB_COM_ENTRY(0x49, "?"), 174 SMB_COM_ENTRY(0x4A, "?"), 175 SMB_COM_ENTRY(0x4B, "?"), 176 SMB_COM_ENTRY(0x4C, "?"), 177 SMB_COM_ENTRY(0x4D, "?"), 178 SMB_COM_ENTRY(0x4E, "?"), 179 SMB_COM_ENTRY(0x4F, "?"), 180 SMB_COM_ENTRY(0x50, "?"), 181 SMB_COM_ENTRY(0x51, "?"), 182 SMB_COM_ENTRY(0x52, "?"), 183 SMB_COM_ENTRY(0x53, "?"), 184 SMB_COM_ENTRY(0x54, "?"), 185 SMB_COM_ENTRY(0x55, "?"), 186 SMB_COM_ENTRY(0x56, "?"), 187 SMB_COM_ENTRY(0x57, "?"), 188 SMB_COM_ENTRY(0x58, "?"), 189 SMB_COM_ENTRY(0x59, "?"), 190 SMB_COM_ENTRY(0x5A, "?"), 191 SMB_COM_ENTRY(0x5B, "?"), 192 SMB_COM_ENTRY(0x5C, "?"), 193 SMB_COM_ENTRY(0x5D, "?"), 194 SMB_COM_ENTRY(0x5E, "?"), 195 SMB_COM_ENTRY(0x5F, "?"), 196 SMB_COM_ENTRY(0x60, "?"), 197 SMB_COM_ENTRY(0x61, "?"), 198 SMB_COM_ENTRY(0x62, "?"), 199 SMB_COM_ENTRY(0x63, "?"), 200 SMB_COM_ENTRY(0x64, "?"), 201 SMB_COM_ENTRY(0x65, "?"), 202 SMB_COM_ENTRY(0x66, "?"), 203 SMB_COM_ENTRY(0x67, "?"), 204 SMB_COM_ENTRY(0x68, "?"), 205 SMB_COM_ENTRY(0x69, "?"), 206 SMB_COM_ENTRY(0x6A, "?"), 207 SMB_COM_ENTRY(0x6B, "?"), 208 SMB_COM_ENTRY(0x6C, "?"), 209 SMB_COM_ENTRY(0x6D, "?"), 210 SMB_COM_ENTRY(0x6E, "?"), 211 SMB_COM_ENTRY(0x6F, "?"), 212 SMB_COM_ENTRY(SMB_COM_TREE_CONNECT, "No"), 213 SMB_COM_ENTRY(SMB_COM_TREE_DISCONNECT, "No"), 214 SMB_COM_ENTRY(SMB_COM_NEGOTIATE, "No"), 215 SMB_COM_ENTRY(SMB_COM_SESSION_SETUP_ANDX, "No"), 216 SMB_COM_ENTRY(SMB_COM_LOGOFF_ANDX, "No"), 217 SMB_COM_ENTRY(SMB_COM_TREE_CONNECT_ANDX, "No"), 218 SMB_COM_ENTRY(0x76, "?"), 219 SMB_COM_ENTRY(0x77, "?"), 220 SMB_COM_ENTRY(0x78, "?"), 221 SMB_COM_ENTRY(0x79, "?"), 222 SMB_COM_ENTRY(0x7A, "?"), 223 SMB_COM_ENTRY(0x7B, "?"), 224 SMB_COM_ENTRY(0x7C, "?"), 225 SMB_COM_ENTRY(0x7D, "?"), 226 SMB_COM_ENTRY(0x7E, "?"), 227 SMB_COM_ENTRY(0x7F, "?"), 228 SMB_COM_ENTRY(SMB_COM_QUERY_INFORMATION_DISK, "No"), 229 SMB_COM_ENTRY(SMB_COM_SEARCH, "No"), 230 SMB_COM_ENTRY(SMB_COM_FIND, "No"), 231 SMB_COM_ENTRY(SMB_COM_FIND_UNIQUE, "No"), 232 SMB_COM_ENTRY(SMB_COM_FIND_CLOSE, "No"), 233 SMB_COM_ENTRY(0x85, "?"), 234 SMB_COM_ENTRY(0x86, "?"), 235 SMB_COM_ENTRY(0x87, "?"), 236 SMB_COM_ENTRY(0x88, "?"), 237 SMB_COM_ENTRY(0x89, "?"), 238 SMB_COM_ENTRY(0x8A, "?"), 239 SMB_COM_ENTRY(0x8B, "?"), 240 SMB_COM_ENTRY(0x8C, "?"), 241 SMB_COM_ENTRY(0x8D, "?"), 242 SMB_COM_ENTRY(0x8E, "?"), 243 SMB_COM_ENTRY(0x8F, "?"), 244 SMB_COM_ENTRY(0x90, "?"), 245 SMB_COM_ENTRY(0x91, "?"), 246 SMB_COM_ENTRY(0x92, "?"), 247 SMB_COM_ENTRY(0x93, "?"), 248 SMB_COM_ENTRY(0x94, "?"), 249 SMB_COM_ENTRY(0x95, "?"), 250 SMB_COM_ENTRY(0x96, "?"), 251 SMB_COM_ENTRY(0x97, "?"), 252 SMB_COM_ENTRY(0x98, "?"), 253 SMB_COM_ENTRY(0x99, "?"), 254 SMB_COM_ENTRY(0x9A, "?"), 255 SMB_COM_ENTRY(0x9B, "?"), 256 SMB_COM_ENTRY(0x9C, "?"), 257 SMB_COM_ENTRY(0x9D, "?"), 258 SMB_COM_ENTRY(0x9E, "?"), 259 SMB_COM_ENTRY(0x9F, "?"), 260 SMB_COM_ENTRY(SMB_COM_NT_TRANSACT, "No"), 261 SMB_COM_ENTRY(SMB_COM_NT_TRANSACT_SECONDARY, "No"), 262 SMB_COM_ENTRY(SMB_COM_NT_CREATE_ANDX, "No"), 263 SMB_COM_ENTRY(0xA3, "?"), 264 SMB_COM_ENTRY(SMB_COM_NT_CANCEL, "No"), 265 SMB_COM_ENTRY(SMB_COM_NT_RENAME, "No"), 266 SMB_COM_ENTRY(0xA6, "?"), 267 SMB_COM_ENTRY(0xA7, "?"), 268 SMB_COM_ENTRY(0xA8, "?"), 269 SMB_COM_ENTRY(0xA9, "?"), 270 SMB_COM_ENTRY(0xAA, "?"), 271 SMB_COM_ENTRY(0xAB, "?"), 272 SMB_COM_ENTRY(0xAC, "?"), 273 SMB_COM_ENTRY(0xAD, "?"), 274 SMB_COM_ENTRY(0xAE, "?"), 275 SMB_COM_ENTRY(0xAF, "?"), 276 SMB_COM_ENTRY(0xB0, "?"), 277 SMB_COM_ENTRY(0xB1, "?"), 278 SMB_COM_ENTRY(0xB2, "?"), 279 SMB_COM_ENTRY(0xB3, "?"), 280 SMB_COM_ENTRY(0xB4, "?"), 281 SMB_COM_ENTRY(0xB5, "?"), 282 SMB_COM_ENTRY(0xB6, "?"), 283 SMB_COM_ENTRY(0xB7, "?"), 284 SMB_COM_ENTRY(0xB8, "?"), 285 SMB_COM_ENTRY(0xB9, "?"), 286 SMB_COM_ENTRY(0xBA, "?"), 287 SMB_COM_ENTRY(0xBB, "?"), 288 SMB_COM_ENTRY(0xBC, "?"), 289 SMB_COM_ENTRY(0xBD, "?"), 290 SMB_COM_ENTRY(0xBE, "?"), 291 SMB_COM_ENTRY(0xBF, "?"), 292 SMB_COM_ENTRY(SMB_COM_OPEN_PRINT_FILE, "No"), 293 SMB_COM_ENTRY(SMB_COM_WRITE_PRINT_FILE, "No"), 294 SMB_COM_ENTRY(SMB_COM_CLOSE_PRINT_FILE, "No"), 295 SMB_COM_ENTRY(SMB_COM_GET_PRINT_QUEUE, "No"), 296 SMB_COM_ENTRY(0xC4, "?"), 297 SMB_COM_ENTRY(0xC5, "?"), 298 SMB_COM_ENTRY(0xC6, "?"), 299 SMB_COM_ENTRY(0xC7, "?"), 300 SMB_COM_ENTRY(0xC8, "?"), 301 SMB_COM_ENTRY(0xC9, "?"), 302 SMB_COM_ENTRY(0xCA, "?"), 303 SMB_COM_ENTRY(0xCB, "?"), 304 SMB_COM_ENTRY(0xCC, "?"), 305 SMB_COM_ENTRY(0xCD, "?"), 306 SMB_COM_ENTRY(0xCE, "?"), 307 SMB_COM_ENTRY(0xCF, "?"), 308 SMB_COM_ENTRY(0xD0, "?"), 309 SMB_COM_ENTRY(0xD1, "?"), 310 SMB_COM_ENTRY(0xD2, "?"), 311 SMB_COM_ENTRY(0xD3, "?"), 312 SMB_COM_ENTRY(0xD4, "?"), 313 SMB_COM_ENTRY(0xD5, "?"), 314 SMB_COM_ENTRY(0xD6, "?"), 315 SMB_COM_ENTRY(0xD7, "?"), 316 SMB_COM_ENTRY(SMB_COM_READ_BULK, "No"), 317 SMB_COM_ENTRY(SMB_COM_WRITE_BULK, "No"), 318 SMB_COM_ENTRY(SMB_COM_WRITE_BULK_DATA, "No"), 319 SMB_COM_ENTRY(0xDB, "?"), 320 SMB_COM_ENTRY(0xDC, "?"), 321 SMB_COM_ENTRY(0xDD, "?"), 322 SMB_COM_ENTRY(0xDE, "?"), 323 SMB_COM_ENTRY(0xDF, "?"), 324 SMB_COM_ENTRY(0xE0, "?"), 325 SMB_COM_ENTRY(0xE1, "?"), 326 SMB_COM_ENTRY(0xE2, "?"), 327 SMB_COM_ENTRY(0xE3, "?"), 328 SMB_COM_ENTRY(0xE4, "?"), 329 SMB_COM_ENTRY(0xE5, "?"), 330 SMB_COM_ENTRY(0xE6, "?"), 331 SMB_COM_ENTRY(0xE7, "?"), 332 SMB_COM_ENTRY(0xE8, "?"), 333 SMB_COM_ENTRY(0xE9, "?"), 334 SMB_COM_ENTRY(0xEA, "?"), 335 SMB_COM_ENTRY(0xEB, "?"), 336 SMB_COM_ENTRY(0xEC, "?"), 337 SMB_COM_ENTRY(0xED, "?"), 338 SMB_COM_ENTRY(0xEE, "?"), 339 SMB_COM_ENTRY(0xEF, "?"), 340 SMB_COM_ENTRY(0xF0, "?"), 341 SMB_COM_ENTRY(0xF1, "?"), 342 SMB_COM_ENTRY(0xF2, "?"), 343 SMB_COM_ENTRY(0xF3, "?"), 344 SMB_COM_ENTRY(0xF4, "?"), 345 SMB_COM_ENTRY(0xF5, "?"), 346 SMB_COM_ENTRY(0xF6, "?"), 347 SMB_COM_ENTRY(0xF7, "?"), 348 SMB_COM_ENTRY(0xF8, "?"), 349 SMB_COM_ENTRY(0xF9, "?"), 350 SMB_COM_ENTRY(0xFA, "?"), 351 SMB_COM_ENTRY(0xFB, "?"), 352 SMB_COM_ENTRY(0xFC, "?"), 353 SMB_COM_ENTRY(0xFD, "?"), 354 SMB_COM_ENTRY(0xFE, "?"), 355 SMB_COM_ENTRY(0xFF, "?") 356 }; 357 358 static int smb_dcmd_list(uintptr_t, uint_t, int, const mdb_arg_t *); 359 static void smb_dcmd_list_help(void); 360 static int smb_dcmd_server(uintptr_t, uint_t, int, const mdb_arg_t *); 361 static void smb_dcmd_session_help(void); 362 static int smb_dcmd_session(uintptr_t, uint_t, int, const mdb_arg_t *); 363 static int smb_dcmd_request(uintptr_t, uint_t, int, const mdb_arg_t *); 364 static void smb_dcmd_user_help(void); 365 static int smb_dcmd_user(uintptr_t, uint_t, int, const mdb_arg_t *); 366 static void smb_dcmd_tree_help(void); 367 static int smb_dcmd_tree(uintptr_t, uint_t, int, const mdb_arg_t *); 368 static int smb_dcmd_odir(uintptr_t, uint_t, int, const mdb_arg_t *); 369 static int smb_dcmd_ofile(uintptr_t, uint_t, int, const mdb_arg_t *); 370 static int smb_vfs(uintptr_t, uint_t, int, const mdb_arg_t *); 371 static int smb_vfs_walk_init(mdb_walk_state_t *); 372 static int smb_vfs_walk_step(mdb_walk_state_t *); 373 static void smb_node_help(void); 374 static int smb_node(uintptr_t, uint_t, int, const mdb_arg_t *); 375 static int smb_node_walk_init(mdb_walk_state_t *); 376 static int smb_node_walk_step(mdb_walk_state_t *); 377 static int smb_lock(uintptr_t, uint_t, int, const mdb_arg_t *); 378 static int smb_ace(uintptr_t, uint_t, int, const mdb_arg_t *); 379 static int smb_ace_walk_init(mdb_walk_state_t *); 380 static int smb_ace_walk_step(mdb_walk_state_t *); 381 static int smb_acl(uintptr_t, uint_t, int, const mdb_arg_t *); 382 static int smb_sd(uintptr_t, uint_t, int, const mdb_arg_t *); 383 static int smb_sid(uintptr_t, uint_t, int, const mdb_arg_t *); 384 static int smb_sid_print(uintptr_t); 385 static int smb_fssd(uintptr_t, uint_t, int, const mdb_arg_t *); 386 static int smb_dcmd_getopt(uint_t *, int, const mdb_arg_t *); 387 static int smb_dcmd_setopt(uint_t, int, mdb_arg_t *); 388 static int smb_obj_expand(uintptr_t, uint_t, const smb_exp_t *, ulong_t); 389 static int smb_obj_list(const char *, uint_t, uint_t); 390 static int smb_worker_findstack(uintptr_t); 391 static int smb_stats(uintptr_t, uint_t, int, const mdb_arg_t *); 392 393 /* 394 * MDB module linkage information: 395 * 396 * We declare a list of structures describing our dcmds, a list of structures 397 * describing our walkers and a function named _mdb_init to return a pointer 398 * to our module information. 399 */ 400 static const mdb_dcmd_t dcmds[] = { 401 { "smblist", 402 "[-seutfdwv]", 403 "print tree of SMB objects", 404 smb_dcmd_list, 405 smb_dcmd_list_help }, 406 { "smbsrv", 407 "[-seutfdwv]", 408 "print smb_server information", 409 smb_dcmd_server }, 410 { "smbvfs", 411 "[-v]", 412 "print smb_vfs information", 413 smb_vfs }, 414 { "smbnode", 415 "?[-vps]", 416 "print smb_node_t information", 417 smb_node, 418 smb_node_help }, 419 { "smbsess", 420 "[-utfdwv]", 421 "print smb_session_t information", 422 smb_dcmd_session, 423 smb_dcmd_session_help}, 424 { "smbreq", 425 ":[-v]", 426 "print smb_request_t information", 427 smb_dcmd_request }, 428 { "smblock", ":[-v]", 429 "print smb_lock_t information", smb_lock }, 430 { "smbuser", 431 ":[-vdftq]", 432 "print smb_user_t information", 433 smb_dcmd_user, 434 smb_dcmd_user_help }, 435 { "smbtree", 436 ":[-vdf]", 437 "print smb_tree_t information", 438 smb_dcmd_tree, 439 smb_dcmd_tree_help }, 440 { "smbodir", 441 ":[-v]", 442 "print smb_odir_t information", 443 smb_dcmd_odir }, 444 { "smbofile", 445 "[-v]", 446 "print smb_odir_t information", 447 smb_dcmd_ofile }, 448 { "smbstat", NULL, 449 "print all smb dispatched requests statistics", 450 smb_stats }, 451 { "smbace", "[-v]", 452 "print smb_ace_t information", smb_ace }, 453 { "smbacl", "[-v]", 454 "print smb_acl_t information", smb_acl }, 455 { "smbsid", "[-v]", 456 "print smb_sid_t information", smb_sid }, 457 { "smbsd", "[-v]", 458 "print smb_sd_t information", smb_sd }, 459 { "smbfssd", "[-v]", 460 "print smb_fssd_t information", smb_fssd }, 461 { NULL } 462 }; 463 464 static const mdb_walker_t walkers[] = { 465 { "smbnode_walker", 466 "walk list of smb_node_t structures", 467 smb_node_walk_init, 468 smb_node_walk_step, 469 NULL, 470 NULL }, 471 { "smbvfs_walker", 472 "walk list of smb_vfs_t structures", 473 smb_vfs_walk_init, 474 smb_vfs_walk_step, 475 NULL, 476 NULL }, 477 { "smbace_walker", 478 "walk list of smb_ace_t structures", 479 smb_ace_walk_init, 480 smb_ace_walk_step, 481 NULL, 482 NULL }, 483 { NULL } 484 }; 485 486 static const mdb_modinfo_t modinfo = { 487 MDB_API_VERSION, dcmds, walkers 488 }; 489 490 const mdb_modinfo_t * 491 _mdb_init(void) 492 { 493 return (&modinfo); 494 } 495 496 /* 497 * ***************************************************************************** 498 * ****************************** Top level DCMD ******************************* 499 * ***************************************************************************** 500 */ 501 502 static void 503 smb_dcmd_list_help(void) 504 { 505 mdb_printf( 506 "Displays the list of objects using an indented tree format.\n" 507 "If no option is specified the entire tree is displayed\n\n"); 508 (void) mdb_dec_indent(2); 509 mdb_printf("%<b>OPTIONS%</b>\n"); 510 (void) mdb_inc_indent(2); 511 mdb_printf( 512 "-v\tDisplay verbose information\n" 513 "-s\tDisplay the list of servers\n" 514 "-e\tDisplay the list of sessions\n" 515 "-r\tDisplay the list of smb requests\n" 516 "-u\tDisplay the list of users\n" 517 "-t\tDisplay the list of trees\n" 518 "-f\tDisplay the list of open files\n" 519 "-d\tDisplay the list of open searches\n"); 520 } 521 522 /* 523 * ::smblist 524 * 525 * This function lists the objects specified on the command line. If no object 526 * is specified the entire tree (server through ofile and odir) is displayed. 527 * 528 */ 529 /*ARGSUSED*/ 530 static int 531 smb_dcmd_list(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv) 532 { 533 GElf_Sym sym; 534 uint_t opts = 0; 535 int new_argc; 536 mdb_arg_t new_argv[SMB_MDB_MAX_OPTS]; 537 538 if (smb_dcmd_getopt(&opts, argc, argv)) 539 return (DCMD_USAGE); 540 541 if (!(opts & ~(SMB_OPT_WALK | SMB_OPT_VERBOSE))) 542 opts |= SMB_OPT_ALL_OBJ; 543 544 opts |= SMB_OPT_WALK; 545 546 new_argc = smb_dcmd_setopt(opts, SMB_MDB_MAX_OPTS, new_argv); 547 548 if (mdb_lookup_by_name("smb_servers", &sym) == -1) { 549 mdb_warn("failed to find symbol smb_servers"); 550 return (DCMD_ERR); 551 } 552 553 addr = (uintptr_t)sym.st_value + offsetof(smb_llist_t, ll_list); 554 555 if (mdb_pwalk_dcmd("list", "smbsrv", new_argc, new_argv, addr)) 556 return (DCMD_ERR); 557 return (DCMD_OK); 558 } 559 560 /* 561 * ***************************************************************************** 562 * ***************************** smb_server_t ********************************** 563 * ***************************************************************************** 564 */ 565 566 static const char *smb_server_state[SMB_SERVER_STATE_SENTINEL] = 567 { 568 "CREATED", 569 "CONFIGURED", 570 "RUNNING", 571 "STOPPING", 572 "DELETING" 573 }; 574 575 /* 576 * List of objects that can be expanded under a server structure. 577 */ 578 static const smb_exp_t smb_server_exp[] = 579 { 580 { SMB_OPT_ALL_OBJ, 581 offsetof(smb_server_t, sv_nbt_daemon.ld_session_list.se_rdy.lst), 582 "smbsess", "smb_session"}, 583 { SMB_OPT_ALL_OBJ, 584 offsetof(smb_server_t, sv_nbt_daemon.ld_session_list.se_act.lst), 585 "smbsess", "smb_session"}, 586 { SMB_OPT_ALL_OBJ, 587 offsetof(smb_server_t, sv_tcp_daemon.ld_session_list.se_rdy.lst), 588 "smbsess", "smb_session"}, 589 { SMB_OPT_ALL_OBJ, 590 offsetof(smb_server_t, sv_tcp_daemon.ld_session_list.se_act.lst), 591 "smbsess", "smb_session"}, 592 { 0, 0, NULL, NULL } 593 }; 594 595 /* 596 * ::smbsrv 597 * 598 * smbsrv dcmd - Print out smb_server structures. 599 */ 600 /*ARGSUSED*/ 601 static int 602 smb_dcmd_server(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv) 603 { 604 uint_t opts; 605 ulong_t indent = 0; 606 607 if (smb_dcmd_getopt(&opts, argc, argv)) 608 return (DCMD_USAGE); 609 610 if (!(flags & DCMD_ADDRSPEC)) 611 return (smb_obj_list("smb_server", opts | SMB_OPT_SERVER, 612 flags)); 613 614 if (((opts & SMB_OPT_WALK) && (opts & SMB_OPT_SERVER)) || 615 !(opts & SMB_OPT_WALK)) { 616 smb_server_t *sv; 617 const char *state; 618 619 sv = mdb_alloc(sizeof (smb_server_t), UM_SLEEP | UM_GC); 620 if (mdb_vread(sv, sizeof (smb_server_t), addr) == -1) { 621 mdb_warn("failed to read smb_server at %p", addr); 622 return (DCMD_ERR); 623 } 624 625 indent = SMB_DCMD_INDENT; 626 627 if (opts & SMB_OPT_VERBOSE) { 628 mdb_arg_t argv; 629 630 argv.a_type = MDB_TYPE_STRING; 631 argv.a_un.a_str = "smb_server_t"; 632 if (mdb_call_dcmd("print", addr, flags, 1, &argv)) 633 return (DCMD_ERR); 634 } else { 635 if (DCMD_HDRSPEC(flags)) 636 mdb_printf( 637 "%<b>%<u>%-?s% " 638 "%-4s% " 639 "%-32s% " 640 "%</u>%</b>\n", 641 "SERVER", "ZONE", "STATE"); 642 643 if (sv->sv_state >= SMB_SERVER_STATE_SENTINEL) 644 state = "UNKNOWN"; 645 else 646 state = smb_server_state[sv->sv_state]; 647 648 mdb_printf("%-?p %-4d %-32s \n", 649 addr, sv->sv_zid, state); 650 } 651 } 652 if (smb_obj_expand(addr, opts, smb_server_exp, indent)) 653 return (DCMD_ERR); 654 return (DCMD_OK); 655 } 656 657 /* 658 * ***************************************************************************** 659 * ***************************** smb_session_t ********************************* 660 * ***************************************************************************** 661 */ 662 663 static const char *smb_session_state[SMB_SESSION_STATE_SENTINEL] = 664 { 665 "INITIALIZED", 666 "DISCONNECTED", 667 "CONNECTED", 668 "ESTABLISHED", 669 "NEGOTIATED", 670 "OPLOCK_BREAKING", 671 "WRITE_RAW_ACTIVE", 672 "READ_RAW_ACTIVE", 673 "TERMINATED" 674 }; 675 676 /* 677 * List of objects that can be expanded under a session structure. 678 */ 679 static const smb_exp_t smb_session_exp[] = 680 { 681 { SMB_OPT_REQUEST, 682 offsetof(smb_session_t, s_req_list.sl_list), 683 "smbreq", "smb_request"}, 684 { SMB_OPT_USER | SMB_OPT_TREE | SMB_OPT_OFILE | SMB_OPT_ODIR, 685 offsetof(smb_session_t, s_user_list.ll_list), 686 "smbuser", "smb_user"}, 687 { 0, 0, NULL, NULL} 688 }; 689 690 static void 691 smb_dcmd_session_help(void) 692 { 693 mdb_printf( 694 "Display the contents of smb_session_t, with optional" 695 " filtering.\n\n"); 696 (void) mdb_dec_indent(2); 697 mdb_printf("%<b>OPTIONS%</b>\n"); 698 (void) mdb_inc_indent(2); 699 mdb_printf( 700 "-v\tDisplay verbose smb_session information\n" 701 "-r\tDisplay the list of smb requests attached\n" 702 "-u\tDisplay the list of users attached\n"); 703 } 704 705 /* 706 * ::smbsess 707 * 708 * smbsess dcmd - Print out the smb_session structure. 709 */ 710 /*ARGSUSED*/ 711 static int 712 smb_dcmd_session(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv) 713 { 714 uint_t opts; 715 ulong_t indent = 0; 716 717 if (smb_dcmd_getopt(&opts, argc, argv)) 718 return (DCMD_USAGE); 719 720 if (!(flags & DCMD_ADDRSPEC)) { 721 opts |= SMB_OPT_SESSION; 722 opts &= ~SMB_OPT_SERVER; 723 return (smb_obj_list("smb_session", opts, flags)); 724 } 725 726 if (((opts & SMB_OPT_WALK) && (opts & SMB_OPT_SESSION)) || 727 !(opts & SMB_OPT_WALK)) { 728 smb_session_t *se; 729 const char *state; 730 731 indent = SMB_DCMD_INDENT; 732 733 se = mdb_alloc(sizeof (*se), UM_SLEEP | UM_GC); 734 if (mdb_vread(se, sizeof (*se), addr) == -1) { 735 mdb_warn("failed to read smb_session at %p", addr); 736 return (DCMD_ERR); 737 } 738 if (se->s_state >= SMB_SESSION_STATE_SENTINEL) 739 state = "INVALID"; 740 else 741 state = smb_session_state[se->s_state]; 742 743 if (opts & SMB_OPT_VERBOSE) { 744 mdb_printf("%<b>%<u>SMB session information " 745 "(%p): %</u>%</b>\n", addr); 746 mdb_printf("Client IP address: %I\n", se->ipaddr); 747 mdb_printf("Local IP Address: %I\n", se->local_ipaddr); 748 mdb_printf("Session KID: %u\n", se->s_kid); 749 mdb_printf("Workstation Name: %s\n", 750 se->workstation); 751 mdb_printf("Session state: %u (%s)\n", se->s_state, 752 state); 753 mdb_printf("Number of Users: %u\n", 754 se->s_user_list.ll_count); 755 mdb_printf("Number of Trees: %u\n", se->s_tree_cnt); 756 mdb_printf("Number of Files: %u\n", se->s_file_cnt); 757 mdb_printf("Number of Shares: %u\n", se->s_dir_cnt); 758 mdb_printf("Number of active Transact.: %u\n\n", 759 se->s_xa_list.ll_count); 760 } else { 761 if (DCMD_HDRSPEC(flags)) 762 mdb_printf( 763 "%<b>%<u>%-?s " 764 "%-16s " 765 "%-16s %-16s%</u>%</b>\n", 766 "SESSION", "CLIENT_IP_ADDR", 767 "LOCAL_IP_ADDR", "STATE"); 768 769 mdb_printf( 770 "%-?p %-16I %-16I %s\n", addr, se->ipaddr.a_ipv4, 771 se->local_ipaddr.a_ipv4, state); 772 } 773 } 774 if (smb_obj_expand(addr, opts, smb_session_exp, indent)) 775 return (DCMD_ERR); 776 return (DCMD_OK); 777 } 778 779 /* 780 * ***************************************************************************** 781 * **************************** smb_request_t ********************************** 782 * ***************************************************************************** 783 */ 784 785 static const char *smb_request_state[SMB_REQ_STATE_SENTINEL] = 786 { 787 "FREE", 788 "INITIALIZING", 789 "SUBMITTED", 790 "ACTIVE", 791 "WAITING_EVENT", 792 "EVENT_OCCURRED", 793 "WAITING_LOCK", 794 "COMPLETED", 795 "CANCELED", 796 "CLEANED_UP" 797 }; 798 799 #define SMB_REQUEST_BANNER \ 800 "%<b>%<u>%-?s %-?s %-14s %-14s %-16s %-32s%</u>%</b>\n" 801 #define SMB_REQUEST_FORMAT \ 802 "%-?p %-?p %e %e %-16s %s\n" 803 804 static int 805 smb_dcmd_request(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv) 806 { 807 uint_t opts; 808 809 if (smb_dcmd_getopt(&opts, argc, argv)) 810 return (DCMD_USAGE); 811 812 if (!(flags & DCMD_ADDRSPEC)) { 813 opts |= SMB_OPT_REQUEST; 814 opts &= ~(SMB_OPT_SERVER | SMB_OPT_SESSION | SMB_OPT_USER); 815 return (smb_obj_list("smb_request", opts, flags)); 816 } 817 818 if (((opts & SMB_OPT_WALK) && (opts & SMB_OPT_REQUEST)) || 819 !(opts & SMB_OPT_WALK)) { 820 smb_request_t *sr; 821 const char *state; 822 uint64_t waiting; 823 uint64_t running; 824 825 sr = mdb_alloc(sizeof (*sr), UM_SLEEP | UM_GC); 826 if (mdb_vread(sr, sizeof (*sr), addr) == -1) { 827 mdb_warn("failed to read smb_request at %p", addr); 828 return (DCMD_ERR); 829 } 830 if (sr->sr_magic != SMB_REQ_MAGIC) { 831 mdb_warn("not an smb_request_t (%p)>", addr); 832 return (DCMD_ERR); 833 } 834 waiting = 0; 835 running = 0; 836 if (sr->sr_time_submitted != 0) { 837 if (sr->sr_time_active != 0) { 838 waiting = sr->sr_time_active - 839 sr->sr_time_submitted; 840 running = mdb_gethrtime() - 841 sr->sr_time_active; 842 } else { 843 waiting = mdb_gethrtime() - 844 sr->sr_time_submitted; 845 } 846 } 847 waiting /= NANOSEC; 848 running /= NANOSEC; 849 850 if (sr->sr_state >= SMB_REQ_STATE_SENTINEL) 851 state = "INVALID"; 852 else 853 state = smb_request_state[sr->sr_state]; 854 855 if (opts & SMB_OPT_VERBOSE) { 856 mdb_printf( 857 "%</b>%</u>SMB request information (%p):" 858 "%</u>%</b>\n\n", addr); 859 860 mdb_printf( 861 "first SMB COM: %u (%s)\n" 862 "current SMB COM: %u (%s)\n" 863 "state: %u (%s)\n" 864 "TID(tree): %u (%p)\n" 865 "UID(user): %u (%p)\n" 866 "FID(file): %u (%p)\n" 867 "PID: %u\n" 868 "MID: %u\n\n" 869 "waiting time: %1.3e\n" 870 "running time: %1.3e", 871 sr->first_smb_com, smb_com[sr->first_smb_com], 872 sr->smb_com, smb_com[sr->smb_com], 873 sr->sr_state, state, 874 sr->smb_tid, sr->tid_tree, 875 sr->smb_uid, sr->uid_user, 876 sr->smb_fid, sr->fid_ofile, 877 sr->smb_pid, 878 sr->smb_mid, 879 waiting, 880 running); 881 882 smb_worker_findstack((uintptr_t)sr->sr_worker); 883 } else { 884 if (DCMD_HDRSPEC(flags)) 885 mdb_printf( 886 SMB_REQUEST_BANNER, 887 "ADDR", 888 "WORKER", 889 "WAITING(s)", 890 "RUNNING(s)", 891 "STATE", 892 "COMMAND"); 893 894 mdb_printf(SMB_REQUEST_FORMAT, 895 addr, 896 sr->sr_worker, 897 waiting, 898 running, 899 state, 900 smb_com[sr->smb_com]); 901 } 902 } 903 return (DCMD_OK); 904 } 905 906 /* 907 * ***************************************************************************** 908 * ****************************** smb_user_t *********************************** 909 * ***************************************************************************** 910 */ 911 912 static const char *smb_user_state[SMB_USER_STATE_SENTINEL] = 913 { 914 "LOGGED_IN", 915 "LOGGING_OFF", 916 "LOGGED_OFF" 917 }; 918 919 /* 920 * List of objects that can be expanded under a user structure. 921 */ 922 static const smb_exp_t smb_user_exp[] = 923 { 924 { SMB_OPT_TREE | SMB_OPT_OFILE | SMB_OPT_ODIR, 925 offsetof(smb_user_t, u_tree_list.ll_list), 926 "smbtree", "smb_tree"}, 927 { 0, 0, NULL, NULL} 928 }; 929 930 static void 931 smb_dcmd_user_help(void) 932 { 933 mdb_printf( 934 "Display the contents of smb_user_t, with optional filtering.\n\n"); 935 (void) mdb_dec_indent(2); 936 mdb_printf("%<b>OPTIONS%</b>\n"); 937 (void) mdb_inc_indent(2); 938 mdb_printf( 939 "-v\tDisplay verbose smb_user information\n" 940 "-d\tDisplay the list of smb_odirs attached\n" 941 "-f\tDisplay the list of smb_ofiles attached\n" 942 "-t\tDisplay the list of smb_trees attached\n"); 943 } 944 945 static int 946 smb_dcmd_user(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv) 947 { 948 uint_t opts; 949 ulong_t indent = 0; 950 951 if (smb_dcmd_getopt(&opts, argc, argv)) 952 return (DCMD_USAGE); 953 954 if (!(flags & DCMD_ADDRSPEC)) { 955 opts |= SMB_OPT_USER; 956 opts &= ~(SMB_OPT_SERVER | SMB_OPT_SESSION | SMB_OPT_REQUEST); 957 return (smb_obj_list("smb_user", opts, flags)); 958 } 959 960 if (((opts & SMB_OPT_WALK) && (opts & SMB_OPT_USER)) || 961 !(opts & SMB_OPT_WALK)) { 962 smb_user_t *user; 963 char *account; 964 965 indent = SMB_DCMD_INDENT; 966 967 user = mdb_alloc(sizeof (*user), UM_SLEEP | UM_GC); 968 if (mdb_vread(user, sizeof (*user), addr) == -1) { 969 mdb_warn("failed to read smb_user at %p", addr); 970 return (DCMD_ERR); 971 } 972 account = mdb_zalloc(user->u_domain_len + user->u_name_len + 2, 973 UM_SLEEP | UM_GC); 974 975 if (user->u_domain_len) 976 (void) mdb_vread(account, user->u_domain_len, 977 (uintptr_t)user->u_domain); 978 979 strcat(account, "\\"); 980 981 if (user->u_name_len) 982 (void) mdb_vread(account + strlen(account), 983 user->u_name_len, (uintptr_t)user->u_name); 984 985 if (opts & SMB_OPT_VERBOSE) { 986 const char *state; 987 988 if (user->u_state >= SMB_USER_STATE_SENTINEL) 989 state = "INVALID"; 990 else 991 state = smb_user_state[user->u_state]; 992 993 mdb_printf("%<b>%<u>SMB user information (%p):" 994 "%</u>%</b>\n", addr); 995 mdb_printf("UID: %u\n", user->u_uid); 996 mdb_printf("State: %d (%s)\n", user->u_state, state); 997 mdb_printf("Flags: 0x%08x\n", user->u_flags); 998 mdb_printf("Privileges: 0x%08x\n", user->u_privileges); 999 mdb_printf("Credential: %p\n", user->u_cred); 1000 mdb_printf("Reference Count: %d\n", user->u_refcnt); 1001 mdb_printf("User Account: %s\n\n", account); 1002 } else { 1003 if (DCMD_HDRSPEC(flags)) 1004 mdb_printf( 1005 "%<b>%<u>%?-s " 1006 "%-5s " 1007 "%-32s%</u>%</b>\n", 1008 "USER", "UID", "ACCOUNT"); 1009 1010 mdb_printf("%-?p %-5u %-32s\n", addr, user->u_uid, 1011 account); 1012 } 1013 } 1014 if (smb_obj_expand(addr, opts, smb_user_exp, indent)) 1015 return (DCMD_ERR); 1016 return (DCMD_OK); 1017 } 1018 1019 /* 1020 * ***************************************************************************** 1021 * ****************************** smb_tree_t *********************************** 1022 * ***************************************************************************** 1023 */ 1024 1025 static const char *smb_tree_state[SMB_TREE_STATE_SENTINEL] = 1026 { 1027 "CONNECTED", 1028 "DISCONNECTING", 1029 "DISCONNECTED" 1030 }; 1031 1032 /* 1033 * List of objects that can be expanded under a tree structure. 1034 */ 1035 static const smb_exp_t smb_tree_exp[] = 1036 { 1037 { SMB_OPT_OFILE, 1038 offsetof(smb_tree_t, t_ofile_list.ll_list), 1039 "smbofile", "smb_ofile"}, 1040 { SMB_OPT_ODIR, 1041 offsetof(smb_tree_t, t_odir_list.ll_list), 1042 "smbodir", "smb_odir"}, 1043 { 0, 0, NULL, NULL} 1044 }; 1045 1046 static void 1047 smb_dcmd_tree_help(void) 1048 { 1049 mdb_printf( 1050 "Display the contents of smb_tree_t, with optional filtering.\n\n"); 1051 (void) mdb_dec_indent(2); 1052 mdb_printf("%<b>OPTIONS%</b>\n"); 1053 (void) mdb_inc_indent(2); 1054 mdb_printf( 1055 "-v\tDisplay verbose smb_tree information\n" 1056 "-d\tDisplay the list of smb_odirs attached\n" 1057 "-f\tDisplay the list of smb_ofiles attached\n"); 1058 } 1059 1060 static int 1061 smb_dcmd_tree(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv) 1062 { 1063 uint_t opts; 1064 ulong_t indent = 0; 1065 1066 if (smb_dcmd_getopt(&opts, argc, argv)) 1067 return (DCMD_USAGE); 1068 1069 if (!(flags & DCMD_ADDRSPEC)) { 1070 opts |= SMB_OPT_TREE; 1071 opts &= ~(SMB_OPT_SERVER | SMB_OPT_SESSION | SMB_OPT_REQUEST | 1072 SMB_OPT_USER); 1073 return (smb_obj_list("smb_tree", opts, flags)); 1074 } 1075 1076 if (((opts & SMB_OPT_WALK) && (opts & SMB_OPT_TREE)) || 1077 !(opts & SMB_OPT_WALK)) { 1078 smb_tree_t *tree; 1079 1080 indent = SMB_DCMD_INDENT; 1081 1082 tree = mdb_alloc(sizeof (*tree), UM_SLEEP | UM_GC); 1083 if (mdb_vread(tree, sizeof (*tree), addr) == -1) { 1084 mdb_warn("failed to read smb_tree at %p", addr); 1085 return (DCMD_ERR); 1086 } 1087 if (opts & SMB_OPT_VERBOSE) { 1088 const char *state; 1089 1090 if (tree->t_state >= SMB_TREE_STATE_SENTINEL) 1091 state = "INVALID"; 1092 else 1093 state = smb_tree_state[tree->t_state]; 1094 1095 mdb_printf("%<b>%<u>SMB tree information (%p):" 1096 "%</u>%</b>\n\n", addr); 1097 mdb_printf("TID: %04x\n", tree->t_tid); 1098 mdb_printf("State: %d (%s)\n", tree->t_state, state); 1099 mdb_printf("Share: %s\n", tree->t_sharename); 1100 mdb_printf("Resource: %s\n", tree->t_resource); 1101 mdb_printf("Type: %s\n", tree->t_typename); 1102 mdb_printf("Volume: %s\n", tree->t_volume); 1103 mdb_printf("Umask: %04x\n", tree->t_umask); 1104 mdb_printf("Flags: %08x\n", tree->t_flags); 1105 mdb_printf("SMB Node: %llx\n", tree->t_snode); 1106 mdb_printf("Reference Count: %d\n\n", tree->t_refcnt); 1107 } else { 1108 if (DCMD_HDRSPEC(flags)) 1109 mdb_printf( 1110 "%<b>%<u>%-?s %-5s %-16s %-32s%</u>%</b>\n", 1111 "TREE", "TID", "SHARE NAME", "RESOURCE"); 1112 1113 mdb_printf("%-?p %-5u %-16s %-32s\n", addr, 1114 tree->t_tid, tree->t_sharename, tree->t_resource); 1115 } 1116 } 1117 if (smb_obj_expand(addr, opts, smb_tree_exp, indent)) 1118 return (DCMD_ERR); 1119 return (DCMD_OK); 1120 } 1121 1122 /* 1123 * ***************************************************************************** 1124 * ****************************** smb_odir_t *********************************** 1125 * ***************************************************************************** 1126 */ 1127 1128 static const char *smb_odir_state[SMB_ODIR_STATE_SENTINEL] = 1129 { 1130 "OPEN", 1131 "IN_USE", 1132 "CLOSING", 1133 "CLOSED" 1134 }; 1135 1136 static int 1137 smb_dcmd_odir(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv) 1138 { 1139 uint_t opts; 1140 1141 if (smb_dcmd_getopt(&opts, argc, argv)) 1142 return (DCMD_USAGE); 1143 1144 if (!(flags & DCMD_ADDRSPEC)) { 1145 opts |= SMB_OPT_ODIR; 1146 opts &= ~(SMB_OPT_SERVER | SMB_OPT_SESSION | SMB_OPT_REQUEST | 1147 SMB_OPT_USER | SMB_OPT_TREE | SMB_OPT_OFILE); 1148 return (smb_obj_list("smb_odir", opts, flags)); 1149 } 1150 1151 if (((opts & SMB_OPT_WALK) && (opts & SMB_OPT_ODIR)) || 1152 !(opts & SMB_OPT_WALK)) { 1153 smb_odir_t *od; 1154 1155 od = mdb_alloc(sizeof (*od), UM_SLEEP | UM_GC); 1156 if (mdb_vread(od, sizeof (*od), addr) == -1) { 1157 mdb_warn("failed to read smb_odir at %p", addr); 1158 return (DCMD_ERR); 1159 } 1160 if (opts & SMB_OPT_VERBOSE) { 1161 const char *state; 1162 1163 if (od->d_state >= SMB_ODIR_STATE_SENTINEL) 1164 state = "INVALID"; 1165 else 1166 state = smb_odir_state[od->d_state]; 1167 1168 mdb_printf( 1169 "%<b>%<u>SMB odir information (%p):%</u>%</b>\n\n", 1170 addr); 1171 mdb_printf("State: %d (%s)\n", od->d_state, state); 1172 mdb_printf("SID: %u\n", od->d_odid); 1173 mdb_printf("Reference Count: %d\n", od->d_refcnt); 1174 mdb_printf("Pattern: %s\n", od->d_pattern); 1175 mdb_printf("SMB Node: %p\n\n", od->d_dnode); 1176 } else { 1177 if (DCMD_HDRSPEC(flags)) 1178 mdb_printf( 1179 "%<b>%<u>%-?s " 1180 "%-5s " 1181 "%-?s " 1182 "%-16s%</u>%</b>\n", 1183 "ODIR", "SID", "VNODE", "PATTERN"); 1184 1185 mdb_printf("%?p %-5u %-16p %s\n", 1186 addr, od->d_odid, od->d_dnode, od->d_pattern); 1187 } 1188 } 1189 return (DCMD_OK); 1190 } 1191 1192 /* 1193 * ***************************************************************************** 1194 * ****************************** smb_ofile_t ********************************** 1195 * ***************************************************************************** 1196 */ 1197 1198 static const char *smb_ofile_state[SMB_OFILE_STATE_SENTINEL] = 1199 { 1200 "OPEN", 1201 "CLOSING", 1202 "CLOSED" 1203 }; 1204 1205 static int 1206 smb_dcmd_ofile(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv) 1207 { 1208 uint_t opts; 1209 1210 if (smb_dcmd_getopt(&opts, argc, argv)) 1211 return (DCMD_USAGE); 1212 1213 if (!(flags & DCMD_ADDRSPEC)) { 1214 opts |= SMB_OPT_OFILE; 1215 opts &= ~(SMB_OPT_SERVER | SMB_OPT_SESSION | SMB_OPT_REQUEST | 1216 SMB_OPT_USER | SMB_OPT_TREE | SMB_OPT_ODIR); 1217 return (smb_obj_list("smb_ofile", opts, flags)); 1218 } 1219 1220 if (((opts & SMB_OPT_WALK) && (opts & SMB_OPT_OFILE)) || 1221 !(opts & SMB_OPT_WALK)) { 1222 smb_ofile_t *of; 1223 1224 of = mdb_alloc(sizeof (*of), UM_SLEEP | UM_GC); 1225 if (mdb_vread(of, sizeof (*of), addr) == -1) { 1226 mdb_warn("failed to read smb_ofile at %p", addr); 1227 return (DCMD_ERR); 1228 } 1229 if (opts & SMB_OPT_VERBOSE) { 1230 const char *state; 1231 1232 if (of->f_state >= SMB_ODIR_STATE_SENTINEL) 1233 state = "INVALID"; 1234 else 1235 state = smb_ofile_state[of->f_state]; 1236 1237 mdb_printf( 1238 "%<b>%<u>SMB ofile information (%p):%</u>%</b>\n\n", 1239 addr); 1240 mdb_printf("FID: %u\n", of->f_fid); 1241 mdb_printf("State: %d (%s)\n", of->f_state, state); 1242 mdb_printf("SMB Node: %p\n", of->f_node); 1243 mdb_printf("LLF Offset: 0x%llx (%s)\n", 1244 of->f_llf_pos, 1245 ((of->f_flags & SMB_OFLAGS_LLF_POS_VALID) ? 1246 "Valid" : "Invalid")); 1247 mdb_printf("Flags: 0x%08x\n", of->f_flags); 1248 mdb_printf("Credential: %p\n\n", of->f_cr); 1249 } else { 1250 if (DCMD_HDRSPEC(flags)) 1251 mdb_printf( 1252 "%<b>%<u>%-?s " 1253 "%-5s " 1254 "%-?s " 1255 "%-?s%</u>%</b>\n", 1256 "OFILE", "FID", "SMB NODE", "CRED"); 1257 1258 mdb_printf("%?p %-5u %-p %p\n", addr, 1259 of->f_fid, of->f_node, of->f_cr); 1260 } 1261 } 1262 return (DCMD_OK); 1263 } 1264 1265 /* 1266 * ***************************************************************************** 1267 * ******************************** smb_vfs_t ********************************** 1268 * ***************************************************************************** 1269 */ 1270 1271 /* 1272 * ::smbvfs 1273 * 1274 * smbvfs dcmd - Prints out smb_vfs structures. 1275 */ 1276 /*ARGSUSED*/ 1277 static int 1278 smb_vfs(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv) 1279 { 1280 int verbose = FALSE; 1281 smb_vfs_t *sf; 1282 vnode_t *vn; 1283 char *path; 1284 1285 if (mdb_getopts(argc, argv, 1286 'v', MDB_OPT_SETBITS, TRUE, &verbose, 1287 NULL) != argc) 1288 return (DCMD_USAGE); 1289 1290 /* 1291 * If no smb_vfs address was specified on the command line, we can 1292 * print out all smb_vfs by invoking the smb_vfs walker, using 1293 * this dcmd itself as the callback. 1294 */ 1295 if (!(flags & DCMD_ADDRSPEC)) { 1296 if (mdb_walk_dcmd("smbvfs_walker", "smbvfs", 1297 argc, argv) == -1) { 1298 mdb_warn("failed to walk 'smb_vfs'"); 1299 return (DCMD_ERR); 1300 } 1301 return (DCMD_OK); 1302 } 1303 1304 if (DCMD_HDRSPEC(flags)) { 1305 mdb_printf( 1306 "%<b>%<u>" 1307 "%-?s " 1308 "%-10s " 1309 "%-16s " 1310 "%-16s" 1311 "%-s" 1312 "%</u>%</b>\n", 1313 "SMB_VFS", "REFCNT", "VFS", "VNODE", "ROOT"); 1314 } 1315 1316 sf = mdb_alloc(sizeof (*sf), UM_SLEEP | UM_GC); 1317 if (mdb_vread(sf, sizeof (*sf), addr) == -1) { 1318 mdb_warn("failed to read smb_vfs at %p", addr); 1319 return (DCMD_ERR); 1320 } 1321 1322 vn = mdb_alloc(sizeof (*vn), UM_SLEEP | UM_GC); 1323 if (mdb_vread(vn, sizeof (*vn), 1324 (uintptr_t)sf->sv_rootvp) == -1) { 1325 mdb_warn("failed to read vnode at %p", sf->sv_rootvp); 1326 return (DCMD_ERR); 1327 } 1328 1329 path = mdb_zalloc(MAXPATHLEN, UM_SLEEP | UM_GC); 1330 (void) mdb_vread(path, MAXPATHLEN, (uintptr_t)vn->v_path); 1331 1332 mdb_printf( 1333 "%-?p %-10d %-?p %-?p %-s\n", addr, sf->sv_refcnt, 1334 sf->sv_vfsp, sf->sv_rootvp, path); 1335 1336 return (DCMD_OK); 1337 } 1338 1339 /* 1340 * Initialize the smb_vfs_t walker by reading the value of smb_export 1341 * in the kernel's symbol table. Only global walk supported. 1342 */ 1343 static int 1344 smb_vfs_walk_init(mdb_walk_state_t *wsp) 1345 { 1346 GElf_Sym sym; 1347 1348 if (wsp->walk_addr != NULL) { 1349 mdb_printf("smb_vfs walk only supports global walks\n"); 1350 return (WALK_ERR); 1351 } 1352 1353 if (mdb_lookup_by_name("smb_export", &sym) == -1) { 1354 mdb_warn("failed to find 'smb_export'"); 1355 return (WALK_ERR); 1356 } 1357 1358 wsp->walk_addr = (uintptr_t)sym.st_value + 1359 offsetof(smb_export_t, e_vfs_list) + offsetof(smb_llist_t, ll_list); 1360 1361 if (mdb_layered_walk("list", wsp) == -1) { 1362 mdb_warn("failed to walk list of VFS"); 1363 return (WALK_ERR); 1364 } 1365 1366 return (WALK_NEXT); 1367 } 1368 1369 static int 1370 smb_vfs_walk_step(mdb_walk_state_t *wsp) 1371 { 1372 return (wsp->walk_callback(wsp->walk_addr, wsp->walk_layer, 1373 wsp->walk_cbdata)); 1374 } 1375 1376 /* 1377 * ***************************************************************************** 1378 * ******************************* smb_node_t ********************************** 1379 * ***************************************************************************** 1380 */ 1381 1382 static void 1383 smb_node_help(void) 1384 { 1385 mdb_printf( 1386 "Display the contents of smb_node_t, with optional filtering.\n\n"); 1387 (void) mdb_dec_indent(2); 1388 mdb_printf("%<b>OPTIONS%</b>\n"); 1389 (void) mdb_inc_indent(2); 1390 mdb_printf( 1391 "-v\tDisplay verbose smb_node information\n" 1392 "-p\tDisplay the full path of the vnode associated\n" 1393 "-s\tDisplay the stack of the last 16 calls that modified the " 1394 "reference\n\tcount\n"); 1395 } 1396 1397 /* 1398 * ::smbnode 1399 * 1400 * smb_node dcmd - Print out smb_node structure. 1401 */ 1402 static int 1403 smb_node(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv) 1404 { 1405 smb_node_t node; 1406 int verbose = FALSE; 1407 int print_full_path = FALSE; 1408 int stack_trace = FALSE; 1409 vnode_t vnode; 1410 char od_name[MAXNAMELEN]; 1411 char path_name[1024]; 1412 uintptr_t list_addr; 1413 1414 if (mdb_getopts(argc, argv, 1415 'v', MDB_OPT_SETBITS, TRUE, &verbose, 1416 'p', MDB_OPT_SETBITS, TRUE, &print_full_path, 1417 's', MDB_OPT_SETBITS, TRUE, &stack_trace, 1418 NULL) != argc) 1419 return (DCMD_USAGE); 1420 1421 /* 1422 * If no smb_node address was specified on the command line, we can 1423 * print out all smb nodes by invoking the smb_node walker, using 1424 * this dcmd itself as the callback. 1425 */ 1426 if (!(flags & DCMD_ADDRSPEC)) { 1427 if (mdb_walk_dcmd("smbnode_walker", "smbnode", 1428 argc, argv) == -1) { 1429 mdb_warn("failed to walk 'smb_node'"); 1430 return (DCMD_ERR); 1431 } 1432 return (DCMD_OK); 1433 } 1434 1435 /* 1436 * If this is the first invocation of the command, print a nice 1437 * header line for the output that will follow. 1438 */ 1439 if (DCMD_HDRSPEC(flags)) { 1440 if (verbose) { 1441 mdb_printf("%<b>%<u>SMB node information:%</u>%</b>\n"); 1442 } else { 1443 mdb_printf( 1444 "%<b>%<u>%-?s " 1445 "%-?s " 1446 "%-18s " 1447 "%-6s " 1448 "%-6s " 1449 "%-6s%</u>%</b>\n", 1450 "ADDR", "VP", "NODE-NAME", "OFILES", "LOCKS", 1451 "REF"); 1452 } 1453 } 1454 1455 /* 1456 * For each smb_node, we just need to read the smb_node_t struct, read 1457 * and then print out the following fields. 1458 */ 1459 if (mdb_vread(&node, sizeof (node), addr) == sizeof (node)) { 1460 (void) mdb_snprintf(od_name, sizeof (od_name), "%s", 1461 node.od_name); 1462 if (print_full_path) { 1463 if (mdb_vread(&vnode, sizeof (vnode_t), 1464 (uintptr_t)node.vp) == sizeof (vnode_t)) { 1465 if (mdb_readstr(path_name, sizeof (path_name), 1466 (uintptr_t)vnode.v_path) != 0) { 1467 (void) mdb_snprintf(od_name, 1468 sizeof (od_name), "N/A"); 1469 } 1470 } 1471 } 1472 if (verbose) { 1473 mdb_printf("VP: %p\n", node.vp); 1474 mdb_printf("Name: %s\n", od_name); 1475 if (print_full_path) 1476 mdb_printf("V-node Path: %s\n", path_name); 1477 mdb_printf("Ofiles: %u\n", node.n_ofile_list.ll_count); 1478 mdb_printf("Range Locks: %u\n", 1479 node.n_lock_list.ll_count); 1480 if (node.n_lock_list.ll_count != 0) { 1481 (void) mdb_inc_indent(SMB_DCMD_INDENT); 1482 list_addr = addr + 1483 offsetof(smb_node_t, n_lock_list) + 1484 offsetof(smb_llist_t, ll_list); 1485 if (mdb_pwalk_dcmd("list", "smblock", 0, 1486 NULL, list_addr)) { 1487 mdb_warn("failed to walk node's active" 1488 " locks"); 1489 } 1490 (void) mdb_dec_indent(SMB_DCMD_INDENT); 1491 } 1492 mdb_printf("Reference Count: %u\n\n", node.n_refcnt); 1493 } else { 1494 mdb_printf("%-?p %-?p %-18s %-6d %-6d %-6d\n", 1495 addr, node.vp, od_name, node.n_ofile_list.ll_count, 1496 node.n_lock_list.ll_count, node.n_refcnt); 1497 if (print_full_path) 1498 mdb_printf("\t%s\n", path_name); 1499 } 1500 if (stack_trace && node.n_audit_buf) { 1501 int ctr; 1502 smb_audit_buf_node_t *anb; 1503 1504 anb = mdb_alloc(sizeof (smb_audit_buf_node_t), 1505 UM_SLEEP | UM_GC); 1506 1507 if (mdb_vread(anb, sizeof (*anb), 1508 (uintptr_t)node.n_audit_buf) != sizeof (*anb)) { 1509 mdb_warn("failed to read audit buffer"); 1510 return (DCMD_ERR); 1511 } 1512 ctr = anb->anb_max_index + 1; 1513 anb->anb_index--; 1514 anb->anb_index &= anb->anb_max_index; 1515 1516 while (ctr) { 1517 smb_audit_record_node_t *anr; 1518 1519 anr = anb->anb_records + anb->anb_index; 1520 1521 if (anr->anr_depth) { 1522 char c[MDB_SYM_NAMLEN]; 1523 GElf_Sym sym; 1524 int i; 1525 1526 mdb_printf("\nRefCnt: %u\t", 1527 anr->anr_refcnt); 1528 1529 for (i = 0; 1530 i < anr->anr_depth; 1531 i++) { 1532 if (mdb_lookup_by_addr( 1533 anr->anr_stack[i], 1534 MDB_SYM_FUZZY, 1535 c, sizeof (c), 1536 &sym) == -1) { 1537 continue; 1538 } 1539 mdb_printf("%s+0x%1x", 1540 c, 1541 anr->anr_stack[i] - 1542 (uintptr_t)sym.st_value); 1543 ++i; 1544 break; 1545 } 1546 1547 while (i < anr->anr_depth) { 1548 if (mdb_lookup_by_addr( 1549 anr->anr_stack[i], 1550 MDB_SYM_FUZZY, 1551 c, sizeof (c), 1552 &sym) == -1) { 1553 ++i; 1554 continue; 1555 } 1556 mdb_printf("\n\t\t%s+0x%1x", 1557 c, 1558 anr->anr_stack[i] - 1559 (uintptr_t)sym.st_value); 1560 ++i; 1561 } 1562 mdb_printf("\n"); 1563 } 1564 anb->anb_index--; 1565 anb->anb_index &= anb->anb_max_index; 1566 ctr--; 1567 } 1568 } 1569 } else { 1570 mdb_warn("failed to read struct smb_node at %p", addr); 1571 return (DCMD_ERR); 1572 } 1573 1574 return (DCMD_OK); 1575 } 1576 1577 /* 1578 * Initialize the smb_node_t walker by reading the value of smb_node_hash_table 1579 * in the kernel's symbol table. Only global walk supported. 1580 */ 1581 static int 1582 smb_node_walk_init(mdb_walk_state_t *wsp) 1583 { 1584 GElf_Sym sym; 1585 int i; 1586 uintptr_t node_hash_table_addr; 1587 1588 if (wsp->walk_addr == NULL) { 1589 if (mdb_lookup_by_name("smb_node_hash_table", &sym) == -1) { 1590 mdb_warn("failed to find 'smb_node_hash_table'"); 1591 return (WALK_ERR); 1592 } 1593 node_hash_table_addr = (uintptr_t)sym.st_value; 1594 } else { 1595 mdb_printf("smb_node walk only supports global walks\n"); 1596 return (WALK_ERR); 1597 } 1598 1599 for (i = 0; i < SMBND_HASH_MASK + 1; i++) { 1600 wsp->walk_addr = node_hash_table_addr + 1601 (i * sizeof (smb_llist_t)) + offsetof(smb_llist_t, ll_list); 1602 if (mdb_layered_walk("list", wsp) == -1) { 1603 mdb_warn("failed to walk 'list'"); 1604 return (WALK_ERR); 1605 } 1606 } 1607 1608 return (WALK_NEXT); 1609 } 1610 1611 static int 1612 smb_node_walk_step(mdb_walk_state_t *wsp) 1613 { 1614 return (wsp->walk_callback(wsp->walk_addr, wsp->walk_layer, 1615 wsp->walk_cbdata)); 1616 } 1617 1618 /* 1619 * ***************************************************************************** 1620 * ****************************** smb_lock_t *********************************** 1621 * ***************************************************************************** 1622 */ 1623 1624 static int 1625 smb_lock(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv) 1626 { 1627 smb_lock_t lock; 1628 int verbose = FALSE; 1629 uintptr_t list_addr; 1630 char *lock_type; 1631 1632 if (mdb_getopts(argc, argv, 1633 'v', MDB_OPT_SETBITS, TRUE, &verbose, 1634 NULL) != argc) 1635 return (DCMD_USAGE); 1636 1637 /* 1638 * An smb_lock_t address must be specified. 1639 */ 1640 if (!(flags & DCMD_ADDRSPEC)) 1641 return (DCMD_USAGE); 1642 1643 /* 1644 * If this is the first invocation of the command, print a nice 1645 * header line for the output that will follow. 1646 */ 1647 if (DCMD_HDRSPEC(flags)) { 1648 if (verbose) 1649 mdb_printf("SMB lock information:\n\n"); 1650 else 1651 mdb_printf("%<u>%-?s %4s %16s %8s %9s%</u>\n", 1652 "Locks: ", "TYPE", "START", "LENGTH", 1653 "CONFLICTS"); 1654 } 1655 1656 if (mdb_vread(&lock, sizeof (lock), addr) == sizeof (lock)) { 1657 switch (lock.l_type) { 1658 case SMB_LOCK_TYPE_READWRITE: 1659 lock_type = "RW"; 1660 break; 1661 case SMB_LOCK_TYPE_READONLY: 1662 lock_type = "RO"; 1663 break; 1664 default: 1665 lock_type = "N/A"; 1666 break; 1667 } 1668 if (verbose) { 1669 mdb_printf("Type :\t%s (%u)\n", 1670 lock_type, lock.l_type); 1671 mdb_printf("Start :\t%llx\n", 1672 lock.l_start); 1673 mdb_printf("Length :\t%lx\n", 1674 lock.l_length); 1675 mdb_printf("Session :\t%p\n", 1676 lock.l_session); 1677 mdb_printf("File :\t%p\n", 1678 lock.l_file); 1679 mdb_printf("User ID :\t%u\n", 1680 lock.l_uid); 1681 mdb_printf("Process ID :\t%u\n", 1682 lock.l_pid); 1683 mdb_printf("Conflicts :\t%u\n", 1684 lock.l_conflict_list.sl_count); 1685 if (lock.l_conflict_list.sl_count != 0) { 1686 (void) mdb_inc_indent(SMB_DCMD_INDENT); 1687 list_addr = addr + 1688 offsetof(smb_lock_t, l_conflict_list) + 1689 offsetof(smb_slist_t, sl_list); 1690 if (mdb_pwalk_dcmd("list", "smb_lock", 1691 0, NULL, list_addr)) { 1692 mdb_warn("failed to walk conflict " 1693 "locks "); 1694 } 1695 (void) mdb_dec_indent(SMB_DCMD_INDENT); 1696 } 1697 mdb_printf("Blocked by :\t%p\n", 1698 lock.l_blocked_by); 1699 mdb_printf("Flags :\t0x%x\n", 1700 lock.l_flags); 1701 mdb_printf("\n"); 1702 } else { 1703 mdb_printf("%?p %4s %16llx %08lx %9x", addr, 1704 lock_type, lock.l_start, lock.l_length, 1705 lock.l_conflict_list.sl_count); 1706 } 1707 } else { 1708 mdb_warn("failed to read struct smb_request at %p", addr); 1709 return (DCMD_ERR); 1710 } 1711 1712 return (DCMD_OK); 1713 } 1714 1715 /* 1716 * ::smbstat 1717 * 1718 * Prints SMB requests statistics. 1719 */ 1720 /*ARGSUSED*/ 1721 static int 1722 smb_stats(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv) 1723 { 1724 smb_server_t *sv; 1725 1726 if (!(flags & DCMD_ADDRSPEC)) 1727 return (DCMD_USAGE); 1728 1729 sv = mdb_alloc(sizeof (*sv), UM_SLEEP | UM_GC); 1730 if (mdb_vread(sv, sizeof (*sv), addr) == -1) { 1731 mdb_warn("failed to read server object at %p", addr); 1732 return (DCMD_ERR); 1733 } 1734 if (sv->sv_magic != SMB_SERVER_MAGIC) { 1735 mdb_warn("not an smb_server_t (%p)>", addr); 1736 return (DCMD_ERR); 1737 } 1738 mdb_printf( 1739 "\n%<b> nbt tcp users trees files pipes%</b>\n" 1740 "%5d %5d %5d %5d %5d %5d\n", 1741 sv->sv_nbt_sess, 1742 sv->sv_tcp_sess, 1743 sv->sv_users, 1744 sv->sv_trees, 1745 sv->sv_files, 1746 sv->sv_pipes); 1747 1748 return (DCMD_OK); 1749 } 1750 1751 /* 1752 * ***************************************************************************** 1753 * ******************************** smb_ace_t ********************************** 1754 * ***************************************************************************** 1755 */ 1756 static const ace_type_entry_t ace_types[ACE_TYPE_TABLEN] = 1757 { 1758 ACE_TYPE_ENTRY(ACE_ACCESS_ALLOWED_ACE_TYPE), 1759 ACE_TYPE_ENTRY(ACE_ACCESS_DENIED_ACE_TYPE), 1760 ACE_TYPE_ENTRY(ACE_SYSTEM_AUDIT_ACE_TYPE), 1761 ACE_TYPE_ENTRY(ACE_SYSTEM_ALARM_ACE_TYPE), 1762 ACE_TYPE_ENTRY(ACE_ACCESS_ALLOWED_COMPOUND_ACE_TYPE), 1763 ACE_TYPE_ENTRY(ACE_ACCESS_ALLOWED_OBJECT_ACE_TYPE), 1764 ACE_TYPE_ENTRY(ACE_ACCESS_DENIED_OBJECT_ACE_TYPE), 1765 ACE_TYPE_ENTRY(ACE_SYSTEM_AUDIT_OBJECT_ACE_TYPE), 1766 ACE_TYPE_ENTRY(ACE_SYSTEM_ALARM_OBJECT_ACE_TYPE), 1767 ACE_TYPE_ENTRY(ACE_ACCESS_ALLOWED_CALLBACK_ACE_TYPE), 1768 ACE_TYPE_ENTRY(ACE_ACCESS_DENIED_CALLBACK_ACE_TYPE), 1769 ACE_TYPE_ENTRY(ACE_ACCESS_ALLOWED_CALLBACK_OBJECT_ACE_TYPE), 1770 ACE_TYPE_ENTRY(ACE_ACCESS_DENIED_CALLBACK_OBJECT_ACE_TYPE), 1771 ACE_TYPE_ENTRY(ACE_SYSTEM_AUDIT_CALLBACK_ACE_TYPE), 1772 ACE_TYPE_ENTRY(ACE_SYSTEM_ALARM_CALLBACK_ACE_TYPE), 1773 ACE_TYPE_ENTRY(ACE_SYSTEM_AUDIT_CALLBACK_OBJECT_ACE_TYPE), 1774 ACE_TYPE_ENTRY(ACE_SYSTEM_ALARM_CALLBACK_OBJECT_ACE_TYPE), 1775 ACE_TYPE_ENTRY(0x11), 1776 ACE_TYPE_ENTRY(0x12), 1777 ACE_TYPE_ENTRY(0x13), 1778 ACE_TYPE_ENTRY(0x14), 1779 ACE_TYPE_ENTRY(0x15), 1780 ACE_TYPE_ENTRY(0x16), 1781 ACE_TYPE_ENTRY(0x17), 1782 ACE_TYPE_ENTRY(0x18), 1783 ACE_TYPE_ENTRY(0x19), 1784 ACE_TYPE_ENTRY(0x1A), 1785 ACE_TYPE_ENTRY(0x1B), 1786 ACE_TYPE_ENTRY(0x1C), 1787 ACE_TYPE_ENTRY(0x1D), 1788 ACE_TYPE_ENTRY(0x1E), 1789 ACE_TYPE_ENTRY(0x1F) 1790 }; 1791 1792 static const mdb_bitmask_t ace_flag_bits[] = { 1793 { "OBJECT_INHERIT_ACE", OBJECT_INHERIT_ACE, OBJECT_INHERIT_ACE }, 1794 { "CONTAINER_INHERIT_ACE", CONTAINER_INHERIT_ACE, 1795 CONTAINER_INHERIT_ACE }, 1796 { "NO_PROPOGATE_INHERIT_ACE", NO_PROPOGATE_INHERIT_ACE, 1797 NO_PROPOGATE_INHERIT_ACE }, 1798 { "INHERIT_ONLY_ACE", INHERIT_ONLY_ACE, INHERIT_ONLY_ACE }, 1799 { "INHERITED_ACE", INHERITED_ACE, INHERITED_ACE }, 1800 { "SUCCESSFUL_ACCESS_ACE_FLAG", SUCCESSFUL_ACCESS_ACE_FLAG, 1801 SUCCESSFUL_ACCESS_ACE_FLAG }, 1802 { "FAILED_ACCESS_ACE_FLAG", FAILED_ACCESS_ACE_FLAG, 1803 FAILED_ACCESS_ACE_FLAG }, 1804 { NULL, 0, 0 } 1805 }; 1806 1807 /* 1808 * ::smbace 1809 */ 1810 static int 1811 smb_ace(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv) 1812 { 1813 smb_ace_t ace; 1814 int verbose = FALSE; 1815 const char *ptr; 1816 int rc; 1817 1818 if (mdb_getopts(argc, argv, 'v', MDB_OPT_SETBITS, TRUE, &verbose, 1819 NULL) != argc) 1820 return (DCMD_USAGE); 1821 1822 /* 1823 * An smb_ace address is required. 1824 */ 1825 if (!(flags & DCMD_ADDRSPEC)) 1826 return (DCMD_USAGE); 1827 1828 if (mdb_vread(&ace, sizeof (ace), addr) != sizeof (ace)) { 1829 mdb_warn("failed to read struct smb_ace at %p", addr); 1830 return (DCMD_ERR); 1831 } 1832 1833 if (verbose) { 1834 if (ace.se_hdr.se_type < ACE_TYPE_TABLEN) 1835 ptr = ace_types[ace.se_hdr.se_type].ace_type_sting; 1836 else 1837 ptr = "Unknown"; 1838 1839 mdb_printf("ACE Type: 0x%02x (%s)\n", ace.se_hdr.se_type, ptr); 1840 mdb_printf("ACE Flags: %b\n", (int)ace.se_hdr.se_flags, 1841 ace_flag_bits); 1842 mdb_printf("ACE Wire Size: 0x%04x\n", ace.se_hdr.se_bsize); 1843 mdb_printf("ACE Mask: 0x%08x\n", ace.se_mask); 1844 mdb_printf("ACE SID: "); 1845 } else { 1846 if (DCMD_HDRSPEC(flags)) 1847 mdb_printf( 1848 "%<b>%<u>%?-s %-4s %-4s %-8s %s%</u>%</b>\n", 1849 "ACE", "TYPE", "FLAGS", "MASK", "SID"); 1850 mdb_printf("%?p 0x%02x 0x%02x 0x%08x ", addr, 1851 ace.se_hdr.se_type, ace.se_hdr.se_flags, ace.se_mask); 1852 } 1853 rc = smb_sid_print((uintptr_t)ace.se_sid); 1854 mdb_printf("\n"); 1855 return (rc); 1856 } 1857 1858 static int 1859 smb_ace_walk_init(mdb_walk_state_t *wsp) 1860 { 1861 if (wsp->walk_addr == 0) { 1862 mdb_printf("smb_ace walk only supports local walks\n"); 1863 return (WALK_ERR); 1864 } 1865 1866 wsp->walk_addr += offsetof(smb_acl_t, sl_sorted); 1867 1868 if (mdb_layered_walk("list", wsp) == -1) { 1869 mdb_warn("failed to walk list of ACEs"); 1870 return (WALK_ERR); 1871 } 1872 1873 return (WALK_NEXT); 1874 } 1875 1876 static int 1877 smb_ace_walk_step(mdb_walk_state_t *wsp) 1878 { 1879 return (wsp->walk_callback(wsp->walk_addr, wsp->walk_layer, 1880 wsp->walk_cbdata)); 1881 } 1882 1883 /* 1884 * ***************************************************************************** 1885 * ******************************** smb_acl_t ********************************** 1886 * ***************************************************************************** 1887 */ 1888 1889 /* 1890 * ::smbacl 1891 */ 1892 static int 1893 smb_acl(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv) 1894 { 1895 smb_acl_t acl; 1896 1897 /* An smb_acl address is required. */ 1898 if (!(flags & DCMD_ADDRSPEC)) 1899 return (DCMD_USAGE); 1900 1901 if (mdb_vread(&acl, sizeof (acl), addr) != sizeof (acl)) { 1902 mdb_warn("failed to read struct smb_acl at %p", addr); 1903 return (DCMD_ERR); 1904 } 1905 1906 mdb_printf("ACL Revision: %d\n", acl.sl_revision); 1907 mdb_printf("ACL Size on Wire: %d\n", acl.sl_bsize); 1908 mdb_printf("ACL Number of ACEs: %d\n", acl.sl_acecnt); 1909 1910 (void) mdb_inc_indent(SMB_DCMD_INDENT); 1911 if (mdb_pwalk_dcmd("smbace_walker", "smbace", argc, argv, addr)) { 1912 (void) mdb_dec_indent(SMB_DCMD_INDENT); 1913 mdb_warn("failed to walk list of ACEs for ACL %p", addr); 1914 return (DCMD_ERR); 1915 } 1916 (void) mdb_dec_indent(SMB_DCMD_INDENT); 1917 return (DCMD_OK); 1918 } 1919 1920 /* 1921 * ***************************************************************************** 1922 * ********************************* smb_sd_t ********************************** 1923 * ***************************************************************************** 1924 */ 1925 1926 /* 1927 * ::smbsd 1928 */ 1929 static int 1930 smb_sd(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv) 1931 { 1932 smb_sd_t sd; 1933 int rc; 1934 1935 /* 1936 * An smb_sid address is required. 1937 */ 1938 if (!(flags & DCMD_ADDRSPEC)) 1939 return (DCMD_USAGE); 1940 1941 if (mdb_vread(&sd, sizeof (sd), addr) != sizeof (sd)) { 1942 mdb_warn("failed to read struct smb_sd at %p", addr); 1943 return (DCMD_ERR); 1944 } 1945 1946 mdb_printf("SD Revision: %d\n", sd.sd_revision); 1947 mdb_printf("SD Control: %04x\n", sd.sd_control); 1948 if (sd.sd_control & SE_OWNER_DEFAULTED) 1949 mdb_printf("\t SE_OWNER_DEFAULTED\n"); 1950 if (sd.sd_control & SE_GROUP_DEFAULTED) 1951 mdb_printf("\t SE_GROUP_DEFAULTED\n"); 1952 if (sd.sd_control & SE_DACL_PRESENT) 1953 mdb_printf("\t SE_DACL_PRESENT\n"); 1954 if (sd.sd_control & SE_DACL_DEFAULTED) 1955 mdb_printf("\t SE_DACL_DEFAULTED\n"); 1956 if (sd.sd_control & SE_SACL_PRESENT) 1957 mdb_printf("\t SE_SACL_PRESENT\n"); 1958 if (sd.sd_control & SE_SACL_DEFAULTED) 1959 mdb_printf("\t SE_SACL_DEFAULTED\n"); 1960 if (sd.sd_control & SE_DACL_AUTO_INHERIT_REQ) 1961 mdb_printf("\t SE_DACL_AUTO_INHERIT_REQ\n"); 1962 if (sd.sd_control & SE_SACL_AUTO_INHERIT_REQ) 1963 mdb_printf("\t SE_SACL_AUTO_INHERIT_REQ\n"); 1964 if (sd.sd_control & SE_DACL_AUTO_INHERITED) 1965 mdb_printf("\t SE_DACL_AUTO_INHERITED\n"); 1966 if (sd.sd_control & SE_SACL_AUTO_INHERITED) 1967 mdb_printf("\t SE_SACL_AUTO_INHERITED\n"); 1968 if (sd.sd_control & SE_DACL_PROTECTED) 1969 mdb_printf("\t SE_DACL_PROTECTED\n"); 1970 if (sd.sd_control & SE_SACL_PROTECTED) 1971 mdb_printf("\t SE_SACL_PROTECTED\n"); 1972 if (sd.sd_control & SE_SELF_RELATIVE) 1973 mdb_printf("\t SE_SELF_RELATIVE\n"); 1974 1975 mdb_printf("SID of Owner: "); 1976 rc = smb_sid_print((uintptr_t)sd.sd_owner); 1977 if (rc != DCMD_OK) 1978 return (rc); 1979 mdb_printf("\nSID of Group: "); 1980 rc = smb_sid_print((uintptr_t)sd.sd_group); 1981 if (rc != DCMD_OK) 1982 return (rc); 1983 mdb_printf("\n"); 1984 1985 if (sd.sd_control & SE_SACL_PRESENT && sd.sd_sacl) { 1986 mdb_printf("%<b>%<u>System ACL%</u>%</b>\n"); 1987 (void) mdb_inc_indent(SMB_DCMD_INDENT); 1988 rc = mdb_call_dcmd("smbacl", (uintptr_t)sd.sd_sacl, flags, 1989 argc, argv); 1990 (void) mdb_dec_indent(SMB_DCMD_INDENT); 1991 if (rc != DCMD_OK) 1992 return (rc); 1993 } 1994 if (sd.sd_control & SE_DACL_PRESENT && sd.sd_dacl) { 1995 mdb_printf("%<b>%<u>Discretionary ACL%</u>%</b>\n"); 1996 (void) mdb_inc_indent(SMB_DCMD_INDENT); 1997 rc = mdb_call_dcmd("smbacl", (uintptr_t)sd.sd_dacl, flags, 1998 argc, argv); 1999 (void) mdb_dec_indent(SMB_DCMD_INDENT); 2000 if (rc != DCMD_OK) 2001 return (rc); 2002 } 2003 2004 return (DCMD_OK); 2005 } 2006 2007 /* 2008 * ***************************************************************************** 2009 * ********************************* smb_sid_t ********************************* 2010 * ***************************************************************************** 2011 */ 2012 2013 /* 2014 * ::smbsid 2015 */ 2016 /*ARGSUSED*/ 2017 static int 2018 smb_sid(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv) 2019 { 2020 /* 2021 * An smb_sid address is required. 2022 */ 2023 if (!(flags & DCMD_ADDRSPEC)) 2024 return (DCMD_USAGE); 2025 2026 return (smb_sid_print(addr)); 2027 } 2028 2029 /* 2030 * smb_sid_print 2031 */ 2032 static int 2033 smb_sid_print(uintptr_t addr) 2034 { 2035 smb_sid_t sid; 2036 smb_sid_t *psid; 2037 size_t sid_size; 2038 int i; 2039 uint64_t authority; 2040 2041 sid_size = offsetof(smb_sid_t, sid_subauth); 2042 2043 if (mdb_vread(&sid, sid_size, addr) != sid_size) { 2044 mdb_warn("failed to read struct smb_sid at %p", addr); 2045 return (DCMD_ERR); 2046 } 2047 2048 sid_size += sid.sid_subauthcnt * sizeof (sid.sid_subauth[0]); 2049 2050 psid = mdb_zalloc(sid_size, UM_SLEEP | UM_GC); 2051 if (mdb_vread(psid, sid_size, addr) != sid_size) { 2052 mdb_warn("failed to read struct smb_sid at %p", addr); 2053 return (DCMD_ERR); 2054 } 2055 2056 mdb_printf("S-%d", psid->sid_revision); 2057 authority = 0; 2058 for (i = 0; i < NT_SID_AUTH_MAX; i++) { 2059 authority += ((uint64_t)psid->sid_authority[i]) << 2060 (8 * (NT_SID_AUTH_MAX - 1) - i); 2061 } 2062 mdb_printf("-%ll", authority); 2063 2064 for (i = 0; i < psid->sid_subauthcnt; i++) 2065 mdb_printf("-%d", psid->sid_subauth[i]); 2066 2067 return (DCMD_OK); 2068 } 2069 2070 /* 2071 * ***************************************************************************** 2072 * ********************************* smb_fssd_t ******************************** 2073 * ***************************************************************************** 2074 */ 2075 2076 /* 2077 * ::smbfssd 2078 */ 2079 static int 2080 smb_fssd(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv) 2081 { 2082 smb_fssd_t fssd; 2083 int rc; 2084 2085 /* 2086 * An smb_fssd address is required. 2087 */ 2088 if (!(flags & DCMD_ADDRSPEC)) 2089 return (DCMD_USAGE); 2090 2091 if (mdb_vread(&fssd, sizeof (fssd), addr) != sizeof (fssd)) { 2092 mdb_warn("failed to read struct smb_fssd at %p", addr); 2093 return (DCMD_ERR); 2094 } 2095 2096 mdb_printf("FSSD secinfo: 0x%x\n", fssd.sd_secinfo); 2097 if (fssd.sd_secinfo & SMB_OWNER_SECINFO) 2098 mdb_printf("FSSD uid: %d\n", fssd.sd_uid); 2099 if (fssd.sd_secinfo & SMB_GROUP_SECINFO) 2100 mdb_printf("FSSD gid: %d\n", fssd.sd_gid); 2101 if (fssd.sd_secinfo & SMB_SACL_SECINFO && fssd.sd_zsacl) { 2102 mdb_printf("%<b>%<u>System ACL%</u>%</b>\n"); 2103 (void) mdb_inc_indent(SMB_DCMD_INDENT); 2104 rc = mdb_call_dcmd("smbacl", (uintptr_t)fssd.sd_zsacl, flags, 2105 argc, argv); 2106 (void) mdb_dec_indent(SMB_DCMD_INDENT); 2107 if (rc != DCMD_OK) 2108 return (rc); 2109 } 2110 if (fssd.sd_secinfo & SMB_DACL_SECINFO && fssd.sd_zdacl) { 2111 mdb_printf("%<b>%<u>Discretionary ACL%</u>%</b>\n"); 2112 (void) mdb_inc_indent(SMB_DCMD_INDENT); 2113 rc = mdb_call_dcmd("smbacl", (uintptr_t)fssd.sd_zdacl, flags, 2114 argc, argv); 2115 (void) mdb_dec_indent(SMB_DCMD_INDENT); 2116 if (rc != DCMD_OK) 2117 return (rc); 2118 } 2119 2120 return (DCMD_OK); 2121 } 2122 2123 /* 2124 * ***************************************************************************** 2125 * **************************** Utility Funcions ******************************* 2126 * ***************************************************************************** 2127 */ 2128 2129 /* 2130 * smb_dcmd_getopt 2131 * 2132 * This function analyzes the arguments passed in and sets the bit corresponding 2133 * to the options found in the opts variable. 2134 * 2135 * Return Value 2136 * 2137 * -1 An error occured during the decoding 2138 * 0 The decoding was successful 2139 */ 2140 static int 2141 smb_dcmd_getopt(uint_t *opts, int argc, const mdb_arg_t *argv) 2142 { 2143 *opts = 0; 2144 2145 if (mdb_getopts(argc, argv, 2146 's', MDB_OPT_SETBITS, SMB_OPT_SERVER, opts, 2147 'e', MDB_OPT_SETBITS, SMB_OPT_SESSION, opts, 2148 'r', MDB_OPT_SETBITS, SMB_OPT_REQUEST, opts, 2149 'u', MDB_OPT_SETBITS, SMB_OPT_USER, opts, 2150 't', MDB_OPT_SETBITS, SMB_OPT_TREE, opts, 2151 'f', MDB_OPT_SETBITS, SMB_OPT_OFILE, opts, 2152 'd', MDB_OPT_SETBITS, SMB_OPT_ODIR, opts, 2153 'w', MDB_OPT_SETBITS, SMB_OPT_WALK, opts, 2154 'v', MDB_OPT_SETBITS, SMB_OPT_VERBOSE, opts, 2155 NULL) != argc) 2156 return (-1); 2157 2158 return (0); 2159 } 2160 2161 /* 2162 * smb_dcmd_setopt 2163 * 2164 * This function set the arguments corresponding to the bits set in opts. 2165 * 2166 * Return Value 2167 * 2168 * Number of arguments set. 2169 */ 2170 static int 2171 smb_dcmd_setopt(uint_t opts, int max_argc, mdb_arg_t *argv) 2172 { 2173 int i; 2174 int argc = 0; 2175 2176 for (i = 0; i < SMB_MDB_MAX_OPTS; i++) { 2177 if ((opts & smb_opts[i].o_value) && (argc < max_argc)) { 2178 argv->a_type = MDB_TYPE_STRING; 2179 argv->a_un.a_str = smb_opts[i].o_name; 2180 argc++; 2181 argv++; 2182 } 2183 } 2184 return (argc); 2185 } 2186 2187 /* 2188 * smb_obj_expand 2189 */ 2190 static int 2191 smb_obj_expand(uintptr_t addr, uint_t opts, const smb_exp_t *x, ulong_t indent) 2192 { 2193 int rc = 0; 2194 int argc; 2195 mdb_arg_t argv[SMB_MDB_MAX_OPTS]; 2196 2197 argc = smb_dcmd_setopt(opts | SMB_OPT_WALK, SMB_MDB_MAX_OPTS, argv); 2198 2199 (void) mdb_inc_indent(indent); 2200 while (x->ex_dcmd) { 2201 if (x->ex_mask & opts) { 2202 rc = mdb_pwalk_dcmd("list", x->ex_dcmd, argc, argv, 2203 addr + x->ex_offset); 2204 2205 if (rc) { 2206 mdb_warn("failed to walk the list of %s in %p", 2207 x->ex_name, addr + x->ex_offset); 2208 break; 2209 } 2210 } 2211 x++; 2212 } 2213 (void) mdb_dec_indent(indent); 2214 return (rc); 2215 } 2216 2217 /* 2218 * smb_obj_list 2219 * 2220 * Function called by the DCMDs when no address is provided. It expands the 2221 * tree under the object type associated with the calling DCMD (based on the 2222 * flags passed in). 2223 * 2224 * Return Value 2225 * 2226 * DCMD_OK 2227 * DCMD_ERR 2228 */ 2229 static int 2230 smb_obj_list(const char *name, uint_t opts, uint_t flags) 2231 { 2232 int argc; 2233 mdb_arg_t argv[SMB_MDB_MAX_OPTS]; 2234 2235 argc = smb_dcmd_setopt(opts, SMB_MDB_MAX_OPTS, argv); 2236 2237 if (mdb_call_dcmd("smblist", 0, flags, argc, argv)) { 2238 mdb_warn("failed to list %s", name); 2239 return (DCMD_ERR); 2240 } 2241 return (DCMD_OK); 2242 } 2243 2244 static int 2245 smb_worker_findstack(uintptr_t addr) 2246 { 2247 kthread_t t; 2248 taskq_t tq; 2249 char cmd[80]; 2250 mdb_arg_t cmdarg; 2251 2252 if (mdb_vread(&t, sizeof (kthread_t), addr) == -1) { 2253 mdb_warn("failed to read kthread_t at %p", addr); 2254 return (DCMD_ERR); 2255 } 2256 2257 if (mdb_vread(&tq, sizeof (taskq_t), (uintptr_t)t.t_taskq) == -1) 2258 tq.tq_name[0] = '\0'; 2259 2260 mdb_inc_indent(2); 2261 2262 mdb_printf("PC: %a", t.t_pc); 2263 if (t.t_tid == 0) { 2264 if (tq.tq_name[0] != '\0') 2265 mdb_printf(" TASKQ: %s\n", tq.tq_name); 2266 else 2267 mdb_printf(" THREAD: %a()\n", t.t_startpc); 2268 } 2269 2270 mdb_snprintf(cmd, sizeof (cmd), "<.$c%d", 16); 2271 cmdarg.a_type = MDB_TYPE_STRING; 2272 cmdarg.a_un.a_str = cmd; 2273 (void) mdb_call_dcmd("findstack", addr, DCMD_ADDRSPEC, 1, &cmdarg); 2274 mdb_dec_indent(2); 2275 mdb_printf("\n"); 2276 return (DCMD_OK); 2277 } 2278