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