and replace the std::string declarations shown below with tstring. It is unfortunate that std:: does not have built-in the concept of Unicode-aware strings. Apparently there is no header file used for this subroutine example class CSID public: //**************** // CSID() // !CSID() //**************** CSID() virtual CSID() //**************************************************************** // Get // Result: PSID // A pointer to the SID if one is present // NULL if there is no SID //**************************************************************** PSID Get() return buffer.size() > 0 ? (PSID)&buffer[0] : NULL; //**************************************************************** // CopySid(PSID sid) // Inputs: // PSID sid: The SID to be copied into this structure // Result: BOOL // TRUE if successful // FALSE if error //**************************************************************** BOOL CopySid(PSID sid) DWORD len = ::GetLengthSid(sid); buffer.resize(len); if(!::CopySid(len, (PSID)&buffer[0], sid)) /* failed */ buffer.resize(0); return FALSE; /* failed */ return TRUE; //**************************************************************** // ToString // Result: std::tstring // The SID expressed as a string // This will be the empty string if there is an error //**************************************************************** std::string ToString() LPTSTR result; if(::ConvertSidToStringSid((PSID)&buffer[0], &result)) /* success */ std::string t = result; LocalFree(result); return t; /* success */ else return std::string(_T("")); //**************** protected: std::vectorbuffer;;/***************************************************************************** GetLogonSid* Inputs:* HANDLE hToken: Token from OpenProcessToken or other source* CSDI & sid: A reference to a CSID structure* Result: BOOL* TRUE if successful* FALSE if error (use ::GetLastError to determine reason)* Effect: * Sets the CSID to the sid of the logon account. This is undefined* if the return value is FALSE****************************************************************************/BOOL GetLogonSid(HANDLE hToken, CSID & sid); File LogonSid.cpp #include #include #include It is not at all clear why all the variables are declared at the top of the function. The title clearly says that this example is written in C++. It is not clear why a temporary structure that is used only inside a single function and which must be deleted before exiting is declared as if the code had been written for the PDP-11 in 1975. In C++, the programmer, had he or she been even marginally literate, would have used at std::vector. BOOL GetLogonSID (HANDLE hToken, PSID *ppsid) BOOL bSuccess = FALSE; DWORD dwIndex; DWORD dwLength = 0; PTOKEN_GROUPS ptg = NULL; BOOL GetLogonSid(HANDLE hToken, CSID & sid) std::vector tg; // Get required buffer size and allocate the TOKEN_GROUPS buffer. DWORD dwLength = 0; // Verify the parameter passed in is not NULL. if (NULL == ppsid) goto Cleanup; Only a C programmer would pass in a PSID *. A C++ programmer would have used a PSID &. I chose to implement a class CSID that provides useful functionality. Since I use a reference, there is no need to check the parameter to see if it is NULL. And the goto Cleanup is simply childish. There is no reason to go to a cleanup routine when there is nothing to clean up! In the code below, there is no reason to pass the argument ptg into the call; NULL is sufficient. There is no reason to cast it to LPVOID because that is implicitly handled by the nature of the C++ language. Note that if GetTokenInformation would succeed, the world is really screwed up. There is no need to use the childish goto or to goto Cleanup at all, because, surprise, there is nothing to clean up! To allocate the required buffer space, I simply set the size of the std::vector to be the size I want. Now there is never a need to goto Cleanup to get rid of it because the destructor of std::vector will free the space! // Get required buffer size and allocate the TOKEN_GROUPS buffer. if (!GetTokenInformation( hToken, // handle to the access token TokenGroups, // get information about the token's groups (LPVOID) ptg, // pointer to TOKEN_GROUPS buffer 0, // size of buffer &dwLength // receives required buffer size )) if (GetLastError() != ERROR_INSUFFICIENT_BUFFER) goto Cleanup; ptg = (PTOKEN_GROUPS)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, dwLength); if (ptg == NULL) goto Cleanup; if (!::GetTokenInformation( hToken, // handle to the access token TokenGroups, // get information about the token's groups NULL, // buffer pointer (ignored) 0, // size of buffer &dwLength // receives required buffer size )) /* allocate buffer */ if (GetLastError() != ERROR_INSUFFICIENT_BUFFER) return FALSE; tg.resize(dwLength); /* allocate buffer */ else /* nominally impossible */ return FALSE; /* nominally impossible */ In the code below, I obtain a pointer to the buffer. If the operation fails, I can simply return FALSE and don't need the childish goto. In pure C, this could be handled with _try/_finally or simply by allocating in a function outside, and calling a second function that produced the result; the calling function will always delete any dynamically-allocated storage when the function it calls returns. You can always spot a programmer too lazy to write a second function because of how they use the goto. But this code is allegedly C++, and it should be written in C++. // Get the token group information from the access token. if (!GetTokenInformation( hToken, // handle to the access token TokenGroups, // get information about the token's groups (LPVOID) ptg, // pointer to TOKEN_GROUPS buffer dwLength, // size of buffer &dwLength // receives required buffer size )) goto Cleanup; // Get the token group information from the access token. if (!::GetTokenInformation( hToken, // handle to the access token TokenGroups, // get information about the token's groups (LPVOID) &tg[0], // pointer to TOKEN_GROUPS buffer dwLength, // size of buffer &dwLength // receives required buffer size )) return FALSE; In the original code, the DWORD dwIndex was declared at the top of the block, as if it were 1975 PDP-11 code. This, however, is C++. A variable should not be declared until it is needed, and in the case of a loop index, if it is not needed outside the loop construct, it should be declared within the for-loop itself.Since I'm actually writing in C++, instead of PDP-11 C, I actually use genuine C++ constructs. There seemed to be no reason to use a pointer which might be NULL when I could declare a reference parameter, and there seemed to be no reason to use primitive allocation (such as the silly HeapAlloc calls) when working in C++, so I put all the smarts, including how to do a copy, in the class. I sort of took the idea of writing the code in C++ seriously as opposed to being noise words. // Loop through the groups to find the logon SID. for (dwIndex = 0; dwIndex GroupCount; dwIndex++) if ((ptg->Groups[dwIndex].Attributes & SE_GROUP_LOGON_ID) == SE_GROUP_LOGON_ID) // Found the logon SID; make a copy of it. dwLength = GetLengthSid(ptg->Groups[dwIndex].Sid); *ppsid = (PSID) HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, dwLength); if (*ppsid == NULL) goto Cleanup; if (!CopySid(dwLength, *ppsid, ptg->Groups[dwIndex].Sid)) HeapFree(GetProcessHeap(), 0, (LPVOID)*ppsid); goto Cleanup; break; bSuccess = TRUE;Cleanup: // Free the buffer for the token groups. if (ptg != NULL) HeapFree(GetProcessHeap(), 0, (LPVOID)ptg); return bSuccess; // Loop through the groups to find the logon SID. PTOKEN_GROUPS ptg = (PTOKEN_GROUPS)&tg[0]; BOOL result = FALSE; for (DWORD dwIndex = 0; dwIndex GroupCount; dwIndex++) /* scan tokens */ if ((ptg->Groups[dwIndex].Attributes & SE_GROUP_LOGON_ID) == SE_GROUP_LOGON_ID) /* logon SID */ // Found the logon SID; make a copy of it. if(!sid.CopySid(ptg->Groups[dwIndex].Sid)) return FALSE; result = TRUE; break; /* logon SID */ /* scan tokens */ return result; There are serious questions here about the competence of the programmer who wrote this example. Such as: why is an explicit deallocation required in C++? Why is this apparently written as a separate .cpp file? Why is it using HeapFree instead of delete? The code in the box below illustrates the total amount of code that is required to accomplish this task when it is written competently in C++. #include VOID FreeLogonSID (PSID *ppsid) HeapFree(GetProcessHeap(), 0, (LPVOID)*ppsid); 34 lines of poorly-structured 1975-style C code 01 lines of missing header file === 35 lines of incredibly-poorly-written code reminiscent of bad programming in 1975 C 19 lines of well-structured C++ 18 lines of a generally-useful C++ class ==== 37 lines of well-structured C++ consistent with the concept of "Getting the Logon SID in C++" GetMessage The example which follows this description is nonsensical. The return type is BOOL, and therefore it should be treated as a BOOL value. Saying that a BOOL value can be -1 makes no sense whatsoever. If the return type is int, it should be declared as int and the description should read that the int value can be -1 (error), 0 (quit) or >0 (successful retrieval of a message). It should not involve declaring a BOOL variable and treating it as if it were an int.
Mfc Token Generator V3.1l
DOWNLOAD: https://shoxet.com/2vFf9n
Symptoms:APM uses the 'username' attribute to pass auth token for SSO enabled native RDP resources on macOS. In case Windows policy forces the user to provide credentials, or if Single Sign-on fails, the end user may see a credentials prompt containing the base 64-encoded auth token in the username field.This behavior is observed only with Remote Desktop Client v10.x for macOS. 2ff7e9595c
Comments