+/*
+ * Dynamically load advapi32.dll for SID manipulation. In its absence,
+ * we degrade gracefully.
+ */
+#ifndef NO_SECURITY
+int advapi_initialised = FALSE;
+static HMODULE advapi;
+DECL_WINDOWS_FUNCTION(static, BOOL, OpenProcessToken,
+ (HANDLE, DWORD, PHANDLE));
+DECL_WINDOWS_FUNCTION(static, BOOL, GetTokenInformation,
+ (HANDLE, TOKEN_INFORMATION_CLASS,
+ LPVOID, DWORD, PDWORD));
+DECL_WINDOWS_FUNCTION(static, BOOL, InitializeSecurityDescriptor,
+ (PSECURITY_DESCRIPTOR, DWORD));
+DECL_WINDOWS_FUNCTION(static, BOOL, SetSecurityDescriptorOwner,
+ (PSECURITY_DESCRIPTOR, PSID, BOOL));
+DECL_WINDOWS_FUNCTION(, DWORD, GetSecurityInfo,
+ (HANDLE, SE_OBJECT_TYPE, SECURITY_INFORMATION,
+ PSID *, PSID *, PACL *, PACL *,
+ PSECURITY_DESCRIPTOR *));
+int init_advapi(void)
+{
+ advapi = load_system32_dll("advapi32.dll");
+ return advapi &&
+ GET_WINDOWS_FUNCTION(advapi, GetSecurityInfo) &&
+ GET_WINDOWS_FUNCTION(advapi, OpenProcessToken) &&
+ GET_WINDOWS_FUNCTION(advapi, GetTokenInformation) &&
+ GET_WINDOWS_FUNCTION(advapi, InitializeSecurityDescriptor) &&
+ GET_WINDOWS_FUNCTION(advapi, SetSecurityDescriptorOwner);
+}
+
+PSID get_user_sid(void)
+{
+ HANDLE proc = NULL, tok = NULL;
+ TOKEN_USER *user = NULL;
+ DWORD toklen, sidlen;
+ PSID sid = NULL, ret = NULL;
+
+ if ((proc = OpenProcess(MAXIMUM_ALLOWED, FALSE,
+ GetCurrentProcessId())) == NULL)
+ goto cleanup;
+
+ if (!p_OpenProcessToken(proc, TOKEN_QUERY, &tok))
+ goto cleanup;
+
+ if (!p_GetTokenInformation(tok, TokenUser, NULL, 0, &toklen) &&
+ GetLastError() != ERROR_INSUFFICIENT_BUFFER)
+ goto cleanup;
+
+ if ((user = (TOKEN_USER *)LocalAlloc(LPTR, toklen)) == NULL)
+ goto cleanup;
+
+ if (!p_GetTokenInformation(tok, TokenUser, user, toklen, &toklen))
+ goto cleanup;
+
+ sidlen = GetLengthSid(user->User.Sid);
+
+ sid = (PSID)smalloc(sidlen);
+
+ if (!CopySid(sidlen, sid, user->User.Sid))
+ goto cleanup;
+
+ /* Success. Move sid into the return value slot, and null it out
+ * to stop the cleanup code freeing it. */
+ ret = sid;
+ sid = NULL;
+
+ cleanup:
+ if (proc != NULL)
+ CloseHandle(proc);
+ if (tok != NULL)
+ CloseHandle(tok);
+ if (user != NULL)
+ LocalFree(user);
+ if (sid != NULL)
+ sfree(sid);
+
+ return ret;
+}
+
+#endif
+