source: branches/samba-3.2.x/source/auth/auth_util.c

Last change on this file was 272, checked in by Herwig Bauernfeind, 16 years ago

Update 3.2 to 3.2.12

File size: 59.0 KB
Line 
1/*
2 Unix SMB/CIFS implementation.
3 Authentication utility functions
4 Copyright (C) Andrew Tridgell 1992-1998
5 Copyright (C) Andrew Bartlett 2001
6 Copyright (C) Jeremy Allison 2000-2001
7 Copyright (C) Rafal Szczesniak 2002
8 Copyright (C) Volker Lendecke 2006
9
10 This program is free software; you can redistribute it and/or modify
11 it under the terms of the GNU General Public License as published by
12 the Free Software Foundation; either version 3 of the License, or
13 (at your option) any later version.
14
15 This program is distributed in the hope that it will be useful,
16 but WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 GNU General Public License for more details.
19
20 You should have received a copy of the GNU General Public License
21 along with this program. If not, see <http://www.gnu.org/licenses/>.
22*/
23
24#include "includes.h"
25
26#undef DBGC_CLASS
27#define DBGC_CLASS DBGC_AUTH
28
29/****************************************************************************
30 Ensure primary group SID is always at position 0 in a
31 auth_serversupplied_info struct.
32****************************************************************************/
33
34static void sort_sid_array_for_smbd(auth_serversupplied_info *result,
35 const DOM_SID *pgroup_sid)
36{
37 unsigned int i;
38
39 if (!result->sids) {
40 return;
41 }
42
43 if (sid_compare(&result->sids[0], pgroup_sid)==0) {
44 return;
45 }
46
47 for (i = 1; i < result->num_sids; i++) {
48 if (sid_compare(pgroup_sid,
49 &result->sids[i]) == 0) {
50 sid_copy(&result->sids[i], &result->sids[0]);
51 sid_copy(&result->sids[0], pgroup_sid);
52 return;
53 }
54 }
55}
56
57/****************************************************************************
58 Create a UNIX user on demand.
59****************************************************************************/
60
61static int smb_create_user(const char *domain, const char *unix_username, const char *homedir)
62{
63 TALLOC_CTX *ctx = talloc_tos();
64 char *add_script;
65 int ret;
66
67 add_script = talloc_strdup(ctx, lp_adduser_script());
68 if (!add_script || !*add_script) {
69 return -1;
70 }
71 add_script = talloc_all_string_sub(ctx,
72 add_script,
73 "%u",
74 unix_username);
75 if (!add_script) {
76 return -1;
77 }
78 if (domain) {
79 add_script = talloc_all_string_sub(ctx,
80 add_script,
81 "%D",
82 domain);
83 if (!add_script) {
84 return -1;
85 }
86 }
87 if (homedir) {
88 add_script = talloc_all_string_sub(ctx,
89 add_script,
90 "%H",
91 homedir);
92 if (!add_script) {
93 return -1;
94 }
95 }
96 ret = smbrun(add_script,NULL);
97 flush_pwnam_cache();
98 DEBUG(ret ? 0 : 3,
99 ("smb_create_user: Running the command `%s' gave %d\n",
100 add_script,ret));
101 return ret;
102}
103
104/****************************************************************************
105 Create an auth_usersupplied_data structure
106****************************************************************************/
107
108static NTSTATUS make_user_info(auth_usersupplied_info **user_info,
109 const char *smb_name,
110 const char *internal_username,
111 const char *client_domain,
112 const char *domain,
113 const char *wksta_name,
114 DATA_BLOB *lm_pwd, DATA_BLOB *nt_pwd,
115 DATA_BLOB *lm_interactive_pwd, DATA_BLOB *nt_interactive_pwd,
116 DATA_BLOB *plaintext,
117 bool encrypted)
118{
119
120 DEBUG(5,("attempting to make a user_info for %s (%s)\n", internal_username, smb_name));
121
122 *user_info = SMB_MALLOC_P(auth_usersupplied_info);
123 if (*user_info == NULL) {
124 DEBUG(0,("malloc failed for user_info (size %lu)\n", (unsigned long)sizeof(*user_info)));
125 return NT_STATUS_NO_MEMORY;
126 }
127
128 ZERO_STRUCTP(*user_info);
129
130 DEBUG(5,("making strings for %s's user_info struct\n", internal_username));
131
132 (*user_info)->smb_name = SMB_STRDUP(smb_name);
133 if ((*user_info)->smb_name == NULL) {
134 free_user_info(user_info);
135 return NT_STATUS_NO_MEMORY;
136 }
137
138 (*user_info)->internal_username = SMB_STRDUP(internal_username);
139 if ((*user_info)->internal_username == NULL) {
140 free_user_info(user_info);
141 return NT_STATUS_NO_MEMORY;
142 }
143
144 (*user_info)->domain = SMB_STRDUP(domain);
145 if ((*user_info)->domain == NULL) {
146 free_user_info(user_info);
147 return NT_STATUS_NO_MEMORY;
148 }
149
150 (*user_info)->client_domain = SMB_STRDUP(client_domain);
151 if ((*user_info)->client_domain == NULL) {
152 free_user_info(user_info);
153 return NT_STATUS_NO_MEMORY;
154 }
155
156 (*user_info)->wksta_name = SMB_STRDUP(wksta_name);
157 if ((*user_info)->wksta_name == NULL) {
158 free_user_info(user_info);
159 return NT_STATUS_NO_MEMORY;
160 }
161
162 DEBUG(5,("making blobs for %s's user_info struct\n", internal_username));
163
164 if (lm_pwd)
165 (*user_info)->lm_resp = data_blob(lm_pwd->data, lm_pwd->length);
166 if (nt_pwd)
167 (*user_info)->nt_resp = data_blob(nt_pwd->data, nt_pwd->length);
168 if (lm_interactive_pwd)
169 (*user_info)->lm_interactive_pwd = data_blob(lm_interactive_pwd->data, lm_interactive_pwd->length);
170 if (nt_interactive_pwd)
171 (*user_info)->nt_interactive_pwd = data_blob(nt_interactive_pwd->data, nt_interactive_pwd->length);
172
173 if (plaintext)
174 (*user_info)->plaintext_password = data_blob(plaintext->data, plaintext->length);
175
176 (*user_info)->encrypted = encrypted;
177
178 (*user_info)->logon_parameters = 0;
179
180 DEBUG(10,("made an %sencrypted user_info for %s (%s)\n", encrypted ? "":"un" , internal_username, smb_name));
181
182 return NT_STATUS_OK;
183}
184
185/****************************************************************************
186 Create an auth_usersupplied_data structure after appropriate mapping.
187****************************************************************************/
188
189NTSTATUS make_user_info_map(auth_usersupplied_info **user_info,
190 const char *smb_name,
191 const char *client_domain,
192 const char *wksta_name,
193 DATA_BLOB *lm_pwd, DATA_BLOB *nt_pwd,
194 DATA_BLOB *lm_interactive_pwd, DATA_BLOB *nt_interactive_pwd,
195 DATA_BLOB *plaintext,
196 bool encrypted)
197{
198 const char *domain;
199 NTSTATUS result;
200 bool was_mapped;
201 fstring internal_username;
202 fstrcpy(internal_username, smb_name);
203 was_mapped = map_username(internal_username);
204
205 DEBUG(5, ("make_user_info_map: Mapping user [%s]\\[%s] from workstation [%s]\n",
206 client_domain, smb_name, wksta_name));
207
208 /* don't allow "" as a domain, fixes a Win9X bug
209 where it doens't supply a domain for logon script
210 'net use' commands. */
211
212 if ( *client_domain )
213 domain = client_domain;
214 else
215 domain = lp_workgroup();
216
217 /* do what win2k does. Always map unknown domains to our own
218 and let the "passdb backend" handle unknown users. */
219
220 if ( !is_trusted_domain(domain) && !strequal(domain, get_global_sam_name()) )
221 domain = my_sam_name();
222
223 /* we know that it is a trusted domain (and we are allowing them) or it is our domain */
224
225 result = make_user_info(user_info, smb_name, internal_username,
226 client_domain, domain, wksta_name,
227 lm_pwd, nt_pwd,
228 lm_interactive_pwd, nt_interactive_pwd,
229 plaintext, encrypted);
230 if (NT_STATUS_IS_OK(result)) {
231 (*user_info)->was_mapped = was_mapped;
232 }
233 return result;
234}
235
236/****************************************************************************
237 Create an auth_usersupplied_data, making the DATA_BLOBs here.
238 Decrypt and encrypt the passwords.
239****************************************************************************/
240
241bool make_user_info_netlogon_network(auth_usersupplied_info **user_info,
242 const char *smb_name,
243 const char *client_domain,
244 const char *wksta_name,
245 uint32 logon_parameters,
246 const uchar *lm_network_pwd,
247 int lm_pwd_len,
248 const uchar *nt_network_pwd,
249 int nt_pwd_len)
250{
251 bool ret;
252 NTSTATUS status;
253 DATA_BLOB lm_blob = data_blob(lm_network_pwd, lm_pwd_len);
254 DATA_BLOB nt_blob = data_blob(nt_network_pwd, nt_pwd_len);
255
256 status = make_user_info_map(user_info,
257 smb_name, client_domain,
258 wksta_name,
259 lm_pwd_len ? &lm_blob : NULL,
260 nt_pwd_len ? &nt_blob : NULL,
261 NULL, NULL, NULL,
262 True);
263
264 if (NT_STATUS_IS_OK(status)) {
265 (*user_info)->logon_parameters = logon_parameters;
266 }
267 ret = NT_STATUS_IS_OK(status) ? True : False;
268
269 data_blob_free(&lm_blob);
270 data_blob_free(&nt_blob);
271 return ret;
272}
273
274/****************************************************************************
275 Create an auth_usersupplied_data, making the DATA_BLOBs here.
276 Decrypt and encrypt the passwords.
277****************************************************************************/
278
279bool make_user_info_netlogon_interactive(auth_usersupplied_info **user_info,
280 const char *smb_name,
281 const char *client_domain,
282 const char *wksta_name,
283 uint32 logon_parameters,
284 const uchar chal[8],
285 const uchar lm_interactive_pwd[16],
286 const uchar nt_interactive_pwd[16],
287 const uchar *dc_sess_key)
288{
289 unsigned char lm_pwd[16];
290 unsigned char nt_pwd[16];
291 unsigned char local_lm_response[24];
292 unsigned char local_nt_response[24];
293 unsigned char key[16];
294
295 memcpy(key, dc_sess_key, 16);
296
297 if (lm_interactive_pwd)
298 memcpy(lm_pwd, lm_interactive_pwd, sizeof(lm_pwd));
299
300 if (nt_interactive_pwd)
301 memcpy(nt_pwd, nt_interactive_pwd, sizeof(nt_pwd));
302
303#ifdef DEBUG_PASSWORD
304 DEBUG(100,("key:"));
305 dump_data(100, key, sizeof(key));
306
307 DEBUG(100,("lm owf password:"));
308 dump_data(100, lm_pwd, sizeof(lm_pwd));
309
310 DEBUG(100,("nt owf password:"));
311 dump_data(100, nt_pwd, sizeof(nt_pwd));
312#endif
313
314 if (lm_interactive_pwd)
315 SamOEMhash(lm_pwd, key, sizeof(lm_pwd));
316
317 if (nt_interactive_pwd)
318 SamOEMhash(nt_pwd, key, sizeof(nt_pwd));
319
320#ifdef DEBUG_PASSWORD
321 DEBUG(100,("decrypt of lm owf password:"));
322 dump_data(100, lm_pwd, sizeof(lm_pwd));
323
324 DEBUG(100,("decrypt of nt owf password:"));
325 dump_data(100, nt_pwd, sizeof(nt_pwd));
326#endif
327
328 if (lm_interactive_pwd)
329 SMBOWFencrypt(lm_pwd, chal,
330 local_lm_response);
331
332 if (nt_interactive_pwd)
333 SMBOWFencrypt(nt_pwd, chal,
334 local_nt_response);
335
336 /* Password info paranoia */
337 ZERO_STRUCT(key);
338
339 {
340 bool ret;
341 NTSTATUS nt_status;
342 DATA_BLOB local_lm_blob;
343 DATA_BLOB local_nt_blob;
344
345 DATA_BLOB lm_interactive_blob;
346 DATA_BLOB nt_interactive_blob;
347
348 if (lm_interactive_pwd) {
349 local_lm_blob = data_blob(local_lm_response,
350 sizeof(local_lm_response));
351 lm_interactive_blob = data_blob(lm_pwd,
352 sizeof(lm_pwd));
353 ZERO_STRUCT(lm_pwd);
354 }
355
356 if (nt_interactive_pwd) {
357 local_nt_blob = data_blob(local_nt_response,
358 sizeof(local_nt_response));
359 nt_interactive_blob = data_blob(nt_pwd,
360 sizeof(nt_pwd));
361 ZERO_STRUCT(nt_pwd);
362 }
363
364 nt_status = make_user_info_map(
365 user_info,
366 smb_name, client_domain, wksta_name,
367 lm_interactive_pwd ? &local_lm_blob : NULL,
368 nt_interactive_pwd ? &local_nt_blob : NULL,
369 lm_interactive_pwd ? &lm_interactive_blob : NULL,
370 nt_interactive_pwd ? &nt_interactive_blob : NULL,
371 NULL, True);
372
373 if (NT_STATUS_IS_OK(nt_status)) {
374 (*user_info)->logon_parameters = logon_parameters;
375 }
376
377 ret = NT_STATUS_IS_OK(nt_status) ? True : False;
378 data_blob_free(&local_lm_blob);
379 data_blob_free(&local_nt_blob);
380 data_blob_free(&lm_interactive_blob);
381 data_blob_free(&nt_interactive_blob);
382 return ret;
383 }
384}
385
386
387/****************************************************************************
388 Create an auth_usersupplied_data structure
389****************************************************************************/
390
391bool make_user_info_for_reply(auth_usersupplied_info **user_info,
392 const char *smb_name,
393 const char *client_domain,
394 const uint8 chal[8],
395 DATA_BLOB plaintext_password)
396{
397
398 DATA_BLOB local_lm_blob;
399 DATA_BLOB local_nt_blob;
400 NTSTATUS ret = NT_STATUS_UNSUCCESSFUL;
401
402 /*
403 * Not encrypted - do so.
404 */
405
406 DEBUG(5,("make_user_info_for_reply: User passwords not in encrypted "
407 "format.\n"));
408
409 if (plaintext_password.data) {
410 unsigned char local_lm_response[24];
411
412#ifdef DEBUG_PASSWORD
413 DEBUG(10,("Unencrypted password (len %d):\n",
414 (int)plaintext_password.length));
415 dump_data(100, plaintext_password.data,
416 plaintext_password.length);
417#endif
418
419 SMBencrypt( (const char *)plaintext_password.data,
420 (const uchar*)chal, local_lm_response);
421 local_lm_blob = data_blob(local_lm_response, 24);
422
423 /* We can't do an NT hash here, as the password needs to be
424 case insensitive */
425 local_nt_blob = data_blob_null;
426
427 } else {
428 local_lm_blob = data_blob_null;
429 local_nt_blob = data_blob_null;
430 }
431
432 ret = make_user_info_map(
433 user_info, smb_name, client_domain,
434 get_remote_machine_name(),
435 local_lm_blob.data ? &local_lm_blob : NULL,
436 local_nt_blob.data ? &local_nt_blob : NULL,
437 NULL, NULL,
438 plaintext_password.data ? &plaintext_password : NULL,
439 False);
440
441 data_blob_free(&local_lm_blob);
442 return NT_STATUS_IS_OK(ret) ? True : False;
443}
444
445/****************************************************************************
446 Create an auth_usersupplied_data structure
447****************************************************************************/
448
449NTSTATUS make_user_info_for_reply_enc(auth_usersupplied_info **user_info,
450 const char *smb_name,
451 const char *client_domain,
452 DATA_BLOB lm_resp, DATA_BLOB nt_resp)
453{
454 return make_user_info_map(user_info, smb_name,
455 client_domain,
456 get_remote_machine_name(),
457 lm_resp.data ? &lm_resp : NULL,
458 nt_resp.data ? &nt_resp : NULL,
459 NULL, NULL, NULL,
460 True);
461}
462
463/****************************************************************************
464 Create a guest user_info blob, for anonymous authenticaion.
465****************************************************************************/
466
467bool make_user_info_guest(auth_usersupplied_info **user_info)
468{
469 NTSTATUS nt_status;
470
471 nt_status = make_user_info(user_info,
472 "","",
473 "","",
474 "",
475 NULL, NULL,
476 NULL, NULL,
477 NULL,
478 True);
479
480 return NT_STATUS_IS_OK(nt_status) ? True : False;
481}
482
483static int server_info_dtor(auth_serversupplied_info *server_info)
484{
485 TALLOC_FREE(server_info->sam_account);
486 ZERO_STRUCTP(server_info);
487 return 0;
488}
489
490/***************************************************************************
491 Make a server_info struct. Free with TALLOC_FREE().
492***************************************************************************/
493
494static auth_serversupplied_info *make_server_info(TALLOC_CTX *mem_ctx)
495{
496 struct auth_serversupplied_info *result;
497
498 result = TALLOC_ZERO_P(mem_ctx, auth_serversupplied_info);
499 if (result == NULL) {
500 DEBUG(0, ("talloc failed\n"));
501 return NULL;
502 }
503
504 talloc_set_destructor(result, server_info_dtor);
505
506 /* Initialise the uid and gid values to something non-zero
507 which may save us from giving away root access if there
508 is a bug in allocating these fields. */
509
510 result->uid = -1;
511 result->gid = -1;
512 return result;
513}
514
515/***************************************************************************
516 Is the incoming username our own machine account ?
517 If so, the connection is almost certainly from winbindd.
518***************************************************************************/
519
520static bool is_our_machine_account(const char *username)
521{
522 bool ret;
523 char *truncname = NULL;
524 size_t ulen = strlen(username);
525
526 if (ulen == 0 || username[ulen-1] != '$') {
527 return false;
528 }
529 truncname = SMB_STRDUP(username);
530 if (!truncname) {
531 return false;
532 }
533 truncname[ulen-1] = '\0';
534 ret = strequal(truncname, global_myname());
535 SAFE_FREE(truncname);
536 return ret;
537}
538
539/***************************************************************************
540 Make (and fill) a user_info struct from a struct samu
541***************************************************************************/
542
543NTSTATUS make_server_info_sam(auth_serversupplied_info **server_info,
544 struct samu *sampass)
545{
546 struct passwd *pwd;
547 gid_t *gids;
548 auth_serversupplied_info *result;
549 const char *username = pdb_get_username(sampass);
550 NTSTATUS status;
551
552 if ( !(result = make_server_info(NULL)) ) {
553 return NT_STATUS_NO_MEMORY;
554 }
555
556 if ( !(pwd = getpwnam_alloc(result, username)) ) {
557 DEBUG(1, ("User %s in passdb, but getpwnam() fails!\n",
558 pdb_get_username(sampass)));
559 TALLOC_FREE(result);
560 return NT_STATUS_NO_SUCH_USER;
561 }
562
563 result->sam_account = sampass;
564 result->unix_name = pwd->pw_name;
565 /* Ensure that we keep pwd->pw_name, because we will free pwd below */
566 talloc_steal(result, pwd->pw_name);
567 result->gid = pwd->pw_gid;
568 result->uid = pwd->pw_uid;
569
570 TALLOC_FREE(pwd);
571
572 if (IS_DC && is_our_machine_account(username)) {
573 /*
574 * Ensure for a connection from our own
575 * machine account (from winbindd on a DC)
576 * there are no supplementary groups.
577 * Prevents loops in calling gid_to_sid().
578 */
579 result->sids = NULL;
580 gids = NULL;
581 result->num_sids = 0;
582
583 /*
584 * This is a hack of monstrous proportions.
585 * If we know it's winbindd talking to us,
586 * we know we must never recurse into it,
587 * so turn off contacting winbindd for this
588 * entire process. This will get fixed when
589 * winbindd doesn't need to talk to smbd on
590 * a PDC. JRA.
591 */
592
593 (void)winbind_off();
594
595 DEBUG(10, ("make_server_info_sam: our machine account %s "
596 "setting supplementary group list empty and "
597 "turning off winbindd requests.\n",
598 username));
599 } else {
600 status = pdb_enum_group_memberships(result, sampass,
601 &result->sids, &gids,
602 &result->num_sids);
603
604 if (!NT_STATUS_IS_OK(status)) {
605 DEBUG(10, ("pdb_enum_group_memberships failed: %s\n",
606 nt_errstr(status)));
607 result->sam_account = NULL; /* Don't free on error exit. */
608 TALLOC_FREE(result);
609 return status;
610 }
611 }
612
613 /* For now we throw away the gids and convert via sid_to_gid
614 * later. This needs fixing, but I'd like to get the code straight and
615 * simple first. */
616
617 TALLOC_FREE(gids);
618
619 DEBUG(5,("make_server_info_sam: made server info for user %s -> %s\n",
620 pdb_get_username(sampass), result->unix_name));
621
622 *server_info = result;
623 /* Ensure thaat the sampass will be freed with the result */
624 talloc_steal(result, sampass);
625
626 return NT_STATUS_OK;
627}
628
629static NTSTATUS log_nt_token(TALLOC_CTX *tmp_ctx, NT_USER_TOKEN *token)
630{
631 char *command;
632 char *group_sidstr;
633 size_t i;
634
635 if ((lp_log_nt_token_command() == NULL) ||
636 (strlen(lp_log_nt_token_command()) == 0)) {
637 return NT_STATUS_OK;
638 }
639
640 group_sidstr = talloc_strdup(tmp_ctx, "");
641 for (i=1; i<token->num_sids; i++) {
642 group_sidstr = talloc_asprintf(
643 tmp_ctx, "%s %s", group_sidstr,
644 sid_string_talloc(tmp_ctx, &token->user_sids[i]));
645 }
646
647 command = talloc_string_sub(
648 tmp_ctx, lp_log_nt_token_command(),
649 "%s", sid_string_talloc(tmp_ctx, &token->user_sids[0]));
650 command = talloc_string_sub(tmp_ctx, command, "%t", group_sidstr);
651
652 if (command == NULL) {
653 return NT_STATUS_NO_MEMORY;
654 }
655
656 DEBUG(8, ("running command: [%s]\n", command));
657 if (smbrun(command, NULL) != 0) {
658 DEBUG(0, ("Could not log NT token\n"));
659 return NT_STATUS_ACCESS_DENIED;
660 }
661
662 return NT_STATUS_OK;
663}
664
665/*
666 * Create the token to use from server_info->sam_account and
667 * server_info->sids (the info3/sam groups). Find the unix gids.
668 */
669
670NTSTATUS create_local_token(auth_serversupplied_info *server_info)
671{
672 TALLOC_CTX *mem_ctx;
673 NTSTATUS status;
674 size_t i;
675 struct dom_sid tmp_sid;
676
677 /*
678 * If winbind is not around, we can not make much use of the SIDs the
679 * domain controller provided us with. Likewise if the user name was
680 * mapped to some local unix user.
681 */
682
683 if (((lp_server_role() == ROLE_DOMAIN_MEMBER) && !winbind_ping()) ||
684 (server_info->was_mapped)) {
685 status = create_token_from_username(server_info,
686 server_info->unix_name,
687 server_info->guest,
688 &server_info->uid,
689 &server_info->gid,
690 &server_info->unix_name,
691 &server_info->ptok);
692
693 } else {
694 server_info->ptok = create_local_nt_token(
695 server_info,
696 pdb_get_user_sid(server_info->sam_account),
697 server_info->guest,
698 server_info->num_sids, server_info->sids);
699 status = server_info->ptok ?
700 NT_STATUS_OK : NT_STATUS_NO_SUCH_USER;
701 }
702
703 if (!NT_STATUS_IS_OK(status)) {
704 return status;
705 }
706
707 /* Convert the SIDs to gids. */
708
709 server_info->n_groups = 0;
710 server_info->groups = NULL;
711
712 /* Start at index 1, where the groups start. */
713
714 for (i=1; i<server_info->ptok->num_sids; i++) {
715 gid_t gid;
716 DOM_SID *sid = &server_info->ptok->user_sids[i];
717
718 if (!sid_to_gid(sid, &gid)) {
719 DEBUG(10, ("Could not convert SID %s to gid, "
720 "ignoring it\n", sid_string_dbg(sid)));
721 continue;
722 }
723 add_gid_to_array_unique(server_info, gid, &server_info->groups,
724 &server_info->n_groups);
725 }
726
727 if (!uid_to_unix_users_sid(server_info->uid, &tmp_sid)) {
728 DEBUG(1,("create_local_token: Failed to create SID "
729 "for uid %d!\n", server_info->uid));
730 }
731 add_sid_to_array_unique(server_info->ptok, &tmp_sid,
732 &server_info->ptok->user_sids,
733 &server_info->ptok->num_sids);
734
735 if (!gid_to_unix_groups_sid( server_info->gid, &tmp_sid)) {
736 DEBUG(1,("create_local_token: Failed to create SID "
737 "for gid %d!\n", server_info->gid));
738 }
739 add_sid_to_array_unique(server_info->ptok, &tmp_sid,
740 &server_info->ptok->user_sids,
741 &server_info->ptok->num_sids);
742
743 for ( i=0; i<server_info->n_groups; i++ ) {
744 if (!gid_to_unix_groups_sid( server_info->groups[i], &tmp_sid ) ) {
745 DEBUG(1,("create_local_token: Failed to create SID "
746 "for gid %d!\n", server_info->groups[i]));
747 continue;
748 }
749 add_sid_to_array_unique(server_info->ptok, &tmp_sid,
750 &server_info->ptok->user_sids,
751 &server_info->ptok->num_sids);
752 }
753
754 debug_nt_user_token(DBGC_AUTH, 10, server_info->ptok);
755 debug_unix_user_token(DBGC_AUTH, 10,
756 server_info->uid,
757 server_info->gid,
758 server_info->n_groups,
759 server_info->groups);
760
761 mem_ctx = talloc_new(NULL);
762 if (mem_ctx == NULL) {
763 DEBUG(0, ("talloc_new failed\n"));
764 return NT_STATUS_NO_MEMORY;
765 }
766
767 status = log_nt_token(mem_ctx, server_info->ptok);
768
769 TALLOC_FREE(mem_ctx);
770 return status;
771}
772
773/*
774 * Create an artificial NT token given just a username. (Initially intended
775 * for force user)
776 *
777 * We go through lookup_name() to avoid problems we had with 'winbind use
778 * default domain'.
779 *
780 * We have 3 cases:
781 *
782 * unmapped unix users: Go directly to nss to find the user's group.
783 *
784 * A passdb user: The list of groups is provided by pdb_enum_group_memberships.
785 *
786 * If the user is provided by winbind, the primary gid is set to "domain
787 * users" of the user's domain. For an explanation why this is necessary, see
788 * the thread starting at
789 * http://lists.samba.org/archive/samba-technical/2006-January/044803.html.
790 */
791
792NTSTATUS create_token_from_username(TALLOC_CTX *mem_ctx, const char *username,
793 bool is_guest,
794 uid_t *uid, gid_t *gid,
795 char **found_username,
796 struct nt_user_token **token)
797{
798 NTSTATUS result = NT_STATUS_NO_SUCH_USER;
799 TALLOC_CTX *tmp_ctx;
800 DOM_SID user_sid;
801 enum lsa_SidType type;
802 gid_t *gids;
803 DOM_SID *group_sids;
804 DOM_SID unix_group_sid;
805 size_t num_group_sids;
806 size_t num_gids;
807 size_t i;
808
809 tmp_ctx = talloc_new(NULL);
810 if (tmp_ctx == NULL) {
811 DEBUG(0, ("talloc_new failed\n"));
812 return NT_STATUS_NO_MEMORY;
813 }
814
815 if (!lookup_name_smbconf(tmp_ctx, username, LOOKUP_NAME_ALL,
816 NULL, NULL, &user_sid, &type)) {
817 DEBUG(1, ("lookup_name_smbconf for %s failed\n", username));
818 goto done;
819 }
820
821 if (type != SID_NAME_USER) {
822 DEBUG(1, ("%s is a %s, not a user\n", username,
823 sid_type_lookup(type)));
824 goto done;
825 }
826
827 if (sid_check_is_in_our_domain(&user_sid)) {
828 bool ret;
829
830 /* This is a passdb user, so ask passdb */
831
832 struct samu *sam_acct = NULL;
833
834 if ( !(sam_acct = samu_new( tmp_ctx )) ) {
835 result = NT_STATUS_NO_MEMORY;
836 goto done;
837 }
838
839 become_root();
840 ret = pdb_getsampwsid(sam_acct, &user_sid);
841 unbecome_root();
842
843 if (!ret) {
844 DEBUG(1, ("pdb_getsampwsid(%s) for user %s failed\n",
845 sid_string_dbg(&user_sid), username));
846 DEBUGADD(1, ("Fall back to unix user %s\n", username));
847 goto unix_user;
848 }
849
850 result = pdb_enum_group_memberships(tmp_ctx, sam_acct,
851 &group_sids, &gids,
852 &num_group_sids);
853 if (!NT_STATUS_IS_OK(result)) {
854 DEBUG(10, ("enum_group_memberships failed for %s\n",
855 username));
856 DEBUGADD(1, ("Fall back to unix user %s\n", username));
857 goto unix_user;
858 }
859
860 /* see the smb_panic() in pdb_default_enum_group_memberships */
861 SMB_ASSERT(num_group_sids > 0);
862
863 *gid = gids[0];
864
865 /* Ensure we're returning the found_username on the right context. */
866 *found_username = talloc_strdup(mem_ctx,
867 pdb_get_username(sam_acct));
868
869 /*
870 * If the SID from lookup_name() was the guest sid, passdb knows
871 * about the mapping of guest sid to lp_guestaccount()
872 * username and will return the unix_pw info for a guest
873 * user. Use it if it's there, else lookup the *uid details
874 * using getpwnam_alloc(). See bug #6291 for details. JRA.
875 */
876
877 /* We must always assign the *uid. */
878 if (sam_acct->unix_pw == NULL) {
879 struct passwd *pwd = getpwnam_alloc(sam_acct, *found_username );
880 if (!pwd) {
881 DEBUG(10, ("getpwnam_alloc failed for %s\n",
882 *found_username));
883 result = NT_STATUS_NO_SUCH_USER;
884 goto done;
885 }
886 result = samu_set_unix(sam_acct, pwd );
887 if (!NT_STATUS_IS_OK(result)) {
888 DEBUG(10, ("samu_set_unix failed for %s\n",
889 *found_username));
890 result = NT_STATUS_NO_SUCH_USER;
891 goto done;
892 }
893 }
894 *uid = sam_acct->unix_pw->pw_uid;
895
896 } else if (sid_check_is_in_unix_users(&user_sid)) {
897
898 /* This is a unix user not in passdb. We need to ask nss
899 * directly, without consulting passdb */
900
901 struct passwd *pass;
902
903 /*
904 * This goto target is used as a fallback for the passdb
905 * case. The concrete bug report is when passdb gave us an
906 * unmapped gid.
907 */
908
909 unix_user:
910
911 if (!sid_to_uid(&user_sid, uid)) {
912 DEBUG(1, ("unix_user case, sid_to_uid for %s (%s) failed\n",
913 username, sid_string_dbg(&user_sid)));
914 result = NT_STATUS_NO_SUCH_USER;
915 goto done;
916 }
917
918 uid_to_unix_users_sid(*uid, &user_sid);
919
920 pass = getpwuid_alloc(tmp_ctx, *uid);
921 if (pass == NULL) {
922 DEBUG(1, ("getpwuid(%d) for user %s failed\n",
923 *uid, username));
924 goto done;
925 }
926
927 if (!getgroups_unix_user(tmp_ctx, username, pass->pw_gid,
928 &gids, &num_group_sids)) {
929 DEBUG(1, ("getgroups_unix_user for user %s failed\n",
930 username));
931 goto done;
932 }
933
934 if (num_group_sids) {
935 group_sids = TALLOC_ARRAY(tmp_ctx, DOM_SID, num_group_sids);
936 if (group_sids == NULL) {
937 DEBUG(1, ("TALLOC_ARRAY failed\n"));
938 result = NT_STATUS_NO_MEMORY;
939 goto done;
940 }
941 } else {
942 group_sids = NULL;
943 }
944
945 for (i=0; i<num_group_sids; i++) {
946 gid_to_sid(&group_sids[i], gids[i]);
947 }
948
949 /* In getgroups_unix_user we always set the primary gid */
950 SMB_ASSERT(num_group_sids > 0);
951
952 *gid = gids[0];
953
954 /* Ensure we're returning the found_username on the right context. */
955 *found_username = talloc_strdup(mem_ctx, pass->pw_name);
956 } else {
957
958 /* This user is from winbind, force the primary gid to the
959 * user's "domain users" group. Under certain circumstances
960 * (user comes from NT4), this might be a loss of
961 * information. But we can not rely on winbind getting the
962 * correct info. AD might prohibit winbind looking up that
963 * information. */
964
965 uint32 dummy;
966
967 /* We must always assign the *uid. */
968 if (!sid_to_uid(&user_sid, uid)) {
969 DEBUG(1, ("winbindd case, sid_to_uid for %s (%s) failed\n",
970 username, sid_string_dbg(&user_sid)));
971 result = NT_STATUS_NO_SUCH_USER;
972 goto done;
973 }
974
975 num_group_sids = 1;
976 group_sids = TALLOC_ARRAY(tmp_ctx, DOM_SID, num_group_sids);
977 if (group_sids == NULL) {
978 DEBUG(1, ("TALLOC_ARRAY failed\n"));
979 result = NT_STATUS_NO_MEMORY;
980 goto done;
981 }
982
983 sid_copy(&group_sids[0], &user_sid);
984 sid_split_rid(&group_sids[0], &dummy);
985 sid_append_rid(&group_sids[0], DOMAIN_GROUP_RID_USERS);
986
987 if (!sid_to_gid(&group_sids[0], gid)) {
988 DEBUG(1, ("sid_to_gid(%s) failed\n",
989 sid_string_dbg(&group_sids[0])));
990 goto done;
991 }
992
993 gids = gid;
994
995 /* Ensure we're returning the found_username on the right context. */
996 *found_username = talloc_strdup(mem_ctx, username);
997 }
998
999 /* Add the "Unix Group" SID for each gid to catch mapped groups
1000 and their Unix equivalent. This is to solve the backwards
1001 compatibility problem of 'valid users = +ntadmin' where
1002 ntadmin has been paired with "Domain Admins" in the group
1003 mapping table. Otherwise smb.conf would need to be changed
1004 to 'valid user = "Domain Admins"'. --jerry */
1005
1006 num_gids = num_group_sids;
1007 for ( i=0; i<num_gids; i++ ) {
1008 gid_t high, low;
1009
1010 /* don't pickup anything managed by Winbind */
1011
1012 if ( lp_idmap_gid(&low, &high) && (gids[i] >= low) && (gids[i] <= high) )
1013 continue;
1014
1015 if ( !gid_to_unix_groups_sid( gids[i], &unix_group_sid ) ) {
1016 DEBUG(1,("create_token_from_username: Failed to create SID "
1017 "for gid %d!\n", gids[i]));
1018 continue;
1019 }
1020 result = add_sid_to_array_unique(tmp_ctx, &unix_group_sid,
1021 &group_sids, &num_group_sids);
1022 if (!NT_STATUS_IS_OK(result)) {
1023 goto done;
1024 }
1025 }
1026
1027 /* Ensure we're creating the nt_token on the right context. */
1028 *token = create_local_nt_token(mem_ctx, &user_sid,
1029 is_guest, num_group_sids, group_sids);
1030
1031 if ((*token == NULL) || (*found_username == NULL)) {
1032 result = NT_STATUS_NO_MEMORY;
1033 goto done;
1034 }
1035
1036 result = NT_STATUS_OK;
1037 done:
1038 TALLOC_FREE(tmp_ctx);
1039 return result;
1040}
1041
1042/***************************************************************************
1043 Build upon create_token_from_username:
1044
1045 Expensive helper function to figure out whether a user given its name is
1046 member of a particular group.
1047***************************************************************************/
1048
1049bool user_in_group_sid(const char *username, const DOM_SID *group_sid)
1050{
1051 NTSTATUS status;
1052 uid_t uid;
1053 gid_t gid;
1054 char *found_username;
1055 struct nt_user_token *token;
1056 bool result;
1057
1058 TALLOC_CTX *mem_ctx;
1059
1060 mem_ctx = talloc_new(NULL);
1061 if (mem_ctx == NULL) {
1062 DEBUG(0, ("talloc_new failed\n"));
1063 return False;
1064 }
1065
1066 status = create_token_from_username(mem_ctx, username, False,
1067 &uid, &gid, &found_username,
1068 &token);
1069
1070 if (!NT_STATUS_IS_OK(status)) {
1071 DEBUG(10, ("could not create token for %s\n", username));
1072 return False;
1073 }
1074
1075 result = nt_token_check_sid(group_sid, token);
1076
1077 TALLOC_FREE(mem_ctx);
1078 return result;
1079
1080}
1081
1082bool user_in_group(const char *username, const char *groupname)
1083{
1084 TALLOC_CTX *mem_ctx;
1085 DOM_SID group_sid;
1086 bool ret;
1087
1088 mem_ctx = talloc_new(NULL);
1089 if (mem_ctx == NULL) {
1090 DEBUG(0, ("talloc_new failed\n"));
1091 return False;
1092 }
1093
1094 ret = lookup_name(mem_ctx, groupname, LOOKUP_NAME_ALL,
1095 NULL, NULL, &group_sid, NULL);
1096 TALLOC_FREE(mem_ctx);
1097
1098 if (!ret) {
1099 DEBUG(10, ("lookup_name for (%s) failed.\n", groupname));
1100 return False;
1101 }
1102
1103 return user_in_group_sid(username, &group_sid);
1104}
1105
1106
1107/***************************************************************************
1108 Make (and fill) a user_info struct from a 'struct passwd' by conversion
1109 to a struct samu
1110***************************************************************************/
1111
1112NTSTATUS make_server_info_pw(auth_serversupplied_info **server_info,
1113 char *unix_username,
1114 struct passwd *pwd)
1115{
1116 NTSTATUS status;
1117 struct samu *sampass = NULL;
1118 gid_t *gids;
1119 char *qualified_name = NULL;
1120 TALLOC_CTX *mem_ctx = NULL;
1121 DOM_SID u_sid;
1122 enum lsa_SidType type;
1123 auth_serversupplied_info *result;
1124
1125 if ( !(sampass = samu_new( NULL )) ) {
1126 return NT_STATUS_NO_MEMORY;
1127 }
1128
1129 status = samu_set_unix( sampass, pwd );
1130 if (!NT_STATUS_IS_OK(status)) {
1131 return status;
1132 }
1133
1134 result = make_server_info(NULL);
1135 if (result == NULL) {
1136 TALLOC_FREE(sampass);
1137 return NT_STATUS_NO_MEMORY;
1138 }
1139
1140 result->sam_account = sampass;
1141 result->unix_name = talloc_strdup(result, unix_username);
1142 result->uid = pwd->pw_uid;
1143 result->gid = pwd->pw_gid;
1144
1145 status = pdb_enum_group_memberships(result, sampass,
1146 &result->sids, &gids,
1147 &result->num_sids);
1148
1149 if (!NT_STATUS_IS_OK(status)) {
1150 DEBUG(10, ("pdb_enum_group_memberships failed: %s\n",
1151 nt_errstr(status)));
1152 TALLOC_FREE(result);
1153 return status;
1154 }
1155
1156 /*
1157 * The SID returned in server_info->sam_account is based
1158 * on our SAM sid even though for a pure UNIX account this should
1159 * not be the case as it doesn't really exist in the SAM db.
1160 * This causes lookups on "[in]valid users" to fail as they
1161 * will lookup this name as a "Unix User" SID to check against
1162 * the user token. Fix this by adding the "Unix User"\unix_username
1163 * SID to the sid array. The correct fix should probably be
1164 * changing the server_info->sam_account user SID to be a
1165 * S-1-22 Unix SID, but this might break old configs where
1166 * plaintext passwords were used with no SAM backend.
1167 */
1168
1169 mem_ctx = talloc_init("make_server_info_pw_tmp");
1170 if (!mem_ctx) {
1171 TALLOC_FREE(result);
1172 return NT_STATUS_NO_MEMORY;
1173 }
1174
1175 qualified_name = talloc_asprintf(mem_ctx, "%s\\%s",
1176 unix_users_domain_name(),
1177 unix_username );
1178 if (!qualified_name) {
1179 TALLOC_FREE(result);
1180 TALLOC_FREE(mem_ctx);
1181 return NT_STATUS_NO_MEMORY;
1182 }
1183
1184 if (!lookup_name(mem_ctx, qualified_name, LOOKUP_NAME_ALL,
1185 NULL, NULL,
1186 &u_sid, &type)) {
1187 TALLOC_FREE(result);
1188 TALLOC_FREE(mem_ctx);
1189 return NT_STATUS_NO_SUCH_USER;
1190 }
1191
1192 TALLOC_FREE(mem_ctx);
1193
1194 if (type != SID_NAME_USER) {
1195 TALLOC_FREE(result);
1196 return NT_STATUS_NO_SUCH_USER;
1197 }
1198
1199 status = add_sid_to_array_unique(result, &u_sid,
1200 &result->sids,
1201 &result->num_sids);
1202 if (!NT_STATUS_IS_OK(status)) {
1203 TALLOC_FREE(result);
1204 return status;
1205 }
1206
1207 /* For now we throw away the gids and convert via sid_to_gid
1208 * later. This needs fixing, but I'd like to get the code straight and
1209 * simple first. */
1210 TALLOC_FREE(gids);
1211
1212 *server_info = result;
1213
1214 return NT_STATUS_OK;
1215}
1216
1217/***************************************************************************
1218 Make (and fill) a user_info struct for a guest login.
1219 This *must* succeed for smbd to start. If there is no mapping entry for
1220 the guest gid, then create one.
1221***************************************************************************/
1222
1223static NTSTATUS make_new_server_info_guest(auth_serversupplied_info **server_info)
1224{
1225 NTSTATUS status;
1226 struct samu *sampass = NULL;
1227 DOM_SID guest_sid;
1228 bool ret;
1229 char zeros[16];
1230
1231 if ( !(sampass = samu_new( NULL )) ) {
1232 return NT_STATUS_NO_MEMORY;
1233 }
1234
1235 sid_copy(&guest_sid, get_global_sam_sid());
1236 sid_append_rid(&guest_sid, DOMAIN_USER_RID_GUEST);
1237
1238 become_root();
1239 ret = pdb_getsampwsid(sampass, &guest_sid);
1240 unbecome_root();
1241
1242 if (!ret) {
1243 TALLOC_FREE(sampass);
1244 return NT_STATUS_NO_SUCH_USER;
1245 }
1246
1247 status = make_server_info_sam(server_info, sampass);
1248 if (!NT_STATUS_IS_OK(status)) {
1249 TALLOC_FREE(sampass);
1250 return status;
1251 }
1252
1253 (*server_info)->guest = True;
1254
1255 status = create_local_token(*server_info);
1256 if (!NT_STATUS_IS_OK(status)) {
1257 DEBUG(10, ("create_local_token failed: %s\n",
1258 nt_errstr(status)));
1259 return status;
1260 }
1261
1262 /* annoying, but the Guest really does have a session key, and it is
1263 all zeros! */
1264 ZERO_STRUCT(zeros);
1265 (*server_info)->user_session_key = data_blob(zeros, sizeof(zeros));
1266 (*server_info)->lm_session_key = data_blob(zeros, sizeof(zeros));
1267
1268 return NT_STATUS_OK;
1269}
1270
1271static auth_serversupplied_info *copy_serverinfo(auth_serversupplied_info *src)
1272{
1273 auth_serversupplied_info *dst;
1274
1275 dst = make_server_info(NULL);
1276 if (dst == NULL) {
1277 return NULL;
1278 }
1279
1280 dst->guest = src->guest;
1281 dst->uid = src->uid;
1282 dst->gid = src->gid;
1283 dst->n_groups = src->n_groups;
1284 if (src->n_groups != 0) {
1285 dst->groups = (gid_t *)TALLOC_MEMDUP(
1286 dst, src->groups, sizeof(gid_t)*dst->n_groups);
1287 } else {
1288 dst->groups = NULL;
1289 }
1290
1291 if (src->ptok) {
1292 dst->ptok = dup_nt_token(dst, src->ptok);
1293 if (!dst->ptok) {
1294 TALLOC_FREE(dst);
1295 return NULL;
1296 }
1297 }
1298
1299 dst->user_session_key = data_blob_talloc( dst, src->user_session_key.data,
1300 src->user_session_key.length);
1301
1302 dst->lm_session_key = data_blob_talloc(dst, src->lm_session_key.data,
1303 src->lm_session_key.length);
1304
1305 dst->sam_account = samu_new(NULL);
1306 if (!dst->sam_account) {
1307 TALLOC_FREE(dst);
1308 return NULL;
1309 }
1310
1311 if (!pdb_copy_sam_account(dst->sam_account, src->sam_account)) {
1312 TALLOC_FREE(dst);
1313 return NULL;
1314 }
1315
1316 dst->pam_handle = NULL;
1317 dst->unix_name = talloc_strdup(dst, src->unix_name);
1318 if (!dst->unix_name) {
1319 TALLOC_FREE(dst);
1320 return NULL;
1321 }
1322
1323 return dst;
1324}
1325
1326static auth_serversupplied_info *guest_info = NULL;
1327
1328bool init_guest_info(void)
1329{
1330 if (guest_info != NULL)
1331 return True;
1332
1333 return NT_STATUS_IS_OK(make_new_server_info_guest(&guest_info));
1334}
1335
1336NTSTATUS make_server_info_guest(auth_serversupplied_info **server_info)
1337{
1338 *server_info = copy_serverinfo(guest_info);
1339 return (*server_info != NULL) ? NT_STATUS_OK : NT_STATUS_NO_MEMORY;
1340}
1341
1342bool copy_current_user(struct current_user *dst, struct current_user *src)
1343{
1344 gid_t *groups;
1345 NT_USER_TOKEN *nt_token;
1346
1347 groups = (gid_t *)memdup(src->ut.groups,
1348 sizeof(gid_t) * src->ut.ngroups);
1349 if ((src->ut.ngroups != 0) && (groups == NULL)) {
1350 return False;
1351 }
1352
1353 nt_token = dup_nt_token(NULL, src->nt_user_token);
1354 if (nt_token == NULL) {
1355 SAFE_FREE(groups);
1356 return False;
1357 }
1358
1359 dst->conn = src->conn;
1360 dst->vuid = src->vuid;
1361 dst->ut.uid = src->ut.uid;
1362 dst->ut.gid = src->ut.gid;
1363 dst->ut.ngroups = src->ut.ngroups;
1364 dst->ut.groups = groups;
1365 dst->nt_user_token = nt_token;
1366 return True;
1367}
1368
1369bool set_current_user_guest(struct current_user *dst)
1370{
1371 gid_t *groups;
1372 NT_USER_TOKEN *nt_token;
1373
1374 groups = (gid_t *)memdup(guest_info->groups,
1375 sizeof(gid_t) * guest_info->n_groups);
1376 if (groups == NULL) {
1377 return False;
1378 }
1379
1380 nt_token = dup_nt_token(NULL, guest_info->ptok);
1381 if (nt_token == NULL) {
1382 SAFE_FREE(groups);
1383 return False;
1384 }
1385
1386 TALLOC_FREE(dst->nt_user_token);
1387 SAFE_FREE(dst->ut.groups);
1388
1389 /* dst->conn is never really dereferenced, it's only tested for
1390 * equality in uid.c */
1391 dst->conn = NULL;
1392
1393 dst->vuid = UID_FIELD_INVALID;
1394 dst->ut.uid = guest_info->uid;
1395 dst->ut.gid = guest_info->gid;
1396 dst->ut.ngroups = guest_info->n_groups;
1397 dst->ut.groups = groups;
1398 dst->nt_user_token = nt_token;
1399 return True;
1400}
1401
1402/***************************************************************************
1403 Purely internal function for make_server_info_info3
1404 Fill the sam account from getpwnam
1405***************************************************************************/
1406static NTSTATUS fill_sam_account(TALLOC_CTX *mem_ctx,
1407 const char *domain,
1408 const char *username,
1409 char **found_username,
1410 uid_t *uid, gid_t *gid,
1411 struct samu *account,
1412 bool *username_was_mapped)
1413{
1414 NTSTATUS nt_status;
1415 fstring dom_user, lower_username;
1416 fstring real_username;
1417 struct passwd *passwd;
1418
1419 fstrcpy( lower_username, username );
1420 strlower_m( lower_username );
1421
1422 fstr_sprintf(dom_user, "%s%c%s", domain, *lp_winbind_separator(),
1423 lower_username);
1424
1425 /* Get the passwd struct. Try to create the account is necessary. */
1426
1427 *username_was_mapped = map_username( dom_user );
1428
1429 if ( !(passwd = smb_getpwnam( NULL, dom_user, real_username, True )) )
1430 return NT_STATUS_NO_SUCH_USER;
1431
1432 *uid = passwd->pw_uid;
1433 *gid = passwd->pw_gid;
1434
1435 /* This is pointless -- there is no suport for differing
1436 unix and windows names. Make sure to always store the
1437 one we actually looked up and succeeded. Have I mentioned
1438 why I hate the 'winbind use default domain' parameter?
1439 --jerry */
1440
1441 *found_username = talloc_strdup( mem_ctx, real_username );
1442
1443 DEBUG(5,("fill_sam_account: located username was [%s]\n", *found_username));
1444
1445 nt_status = samu_set_unix( account, passwd );
1446
1447 TALLOC_FREE(passwd);
1448
1449 return nt_status;
1450}
1451
1452/****************************************************************************
1453 Wrapper to allow the getpwnam() call to strip the domain name and
1454 try again in case a local UNIX user is already there. Also run through
1455 the username if we fallback to the username only.
1456 ****************************************************************************/
1457
1458struct passwd *smb_getpwnam( TALLOC_CTX *mem_ctx, char *domuser,
1459 fstring save_username, bool create )
1460{
1461 struct passwd *pw = NULL;
1462 char *p;
1463 fstring username;
1464
1465 /* we only save a copy of the username it has been mangled
1466 by winbindd use default domain */
1467
1468 save_username[0] = '\0';
1469
1470 /* don't call map_username() here since it has to be done higher
1471 up the stack so we don't call it mutliple times */
1472
1473 fstrcpy( username, domuser );
1474
1475 p = strchr_m( username, *lp_winbind_separator() );
1476
1477 /* code for a DOMAIN\user string */
1478
1479 if ( p ) {
1480 fstring strip_username;
1481
1482 pw = Get_Pwnam_alloc( mem_ctx, domuser );
1483 if ( pw ) {
1484 /* make sure we get the case of the username correct */
1485 /* work around 'winbind use default domain = yes' */
1486
1487 if ( !strchr_m( pw->pw_name, *lp_winbind_separator() ) ) {
1488 char *domain;
1489
1490 /* split the domain and username into 2 strings */
1491 *p = '\0';
1492 domain = username;
1493
1494 fstr_sprintf(save_username, "%s%c%s", domain, *lp_winbind_separator(), pw->pw_name);
1495 }
1496 else
1497 fstrcpy( save_username, pw->pw_name );
1498
1499 /* whew -- done! */
1500 return pw;
1501 }
1502
1503 /* setup for lookup of just the username */
1504 /* remember that p and username are overlapping memory */
1505
1506 p++;
1507 fstrcpy( strip_username, p );
1508 fstrcpy( username, strip_username );
1509 }
1510
1511 /* just lookup a plain username */
1512
1513 pw = Get_Pwnam_alloc(mem_ctx, username);
1514
1515 /* Create local user if requested but only if winbindd
1516 is not running. We need to protect against cases
1517 where winbindd is failing and then prematurely
1518 creating users in /etc/passwd */
1519
1520 if ( !pw && create && !winbind_ping() ) {
1521 /* Don't add a machine account. */
1522 if (username[strlen(username)-1] == '$')
1523 return NULL;
1524
1525 smb_create_user(NULL, username, NULL);
1526 pw = Get_Pwnam_alloc(mem_ctx, username);
1527 }
1528
1529 /* one last check for a valid passwd struct */
1530
1531 if ( pw )
1532 fstrcpy( save_username, pw->pw_name );
1533
1534 return pw;
1535}
1536
1537/***************************************************************************
1538 Make a server_info struct from the info3 returned by a domain logon
1539***************************************************************************/
1540
1541NTSTATUS make_server_info_info3(TALLOC_CTX *mem_ctx,
1542 const char *sent_nt_username,
1543 const char *domain,
1544 auth_serversupplied_info **server_info,
1545 struct netr_SamInfo3 *info3)
1546{
1547 char zeros[16];
1548
1549 NTSTATUS nt_status = NT_STATUS_OK;
1550 char *found_username = NULL;
1551 const char *nt_domain;
1552 const char *nt_username;
1553 struct samu *sam_account = NULL;
1554 DOM_SID user_sid;
1555 DOM_SID group_sid;
1556 bool username_was_mapped;
1557
1558 uid_t uid = (uid_t)-1;
1559 gid_t gid = (gid_t)-1;
1560
1561 auth_serversupplied_info *result;
1562
1563 /*
1564 Here is where we should check the list of
1565 trusted domains, and verify that the SID
1566 matches.
1567 */
1568
1569 sid_copy(&user_sid, info3->base.domain_sid);
1570 if (!sid_append_rid(&user_sid, info3->base.rid)) {
1571 return NT_STATUS_INVALID_PARAMETER;
1572 }
1573
1574 sid_copy(&group_sid, info3->base.domain_sid);
1575 if (!sid_append_rid(&group_sid, info3->base.primary_gid)) {
1576 return NT_STATUS_INVALID_PARAMETER;
1577 }
1578
1579 nt_username = talloc_strdup(mem_ctx, info3->base.account_name.string);
1580 if (!nt_username) {
1581 /* If the server didn't give us one, just use the one we sent
1582 * them */
1583 nt_username = sent_nt_username;
1584 }
1585
1586 nt_domain = talloc_strdup(mem_ctx, info3->base.domain.string);
1587 if (!nt_domain) {
1588 /* If the server didn't give us one, just use the one we sent
1589 * them */
1590 nt_domain = domain;
1591 }
1592
1593 /* try to fill the SAM account.. If getpwnam() fails, then try the
1594 add user script (2.2.x behavior).
1595
1596 We use the _unmapped_ username here in an attempt to provide
1597 consistent username mapping behavior between kerberos and NTLM[SSP]
1598 authentication in domain mode security. I.E. Username mapping
1599 should be applied to the fully qualified username
1600 (e.g. DOMAIN\user) and not just the login name. Yes this means we
1601 called map_username() unnecessarily in make_user_info_map() but
1602 that is how the current code is designed. Making the change here
1603 is the least disruptive place. -- jerry */
1604
1605 if ( !(sam_account = samu_new( NULL )) ) {
1606 return NT_STATUS_NO_MEMORY;
1607 }
1608
1609 /* this call will try to create the user if necessary */
1610
1611 nt_status = fill_sam_account(mem_ctx, nt_domain, sent_nt_username,
1612 &found_username, &uid, &gid, sam_account,
1613 &username_was_mapped);
1614
1615
1616 /* if we still don't have a valid unix account check for
1617 'map to guest = bad uid' */
1618
1619 if (!NT_STATUS_IS_OK(nt_status)) {
1620 TALLOC_FREE( sam_account );
1621 if ( lp_map_to_guest() == MAP_TO_GUEST_ON_BAD_UID ) {
1622 make_server_info_guest(server_info);
1623 return NT_STATUS_OK;
1624 }
1625 return nt_status;
1626 }
1627
1628 if (!pdb_set_nt_username(sam_account, nt_username, PDB_CHANGED)) {
1629 TALLOC_FREE(sam_account);
1630 return NT_STATUS_NO_MEMORY;
1631 }
1632
1633 if (!pdb_set_username(sam_account, nt_username, PDB_CHANGED)) {
1634 TALLOC_FREE(sam_account);
1635 return NT_STATUS_NO_MEMORY;
1636 }
1637
1638 if (!pdb_set_domain(sam_account, nt_domain, PDB_CHANGED)) {
1639 TALLOC_FREE(sam_account);
1640 return NT_STATUS_NO_MEMORY;
1641 }
1642
1643 if (!pdb_set_user_sid(sam_account, &user_sid, PDB_CHANGED)) {
1644 TALLOC_FREE(sam_account);
1645 return NT_STATUS_UNSUCCESSFUL;
1646 }
1647
1648 if (!pdb_set_group_sid(sam_account, &group_sid, PDB_CHANGED)) {
1649 TALLOC_FREE(sam_account);
1650 return NT_STATUS_UNSUCCESSFUL;
1651 }
1652
1653 if (!pdb_set_fullname(sam_account,
1654 info3->base.full_name.string,
1655 PDB_CHANGED)) {
1656 TALLOC_FREE(sam_account);
1657 return NT_STATUS_NO_MEMORY;
1658 }
1659
1660 if (!pdb_set_logon_script(sam_account,
1661 info3->base.logon_script.string,
1662 PDB_CHANGED)) {
1663 TALLOC_FREE(sam_account);
1664 return NT_STATUS_NO_MEMORY;
1665 }
1666
1667 if (!pdb_set_profile_path(sam_account,
1668 info3->base.profile_path.string,
1669 PDB_CHANGED)) {
1670 TALLOC_FREE(sam_account);
1671 return NT_STATUS_NO_MEMORY;
1672 }
1673
1674 if (!pdb_set_homedir(sam_account,
1675 info3->base.home_directory.string,
1676 PDB_CHANGED)) {
1677 TALLOC_FREE(sam_account);
1678 return NT_STATUS_NO_MEMORY;
1679 }
1680
1681 if (!pdb_set_dir_drive(sam_account,
1682 info3->base.home_drive.string,
1683 PDB_CHANGED)) {
1684 TALLOC_FREE(sam_account);
1685 return NT_STATUS_NO_MEMORY;
1686 }
1687
1688 if (!pdb_set_acct_ctrl(sam_account, info3->base.acct_flags, PDB_CHANGED)) {
1689 TALLOC_FREE(sam_account);
1690 return NT_STATUS_NO_MEMORY;
1691 }
1692
1693 if (!pdb_set_pass_last_set_time(
1694 sam_account,
1695 nt_time_to_unix(info3->base.last_password_change),
1696 PDB_CHANGED)) {
1697 TALLOC_FREE(sam_account);
1698 return NT_STATUS_NO_MEMORY;
1699 }
1700
1701 if (!pdb_set_pass_can_change_time(
1702 sam_account,
1703 nt_time_to_unix(info3->base.allow_password_change),
1704 PDB_CHANGED)) {
1705 TALLOC_FREE(sam_account);
1706 return NT_STATUS_NO_MEMORY;
1707 }
1708
1709 if (!pdb_set_pass_must_change_time(
1710 sam_account,
1711 nt_time_to_unix(info3->base.force_password_change),
1712 PDB_CHANGED)) {
1713 TALLOC_FREE(sam_account);
1714 return NT_STATUS_NO_MEMORY;
1715 }
1716
1717 result = make_server_info(NULL);
1718 if (result == NULL) {
1719 DEBUG(4, ("make_server_info failed!\n"));
1720 TALLOC_FREE(sam_account);
1721 return NT_STATUS_NO_MEMORY;
1722 }
1723
1724 /* save this here to _net_sam_logon() doesn't fail (it assumes a
1725 valid struct samu) */
1726
1727 result->sam_account = sam_account;
1728 result->unix_name = talloc_strdup(result, found_username);
1729
1730 /* Fill in the unix info we found on the way */
1731
1732 result->uid = uid;
1733 result->gid = gid;
1734
1735 /* Create a 'combined' list of all SIDs we might want in the SD */
1736
1737 result->num_sids = 0;
1738 result->sids = NULL;
1739
1740 nt_status = sid_array_from_info3(result, info3,
1741 &result->sids,
1742 &result->num_sids,
1743 false, false);
1744 if (!NT_STATUS_IS_OK(nt_status)) {
1745 TALLOC_FREE(result);
1746 return nt_status;
1747 }
1748
1749 /* Ensure the primary group sid is at position 0. */
1750 sort_sid_array_for_smbd(result, &group_sid);
1751
1752 result->login_server = talloc_strdup(result,
1753 info3->base.logon_server.string);
1754
1755 /* ensure we are never given NULL session keys */
1756
1757 ZERO_STRUCT(zeros);
1758
1759 if (memcmp(info3->base.key.key, zeros, sizeof(zeros)) == 0) {
1760 result->user_session_key = data_blob_null;
1761 } else {
1762 result->user_session_key = data_blob_talloc(
1763 result, info3->base.key.key,
1764 sizeof(info3->base.key.key));
1765 }
1766
1767 if (memcmp(info3->base.LMSessKey.key, zeros, 8) == 0) {
1768 result->lm_session_key = data_blob_null;
1769 } else {
1770 result->lm_session_key = data_blob_talloc(
1771 result, info3->base.LMSessKey.key,
1772 sizeof(info3->base.LMSessKey.key));
1773 }
1774
1775 result->was_mapped = username_was_mapped;
1776
1777 *server_info = result;
1778
1779 return NT_STATUS_OK;
1780}
1781
1782/*****************************************************************************
1783 Make a server_info struct from the wbcAuthUserInfo returned by a domain logon
1784******************************************************************************/
1785
1786NTSTATUS make_server_info_wbcAuthUserInfo(TALLOC_CTX *mem_ctx,
1787 const char *sent_nt_username,
1788 const char *domain,
1789 const struct wbcAuthUserInfo *info,
1790 auth_serversupplied_info **server_info)
1791{
1792 char zeros[16];
1793
1794 NTSTATUS nt_status = NT_STATUS_OK;
1795 char *found_username = NULL;
1796 const char *nt_domain;
1797 const char *nt_username;
1798 struct samu *sam_account = NULL;
1799 DOM_SID user_sid;
1800 DOM_SID group_sid;
1801 bool username_was_mapped;
1802 uint32_t i;
1803
1804 uid_t uid = (uid_t)-1;
1805 gid_t gid = (gid_t)-1;
1806
1807 auth_serversupplied_info *result;
1808
1809 result = make_server_info(NULL);
1810 if (result == NULL) {
1811 DEBUG(4, ("make_server_info failed!\n"));
1812 return NT_STATUS_NO_MEMORY;
1813 }
1814
1815 /*
1816 Here is where we should check the list of
1817 trusted domains, and verify that the SID
1818 matches.
1819 */
1820
1821 memcpy(&user_sid, &info->sids[0].sid, sizeof(user_sid));
1822 memcpy(&group_sid, &info->sids[1].sid, sizeof(group_sid));
1823
1824 if (info->account_name) {
1825 nt_username = talloc_strdup(result, info->account_name);
1826 } else {
1827 /* If the server didn't give us one, just use the one we sent
1828 * them */
1829 nt_username = talloc_strdup(result, sent_nt_username);
1830 }
1831 if (!nt_username) {
1832 TALLOC_FREE(result);
1833 return NT_STATUS_NO_MEMORY;
1834 }
1835
1836 if (info->domain_name) {
1837 nt_domain = talloc_strdup(result, info->domain_name);
1838 } else {
1839 /* If the server didn't give us one, just use the one we sent
1840 * them */
1841 nt_domain = talloc_strdup(result, domain);
1842 }
1843 if (!nt_domain) {
1844 TALLOC_FREE(result);
1845 return NT_STATUS_NO_MEMORY;
1846 }
1847
1848 /* try to fill the SAM account.. If getpwnam() fails, then try the
1849 add user script (2.2.x behavior).
1850
1851 We use the _unmapped_ username here in an attempt to provide
1852 consistent username mapping behavior between kerberos and NTLM[SSP]
1853 authentication in domain mode security. I.E. Username mapping
1854 should be applied to the fully qualified username
1855 (e.g. DOMAIN\user) and not just the login name. Yes this means we
1856 called map_username() unnecessarily in make_user_info_map() but
1857 that is how the current code is designed. Making the change here
1858 is the least disruptive place. -- jerry */
1859
1860 if ( !(sam_account = samu_new( result )) ) {
1861 TALLOC_FREE(result);
1862 return NT_STATUS_NO_MEMORY;
1863 }
1864
1865 /* this call will try to create the user if necessary */
1866
1867 nt_status = fill_sam_account(result, nt_domain, sent_nt_username,
1868 &found_username, &uid, &gid, sam_account,
1869 &username_was_mapped);
1870
1871 /* if we still don't have a valid unix account check for
1872 'map to guest = bad uid' */
1873
1874 if (!NT_STATUS_IS_OK(nt_status)) {
1875 TALLOC_FREE( result );
1876 if ( lp_map_to_guest() == MAP_TO_GUEST_ON_BAD_UID ) {
1877 make_server_info_guest(server_info);
1878 return NT_STATUS_OK;
1879 }
1880 return nt_status;
1881 }
1882
1883 if (!pdb_set_nt_username(sam_account, nt_username, PDB_CHANGED)) {
1884 TALLOC_FREE(result);
1885 return NT_STATUS_NO_MEMORY;
1886 }
1887
1888 if (!pdb_set_username(sam_account, nt_username, PDB_CHANGED)) {
1889 TALLOC_FREE(result);
1890 return NT_STATUS_NO_MEMORY;
1891 }
1892
1893 if (!pdb_set_domain(sam_account, nt_domain, PDB_CHANGED)) {
1894 TALLOC_FREE(result);
1895 return NT_STATUS_NO_MEMORY;
1896 }
1897
1898 if (!pdb_set_user_sid(sam_account, &user_sid, PDB_CHANGED)) {
1899 TALLOC_FREE(result);
1900 return NT_STATUS_UNSUCCESSFUL;
1901 }
1902
1903 if (!pdb_set_group_sid(sam_account, &group_sid, PDB_CHANGED)) {
1904 TALLOC_FREE(result);
1905 return NT_STATUS_UNSUCCESSFUL;
1906 }
1907
1908 if (!pdb_set_fullname(sam_account, info->full_name, PDB_CHANGED)) {
1909 TALLOC_FREE(result);
1910 return NT_STATUS_NO_MEMORY;
1911 }
1912
1913 if (!pdb_set_logon_script(sam_account, info->logon_script, PDB_CHANGED)) {
1914 TALLOC_FREE(result);
1915 return NT_STATUS_NO_MEMORY;
1916 }
1917
1918 if (!pdb_set_profile_path(sam_account, info->profile_path, PDB_CHANGED)) {
1919 TALLOC_FREE(result);
1920 return NT_STATUS_NO_MEMORY;
1921 }
1922
1923 if (!pdb_set_homedir(sam_account, info->home_directory, PDB_CHANGED)) {
1924 TALLOC_FREE(result);
1925 return NT_STATUS_NO_MEMORY;
1926 }
1927
1928 if (!pdb_set_dir_drive(sam_account, info->home_drive, PDB_CHANGED)) {
1929 TALLOC_FREE(result);
1930 return NT_STATUS_NO_MEMORY;
1931 }
1932
1933 if (!pdb_set_acct_ctrl(sam_account, info->acct_flags, PDB_CHANGED)) {
1934 TALLOC_FREE(result);
1935 return NT_STATUS_NO_MEMORY;
1936 }
1937
1938 if (!pdb_set_pass_last_set_time(
1939 sam_account,
1940 nt_time_to_unix(info->pass_last_set_time),
1941 PDB_CHANGED)) {
1942 TALLOC_FREE(result);
1943 return NT_STATUS_NO_MEMORY;
1944 }
1945
1946 if (!pdb_set_pass_can_change_time(
1947 sam_account,
1948 nt_time_to_unix(info->pass_can_change_time),
1949 PDB_CHANGED)) {
1950 TALLOC_FREE(result);
1951 return NT_STATUS_NO_MEMORY;
1952 }
1953
1954 if (!pdb_set_pass_must_change_time(
1955 sam_account,
1956 nt_time_to_unix(info->pass_must_change_time),
1957 PDB_CHANGED)) {
1958 TALLOC_FREE(result);
1959 return NT_STATUS_NO_MEMORY;
1960 }
1961
1962 /* save this here to _net_sam_logon() doesn't fail (it assumes a
1963 valid struct samu) */
1964
1965 result->sam_account = sam_account;
1966 result->unix_name = talloc_strdup(result, found_username);
1967
1968 result->login_server = talloc_strdup(result, info->logon_server);
1969
1970 /* Fill in the unix info we found on the way */
1971
1972 result->uid = uid;
1973 result->gid = gid;
1974
1975 /* Create a 'combined' list of all SIDs we might want in the SD */
1976
1977 result->num_sids = info->num_sids - 2;
1978 result->sids = talloc_array(result, DOM_SID, result->num_sids);
1979 if (result->sids == NULL) {
1980 TALLOC_FREE(result);
1981 return NT_STATUS_NO_MEMORY;
1982 }
1983
1984 for (i=0; i < result->num_sids; i++) {
1985 memcpy(&result->sids[i], &info->sids[i+2].sid, sizeof(result->sids[i]));
1986 }
1987
1988 /* Ensure the primary group sid is at position 0. */
1989 sort_sid_array_for_smbd(result, &group_sid);
1990
1991 /* ensure we are never given NULL session keys */
1992
1993 ZERO_STRUCT(zeros);
1994
1995 if (memcmp(info->user_session_key, zeros, sizeof(zeros)) == 0) {
1996 result->user_session_key = data_blob_null;
1997 } else {
1998 result->user_session_key = data_blob_talloc(
1999 result, info->user_session_key,
2000 sizeof(info->user_session_key));
2001 }
2002
2003 if (memcmp(info->lm_session_key, zeros, 8) == 0) {
2004 result->lm_session_key = data_blob_null;
2005 } else {
2006 result->lm_session_key = data_blob_talloc(
2007 result, info->lm_session_key,
2008 sizeof(info->lm_session_key));
2009 }
2010
2011 result->was_mapped = username_was_mapped;
2012
2013 *server_info = result;
2014
2015 return NT_STATUS_OK;
2016}
2017
2018/***************************************************************************
2019 Free a user_info struct
2020***************************************************************************/
2021
2022void free_user_info(auth_usersupplied_info **user_info)
2023{
2024 DEBUG(5,("attempting to free (and zero) a user_info structure\n"));
2025 if (*user_info != NULL) {
2026 if ((*user_info)->smb_name) {
2027 DEBUG(10,("structure was created for %s\n",
2028 (*user_info)->smb_name));
2029 }
2030 SAFE_FREE((*user_info)->smb_name);
2031 SAFE_FREE((*user_info)->internal_username);
2032 SAFE_FREE((*user_info)->client_domain);
2033 SAFE_FREE((*user_info)->domain);
2034 SAFE_FREE((*user_info)->wksta_name);
2035 data_blob_free(&(*user_info)->lm_resp);
2036 data_blob_free(&(*user_info)->nt_resp);
2037 data_blob_clear_free(&(*user_info)->lm_interactive_pwd);
2038 data_blob_clear_free(&(*user_info)->nt_interactive_pwd);
2039 data_blob_clear_free(&(*user_info)->plaintext_password);
2040 ZERO_STRUCT(**user_info);
2041 }
2042 SAFE_FREE(*user_info);
2043}
2044
2045/***************************************************************************
2046 Make an auth_methods struct
2047***************************************************************************/
2048
2049bool make_auth_methods(struct auth_context *auth_context, auth_methods **auth_method)
2050{
2051 if (!auth_context) {
2052 smb_panic("no auth_context supplied to "
2053 "make_auth_methods()!\n");
2054 }
2055
2056 if (!auth_method) {
2057 smb_panic("make_auth_methods: pointer to auth_method pointer "
2058 "is NULL!\n");
2059 }
2060
2061 *auth_method = TALLOC_P(auth_context->mem_ctx, auth_methods);
2062 if (!*auth_method) {
2063 DEBUG(0,("make_auth_method: malloc failed!\n"));
2064 return False;
2065 }
2066 ZERO_STRUCTP(*auth_method);
2067
2068 return True;
2069}
2070
2071/**
2072 * Verify whether or not given domain is trusted.
2073 *
2074 * @param domain_name name of the domain to be verified
2075 * @return true if domain is one of the trusted once or
2076 * false if otherwise
2077 **/
2078
2079bool is_trusted_domain(const char* dom_name)
2080{
2081 DOM_SID trustdom_sid;
2082 bool ret;
2083
2084 /* no trusted domains for a standalone server */
2085
2086 if ( lp_server_role() == ROLE_STANDALONE )
2087 return False;
2088
2089 /* if we are a DC, then check for a direct trust relationships */
2090
2091 if ( IS_DC ) {
2092 become_root();
2093 DEBUG (5,("is_trusted_domain: Checking for domain trust with "
2094 "[%s]\n", dom_name ));
2095 ret = pdb_get_trusteddom_pw(dom_name, NULL, NULL, NULL);
2096 unbecome_root();
2097 if (ret)
2098 return True;
2099 }
2100 else {
2101 wbcErr result;
2102
2103 /* If winbind is around, ask it */
2104
2105 result = wb_is_trusted_domain(dom_name);
2106
2107 if (result == WBC_ERR_SUCCESS) {
2108 return True;
2109 }
2110
2111 if (result == WBC_ERR_DOMAIN_NOT_FOUND) {
2112 /* winbind could not find the domain */
2113 return False;
2114 }
2115
2116 /* The only other possible result is that winbind is not up
2117 and running. We need to update the trustdom_cache
2118 ourselves */
2119
2120 update_trustdom_cache();
2121 }
2122
2123 /* now the trustdom cache should be available a DC could still
2124 * have a transitive trust so fall back to the cache of trusted
2125 * domains (like a domain member would use */
2126
2127 if ( trustdom_cache_fetch(dom_name, &trustdom_sid) ) {
2128 return True;
2129 }
2130
2131 return False;
2132}
2133
Note: See TracBrowser for help on using the repository browser.