summaryrefslogtreecommitdiffstats
path: root/src/ccapi/common/win/OldCC/util.cxx
diff options
context:
space:
mode:
Diffstat (limited to 'src/ccapi/common/win/OldCC/util.cxx')
-rw-r--r--src/ccapi/common/win/OldCC/util.cxx519
1 files changed, 519 insertions, 0 deletions
diff --git a/src/ccapi/common/win/OldCC/util.cxx b/src/ccapi/common/win/OldCC/util.cxx
new file mode 100644
index 0000000000..62b204b927
--- /dev/null
+++ b/src/ccapi/common/win/OldCC/util.cxx
@@ -0,0 +1,519 @@
+/*
+ * $Header$
+ *
+ * Copyright 2008 Massachusetts Institute of Technology.
+ * All Rights Reserved.
+ *
+ * Export of this software from the United States of America may
+ * require a specific license from the United States Government.
+ * It is the responsibility of any person or organization contemplating
+ * export to obtain such a license before exporting.
+ *
+ * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
+ * distribute this software and its documentation for any purpose and
+ * without fee is hereby granted, provided that the above copyright
+ * notice appear in all copies and that both that copyright notice and
+ * this permission notice appear in supporting documentation, and that
+ * the name of M.I.T. not be used in advertising or publicity pertaining
+ * to distribution of the software without specific, written prior
+ * permission. Furthermore if you modify this software you must label
+ * your software as modified software and not distribute it in such a
+ * fashion that it might be confused with the original M.I.T. software.
+ * M.I.T. makes no representations about the suitability of
+ * this software for any purpose. It is provided "as is" without express
+ * or implied warranty.
+ */
+
+#include <windows.h>
+#include <stdio.h> // for _snprintf
+
+#include "util.h"
+#include "secure.hxx"
+
+extern "C" {
+#include "cci_debugging.h"
+#include "ccutils.h"
+ }
+
+
+
+void* malloc_alloc_p(size_t size) {
+ return malloc(size);
+ }
+
+void free_alloc_p(void *pptr) {
+ void **real_pptr = (void**)pptr;
+ if (*real_pptr) {
+ free(*real_pptr);
+ *real_pptr = 0;
+ }
+ }
+
+extern "C" DWORD alloc_textual_sid(
+ PSID pSid, // binary Sid
+ LPSTR *pTextualSid // buffer for Textual representaion of Sid
+ ) {
+ PSID_IDENTIFIER_AUTHORITY psia;
+ DWORD dwSubAuthorities;
+ DWORD dwSidRev = SID_REVISION;
+ DWORD dwCounter;
+ DWORD dwSidSize;
+
+ *pTextualSid = 0;
+
+ //
+ // test if Sid passed in is valid
+ //
+ if(!IsValidSid(pSid)) return ERROR_INVALID_PARAMETER;
+
+ // obtain SidIdentifierAuthority
+ psia = GetSidIdentifierAuthority(pSid);
+
+ // obtain sidsubauthority count
+ dwSubAuthorities =* GetSidSubAuthorityCount(pSid);
+
+ //
+ // compute buffer length
+ // S-SID_REVISION- + identifierauthority- + subauthorities- + NULL
+ //
+ dwSidSize = (15 + 12 + (12 * dwSubAuthorities) + 1) * sizeof(TCHAR);
+ *pTextualSid = (LPSTR)malloc_alloc_p(dwSidSize);
+ if (!*pTextualSid)
+ return GetLastError();
+
+ LPSTR TextualSid = *pTextualSid;
+
+ //
+ // prepare S-SID_REVISION-
+ //
+ wsprintf(TextualSid, TEXT("S-%lu-"), dwSidRev );
+
+ //
+ // prepare SidIdentifierAuthority
+ //
+ if ( (psia->Value[0] != 0) || (psia->Value[1] != 0) )
+ {
+ wsprintf(TextualSid + lstrlen(TextualSid),
+ TEXT("0x%02hx%02hx%02hx%02hx%02hx%02hx"),
+ (USHORT)psia->Value[0],
+ (USHORT)psia->Value[1],
+ (USHORT)psia->Value[2],
+ (USHORT)psia->Value[3],
+ (USHORT)psia->Value[4],
+ (USHORT)psia->Value[5]);
+ }
+ else
+ {
+ wsprintf(TextualSid + lstrlen(TextualSid), TEXT("%lu"),
+ (ULONG)(psia->Value[5] ) +
+ (ULONG)(psia->Value[4] << 8) +
+ (ULONG)(psia->Value[3] << 16) +
+ (ULONG)(psia->Value[2] << 24) );
+ }
+
+ //
+ // loop through SidSubAuthorities
+ //
+ for (dwCounter=0 ; dwCounter < dwSubAuthorities ; dwCounter++)
+ {
+ wsprintf(TextualSid + lstrlen(TextualSid), TEXT("-%lu"),
+ *GetSidSubAuthority(pSid, dwCounter) );
+ }
+ return 0;
+}
+
+DWORD alloc_token_user(HANDLE hToken, PTOKEN_USER *pptu) {
+ DWORD status = 0;
+ DWORD size = 0;
+ *pptu = 0;
+
+ GetTokenInformation(hToken, TokenUser, *pptu, 0, &size);
+ if (size == 0) status = GetLastError();
+
+ if (!status) {
+ if (!(*pptu = (PTOKEN_USER)malloc_alloc_p(size)))
+ status = GetLastError();
+ }
+
+ if (!status) {
+ if (!GetTokenInformation(hToken, TokenUser, *pptu, size, &size))
+ status = GetLastError();
+ }
+
+ if (status && *pptu) {
+ free_alloc_p(pptu);
+ }
+ return status;
+ }
+
+DWORD
+alloc_username(
+ PSID Sid,
+ LPSTR* pname,
+ LPSTR* pdomain = 0
+ )
+{
+ DWORD status = 0;
+ DWORD name_len = 0;
+ DWORD domain_len = 0;
+ SID_NAME_USE snu;
+ LPSTR name = 0;
+ LPSTR domain = 0;
+
+ *pname = 0;
+ if (pdomain) *pdomain = 0;
+
+ LookupAccountSidA(NULL, Sid, 0, &name_len, 0, &domain_len, &snu);
+ if ((name_len == 0) || (domain_len == 0)) status = GetLastError();
+
+ if (!status) {
+ if (!(name = (LPSTR)malloc_alloc_p(name_len))) status = GetLastError();
+ }
+
+ if (!status) {
+ if (!(domain = (LPSTR)malloc_alloc_p(domain_len))) status = GetLastError();
+ }
+
+ if (!status) {
+ if (!LookupAccountSidA(NULL, Sid, name, &name_len, domain, &domain_len, &snu)) status = GetLastError();
+ }
+
+ if (status) {
+ if (name) free_alloc_p(&name);
+ if (domain) free_alloc_p(&domain);
+ }
+ else {
+ if (pdomain) {
+ *pname = name;
+ *pdomain = domain;
+ }
+ else {
+ DWORD size = name_len + domain_len + 1;
+ *pname = (LPSTR)malloc_alloc_p(size);
+ if (!*pname) status = GetLastError();
+ else _snprintf(*pname, size, "%s\\%s", name, domain);
+ }
+ }
+ return status;
+ }
+
+DWORD get_authentication_id(HANDLE hToken, LUID* pAuthId) {
+ TOKEN_STATISTICS ts;
+ DWORD len;
+
+ if (!GetTokenInformation(hToken, TokenStatistics, &ts, sizeof(ts), &len))
+ return GetLastError();
+ *pAuthId = ts.AuthenticationId;
+ return 0;
+ }
+
+DWORD
+alloc_name_9x(
+ LPSTR* pname,
+ LPSTR postfix
+ )
+{
+ char prefix[] = "krbcc";
+ DWORD len = (sizeof(prefix) - 1) + 1 + strlen(postfix) + 1;
+
+ *pname = (LPSTR)malloc_alloc_p(len);
+ if (!*pname) return GetLastError();
+ _snprintf(*pname, len, "%s.%s", prefix, postfix);
+ return 0;
+}
+
+DWORD alloc_name_NT(LPSTR* pname, LPSTR postfix) {
+ DWORD status = 0;
+ HANDLE hToken = 0;
+ LUID auth_id;
+#ifdef _DEBUG
+ PTOKEN_USER ptu = 0;
+ LPSTR name = 0;
+ LPSTR domain = 0;
+ LPSTR sid = 0;
+#endif
+ char prefix[] = "krbcc";
+ // Play it safe and say 3 characters are needed per 8 bits (byte).
+ // Note that 20 characters are needed for a 64-bit number in
+ // decimal (plus one for the string termination.
+ // and include room for sessionId.
+ char lid[3*sizeof(LUID)+1+5];
+ DWORD sessionId;
+ DWORD len = 0;
+
+ *pname = 0;
+
+ status = SecureClient::Token(hToken);
+
+ if (!status) {
+ status = get_authentication_id(hToken, &auth_id);
+ }
+
+ if (!status) {
+ if (!ProcessIdToSessionId(GetCurrentProcessId(), &sessionId))
+ sessionId = 0;
+ }
+
+#ifdef _DEBUG
+ if (!status) {status = alloc_token_user(hToken, &ptu);}
+ if (!status) {status = alloc_username(ptu->User.Sid, &name, &domain);}
+ if (!status) {status = alloc_textual_sid(ptu->User.Sid, &sid);}
+#endif
+
+ if (!status) {
+ _snprintf(lid, sizeof(lid), "%I64u.%u", auth_id, sessionId);
+ lid[sizeof(lid)-1] = 0; // be safe
+
+ len = (sizeof(prefix) - 1) + 1 + strlen(lid) + 1 + strlen(postfix) + 1;
+ *pname = (LPSTR)malloc_alloc_p(len);
+ if (!*pname) status = GetLastError();
+ }
+
+ //
+ // We used to allocate a name of the form:
+ // "prefix.domain.name.sid.lid.postfix" (usually under 80
+ // characters, depending on username). However, XP thought this
+ // was "invalid" (too long?) for some reason.
+ //
+ // Therefore, we now use "prefix.lid.postfix"
+ // and for Terminal server we use "prefix.lid.sessionId.postfix"
+ //
+
+ if (!status) {
+ _snprintf(*pname, len, "%s.%s.%s", prefix, lid, postfix);
+ }
+
+#ifdef _DEBUG
+ if (sid)
+ free_alloc_p(&sid);
+ if (name)
+ free_alloc_p(&name);
+ if (domain)
+ free_alloc_p(&domain);
+ if (ptu)
+ free_alloc_p(&ptu);
+#endif
+ if (hToken && hToken != INVALID_HANDLE_VALUE)
+ CloseHandle(hToken);
+ if (status && *pname)
+ free_alloc_p(pname);
+ return status;
+}
+
+extern "C" DWORD alloc_name(LPSTR* pname, LPSTR postfix, BOOL isNT) {
+ return isNT ? alloc_name_NT(pname, postfix) :
+ alloc_name_9x(pname, postfix);
+ }
+
+extern "C" DWORD alloc_own_security_descriptor_NT(PSECURITY_DESCRIPTOR* ppsd) {
+ DWORD status = 0;
+ HANDLE hToken = 0;
+ PTOKEN_USER ptu = 0;
+ PSID pSid = 0;
+ PACL pAcl = 0;
+ DWORD size = 0;
+ SECURITY_DESCRIPTOR sd;
+
+ *ppsd = 0;
+
+ if (!status) {status = SecureClient::Token(hToken);}
+
+ // Get SID:
+ if (!status) {status = alloc_token_user(hToken, &ptu);}
+
+ if (!status) {
+ size = GetLengthSid(ptu->User.Sid);
+ pSid = (PSID) malloc_alloc_p(size);
+ if (!pSid) status = GetLastError();
+ }
+ if (!status) {
+ if (!CopySid(size, pSid, ptu->User.Sid)) status = GetLastError();
+ }
+
+ if (!status) {
+ // Prepare ACL:
+ size = sizeof(ACL);
+ // Add an ACE:
+ size += sizeof(ACCESS_ALLOWED_ACE) - sizeof(DWORD) + GetLengthSid(pSid);
+ pAcl = (PACL) malloc_alloc_p(size);
+ if (!pAcl) status = GetLastError();
+ }
+
+ if (!status) {
+ if (!InitializeAcl(pAcl, size, ACL_REVISION)) status = GetLastError();
+ }
+
+ if (!status) {
+ if (!AddAccessAllowedAce(pAcl, ACL_REVISION, GENERIC_ALL, pSid)) status = GetLastError();
+ }
+
+ if (!status) {
+ // Prepare SD itself:
+ if (!InitializeSecurityDescriptor(&sd, SECURITY_DESCRIPTOR_REVISION)) status = GetLastError();
+ }
+
+ if (!status) {
+ if (!SetSecurityDescriptorDacl(&sd, TRUE, pAcl, FALSE)) status = GetLastError();
+ }
+
+ if (!status) {
+ if (!SetSecurityDescriptorOwner(&sd, pSid, FALSE)) status = GetLastError();
+ }
+
+ if (!status) {
+ if (!IsValidSecurityDescriptor(&sd)) status = ERROR_INVALID_PARAMETER;
+ }
+
+ if (!status) {
+ // We now have a SD. Let's copy it.
+ {
+ // This should not succeed. Instead it should give us the size.
+ BOOL ok = MakeSelfRelativeSD(&sd, 0, &size);
+ }
+ if (size == 0) status = GetLastError();
+ }
+
+ if (!status) {
+ *ppsd = (PSECURITY_DESCRIPTOR) malloc_alloc_p(size);
+ if (!*ppsd) status = GetLastError();
+ }
+
+ if (!status) {
+ if (!MakeSelfRelativeSD(&sd, *ppsd, &size)) status = GetLastError();
+ }
+
+ if (ptu) free_alloc_p(&ptu);
+ if (pSid) free_alloc_p(&pSid);
+ if (pAcl) free_alloc_p(&pAcl);
+ if (hToken && hToken != INVALID_HANDLE_VALUE) CloseHandle(hToken);
+ if (status && *ppsd) free_alloc_p(ppsd);
+ return status;
+}
+
+DWORD
+alloc_module_file_name(
+ char* module,
+ char** pname
+ )
+{
+ const DWORD max = 8192;
+ DWORD status = 0;
+ DWORD got = 0;
+ DWORD size = 512; // use low number to test...
+ HMODULE h = 0;
+ BOOL ok = FALSE;
+ char* name = 0;
+
+ if (!pname)
+ return ERROR_INVALID_PARAMETER;
+ *pname = 0;
+
+ h = GetModuleHandle(module);
+
+ if (!h) return GetLastError();
+
+ // We assume size < max and size > 0
+ while (!status && !ok) {
+ if (size > max) {
+ // XXX - Assert?
+ status = ERROR_INVALID_DATA;
+ continue;
+ }
+ if (name) free_alloc_p(&name);
+ name = (char*)malloc_alloc_p(size + 1);
+ if (!name) {
+ status = ERROR_NOT_ENOUGH_MEMORY;
+ continue;
+ }
+ name[size] = 0;
+ got = GetModuleFileName(h, name, size);
+ if (!got) {
+ status = GetLastError();
+ // sanity check:
+ if (!status) {
+ // XXX - print nasty message...assert?
+ status = ERROR_INVALID_DATA;
+ }
+ continue;
+ }
+ // To know we're ok, we need to verify that what we got
+ // was bigger than GetModuleSize thought it got.
+ ok = got && (got < size) && !name[got];
+ size *= 2;
+ }
+ if (status && name)
+ free_alloc_p(&name);
+ else
+ *pname = name;
+ return status;
+}
+
+DWORD
+alloc_module_dir_name(
+ char* module,
+ char** pname
+ )
+{
+ DWORD status = alloc_module_file_name(module, pname);
+ if (!status) {
+ char* name = *pname;
+ char* p = name + strlen(name);
+ while ((p >= name) && (*p != '\\') && (*p != '/')) p--;
+ if (p < name) {
+ free_alloc_p(pname);
+ status = ERROR_INVALID_DATA;
+ } else {
+ *p = 0;
+ }
+ }
+ return status;
+}
+
+DWORD
+alloc_module_dir_name_with_file(
+ char* module,
+ char* file,
+ char** pname
+ )
+{
+ DWORD status = alloc_module_dir_name(module, pname);
+ if (!status) {
+ char* name = *pname;
+ size_t name_size = strlen(name);
+ size_t size = name_size + 1 + strlen(file) + 1;
+ char* result = (char*)malloc_alloc_p(size);
+ if (!result) {
+ status = ERROR_NOT_ENOUGH_MEMORY;
+ free_alloc_p(pname);
+ } else {
+ strcpy(result, name);
+ result[name_size] = '\\';
+ strcpy(result + name_size + 1, file);
+ free_alloc_p(pname);
+ *pname = result;
+ }
+ }
+ return status;
+}
+
+DWORD alloc_cmdline_2_args(char* prog,
+ char* arg1,
+ char* arg2,
+ char** pname) {
+ DWORD status = 0;
+ size_t size = strlen(prog) + strlen(arg1) + strlen(arg2) + 4;
+ char* result = (char*)malloc_alloc_p(size);
+ if (!result) {
+ status = ERROR_NOT_ENOUGH_MEMORY;
+ }
+ else {
+ strcpy(result, prog);
+ strcat(result, " ");
+ strcat(result, arg1);
+ strcat(result, " ");
+ strcat(result, arg2);
+ *pname = result;
+ }
+ cci_debug_printf("%s made <%s>", __FUNCTION__, result);
+ return status;
+ }