~lefteris-nikoltsios/+junk/samba-lp1016895

« back to all changes in this revision

Viewing changes to source3/utils/ntlm_auth.c

  • Committer: Package Import Robot
  • Author(s): Chuck Short
  • Date: 2011-12-21 13:18:04 UTC
  • mfrom: (0.39.21 sid)
  • Revision ID: package-import@ubuntu.com-20111221131804-xtlr39wx6njehxxr
Tags: 2:3.6.1-3ubuntu1
* Merge from Debian testing.  Remaining changes:
  + debian/patches/VERSION.patch:
    - set SAMBA_VERSION_SUFFIX to Ubuntu.
  + debian/patches/error-trans.fix-276472:
    - Add the translation of Unix Error code -ENOTSUP to NT Error Code
    - NT_STATUS_NOT_SUPPORTED to prevent the Permission denied error.
  + debian/smb.conf:
    - add "(Samba, Ubuntu)" to server string.
    - comment out the default [homes] share, and add a comment about
      "valid users = %S" to show users how to restrict access to
      \\server\username to only username.
    - Set 'usershare allow guests', so that usershare admins are 
      allowed to create public shares in addition to authenticated
      ones.
    - add map to guest = Bad user, maps bad username to guest access.
  + debian/samba-common.config:
    - Do not change priority to high if dhclient3 is installed.
    - Use priority medium instead of high for the workgroup question.
  + debian/control:
    - Don't build against or suggest ctdb.
    - Add dependency on samba-common-bin to samba.
  + Add ufw integration:
    - Created debian/samba.ufw.profile
    - debian/rules, debian/samba.dirs, debian/samba.files: install
      profile
    - debian/control: have samba suggest ufw
  + Add apport hook:
    - Created debian/source_samba.py.
    - debian/rules, debian/samba.dirs, debian/samba-common-bin.files: install
  + Switch to upstart:
    - Add debian/samba.{nmbd,smbd}.upstart.
  + debian/samba.logrotate, debian/samba-common.dhcp, debian/samba.if-up:
    - Make them upstart compatible
  + debian/samba.postinst: 
    - Avoid scary pdbedit warnings on first import.
  + debian/samba-common.postinst: Add more informative error message for
    the case where smb.conf was manually deleted
  + debian/patches/fix-debuglevel-name-conflict.patch: don't use 'debug_level'
    as a global variable name in an NSS module 
  + Dropped:
    - debian/patches/error-trans.fix-276472
    - debian/patches/fix-debuglevel-name-conflict.patch

Show diffs side-by-side

added added

removed removed

Lines of Context:
24
24
*/
25
25
 
26
26
#include "includes.h"
 
27
#include "popt_common.h"
27
28
#include "utils/ntlm_auth.h"
28
29
#include "../libcli/auth/libcli_auth.h"
29
30
#include "../libcli/auth/spnego.h"
 
31
#include "../libcli/auth/ntlmssp.h"
30
32
#include "smb_krb5.h"
31
33
#include <iniparser.h>
 
34
#include "../lib/crypto/arcfour.h"
 
35
#include "libads/kerberos_proto.h"
 
36
#include "nsswitch/winbind_client.h"
 
37
#include "librpc/gen_ndr/krb5pac.h"
 
38
#include "../lib/util/asn1.h"
32
39
 
33
40
#ifndef PAM_WINBIND_CONFIG_FILE
34
41
#define PAM_WINBIND_CONFIG_FILE "/etc/security/pam_winbind.conf"
224
231
        static DATA_BLOB chal;
225
232
        if (opt_challenge.length)
226
233
                return opt_challenge;
227
 
        
 
234
 
228
235
        chal = data_blob(NULL, 8);
229
236
 
230
237
        generate_random_buffer(chal.data, chal.length);
243
250
        if (!p) {
244
251
                return False;
245
252
        }
246
 
        
 
253
 
247
254
        fstrcpy(user, p+1);
248
255
        fstrcpy(domain, domuser);
249
256
        domain[PTR_DIFF(p, domuser)] = 0;
301
308
{
302
309
        int ctrl = 0;
303
310
        dictionary *d = NULL;
304
 
        
 
311
 
305
312
        if (!opt_pam_winbind_conf || !*opt_pam_winbind_conf) {
306
313
                opt_pam_winbind_conf = PAM_WINBIND_CONFIG_FILE;
307
314
        }
308
315
 
309
316
        d = iniparser_load(CONST_DISCARD(char *, opt_pam_winbind_conf));
310
 
        
 
317
 
311
318
        if (!d) {
312
319
                return 0;
313
320
        }
314
 
        
 
321
 
315
322
        if (iniparser_getboolean(d, CONST_DISCARD(char *, "global:krb5_auth"), false)) {
316
323
                ctrl |= WINBIND_KRB5_AUTH;
317
324
        }
318
325
 
319
326
        iniparser_freedict(d);
320
 
        
 
327
 
321
328
        return ctrl;
322
329
}
323
330
 
