Ignore:
Timestamp:
Nov 24, 2016, 1:14:11 PM (9 years ago)
Author:
Silvan Scherrer
Message:

Samba Server: update vendor to version 4.4.3

File:
1 edited

Legend:

Unmodified
Added
Removed
  • vendor/current/source3/libsmb/clifsinfo.c

    r746 r988  
    44   Copyright (C) Stefan (metze) Metzmacher      2003
    55   Copyright (C) Jeremy Allison 2007
     6   Copyright (C) Andrew Bartlett 2011
    67
    78   This program is free software; you can redistribute it and/or modify
     
    2122#include "includes.h"
    2223#include "libsmb/libsmb.h"
    23 #include "../libcli/auth/spnego.h"
    24 #include "../libcli/auth/ntlmssp.h"
    2524#include "../lib/util/tevent_ntstatus.h"
    2625#include "async_smb.h"
    27 #include "smb_crypt.h"
     26#include "../libcli/smb/smb_seal.h"
    2827#include "trans2.h"
     28#include "auth_generic.h"
     29#include "auth/gensec/gensec.h"
     30#include "../libcli/smb/smbXcli_base.h"
     31#include "auth/credentials/credentials.h"
    2932
    3033/****************************************************************************
     
    116119}
    117120
    118 NTSTATUS cli_unix_extensions_version(struct cli_state *cli, uint16 *pmajor,
    119                                      uint16 *pminor, uint32 *pcaplow,
    120                                      uint32 *pcaphigh)
     121NTSTATUS cli_unix_extensions_version(struct cli_state *cli, uint16_t *pmajor,
     122                                     uint16_t *pminor, uint32_t *pcaplow,
     123                                     uint32_t *pcaphigh)
    121124{
    122125        TALLOC_CTX *frame = talloc_stackframe();
    123         struct event_context *ev;
     126        struct tevent_context *ev;
    124127        struct tevent_req *req;
    125128        NTSTATUS status = NT_STATUS_OK;
    126129
    127         if (cli_has_async_calls(cli)) {
     130        if (smbXcli_conn_has_async_calls(cli->conn)) {
    128131                /*
    129132                 * Can't use sync call while an async call is in flight
     
    133136        }
    134137
    135         ev = event_context_init(frame);
     138        ev = samba_tevent_context_init(frame);
    136139        if (ev == NULL) {
    137140                status = NT_STATUS_NO_MEMORY;
     
    145148        }
    146149
    147         if (!tevent_req_poll(req, ev)) {
    148                 status = map_nt_error_from_unix(errno);
     150        if (!tevent_req_poll_ntstatus(req, ev, &status)) {
    149151                goto fail;
    150152        }
     
    231233
    232234NTSTATUS cli_set_unix_extensions_capabilities(struct cli_state *cli,
    233                                               uint16 major, uint16 minor,
    234                                               uint32 caplow, uint32 caphigh)
     235                                              uint16_t major, uint16_t minor,
     236                                              uint32_t caplow, uint32_t caphigh)
    235237{
    236238        struct tevent_context *ev;
     
    238240        NTSTATUS status = NT_STATUS_NO_MEMORY;
    239241
    240         if (cli_has_async_calls(cli)) {
     242        if (smbXcli_conn_has_async_calls(cli->conn)) {
    241243                return NT_STATUS_INVALID_PARAMETER;
    242244        }
    243         ev = tevent_context_init(talloc_tos());
     245        ev = samba_tevent_context_init(talloc_tos());
    244246        if (ev == NULL) {
    245247                goto fail;
     
    335337        NTSTATUS status = NT_STATUS_NO_MEMORY;
    336338
    337         if (cli_has_async_calls(cli)) {
     339        if (smbXcli_conn_has_async_calls(cli->conn)) {
    338340                return NT_STATUS_INVALID_PARAMETER;
    339341        }
    340         ev = tevent_context_init(talloc_tos());
     342        ev = samba_tevent_context_init(talloc_tos());
    341343        if (ev == NULL) {
    342344                goto fail;
     
    355357}
    356358
    357 NTSTATUS cli_get_fs_volume_info(struct cli_state *cli, fstring volume_name,
    358                                 uint32 *pserial_number, time_t *pdate)
    359 {
    360         NTSTATUS status;
    361         uint16 setup[1];
     359NTSTATUS cli_get_fs_volume_info(struct cli_state *cli,
     360                                TALLOC_CTX *mem_ctx,
     361                                char **_volume_name,
     362                                uint32_t *pserial_number,
     363                                time_t *pdate)
     364{
     365        NTSTATUS status;
     366        uint16_t recv_flags2;
     367        uint16_t setup[1];
    362368        uint8_t param[2];
    363369        uint8_t *rdata;
    364370        uint32_t rdata_count;
    365371        unsigned int nlen;
     372        char *volume_name = NULL;
    366373
    367374        SSVAL(setup, 0, TRANSACT2_QFSINFO);
     
    373380                           param, 2, 0,
    374381                           NULL, 0, 560,
    375                            NULL,
     382                           &recv_flags2,
    376383                           NULL, 0, NULL,
    377384                           NULL, 0, NULL,
    378                            &rdata, 10, &rdata_count);
     385                           &rdata, 18, &rdata_count);
    379386        if (!NT_STATUS_IS_OK(status)) {
    380387                return status;
     
    390397        }
    391398        nlen = IVAL(rdata,12);
    392         clistr_pull(cli->inbuf, volume_name, rdata + 18, sizeof(fstring),
    393                     nlen, STR_UNICODE);
     399        if (nlen > (rdata_count - 18)) {
     400                TALLOC_FREE(rdata);
     401                return NT_STATUS_INVALID_NETWORK_RESPONSE;
     402        }
     403
     404        clistr_pull_talloc(mem_ctx,
     405                           (const char *)rdata,
     406                           recv_flags2,
     407                           &volume_name,
     408                           rdata + 18,
     409                           nlen, STR_UNICODE);
     410        if (volume_name == NULL) {
     411                status = map_nt_error_from_unix(errno);
     412                TALLOC_FREE(rdata);
     413                return status;
     414        }
    394415
    395416        /* todo: but not yet needed
     
    397418         */
    398419
     420        *_volume_name = volume_name;
    399421        TALLOC_FREE(rdata);
    400422        return NT_STATUS_OK;
     
    408430                                   uint64_t *bytes_per_sector)
    409431{
    410         uint16 setup[1];
     432        uint16_t setup[1];
    411433        uint8_t param[2];
    412434        uint8_t *rdata = NULL;
     
    452474
    453475NTSTATUS cli_get_posix_fs_info(struct cli_state *cli,
    454                                uint32 *optimal_transfer_size,
    455                                uint32 *block_size,
     476                               uint32_t *optimal_transfer_size,
     477                               uint32_t *block_size,
    456478                               uint64_t *total_blocks,
    457479                               uint64_t *blocks_available,
     
    461483                               uint64_t *fs_identifier)
    462484{
    463         uint16 setup[1];
     485        uint16_t setup[1];
    464486        uint8_t param[2];
    465487        uint8_t *rdata = NULL;
     
    549571
    550572/******************************************************************************
    551  Make a client state struct.
    552 ******************************************************************************/
    553 
    554 static struct smb_trans_enc_state *make_cli_enc_state(enum smb_trans_enc_type smb_enc_type)
    555 {
    556         struct smb_trans_enc_state *es = NULL;
    557         es = SMB_MALLOC_P(struct smb_trans_enc_state);
    558         if (!es) {
    559                 return NULL;
    560         }
    561         ZERO_STRUCTP(es);
    562         es->smb_enc_type = smb_enc_type;
    563 
    564 #if defined(HAVE_GSSAPI) && defined(HAVE_KRB5)
    565         if (smb_enc_type == SMB_TRANS_ENC_GSS) {
    566                 es->s.gss_state = SMB_MALLOC_P(struct smb_tran_enc_state_gss);
    567                 if (!es->s.gss_state) {
    568                         SAFE_FREE(es);
    569                         return NULL;
    570                 }
    571                 ZERO_STRUCTP(es->s.gss_state);
    572         }
    573 #endif
    574         return es;
    575 }
    576 
    577 /******************************************************************************
    578573 Start a raw ntlmssp encryption.
    579574******************************************************************************/
     
    588583        DATA_BLOB param_out = data_blob_null;
    589584        NTSTATUS status = NT_STATUS_UNSUCCESSFUL;
    590         struct smb_trans_enc_state *es = make_cli_enc_state(SMB_TRANS_ENC_NTLM);
    591 
     585        struct auth_generic_state *auth_generic_state;
     586        struct smb_trans_enc_state *es = talloc_zero(NULL, struct smb_trans_enc_state);
    592587        if (!es) {
    593588                return NT_STATUS_NO_MEMORY;
    594589        }
    595         status = ntlmssp_client_start(NULL,
    596                                       global_myname(),
    597                                       lp_workgroup(),
    598                                       lp_client_ntlmv2_auth(),
    599                                       &es->s.ntlmssp_state);
    600         if (!NT_STATUS_IS_OK(status)) {
    601                 goto fail;
    602         }
    603 
    604         ntlmssp_want_feature(es->s.ntlmssp_state, NTLMSSP_FEATURE_SESSION_KEY);
    605         es->s.ntlmssp_state->neg_flags |= (NTLMSSP_NEGOTIATE_SIGN|NTLMSSP_NEGOTIATE_SEAL);
    606 
    607         if (!NT_STATUS_IS_OK(status = ntlmssp_set_username(es->s.ntlmssp_state, user))) {
    608                 goto fail;
    609         }
    610         if (!NT_STATUS_IS_OK(status = ntlmssp_set_domain(es->s.ntlmssp_state, domain))) {
    611                 goto fail;
    612         }
    613         if (!NT_STATUS_IS_OK(status = ntlmssp_set_password(es->s.ntlmssp_state, pass))) {
     590        status = auth_generic_client_prepare(es,
     591                                             &auth_generic_state);
     592        if (!NT_STATUS_IS_OK(status)) {
     593                goto fail;
     594        }
     595
     596        gensec_want_feature(auth_generic_state->gensec_security, GENSEC_FEATURE_SESSION_KEY);
     597        gensec_want_feature(auth_generic_state->gensec_security, GENSEC_FEATURE_SEAL);
     598
     599        if (!NT_STATUS_IS_OK(status = auth_generic_set_username(auth_generic_state, user))) {
     600                goto fail;
     601        }
     602        if (!NT_STATUS_IS_OK(status = auth_generic_set_domain(auth_generic_state, domain))) {
     603                goto fail;
     604        }
     605        if (!NT_STATUS_IS_OK(status = auth_generic_set_password(auth_generic_state, pass))) {
     606                goto fail;
     607        }
     608
     609        if (!NT_STATUS_IS_OK(status = auth_generic_client_start(auth_generic_state, GENSEC_OID_NTLMSSP))) {
    614610                goto fail;
    615611        }
    616612
    617613        do {
    618                 status = ntlmssp_update(es->s.ntlmssp_state, blob_in, &blob_out);
     614                status = gensec_update(auth_generic_state->gensec_security, auth_generic_state,
     615                                       blob_in, &blob_out);
    619616                data_blob_free(&blob_in);
    620617                data_blob_free(&param_out);
     
    640637
    641638        if (NT_STATUS_IS_OK(status)) {
     639                es->enc_on = true;
    642640                /* Replace the old state, if any. */
    643                 if (cli->trans_enc_state) {
    644                         common_free_encryption_state(&cli->trans_enc_state);
    645                 }
    646                 cli->trans_enc_state = es;
    647                 cli->trans_enc_state->enc_on = True;
     641                /* We only need the gensec_security part from here.
     642                 * es is a malloc()ed pointer, so we cannot make
     643                 * gensec_security a talloc child */
     644                es->gensec_security = talloc_move(NULL,
     645                                                  &auth_generic_state->gensec_security);
     646                smb1cli_conn_set_encryption(cli->conn, es);
    648647                es = NULL;
    649648        }
    650649
    651650  fail:
    652 
    653         common_free_encryption_state(&es);
    654         return status;
    655 }
    656 
    657 #if defined(HAVE_GSSAPI) && defined(HAVE_KRB5)
    658 
    659 #ifndef SMB_GSS_REQUIRED_FLAGS
    660 #define SMB_GSS_REQUIRED_FLAGS (GSS_C_CONF_FLAG|GSS_C_INTEG_FLAG|GSS_C_MUTUAL_FLAG|GSS_C_REPLAY_FLAG|GSS_C_SEQUENCE_FLAG)
    661 #endif
    662 
    663 /******************************************************************************
    664  Get client gss blob to send to a server.
    665 ******************************************************************************/
    666 
    667 static NTSTATUS make_cli_gss_blob(TALLOC_CTX *ctx,
    668                                 struct smb_trans_enc_state *es,
    669                                 const char *service,
    670                                 const char *host,
    671                                 NTSTATUS status_in,
    672                                 DATA_BLOB spnego_blob_in,
    673                                 DATA_BLOB *p_blob_out)
    674 {
    675         const char *krb_mechs[] = {OID_KERBEROS5, NULL};
    676         OM_uint32 ret;
    677         OM_uint32 min;
    678         gss_name_t srv_name;
    679         gss_buffer_desc input_name;
    680         gss_buffer_desc *p_tok_in;
    681         gss_buffer_desc tok_out, tok_in;
    682         DATA_BLOB blob_out = data_blob_null;
    683         DATA_BLOB blob_in = data_blob_null;
    684         char *host_princ_s = NULL;
    685         OM_uint32 ret_flags = 0;
    686         NTSTATUS status = NT_STATUS_OK;
    687 
    688         gss_OID_desc nt_hostbased_service =
    689         {10, CONST_DISCARD(char *,"\x2a\x86\x48\x86\xf7\x12\x01\x02\x01\x04")};
    690 
    691         memset(&tok_out, '\0', sizeof(tok_out));
    692 
    693         /* Get a ticket for the service@host */
    694         if (asprintf(&host_princ_s, "%s@%s", service, host) == -1) {
    695                 return NT_STATUS_NO_MEMORY;
    696         }
    697 
    698         input_name.value = host_princ_s;
    699         input_name.length = strlen(host_princ_s) + 1;
    700 
    701         ret = gss_import_name(&min,
    702                                 &input_name,
    703                                 &nt_hostbased_service,
    704                                 &srv_name);
    705 
    706         if (ret != GSS_S_COMPLETE) {
    707                 SAFE_FREE(host_princ_s);
    708                 return map_nt_error_from_gss(ret, min);
    709         }
    710 
    711         if (spnego_blob_in.length == 0) {
    712                 p_tok_in = GSS_C_NO_BUFFER;
    713         } else {
    714                 /* Remove the SPNEGO wrapper */
    715                 if (!spnego_parse_auth_response(ctx, spnego_blob_in, status_in, OID_KERBEROS5, &blob_in)) {
    716                         status = NT_STATUS_UNSUCCESSFUL;
    717                         goto fail;
    718                 }
    719                 tok_in.value = blob_in.data;
    720                 tok_in.length = blob_in.length;
    721                 p_tok_in = &tok_in;
    722         }
    723 
    724         ret = gss_init_sec_context(&min,
    725                                 GSS_C_NO_CREDENTIAL, /* Use our default cred. */
    726                                 &es->s.gss_state->gss_ctx,
    727                                 srv_name,
    728                                 GSS_C_NO_OID, /* default OID. */
    729                                 GSS_C_MUTUAL_FLAG | GSS_C_REPLAY_FLAG | GSS_C_SEQUENCE_FLAG | GSS_C_DELEG_FLAG,
    730                                 GSS_C_INDEFINITE,       /* requested ticket lifetime. */
    731                                 NULL,   /* no channel bindings */
    732                                 p_tok_in,
    733                                 NULL,   /* ignore mech type */
    734                                 &tok_out,
    735                                 &ret_flags,
    736                                 NULL);  /* ignore time_rec */
    737 
    738         status = map_nt_error_from_gss(ret, min);
    739         if (!NT_STATUS_IS_OK(status) && !NT_STATUS_EQUAL(status,NT_STATUS_MORE_PROCESSING_REQUIRED)) {
    740                 ADS_STATUS adss = ADS_ERROR_GSS(ret, min);
    741                 DEBUG(10,("make_cli_gss_blob: gss_init_sec_context failed with %s\n",
    742                         ads_errstr(adss)));
    743                 goto fail;
    744         }
    745 
    746         if ((ret_flags & SMB_GSS_REQUIRED_FLAGS) != SMB_GSS_REQUIRED_FLAGS) {
    747                 status = NT_STATUS_ACCESS_DENIED;
    748         }
    749 
    750         blob_out = data_blob_talloc(ctx, tok_out.value, tok_out.length);
    751 
    752         /* Wrap in an SPNEGO wrapper */
    753         *p_blob_out = spnego_gen_negTokenInit(ctx, krb_mechs, &blob_out, NULL);
    754 
    755   fail:
    756 
    757         data_blob_free(&blob_out);
    758         data_blob_free(&blob_in);
    759         SAFE_FREE(host_princ_s);
    760         gss_release_name(&min, &srv_name);
    761         if (tok_out.value) {
    762                 gss_release_buffer(&min, &tok_out);
    763         }
     651        TALLOC_FREE(es);
    764652        return status;
    765653}
     
    775663        DATA_BLOB param_out = data_blob_null;
    776664        NTSTATUS status = NT_STATUS_UNSUCCESSFUL;
    777         fstring fqdn;
    778         const char *servicename;
    779         struct smb_trans_enc_state *es = make_cli_enc_state(SMB_TRANS_ENC_GSS);
     665        struct auth_generic_state *auth_generic_state;
     666        struct smb_trans_enc_state *es = talloc_zero(NULL, struct smb_trans_enc_state);
    780667
    781668        if (!es) {
     
    783670        }
    784671
    785         name_to_fqdn(fqdn, cli->desthost);
    786         strlower_m(fqdn);
    787 
    788         servicename = "cifs";
    789         status = make_cli_gss_blob(talloc_tos(), es, servicename, fqdn, NT_STATUS_OK, blob_recv, &blob_send);
    790         if (!NT_STATUS_EQUAL(status,NT_STATUS_MORE_PROCESSING_REQUIRED)) {
    791                 servicename = "host";
    792                 status = make_cli_gss_blob(talloc_tos(), es, servicename, fqdn, NT_STATUS_OK, blob_recv, &blob_send);
    793                 if (!NT_STATUS_EQUAL(status,NT_STATUS_MORE_PROCESSING_REQUIRED)) {
    794                         goto fail;
    795                 }
    796         }
     672        status = auth_generic_client_prepare(es,
     673                                             &auth_generic_state);
     674        if (!NT_STATUS_IS_OK(status)) {
     675                goto fail;
     676        }
     677
     678        gensec_want_feature(auth_generic_state->gensec_security, GENSEC_FEATURE_SESSION_KEY);
     679        gensec_want_feature(auth_generic_state->gensec_security, GENSEC_FEATURE_SEAL);
     680
     681        cli_credentials_set_kerberos_state(auth_generic_state->credentials,
     682                                           CRED_MUST_USE_KERBEROS);
     683
     684        status = gensec_set_target_service(auth_generic_state->gensec_security, "cifs");
     685        if (!NT_STATUS_IS_OK(status)) {
     686                goto fail;
     687        }
     688
     689        status = gensec_set_target_hostname(auth_generic_state->gensec_security,
     690                                            smbXcli_conn_remote_name(cli->conn));
     691        if (!NT_STATUS_IS_OK(status)) {
     692                goto fail;
     693        }
     694
     695        if (!NT_STATUS_IS_OK(status = auth_generic_client_start(auth_generic_state, GENSEC_OID_SPNEGO))) {
     696                goto fail;
     697        }
     698
     699        status = gensec_update(auth_generic_state->gensec_security, talloc_tos(),
     700                               blob_recv, &blob_send);
    797701
    798702        do {
     
    803707                }
    804708                data_blob_free(&blob_send);
    805                 status = make_cli_gss_blob(talloc_tos(), es, servicename, fqdn, status, blob_recv, &blob_send);
     709                status = gensec_update(auth_generic_state->gensec_security, talloc_tos(),
     710                                       blob_recv, &blob_send);
    806711        } while (NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED));
    807712        data_blob_free(&blob_recv);
    808713
    809714        if (NT_STATUS_IS_OK(status)) {
     715                if (!gensec_have_feature(auth_generic_state->gensec_security,
     716                                         GENSEC_FEATURE_SIGN) ||
     717                    !gensec_have_feature(auth_generic_state->gensec_security,
     718                                         GENSEC_FEATURE_SEAL)) {
     719                        status = NT_STATUS_ACCESS_DENIED;
     720                }
     721        }
     722
     723        if (NT_STATUS_IS_OK(status)) {
     724                es->enc_on = true;
    810725                /* Replace the old state, if any. */
    811                 if (cli->trans_enc_state) {
    812                         common_free_encryption_state(&cli->trans_enc_state);
    813                 }
    814                 cli->trans_enc_state = es;
    815                 cli->trans_enc_state->enc_on = True;
     726                /* We only need the gensec_security part from here.
     727                 * es is a malloc()ed pointer, so we cannot make
     728                 * gensec_security a talloc child */
     729                es->gensec_security = talloc_move(es,
     730                                                  &auth_generic_state->gensec_security);
     731                smb1cli_conn_set_encryption(cli->conn, es);
    816732                es = NULL;
    817733        }
    818 
    819   fail:
    820 
    821         common_free_encryption_state(&es);
     734fail:
     735        TALLOC_FREE(es);
    822736        return status;
    823737}
    824 #else
    825 NTSTATUS cli_gss_smb_encryption_start(struct cli_state *cli)
    826 {
    827         return NT_STATUS_NOT_SUPPORTED;
    828 }
    829 #endif
    830738
    831739/********************************************************************
     
    838746                        const char *domain)
    839747{
    840         uint16 major, minor;
    841         uint32 caplow, caphigh;
     748        uint16_t major, minor;
     749        uint32_t caplow, caphigh;
    842750        NTSTATUS status;
    843751
Note: See TracChangeset for help on using the changeset viewer.