sdmgmt.cpp

Go to the documentation of this file.
00001 /*++
00002 
00003 DCOM Permission Configuration Sample
00004 Copyright (c) 1996, Microsoft Corporation. All rights reserved.
00005 
00006 Module Name:
00007 
00008     sdmgmt.cpp
00009 
00010 Abstract:
00011 
00012     Routines to manage security descriptors
00013 
00014 Author:
00015 
00016     Michael Nelson
00017 
00018 Environment:
00019 
00020     Windows NT
00021 
00022 --*/
00023 
00024 #include <windows.h>
00025 #include <comdef.h>
00026 #include <stdio.h>
00027 #include <conio.h>
00028 #include <malloc.h>
00029 #include <tchar.h>
00030 #include "ntsecapi.h"
00031 #include "dcomperm.h"
00032 
00033 DWORD
00034 CreateNewSD (
00035     SECURITY_DESCRIPTOR **SD,
00036     bool install_defaults
00037     )
00038 {
00039     PACL    dacl = NIL;
00040     DWORD   sidLength = 0;
00041     PSID    groupSID = NIL;
00042     PSID    ownerSID = NIL;
00043     DWORD   returnValue = 0;
00044 
00045     *SD = NULL;
00046 
00047     PSID    sid = NIL;
00048     returnValue = GetCurrentUserSID (&sid);
00049     if (returnValue != ERROR_SUCCESS)
00050         return returnValue;
00051 
00052     sidLength = GetLengthSid (sid);
00053 
00054     *SD = (SECURITY_DESCRIPTOR *) malloc (
00055         (sizeof (ACL)+sizeof (ACCESS_ALLOWED_ACE)+sidLength) +
00056         (2 * sidLength) +
00057         sizeof (SECURITY_DESCRIPTOR));
00058 
00059     groupSID = (SID *) (*SD + 1);
00060     ownerSID = (SID *) (((BYTE *) groupSID) + sidLength);
00061     dacl = (ACL *) (((BYTE *) ownerSID) + sidLength);
00062 
00063     if (!InitializeSecurityDescriptor (*SD, SECURITY_DESCRIPTOR_REVISION))
00064     {
00065         free (*SD);
00066         free (sid);
00067         return GetLastError();
00068     }
00069 
00070     if (!InitializeAcl (dacl,
00071                         sizeof (ACL)+sizeof (ACCESS_ALLOWED_ACE)+sidLength,
00072                         ACL_REVISION2))
00073     {
00074         free (*SD);
00075         free (sid);
00076         return GetLastError();
00077     }
00078 
00079     if (install_defaults) {
00080       if (!AddAccessAllowedAce (dacl,
00081                                 ACL_REVISION2,
00082                                 COM_RIGHTS_EXECUTE,
00083                                 sid))
00084       {
00085           free (*SD);
00086           free (sid);
00087           return GetLastError();
00088       }
00089     }
00090 
00091     if (!SetSecurityDescriptorDacl (*SD, TRUE, dacl, FALSE))
00092     {
00093         free (*SD);
00094         free (sid);
00095         return GetLastError();
00096     }
00097 
00098     memcpy (groupSID, sid, sidLength);
00099     if (!SetSecurityDescriptorGroup (*SD, groupSID, FALSE))
00100     {
00101         free (*SD);
00102         free (sid);
00103         return GetLastError();
00104     }
00105 
00106     memcpy (ownerSID, sid, sidLength);
00107     if (!SetSecurityDescriptorOwner (*SD, ownerSID, FALSE))
00108     {
00109         free (*SD);
00110         free (sid);
00111         return GetLastError();
00112     }
00113     return ERROR_SUCCESS;
00114 }
00115 
00116 
00117 DWORD
00118 MakeSDAbsolute (
00119     PSECURITY_DESCRIPTOR OldSD,
00120     PSECURITY_DESCRIPTOR *NewSD
00121     )
00122 {
00123     PSECURITY_DESCRIPTOR  sd = NIL;
00124     DWORD                 descriptorSize = 0;
00125     DWORD                 daclSize = 0;
00126     DWORD                 saclSize = 0;
00127     DWORD                 ownerSIDSize = 0;
00128     DWORD                 groupSIDSize = 0;
00129     PACL                  dacl = NIL;
00130     PACL                  sacl = NIL;
00131     PSID                  ownerSID = NIL;
00132     PSID                  groupSID = NIL;
00133     BOOL                  present = false;
00134     BOOL                  systemDefault = false;
00135 
00136     //
00137     // Get SACL
00138     //
00139 
00140     if (!GetSecurityDescriptorSacl (OldSD, &present, &sacl, &systemDefault))
00141         return GetLastError();
00142 
00143     if (sacl && present)
00144     {
00145         saclSize = sacl->AclSize;
00146     } else saclSize = 0;
00147 
00148     //
00149     // Get DACL
00150     //
00151 
00152     if (!GetSecurityDescriptorDacl (OldSD, &present, &dacl, &systemDefault))
00153         return GetLastError();
00154 
00155     if (dacl && present)
00156     {
00157         daclSize = dacl->AclSize;
00158     } else daclSize = 0;
00159 
00160     //
00161     // Get Owner
00162     //
00163 
00164     if (!GetSecurityDescriptorOwner (OldSD, &ownerSID, &systemDefault))
00165         return GetLastError();
00166 
00167     ownerSIDSize = GetLengthSid (ownerSID);
00168 
00169     //
00170     // Get Group
00171     //
00172 
00173     if (!GetSecurityDescriptorGroup (OldSD, &groupSID, &systemDefault))
00174         return GetLastError();
00175 
00176     groupSIDSize = GetLengthSid (groupSID);
00177 
00178     //
00179     // Do the conversion
00180     //
00181 
00182     descriptorSize = 0;
00183 
00184     MakeAbsoluteSD (OldSD, sd, &descriptorSize, dacl, &daclSize, sacl,
00185                     &saclSize, ownerSID, &ownerSIDSize, groupSID,
00186                     &groupSIDSize);
00187 
00188     sd = (PSECURITY_DESCRIPTOR) new BYTE [SECURITY_DESCRIPTOR_MIN_LENGTH];
00189     if (!InitializeSecurityDescriptor (sd, SECURITY_DESCRIPTOR_REVISION))
00190         return GetLastError();
00191 
00192     if (!MakeAbsoluteSD (OldSD, sd, &descriptorSize, dacl, &daclSize, sacl,
00193                          &saclSize, ownerSID, &ownerSIDSize, groupSID,
00194                          &groupSIDSize))
00195         return GetLastError();
00196 
00197     *NewSD = sd;
00198     return ERROR_SUCCESS;
00199 }
00200 
00201 DWORD
00202 SetNamedValueSD (
00203     HKEY RootKey,
00204     LPTSTR KeyName,
00205     LPTSTR ValueName,
00206     SECURITY_DESCRIPTOR *SD
00207     )
00208 {
00209     DWORD   returnValue = 0;
00210     DWORD   disposition = 0;
00211     HKEY    registryKey;
00212 
00213     //
00214     // Create new key or open existing key
00215     //
00216 
00217     returnValue = RegCreateKeyEx (RootKey, KeyName, 0, TEXT(""), 0, KEY_ALL_ACCESS, NULL, &registryKey, &disposition);
00218     if (returnValue != ERROR_SUCCESS)
00219         return returnValue;
00220 
00221     //
00222     // Write the security descriptor
00223     //
00224 
00225     returnValue = RegSetValueEx (registryKey, ValueName, 0, REG_BINARY, (LPBYTE) SD, GetSecurityDescriptorLength (SD));
00226     if (returnValue != ERROR_SUCCESS)
00227         return returnValue;
00228 
00229     RegCloseKey (registryKey);
00230 
00231     return ERROR_SUCCESS;
00232 }
00233 
00234 DWORD
00235 GetNamedValueSD (
00236     HKEY RootKey,
00237     LPTSTR KeyName,
00238     LPTSTR ValueName,
00239     SECURITY_DESCRIPTOR **SD,
00240     BOOL *NewSD,
00241     bool install_defaults
00242     )
00243 {
00244     DWORD               returnValue = 0;
00245     HKEY                registryKey;
00246     DWORD               valueType = 0;
00247     DWORD               valueSize = 0;
00248 
00249     *NewSD = FALSE;
00250 
00251     //
00252     // Get the security descriptor from the named value. If it doesn't
00253     // exist, create a fresh one.
00254     //
00255 
00256     returnValue = RegOpenKeyEx (RootKey, KeyName, 0, KEY_ALL_ACCESS, &registryKey);
00257 
00258     if (returnValue != ERROR_SUCCESS)
00259     {
00260         if (returnValue == ERROR_FILE_NOT_FOUND)
00261         {
00262             *SD = NULL;
00263             returnValue = CreateNewSD (SD, install_defaults);
00264             if (returnValue != ERROR_SUCCESS)
00265                 return returnValue;
00266 
00267             *NewSD = TRUE;
00268             return ERROR_SUCCESS;
00269         } else
00270             return returnValue;
00271     }
00272 
00273     returnValue = RegQueryValueEx (registryKey, ValueName, NULL, &valueType, NULL, &valueSize);
00274 
00275     if (returnValue && returnValue != ERROR_INSUFFICIENT_BUFFER)
00276     {
00277         *SD = NULL;
00278         returnValue = CreateNewSD (SD, install_defaults);
00279         if (returnValue != ERROR_SUCCESS)
00280             return returnValue;
00281 
00282         *NewSD = TRUE;
00283     } else
00284     {
00285         *SD = (SECURITY_DESCRIPTOR *) malloc (valueSize);
00286 
00287         returnValue = RegQueryValueEx (registryKey, ValueName, NULL, &valueType, (LPBYTE) *SD, &valueSize);
00288         if (returnValue)
00289         {
00290             free (*SD);
00291 
00292             *SD = NULL;
00293             returnValue = CreateNewSD (SD, install_defaults);
00294             if (returnValue != ERROR_SUCCESS)
00295                 return returnValue;
00296 
00297             *NewSD = TRUE;
00298         }
00299     }
00300 
00301     RegCloseKey (registryKey);
00302 
00303     return ERROR_SUCCESS;
00304 }
00305 
00306 DWORD
00307 ListNamedValueSD (
00308     HKEY RootKey,
00309     LPTSTR KeyName,
00310     LPTSTR ValueName
00311     )
00312 {
00313     DWORD               returnValue = 0;
00314     SECURITY_DESCRIPTOR *sd = NIL;
00315     BOOL                present = false;
00316     BOOL                defaultDACL = false;
00317     PACL                dacl = NIL;
00318     BOOL                newSD = FALSE;
00319 
00320     returnValue = GetNamedValueSD (RootKey, KeyName, ValueName, &sd, &newSD);
00321 
00322     if ((returnValue != ERROR_SUCCESS) || (newSD == TRUE))
00323     {
00324         _tprintf (TEXT("<Using Default Permissions>\n"));
00325         free (sd);
00326         return returnValue;
00327     }
00328 
00329     if (!GetSecurityDescriptorDacl (sd, &present, &dacl, &defaultDACL))
00330     {
00331         free (sd);
00332         return GetLastError();
00333     }
00334 
00335     if (!present)
00336     {
00337         _tprintf (TEXT("<Access is denied to everyone>\n"));
00338         free (sd);
00339         return ERROR_SUCCESS;
00340     }
00341 
00342     ListACL (dacl);
00343 
00344     free (sd);
00345 
00346     return ERROR_SUCCESS;
00347 }
00348 
00349 DWORD ZapNamedValueSD(HKEY RootKey, LPTSTR KeyName, LPTSTR ValueName)
00350 {
00351     DWORD               returnValue = 0;
00352     SECURITY_DESCRIPTOR *sd = NIL;
00353     BOOL                present = true;
00354     BOOL                defaultDACL = false;
00355     PACL                dacl = NIL;
00356     BOOL                newSD = FALSE;
00357     HKEY registryKey;
00358 
00359     // first whack the launch permissions.
00360     returnValue = RegOpenKeyEx (HKEY_CLASSES_ROOT, KeyName, 0, KEY_ALL_ACCESS, &registryKey);
00361     if (returnValue != ERROR_SUCCESS && returnValue != ERROR_FILE_NOT_FOUND) {
00362       _tprintf (TEXT("ERROR: Cannot open AppID registry key.\n"));
00363       return returnValue;
00364     }
00365 
00366     returnValue = RegDeleteValue (registryKey, TEXT("LaunchPermission"));
00367     if (returnValue != ERROR_SUCCESS && returnValue != ERROR_FILE_NOT_FOUND) {
00368       _tprintf (TEXT("ERROR: Cannot delete LaunchPermission value.\n"));
00369       return returnValue;
00370     }
00371 
00372     RegCloseKey (registryKey);
00373 
00374     returnValue = AddPrincipalToNamedValueSD(RootKey, KeyName, ValueName,
00375         "Everyone", false, false);
00376     if (returnValue != ERROR_SUCCESS) {
00377       _tprintf (TEXT("ERROR: Cannot deny Everyone.\n"));
00378       return returnValue;
00379     }
00380 
00381     return ERROR_SUCCESS;
00382 }
00383 
00384 DWORD
00385 AddPrincipalToNamedValueSD (
00386     HKEY RootKey,
00387     LPTSTR KeyName,
00388     LPTSTR ValueName,
00389     LPTSTR Principal,
00390     BOOL Permit,
00391     bool install_defaults
00392     )
00393 {
00394     DWORD               returnValue = 0;
00395     SECURITY_DESCRIPTOR *sd = NIL;
00396     SECURITY_DESCRIPTOR *sdSelfRelative = NIL;
00397     SECURITY_DESCRIPTOR *sdAbsolute = NIL;
00398     DWORD               secDescSize = 0;
00399     BOOL                present = false;
00400     BOOL                defaultDACL = false;
00401     PACL                dacl = NIL;
00402     BOOL                newSD = FALSE;
00403 
00404     returnValue = GetNamedValueSD (RootKey, KeyName, ValueName, &sd, &newSD, install_defaults);
00405 
00406     //
00407     // Get security descriptor from registry or create a new one
00408     //
00409 
00410     if (returnValue != ERROR_SUCCESS)
00411         return returnValue;
00412 
00413     if (!GetSecurityDescriptorDacl (sd, &present, &dacl, &defaultDACL))
00414         return GetLastError();
00415 
00416     if (newSD && install_defaults)
00417     {
00418         AddAccessAllowedACEToACL (&dacl, COM_RIGHTS_EXECUTE, TEXT("SYSTEM"));
00419         AddAccessAllowedACEToACL (&dacl, COM_RIGHTS_EXECUTE, TEXT("INTERACTIVE"));
00420     }
00421 
00422     //
00423     // Add the Principal that the caller wants added
00424     //
00425 
00426     if (Permit)
00427         returnValue = AddAccessAllowedACEToACL (&dacl, COM_RIGHTS_EXECUTE, Principal); else
00428         returnValue = AddAccessDeniedACEToACL (&dacl, GENERIC_ALL, Principal);
00429 
00430     if (returnValue != ERROR_SUCCESS)
00431     {
00432         free (sd);
00433         return returnValue;
00434     }
00435 
00436     //
00437     // Make the security descriptor absolute if it isn't new
00438     //
00439 
00440     if (!newSD)
00441         MakeSDAbsolute ((PSECURITY_DESCRIPTOR) sd, (PSECURITY_DESCRIPTOR *) &sdAbsolute); else
00442         sdAbsolute = sd;
00443 
00444     //
00445     // Set the discretionary ACL on the security descriptor
00446     //
00447 
00448     if (!SetSecurityDescriptorDacl (sdAbsolute, TRUE, dacl, FALSE))
00449         return GetLastError();
00450 
00451     //
00452     // Make the security descriptor self-relative so that we can
00453     // store it in the registry
00454     //
00455 
00456     secDescSize = 0;
00457     MakeSelfRelativeSD (sdAbsolute, sdSelfRelative, &secDescSize);
00458     sdSelfRelative = (SECURITY_DESCRIPTOR *) malloc (secDescSize);
00459     if (!MakeSelfRelativeSD (sdAbsolute, sdSelfRelative, &secDescSize))
00460         return GetLastError();
00461 
00462     //
00463     // Store the security descriptor in the registry
00464     //
00465 
00466     SetNamedValueSD (RootKey, KeyName, ValueName, sdSelfRelative);
00467 
00468     free (sd);
00469     free (sdSelfRelative);
00470     free (sdAbsolute);
00471 
00472     return ERROR_SUCCESS;
00473 }
00474 
00475 DWORD
00476 RemovePrincipalFromNamedValueSD (
00477     HKEY RootKey,
00478     LPTSTR KeyName,
00479     LPTSTR ValueName,
00480     LPTSTR Principal,
00481     bool install_defaults
00482     )
00483 {
00484     DWORD               returnValue = 0;
00485     SECURITY_DESCRIPTOR *sd = NIL;
00486     SECURITY_DESCRIPTOR *sdSelfRelative = NIL;
00487     SECURITY_DESCRIPTOR *sdAbsolute = NIL;
00488     DWORD               secDescSize = 0;
00489     BOOL                present = false;
00490     BOOL                defaultDACL = false;
00491     PACL                dacl = NIL;
00492     BOOL                newSD = FALSE;
00493 
00494     returnValue = GetNamedValueSD (RootKey, KeyName, ValueName, &sd, &newSD);
00495 
00496     //
00497     // Get security descriptor from registry or create a new one
00498     //
00499 
00500     if (returnValue != ERROR_SUCCESS)
00501         return returnValue;
00502 
00503     if (!GetSecurityDescriptorDacl (sd, &present, &dacl, &defaultDACL))
00504         return GetLastError();
00505 
00506     //
00507     // If the security descriptor is new, add the required Principals to it
00508     //
00509 
00510     if (newSD && install_defaults)
00511     {
00512         AddAccessAllowedACEToACL (&dacl, COM_RIGHTS_EXECUTE, TEXT("SYSTEM"));
00513         AddAccessAllowedACEToACL (&dacl, COM_RIGHTS_EXECUTE, TEXT("INTERACTIVE"));
00514     }
00515 
00516     //
00517     // Remove the Principal that the caller wants removed
00518     //
00519 
00520     returnValue = RemovePrincipalFromACL (dacl, Principal);
00521     if (returnValue != ERROR_SUCCESS)
00522     {
00523         free (sd);
00524         return returnValue;
00525     }
00526 
00527     //
00528     // Make the security descriptor absolute if it isn't new
00529     //
00530 
00531     if (!newSD)
00532         MakeSDAbsolute ((PSECURITY_DESCRIPTOR) sd, (PSECURITY_DESCRIPTOR *) &sdAbsolute); else
00533         sdAbsolute = sd;
00534 
00535     //
00536     // Set the discretionary ACL on the security descriptor
00537     //
00538 
00539     if (!SetSecurityDescriptorDacl (sdAbsolute, TRUE, dacl, FALSE))
00540         return GetLastError();
00541 
00542     //
00543     // Make the security descriptor self-relative so that we can
00544     // store it in the registry
00545     //
00546 
00547     secDescSize = 0;
00548     MakeSelfRelativeSD (sdAbsolute, sdSelfRelative, &secDescSize);
00549     sdSelfRelative = (SECURITY_DESCRIPTOR *) malloc (secDescSize);
00550     if (!MakeSelfRelativeSD (sdAbsolute, sdSelfRelative, &secDescSize))
00551         return GetLastError();
00552 
00553     //
00554     // Store the security descriptor in the registry
00555     //
00556 
00557     SetNamedValueSD (RootKey, KeyName, ValueName, sdSelfRelative);
00558 
00559     free (sd);
00560     free (sdSelfRelative);
00561     free (sdAbsolute);
00562 
00563     return ERROR_SUCCESS;
00564 }
00565 

Generated on Fri Nov 21 04:28:59 2008 for HOOPLE Libraries by  doxygen 1.5.1