439
446
                }
440
447
                request.data.auth_crap.nt_resp_len = nt_response->length;
441
448
        }
442
 
        
 
449
 
443
450
        result = winbindd_request_response(WINBINDD_PAM_AUTH_CRAP, &request, &response);
444
451
        SAFE_FREE(request.extra_data.data);
445
452
 
452
459
                winbindd_free_response(&response);
453
460
                return nt_status;
454
461
        }
455
 
        
 
462
 
456
463
        nt_status = (NT_STATUS(response.data.auth.nt_status));
457
464
        if (!NT_STATUS_IS_OK(nt_status)) {
458
465
                if (error_string) 
534
541
                memcpy(request.data.chng_pswd_auth_crap.old_lm_hash_enc, old_lm_hash_enc.data, sizeof(request.data.chng_pswd_auth_crap.old_lm_hash_enc));
535
542
                request.data.chng_pswd_auth_crap.old_lm_hash_enc_len = old_lm_hash_enc.length;
536
543
        }
537
 
        
 
544
 
538
545
        result = winbindd_request_response(WINBINDD_PAM_CHNG_PSWD_AUTH_CRAP, &request, &response);
539
546
 
540
547
        /* Display response */
547
554
                winbindd_free_response(&response);
548
555
                return nt_status;
549
556
        }
550
 
        
 
557
 
551
558
        nt_status = (NT_STATUS(response.data.auth.nt_status));
552
559
        if (!NT_STATUS_IS_OK(nt_status))
553
560
        {
558
565
        }
559
566
 
560
567
        winbindd_free_response(&response);
561
 
        
 
568
 
562
569
    return nt_status;
563
570
}
564
571
 
565
 
static NTSTATUS winbind_pw_check(struct ntlmssp_state *ntlmssp_state, DATA_BLOB *user_session_key, DATA_BLOB *lm_session_key) 
 
572
static NTSTATUS winbind_pw_check(struct ntlmssp_state *ntlmssp_state, TALLOC_CTX *mem_ctx,
 
573
                                 DATA_BLOB *user_session_key, DATA_BLOB *lm_session_key)
