gensec: clarify memory ownership for gensec_session_info() and gensec_session_key()
[amitay/samba.git] / source3 / auth / auth_util.c
1 /*
2    Unix SMB/CIFS implementation.
3    Authentication utility functions
4    Copyright (C) Andrew Tridgell 1992-1998
5    Copyright (C) Andrew Bartlett 2001-2011
6    Copyright (C) Jeremy Allison 2000-2001
7    Copyright (C) Rafal Szczesniak 2002
8    Copyright (C) Volker Lendecke 2006-2008
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 "auth.h"
26 #include "../libcli/auth/libcli_auth.h"
27 #include "../lib/crypto/arcfour.h"
28 #include "rpc_client/init_lsa.h"
29 #include "../libcli/security/security.h"
30 #include "../lib/util/util_pw.h"
31 #include "lib/winbind_util.h"
32 #include "passdb.h"
33 #include "../librpc/gen_ndr/ndr_auth.h"
34 #include "../auth/auth_sam_reply.h"
35
36 #undef DBGC_CLASS
37 #define DBGC_CLASS DBGC_AUTH
38
39 /****************************************************************************
40  Create a UNIX user on demand.
41 ****************************************************************************/
42
43 static int _smb_create_user(const char *domain, const char *unix_username, const char *homedir)
44 {
45         TALLOC_CTX *ctx = talloc_tos();
46         char *add_script;
47         int ret;
48
49         add_script = talloc_strdup(ctx, lp_adduser_script());
50         if (!add_script || !*add_script) {
51                 return -1;
52         }
53         add_script = talloc_all_string_sub(ctx,
54                                 add_script,
55                                 "%u",
56                                 unix_username);
57         if (!add_script) {
58                 return -1;
59         }
60         if (domain) {
61                 add_script = talloc_all_string_sub(ctx,
62                                         add_script,
63                                         "%D",
64                                         domain);
65                 if (!add_script) {
66                         return -1;
67                 }
68         }
69         if (homedir) {
70                 add_script = talloc_all_string_sub(ctx,
71                                 add_script,
72                                 "%H",
73                                 homedir);
74                 if (!add_script) {
75                         return -1;
76                 }
77         }
78         ret = smbrun(add_script,NULL);
79         flush_pwnam_cache();
80         DEBUG(ret ? 0 : 3,
81                 ("smb_create_user: Running the command `%s' gave %d\n",
82                  add_script,ret));
83         return ret;
84 }
85
86 /****************************************************************************
87  Create an auth_usersupplied_data structure after appropriate mapping.
88 ****************************************************************************/
89
90 NTSTATUS make_user_info_map(struct auth_usersupplied_info **user_info,
91                             const char *smb_name,
92                             const char *client_domain,
93                             const char *workstation_name,
94                             const struct tsocket_address *remote_address,
95                             DATA_BLOB *lm_pwd,
96                             DATA_BLOB *nt_pwd,
97                             const struct samr_Password *lm_interactive_pwd,
98                             const struct samr_Password *nt_interactive_pwd,
99                             const char *plaintext,
100                             enum auth_password_state password_state)
101 {
102         const char *domain;
103         NTSTATUS result;
104         bool was_mapped;
105         char *internal_username = NULL;
106
107         was_mapped = map_username(talloc_tos(), smb_name, &internal_username);
108         if (!internal_username) {
109                 return NT_STATUS_NO_MEMORY;
110         }
111
112         DEBUG(5, ("Mapping user [%s]\\[%s] from workstation [%s]\n",
113                  client_domain, smb_name, workstation_name));
114
115         domain = client_domain;
116
117         /* If you connect to a Windows domain member using a bogus domain name,
118          * the Windows box will map the BOGUS\user to SAMNAME\user.  Thus, if
119          * the Windows box is a DC the name will become DOMAIN\user and be
120          * authenticated against AD, if the Windows box is a member server but
121          * not a DC the name will become WORKSTATION\user.  A standalone
122          * non-domain member box will also map to WORKSTATION\user.
123          * This also deals with the client passing in a "" domain */
124
125         if (!is_trusted_domain(domain) &&
126             !strequal(domain, my_sam_name()))
127         {
128                 if (lp_map_untrusted_to_domain())
129                         domain = my_sam_name();
130                 else
131                         domain = get_global_sam_name();
132                 DEBUG(5, ("Mapped domain from [%s] to [%s] for user [%s] from "
133                           "workstation [%s]\n",
134                           client_domain, domain, smb_name, workstation_name));
135         }
136
137         /* We know that the given domain is trusted (and we are allowing them),
138          * it is our global SAM name, or for legacy behavior it is our
139          * primary domain name */
140
141         result = make_user_info(user_info, smb_name, internal_username,
142                               client_domain, domain, workstation_name,
143                               remote_address, lm_pwd, nt_pwd,
144                               lm_interactive_pwd, nt_interactive_pwd,
145                               plaintext, password_state);
146         if (NT_STATUS_IS_OK(result)) {
147                 /* We have tried mapping */
148                 (*user_info)->mapped_state = true;
149                 /* did we actually map the user to a different name? */
150                 (*user_info)->was_mapped = was_mapped;
151         }
152         return result;
153 }
154
155 /****************************************************************************
156  Create an auth_usersupplied_data, making the DATA_BLOBs here. 
157  Decrypt and encrypt the passwords.
158 ****************************************************************************/
159
160 bool make_user_info_netlogon_network(struct auth_usersupplied_info **user_info,
161                                      const char *smb_name, 
162                                      const char *client_domain, 
163                                      const char *workstation_name,
164                                      const struct tsocket_address *remote_address,
165                                      uint32 logon_parameters,
166                                      const uchar *lm_network_pwd,
167                                      int lm_pwd_len,
168                                      const uchar *nt_network_pwd,
169                                      int nt_pwd_len)
170 {
171         bool ret;
172         NTSTATUS status;
173         DATA_BLOB lm_blob = data_blob(lm_network_pwd, lm_pwd_len);
174         DATA_BLOB nt_blob = data_blob(nt_network_pwd, nt_pwd_len);
175
176         status = make_user_info_map(user_info,
177                                     smb_name, client_domain, 
178                                     workstation_name,
179                                     remote_address,
180                                     lm_pwd_len ? &lm_blob : NULL, 
181                                     nt_pwd_len ? &nt_blob : NULL,
182                                     NULL, NULL, NULL,
183                                     AUTH_PASSWORD_RESPONSE);
184
185         if (NT_STATUS_IS_OK(status)) {
186                 (*user_info)->logon_parameters = logon_parameters;
187         }
188         ret = NT_STATUS_IS_OK(status) ? true : false;
189
190         data_blob_free(&lm_blob);
191         data_blob_free(&nt_blob);
192         return ret;
193 }
194
195 /****************************************************************************
196  Create an auth_usersupplied_data, making the DATA_BLOBs here. 
197  Decrypt and encrypt the passwords.
198 ****************************************************************************/
199
200 bool make_user_info_netlogon_interactive(struct auth_usersupplied_info **user_info,
201                                          const char *smb_name, 
202                                          const char *client_domain, 
203                                          const char *workstation_name,
204                                          const struct tsocket_address *remote_address,
205                                          uint32 logon_parameters,
206                                          const uchar chal[8], 
207                                          const uchar lm_interactive_pwd[16], 
208                                          const uchar nt_interactive_pwd[16], 
209                                          const uchar *dc_sess_key)
210 {
211         struct samr_Password lm_pwd;
212         struct samr_Password nt_pwd;
213         unsigned char local_lm_response[24];
214         unsigned char local_nt_response[24];
215         unsigned char key[16];
216
217         memcpy(key, dc_sess_key, 16);
218
219         if (lm_interactive_pwd)
220                 memcpy(lm_pwd.hash, lm_interactive_pwd, sizeof(lm_pwd.hash));
221
222         if (nt_interactive_pwd)
223                 memcpy(nt_pwd.hash, nt_interactive_pwd, sizeof(nt_pwd.hash));
224
225 #ifdef DEBUG_PASSWORD
226         DEBUG(100,("key:"));
227         dump_data(100, key, sizeof(key));
228
229         DEBUG(100,("lm owf password:"));
230         dump_data(100, lm_pwd.hash, sizeof(lm_pwd.hash));
231
232         DEBUG(100,("nt owf password:"));
233         dump_data(100, nt_pwd.hash, sizeof(nt_pwd.hash));
234 #endif
235
236         if (lm_interactive_pwd)
237                 arcfour_crypt(lm_pwd.hash, key, sizeof(lm_pwd.hash));
238
239         if (nt_interactive_pwd)
240                 arcfour_crypt(nt_pwd.hash, key, sizeof(nt_pwd.hash));
241
242 #ifdef DEBUG_PASSWORD
243         DEBUG(100,("decrypt of lm owf password:"));
244         dump_data(100, lm_pwd.hash, sizeof(lm_pwd));
245
246         DEBUG(100,("decrypt of nt owf password:"));
247         dump_data(100, nt_pwd.hash, sizeof(nt_pwd));
248 #endif
249
250         if (lm_interactive_pwd)
251                 SMBOWFencrypt(lm_pwd.hash, chal,
252                               local_lm_response);
253
254         if (nt_interactive_pwd)
255                 SMBOWFencrypt(nt_pwd.hash, chal,
256                               local_nt_response);
257
258         /* Password info paranoia */
259         ZERO_STRUCT(key);
260
261         {
262                 bool ret;
263                 NTSTATUS nt_status;
264                 DATA_BLOB local_lm_blob;
265                 DATA_BLOB local_nt_blob;
266
267                 if (lm_interactive_pwd) {
268                         local_lm_blob = data_blob(local_lm_response,
269                                                   sizeof(local_lm_response));
270                 }
271
272                 if (nt_interactive_pwd) {
273                         local_nt_blob = data_blob(local_nt_response,
274                                                   sizeof(local_nt_response));
275                 }
276
277                 nt_status = make_user_info_map(
278                         user_info, 
279                         smb_name, client_domain, workstation_name,
280                         remote_address,
281                         lm_interactive_pwd ? &local_lm_blob : NULL,
282                         nt_interactive_pwd ? &local_nt_blob : NULL,
283                         lm_interactive_pwd ? &lm_pwd : NULL,
284                         nt_interactive_pwd ? &nt_pwd : NULL,
285                         NULL, AUTH_PASSWORD_HASH);
286
287                 if (NT_STATUS_IS_OK(nt_status)) {
288                         (*user_info)->logon_parameters = logon_parameters;
289                 }
290
291                 ret = NT_STATUS_IS_OK(nt_status) ? true : false;
292                 data_blob_free(&local_lm_blob);
293                 data_blob_free(&local_nt_blob);
294                 return ret;
295         }
296 }
297
298
299 /****************************************************************************
300  Create an auth_usersupplied_data structure
301 ****************************************************************************/
302
303 bool make_user_info_for_reply(struct auth_usersupplied_info **user_info,
304                               const char *smb_name, 
305                               const char *client_domain,
306                               const struct tsocket_address *remote_address,
307                               const uint8 chal[8],
308                               DATA_BLOB plaintext_password)
309 {
310
311         DATA_BLOB local_lm_blob;
312         DATA_BLOB local_nt_blob;
313         NTSTATUS ret = NT_STATUS_UNSUCCESSFUL;
314         char *plaintext_password_string;
315         /*
316          * Not encrypted - do so.
317          */
318
319         DEBUG(5,("make_user_info_for_reply: User passwords not in encrypted "
320                  "format.\n"));
321         if (plaintext_password.data && plaintext_password.length) {
322                 unsigned char local_lm_response[24];
323
324 #ifdef DEBUG_PASSWORD
325                 DEBUG(10,("Unencrypted password (len %d):\n",
326                           (int)plaintext_password.length));
327                 dump_data(100, plaintext_password.data,
328                           plaintext_password.length);
329 #endif
330
331                 SMBencrypt( (const char *)plaintext_password.data,
332                             (const uchar*)chal, local_lm_response);
333                 local_lm_blob = data_blob(local_lm_response, 24);
334
335                 /* We can't do an NT hash here, as the password needs to be
336                    case insensitive */
337                 local_nt_blob = data_blob_null; 
338         } else {
339                 local_lm_blob = data_blob_null; 
340                 local_nt_blob = data_blob_null; 
341         }
342
343         plaintext_password_string = talloc_strndup(talloc_tos(),
344                                                    (const char *)plaintext_password.data,
345                                                    plaintext_password.length);
346         if (!plaintext_password_string) {
347                 return false;
348         }
349
350         ret = make_user_info_map(
351                 user_info, smb_name, client_domain, 
352                 get_remote_machine_name(),
353                 remote_address,
354                 local_lm_blob.data ? &local_lm_blob : NULL,
355                 local_nt_blob.data ? &local_nt_blob : NULL,
356                 NULL, NULL,
357                 plaintext_password_string,
358                 AUTH_PASSWORD_PLAIN);
359
360         if (plaintext_password_string) {
361                 memset(plaintext_password_string, '\0', strlen(plaintext_password_string));
362                 talloc_free(plaintext_password_string);
363         }
364
365         data_blob_free(&local_lm_blob);
366         return NT_STATUS_IS_OK(ret) ? true : false;
367 }
368
369 /****************************************************************************
370  Create an auth_usersupplied_data structure
371 ****************************************************************************/
372
373 NTSTATUS make_user_info_for_reply_enc(struct auth_usersupplied_info **user_info,
374                                       const char *smb_name,
375                                       const char *client_domain,
376                                       const struct tsocket_address *remote_address,
377                                       DATA_BLOB lm_resp, DATA_BLOB nt_resp)
378 {
379         return make_user_info_map(user_info, smb_name, 
380                                   client_domain, 
381                                   get_remote_machine_name(),
382                                   remote_address,
383                                   lm_resp.data && (lm_resp.length > 0) ? &lm_resp : NULL,
384                                   nt_resp.data && (nt_resp.length > 0) ? &nt_resp : NULL,
385                                   NULL, NULL, NULL,
386                                   AUTH_PASSWORD_RESPONSE);
387 }
388
389 /****************************************************************************
390  Create a guest user_info blob, for anonymous authentication.
391 ****************************************************************************/
392
393 bool make_user_info_guest(const struct tsocket_address *remote_address,
394                           struct auth_usersupplied_info **user_info)
395 {
396         NTSTATUS nt_status;
397
398         nt_status = make_user_info(user_info, 
399                                    "","", 
400                                    "","", 
401                                    "", 
402                                    remote_address,
403                                    NULL, NULL, 
404                                    NULL, NULL, 
405                                    NULL,
406                                    AUTH_PASSWORD_RESPONSE);
407
408         return NT_STATUS_IS_OK(nt_status) ? true : false;
409 }
410
411 static NTSTATUS log_nt_token(struct security_token *token)
412 {
413         TALLOC_CTX *frame = talloc_stackframe();
414         char *command;
415         char *group_sidstr;
416         size_t i;
417
418         if ((lp_log_nt_token_command() == NULL) ||
419             (strlen(lp_log_nt_token_command()) == 0)) {
420                 TALLOC_FREE(frame);
421                 return NT_STATUS_OK;
422         }
423
424         group_sidstr = talloc_strdup(frame, "");
425         for (i=1; i<token->num_sids; i++) {
426                 group_sidstr = talloc_asprintf(
427                         frame, "%s %s", group_sidstr,
428                         sid_string_talloc(frame, &token->sids[i]));
429         }
430
431         command = talloc_string_sub(
432                 frame, lp_log_nt_token_command(),
433                 "%s", sid_string_talloc(frame, &token->sids[0]));
434         command = talloc_string_sub(frame, command, "%t", group_sidstr);
435
436         if (command == NULL) {
437                 TALLOC_FREE(frame);
438                 return NT_STATUS_NO_MEMORY;
439         }
440
441         DEBUG(8, ("running command: [%s]\n", command));
442         if (smbrun(command, NULL) != 0) {
443                 DEBUG(0, ("Could not log NT token\n"));
444                 TALLOC_FREE(frame);
445                 return NT_STATUS_ACCESS_DENIED;
446         }
447
448         TALLOC_FREE(frame);
449         return NT_STATUS_OK;
450 }
451
452 /*
453  * Create the token to use from server_info->info3 and
454  * server_info->sids (the info3/sam groups). Find the unix gids.
455  */
456
457 NTSTATUS create_local_token(TALLOC_CTX *mem_ctx,
458                             const struct auth_serversupplied_info *server_info,
459                             DATA_BLOB *session_key,
460                             struct auth_session_info **session_info_out)
461 {
462         struct security_token *t;
463         NTSTATUS status;
464         size_t i;
465         struct dom_sid tmp_sid;
466         struct auth_session_info *session_info;
467         struct wbcUnixId *ids;
468
469         /* Ensure we can't possible take a code path leading to a
470          * null defref. */
471         if (!server_info) {
472                 return NT_STATUS_LOGON_FAILURE;
473         }
474
475         session_info = talloc_zero(mem_ctx, struct auth_session_info);
476         if (!session_info) {
477                 return NT_STATUS_NO_MEMORY;
478         }
479
480         session_info->unix_token = talloc_zero(session_info, struct security_unix_token);
481         if (!session_info->unix_token) {
482                 TALLOC_FREE(session_info);
483                 return NT_STATUS_NO_MEMORY;
484         }
485
486         session_info->unix_token->uid = server_info->utok.uid;
487         session_info->unix_token->gid = server_info->utok.gid;
488
489         session_info->unix_info = talloc_zero(session_info, struct auth_user_info_unix);
490         if (!session_info->unix_info) {
491                 TALLOC_FREE(session_info);
492                 return NT_STATUS_NO_MEMORY;
493         }
494
495         session_info->unix_info->unix_name = talloc_strdup(session_info, server_info->unix_name);
496         if (!session_info->unix_info->unix_name) {
497                 TALLOC_FREE(session_info);
498                 return NT_STATUS_NO_MEMORY;
499         }
500
501         session_info->unix_info->sanitized_username = talloc_strdup(session_info, server_info->sanitized_username);
502         if (!session_info->unix_info->sanitized_username) {
503                 TALLOC_FREE(session_info);
504                 return NT_STATUS_NO_MEMORY;
505         }
506
507         session_info->unix_info->system = server_info->system;
508
509         if (session_key) {
510                 data_blob_free(&session_info->session_key);
511                 session_info->session_key = data_blob_talloc(session_info,
512                                                                   session_key->data,
513                                                                   session_key->length);
514                 if (!session_info->session_key.data && session_key->length) {
515                         return NT_STATUS_NO_MEMORY;
516                 }
517         } else {
518                 session_info->session_key = data_blob_talloc( session_info, server_info->session_key.data,
519                                                               server_info->session_key.length);
520         }
521
522         if (session_info->security_token) {
523                 /* Just copy the token, it has already been finalised
524                  * (nasty hack to support a cached guest session_info,
525                  * and a possible strategy for auth_samba4 to pass in
526                  * a finalised session) */
527
528                 session_info->security_token = dup_nt_token(session_info, server_info->security_token);
529                 if (!session_info->security_token) {
530                         TALLOC_FREE(session_info);
531                         return NT_STATUS_NO_MEMORY;
532                 }
533
534                 session_info->unix_token->ngroups = server_info->utok.ngroups;
535                 if (server_info->utok.ngroups != 0) {
536                         session_info->unix_token->groups = (gid_t *)talloc_memdup(
537                                 session_info->unix_token, server_info->utok.groups,
538                                 sizeof(gid_t)*session_info->unix_token->ngroups);
539                 } else {
540                         session_info->unix_token->groups = NULL;
541                 }
542
543                 *session_info_out = session_info;
544                 return NT_STATUS_OK;
545         }
546
547         /* We need to populate session_info->info with the information found in server_info->info3 */
548         status = make_user_info_SamBaseInfo(session_info, "", &server_info->info3->base,
549                                             server_info->guest == false,
550                                             &session_info->info);
551         if (!NT_STATUS_IS_OK(status)) {
552                 DEBUG(0, ("conversion of info3 into auth_user_info failed!\n"));
553                 TALLOC_FREE(session_info);
554                 return status;
555         }
556
557         /*
558          * If winbind is not around, we can not make much use of the SIDs the
559          * domain controller provided us with. Likewise if the user name was
560          * mapped to some local unix user.
561          */
562
563         if (((lp_server_role() == ROLE_DOMAIN_MEMBER) && !winbind_ping()) ||
564             (server_info->nss_token)) {
565                 char *found_username = NULL;
566                 status = create_token_from_username(session_info,
567                                                     server_info->unix_name,
568                                                     server_info->guest,
569                                                     &session_info->unix_token->uid,
570                                                     &session_info->unix_token->gid,
571                                                     &found_username,
572                                                     &session_info->security_token);
573                 if (NT_STATUS_IS_OK(status)) {
574                         session_info->unix_info->unix_name = found_username;
575                 }
576         } else {
577                 status = create_local_nt_token_from_info3(session_info,
578                                                           server_info->guest,
579                                                           server_info->info3,
580                                                           &server_info->extra,
581                                                           &session_info->security_token);
582         }
583
584         if (!NT_STATUS_IS_OK(status)) {
585                 return status;
586         }
587
588         /* Convert the SIDs to gids. */
589
590         session_info->unix_token->ngroups = 0;
591         session_info->unix_token->groups = NULL;
592
593         t = session_info->security_token;
594
595         ids = talloc_array(talloc_tos(), struct wbcUnixId,
596                            t->num_sids);
597         if (ids == NULL) {
598                 return NT_STATUS_NO_MEMORY;
599         }
600
601         if (!sids_to_unix_ids(t->sids, t->num_sids, ids)) {
602                 TALLOC_FREE(ids);
603                 return NT_STATUS_NO_MEMORY;
604         }
605
606         /* Start at index 1, where the groups start. */
607
608         for (i=1; i<t->num_sids; i++) {
609
610                 if (ids[i].type != WBC_ID_TYPE_GID) {
611                         DEBUG(10, ("Could not convert SID %s to gid, "
612                                    "ignoring it\n",
613                                    sid_string_dbg(&t->sids[i])));
614                         continue;
615                 }
616                 if (!add_gid_to_array_unique(session_info, ids[i].id.gid,
617                                              &session_info->unix_token->groups,
618                                              &session_info->unix_token->ngroups)) {
619                         return NT_STATUS_NO_MEMORY;
620                 }
621         }
622
623         /*
624          * Add the "Unix Group" SID for each gid to catch mapped groups
625          * and their Unix equivalent.  This is to solve the backwards
626          * compatibility problem of 'valid users = +ntadmin' where
627          * ntadmin has been paired with "Domain Admins" in the group
628          * mapping table.  Otherwise smb.conf would need to be changed
629          * to 'valid user = "Domain Admins"'.  --jerry
630          *
631          * For consistency we also add the "Unix User" SID,
632          * so that the complete unix token is represented within
633          * the nt token.
634          */
635
636         uid_to_unix_users_sid(session_info->unix_token->uid, &tmp_sid);
637
638         add_sid_to_array_unique(session_info->security_token, &tmp_sid,
639                                 &session_info->security_token->sids,
640                                 &session_info->security_token->num_sids);
641
642         for ( i=0; i<session_info->unix_token->ngroups; i++ ) {
643                 gid_to_unix_groups_sid(session_info->unix_token->groups[i], &tmp_sid);
644                 add_sid_to_array_unique(session_info->security_token, &tmp_sid,
645                                         &session_info->security_token->sids,
646                                         &session_info->security_token->num_sids);
647         }
648
649         security_token_debug(DBGC_AUTH, 10, session_info->security_token);
650         debug_unix_user_token(DBGC_AUTH, 10,
651                               session_info->unix_token->uid,
652                               session_info->unix_token->gid,
653                               session_info->unix_token->ngroups,
654                               session_info->unix_token->groups);
655
656         status = log_nt_token(session_info->security_token);
657         if (!NT_STATUS_IS_OK(status)) {
658                 return status;
659         }
660
661         *session_info_out = session_info;
662         return NT_STATUS_OK;
663 }
664
665 /***************************************************************************
666  Make (and fill) a server_info struct from a 'struct passwd' by conversion
667  to a struct samu
668 ***************************************************************************/
669
670 NTSTATUS make_server_info_pw(struct auth_serversupplied_info **server_info,
671                              char *unix_username,
672                              struct passwd *pwd)
673 {
674         NTSTATUS status;
675         struct samu *sampass = NULL;
676         char *qualified_name = NULL;
677         TALLOC_CTX *mem_ctx = NULL;
678         struct dom_sid u_sid;
679         enum lsa_SidType type;
680         struct auth_serversupplied_info *result;
681
682         /*
683          * The SID returned in server_info->sam_account is based
684          * on our SAM sid even though for a pure UNIX account this should
685          * not be the case as it doesn't really exist in the SAM db.
686          * This causes lookups on "[in]valid users" to fail as they
687          * will lookup this name as a "Unix User" SID to check against
688          * the user token. Fix this by adding the "Unix User"\unix_username
689          * SID to the sid array. The correct fix should probably be
690          * changing the server_info->sam_account user SID to be a
691          * S-1-22 Unix SID, but this might break old configs where
692          * plaintext passwords were used with no SAM backend.
693          */
694
695         mem_ctx = talloc_init("make_server_info_pw_tmp");
696         if (!mem_ctx) {
697                 return NT_STATUS_NO_MEMORY;
698         }
699
700         qualified_name = talloc_asprintf(mem_ctx, "%s\\%s",
701                                         unix_users_domain_name(),
702                                         unix_username );
703         if (!qualified_name) {
704                 TALLOC_FREE(mem_ctx);
705                 return NT_STATUS_NO_MEMORY;
706         }
707
708         if (!lookup_name(mem_ctx, qualified_name, LOOKUP_NAME_ALL,
709                                                 NULL, NULL,
710                                                 &u_sid, &type)) {
711                 TALLOC_FREE(mem_ctx);
712                 return NT_STATUS_NO_SUCH_USER;
713         }
714
715         TALLOC_FREE(mem_ctx);
716
717         if (type != SID_NAME_USER) {
718                 return NT_STATUS_NO_SUCH_USER;
719         }
720
721         if ( !(sampass = samu_new( NULL )) ) {
722                 return NT_STATUS_NO_MEMORY;
723         }
724
725         status = samu_set_unix( sampass, pwd );
726         if (!NT_STATUS_IS_OK(status)) {
727                 return status;
728         }
729
730         /* In pathological cases the above call can set the account
731          * name to the DOMAIN\username form. Reset the account name
732          * using unix_username */
733         pdb_set_username(sampass, unix_username, PDB_SET);
734
735         /* set the user sid to be the calculated u_sid */
736         pdb_set_user_sid(sampass, &u_sid, PDB_SET);
737
738         result = make_server_info(NULL);
739         if (result == NULL) {
740                 TALLOC_FREE(sampass);
741                 return NT_STATUS_NO_MEMORY;
742         }
743
744         status = samu_to_SamInfo3(result, sampass, lp_netbios_name(),
745                                   &result->info3, &result->extra);
746         TALLOC_FREE(sampass);
747         if (!NT_STATUS_IS_OK(status)) {
748                 DEBUG(10, ("Failed to convert samu to info3: %s\n",
749                            nt_errstr(status)));
750                 TALLOC_FREE(result);
751                 return status;
752         }
753
754         result->unix_name = talloc_strdup(result, unix_username);
755         result->sanitized_username = sanitize_username(result, unix_username);
756
757         if ((result->unix_name == NULL)
758             || (result->sanitized_username == NULL)) {
759                 TALLOC_FREE(result);
760                 return NT_STATUS_NO_MEMORY;
761         }
762
763         result->utok.uid = pwd->pw_uid;
764         result->utok.gid = pwd->pw_gid;
765
766         *server_info = result;
767
768         return NT_STATUS_OK;
769 }
770
771 static NTSTATUS get_guest_info3(TALLOC_CTX *mem_ctx,
772                                 struct netr_SamInfo3 *info3)
773 {
774         const char *guest_account = lp_guestaccount();
775         struct dom_sid domain_sid;
776         struct passwd *pwd;
777         const char *tmp;
778
779         pwd = Get_Pwnam_alloc(mem_ctx, guest_account);
780         if (pwd == NULL) {
781                 DEBUG(0,("SamInfo3_for_guest: Unable to locate guest "
782                          "account [%s]!\n", guest_account));
783                 return NT_STATUS_NO_SUCH_USER;
784         }
785
786         /* Set account name */
787         tmp = talloc_strdup(mem_ctx, pwd->pw_name);
788         if (tmp == NULL) {
789                 return NT_STATUS_NO_MEMORY;
790         }
791         init_lsa_String(&info3->base.account_name, tmp);
792
793         /* Set domain name */
794         tmp = talloc_strdup(mem_ctx, get_global_sam_name());
795         if (tmp == NULL) {
796                 return NT_STATUS_NO_MEMORY;
797         }
798         init_lsa_StringLarge(&info3->base.domain, tmp);
799
800         /* Domain sid */
801         sid_copy(&domain_sid, get_global_sam_sid());
802
803         info3->base.domain_sid = dom_sid_dup(mem_ctx, &domain_sid);
804         if (info3->base.domain_sid == NULL) {
805                 return NT_STATUS_NO_MEMORY;
806         }
807
808         /* Guest rid */
809         info3->base.rid = DOMAIN_RID_GUEST;
810
811         /* Primary gid */
812         info3->base.primary_gid = BUILTIN_RID_GUESTS;
813
814         /* Set as guest */
815         info3->base.user_flags = NETLOGON_GUEST;
816
817         TALLOC_FREE(pwd);
818         return NT_STATUS_OK;
819 }
820
821 /***************************************************************************
822  Make (and fill) a user_info struct for a guest login.
823  This *must* succeed for smbd to start. If there is no mapping entry for
824  the guest gid, then create one.
825
826  The resulting structure is a 'session_info' because
827  create_local_token() has already been called on it.  This is quite
828  nasty, as the auth subsystem isn't expect this, but the behavior is
829  left as-is for now.
830 ***************************************************************************/
831
832 static NTSTATUS make_new_session_info_guest(struct auth_session_info **session_info, struct auth_serversupplied_info **server_info)
833 {
834         static const char zeros[16] = {0};
835         const char *guest_account = lp_guestaccount();
836         const char *domain = lp_netbios_name();
837         struct netr_SamInfo3 info3;
838         TALLOC_CTX *tmp_ctx;
839         NTSTATUS status;
840         fstring tmp;
841
842         tmp_ctx = talloc_stackframe();
843         if (tmp_ctx == NULL) {
844                 return NT_STATUS_NO_MEMORY;
845         }
846
847         ZERO_STRUCT(info3);
848
849         status = get_guest_info3(tmp_ctx, &info3);
850         if (!NT_STATUS_IS_OK(status)) {
851                 DEBUG(0, ("get_guest_info3 failed with %s\n",
852                           nt_errstr(status)));
853                 goto done;
854         }
855
856         status = make_server_info_info3(tmp_ctx,
857                                         guest_account,
858                                         domain,
859                                         server_info,
860                                         &info3);
861         if (!NT_STATUS_IS_OK(status)) {
862                 DEBUG(0, ("make_server_info_info3 failed with %s\n",
863                           nt_errstr(status)));
864                 goto done;
865         }
866
867         (*server_info)->guest = true;
868
869         /* This should not be done here (we should produce a server
870          * info, and later construct a session info from it), but for
871          * now this does not change the previous behavior */
872         status = create_local_token(tmp_ctx, *server_info, NULL, session_info);
873         if (!NT_STATUS_IS_OK(status)) {
874                 DEBUG(0, ("create_local_token failed: %s\n",
875                           nt_errstr(status)));
876                 goto done;
877         }
878         talloc_steal(NULL, *session_info);
879         talloc_steal(NULL, *server_info);
880
881         /* annoying, but the Guest really does have a session key, and it is
882            all zeros! */
883         (*session_info)->session_key = data_blob(zeros, sizeof(zeros));
884
885         alpha_strcpy(tmp, (*server_info)->info3->base.account_name.string,
886                      ". _-$", sizeof(tmp));
887         (*session_info)->unix_info->sanitized_username = talloc_strdup(*session_info, tmp);
888
889         status = NT_STATUS_OK;
890 done:
891         TALLOC_FREE(tmp_ctx);
892         return status;
893 }
894
895 /***************************************************************************
896  Make (and fill) a auth_session_info struct for a system user login.
897  This *must* succeed for smbd to start.
898 ***************************************************************************/
899
900 static NTSTATUS make_new_session_info_system(TALLOC_CTX *mem_ctx,
901                                             struct auth_session_info **session_info)
902 {
903         struct passwd *pwd;
904         NTSTATUS status;
905
906         pwd = getpwuid_alloc(mem_ctx, sec_initial_uid());
907         if (pwd == NULL) {
908                 return NT_STATUS_NO_SUCH_USER;
909         }
910
911         status = make_session_info_from_username(mem_ctx,
912                                                  pwd->pw_name,
913                                                  false,
914                                                  session_info);
915         TALLOC_FREE(pwd);
916         if (!NT_STATUS_IS_OK(status)) {
917                 return status;
918         }
919
920         (*session_info)->unix_info->system = true;
921
922         status = add_sid_to_array_unique((*session_info)->security_token->sids,
923                                          &global_sid_System,
924                                          &(*session_info)->security_token->sids,
925                                          &(*session_info)->security_token->num_sids);
926         if (!NT_STATUS_IS_OK(status)) {
927                 TALLOC_FREE((*session_info));
928                 return status;
929         }
930
931         return NT_STATUS_OK;
932 }
933
934 /****************************************************************************
935   Fake a auth_session_info just from a username (as a
936   session_info structure, with create_local_token() already called on
937   it.
938 ****************************************************************************/
939
940 NTSTATUS make_session_info_from_username(TALLOC_CTX *mem_ctx,
941                                          const char *username,
942                                          bool is_guest,
943                                          struct auth_session_info **session_info)
944 {
945         struct auth_serversupplied_info *result;
946         struct passwd *pwd;
947         NTSTATUS status;
948
949         pwd = Get_Pwnam_alloc(talloc_tos(), username);
950         if (pwd == NULL) {
951                 return NT_STATUS_NO_SUCH_USER;
952         }
953
954         status = make_server_info_pw(&result, pwd->pw_name, pwd);
955
956         TALLOC_FREE(pwd);
957
958         if (!NT_STATUS_IS_OK(status)) {
959                 return status;
960         }
961
962         result->nss_token = true;
963         result->guest = is_guest;
964
965         /* Now turn the server_info into a session_info with the full token etc */
966         status = create_local_token(mem_ctx, result, NULL, session_info);
967         talloc_free(result);
968         return status;
969 }
970
971 /* This function MUST only used to create the cached server_info for
972  * guest.
973  *
974  * This is a lossy conversion.  Variables known to be lost so far
975  * include:
976  *
977  * - nss_token (not needed because the only read doesn't happen
978  * for the GUEST user, as this routine populates ->security_token
979  *
980  * - extra (not needed because the guest account must have valid RIDs per the output of get_guest_info3())
981  *
982  * - The 'server_info' parameter allows the missing 'info3' to be copied across.
983  */
984 static struct auth_serversupplied_info *copy_session_info_serverinfo_guest(TALLOC_CTX *mem_ctx,
985                                                                            const struct auth_session_info *src,
986                                                                            struct auth_serversupplied_info *server_info)
987 {
988         struct auth_serversupplied_info *dst;
989
990         dst = make_server_info(mem_ctx);
991         if (dst == NULL) {
992                 return NULL;
993         }
994
995         /* This element must be provided to convert back to an auth_serversupplied_info */
996         SMB_ASSERT(src->unix_info);
997
998         dst->guest = true;
999         dst->system = false;
1000
1001         /* This element must be provided to convert back to an
1002          * auth_serversupplied_info.  This needs to be from the
1003          * auth_session_info because the group values in particular
1004          * may change during create_local_token() processing */
1005         SMB_ASSERT(src->unix_token);
1006         dst->utok.uid = src->unix_token->uid;
1007         dst->utok.gid = src->unix_token->gid;
1008         dst->utok.ngroups = src->unix_token->ngroups;
1009         if (src->unix_token->ngroups != 0) {
1010                 dst->utok.groups = (gid_t *)talloc_memdup(
1011                         dst, src->unix_token->groups,
1012                         sizeof(gid_t)*dst->utok.ngroups);
1013         } else {
1014                 dst->utok.groups = NULL;
1015         }
1016
1017         /* We must have a security_token as otherwise the lossy
1018          * conversion without nss_token would cause create_local_token
1019          * to take the wrong path */
1020         SMB_ASSERT(src->security_token);
1021
1022         dst->security_token = dup_nt_token(dst, src->security_token);
1023         if (!dst->security_token) {
1024                 TALLOC_FREE(dst);
1025                 return NULL;
1026         }
1027
1028         dst->session_key = data_blob_talloc( dst, src->session_key.data,
1029                                                 src->session_key.length);
1030
1031         /* This is OK because this functions is only used for the
1032          * GUEST account, which has all-zero keys for both values */
1033         dst->lm_session_key = data_blob_talloc(dst, src->session_key.data,
1034                                                 src->session_key.length);
1035
1036         dst->info3 = copy_netr_SamInfo3(dst, server_info->info3);
1037         if (!dst->info3) {
1038                 TALLOC_FREE(dst);
1039                 return NULL;
1040         }
1041
1042         dst->unix_name = talloc_strdup(dst, src->unix_info->unix_name);
1043         if (!dst->unix_name) {
1044                 TALLOC_FREE(dst);
1045                 return NULL;
1046         }
1047
1048         dst->sanitized_username = talloc_strdup(dst, src->unix_info->sanitized_username);
1049         if (!dst->sanitized_username) {
1050                 TALLOC_FREE(dst);
1051                 return NULL;
1052         }
1053
1054         return dst;
1055 }
1056
1057 struct auth_session_info *copy_session_info(TALLOC_CTX *mem_ctx,
1058                                              const struct auth_session_info *src)
1059 {
1060         struct auth_session_info *dst;
1061         DATA_BLOB blob;
1062         enum ndr_err_code ndr_err;
1063
1064         ndr_err = ndr_push_struct_blob(
1065                 &blob, talloc_tos(), src,
1066                 (ndr_push_flags_fn_t)ndr_push_auth_session_info);
1067         if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
1068                 DEBUG(0, ("copy_session_info(): ndr_push_auth_session_info failed: "
1069                            "%s\n", ndr_errstr(ndr_err)));
1070                 return NULL;
1071         }
1072
1073         dst = talloc(mem_ctx, struct auth_session_info);
1074         if (dst == NULL) {
1075                 DEBUG(0, ("talloc failed\n"));
1076                 TALLOC_FREE(blob.data);
1077                 return NULL;
1078         }
1079
1080         ndr_err = ndr_pull_struct_blob(
1081                 &blob, dst, dst,
1082                 (ndr_pull_flags_fn_t)ndr_pull_auth_session_info);
1083         TALLOC_FREE(blob.data);
1084
1085         if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
1086                 DEBUG(0, ("copy_session_info(): ndr_pull_auth_session_info failed: "
1087                            "%s\n", ndr_errstr(ndr_err)));
1088                 TALLOC_FREE(dst);
1089                 return NULL;
1090         }
1091
1092         return dst;
1093 }
1094
1095 /*
1096  * Set a new session key. Used in the rpc server where we have to override the
1097  * SMB level session key with SystemLibraryDTC
1098  */
1099
1100 bool session_info_set_session_key(struct auth_session_info *info,
1101                                  DATA_BLOB session_key)
1102 {
1103         TALLOC_FREE(info->session_key.data);
1104
1105         info->session_key = data_blob_talloc(
1106                 info, session_key.data, session_key.length);
1107
1108         return (info->session_key.data != NULL);
1109 }
1110
1111 static struct auth_session_info *guest_info = NULL;
1112
1113 static struct auth_serversupplied_info *guest_server_info = NULL;
1114
1115 bool init_guest_info(void)
1116 {
1117         if (guest_info != NULL)
1118                 return true;
1119
1120         return NT_STATUS_IS_OK(make_new_session_info_guest(&guest_info, &guest_server_info));
1121 }
1122
1123 NTSTATUS make_server_info_guest(TALLOC_CTX *mem_ctx,
1124                                 struct auth_serversupplied_info **server_info)
1125 {
1126         /* This is trickier than it would appear to need to be because
1127          * we are trying to avoid certain costly operations when the
1128          * structure is converted to a 'auth_session_info' again in
1129          * create_local_token() */
1130         *server_info = copy_session_info_serverinfo_guest(mem_ctx, guest_info, guest_server_info);
1131         return (*server_info != NULL) ? NT_STATUS_OK : NT_STATUS_NO_MEMORY;
1132 }
1133
1134 NTSTATUS make_session_info_guest(TALLOC_CTX *mem_ctx,
1135                                 struct auth_session_info **session_info)
1136 {
1137         *session_info = copy_session_info(mem_ctx, guest_info);
1138         return (*session_info != NULL) ? NT_STATUS_OK : NT_STATUS_NO_MEMORY;
1139 }
1140
1141 static struct auth_session_info *system_info = NULL;
1142
1143 NTSTATUS init_system_info(void)
1144 {
1145         if (system_info != NULL)
1146                 return NT_STATUS_OK;
1147
1148         return make_new_session_info_system(NULL, &system_info);
1149 }
1150
1151 NTSTATUS make_session_info_system(TALLOC_CTX *mem_ctx,
1152                                 struct auth_session_info **session_info)
1153 {
1154         if (system_info == NULL) return NT_STATUS_UNSUCCESSFUL;
1155         *session_info = copy_session_info(mem_ctx, system_info);
1156         return (*session_info != NULL) ? NT_STATUS_OK : NT_STATUS_NO_MEMORY;
1157 }
1158
1159 const struct auth_session_info *get_session_info_system(void)
1160 {
1161     return system_info;
1162 }
1163
1164 bool copy_current_user(struct current_user *dst, struct current_user *src)
1165 {
1166         gid_t *groups;
1167         struct security_token *nt_token;
1168
1169         groups = (gid_t *)memdup(src->ut.groups,
1170                                  sizeof(gid_t) * src->ut.ngroups);
1171         if ((src->ut.ngroups != 0) && (groups == NULL)) {
1172                 return false;
1173         }
1174
1175         nt_token = dup_nt_token(NULL, src->nt_user_token);
1176         if (nt_token == NULL) {
1177                 SAFE_FREE(groups);
1178                 return false;
1179         }
1180
1181         dst->conn = src->conn;
1182         dst->vuid = src->vuid;
1183         dst->ut.uid = src->ut.uid;
1184         dst->ut.gid = src->ut.gid;
1185         dst->ut.ngroups = src->ut.ngroups;
1186         dst->ut.groups = groups;
1187         dst->nt_user_token = nt_token;
1188         return true;
1189 }
1190
1191 /***************************************************************************
1192  Purely internal function for make_server_info_info3
1193 ***************************************************************************/
1194
1195 static NTSTATUS check_account(TALLOC_CTX *mem_ctx, const char *domain,
1196                               const char *username, char **found_username,
1197                               struct passwd **pwd,
1198                               bool *username_was_mapped)
1199 {
1200         char *orig_dom_user = NULL;
1201         char *dom_user = NULL;
1202         char *lower_username = NULL;
1203         char *real_username = NULL;
1204         struct passwd *passwd;
1205
1206         lower_username = talloc_strdup(mem_ctx, username);
1207         if (!lower_username) {
1208                 return NT_STATUS_NO_MEMORY;
1209         }
1210         strlower_m( lower_username );
1211
1212         orig_dom_user = talloc_asprintf(mem_ctx,
1213                                 "%s%c%s",
1214                                 domain,
1215                                 *lp_winbind_separator(),
1216                                 lower_username);
1217         if (!orig_dom_user) {
1218                 return NT_STATUS_NO_MEMORY;
1219         }
1220
1221         /* Get the passwd struct.  Try to create the account if necessary. */
1222
1223         *username_was_mapped = map_username(mem_ctx, orig_dom_user, &dom_user);
1224         if (!dom_user) {
1225                 return NT_STATUS_NO_MEMORY;
1226         }
1227
1228         passwd = smb_getpwnam(mem_ctx, dom_user, &real_username, true );
1229         if (!passwd) {
1230                 DEBUG(3, ("Failed to find authenticated user %s via "
1231                           "getpwnam(), denying access.\n", dom_user));
1232                 return NT_STATUS_NO_SUCH_USER;
1233         }
1234
1235         if (!real_username) {
1236                 return NT_STATUS_NO_MEMORY;
1237         }
1238
1239         *pwd = passwd;
1240
1241         /* This is pointless -- there is no support for differing
1242            unix and windows names.  Make sure to always store the 
1243            one we actually looked up and succeeded. Have I mentioned
1244            why I hate the 'winbind use default domain' parameter?   
1245                                          --jerry              */
1246
1247         *found_username = talloc_strdup( mem_ctx, real_username );
1248
1249         return NT_STATUS_OK;
1250 }
1251
1252 /****************************************************************************
1253  Wrapper to allow the getpwnam() call to strip the domain name and 
1254  try again in case a local UNIX user is already there.  Also run through 
1255  the username if we fallback to the username only.
1256  ****************************************************************************/
1257
1258 struct passwd *smb_getpwnam( TALLOC_CTX *mem_ctx, const char *domuser,
1259                              char **p_save_username, bool create )
1260 {
1261         struct passwd *pw = NULL;
1262         char *p = NULL;
1263         char *username = NULL;
1264
1265         /* we only save a copy of the username it has been mangled 
1266            by winbindd use default domain */
1267         *p_save_username = NULL;
1268
1269         /* don't call map_username() here since it has to be done higher 
1270            up the stack so we don't call it multiple times */
1271
1272         username = talloc_strdup(mem_ctx, domuser);
1273         if (!username) {
1274                 return NULL;
1275         }
1276
1277         p = strchr_m( username, *lp_winbind_separator() );
1278
1279         /* code for a DOMAIN\user string */
1280
1281         if ( p ) {
1282                 pw = Get_Pwnam_alloc( mem_ctx, domuser );
1283                 if ( pw ) {
1284                         /* make sure we get the case of the username correct */
1285                         /* work around 'winbind use default domain = yes' */
1286
1287                         if ( !strchr_m( pw->pw_name, *lp_winbind_separator() ) ) {
1288                                 char *domain;
1289
1290                                 /* split the domain and username into 2 strings */
1291                                 *p = '\0';
1292                                 domain = username;
1293
1294                                 *p_save_username = talloc_asprintf(mem_ctx,
1295                                                                 "%s%c%s",
1296                                                                 domain,
1297                                                                 *lp_winbind_separator(),
1298                                                                 pw->pw_name);
1299                                 if (!*p_save_username) {
1300                                         TALLOC_FREE(pw);
1301                                         return NULL;
1302                                 }
1303                         } else {
1304                                 *p_save_username = talloc_strdup(mem_ctx, pw->pw_name);
1305                         }
1306
1307                         /* whew -- done! */
1308                         return pw;
1309                 }
1310
1311                 /* setup for lookup of just the username */
1312                 /* remember that p and username are overlapping memory */
1313
1314                 p++;
1315                 username = talloc_strdup(mem_ctx, p);
1316                 if (!username) {
1317                         return NULL;
1318                 }
1319         }
1320
1321         /* just lookup a plain username */
1322
1323         pw = Get_Pwnam_alloc(mem_ctx, username);
1324
1325         /* Create local user if requested but only if winbindd
1326            is not running.  We need to protect against cases
1327            where winbindd is failing and then prematurely
1328            creating users in /etc/passwd */
1329
1330         if ( !pw && create && !winbind_ping() ) {
1331                 /* Don't add a machine account. */
1332                 if (username[strlen(username)-1] == '$')
1333                         return NULL;
1334
1335                 _smb_create_user(NULL, username, NULL);
1336                 pw = Get_Pwnam_alloc(mem_ctx, username);
1337         }
1338
1339         /* one last check for a valid passwd struct */
1340
1341         if (pw) {
1342                 *p_save_username = talloc_strdup(mem_ctx, pw->pw_name);
1343         }
1344         return pw;
1345 }
1346
1347 /***************************************************************************
1348  Make a server_info struct from the info3 returned by a domain logon 
1349 ***************************************************************************/
1350
1351 NTSTATUS make_server_info_info3(TALLOC_CTX *mem_ctx, 
1352                                 const char *sent_nt_username,
1353                                 const char *domain,
1354                                 struct auth_serversupplied_info **server_info,
1355                                 struct netr_SamInfo3 *info3)
1356 {
1357         static const char zeros[16] = {0, };
1358
1359         NTSTATUS nt_status = NT_STATUS_OK;
1360         char *found_username = NULL;
1361         const char *nt_domain;
1362         const char *nt_username;
1363         bool username_was_mapped;
1364         struct passwd *pwd;
1365         struct auth_serversupplied_info *result;
1366         struct dom_sid *group_sid;
1367         struct netr_SamInfo3 *i3;
1368
1369         /* 
1370            Here is where we should check the list of
1371            trusted domains, and verify that the SID 
1372            matches.
1373         */
1374
1375         nt_username = talloc_strdup(mem_ctx, info3->base.account_name.string);
1376         if (!nt_username) {
1377                 /* If the server didn't give us one, just use the one we sent
1378                  * them */
1379                 nt_username = sent_nt_username;
1380         }
1381
1382         nt_domain = talloc_strdup(mem_ctx, info3->base.domain.string);
1383         if (!nt_domain) {
1384                 /* If the server didn't give us one, just use the one we sent
1385                  * them */
1386                 nt_domain = domain;
1387         }
1388
1389         /* If getpwnam() fails try the add user script (2.2.x behavior).
1390
1391            We use the _unmapped_ username here in an attempt to provide
1392            consistent username mapping behavior between kerberos and NTLM[SSP]
1393            authentication in domain mode security.  I.E. Username mapping
1394            should be applied to the fully qualified username
1395            (e.g. DOMAIN\user) and not just the login name.  Yes this means we
1396            called map_username() unnecessarily in make_user_info_map() but
1397            that is how the current code is designed.  Making the change here
1398            is the least disruptive place.  -- jerry */
1399
1400         /* this call will try to create the user if necessary */
1401
1402         nt_status = check_account(mem_ctx, nt_domain, sent_nt_username,
1403                                      &found_username, &pwd,
1404                                      &username_was_mapped);
1405
1406         if (!NT_STATUS_IS_OK(nt_status)) {
1407                 return nt_status;
1408         }
1409
1410         result = make_server_info(NULL);
1411         if (result == NULL) {
1412                 DEBUG(4, ("make_server_info failed!\n"));
1413                 return NT_STATUS_NO_MEMORY;
1414         }
1415
1416         result->unix_name = talloc_strdup(result, found_username);
1417
1418         result->sanitized_username = sanitize_username(result,
1419                                                        result->unix_name);
1420         if (result->sanitized_username == NULL) {
1421                 TALLOC_FREE(result);
1422                 return NT_STATUS_NO_MEMORY;
1423         }
1424
1425         /* copy in the info3 */
1426         result->info3 = i3 = copy_netr_SamInfo3(result, info3);
1427         if (result->info3 == NULL) {
1428                 TALLOC_FREE(result);
1429                 return NT_STATUS_NO_MEMORY;
1430         }
1431
1432         /* Fill in the unix info we found on the way */
1433         result->utok.uid = pwd->pw_uid;
1434         result->utok.gid = pwd->pw_gid;
1435
1436         /* We can't just trust that the primary group sid sent us is something
1437          * we can really use. Obtain the usable sid, and store the original
1438          * one as an additional group if it had to be replaced */
1439         nt_status = get_primary_group_sid(mem_ctx, found_username,
1440                                           &pwd, &group_sid);
1441         if (!NT_STATUS_IS_OK(nt_status)) {
1442                 TALLOC_FREE(result);
1443                 return nt_status;
1444         }
1445
1446         /* store and check if it is the same we got originally */
1447         sid_peek_rid(group_sid, &i3->base.primary_gid);
1448         if (i3->base.primary_gid != info3->base.primary_gid) {
1449                 uint32_t n = i3->base.groups.count;
1450                 /* not the same, store the original as an additional group */
1451                 i3->base.groups.rids =
1452                         talloc_realloc(i3, i3->base.groups.rids,
1453                                         struct samr_RidWithAttribute, n + 1);
1454                 if (i3->base.groups.rids == NULL) {
1455                         TALLOC_FREE(result);
1456                         return NT_STATUS_NO_MEMORY;
1457                 }
1458                 i3->base.groups.rids[n].rid = info3->base.primary_gid;
1459                 i3->base.groups.rids[n].attributes = SE_GROUP_ENABLED;
1460                 i3->base.groups.count = n + 1;
1461         }
1462
1463         /* ensure we are never given NULL session keys */
1464
1465         if (memcmp(info3->base.key.key, zeros, sizeof(zeros)) == 0) {
1466                 result->session_key = data_blob_null;
1467         } else {
1468                 result->session_key = data_blob_talloc(
1469                         result, info3->base.key.key,
1470                         sizeof(info3->base.key.key));
1471         }
1472
1473         if (memcmp(info3->base.LMSessKey.key, zeros, 8) == 0) {
1474                 result->lm_session_key = data_blob_null;
1475         } else {
1476                 result->lm_session_key = data_blob_talloc(
1477                         result, info3->base.LMSessKey.key,
1478                         sizeof(info3->base.LMSessKey.key));
1479         }
1480
1481         result->nss_token |= username_was_mapped;
1482
1483         result->guest = (info3->base.user_flags & NETLOGON_GUEST);
1484
1485         *server_info = result;
1486
1487         return NT_STATUS_OK;
1488 }
1489
1490 /*****************************************************************************
1491  Make a server_info struct from the wbcAuthUserInfo returned by a domain logon
1492 ******************************************************************************/
1493
1494 NTSTATUS make_server_info_wbcAuthUserInfo(TALLOC_CTX *mem_ctx,
1495                                           const char *sent_nt_username,
1496                                           const char *domain,
1497                                           const struct wbcAuthUserInfo *info,
1498                                           struct auth_serversupplied_info **server_info)
1499 {
1500         struct netr_SamInfo3 *info3;
1501
1502         info3 = wbcAuthUserInfo_to_netr_SamInfo3(mem_ctx, info);
1503         if (!info3) {
1504                 return NT_STATUS_NO_MEMORY;
1505         }
1506
1507         return make_server_info_info3(mem_ctx,
1508                                       sent_nt_username, domain,
1509                                       server_info, info3);
1510 }
1511
1512 /**
1513  * Verify whether or not given domain is trusted.
1514  *
1515  * @param domain_name name of the domain to be verified
1516  * @return true if domain is one of the trusted ones or
1517  *         false if otherwise
1518  **/
1519
1520 bool is_trusted_domain(const char* dom_name)
1521 {
1522         struct dom_sid trustdom_sid;
1523         bool ret;
1524
1525         /* no trusted domains for a standalone server */
1526
1527         if ( lp_server_role() == ROLE_STANDALONE )
1528                 return false;
1529
1530         if (dom_name == NULL || dom_name[0] == '\0') {
1531                 return false;
1532         }
1533
1534         if (strequal(dom_name, get_global_sam_name())) {
1535                 return false;
1536         }
1537
1538         /* if we are a DC, then check for a direct trust relationships */
1539
1540         if ( IS_DC ) {
1541                 become_root();
1542                 DEBUG (5,("is_trusted_domain: Checking for domain trust with "
1543                           "[%s]\n", dom_name ));
1544                 ret = pdb_get_trusteddom_pw(dom_name, NULL, NULL, NULL);
1545                 unbecome_root();
1546                 if (ret)
1547                         return true;
1548         }
1549         else {
1550                 wbcErr result;
1551
1552                 /* If winbind is around, ask it */
1553
1554                 result = wb_is_trusted_domain(dom_name);
1555
1556                 if (result == WBC_ERR_SUCCESS) {
1557                         return true;
1558                 }
1559
1560                 if (result == WBC_ERR_DOMAIN_NOT_FOUND) {
1561                         /* winbind could not find the domain */
1562                         return false;
1563                 }
1564
1565                 /* The only other possible result is that winbind is not up
1566                    and running. We need to update the trustdom_cache
1567                    ourselves */
1568
1569                 update_trustdom_cache();
1570         }
1571
1572         /* now the trustdom cache should be available a DC could still
1573          * have a transitive trust so fall back to the cache of trusted
1574          * domains (like a domain member would use  */
1575
1576         if ( trustdom_cache_fetch(dom_name, &trustdom_sid) ) {
1577                 return true;
1578         }
1579
1580         return false;
1581 }
1582