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