2 * PROJECT: ReactOS RPC Subsystem Service
3 * LICENSE: GPL-2.0+ (https://spdx.org/licenses/GPL-2.0+)
4 * PURPOSE: One-time service setup configuration.
5 * COPYRIGHT: Copyright 2018 Hermes Belusca-Maito
8 /* INCLUDES *****************************************************************/
10 /* PSDK/NDK Headers */
11 #define WIN32_NO_STATUS
17 #include <ndk/rtlfuncs.h>
20 #include "wine/debug.h"
22 WINE_DEFAULT_DEBUG_CHANNEL(rpcss
);
24 /* FUNCTIONS ****************************************************************/
32 DWORD cbData
= sizeof(dwData
);
33 DWORD dwType
= REG_NONE
;
35 lResult
= RegOpenKeyExW(HKEY_LOCAL_MACHINE
, L
"SYSTEM\\Setup", 0, KEY_QUERY_VALUE
, &hKey
);
36 if (lResult
!= ERROR_SUCCESS
)
39 lResult
= RegQueryValueExW(hKey
, L
"SystemSetupInProgress", NULL
,
40 &dwType
, (LPBYTE
)&dwData
, &cbData
);
43 if ((lResult
== ERROR_SUCCESS
) && (dwType
== REG_DWORD
) &&
44 (cbData
== sizeof(dwData
)) && (dwData
== 1))
55 /* S-1-5-18 -- Local System */
56 static SID SystemSid
= { SID_REVISION
, 1, { SECURITY_NT_AUTHORITY
}, { SECURITY_LOCAL_SYSTEM_RID
} };
59 PTOKEN_USER pTokenUser
;
61 DWORD cbTokenBuffer
= 0;
63 /* Get the process token */
64 if (!OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY
, &hToken
))
67 /* Retrieve token's information */
68 if (!GetTokenInformation(hToken
, TokenUser
, NULL
, 0, &cbTokenBuffer
) &&
69 GetLastError() != ERROR_INSUFFICIENT_BUFFER
)
74 pTokenUser
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, cbTokenBuffer
);
78 if (GetTokenInformation(hToken
, TokenUser
, pTokenUser
, cbTokenBuffer
, &cbTokenBuffer
))
80 /* Compare with SYSTEM SID */
81 bRet
= EqualSid(pTokenUser
->User
.Sid
, &SystemSid
);
84 HeapFree(GetProcessHeap(), 0, pTokenUser
);
92 RpcSsConfigureAsNetworkService(VOID
)
94 SC_HANDLE hSCManager
, hService
;
96 /* Open the service controller */
97 hSCManager
= OpenSCManagerW(NULL
, SERVICES_ACTIVE_DATABASE
, SC_MANAGER_CONNECT
);
100 ERR("OpenSCManager() failed with error 0x%lx\n", GetLastError());
104 /* Open the RPCSS service */
105 hService
= OpenServiceW(hSCManager
, L
"RPCSS", SERVICE_CHANGE_CONFIG
);
107 ERR("OpenService(\"RPCSS\") failed with error 0x%lx\n", GetLastError());
110 /* Use the NetworkService account */
111 if (!ChangeServiceConfigW(hService
,
119 L
"NT AUTHORITY\\NetworkService",
123 ERR("ChangeServiceConfig(\"RPCSS\") failed with error 0x%lx\n", GetLastError());
126 CloseServiceHandle(hService
);
129 CloseServiceHandle(hSCManager
);
133 AddImpersonatePrivilege(VOID
)
135 /* S-1-5-6 -- "Service" group */
136 static SID ServiceSid
= { SID_REVISION
, 1, { SECURITY_NT_AUTHORITY
}, { SECURITY_SERVICE_RID
} };
139 LSA_HANDLE PolicyHandle
;
140 LSA_OBJECT_ATTRIBUTES ObjectAttributes
;
141 LSA_UNICODE_STRING RightString
;
143 ZeroMemory(&ObjectAttributes
, sizeof(ObjectAttributes
));
144 Status
= LsaOpenPolicy(NULL
, &ObjectAttributes
,
145 POLICY_CREATE_ACCOUNT
| POLICY_LOOKUP_NAMES
,
147 if (!NT_SUCCESS(Status
))
149 ERR("LsaOpenPolicy() failed with Status 0x%08lx\n", Status
);
153 RtlInitUnicodeString(&RightString
, L
"SeImpersonatePrivilege");
154 Status
= LsaAddAccountRights(PolicyHandle
, &ServiceSid
, &RightString
, 1);
155 if (!NT_SUCCESS(Status
))
157 ERR("LsaAddAccountRights(\"S-1-5-6\", \"%wZ\") failed with Status 0x%08lx\n", Status
, &RightString
);
160 LsaClose(PolicyHandle
);
163 VOID
DoRpcSsSetupConfiguration(VOID
)
166 * On first run during the setup phase, the RPCSS service runs under
167 * the LocalSystem account. RPCSS then re-configures itself to run
168 * under the NetworkService account and adds the Impersonate privilege
169 * to the "Service" group.
170 * This is done in this way, because the NetworkService account does not
171 * initially exist when the setup phase is running and the RPCSS service
172 * is started, but this account is created later during the setup phase.
174 if (SetupIsActive() && RunningAsSYSTEM())
176 RpcSsConfigureAsNetworkService();
177 AddImpersonatePrivilege();