~zulcss/samba/server-dailies-3.4

« back to all changes in this revision

Viewing changes to source3/auth/auth_util.c

  • Committer: Chuck Short
  • Date: 2010-09-28 20:38:39 UTC
  • Revision ID: zulcss@ubuntu.com-20100928203839-pgjulytsi9ue63x1
Initial version

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
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
 
 
26
#undef DBGC_CLASS
 
27
#define DBGC_CLASS DBGC_AUTH
 
28
 
 
29
/****************************************************************************
 
30
 Ensure primary group SID is always at position 0 in a 
 
31
 auth_serversupplied_info struct.
 
32
****************************************************************************/
 
33
 
 
34
static void sort_sid_array_for_smbd(auth_serversupplied_info *result,
 
35
                                const DOM_SID *pgroup_sid)
 
36
{
 
37
        unsigned int i;
 
38
 
 
39
        if (!result->sids) {
 
40
                return;
 
41
        }
 
42
 
 
43
        if (sid_compare(&result->sids[0], pgroup_sid)==0) {
 
44
                return;
 
45
        }
 
46
 
 
47
        for (i = 1; i < result->num_sids; i++) {
 
48
                if (sid_compare(pgroup_sid,
 
49
                                &result->sids[i]) == 0) {
 
50
                        sid_copy(&result->sids[i], &result->sids[0]);
 
51
                        sid_copy(&result->sids[0], pgroup_sid);
 
52
                        return;
 
53
                }
 
54
        }
 
55
}
 
56
 
 
57
/****************************************************************************
 
58
 Create a UNIX user on demand.
 
59
****************************************************************************/
 
60
 
 
61
static int _smb_create_user(const char *domain, const char *unix_username, const char *homedir)
 
62
{
 
63
        TALLOC_CTX *ctx = talloc_tos();
 
64
        char *add_script;
 
65
        int ret;
 
66
 
 
67
        add_script = talloc_strdup(ctx, lp_adduser_script());
 
68
        if (!add_script || !*add_script) {
 
69
                return -1;
 
70
        }
 
71
        add_script = talloc_all_string_sub(ctx,
 
72
                                add_script,
 
73
                                "%u",
 
74
                                unix_username);
 
75
        if (!add_script) {
 
76
                return -1;
 
77
        }
 
78
        if (domain) {
 
79
                add_script = talloc_all_string_sub(ctx,
 
80
                                        add_script,
 
81
                                        "%D",
 
82
                                        domain);
 
83
                if (!add_script) {
 
84
                        return -1;
 
85
                }
 
86
        }
 
87
        if (homedir) {
 
88
                add_script = talloc_all_string_sub(ctx,
 
89
                                add_script,
 
90
                                "%H",
 
91
                                homedir);
 
92
                if (!add_script) {
 
93
                        return -1;
 
94
                }
 
95
        }
 
96
        ret = smbrun(add_script,NULL);
 
97
        flush_pwnam_cache();
 
98
        DEBUG(ret ? 0 : 3,
 
99
                ("smb_create_user: Running the command `%s' gave %d\n",
 
100
                 add_script,ret));
 
101
        return ret;
 
102
}
 
103
 
 
104
/****************************************************************************
 
105
 Create an auth_usersupplied_data structure
 
106
****************************************************************************/
 
107
 
 
108
static NTSTATUS make_user_info(auth_usersupplied_info **user_info,
 
109
                               const char *smb_name,
 
110
                               const char *internal_username,
 
111
                               const char *client_domain,
 
112
                               const char *domain,
 
113
                               const char *wksta_name,
 
114
                               DATA_BLOB *lm_pwd, DATA_BLOB *nt_pwd,
 
115
                               DATA_BLOB *lm_interactive_pwd, DATA_BLOB *nt_interactive_pwd,
 
116
                               DATA_BLOB *plaintext,
 
117
                               bool encrypted)
 
118
{
 
119
 
 
120
        DEBUG(5,("attempting to make a user_info for %s (%s)\n", internal_username, smb_name));
 
121
 
 
122
        *user_info = SMB_MALLOC_P(auth_usersupplied_info);
 
123
        if (*user_info == NULL) {
 
124
                DEBUG(0,("malloc failed for user_info (size %lu)\n", (unsigned long)sizeof(*user_info)));
 
125
                return NT_STATUS_NO_MEMORY;
 
126
        }
 
127
 
 
128
        ZERO_STRUCTP(*user_info);
 
129
 
 
130
        DEBUG(5,("making strings for %s's user_info struct\n", internal_username));
 
131
 
 
132
        (*user_info)->smb_name = SMB_STRDUP(smb_name);
 
133
        if ((*user_info)->smb_name == NULL) { 
 
134
                free_user_info(user_info);
 
135
                return NT_STATUS_NO_MEMORY;
 
136
        }
 
137
        
 
138
        (*user_info)->internal_username = SMB_STRDUP(internal_username);
 
139
        if ((*user_info)->internal_username == NULL) { 
 
140
                free_user_info(user_info);
 
141
                return NT_STATUS_NO_MEMORY;
 
142
        }
 
143
 
 
144
        (*user_info)->domain = SMB_STRDUP(domain);
 
145
        if ((*user_info)->domain == NULL) { 
 
146
                free_user_info(user_info);
 
147
                return NT_STATUS_NO_MEMORY;
 
148
        }
 
149
 
 
150
        (*user_info)->client_domain = SMB_STRDUP(client_domain);
 
151
        if ((*user_info)->client_domain == NULL) { 
 
152
                free_user_info(user_info);
 
153
                return NT_STATUS_NO_MEMORY;
 
154
        }
 
155
 
 
156
        (*user_info)->wksta_name = SMB_STRDUP(wksta_name);
 
157
        if ((*user_info)->wksta_name == NULL) { 
 
158
                free_user_info(user_info);
 
159
                return NT_STATUS_NO_MEMORY;
 
160
        }
 
161
 
 
162
        DEBUG(5,("making blobs for %s's user_info struct\n", internal_username));
 
163
 
 
164
        if (lm_pwd)
 
165
                (*user_info)->lm_resp = data_blob(lm_pwd->data, lm_pwd->length);
 
166
        if (nt_pwd)
 
167
                (*user_info)->nt_resp = data_blob(nt_pwd->data, nt_pwd->length);
 
168
        if (lm_interactive_pwd)
 
169
                (*user_info)->lm_interactive_pwd = data_blob(lm_interactive_pwd->data, lm_interactive_pwd->length);
 
170
        if (nt_interactive_pwd)
 
171
                (*user_info)->nt_interactive_pwd = data_blob(nt_interactive_pwd->data, nt_interactive_pwd->length);
 
172
 
 
173
        if (plaintext)
 
174
                (*user_info)->plaintext_password = data_blob(plaintext->data, plaintext->length);
 
175
 
 
176
        (*user_info)->encrypted = encrypted;
 
177
 
 
178
        (*user_info)->logon_parameters = 0;
 
179
 
 
180
        DEBUG(10,("made an %sencrypted user_info for %s (%s)\n", encrypted ? "":"un" , internal_username, smb_name));
 
181
 
 
182
        return NT_STATUS_OK;
 
183
}
 
184
 
 
185
/****************************************************************************
 
186
 Create an auth_usersupplied_data structure after appropriate mapping.
 
187
****************************************************************************/
 
188
 
 
189
NTSTATUS make_user_info_map(auth_usersupplied_info **user_info,
 
190
                            const char *smb_name,
 
191
                            const char *client_domain,
 
192
                            const char *wksta_name,
 
193
                            DATA_BLOB *lm_pwd,
 
194
                            DATA_BLOB *nt_pwd,
 
195
                            DATA_BLOB *lm_interactive_pwd,
 
196
                            DATA_BLOB *nt_interactive_pwd,
 
197
                            DATA_BLOB *plaintext,
 
198
                            bool encrypted)
 
199
{
 
200
        const char *domain;
 
201
        NTSTATUS result;
 
202
        bool was_mapped;
 
203
        fstring internal_username;
 
204
        fstrcpy(internal_username, smb_name);
 
205
        was_mapped = map_username(internal_username);
 
206
 
 
207
        DEBUG(5, ("Mapping user [%s]\\[%s] from workstation [%s]\n",
 
208
                 client_domain, smb_name, wksta_name));
 
209
 
 
210
        domain = client_domain;
 
211
 
 
212
        /* If you connect to a Windows domain member using a bogus domain name,
 
213
         * the Windows box will map the BOGUS\user to SAMNAME\user.  Thus, if
 
214
         * the Windows box is a DC the name will become DOMAIN\user and be
 
215
         * authenticated against AD, if the Windows box is a member server but
 
216
         * not a DC the name will become WORKSTATION\user.  A standalone
 
217
         * non-domain member box will also map to WORKSTATION\user.
 
218
         * This also deals with the client passing in a "" domain */
 
219
 
 
220
        if (!is_trusted_domain(domain) &&
 
221
            !strequal(domain, my_sam_name()))
 
222
        {
 
223
                if (lp_map_untrusted_to_domain())
 
224
                        domain = my_sam_name();
 
225
                else
 
226
                        domain = get_global_sam_name();
 
227
                DEBUG(5, ("Mapped domain from [%s] to [%s] for user [%s] from "
 
228
                          "workstation [%s]\n",
 
229
                          client_domain, domain, smb_name, wksta_name));
 
230
        }
 
231
 
 
232
        /* We know that the given domain is trusted (and we are allowing them),
 
233
         * it is our global SAM name, or for legacy behavior it is our
 
234
         * primary domain name */
 
235
 
 
236
        result = make_user_info(user_info, smb_name, internal_username,
 
237
                              client_domain, domain, wksta_name,
 
238
                              lm_pwd, nt_pwd,
 
239
                              lm_interactive_pwd, nt_interactive_pwd,
 
240
                              plaintext, encrypted);
 
241
        if (NT_STATUS_IS_OK(result)) {
 
242
                (*user_info)->was_mapped = was_mapped;
 
243
        }
 
244
        return result;
 
245
}
 
246
 
 
247
/****************************************************************************
 
248
 Create an auth_usersupplied_data, making the DATA_BLOBs here. 
 
249
 Decrypt and encrypt the passwords.
 
250
****************************************************************************/
 
251
 
 
252
bool make_user_info_netlogon_network(auth_usersupplied_info **user_info, 
 
253
                                     const char *smb_name, 
 
254
                                     const char *client_domain, 
 
255
                                     const char *wksta_name, 
 
256
                                     uint32 logon_parameters,
 
257
                                     const uchar *lm_network_pwd,
 
258
                                     int lm_pwd_len,
 
259
                                     const uchar *nt_network_pwd,
 
260
                                     int nt_pwd_len)
 
261
{
 
262
        bool ret;
 
263
        NTSTATUS status;
 
264
        DATA_BLOB lm_blob = data_blob(lm_network_pwd, lm_pwd_len);
 
265
        DATA_BLOB nt_blob = data_blob(nt_network_pwd, nt_pwd_len);
 
266
 
 
267
        status = make_user_info_map(user_info,
 
268
                                    smb_name, client_domain, 
 
269
                                    wksta_name, 
 
270
                                    lm_pwd_len ? &lm_blob : NULL, 
 
271
                                    nt_pwd_len ? &nt_blob : NULL,
 
272
                                    NULL, NULL, NULL,
 
273
                                    True);
 
274
 
 
275
        if (NT_STATUS_IS_OK(status)) {
 
276
                (*user_info)->logon_parameters = logon_parameters;
 
277
        }
 
278
        ret = NT_STATUS_IS_OK(status) ? True : False;
 
279
 
 
280
        data_blob_free(&lm_blob);
 
281
        data_blob_free(&nt_blob);
 
282
        return ret;
 
283
}
 
284
 
 
285
/****************************************************************************
 
286
 Create an auth_usersupplied_data, making the DATA_BLOBs here. 
 
287
 Decrypt and encrypt the passwords.
 
288
****************************************************************************/
 
