-/* $Id$
- *
+/*
* COPYRIGHT: See COPYING in the top level directory
* WINE COPYRIGHT:
* Copyright 1999, 2000 Juergen Schmied <juergen.schmied@debitel.net>
* Copyright 2003 CodeWeavers Inc. (Ulrich Czekalla)
+ * Copyright 2006 Robert Reif
+ * Copyright 2006 Hervé Poussineau
*
* PROJECT: ReactOS system libraries
- * FILE: lib/advapi32/sec/sid.c
+ * FILE: dll/win32/advapi32/sec/sid.c
* PURPOSE: Security ID functions
*/
#include <advapi32.h>
+#include <sddl.h>
#include <wine/debug.h>
#include <wine/unicode.h>
WINE_DEFAULT_DEBUG_CHANNEL(advapi);
+#define MAX_GUID_STRING_LEN 39
+
+BOOL WINAPI
+AddAuditAccessAceEx(PACL pAcl,
+ DWORD dwAceRevision,
+ DWORD AceFlags,
+ DWORD dwAccessMask,
+ PSID pSid,
+ BOOL bAuditSuccess,
+ BOOL bAuditFailure);
+
+typedef struct RECORD
+{
+ LPCWSTR key;
+ DWORD value;
+} RECORD;
-static BOOL ParseStringSidToSid(LPCWSTR StringSid, PSID pSid, LPDWORD cBytes);
-static BOOL ParseStringAclToAcl(LPCWSTR StringAcl, LPDWORD lpdwFlags,
- PACL pAcl, LPDWORD cBytes);
-static BYTE ParseAceStringFlags(LPCWSTR* StringAcl);
-static BYTE ParseAceStringType(LPCWSTR* StringAcl);
-static DWORD ParseAceStringRights(LPCWSTR* StringAcl);
-static DWORD ParseAclStringFlags(LPCWSTR* StringAcl);
+
+typedef struct _MAX_SID
+{
+ /* same fields as struct _SID */
+ BYTE Revision;
+ BYTE SubAuthorityCount;
+ SID_IDENTIFIER_AUTHORITY IdentifierAuthority;
+ DWORD SubAuthority[SID_MAX_SUB_AUTHORITIES];
+} MAX_SID;
+
+typedef struct WELLKNOWNSID
+{
+ WCHAR wstr[2];
+ WELL_KNOWN_SID_TYPE Type;
+ MAX_SID Sid;
+} WELLKNOWNSID;
typedef struct _ACEFLAG
{
DWORD value;
} ACEFLAG, *LPACEFLAG;
-static const SID sidWorld = { SID_REVISION, 1, { SECURITY_WORLD_SID_AUTHORITY} , { SECURITY_WORLD_RID } };
+static const WELLKNOWNSID WellKnownSids[] =
+{
+ { {0,0}, WinNullSid, { SID_REVISION, 1, { SECURITY_NULL_SID_AUTHORITY }, { SECURITY_NULL_RID } } },
+ { {'W','D'}, WinWorldSid, { SID_REVISION, 1, { SECURITY_WORLD_SID_AUTHORITY }, { SECURITY_WORLD_RID } } },
+ { {0,0}, WinLocalSid, { SID_REVISION, 1, { SECURITY_LOCAL_SID_AUTHORITY }, { SECURITY_LOCAL_RID } } },
+ { {'C','O'}, WinCreatorOwnerSid, { SID_REVISION, 1, { SECURITY_CREATOR_SID_AUTHORITY }, { SECURITY_CREATOR_OWNER_RID } } },
+ { {'C','G'}, WinCreatorGroupSid, { SID_REVISION, 1, { SECURITY_CREATOR_SID_AUTHORITY }, { SECURITY_CREATOR_GROUP_RID } } },
+ { {0,0}, WinCreatorOwnerServerSid, { SID_REVISION, 1, { SECURITY_CREATOR_SID_AUTHORITY }, { SECURITY_CREATOR_OWNER_SERVER_RID } } },
+ { {0,0}, WinCreatorGroupServerSid, { SID_REVISION, 1, { SECURITY_CREATOR_SID_AUTHORITY }, { SECURITY_CREATOR_GROUP_SERVER_RID } } },
+ { {0,0}, WinNtAuthoritySid, { SID_REVISION, 0, { SECURITY_NT_AUTHORITY }, { SECURITY_NULL_RID } } },
+ { {0,0}, WinDialupSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_DIALUP_RID } } },
+ { {'N','U'}, WinNetworkSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_NETWORK_RID } } },
+ { {0,0}, WinBatchSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_BATCH_RID } } },
+ { {'I','U'}, WinInteractiveSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_INTERACTIVE_RID } } },
+ { {'S','U'}, WinServiceSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_SERVICE_RID } } },
+ { {'A','N'}, WinAnonymousSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_ANONYMOUS_LOGON_RID } } },
+ { {0,0}, WinProxySid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_PROXY_RID } } },
+ { {'E','D'}, WinEnterpriseControllersSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_ENTERPRISE_CONTROLLERS_RID } } },
+ { {'P','S'}, WinSelfSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_PRINCIPAL_SELF_RID } } },
+ { {'A','U'}, WinAuthenticatedUserSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_AUTHENTICATED_USER_RID } } },
+ { {'R','C'}, WinRestrictedCodeSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_RESTRICTED_CODE_RID } } },
+ { {0,0}, WinTerminalServerSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_TERMINAL_SERVER_RID } } },
+ { {0,0}, WinRemoteLogonIdSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_REMOTE_LOGON_RID } } },
+ { {'S','Y'}, WinLocalSystemSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_LOCAL_SYSTEM_RID } } },
+ { {'L','S'}, WinLocalServiceSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_LOCAL_SERVICE_RID } } },
+ { {'N','S'}, WinNetworkServiceSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_NETWORK_SERVICE_RID } } },
+ { {0,0}, WinBuiltinDomainSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID } } },
+ { {'B','A'}, WinBuiltinAdministratorsSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_ADMINS } } },
+ { {'B','U'}, WinBuiltinUsersSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_USERS } } },
+ { {'B','G'}, WinBuiltinGuestsSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_GUESTS } } },
+ { {'P','U'}, WinBuiltinPowerUsersSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_POWER_USERS } } },
+ { {'A','O'}, WinBuiltinAccountOperatorsSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_ACCOUNT_OPS } } },
+ { {'S','O'}, WinBuiltinSystemOperatorsSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_SYSTEM_OPS } } },
+ { {'P','O'}, WinBuiltinPrintOperatorsSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_PRINT_OPS } } },
+ { {'B','O'}, WinBuiltinBackupOperatorsSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_BACKUP_OPS } } },
+ { {'R','E'}, WinBuiltinReplicatorSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_REPLICATOR } } },
+ { {'R','U'}, WinBuiltinPreWindows2000CompatibleAccessSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_PREW2KCOMPACCESS } } },
+ { {'R','D'}, WinBuiltinRemoteDesktopUsersSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_REMOTE_DESKTOP_USERS } } },
+ { {'N','O'}, WinBuiltinNetworkConfigurationOperatorsSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_NETWORK_CONFIGURATION_OPS } } },
+ { {0,0}, WinNTLMAuthenticationSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_PACKAGE_BASE_RID, SECURITY_PACKAGE_NTLM_RID } } },
+ { {0,0}, WinDigestAuthenticationSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_PACKAGE_BASE_RID, SECURITY_PACKAGE_DIGEST_RID } } },
+ { {0,0}, WinSChannelAuthenticationSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_PACKAGE_BASE_RID, SECURITY_PACKAGE_SCHANNEL_RID } } },
+ { {0,0}, WinThisOrganizationSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_THIS_ORGANIZATION_RID } } },
+ { {0,0}, WinOtherOrganizationSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_OTHER_ORGANIZATION_RID } } },
+ { {0,0}, WinBuiltinIncomingForestTrustBuildersSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_INCOMING_FOREST_TRUST_BUILDERS } } },
+ { {0,0}, WinBuiltinPerfMonitoringUsersSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_MONITORING_USERS } } },
+ { {0,0}, WinBuiltinPerfLoggingUsersSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_LOGGING_USERS } } },
+ { {0,0}, WinBuiltinAuthorizationAccessSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_AUTHORIZATIONACCESS } } },
+ { {0,0}, WinBuiltinTerminalServerLicenseServersSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_TS_LICENSE_SERVERS } } },
+ { {0,0}, WinBuiltinDCOMUsersSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_DCOM_USERS } } },
+ { {'L','W'}, WinLowLabelSid, { SID_REVISION, 1, { SECURITY_MANDATORY_LABEL_AUTHORITY}, { SECURITY_MANDATORY_LOW_RID} } },
+ { {'M','E'}, WinMediumLabelSid, { SID_REVISION, 1, { SECURITY_MANDATORY_LABEL_AUTHORITY}, { SECURITY_MANDATORY_MEDIUM_RID } } },
+ { {'H','I'}, WinHighLabelSid, { SID_REVISION, 1, { SECURITY_MANDATORY_LABEL_AUTHORITY}, { SECURITY_MANDATORY_HIGH_RID } } },
+ { {'S','I'}, WinSystemLabelSid, { SID_REVISION, 1, { SECURITY_MANDATORY_LABEL_AUTHORITY}, { SECURITY_MANDATORY_SYSTEM_RID } } },
+};
-/*
- * ACE access rights
- */
-static const WCHAR SDDL_READ_CONTROL[] = {'R','C',0};
-static const WCHAR SDDL_WRITE_DAC[] = {'W','D',0};
-static const WCHAR SDDL_WRITE_OWNER[] = {'W','O',0};
-static const WCHAR SDDL_STANDARD_DELETE[] = {'S','D',0};
-static const WCHAR SDDL_GENERIC_ALL[] = {'G','A',0};
-static const WCHAR SDDL_GENERIC_READ[] = {'G','R',0};
-static const WCHAR SDDL_GENERIC_WRITE[] = {'G','W',0};
-static const WCHAR SDDL_GENERIC_EXECUTE[] = {'G','X',0};
+typedef struct WELLKNOWNRID
+{
+ WELL_KNOWN_SID_TYPE Type;
+ DWORD Rid;
+} WELLKNOWNRID;
+
+static const WELLKNOWNRID WellKnownRids[] = {
+ { WinAccountAdministratorSid, DOMAIN_USER_RID_ADMIN },
+ { WinAccountGuestSid, DOMAIN_USER_RID_GUEST },
+ { WinAccountKrbtgtSid, DOMAIN_USER_RID_KRBTGT },
+ { WinAccountDomainAdminsSid, DOMAIN_GROUP_RID_ADMINS },
+ { WinAccountDomainUsersSid, DOMAIN_GROUP_RID_USERS },
+ { WinAccountDomainGuestsSid, DOMAIN_GROUP_RID_GUESTS },
+ { WinAccountComputersSid, DOMAIN_GROUP_RID_COMPUTERS },
+ { WinAccountControllersSid, DOMAIN_GROUP_RID_CONTROLLERS },
+ { WinAccountCertAdminsSid, DOMAIN_GROUP_RID_CERT_ADMINS },
+ { WinAccountSchemaAdminsSid, DOMAIN_GROUP_RID_SCHEMA_ADMINS },
+ { WinAccountEnterpriseAdminsSid, DOMAIN_GROUP_RID_ENTERPRISE_ADMINS },
+ { WinAccountPolicyAdminsSid, DOMAIN_GROUP_RID_POLICY_ADMINS },
+ { WinAccountRasAndIasServersSid, DOMAIN_ALIAS_RID_RAS_SERVERS },
+};
+
+static const SID sidWorld = { SID_REVISION, 1, { SECURITY_WORLD_SID_AUTHORITY} , { SECURITY_WORLD_RID } };
/*
* ACE types
static const WCHAR SDDL_OBJECT_AUDIT[] = {'O','U',0};
static const WCHAR SDDL_OBJECT_ALARM[] = {'O','L',0};
-/*
- * ACE flags
- */
-static const WCHAR SDDL_CONTAINER_INHERIT[] = {'C','I',0};
-static const WCHAR SDDL_OBJECT_INHERIT[] = {'O','I',0};
-static const WCHAR SDDL_NO_PROPAGATE[] = {'N','P',0};
-static const WCHAR SDDL_INHERIT_ONLY[] = {'I','O',0};
-static const WCHAR SDDL_INHERITED[] = {'I','D',0};
-static const WCHAR SDDL_AUDIT_SUCCESS[] = {'S','A',0};
-static const WCHAR SDDL_AUDIT_FAILURE[] = {'F','A',0};
+/*
+ * SDDL ADS Rights
+ */
+#define ADS_RIGHT_DS_CREATE_CHILD 0x0001
+#define ADS_RIGHT_DS_DELETE_CHILD 0x0002
+#define ADS_RIGHT_ACTRL_DS_LIST 0x0004
+#define ADS_RIGHT_DS_SELF 0x0008
+#define ADS_RIGHT_DS_READ_PROP 0x0010
+#define ADS_RIGHT_DS_WRITE_PROP 0x0020
+#define ADS_RIGHT_DS_DELETE_TREE 0x0040
+#define ADS_RIGHT_DS_LIST_OBJECT 0x0080
+#define ADS_RIGHT_DS_CONTROL_ACCESS 0x0100
+
+/*
+ * ACE flags
+ */
+static const WCHAR SDDL_CONTAINER_INHERIT[] = {'C','I',0};
+static const WCHAR SDDL_OBJECT_INHERIT[] = {'O','I',0};
+static const WCHAR SDDL_NO_PROPAGATE[] = {'N','P',0};
+static const WCHAR SDDL_INHERIT_ONLY[] = {'I','O',0};
+static const WCHAR SDDL_INHERITED[] = {'I','D',0};
+static const WCHAR SDDL_AUDIT_SUCCESS[] = {'S','A',0};
+static const WCHAR SDDL_AUDIT_FAILURE[] = {'F','A',0};
+
+static const char * debugstr_sid(PSID sid)
+{
+ int auth = 0;
+ SID * psid = (SID *)sid;
+
+ if (psid == NULL)
+ return "(null)";
+
+ auth = psid->IdentifierAuthority.Value[5] +
+ (psid->IdentifierAuthority.Value[4] << 8) +
+ (psid->IdentifierAuthority.Value[3] << 16) +
+ (psid->IdentifierAuthority.Value[2] << 24);
+
+ switch (psid->SubAuthorityCount) {
+ case 0:
+ return wine_dbg_sprintf("S-%d-%d", psid->Revision, auth);
+ case 1:
+ return wine_dbg_sprintf("S-%d-%d-%lu", psid->Revision, auth,
+ psid->SubAuthority[0]);
+ case 2:
+ return wine_dbg_sprintf("S-%d-%d-%lu-%lu", psid->Revision, auth,
+ psid->SubAuthority[0], psid->SubAuthority[1]);
+ case 3:
+ return wine_dbg_sprintf("S-%d-%d-%lu-%lu-%lu", psid->Revision, auth,
+ psid->SubAuthority[0], psid->SubAuthority[1], psid->SubAuthority[2]);
+ case 4:
+ return wine_dbg_sprintf("S-%d-%d-%lu-%lu-%lu-%lu", psid->Revision, auth,
+ psid->SubAuthority[0], psid->SubAuthority[1], psid->SubAuthority[2],
+ psid->SubAuthority[3]);
+ case 5:
+ return wine_dbg_sprintf("S-%d-%d-%lu-%lu-%lu-%lu-%lu", psid->Revision, auth,
+ psid->SubAuthority[0], psid->SubAuthority[1], psid->SubAuthority[2],
+ psid->SubAuthority[3], psid->SubAuthority[4]);
+ case 6:
+ return wine_dbg_sprintf("S-%d-%d-%lu-%lu-%lu-%lu-%lu-%lu", psid->Revision, auth,
+ psid->SubAuthority[3], psid->SubAuthority[1], psid->SubAuthority[2],
+ psid->SubAuthority[0], psid->SubAuthority[4], psid->SubAuthority[5]);
+ case 7:
+ return wine_dbg_sprintf("S-%d-%d-%lu-%lu-%lu-%lu-%lu-%lu-%lu", psid->Revision, auth,
+ psid->SubAuthority[0], psid->SubAuthority[1], psid->SubAuthority[2],
+ psid->SubAuthority[3], psid->SubAuthority[4], psid->SubAuthority[5],
+ psid->SubAuthority[6]);
+ case 8:
+ return wine_dbg_sprintf("S-%d-%d-%lu-%lu-%lu-%lu-%lu-%lu-%lu-%lu", psid->Revision, auth,
+ psid->SubAuthority[0], psid->SubAuthority[1], psid->SubAuthority[2],
+ psid->SubAuthority[3], psid->SubAuthority[4], psid->SubAuthority[5],
+ psid->SubAuthority[6], psid->SubAuthority[7]);
+ }
+ return "(too-big)";
+}
+
+static const ACEFLAG AceRights[] =
+{
+ { SDDL_GENERIC_ALL, GENERIC_ALL },
+ { SDDL_GENERIC_READ, GENERIC_READ },
+ { SDDL_GENERIC_WRITE, GENERIC_WRITE },
+ { SDDL_GENERIC_EXECUTE, GENERIC_EXECUTE },
+
+ { SDDL_READ_CONTROL, READ_CONTROL },
+ { SDDL_STANDARD_DELETE, DELETE },
+ { SDDL_WRITE_DAC, WRITE_DAC },
+ { SDDL_WRITE_OWNER, WRITE_OWNER },
+
+ { SDDL_READ_PROPERTY, ADS_RIGHT_DS_READ_PROP},
+ { SDDL_WRITE_PROPERTY, ADS_RIGHT_DS_WRITE_PROP},
+ { SDDL_CREATE_CHILD, ADS_RIGHT_DS_CREATE_CHILD},
+ { SDDL_DELETE_CHILD, ADS_RIGHT_DS_DELETE_CHILD},
+ { SDDL_LIST_CHILDREN, ADS_RIGHT_ACTRL_DS_LIST},
+ { SDDL_SELF_WRITE, ADS_RIGHT_DS_SELF},
+ { SDDL_LIST_OBJECT, ADS_RIGHT_DS_LIST_OBJECT},
+ { SDDL_DELETE_TREE, ADS_RIGHT_DS_DELETE_TREE},
+ { SDDL_CONTROL_ACCESS, ADS_RIGHT_DS_CONTROL_ACCESS},
+
+ { SDDL_FILE_ALL, FILE_ALL_ACCESS },
+ { SDDL_FILE_READ, FILE_GENERIC_READ },
+ { SDDL_FILE_WRITE, FILE_GENERIC_WRITE },
+ { SDDL_FILE_EXECUTE, FILE_GENERIC_EXECUTE },
+
+ { SDDL_KEY_ALL, KEY_ALL_ACCESS },
+ { SDDL_KEY_READ, KEY_READ },
+ { SDDL_KEY_WRITE, KEY_WRITE },
+ { SDDL_KEY_EXECUTE, KEY_EXECUTE },
+ { NULL, 0 },
+};
+
+static const LPCWSTR AceRightBitNames[32] = {
+ SDDL_CREATE_CHILD, /* 0 */
+ SDDL_DELETE_CHILD,
+ SDDL_LIST_CHILDREN,
+ SDDL_SELF_WRITE,
+ SDDL_READ_PROPERTY, /* 4 */
+ SDDL_WRITE_PROPERTY,
+ SDDL_DELETE_TREE,
+ SDDL_LIST_OBJECT,
+ SDDL_CONTROL_ACCESS, /* 8 */
+ NULL,
+ NULL,
+ NULL,
+ NULL, /* 12 */
+ NULL,
+ NULL,
+ NULL,
+ SDDL_STANDARD_DELETE, /* 16 */
+ SDDL_READ_CONTROL,
+ SDDL_WRITE_DAC,
+ SDDL_WRITE_OWNER,
+ NULL, /* 20 */
+ NULL,
+ NULL,
+ NULL,
+ NULL, /* 24 */
+ NULL,
+ NULL,
+ NULL,
+ SDDL_GENERIC_ALL, /* 28 */
+ SDDL_GENERIC_EXECUTE,
+ SDDL_GENERIC_WRITE,
+ SDDL_GENERIC_READ
+};
+
+
+/* set last error code from NT status and get the proper boolean return value */
+/* used for functions that are a simple wrapper around the corresponding ntdll API */
+static __inline BOOL set_ntstatus( NTSTATUS status )
+{
+ if (status) SetLastError( RtlNtStatusToDosError( status ));
+ return !status;
+}
+
+/* Exported functions */
+
+/*
+ * @implemented
+ */
+BOOL WINAPI
+AllocateLocallyUniqueId(PLUID Luid)
+{
+ NTSTATUS Status;
+
+ Status = NtAllocateLocallyUniqueId (Luid);
+ if (!NT_SUCCESS (Status))
+ {
+ SetLastError(RtlNtStatusToDosError(Status));
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+
+/*
+ * @implemented
+ */
+BOOL WINAPI
+AllocateAndInitializeSid(PSID_IDENTIFIER_AUTHORITY pIdentifierAuthority,
+ BYTE nSubAuthorityCount,
+ DWORD dwSubAuthority0,
+ DWORD dwSubAuthority1,
+ DWORD dwSubAuthority2,
+ DWORD dwSubAuthority3,
+ DWORD dwSubAuthority4,
+ DWORD dwSubAuthority5,
+ DWORD dwSubAuthority6,
+ DWORD dwSubAuthority7,
+ PSID *pSid)
+{
+ NTSTATUS Status;
+
+ Status = RtlAllocateAndInitializeSid(pIdentifierAuthority,
+ nSubAuthorityCount,
+ dwSubAuthority0,
+ dwSubAuthority1,
+ dwSubAuthority2,
+ dwSubAuthority3,
+ dwSubAuthority4,
+ dwSubAuthority5,
+ dwSubAuthority6,
+ dwSubAuthority7,
+ pSid);
+ if (!NT_SUCCESS(Status))
+ {
+ SetLastError(RtlNtStatusToDosError(Status));
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+
+/*
+ * @implemented
+ */
+BOOL WINAPI
+CopySid(DWORD nDestinationSidLength,
+ PSID pDestinationSid,
+ PSID pSourceSid)
+{
+ NTSTATUS Status;
+
+ Status = RtlCopySid(nDestinationSidLength,
+ pDestinationSid,
+ pSourceSid);
+ if (!NT_SUCCESS (Status))
+ {
+ SetLastError(RtlNtStatusToDosError(Status));
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+static void DumpString(LPCWSTR string, int cch, WCHAR **pwptr, ULONG *plen)
+{
+ if (cch == -1)
+ cch = strlenW(string);
+
+ if (plen)
+ *plen += cch;
+
+ if (pwptr)
+ {
+ memcpy(*pwptr, string, sizeof(WCHAR)*cch);
+ *pwptr += cch;
+ }
+}
+
+static BOOL DumpSidNumeric(PSID psid, WCHAR **pwptr, ULONG *plen)
+{
+ DWORD i;
+ WCHAR fmt[] = { 'S','-','%','u','-','%','d',0 };
+ WCHAR subauthfmt[] = { '-','%','u',0 };
+ WCHAR buf[26];
+ SID *pisid = psid;
+
+ if( !IsValidSid( psid ) || pisid->Revision != SDDL_REVISION)
+ {
+ SetLastError(ERROR_INVALID_SID);
+ return FALSE;
+ }
+
+ if (pisid->IdentifierAuthority.Value[0] ||
+ pisid->IdentifierAuthority.Value[1])
+ {
+ FIXME("not matching MS' bugs\n");
+ SetLastError(ERROR_INVALID_SID);
+ return FALSE;
+ }
+
+ sprintfW( buf, fmt, pisid->Revision,
+ MAKELONG(
+ MAKEWORD( pisid->IdentifierAuthority.Value[5],
+ pisid->IdentifierAuthority.Value[4] ),
+ MAKEWORD( pisid->IdentifierAuthority.Value[3],
+ pisid->IdentifierAuthority.Value[2] )
+ ) );
+ DumpString(buf, -1, pwptr, plen);
+
+ for( i=0; i<pisid->SubAuthorityCount; i++ )
+ {
+ sprintfW( buf, subauthfmt, pisid->SubAuthority[i] );
+ DumpString(buf, -1, pwptr, plen);
+ }
+ return TRUE;
+}
+
+static BOOL DumpSid(PSID psid, WCHAR **pwptr, ULONG *plen)
+{
+ size_t i;
+ for (i = 0; i < sizeof(WellKnownSids) / sizeof(WellKnownSids[0]); i++)
+ {
+ if (WellKnownSids[i].wstr[0] && EqualSid(psid, (PSID)&(WellKnownSids[i].Sid.Revision)))
+ {
+ DumpString(WellKnownSids[i].wstr, 2, pwptr, plen);
+ return TRUE;
+ }
+ }
+
+ return DumpSidNumeric(psid, pwptr, plen);
+}
+
+static void DumpRights(DWORD mask, WCHAR **pwptr, ULONG *plen)
+{
+ static const WCHAR fmtW[] = {'0','x','%','x',0};
+ WCHAR buf[15];
+ size_t i;
+
+ if (mask == 0)
+ return;
+
+ /* first check if the right have name */
+ for (i = 0; i < sizeof(AceRights)/sizeof(AceRights[0]); i++)
+ {
+ if (AceRights[i].wstr == NULL)
+ break;
+ if (mask == AceRights[i].value)
+ {
+ DumpString(AceRights[i].wstr, -1, pwptr, plen);
+ return;
+ }
+ }
+
+ /* then check if it can be built from bit names */
+ for (i = 0; i < 32; i++)
+ {
+ if ((mask & (1 << i)) && (AceRightBitNames[i] == NULL))
+ {
+ /* can't be built from bit names */
+ sprintfW(buf, fmtW, mask);
+ DumpString(buf, -1, pwptr, plen);
+ return;
+ }
+ }
+
+ /* build from bit names */
+ for (i = 0; i < 32; i++)
+ if (mask & (1 << i))
+ DumpString(AceRightBitNames[i], -1, pwptr, plen);
+}
+
+static BOOL DumpAce(LPVOID pace, WCHAR **pwptr, ULONG *plen)
+{
+ ACCESS_ALLOWED_ACE *piace; /* all the supported ACEs have the same memory layout */
+ static const WCHAR openbr = '(';
+ static const WCHAR closebr = ')';
+ static const WCHAR semicolon = ';';
+
+ if (((PACE_HEADER)pace)->AceType > SYSTEM_ALARM_ACE_TYPE || ((PACE_HEADER)pace)->AceSize < sizeof(ACCESS_ALLOWED_ACE))
+ {
+ SetLastError(ERROR_INVALID_ACL);
+ return FALSE;
+ }
+
+ piace = pace;
+ DumpString(&openbr, 1, pwptr, plen);
+ switch (piace->Header.AceType)
+ {
+ case ACCESS_ALLOWED_ACE_TYPE:
+ DumpString(SDDL_ACCESS_ALLOWED, -1, pwptr, plen);
+ break;
+ case ACCESS_DENIED_ACE_TYPE:
+ DumpString(SDDL_ACCESS_DENIED, -1, pwptr, plen);
+ break;
+ case SYSTEM_AUDIT_ACE_TYPE:
+ DumpString(SDDL_AUDIT, -1, pwptr, plen);
+ break;
+ case SYSTEM_ALARM_ACE_TYPE:
+ DumpString(SDDL_ALARM, -1, pwptr, plen);
+ break;
+ }
+ DumpString(&semicolon, 1, pwptr, plen);
+
+ if (piace->Header.AceFlags & OBJECT_INHERIT_ACE)
+ DumpString(SDDL_OBJECT_INHERIT, -1, pwptr, plen);
+ if (piace->Header.AceFlags & CONTAINER_INHERIT_ACE)
+ DumpString(SDDL_CONTAINER_INHERIT, -1, pwptr, plen);
+ if (piace->Header.AceFlags & NO_PROPAGATE_INHERIT_ACE)
+ DumpString(SDDL_NO_PROPAGATE, -1, pwptr, plen);
+ if (piace->Header.AceFlags & INHERIT_ONLY_ACE)
+ DumpString(SDDL_INHERIT_ONLY, -1, pwptr, plen);
+ if (piace->Header.AceFlags & INHERITED_ACE)
+ DumpString(SDDL_INHERITED, -1, pwptr, plen);
+ if (piace->Header.AceFlags & SUCCESSFUL_ACCESS_ACE_FLAG)
+ DumpString(SDDL_AUDIT_SUCCESS, -1, pwptr, plen);
+ if (piace->Header.AceFlags & FAILED_ACCESS_ACE_FLAG)
+ DumpString(SDDL_AUDIT_FAILURE, -1, pwptr, plen);
+ DumpString(&semicolon, 1, pwptr, plen);
+ DumpRights(piace->Mask, pwptr, plen);
+ DumpString(&semicolon, 1, pwptr, plen);
+ /* objects not supported */
+ DumpString(&semicolon, 1, pwptr, plen);
+ /* objects not supported */
+ DumpString(&semicolon, 1, pwptr, plen);
+ if (!DumpSid((PSID)&piace->SidStart, pwptr, plen))
+ return FALSE;
+ DumpString(&closebr, 1, pwptr, plen);
+ return TRUE;
+}
+
+static BOOL DumpAcl(PACL pacl, WCHAR **pwptr, ULONG *plen, BOOL protected, BOOL autoInheritReq, BOOL autoInherited)
+{
+ WORD count;
+ int i;
+
+ if (protected)
+ DumpString(SDDL_PROTECTED, -1, pwptr, plen);
+ if (autoInheritReq)
+ DumpString(SDDL_AUTO_INHERIT_REQ, -1, pwptr, plen);
+ if (autoInherited)
+ DumpString(SDDL_AUTO_INHERITED, -1, pwptr, plen);
+
+ if (pacl == NULL)
+ return TRUE;
+
+ if (!IsValidAcl(pacl))
+ return FALSE;
+
+ count = pacl->AceCount;
+ for (i = 0; i < count; i++)
+ {
+ LPVOID ace;
+ if (!GetAce(pacl, i, &ace))
+ return FALSE;
+ if (!DumpAce(ace, pwptr, plen))
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+static BOOL DumpOwner(PSECURITY_DESCRIPTOR SecurityDescriptor, WCHAR **pwptr, ULONG *plen)
+{
+ static const WCHAR prefix[] = {'O',':',0};
+ BOOL bDefaulted;
+ PSID psid;
+
+ if (!GetSecurityDescriptorOwner(SecurityDescriptor, &psid, &bDefaulted))
+ return FALSE;
+
+ if (psid == NULL)
+ return TRUE;
+
+ DumpString(prefix, -1, pwptr, plen);
+ if (!DumpSid(psid, pwptr, plen))
+ return FALSE;
+ return TRUE;
+}
+
+static BOOL DumpGroup(PSECURITY_DESCRIPTOR SecurityDescriptor, WCHAR **pwptr, ULONG *plen)
+{
+ static const WCHAR prefix[] = {'G',':',0};
+ BOOL bDefaulted;
+ PSID psid;
+
+ if (!GetSecurityDescriptorGroup(SecurityDescriptor, &psid, &bDefaulted))
+ return FALSE;
+
+ if (psid == NULL)
+ return TRUE;
+
+ DumpString(prefix, -1, pwptr, plen);
+ if (!DumpSid(psid, pwptr, plen))
+ return FALSE;
+ return TRUE;
+}
+
+static BOOL DumpDacl(PSECURITY_DESCRIPTOR SecurityDescriptor, WCHAR **pwptr, ULONG *plen)
+{
+ static const WCHAR dacl[] = {'D',':',0};
+ SECURITY_DESCRIPTOR_CONTROL control;
+ BOOL present, defaulted;
+ DWORD revision;
+ PACL pacl;
+
+ if (!GetSecurityDescriptorDacl(SecurityDescriptor, &present, &pacl, &defaulted))
+ return FALSE;
+
+ if (!GetSecurityDescriptorControl(SecurityDescriptor, &control, &revision))
+ return FALSE;
+
+ if (!present)
+ return TRUE;
+
+ DumpString(dacl, 2, pwptr, plen);
+ if (!DumpAcl(pacl, pwptr, plen, control & SE_DACL_PROTECTED, control & SE_DACL_AUTO_INHERIT_REQ, control & SE_DACL_AUTO_INHERITED))
+ return FALSE;
+ return TRUE;
+}
+
+static BOOL DumpSacl(PSECURITY_DESCRIPTOR SecurityDescriptor, WCHAR **pwptr, ULONG *plen)
+{
+ static const WCHAR sacl[] = {'S',':',0};
+ SECURITY_DESCRIPTOR_CONTROL control;
+ BOOL present, defaulted;
+ DWORD revision;
+ PACL pacl;
+
+ if (!GetSecurityDescriptorSacl(SecurityDescriptor, &present, &pacl, &defaulted))
+ return FALSE;
+
+ if (!GetSecurityDescriptorControl(SecurityDescriptor, &control, &revision))
+ return FALSE;
+
+ if (!present)
+ return TRUE;
+
+ DumpString(sacl, 2, pwptr, plen);
+ if (!DumpAcl(pacl, pwptr, plen, control & SE_SACL_PROTECTED, control & SE_SACL_AUTO_INHERIT_REQ, control & SE_SACL_AUTO_INHERITED))
+ return FALSE;
+ return TRUE;
+}
+
+/******************************************************************************
+ * ConvertSecurityDescriptorToStringSecurityDescriptorW [ADVAPI32.@]
+ * @implemented
+ */
+BOOL WINAPI
+ConvertSecurityDescriptorToStringSecurityDescriptorW(PSECURITY_DESCRIPTOR SecurityDescriptor,
+ DWORD SDRevision,
+ SECURITY_INFORMATION SecurityInformation,
+ LPWSTR *OutputString,
+ PULONG OutputLen)
+{
+ ULONG len;
+ WCHAR *wptr, *wstr;
+
+ if (SDRevision != SDDL_REVISION_1)
+ {
+ ERR("Pogram requested unknown SDDL revision %d\n", SDRevision);
+ SetLastError(ERROR_UNKNOWN_REVISION);
+ return FALSE;
+ }
+
+ len = 0;
+ if (SecurityInformation & OWNER_SECURITY_INFORMATION)
+ if (!DumpOwner(SecurityDescriptor, NULL, &len))
+ return FALSE;
+ if (SecurityInformation & GROUP_SECURITY_INFORMATION)
+ if (!DumpGroup(SecurityDescriptor, NULL, &len))
+ return FALSE;
+ if (SecurityInformation & DACL_SECURITY_INFORMATION)
+ if (!DumpDacl(SecurityDescriptor, NULL, &len))
+ return FALSE;
+ if (SecurityInformation & SACL_SECURITY_INFORMATION)
+ if (!DumpSacl(SecurityDescriptor, NULL, &len))
+ return FALSE;
+
+ wstr = wptr = LocalAlloc(0, (len + 1)*sizeof(WCHAR));
+ if (SecurityInformation & OWNER_SECURITY_INFORMATION)
+ if (!DumpOwner(SecurityDescriptor, &wptr, NULL))
+ return FALSE;
+ if (SecurityInformation & GROUP_SECURITY_INFORMATION)
+ if (!DumpGroup(SecurityDescriptor, &wptr, NULL))
+ return FALSE;
+ if (SecurityInformation & DACL_SECURITY_INFORMATION)
+ if (!DumpDacl(SecurityDescriptor, &wptr, NULL))
+ return FALSE;
+ if (SecurityInformation & SACL_SECURITY_INFORMATION)
+ if (!DumpSacl(SecurityDescriptor, &wptr, NULL))
+ return FALSE;
+ *wptr = 0;
+
+ TRACE("ret: %s, %d\n", wine_dbgstr_w(wstr), len);
+ *OutputString = wstr;
+ if (OutputLen)
+ *OutputLen = strlenW(*OutputString)+1;
+ return TRUE;
+}
+
+
+/******************************************************************************
+ * ConvertSecurityDescriptorToStringSecurityDescriptorA [ADVAPI32.@]
+ * @implemented
+ */
+BOOL WINAPI
+ConvertSecurityDescriptorToStringSecurityDescriptorA(PSECURITY_DESCRIPTOR SecurityDescriptor,
+ DWORD SDRevision,
+ SECURITY_INFORMATION Information,
+ LPSTR *OutputString,
+ PULONG OutputLen)
+{
+ LPWSTR wstr;
+ ULONG len;
+ if (ConvertSecurityDescriptorToStringSecurityDescriptorW(SecurityDescriptor, SDRevision, Information, &wstr, &len))
+ {
+ int lenA;
+
+ lenA = WideCharToMultiByte(CP_ACP, 0, wstr, len, NULL, 0, NULL, NULL);
+ *OutputString = HeapAlloc(GetProcessHeap(), 0, lenA);
+ WideCharToMultiByte(CP_ACP, 0, wstr, len, *OutputString, lenA, NULL, NULL);
+ LocalFree(wstr);
+
+ if (OutputLen != NULL)
+ *OutputLen = lenA;
+ return TRUE;
+ }
+ else
+ {
+ *OutputString = NULL;
+ if (OutputLen)
+ *OutputLen = 0;
+ return FALSE;
+ }
+}
+
+
+/******************************************************************************
+ * ComputeStringSidSize
+ */
+static DWORD ComputeStringSidSize(LPCWSTR StringSid)
+{
+ if (StringSid[0] == 'S' && StringSid[1] == '-') /* S-R-I(-S)+ */
+ {
+ int ctok = 0;
+ while (*StringSid)
+ {
+ if (*StringSid == '-')
+ ctok++;
+ StringSid++;
+ }
+
+ if (ctok >= 3)
+ return GetSidLengthRequired(ctok - 2);
+ }
+ else /* String constant format - Only available in winxp and above */
+ {
+ unsigned int i;
+
+ for (i = 0; i < sizeof(WellKnownSids)/sizeof(WellKnownSids[0]); i++)
+ if (!strncmpW(WellKnownSids[i].wstr, StringSid, 2))
+ return GetSidLengthRequired(WellKnownSids[i].Sid.SubAuthorityCount);
+ }
+
+ return GetSidLengthRequired(0);
+}
+
+/******************************************************************************
+ * ParseStringSidToSid
+ */
+static BOOL ParseStringSidToSid(LPCWSTR StringSid, PSID pSid, LPDWORD cBytes)
+{
+ BOOL bret = FALSE;
+ SID* pisid=pSid;
+
+ TRACE("%s, %p, %p\n", debugstr_w(StringSid), pSid, cBytes);
+ if (!StringSid)
+ {
+ SetLastError(ERROR_INVALID_PARAMETER);
+ TRACE("StringSid is NULL, returning FALSE\n");
+ return FALSE;
+ }
+
+ while (*StringSid == ' ')
+ StringSid++;
+
+ *cBytes = ComputeStringSidSize(StringSid);
+ if (!pisid) /* Simply compute the size */
+ {
+ TRACE("only size requested, returning TRUE\n");
+ return TRUE;
+ }
+
+ if (StringSid[0] == 'S' && StringSid[1] == '-') /* S-R-I-S-S */
+ {
+ DWORD i = 0, identAuth;
+ DWORD csubauth = ((*cBytes - GetSidLengthRequired(0)) / sizeof(DWORD));
+
+ StringSid += 2; /* Advance to Revision */
+ pisid->Revision = atoiW(StringSid);
+
+ if (pisid->Revision != SDDL_REVISION)
+ {
+ TRACE("Revision %d is unknown\n", pisid->Revision);
+ goto lend; /* ERROR_INVALID_SID */
+ }
+ if (csubauth == 0)
+ {
+ TRACE("SubAuthorityCount is 0\n");
+ goto lend; /* ERROR_INVALID_SID */
+ }
+
+ pisid->SubAuthorityCount = csubauth;
+
+ /* Advance to identifier authority */
+ while (*StringSid && *StringSid != '-')
+ StringSid++;
+ if (*StringSid == '-')
+ StringSid++;
+
+ /* MS' implementation can't handle values greater than 2^32 - 1, so
+ * we don't either; assume most significant bytes are always 0
+ */
+ pisid->IdentifierAuthority.Value[0] = 0;
+ pisid->IdentifierAuthority.Value[1] = 0;
+ identAuth = atoiW(StringSid);
+ pisid->IdentifierAuthority.Value[5] = identAuth & 0xff;
+ pisid->IdentifierAuthority.Value[4] = (identAuth & 0xff00) >> 8;
+ pisid->IdentifierAuthority.Value[3] = (identAuth & 0xff0000) >> 16;
+ pisid->IdentifierAuthority.Value[2] = (identAuth & 0xff000000) >> 24;
+
+ /* Advance to first sub authority */
+ while (*StringSid && *StringSid != '-')
+ StringSid++;
+ if (*StringSid == '-')
+ StringSid++;
+
+ while (*StringSid)
+ {
+ pisid->SubAuthority[i++] = atoiW(StringSid);
+
+ while (*StringSid && *StringSid != '-')
+ StringSid++;
+ if (*StringSid == '-')
+ StringSid++;
+ }
+
+ if (i != pisid->SubAuthorityCount)
+ goto lend; /* ERROR_INVALID_SID */
+
+ bret = TRUE;
+ }
+ else /* String constant format - Only available in winxp and above */
+ {
+ unsigned int i;
+ pisid->Revision = SDDL_REVISION;
+
+ for (i = 0; i < sizeof(WellKnownSids)/sizeof(WellKnownSids[0]); i++)
+ if (!strncmpW(WellKnownSids[i].wstr, StringSid, 2))
+ {
+ DWORD j;
+ pisid->SubAuthorityCount = WellKnownSids[i].Sid.SubAuthorityCount;
+ pisid->IdentifierAuthority = WellKnownSids[i].Sid.IdentifierAuthority;
+ for (j = 0; j < WellKnownSids[i].Sid.SubAuthorityCount; j++)
+ pisid->SubAuthority[j] = WellKnownSids[i].Sid.SubAuthority[j];
+ bret = TRUE;
+ }
-/* set last error code from NT status and get the proper boolean return value */
-/* used for functions that are a simple wrapper around the corresponding ntdll API */
-static __inline BOOL set_ntstatus( NTSTATUS status )
-{
- if (status) SetLastError( RtlNtStatusToDosError( status ));
- return !status;
-}
+ if (!bret)
+ FIXME("String constant not supported: %s\n", debugstr_wn(StringSid, 2));
+ }
-#define WINE_SIZE_OF_WORLD_ACCESS_ACL (sizeof(ACL) + sizeof(ACCESS_ALLOWED_ACE) + sizeof(sidWorld) - sizeof(DWORD))
+lend:
+ if (!bret)
+ SetLastError(ERROR_INVALID_SID);
+ TRACE("returning %s\n", bret ? "TRUE" : "FALSE");
+ return bret;
+}
-/* some helper functions - taken from winehq cvs 20050916 */
/******************************************************************************
- * ComputeStringSidSize
+ * ParseAclStringFlags
*/
-static DWORD ComputeStringSidSize(LPCWSTR StringSid)
+static DWORD ParseAclStringFlags(LPCWSTR* StringAcl)
{
- int ctok = 0;
- DWORD size = sizeof(SID);
+ DWORD flags = 0;
+ LPCWSTR szAcl = *StringAcl;
- while (*StringSid)
+ while (*szAcl != '(')
{
- if (*StringSid == '-')
- ctok++;
- StringSid++;
+ if (*szAcl == 'P')
+ {
+ flags |= SE_DACL_PROTECTED;
+ }
+ else if (*szAcl == 'A')
+ {
+ szAcl++;
+ if (*szAcl == 'R')
+ flags |= SE_DACL_AUTO_INHERIT_REQ;
+ else if (*szAcl == 'I')
+ flags |= SE_DACL_AUTO_INHERITED;
+ }
+ szAcl++;
}
- if (ctok > 3)
- size += (ctok - 3) * sizeof(DWORD);
-
- return size;
+ *StringAcl = szAcl;
+ return flags;
}
/******************************************************************************
*/
static const ACEFLAG AceType[] =
{
- { SDDL_ACCESS_ALLOWED, ACCESS_ALLOWED_ACE_TYPE },
{ SDDL_ALARM, SYSTEM_ALARM_ACE_TYPE },
{ SDDL_AUDIT, SYSTEM_AUDIT_ACE_TYPE },
+ { SDDL_ACCESS_ALLOWED, ACCESS_ALLOWED_ACE_TYPE },
{ SDDL_ACCESS_DENIED, ACCESS_DENIED_ACE_TYPE },
+ /*
{ SDDL_OBJECT_ACCESS_ALLOWED, ACCESS_ALLOWED_OBJECT_ACE_TYPE },
{ SDDL_OBJECT_ACCESS_DENIED, ACCESS_DENIED_OBJECT_ACE_TYPE },
{ SDDL_OBJECT_ALARM, SYSTEM_ALARM_OBJECT_ACE_TYPE },
{ SDDL_OBJECT_AUDIT, SYSTEM_AUDIT_OBJECT_ACE_TYPE },
+ */
{ NULL, 0 },
};
/******************************************************************************
* ParseAceStringRights
*/
-static const ACEFLAG AceRights[] =
-{
- { SDDL_GENERIC_ALL, GENERIC_ALL },
- { SDDL_GENERIC_READ, GENERIC_READ },
- { SDDL_GENERIC_WRITE, GENERIC_WRITE },
- { SDDL_GENERIC_EXECUTE, GENERIC_EXECUTE },
- { SDDL_READ_CONTROL, READ_CONTROL },
- { SDDL_STANDARD_DELETE, DELETE },
- { SDDL_WRITE_DAC, WRITE_DAC },
- { SDDL_WRITE_OWNER, WRITE_OWNER },
- { NULL, 0 },
-};
-
static DWORD ParseAceStringRights(LPCWSTR* StringAcl)
{
UINT len = 0;
while (*p && *p != ';')
p++;
- if (p - szAcl <= 8)
+ if (p - szAcl <= 10 /* 8 hex digits + "0x" */ )
{
rights = strtoulW(szAcl, NULL, 16);
- *StringAcl = p;
+ szAcl = p;
}
else
WARN("Invalid rights string format: %s\n", debugstr_wn(szAcl, p - szAcl));
return rights;
}
+
/******************************************************************************
* ParseStringAclToAcl
*
DWORD val;
DWORD sidlen;
DWORD length = sizeof(ACL);
+ DWORD acesize = 0;
+ DWORD acecount = 0;
PACCESS_ALLOWED_ACE pAce = NULL; /* pointer to current ACE */
TRACE("%s\n", debugstr_w(StringAcl));
return FALSE;
if (pAcl) /* pAce is only useful if we're setting values */
- pAce = (PACCESS_ALLOWED_ACE) ((LPBYTE)pAcl + sizeof(PACL));
+ pAce = (PACCESS_ALLOWED_ACE) (pAcl + 1);
/* Parse ACL flags */
*lpdwFlags = ParseAclStringFlags(&StringAcl);
StringAcl++;
/* Parse ACE account sid */
- if (ParseStringSidToSid(StringAcl, pAce ? (PSID)&pAce->SidStart : NULL, &sidlen))
+ if (ParseStringSidToSid(StringAcl, pAce ? &pAce->SidStart : NULL, &sidlen))
{
while (*StringAcl && *StringAcl != ')')
StringAcl++;
goto lerr;
StringAcl++;
- length += sizeof(ACCESS_ALLOWED_ACE) - sizeof(DWORD) + sidlen;
+ acesize = sizeof(ACCESS_ALLOWED_ACE) - sizeof(DWORD) + sidlen;
+ length += acesize;
+ if (pAce)
+ {
+ pAce->Header.AceSize = acesize;
+ pAce = (PACCESS_ALLOWED_ACE)((LPBYTE)pAce + acesize);
+ }
+ acecount++;
}
*cBytes = length;
+
+ if (length > 0xffff)
+ {
+ ERR("ACL too large\n");
+ goto lerr;
+ }
+
+ if (pAcl)
+ {
+ pAcl->AclRevision = ACL_REVISION;
+ pAcl->Sbz1 = 0;
+ pAcl->AclSize = length;
+ pAcl->AceCount = acecount++;
+ pAcl->Sbz2 = 0;
+ }
return TRUE;
lerr:
+ SetLastError(ERROR_INVALID_ACL);
WARN("Invalid ACE string format\n");
return FALSE;
}
+
/******************************************************************************
* ParseStringSecurityDescriptorToSecurityDescriptor
*/
static BOOL ParseStringSecurityDescriptorToSecurityDescriptor(
LPCWSTR StringSecurityDescriptor,
- SECURITY_DESCRIPTOR* SecurityDescriptor,
+ SECURITY_DESCRIPTOR_RELATIVE* SecurityDescriptor,
LPDWORD cBytes)
{
BOOL bret = FALSE;
LPBYTE lpNext = NULL;
DWORD len;
- *cBytes = 0;
+ *cBytes = sizeof(SECURITY_DESCRIPTOR);
if (SecurityDescriptor)
- lpNext = ((LPBYTE) SecurityDescriptor) + sizeof(SECURITY_DESCRIPTOR);
+ lpNext = (LPBYTE)(SecurityDescriptor + 1);
while (*StringSecurityDescriptor)
{
- toktype = *StringSecurityDescriptor;
-
- /* Expect char identifier followed by ':' */
- StringSecurityDescriptor++;
- if (*StringSecurityDescriptor != ':')
- {
- SetLastError(ERROR_INVALID_PARAMETER);
- goto lend;
- }
- StringSecurityDescriptor++;
-
- /* Extract token */
- lptoken = StringSecurityDescriptor;
- while (*lptoken && *lptoken != ':')
- lptoken++;
-
- if (*lptoken)
- lptoken--;
-
- len = lptoken - StringSecurityDescriptor;
- memcpy( tok, StringSecurityDescriptor, len * sizeof(WCHAR) );
- tok[len] = 0;
-
- switch (toktype)
- {
- case 'O':
- {
- DWORD bytes;
-
- if (!ParseStringSidToSid(tok, (PSID)lpNext, &bytes))
- goto lend;
-
- if (SecurityDescriptor)
- {
- SecurityDescriptor->Owner = (PSID) ((DWORD) lpNext -
- (DWORD) SecurityDescriptor);
- lpNext += bytes; /* Advance to next token */
- }
-
- *cBytes += bytes;
-
- break;
- }
-
- case 'G':
- {
- DWORD bytes;
-
- if (!ParseStringSidToSid(tok, (PSID)lpNext, &bytes))
- goto lend;
-
- if (SecurityDescriptor)
- {
- SecurityDescriptor->Group = (PSID) ((DWORD) lpNext -
- (DWORD) SecurityDescriptor);
- lpNext += bytes; /* Advance to next token */
- }
-
- *cBytes += bytes;
-
- break;
- }
-
- case 'D':
- {
- DWORD flags;
- DWORD bytes;
-
- if (!ParseStringAclToAcl(tok, &flags, (PACL)lpNext, &bytes))
- goto lend;
-
- if (SecurityDescriptor)
- {
- SecurityDescriptor->Control |= SE_DACL_PRESENT | flags;
- SecurityDescriptor->Dacl = (PACL) ((DWORD) lpNext -
- (DWORD) SecurityDescriptor);
- lpNext += bytes; /* Advance to next token */
- }
-
- *cBytes += bytes;
-
- break;
- }
-
- case 'S':
- {
- DWORD flags;
- DWORD bytes;
-
- if (!ParseStringAclToAcl(tok, &flags, (PACL)lpNext, &bytes))
- goto lend;
-
- if (SecurityDescriptor)
- {
- SecurityDescriptor->Control |= SE_SACL_PRESENT | flags;
- SecurityDescriptor->Sacl = (PACL) ((DWORD) lpNext -
- (DWORD) SecurityDescriptor);
- lpNext += bytes; /* Advance to next token */
- }
-
- *cBytes += bytes;
-
- break;
- }
-
- default:
- FIXME("Unknown token\n");
- SetLastError(ERROR_INVALID_PARAMETER);
- goto lend;
- }
-
- StringSecurityDescriptor = lptoken;
- }
-
- bret = TRUE;
-
-lend:
- return bret;
-}
-
-/******************************************************************************
- * ParseAclStringFlags
- */
-static DWORD ParseAclStringFlags(LPCWSTR* StringAcl)
-{
- DWORD flags = 0;
- LPCWSTR szAcl = *StringAcl;
-
- while (*szAcl != '(')
- {
- if (*szAcl == 'P')
- {
- flags |= SE_DACL_PROTECTED;
- }
- else if (*szAcl == 'A')
- {
- szAcl++;
- if (*szAcl == 'R')
- flags |= SE_DACL_AUTO_INHERIT_REQ;
- else if (*szAcl == 'I')
- flags |= SE_DACL_AUTO_INHERITED;
- }
- szAcl++;
- }
-
- *StringAcl = szAcl;
- return flags;
-}
-
-/******************************************************************************
- * ParseStringSidToSid
- */
-static BOOL ParseStringSidToSid(LPCWSTR StringSid, PSID pSid, LPDWORD cBytes)
-{
- BOOL bret = FALSE;
- SID* pisid=pSid;
-
- TRACE("%s, %p, %p\n", debugstr_w(StringSid), pSid, cBytes);
- if (!StringSid)
- {
- SetLastError(ERROR_INVALID_PARAMETER);
- TRACE("StringSid is NULL, returning FALSE\n");
- return FALSE;
- }
-
- *cBytes = ComputeStringSidSize(StringSid);
- if (!pisid) /* Simply compute the size */
- {
- TRACE("only size requested, returning TRUE\n");
- return TRUE;
- }
-
- if (*StringSid != 'S' || *StringSid != '-') /* S-R-I-S-S */
- {
- DWORD i = 0, identAuth;
- DWORD csubauth = ((*cBytes - sizeof(SID)) / sizeof(DWORD)) + 1;
-
- StringSid += 2; /* Advance to Revision */
- pisid->Revision = atoiW(StringSid);
-
- if (pisid->Revision != SDDL_REVISION)
- {
- TRACE("Revision %d is unknown\n", pisid->Revision);
- goto lend; /* ERROR_INVALID_SID */
- }
- if (csubauth == 0)
+ toktype = *StringSecurityDescriptor;
+
+ /* Expect char identifier followed by ':' */
+ StringSecurityDescriptor++;
+ if (*StringSecurityDescriptor != ':')
{
- TRACE("SubAuthorityCount is 0\n");
- goto lend; /* ERROR_INVALID_SID */
+ SetLastError(ERROR_INVALID_PARAMETER);
+ goto lend;
}
+ StringSecurityDescriptor++;
- pisid->SubAuthorityCount = csubauth;
+ /* Extract token */
+ lptoken = StringSecurityDescriptor;
+ while (*lptoken && *lptoken != ':')
+ lptoken++;
- /* Advance to identifier authority */
- while (*StringSid && *StringSid != '-')
- StringSid++;
- if (*StringSid == '-')
- StringSid++;
+ if (*lptoken)
+ lptoken--;
- /* MS' implementation can't handle values greater than 2^32 - 1, so
- * we don't either; assume most significant bytes are always 0
- */
- pisid->IdentifierAuthority.Value[0] = 0;
- pisid->IdentifierAuthority.Value[1] = 0;
- identAuth = atoiW(StringSid);
- pisid->IdentifierAuthority.Value[5] = identAuth & 0xff;
- pisid->IdentifierAuthority.Value[4] = (identAuth & 0xff00) >> 8;
- pisid->IdentifierAuthority.Value[3] = (identAuth & 0xff0000) >> 16;
- pisid->IdentifierAuthority.Value[2] = (identAuth & 0xff000000) >> 24;
+ len = lptoken - StringSecurityDescriptor;
+ memcpy( tok, StringSecurityDescriptor, len * sizeof(WCHAR) );
+ tok[len] = 0;
- /* Advance to first sub authority */
- while (*StringSid && *StringSid != '-')
- StringSid++;
- if (*StringSid == '-')
- StringSid++;
+ switch (toktype)
+ {
+ case 'O':
+ {
+ DWORD bytes;
- while (*StringSid)
- {
- while (*StringSid && *StringSid != '-')
- StringSid++;
+ if (!ParseStringSidToSid(tok, lpNext, &bytes))
+ goto lend;
- pisid->SubAuthority[i++] = atoiW(StringSid);
- }
+ if (SecurityDescriptor)
+ {
+ SecurityDescriptor->Owner = lpNext - (LPBYTE)SecurityDescriptor;
+ lpNext += bytes; /* Advance to next token */
+ }
- if (i != pisid->SubAuthorityCount)
- goto lend; /* ERROR_INVALID_SID */
+ *cBytes += bytes;
- bret = TRUE;
- }
- else /* String constant format - Only available in winxp and above */
- {
- pisid->Revision = SDDL_REVISION;
- pisid->SubAuthorityCount = 1;
+ break;
+ }
- FIXME("String constant not supported: %s\n", debugstr_wn(StringSid, 2));
+ case 'G':
+ {
+ DWORD bytes;
- /* TODO: Lookup string of well-known SIDs in table */
- pisid->IdentifierAuthority.Value[5] = 0;
- pisid->SubAuthority[0] = 0;
+ if (!ParseStringSidToSid(tok, lpNext, &bytes))
+ goto lend;
- bret = TRUE;
- }
+ if (SecurityDescriptor)
+ {
+ SecurityDescriptor->Group = lpNext - (LPBYTE)SecurityDescriptor;
+ lpNext += bytes; /* Advance to next token */
+ }
-lend:
- if (!bret)
- SetLastError(ERROR_INVALID_SID);
+ *cBytes += bytes;
- TRACE("returning %s\n", bret ? "TRUE" : "FALSE");
- return bret;
-}
+ break;
+ }
-/* Exported functions */
+ case 'D':
+ {
+ DWORD flags;
+ DWORD bytes;
-/*
- * @implemented
- */
-BOOL STDCALL
-AllocateLocallyUniqueId(PLUID Luid)
-{
- NTSTATUS Status;
+ if (!ParseStringAclToAcl(tok, &flags, (PACL)lpNext, &bytes))
+ goto lend;
- Status = NtAllocateLocallyUniqueId (Luid);
- if (!NT_SUCCESS (Status))
- {
- SetLastError (RtlNtStatusToDosError (Status));
- return FALSE;
- }
+ if (SecurityDescriptor)
+ {
+ SecurityDescriptor->Control |= SE_DACL_PRESENT | flags;
+ SecurityDescriptor->Dacl = lpNext - (LPBYTE)SecurityDescriptor;
+ lpNext += bytes; /* Advance to next token */
+ }
- return TRUE;
-}
+ *cBytes += bytes;
+ break;
+ }
-/*
- * @implemented
- */
-BOOL STDCALL
-AllocateAndInitializeSid (PSID_IDENTIFIER_AUTHORITY pIdentifierAuthority,
- BYTE nSubAuthorityCount,
- DWORD dwSubAuthority0,
- DWORD dwSubAuthority1,
- DWORD dwSubAuthority2,
- DWORD dwSubAuthority3,
- DWORD dwSubAuthority4,
- DWORD dwSubAuthority5,
- DWORD dwSubAuthority6,
- DWORD dwSubAuthority7,
- PSID *pSid)
-{
- NTSTATUS Status;
-
- Status = RtlAllocateAndInitializeSid (pIdentifierAuthority,
- nSubAuthorityCount,
- dwSubAuthority0,
- dwSubAuthority1,
- dwSubAuthority2,
- dwSubAuthority3,
- dwSubAuthority4,
- dwSubAuthority5,
- dwSubAuthority6,
- dwSubAuthority7,
- pSid);
- if (!NT_SUCCESS (Status))
- {
- SetLastError (RtlNtStatusToDosError (Status));
- return FALSE;
- }
+ case 'S':
+ {
+ DWORD flags;
+ DWORD bytes;
- return TRUE;
-}
+ if (!ParseStringAclToAcl(tok, &flags, (PACL)lpNext, &bytes))
+ goto lend;
+ if (SecurityDescriptor)
+ {
+ SecurityDescriptor->Control |= SE_SACL_PRESENT | flags;
+ SecurityDescriptor->Sacl = lpNext - (LPBYTE)SecurityDescriptor;
+ lpNext += bytes; /* Advance to next token */
+ }
-/*
- * @implemented
- */
-BOOL STDCALL
-CopySid (DWORD nDestinationSidLength,
- PSID pDestinationSid,
- PSID pSourceSid)
-{
- NTSTATUS Status;
+ *cBytes += bytes;
- Status = RtlCopySid (nDestinationSidLength,
- pDestinationSid,
- pSourceSid);
- if (!NT_SUCCESS (Status))
- {
- SetLastError (RtlNtStatusToDosError (Status));
- return FALSE;
+ break;
+ }
+
+ default:
+ FIXME("Unknown token\n");
+ SetLastError(ERROR_INVALID_PARAMETER);
+ goto lend;
+ }
+
+ StringSecurityDescriptor = lptoken;
}
- return TRUE;
+ bret = TRUE;
+
+lend:
+ return bret;
}
-/* Winehq cvs 20050916 */
+
+
/******************************************************************************
* ConvertStringSecurityDescriptorToSecurityDescriptorW [ADVAPI32.@]
* @implemented
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
goto lend;
}
+ else if (!StringSecurityDescriptor || !SecurityDescriptor)
+ {
+ SetLastError(ERROR_INVALID_PARAMETER);
+ goto lend;
+ }
else if (StringSDRevision != SID_REVISION)
{
SetLastError(ERROR_UNKNOWN_REVISION);
NULL, &cBytes))
goto lend;
- psd = *SecurityDescriptor = (SECURITY_DESCRIPTOR*) LocalAlloc(
- GMEM_ZEROINIT, cBytes);
+ psd = *SecurityDescriptor = LocalAlloc(GMEM_ZEROINIT, cBytes);
+ if (!psd) goto lend;
psd->Revision = SID_REVISION;
psd->Control |= SE_SELF_RELATIVE;
if (!ParseStringSecurityDescriptorToSecurityDescriptor(StringSecurityDescriptor,
- psd, &cBytes))
+ (SECURITY_DESCRIPTOR_RELATIVE *)psd, &cBytes))
{
LocalFree(psd);
goto lend;
return bret;
}
+
/* Winehq cvs 20050916 */
/******************************************************************************
* ConvertStringSecurityDescriptorToSecurityDescriptorA [ADVAPI32.@]
/*
* @implemented
*/
-BOOL STDCALL
-EqualPrefixSid (PSID pSid1,
- PSID pSid2)
+BOOL WINAPI
+EqualPrefixSid(PSID pSid1,
+ PSID pSid2)
{
- return RtlEqualPrefixSid (pSid1, pSid2);
+ return RtlEqualPrefixSid (pSid1, pSid2);
}
/*
* @implemented
*/
-BOOL STDCALL
-EqualSid (PSID pSid1,
- PSID pSid2)
+BOOL WINAPI
+EqualSid(PSID pSid1,
+ PSID pSid2)
{
- return RtlEqualSid (pSid1, pSid2);
+ return RtlEqualSid (pSid1, pSid2);
}
* Docs says this function does NOT return a value
* even thou it's defined to return a PVOID...
*/
-PVOID STDCALL
-FreeSid (PSID pSid)
+PVOID WINAPI
+FreeSid(PSID pSid)
{
- return RtlFreeSid (pSid);
+ return RtlFreeSid(pSid);
}
/*
* @implemented
*/
-DWORD STDCALL
-GetLengthSid (PSID pSid)
+DWORD WINAPI
+GetLengthSid(PSID pSid)
{
- return (DWORD)RtlLengthSid (pSid);
+ return (DWORD)RtlLengthSid(pSid);
}
/*
* @implemented
*/
-PSID_IDENTIFIER_AUTHORITY STDCALL
-GetSidIdentifierAuthority (PSID pSid)
+PSID_IDENTIFIER_AUTHORITY WINAPI
+GetSidIdentifierAuthority(PSID pSid)
{
- return RtlIdentifierAuthoritySid (pSid);
+ return RtlIdentifierAuthoritySid(pSid);
}
/*
* @implemented
*/
-DWORD STDCALL
-GetSidLengthRequired (UCHAR nSubAuthorityCount)
+DWORD WINAPI
+GetSidLengthRequired(UCHAR nSubAuthorityCount)
{
- return (DWORD)RtlLengthRequiredSid (nSubAuthorityCount);
+ return (DWORD)RtlLengthRequiredSid(nSubAuthorityCount);
}
/*
* @implemented
*/
-PDWORD STDCALL
-GetSidSubAuthority (PSID pSid,
- DWORD nSubAuthority)
+PDWORD WINAPI
+GetSidSubAuthority(PSID pSid,
+ DWORD nSubAuthority)
{
- return (PDWORD)RtlSubAuthoritySid (pSid, nSubAuthority);
+ return (PDWORD)RtlSubAuthoritySid(pSid, nSubAuthority);
}
/*
* @implemented
*/
-PUCHAR STDCALL
-GetSidSubAuthorityCount (PSID pSid)
+PUCHAR WINAPI
+GetSidSubAuthorityCount(PSID pSid)
{
- return RtlSubAuthorityCountSid (pSid);
+ return RtlSubAuthorityCountSid(pSid);
}
/*
* @implemented
*/
-BOOL STDCALL
-InitializeSid (PSID Sid,
- PSID_IDENTIFIER_AUTHORITY pIdentifierAuthority,
- BYTE nSubAuthorityCount)
+BOOL WINAPI
+InitializeSid(PSID Sid,
+ PSID_IDENTIFIER_AUTHORITY pIdentifierAuthority,
+ BYTE nSubAuthorityCount)
{
- NTSTATUS Status;
+ NTSTATUS Status;
- Status = RtlInitializeSid (Sid,
- pIdentifierAuthority,
- nSubAuthorityCount);
- if (!NT_SUCCESS (Status))
+ Status = RtlInitializeSid(Sid,
+ pIdentifierAuthority,
+ nSubAuthorityCount);
+ if (!NT_SUCCESS(Status))
{
- SetLastError (RtlNtStatusToDosError (Status));
- return FALSE;
+ SetLastError(RtlNtStatusToDosError(Status));
+ return FALSE;
}
- return TRUE;
+ return TRUE;
}
/*
* @implemented
*/
-BOOL STDCALL
-IsValidSid (PSID pSid)
+BOOL WINAPI
+IsValidSid(PSID pSid)
{
- return (BOOL)RtlValidSid (pSid);
+ return (BOOL)RtlValidSid(pSid);
}
+
/*
* @implemented
*/
-BOOL STDCALL
-ConvertSidToStringSidW(PSID Sid, LPWSTR *StringSid)
+BOOL WINAPI
+ConvertSidToStringSidW(PSID Sid,
+ LPWSTR *StringSid)
{
- NTSTATUS Status;
- UNICODE_STRING UnicodeString;
- WCHAR FixedBuffer[64];
+ NTSTATUS Status;
+ UNICODE_STRING UnicodeString;
+ WCHAR FixedBuffer[64];
- if (! RtlValidSid(Sid))
+ if (!RtlValidSid(Sid))
{
- SetLastError(ERROR_INVALID_SID);
- return FALSE;
+ SetLastError(ERROR_INVALID_SID);
+ return FALSE;
}
- UnicodeString.Length = 0;
- UnicodeString.MaximumLength = sizeof(FixedBuffer);
- UnicodeString.Buffer = FixedBuffer;
- Status = RtlConvertSidToUnicodeString(&UnicodeString, Sid, FALSE);
- if (STATUS_BUFFER_TOO_SMALL == Status)
+ UnicodeString.Length = 0;
+ UnicodeString.MaximumLength = sizeof(FixedBuffer);
+ UnicodeString.Buffer = FixedBuffer;
+ Status = RtlConvertSidToUnicodeString(&UnicodeString, Sid, FALSE);
+ if (STATUS_BUFFER_TOO_SMALL == Status)
{
- Status = RtlConvertSidToUnicodeString(&UnicodeString, Sid, TRUE);
+ Status = RtlConvertSidToUnicodeString(&UnicodeString, Sid, TRUE);
}
- if (! NT_SUCCESS(Status))
+
+ if (!NT_SUCCESS(Status))
{
- SetLastError(RtlNtStatusToDosError(Status));
- return FALSE;
+ SetLastError(RtlNtStatusToDosError(Status));
+ return FALSE;
}
- *StringSid = LocalAlloc(LMEM_FIXED, UnicodeString.Length + sizeof(WCHAR));
- if (NULL == *StringSid)
+ *StringSid = LocalAlloc(LMEM_FIXED, UnicodeString.Length + sizeof(WCHAR));
+ if (NULL == *StringSid)
{
- if (UnicodeString.Buffer != FixedBuffer)
+ if (UnicodeString.Buffer != FixedBuffer)
{
- RtlFreeUnicodeString(&UnicodeString);
+ RtlFreeUnicodeString(&UnicodeString);
}
SetLastError(ERROR_NOT_ENOUGH_MEMORY);
return FALSE;
}
- MoveMemory(*StringSid, UnicodeString.Buffer, UnicodeString.Length);
- ZeroMemory((PCHAR) *StringSid + UnicodeString.Length, sizeof(WCHAR));
- if (UnicodeString.Buffer != FixedBuffer)
+ MoveMemory(*StringSid, UnicodeString.Buffer, UnicodeString.Length);
+ ZeroMemory((PCHAR) *StringSid + UnicodeString.Length, sizeof(WCHAR));
+ if (UnicodeString.Buffer != FixedBuffer)
{
- RtlFreeUnicodeString(&UnicodeString);
+ RtlFreeUnicodeString(&UnicodeString);
}
- return TRUE;
+ return TRUE;
}
/*
* @implemented
*/
-BOOL STDCALL
-ConvertSidToStringSidA(PSID Sid, LPSTR *StringSid)
+BOOL WINAPI
+ConvertSidToStringSidA(PSID Sid,
+ LPSTR *StringSid)
{
- LPWSTR StringSidW;
- int Len;
+ LPWSTR StringSidW;
+ int Len;
- if (! ConvertSidToStringSidW(Sid, &StringSidW))
+ if (!ConvertSidToStringSidW(Sid, &StringSidW))
{
- return FALSE;
+ return FALSE;
}
- Len = WideCharToMultiByte(CP_ACP, 0, StringSidW, -1, NULL, 0, NULL, NULL);
- if (Len <= 0)
+ Len = WideCharToMultiByte(CP_ACP, 0, StringSidW, -1, NULL, 0, NULL, NULL);
+ if (Len <= 0)
{
- LocalFree(StringSidW);
- SetLastError(ERROR_NOT_ENOUGH_MEMORY);
- return FALSE;
+ LocalFree(StringSidW);
+ SetLastError(ERROR_NOT_ENOUGH_MEMORY);
+ return FALSE;
}
- *StringSid = LocalAlloc(LMEM_FIXED, Len);
- if (NULL == *StringSid)
+
+ *StringSid = LocalAlloc(LMEM_FIXED, Len);
+ if (NULL == *StringSid)
{
- LocalFree(StringSidW);
- SetLastError(ERROR_NOT_ENOUGH_MEMORY);
- return FALSE;
+ LocalFree(StringSidW);
+ SetLastError(ERROR_NOT_ENOUGH_MEMORY);
+ return FALSE;
}
- if (! WideCharToMultiByte(CP_ACP, 0, StringSidW, -1, *StringSid, Len, NULL, NULL))
+ if (!WideCharToMultiByte(CP_ACP, 0, StringSidW, -1, *StringSid, Len, NULL, NULL))
{
- LocalFree(StringSid);
- LocalFree(StringSidW);
- return FALSE;
+ LocalFree(StringSid);
+ LocalFree(StringSidW);
+ return FALSE;
}
- LocalFree(StringSidW);
+ LocalFree(StringSidW);
- return TRUE;
+ return TRUE;
}
/*
* @unimplemented
*/
-BOOL STDCALL
+BOOL WINAPI
EqualDomainSid(IN PSID pSid1,
IN PSID pSid2,
OUT BOOL* pfEqual)
{
- FIXME("%s() not implemented!\n", __FUNCTION__);
+ UNIMPLEMENTED;
return FALSE;
}
/*
* @unimplemented
*/
-BOOL STDCALL
+BOOL WINAPI
GetWindowsAccountDomainSid(IN PSID pSid,
OUT PSID ppDomainSid,
IN OUT DWORD* cbSid)
{
- FIXME("%s() not implemented!\n", __FUNCTION__);
+ UNIMPLEMENTED;
return FALSE;
}
/*
* @unimplemented
*/
-BOOL STDCALL
+BOOL WINAPI
CreateWellKnownSid(IN WELL_KNOWN_SID_TYPE WellKnownSidType,
IN PSID DomainSid OPTIONAL,
OUT PSID pSid,
IN OUT DWORD* cbSid)
{
- FIXME("unimplemented!\n", __FUNCTION__);
+ unsigned int i;
+ TRACE("(%d, %s, %p, %p)\n", WellKnownSidType, debugstr_sid(DomainSid), pSid, cbSid);
+
+ if (cbSid == NULL || (DomainSid && !IsValidSid(DomainSid)))
+ {
+ SetLastError(ERROR_INVALID_PARAMETER);
+ return FALSE;
+ }
+
+ for (i = 0; i < sizeof(WellKnownSids)/sizeof(WellKnownSids[0]); i++) {
+ if (WellKnownSids[i].Type == WellKnownSidType) {
+ DWORD length = GetSidLengthRequired(WellKnownSids[i].Sid.SubAuthorityCount);
+
+ if (*cbSid < length)
+ {
+ *cbSid = length;
+ SetLastError(ERROR_INSUFFICIENT_BUFFER);
+ return FALSE;
+ }
+ if (!pSid)
+ {
+ SetLastError(ERROR_INVALID_PARAMETER);
+ return FALSE;
+ }
+ CopyMemory(pSid, &WellKnownSids[i].Sid.Revision, length);
+ *cbSid = length;
+ return TRUE;
+ }
+ }
+
+ if (DomainSid == NULL || *GetSidSubAuthorityCount(DomainSid) == SID_MAX_SUB_AUTHORITIES)
+ {
+ SetLastError(ERROR_INVALID_PARAMETER);
+ return FALSE;
+ }
+
+ for (i = 0; i < sizeof(WellKnownRids)/sizeof(WellKnownRids[0]); i++)
+ if (WellKnownRids[i].Type == WellKnownSidType) {
+ UCHAR domain_subauth = *GetSidSubAuthorityCount(DomainSid);
+ DWORD domain_sid_length = GetSidLengthRequired(domain_subauth);
+ DWORD output_sid_length = GetSidLengthRequired(domain_subauth + 1);
+
+ if (*cbSid < output_sid_length)
+ {
+ *cbSid = output_sid_length;
+ SetLastError(ERROR_INSUFFICIENT_BUFFER);
+ return FALSE;
+ }
+ if (!pSid)
+ {
+ SetLastError(ERROR_INVALID_PARAMETER);
+ return FALSE;
+ }
+ CopyMemory(pSid, DomainSid, domain_sid_length);
+ (*GetSidSubAuthorityCount(pSid))++;
+ (*GetSidSubAuthority(pSid, domain_subauth)) = WellKnownRids[i].Rid;
+ *cbSid = output_sid_length;
+ return TRUE;
+ }
+
+ SetLastError(ERROR_INVALID_PARAMETER);
return FALSE;
}
/*
* @unimplemented
*/
-BOOL STDCALL
+BOOL WINAPI
IsWellKnownSid(IN PSID pSid,
IN WELL_KNOWN_SID_TYPE WellKnownSidType)
{
- FIXME("unimplemented!\n", __FUNCTION__);
+ unsigned int i;
+ TRACE("(%s, %d)\n", debugstr_sid(pSid), WellKnownSidType);
+
+ for (i = 0; i < sizeof(WellKnownSids) / sizeof(WellKnownSids[0]); i++)
+ {
+ if (WellKnownSids[i].Type == WellKnownSidType)
+ {
+ if (EqualSid(pSid, (PSID)((ULONG_PTR)&WellKnownSids[i].Sid.Revision)))
+ return TRUE;
+ }
+ }
+
return FALSE;
}
/*
* @implemented
*/
-BOOL STDCALL
-ConvertStringSidToSidA(
- IN LPCSTR StringSid,
- OUT PSID* sid)
+BOOL WINAPI
+ConvertStringSidToSidA(IN LPCSTR StringSid,
+ OUT PSID* sid)
{
BOOL bRetVal = FALSE;
return bRetVal;
}
+
+static const RECORD SidTable[] =
+{
+ { SDDL_ACCOUNT_OPERATORS, WinBuiltinAccountOperatorsSid },
+ { SDDL_ALIAS_PREW2KCOMPACC, WinBuiltinPreWindows2000CompatibleAccessSid },
+ { SDDL_ANONYMOUS, WinAnonymousSid },
+ { SDDL_AUTHENTICATED_USERS, WinAuthenticatedUserSid },
+ { SDDL_BUILTIN_ADMINISTRATORS, WinBuiltinAdministratorsSid },
+ { SDDL_BUILTIN_GUESTS, WinBuiltinGuestsSid },
+ { SDDL_BACKUP_OPERATORS, WinBuiltinBackupOperatorsSid },
+ { SDDL_BUILTIN_USERS, WinBuiltinUsersSid },
+ { SDDL_CERT_SERV_ADMINISTRATORS, WinAccountCertAdminsSid /* FIXME: DOMAIN_GROUP_RID_CERT_ADMINS */ },
+ { SDDL_CREATOR_GROUP, WinCreatorGroupSid },
+ { SDDL_CREATOR_OWNER, WinCreatorOwnerSid },
+ { SDDL_DOMAIN_ADMINISTRATORS, WinAccountDomainAdminsSid /* FIXME: DOMAIN_GROUP_RID_ADMINS */ },
+ { SDDL_DOMAIN_COMPUTERS, WinAccountComputersSid /* FIXME: DOMAIN_GROUP_RID_COMPUTERS */ },
+ { SDDL_DOMAIN_DOMAIN_CONTROLLERS, WinAccountControllersSid /* FIXME: DOMAIN_GROUP_RID_CONTROLLERS */ },
+ { SDDL_DOMAIN_GUESTS, WinAccountDomainGuestsSid /* FIXME: DOMAIN_GROUP_RID_GUESTS */ },
+ { SDDL_DOMAIN_USERS, WinAccountDomainUsersSid /* FIXME: DOMAIN_GROUP_RID_USERS */ },
+ { SDDL_ENTERPRISE_ADMINS, WinAccountEnterpriseAdminsSid /* FIXME: DOMAIN_GROUP_RID_ENTERPRISE_ADMINS */ },
+ { SDDL_ENTERPRISE_DOMAIN_CONTROLLERS, WinLogonIdsSid /* FIXME: SECURITY_SERVER_LOGON_RID */ },
+ { SDDL_EVERYONE, WinWorldSid },
+ { SDDL_GROUP_POLICY_ADMINS, WinAccountPolicyAdminsSid /* FIXME: DOMAIN_GROUP_RID_POLICY_ADMINS */ },
+ { SDDL_INTERACTIVE, WinInteractiveSid },
+ { SDDL_LOCAL_ADMIN, WinAccountAdministratorSid /* FIXME: DOMAIN_USER_RID_ADMIN */ },
+ { SDDL_LOCAL_GUEST, WinAccountGuestSid /* FIXME: DOMAIN_USER_RID_GUEST */ },
+ { SDDL_LOCAL_SERVICE, WinLocalServiceSid },
+ { SDDL_LOCAL_SYSTEM, WinLocalSystemSid },
+ { SDDL_NETWORK, WinNetworkSid },
+ { SDDL_NETWORK_CONFIGURATION_OPS, WinBuiltinNetworkConfigurationOperatorsSid },
+ { SDDL_NETWORK_SERVICE, WinNetworkServiceSid },
+ { SDDL_PRINTER_OPERATORS, WinBuiltinPrintOperatorsSid },
+ { SDDL_PERSONAL_SELF, WinSelfSid },
+ { SDDL_POWER_USERS, WinBuiltinPowerUsersSid },
+ { SDDL_RAS_SERVERS, WinAccountRasAndIasServersSid /* FIXME: DOMAIN_ALIAS_RID_RAS_SERVERS */ },
+ { SDDL_REMOTE_DESKTOP, WinBuiltinRemoteDesktopUsersSid },
+ { SDDL_REPLICATOR, WinBuiltinReplicatorSid },
+ { SDDL_RESTRICTED_CODE, WinRestrictedCodeSid },
+ { SDDL_SCHEMA_ADMINISTRATORS, WinAccountSchemaAdminsSid /* FIXME: DOMAIN_GROUP_RID_SCHEMA_ADMINS */ },
+ { SDDL_SERVER_OPERATORS, WinBuiltinSystemOperatorsSid },
+ { SDDL_SERVICE, WinServiceSid },
+ { NULL, 0 },
+};
+
/*
- * @unimplemented
+ * @implemented
*/
-BOOL STDCALL
-ConvertStringSidToSidW(
- IN LPCWSTR StringSid,
- OUT PSID* sid)
+BOOL WINAPI
+ConvertStringSidToSidW(IN LPCWSTR StringSid,
+ OUT PSID* sid)
{
- FIXME("unimplemented!\n", __FUNCTION__);
- return FALSE;
+ DWORD size;
+ DWORD i, cBytes, identAuth, csubauth;
+ BOOL ret;
+ SID* pisid;
+
+ TRACE("%s %p\n", debugstr_w(StringSid), sid);
+
+ if (!StringSid)
+ {
+ SetLastError(ERROR_INVALID_SID);
+ return FALSE;
+ }
+ for (i = 0; i < sizeof(SidTable) / sizeof(SidTable[0]) - 1; i++)
+ {
+ if (wcscmp(StringSid, SidTable[i].key) == 0)
+ {
+ WELL_KNOWN_SID_TYPE knownSid = (WELL_KNOWN_SID_TYPE)SidTable[i].value;
+ size = SECURITY_MAX_SID_SIZE;
+ *sid = LocalAlloc(0, size);
+ if (!*sid)
+ {
+ SetLastError(ERROR_NOT_ENOUGH_MEMORY);
+ return FALSE;
+ }
+ ret = CreateWellKnownSid(
+ knownSid,
+ NULL,
+ *sid,
+ &size);
+ if (!ret)
+ {
+ SetLastError(ERROR_INVALID_SID);
+ LocalFree(*sid);
+ }
+ return ret;
+ }
+ }
+
+ /* That's probably a string S-R-I-S-S... */
+ if (StringSid[0] != 'S' || StringSid[1] != '-')
+ {
+ SetLastError(ERROR_INVALID_SID);
+ return FALSE;
+ }
+
+ cBytes = ComputeStringSidSize(StringSid);
+ pisid = (SID*)LocalAlloc( 0, cBytes );
+ if (!pisid)
+ {
+ SetLastError(ERROR_NOT_ENOUGH_MEMORY);
+ return FALSE;
+ }
+ i = 0;
+ ret = FALSE;
+ csubauth = ((cBytes - GetSidLengthRequired(0)) / sizeof(DWORD));
+
+ StringSid += 2; /* Advance to Revision */
+ pisid->Revision = atoiW(StringSid);
+
+ if (pisid->Revision != SDDL_REVISION)
+ {
+ TRACE("Revision %d is unknown\n", pisid->Revision);
+ goto lend; /* ERROR_INVALID_SID */
+ }
+ if (csubauth == 0)
+ {
+ TRACE("SubAuthorityCount is 0\n");
+ goto lend; /* ERROR_INVALID_SID */
+ }
+
+ pisid->SubAuthorityCount = csubauth;
+
+ /* Advance to identifier authority */
+ while (*StringSid && *StringSid != '-')
+ StringSid++;
+ if (*StringSid == '-')
+ StringSid++;
+
+ /* MS' implementation can't handle values greater than 2^32 - 1, so
+ * we don't either; assume most significant bytes are always 0
+ */
+ pisid->IdentifierAuthority.Value[0] = 0;
+ pisid->IdentifierAuthority.Value[1] = 0;
+ identAuth = atoiW(StringSid);
+ pisid->IdentifierAuthority.Value[5] = identAuth & 0xff;
+ pisid->IdentifierAuthority.Value[4] = (identAuth & 0xff00) >> 8;
+ pisid->IdentifierAuthority.Value[3] = (identAuth & 0xff0000) >> 16;
+ pisid->IdentifierAuthority.Value[2] = (identAuth & 0xff000000) >> 24;
+
+ /* Advance to first sub authority */
+ while (*StringSid && *StringSid != '-')
+ StringSid++;
+ if (*StringSid == '-')
+ StringSid++;
+
+ pisid->SubAuthority[i] = atoiW(StringSid);
+
+ while (*StringSid)
+ {
+ while (*StringSid && *StringSid != '-')
+ StringSid++;
+ if (*StringSid == '-')
+ StringSid++;
+
+ pisid->SubAuthority[++i] = atoiW(StringSid);
+ }
+
+ if (i != pisid->SubAuthorityCount)
+ goto lend; /* ERROR_INVALID_SID */
+
+ *sid = pisid;
+ ret = TRUE;
+
+lend:
+ if (!ret)
+ SetLastError(ERROR_INVALID_SID);
+
+ TRACE("returning %s\n", ret ? "TRUE" : "FALSE");
+ return ret;
}