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