Beispiel #1
0
/*
 * Here we expect something like
 *   "//[workgroup;][user[:password]@]host[/share[/path]]"
 * See http://ietf.org/internet-drafts/draft-crhertel-smb-url-07.txt
 */
int ParseSMBURL(struct smb_ctx *ctx)
{
	int error  = EINVAL;

	/* Make sure its a good URL, better be at this point */
	if ((!CFURLCanBeDecomposed(ctx->ct_url)) || (SMBSchemeLength(ctx->ct_url) < 0)) {
		smb_log_info("This is an invalid URL, syserr = %s", ASL_LEVEL_ERR, 
					 strerror(error));
		return error;
	}

	error = SetServerFromURL(ctx, ctx->ct_url);
	if (error) {
		smb_log_info("The URL has a bad server name, syserr = %s", ASL_LEVEL_ERR, 
					 strerror(error));
		return error;
	}
	error = SetUserNameFromURL(ctx, ctx->ct_url);
	if (error) {
		smb_log_info("The URL has a bad user name, syserr = %s", ASL_LEVEL_ERR, 
					 strerror(error));
		return error;
	}
	error = SetPasswordFromURL(ctx, ctx->ct_url);
	if (error) {
		smb_log_info("The URL has a bad password, syserr = %s", ASL_LEVEL_ERR, 
					 strerror(error));
		return error;
	}
	SetPortNumberFromURL(ctx, ctx->ct_url);
	error = SetShareAndPathFromURL(ctx, ctx->ct_url);
	/* CFURLCopyQueryString to get ?WINS=msfilsys.apple.com;NODETYPE=H info */
	return error;
}
Beispiel #2
0
static netfsError
GetServerInfo9P(CFURLRef url, void *v, CFDictionaryRef opts,
                CFDictionaryRef * params)
{
#pragma unused(v)
#pragma unused(opts)

        CFMutableDictionaryRef dict;
        CFStringRef host;

        TRACE();
        if (url == NULL || params == NULL || !CFURLCanBeDecomposed(url))
                return EINVAL;

        *params = dict = CreateDict9P();
        if (dict == NULL)
                return ENOMEM;

        host = CFURLCopyHostName(url);
        if (host != NULL) {
                CFDictionarySetValue(dict, kNetFSServerDisplayNameKey, host);
                CFRelease(host);
        }

        CFDictionarySetValue(dict, kNetFSSupportsChangePasswordKey,
                             kCFBooleanFalse);
        CFDictionarySetValue(dict, kNetFSSupportsGuestKey, kCFBooleanTrue);
        CFDictionarySetValue(dict, kNetFSSupportsKerberosKey, kCFBooleanFalse);
        CFDictionarySetValue(dict, kNetFSGuestOnlyKey, kCFBooleanFalse);
        return 0;
}
Beispiel #3
0
static netfsError
OpenSession9P(CFURLRef url, void *v, CFDictionaryRef opts,
              CFDictionaryRef * info)
{
        CFMutableDictionaryRef dict;
        Context9P *ctx;
        int useGuest, e;

        TRACE();
        ctx = v;
        if (ctx == NULL || url == NULL || info == NULL
            || !CFURLCanBeDecomposed(url))
                return EINVAL;

        DEBUG("url=%s opts=%s", NetFSCFStringtoCString(CFURLGetString(url)),
              NetFSCFStringtoCString(CFCopyDescription(opts)));
        *info = dict = CreateDict9P();
        if (dict == NULL)
                return ENOMEM;

        useGuest = FALSE;
        if (opts != NULL) {
                CFBooleanRef boolean =
                    CFDictionaryGetValue(opts, kNetFSUseGuestKey);
                if (boolean != NULL)
                        useGuest = CFBooleanGetValue(boolean);
        }

        if (useGuest)
                CFDictionarySetValue(dict, kNetFSMountedByGuestKey,
                                     kCFBooleanTrue);
        else {
                ctx->user = CFURLCopyUserName(url);
                ctx->pass = CFURLCopyPassword(url);
                if (ctx->user == NULL || ctx->pass == NULL) {
                        if (ctx->user)
                                CFRelease(ctx->user);
                        if (ctx->pass)
                                CFRelease(ctx->pass);
                        ctx->user = ctx->pass = NULL;
                        goto error;
                }
                DEBUG("user=%s pass=%s", NetFSCFStringtoCString(ctx->user),
                      NetFSCFStringtoCString(ctx->pass));
                CFDictionarySetValue(dict, kNetFSMountedByUserKey, ctx->user);
        }
        return 0;

 error:
        e = errno;
        *info = NULL;
        CFRelease(dict);
        return e;
}
Beispiel #4
0
CFNetDiagnosticRef CFNetDiagnosticCreateWithURL(CFAllocatorRef allocator, CFURLRef url) {
	CFMutableDictionaryRef retval;
	SInt32 port = 0;
	
	retval = CFDictionaryCreateMutable(allocator, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
	
	if(retval != NULL && CFURLCanBeDecomposed(url)) {
		port = CFURLGetPortNumber(url);
		
		_CFNetDiagnosticSetDictionaryKeyIfNotNull(_CFNetDiagnosticNameKey, CFBundleGetValueForInfoDictionaryKey(CFBundleGetMainBundle(), kCFBundleNameKey), retval);		
		_CFNetDiagnosticSetDictionaryKeyIfNotNull(_CFNetDiagnosticBundleKey, CFBundleGetIdentifier( CFBundleGetMainBundle() ), retval);
		_CFNetDiagnosticSetDictionaryKeyAndReleaseIfNotNull(_CFNetDiagnosticRemoteHostKey, CFURLCopyHostName(url), retval);
		_CFNetDiagnosticSetDictionaryKeyAndReleaseIfNotNull(_CFNetDiagnosticProtocolKey, CFURLCopyScheme(url), retval);
		_CFNetDiagnosticSetDictionaryKeyAndReleaseIfNotNull(_CFNetDiagnosticPortKey, CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt32Type, &port), retval);
		
		_CFNetDiagnosticSetDictionaryKeyIfNotNull(_CFNetDiagnosticMethodKey, CFSTR("CFNetDiagnosticCreateWithURL"), retval);
	}
	
	return (CFNetDiagnosticRef)retval;
}
Beispiel #5
0
static netfsError ParseURL9P(CFURLRef url, CFDictionaryRef * params)
{
        CFMutableDictionaryRef dict;
        CFStringRef str;
        SInt32 port;
        int e;

        TRACE();
        if (url == NULL || params == NULL || !CFURLCanBeDecomposed(url))
                return EINVAL;

        DEBUG("url=%s", NetFSCFStringtoCString(CFURLGetString(url)));
        *params = dict = CreateDict9P();
        if (dict == NULL)
                return ENOMEM;

        /* mandatory */
        str = CFURLCopyScheme(url);
        if (str == NULL)
                goto error;
        CFDictionarySetValue(dict, kNetFSSchemeKey, str);
        CFRelease(str);

        str = CFURLCopyHostName(url);
        if (str == NULL)
                goto error;
        CFDictionarySetValue(dict, kNetFSHostKey, str);
        CFRelease(str);

        /* optional */
        port = CFURLGetPortNumber(url);
        if (port != -1) {
                str =
                    CFStringCreateWithFormat(kCFAllocatorDefault, NULL,
                                             CFSTR("%d"), (int)port);
                if (str == NULL)
                        goto error;
                CFDictionarySetValue(dict, kNetFSAlternatePortKey, str);
                CFRelease(str);
        }

        str = CFURLCopyUserName(url);
        if (str != NULL) {
                CFDictionarySetValue(dict, kNetFSUserNameKey, str);
                CFRelease(str);
        }

        str = CFURLCopyPassword(url);
        if (str != NULL) {
                CFDictionarySetValue(dict, kNetFSPasswordKey, str);
                CFRelease(str);
        }
/*
	str = CFURLCopyPath(url);
	if (str != NULL) {
		CFDictionarySetValue(dict, kNetFSPathKey, str);
		CFRelease(str);
	}
*/
        return 0;

 error:
        e = errno;
        *params = NULL;
        CFRelease(dict);
        return e;
}
Beispiel #6
0
static netfsError
Mount9P(void *v, CFURLRef url, CFStringRef mntpointstr, CFDictionaryRef opts,
        CFDictionaryRef * info)
{
        CFMutableDictionaryRef dict;
        CFMutableStringRef mntoptsstr;
        CFStringRef str;
        CFNumberRef num;
        Context9P *ctx;
        char *host, *mntpoint, *mntopts;
        int32_t mntflags;
        int e;

        TRACE();
        ctx = v;
        if (ctx == NULL || url == NULL || mntpointstr == NULL || info == NULL
            || !CFURLCanBeDecomposed(url))
                return EINVAL;

        DEBUG("url=%s opts=%s", NetFSCFStringtoCString(CFURLGetString(url)),
              NetFSCFStringtoCString(CFCopyDescription(opts)));
        mntoptsstr = NULL;
        host = mntpoint = mntopts = NULL;
        *info = dict = CreateDict9P();
        if (dict == NULL)
                return ENOMEM;

        str = CFURLCopyHostName(url);
        if (str == NULL)
                goto error;

        host = NetFSCFStringtoCString(str);
        CFRelease(str);
        if (host == NULL)
                goto error;

        mntpoint = NetFSCFStringtoCString(mntpointstr);
        if (mntpoint == NULL)
                goto error;

        mntflags = 0;
        if (opts != NULL) {
                num =
                    (CFNumberRef) CFDictionaryGetValue(opts,
                                                       kNetFSMountFlagsKey);
                CFNumberGetValue(num, kCFNumberSInt32Type, &mntflags);
        }

        mntoptsstr =
            CFStringCreateMutableCopy(kCFAllocatorDefault, 0, CFSTR("-o"));
        if (mntoptsstr == NULL)
                goto error;

        if (ctx->user && ctx->pass)
                CFStringAppendFormat(mntoptsstr, NULL,
                                     CFSTR("uname=%@,pass=%@"), ctx->user,
                                     ctx->pass);
        else
                CFStringAppend(mntoptsstr, CFSTR("noauth"));

        /* query if there's any */
        str = CFURLCopyQueryString(url, CFSTR(""));
        if (str && CFStringGetLength(str) > 0) {
                CFStringAppend(mntoptsstr, CFSTR(","));
                CFStringAppend(mntoptsstr, str);
                CFRelease(str);
        }

        mntopts = NetFSCFStringtoCString(mntoptsstr);
        if (mntopts == NULL)
                goto error;

        DEBUG("host=%s mntpoint=%s mntopts=%s", host, mntpoint, mntopts);
        if (DoMount9P(host, mntpoint, mntopts, mntflags) < 0)
                goto error;

        CFDictionarySetValue(dict, kNetFSMountPathKey, mntpointstr);
        if (ctx->user)
                CFDictionarySetValue(dict, kNetFSMountedByUserKey, ctx->user);
        else
                CFDictionarySetValue(dict, kNetFSMountedByGuestKey,
                                     kCFBooleanTrue);

        if (mntoptsstr)
                CFRelease(mntoptsstr);
        free(host);
        free(mntpoint);
        free(mntopts);
        return 0;

 error:
        e = errno;
        *info = NULL;
        CFRelease(dict);
        if (mntoptsstr)
                CFRelease(mntoptsstr);
        free(host);
        free(mntpoint);
        free(mntopts);
        return e;
}
Beispiel #7
0
/* 
 * Given a url parse it and place the component in a dictionary we create.
 */
