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