backport to buster
[hcoop/debian/openafs.git] / src / util / secutil_nt.c
CommitLineData
805e021f
CE
1/*
2 * Copyright 2000, International Business Machines Corporation and others.
3 * All Rights Reserved.
4 *
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
8 */
9
10/* Security related utilities for the Windows platform */
11
12#include <afsconfig.h>
13#include <afs/param.h>
14#include <afs/stds.h>
15
16#include <stddef.h>
17#include <stdlib.h>
18#include <errno.h>
19
20#include <windows.h>
21#include <aclapi.h>
22
23#include "secutil_nt.h"
24
25
26
27/* local declarations */
28
29static BOOL WorldGroupSidAllocate(PSID * sidPP);
30
31static BOOL LocalAdminsGroupSidAllocate(PSID * sidPP);
32
33static void
34 BuildExplicitAccessWithSid(PEXPLICIT_ACCESS explicitAccessP,
35 PSID trusteeSidP, DWORD accessPerm,
36 ACCESS_MODE accessMode, DWORD inheritance);
37
38
39
40/* -------------------- Exported functions ------------------------ */
41
42
43
44/*
45 * ObjectDaclEntryAdd() -- add an access-control entry to an object's DACL.
46 *
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.
50 *
51 * RETURN CODES: Win32 status code (ERROR_SUCCESS if succeeds)
52 */
53DWORD
54ObjectDaclEntryAdd(HANDLE objectHandle, SE_OBJECT_TYPE objectType,
55 WELLKNOWN_TRUSTEE_ID trustee, DWORD accessPerm,
56 ACCESS_MODE accessMode, DWORD inheritance)
57{
58 DWORD status = ERROR_SUCCESS;
59 PSID trusteeSidP;
60
61 /* allocate SID for (well-known) trustee */
62
63 if (trustee == WorldGroup) {
64 if (!WorldGroupSidAllocate(&trusteeSidP)) {
65 status = GetLastError();
66 }
67 } else if (trustee == LocalAdministratorsGroup) {
68 if (!LocalAdminsGroupSidAllocate(&trusteeSidP)) {
69 status = GetLastError();
70 }
71 } else {
72 status = ERROR_INVALID_PARAMETER;
73 }
74
75 if (status == ERROR_SUCCESS) {
76 EXPLICIT_ACCESS accessEntry;
77 PACL curDaclP, newDaclP;
78 PSECURITY_DESCRIPTOR secP;
79
80 /* initialize access information for trustee */
81
82 BuildExplicitAccessWithSid(&accessEntry, trusteeSidP, accessPerm,
83 accessMode, inheritance);
84
85 /* get object's current DACL */
86
87 status =
88 GetSecurityInfo(objectHandle, objectType,
89 DACL_SECURITY_INFORMATION, NULL, NULL, &curDaclP,
90 NULL, &secP);
91
92 if (status == ERROR_SUCCESS) {
93 /* merge access information into current DACL to form new DACL */
94 status = SetEntriesInAcl(1, &accessEntry, curDaclP, &newDaclP);
95
96 if (status == ERROR_SUCCESS) {
97 /* replace object's current DACL with newly formed DACL */
98
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).
103 */
104
105 if (objectType != SE_KERNEL_OBJECT) {
106 status =
107 SetSecurityInfo(objectHandle, objectType,
108 DACL_SECURITY_INFORMATION, NULL, NULL,
109 newDaclP, NULL);
110 } else {
111 if (!SetSecurityDescriptorDacl
112 (secP, TRUE, newDaclP, FALSE)
113 || !SetKernelObjectSecurity(objectHandle,
114 DACL_SECURITY_INFORMATION,
115 secP)) {
116 status = GetLastError();
117 }
118 }
119
120 (void)LocalFree((HLOCAL) newDaclP);
121 }
122
123 (void)LocalFree((HLOCAL) secP);
124 }
125
126 FreeSid(trusteeSidP);
127 }
128
129 return status;
130}
131
132
133
134
135/* -------------------- Local functions ------------------------ */
136
137/*
138 * WorldGroupSidAllocate() -- allocate and initialize SID for the
139 * well-known World group representing all users.
140 *
141 * SID is freed via FreeSid()
142 *
143 * RETURN CODES: TRUE success, FALSE failure (GetLastError() indicates why)
144 */
145static BOOL
146WorldGroupSidAllocate(PSID * sidPP)
147{
148 SID_IDENTIFIER_AUTHORITY sidAuth = SECURITY_WORLD_SID_AUTHORITY;
149
150 return AllocateAndInitializeSid(&sidAuth, 1, SECURITY_WORLD_RID, 0, 0, 0,
151 0, 0, 0, 0, sidPP);
152}
153
154
155/*
156 * LocalAdminsGroupSidAllocate() -- allocate and initialize SID for the
157 * well-known local Administrators group.
158 *
159 * SID is freed via FreeSid()
160 *
161 * RETURN CODES: TRUE success, FALSE failure (GetLastError() indicates why)
162 */
163static BOOL
164LocalAdminsGroupSidAllocate(PSID * sidPP)
165{
166 SID_IDENTIFIER_AUTHORITY sidAuth = SECURITY_NT_AUTHORITY;
167
168 return AllocateAndInitializeSid(&sidAuth, 2, SECURITY_BUILTIN_DOMAIN_RID,
169 DOMAIN_ALIAS_RID_ADMINS, 0, 0, 0, 0, 0, 0,
170 sidPP);
171}
172
173
174/*
175 * BuildExplicitAccessWithSid() - counterpart to the Win32 API function
176 * BuildExplicitAccessWithName() (surprisingly, MS doesn't provide this).
177 */
178static void
179BuildExplicitAccessWithSid(PEXPLICIT_ACCESS explicitAccessP, PSID trusteeSidP,
180 DWORD accessPerm, ACCESS_MODE accessMode,
181 DWORD inheritance)
182{
183 if (explicitAccessP != NULL) {
184 explicitAccessP->grfAccessPermissions = accessPerm;
185 explicitAccessP->grfAccessMode = accessMode;
186 explicitAccessP->grfInheritance = inheritance;
187 BuildTrusteeWithSid(&explicitAccessP->Trustee, trusteeSidP);
188 }
189}