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