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