2 * Copyright 2000, International Business Machines Corporation and others.
5 * This software has been released under the terms of the IBM Public
6 * License. For details, see the LICENSE file in the top-level source
7 * directory or online at http://www.openafs.org/dl/license10.html
10 /* Security related utilities for the Windows platform */
12 #include <afsconfig.h>
13 #include <afs/param.h>
23 #include "secutil_nt.h"
27 /* local declarations */
29 static BOOL
WorldGroupSidAllocate(PSID
* sidPP
);
31 static BOOL
LocalAdminsGroupSidAllocate(PSID
* sidPP
);
34 BuildExplicitAccessWithSid(PEXPLICIT_ACCESS explicitAccessP
,
35 PSID trusteeSidP
, DWORD accessPerm
,
36 ACCESS_MODE accessMode
, DWORD inheritance
);
40 /* -------------------- Exported functions ------------------------ */
45 * ObjectDaclEntryAdd() -- add an access-control entry to an object's DACL.
47 * Notes: The accessPerm, accessMode, and inheritance args must be correct
48 * for an EXPLICIT_ACCESS structure describing a DACL entry.
49 * Caller must have READ_CONTRL/WRITE_DAC rights for object handle.
51 * RETURN CODES: Win32 status code (ERROR_SUCCESS if succeeds)
54 ObjectDaclEntryAdd(HANDLE objectHandle
, SE_OBJECT_TYPE objectType
,
55 WELLKNOWN_TRUSTEE_ID trustee
, DWORD accessPerm
,
56 ACCESS_MODE accessMode
, DWORD inheritance
)
58 DWORD status
= ERROR_SUCCESS
;
61 /* allocate SID for (well-known) trustee */
63 if (trustee
== WorldGroup
) {
64 if (!WorldGroupSidAllocate(&trusteeSidP
)) {
65 status
= GetLastError();
67 } else if (trustee
== LocalAdministratorsGroup
) {
68 if (!LocalAdminsGroupSidAllocate(&trusteeSidP
)) {
69 status
= GetLastError();
72 status
= ERROR_INVALID_PARAMETER
;
75 if (status
== ERROR_SUCCESS
) {
76 EXPLICIT_ACCESS accessEntry
;
77 PACL curDaclP
, newDaclP
;
78 PSECURITY_DESCRIPTOR secP
;
80 /* initialize access information for trustee */
82 BuildExplicitAccessWithSid(&accessEntry
, trusteeSidP
, accessPerm
,
83 accessMode
, inheritance
);
85 /* get object's current DACL */
88 GetSecurityInfo(objectHandle
, objectType
,
89 DACL_SECURITY_INFORMATION
, NULL
, NULL
, &curDaclP
,
92 if (status
== ERROR_SUCCESS
) {
93 /* merge access information into current DACL to form new DACL */
94 status
= SetEntriesInAcl(1, &accessEntry
, curDaclP
, &newDaclP
);
96 if (status
== ERROR_SUCCESS
) {
97 /* replace object's current DACL with newly formed DACL */
99 /* MS SP4 introduced a bug into SetSecurityInfo() so that it
100 * no longer operates correctly with named pipes. Work around
101 * this problem by using "low-level" access control functions
102 * for kernel objects (of which named pipes are one example).
105 if (objectType
!= SE_KERNEL_OBJECT
) {
107 SetSecurityInfo(objectHandle
, objectType
,
108 DACL_SECURITY_INFORMATION
, NULL
, NULL
,
111 if (!SetSecurityDescriptorDacl
112 (secP
, TRUE
, newDaclP
, FALSE
)
113 || !SetKernelObjectSecurity(objectHandle
,
114 DACL_SECURITY_INFORMATION
,
116 status
= GetLastError();
120 (void)LocalFree((HLOCAL
) newDaclP
);
123 (void)LocalFree((HLOCAL
) secP
);
126 FreeSid(trusteeSidP
);
135 /* -------------------- Local functions ------------------------ */
138 * WorldGroupSidAllocate() -- allocate and initialize SID for the
139 * well-known World group representing all users.
141 * SID is freed via FreeSid()
143 * RETURN CODES: TRUE success, FALSE failure (GetLastError() indicates why)
146 WorldGroupSidAllocate(PSID
* sidPP
)
148 SID_IDENTIFIER_AUTHORITY sidAuth
= SECURITY_WORLD_SID_AUTHORITY
;
150 return AllocateAndInitializeSid(&sidAuth
, 1, SECURITY_WORLD_RID
, 0, 0, 0,
156 * LocalAdminsGroupSidAllocate() -- allocate and initialize SID for the
157 * well-known local Administrators group.
159 * SID is freed via FreeSid()
161 * RETURN CODES: TRUE success, FALSE failure (GetLastError() indicates why)
164 LocalAdminsGroupSidAllocate(PSID
* sidPP
)
166 SID_IDENTIFIER_AUTHORITY sidAuth
= SECURITY_NT_AUTHORITY
;
168 return AllocateAndInitializeSid(&sidAuth
, 2, SECURITY_BUILTIN_DOMAIN_RID
,
169 DOMAIN_ALIAS_RID_ADMINS
, 0, 0, 0, 0, 0, 0,
175 * BuildExplicitAccessWithSid() - counterpart to the Win32 API function
176 * BuildExplicitAccessWithName() (surprisingly, MS doesn't provide this).
179 BuildExplicitAccessWithSid(PEXPLICIT_ACCESS explicitAccessP
, PSID trusteeSidP
,
180 DWORD accessPerm
, ACCESS_MODE accessMode
,
183 if (explicitAccessP
!= NULL
) {
184 explicitAccessP
->grfAccessPermissions
= accessPerm
;
185 explicitAccessP
->grfAccessMode
= accessMode
;
186 explicitAccessP
->grfInheritance
= inheritance
;
187 BuildTrusteeWithSid(&explicitAccessP
->Trustee
, trusteeSidP
);