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