Exemple #1
0
/*
 * SMBNetFsCloseSession
 */
int32_t 
SMBNetFsCloseSession(SMBHANDLE inConnection) 
{
	NTSTATUS status = SMBReleaseServer(inConnection);
	
	if (NT_SUCCESS(status)) {
		return 0;
	}
	return errno;
}
Exemple #2
0
int
SMBGetDfsReferral(const char * url, CFMutableDictionaryRef dfsReferralDict)
{
    int			error;
    NTSTATUS	status;
    SMBHANDLE	serverConnection;
    void *      hContext = NULL;

    if (!dfsReferralDict) {
        errno = EINVAL;
        return -1;
    }

    status = SMBOpenServerEx(url, &serverConnection, kSMBOptionSessionOnly);
    /* SMBOpenServerEx sets errno, */
    if (!NT_SUCCESS(status)) {
        return -1;
    }

    status = SMBServerContext(serverConnection, &hContext);
    if (!NT_SUCCESS(status)) {
        /* Couldn't get the context? */
        SMBReleaseServer(serverConnection);
        return -1;
    }

    error = getDfsReferralList(hContext, dfsReferralDict);
    if (error) {
        SMBReleaseServer(serverConnection);
        errno = error;
        return -1;
    }

    SMBReleaseServer(serverConnection);
    return 0;
}
Exemple #3
0
int main(int argc, char *argv[])
{
	SMBHANDLE serverConnection = NULL;
	uint64_t options = kSMBOptionSessionOnly;
	uint64_t mntOptions = 0;
	int altflags = SMBFS_MNT_STREAMS_ON;
	mode_t fileMode = 0, dirMode = 0;
	int mntflags = 0;
	NTSTATUS	status;
	char mountPoint[MAXPATHLEN];
	struct stat st;
	char *next;
	int opt;
	const char * url = NULL;
	int version = SMBFrameworkVersion();

	while ((opt = getopt(argc, argv, "Nvhd:f:o:")) != -1) {
		switch (opt) {
		    case 'd':
				errno = 0;
				dirMode = strtol(optarg, &next, 8);
				if (errno || *next != 0)
					errx(EX_DATAERR, "invalid value for directory mode");
				break;
		    case 'f':
				errno = 0;
				fileMode = strtol(optarg, &next, 8);
				if (errno || *next != 0)
					errx(EX_DATAERR, "invalid value for file mode");
				break;
			case 'N':
				options |= kSMBOptionNoPrompt;
				break;
			case 'o': {
				mntoptparse_t mp = getmntopts(optarg, mopts, &mntflags, &altflags);
				if (mp == NULL)
					err(1, NULL);
				freemntopts(mp);
				break;
			}
			case 'v':
				errx(EX_OK, "version %d.%d.%d", 
					version / 100000, (version % 10000) / 1000, (version % 1000) / 100);
				break;
			case '?':
			case 'h':
		    default:
				usage();
				break;
		}
	}
	if (optind >= argc)
		usage();
	
	argc -= optind;
	/* At this point we should only have a url and a mount point */
	if (argc != 2)
		usage();
	url = argv[optind];
	optind++;
	realpath(unpercent(argv[optind]), mountPoint);
	
	if (stat(mountPoint, &st) == -1)
		err(EX_OSERR, "could not find mount point %s", mountPoint);
	
	if (!S_ISDIR(st.st_mode)) {
		errno = ENOTDIR;
		err(EX_OSERR, "can't mount on %s", mountPoint);
	}
	
	if (mntflags & MNT_AUTOMOUNTED) {
		/* Automount volume, don't look in the user home directory */
		options |= kSMBOptionNoUserPreferences;
	}

	if ((altflags & SMBFS_MNT_STREAMS_ON) != SMBFS_MNT_STREAMS_ON) {
		/* They told us to turn of named streams */
		mntOptions |= kSMBMntOptionNoStreams;
	}
	if ((altflags & SMBFS_MNT_NOTIFY_OFF) == SMBFS_MNT_NOTIFY_OFF) {
		/* They told us to turn off remote notifications */
		mntOptions |= kSMBMntOptionNoNotifcations;
	}
	if ((altflags & SMBFS_MNT_SOFT) == SMBFS_MNT_SOFT) {
		/* Make this a soft mount */
		mntOptions |= kSMBMntOptionSoftMount;
	}
	if ((altflags & SMBFS_MNT_TIME_MACHINE) == SMBFS_MNT_TIME_MACHINE) {
		/* Make this a tm mount */
		mntOptions |= kSMBReservedTMMount;
	}
	
	status = SMBOpenServerEx(url, &serverConnection, options);
	if (NT_SUCCESS(status)) {
		status = SMBMountShareEx(serverConnection, NULL, mountPoint, mntflags, 
								 mntOptions, fileMode, dirMode, setNetworkAccountSID, NULL);
	}
	/* 
	 * SMBOpenServerEx now sets errno, so err will work correctly. We change 
	 * the string based on the NTSTATUS Error.
	 */
	if (!NT_SUCCESS(status)) {
		switch (status) {
			case STATUS_NO_SUCH_DEVICE:
				err(EX_UNAVAILABLE, "failed to intitialize the smb library");
				break;
			case STATUS_LOGON_FAILURE:
				err(EX_NOPERM, "server rejected the connection");
				break;
			case STATUS_CONNECTION_REFUSED:
				err(EX_NOHOST, "server connection failed");
			break;
			case STATUS_INVALID_HANDLE:
			case STATUS_NO_MEMORY:
				err(EX_UNAVAILABLE, "internal error");
				break;
			case STATUS_UNSUCCESSFUL:
				err(EX_USAGE, "mount error: %s", mountPoint);
				break;
			case STATUS_INVALID_PARAMETER:
				err(EX_USAGE, "URL parsing failed, please correct the URL and try again");
				break;
			case STATUS_BAD_NETWORK_NAME:
				err(EX_NOHOST, "share connection failed");
				break;
			default:
				err(EX_OSERR, "unknown status %d", status);
				break;
		}
	}

	/* We are done clean up anything left around */
	if (serverConnection)
		SMBReleaseServer(serverConnection);
	return 0;
}
Exemple #4
0
NTSTATUS
SMBOpenServerWithMountPoint(
	const char * pTargetMountPath,
	const char * pTargetTreeName,
	SMBHANDLE * outConnection,
	uint64_t    options)
{
	NTSTATUS	status;
	int         err;
	void *      hContext;
	struct statfs statbuf;
		
	*outConnection = NULL;
	
	status = SMBLibraryInit();
	if (!NT_SUCCESS(status)) {
		goto done;
	}
	
	/* Need to get the mount from name, use that as the URL */
	err = statfs(pTargetMountPath, &statbuf);
	if (err) {
		status = STATUS_OBJECT_PATH_NOT_FOUND;
		goto done;
	}
	
	status = SMBAllocateServer(outConnection, statbuf.f_mntfromname);
	if (!NT_SUCCESS(status)) {
		goto done;
	}

	status = SMBServerContext(*outConnection, &hContext);
	if (!NT_SUCCESS(status)) {
		goto done;
	}

	/* Need to clear out the user name field */
	smb_ctx_setuser(hContext, "");
	err = findMountPointVC(hContext, pTargetMountPath);
	if (err) {
		status = STATUS_OBJECT_NAME_NOT_FOUND;
		errno = err;
		goto done;
    }

	if (options & kSMBOptionSessionOnly) {
		goto done;
	}
	
	/*  No tree name, let's assume that the caller means IPC$ */
	if (!pTargetTreeName) {
		pTargetTreeName = "IPC$";
	}
	err = smb_ctx_setshare(hContext, pTargetTreeName);
	if (err) {
		if (err == ENAMETOOLONG) {
			status = STATUS_NAME_TOO_LONG;
		} else {
			status = STATUS_NO_MEMORY;
		}
		errno = err;
		goto done;
	}
	
	/* OK, now we have a virtual circuit but no tree connection yet. */
	err = smb_share_connect((*outConnection)->context);
	if (err) {
		status = STATUS_BAD_NETWORK_NAME;
		errno = err;
		goto done;
	}
	
	status = STATUS_SUCCESS;
	
done:
	if ((!NT_SUCCESS(status)) && *outConnection) {
		SMBReleaseServer(*outConnection);
		*outConnection = NULL;
	}

	return status;
}
Exemple #5
0
NTSTATUS 
SMBOpenServerEx(
    const char * targetServer,
    SMBHANDLE * outConnection,
    uint64_t    options)
{
    NTSTATUS    status;
    int         err;
    void *      hContext;

    CFMutableDictionaryRef netfsOptions = NULL;
	CFDictionaryRef ServerParams = NULL;

    *outConnection = NULL;

    status = SMBLibraryInit();
	if (!NT_SUCCESS(status)) {
        goto done;
    }

    netfsOptions = SMBCreateDefaultOptions(options);
    if (netfsOptions == NULL) {
        status = STATUS_NO_MEMORY;
        goto done;
    }

    status = SMBAllocateServer(outConnection, targetServer);
	if (!NT_SUCCESS(status)) {
        goto done;
    }

    status = SMBServerContext(*outConnection, &hContext);
	if (!NT_SUCCESS(status)) {
        goto done;
    }
	
	err = smb_get_server_info(hContext, NULL, netfsOptions, &ServerParams);
	if (err) {
        /* XXX map real NTSTATUS code */
        status = STATUS_CONNECTION_REFUSED;
		errno = err;
		goto done;
    }
	/*
	 * They didn't set the force new session option and we have a shared session,
	 * then we are done. We have a connection and we are authenticated.
	 */
	if (!(options & kSMBOptionForceNewSession) && (((struct smb_ctx *)hContext)->ct_vc_shared)) {
		goto authDone;
	}
	/*
	 * They have guest as the username in the url, then they want us to 
	 * force guest access.
	 */
	if (((struct smb_ctx *)hContext)->ct_setup.ioc_userflags & SMBV_GUEST_ACCESS) {
		options |= kSMBOptionUseGuestOnlyAuth;
	}
	
	/* Connect using Guest Access only */
	if (options & kSMBOptionUseGuestOnlyAuth) {
		status = SMBServerConnect(*outConnection, NULL, netfsOptions, kSMBAuthTypeGuest);
		goto authDone;
	}

	/* Connect using Anonymous Access only  */
	if (options & kSMBOptionUseAnonymousOnlyAuth) {
		status = SMBServerConnect(*outConnection, NULL, netfsOptions, kSMBAuthTypeAnonymous);
		goto authDone;
	}
	
	/* Attempt an authenticated connect, could be kerberos or ntlm. */
	status = SMBServerConnect(*outConnection, NULL, netfsOptions, kSMBAuthTypeAuthenticated);
	if (NT_SUCCESS(status)) {
		goto authDone;
	}
	
	/* See if we need to prompt for a password */
	if (SMBPasswordPrompt(*outConnection, options)) {
		/* Attempt an authenticated connect again , could be kerberos or ntlm. */
		status = SMBServerConnect(*outConnection, NULL, netfsOptions, kSMBAuthTypeAuthenticated);
		if (NT_SUCCESS(status)) {
			goto authDone;
		}
	}

	/* Kerberos and NTLM failed, attempt Guest access if option set */
	if (options & kSMBOptionAllowGuestAuth) {
		status = SMBServerConnect(*outConnection, NULL, netfsOptions, kSMBAuthTypeGuest);
		if (NT_SUCCESS(status)) {
			goto authDone;
		}
	}
	
	/* Kerberos and NTLM failed, attempt Anonymous access if option set */
	if (options & kSMBOptionAllowAnonymousAuth) {
		status = SMBServerConnect(*outConnection, NULL, netfsOptions, kSMBAuthTypeAnonymous);
		if (NT_SUCCESS(status)) {
			goto authDone;
		}
	}

authDone:

	if (!NT_SUCCESS(status)) {
		goto done;
	}
		
	if (options & kSMBOptionSessionOnly) {
		goto done;
	}
	
    /* 
	 * If the target doesn't contain a share name, let's assume that the
     * caller means IPC$, unless a share name is required.
     */
    if (!((struct smb_ctx *)hContext)->ct_origshare) {
        err = smb_ctx_setshare(hContext, "IPC$");
        if (err) {
			if (err == ENAMETOOLONG) {
				status = STATUS_NAME_TOO_LONG;
			} else {
				status = STATUS_NO_MEMORY;
			}
			errno = err;
            goto done;
        }
    }
	
    /* OK, now we have a virtual circuit but no tree connection yet. */
    err = smb_share_connect((*outConnection)->context);
    if (err) {
        status = STATUS_BAD_NETWORK_NAME;
		errno = err;
        goto done;
    }
    
    status = STATUS_SUCCESS;

done:
    if (netfsOptions) {
        CFRelease(netfsOptions);
    }
	if (ServerParams) {
		CFRelease(ServerParams);
	}
    if ((!NT_SUCCESS(status)) && *outConnection) {
        SMBReleaseServer(*outConnection);
        *outConnection = NULL;
    }

    return status;
}