289
 
 
290
bool make_user_info_netlogon_interactive(auth_usersupplied_info **user_info, 
 
291
                                         const char *smb_name, 
 
292
                                         const char *client_domain, 
 
293
                                         const char *wksta_name, 
 
294
                                         uint32 logon_parameters,
 
295
                                         const uchar chal[8], 
 
296
                                         const uchar lm_interactive_pwd[16], 
 
297
                                         const uchar nt_interactive_pwd[16], 
 
298
                                         const uchar *dc_sess_key)
 
299
{
 
300
        unsigned char lm_pwd[16];
 
301
        unsigned char nt_pwd[16];
 
302
        unsigned char local_lm_response[24];
 
303
        unsigned char local_nt_response[24];
 
304
        unsigned char key[16];
 
305
        
 
306
        memcpy(key, dc_sess_key, 16);
 
307
        
 
308
        if (lm_interactive_pwd)
 
309
                memcpy(lm_pwd, lm_interactive_pwd, sizeof(lm_pwd));
 
310
 
 
311
        if (nt_interactive_pwd)
 
312
                memcpy(nt_pwd, nt_interactive_pwd, sizeof(nt_pwd));
 
313
        
 
314
#ifdef DEBUG_PASSWORD
 
315
        DEBUG(100,("key:"));
 
316
        dump_data(100, key, sizeof(key));
 
317
        
 
318
        DEBUG(100,("lm owf password:"));
 
319
        dump_data(100, lm_pwd, sizeof(lm_pwd));
 
320
        
 
321
        DEBUG(100,("nt owf password:"));
 
322
        dump_data(100, nt_pwd, sizeof(nt_pwd));
 
323
#endif
 
324
        
 
325
        if (lm_interactive_pwd)
 
326
                SamOEMhash(lm_pwd, key, sizeof(lm_pwd));
 
327
        
 
328
        if (nt_interactive_pwd)
 
329
                SamOEMhash(nt_pwd, key, sizeof(nt_pwd));
 
330
        
 
331
#ifdef DEBUG_PASSWORD
 
332
        DEBUG(100,("decrypt of lm owf password:"));
 
333
        dump_data(100, lm_pwd, sizeof(lm_pwd));
 
334
        
 
335
        DEBUG(100,("decrypt of nt owf password:"));
 
336
        dump_data(100, nt_pwd, sizeof(nt_pwd));
 
337
#endif
 
338
        
 
339
        if (lm_interactive_pwd)
 
340
                SMBOWFencrypt(lm_pwd, chal,
 
341
                              local_lm_response);
 
342
 
 
343
        if (nt_interactive_pwd)
 
344
                SMBOWFencrypt(nt_pwd, chal,
 
345
                              local_nt_response);
 
346
        
 
347
        /* Password info paranoia */
 
348
        ZERO_STRUCT(key);
 
349
 
 
350
        {
 
351
                bool ret;
 
352
                NTSTATUS nt_status;
 
353
                DATA_BLOB local_lm_blob;
 
354
                DATA_BLOB local_nt_blob;
 
355
 
 
356
                DATA_BLOB lm_interactive_blob;
 
357
                DATA_BLOB nt_interactive_blob;
 
358
                
 
359
                if (lm_interactive_pwd) {
 
360
                        local_lm_blob = data_blob(local_lm_response,
 
361
                                                  sizeof(local_lm_response));
 
362
                        lm_interactive_blob = data_blob(lm_pwd,
 
363
                                                        sizeof(lm_pwd));
 
364
                        ZERO_STRUCT(lm_pwd);
 
365
                }
 
366
                
 
367
                if (nt_interactive_pwd) {
 
368
                        local_nt_blob = data_blob(local_nt_response,
 
369
                                                  sizeof(local_nt_response));
 
370
                        nt_interactive_blob = data_blob(nt_pwd,
 
371
                                                        sizeof(nt_pwd));
 
372
                        ZERO_STRUCT(nt_pwd);
 
373
                }
 
374
 
 
375
                nt_status = make_user_info_map(
 
376
                        user_info, 
 
377
                        smb_name, client_domain, wksta_name, 
 
378
                        lm_interactive_pwd ? &local_lm_blob : NULL,
 
379
                        nt_interactive_pwd ? &local_nt_blob : NULL,
 
380
                        lm_interactive_pwd ? &lm_interactive_blob : NULL,
 
381
                        nt_interactive_pwd ? &nt_interactive_blob : NULL,
 
382
                        NULL, True);
 
383
 
 
384
                if (NT_STATUS_IS_OK(nt_status)) {
 
385
                        (*user_info)->logon_parameters = logon_parameters;
 
386
                }
 
387
 
 
388
                ret = NT_STATUS_IS_OK(nt_status) ? True : False;
 
389
                data_blob_free(&local_lm_blob);
 
390
                data_blob_free(&local_nt_blob);
 
391
                data_blob_free(&lm_interactive_blob);
 
392
                data_blob_free(&nt_interactive_blob);
 
393
                return ret;
 
394
        }
 
395
}
 
396
 
 
397
 
 
398
/****************************************************************************
 
399
 Create an auth_usersupplied_data structure
 
400
****************************************************************************/
 
401
 
 
402
bool make_user_info_for_reply(auth_usersupplied_info **user_info, 
 
403
                              const char *smb_name, 
 
404
                              const char *client_domain,
 
405
                              const uint8 chal[8],
 
406
                              DATA_BLOB plaintext_password)
 
407
{
 
408
 
 
409
        DATA_BLOB local_lm_blob;
 
410
        DATA_BLOB local_nt_blob;
 
411
        NTSTATUS ret = NT_STATUS_UNSUCCESSFUL;
 
412
                        
 
413
        /*
 
414
         * Not encrypted - do so.
 
415
         */
 
416
        
 
417
        DEBUG(5,("make_user_info_for_reply: User passwords not in encrypted "
 
418
                 "format.\n"));
 
419
        
 
420
        if (plaintext_password.data) {
 
421
                unsigned char local_lm_response[24];
 
422
                
 
423
#ifdef DEBUG_PASSWORD
 
424
                DEBUG(10,("Unencrypted password (len %d):\n",
 
425
                          (int)plaintext_password.length));
 
426
                dump_data(100, plaintext_password.data,
 
427
                          plaintext_password.length);
 
428
#endif
 
429
 
 
430
                SMBencrypt( (const char *)plaintext_password.data,
 
431
                            (const uchar*)chal, local_lm_response);
 
432
                local_lm_blob = data_blob(local_lm_response, 24);
 
433
                
 
434
                /* We can't do an NT hash here, as the password needs to be
 
435
                   case insensitive */
 
436
                local_nt_blob = data_blob_null; 
 
437
                
 
438
        } else {
 
439
                local_lm_blob = data_blob_null; 
 
440
                local_nt_blob = data_blob_null; 
 
441
        }
 
442
        
 
443
        ret = make_user_info_map(
 
444
                user_info, smb_name, client_domain, 
 
445
                get_remote_machine_name(),
 
446
                local_lm_blob.data ? &local_lm_blob : NULL,
 
447
                local_nt_blob.data ? &local_nt_blob : NULL,
 
448
                NULL, NULL,
 
449
                plaintext_password.data ? &plaintext_password : NULL, 
 
450
                False);
 
451
        
 
452
        data_blob_free(&local_lm_blob);
 
453
        return NT_STATUS_IS_OK(ret) ? True : False;
 
454
}
 
455
 
 
456
/****************************************************************************
 
457
 Create an auth_usersupplied_data structure
 
458
****************************************************************************/
 
459
 
 
460
NTSTATUS make_user_info_for_reply_enc(auth_usersupplied_info **user_info, 
 
461
                                      const char *smb_name,
 
462
                                      const char *client_domain, 
 
463
                                      DATA_BLOB lm_resp, DATA_BLOB nt_resp)
 
464
{
 
465
        return make_user_info_map(user_info, smb_name, 
 
466
                                  client_domain, 
 
467
                                  get_remote_machine_name(), 
 
468
                                  lm_resp.data ? &lm_resp : NULL, 
 
469
                                  nt_resp.data ? &nt_resp : NULL, 
 
470
                                  NULL, NULL, NULL,
 
471
                                  True);
 
472
}
 
473
 
 
474
/****************************************************************************
 
475
 Create a guest user_info blob, for anonymous authenticaion.
 
476
****************************************************************************/
 
477
 
 
478
bool make_user_info_guest(auth_usersupplied_info **user_info) 
 
479
{
 
480
        NTSTATUS nt_status;
 
481
 
 
482
        nt_status = make_user_info(user_info, 
 
483
                                   "","", 
 
484
                                   "","", 
 
485
                                   "", 
 
486
                                   NULL, NULL, 
 
487
                                   NULL, NULL, 
 
488
                                   NULL,
 
489
                                   True);
 
490
                              
 
491
        return NT_STATUS_IS_OK(nt_status) ? True : False;
 
492
}
 
493
 
 
494
static int server_info_dtor(auth_serversupplied_info *server_info)
 
495
{
 
496
        TALLOC_FREE(server_info->sam_account);
 
497
        ZERO_STRUCTP(server_info);
 
498
        return 0;
 
499
}
 
500
 
 
501
/***************************************************************************
 
502
 Make a server_info struct. Free with TALLOC_FREE().
 
503
***************************************************************************/
 
504
 
 
505
static auth_serversupplied_info *make_server_info(TALLOC_CTX *mem_ctx)
 
506
{
 
507
        struct auth_serversupplied_info *result;
 
508
 
 
509
        result = TALLOC_ZERO_P(mem_ctx, auth_serversupplied_info);
 
510
        if (result == NULL) {
 
511
                DEBUG(0, ("talloc failed\n"));
 
512
                return NULL;
 
513
        }
 
514
 
 
515
        talloc_set_destructor(result, server_info_dtor);
 
516
 
 
517
        /* Initialise the uid and gid values to something non-zero
 
518
           which may save us from giving away root access if there
 
519
           is a bug in allocating these fields. */
 
520
 
 
521
        result->utok.uid = -1;
 
522
        result->utok.gid = -1;
 
523
        return result;
 
524
}
 
525
 
 
526
static char *sanitize_username(TALLOC_CTX *mem_ctx, const char *username)
 
527
{
 
528
        fstring tmp;
 
529
 
 
530
        alpha_strcpy(tmp, username, ". _-$", sizeof(tmp));
 
531
        return talloc_strdup(mem_ctx, tmp);
 
532
}
 
533
 
 
534
/***************************************************************************
 
535
 Is the incoming username our own machine account ?
 
536
 If so, the connection is almost certainly from winbindd.
 
537
***************************************************************************/
 
538
 
 
539
static bool is_our_machine_account(const char *username)
 
540
{
 
541
        bool ret;
 
542
        char *truncname = NULL;
 
543
        size_t ulen = strlen(username);
 
544
 
 
545
        if (ulen == 0 || username[ulen-1] != '$') {
 
546
                return false;
 
547
        }
 
548
        truncname = SMB_STRDUP(username);
 
549
        if (!truncname) {
 
550
                return false;
 
551
        }
 
552
        truncname[ulen-1] = '\0';
 
553
        ret = strequal(truncname, global_myname());
 
554
        SAFE_FREE(truncname);
 
555
        return ret;
 
556
}
 
557
 
 
558
/***************************************************************************
 
559
 Make (and fill) a user_info struct from a struct samu
 
560
***************************************************************************/
 
561
 
 
562
NTSTATUS make_server_info_sam(auth_serversupplied_info **server_info,
 
563
                              struct samu *sampass)
 
