Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygencacls.cGo to the documentation of this file.00001 /* 00002 * ReactOS Control ACLs Program 00003 * Copyright (C) 2006 Thomas Weidenmueller 00004 * 00005 * This library is free software; you can redistribute it and/or 00006 * modify it under the terms of the GNU Lesser General Public 00007 * License as published by the Free Software Foundation; either 00008 * version 2.1 of the License, or (at your option) any later version. 00009 * 00010 * This library is distributed in the hope that it will be useful, 00011 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00012 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00013 * Lesser General Public License for more details. 00014 * 00015 * You should have received a copy of the GNU Lesser General Public 00016 * License along with this library; if not, write to the Free Software 00017 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 00018 */ 00019 00020 #include <precomp.h> 00021 00022 static GENERIC_MAPPING FileGenericMapping = 00023 { 00024 FILE_GENERIC_READ, 00025 FILE_GENERIC_WRITE, 00026 FILE_GENERIC_EXECUTE, 00027 FILE_ALL_ACCESS 00028 }; 00029 00030 00031 static 00032 INT 00033 LengthOfStrResource(IN HINSTANCE hInst, 00034 IN UINT uID) 00035 { 00036 HRSRC hrSrc; 00037 HGLOBAL hRes; 00038 LPWSTR lpName, lpStr; 00039 00040 if (hInst == NULL) 00041 { 00042 hInst = GetModuleHandle(NULL); 00043 } 00044 00045 /* There are always blocks of 16 strings */ 00046 lpName = (LPWSTR)MAKEINTRESOURCE((uID >> 4) + 1); 00047 00048 /* Find the string table block */ 00049 hrSrc = FindResourceW(hInst, lpName, (LPWSTR)RT_STRING); 00050 if (hrSrc) 00051 { 00052 hRes = LoadResource(hInst, hrSrc); 00053 if (hRes) 00054 { 00055 lpStr = LockResource(hRes); 00056 if (lpStr) 00057 { 00058 UINT x; 00059 00060 /* Find the string we're looking for */ 00061 uID &= 0xF; /* position in the block, same as % 16 */ 00062 for (x = 0; x < uID; x++) 00063 { 00064 lpStr += (*lpStr) + 1; 00065 } 00066 00067 /* Found the string */ 00068 return (int)(*lpStr); 00069 } 00070 } 00071 } 00072 return -1; 00073 } 00074 00075 00076 static 00077 INT 00078 AllocAndLoadString(OUT LPTSTR *lpTarget, 00079 IN HINSTANCE hInst, 00080 IN UINT uID) 00081 { 00082 INT ln; 00083 00084 ln = LengthOfStrResource(hInst, 00085 uID); 00086 if (ln++ > 0) 00087 { 00088 (*lpTarget) = (LPTSTR)HeapAlloc(GetProcessHeap(), 00089 0, 00090 ln * sizeof(TCHAR)); 00091 if ((*lpTarget) != NULL) 00092 { 00093 INT Ret; 00094 Ret = LoadString(hInst, 00095 uID, 00096 *lpTarget, 00097 ln); 00098 if (!Ret) 00099 { 00100 HeapFree(GetProcessHeap(), 00101 0, 00102 *lpTarget); 00103 } 00104 return Ret; 00105 } 00106 } 00107 return 0; 00108 } 00109 00110 00111 static 00112 VOID 00113 PrintHelp(VOID) 00114 { 00115 LPTSTR szHelp; 00116 00117 if (AllocAndLoadString(&szHelp, 00118 NULL, 00119 IDS_HELP) != 0) 00120 { 00121 _tprintf(_T("%s"), 00122 szHelp); 00123 00124 HeapFree(GetProcessHeap(), 00125 0, 00126 szHelp); 00127 } 00128 } 00129 00130 00131 static 00132 VOID 00133 PrintErrorMessage(IN DWORD dwError) 00134 { 00135 LPTSTR szError; 00136 00137 if (FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | 00138 FORMAT_MESSAGE_IGNORE_INSERTS | 00139 FORMAT_MESSAGE_FROM_SYSTEM, 00140 NULL, 00141 dwError, 00142 MAKELANGID(LANG_NEUTRAL, 00143 SUBLANG_DEFAULT), 00144 (LPTSTR)&szError, 00145 0, 00146 NULL) != 0) 00147 { 00148 _tprintf(_T("%s"), 00149 szError); 00150 LocalFree((HLOCAL)szError); 00151 } 00152 } 00153 00154 00155 static 00156 DWORD 00157 LoadAndPrintString(IN HINSTANCE hInst, 00158 IN UINT uID) 00159 { 00160 TCHAR szTemp[255]; 00161 DWORD Len; 00162 00163 Len = (DWORD)LoadString(hInst, 00164 uID, 00165 szTemp, 00166 sizeof(szTemp) / sizeof(szTemp[0])); 00167 00168 if (Len != 0) 00169 { 00170 _tprintf(_T("%s"), 00171 szTemp); 00172 } 00173 00174 return Len; 00175 } 00176 00177 00178 static 00179 BOOL 00180 PrintFileDacl(IN LPTSTR FilePath, 00181 IN LPTSTR FileName) 00182 { 00183 SIZE_T Length; 00184 PSECURITY_DESCRIPTOR SecurityDescriptor; 00185 DWORD SDSize = 0; 00186 TCHAR FullFileName[MAX_PATH + 1]; 00187 BOOL Error = FALSE, Ret = FALSE; 00188 00189 Length = _tcslen(FilePath) + _tcslen(FileName); 00190 if (Length > MAX_PATH) 00191 { 00192 /* file name too long */ 00193 SetLastError(ERROR_FILE_NOT_FOUND); 00194 return FALSE; 00195 } 00196 00197 _tcscpy(FullFileName, 00198 FilePath); 00199 _tcscat(FullFileName, 00200 FileName); 00201 00202 /* find out how much memory we need */ 00203 if (!GetFileSecurity(FullFileName, 00204 DACL_SECURITY_INFORMATION, 00205 NULL, 00206 0, 00207 &SDSize) && 00208 GetLastError() != ERROR_INSUFFICIENT_BUFFER) 00209 { 00210 return FALSE; 00211 } 00212 00213 SecurityDescriptor = (PSECURITY_DESCRIPTOR)HeapAlloc(GetProcessHeap(), 00214 0, 00215 SDSize); 00216 if (SecurityDescriptor != NULL) 00217 { 00218 if (GetFileSecurity(FullFileName, 00219 DACL_SECURITY_INFORMATION, 00220 SecurityDescriptor, 00221 SDSize, 00222 &SDSize)) 00223 { 00224 PACL Dacl; 00225 BOOL DaclPresent; 00226 BOOL DaclDefaulted; 00227 00228 if (GetSecurityDescriptorDacl(SecurityDescriptor, 00229 &DaclPresent, 00230 &Dacl, 00231 &DaclDefaulted)) 00232 { 00233 if (DaclPresent) 00234 { 00235 PACCESS_ALLOWED_ACE Ace; 00236 DWORD AceIndex = 0; 00237 00238 /* dump the ACL */ 00239 while (GetAce(Dacl, 00240 AceIndex, 00241 (PVOID*)&Ace)) 00242 { 00243 SID_NAME_USE Use; 00244 DWORD NameSize = 0; 00245 DWORD DomainSize = 0; 00246 LPTSTR Name = NULL; 00247 LPTSTR Domain = NULL; 00248 LPTSTR SidString = NULL; 00249 DWORD IndentAccess; 00250 DWORD AccessMask = Ace->Mask; 00251 PSID Sid = (PSID)&Ace->SidStart; 00252 00253 /* attempt to translate the SID into a readable string */ 00254 if (!LookupAccountSid(NULL, 00255 Sid, 00256 Name, 00257 &NameSize, 00258 Domain, 00259 &DomainSize, 00260 &Use)) 00261 { 00262 if (GetLastError() == ERROR_NONE_MAPPED || NameSize == 0) 00263 { 00264 goto BuildSidString; 00265 } 00266 else 00267 { 00268 if (GetLastError() != ERROR_INSUFFICIENT_BUFFER) 00269 { 00270 Error = TRUE; 00271 break; 00272 } 00273 00274 Name = (LPTSTR)HeapAlloc(GetProcessHeap(), 00275 0, 00276 (NameSize + DomainSize) * sizeof(TCHAR)); 00277 if (Name == NULL) 00278 { 00279 SetLastError(ERROR_NOT_ENOUGH_MEMORY); 00280 Error = TRUE; 00281 break; 00282 } 00283 00284 Domain = Name + NameSize; 00285 Name[0] = _T('\0'); 00286 if (DomainSize != 0) 00287 Domain[0] = _T('\0'); 00288 if (!LookupAccountSid(NULL, 00289 Sid, 00290 Name, 00291 &NameSize, 00292 Domain, 00293 &DomainSize, 00294 &Use)) 00295 { 00296 HeapFree(GetProcessHeap(), 00297 0, 00298 Name); 00299 Name = NULL; 00300 goto BuildSidString; 00301 } 00302 } 00303 } 00304 else 00305 { 00306 BuildSidString: 00307 if (!ConvertSidToStringSid(Sid, 00308 &SidString)) 00309 { 00310 Error = TRUE; 00311 break; 00312 } 00313 } 00314 00315 /* print the file name or space */ 00316 _tprintf(_T("%s "), 00317 FullFileName); 00318 00319 /* attempt to map the SID to a user name */ 00320 if (AceIndex == 0) 00321 { 00322 DWORD i = 0; 00323 00324 /* overwrite the full file name with spaces so we 00325 only print the file name once */ 00326 while (FullFileName[i] != _T('\0')) 00327 FullFileName[i++] = _T(' '); 00328 } 00329 00330 /* print the domain and/or user if possible, or the SID string */ 00331 if (Name != NULL && Domain[0] != _T('\0')) 00332 { 00333 _tprintf(_T("%s\\%s:"), 00334 Domain, 00335 Name); 00336 IndentAccess = (DWORD)_tcslen(Domain) + _tcslen(Name); 00337 } 00338 else 00339 { 00340 LPTSTR DisplayString = (Name != NULL ? Name : SidString); 00341 00342 _tprintf(_T("%s:"), 00343 DisplayString); 00344 IndentAccess = (DWORD)_tcslen(DisplayString); 00345 } 00346 00347 /* print the ACE Flags */ 00348 if (Ace->Header.AceFlags & CONTAINER_INHERIT_ACE) 00349 { 00350 IndentAccess += LoadAndPrintString(NULL, 00351 IDS_ABBR_CI); 00352 } 00353 if (Ace->Header.AceFlags & OBJECT_INHERIT_ACE) 00354 { 00355 IndentAccess += LoadAndPrintString(NULL, 00356 IDS_ABBR_OI); 00357 } 00358 if (Ace->Header.AceFlags & INHERIT_ONLY_ACE) 00359 { 00360 IndentAccess += LoadAndPrintString(NULL, 00361 IDS_ABBR_IO); 00362 } 00363 00364 IndentAccess += 2; 00365 00366 /* print the access rights */ 00367 MapGenericMask(&AccessMask, 00368 &FileGenericMapping); 00369 if (Ace->Header.AceType & ACCESS_DENIED_ACE_TYPE) 00370 { 00371 if (AccessMask == FILE_ALL_ACCESS) 00372 { 00373 LoadAndPrintString(NULL, 00374 IDS_ABBR_NONE); 00375 } 00376 else 00377 { 00378 LoadAndPrintString(NULL, 00379 IDS_DENY); 00380 goto PrintSpecialAccess; 00381 } 00382 } 00383 else 00384 { 00385 if (AccessMask == FILE_ALL_ACCESS) 00386 { 00387 LoadAndPrintString(NULL, 00388 IDS_ABBR_FULL); 00389 } 00390 else if (!(Ace->Mask & (GENERIC_READ | GENERIC_EXECUTE)) && 00391 AccessMask == (FILE_GENERIC_READ | FILE_EXECUTE)) 00392 { 00393 LoadAndPrintString(NULL, 00394 IDS_ABBR_READ); 00395 } 00396 else if (AccessMask == (FILE_GENERIC_READ | FILE_GENERIC_WRITE | FILE_EXECUTE | DELETE)) 00397 { 00398 LoadAndPrintString(NULL, 00399 IDS_ABBR_CHANGE); 00400 } 00401 else if (AccessMask == FILE_GENERIC_WRITE) 00402 { 00403 LoadAndPrintString(NULL, 00404 IDS_ABBR_WRITE); 00405 } 00406 else 00407 { 00408 DWORD x, x2; 00409 static const struct 00410 { 00411 DWORD Access; 00412 UINT uID; 00413 } 00414 AccessRights[] = 00415 { 00416 {FILE_WRITE_ATTRIBUTES, IDS_FILE_WRITE_ATTRIBUTES}, 00417 {FILE_READ_ATTRIBUTES, IDS_FILE_READ_ATTRIBUTES}, 00418 {FILE_DELETE_CHILD, IDS_FILE_DELETE_CHILD}, 00419 {FILE_EXECUTE, IDS_FILE_EXECUTE}, 00420 {FILE_WRITE_EA, IDS_FILE_WRITE_EA}, 00421 {FILE_READ_EA, IDS_FILE_READ_EA}, 00422 {FILE_APPEND_DATA, IDS_FILE_APPEND_DATA}, 00423 {FILE_WRITE_DATA, IDS_FILE_WRITE_DATA}, 00424 {FILE_READ_DATA, IDS_FILE_READ_DATA}, 00425 {FILE_GENERIC_EXECUTE, IDS_FILE_GENERIC_EXECUTE}, 00426 {FILE_GENERIC_WRITE, IDS_FILE_GENERIC_WRITE}, 00427 {FILE_GENERIC_READ, IDS_FILE_GENERIC_READ}, 00428 {GENERIC_ALL, IDS_GENERIC_ALL}, 00429 {GENERIC_EXECUTE, IDS_GENERIC_EXECUTE}, 00430 {GENERIC_WRITE, IDS_GENERIC_WRITE}, 00431 {GENERIC_READ, IDS_GENERIC_READ}, 00432 {MAXIMUM_ALLOWED, IDS_MAXIMUM_ALLOWED}, 00433 {ACCESS_SYSTEM_SECURITY, IDS_ACCESS_SYSTEM_SECURITY}, 00434 {SPECIFIC_RIGHTS_ALL, IDS_SPECIFIC_RIGHTS_ALL}, 00435 {STANDARD_RIGHTS_REQUIRED, IDS_STANDARD_RIGHTS_REQUIRED}, 00436 {SYNCHRONIZE, IDS_SYNCHRONIZE}, 00437 {WRITE_OWNER, IDS_WRITE_OWNER}, 00438 {WRITE_DAC, IDS_WRITE_DAC}, 00439 {READ_CONTROL, IDS_READ_CONTROL}, 00440 {DELETE, IDS_DELETE}, 00441 {STANDARD_RIGHTS_ALL, IDS_STANDARD_RIGHTS_ALL}, 00442 }; 00443 00444 LoadAndPrintString(NULL, 00445 IDS_ALLOW); 00446 00447 PrintSpecialAccess: 00448 LoadAndPrintString(NULL, 00449 IDS_SPECIAL_ACCESS); 00450 00451 /* print the special access rights */ 00452 x = sizeof(AccessRights) / sizeof(AccessRights[0]); 00453 while (x-- != 0) 00454 { 00455 if ((Ace->Mask & AccessRights[x].Access) == AccessRights[x].Access) 00456 { 00457 _tprintf(_T("\n%s "), 00458 FullFileName); 00459 for (x2 = 0; 00460 x2 < IndentAccess; 00461 x2++) 00462 { 00463 _tprintf(_T(" ")); 00464 } 00465 00466 LoadAndPrintString(NULL, 00467 AccessRights[x].uID); 00468 } 00469 } 00470 00471 _tprintf(_T("\n")); 00472 } 00473 } 00474 00475 _tprintf(_T("\n")); 00476 00477 /* free up all resources */ 00478 if (Name != NULL) 00479 { 00480 HeapFree(GetProcessHeap(), 00481 0, 00482 Name); 00483 } 00484 00485 if (SidString != NULL) 00486 { 00487 LocalFree((HLOCAL)SidString); 00488 } 00489 00490 AceIndex++; 00491 } 00492 00493 if (!Error) 00494 Ret = TRUE; 00495 } 00496 else 00497 { 00498 SetLastError(ERROR_NO_SECURITY_ON_OBJECT); 00499 } 00500 } 00501 } 00502 00503 HeapFree(GetProcessHeap(), 00504 0, 00505 SecurityDescriptor); 00506 } 00507 else 00508 { 00509 SetLastError(ERROR_NOT_ENOUGH_MEMORY); 00510 } 00511 00512 return Ret; 00513 } 00514 00515 00516 int 00517 __cdecl 00518 _tmain(int argc, const TCHAR *argv[]) 00519 { 00520 if (argc < 2) 00521 { 00522 PrintHelp(); 00523 return 1; 00524 } 00525 else 00526 { 00527 TCHAR FullPath[MAX_PATH + 1]; 00528 TCHAR *FilePart = NULL; 00529 WIN32_FIND_DATA FindData; 00530 HANDLE hFind; 00531 DWORD LastError; 00532 00533 if (argc > 2) 00534 { 00535 /* FIXME - parse arguments */ 00536 } 00537 00538 /* get the full path of where we're searching in */ 00539 if (GetFullPathName(argv[1], 00540 sizeof(FullPath) / sizeof(FullPath[0]), 00541 FullPath, 00542 &FilePart) != 0) 00543 { 00544 if (FilePart != NULL) 00545 *FilePart = _T('\0'); 00546 } 00547 else 00548 goto Error; 00549 00550 /* find the file(s) */ 00551 hFind = FindFirstFile(argv[1], 00552 &FindData); 00553 if (hFind != INVALID_HANDLE_VALUE) 00554 { 00555 do 00556 { 00557 if (!(FindData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) || 00558 (_tcscmp(FindData.cFileName, 00559 _T(".")) && 00560 _tcscmp(FindData.cFileName, 00561 _T("..")))) 00562 { 00563 if (argc > 2) 00564 { 00565 /* FIXME - edit or replace the descriptor */ 00566 } 00567 else 00568 { 00569 if (!PrintFileDacl(FullPath, 00570 FindData.cFileName)) 00571 { 00572 LastError = GetLastError(); 00573 00574 if (LastError == ERROR_ACCESS_DENIED) 00575 { 00576 PrintErrorMessage(LastError); 00577 } 00578 else 00579 break; 00580 } 00581 else 00582 _tprintf(_T("\n")); 00583 } 00584 } 00585 } while (FindNextFile(hFind, 00586 &FindData)); 00587 00588 FindClose(hFind); 00589 00590 if (GetLastError() != ERROR_NO_MORE_FILES) 00591 { 00592 goto Error; 00593 } 00594 } 00595 else 00596 { 00597 Error: 00598 PrintErrorMessage(GetLastError()); 00599 return 1; 00600 } 00601 } 00602 00603 return 0; 00604 } Generated on Thu Feb 9 04:38:50 2012 for ReactOS by
1.6.3
|