DWORD VMCAGetClientName(handle_t IDL_handle) { #if DEBUG_RPC rpc_binding_handle_t Srv; PSTR pszBinding = NULL; PSTR pszObjUUID = NULL; PSTR pszProtoSeq = NULL; PSTR pszNetworkAddress = NULL; PSTR pszEndPoint = NULL; PSTR pszNetworkOptions = NULL; unsigned32 rs = 0; rpc_binding_server_from_client (IDL_handle, &Srv, &rs); BAIL_ON_VMCA_ERROR(rs); rpc_binding_to_string_binding(Srv, (unsigned char **) &pszBinding, &rs); printf("Binding Info : %s\n", pszBinding); rpc_binding_free(&Srv, &rs); rpc_string_binding_parse(pszBinding, (unsigned_char_t **) &pszObjUUID, (unsigned_char_t **) &pszProtoSeq, (unsigned_char_t **) &pszNetworkAddress, (unsigned_char_t **) &pszEndPoint, (unsigned_char_t **) &pszNetworkOptions, &rs); printf("Obj UUID : %s, Proto : %s, Network : %s, \ EndPoint %s, Network Options : %s \n", pszObjUUID, pszProtoSeq, pszNetworkAddress, pszEndPoint, pszNetworkOptions); rpc_string_free((unsigned_char_t **) &pszBinding, &rs); rpc_string_free((unsigned_char_t **) &pszObjUUID, &rs); rpc_string_free((unsigned_char_t **) &pszProtoSeq, &rs); rpc_string_free((unsigned_char_t **) &pszNetworkAddress, &rs); rpc_string_free((unsigned_char_t **) &pszEndPoint, &rs); rpc_string_free((unsigned_char_t **) &pszNetworkOptions, &rs); #endif return 0; }
BOOLEAN CreateRpcBinding( PVOID *phBinding, RPC_BINDING_TYPE eBindingType, PCWSTR pwszHostname, PCWSTR pwszBinding, PCREDENTIALS pCredentials ) { PCSTR pszNtlmsspAuth = "ntlmssp"; PCSTR pszSign = "sign"; PCSTR pszSeal = "seal"; BOOLEAN bRet = TRUE; NTSTATUS ntStatus = STATUS_SUCCESS; DWORD dwError = ERROR_SUCCESS; unsigned32 rpcStatus = RPC_S_OK; LSA_BINDING hBinding = NULL; LW_PIO_CREDS pIoCreds = NULL; PWSTR pwszBindingString = NULL; size_t sBindingStringLen = 0; PSTR pszBindingString = NULL; PSTR *ppszOptions = NULL; DWORD iOpt = 0; DWORD i = 0; DWORD dwNumValidOptions = 0; unsigned32 AuthType = 0; unsigned32 ProtectionLevel = 0; SEC_WINNT_AUTH_IDENTITY *pNtlmSspAuthInfo = NULL; PVOID pAuthInfo = NULL; unsigned char *pszUuid = NULL; unsigned char *pszProtSeq = NULL; unsigned char *pszNetworkAddr = NULL; unsigned char *pszEndpoint = NULL; unsigned char *pszOptions = NULL; PSTR pszHostname = NULL; if (phBinding == NULL) { ntStatus = STATUS_INVALID_PARAMETER; BAIL_ON_NT_STATUS(ntStatus); } if (pwszBinding) { dwError = LwAllocateWc16String(&pwszBindingString, pwszBinding); BAIL_ON_WIN_ERROR(dwError); dwError = LwWc16sLen(pwszBindingString, &sBindingStringLen); BAIL_ON_WIN_ERROR(dwError); dwError = LwWc16sToMbs(pwszBindingString, &pszBindingString); BAIL_ON_WIN_ERROR(dwError); ppszOptions = get_string_list(pszBindingString, ':'); if (ppszOptions == NULL) { ntStatus = STATUS_INVALID_PARAMETER; BAIL_ON_NT_STATUS(ntStatus); } /* * Find and identify valid options */ while (ppszOptions[iOpt]) { if (!strcasecmp(pszNtlmsspAuth, ppszOptions[iOpt])) { AuthType = rpc_c_authn_winnt; dwNumValidOptions++; } else if (!strcasecmp(pszSign, ppszOptions[iOpt])) { ProtectionLevel = rpc_c_authn_level_pkt_integrity; dwNumValidOptions++; } else if (!strcasecmp(pszSeal, ppszOptions[iOpt])) { ProtectionLevel = rpc_c_authn_level_pkt_privacy; dwNumValidOptions++; } iOpt++; } } /* * Cut off the options from the binding string so it can * be passed to rpc routines */ if (dwNumValidOptions > 0) { i = sBindingStringLen; while (dwNumValidOptions && pwszBindingString[--i]) { if (pwszBindingString[i] == (WCHAR)':') { dwNumValidOptions--; } } pwszBindingString[i] = (WCHAR)'\0'; pszBindingString[i] = '\0'; } ntStatus = LwIoGetActiveCreds(NULL, &pIoCreds); BAIL_ON_NT_STATUS(ntStatus); if (pwszBindingString) { ntStatus = RpcInitBindingFromBindingString( (handle_t*)&hBinding, pwszBindingString, pIoCreds); } else { switch (eBindingType) { case RPC_LSA_BINDING: ntStatus = LsaInitBindingDefault(&hBinding, pwszHostname, pIoCreds); break; case RPC_SAMR_BINDING: ntStatus = SamrInitBindingDefault(&hBinding, pwszHostname, pIoCreds); break; case RPC_NETLOGON_BINDING: ntStatus = NetrInitBindingDefault(&hBinding, pwszHostname, pIoCreds); break; case RPC_DSSETUP_BINDING: ntStatus = DsrInitBindingDefault(&hBinding, pwszHostname, pIoCreds); break; case RPC_WKSSVC_BINDING: ntStatus = WkssInitBindingDefault(&hBinding, pwszHostname, pIoCreds); break; default: ntStatus = STATUS_NOT_IMPLEMENTED; break; } } BAIL_ON_NT_STATUS(ntStatus); switch (AuthType) { case rpc_c_authn_winnt: dwError = LwAllocateMemory(sizeof(*pNtlmSspAuthInfo), OUT_PPVOID(&pNtlmSspAuthInfo)); BAIL_ON_WIN_ERROR(dwError); if (pCredentials->Ntlm.pwszDomain) { dwError = LwWc16sToMbs(pCredentials->Ntlm.pwszDomain, &pNtlmSspAuthInfo->Domain); BAIL_ON_WIN_ERROR(dwError); pNtlmSspAuthInfo->DomainLength = strlen(pNtlmSspAuthInfo->Domain); } dwError = LwWc16sToMbs(pCredentials->Ntlm.pwszUsername, &pNtlmSspAuthInfo->User); BAIL_ON_WIN_ERROR(dwError); pNtlmSspAuthInfo->UserLength = strlen(pNtlmSspAuthInfo->User); dwError = LwWc16sToMbs(pCredentials->Ntlm.pwszPassword, &pNtlmSspAuthInfo->Password); BAIL_ON_WIN_ERROR(dwError); pNtlmSspAuthInfo->PasswordLength = strlen(pNtlmSspAuthInfo->Password); pAuthInfo = (PVOID)pNtlmSspAuthInfo; break; default: pAuthInfo = NULL; break; } if (pwszHostname) { dwError = LwWc16sToMbs(pwszHostname, &pszHostname); BAIL_ON_WIN_ERROR(dwError); } else { rpc_string_binding_parse((unsigned char*)pszBindingString, &pszUuid, &pszProtSeq, &pszNetworkAddr, &pszEndpoint, &pszOptions, &rpcStatus); if (rpcStatus) { ntStatus = LwRpcStatusToNtStatus(rpcStatus); BAIL_ON_NT_STATUS(ntStatus); } dwError = LwAllocateString((PSTR)pszNetworkAddr, &pszHostname); BAIL_ON_WIN_ERROR(dwError); } if (AuthType) { rpc_binding_set_auth_info(hBinding, (unsigned char*)pszHostname, ProtectionLevel, AuthType, (rpc_auth_identity_handle_t)pAuthInfo, rpc_c_authz_name, /* authz_protocol */ &rpcStatus); if (rpcStatus) { ntStatus = LwRpcStatusToNtStatus(rpcStatus); BAIL_ON_NT_STATUS(ntStatus); } } *phBinding = hBinding; cleanup: if (pIoCreds) { LwIoDeleteCreds(pIoCreds); } LW_SAFE_FREE_MEMORY(pwszBindingString); LW_SAFE_FREE_MEMORY(pszBindingString); LW_SAFE_FREE_MEMORY(pszHostname); rpc_string_free(&pszUuid, &rpcStatus); rpc_string_free(&pszProtSeq, &rpcStatus); rpc_string_free(&pszNetworkAddr, &rpcStatus); rpc_string_free(&pszEndpoint, &rpcStatus); rpc_string_free(&pszOptions, &rpcStatus); if (ppszOptions) { free_string_list(ppszOptions); } if (ntStatus == STATUS_SUCCESS && dwError != ERROR_SUCCESS) { ntStatus = LwWin32ErrorToNtStatus(dwError); } if (ntStatus != STATUS_SUCCESS) { bRet = FALSE; } return bRet; error: *phBinding = NULL; bRet = FALSE; goto cleanup; }
INTERNAL int is_unpriv_handle( handle_t h, error_status_t *st ) { error_status_t status,status1; rpc_binding_vector_p_t bv; handle_t binding; unsigned_char_p_t stb,our_netaddr,client_netaddr; unsigned32 i; static unsigned_char_p_t *local_netaddr = NULL; static unsigned32 addr_count = 0; unsigned32 prot_seq = 0; rpc_transport_info_handle_t info; unsigned32 uid = (unsigned32) -1; unsigned32 gid = (unsigned32) -1; rpc_binding_inq_prot_seq(h, &prot_seq, &status); if (! STATUS_OK(&status)) { *st = status; return(1); } if (prot_seq == rpc_c_protseq_id_ncalrpc) { rpc_binding_inq_transport_info(h, &info, &status); if (! STATUS_OK(&status)) { *st = status; return(1); } rpc_lrpc_transport_info_inq_peer_eid(info, &uid, &gid); *st = rpc_s_ok; return (uid != 0); } /* Get client network address from binding handle (client_netaddr) */ rpc_binding_server_from_client(h,&binding,&status); if (! STATUS_OK(&status)) { *st = status; return(1); } rpc_binding_to_string_binding(binding,&stb,&status); if (! STATUS_OK(&status)) { rpc_binding_free(&binding,&status1); *st = status; return(1); } rpc_binding_free(&binding,&status1); rpc_string_binding_parse(stb,NULL,NULL,&client_netaddr,NULL,NULL,&status); if (! STATUS_OK(&status)) { rpc_string_free(&stb,&status1); *st = status; return(1); } rpc_string_free(&stb,&status1); /* * Lookup all of the addresses which this node answers to. * Cache these in static storage so we only do this work once. */ if (addr_count == 0) { rpc_server_inq_bindings(&bv,&status); if (! STATUS_OK(&status)) { rpc_string_free(&client_netaddr,&status1); *st = status; return(1); } addr_count = bv->count; local_netaddr = (unsigned_char_p_t *) malloc( (size_t) (addr_count * sizeof(unsigned_char_p_t))); if (local_netaddr == NULL) { rpc_string_free(&client_netaddr,&status1); rpc_binding_vector_free(&bv,&status1); *st = ept_s_no_memory; return(1); } for ( i=0; i < bv->count; i++ ) { rpc_binding_to_string_binding(bv->binding_h[i],&stb,&status); if (! STATUS_OK(&status)) { rpc_binding_vector_free(&bv,&status1); rpc_string_free(&client_netaddr,&status1); *st = status; return(1); } rpc_string_binding_parse(stb,NULL,NULL, &our_netaddr,NULL,NULL,&status); if (! STATUS_OK(&status)) { rpc_binding_vector_free(&bv,&status1); rpc_string_free(&stb,&status1); rpc_string_free(&client_netaddr,&status1); *st = status; return(1); } local_netaddr[i] = our_netaddr; rpc_string_free(&stb,&status1); } rpc_binding_vector_free(&bv,&status1); } /* * Compare the addresses with the client address */ *st = rpc_s_ok; for ( i=0; i < addr_count; i++ ) { if(strcmp((char*) client_netaddr, (char*) local_netaddr[i]) == 0) { rpc_string_free(&client_netaddr,&status1); return(0); } } rpc_string_free(&client_netaddr,&status1); return(1); }