Exemple #1
0
/*
 * SMBNetFsOpenSession
 */
int32_t 
SMBNetFsOpenSession(CFURLRef url, SMBHANDLE inConnection, CFDictionaryRef 
							openOptions, CFDictionaryRef *sessionInfo)
{
	int error = 0;
    void *hContext = NULL;
	
	SMBServerContext(inConnection, &hContext);
	error = smb_open_session(hContext, url, openOptions, sessionInfo);
	return error;
}
Exemple #2
0
static int
GetRootShareConnection(struct smb_ctx *ctx, const char *url, uint32_t authFlags,
                       const char * clientPrincipal, uint32_t clientNameType,
                       uint32_t	maxTimer)
{
    CFDictionaryRef serverParams = NULL;
    CFDictionaryRef sessionInfo = NULL;
    CFMutableDictionaryRef openOptions;
    int error = 0;
    time_t  start_time = time(NULL);

    openOptions = CFDictionaryCreateMutable(kCFAllocatorDefault, 0,
                                            &kCFTypeDictionaryKeyCallBacks,
                                            &kCFTypeDictionaryValueCallBacks);
    if (!openOptions) {
        smb_log_info("%s: Couldn't create open options for %s", ASL_LEVEL_ERR,
                     __FUNCTION__, url);
        error = ENOMEM;
        goto done;
    }

#ifdef SMBDEBUG_REMOUNT
    /* This is only needed for testing and should be remove once we have autofs hooked up */
    CFDictionarySetValue(openOptions, kNetFSForceNewSessionKey, kCFBooleanTrue);
#endif // SMBDEBUG_REMOUNT

    /* Never touch the user home directory */
    CFDictionarySetValue(openOptions, kNetFSNoUserPreferencesKey, kCFBooleanTrue);
    /*
     * If they have a loopback in the referral we always allow it, no way for
     * us to decided what is correct at this point.
     */
    CFDictionarySetValue(openOptions, kNetFSAllowLoopbackKey, kCFBooleanTrue);

    /*
     * Do a get server info call first to determine the if the server supports
     * the security we need. Also needed it to make sure we have the correct
     * server principal name.
     */
    while (difftime(time(NULL), start_time) < maxTimer ) {
        error = smb_get_server_info(ctx, NULL, openOptions, &serverParams);
        if (!error) {
            break;
        }
        smb_log_info("%s: get server info failed %d, sleeping one second, have %d seconds left.",
                     ASL_LEVEL_DEBUG,  __FUNCTION__, error,
                     maxTimer - (int)difftime(time(NULL), start_time));
        sleep(1);	/* Wait one second before trying again */
    }
    if (error) {
        smb_log_info("%s: get server info failed from %s with %d",
                     ASL_LEVEL_ERR,  __FUNCTION__, url, error);
        goto done;
    }

    /*
     * We should check the server params and make sure this server supports
     * the same auth method as the old server. Doesn't really make any difference
     * we should fail in the open if they don't support the correct auth.
     */

    /*
     * Set up the authorization using the same auth method that was use in the
     * original mount.
     */
    if (authFlags & (SMBV_GUEST_ACCESS | SMBV_SFS_ACCESS | SMBV_PRIV_GUEST_ACCESS)) {
        CFDictionarySetValue( openOptions, kNetFSUseGuestKey, kCFBooleanTrue);
    } else {
        CFMutableDictionaryRef authInfoDict;

        authInfoDict = CreateAuthDictionary(ctx, authFlags, clientPrincipal, clientNameType);
        if (!authInfoDict) {
            smb_log_info("%s: Creating authorization dictionary failed for  %s",
                         ASL_LEVEL_ERR, __FUNCTION__, url);
            error = ENOMEM;
            goto done;
        }
        CFDictionarySetValue( openOptions, kNetFSUseAuthenticationInfoKey, kCFBooleanTrue);
        CFDictionarySetValue(openOptions, kNetFSAuthenticationInfoKey, authInfoDict);
        CFRelease(authInfoDict);
    }

    error = smb_open_session(ctx, NULL, openOptions, &sessionInfo);
    if (error) {
        smb_log_info("%s: open session failed from url %s with %d", ASL_LEVEL_ERR,
                     __FUNCTION__, url, error);
        goto done;
    }
    error = smb_share_connect(ctx);
    if (error) {
        smb_log_info("%s: share connect failed from url %s with %d", ASL_LEVEL_ERR,
                     __FUNCTION__, url, error);
        goto done;
    }
done:
    if (sessionInfo) {
        CFRelease(sessionInfo);
    }
    if (serverParams) {
        CFRelease(serverParams);
    }
    if (openOptions) {
        CFRelease(openOptions);
    }
    return error;
}
Exemple #3
0
static NTSTATUS
SMBServerConnect(
        SMBHANDLE   hConnection,
        CFURLRef    targetUrl,
        CFMutableDictionaryRef netfsOptions,
        SMBAuthType authType)
{
    void * hContext;
    NTSTATUS status;
    int err;

    status = SMBServerContext(hConnection, &hContext);
	if (!NT_SUCCESS(status)) {
        return status;
    }

    /* Reset all the authentication options. This puts us into the
     * state of requiring user authentication (ie. forces NTLM).
     */
    CFDictionarySetValue(netfsOptions, kNetFSUseGuestKey, kCFBooleanFalse);
    CFDictionarySetValue(netfsOptions, kNetFSUseAnonymousKey, kCFBooleanFalse);

    switch (authType) {
		case kSMBAuthTypeAuthenticated:
        case kSMBAuthTypeKerberos:
        case kSMBAuthTypeUser:
			CFDictionarySetValue(netfsOptions, kNetFSUseAuthenticationInfoKey, kCFBooleanFalse);
			break;
        case kSMBAuthTypeGuest:
			/* Don't try Kerberos */
 			CFDictionarySetValue(netfsOptions, kNetFSUseAuthenticationInfoKey, kCFBooleanFalse);
			CFDictionarySetValue(netfsOptions, kNetFSUseGuestKey, kCFBooleanTrue);
            break;
        case kSMBAuthTypeAnonymous:
			/* Don't try Kerberos */
			CFDictionarySetValue(netfsOptions, kNetFSUseAuthenticationInfoKey, kCFBooleanFalse);
            CFDictionarySetValue(netfsOptions, kNetFSUseAnonymousKey, kCFBooleanTrue);
            break;
        default:
            return STATUS_INVALID_PARAMETER;
    }

    err = smb_open_session(hContext, targetUrl, netfsOptions,
            NULL /* [OUT] session_info */);

	/* XXX map real NTSTATUS code */
	if (err) {
		if (err< 0) {
			/* 
			 * A negative error is a special NetFSAuth error. We have no method
			 * to tell us if the calling routine understands these errors, so
			 * always set errno to a number defined in sys/errno.h.
			 */
			switch (errno) {
				case SMB_ENETFSNOAUTHMECHSUPP:
					errno = ENOTSUP;
					break;
				case SMB_ENETFSNOPROTOVERSSUPP:
					errno = ENOTSUP;
					break;
				case SMB_ENETFSACCOUNTRESTRICTED:
				case SMB_ENETFSPWDNEEDSCHANGE:
				case SMB_ENETFSPWDPOLICY:
				default:
					errno = EAUTH;
					break;
			}
		} else {
			errno = err;
		}
		if (err == EAUTH) {
			return STATUS_LOGON_FAILURE;
		}
		return STATUS_CONNECTION_REFUSED;
	}

    return STATUS_SUCCESS;
}