From 69d68eb22f4927088bd011d4d11cda90929f7484 Mon Sep 17 00:00:00 2001 From: Bill Zissimopoulos Date: Wed, 29 Nov 2017 16:20:15 -0800 Subject: [PATCH] launcher: compute user name from client token dll: np: do not pass user name as launcher argument --- src/dll/np.c | 12 ----- src/launcher/launcher.c | 115 +++++++++++++++++++++++++++++++++++++++- 2 files changed, 114 insertions(+), 13 deletions(-) diff --git a/src/dll/np.c b/src/dll/np.c index 09010b28..dfa38f7b 100644 --- a/src/dll/np.c +++ b/src/dll/np.c @@ -17,7 +17,6 @@ #include #include -#include #include #include @@ -169,12 +168,6 @@ static inline BOOLEAN FspNpParseRemoteUserName(PWSTR RemoteName, return FALSE; } -static inline BOOLEAN FspNpGetLocalUserName( - PWSTR UserName, ULONG UserNameSize/* in chars */) -{ - return GetUserName(UserName, &UserNameSize); -} - static inline DWORD FspNpCallLauncherPipe(PWSTR PipeBuf, ULONG SendSize, ULONG RecvSize) { DWORD NpResult; @@ -496,7 +489,6 @@ DWORD APIENTRY NPAddConnection(LPNETRESOURCEW lpNetResource, LPWSTR lpPassword, WCHAR LocalNameBuf[3]; PWSTR ClassName, InstanceName, RemoteName, P; ULONG ClassNameLen, InstanceNameLen; - WCHAR LocalUserName[UNLEN + 1]; DWORD CredentialsKind; PWSTR PipeBuf = 0; #if defined(FSP_NP_CREDENTIAL_MANAGER) @@ -525,9 +517,6 @@ DWORD APIENTRY NPAddConnection(LPNETRESOURCEW lpNetResource, LPWSTR lpPassword, return WN_ALREADY_CONNECTED; } - if (!FspNpGetLocalUserName(LocalUserName, sizeof LocalUserName / sizeof LocalUserName[0])) - LocalUserName[0] = L'\0'; - FspNpGetCredentialsKind(lpRemoteName, &CredentialsKind); #if defined(FSP_NP_CREDENTIAL_MANAGER) @@ -582,7 +571,6 @@ DWORD APIENTRY NPAddConnection(LPNETRESOURCEW lpNetResource, LPWSTR lpPassword, memcpy(P, InstanceName, InstanceNameLen * sizeof(WCHAR)); P += InstanceNameLen; *P++ = L'\0'; lstrcpyW(P, RemoteName); P += lstrlenW(RemoteName) + 1; lstrcpyW(P, LocalNameBuf); P += lstrlenW(LocalNameBuf) + 1; - lstrcpyW(P, LocalUserName); P += lstrlenW(LocalUserName) + 1; if (FSP_NP_CREDENTIALS_USERPASS == CredentialsKind) { lstrcpyW(P, lpUserName); P += lstrlenW(lpUserName) + 1; diff --git a/src/launcher/launcher.c b/src/launcher/launcher.c index 3f13722b..76b19d93 100644 --- a/src/launcher/launcher.c +++ b/src/launcher/launcher.c @@ -67,6 +67,76 @@ BOOL CreateOverlappedPipe( return TRUE; } +static NTSTATUS GetTokenUserName(HANDLE Token, PWSTR *PUserName) +{ + TOKEN_USER *User = 0; + WCHAR Name[256], Domn[256]; + DWORD UserSize, NameSize, DomnSize; + SID_NAME_USE Use; + PWSTR P; + NTSTATUS Result; + + *PUserName = 0; + + if (GetTokenInformation(Token, TokenUser, 0, 0, &UserSize)) + { + Result = STATUS_INVALID_PARAMETER; + goto exit; + } + if (ERROR_INSUFFICIENT_BUFFER != GetLastError()) + { + Result = FspNtStatusFromWin32(GetLastError()); + goto exit; + } + + User = MemAlloc(UserSize); + if (0 == User) + { + Result = STATUS_INSUFFICIENT_RESOURCES; + goto exit; + } + + if (!GetTokenInformation(Token, TokenUser, User, UserSize, &UserSize)) + { + Result = FspNtStatusFromWin32(GetLastError()); + goto exit; + } + + NameSize = sizeof Name / sizeof Name[0]; + DomnSize = sizeof Domn / sizeof Domn[0]; + if (!LookupAccountSidW(0, User->User.Sid, Name, &NameSize, Domn, &DomnSize, &Use)) + { + Result = FspNtStatusFromWin32(GetLastError()); + goto exit; + } + + NameSize = lstrlenW(Name); + DomnSize = lstrlenW(Domn); + + P = *PUserName = MemAlloc((DomnSize + 1 + NameSize + 1) * sizeof(WCHAR)); + if (0 == P) + { + Result = STATUS_INSUFFICIENT_RESOURCES; + goto exit; + } + + if (0 < DomnSize) + { + memcpy(P, Domn, DomnSize * sizeof(WCHAR)); + P[DomnSize] = L'\\'; + P += DomnSize + 1; + } + memcpy(P, Name, NameSize * sizeof(WCHAR)); + P[NameSize] = L'\0'; + + Result = STATUS_SUCCESS; + +exit: + MemFree(User); + + return Result; +} + typedef struct { HANDLE Process; @@ -142,6 +212,17 @@ typedef struct static CRITICAL_SECTION SvcInstanceLock; static HANDLE SvcInstanceEvent; static LIST_ENTRY SvcInstanceList = { &SvcInstanceList, &SvcInstanceList }; +static DWORD SvcInstanceTlsKey = TLS_OUT_OF_INDEXES; + +static inline PWSTR SvcInstanceUserName(VOID) +{ + return TlsGetValue(SvcInstanceTlsKey); +} + +static inline VOID SvcInstanceSetUserName(PWSTR UserName) +{ + TlsSetValue(SvcInstanceTlsKey, UserName); +} static VOID CALLBACK SvcInstanceTerminated(PVOID Context, BOOLEAN Timeout); @@ -210,6 +291,14 @@ static NTSTATUS SvcInstanceReplaceArguments(PWSTR String, ULONG Argc, PWSTR *Arg else Length += SvcInstanceArgumentLength(EmptyArg); } + else + if (L'U' == *P) + { + if (0 != SvcInstanceUserName()) + Length += SvcInstanceArgumentLength(SvcInstanceUserName()); + else + Length += SvcInstanceArgumentLength(EmptyArg); + } else Length++; break; @@ -236,6 +325,14 @@ static NTSTATUS SvcInstanceReplaceArguments(PWSTR String, ULONG Argc, PWSTR *Arg else Q = SvcInstanceArgumentCopy(Q, EmptyArg); } + else + if (L'U' == *P) + { + if (0 != SvcInstanceUserName()) + Q = SvcInstanceArgumentCopy(Q, SvcInstanceUserName()); + else + Q = SvcInstanceArgumentCopy(Q, EmptyArg); + } else *Q++ = *P; break; @@ -918,6 +1015,10 @@ static NTSTATUS SvcStart(FSP_SERVICE *Service, ULONG argc, PWSTR *argv) if (0 == SvcInstanceEvent) goto fail; + SvcInstanceTlsKey = TlsAlloc(); + if (TLS_OUT_OF_INDEXES == SvcInstanceTlsKey) + goto fail; + SvcJob = CreateJobObjectW(0, 0); if (0 != SvcJob) { @@ -980,6 +1081,9 @@ fail: if (0 != SvcJob) CloseHandle(SvcJob); + if (TLS_OUT_OF_INDEXES != SvcInstanceTlsKey) + TlsFree(SvcInstanceTlsKey); + if (0 != SvcInstanceEvent) CloseHandle(SvcInstanceEvent); @@ -1023,6 +1127,9 @@ static NTSTATUS SvcStop(FSP_SERVICE *Service) if (0 != SvcJob) CloseHandle(SvcJob); + if (TLS_OUT_OF_INDEXES != SvcInstanceTlsKey) + TlsFree(SvcInstanceTlsKey); + if (0 != SvcInstanceEvent) CloseHandle(SvcInstanceEvent); @@ -1194,13 +1301,16 @@ static VOID SvcPipeTransact(HANDLE ClientToken, PWSTR PipeBuf, PULONG PSize) return; PWSTR P = PipeBuf, PipeBufEnd = PipeBuf + *PSize / sizeof(WCHAR); - PWSTR ClassName, InstanceName; + PWSTR ClassName, InstanceName, UserName; ULONG Argc; PWSTR Argv[9]; BOOLEAN HasSecret = FALSE; NTSTATUS Result; *PSize = 0; + GetTokenUserName(ClientToken, &UserName); + SvcInstanceSetUserName(UserName); + switch (*P++) { case LauncherSvcInstanceStartWithSecret: @@ -1264,6 +1374,9 @@ static VOID SvcPipeTransact(HANDLE ClientToken, PWSTR PipeBuf, PULONG PSize) SvcPipeTransactResult(STATUS_INVALID_PARAMETER, PipeBuf, PSize); break; } + + SvcInstanceSetUserName(0); + MemFree(UserName); } int wmain(int argc, wchar_t **argv)