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