Home | Info | Community | Development | myReactOS | Contact Us

  1. Home
  2. Community
  3. Development
  4. myReactOS

  1. Main Page
  2. Alphabetical List
  3. Data Structures
  4. Directories
  5. File List
  6. Data Fields
  7. Globals
  8. Related Pages

ReactOS Development > Doxygen

cacls.c

Go 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 doxygen 1.6.3

ReactOS is a registered trademark or a trademark of ReactOS Foundation in the United States and other countries.