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