/* * 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; }
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; }
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; }