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