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