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