xref: /illumos-gate/usr/src/lib/smbsrv/libsmb/common/smb_wksids.c (revision c9eab9d4e096bb9b983e9b007577edfa73c32eff)
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 2009 Sun Microsystems, Inc.  All rights reserved.
23  * Use is subject to license terms.
24  */
25 
26 #include <stdlib.h>
27 #include <string.h>
28 #include <synch.h>
29 
30 #include <smbsrv/libsmb.h>
31 
32 static int wk_init = 0;
33 static rwlock_t wk_rwlock;
34 
35 static char *wka_nbdomain[] = {
36 	"",
37 	"NT Pseudo Domain",
38 	"NT Authority",
39 	"Builtin",
40 	"Internet$",
41 };
42 
43 /*
44  * Predefined well known accounts table
45  */
46 static smb_wka_t wka_tbl[] = {
47 	{ 0, "S-1-0-0",		"Null",
48 		SidTypeWellKnownGroup, 0, NULL, NULL },
49 	{ 0, "S-1-1-0",		"Everyone",
50 		SidTypeWellKnownGroup, 0, NULL, NULL },
51 	{ 0, "S-1-2-0",		"Local",
52 		SidTypeWellKnownGroup, 0, NULL, NULL },
53 	{ 0, "S-1-3-0",		"Creator Owner",
54 		SidTypeWellKnownGroup, 0, NULL, NULL },
55 	{ 0, "S-1-3-1",		"Creator Group",
56 		SidTypeWellKnownGroup, 0, NULL, NULL },
57 	{ 0, "S-1-3-2",		"Creator Owner Server",
58 		SidTypeWellKnownGroup, 0, NULL, NULL },
59 	{ 0, "S-1-3-3",		"Creator Group Server",
60 		SidTypeWellKnownGroup, 0, NULL, NULL },
61 	{ 0, "S-1-3-4",		"Owner Rights",
62 		SidTypeWellKnownGroup, 0, NULL, NULL },
63 	{ 1, "S-1-5",		"NT Pseudo Domain",
64 		SidTypeDomain, 0, NULL, NULL },
65 	{ 2, "S-1-5-1",		"Dialup",
66 		SidTypeWellKnownGroup, 0, NULL, NULL },
67 	{ 2, "S-1-5-2",		"Network",
68 		SidTypeWellKnownGroup, 0, NULL, NULL },
69 	{ 2, "S-1-5-3",		"Batch",
70 		SidTypeWellKnownGroup, 0, NULL, NULL },
71 	{ 2, "S-1-5-4",		"Interactive",
72 		SidTypeWellKnownGroup, 0, NULL, NULL },
73 	{ 2, "S-1-5-6",		"Service",
74 		SidTypeWellKnownGroup, 0, NULL, NULL },
75 	{ 2, "S-1-5-7",		"Anonymous",
76 		SidTypeWellKnownGroup, 0, NULL, NULL },
77 	{ 2, "S-1-5-8",		"Proxy",
78 		SidTypeWellKnownGroup, 0, NULL, NULL },
79 	{ 2, "S-1-5-9",		"Enterprise Domain Controllers",
80 		SidTypeWellKnownGroup, 0, NULL, NULL },
81 	{ 2, "S-1-5-10",	"Self",
82 		SidTypeWellKnownGroup, 0, NULL, NULL },
83 	{ 2, "S-1-5-11",	"Authenticated Users",
84 		SidTypeWellKnownGroup, 0, NULL, NULL },
85 	{ 2, "S-1-5-12",	"Restricted",
86 		SidTypeWellKnownGroup, 0, NULL, NULL },
87 	{ 2, "S-1-5-13",	"Terminal Server User",
88 		SidTypeWellKnownGroup, 0, NULL, NULL },
89 	{ 2, "S-1-5-14",	"Remote Interactive Logon",
90 		SidTypeWellKnownGroup, 0, NULL, NULL },
91 	{ 2, "S-1-5-15",	"This Organization",
92 		SidTypeWellKnownGroup, 0, NULL, NULL },
93 	{ 2, "S-1-5-18",	"System",
94 		SidTypeWellKnownGroup, 0, NULL, NULL },
95 	{ 2, "S-1-5-19",	"Local Service",
96 		SidTypeWellKnownGroup, 0, NULL, NULL },
97 	{ 2, "S-1-5-20",	"Network Service",
98 		SidTypeWellKnownGroup, 0, NULL, NULL },
99 	{ 2, "S-1-5-33",	"Write Restricted",
100 		SidTypeWellKnownGroup, 0, NULL, NULL },
101 	{ 2, "S-1-5-1000",	"Other Organization",
102 		SidTypeWellKnownGroup, 0, NULL, NULL },
103 	{ 3, "S-1-5-32",	"Builtin",
104 		SidTypeDomain, 0, NULL, NULL },
105 	{ 4, "S-1-7",		"Internet$",
106 		SidTypeDomain, 0, NULL, NULL },
107 
108 	{ 3, "S-1-5-32-544",	"Administrators", SidTypeAlias,
109 	    SMB_WKAFLG_LGRP_ENABLE,
110 	    "Members can fully administer the computer/domain", NULL },
111 	{ 3, "S-1-5-32-545",	"Users",
112 		SidTypeAlias, 0, NULL, NULL },
113 	{ 3, "S-1-5-32-546",	"Guests",
114 		SidTypeAlias, 0, NULL, NULL },
115 	{ 3, "S-1-5-32-547",	"Power Users", SidTypeAlias,
116 	    SMB_WKAFLG_LGRP_ENABLE, "Members can share directories", NULL },
117 	{ 3, "S-1-5-32-548",	"Account Operators",
118 		SidTypeAlias, 0, NULL, NULL },
119 	{ 3, "S-1-5-32-549",	"Server Operators",
120 		SidTypeAlias, 0, NULL, NULL },
121 	{ 3, "S-1-5-32-550",	"Print Operators",
122 		SidTypeAlias, 0, NULL, NULL },
123 	{ 3, "S-1-5-32-551",	"Backup Operators", SidTypeAlias,
124 	    SMB_WKAFLG_LGRP_ENABLE,
125 	    "Members can bypass file security to back up files", NULL },
126 	{ 3, "S-1-5-32-552",	"Replicator",
127 		SidTypeAlias, 0, NULL, NULL }
128 };
129 
130 #define	SMB_WKA_NUM	(sizeof (wka_tbl)/sizeof (wka_tbl[0]))
131 
132 /*
133  * Looks up well known accounts table for the given SID.
134  * Upon success returns a pointer to the account entry in
135  * the table, otherwise returns NULL.
136  */
137 smb_wka_t *
138 smb_wka_lookup_sid(smb_sid_t *sid)
139 {
140 	smb_wka_t *entry;
141 	int i;
142 
143 	(void) rw_rdlock(&wk_rwlock);
144 
145 	for (i = 0; i < SMB_WKA_NUM; ++i) {
146 		entry = &wka_tbl[i];
147 		if (smb_sid_cmp(sid, entry->wka_binsid)) {
148 			(void) rw_unlock(&wk_rwlock);
149 			return (entry);
150 		}
151 	}
152 
153 	(void) rw_unlock(&wk_rwlock);
154 	return (NULL);
155 }
156 
157 
158 /*
159  * Looks up well known accounts table for the given name.
160  * Upon success returns a pointer to the binary SID of the
161  * entry, otherwise returns NULL.
162  */
163 smb_sid_t *
164 smb_wka_get_sid(char *name)
165 {
166 	smb_wka_t *entry;
167 	smb_sid_t *sid = NULL;
168 
169 	if ((entry = smb_wka_lookup_name(name)) != NULL)
170 		sid = entry->wka_binsid;
171 
172 	return (sid);
173 }
174 
175 /*
176  * Looks up well known accounts table for the given name.
177  * Upon success returns a pointer to the account entry in
178  * the table, otherwise returns NULL.
179  */
180 smb_wka_t *
181 smb_wka_lookup_name(char *name)
182 {
183 	smb_wka_t *entry;
184 	int i;
185 
186 	(void) rw_rdlock(&wk_rwlock);
187 	for (i = 0; i < SMB_WKA_NUM; ++i) {
188 		entry = &wka_tbl[i];
189 		if (!utf8_strcasecmp(name, entry->wka_name)) {
190 			(void) rw_unlock(&wk_rwlock);
191 			return (entry);
192 		}
193 	}
194 
195 	(void) rw_unlock(&wk_rwlock);
196 	return (NULL);
197 }
198 
199 /*
200  * Returns the Netbios domain name for the given index
201  */
202 char *
203 smb_wka_get_domain(int idx)
204 {
205 	if ((idx >= 0) && (idx < SMB_WKA_NUM))
206 		return (wka_nbdomain[idx]);
207 
208 	return (NULL);
209 }
210 
211 uint32_t
212 smb_wka_token_groups(boolean_t isadmin, smb_ids_t *gids)
213 {
214 	static char *grps[] =
215 		{"Authenticated Users", "NETWORK", "Administrators"};
216 	smb_id_t *id;
217 	int gcnt, i;
218 	int total_cnt;
219 
220 	gcnt = (isadmin) ? 3 : 2;
221 	total_cnt = gids->i_cnt + gcnt;
222 
223 	gids->i_ids = realloc(gids->i_ids, total_cnt * sizeof (smb_id_t));
224 	if (gids->i_ids == NULL)
225 		return (NT_STATUS_NO_MEMORY);
226 
227 	id = gids->i_ids + gids->i_cnt;
228 	for (i = 0; i < gcnt; i++, gids->i_cnt++, id++) {
229 		id->i_sid = smb_sid_dup(smb_wka_get_sid(grps[i]));
230 		id->i_attrs = 0x7;
231 		if (id->i_sid == NULL)
232 			return (NT_STATUS_NO_MEMORY);
233 	}
234 
235 	return (NT_STATUS_SUCCESS);
236 }
237 
238 /*
239  * smb_wka_init
240  *
241  * Generate binary SIDs from the string SIDs in the table
242  * and set the proper field.
243  *
244  * Caller MUST not store the binary SID pointer anywhere that
245  * could lead to freeing it.
246  *
247  * This function should only be called once.
248  */
249 int
250 smb_wka_init(void)
251 {
252 	smb_wka_t *entry;
253 	int i;
254 
255 	(void) rw_wrlock(&wk_rwlock);
256 	if (wk_init) {
257 		(void) rw_unlock(&wk_rwlock);
258 		return (1);
259 	}
260 
261 	for (i = 0; i < SMB_WKA_NUM; ++i) {
262 		entry = &wka_tbl[i];
263 		entry->wka_binsid = smb_sid_fromstr(entry->wka_sid);
264 		if (entry->wka_binsid == NULL) {
265 			(void) rw_unlock(&wk_rwlock);
266 			smb_wka_fini();
267 			return (0);
268 		}
269 	}
270 
271 	wk_init = 1;
272 	(void) rw_unlock(&wk_rwlock);
273 	return (1);
274 }
275 
276 void
277 smb_wka_fini(void)
278 {
279 	int i;
280 
281 	(void) rw_wrlock(&wk_rwlock);
282 	if (wk_init == 0) {
283 		(void) rw_unlock(&wk_rwlock);
284 		return;
285 	}
286 
287 	for (i = 0; i < SMB_WKA_NUM; ++i) {
288 		if (wka_tbl[i].wka_binsid) {
289 			free(wka_tbl[i].wka_binsid);
290 			wka_tbl[i].wka_binsid = NULL;
291 		}
292 	}
293 
294 	wk_init = 0;
295 	(void) rw_unlock(&wk_rwlock);
296 }
297