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