1*7f2fe78bSCy Schubert /*
2*7f2fe78bSCy Schubert * $Header$
3*7f2fe78bSCy Schubert *
4*7f2fe78bSCy Schubert * Copyright 2008 Massachusetts Institute of Technology.
5*7f2fe78bSCy Schubert * All Rights Reserved.
6*7f2fe78bSCy Schubert *
7*7f2fe78bSCy Schubert * Export of this software from the United States of America may
8*7f2fe78bSCy Schubert * require a specific license from the United States Government.
9*7f2fe78bSCy Schubert * It is the responsibility of any person or organization contemplating
10*7f2fe78bSCy Schubert * export to obtain such a license before exporting.
11*7f2fe78bSCy Schubert *
12*7f2fe78bSCy Schubert * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
13*7f2fe78bSCy Schubert * distribute this software and its documentation for any purpose and
14*7f2fe78bSCy Schubert * without fee is hereby granted, provided that the above copyright
15*7f2fe78bSCy Schubert * notice appear in all copies and that both that copyright notice and
16*7f2fe78bSCy Schubert * this permission notice appear in supporting documentation, and that
17*7f2fe78bSCy Schubert * the name of M.I.T. not be used in advertising or publicity pertaining
18*7f2fe78bSCy Schubert * to distribution of the software without specific, written prior
19*7f2fe78bSCy Schubert * permission. Furthermore if you modify this software you must label
20*7f2fe78bSCy Schubert * your software as modified software and not distribute it in such a
21*7f2fe78bSCy Schubert * fashion that it might be confused with the original M.I.T. software.
22*7f2fe78bSCy Schubert * M.I.T. makes no representations about the suitability of
23*7f2fe78bSCy Schubert * this software for any purpose. It is provided "as is" without express
24*7f2fe78bSCy Schubert * or implied warranty.
25*7f2fe78bSCy Schubert */
26*7f2fe78bSCy Schubert
27*7f2fe78bSCy Schubert #include <windows.h>
28*7f2fe78bSCy Schubert #include <stdio.h> // for _snprintf
29*7f2fe78bSCy Schubert #include <malloc.h>
30*7f2fe78bSCy Schubert #include <stdlib.h>
31*7f2fe78bSCy Schubert
32*7f2fe78bSCy Schubert extern "C" {
33*7f2fe78bSCy Schubert #include "cci_debugging.h"
34*7f2fe78bSCy Schubert #include "ccutils.h"
35*7f2fe78bSCy Schubert }
36*7f2fe78bSCy Schubert
37*7f2fe78bSCy Schubert #include "util.h"
38*7f2fe78bSCy Schubert #include "secure.hxx"
39*7f2fe78bSCy Schubert
40*7f2fe78bSCy Schubert
malloc_alloc_p(size_t size)41*7f2fe78bSCy Schubert void* malloc_alloc_p(size_t size) {
42*7f2fe78bSCy Schubert return malloc(size);
43*7f2fe78bSCy Schubert }
44*7f2fe78bSCy Schubert
free_alloc_p(void * pptr)45*7f2fe78bSCy Schubert void free_alloc_p(void *pptr) {
46*7f2fe78bSCy Schubert void **real_pptr = (void**)pptr;
47*7f2fe78bSCy Schubert if (*real_pptr) {
48*7f2fe78bSCy Schubert free(*real_pptr);
49*7f2fe78bSCy Schubert *real_pptr = 0;
50*7f2fe78bSCy Schubert }
51*7f2fe78bSCy Schubert }
52*7f2fe78bSCy Schubert
alloc_textual_sid(PSID pSid,LPSTR * pTextualSid)53*7f2fe78bSCy Schubert extern "C" DWORD alloc_textual_sid(
54*7f2fe78bSCy Schubert PSID pSid, // binary Sid
55*7f2fe78bSCy Schubert LPSTR *pTextualSid // buffer for Textual representation of Sid
56*7f2fe78bSCy Schubert ) {
57*7f2fe78bSCy Schubert PSID_IDENTIFIER_AUTHORITY psia;
58*7f2fe78bSCy Schubert DWORD dwSubAuthorities;
59*7f2fe78bSCy Schubert DWORD dwSidRev = SID_REVISION;
60*7f2fe78bSCy Schubert DWORD dwCounter;
61*7f2fe78bSCy Schubert DWORD dwSidSize;
62*7f2fe78bSCy Schubert
63*7f2fe78bSCy Schubert *pTextualSid = 0;
64*7f2fe78bSCy Schubert
65*7f2fe78bSCy Schubert //
66*7f2fe78bSCy Schubert // test if Sid passed in is valid
67*7f2fe78bSCy Schubert //
68*7f2fe78bSCy Schubert if(!IsValidSid(pSid)) return ERROR_INVALID_PARAMETER;
69*7f2fe78bSCy Schubert
70*7f2fe78bSCy Schubert // obtain SidIdentifierAuthority
71*7f2fe78bSCy Schubert psia = GetSidIdentifierAuthority(pSid);
72*7f2fe78bSCy Schubert
73*7f2fe78bSCy Schubert // obtain sidsubauthority count
74*7f2fe78bSCy Schubert dwSubAuthorities =* GetSidSubAuthorityCount(pSid);
75*7f2fe78bSCy Schubert
76*7f2fe78bSCy Schubert //
77*7f2fe78bSCy Schubert // compute buffer length
78*7f2fe78bSCy Schubert // S-SID_REVISION- + identifierauthority- + subauthorities- + NULL
79*7f2fe78bSCy Schubert //
80*7f2fe78bSCy Schubert dwSidSize = (15 + 12 + (12 * dwSubAuthorities) + 1) * sizeof(TCHAR);
81*7f2fe78bSCy Schubert *pTextualSid = (LPSTR)malloc_alloc_p(dwSidSize);
82*7f2fe78bSCy Schubert if (!*pTextualSid)
83*7f2fe78bSCy Schubert return GetLastError();
84*7f2fe78bSCy Schubert
85*7f2fe78bSCy Schubert LPSTR TextualSid = *pTextualSid;
86*7f2fe78bSCy Schubert
87*7f2fe78bSCy Schubert //
88*7f2fe78bSCy Schubert // prepare S-SID_REVISION-
89*7f2fe78bSCy Schubert //
90*7f2fe78bSCy Schubert wsprintf(TextualSid, TEXT("S-%lu-"), dwSidRev );
91*7f2fe78bSCy Schubert
92*7f2fe78bSCy Schubert //
93*7f2fe78bSCy Schubert // prepare SidIdentifierAuthority
94*7f2fe78bSCy Schubert //
95*7f2fe78bSCy Schubert if ( (psia->Value[0] != 0) || (psia->Value[1] != 0) )
96*7f2fe78bSCy Schubert {
97*7f2fe78bSCy Schubert wsprintf(TextualSid + lstrlen(TextualSid),
98*7f2fe78bSCy Schubert TEXT("0x%02hx%02hx%02hx%02hx%02hx%02hx"),
99*7f2fe78bSCy Schubert (USHORT)psia->Value[0],
100*7f2fe78bSCy Schubert (USHORT)psia->Value[1],
101*7f2fe78bSCy Schubert (USHORT)psia->Value[2],
102*7f2fe78bSCy Schubert (USHORT)psia->Value[3],
103*7f2fe78bSCy Schubert (USHORT)psia->Value[4],
104*7f2fe78bSCy Schubert (USHORT)psia->Value[5]);
105*7f2fe78bSCy Schubert }
106*7f2fe78bSCy Schubert else
107*7f2fe78bSCy Schubert {
108*7f2fe78bSCy Schubert wsprintf(TextualSid + lstrlen(TextualSid), TEXT("%lu"),
109*7f2fe78bSCy Schubert (ULONG)(psia->Value[5] ) +
110*7f2fe78bSCy Schubert (ULONG)(psia->Value[4] << 8) +
111*7f2fe78bSCy Schubert (ULONG)(psia->Value[3] << 16) +
112*7f2fe78bSCy Schubert (ULONG)(psia->Value[2] << 24) );
113*7f2fe78bSCy Schubert }
114*7f2fe78bSCy Schubert
115*7f2fe78bSCy Schubert //
116*7f2fe78bSCy Schubert // loop through SidSubAuthorities
117*7f2fe78bSCy Schubert //
118*7f2fe78bSCy Schubert for (dwCounter=0 ; dwCounter < dwSubAuthorities ; dwCounter++)
119*7f2fe78bSCy Schubert {
120*7f2fe78bSCy Schubert wsprintf(TextualSid + lstrlen(TextualSid), TEXT("-%lu"),
121*7f2fe78bSCy Schubert *GetSidSubAuthority(pSid, dwCounter) );
122*7f2fe78bSCy Schubert }
123*7f2fe78bSCy Schubert return 0;
124*7f2fe78bSCy Schubert }
125*7f2fe78bSCy Schubert
alloc_token_user(HANDLE hToken,PTOKEN_USER * pptu)126*7f2fe78bSCy Schubert DWORD alloc_token_user(HANDLE hToken, PTOKEN_USER *pptu) {
127*7f2fe78bSCy Schubert DWORD status = 0;
128*7f2fe78bSCy Schubert DWORD size = 0;
129*7f2fe78bSCy Schubert *pptu = 0;
130*7f2fe78bSCy Schubert
131*7f2fe78bSCy Schubert GetTokenInformation(hToken, TokenUser, *pptu, 0, &size);
132*7f2fe78bSCy Schubert if (size == 0) status = GetLastError();
133*7f2fe78bSCy Schubert
134*7f2fe78bSCy Schubert if (!status) {
135*7f2fe78bSCy Schubert if (!(*pptu = (PTOKEN_USER)malloc_alloc_p(size)))
136*7f2fe78bSCy Schubert status = GetLastError();
137*7f2fe78bSCy Schubert }
138*7f2fe78bSCy Schubert
139*7f2fe78bSCy Schubert if (!status) {
140*7f2fe78bSCy Schubert if (!GetTokenInformation(hToken, TokenUser, *pptu, size, &size))
141*7f2fe78bSCy Schubert status = GetLastError();
142*7f2fe78bSCy Schubert }
143*7f2fe78bSCy Schubert
144*7f2fe78bSCy Schubert if (status && *pptu) {
145*7f2fe78bSCy Schubert free_alloc_p(pptu);
146*7f2fe78bSCy Schubert }
147*7f2fe78bSCy Schubert return status;
148*7f2fe78bSCy Schubert }
149*7f2fe78bSCy Schubert
150*7f2fe78bSCy Schubert DWORD
alloc_username(PSID Sid,LPSTR * pname,LPSTR * pdomain=0)151*7f2fe78bSCy Schubert alloc_username(
152*7f2fe78bSCy Schubert PSID Sid,
153*7f2fe78bSCy Schubert LPSTR* pname,
154*7f2fe78bSCy Schubert LPSTR* pdomain = 0
155*7f2fe78bSCy Schubert )
156*7f2fe78bSCy Schubert {
157*7f2fe78bSCy Schubert DWORD status = 0;
158*7f2fe78bSCy Schubert DWORD name_len = 0;
159*7f2fe78bSCy Schubert DWORD domain_len = 0;
160*7f2fe78bSCy Schubert SID_NAME_USE snu;
161*7f2fe78bSCy Schubert LPSTR name = 0;
162*7f2fe78bSCy Schubert LPSTR domain = 0;
163*7f2fe78bSCy Schubert
164*7f2fe78bSCy Schubert *pname = 0;
165*7f2fe78bSCy Schubert if (pdomain) *pdomain = 0;
166*7f2fe78bSCy Schubert
167*7f2fe78bSCy Schubert LookupAccountSidA(NULL, Sid, 0, &name_len, 0, &domain_len, &snu);
168*7f2fe78bSCy Schubert if ((name_len == 0) || (domain_len == 0)) status = GetLastError();
169*7f2fe78bSCy Schubert
170*7f2fe78bSCy Schubert if (!status) {
171*7f2fe78bSCy Schubert if (!(name = (LPSTR)malloc_alloc_p(name_len))) status = GetLastError();
172*7f2fe78bSCy Schubert }
173*7f2fe78bSCy Schubert
174*7f2fe78bSCy Schubert if (!status) {
175*7f2fe78bSCy Schubert if (!(domain = (LPSTR)malloc_alloc_p(domain_len))) status = GetLastError();
176*7f2fe78bSCy Schubert }
177*7f2fe78bSCy Schubert
178*7f2fe78bSCy Schubert if (!status) {
179*7f2fe78bSCy Schubert if (!LookupAccountSidA(NULL, Sid, name, &name_len, domain, &domain_len, &snu)) status = GetLastError();
180*7f2fe78bSCy Schubert }
181*7f2fe78bSCy Schubert
182*7f2fe78bSCy Schubert if (status) {
183*7f2fe78bSCy Schubert if (name) free_alloc_p(&name);
184*7f2fe78bSCy Schubert if (domain) free_alloc_p(&domain);
185*7f2fe78bSCy Schubert }
186*7f2fe78bSCy Schubert else {
187*7f2fe78bSCy Schubert if (pdomain) {
188*7f2fe78bSCy Schubert *pname = name;
189*7f2fe78bSCy Schubert *pdomain = domain;
190*7f2fe78bSCy Schubert }
191*7f2fe78bSCy Schubert else {
192*7f2fe78bSCy Schubert DWORD size = name_len + domain_len + 1;
193*7f2fe78bSCy Schubert *pname = (LPSTR)malloc_alloc_p(size);
194*7f2fe78bSCy Schubert if (!*pname) status = GetLastError();
195*7f2fe78bSCy Schubert else _snprintf(*pname, size, "%s\\%s", name, domain);
196*7f2fe78bSCy Schubert }
197*7f2fe78bSCy Schubert }
198*7f2fe78bSCy Schubert return status;
199*7f2fe78bSCy Schubert }
200*7f2fe78bSCy Schubert
get_authentication_id(HANDLE hToken,LUID * pAuthId)201*7f2fe78bSCy Schubert DWORD get_authentication_id(HANDLE hToken, LUID* pAuthId) {
202*7f2fe78bSCy Schubert TOKEN_STATISTICS ts;
203*7f2fe78bSCy Schubert DWORD len;
204*7f2fe78bSCy Schubert
205*7f2fe78bSCy Schubert if (!GetTokenInformation(hToken, TokenStatistics, &ts, sizeof(ts), &len))
206*7f2fe78bSCy Schubert return GetLastError();
207*7f2fe78bSCy Schubert *pAuthId = ts.AuthenticationId;
208*7f2fe78bSCy Schubert return 0;
209*7f2fe78bSCy Schubert }
210*7f2fe78bSCy Schubert
211*7f2fe78bSCy Schubert DWORD
alloc_name_9x(LPSTR * pname,LPSTR postfix)212*7f2fe78bSCy Schubert alloc_name_9x(
213*7f2fe78bSCy Schubert LPSTR* pname,
214*7f2fe78bSCy Schubert LPSTR postfix
215*7f2fe78bSCy Schubert )
216*7f2fe78bSCy Schubert {
217*7f2fe78bSCy Schubert char prefix[] = "krbcc";
218*7f2fe78bSCy Schubert DWORD len = (sizeof(prefix) - 1) + 1 + strlen(postfix) + 1;
219*7f2fe78bSCy Schubert
220*7f2fe78bSCy Schubert *pname = (LPSTR)malloc_alloc_p(len);
221*7f2fe78bSCy Schubert if (!*pname) return GetLastError();
222*7f2fe78bSCy Schubert _snprintf(*pname, len, "%s.%s", prefix, postfix);
223*7f2fe78bSCy Schubert return 0;
224*7f2fe78bSCy Schubert }
225*7f2fe78bSCy Schubert
alloc_name_NT(LPSTR * pname,LPSTR postfix)226*7f2fe78bSCy Schubert DWORD alloc_name_NT(LPSTR* pname, LPSTR postfix) {
227*7f2fe78bSCy Schubert DWORD status = 0;
228*7f2fe78bSCy Schubert HANDLE hToken = 0;
229*7f2fe78bSCy Schubert LUID auth_id;
230*7f2fe78bSCy Schubert #ifdef _DEBUG
231*7f2fe78bSCy Schubert PTOKEN_USER ptu = 0;
232*7f2fe78bSCy Schubert LPSTR name = 0;
233*7f2fe78bSCy Schubert LPSTR domain = 0;
234*7f2fe78bSCy Schubert LPSTR sid = 0;
235*7f2fe78bSCy Schubert #endif
236*7f2fe78bSCy Schubert char prefix[] = "krbcc";
237*7f2fe78bSCy Schubert // Play it safe and say 3 characters are needed per 8 bits (byte).
238*7f2fe78bSCy Schubert // Note that 20 characters are needed for a 64-bit number in
239*7f2fe78bSCy Schubert // decimal (plus one for the string termination.
240*7f2fe78bSCy Schubert // and include room for sessionId.
241*7f2fe78bSCy Schubert char lid[3*sizeof(LUID)+1+5];
242*7f2fe78bSCy Schubert DWORD sessionId;
243*7f2fe78bSCy Schubert DWORD len = 0;
244*7f2fe78bSCy Schubert
245*7f2fe78bSCy Schubert *pname = 0;
246*7f2fe78bSCy Schubert
247*7f2fe78bSCy Schubert status = SecureClient::Token(hToken);
248*7f2fe78bSCy Schubert
249*7f2fe78bSCy Schubert if (!status) {
250*7f2fe78bSCy Schubert status = get_authentication_id(hToken, &auth_id);
251*7f2fe78bSCy Schubert }
252*7f2fe78bSCy Schubert
253*7f2fe78bSCy Schubert if (!status) {
254*7f2fe78bSCy Schubert if (!ProcessIdToSessionId(GetCurrentProcessId(), &sessionId))
255*7f2fe78bSCy Schubert sessionId = 0;
256*7f2fe78bSCy Schubert }
257*7f2fe78bSCy Schubert
258*7f2fe78bSCy Schubert #ifdef _DEBUG
259*7f2fe78bSCy Schubert if (!status) {status = alloc_token_user(hToken, &ptu);}
260*7f2fe78bSCy Schubert if (!status) {status = alloc_username(ptu->User.Sid, &name, &domain);}
261*7f2fe78bSCy Schubert if (!status) {status = alloc_textual_sid(ptu->User.Sid, &sid);}
262*7f2fe78bSCy Schubert #endif
263*7f2fe78bSCy Schubert
264*7f2fe78bSCy Schubert if (!status) {
265*7f2fe78bSCy Schubert _snprintf(lid, sizeof(lid), "%I64u.%u", auth_id, sessionId);
266*7f2fe78bSCy Schubert lid[sizeof(lid)-1] = 0; // be safe
267*7f2fe78bSCy Schubert
268*7f2fe78bSCy Schubert len = (sizeof(prefix) - 1) + 1 + strlen(lid) + 1 + strlen(postfix) + 1;
269*7f2fe78bSCy Schubert *pname = (LPSTR)malloc_alloc_p(len);
270*7f2fe78bSCy Schubert if (!*pname) status = GetLastError();
271*7f2fe78bSCy Schubert }
272*7f2fe78bSCy Schubert
273*7f2fe78bSCy Schubert //
274*7f2fe78bSCy Schubert // We used to allocate a name of the form:
275*7f2fe78bSCy Schubert // "prefix.domain.name.sid.lid.postfix" (usually under 80
276*7f2fe78bSCy Schubert // characters, depending on username). However, XP thought this
277*7f2fe78bSCy Schubert // was "invalid" (too long?) for some reason.
278*7f2fe78bSCy Schubert //
279*7f2fe78bSCy Schubert // Therefore, we now use "prefix.lid.postfix"
280*7f2fe78bSCy Schubert // and for Terminal server we use "prefix.lid.sessionId.postfix"
281*7f2fe78bSCy Schubert //
282*7f2fe78bSCy Schubert
283*7f2fe78bSCy Schubert if (!status) {
284*7f2fe78bSCy Schubert _snprintf(*pname, len, "%s.%s.%s", prefix, lid, postfix);
285*7f2fe78bSCy Schubert }
286*7f2fe78bSCy Schubert
287*7f2fe78bSCy Schubert #ifdef _DEBUG
288*7f2fe78bSCy Schubert if (sid)
289*7f2fe78bSCy Schubert free_alloc_p(&sid);
290*7f2fe78bSCy Schubert if (name)
291*7f2fe78bSCy Schubert free_alloc_p(&name);
292*7f2fe78bSCy Schubert if (domain)
293*7f2fe78bSCy Schubert free_alloc_p(&domain);
294*7f2fe78bSCy Schubert if (ptu)
295*7f2fe78bSCy Schubert free_alloc_p(&ptu);
296*7f2fe78bSCy Schubert #endif
297*7f2fe78bSCy Schubert if (hToken && hToken != INVALID_HANDLE_VALUE)
298*7f2fe78bSCy Schubert CloseHandle(hToken);
299*7f2fe78bSCy Schubert if (status && *pname)
300*7f2fe78bSCy Schubert free_alloc_p(pname);
301*7f2fe78bSCy Schubert return status;
302*7f2fe78bSCy Schubert }
303*7f2fe78bSCy Schubert
alloc_name(LPSTR * pname,LPSTR postfix,BOOL isNT)304*7f2fe78bSCy Schubert extern "C" DWORD alloc_name(LPSTR* pname, LPSTR postfix, BOOL isNT) {
305*7f2fe78bSCy Schubert return isNT ? alloc_name_NT(pname, postfix) :
306*7f2fe78bSCy Schubert alloc_name_9x(pname, postfix);
307*7f2fe78bSCy Schubert }
308*7f2fe78bSCy Schubert
alloc_own_security_descriptor_NT(PSECURITY_DESCRIPTOR * ppsd)309*7f2fe78bSCy Schubert extern "C" DWORD alloc_own_security_descriptor_NT(PSECURITY_DESCRIPTOR* ppsd) {
310*7f2fe78bSCy Schubert DWORD status = 0;
311*7f2fe78bSCy Schubert HANDLE hToken = 0;
312*7f2fe78bSCy Schubert PTOKEN_USER ptu = 0;
313*7f2fe78bSCy Schubert PSID pSid = 0;
314*7f2fe78bSCy Schubert PACL pAcl = 0;
315*7f2fe78bSCy Schubert DWORD size = 0;
316*7f2fe78bSCy Schubert SECURITY_DESCRIPTOR sd;
317*7f2fe78bSCy Schubert
318*7f2fe78bSCy Schubert *ppsd = 0;
319*7f2fe78bSCy Schubert
320*7f2fe78bSCy Schubert if (!status) {status = SecureClient::Token(hToken);}
321*7f2fe78bSCy Schubert
322*7f2fe78bSCy Schubert // Get SID:
323*7f2fe78bSCy Schubert if (!status) {status = alloc_token_user(hToken, &ptu);}
324*7f2fe78bSCy Schubert
325*7f2fe78bSCy Schubert if (!status) {
326*7f2fe78bSCy Schubert size = GetLengthSid(ptu->User.Sid);
327*7f2fe78bSCy Schubert pSid = (PSID) malloc_alloc_p(size);
328*7f2fe78bSCy Schubert if (!pSid) status = GetLastError();
329*7f2fe78bSCy Schubert }
330*7f2fe78bSCy Schubert if (!status) {
331*7f2fe78bSCy Schubert if (!CopySid(size, pSid, ptu->User.Sid)) status = GetLastError();
332*7f2fe78bSCy Schubert }
333*7f2fe78bSCy Schubert
334*7f2fe78bSCy Schubert if (!status) {
335*7f2fe78bSCy Schubert // Prepare ACL:
336*7f2fe78bSCy Schubert size = sizeof(ACL);
337*7f2fe78bSCy Schubert // Add an ACE:
338*7f2fe78bSCy Schubert size += sizeof(ACCESS_ALLOWED_ACE) - sizeof(DWORD) + GetLengthSid(pSid);
339*7f2fe78bSCy Schubert pAcl = (PACL) malloc_alloc_p(size);
340*7f2fe78bSCy Schubert if (!pAcl) status = GetLastError();
341*7f2fe78bSCy Schubert }
342*7f2fe78bSCy Schubert
343*7f2fe78bSCy Schubert if (!status) {
344*7f2fe78bSCy Schubert if (!InitializeAcl(pAcl, size, ACL_REVISION)) status = GetLastError();
345*7f2fe78bSCy Schubert }
346*7f2fe78bSCy Schubert
347*7f2fe78bSCy Schubert if (!status) {
348*7f2fe78bSCy Schubert if (!AddAccessAllowedAce(pAcl, ACL_REVISION, GENERIC_ALL, pSid)) status = GetLastError();
349*7f2fe78bSCy Schubert }
350*7f2fe78bSCy Schubert
351*7f2fe78bSCy Schubert if (!status) {
352*7f2fe78bSCy Schubert // Prepare SD itself:
353*7f2fe78bSCy Schubert if (!InitializeSecurityDescriptor(&sd, SECURITY_DESCRIPTOR_REVISION)) status = GetLastError();
354*7f2fe78bSCy Schubert }
355*7f2fe78bSCy Schubert
356*7f2fe78bSCy Schubert if (!status) {
357*7f2fe78bSCy Schubert if (!SetSecurityDescriptorDacl(&sd, TRUE, pAcl, FALSE)) status = GetLastError();
358*7f2fe78bSCy Schubert }
359*7f2fe78bSCy Schubert
360*7f2fe78bSCy Schubert if (!status) {
361*7f2fe78bSCy Schubert if (!SetSecurityDescriptorOwner(&sd, pSid, FALSE)) status = GetLastError();
362*7f2fe78bSCy Schubert }
363*7f2fe78bSCy Schubert
364*7f2fe78bSCy Schubert if (!status) {
365*7f2fe78bSCy Schubert if (!IsValidSecurityDescriptor(&sd)) status = ERROR_INVALID_PARAMETER;
366*7f2fe78bSCy Schubert }
367*7f2fe78bSCy Schubert
368*7f2fe78bSCy Schubert if (!status) {
369*7f2fe78bSCy Schubert // We now have a SD. Let's copy it.
370*7f2fe78bSCy Schubert {
371*7f2fe78bSCy Schubert // This should not succeed. Instead it should give us the size.
372*7f2fe78bSCy Schubert BOOL ok = MakeSelfRelativeSD(&sd, 0, &size);
373*7f2fe78bSCy Schubert }
374*7f2fe78bSCy Schubert if (size == 0) status = GetLastError();
375*7f2fe78bSCy Schubert }
376*7f2fe78bSCy Schubert
377*7f2fe78bSCy Schubert if (!status) {
378*7f2fe78bSCy Schubert *ppsd = (PSECURITY_DESCRIPTOR) malloc_alloc_p(size);
379*7f2fe78bSCy Schubert if (!*ppsd) status = GetLastError();
380*7f2fe78bSCy Schubert }
381*7f2fe78bSCy Schubert
382*7f2fe78bSCy Schubert if (!status) {
383*7f2fe78bSCy Schubert if (!MakeSelfRelativeSD(&sd, *ppsd, &size)) status = GetLastError();
384*7f2fe78bSCy Schubert }
385*7f2fe78bSCy Schubert
386*7f2fe78bSCy Schubert if (ptu) free_alloc_p(&ptu);
387*7f2fe78bSCy Schubert if (pSid) free_alloc_p(&pSid);
388*7f2fe78bSCy Schubert if (pAcl) free_alloc_p(&pAcl);
389*7f2fe78bSCy Schubert if (hToken && hToken != INVALID_HANDLE_VALUE) CloseHandle(hToken);
390*7f2fe78bSCy Schubert if (status && *ppsd) free_alloc_p(ppsd);
391*7f2fe78bSCy Schubert return status;
392*7f2fe78bSCy Schubert }
393*7f2fe78bSCy Schubert
394*7f2fe78bSCy Schubert DWORD
alloc_module_file_name(char * module,char ** pname)395*7f2fe78bSCy Schubert alloc_module_file_name(
396*7f2fe78bSCy Schubert char* module,
397*7f2fe78bSCy Schubert char** pname
398*7f2fe78bSCy Schubert )
399*7f2fe78bSCy Schubert {
400*7f2fe78bSCy Schubert const DWORD max = 8192;
401*7f2fe78bSCy Schubert DWORD status = 0;
402*7f2fe78bSCy Schubert DWORD got = 0;
403*7f2fe78bSCy Schubert DWORD size = 512; // use low number to test...
404*7f2fe78bSCy Schubert HMODULE h = 0;
405*7f2fe78bSCy Schubert BOOL ok = FALSE;
406*7f2fe78bSCy Schubert char* name = 0;
407*7f2fe78bSCy Schubert
408*7f2fe78bSCy Schubert if (!pname)
409*7f2fe78bSCy Schubert return ERROR_INVALID_PARAMETER;
410*7f2fe78bSCy Schubert *pname = 0;
411*7f2fe78bSCy Schubert
412*7f2fe78bSCy Schubert h = GetModuleHandle(module);
413*7f2fe78bSCy Schubert
414*7f2fe78bSCy Schubert if (!h) return GetLastError();
415*7f2fe78bSCy Schubert
416*7f2fe78bSCy Schubert // We assume size < max and size > 0
417*7f2fe78bSCy Schubert while (!status && !ok) {
418*7f2fe78bSCy Schubert if (size > max) {
419*7f2fe78bSCy Schubert // XXX - Assert?
420*7f2fe78bSCy Schubert status = ERROR_INVALID_DATA;
421*7f2fe78bSCy Schubert continue;
422*7f2fe78bSCy Schubert }
423*7f2fe78bSCy Schubert if (name) free_alloc_p(&name);
424*7f2fe78bSCy Schubert name = (char*)malloc_alloc_p(size + 1);
425*7f2fe78bSCy Schubert if (!name) {
426*7f2fe78bSCy Schubert status = ERROR_NOT_ENOUGH_MEMORY;
427*7f2fe78bSCy Schubert continue;
428*7f2fe78bSCy Schubert }
429*7f2fe78bSCy Schubert name[size] = 0;
430*7f2fe78bSCy Schubert got = GetModuleFileName(h, name, size);
431*7f2fe78bSCy Schubert if (!got) {
432*7f2fe78bSCy Schubert status = GetLastError();
433*7f2fe78bSCy Schubert // sanity check:
434*7f2fe78bSCy Schubert if (!status) {
435*7f2fe78bSCy Schubert // XXX - print nasty message...assert?
436*7f2fe78bSCy Schubert status = ERROR_INVALID_DATA;
437*7f2fe78bSCy Schubert }
438*7f2fe78bSCy Schubert continue;
439*7f2fe78bSCy Schubert }
440*7f2fe78bSCy Schubert // To know we're ok, we need to verify that what we got
441*7f2fe78bSCy Schubert // was bigger than GetModuleSize thought it got.
442*7f2fe78bSCy Schubert ok = got && (got < size) && !name[got];
443*7f2fe78bSCy Schubert size *= 2;
444*7f2fe78bSCy Schubert }
445*7f2fe78bSCy Schubert if (status && name)
446*7f2fe78bSCy Schubert free_alloc_p(&name);
447*7f2fe78bSCy Schubert else
448*7f2fe78bSCy Schubert *pname = name;
449*7f2fe78bSCy Schubert return status;
450*7f2fe78bSCy Schubert }
451*7f2fe78bSCy Schubert
452*7f2fe78bSCy Schubert DWORD
alloc_module_dir_name(char * module,char ** pname)453*7f2fe78bSCy Schubert alloc_module_dir_name(
454*7f2fe78bSCy Schubert char* module,
455*7f2fe78bSCy Schubert char** pname
456*7f2fe78bSCy Schubert )
457*7f2fe78bSCy Schubert {
458*7f2fe78bSCy Schubert DWORD status = alloc_module_file_name(module, pname);
459*7f2fe78bSCy Schubert if (!status) {
460*7f2fe78bSCy Schubert char* name = *pname;
461*7f2fe78bSCy Schubert char* p = name + strlen(name);
462*7f2fe78bSCy Schubert while ((p >= name) && (*p != '\\') && (*p != '/')) p--;
463*7f2fe78bSCy Schubert if (p < name) {
464*7f2fe78bSCy Schubert free_alloc_p(pname);
465*7f2fe78bSCy Schubert status = ERROR_INVALID_DATA;
466*7f2fe78bSCy Schubert } else {
467*7f2fe78bSCy Schubert *p = 0;
468*7f2fe78bSCy Schubert }
469*7f2fe78bSCy Schubert }
470*7f2fe78bSCy Schubert return status;
471*7f2fe78bSCy Schubert }
472*7f2fe78bSCy Schubert
473*7f2fe78bSCy Schubert DWORD
alloc_module_dir_name_with_file(char * module,char * file,char ** pname)474*7f2fe78bSCy Schubert alloc_module_dir_name_with_file(
475*7f2fe78bSCy Schubert char* module,
476*7f2fe78bSCy Schubert char* file,
477*7f2fe78bSCy Schubert char** pname
478*7f2fe78bSCy Schubert )
479*7f2fe78bSCy Schubert {
480*7f2fe78bSCy Schubert DWORD status = alloc_module_dir_name(module, pname);
481*7f2fe78bSCy Schubert if (!status) {
482*7f2fe78bSCy Schubert char* name = *pname;
483*7f2fe78bSCy Schubert size_t name_size = strlen(name);
484*7f2fe78bSCy Schubert size_t size = name_size + 1 + strlen(file) + 1;
485*7f2fe78bSCy Schubert char* result = (char*)malloc_alloc_p(size);
486*7f2fe78bSCy Schubert if (!result) {
487*7f2fe78bSCy Schubert status = ERROR_NOT_ENOUGH_MEMORY;
488*7f2fe78bSCy Schubert free_alloc_p(pname);
489*7f2fe78bSCy Schubert } else {
490*7f2fe78bSCy Schubert strcpy(result, name);
491*7f2fe78bSCy Schubert result[name_size] = '\\';
492*7f2fe78bSCy Schubert strcpy(result + name_size + 1, file);
493*7f2fe78bSCy Schubert free_alloc_p(pname);
494*7f2fe78bSCy Schubert *pname = result;
495*7f2fe78bSCy Schubert }
496*7f2fe78bSCy Schubert }
497*7f2fe78bSCy Schubert return status;
498*7f2fe78bSCy Schubert }
499*7f2fe78bSCy Schubert
alloc_cmdline_2_args(char * prog,char * arg1,char * arg2,char ** pname)500*7f2fe78bSCy Schubert DWORD alloc_cmdline_2_args(char* prog,
501*7f2fe78bSCy Schubert char* arg1,
502*7f2fe78bSCy Schubert char* arg2,
503*7f2fe78bSCy Schubert char** pname) {
504*7f2fe78bSCy Schubert DWORD status = 0;
505*7f2fe78bSCy Schubert size_t size = strlen(prog) + strlen(arg1) + strlen(arg2) + 4;
506*7f2fe78bSCy Schubert char* result = (char*)malloc_alloc_p(size);
507*7f2fe78bSCy Schubert if (!result) {
508*7f2fe78bSCy Schubert status = ERROR_NOT_ENOUGH_MEMORY;
509*7f2fe78bSCy Schubert }
510*7f2fe78bSCy Schubert else {
511*7f2fe78bSCy Schubert strcpy(result, prog);
512*7f2fe78bSCy Schubert strcat(result, " ");
513*7f2fe78bSCy Schubert strcat(result, arg1);
514*7f2fe78bSCy Schubert strcat(result, " ");
515*7f2fe78bSCy Schubert strcat(result, arg2);
516*7f2fe78bSCy Schubert *pname = result;
517*7f2fe78bSCy Schubert }
518*7f2fe78bSCy Schubert cci_debug_printf("%s made <%s>", __FUNCTION__, result);
519*7f2fe78bSCy Schubert return status;
520*7f2fe78bSCy Schubert }
521