1/* 2 * Copyright (c) 2006 - 2010 Apple Inc. All rights reserved. 3 * 4 * @APPLE_LICENSE_HEADER_START@ 5 * 6 * This file contains Original Code and/or Modifications of Original Code 7 * as defined in and that are subject to the Apple Public Source License 8 * Version 2.0 (the 'License'). You may not use this file except in 9 * compliance with the License. Please obtain a copy of the License at 10 * http://www.opensource.apple.com/apsl/ and read it before using this 11 * file. 12 * 13 * The Original Code and all software distributed under the License are 14 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER 15 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, 16 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, 17 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. 18 * Please see the License for the specific language governing rights and 19 * limitations under the License. 20 * 21 * @APPLE_LICENSE_HEADER_END@ 22 */ 23 24#include <sys/param.h> 25#include <sys/mount.h> 26#include <asl.h> 27 28#include <NetFS/NetFSPlugin.h> 29#include <NetFS/NetFSUtil.h> 30#include <NetFS/NetFSPrivate.h> 31#include <NetFS/NetFSUtilPrivate.h> 32 33#include <smbclient/smbclient.h> 34#include <smbclient/smbclient_netfs.h> 35#include <smbclient/smbclient_internal.h> 36 37#include "smb_netfs.h" 38#include "netshareenum.h" 39#include "SetNetworkAccountSID.h" 40 41/* 42 * SMB_GetTraceMessageScheme 43 * 44 * See whether we were passed a scheme to use when logging failures. If so, we 45 * log them with NetFSLogToMessageTracer. The scheme string needs to be freed 46 * by the calling process. 47 */ 48static char *SMB_GetTraceMessageScheme(CFDictionaryRef options) 49{ 50 CFStringRef schemeRef; 51 52 if (!options) { 53 return NULL; 54 } 55 schemeRef = CFDictionaryGetValue(options, kNetFSTraceMessageSchemeKey); 56 if (!schemeRef) { 57 return NULL; 58 } 59 return NetFSCFStringtoCString(schemeRef); 60} 61 62/* 63 * SMB_CreateSessionRef 64 * 65 * Load the smbfs kext if need, initialize anything needed by the library and 66 * create a session reference structure, the first element must have our schema 67 * as a CFStringRef. 68 */ 69static netfsError SMB_CreateSessionRef(void **outConnection) 70{ 71 int error = SMBNetFsCreateSessionRef((SMBHANDLE *)outConnection); 72 73 if (*outConnection == NULL) { 74 SMBLogInfo("%s: creating smb handle failed, syserr = %s", 75 ASL_LEVEL_ERR, __FUNCTION__, strerror(error)); 76 } 77 return error; 78} 79 80/* 81 * SMB_CancelSession 82 */ 83static netfsError SMB_Cancel(void *inConnection) 84{ 85 return SMBNetFsCancel(inConnection); 86} 87 88/* 89 * SMB_CloseSession 90 */ 91static netfsError SMB_CloseSession(void *inConnection) 92{ 93 return SMBNetFsCloseSession(inConnection); 94} 95 96/* 97 * SMB_ParseURL 98 */ 99static netfsError SMB_ParseURL(CFURLRef url, CFDictionaryRef *urlParms) 100{ 101 return SMBNetFsParseURL(url, urlParms); 102} 103 104/* 105 * SMB_CreateURL 106 */ 107static netfsError SMB_CreateURL(CFDictionaryRef urlParms, CFURLRef *url) 108{ 109 return SMBNetFsCreateURL(urlParms, url); 110} 111 112/* 113 * SMB_OpenSession 114 */ 115static netfsError SMB_OpenSession(CFURLRef url, void *inConnection, 116 CFDictionaryRef openOptions, 117 CFDictionaryRef *sessionInfo) 118{ 119 int error = 0; 120 char *tmscheme = SMB_GetTraceMessageScheme(openOptions); 121 122 if ((inConnection == NULL) || (url == NULL)) { 123 error = EINVAL; 124 NetFSLogToMessageTracer(tmscheme, "checking parameters in SMB_OpenSession", error); 125 goto done; 126 } 127 SMBNetFsLockSession(inConnection); 128 error = SMBNetFsOpenSession(url, inConnection, openOptions, sessionInfo); 129 if (error) { 130 SMBLogInfo("%s: - error = %d!", ASL_LEVEL_DEBUG, __FUNCTION__, error); 131 /* Tracing handled in smb_open_session */ 132 } 133 SMBNetFsUnlockSession(inConnection); 134done: 135 if (tmscheme) { 136 free(tmscheme); 137 } 138 return error; 139} 140 141/* 142 * SMB_GetServerInfo 143 */ 144static netfsError SMB_GetServerInfo(CFURLRef url, void *inConnection, 145 CFDictionaryRef openOptions, 146 CFDictionaryRef *serverParms) 147{ 148 int error; 149 150 if ((inConnection == NULL) || (url == NULL)) { 151 return EINVAL; 152 } 153 SMBNetFsLockSession(inConnection); 154 error = SMBNetFsGetServerInfo(url, inConnection, openOptions, serverParms); 155 if (error) { 156 SMBLogInfo("%s: - error = %d!", ASL_LEVEL_DEBUG, __FUNCTION__, error); 157 } 158 SMBNetFsUnlockSession(inConnection); 159 return error; 160} 161 162/* 163 * SMB_EnumerateShares 164 */ 165static netfsError SMB_EnumerateShares(void *inConnection, 166 CFDictionaryRef enumerateOptions, 167 CFDictionaryRef *sharePoints ) 168{ 169#pragma unused(enumerateOptions) 170 int error; 171 172 if (inConnection == NULL) { 173 return EINVAL; 174 } 175 SMBNetFsLockSession(inConnection); 176 /* 177 * Make sure we have a tree connect to IPC$.This is safe because all 178 * the NetAuth routines that care about the share name will reset it. 179 */ 180 error = SMBNetFsTreeConnectForEnumerateShares(inConnection); 181 if (!error) { 182 error = smb_netshareenum(inConnection, sharePoints, TRUE); 183 } 184 if (error) { 185 SMBLogInfo("%s: - error = %d!", ASL_LEVEL_DEBUG, __FUNCTION__, error); 186 } 187 SMBNetFsUnlockSession(inConnection); 188 return error; 189} 190 191/* 192 * SMB_Mount 193 */ 194static netfsError SMB_Mount(void *inConnection, CFURLRef url, CFStringRef mPoint, 195 CFDictionaryRef mOptions, CFDictionaryRef *mInfo) 196{ 197 int error; 198 char *tmscheme = SMB_GetTraceMessageScheme(mOptions); 199 200 if ((inConnection == NULL) || (mPoint == NULL) || (url == NULL)) { 201 error = EINVAL; 202 NetFSLogToMessageTracer(tmscheme, "checking parameters in SMB_Mount", error); 203 goto done; 204 } 205 SMBNetFsLockSession(inConnection); 206 error = SMBNetFsMount(inConnection,url, mPoint, mOptions, mInfo, setNetworkAccountSID, NULL); 207 if (error) { 208 SMBLogInfo("%s: - error = %d!", ASL_LEVEL_DEBUG, __FUNCTION__, error); 209 /* Tracing handled in smb_mount */ 210 } 211 SMBNetFsUnlockSession(inConnection); 212done: 213 if (tmscheme) { 214 free(tmscheme); 215 } 216 return error; 217} 218 219/* 220 * SMB_GetMountInfo 221 */ 222static netfsError SMB_GetMountInfo(CFStringRef in_Mountpath, CFDictionaryRef *out_MountInfo) 223{ 224 return SMBNetFsGetMountInfo(in_Mountpath, out_MountInfo); 225} 226 227 228 229 230/* CIFS NetFS factory ID: 92D4EFEF-F5AA-11D5-A1EE-003065A0E6DE */ 231#define kCIFSNetFSInterfaceFactoryID (CFUUIDGetConstantUUIDWithBytes(NULL, 0x92, 0xd4, 0xef, 0xef, 0xf5, 0xaa, 0x11, 0xd5, 0xa1, 0xee, 0x00, 0x30, 0x65, 0xa0, 0xe6, 0xde)) 232 233/* 234 * NetFS Type implementation: 235 */ 236static NetFSMountInterface_V1 gCIFSNetFSMountInterfaceFTbl = { 237 NULL, /* IUNKNOWN_C_GUTS: _reserved */ 238 NetFSQueryInterface, /* IUNKNOWN_C_GUTS: QueryInterface */ 239 NetFSInterface_AddRef, /* IUNKNOWN_C_GUTS: AddRef */ 240 NetFSInterface_Release, /* IUNKNOWN_C_GUTS: Release */ 241 SMB_CreateSessionRef, /* CreateSessionRef */ 242 SMB_GetServerInfo, /* GetServerInfo */ 243 SMB_ParseURL, /* ParseURL */ 244 SMB_CreateURL, /* CreateURL */ 245 SMB_OpenSession, /* OpenSession */ 246 SMB_EnumerateShares, /* EnumerateShares */ 247 SMB_Mount, /* Mount */ 248 SMB_Cancel, /* Cancel */ 249 SMB_CloseSession, /* CloseSession */ 250 SMB_GetMountInfo, /* GetMountInfo */ 251}; 252 253void * CIFSNetFSInterfaceFactory(CFAllocatorRef allocator, CFUUIDRef typeID); 254 255void *CIFSNetFSInterfaceFactory(CFAllocatorRef allocator, CFUUIDRef typeID) 256{ 257#pragma unused(allocator) 258 if (CFEqual(typeID, kNetFSTypeID)) { 259 return NetFS_CreateInterface(kCIFSNetFSInterfaceFactoryID, &gCIFSNetFSMountInterfaceFTbl); 260 } else { 261 return NULL; 262 } 263} 264 265