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