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