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