564
{
 
565
        struct passwd *pwd;
 
566
        gid_t *gids;
 
567
        auth_serversupplied_info *result;
 
568
        const char *username = pdb_get_username(sampass);
 
569
        NTSTATUS status;
 
570
 
 
571
        if ( !(result = make_server_info(NULL)) ) {
 
572
                return NT_STATUS_NO_MEMORY;
 
573
        }
 
574
 
 
575
        if ( !(pwd = getpwnam_alloc(result, username)) ) {
 
576
                DEBUG(1, ("User %s in passdb, but getpwnam() fails!\n",
 
577
                          pdb_get_username(sampass)));
 
578
                TALLOC_FREE(result);
 
579
                return NT_STATUS_NO_SUCH_USER;
 
580
        }
 
581
 
 
582
        result->sam_account = sampass;
 
583
        result->unix_name = pwd->pw_name;
 
584
        /* Ensure that we keep pwd->pw_name, because we will free pwd below */
 
585
        talloc_steal(result, pwd->pw_name);
 
586
        result->utok.gid = pwd->pw_gid;
 
587
        result->utok.uid = pwd->pw_uid;
 
588
 
 
589
        TALLOC_FREE(pwd);
 
590
 
 
591
        result->sanitized_username = sanitize_username(result,
 
592
                                                       result->unix_name);
 
593
        if (result->sanitized_username == NULL) {
 
594
                TALLOC_FREE(result);
 
595
                return NT_STATUS_NO_MEMORY;
 
596
        }
 
597
 
 
598
        if (IS_DC && is_our_machine_account(username)) {
 
599
                /*
 
600
                 * Ensure for a connection from our own
 
601
                 * machine account (from winbindd on a DC)
 
602
                 * there are no supplementary groups.
 
603
                 * Prevents loops in calling gid_to_sid().
 
604
                 */
 
605
                result->sids = NULL;
 
606
                gids = NULL;
 
607
                result->num_sids = 0;
 
608
 
 
609
                /*
 
610
                 * This is a hack of monstrous proportions.
 
611
                 * If we know it's winbindd talking to us,
 
612
                 * we know we must never recurse into it,
 
613
                 * so turn off contacting winbindd for this
 
614
                 * entire process. This will get fixed when
 
615
                 * winbindd doesn't need to talk to smbd on
 
616
                 * a PDC. JRA.
 
617
                 */
 
618
 
 
619
                (void)winbind_off();
 
620
 
 
621
                DEBUG(10, ("make_server_info_sam: our machine account %s "
 
622
                        "setting supplementary group list empty and "
 
623
                        "turning off winbindd requests.\n",
 
624
                        username));
 
625
        } else {
 
626
                status = pdb_enum_group_memberships(result, sampass,
 
627
                                            &result->sids, &gids,
 
628
                                            &result->num_sids);
 
629
 
 
630
                if (!NT_STATUS_IS_OK(status)) {
 
631
                        DEBUG(10, ("pdb_enum_group_memberships failed: %s\n",
 
632
                                   nt_errstr(status)));
 
633
                        result->sam_account = NULL; /* Don't free on error exit. */
 
634
                        TALLOC_FREE(result);
 
635
                        return status;
 
636
                }
 
637
        }
 
638
 
 
639
        /* For now we throw away the gids and convert via sid_to_gid
 
640
         * later. This needs fixing, but I'd like to get the code straight and
 
641
         * simple first. */
 
642
         
 
643
        TALLOC_FREE(gids);
 
644
 
 
645
        DEBUG(5,("make_server_info_sam: made server info for user %s -> %s\n",
 
646
                 pdb_get_username(sampass), result->unix_name));
 
647
 
 
648
        *server_info = result;
 
649
        /* Ensure that the sampass will be freed with the result */
 
650
        talloc_steal(result, sampass);
 
651
 
 
652
        return NT_STATUS_OK;
 
653
}
 
654
 
 
655
static NTSTATUS log_nt_token(NT_USER_TOKEN *token)
 
656
{
 
657
        TALLOC_CTX *frame = talloc_stackframe();
 
658
        char *command;
 
659
        char *group_sidstr;
 
660
        size_t i;
 
661
 
 
662
        if ((lp_log_nt_token_command() == NULL) ||
 
663
            (strlen(lp_log_nt_token_command()) == 0)) {
 
664
                TALLOC_FREE(frame);
 
665
                return NT_STATUS_OK;
 
666
        }
 
667
 
 
668
        group_sidstr = talloc_strdup(frame, "");
 
669
        for (i=1; i<token->num_sids; i++) {
 
670
                group_sidstr = talloc_asprintf(
 
671
                        frame, "%s %s", group_sidstr,
 
672
                        sid_string_talloc(frame, &token->user_sids[i]));
 
673
        }
 
674
 
 
675
        command = talloc_string_sub(
 
676
                frame, lp_log_nt_token_command(),
 
677
                "%s", sid_string_talloc(frame, &token->user_sids[0]));
 
678
        command = talloc_string_sub(frame, command, "%t", group_sidstr);
 
679
 
 
680
        if (command == NULL) {
 
681
                TALLOC_FREE(frame);
 
682
                return NT_STATUS_NO_MEMORY;
 
683
        }
 
684
 
 
685
        DEBUG(8, ("running command: [%s]\n", command));
 
686
        if (smbrun(command, NULL) != 0) {
 
687
                DEBUG(0, ("Could not log NT token\n"));
 
688
                TALLOC_FREE(frame);
 
689
                return NT_STATUS_ACCESS_DENIED;
 
690
        }
 
691
 
 
692
        TALLOC_FREE(frame);
 
693
        return NT_STATUS_OK;
 
694
}
 
695
 
 
696
/*
 
697
 * Create the token to use from server_info->sam_account and
 
698
 * server_info->sids (the info3/sam groups). Find the unix gids.
 
699
 */
 
700
 
 
701
NTSTATUS create_local_token(auth_serversupplied_info *server_info)
 
702
{
 
703
        NTSTATUS status;
 
704
        size_t i;
 
705
        struct dom_sid tmp_sid;
 
706
 
 
707
        /*
 
708
         * If winbind is not around, we can not make much use of the SIDs the
 
709
         * domain controller provided us with. Likewise if the user name was
 
710
         * mapped to some local unix user.
 
711
         */
 
712
 
 
713
        if (((lp_server_role() == ROLE_DOMAIN_MEMBER) && !winbind_ping()) ||
 
714
            (server_info->nss_token)) {
 
715
                status = create_token_from_username(server_info,
 
716
                                                    server_info->unix_name,
 
717
                                                    server_info->guest,
 
718
                                                    &server_info->utok.uid,
 
719
                                                    &server_info->utok.gid,
 
720
                                                    &server_info->unix_name,
 
721
                                                    &server_info->ptok);
 
722
 
 
723
        } else {
 
724
                server_info->ptok = create_local_nt_token(
 
725
                        server_info,
 
726
                        pdb_get_user_sid(server_info->sam_account),
 
727
                        server_info->guest,
 
728
                        server_info->num_sids, server_info->sids);
 
729
                status = server_info->ptok ?
 
730
                        NT_STATUS_OK : NT_STATUS_NO_SUCH_USER;
 
731
        }
 
732
 
 
733
        if (!NT_STATUS_IS_OK(status)) {
 
734
                return status;
 
735
        }
 
736
 
 
737
        /* Convert the SIDs to gids. */
 
738
 
 
739
        server_info->utok.ngroups = 0;
 
740
        server_info->utok.groups = NULL;
 
741
 
 
742
        /* Start at index 1, where the groups start. */
 
743
 
 
744
        for (i=1; i<server_info->ptok->num_sids; i++) {
 
745
                gid_t gid;
 
746
                DOM_SID *sid = &server_info->ptok->user_sids[i];
 
747
 
 
748
                if (!sid_to_gid(sid, &gid)) {
 
749
                        DEBUG(10, ("Could not convert SID %s to gid, "
 
750
                                   "ignoring it\n", sid_string_dbg(sid)));
 
751
                        continue;
 
752
                }
 
753
                add_gid_to_array_unique(server_info, gid,
 
754
                                        &server_info->utok.groups,
 
755
                                        &server_info->utok.ngroups);
 
756
        }
 
757
 
 
758
        /*
 
759
         * Add the "Unix Group" SID for each gid to catch mapped groups
 
760
         * and their Unix equivalent.  This is to solve the backwards
 
761
         * compatibility problem of 'valid users = +ntadmin' where
 
762
         * ntadmin has been paired with "Domain Admins" in the group
 
763
         * mapping table.  Otherwise smb.conf would need to be changed
 
764
         * to 'valid user = "Domain Admins"'.  --jerry
 
765
         *
 
766
         * For consistency we also add the "Unix User" SID,
 
767
         * so that the complete unix token is represented within
 
768
         * the nt token.
 
769
         */
 
770
 
 
771
        if (!uid_to_unix_users_sid(server_info->utok.uid, &tmp_sid)) {
 
772
                DEBUG(1,("create_local_token: Failed to create SID "
 
773
                        "for uid %u!\n", (unsigned int)server_info->utok.uid));
 
774
        }
 
775
        add_sid_to_array_unique(server_info->ptok, &tmp_sid,
 
776
                                &server_info->ptok->user_sids,
 
777
                                &server_info->ptok->num_sids);
 
778
 
 
779
        for ( i=0; i<server_info->utok.ngroups; i++ ) {
 
780
                if (!gid_to_unix_groups_sid( server_info->utok.groups[i], &tmp_sid ) ) {
 
781
                        DEBUG(1,("create_local_token: Failed to create SID "
 
782
                                "for gid %u!\n", (unsigned int)server_info->utok.groups[i]));
 
783
                        continue;
 
784
                }
 
785
                add_sid_to_array_unique(server_info->ptok, &tmp_sid,
 
786
                                        &server_info->ptok->user_sids,
 
787
                                        &server_info->ptok->num_sids);
 
788
        }
 
789
 
 
790
        debug_nt_user_token(DBGC_AUTH, 10, server_info->ptok);
 
791
        debug_unix_user_token(DBGC_AUTH, 10,
 
792
                              server_info->utok.uid,
 
793
                              server_info->utok.gid,
 
794
                              server_info->utok.ngroups,
 
795
                              server_info->utok.groups);
 
796
 
 
797
        status = log_nt_token(server_info->ptok);
 
798
        return status;
 
799
}
 
800
 
 
801
/*
 
802
 * Create an artificial NT token given just a username. (Initially intended
 
803
 * for force user)
 
804
 *
 
805
 * We go through lookup_name() to avoid problems we had with 'winbind use
 
806
 * default domain'.
 
807
 *
 
808
 * We have 3 cases:
 
809
 *
 
810
 * unmapped unix users: Go directly to nss to find the user's group.
 
811
 *
 
812
 * A passdb user: The list of groups is provided by pdb_enum_group_memberships.
 
813
 *
 
814
 * If the user is provided by winbind, the primary gid is set to "domain
 
815
 * users" of the user's domain. For an explanation why this is necessary, see
 
816
 * the thread starting at
 
817
 * http://lists.samba.org/archive/samba-technical/2006-January/044803.html.
 
818
 */
 
819
 
 
820
NTSTATUS create_token_from_username(TALLOC_CTX *mem_ctx, const char *username,
 
821
                                    bool is_guest,
 
822
                                    uid_t *uid, gid_t *gid,
 
823
                                    char **found_username,
 
824
                                    struct nt_user_token **token)
 
