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