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 * smb_wka_lookup_sid 134 * 135 * Search the wka_tbl looking for a match on the specified SID. If the 136 * SID matches a builtin entry, the associated name is returned. 137 * Otherwise a null pointer is returned. 138 */ 139 char * 140 smb_wka_lookup_sid(smb_sid_t *sid, uint16_t *sid_name_use) 141 { 142 smb_wka_t *entry; 143 int i; 144 145 for (i = 0; i < SMB_WKA_NUM; ++i) { 146 entry = &wka_tbl[i]; 147 148 if (smb_sid_cmp(sid, entry->wka_binsid)) { 149 if (sid_name_use) 150 *sid_name_use = entry->wka_type; 151 return (entry->wka_name); 152 } 153 } 154 155 return (NULL); 156 } 157 158 159 /* 160 * smb_wka_lookup_name 161 * 162 * Search the wka_tbl looking for a match on the specified name. If the 163 * name matches a builtin entry, the associated SID (which is in 164 * malloc'd memory) is returned. Otherwise a null pointer is returned. 165 */ 166 smb_sid_t * 167 smb_wka_lookup_name(char *name, uint16_t *sid_name_use) 168 { 169 smb_wka_t *entry; 170 int i; 171 172 for (i = 0; i < SMB_WKA_NUM; ++i) { 173 entry = &wka_tbl[i]; 174 175 if (!utf8_strcasecmp(name, entry->wka_name)) { 176 if (sid_name_use) 177 *sid_name_use = entry->wka_type; 178 return (smb_sid_dup(entry->wka_binsid)); 179 } 180 } 181 182 return (NULL); 183 } 184 185 /* 186 * smb_wka_lookup 187 * 188 * Search the wka_tbl looking for a match on the specified name. If the 189 * name matches a builtin entry then pointer to that entry will be 190 * returned. Otherwise 0 is returned. 191 */ 192 smb_wka_t * 193 smb_wka_lookup(char *name) 194 { 195 smb_wka_t *entry; 196 int i; 197 198 (void) rw_rdlock(&wk_rwlock); 199 for (i = 0; i < SMB_WKA_NUM; ++i) { 200 entry = &wka_tbl[i]; 201 202 if (!utf8_strcasecmp(name, entry->wka_name)) { 203 (void) rw_unlock(&wk_rwlock); 204 return (entry); 205 } 206 } 207 208 (void) rw_unlock(&wk_rwlock); 209 return (NULL); 210 } 211 212 213 /* 214 * smb_wka_is_wellknown 215 * 216 * Search the wka_tbl looking for a match on the specified name. If the 217 * name matches a builtin entry returns 1. Otherwise returns 0. 218 */ 219 boolean_t 220 smb_wka_is_wellknown(char *name) 221 { 222 int i; 223 224 for (i = 0; i < SMB_WKA_NUM; ++i) { 225 if (utf8_strcasecmp(name, wka_tbl[i].wka_name) == 0) 226 return (B_TRUE); 227 } 228 229 return (B_FALSE); 230 } 231 232 /* 233 * smb_wka_lookup_domain 234 * 235 * Return the builtin domain name for the specified alias or group name. 236 */ 237 char * 238 smb_wka_lookup_domain(char *name) 239 { 240 smb_wka_t *entry; 241 int i; 242 243 for (i = 0; i < SMB_WKA_NUM; ++i) { 244 entry = &wka_tbl[i]; 245 246 if (!utf8_strcasecmp(name, entry->wka_name)) 247 return (wka_nbdomain[entry->wka_domidx]); 248 } 249 250 return (NULL); 251 } 252 253 /* 254 * Returns the Netbios domain name for the given index 255 */ 256 char * 257 smb_wka_get_domain(int idx) 258 { 259 if ((idx >= 0) && (idx < SMB_WKA_NUM)) 260 return (wka_nbdomain[idx]); 261 262 return (NULL); 263 } 264 265 /* 266 * smb_wka_init 267 * 268 * Generate binary SIDs from the string SIDs in the table 269 * and set the proper field. 270 * 271 * Caller MUST not store the binary SID pointer anywhere that 272 * could lead to freeing it. 273 * 274 * This function should only be called once. 275 */ 276 int 277 smb_wka_init(void) 278 { 279 smb_wka_t *entry; 280 int i; 281 282 (void) rw_wrlock(&wk_rwlock); 283 if (wk_init) { 284 (void) rw_unlock(&wk_rwlock); 285 return (1); 286 } 287 288 for (i = 0; i < SMB_WKA_NUM; ++i) { 289 entry = &wka_tbl[i]; 290 entry->wka_binsid = smb_sid_fromstr(entry->wka_sid); 291 if (entry->wka_binsid == NULL) { 292 (void) rw_unlock(&wk_rwlock); 293 smb_wka_fini(); 294 return (0); 295 } 296 } 297 298 wk_init = 1; 299 (void) rw_unlock(&wk_rwlock); 300 return (1); 301 } 302 303 void 304 smb_wka_fini(void) 305 { 306 int i; 307 308 (void) rw_wrlock(&wk_rwlock); 309 if (wk_init == 0) { 310 (void) rw_unlock(&wk_rwlock); 311 return; 312 } 313 314 for (i = 0; i < SMB_WKA_NUM; ++i) { 315 if (wka_tbl[i].wka_binsid) { 316 free(wka_tbl[i].wka_binsid); 317 wka_tbl[i].wka_binsid = NULL; 318 } 319 } 320 321 wk_init = 0; 322 (void) rw_unlock(&wk_rwlock); 323 } 324