ReactOS Fundraising Campaign 2012
 
€ 4,410 / € 30,000

Information | Donate

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

  1. Home
  2. Community
  3. Development
  4. myReactOS
  5. Fundraiser 2012

  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

sid.c
Go to the documentation of this file.
00001 /*
00002  * COPYRIGHT:       See COPYING in the top level directory
00003  * WINE COPYRIGHT:
00004  * Copyright 1999, 2000 Juergen Schmied <juergen.schmied@debitel.net>
00005  * Copyright 2003 CodeWeavers Inc. (Ulrich Czekalla)
00006  * Copyright 2006 Robert Reif
00007  * Copyright 2006 Hervé Poussineau
00008  *
00009  * PROJECT:         ReactOS system libraries
00010  * FILE:            dll/win32/advapi32/sec/sid.c
00011  * PURPOSE:         Security ID functions
00012  */
00013 
00014 #include <advapi32.h>
00015 WINE_DEFAULT_DEBUG_CHANNEL(advapi);
00016 
00017 #define MAX_GUID_STRING_LEN 39
00018 
00019 BOOL WINAPI
00020 AddAuditAccessAceEx(PACL pAcl,
00021             DWORD dwAceRevision,
00022             DWORD AceFlags,
00023             DWORD dwAccessMask,
00024             PSID pSid,
00025             BOOL bAuditSuccess,
00026             BOOL bAuditFailure);
00027 
00028 typedef struct RECORD
00029 {
00030     LPCWSTR key;
00031     DWORD value;
00032 } RECORD;
00033 
00034 
00035 typedef struct _MAX_SID
00036 {
00037     /* same fields as struct _SID */
00038     BYTE Revision;
00039     BYTE SubAuthorityCount;
00040     SID_IDENTIFIER_AUTHORITY IdentifierAuthority;
00041     DWORD SubAuthority[SID_MAX_SUB_AUTHORITIES];
00042 } MAX_SID;
00043 
00044 typedef struct WELLKNOWNSID
00045 {
00046     WCHAR wstr[2];
00047     WELL_KNOWN_SID_TYPE Type;
00048     MAX_SID Sid;
00049 } WELLKNOWNSID;
00050 
00051 typedef struct _ACEFLAG
00052 {
00053    LPCWSTR wstr;
00054    DWORD value;
00055 } ACEFLAG, *LPACEFLAG;
00056 
00057 static const WELLKNOWNSID WellKnownSids[] =
00058 {
00059     { {0,0}, WinNullSid, { SID_REVISION, 1, { SECURITY_NULL_SID_AUTHORITY }, { SECURITY_NULL_RID } } },
00060     { {'W','D'}, WinWorldSid, { SID_REVISION, 1, { SECURITY_WORLD_SID_AUTHORITY }, { SECURITY_WORLD_RID } } },
00061     { {0,0}, WinLocalSid, { SID_REVISION, 1, { SECURITY_LOCAL_SID_AUTHORITY }, { SECURITY_LOCAL_RID } } },
00062     { {'C','O'}, WinCreatorOwnerSid, { SID_REVISION, 1, { SECURITY_CREATOR_SID_AUTHORITY }, { SECURITY_CREATOR_OWNER_RID } } },
00063     { {'C','G'}, WinCreatorGroupSid, { SID_REVISION, 1, { SECURITY_CREATOR_SID_AUTHORITY }, { SECURITY_CREATOR_GROUP_RID } } },
00064     { {0,0}, WinCreatorOwnerServerSid, { SID_REVISION, 1, { SECURITY_CREATOR_SID_AUTHORITY }, { SECURITY_CREATOR_OWNER_SERVER_RID } } },
00065     { {0,0}, WinCreatorGroupServerSid, { SID_REVISION, 1, { SECURITY_CREATOR_SID_AUTHORITY }, { SECURITY_CREATOR_GROUP_SERVER_RID } } },
00066     { {0,0}, WinNtAuthoritySid, { SID_REVISION, 0, { SECURITY_NT_AUTHORITY }, { SECURITY_NULL_RID } } },
00067     { {0,0}, WinDialupSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_DIALUP_RID } } },
00068     { {'N','U'}, WinNetworkSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_NETWORK_RID } } },
00069     { {0,0}, WinBatchSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_BATCH_RID } } },
00070     { {'I','U'}, WinInteractiveSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_INTERACTIVE_RID } } },
00071     { {'S','U'}, WinServiceSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_SERVICE_RID } } },
00072     { {'A','N'}, WinAnonymousSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_ANONYMOUS_LOGON_RID } } },
00073     { {0,0}, WinProxySid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_PROXY_RID } } },
00074     { {'E','D'}, WinEnterpriseControllersSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_ENTERPRISE_CONTROLLERS_RID } } },
00075     { {'P','S'}, WinSelfSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_PRINCIPAL_SELF_RID } } },
00076     { {'A','U'}, WinAuthenticatedUserSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_AUTHENTICATED_USER_RID } } },
00077     { {'R','C'}, WinRestrictedCodeSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_RESTRICTED_CODE_RID } } },
00078     { {0,0}, WinTerminalServerSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_TERMINAL_SERVER_RID } } },
00079     { {0,0}, WinRemoteLogonIdSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_REMOTE_LOGON_RID } } },
00080     { {'S','Y'}, WinLocalSystemSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_LOCAL_SYSTEM_RID } } },
00081     { {'L','S'}, WinLocalServiceSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_LOCAL_SERVICE_RID } } },
00082     { {'N','S'}, WinNetworkServiceSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_NETWORK_SERVICE_RID } } },
00083     { {0,0}, WinBuiltinDomainSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID } } },
00084     { {'B','A'}, WinBuiltinAdministratorsSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_ADMINS } } },
00085     { {'B','U'}, WinBuiltinUsersSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_USERS } } },
00086     { {'B','G'}, WinBuiltinGuestsSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_GUESTS } } },
00087     { {'P','U'}, WinBuiltinPowerUsersSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_POWER_USERS } } },
00088     { {'A','O'}, WinBuiltinAccountOperatorsSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_ACCOUNT_OPS } } },
00089     { {'S','O'}, WinBuiltinSystemOperatorsSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_SYSTEM_OPS } } },
00090     { {'P','O'}, WinBuiltinPrintOperatorsSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_PRINT_OPS } } },
00091     { {'B','O'}, WinBuiltinBackupOperatorsSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_BACKUP_OPS } } },
00092     { {'R','E'}, WinBuiltinReplicatorSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_REPLICATOR } } },
00093     { {'R','U'}, WinBuiltinPreWindows2000CompatibleAccessSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_PREW2KCOMPACCESS } } },
00094     { {'R','D'}, WinBuiltinRemoteDesktopUsersSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_REMOTE_DESKTOP_USERS } } },
00095     { {'N','O'}, WinBuiltinNetworkConfigurationOperatorsSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_NETWORK_CONFIGURATION_OPS } } },
00096     { {0,0}, WinNTLMAuthenticationSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_PACKAGE_BASE_RID, SECURITY_PACKAGE_NTLM_RID } } },
00097     { {0,0}, WinDigestAuthenticationSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_PACKAGE_BASE_RID, SECURITY_PACKAGE_DIGEST_RID } } },
00098     { {0,0}, WinSChannelAuthenticationSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_PACKAGE_BASE_RID, SECURITY_PACKAGE_SCHANNEL_RID } } },
00099     { {0,0}, WinThisOrganizationSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_THIS_ORGANIZATION_RID } } },
00100     { {0,0}, WinOtherOrganizationSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_OTHER_ORGANIZATION_RID } } },
00101     { {0,0}, WinBuiltinIncomingForestTrustBuildersSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_INCOMING_FOREST_TRUST_BUILDERS  } } },
00102     { {0,0}, WinBuiltinPerfMonitoringUsersSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_MONITORING_USERS } } },
00103     { {0,0}, WinBuiltinPerfLoggingUsersSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_LOGGING_USERS } } },
00104     { {0,0}, WinBuiltinAuthorizationAccessSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_AUTHORIZATIONACCESS } } },
00105     { {0,0}, WinBuiltinTerminalServerLicenseServersSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_TS_LICENSE_SERVERS } } },
00106     { {0,0}, WinBuiltinDCOMUsersSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_DCOM_USERS } } },
00107     { {'L','W'}, WinLowLabelSid, { SID_REVISION, 1, { SECURITY_MANDATORY_LABEL_AUTHORITY}, { SECURITY_MANDATORY_LOW_RID} } },
00108     { {'M','E'}, WinMediumLabelSid, { SID_REVISION, 1, { SECURITY_MANDATORY_LABEL_AUTHORITY}, { SECURITY_MANDATORY_MEDIUM_RID } } },
00109     { {'H','I'}, WinHighLabelSid, { SID_REVISION, 1, { SECURITY_MANDATORY_LABEL_AUTHORITY}, { SECURITY_MANDATORY_HIGH_RID } } },
00110     { {'S','I'}, WinSystemLabelSid, { SID_REVISION, 1, { SECURITY_MANDATORY_LABEL_AUTHORITY}, { SECURITY_MANDATORY_SYSTEM_RID } } },
00111 };
00112 
00113 typedef struct WELLKNOWNRID
00114 {
00115     WELL_KNOWN_SID_TYPE Type;
00116     DWORD Rid;
00117 } WELLKNOWNRID;
00118 
00119 static const WELLKNOWNRID WellKnownRids[] = {
00120     { WinAccountAdministratorSid,    DOMAIN_USER_RID_ADMIN },
00121     { WinAccountGuestSid,            DOMAIN_USER_RID_GUEST },
00122     { WinAccountKrbtgtSid,           DOMAIN_USER_RID_KRBTGT },
00123     { WinAccountDomainAdminsSid,     DOMAIN_GROUP_RID_ADMINS },
00124     { WinAccountDomainUsersSid,      DOMAIN_GROUP_RID_USERS },
00125     { WinAccountDomainGuestsSid,     DOMAIN_GROUP_RID_GUESTS },
00126     { WinAccountComputersSid,        DOMAIN_GROUP_RID_COMPUTERS },
00127     { WinAccountControllersSid,      DOMAIN_GROUP_RID_CONTROLLERS },
00128     { WinAccountCertAdminsSid,       DOMAIN_GROUP_RID_CERT_ADMINS },
00129     { WinAccountSchemaAdminsSid,     DOMAIN_GROUP_RID_SCHEMA_ADMINS },
00130     { WinAccountEnterpriseAdminsSid, DOMAIN_GROUP_RID_ENTERPRISE_ADMINS },
00131     { WinAccountPolicyAdminsSid,     DOMAIN_GROUP_RID_POLICY_ADMINS },
00132     { WinAccountRasAndIasServersSid, DOMAIN_ALIAS_RID_RAS_SERVERS },
00133 };
00134 
00135 static const SID sidWorld = { SID_REVISION, 1, { SECURITY_WORLD_SID_AUTHORITY} , { SECURITY_WORLD_RID } };
00136 
00137 /*
00138  * ACE types
00139  */
00140 static const WCHAR SDDL_ACCESS_ALLOWED[]        = {'A',0};
00141 static const WCHAR SDDL_ACCESS_DENIED[]         = {'D',0};
00142 static const WCHAR SDDL_OBJECT_ACCESS_ALLOWED[] = {'O','A',0};
00143 static const WCHAR SDDL_OBJECT_ACCESS_DENIED[]  = {'O','D',0};
00144 static const WCHAR SDDL_AUDIT[]                 = {'A','U',0};
00145 static const WCHAR SDDL_ALARM[]                 = {'A','L',0};
00146 static const WCHAR SDDL_OBJECT_AUDIT[]          = {'O','U',0};
00147 static const WCHAR SDDL_OBJECT_ALARM[]          = {'O','L',0};
00148 
00149 /*
00150  * SDDL ADS Rights
00151  */
00152 #define ADS_RIGHT_DS_CREATE_CHILD   0x0001
00153 #define ADS_RIGHT_DS_DELETE_CHILD   0x0002
00154 #define ADS_RIGHT_ACTRL_DS_LIST     0x0004
00155 #define ADS_RIGHT_DS_SELF           0x0008
00156 #define ADS_RIGHT_DS_READ_PROP      0x0010
00157 #define ADS_RIGHT_DS_WRITE_PROP     0x0020
00158 #define ADS_RIGHT_DS_DELETE_TREE    0x0040
00159 #define ADS_RIGHT_DS_LIST_OBJECT    0x0080
00160 #define ADS_RIGHT_DS_CONTROL_ACCESS 0x0100
00161 
00162 /*
00163  * ACE flags
00164  */
00165 static const WCHAR SDDL_CONTAINER_INHERIT[]  = {'C','I',0};
00166 static const WCHAR SDDL_OBJECT_INHERIT[]     = {'O','I',0};
00167 static const WCHAR SDDL_NO_PROPAGATE[]       = {'N','P',0};
00168 static const WCHAR SDDL_INHERIT_ONLY[]       = {'I','O',0};
00169 static const WCHAR SDDL_INHERITED[]          = {'I','D',0};
00170 static const WCHAR SDDL_AUDIT_SUCCESS[]      = {'S','A',0};
00171 static const WCHAR SDDL_AUDIT_FAILURE[]      = {'F','A',0};
00172 
00173 static const char * debugstr_sid(PSID sid)
00174 {
00175     int auth = 0;
00176     SID * psid = (SID *)sid;
00177 
00178     if (psid == NULL)
00179         return "(null)";
00180 
00181     auth = psid->IdentifierAuthority.Value[5] +
00182            (psid->IdentifierAuthority.Value[4] << 8) +
00183            (psid->IdentifierAuthority.Value[3] << 16) +
00184            (psid->IdentifierAuthority.Value[2] << 24);
00185 
00186     switch (psid->SubAuthorityCount) {
00187     case 0:
00188         return wine_dbg_sprintf("S-%d-%d", psid->Revision, auth);
00189     case 1:
00190         return wine_dbg_sprintf("S-%d-%d-%lu", psid->Revision, auth,
00191             psid->SubAuthority[0]);
00192     case 2:
00193         return wine_dbg_sprintf("S-%d-%d-%lu-%lu", psid->Revision, auth,
00194             psid->SubAuthority[0], psid->SubAuthority[1]);
00195     case 3:
00196         return wine_dbg_sprintf("S-%d-%d-%lu-%lu-%lu", psid->Revision, auth,
00197             psid->SubAuthority[0], psid->SubAuthority[1], psid->SubAuthority[2]);
00198     case 4:
00199         return wine_dbg_sprintf("S-%d-%d-%lu-%lu-%lu-%lu", psid->Revision, auth,
00200             psid->SubAuthority[0], psid->SubAuthority[1], psid->SubAuthority[2],
00201             psid->SubAuthority[3]);
00202     case 5:
00203         return wine_dbg_sprintf("S-%d-%d-%lu-%lu-%lu-%lu-%lu", psid->Revision, auth,
00204             psid->SubAuthority[0], psid->SubAuthority[1], psid->SubAuthority[2],
00205             psid->SubAuthority[3], psid->SubAuthority[4]);
00206     case 6:
00207         return wine_dbg_sprintf("S-%d-%d-%lu-%lu-%lu-%lu-%lu-%lu", psid->Revision, auth,
00208             psid->SubAuthority[3], psid->SubAuthority[1], psid->SubAuthority[2],
00209             psid->SubAuthority[0], psid->SubAuthority[4], psid->SubAuthority[5]);
00210     case 7:
00211         return wine_dbg_sprintf("S-%d-%d-%lu-%lu-%lu-%lu-%lu-%lu-%lu", psid->Revision, auth,
00212             psid->SubAuthority[0], psid->SubAuthority[1], psid->SubAuthority[2],
00213             psid->SubAuthority[3], psid->SubAuthority[4], psid->SubAuthority[5],
00214             psid->SubAuthority[6]);
00215     case 8:
00216         return wine_dbg_sprintf("S-%d-%d-%lu-%lu-%lu-%lu-%lu-%lu-%lu-%lu", psid->Revision, auth,
00217             psid->SubAuthority[0], psid->SubAuthority[1], psid->SubAuthority[2],
00218             psid->SubAuthority[3], psid->SubAuthority[4], psid->SubAuthority[5],
00219             psid->SubAuthority[6], psid->SubAuthority[7]);
00220     }
00221     return "(too-big)";
00222 }
00223 
00224 static const ACEFLAG AceRights[] =
00225 {
00226     { SDDL_GENERIC_ALL,     GENERIC_ALL },
00227     { SDDL_GENERIC_READ,    GENERIC_READ },
00228     { SDDL_GENERIC_WRITE,   GENERIC_WRITE },
00229     { SDDL_GENERIC_EXECUTE, GENERIC_EXECUTE },
00230 
00231     { SDDL_READ_CONTROL,    READ_CONTROL },
00232     { SDDL_STANDARD_DELETE, DELETE },
00233     { SDDL_WRITE_DAC,       WRITE_DAC },
00234     { SDDL_WRITE_OWNER,     WRITE_OWNER },
00235 
00236     { SDDL_READ_PROPERTY,   ADS_RIGHT_DS_READ_PROP},
00237     { SDDL_WRITE_PROPERTY,  ADS_RIGHT_DS_WRITE_PROP},
00238     { SDDL_CREATE_CHILD,    ADS_RIGHT_DS_CREATE_CHILD},
00239     { SDDL_DELETE_CHILD,    ADS_RIGHT_DS_DELETE_CHILD},
00240     { SDDL_LIST_CHILDREN,   ADS_RIGHT_ACTRL_DS_LIST},
00241     { SDDL_SELF_WRITE,      ADS_RIGHT_DS_SELF},
00242     { SDDL_LIST_OBJECT,     ADS_RIGHT_DS_LIST_OBJECT},
00243     { SDDL_DELETE_TREE,     ADS_RIGHT_DS_DELETE_TREE},
00244     { SDDL_CONTROL_ACCESS,  ADS_RIGHT_DS_CONTROL_ACCESS},
00245 
00246     { SDDL_FILE_ALL,        FILE_ALL_ACCESS },
00247     { SDDL_FILE_READ,       FILE_GENERIC_READ },
00248     { SDDL_FILE_WRITE,      FILE_GENERIC_WRITE },
00249     { SDDL_FILE_EXECUTE,    FILE_GENERIC_EXECUTE },
00250 
00251     { SDDL_KEY_ALL,         KEY_ALL_ACCESS },
00252     { SDDL_KEY_READ,        KEY_READ },
00253     { SDDL_KEY_WRITE,       KEY_WRITE },
00254     { SDDL_KEY_EXECUTE,     KEY_EXECUTE },
00255     { NULL, 0 },
00256 };
00257 
00258 static const LPCWSTR AceRightBitNames[32] = {
00259         SDDL_CREATE_CHILD,        /*  0 */
00260         SDDL_DELETE_CHILD,
00261         SDDL_LIST_CHILDREN,
00262         SDDL_SELF_WRITE,
00263         SDDL_READ_PROPERTY,       /*  4 */
00264         SDDL_WRITE_PROPERTY,
00265         SDDL_DELETE_TREE,
00266         SDDL_LIST_OBJECT,
00267         SDDL_CONTROL_ACCESS,      /*  8 */
00268         NULL,
00269         NULL,
00270         NULL,
00271         NULL,                     /* 12 */
00272         NULL,
00273         NULL,
00274         NULL,
00275         SDDL_STANDARD_DELETE,     /* 16 */
00276         SDDL_READ_CONTROL,
00277         SDDL_WRITE_DAC,
00278         SDDL_WRITE_OWNER,
00279         NULL,                     /* 20 */
00280         NULL,
00281         NULL,
00282         NULL,
00283         NULL,                     /* 24 */
00284         NULL,
00285         NULL,
00286         NULL,
00287         SDDL_GENERIC_ALL,         /* 28 */
00288         SDDL_GENERIC_EXECUTE,
00289         SDDL_GENERIC_WRITE,
00290         SDDL_GENERIC_READ
00291 };
00292 
00293 
00294 /* set last error code from NT status and get the proper boolean return value */
00295 /* used for functions that are a simple wrapper around the corresponding ntdll API */
00296 static __inline BOOL set_ntstatus( NTSTATUS status )
00297 {
00298     if (status) SetLastError( RtlNtStatusToDosError( status ));
00299     return !status;
00300 }
00301 
00302 /************************************************************
00303  *                ADVAPI_GetComputerSid
00304  *
00305  * Reads the computer SID from the registry.
00306  */
00307 BOOL ADVAPI_GetComputerSid(PSID sid)
00308 {
00309     HKEY key;
00310     LONG ret;
00311     BOOL retval = FALSE;
00312     static const WCHAR Account[] = { 'S','E','C','U','R','I','T','Y','\\','S','A','M','\\','D','o','m','a','i','n','s','\\','A','c','c','o','u','n','t',0 };
00313     static const WCHAR V[] = { 'V',0 };
00314 
00315     if ((ret = RegOpenKeyExW(HKEY_LOCAL_MACHINE, Account, 0,
00316         KEY_READ, &key)) == ERROR_SUCCESS)
00317     {
00318         DWORD size = 0;
00319         ret = RegQueryValueExW(key, V, NULL, NULL, NULL, &size);
00320         if (ret == ERROR_MORE_DATA || ret == ERROR_SUCCESS)
00321         {
00322             BYTE * data = HeapAlloc(GetProcessHeap(), 0, size);
00323             if (data)
00324             {
00325                 if ((ret = RegQueryValueExW(key, V, NULL, NULL,
00326                      data, &size)) == ERROR_SUCCESS)
00327                 {
00328                     /* the SID is in the last 24 bytes of the binary data */
00329                     CopyMemory(sid, &data[size-24], 24);
00330                     retval = TRUE;
00331                 }
00332                 HeapFree(GetProcessHeap(), 0, data);
00333             }
00334         }
00335         RegCloseKey(key);
00336     }
00337 
00338     if(retval == TRUE) return retval;
00339 
00340     /* create a new random SID */
00341     if (RegCreateKeyExW(HKEY_LOCAL_MACHINE, Account,
00342         0, NULL, 0, KEY_ALL_ACCESS, NULL, &key, NULL) == ERROR_SUCCESS)
00343     {
00344         PSID new_sid;
00345         SID_IDENTIFIER_AUTHORITY identifierAuthority = {SECURITY_NT_AUTHORITY};
00346         DWORD id[3];
00347 
00348         if (RtlGenRandom(id, sizeof(id)))
00349         {
00350             if (AllocateAndInitializeSid(&identifierAuthority, 4, SECURITY_NT_NON_UNIQUE, id[0], id[1], id[2], 0, 0, 0, 0, &new_sid))
00351             {
00352                 if (RegSetValueExW(key, V, 0, REG_BINARY, new_sid, GetLengthSid(new_sid)) == ERROR_SUCCESS)
00353                     retval = CopySid(GetLengthSid(new_sid), sid, new_sid);
00354 
00355                 FreeSid(new_sid);
00356             }
00357         }
00358         RegCloseKey(key);
00359     }
00360 
00361     return retval;
00362 }
00363 
00364 /* Exported functions */
00365 
00366 /*
00367  * @implemented
00368  */
00369 BOOL WINAPI
00370 AllocateLocallyUniqueId(PLUID Luid)
00371 {
00372     NTSTATUS Status;
00373 
00374     Status = NtAllocateLocallyUniqueId (Luid);
00375     if (!NT_SUCCESS (Status))
00376     {
00377         SetLastError(RtlNtStatusToDosError(Status));
00378         return FALSE;
00379     }
00380 
00381     return TRUE;
00382 }
00383 
00384 
00385 /*
00386  * @implemented
00387  */
00388 BOOL WINAPI
00389 AllocateAndInitializeSid(PSID_IDENTIFIER_AUTHORITY pIdentifierAuthority,
00390                          BYTE nSubAuthorityCount,
00391                          DWORD dwSubAuthority0,
00392                          DWORD dwSubAuthority1,
00393                          DWORD dwSubAuthority2,
00394                          DWORD dwSubAuthority3,
00395                          DWORD dwSubAuthority4,
00396                          DWORD dwSubAuthority5,
00397                          DWORD dwSubAuthority6,
00398                          DWORD dwSubAuthority7,
00399                          PSID *pSid)
00400 {
00401     NTSTATUS Status;
00402 
00403     Status = RtlAllocateAndInitializeSid(pIdentifierAuthority,
00404                                          nSubAuthorityCount,
00405                                          dwSubAuthority0,
00406                                          dwSubAuthority1,
00407                                          dwSubAuthority2,
00408                                          dwSubAuthority3,
00409                                          dwSubAuthority4,
00410                                          dwSubAuthority5,
00411                                          dwSubAuthority6,
00412                                          dwSubAuthority7,
00413                                          pSid);
00414     if (!NT_SUCCESS(Status))
00415     {
00416         SetLastError(RtlNtStatusToDosError(Status));
00417         return FALSE;
00418     }
00419 
00420     return TRUE;
00421 }
00422 
00423 
00424 /*
00425  * @implemented
00426  */
00427 BOOL WINAPI
00428 CopySid(DWORD nDestinationSidLength,
00429         PSID pDestinationSid,
00430         PSID pSourceSid)
00431 {
00432     NTSTATUS Status;
00433 
00434     Status = RtlCopySid(nDestinationSidLength,
00435                         pDestinationSid,
00436                         pSourceSid);
00437     if (!NT_SUCCESS (Status))
00438     {
00439         SetLastError(RtlNtStatusToDosError(Status));
00440         return FALSE;
00441     }
00442 
00443   return TRUE;
00444 }
00445 
00446 static void DumpString(LPCWSTR string, int cch, WCHAR **pwptr, ULONG *plen)
00447 {
00448     if (cch == -1)
00449         cch = strlenW(string);
00450 
00451     if (plen)
00452         *plen += cch;
00453 
00454     if (pwptr)
00455     {
00456         memcpy(*pwptr, string, sizeof(WCHAR)*cch);
00457         *pwptr += cch;
00458     }
00459 }
00460 
00461 static BOOL DumpSidNumeric(PSID psid, WCHAR **pwptr, ULONG *plen)
00462 {
00463     DWORD i;
00464     WCHAR fmt[] = { 'S','-','%','u','-','%','d',0 };
00465     WCHAR subauthfmt[] = { '-','%','u',0 };
00466     WCHAR buf[26];
00467     SID *pisid = psid;
00468 
00469     if( !IsValidSid( psid ) || pisid->Revision != SDDL_REVISION)
00470     {
00471         SetLastError(ERROR_INVALID_SID);
00472         return FALSE;
00473     }
00474 
00475     if (pisid->IdentifierAuthority.Value[0] ||
00476      pisid->IdentifierAuthority.Value[1])
00477     {
00478         FIXME("not matching MS' bugs\n");
00479         SetLastError(ERROR_INVALID_SID);
00480         return FALSE;
00481     }
00482 
00483     sprintfW( buf, fmt, pisid->Revision,
00484         MAKELONG(
00485             MAKEWORD( pisid->IdentifierAuthority.Value[5],
00486                     pisid->IdentifierAuthority.Value[4] ),
00487             MAKEWORD( pisid->IdentifierAuthority.Value[3],
00488                     pisid->IdentifierAuthority.Value[2] )
00489         ) );
00490     DumpString(buf, -1, pwptr, plen);
00491 
00492     for( i=0; i<pisid->SubAuthorityCount; i++ )
00493     {
00494         sprintfW( buf, subauthfmt, pisid->SubAuthority[i] );
00495         DumpString(buf, -1, pwptr, plen);
00496     }
00497     return TRUE;
00498 }
00499 
00500 static BOOL DumpSid(PSID psid, WCHAR **pwptr, ULONG *plen)
00501 {
00502     size_t i;
00503     for (i = 0; i < sizeof(WellKnownSids) / sizeof(WellKnownSids[0]); i++)
00504     {
00505         if (WellKnownSids[i].wstr[0] && EqualSid(psid, (PSID)&(WellKnownSids[i].Sid.Revision)))
00506         {
00507             DumpString(WellKnownSids[i].wstr, 2, pwptr, plen);
00508             return TRUE;
00509         }
00510     }
00511 
00512     return DumpSidNumeric(psid, pwptr, plen);
00513 }
00514 
00515 static void DumpRights(DWORD mask, WCHAR **pwptr, ULONG *plen)
00516 {
00517     static const WCHAR fmtW[] = {'0','x','%','x',0};
00518     WCHAR buf[15];
00519     size_t i;
00520 
00521     if (mask == 0)
00522         return;
00523 
00524     /* first check if the right have name */
00525     for (i = 0; i < sizeof(AceRights)/sizeof(AceRights[0]); i++)
00526     {
00527         if (AceRights[i].wstr == NULL)
00528             break;
00529         if (mask == AceRights[i].value)
00530         {
00531             DumpString(AceRights[i].wstr, -1, pwptr, plen);
00532             return;
00533         }
00534     }
00535 
00536     /* then check if it can be built from bit names */
00537     for (i = 0; i < 32; i++)
00538     {
00539         if ((mask & (1 << i)) && (AceRightBitNames[i] == NULL))
00540         {
00541             /* can't be built from bit names */
00542             sprintfW(buf, fmtW, mask);
00543             DumpString(buf, -1, pwptr, plen);
00544             return;
00545         }
00546     }
00547 
00548     /* build from bit names */
00549     for (i = 0; i < 32; i++)
00550         if (mask & (1 << i))
00551             DumpString(AceRightBitNames[i], -1, pwptr, plen);
00552 }
00553 
00554 static BOOL DumpAce(LPVOID pace, WCHAR **pwptr, ULONG *plen)
00555 {
00556     ACCESS_ALLOWED_ACE *piace; /* all the supported ACEs have the same memory layout */
00557     static const WCHAR openbr = '(';
00558     static const WCHAR closebr = ')';
00559     static const WCHAR semicolon = ';';
00560 
00561     if (((PACE_HEADER)pace)->AceType > SYSTEM_ALARM_ACE_TYPE || ((PACE_HEADER)pace)->AceSize < sizeof(ACCESS_ALLOWED_ACE))
00562     {
00563         SetLastError(ERROR_INVALID_ACL);
00564         return FALSE;
00565     }
00566 
00567     piace = pace;
00568     DumpString(&openbr, 1, pwptr, plen);
00569     switch (piace->Header.AceType)
00570     {
00571         case ACCESS_ALLOWED_ACE_TYPE:
00572             DumpString(SDDL_ACCESS_ALLOWED, -1, pwptr, plen);
00573             break;
00574         case ACCESS_DENIED_ACE_TYPE:
00575             DumpString(SDDL_ACCESS_DENIED, -1, pwptr, plen);
00576             break;
00577         case SYSTEM_AUDIT_ACE_TYPE:
00578             DumpString(SDDL_AUDIT, -1, pwptr, plen);
00579             break;
00580         case SYSTEM_ALARM_ACE_TYPE:
00581             DumpString(SDDL_ALARM, -1, pwptr, plen);
00582             break;
00583     }
00584     DumpString(&semicolon, 1, pwptr, plen);
00585 
00586     if (piace->Header.AceFlags & OBJECT_INHERIT_ACE)
00587         DumpString(SDDL_OBJECT_INHERIT, -1, pwptr, plen);
00588     if (piace->Header.AceFlags & CONTAINER_INHERIT_ACE)
00589         DumpString(SDDL_CONTAINER_INHERIT, -1, pwptr, plen);
00590     if (piace->Header.AceFlags & NO_PROPAGATE_INHERIT_ACE)
00591         DumpString(SDDL_NO_PROPAGATE, -1, pwptr, plen);
00592     if (piace->Header.AceFlags & INHERIT_ONLY_ACE)
00593         DumpString(SDDL_INHERIT_ONLY, -1, pwptr, plen);
00594     if (piace->Header.AceFlags & INHERITED_ACE)
00595         DumpString(SDDL_INHERITED, -1, pwptr, plen);
00596     if (piace->Header.AceFlags & SUCCESSFUL_ACCESS_ACE_FLAG)
00597         DumpString(SDDL_AUDIT_SUCCESS, -1, pwptr, plen);
00598     if (piace->Header.AceFlags & FAILED_ACCESS_ACE_FLAG)
00599         DumpString(SDDL_AUDIT_FAILURE, -1, pwptr, plen);
00600     DumpString(&semicolon, 1, pwptr, plen);
00601     DumpRights(piace->Mask, pwptr, plen);
00602     DumpString(&semicolon, 1, pwptr, plen);
00603     /* objects not supported */
00604     DumpString(&semicolon, 1, pwptr, plen);
00605     /* objects not supported */
00606     DumpString(&semicolon, 1, pwptr, plen);
00607     if (!DumpSid((PSID)&piace->SidStart, pwptr, plen))
00608         return FALSE;
00609     DumpString(&closebr, 1, pwptr, plen);
00610     return TRUE;
00611 }
00612 
00613 static BOOL DumpAcl(PACL pacl, WCHAR **pwptr, ULONG *plen, BOOL protected, BOOL autoInheritReq, BOOL autoInherited)
00614 {
00615     WORD count;
00616     int i;
00617 
00618     if (protected)
00619         DumpString(SDDL_PROTECTED, -1, pwptr, plen);
00620     if (autoInheritReq)
00621         DumpString(SDDL_AUTO_INHERIT_REQ, -1, pwptr, plen);
00622     if (autoInherited)
00623         DumpString(SDDL_AUTO_INHERITED, -1, pwptr, plen);
00624 
00625     if (pacl == NULL)
00626         return TRUE;
00627 
00628     if (!IsValidAcl(pacl))
00629         return FALSE;
00630 
00631     count = pacl->AceCount;
00632     for (i = 0; i < count; i++)
00633     {
00634         LPVOID ace;
00635         if (!GetAce(pacl, i, &ace))
00636             return FALSE;
00637         if (!DumpAce(ace, pwptr, plen))
00638             return FALSE;
00639     }
00640 
00641     return TRUE;
00642 }
00643 
00644 static BOOL DumpOwner(PSECURITY_DESCRIPTOR SecurityDescriptor, WCHAR **pwptr, ULONG *plen)
00645 {
00646     static const WCHAR prefix[] = {'O',':',0};
00647     BOOL bDefaulted;
00648     PSID psid;
00649 
00650     if (!GetSecurityDescriptorOwner(SecurityDescriptor, &psid, &bDefaulted))
00651         return FALSE;
00652 
00653     if (psid == NULL)
00654         return TRUE;
00655 
00656     DumpString(prefix, -1, pwptr, plen);
00657     if (!DumpSid(psid, pwptr, plen))
00658         return FALSE;
00659     return TRUE;
00660 }
00661 
00662 static BOOL DumpGroup(PSECURITY_DESCRIPTOR SecurityDescriptor, WCHAR **pwptr, ULONG *plen)
00663 {
00664     static const WCHAR prefix[] = {'G',':',0};
00665     BOOL bDefaulted;
00666     PSID psid;
00667 
00668     if (!GetSecurityDescriptorGroup(SecurityDescriptor, &psid, &bDefaulted))
00669         return FALSE;
00670 
00671     if (psid == NULL)
00672         return TRUE;
00673 
00674     DumpString(prefix, -1, pwptr, plen);
00675     if (!DumpSid(psid, pwptr, plen))
00676         return FALSE;
00677     return TRUE;
00678 }
00679 
00680 static BOOL DumpDacl(PSECURITY_DESCRIPTOR SecurityDescriptor, WCHAR **pwptr, ULONG *plen)
00681 {
00682     static const WCHAR dacl[] = {'D',':',0};
00683     SECURITY_DESCRIPTOR_CONTROL control;
00684     BOOL present, defaulted;
00685     DWORD revision;
00686     PACL pacl;
00687 
00688     if (!GetSecurityDescriptorDacl(SecurityDescriptor, &present, &pacl, &defaulted))
00689         return FALSE;
00690 
00691     if (!GetSecurityDescriptorControl(SecurityDescriptor, &control, &revision))
00692         return FALSE;
00693 
00694     if (!present)
00695         return TRUE;
00696 
00697     DumpString(dacl, 2, pwptr, plen);
00698     if (!DumpAcl(pacl, pwptr, plen, control & SE_DACL_PROTECTED, control & SE_DACL_AUTO_INHERIT_REQ, control & SE_DACL_AUTO_INHERITED))
00699         return FALSE;
00700     return TRUE;
00701 }
00702 
00703 static BOOL DumpSacl(PSECURITY_DESCRIPTOR SecurityDescriptor, WCHAR **pwptr, ULONG *plen)
00704 {
00705     static const WCHAR sacl[] = {'S',':',0};
00706     SECURITY_DESCRIPTOR_CONTROL control;
00707     BOOL present, defaulted;
00708     DWORD revision;
00709     PACL pacl;
00710 
00711     if (!GetSecurityDescriptorSacl(SecurityDescriptor, &present, &pacl, &defaulted))
00712         return FALSE;
00713 
00714     if (!GetSecurityDescriptorControl(SecurityDescriptor, &control, &revision))
00715         return FALSE;
00716 
00717     if (!present)
00718         return TRUE;
00719 
00720     DumpString(sacl, 2, pwptr, plen);
00721     if (!DumpAcl(pacl, pwptr, plen, control & SE_SACL_PROTECTED, control & SE_SACL_AUTO_INHERIT_REQ, control & SE_SACL_AUTO_INHERITED))
00722         return FALSE;
00723     return TRUE;
00724 }
00725 
00726 /******************************************************************************
00727  * ConvertSecurityDescriptorToStringSecurityDescriptorW [ADVAPI32.@]
00728  * @implemented
00729  */
00730 BOOL WINAPI
00731 ConvertSecurityDescriptorToStringSecurityDescriptorW(PSECURITY_DESCRIPTOR SecurityDescriptor,
00732                                                      DWORD SDRevision,
00733                                                      SECURITY_INFORMATION SecurityInformation,
00734                                                      LPWSTR *OutputString,
00735                                                      PULONG OutputLen)
00736 {
00737     ULONG len;
00738     WCHAR *wptr, *wstr;
00739 
00740     if (SDRevision != SDDL_REVISION_1)
00741     {
00742         ERR("Pogram requested unknown SDDL revision %d\n", SDRevision);
00743         SetLastError(ERROR_UNKNOWN_REVISION);
00744         return FALSE;
00745     }
00746 
00747     len = 0;
00748     if (SecurityInformation & OWNER_SECURITY_INFORMATION)
00749         if (!DumpOwner(SecurityDescriptor, NULL, &len))
00750             return FALSE;
00751     if (SecurityInformation & GROUP_SECURITY_INFORMATION)
00752         if (!DumpGroup(SecurityDescriptor, NULL, &len))
00753             return FALSE;
00754     if (SecurityInformation & DACL_SECURITY_INFORMATION)
00755         if (!DumpDacl(SecurityDescriptor, NULL, &len))
00756             return FALSE;
00757     if (SecurityInformation & SACL_SECURITY_INFORMATION)
00758         if (!DumpSacl(SecurityDescriptor, NULL, &len))
00759             return FALSE;
00760 
00761     wstr = wptr = LocalAlloc(0, (len + 1)*sizeof(WCHAR));
00762     if (SecurityInformation & OWNER_SECURITY_INFORMATION)
00763         if (!DumpOwner(SecurityDescriptor, &wptr, NULL))
00764             return FALSE;
00765     if (SecurityInformation & GROUP_SECURITY_INFORMATION)
00766         if (!DumpGroup(SecurityDescriptor, &wptr, NULL))
00767             return FALSE;
00768     if (SecurityInformation & DACL_SECURITY_INFORMATION)
00769         if (!DumpDacl(SecurityDescriptor, &wptr, NULL))
00770             return FALSE;
00771     if (SecurityInformation & SACL_SECURITY_INFORMATION)
00772         if (!DumpSacl(SecurityDescriptor, &wptr, NULL))
00773             return FALSE;
00774     *wptr = 0;
00775 
00776     TRACE("ret: %s, %d\n", wine_dbgstr_w(wstr), len);
00777     *OutputString = wstr;
00778     if (OutputLen)
00779         *OutputLen = strlenW(*OutputString)+1;
00780     return TRUE;
00781 }
00782 
00783 
00784 /******************************************************************************
00785  * ConvertSecurityDescriptorToStringSecurityDescriptorA [ADVAPI32.@]
00786  * @implemented
00787  */
00788 BOOL WINAPI
00789 ConvertSecurityDescriptorToStringSecurityDescriptorA(PSECURITY_DESCRIPTOR SecurityDescriptor,
00790                                                      DWORD SDRevision,
00791                                                      SECURITY_INFORMATION Information,
00792                                                      LPSTR *OutputString,
00793                                                      PULONG OutputLen)
00794 {
00795     LPWSTR wstr;
00796     ULONG len;
00797     if (ConvertSecurityDescriptorToStringSecurityDescriptorW(SecurityDescriptor, SDRevision, Information, &wstr, &len))
00798     {
00799         int lenA;
00800 
00801         lenA = WideCharToMultiByte(CP_ACP, 0, wstr, len, NULL, 0, NULL, NULL);
00802         *OutputString = HeapAlloc(GetProcessHeap(), 0, lenA);
00803         WideCharToMultiByte(CP_ACP, 0, wstr, len, *OutputString, lenA, NULL, NULL);
00804         LocalFree(wstr);
00805 
00806         if (OutputLen != NULL)
00807             *OutputLen = lenA;
00808         return TRUE;
00809     }
00810     else
00811     {
00812         *OutputString = NULL;
00813         if (OutputLen)
00814             *OutputLen = 0;
00815         return FALSE;
00816     }
00817 }
00818 
00819 
00820 /******************************************************************************
00821  * ComputeStringSidSize
00822  */
00823 static DWORD ComputeStringSidSize(LPCWSTR StringSid)
00824 {
00825     if (StringSid[0] == 'S' && StringSid[1] == '-') /* S-R-I(-S)+ */
00826     {
00827         int ctok = 0;
00828         while (*StringSid)
00829         {
00830             if (*StringSid == '-')
00831                 ctok++;
00832             StringSid++;
00833         }
00834 
00835         if (ctok >= 3)
00836             return GetSidLengthRequired(ctok - 2);
00837     }
00838     else /* String constant format  - Only available in winxp and above */
00839     {
00840         unsigned int i;
00841 
00842         for (i = 0; i < sizeof(WellKnownSids)/sizeof(WellKnownSids[0]); i++)
00843             if (!strncmpW(WellKnownSids[i].wstr, StringSid, 2))
00844                 return GetSidLengthRequired(WellKnownSids[i].Sid.SubAuthorityCount);
00845     }
00846 
00847     return GetSidLengthRequired(0);
00848 }
00849 
00850 /******************************************************************************
00851  * ParseStringSidToSid
00852  */
00853 static BOOL ParseStringSidToSid(LPCWSTR StringSid, PSID pSid, LPDWORD cBytes)
00854 {
00855     BOOL bret = FALSE;
00856     SID* pisid=pSid;
00857 
00858     TRACE("%s, %p, %p\n", debugstr_w(StringSid), pSid, cBytes);
00859     if (!StringSid)
00860     {
00861         SetLastError(ERROR_INVALID_PARAMETER);
00862         TRACE("StringSid is NULL, returning FALSE\n");
00863         return FALSE;
00864     }
00865 
00866     while (*StringSid == ' ')
00867         StringSid++;
00868 
00869     *cBytes = ComputeStringSidSize(StringSid);
00870     if (!pisid) /* Simply compute the size */
00871     {
00872         TRACE("only size requested, returning TRUE\n");
00873         return TRUE;
00874     }
00875 
00876     if (StringSid[0] == 'S' && StringSid[1] == '-') /* S-R-I-S-S */
00877     {
00878         DWORD i = 0, identAuth;
00879         DWORD csubauth = ((*cBytes - GetSidLengthRequired(0)) / sizeof(DWORD));
00880 
00881         StringSid += 2; /* Advance to Revision */
00882         pisid->Revision = atoiW(StringSid);
00883 
00884         if (pisid->Revision != SDDL_REVISION)
00885         {
00886             TRACE("Revision %d is unknown\n", pisid->Revision);
00887             goto lend; /* ERROR_INVALID_SID */
00888         }
00889         if (csubauth == 0)
00890         {
00891             TRACE("SubAuthorityCount is 0\n");
00892             goto lend; /* ERROR_INVALID_SID */
00893         }
00894 
00895         pisid->SubAuthorityCount = csubauth;
00896 
00897         /* Advance to identifier authority */
00898         while (*StringSid && *StringSid != '-')
00899             StringSid++;
00900         if (*StringSid == '-')
00901             StringSid++;
00902 
00903         /* MS' implementation can't handle values greater than 2^32 - 1, so
00904          * we don't either; assume most significant bytes are always 0
00905          */
00906         pisid->IdentifierAuthority.Value[0] = 0;
00907         pisid->IdentifierAuthority.Value[1] = 0;
00908         identAuth = atoiW(StringSid);
00909         pisid->IdentifierAuthority.Value[5] = identAuth & 0xff;
00910         pisid->IdentifierAuthority.Value[4] = (identAuth & 0xff00) >> 8;
00911         pisid->IdentifierAuthority.Value[3] = (identAuth & 0xff0000) >> 16;
00912         pisid->IdentifierAuthority.Value[2] = (identAuth & 0xff000000) >> 24;
00913 
00914         /* Advance to first sub authority */
00915         while (*StringSid && *StringSid != '-')
00916             StringSid++;
00917         if (*StringSid == '-')
00918             StringSid++;
00919 
00920         while (*StringSid)
00921         {
00922             pisid->SubAuthority[i++] = atoiW(StringSid);
00923 
00924             while (*StringSid && *StringSid != '-')
00925                 StringSid++;
00926             if (*StringSid == '-')
00927                 StringSid++;
00928         }
00929 
00930         if (i != pisid->SubAuthorityCount)
00931             goto lend; /* ERROR_INVALID_SID */
00932 
00933         bret = TRUE;
00934     }
00935     else /* String constant format  - Only available in winxp and above */
00936     {
00937         unsigned int i;
00938         pisid->Revision = SDDL_REVISION;
00939 
00940         for (i = 0; i < sizeof(WellKnownSids)/sizeof(WellKnownSids[0]); i++)
00941             if (!strncmpW(WellKnownSids[i].wstr, StringSid, 2))
00942             {
00943                 DWORD j;
00944                 pisid->SubAuthorityCount = WellKnownSids[i].Sid.SubAuthorityCount;
00945                 pisid->IdentifierAuthority = WellKnownSids[i].Sid.IdentifierAuthority;
00946                 for (j = 0; j < WellKnownSids[i].Sid.SubAuthorityCount; j++)
00947                     pisid->SubAuthority[j] = WellKnownSids[i].Sid.SubAuthority[j];
00948                 bret = TRUE;
00949             }
00950 
00951         if (!bret)
00952             FIXME("String constant not supported: %s\n", debugstr_wn(StringSid, 2));
00953     }
00954 
00955 lend:
00956     if (!bret)
00957         SetLastError(ERROR_INVALID_SID);
00958 
00959     TRACE("returning %s\n", bret ? "TRUE" : "FALSE");
00960     return bret;
00961 }
00962 
00963 /******************************************************************************
00964  * ParseAclStringFlags
00965  */
00966 static DWORD ParseAclStringFlags(LPCWSTR* StringAcl)
00967 {
00968     DWORD flags = 0;
00969     LPCWSTR szAcl = *StringAcl;
00970 
00971     while (*szAcl != '(')
00972     {
00973         if (*szAcl == 'P')
00974     {
00975             flags |= SE_DACL_PROTECTED;
00976     }
00977         else if (*szAcl == 'A')
00978         {
00979             szAcl++;
00980             if (*szAcl == 'R')
00981                 flags |= SE_DACL_AUTO_INHERIT_REQ;
00982         else if (*szAcl == 'I')
00983                 flags |= SE_DACL_AUTO_INHERITED;
00984         }
00985         szAcl++;
00986     }
00987 
00988     *StringAcl = szAcl;
00989     return flags;
00990 }
00991 
00992 /******************************************************************************
00993  * ParseAceStringType
00994  */
00995 static const ACEFLAG AceType[] =
00996 {
00997     { SDDL_ALARM,          SYSTEM_ALARM_ACE_TYPE },
00998     { SDDL_AUDIT,          SYSTEM_AUDIT_ACE_TYPE },
00999     { SDDL_ACCESS_ALLOWED, ACCESS_ALLOWED_ACE_TYPE },
01000     { SDDL_ACCESS_DENIED,  ACCESS_DENIED_ACE_TYPE },
01001     /*
01002     { SDDL_OBJECT_ACCESS_ALLOWED, ACCESS_ALLOWED_OBJECT_ACE_TYPE },
01003     { SDDL_OBJECT_ACCESS_DENIED,  ACCESS_DENIED_OBJECT_ACE_TYPE },
01004     { SDDL_OBJECT_ALARM,          SYSTEM_ALARM_OBJECT_ACE_TYPE },
01005     { SDDL_OBJECT_AUDIT,          SYSTEM_AUDIT_OBJECT_ACE_TYPE },
01006     */
01007     { NULL, 0 },
01008 };
01009 
01010 static BYTE ParseAceStringType(LPCWSTR* StringAcl)
01011 {
01012     UINT len = 0;
01013     LPCWSTR szAcl = *StringAcl;
01014     const ACEFLAG *lpaf = AceType;
01015 
01016     while (lpaf->wstr &&
01017         (len = strlenW(lpaf->wstr)) &&
01018         strncmpW(lpaf->wstr, szAcl, len))
01019         lpaf++;
01020 
01021     if (!lpaf->wstr)
01022         return 0;
01023 
01024     *StringAcl += len;
01025     return lpaf->value;
01026 }
01027 
01028 
01029 /******************************************************************************
01030  * ParseAceStringFlags
01031  */
01032 static const ACEFLAG AceFlags[] =
01033 {
01034     { SDDL_CONTAINER_INHERIT, CONTAINER_INHERIT_ACE },
01035     { SDDL_AUDIT_FAILURE,     FAILED_ACCESS_ACE_FLAG },
01036     { SDDL_INHERITED,         INHERITED_ACE },
01037     { SDDL_INHERIT_ONLY,      INHERIT_ONLY_ACE },
01038     { SDDL_NO_PROPAGATE,      NO_PROPAGATE_INHERIT_ACE },
01039     { SDDL_OBJECT_INHERIT,    OBJECT_INHERIT_ACE },
01040     { SDDL_AUDIT_SUCCESS,     SUCCESSFUL_ACCESS_ACE_FLAG },
01041     { NULL, 0 },
01042 };
01043 
01044 static BYTE ParseAceStringFlags(LPCWSTR* StringAcl)
01045 {
01046     UINT len = 0;
01047     BYTE flags = 0;
01048     LPCWSTR szAcl = *StringAcl;
01049 
01050     while (*szAcl != ';')
01051     {
01052         const ACEFLAG *lpaf = AceFlags;
01053 
01054         while (lpaf->wstr &&
01055                (len = strlenW(lpaf->wstr)) &&
01056                strncmpW(lpaf->wstr, szAcl, len))
01057             lpaf++;
01058 
01059         if (!lpaf->wstr)
01060             return 0;
01061 
01062     flags |= lpaf->value;
01063         szAcl += len;
01064     }
01065 
01066     *StringAcl = szAcl;
01067     return flags;
01068 }
01069 
01070 
01071 /******************************************************************************
01072  * ParseAceStringRights
01073  */
01074 static DWORD ParseAceStringRights(LPCWSTR* StringAcl)
01075 {
01076     UINT len = 0;
01077     DWORD rights = 0;
01078     LPCWSTR szAcl = *StringAcl;
01079 
01080     if ((*szAcl == '0') && (*(szAcl + 1) == 'x'))
01081     {
01082         LPCWSTR p = szAcl;
01083 
01084     while (*p && *p != ';')
01085             p++;
01086 
01087     if (p - szAcl <= 10 /* 8 hex digits + "0x" */ )
01088     {
01089         rights = strtoulW(szAcl, NULL, 16);
01090         szAcl = p;
01091     }
01092     else
01093             WARN("Invalid rights string format: %s\n", debugstr_wn(szAcl, p - szAcl));
01094     }
01095     else
01096     {
01097         while (*szAcl != ';')
01098         {
01099             const ACEFLAG *lpaf = AceRights;
01100 
01101             while (lpaf->wstr &&
01102                (len = strlenW(lpaf->wstr)) &&
01103                strncmpW(lpaf->wstr, szAcl, len))
01104         {
01105                lpaf++;
01106         }
01107 
01108             if (!lpaf->wstr)
01109                 return 0;
01110 
01111         rights |= lpaf->value;
01112             szAcl += len;
01113         }
01114     }
01115 
01116     *StringAcl = szAcl;
01117     return rights;
01118 }
01119 
01120 
01121 /******************************************************************************
01122  * ParseStringAclToAcl
01123  * 
01124  * dacl_flags(string_ace1)(string_ace2)... (string_acen) 
01125  */
01126 static BOOL ParseStringAclToAcl(LPCWSTR StringAcl, LPDWORD lpdwFlags, 
01127     PACL pAcl, LPDWORD cBytes)
01128 {
01129     DWORD val;
01130     DWORD sidlen;
01131     DWORD length = sizeof(ACL);
01132     DWORD acesize = 0;
01133     DWORD acecount = 0;
01134     PACCESS_ALLOWED_ACE pAce = NULL; /* pointer to current ACE */
01135 
01136     TRACE("%s\n", debugstr_w(StringAcl));
01137 
01138     if (!StringAcl)
01139     return FALSE;
01140 
01141     if (pAcl) /* pAce is only useful if we're setting values */
01142         pAce = (PACCESS_ALLOWED_ACE) (pAcl + 1);
01143 
01144     /* Parse ACL flags */
01145     *lpdwFlags = ParseAclStringFlags(&StringAcl);
01146 
01147     /* Parse ACE */
01148     while (*StringAcl == '(')
01149     {
01150         StringAcl++;
01151 
01152         /* Parse ACE type */
01153         val = ParseAceStringType(&StringAcl);
01154     if (pAce)
01155             pAce->Header.AceType = (BYTE) val;
01156         if (*StringAcl != ';')
01157             goto lerr;
01158         StringAcl++;
01159 
01160         /* Parse ACE flags */
01161     val = ParseAceStringFlags(&StringAcl);
01162     if (pAce)
01163             pAce->Header.AceFlags = (BYTE) val;
01164         if (*StringAcl != ';')
01165             goto lerr;
01166         StringAcl++;
01167 
01168         /* Parse ACE rights */
01169     val = ParseAceStringRights(&StringAcl);
01170     if (pAce)
01171             pAce->Mask = val;
01172         if (*StringAcl != ';')
01173             goto lerr;
01174         StringAcl++;
01175 
01176         /* Parse ACE object guid */
01177         if (*StringAcl != ';')
01178         {
01179             FIXME("Support for *_OBJECT_ACE_TYPE not implemented\n");
01180             goto lerr;
01181         }
01182         StringAcl++;
01183 
01184         /* Parse ACE inherit object guid */
01185         if (*StringAcl != ';')
01186         {
01187             FIXME("Support for *_OBJECT_ACE_TYPE not implemented\n");
01188             goto lerr;
01189         }
01190         StringAcl++;
01191 
01192         /* Parse ACE account sid */
01193         if (ParseStringSidToSid(StringAcl, pAce ? &pAce->SidStart : NULL, &sidlen))
01194     {
01195             while (*StringAcl && *StringAcl != ')')
01196                 StringAcl++;
01197     }
01198 
01199         if (*StringAcl != ')')
01200             goto lerr;
01201         StringAcl++;
01202 
01203         acesize = sizeof(ACCESS_ALLOWED_ACE) - sizeof(DWORD) + sidlen;
01204         length += acesize;
01205         if (pAce)
01206         {
01207             pAce->Header.AceSize = acesize;
01208             pAce = (PACCESS_ALLOWED_ACE)((LPBYTE)pAce + acesize);
01209         }
01210         acecount++;
01211     }
01212 
01213     *cBytes = length;
01214 
01215     if (length > 0xffff)
01216     {
01217         ERR("ACL too large\n");
01218         goto lerr;
01219     }
01220 
01221     if (pAcl)
01222     {
01223         pAcl->AclRevision = ACL_REVISION;
01224         pAcl->Sbz1 = 0;
01225         pAcl->AclSize = length;
01226         pAcl->AceCount = acecount++;
01227         pAcl->Sbz2 = 0;
01228     }
01229     return TRUE;
01230 
01231 lerr:
01232     SetLastError(ERROR_INVALID_ACL);
01233     WARN("Invalid ACE string format\n");
01234     return FALSE;
01235 }
01236 
01237 
01238 /******************************************************************************
01239  * ParseStringSecurityDescriptorToSecurityDescriptor
01240  */
01241 static BOOL ParseStringSecurityDescriptorToSecurityDescriptor(
01242     LPCWSTR StringSecurityDescriptor,
01243     SECURITY_DESCRIPTOR_RELATIVE* SecurityDescriptor,
01244     LPDWORD cBytes)
01245 {
01246     BOOL bret = FALSE;
01247     WCHAR toktype;
01248     WCHAR tok[MAX_PATH];
01249     LPCWSTR lptoken;
01250     LPBYTE lpNext = NULL;
01251     DWORD len;
01252 
01253     *cBytes = sizeof(SECURITY_DESCRIPTOR);
01254 
01255     if (SecurityDescriptor)
01256         lpNext = (LPBYTE)(SecurityDescriptor + 1);
01257 
01258     while (*StringSecurityDescriptor)
01259     {
01260         toktype = *StringSecurityDescriptor;
01261 
01262     /* Expect char identifier followed by ':' */
01263     StringSecurityDescriptor++;
01264         if (*StringSecurityDescriptor != ':')
01265         {
01266             SetLastError(ERROR_INVALID_PARAMETER);
01267             goto lend;
01268         }
01269     StringSecurityDescriptor++;
01270 
01271     /* Extract token */
01272     lptoken = StringSecurityDescriptor;
01273     while (*lptoken && *lptoken != ':')
01274             lptoken++;
01275 
01276     if (*lptoken)
01277             lptoken--;
01278 
01279         len = lptoken - StringSecurityDescriptor;
01280         memcpy( tok, StringSecurityDescriptor, len * sizeof(WCHAR) );
01281         tok[len] = 0;
01282 
01283         switch (toktype)
01284     {
01285             case 'O':
01286             {
01287                 DWORD bytes;
01288 
01289                 if (!ParseStringSidToSid(tok, lpNext, &bytes))
01290                     goto lend;
01291 
01292                 if (SecurityDescriptor)
01293                 {
01294                     SecurityDescriptor->Owner = lpNext - (LPBYTE)SecurityDescriptor;
01295                     lpNext += bytes; /* Advance to next token */
01296                 }
01297 
01298         *cBytes += bytes;
01299 
01300                 break;
01301             }
01302 
01303             case 'G':
01304             {
01305                 DWORD bytes;
01306 
01307                 if (!ParseStringSidToSid(tok, lpNext, &bytes))
01308                     goto lend;
01309 
01310                 if (SecurityDescriptor)
01311                 {
01312                     SecurityDescriptor->Group = lpNext - (LPBYTE)SecurityDescriptor;
01313                     lpNext += bytes; /* Advance to next token */
01314                 }
01315 
01316         *cBytes += bytes;
01317 
01318                 break;
01319             }
01320 
01321             case 'D':
01322         {
01323                 DWORD flags;
01324                 DWORD bytes;
01325 
01326                 if (!ParseStringAclToAcl(tok, &flags, (PACL)lpNext, &bytes))
01327                     goto lend;
01328 
01329                 if (SecurityDescriptor)
01330                 {
01331                     SecurityDescriptor->Control |= SE_DACL_PRESENT | flags;
01332                     SecurityDescriptor->Dacl = lpNext - (LPBYTE)SecurityDescriptor;
01333                     lpNext += bytes; /* Advance to next token */
01334         }
01335 
01336         *cBytes += bytes;
01337 
01338         break;
01339             }
01340 
01341             case 'S':
01342             {
01343                 DWORD flags;
01344                 DWORD bytes;
01345 
01346                 if (!ParseStringAclToAcl(tok, &flags, (PACL)lpNext, &bytes))
01347                     goto lend;
01348 
01349                 if (SecurityDescriptor)
01350                 {
01351                     SecurityDescriptor->Control |= SE_SACL_PRESENT | flags;
01352                     SecurityDescriptor->Sacl = lpNext - (LPBYTE)SecurityDescriptor;
01353                     lpNext += bytes; /* Advance to next token */
01354         }
01355 
01356         *cBytes += bytes;
01357 
01358         break;
01359             }
01360 
01361             default:
01362                 FIXME("Unknown token\n");
01363                 SetLastError(ERROR_INVALID_PARAMETER);
01364         goto lend;
01365     }
01366 
01367         StringSecurityDescriptor = lptoken;
01368     }
01369 
01370     bret = TRUE;
01371 
01372 lend:
01373     return bret;
01374 }
01375 
01376 
01377 /******************************************************************************
01378  * ConvertStringSecurityDescriptorToSecurityDescriptorW [ADVAPI32.@]
01379  * @implemented
01380  */
01381 BOOL WINAPI ConvertStringSecurityDescriptorToSecurityDescriptorW(
01382         LPCWSTR StringSecurityDescriptor,
01383         DWORD StringSDRevision,
01384         PSECURITY_DESCRIPTOR* SecurityDescriptor,
01385         PULONG SecurityDescriptorSize)
01386 {
01387     DWORD cBytes;
01388     SECURITY_DESCRIPTOR* psd;
01389     BOOL bret = FALSE;
01390 
01391     TRACE("%s\n", debugstr_w(StringSecurityDescriptor));
01392 
01393     if (GetVersion() & 0x80000000)
01394     {
01395         SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
01396         goto lend;
01397     }
01398     else if (!StringSecurityDescriptor || !SecurityDescriptor)
01399     {
01400         SetLastError(ERROR_INVALID_PARAMETER);
01401         goto lend;
01402     }
01403     else if (StringSDRevision != SID_REVISION)
01404     {
01405         SetLastError(ERROR_UNKNOWN_REVISION);
01406     goto lend;
01407     }
01408 
01409     /* Compute security descriptor length */
01410     if (!ParseStringSecurityDescriptorToSecurityDescriptor(StringSecurityDescriptor,
01411         NULL, &cBytes))
01412     goto lend;
01413 
01414     psd = *SecurityDescriptor = LocalAlloc(GMEM_ZEROINIT, cBytes);
01415     if (!psd) goto lend;
01416 
01417     psd->Revision = SID_REVISION;
01418     psd->Control |= SE_SELF_RELATIVE;
01419 
01420     if (!ParseStringSecurityDescriptorToSecurityDescriptor(StringSecurityDescriptor,
01421              (SECURITY_DESCRIPTOR_RELATIVE *)psd, &cBytes))
01422     {
01423         LocalFree(psd);
01424     goto lend;
01425     }
01426 
01427     if (SecurityDescriptorSize)
01428         *SecurityDescriptorSize = cBytes;
01429 
01430     bret = TRUE;
01431  
01432 lend:
01433     TRACE(" ret=%d\n", bret);
01434     return bret;
01435 }
01436 
01437 
01438 /* Winehq cvs 20050916 */
01439 /******************************************************************************
01440  * ConvertStringSecurityDescriptorToSecurityDescriptorA [ADVAPI32.@]
01441  * @implemented
01442  */
01443 BOOL WINAPI ConvertStringSecurityDescriptorToSecurityDescriptorA(
01444         LPCSTR StringSecurityDescriptor,
01445         DWORD StringSDRevision,
01446         PSECURITY_DESCRIPTOR* SecurityDescriptor,
01447         PULONG SecurityDescriptorSize)
01448 {
01449     UINT len;
01450     BOOL ret = FALSE;
01451     LPWSTR StringSecurityDescriptorW;
01452 
01453     len = MultiByteToWideChar(CP_ACP, 0, StringSecurityDescriptor, -1, NULL, 0);
01454     StringSecurityDescriptorW = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR));
01455 
01456     if (StringSecurityDescriptorW)
01457     {
01458         MultiByteToWideChar(CP_ACP, 0, StringSecurityDescriptor, -1, StringSecurityDescriptorW, len);
01459 
01460         ret = ConvertStringSecurityDescriptorToSecurityDescriptorW(StringSecurityDescriptorW,
01461                                                                    StringSDRevision, SecurityDescriptor,
01462                                                                    SecurityDescriptorSize);
01463         HeapFree(GetProcessHeap(), 0, StringSecurityDescriptorW);
01464     }
01465 
01466     return ret;
01467 }
01468 
01469 /*
01470  * @implemented
01471  */
01472 BOOL WINAPI
01473 EqualPrefixSid(PSID pSid1,
01474                PSID pSid2)
01475 {
01476     return RtlEqualPrefixSid (pSid1, pSid2);
01477 }
01478 
01479 
01480 /*
01481  * @implemented
01482  */
01483 BOOL WINAPI
01484 EqualSid(PSID pSid1,
01485          PSID pSid2)
01486 {
01487     return RtlEqualSid (pSid1, pSid2);
01488 }
01489 
01490 
01491 /*
01492  * @implemented
01493  *
01494  * RETURNS
01495  *  Docs says this function does NOT return a value
01496  *  even thou it's defined to return a PVOID...
01497  */
01498 PVOID WINAPI
01499 FreeSid(PSID pSid)
01500 {
01501     return RtlFreeSid(pSid);
01502 }
01503 
01504 
01505 /*
01506  * @implemented
01507  */
01508 DWORD WINAPI
01509 GetLengthSid(PSID pSid)
01510 {
01511     return (DWORD)RtlLengthSid(pSid);
01512 }
01513 
01514 
01515 /*
01516  * @implemented
01517  */
01518 PSID_IDENTIFIER_AUTHORITY WINAPI
01519 GetSidIdentifierAuthority(PSID pSid)
01520 {
01521     return RtlIdentifierAuthoritySid(pSid);
01522 }
01523 
01524 
01525 /*
01526  * @implemented
01527  */
01528 DWORD WINAPI
01529 GetSidLengthRequired(UCHAR nSubAuthorityCount)
01530 {
01531     return (DWORD)RtlLengthRequiredSid(nSubAuthorityCount);
01532 }
01533 
01534 
01535 /*
01536  * @implemented
01537  */
01538 PDWORD WINAPI
01539 GetSidSubAuthority(PSID pSid,
01540                    DWORD nSubAuthority)
01541 {
01542     return (PDWORD)RtlSubAuthoritySid(pSid, nSubAuthority);
01543 }
01544 
01545 
01546 /*
01547  * @implemented
01548  */
01549 PUCHAR WINAPI
01550 GetSidSubAuthorityCount(PSID pSid)
01551 {
01552     return RtlSubAuthorityCountSid(pSid);
01553 }
01554 
01555 
01556 /*
01557  * @implemented
01558  */
01559 BOOL WINAPI
01560 InitializeSid(PSID Sid,
01561               PSID_IDENTIFIER_AUTHORITY pIdentifierAuthority,
01562               BYTE nSubAuthorityCount)
01563 {
01564     NTSTATUS Status;
01565 
01566     Status = RtlInitializeSid(Sid,
01567                               pIdentifierAuthority,
01568                               nSubAuthorityCount);
01569     if (!NT_SUCCESS(Status))
01570     {
01571         SetLastError(RtlNtStatusToDosError(Status));
01572         return FALSE;
01573     }
01574 
01575     return TRUE;
01576 }
01577 
01578 
01579 /*
01580  * @implemented
01581  */
01582 BOOL WINAPI
01583 IsValidSid(PSID pSid)
01584 {
01585     return (BOOL)RtlValidSid(pSid);
01586 }
01587 
01588 
01589 /*
01590  * @implemented
01591  */
01592 BOOL WINAPI
01593 ConvertSidToStringSidW(PSID Sid,
01594                        LPWSTR *StringSid)
01595 {
01596     NTSTATUS Status;
01597     UNICODE_STRING UnicodeString;
01598     WCHAR FixedBuffer[64];
01599 
01600     if (!RtlValidSid(Sid))
01601     {
01602         SetLastError(ERROR_INVALID_SID);
01603         return FALSE;
01604     }
01605 
01606     UnicodeString.Length = 0;
01607     UnicodeString.MaximumLength = sizeof(FixedBuffer);
01608     UnicodeString.Buffer = FixedBuffer;
01609     Status = RtlConvertSidToUnicodeString(&UnicodeString, Sid, FALSE);
01610     if (STATUS_BUFFER_TOO_SMALL == Status)
01611     {
01612         Status = RtlConvertSidToUnicodeString(&UnicodeString, Sid, TRUE);
01613     }
01614 
01615     if (!NT_SUCCESS(Status))
01616     {
01617         SetLastError(RtlNtStatusToDosError(Status));
01618         return FALSE;
01619     }
01620 
01621     *StringSid = LocalAlloc(LMEM_FIXED, UnicodeString.Length + sizeof(WCHAR));
01622     if (NULL == *StringSid)
01623     {
01624         if (UnicodeString.Buffer != FixedBuffer)
01625         {
01626             RtlFreeUnicodeString(&UnicodeString);
01627         }
01628       SetLastError(ERROR_NOT_ENOUGH_MEMORY);
01629       return FALSE;
01630     }
01631 
01632     MoveMemory(*StringSid, UnicodeString.Buffer, UnicodeString.Length);
01633     ZeroMemory((PCHAR) *StringSid + UnicodeString.Length, sizeof(WCHAR));
01634     if (UnicodeString.Buffer != FixedBuffer)
01635     {
01636         RtlFreeUnicodeString(&UnicodeString);
01637     }
01638 
01639     return TRUE;
01640 }
01641 
01642 
01643 /*
01644  * @implemented
01645  */
01646 BOOL WINAPI
01647 ConvertSidToStringSidA(PSID Sid,
01648                        LPSTR *StringSid)
01649 {
01650     LPWSTR StringSidW;
01651     int Len;
01652 
01653     if (!ConvertSidToStringSidW(Sid, &StringSidW))
01654     {
01655         return FALSE;
01656     }
01657 
01658     Len = WideCharToMultiByte(CP_ACP, 0, StringSidW, -1, NULL, 0, NULL, NULL);
01659     if (Len <= 0)
01660     {
01661         LocalFree(StringSidW);
01662         SetLastError(ERROR_NOT_ENOUGH_MEMORY);
01663         return FALSE;
01664     }
01665 
01666     *StringSid = LocalAlloc(LMEM_FIXED, Len);
01667     if (NULL == *StringSid)
01668     {
01669         LocalFree(StringSidW);
01670         SetLastError(ERROR_NOT_ENOUGH_MEMORY);
01671         return FALSE;
01672     }
01673 
01674     if (!WideCharToMultiByte(CP_ACP, 0, StringSidW, -1, *StringSid, Len, NULL, NULL))
01675     {
01676         LocalFree(StringSid);
01677         LocalFree(StringSidW);
01678         return FALSE;
01679     }
01680 
01681     LocalFree(StringSidW);
01682 
01683     return TRUE;
01684 }
01685 
01686 
01687 /*
01688  * @unimplemented
01689  */
01690 BOOL WINAPI
01691 EqualDomainSid(IN PSID pSid1,
01692                IN PSID pSid2,
01693                OUT BOOL* pfEqual)
01694 {
01695     UNIMPLEMENTED;
01696     return FALSE;
01697 }
01698 
01699 
01700 /*
01701  * @unimplemented
01702  */
01703 BOOL WINAPI
01704 GetWindowsAccountDomainSid(IN PSID pSid,
01705                            OUT PSID ppDomainSid,
01706                            IN OUT DWORD* cbSid)
01707 {
01708     UNIMPLEMENTED;
01709     return FALSE;
01710 }
01711 
01712 
01713 /*
01714  * @unimplemented
01715  */
01716 BOOL WINAPI
01717 CreateWellKnownSid(IN WELL_KNOWN_SID_TYPE WellKnownSidType,
01718                    IN PSID DomainSid  OPTIONAL,
01719                    OUT PSID pSid,
01720                    IN OUT DWORD* cbSid)
01721 {
01722     unsigned int i;
01723     TRACE("(%d, %s, %p, %p)\n", WellKnownSidType, debugstr_sid(DomainSid), pSid, cbSid);
01724 
01725     if (cbSid == NULL || (DomainSid && !IsValidSid(DomainSid)))
01726     {
01727         SetLastError(ERROR_INVALID_PARAMETER);
01728         return FALSE;
01729     }
01730 
01731     for (i = 0; i < sizeof(WellKnownSids)/sizeof(WellKnownSids[0]); i++) {
01732         if (WellKnownSids[i].Type == WellKnownSidType) {
01733             DWORD length = GetSidLengthRequired(WellKnownSids[i].Sid.SubAuthorityCount);
01734 
01735             if (*cbSid < length)
01736             {
01737                 *cbSid = length;
01738                 SetLastError(ERROR_INSUFFICIENT_BUFFER);
01739                 return FALSE;
01740             }
01741             if (!pSid)
01742             {
01743                 SetLastError(ERROR_INVALID_PARAMETER);
01744                 return FALSE;
01745             }
01746             CopyMemory(pSid, &WellKnownSids[i].Sid.Revision, length);
01747             *cbSid = length;
01748             return TRUE;
01749         }
01750     }
01751 
01752     if (DomainSid == NULL || *GetSidSubAuthorityCount(DomainSid) == SID_MAX_SUB_AUTHORITIES)
01753     {
01754         SetLastError(ERROR_INVALID_PARAMETER);
01755         return FALSE;
01756     }
01757 
01758     for (i = 0; i < sizeof(WellKnownRids)/sizeof(WellKnownRids[0]); i++)
01759         if (WellKnownRids[i].Type == WellKnownSidType) {
01760             UCHAR domain_subauth = *GetSidSubAuthorityCount(DomainSid);
01761             DWORD domain_sid_length = GetSidLengthRequired(domain_subauth);
01762             DWORD output_sid_length = GetSidLengthRequired(domain_subauth + 1);
01763 
01764             if (*cbSid < output_sid_length)
01765             {
01766                 *cbSid = output_sid_length;
01767                 SetLastError(ERROR_INSUFFICIENT_BUFFER);
01768                 return FALSE;
01769             }
01770             if (!pSid)
01771             {
01772                 SetLastError(ERROR_INVALID_PARAMETER);
01773                 return FALSE;
01774             }
01775             CopyMemory(pSid, DomainSid, domain_sid_length);
01776             (*GetSidSubAuthorityCount(pSid))++;
01777             (*GetSidSubAuthority(pSid, domain_subauth)) = WellKnownRids[i].Rid;
01778             *cbSid = output_sid_length;
01779             return TRUE;
01780         }
01781 
01782     SetLastError(ERROR_INVALID_PARAMETER);
01783     return FALSE;
01784 }
01785 
01786 
01787 /*
01788  * @unimplemented
01789  */
01790 BOOL WINAPI
01791 IsWellKnownSid(IN PSID pSid,
01792                IN WELL_KNOWN_SID_TYPE WellKnownSidType)
01793 {
01794     unsigned int i;
01795     TRACE("(%s, %d)\n", debugstr_sid(pSid), WellKnownSidType);
01796 
01797     for (i = 0; i < sizeof(WellKnownSids) / sizeof(WellKnownSids[0]); i++)
01798     {
01799         if (WellKnownSids[i].Type == WellKnownSidType)
01800         {
01801             if (EqualSid(pSid, (PSID)(&WellKnownSids[i].Sid.Revision)))
01802                 return TRUE;
01803         }
01804     }
01805 
01806     return FALSE;
01807 }
01808 
01809 
01810 /*
01811  * @implemented
01812  */
01813 BOOL WINAPI
01814 ConvertStringSidToSidA(IN LPCSTR StringSid,
01815                        OUT PSID* sid)
01816 {
01817     BOOL bRetVal = FALSE;
01818 
01819     TRACE("%s, %p\n", debugstr_a(StringSid), sid);
01820     if (GetVersion() & 0x80000000)
01821         SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
01822     else if (!StringSid || !sid)
01823         SetLastError(ERROR_INVALID_PARAMETER);
01824     else
01825     {
01826         UINT len = MultiByteToWideChar(CP_ACP, 0, StringSid, -1, NULL, 0);
01827         LPWSTR wStringSid = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR));
01828         MultiByteToWideChar(CP_ACP, 0, StringSid, - 1, wStringSid, len);
01829         bRetVal = ConvertStringSidToSidW(wStringSid, sid);
01830         HeapFree(GetProcessHeap(), 0, wStringSid);
01831     }
01832     return bRetVal;
01833 }
01834 
01835 
01836 static const RECORD SidTable[] =
01837 {
01838     { SDDL_ACCOUNT_OPERATORS, WinBuiltinAccountOperatorsSid },
01839     { SDDL_ALIAS_PREW2KCOMPACC, WinBuiltinPreWindows2000CompatibleAccessSid },
01840     { SDDL_ANONYMOUS, WinAnonymousSid },
01841     { SDDL_AUTHENTICATED_USERS, WinAuthenticatedUserSid },
01842     { SDDL_BUILTIN_ADMINISTRATORS, WinBuiltinAdministratorsSid },
01843     { SDDL_BUILTIN_GUESTS, WinBuiltinGuestsSid },
01844     { SDDL_BACKUP_OPERATORS, WinBuiltinBackupOperatorsSid },
01845     { SDDL_BUILTIN_USERS, WinBuiltinUsersSid },
01846     { SDDL_CERT_SERV_ADMINISTRATORS, WinAccountCertAdminsSid /* FIXME: DOMAIN_GROUP_RID_CERT_ADMINS */ },
01847     { SDDL_CREATOR_GROUP, WinCreatorGroupSid },
01848     { SDDL_CREATOR_OWNER, WinCreatorOwnerSid },
01849     { SDDL_DOMAIN_ADMINISTRATORS, WinAccountDomainAdminsSid /* FIXME: DOMAIN_GROUP_RID_ADMINS */ },
01850     { SDDL_DOMAIN_COMPUTERS, WinAccountComputersSid /* FIXME: DOMAIN_GROUP_RID_COMPUTERS */ },
01851     { SDDL_DOMAIN_DOMAIN_CONTROLLERS, WinAccountControllersSid /* FIXME: DOMAIN_GROUP_RID_CONTROLLERS */ },
01852     { SDDL_DOMAIN_GUESTS, WinAccountDomainGuestsSid /* FIXME: DOMAIN_GROUP_RID_GUESTS */ },
01853     { SDDL_DOMAIN_USERS, WinAccountDomainUsersSid /* FIXME: DOMAIN_GROUP_RID_USERS */ },
01854     { SDDL_ENTERPRISE_ADMINS, WinAccountEnterpriseAdminsSid /* FIXME: DOMAIN_GROUP_RID_ENTERPRISE_ADMINS */ },
01855     { SDDL_ENTERPRISE_DOMAIN_CONTROLLERS, WinLogonIdsSid /* FIXME: SECURITY_SERVER_LOGON_RID */ },
01856     { SDDL_EVERYONE, WinWorldSid },
01857     { SDDL_GROUP_POLICY_ADMINS, WinAccountPolicyAdminsSid /* FIXME: DOMAIN_GROUP_RID_POLICY_ADMINS */ },
01858     { SDDL_INTERACTIVE, WinInteractiveSid },
01859     { SDDL_LOCAL_ADMIN, WinAccountAdministratorSid /* FIXME: DOMAIN_USER_RID_ADMIN */ },
01860     { SDDL_LOCAL_GUEST, WinAccountGuestSid /* FIXME: DOMAIN_USER_RID_GUEST */ },
01861     { SDDL_LOCAL_SERVICE, WinLocalServiceSid },
01862     { SDDL_LOCAL_SYSTEM, WinLocalSystemSid },
01863     { SDDL_NETWORK, WinNetworkSid },
01864     { SDDL_NETWORK_CONFIGURATION_OPS, WinBuiltinNetworkConfigurationOperatorsSid },
01865     { SDDL_NETWORK_SERVICE, WinNetworkServiceSid },
01866     { SDDL_PRINTER_OPERATORS, WinBuiltinPrintOperatorsSid },
01867     { SDDL_PERSONAL_SELF, WinSelfSid },
01868     { SDDL_POWER_USERS, WinBuiltinPowerUsersSid },
01869     { SDDL_RAS_SERVERS, WinAccountRasAndIasServersSid /* FIXME: DOMAIN_ALIAS_RID_RAS_SERVERS */ },
01870     { SDDL_REMOTE_DESKTOP, WinBuiltinRemoteDesktopUsersSid },
01871     { SDDL_REPLICATOR, WinBuiltinReplicatorSid },
01872     { SDDL_RESTRICTED_CODE, WinRestrictedCodeSid },
01873     { SDDL_SCHEMA_ADMINISTRATORS, WinAccountSchemaAdminsSid /* FIXME: DOMAIN_GROUP_RID_SCHEMA_ADMINS */ },
01874     { SDDL_SERVER_OPERATORS, WinBuiltinSystemOperatorsSid },
01875     { SDDL_SERVICE, WinServiceSid },
01876     { NULL, 0 },
01877 };
01878 
01879 /*
01880  * @implemented
01881  */
01882 BOOL WINAPI
01883 ConvertStringSidToSidW(IN LPCWSTR StringSid,
01884                        OUT PSID* sid)
01885 {
01886     DWORD size;
01887     DWORD i, cBytes, identAuth, csubauth;
01888     BOOL ret;
01889     SID* pisid;
01890 
01891     TRACE("%s %p\n", debugstr_w(StringSid), sid);
01892 
01893     if (!StringSid)
01894     {
01895         SetLastError(ERROR_INVALID_SID);
01896         return FALSE;
01897     }
01898     for (i = 0; i < sizeof(SidTable) / sizeof(SidTable[0]) - 1; i++)
01899     {
01900         if (wcscmp(StringSid, SidTable[i].key) == 0)
01901         {
01902             WELL_KNOWN_SID_TYPE knownSid = (WELL_KNOWN_SID_TYPE)SidTable[i].value;
01903             size = SECURITY_MAX_SID_SIZE;
01904             *sid = LocalAlloc(0, size);
01905             if (!*sid)
01906             {
01907                 SetLastError(ERROR_NOT_ENOUGH_MEMORY);
01908                 return FALSE;
01909             }
01910             ret = CreateWellKnownSid(
01911                 knownSid,
01912                 NULL,
01913                 *sid,
01914                 &size);
01915             if (!ret)
01916             {
01917                 SetLastError(ERROR_INVALID_SID);
01918                 LocalFree(*sid);
01919             }
01920             return ret;
01921         }
01922     }
01923 
01924     /* That's probably a string S-R-I-S-S... */
01925     if (StringSid[0] != 'S' || StringSid[1] != '-')
01926     {
01927         SetLastError(ERROR_INVALID_SID);
01928         return FALSE;
01929     }
01930 
01931     cBytes = ComputeStringSidSize(StringSid);
01932     pisid = (SID*)LocalAlloc( 0, cBytes );
01933     if (!pisid)
01934     {
01935         SetLastError(ERROR_NOT_ENOUGH_MEMORY);
01936         return FALSE;
01937     }
01938     i = 0;
01939     ret = FALSE;
01940     csubauth = ((cBytes - GetSidLengthRequired(0)) / sizeof(DWORD));
01941 
01942     StringSid += 2; /* Advance to Revision */
01943     pisid->Revision = atoiW(StringSid);
01944 
01945     if (pisid->Revision != SDDL_REVISION)
01946     {
01947         TRACE("Revision %d is unknown\n", pisid->Revision);
01948         goto lend; /* ERROR_INVALID_SID */
01949     }
01950     if (csubauth == 0)
01951     {
01952         TRACE("SubAuthorityCount is 0\n");
01953         goto lend; /* ERROR_INVALID_SID */
01954     }
01955 
01956     pisid->SubAuthorityCount = csubauth;
01957 
01958     /* Advance to identifier authority */
01959     while (*StringSid && *StringSid != '-')
01960         StringSid++;
01961     if (*StringSid == '-')
01962         StringSid++;
01963 
01964     /* MS' implementation can't handle values greater than 2^32 - 1, so
01965      * we don't either; assume most significant bytes are always 0
01966      */
01967     pisid->IdentifierAuthority.Value[0] = 0;
01968     pisid->IdentifierAuthority.Value[1] = 0;
01969     identAuth = atoiW(StringSid);
01970     pisid->IdentifierAuthority.Value[5] = identAuth & 0xff;
01971     pisid->IdentifierAuthority.Value[4] = (identAuth & 0xff00) >> 8;
01972     pisid->IdentifierAuthority.Value[3] = (identAuth & 0xff0000) >> 16;
01973     pisid->IdentifierAuthority.Value[2] = (identAuth & 0xff000000) >> 24;
01974 
01975     /* Advance to first sub authority */
01976     while (*StringSid && *StringSid != '-')
01977         StringSid++;
01978     if (*StringSid == '-')
01979         StringSid++;
01980 
01981     while (*StringSid)
01982     {
01983         pisid->SubAuthority[i++] = atoiW(StringSid);
01984 
01985         while (*StringSid && *StringSid != '-')
01986             StringSid++;
01987         if (*StringSid == '-')
01988             StringSid++;
01989     }
01990 
01991     if (i != pisid->SubAuthorityCount)
01992         goto lend; /* ERROR_INVALID_SID */
01993 
01994     *sid = pisid;
01995     ret = TRUE;
01996 
01997 lend:
01998     if (!ret)
01999     {
02000         LocalFree(pisid);
02001         SetLastError(ERROR_INVALID_SID);
02002     }
02003 
02004     TRACE("returning %s\n", ret ? "TRUE" : "FALSE");
02005     return ret;
02006 }
02007 
02008 
02009 /* EOF */

Generated on Sun May 27 2012 04:22:44 for ReactOS by doxygen 1.7.6.1

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