DWORD WinRegUnregisterForRPC( rpc_binding_vector_p_t pServerBinding ) { volatile DWORD dwError = 0; volatile DWORD dwRpcStatus = 0; DCETHREAD_TRY { SRVSVC_LOG_INFO("Unregistering server from the endpoint mapper..."); rpc_ep_unregister(winreg_v1_0_s_ifspec, pServerBinding, NULL, (unsigned32*)&dwRpcStatus); } DCETHREAD_CATCH_ALL(THIS_CATCH) { if (dwRpcStatus == RPC_S_OK) { dwError = dcethread_exc_getstatus(THIS_CATCH); if (!dwError) { dwError = SRVSVC_ERROR_RPC_EXCEPTION_UPON_UNREGISTER; } } } DCETHREAD_ENDTRY BAIL_ON_DCE_ERROR(dwError, dwRpcStatus); BAIL_ON_SRVSVC_ERROR(dwError); DCETHREAD_TRY { rpc_binding_vector_free(&pServerBinding, (unsigned32*)&dwRpcStatus); } DCETHREAD_CATCH_ALL(THIS_CATCH) { if (dwRpcStatus == RPC_S_OK) { dwError = dcethread_exc_getstatus(THIS_CATCH); if (!dwError) { dwError = SRVSVC_ERROR_RPC_EXCEPTION_UPON_UNREGISTER; } } } DCETHREAD_ENDTRY BAIL_ON_DCE_ERROR(dwError, dwRpcStatus); BAIL_ON_SRVSVC_ERROR(dwError); DCETHREAD_TRY { SRVSVC_LOG_INFO("Cleaning up the communications endpoints..."); rpc_server_unregister_if(winreg_v1_0_s_ifspec, NULL, (unsigned32*)&dwRpcStatus); } DCETHREAD_CATCH_ALL(THIS_CATCH) { if (dwRpcStatus == RPC_S_OK) { dwError = dcethread_exc_getstatus(THIS_CATCH); if (!dwError) { dwError = SRVSVC_ERROR_RPC_EXCEPTION_UPON_UNREGISTER; } } } DCETHREAD_ENDTRY BAIL_ON_DCE_ERROR(dwError, dwRpcStatus); BAIL_ON_SRVSVC_ERROR(dwError); cleanup: return dwError; error: SRVSVC_LOG_ERROR("Failed to unregister RPC endpoint. Error code [%d]\n", dwError); goto cleanup; }
DWORD SrvSvcRegisterForRPC( PSTR pszServiceName, rpc_binding_vector_p_t* ppServerBinding ) { volatile DWORD dwError = 0; volatile DWORD dwRpcStatus = 0; rpc_binding_vector_p_t pServerBinding = NULL; BOOLEAN bRegistered = FALSE; BOOLEAN bBound = FALSE; BOOLEAN bEPRegistered = FALSE; static ENDPOINT endpoints[] = { {"ncacn_np", "\\\\pipe\\\\srvsvc"}, {"ncalrpc", NULL}, // endpoint is fetched from config parameter {NULL, NULL}, // placeholder for ncacn_ip_tcp (if enabled) {NULL, NULL} }; DWORD i = 0; PSTR lpcSocketPath = NULL; BOOLEAN registerTcpIp = FALSE; dwError = SrvSvcConfigGetLpcSocketPath(&lpcSocketPath); BAIL_ON_SRVSVC_ERROR(dwError); // Fill in the socket path for local procedure calls (ncalrpc) while (endpoints[i].protocol) { if (lpcSocketPath && LwRtlCStringIsEqual(endpoints[i].protocol, "ncalrpc", TRUE)) { endpoints[i].endpoint = lpcSocketPath; } i++; } dwError = SrvSvcConfigGetRegisterTcpIp(®isterTcpIp); BAIL_ON_SRVSVC_ERROR(dwError); // Append ncacn_ip_tcp endpoint if it's enabled in the configuration if (registerTcpIp) { endpoints[i++].protocol = "ncacn_ip_tcp"; } DCETHREAD_TRY { rpc_server_register_if (srvsvc_v3_0_s_ifspec, NULL, NULL, (unsigned32*)&dwRpcStatus); } DCETHREAD_CATCH_ALL(THIS_CATCH) { if ( dwRpcStatus == RPC_S_OK ) { dwError = dcethread_exc_getstatus (THIS_CATCH); if(!dwError) { dwError = SRVSVC_ERROR_RPC_EXCEPTION_UPON_REGISTER; } } } DCETHREAD_ENDTRY; BAIL_ON_DCE_ERROR(dwError, dwRpcStatus); BAIL_ON_SRVSVC_ERROR(dwError); bRegistered = TRUE; SRVSVC_LOG_INFO("RPC Service registered successfully."); DCETHREAD_TRY { dwError = bind_server(&pServerBinding, srvsvc_v3_0_s_ifspec, endpoints); } DCETHREAD_CATCH_ALL(THIS_CATCH) { if(!dwError) { dwError = dcethread_exc_getstatus (THIS_CATCH); } if(!dwError) { dwError = SRVSVC_ERROR_RPC_EXCEPTION_UPON_REGISTER; } } DCETHREAD_ENDTRY; BAIL_ON_SRVSVC_ERROR(dwError); bBound = TRUE; DCETHREAD_TRY { rpc_ep_register(srvsvc_v3_0_s_ifspec, pServerBinding, NULL, (idl_char*)pszServiceName, (unsigned32*)&dwRpcStatus); } DCETHREAD_CATCH_ALL(THIS_CATCH) { if ( dwRpcStatus == RPC_S_OK ) { dwError = dcethread_exc_getstatus (THIS_CATCH); if(!dwError) { dwError = SRVSVC_ERROR_RPC_EXCEPTION_UPON_REGISTER; } } } DCETHREAD_ENDTRY; BAIL_ON_DCE_ERROR(dwError, dwRpcStatus); BAIL_ON_SRVSVC_ERROR(dwError); bEPRegistered = TRUE; SRVSVC_LOG_INFO("RPC Endpoint registered successfully."); *ppServerBinding = pServerBinding; cleanup: // DCE/RPC runtime makes a copy of ncalrpc socket path internally // so it is safe to free it here LW_SAFE_FREE_MEMORY(lpcSocketPath); return dwError; error: SRVSVC_LOG_ERROR("Failed to register RPC endpoint. Error Code: [%u]\n", dwError); if (bEPRegistered) { DCETHREAD_TRY { DWORD tmpStatus = 0; rpc_ep_unregister(srvsvc_v3_0_s_ifspec, pServerBinding, NULL, (unsigned32*)&tmpStatus); } DCETHREAD_CATCH_ALL(THIS_CATCH) DCETHREAD_ENDTRY; } if (bBound) { DCETHREAD_TRY { DWORD tmpStatus = 0; rpc_binding_vector_free(&pServerBinding, (unsigned32*)&tmpStatus); } DCETHREAD_CATCH_ALL(THIS_CATCH) DCETHREAD_ENDTRY; } if (bRegistered) { DCETHREAD_TRY { DWORD tmpStatus = 0; rpc_server_unregister_if (srvsvc_v3_0_s_ifspec, NULL, (unsigned32*)&tmpStatus); } DCETHREAD_CATCH_ALL(THIS_CATCH) DCETHREAD_ENDTRY; } *ppServerBinding = NULL; goto cleanup; }
DWORD WinRegRegisterForRPC( PSTR pszServiceName, rpc_binding_vector_p_t* ppServerBinding ) { volatile DWORD dwError = 0; volatile DWORD dwRpcStatus = 0; rpc_binding_vector_p_t pServerBinding = NULL; BOOLEAN bRegistered = FALSE; BOOLEAN bBound = FALSE; BOOLEAN bEPRegistered = FALSE; static ENDPOINT endpoints[] = { {"ncacn_ip_tcp", NULL}, {"ncacn_np" , "\\\\pipe\\\\winreg"}, {NULL , NULL} }; DCETHREAD_TRY { rpc_server_register_if(winreg_v1_0_s_ifspec, NULL, NULL, (unsigned32*)&dwRpcStatus); } DCETHREAD_CATCH_ALL(THIS_CATCH) { if (dwRpcStatus == RPC_S_OK) { dwError = dcethread_exc_getstatus(THIS_CATCH); if (!dwError) { dwError = SRVSVC_ERROR_RPC_EXCEPTION_UPON_REGISTER; } } } DCETHREAD_ENDTRY; BAIL_ON_DCE_ERROR(dwError, dwRpcStatus); BAIL_ON_SRVSVC_ERROR(dwError); bRegistered = TRUE; SRVSVC_LOG_INFO("RPC Service registered successfully."); DCETHREAD_TRY { dwError = bind_server(&pServerBinding, winreg_v1_0_s_ifspec, endpoints); } DCETHREAD_CATCH_ALL(THIS_CATCH) { if (!dwError) { dwError = dcethread_exc_getstatus(THIS_CATCH); } if (!dwError) { dwError = SRVSVC_ERROR_RPC_EXCEPTION_UPON_REGISTER; } } DCETHREAD_ENDTRY; BAIL_ON_SRVSVC_ERROR(dwError); bBound = TRUE; DCETHREAD_TRY { rpc_ep_register(winreg_v1_0_s_ifspec, pServerBinding, NULL, (idl_char*)pszServiceName, (unsigned32*)&dwRpcStatus); } DCETHREAD_CATCH_ALL(THIS_CATCH) { if (dwRpcStatus == RPC_S_OK) { dwError = dcethread_exc_getstatus(THIS_CATCH); if (!dwError) { dwError = SRVSVC_ERROR_RPC_EXCEPTION_UPON_REGISTER; } } } DCETHREAD_ENDTRY; BAIL_ON_DCE_ERROR(dwError, dwRpcStatus); BAIL_ON_SRVSVC_ERROR(dwError); bEPRegistered = TRUE; SRVSVC_LOG_INFO("RPC Endpoint registered successfully."); *ppServerBinding = pServerBinding; cleanup: return dwError; error: SRVSVC_LOG_ERROR("Failed to register RPC endpoint. Error Code: [%u]\n", dwError); if (bEPRegistered) { DCETHREAD_TRY { DWORD tmpStatus = 0; rpc_ep_unregister(winreg_v1_0_s_ifspec, pServerBinding, NULL, (unsigned32*)&tmpStatus); } DCETHREAD_CATCH_ALL(THIS_CATCH) DCETHREAD_ENDTRY; } if (bBound) { DCETHREAD_TRY { DWORD tmpStatus = 0; rpc_binding_vector_free(&pServerBinding, (unsigned32*)&tmpStatus); } DCETHREAD_CATCH_ALL(THIS_CATCH) DCETHREAD_ENDTRY; } if (bRegistered) { DCETHREAD_TRY { DWORD tmpStatus = 0; rpc_server_unregister_if(winreg_v1_0_s_ifspec, NULL, (unsigned32*)&tmpStatus); } DCETHREAD_CATCH_ALL(THIS_CATCH) DCETHREAD_ENDTRY; } *ppServerBinding = NULL; goto cleanup; }
DWORD SrvSvcRpcInitialize( VOID ) { DWORD dwError = ERROR_SUCCESS; DWORD dwBindAttempts = 0; BOOLEAN bInLock = FALSE; static const DWORD dwMaxBindAttempts = 5; static const DWORD dwBindSleepSeconds = 5; SRVSVC_LOCK_MUTEX(bInLock, &gSrvsServerInfo.mutex); /* Binding to our RPC end-point might fail if dcerpcd is not yet ready when we start, so attempt it in a loop with a small delay between attempts */ for (dwBindAttempts = 0; dwBindAttempts < dwMaxBindAttempts; dwBindAttempts++) { dwError = SrvSvcRegisterForRPC( "Likewise Server Service", &gSrvsServerInfo.pServerBinding); if (dwError) { SRVSVC_LOG_INFO("Failed to bind srvsvc endpoint; retrying in " "%i seconds...", (int) dwBindSleepSeconds); sleep(dwBindSleepSeconds); } else { break; } } /* Bail if we still haven't succeeded after several attempts */ BAIL_ON_SRVSVC_ERROR(dwError); /* Now register the winreg pipe */ for (dwBindAttempts = 0; dwBindAttempts < dwMaxBindAttempts; dwBindAttempts++) { dwError = WinRegRegisterForRPC( "Likewise Registry Service", &gSrvsServerInfo.pRegistryBinding); if (dwError) { SRVSVC_LOG_INFO("Failed to bind wkssvc endpoint; retrying in " "%i seconds...", (int) dwBindSleepSeconds); sleep(dwBindSleepSeconds); } else { break; } } /* Bail if we still haven't succeeded after several attempts */ BAIL_ON_SRVSVC_ERROR(dwError); dwError = LwMapErrnoToLwError(dcethread_create( &gSrvsServerInfo.pRpcListenerThread, NULL, &SrvSvcListenForRPC, NULL)); BAIL_ON_SRVSVC_ERROR(dwError); while (!SrvSvcRpcIsListening()) { } error: SRVSVC_UNLOCK_MUTEX(bInLock, &gSrvsServerInfo.mutex); return dwError; }