4.3 TermSrvBindSecure Example
The following example creates an RPC binding to an endpoint that uses authentication, authorization, and security quality-of-service information.
-
RPC_STATUS TermSrvBindSecure( LPCWSTR pszUuid, LPCWSTR pszProtocolSequence, LPCWSTR pszNetworkAddress, LPCWSTR pszEndPoint, LPCWSTR pszOptions, RPC_BINDING_HANDLE *pHandle ) { RPC_STATUS Status; RPC_SECURITY_QOS qos; LPWSTR wszServerSPN = NULL; *pHandle = NULL; Status = TermSrvBind( pszUuid, pszProtocolSequence, pszNetworkAddress, pszEndPoint, pszOptions, pHandle); if( Status != RPC_S_OK ) { wprintf ( L"Error %d in TermSrvBind", Status ); goto TS_EXIT_POINT; } qos.Capabilities = RPC_C_QOS_CAPABILITIES_MUTUAL_AUTH; qos.IdentityTracking = RPC_C_QOS_IDENTITY_DYNAMIC; qos.ImpersonationType = RPC_C_IMP_LEVEL_IMPERSONATE; qos.Version = RPC_C_SECURITY_QOS_VERSION; if( PrepareServerSPN( pszNetworkAddress, &wszServerSPN )) { Status = RpcBindingSetAuthInfoEx( *pHandle, wszServerSPN, RPC_C_AUTHN_LEVEL_PKT_PRIVACY, RPC_C_AUTHN_GSS_NEGOTIATE, NULL, RPC_C_AUTHZ_NAME, &qos); LocalFree(wszServerSPN); } else { Status = RpcBindingSetAuthInfoEx( *pHandle, (LPWSTR)pszNetworkAddress, RPC_C_AUTHN_LEVEL_PKT_PRIVACY, RPC_C_AUTHN_GSS_NEGOTIATE, NULL, RPC_C_AUTHZ_NAME, &qos); } if ( RPC_S_OK != Status ) { wprintf ( L"Error %d in RpcBindingSetAuthInfoEx", Status ); goto TS_EXIT_POINT; } TS_EXIT_POINT: if ( RPC_S_OK != Status && NULL != *pHandle ) { RpcBindingFree( pHandle ); } return Status; }
Generate a standard RPC binding from the protocol sequence, security options, and UUID, for example.
-
RPC_STATUS TermSrvBind( IN LPCWSTR pszUuid, IN LPCWSTR pszProtocolSequence, IN LPCWSTR pszNetworkAddress, IN LPCWSTR pszEndPoint, IN LPCWSTR pszOptions, OUT RPC_BINDING_HANDLE *pHandle ) { RPC_STATUS Status; LPWSTR pszString = NULL; /* * Compose the binding string using the helper routine * and our protocol sequence, security options, UUID, and so on. */ Status = RpcStringBindingCompose( (LPWSTR)pszUuid, (LPWSTR)pszProtocolSequence, (LPWSTR)pszNetworkAddress, (LPWSTR)pszEndPoint, (LPWSTR)pszOptions, &pszString ); if( Status != RPC_S_OK ) { wprintf ( L"Error %d in RpcStringBindingCompose", Status ); goto TS_EXIT_POINT; } /* * Now generate the RPC binding from the canonical RPC * binding string. */ Status = RpcBindingFromStringBinding( pszString, pHandle ); if( Status != RPC_S_OK ) { wprintf ( L"Error %d in RpcBindingFromStringBinding", Status ); goto TS_EXIT_POINT; } TS_EXIT_POINT: if ( NULL != pszString ) { /* * Free the memory returned from RpcStringBindingCompose() */ RpcStringFree( &pszString ); } return( Status ); }
Recreate a valid SPN for Windows Vista operating system from an existing SPN.
-
BOOL PrepareServerSPN( IN LPCWSTR pszNetworkAddress, __deref_out_opt LPWSTR *ppwszServerSPN ) { // Windows Server 2008 RPC does not accept "net use" credential anymore. // <Domain>\<Machine> is not a valid SPN, a valid SPN is host/<Machine Name> LPWSTR pszTemplate = L"host/%s"; *ppwszServerSPN = NULL; HRESULT hr = S_OK; UINT stringLength = wcslen(pszTemplate)+wcslen(pszNetworkAddress)+1; *ppwszServerSPN = (LPWSTR)LocalAlloc(LPTR, stringLength * sizeof(WCHAR)); if(*ppwszServerSPN) { hr = StringCchPrintf( *ppwszServerSPN, stringLength, pszTemplate, pszNetworkAddress ); ASSERT( SUCCEEDED( hr )); } if( FAILED(hr) ) { if( NULL != *ppwszServerSPN ) { LocalFree( *ppwszServerSPN ); *ppwszServerSPN = NULL; } } return SUCCEEDED(hr); }