825
{
 
826
        NTSTATUS result = NT_STATUS_NO_SUCH_USER;
 
827
        TALLOC_CTX *tmp_ctx;
 
828
        DOM_SID user_sid;
 
829
        enum lsa_SidType type;
 
830
        gid_t *gids;
 
831
        DOM_SID *group_sids;
 
832
        DOM_SID unix_group_sid;
 
833
        size_t num_group_sids;
 
834
        size_t num_gids;
 
835
        size_t i;
 
836
 
 
837
        tmp_ctx = talloc_new(NULL);
 
838
        if (tmp_ctx == NULL) {
 
839
                DEBUG(0, ("talloc_new failed\n"));
 
840
                return NT_STATUS_NO_MEMORY;
 
841
        }
 
842
 
 
843
        if (!lookup_name_smbconf(tmp_ctx, username, LOOKUP_NAME_ALL,
 
844
                         NULL, NULL, &user_sid, &type)) {
 
845
                DEBUG(1, ("lookup_name_smbconf for %s failed\n", username));
 
846
                goto done;
 
847
        }
 
848
 
 
849
        if (type != SID_NAME_USER) {
 
850
                DEBUG(1, ("%s is a %s, not a user\n", username,
 
851
                          sid_type_lookup(type)));
 
852
                goto done;
 
853
        }
 
854
 
 
855
        if (sid_check_is_in_our_domain(&user_sid)) {
 
856
                bool ret;
 
857
 
 
858
                /* This is a passdb user, so ask passdb */
 
859
 
 
860
                struct samu *sam_acct = NULL;
 
861
 
 
862
                if ( !(sam_acct = samu_new( tmp_ctx )) ) {
 
863
                        result = NT_STATUS_NO_MEMORY;
 
864
                        goto done;
 
865
                }
 
866
 
 
867
                become_root();
 
868
                ret = pdb_getsampwsid(sam_acct, &user_sid);
 
869
                unbecome_root();
 
870
 
 
871
                if (!ret) {
 
872
                        DEBUG(1, ("pdb_getsampwsid(%s) for user %s failed\n",
 
873
                                  sid_string_dbg(&user_sid), username));
 
874
                        DEBUGADD(1, ("Fall back to unix user %s\n", username));
 
875
                        goto unix_user;
 
876
                }
 
877
 
 
878
                result = pdb_enum_group_memberships(tmp_ctx, sam_acct,
 
879
                                                    &group_sids, &gids,
 
880
                                                    &num_group_sids);
 
881
                if (!NT_STATUS_IS_OK(result)) {
 
882
                        DEBUG(10, ("enum_group_memberships failed for %s\n",
 
883
                                   username));
 
884
                        DEBUGADD(1, ("Fall back to unix user %s\n", username));
 
885
                        goto unix_user;
 
886
                }
 
887
 
 
888
                /* see the smb_panic() in pdb_default_enum_group_memberships */
 
889
                SMB_ASSERT(num_group_sids > 0); 
 
890
 
 
891
                *gid = gids[0];
 
892
 
 
893
                /* Ensure we're returning the found_username on the right context. */
 
894
                *found_username = talloc_strdup(mem_ctx,
 
895
                                                pdb_get_username(sam_acct));
 
896
 
 
897
                /*
 
898
                 * If the SID from lookup_name() was the guest sid, passdb knows
 
899
                 * about the mapping of guest sid to lp_guestaccount()
 
900
                 * username and will return the unix_pw info for a guest
 
901
                 * user. Use it if it's there, else lookup the *uid details
 
902
                 * using getpwnam_alloc(). See bug #6291 for details. JRA.
 
903
                 */
 
904
 
 
905
                /* We must always assign the *uid. */
 
906
                if (sam_acct->unix_pw == NULL) {
 
907
                        struct passwd *pwd = getpwnam_alloc(sam_acct, *found_username );
 
908
                        if (!pwd) {
 
909
                                DEBUG(10, ("getpwnam_alloc failed for %s\n",
 
910
                                        *found_username));
 
911
                                result = NT_STATUS_NO_SUCH_USER;
 
912
                                goto done;
 
913
                        }
 
914
                        result = samu_set_unix(sam_acct, pwd );
 
915
                        if (!NT_STATUS_IS_OK(result)) {
 
916
                                DEBUG(10, ("samu_set_unix failed for %s\n",
 
917
                                        *found_username));
 
918
                                result = NT_STATUS_NO_SUCH_USER;
 
919
                                goto done;
 
920
                        }
 
921
                }
 
922
                *uid = sam_acct->unix_pw->pw_uid;
 
923
 
 
924
        } else  if (sid_check_is_in_unix_users(&user_sid)) {
 
925
 
 
926
                /* This is a unix user not in passdb. We need to ask nss
 
927
                 * directly, without consulting passdb */
 
928
 
 
929
                struct passwd *pass;
 
930
 
 
931
                /*
 
932
                 * This goto target is used as a fallback for the passdb
 
933
                 * case. The concrete bug report is when passdb gave us an
 
934
                 * unmapped gid.
 
935
                 */
 
936
 
 
937
        unix_user:
 
938
 
 
939
                if (!sid_to_uid(&user_sid, uid)) {
 
940
                        DEBUG(1, ("unix_user case, sid_to_uid for %s (%s) failed\n",
 
941
                                  username, sid_string_dbg(&user_sid)));
 
942
                        result = NT_STATUS_NO_SUCH_USER;
 
943
                        goto done;
 
944
                }
 
945
 
 
946
                uid_to_unix_users_sid(*uid, &user_sid);
 
947
 
 
948
                pass = getpwuid_alloc(tmp_ctx, *uid);
 
949
                if (pass == NULL) {
 
950
                        DEBUG(1, ("getpwuid(%u) for user %s failed\n",
 
951
                                  (unsigned int)*uid, username));
 
952
                        goto done;
 
953
                }
 
954
 
 
955
                if (!getgroups_unix_user(tmp_ctx, username, pass->pw_gid,
 
956
                                         &gids, &num_group_sids)) {
 
957
                        DEBUG(1, ("getgroups_unix_user for user %s failed\n",
 
958
                                  username));
 
959
                        goto done;
 
960
                }
 
961
 
 
962
                if (num_group_sids) {
 
963
                        group_sids = TALLOC_ARRAY(tmp_ctx, DOM_SID, num_group_sids);
 
964
                        if (group_sids == NULL) {
 
965
                                DEBUG(1, ("TALLOC_ARRAY failed\n"));
 
966
                                result = NT_STATUS_NO_MEMORY;
 
967
                                goto done;
 
968
                        }
 
969
                } else {
 
970
                        group_sids = NULL;
 
971
                }
 
972
 
 
973
                for (i=0; i<num_group_sids; i++) {
 
974
                        gid_to_sid(&group_sids[i], gids[i]);
 
975
                }
 
976
 
 
977
                /* In getgroups_unix_user we always set the primary gid */
 
978
                SMB_ASSERT(num_group_sids > 0); 
 
979
 
 
980
                *gid = gids[0];
 
981
 
 
982
                /* Ensure we're returning the found_username on the right context. */
 
983
                *found_username = talloc_strdup(mem_ctx, pass->pw_name);
 
984
        } else {
 
985
 
 
986
                /* This user is from winbind, force the primary gid to the
 
987
                 * user's "domain users" group. Under certain circumstances
 
988
                 * (user comes from NT4), this might be a loss of
 
989
                 * information. But we can not rely on winbind getting the
 
990
                 * correct info. AD might prohibit winbind looking up that
 
991
                 * information. */
 
992
 
 
993
                uint32 dummy;
 
994
 
 
995
                /* We must always assign the *uid. */
 
996
                if (!sid_to_uid(&user_sid, uid)) {
 
997
                        DEBUG(1, ("winbindd case, sid_to_uid for %s (%s) failed\n",
 
998
                                  username, sid_string_dbg(&user_sid)));
 
999
                        result = NT_STATUS_NO_SUCH_USER;
 
1000
                        goto done;
 
1001
                }
 
1002
 
 
1003
                num_group_sids = 1;
 
1004
                group_sids = TALLOC_ARRAY(tmp_ctx, DOM_SID, num_group_sids);
 
1005
                if (group_sids == NULL) {
 
1006
                        DEBUG(1, ("TALLOC_ARRAY failed\n"));
 
1007
                        result = NT_STATUS_NO_MEMORY;
 
1008
                        goto done;
 
1009
                }
 
1010
 
 
1011
                sid_copy(&group_sids[0], &user_sid);
 
1012
                sid_split_rid(&group_sids[0], &dummy);
 
1013
                sid_append_rid(&group_sids[0], DOMAIN_GROUP_RID_USERS);
 
1014
 
 
1015
                if (!sid_to_gid(&group_sids[0], gid)) {
 
1016
                        DEBUG(1, ("sid_to_gid(%s) failed\n",
 
1017
                                  sid_string_dbg(&group_sids[0])));
 
1018
                        goto done;
 
1019
                }
 
1020
 
 
1021
                gids = gid;
 
1022
 
 
1023
                /* Ensure we're returning the found_username on the right context. */
 
1024
                *found_username = talloc_strdup(mem_ctx, username);
 
1025
        }
 
1026
 
 
1027
        /* Add the "Unix Group" SID for each gid to catch mapped groups
 
1028
           and their Unix equivalent.  This is to solve the backwards
 
1029
           compatibility problem of 'valid users = +ntadmin' where
 
1030
           ntadmin has been paired with "Domain Admins" in the group
 
1031
           mapping table.  Otherwise smb.conf would need to be changed
 
1032
           to 'valid user = "Domain Admins"'.  --jerry */
 
1033
 
 
1034
        num_gids = num_group_sids;
 
1035
        for ( i=0; i<num_gids; i++ ) {
 
1036
                gid_t high, low;
 
1037
 
 
1038
                /* don't pickup anything managed by Winbind */
 
1039
 
 
1040
                if ( lp_idmap_gid(&low, &high) && (gids[i] >= low) && (gids[i] <= high) )
 
1041
                        continue;
 
1042
 
 
1043
                if ( !gid_to_unix_groups_sid( gids[i], &unix_group_sid ) ) {
 
1044
                        DEBUG(1,("create_token_from_username: Failed to create SID "
 
1045
                                "for gid %u!\n", (unsigned int)gids[i]));
 
1046
                        continue;
 
1047
                }
 
1048
                result = add_sid_to_array_unique(tmp_ctx, &unix_group_sid,
 
1049
                                                 &group_sids, &num_group_sids);
 
1050
                if (!NT_STATUS_IS_OK(result)) {
 
1051
                        goto done;
 
1052
                }
 
1053
        }
 
1054
 
 
1055
        /* Ensure we're creating the nt_token on the right context. */
 
1056
        *token = create_local_nt_token(mem_ctx, &user_sid,
 
1057
                                       is_guest, num_group_sids, group_sids);
 
1058
 
 
1059
        if ((*token == NULL) || (*found_username == NULL)) {
 
1060
                result = NT_STATUS_NO_MEMORY;
 
1061
                goto done;
 
1062
        }
 
1063
 
 
1064
        result = NT_STATUS_OK;
 
1065
 done:
 
1066
        TALLOC_FREE(tmp_ctx);
 
1067
        return result;
 
1068
}
 
1069
 
 
1070
/***************************************************************************
 
1071
 Build upon create_token_from_username:
 
1072
 
 
1073
 Expensive helper function to figure out whether a user given its name is
 
1074
 member of a particular group.
 
1075
***************************************************************************/
 
1076
 
 
1077
bool user_in_group_sid(const char *username, const DOM_SID *group_sid)
 
1078
{
 
1079
        NTSTATUS status;
 
1080
        uid_t uid;
 
1081
        gid_t gid;
 
1082
        char *found_username;
 
1083
        struct nt_user_token *token;
 
1084
        bool result;
 
1085
 
 
1086
        TALLOC_CTX *mem_ctx;
 
1087
 
 
1088
        mem_ctx = talloc_new(NULL);
 
1089
        if (mem_ctx == NULL) {
 
1090
                DEBUG(0, ("talloc_new failed\n"));
 
1091
                return False;
 
1092
        }
 
1093
 
 
1094
        status = create_token_from_username(mem_ctx, username, False,
 
1095
                                            &uid, &gid, &found_username,
 
1096
                                            &token);
 
1097
 
 
1098
        if (!NT_STATUS_IS_OK(status)) {
 
1099
                DEBUG(10, ("could not create token for %s\n", username));
 
1100
                return False;
 
1101
        }
 
1102
 
 
1103
        result = nt_token_check_sid(group_sid, token);
 
1104
 
 
1105
        TALLOC_FREE(mem_ctx);
 
1106
        return result;
 
1107
        
 
1108
}
 
1109
 
 
1110
bool user_in_group(const char *username, const char *groupname)
 
1111
{
 
1112
        TALLOC_CTX *mem_ctx;
 
1113
        DOM_SID group_sid;
 
1114
        bool ret;
 
1115
 
 
1116
        mem_ctx = talloc_new(NULL);
 
1117
        if (mem_ctx == NULL) {
 
1118
                DEBUG(0, ("talloc_new failed\n"));
 
1119
                return False;
 
1120
        }
 
1121
 
 
1122
        ret = lookup_name(mem_ctx, groupname, LOOKUP_NAME_ALL,
 
1123
                          NULL, NULL, &group_sid, NULL);
 
1124
        TALLOC_FREE(mem_ctx);
 
1125
 
 
1126
        if (!ret) {
 
1127
                DEBUG(10, ("lookup_name for (%s) failed.\n", groupname));
 
1128
                return False;
 
1129
        }
 
1130
 
 
1131
        return user_in_group_sid(username, &group_sid);
 
1132
}
 
