Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/mobile
Path: blob/master/test/jdk/sun/management/windows/exerevokeall.c
41149 views
1
/*
2
* Copyright (c) 2004, 2019, Oracle and/or its affiliates. All rights reserved.
3
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4
*
5
* This code is free software; you can redistribute it and/or modify it
6
* under the terms of the GNU General Public License version 2 only, as
7
* published by the Free Software Foundation.
8
*
9
* This code is distributed in the hope that it will be useful, but WITHOUT
10
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12
* version 2 for more details (a copy is included in the LICENSE file that
13
* accompanied this code).
14
*
15
* You should have received a copy of the GNU General Public License version
16
* 2 along with this work; if not, write to the Free Software Foundation,
17
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18
*
19
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20
* or visit www.oracle.com if you need additional information or have any
21
* questions.
22
*/
23
24
#include <stdio.h>
25
#include <windows.h>
26
#include <malloc.h>
27
#include <string.h>
28
29
/*
30
* Simple Windows utility to remove all non-owner access to a given file.
31
*/
32
33
34
/*
35
* Access mask to represent any file access
36
*/
37
#define ANY_ACCESS (FILE_GENERIC_READ | FILE_GENERIC_WRITE | FILE_GENERIC_EXECUTE)
38
39
40
/*
41
* Print error message to stderr
42
*/
43
static void printLastError(const char* msg) {
44
int len;
45
char buf[128];
46
DWORD errval;
47
48
buf[0] = '\0';
49
len = sizeof(buf);
50
51
errval = GetLastError();
52
if (errval != 0) {
53
int n = FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM|FORMAT_MESSAGE_IGNORE_INSERTS,
54
NULL, errval,
55
0, buf, len, NULL);
56
if (n > 3) {
57
/* Drop final '.', CR, LF */
58
if (buf[n - 1] == '\n') n--;
59
if (buf[n - 1] == '\r') n--;
60
if (buf[n - 1] == '.') n--;
61
buf[n] = '\0';
62
}
63
}
64
65
if (strlen(buf) > 0) {
66
fprintf(stderr, "revokeall %s: %s\n", msg, buf);
67
} else {
68
fprintf(stderr, "revokeall %s\n", msg);
69
}
70
}
71
72
73
74
/*
75
* Return a string that includes all the components of a given SID.
76
* See here for a description of the SID components :-
77
* http://msdn.microsoft.com/library/default.asp?url=/library/en-us/security/security/sid_components.asp
78
*/
79
static char *getTextualSid(SID* sid) {
80
SID_IDENTIFIER_AUTHORITY* sia;
81
DWORD i, count;
82
DWORD len;
83
char* name;
84
85
/*
86
* Get the identifier authority and the number of sub-authorities
87
*/
88
sia = GetSidIdentifierAuthority(sid);
89
count = *GetSidSubAuthorityCount(sid);
90
91
/*
92
* Allocate buffer for the string - buffer is :-
93
* S-SID_REVISION- + identifierAuthority- + subauthorities- + NULL
94
*/
95
len=(15 + 12 + (12 * count) + 1) * sizeof(char);
96
name = (char*)malloc(len);
97
if (name == NULL) {
98
return NULL;
99
}
100
101
// S-SID_REVISION
102
sprintf(name, "S-%lu-", SID_REVISION );
103
104
// Identifier authority
105
if ((sia->Value[0] != 0) || (sia->Value[1] != 0))
106
{
107
sprintf(name + strlen(name), "0x%02hx%02hx%02hx%02hx%02hx%02hx",
108
(USHORT)sia->Value[0],
109
(USHORT)sia->Value[1],
110
(USHORT)sia->Value[2],
111
(USHORT)sia->Value[3],
112
(USHORT)sia->Value[4],
113
(USHORT)sia->Value[5]);
114
}
115
else
116
{
117
sprintf(name + strlen(name), "%lu",
118
(ULONG)(sia->Value[5] ) +
119
(ULONG)(sia->Value[4] << 8) +
120
(ULONG)(sia->Value[3] << 16) +
121
(ULONG)(sia->Value[2] << 24) );
122
}
123
124
// finally, the sub-authorities
125
for (i=0 ; i<count; i++) {
126
sprintf(name + strlen(name), "-%lu",
127
*GetSidSubAuthority(sid, i) );
128
}
129
130
return name;
131
}
132
133
/*
134
* Returns a string to represent the given security identifier (SID).
135
* If the account is known to the local computer then the account
136
* domain is returned. The format will be \\name or domain\\name depending
137
* on if the computer belongs to a domain.
138
* If the account name is not known then the textual representation of
139
* SID is returned -- eg: S-1-5-21-2818032319-470147023-1036452850-13037.
140
*/
141
static char *getSIDString(SID* sid) {
142
char domain[255];
143
char name[255];
144
DWORD domainLen = sizeof(domain);
145
DWORD nameLen = sizeof(name);
146
SID_NAME_USE use;
147
148
if(!IsValidSid(sid)) {
149
return strdup("<Invalid SID>");
150
}
151
152
if (LookupAccountSid(NULL, sid, name, &nameLen, domain, &domainLen, &use)) {
153
size_t len = strlen(name) + strlen(domain) + 3;
154
char* s = (char*)malloc(len);
155
if (s != NULL) {
156
strcpy(s, domain);
157
strcat(s, "\\\\");
158
strcat(s, name);
159
}
160
return s;
161
} else {
162
return getTextualSid(sid);
163
}
164
}
165
166
167
168
/*
169
* Returns 1 if the specified file is on a file system that supports
170
* persistent ACLs (On NTFS file systems returns true, on FAT32 file systems
171
* returns false), otherwise 0. Returns -1 if error.
172
*/
173
static int isSecuritySupported(const char* path) {
174
char* root;
175
char* p;
176
BOOL res;
177
DWORD dwMaxComponentLength;
178
DWORD dwFlags;
179
char fsName[128];
180
DWORD fsNameLength;
181
182
/*
183
* Get root directory. For UNCs the slash after the share name is required.
184
*/
185
root = strdup(path);
186
if (*root == '\\') {
187
/*
188
* \\server\share\file ==> \\server\share\
189
*/
190
int slashskip = 3;
191
p = root;
192
while ((*p == '\\') && (slashskip > 0)) {
193
char* p2;
194
p++;
195
p2 = strchr(p, '\\');
196
if ((p2 == NULL) || (*p2 != '\\')) {
197
free(root);
198
fprintf(stderr, "Malformed UNC");
199
return -1;
200
}
201
p = p2;
202
slashskip--;
203
}
204
if (slashskip != 0) {
205
free(root);
206
fprintf(stderr, "Malformed UNC");
207
return -1;
208
}
209
p++;
210
*p = '\0';
211
212
} else {
213
p = strchr(root, '\\');
214
215
/*
216
* Relative path so use current directory
217
*/
218
if (p == NULL) {
219
free(root);
220
root = malloc(255);
221
if (GetCurrentDirectory(255, root) == 0) {
222
printLastError("GetCurrentDirectory failed");
223
return -1;
224
}
225
p = strchr(root, '\\');
226
if (p == NULL) {
227
fprintf(stderr, "GetCurrentDirectory doesn't include drive letter!!!!\n");
228
return -1;
229
}
230
}
231
p++;
232
*p = '\0';
233
}
234
235
/*
236
* Get the volume information - this gives us the file system file and
237
* also tells us if the file system supports persistent ACLs.
238
*/
239
fsNameLength = sizeof(fsName)-1;
240
res = GetVolumeInformation(root,
241
NULL, // address of name of the volume, can be NULL
242
0, // length of volume name
243
NULL, // address of volume serial number, can be NULL
244
&dwMaxComponentLength,
245
&dwFlags,
246
fsName,
247
fsNameLength);
248
if (res == 0) {
249
printLastError("GetVolumeInformation failed");
250
free(root);
251
return -1;
252
}
253
254
free(root);
255
return (dwFlags & FS_PERSISTENT_ACLS) ? 1 : 0;
256
}
257
258
259
/*
260
* Returns the security descriptor for a file.
261
*/
262
static SECURITY_DESCRIPTOR* getFileSecurityDescriptor(const char* path) {
263
SECURITY_DESCRIPTOR* sd;
264
DWORD len = 0;
265
SECURITY_INFORMATION info =
266
OWNER_SECURITY_INFORMATION | DACL_SECURITY_INFORMATION;
267
268
GetFileSecurity(path, info , 0, 0, &len);
269
if (GetLastError() != ERROR_INSUFFICIENT_BUFFER) {
270
printLastError("GetFileSecurity failed");
271
return NULL;
272
}
273
sd = (SECURITY_DESCRIPTOR *)malloc(len);
274
if (sd == NULL) {
275
fprintf(stderr, "Out of memory");
276
} else {
277
if (!GetFileSecurity(path, info, sd, len, &len)) {
278
printLastError("GetFileSecurity failed");
279
free(sd);
280
return NULL;
281
}
282
}
283
return sd;
284
}
285
286
287
/*
288
* Revoke all access to the specific file
289
*/
290
static int revokeAll(const char* path) {
291
SECURITY_DESCRIPTOR* sd;
292
SID* owner;
293
ACL *acl;
294
BOOL defaulted, present;
295
ACL_SIZE_INFORMATION acl_size_info;
296
DWORD i, count;
297
char* str;
298
299
/*
300
* Get security descriptor for file; From security descriptor get the
301
* owner SID, and the DACL.
302
*/
303
sd = getFileSecurityDescriptor(path);
304
if (sd == NULL) {
305
return -1; /* error already reported */
306
}
307
if (!GetSecurityDescriptorOwner(sd, &owner, &defaulted)) {
308
printLastError("GetSecurityDescriptorOwner failed");
309
return -1;
310
}
311
str = getSIDString(owner);
312
if (str != NULL) {
313
printf("owner: %s\n", str);
314
free(str);
315
}
316
if (!GetSecurityDescriptorDacl(sd, &present, &acl, &defaulted)) {
317
printLastError("GetSecurityDescriptorDacl failed");
318
return -1;
319
}
320
if (!present) {
321
fprintf(stderr, "Security descriptor does not contain a DACL");
322
return -1;
323
}
324
325
/*
326
* If DACL is NULL there is no access to the file - we are done
327
*/
328
if (acl == NULL) {
329
return 1;
330
}
331
332
/*
333
* Iterate over the ACEs. For each "allow" type check that the SID
334
* matches the owner - if not we remove the ACE from the ACL
335
*/
336
if (!GetAclInformation(acl, (void *) &acl_size_info, sizeof(acl_size_info),
337
AclSizeInformation)) {
338
printLastError("GetAclInformation failed");
339
return -1;
340
}
341
count = acl_size_info.AceCount;
342
i = 0;
343
while (count > 0) {
344
void* ace;
345
ACCESS_ALLOWED_ACE *access;
346
SID* sid;
347
BOOL deleted;
348
349
if (!GetAce(acl, i, &ace)) {
350
printLastError("GetAce failed");
351
return -1;
352
}
353
if (((ACCESS_ALLOWED_ACE *)ace)->Header.AceType != ACCESS_ALLOWED_ACE_TYPE) {
354
i++;
355
count--;
356
continue;
357
}
358
access = (ACCESS_ALLOWED_ACE *)ace;
359
sid = (SID *) &access->SidStart;
360
361
362
deleted = FALSE;
363
if (!EqualSid(owner, sid)) {
364
/*
365
* If the ACE allows any access then the file then we
366
* delete it.
367
*/
368
if (access->Mask & ANY_ACCESS) {
369
str = getSIDString(sid);
370
if (str != NULL) {
371
printf("remove ALLOW %s\n", str);
372
free(str);
373
}
374
if (DeleteAce(acl, i) == 0) {
375
printLastError("DeleteAce failed");
376
return -1;
377
}
378
deleted = TRUE;
379
}
380
}
381
382
if (!deleted) {
383
str = getSIDString(sid);
384
if (str != NULL) {
385
printf("ALLOW %s (access mask=%x)\n", str, access->Mask);
386
free(str);
387
}
388
389
/* onto the next ACE */
390
i++;
391
}
392
count--;
393
}
394
395
/*
396
* No changes - only owner has access
397
*/
398
if (i == acl_size_info.AceCount) {
399
printf("No changes.\n");
400
return 1;
401
}
402
403
/*
404
* Create security descriptor and set its DACL to the version
405
* that we just edited
406
*/
407
if (!InitializeSecurityDescriptor(sd, SECURITY_DESCRIPTOR_REVISION)) {
408
printLastError("InitializeSecurityDescriptor failed");
409
return -1;
410
}
411
if (!SetSecurityDescriptorDacl(sd, present, acl, defaulted)) {
412
printLastError("SetSecurityDescriptorDacl failed");
413
return -1;
414
}
415
if (!SetFileSecurity(path, DACL_SECURITY_INFORMATION, sd)) {
416
printLastError("SetFileSecurity failed");
417
return -1;
418
}
419
420
printf("File updated.\n");
421
422
return 1;
423
}
424
425
/*
426
* Convert slashes in the pathname to backslashes if needed.
427
*/
428
static char* convert_path(const char* p) {
429
int i = 0;
430
char* path = strdup(p);
431
while (p[i] != '\0') {
432
if (p[i] == '/') {
433
path[i] = '\\';
434
}
435
i++;
436
}
437
return path;
438
}
439
440
/*
441
* Usage: revokeall file
442
*/
443
int main( int argc, char *argv[])
444
{
445
int rc;
446
const char* path;
447
448
if (argc != 2) {
449
fprintf(stderr, "Usage: %s file\n", argv[0]);
450
return -1;
451
}
452
path = convert_path(argv[1]);
453
printf("Revoking all non-owner access to %s\n", path);
454
rc = isSecuritySupported(path);
455
if (rc != 1) {
456
if (rc == 0) {
457
printf("File security not supported on this file system\n");
458
}
459
return rc;
460
} else {
461
return revokeAll(path);
462
}
463
}
464
465