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 <afs/param.h>
13 #include <afsconfig.h>
25 #include "secutil_nt.h"
29 /* local declarations */
31 static BOOL WorldGroupSidAllocate(PSID * sidPP);
33 static BOOL LocalAdminsGroupSidAllocate(PSID * sidPP);
36 BuildExplicitAccessWithSid(PEXPLICIT_ACCESS explicitAccessP,
37 PSID trusteeSidP, DWORD accessPerm,
38 ACCESS_MODE accessMode, DWORD inheritance);
42 /* -------------------- Exported functions ------------------------ */
47 * ObjectDaclEntryAdd() -- add an access-control entry to an object's DACL.
49 * Notes: The accessPerm, accessMode, and inheritance args must be correct
50 * for an EXPLICIT_ACCESS structure describing a DACL entry.
51 * Caller must have READ_CONTRL/WRITE_DAC rights for object handle.
53 * RETURN CODES: Win32 status code (ERROR_SUCCESS if succeeds)
56 ObjectDaclEntryAdd(HANDLE objectHandle, SE_OBJECT_TYPE objectType,
57 WELLKNOWN_TRUSTEE_ID trustee, DWORD accessPerm,
58 ACCESS_MODE accessMode, DWORD inheritance)
60 DWORD status = ERROR_SUCCESS;
63 /* allocate SID for (well-known) trustee */
65 if (trustee == WorldGroup) {
66 if (!WorldGroupSidAllocate(&trusteeSidP)) {
67 status = GetLastError();
69 } else if (trustee == LocalAdministratorsGroup) {
70 if (!LocalAdminsGroupSidAllocate(&trusteeSidP)) {
71 status = GetLastError();
74 status = ERROR_INVALID_PARAMETER;
77 if (status == ERROR_SUCCESS) {
78 EXPLICIT_ACCESS accessEntry;
79 PACL curDaclP, newDaclP;
80 PSECURITY_DESCRIPTOR secP;
82 /* initialize access information for trustee */
84 BuildExplicitAccessWithSid(&accessEntry, trusteeSidP, accessPerm,
85 accessMode, inheritance);
87 /* get object's current DACL */
90 GetSecurityInfo(objectHandle, objectType,
91 DACL_SECURITY_INFORMATION, NULL, NULL, &curDaclP,
94 if (status == ERROR_SUCCESS) {
95 /* merge access information into current DACL to form new DACL */
96 status = SetEntriesInAcl(1, &accessEntry, curDaclP, &newDaclP);
98 if (status == ERROR_SUCCESS) {
99 /* replace object's current DACL with newly formed DACL */
101 /* MS SP4 introduced a bug into SetSecurityInfo() so that it
102 * no longer operates correctly with named pipes. Work around
103 * this problem by using "low-level" access control functions
104 * for kernel objects (of which named pipes are one example).
107 if (objectType != SE_KERNEL_OBJECT) {
109 SetSecurityInfo(objectHandle, objectType,
110 DACL_SECURITY_INFORMATION, NULL, NULL,
113 if (!SetSecurityDescriptorDacl
114 (secP, TRUE, newDaclP, FALSE)
115 || !SetKernelObjectSecurity(objectHandle,
116 DACL_SECURITY_INFORMATION,
118 status = GetLastError();
122 (void)LocalFree((HLOCAL) newDaclP);
125 (void)LocalFree((HLOCAL) secP);
128 FreeSid(trusteeSidP);
137 /* -------------------- Local functions ------------------------ */
140 * WorldGroupSidAllocate() -- allocate and initialize SID for the
141 * well-known World group representing all users.
143 * SID is freed via FreeSid()
145 * RETURN CODES: TRUE success, FALSE failure (GetLastError() indicates why)
148 WorldGroupSidAllocate(PSID * sidPP)
150 SID_IDENTIFIER_AUTHORITY sidAuth = SECURITY_WORLD_SID_AUTHORITY;
152 return AllocateAndInitializeSid(&sidAuth, 1, SECURITY_WORLD_RID, 0, 0, 0,
158 * LocalAdminsGroupSidAllocate() -- allocate and initialize SID for the
159 * well-known local Administrators group.
161 * SID is freed via FreeSid()
163 * RETURN CODES: TRUE success, FALSE failure (GetLastError() indicates why)
166 LocalAdminsGroupSidAllocate(PSID * sidPP)
168 SID_IDENTIFIER_AUTHORITY sidAuth = SECURITY_NT_AUTHORITY;
170 return AllocateAndInitializeSid(&sidAuth, 2, SECURITY_BUILTIN_DOMAIN_RID,
171 DOMAIN_ALIAS_RID_ADMINS, 0, 0, 0, 0, 0, 0,
177 * BuildExplicitAccessWithSid() - counterpart to the Win32 API function
178 * BuildExplicitAccessWithName() (surprisingly, MS doesn't provide this).
181 BuildExplicitAccessWithSid(PEXPLICIT_ACCESS explicitAccessP, PSID trusteeSidP,
182 DWORD accessPerm, ACCESS_MODE accessMode,
185 if (explicitAccessP != NULL) {
186 explicitAccessP->grfAccessPermissions = accessPerm;
187 explicitAccessP->grfAccessMode = accessMode;
188 explicitAccessP->grfInheritance = inheritance;
189 BuildTrusteeWithSid(&explicitAccessP->Trustee, trusteeSidP);