1133
 
 
1134
/***************************************************************************
 
1135
 Make (and fill) a server_info struct from a 'struct passwd' by conversion
 
1136
 to a struct samu
 
1137
***************************************************************************/
 
1138
 
 
1139
NTSTATUS make_server_info_pw(auth_serversupplied_info **server_info, 
 
1140
                             char *unix_username,
 
1141
                             struct passwd *pwd)
 
1142
{
 
1143
        NTSTATUS status;
 
1144
        struct samu *sampass = NULL;
 
1145
        gid_t *gids;
 
1146
        char *qualified_name = NULL;
 
1147
        TALLOC_CTX *mem_ctx = NULL;
 
1148
        DOM_SID u_sid;
 
1149
        enum lsa_SidType type;
 
1150
        auth_serversupplied_info *result;
 
1151
        
 
1152
        if ( !(sampass = samu_new( NULL )) ) {
 
1153
                return NT_STATUS_NO_MEMORY;
 
1154
        }
 
1155
        
 
1156
        status = samu_set_unix( sampass, pwd );
 
1157
        if (!NT_STATUS_IS_OK(status)) {
 
1158
                return status;
 
1159
        }
 
1160
 
 
1161
        result = make_server_info(NULL);
 
1162
        if (result == NULL) {
 
1163
                TALLOC_FREE(sampass);
 
1164
                return NT_STATUS_NO_MEMORY;
 
1165
        }
 
1166
 
 
1167
        result->sam_account = sampass;
 
1168
 
 
1169
        result->unix_name = talloc_strdup(result, unix_username);
 
1170
        result->sanitized_username = sanitize_username(result, unix_username);
 
1171
 
 
1172
        if ((result->unix_name == NULL)
 
1173
            || (result->sanitized_username == NULL)) {
 
1174
                TALLOC_FREE(sampass);
 
1175
                TALLOC_FREE(result);
 
1176
                return NT_STATUS_NO_MEMORY;
 
1177
        }
 
1178
 
 
1179
        result->utok.uid = pwd->pw_uid;
 
1180
        result->utok.gid = pwd->pw_gid;
 
1181
 
 
1182
        status = pdb_enum_group_memberships(result, sampass,
 
1183
                                            &result->sids, &gids,
 
1184
                                            &result->num_sids);
 
1185
 
 
1186
        if (!NT_STATUS_IS_OK(status)) {
 
1187
                DEBUG(10, ("pdb_enum_group_memberships failed: %s\n",
 
1188
                           nt_errstr(status)));
 
1189
                TALLOC_FREE(result);
 
1190
                return status;
 
1191
        }
 
1192
 
 
1193
        /*
 
1194
         * The SID returned in server_info->sam_account is based
 
1195
         * on our SAM sid even though for a pure UNIX account this should
 
1196
         * not be the case as it doesn't really exist in the SAM db.
 
1197
         * This causes lookups on "[in]valid users" to fail as they
 
1198
         * will lookup this name as a "Unix User" SID to check against
 
1199
         * the user token. Fix this by adding the "Unix User"\unix_username
 
1200
         * SID to the sid array. The correct fix should probably be
 
1201
         * changing the server_info->sam_account user SID to be a
 
1202
         * S-1-22 Unix SID, but this might break old configs where
 
1203
         * plaintext passwords were used with no SAM backend.
 
1204
         */
 
1205
 
 
1206
        mem_ctx = talloc_init("make_server_info_pw_tmp");
 
1207
        if (!mem_ctx) {
 
1208
                TALLOC_FREE(result);
 
1209
                return NT_STATUS_NO_MEMORY;
 
1210
        }
 
1211
 
 
1212
        qualified_name = talloc_asprintf(mem_ctx, "%s\\%s",
 
1213
                                        unix_users_domain_name(),
 
1214
                                        unix_username );
 
1215
        if (!qualified_name) {
 
1216
                TALLOC_FREE(result);
 
1217
                TALLOC_FREE(mem_ctx);
 
1218
                return NT_STATUS_NO_MEMORY;
 
1219
        }
 
1220
 
 
1221
        if (!lookup_name(mem_ctx, qualified_name, LOOKUP_NAME_ALL,
 
1222
                                                NULL, NULL,
 
1223
                                                &u_sid, &type)) {
 
1224
                TALLOC_FREE(result);
 
1225
                TALLOC_FREE(mem_ctx);
 
1226
                return NT_STATUS_NO_SUCH_USER;
 
1227
        }
 
1228
 
 
1229
        TALLOC_FREE(mem_ctx);
 
1230
 
 
1231
        if (type != SID_NAME_USER) {
 
1232
                TALLOC_FREE(result);
 
1233
                return NT_STATUS_NO_SUCH_USER;
 
1234
        }
 
1235
 
 
1236
        status = add_sid_to_array_unique(result, &u_sid,
 
1237
                                         &result->sids,
 
1238
                                         &result->num_sids);
 
1239
        if (!NT_STATUS_IS_OK(status)) {
 
1240
                TALLOC_FREE(result);
 
1241
                return status;
 
1242
        }
 
1243
 
 
1244
        /* For now we throw away the gids and convert via sid_to_gid
 
1245
         * later. This needs fixing, but I'd like to get the code straight and
 
1246
         * simple first. */
 
1247
        TALLOC_FREE(gids);
 
1248
 
 
1249
        *server_info = result;
 
1250
 
 
1251
        return NT_STATUS_OK;
 
1252
}
 
1253
 
 
1254
/***************************************************************************
 
1255
 Make (and fill) a user_info struct for a guest login.
 
1256
 This *must* succeed for smbd to start. If there is no mapping entry for
 
1257
 the guest gid, then create one.
 
1258
***************************************************************************/
 
1259
 
 
1260
static NTSTATUS make_new_server_info_guest(auth_serversupplied_info **server_info)
 
1261
{
 
1262
        NTSTATUS status;
 
1263
        struct samu *sampass = NULL;
 
1264
        DOM_SID guest_sid;
 
1265
        bool ret;
 
1266
        char zeros[16];
 
1267
        fstring tmp;
 
1268
 
 
1269
        if ( !(sampass = samu_new( NULL )) ) {
 
1270
                return NT_STATUS_NO_MEMORY;
 
1271
        }
 
1272
 
 
1273
        sid_copy(&guest_sid, get_global_sam_sid());
 
1274
        sid_append_rid(&guest_sid, DOMAIN_USER_RID_GUEST);
 
1275
 
 
1276
        become_root();
 
1277
        ret = pdb_getsampwsid(sampass, &guest_sid);
 
1278
        unbecome_root();
 
1279
 
 
1280
        if (!ret) {
 
1281
                TALLOC_FREE(sampass);
 
1282
                return NT_STATUS_NO_SUCH_USER;
 
1283
        }
 
1284
 
 
1285
        status = make_server_info_sam(server_info, sampass);
 
1286
        if (!NT_STATUS_IS_OK(status)) {
 
1287
                TALLOC_FREE(sampass);
 
1288
                return status;
 
1289
        }
 
1290
        
 
1291
        (*server_info)->guest = True;
 
1292
 
 
1293
        status = create_local_token(*server_info);
 
1294
        if (!NT_STATUS_IS_OK(status)) {
 
1295
                DEBUG(10, ("create_local_token failed: %s\n",
 
1296
                           nt_errstr(status)));
 
1297
                return status;
 
1298
        }
 
1299
 
 
1300
        /* annoying, but the Guest really does have a session key, and it is
 
1301
           all zeros! */
 
1302
        ZERO_STRUCT(zeros);
 
1303
        (*server_info)->user_session_key = data_blob(zeros, sizeof(zeros));
 
1304
        (*server_info)->lm_session_key = data_blob(zeros, sizeof(zeros));
 
1305
 
 
1306
        alpha_strcpy(tmp, pdb_get_username(sampass), ". _-$", sizeof(tmp));
 
1307
        (*server_info)->sanitized_username = talloc_strdup(*server_info, tmp);
 
1308
 
 
1309
        return NT_STATUS_OK;
 
1310
}
 
1311
 
 
1312
/****************************************************************************
 
1313
  Fake a auth_serversupplied_info just from a username
 
1314
****************************************************************************/
 
1315
 
 
1316
NTSTATUS make_serverinfo_from_username(TALLOC_CTX *mem_ctx,
 
1317
                                       const char *username,
 
1318
                                       bool is_guest,
 
1319
                                       struct auth_serversupplied_info **presult)
 
1320
{
 
1321
        struct auth_serversupplied_info *result;
 
1322
        struct passwd *pwd;
 
1323
        NTSTATUS status;
 
1324
 
 
1325
        pwd = getpwnam_alloc(talloc_tos(), username);
 
1326
        if (pwd == NULL) {
 
1327
                return NT_STATUS_NO_SUCH_USER;
 
1328
        }
 
1329
 
 
1330
        status = make_server_info_pw(&result, pwd->pw_name, pwd);
 
1331
 
 
1332
        TALLOC_FREE(pwd);
 
1333
 
 
1334
        if (!NT_STATUS_IS_OK(status)) {
 
1335
                return status;
 
1336
        }
 
1337
 
 
1338
        result->nss_token = true;
 
1339
        result->guest = is_guest;
 
1340
 
 
1341
        status = create_local_token(result);
 
1342
 
 
1343
        if (!NT_STATUS_IS_OK(status)) {
 
1344
                TALLOC_FREE(result);
 
1345
                return status;
 
1346
        }
 
1347
 
 
1348
        *presult = result;
 
1349
        return NT_STATUS_OK;
 
1350
}
 
1351
 
 
1352
 
 
1353
struct auth_serversupplied_info *copy_serverinfo(TALLOC_CTX *mem_ctx,
 
1354
                                                 const auth_serversupplied_info *src)
 
1355
{
 
1356
        auth_serversupplied_info *dst;
 
1357
 
 
1358
        dst = make_server_info(mem_ctx);
 
1359
        if (dst == NULL) {
 
1360
                return NULL;
 
1361
        }
 
1362
 
 
1363
        dst->guest = src->guest;
 
1364
        dst->utok.uid = src->utok.uid;
 
1365
        dst->utok.gid = src->utok.gid;
 
1366
        dst->utok.ngroups = src->utok.ngroups;
 
1367
        if (src->utok.ngroups != 0) {
 
1368
                dst->utok.groups = (gid_t *)TALLOC_MEMDUP(
 
1369
                        dst, src->utok.groups,
 
1370
                        sizeof(gid_t)*dst->utok.ngroups);
 
1371
        } else {
 
1372
                dst->utok.groups = NULL;
 
1373
        }
 
1374
 
 
1375
        if (src->ptok) {
 
1376
                dst->ptok = dup_nt_token(dst, src->ptok);
 
1377
                if (!dst->ptok) {
 
1378
                        TALLOC_FREE(dst);
 
1379
                        return NULL;
 
1380
                }
 
1381
        }
 
1382
        
 
1383
        dst->user_session_key = data_blob_talloc( dst, src->user_session_key.data,
 
1384
                                                src->user_session_key.length);
 
1385
 
 
1386
        dst->lm_session_key = data_blob_talloc(dst, src->lm_session_key.data,
 
1387
                                                src->lm_session_key.length);
 
1388
 
 
1389
        dst->sam_account = samu_new(NULL);
 
1390
        if (!dst->sam_account) {
 
1391
                TALLOC_FREE(dst);
 
1392
                return NULL;
 
1393
        }
 
1394
 
 
1395
        if (!pdb_copy_sam_account(dst->sam_account, src->sam_account)) {
 
1396
                TALLOC_FREE(dst);
 
1397
                return NULL;
 
1398
        }
 
1399
        
 
1400
        dst->pam_handle = NULL;
 
1401
        dst->unix_name = talloc_strdup(dst, src->unix_name);
 
1402
        if (!dst->unix_name) {
 
1403
                TALLOC_FREE(dst);
 
1404
                return NULL;
 
1405
        }
 
1406
 
 
1407
        dst->sanitized_username = talloc_strdup(dst, src->sanitized_username);
 
1408
        if (!dst->sanitized_username) {
 
1409
                TALLOC_FREE(dst);
 
1410
                return NULL;
 
1411
        }
 
1412
 
 
1413
        return dst;
 
1414
}
 