566
574
{
567
575
        static const char zeros[16] = { 0, };
568
576
        NTSTATUS nt_status;
572
580
        char *unix_name = NULL;
573
581
 
574
582
        nt_status = contact_winbind_auth_crap(ntlmssp_state->user, ntlmssp_state->domain,
575
 
                                              ntlmssp_state->workstation,
 
583
                                              ntlmssp_state->client.netbios_name,
576
584
                                              &ntlmssp_state->chal,
577
585
                                              &ntlmssp_state->lm_resp,
578
586
                                              &ntlmssp_state->nt_resp, 
582
590
 
583
591
        if (NT_STATUS_IS_OK(nt_status)) {
584
592
                if (memcmp(lm_key, zeros, 8) != 0) {
585
 
                        *lm_session_key = data_blob_talloc(ntlmssp_state, NULL, 16);
 
593
                        *lm_session_key = data_blob_talloc(mem_ctx, NULL, 16);
586
594
                        memcpy(lm_session_key->data, lm_key, 8);
587
595
                        memset(lm_session_key->data+8, '\0', 8);
588
596
                }
589
 
                
 
597
 
590
598
                if (memcmp(user_sess_key, zeros, 16) != 0) {
591
 
                        *user_session_key = data_blob_talloc(ntlmssp_state, user_sess_key, 16);
 
599
                        *user_session_key = data_blob_talloc(mem_ctx, user_sess_key, 16);
592
600
                }
593
 
                ntlmssp_state->auth_context = talloc_strdup(ntlmssp_state,
594
 
                                                            unix_name);
 
601
                ntlmssp_state->callback_private = talloc_strdup(ntlmssp_state,
 
602
                                                                unix_name);
595
603
        } else {
596
604
                DEBUG(NT_STATUS_EQUAL(nt_status, NT_STATUS_ACCESS_DENIED) ? 0 : 3, 
597
605
                      ("Login for user [%s]\\[%s]@[%s] failed due to [%s]\n", 
598
606
                       ntlmssp_state->domain, ntlmssp_state->user, 
599
 
                       ntlmssp_state->workstation, 
 
607
                       ntlmssp_state->client.netbios_name,
600
608
                       error_string ? error_string : "unknown error (NULL)"));
601
 
                ntlmssp_state->auth_context = NULL;
 
609
                ntlmssp_state->callback_private = NULL;
602
610
        }
603
611
 
604
612
        SAFE_FREE(error_string);
606
614
        return nt_status;
607
615
}
608
616
 
609
 
static NTSTATUS local_pw_check(struct ntlmssp_state *ntlmssp_state, DATA_BLOB *user_session_key, DATA_BLOB *lm_session_key) 
 
617
static NTSTATUS local_pw_check(struct ntlmssp_state *ntlmssp_state, TALLOC_CTX *mem_ctx,
 
618
                               DATA_BLOB *user_session_key, DATA_BLOB *lm_session_key)
610
619
{
611
620
        NTSTATUS nt_status;
612
621
        struct samr_Password lm_pw, nt_pw;
613
622
 
614
623
        nt_lm_owf_gen (opt_password, nt_pw.hash, lm_pw.hash);
615
 
        
616
 
        nt_status = ntlm_password_check(ntlmssp_state,
 
624
 
 
625
        nt_status = ntlm_password_check(mem_ctx,
617
626
                                        true, true, 0,
618
627
                                        &ntlmssp_state->chal,
619
628
                                        &ntlmssp_state->lm_resp,
622
631
                                        ntlmssp_state->user, 
623
632
                                        ntlmssp_state->domain,
624
633
                                        &lm_pw, &nt_pw, user_session_key, lm_session_key);
625
 
        
 
634
 
626
635
        if (NT_STATUS_IS_OK(nt_status)) {
627
 
                ntlmssp_state->auth_context = talloc_asprintf(ntlmssp_state,
 
636
                ntlmssp_state->callback_private = talloc_asprintf(ntlmssp_state,
628
637
                                                              "%s%c%s", ntlmssp_state->domain, 
629
638
                                                              *lp_winbind_separator(), 
630
639
                                                              ntlmssp_state->user);
631
640
        } else {
632
641
                DEBUG(3, ("Login for user [%s]\\[%s]@[%s] failed due to [%s]\n", 
633
 
                          ntlmssp_state->domain, ntlmssp_state->user, ntlmssp_state->workstation, 
 
642
                          ntlmssp_state->domain, ntlmssp_state->user,
 
643
                          ntlmssp_state->client.netbios_name,
634
644
                          nt_errstr(nt_status)));
635
 
                ntlmssp_state->auth_context = NULL;
 
645
                ntlmssp_state->callback_private = NULL;
636
646
        }
637
647
        return nt_status;
638
648
}
639
649
 
640
 
static NTSTATUS ntlm_auth_start_ntlmssp_client(NTLMSSP_STATE **client_ntlmssp_state) 
 
650
static NTSTATUS ntlm_auth_start_ntlmssp_client(struct ntlmssp_state **client_ntlmssp_state)
641
651
{
642
652
        NTSTATUS status;
643
653
        if ( (opt_username == NULL) || (opt_domain == NULL) ) {
646
656
                return NT_STATUS_INVALID_PARAMETER;
647
657
        }
648
658
 
649
 
        status = ntlmssp_client_start(client_ntlmssp_state);
 
659
        status = ntlmssp_client_start(NULL,
 
660
                                      global_myname(),
 
661
                                      lp_workgroup(),
 
662
                                      lp_client_ntlmv2_auth(),
 
663
                                      client_ntlmssp_state);
650
664
 
651
665
        if (!NT_STATUS_IS_OK(status)) {
652
666
                DEBUG(1, ("Could not start NTLMSSP client: %s\n",
653
667
                          nt_errstr(status)));
654
 
                ntlmssp_end(client_ntlmssp_state);
 
668
                TALLOC_FREE(*client_ntlmssp_state);
655
669
                return status;
656
670
        }
657
671
 
660
674
        if (!NT_STATUS_IS_OK(status)) {
661
675
                DEBUG(1, ("Could not set username: %s\n",
662
676
                          nt_errstr(status)));
663
 
                ntlmssp_end(client_ntlmssp_state);
 
677
                TALLOC_FREE(*client_ntlmssp_state);
664
678
                return status;
665
679
        }
666
680
 
669
683
        if (!NT_STATUS_IS_OK(status)) {
670
684
                DEBUG(1, ("Could not set domain: %s\n",
671
685
                          nt_errstr(status)));
672
 
                ntlmssp_end(client_ntlmssp_state);
 
686
                TALLOC_FREE(*client_ntlmssp_state);
673
687
                return status;
674
688
        }
675
689
 
676
690
        if (opt_password) {
677
691
                status = ntlmssp_set_password(*client_ntlmssp_state, opt_password);
678
 
        
 
692
 
679
693
                if (!NT_STATUS_IS_OK(status)) {
680
694
                        DEBUG(1, ("Could not set password: %s\n",
681
695
                                  nt_errstr(status)));
682
 
                        ntlmssp_end(client_ntlmssp_state);
 
696
                        TALLOC_FREE(*client_ntlmssp_state);
683
697
                        return status;
684
698
                }
685
699
        }
687
701
        return NT_STATUS_OK;
688
702
}
689
703
 
690
 
static NTSTATUS ntlm_auth_start_ntlmssp_server(NTLMSSP_STATE **ntlmssp_state) 
 
704
static NTSTATUS ntlm_auth_start_ntlmssp_server(struct ntlmssp_state **ntlmssp_state)
691
705
{
692
 
        NTSTATUS status = ntlmssp_server_start(ntlmssp_state);
693
 
        
 
706
        NTSTATUS status;
 
707
        const char *netbios_name;
 
708
        const char *netbios_domain;
 
709
        const char *dns_name;
 
710
        char *dns_domain;
 
711
        bool is_standalone = false;
 
712
 
 
713
        if (opt_password) {
 
714
                netbios_name = global_myname();
 
715
                netbios_domain = lp_workgroup();
 
716
        } else {
 
717
                netbios_name = get_winbind_netbios_name();
 
718
                netbios_domain = get_winbind_domain();
 
719
        }
 
720
        /* This should be a 'netbios domain -> DNS domain' mapping */
 
721
        dns_domain = get_mydnsdomname(talloc_tos());
 
722
        if (dns_domain) {
 
723
                strlower_m(dns_domain);
 
724
        }
 
725
        dns_name = get_mydnsfullname();
 
726
 
 
727
        status = ntlmssp_server_start(NULL,
 
728
                                      is_standalone,
 
729
                                      netbios_name,
 
730
                                      netbios_domain,
 
731
                                      dns_name,
 
732
                                      dns_domain,
 
733
                                      ntlmssp_state);
694
734
        if (!NT_STATUS_IS_OK(status)) {
695
735
                DEBUG(1, ("Could not start NTLMSSP server: %s\n",
696
736
                          nt_errstr(status)));
700
740
        /* Have we been given a local password, or should we ask winbind? */
701
741
        if (opt_password) {
702
742
                (*ntlmssp_state)->check_password = local_pw_check;
703
 
                (*ntlmssp_state)->get_domain = lp_workgroup;
704
 
                (*ntlmssp_state)->get_global_myname = global_myname;
705
743
        } else {
706
744
                (*ntlmssp_state)->check_password = winbind_pw_check;
707
 
                (*ntlmssp_state)->get_domain = get_winbind_domain;
708
 
                (*ntlmssp_state)->get_global_myname = get_winbind_netbios_name;
709
745
        }
710
746
        return NT_STATUS_OK;
711
747
}
732
768
         * child of the trusted domain. If we ask the primary domain for
733
769
         * ntlm_ccache_auth, it will fail. So, we have to ask the trusted
734
770
         * domain's child for ccache_ntlm_auth. that is to say, we have to 
735
 
         * set WBFALG_PAM_CONTACT_TRUSTDOM in request.flags.
 
771
         * set WBFLAG_PAM_CONTACT_TRUSTDOM in request.flags.
736
772
         */
737
773
        ctrl = get_pam_winbind_config();
738
774
 
828
864
        }
829
865
 
830
866
        if (strncmp(buf, "YR", 2) == 0) {
831
 
                if (state->ntlmssp_state)
832
 
                        ntlmssp_end(&state->ntlmssp_state);
 
867
                TALLOC_FREE(state->ntlmssp_state);
833
868
                state->svr_state = SERVER_INITIAL;
834
869
        } else if (strncmp(buf, "KK", 2) == 0) {
835
870
                /* No special preprocessing required */
895
930
                                         nt_errstr(nt_status));
896
931
                DEBUG(0, ("NTLMSSP BH: %s\n", nt_errstr(nt_status)));
897
932
 
898
 
                ntlmssp_end(&state->ntlmssp_state);
 
933
                TALLOC_FREE(state->ntlmssp_state);
899
934
        } else if (!NT_STATUS_IS_OK(nt_status)) {
900
935
                *response = talloc_asprintf(mem_ctx, "NA %s",
901
936
                                         nt_errstr(nt_status));
903
938
        } else {
904
939
                *response = talloc_asprintf(
905
940
                        mem_ctx, "AF %s",
906
 
                        (char *)state->ntlmssp_state->auth_context);
 
941
                        (char *)state->ntlmssp_state->callback_private);
907
942
                DEBUG(10, ("NTLMSSP OK!\n"));
908
943
 
909
944
                if(state->have_session_key)
1006
1041
        }
1007
1042
 
1008
1043
        if (strncmp(buf, "YR", 2) == 0) {
1009
 
                if (state->ntlmssp_state)
1010
 
                        ntlmssp_end(&state->ntlmssp_state);
 
1044
                TALLOC_FREE(state->ntlmssp_state);
1011
1045
                state->cli_state = CLIENT_INITIAL;
1012
1046
        } else if (strncmp(buf, "TT", 2) == 0) {
1013
1047
                /* No special preprocessing required */
1098
1132
 
1099
1133
                DEBUG(10, ("NTLMSSP OK!\n"));
1100
1134
                state->cli_state = CLIENT_FINISHED;
1101
 
                if (state->ntlmssp_state)
1102
 
                        ntlmssp_end(&state->ntlmssp_state);
 
1135
                TALLOC_FREE(state->ntlmssp_state);
1103
1136
        } else {
1104
1137
                x_fprintf(x_stdout, "BH %s\n", nt_errstr(nt_status));
1105
1138
                DEBUG(0, ("NTLMSSP BH: %s\n", nt_errstr(nt_status)));
1106
1139
                state->cli_state = CLIENT_ERROR;
1107
 
                if (state->ntlmssp_state)
1108
 
                        ntlmssp_end(&state->ntlmssp_state);
 
1140
                TALLOC_FREE(state->ntlmssp_state);
1109
1141
        }
1110
1142
 
1111
1143
        data_blob_free(&request);
1116
1148
{
1117
1149
        char *user, *pass;      
1118
1150
        user=buf;
1119
 
        
 
1151
 
1120
1152
        pass=(char *)memchr(buf,' ',length);
1121
1153
        if (!pass) {
1122
1154
                DEBUG(2, ("Password not found. Denying access\n"));
1125
1157
        }
1126
1158
        *pass='\0';
1127
1159
        pass++;
1128
 
        
 
1160
 
1129
1161
        if (state->helper_mode == SQUID_2_5_BASIC) {
1130
1162
                rfc1738_unescape(user);
1131
1163
                rfc1738_unescape(pass);
1132
1164
        }
1133
 
        
 
1165
 
1134
1166
        if (check_plaintext_auth(user, pass, False)) {
1135
1167
                x_fprintf(x_stdout, "OK\n");
1136
1168
        } else {
1196
1228
        return;
1197
1229
}
1198
1230
 
1199
 
static bool _spnego_parse_krb5_wrap(TALLOC_CTX *ctx, DATA_BLOB blob, DATA_BLOB *ticket, uint8 tok_id[2])
 
1231
bool spnego_parse_krb5_wrap(TALLOC_CTX *ctx, DATA_BLOB blob, DATA_BLOB *ticket, uint8 tok_id[2])
1200
1232
{
1201
1233
        bool ret;
1202
1234
        ASN1_DATA *data;
1261
1293
        }
1262
1294
 
1263
1295
        if (strncmp(buf, "YR", 2) == 0) {
1264
 
                if (state->ntlmssp_state)
1265
 
                        ntlmssp_end(&state->ntlmssp_state);
 
1296
                TALLOC_FREE(state->ntlmssp_state);
1266
1297
                TALLOC_FREE(state->spnego_mech);
1267
1298
                TALLOC_FREE(state->spnego_mech_oid);
1268
1299
        } else if (strncmp(buf, "KK", 2) == 0) {
1395
1426
                                x_fprintf(x_stdout, "BH Client wants a new "
1396
1427
                                                    "NTLMSSP challenge, but "
1397
1428
                                                    "already got one\n");
1398
 
                                ntlmssp_end(&state->ntlmssp_state);
 
1429
                                TALLOC_FREE(state->ntlmssp_state);
1399
1430
                                return;
1400
1431
                        }
1401
1432
 
1472
1503
                        domain = talloc_strdup(ctx, state->ntlmssp_state->domain);
1473
1504
                }
1474
1505
                if (!NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
1475
 
                        ntlmssp_end(&state->ntlmssp_state);
 
1506
                        TALLOC_FREE(state->ntlmssp_state);
1476
1507
                }
1477
1508
#ifdef HAVE_KRB5
1478
1509
        } else if (strcmp(state->spnego_mech, "krb5") == 0) {
1479
1510
                char *principal;
1480
1511
                DATA_BLOB ap_rep;
1481
1512
                DATA_BLOB session_key;
1482
 
                struct PAC_DATA *pac_data = NULL;
 
1513
                struct PAC_LOGON_INFO *logon_info = NULL;
1483
1514
                DATA_BLOB ticket;
1484
1515
                uint8_t tok_id[2];
1485
1516
 
1486
 
                if (!_spnego_parse_krb5_wrap(ctx, raw_in_token,
1487
 
                                             &ticket, tok_id)) {
 
1517
                if (!spnego_parse_krb5_wrap(ctx, raw_in_token,
 
1518
                                            &ticket, tok_id)) {
1488
1519
                        DEBUG(1, ("spnego_parse_krb5_wrap failed\n"));
1489
1520
                        x_fprintf(x_stdout, "BH spnego_parse_krb5_wrap failed\n");
1490
1521
                        return;
1492
1523
 
1493
1524
                status = ads_verify_ticket(ctx, lp_realm(), 0,
1494
1525
                                           &ticket,
1495
 
                                           &principal, &pac_data, &ap_rep,
 
1526
                                           &principal, &logon_info, &ap_rep,
1496
1527
                                           &session_key, True);
1497
1528
 
1498
1529
                /* Now in "principal" we have the name we are authenticated as. */
1514
1545
                        domain = talloc_strdup(ctx, domain);
1515
1546
                        user = talloc_strdup(ctx, principal);
1516
1547
 
1517
 
                        if (pac_data) {
1518
 
                                struct PAC_LOGON_INFO *logon_info;
1519
 
                                logon_info = get_logon_info_from_pac(
1520
 
                                        pac_data);
1521
 
                                if (logon_info) {
1522
 
                                        netsamlogon_cache_store(
1523
 
                                                user,
1524
 
                                                &logon_info->info3);
1525
 
                                }
 
1548
                        if (logon_info) {
 
1549
                                netsamlogon_cache_store(
 
1550
                                        user, &logon_info->info3);
1526
1551
                        }
1527
1552
 
1528
1553
                        data_blob_free(&ap_rep);
1586
1611
        return;
1587
1612
}
1588
1613
 
1589
 
static NTLMSSP_STATE *client_ntlmssp_state = NULL;
 
1614
static struct ntlmssp_state *client_ntlmssp_state = NULL;
1590
1615
 
1591
1616
static bool manage_client_ntlmssp_init(struct spnego_data spnego)
1592
1617
{
1637
1662
                        NT_STATUS_IS_OK(status)) ) {
1638
1663
                DEBUG(1, ("Expected OK or MORE_PROCESSING_REQUIRED, got: %s\n",
1639
1664
                          nt_errstr(status)));
1640
 
                ntlmssp_end(&client_ntlmssp_state);
 
1665
                TALLOC_FREE(client_ntlmssp_state);
1641
1666
                return False;
1642
1667
        }
1643
1668
 
1670
1695
 
1671
1696
        if (spnego.negTokenTarg.negResult == SPNEGO_REJECT) {
1672
1697
                x_fprintf(x_stdout, "NA\n");
1673
 
                ntlmssp_end(&client_ntlmssp_state);
 
1698
                TALLOC_FREE(client_ntlmssp_state);
1674
1699
                return;
1675
1700
        }
1676
1701
 
1677
1702
        if (spnego.negTokenTarg.negResult == SPNEGO_ACCEPT_COMPLETED) {
1678
1703
                x_fprintf(x_stdout, "AF\n");
1679
 
                ntlmssp_end(&client_ntlmssp_state);
 
1704
                TALLOC_FREE(client_ntlmssp_state);
1680
1705
                return;
1681
1706
        }
1682
1707
 
1683
1708
        status = ntlmssp_update(client_ntlmssp_state,
1684
1709
                                       spnego.negTokenTarg.responseToken,
1685
1710
                                       &request);
1686
 
                
 
1711
 
1687
1712
        if (!NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
1688
1713
                DEBUG(1, ("Expected MORE_PROCESSING_REQUIRED from "
1689
1714
                          "ntlmssp_client_update, got: %s\n",
1691
1716
                x_fprintf(x_stdout, "BH Expected MORE_PROCESSING_REQUIRED from "
1692
1717
                                    "ntlmssp_client_update\n");
1693
1718
                data_blob_free(&request);
1694
 
                ntlmssp_end(&client_ntlmssp_state);
 
1719
                TALLOC_FREE(client_ntlmssp_state);
1695
1720
                return;
1696
1721
        }
1697
1722
 
1700
1725
        spnego.negTokenTarg.supportedMech = (char *)OID_NTLMSSP;
1701
1726
        spnego.negTokenTarg.responseToken = request;
1702
1727
        spnego.negTokenTarg.mechListMIC = null_blob;
1703
 
        
 
1728
 
1704
1729
        spnego_write_data(ctx, &to_server, &spnego);
1705
1730
        data_blob_free(&request);
1706
1731
 
1744
1769
               spnego.negTokenInit.mechListMIC.length);
1745
1770
        principal[spnego.negTokenInit.mechListMIC.length] = '\0';
1746
1771
 
1747
 
        retval = cli_krb5_get_ticket(principal, 0, &tkt, &session_key_krb5, 0, NULL, NULL, NULL);
1748
 
 
 
1772
        retval = cli_krb5_get_ticket(ctx, principal, 0,
 
1773
                                          &tkt, &session_key_krb5,
 
1774
                                          0, NULL, NULL, NULL);
1749
1775
        if (retval) {
1750
1776
                char *user = NULL;
1751
1777
 
1768
1794
                        return False;
1769
1795
                }
1770
1796
 
1771
 
                retval = cli_krb5_get_ticket(principal, 0, &tkt, &session_key_krb5, 0, NULL, NULL, NULL);
1772
 
 
 
1797
                retval = cli_krb5_get_ticket(ctx, principal, 0,
 
1798
                                                  &tkt, &session_key_krb5,
 
1799
                                                  0, NULL, NULL, NULL);
1773
1800
                if (retval) {
1774
1801
                        DEBUG(10, ("Kinit suceeded, but getting a ticket failed: %s\n", error_message(retval)));
1775
1802
                        return False;
1854
1881
                /* We asked for a password and obviously got it :-) */
1855
1882
 
1856
1883
                opt_password = SMB_STRNDUP((const char *)request.data, request.length);
1857
 
                
 
1884
 
1858
1885
                if (opt_password == NULL) {
1859
1886
                        DEBUG(1, ("Out of memory\n"));
1860
1887
                        x_fprintf(x_stdout, "BH Out of memory\n");
1940
1967
                                                    "negResult\n");
1941
1968
                        }
1942
1969
 
1943
 
                        ntlmssp_end(&client_ntlmssp_state);
 
1970
                        TALLOC_FREE(client_ntlmssp_state);
1944
1971
                        goto out;
1945
1972
                }
1946
1973
 
1982
2009
        static char *plaintext_password;
1983
2010
        static bool ntlm_server_1_user_session_key;
1984
2011
        static bool ntlm_server_1_lm_session_key;
1985
 
        
 
2012
 
1986
2013
        if (strequal(buf, ".")) {
1987
2014
                if (!full_username && !username) {      
1988
2015
                        x_fprintf(x_stdout, "Error: No username supplied!\n");
2012
2039
                        if (full_username && !username) {
2013
2040
                                fstring fstr_user;
2014
2041
                                fstring fstr_domain;
2015
 
                                
 
2042
 
2016
2043
                                if (!parse_ntlm_auth_domain_user(full_username, fstr_user, fstr_domain)) {
2017
2044
                                        /* username might be 'tainted', don't print into our new-line deleimianted stream */
2018
2045
                                        x_fprintf(x_stdout, "Error: Could not parse into domain and username\n");
2029
2056
 
2030
2057
                        if (ntlm_server_1_lm_session_key) 
2031
2058
                                flags |= WBFLAG_PAM_LMKEY;
2032
 
                        
 
2059
 
2033
2060
                        if (ntlm_server_1_user_session_key) 
2034
2061
                                flags |= WBFLAG_PAM_USER_SESSION_KEY;
2035
2062
 
2098
2125
        parameter = strstr_m(request, ":: ");
2099
2126
        if (!parameter) {
2100
2127
                parameter = strstr_m(request, ": ");
2101
 
                
 
2128
 
2102
2129
                if (!parameter) {
2103
2130
                        DEBUG(0, ("Parameter not found!\n"));
2104
2131
                        x_fprintf(x_stdout, "Error: Parameter not found!\n.\n");
2105
2132
                        return;
2106
2133
                }
2107
 
                
 
2134
 
2108
2135
                parameter[0] ='\0';
2109
2136
                parameter++;
2110
2137
                parameter[0] ='\0';
2185
2212
 
2186
2213
                        new_nt_pswd = data_blob(NULL, 516);
2187
2214
                        old_nt_hash_enc = data_blob(NULL, 16);
2188
 
                        
 
2215
 
2189
2216
                        /* Calculate the MD4 hash (NT compatible) of the
2190
2217
                         * password */
2191
2218
                        E_md4hash(oldpswd, old_nt_hash);
2193
2220
 
2194
2221
                        /* E_deshash returns false for 'long'
2195
2222
                           passwords (> 14 DOS chars).  
2196
 
                           
 
2223
 
2197
2224
                           Therefore, don't send a buffer
2198
2225
                           encrypted with the truncated hash
2199
2226
                           (it could allow an even easier
2222
2249
 
2223
2250
                        encode_pw_buffer(new_nt_pswd.data, newpswd,
2224
2251
                                         STR_UNICODE);
2225
 
        
 
2252
 
2226
2253
                        arcfour_crypt(new_nt_pswd.data, old_nt_hash, 516);
2227
2254
                        E_old_pw_hash(new_nt_hash, old_nt_hash,
2228
2255
                                      old_nt_hash_enc.data);
2229
2256
                }
2230
 
                
 
2257
 
2231
2258
                if (!full_username && !username) {      
2232
2259
                        x_fprintf(x_stdout, "Error: No username supplied!\n");
2233
2260
                } else if ((!new_nt_pswd.data || !old_nt_hash_enc.data) &&
2236
2263
                                  "blobs supplied!\n");
2237
2264
                } else {
2238
2265
                        char *error_string = NULL;
2239
 
                        
 
2266
 
2240
2267
                        if (full_username && !username) {
2241
2268
                                fstring fstr_user;
2242
2269
                                fstring fstr_domain;
2243
 
                                
 
2270
 
2244
2271
                                if (!parse_ntlm_auth_domain_user(full_username,
2245
2272
                                                                 fstr_user,
2246
2273
                                                                 fstr_domain)) {
2258
2285
                                        username = smb_xstrdup(fstr_user);
2259
2286
                                        domain = smb_xstrdup(fstr_domain);
2260
2287
                                }
2261
 
                                
 
2288
 
2262
2289
                        }
2263
2290
 
2264
2291
                        if(!NT_STATUS_IS_OK(contact_winbind_change_pswd_auth_crap(
2298
2325
        parameter = strstr_m(request, ":: ");
2299
2326
        if (!parameter) {
2300
2327
                parameter = strstr_m(request, ": ");
2301
 
                
 
2328
 
2302
2329
                if (!parameter) {
2303
2330
                        DEBUG(0, ("Parameter not found!\n"));
2304
2331
                        x_fprintf(x_stdout, "Error: Parameter not found!\n.\n");
2305
2332
                        return;
2306
2333
                }
2307
 
                
 
2334
 
2308
2335
                parameter[0] ='\0';
2309
2336
                parameter++;
2310
2337
                parameter[0] ='\0';
2580
2607
                { "request-lm-key", 0, POPT_ARG_NONE, &request_lm_key, OPT_LM_KEY, "Retrieve LM session key"},
2581
2608
                { "request-nt-key", 0, POPT_ARG_NONE, &request_user_session_key, OPT_USER_SESSION_KEY, "Retrieve User (NT) session key"},
2582
2609
                { "use-cached-creds", 0, POPT_ARG_NONE, &use_cached_creds, OPT_USE_CACHED_CREDS, "Use cached credentials if no password is given"},
2583
 
                { "diagnostics", 0, POPT_ARG_NONE, &diagnostics, OPT_DIAGNOSTICS, "Perform diagnostics on the authentictaion chain"},
 
2610
                { "diagnostics", 0, POPT_ARG_NONE, &diagnostics,
 
2611
                  OPT_DIAGNOSTICS,
 
2612
                  "Perform diagnostics on the authentication chain"},
2584
2613
                { "require-membership-of", 0, POPT_ARG_STRING, &require_membership_of, OPT_REQUIRE_MEMBERSHIP, "Require that a user be a member of this group (either name or SID) for authentication to succeed" },
2585
2614
                { "pam-winbind-conf", 0, POPT_ARG_STRING, &opt_pam_winbind_conf, OPT_PAM_WINBIND_CONF, "Require that request must set WBFLAG_PAM_CONTACT_TRUSTDOM when krb5 auth is required" },
2586
2615
                POPT_COMMON_CONFIGFILE
2591
2620
        /* Samba client initialisation */
2592
2621
        load_case_tables();
2593
2622
 
2594
 
        dbf = x_stderr;
 
2623
        setup_logging("ntlm_auth", DEBUG_STDERR);
2595
2624
 
2596
2625
        /* Parse options */
2597
2626