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 /* 212 * This function adds well known groups to groups in a user's 213 * access token (gids). 214 * 215 * "Network" SID is added for all users connecting over CIFS. 216 * 217 * "Authenticated Users" SID is added for all users except Guest 218 * and Anonymous. 219 * 220 * "Guests" SID is added for guest users and Administrators SID 221 * is added for admin users. 222 */ 223 uint32_t 224 smb_wka_token_groups(uint32_t flags, smb_ids_t *gids) 225 { 226 smb_id_t *id; 227 int total_cnt; 228 229 total_cnt = gids->i_cnt + 3; 230 231 gids->i_ids = realloc(gids->i_ids, total_cnt * sizeof (smb_id_t)); 232 if (gids->i_ids == NULL) 233 return (NT_STATUS_NO_MEMORY); 234 235 id = gids->i_ids + gids->i_cnt; 236 id->i_sid = smb_sid_dup(smb_wka_get_sid("Network")); 237 id->i_attrs = 0x7; 238 if (id->i_sid == NULL) 239 return (NT_STATUS_NO_MEMORY); 240 id++; 241 gids->i_cnt++; 242 243 if ((flags & SMB_ATF_ANON) == 0) { 244 if (flags & SMB_ATF_GUEST) 245 id->i_sid = smb_sid_dup(smb_wka_get_sid("Guests")); 246 else 247 id->i_sid = 248 smb_sid_dup(smb_wka_get_sid("Authenticated Users")); 249 id->i_attrs = 0x7; 250 if (id->i_sid == NULL) 251 return (NT_STATUS_NO_MEMORY); 252 id++; 253 gids->i_cnt++; 254 } 255 256 if (flags & SMB_ATF_ADMIN) { 257 id->i_sid = smb_sid_dup(smb_wka_get_sid("Administrators")); 258 id->i_attrs = 0x7; 259 if (id->i_sid == NULL) 260 return (NT_STATUS_NO_MEMORY); 261 gids->i_cnt++; 262 } 263 264 return (NT_STATUS_SUCCESS); 265 } 266 267 /* 268 * smb_wka_init 269 * 270 * Generate binary SIDs from the string SIDs in the table 271 * and set the proper field. 272 * 273 * Caller MUST not store the binary SID pointer anywhere that 274 * could lead to freeing it. 275 * 276 * This function should only be called once. 277 */ 278 int 279 smb_wka_init(void) 280 { 281 smb_wka_t *entry; 282 int i; 283 284 (void) rw_wrlock(&wk_rwlock); 285 if (wk_init) { 286 (void) rw_unlock(&wk_rwlock); 287 return (1); 288 } 289 290 for (i = 0; i < SMB_WKA_NUM; ++i) { 291 entry = &wka_tbl[i]; 292 entry->wka_binsid = smb_sid_fromstr(entry->wka_sid); 293 if (entry->wka_binsid == NULL) { 294 (void) rw_unlock(&wk_rwlock); 295 smb_wka_fini(); 296 return (0); 297 } 298 } 299 300 wk_init = 1; 301 (void) rw_unlock(&wk_rwlock); 302 return (1); 303 } 304 305 void 306 smb_wka_fini(void) 307 { 308 int i; 309 310 (void) rw_wrlock(&wk_rwlock); 311 if (wk_init == 0) { 312 (void) rw_unlock(&wk_rwlock); 313 return; 314 } 315 316 for (i = 0; i < SMB_WKA_NUM; ++i) { 317 if (wka_tbl[i].wka_binsid) { 318 free(wka_tbl[i].wka_binsid); 319 wka_tbl[i].wka_binsid = NULL; 320 } 321 } 322 323 wk_init = 0; 324 (void) rw_unlock(&wk_rwlock); 325 } 326