1415
 
 
1416
/*
 
1417
 * Set a new session key. Used in the rpc server where we have to override the
 
1418
 * SMB level session key with SystemLibraryDTC
 
1419
 */
 
1420
 
 
1421
bool server_info_set_session_key(struct auth_serversupplied_info *info,
 
1422
                                 DATA_BLOB session_key)
 
1423
{
 
1424
        TALLOC_FREE(info->user_session_key.data);
 
1425
 
 
1426
        info->user_session_key = data_blob_talloc(
 
1427
                info, session_key.data, session_key.length);
 
1428
 
 
1429
        return (info->user_session_key.data != NULL);
 
1430
}
 
1431
 
 
1432
static auth_serversupplied_info *guest_info = NULL;
 
1433
 
 
1434
bool init_guest_info(void)
 
1435
{
 
1436
        if (guest_info != NULL)
 
1437
                return True;
 
1438
 
 
1439
        return NT_STATUS_IS_OK(make_new_server_info_guest(&guest_info));
 
1440
}
 
1441
 
 
1442
NTSTATUS make_server_info_guest(TALLOC_CTX *mem_ctx,
 
1443
                                auth_serversupplied_info **server_info)
 
1444
{
 
1445
        *server_info = copy_serverinfo(mem_ctx, guest_info);
 
1446
        return (*server_info != NULL) ? NT_STATUS_OK : NT_STATUS_NO_MEMORY;
 
1447
}
 
1448
 
 
1449
bool copy_current_user(struct current_user *dst, struct current_user *src)
 
1450
{
 
1451
        gid_t *groups;
 
1452
        NT_USER_TOKEN *nt_token;
 
1453
 
 
1454
        groups = (gid_t *)memdup(src->ut.groups,
 
1455
                                 sizeof(gid_t) * src->ut.ngroups);
 
1456
        if ((src->ut.ngroups != 0) && (groups == NULL)) {
 
1457
                return False;
 
1458
        }
 
1459
 
 
1460
        nt_token = dup_nt_token(NULL, src->nt_user_token);
 
1461
        if (nt_token == NULL) {
 
1462
                SAFE_FREE(groups);
 
1463
                return False;
 
1464
        }
 
1465
 
 
1466
        dst->conn = src->conn;
 
1467
        dst->vuid = src->vuid;
 
1468
        dst->ut.uid = src->ut.uid;
 
1469
        dst->ut.gid = src->ut.gid;
 
1470
        dst->ut.ngroups = src->ut.ngroups;
 
1471
        dst->ut.groups = groups;
 
1472
        dst->nt_user_token = nt_token;
 
1473
        return True;
 
1474
}
 
1475
 
 
1476
/***************************************************************************
 
1477
 Purely internal function for make_server_info_info3
 
1478
 Fill the sam account from getpwnam
 
1479
***************************************************************************/
 
1480
static NTSTATUS fill_sam_account(TALLOC_CTX *mem_ctx, 
 
1481
                                 const char *domain,
 
1482
                                 const char *username,
 
1483
                                 char **found_username,
 
1484
                                 uid_t *uid, gid_t *gid,
 
1485
                                 struct samu *account,
 
1486
                                 bool *username_was_mapped)
 
1487
{
 
1488
        NTSTATUS nt_status;
 
1489
        fstring dom_user, lower_username;
 
1490
        fstring real_username;
 
1491
        struct passwd *passwd;
 
1492
 
 
1493
        fstrcpy( lower_username, username );
 
1494
        strlower_m( lower_username );
 
1495
 
 
1496
        fstr_sprintf(dom_user, "%s%c%s", domain, *lp_winbind_separator(), 
 
1497
                lower_username);
 
1498
 
 
1499
        /* Get the passwd struct.  Try to create the account is necessary. */
 
1500
 
 
1501
        *username_was_mapped = map_username( dom_user );
 
1502
 
 
1503
        if ( !(passwd = smb_getpwnam( NULL, dom_user, real_username, True )) )
 
1504
                return NT_STATUS_NO_SUCH_USER;
 
1505
 
 
1506
        *uid = passwd->pw_uid;
 
1507
        *gid = passwd->pw_gid;
 
1508
 
 
1509
        /* This is pointless -- there is no suport for differing 
 
1510
           unix and windows names.  Make sure to always store the 
 
1511
           one we actually looked up and succeeded. Have I mentioned
 
1512
           why I hate the 'winbind use default domain' parameter?   
 
1513
                                         --jerry              */
 
1514
           
 
1515
        *found_username = talloc_strdup( mem_ctx, real_username );
 
1516
        
 
1517
        DEBUG(5,("fill_sam_account: located username was [%s]\n", *found_username));
 
1518
 
 
1519
        nt_status = samu_set_unix( account, passwd );
 
1520
        
 
1521
        TALLOC_FREE(passwd);
 
1522
        
 
1523
        return nt_status;
 
1524
}
 
1525
 
 
1526
/****************************************************************************
 
1527
 Wrapper to allow the getpwnam() call to strip the domain name and 
 
1528
 try again in case a local UNIX user is already there.  Also run through 
 
1529
 the username if we fallback to the username only.
 
1530
 ****************************************************************************/
 
1531
 
 
1532
struct passwd *smb_getpwnam( TALLOC_CTX *mem_ctx, char *domuser,
 
1533
                             fstring save_username, bool create )
 
1534
{
 
1535
        struct passwd *pw = NULL;
 
1536
        char *p;
 
1537
        fstring username;
 
1538
        
 
1539
        /* we only save a copy of the username it has been mangled 
 
1540
           by winbindd use default domain */
 
1541
           
 
1542
        save_username[0] = '\0';
 
1543
           
 
1544
        /* don't call map_username() here since it has to be done higher 
 
1545
           up the stack so we don't call it mutliple times */
 
1546
 
 
1547
        fstrcpy( username, domuser );
 
1548
        
 
1549
        p = strchr_m( username, *lp_winbind_separator() );
 
1550
        
 
1551
        /* code for a DOMAIN\user string */
 
1552
        
 
1553
        if ( p ) {
 
1554
                fstring strip_username;
 
1555
 
 
1556
                pw = Get_Pwnam_alloc( mem_ctx, domuser );
 
1557
                if ( pw ) {     
 
1558
                        /* make sure we get the case of the username correct */
 
1559
                        /* work around 'winbind use default domain = yes' */
 
1560
 
 
1561
                        if ( !strchr_m( pw->pw_name, *lp_winbind_separator() ) ) {
 
1562
                                char *domain;
 
1563
                                
 
1564
                                /* split the domain and username into 2 strings */
 
1565
                                *p = '\0';
 
1566
                                domain = username;
 
1567
 
 
1568
                                fstr_sprintf(save_username, "%s%c%s", domain, *lp_winbind_separator(), pw->pw_name);
 
1569
                        }
 
1570
                        else
 
1571
                                fstrcpy( save_username, pw->pw_name );
 
1572
 
 
1573
                        /* whew -- done! */             
 
1574
                        return pw;
 
1575
                }
 
1576
 
 
1577
                /* setup for lookup of just the username */
 
1578
                /* remember that p and username are overlapping memory */
 
1579
 
 
1580
                p++;
 
1581
                fstrcpy( strip_username, p );
 
1582
                fstrcpy( username, strip_username );
 
1583
        }
 
1584
        
 
1585
        /* just lookup a plain username */
 
1586
        
 
1587
        pw = Get_Pwnam_alloc(mem_ctx, username);
 
1588
                
 
1589
        /* Create local user if requested but only if winbindd
 
1590
           is not running.  We need to protect against cases
 
1591
           where winbindd is failing and then prematurely
 
1592
           creating users in /etc/passwd */
 
1593
        
 
1594
        if ( !pw && create && !winbind_ping() ) {
 
1595
                /* Don't add a machine account. */
 
1596
                if (username[strlen(username)-1] == '$')
 
1597
                        return NULL;
 
1598
 
 
1599
                _smb_create_user(NULL, username, NULL);
 
1600
                pw = Get_Pwnam_alloc(mem_ctx, username);
 
1601
        }
 
1602
        
 
1603
        /* one last check for a valid passwd struct */
 
1604
        
 
1605
        if ( pw )
 
1606
                fstrcpy( save_username, pw->pw_name );
 
1607
 
 
1608
        return pw;
 
1609
}
 
1610
 
 
1611
/***************************************************************************
 
1612
 Make a server_info struct from the info3 returned by a domain logon 
 
1613
***************************************************************************/
 
1614
 
 
1615
NTSTATUS make_server_info_info3(TALLOC_CTX *mem_ctx, 
 
1616
                                const char *sent_nt_username,
 
1617
                                const char *domain,
 
1618
                                auth_serversupplied_info **server_info, 
 
1619
                                struct netr_SamInfo3 *info3)
 
