2fcee89bbbaf8e3118eecb7b51a4f0edb75e62e9
[kai/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         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         security_token_debug(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 = Get_Pwnam_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         TALLOC_FREE(pwd);
765         if (!NT_STATUS_IS_OK(status)) {
766                 return status;
767         }
768
769         (*server_info)->system = true;
770
771         status = add_sid_to_array_unique((*server_info)->ptok->sids,
772                                          &global_sid_System,
773                                          &(*server_info)->ptok->sids,
774                                          &(*server_info)->ptok->num_sids);
775         if (!NT_STATUS_IS_OK(status)) {
776                 TALLOC_FREE((*server_info));
777                 return status;
778         }
779
780         return NT_STATUS_OK;
781 }
782
783 /****************************************************************************
784   Fake a auth_serversupplied_info just from a username
785 ****************************************************************************/
786
787 NTSTATUS make_serverinfo_from_username(TALLOC_CTX *mem_ctx,
788                                        const char *username,
789                                        bool is_guest,
790                                        struct auth_serversupplied_info **presult)
791 {
792         struct auth_serversupplied_info *result;
793         struct passwd *pwd;
794         NTSTATUS status;
795
796         pwd = Get_Pwnam_alloc(talloc_tos(), username);
797         if (pwd == NULL) {
798                 return NT_STATUS_NO_SUCH_USER;
799         }
800
801         status = make_server_info_pw(&result, pwd->pw_name, pwd);
802
803         TALLOC_FREE(pwd);
804
805         if (!NT_STATUS_IS_OK(status)) {
806                 return status;
807         }
808
809         result->nss_token = true;
810         result->guest = is_guest;
811
812         status = create_local_token(result);
813
814         if (!NT_STATUS_IS_OK(status)) {
815                 TALLOC_FREE(result);
816                 return status;
817         }
818
819         *presult = result;
820         return NT_STATUS_OK;
821 }
822
823
824 struct auth_serversupplied_info *copy_serverinfo(TALLOC_CTX *mem_ctx,
825                                                  const struct auth_serversupplied_info *src)
826 {
827         struct auth_serversupplied_info *dst;
828
829         dst = make_server_info(mem_ctx);
830         if (dst == NULL) {
831                 return NULL;
832         }
833
834         dst->guest = src->guest;
835         dst->system = src->system;
836         dst->utok.uid = src->utok.uid;
837         dst->utok.gid = src->utok.gid;
838         dst->utok.ngroups = src->utok.ngroups;
839         if (src->utok.ngroups != 0) {
840                 dst->utok.groups = (gid_t *)TALLOC_MEMDUP(
841                         dst, src->utok.groups,
842                         sizeof(gid_t)*dst->utok.ngroups);
843         } else {
844                 dst->utok.groups = NULL;
845         }
846
847         if (src->ptok) {
848                 dst->ptok = dup_nt_token(dst, src->ptok);
849                 if (!dst->ptok) {
850                         TALLOC_FREE(dst);
851                         return NULL;
852                 }
853         }
854
855         dst->user_session_key = data_blob_talloc( dst, src->user_session_key.data,
856                                                 src->user_session_key.length);
857
858         dst->lm_session_key = data_blob_talloc(dst, src->lm_session_key.data,
859                                                 src->lm_session_key.length);
860
861         dst->info3 = copy_netr_SamInfo3(dst, src->info3);
862         if (!dst->info3) {
863                 TALLOC_FREE(dst);
864                 return NULL;
865         }
866         dst->extra = src->extra;
867
868         dst->pam_handle = NULL;
869         dst->unix_name = talloc_strdup(dst, src->unix_name);
870         if (!dst->unix_name) {
871                 TALLOC_FREE(dst);
872                 return NULL;
873         }
874
875         dst->sanitized_username = talloc_strdup(dst, src->sanitized_username);
876         if (!dst->sanitized_username) {
877                 TALLOC_FREE(dst);
878                 return NULL;
879         }
880
881         return dst;
882 }
883
884 /*
885  * Set a new session key. Used in the rpc server where we have to override the
886  * SMB level session key with SystemLibraryDTC
887  */
888
889 bool server_info_set_session_key(struct auth_serversupplied_info *info,
890                                  DATA_BLOB session_key)
891 {
892         TALLOC_FREE(info->user_session_key.data);
893
894         info->user_session_key = data_blob_talloc(
895                 info, session_key.data, session_key.length);
896
897         return (info->user_session_key.data != NULL);
898 }
899
900 static struct auth_serversupplied_info *guest_info = NULL;
901
902 bool init_guest_info(void)
903 {
904         if (guest_info != NULL)
905                 return True;
906
907         return NT_STATUS_IS_OK(make_new_server_info_guest(&guest_info));
908 }
909
910 NTSTATUS make_server_info_guest(TALLOC_CTX *mem_ctx,
911                                 struct auth_serversupplied_info **server_info)
912 {
913         *server_info = copy_serverinfo(mem_ctx, guest_info);
914         return (*server_info != NULL) ? NT_STATUS_OK : NT_STATUS_NO_MEMORY;
915 }
916
917 static struct auth_serversupplied_info *system_info = NULL;
918
919 bool init_system_info(void)
920 {
921         if (system_info != NULL)
922                 return True;
923
924         return NT_STATUS_IS_OK(make_new_server_info_system(NULL,
925                                                            &system_info));
926 }
927
928 NTSTATUS make_server_info_system(TALLOC_CTX *mem_ctx,
929                                 struct auth_serversupplied_info **server_info)
930 {
931         if (system_info == NULL) return NT_STATUS_UNSUCCESSFUL;
932         *server_info = copy_serverinfo(mem_ctx, system_info);
933         return (*server_info != NULL) ? NT_STATUS_OK : NT_STATUS_NO_MEMORY;
934 }
935
936 const struct auth_serversupplied_info *get_server_info_system(void)
937 {
938     return system_info;
939 }
940
941 bool copy_current_user(struct current_user *dst, struct current_user *src)
942 {
943         gid_t *groups;
944         struct security_token *nt_token;
945
946         groups = (gid_t *)memdup(src->ut.groups,
947                                  sizeof(gid_t) * src->ut.ngroups);
948         if ((src->ut.ngroups != 0) && (groups == NULL)) {
949                 return False;
950         }
951
952         nt_token = dup_nt_token(NULL, src->nt_user_token);
953         if (nt_token == NULL) {
954                 SAFE_FREE(groups);
955                 return False;
956         }
957
958         dst->conn = src->conn;
959         dst->vuid = src->vuid;
960         dst->ut.uid = src->ut.uid;
961         dst->ut.gid = src->ut.gid;
962         dst->ut.ngroups = src->ut.ngroups;
963         dst->ut.groups = groups;
964         dst->nt_user_token = nt_token;
965         return True;
966 }
967
968 /***************************************************************************
969  Purely internal function for make_server_info_info3
970 ***************************************************************************/
971
972 static NTSTATUS check_account(TALLOC_CTX *mem_ctx, const char *domain,
973                               const char *username, char **found_username,
974                               struct passwd **pwd,
975                               bool *username_was_mapped)
976 {
977         fstring dom_user, lower_username;
978         fstring real_username;
979         struct passwd *passwd;
980
981         fstrcpy( lower_username, username );
982         strlower_m( lower_username );
983
984         fstr_sprintf(dom_user, "%s%c%s", domain, *lp_winbind_separator(), 
985                 lower_username);
986
987         /* Get the passwd struct.  Try to create the account if necessary. */
988
989         *username_was_mapped = map_username(dom_user);
990
991         passwd = smb_getpwnam( NULL, dom_user, real_username, True );
992         if (!passwd) {
993                 DEBUG(3, ("Failed to find authenticated user %s via "
994                           "getpwnam(), denying access.\n", dom_user));
995                 return NT_STATUS_NO_SUCH_USER;
996         }
997
998         *pwd = passwd;
999
1000         /* This is pointless -- there is no suport for differing 
1001            unix and windows names.  Make sure to always store the 
1002            one we actually looked up and succeeded. Have I mentioned
1003            why I hate the 'winbind use default domain' parameter?   
1004                                          --jerry              */
1005
1006         *found_username = talloc_strdup( mem_ctx, real_username );
1007
1008         return NT_STATUS_OK;
1009 }
1010
1011 /****************************************************************************
1012  Wrapper to allow the getpwnam() call to strip the domain name and 
1013  try again in case a local UNIX user is already there.  Also run through 
1014  the username if we fallback to the username only.
1015  ****************************************************************************/
1016
1017 struct passwd *smb_getpwnam( TALLOC_CTX *mem_ctx, const char *domuser,
1018                              fstring save_username, bool create )
1019 {
1020         struct passwd *pw = NULL;
1021         char *p;
1022         fstring username;
1023
1024         /* we only save a copy of the username it has been mangled 
1025            by winbindd use default domain */
1026
1027         save_username[0] = '\0';
1028
1029         /* don't call map_username() here since it has to be done higher 
1030            up the stack so we don't call it multiple times */
1031
1032         fstrcpy( username, domuser );
1033
1034         p = strchr_m( username, *lp_winbind_separator() );
1035
1036         /* code for a DOMAIN\user string */
1037
1038         if ( p ) {
1039                 fstring strip_username;
1040
1041                 pw = Get_Pwnam_alloc( mem_ctx, domuser );
1042                 if ( pw ) {     
1043                         /* make sure we get the case of the username correct */
1044                         /* work around 'winbind use default domain = yes' */
1045
1046                         if ( !strchr_m( pw->pw_name, *lp_winbind_separator() ) ) {
1047                                 char *domain;
1048
1049                                 /* split the domain and username into 2 strings */
1050                                 *p = '\0';
1051                                 domain = username;
1052
1053                                 fstr_sprintf(save_username, "%s%c%s", domain, *lp_winbind_separator(), pw->pw_name);
1054                         }
1055                         else
1056                                 fstrcpy( save_username, pw->pw_name );
1057
1058                         /* whew -- done! */             
1059                         return pw;
1060                 }
1061
1062                 /* setup for lookup of just the username */
1063                 /* remember that p and username are overlapping memory */
1064
1065                 p++;
1066                 fstrcpy( strip_username, p );
1067                 fstrcpy( username, strip_username );
1068         }
1069
1070         /* just lookup a plain username */
1071
1072         pw = Get_Pwnam_alloc(mem_ctx, username);
1073
1074         /* Create local user if requested but only if winbindd
1075            is not running.  We need to protect against cases
1076            where winbindd is failing and then prematurely
1077            creating users in /etc/passwd */
1078
1079         if ( !pw && create && !winbind_ping() ) {
1080                 /* Don't add a machine account. */
1081                 if (username[strlen(username)-1] == '$')
1082                         return NULL;
1083
1084                 _smb_create_user(NULL, username, NULL);
1085                 pw = Get_Pwnam_alloc(mem_ctx, username);
1086         }
1087
1088         /* one last check for a valid passwd struct */
1089
1090         if ( pw )
1091                 fstrcpy( save_username, pw->pw_name );
1092
1093         return pw;
1094 }
1095
1096 /***************************************************************************
1097  Make a server_info struct from the info3 returned by a domain logon 
1098 ***************************************************************************/
1099
1100 NTSTATUS make_server_info_info3(TALLOC_CTX *mem_ctx, 
1101                                 const char *sent_nt_username,
1102                                 const char *domain,
1103                                 struct auth_serversupplied_info **server_info,
1104                                 struct netr_SamInfo3 *info3)
1105 {
1106         static const char zeros[16] = {0, };
1107
1108         NTSTATUS nt_status = NT_STATUS_OK;
1109         char *found_username = NULL;
1110         const char *nt_domain;
1111         const char *nt_username;
1112         bool username_was_mapped;
1113         struct passwd *pwd;
1114         struct auth_serversupplied_info *result;
1115         struct dom_sid *group_sid;
1116         struct netr_SamInfo3 *i3;
1117
1118         /* 
1119            Here is where we should check the list of
1120            trusted domains, and verify that the SID 
1121            matches.
1122         */
1123
1124         nt_username = talloc_strdup(mem_ctx, info3->base.account_name.string);
1125         if (!nt_username) {
1126                 /* If the server didn't give us one, just use the one we sent
1127                  * them */
1128                 nt_username = sent_nt_username;
1129         }
1130
1131         nt_domain = talloc_strdup(mem_ctx, info3->base.domain.string);
1132         if (!nt_domain) {
1133                 /* If the server didn't give us one, just use the one we sent
1134                  * them */
1135                 nt_domain = domain;
1136         }
1137
1138         /* If getpwnam() fails try the add user script (2.2.x behavior).
1139
1140            We use the _unmapped_ username here in an attempt to provide
1141            consistent username mapping behavior between kerberos and NTLM[SSP]
1142            authentication in domain mode security.  I.E. Username mapping
1143            should be applied to the fully qualified username
1144            (e.g. DOMAIN\user) and not just the login name.  Yes this means we
1145            called map_username() unnecessarily in make_user_info_map() but
1146            that is how the current code is designed.  Making the change here
1147            is the least disruptive place.  -- jerry */
1148
1149         /* this call will try to create the user if necessary */
1150
1151         nt_status = check_account(mem_ctx, nt_domain, sent_nt_username,
1152                                      &found_username, &pwd,
1153                                      &username_was_mapped);
1154
1155         if (!NT_STATUS_IS_OK(nt_status)) {
1156                 return nt_status;
1157         }
1158
1159         result = make_server_info(NULL);
1160         if (result == NULL) {
1161                 DEBUG(4, ("make_server_info failed!\n"));
1162                 return NT_STATUS_NO_MEMORY;
1163         }
1164
1165         result->unix_name = talloc_strdup(result, found_username);
1166
1167         result->sanitized_username = sanitize_username(result,
1168                                                        result->unix_name);
1169         if (result->sanitized_username == NULL) {
1170                 TALLOC_FREE(result);
1171                 return NT_STATUS_NO_MEMORY;
1172         }
1173
1174         /* copy in the info3 */
1175         result->info3 = i3 = copy_netr_SamInfo3(result, info3);
1176         if (result->info3 == NULL) {
1177                 TALLOC_FREE(result);
1178                 return NT_STATUS_NO_MEMORY;
1179         }
1180
1181         /* Fill in the unix info we found on the way */
1182         result->utok.uid = pwd->pw_uid;
1183         result->utok.gid = pwd->pw_gid;
1184
1185         /* We can't just trust that the primary group sid sent us is something
1186          * we can really use. Obtain the useable sid, and store the original
1187          * one as an additional group if it had to be replaced */
1188         nt_status = get_primary_group_sid(mem_ctx, found_username,
1189                                           &pwd, &group_sid);
1190         if (!NT_STATUS_IS_OK(nt_status)) {
1191                 TALLOC_FREE(result);
1192                 return nt_status;
1193         }
1194
1195         /* store and check if it is the same we got originally */
1196         sid_peek_rid(group_sid, &i3->base.primary_gid);
1197         if (i3->base.primary_gid != info3->base.primary_gid) {
1198                 uint32_t n = i3->base.groups.count;
1199                 /* not the same, store the original as an additional group */
1200                 i3->base.groups.rids =
1201                         talloc_realloc(i3, i3->base.groups.rids,
1202                                         struct samr_RidWithAttribute, n + 1);
1203                 if (i3->base.groups.rids == NULL) {
1204                         TALLOC_FREE(result);
1205                         return NT_STATUS_NO_MEMORY;
1206                 }
1207                 i3->base.groups.rids[n].rid = info3->base.primary_gid;
1208                 i3->base.groups.rids[n].attributes = SE_GROUP_ENABLED;
1209                 i3->base.groups.count = n + 1;
1210         }
1211
1212         /* ensure we are never given NULL session keys */
1213
1214         if (memcmp(info3->base.key.key, zeros, sizeof(zeros)) == 0) {
1215                 result->user_session_key = data_blob_null;
1216         } else {
1217                 result->user_session_key = data_blob_talloc(
1218                         result, info3->base.key.key,
1219                         sizeof(info3->base.key.key));
1220         }
1221
1222         if (memcmp(info3->base.LMSessKey.key, zeros, 8) == 0) {
1223                 result->lm_session_key = data_blob_null;
1224         } else {
1225                 result->lm_session_key = data_blob_talloc(
1226                         result, info3->base.LMSessKey.key,
1227                         sizeof(info3->base.LMSessKey.key));
1228         }
1229
1230         result->nss_token |= username_was_mapped;
1231
1232         *server_info = result;
1233
1234         return NT_STATUS_OK;
1235 }
1236
1237 /*****************************************************************************
1238  Make a server_info struct from the wbcAuthUserInfo returned by a domain logon
1239 ******************************************************************************/
1240
1241 NTSTATUS make_server_info_wbcAuthUserInfo(TALLOC_CTX *mem_ctx,
1242                                           const char *sent_nt_username,
1243                                           const char *domain,
1244                                           const struct wbcAuthUserInfo *info,
1245                                           struct auth_serversupplied_info **server_info)
1246 {
1247         struct netr_SamInfo3 *info3;
1248
1249         info3 = wbcAuthUserInfo_to_netr_SamInfo3(mem_ctx, info);
1250         if (!info3) {
1251                 return NT_STATUS_NO_MEMORY;
1252         }
1253
1254         return make_server_info_info3(mem_ctx,
1255                                       sent_nt_username, domain,
1256                                       server_info, info3);
1257 }
1258
1259 /**
1260  * Verify whether or not given domain is trusted.
1261  *
1262  * @param domain_name name of the domain to be verified
1263  * @return true if domain is one of the trusted ones or
1264  *         false if otherwise
1265  **/
1266
1267 bool is_trusted_domain(const char* dom_name)
1268 {
1269         struct dom_sid trustdom_sid;
1270         bool ret;
1271
1272         /* no trusted domains for a standalone server */
1273
1274         if ( lp_server_role() == ROLE_STANDALONE )
1275                 return False;
1276
1277         if (dom_name == NULL || dom_name[0] == '\0') {
1278                 return false;
1279         }
1280
1281         if (strequal(dom_name, get_global_sam_name())) {
1282                 return false;
1283         }
1284
1285         /* if we are a DC, then check for a direct trust relationships */
1286
1287         if ( IS_DC ) {
1288                 become_root();
1289                 DEBUG (5,("is_trusted_domain: Checking for domain trust with "
1290                           "[%s]\n", dom_name ));
1291                 ret = pdb_get_trusteddom_pw(dom_name, NULL, NULL, NULL);
1292                 unbecome_root();
1293                 if (ret)
1294                         return True;
1295         }
1296         else {
1297                 wbcErr result;
1298
1299                 /* If winbind is around, ask it */
1300
1301                 result = wb_is_trusted_domain(dom_name);
1302
1303                 if (result == WBC_ERR_SUCCESS) {
1304                         return True;
1305                 }
1306
1307                 if (result == WBC_ERR_DOMAIN_NOT_FOUND) {
1308                         /* winbind could not find the domain */
1309                         return False;
1310                 }
1311
1312                 /* The only other possible result is that winbind is not up
1313                    and running. We need to update the trustdom_cache
1314                    ourselves */
1315
1316                 update_trustdom_cache();
1317         }
1318
1319         /* now the trustdom cache should be available a DC could still
1320          * have a transitive trust so fall back to the cache of trusted
1321          * domains (like a domain member would use  */
1322
1323         if ( trustdom_cache_fetch(dom_name, &trustdom_sid) ) {
1324                 return True;
1325         }
1326
1327         return False;
1328 }
1329