Changeset 745 for trunk/server/source3/auth
- Timestamp:
- Nov 27, 2012, 4:43:17 PM (13 years ago)
- Location:
- trunk/server
- Files:
-
- 17 edited
- 8 copied
Legend:
- Unmodified
- Added
- Removed
-
trunk/server
- Property svn:mergeinfo changed
/vendor/current merged: 581,587,591,594,597,600,615,618,740
- Property svn:mergeinfo changed
-
trunk/server/source3/auth/auth.c
r414 r745 19 19 20 20 #include "includes.h" 21 #include "auth.h" 22 #include "smbd/globals.h" 21 23 22 24 #undef DBGC_CLASS … … 25 27 static_decl_auth; 26 28 27 static struct auth_init_function_entry * backends = NULL;29 static struct auth_init_function_entry *auth_backends = NULL; 28 30 29 31 static struct auth_init_function_entry *auth_find_backend_entry(const char *name); … … 31 33 NTSTATUS smb_register_auth(int version, const char *name, auth_init_function init) 32 34 { 33 struct auth_init_function_entry *entry = backends;35 struct auth_init_function_entry *entry = auth_backends; 34 36 35 37 if (version != AUTH_INTERFACE_VERSION) { … … 55 57 entry->init = init; 56 58 57 DLIST_ADD( backends, entry);59 DLIST_ADD(auth_backends, entry); 58 60 DEBUG(5,("Successfully added auth method '%s'\n", name)); 59 61 return NT_STATUS_OK; … … 62 64 static struct auth_init_function_entry *auth_find_backend_entry(const char *name) 63 65 { 64 struct auth_init_function_entry *entry = backends;66 struct auth_init_function_entry *entry = auth_backends; 65 67 66 68 while(entry) { … … 77 79 ****************************************************************************/ 78 80 79 static voidget_ntlm_challenge(struct auth_context *auth_context,81 static NTSTATUS get_ntlm_challenge(struct auth_context *auth_context, 80 82 uint8_t chal[8]) 81 83 { … … 88 90 auth_context->challenge_set_by)); 89 91 memcpy(chal, auth_context->challenge.data, 8); 90 return ;92 return NT_STATUS_OK; 91 93 } 92 94 … … 107 109 108 110 challenge = auth_method->get_chal(auth_context, &auth_method->private_data, 109 auth_context->mem_ctx);111 auth_context); 110 112 if (!challenge.length) { 111 113 DEBUG(3, ("auth_get_challenge: getting challenge from authentication method %s FAILED.\n", … … 123 125 124 126 generate_random_buffer(tmp, sizeof(tmp)); 125 auth_context->challenge = data_blob_talloc(auth_context ->mem_ctx,127 auth_context->challenge = data_blob_talloc(auth_context, 126 128 tmp, sizeof(tmp)); 127 129 … … 139 141 140 142 memcpy(chal, auth_context->challenge.data, 8); 143 return NT_STATUS_OK; 141 144 } 142 145 … … 214 217 215 218 DEBUG(3, ("check_ntlm_password: Checking password for unmapped user [%s]\\[%s]@[%s] with the new password interface\n", 216 user_info->client _domain, user_info->smb_name, user_info->wksta_name));219 user_info->client.domain_name, user_info->client.account_name, user_info->workstation_name)); 217 220 218 221 DEBUG(3, ("check_ntlm_password: mapped user is: [%s]\\[%s]@[%s]\n", 219 user_info-> domain, user_info->internal_username, user_info->wksta_name));222 user_info->mapped.domain_name, user_info->mapped.account_name, user_info->workstation_name)); 220 223 221 224 if (auth_context->challenge.length != 8) { … … 233 236 #ifdef DEBUG_PASSWORD 234 237 DEBUG(100, ("user_info has passwords of length %d and %d\n", 235 (int)user_info-> lm_resp.length, (int)user_info->nt_resp.length));238 (int)user_info->password.response.lanman.length, (int)user_info->password.response.nt.length)); 236 239 DEBUG(100, ("lm:\n")); 237 dump_data(100, user_info-> lm_resp.data, user_info->lm_resp.length);240 dump_data(100, user_info->password.response.lanman.data, user_info->password.response.lanman.length); 238 241 DEBUG(100, ("nt:\n")); 239 dump_data(100, user_info-> nt_resp.data, user_info->nt_resp.length);242 dump_data(100, user_info->password.response.nt.data, user_info->password.response.nt.length); 240 243 #endif 241 244 242 245 /* This needs to be sorted: If it doesn't match, what should we do? */ 243 if (!check_domain_match(user_info->smb_name, user_info->domain))246 if (!check_domain_match(user_info->client.account_name, user_info->mapped.domain_name)) 244 247 return NT_STATUS_LOGON_FAILURE; 245 248 … … 247 250 NTSTATUS result; 248 251 249 mem_ctx = talloc_init("%s authentication for user %s\\%s", auth_method->name, 250 user_info->domain, user_info->smb_name);252 mem_ctx = talloc_init("%s authentication for user %s\\%s", auth_method->name, 253 user_info->mapped.domain_name, user_info->client.account_name); 251 254 252 255 result = auth_method->auth(auth_context, auth_method->private_data, mem_ctx, user_info, server_info); … … 263 266 if (NT_STATUS_IS_OK(nt_status)) { 264 267 DEBUG(3, ("check_ntlm_password: %s authentication for user [%s] succeeded\n", 265 auth_method->name, user_info-> smb_name));268 auth_method->name, user_info->client.account_name)); 266 269 } else { 267 270 DEBUG(5, ("check_ntlm_password: %s authentication for user [%s] FAILED with error %s\n", 268 auth_method->name, user_info-> smb_name, nt_errstr(nt_status)));271 auth_method->name, user_info->client.account_name, nt_errstr(nt_status))); 269 272 } 270 273 … … 284 287 /* We might not be root if we are an RPC call */ 285 288 become_root(); 286 nt_status = smb_pam_accountcheck(unix_username); 289 nt_status = smb_pam_accountcheck( 290 unix_username, 291 smbd_server_conn->client_id.name); 287 292 unbecome_root(); 288 293 … … 298 303 if (NT_STATUS_IS_OK(nt_status)) { 299 304 DEBUG((*server_info)->guest ? 5 : 2, 300 ("check_ntlm_password: %sauthentication for user [%s] -> [%s] -> [%s] succeeded\n", 301 (*server_info)->guest ? "guest " : "", 302 user_info-> smb_name,303 user_info-> internal_username,305 ("check_ntlm_password: %sauthentication for user [%s] -> [%s] -> [%s] succeeded\n", 306 (*server_info)->guest ? "guest " : "", 307 user_info->client.account_name, 308 user_info->mapped.account_name, 304 309 unix_username)); 305 310 } … … 310 315 /* failed authentication; check for guest lapping */ 311 316 312 DEBUG(2, ("check_ntlm_password: Authentication for user [%s] -> [%s] FAILED with error %s\n", 313 user_info-> smb_name, user_info->internal_username,317 DEBUG(2, ("check_ntlm_password: Authentication for user [%s] -> [%s] FAILED with error %s\n", 318 user_info->client.account_name, user_info->mapped.account_name, 314 319 nt_errstr(nt_status))); 315 ZERO_STRUCTP(server_info); 320 ZERO_STRUCTP(server_info); 316 321 317 322 return nt_status; … … 322 327 ***************************************************************************/ 323 328 324 static void free_auth_context(struct auth_context **auth_context) 325 { 326 auth_methods *auth_method; 327 328 if (*auth_context) { 329 /* Free private data of context's authentication methods */ 330 for (auth_method = (*auth_context)->auth_method_list; auth_method; auth_method = auth_method->next) { 331 TALLOC_FREE(auth_method->private_data); 332 } 333 334 talloc_destroy((*auth_context)->mem_ctx); 335 *auth_context = NULL; 336 } 329 static int auth_context_destructor(void *ptr) 330 { 331 struct auth_context *ctx = talloc_get_type(ptr, struct auth_context); 332 struct auth_methods *am; 333 334 335 /* Free private data of context's authentication methods */ 336 for (am = ctx->auth_method_list; am; am = am->next) { 337 TALLOC_FREE(am->private_data); 338 } 339 340 return 0; 337 341 } 338 342 … … 341 345 ***************************************************************************/ 342 346 343 static NTSTATUS make_auth_context(struct auth_context **auth_context) 344 { 345 TALLOC_CTX *mem_ctx; 346 347 mem_ctx = talloc_init("authentication context"); 348 349 *auth_context = TALLOC_P(mem_ctx, struct auth_context); 350 if (!*auth_context) { 347 static NTSTATUS make_auth_context(TALLOC_CTX *mem_ctx, 348 struct auth_context **auth_context) 349 { 350 struct auth_context *ctx; 351 352 ctx = talloc_zero(mem_ctx, struct auth_context); 353 if (!ctx) { 351 354 DEBUG(0,("make_auth_context: talloc failed!\n")); 352 talloc_destroy(mem_ctx);353 355 return NT_STATUS_NO_MEMORY; 354 356 } 355 ZERO_STRUCTP(*auth_context); 356 357 (*auth_context)->mem_ctx = mem_ctx;358 (*auth_context)->check_ntlm_password = check_ntlm_password; 359 (*auth_context)->get_ntlm_challenge = get_ntlm_challenge;360 (*auth_context)->free = free_auth_context; 361 357 358 ctx->check_ntlm_password = check_ntlm_password; 359 ctx->get_ntlm_challenge = get_ntlm_challenge; 360 361 talloc_set_destructor((TALLOC_CTX *)ctx, auth_context_destructor); 362 363 *auth_context = ctx; 362 364 return NT_STATUS_OK; 363 365 } … … 421 423 ***************************************************************************/ 422 424 423 static NTSTATUS make_auth_context_text_list(struct auth_context **auth_context, char **text_list) 425 static NTSTATUS make_auth_context_text_list(TALLOC_CTX *mem_ctx, 426 struct auth_context **auth_context, 427 char **text_list) 424 428 { 425 429 auth_methods *list = NULL; … … 432 436 } 433 437 434 if (!NT_STATUS_IS_OK(nt_status = make_auth_context(auth_context))) 438 nt_status = make_auth_context(mem_ctx, auth_context); 439 440 if (!NT_STATUS_IS_OK(nt_status)) { 435 441 return nt_status; 442 } 436 443 437 444 for (;*text_list; text_list++) { … … 450 457 ***************************************************************************/ 451 458 452 NTSTATUS make_auth_context_subsystem(struct auth_context **auth_context) 459 NTSTATUS make_auth_context_subsystem(TALLOC_CTX *mem_ctx, 460 struct auth_context **auth_context) 453 461 { 454 462 char **auth_method_list = NULL; … … 521 529 } 522 530 523 nt_status = make_auth_context_text_list( auth_context,531 nt_status = make_auth_context_text_list(mem_ctx, auth_context, 524 532 auth_method_list); 525 533 … … 532 540 ***************************************************************************/ 533 541 534 NTSTATUS make_auth_context_fixed(struct auth_context **auth_context, uchar chal[8]) 542 NTSTATUS make_auth_context_fixed(TALLOC_CTX *mem_ctx, 543 struct auth_context **auth_context, 544 uchar chal[8]) 535 545 { 536 546 NTSTATUS nt_status; 537 if (!NT_STATUS_IS_OK(nt_status = make_auth_context_subsystem(auth_context))) { 547 nt_status = make_auth_context_subsystem(mem_ctx, auth_context); 548 if (!NT_STATUS_IS_OK(nt_status)) { 538 549 return nt_status; 539 550 } 540 551 541 (*auth_context)->challenge = data_blob_talloc( (*auth_context)->mem_ctx, chal, 8);552 (*auth_context)->challenge = data_blob_talloc(*auth_context, chal, 8); 542 553 (*auth_context)->challenge_set_by = "fixed"; 543 554 return nt_status; -
trunk/server/source3/auth/auth_builtin.c
r414 r745 4 4 Copyright (C) Andrew Bartlett 2001-2002 5 5 Copyright (C) Jelmer Vernooij 2002 6 6 7 7 This program is free software; you can redistribute it and/or modify 8 8 it under the terms of the GNU General Public License as published by 9 9 the Free Software Foundation; either version 3 of the License, or 10 10 (at your option) any later version. 11 11 12 12 This program is distributed in the hope that it will be useful, 13 13 but WITHOUT ANY WARRANTY; without even the implied warranty of 14 14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 15 GNU General Public License for more details. 16 16 17 17 You should have received a copy of the GNU General Public License 18 18 along with this program. If not, see <http://www.gnu.org/licenses/>. … … 20 20 21 21 #include "includes.h" 22 #include "auth.h" 22 23 23 24 #undef DBGC_CLASS … … 35 36 void *my_private_data, 36 37 TALLOC_CTX *mem_ctx, 37 const auth_usersupplied_info *user_info,38 auth_serversupplied_info **server_info)38 const struct auth_usersupplied_info *user_info, 39 struct auth_serversupplied_info **server_info) 39 40 { 40 41 /* mark this as 'not for me' */ 41 42 NTSTATUS nt_status = NT_STATUS_NOT_IMPLEMENTED; 42 43 43 if (!(user_info->internal_username 44 && *user_info->internal_username)) { 44 DEBUG(10, ("Check auth for: [%s]\n", user_info->mapped.account_name)); 45 46 if (!(user_info->mapped.account_name 47 && *user_info->mapped.account_name)) { 45 48 nt_status = make_server_info_guest(NULL, server_info); 46 49 } … … 53 56 static NTSTATUS auth_init_guest(struct auth_context *auth_context, const char *options, auth_methods **auth_method) 54 57 { 55 if (!make_auth_methods(auth_context, auth_method)) 58 struct auth_methods *result; 59 60 result = TALLOC_ZERO_P(auth_context, struct auth_methods); 61 if (result == NULL) { 56 62 return NT_STATUS_NO_MEMORY; 63 } 64 result->auth = check_guest_security; 65 result->name = "guest"; 57 66 58 (*auth_method)->auth = check_guest_security; 59 (*auth_method)->name = "guest"; 67 *auth_method = result; 60 68 return NT_STATUS_OK; 61 69 } … … 78 86 void *my_private_data, 79 87 TALLOC_CTX *mem_ctx, 80 const auth_usersupplied_info *user_info,81 auth_serversupplied_info **server_info)88 const struct auth_usersupplied_info *user_info, 89 struct auth_serversupplied_info **server_info) 82 90 { 83 91 NTSTATUS nt_status; 84 92 fstring user; 85 93 long error_num; 86 fstrcpy(user, user_info->smb_name); 87 94 95 DEBUG(10, ("Check auth for: [%s]\n", user_info->mapped.account_name)); 96 97 fstrcpy(user, user_info->client.account_name); 98 88 99 if (strnequal("NT_STATUS", user, strlen("NT_STATUS"))) { 89 100 strupper_m(user); … … 93 104 strlower_m(user); 94 105 error_num = strtoul(user, NULL, 16); 95 106 96 107 DEBUG(5,("check_name_to_ntstatus_security: Error for user %s was %lx\n", user, error_num)); 97 108 98 109 nt_status = NT_STATUS(error_num); 99 110 100 111 return nt_status; 101 112 } … … 105 116 static NTSTATUS auth_init_name_to_ntstatus(struct auth_context *auth_context, const char *param, auth_methods **auth_method) 106 117 { 107 if (!make_auth_methods(auth_context, auth_method)) 118 struct auth_methods *result; 119 120 result = TALLOC_ZERO_P(auth_context, struct auth_methods); 121 if (result == NULL) { 108 122 return NT_STATUS_NO_MEMORY; 123 } 124 result->auth = check_name_to_ntstatus_security; 125 result->name = "name_to_ntstatus"; 109 126 110 (*auth_method)->auth = check_name_to_ntstatus_security; 111 (*auth_method)->name = "name_to_ntstatus"; 127 *auth_method = result; 112 128 return NT_STATUS_OK; 113 129 } … … 131 147 void *my_private_data, 132 148 TALLOC_CTX *mem_ctx, 133 const auth_usersupplied_info *user_info,134 auth_serversupplied_info **server_info)149 const struct auth_usersupplied_info *user_info, 150 struct auth_serversupplied_info **server_info) 135 151 { 136 152 return NT_STATUS_NOT_IMPLEMENTED; … … 150 166 151 167 152 /** Module init ailisation function */168 /** Module initialisation function */ 153 169 154 170 static NTSTATUS auth_init_fixed_challenge(struct auth_context *auth_context, const char *param, auth_methods **auth_method) 155 171 { 156 if (!make_auth_methods(auth_context, auth_method)) 172 struct auth_methods *result; 173 174 result = TALLOC_ZERO_P(auth_context, struct auth_methods); 175 if (result == NULL) { 157 176 return NT_STATUS_NO_MEMORY; 177 } 178 result->auth = check_fixed_challenge_security; 179 result->get_chal = auth_get_fixed_challenge; 180 result->name = "fixed_challenge"; 158 181 159 (*auth_method)->auth = check_fixed_challenge_security; 160 (*auth_method)->get_chal = auth_get_fixed_challenge; 161 (*auth_method)->name = "fixed_challenge"; 182 *auth_method = result; 162 183 return NT_STATUS_OK; 163 184 } -
trunk/server/source3/auth/auth_compat.c
r414 r745 19 19 20 20 #include "includes.h" 21 #include "auth.h" 21 22 22 23 extern struct auth_context *negprot_global_auth_context; … … 31 32 32 33 /**************************************************************************** 33 check if a username/password is OK assuming the password is a 24 byte 34 SMB hash 34 check if a username/password is OK assuming the password is in plaintext 35 35 return True if the password is correct, False otherwise 36 36 ****************************************************************************/ 37 37 38 NTSTATUS check_plaintext_password(const char *smb_name, DATA_BLOB plaintext_password, auth_serversupplied_info **server_info) 38 NTSTATUS check_plaintext_password(const char *smb_name, 39 DATA_BLOB plaintext_blob, 40 struct auth_serversupplied_info **server_info) 39 41 { 40 42 struct auth_context *plaintext_auth_context = NULL; 41 auth_usersupplied_info *user_info = NULL;43 struct auth_usersupplied_info *user_info = NULL; 42 44 uint8_t chal[8]; 43 45 NTSTATUS nt_status; 44 if (!NT_STATUS_IS_OK(nt_status = make_auth_context_subsystem(&plaintext_auth_context))) { 46 47 nt_status = make_auth_context_subsystem(talloc_tos(), 48 &plaintext_auth_context); 49 if (!NT_STATUS_IS_OK(nt_status)) { 45 50 return nt_status; 46 51 } … … 51 56 if (!make_user_info_for_reply(&user_info, 52 57 smb_name, lp_workgroup(), chal, 53 plaintext_ password)) {58 plaintext_blob)) { 54 59 return NT_STATUS_NO_MEMORY; 55 60 } … … 58 63 user_info, server_info); 59 64 60 (plaintext_auth_context->free)(&plaintext_auth_context);65 TALLOC_FREE(plaintext_auth_context); 61 66 free_user_info(&user_info); 62 67 return nt_status; … … 67 72 const char *domain, 68 73 DATA_BLOB lm_pwd, 69 DATA_BLOB nt_pwd, 70 DATA_BLOB plaintext_password, 71 bool encrypted) 74 DATA_BLOB nt_pwd) 72 75 73 76 { 74 77 NTSTATUS nt_status; 75 auth_serversupplied_info *server_info = NULL; 76 if (encrypted) { 77 auth_usersupplied_info *user_info = NULL; 78 if (actx == NULL) { 79 return NT_STATUS_INTERNAL_ERROR; 80 } 81 make_user_info_for_reply_enc(&user_info, smb_name, 82 domain, 83 lm_pwd, 84 nt_pwd); 85 nt_status = actx->check_ntlm_password(actx, user_info, &server_info); 86 free_user_info(&user_info); 87 } else { 88 nt_status = check_plaintext_password(smb_name, plaintext_password, &server_info); 89 } 78 struct auth_serversupplied_info *server_info = NULL; 79 struct auth_usersupplied_info *user_info = NULL; 80 if (actx == NULL) { 81 return NT_STATUS_INTERNAL_ERROR; 82 } 83 make_user_info_for_reply_enc(&user_info, smb_name, 84 domain, 85 lm_pwd, 86 nt_pwd); 87 nt_status = actx->check_ntlm_password(actx, user_info, &server_info); 88 free_user_info(&user_info); 90 89 TALLOC_FREE(server_info); 91 90 return nt_status; … … 112 111 */ 113 112 if (session_workgroup) { 114 if (NT_STATUS_IS_OK(pass_check_smb(actx, smb_name, session_workgroup, null_password, password_blob , null_password, encrypted))) {113 if (NT_STATUS_IS_OK(pass_check_smb(actx, smb_name, session_workgroup, null_password, password_blob))) { 115 114 return True; 116 115 } 117 if (NT_STATUS_IS_OK(pass_check_smb(actx, smb_name, session_workgroup, password_blob, null_password , null_password, encrypted))) {116 if (NT_STATUS_IS_OK(pass_check_smb(actx, smb_name, session_workgroup, password_blob, null_password))) { 118 117 return True; 119 118 } 120 119 } 121 120 122 if (NT_STATUS_IS_OK(pass_check_smb(actx, smb_name, lp_workgroup(), null_password, password_blob , null_password, encrypted))) {121 if (NT_STATUS_IS_OK(pass_check_smb(actx, smb_name, lp_workgroup(), null_password, password_blob))) { 123 122 return True; 124 123 } 125 124 126 if (NT_STATUS_IS_OK(pass_check_smb(actx, smb_name, lp_workgroup(), password_blob, null_password , null_password, encrypted))) {125 if (NT_STATUS_IS_OK(pass_check_smb(actx, smb_name, lp_workgroup(), password_blob, null_password))) { 127 126 return True; 128 127 } 129 128 } else { 130 if (NT_STATUS_IS_OK(pass_check_smb(actx, smb_name, lp_workgroup(), null_password, null_password, password_blob, encrypted))) { 129 struct auth_serversupplied_info *server_info = NULL; 130 NTSTATUS nt_status = check_plaintext_password(smb_name, password_blob, &server_info); 131 TALLOC_FREE(server_info); 132 if (NT_STATUS_IS_OK(nt_status)) { 131 133 return True; 132 134 } -
trunk/server/source3/auth/auth_domain.c
r596 r745 4 4 Copyright (C) Andrew Tridgell 1992-1998 5 5 Copyright (C) Andrew Bartlett 2001 6 6 7 7 This program is free software; you can redistribute it and/or modify 8 8 it under the terms of the GNU General Public License as published by 9 9 the Free Software Foundation; either version 3 of the License, or 10 10 (at your option) any later version. 11 11 12 12 This program is distributed in the hope that it will be useful, 13 13 but WITHOUT ANY WARRANTY; without even the implied warranty of 14 14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 15 GNU General Public License for more details. 16 16 17 17 You should have received a copy of the GNU General Public License 18 18 along with this program. If not, see <http://www.gnu.org/licenses/>. … … 20 20 21 21 #include "includes.h" 22 #include "auth.h" 22 23 #include "../libcli/auth/libcli_auth.h" 24 #include "../librpc/gen_ndr/ndr_netlogon.h" 25 #include "rpc_client/cli_pipe.h" 26 #include "rpc_client/cli_netlogon.h" 27 #include "secrets.h" 28 #include "passdb.h" 29 #include "libsmb/libsmb.h" 23 30 24 31 #undef DBGC_CLASS … … 111 118 const char *dc_name, 112 119 struct sockaddr_storage *dc_ss, 113 struct rpc_pipe_client **pipe_ret, 114 bool *retry) 120 struct rpc_pipe_client **pipe_ret) 115 121 { 116 122 NTSTATUS result; … … 139 145 return NT_STATUS_NO_LOGON_SERVERS; 140 146 } 141 147 142 148 /* Attempt connection */ 143 *retry = True;144 149 result = cli_full_connection(cli, global_myname(), dc_name, dc_ss, 0, 145 "IPC$", "IPC", "", "", "", 0, Undefined , retry);150 "IPC$", "IPC", "", "", "", 0, Undefined); 146 151 147 152 if (!NT_STATUS_IS_OK(result)) { … … 252 257 253 258 static NTSTATUS domain_client_validate(TALLOC_CTX *mem_ctx, 254 const auth_usersupplied_info *user_info,259 const struct auth_usersupplied_info *user_info, 255 260 const char *domain, 256 261 uchar chal[8], 257 auth_serversupplied_info **server_info,262 struct auth_serversupplied_info **server_info, 258 263 const char *dc_name, 259 264 struct sockaddr_storage *dc_ss) … … 265 270 NTSTATUS nt_status = NT_STATUS_NO_LOGON_SERVERS; 266 271 int i; 267 bool retry = True;268 272 269 273 /* … … 276 280 277 281 /* rety loop for robustness */ 278 279 for (i = 0; !NT_STATUS_IS_OK(nt_status) && retry &&(i < 3); i++) {282 283 for (i = 0; !NT_STATUS_IS_OK(nt_status) && (i < 3); i++) { 280 284 nt_status = connect_to_domain_password_server(&cli, 281 285 domain, 282 286 dc_name, 283 287 dc_ss, 284 &netlogon_pipe, 285 &retry); 288 &netlogon_pipe); 286 289 } 287 290 … … 305 308 nt_status = rpccli_netlogon_sam_network_logon(netlogon_pipe, 306 309 mem_ctx, 307 user_info->logon_parameters, /* flags such as 'allow workstation logon' */308 dc_name, /* server name */309 user_info-> smb_name,/* user name logging on. */310 user_info->client _domain,/* domain name */311 user_info->w ksta_name,/* workstation name */312 chal, /* 8 byte challenge. */313 3, 314 user_info-> lm_resp,/* lanman 24 byte response */315 user_info-> nt_resp,/* nt 24 byte response */316 &info3); /* info3 out */310 user_info->logon_parameters, /* flags such as 'allow workstation logon' */ 311 dc_name, /* server name */ 312 user_info->client.account_name, /* user name logging on. */ 313 user_info->client.domain_name, /* domain name */ 314 user_info->workstation_name, /* workstation name */ 315 chal, /* 8 byte challenge. */ 316 3, /* validation level */ 317 user_info->password.response.lanman, /* lanman 24 byte response */ 318 user_info->password.response.nt, /* nt 24 byte response */ 319 &info3); /* info3 out */ 317 320 318 321 /* Let go as soon as possible so we avoid any potential deadlocks 319 322 with winbind lookup up users or groups. */ 320 323 321 324 TALLOC_FREE(mutex); 322 325 … … 324 327 DEBUG(0,("domain_client_validate: unable to validate password " 325 328 "for user %s in domain %s to Domain controller %s. " 326 "Error was %s.\n", user_info-> smb_name,327 user_info->client _domain, dc_name,329 "Error was %s.\n", user_info->client.account_name, 330 user_info->client.domain_name, dc_name, 328 331 nt_errstr(nt_status))); 329 332 … … 334 337 } else { 335 338 nt_status = make_server_info_info3(mem_ctx, 336 user_info->smb_name,337 domain,338 server_info,339 info3);339 user_info->client.account_name, 340 domain, 341 server_info, 342 info3); 340 343 341 344 if (NT_STATUS_IS_OK(nt_status)) { 342 345 (*server_info)->nss_token |= user_info->was_mapped; 343 344 if ( ! (*server_info)->guest) { 345 /* if a real user check pam account restrictions */ 346 /* only really perfomed if "obey pam restriction" is true */ 347 nt_status = smb_pam_accountcheck((*server_info)->unix_name); 348 if ( !NT_STATUS_IS_OK(nt_status)) { 349 DEBUG(1, ("PAM account restriction prevents user login\n")); 350 cli_shutdown(cli); 351 TALLOC_FREE(info3); 352 return nt_status; 353 } 354 } 355 } 356 357 netsamlogon_cache_store(user_info->smb_name, info3); 358 TALLOC_FREE(info3); 346 netsamlogon_cache_store(user_info->client.account_name, info3); 347 TALLOC_FREE(info3); 348 } 359 349 } 360 350 … … 374 364 void *my_private_data, 375 365 TALLOC_CTX *mem_ctx, 376 const auth_usersupplied_info *user_info,377 auth_serversupplied_info **server_info)366 const struct auth_usersupplied_info *user_info, 367 struct auth_serversupplied_info **server_info) 378 368 { 379 369 NTSTATUS nt_status = NT_STATUS_LOGON_FAILURE; … … 393 383 } 394 384 385 DEBUG(10, ("Check auth for: [%s]\n", user_info->mapped.account_name)); 386 395 387 /* 396 388 * Check that the requested domain is not our own machine name. … … 399 391 */ 400 392 401 if(strequal(get_global_sam_name(), user_info-> domain)) {393 if(strequal(get_global_sam_name(), user_info->mapped.domain_name)) { 402 394 DEBUG(3,("check_ntdomain_security: Requested domain was for this machine.\n")); 403 395 return NT_STATUS_NOT_IMPLEMENTED; … … 408 400 if ( !get_dc_name(domain, NULL, dc_name, &dc_ss) ) { 409 401 DEBUG(5,("check_ntdomain_security: unable to locate a DC for domain %s\n", 410 user_info-> domain));402 user_info->mapped.domain_name)); 411 403 return NT_STATUS_NO_LOGON_SERVERS; 412 404 } 413 405 414 406 nt_status = domain_client_validate(mem_ctx, 415 407 user_info, … … 419 411 dc_name, 420 412 &dc_ss); 421 413 422 414 return nt_status; 423 415 } … … 426 418 static NTSTATUS auth_init_ntdomain(struct auth_context *auth_context, const char* param, auth_methods **auth_method) 427 419 { 428 if (!make_auth_methods(auth_context, auth_method)) { 420 struct auth_methods *result; 421 422 result = TALLOC_ZERO_P(auth_context, struct auth_methods); 423 if (result == NULL) { 429 424 return NT_STATUS_NO_MEMORY; 430 425 } 431 432 (*auth_method)->name = "ntdomain"; 433 (*auth_method)->auth = check_ntdomain_security; 426 result->name = "ntdomain"; 427 result->auth = check_ntdomain_security; 428 429 *auth_method = result; 434 430 return NT_STATUS_OK; 435 431 } … … 443 439 void *my_private_data, 444 440 TALLOC_CTX *mem_ctx, 445 const auth_usersupplied_info *user_info,446 auth_serversupplied_info **server_info)441 const struct auth_usersupplied_info *user_info, 442 struct auth_serversupplied_info **server_info) 447 443 { 448 444 NTSTATUS nt_status = NT_STATUS_LOGON_FAILURE; … … 457 453 } 458 454 455 DEBUG(10, ("Check auth for: [%s]\n", user_info->mapped.account_name)); 456 459 457 /* 460 458 * Check that the requested domain is not our own machine name or domain name. 461 459 */ 462 460 463 if( strequal(get_global_sam_name(), user_info-> domain)) {461 if( strequal(get_global_sam_name(), user_info->mapped.domain_name)) { 464 462 DEBUG(3,("check_trustdomain_security: Requested domain [%s] was for this machine.\n", 465 user_info-> domain));463 user_info->mapped.domain_name)); 466 464 return NT_STATUS_NOT_IMPLEMENTED; 467 465 } … … 471 469 The logic is that if we know nothing about the domain, that 472 470 user is not known to us and does not exist */ 473 474 if ( !is_trusted_domain( user_info-> domain) )471 472 if ( !is_trusted_domain( user_info->mapped.domain_name ) ) 475 473 return NT_STATUS_NOT_IMPLEMENTED; 476 474 … … 480 478 */ 481 479 482 if (!pdb_get_trusteddom_pw(user_info-> domain, &trust_password,480 if (!pdb_get_trusteddom_pw(user_info->mapped.domain_name, &trust_password, 483 481 NULL, NULL)) { 484 482 DEBUG(0, ("check_trustdomain_security: could not fetch trust " 485 483 "account password for domain %s\n", 486 user_info-> domain));484 user_info->mapped.domain_name)); 487 485 return NT_STATUS_CANT_ACCESS_DOMAIN_INFO; 488 486 } 489 487 490 488 #ifdef DEBUG_PASSWORD 491 DEBUG(100, ("Trust password for domain %s is %s\n", user_info-> domain,489 DEBUG(100, ("Trust password for domain %s is %s\n", user_info->mapped.domain_name, 492 490 trust_password)); 493 491 #endif … … 505 503 /* use get_dc_name() for consistency even through we know that it will be 506 504 a netbios name */ 507 508 if ( !get_dc_name(user_info-> domain, NULL, dc_name, &dc_ss) ) {505 506 if ( !get_dc_name(user_info->mapped.domain_name, NULL, dc_name, &dc_ss) ) { 509 507 DEBUG(5,("check_trustdomain_security: unable to locate a DC for domain %s\n", 510 user_info-> domain));508 user_info->mapped.domain_name)); 511 509 return NT_STATUS_NO_LOGON_SERVERS; 512 510 } 513 511 514 512 nt_status = domain_client_validate(mem_ctx, 515 user_info,516 user_info->domain,517 (uchar *)auth_context->challenge.data,518 server_info,519 dc_name,520 &dc_ss);513 user_info, 514 user_info->mapped.domain_name, 515 (uchar *)auth_context->challenge.data, 516 server_info, 517 dc_name, 518 &dc_ss); 521 519 522 520 return nt_status; … … 526 524 static NTSTATUS auth_init_trustdomain(struct auth_context *auth_context, const char* param, auth_methods **auth_method) 527 525 { 528 if (!make_auth_methods(auth_context, auth_method)) { 526 struct auth_methods *result; 527 528 result = TALLOC_ZERO_P(auth_context, struct auth_methods); 529 if (result == NULL) { 529 530 return NT_STATUS_NO_MEMORY; 530 531 } 531 532 (*auth_method)->name = "trustdomain"; 533 (*auth_method)->auth = check_trustdomain_security; 532 result->name = "trustdomain"; 533 result->auth = check_trustdomain_security; 534 535 *auth_method = result; 534 536 return NT_STATUS_OK; 535 537 } -
trunk/server/source3/auth/auth_netlogond.c
r596 r745 19 19 20 20 #include "includes.h" 21 #include "auth.h" 21 22 #include "../libcli/auth/libcli_auth.h" 23 #include "../librpc/gen_ndr/ndr_netlogon.h" 24 #include "librpc/gen_ndr/ndr_schannel.h" 25 #include "rpc_client/cli_pipe.h" 26 #include "rpc_client/cli_netlogon.h" 27 #include "secrets.h" 28 #include "tldap.h" 29 #include "tldap_util.h" 22 30 23 31 #undef DBGC_CLASS 24 32 #define DBGC_CLASS DBGC_AUTH 33 34 static bool secrets_store_local_schannel_creds( 35 const struct netlogon_creds_CredentialState *creds) 36 { 37 DATA_BLOB blob; 38 enum ndr_err_code ndr_err; 39 bool ret; 40 41 ndr_err = ndr_push_struct_blob( 42 &blob, talloc_tos(), creds, 43 (ndr_push_flags_fn_t)ndr_push_netlogon_creds_CredentialState); 44 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { 45 DEBUG(10, ("ndr_push_netlogon_creds_CredentialState failed: " 46 "%s\n", ndr_errstr(ndr_err))); 47 return false; 48 } 49 ret = secrets_store(SECRETS_LOCAL_SCHANNEL_KEY, 50 blob.data, blob.length); 51 data_blob_free(&blob); 52 return ret; 53 } 54 55 static struct netlogon_creds_CredentialState * 56 secrets_fetch_local_schannel_creds(TALLOC_CTX *mem_ctx) 57 { 58 struct netlogon_creds_CredentialState *creds; 59 enum ndr_err_code ndr_err; 60 DATA_BLOB blob; 61 62 blob.data = (uint8_t *)secrets_fetch(SECRETS_LOCAL_SCHANNEL_KEY, 63 &blob.length); 64 if (blob.data == NULL) { 65 DEBUG(10, ("secrets_fetch failed\n")); 66 return NULL; 67 } 68 69 creds = talloc(mem_ctx, struct netlogon_creds_CredentialState); 70 if (creds == NULL) { 71 DEBUG(10, ("talloc failed\n")); 72 SAFE_FREE(blob.data); 73 return NULL; 74 } 75 ndr_err = ndr_pull_struct_blob( 76 &blob, creds, creds, 77 (ndr_pull_flags_fn_t)ndr_pull_netlogon_creds_CredentialState); 78 SAFE_FREE(blob.data); 79 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { 80 DEBUG(10, ("ndr_pull_netlogon_creds_CredentialState failed: " 81 "%s\n", ndr_errstr(ndr_err))); 82 TALLOC_FREE(creds); 83 return NULL; 84 } 85 86 return creds; 87 } 25 88 26 89 static NTSTATUS netlogond_validate(TALLOC_CTX *mem_ctx, 27 90 const struct auth_context *auth_context, 28 91 const char *ncalrpc_sockname, 29 uint8_t schannel_key[16],30 const auth_usersupplied_info *user_info,92 struct netlogon_creds_CredentialState *creds, 93 const struct auth_usersupplied_info *user_info, 31 94 struct netr_SamInfo3 **pinfo3, 32 95 NTSTATUS *schannel_bind_result) 33 96 { 34 97 struct rpc_pipe_client *p = NULL; 35 struct cli_pipe_auth_data *auth = NULL;98 struct pipe_auth_data *auth = NULL; 36 99 struct netr_SamInfo3 *info3 = NULL; 37 100 NTSTATUS status; … … 47 110 } 48 111 49 /* 50 * We have to fake a struct dcinfo, so that 51 * rpccli_netlogon_sam_network_logon_ex can decrypt the session keys. 52 */ 53 54 p->dc = netlogon_creds_client_init_session_key(p, schannel_key); 55 if (p->dc == NULL) { 56 DEBUG(0, ("talloc failed\n")); 57 TALLOC_FREE(p); 58 return NT_STATUS_NO_MEMORY; 59 } 112 p->dc = creds; 60 113 61 114 status = rpccli_schannel_bind_data(p, lp_workgroup(), … … 79 132 status = rpccli_netlogon_sam_network_logon_ex( 80 133 p, p, 81 user_info->logon_parameters, /* flags such as 'allow82 * workstation logon' */83 global_myname(), /* server name */84 user_info-> smb_name, /* user name logging on. */85 user_info->client _domain,/* domain name */86 user_info->w ksta_name,/* workstation name */134 user_info->logon_parameters, /* flags such as 'allow 135 * workstation logon' */ 136 global_myname(), /* server name */ 137 user_info->client.account_name, /* user name logging on. */ 138 user_info->client.domain_name, /* domain name */ 139 user_info->workstation_name, /* workstation name */ 87 140 (uchar *)auth_context->challenge.data, /* 8 byte challenge. */ 88 3, 89 user_info-> lm_resp,/* lanman 24 byte response */90 user_info-> nt_resp,/* nt 24 byte response */91 &info3); /* info3 out */141 3, /* validation level */ 142 user_info->password.response.lanman, /* lanman 24 byte response */ 143 user_info->password.response.nt, /* nt 24 byte response */ 144 &info3); /* info3 out */ 92 145 93 146 DEBUG(10, ("rpccli_netlogon_sam_network_logon_ex returned %s\n", … … 105 158 } 106 159 107 static char *mymachinepw(TALLOC_CTX *mem_ctx) 108 { 109 fstring pwd; 110 const char *script; 111 char *to_free = NULL; 112 ssize_t nread; 113 int ret, fd; 114 115 script = lp_parm_const_string( 116 GLOBAL_SECTION_SNUM, "auth_netlogond", "machinepwscript", 117 NULL); 118 119 if (script == NULL) { 120 to_free = talloc_asprintf(talloc_tos(), "%s/%s", 121 get_dyn_SBINDIR(), "mymachinepw"); 122 script = to_free; 123 } 124 if (script == NULL) { 125 return NULL; 126 } 127 128 ret = smbrun(script, &fd); 129 DEBUG(ret ? 0 : 3, ("mymachinepw: Running the command `%s' gave %d\n", 130 script, ret)); 131 TALLOC_FREE(to_free); 132 133 if (ret != 0) { 134 return NULL; 135 } 136 137 nread = read(fd, pwd, sizeof(pwd)-1); 138 close(fd); 139 140 if (nread <= 0) { 141 DEBUG(3, ("mymachinepwd: Could not read password\n")); 142 return NULL; 143 } 144 145 pwd[nread] = '\0'; 146 147 if (pwd[nread-1] == '\n') { 148 pwd[nread-1] = '\0'; 149 } 150 151 return talloc_strdup(mem_ctx, pwd); 160 static NTSTATUS get_ldapi_ctx(TALLOC_CTX *mem_ctx, struct tldap_context **pld) 161 { 162 struct tldap_context *ld; 163 struct sockaddr_un addr; 164 char *sockaddr; 165 int fd; 166 NTSTATUS status; 167 int res; 168 169 sockaddr = talloc_asprintf(talloc_tos(), "/%s/ldap_priv/ldapi", 170 lp_private_dir()); 171 if (sockaddr == NULL) { 172 DEBUG(10, ("talloc failed\n")); 173 return NT_STATUS_NO_MEMORY; 174 } 175 176 ZERO_STRUCT(addr); 177 addr.sun_family = AF_UNIX; 178 strncpy(addr.sun_path, sockaddr, sizeof(addr.sun_path)); 179 TALLOC_FREE(sockaddr); 180 181 status = open_socket_out((struct sockaddr_storage *)(void *)&addr, 182 0, 0, &fd); 183 if (!NT_STATUS_IS_OK(status)) { 184 DEBUG(10, ("Could not connect to %s: %s\n", addr.sun_path, 185 nt_errstr(status))); 186 return status; 187 } 188 set_blocking(fd, false); 189 190 ld = tldap_context_create(mem_ctx, fd); 191 if (ld == NULL) { 192 close(fd); 193 return NT_STATUS_NO_MEMORY; 194 } 195 res = tldap_fetch_rootdse(ld); 196 if (res != TLDAP_SUCCESS) { 197 DEBUG(10, ("tldap_fetch_rootdse failed: %s\n", 198 tldap_errstr(talloc_tos(), ld, res))); 199 TALLOC_FREE(ld); 200 return NT_STATUS_LDAP(res); 201 } 202 *pld = ld; 203 return NT_STATUS_OK;; 204 } 205 206 static NTSTATUS mymachinepw(uint8_t pwd[16]) 207 { 208 TALLOC_CTX *frame = talloc_stackframe(); 209 struct tldap_context *ld = NULL; 210 struct tldap_message *rootdse, **msg; 211 const char *attrs[1] = { "unicodePwd" }; 212 char *default_nc, *myname; 213 int rc, num_msg; 214 DATA_BLOB pwdblob; 215 NTSTATUS status; 216 217 status = get_ldapi_ctx(talloc_tos(), &ld); 218 if (!NT_STATUS_IS_OK(status)) { 219 goto fail; 220 } 221 rootdse = tldap_rootdse(ld); 222 if (rootdse == NULL) { 223 DEBUG(10, ("Could not get rootdse\n")); 224 status = NT_STATUS_INTERNAL_ERROR; 225 goto fail; 226 } 227 default_nc = tldap_talloc_single_attribute( 228 rootdse, "defaultNamingContext", talloc_tos()); 229 if (default_nc == NULL) { 230 DEBUG(10, ("Could not get defaultNamingContext\n")); 231 status = NT_STATUS_NO_MEMORY; 232 goto fail; 233 } 234 DEBUG(10, ("default_nc = %s\n", default_nc)); 235 236 myname = talloc_asprintf_strupper_m(talloc_tos(), "%s$", 237 global_myname()); 238 if (myname == NULL) { 239 DEBUG(10, ("talloc failed\n")); 240 status = NT_STATUS_NO_MEMORY; 241 goto fail; 242 } 243 244 rc = tldap_search_fmt( 245 ld, default_nc, TLDAP_SCOPE_SUB, attrs, ARRAY_SIZE(attrs), 0, 246 talloc_tos(), &msg, 247 "(&(sAMAccountName=%s)(objectClass=computer))", myname); 248 if (rc != TLDAP_SUCCESS) { 249 DEBUG(10, ("Could not retrieve our account: %s\n", 250 tldap_errstr(talloc_tos(), ld, rc))); 251 status = NT_STATUS_LDAP(rc); 252 goto fail; 253 } 254 num_msg = talloc_array_length(msg); 255 if (num_msg != 1) { 256 DEBUG(10, ("Got %d accounts, expected one\n", num_msg)); 257 status = NT_STATUS_INTERNAL_DB_CORRUPTION; 258 goto fail; 259 } 260 if (!tldap_get_single_valueblob(msg[0], "unicodePwd", &pwdblob)) { 261 char *dn = NULL; 262 tldap_entry_dn(msg[0], &dn); 263 DEBUG(10, ("No unicodePwd attribute in %s\n", 264 dn ? dn : "<unknown DN>")); 265 status = NT_STATUS_INTERNAL_DB_CORRUPTION; 266 goto fail; 267 } 268 if (pwdblob.length != 16) { 269 DEBUG(10, ("Password hash hash has length %d, expected 16\n", 270 (int)pwdblob.length)); 271 status = NT_STATUS_INTERNAL_DB_CORRUPTION; 272 goto fail; 273 } 274 memcpy(pwd, pwdblob.data, 16); 275 276 fail: 277 TALLOC_FREE(frame); 278 return status; 152 279 } 153 280 … … 155 282 void *my_private_data, 156 283 TALLOC_CTX *mem_ctx, 157 const auth_usersupplied_info *user_info,158 auth_serversupplied_info **server_info)284 const struct auth_usersupplied_info *user_info, 285 struct auth_serversupplied_info **server_info) 159 286 { 160 287 TALLOC_CTX *frame = talloc_stackframe(); 161 288 struct netr_SamInfo3 *info3 = NULL; 162 289 struct rpc_pipe_client *p = NULL; 163 struct cli_pipe_auth_data *auth = NULL;290 struct pipe_auth_data *auth = NULL; 164 291 uint32_t neg_flags = NETLOGON_NEG_AUTH2_ADS_FLAGS; 165 char *plaintext_machinepw = NULL;166 292 uint8_t machine_password[16]; 167 uint8_t schannel_key[16];293 struct netlogon_creds_CredentialState *creds; 168 294 NTSTATUS schannel_bind_result, status; 169 295 struct named_mutex *mutex = NULL; 170 296 const char *ncalrpcsock; 171 297 298 DEBUG(10, ("Check auth for: [%s]\n", user_info->mapped.account_name)); 299 172 300 ncalrpcsock = lp_parm_const_string( 173 301 GLOBAL_SECTION_SNUM, "auth_netlogond", "socket", NULL); … … 183 311 } 184 312 185 if (!secrets_fetch_local_schannel_key(schannel_key)) { 313 creds = secrets_fetch_local_schannel_creds(talloc_tos()); 314 if (creds == NULL) { 186 315 goto new_key; 187 316 } 188 317 189 318 status = netlogond_validate(talloc_tos(), auth_context, ncalrpcsock, 190 schannel_key, user_info, &info3,319 creds, user_info, &info3, 191 320 &schannel_bind_result); 192 321 … … 237 366 } 238 367 239 plaintext_machinepw = mymachinepw(talloc_tos()); 240 if (plaintext_machinepw == NULL) { 241 status = NT_STATUS_NO_MEMORY; 242 goto done; 243 } 244 245 E_md4hash(plaintext_machinepw, machine_password); 246 247 TALLOC_FREE(plaintext_machinepw); 368 status = mymachinepw(machine_password); 369 if (!NT_STATUS_IS_OK(status)) { 370 DEBUG(10, ("mymachinepw failed: %s\n", nt_errstr(status))); 371 goto done; 372 } 373 374 DEBUG(10, ("machinepw ")); 375 dump_data(10, machine_password, 16); 248 376 249 377 status = rpccli_netlogon_setup_creds( … … 257 385 } 258 386 259 memcpy(schannel_key, p->dc->session_key, 16); 260 secrets_store_local_schannel_key(schannel_key); 261 262 TALLOC_FREE(p); 387 secrets_store_local_schannel_creds(p->dc); 263 388 264 389 /* … … 268 393 269 394 status = netlogond_validate(talloc_tos(), auth_context, ncalrpcsock, 270 schannel_key, user_info, &info3,395 p->dc, user_info, &info3, 271 396 &schannel_bind_result); 272 397 398 TALLOC_FREE(p); 399 273 400 DEBUG(10, ("netlogond_validate returned %s\n", nt_errstr(status))); 274 401 … … 279 406 okay: 280 407 281 status = make_server_info_info3(mem_ctx, user_info-> smb_name,282 user_info-> domain, server_info,408 status = make_server_info_info3(mem_ctx, user_info->client.account_name, 409 user_info->mapped.domain_name, server_info, 283 410 info3); 284 411 if (!NT_STATUS_IS_OK(status)) { … … 301 428 auth_methods **auth_method) 302 429 { 303 if (!make_auth_methods(auth_context, auth_method)) { 430 struct auth_methods *result; 431 432 result = TALLOC_ZERO_P(auth_context, struct auth_methods); 433 if (result == NULL) { 304 434 return NT_STATUS_NO_MEMORY; 305 435 } 306 307 (*auth_method)->name = "netlogond"; 308 (*auth_method)->auth = check_netlogond_security; 436 result->name = "netlogond"; 437 result->auth = check_netlogond_security; 438 439 *auth_method = result; 309 440 return NT_STATUS_OK; 310 441 } -
trunk/server/source3/auth/auth_ntlmssp.c
r596 r745 22 22 23 23 #include "includes.h" 24 #include "auth.h" 25 #include "../libcli/auth/ntlmssp.h" 26 #include "ntlmssp_wrap.h" 27 #include "../librpc/gen_ndr/netlogon.h" 28 #include "smbd/smbd.h" 29 30 NTSTATUS auth_ntlmssp_steal_session_info(TALLOC_CTX *mem_ctx, 31 struct auth_ntlmssp_state *auth_ntlmssp_state, 32 struct auth_serversupplied_info **session_info) 33 { 34 /* Free the current server_info user_session_key and reset it from the 35 * current ntlmssp_state session_key */ 36 data_blob_free(&auth_ntlmssp_state->server_info->user_session_key); 37 /* Set up the final session key for the connection */ 38 auth_ntlmssp_state->server_info->user_session_key = 39 data_blob_talloc( 40 auth_ntlmssp_state->server_info, 41 auth_ntlmssp_state->ntlmssp_state->session_key.data, 42 auth_ntlmssp_state->ntlmssp_state->session_key.length); 43 if (auth_ntlmssp_state->ntlmssp_state->session_key.length && 44 !auth_ntlmssp_state->server_info->user_session_key.data) { 45 *session_info = NULL; 46 return NT_STATUS_NO_MEMORY; 47 } 48 /* Steal session_info away from auth_ntlmssp_state */ 49 *session_info = talloc_move(mem_ctx, &auth_ntlmssp_state->server_info); 50 return NT_STATUS_OK; 51 } 24 52 25 53 /** … … 28 56 */ 29 57 30 static voidauth_ntlmssp_get_challenge(const struct ntlmssp_state *ntlmssp_state,31 32 { 33 AUTH_NTLMSSP_STATE*auth_ntlmssp_state =34 ( AUTH_NTLMSSP_STATE *)ntlmssp_state->auth_context;58 static NTSTATUS auth_ntlmssp_get_challenge(const struct ntlmssp_state *ntlmssp_state, 59 uint8_t chal[8]) 60 { 61 struct auth_ntlmssp_state *auth_ntlmssp_state = 62 (struct auth_ntlmssp_state *)ntlmssp_state->callback_private; 35 63 auth_ntlmssp_state->auth_context->get_ntlm_challenge( 36 64 auth_ntlmssp_state->auth_context, chal); 65 return NT_STATUS_OK; 37 66 } 38 67 … … 44 73 static bool auth_ntlmssp_may_set_challenge(const struct ntlmssp_state *ntlmssp_state) 45 74 { 46 AUTH_NTLMSSP_STATE*auth_ntlmssp_state =47 ( AUTH_NTLMSSP_STATE *)ntlmssp_state->auth_context;75 struct auth_ntlmssp_state *auth_ntlmssp_state = 76 (struct auth_ntlmssp_state *)ntlmssp_state->callback_private; 48 77 struct auth_context *auth_context = auth_ntlmssp_state->auth_context; 49 78 … … 57 86 static NTSTATUS auth_ntlmssp_set_challenge(struct ntlmssp_state *ntlmssp_state, DATA_BLOB *challenge) 58 87 { 59 AUTH_NTLMSSP_STATE*auth_ntlmssp_state =60 ( AUTH_NTLMSSP_STATE *)ntlmssp_state->auth_context;88 struct auth_ntlmssp_state *auth_ntlmssp_state = 89 (struct auth_ntlmssp_state *)ntlmssp_state->callback_private; 61 90 struct auth_context *auth_context = auth_ntlmssp_state->auth_context; 62 91 63 92 SMB_ASSERT(challenge->length == 8); 64 93 65 auth_context->challenge = data_blob_talloc(auth_context ->mem_ctx,94 auth_context->challenge = data_blob_talloc(auth_context, 66 95 challenge->data, challenge->length); 67 96 … … 80 109 */ 81 110 82 static NTSTATUS auth_ntlmssp_check_password(struct ntlmssp_state *ntlmssp_state, DATA_BLOB *user_session_key, DATA_BLOB *lm_session_key) 83 { 84 AUTH_NTLMSSP_STATE *auth_ntlmssp_state = 85 (AUTH_NTLMSSP_STATE *)ntlmssp_state->auth_context; 86 auth_usersupplied_info *user_info = NULL; 111 static NTSTATUS auth_ntlmssp_check_password(struct ntlmssp_state *ntlmssp_state, TALLOC_CTX *mem_ctx, 112 DATA_BLOB *user_session_key, DATA_BLOB *lm_session_key) 113 { 114 struct auth_ntlmssp_state *auth_ntlmssp_state = 115 (struct auth_ntlmssp_state *)ntlmssp_state->callback_private; 116 struct auth_usersupplied_info *user_info = NULL; 87 117 NTSTATUS nt_status; 88 118 bool username_was_mapped; … … 91 121 we need to possibly reload smb.conf if smb.conf includes depend on the machine name */ 92 122 93 set_remote_machine_name(auth_ntlmssp_state->ntlmssp_state-> workstation, True);123 set_remote_machine_name(auth_ntlmssp_state->ntlmssp_state->client.netbios_name, True); 94 124 95 125 /* setup the string used by %U */ … … 97 127 sub_set_smb_name(auth_ntlmssp_state->ntlmssp_state->user); 98 128 99 reload_services( True);129 reload_services(smbd_messaging_context(), -1, True); 100 130 101 131 nt_status = make_user_info_map(&user_info, 102 132 auth_ntlmssp_state->ntlmssp_state->user, 103 133 auth_ntlmssp_state->ntlmssp_state->domain, 104 auth_ntlmssp_state->ntlmssp_state-> workstation,134 auth_ntlmssp_state->ntlmssp_state->client.netbios_name, 105 135 auth_ntlmssp_state->ntlmssp_state->lm_resp.data ? &auth_ntlmssp_state->ntlmssp_state->lm_resp : NULL, 106 136 auth_ntlmssp_state->ntlmssp_state->nt_resp.data ? &auth_ntlmssp_state->ntlmssp_state->nt_resp : NULL, 107 137 NULL, NULL, NULL, 108 True); 138 AUTH_PASSWORD_RESPONSE); 139 140 if (!NT_STATUS_IS_OK(nt_status)) { 141 return nt_status; 142 } 109 143 110 144 user_info->logon_parameters = MSV1_0_ALLOW_SERVER_TRUST_ACCOUNT | MSV1_0_ALLOW_WORKSTATION_TRUST_ACCOUNT; 111 112 if (!NT_STATUS_IS_OK(nt_status)) {113 return nt_status;114 }115 145 116 146 nt_status = auth_ntlmssp_state->auth_context->check_ntlm_password(auth_ntlmssp_state->auth_context, … … 127 157 auth_ntlmssp_state->server_info->nss_token |= username_was_mapped; 128 158 129 if (auth_ntlmssp_state->server_info->ptok == NULL) { 130 nt_status = create_local_token(auth_ntlmssp_state->server_info); 131 if (!NT_STATUS_IS_OK(nt_status)) { 132 DEBUG(10, ("create_local_token failed: %s\n", 133 nt_errstr(nt_status))); 134 return nt_status; 135 } 136 } 137 159 nt_status = create_local_token(auth_ntlmssp_state->server_info); 160 161 if (!NT_STATUS_IS_OK(nt_status)) { 162 DEBUG(10, ("create_local_token failed: %s\n", 163 nt_errstr(nt_status))); 164 return nt_status; 165 } 166 167 /* Clear out the session keys, and pass them to the caller. 168 * They will not be used in this form again - instead the 169 * NTLMSSP code will decide on the final correct session key, 170 * and put it back here at the end of 171 * auth_ntlmssp_steal_server_info */ 138 172 if (auth_ntlmssp_state->server_info->user_session_key.length) { 139 173 DEBUG(10, ("Got NT session key of length %u\n", 140 174 (unsigned int)auth_ntlmssp_state->server_info->user_session_key.length)); 141 *user_session_key = data_blob_talloc(auth_ntlmssp_state->mem_ctx,142 auth_ntlmssp_state->server_info->user_session_key.data,143 auth_ntlmssp_state->server_info->user_session_key.length);175 *user_session_key = auth_ntlmssp_state->server_info->user_session_key; 176 talloc_steal(mem_ctx, auth_ntlmssp_state->server_info->user_session_key.data); 177 auth_ntlmssp_state->server_info->user_session_key = data_blob_null; 144 178 } 145 179 if (auth_ntlmssp_state->server_info->lm_session_key.length) { 146 180 DEBUG(10, ("Got LM session key of length %u\n", 147 181 (unsigned int)auth_ntlmssp_state->server_info->lm_session_key.length)); 148 *lm_session_key = data_blob_talloc(auth_ntlmssp_state->mem_ctx,149 auth_ntlmssp_state->server_info->lm_session_key.data,150 auth_ntlmssp_state->server_info->lm_session_key.length);182 *lm_session_key = auth_ntlmssp_state->server_info->lm_session_key; 183 talloc_steal(mem_ctx, auth_ntlmssp_state->server_info->lm_session_key.data); 184 auth_ntlmssp_state->server_info->lm_session_key = data_blob_null; 151 185 } 152 186 return nt_status; 153 187 } 154 188 155 NTSTATUS auth_ntlmssp_start(AUTH_NTLMSSP_STATE **auth_ntlmssp_state) 189 static int auth_ntlmssp_state_destructor(void *ptr); 190 191 NTSTATUS auth_ntlmssp_start(struct auth_ntlmssp_state **auth_ntlmssp_state) 156 192 { 157 193 NTSTATUS nt_status; 158 TALLOC_CTX *mem_ctx; 159 160 mem_ctx = talloc_init("AUTH NTLMSSP context"); 161 162 *auth_ntlmssp_state = TALLOC_ZERO_P(mem_ctx, AUTH_NTLMSSP_STATE); 163 if (!*auth_ntlmssp_state) { 194 bool is_standalone; 195 const char *netbios_name; 196 const char *netbios_domain; 197 const char *dns_name; 198 char *dns_domain; 199 struct auth_ntlmssp_state *ans; 200 struct auth_context *auth_context; 201 202 if ((enum server_types)lp_server_role() == ROLE_STANDALONE) { 203 is_standalone = true; 204 } else { 205 is_standalone = false; 206 } 207 208 netbios_name = global_myname(); 209 netbios_domain = lp_workgroup(); 210 /* This should be a 'netbios domain -> DNS domain' mapping */ 211 dns_domain = get_mydnsdomname(talloc_tos()); 212 if (dns_domain) { 213 strlower_m(dns_domain); 214 } 215 dns_name = get_mydnsfullname(); 216 217 ans = talloc_zero(NULL, struct auth_ntlmssp_state); 218 if (!ans) { 164 219 DEBUG(0,("auth_ntlmssp_start: talloc failed!\n")); 165 talloc_destroy(mem_ctx);166 220 return NT_STATUS_NO_MEMORY; 167 221 } 168 222 169 ZERO_STRUCTP(*auth_ntlmssp_state); 170 171 (*auth_ntlmssp_state)->mem_ctx = mem_ctx; 172 173 if (!NT_STATUS_IS_OK(nt_status = ntlmssp_server_start(&(*auth_ntlmssp_state)->ntlmssp_state))) { 174 return nt_status; 175 } 176 177 if (!NT_STATUS_IS_OK(nt_status = make_auth_context_subsystem(&(*auth_ntlmssp_state)->auth_context))) { 178 return nt_status; 179 } 180 181 (*auth_ntlmssp_state)->ntlmssp_state->auth_context = (*auth_ntlmssp_state); 182 (*auth_ntlmssp_state)->ntlmssp_state->get_challenge = auth_ntlmssp_get_challenge; 183 (*auth_ntlmssp_state)->ntlmssp_state->may_set_challenge = auth_ntlmssp_may_set_challenge; 184 (*auth_ntlmssp_state)->ntlmssp_state->set_challenge = auth_ntlmssp_set_challenge; 185 (*auth_ntlmssp_state)->ntlmssp_state->check_password = auth_ntlmssp_check_password; 186 (*auth_ntlmssp_state)->ntlmssp_state->server_role = (enum server_types)lp_server_role(); 187 188 return NT_STATUS_OK; 189 } 190 191 void auth_ntlmssp_end(AUTH_NTLMSSP_STATE **auth_ntlmssp_state) 192 { 193 TALLOC_CTX *mem_ctx; 194 195 if (*auth_ntlmssp_state == NULL) { 196 return; 197 } 198 199 mem_ctx = (*auth_ntlmssp_state)->mem_ctx; 200 if ((*auth_ntlmssp_state)->ntlmssp_state) { 201 ntlmssp_end(&(*auth_ntlmssp_state)->ntlmssp_state); 202 } 203 if ((*auth_ntlmssp_state)->auth_context) { 204 ((*auth_ntlmssp_state)->auth_context->free)(&(*auth_ntlmssp_state)->auth_context); 205 } 206 if ((*auth_ntlmssp_state)->server_info) { 207 TALLOC_FREE((*auth_ntlmssp_state)->server_info); 208 } 209 talloc_destroy(mem_ctx); 210 *auth_ntlmssp_state = NULL; 211 } 212 213 NTSTATUS auth_ntlmssp_update(AUTH_NTLMSSP_STATE *auth_ntlmssp_state, 214 const DATA_BLOB request, DATA_BLOB *reply) 215 { 216 return ntlmssp_update(auth_ntlmssp_state->ntlmssp_state, request, reply); 217 } 223 nt_status = ntlmssp_server_start(ans, 224 is_standalone, 225 netbios_name, 226 netbios_domain, 227 dns_name, 228 dns_domain, 229 &ans->ntlmssp_state); 230 if (!NT_STATUS_IS_OK(nt_status)) { 231 return nt_status; 232 } 233 234 nt_status = make_auth_context_subsystem(talloc_tos(), &auth_context); 235 if (!NT_STATUS_IS_OK(nt_status)) { 236 return nt_status; 237 } 238 ans->auth_context = talloc_steal(ans, auth_context); 239 240 ans->ntlmssp_state->callback_private = ans; 241 ans->ntlmssp_state->get_challenge = auth_ntlmssp_get_challenge; 242 ans->ntlmssp_state->may_set_challenge = auth_ntlmssp_may_set_challenge; 243 ans->ntlmssp_state->set_challenge = auth_ntlmssp_set_challenge; 244 ans->ntlmssp_state->check_password = auth_ntlmssp_check_password; 245 246 talloc_set_destructor((TALLOC_CTX *)ans, auth_ntlmssp_state_destructor); 247 248 *auth_ntlmssp_state = ans; 249 return NT_STATUS_OK; 250 } 251 252 static int auth_ntlmssp_state_destructor(void *ptr) 253 { 254 struct auth_ntlmssp_state *ans; 255 256 ans = talloc_get_type(ptr, struct auth_ntlmssp_state); 257 258 TALLOC_FREE(ans->server_info); 259 TALLOC_FREE(ans->ntlmssp_state); 260 return 0; 261 } -
trunk/server/source3/auth/auth_sam.c
r480 r745 22 22 23 23 #include "includes.h" 24 #include " ../libcli/auth/libcli_auth.h"24 #include "auth.h" 25 25 26 26 #undef DBGC_CLASS 27 27 #define DBGC_CLASS DBGC_AUTH 28 28 29 /**************************************************************************** 30 Do a specific test for an smb password being correct, given a smb_password and 31 the lanman and NT responses. 32 ****************************************************************************/ 33 34 static NTSTATUS sam_password_ok(const struct auth_context *auth_context, 35 TALLOC_CTX *mem_ctx, 36 const char *username, 37 uint32_t acct_ctrl, 38 const uint8_t *lm_pw, 39 const uint8_t *nt_pw, 40 const auth_usersupplied_info *user_info, 41 DATA_BLOB *user_sess_key, 42 DATA_BLOB *lm_sess_key) 29 static NTSTATUS auth_sam_ignoredomain_auth(const struct auth_context *auth_context, 30 void *my_private_data, 31 TALLOC_CTX *mem_ctx, 32 const struct auth_usersupplied_info *user_info, 33 struct auth_serversupplied_info **server_info) 43 34 { 44 struct samr_Password _lm_hash, _nt_hash, _client_lm_hash, _client_nt_hash;45 struct samr_Password *lm_hash = NULL;46 struct samr_Password *nt_hash = NULL;47 struct samr_Password *client_lm_hash = NULL;48 struct samr_Password *client_nt_hash = NULL;49 50 *user_sess_key = data_blob_null;51 *lm_sess_key = data_blob_null;52 53 if (acct_ctrl & ACB_PWNOTREQ) {54 if (lp_null_passwords()) {55 DEBUG(3,("Account for user '%s' has no password and null passwords are allowed.\n", username));56 return NT_STATUS_OK;57 } else {58 DEBUG(3,("Account for user '%s' has no password and null passwords are NOT allowed.\n", username));59 return NT_STATUS_LOGON_FAILURE;60 }61 }62 63 if (lm_pw) {64 memcpy(_lm_hash.hash, lm_pw, sizeof(_lm_hash.hash));65 lm_hash = &_lm_hash;66 }67 if (nt_pw) {68 memcpy(_nt_hash.hash, nt_pw, sizeof(_nt_hash.hash));69 nt_hash = &_nt_hash;70 }71 if (user_info->lm_interactive_pwd.data && sizeof(_client_lm_hash.hash) == user_info->lm_interactive_pwd.length) {72 memcpy(_client_lm_hash.hash, user_info->lm_interactive_pwd.data, sizeof(_lm_hash.hash));73 client_lm_hash = &_client_lm_hash;74 }75 if (user_info->nt_interactive_pwd.data && sizeof(_client_nt_hash.hash) == user_info->nt_interactive_pwd.length) {76 memcpy(_client_nt_hash.hash, user_info->nt_interactive_pwd.data, sizeof(_nt_hash.hash));77 client_nt_hash = &_client_nt_hash;78 }79 80 if (client_lm_hash || client_nt_hash) {81 if (!nt_pw) {82 return NT_STATUS_WRONG_PASSWORD;83 }84 *user_sess_key = data_blob_talloc(mem_ctx, NULL, 16);85 if (!user_sess_key->data) {86 return NT_STATUS_NO_MEMORY;87 }88 SMBsesskeygen_ntv1(nt_pw, user_sess_key->data);89 return hash_password_check(mem_ctx, lp_lanman_auth(),90 client_lm_hash,91 client_nt_hash,92 username,93 lm_hash,94 nt_hash);95 } else {96 return ntlm_password_check(mem_ctx, lp_lanman_auth(),97 lp_ntlm_auth(),98 user_info->logon_parameters,99 &auth_context->challenge,100 &user_info->lm_resp, &user_info->nt_resp,101 username,102 user_info->smb_name,103 user_info->client_domain,104 lm_hash,105 nt_hash,106 user_sess_key, lm_sess_key);107 }108 }109 110 /****************************************************************************111 Check if a user is allowed to logon at this time. Note this is the112 servers local time, as logon hours are just specified as a weekly113 bitmask.114 ****************************************************************************/115 116 static bool logon_hours_ok(struct samu *sampass)117 {118 /* In logon hours first bit is Sunday from 12AM to 1AM */119 const uint8 *hours;120 struct tm *utctime;121 time_t lasttime;122 const char *asct;123 uint8 bitmask, bitpos;124 125 hours = pdb_get_hours(sampass);126 if (!hours) {127 DEBUG(5,("logon_hours_ok: No hours restrictions for user %s\n",pdb_get_username(sampass)));128 return True;129 }130 131 lasttime = time(NULL);132 utctime = gmtime(&lasttime);133 if (!utctime) {134 DEBUG(1, ("logon_hours_ok: failed to get gmtime. Failing logon for user %s\n",135 pdb_get_username(sampass) ));136 return False;137 }138 139 /* find the corresponding byte and bit */140 bitpos = (utctime->tm_wday * 24 + utctime->tm_hour) % 168;141 bitmask = 1 << (bitpos % 8);142 143 if (! (hours[bitpos/8] & bitmask)) {144 struct tm *t = localtime(&lasttime);145 if (!t) {146 asct = "INVALID TIME";147 } else {148 asct = asctime(t);149 if (!asct) {150 asct = "INVALID TIME";151 }152 }153 154 DEBUG(1, ("logon_hours_ok: Account for user %s not allowed to "155 "logon at this time (%s).\n",156 pdb_get_username(sampass), asct ));157 return False;158 }159 160 asct = asctime(utctime);161 DEBUG(5,("logon_hours_ok: user %s allowed to logon at this time (%s)\n",162 pdb_get_username(sampass), asct ? asct : "UNKNOWN TIME" ));163 164 return True;165 }166 167 /****************************************************************************168 Do a specific test for a struct samu being valid for this connection169 (ie not disabled, expired and the like).170 ****************************************************************************/171 172 static NTSTATUS sam_account_ok(TALLOC_CTX *mem_ctx,173 struct samu *sampass,174 const auth_usersupplied_info *user_info)175 {176 uint32 acct_ctrl = pdb_get_acct_ctrl(sampass);177 char *workstation_list;178 time_t kickoff_time;179 180 DEBUG(4,("sam_account_ok: Checking SMB password for user %s\n",pdb_get_username(sampass)));181 182 /* Quit if the account was disabled. */183 if (acct_ctrl & ACB_DISABLED) {184 DEBUG(1,("sam_account_ok: Account for user '%s' was disabled.\n", pdb_get_username(sampass)));185 return NT_STATUS_ACCOUNT_DISABLED;186 }187 188 /* Quit if the account was locked out. */189 if (acct_ctrl & ACB_AUTOLOCK) {190 DEBUG(1,("sam_account_ok: Account for user %s was locked out.\n", pdb_get_username(sampass)));191 return NT_STATUS_ACCOUNT_LOCKED_OUT;192 }193 194 /* Quit if the account is not allowed to logon at this time. */195 if (! logon_hours_ok(sampass)) {196 return NT_STATUS_INVALID_LOGON_HOURS;197 }198 199 /* Test account expire time */200 201 kickoff_time = pdb_get_kickoff_time(sampass);202 if (kickoff_time != 0 && time(NULL) > kickoff_time) {203 DEBUG(1,("sam_account_ok: Account for user '%s' has expired.\n", pdb_get_username(sampass)));204 DEBUG(3,("sam_account_ok: Account expired at '%ld' unix time.\n", (long)kickoff_time));205 return NT_STATUS_ACCOUNT_EXPIRED;206 }207 208 if (!(pdb_get_acct_ctrl(sampass) & ACB_PWNOEXP) && !(pdb_get_acct_ctrl(sampass) & ACB_PWNOTREQ)) {209 time_t must_change_time = pdb_get_pass_must_change_time(sampass);210 time_t last_set_time = pdb_get_pass_last_set_time(sampass);211 212 /* check for immediate expiry "must change at next logon"213 * for a user account. */214 if (((acct_ctrl & (ACB_WSTRUST|ACB_SVRTRUST)) == 0) && (last_set_time == 0)) {215 DEBUG(1,("sam_account_ok: Account for user '%s' password must change!\n", pdb_get_username(sampass)));216 return NT_STATUS_PASSWORD_MUST_CHANGE;217 }218 219 /* check for expired password */220 if (must_change_time < time(NULL) && must_change_time != 0) {221 DEBUG(1,("sam_account_ok: Account for user '%s' password expired!\n", pdb_get_username(sampass)));222 DEBUG(1,("sam_account_ok: Password expired at '%s' (%ld) unix time.\n", http_timestring(talloc_tos(), must_change_time), (long)must_change_time));223 return NT_STATUS_PASSWORD_EXPIRED;224 }225 }226 227 /* Test workstation. Workstation list is comma separated. */228 229 workstation_list = talloc_strdup(mem_ctx, pdb_get_workstations(sampass));230 if (!workstation_list)231 return NT_STATUS_NO_MEMORY;232 233 if (*workstation_list) {234 bool invalid_ws = True;235 char *tok = NULL;236 const char *s = workstation_list;237 char *machine_name = talloc_asprintf(mem_ctx, "%s$", user_info->wksta_name);238 239 if (machine_name == NULL)240 return NT_STATUS_NO_MEMORY;241 242 while (next_token_talloc(mem_ctx, &s, &tok, ",")) {243 DEBUG(10,("sam_account_ok: checking for workstation match %s and %s\n",244 tok, user_info->wksta_name));245 if(strequal(tok, user_info->wksta_name)) {246 invalid_ws = False;247 break;248 }249 if (tok[0] == '+') {250 DEBUG(10,("sam_account_ok: checking for workstation %s in group: %s\n",251 machine_name, tok + 1));252 if (user_in_group(machine_name, tok + 1)) {253 invalid_ws = False;254 break;255 }256 }257 TALLOC_FREE(tok);258 }259 TALLOC_FREE(tok);260 TALLOC_FREE(machine_name);261 262 if (invalid_ws)263 return NT_STATUS_INVALID_WORKSTATION;264 }265 266 if (acct_ctrl & ACB_DOMTRUST) {267 DEBUG(2,("sam_account_ok: Domain trust account %s denied by server\n", pdb_get_username(sampass)));268 return NT_STATUS_NOLOGON_INTERDOMAIN_TRUST_ACCOUNT;269 }270 271 if (acct_ctrl & ACB_SVRTRUST) {272 if (!(user_info->logon_parameters & MSV1_0_ALLOW_SERVER_TRUST_ACCOUNT)) {273 DEBUG(2,("sam_account_ok: Server trust account %s denied by server\n", pdb_get_username(sampass)));274 return NT_STATUS_NOLOGON_SERVER_TRUST_ACCOUNT;275 }276 }277 278 if (acct_ctrl & ACB_WSTRUST) {279 if (!(user_info->logon_parameters & MSV1_0_ALLOW_WORKSTATION_TRUST_ACCOUNT)) {280 DEBUG(2,("sam_account_ok: Wksta trust account %s denied by server\n", pdb_get_username(sampass)));281 return NT_STATUS_NOLOGON_WORKSTATION_TRUST_ACCOUNT;282 }283 }284 return NT_STATUS_OK;285 }286 287 /**288 * Check whether the given password is one of the last two289 * password history entries. If so, the bad pwcount should290 * not be incremented even thought the actual password check291 * failed.292 */293 static bool need_to_increment_bad_pw_count(294 const struct auth_context *auth_context,295 struct samu* sampass,296 const auth_usersupplied_info *user_info)297 {298 uint8_t i;299 const uint8_t *pwhistory;300 uint32_t pwhistory_len;301 uint32_t policy_pwhistory_len;302 uint32_t acct_ctrl;303 const char *username;304 TALLOC_CTX *mem_ctx = talloc_stackframe();305 bool result = true;306 307 pdb_get_account_policy(PDB_POLICY_PASSWORD_HISTORY,308 &policy_pwhistory_len);309 if (policy_pwhistory_len == 0) {310 goto done;311 }312 313 pwhistory = pdb_get_pw_history(sampass, &pwhistory_len);314 if (!pwhistory || pwhistory_len == 0) {315 goto done;316 }317 318 acct_ctrl = pdb_get_acct_ctrl(sampass);319 username = pdb_get_username(sampass);320 321 for (i=1; i < MIN(MIN(3, policy_pwhistory_len), pwhistory_len); i++) {322 static const uint8_t zero16[SALTED_MD5_HASH_LEN];323 const uint8_t *salt;324 const uint8_t *nt_pw;325 NTSTATUS status;326 DATA_BLOB user_sess_key = data_blob_null;327 DATA_BLOB lm_sess_key = data_blob_null;328 329 salt = &pwhistory[i*PW_HISTORY_ENTRY_LEN];330 nt_pw = salt + PW_HISTORY_SALT_LEN;331 332 if (memcmp(zero16, nt_pw, NT_HASH_LEN) == 0) {333 /* skip zero password hash */334 continue;335 }336 337 if (memcmp(zero16, salt, PW_HISTORY_SALT_LEN) != 0) {338 /* skip nonzero salt (old format entry) */339 continue;340 }341 342 status = sam_password_ok(auth_context, mem_ctx,343 username, acct_ctrl, NULL, nt_pw,344 user_info, &user_sess_key, &lm_sess_key);345 if (NT_STATUS_IS_OK(status)) {346 result = false;347 break;348 }349 }350 351 done:352 TALLOC_FREE(mem_ctx);353 return result;354 }355 356 /****************************************************************************357 check if a username/password is OK assuming the password is a 24 byte358 SMB hash supplied in the user_info structure359 return an NT_STATUS constant.360 ****************************************************************************/361 362 static NTSTATUS check_sam_security(const struct auth_context *auth_context,363 void *my_private_data,364 TALLOC_CTX *mem_ctx,365 const auth_usersupplied_info *user_info,366 auth_serversupplied_info **server_info)367 {368 struct samu *sampass=NULL;369 bool ret;370 NTSTATUS nt_status;371 NTSTATUS update_login_attempts_status;372 DATA_BLOB user_sess_key = data_blob_null;373 DATA_BLOB lm_sess_key = data_blob_null;374 bool updated_autolock = False, updated_badpw = False;375 const char *username;376 const uint8_t *nt_pw;377 const uint8_t *lm_pw;378 379 35 if (!user_info || !auth_context) { 380 36 return NT_STATUS_UNSUCCESSFUL; 381 37 } 382 383 /* the returned struct gets kept on the server_info, by means 384 of a steal further down */ 385 386 sampass = samu_new(mem_ctx); 387 if (sampass == NULL) { 388 return NT_STATUS_NO_MEMORY; 389 } 390 391 /* get the account information */ 392 393 become_root(); 394 ret = pdb_getsampwnam(sampass, user_info->internal_username); 395 unbecome_root(); 396 397 if (ret == False) { 398 DEBUG(3,("check_sam_security: Couldn't find user '%s' in " 399 "passdb.\n", user_info->internal_username)); 400 TALLOC_FREE(sampass); 401 return NT_STATUS_NO_SUCH_USER; 402 } 403 404 username = pdb_get_username(sampass); 405 nt_pw = pdb_get_nt_passwd(sampass); 406 lm_pw = pdb_get_lanman_passwd(sampass); 407 408 /* see if autolock flag needs to be updated */ 409 if (pdb_get_acct_ctrl(sampass) & ACB_NORMAL) 410 pdb_update_autolock_flag(sampass, &updated_autolock); 411 /* Quit if the account was locked out. */ 412 if (pdb_get_acct_ctrl(sampass) & ACB_AUTOLOCK) { 413 DEBUG(3,("check_sam_security: Account for user %s was locked out.\n", username)); 414 return NT_STATUS_ACCOUNT_LOCKED_OUT; 415 } 416 417 nt_status = sam_password_ok(auth_context, mem_ctx, 418 username, pdb_get_acct_ctrl(sampass), lm_pw, nt_pw, 419 user_info, &user_sess_key, &lm_sess_key); 420 421 /* Notify passdb backend of login success/failure. If not 422 NT_STATUS_OK the backend doesn't like the login */ 423 424 update_login_attempts_status = pdb_update_login_attempts(sampass, NT_STATUS_IS_OK(nt_status)); 425 426 if (!NT_STATUS_IS_OK(nt_status)) { 427 bool increment_bad_pw_count = false; 428 429 if (NT_STATUS_EQUAL(nt_status,NT_STATUS_WRONG_PASSWORD) && 430 pdb_get_acct_ctrl(sampass) & ACB_NORMAL && 431 NT_STATUS_IS_OK(update_login_attempts_status)) 432 { 433 increment_bad_pw_count = 434 need_to_increment_bad_pw_count(auth_context, 435 sampass, 436 user_info); 437 } 438 439 if (increment_bad_pw_count) { 440 pdb_increment_bad_password_count(sampass); 441 updated_badpw = True; 442 } else { 443 pdb_update_bad_password_count(sampass, 444 &updated_badpw); 445 } 446 if (updated_autolock || updated_badpw){ 447 NTSTATUS status; 448 449 become_root(); 450 status = pdb_update_sam_account(sampass); 451 unbecome_root(); 452 453 if (!NT_STATUS_IS_OK(status)) { 454 DEBUG(1, ("Failed to modify entry: %s\n", 455 nt_errstr(status))); 456 } 457 } 458 goto done; 459 } 460 461 if ((pdb_get_acct_ctrl(sampass) & ACB_NORMAL) && 462 (pdb_get_bad_password_count(sampass) > 0)){ 463 pdb_set_bad_password_count(sampass, 0, PDB_CHANGED); 464 pdb_set_bad_password_time(sampass, 0, PDB_CHANGED); 465 updated_badpw = True; 466 } 467 468 if (updated_autolock || updated_badpw){ 469 NTSTATUS status; 470 471 become_root(); 472 status = pdb_update_sam_account(sampass); 473 unbecome_root(); 474 475 if (!NT_STATUS_IS_OK(status)) { 476 DEBUG(1, ("Failed to modify entry: %s\n", 477 nt_errstr(status))); 478 } 479 } 480 481 nt_status = sam_account_ok(mem_ctx, sampass, user_info); 482 483 if (!NT_STATUS_IS_OK(nt_status)) { 484 goto done; 485 } 486 487 become_root(); 488 nt_status = make_server_info_sam(server_info, sampass); 489 unbecome_root(); 490 sampass = NULL; 491 492 if (!NT_STATUS_IS_OK(nt_status)) { 493 DEBUG(0,("check_sam_security: make_server_info_sam() failed with '%s'\n", nt_errstr(nt_status))); 494 goto done; 495 } 496 497 (*server_info)->user_session_key = 498 data_blob_talloc(*server_info, user_sess_key.data, 499 user_sess_key.length); 500 data_blob_free(&user_sess_key); 501 502 (*server_info)->lm_session_key = 503 data_blob_talloc(*server_info, lm_sess_key.data, 504 lm_sess_key.length); 505 data_blob_free(&lm_sess_key); 506 507 (*server_info)->nss_token |= user_info->was_mapped; 508 509 done: 510 TALLOC_FREE(sampass); 511 data_blob_free(&user_sess_key); 512 data_blob_free(&lm_sess_key); 513 return nt_status; 38 return check_sam_security(&auth_context->challenge, mem_ctx, 39 user_info, server_info); 514 40 } 515 41 … … 517 43 static NTSTATUS auth_init_sam_ignoredomain(struct auth_context *auth_context, const char *param, auth_methods **auth_method) 518 44 { 519 if (!make_auth_methods(auth_context, auth_method)) { 45 struct auth_methods *result; 46 47 result = TALLOC_ZERO_P(auth_context, struct auth_methods); 48 if (result == NULL) { 520 49 return NT_STATUS_NO_MEMORY; 521 50 } 51 result->auth = auth_sam_ignoredomain_auth; 52 result->name = "sam_ignoredomain"; 522 53 523 (*auth_method)->auth = check_sam_security; 524 (*auth_method)->name = "sam_ignoredomain"; 54 *auth_method = result; 525 55 return NT_STATUS_OK; 526 56 } … … 531 61 ****************************************************************************/ 532 62 533 static NTSTATUS check_samstrict_security(const struct auth_context *auth_context,534 void *my_private_data,535 536 const auth_usersupplied_info *user_info,537 63 static NTSTATUS auth_samstrict_auth(const struct auth_context *auth_context, 64 void *my_private_data, 65 TALLOC_CTX *mem_ctx, 66 const struct auth_usersupplied_info *user_info, 67 struct auth_serversupplied_info **server_info) 538 68 { 539 69 bool is_local_name, is_my_domain; … … 543 73 } 544 74 545 is_local_name = is_myname(user_info->domain); 546 is_my_domain = strequal(user_info->domain, lp_workgroup()); 75 DEBUG(10, ("Check auth for: [%s]\n", user_info->mapped.account_name)); 76 77 is_local_name = is_myname(user_info->mapped.domain_name); 78 is_my_domain = strequal(user_info->mapped.domain_name, lp_workgroup()); 547 79 548 80 /* check whether or not we service this domain/workgroup name */ … … 553 85 if ( !is_local_name ) { 554 86 DEBUG(6,("check_samstrict_security: %s is not one of my local names (%s)\n", 555 user_info-> domain, (lp_server_role() == ROLE_DOMAIN_MEMBER87 user_info->mapped.domain_name, (lp_server_role() == ROLE_DOMAIN_MEMBER 556 88 ? "ROLE_DOMAIN_MEMBER" : "ROLE_STANDALONE") )); 557 89 return NT_STATUS_NOT_IMPLEMENTED; … … 561 93 if ( !is_local_name && !is_my_domain ) { 562 94 DEBUG(6,("check_samstrict_security: %s is not one of my local names or domain name (DC)\n", 563 user_info-> domain));95 user_info->mapped.domain_name)); 564 96 return NT_STATUS_NOT_IMPLEMENTED; 565 97 } … … 568 100 } 569 101 570 return check_sam_security(auth_context, my_private_data, mem_ctx, user_info, server_info); 102 return check_sam_security(&auth_context->challenge, mem_ctx, 103 user_info, server_info); 571 104 } 572 105 … … 574 107 static NTSTATUS auth_init_sam(struct auth_context *auth_context, const char *param, auth_methods **auth_method) 575 108 { 576 if (!make_auth_methods(auth_context, auth_method)) { 109 struct auth_methods *result; 110 111 result = TALLOC_ZERO_P(auth_context, struct auth_methods); 112 if (result == NULL) { 577 113 return NT_STATUS_NO_MEMORY; 578 114 } 115 result->auth = auth_samstrict_auth; 116 result->name = "sam"; 579 117 580 (*auth_method)->auth = check_samstrict_security; 581 (*auth_method)->name = "sam"; 118 *auth_method = result; 582 119 return NT_STATUS_OK; 583 120 } -
trunk/server/source3/auth/auth_script.c
r414 r745 5 5 6 6 Copyright (C) Jeremy Allison 2005. 7 7 8 8 This program is free software; you can redistribute it and/or modify 9 9 it under the terms of the GNU General Public License as published by 10 10 the Free Software Foundation; either version 3 of the License, or 11 11 (at your option) any later version. 12 12 13 13 This program is distributed in the hope that it will be useful, 14 14 but WITHOUT ANY WARRANTY; without even the implied warranty of 15 15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 16 GNU General Public License for more details. 17 17 18 18 You should have received a copy of the GNU General Public License 19 19 along with this program. If not, see <http://www.gnu.org/licenses/>. … … 21 21 22 22 #include "includes.h" 23 #include "auth.h" 23 24 24 25 #undef malloc … … 41 42 void *my_private_data, 42 43 TALLOC_CTX *mem_ctx, 43 const auth_usersupplied_info *user_info,44 auth_serversupplied_info **server_info)44 const struct auth_usersupplied_info *user_info, 45 struct auth_serversupplied_info **server_info) 45 46 { 46 47 const char *script = lp_parm_const_string( GLOBAL_SECTION_SNUM, "auth_script", "script", NULL); … … 63 64 } 64 65 65 secret_str_len = strlen(user_info-> domain) + 1 +66 strlen(user_info-> smb_name) + 1 +66 secret_str_len = strlen(user_info->mapped.domain_name) + 1 + 67 strlen(user_info->client.account_name) + 1 + 67 68 16 + 1 + /* 8 bytes of challenge going to 16 */ 68 69 48 + 1 + /* 24 bytes of challenge going to 48 */ … … 74 75 } 75 76 76 safe_strcpy( secret_str, user_info-> domain, secret_str_len - 1);77 safe_strcpy( secret_str, user_info->mapped.domain_name, secret_str_len - 1); 77 78 safe_strcat( secret_str, "\n", secret_str_len - 1); 78 safe_strcat( secret_str, user_info-> smb_name, secret_str_len - 1);79 safe_strcat( secret_str, user_info->client.account_name, secret_str_len - 1); 79 80 safe_strcat( secret_str, "\n", secret_str_len - 1); 80 81 … … 85 86 safe_strcat( secret_str, "\n", secret_str_len - 1); 86 87 87 if (user_info-> lm_resp.data) {88 if (user_info->password.response.lanman.data) { 88 89 for (i = 0; i < 24; i++) { 89 slprintf(&hex_str[i*2], 3, "%02X", user_info-> lm_resp.data[i]);90 slprintf(&hex_str[i*2], 3, "%02X", user_info->password.response.lanman.data[i]); 90 91 } 91 92 safe_strcat( secret_str, hex_str, secret_str_len - 1); … … 93 94 safe_strcat( secret_str, "\n", secret_str_len - 1); 94 95 95 if (user_info-> nt_resp.data) {96 if (user_info->password.response.nt.data) { 96 97 for (i = 0; i < 24; i++) { 97 slprintf(&hex_str[i*2], 3, "%02X", user_info-> nt_resp.data[i]);98 slprintf(&hex_str[i*2], 3, "%02X", user_info->password.response.nt.data[i]); 98 99 } 99 100 safe_strcat( secret_str, hex_str, secret_str_len - 1); … … 110 111 if (ret) { 111 112 DEBUG(1,("script_check_user_credentials: failed to authenticate %s\\%s\n", 112 user_info-> domain, user_info->smb_name ));113 user_info->mapped.domain_name, user_info->client.account_name )); 113 114 /* auth failed. */ 114 115 return NT_STATUS_NO_SUCH_USER; … … 122 123 static NTSTATUS auth_init_script(struct auth_context *auth_context, const char *param, auth_methods **auth_method) 123 124 { 124 if (!make_auth_methods(auth_context, auth_method)) { 125 struct auth_methods *result; 126 127 result = TALLOC_ZERO_P(auth_context, struct auth_methods); 128 if (result == NULL) { 125 129 return NT_STATUS_NO_MEMORY; 126 130 } 127 128 (*auth_method)->name = "script"; 129 (*auth_method)->auth = script_check_user_credentials; 131 result->name = "script"; 132 result->auth = script_check_user_credentials; 130 133 131 134 if (param && *param) { … … 136 139 return NT_STATUS_UNSUCCESSFUL; 137 140 } 138 (*auth_method)->private_data = (void *)priv;141 result->private_data = (void *)priv; 139 142 } 143 144 *auth_method = result; 140 145 return NT_STATUS_OK; 141 146 } -
trunk/server/source3/auth/auth_server.c
r414 r745 9 9 the Free Software Foundation; either version 3 of the License, or 10 10 (at your option) any later version. 11 11 12 12 This program is distributed in the hope that it will be useful, 13 13 but WITHOUT ANY WARRANTY; without even the implied warranty of 14 14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 15 GNU General Public License for more details. 16 16 17 17 You should have received a copy of the GNU General Public License 18 18 along with this program. If not, see <http://www.gnu.org/licenses/>. … … 20 20 21 21 #include "includes.h" 22 #include "auth.h" 23 #include "system/passwd.h" 24 #include "smbd/smbd.h" 25 #include "libsmb/libsmb.h" 22 26 23 27 #undef DBGC_CLASS … … 136 140 */ 137 141 138 if (!NT_STATUS_IS_OK(cli_session_setup(cli, "", "", 0, "", 0,139 ""))) {142 status = cli_session_setup(cli, "", "", 0, "", 0, ""); 143 if (!NT_STATUS_IS_OK(status)) { 140 144 TALLOC_FREE(mutex); 141 145 DEBUG(0,("%s rejected the initial session setup (%s)\n", 142 desthost, cli_errstr(cli)));146 desthost, nt_errstr(status))); 143 147 cli_shutdown(cli); 144 148 return NULL; … … 207 211 interval.tv_usec = 0; 208 212 209 if (event_add_idle(s mbd_event_context(), result, interval,213 if (event_add_idle(server_event_context(), result, interval, 210 214 "server_security_keepalive", 211 215 send_server_keepalive, … … 229 233 { 230 234 struct cli_state *cli = server_cryptkey(mem_ctx); 231 235 232 236 if (cli) { 233 237 DEBUG(3,("using password server validation\n")); … … 237 241 unless 'encrypt passwords = no' */ 238 242 DEBUG(5,("make_auth_info_server: Server is unencrypted, no challenge available..\n")); 239 243 240 244 /* However, it is still a perfectly fine connection 241 245 to pass that unencrypted password over */ … … 256 260 /* The return must be allocated on the caller's mem_ctx, as our own will be 257 261 destoyed just after the call. */ 258 return data_blob_talloc( auth_context->mem_ctx, cli->secblob.data,8);262 return data_blob_talloc((TALLOC_CTX *)auth_context, cli->secblob.data,8); 259 263 } else { 260 264 return data_blob_null; … … 271 275 void *my_private_data, 272 276 TALLOC_CTX *mem_ctx, 273 const auth_usersupplied_info *user_info, 274 auth_serversupplied_info **server_info) 275 { 276 struct server_security_state *state = talloc_get_type_abort( 277 my_private_data, struct server_security_state); 278 struct cli_state *cli; 277 const struct auth_usersupplied_info *user_info, 278 struct auth_serversupplied_info **server_info) 279 { 280 struct server_security_state *state = NULL; 281 struct cli_state *cli = NULL; 279 282 static bool tested_password_server = False; 280 283 static bool bad_password_server = False; … … 282 285 bool locally_made_cli = False; 283 286 287 DEBUG(10, ("check_smbserver_security: Check auth for: [%s]\n", 288 user_info->mapped.account_name)); 289 290 if (my_private_data == NULL) { 291 DEBUG(10,("check_smbserver_security: " 292 "password server is not connected\n")); 293 return NT_STATUS_LOGON_FAILURE; 294 } 295 296 state = talloc_get_type_abort(my_private_data, struct server_security_state); 284 297 cli = state->cli; 285 298 286 299 if (cli) { 287 300 } else { … … 294 307 return NT_STATUS_LOGON_FAILURE; 295 308 } 296 309 297 310 if ((cli->sec_mode & NEGOTIATE_SECURITY_CHALLENGE_RESPONSE) == 0) { 298 if (user_info-> encrypted) {311 if (user_info->password_state != AUTH_PASSWORD_PLAIN) { 299 312 DEBUG(1,("password server %s is plaintext, but we are encrypted. This just can't work :-(\n", cli->desthost)); 300 313 return NT_STATUS_LOGON_FAILURE; … … 325 338 memset(badpass, 0x1f, sizeof(badpass)); 326 339 327 if((user_info-> nt_resp.length == sizeof(badpass)) &&328 !memcmp(badpass, user_info-> nt_resp.data, sizeof(badpass))) {340 if((user_info->password.response.nt.length == sizeof(badpass)) && 341 !memcmp(badpass, user_info->password.response.nt.data, sizeof(badpass))) { 329 342 /* 330 343 * Very unlikely, our random bad password is the same as the users … … 347 360 (char *)badpass, 348 361 sizeof(badpass), 349 user_info-> domain))) {362 user_info->mapped.domain_name))) { 350 363 351 364 /* … … 390 403 * not guest enabled, we can try with the real password. 391 404 */ 392 393 if (!user_info->encrypted) {405 switch (user_info->password_state) { 406 case AUTH_PASSWORD_PLAIN: 394 407 /* Plaintext available */ 395 408 nt_status = cli_session_setup( 396 cli, user_info->smb_name, 397 (char *)user_info->plaintext_password.data, 398 user_info->plaintext_password.length, 399 NULL, 0, user_info->domain); 400 401 } else { 409 cli, user_info->client.account_name, 410 user_info->password.plaintext, 411 strlen(user_info->password.plaintext), 412 NULL, 0, user_info->mapped.domain_name); 413 break; 414 415 /* currently the hash values include a challenge-response as well */ 416 case AUTH_PASSWORD_HASH: 417 case AUTH_PASSWORD_RESPONSE: 402 418 nt_status = cli_session_setup( 403 cli, user_info->smb_name, 404 (char *)user_info->lm_resp.data, 405 user_info->lm_resp.length, 406 (char *)user_info->nt_resp.data, 407 user_info->nt_resp.length, 408 user_info->domain); 419 cli, user_info->client.account_name, 420 (char *)user_info->password.response.lanman.data, 421 user_info->password.response.lanman.length, 422 (char *)user_info->password.response.nt.data, 423 user_info->password.response.nt.length, 424 user_info->mapped.domain_name); 425 break; 426 default: 427 DEBUG(0,("user_info constructed for user '%s' was invalid - password_state=%u invalid.\n",user_info->mapped.account_name, user_info->password_state)); 428 nt_status = NT_STATUS_INTERNAL_ERROR; 409 429 } 410 430 … … 415 435 416 436 /* if logged in as guest then reject */ 417 if ( (SVAL(cli->inbuf,smb_vwv2) & 1) != 0) {437 if (cli->is_guestlogin) { 418 438 DEBUG(1,("password server %s gave us guest only\n", cli->desthost)); 419 439 nt_status = NT_STATUS_LOGON_FAILURE; … … 423 443 424 444 if (NT_STATUS_IS_OK(nt_status)) { 425 fstring real_username;426 struct passwd *pass ;427 428 if ( (pass = smb_getpwnam( NULL, user_info->internal_username,429 real_username, True )) != NULL )445 char *real_username = NULL; 446 struct passwd *pass = NULL; 447 448 if ( (pass = smb_getpwnam(talloc_tos(), user_info->mapped.account_name, 449 &real_username, True )) != NULL ) 430 450 { 431 /* if a real user check pam account restrictions */ 432 /* only really perfomed if "obey pam restriction" is true */ 433 nt_status = smb_pam_accountcheck(pass->pw_name); 434 if ( !NT_STATUS_IS_OK(nt_status)) { 435 DEBUG(1, ("PAM account restriction prevents user login\n")); 436 } else { 437 438 nt_status = make_server_info_pw(server_info, pass->pw_name, pass); 439 } 451 nt_status = make_server_info_pw(server_info, pass->pw_name, pass); 440 452 TALLOC_FREE(pass); 453 TALLOC_FREE(real_username); 441 454 } 442 455 else … … 455 468 static NTSTATUS auth_init_smbserver(struct auth_context *auth_context, const char* param, auth_methods **auth_method) 456 469 { 457 if (!make_auth_methods(auth_context, auth_method)) { 470 struct auth_methods *result; 471 472 result = TALLOC_ZERO_P(auth_context, struct auth_methods); 473 if (result == NULL) { 458 474 return NT_STATUS_NO_MEMORY; 459 475 } 460 (*auth_method)->name = "smbserver"; 461 (*auth_method)->auth = check_smbserver_security; 462 (*auth_method)->get_chal = auth_get_challenge_server; 476 result->name = "smbserver"; 477 result->auth = check_smbserver_security; 478 result->get_chal = auth_get_challenge_server; 479 480 *auth_method = result; 463 481 return NT_STATUS_OK; 464 482 } -
trunk/server/source3/auth/auth_unix.c
r414 r745 3 3 Password and authentication handling 4 4 Copyright (C) Andrew Bartlett 2001 5 5 6 6 This program is free software; you can redistribute it and/or modify 7 7 it under the terms of the GNU General Public License as published by 8 8 the Free Software Foundation; either version 3 of the License, or 9 9 (at your option) any later version. 10 10 11 11 This program is distributed in the hope that it will be useful, 12 12 but WITHOUT ANY WARRANTY; without even the implied warranty of 13 13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 14 GNU General Public License for more details. 15 15 16 16 You should have received a copy of the GNU General Public License 17 17 along with this program. If not, see <http://www.gnu.org/licenses/>. … … 19 19 20 20 #include "includes.h" 21 #include "auth.h" 22 #include "system/passwd.h" 23 #include "smbd/globals.h" 21 24 22 25 #undef DBGC_CLASS 23 26 #define DBGC_CLASS DBGC_AUTH 24 25 /**26 * update the encrypted smbpasswd file from the plaintext username and password27 *28 * this ugly hack needs to die, but not quite yet, I think people still use it...29 **/30 static bool update_smbpassword_file(const char *user, const char *password)31 {32 struct samu *sampass;33 bool ret;34 35 if ( !(sampass = samu_new( NULL )) ) {36 return False;37 }38 39 become_root();40 ret = pdb_getsampwnam(sampass, user);41 unbecome_root();42 43 if(ret == False) {44 DEBUG(0,("pdb_getsampwnam returned NULL\n"));45 TALLOC_FREE(sampass);46 return False;47 }48 49 /*50 * Remove the account disabled flag - we are updating the51 * users password from a login.52 */53 if (!pdb_set_acct_ctrl(sampass, pdb_get_acct_ctrl(sampass) & ~ACB_DISABLED, PDB_CHANGED)) {54 TALLOC_FREE(sampass);55 return False;56 }57 58 if (!pdb_set_plaintext_passwd (sampass, password)) {59 TALLOC_FREE(sampass);60 return False;61 }62 63 /* Now write it into the file. */64 become_root();65 66 ret = NT_STATUS_IS_OK(pdb_update_sam_account (sampass));67 68 unbecome_root();69 70 if (ret) {71 DEBUG(3,("pdb_update_sam_account returned %d\n",ret));72 }73 74 TALLOC_FREE(sampass);75 return ret;76 }77 78 27 79 28 /** Check a plaintext username/password … … 86 35 void *my_private_data, 87 36 TALLOC_CTX *mem_ctx, 88 const auth_usersupplied_info *user_info,89 auth_serversupplied_info **server_info)37 const struct auth_usersupplied_info *user_info, 38 struct auth_serversupplied_info **server_info) 90 39 { 91 40 NTSTATUS nt_status; 92 41 struct passwd *pass = NULL; 93 42 43 DEBUG(10, ("Check auth for: [%s]\n", user_info->mapped.account_name)); 44 94 45 become_root(); 95 pass = Get_Pwnam_alloc(talloc_tos(), user_info-> internal_username);46 pass = Get_Pwnam_alloc(talloc_tos(), user_info->mapped.account_name); 96 47 97 98 48 /** @todo This call assumes a ASCII password, no charset transformation is 99 49 done. We may need to revisit this **/ 100 50 nt_status = pass_check(pass, 101 pass ? pass->pw_name : user_info->internal_username, 102 (char *)user_info->plaintext_password.data, 103 user_info->plaintext_password.length-1, 104 lp_update_encrypted() ? 105 update_smbpassword_file : NULL, 106 True); 107 51 pass ? pass->pw_name : user_info->mapped.account_name, 52 smbd_server_conn->client_id.name, 53 user_info->password.plaintext, 54 true); 55 108 56 unbecome_root(); 109 57 110 58 if (NT_STATUS_IS_OK(nt_status)) { 111 59 if (pass) { 112 /* if a real user check pam account restrictions */ 113 /* only really perfomed if "obey pam restriction" is true */ 114 nt_status = smb_pam_accountcheck(pass->pw_name); 115 if ( !NT_STATUS_IS_OK(nt_status)) { 116 DEBUG(1, ("PAM account restriction prevents user login\n")); 117 } else { 118 make_server_info_pw(server_info, pass->pw_name, pass); 119 } 60 make_server_info_pw(server_info, pass->pw_name, pass); 120 61 } else { 121 62 /* we need to do somthing more useful here */ … … 131 72 static NTSTATUS auth_init_unix(struct auth_context *auth_context, const char* param, auth_methods **auth_method) 132 73 { 133 if (!make_auth_methods(auth_context, auth_method)) { 74 struct auth_methods *result; 75 76 result = TALLOC_ZERO_P(auth_context, struct auth_methods); 77 if (result == NULL) { 134 78 return NT_STATUS_NO_MEMORY; 135 79 } 80 result->name = "unix"; 81 result->auth = check_unix_security; 136 82 137 (*auth_method)->name = "unix"; 138 (*auth_method)->auth = check_unix_security; 83 *auth_method = result; 139 84 return NT_STATUS_OK; 140 85 } -
trunk/server/source3/auth/auth_util.c
r596 r745 12 12 the Free Software Foundation; either version 3 of the License, or 13 13 (at your option) any later version. 14 14 15 15 This program is distributed in the hope that it will be useful, 16 16 but WITHOUT ANY WARRANTY; without even the implied warranty of 17 17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 18 GNU General Public License for more details. 19 19 20 20 You should have received a copy of the GNU General Public License 21 21 along with this program. If not, see <http://www.gnu.org/licenses/>. … … 23 23 24 24 #include "includes.h" 25 #include " smbd/globals.h"25 #include "auth.h" 26 26 #include "../libcli/auth/libcli_auth.h" 27 #include "../lib/crypto/arcfour.h" 28 #include "rpc_client/init_lsa.h" 29 #include "../libcli/security/security.h" 30 #include "../lib/util/util_pw.h" 31 #include "lib/winbind_util.h" 32 #include "passdb.h" 27 33 28 34 #undef DBGC_CLASS 29 35 #define DBGC_CLASS DBGC_AUTH 30 31 /****************************************************************************32 Ensure primary group SID is always at position 0 in a33 auth_serversupplied_info struct.34 ****************************************************************************/35 36 static void sort_sid_array_for_smbd(auth_serversupplied_info *result,37 const DOM_SID *pgroup_sid)38 {39 unsigned int i;40 41 if (!result->sids) {42 return;43 }44 45 if (sid_compare(&result->sids[0], pgroup_sid)==0) {46 return;47 }48 49 for (i = 1; i < result->num_sids; i++) {50 if (sid_compare(pgroup_sid,51 &result->sids[i]) == 0) {52 sid_copy(&result->sids[i], &result->sids[0]);53 sid_copy(&result->sids[0], pgroup_sid);54 return;55 }56 }57 }58 36 59 37 /**************************************************************************** … … 105 83 106 84 /**************************************************************************** 107 Create an auth_usersupplied_data structure108 ****************************************************************************/109 110 static NTSTATUS make_user_info(auth_usersupplied_info **user_info,111 const char *smb_name,112 const char *internal_username,113 const char *client_domain,114 const char *domain,115 const char *wksta_name,116 DATA_BLOB *lm_pwd, DATA_BLOB *nt_pwd,117 DATA_BLOB *lm_interactive_pwd, DATA_BLOB *nt_interactive_pwd,118 DATA_BLOB *plaintext,119 bool encrypted)120 {121 122 DEBUG(5,("attempting to make a user_info for %s (%s)\n", internal_username, smb_name));123 124 *user_info = SMB_MALLOC_P(auth_usersupplied_info);125 if (*user_info == NULL) {126 DEBUG(0,("malloc failed for user_info (size %lu)\n", (unsigned long)sizeof(*user_info)));127 return NT_STATUS_NO_MEMORY;128 }129 130 ZERO_STRUCTP(*user_info);131 132 DEBUG(5,("making strings for %s's user_info struct\n", internal_username));133 134 (*user_info)->smb_name = SMB_STRDUP(smb_name);135 if ((*user_info)->smb_name == NULL) {136 free_user_info(user_info);137 return NT_STATUS_NO_MEMORY;138 }139 140 (*user_info)->internal_username = SMB_STRDUP(internal_username);141 if ((*user_info)->internal_username == NULL) {142 free_user_info(user_info);143 return NT_STATUS_NO_MEMORY;144 }145 146 (*user_info)->domain = SMB_STRDUP(domain);147 if ((*user_info)->domain == NULL) {148 free_user_info(user_info);149 return NT_STATUS_NO_MEMORY;150 }151 152 (*user_info)->client_domain = SMB_STRDUP(client_domain);153 if ((*user_info)->client_domain == NULL) {154 free_user_info(user_info);155 return NT_STATUS_NO_MEMORY;156 }157 158 (*user_info)->wksta_name = SMB_STRDUP(wksta_name);159 if ((*user_info)->wksta_name == NULL) {160 free_user_info(user_info);161 return NT_STATUS_NO_MEMORY;162 }163 164 DEBUG(5,("making blobs for %s's user_info struct\n", internal_username));165 166 if (lm_pwd)167 (*user_info)->lm_resp = data_blob(lm_pwd->data, lm_pwd->length);168 if (nt_pwd)169 (*user_info)->nt_resp = data_blob(nt_pwd->data, nt_pwd->length);170 if (lm_interactive_pwd)171 (*user_info)->lm_interactive_pwd = data_blob(lm_interactive_pwd->data, lm_interactive_pwd->length);172 if (nt_interactive_pwd)173 (*user_info)->nt_interactive_pwd = data_blob(nt_interactive_pwd->data, nt_interactive_pwd->length);174 175 if (plaintext)176 (*user_info)->plaintext_password = data_blob(plaintext->data, plaintext->length);177 178 (*user_info)->encrypted = encrypted;179 180 (*user_info)->logon_parameters = 0;181 182 DEBUG(10,("made an %sencrypted user_info for %s (%s)\n", encrypted ? "":"un" , internal_username, smb_name));183 184 return NT_STATUS_OK;185 }186 187 /****************************************************************************188 85 Create an auth_usersupplied_data structure after appropriate mapping. 189 86 ****************************************************************************/ 190 87 191 NTSTATUS make_user_info_map( auth_usersupplied_info **user_info,88 NTSTATUS make_user_info_map(struct auth_usersupplied_info **user_info, 192 89 const char *smb_name, 193 90 const char *client_domain, 194 const char *w ksta_name,91 const char *workstation_name, 195 92 DATA_BLOB *lm_pwd, 196 93 DATA_BLOB *nt_pwd, 197 DATA_BLOB *lm_interactive_pwd, 198 DATA_BLOB *nt_interactive_pwd, 199 DATA_BLOB *plaintext, 200 bool encrypted) 201 { 202 struct smbd_server_connection *sconn = smbd_server_conn; 94 const struct samr_Password *lm_interactive_pwd, 95 const struct samr_Password *nt_interactive_pwd, 96 const char *plaintext, 97 enum auth_password_state password_state) 98 { 203 99 const char *domain; 204 100 NTSTATUS result; 205 101 bool was_mapped; 206 fstring internal_username; 207 fstrcpy(internal_username, smb_name); 208 was_mapped = map_username(sconn, internal_username); 102 char *internal_username = NULL; 103 104 was_mapped = map_username(talloc_tos(), smb_name, &internal_username); 105 if (!internal_username) { 106 return NT_STATUS_NO_MEMORY; 107 } 209 108 210 109 DEBUG(5, ("Mapping user [%s]\\[%s] from workstation [%s]\n", 211 client_domain, smb_name, w ksta_name));110 client_domain, smb_name, workstation_name)); 212 111 213 112 domain = client_domain; … … 230 129 DEBUG(5, ("Mapped domain from [%s] to [%s] for user [%s] from " 231 130 "workstation [%s]\n", 232 client_domain, domain, smb_name, w ksta_name));131 client_domain, domain, smb_name, workstation_name)); 233 132 } 234 133 … … 238 137 239 138 result = make_user_info(user_info, smb_name, internal_username, 240 client_domain, domain, w ksta_name,139 client_domain, domain, workstation_name, 241 140 lm_pwd, nt_pwd, 242 141 lm_interactive_pwd, nt_interactive_pwd, 243 plaintext, encrypted);142 plaintext, password_state); 244 143 if (NT_STATUS_IS_OK(result)) { 144 /* We have tried mapping */ 145 (*user_info)->mapped_state = True; 146 /* did we actually map the user to a different name? */ 245 147 (*user_info)->was_mapped = was_mapped; 246 148 } … … 253 155 ****************************************************************************/ 254 156 255 bool make_user_info_netlogon_network( auth_usersupplied_info **user_info,157 bool make_user_info_netlogon_network(struct auth_usersupplied_info **user_info, 256 158 const char *smb_name, 257 159 const char *client_domain, 258 const char *w ksta_name,160 const char *workstation_name, 259 161 uint32 logon_parameters, 260 162 const uchar *lm_network_pwd, … … 270 172 status = make_user_info_map(user_info, 271 173 smb_name, client_domain, 272 w ksta_name,174 workstation_name, 273 175 lm_pwd_len ? &lm_blob : NULL, 274 176 nt_pwd_len ? &nt_blob : NULL, 275 177 NULL, NULL, NULL, 276 True);178 AUTH_PASSWORD_RESPONSE); 277 179 278 180 if (NT_STATUS_IS_OK(status)) { … … 291 193 ****************************************************************************/ 292 194 293 bool make_user_info_netlogon_interactive( auth_usersupplied_info **user_info,195 bool make_user_info_netlogon_interactive(struct auth_usersupplied_info **user_info, 294 196 const char *smb_name, 295 197 const char *client_domain, 296 const char *w ksta_name,198 const char *workstation_name, 297 199 uint32 logon_parameters, 298 200 const uchar chal[8], … … 301 203 const uchar *dc_sess_key) 302 204 { 303 unsigned char lm_pwd[16];304 unsigned char nt_pwd[16];205 struct samr_Password lm_pwd; 206 struct samr_Password nt_pwd; 305 207 unsigned char local_lm_response[24]; 306 208 unsigned char local_nt_response[24]; 307 209 unsigned char key[16]; 308 210 309 211 memcpy(key, dc_sess_key, 16); 310 212 311 213 if (lm_interactive_pwd) 312 memcpy(lm_pwd , lm_interactive_pwd, sizeof(lm_pwd));214 memcpy(lm_pwd.hash, lm_interactive_pwd, sizeof(lm_pwd.hash)); 313 215 314 216 if (nt_interactive_pwd) 315 memcpy(nt_pwd , nt_interactive_pwd, sizeof(nt_pwd));316 217 memcpy(nt_pwd.hash, nt_interactive_pwd, sizeof(nt_pwd.hash)); 218 317 219 #ifdef DEBUG_PASSWORD 318 220 DEBUG(100,("key:")); 319 221 dump_data(100, key, sizeof(key)); 320 222 321 223 DEBUG(100,("lm owf password:")); 322 dump_data(100, lm_pwd , sizeof(lm_pwd));323 224 dump_data(100, lm_pwd.hash, sizeof(lm_pwd.hash)); 225 324 226 DEBUG(100,("nt owf password:")); 325 dump_data(100, nt_pwd , sizeof(nt_pwd));227 dump_data(100, nt_pwd.hash, sizeof(nt_pwd.hash)); 326 228 #endif 327 229 328 230 if (lm_interactive_pwd) 329 arcfour_crypt(lm_pwd , key, sizeof(lm_pwd));330 231 arcfour_crypt(lm_pwd.hash, key, sizeof(lm_pwd.hash)); 232 331 233 if (nt_interactive_pwd) 332 arcfour_crypt(nt_pwd , key, sizeof(nt_pwd));333 234 arcfour_crypt(nt_pwd.hash, key, sizeof(nt_pwd.hash)); 235 334 236 #ifdef DEBUG_PASSWORD 335 237 DEBUG(100,("decrypt of lm owf password:")); 336 dump_data(100, lm_pwd , sizeof(lm_pwd));337 238 dump_data(100, lm_pwd.hash, sizeof(lm_pwd)); 239 338 240 DEBUG(100,("decrypt of nt owf password:")); 339 dump_data(100, nt_pwd , sizeof(nt_pwd));241 dump_data(100, nt_pwd.hash, sizeof(nt_pwd)); 340 242 #endif 341 243 342 244 if (lm_interactive_pwd) 343 SMBOWFencrypt(lm_pwd , chal,245 SMBOWFencrypt(lm_pwd.hash, chal, 344 246 local_lm_response); 345 247 346 248 if (nt_interactive_pwd) 347 SMBOWFencrypt(nt_pwd , chal,249 SMBOWFencrypt(nt_pwd.hash, chal, 348 250 local_nt_response); 349 251 350 252 /* Password info paranoia */ 351 253 ZERO_STRUCT(key); … … 357 259 DATA_BLOB local_nt_blob; 358 260 359 DATA_BLOB lm_interactive_blob;360 DATA_BLOB nt_interactive_blob;361 362 261 if (lm_interactive_pwd) { 363 262 local_lm_blob = data_blob(local_lm_response, 364 263 sizeof(local_lm_response)); 365 lm_interactive_blob = data_blob(lm_pwd,366 sizeof(lm_pwd));367 ZERO_STRUCT(lm_pwd);368 264 } 369 265 370 266 if (nt_interactive_pwd) { 371 267 local_nt_blob = data_blob(local_nt_response, 372 268 sizeof(local_nt_response)); 373 nt_interactive_blob = data_blob(nt_pwd,374 sizeof(nt_pwd));375 ZERO_STRUCT(nt_pwd);376 269 } 377 270 378 271 nt_status = make_user_info_map( 379 272 user_info, 380 smb_name, client_domain, w ksta_name,273 smb_name, client_domain, workstation_name, 381 274 lm_interactive_pwd ? &local_lm_blob : NULL, 382 275 nt_interactive_pwd ? &local_nt_blob : NULL, 383 lm_interactive_pwd ? &lm_ interactive_blob: NULL,384 nt_interactive_pwd ? &nt_ interactive_blob: NULL,385 NULL, True);276 lm_interactive_pwd ? &lm_pwd : NULL, 277 nt_interactive_pwd ? &nt_pwd : NULL, 278 NULL, AUTH_PASSWORD_HASH); 386 279 387 280 if (NT_STATUS_IS_OK(nt_status)) { … … 392 285 data_blob_free(&local_lm_blob); 393 286 data_blob_free(&local_nt_blob); 394 data_blob_free(&lm_interactive_blob);395 data_blob_free(&nt_interactive_blob);396 287 return ret; 397 288 } … … 403 294 ****************************************************************************/ 404 295 405 bool make_user_info_for_reply( auth_usersupplied_info **user_info,296 bool make_user_info_for_reply(struct auth_usersupplied_info **user_info, 406 297 const char *smb_name, 407 298 const char *client_domain, … … 413 304 DATA_BLOB local_nt_blob; 414 305 NTSTATUS ret = NT_STATUS_UNSUCCESSFUL; 415 306 char *plaintext_password_string; 416 307 /* 417 308 * Not encrypted - do so. 418 309 */ 419 310 420 311 DEBUG(5,("make_user_info_for_reply: User passwords not in encrypted " 421 312 "format.\n")); 422 423 if (plaintext_password.data) { 313 if (plaintext_password.data && plaintext_password.length) { 424 314 unsigned char local_lm_response[24]; 425 315 426 316 #ifdef DEBUG_PASSWORD 427 317 DEBUG(10,("Unencrypted password (len %d):\n", … … 434 324 (const uchar*)chal, local_lm_response); 435 325 local_lm_blob = data_blob(local_lm_response, 24); 436 326 437 327 /* We can't do an NT hash here, as the password needs to be 438 328 case insensitive */ 439 329 local_nt_blob = data_blob_null; 440 441 330 } else { 442 331 local_lm_blob = data_blob_null; 443 332 local_nt_blob = data_blob_null; 444 333 } 445 334 335 plaintext_password_string = talloc_strndup(talloc_tos(), 336 (const char *)plaintext_password.data, 337 plaintext_password.length); 338 if (!plaintext_password_string) { 339 return False; 340 } 341 446 342 ret = make_user_info_map( 447 343 user_info, smb_name, client_domain, … … 450 346 local_nt_blob.data ? &local_nt_blob : NULL, 451 347 NULL, NULL, 452 plaintext_password.data ? &plaintext_password : NULL, 453 False); 454 348 plaintext_password_string, 349 AUTH_PASSWORD_PLAIN); 350 351 if (plaintext_password_string) { 352 memset(plaintext_password_string, '\0', strlen(plaintext_password_string)); 353 talloc_free(plaintext_password_string); 354 } 355 455 356 data_blob_free(&local_lm_blob); 456 357 return NT_STATUS_IS_OK(ret) ? True : False; … … 461 362 ****************************************************************************/ 462 363 463 NTSTATUS make_user_info_for_reply_enc( auth_usersupplied_info **user_info,364 NTSTATUS make_user_info_for_reply_enc(struct auth_usersupplied_info **user_info, 464 365 const char *smb_name, 465 366 const char *client_domain, … … 472 373 nt_resp.data && (nt_resp.length > 0) ? &nt_resp : NULL, 473 374 NULL, NULL, NULL, 474 True);375 AUTH_PASSWORD_RESPONSE); 475 376 } 476 377 … … 479 380 ****************************************************************************/ 480 381 481 bool make_user_info_guest( auth_usersupplied_info **user_info)382 bool make_user_info_guest(struct auth_usersupplied_info **user_info) 482 383 { 483 384 NTSTATUS nt_status; … … 490 391 NULL, NULL, 491 392 NULL, 492 True);493 393 AUTH_PASSWORD_RESPONSE); 394 494 395 return NT_STATUS_IS_OK(nt_status) ? True : False; 495 396 } 496 397 497 static int server_info_dtor(auth_serversupplied_info *server_info) 498 { 499 TALLOC_FREE(server_info->sam_account); 500 ZERO_STRUCTP(server_info); 501 return 0; 502 } 503 504 /*************************************************************************** 505 Make a server_info struct. Free with TALLOC_FREE(). 506 ***************************************************************************/ 507 508 static auth_serversupplied_info *make_server_info(TALLOC_CTX *mem_ctx) 509 { 510 struct auth_serversupplied_info *result; 511 512 result = TALLOC_ZERO_P(mem_ctx, auth_serversupplied_info); 513 if (result == NULL) { 514 DEBUG(0, ("talloc failed\n")); 515 return NULL; 516 } 517 518 talloc_set_destructor(result, server_info_dtor); 519 520 /* Initialise the uid and gid values to something non-zero 521 which may save us from giving away root access if there 522 is a bug in allocating these fields. */ 523 524 result->utok.uid = -1; 525 result->utok.gid = -1; 526 return result; 527 } 528 529 static char *sanitize_username(TALLOC_CTX *mem_ctx, const char *username) 530 { 531 fstring tmp; 532 533 alpha_strcpy(tmp, username, ". _-$", sizeof(tmp)); 534 return talloc_strdup(mem_ctx, tmp); 535 } 536 537 /*************************************************************************** 538 Is the incoming username our own machine account ? 539 If so, the connection is almost certainly from winbindd. 540 ***************************************************************************/ 541 542 static bool is_our_machine_account(const char *username) 543 { 544 bool ret; 545 char *truncname = NULL; 546 size_t ulen = strlen(username); 547 548 if (ulen == 0 || username[ulen-1] != '$') { 549 return false; 550 } 551 truncname = SMB_STRDUP(username); 552 if (!truncname) { 553 return false; 554 } 555 truncname[ulen-1] = '\0'; 556 ret = strequal(truncname, global_myname()); 557 SAFE_FREE(truncname); 558 return ret; 559 } 560 561 /*************************************************************************** 562 Make (and fill) a user_info struct from a struct samu 563 ***************************************************************************/ 564 565 NTSTATUS make_server_info_sam(auth_serversupplied_info **server_info, 566 struct samu *sampass) 567 { 568 struct passwd *pwd; 569 gid_t *gids; 570 auth_serversupplied_info *result; 571 const char *username = pdb_get_username(sampass); 572 NTSTATUS status; 573 574 if ( !(result = make_server_info(NULL)) ) { 575 return NT_STATUS_NO_MEMORY; 576 } 577 578 if ( !(pwd = Get_Pwnam_alloc(result, username)) ) { 579 DEBUG(1, ("User %s in passdb, but getpwnam() fails!\n", 580 pdb_get_username(sampass))); 581 TALLOC_FREE(result); 582 return NT_STATUS_NO_SUCH_USER; 583 } 584 585 result->sam_account = sampass; 586 result->unix_name = pwd->pw_name; 587 /* Ensure that we keep pwd->pw_name, because we will free pwd below */ 588 talloc_steal(result, pwd->pw_name); 589 result->utok.gid = pwd->pw_gid; 590 result->utok.uid = pwd->pw_uid; 591 592 TALLOC_FREE(pwd); 593 594 result->sanitized_username = sanitize_username(result, 595 result->unix_name); 596 if (result->sanitized_username == NULL) { 597 TALLOC_FREE(result); 598 return NT_STATUS_NO_MEMORY; 599 } 600 601 if (IS_DC && is_our_machine_account(username)) { 602 /* 603 * Ensure for a connection from our own 604 * machine account (from winbindd on a DC) 605 * there are no supplementary groups. 606 * Prevents loops in calling gid_to_sid(). 607 */ 608 result->sids = NULL; 609 gids = NULL; 610 result->num_sids = 0; 611 612 /* 613 * This is a hack of monstrous proportions. 614 * If we know it's winbindd talking to us, 615 * we know we must never recurse into it, 616 * so turn off contacting winbindd for this 617 * entire process. This will get fixed when 618 * winbindd doesn't need to talk to smbd on 619 * a PDC. JRA. 620 */ 621 622 (void)winbind_off(); 623 624 DEBUG(10, ("make_server_info_sam: our machine account %s " 625 "setting supplementary group list empty and " 626 "turning off winbindd requests.\n", 627 username)); 628 } else { 629 status = pdb_enum_group_memberships(result, sampass, 630 &result->sids, &gids, 631 &result->num_sids); 632 633 if (!NT_STATUS_IS_OK(status)) { 634 DEBUG(10, ("pdb_enum_group_memberships failed: %s\n", 635 nt_errstr(status))); 636 result->sam_account = NULL; /* Don't free on error exit. */ 637 TALLOC_FREE(result); 638 return status; 639 } 640 } 641 642 /* For now we throw away the gids and convert via sid_to_gid 643 * later. This needs fixing, but I'd like to get the code straight and 644 * simple first. */ 645 646 TALLOC_FREE(gids); 647 648 DEBUG(5,("make_server_info_sam: made server info for user %s -> %s\n", 649 pdb_get_username(sampass), result->unix_name)); 650 651 *server_info = result; 652 /* Ensure that the sampass will be freed with the result */ 653 talloc_steal(result, sampass); 654 655 return NT_STATUS_OK; 656 } 657 658 static NTSTATUS log_nt_token(NT_USER_TOKEN *token) 398 static NTSTATUS log_nt_token(struct security_token *token) 659 399 { 660 400 TALLOC_CTX *frame = talloc_stackframe(); … … 673 413 group_sidstr = talloc_asprintf( 674 414 frame, "%s %s", group_sidstr, 675 sid_string_talloc(frame, &token-> user_sids[i]));415 sid_string_talloc(frame, &token->sids[i])); 676 416 } 677 417 678 418 command = talloc_string_sub( 679 419 frame, lp_log_nt_token_command(), 680 "%s", sid_string_talloc(frame, &token-> user_sids[0]));420 "%s", sid_string_talloc(frame, &token->sids[0])); 681 421 command = talloc_string_sub(frame, command, "%t", group_sidstr); 682 422 … … 698 438 699 439 /* 700 * Create the token to use from server_info-> sam_accountand440 * Create the token to use from server_info->info3 and 701 441 * server_info->sids (the info3/sam groups). Find the unix gids. 702 442 */ 703 443 704 NTSTATUS create_local_token(auth_serversupplied_info *server_info) 705 { 444 NTSTATUS create_local_token(struct auth_serversupplied_info *server_info) 445 { 446 struct security_token *t; 706 447 NTSTATUS status; 707 448 size_t i; 708 449 struct dom_sid tmp_sid; 450 struct wbcUnixId *ids; 709 451 710 452 /* … … 722 464 &server_info->utok.gid, 723 465 &server_info->unix_name, 724 &server_info-> ptok);466 &server_info->security_token); 725 467 726 468 } else { 727 server_info->ptok = create_local_nt_token( 728 server_info, 729 pdb_get_user_sid(server_info->sam_account), 730 server_info->guest, 731 server_info->num_sids, server_info->sids); 732 status = server_info->ptok ? 733 NT_STATUS_OK : NT_STATUS_NO_SUCH_USER; 469 status = create_local_nt_token_from_info3(server_info, 470 server_info->guest, 471 server_info->info3, 472 &server_info->extra, 473 &server_info->security_token); 734 474 } 735 475 … … 743 483 server_info->utok.groups = NULL; 744 484 485 t = server_info->security_token; 486 487 ids = TALLOC_ARRAY(talloc_tos(), struct wbcUnixId, 488 t->num_sids); 489 if (ids == NULL) { 490 return NT_STATUS_NO_MEMORY; 491 } 492 493 if (!sids_to_unix_ids(t->sids, t->num_sids, ids)) { 494 TALLOC_FREE(ids); 495 return NT_STATUS_NO_MEMORY; 496 } 497 745 498 /* Start at index 1, where the groups start. */ 746 499 747 for (i=1; i<server_info->ptok->num_sids; i++) { 748 gid_t gid; 749 DOM_SID *sid = &server_info->ptok->user_sids[i]; 750 751 if (!sid_to_gid(sid, &gid)) { 500 for (i=1; i<t->num_sids; i++) { 501 502 if (ids[i].type != WBC_ID_TYPE_GID) { 752 503 DEBUG(10, ("Could not convert SID %s to gid, " 753 "ignoring it\n", sid_string_dbg(sid))); 504 "ignoring it\n", 505 sid_string_dbg(&t->sids[i]))); 754 506 continue; 755 507 } 756 add_gid_to_array_unique(server_info, gid, 757 &server_info->utok.groups, 758 &server_info->utok.ngroups); 508 if (!add_gid_to_array_unique(server_info, ids[i].id.gid, 509 &server_info->utok.groups, 510 &server_info->utok.ngroups)) { 511 return NT_STATUS_NO_MEMORY; 512 } 759 513 } 760 514 … … 772 526 */ 773 527 774 if (!uid_to_unix_users_sid(server_info->utok.uid, &tmp_sid)) { 775 DEBUG(1,("create_local_token: Failed to create SID " 776 "for uid %u!\n", (unsigned int)server_info->utok.uid)); 777 } 778 add_sid_to_array_unique(server_info->ptok, &tmp_sid, 779 &server_info->ptok->user_sids, 780 &server_info->ptok->num_sids); 528 uid_to_unix_users_sid(server_info->utok.uid, &tmp_sid); 529 530 add_sid_to_array_unique(server_info->security_token, &tmp_sid, 531 &server_info->security_token->sids, 532 &server_info->security_token->num_sids); 781 533 782 534 for ( i=0; i<server_info->utok.ngroups; i++ ) { 783 if (!gid_to_unix_groups_sid( server_info->utok.groups[i], &tmp_sid ) ) { 784 DEBUG(1,("create_local_token: Failed to create SID " 785 "for gid %u!\n", (unsigned int)server_info->utok.groups[i])); 786 continue; 787 } 788 add_sid_to_array_unique(server_info->ptok, &tmp_sid, 789 &server_info->ptok->user_sids, 790 &server_info->ptok->num_sids); 791 } 792 793 debug_nt_user_token(DBGC_AUTH, 10, server_info->ptok); 535 gid_to_unix_groups_sid(server_info->utok.groups[i], &tmp_sid); 536 add_sid_to_array_unique(server_info->security_token, &tmp_sid, 537 &server_info->security_token->sids, 538 &server_info->security_token->num_sids); 539 } 540 541 security_token_debug(DBGC_AUTH, 10, server_info->security_token); 794 542 debug_unix_user_token(DBGC_AUTH, 10, 795 543 server_info->utok.uid, … … 798 546 server_info->utok.groups); 799 547 800 status = log_nt_token(server_info-> ptok);548 status = log_nt_token(server_info->security_token); 801 549 return status; 802 }803 804 /*805 * Create an artificial NT token given just a username. (Initially intended806 * for force user)807 *808 * We go through lookup_name() to avoid problems we had with 'winbind use809 * default domain'.810 *811 * We have 3 cases:812 *813 * unmapped unix users: Go directly to nss to find the user's group.814 *815 * A passdb user: The list of groups is provided by pdb_enum_group_memberships.816 *817 * If the user is provided by winbind, the primary gid is set to "domain818 * users" of the user's domain. For an explanation why this is necessary, see819 * the thread starting at820 * http://lists.samba.org/archive/samba-technical/2006-January/044803.html.821 */822 823 NTSTATUS create_token_from_username(TALLOC_CTX *mem_ctx, const char *username,824 bool is_guest,825 uid_t *uid, gid_t *gid,826 char **found_username,827 struct nt_user_token **token)828 {829 NTSTATUS result = NT_STATUS_NO_SUCH_USER;830 TALLOC_CTX *tmp_ctx;831 DOM_SID user_sid;832 enum lsa_SidType type;833 gid_t *gids;834 DOM_SID *group_sids;835 DOM_SID unix_group_sid;836 size_t num_group_sids;837 size_t num_gids;838 size_t i;839 840 tmp_ctx = talloc_new(NULL);841 if (tmp_ctx == NULL) {842 DEBUG(0, ("talloc_new failed\n"));843 return NT_STATUS_NO_MEMORY;844 }845 846 if (!lookup_name_smbconf(tmp_ctx, username, LOOKUP_NAME_ALL,847 NULL, NULL, &user_sid, &type)) {848 DEBUG(1, ("lookup_name_smbconf for %s failed\n", username));849 goto done;850 }851 852 if (type != SID_NAME_USER) {853 DEBUG(1, ("%s is a %s, not a user\n", username,854 sid_type_lookup(type)));855 goto done;856 }857 858 if (sid_check_is_in_our_domain(&user_sid)) {859 bool ret;860 861 /* This is a passdb user, so ask passdb */862 863 struct samu *sam_acct = NULL;864 865 if ( !(sam_acct = samu_new( tmp_ctx )) ) {866 result = NT_STATUS_NO_MEMORY;867 goto done;868 }869 870 become_root();871 ret = pdb_getsampwsid(sam_acct, &user_sid);872 unbecome_root();873 874 if (!ret) {875 DEBUG(1, ("pdb_getsampwsid(%s) for user %s failed\n",876 sid_string_dbg(&user_sid), username));877 DEBUGADD(1, ("Fall back to unix user %s\n", username));878 goto unix_user;879 }880 881 result = pdb_enum_group_memberships(tmp_ctx, sam_acct,882 &group_sids, &gids,883 &num_group_sids);884 if (!NT_STATUS_IS_OK(result)) {885 DEBUG(1, ("enum_group_memberships failed for %s (%s): "886 "%s\n", username, sid_string_dbg(&user_sid),887 nt_errstr(result)));888 DEBUGADD(1, ("Fall back to unix user %s\n", username));889 goto unix_user;890 }891 892 /* see the smb_panic() in pdb_default_enum_group_memberships */893 SMB_ASSERT(num_group_sids > 0);894 895 *gid = gids[0];896 897 /* Ensure we're returning the found_username on the right context. */898 *found_username = talloc_strdup(mem_ctx,899 pdb_get_username(sam_acct));900 901 /*902 * If the SID from lookup_name() was the guest sid, passdb knows903 * about the mapping of guest sid to lp_guestaccount()904 * username and will return the unix_pw info for a guest905 * user. Use it if it's there, else lookup the *uid details906 * using Get_Pwnam_alloc(). See bug #6291 for details. JRA.907 */908 909 /* We must always assign the *uid. */910 if (sam_acct->unix_pw == NULL) {911 struct passwd *pwd = Get_Pwnam_alloc(sam_acct, *found_username );912 if (!pwd) {913 DEBUG(10, ("Get_Pwnam_alloc failed for %s\n",914 *found_username));915 result = NT_STATUS_NO_SUCH_USER;916 goto done;917 }918 result = samu_set_unix(sam_acct, pwd );919 if (!NT_STATUS_IS_OK(result)) {920 DEBUG(10, ("samu_set_unix failed for %s\n",921 *found_username));922 result = NT_STATUS_NO_SUCH_USER;923 goto done;924 }925 }926 *uid = sam_acct->unix_pw->pw_uid;927 928 } else if (sid_check_is_in_unix_users(&user_sid)) {929 930 /* This is a unix user not in passdb. We need to ask nss931 * directly, without consulting passdb */932 933 struct passwd *pass;934 935 /*936 * This goto target is used as a fallback for the passdb937 * case. The concrete bug report is when passdb gave us an938 * unmapped gid.939 */940 941 unix_user:942 943 if (!sid_to_uid(&user_sid, uid)) {944 DEBUG(1, ("unix_user case, sid_to_uid for %s (%s) failed\n",945 username, sid_string_dbg(&user_sid)));946 result = NT_STATUS_NO_SUCH_USER;947 goto done;948 }949 950 uid_to_unix_users_sid(*uid, &user_sid);951 952 pass = getpwuid_alloc(tmp_ctx, *uid);953 if (pass == NULL) {954 DEBUG(1, ("getpwuid(%u) for user %s failed\n",955 (unsigned int)*uid, username));956 goto done;957 }958 959 if (!getgroups_unix_user(tmp_ctx, username, pass->pw_gid,960 &gids, &num_group_sids)) {961 DEBUG(1, ("getgroups_unix_user for user %s failed\n",962 username));963 goto done;964 }965 966 if (num_group_sids) {967 group_sids = TALLOC_ARRAY(tmp_ctx, DOM_SID, num_group_sids);968 if (group_sids == NULL) {969 DEBUG(1, ("TALLOC_ARRAY failed\n"));970 result = NT_STATUS_NO_MEMORY;971 goto done;972 }973 } else {974 group_sids = NULL;975 }976 977 for (i=0; i<num_group_sids; i++) {978 gid_to_sid(&group_sids[i], gids[i]);979 }980 981 /* In getgroups_unix_user we always set the primary gid */982 SMB_ASSERT(num_group_sids > 0);983 984 *gid = gids[0];985 986 /* Ensure we're returning the found_username on the right context. */987 *found_username = talloc_strdup(mem_ctx, pass->pw_name);988 } else {989 990 /* This user is from winbind, force the primary gid to the991 * user's "domain users" group. Under certain circumstances992 * (user comes from NT4), this might be a loss of993 * information. But we can not rely on winbind getting the994 * correct info. AD might prohibit winbind looking up that995 * information. */996 997 uint32 dummy;998 999 /* We must always assign the *uid. */1000 if (!sid_to_uid(&user_sid, uid)) {1001 DEBUG(1, ("winbindd case, sid_to_uid for %s (%s) failed\n",1002 username, sid_string_dbg(&user_sid)));1003 result = NT_STATUS_NO_SUCH_USER;1004 goto done;1005 }1006 1007 num_group_sids = 1;1008 group_sids = TALLOC_ARRAY(tmp_ctx, DOM_SID, num_group_sids);1009 if (group_sids == NULL) {1010 DEBUG(1, ("TALLOC_ARRAY failed\n"));1011 result = NT_STATUS_NO_MEMORY;1012 goto done;1013 }1014 1015 sid_copy(&group_sids[0], &user_sid);1016 sid_split_rid(&group_sids[0], &dummy);1017 sid_append_rid(&group_sids[0], DOMAIN_GROUP_RID_USERS);1018 1019 if (!sid_to_gid(&group_sids[0], gid)) {1020 DEBUG(1, ("sid_to_gid(%s) failed\n",1021 sid_string_dbg(&group_sids[0])));1022 goto done;1023 }1024 1025 gids = gid;1026 1027 /* Ensure we're returning the found_username on the right context. */1028 *found_username = talloc_strdup(mem_ctx, username);1029 }1030 1031 /* Add the "Unix Group" SID for each gid to catch mapped groups1032 and their Unix equivalent. This is to solve the backwards1033 compatibility problem of 'valid users = +ntadmin' where1034 ntadmin has been paired with "Domain Admins" in the group1035 mapping table. Otherwise smb.conf would need to be changed1036 to 'valid user = "Domain Admins"'. --jerry */1037 1038 num_gids = num_group_sids;1039 for ( i=0; i<num_gids; i++ ) {1040 gid_t high, low;1041 1042 /* don't pickup anything managed by Winbind */1043 1044 if ( lp_idmap_gid(&low, &high) && (gids[i] >= low) && (gids[i] <= high) )1045 continue;1046 1047 if ( !gid_to_unix_groups_sid( gids[i], &unix_group_sid ) ) {1048 DEBUG(1,("create_token_from_username: Failed to create SID "1049 "for gid %u!\n", (unsigned int)gids[i]));1050 continue;1051 }1052 result = add_sid_to_array_unique(tmp_ctx, &unix_group_sid,1053 &group_sids, &num_group_sids);1054 if (!NT_STATUS_IS_OK(result)) {1055 goto done;1056 }1057 }1058 1059 /* Ensure we're creating the nt_token on the right context. */1060 *token = create_local_nt_token(mem_ctx, &user_sid,1061 is_guest, num_group_sids, group_sids);1062 1063 if ((*token == NULL) || (*found_username == NULL)) {1064 result = NT_STATUS_NO_MEMORY;1065 goto done;1066 }1067 1068 result = NT_STATUS_OK;1069 done:1070 TALLOC_FREE(tmp_ctx);1071 return result;1072 }1073 1074 /***************************************************************************1075 Build upon create_token_from_username:1076 1077 Expensive helper function to figure out whether a user given its name is1078 member of a particular group.1079 ***************************************************************************/1080 1081 bool user_in_group_sid(const char *username, const DOM_SID *group_sid)1082 {1083 NTSTATUS status;1084 uid_t uid;1085 gid_t gid;1086 char *found_username;1087 struct nt_user_token *token;1088 bool result;1089 1090 TALLOC_CTX *mem_ctx;1091 1092 mem_ctx = talloc_new(NULL);1093 if (mem_ctx == NULL) {1094 DEBUG(0, ("talloc_new failed\n"));1095 return False;1096 }1097 1098 status = create_token_from_username(mem_ctx, username, False,1099 &uid, &gid, &found_username,1100 &token);1101 1102 if (!NT_STATUS_IS_OK(status)) {1103 DEBUG(10, ("could not create token for %s\n", username));1104 return False;1105 }1106 1107 result = nt_token_check_sid(group_sid, token);1108 1109 TALLOC_FREE(mem_ctx);1110 return result;1111 1112 }1113 1114 bool user_in_group(const char *username, const char *groupname)1115 {1116 TALLOC_CTX *mem_ctx;1117 DOM_SID group_sid;1118 bool ret;1119 1120 mem_ctx = talloc_new(NULL);1121 if (mem_ctx == NULL) {1122 DEBUG(0, ("talloc_new failed\n"));1123 return False;1124 }1125 1126 ret = lookup_name(mem_ctx, groupname, LOOKUP_NAME_ALL,1127 NULL, NULL, &group_sid, NULL);1128 TALLOC_FREE(mem_ctx);1129 1130 if (!ret) {1131 DEBUG(10, ("lookup_name for (%s) failed.\n", groupname));1132 return False;1133 }1134 1135 return user_in_group_sid(username, &group_sid);1136 550 } 1137 551 … … 1141 555 ***************************************************************************/ 1142 556 1143 NTSTATUS make_server_info_pw( auth_serversupplied_info **server_info,557 NTSTATUS make_server_info_pw(struct auth_serversupplied_info **server_info, 1144 558 char *unix_username, 1145 559 struct passwd *pwd) … … 1147 561 NTSTATUS status; 1148 562 struct samu *sampass = NULL; 1149 gid_t *gids;1150 563 char *qualified_name = NULL; 1151 564 TALLOC_CTX *mem_ctx = NULL; 1152 DOM_SIDu_sid;565 struct dom_sid u_sid; 1153 566 enum lsa_SidType type; 1154 auth_serversupplied_info *result; 1155 1156 if ( !(sampass = samu_new( NULL )) ) { 1157 return NT_STATUS_NO_MEMORY; 1158 } 1159 1160 status = samu_set_unix( sampass, pwd ); 1161 if (!NT_STATUS_IS_OK(status)) { 1162 return status; 1163 } 1164 1165 result = make_server_info(NULL); 1166 if (result == NULL) { 1167 TALLOC_FREE(sampass); 1168 return NT_STATUS_NO_MEMORY; 1169 } 1170 1171 result->sam_account = sampass; 1172 1173 result->unix_name = talloc_strdup(result, unix_username); 1174 result->sanitized_username = sanitize_username(result, unix_username); 1175 1176 if ((result->unix_name == NULL) 1177 || (result->sanitized_username == NULL)) { 1178 TALLOC_FREE(sampass); 1179 TALLOC_FREE(result); 1180 return NT_STATUS_NO_MEMORY; 1181 } 1182 1183 result->utok.uid = pwd->pw_uid; 1184 result->utok.gid = pwd->pw_gid; 1185 1186 status = pdb_enum_group_memberships(result, sampass, 1187 &result->sids, &gids, 1188 &result->num_sids); 1189 1190 if (!NT_STATUS_IS_OK(status)) { 1191 DEBUG(10, ("pdb_enum_group_memberships failed: %s\n", 1192 nt_errstr(status))); 1193 TALLOC_FREE(result); 1194 return status; 1195 } 567 struct auth_serversupplied_info *result; 1196 568 1197 569 /* … … 1210 582 mem_ctx = talloc_init("make_server_info_pw_tmp"); 1211 583 if (!mem_ctx) { 1212 TALLOC_FREE(result);1213 584 return NT_STATUS_NO_MEMORY; 1214 585 } … … 1218 589 unix_username ); 1219 590 if (!qualified_name) { 1220 TALLOC_FREE(result);1221 591 TALLOC_FREE(mem_ctx); 1222 592 return NT_STATUS_NO_MEMORY; … … 1226 596 NULL, NULL, 1227 597 &u_sid, &type)) { 1228 TALLOC_FREE(result);1229 598 TALLOC_FREE(mem_ctx); 1230 599 return NT_STATUS_NO_SUCH_USER; … … 1234 603 1235 604 if (type != SID_NAME_USER) { 1236 TALLOC_FREE(result);1237 605 return NT_STATUS_NO_SUCH_USER; 1238 606 } 1239 607 1240 status = add_sid_to_array_unique(result, &u_sid, 1241 &result->sids, 1242 &result->num_sids); 608 if ( !(sampass = samu_new( NULL )) ) { 609 return NT_STATUS_NO_MEMORY; 610 } 611 612 status = samu_set_unix( sampass, pwd ); 1243 613 if (!NT_STATUS_IS_OK(status)) { 614 return status; 615 } 616 617 /* In pathological cases the above call can set the account 618 * name to the DOMAIN\username form. Reset the account name 619 * using unix_username */ 620 pdb_set_username(sampass, unix_username, PDB_SET); 621 622 /* set the user sid to be the calculated u_sid */ 623 pdb_set_user_sid(sampass, &u_sid, PDB_SET); 624 625 result = make_server_info(NULL); 626 if (result == NULL) { 627 TALLOC_FREE(sampass); 628 return NT_STATUS_NO_MEMORY; 629 } 630 631 status = samu_to_SamInfo3(result, sampass, global_myname(), 632 &result->info3, &result->extra); 633 TALLOC_FREE(sampass); 634 if (!NT_STATUS_IS_OK(status)) { 635 DEBUG(10, ("Failed to convert samu to info3: %s\n", 636 nt_errstr(status))); 1244 637 TALLOC_FREE(result); 1245 638 return status; 1246 639 } 1247 640 1248 /* For now we throw away the gids and convert via sid_to_gid 1249 * later. This needs fixing, but I'd like to get the code straight and 1250 * simple first. */ 1251 TALLOC_FREE(gids); 641 result->unix_name = talloc_strdup(result, unix_username); 642 result->sanitized_username = sanitize_username(result, unix_username); 643 644 if ((result->unix_name == NULL) 645 || (result->sanitized_username == NULL)) { 646 TALLOC_FREE(result); 647 return NT_STATUS_NO_MEMORY; 648 } 649 650 result->utok.uid = pwd->pw_uid; 651 result->utok.gid = pwd->pw_gid; 1252 652 1253 653 *server_info = result; 1254 654 655 return NT_STATUS_OK; 656 } 657 658 static NTSTATUS get_guest_info3(TALLOC_CTX *mem_ctx, 659 struct netr_SamInfo3 *info3) 660 { 661 const char *guest_account = lp_guestaccount(); 662 struct dom_sid domain_sid; 663 struct passwd *pwd; 664 const char *tmp; 665 666 pwd = Get_Pwnam_alloc(mem_ctx, guest_account); 667 if (pwd == NULL) { 668 DEBUG(0,("SamInfo3_for_guest: Unable to locate guest " 669 "account [%s]!\n", guest_account)); 670 return NT_STATUS_NO_SUCH_USER; 671 } 672 673 /* Set acount name */ 674 tmp = talloc_strdup(mem_ctx, pwd->pw_name); 675 if (tmp == NULL) { 676 return NT_STATUS_NO_MEMORY; 677 } 678 init_lsa_String(&info3->base.account_name, tmp); 679 680 /* Set domain name */ 681 tmp = talloc_strdup(mem_ctx, get_global_sam_name()); 682 if (tmp == NULL) { 683 return NT_STATUS_NO_MEMORY; 684 } 685 init_lsa_StringLarge(&info3->base.domain, tmp); 686 687 /* Domain sid */ 688 sid_copy(&domain_sid, get_global_sam_sid()); 689 690 info3->base.domain_sid = dom_sid_dup(mem_ctx, &domain_sid); 691 if (info3->base.domain_sid == NULL) { 692 return NT_STATUS_NO_MEMORY; 693 } 694 695 /* Guest rid */ 696 info3->base.rid = DOMAIN_RID_GUEST; 697 698 /* Primary gid */ 699 info3->base.primary_gid = BUILTIN_RID_GUESTS; 700 701 TALLOC_FREE(pwd); 1255 702 return NT_STATUS_OK; 1256 703 } … … 1262 709 ***************************************************************************/ 1263 710 1264 static NTSTATUS make_new_server_info_guest(auth_serversupplied_info **server_info) 1265 { 711 static NTSTATUS make_new_server_info_guest(struct auth_serversupplied_info **server_info) 712 { 713 static const char zeros[16] = {0}; 714 const char *guest_account = lp_guestaccount(); 715 const char *domain = global_myname(); 716 struct netr_SamInfo3 info3; 717 TALLOC_CTX *tmp_ctx; 1266 718 NTSTATUS status; 1267 struct samu *sampass = NULL;1268 DOM_SID guest_sid;1269 bool ret;1270 char zeros[16];1271 719 fstring tmp; 1272 720 1273 if ( !(sampass = samu_new( NULL )) ) { 1274 return NT_STATUS_NO_MEMORY; 1275 } 1276 1277 sid_copy(&guest_sid, get_global_sam_sid()); 1278 sid_append_rid(&guest_sid, DOMAIN_USER_RID_GUEST); 1279 1280 become_root(); 1281 ret = pdb_getsampwsid(sampass, &guest_sid); 1282 unbecome_root(); 1283 1284 if (!ret) { 1285 TALLOC_FREE(sampass); 1286 return NT_STATUS_NO_SUCH_USER; 1287 } 1288 1289 status = make_server_info_sam(server_info, sampass); 721 tmp_ctx = talloc_stackframe(); 722 if (tmp_ctx == NULL) { 723 return NT_STATUS_NO_MEMORY; 724 } 725 726 ZERO_STRUCT(info3); 727 728 status = get_guest_info3(tmp_ctx, &info3); 1290 729 if (!NT_STATUS_IS_OK(status)) { 1291 TALLOC_FREE(sampass); 1292 return status; 1293 } 1294 730 goto done; 731 } 732 733 status = make_server_info_info3(tmp_ctx, 734 guest_account, 735 domain, 736 server_info, 737 &info3); 738 if (!NT_STATUS_IS_OK(status)) { 739 goto done; 740 } 741 1295 742 (*server_info)->guest = True; 1296 743 … … 1299 746 DEBUG(10, ("create_local_token failed: %s\n", 1300 747 nt_errstr(status))); 1301 return status;748 goto done; 1302 749 } 1303 750 1304 751 /* annoying, but the Guest really does have a session key, and it is 1305 752 all zeros! */ 1306 ZERO_STRUCT(zeros);1307 753 (*server_info)->user_session_key = data_blob(zeros, sizeof(zeros)); 1308 754 (*server_info)->lm_session_key = data_blob(zeros, sizeof(zeros)); 1309 755 1310 alpha_strcpy(tmp, pdb_get_username(sampass), ". _-$", sizeof(tmp)); 756 alpha_strcpy(tmp, (*server_info)->info3->base.account_name.string, 757 ". _-$", sizeof(tmp)); 1311 758 (*server_info)->sanitized_username = talloc_strdup(*server_info, tmp); 759 760 status = NT_STATUS_OK; 761 done: 762 TALLOC_FREE(tmp_ctx); 763 return NT_STATUS_OK; 764 } 765 766 /*************************************************************************** 767 Make (and fill) a auth_session_info struct for a system user login. 768 This *must* succeed for smbd to start. 769 ***************************************************************************/ 770 771 static NTSTATUS make_new_session_info_system(TALLOC_CTX *mem_ctx, 772 struct auth_serversupplied_info **session_info) 773 { 774 struct passwd *pwd; 775 NTSTATUS status; 776 777 pwd = getpwuid_alloc(mem_ctx, sec_initial_uid()); 778 if (pwd == NULL) { 779 return NT_STATUS_NO_SUCH_USER; 780 } 781 782 status = make_serverinfo_from_username(mem_ctx, 783 pwd->pw_name, 784 false, 785 session_info); 786 TALLOC_FREE(pwd); 787 if (!NT_STATUS_IS_OK(status)) { 788 return status; 789 } 790 791 (*session_info)->system = true; 792 793 status = add_sid_to_array_unique((*session_info)->security_token->sids, 794 &global_sid_System, 795 &(*session_info)->security_token->sids, 796 &(*session_info)->security_token->num_sids); 797 if (!NT_STATUS_IS_OK(status)) { 798 TALLOC_FREE((*session_info)); 799 return status; 800 } 1312 801 1313 802 return NT_STATUS_OK; … … 1350 839 } 1351 840 1352 *presult = result;841 *presult = talloc_steal(mem_ctx, result); 1353 842 return NT_STATUS_OK; 1354 843 } … … 1356 845 1357 846 struct auth_serversupplied_info *copy_serverinfo(TALLOC_CTX *mem_ctx, 1358 const auth_serversupplied_info *src)1359 { 1360 auth_serversupplied_info *dst;847 const struct auth_serversupplied_info *src) 848 { 849 struct auth_serversupplied_info *dst; 1361 850 1362 851 dst = make_server_info(mem_ctx); … … 1366 855 1367 856 dst->guest = src->guest; 857 dst->system = src->system; 1368 858 dst->utok.uid = src->utok.uid; 1369 859 dst->utok.gid = src->utok.gid; … … 1377 867 } 1378 868 1379 if (src-> ptok) {1380 dst-> ptok = dup_nt_token(dst, src->ptok);1381 if (!dst-> ptok) {869 if (src->security_token) { 870 dst->security_token = dup_nt_token(dst, src->security_token); 871 if (!dst->security_token) { 1382 872 TALLOC_FREE(dst); 1383 873 return NULL; 1384 874 } 1385 875 } 1386 876 1387 877 dst->user_session_key = data_blob_talloc( dst, src->user_session_key.data, 1388 878 src->user_session_key.length); … … 1391 881 src->lm_session_key.length); 1392 882 1393 dst-> sam_account = samu_new(NULL);1394 if (!dst-> sam_account) {883 dst->info3 = copy_netr_SamInfo3(dst, src->info3); 884 if (!dst->info3) { 1395 885 TALLOC_FREE(dst); 1396 886 return NULL; 1397 887 } 1398 1399 if (!pdb_copy_sam_account(dst->sam_account, src->sam_account)) { 1400 TALLOC_FREE(dst); 1401 return NULL; 1402 } 1403 1404 dst->pam_handle = NULL; 888 dst->extra = src->extra; 889 1405 890 dst->unix_name = talloc_strdup(dst, src->unix_name); 1406 891 if (!dst->unix_name) { … … 1423 908 */ 1424 909 1425 bool se rver_info_set_session_key(struct auth_serversupplied_info *info,910 bool session_info_set_session_key(struct auth_serversupplied_info *info, 1426 911 DATA_BLOB session_key) 1427 912 { … … 1434 919 } 1435 920 1436 static auth_serversupplied_info *guest_info = NULL;921 static struct auth_serversupplied_info *guest_info = NULL; 1437 922 1438 923 bool init_guest_info(void) … … 1445 930 1446 931 NTSTATUS make_server_info_guest(TALLOC_CTX *mem_ctx, 1447 auth_serversupplied_info **server_info)932 struct auth_serversupplied_info **server_info) 1448 933 { 1449 934 *server_info = copy_serverinfo(mem_ctx, guest_info); … … 1451 936 } 1452 937 938 static struct auth_serversupplied_info *system_info = NULL; 939 940 NTSTATUS init_system_info(void) 941 { 942 if (system_info != NULL) 943 return NT_STATUS_OK; 944 945 return make_new_session_info_system(NULL, &system_info); 946 } 947 948 NTSTATUS make_session_info_system(TALLOC_CTX *mem_ctx, 949 struct auth_serversupplied_info **session_info) 950 { 951 if (system_info == NULL) return NT_STATUS_UNSUCCESSFUL; 952 *session_info = copy_serverinfo(mem_ctx, system_info); 953 return (*session_info != NULL) ? NT_STATUS_OK : NT_STATUS_NO_MEMORY; 954 } 955 956 const struct auth_serversupplied_info *get_session_info_system(void) 957 { 958 return system_info; 959 } 960 1453 961 bool copy_current_user(struct current_user *dst, struct current_user *src) 1454 962 { 1455 963 gid_t *groups; 1456 NT_USER_TOKEN*nt_token;964 struct security_token *nt_token; 1457 965 1458 966 groups = (gid_t *)memdup(src->ut.groups, … … 1480 988 /*************************************************************************** 1481 989 Purely internal function for make_server_info_info3 1482 Fill the sam account from getpwnam1483 990 ***************************************************************************/ 1484 static NTSTATUS fill_sam_account(TALLOC_CTX *mem_ctx, 1485 const char *domain, 1486 const char *username, 1487 char **found_username, 1488 uid_t *uid, gid_t *gid, 1489 struct samu *account, 1490 bool *username_was_mapped) 1491 { 1492 struct smbd_server_connection *sconn = smbd_server_conn; 1493 NTSTATUS nt_status; 1494 fstring dom_user, lower_username; 1495 fstring real_username; 991 992 static NTSTATUS check_account(TALLOC_CTX *mem_ctx, const char *domain, 993 const char *username, char **found_username, 994 struct passwd **pwd, 995 bool *username_was_mapped) 996 { 997 char *orig_dom_user = NULL; 998 char *dom_user = NULL; 999 char *lower_username = NULL; 1000 char *real_username = NULL; 1496 1001 struct passwd *passwd; 1497 1002 1498 fstrcpy( lower_username, username ); 1003 lower_username = talloc_strdup(mem_ctx, username); 1004 if (!lower_username) { 1005 return NT_STATUS_NO_MEMORY; 1006 } 1499 1007 strlower_m( lower_username ); 1500 1008 1501 fstr_sprintf(dom_user, "%s%c%s", domain, *lp_winbind_separator(), 1502 lower_username); 1503 1504 /* Get the passwd struct. Try to create the account is necessary. */ 1505 1506 *username_was_mapped = map_username(sconn, dom_user); 1507 1508 if ( !(passwd = smb_getpwnam( NULL, dom_user, real_username, True )) ) 1009 orig_dom_user = talloc_asprintf(mem_ctx, 1010 "%s%c%s", 1011 domain, 1012 *lp_winbind_separator(), 1013 lower_username); 1014 if (!orig_dom_user) { 1015 return NT_STATUS_NO_MEMORY; 1016 } 1017 1018 /* Get the passwd struct. Try to create the account if necessary. */ 1019 1020 *username_was_mapped = map_username(mem_ctx, orig_dom_user, &dom_user); 1021 if (!dom_user) { 1022 return NT_STATUS_NO_MEMORY; 1023 } 1024 1025 passwd = smb_getpwnam(mem_ctx, dom_user, &real_username, True ); 1026 if (!passwd) { 1027 DEBUG(3, ("Failed to find authenticated user %s via " 1028 "getpwnam(), denying access.\n", dom_user)); 1509 1029 return NT_STATUS_NO_SUCH_USER; 1510 1511 *uid = passwd->pw_uid; 1512 *gid = passwd->pw_gid; 1030 } 1031 1032 if (!real_username) { 1033 return NT_STATUS_NO_MEMORY; 1034 } 1035 1036 *pwd = passwd; 1513 1037 1514 1038 /* This is pointless -- there is no suport for differing … … 1517 1041 why I hate the 'winbind use default domain' parameter? 1518 1042 --jerry */ 1519 1043 1520 1044 *found_username = talloc_strdup( mem_ctx, real_username ); 1521 1522 DEBUG(5,("fill_sam_account: located username was [%s]\n", *found_username)); 1523 1524 nt_status = samu_set_unix( account, passwd ); 1525 1526 TALLOC_FREE(passwd); 1527 1528 return nt_status; 1045 1046 return NT_STATUS_OK; 1529 1047 } 1530 1048 … … 1534 1052 the username if we fallback to the username only. 1535 1053 ****************************************************************************/ 1536 1537 struct passwd *smb_getpwnam( TALLOC_CTX *mem_ctx, c har *domuser,1538 fstringsave_username, bool create )1054 1055 struct passwd *smb_getpwnam( TALLOC_CTX *mem_ctx, const char *domuser, 1056 char **p_save_username, bool create ) 1539 1057 { 1540 1058 struct passwd *pw = NULL; 1541 char *p ;1542 fstring username;1543 1059 char *p = NULL; 1060 char *username = NULL; 1061 1544 1062 /* we only save a copy of the username it has been mangled 1545 1063 by winbindd use default domain */ 1546 1547 save_username[0] = '\0'; 1548 1064 *p_save_username = NULL; 1065 1549 1066 /* don't call map_username() here since it has to be done higher 1550 up the stack so we don't call it mutliple times */ 1551 1552 fstrcpy( username, domuser ); 1553 1067 up the stack so we don't call it multiple times */ 1068 1069 username = talloc_strdup(mem_ctx, domuser); 1070 if (!username) { 1071 return NULL; 1072 } 1073 1554 1074 p = strchr_m( username, *lp_winbind_separator() ); 1555 1075 1556 1076 /* code for a DOMAIN\user string */ 1557 1077 1558 1078 if ( p ) { 1559 fstring strip_username;1560 1561 1079 pw = Get_Pwnam_alloc( mem_ctx, domuser ); 1562 if ( pw ) { 1080 if ( pw ) { 1563 1081 /* make sure we get the case of the username correct */ 1564 1082 /* work around 'winbind use default domain = yes' */ … … 1566 1084 if ( !strchr_m( pw->pw_name, *lp_winbind_separator() ) ) { 1567 1085 char *domain; 1568 1086 1569 1087 /* split the domain and username into 2 strings */ 1570 1088 *p = '\0'; 1571 1089 domain = username; 1572 1090 1573 fstr_sprintf(save_username, "%s%c%s", domain, *lp_winbind_separator(), pw->pw_name); 1091 *p_save_username = talloc_asprintf(mem_ctx, 1092 "%s%c%s", 1093 domain, 1094 *lp_winbind_separator(), 1095 pw->pw_name); 1096 if (!*p_save_username) { 1097 TALLOC_FREE(pw); 1098 return NULL; 1099 } 1100 } else { 1101 *p_save_username = talloc_strdup(mem_ctx, pw->pw_name); 1574 1102 } 1575 else 1576 fstrcpy( save_username, pw->pw_name ); 1577 1578 /* whew -- done! */ 1103 1104 /* whew -- done! */ 1579 1105 return pw; 1580 1106 } … … 1584 1110 1585 1111 p++; 1586 fstrcpy( strip_username, p ); 1587 fstrcpy( username, strip_username ); 1588 } 1589 1112 username = talloc_strdup(mem_ctx, p); 1113 if (!username) { 1114 return NULL; 1115 } 1116 } 1117 1590 1118 /* just lookup a plain username */ 1591 1119 1592 1120 pw = Get_Pwnam_alloc(mem_ctx, username); 1593 1121 1594 1122 /* Create local user if requested but only if winbindd 1595 1123 is not running. We need to protect against cases 1596 1124 where winbindd is failing and then prematurely 1597 1125 creating users in /etc/passwd */ 1598 1126 1599 1127 if ( !pw && create && !winbind_ping() ) { 1600 1128 /* Don't add a machine account. */ … … 1605 1133 pw = Get_Pwnam_alloc(mem_ctx, username); 1606 1134 } 1607 1135 1608 1136 /* one last check for a valid passwd struct */ 1609 1610 if ( pw )1611 fstrcpy( save_username, pw->pw_name);1612 1137 1138 if (pw) { 1139 *p_save_username = talloc_strdup(mem_ctx, pw->pw_name); 1140 } 1613 1141 return pw; 1614 1142 } … … 1621 1149 const char *sent_nt_username, 1622 1150 const char *domain, 1623 auth_serversupplied_info **server_info,1151 struct auth_serversupplied_info **server_info, 1624 1152 struct netr_SamInfo3 *info3) 1625 1153 { 1626 char zeros[16];1154 static const char zeros[16] = {0, }; 1627 1155 1628 1156 NTSTATUS nt_status = NT_STATUS_OK; … … 1630 1158 const char *nt_domain; 1631 1159 const char *nt_username; 1632 struct samu *sam_account = NULL;1633 DOM_SID user_sid;1634 DOM_SID group_sid;1635 1160 bool username_was_mapped; 1636 1637 uid_t uid = (uid_t)-1; 1638 gid_t gid = (gid_t)-1; 1639 1640 auth_serversupplied_info *result; 1161 struct passwd *pwd; 1162 struct auth_serversupplied_info *result; 1163 struct dom_sid *group_sid; 1164 struct netr_SamInfo3 *i3; 1641 1165 1642 1166 /* … … 1646 1170 */ 1647 1171 1648 sid_copy(&user_sid, info3->base.domain_sid);1649 if (!sid_append_rid(&user_sid, info3->base.rid)) {1650 return NT_STATUS_INVALID_PARAMETER;1651 }1652 1653 sid_copy(&group_sid, info3->base.domain_sid);1654 if (!sid_append_rid(&group_sid, info3->base.primary_gid)) {1655 return NT_STATUS_INVALID_PARAMETER;1656 }1657 1658 1172 nt_username = talloc_strdup(mem_ctx, info3->base.account_name.string); 1659 1173 if (!nt_username) { … … 1669 1183 nt_domain = domain; 1670 1184 } 1671 1672 /* try to fill the SAM account.. If getpwnam() fails, then try the 1673 add user script (2.2.x behavior). 1185 1186 /* If getpwnam() fails try the add user script (2.2.x behavior). 1674 1187 1675 1188 We use the _unmapped_ username here in an attempt to provide … … 1681 1194 that is how the current code is designed. Making the change here 1682 1195 is the least disruptive place. -- jerry */ 1683 1684 if ( !(sam_account = samu_new( NULL )) ) {1685 return NT_STATUS_NO_MEMORY;1686 }1687 1196 1688 1197 /* this call will try to create the user if necessary */ 1689 1198 1690 nt_status = fill_sam_account(mem_ctx, nt_domain, sent_nt_username,1691 &found_username, & uid, &gid, sam_account,1199 nt_status = check_account(mem_ctx, nt_domain, sent_nt_username, 1200 &found_username, &pwd, 1692 1201 &username_was_mapped); 1693 1202 1694 1695 /* if we still don't have a valid unix account check for1696 'map to guest = bad uid' */1697 1698 1203 if (!NT_STATUS_IS_OK(nt_status)) { 1699 TALLOC_FREE( sam_account );1700 if ( lp_map_to_guest() == MAP_TO_GUEST_ON_BAD_UID ) {1701 make_server_info_guest(NULL, server_info);1702 return NT_STATUS_OK;1703 }1704 1204 return nt_status; 1705 }1706 1707 if (!pdb_set_nt_username(sam_account, nt_username, PDB_CHANGED)) {1708 TALLOC_FREE(sam_account);1709 return NT_STATUS_NO_MEMORY;1710 }1711 1712 if (!pdb_set_username(sam_account, nt_username, PDB_CHANGED)) {1713 TALLOC_FREE(sam_account);1714 return NT_STATUS_NO_MEMORY;1715 }1716 1717 if (!pdb_set_domain(sam_account, nt_domain, PDB_CHANGED)) {1718 TALLOC_FREE(sam_account);1719 return NT_STATUS_NO_MEMORY;1720 }1721 1722 if (!pdb_set_user_sid(sam_account, &user_sid, PDB_CHANGED)) {1723 TALLOC_FREE(sam_account);1724 return NT_STATUS_UNSUCCESSFUL;1725 }1726 1727 if (!pdb_set_group_sid(sam_account, &group_sid, PDB_CHANGED)) {1728 TALLOC_FREE(sam_account);1729 return NT_STATUS_UNSUCCESSFUL;1730 }1731 1732 if (!pdb_set_fullname(sam_account,1733 info3->base.full_name.string,1734 PDB_CHANGED)) {1735 TALLOC_FREE(sam_account);1736 return NT_STATUS_NO_MEMORY;1737 }1738 1739 if (!pdb_set_logon_script(sam_account,1740 info3->base.logon_script.string,1741 PDB_CHANGED)) {1742 TALLOC_FREE(sam_account);1743 return NT_STATUS_NO_MEMORY;1744 }1745 1746 if (!pdb_set_profile_path(sam_account,1747 info3->base.profile_path.string,1748 PDB_CHANGED)) {1749 TALLOC_FREE(sam_account);1750 return NT_STATUS_NO_MEMORY;1751 }1752 1753 if (!pdb_set_homedir(sam_account,1754 info3->base.home_directory.string,1755 PDB_CHANGED)) {1756 TALLOC_FREE(sam_account);1757 return NT_STATUS_NO_MEMORY;1758 }1759 1760 if (!pdb_set_dir_drive(sam_account,1761 info3->base.home_drive.string,1762 PDB_CHANGED)) {1763 TALLOC_FREE(sam_account);1764 return NT_STATUS_NO_MEMORY;1765 }1766 1767 if (!pdb_set_acct_ctrl(sam_account, info3->base.acct_flags, PDB_CHANGED)) {1768 TALLOC_FREE(sam_account);1769 return NT_STATUS_NO_MEMORY;1770 }1771 1772 if (!pdb_set_pass_last_set_time(1773 sam_account,1774 nt_time_to_unix(info3->base.last_password_change),1775 PDB_CHANGED)) {1776 TALLOC_FREE(sam_account);1777 return NT_STATUS_NO_MEMORY;1778 }1779 1780 if (!pdb_set_pass_can_change_time(1781 sam_account,1782 nt_time_to_unix(info3->base.allow_password_change),1783 PDB_CHANGED)) {1784 TALLOC_FREE(sam_account);1785 return NT_STATUS_NO_MEMORY;1786 }1787 1788 if (!pdb_set_pass_must_change_time(1789 sam_account,1790 nt_time_to_unix(info3->base.force_password_change),1791 PDB_CHANGED)) {1792 TALLOC_FREE(sam_account);1793 return NT_STATUS_NO_MEMORY;1794 1205 } 1795 1206 … … 1797 1208 if (result == NULL) { 1798 1209 DEBUG(4, ("make_server_info failed!\n")); 1799 TALLOC_FREE(sam_account); 1800 return NT_STATUS_NO_MEMORY; 1801 } 1802 1803 /* save this here to _net_sam_logon() doesn't fail (it assumes a 1804 valid struct samu) */ 1805 1806 result->sam_account = sam_account; 1210 return NT_STATUS_NO_MEMORY; 1211 } 1212 1807 1213 result->unix_name = talloc_strdup(result, found_username); 1808 1214 … … 1814 1220 } 1815 1221 1222 /* copy in the info3 */ 1223 result->info3 = i3 = copy_netr_SamInfo3(result, info3); 1224 if (result->info3 == NULL) { 1225 TALLOC_FREE(result); 1226 return NT_STATUS_NO_MEMORY; 1227 } 1228 1816 1229 /* Fill in the unix info we found on the way */ 1817 1818 result->utok.uid = uid; 1819 result->utok.gid = gid; 1820 1821 /* Create a 'combined' list of all SIDs we might want in the SD */ 1822 1823 result->num_sids = 0; 1824 result->sids = NULL; 1825 1826 nt_status = sid_array_from_info3(result, info3, 1827 &result->sids, 1828 &result->num_sids, 1829 false, false); 1230 result->utok.uid = pwd->pw_uid; 1231 result->utok.gid = pwd->pw_gid; 1232 1233 /* We can't just trust that the primary group sid sent us is something 1234 * we can really use. Obtain the useable sid, and store the original 1235 * one as an additional group if it had to be replaced */ 1236 nt_status = get_primary_group_sid(mem_ctx, found_username, 1237 &pwd, &group_sid); 1830 1238 if (!NT_STATUS_IS_OK(nt_status)) { 1831 1239 TALLOC_FREE(result); … … 1833 1241 } 1834 1242 1835 /* Ensure the primary group sid is at position 0. */ 1836 sort_sid_array_for_smbd(result, &group_sid); 1837 1838 result->login_server = talloc_strdup(result, 1839 info3->base.logon_server.string); 1243 /* store and check if it is the same we got originally */ 1244 sid_peek_rid(group_sid, &i3->base.primary_gid); 1245 if (i3->base.primary_gid != info3->base.primary_gid) { 1246 uint32_t n = i3->base.groups.count; 1247 /* not the same, store the original as an additional group */ 1248 i3->base.groups.rids = 1249 talloc_realloc(i3, i3->base.groups.rids, 1250 struct samr_RidWithAttribute, n + 1); 1251 if (i3->base.groups.rids == NULL) { 1252 TALLOC_FREE(result); 1253 return NT_STATUS_NO_MEMORY; 1254 } 1255 i3->base.groups.rids[n].rid = info3->base.primary_gid; 1256 i3->base.groups.rids[n].attributes = SE_GROUP_ENABLED; 1257 i3->base.groups.count = n + 1; 1258 } 1840 1259 1841 1260 /* ensure we are never given NULL session keys */ 1842 1843 ZERO_STRUCT(zeros);1844 1261 1845 1262 if (memcmp(info3->base.key.key, zeros, sizeof(zeros)) == 0) { … … 1874 1291 const char *domain, 1875 1292 const struct wbcAuthUserInfo *info, 1876 auth_serversupplied_info **server_info) 1877 { 1878 char zeros[16]; 1879 1880 NTSTATUS nt_status = NT_STATUS_OK; 1881 char *found_username = NULL; 1882 const char *nt_domain; 1883 const char *nt_username; 1884 struct samu *sam_account = NULL; 1885 DOM_SID user_sid; 1886 DOM_SID group_sid; 1887 bool username_was_mapped; 1888 uint32_t i; 1889 1890 uid_t uid = (uid_t)-1; 1891 gid_t gid = (gid_t)-1; 1892 1893 auth_serversupplied_info *result; 1894 1895 result = make_server_info(NULL); 1896 if (result == NULL) { 1897 DEBUG(4, ("make_server_info failed!\n")); 1898 return NT_STATUS_NO_MEMORY; 1899 } 1900 1901 /* 1902 Here is where we should check the list of 1903 trusted domains, and verify that the SID 1904 matches. 1905 */ 1906 1907 memcpy(&user_sid, &info->sids[0].sid, sizeof(user_sid)); 1908 memcpy(&group_sid, &info->sids[1].sid, sizeof(group_sid)); 1909 1910 if (info->account_name) { 1911 nt_username = talloc_strdup(result, info->account_name); 1912 } else { 1913 /* If the server didn't give us one, just use the one we sent 1914 * them */ 1915 nt_username = talloc_strdup(result, sent_nt_username); 1916 } 1917 if (!nt_username) { 1918 TALLOC_FREE(result); 1919 return NT_STATUS_NO_MEMORY; 1920 } 1921 1922 if (info->domain_name) { 1923 nt_domain = talloc_strdup(result, info->domain_name); 1924 } else { 1925 /* If the server didn't give us one, just use the one we sent 1926 * them */ 1927 nt_domain = talloc_strdup(result, domain); 1928 } 1929 if (!nt_domain) { 1930 TALLOC_FREE(result); 1931 return NT_STATUS_NO_MEMORY; 1932 } 1933 1934 /* try to fill the SAM account.. If getpwnam() fails, then try the 1935 add user script (2.2.x behavior). 1936 1937 We use the _unmapped_ username here in an attempt to provide 1938 consistent username mapping behavior between kerberos and NTLM[SSP] 1939 authentication in domain mode security. I.E. Username mapping 1940 should be applied to the fully qualified username 1941 (e.g. DOMAIN\user) and not just the login name. Yes this means we 1942 called map_username() unnecessarily in make_user_info_map() but 1943 that is how the current code is designed. Making the change here 1944 is the least disruptive place. -- jerry */ 1945 1946 if ( !(sam_account = samu_new( result )) ) { 1947 TALLOC_FREE(result); 1948 return NT_STATUS_NO_MEMORY; 1949 } 1950 1951 /* this call will try to create the user if necessary */ 1952 1953 nt_status = fill_sam_account(result, nt_domain, sent_nt_username, 1954 &found_username, &uid, &gid, sam_account, 1955 &username_was_mapped); 1956 1957 /* if we still don't have a valid unix account check for 1958 'map to guest = bad uid' */ 1959 1960 if (!NT_STATUS_IS_OK(nt_status)) { 1961 TALLOC_FREE( result ); 1962 if ( lp_map_to_guest() == MAP_TO_GUEST_ON_BAD_UID ) { 1963 make_server_info_guest(NULL, server_info); 1964 return NT_STATUS_OK; 1965 } 1966 return nt_status; 1967 } 1968 1969 if (!pdb_set_nt_username(sam_account, nt_username, PDB_CHANGED)) { 1970 TALLOC_FREE(result); 1971 return NT_STATUS_NO_MEMORY; 1972 } 1973 1974 if (!pdb_set_username(sam_account, nt_username, PDB_CHANGED)) { 1975 TALLOC_FREE(result); 1976 return NT_STATUS_NO_MEMORY; 1977 } 1978 1979 if (!pdb_set_domain(sam_account, nt_domain, PDB_CHANGED)) { 1980 TALLOC_FREE(result); 1981 return NT_STATUS_NO_MEMORY; 1982 } 1983 1984 if (!pdb_set_user_sid(sam_account, &user_sid, PDB_CHANGED)) { 1985 TALLOC_FREE(result); 1986 return NT_STATUS_UNSUCCESSFUL; 1987 } 1988 1989 if (!pdb_set_group_sid(sam_account, &group_sid, PDB_CHANGED)) { 1990 TALLOC_FREE(result); 1991 return NT_STATUS_UNSUCCESSFUL; 1992 } 1993 1994 if (!pdb_set_fullname(sam_account, info->full_name, PDB_CHANGED)) { 1995 TALLOC_FREE(result); 1996 return NT_STATUS_NO_MEMORY; 1997 } 1998 1999 if (!pdb_set_logon_script(sam_account, info->logon_script, PDB_CHANGED)) { 2000 TALLOC_FREE(result); 2001 return NT_STATUS_NO_MEMORY; 2002 } 2003 2004 if (!pdb_set_profile_path(sam_account, info->profile_path, PDB_CHANGED)) { 2005 TALLOC_FREE(result); 2006 return NT_STATUS_NO_MEMORY; 2007 } 2008 2009 if (!pdb_set_homedir(sam_account, info->home_directory, PDB_CHANGED)) { 2010 TALLOC_FREE(result); 2011 return NT_STATUS_NO_MEMORY; 2012 } 2013 2014 if (!pdb_set_dir_drive(sam_account, info->home_drive, PDB_CHANGED)) { 2015 TALLOC_FREE(result); 2016 return NT_STATUS_NO_MEMORY; 2017 } 2018 2019 if (!pdb_set_acct_ctrl(sam_account, info->acct_flags, PDB_CHANGED)) { 2020 TALLOC_FREE(result); 2021 return NT_STATUS_NO_MEMORY; 2022 } 2023 2024 if (!pdb_set_pass_last_set_time( 2025 sam_account, 2026 info->pass_last_set_time, 2027 PDB_CHANGED)) { 2028 TALLOC_FREE(result); 2029 return NT_STATUS_NO_MEMORY; 2030 } 2031 2032 if (!pdb_set_pass_can_change_time( 2033 sam_account, 2034 info->pass_can_change_time, 2035 PDB_CHANGED)) { 2036 TALLOC_FREE(result); 2037 return NT_STATUS_NO_MEMORY; 2038 } 2039 2040 if (!pdb_set_pass_must_change_time( 2041 sam_account, 2042 info->pass_must_change_time, 2043 PDB_CHANGED)) { 2044 TALLOC_FREE(result); 2045 return NT_STATUS_NO_MEMORY; 2046 } 2047 2048 /* save this here to _net_sam_logon() doesn't fail (it assumes a 2049 valid struct samu) */ 2050 2051 result->sam_account = sam_account; 2052 result->unix_name = talloc_strdup(result, found_username); 2053 2054 result->sanitized_username = sanitize_username(result, 2055 result->unix_name); 2056 result->login_server = talloc_strdup(result, info->logon_server); 2057 2058 if ((result->unix_name == NULL) 2059 || (result->sanitized_username == NULL) 2060 || (result->login_server == NULL)) { 2061 TALLOC_FREE(result); 2062 return NT_STATUS_NO_MEMORY; 2063 } 2064 2065 /* Fill in the unix info we found on the way */ 2066 2067 result->utok.uid = uid; 2068 result->utok.gid = gid; 2069 2070 /* Create a 'combined' list of all SIDs we might want in the SD */ 2071 2072 result->num_sids = info->num_sids - 2; 2073 result->sids = talloc_array(result, DOM_SID, result->num_sids); 2074 if (result->sids == NULL) { 2075 TALLOC_FREE(result); 2076 return NT_STATUS_NO_MEMORY; 2077 } 2078 2079 for (i=0; i < result->num_sids; i++) { 2080 memcpy(&result->sids[i], &info->sids[i+2].sid, sizeof(result->sids[i])); 2081 } 2082 2083 /* Ensure the primary group sid is at position 0. */ 2084 sort_sid_array_for_smbd(result, &group_sid); 2085 2086 /* ensure we are never given NULL session keys */ 2087 2088 ZERO_STRUCT(zeros); 2089 2090 if (memcmp(info->user_session_key, zeros, sizeof(zeros)) == 0) { 2091 result->user_session_key = data_blob_null; 2092 } else { 2093 result->user_session_key = data_blob_talloc( 2094 result, info->user_session_key, 2095 sizeof(info->user_session_key)); 2096 } 2097 2098 if (memcmp(info->lm_session_key, zeros, 8) == 0) { 2099 result->lm_session_key = data_blob_null; 2100 } else { 2101 result->lm_session_key = data_blob_talloc( 2102 result, info->lm_session_key, 2103 sizeof(info->lm_session_key)); 2104 } 2105 2106 result->nss_token |= username_was_mapped; 2107 2108 *server_info = result; 2109 2110 return NT_STATUS_OK; 2111 } 2112 2113 /*************************************************************************** 2114 Free a user_info struct 2115 ***************************************************************************/ 2116 2117 void free_user_info(auth_usersupplied_info **user_info) 2118 { 2119 DEBUG(5,("attempting to free (and zero) a user_info structure\n")); 2120 if (*user_info != NULL) { 2121 if ((*user_info)->smb_name) { 2122 DEBUG(10,("structure was created for %s\n", 2123 (*user_info)->smb_name)); 2124 } 2125 SAFE_FREE((*user_info)->smb_name); 2126 SAFE_FREE((*user_info)->internal_username); 2127 SAFE_FREE((*user_info)->client_domain); 2128 SAFE_FREE((*user_info)->domain); 2129 SAFE_FREE((*user_info)->wksta_name); 2130 data_blob_free(&(*user_info)->lm_resp); 2131 data_blob_free(&(*user_info)->nt_resp); 2132 data_blob_clear_free(&(*user_info)->lm_interactive_pwd); 2133 data_blob_clear_free(&(*user_info)->nt_interactive_pwd); 2134 data_blob_clear_free(&(*user_info)->plaintext_password); 2135 ZERO_STRUCT(**user_info); 2136 } 2137 SAFE_FREE(*user_info); 2138 } 2139 2140 /*************************************************************************** 2141 Make an auth_methods struct 2142 ***************************************************************************/ 2143 2144 bool make_auth_methods(struct auth_context *auth_context, auth_methods **auth_method) 2145 { 2146 if (!auth_context) { 2147 smb_panic("no auth_context supplied to " 2148 "make_auth_methods()!\n"); 2149 } 2150 2151 if (!auth_method) { 2152 smb_panic("make_auth_methods: pointer to auth_method pointer " 2153 "is NULL!\n"); 2154 } 2155 2156 *auth_method = TALLOC_P(auth_context->mem_ctx, auth_methods); 2157 if (!*auth_method) { 2158 DEBUG(0,("make_auth_method: malloc failed!\n")); 2159 return False; 2160 } 2161 ZERO_STRUCTP(*auth_method); 2162 2163 return True; 1293 struct auth_serversupplied_info **server_info) 1294 { 1295 struct netr_SamInfo3 *info3; 1296 1297 info3 = wbcAuthUserInfo_to_netr_SamInfo3(mem_ctx, info); 1298 if (!info3) { 1299 return NT_STATUS_NO_MEMORY; 1300 } 1301 1302 return make_server_info_info3(mem_ctx, 1303 sent_nt_username, domain, 1304 server_info, info3); 2164 1305 } 2165 1306 … … 2174 1315 bool is_trusted_domain(const char* dom_name) 2175 1316 { 2176 DOM_SIDtrustdom_sid;1317 struct dom_sid trustdom_sid; 2177 1318 bool ret; 2178 1319 … … 2220 1361 and running. We need to update the trustdom_cache 2221 1362 ourselves */ 2222 1363 2223 1364 update_trustdom_cache(); 2224 1365 } -
trunk/server/source3/auth/auth_wbc.c
r414 r745 39 39 40 40 #include "includes.h" 41 #include "auth.h" 42 #include "nsswitch/libwbclient/wbclient.h" 41 43 42 44 #undef DBGC_CLASS … … 48 50 void *my_private_data, 49 51 TALLOC_CTX *mem_ctx, 50 const auth_usersupplied_info *user_info,51 auth_serversupplied_info **server_info)52 const struct auth_usersupplied_info *user_info, 53 struct auth_serversupplied_info **server_info) 52 54 { 53 55 NTSTATUS nt_status; … … 60 62 return NT_STATUS_INVALID_PARAMETER; 61 63 } 64 65 ZERO_STRUCT(params); 66 62 67 /* Send off request */ 63 68 64 params.account_name = user_info->smb_name; 65 params.domain_name = user_info->domain; 66 params.workstation_name = user_info->wksta_name; 69 DEBUG(10, ("Check auth for: [%s]", user_info->mapped.account_name)); 70 71 params.account_name = user_info->client.account_name; 72 params.domain_name = user_info->mapped.domain_name; 73 params.workstation_name = user_info->workstation_name; 67 74 68 75 params.flags = 0; … … 70 77 71 78 /* Handle plaintext */ 72 if (!user_info->encrypted) { 79 switch (user_info->password_state) { 80 case AUTH_PASSWORD_PLAIN: 81 { 73 82 DEBUG(3,("Checking plaintext password for %s.\n", 74 user_info-> internal_username));83 user_info->mapped.account_name)); 75 84 params.level = WBC_AUTH_USER_LEVEL_PLAIN; 76 85 77 params.password.plaintext = (char *)user_info->plaintext_password.data; 78 } else { 86 params.password.plaintext = user_info->password.plaintext; 87 break; 88 } 89 case AUTH_PASSWORD_RESPONSE: 90 case AUTH_PASSWORD_HASH: 91 { 79 92 DEBUG(3,("Checking encrypted password for %s.\n", 80 user_info-> internal_username));93 user_info->mapped.account_name)); 81 94 params.level = WBC_AUTH_USER_LEVEL_RESPONSE; 82 95 … … 85 98 sizeof(params.password.response.challenge)); 86 99 87 params.password.response.nt_length = user_info->nt_resp.length; 88 params.password.response.nt_data = user_info->nt_resp.data; 89 params.password.response.lm_length = user_info->lm_resp.length; 90 params.password.response.lm_data = user_info->lm_resp.data; 100 if (user_info->password.response.nt.length != 0) { 101 params.password.response.nt_length = 102 user_info->password.response.nt.length; 103 params.password.response.nt_data = 104 user_info->password.response.nt.data; 105 } 106 if (user_info->password.response.lanman.length != 0) { 107 params.password.response.lm_length = 108 user_info->password.response.lanman.length; 109 params.password.response.lm_data = 110 user_info->password.response.lanman.data; 111 } 112 break; 113 } 114 default: 115 DEBUG(0,("user_info constructed for user '%s' was invalid - password_state=%u invalid.\n",user_info->mapped.account_name, user_info->password_state)); 116 return NT_STATUS_INTERNAL_ERROR; 117 #if 0 /* If ever implemented in libwbclient */ 118 case AUTH_PASSWORD_HASH: 119 { 120 DEBUG(3,("Checking logon (hash) password for %s.\n", 121 user_info->mapped.account_name)); 122 params.level = WBC_AUTH_USER_LEVEL_HASH; 91 123 124 if (user_info->password.hash.nt) { 125 memcpy(params.password.hash.nt_hash, user_info->password.hash.nt, sizeof(* user_info->password.hash.nt)); 126 } else { 127 memset(params.password.hash.nt_hash, '\0', sizeof(params.password.hash.nt_hash)); 128 } 129 130 if (user_info->password.hash.lanman) { 131 memcpy(params.password.hash.lm_hash, user_info->password.hash.lanman, sizeof(* user_info->password.hash.lanman)); 132 } else { 133 memset(params.password.hash.lm_hash, '\0', sizeof(params.password.hash.lm_hash)); 134 } 135 136 } 137 #endif 92 138 } 93 139 … … 119 165 120 166 nt_status = make_server_info_wbcAuthUserInfo(mem_ctx, 121 user_info-> smb_name,122 user_info-> domain,167 user_info->client.account_name, 168 user_info->mapped.domain_name, 123 169 info, server_info); 124 170 wbcFreeMemory(info); … … 135 181 static NTSTATUS auth_init_wbc(struct auth_context *auth_context, const char *param, auth_methods **auth_method) 136 182 { 137 if (!make_auth_methods(auth_context, auth_method)) { 183 struct auth_methods *result; 184 185 result = TALLOC_ZERO_P(auth_context, struct auth_methods); 186 if (result == NULL) { 138 187 return NT_STATUS_NO_MEMORY; 139 188 } 189 result->name = "wbc"; 190 result->auth = check_wbc_security; 140 191 141 (*auth_method)->name = "wbc"; 142 (*auth_method)->auth = check_wbc_security; 143 192 *auth_method = result; 144 193 return NT_STATUS_OK; 145 194 } -
trunk/server/source3/auth/auth_winbind.c
r414 r745 6 6 Copyright (C) Tim Potter 2000 7 7 Copyright (C) Andrew Bartlett 2001 - 2002 8 8 9 9 This program is free software; you can redistribute it and/or modify 10 10 it under the terms of the GNU General Public License as published by 11 11 the Free Software Foundation; either version 3 of the License, or 12 12 (at your option) any later version. 13 13 14 14 This program is distributed in the hope that it will be useful, 15 15 but WITHOUT ANY WARRANTY; without even the implied warranty of 16 16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17 17 GNU General Public License for more details. 18 18 19 19 You should have received a copy of the GNU General Public License 20 20 along with this program. If not, see <http://www.gnu.org/licenses/>. … … 22 22 23 23 #include "includes.h" 24 #include "auth.h" 25 #include "nsswitch/libwbclient/wbclient.h" 24 26 25 27 #undef DBGC_CLASS … … 31 33 void *my_private_data, 32 34 TALLOC_CTX *mem_ctx, 33 const auth_usersupplied_info *user_info,34 auth_serversupplied_info **server_info)35 const struct auth_usersupplied_info *user_info, 36 struct auth_serversupplied_info **server_info) 35 37 { 36 38 NTSTATUS nt_status; … … 40 42 struct wbcAuthErrorInfo *err = NULL; 41 43 44 ZERO_STRUCT(params); 45 42 46 if (!user_info) { 43 47 return NT_STATUS_INVALID_PARAMETER; 44 48 } 45 49 50 DEBUG(10, ("Check auth for: [%s]\n", user_info->mapped.account_name)); 51 46 52 if (!auth_context) { 47 53 DEBUG(3,("Password for user %s cannot be checked because we have no auth_info to get the challenge from.\n", 48 user_info-> internal_username));54 user_info->mapped.account_name)); 49 55 return NT_STATUS_INVALID_PARAMETER; 50 56 } 51 57 52 if (strequal(user_info-> domain, get_global_sam_name())) {58 if (strequal(user_info->mapped.domain_name, get_global_sam_name())) { 53 59 DEBUG(3,("check_winbind_security: Not using winbind, requested domain [%s] was for this SAM.\n", 54 user_info-> domain));60 user_info->mapped.domain_name)); 55 61 return NT_STATUS_NOT_IMPLEMENTED; 56 62 } … … 58 64 /* Send off request */ 59 65 60 params.account_name = user_info-> smb_name;61 params.domain_name = user_info-> domain;62 params.workstation_name = user_info->w ksta_name;66 params.account_name = user_info->client.account_name; 67 params.domain_name = user_info->mapped.domain_name; 68 params.workstation_name = user_info->workstation_name; 63 69 64 70 params.flags = 0; … … 71 77 sizeof(params.password.response.challenge)); 72 78 73 params.password.response.nt_length = user_info->nt_resp.length; 74 params.password.response.nt_data = user_info->nt_resp.data; 75 params.password.response.lm_length = user_info->lm_resp.length; 76 params.password.response.lm_data = user_info->lm_resp.data; 79 if (user_info->password.response.nt.length != 0) { 80 params.password.response.nt_length = 81 user_info->password.response.nt.length; 82 params.password.response.nt_data = 83 user_info->password.response.nt.data; 84 } 85 if (user_info->password.response.lanman.length != 0) { 86 params.password.response.lm_length = 87 user_info->password.response.lanman.length; 88 params.password.response.lm_data = 89 user_info->password.response.lanman.data; 90 } 77 91 78 92 /* we are contacting the privileged pipe */ … … 97 111 return auth_method->auth(auth_context, auth_method->private_data, 98 112 mem_ctx, user_info, server_info); 99 else 100 /* log an error since this should not happen */ 101 DEBUG(0,("check_winbind_security: ERROR! my_private_data == NULL!\n")); 113 return NT_STATUS_LOGON_FAILURE; 102 114 } 103 115 … … 113 125 114 126 nt_status = make_server_info_wbcAuthUserInfo(mem_ctx, 115 user_info-> smb_name,116 user_info-> domain,127 user_info->client.account_name, 128 user_info->mapped.domain_name, 117 129 info, server_info); 118 130 wbcFreeMemory(info); … … 129 141 static NTSTATUS auth_init_winbind(struct auth_context *auth_context, const char *param, auth_methods **auth_method) 130 142 { 131 if (!make_auth_methods(auth_context, auth_method)) { 143 struct auth_methods *result; 144 145 result = TALLOC_ZERO_P(auth_context, struct auth_methods); 146 if (result == NULL) { 132 147 return NT_STATUS_NO_MEMORY; 133 148 } 134 135 (*auth_method)->name = "winbind"; 136 (*auth_method)->auth = check_winbind_security; 149 result->name = "winbind"; 150 result->auth = check_winbind_security; 137 151 138 152 if (param && *param) { … … 143 157 return NT_STATUS_UNSUCCESSFUL; 144 158 } 145 (*auth_method)->private_data = (void *)priv;159 result->private_data = (void *)priv; 146 160 } 161 162 *auth_method = result; 147 163 return NT_STATUS_OK; 148 164 } -
trunk/server/source3/auth/pampass.c
r414 r745 6 6 Copyright (C) Andrew Bartlett 2001 7 7 Copyright (C) Jeremy Allison 2001 8 8 9 9 This program is free software; you can redistribute it and/or modify 10 10 it under the terms of the GNU General Public License as published by 11 11 the Free Software Foundation; either version 3 of the License, or 12 12 (at your option) any later version. 13 13 14 14 This program is distributed in the hope that it will be useful, 15 15 but WITHOUT ANY WARRANTY; without even the implied warranty of 16 16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17 17 GNU General Public License for more details. 18 18 19 19 You should have received a copy of the GNU General Public License 20 20 along with this program. If not, see <http://www.gnu.org/licenses/>. … … 28 28 29 29 #include "includes.h" 30 #include "auth.h" 31 #include "../libcli/auth/pam_errors.h" 30 32 31 33 #undef DBGC_CLASS … … 60 62 typedef int (*smb_pam_conv_fn)(int, const struct pam_message **, struct pam_response **, void *appdata_ptr); 61 63 62 /* 63 * Macros to help make life easy 64 */ 65 #define COPY_STRING(s) (s) ? SMB_STRDUP(s) : NULL 66 #define COPY_FSTRING(s) (s[0]) ? SMB_STRDUP(s) : NULL 64 static char *smb_pam_copy_string(const char *s) 65 { 66 if (s == NULL) { 67 return NULL; 68 } 69 return SMB_STRDUP(s); 70 } 71 72 static char *smb_pam_copy_fstring(const char *s) 73 { 74 if (s[0] == '\0') { 75 return NULL; 76 } 77 return SMB_STRDUP(s); 78 } 67 79 68 80 /******************************************************************* … … 76 88 DEBUG(dbglvl, ("smb_pam_error_handler: PAM: %s : %s\n", 77 89 msg, pam_strerror(pamh, pam_error))); 78 79 90 return False; 80 91 } … … 145 156 case PAM_PROMPT_ECHO_ON: 146 157 reply[replies].resp_retcode = PAM_SUCCESS; 147 reply[replies].resp = COPY_STRING(udp->PAM_username); 158 reply[replies].resp = smb_pam_copy_string( 159 udp->PAM_username); 148 160 /* PAM frees resp */ 149 161 break; … … 151 163 case PAM_PROMPT_ECHO_OFF: 152 164 reply[replies].resp_retcode = PAM_SUCCESS; 153 reply[replies].resp = COPY_STRING(udp->PAM_password); 165 reply[replies].resp = smb_pam_copy_string( 166 udp->PAM_password); 154 167 /* PAM frees resp */ 155 168 break; … … 281 294 bool found; 282 295 *resp = NULL; 283 296 284 297 DEBUG(10,("smb_pam_passchange_conv: starting converstation for %d messages\n", num_msg)); 285 298 … … 326 339 pwd_sub(current_reply, udp->PAM_username, udp->PAM_password, udp->PAM_newpassword); 327 340 #ifdef DEBUG_PASSWORD 328 DEBUG(100,("smb_pam_passchange_conv: PAM_PROMPT_ECHO_ON: We actual y sent: %s\n", current_reply));341 DEBUG(100,("smb_pam_passchange_conv: PAM_PROMPT_ECHO_ON: We actually sent: %s\n", current_reply)); 329 342 #endif 330 343 reply[replies].resp_retcode = PAM_SUCCESS; 331 reply[replies].resp = COPY_FSTRING(current_reply); 344 reply[replies].resp = smb_pam_copy_fstring( 345 current_reply); 332 346 found = True; 333 347 break; … … 357 371 pwd_sub(current_reply, udp->PAM_username, udp->PAM_password, udp->PAM_newpassword); 358 372 reply[replies].resp_retcode = PAM_SUCCESS; 359 reply[replies].resp = COPY_FSTRING(current_reply); 373 reply[replies].resp = smb_pam_copy_fstring( 374 current_reply); 360 375 #ifdef DEBUG_PASSWORD 361 DEBUG(100,("smb_pam_passchange_conv: PAM_PROMPT_ECHO_OFF: We actual y sent: %s\n", current_reply));376 DEBUG(100,("smb_pam_passchange_conv: PAM_PROMPT_ECHO_OFF: We actually sent: %s\n", current_reply)); 362 377 #endif 363 378 found = True; … … 366 381 } 367 382 /* PAM frees resp */ 368 383 369 384 if (!found) { 370 385 DEBUG(3,("smb_pam_passchange_conv: Could not find reply for PAM prompt: %s\n",msg[replies]->msg)); … … 383 398 reply[replies].resp = NULL; 384 399 break; 385 400 386 401 default: 387 402 /* Must be an error of some sort... */ … … 391 406 } 392 407 } 393 408 394 409 free_pw_chat(pw_chat); 395 410 if (reply) … … 444 459 445 460 smb_free_pam_conv(smb_pam_conv_ptr); 446 461 447 462 if( pamh != NULL ) { 448 463 pam_error = pam_end(pamh, 0); … … 463 478 { 464 479 int pam_error; 465 #ifdef PAM_RHOST466 const char *our_rhost;467 char addr[INET6_ADDRSTRLEN];468 #endif469 480 470 481 *pamh = (pam_handle_t *)NULL; … … 478 489 } 479 490 480 #ifdef PAM_RHOST 481 if (rhost == NULL) { 482 our_rhost = client_name(get_client_fd()); 483 if (strequal(our_rhost,"UNKNOWN")) 484 our_rhost = client_addr(get_client_fd(),addr,sizeof(addr)); 485 } else { 486 our_rhost = rhost; 487 } 488 489 DEBUG(4,("smb_pam_start: PAM: setting rhost to: %s\n", our_rhost)); 490 pam_error = pam_set_item(*pamh, PAM_RHOST, our_rhost); 491 #if HAVE_PAM_RHOST 492 DEBUG(4,("smb_pam_start: PAM: setting rhost to: %s\n", rhost)); 493 pam_error = pam_set_item(*pamh, PAM_RHOST, rhost); 491 494 if(!smb_pam_error_handler(*pamh, pam_error, "set rhost failed", 0)) { 492 495 smb_pam_end(*pamh, pconv); … … 495 498 } 496 499 #endif 497 #if defPAM_TTY500 #if HAVE_PAM_TTY 498 501 DEBUG(4,("smb_pam_start: PAM: setting tty\n")); 499 502 pam_error = pam_set_item(*pamh, PAM_TTY, "samba"); … … 520 523 * auth required /lib/security/pam_pwdb.so nullok shadow audit 521 524 */ 522 525 523 526 DEBUG(4,("smb_pam_auth: PAM: Authenticate User: %s\n", user)); 524 527 pam_error = pam_authenticate(pamh, PAM_SILENT | lp_null_passwords() ? 0 : PAM_DISALLOW_NULL_AUTHTOK); … … 640 643 int pam_error; 641 644 642 #if defPAM_TTY645 #if HAVE_PAM_TTY 643 646 DEBUG(4,("smb_internal_pam_session: PAM: tty set to: %s\n", tty)); 644 647 pam_error = pam_set_item(pamh, PAM_TTY, tty); … … 774 777 */ 775 778 776 NTSTATUS smb_pam_accountcheck(const char * user)779 NTSTATUS smb_pam_accountcheck(const char *user, const char *rhost) 777 780 { 778 781 NTSTATUS nt_status = NT_STATUS_ACCOUNT_DISABLED; … … 788 791 return NT_STATUS_NO_MEMORY; 789 792 790 if (!smb_pam_start(&pamh, user, NULL, pconv))793 if (!smb_pam_start(&pamh, user, rhost, pconv)) 791 794 return NT_STATUS_ACCOUNT_DISABLED; 792 795 … … 802 805 */ 803 806 804 NTSTATUS smb_pam_passcheck(const char * user, const char * password) 807 NTSTATUS smb_pam_passcheck(const char * user, const char * rhost, 808 const char * password) 805 809 { 806 810 pam_handle_t *pamh = NULL; … … 817 821 return NT_STATUS_LOGON_FAILURE; 818 822 819 if (!smb_pam_start(&pamh, user, NULL, pconv))823 if (!smb_pam_start(&pamh, user, rhost, pconv)) 820 824 return NT_STATUS_LOGON_FAILURE; 821 825 … … 846 850 */ 847 851 848 bool smb_pam_passchange(const char * user, const char * oldpassword, const char * newpassword) 852 bool smb_pam_passchange(const char *user, const char *rhost, 853 const char *oldpassword, const char *newpassword) 849 854 { 850 855 /* Appropriate quantities of root should be obtained BEFORE calling this function */ … … 855 860 return False; 856 861 857 if(!smb_pam_start(&pamh, user, NULL, pconv))862 if(!smb_pam_start(&pamh, user, rhost, pconv)) 858 863 return False; 859 864 … … 870 875 871 876 /* If PAM not used, no PAM restrictions on accounts. */ 872 NTSTATUS smb_pam_accountcheck(const char * user)877 NTSTATUS smb_pam_accountcheck(const char *user, const char *rhost) 873 878 { 874 879 return NT_STATUS_OK; -
trunk/server/source3/auth/pass_check.c
r414 r745 1 /* 1 /* 2 2 Unix SMB/CIFS implementation. 3 3 Password checking 4 4 Copyright (C) Andrew Tridgell 1992-1998 5 5 6 6 This program is free software; you can redistribute it and/or modify 7 7 it under the terms of the GNU General Public License as published by 8 8 the Free Software Foundation; either version 3 of the License, or 9 9 (at your option) any later version. 10 10 11 11 This program is distributed in the hope that it will be useful, 12 12 but WITHOUT ANY WARRANTY; without even the implied warranty of 13 13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 14 GNU General Public License for more details. 15 15 16 16 You should have received a copy of the GNU General Public License 17 17 along with this program. If not, see <http://www.gnu.org/licenses/>. … … 22 22 23 23 #include "includes.h" 24 #include "system/passwd.h" 25 #include "auth.h" 24 26 25 27 #undef DBGC_CLASS 26 28 #define DBGC_CLASS DBGC_AUTH 29 30 /* what is the longest significant password available on your system? 31 Knowing this speeds up password searches a lot */ 32 #ifndef PASSWORD_LENGTH 33 #define PASSWORD_LENGTH 8 34 #endif 27 35 28 36 /* these are kept here to keep the string_combinations function simple */ … … 493 501 it assumes the string starts lowercased 494 502 ****************************************************************************/ 495 static NTSTATUS string_combinations2(char *s, int offset, NTSTATUS (*fn) (const char *), 496 int N) 503 static NTSTATUS string_combinations2(char *s, int offset, 504 NTSTATUS (*fn)(const char *s, 505 void *private_data), 506 int N, void *private_data) 497 507 { 498 508 int len = strlen(s); … … 505 515 506 516 if (N <= 0 || offset >= len) 507 return (fn(s ));517 return (fn(s, private_data)); 508 518 509 519 for (i = offset; i < (len - (N - 1)); i++) { 510 520 char c = s[i]; 511 if (!islower_ ascii(c))521 if (!islower_m(c)) 512 522 continue; 513 s[i] = toupper_ascii(c); 514 if (!NT_STATUS_EQUAL(nt_status = string_combinations2(s, i + 1, fn, N - 1),NT_STATUS_WRONG_PASSWORD)) { 515 return (nt_status); 523 s[i] = toupper_m(c); 524 nt_status = string_combinations2(s, i + 1, fn, N - 1, 525 private_data); 526 if (!NT_STATUS_EQUAL(nt_status, NT_STATUS_WRONG_PASSWORD)) { 527 return nt_status; 516 528 } 517 529 s[i] = c; … … 527 539 it assumes the string starts lowercased 528 540 ****************************************************************************/ 529 static NTSTATUS string_combinations(char *s, NTSTATUS (*fn) (const char *), int N) 541 static NTSTATUS string_combinations(char *s, 542 NTSTATUS (*fn)(const char *s, 543 void *private_data), 544 int N, void *private_data) 530 545 { 531 546 int n; 532 547 NTSTATUS nt_status; 533 for (n = 1; n <= N; n++) 534 if (!NT_STATUS_EQUAL(nt_status = string_combinations2(s, 0, fn, n), NT_STATUS_WRONG_PASSWORD)) 548 for (n = 1; n <= N; n++) { 549 nt_status = string_combinations2(s, 0, fn, n, private_data); 550 if (!NT_STATUS_EQUAL(nt_status, NT_STATUS_WRONG_PASSWORD)) { 535 551 return nt_status; 552 } 553 } 536 554 return NT_STATUS_WRONG_PASSWORD; 537 555 } … … 541 559 core of password checking routine 542 560 ****************************************************************************/ 543 static NTSTATUS password_check(const char *password )561 static NTSTATUS password_check(const char *password, void *private_data) 544 562 { 545 563 #ifdef WITH_PAM 546 return smb_pam_passcheck(get_this_user(), password); 564 const char *rhost = (const char *)private_data; 565 return smb_pam_passcheck(get_this_user(), rhost, password); 547 566 #else 548 567 … … 560 579 561 580 #ifdef OSF1_ENH_SEC 562 581 563 582 ret = (strcmp(osf1_bigcrypt(password, get_this_salt()), 564 583 get_this_crypted()) == 0); … … 573 592 return NT_STATUS_WRONG_PASSWORD; 574 593 } 575 594 576 595 #endif /* OSF1_ENH_SEC */ 577 596 578 597 #ifdef ULTRIX_AUTH 579 598 ret = (strcmp((char *)crypt16(password, get_this_salt()), get_this_crypted()) == 0); … … 583 602 return NT_STATUS_WRONG_PASSWORD; 584 603 } 585 604 586 605 #endif /* ULTRIX_AUTH */ 587 606 588 607 #ifdef LINUX_BIGCRYPT 589 608 ret = (linux_bigcrypt(password, get_this_salt(), get_this_crypted())); … … 594 613 } 595 614 #endif /* LINUX_BIGCRYPT */ 596 615 597 616 #if defined(HAVE_BIGCRYPT) && defined(HAVE_CRYPT) && defined(USE_BOTH_CRYPT_CALLS) 598 617 599 618 /* 600 619 * Some systems have bigcrypt in the C library but might not … … 614 633 } 615 634 #else /* HAVE_BIGCRYPT && HAVE_CRYPT && USE_BOTH_CRYPT_CALLS */ 616 635 617 636 #ifdef HAVE_BIGCRYPT 618 637 ret = (strcmp(bigcrypt(password, get_this_salt()), get_this_crypted()) == 0); … … 623 642 } 624 643 #endif /* HAVE_BIGCRYPT */ 625 644 626 645 #ifndef HAVE_CRYPT 627 646 DEBUG(1, ("Warning - no crypt available\n")); … … 648 667 ****************************************************************************/ 649 668 650 NTSTATUS pass_check(const struct passwd *pass, const char *user, const char *password, 651 int pwlen, bool (*fn) (const char *, const char *), bool run_cracker) 669 NTSTATUS pass_check(const struct passwd *pass, 670 const char *user, 671 const char *rhost, 672 const char *password, 673 bool run_cracker) 652 674 { 653 675 char *pass2 = NULL; … … 663 685 return NT_STATUS_LOGON_FAILURE; 664 686 665 if (( (!*password) || (!pwlen)) && !lp_null_passwords())687 if ((!*password) && !lp_null_passwords()) 666 688 return NT_STATUS_LOGON_FAILURE; 667 689 … … 677 699 } 678 700 679 DEBUG(4, ("pass_check: Checking (PAM) password for user %s (l=%d)\n", user, pwlen));701 DEBUG(4, ("pass_check: Checking (PAM) password for user %s\n", user)); 680 702 681 703 #else /* Not using PAM */ 682 704 683 DEBUG(4, ("pass_check: Checking password for user %s (l=%d)\n", user, pwlen));705 DEBUG(4, ("pass_check: Checking password for user %s\n", user)); 684 706 685 707 if (!pass) { … … 819 841 820 842 /* try it as it came to us */ 821 nt_status = password_check(password );843 nt_status = password_check(password, (void *)rhost); 822 844 if NT_STATUS_IS_OK(nt_status) { 823 if (fn) {824 fn(user, password);825 }826 845 return (nt_status); 827 846 } else if (!NT_STATUS_EQUAL(nt_status, NT_STATUS_WRONG_PASSWORD)) { … … 850 869 if (strhasupper(pass2)) { 851 870 strlower_m(pass2); 852 if NT_STATUS_IS_OK(nt_status = password_check(pass2)) { 853 if (fn) 854 fn(user, pass2); 871 nt_status = password_check(pass2, (void *)rhost); 872 if (NT_STATUS_IS_OK(nt_status)) { 855 873 return (nt_status); 856 874 } … … 864 882 /* last chance - all combinations of up to level chars upper! */ 865 883 strlower_m(pass2); 866 867 if (NT_STATUS_IS_OK(nt_status = string_combinations(pass2, password_check, level))) { 868 if (fn) 869 fn(user, pass2); 884 885 nt_status = string_combinations(pass2, password_check, level, 886 (void *)rhost); 887 if (NT_STATUS_IS_OK(nt_status)) { 870 888 return nt_status; 871 889 } 872 890 873 891 return NT_STATUS_WRONG_PASSWORD; 874 892 } -
trunk/server/source3/auth/token_util.c
r414 r745 26 26 27 27 #include "includes.h" 28 #include "auth.h" 29 #include "secrets.h" 30 #include "memcache.h" 31 #include "../librpc/gen_ndr/netlogon.h" 32 #include "../libcli/security/security.h" 33 #include "../lib/util/util_pw.h" 34 #include "passdb.h" 35 #include "lib/privileges.h" 28 36 29 37 /**************************************************************************** 30 Check for a SID in an NT_USER_TOKEN38 Check for a SID in an struct security_token 31 39 ****************************************************************************/ 32 40 33 bool nt_token_check_sid ( const DOM_SID *sid, const NT_USER_TOKEN *token ) 34 { 35 int i; 36 41 bool nt_token_check_sid ( const struct dom_sid *sid, const struct security_token *token ) 42 { 37 43 if ( !sid || !token ) 38 44 return False; 39 45 40 for ( i=0; i<token->num_sids; i++ ) { 41 if ( sid_equal( sid, &token->user_sids[i] ) ) 42 return True; 43 } 44 45 return False; 46 } 47 48 bool nt_token_check_domain_rid( NT_USER_TOKEN *token, uint32 rid ) 49 { 50 DOM_SID domain_sid; 46 return security_token_has_sid(token, sid); 47 } 48 49 bool nt_token_check_domain_rid( struct security_token *token, uint32 rid ) 50 { 51 struct dom_sid domain_sid; 51 52 52 53 /* if we are a domain member, the get the domain SID, else for … … 73 74 This is similar to running under the context of the LOCAL_SYSTEM account 74 75 in Windows. This is a read-only token. Do not modify it or free() it. 75 Create a copy if you rneed to change it.76 Create a copy if you need to change it. 76 77 ******************************************************************************/ 77 78 78 NT_USER_TOKEN*get_root_nt_token( void )79 { 80 struct nt_user_token *token, *for_cache;81 DOM_SIDu_sid, g_sid;79 struct security_token *get_root_nt_token( void ) 80 { 81 struct security_token *token, *for_cache; 82 struct dom_sid u_sid, g_sid; 82 83 struct passwd *pw; 83 84 void *cache_data; … … 89 90 if (cache_data != NULL) { 90 91 return talloc_get_type_abort( 91 cache_data, struct nt_user_token);92 cache_data, struct security_token); 92 93 } 93 94 … … 106 107 gid_to_sid(&g_sid, pw->pw_gid); 107 108 108 token = create_local_nt_token(talloc_ autofree_context(), &u_sid, False,109 token = create_local_nt_token(talloc_tos(), &u_sid, False, 109 110 1, &global_sid_Builtin_Administrators); 110 111 111 token->privileges = se_disk_operators;112 security_token_set_privilege(token, SEC_PRIV_DISK_OPERATOR); 112 113 113 114 for_cache = token; … … 125 126 */ 126 127 127 NTSTATUS add_aliases(const DOM_SID*domain_sid,128 struct nt_user_token *token)128 NTSTATUS add_aliases(const struct dom_sid *domain_sid, 129 struct security_token *token) 129 130 { 130 131 uint32 *aliases; … … 141 142 142 143 status = pdb_enum_alias_memberships(tmp_ctx, domain_sid, 143 token-> user_sids,144 token->sids, 144 145 token->num_sids, 145 146 &aliases, &num_aliases); … … 152 153 153 154 for (i=0; i<num_aliases; i++) { 154 DOM_SIDalias_sid;155 struct dom_sid alias_sid; 155 156 sid_compose(&alias_sid, domain_sid, aliases[i]); 156 157 status = add_sid_to_array_unique(token, &alias_sid, 157 &token-> user_sids,158 &token->sids, 158 159 &token->num_sids); 159 160 if (!NT_STATUS_IS_OK(status)) { … … 171 172 *******************************************************************/ 172 173 173 static NTSTATUS add_builtin_administrators(struct nt_user_token *token,174 const DOM_SID*dom_sid)175 { 176 DOM_SIDdomadm;174 static NTSTATUS add_builtin_administrators(struct security_token *token, 175 const struct dom_sid *dom_sid) 176 { 177 struct dom_sid domadm; 177 178 NTSTATUS status; 178 179 … … 190 191 sid_copy(&domadm, dom_sid); 191 192 } 192 sid_append_rid( &domadm, DOMAIN_ GROUP_RID_ADMINS );193 sid_append_rid( &domadm, DOMAIN_RID_ADMINS ); 193 194 194 195 /* Add Administrators if the user beloongs to Domain Admins */ … … 197 198 status = add_sid_to_array(token, 198 199 &global_sid_Builtin_Administrators, 199 &token-> user_sids, &token->num_sids);200 &token->sids, &token->num_sids); 200 201 if (!NT_STATUS_IS_OK(status)) { 201 202 return status; … … 206 207 } 207 208 208 /** 209 * Create the requested BUILTIN if it doesn't already exist. This requires 210 * winbindd to be running. 211 * 212 * @param[in] rid BUILTIN rid to create 213 * @return Normal NTSTATUS return. 214 */ 215 static NTSTATUS create_builtin(uint32 rid) 216 { 217 NTSTATUS status = NT_STATUS_OK; 218 DOM_SID sid; 219 gid_t gid; 220 221 if (!sid_compose(&sid, &global_sid_Builtin, rid)) { 222 return NT_STATUS_NO_SUCH_ALIAS; 223 } 224 225 if (!sid_to_gid(&sid, &gid)) { 226 if (!lp_winbind_nested_groups() || !winbind_ping()) { 227 return NT_STATUS_PROTOCOL_UNREACHABLE; 228 } 229 status = pdb_create_builtin_alias(rid); 230 } 231 return status; 232 } 233 234 /** 235 * Add sid as a member of builtin_sid. 236 * 237 * @param[in] builtin_sid An existing builtin group. 238 * @param[in] dom_sid sid to add as a member of builtin_sid. 239 * @return Normal NTSTATUS return 240 */ 241 static NTSTATUS add_sid_to_builtin(const DOM_SID *builtin_sid, 242 const DOM_SID *dom_sid) 243 { 244 NTSTATUS status = NT_STATUS_OK; 245 246 if (!dom_sid || !builtin_sid) { 247 return NT_STATUS_INVALID_PARAMETER; 248 } 249 250 status = pdb_add_aliasmem(builtin_sid, dom_sid); 251 252 if (NT_STATUS_EQUAL(status, NT_STATUS_MEMBER_IN_ALIAS)) { 253 DEBUG(5, ("add_sid_to_builtin %s is already a member of %s\n", 254 sid_string_dbg(dom_sid), 255 sid_string_dbg(builtin_sid))); 256 return NT_STATUS_OK; 257 } 258 259 if (!NT_STATUS_IS_OK(status)) { 260 DEBUG(4, ("add_sid_to_builtin %s could not be added to %s: " 261 "%s\n", sid_string_dbg(dom_sid), 262 sid_string_dbg(builtin_sid), nt_errstr(status))); 263 } 264 return status; 265 } 266 267 /******************************************************************* 268 *******************************************************************/ 269 270 NTSTATUS create_builtin_users(const DOM_SID *dom_sid) 271 { 209 static NTSTATUS finalize_local_nt_token(struct security_token *result, 210 bool is_guest); 211 212 NTSTATUS create_local_nt_token_from_info3(TALLOC_CTX *mem_ctx, 213 bool is_guest, 214 struct netr_SamInfo3 *info3, 215 struct extra_auth_info *extra, 216 struct security_token **ntok) 217 { 218 struct security_token *usrtok = NULL; 272 219 NTSTATUS status; 273 DOM_SID dom_users; 274 275 status = create_builtin(BUILTIN_ALIAS_RID_USERS); 276 if ( !NT_STATUS_IS_OK(status) ) { 277 DEBUG(5,("create_builtin_users: Failed to create Users\n")); 278 return status; 279 } 280 281 /* add domain users */ 282 if ((IS_DC || (lp_server_role() == ROLE_DOMAIN_MEMBER)) 283 && sid_compose(&dom_users, dom_sid, DOMAIN_GROUP_RID_USERS)) 284 { 285 status = add_sid_to_builtin(&global_sid_Builtin_Users, 286 &dom_users); 287 } 288 289 return status; 290 } 291 292 /******************************************************************* 293 *******************************************************************/ 294 295 NTSTATUS create_builtin_administrators(const DOM_SID *dom_sid) 296 { 297 NTSTATUS status; 298 DOM_SID dom_admins, root_sid; 299 fstring root_name; 300 enum lsa_SidType type; 301 TALLOC_CTX *ctx; 302 bool ret; 303 304 status = create_builtin(BUILTIN_ALIAS_RID_ADMINS); 305 if ( !NT_STATUS_IS_OK(status) ) { 306 DEBUG(5,("create_builtin_administrators: Failed to create Administrators\n")); 307 return status; 308 } 309 310 /* add domain admins */ 311 if ((IS_DC || (lp_server_role() == ROLE_DOMAIN_MEMBER)) 312 && sid_compose(&dom_admins, dom_sid, DOMAIN_GROUP_RID_ADMINS)) 313 { 314 status = add_sid_to_builtin(&global_sid_Builtin_Administrators, 315 &dom_admins); 316 if (!NT_STATUS_IS_OK(status)) { 317 return status; 318 } 319 } 320 321 /* add root */ 322 if ( (ctx = talloc_init("create_builtin_administrators")) == NULL ) { 220 int i; 221 222 DEBUG(10, ("Create local NT token for %s\n", 223 info3->base.account_name.string)); 224 225 usrtok = talloc_zero(mem_ctx, struct security_token); 226 if (!usrtok) { 227 DEBUG(0, ("talloc failed\n")); 323 228 return NT_STATUS_NO_MEMORY; 324 229 } 325 fstr_sprintf( root_name, "%s\\root", get_global_sam_name() ); 326 ret = lookup_name(ctx, root_name, LOOKUP_NAME_DOMAIN, NULL, NULL, 327 &root_sid, &type); 328 TALLOC_FREE( ctx ); 329 330 if ( ret ) { 331 status = add_sid_to_builtin(&global_sid_Builtin_Administrators, 332 &root_sid); 333 } 334 335 return status; 336 } 337 338 339 /******************************************************************* 340 Create a NT token for the user, expanding local aliases 341 *******************************************************************/ 342 343 struct nt_user_token *create_local_nt_token(TALLOC_CTX *mem_ctx, 344 const DOM_SID *user_sid, 345 bool is_guest, 346 int num_groupsids, 347 const DOM_SID *groupsids) 348 { 349 struct nt_user_token *result = NULL; 350 int i; 351 NTSTATUS status; 352 gid_t gid; 353 DOM_SID dom_sid; 354 355 DEBUG(10, ("Create local NT token for %s\n", 356 sid_string_dbg(user_sid))); 357 358 if (!(result = TALLOC_ZERO_P(mem_ctx, struct nt_user_token))) { 359 DEBUG(0, ("talloc failed\n")); 360 return NULL; 361 } 362 363 /* Add the user and primary group sid */ 364 365 status = add_sid_to_array(result, user_sid, 366 &result->user_sids, &result->num_sids); 367 if (!NT_STATUS_IS_OK(status)) { 368 return NULL; 369 } 370 371 /* For guest, num_groupsids may be zero. */ 372 if (num_groupsids) { 373 status = add_sid_to_array(result, &groupsids[0], 374 &result->user_sids, 375 &result->num_sids); 376 if (!NT_STATUS_IS_OK(status)) { 377 return NULL; 378 } 379 } 380 381 /* Add in BUILTIN sids */ 382 383 status = add_sid_to_array(result, &global_sid_World, 384 &result->user_sids, &result->num_sids); 385 if (!NT_STATUS_IS_OK(status)) { 386 return NULL; 387 } 388 status = add_sid_to_array(result, &global_sid_Network, 389 &result->user_sids, &result->num_sids); 390 if (!NT_STATUS_IS_OK(status)) { 391 return NULL; 392 } 393 394 if (is_guest) { 395 status = add_sid_to_array(result, &global_sid_Builtin_Guests, 396 &result->user_sids, 397 &result->num_sids); 398 if (!NT_STATUS_IS_OK(status)) { 399 return NULL; 400 } 230 231 /* Add the user and primary group sid FIRST */ 232 /* check if the user rid is the special "Domain Guests" rid. 233 * If so pick the first sid for the extra sids instead as it 234 * is a local fake account */ 235 usrtok->sids = talloc_array(usrtok, struct dom_sid, 2); 236 if (!usrtok->sids) { 237 TALLOC_FREE(usrtok); 238 return NT_STATUS_NO_MEMORY; 239 } 240 usrtok->num_sids = 2; 241 242 /* USER SID */ 243 if (info3->base.rid == (uint32_t)(-1)) { 244 /* this is a signal the user was fake and generated, 245 * the actual SID we want to use is stored in the extra 246 * sids */ 247 if (is_null_sid(&extra->user_sid)) { 248 /* we couldn't find the user sid, bail out */ 249 DEBUG(3, ("Invalid user SID\n")); 250 TALLOC_FREE(usrtok); 251 return NT_STATUS_UNSUCCESSFUL; 252 } 253 sid_copy(&usrtok->sids[0], &extra->user_sid); 401 254 } else { 402 status = add_sid_to_array(result, 403 &global_sid_Authenticated_Users, 404 &result->user_sids, 405 &result->num_sids); 406 if (!NT_STATUS_IS_OK(status)) { 407 return NULL; 408 } 255 sid_copy(&usrtok->sids[0], info3->base.domain_sid); 256 sid_append_rid(&usrtok->sids[0], info3->base.rid); 257 } 258 259 /* GROUP SID */ 260 if (info3->base.primary_gid == (uint32_t)(-1)) { 261 /* this is a signal the user was fake and generated, 262 * the actual SID we want to use is stored in the extra 263 * sids */ 264 if (is_null_sid(&extra->pgid_sid)) { 265 /* we couldn't find the user sid, bail out */ 266 DEBUG(3, ("Invalid group SID\n")); 267 TALLOC_FREE(usrtok); 268 return NT_STATUS_UNSUCCESSFUL; 269 } 270 sid_copy(&usrtok->sids[1], &extra->pgid_sid); 271 } else { 272 sid_copy(&usrtok->sids[1], info3->base.domain_sid); 273 sid_append_rid(&usrtok->sids[1], 274 info3->base.primary_gid); 409 275 } 410 276 … … 415 281 * first group sid as primary above. */ 416 282 283 for (i = 0; i < info3->base.groups.count; i++) { 284 struct dom_sid tmp_sid; 285 286 sid_copy(&tmp_sid, info3->base.domain_sid); 287 sid_append_rid(&tmp_sid, info3->base.groups.rids[i].rid); 288 289 status = add_sid_to_array_unique(usrtok, &tmp_sid, 290 &usrtok->sids, 291 &usrtok->num_sids); 292 if (!NT_STATUS_IS_OK(status)) { 293 DEBUG(3, ("Failed to add SID to nt token\n")); 294 TALLOC_FREE(usrtok); 295 return status; 296 } 297 } 298 299 /* now also add extra sids if they are not the special user/group 300 * sids */ 301 for (i = 0; i < info3->sidcount; i++) { 302 status = add_sid_to_array_unique(usrtok, 303 info3->sids[i].sid, 304 &usrtok->sids, 305 &usrtok->num_sids); 306 if (!NT_STATUS_IS_OK(status)) { 307 DEBUG(3, ("Failed to add SID to nt token\n")); 308 TALLOC_FREE(usrtok); 309 return status; 310 } 311 } 312 313 status = finalize_local_nt_token(usrtok, is_guest); 314 if (!NT_STATUS_IS_OK(status)) { 315 DEBUG(3, ("Failed to finalize nt token\n")); 316 TALLOC_FREE(usrtok); 317 return status; 318 } 319 320 *ntok = usrtok; 321 return NT_STATUS_OK; 322 } 323 324 /******************************************************************* 325 Create a NT token for the user, expanding local aliases 326 *******************************************************************/ 327 328 struct security_token *create_local_nt_token(TALLOC_CTX *mem_ctx, 329 const struct dom_sid *user_sid, 330 bool is_guest, 331 int num_groupsids, 332 const struct dom_sid *groupsids) 333 { 334 struct security_token *result = NULL; 335 int i; 336 NTSTATUS status; 337 338 DEBUG(10, ("Create local NT token for %s\n", 339 sid_string_dbg(user_sid))); 340 341 if (!(result = TALLOC_ZERO_P(mem_ctx, struct security_token))) { 342 DEBUG(0, ("talloc failed\n")); 343 return NULL; 344 } 345 346 /* Add the user and primary group sid */ 347 348 status = add_sid_to_array(result, user_sid, 349 &result->sids, &result->num_sids); 350 if (!NT_STATUS_IS_OK(status)) { 351 TALLOC_FREE(result); 352 return NULL; 353 } 354 355 /* For guest, num_groupsids may be zero. */ 356 if (num_groupsids) { 357 status = add_sid_to_array(result, &groupsids[0], 358 &result->sids, 359 &result->num_sids); 360 if (!NT_STATUS_IS_OK(status)) { 361 TALLOC_FREE(result); 362 return NULL; 363 } 364 } 365 366 /* Now the SIDs we got from authentication. These are the ones from 367 * the info3 struct or from the pdb_enum_group_memberships, depending 368 * on who authenticated the user. 369 * Note that we start the for loop at "1" here, we already added the 370 * first group sid as primary above. */ 371 417 372 for (i=1; i<num_groupsids; i++) { 418 373 status = add_sid_to_array_unique(result, &groupsids[i], 419 &result-> user_sids,374 &result->sids, 420 375 &result->num_sids); 421 376 if (!NT_STATUS_IS_OK(status)) { 377 TALLOC_FREE(result); 422 378 return NULL; 379 } 380 } 381 382 status = finalize_local_nt_token(result, is_guest); 383 if (!NT_STATUS_IS_OK(status)) { 384 TALLOC_FREE(result); 385 return NULL; 386 } 387 388 return result; 389 } 390 391 static NTSTATUS finalize_local_nt_token(struct security_token *result, 392 bool is_guest) 393 { 394 struct dom_sid dom_sid; 395 gid_t gid; 396 NTSTATUS status; 397 398 /* Add in BUILTIN sids */ 399 400 status = add_sid_to_array(result, &global_sid_World, 401 &result->sids, &result->num_sids); 402 if (!NT_STATUS_IS_OK(status)) { 403 return status; 404 } 405 status = add_sid_to_array(result, &global_sid_Network, 406 &result->sids, &result->num_sids); 407 if (!NT_STATUS_IS_OK(status)) { 408 return status; 409 } 410 411 if (is_guest) { 412 status = add_sid_to_array(result, &global_sid_Builtin_Guests, 413 &result->sids, 414 &result->num_sids); 415 if (!NT_STATUS_IS_OK(status)) { 416 return status; 417 } 418 } else { 419 status = add_sid_to_array(result, 420 &global_sid_Authenticated_Users, 421 &result->sids, 422 &result->num_sids); 423 if (!NT_STATUS_IS_OK(status)) { 424 return status; 423 425 } 424 426 } … … 491 493 if (!NT_STATUS_IS_OK(status)) { 492 494 unbecome_root(); 493 TALLOC_FREE(result); 494 return NULL; 495 return status; 495 496 } 496 497 … … 501 502 if (!NT_STATUS_IS_OK(status)) { 502 503 unbecome_root(); 503 TALLOC_FREE(result); 504 return NULL; 504 return status; 505 505 } 506 506 … … 508 508 } 509 509 510 511 get_privileges_for_sids(&result->privileges, result->user_sids, 510 /* Add privileges based on current user sids */ 511 512 get_privileges_for_sids(&result->privilege_mask, result->sids, 512 513 result->num_sids); 513 return result; 514 } 515 516 /**************************************************************************** 517 prints a NT_USER_TOKEN to debug output. 518 ****************************************************************************/ 519 520 void debug_nt_user_token(int dbg_class, int dbg_lev, NT_USER_TOKEN *token) 521 { 522 size_t i; 523 524 if (!token) { 525 DEBUGC(dbg_class, dbg_lev, ("NT user token: (NULL)\n")); 526 return; 527 } 528 529 DEBUGC(dbg_class, dbg_lev, 530 ("NT user token of user %s\n", 531 sid_string_dbg(&token->user_sids[0]) )); 532 DEBUGADDC(dbg_class, dbg_lev, 533 ("contains %lu SIDs\n", (unsigned long)token->num_sids)); 534 for (i = 0; i < token->num_sids; i++) 535 DEBUGADDC(dbg_class, dbg_lev, 536 ("SID[%3lu]: %s\n", (unsigned long)i, 537 sid_string_dbg(&token->user_sids[i]))); 538 539 dump_se_priv( dbg_class, dbg_lev, &token->privileges ); 514 515 return NT_STATUS_OK; 540 516 } 541 517 … … 559 535 } 560 536 537 /* 538 * Create an artificial NT token given just a username. (Initially intended 539 * for force user) 540 * 541 * We go through lookup_name() to avoid problems we had with 'winbind use 542 * default domain'. 543 * 544 * We have 3 cases: 545 * 546 * unmapped unix users: Go directly to nss to find the user's group. 547 * 548 * A passdb user: The list of groups is provided by pdb_enum_group_memberships. 549 * 550 * If the user is provided by winbind, the primary gid is set to "domain 551 * users" of the user's domain. For an explanation why this is necessary, see 552 * the thread starting at 553 * http://lists.samba.org/archive/samba-technical/2006-January/044803.html. 554 */ 555 556 NTSTATUS create_token_from_username(TALLOC_CTX *mem_ctx, const char *username, 557 bool is_guest, 558 uid_t *uid, gid_t *gid, 559 char **found_username, 560 struct security_token **token) 561 { 562 NTSTATUS result = NT_STATUS_NO_SUCH_USER; 563 TALLOC_CTX *tmp_ctx = talloc_stackframe(); 564 struct dom_sid user_sid; 565 enum lsa_SidType type; 566 gid_t *gids; 567 struct dom_sid *group_sids; 568 struct dom_sid unix_group_sid; 569 uint32_t num_group_sids; 570 uint32_t num_gids; 571 uint32_t i; 572 573 if (!lookup_name_smbconf(tmp_ctx, username, LOOKUP_NAME_ALL, 574 NULL, NULL, &user_sid, &type)) { 575 DEBUG(1, ("lookup_name_smbconf for %s failed\n", username)); 576 goto done; 577 } 578 579 if (type != SID_NAME_USER) { 580 DEBUG(1, ("%s is a %s, not a user\n", username, 581 sid_type_lookup(type))); 582 goto done; 583 } 584 585 if (sid_check_is_in_our_domain(&user_sid)) { 586 bool ret; 587 uint32_t pdb_num_group_sids; 588 /* This is a passdb user, so ask passdb */ 589 590 struct samu *sam_acct = NULL; 591 592 if ( !(sam_acct = samu_new( tmp_ctx )) ) { 593 result = NT_STATUS_NO_MEMORY; 594 goto done; 595 } 596 597 become_root(); 598 ret = pdb_getsampwsid(sam_acct, &user_sid); 599 unbecome_root(); 600 601 if (!ret) { 602 DEBUG(1, ("pdb_getsampwsid(%s) for user %s failed\n", 603 sid_string_dbg(&user_sid), username)); 604 DEBUGADD(1, ("Fall back to unix user %s\n", username)); 605 goto unix_user; 606 } 607 608 result = pdb_enum_group_memberships(tmp_ctx, sam_acct, 609 &group_sids, &gids, 610 &pdb_num_group_sids); 611 if (!NT_STATUS_IS_OK(result)) { 612 DEBUG(1, ("enum_group_memberships failed for %s (%s): " 613 "%s\n", username, sid_string_dbg(&user_sid), 614 nt_errstr(result))); 615 DEBUGADD(1, ("Fall back to unix user %s\n", username)); 616 goto unix_user; 617 } 618 num_group_sids = pdb_num_group_sids; 619 620 /* see the smb_panic() in pdb_default_enum_group_memberships */ 621 SMB_ASSERT(num_group_sids > 0); 622 623 *gid = gids[0]; 624 625 /* Ensure we're returning the found_username on the right context. */ 626 *found_username = talloc_strdup(mem_ctx, 627 pdb_get_username(sam_acct)); 628 629 /* 630 * If the SID from lookup_name() was the guest sid, passdb knows 631 * about the mapping of guest sid to lp_guestaccount() 632 * username and will return the unix_pw info for a guest 633 * user. Use it if it's there, else lookup the *uid details 634 * using Get_Pwnam_alloc(). See bug #6291 for details. JRA. 635 */ 636 637 /* We must always assign the *uid. */ 638 if (sam_acct->unix_pw == NULL) { 639 struct passwd *pwd = Get_Pwnam_alloc(sam_acct, *found_username ); 640 if (!pwd) { 641 DEBUG(10, ("Get_Pwnam_alloc failed for %s\n", 642 *found_username)); 643 result = NT_STATUS_NO_SUCH_USER; 644 goto done; 645 } 646 result = samu_set_unix(sam_acct, pwd ); 647 if (!NT_STATUS_IS_OK(result)) { 648 DEBUG(10, ("samu_set_unix failed for %s\n", 649 *found_username)); 650 result = NT_STATUS_NO_SUCH_USER; 651 goto done; 652 } 653 } 654 *uid = sam_acct->unix_pw->pw_uid; 655 656 } else if (sid_check_is_in_unix_users(&user_sid)) { 657 uint32_t getgroups_num_group_sids; 658 /* This is a unix user not in passdb. We need to ask nss 659 * directly, without consulting passdb */ 660 661 struct passwd *pass; 662 663 /* 664 * This goto target is used as a fallback for the passdb 665 * case. The concrete bug report is when passdb gave us an 666 * unmapped gid. 667 */ 668 669 unix_user: 670 671 if (!sid_to_uid(&user_sid, uid)) { 672 DEBUG(1, ("unix_user case, sid_to_uid for %s (%s) failed\n", 673 username, sid_string_dbg(&user_sid))); 674 result = NT_STATUS_NO_SUCH_USER; 675 goto done; 676 } 677 678 uid_to_unix_users_sid(*uid, &user_sid); 679 680 pass = getpwuid_alloc(tmp_ctx, *uid); 681 if (pass == NULL) { 682 DEBUG(1, ("getpwuid(%u) for user %s failed\n", 683 (unsigned int)*uid, username)); 684 goto done; 685 } 686 687 if (!getgroups_unix_user(tmp_ctx, username, pass->pw_gid, 688 &gids, &getgroups_num_group_sids)) { 689 DEBUG(1, ("getgroups_unix_user for user %s failed\n", 690 username)); 691 goto done; 692 } 693 num_group_sids = getgroups_num_group_sids; 694 695 if (num_group_sids) { 696 group_sids = TALLOC_ARRAY(tmp_ctx, struct dom_sid, num_group_sids); 697 if (group_sids == NULL) { 698 DEBUG(1, ("TALLOC_ARRAY failed\n")); 699 result = NT_STATUS_NO_MEMORY; 700 goto done; 701 } 702 } else { 703 group_sids = NULL; 704 } 705 706 for (i=0; i<num_group_sids; i++) { 707 gid_to_sid(&group_sids[i], gids[i]); 708 } 709 710 /* In getgroups_unix_user we always set the primary gid */ 711 SMB_ASSERT(num_group_sids > 0); 712 713 *gid = gids[0]; 714 715 /* Ensure we're returning the found_username on the right context. */ 716 *found_username = talloc_strdup(mem_ctx, pass->pw_name); 717 } else { 718 719 /* This user is from winbind, force the primary gid to the 720 * user's "domain users" group. Under certain circumstances 721 * (user comes from NT4), this might be a loss of 722 * information. But we can not rely on winbind getting the 723 * correct info. AD might prohibit winbind looking up that 724 * information. */ 725 726 /* We must always assign the *uid. */ 727 if (!sid_to_uid(&user_sid, uid)) { 728 DEBUG(1, ("winbindd case, sid_to_uid for %s (%s) failed\n", 729 username, sid_string_dbg(&user_sid))); 730 result = NT_STATUS_NO_SUCH_USER; 731 goto done; 732 } 733 734 num_group_sids = 1; 735 group_sids = TALLOC_ARRAY(tmp_ctx, struct dom_sid, num_group_sids); 736 if (group_sids == NULL) { 737 DEBUG(1, ("TALLOC_ARRAY failed\n")); 738 result = NT_STATUS_NO_MEMORY; 739 goto done; 740 } 741 742 sid_copy(&group_sids[0], &user_sid); 743 sid_split_rid(&group_sids[0], NULL); 744 sid_append_rid(&group_sids[0], DOMAIN_RID_USERS); 745 746 if (!sid_to_gid(&group_sids[0], gid)) { 747 DEBUG(1, ("sid_to_gid(%s) failed\n", 748 sid_string_dbg(&group_sids[0]))); 749 goto done; 750 } 751 752 gids = gid; 753 754 /* Ensure we're returning the found_username on the right context. */ 755 *found_username = talloc_strdup(mem_ctx, username); 756 } 757 758 /* Add the "Unix Group" SID for each gid to catch mapped groups 759 and their Unix equivalent. This is to solve the backwards 760 compatibility problem of 'valid users = +ntadmin' where 761 ntadmin has been paired with "Domain Admins" in the group 762 mapping table. Otherwise smb.conf would need to be changed 763 to 'valid user = "Domain Admins"'. --jerry */ 764 765 num_gids = num_group_sids; 766 for ( i=0; i<num_gids; i++ ) { 767 gid_t high, low; 768 769 /* don't pickup anything managed by Winbind */ 770 771 if ( lp_idmap_gid(&low, &high) && (gids[i] >= low) && (gids[i] <= high) ) 772 continue; 773 774 gid_to_unix_groups_sid(gids[i], &unix_group_sid); 775 776 result = add_sid_to_array_unique(tmp_ctx, &unix_group_sid, 777 &group_sids, &num_group_sids); 778 if (!NT_STATUS_IS_OK(result)) { 779 goto done; 780 } 781 } 782 783 /* Ensure we're creating the nt_token on the right context. */ 784 *token = create_local_nt_token(mem_ctx, &user_sid, 785 is_guest, num_group_sids, group_sids); 786 787 if ((*token == NULL) || (*found_username == NULL)) { 788 result = NT_STATUS_NO_MEMORY; 789 goto done; 790 } 791 792 result = NT_STATUS_OK; 793 done: 794 TALLOC_FREE(tmp_ctx); 795 return result; 796 } 797 798 /*************************************************************************** 799 Build upon create_token_from_username: 800 801 Expensive helper function to figure out whether a user given its name is 802 member of a particular group. 803 ***************************************************************************/ 804 805 bool user_in_group_sid(const char *username, const struct dom_sid *group_sid) 806 { 807 NTSTATUS status; 808 uid_t uid; 809 gid_t gid; 810 char *found_username; 811 struct security_token *token; 812 bool result; 813 TALLOC_CTX *mem_ctx = talloc_stackframe(); 814 815 status = create_token_from_username(mem_ctx, username, False, 816 &uid, &gid, &found_username, 817 &token); 818 819 if (!NT_STATUS_IS_OK(status)) { 820 DEBUG(10, ("could not create token for %s\n", username)); 821 TALLOC_FREE(mem_ctx); 822 return False; 823 } 824 825 result = security_token_has_sid(token, group_sid); 826 827 TALLOC_FREE(mem_ctx); 828 return result; 829 } 830 831 bool user_in_group(const char *username, const char *groupname) 832 { 833 TALLOC_CTX *mem_ctx = talloc_stackframe(); 834 struct dom_sid group_sid; 835 bool ret; 836 837 ret = lookup_name(mem_ctx, groupname, LOOKUP_NAME_ALL, 838 NULL, NULL, &group_sid, NULL); 839 TALLOC_FREE(mem_ctx); 840 841 if (!ret) { 842 DEBUG(10, ("lookup_name for (%s) failed.\n", groupname)); 843 return False; 844 } 845 846 return user_in_group_sid(username, &group_sid); 847 } 848 561 849 /* END */
Note:
See TracChangeset
for help on using the changeset viewer.