int smb_url_to_dictionary(CFURLRef url, CFDictionaryRef *dict)
{
	CFMutableDictionaryRef mutableDict = NULL;
	int error  = 0;
	CFStringRef Server = NULL;
	CFStringRef Username = NULL;
	CFStringRef DomainWrkgrp = NULL;
	CFStringRef Password = NULL;
	CFStringRef Share = NULL;
	CFStringRef Path = NULL;
	CFStringRef Port = NULL;
	
	/* Make sure its a good URL, better be at this point */
	if ((!CFURLCanBeDecomposed(url)) || (SMBSchemeLength(url) < 0)) {
		smb_log_info("%s: Invalid URL, syserr = %s", ASL_LEVEL_ERR, 
					 __FUNCTION__, strerror(EINVAL));	
		goto ErrorOut;
	}
	
	/* create and return the server parameters dictionary */
	mutableDict = CFDictionaryCreateMutable(kCFAllocatorDefault, 0, &kCFTypeDictionaryKeyCallBacks, 
												&kCFTypeDictionaryValueCallBacks);
	if (mutableDict == NULL) {
		error = errno;
		smb_log_info("%s: CFDictionaryCreateMutable failed, syserr = %s", 
					 ASL_LEVEL_ERR, __FUNCTION__, strerror(error));	
		goto ErrorOut;
	}
	
	/*
	 * SMB can have two different scheme's cifs or smb. When we made SMBSchemeLength call at the
	 * start of this routine it made sure we had one or the other scheme. Always default here to
	 * the SMB scheme.
	 */
	CFDictionarySetValue (mutableDict, kNetFSSchemeKey, CFSTR(SMB_SCHEME_STRING));

    error = NetFSCopyHostAndPort(url, &Server, &Port);
	if ((Server == NULL) || (error != noErr)) {
        if (Port != NULL) {
            CFRelease(Port);
        }
		goto ErrorOut; /* Server name is required */
    }
	
	LogCFString(Server, "Server String", __FUNCTION__, __LINE__);
	CFDictionarySetValue (mutableDict, kNetFSHostKey, Server);
	CFRelease(Server);
	Server = NULL;
	
    if (Port != NULL) {
        CFDictionarySetValue (mutableDict, kNetFSAlternatePortKey, Port);
        CFRelease(Port);
        Port = NULL;
    }

	Username = CopyUserAndWorkgroupFromURL(&DomainWrkgrp, url);
	LogCFString(Username, "Username String", __FUNCTION__, __LINE__);
	LogCFString(DomainWrkgrp, "DomainWrkgrp String", __FUNCTION__, __LINE__);
	error = 0;
	if ((Username) && (CFStringGetLength(Username) >= SMB_MAXUSERNAMELEN))
		error = ENAMETOOLONG;

	if ((DomainWrkgrp) && (CFStringGetLength(DomainWrkgrp) > SMB_MAXNetBIOSNAMELEN))
		error = ENAMETOOLONG;
	
	if (error) {
		if (Username)
			CFRelease(Username);
		if (DomainWrkgrp)
			CFRelease(DomainWrkgrp);
		goto ErrorOut; /* Username or Domain name is too long */
	}
	
	/* 
	 * We have a domain name so combined it with the user name so we can it 
	 * display to the user. We now test to make sure we have a username. Having
	 * a domain without a username makes no sense, so don't return either.
	 */
	if (DomainWrkgrp && Username && CFStringGetLength(Username)) {
		CFMutableStringRef tempString = CFStringCreateMutableCopy(NULL, 0, DomainWrkgrp);
		
		if (tempString) {
			CFStringAppend(tempString, CFSTR("\\"));
			CFStringAppend(tempString, Username);
			CFRelease(Username);
			Username = tempString;
		}
	}

	if (Username)
	{
		CFDictionarySetValue (mutableDict, kNetFSUserNameKey, Username);
		CFRelease(Username);				
	}	

    if (DomainWrkgrp) {
		CFRelease(DomainWrkgrp);
    }
    
	Password = CFURLCopyPassword(url);
	if (Password) {
		if (CFStringGetLength(Password) >= SMB_MAXPASSWORDLEN) {
			error = ENAMETOOLONG;
			CFRelease(Password);		
			goto ErrorOut; /* Password is too long */
		}
		CFDictionarySetValue (mutableDict, kNetFSPasswordKey, Password);
		CFRelease(Password);		
	}
	
	/*
	 * We used to keep the share and path as two different elements in the dictionary. This was
	 * changed to satisfy NetFS and other plugins. We still need to check and make sure the
	 * share and path are correct. So now split them apart and then put them put them back together.
	 */
	error = GetShareAndPathFromURL(url, &Share, &Path);
	if (error)
		goto ErrorOut; /* Share name is too long */
	
	LogCFString(Share, "Share String", __FUNCTION__, __LINE__);
	LogCFString(Path, "Path String", __FUNCTION__, __LINE__);

	if (Share && Path) {
		/* 
		 * We have a share and path, but there is nothing in the 
		 * share, then return an error 
		 */
	    if (CFStringGetLength(Share) == 0) {
			CFRelease(Path);
			CFRelease(Share);
			Share = Path = NULL;
			error = EINVAL;
			smb_log_info("%s: No share name found, syserr = %s", 
						 ASL_LEVEL_ERR, __FUNCTION__, strerror(error));	
			goto ErrorOut;
		}
		if (CFStringGetLength(Path)) {
			CFMutableStringRef tempString = CFStringCreateMutableCopy(NULL, 0, Share);
			if (tempString) {
				CFStringAppend(tempString, CFSTR("/"));
				CFStringAppend(tempString, Path);
				CFDictionarySetValue (mutableDict, kNetFSPathKey, tempString);
				CFRelease(tempString);		
				CFRelease(Share);		
				Share = NULL;
			} 
		}
	}
	/* Ignore any empty share at this point */
	if (Share && CFStringGetLength(Share))
		CFDictionarySetValue (mutableDict, kNetFSPathKey, Share);

	if (Share)
		CFRelease(Share);		
	
	if (Path) 
		CFRelease(Path);		

	*dict = mutableDict;
	return 0;
		
ErrorOut:
		
	*dict = NULL;
	if (mutableDict)
		CFRelease(mutableDict);
	if (!error)	/* No error set it to the default error */
		error = EINVAL;
	return error;
	
}
static
CFArrayRef _SecIdentityCopyPossiblePaths(
    CFStringRef name)
{
    // utility function to build and return an array of possible paths for the given name.
    // if name is not a URL, this returns a single-element array.
    // if name is a URL, the array may contain 1..N elements, one for each level of the path hierarchy.

    CFMutableArrayRef names = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks);
    if (!name) {
        return names;
    }
    CFIndex oldLength = CFStringGetLength(name);
    CFArrayAppendValue(names, name);

    CFURLRef url = CFURLCreateWithString(NULL, name, NULL);
    if (url) {
		if (CFURLCanBeDecomposed(url)) {
			// first, remove the query portion of this URL, if any
			CFStringRef qs = CFURLCopyQueryString(url, NULL);
			if (qs) {
				CFMutableStringRef newName = CFStringCreateMutableCopy(NULL, oldLength, name);
				if (newName) {
					CFIndex qsLength = CFStringGetLength(qs) + 1; // include the '?'
					CFStringDelete(newName, CFRangeMake(oldLength-qsLength, qsLength));
					CFRelease(url);
					url = CFURLCreateWithString(NULL, newName, NULL);
					CFArraySetValueAtIndex(names, 0, newName);
					CFRelease(newName);
				}
				CFRelease(qs);
			}
			// now add an entry for each level of the path
			while (url) {
				CFURLRef parent = CFURLCreateCopyDeletingLastPathComponent(NULL, url);
				if (parent) {
					CFStringRef parentURLString = CFURLGetString(parent);
					if (parentURLString) {
						CFIndex newLength = CFStringGetLength(parentURLString);
						// check that string length has decreased as expected; for file URLs,
						// CFURLCreateCopyDeletingLastPathComponent can insert './' or '../'
						if ((newLength >= oldLength) || (!CFStringHasPrefix(name, parentURLString))) {
							CFRelease(parent);
							CFRelease(url);
							break;
						}
						oldLength = newLength;
						CFArrayAppendValue(names, parentURLString);
					}
				}
				CFRelease(url);
				url = parent;
			}
		}
		else {
			CFRelease(url);
		}
	}
	// finally, add wildcard entries for each subdomain
	url = CFURLCreateWithString(NULL, name, NULL);
	if (url) {
		if (CFURLCanBeDecomposed(url)) {
			CFStringRef netLocString = CFURLCopyNetLocation(url);
			if (netLocString) {
				// first strip off port number, if present
				CFStringRef tmpLocString = netLocString;
				CFArrayRef hostnameArray = CFStringCreateArrayBySeparatingStrings(NULL, netLocString, CFSTR(":"));
				tmpLocString = (CFStringRef)CFRetain((CFStringRef)CFArrayGetValueAtIndex(hostnameArray, 0));
				CFRelease(netLocString);
				CFRelease(hostnameArray);
				netLocString = tmpLocString;
				// split remaining string into domain components
				hostnameArray = CFStringCreateArrayBySeparatingStrings(NULL, netLocString, CFSTR("."));
				CFIndex subdomainCount = CFArrayGetCount(hostnameArray);
				CFIndex i = 0;
				while (++i < subdomainCount) {
					CFIndex j = i;
					CFMutableStringRef wildcardString = CFStringCreateMutable(NULL, 0);
					if (wildcardString) {
						CFStringAppendCString(wildcardString, "*", kCFStringEncodingUTF8);
						while (j < subdomainCount) {
							CFStringRef domainString = (CFStringRef)CFArrayGetValueAtIndex(hostnameArray, j++);
							if (CFStringGetLength(domainString) > 0) {
								CFStringAppendCString(wildcardString, ".", kCFStringEncodingUTF8);
								CFStringAppend(wildcardString, domainString);
							}
						}
						if (CFStringGetLength(wildcardString) > 1) {
							CFArrayAppendValue(names, wildcardString);
						}
						CFRelease(wildcardString);
					}
				}
				CFRelease(hostnameArray);
				CFRelease(netLocString);
			}
		}
		CFRelease(url);
	}

    return names;
}