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