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