1/* 2 * Copyright (c) 2000-2001, Boris Popov 3 * All rights reserved. 4 * 5 * Portions Copyright (C) 2001 - 2014 Apple Inc. All rights reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions 9 * are met: 10 * 1. Redistributions of source code must retain the above copyright 11 * notice, this list of conditions and the following disclaimer. 12 * 2. Redistributions in binary form must reproduce the above copyright 13 * notice, this list of conditions and the following disclaimer in the 14 * documentation and/or other materials provided with the distribution. 15 * 3. All advertising materials mentioning features or use of this software 16 * must display the following acknowledgement: 17 * This product includes software developed by Boris Popov. 18 * 4. Neither the name of the author nor the names of any co-contributors 19 * may be used to endorse or promote products derived from this software 20 * without specific prior written permission. 21 * 22 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 23 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 24 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 25 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 26 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 27 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 28 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 29 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 30 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 31 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 32 * SUCH DAMAGE. 33 * 34 */ 35 36#ifndef _SMBFS_SMBFS_H_ 37#define _SMBFS_SMBFS_H_ 38 39#include <sys/kdebug.h> 40#include <netinet/in.h> 41#include <netsmb/netbios.h> 42 43#define SMBFS_VERMAJ 3 44#define SMBFS_VERMIN 0000 45#define SMBFS_VERSION (SMBFS_VERMAJ*100000 + SMBFS_VERMIN) 46#define SMBFS_VFSNAME "smbfs" 47#define SMBFS_LANMAN "SMBFS 3.0.0" /* Needs to match SMBFS_VERSION */ 48#define SMBFS_NATIVEOS "Mac OS X 10.10" /* Needs to match current OS version major number only */ 49#define SMBFS_SLASH_TONAME "/Volumes/0x2f" 50 51#define SMBFS_MAXPATHCOMP 256 /* maximum number of path components */ 52 53#include <sys/mount.h> 54 55#define SMB_STREAMS_ON ".com.apple.smb.streams.on" 56#define SMB_STREAMS_OFF ".com.apple.smb.streams.off" 57 58#define SMB_MAX_UNIQUE_ID 128 + MAXPATHLEN + (int32_t)sizeof(struct sockaddr_storage) /* Share name, path, sockaddr */ 59 60 61#define kGuestAccountName "GUEST" 62#define kGuestPassword "" 63 64 65struct ByteRangeLockPB { 66 int64_t offset; /* offset to first byte to lock */ 67 int64_t length; /* nbr of bytes to lock */ 68 uint64_t retRangeStart; /* nbr of first byte locked if successful */ 69 uint8_t unLockFlag; /* 1 = unlock, 0 = lock */ 70 uint8_t startEndFlag; /* 1 = rel to end of fork, 0 = rel to start */ 71}; 72 73struct ByteRangeLockPB2 { 74 int64_t offset; /* offset to first byte to lock */ 75 int64_t length; /* nbr of bytes to lock */ 76 uint64_t retRangeStart; /* nbr of first byte locked if successful */ 77 uint8_t unLockFlag; /* 1 = unlock, 0 = lock */ 78 uint8_t startEndFlag; /* 1 = rel to end of fork, 0 = rel to start */ 79 int32_t fd; 80}; 81 82struct gssdProxyPB 83{ 84 uint32_t mechtype; 85 uint32_t alignPad1; 86 uint8_t *intoken; 87 uint32_t intokenLen; 88 uint32_t uid; 89 uint8_t *svc_namestr; 90 uint64_t verifier; // inout 91 uint32_t context; // inout 92 uint32_t cred_handle; // inout 93 uint8_t *outtoken; // out 94 uint32_t outtokenLen; // inout 95 uint32_t major_stat; // out 96 uint32_t minor_stat; // out 97}; 98 99#ifdef KERNEL 100 101struct user_gssdProxyPB 102{ 103 uint32_t mechtype; 104 user_addr_t intoken; 105 uint32_t intokenLen; 106 uint32_t uid; 107 user_addr_t svc_namestr; 108 uint64_t verifier; // inout 109 uint32_t context; // inout 110 uint32_t cred_handle; // inout 111 user_addr_t outtoken; // out 112 uint32_t outtokenLen; // inout 113 uint32_t major_stat; // out 114 uint32_t minor_stat; // out 115}; 116#endif 117 118enum { 119 kConnectedByUser = 0, 120 kConnectedByGuest = 1, 121 kConnectedByAnonymous = 2, 122 kConnectedByKerberos = 4 123}; 124 125/* 126 * We just want to know the type of access used to mount the volume and the 127 * user name used. If not set then the unique_id needs to be set. 128 */ 129#define SMBFS_GET_ACCESS_INFO 1 130 131struct UniqueSMBShareID { 132 int32_t connection_type; 133 int32_t flags; 134 int32_t error; 135 int32_t unique_id_len; 136 unsigned char unique_id[SMB_MAX_UNIQUE_ID] __attribute((aligned(8))); /* A set of bytes that uniquely identifies this volume */ 137 char user[SMB_MAXUSERNAMELEN + 1] __attribute((aligned(8))); 138}; 139 140#define smbfsByteRangeLock2FSCTL _IOWR('z', 23, struct ByteRangeLockPB2) 141#define smbfsByteRangeLock2FSCTL_BASECMD IOCBASECMD(smbfsByteRangeLock2FSCTL) 142 143#define smbfsByteRangeLockFSCTL _IOWR('z', 17, struct ByteRangeLockPB) 144#define smbfsByteRangeLockFSCTL_BASECMD IOCBASECMD(smbfsByteRangeLockFSCTL) 145 146#define smbfsUniqueShareIDFSCTL _IOWR('z', 19, struct UniqueSMBShareID) 147#define smbfsUniqueShareIDFSCTL_BASECMD IOCBASECMD(smbfsUniqueShareIDFSCTL) 148 149#define smbfsGetVCSockaddrFSCTL _IOR('z', 20, struct sockaddr_storage) 150#define smbfsGetVCSockaddrFSCTL_BASECMD IOCBASECMD(smbfsGetVCSockaddrFSCTL) 151 152/* Layout of the mount control block for an smb file system. */ 153struct smb_mount_args { 154 int32_t version; 155 int32_t dev; 156 int32_t altflags; 157 int32_t KernelLogLevel; 158 uid_t uid; 159 gid_t gid; 160 mode_t file_mode; 161 mode_t dir_mode; 162 uint32_t path_len; 163 int32_t unique_id_len; 164 char path[MAXPATHLEN] __attribute((aligned(8))); /* The starting path they want used for the mount */ 165 char url_fromname[MAXPATHLEN] __attribute((aligned(8))); /* The from name is the url used to mount the volume. */ 166 unsigned char unique_id[SMB_MAX_UNIQUE_ID] __attribute((aligned(8))); /* A set of bytes that uniquely identifies this volume */ 167 char volume_name[MAXPATHLEN] __attribute((aligned(8))); /* The starting path they want used for the mount */ 168 uint64_t ioc_reserved __attribute((aligned(8))); /* Force correct size always */ 169 int32_t max_resp_timeout; 170}; 171 172#define SMBFS_SYSCTL_REMOUNT 1 173#define SMBFS_SYSCTL_REMOUNT_INFO 2 174#define SMBFS_SYSCTL_GET_SERVER_SHARE 3 175 176#define REMOUNT_INFO_VERSION 1 177 178struct smb_remount_info { 179 uint32_t version; 180 uint32_t mntAuthFlags; 181 uid_t mntOwner; 182 uid_t mntGroup; 183 uint32_t mntDeadTimer; 184 uint32_t mntClientPrincipalNameType; 185 char mntClientPrincipalName[MAXPATHLEN] __attribute((aligned(8))); 186 char mntURL[MAXPATHLEN] __attribute((aligned(8))); 187}; 188 189#ifdef KERNEL 190 191/* The items the mount point keeps in memory */ 192struct smbfs_args { 193 int32_t altflags; 194 uid_t uid; 195 gid_t gid; 196 guid_t uuid; /* The UUID of the user that mounted the volume */ 197 mode_t file_mode; 198 mode_t dir_mode; 199 size_t path_len; /* Must be less than MAXPATHLEN and does not count the null byte */ 200 char *path; /* The starting path they want to use with this mounted volume */ 201 int32_t unique_id_len; 202 unsigned char *unique_id; /* A set of bytes that uniquely identifies this volume */ 203 char *volume_name; 204}; 205 206#ifdef MALLOC_DECLARE 207MALLOC_DECLARE(M_SMBFSMNT); 208#endif 209 210struct smbnode; 211struct smb_share; 212struct u_cred; 213struct vnop_ioctl_args; 214struct buf; 215struct smbfs_notify_change; 216 217/* 218 * SM_MAX_STATFSTIME is the maximum time to cache statfs data. Since this 219 * should be a fast call on the server, the time the data cached is short. 220 * That lets the cache handle bursts of statfs() requests without generating 221 * lots of network traffic. 222 */ 223#define SM_MAX_STATFSTIME 2 224 225/* Mask values for smbmount structure sm_status field */ 226#define SM_STATUS_STATFS 0x00000001 /* statfs is in progress */ 227#define SM_STATUS_STATFS_WANTED 0x00000002 /* statfs wakeup is wanted */ 228#define SM_STATUS_DOWN 0x00000004 /* this mount is not responding */ 229#define SM_STATUS_DEAD 0x00000010 /* connection gone - unmount this */ 230#define SM_STATUS_REMOUNT 0x00000020 /* remount inprogress */ 231#define SM_STATUS_UPDATED 0x00000040 /* Remounted with new server/share */ 232/* 233 * Some servers do not support all the info levels on Trans2 calls. Most systems do not care if you 234 * use a file descriptor or a path name to do a get or set info call. Seems NetApp requires an file descriptor when 235 * setting the time on a file. 236 */ 237#define MNT_REQUIRES_FILEID_FOR_TIME 0x0001 /* Setting time requires a file descriptor */ 238#define MNT_MAPS_NETWORK_LOCAL_USER 0x0002 /* Map Network User <==> Local User */ 239#define MNT_IS_SFM_VOLUME 0x0004 /* We mount a Service for Macintosh Volume */ 240#define MNT_SUPPORTS_REPARSE_SYMLINKS 0x0008 241 242/* 243 * Bit definitions for the svrmsg_pending field in the smbmount structure 244 */ 245#define SVRMSG_RCVD_GOING_DOWN 0x0000000000000001 246#define SVRMSG_RCVD_SHUTDOWN_CANCEL 0x0000000000000002 247 248struct smbmount { 249 uint64_t ntwrk_uid; 250 uint64_t ntwrk_gid; 251 uint32_t ntwrk_cnt_gid; 252 uint64_t *ntwrk_gids; 253 ntsid_t *ntwrk_sids; 254 uint32_t ntwrk_sids_cnt; 255 struct smbfs_args sm_args; 256 struct mount * sm_mp; 257 vnode_t sm_rvp; 258 uint64_t sm_root_ino; 259 struct smb_share * sm_share; 260 lck_rw_t sm_rw_sharelock; 261 int sm_flags; 262 lck_mtx_t *sm_hashlock; 263 LIST_HEAD(smbnode_hashhead, smbnode) *sm_hash; 264 u_long sm_hashlen; 265 uint32_t sm_status; /* status bits for this mount */ 266 time_t sm_statfstime; /* sm_statfsbuf cache time */ 267 lck_mtx_t sm_statfslock; /* sm_statsbuf lock */ 268 struct vfsstatfs sm_statfsbuf; /* cached statfs data */ 269 lck_mtx_t sm_reclaim_lock; /* mount reclaim lock */ 270 void *notify_thread; /* pointer to the notify thread structure */ 271 int32_t tooManyNotifies; 272 lck_mtx_t sm_svrmsg_lock; /* protects svrmsg fields */ 273 uint64_t sm_svrmsg_pending; /* svrmsg replies pending (bits defined above) */ 274 uint32_t sm_svrmsg_shutdown_delay; /* valid when SVRMSG_GOING_DOWN is set */ 275}; 276 277#define VFSTOSMBFS(mp) ((struct smbmount *)(vfs_fsprivate(mp))) 278#define VTOSMBFS(vp) (VFSTOSMBFS(vnode_mount(vp))) 279 280#define SMB_SYMMAGICLEN (4+1) /* includes a '\n' seperator */ 281extern char smb_symmagic[]; 282#define SMB_SYMLENLEN (4+1) /* includes a '\n' seperator */ 283#define SMB_SYMMD5LEN (32+1) /* includes a '\n' seperator */ 284#define SMB_SYMHDRLEN (SMB_SYMMAGICLEN + SMB_SYMLENLEN + SMB_SYMMD5LEN) 285#define SMB_SYMLEN (SMB_SYMHDRLEN + MAXPATHLEN) 286 287#define CON_FILENAME(nn, nl) \ 288 (((nl) >= 3) && \ 289 (((*(nn) == 'c') || (*(nn) == 'C')) && \ 290 ((*((nn)+1) == 'o') || (*((nn)+1) == 'O')) && \ 291 ((*((nn)+2) == 'n') || (*((nn)+2) == 'N')))) 292 293/* 294 * internal versions of VOPs 295 */ 296int smbfs_close(struct smb_share *share, vnode_t vp, int openMode, 297 vfs_context_t context); 298int smbfs_open(struct smb_share *share, vnode_t vp, int mode, 299 vfs_context_t context); 300 301int smbfs_update_cache(struct smb_share *share, vnode_t vp, 302 struct vnode_attr *vap, vfs_context_t context); 303int smbfs_fsync(struct smb_share *share, vnode_t vp, int waitfor, int ubc_flags, 304 vfs_context_t context); 305 306/* 307 * Notify change routines 308 */ 309void smbfs_notify_change_create_thread(struct smbmount *smp); 310void smbfs_notify_change_destroy_thread(struct smbmount *smp); 311int smbfs_start_change_notify(struct smb_share *share, struct smbnode *np, 312 vfs_context_t context, int *releaseLock); 313int smbfs_start_svrmsg_notify(struct smbmount *smp); 314int smbfs_stop_change_notify(struct smb_share *share, struct smbnode *np, 315 int forceClose, vfs_context_t context, int *releaseLock); 316int smbfs_stop_svrmsg_notify(struct smbmount *smp); 317void smbfs_restart_change_notify(struct smb_share *share, struct smbnode *np, 318 vfs_context_t context); 319 320#define SMB_IOMIN (1024 * 1024) 321#define SMB_IOMAXCACHE (SMB_IOMIN * 4) 322#define SMB_IOMAX ((size_t)MAX_UPL_SIZE * PAGE_SIZE) 323 324/* 325* KERNEL_DEBUG related definitions for SMB. 326* 327* NOTE: The Class DBG_FSYSTEM = 3, and Subclass DBG_SMB = 0xA, so these 328* debug codes are of the form 0x030Annnn. 329*/ 330#define DBG_SMB 0xA /* SMB-specific events; see the smb project */ 331 332#define SMB_DBG_CODE(code) FSDBG_CODE(DBG_SMB, code) 333 334/* example usage */ 335//SMB_LOG_KTRACE(SMB_DBG_MOUNT | DBG_FUNC_START, 0, 0, 0, 0, 0); 336//SMB_LOG_KTRACE(SMB_DBG_MOUNT | DBG_FUNC_END, error, 0, 0, 0, 0); 337//SMB_LOG_KTRACE(SMB_DBG_MOUNT | DBG_FUNC_NONE, 0xabc001, error, 0, 0, 0); 338 339enum { 340 /* VFS OPs */ 341 SMB_DBG_MOUNT = SMB_DBG_CODE(0), /* 0x030A0000 */ 342 SMB_DBG_UNMOUNT = SMB_DBG_CODE(1), /* 0x030A0004 */ 343 SMB_DBG_ROOT = SMB_DBG_CODE(2), /* 0x030A0008 */ 344 SMB_DBG_VFS_GETATTR = SMB_DBG_CODE(3), /* 0x030A000C */ 345 SMB_DBG_SYNC = SMB_DBG_CODE(4), /* 0x030A0010 */ 346 SMB_DBG_VGET = SMB_DBG_CODE(5), /* 0x030A0014 */ 347 SMB_DBG_SYSCTL = SMB_DBG_CODE(6), /* 0x030A0018 */ 348 349 /* VFS VNODE OPs */ 350 SMB_DBG_ADVLOCK = SMB_DBG_CODE(7), /* 0x030A001C */ 351 SMB_DBG_CLOSE = SMB_DBG_CODE(8), /* 0x030A0020 */ 352 SMB_DBG_CREATE = SMB_DBG_CODE(9), /* 0x030A0024 */ 353 SMB_DBG_FSYNC = SMB_DBG_CODE(10), /* 0x030A0028 */ 354 SMB_DBG_GET_ATTR = SMB_DBG_CODE(11), /* 0x030A002C */ 355 SMB_DBG_PAGE_IN = SMB_DBG_CODE(12), /* 0x030A0030 */ 356 SMB_DBG_INACTIVE = SMB_DBG_CODE(13), /* 0x030A0034 */ 357 SMB_DBG_IOCTL = SMB_DBG_CODE(14), /* 0x030A0038 */ 358 SMB_DBG_LINK = SMB_DBG_CODE(15), /* 0x030A003C */ 359 SMB_DBG_LOOKUP = SMB_DBG_CODE(16), /* 0x030A0040 */ 360 SMB_DBG_MKDIR = SMB_DBG_CODE(17), /* 0x030A0044 */ 361 SMB_DBG_MKNODE = SMB_DBG_CODE(18), /* 0x030A0048 */ 362 SMB_DBG_MMAP = SMB_DBG_CODE(19), /* 0x030A004C */ 363 SMB_DBG_MNOMAP = SMB_DBG_CODE(20), /* 0x030A0050 */ 364 SMB_DBG_OPEN = SMB_DBG_CODE(21), /* 0x030A0054 */ 365 SMB_DBG_CMPD_OPEN = SMB_DBG_CODE(22), /* 0x030A0058 */ 366 SMB_DBG_PATHCONF = SMB_DBG_CODE(23), /* 0x030A005C */ 367 SMB_DBG_PAGE_OUT = SMB_DBG_CODE(24), /* 0x030A0060 */ 368 SMB_DBG_COPYFILE = SMB_DBG_CODE(25), /* 0x030A0064 */ 369 SMB_DBG_READ = SMB_DBG_CODE(26), /* 0x030A0068 */ 370 SMB_DBG_READ_DIR = SMB_DBG_CODE(27), /* 0x030A006C */ 371 SMB_DBG_READ_DIR_ATTR = SMB_DBG_CODE(28), /* 0x030A0070 */ 372 SMB_DBG_READ_LINK = SMB_DBG_CODE(29), /* 0x030A0074 */ 373 SMB_DBG_RECLAIM = SMB_DBG_CODE(30), /* 0x030A0078 */ 374 SMB_DBG_REMOVE = SMB_DBG_CODE(31), /* 0x030A007C */ 375 SMB_DBG_RENAME = SMB_DBG_CODE(32), /* 0x030A0080 */ 376 SMB_DBG_RM_DIR = SMB_DBG_CODE(33), /* 0x030A0084 */ 377 SMB_DBG_SET_ATTR = SMB_DBG_CODE(34), /* 0x030A0088 */ 378 SMB_DBG_SYM_LINK = SMB_DBG_CODE(35), /* 0x030A008C */ 379 SMB_DBG_WRITE = SMB_DBG_CODE(36), /* 0x030A0090 */ 380 SMB_DBG_STRATEGY = SMB_DBG_CODE(37), /* 0x030A0094 */ 381 SMB_DBG_GET_XATTR = SMB_DBG_CODE(38), /* 0x030A0098 */ 382 SMB_DBG_SET_XATTR = SMB_DBG_CODE(39), /* 0x030A009C */ 383 SMB_DBG_RM_XATTR = SMB_DBG_CODE(40), /* 0x030A00A0 */ 384 SMB_DBG_LIST_XATTR = SMB_DBG_CODE(41), /* 0x030A00A4 */ 385 SMB_DBG_MONITOR = SMB_DBG_CODE(42), /* 0x030A00A8 */ 386 SMB_DBG_GET_NSTREAM = SMB_DBG_CODE(43), /* 0x030A00AC */ 387 SMB_DBG_MAKE_NSTREAM = SMB_DBG_CODE(44), /* 0x030A00B0 */ 388 SMB_DBG_RM_NSTREAM = SMB_DBG_CODE(45), /* 0x030A00B4 */ 389 SMB_DBG_ACCESS = SMB_DBG_CODE(46), /* 0x030A00B8 */ 390 SMB_DBG_ALLOCATE = SMB_DBG_CODE(47), /* 0x030A00BC */ 391 392 /* Sub Functions */ 393 SMB_DBG_SMBFS_CLOSE = SMB_DBG_CODE(48), /* 0x030A00C0 */ 394 SMB_DBG_SMBFS_CREATE = SMB_DBG_CODE(49), /* 0x030A00C4 */ 395 SMB_DBG_SMBFS_FSYNC = SMB_DBG_CODE(50), /* 0x030A00C8 */ 396 SMB_DBG_SMB_FSYNC = SMB_DBG_CODE(51), /* 0x030A00CC */ 397 SMB_DBG_SMBFS_UPDATE_CACHE = SMB_DBG_CODE(52), /* 0x030A00D0 */ 398 SMB_DBG_SMBFS_OPEN = SMB_DBG_CODE(53), /* 0x030A00D4 */ 399 SMB_DBG_SMB_READ = SMB_DBG_CODE(54), /* 0x030A00D8 */ 400 SMB_DBG_SMB_RW_ASYNC = SMB_DBG_CODE(55), /* 0x030A00DC */ 401 SMB_DBG_SMB_RW_FILL = SMB_DBG_CODE(56), /* 0x030A00E0 */ 402 SMB_DBG_PACK_ATTR_BLK = SMB_DBG_CODE(57), /* 0x030A00E4 */ 403 SMB_DBG_SMBFS_REMOVE = SMB_DBG_CODE(58), /* 0x030A00E8 */ 404 SMB_DBG_SMBFS_SETATTR = SMB_DBG_CODE(59), /* 0x030A00EC */ 405 SMB_DBG_SMBFS_GET_SEC = SMB_DBG_CODE(60), /* 0x030A00F0 */ 406 SMB_DBG_SMBFS_SET_SEC = SMB_DBG_CODE(61), /* 0x030A00F4 */ 407 SMB_DBG_SMBFS_GET_MAX_ACCESS = SMB_DBG_CODE(62), /* 0x030A00F8 */ 408 SMB_DBG_SMBFS_LOOKUP = SMB_DBG_CODE(63), /* 0x030A00FC */ 409 SMB_DBG_SMBFS_NOTIFY = SMB_DBG_CODE(64), /* 0x030A0100 */ 410 411 SMB_DBG_GET_ATTRLIST_BULK = SMB_DBG_CODE(65), /* 0x030A0104 */ 412 SMB_DBG_UPDATE_CTX = SMB_DBG_CODE(66), /* 0x030A0108 */ 413}; 414 415 416#endif /* KERNEL */ 417 418#endif /* _SMBFS_SMBFS_H_ */ 419