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>
27 #include "secutil_nt.h"
31 /* local declarations */
33 static BOOL WorldGroupSidAllocate(PSID * sidPP);
35 static BOOL LocalAdminsGroupSidAllocate(PSID * sidPP);
38 BuildExplicitAccessWithSid(PEXPLICIT_ACCESS explicitAccessP,
39 PSID trusteeSidP, DWORD accessPerm,
40 ACCESS_MODE accessMode, DWORD inheritance);
44 /* -------------------- Exported functions ------------------------ */
49 * ObjectDaclEntryAdd() -- add an access-control entry to an object's DACL.
51 * Notes: The accessPerm, accessMode, and inheritance args must be correct
52 * for an EXPLICIT_ACCESS structure describing a DACL entry.
53 * Caller must have READ_CONTRL/WRITE_DAC rights for object handle.
55 * RETURN CODES: Win32 status code (ERROR_SUCCESS if succeeds)
58 ObjectDaclEntryAdd(HANDLE objectHandle, SE_OBJECT_TYPE objectType,
59 WELLKNOWN_TRUSTEE_ID trustee, DWORD accessPerm,
60 ACCESS_MODE accessMode, DWORD inheritance)
62 DWORD status = ERROR_SUCCESS;
65 /* allocate SID for (well-known) trustee */
67 if (trustee == WorldGroup) {
68 if (!WorldGroupSidAllocate(&trusteeSidP)) {
69 status = GetLastError();
71 } else if (trustee == LocalAdministratorsGroup) {
72 if (!LocalAdminsGroupSidAllocate(&trusteeSidP)) {
73 status = GetLastError();
76 status = ERROR_INVALID_PARAMETER;
79 if (status == ERROR_SUCCESS) {
80 EXPLICIT_ACCESS accessEntry;
81 PACL curDaclP, newDaclP;
82 PSECURITY_DESCRIPTOR secP;
84 /* initialize access information for trustee */
86 BuildExplicitAccessWithSid(&accessEntry, trusteeSidP, accessPerm,
87 accessMode, inheritance);
89 /* get object's current DACL */
92 GetSecurityInfo(objectHandle, objectType,
93 DACL_SECURITY_INFORMATION, NULL, NULL, &curDaclP,
96 if (status == ERROR_SUCCESS) {
97 /* merge access information into current DACL to form new DACL */
98 status = SetEntriesInAcl(1, &accessEntry, curDaclP, &newDaclP);
100 if (status == ERROR_SUCCESS) {
101 /* replace object's current DACL with newly formed DACL */
103 /* MS SP4 introduced a bug into SetSecurityInfo() so that it
104 * no longer operates correctly with named pipes. Work around
105 * this problem by using "low-level" access control functions
106 * for kernel objects (of which named pipes are one example).
109 if (objectType != SE_KERNEL_OBJECT) {
111 SetSecurityInfo(objectHandle, objectType,
112 DACL_SECURITY_INFORMATION, NULL, NULL,
115 if (!SetSecurityDescriptorDacl
116 (secP, TRUE, newDaclP, FALSE)
117 || !SetKernelObjectSecurity(objectHandle,
118 DACL_SECURITY_INFORMATION,
120 status = GetLastError();
124 (void)LocalFree((HLOCAL) newDaclP);
127 (void)LocalFree((HLOCAL) secP);
130 FreeSid(trusteeSidP);
139 /* -------------------- Local functions ------------------------ */
142 * WorldGroupSidAllocate() -- allocate and initialize SID for the
143 * well-known World group representing all users.
145 * SID is freed via FreeSid()
147 * RETURN CODES: TRUE success, FALSE failure (GetLastError() indicates why)
150 WorldGroupSidAllocate(PSID * sidPP)
152 SID_IDENTIFIER_AUTHORITY sidAuth = SECURITY_WORLD_SID_AUTHORITY;
154 return AllocateAndInitializeSid(&sidAuth, 1, SECURITY_WORLD_RID, 0, 0, 0,
160 * LocalAdminsGroupSidAllocate() -- allocate and initialize SID for the
161 * well-known local Administrators group.
163 * SID is freed via FreeSid()
165 * RETURN CODES: TRUE success, FALSE failure (GetLastError() indicates why)
168 LocalAdminsGroupSidAllocate(PSID * sidPP)
170 SID_IDENTIFIER_AUTHORITY sidAuth = SECURITY_NT_AUTHORITY;
172 return AllocateAndInitializeSid(&sidAuth, 2, SECURITY_BUILTIN_DOMAIN_RID,
173 DOMAIN_ALIAS_RID_ADMINS, 0, 0, 0, 0, 0, 0,
179 * BuildExplicitAccessWithSid() - counterpart to the Win32 API function
180 * BuildExplicitAccessWithName() (surprisingly, MS doesn't provide this).
183 BuildExplicitAccessWithSid(PEXPLICIT_ACCESS explicitAccessP, PSID trusteeSidP,
184 DWORD accessPerm, ACCESS_MODE accessMode,
187 if (explicitAccessP != NULL) {
188 explicitAccessP->grfAccessPermissions = accessPerm;
189 explicitAccessP->grfAccessMode = accessMode;
190 explicitAccessP->grfInheritance = inheritance;
191 BuildTrusteeWithSid(&explicitAccessP->Trustee, trusteeSidP);