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