r22135: Check in most of Michael Adam's net conf utility. A good share of this patch
[ira/wip.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 2 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, write to the Free Software
22    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
23 */
24
25 #include "includes.h"
26
27 #undef DBGC_CLASS
28 #define DBGC_CLASS DBGC_AUTH
29
30 /****************************************************************************
31  Create a UNIX user on demand.
32 ****************************************************************************/
33
34 static int smb_create_user(const char *domain, const char *unix_username, const char *homedir)
35 {
36         pstring add_script;
37         int ret;
38
39         pstrcpy(add_script, lp_adduser_script());
40         if (! *add_script)
41                 return -1;
42         all_string_sub(add_script, "%u", unix_username, sizeof(pstring));
43         if (domain)
44                 all_string_sub(add_script, "%D", domain, sizeof(pstring));
45         if (homedir)
46                 all_string_sub(add_script, "%H", homedir, sizeof(pstring));
47         ret = smbrun(add_script,NULL);
48         flush_pwnam_cache();
49         DEBUG(ret ? 0 : 3,("smb_create_user: Running the command `%s' gave %d\n",add_script,ret));
50         return ret;
51 }
52
53 /****************************************************************************
54  Create an auth_usersupplied_data structure
55 ****************************************************************************/
56
57 static NTSTATUS make_user_info(auth_usersupplied_info **user_info, 
58                                const char *smb_name, 
59                                const char *internal_username,
60                                const char *client_domain, 
61                                const char *domain,
62                                const char *wksta_name, 
63                                DATA_BLOB *lm_pwd, DATA_BLOB *nt_pwd,
64                                DATA_BLOB *lm_interactive_pwd, DATA_BLOB *nt_interactive_pwd,
65                                DATA_BLOB *plaintext, 
66                                BOOL encrypted)
67 {
68
69         DEBUG(5,("attempting to make a user_info for %s (%s)\n", internal_username, smb_name));
70
71         *user_info = SMB_MALLOC_P(auth_usersupplied_info);
72         if (*user_info == NULL) {
73                 DEBUG(0,("malloc failed for user_info (size %lu)\n", (unsigned long)sizeof(*user_info)));
74                 return NT_STATUS_NO_MEMORY;
75         }
76
77         ZERO_STRUCTP(*user_info);
78
79         DEBUG(5,("making strings for %s's user_info struct\n", internal_username));
80
81         (*user_info)->smb_name = SMB_STRDUP(smb_name);
82         if ((*user_info)->smb_name == NULL) { 
83                 free_user_info(user_info);
84                 return NT_STATUS_NO_MEMORY;
85         }
86         
87         (*user_info)->internal_username = SMB_STRDUP(internal_username);
88         if ((*user_info)->internal_username == NULL) { 
89                 free_user_info(user_info);
90                 return NT_STATUS_NO_MEMORY;
91         }
92
93         (*user_info)->domain = SMB_STRDUP(domain);
94         if ((*user_info)->domain == NULL) { 
95                 free_user_info(user_info);
96                 return NT_STATUS_NO_MEMORY;
97         }
98
99         (*user_info)->client_domain = SMB_STRDUP(client_domain);
100         if ((*user_info)->client_domain == NULL) { 
101                 free_user_info(user_info);
102                 return NT_STATUS_NO_MEMORY;
103         }
104
105         (*user_info)->wksta_name = SMB_STRDUP(wksta_name);
106         if ((*user_info)->wksta_name == NULL) { 
107                 free_user_info(user_info);
108                 return NT_STATUS_NO_MEMORY;
109         }
110
111         DEBUG(5,("making blobs for %s's user_info struct\n", internal_username));
112
113         if (lm_pwd)
114                 (*user_info)->lm_resp = data_blob(lm_pwd->data, lm_pwd->length);
115         if (nt_pwd)
116                 (*user_info)->nt_resp = data_blob(nt_pwd->data, nt_pwd->length);
117         if (lm_interactive_pwd)
118                 (*user_info)->lm_interactive_pwd = data_blob(lm_interactive_pwd->data, lm_interactive_pwd->length);
119         if (nt_interactive_pwd)
120                 (*user_info)->nt_interactive_pwd = data_blob(nt_interactive_pwd->data, nt_interactive_pwd->length);
121
122         if (plaintext)
123                 (*user_info)->plaintext_password = data_blob(plaintext->data, plaintext->length);
124
125         (*user_info)->encrypted = encrypted;
126
127         (*user_info)->logon_parameters = 0;
128
129         DEBUG(10,("made an %sencrypted user_info for %s (%s)\n", encrypted ? "":"un" , internal_username, smb_name));
130
131         return NT_STATUS_OK;
132 }
133
134 /****************************************************************************
135  Create an auth_usersupplied_data structure after appropriate mapping.
136 ****************************************************************************/
137
138 NTSTATUS make_user_info_map(auth_usersupplied_info **user_info, 
139                             const char *smb_name, 
140                             const char *client_domain, 
141                             const char *wksta_name, 
142                             DATA_BLOB *lm_pwd, DATA_BLOB *nt_pwd,
143                             DATA_BLOB *lm_interactive_pwd, DATA_BLOB *nt_interactive_pwd,
144                             DATA_BLOB *plaintext, 
145                             BOOL encrypted)
146 {
147         const char *domain;
148         NTSTATUS result;
149         BOOL was_mapped;
150         fstring internal_username;
151         fstrcpy(internal_username, smb_name);
152         was_mapped = map_username(internal_username); 
153         
154         DEBUG(5, ("make_user_info_map: Mapping user [%s]\\[%s] from workstation [%s]\n",
155               client_domain, smb_name, wksta_name));
156         
157         /* don't allow "" as a domain, fixes a Win9X bug 
158            where it doens't supply a domain for logon script
159            'net use' commands.                                 */
160
161         if ( *client_domain )
162                 domain = client_domain;
163         else
164                 domain = lp_workgroup();
165
166         /* do what win2k does.  Always map unknown domains to our own
167            and let the "passdb backend" handle unknown users. */
168
169         if ( !is_trusted_domain(domain) && !strequal(domain, get_global_sam_name()) ) 
170                 domain = my_sam_name();
171         
172         /* we know that it is a trusted domain (and we are allowing them) or it is our domain */
173         
174         result = make_user_info(user_info, smb_name, internal_username, 
175                               client_domain, domain, wksta_name, 
176                               lm_pwd, nt_pwd,
177                               lm_interactive_pwd, nt_interactive_pwd,
178                               plaintext, encrypted);
179         if (NT_STATUS_IS_OK(result)) {
180                 (*user_info)->was_mapped = was_mapped;
181         }
182         return result;
183 }
184
185 /****************************************************************************
186  Create an auth_usersupplied_data, making the DATA_BLOBs here. 
187  Decrypt and encrypt the passwords.
188 ****************************************************************************/
189
190 BOOL make_user_info_netlogon_network(auth_usersupplied_info **user_info, 
191                                      const char *smb_name, 
192                                      const char *client_domain, 
193                                      const char *wksta_name, 
194                                      uint32 logon_parameters,
195                                      const uchar *lm_network_pwd,
196                                      int lm_pwd_len,
197                                      const uchar *nt_network_pwd,
198                                      int nt_pwd_len)
199 {
200         BOOL ret;
201         NTSTATUS status;
202         DATA_BLOB lm_blob = data_blob(lm_network_pwd, lm_pwd_len);
203         DATA_BLOB nt_blob = data_blob(nt_network_pwd, nt_pwd_len);
204
205         status = make_user_info_map(user_info,
206                                     smb_name, client_domain, 
207                                     wksta_name, 
208                                     lm_pwd_len ? &lm_blob : NULL, 
209                                     nt_pwd_len ? &nt_blob : NULL,
210                                     NULL, NULL, NULL,
211                                     True);
212
213         if (NT_STATUS_IS_OK(status)) {
214                 (*user_info)->logon_parameters = logon_parameters;
215         }
216         ret = NT_STATUS_IS_OK(status) ? True : False;
217
218         data_blob_free(&lm_blob);
219         data_blob_free(&nt_blob);
220         return ret;
221 }
222
223 /****************************************************************************
224  Create an auth_usersupplied_data, making the DATA_BLOBs here. 
225  Decrypt and encrypt the passwords.
226 ****************************************************************************/
227
228 BOOL make_user_info_netlogon_interactive(auth_usersupplied_info **user_info, 
229                                          const char *smb_name, 
230                                          const char *client_domain, 
231                                          const char *wksta_name, 
232                                          uint32 logon_parameters,
233                                          const uchar chal[8], 
234                                          const uchar lm_interactive_pwd[16], 
235                                          const uchar nt_interactive_pwd[16], 
236                                          const uchar *dc_sess_key)
237 {
238         unsigned char lm_pwd[16];
239         unsigned char nt_pwd[16];
240         unsigned char local_lm_response[24];
241         unsigned char local_nt_response[24];
242         unsigned char key[16];
243         
244         ZERO_STRUCT(key);
245         memcpy(key, dc_sess_key, 8);
246         
247         if (lm_interactive_pwd)
248                 memcpy(lm_pwd, lm_interactive_pwd, sizeof(lm_pwd));
249
250         if (nt_interactive_pwd)
251                 memcpy(nt_pwd, nt_interactive_pwd, sizeof(nt_pwd));
252         
253 #ifdef DEBUG_PASSWORD
254         DEBUG(100,("key:"));
255         dump_data(100, key, sizeof(key));
256         
257         DEBUG(100,("lm owf password:"));
258         dump_data(100, lm_pwd, sizeof(lm_pwd));
259         
260         DEBUG(100,("nt owf password:"));
261         dump_data(100, nt_pwd, sizeof(nt_pwd));
262 #endif
263         
264         if (lm_interactive_pwd)
265                 SamOEMhash(lm_pwd, key, sizeof(lm_pwd));
266         
267         if (nt_interactive_pwd)
268                 SamOEMhash(nt_pwd, key, sizeof(nt_pwd));
269         
270 #ifdef DEBUG_PASSWORD
271         DEBUG(100,("decrypt of lm owf password:"));
272         dump_data(100, lm_pwd, sizeof(lm_pwd));
273         
274         DEBUG(100,("decrypt of nt owf password:"));
275         dump_data(100, nt_pwd, sizeof(nt_pwd));
276 #endif
277         
278         if (lm_interactive_pwd)
279                 SMBOWFencrypt(lm_pwd, chal,
280                               local_lm_response);
281
282         if (nt_interactive_pwd)
283                 SMBOWFencrypt(nt_pwd, chal,
284                               local_nt_response);
285         
286         /* Password info paranoia */
287         ZERO_STRUCT(key);
288
289         {
290                 BOOL ret;
291                 NTSTATUS nt_status;
292                 DATA_BLOB local_lm_blob;
293                 DATA_BLOB local_nt_blob;
294
295                 DATA_BLOB lm_interactive_blob;
296                 DATA_BLOB nt_interactive_blob;
297                 
298                 if (lm_interactive_pwd) {
299                         local_lm_blob = data_blob(local_lm_response,
300                                                   sizeof(local_lm_response));
301                         lm_interactive_blob = data_blob(lm_pwd,
302                                                         sizeof(lm_pwd));
303                         ZERO_STRUCT(lm_pwd);
304                 }
305                 
306                 if (nt_interactive_pwd) {
307                         local_nt_blob = data_blob(local_nt_response,
308                                                   sizeof(local_nt_response));
309                         nt_interactive_blob = data_blob(nt_pwd,
310                                                         sizeof(nt_pwd));
311                         ZERO_STRUCT(nt_pwd);
312                 }
313
314                 nt_status = make_user_info_map(
315                         user_info, 
316                         smb_name, client_domain, wksta_name, 
317                         lm_interactive_pwd ? &local_lm_blob : NULL,
318                         nt_interactive_pwd ? &local_nt_blob : NULL,
319                         lm_interactive_pwd ? &lm_interactive_blob : NULL,
320                         nt_interactive_pwd ? &nt_interactive_blob : NULL,
321                         NULL, True);
322
323                 if (NT_STATUS_IS_OK(nt_status)) {
324                         (*user_info)->logon_parameters = logon_parameters;
325                 }
326
327                 ret = NT_STATUS_IS_OK(nt_status) ? True : False;
328                 data_blob_free(&local_lm_blob);
329                 data_blob_free(&local_nt_blob);
330                 data_blob_free(&lm_interactive_blob);
331                 data_blob_free(&nt_interactive_blob);
332                 return ret;
333         }
334 }
335
336
337 /****************************************************************************
338  Create an auth_usersupplied_data structure
339 ****************************************************************************/
340
341 BOOL make_user_info_for_reply(auth_usersupplied_info **user_info, 
342                               const char *smb_name, 
343                               const char *client_domain,
344                               const uint8 chal[8],
345                               DATA_BLOB plaintext_password)
346 {
347
348         DATA_BLOB local_lm_blob;
349         DATA_BLOB local_nt_blob;
350         NTSTATUS ret = NT_STATUS_UNSUCCESSFUL;
351                         
352         /*
353          * Not encrypted - do so.
354          */
355         
356         DEBUG(5,("make_user_info_for_reply: User passwords not in encrypted "
357                  "format.\n"));
358         
359         if (plaintext_password.data) {
360                 unsigned char local_lm_response[24];
361                 
362 #ifdef DEBUG_PASSWORD
363                 DEBUG(10,("Unencrypted password (len %d):\n",
364                           (int)plaintext_password.length));
365                 dump_data(100, plaintext_password.data,
366                           plaintext_password.length);
367 #endif
368
369                 SMBencrypt( (const char *)plaintext_password.data,
370                             (const uchar*)chal, local_lm_response);
371                 local_lm_blob = data_blob(local_lm_response, 24);
372                 
373                 /* We can't do an NT hash here, as the password needs to be
374                    case insensitive */
375                 local_nt_blob = data_blob(NULL, 0); 
376                 
377         } else {
378                 local_lm_blob = data_blob(NULL, 0); 
379                 local_nt_blob = data_blob(NULL, 0); 
380         }
381         
382         ret = make_user_info_map(
383                 user_info, smb_name, client_domain, 
384                 get_remote_machine_name(),
385                 local_lm_blob.data ? &local_lm_blob : NULL,
386                 local_nt_blob.data ? &local_nt_blob : NULL,
387                 NULL, NULL,
388                 plaintext_password.data ? &plaintext_password : NULL, 
389                 False);
390         
391         data_blob_free(&local_lm_blob);
392         return NT_STATUS_IS_OK(ret) ? True : False;
393 }
394
395 /****************************************************************************
396  Create an auth_usersupplied_data structure
397 ****************************************************************************/
398
399 NTSTATUS make_user_info_for_reply_enc(auth_usersupplied_info **user_info, 
400                                       const char *smb_name,
401                                       const char *client_domain, 
402                                       DATA_BLOB lm_resp, DATA_BLOB nt_resp)
403 {
404         return make_user_info_map(user_info, smb_name, 
405                                   client_domain, 
406                                   get_remote_machine_name(), 
407                                   lm_resp.data ? &lm_resp : NULL, 
408                                   nt_resp.data ? &nt_resp : NULL, 
409                                   NULL, NULL, NULL,
410                                   True);
411 }
412
413 /****************************************************************************
414  Create a guest user_info blob, for anonymous authenticaion.
415 ****************************************************************************/
416
417 BOOL make_user_info_guest(auth_usersupplied_info **user_info) 
418 {
419         NTSTATUS nt_status;
420
421         nt_status = make_user_info(user_info, 
422                                    "","", 
423                                    "","", 
424                                    "", 
425                                    NULL, NULL, 
426                                    NULL, NULL, 
427                                    NULL,
428                                    True);
429                               
430         return NT_STATUS_IS_OK(nt_status) ? True : False;
431 }
432
433 /****************************************************************************
434  prints a NT_USER_TOKEN to debug output.
435 ****************************************************************************/
436
437 void debug_nt_user_token(int dbg_class, int dbg_lev, NT_USER_TOKEN *token)
438 {
439         size_t     i;
440         
441         if (!token) {
442                 DEBUGC(dbg_class, dbg_lev, ("NT user token: (NULL)\n"));
443                 return;
444         }
445         
446         DEBUGC(dbg_class, dbg_lev,
447                ("NT user token of user %s\n",
448                 sid_string_static(&token->user_sids[0]) ));
449         DEBUGADDC(dbg_class, dbg_lev,
450                   ("contains %lu SIDs\n", (unsigned long)token->num_sids));
451         for (i = 0; i < token->num_sids; i++)
452                 DEBUGADDC(dbg_class, dbg_lev,
453                           ("SID[%3lu]: %s\n", (unsigned long)i, 
454                            sid_string_static(&token->user_sids[i])));
455
456         dump_se_priv( dbg_class, dbg_lev, &token->privileges );
457 }
458
459 /****************************************************************************
460  prints a UNIX 'token' to debug output.
461 ****************************************************************************/
462
463 void debug_unix_user_token(int dbg_class, int dbg_lev, uid_t uid, gid_t gid,
464                            int n_groups, gid_t *groups)
465 {
466         int     i;
467         DEBUGC(dbg_class, dbg_lev,
468                ("UNIX token of user %ld\n", (long int)uid));
469
470         DEBUGADDC(dbg_class, dbg_lev,
471                   ("Primary group is %ld and contains %i supplementary "
472                    "groups\n", (long int)gid, n_groups));
473         for (i = 0; i < n_groups; i++)
474                 DEBUGADDC(dbg_class, dbg_lev, ("Group[%3i]: %ld\n", i, 
475                         (long int)groups[i]));
476 }
477
478 static int server_info_dtor(auth_serversupplied_info *server_info)
479 {
480         TALLOC_FREE(server_info->sam_account);
481         ZERO_STRUCTP(server_info);
482         return 0;
483 }
484
485 /***************************************************************************
486  Make a server_info struct. Free with TALLOC_FREE().
487 ***************************************************************************/
488
489 static auth_serversupplied_info *make_server_info(TALLOC_CTX *mem_ctx)
490 {
491         struct auth_serversupplied_info *result;
492
493         result = TALLOC_ZERO_P(mem_ctx, auth_serversupplied_info);
494         if (result == NULL) {
495                 DEBUG(0, ("talloc failed\n"));
496                 return NULL;
497         }
498
499         talloc_set_destructor(result, server_info_dtor);
500
501         /* Initialise the uid and gid values to something non-zero
502            which may save us from giving away root access if there
503            is a bug in allocating these fields. */
504
505         result->uid = -1;
506         result->gid = -1;
507         return result;
508 }
509
510 /***************************************************************************
511  Make (and fill) a user_info struct from a struct samu
512 ***************************************************************************/
513
514 NTSTATUS make_server_info_sam(auth_serversupplied_info **server_info, 
515                               struct samu *sampass)
516 {
517         NTSTATUS status;
518         struct passwd *pwd;
519         gid_t *gids;
520         auth_serversupplied_info *result;
521         int i;
522         size_t num_gids;
523         DOM_SID unix_group_sid;
524         
525
526         if ( !(result = make_server_info(NULL)) ) {
527                 return NT_STATUS_NO_MEMORY;
528         }
529
530         if ( !(pwd = getpwnam_alloc(result, pdb_get_username(sampass))) ) {
531                 DEBUG(1, ("User %s in passdb, but getpwnam() fails!\n",
532                           pdb_get_username(sampass)));
533                 TALLOC_FREE(result);
534                 return NT_STATUS_NO_SUCH_USER;
535         }
536
537         result->sam_account = sampass;
538         /* Ensure thaat the sampass will be freed with the result */
539         talloc_steal(result, sampass);
540         result->unix_name = pwd->pw_name;
541         /* Ensure that we keep pwd->pw_name, because we will free pwd below */
542         talloc_steal(result, pwd->pw_name);
543         result->gid = pwd->pw_gid;
544         result->uid = pwd->pw_uid;
545         
546         TALLOC_FREE(pwd);
547
548         status = pdb_enum_group_memberships(result, sampass,
549                                             &result->sids, &gids,
550                                             &result->num_sids);
551
552         if (!NT_STATUS_IS_OK(status)) {
553                 DEBUG(10, ("pdb_enum_group_memberships failed: %s\n",
554                            nt_errstr(status)));
555                 result->sam_account = NULL; /* Don't free on error exit. */
556                 TALLOC_FREE(result);
557                 return status;
558         }
559         
560         /* Add the "Unix Group" SID for each gid to catch mapped groups
561            and their Unix equivalent.  This is to solve the backwards 
562            compatibility problem of 'valid users = +ntadmin' where 
563            ntadmin has been paired with "Domain Admins" in the group 
564            mapping table.  Otherwise smb.conf would need to be changed
565            to 'valid user = "Domain Admins"'.  --jerry */
566         
567         num_gids = result->num_sids;
568         for ( i=0; i<num_gids; i++ ) {
569                 if ( !gid_to_unix_groups_sid( gids[i], &unix_group_sid ) ) {
570                         DEBUG(1,("make_server_info_sam: Failed to create SID "
571                                 "for gid %d!\n", gids[i]));
572                         continue;
573                 }
574                 if (!add_sid_to_array_unique( result, &unix_group_sid,
575                                 &result->sids, &result->num_sids )) {
576                         result->sam_account = NULL; /* Don't free on error exit. */
577                         TALLOC_FREE(result);
578                         return NT_STATUS_NO_MEMORY;
579                 }
580         }
581
582         /* For now we throw away the gids and convert via sid_to_gid
583          * later. This needs fixing, but I'd like to get the code straight and
584          * simple first. */
585          
586         TALLOC_FREE(gids);
587
588         DEBUG(5,("make_server_info_sam: made server info for user %s -> %s\n",
589                  pdb_get_username(sampass), result->unix_name));
590
591         *server_info = result;
592
593         return NT_STATUS_OK;
594 }
595
596 static NTSTATUS log_nt_token(TALLOC_CTX *tmp_ctx, NT_USER_TOKEN *token)
597 {
598         char *command;
599         char *group_sidstr;
600         size_t i;
601
602         if ((lp_log_nt_token_command() == NULL) ||
603             (strlen(lp_log_nt_token_command()) == 0)) {
604                 return NT_STATUS_OK;
605         }
606
607         group_sidstr = talloc_strdup(tmp_ctx, "");
608         for (i=1; i<token->num_sids; i++) {
609                 group_sidstr = talloc_asprintf(
610                         tmp_ctx, "%s %s", group_sidstr,
611                         sid_string_static(&token->user_sids[i]));
612         }
613
614         command = talloc_string_sub(
615                 tmp_ctx, lp_log_nt_token_command(),
616                 "%s", sid_string_static(&token->user_sids[0]));
617         command = talloc_string_sub(tmp_ctx, command, "%t", group_sidstr);
618
619         if (command == NULL) {
620                 return NT_STATUS_NO_MEMORY;
621         }
622
623         DEBUG(8, ("running command: [%s]\n", command));
624         if (smbrun(command, NULL) != 0) {
625                 DEBUG(0, ("Could not log NT token\n"));
626                 return NT_STATUS_ACCESS_DENIED;
627         }
628
629         return NT_STATUS_OK;
630 }
631
632 /*
633  * Create the token to use from server_info->sam_account and
634  * server_info->sids (the info3/sam groups). Find the unix gids.
635  */
636
637 NTSTATUS create_local_token(auth_serversupplied_info *server_info)
638 {
639         TALLOC_CTX *mem_ctx;
640         struct id_map *ids;
641         NTSTATUS status;
642         BOOL wb = True;
643         size_t i;
644         
645
646         mem_ctx = talloc_new(NULL);
647         if (mem_ctx == NULL) {
648                 DEBUG(0, ("talloc_new failed\n"));
649                 return NT_STATUS_NO_MEMORY;
650         }
651
652         /*
653          * If winbind is not around, we can not make much use of the SIDs the
654          * domain controller provided us with. Likewise if the user name was
655          * mapped to some local unix user.
656          */
657
658         if (((lp_server_role() == ROLE_DOMAIN_MEMBER) && !winbind_ping()) ||
659             (server_info->was_mapped)) {
660                 status = create_token_from_username(server_info,
661                                                     server_info->unix_name,
662                                                     server_info->guest,
663                                                     &server_info->uid,
664                                                     &server_info->gid,
665                                                     &server_info->unix_name,
666                                                     &server_info->ptok);
667                 
668         } else {
669                 server_info->ptok = create_local_nt_token(
670                         server_info,
671                         pdb_get_user_sid(server_info->sam_account),
672                         server_info->guest,
673                         server_info->num_sids, server_info->sids);
674                 status = server_info->ptok ?
675                         NT_STATUS_OK : NT_STATUS_NO_SUCH_USER;
676         }
677
678         if (!NT_STATUS_IS_OK(status)) {
679                 TALLOC_FREE(mem_ctx);
680                 return status;
681         }
682         
683         /* Convert the SIDs to gids. */
684
685         server_info->n_groups = 0;
686         server_info->groups = NULL;
687
688         /* Start at index 1, where the groups start. */
689         ids = talloc_zero_array(mem_ctx, struct id_map, server_info->ptok->num_sids);
690         for (i = 0; i < server_info->ptok->num_sids-1; i++) {
691                 ids[i].sid = &server_info->ptok->user_sids[i + 1]; /* store the sids */
692         }
693
694         if (!winbind_sids_to_unixids(ids, server_info->ptok->num_sids-1)) {
695                 DEBUG(2, ("Query to map secondary SIDs failed!\n"));
696                 if (!winbind_ping()) {
697                         DEBUG(2, ("Winbindd is not running, will try to map SIDs one by one with legacy code\n"));
698                         wb = False;
699                 }
700         }
701
702         for (i = 0; i < server_info->ptok->num_sids-1; i++) {
703                 gid_t agid;
704
705                 if (wb) {
706                         if (ids[i].status != ID_MAPPED) {
707                                 DEBUG(10, ("Could not convert SID %s to gid, "
708                                            "ignoring it\n", sid_string_static(ids[i].sid)));
709                                 continue;
710                         }
711                         if (ids[i].xid.type == ID_TYPE_UID) {
712                                 DEBUG(10, ("SID %s is a User ID (%u) not a Group ID, "
713                                            "ignoring it\n", sid_string_static(ids[i].sid), ids[i].xid.id));
714                                 continue;
715                         }
716                         agid = (gid_t)ids[i].xid.id;
717                 } else {
718                         if (! sid_to_gid(ids[i].sid, &agid)) {
719                                 continue;
720                         }
721                 }
722                 if (!add_gid_to_array_unique(server_info, agid, &server_info->groups,
723                                         &server_info->n_groups)) {
724                         TALLOC_FREE(mem_ctx);
725                         return NT_STATUS_NO_MEMORY;
726                 }
727         }
728
729         debug_nt_user_token(DBGC_AUTH, 10, server_info->ptok);
730
731         status = log_nt_token(mem_ctx, server_info->ptok);
732
733         TALLOC_FREE(mem_ctx);
734         return status;
735 }
736
737 /*
738  * Create an artificial NT token given just a username. (Initially indended
739  * for force user)
740  *
741  * We go through lookup_name() to avoid problems we had with 'winbind use
742  * default domain'.
743  *
744  * We have 3 cases:
745  *
746  * unmapped unix users: Go directly to nss to find the user's group.
747  *
748  * A passdb user: The list of groups is provided by pdb_enum_group_memberships.
749  *
750  * If the user is provided by winbind, the primary gid is set to "domain
751  * users" of the user's domain. For an explanation why this is necessary, see
752  * the thread starting at
753  * http://lists.samba.org/archive/samba-technical/2006-January/044803.html.
754  */
755
756 NTSTATUS create_token_from_username(TALLOC_CTX *mem_ctx, const char *username,
757                                     BOOL is_guest,
758                                     uid_t *uid, gid_t *gid,
759                                     char **found_username,
760                                     struct nt_user_token **token)
761 {
762         NTSTATUS result = NT_STATUS_NO_SUCH_USER;
763         TALLOC_CTX *tmp_ctx;
764         DOM_SID user_sid;
765         enum lsa_SidType type;
766         gid_t *gids;
767         DOM_SID *group_sids;
768         DOM_SID unix_group_sid;
769         size_t num_group_sids;
770         size_t num_gids;
771         size_t i;
772
773         tmp_ctx = talloc_new(NULL);
774         if (tmp_ctx == NULL) {
775                 DEBUG(0, ("talloc_new failed\n"));
776                 return NT_STATUS_NO_MEMORY;
777         }
778
779         if (!lookup_name_smbconf(tmp_ctx, username, LOOKUP_NAME_ALL,
780                          NULL, NULL, &user_sid, &type)) {
781                 DEBUG(1, ("lookup_name_smbconf for %s failed\n", username));
782                 goto done;
783         }
784
785         if (type != SID_NAME_USER) {
786                 DEBUG(1, ("%s is a %s, not a user\n", username,
787                           sid_type_lookup(type)));
788                 goto done;
789         }
790
791         if (!sid_to_uid(&user_sid, uid)) {
792                 DEBUG(1, ("sid_to_uid for %s (%s) failed\n",
793                           username, sid_string_static(&user_sid)));
794                 goto done;
795         }
796
797         if (sid_check_is_in_our_domain(&user_sid)) {
798
799                 /* This is a passdb user, so ask passdb */
800
801                 struct samu *sam_acct = NULL;
802
803                 if ( !(sam_acct = samu_new( tmp_ctx )) ) {
804                         result = NT_STATUS_NO_MEMORY;
805                         goto done;
806                 }
807
808                 if (!pdb_getsampwsid(sam_acct, &user_sid)) {
809                         DEBUG(1, ("pdb_getsampwsid(%s) for user %s failed\n",
810                                   sid_string_static(&user_sid), username));
811                         DEBUGADD(1, ("Fall back to unix user %s\n", username));
812                         goto unix_user;
813                 }
814
815                 result = pdb_enum_group_memberships(tmp_ctx, sam_acct,
816                                                     &group_sids, &gids,
817                                                     &num_group_sids);
818                 if (!NT_STATUS_IS_OK(result)) {
819                         DEBUG(10, ("enum_group_memberships failed for %s\n",
820                                    username));
821                         DEBUGADD(1, ("Fall back to unix user %s\n", username));
822                         goto unix_user;
823                 }
824
825                 /* see the smb_panic() in pdb_default_enum_group_memberships */
826                 SMB_ASSERT(num_group_sids > 0); 
827
828                 *gid = gids[0];
829
830                 /* Ensure we're returning the found_username on the right context. */
831                 *found_username = talloc_strdup(mem_ctx,
832                                                 pdb_get_username(sam_acct));
833
834         } else  if (sid_check_is_in_unix_users(&user_sid)) {
835
836                 /* This is a unix user not in passdb. We need to ask nss
837                  * directly, without consulting passdb */
838
839                 struct passwd *pass;
840
841                 /*
842                  * This goto target is used as a fallback for the passdb
843                  * case. The concrete bug report is when passdb gave us an
844                  * unmapped gid.
845                  */
846
847         unix_user:
848
849                 uid_to_unix_users_sid(*uid, &user_sid);
850
851                 pass = getpwuid_alloc(tmp_ctx, *uid);
852                 if (pass == NULL) {
853                         DEBUG(1, ("getpwuid(%d) for user %s failed\n",
854                                   *uid, username));
855                         goto done;
856                 }
857
858                 if (!getgroups_unix_user(tmp_ctx, username, pass->pw_gid,
859                                          &gids, &num_group_sids)) {
860                         DEBUG(1, ("getgroups_unix_user for user %s failed\n",
861                                   username));
862                         goto done;
863                 }
864
865                 group_sids = talloc_array(tmp_ctx, DOM_SID, num_group_sids);
866                 if (group_sids == NULL) {
867                         DEBUG(1, ("talloc_array failed\n"));
868                         result = NT_STATUS_NO_MEMORY;
869                         goto done;
870                 }
871
872                 for (i=0; i<num_group_sids; i++) {
873                         gid_to_sid(&group_sids[i], gids[i]);
874                 }
875
876                 /* In getgroups_unix_user we always set the primary gid */
877                 SMB_ASSERT(num_group_sids > 0); 
878
879                 *gid = gids[0];
880
881                 /* Ensure we're returning the found_username on the right context. */
882                 *found_username = talloc_strdup(mem_ctx, pass->pw_name);
883         } else {
884
885                 /* This user is from winbind, force the primary gid to the
886                  * user's "domain users" group. Under certain circumstances
887                  * (user comes from NT4), this might be a loss of
888                  * information. But we can not rely on winbind getting the
889                  * correct info. AD might prohibit winbind looking up that
890                  * information. */
891
892                 uint32 dummy;
893
894                 num_group_sids = 1;
895                 group_sids = talloc_array(tmp_ctx, DOM_SID, num_group_sids);
896                 if (group_sids == NULL) {
897                         DEBUG(1, ("talloc_array failed\n"));
898                         result = NT_STATUS_NO_MEMORY;
899                         goto done;
900                 }
901
902                 sid_copy(&group_sids[0], &user_sid);
903                 sid_split_rid(&group_sids[0], &dummy);
904                 sid_append_rid(&group_sids[0], DOMAIN_GROUP_RID_USERS);
905
906                 if (!sid_to_gid(&group_sids[0], gid)) {
907                         DEBUG(1, ("sid_to_gid(%s) failed\n",
908                                   sid_string_static(&group_sids[0])));
909                         goto done;
910                 }
911
912                 gids = gid;
913
914                 /* Ensure we're returning the found_username on the right context. */
915                 *found_username = talloc_strdup(mem_ctx, username);
916         }
917
918         /* Add the "Unix Group" SID for each gid to catch mapped groups
919            and their Unix equivalent.  This is to solve the backwards
920            compatibility problem of 'valid users = +ntadmin' where
921            ntadmin has been paired with "Domain Admins" in the group
922            mapping table.  Otherwise smb.conf would need to be changed
923            to 'valid user = "Domain Admins"'.  --jerry */
924
925         num_gids = num_group_sids;
926         for ( i=0; i<num_gids; i++ ) {
927                 gid_t high, low;
928
929                 /* don't pickup anything managed by Winbind */
930
931                 if ( lp_idmap_gid(&low, &high) && (gids[i] >= low) && (gids[i] <= high) )
932                         continue;
933
934                 if ( !gid_to_unix_groups_sid( gids[i], &unix_group_sid ) ) {
935                         DEBUG(1,("create_token_from_username: Failed to create SID "
936                                 "for gid %d!\n", gids[i]));
937                         continue;
938                 }
939                 if (!add_sid_to_array_unique(tmp_ctx, &unix_group_sid,
940                                 &group_sids, &num_group_sids )) {
941                         result = NT_STATUS_NO_MEMORY;
942                         goto done;
943                 }
944         }
945
946         /* Ensure we're creating the nt_token on the right context. */
947         *token = create_local_nt_token(mem_ctx, &user_sid,
948                                        is_guest, num_group_sids, group_sids);
949
950         if ((*token == NULL) || (*found_username == NULL)) {
951                 result = NT_STATUS_NO_MEMORY;
952                 goto done;
953         }
954
955         result = NT_STATUS_OK;
956  done:
957         TALLOC_FREE(tmp_ctx);
958         return result;
959 }
960
961 /***************************************************************************
962  Build upon create_token_from_username:
963
964  Expensive helper function to figure out whether a user given its name is
965  member of a particular group.
966 ***************************************************************************/
967
968 BOOL user_in_group_sid(const char *username, const DOM_SID *group_sid)
969 {
970         NTSTATUS status;
971         uid_t uid;
972         gid_t gid;
973         char *found_username;
974         struct nt_user_token *token;
975         BOOL result;
976
977         TALLOC_CTX *mem_ctx;
978
979         mem_ctx = talloc_new(NULL);
980         if (mem_ctx == NULL) {
981                 DEBUG(0, ("talloc_new failed\n"));
982                 return False;
983         }
984
985         status = create_token_from_username(mem_ctx, username, False,
986                                             &uid, &gid, &found_username,
987                                             &token);
988
989         if (!NT_STATUS_IS_OK(status)) {
990                 DEBUG(10, ("could not create token for %s\n", username));
991                 return False;
992         }
993
994         result = nt_token_check_sid(group_sid, token);
995
996         TALLOC_FREE(mem_ctx);
997         return result;
998         
999 }
1000
1001 BOOL user_in_group(const char *username, const char *groupname)
1002 {
1003         TALLOC_CTX *mem_ctx;
1004         DOM_SID group_sid;
1005         BOOL ret;
1006
1007         mem_ctx = talloc_new(NULL);
1008         if (mem_ctx == NULL) {
1009                 DEBUG(0, ("talloc_new failed\n"));
1010                 return False;
1011         }
1012
1013         ret = lookup_name(mem_ctx, groupname, LOOKUP_NAME_ALL,
1014                           NULL, NULL, &group_sid, NULL);
1015         TALLOC_FREE(mem_ctx);
1016
1017         if (!ret) {
1018                 DEBUG(10, ("lookup_name for (%s) failed.\n", groupname));
1019                 return False;
1020         }
1021
1022         return user_in_group_sid(username, &group_sid);
1023 }
1024
1025
1026 /***************************************************************************
1027  Make (and fill) a user_info struct from a 'struct passwd' by conversion 
1028  to a struct samu
1029 ***************************************************************************/
1030
1031 NTSTATUS make_server_info_pw(auth_serversupplied_info **server_info, 
1032                              char *unix_username,
1033                              struct passwd *pwd)
1034 {
1035         NTSTATUS status;
1036         struct samu *sampass = NULL;
1037         gid_t *gids;
1038         auth_serversupplied_info *result;
1039         
1040         if ( !(sampass = samu_new( NULL )) ) {
1041                 return NT_STATUS_NO_MEMORY;
1042         }
1043         
1044         status = samu_set_unix( sampass, pwd );
1045         if (!NT_STATUS_IS_OK(status)) {
1046                 return status;
1047         }
1048
1049         result = make_server_info(NULL);
1050         if (result == NULL) {
1051                 TALLOC_FREE(sampass);
1052                 return NT_STATUS_NO_MEMORY;
1053         }
1054
1055         result->sam_account = sampass;
1056         result->unix_name = talloc_strdup(result, unix_username);
1057         result->uid = pwd->pw_uid;
1058         result->gid = pwd->pw_gid;
1059
1060         status = pdb_enum_group_memberships(result, sampass,
1061                                             &result->sids, &gids,
1062                                             &result->num_sids);
1063
1064         if (!NT_STATUS_IS_OK(status)) {
1065                 DEBUG(10, ("pdb_enum_group_memberships failed: %s\n",
1066                            nt_errstr(status)));
1067                 TALLOC_FREE(result);
1068                 return status;
1069         }
1070
1071         /* For now we throw away the gids and convert via sid_to_gid
1072          * later. This needs fixing, but I'd like to get the code straight and
1073          * simple first. */
1074         TALLOC_FREE(gids);
1075
1076         *server_info = result;
1077
1078         return NT_STATUS_OK;
1079 }
1080
1081 /***************************************************************************
1082  Make (and fill) a user_info struct for a guest login.
1083  This *must* succeed for smbd to start. If there is no mapping entry for
1084  the guest gid, then create one.
1085 ***************************************************************************/
1086
1087 static NTSTATUS make_new_server_info_guest(auth_serversupplied_info **server_info)
1088 {
1089         NTSTATUS status;
1090         struct samu *sampass = NULL;
1091         DOM_SID guest_sid;
1092         BOOL ret;
1093         static const char zeros[16] = { 0, };
1094
1095         if ( !(sampass = samu_new( NULL )) ) {
1096                 return NT_STATUS_NO_MEMORY;
1097         }
1098
1099         sid_copy(&guest_sid, get_global_sam_sid());
1100         sid_append_rid(&guest_sid, DOMAIN_USER_RID_GUEST);
1101
1102         become_root();
1103         ret = pdb_getsampwsid(sampass, &guest_sid);
1104         unbecome_root();
1105
1106         if (!ret) {
1107                 TALLOC_FREE(sampass);
1108                 return NT_STATUS_NO_SUCH_USER;
1109         }
1110
1111         status = make_server_info_sam(server_info, sampass);
1112         if (!NT_STATUS_IS_OK(status)) {
1113                 TALLOC_FREE(sampass);
1114                 return status;
1115         }
1116         
1117         (*server_info)->guest = True;
1118
1119         status = create_local_token(*server_info);
1120         if (!NT_STATUS_IS_OK(status)) {
1121                 DEBUG(10, ("create_local_token failed: %s\n",
1122                            nt_errstr(status)));
1123                 return status;
1124         }
1125
1126         /* annoying, but the Guest really does have a session key, and it is
1127            all zeros! */
1128         (*server_info)->user_session_key = data_blob(zeros, sizeof(zeros));
1129         (*server_info)->lm_session_key = data_blob(zeros, sizeof(zeros));
1130
1131         return NT_STATUS_OK;
1132 }
1133
1134 static auth_serversupplied_info *copy_serverinfo(auth_serversupplied_info *src)
1135 {
1136         auth_serversupplied_info *dst;
1137
1138         dst = make_server_info(NULL);
1139         if (dst == NULL) {
1140                 return NULL;
1141         }
1142
1143         dst->guest = src->guest;
1144         dst->uid = src->uid;
1145         dst->gid = src->gid;
1146         dst->n_groups = src->n_groups;
1147         if (src->n_groups != 0) {
1148                 dst->groups = (gid_t *)talloc_memdup(
1149                         dst, src->groups, sizeof(gid_t)*dst->n_groups);
1150         } else {
1151                 dst->groups = NULL;
1152         }
1153
1154         if (src->ptok) {
1155                 dst->ptok = dup_nt_token(dst, src->ptok);
1156                 if (!dst->ptok) {
1157                         TALLOC_FREE(dst);
1158                         return NULL;
1159                 }
1160         }
1161         
1162         dst->user_session_key = data_blob_talloc( dst, src->user_session_key.data,
1163                                                 src->user_session_key.length);
1164
1165         dst->lm_session_key = data_blob_talloc(dst, src->lm_session_key.data,
1166                                                 src->lm_session_key.length);
1167
1168         dst->sam_account = samu_new(NULL);
1169         if (!dst->sam_account) {
1170                 TALLOC_FREE(dst);
1171                 return NULL;
1172         }
1173
1174         if (!pdb_copy_sam_account(dst->sam_account, src->sam_account)) {
1175                 TALLOC_FREE(dst);
1176                 return NULL;
1177         }
1178         
1179         dst->pam_handle = NULL;
1180         dst->unix_name = talloc_strdup(dst, src->unix_name);
1181         if (!dst->unix_name) {
1182                 TALLOC_FREE(dst);
1183                 return NULL;
1184         }
1185
1186         return dst;
1187 }
1188
1189 static auth_serversupplied_info *guest_info = NULL;
1190
1191 BOOL init_guest_info(void)
1192 {
1193         if (guest_info != NULL)
1194                 return True;
1195
1196         return NT_STATUS_IS_OK(make_new_server_info_guest(&guest_info));
1197 }
1198
1199 NTSTATUS make_server_info_guest(auth_serversupplied_info **server_info)
1200 {
1201         *server_info = copy_serverinfo(guest_info);
1202         return (*server_info != NULL) ? NT_STATUS_OK : NT_STATUS_NO_MEMORY;
1203 }
1204
1205 BOOL copy_current_user(struct current_user *dst, struct current_user *src)
1206 {
1207         gid_t *groups;
1208         NT_USER_TOKEN *nt_token;
1209
1210         groups = (gid_t *)memdup(src->ut.groups,
1211                                  sizeof(gid_t) * src->ut.ngroups);
1212         if ((src->ut.ngroups != 0) && (groups == NULL)) {
1213                 return False;
1214         }
1215
1216         nt_token = dup_nt_token(NULL, src->nt_user_token);
1217         if (nt_token == NULL) {
1218                 SAFE_FREE(groups);
1219                 return False;
1220         }
1221
1222         dst->conn = src->conn;
1223         dst->vuid = src->vuid;
1224         dst->ut.uid = src->ut.uid;
1225         dst->ut.gid = src->ut.gid;
1226         dst->ut.ngroups = src->ut.ngroups;
1227         dst->ut.groups = groups;
1228         dst->nt_user_token = nt_token;
1229         return True;
1230 }
1231
1232 BOOL set_current_user_guest(struct current_user *dst)
1233 {
1234         gid_t *groups;
1235         NT_USER_TOKEN *nt_token;
1236
1237         groups = (gid_t *)memdup(guest_info->groups,
1238                                  sizeof(gid_t) * guest_info->n_groups);
1239         if (groups == NULL) {
1240                 return False;
1241         }
1242
1243         nt_token = dup_nt_token(NULL, guest_info->ptok);
1244         if (nt_token == NULL) {
1245                 SAFE_FREE(groups);
1246                 return False;
1247         }
1248
1249         TALLOC_FREE(dst->nt_user_token);
1250         SAFE_FREE(dst->ut.groups);
1251
1252         /* dst->conn is never really dereferenced, it's only tested for
1253          * equality in uid.c */
1254         dst->conn = NULL;
1255
1256         dst->vuid = UID_FIELD_INVALID;
1257         dst->ut.uid = guest_info->uid;
1258         dst->ut.gid = guest_info->gid;
1259         dst->ut.ngroups = guest_info->n_groups;
1260         dst->ut.groups = groups;
1261         dst->nt_user_token = nt_token;
1262         return True;
1263 }
1264
1265 /***************************************************************************
1266  Purely internal function for make_server_info_info3
1267  Fill the sam account from getpwnam
1268 ***************************************************************************/
1269 static NTSTATUS fill_sam_account(TALLOC_CTX *mem_ctx, 
1270                                  const char *domain,
1271                                  const char *username,
1272                                  char **found_username,
1273                                  uid_t *uid, gid_t *gid,
1274                                  struct samu *account,
1275                                  BOOL *username_was_mapped)
1276 {
1277         NTSTATUS nt_status;
1278         fstring dom_user, lower_username;
1279         fstring real_username;
1280         struct passwd *passwd;
1281
1282         fstrcpy( lower_username, username );
1283         strlower_m( lower_username );
1284
1285         fstr_sprintf(dom_user, "%s%c%s", domain, *lp_winbind_separator(), 
1286                 lower_username);
1287
1288         /* Get the passwd struct.  Try to create the account is necessary. */
1289
1290         *username_was_mapped = map_username( dom_user );
1291
1292         if ( !(passwd = smb_getpwnam( NULL, dom_user, real_username, True )) )
1293                 return NT_STATUS_NO_SUCH_USER;
1294
1295         *uid = passwd->pw_uid;
1296         *gid = passwd->pw_gid;
1297
1298         /* This is pointless -- there is no suport for differing 
1299            unix and windows names.  Make sure to always store the 
1300            one we actually looked up and succeeded. Have I mentioned
1301            why I hate the 'winbind use default domain' parameter?   
1302                                          --jerry              */
1303            
1304         *found_username = talloc_strdup( mem_ctx, real_username );
1305         
1306         DEBUG(5,("fill_sam_account: located username was [%s]\n", *found_username));
1307
1308         nt_status = samu_set_unix( account, passwd );
1309         
1310         TALLOC_FREE(passwd);
1311         
1312         return nt_status;
1313 }
1314
1315 /****************************************************************************
1316  Wrapper to allow the getpwnam() call to strip the domain name and 
1317  try again in case a local UNIX user is already there.  Also run through 
1318  the username if we fallback to the username only.
1319  ****************************************************************************/
1320  
1321 struct passwd *smb_getpwnam( TALLOC_CTX *mem_ctx, char *domuser,
1322                              fstring save_username, BOOL create )
1323 {
1324         struct passwd *pw = NULL;
1325         char *p;
1326         fstring username;
1327         
1328         /* we only save a copy of the username it has been mangled 
1329            by winbindd use default domain */
1330            
1331         save_username[0] = '\0';
1332            
1333         /* don't call map_username() here since it has to be done higher 
1334            up the stack so we don't call it mutliple times */
1335
1336         fstrcpy( username, domuser );
1337         
1338         p = strchr_m( username, *lp_winbind_separator() );
1339         
1340         /* code for a DOMAIN\user string */
1341         
1342         if ( p ) {
1343                 fstring strip_username;
1344
1345                 pw = Get_Pwnam_alloc( mem_ctx, domuser );
1346                 if ( pw ) {     
1347                         /* make sure we get the case of the username correct */
1348                         /* work around 'winbind use default domain = yes' */
1349
1350                         if ( !strchr_m( pw->pw_name, *lp_winbind_separator() ) ) {
1351                                 char *domain;
1352                                 
1353                                 /* split the domain and username into 2 strings */
1354                                 *p = '\0';
1355                                 domain = username;
1356
1357                                 fstr_sprintf(save_username, "%s%c%s", domain, *lp_winbind_separator(), pw->pw_name);
1358                         }
1359                         else
1360                                 fstrcpy( save_username, pw->pw_name );
1361
1362                         /* whew -- done! */             
1363                         return pw;
1364                 }
1365
1366                 /* setup for lookup of just the username */
1367                 /* remember that p and username are overlapping memory */
1368
1369                 p++;
1370                 fstrcpy( strip_username, p );
1371                 fstrcpy( username, strip_username );
1372         }
1373         
1374         /* just lookup a plain username */
1375         
1376         pw = Get_Pwnam_alloc(mem_ctx, username);
1377                 
1378         /* Create local user if requested but only if winbindd
1379            is not running.  We need to protect against cases
1380            where winbindd is failing and then prematurely
1381            creating users in /etc/passwd */
1382         
1383         if ( !pw && create && !winbind_ping() ) {
1384                 /* Don't add a machine account. */
1385                 if (username[strlen(username)-1] == '$')
1386                         return NULL;
1387
1388                 smb_create_user(NULL, username, NULL);
1389                 pw = Get_Pwnam_alloc(mem_ctx, username);
1390         }
1391         
1392         /* one last check for a valid passwd struct */
1393         
1394         if ( pw )
1395                 fstrcpy( save_username, pw->pw_name );
1396
1397         return pw;
1398 }
1399
1400 /***************************************************************************
1401  Make a server_info struct from the info3 returned by a domain logon 
1402 ***************************************************************************/
1403
1404 NTSTATUS make_server_info_info3(TALLOC_CTX *mem_ctx, 
1405                                 const char *sent_nt_username,
1406                                 const char *domain,
1407                                 auth_serversupplied_info **server_info, 
1408                                 NET_USER_INFO_3 *info3) 
1409 {
1410         static const char zeros[16] = { 0, };
1411
1412         NTSTATUS nt_status = NT_STATUS_OK;
1413         char *found_username;
1414         const char *nt_domain;
1415         const char *nt_username;
1416         struct samu *sam_account = NULL;
1417         DOM_SID user_sid;
1418         DOM_SID group_sid;
1419         BOOL username_was_mapped;
1420
1421         uid_t uid;
1422         gid_t gid;
1423
1424         size_t i;
1425
1426         auth_serversupplied_info *result;
1427
1428         /* 
1429            Here is where we should check the list of
1430            trusted domains, and verify that the SID 
1431            matches.
1432         */
1433
1434         sid_copy(&user_sid, &info3->dom_sid.sid);
1435         if (!sid_append_rid(&user_sid, info3->user_rid)) {
1436                 return NT_STATUS_INVALID_PARAMETER;
1437         }
1438         
1439         sid_copy(&group_sid, &info3->dom_sid.sid);
1440         if (!sid_append_rid(&group_sid, info3->group_rid)) {
1441                 return NT_STATUS_INVALID_PARAMETER;
1442         }
1443
1444         if (!(nt_username = unistr2_tdup(mem_ctx, &(info3->uni_user_name)))) {
1445                 /* If the server didn't give us one, just use the one we sent
1446                  * them */
1447                 nt_username = sent_nt_username;
1448         }
1449
1450         if (!(nt_domain = unistr2_tdup(mem_ctx, &(info3->uni_logon_dom)))) {
1451                 /* If the server didn't give us one, just use the one we sent
1452                  * them */
1453                 nt_domain = domain;
1454         }
1455         
1456         /* try to fill the SAM account..  If getpwnam() fails, then try the 
1457            add user script (2.2.x behavior).
1458
1459            We use the _unmapped_ username here in an attempt to provide
1460            consistent username mapping behavior between kerberos and NTLM[SSP]
1461            authentication in domain mode security.  I.E. Username mapping
1462            should be applied to the fully qualified username
1463            (e.g. DOMAIN\user) and not just the login name.  Yes this means we
1464            called map_username() unnecessarily in make_user_info_map() but
1465            that is how the current code is designed.  Making the change here
1466            is the least disruptive place.  -- jerry */
1467            
1468         if ( !(sam_account = samu_new( NULL )) ) {
1469                 return NT_STATUS_NO_MEMORY;
1470         }
1471
1472         /* this call will try to create the user if necessary */
1473
1474         nt_status = fill_sam_account(mem_ctx, nt_domain, sent_nt_username,
1475                                      &found_username, &uid, &gid, sam_account,
1476                                      &username_was_mapped);
1477
1478         
1479         /* if we still don't have a valid unix account check for 
1480           'map to guest = bad uid' */
1481           
1482         if (!NT_STATUS_IS_OK(nt_status)) {
1483                 TALLOC_FREE( sam_account );
1484                 if ( lp_map_to_guest() == MAP_TO_GUEST_ON_BAD_UID ) {
1485                         make_server_info_guest(server_info); 
1486                         return NT_STATUS_OK;
1487                 }
1488                 return nt_status;
1489         }
1490                 
1491         if (!pdb_set_nt_username(sam_account, nt_username, PDB_CHANGED)) {
1492                 TALLOC_FREE(sam_account);
1493                 return NT_STATUS_NO_MEMORY;
1494         }
1495
1496         if (!pdb_set_username(sam_account, nt_username, PDB_CHANGED)) {
1497                 TALLOC_FREE(sam_account);
1498                 return NT_STATUS_NO_MEMORY;
1499         }
1500
1501         if (!pdb_set_domain(sam_account, nt_domain, PDB_CHANGED)) {
1502                 TALLOC_FREE(sam_account);
1503                 return NT_STATUS_NO_MEMORY;
1504         }
1505
1506         if (!pdb_set_user_sid(sam_account, &user_sid, PDB_CHANGED)) {
1507                 TALLOC_FREE(sam_account);
1508                 return NT_STATUS_UNSUCCESSFUL;
1509         }
1510
1511         if (!pdb_set_group_sid(sam_account, &group_sid, PDB_CHANGED)) {
1512                 TALLOC_FREE(sam_account);
1513                 return NT_STATUS_UNSUCCESSFUL;
1514         }
1515                 
1516         if (!pdb_set_fullname(sam_account,
1517                               unistr2_static(&(info3->uni_full_name)), 
1518                               PDB_CHANGED)) {
1519                 TALLOC_FREE(sam_account);
1520                 return NT_STATUS_NO_MEMORY;
1521         }
1522
1523         if (!pdb_set_logon_script(sam_account,
1524                                   unistr2_static(&(info3->uni_logon_script)),
1525                                   PDB_CHANGED)) {
1526                 TALLOC_FREE(sam_account);
1527                 return NT_STATUS_NO_MEMORY;
1528         }
1529
1530         if (!pdb_set_profile_path(sam_account,
1531                                   unistr2_static(&(info3->uni_profile_path)),
1532                                   PDB_CHANGED)) {
1533                 TALLOC_FREE(sam_account);
1534                 return NT_STATUS_NO_MEMORY;
1535         }
1536
1537         if (!pdb_set_homedir(sam_account,
1538                              unistr2_static(&(info3->uni_home_dir)),
1539                              PDB_CHANGED)) {
1540                 TALLOC_FREE(sam_account);
1541                 return NT_STATUS_NO_MEMORY;
1542         }
1543
1544         if (!pdb_set_dir_drive(sam_account,
1545                                unistr2_static(&(info3->uni_dir_drive)),
1546                                PDB_CHANGED)) {
1547                 TALLOC_FREE(sam_account);
1548                 return NT_STATUS_NO_MEMORY;
1549         }
1550
1551         if (!pdb_set_acct_ctrl(sam_account, info3->acct_flags, PDB_CHANGED)) {
1552                 TALLOC_FREE(sam_account);
1553                 return NT_STATUS_NO_MEMORY;
1554         }
1555
1556         result = make_server_info(NULL);
1557         if (result == NULL) {
1558                 DEBUG(4, ("make_server_info failed!\n"));
1559                 TALLOC_FREE(sam_account);
1560                 return NT_STATUS_NO_MEMORY;
1561         }
1562
1563         /* save this here to _net_sam_logon() doesn't fail (it assumes a 
1564            valid struct samu) */
1565                    
1566         result->sam_account = sam_account;
1567         result->unix_name = talloc_strdup(result, found_username);
1568
1569         /* Fill in the unix info we found on the way */
1570
1571         result->uid = uid;
1572         result->gid = gid;
1573
1574         /* Create a 'combined' list of all SIDs we might want in the SD */
1575
1576         result->num_sids = 0;
1577         result->sids = NULL;
1578
1579         /* and create (by appending rids) the 'domain' sids */
1580         
1581         for (i = 0; i < info3->num_groups2; i++) {
1582                 DOM_SID sid;
1583                 if (!sid_compose(&sid, &info3->dom_sid.sid,
1584                                  info3->gids[i].g_rid)) {
1585                         DEBUG(3,("could not append additional group rid "
1586                                  "0x%x\n", info3->gids[i].g_rid));
1587                         TALLOC_FREE(result);
1588                         return NT_STATUS_INVALID_PARAMETER;
1589                 }
1590                 if (!add_sid_to_array(result, &sid, &result->sids,
1591                                  &result->num_sids)) {
1592                         TALLOC_FREE(result);
1593                         return NT_STATUS_NO_MEMORY;
1594                 }
1595         }
1596
1597         /* Copy 'other' sids.  We need to do sid filtering here to
1598            prevent possible elevation of privileges.  See:
1599
1600            http://www.microsoft.com/windows2000/techinfo/administration/security/sidfilter.asp
1601          */
1602
1603         for (i = 0; i < info3->num_other_sids; i++) {
1604                 if (!add_sid_to_array(result, &info3->other_sids[i].sid,
1605                                          &result->sids,
1606                                          &result->num_sids)) {
1607                         TALLOC_FREE(result);
1608                         return NT_STATUS_NO_MEMORY;
1609                 }
1610         }
1611
1612         result->login_server = unistr2_tdup(result, 
1613                                             &(info3->uni_logon_srv));
1614
1615         /* ensure we are never given NULL session keys */
1616         
1617         if (memcmp(info3->user_sess_key, zeros, sizeof(zeros)) == 0) {
1618                 result->user_session_key = data_blob(NULL, 0);
1619         } else {
1620                 result->user_session_key = data_blob_talloc(
1621                         result, info3->user_sess_key,
1622                         sizeof(info3->user_sess_key));
1623         }
1624
1625         if (memcmp(info3->lm_sess_key, zeros, 8) == 0) {
1626                 result->lm_session_key = data_blob(NULL, 0);
1627         } else {
1628                 result->lm_session_key = data_blob_talloc(
1629                         result, info3->lm_sess_key,
1630                         sizeof(info3->lm_sess_key));
1631         }
1632
1633         result->was_mapped = username_was_mapped;
1634
1635         *server_info = result;
1636
1637         return NT_STATUS_OK;
1638 }
1639
1640 /***************************************************************************
1641  Free a user_info struct
1642 ***************************************************************************/
1643
1644 void free_user_info(auth_usersupplied_info **user_info)
1645 {
1646         DEBUG(5,("attempting to free (and zero) a user_info structure\n"));
1647         if (*user_info != NULL) {
1648                 if ((*user_info)->smb_name) {
1649                         DEBUG(10,("structure was created for %s\n",
1650                                   (*user_info)->smb_name));
1651                 }
1652                 SAFE_FREE((*user_info)->smb_name);
1653                 SAFE_FREE((*user_info)->internal_username);
1654                 SAFE_FREE((*user_info)->client_domain);
1655                 SAFE_FREE((*user_info)->domain);
1656                 SAFE_FREE((*user_info)->wksta_name);
1657                 data_blob_free(&(*user_info)->lm_resp);
1658                 data_blob_free(&(*user_info)->nt_resp);
1659                 data_blob_clear_free(&(*user_info)->lm_interactive_pwd);
1660                 data_blob_clear_free(&(*user_info)->nt_interactive_pwd);
1661                 data_blob_clear_free(&(*user_info)->plaintext_password);
1662                 ZERO_STRUCT(**user_info);
1663         }
1664         SAFE_FREE(*user_info);
1665 }
1666
1667 /***************************************************************************
1668  Make an auth_methods struct
1669 ***************************************************************************/
1670
1671 BOOL make_auth_methods(struct auth_context *auth_context, auth_methods **auth_method) 
1672 {
1673         if (!auth_context) {
1674                 smb_panic("no auth_context supplied to "
1675                           "make_auth_methods()!\n");
1676         }
1677
1678         if (!auth_method) {
1679                 smb_panic("make_auth_methods: pointer to auth_method pointer "
1680                           "is NULL!\n");
1681         }
1682
1683         *auth_method = TALLOC_P(auth_context->mem_ctx, auth_methods);
1684         if (!*auth_method) {
1685                 DEBUG(0,("make_auth_method: malloc failed!\n"));
1686                 return False;
1687         }
1688         ZERO_STRUCTP(*auth_method);
1689         
1690         return True;
1691 }
1692
1693 /**
1694  * Verify whether or not given domain is trusted.
1695  *
1696  * @param domain_name name of the domain to be verified
1697  * @return true if domain is one of the trusted once or
1698  *         false if otherwise
1699  **/
1700
1701 BOOL is_trusted_domain(const char* dom_name)
1702 {
1703         DOM_SID trustdom_sid;
1704         BOOL ret;
1705
1706         /* no trusted domains for a standalone server */
1707
1708         if ( lp_server_role() == ROLE_STANDALONE )
1709                 return False;
1710
1711         /* if we are a DC, then check for a direct trust relationships */
1712
1713         if ( IS_DC ) {
1714                 become_root();
1715                 DEBUG (5,("is_trusted_domain: Checking for domain trust with "
1716                           "[%s]\n", dom_name ));
1717                 ret = pdb_get_trusteddom_pw(dom_name, NULL, NULL, NULL);
1718                 unbecome_root();
1719                 if (ret)
1720                         return True;
1721         }
1722         else {
1723                 NSS_STATUS result;
1724
1725                 /* If winbind is around, ask it */
1726
1727                 result = wb_is_trusted_domain(dom_name);
1728
1729                 if (result == NSS_STATUS_SUCCESS) {
1730                         return True;
1731                 }
1732
1733                 if (result == NSS_STATUS_NOTFOUND) {
1734                         /* winbind could not find the domain */
1735                         return False;
1736                 }
1737
1738                 /* The only other possible result is that winbind is not up
1739                    and running. We need to update the trustdom_cache
1740                    ourselves */
1741                 
1742                 update_trustdom_cache();
1743         }
1744
1745         /* now the trustdom cache should be available a DC could still
1746          * have a transitive trust so fall back to the cache of trusted
1747          * domains (like a domain member would use  */
1748
1749         if ( trustdom_cache_fetch(dom_name, &trustdom_sid) ) {
1750                 return True;
1751         }
1752
1753         return False;
1754 }
1755