xref: /illumos-gate/usr/src/cmd/idmap/idmapd/wksids.c (revision 1fcced4c)
1*1fcced4cSJordan Brown /*
2*1fcced4cSJordan Brown  * CDDL HEADER START
3*1fcced4cSJordan Brown  *
4*1fcced4cSJordan Brown  * The contents of this file are subject to the terms of the
5*1fcced4cSJordan Brown  * Common Development and Distribution License (the "License").
6*1fcced4cSJordan Brown  * You may not use this file except in compliance with the License.
7*1fcced4cSJordan Brown  *
8*1fcced4cSJordan Brown  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9*1fcced4cSJordan Brown  * or http://www.opensolaris.org/os/licensing.
10*1fcced4cSJordan Brown  * See the License for the specific language governing permissions
11*1fcced4cSJordan Brown  * and limitations under the License.
12*1fcced4cSJordan Brown  *
13*1fcced4cSJordan Brown  * When distributing Covered Code, include this CDDL HEADER in each
14*1fcced4cSJordan Brown  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15*1fcced4cSJordan Brown  * If applicable, add the following below this CDDL HEADER, with the
16*1fcced4cSJordan Brown  * fields enclosed by brackets "[]" replaced with your own identifying
17*1fcced4cSJordan Brown  * information: Portions Copyright [yyyy] [name of copyright owner]
18*1fcced4cSJordan Brown  *
19*1fcced4cSJordan Brown  * CDDL HEADER END
20*1fcced4cSJordan Brown  */
21*1fcced4cSJordan Brown 
22*1fcced4cSJordan Brown /*
23*1fcced4cSJordan Brown  * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
24*1fcced4cSJordan Brown  * Use is subject to license terms.
25*1fcced4cSJordan Brown  */
26*1fcced4cSJordan Brown 
27*1fcced4cSJordan Brown /*
28*1fcced4cSJordan Brown  * Information about well-known (builtin) names, and functions to retrieve
29*1fcced4cSJordan Brown  * information about them.
30*1fcced4cSJordan Brown  */
31*1fcced4cSJordan Brown 
32*1fcced4cSJordan Brown #include <assert.h>
33*1fcced4cSJordan Brown #include <string.h>
34*1fcced4cSJordan Brown #include "idmapd.h"
35*1fcced4cSJordan Brown #include "miscutils.h"
36*1fcced4cSJordan Brown 
37*1fcced4cSJordan Brown /*
38*1fcced4cSJordan Brown  * Table for well-known SIDs.
39*1fcced4cSJordan Brown  *
40*1fcced4cSJordan Brown  * Background:
41*1fcced4cSJordan Brown  *
42*1fcced4cSJordan Brown  * Some of the well-known principals are stored under:
43*1fcced4cSJordan Brown  * cn=WellKnown Security Principals, cn=Configuration, dc=<forestRootDomain>
44*1fcced4cSJordan Brown  * They belong to objectClass "foreignSecurityPrincipal". They don't have
45*1fcced4cSJordan Brown  * "samAccountName" nor "userPrincipalName" attributes. Their names are
46*1fcced4cSJordan Brown  * available in "cn" and "name" attributes. Some of these principals have a
47*1fcced4cSJordan Brown  * second entry under CN=ForeignSecurityPrincipals,dc=<forestRootDomain> and
48*1fcced4cSJordan Brown  * these duplicate entries have the stringified SID in the "name" and "cn"
49*1fcced4cSJordan Brown  * attributes instead of the actual name.
50*1fcced4cSJordan Brown  *
51*1fcced4cSJordan Brown  * Those of the form S-1-5-32-X are Builtin groups and are stored in the
52*1fcced4cSJordan Brown  * cn=builtin container (except, Power Users which is not stored in AD)
53*1fcced4cSJordan Brown  *
54*1fcced4cSJordan Brown  * These principals are and will remain constant. Therefore doing AD lookups
55*1fcced4cSJordan Brown  * provides no benefit. Also, using hard-coded table (and thus avoiding AD
56*1fcced4cSJordan Brown  * lookup) improves performance and avoids additional complexity in the
57*1fcced4cSJordan Brown  * adutils.c code. Moreover these SIDs can be used when no Active Directory
58*1fcced4cSJordan Brown  * is available (such as the CIFS server's "workgroup" mode).
59*1fcced4cSJordan Brown  *
60*1fcced4cSJordan Brown  * Notes:
61*1fcced4cSJordan Brown  * 1. Currently we don't support localization of well-known SID names,
62*1fcced4cSJordan Brown  * unlike Windows.
63*1fcced4cSJordan Brown  *
64*1fcced4cSJordan Brown  * 2. Other well-known SIDs i.e. S-1-5-<domain>-<w-k RID> are not stored
65*1fcced4cSJordan Brown  * here. AD does have normal user/group objects for these objects and
66*1fcced4cSJordan Brown  * can be looked up using the existing AD lookup code.
67*1fcced4cSJordan Brown  *
68*1fcced4cSJordan Brown  * 3. See comments above lookup_wksids_sid2pid() for more information
69*1fcced4cSJordan Brown  * on how we lookup the wksids table.
70*1fcced4cSJordan Brown  *
71*1fcced4cSJordan Brown  * 4. If this table contains two entries for a particular Windows name,
72*1fcced4cSJordan Brown  * so as to offer both UID and GID mappings, the preferred mapping (the
73*1fcced4cSJordan Brown  * one that matches Windows usage) must be listed first.  That is the
74*1fcced4cSJordan Brown  * entry that will be used when the caller specifies IDMAP_POSIXID
75*1fcced4cSJordan Brown  * ("don't care") as the target.
76*1fcced4cSJordan Brown  *
77*1fcced4cSJordan Brown  * Entries here come from KB243330, MS-LSAT, and
78*1fcced4cSJordan Brown  * http://technet.microsoft.com/en-us/library/cc755854.aspx
79*1fcced4cSJordan Brown  * http://technet.microsoft.com/en-us/library/cc755925.aspx
80*1fcced4cSJordan Brown  * http://msdn.microsoft.com/en-us/library/cc980032(PROT.10).aspx
81*1fcced4cSJordan Brown  */
82*1fcced4cSJordan Brown static wksids_table_t wksids[] = {
83*1fcced4cSJordan Brown 	/* S-1-0	Null Authority */
84*1fcced4cSJordan Brown 	{"S-1-0", 0, "", "Nobody", 1, SENTINEL_PID, -1, 1},
85*1fcced4cSJordan Brown 
86*1fcced4cSJordan Brown 	/* S-1-1	World Authority */
87*1fcced4cSJordan Brown 	{"S-1-1", 0, "", "Everyone", 0, SENTINEL_PID, -1, -1},
88*1fcced4cSJordan Brown 
89*1fcced4cSJordan Brown 	/* S-1-2	Local Authority */
90*1fcced4cSJordan Brown 	{"S-1-2", 0, "", "Local", 0, SENTINEL_PID, -1, -1},
91*1fcced4cSJordan Brown 	{"S-1-2", 1, "", "Console Logon", 0, SENTINEL_PID, -1, -1},
92*1fcced4cSJordan Brown 
93*1fcced4cSJordan Brown 	/* S-1-3	Creator Authority */
94*1fcced4cSJordan Brown 	{"S-1-3", 0, "", "Creator Owner", 1, IDMAP_WK_CREATOR_OWNER_UID, 1, 0},
95*1fcced4cSJordan Brown 	{"S-1-3", 1, "", "Creator Group", 0, IDMAP_WK_CREATOR_GROUP_GID, 0, 0},
96*1fcced4cSJordan Brown 	{"S-1-3", 2, "", "Creator Owner Server", 1, SENTINEL_PID, -1, -1},
97*1fcced4cSJordan Brown 	{"S-1-3", 3, "", "Creator Group Server", 0, SENTINEL_PID, -1, 1},
98*1fcced4cSJordan Brown 	{"S-1-3", 4, "", "Owner Rights", 0, SENTINEL_PID, -1, -1},
99*1fcced4cSJordan Brown 
100*1fcced4cSJordan Brown 	/* S-1-4	Non-unique Authority */
101*1fcced4cSJordan Brown 
102*1fcced4cSJordan Brown 	/* S-1-5	NT Authority */
103*1fcced4cSJordan Brown 	{"S-1-5", 1, "", "Dialup", 0, SENTINEL_PID, -1, -1},
104*1fcced4cSJordan Brown 	{"S-1-5", 2, "", "Network", 0, SENTINEL_PID, -1, -1},
105*1fcced4cSJordan Brown 	{"S-1-5", 3, "", "Batch", 0, SENTINEL_PID, -1, -1},
106*1fcced4cSJordan Brown 	{"S-1-5", 4, "", "Interactive", 0, SENTINEL_PID, -1, -1},
107*1fcced4cSJordan Brown 	/* S-1-5-5-X-Y	Logon Session */
108*1fcced4cSJordan Brown 	{"S-1-5", 6, "", "Service", 0, SENTINEL_PID, -1, -1},
109*1fcced4cSJordan Brown 	{"S-1-5", 7, "", "Anonymous Logon", 0, GID_NOBODY, 0, 0},
110*1fcced4cSJordan Brown 	{"S-1-5", 7, "", "Anonymous Logon", 0, UID_NOBODY, 1, 0},
111*1fcced4cSJordan Brown 	{"S-1-5", 8, "", "Proxy", 0, SENTINEL_PID, -1, -1},
112*1fcced4cSJordan Brown 	{"S-1-5", 9, "", "Enterprise Domain Controllers", 0,
113*1fcced4cSJordan Brown 	    SENTINEL_PID, -1, -1},
114*1fcced4cSJordan Brown 	{"S-1-5", 10, "", "Self", 0, SENTINEL_PID, -1, -1},
115*1fcced4cSJordan Brown 	{"S-1-5", 11, "", "Authenticated Users", 0, SENTINEL_PID, -1, -1},
116*1fcced4cSJordan Brown 	{"S-1-5", 12, "", "Restricted", 0, SENTINEL_PID, -1, -1},
117*1fcced4cSJordan Brown 	{"S-1-5", 13, "", "Terminal Server Users", 0, SENTINEL_PID, -1, -1},
118*1fcced4cSJordan Brown 	{"S-1-5", 14, "", "Remote Interactive Logon", 0, SENTINEL_PID, -1, -1},
119*1fcced4cSJordan Brown 	{"S-1-5", 15, "", "This Organization", 0, SENTINEL_PID, -1, -1},
120*1fcced4cSJordan Brown 	{"S-1-5", 17, "", "IUSR", 0, SENTINEL_PID, -1, -1},
121*1fcced4cSJordan Brown 	{"S-1-5", 18, "", "Local System", 0, IDMAP_WK_LOCAL_SYSTEM_GID, 0, 0},
122*1fcced4cSJordan Brown 	{"S-1-5", 19, "", "Local Service", 0, SENTINEL_PID, -1, -1},
123*1fcced4cSJordan Brown 	{"S-1-5", 20, "", "Network Service", 0, SENTINEL_PID, -1, -1},
124*1fcced4cSJordan Brown 
125*1fcced4cSJordan Brown 	/* S-1-5-21-<domain>	Machine-local definitions */
126*1fcced4cSJordan Brown 	{NULL, 498, NULL, "Enterprise Read-only Domain Controllers", 0,
127*1fcced4cSJordan Brown 	    SENTINEL_PID, -1, -1},
128*1fcced4cSJordan Brown 	{NULL, 500, NULL, "Administrator", 1, SENTINEL_PID, 1, -1},
129*1fcced4cSJordan Brown 	{NULL, 501, NULL, "Guest", 1, SENTINEL_PID, 1, -1},
130*1fcced4cSJordan Brown 	{NULL, 502, NULL, "KRBTGT", 1, SENTINEL_PID, 1, -1},
131*1fcced4cSJordan Brown 	{NULL, 512, NULL, "Domain Admins", 0, SENTINEL_PID, -1, -1},
132*1fcced4cSJordan Brown 	{NULL, 513, NULL, "Domain Users", 0, SENTINEL_PID, -1, -1},
133*1fcced4cSJordan Brown 	{NULL, 514, NULL, "Domain Guests", 0, SENTINEL_PID, -1, -1},
134*1fcced4cSJordan Brown 	{NULL, 515, NULL, "Domain Computers", 0, SENTINEL_PID, -1, -1},
135*1fcced4cSJordan Brown 	{NULL, 516, NULL, "Domain Controllers", 0, SENTINEL_PID, -1, -1},
136*1fcced4cSJordan Brown 	{NULL, 517, NULL, "Cert Publishers", 0, SENTINEL_PID, -1, -1},
137*1fcced4cSJordan Brown 	{NULL, 518, NULL, "Schema Admins", 0, SENTINEL_PID, -1, -1},
138*1fcced4cSJordan Brown 	{NULL, 519, NULL, "Enterprise Admins", 0, SENTINEL_PID, -1, -1},
139*1fcced4cSJordan Brown 	{NULL, 520, NULL, "Global Policy Creator Owners", 0,
140*1fcced4cSJordan Brown 	    SENTINEL_PID, -1, -1},
141*1fcced4cSJordan Brown 	{NULL, 533, NULL, "RAS and IAS Servers", 0, SENTINEL_PID, -1, -1},
142*1fcced4cSJordan Brown 
143*1fcced4cSJordan Brown 	/* S-1-5-32	BUILTIN */
144*1fcced4cSJordan Brown 	{"S-1-5-32", 544, "BUILTIN", "Administrators", 0, SENTINEL_PID, -1, -1},
145*1fcced4cSJordan Brown 	{"S-1-5-32", 545, "BUILTIN", "Users", 0, SENTINEL_PID, -1, -1},
146*1fcced4cSJordan Brown 	{"S-1-5-32", 546, "BUILTIN", "Guests", 0, SENTINEL_PID, -1, -1},
147*1fcced4cSJordan Brown 	{"S-1-5-32", 547, "BUILTIN", "Power Users", 0, SENTINEL_PID, -1, -1},
148*1fcced4cSJordan Brown 	{"S-1-5-32", 548, "BUILTIN", "Account Operators", 0,
149*1fcced4cSJordan Brown 	    SENTINEL_PID, -1, -1},
150*1fcced4cSJordan Brown 	{"S-1-5-32", 549, "BUILTIN", "Server Operators", 0,
151*1fcced4cSJordan Brown 	    SENTINEL_PID, -1, -1},
152*1fcced4cSJordan Brown 	{"S-1-5-32", 550, "BUILTIN", "Print Operators", 0,
153*1fcced4cSJordan Brown 	    SENTINEL_PID, -1, -1},
154*1fcced4cSJordan Brown 	{"S-1-5-32", 551, "BUILTIN", "Backup Operators", 0,
155*1fcced4cSJordan Brown 	    SENTINEL_PID, -1, -1},
156*1fcced4cSJordan Brown 	{"S-1-5-32", 552, "BUILTIN", "Replicator", 0, SENTINEL_PID, -1, -1},
157*1fcced4cSJordan Brown 	{"S-1-5-32", 554, "BUILTIN", "Pre-Windows 2000 Compatible Access", 0,
158*1fcced4cSJordan Brown 	    SENTINEL_PID, -1, -1},
159*1fcced4cSJordan Brown 	{"S-1-5-32", 555, "BUILTIN", "Remote Desktop Users", 0,
160*1fcced4cSJordan Brown 	    SENTINEL_PID, -1, -1},
161*1fcced4cSJordan Brown 	{"S-1-5-32", 556, "BUILTIN", "Network Configuration Operators", 0,
162*1fcced4cSJordan Brown 	    SENTINEL_PID, -1, -1},
163*1fcced4cSJordan Brown 	{"S-1-5-32", 557, "BUILTIN", "Incoming Forest Trust Builders", 0,
164*1fcced4cSJordan Brown 	    SENTINEL_PID, -1, -1},
165*1fcced4cSJordan Brown 	{"S-1-5-32", 558, "BUILTIN", "Performance Monitor Users", 0,
166*1fcced4cSJordan Brown 	    SENTINEL_PID, -1, -1},
167*1fcced4cSJordan Brown 	{"S-1-5-32", 559, "BUILTIN", "Performance Log Users", 0,
168*1fcced4cSJordan Brown 	    SENTINEL_PID, -1, -1},
169*1fcced4cSJordan Brown 	{"S-1-5-32", 560, "BUILTIN", "Windows Authorization Access Group", 0,
170*1fcced4cSJordan Brown 	    SENTINEL_PID, -1, -1},
171*1fcced4cSJordan Brown 	{"S-1-5-32", 561, "BUILTIN", "Terminal Server License Servers", 0,
172*1fcced4cSJordan Brown 	    SENTINEL_PID, -1, -1},
173*1fcced4cSJordan Brown 	{"S-1-5-32", 562, "BUILTIN", "Distributed COM Users", 0,
174*1fcced4cSJordan Brown 	    SENTINEL_PID, -1, -1},
175*1fcced4cSJordan Brown 	{"S-1-5-32", 568, "BUILTIN", "IIS_IUSRS", 0, SENTINEL_PID, -1, -1},
176*1fcced4cSJordan Brown 	{"S-1-5-32", 569, "BUILTIN", "Cryptographic Operators", 0,
177*1fcced4cSJordan Brown 	    SENTINEL_PID, -1, -1},
178*1fcced4cSJordan Brown 	{"S-1-5-32", 573, "BUILTIN", "Event Log Readers", 0,
179*1fcced4cSJordan Brown 	    SENTINEL_PID, -1, -1},
180*1fcced4cSJordan Brown 	{"S-1-5-32", 574, "BUILTIN", "Certificate Service DCOM Access", 0,
181*1fcced4cSJordan Brown 	    SENTINEL_PID, -1, -1},
182*1fcced4cSJordan Brown 
183*1fcced4cSJordan Brown 	{"S-1-5", 33, "", "Write Restricted", 0, SENTINEL_PID, -1, -1},
184*1fcced4cSJordan Brown 
185*1fcced4cSJordan Brown 	/* S-1-5-64	NT Authority */
186*1fcced4cSJordan Brown 	{"S-1-5-64", 10, "", "NTLM Authentication", 0, SENTINEL_PID, -1, -1},
187*1fcced4cSJordan Brown 	{"S-1-5-64", 14, "", "SChannel Authentication", 0,
188*1fcced4cSJordan Brown 	    SENTINEL_PID, -1, -1},
189*1fcced4cSJordan Brown 	{"S-1-5-64", 21, "", "Digest Authentication", 0, SENTINEL_PID, -1, -1},
190*1fcced4cSJordan Brown 
191*1fcced4cSJordan Brown 	/* S-1-5-80-a-b-c-d NT Service */
192*1fcced4cSJordan Brown 
193*1fcced4cSJordan Brown 	{"S-1-5", 1000, "", "Other Organization", 0, SENTINEL_PID, -1, -1},
194*1fcced4cSJordan Brown 
195*1fcced4cSJordan Brown 	/* S-1-7 Internet$ */
196*1fcced4cSJordan Brown 
197*1fcced4cSJordan Brown 	/*
198*1fcced4cSJordan Brown 	 * S-1-16	Mandatory Label
199*1fcced4cSJordan Brown 	 * S-1-16-0	Untrusted Mandatory Level
200*1fcced4cSJordan Brown 	 * S-1-16-4096	Low Mandatory Level
201*1fcced4cSJordan Brown 	 * S-1-16-8192	Medium Mandatory Level
202*1fcced4cSJordan Brown 	 * S-1-16-8448	Medium Plus Mandatory Level
203*1fcced4cSJordan Brown 	 * S-1-16-12288	High Mandatory Level
204*1fcced4cSJordan Brown 	 * S-1-16-16384	System Mandatory Level
205*1fcced4cSJordan Brown 	 * S-1-16-20480	Protected Process Mandatory Level
206*1fcced4cSJordan Brown 	 */
207*1fcced4cSJordan Brown };
208*1fcced4cSJordan Brown 
209*1fcced4cSJordan Brown /*
210*1fcced4cSJordan Brown  * Find a wksid entry for the specified Windows name and domain, of the
211*1fcced4cSJordan Brown  * specified type.
212*1fcced4cSJordan Brown  *
213*1fcced4cSJordan Brown  * Ignore entries intended only for U2W use.
214*1fcced4cSJordan Brown  */
215*1fcced4cSJordan Brown const
216*1fcced4cSJordan Brown wksids_table_t *
217*1fcced4cSJordan Brown find_wksid_by_name(const char *name, const char *domain, int type)
218*1fcced4cSJordan Brown {
219*1fcced4cSJordan Brown 	int i;
220*1fcced4cSJordan Brown 
221*1fcced4cSJordan Brown 	RDLOCK_CONFIG();
222*1fcced4cSJordan Brown 	int len = strlen(_idmapdstate.hostname);
223*1fcced4cSJordan Brown 	char my_host_name[len + 1];
224*1fcced4cSJordan Brown 	(void) strcpy(my_host_name, _idmapdstate.hostname);
225*1fcced4cSJordan Brown 	UNLOCK_CONFIG();
226*1fcced4cSJordan Brown 
227*1fcced4cSJordan Brown 	for (i = 0; i < NELEM(wksids); i++) {
228*1fcced4cSJordan Brown 		/* Check to see if this entry yields the desired type */
229*1fcced4cSJordan Brown 		switch (type) {
230*1fcced4cSJordan Brown 		case IDMAP_UID:
231*1fcced4cSJordan Brown 			if (wksids[i].is_user == 0)
232*1fcced4cSJordan Brown 				continue;
233*1fcced4cSJordan Brown 			break;
234*1fcced4cSJordan Brown 		case IDMAP_GID:
235*1fcced4cSJordan Brown 			if (wksids[i].is_user == 1)
236*1fcced4cSJordan Brown 				continue;
237*1fcced4cSJordan Brown 			break;
238*1fcced4cSJordan Brown 		case IDMAP_POSIXID:
239*1fcced4cSJordan Brown 			break;
240*1fcced4cSJordan Brown 		default:
241*1fcced4cSJordan Brown 			assert(FALSE);
242*1fcced4cSJordan Brown 		}
243*1fcced4cSJordan Brown 
244*1fcced4cSJordan Brown 		if (strcasecmp(wksids[i].winname, name) != 0)
245*1fcced4cSJordan Brown 			continue;
246*1fcced4cSJordan Brown 
247*1fcced4cSJordan Brown 		if (!EMPTY_STRING(domain)) {
248*1fcced4cSJordan Brown 			const char *dom;
249*1fcced4cSJordan Brown 
250*1fcced4cSJordan Brown 			if (wksids[i].domain != NULL) {
251*1fcced4cSJordan Brown 				dom = wksids[i].domain;
252*1fcced4cSJordan Brown 			} else {
253*1fcced4cSJordan Brown 				dom = my_host_name;
254*1fcced4cSJordan Brown 			}
255*1fcced4cSJordan Brown 			if (strcasecmp(dom, domain) != 0)
256*1fcced4cSJordan Brown 				continue;
257*1fcced4cSJordan Brown 		}
258*1fcced4cSJordan Brown 
259*1fcced4cSJordan Brown 		/*
260*1fcced4cSJordan Brown 		 * We have a Windows name, so ignore entries that are only
261*1fcced4cSJordan Brown 		 * usable for mapping UNIX->Windows.  (Note:  the current
262*1fcced4cSJordan Brown 		 * table does not have any such entries.)
263*1fcced4cSJordan Brown 		 */
264*1fcced4cSJordan Brown 		if (wksids[i].direction == IDMAP_DIRECTION_U2W)
265*1fcced4cSJordan Brown 			continue;
266*1fcced4cSJordan Brown 
267*1fcced4cSJordan Brown 		return (&wksids[i]);
268*1fcced4cSJordan Brown 	}
269*1fcced4cSJordan Brown 
270*1fcced4cSJordan Brown 	return (NULL);
271*1fcced4cSJordan Brown }
272*1fcced4cSJordan Brown 
273*1fcced4cSJordan Brown /*
274*1fcced4cSJordan Brown  * Find a wksid entry for the specified SID, of the specified type.
275*1fcced4cSJordan Brown  *
276*1fcced4cSJordan Brown  * Ignore entries intended only for U2W use.
277*1fcced4cSJordan Brown  */
278*1fcced4cSJordan Brown const
279*1fcced4cSJordan Brown wksids_table_t *
280*1fcced4cSJordan Brown find_wksid_by_sid(const char *sid, int rid, int type)
281*1fcced4cSJordan Brown {
282*1fcced4cSJordan Brown 	int i;
283*1fcced4cSJordan Brown 
284*1fcced4cSJordan Brown 	RDLOCK_CONFIG();
285*1fcced4cSJordan Brown 	int len = strlen(_idmapdstate.cfg->pgcfg.machine_sid);
286*1fcced4cSJordan Brown 	char my_machine_sid[len + 1];
287*1fcced4cSJordan Brown 	(void) strcpy(my_machine_sid, _idmapdstate.cfg->pgcfg.machine_sid);
288*1fcced4cSJordan Brown 	UNLOCK_CONFIG();
289*1fcced4cSJordan Brown 
290*1fcced4cSJordan Brown 	for (i = 0; i < NELEM(wksids); i++) {
291*1fcced4cSJordan Brown 		int sidcmp;
292*1fcced4cSJordan Brown 
293*1fcced4cSJordan Brown 		/* Check to see if this entry yields the desired type */
294*1fcced4cSJordan Brown 		switch (type) {
295*1fcced4cSJordan Brown 		case IDMAP_UID:
296*1fcced4cSJordan Brown 			if (wksids[i].is_user == 0)
297*1fcced4cSJordan Brown 				continue;
298*1fcced4cSJordan Brown 			break;
299*1fcced4cSJordan Brown 		case IDMAP_GID:
300*1fcced4cSJordan Brown 			if (wksids[i].is_user == 1)
301*1fcced4cSJordan Brown 				continue;
302*1fcced4cSJordan Brown 			break;
303*1fcced4cSJordan Brown 		case IDMAP_POSIXID:
304*1fcced4cSJordan Brown 			break;
305*1fcced4cSJordan Brown 		default:
306*1fcced4cSJordan Brown 			assert(FALSE);
307*1fcced4cSJordan Brown 		}
308*1fcced4cSJordan Brown 
309*1fcced4cSJordan Brown 		if (wksids[i].sidprefix != NULL) {
310*1fcced4cSJordan Brown 			sidcmp = strcasecmp(wksids[i].sidprefix, sid);
311*1fcced4cSJordan Brown 		} else {
312*1fcced4cSJordan Brown 			sidcmp = strcasecmp(my_machine_sid, sid);
313*1fcced4cSJordan Brown 		}
314*1fcced4cSJordan Brown 
315*1fcced4cSJordan Brown 		if (sidcmp != 0)
316*1fcced4cSJordan Brown 			continue;
317*1fcced4cSJordan Brown 		if (wksids[i].rid != rid)
318*1fcced4cSJordan Brown 			continue;
319*1fcced4cSJordan Brown 
320*1fcced4cSJordan Brown 		/*
321*1fcced4cSJordan Brown 		 * We have a SID, so ignore entries that are only usable
322*1fcced4cSJordan Brown 		 * for mapping UNIX->Windows.  (Note:  the current table
323*1fcced4cSJordan Brown 		 * does not have any such entries.)
324*1fcced4cSJordan Brown 		 */
325*1fcced4cSJordan Brown 		if (wksids[i].direction == IDMAP_DIRECTION_U2W)
326*1fcced4cSJordan Brown 			continue;
327*1fcced4cSJordan Brown 
328*1fcced4cSJordan Brown 		return (&wksids[i]);
329*1fcced4cSJordan Brown 	}
330*1fcced4cSJordan Brown 
331*1fcced4cSJordan Brown 	return (NULL);
332*1fcced4cSJordan Brown }
333*1fcced4cSJordan Brown 
334*1fcced4cSJordan Brown /*
335*1fcced4cSJordan Brown  * Find a wksid entry for the specified pid, of the specified type.
336*1fcced4cSJordan Brown  * Ignore entries that do not specify U2W mappings.
337*1fcced4cSJordan Brown  */
338*1fcced4cSJordan Brown const
339*1fcced4cSJordan Brown wksids_table_t *
340*1fcced4cSJordan Brown find_wksid_by_pid(uid_t pid, int is_user)
341*1fcced4cSJordan Brown {
342*1fcced4cSJordan Brown 	int i;
343*1fcced4cSJordan Brown 
344*1fcced4cSJordan Brown 	if (pid == SENTINEL_PID)
345*1fcced4cSJordan Brown 		return (NULL);
346*1fcced4cSJordan Brown 
347*1fcced4cSJordan Brown 	for (i = 0; i < NELEM(wksids); i++) {
348*1fcced4cSJordan Brown 		if (wksids[i].pid == pid &&
349*1fcced4cSJordan Brown 		    wksids[i].is_user == is_user &&
350*1fcced4cSJordan Brown 		    (wksids[i].direction == IDMAP_DIRECTION_BI ||
351*1fcced4cSJordan Brown 		    wksids[i].direction == IDMAP_DIRECTION_U2W)) {
352*1fcced4cSJordan Brown 			return (&wksids[i]);
353*1fcced4cSJordan Brown 		}
354*1fcced4cSJordan Brown 	}
355*1fcced4cSJordan Brown 	return (NULL);
356*1fcced4cSJordan Brown }
357*1fcced4cSJordan Brown 
358*1fcced4cSJordan Brown /*
359*1fcced4cSJordan Brown  * It is probably a bug that both this and find_wksid_by_sid exist,
360*1fcced4cSJordan Brown  * but for now the distinction is primarily that one takes {machinesid,rid}
361*1fcced4cSJordan Brown  * and the other takes a full SID.
362*1fcced4cSJordan Brown  */
363*1fcced4cSJordan Brown const
364*1fcced4cSJordan Brown wksids_table_t *
365*1fcced4cSJordan Brown find_wk_by_sid(char *sid)
366*1fcced4cSJordan Brown {
367*1fcced4cSJordan Brown 	int i;
368*1fcced4cSJordan Brown 
369*1fcced4cSJordan Brown 	RDLOCK_CONFIG();
370*1fcced4cSJordan Brown 	int len = strlen(_idmapdstate.cfg->pgcfg.machine_sid);
371*1fcced4cSJordan Brown 	char my_machine_sid[len + 1];
372*1fcced4cSJordan Brown 	(void) strcpy(my_machine_sid, _idmapdstate.cfg->pgcfg.machine_sid);
373*1fcced4cSJordan Brown 	UNLOCK_CONFIG();
374*1fcced4cSJordan Brown 
375*1fcced4cSJordan Brown 	for (i = 0; i < NELEM(wksids); i++) {
376*1fcced4cSJordan Brown 		int len;
377*1fcced4cSJordan Brown 		const char *prefix;
378*1fcced4cSJordan Brown 		char *p;
379*1fcced4cSJordan Brown 		unsigned long rid;
380*1fcced4cSJordan Brown 
381*1fcced4cSJordan Brown 		if (wksids[i].sidprefix == NULL)
382*1fcced4cSJordan Brown 			prefix = my_machine_sid;
383*1fcced4cSJordan Brown 		else
384*1fcced4cSJordan Brown 			prefix = wksids[i].sidprefix;
385*1fcced4cSJordan Brown 
386*1fcced4cSJordan Brown 		len = strlen(prefix);
387*1fcced4cSJordan Brown 
388*1fcced4cSJordan Brown 		/*
389*1fcced4cSJordan Brown 		 * Check to see whether the SID we're looking for starts
390*1fcced4cSJordan Brown 		 * with this prefix, then a -, then a single RID, and it's
391*1fcced4cSJordan Brown 		 * the right RID.
392*1fcced4cSJordan Brown 		 */
393*1fcced4cSJordan Brown 		if (strncasecmp(sid, prefix, len) != 0)
394*1fcced4cSJordan Brown 			continue;
395*1fcced4cSJordan Brown 		if (sid[len] != '-')
396*1fcced4cSJordan Brown 			continue;
397*1fcced4cSJordan Brown 		rid = strtoul(sid + len + 1, &p, 10);
398*1fcced4cSJordan Brown 		if (*p != '\0')
399*1fcced4cSJordan Brown 			continue;
400*1fcced4cSJordan Brown 
401*1fcced4cSJordan Brown 		if (rid != wksids[i].rid)
402*1fcced4cSJordan Brown 			continue;
403*1fcced4cSJordan Brown 
404*1fcced4cSJordan Brown 		return (&wksids[i]);
405*1fcced4cSJordan Brown 	}
406*1fcced4cSJordan Brown 	return (NULL);
407*1fcced4cSJordan Brown }
408