2006-10-11 22:14:05 +00:00
|
|
|
|
/*
|
2000-04-05 01:41:01 +00:00
|
|
|
|
* COPYRIGHT: See COPYING in the top level directory
|
2005-08-16 05:17:06 +00:00
|
|
|
|
* WINE COPYRIGHT:
|
|
|
|
|
* Copyright 1999, 2000 Juergen Schmied <juergen.schmied@debitel.net>
|
|
|
|
|
* Copyright 2003 CodeWeavers Inc. (Ulrich Czekalla)
|
2008-11-24 19:27:30 +00:00
|
|
|
|
* Copyright 2006 Robert Reif
|
2006-10-11 22:14:05 +00:00
|
|
|
|
* Copyright 2006 Herv<EFBFBD> Poussineau
|
2005-08-16 05:17:06 +00:00
|
|
|
|
*
|
2000-04-05 01:41:01 +00:00
|
|
|
|
* PROJECT: ReactOS system libraries
|
2008-11-24 19:27:30 +00:00
|
|
|
|
* FILE: dll/win32/advapi32/sec/sid.c
|
2000-04-05 01:41:01 +00:00
|
|
|
|
* PURPOSE: Security ID functions
|
|
|
|
|
*/
|
|
|
|
|
|
2005-08-05 10:31:28 +00:00
|
|
|
|
#include <advapi32.h>
|
2006-10-11 22:14:05 +00:00
|
|
|
|
#include <sddl.h>
|
2005-08-16 05:17:06 +00:00
|
|
|
|
#include <wine/debug.h>
|
|
|
|
|
#include <wine/unicode.h>
|
|
|
|
|
|
|
|
|
|
WINE_DEFAULT_DEBUG_CHANNEL(advapi);
|
|
|
|
|
|
2006-10-11 22:14:05 +00:00
|
|
|
|
#define MAX_GUID_STRING_LEN 39
|
2005-08-16 05:17:06 +00:00
|
|
|
|
|
2008-11-30 11:42:05 +00:00
|
|
|
|
BOOL WINAPI
|
2007-05-15 11:21:09 +00:00
|
|
|
|
AddAuditAccessAceEx(PACL pAcl,
|
|
|
|
|
DWORD dwAceRevision,
|
|
|
|
|
DWORD AceFlags,
|
|
|
|
|
DWORD dwAccessMask,
|
|
|
|
|
PSID pSid,
|
|
|
|
|
BOOL bAuditSuccess,
|
|
|
|
|
BOOL bAuditFailure);
|
|
|
|
|
|
2006-10-11 22:14:05 +00:00
|
|
|
|
typedef struct RECORD
|
2005-08-16 05:17:06 +00:00
|
|
|
|
{
|
2006-10-11 22:14:05 +00:00
|
|
|
|
LPCWSTR key;
|
|
|
|
|
DWORD value;
|
|
|
|
|
} RECORD;
|
|
|
|
|
|
2005-08-16 05:17:06 +00:00
|
|
|
|
|
2006-08-06 18:22:36 +00:00
|
|
|
|
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;
|
|
|
|
|
|
2008-11-10 14:25:24 +00:00
|
|
|
|
typedef struct _ACEFLAG
|
|
|
|
|
{
|
|
|
|
|
LPCWSTR wstr;
|
|
|
|
|
DWORD value;
|
|
|
|
|
} ACEFLAG, *LPACEFLAG;
|
|
|
|
|
|
2006-08-06 18:22:36 +00:00
|
|
|
|
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 } } },
|
2007-12-09 15:46:24 +00:00
|
|
|
|
{ {0,0}, WinNtAuthoritySid, { SID_REVISION, 0, { SECURITY_NT_AUTHORITY }, { SECURITY_NULL_RID } } },
|
2006-08-06 18:22:36 +00:00
|
|
|
|
{ {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 } } },
|
|
|
|
|
};
|
|
|
|
|
|
2006-05-10 09:44:06 +00:00
|
|
|
|
static const SID sidWorld = { SID_REVISION, 1, { SECURITY_WORLD_SID_AUTHORITY} , { SECURITY_WORLD_RID } };
|
2000-04-05 01:41:01 +00:00
|
|
|
|
|
2005-08-16 05:17:06 +00:00
|
|
|
|
/*
|
|
|
|
|
* ACE types
|
|
|
|
|
*/
|
|
|
|
|
static const WCHAR SDDL_ACCESS_ALLOWED[] = {'A',0};
|
|
|
|
|
static const WCHAR SDDL_ACCESS_DENIED[] = {'D',0};
|
|
|
|
|
static const WCHAR SDDL_OBJECT_ACCESS_ALLOWED[] = {'O','A',0};
|
|
|
|
|
static const WCHAR SDDL_OBJECT_ACCESS_DENIED[] = {'O','D',0};
|
|
|
|
|
static const WCHAR SDDL_AUDIT[] = {'A','U',0};
|
|
|
|
|
static const WCHAR SDDL_ALARM[] = {'A','L',0};
|
|
|
|
|
static const WCHAR SDDL_OBJECT_AUDIT[] = {'O','U',0};
|
2006-05-10 09:44:06 +00:00
|
|
|
|
static const WCHAR SDDL_OBJECT_ALARM[] = {'O','L',0};
|
2005-08-16 05:17:06 +00:00
|
|
|
|
|
2006-10-11 22:14:05 +00:00
|
|
|
|
/*
|
|
|
|
|
* 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
|
|
|
|
|
|
2005-08-16 05:17:06 +00:00
|
|
|
|
/*
|
|
|
|
|
* 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};
|
|
|
|
|
|
2006-08-06 18:22:36 +00:00
|
|
|
|
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)";
|
|
|
|
|
}
|
|
|
|
|
|
2008-11-10 14:25:24 +00:00
|
|
|
|
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
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
2005-08-16 05:17:06 +00:00
|
|
|
|
/* 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 */
|
2005-11-28 23:35:35 +00:00
|
|
|
|
static __inline BOOL set_ntstatus( NTSTATUS status )
|
2005-08-16 05:17:06 +00:00
|
|
|
|
{
|
|
|
|
|
if (status) SetLastError( RtlNtStatusToDosError( status ));
|
|
|
|
|
return !status;
|
|
|
|
|
}
|
|
|
|
|
|
2006-10-11 22:14:05 +00:00
|
|
|
|
static BOOL
|
|
|
|
|
FindKeyInTable(
|
|
|
|
|
IN const RECORD* Table,
|
|
|
|
|
IN LPCWSTR Key,
|
|
|
|
|
OUT SIZE_T* pKeyLength,
|
|
|
|
|
OUT DWORD* pItem)
|
2005-08-16 05:17:06 +00:00
|
|
|
|
{
|
2006-10-11 22:14:05 +00:00
|
|
|
|
const RECORD* pRecord = Table;
|
|
|
|
|
while (pRecord->key != NULL)
|
|
|
|
|
{
|
|
|
|
|
if (wcsncmp(pRecord->key, Key, wcslen(pRecord->key)) == 0)
|
|
|
|
|
{
|
|
|
|
|
*pKeyLength = wcslen(pRecord->key);
|
|
|
|
|
*pItem = pRecord->value;
|
|
|
|
|
return TRUE;
|
|
|
|
|
}
|
|
|
|
|
pRecord++;
|
|
|
|
|
}
|
|
|
|
|
SetLastError(ERROR_INVALID_PARAMETER);
|
|
|
|
|
return FALSE;
|
2005-08-16 05:17:06 +00:00
|
|
|
|
}
|
|
|
|
|
|
2006-10-11 22:14:05 +00:00
|
|
|
|
static BOOL
|
|
|
|
|
ParseSidString(
|
|
|
|
|
IN LPCWSTR Buffer,
|
|
|
|
|
OUT PSID* pSid,
|
|
|
|
|
OUT SIZE_T* pLength)
|
2005-08-16 05:17:06 +00:00
|
|
|
|
{
|
2006-10-11 22:14:05 +00:00
|
|
|
|
WCHAR str[SDDL_ALIAS_SIZE + 1];
|
|
|
|
|
LPWSTR strSid;
|
|
|
|
|
LPCWSTR end;
|
|
|
|
|
BOOL ret;
|
|
|
|
|
DWORD i;
|
|
|
|
|
|
|
|
|
|
wcsncpy(str, Buffer, SDDL_ALIAS_SIZE);
|
|
|
|
|
for (i = SDDL_ALIAS_SIZE; i > 0; i--)
|
|
|
|
|
{
|
|
|
|
|
str[i] = UNICODE_NULL;
|
|
|
|
|
if (ConvertStringSidToSidW(str, pSid))
|
|
|
|
|
{
|
|
|
|
|
*pLength = i;
|
|
|
|
|
return TRUE;
|
|
|
|
|
}
|
|
|
|
|
}
|
2005-08-16 05:17:06 +00:00
|
|
|
|
|
2006-10-11 22:14:05 +00:00
|
|
|
|
end = wcschr(Buffer, SDDL_ACE_ENDC);
|
|
|
|
|
if (!end)
|
|
|
|
|
{
|
|
|
|
|
SetLastError(ERROR_NOT_ENOUGH_MEMORY);
|
|
|
|
|
return FALSE;
|
|
|
|
|
}
|
|
|
|
|
strSid = (LPWSTR)LocalAlloc(0, (end - Buffer) * sizeof(WCHAR) + sizeof(UNICODE_NULL));
|
|
|
|
|
if (!strSid)
|
|
|
|
|
{
|
|
|
|
|
SetLastError(ERROR_NOT_ENOUGH_MEMORY);
|
|
|
|
|
return FALSE;
|
|
|
|
|
}
|
|
|
|
|
wcsncpy(strSid, Buffer, end - Buffer + 1);
|
|
|
|
|
strSid[end - Buffer] = UNICODE_NULL;
|
|
|
|
|
*pLength = end - Buffer;
|
|
|
|
|
ret = ConvertStringSidToSidW(strSid, pSid);
|
|
|
|
|
LocalFree(strSid);
|
|
|
|
|
return ret;
|
2005-08-16 05:17:06 +00:00
|
|
|
|
}
|
|
|
|
|
|
2006-10-11 22:14:05 +00:00
|
|
|
|
static const RECORD DaclFlagTable[] =
|
2005-08-16 05:17:06 +00:00
|
|
|
|
{
|
2006-10-11 22:14:05 +00:00
|
|
|
|
{ SDDL_PROTECTED, SE_DACL_PROTECTED },
|
|
|
|
|
{ SDDL_AUTO_INHERIT_REQ, SE_DACL_AUTO_INHERIT_REQ },
|
|
|
|
|
{ SDDL_AUTO_INHERITED, SE_DACL_AUTO_INHERITED },
|
|
|
|
|
{ NULL, 0 },
|
2005-08-16 05:17:06 +00:00
|
|
|
|
};
|
|
|
|
|
|
2006-10-11 22:14:05 +00:00
|
|
|
|
static const RECORD SaclFlagTable[] =
|
2005-08-16 05:17:06 +00:00
|
|
|
|
{
|
2006-10-11 22:14:05 +00:00
|
|
|
|
{ SDDL_PROTECTED, SE_SACL_PROTECTED },
|
|
|
|
|
{ SDDL_AUTO_INHERIT_REQ, SE_SACL_AUTO_INHERIT_REQ },
|
|
|
|
|
{ SDDL_AUTO_INHERITED, SE_SACL_AUTO_INHERITED },
|
|
|
|
|
{ NULL, 0 },
|
|
|
|
|
};
|
2005-08-16 05:17:06 +00:00
|
|
|
|
|
2006-10-11 22:14:05 +00:00
|
|
|
|
static const RECORD AceFlagTable[] =
|
2005-08-16 05:17:06 +00:00
|
|
|
|
{
|
2006-10-11 22:14:05 +00:00
|
|
|
|
{ SDDL_CONTAINER_INHERIT, CONTAINER_INHERIT_ACE },
|
|
|
|
|
{ SDDL_OBJECT_INHERIT, OBJECT_INHERIT_ACE },
|
|
|
|
|
{ SDDL_NO_PROPAGATE, NO_PROPAGATE_INHERIT_ACE },
|
|
|
|
|
{ SDDL_INHERIT_ONLY, INHERIT_ONLY_ACE },
|
|
|
|
|
{ SDDL_INHERITED, INHERITED_ACE },
|
|
|
|
|
{ SDDL_AUDIT_SUCCESS, SUCCESSFUL_ACCESS_ACE_FLAG },
|
|
|
|
|
{ SDDL_AUDIT_FAILURE, FAILED_ACCESS_ACE_FLAG },
|
|
|
|
|
{ NULL, 0 },
|
2005-08-16 05:17:06 +00:00
|
|
|
|
};
|
|
|
|
|
|
2006-10-11 22:14:05 +00:00
|
|
|
|
static BOOL
|
|
|
|
|
ParseFlagsString(
|
|
|
|
|
IN LPCWSTR Buffer,
|
|
|
|
|
IN const RECORD* FlagTable,
|
|
|
|
|
IN WCHAR LimitChar,
|
|
|
|
|
OUT DWORD* pFlags,
|
|
|
|
|
OUT SIZE_T* pLength)
|
2005-08-16 05:17:06 +00:00
|
|
|
|
{
|
2006-10-11 22:14:05 +00:00
|
|
|
|
LPCWSTR ptr = Buffer;
|
|
|
|
|
SIZE_T PartialLength;
|
|
|
|
|
DWORD Flag;
|
2005-08-16 05:17:06 +00:00
|
|
|
|
|
2006-10-11 22:14:05 +00:00
|
|
|
|
*pFlags = 0;
|
|
|
|
|
while (*ptr != LimitChar)
|
2005-08-16 05:17:06 +00:00
|
|
|
|
{
|
2006-10-11 22:14:05 +00:00
|
|
|
|
if (!FindKeyInTable(FlagTable, ptr, &PartialLength, &Flag))
|
|
|
|
|
return FALSE;
|
|
|
|
|
*pFlags |= Flag;
|
|
|
|
|
ptr += PartialLength;
|
2005-08-16 05:17:06 +00:00
|
|
|
|
}
|
2006-10-11 22:14:05 +00:00
|
|
|
|
*pLength = ptr - Buffer;
|
|
|
|
|
return TRUE;
|
2005-08-16 05:17:06 +00:00
|
|
|
|
}
|
|
|
|
|
|
2006-10-11 22:14:05 +00:00
|
|
|
|
static const RECORD AccessMaskTable[] =
|
2005-08-16 05:17:06 +00:00
|
|
|
|
{
|
2006-10-11 22:14:05 +00:00
|
|
|
|
{ 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 },
|
|
|
|
|
};
|
2005-08-16 05:17:06 +00:00
|
|
|
|
|
2006-10-11 22:14:05 +00:00
|
|
|
|
static BOOL
|
|
|
|
|
ParseAccessMaskString(
|
|
|
|
|
IN LPCWSTR Buffer,
|
|
|
|
|
OUT DWORD* pAccessMask,
|
|
|
|
|
OUT SIZE_T* pLength)
|
|
|
|
|
{
|
|
|
|
|
/* FIXME: Allow hexadecimal string for access rights! */
|
2005-08-16 05:17:06 +00:00
|
|
|
|
|
2006-10-11 22:14:05 +00:00
|
|
|
|
return ParseFlagsString(Buffer, AccessMaskTable, SDDL_SEPERATORC, pAccessMask, pLength);
|
2005-08-16 05:17:06 +00:00
|
|
|
|
}
|
|
|
|
|
|
2006-10-11 22:14:05 +00:00
|
|
|
|
static BOOL
|
|
|
|
|
ParseGuidString(
|
|
|
|
|
IN LPCWSTR Buffer,
|
|
|
|
|
OUT GUID* pGuid,
|
|
|
|
|
OUT BOOL* pIsGuidValid,
|
|
|
|
|
OUT SIZE_T* pLength)
|
2005-08-16 05:17:06 +00:00
|
|
|
|
{
|
2006-10-11 22:14:05 +00:00
|
|
|
|
WCHAR GuidStr[MAX_GUID_STRING_LEN + 1];
|
|
|
|
|
LPCWSTR end;
|
2005-08-16 05:17:06 +00:00
|
|
|
|
|
2006-10-11 22:14:05 +00:00
|
|
|
|
end = wcschr(Buffer, SDDL_SEPERATORC);
|
|
|
|
|
if (!end)
|
2005-08-16 05:17:06 +00:00
|
|
|
|
{
|
2006-10-11 22:14:05 +00:00
|
|
|
|
SetLastError(ERROR_INVALID_PARAMETER);
|
|
|
|
|
return FALSE;
|
2005-08-16 05:17:06 +00:00
|
|
|
|
}
|
|
|
|
|
|
2006-10-11 22:14:05 +00:00
|
|
|
|
*pLength = end - Buffer;
|
|
|
|
|
*pIsGuidValid = (end != Buffer);
|
|
|
|
|
if (!*pIsGuidValid)
|
|
|
|
|
return TRUE;
|
2005-08-16 05:17:06 +00:00
|
|
|
|
|
2006-10-11 22:14:05 +00:00
|
|
|
|
if (end - Buffer > MAX_GUID_STRING_LEN - 1)
|
2005-08-16 05:17:06 +00:00
|
|
|
|
{
|
2006-10-11 22:14:05 +00:00
|
|
|
|
SetLastError(ERROR_INVALID_PARAMETER);
|
|
|
|
|
return FALSE;
|
2005-08-16 05:17:06 +00:00
|
|
|
|
}
|
2006-10-11 22:14:05 +00:00
|
|
|
|
GuidStr[end - Buffer] = UNICODE_NULL;
|
|
|
|
|
wcsncpy(GuidStr, Buffer, end - Buffer);
|
|
|
|
|
if (RPC_S_OK != UuidFromStringW((unsigned short*)&GuidStr, pGuid))
|
|
|
|
|
{
|
|
|
|
|
SetLastError(ERROR_INVALID_PARAMETER);
|
|
|
|
|
return FALSE;
|
|
|
|
|
}
|
|
|
|
|
return TRUE;
|
2005-08-16 05:17:06 +00:00
|
|
|
|
}
|
|
|
|
|
|
2006-10-11 22:14:05 +00:00
|
|
|
|
static const RECORD AceTypeTable[] =
|
2005-08-16 05:17:06 +00:00
|
|
|
|
{
|
2006-10-11 22:14:05 +00:00
|
|
|
|
{ SDDL_OBJECT_ACCESS_ALLOWED, ACCESS_ALLOWED_OBJECT_ACE_TYPE },
|
|
|
|
|
{ SDDL_OBJECT_ACCESS_DENIED, ACCESS_DENIED_OBJECT_ACE_TYPE },
|
|
|
|
|
{ SDDL_AUDIT, SYSTEM_AUDIT_ACE_TYPE },
|
|
|
|
|
{ SDDL_ALARM, SYSTEM_ALARM_ACE_TYPE },
|
|
|
|
|
{ SDDL_OBJECT_AUDIT, SYSTEM_AUDIT_OBJECT_ACE_TYPE },
|
|
|
|
|
{ SDDL_OBJECT_ALARM, SYSTEM_ALARM_OBJECT_ACE_TYPE },
|
|
|
|
|
{ SDDL_ACCESS_ALLOWED, ACCESS_ALLOWED_ACE_TYPE },
|
|
|
|
|
{ SDDL_ACCESS_DENIED, ACCESS_DENIED_ACE_TYPE },
|
|
|
|
|
{ NULL, 0 },
|
|
|
|
|
};
|
2005-08-16 05:17:06 +00:00
|
|
|
|
|
2006-10-11 22:14:05 +00:00
|
|
|
|
static BOOL
|
|
|
|
|
ParseAceString(
|
|
|
|
|
IN LPCWSTR Buffer,
|
|
|
|
|
IN PACL pAcl,
|
|
|
|
|
OUT SIZE_T* pLength)
|
|
|
|
|
{
|
|
|
|
|
LPCWSTR ptr = Buffer;
|
|
|
|
|
SIZE_T PartialLength;
|
|
|
|
|
DWORD aceType, aceFlags, accessMask;
|
|
|
|
|
GUID object, inheritObject;
|
|
|
|
|
BOOL objectValid, inheritObjectValid;
|
|
|
|
|
PSID sid = NULL;
|
|
|
|
|
BOOL ret;
|
|
|
|
|
|
|
|
|
|
if (*ptr != SDDL_ACE_BEGINC)
|
|
|
|
|
{
|
|
|
|
|
SetLastError(ERROR_INVALID_PARAMETER);
|
|
|
|
|
return FALSE;
|
|
|
|
|
}
|
|
|
|
|
ptr++; /* Skip SDDL_ACE_BEGINC */
|
2005-08-16 05:17:06 +00:00
|
|
|
|
|
2006-10-11 22:14:05 +00:00
|
|
|
|
if (!FindKeyInTable(AceTypeTable, ptr, &PartialLength, &aceType))
|
|
|
|
|
return FALSE;
|
|
|
|
|
ptr += PartialLength;
|
2005-08-16 05:17:06 +00:00
|
|
|
|
|
2006-10-11 22:14:05 +00:00
|
|
|
|
if (*ptr != SDDL_SEPERATORC)
|
|
|
|
|
{
|
|
|
|
|
SetLastError(ERROR_INVALID_PARAMETER);
|
|
|
|
|
return FALSE;
|
|
|
|
|
}
|
|
|
|
|
ptr++; /* Skip SDDL_SEPERATORC */
|
2005-08-16 05:17:06 +00:00
|
|
|
|
|
2006-10-11 22:14:05 +00:00
|
|
|
|
if (!ParseFlagsString(ptr, AceFlagTable, SDDL_SEPERATORC, &aceFlags, &PartialLength))
|
|
|
|
|
return FALSE;
|
|
|
|
|
ptr += PartialLength + 1;
|
2005-08-16 05:17:06 +00:00
|
|
|
|
|
2006-10-11 22:14:05 +00:00
|
|
|
|
if (!ParseAccessMaskString(ptr, &accessMask, &PartialLength))
|
|
|
|
|
return FALSE;
|
|
|
|
|
ptr += PartialLength + 1;
|
2005-08-16 05:17:06 +00:00
|
|
|
|
|
2006-10-11 22:14:05 +00:00
|
|
|
|
if (!ParseGuidString(ptr, &object, &objectValid, &PartialLength))
|
|
|
|
|
return FALSE;
|
|
|
|
|
ptr += PartialLength + 1;
|
2005-08-16 05:17:06 +00:00
|
|
|
|
|
2006-10-11 22:14:05 +00:00
|
|
|
|
if (!ParseGuidString(ptr, &inheritObject, &inheritObjectValid, &PartialLength))
|
|
|
|
|
return FALSE;
|
|
|
|
|
ptr += PartialLength + 1;
|
2005-08-16 05:17:06 +00:00
|
|
|
|
|
2006-10-11 22:14:05 +00:00
|
|
|
|
if (!ParseSidString(ptr, &sid, &PartialLength))
|
|
|
|
|
return FALSE;
|
|
|
|
|
ptr += PartialLength;
|
|
|
|
|
if (*ptr != SDDL_ACE_ENDC)
|
|
|
|
|
{
|
|
|
|
|
SetLastError(ERROR_INVALID_PARAMETER);
|
|
|
|
|
return FALSE;
|
|
|
|
|
}
|
|
|
|
|
ptr++; /* Skip SDDL_ACE_ENDC */
|
|
|
|
|
*pLength = ptr - Buffer;
|
2005-08-16 05:17:06 +00:00
|
|
|
|
|
2006-10-11 22:14:05 +00:00
|
|
|
|
switch (aceType)
|
|
|
|
|
{
|
|
|
|
|
case ACCESS_ALLOWED_ACE_TYPE:
|
|
|
|
|
ret = AddAccessAllowedAceEx(
|
|
|
|
|
pAcl,
|
|
|
|
|
ACL_REVISION_DS,
|
|
|
|
|
aceFlags,
|
|
|
|
|
accessMask,
|
|
|
|
|
sid);
|
|
|
|
|
break;
|
|
|
|
|
case ACCESS_ALLOWED_OBJECT_ACE_TYPE:
|
|
|
|
|
ret = AddAccessAllowedObjectAce(
|
|
|
|
|
pAcl,
|
|
|
|
|
ACL_REVISION_DS,
|
|
|
|
|
aceFlags,
|
|
|
|
|
accessMask,
|
|
|
|
|
objectValid ? &object : NULL,
|
|
|
|
|
inheritObjectValid ? &inheritObject : NULL,
|
|
|
|
|
sid);
|
|
|
|
|
break;
|
|
|
|
|
case ACCESS_DENIED_ACE_TYPE:
|
|
|
|
|
ret = AddAccessDeniedAceEx(
|
|
|
|
|
pAcl,
|
|
|
|
|
ACL_REVISION_DS,
|
|
|
|
|
aceFlags,
|
|
|
|
|
accessMask,
|
|
|
|
|
sid);
|
|
|
|
|
break;
|
|
|
|
|
case ACCESS_DENIED_OBJECT_ACE_TYPE:
|
|
|
|
|
ret = AddAccessDeniedObjectAce(
|
|
|
|
|
pAcl,
|
|
|
|
|
ACL_REVISION_DS,
|
|
|
|
|
aceFlags,
|
|
|
|
|
accessMask,
|
|
|
|
|
objectValid ? &object : NULL,
|
|
|
|
|
inheritObjectValid ? &inheritObject : NULL,
|
|
|
|
|
sid);
|
|
|
|
|
break;
|
|
|
|
|
case SYSTEM_AUDIT_ACE_TYPE:
|
|
|
|
|
ret = AddAuditAccessAceEx(
|
|
|
|
|
pAcl,
|
|
|
|
|
ACL_REVISION_DS,
|
|
|
|
|
aceFlags,
|
|
|
|
|
accessMask,
|
|
|
|
|
sid,
|
|
|
|
|
FALSE,
|
|
|
|
|
FALSE);
|
|
|
|
|
break;
|
|
|
|
|
case SYSTEM_AUDIT_OBJECT_ACE_TYPE:
|
|
|
|
|
ret = AddAuditAccessObjectAce(
|
|
|
|
|
pAcl,
|
|
|
|
|
ACL_REVISION_DS,
|
|
|
|
|
aceFlags,
|
|
|
|
|
accessMask,
|
|
|
|
|
objectValid ? &object : NULL,
|
|
|
|
|
inheritObjectValid ? &inheritObject : NULL,
|
|
|
|
|
sid,
|
|
|
|
|
FALSE,
|
|
|
|
|
FALSE);
|
|
|
|
|
break;
|
|
|
|
|
case SYSTEM_ALARM_ACE_TYPE:
|
|
|
|
|
case SYSTEM_ALARM_OBJECT_ACE_TYPE:
|
|
|
|
|
default:
|
|
|
|
|
{
|
|
|
|
|
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
|
|
|
|
|
ret = FALSE;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
LocalFree(sid);
|
|
|
|
|
return ret;
|
2005-08-16 05:17:06 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Exported functions */
|
2000-04-05 01:41:01 +00:00
|
|
|
|
|
2003-07-10 15:05:55 +00:00
|
|
|
|
/*
|
|
|
|
|
* @implemented
|
|
|
|
|
*/
|
2008-11-30 11:42:05 +00:00
|
|
|
|
BOOL WINAPI
|
2001-06-17 20:20:21 +00:00
|
|
|
|
AllocateLocallyUniqueId(PLUID Luid)
|
|
|
|
|
{
|
2008-09-21 13:55:53 +00:00
|
|
|
|
NTSTATUS Status;
|
2004-03-25 11:30:07 +00:00
|
|
|
|
|
2008-09-21 13:55:53 +00:00
|
|
|
|
Status = NtAllocateLocallyUniqueId (Luid);
|
|
|
|
|
if (!NT_SUCCESS (Status))
|
2004-03-25 11:30:07 +00:00
|
|
|
|
{
|
2008-09-21 13:55:53 +00:00
|
|
|
|
SetLastError(RtlNtStatusToDosError(Status));
|
|
|
|
|
return FALSE;
|
2004-03-25 11:30:07 +00:00
|
|
|
|
}
|
|
|
|
|
|
2008-09-21 13:55:53 +00:00
|
|
|
|
return TRUE;
|
2001-06-17 20:20:21 +00:00
|
|
|
|
}
|
|
|
|
|
|
2003-07-10 15:05:55 +00:00
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* @implemented
|
|
|
|
|
*/
|
2008-11-30 11:42:05 +00:00
|
|
|
|
BOOL WINAPI
|
2008-09-21 13:55:53 +00:00
|
|
|
|
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)
|
2000-04-05 01:41:01 +00:00
|
|
|
|
{
|
2008-09-21 13:55:53 +00:00
|
|
|
|
NTSTATUS Status;
|
|
|
|
|
|
|
|
|
|
Status = RtlAllocateAndInitializeSid(pIdentifierAuthority,
|
|
|
|
|
nSubAuthorityCount,
|
|
|
|
|
dwSubAuthority0,
|
|
|
|
|
dwSubAuthority1,
|
|
|
|
|
dwSubAuthority2,
|
|
|
|
|
dwSubAuthority3,
|
|
|
|
|
dwSubAuthority4,
|
|
|
|
|
dwSubAuthority5,
|
|
|
|
|
dwSubAuthority6,
|
|
|
|
|
dwSubAuthority7,
|
|
|
|
|
pSid);
|
|
|
|
|
if (!NT_SUCCESS(Status))
|
2004-03-25 11:30:07 +00:00
|
|
|
|
{
|
2008-09-21 13:55:53 +00:00
|
|
|
|
SetLastError(RtlNtStatusToDosError(Status));
|
|
|
|
|
return FALSE;
|
2004-03-25 11:30:07 +00:00
|
|
|
|
}
|
2000-04-05 01:41:01 +00:00
|
|
|
|
|
2008-09-21 13:55:53 +00:00
|
|
|
|
return TRUE;
|
2000-04-05 01:41:01 +00:00
|
|
|
|
}
|
|
|
|
|
|
2003-07-10 15:05:55 +00:00
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* @implemented
|
|
|
|
|
*/
|
2008-11-30 11:42:05 +00:00
|
|
|
|
BOOL WINAPI
|
2008-09-21 13:55:53 +00:00
|
|
|
|
CopySid(DWORD nDestinationSidLength,
|
|
|
|
|
PSID pDestinationSid,
|
|
|
|
|
PSID pSourceSid)
|
2000-04-05 01:41:01 +00:00
|
|
|
|
{
|
2008-09-21 13:55:53 +00:00
|
|
|
|
NTSTATUS Status;
|
2004-03-25 11:30:07 +00:00
|
|
|
|
|
2008-09-21 13:55:53 +00:00
|
|
|
|
Status = RtlCopySid(nDestinationSidLength,
|
|
|
|
|
pDestinationSid,
|
|
|
|
|
pSourceSid);
|
|
|
|
|
if (!NT_SUCCESS (Status))
|
2004-03-25 11:30:07 +00:00
|
|
|
|
{
|
2008-09-21 13:55:53 +00:00
|
|
|
|
SetLastError(RtlNtStatusToDosError(Status));
|
|
|
|
|
return FALSE;
|
2004-03-25 11:30:07 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return TRUE;
|
2000-04-05 01:41:01 +00:00
|
|
|
|
}
|
2008-09-21 13:55:53 +00:00
|
|
|
|
|
2008-11-10 14:25:24 +00:00
|
|
|
|
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 = (ACCESS_ALLOWED_ACE *)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;
|
|
|
|
|
}
|
2008-09-21 13:55:53 +00:00
|
|
|
|
|
2008-10-26 12:16:48 +00:00
|
|
|
|
/******************************************************************************
|
|
|
|
|
* ConvertSecurityDescriptorToStringSecurityDescriptorW [ADVAPI32.@]
|
2008-11-10 14:25:24 +00:00
|
|
|
|
* @implemented
|
2008-10-26 12:16:48 +00:00
|
|
|
|
*/
|
|
|
|
|
BOOL WINAPI
|
|
|
|
|
ConvertSecurityDescriptorToStringSecurityDescriptorW(PSECURITY_DESCRIPTOR SecurityDescriptor,
|
|
|
|
|
DWORD SDRevision,
|
|
|
|
|
SECURITY_INFORMATION SecurityInformation,
|
|
|
|
|
LPWSTR *OutputString,
|
|
|
|
|
PULONG OutputLen)
|
|
|
|
|
{
|
2008-11-10 14:25:24 +00:00
|
|
|
|
ULONG len;
|
|
|
|
|
WCHAR *wptr, *wstr;
|
|
|
|
|
|
2008-10-26 12:16:48 +00:00
|
|
|
|
if (SDRevision != SDDL_REVISION_1)
|
|
|
|
|
{
|
|
|
|
|
ERR("Pogram requested unknown SDDL revision %d\n", SDRevision);
|
|
|
|
|
SetLastError(ERROR_UNKNOWN_REVISION);
|
|
|
|
|
return FALSE;
|
|
|
|
|
}
|
|
|
|
|
|
2008-11-10 14:25:24 +00:00
|
|
|
|
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;
|
2008-10-26 12:16:48 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/******************************************************************************
|
|
|
|
|
* 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;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2005-08-16 05:17:06 +00:00
|
|
|
|
/******************************************************************************
|
|
|
|
|
* ConvertStringSecurityDescriptorToSecurityDescriptorW [ADVAPI32.@]
|
|
|
|
|
* @implemented
|
|
|
|
|
*/
|
2006-10-11 22:14:05 +00:00
|
|
|
|
BOOL WINAPI
|
|
|
|
|
ConvertStringSecurityDescriptorToSecurityDescriptorW(
|
|
|
|
|
IN LPCWSTR StringSecurityDescriptor,
|
|
|
|
|
IN DWORD StringSDRevision,
|
|
|
|
|
OUT PSECURITY_DESCRIPTOR* SecurityDescriptor,
|
|
|
|
|
OUT PULONG SecurityDescriptorSize)
|
2005-08-16 05:17:06 +00:00
|
|
|
|
{
|
2006-10-11 22:14:05 +00:00
|
|
|
|
PSECURITY_DESCRIPTOR sd = NULL;
|
|
|
|
|
BOOL ret = FALSE;
|
2005-08-16 05:17:06 +00:00
|
|
|
|
|
2006-10-11 22:14:05 +00:00
|
|
|
|
if (!StringSecurityDescriptor)
|
|
|
|
|
SetLastError(ERROR_INVALID_PARAMETER);
|
|
|
|
|
else if (StringSDRevision != SDDL_REVISION_1)
|
|
|
|
|
SetLastError(ERROR_INVALID_PARAMETER);
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
LPCWSTR ptr = StringSecurityDescriptor;
|
|
|
|
|
DWORD numberOfAces = 0;
|
|
|
|
|
DWORD relativeSdSize;
|
|
|
|
|
SIZE_T MaxAclSize;
|
|
|
|
|
PSECURITY_DESCRIPTOR relativeSd = NULL;
|
|
|
|
|
PSID pSid;
|
|
|
|
|
PACL pAcl;
|
|
|
|
|
BOOL present, dummy;
|
|
|
|
|
/* An easy way to know how much space we need for an ACL is to count
|
|
|
|
|
* the number of ACEs and say that we have 1 SID by ACE
|
|
|
|
|
*/
|
|
|
|
|
ptr = wcschr(StringSecurityDescriptor, SDDL_ACE_BEGINC);
|
|
|
|
|
while (ptr != NULL)
|
|
|
|
|
{
|
|
|
|
|
numberOfAces++;
|
|
|
|
|
ptr = wcschr(ptr + 1, SDDL_ACE_BEGINC);
|
|
|
|
|
}
|
|
|
|
|
MaxAclSize = sizeof(ACL) + numberOfAces *
|
|
|
|
|
(sizeof(ACCESS_ALLOWED_OBJECT_ACE) + SECURITY_MAX_SID_SIZE);
|
|
|
|
|
|
|
|
|
|
sd = (SECURITY_DESCRIPTOR*)LocalAlloc(0, sizeof(SECURITY_DESCRIPTOR));
|
|
|
|
|
if (!sd)
|
|
|
|
|
{
|
|
|
|
|
SetLastError(ERROR_NOT_ENOUGH_MEMORY);
|
|
|
|
|
return FALSE;
|
|
|
|
|
}
|
|
|
|
|
ret = InitializeSecurityDescriptor(sd, SECURITY_DESCRIPTOR_REVISION);
|
|
|
|
|
if (!ret)
|
|
|
|
|
goto cleanup;
|
|
|
|
|
|
|
|
|
|
/* Now, really parse the string */
|
|
|
|
|
ptr = StringSecurityDescriptor;
|
|
|
|
|
while (*ptr)
|
|
|
|
|
{
|
|
|
|
|
if (ptr[1] != SDDL_DELIMINATORC)
|
|
|
|
|
{
|
|
|
|
|
SetLastError(ERROR_INVALID_PARAMETER);
|
|
|
|
|
ret = FALSE;
|
|
|
|
|
goto cleanup;
|
|
|
|
|
}
|
|
|
|
|
ptr += 2;
|
|
|
|
|
switch (ptr[-2])
|
|
|
|
|
{
|
|
|
|
|
case 'O':
|
|
|
|
|
case 'G':
|
|
|
|
|
{
|
|
|
|
|
PSID pSid;
|
|
|
|
|
SIZE_T Length;
|
|
|
|
|
|
|
|
|
|
ret = ParseSidString(ptr, &pSid, &Length);
|
|
|
|
|
if (!ret)
|
|
|
|
|
goto cleanup;
|
|
|
|
|
if (ptr[-2] == 'O')
|
|
|
|
|
ret = SetSecurityDescriptorOwner(sd, pSid, FALSE);
|
|
|
|
|
else
|
|
|
|
|
ret = SetSecurityDescriptorGroup(sd, pSid, FALSE);
|
|
|
|
|
if (!ret)
|
|
|
|
|
{
|
|
|
|
|
LocalFree(pSid);
|
|
|
|
|
goto cleanup;
|
|
|
|
|
}
|
|
|
|
|
ptr += Length;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
case 'D':
|
|
|
|
|
case 'S':
|
|
|
|
|
{
|
|
|
|
|
DWORD aclFlags;
|
|
|
|
|
SIZE_T Length;
|
|
|
|
|
BOOL isDacl = (ptr[-2] == 'D');
|
2007-10-19 23:21:45 +00:00
|
|
|
|
|
2006-10-11 22:14:05 +00:00
|
|
|
|
if (isDacl)
|
|
|
|
|
ret = ParseFlagsString(ptr, DaclFlagTable, SDDL_ACE_BEGINC, &aclFlags, &Length);
|
|
|
|
|
else
|
|
|
|
|
ret = ParseFlagsString(ptr, SaclFlagTable, SDDL_ACE_BEGINC, &aclFlags, &Length);
|
|
|
|
|
if (!ret)
|
|
|
|
|
goto cleanup;
|
|
|
|
|
pAcl = (PACL)LocalAlloc(0, MaxAclSize);
|
|
|
|
|
if (!pAcl)
|
|
|
|
|
{
|
|
|
|
|
SetLastError(ERROR_NOT_ENOUGH_MEMORY);
|
|
|
|
|
ret = FALSE;
|
|
|
|
|
goto cleanup;
|
|
|
|
|
}
|
|
|
|
|
if (!InitializeAcl(pAcl, (DWORD)MaxAclSize, ACL_REVISION_DS))
|
|
|
|
|
{
|
|
|
|
|
LocalFree(pAcl);
|
|
|
|
|
goto cleanup;
|
|
|
|
|
}
|
|
|
|
|
if (aclFlags != 0)
|
|
|
|
|
{
|
|
|
|
|
ret = SetSecurityDescriptorControl(
|
|
|
|
|
sd,
|
|
|
|
|
(SECURITY_DESCRIPTOR_CONTROL)aclFlags,
|
|
|
|
|
(SECURITY_DESCRIPTOR_CONTROL)aclFlags);
|
|
|
|
|
if (!ret)
|
|
|
|
|
{
|
|
|
|
|
LocalFree(pAcl);
|
|
|
|
|
goto cleanup;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
ptr += Length;
|
|
|
|
|
while (*ptr == SDDL_ACE_BEGINC)
|
|
|
|
|
{
|
|
|
|
|
ret = ParseAceString(ptr, pAcl, &Length);
|
|
|
|
|
if (!ret)
|
|
|
|
|
{
|
|
|
|
|
LocalFree(pAcl);
|
|
|
|
|
goto cleanup;
|
|
|
|
|
}
|
|
|
|
|
ptr += Length;
|
|
|
|
|
}
|
|
|
|
|
if (isDacl)
|
|
|
|
|
ret = SetSecurityDescriptorDacl(sd, TRUE, pAcl, FALSE);
|
|
|
|
|
else
|
|
|
|
|
ret = SetSecurityDescriptorSacl(sd, TRUE, pAcl, FALSE);
|
|
|
|
|
if (!ret)
|
|
|
|
|
{
|
|
|
|
|
LocalFree(pAcl);
|
|
|
|
|
goto cleanup;
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
default:
|
|
|
|
|
{
|
|
|
|
|
SetLastError(ERROR_INVALID_PARAMETER);
|
|
|
|
|
ret = FALSE;
|
|
|
|
|
goto cleanup;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
2005-08-16 05:17:06 +00:00
|
|
|
|
|
2006-10-11 22:14:05 +00:00
|
|
|
|
relativeSdSize = 0;
|
|
|
|
|
while (TRUE)
|
|
|
|
|
{
|
|
|
|
|
if (relativeSd)
|
|
|
|
|
LocalFree(relativeSd);
|
|
|
|
|
relativeSd = LocalAlloc(0, relativeSdSize);
|
|
|
|
|
if (!relativeSd)
|
|
|
|
|
{
|
|
|
|
|
SetLastError(ERROR_NOT_ENOUGH_MEMORY);
|
|
|
|
|
goto cleanup;
|
|
|
|
|
}
|
|
|
|
|
ret = MakeSelfRelativeSD(sd, relativeSd, &relativeSdSize);
|
|
|
|
|
if (ret || GetLastError() != ERROR_INSUFFICIENT_BUFFER)
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
if (SecurityDescriptorSize)
|
|
|
|
|
*SecurityDescriptorSize = relativeSdSize;
|
|
|
|
|
*SecurityDescriptor = relativeSd;
|
|
|
|
|
|
|
|
|
|
cleanup:
|
|
|
|
|
if (GetSecurityDescriptorOwner(sd, &pSid, &dummy))
|
|
|
|
|
LocalFree(pSid);
|
|
|
|
|
if (GetSecurityDescriptorGroup(sd, &pSid, &dummy))
|
|
|
|
|
LocalFree(pSid);
|
|
|
|
|
if (GetSecurityDescriptorDacl(sd, &present, &pAcl, &dummy) && present)
|
|
|
|
|
LocalFree(pAcl);
|
|
|
|
|
if (GetSecurityDescriptorSacl(sd, &present, &pAcl, &dummy) && present)
|
|
|
|
|
LocalFree(pAcl);
|
|
|
|
|
LocalFree(sd);
|
|
|
|
|
return ret;
|
|
|
|
|
}
|
|
|
|
|
return FALSE;
|
2005-08-16 05:17:06 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Winehq cvs 20050916 */
|
|
|
|
|
/******************************************************************************
|
|
|
|
|
* ConvertStringSecurityDescriptorToSecurityDescriptorA [ADVAPI32.@]
|
|
|
|
|
* @implemented
|
|
|
|
|
*/
|
|
|
|
|
BOOL WINAPI ConvertStringSecurityDescriptorToSecurityDescriptorA(
|
|
|
|
|
LPCSTR StringSecurityDescriptor,
|
|
|
|
|
DWORD StringSDRevision,
|
|
|
|
|
PSECURITY_DESCRIPTOR* SecurityDescriptor,
|
|
|
|
|
PULONG SecurityDescriptorSize)
|
|
|
|
|
{
|
|
|
|
|
UINT len;
|
|
|
|
|
BOOL ret = FALSE;
|
|
|
|
|
LPWSTR StringSecurityDescriptorW;
|
2000-04-05 01:41:01 +00:00
|
|
|
|
|
2005-08-16 05:17:06 +00:00
|
|
|
|
len = MultiByteToWideChar(CP_ACP, 0, StringSecurityDescriptor, -1, NULL, 0);
|
|
|
|
|
StringSecurityDescriptorW = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR));
|
|
|
|
|
|
|
|
|
|
if (StringSecurityDescriptorW)
|
|
|
|
|
{
|
|
|
|
|
MultiByteToWideChar(CP_ACP, 0, StringSecurityDescriptor, -1, StringSecurityDescriptorW, len);
|
|
|
|
|
|
|
|
|
|
ret = ConvertStringSecurityDescriptorToSecurityDescriptorW(StringSecurityDescriptorW,
|
|
|
|
|
StringSDRevision, SecurityDescriptor,
|
|
|
|
|
SecurityDescriptorSize);
|
|
|
|
|
HeapFree(GetProcessHeap(), 0, StringSecurityDescriptorW);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return ret;
|
|
|
|
|
}
|
2003-07-10 15:05:55 +00:00
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* @implemented
|
|
|
|
|
*/
|
2008-11-30 11:42:05 +00:00
|
|
|
|
BOOL WINAPI
|
2008-09-21 13:55:53 +00:00
|
|
|
|
EqualPrefixSid(PSID pSid1,
|
|
|
|
|
PSID pSid2)
|
2000-04-05 01:41:01 +00:00
|
|
|
|
{
|
2008-09-21 13:55:53 +00:00
|
|
|
|
return RtlEqualPrefixSid (pSid1, pSid2);
|
2000-04-05 01:41:01 +00:00
|
|
|
|
}
|
|
|
|
|
|
2003-07-10 15:05:55 +00:00
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* @implemented
|
|
|
|
|
*/
|
2008-11-30 11:42:05 +00:00
|
|
|
|
BOOL WINAPI
|
2008-09-21 13:55:53 +00:00
|
|
|
|
EqualSid(PSID pSid1,
|
|
|
|
|
PSID pSid2)
|
2000-04-05 01:41:01 +00:00
|
|
|
|
{
|
2008-09-21 13:55:53 +00:00
|
|
|
|
return RtlEqualSid (pSid1, pSid2);
|
2000-04-05 01:41:01 +00:00
|
|
|
|
}
|
|
|
|
|
|
2003-07-10 15:05:55 +00:00
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* @implemented
|
2004-06-20 23:39:07 +00:00
|
|
|
|
*
|
|
|
|
|
* RETURNS
|
|
|
|
|
* Docs says this function does NOT return a value
|
|
|
|
|
* even thou it's defined to return a PVOID...
|
2003-07-10 15:05:55 +00:00
|
|
|
|
*/
|
2008-11-30 11:42:05 +00:00
|
|
|
|
PVOID WINAPI
|
2008-09-21 13:55:53 +00:00
|
|
|
|
FreeSid(PSID pSid)
|
2000-04-05 01:41:01 +00:00
|
|
|
|
{
|
2008-09-21 13:55:53 +00:00
|
|
|
|
return RtlFreeSid(pSid);
|
2000-04-05 01:41:01 +00:00
|
|
|
|
}
|
|
|
|
|
|
2003-07-10 15:05:55 +00:00
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* @implemented
|
|
|
|
|
*/
|
2008-11-30 11:42:05 +00:00
|
|
|
|
DWORD WINAPI
|
2008-09-21 13:55:53 +00:00
|
|
|
|
GetLengthSid(PSID pSid)
|
2000-04-05 01:41:01 +00:00
|
|
|
|
{
|
2008-09-21 13:55:53 +00:00
|
|
|
|
return (DWORD)RtlLengthSid(pSid);
|
2000-04-05 01:41:01 +00:00
|
|
|
|
}
|
|
|
|
|
|
2003-07-10 15:05:55 +00:00
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* @implemented
|
|
|
|
|
*/
|
2008-11-30 11:42:05 +00:00
|
|
|
|
PSID_IDENTIFIER_AUTHORITY WINAPI
|
2008-09-21 13:55:53 +00:00
|
|
|
|
GetSidIdentifierAuthority(PSID pSid)
|
2000-04-05 01:41:01 +00:00
|
|
|
|
{
|
2008-09-21 13:55:53 +00:00
|
|
|
|
return RtlIdentifierAuthoritySid(pSid);
|
2000-04-05 01:41:01 +00:00
|
|
|
|
}
|
|
|
|
|
|
2003-07-10 15:05:55 +00:00
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* @implemented
|
|
|
|
|
*/
|
2008-11-30 11:42:05 +00:00
|
|
|
|
DWORD WINAPI
|
2008-09-21 13:55:53 +00:00
|
|
|
|
GetSidLengthRequired(UCHAR nSubAuthorityCount)
|
2000-04-05 01:41:01 +00:00
|
|
|
|
{
|
2008-09-21 13:55:53 +00:00
|
|
|
|
return (DWORD)RtlLengthRequiredSid(nSubAuthorityCount);
|
2000-04-05 01:41:01 +00:00
|
|
|
|
}
|
|
|
|
|
|
2003-07-10 15:05:55 +00:00
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* @implemented
|
|
|
|
|
*/
|
2008-11-30 11:42:05 +00:00
|
|
|
|
PDWORD WINAPI
|
2008-09-21 13:55:53 +00:00
|
|
|
|
GetSidSubAuthority(PSID pSid,
|
|
|
|
|
DWORD nSubAuthority)
|
2000-04-05 01:41:01 +00:00
|
|
|
|
{
|
2008-09-21 13:55:53 +00:00
|
|
|
|
return (PDWORD)RtlSubAuthoritySid(pSid, nSubAuthority);
|
2000-04-05 01:41:01 +00:00
|
|
|
|
}
|
|
|
|
|
|
2003-07-10 15:05:55 +00:00
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* @implemented
|
|
|
|
|
*/
|
2008-11-30 11:42:05 +00:00
|
|
|
|
PUCHAR WINAPI
|
2008-09-21 13:55:53 +00:00
|
|
|
|
GetSidSubAuthorityCount(PSID pSid)
|
2000-04-05 01:41:01 +00:00
|
|
|
|
{
|
2008-09-21 13:55:53 +00:00
|
|
|
|
return RtlSubAuthorityCountSid(pSid);
|
2000-04-05 01:41:01 +00:00
|
|
|
|
}
|
|
|
|
|
|
2001-11-22 02:37:32 +00:00
|
|
|
|
|
2003-07-10 15:05:55 +00:00
|
|
|
|
/*
|
|
|
|
|
* @implemented
|
|
|
|
|
*/
|
2008-11-30 11:42:05 +00:00
|
|
|
|
BOOL WINAPI
|
2008-09-21 13:55:53 +00:00
|
|
|
|
InitializeSid(PSID Sid,
|
|
|
|
|
PSID_IDENTIFIER_AUTHORITY pIdentifierAuthority,
|
|
|
|
|
BYTE nSubAuthorityCount)
|
2000-04-05 01:41:01 +00:00
|
|
|
|
{
|
2008-09-21 13:55:53 +00:00
|
|
|
|
NTSTATUS Status;
|
2004-03-25 11:30:07 +00:00
|
|
|
|
|
2008-09-21 13:55:53 +00:00
|
|
|
|
Status = RtlInitializeSid(Sid,
|
|
|
|
|
pIdentifierAuthority,
|
|
|
|
|
nSubAuthorityCount);
|
|
|
|
|
if (!NT_SUCCESS(Status))
|
2004-03-25 11:30:07 +00:00
|
|
|
|
{
|
2008-09-21 13:55:53 +00:00
|
|
|
|
SetLastError(RtlNtStatusToDosError(Status));
|
|
|
|
|
return FALSE;
|
2004-03-25 11:30:07 +00:00
|
|
|
|
}
|
|
|
|
|
|
2008-09-21 13:55:53 +00:00
|
|
|
|
return TRUE;
|
2000-04-05 01:41:01 +00:00
|
|
|
|
}
|
|
|
|
|
|
2004-03-10 21:34:42 +00:00
|
|
|
|
|
2004-03-25 11:30:07 +00:00
|
|
|
|
/*
|
|
|
|
|
* @implemented
|
2004-03-10 21:34:42 +00:00
|
|
|
|
*/
|
2008-11-30 11:42:05 +00:00
|
|
|
|
BOOL WINAPI
|
2008-09-21 13:55:53 +00:00
|
|
|
|
IsValidSid(PSID pSid)
|
2004-03-10 21:34:42 +00:00
|
|
|
|
{
|
2008-09-21 13:55:53 +00:00
|
|
|
|
return (BOOL)RtlValidSid(pSid);
|
2004-03-10 21:34:42 +00:00
|
|
|
|
}
|
|
|
|
|
|
2008-09-21 13:55:53 +00:00
|
|
|
|
|
2004-08-23 21:16:26 +00:00
|
|
|
|
/*
|
|
|
|
|
* @implemented
|
|
|
|
|
*/
|
2008-11-30 11:42:05 +00:00
|
|
|
|
BOOL WINAPI
|
2008-09-21 13:55:53 +00:00
|
|
|
|
ConvertSidToStringSidW(PSID Sid,
|
|
|
|
|
LPWSTR *StringSid)
|
2004-08-23 21:16:26 +00:00
|
|
|
|
{
|
2008-09-21 13:55:53 +00:00
|
|
|
|
NTSTATUS Status;
|
|
|
|
|
UNICODE_STRING UnicodeString;
|
|
|
|
|
WCHAR FixedBuffer[64];
|
2004-08-23 21:16:26 +00:00
|
|
|
|
|
2008-09-21 13:55:53 +00:00
|
|
|
|
if (!RtlValidSid(Sid))
|
2004-08-23 21:16:26 +00:00
|
|
|
|
{
|
2008-09-21 13:55:53 +00:00
|
|
|
|
SetLastError(ERROR_INVALID_SID);
|
|
|
|
|
return FALSE;
|
2004-08-23 21:16:26 +00:00
|
|
|
|
}
|
|
|
|
|
|
2008-09-21 13:55:53 +00:00
|
|
|
|
UnicodeString.Length = 0;
|
|
|
|
|
UnicodeString.MaximumLength = sizeof(FixedBuffer);
|
|
|
|
|
UnicodeString.Buffer = FixedBuffer;
|
|
|
|
|
Status = RtlConvertSidToUnicodeString(&UnicodeString, Sid, FALSE);
|
|
|
|
|
if (STATUS_BUFFER_TOO_SMALL == Status)
|
2004-08-23 21:16:26 +00:00
|
|
|
|
{
|
2008-09-21 13:55:53 +00:00
|
|
|
|
Status = RtlConvertSidToUnicodeString(&UnicodeString, Sid, TRUE);
|
2004-08-23 21:16:26 +00:00
|
|
|
|
}
|
2008-09-21 13:55:53 +00:00
|
|
|
|
|
|
|
|
|
if (!NT_SUCCESS(Status))
|
2004-08-23 21:16:26 +00:00
|
|
|
|
{
|
2008-09-21 13:55:53 +00:00
|
|
|
|
SetLastError(RtlNtStatusToDosError(Status));
|
|
|
|
|
return FALSE;
|
2004-08-23 21:16:26 +00:00
|
|
|
|
}
|
|
|
|
|
|
2008-09-21 13:55:53 +00:00
|
|
|
|
*StringSid = LocalAlloc(LMEM_FIXED, UnicodeString.Length + sizeof(WCHAR));
|
|
|
|
|
if (NULL == *StringSid)
|
2004-08-23 21:16:26 +00:00
|
|
|
|
{
|
2008-09-21 13:55:53 +00:00
|
|
|
|
if (UnicodeString.Buffer != FixedBuffer)
|
2004-08-23 21:16:26 +00:00
|
|
|
|
{
|
2008-09-21 13:55:53 +00:00
|
|
|
|
RtlFreeUnicodeString(&UnicodeString);
|
2004-08-23 21:16:26 +00:00
|
|
|
|
}
|
|
|
|
|
SetLastError(ERROR_NOT_ENOUGH_MEMORY);
|
|
|
|
|
return FALSE;
|
|
|
|
|
}
|
|
|
|
|
|
2008-09-21 13:55:53 +00:00
|
|
|
|
MoveMemory(*StringSid, UnicodeString.Buffer, UnicodeString.Length);
|
|
|
|
|
ZeroMemory((PCHAR) *StringSid + UnicodeString.Length, sizeof(WCHAR));
|
|
|
|
|
if (UnicodeString.Buffer != FixedBuffer)
|
2004-08-23 21:16:26 +00:00
|
|
|
|
{
|
2008-09-21 13:55:53 +00:00
|
|
|
|
RtlFreeUnicodeString(&UnicodeString);
|
2004-08-23 21:16:26 +00:00
|
|
|
|
}
|
|
|
|
|
|
2008-09-21 13:55:53 +00:00
|
|
|
|
return TRUE;
|
2004-08-23 21:16:26 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* @implemented
|
|
|
|
|
*/
|
2008-11-30 11:42:05 +00:00
|
|
|
|
BOOL WINAPI
|
2008-09-21 13:55:53 +00:00
|
|
|
|
ConvertSidToStringSidA(PSID Sid,
|
|
|
|
|
LPSTR *StringSid)
|
2004-08-23 21:16:26 +00:00
|
|
|
|
{
|
2008-09-21 13:55:53 +00:00
|
|
|
|
LPWSTR StringSidW;
|
|
|
|
|
int Len;
|
2004-08-23 21:16:26 +00:00
|
|
|
|
|
2008-09-21 13:55:53 +00:00
|
|
|
|
if (!ConvertSidToStringSidW(Sid, &StringSidW))
|
2004-08-23 21:16:26 +00:00
|
|
|
|
{
|
2008-09-21 13:55:53 +00:00
|
|
|
|
return FALSE;
|
2004-08-23 21:16:26 +00:00
|
|
|
|
}
|
|
|
|
|
|
2008-09-21 13:55:53 +00:00
|
|
|
|
Len = WideCharToMultiByte(CP_ACP, 0, StringSidW, -1, NULL, 0, NULL, NULL);
|
|
|
|
|
if (Len <= 0)
|
2004-08-23 21:16:26 +00:00
|
|
|
|
{
|
2008-09-21 13:55:53 +00:00
|
|
|
|
LocalFree(StringSidW);
|
|
|
|
|
SetLastError(ERROR_NOT_ENOUGH_MEMORY);
|
|
|
|
|
return FALSE;
|
2004-08-23 21:16:26 +00:00
|
|
|
|
}
|
2008-09-21 13:55:53 +00:00
|
|
|
|
|
|
|
|
|
*StringSid = LocalAlloc(LMEM_FIXED, Len);
|
|
|
|
|
if (NULL == *StringSid)
|
2004-08-23 21:16:26 +00:00
|
|
|
|
{
|
2008-09-21 13:55:53 +00:00
|
|
|
|
LocalFree(StringSidW);
|
|
|
|
|
SetLastError(ERROR_NOT_ENOUGH_MEMORY);
|
|
|
|
|
return FALSE;
|
2004-08-23 21:16:26 +00:00
|
|
|
|
}
|
|
|
|
|
|
2008-09-21 13:55:53 +00:00
|
|
|
|
if (!WideCharToMultiByte(CP_ACP, 0, StringSidW, -1, *StringSid, Len, NULL, NULL))
|
2004-08-23 21:16:26 +00:00
|
|
|
|
{
|
2008-09-21 13:55:53 +00:00
|
|
|
|
LocalFree(StringSid);
|
|
|
|
|
LocalFree(StringSidW);
|
|
|
|
|
return FALSE;
|
2004-08-23 21:16:26 +00:00
|
|
|
|
}
|
|
|
|
|
|
2008-09-21 13:55:53 +00:00
|
|
|
|
LocalFree(StringSidW);
|
2004-08-23 21:16:26 +00:00
|
|
|
|
|
2008-09-21 13:55:53 +00:00
|
|
|
|
return TRUE;
|
2004-08-23 21:16:26 +00:00
|
|
|
|
}
|
|
|
|
|
|
2005-07-27 01:31:34 +00:00
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* @unimplemented
|
|
|
|
|
*/
|
2008-11-30 11:42:05 +00:00
|
|
|
|
BOOL WINAPI
|
2005-07-27 01:31:34 +00:00
|
|
|
|
EqualDomainSid(IN PSID pSid1,
|
|
|
|
|
IN PSID pSid2,
|
|
|
|
|
OUT BOOL* pfEqual)
|
|
|
|
|
{
|
2008-06-01 19:56:21 +00:00
|
|
|
|
UNIMPLEMENTED;
|
2005-07-27 01:31:34 +00:00
|
|
|
|
return FALSE;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* @unimplemented
|
|
|
|
|
*/
|
2008-11-30 11:42:05 +00:00
|
|
|
|
BOOL WINAPI
|
2005-07-27 01:31:34 +00:00
|
|
|
|
GetWindowsAccountDomainSid(IN PSID pSid,
|
|
|
|
|
OUT PSID ppDomainSid,
|
|
|
|
|
IN OUT DWORD* cbSid)
|
|
|
|
|
{
|
2008-06-01 19:56:21 +00:00
|
|
|
|
UNIMPLEMENTED;
|
2005-07-27 01:31:34 +00:00
|
|
|
|
return FALSE;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* @unimplemented
|
|
|
|
|
*/
|
2008-11-30 11:42:05 +00:00
|
|
|
|
BOOL WINAPI
|
2005-07-27 01:31:34 +00:00
|
|
|
|
CreateWellKnownSid(IN WELL_KNOWN_SID_TYPE WellKnownSidType,
|
|
|
|
|
IN PSID DomainSid OPTIONAL,
|
|
|
|
|
OUT PSID pSid,
|
|
|
|
|
IN OUT DWORD* cbSid)
|
|
|
|
|
{
|
2008-12-07 21:52:22 +00:00
|
|
|
|
unsigned int i;
|
2006-08-06 18:22:36 +00:00
|
|
|
|
TRACE("(%d, %s, %p, %p)\n", WellKnownSidType, debugstr_sid(DomainSid), pSid, cbSid);
|
|
|
|
|
|
2008-09-21 13:55:53 +00:00
|
|
|
|
if (DomainSid != NULL)
|
|
|
|
|
{
|
2006-08-06 18:22:36 +00:00
|
|
|
|
FIXME("Only local computer supported!\n");
|
|
|
|
|
SetLastError(ERROR_INVALID_PARAMETER); /* FIXME */
|
|
|
|
|
return FALSE;
|
|
|
|
|
}
|
|
|
|
|
|
2008-09-21 13:55:53 +00:00
|
|
|
|
if (cbSid == NULL || pSid == NULL)
|
|
|
|
|
{
|
2006-08-06 18:22:36 +00:00
|
|
|
|
SetLastError(ERROR_INVALID_PARAMETER);
|
|
|
|
|
return FALSE;
|
|
|
|
|
}
|
|
|
|
|
|
2008-09-21 13:55:53 +00:00
|
|
|
|
for (i = 0; i < sizeof(WellKnownSids)/sizeof(WellKnownSids[0]); i++)
|
|
|
|
|
{
|
|
|
|
|
if (WellKnownSids[i].Type == WellKnownSidType)
|
|
|
|
|
{
|
2006-08-06 18:22:36 +00:00
|
|
|
|
DWORD length = GetSidLengthRequired(WellKnownSids[i].Sid.SubAuthorityCount);
|
|
|
|
|
|
2008-09-21 13:55:53 +00:00
|
|
|
|
if (*cbSid < length)
|
|
|
|
|
{
|
2006-08-06 18:22:36 +00:00
|
|
|
|
SetLastError(ERROR_INSUFFICIENT_BUFFER);
|
|
|
|
|
return FALSE;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
CopyMemory(pSid, &WellKnownSids[i].Sid.Revision, length);
|
|
|
|
|
*cbSid = length;
|
|
|
|
|
return TRUE;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
SetLastError(ERROR_INVALID_PARAMETER);
|
2005-07-27 01:31:34 +00:00
|
|
|
|
return FALSE;
|
|
|
|
|
}
|
|
|
|
|
|
2005-09-29 02:02:40 +00:00
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* @unimplemented
|
|
|
|
|
*/
|
2008-11-30 11:42:05 +00:00
|
|
|
|
BOOL WINAPI
|
2005-09-29 02:02:40 +00:00
|
|
|
|
IsWellKnownSid(IN PSID pSid,
|
|
|
|
|
IN WELL_KNOWN_SID_TYPE WellKnownSidType)
|
|
|
|
|
{
|
2008-12-07 21:52:22 +00:00
|
|
|
|
unsigned int i;
|
2006-08-06 18:22:36 +00:00
|
|
|
|
TRACE("(%s, %d)\n", debugstr_sid(pSid), WellKnownSidType);
|
|
|
|
|
|
2008-09-21 13:55:53 +00:00
|
|
|
|
for (i = 0; i < sizeof(WellKnownSids) / sizeof(WellKnownSids[0]); i++)
|
|
|
|
|
{
|
2006-08-06 18:22:36 +00:00
|
|
|
|
if (WellKnownSids[i].Type == WellKnownSidType)
|
2008-09-21 13:55:53 +00:00
|
|
|
|
{
|
2007-01-21 22:42:44 +00:00
|
|
|
|
if (EqualSid(pSid, (PSID)((ULONG_PTR)&WellKnownSids[i].Sid.Revision)))
|
2006-08-06 18:22:36 +00:00
|
|
|
|
return TRUE;
|
2008-09-21 13:55:53 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
2006-08-06 18:22:36 +00:00
|
|
|
|
|
2005-09-29 02:02:40 +00:00
|
|
|
|
return FALSE;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
2005-11-14 22:44:36 +00:00
|
|
|
|
/*
|
|
|
|
|
* @implemented
|
|
|
|
|
*/
|
2008-11-30 11:42:05 +00:00
|
|
|
|
BOOL WINAPI
|
2008-09-21 13:55:53 +00:00
|
|
|
|
ConvertStringSidToSidA(IN LPCSTR StringSid,
|
|
|
|
|
OUT PSID* sid)
|
2005-11-14 22:44:36 +00:00
|
|
|
|
{
|
|
|
|
|
BOOL bRetVal = FALSE;
|
|
|
|
|
|
|
|
|
|
if (!StringSid || !sid)
|
|
|
|
|
SetLastError(ERROR_INVALID_PARAMETER);
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
UINT len = MultiByteToWideChar(CP_ACP, 0, StringSid, -1, NULL, 0);
|
|
|
|
|
LPWSTR wStringSid = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR));
|
|
|
|
|
MultiByteToWideChar(CP_ACP, 0, StringSid, - 1, wStringSid, len);
|
|
|
|
|
bRetVal = ConvertStringSidToSidW(wStringSid, sid);
|
|
|
|
|
HeapFree(GetProcessHeap(), 0, wStringSid);
|
|
|
|
|
}
|
|
|
|
|
return bRetVal;
|
|
|
|
|
}
|
|
|
|
|
|
2008-09-21 13:55:53 +00:00
|
|
|
|
|
2006-10-11 22:14:05 +00:00
|
|
|
|
/******************************************************************************
|
|
|
|
|
* ComputeStringSidSize
|
|
|
|
|
*/
|
2008-09-21 13:55:53 +00:00
|
|
|
|
static DWORD
|
|
|
|
|
ComputeStringSidSize(LPCWSTR StringSid)
|
2006-10-11 22:14:05 +00:00
|
|
|
|
{
|
|
|
|
|
DWORD size = sizeof(SID);
|
|
|
|
|
|
|
|
|
|
if (StringSid[0] == 'S' && StringSid[1] == '-') /* S-R-I-S-S */
|
|
|
|
|
{
|
|
|
|
|
int ctok = 0;
|
|
|
|
|
while (*StringSid)
|
|
|
|
|
{
|
|
|
|
|
if (*StringSid == '-')
|
|
|
|
|
ctok++;
|
|
|
|
|
StringSid++;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (ctok > 3)
|
|
|
|
|
size += (ctok - 3) * sizeof(DWORD);
|
|
|
|
|
}
|
|
|
|
|
else /* String constant format - Only available in winxp and above */
|
|
|
|
|
{
|
2008-12-07 21:52:22 +00:00
|
|
|
|
unsigned int i;
|
2006-10-11 22:14:05 +00:00
|
|
|
|
|
|
|
|
|
for (i = 0; i < sizeof(WellKnownSids)/sizeof(WellKnownSids[0]); i++)
|
|
|
|
|
if (!strncmpW(WellKnownSids[i].wstr, StringSid, 2))
|
|
|
|
|
size += (WellKnownSids[i].Sid.SubAuthorityCount - 1) * sizeof(DWORD);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return size;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
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 },
|
|
|
|
|
};
|
|
|
|
|
|
2005-11-14 22:44:36 +00:00
|
|
|
|
/*
|
2006-10-11 22:14:05 +00:00
|
|
|
|
* @implemented
|
2005-11-14 22:44:36 +00:00
|
|
|
|
*/
|
2006-10-11 22:14:05 +00:00
|
|
|
|
BOOL WINAPI
|
2008-09-21 13:55:53 +00:00
|
|
|
|
ConvertStringSidToSidW(IN LPCWSTR StringSid,
|
|
|
|
|
OUT PSID* sid)
|
2005-11-14 22:44:36 +00:00
|
|
|
|
{
|
2008-09-21 13:55:53 +00:00
|
|
|
|
DWORD size;
|
|
|
|
|
DWORD i, cBytes, identAuth, csubauth;
|
|
|
|
|
BOOL ret;
|
|
|
|
|
SID* pisid;
|
2006-10-11 22:14:05 +00:00
|
|
|
|
|
2008-09-21 13:55:53 +00:00
|
|
|
|
TRACE("%s %p\n", debugstr_w(StringSid), sid);
|
2006-10-11 22:14:05 +00:00
|
|
|
|
|
|
|
|
|
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 - 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)
|
|
|
|
|
{
|
|
|
|
|
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++;
|
|
|
|
|
|
2008-12-08 15:51:53 +00:00
|
|
|
|
pisid->SubAuthority[i] = atoiW(StringSid);
|
|
|
|
|
|
2006-10-11 22:14:05 +00:00
|
|
|
|
while (*StringSid)
|
|
|
|
|
{
|
|
|
|
|
while (*StringSid && *StringSid != '-')
|
|
|
|
|
StringSid++;
|
|
|
|
|
if (*StringSid == '-')
|
|
|
|
|
StringSid++;
|
|
|
|
|
|
2008-12-08 15:51:53 +00:00
|
|
|
|
pisid->SubAuthority[++i] = atoiW(StringSid);
|
2006-10-11 22:14:05 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
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;
|
2005-11-14 22:44:36 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
2000-04-05 01:41:01 +00:00
|
|
|
|
/* EOF */
|