Line data Source code
1 : /*
2 : Authors:
3 : Sumit Bose <sbose@redhat.com>
4 :
5 : Copyright (C) 2013 Red Hat
6 :
7 : Translate well-known SIDs to domains and names
8 :
9 : This program is free software; you can redistribute it and/or modify
10 : it under the terms of the GNU General Public License as published by
11 : the Free Software Foundation; either version 3 of the License, or
12 : (at your option) any later version.
13 :
14 : This program is distributed in the hope that it will be useful,
15 : but WITHOUT ANY WARRANTY; without even the implied warranty of
16 : MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 : GNU General Public License for more details.
18 :
19 : You should have received a copy of the GNU General Public License
20 : along with this program. If not, see <http://www.gnu.org/licenses/>.
21 : */
22 :
23 : #include "util/util.h"
24 : #include "util/strtonum.h"
25 :
26 : /* Well-Known SIDs are documented in section 2.4.2.4 "Well-Known SID
27 : * Structures" of the "[MS-DTYP]: Windows Data Types" document. */
28 :
29 : #define DOM_SID_PREFIX "S-1-5-21-"
30 : #define DOM_SID_PREFIX_LEN (sizeof(DOM_SID_PREFIX) - 1)
31 :
32 : #define BUILTIN_SID_PREFIX "S-1-5-32-"
33 : #define BUILTIN_SID_PREFIX_LEN (sizeof(BUILTIN_SID_PREFIX) - 1)
34 : #define BUILTIN_DOM_NAME "BUILTIN"
35 :
36 : #define NT_SID_PREFIX "S-1-5-"
37 : #define NT_SID_PREFIX_LEN (sizeof(NT_SID_PREFIX) - 1)
38 : #define NT_DOM_NAME "NT AUTHORITY"
39 :
40 : #define SPECIAL_SID_PREFIX "S-1-"
41 : #define SPECIAL_SID_PREFIX_LEN (sizeof(SPECIAL_SID_PREFIX) - 1)
42 : #define NULL_DOM_NAME "NULL AUTHORITY"
43 : #define WORLD_DOM_NAME "WORLD AUTHORITY"
44 : #define LOCAL_DOM_NAME "LOCAL AUTHORITY"
45 : #define CREATOR_DOM_NAME "CREATOR AUTHORITY"
46 :
47 : #define NT_MAP_ENTRY(rid, name) {rid, NT_SID_PREFIX #rid, name}
48 : #define BUILTIN_MAP_ENTRY(rid, name) {rid, BUILTIN_SID_PREFIX #rid, name}
49 : #define SPECIAL_MAP_ENTRY(id_auth, rid, dom, name) \
50 : {(48 + id_auth), (48 + rid), SPECIAL_SID_PREFIX #id_auth "-" #rid, dom, name}
51 :
52 : struct rid_sid_name {
53 : uint32_t rid;
54 : const char *sid;
55 : const char *name;
56 : };
57 :
58 : struct special_map {
59 : const char id_auth;
60 : char rid;
61 : const char *sid;
62 : const char *dom;
63 : const char *name;
64 : };
65 :
66 : struct rid_sid_name builtin_map[] = {
67 : BUILTIN_MAP_ENTRY(544, "Administrators"),
68 : BUILTIN_MAP_ENTRY(545, "Users"),
69 : BUILTIN_MAP_ENTRY(546, "Guests"),
70 : BUILTIN_MAP_ENTRY(547, "Power Users"),
71 : BUILTIN_MAP_ENTRY(548, "Account Operators"),
72 : BUILTIN_MAP_ENTRY(549, "Server Operators"),
73 : BUILTIN_MAP_ENTRY(550, "Print Operators"),
74 : BUILTIN_MAP_ENTRY(551, "Backup Operators"),
75 : BUILTIN_MAP_ENTRY(552, "Replicator"),
76 : BUILTIN_MAP_ENTRY(554, "Pre-Windows 2000 Compatible Access"),
77 : BUILTIN_MAP_ENTRY(555, "Remote Desktop Users"),
78 : BUILTIN_MAP_ENTRY(556, "Network Configuration Operators"),
79 : BUILTIN_MAP_ENTRY(557, "Incoming Forest Trust Builders"),
80 : BUILTIN_MAP_ENTRY(558, "Performance Monitor Users"),
81 : BUILTIN_MAP_ENTRY(559, "Performance Log Users"),
82 : BUILTIN_MAP_ENTRY(560, "Windows Authorization Access Group"),
83 : BUILTIN_MAP_ENTRY(561, "Terminal Server License Servers"),
84 : BUILTIN_MAP_ENTRY(562, "Distributed COM Users"),
85 : BUILTIN_MAP_ENTRY(568, "IIS_IUSRS"),
86 : BUILTIN_MAP_ENTRY(569, "Cryptographic Operators"),
87 : BUILTIN_MAP_ENTRY(573, "Event Log Readers"),
88 : BUILTIN_MAP_ENTRY(574, "Certificate Service DCOM Access"),
89 : BUILTIN_MAP_ENTRY(575, "RDS Remote Access Servers"),
90 : BUILTIN_MAP_ENTRY(576, "RDS Endpoint Servers"),
91 : BUILTIN_MAP_ENTRY(577, "RDS Management Servers"),
92 : BUILTIN_MAP_ENTRY(578, "Hyper-V Admins"),
93 : BUILTIN_MAP_ENTRY(579, "Access Control Assistance OPS"),
94 : BUILTIN_MAP_ENTRY(580, "Remote Management Users"),
95 :
96 : {UINT32_MAX, NULL, NULL}
97 : };
98 :
99 : struct rid_sid_name nt_map[] = {
100 : NT_MAP_ENTRY(1, "DIALUP"),
101 : NT_MAP_ENTRY(2, "NETWORK"),
102 : NT_MAP_ENTRY(3, "BATCH"),
103 : NT_MAP_ENTRY(4, "INTERACTIVE"),
104 : NT_MAP_ENTRY(6, "SERVICE"),
105 : NT_MAP_ENTRY(7, "ANONYMOUS LOGON"),
106 : NT_MAP_ENTRY(8, "PROXY"),
107 : NT_MAP_ENTRY(9, "ENTERPRISE DOMAIN CONTROLLERS"),
108 : NT_MAP_ENTRY(10, "SELF"),
109 : NT_MAP_ENTRY(11, "Authenticated Users"),
110 : NT_MAP_ENTRY(12, "RESTRICTED"),
111 : NT_MAP_ENTRY(13, "TERMINAL SERVER USER"),
112 : NT_MAP_ENTRY(14, "REMOTE INTERACTIVE LOGON"),
113 : NT_MAP_ENTRY(15, "This Organization"),
114 : NT_MAP_ENTRY(17, "IUSR"),
115 : NT_MAP_ENTRY(18, "SYSTEM"),
116 : NT_MAP_ENTRY(19, "LOCAL SERVICE"),
117 : NT_MAP_ENTRY(20, "NETWORK SERVICE"),
118 :
119 : {UINT32_MAX, NULL, NULL}
120 : };
121 :
122 : /* The code to handle the SIDs of the Null, World, Local and Creator
123 : * Authorities (id_auth=0,1,2,3 respectively) is optimized to handle only
124 : * single digit id_auth and rid. */
125 :
126 : struct special_map sp_map[] = {
127 : SPECIAL_MAP_ENTRY(0, 0, NULL_DOM_NAME, "NULL SID"),
128 : SPECIAL_MAP_ENTRY(1, 0, WORLD_DOM_NAME, "Everyone"),
129 : SPECIAL_MAP_ENTRY(2, 0, LOCAL_DOM_NAME, "LOCAL"),
130 : SPECIAL_MAP_ENTRY(2, 1, LOCAL_DOM_NAME, "CONSOLE LOGON"),
131 : SPECIAL_MAP_ENTRY(3, 0, CREATOR_DOM_NAME, "CREATOR OWNER"),
132 : SPECIAL_MAP_ENTRY(3, 1, CREATOR_DOM_NAME, "CREATOR GROUP"),
133 : SPECIAL_MAP_ENTRY(3, 2, CREATOR_DOM_NAME, "CREATOR OWNER SERVER"),
134 : SPECIAL_MAP_ENTRY(3, 3, CREATOR_DOM_NAME, "CREATOR GROUP SERVER"),
135 : SPECIAL_MAP_ENTRY(3, 4, CREATOR_DOM_NAME, "OWNER RIGHTS"),
136 : SPECIAL_MAP_ENTRY(18,1, "ASSERTED IDENTITY", "AUTHENTICATION ASSERTION"),
137 : SPECIAL_MAP_ENTRY(18,2, "ASSERTED IDENTITY", "SERVICE ASSERTION"),
138 :
139 : {'\0', '\0', NULL, NULL, NULL}
140 : };
141 :
142 7 : static errno_t handle_special_sids(const char *sid, const char **dom,
143 : const char **name)
144 : {
145 : size_t c;
146 :
147 7 : if (!isdigit(sid[SPECIAL_SID_PREFIX_LEN])
148 6 : || sid[SPECIAL_SID_PREFIX_LEN + 1] != '-'
149 4 : || !isdigit(sid[SPECIAL_SID_PREFIX_LEN + 2])
150 3 : || sid[SPECIAL_SID_PREFIX_LEN + 3] != '\0' ) {
151 5 : return EINVAL;
152 : }
153 :
154 4 : for (c = 0; sp_map[c].name != NULL; c++) {
155 4 : if (sid[SPECIAL_SID_PREFIX_LEN] == sp_map[c].id_auth
156 2 : && sid[SPECIAL_SID_PREFIX_LEN + 2] == sp_map[c].rid) {
157 2 : *name = sp_map[c].name;
158 2 : *dom = sp_map[c].dom;
159 2 : return EOK;
160 : }
161 : }
162 :
163 0 : return EINVAL;
164 : }
165 :
166 3 : static errno_t handle_special_names(const char *dom, const char *name,
167 : const char **sid)
168 : {
169 : size_t c;
170 :
171 13 : for (c = 0; sp_map[c].name != NULL; c++) {
172 13 : if (strcmp(name, sp_map[c].name) == 0
173 3 : && strcmp(dom, sp_map[c].dom) == 0) {
174 3 : *sid = sp_map[c].sid;
175 3 : return EOK;
176 : }
177 : }
178 :
179 0 : return EINVAL;
180 : }
181 :
182 11 : static errno_t handle_rid_to_name_map(const char *sid, size_t prefix_len,
183 : struct rid_sid_name *map,
184 : const char* dom_name, const char **dom,
185 : const char **name)
186 : {
187 : uint32_t rid;
188 : char *endptr;
189 : size_t c;
190 :
191 11 : errno = 0;
192 11 : rid = (uint32_t) strtouint32(sid + prefix_len, &endptr, 10);
193 11 : if (errno != 0 || *endptr != '\0') {
194 2 : return EINVAL;
195 : }
196 :
197 142 : for (c = 0; map[c].name != NULL; c++) {
198 137 : if (rid == map[c].rid) {
199 4 : *name = map[c].name;
200 4 : *dom = dom_name;
201 4 : return EOK;
202 : }
203 : }
204 :
205 5 : return EINVAL;
206 : }
207 :
208 8 : static errno_t handle_name_to_sid_map(const char *name,
209 : struct rid_sid_name *map,
210 : const char **sid)
211 : {
212 : size_t c;
213 :
214 167 : for (c = 0; map[c].name != NULL; c++) {
215 163 : if (strcmp(name, map[c].name) == 0) {
216 4 : *sid = map[c].sid;
217 4 : return EOK;
218 : }
219 : }
220 :
221 4 : return EINVAL;
222 : }
223 :
224 5 : static errno_t handle_nt_sids(const char *sid, const char **dom,
225 : const char **name)
226 : {
227 5 : return handle_rid_to_name_map(sid, NT_SID_PREFIX_LEN, nt_map, NT_DOM_NAME,
228 : dom, name);
229 : }
230 :
231 2 : static errno_t handle_nt_names(const char *name, const char **sid)
232 : {
233 2 : return handle_name_to_sid_map(name, nt_map, sid);
234 : }
235 :
236 6 : static errno_t handle_builtin_sids(const char *sid, const char **dom,
237 : const char **name)
238 : {
239 6 : return handle_rid_to_name_map(sid, BUILTIN_SID_PREFIX_LEN, builtin_map,
240 : BUILTIN_DOM_NAME, dom, name);
241 : }
242 :
243 6 : static errno_t handle_builtin_names(const char *name, const char **sid)
244 : {
245 6 : return handle_name_to_sid_map(name, builtin_map, sid);
246 : }
247 :
248 27 : errno_t well_known_sid_to_name(const char *sid, const char **dom,
249 : const char **name)
250 : {
251 : int ret;
252 :
253 27 : if (sid == NULL || dom == NULL || name == NULL) {
254 1 : return EINVAL;
255 : }
256 :
257 26 : if (strncmp(sid, DOM_SID_PREFIX, DOM_SID_PREFIX_LEN) == 0) {
258 6 : ret = ENOENT;
259 20 : } else if (strncmp(sid, BUILTIN_SID_PREFIX, BUILTIN_SID_PREFIX_LEN) == 0) {
260 6 : ret = handle_builtin_sids(sid, dom, name);
261 6 : if (ret != EOK) {
262 3 : DEBUG(SSSDBG_OP_FAILURE, "handle_builtin_sids failed.\n");
263 : }
264 14 : } else if (strncmp(sid, NT_SID_PREFIX, NT_SID_PREFIX_LEN) == 0) {
265 5 : ret = handle_nt_sids(sid, dom, name);
266 5 : if (ret != EOK) {
267 4 : DEBUG(SSSDBG_OP_FAILURE, "handle_nt_sids failed.\n");
268 : }
269 9 : } else if (strncmp(sid, SPECIAL_SID_PREFIX, SPECIAL_SID_PREFIX_LEN) == 0) {
270 7 : ret = handle_special_sids(sid, dom, name);
271 7 : if (ret != EOK) {
272 5 : DEBUG(SSSDBG_OP_FAILURE, "handle_special_sids failed.\n");
273 : }
274 : } else {
275 2 : ret = EINVAL;
276 : }
277 :
278 26 : return ret;
279 : }
280 :
281 15 : errno_t name_to_well_known_sid(const char *dom, const char *name,
282 : const char **sid)
283 : {
284 : int ret;
285 :
286 15 : if (sid == NULL || dom == NULL || name == NULL) {
287 2 : return EINVAL;
288 : }
289 :
290 13 : if (strcmp(dom, NT_DOM_NAME) == 0) {
291 2 : ret = handle_nt_names(name, sid);
292 2 : if (ret != EOK) {
293 1 : DEBUG(SSSDBG_OP_FAILURE, "handle_nt_name failed.\n");
294 : }
295 11 : } else if (strcmp(dom, BUILTIN_DOM_NAME) == 0) {
296 6 : ret = handle_builtin_names(name, sid);
297 6 : if (ret != EOK) {
298 3 : DEBUG(SSSDBG_OP_FAILURE, "handle_builtin_name failed.\n");
299 : }
300 5 : } else if (strcmp(dom, NULL_DOM_NAME) == 0
301 5 : || strcmp(dom, WORLD_DOM_NAME) == 0
302 5 : || strcmp(dom, LOCAL_DOM_NAME) == 0
303 4 : || strcmp(dom, CREATOR_DOM_NAME) == 0) {
304 3 : ret = handle_special_names(dom, name, sid);
305 6 : if (ret != EOK) {
306 0 : DEBUG(SSSDBG_OP_FAILURE, "handle_special_name failed.\n");
307 : }
308 : } else {
309 2 : ret = ENOENT;
310 : }
311 :
312 13 : return ret;
313 : }
|