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 uint32_t 212 smb_wka_token_groups(boolean_t isadmin, smb_ids_t *gids) 213 { 214 static char *grps[] = 215 {"Authenticated Users", "NETWORK", "Administrators"}; 216 smb_id_t *id; 217 int gcnt, i; 218 int total_cnt; 219 220 gcnt = (isadmin) ? 3 : 2; 221 total_cnt = gids->i_cnt + gcnt; 222 223 gids->i_ids = realloc(gids->i_ids, total_cnt * sizeof (smb_id_t)); 224 if (gids->i_ids == NULL) 225 return (NT_STATUS_NO_MEMORY); 226 227 id = gids->i_ids + gids->i_cnt; 228 for (i = 0; i < gcnt; i++, gids->i_cnt++, id++) { 229 id->i_sid = smb_sid_dup(smb_wka_get_sid(grps[i])); 230 id->i_attrs = 0x7; 231 if (id->i_sid == NULL) 232 return (NT_STATUS_NO_MEMORY); 233 } 234 235 return (NT_STATUS_SUCCESS); 236 } 237 238 /* 239 * smb_wka_init 240 * 241 * Generate binary SIDs from the string SIDs in the table 242 * and set the proper field. 243 * 244 * Caller MUST not store the binary SID pointer anywhere that 245 * could lead to freeing it. 246 * 247 * This function should only be called once. 248 */ 249 int 250 smb_wka_init(void) 251 { 252 smb_wka_t *entry; 253 int i; 254 255 (void) rw_wrlock(&wk_rwlock); 256 if (wk_init) { 257 (void) rw_unlock(&wk_rwlock); 258 return (1); 259 } 260 261 for (i = 0; i < SMB_WKA_NUM; ++i) { 262 entry = &wka_tbl[i]; 263 entry->wka_binsid = smb_sid_fromstr(entry->wka_sid); 264 if (entry->wka_binsid == NULL) { 265 (void) rw_unlock(&wk_rwlock); 266 smb_wka_fini(); 267 return (0); 268 } 269 } 270 271 wk_init = 1; 272 (void) rw_unlock(&wk_rwlock); 273 return (1); 274 } 275 276 void 277 smb_wka_fini(void) 278 { 279 int i; 280 281 (void) rw_wrlock(&wk_rwlock); 282 if (wk_init == 0) { 283 (void) rw_unlock(&wk_rwlock); 284 return; 285 } 286 287 for (i = 0; i < SMB_WKA_NUM; ++i) { 288 if (wka_tbl[i].wka_binsid) { 289 free(wka_tbl[i].wka_binsid); 290 wka_tbl[i].wka_binsid = NULL; 291 } 292 } 293 294 wk_init = 0; 295 (void) rw_unlock(&wk_rwlock); 296 } 297