#include "libtest.h"
#include <URLMount/URLMount.h>
#include <sys/stat.h>
#include <asl.h>
#include "smb_netfs.h"
#include <netsmb/smb_lib.h>
#include <netsmb/smb_lib.h>
#include <parse_url.h>
#include <netsmb/smb_conn.h>
#include <unistd.h>
#include <sys/stat.h>
#include <CoreFoundation/CoreFoundation.h>
#include <URLMount/URLMount.h>
#include <asl.h>
#include "smb_netfs.h"
#include <netsmb/smb_lib.h>
#include <netsmb/smb_lib.h>
#include <parse_url.h>
#ifdef TEST_SMB_GETMOUNTINFO
netfsError TEST_SMB_GetMountInfo(CFStringRef in_Mountpath, CFDictionaryRef *out_MountInfo)
{
int error;
char mountpath[256];
struct statfs statbuf;
char *sharepointname;
char *url;
size_t url_length;
CFStringRef url_CString;
CFMutableDictionaryRef mutableDict = NULL;
*out_MountInfo = NULL;
mutableDict = CFDictionaryCreateMutable(kCFAllocatorDefault, 0, &kCFTypeDictionaryKeyCallBacks,
&kCFTypeDictionaryValueCallBacks);
if (mutableDict == NULL)
return ENOMEM;
CFStringGetCString(in_Mountpath, mountpath, sizeof(mountpath), kCFStringEncodingUTF8);
if (statfs(mountpath, &statbuf) == -1) {
CFRelease(mutableDict);
error = errno;
free(mountpath);
return error;
}
smb_ctx_get_user_mount_info(statbuf.f_mntonname, mutableDict);
sharepointname = statbuf.f_mntfromname;
while ((*sharepointname == '/') || (*sharepointname == '\\')) {
++sharepointname;
}
url_length = sizeof(SMB_PREFIX) + strlen(sharepointname);
url = malloc(url_length);
if (url == NULL) {
CFRelease(mutableDict);
return ENOMEM;
}
strlcpy(url, SMB_PREFIX, url_length);
strlcat(url, sharepointname, url_length);
url_CString = CFStringCreateWithCString(kCFAllocatorDefault, url,
kCFStringEncodingUTF8);
free(url);
if (url_CString == NULL) {
CFRelease(mutableDict);
return ENOMEM;
}
CFDictionarySetValue (mutableDict, kMountedURLKey, url_CString);
*out_MountInfo = mutableDict;
CFRelease(url_CString);
return 0;
}
#endif // TEST_SMB_GETMOUNTINFO
netfsError SMB_CreateSessionRef(void **sessionRef)
{
int error;
error = smb_load_library();
if (error) {
smb_log_info("%s: loading the smb library failed!", error, ASL_LEVEL_ERR, __FUNCTION__);
*sessionRef = NULL;
return error;
}
*sessionRef = smb_create_ctx();
if (*sessionRef == NULL) {
smb_log_info("%s: creating session refernce failed!\n", ENOMEM, ASL_LEVEL_ERR, __FUNCTION__);
return ENOMEM;
}
return 0;
}
netfsError SMB_CloseSession(void *sessionRef)
{
smb_ctx_done(sessionRef);
return 0;
}
netfsError SMB_ParseURL(CFURLRef url, CFDictionaryRef *urlParms)
{
*urlParms = NULL;
if (url == NULL) {
smb_log_info("%s: failed URL is NULL!", EINVAL, ASL_LEVEL_ERR, __FUNCTION__);
return EINVAL;
}
return smb_url_to_dictionary(url, urlParms);
}
netfsError SMB_CreateURL(CFDictionaryRef urlParms, CFURLRef *url)
{
*url = NULL;
if (urlParms == NULL) {
smb_log_info("%s: failed dictionary is NULL!", EINVAL, ASL_LEVEL_ERR, __FUNCTION__);
return EINVAL;
}
return smb_dictionary_to_url(urlParms, url);
}
netfsError SMB_OpenSession(CFURLRef url, void *sessionRef, CFDictionaryRef openOptions, CFDictionaryRef *sessionInfo)
{
if ((sessionRef == NULL) || (url == NULL)) {
smb_log_info("%s: - in parameters are NULL!", EINVAL, ASL_LEVEL_ERR, __FUNCTION__);
return EINVAL;
}
return smb_open_session(sessionRef, url, openOptions, sessionInfo);
}
netfsError SMB_GetServerInfo(CFURLRef url, void *sessionRef, CFDictionaryRef openOptions, CFDictionaryRef *serverParms)
{
if ((sessionRef == NULL) || (url == NULL)) {
smb_log_info("%s: - in parameters are NULL!", EINVAL, ASL_LEVEL_ERR, __FUNCTION__);
return EINVAL;
}
return smb_get_server_info(sessionRef, url, openOptions, serverParms);
}
netfsError SMB_EnumerateShares(void *sessionRef, CFDictionaryRef in_EnumerateOptions, CFDictionaryRef *sharePoints )
{
#pragma unused(in_EnumerateOptions)
if (sessionRef == NULL) {
smb_log_info("%s: failed session reference is NULL!", EINVAL, ASL_LEVEL_ERR, __FUNCTION__);
return EINVAL;
}
return smb_enumerate_shares(sessionRef, sharePoints);
}
netfsError SMB_Mount(void *sessionRef, CFURLRef url, CFStringRef mPoint, CFDictionaryRef mOptions, CFDictionaryRef *mInfo)
{
struct smb_ctx *ctx = sessionRef;
int error = 0;
if ((sessionRef == NULL) || (mPoint == NULL) || (url == NULL)) {
smb_log_info("%s: - in parameters are NULL!", EINVAL, ASL_LEVEL_ERR, __FUNCTION__);
return EINVAL;
}
if (ctx->ct_url)
CFRelease(ctx->ct_url);
ctx->ct_url = CFURLCopyAbsoluteURL(url);
if (ctx->ct_url)
error = ParseSMBURL(ctx, SMB_ST_DISK);
else
error = ENOMEM;
if (error) {
smb_log_info("%s: Parsing URL failed!", error, ASL_LEVEL_ERR, __FUNCTION__);
return error;
}
return smb_mount(sessionRef, mPoint, mOptions, mInfo);
}
static CFURLRef create_url_with_share(CFURLRef url, CFStringRef sharePoint)
{
CFMutableDictionaryRef urlParms = NULL;
errno = SMB_ParseURL(url, (CFDictionaryRef *)&urlParms);
if (errno)
return NULL;
CFDictionarySetValue (urlParms, kPathKey, sharePoint);
url = NULL;
errno = SMB_CreateURL(urlParms, &url);
if (errno)
return NULL;
return url;
}
#ifdef TEST_ONE
static int netfs_test_mounts(void *sessionRef, CFURLRef url)
{
CFURLRef mount_url = NULL;
CFMutableDictionaryRef mountOptions = NULL;
CFDictionaryRef mountInfo = NULL;
int error;
if ((mkdir("/Volumes/george/TestMountPts/mp", S_IRWXU | S_IRWXG) == -1) && (errno != EEXIST))
return errno;
mountOptions = CFDictionaryCreateMutable(kCFAllocatorDefault, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
if (!mountOptions)
return errno;
CFDictionarySetValue (mountOptions, kForceNewSessionKey, kCFBooleanFalse);
mount_url = create_url_with_share(url, CFSTR("TestShare"));
if (mount_url == NULL) {
error = errno;
goto WeAreDone;
}
error = SMB_Mount(sessionRef, mount_url, CFSTR("/Volumes/george/TestMountPts/mp"), mountOptions, &mountInfo);
if (error)
goto WeAreDone;
if (mountInfo) {
CFShow(mountInfo);
CFRelease(mountInfo);
}
WeAreDone:
if (mountOptions)
CFRelease(mountOptions);
if (mount_url)
CFRelease(mount_url);
return error;
}
#else // TEST_ONE
static int netfs_test_mounts(void *sessionRef, CFURLRef url)
{
CFURLRef mount_url = NULL;
CFMutableDictionaryRef mountOptions = NULL;
CFDictionaryRef mountInfo = NULL;
int error;
if ((mkdir("/Volumes/george/TestMountPts/mp", S_IRWXU | S_IRWXG) == -1) && (errno != EEXIST))
return errno;
if ((mkdir("/Volumes/george/TestMountPts/mp1", S_IRWXU | S_IRWXG) == -1) && (errno != EEXIST))
return errno;
if ((mkdir("/Volumes/george/TestMountPts/mp2", S_IRWXU | S_IRWXG) == -1) && (errno != EEXIST))
return errno;
mountOptions = CFDictionaryCreateMutable(kCFAllocatorDefault, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
if (!mountOptions)
return errno;
CFDictionarySetValue (mountOptions, kForceNewSessionKey, kCFBooleanFalse);
mount_url = create_url_with_share(url, CFSTR("TestShare"));
if (mount_url == NULL) {
error = errno;
goto WeAreDone;
}
error = SMB_Mount(sessionRef, mount_url, CFSTR("/Volumes/george/TestMountPts/mp"), mountOptions, &mountInfo);
if (error)
goto WeAreDone;
if (mountInfo) {
CFShow(mountInfo);
CFRelease(mountInfo);
}
mountInfo = NULL;
CFRelease(mount_url);
mount_url = NULL;
mount_url = create_url_with_share(url, CFSTR("ntfsshare"));
if (mount_url == NULL) {
error = errno;
goto WeAreDone;
}
error = SMB_Mount(sessionRef,mount_url, CFSTR("/Volumes/george/TestMountPts/mp1"), mountOptions, &mountInfo);
if (error)
goto WeAreDone;
if (mountInfo) {
CFShow(mountInfo);
CFRelease(mountInfo);
}
mountInfo = NULL;
CFRelease(mount_url);
mount_url = NULL;
mount_url = create_url_with_share(url, CFSTR("fat32share"));
if (mount_url == NULL) {
error = errno;
goto WeAreDone;
}
error = SMB_Mount(sessionRef, mount_url, CFSTR("/Volumes/george/TestMountPts/mp2"), mountOptions, &mountInfo);
if (error)
goto WeAreDone;
if (mountInfo) {
CFShow(mountInfo);
CFRelease(mountInfo);
}
WeAreDone:
if (mountOptions)
CFRelease(mountOptions);
if (mount_url)
CFRelease(mount_url);
return error;
}
#endif // TEST_ONE
static int do_user_test(CFStringRef urlString)
{
CFURLRef url;
void *ref;
int error;
CFMutableDictionaryRef OpenOptions = NULL;
CFDictionaryRef shares = NULL;
CFDictionaryRef ServerParams = NULL;
error = smb_load_library();
if (error)
return error;
url = CFURLCreateWithString (NULL, urlString, NULL);
if (error)
return errno;
OpenOptions = CFDictionaryCreateMutable(kCFAllocatorDefault, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
if (OpenOptions == NULL)
return errno;
CFDictionarySetValue (OpenOptions, kUseKerberosKey, kCFBooleanTrue);
ref = smb_create_ctx();
if (ref == NULL)
exit(-1);
error = smb_get_server_info(ref, url, OpenOptions, &ServerParams);
if ((error == 0) && ServerParams)
CFShow(ServerParams);
CFDictionarySetValue (OpenOptions, kUseKerberosKey, kCFBooleanFalse);
if (error == 0)
error = smb_open_session(ref, url, OpenOptions, NULL);
if (error == 0)
error = smb_enumerate_shares(ref, &shares);
if (error == 0)
CFShow(shares);
if (error == 0)
error = mkdir("/Volumes/george/TestShare", S_IRWXU | S_IRWXG);
if (error == 0)
error = smb_mount(ref, CFSTR("/Volumes/george/TestShare"), NULL, NULL);
if (ServerParams)
CFRelease(ServerParams);
if (url)
CFRelease(url);
if (OpenOptions)
CFRelease(OpenOptions);
if (shares)
CFRelease(shares);
smb_ctx_done(ref);
return 0;
}
static int mount_one_volume(CFStringRef urlString)
{
CFURLRef url;
void *ref;
int error;
CFMutableDictionaryRef OpenOptions = NULL;
if ((mkdir("/Volumes/george/TestMountPts/mp", S_IRWXU | S_IRWXG) == -1) && (errno != EEXIST))
return errno;
error = smb_load_library();
if (error)
return error;
url = CFURLCreateWithString (NULL, urlString, NULL);
if (url == NULL)
return errno;
OpenOptions = CFDictionaryCreateMutable(kCFAllocatorDefault, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
if (OpenOptions == NULL)
return errno;
CFDictionarySetValue (OpenOptions, kUseKerberosKey, kCFBooleanFalse);
ref = smb_create_ctx();
if (ref == NULL)
return -1;
error = smb_open_session(ref, url, OpenOptions, NULL);
if(error == 0)
error = smb_mount(ref, CFSTR("/Volumes/george/TestMountPts/mp"), NULL, NULL);
if (url)
CFRelease(url);
if (OpenOptions)
CFRelease(OpenOptions);
smb_ctx_done(ref);
return error;
}
static CFStringRef TestCreateStringByReplacingPercentEscapesUTF8(CFStringRef theStr, CFStringRef LeaveEscaped)
{
CFStringRef outStr;
if (!theStr)
return NULL;
outStr = CFURLCreateStringByReplacingPercentEscapesUsingEncoding(kCFAllocatorDefault, theStr,
LeaveEscaped, kCFStringEncodingUTF8);
if (outStr)
CFRelease(theStr);
else
outStr = theStr;
return outStr;
}
static CFStringRef TestCreateStringByAddingPercentEscapesUTF8(CFStringRef theStr)
{
CFStringRef outStr;
if (!theStr)
return NULL;
outStr = CFURLCreateStringByAddingPercentEscapes(NULL, theStr, NULL, NULL, kCFStringEncodingUTF8);
if (outStr)
CFRelease(theStr);
else
outStr = theStr;
return outStr;
}
static int list_shares_once(CFStringRef urlString)
{
CFURLRef url;
void *ref;
int error;
CFMutableDictionaryRef OpenOptions = NULL;
CFDictionaryRef shares = NULL;
error = smb_load_library();
if (error)
return error;
urlString = TestCreateStringByReplacingPercentEscapesUTF8(urlString, CFSTR(""));
urlString = TestCreateStringByAddingPercentEscapesUTF8(urlString);
url = CFURLCreateWithString (NULL, urlString, NULL);
if (error)
return errno;
OpenOptions = CFDictionaryCreateMutable(kCFAllocatorDefault, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
if (OpenOptions == NULL)
return errno;
CFDictionarySetValue (OpenOptions, kUseKerberosKey, kCFBooleanFalse);
ref = smb_create_ctx();
if (ref == NULL)
return errno;
error = smb_open_session(ref, url, OpenOptions, NULL);
if (error == 0)
error = smb_enumerate_shares(ref, &shares);
if (error == 0)
CFShow(shares);
else
CFShow(CFSTR("smb_enumerate_shares returned and error"));
if (url)
CFRelease(url);
if (OpenOptions)
CFRelease(OpenOptions);
if (shares)
CFRelease(shares);
smb_ctx_done(ref);
return 0;
}
static void do_netfs_test(CFStringRef urlString, int doGuest, int doKerberos)
{
CFURLRef url = NULL;
CFMutableDictionaryRef openOptions = NULL;
CFDictionaryRef serverParms = NULL;
void *sessionRef = NULL;
CFDictionaryRef sharePoints = NULL;
int error;
url = CFURLCreateWithString (NULL, urlString, NULL);
if (!url)
goto WeAreDone;
openOptions = CFDictionaryCreateMutable(kCFAllocatorDefault, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
if (!openOptions)
goto WeAreDone;
error = SMB_CreateSessionRef(&sessionRef);
if (error)
goto WeAreDone;
error = SMB_GetServerInfo(url, sessionRef, openOptions, &serverParms);
if (error)
goto WeAreDone;
CFShow(serverParms);
if (doKerberos)
CFDictionarySetValue (openOptions, kUseKerberosKey, kCFBooleanTrue);
else if (doGuest)
CFDictionarySetValue (openOptions, kUseGuestKey, kCFBooleanTrue);
else {
CFDictionarySetValue (openOptions, kUseGuestKey, kCFBooleanFalse);
CFDictionarySetValue (openOptions, kUseKerberosKey, kCFBooleanFalse);
}
error = SMB_OpenSession(url, sessionRef, openOptions, NULL);
if (error)
goto WeAreDone;
error = SMB_EnumerateShares(sessionRef, NULL, &sharePoints);
if (error)
goto WeAreDone;
CFShow(sharePoints);
CFRelease(sharePoints);
sharePoints = NULL;
error = SMB_EnumerateShares(sessionRef, NULL, &sharePoints);
CFShow(sharePoints);
if (error == 0)
error = netfs_test_mounts(sessionRef, url);
WeAreDone:
if (url)
CFRelease(url);
if (openOptions)
CFRelease(openOptions);
if (serverParms)
CFRelease(serverParms);
if (sharePoints)
CFRelease(sharePoints);
if (sessionRef)
error = SMB_CloseSession(sessionRef);
}
static void do_ctx_test(int type_of_test)
{
int error = 0;
switch (type_of_test) {
case 0:
error = list_shares_once(CFSTR("smb://local1:local@msfilsys.apple.com"));
if (error)
fprintf(stderr, " list_shares_once returned %d\n", error);
break;
case 1:
error = mount_one_volume(CFSTR("smb://local1:local@smb-win2003.apple.com/TestShare"));
if (error)
fprintf(stderr, " mount_one_volume returned %d\n", error);
break;
case 2:
error = do_user_test(CFSTR("smb://local1:local@smb-win2003.apple.com/TestShare"));
if (error)
fprintf(stderr, " do_user_test returned %d\n", error);
break;
case 3:
{
CFDictionaryRef dict;
CFURLRef url = CFURLCreateWithString (NULL, CFSTR("smb://BAD%3A%3B%2FBAD@colley2/badbad"), NULL);
error = smb_url_to_dictionary(url, &dict);
if (error)
fprintf(stderr, " smb_url_to_dictionary returned %d\n", error);
else if (dict) {
CFShow(dict);
CFRelease(dict);
}
CFRelease(url);
}
break;
default:
fprintf(stderr, " Unknown command %d\n", type_of_test);
break;
};
}
int main(int argc, char **argv)
{
#pragma unused(argc, argv)
int type_of_test = 5;
int doGuest = FALSE;
int doKerberos = FALSE;
#ifdef TEST_SMB_GETMOUNTINFO
CFDictionaryRef out_MountInfo;
int error = TEST_SMB_GetMountInfo(CFSTR("/Volumes/EmptyShare"), &out_MountInfo);
fprintf(stderr, " SMB_GetMountInfo returned %d\n", error);
if (error == 0)
CFShow(out_MountInfo);
#endif // TEST_SMB_GETMOUNTINFO
if (type_of_test < 4)
do_ctx_test(type_of_test);
else if (!doGuest)
do_netfs_test(CFSTR("smb://local1:local@smb-win2003.apple.com"), doGuest, doKerberos);
else
do_netfs_test(CFSTR("smb://griffinfax"), doGuest, doKerberos);
return 0;
}