1620
{
 
1621
        char zeros[16];
 
1622
 
 
1623
        NTSTATUS nt_status = NT_STATUS_OK;
 
1624
        char *found_username = NULL;
 
1625
        const char *nt_domain;
 
1626
        const char *nt_username;
 
1627
        struct samu *sam_account = NULL;
 
1628
        DOM_SID user_sid;
 
1629
        DOM_SID group_sid;
 
1630
        bool username_was_mapped;
 
1631
 
 
1632
        uid_t uid = (uid_t)-1;
 
1633
        gid_t gid = (gid_t)-1;
 
1634
 
 
1635
        auth_serversupplied_info *result;
 
1636
 
 
1637
        /* 
 
1638
           Here is where we should check the list of
 
1639
           trusted domains, and verify that the SID 
 
1640
           matches.
 
1641
        */
 
1642
 
 
1643
        sid_copy(&user_sid, info3->base.domain_sid);
 
1644
        if (!sid_append_rid(&user_sid, info3->base.rid)) {
 
1645
                return NT_STATUS_INVALID_PARAMETER;
 
1646
        }
 
1647
        
 
1648
        sid_copy(&group_sid, info3->base.domain_sid);
 
1649
        if (!sid_append_rid(&group_sid, info3->base.primary_gid)) {
 
1650
                return NT_STATUS_INVALID_PARAMETER;
 
1651
        }
 
1652
 
 
1653
        nt_username = talloc_strdup(mem_ctx, info3->base.account_name.string);
 
1654
        if (!nt_username) {
 
1655
                /* If the server didn't give us one, just use the one we sent
 
1656
                 * them */
 
1657
                nt_username = sent_nt_username;
 
1658
        }
 
1659
 
 
1660
        nt_domain = talloc_strdup(mem_ctx, info3->base.domain.string);
 
1661
        if (!nt_domain) {
 
1662
                /* If the server didn't give us one, just use the one we sent
 
1663
                 * them */
 
1664
                nt_domain = domain;
 
1665
        }
 
1666
        
 
1667
        /* try to fill the SAM account..  If getpwnam() fails, then try the 
 
1668
           add user script (2.2.x behavior).
 
1669
 
 
1670
           We use the _unmapped_ username here in an attempt to provide
 
1671
           consistent username mapping behavior between kerberos and NTLM[SSP]
 
1672
           authentication in domain mode security.  I.E. Username mapping
 
1673
           should be applied to the fully qualified username
 
1674
           (e.g. DOMAIN\user) and not just the login name.  Yes this means we
 
1675
           called map_username() unnecessarily in make_user_info_map() but
 
1676
           that is how the current code is designed.  Making the change here
 
1677
           is the least disruptive place.  -- jerry */
 
1678
           
 
1679
        if ( !(sam_account = samu_new( NULL )) ) {
 
1680
                return NT_STATUS_NO_MEMORY;
 
1681
        }
 
1682
 
 
1683
        /* this call will try to create the user if necessary */
 
1684
 
 
1685
        nt_status = fill_sam_account(mem_ctx, nt_domain, sent_nt_username,
 
1686
                                     &found_username, &uid, &gid, sam_account,
 
1687
                                     &username_was_mapped);
 
1688
 
 
1689
        
 
1690
        /* if we still don't have a valid unix account check for 
 
1691
          'map to guest = bad uid' */
 
1692
          
 
1693
        if (!NT_STATUS_IS_OK(nt_status)) {
 
1694
                TALLOC_FREE( sam_account );
 
1695
                if ( lp_map_to_guest() == MAP_TO_GUEST_ON_BAD_UID ) {
 
1696
                        make_server_info_guest(NULL, server_info);
 
1697
                        return NT_STATUS_OK;
 
1698
                }
 
1699
                return nt_status;
 
1700
        }
 
1701
                
 
1702
        if (!pdb_set_nt_username(sam_account, nt_username, PDB_CHANGED)) {
 
1703
                TALLOC_FREE(sam_account);
 
1704
                return NT_STATUS_NO_MEMORY;
 
1705
        }
 
1706
 
 
1707
        if (!pdb_set_username(sam_account, nt_username, PDB_CHANGED)) {
 
1708
                TALLOC_FREE(sam_account);
 
1709
                return NT_STATUS_NO_MEMORY;
 
1710
        }
 
1711
 
 
1712
        if (!pdb_set_domain(sam_account, nt_domain, PDB_CHANGED)) {
 
1713
                TALLOC_FREE(sam_account);
 
1714
                return NT_STATUS_NO_MEMORY;
 
1715
        }
 
1716
 
 
1717
        if (!pdb_set_user_sid(sam_account, &user_sid, PDB_CHANGED)) {
 
1718
                TALLOC_FREE(sam_account);
 
1719
                return NT_STATUS_UNSUCCESSFUL;
 
1720
        }
 
1721
 
 
1722
        if (!pdb_set_group_sid(sam_account, &group_sid, PDB_CHANGED)) {
 
1723
                TALLOC_FREE(sam_account);
 
1724
                return NT_STATUS_UNSUCCESSFUL;
 
1725
        }
 
1726
 
 
1727
        if (!pdb_set_fullname(sam_account,
 
1728
                              info3->base.full_name.string,
 
1729
                              PDB_CHANGED)) {
 
1730
                TALLOC_FREE(sam_account);
 
1731
                return NT_STATUS_NO_MEMORY;
 
1732
        }
 
1733
 
 
1734
        if (!pdb_set_logon_script(sam_account,
 
1735
                                  info3->base.logon_script.string,
 
1736
                                  PDB_CHANGED)) {
 
1737
                TALLOC_FREE(sam_account);
 
1738
                return NT_STATUS_NO_MEMORY;
 
1739
        }
 
1740
 
 
1741
        if (!pdb_set_profile_path(sam_account,
 
1742
                                  info3->base.profile_path.string,
 
1743
                                  PDB_CHANGED)) {
 
1744
                TALLOC_FREE(sam_account);
 
1745
                return NT_STATUS_NO_MEMORY;
 
1746
        }
 
1747
 
 
1748
        if (!pdb_set_homedir(sam_account,
 
1749
                             info3->base.home_directory.string,
 
1750
                             PDB_CHANGED)) {
 
1751
                TALLOC_FREE(sam_account);
 
1752
                return NT_STATUS_NO_MEMORY;
 
1753
        }
 
1754
 
 
1755
        if (!pdb_set_dir_drive(sam_account,
 
1756
                               info3->base.home_drive.string,
 
1757
                               PDB_CHANGED)) {
 
1758
                TALLOC_FREE(sam_account);
 
1759
                return NT_STATUS_NO_MEMORY;
 
1760
        }
 
1761
 
 
1762
        if (!pdb_set_acct_ctrl(sam_account, info3->base.acct_flags, PDB_CHANGED)) {
 
1763
                TALLOC_FREE(sam_account);
 
1764
                return NT_STATUS_NO_MEMORY;
 
1765
        }
 
1766
 
 
1767
        if (!pdb_set_pass_last_set_time(
 
1768
                    sam_account,
 
1769
                    nt_time_to_unix(info3->base.last_password_change),
 
1770
                    PDB_CHANGED)) {
 
1771
                TALLOC_FREE(sam_account);
 
1772
                return NT_STATUS_NO_MEMORY;
 
1773
        }
 
1774
 
 
1775
        if (!pdb_set_pass_can_change_time(
 
1776
                    sam_account,
 
1777
                    nt_time_to_unix(info3->base.allow_password_change),
 
1778
                    PDB_CHANGED)) {
 
1779
                TALLOC_FREE(sam_account);
 
1780
                return NT_STATUS_NO_MEMORY;
 
1781
        }
 
1782
 
 
1783
        if (!pdb_set_pass_must_change_time(
 
1784
                    sam_account,
 
1785
                    nt_time_to_unix(info3->base.force_password_change),
 
1786
                    PDB_CHANGED)) {
 
1787
                TALLOC_FREE(sam_account);
 
1788
                return NT_STATUS_NO_MEMORY;
 
1789
        }
 
1790
 
 
1791
        result = make_server_info(NULL);
 
1792
        if (result == NULL) {
 
1793
                DEBUG(4, ("make_server_info failed!\n"));
 
1794
                TALLOC_FREE(sam_account);
 
1795
                return NT_STATUS_NO_MEMORY;
 
1796
        }
 
1797
 
 
1798
        /* save this here to _net_sam_logon() doesn't fail (it assumes a 
 
1799
           valid struct samu) */
 
1800
                   
 
1801
        result->sam_account = sam_account;
 
1802
        result->unix_name = talloc_strdup(result, found_username);
 
1803
 
 
1804
        result->sanitized_username = sanitize_username(result,
 
1805
                                                       result->unix_name);
 
1806
        if (result->sanitized_username == NULL) {
 
1807
                TALLOC_FREE(result);
 
1808
                return NT_STATUS_NO_MEMORY;
 
1809
        }
 
1810
 
 
1811
        /* Fill in the unix info we found on the way */
 
1812
 
 
1813
        result->utok.uid = uid;
 
1814
        result->utok.gid = gid;
 
1815
 
 
1816
        /* Create a 'combined' list of all SIDs we might want in the SD */
 
1817
 
 
1818
        result->num_sids = 0;
 
1819
        result->sids = NULL;
 
1820
 
 
1821
        nt_status = sid_array_from_info3(result, info3,
 
1822
                                         &result->sids,
 
1823
                                         &result->num_sids,
 
1824
                                         false, false);
 
1825
        if (!NT_STATUS_IS_OK(nt_status)) {
 
1826
                TALLOC_FREE(result);
 
1827
                return nt_status;
 
1828
        }
 
1829
 
 
1830
        /* Ensure the primary group sid is at position 0. */
 
1831
        sort_sid_array_for_smbd(result, &group_sid);
 
1832
 
 
1833
        result->login_server = talloc_strdup(result,
 
1834
                                             info3->base.logon_server.string);
 
1835
 
 
1836
        /* ensure we are never given NULL session keys */
 
1837
 
 
1838
        ZERO_STRUCT(zeros);
 
1839
 
 
1840
        if (memcmp(info3->base.key.key, zeros, sizeof(zeros)) == 0) {
 
1841
                result->user_session_key = data_blob_null;
 
1842
        } else {
 
1843
                result->user_session_key = data_blob_talloc(
 
1844
                        result, info3->base.key.key,
 
1845
                        sizeof(info3->base.key.key));
 
1846
        }
 
1847
 
 
1848
        if (memcmp(info3->base.LMSessKey.key, zeros, 8) == 0) {
 
1849
                result->lm_session_key = data_blob_null;
 
1850
        } else {
 
1851
                result->lm_session_key = data_blob_talloc(
 
1852
                        result, info3->base.LMSessKey.key,
 
1853
                        sizeof(info3->base.LMSessKey.key));
 
1854
        }
 
1855
 
 
1856
        result->nss_token |= username_was_mapped;
 
1857
 
 
1858
        *server_info = result;
 
1859
 
 
1860
        return NT_STATUS_OK;
 
1861
}
 
1862
 
 
1863
/*****************************************************************************
 
1864
 Make a server_info struct from the wbcAuthUserInfo returned by a domain logon
 
1865
******************************************************************************/
 
1866
 
 
1867
NTSTATUS make_server_info_wbcAuthUserInfo(TALLOC_CTX *mem_ctx,
 
1868
                                          const char *sent_nt_username,
 
1869
                                          const char *domain,
 
1870
                                          const struct wbcAuthUserInfo *info,
 
1871
                                          auth_serversupplied_info **server_info)
 
