1/*
2 * Copyright (c) 2007 - 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 <SMBClient/netbios.h>
25#include "libtest.h"
26
27#include <NetFS/NetFS.h>
28#include <sys/stat.h>
29#include <asl.h>
30#include "smb_netfs.h"
31#include <netsmb/smb_lib.h>
32#include <netsmb/smb_lib.h>
33#include <parse_url.h>
34#include <netsmb/smb_conn.h>
35
36#include <unistd.h>
37#include <sys/stat.h>
38
39#include <CoreFoundation/CoreFoundation.h>
40
41#include <asl.h>
42#include "smb_netfs.h"
43#include <netsmb/smb_lib.h>
44#include <netsmb/smb_lib.h>
45#include <parse_url.h>
46#include <netsmb/upi_mbuf.h>
47#include <sys/mchain.h>
48#include <netsmb/smb_lib.h>
49#include <netsmb/rq.h>
50#include <netsmb/smbio.h>
51#include <netsmb/smbio_2.h>
52#include <netsmb/smb_converter.h>
53#include "msdfs.h"
54#include "libtest.h"
55#include "smbclient.h"
56#include "smbclient_netfs.h"
57#include "smbclient_private.h"
58#include "smbclient_internal.h"
59#include "ntstatus.h"
60#include "netshareenum.h"
61#include "LsarLookup.h"
62#include "SetNetworkAccountSID.h"
63#include "remount.h"
64
65int verbose = FALSE;
66#define MAX_SID_PRINTBUFFER	256	/* Used to print out the sid in case of an error */
67
68static
69void print_ntsid(ntsid_t *sidptr, const char *printstr)
70{
71	char sidprintbuf[MAX_SID_PRINTBUFFER];
72	char *s = sidprintbuf;
73	int subs;
74	uint64_t auth = 0;
75	unsigned i;
76	uint32_t *ip;
77	size_t len;
78
79	bzero(sidprintbuf, MAX_SID_PRINTBUFFER);
80	for (i = 0; i < sizeof(sidptr->sid_authority); i++)
81		auth = (auth << 8) | sidptr->sid_authority[i];
82	s += snprintf(s, MAX_SID_PRINTBUFFER, "S-%u-%llu", sidptr->sid_kind, auth);
83
84	subs = sidptr->sid_authcount;
85
86	for (ip = sidptr->sid_authorities; subs--; ip++)  {
87		len = MAX_SID_PRINTBUFFER - (s - sidprintbuf);
88		s += snprintf(s, len, "-%u", *ip);
89	}
90	fprintf(stderr, "%s: sid = %s \n", printstr, sidprintbuf);
91}
92
93static int test_netbios_name_conversion(void)
94{
95    static const struct {
96	CFStringRef	proposed;
97	CFStringRef	expected;
98    } test_names[] = {
99	{ NULL , NULL },
100	{ CFSTR(""), NULL },
101	{ CFSTR("james"), CFSTR("JAMES") },
102	{ CFSTR("colley-xp4"), CFSTR("COLLEY-XP4") },
103	{ CFSTR("jåmes"), CFSTR("JAMES") },
104	{ CFSTR("longnameshouldbetruncated"), CFSTR("LONGNAMESHOULDB") },
105	{ CFSTR("iPadæøåýÐ만돌"), CFSTR("IPADAYMANDOL") }
106    };
107
108    unsigned ii;
109    unsigned count = (unsigned)(sizeof(test_names) / sizeof(test_names[0]));
110
111
112    for (ii = 0; ii < sizeof(test_names) / sizeof(test_names[0]); ++ii) {
113	CFStringRef converted;
114
115	converted = SMBCreateNetBIOSName(test_names[ii].proposed);
116
117	if (converted == NULL && test_names[ii].expected == NULL) {
118	    /* Expected this to fail ... good! */
119	    --count;
120	    continue;
121	}
122
123	if (!converted) {
124	    char buf[256];
125
126	    buf[0] = '\0';
127	    CFStringGetCString(test_names[ii].proposed, buf, sizeof(buf), kCFStringEncodingUTF8);
128
129	    fprintf(stderr, "failed to convert '%s'\n", buf);
130	    continue;
131	}
132
133	// CFShow(converted);
134
135	if (CFEqual(converted, test_names[ii].expected)) {
136	    /* pass */
137	    --count;
138	} else {
139	    char buf1[256];
140	    char buf2[256];
141
142	    buf1[0] = buf2[0] = '\0';
143	    CFStringGetCString(test_names[ii].expected, buf1, sizeof(buf1), kCFStringEncodingUTF8);
144	    CFStringGetCString(converted, buf2, sizeof(buf2), kCFStringEncodingUTF8);
145
146	    fprintf(stderr, "expected '%s' but received '%s'\n", buf1, buf2);
147	}
148
149	CFRelease(converted);
150    }
151
152    return count;
153}
154
155static int test_guest_anonymous_only(const char *url, int guest)
156{
157	SMBHANDLE	serverConnection = NULL;
158	uint64_t	options = (guest) ? kSMBOptionUseGuestOnlyAuth : kSMBOptionUseAnonymousOnlyAuth;
159	uint32_t	status = 0;
160	SMBServerPropertiesV1 properties;
161
162	status = SMBOpenServerEx(url, &serverConnection, options);
163	if (!NT_SUCCESS(status)) {
164		if (verbose)
165			fprintf(stdout, "SMBOpenServerEx failed %d guest = %d\n", errno, guest);
166		return errno;
167	}
168	memset(&properties, 0, sizeof(properties));
169	status = SMBGetServerProperties(serverConnection, &properties, kPropertiesVersion, sizeof(properties));
170	SMBReleaseServer(serverConnection);
171	if (!NT_SUCCESS(status)) {
172		/* Should never happen */
173		if (verbose)
174			fprintf(stdout, "SMBGetServerProperties failed %d guest = %d\n", errno, guest);
175		return errno;
176	}
177	if (guest && (properties.authType == kSMBAuthTypeGuest)) {
178		return 0;
179	} else if (!guest && (properties.authType == kSMBAuthTypeAnonymous)) {
180		return 0;
181	}
182	return -1;
183}
184
185static int test_accountname_sid(const char *url)
186{
187	ntsid_t	*sid = NULL;
188	SMBHANDLE	serverConnection = NULL;
189	uint64_t	options = kSMBOptionAllowGuestAuth | kSMBOptionAllowAnonymousAuth;
190	uint32_t	status = 0;
191	SMBServerPropertiesV1 properties;
192	char *AccountName = NULL, *DomainName = NULL;
193
194	status = SMBOpenServerEx(url, &serverConnection, options);
195	if (!NT_SUCCESS(status)) {
196		if (verbose)
197			fprintf(stdout, "SMBOpenServerEx failed %d\n", errno);
198		return errno;
199	}
200	status = SMBGetServerProperties(serverConnection, &properties, kPropertiesVersion, sizeof(properties));
201	if (!NT_SUCCESS(status)) {
202		if (verbose)
203			fprintf(stdout, "SMBGetServerProperties failed %d\n", errno);
204		return errno;
205	}
206
207	status = GetNetworkAccountSID(properties.serverName, &AccountName, &DomainName, &sid);
208	if (!NT_SUCCESS(status)) {
209		if (verbose)
210			fprintf(stdout, "GetNetworkAccountSID failed %d\n", errno);
211		return errno;
212	}
213	if (serverConnection)
214		SMBReleaseServer(serverConnection);
215	if (verbose) {
216		fprintf(stderr, "user = %s domain = %s\n", AccountName, DomainName);
217		print_ntsid(sid, "Network Users ");
218	}
219	if (sid) {
220		free(sid);
221	}
222	if (AccountName) {
223		free(AccountName);
224	}
225	if (DomainName) {
226		free(DomainName);
227	}
228	return 0;
229}
230
231static CFURLRef create_url_with_share(CFURLRef url, const char *share)
232{
233	int error = ENOMEM;
234	CFMutableDictionaryRef urlParms = NULL;
235	CFStringRef sharePoint = CFStringCreateWithCString(kCFAllocatorDefault, share, kCFStringEncodingUTF8);
236
237	if (sharePoint == NULL) {
238		url = NULL;
239		goto done;
240	}
241	errno = SMBNetFsParseURL(url, (CFDictionaryRef *)&urlParms);
242	if (errno) {
243		url = NULL;
244		goto done;
245	}
246
247	CFDictionarySetValue (urlParms, kNetFSPathKey, sharePoint);
248	url = NULL;
249	error = SMBNetFsCreateURL(urlParms, &url);
250done:
251	if (sharePoint) {
252		CFRelease(sharePoint);
253	}
254	if (error) {
255		errno = error;
256	}
257	return url;
258
259}
260
261static int netfs_test_mounts(SMBHANDLE inConnection, CFURLRef url)
262{
263	const char *mp1 = "/tmp/mp1";
264	const char *mp2 = "/tmp/mp2";
265	const char *mp3 = "/tmp/mp3";
266	const char *share1 = "TestShare";
267	const char *share2 = "ntfsshare";
268	const char *share3 = "fat32share";
269	CFStringRef mountPoint = NULL;
270	CFURLRef mount_url = NULL;
271	CFMutableDictionaryRef mountOptions = NULL;
272	CFDictionaryRef mountInfo = NULL;
273	int error = 0;
274
275	if ((mkdir(mp1, S_IRWXU | S_IRWXG) == -1) && (errno != EEXIST))
276		return errno;
277	if ((mkdir(mp2, S_IRWXU | S_IRWXG) == -1) && (errno != EEXIST))
278		return errno;
279	if ((mkdir(mp3, S_IRWXU | S_IRWXG) == -1) && (errno != EEXIST))
280		return errno;
281
282	mountOptions = CFDictionaryCreateMutable(kCFAllocatorDefault, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
283	if (!mountOptions) {
284		goto WeAreDone;
285	}
286	CFDictionarySetValue (mountOptions, kNetFSForceNewSessionKey, kCFBooleanFalse);
287
288	mount_url = create_url_with_share(url, share1);
289	if (mount_url == NULL) {
290		error = errno;
291		goto WeAreDone;
292	}
293
294	mountPoint = CFStringCreateWithCString(kCFAllocatorDefault, mp1, kCFStringEncodingUTF8);
295	if (mountPoint) {
296		error = SMBNetFsMount(inConnection, mount_url, mountPoint, mountOptions, &mountInfo, setNetworkAccountSID, NULL);
297		CFRelease(mountPoint);
298	} else {
299		error = ENOMEM;
300	}
301
302	if (error) {
303		if (verbose) {
304			fprintf(stderr, "SMBNetFsMount failed %s %s\n", mp1, share1);
305		}
306		goto WeAreDone;
307	}
308	if (mountInfo) {
309		if (verbose)
310			CFShow(mountInfo);
311		CFRelease(mountInfo);
312	}
313	mountInfo = NULL;
314	CFRelease(mount_url);
315	mount_url = NULL;
316	mount_url = create_url_with_share(url, share2);
317	if (mount_url == NULL) {
318		error = errno;
319		goto WeAreDone;
320	}
321
322	mountPoint = CFStringCreateWithCString(kCFAllocatorDefault, mp2, kCFStringEncodingUTF8);
323	if (mountPoint) {
324		error = SMBNetFsMount(inConnection, mount_url, mountPoint, mountOptions, &mountInfo, setNetworkAccountSID, NULL);
325		CFRelease(mountPoint);
326	} else {
327		error = ENOMEM;
328	}
329
330	if (error) {
331		if (verbose) {
332			fprintf(stderr, "SMBNetFsMount failed %s %s\n", mp2, share2);
333		}
334		goto WeAreDone;
335	}
336	if (mountInfo) {
337		if (verbose)
338			CFShow(mountInfo);
339		CFRelease(mountInfo);
340	}
341	mountInfo = NULL;
342	CFRelease(mount_url);
343	mount_url = NULL;
344	mount_url = create_url_with_share(url, share3);
345	if (mount_url == NULL) {
346		error = errno;
347		goto WeAreDone;
348	}
349	mountPoint = CFStringCreateWithCString(kCFAllocatorDefault, mp3, kCFStringEncodingUTF8);
350	if (mountPoint) {
351		error = SMBNetFsMount(inConnection, mount_url, mountPoint, mountOptions, &mountInfo, setNetworkAccountSID, NULL);
352		CFRelease(mountPoint);
353	} else {
354		error = ENOMEM;
355	}
356	if (error) {
357		if (verbose) {
358			fprintf(stderr, "SMBNetFsMount failed %s %s\n", mp3, share3);
359		}
360		goto WeAreDone;
361	}
362	if (mountInfo) {
363		if (verbose)
364			CFShow(mountInfo);
365		CFRelease(mountInfo);
366	}
367WeAreDone:
368	unmount(mp1, 0);
369	unmount(mp2, 0);
370	unmount(mp3, 0);
371	if (mountOptions)
372		CFRelease(mountOptions);
373	if (mount_url)
374		CFRelease(mount_url);
375	return error;
376}
377
378
379static int do_mount(const char *mp, CFURLRef url, CFDictionaryRef openOptions, int mntflags)
380{
381
382	SMBHANDLE theConnection = NULL;
383	CFStringRef mountPoint = NULL;
384	CFDictionaryRef mountInfo = NULL;
385	int error;
386	CFNumberRef numRef = NULL;
387	CFMutableDictionaryRef mountOptions = NULL;
388
389	if ((mkdir(mp, S_IRWXU | S_IRWXG) == -1) && (errno != EEXIST))
390		return errno;
391
392	error = SMBNetFsCreateSessionRef(&theConnection);
393	if (error)
394		return error;
395	error = SMBNetFsOpenSession(url, theConnection, openOptions, NULL);
396	if (error) {
397		(void)SMBNetFsCloseSession(theConnection);
398		return error;
399	}
400
401	mountOptions = CFDictionaryCreateMutable(kCFAllocatorDefault, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
402	if (!mountOptions) {
403		(void)SMBNetFsCloseSession(theConnection);
404		return error;
405	}
406	numRef = CFNumberCreate( nil, kCFNumberIntType, &mntflags);
407	if (numRef) {
408		CFDictionarySetValue( mountOptions, kNetFSMountFlagsKey, numRef);
409		CFRelease(numRef);
410	}
411
412	mountPoint = CFStringCreateWithCString(kCFAllocatorDefault, mp, kCFStringEncodingUTF8);
413	if (mountPoint) {
414		error = SMBNetFsMount(theConnection, url, mountPoint, mountOptions, &mountInfo, NULL, NULL);
415		CFRelease(mountPoint);
416		if (mountInfo)
417			CFRelease(mountInfo);
418	} else {
419		error = ENOMEM;
420	}
421	CFRelease(mountOptions);
422	(void)SMBNetFsCloseSession(theConnection);
423	return error;
424}
425
426static int test_mount_exist(CFStringRef urlString)
427{
428	int error;
429	CFURLRef url = NULL;
430	const char *mp1 = "/private/tmp/mp1";
431	const char *mp2 = "/private/tmp/mp2";
432
433	url = CFURLCreateWithString (NULL, urlString, NULL);
434	if (!url) {
435		error = ENOMEM;
436		goto done;
437	}
438	/* Test one: mount no browse twice */
439	error = do_mount(mp1, url, NULL, MNT_DONTBROWSE);
440	if (error) {
441		fprintf(stdout, "TEST 1 mntFlags = MNT_DONTBROWSE: Couldn't mount first volume: shouldn't happen %d\n", error);
442		goto done;
443	}
444	error = do_mount(mp2, url, NULL, MNT_DONTBROWSE);
445	if (unmount(mp1, 0) == -1) {
446		fprintf(stdout, "TEST 1 unmount mp1 failed %d\n", errno);
447	}
448	if (error != EEXIST) {
449		fprintf(stdout, "TEST 1, mntFlags = MNT_DONTBROWSE: Second volume return wrong error: %d\n", error);
450		if ((error == 0) && (unmount(mp2, 0) == -1)) {
451			fprintf(stdout, "TEST 1 unmount mp2 failed %d\n", errno);
452		}
453		goto done;
454	}
455
456	/* Test two: mount first no browse second browse */
457	error = do_mount(mp1, url, NULL, MNT_DONTBROWSE);
458	if (error) {
459		fprintf(stdout, "TEST 2, mntFlags = MNT_DONTBROWSE: Couldn't mount first volume: shouldn't happen %d\n", error);
460		goto done;
461	}
462	error = do_mount(mp2, url, NULL, 0);
463	if (unmount(mp1, 0) == -1) {
464		fprintf(stdout, "TEST 2 unmount mp1 failed %d\n", errno);
465	}
466	if (error != 0) {
467		fprintf(stdout, "TEST 2, mntFlags = 0: Second volume return wrong error: %d\n", error);
468		goto done;
469	}
470	if (unmount(mp2, 0) == -1) {
471		fprintf(stdout, "TEST 2 unmount mp2 failed %d\n", errno);
472	}
473
474	/* Test three: mount first browse second no  browse */
475	error = do_mount(mp1, url, NULL, 0);
476	if (error) {
477		fprintf(stdout, "TEST 2, mntFlags = 0: Couldn't mount first volume: shouldn't happen %d\n", error);
478		goto done;
479	}
480	error = do_mount(mp2, url, NULL, MNT_DONTBROWSE);
481	if (unmount(mp1, 0) == -1) {
482		fprintf(stdout, "TEST 3 mp1 unmount failed %d\n", errno);
483	}
484	if (error != 0) {
485		fprintf(stdout, "TEST 2, mntFlags = MNT_DONTBROWSE: Second volume return wrong error: %d\n", error);
486		goto done;
487	}
488	if (unmount(mp2, 0) == -1) {
489		fprintf(stdout, "TEST 3 unmount mp2 failed %d\n", errno);
490	}
491
492	/* Test four: mount first browse second browse */
493	error = do_mount(mp1, url, NULL, 0);
494	if (error) {
495		fprintf(stdout, "TEST 4, mntFlags = 0: Couldn't mount first volume: shouldn't happen %d\n", error);
496		goto done;
497	}
498	error = do_mount(mp2, url, NULL, 0);
499	if (unmount(mp1, 0) == -1) {
500		fprintf(stdout, "TEST 4 mp1 unmount failed %d\n", errno);
501	}
502	if (error != EEXIST) {
503		fprintf(stdout, "TEST 4, mntFlags = 0: Second volume return wrong error: %d\n", error);
504		if ((error == 0) && (unmount(mp2, 0) == -1)) {
505			fprintf(stdout, "TEST 4 unmount mp2 failed %d\n", errno);
506		}
507		goto done;
508	}
509
510	/* Test five: mount first automount second no flags */
511	error = do_mount(mp1, url, NULL, MNT_AUTOMOUNTED);
512	if (error) {
513		fprintf(stdout, "TEST 5, mntFlags = MNT_AUTOMOUNTED: Couldn't mount first volume: shouldn't happen %d\n", error);
514		goto done;
515	}
516	error = do_mount(mp2, url, NULL, 0);
517	if (unmount(mp1, 0) == -1) {
518		fprintf(stdout, "TEST 5 unmount mp1 failed %d\n", errno);
519	}
520	if (error != 0) {
521		fprintf(stdout, "TEST 5, mntFlags = 0: Second volume return wrong error: %d\n", error);
522		goto done;
523	}
524	if (unmount(mp2, 0) == -1) {
525		fprintf(stdout, "TEST 5 unmount mp2 failed %d\n", errno);
526	}
527
528	/* Test six: mount first no flags second automount */
529	error = do_mount(mp1, url, NULL, 0);
530	if (error) {
531		fprintf(stdout, "TEST 6, mntFlags = 0: Couldn't mount first volume: shouldn't happen %d\n", error);
532		goto done;
533	}
534	error = do_mount(mp2, url, NULL, MNT_AUTOMOUNTED);
535	if (unmount(mp1, 0) == -1) {
536		fprintf(stdout, "TEST 6 unmount mp1 failed %d\n", errno);
537	}
538	if (error != 0) {
539		fprintf(stdout, "TEST 6, mntFlags = MNT_AUTOMOUNTED: Second volume return wrong error: %d\n", error);
540		goto done;
541	}
542	if (unmount(mp2, 0) == -1) {
543		fprintf(stdout, "TEST 6 unmount mp2 failed %d\n", errno);
544	}
545
546
547done:
548	rmdir(mp1);
549	rmdir(mp2);
550	if (url)
551		CFRelease(url);
552	return error;
553}
554static int do_user_test(CFStringRef urlString)
555{
556	CFURLRef	url;
557	void		*ref;
558	int error;
559	CFMutableDictionaryRef OpenOptions = NULL;
560	CFDictionaryRef ServerParams = NULL;
561
562	error = smb_load_library();
563	if (error)
564		return error;
565	url = CFURLCreateWithString (NULL, urlString, NULL);
566	if (!url)
567		return errno;
568	OpenOptions = CFDictionaryCreateMutable(kCFAllocatorDefault, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
569	if (OpenOptions == NULL) {
570		error = errno;
571		CFRelease(url);
572		return error;
573	}
574	/* Unit test always allows loopback */
575	CFDictionarySetValue(OpenOptions, kNetFSAllowLoopbackKey, kCFBooleanTrue);
576
577	ref = create_smb_ctx();
578	if (ref == NULL)
579		exit(-1);
580	error = smb_get_server_info(ref, url, OpenOptions, &ServerParams);
581	if ((error == 0) && ServerParams) {
582		if (verbose)
583			CFShow(ServerParams);
584	}
585	if (error == 0) {
586		error = smb_open_session(ref, url, OpenOptions, NULL);
587	}
588	if (error == 0)
589		error = mkdir("/Volumes/george/TestShare", S_IRWXU | S_IRWXG);
590	if (error == 0)
591		error = smb_mount(ref, CFSTR("/Volumes/george/TestShare"), NULL, NULL, NULL, NULL);
592
593	if (ServerParams)
594		CFRelease(ServerParams);
595	if (url)
596		CFRelease(url);
597	if (OpenOptions)
598		CFRelease(OpenOptions);
599	smb_ctx_done(ref);
600	return error;
601}
602
603static int mount_one_volume(CFStringRef urlString)
604{
605	CFURLRef url = NULL;
606	void *ref = NULL;
607	int error = 0;
608	CFMutableDictionaryRef OpenOptions = NULL;
609
610
611	if ((mkdir("/tmp/mp", S_IRWXU | S_IRWXG) == -1) && (errno != EEXIST))
612		return errno;
613	error = smb_load_library();
614	if (error)
615		return error;
616	url = CFURLCreateWithString (NULL, urlString, NULL);
617	if (url == NULL)
618		return errno;
619	OpenOptions = CFDictionaryCreateMutable(kCFAllocatorDefault, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
620	if (OpenOptions == NULL) {
621		error = errno;
622		CFRelease(url);
623		return error;
624	}
625	/* Unit test always allows loopback */
626	CFDictionarySetValue(OpenOptions, kNetFSAllowLoopbackKey, kCFBooleanTrue);
627
628	ref = create_smb_ctx();
629	if (ref == NULL) {
630		CFRelease(OpenOptions);
631		CFRelease(url);
632		return -1;
633	}
634	error = smb_open_session(ref, url, OpenOptions, NULL);
635	if(error == 0)
636		error = smb_mount(ref, CFSTR("/tmp/mp"), NULL, NULL, NULL, NULL);
637
638	if (url)
639		CFRelease(url);
640	if (OpenOptions)
641		CFRelease(OpenOptions);
642
643	smb_ctx_done(ref);
644	unmount("/tmp/mp", 0);
645	return error;
646
647}
648
649static int test_path(struct smb_ctx *ctx, const char *instring, const char *comparestring, uint32_t flags)
650{
651	char utf8str[1024];
652	char ntwrkstr[1024];
653	size_t ntwrk_len = 1024;
654	size_t utf8_len = 1024;
655
656	if (verbose)
657		printf("\nTesting string  %s\n", instring);
658
659	ntwrk_len = 1024;
660	memset(ntwrkstr, 0, 1024);
661	if (smb_localpath_to_ntwrkpath(ctx, instring, strlen(instring), ntwrkstr, &ntwrk_len, flags)) {
662		printf("smb_localpath_to_ntwrkpath: %s failed %d\n", instring, errno);
663		return -1;
664	}
665	if (verbose)
666		smb_ctx_hexdump(__FUNCTION__, "network name  =", (u_char *)ntwrkstr, ntwrk_len);
667
668	memset(utf8str, 0, 1024);
669	if (smb_ntwrkpath_to_localpath(ctx, ntwrkstr, ntwrk_len, utf8str, &utf8_len, flags)) {
670		printf("smb_ntwrkpath_to_localpath: %s failed %d\n", instring, errno);
671		return -1;
672	}
673	if (strcmp(comparestring, utf8str) != 0) {
674		printf("UTF8 string didn't match: %s != %s\n", instring, utf8str);
675		return -1;
676	}
677	if (verbose)
678		printf("utf8str = %s len = %ld\n", utf8str, utf8_len);
679	return 0;
680}
681
682const char *teststr[MAX_NUMBER_TESTSTRING] = {TESTSTRING1, TESTSTRING2, TESTSTRING3, TESTSTRING4, TESTSTRING5, TESTSTRING6 };
683const char *testslashstr[MAX_NUMBER_TESTSTRING] = {TESTSTRING1, TESTSTRING2, TESTSTRING2, TESTSTRING1, TESTSTRING7, TESTSTRING6 };
684
685static int test_path_conversion(struct smb_ctx *ctx)
686{
687	int ii, failcnt = 0, passcnt = 0;
688	int maxcnt = MAX_NUMBER_TESTSTRING;
689	uint32_t flags = SMB_UTF_SFM_CONVERSIONS;
690
691	for (ii = 0; ii < maxcnt; ii++) {
692		if (test_path(ctx, teststr[ii], teststr[ii], flags) == -1)
693			failcnt++;
694		else
695			passcnt++;
696	}
697
698	flags |= SMB_FULLPATH_CONVERSIONS;
699	for (ii = 0; ii < maxcnt; ii++) {
700		if (test_path(ctx, teststr[ii], testslashstr[ii], flags) == -1)
701			failcnt++;
702		else
703			passcnt++;
704	}
705	if (verbose) {
706		printf("Path Conversion Test: Total = %d Passed = %d Failed = %d\n", (maxcnt * 2), passcnt, failcnt);
707	}
708	return (failcnt) ? EIO : 0;
709}
710
711static int list_shares_once(const char *urlCStr)
712{
713	CFURLRef	url = NULL;
714	SMBHANDLE	serverConnection = NULL;
715	int error;
716	CFMutableDictionaryRef OpenOptions = NULL;
717	CFDictionaryRef shares = NULL;
718
719	error = SMBNetFsCreateSessionRef(&serverConnection);
720	if (error) {
721		goto done;
722	}
723	url = CreateSMBURL(urlCStr);
724	if (!url) {
725		error = errno;
726		goto done;
727	}
728	OpenOptions = CFDictionaryCreateMutable(kCFAllocatorDefault, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
729	if (OpenOptions == NULL) {
730		error = errno;
731		goto done;
732	}
733	error = SMBNetFsOpenSession(url, serverConnection, OpenOptions, NULL);
734	if (error == 0)
735		error = smb_netshareenum(serverConnection, &shares, FALSE);
736	if (error == 0) {
737		if (verbose)
738			CFShow(shares);
739	} else if (verbose)
740		CFShow(CFSTR("smb_enumerate_shares returned and error"));
741done:
742	if (url)
743		CFRelease(url);
744	if (OpenOptions)
745		CFRelease(OpenOptions);
746	if (shares)
747		CFRelease(shares);
748	if (serverConnection) {
749		SMBNetFsCloseSession(serverConnection);
750	}
751	return error;
752}
753
754static int test_name_conversion(CFStringRef Domain, CFStringRef Username, CFStringRef Password,
755								CFStringRef ServerName, CFStringRef Path, CFStringRef PortNumber)
756{
757	CFURLRef	url = NULL;
758	void		*ref = NULL;
759	int			error = 0;
760	CFMutableDictionaryRef OpenOptions = NULL;
761	CFStringRef	urlString;
762
763	error = smb_load_library();
764	if (error)
765		return error;
766	urlString = CreateURLCFString(Domain, Username, Password, ServerName, Path, PortNumber);
767
768	if (!urlString) {
769		error = errno;
770		goto done;
771	}
772
773	url = CFURLCreateWithString (NULL, urlString, NULL);
774	if (!url) {
775		error = errno;
776		goto done;
777	}
778	OpenOptions = CFDictionaryCreateMutable(kCFAllocatorDefault, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
779	if (OpenOptions == NULL) {
780		error = errno;
781		goto done;
782	}
783	/* Unit test always allows loopback */
784	CFDictionarySetValue(OpenOptions, kNetFSAllowLoopbackKey, kCFBooleanTrue);
785	ref = create_smb_ctx();
786	if (ref == NULL) {
787		error = errno;
788		goto done;
789	}
790	error = smb_open_session(ref, url, OpenOptions, NULL);
791	if (error) {
792		CFShow(CFSTR("smb_open_session returned and error"));
793		goto done;
794	}
795	error = test_path_conversion((struct smb_ctx *)ref);
796
797done:
798	if (OpenOptions)
799		CFRelease(OpenOptions);
800	if (urlString)
801		CFRelease(urlString);
802	if (url)
803		CFRelease(url);
804
805	smb_ctx_done(ref);
806	return error;
807}
808
809static int test_user_smb_calls(CFStringRef Domain, CFStringRef Username, CFStringRef Password,
810							   CFStringRef ServerName, CFStringRef Path, CFStringRef PortNumber)
811{
812	CFURLRef	url = NULL;
813	void		*ref = NULL;
814	int			error = 0;
815	CFMutableDictionaryRef OpenOptions = NULL;
816	CFStringRef	urlString;
817
818	error = smb_load_library();
819	if (error)
820		return error;
821	urlString = CreateURLCFString(Domain, Username, Password, ServerName, Path, PortNumber);
822	if (!urlString) {
823		error = errno;
824		goto done;
825	}
826	url = CFURLCreateWithString (NULL, urlString, NULL);
827	if (!url) {
828		error = errno;
829		goto done;
830	}
831	OpenOptions = CFDictionaryCreateMutable(kCFAllocatorDefault, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
832	if (OpenOptions == NULL) {
833		error = errno;
834		goto done;
835	}
836	/* Unit test always allows loopback */
837	CFDictionarySetValue(OpenOptions, kNetFSAllowLoopbackKey, kCFBooleanTrue);
838	ref = create_smb_ctx();
839	if (ref == NULL) {
840		error = errno;
841		goto done;
842	}
843	error = smb_open_session(ref, url, OpenOptions, NULL);
844	if (error) {
845		CFShow(CFSTR("smb_open_session returned and error"));
846		goto done;
847	}
848
849	error = smb_share_connect(ref);
850	if (error) {
851		CFShow(CFSTR("smb_share_connect returned and error"));
852		goto done;
853	}
854	/* TEST CHECK DIRECTORY */
855	error =  smb2io_check_directory(ref, "/UnitTest/Library/Preferences/ByHost", 0, NULL);
856	if (error)
857		printf("check directory lookup of 'ByHost' failed with error = %d\n", error);
858	error =  smb2io_check_directory(ref, "UnitTest/Library", 0, NULL);
859	if (error)
860		printf("check directory lookup of 'UnitTest/Library' failed with error = %d\n", error);
861	error =  smb2io_check_directory(ref, "/UnitTest/Library", 0, NULL);
862	if (error)
863		printf("check directory lookup of '/UnitTest/Library' failed with error = %d\n", error);
864	error =  smb2io_check_directory(ref, "/UnitTest/Downloadsx", 0, NULL);
865	if (error != ENOENT) {
866		printf("check directory lookup of '/UnitTest/Downloadsx' should failed with ENENT, goterror = %d?\n", error);
867	}
868	error =  smb2io_check_directory(ref, "/UnitTest/myFile", 0, NULL);
869	if (error != ENOTDIR) {
870		printf("check directory lookup of 'myFile' should failed with ENENT, goterror = %d?\n", error);
871	}
872	/* END OF CHECK DIRECTORY TEST */
873	/* TEST OPEN/CLOSE */
874	{
875		int fid;
876		error = smbio_open_pipe(ref, "UnitTest/myFile", &fid);
877		if (error)
878			printf("smbio_open_pipe of '/UnitTest/myFile' failed with error = %d\n", error);
879		else {
880			error = smb2io_close_file(ref, fid);
881			if (error)
882				printf("smb2io_close_file of '/UnitTest/myFile' failed with error = %d\n", error);
883		}
884	}
885	/* END OF OPEN/CLOSE TEST */
886
887done:
888	smb_ctx_done(ref);
889	if (urlString)
890		CFRelease(urlString);
891	if (url)
892		CFRelease(url);
893	if (OpenOptions)
894		CFRelease(OpenOptions);
895	return error;
896}
897
898static int test_dfs_smb_calls(CFStringRef Domain, CFStringRef Username, CFStringRef Password,
899							  CFStringRef ServerName, CFStringRef Path, CFStringRef PortNumber,
900							  const char *mountpt, const char * server,  int dfsVersionsReferralTest)
901{
902#ifndef SMB_DEBUG
903#pragma unused(server)
904#endif // SMB_DEBUG
905
906	CFURLRef	url = NULL;
907	void		*ref = NULL;
908	int			error = 0;
909	CFMutableDictionaryRef OpenOptions = NULL;
910	CFStringRef	urlString;
911
912	error = smb_load_library();
913	if (error)
914		return error;
915	urlString = CreateURLCFString(Domain, Username, Password, ServerName, Path, PortNumber);
916	if (urlString == NULL) {
917		error = errno;
918		goto done;
919	}
920	url = CFURLCreateWithString (NULL, urlString, NULL);
921	if (url == NULL) {
922		error = errno;
923		goto done;
924	}
925	OpenOptions = CFDictionaryCreateMutable(kCFAllocatorDefault, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
926	if (OpenOptions == NULL) {
927		error = errno;
928		goto done;
929	}
930	/* Unit test always allows loopback */
931	CFDictionarySetValue(OpenOptions, kNetFSAllowLoopbackKey, kCFBooleanTrue);
932	ref = create_smb_ctx();
933	if (ref == NULL) {
934		error = errno;
935		goto done;
936	}
937
938	error = smb_open_session(ref, url, OpenOptions, NULL);
939	if (error) {
940		CFShow(CFSTR("smb_open_session returned and error"));
941		goto done;
942	}
943	if (url)
944		CFRelease(url);
945#ifdef SMB_DEBUG
946	{
947		CFIndex urlrefct = CFGetRetainCount(((struct smb_ctx *)ref)->ct_url);
948		if (urlrefct > 1)
949			CFShow(CFSTR("testing reference counting for leaks."));
950	}
951#endif // SMB_DEBUG
952	url = NULL;
953
954	if (dfsVersionsReferralTest) {
955#ifdef SMB_DEBUG
956		smb_ctx_setshare(ref, "IPC$");
957		error = smb_share_connect(ref);
958		if (error) {
959			CFShow(CFSTR("smb_share_connect returned and error"));
960			goto done;
961		}
962
963		if (strcmp(server, "waldorf.apple.com") == 0) {
964			error = testGettingDfsReferralDict(ref, "/waldorf.apple.com/dfs_share");
965			if (error) {
966				CFShow(CFSTR("testGettingDfsReferralDict dfs_share returned and error"));
967			}
968			error = testGettingDfsReferralDict(ref, "/waldorf.apple.com/dfs_share/crossdomain");
969			if (error) {
970				CFShow(CFSTR("testGettingDfsReferralDict crossdomain returned and error"));
971			}
972			error = testGettingDfsReferralDict(ref, "/waldorf.apple.com/dfs_share/test");
973			if (error) {
974				CFShow(CFSTR("testGettingDfsReferralDict test returned and error"));
975			}
976		} else {
977			error = testGettingDfsReferralDict(ref, "/smb-win2003.apple.com/DfsRoot");
978			if (error) {
979				CFShow(CFSTR("testGettingDfsReferralDict DfsRoot returned and error"));
980			}
981			error = testGettingDfsReferralDict(ref, "/smb-win2003.apple.com/DfsRoot/DfsLink1");
982			if (error) {
983				CFShow(CFSTR("testGettingDfsReferralDict DfsLink1 returned and error"));
984			}
985			error = testGettingDfsReferralDict(ref, "/smb-win2003.apple.com/DfsRoot2/LinkToRoot");
986			if (error) {
987				CFShow(CFSTR("testGettingDfsReferralDict LinkToRoot returned and error"));
988			}
989		}
990		error = smb_share_disconnect(ref);
991#endif // SMB_DEBUG
992	} else {
993		CFMutableDictionaryRef mountOptions = NULL;
994		CFStringRef mountPt = CFStringCreateWithCString(NULL, mountpt, kCFStringEncodingUTF8);
995
996		if ((mkdir(mountpt, S_IRWXU | S_IRWXG) == -1) && (errno != EEXIST))
997			CFShow(CFSTR("make dir faled"));
998		else {
999			mountOptions = CFDictionaryCreateMutable(kCFAllocatorDefault, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
1000			error = smb_mount(ref, mountPt, mountOptions, NULL, NULL, NULL);
1001			if (error && verbose)
1002				fprintf(stderr, "Dfs Mounting %s failed error =  %d\n", mountpt, error);
1003
1004		}
1005		if (mountPt)
1006			CFRelease(mountPt);
1007		if (mountOptions)
1008			CFRelease(mountOptions);
1009	}
1010
1011done:
1012	smb_ctx_done(ref);
1013	if (urlString)
1014		CFRelease(urlString);
1015	if (url)
1016		CFRelease(url);
1017	if (OpenOptions)
1018		CFRelease(OpenOptions);
1019	return error;
1020}
1021
1022/*
1023* Test based on the netfs routines
1024 */
1025static int do_netfs_test(CFStringRef urlString)
1026{
1027	CFURLRef url = NULL;
1028	CFMutableDictionaryRef openOptions = NULL;
1029	CFDictionaryRef serverParms = NULL;
1030	SMBHANDLE inConnection = NULL;
1031	CFDictionaryRef sharePoints = NULL;
1032	int error = 0;
1033
1034	url = CFURLCreateWithString (NULL, urlString, NULL);
1035	if (!url)
1036		goto WeAreDone;
1037	openOptions = CFDictionaryCreateMutable(kCFAllocatorDefault, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
1038	if (!openOptions)
1039		goto WeAreDone;
1040
1041	error = SMBNetFsCreateSessionRef(&inConnection);
1042	if (error)
1043		goto WeAreDone;
1044	error = SMBNetFsGetServerInfo(url, inConnection, openOptions, &serverParms);
1045	if (error)
1046		goto WeAreDone;
1047	if (verbose) {
1048		CFShow(serverParms);
1049	}
1050
1051	/* XXX Need work here, we should add the mech type here in the future */
1052
1053	error = SMBNetFsOpenSession(url, inConnection, openOptions, NULL);
1054	if (error)
1055		goto WeAreDone;
1056	error = smb_netshareenum(inConnection, &sharePoints, FALSE);
1057	if (error)
1058		goto WeAreDone;
1059	if (verbose) {
1060		CFShow(sharePoints);
1061	}
1062	if (sharePoints == NULL) {
1063		fprintf(stderr, "NetFS No Shares returned? \n");
1064	}
1065	if (error == 0)
1066		error = netfs_test_mounts(inConnection, url);
1067
1068WeAreDone:
1069	if (url)
1070		CFRelease(url);
1071	if (openOptions)
1072		CFRelease(openOptions);
1073	if (serverParms)
1074		CFRelease(serverParms);
1075	if (sharePoints)
1076		CFRelease(sharePoints);
1077	if (inConnection)
1078		error = SMBNetFsCloseSession(inConnection);
1079	return error;
1080}
1081
1082/* Test converting ULR ot a Dictionary and back to a URL */
1083const char *urlToDictToUrlCstrings[MAX_URL_TO_DICT_TO_URL_TEST] = {
1084					URL_TO_DICT_TO_URL_TEST_STR1,
1085					URL_TO_DICT_TO_URL_TEST_STR2,
1086					URL_TO_DICT_TO_URL_TEST_STR3,
1087					URL_TO_DICT_TO_URL_TEST_STR4};
1088
1089static int testUrlToDictToURL()
1090{
1091	CFURLRef startURL, endURL;
1092	CFDictionaryRef dict;
1093	int ii, error = 0;
1094
1095	for (ii = 0; ii < MAX_URL_TO_DICT_TO_URL_TEST; ii++) {
1096		startURL = CreateSMBURL(urlToDictToUrlCstrings[ii]);
1097		if (!startURL) {
1098			error = errno;
1099			fprintf(stderr, "CreateSMBURL with %s failed, %d\n", urlToDictToUrlCstrings[ii], error);
1100			break;
1101		}
1102		error = smb_url_to_dictionary(startURL, &dict);
1103		if (error) {
1104			fprintf(stderr, "smb_url_to_dictionary with %s failed, %d\n", urlToDictToUrlCstrings[ii], error);
1105			CFRelease(startURL);
1106			break;
1107		}
1108		error = smb_dictionary_to_url(dict, &endURL);
1109		if (error) {
1110			fprintf(stderr, "smb_dictionary_to_url with %s failed, %d\n", urlToDictToUrlCstrings[ii],  error);
1111			CFRelease(dict);
1112			CFRelease(startURL);
1113			break;
1114		}
1115		/* We only want to compare the URL string currently, may want to add more later */
1116		if (CFStringCompare(CFURLGetString(startURL), CFURLGetString(endURL), kCFCompareCaseInsensitive) != kCFCompareEqualTo) {
1117			fprintf(stderr, "%s round tripped failed\n", urlToDictToUrlCstrings[ii]);
1118			if (verbose) {
1119				CFShow(dict);
1120				CFShow(startURL);
1121				CFShow(endURL);
1122			}
1123		}
1124		if (verbose) {
1125			fprintf(stderr, "%s round tripped successfully\n", urlToDictToUrlCstrings[ii]);
1126		}
1127		CFRelease(dict);
1128		CFRelease(startURL);
1129		CFRelease(endURL);
1130	}
1131	return error;
1132}
1133
1134static int testSMBOpenServerWithMountPoint()
1135{
1136	SMBHANDLE	mpConnection = NULL;
1137	SMBHANDLE	shareConnection = NULL;
1138	int			error = 0;
1139	uint32_t	status = 0;
1140
1141	/* First mount a volume */
1142	if ((mkdir("/tmp/mp", S_IRWXU | S_IRWXG) == -1) && (errno != EEXIST))
1143		return errno;
1144
1145	status = SMBOpenServerEx("smb://local1:local@smb-win2003/EmptyShare",
1146							 &mpConnection, kSMBOptionNoPrompt | kSMBOptionSessionOnly);
1147
1148	if (!NT_SUCCESS(status)) {
1149		if (verbose)
1150			fprintf(stdout, "SMBOpenServerEx failed %d\n", errno);
1151		return errno;
1152	}
1153	status = SMBMountShareEx(mpConnection, NULL, "/tmp/mp", 0, 0, 0, 0, NULL, NULL);
1154	if (!NT_SUCCESS(status)) {
1155		if (verbose)
1156			fprintf(stdout, "smb_mount failed %d\n", errno);
1157		return errno;
1158	}
1159	/* Now that we have a mounted volume we run the real test */
1160	status =  SMBOpenServerWithMountPoint("/tmp/mp", "IPC$", &shareConnection, 0);
1161
1162	if (!NT_SUCCESS(status)) {
1163		if (verbose)
1164			fprintf(stdout, "SMBOpenServerWithMountPoint failed %d\n", errno);
1165		error = errno;
1166	} else {
1167		CFDictionaryRef shares = NULL;
1168
1169		error = smb_netshareenum(shareConnection, &shares, FALSE);
1170		if (error == 0) {
1171			if (verbose)
1172				CFShow(shares);
1173		}
1174		if (shares)
1175			CFRelease(shares);
1176	}
1177
1178	/* Now cleanup everything */
1179	if (shareConnection)
1180		SMBReleaseServer(shareConnection);
1181	if (mpConnection)
1182		SMBReleaseServer(mpConnection);
1183	unmount("/tmp/mp", 0);
1184	return error;
1185}
1186
1187
1188/*
1189 * Get a list of all mount volumes. The calling routine will need to free the memory.
1190 */
1191static struct statfs *smblib_getfsstat(int *fs_cnt)
1192{
1193	struct statfs *fs;
1194	int bufsize = 0;
1195
1196	/* See what we need to allocate */
1197	*fs_cnt = getfsstat(NULL, bufsize, MNT_NOWAIT);
1198	if (*fs_cnt <=  0)
1199		return NULL;
1200	bufsize = *fs_cnt * (int)sizeof(*fs);
1201	fs = malloc(bufsize);
1202	if (fs == NULL)
1203		return NULL;
1204
1205	*fs_cnt = getfsstat(fs, bufsize, MNT_NOWAIT);
1206	if (*fs_cnt < 0) {
1207		*fs_cnt = 0;
1208		free (fs);
1209		fs = NULL;
1210	}
1211	return fs;
1212}
1213
1214static int test_remount()
1215{
1216	int found = 0;
1217	int error = 0;
1218	int fs_cnt = 0;
1219	int ii;
1220	struct statfs *fs = smblib_getfsstat(&fs_cnt);	/* Get the list of  mounted volumes */
1221	struct statfs *hold = fs;
1222
1223	if (fs == NULL) {
1224		fprintf(stdout, "%s: smb_getfsstat failed\n", __FUNCTION__);
1225		return errno;
1226	}
1227
1228	for (ii = 0; ii < fs_cnt; ii++, fs++) {
1229		if (strcmp(fs->f_fstypename, "smbfs") != 0) {
1230			continue;
1231		}
1232		if (fs->f_flags & MNT_DONTBROWSE)  {
1233			found++;
1234			fprintf(stdout, "%s: %s:%s f_owner = %d\n", __FUNCTION__,
1235					fs->f_fstypename, fs->f_mntfromname, fs->f_owner);
1236#ifdef SMBCLIENT_TEST
1237			SMBRemountServer(&fs->f_fsid, sizeof(fs->f_fsid));
1238#else // SMBCLIENT_TEST
1239			error = smb_remount_with_fsid(fs->f_fsid);
1240			if (error) {
1241				break;
1242			}
1243#endif // SMBCLIENT_TEST
1244		}
1245	}
1246	if (hold)	/* Done with free it */
1247		free(hold);
1248	if (!found) {
1249		fprintf(stdout, "%s: no smbfs mount points found!\n", __FUNCTION__);
1250	}
1251	return error;
1252}
1253
1254static int dispalyDfsReferrals(const char *url)
1255{
1256	CFMutableDictionaryRef dfsReferralDict;
1257
1258	dfsReferralDict = CFDictionaryCreateMutable(kCFAllocatorSystemDefault, 0,
1259                                                &kCFTypeDictionaryKeyCallBacks,
1260                                                &kCFTypeDictionaryValueCallBacks);
1261	if (!dfsReferralDict) {
1262		return ENOMEM;
1263	}
1264	SMBGetDfsReferral(url,dfsReferralDict);
1265	CFShow(dfsReferralDict);
1266	CFRelease(dfsReferralDict);
1267	return 0;
1268}
1269/*
1270 * Test low level smb library routines. This routine
1271 * will change depending on why routine is being tested.
1272 */
1273static int do_ctx_test(int type_of_test)
1274{
1275	int ErrorCnt = 0;
1276	int error = 0;
1277
1278	switch (type_of_test) {
1279		case REMOUNT_UNIT_TEST:
1280			if (test_remount()) {
1281				ErrorCnt++;
1282			}
1283			break;
1284		case LIST_DFS_REFERRALS:
1285			if (dispalyDfsReferrals("smb://local1:local@smb-win2003/DrillDownRoot/TwoShare")) {
1286				ErrorCnt++;
1287			}
1288			if (dispalyDfsReferrals("smb://COS;dfswriter:%40pple1nc@cosdfs/DfsRoot/DfsLink1/Shares")) {
1289				ErrorCnt++;
1290			}
1291			break;
1292		case LIST_SHARE_CONNECT_TEST:
1293		{
1294			char *urlString;
1295#ifdef TEST_REQUIRES_SPECIAL_SERVER
1296			urlString = SMBCreateURLString(NULL, "local", "local",  "iPadæøåýÐ만돌._smb._tcp.local", NULL, -1);
1297			if (urlString) {
1298				error = list_shares_once(urlString);
1299				free(urlString);
1300				if (error) {
1301					fprintf(stdout, "iPadæøåýÐ만돌._smb._tcp.local: Share test failed %d\n", error);
1302					ErrorCnt++;
1303				}
1304			} else {
1305				fprintf(stdout, "SMBCreateURLString failed %d\n", errno);
1306			}
1307#endif // TEST_REQUIRES_SPECIAL_SERVER
1308
1309			/* Try 2008 DNS name */
1310			urlString = SMBCreateURLString(NULL, "Administrator", "Ranger#1",  "netfs-win2k8.apple.com", NULL, -1);
1311			if (urlString) {
1312				error = list_shares_once(urlString);
1313				free(urlString);
1314				if (error) {
1315					fprintf(stdout, "netfs-win2k8.apple.com: Share test failed %d\n", error);
1316					ErrorCnt++;
1317				}
1318			} else {
1319				fprintf(stdout, "SMBCreateURLString failed %d\n", errno);
1320			}
1321			/* Try XP DNS name */
1322			error = list_shares_once("smb://local1:local@smb-xp4.apple.com");
1323			if (error) {
1324				fprintf(stdout, "smb-xp4.apple.com: Share test failed %d\n", error);
1325				ErrorCnt++;
1326			}
1327			/* Try Weird DNS name */
1328			error = list_shares_once("smb://local1:local@msfilsys.filsys.ads.apple.com");
1329			if (error) {
1330				fprintf(stdout, "msfilsys.filsys.ads.apple.com: Share test failed %d\n", error);
1331				ErrorCnt++;
1332			}
1333			/* Try Bonjour name */
1334			error = list_shares_once("smb://smbtest:smbtest@homedepot._smb._tcp.local");
1335			if (error) {
1336				fprintf(stdout, "homedepot._smb._tcp.local: Share test failed %d\n", error);
1337				ErrorCnt++;
1338			}
1339			/* Try DNS non fully qualified name */
1340			error = list_shares_once("smb://local1:local@smb-win2003");
1341			if (error) {
1342				fprintf(stdout, "smb-win2003: Share test failed %d\n", error);
1343				ErrorCnt++;
1344			}
1345			/* Try DNS  fully qualified name */
1346			error = list_shares_once("smb://local1:local@smb-win2003.apple.com");
1347			if (error) {
1348				fprintf(stdout, "smb-win2003.apple.com: Share test failed %d\n", error);
1349				ErrorCnt++;
1350			}
1351			/* Try NetBIOS name */
1352			error = list_shares_once("smb://local1:local@colley-xp4");
1353			if (error) {
1354				fprintf(stdout, "colley-xp4: Share test failed %d\n", error);
1355				ErrorCnt++;
1356			}
1357			/* Try NetBIOS name, require WINS */
1358			error = list_shares_once("smb://local1:local@msfilsys");
1359			if (error) {
1360				fprintf(stdout, "msfilsys: Share test failed %d (WINS Required)\n", error);
1361				ErrorCnt++;
1362			}
1363			/* Try IPV6 name, currently nothing thats up all the time */
1364			error = list_shares_once("smb://local1:local@[fe80::d9b6:f149:a17c:8307%25en1]");
1365			if (error) {
1366				fprintf(stdout, "IPv6: Share test failed %d\n", error);
1367				ErrorCnt++;
1368			}
1369			break;
1370		}
1371		case MOUNT_WIN2003_VOLUME_TEST:
1372			error = mount_one_volume(CFSTR("smb://local1:local@smb-win2003.apple.com/EmptyShare"));
1373			if (error) {
1374				fprintf(stderr, " mount_one_volume returned %d\n", error);
1375				ErrorCnt++;
1376			}
1377			break;
1378		case 2:
1379			error = do_user_test(CFSTR("smb://local1:local@smb-win2003.apple.com/TestShare"));
1380			if (error) {
1381				fprintf(stderr, " do_user_test returned %d\n", error);
1382				ErrorCnt++;
1383			}
1384			break;
1385		case URL_TO_DICT_TO_URL_TEST:
1386			error = testUrlToDictToURL();
1387			if (error) {
1388				fprintf(stderr, " testUrlToDictToURL returned %d\n", error);
1389				ErrorCnt++;
1390			}
1391			break;
1392		case 4:
1393			error = test_name_conversion(NULL, CFSTR("local1"), CFSTR("local"), CFSTR("smb-win2003.apple.com"), NULL, NULL);
1394			if (error) {
1395				fprintf(stderr, " test_name_conversion returned %d, if EIO then turn on verbose\n", error);
1396				ErrorCnt++;
1397			}
1398			break;
1399		case 5:
1400			error = test_user_smb_calls(NULL, CFSTR("local1"), CFSTR("local"), CFSTR("smb-win2003.apple.com"), NULL, NULL);
1401			if (error) {
1402				fprintf(stderr, " test_user_smb_calls returned %d\n", error);
1403				ErrorCnt++;
1404			}
1405			break;
1406		case DFS_MOUNT_TEST:
1407			error = test_dfs_smb_calls(CFSTR("COS"), CFSTR("dfswriter"), CFSTR("@pple1nc"), CFSTR("cosdfs.apple.com"),
1408									   CFSTR("DfsRoot/NSSHARE"), NULL, "/tmp/NTSHARE", "cosdfs", 0);
1409			if (error) {
1410				fprintf(stderr, "DFS path DfsRoot returned an error %d\n", error);
1411				ErrorCnt++;
1412			}
1413
1414			error = test_dfs_smb_calls(NULL, CFSTR("local1"), CFSTR("local"), CFSTR("smb-win2003.apple.com"),
1415									   CFSTR("DfsRoot"), NULL, "/tmp/DfsRoot", "smb-win2003.apple.com", 0);
1416			if (error) {
1417				fprintf(stderr, "DFS path DfsRoot returned an error %d\n", error);
1418				ErrorCnt++;
1419			}
1420			error = test_dfs_smb_calls(NULL, CFSTR("local1"), CFSTR("local"), CFSTR("smb-win2003.apple.com"),
1421									   CFSTR("DfsRoot/DfsLink1"), NULL, "/tmp/DfsLink1", "smb-win2003.apple.com", 0);
1422			if (error) {
1423				fprintf(stderr, "DFS path DfsRoot/DfsLink1 returned an error %d\n", error);
1424				ErrorCnt++;
1425			}
1426			error = test_dfs_smb_calls(NULL, CFSTR("local1"), CFSTR("local"), CFSTR("smb-win2003.apple.com"),
1427									   CFSTR("DfsRoot2"), NULL, "/tmp/DfsRoot2", "smb-win2003.apple.com", 0);
1428			if (error) {
1429				fprintf(stderr, "DFS path DfsRoot2 returned an error %d\n", error);
1430				ErrorCnt++;
1431			}
1432			error = test_dfs_smb_calls(NULL, CFSTR("local1"), CFSTR("local"), CFSTR("smb-win2003.apple.com"),
1433									   CFSTR("DfsRoot2/LinkToRoot"), NULL, "/tmp/LinkToRoot", "smb-win2003.apple.com", 0);
1434			if (error) {
1435				fprintf(stderr, "DFS path DfsRoot2/LinkToRoot returned an error %d\n", error);
1436				ErrorCnt++;
1437			}
1438			error = test_dfs_smb_calls(NULL, CFSTR("local1"), CFSTR("local"), CFSTR("smb-win2003.apple.com"),
1439									   CFSTR("DfsRoot2/LinkToRoot/DfsLink1/George"), NULL, "/tmp/George", "smb-win2003.apple.com", 0);
1440			if (error) {
1441				fprintf(stderr, "DFS path DfsRoot2/LinkToRoot/DfsLink1/George returned an error %d\n", error);
1442				ErrorCnt++;
1443			}
1444			error = test_dfs_smb_calls(CFSTR("ets"), CFSTR("gcolley"), CFSTR("1finiteLoop"), CFSTR("waldorf.apple.com"),
1445									   CFSTR("dfs_share"), NULL, "/tmp/dfs_share", "waldorf.apple.com", 0);
1446			if (error) {
1447				fprintf(stderr, "DFS path dfs_share  returned an error %d\n", error);
1448				ErrorCnt++;
1449			}
1450			error = test_dfs_smb_calls(NULL, CFSTR("gcolley"), CFSTR("1finiteLoop"), CFSTR("waldorf.apple.com"),
1451									   CFSTR("dfs_share/crossdomain"), NULL, "/tmp/crossdomain", "waldorf.apple.com", 0);
1452			if (error != EAUTH) {
1453				fprintf(stderr, "DFS path dfs_share/crossdomain  returned the wrong error %d\n", error);
1454				ErrorCnt++;
1455			}
1456			error = test_dfs_smb_calls(CFSTR("ets"), CFSTR("gcolley"), CFSTR("1finiteLoop"), CFSTR("waldorf.apple.com"),
1457									   CFSTR("dfs_share/crossdomain"), NULL, "/tmp/ets_crossdomain", "waldorf.apple.com", 0);
1458			if (error) {
1459				fprintf(stderr, "DFS path dfs_share/crossdomain returned an error %d\n", error);
1460				ErrorCnt++;
1461			}
1462			error = test_dfs_smb_calls(CFSTR("ets"), CFSTR("gcolley"), CFSTR("1finiteLoop"), CFSTR("waldorf.apple.com"),
1463									   CFSTR("dfs_share/test"), NULL, "/tmp/test", "waldorf.apple.com", 0);
1464			if (error) {
1465				fprintf(stderr, "DFS path dfs_share/test  returned an error %d\n", error);
1466				ErrorCnt++;
1467			}
1468			unmount("/tmp/DfsRoot", 0);
1469			unmount("/tmp/DfsLink1", 0);
1470			unmount("/tmp/DfsRoot2", 0);
1471			unmount("/tmp/LinkToRoot", 0);
1472			unmount("/tmp/George", 0);
1473			unmount("/tmp/dfs_share", 0);
1474			unmount("/tmp/crossdomain", 0);
1475			unmount("/tmp/ets_crossdomain", 0);
1476			unmount("/tmp/test", 0);
1477			break;
1478		case DFS_LOOP_TEST:
1479			error = test_dfs_smb_calls(NULL, CFSTR("local1"), CFSTR("local"), CFSTR("smb-win2003.apple.com"),
1480									   CFSTR("DfsRoot2/LoopLinkToLoopLink"), NULL, "/tmp/LoopTest", "smb-win2003.apple.com", 0);
1481			if (error != EMLINK) {
1482				fprintf(stderr, "LoopTest returned the wrong error %d\n", error);
1483				ErrorCnt++;
1484			}
1485			unmount("/tmp/LoopTest", 0);
1486			break;
1487		case URL_TO_DICTIONARY:
1488		{
1489			CFDictionaryRef dict;
1490			CFURLRef url;
1491
1492			url = CFURLCreateWithString (NULL, CFSTR("smb://;homedepot"), NULL);
1493			error = smb_url_to_dictionary(url, &dict);
1494			if (error) {
1495				fprintf(stderr, "empty workgroup smb_url_to_dictionary returned %d\n", error);
1496				ErrorCnt++;
1497			} else if (dict) {
1498				if (verbose)
1499					CFShow(dict);
1500				CFRelease(dict);
1501			}
1502			CFRelease(url);
1503
1504			url = CFURLCreateWithString (NULL, CFSTR("smb://;@homedepot"), NULL);
1505			error = smb_url_to_dictionary(url, &dict);
1506			if (error) {
1507				fprintf(stderr, "empty workgroup and userame smb_url_to_dictionary returned %d\n", error);
1508				ErrorCnt++;
1509			} else if (dict) {
1510				if (verbose)
1511					CFShow(dict);
1512				CFRelease(dict);
1513			}
1514			CFRelease(url);
1515
1516			url = CFURLCreateWithString (NULL, CFSTR("smb://;:homedepot"), NULL);
1517			error = smb_url_to_dictionary(url, &dict);
1518			if (error) {
1519				fprintf(stderr, "empty workgroup and password smb_url_to_dictionary returned %d\n", error);
1520				ErrorCnt++;
1521			} else if (dict) {
1522				if (verbose)
1523					CFShow(dict);
1524				CFRelease(dict);
1525			}
1526			CFRelease(url);
1527
1528			url = CFURLCreateWithString (NULL, CFSTR("smb://;:@homedepot"), NULL);
1529			error = smb_url_to_dictionary(url, &dict);
1530			if (error) {
1531				fprintf(stderr, "anonymous smb_url_to_dictionary returned %d\n", error);
1532				ErrorCnt++;
1533			} else if (dict) {
1534				if (verbose)
1535					CFShow(dict);
1536				CFRelease(dict);
1537			}
1538			CFRelease(url);
1539		}
1540			break;
1541		case FIND_VC_FROM_MP_TEST:
1542			error = testSMBOpenServerWithMountPoint();
1543			if (error) {
1544				fprintf(stderr, "FIND_VC_FROM_MP_TEST failed\n");
1545				ErrorCnt++;
1546			}
1547			break;
1548		case NETFS_TEST:
1549			error = do_netfs_test(CFSTR("smb://local1:local@smb-win2003.apple.com"));
1550			if (error) {
1551				fprintf(stderr, "NETFS_TEST failed\n");
1552				ErrorCnt++;
1553			}
1554			break;
1555		case GETACCOUNTNAME_AND_SID_TEST:
1556			error = test_accountname_sid("smb://local1:local@smb-win2003.apple.com");
1557			if (error) {
1558				fprintf(stderr, "test_accountname_sid failed for smb-win2003.apple.com\n");
1559				ErrorCnt++;
1560			}
1561			error = test_accountname_sid("smb://cindy:Ranger%231@msfilsys.filsys.ads.apple.com");
1562			if (error) {
1563				fprintf(stderr, "test_accountname_sid failed for msfilsys.filsys.ads.apple.com\n");
1564				ErrorCnt++;
1565			}
1566			error = test_accountname_sid("smb://cindy:Ranger%231@msfilsys");
1567			if (error) {
1568				fprintf(stderr, "test_accountname_sid failed for msfilsys (WINS required)\n");
1569				ErrorCnt++;
1570			}
1571			error = test_accountname_sid("smb://smbtest:smbtest@homedepot.apple.com");
1572			if (error) {
1573				fprintf(stderr, "test_accountname_sid failed for homedepot.apple.com\n");
1574				ErrorCnt++;
1575			}
1576			break;
1577		case FORCE_GUEST_ANON_TEST:
1578			error = test_guest_anonymous_only("smb://homedepot.apple.com", TRUE);
1579			if (error) {
1580				fprintf(stderr, "Guest Only failed for homedepot %d\n", error);
1581				ErrorCnt++;
1582			}
1583			error = test_guest_anonymous_only("smb://msfilsys.filsys.ads.apple.com", FALSE);
1584			if (error) {
1585				fprintf(stderr, "Anonymous Only failed for msfilsys\n");
1586				ErrorCnt++;
1587			}
1588			break;
1589		case MOUNT_EXIST_TEST:
1590			error = test_mount_exist(CFSTR("smb://local1:local@smb-win2003/TestShare"));
1591			if (error) {
1592				fprintf(stderr, "Mount exist test faile with smb-win2003/TestShare\n");
1593				ErrorCnt++;
1594			}
1595			break;
1596		case 16:
1597		{
1598		    error = test_netbios_name_conversion();
1599		    if (error) {
1600			    fprintf(stderr, "NetBIOS name conversion test failed\n");
1601			    ErrorCnt++;
1602		    }
1603
1604		    break;
1605		}
1606
1607		default:
1608			fprintf(stderr, " Unknown command %d\n", type_of_test);
1609			break;
1610
1611	};
1612#ifdef TEST_MEMORY_LEAKS
1613	while (1) {
1614		;
1615	}
1616#endif // TEST_MEMORY_LEAKS
1617	return ErrorCnt;
1618}
1619
1620/*
1621 * Need to rewrite this test code, we should make this our library unit test
1622 * code.
1623 */
1624int main(int argc, char **argv)
1625{
1626	int opt;
1627	int ErrorCnt = 0;
1628	int type_of_test = RUN_ALL_TEST;
1629	int ii;
1630
1631	while ((opt = getopt(argc, argv, "hvn:")) != EOF) {
1632		switch (opt) {
1633		    case 'v':
1634				verbose = TRUE;
1635				break;
1636			case 'n':
1637				type_of_test = (int)strtol(optarg, NULL, 0);
1638				fprintf(stderr, " type_of_test  %d \n", type_of_test);
1639				break;
1640		    case 'h':
1641		    default:
1642				fprintf(stderr, " Bad value\n");
1643				return 1;
1644				break;
1645		}
1646	}
1647
1648	if (type_of_test != RUN_ALL_TEST) {
1649		ErrorCnt += do_ctx_test(type_of_test);
1650	} else  {
1651		for (ii = START_UNIT_TEST; ii <= END_UNIT_TEST; ii++)
1652			ErrorCnt += do_ctx_test(ii);
1653	}
1654	if (ErrorCnt) {
1655		fprintf(stderr, " Failed  %d test\n", ErrorCnt);
1656	} else {
1657		fprintf(stderr, " Passed all test\n");
1658	}
1659	return 0;
1660}
1661