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