1872
{
 
1873
        char zeros[16];
 
1874
 
 
1875
        NTSTATUS nt_status = NT_STATUS_OK;
 
1876
        char *found_username = NULL;
 
1877
        const char *nt_domain;
 
1878
        const char *nt_username;
 
1879
        struct samu *sam_account = NULL;
 
1880
        DOM_SID user_sid;
 
1881
        DOM_SID group_sid;
 
1882
        bool username_was_mapped;
 
1883
        uint32_t i;
 
1884
 
 
1885
        uid_t uid = (uid_t)-1;
 
1886
        gid_t gid = (gid_t)-1;
 
1887
 
 
1888
        auth_serversupplied_info *result;
 
1889
 
 
1890
        result = make_server_info(NULL);
 
1891
        if (result == NULL) {
 
1892
                DEBUG(4, ("make_server_info failed!\n"));
 
1893
                return NT_STATUS_NO_MEMORY;
 
1894
        }
 
1895
 
 
1896
        /*
 
1897
           Here is where we should check the list of
 
1898
           trusted domains, and verify that the SID
 
1899
           matches.
 
1900
        */
 
1901
 
 
1902
        memcpy(&user_sid, &info->sids[0].sid, sizeof(user_sid));
 
1903
        memcpy(&group_sid, &info->sids[1].sid, sizeof(group_sid));
 
1904
 
 
1905
        if (info->account_name) {
 
1906
                nt_username = talloc_strdup(result, info->account_name);
 
1907
        } else {
 
1908
                /* If the server didn't give us one, just use the one we sent
 
1909
                 * them */
 
1910
                nt_username = talloc_strdup(result, sent_nt_username);
 
1911
        }
 
1912
        if (!nt_username) {
 
1913
                TALLOC_FREE(result);
 
1914
                return NT_STATUS_NO_MEMORY;
 
1915
        }
 
1916
 
 
1917
        if (info->domain_name) {
 
1918
                nt_domain = talloc_strdup(result, info->domain_name);
 
1919
        } else {
 
1920
                /* If the server didn't give us one, just use the one we sent
 
1921
                 * them */
 
1922
                nt_domain = talloc_strdup(result, domain);
 
1923
        }
 
1924
        if (!nt_domain) {
 
1925
                TALLOC_FREE(result);
 
1926
                return NT_STATUS_NO_MEMORY;
 
1927
        }
 
1928
 
 
1929
        /* try to fill the SAM account..  If getpwnam() fails, then try the
 
1930
           add user script (2.2.x behavior).
 
1931
 
 
1932
           We use the _unmapped_ username here in an attempt to provide
 
1933
           consistent username mapping behavior between kerberos and NTLM[SSP]
 
1934
           authentication in domain mode security.  I.E. Username mapping
 
1935
           should be applied to the fully qualified username
 
1936
           (e.g. DOMAIN\user) and not just the login name.  Yes this means we
 
1937
           called map_username() unnecessarily in make_user_info_map() but
 
1938
           that is how the current code is designed.  Making the change here
 
1939
           is the least disruptive place.  -- jerry */
 
1940
 
 
1941
        if ( !(sam_account = samu_new( result )) ) {
 
1942
                TALLOC_FREE(result);
 
1943
                return NT_STATUS_NO_MEMORY;
 
1944
        }
 
1945
 
 
1946
        /* this call will try to create the user if necessary */
 
1947
 
 
1948
        nt_status = fill_sam_account(result, nt_domain, sent_nt_username,
 
1949
                                     &found_username, &uid, &gid, sam_account,
 
1950
                                     &username_was_mapped);
 
1951
 
 
1952
        /* if we still don't have a valid unix account check for
 
1953
          'map to guest = bad uid' */
 
1954
 
 
1955
        if (!NT_STATUS_IS_OK(nt_status)) {
 
1956
                TALLOC_FREE( result );
 
1957
                if ( lp_map_to_guest() == MAP_TO_GUEST_ON_BAD_UID ) {
 
1958
                        make_server_info_guest(NULL, server_info);
 
1959
                        return NT_STATUS_OK;
 
1960
                }
 
1961
                return nt_status;
 
1962
        }
 
1963
 
 
1964
        if (!pdb_set_nt_username(sam_account, nt_username, PDB_CHANGED)) {
 
1965
                TALLOC_FREE(result);
 
1966
                return NT_STATUS_NO_MEMORY;
 
1967
        }
 
1968
 
 
1969
        if (!pdb_set_username(sam_account, nt_username, PDB_CHANGED)) {
 
1970
                TALLOC_FREE(result);
 
1971
                return NT_STATUS_NO_MEMORY;
 
1972
        }
 
1973
 
 
1974
        if (!pdb_set_domain(sam_account, nt_domain, PDB_CHANGED)) {
 
1975
                TALLOC_FREE(result);
 
1976
                return NT_STATUS_NO_MEMORY;
 
1977
        }
 
1978
 
 
1979
        if (!pdb_set_user_sid(sam_account, &user_sid, PDB_CHANGED)) {
 
1980
                TALLOC_FREE(result);
 
1981
                return NT_STATUS_UNSUCCESSFUL;
 
1982
        }
 
1983
 
 
1984
        if (!pdb_set_group_sid(sam_account, &group_sid, PDB_CHANGED)) {
 
1985
                TALLOC_FREE(result);
 
1986
                return NT_STATUS_UNSUCCESSFUL;
 
1987
        }
 
1988
 
 
1989
        if (!pdb_set_fullname(sam_account, info->full_name, PDB_CHANGED)) {
 
1990
                TALLOC_FREE(result);
 
1991
                return NT_STATUS_NO_MEMORY;
 
1992
        }
 
1993
 
 
1994
        if (!pdb_set_logon_script(sam_account, info->logon_script, PDB_CHANGED)) {
 
1995
                TALLOC_FREE(result);
 
1996
                return NT_STATUS_NO_MEMORY;
 
1997
        }
 
1998
 
 
1999
        if (!pdb_set_profile_path(sam_account, info->profile_path, PDB_CHANGED)) {
 
2000
                TALLOC_FREE(result);
 
2001
                return NT_STATUS_NO_MEMORY;
 
2002
        }
 
2003
 
 
2004
        if (!pdb_set_homedir(sam_account, info->home_directory, PDB_CHANGED)) {
 
2005
                TALLOC_FREE(result);
 
2006
                return NT_STATUS_NO_MEMORY;
 
2007
        }
 
2008
 
 
2009
        if (!pdb_set_dir_drive(sam_account, info->home_drive, PDB_CHANGED)) {
 
2010
                TALLOC_FREE(result);
 
2011
                return NT_STATUS_NO_MEMORY;
 
2012
        }
 
2013
 
 
2014
        if (!pdb_set_acct_ctrl(sam_account, info->acct_flags, PDB_CHANGED)) {
 
2015
                TALLOC_FREE(result);
 
2016
                return NT_STATUS_NO_MEMORY;
 
2017
        }
 
2018
 
 
2019
        if (!pdb_set_pass_last_set_time(
 
2020
                    sam_account,
 
2021
                    nt_time_to_unix(info->pass_last_set_time),
 
2022
                    PDB_CHANGED)) {
 
2023
                TALLOC_FREE(result);
 
2024
                return NT_STATUS_NO_MEMORY;
 
2025
        }
 
2026
 
 
2027
        if (!pdb_set_pass_can_change_time(
 
2028
                    sam_account,
 
2029
                    nt_time_to_unix(info->pass_can_change_time),
 
2030
                    PDB_CHANGED)) {
 
2031
                TALLOC_FREE(result);
 
2032
                return NT_STATUS_NO_MEMORY;
 
2033
        }
 
2034
 
 
2035
        if (!pdb_set_pass_must_change_time(
 
2036
                    sam_account,
 
2037
                    nt_time_to_unix(info->pass_must_change_time),
 
2038
                    PDB_CHANGED)) {
 
2039
                TALLOC_FREE(result);
 
2040
                return NT_STATUS_NO_MEMORY;
 
2041
        }
 
2042
 
 
2043
        /* save this here to _net_sam_logon() doesn't fail (it assumes a
 
2044
           valid struct samu) */
 
2045
 
 
2046
        result->sam_account = sam_account;
 
2047
        result->unix_name = talloc_strdup(result, found_username);
 
2048
 
 
2049
        result->sanitized_username = sanitize_username(result,
 
2050
                                                       result->unix_name);
 
2051
        result->login_server = talloc_strdup(result, info->logon_server);
 
2052
 
 
2053
        if ((result->unix_name == NULL)
 
2054
            || (result->sanitized_username == NULL)
 
2055
            || (result->login_server == NULL)) {
 
2056
                TALLOC_FREE(result);
 
2057
                return NT_STATUS_NO_MEMORY;
 
2058
        }
 
2059
 
 
2060
        /* Fill in the unix info we found on the way */
 
2061
 
 
2062
        result->utok.uid = uid;
 
2063
        result->utok.gid = gid;
 
2064
 
 
2065
        /* Create a 'combined' list of all SIDs we might want in the SD */
 
2066
 
 
2067
        result->num_sids = info->num_sids - 2;
 
2068
        result->sids = talloc_array(result, DOM_SID, result->num_sids);
 
2069
        if (result->sids == NULL) {
 
2070
                TALLOC_FREE(result);
 
2071
                return NT_STATUS_NO_MEMORY;
 
2072
        }
 
2073
 
 
2074
        for (i=0; i < result->num_sids; i++) {
 
2075
                memcpy(&result->sids[i], &info->sids[i+2].sid, sizeof(result->sids[i]));
 
2076
        }
 
2077
 
 
2078
        /* Ensure the primary group sid is at position 0. */
 
2079
        sort_sid_array_for_smbd(result, &group_sid);
 
2080
 
 
2081
        /* ensure we are never given NULL session keys */
 
2082
 
 
2083
        ZERO_STRUCT(zeros);
 
2084
 
 
2085
        if (memcmp(info->user_session_key, zeros, sizeof(zeros)) == 0) {
 
2086
                result->user_session_key = data_blob_null;
 
2087
        } else {
 
2088
                result->user_session_key = data_blob_talloc(
 
2089
                        result, info->user_session_key,
 
2090
                        sizeof(info->user_session_key));
 
2091
        }
 
2092
 
 
2093
        if (memcmp(info->lm_session_key, zeros, 8) == 0) {
 
2094
                result->lm_session_key = data_blob_null;
 
2095
        } else {
 
2096
                result->lm_session_key = data_blob_talloc(
 
2097
                        result, info->lm_session_key,
 
2098
                        sizeof(info->lm_session_key));
 
2099
        }
 
2100
 
 
2101
        result->nss_token |= username_was_mapped;
 
2102
 
 
2103
        *server_info = result;
 
2104
 
 
2105
        return NT_STATUS_OK;
 
2106
}
 
2107
 
 
2108
/***************************************************************************
 
2109
 Free a user_info struct
 
2110
***************************************************************************/
 
2111
 
 
2112
void free_user_info(auth_usersupplied_info **user_info)
 
2113
{
 
2114
        DEBUG(5,("attempting to free (and zero) a user_info structure\n"));
 
2115
        if (*user_info != NULL) {
 
2116
                if ((*user_info)->smb_name) {
 
2117
                        DEBUG(10,("structure was created for %s\n",
 
2118
                                  (*user_info)->smb_name));
 
2119
                }
 
2120
                SAFE_FREE((*user_info)->smb_name);
 
2121
                SAFE_FREE((*user_info)->internal_username);
 
2122
                SAFE_FREE((*user_info)->client_domain);
 
2123
                SAFE_FREE((*user_info)->domain);
 
2124
                SAFE_FREE((*user_info)->wksta_name);
 
2125
                data_blob_free(&(*user_info)->lm_resp);
 
2126
                data_blob_free(&(*user_info)->nt_resp);
 
2127
                data_blob_clear_free(&(*user_info)->lm_interactive_pwd);
 
2128
                data_blob_clear_free(&(*user_info)->nt_interactive_pwd);
 
2129
                data_blob_clear_free(&(*user_info)->plaintext_password);
 
2130
                ZERO_STRUCT(**user_info);
 
2131
        }
 
2132
        SAFE_FREE(*user_info);
 
2133
}
 
2134
 
 
2135
/***************************************************************************
 
2136
 Make an auth_methods struct
 
2137
***************************************************************************/
 
2138
 
 
2139
bool make_auth_methods(struct auth_context *auth_context, auth_methods **auth_method) 
 
2140
{
 
2141
        if (!auth_context) {
 
2142
                smb_panic("no auth_context supplied to "
 
2143
                          "make_auth_methods()!\n");
 
2144
        }
 
2145
 
 
2146
        if (!auth_method) {
 
2147
                smb_panic("make_auth_methods: pointer to auth_method pointer "
 
2148
                          "is NULL!\n");
 
2149
        }
 
2150
 
 
2151
        *auth_method = TALLOC_P(auth_context->mem_ctx, auth_methods);
 
2152
        if (!*auth_method) {
 
2153
                DEBUG(0,("make_auth_method: malloc failed!\n"));
 
2154
                return False;
 
2155
        }
 
2156
        ZERO_STRUCTP(*auth_method);
 
2157
        
 
2158
        return True;
 
2159
}
 
2160
 
 
2161
/**
 
2162
 * Verify whether or not given domain is trusted.
 
2163
 *
 
2164
 * @param domain_name name of the domain to be verified
 
2165
 * @return true if domain is one of the trusted once or
 
2166
 *         false if otherwise
 
2167
 **/
 
2168
 
 
2169
bool is_trusted_domain(const char* dom_name)
 
2170
{
 
2171
        DOM_SID trustdom_sid;
 
2172
        bool ret;
 
2173
 
 
2174
        /* no trusted domains for a standalone server */
 
2175
 
 
2176
        if ( lp_server_role() == ROLE_STANDALONE )
 
2177
                return False;
 
2178
 
 
2179
        if (dom_name == NULL || dom_name[0] == '\0') {
 
2180
                return false;
 
2181
        }
 
2182
 
 
2183
        if (strequal(dom_name, get_global_sam_name())) {
 
2184
                return false;
 
2185
        }
 
2186
 
 
2187
        /* if we are a DC, then check for a direct trust relationships */
 
2188
 
 
2189
        if ( IS_DC ) {
 
2190
                become_root();
 
2191
                DEBUG (5,("is_trusted_domain: Checking for domain trust with "
 
2192
                          "[%s]\n", dom_name ));
 
2193
                ret = pdb_get_trusteddom_pw(dom_name, NULL, NULL, NULL);
 
2194
                unbecome_root();
 
2195
                if (ret)
 
2196
                        return True;
 
2197
        }
 
2198
        else {
 
2199
                wbcErr result;
 
2200
 
 
2201
                /* If winbind is around, ask it */
 
2202
 
 
2203
                result = wb_is_trusted_domain(dom_name);
 
2204
 
 
2205
                if (result == WBC_ERR_SUCCESS) {
 
2206
                        return True;
 
2207
                }
 
2208
 
 
2209
                if (result == WBC_ERR_DOMAIN_NOT_FOUND) {
 
2210
                        /* winbind could not find the domain */
 
2211
                        return False;
 
2212
                }
 
2213
 
 
2214
                /* The only other possible result is that winbind is not up
 
2215
                   and running. We need to update the trustdom_cache
 
2216
                   ourselves */
 
2217
                
 
2218
                update_trustdom_cache();
 
2219
        }
 
2220
 
 
2221
        /* now the trustdom cache should be available a DC could still
 
2222
         * have a transitive trust so fall back to the cache of trusted
 
2223
         * domains (like a domain member would use  */
 
2224
 
 
2225
        if ( trustdom_cache_fetch(dom_name, &trustdom_sid) ) {
 
2226
                return True;
 
2227
        }
 
2228
 
 
2229
        return False;
 
2230
}
 
2231