source: branches/samba-3.0/source/auth/auth_util.c

Last change on this file was 140, checked in by Paul Smedley, 17 years ago

Update branch to 3.0.31 release

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