xref: /illumos-gate/usr/src/lib/smbsrv/libsmb/common/smb_wksids.c (revision 6537f381d2d9e7b4e2f7b29c3e7a3f13be036f2e)
1 /*
2  * CDDL HEADER START
3  *
4  * The contents of this file are subject to the terms of the
5  * Common Development and Distribution License (the "License").
6  * You may not use this file except in compliance with the License.
7  *
8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9  * or http://www.opensolaris.org/os/licensing.
10  * See the License for the specific language governing permissions
11  * and limitations under the License.
12  *
13  * When distributing Covered Code, include this CDDL HEADER in each
14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15  * If applicable, add the following below this CDDL HEADER, with the
16  * fields enclosed by brackets "[]" replaced with your own identifying
17  * information: Portions Copyright [yyyy] [name of copyright owner]
18  *
19  * CDDL HEADER END
20  */
21 /*
22  * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
23  * Use is subject to license terms.
24  */
25 
26 #pragma ident	"%Z%%M%	%I%	%E% SMI"
27 
28 /*
29  * This module provides the interface to builtin domain information.
30  * These are the predefined groups and aliases in the NT AUTHORITY or
31  * BUILTIN domains, and some other miscellaneous bits.
32  */
33 
34 #include <stdlib.h>
35 #include <string.h>
36 #include <synch.h>
37 
38 #include <smbsrv/smb_sid.h>
39 #include <smbsrv/string.h>
40 
41 /*
42  * This table should contain all of the NT builtin domain names.
43  */
44 static char *domain[] = {
45 	"LOCAL",
46 	"BUILTIN",
47 	"NT AUTHORITY",
48 	"UNKNOWN"
49 };
50 
51 static int wk_init = 0;
52 static rwlock_t wk_rwlock;
53 
54 /*
55  * This table should contain all of the builtin domains, groups and
56  * aliases. The order is important because we do string compares on
57  * the SIDs. For each domain, ensure that the domain SID appears
58  * before any aliases in that domain.
59  */
60 static smb_wka_t wka_tbl[] = {
61 	{ SidTypeWellKnownGroup, 0, "S-1-0-0",		"Null",
62 	    0, NULL, NULL},
63 	{ SidTypeWellKnownGroup, 1, "S-1-1-0",		"Everyone",
64 	    0, NULL, NULL},
65 	{ SidTypeWellKnownGroup, 1, "S-1-2-0",		"LOCAL",
66 	    0, NULL, NULL},
67 	{ SidTypeWellKnownGroup, 1, "S-1-3-0",		"CREATOR OWNER",
68 	    0, NULL, NULL},
69 	{ SidTypeWellKnownGroup, 1, "S-1-3-1",		"CREATOR GROUP",
70 	    0, NULL, NULL},
71 	{ SidTypeWellKnownGroup, 1, "S-1-3-2",		"CREATOR OWNER SERVER",
72 	    0, NULL, NULL},
73 	{ SidTypeWellKnownGroup, 1, "S-1-3-3",		"CREATOR GROUP SERVER",
74 	    0, NULL, NULL},
75 	{ SidTypeDomain, 1, "S-1-4",			"NON UNIQUE",
76 	    0, NULL, NULL},
77 	{ SidTypeDomain, 2, "S-1-5",			"NT AUTHORITY",
78 	    0, NULL, NULL},
79 	{ SidTypeWellKnownGroup, 2, "S-1-5-1",		"DIALUP",
80 	    0, NULL, NULL},
81 	{ SidTypeWellKnownGroup, 2, "S-1-5-2",		"NETWORK",
82 	    0, NULL, NULL},
83 	{ SidTypeWellKnownGroup, 2, "S-1-5-3",		"BATCH",
84 	    0, NULL, NULL},
85 	{ SidTypeWellKnownGroup, 2, "S-1-5-4",		"INTERACTIVE",
86 	    0, NULL, NULL},
87 	{ SidTypeWellKnownGroup, 2, "S-1-5-6",		"SERVICE",
88 	    0, NULL, NULL},
89 	{ SidTypeWellKnownGroup, 2, "S-1-5-7",		"ANONYMOUS",
90 	    0, NULL, NULL},
91 	{ SidTypeWellKnownGroup, 2, "S-1-5-8",		"PROXY",
92 	    0, NULL, NULL},
93 	{ SidTypeWellKnownGroup, 2, "S-1-5-9",		"SERVER",
94 	    0, NULL, NULL},
95 	{ SidTypeWellKnownGroup, 2, "S-1-5-10",		"SELF",
96 	    0, NULL, NULL},
97 	{ SidTypeWellKnownGroup, 2, "S-1-5-11",		"Authenticated Users",
98 	    0, NULL, NULL},
99 	{ SidTypeWellKnownGroup, 2, "S-1-5-12",		"RESTRICTED",
100 	    0, NULL, NULL},
101 	{ SidTypeWellKnownGroup, 2, "S-1-5-18",		"SYSTEM",
102 	    0, NULL, NULL},
103 	{ SidTypeWellKnownGroup, 2, "S-1-5-21",		"NON_UNIQUE",
104 	    0, NULL, NULL},
105 	{ SidTypeDomain, 2, "S-1-5-32",			"BUILTIN",
106 	    0, NULL, NULL},
107 	{ SidTypeAlias, 1, "S-1-5-32-544",		"Administrators",
108 	    SMB_WKAFLG_LGRP_ENABLE,
109 	    "Members can fully administer the computer/domain", NULL },
110 	{ SidTypeAlias, 1, "S-1-5-32-545",		"Users",
111 	    0, NULL, NULL},
112 	{ SidTypeAlias, 1, "S-1-5-32-546",		"Guests",
113 	    0, NULL, NULL},
114 	{ SidTypeAlias, 1, "S-1-5-32-547",		"Power Users",
115 	    SMB_WKAFLG_LGRP_ENABLE, "Members can share directories", NULL },
116 	{ SidTypeAlias, 1, "S-1-5-32-548",		"Account Operators",
117 	    0, NULL, NULL},
118 	{ SidTypeAlias, 1, "S-1-5-32-549",		"Server Operators",
119 	    0, NULL, NULL},
120 	{ SidTypeAlias, 1, "S-1-5-32-550",		"Print Operators",
121 	    0, NULL, NULL},
122 	{ SidTypeAlias, 1, "S-1-5-32-551",		"Backup Operators",
123 	    SMB_WKAFLG_LGRP_ENABLE,
124 	    "Members can bypass file security to back up files", NULL },
125 	{ SidTypeAlias, 1, "S-1-5-32-552",		"Replicator",
126 	    0, NULL, NULL}
127 };
128 
129 #define	SMB_WKA_NUM	(sizeof (wka_tbl)/sizeof (wka_tbl[0]))
130 
131 /*
132  * smb_wka_lookup_sid
133  *
134  * Search the wka_tbl looking for a match on the specified SID. If the
135  * SID matches a builtin entry, the associated name is returned.
136  * Otherwise a null pointer is returned.
137  */
138 char *
139 smb_wka_lookup_sid(smb_sid_t *sid, uint16_t *sid_name_use)
140 {
141 	smb_wka_t *entry;
142 	int i;
143 
144 	for (i = 0; i < SMB_WKA_NUM; ++i) {
145 		entry = &wka_tbl[i];
146 
147 		if (smb_sid_cmp(sid, entry->wka_binsid)) {
148 			if (sid_name_use)
149 				*sid_name_use = entry->wka_type;
150 			return (entry->wka_name);
151 		}
152 	}
153 
154 	return (NULL);
155 }
156 
157 
158 /*
159  * smb_wka_lookup_name
160  *
161  * Search the wka_tbl looking for a match on the specified name. If the
162  * name matches a builtin entry, the associated SID (which is in
163  * malloc'd memory) is returned. Otherwise a null pointer is returned.
164  */
165 smb_sid_t *
166 smb_wka_lookup_name(char *name, uint16_t *sid_name_use)
167 {
168 	smb_wka_t *entry;
169 	int i;
170 
171 	for (i = 0; i < SMB_WKA_NUM; ++i) {
172 		entry = &wka_tbl[i];
173 
174 		if (!utf8_strcasecmp(name, entry->wka_name)) {
175 			if (sid_name_use)
176 				*sid_name_use = entry->wka_type;
177 			return (smb_sid_dup(entry->wka_binsid));
178 		}
179 	}
180 
181 	return (NULL);
182 }
183 
184 /*
185  * smb_wka_lookup
186  *
187  * Search the wka_tbl looking for a match on the specified name. If the
188  * name matches a builtin entry then pointer to that entry will be
189  * returned. Otherwise 0 is returned.
190  */
191 smb_wka_t *
192 smb_wka_lookup(char *name)
193 {
194 	smb_wka_t *entry;
195 	int i;
196 
197 	(void) rw_rdlock(&wk_rwlock);
198 	for (i = 0; i < SMB_WKA_NUM; ++i) {
199 		entry = &wka_tbl[i];
200 
201 		if (!utf8_strcasecmp(name, entry->wka_name)) {
202 			(void) rw_unlock(&wk_rwlock);
203 			return (entry);
204 		}
205 	}
206 
207 	(void) rw_unlock(&wk_rwlock);
208 	return (NULL);
209 }
210 
211 
212 /*
213  * smb_wka_is_wellknown
214  *
215  * Search the wka_tbl looking for a match on the specified name. If the
216  * name matches a builtin entry returns 1. Otherwise returns 0.
217  */
218 boolean_t
219 smb_wka_is_wellknown(char *name)
220 {
221 	int i;
222 
223 	for (i = 0; i < SMB_WKA_NUM; ++i) {
224 		if (utf8_strcasecmp(name, wka_tbl[i].wka_name) == 0)
225 			return (B_TRUE);
226 	}
227 
228 	return (B_FALSE);
229 }
230 
231 /*
232  * smb_wka_lookup_domain
233  *
234  * Return the builtin domain name for the specified alias or group name.
235  */
236 char *
237 smb_wka_lookup_domain(char *name)
238 {
239 	smb_wka_t *entry;
240 	int i;
241 
242 	for (i = 0; i < SMB_WKA_NUM; ++i) {
243 		entry = &wka_tbl[i];
244 
245 		if (!utf8_strcasecmp(name, entry->wka_name))
246 			return (domain[entry->wka_domidx]);
247 	}
248 
249 	return (NULL);
250 }
251 
252 /*
253  * smb_wka_init
254  *
255  * Generate binary SIDs from the string SIDs in the table
256  * and set the proper field.
257  *
258  * Caller MUST not store the binary SID pointer anywhere that
259  * could lead to freeing it.
260  *
261  * This function should only be called once.
262  */
263 int
264 smb_wka_init(void)
265 {
266 	smb_wka_t *entry;
267 	int i;
268 
269 	(void) rw_wrlock(&wk_rwlock);
270 	if (wk_init) {
271 		(void) rw_unlock(&wk_rwlock);
272 		return (1);
273 	}
274 
275 	for (i = 0; i < SMB_WKA_NUM; ++i) {
276 		entry = &wka_tbl[i];
277 		entry->wka_binsid = smb_sid_fromstr(entry->wka_sid);
278 		if (entry->wka_binsid == NULL) {
279 			(void) rw_unlock(&wk_rwlock);
280 			smb_wka_fini();
281 			return (0);
282 		}
283 	}
284 
285 	wk_init = 1;
286 	(void) rw_unlock(&wk_rwlock);
287 	return (1);
288 }
289 
290 void
291 smb_wka_fini(void)
292 {
293 	int i;
294 
295 	(void) rw_wrlock(&wk_rwlock);
296 	if (wk_init == 0) {
297 		(void) rw_unlock(&wk_rwlock);
298 		return;
299 	}
300 
301 	for (i = 0; i < SMB_WKA_NUM; ++i) {
302 		if (wka_tbl[i].wka_binsid) {
303 			free(wka_tbl[i].wka_binsid);
304 			wka_tbl[i].wka_binsid = NULL;
305 		}
306 	}
307 
308 	wk_init = 0;
309 	(void) rw_unlock(&wk_rwlock);
310 }
311