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