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