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/smbd/seal.c

    r740 r988  
    33   SMB Transport encryption (sealing) code - server code.
    44   Copyright (C) Jeremy Allison 2007.
    5    
     5
    66   This program is free software; you can redistribute it and/or modify
    77   it under the terms of the GNU General Public License as published by
    88   the Free Software Foundation; either version 3 of the License, or
    99   (at your option) any later version.
    10    
     10
    1111   This program is distributed in the hope that it will be useful,
    1212   but WITHOUT ANY WARRANTY; without even the implied warranty of
    1313   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    1414   GNU General Public License for more details.
    15    
     15
    1616   You should have received a copy of the GNU General Public License
    1717   along with this program.  If not, see <http://www.gnu.org/licenses/>.
     
    2121#include "smbd/smbd.h"
    2222#include "smbd/globals.h"
    23 #include "../libcli/auth/spnego.h"
    24 #include "../libcli/auth/ntlmssp.h"
    25 #include "ntlmssp_wrap.h"
    26 #include "smb_crypt.h"
    27 #include "../lib/util/asn1.h"
     23#include "../libcli/smb/smb_seal.h"
    2824#include "auth.h"
    2925#include "libsmb/libsmb.h"
     26#include "../lib/tsocket/tsocket.h"
     27#include "auth/gensec/gensec.h"
    3028
    3129/******************************************************************************
     
    3432
    3533/******************************************************************************
    36  Global server state.
    37 ******************************************************************************/
    38 
    39 struct smb_srv_trans_enc_ctx {
    40         struct smb_trans_enc_state *es;
    41         struct auth_ntlmssp_state *auth_ntlmssp_state; /* Must be kept in sync with pointer in ec->ntlmssp_state. */
    42 };
    43 
    44 /******************************************************************************
    4534 Return global enc context - this must change if we ever do multiple contexts.
    4635******************************************************************************/
    4736
    48 uint16_t srv_enc_ctx(void)
    49 {
    50         return srv_trans_enc_ctx->es->enc_ctx_num;
     37static uint16_t srv_enc_ctx(const struct smb_trans_enc_state *es)
     38{
     39        return es->enc_ctx_num;
    5140}
    5241
     
    7362
    7463        /* Encrypted messages are 0xFF'E'<ctx> */
    75         if (srv_trans_enc_ctx && enc_num == srv_enc_ctx()) {
     64        if (srv_trans_enc_ctx && enc_num == srv_enc_ctx(srv_trans_enc_ctx)) {
    7665                return true;
    7766        }
     
    8069
    8170/******************************************************************************
    82  Create an auth_ntlmssp_state and ensure pointer copy is correct.
    83 ******************************************************************************/
    84 
    85 static NTSTATUS make_auth_ntlmssp(struct smb_srv_trans_enc_ctx *ec)
    86 {
    87         NTSTATUS status = auth_ntlmssp_start(&ec->auth_ntlmssp_state);
     71 Create an gensec_security and ensure pointer copy is correct.
     72******************************************************************************/
     73
     74static NTSTATUS make_auth_gensec(const struct tsocket_address *remote_address,
     75                                 struct smb_trans_enc_state *es)
     76{
     77        NTSTATUS status;
     78
     79        status = auth_generic_prepare(es, remote_address,
     80                                      &es->gensec_security);
    8881        if (!NT_STATUS_IS_OK(status)) {
    8982                return nt_status_squash(status);
    9083        }
    9184
     85        gensec_want_feature(es->gensec_security, GENSEC_FEATURE_SEAL);
     86
    9287        /*
    93          * We must remember to update the pointer copy for the common
    94          * functions after any auth_ntlmssp_start/auth_ntlmssp_end.
    95          */
    96         ec->es->s.ntlmssp_state = auth_ntlmssp_get_ntlmssp_state(ec->auth_ntlmssp_state);
    97         return status;
    98 }
    99 
    100 /******************************************************************************
    101  Destroy an auth_ntlmssp_state and ensure pointer copy is correct.
    102 ******************************************************************************/
    103 
    104 static void destroy_auth_ntlmssp(struct smb_srv_trans_enc_ctx *ec)
    105 {
    106         /*
    107          * We must remember to update the pointer copy for the common
    108          * functions after any auth_ntlmssp_start/auth_ntlmssp_end.
    109          */
    110 
    111         if (ec->auth_ntlmssp_state) {
    112                 TALLOC_FREE(ec->auth_ntlmssp_state);
    113                 /* The auth_ntlmssp_end killed this already. */
    114                 ec->es->s.ntlmssp_state = NULL;
    115         }
    116 }
    117 
    118 #if defined(HAVE_GSSAPI) && defined(HAVE_KRB5)
    119 
    120 /******************************************************************************
    121  Import a name.
    122 ******************************************************************************/
    123 
    124 static NTSTATUS get_srv_gss_creds(const char *service,
    125                                 const char *name,
    126                                 gss_cred_usage_t cred_type,
    127                                 gss_cred_id_t *p_srv_cred)
    128 {
    129         OM_uint32 ret;
    130         OM_uint32 min;
    131         gss_name_t srv_name;
    132         gss_buffer_desc input_name;
    133         char *host_princ_s = NULL;
    134         NTSTATUS status = NT_STATUS_OK;
    135 
    136         gss_OID_desc nt_hostbased_service =
    137         {10, CONST_DISCARD(char *,"\x2a\x86\x48\x86\xf7\x12\x01\x02\x01\x04")};
    138 
    139         if (asprintf(&host_princ_s, "%s@%s", service, name) == -1) {
    140                 return NT_STATUS_NO_MEMORY;
    141         }
    142 
    143         input_name.value = host_princ_s;
    144         input_name.length = strlen(host_princ_s) + 1;
    145 
    146         ret = gss_import_name(&min,
    147                                 &input_name,
    148                                 &nt_hostbased_service,
    149                                 &srv_name);
    150 
    151         DEBUG(10,("get_srv_gss_creds: imported name %s\n",
    152                 host_princ_s ));
    153 
    154         if (ret != GSS_S_COMPLETE) {
    155                 SAFE_FREE(host_princ_s);
    156                 return map_nt_error_from_gss(ret, min);
    157         }
    158 
    159         /*
    160          * We're accessing the krb5.keytab file here.
     88         * We could be accessing the secrets.tdb or krb5.keytab file here.
    16189         * ensure we have permissions to do so.
    16290         */
    16391        become_root();
    16492
    165         ret = gss_acquire_cred(&min,
    166                                 srv_name,
    167                                 GSS_C_INDEFINITE,
    168                                 GSS_C_NULL_OID_SET,
    169                                 cred_type,
    170                                 p_srv_cred,
    171                                 NULL,
    172                                 NULL);
     93        status = gensec_start_mech_by_oid(es->gensec_security, GENSEC_OID_SPNEGO);
     94
    17395        unbecome_root();
    17496
    175         if (ret != GSS_S_COMPLETE) {
    176                 ADS_STATUS adss = ADS_ERROR_GSS(ret, min);
    177                 DEBUG(10,("get_srv_gss_creds: gss_acquire_cred failed with %s\n",
    178                         ads_errstr(adss)));
    179                 status = map_nt_error_from_gss(ret, min);
    180         }
    181 
    182         SAFE_FREE(host_princ_s);
    183         gss_release_name(&min, &srv_name);
     97        if (!NT_STATUS_IS_OK(status)) {
     98                return nt_status_squash(status);
     99        }
     100
    184101        return status;
    185102}
    186103
    187104/******************************************************************************
    188  Create a gss state.
    189  Try and get the cifs/server@realm principal first, then fall back to
    190  host/server@realm.
    191 ******************************************************************************/
    192 
    193 static NTSTATUS make_auth_gss(struct smb_srv_trans_enc_ctx *ec)
    194 {
    195         NTSTATUS status;
    196         gss_cred_id_t srv_cred;
    197         fstring fqdn;
    198 
    199         name_to_fqdn(fqdn, global_myname());
    200         strlower_m(fqdn);
    201 
    202         status = get_srv_gss_creds("cifs", fqdn, GSS_C_ACCEPT, &srv_cred);
    203         if (!NT_STATUS_IS_OK(status)) {
    204                 status = get_srv_gss_creds("host", fqdn, GSS_C_ACCEPT, &srv_cred);
    205                 if (!NT_STATUS_IS_OK(status)) {
    206                         return nt_status_squash(status);
    207                 }
    208         }
    209 
    210         ec->es->s.gss_state = SMB_MALLOC_P(struct smb_tran_enc_state_gss);
    211         if (!ec->es->s.gss_state) {
    212                 OM_uint32 min;
    213                 gss_release_cred(&min, &srv_cred);
     105 Create a server encryption context.
     106******************************************************************************/
     107
     108static NTSTATUS make_srv_encryption_context(const struct tsocket_address *remote_address,
     109                                            struct smb_trans_enc_state **pp_es)
     110{
     111        NTSTATUS status;
     112        struct smb_trans_enc_state *es;
     113
     114        *pp_es = NULL;
     115
     116        ZERO_STRUCTP(partial_srv_trans_enc_ctx);
     117        es = talloc_zero(NULL, struct smb_trans_enc_state);
     118        if (!es) {
    214119                return NT_STATUS_NO_MEMORY;
    215120        }
    216         ZERO_STRUCTP(ec->es->s.gss_state);
    217         ec->es->s.gss_state->creds = srv_cred;
    218 
    219         /* No context yet. */
    220         ec->es->s.gss_state->gss_ctx = GSS_C_NO_CONTEXT;
    221 
    222         return NT_STATUS_OK;
    223 }
    224 #endif
    225 
    226 /******************************************************************************
    227  Shutdown a server encryption context.
    228 ******************************************************************************/
    229 
    230 static void srv_free_encryption_context(struct smb_srv_trans_enc_ctx **pp_ec)
    231 {
    232         struct smb_srv_trans_enc_ctx *ec = *pp_ec;
    233 
    234         if (!ec) {
    235                 return;
    236         }
    237 
    238         if (ec->es) {
    239                 switch (ec->es->smb_enc_type) {
    240                         case SMB_TRANS_ENC_NTLM:
    241                                 destroy_auth_ntlmssp(ec);
    242                                 break;
    243 #if defined(HAVE_GSSAPI) && defined(HAVE_KRB5)
    244                         case SMB_TRANS_ENC_GSS:
    245                                 break;
    246 #endif
    247                 }
    248                 common_free_encryption_state(&ec->es);
    249         }
    250 
    251         SAFE_FREE(ec);
    252         *pp_ec = NULL;
    253 }
    254 
    255 /******************************************************************************
    256  Create a server encryption context.
    257 ******************************************************************************/
    258 
    259 static NTSTATUS make_srv_encryption_context(enum smb_trans_enc_type smb_enc_type, struct smb_srv_trans_enc_ctx **pp_ec)
    260 {
    261         struct smb_srv_trans_enc_ctx *ec;
    262 
    263         *pp_ec = NULL;
    264 
    265         ec = SMB_MALLOC_P(struct smb_srv_trans_enc_ctx);
    266         if (!ec) {
    267                 return NT_STATUS_NO_MEMORY;
    268         }
    269         ZERO_STRUCTP(partial_srv_trans_enc_ctx);
    270         ec->es = SMB_MALLOC_P(struct smb_trans_enc_state);
    271         if (!ec->es) {
    272                 SAFE_FREE(ec);
    273                 return NT_STATUS_NO_MEMORY;
    274         }
    275         ZERO_STRUCTP(ec->es);
    276         ec->es->smb_enc_type = smb_enc_type;
    277         switch (smb_enc_type) {
    278                 case SMB_TRANS_ENC_NTLM:
    279                         {
    280                                 NTSTATUS status = make_auth_ntlmssp(ec);
    281                                 if (!NT_STATUS_IS_OK(status)) {
    282                                         srv_free_encryption_context(&ec);
    283                                         return status;
    284                                 }
    285                         }
    286                         break;
    287 
    288 #if defined(HAVE_GSSAPI) && defined(HAVE_KRB5)
    289                 case SMB_TRANS_ENC_GSS:
    290                         /* Acquire our credentials by calling gss_acquire_cred here. */
    291                         {
    292                                 NTSTATUS status = make_auth_gss(ec);
    293                                 if (!NT_STATUS_IS_OK(status)) {
    294                                         srv_free_encryption_context(&ec);
    295                                         return status;
    296                                 }
    297                         }
    298                         break;
    299 #endif
    300                 default:
    301                         srv_free_encryption_context(&ec);
    302                         return NT_STATUS_INVALID_PARAMETER;
    303         }
    304         *pp_ec = ec;
     121        status = make_auth_gensec(remote_address,
     122                                  es);
     123        if (!NT_STATUS_IS_OK(status)) {
     124                TALLOC_FREE(es);
     125                return status;
     126        }
     127        *pp_es = es;
    305128        return NT_STATUS_OK;
    306129}
     
    310133******************************************************************************/
    311134
    312 void srv_free_enc_buffer(char *buf)
     135void srv_free_enc_buffer(struct smbXsrv_connection *xconn, char *buf)
    313136{
    314137        /* We know this is an smb buffer, and we
     
    321144
    322145        if (srv_trans_enc_ctx) {
    323                 common_free_enc_buffer(srv_trans_enc_ctx->es, buf);
     146                common_free_enc_buffer(srv_trans_enc_ctx, buf);
    324147        }
    325148}
     
    329152******************************************************************************/
    330153
    331 NTSTATUS srv_decrypt_buffer(char *buf)
     154NTSTATUS srv_decrypt_buffer(struct smbXsrv_connection *xconn, char *buf)
    332155{
    333156        /* Ignore non-session messages. */
     
    337160
    338161        if (srv_trans_enc_ctx) {
    339                 return common_decrypt_buffer(srv_trans_enc_ctx->es, buf);
     162                return common_decrypt_buffer(srv_trans_enc_ctx, buf);
    340163        }
    341164
     
    347170******************************************************************************/
    348171
    349 NTSTATUS srv_encrypt_buffer(char *buf, char **buf_out)
     172NTSTATUS srv_encrypt_buffer(struct smbXsrv_connection *xconn, char *buf,
     173                            char **buf_out)
    350174{
    351175        *buf_out = buf;
     
    357181
    358182        if (srv_trans_enc_ctx) {
    359                 return common_encrypt_buffer(srv_trans_enc_ctx->es, buf, buf_out);
     183                return common_encrypt_buffer(srv_trans_enc_ctx, buf, buf_out);
    360184        }
    361185        /* Not encrypting. */
     
    364188
    365189/******************************************************************************
    366  Do the gss encryption negotiation. Parameters are in/out.
    367  Until success we do everything on the partial enc ctx.
    368 ******************************************************************************/
    369 
    370 #if defined(HAVE_GSSAPI) && defined(HAVE_KRB5)
    371 static NTSTATUS srv_enc_spnego_gss_negotiate(unsigned char **ppdata, size_t *p_data_size, DATA_BLOB secblob)
    372 {
    373         OM_uint32 ret;
    374         OM_uint32 min;
    375         OM_uint32 flags = 0;
    376         gss_buffer_desc in_buf, out_buf;
    377         struct smb_tran_enc_state_gss *gss_state;
    378         DATA_BLOB auth_reply = data_blob_null;
    379         DATA_BLOB response = data_blob_null;
    380         NTSTATUS status;
    381 
    382         if (!partial_srv_trans_enc_ctx) {
    383                 status = make_srv_encryption_context(SMB_TRANS_ENC_GSS, &partial_srv_trans_enc_ctx);
    384                 if (!NT_STATUS_IS_OK(status)) {
    385                         return status;
    386                 }
    387         }
    388 
    389         gss_state = partial_srv_trans_enc_ctx->es->s.gss_state;
    390 
    391         in_buf.value = secblob.data;
    392         in_buf.length = secblob.length;
    393 
    394         out_buf.value = NULL;
    395         out_buf.length = 0;
    396 
    397         become_root();
    398 
    399         ret = gss_accept_sec_context(&min,
    400                                 &gss_state->gss_ctx,
    401                                 gss_state->creds,
    402                                 &in_buf,
    403                                 GSS_C_NO_CHANNEL_BINDINGS,
    404                                 NULL,
    405                                 NULL,           /* Ignore oids. */
    406                                 &out_buf,       /* To return. */
    407                                 &flags,
    408                                 NULL,           /* Ingore time. */
    409                                 NULL);          /* Ignore delegated creds. */
    410         unbecome_root();
    411 
    412         status = gss_err_to_ntstatus(ret, min);
    413         if (ret != GSS_S_COMPLETE && ret != GSS_S_CONTINUE_NEEDED) {
    414                 return status;
    415         }
    416 
    417         /* Ensure we've got sign+seal available. */
    418         if (ret == GSS_S_COMPLETE) {
    419                 if ((flags & (GSS_C_INTEG_FLAG|GSS_C_CONF_FLAG|GSS_C_REPLAY_FLAG|GSS_C_SEQUENCE_FLAG)) !=
    420                                 (GSS_C_INTEG_FLAG|GSS_C_CONF_FLAG|GSS_C_REPLAY_FLAG|GSS_C_SEQUENCE_FLAG)) {
    421                         DEBUG(0,("srv_enc_spnego_gss_negotiate: quality of service not good enough "
    422                                 "for SMB sealing.\n"));
    423                         gss_release_buffer(&min, &out_buf);
    424                         return NT_STATUS_ACCESS_DENIED;
    425                 }
    426         }
    427 
    428         auth_reply = data_blob(out_buf.value, out_buf.length);
    429         gss_release_buffer(&min, &out_buf);
    430 
    431         /* Wrap in SPNEGO. */
    432         response = spnego_gen_auth_response(talloc_tos(), &auth_reply, status, OID_KERBEROS5);
    433         data_blob_free(&auth_reply);
    434 
    435         SAFE_FREE(*ppdata);
    436         *ppdata = (unsigned char *)memdup(response.data, response.length);
    437         if ((*ppdata) == NULL && response.length > 0) {
    438                 status = NT_STATUS_NO_MEMORY;
    439         }
    440         *p_data_size = response.length;
    441 
    442         data_blob_free(&response);
    443 
    444         return status;
    445 }
    446 #endif
    447 
    448 /******************************************************************************
    449  Do the NTLM SPNEGO (or raw) encryption negotiation. Parameters are in/out.
    450  Until success we do everything on the partial enc ctx.
    451 ******************************************************************************/
    452 
    453 static NTSTATUS srv_enc_ntlm_negotiate(unsigned char **ppdata, size_t *p_data_size, DATA_BLOB secblob, bool spnego_wrap)
    454 {
    455         NTSTATUS status;
    456         DATA_BLOB chal = data_blob_null;
    457         DATA_BLOB response = data_blob_null;
    458 
    459         status = make_srv_encryption_context(SMB_TRANS_ENC_NTLM, &partial_srv_trans_enc_ctx);
    460         if (!NT_STATUS_IS_OK(status)) {
    461                 return status;
    462         }
    463 
    464         status = auth_ntlmssp_update(partial_srv_trans_enc_ctx->auth_ntlmssp_state, secblob, &chal);
    465 
    466         /* status here should be NT_STATUS_MORE_PROCESSING_REQUIRED
    467          * for success ... */
    468 
    469         if (spnego_wrap) {
    470                 response = spnego_gen_auth_response(talloc_tos(), &chal, status, OID_NTLMSSP);
    471                 data_blob_free(&chal);
    472         } else {
    473                 /* Return the raw blob. */
    474                 response = chal;
    475         }
    476 
    477         SAFE_FREE(*ppdata);
    478         *ppdata = (unsigned char *)memdup(response.data, response.length);
    479         if ((*ppdata) == NULL && response.length > 0) {
    480                 status = NT_STATUS_NO_MEMORY;
    481         }
    482         *p_data_size = response.length;
    483         data_blob_free(&response);
    484 
    485         return status;
    486 }
    487 
    488 /******************************************************************************
    489190 Do the SPNEGO encryption negotiation. Parameters are in/out.
    490  Based off code in smbd/sesssionsetup.c
    491  Until success we do everything on the partial enc ctx.
    492 ******************************************************************************/
    493 
    494 static NTSTATUS srv_enc_spnego_negotiate(connection_struct *conn,
     191******************************************************************************/
     192
     193NTSTATUS srv_request_encryption_setup(connection_struct *conn,
    495194                                        unsigned char **ppdata,
    496195                                        size_t *p_data_size,
     
    499198{
    500199        NTSTATUS status;
    501         DATA_BLOB blob = data_blob_null;
    502         DATA_BLOB secblob = data_blob_null;
    503         char *kerb_mech = NULL;
    504 
    505         blob = data_blob_const(*ppdata, *p_data_size);
    506 
    507         status = parse_spnego_mechanisms(talloc_tos(), blob, &secblob, &kerb_mech);
    508         if (!NT_STATUS_IS_OK(status)) {
    509                 return nt_status_squash(status);
    510         }
    511 
    512         /* We should have no partial context at this point. */
    513 
    514         srv_free_encryption_context(&partial_srv_trans_enc_ctx);
    515 
    516         if (kerb_mech) {
    517                 TALLOC_FREE(kerb_mech);
    518 
    519 #if defined(HAVE_GSSAPI) && defined(HAVE_KRB5)
    520                 status = srv_enc_spnego_gss_negotiate(ppdata, p_data_size, secblob);
    521 #else
    522                 /* Currently we don't SPNEGO negotiate
    523                  * back to NTLMSSP as we do in sessionsetupX. We should... */
    524                 return NT_STATUS_LOGON_FAILURE;
    525 #endif
    526         } else {
    527                 status = srv_enc_ntlm_negotiate(ppdata, p_data_size, secblob, true);
    528         }
    529 
    530         data_blob_free(&secblob);
    531 
    532         if (!NT_STATUS_EQUAL(status,NT_STATUS_MORE_PROCESSING_REQUIRED) && !NT_STATUS_IS_OK(status)) {
    533                 srv_free_encryption_context(&partial_srv_trans_enc_ctx);
     200        DATA_BLOB blob = data_blob_const(*ppdata, *p_data_size);
     201        DATA_BLOB response = data_blob_null;
     202        struct smb_trans_enc_state *es;
     203
     204        SAFE_FREE(*pparam);
     205        *p_param_size = 0;
     206
     207        if (!partial_srv_trans_enc_ctx) {
     208                /* This is the initial step. */
     209                status = make_srv_encryption_context(conn->sconn->remote_address,
     210                                        &partial_srv_trans_enc_ctx);
     211                if (!NT_STATUS_IS_OK(status)) {
     212                        return status;
     213                }
     214        }
     215
     216        es = partial_srv_trans_enc_ctx;
     217        if (!es || es->gensec_security == NULL) {
     218                TALLOC_FREE(partial_srv_trans_enc_ctx);
     219                return NT_STATUS_INVALID_PARAMETER;
     220        }
     221
     222        /* Second step. */
     223        become_root();
     224        status = gensec_update(es->gensec_security,
     225                               talloc_tos(),
     226                               blob, &response);
     227        unbecome_root();
     228        if (!NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED) &&
     229            !NT_STATUS_IS_OK(status)) {
     230                TALLOC_FREE(partial_srv_trans_enc_ctx);
    534231                return nt_status_squash(status);
    535232        }
     
    540237                        return NT_STATUS_NO_MEMORY;
    541238                }
    542                 SSVAL(*pparam,0,partial_srv_trans_enc_ctx->es->enc_ctx_num);
     239                SSVAL(*pparam, 0, es->enc_ctx_num);
    543240                *p_param_size = 2;
    544241        }
    545242
    546         return status;
    547 }
    548 
    549 /******************************************************************************
    550  Complete a SPNEGO encryption negotiation. Parameters are in/out.
    551  We only get this for a NTLM auth second stage.
    552 ******************************************************************************/
    553 
    554 static NTSTATUS srv_enc_spnego_ntlm_auth(connection_struct *conn,
    555                                         unsigned char **ppdata,
    556                                         size_t *p_data_size,
    557                                         unsigned char **pparam,
    558                                         size_t *p_param_size)
    559 {
    560         NTSTATUS status;
    561         DATA_BLOB blob = data_blob_null;
    562         DATA_BLOB auth = data_blob_null;
    563         DATA_BLOB auth_reply = data_blob_null;
    564         DATA_BLOB response = data_blob_null;
    565         struct smb_srv_trans_enc_ctx *ec = partial_srv_trans_enc_ctx;
    566 
    567         /* We must have a partial context here. */
    568 
    569         if (!ec || !ec->es || ec->auth_ntlmssp_state == NULL || ec->es->smb_enc_type != SMB_TRANS_ENC_NTLM) {
    570                 srv_free_encryption_context(&partial_srv_trans_enc_ctx);
    571                 return NT_STATUS_INVALID_PARAMETER;
    572         }
    573 
    574         blob = data_blob_const(*ppdata, *p_data_size);
    575         if (!spnego_parse_auth(talloc_tos(), blob, &auth)) {
    576                 srv_free_encryption_context(&partial_srv_trans_enc_ctx);
    577                 return NT_STATUS_INVALID_PARAMETER;
    578         }
    579 
    580         status = auth_ntlmssp_update(ec->auth_ntlmssp_state, auth, &auth_reply);
    581         data_blob_free(&auth);
    582 
    583         /* From RFC4178.
    584          *
    585          *    supportedMech
    586          *
    587          *          This field SHALL only be present in the first reply from the
    588          *                target.
    589          * So set mechOID to NULL here.
    590          */
    591 
    592         response = spnego_gen_auth_response(talloc_tos(), &auth_reply, status, NULL);
    593         data_blob_free(&auth_reply);
    594 
    595         if (NT_STATUS_IS_OK(status)) {
    596                 /* Return the context we're using for this encryption state. */
    597                 if (!(*pparam = SMB_MALLOC_ARRAY(unsigned char, 2))) {
    598                         return NT_STATUS_NO_MEMORY;
    599                 }
    600                 SSVAL(*pparam,0,ec->es->enc_ctx_num);
    601                 *p_param_size = 2;
    602         }
    603 
     243        /* Return the raw blob. */
    604244        SAFE_FREE(*ppdata);
    605         *ppdata = (unsigned char *)memdup(response.data, response.length);
     245        *ppdata = (unsigned char *)smb_memdup(response.data, response.length);
    606246        if ((*ppdata) == NULL && response.length > 0)
    607247                return NT_STATUS_NO_MEMORY;
     
    612252
    613253/******************************************************************************
    614  Raw NTLM encryption negotiation. Parameters are in/out.
    615  This function does both steps.
    616 ******************************************************************************/
    617 
    618 static NTSTATUS srv_enc_raw_ntlm_auth(connection_struct *conn,
    619                                         unsigned char **ppdata,
    620                                         size_t *p_data_size,
    621                                         unsigned char **pparam,
    622                                         size_t *p_param_size)
    623 {
    624         NTSTATUS status;
    625         DATA_BLOB blob = data_blob_const(*ppdata, *p_data_size);
    626         DATA_BLOB response = data_blob_null;
    627         struct smb_srv_trans_enc_ctx *ec;
    628 
    629         if (!partial_srv_trans_enc_ctx) {
    630                 /* This is the initial step. */
    631                 status = srv_enc_ntlm_negotiate(ppdata, p_data_size, blob, false);
    632                 if (!NT_STATUS_EQUAL(status,NT_STATUS_MORE_PROCESSING_REQUIRED) && !NT_STATUS_IS_OK(status)) {
    633                         srv_free_encryption_context(&partial_srv_trans_enc_ctx);
    634                         return nt_status_squash(status);
    635                 }
    636                 return status;
    637         }
    638 
    639         ec = partial_srv_trans_enc_ctx;
    640         if (!ec || !ec->es || ec->auth_ntlmssp_state == NULL || ec->es->smb_enc_type != SMB_TRANS_ENC_NTLM) {
    641                 srv_free_encryption_context(&partial_srv_trans_enc_ctx);
     254 Negotiation was successful - turn on server-side encryption.
     255******************************************************************************/
     256
     257static NTSTATUS check_enc_good(struct smb_trans_enc_state *es)
     258{
     259        if (!es) {
     260                return NT_STATUS_LOGON_FAILURE;
     261        }
     262
     263        if (!gensec_have_feature(es->gensec_security, GENSEC_FEATURE_SIGN)) {
    642264                return NT_STATUS_INVALID_PARAMETER;
    643265        }
    644266
    645         /* Second step. */
    646         status = auth_ntlmssp_update(partial_srv_trans_enc_ctx->auth_ntlmssp_state, blob, &response);
    647 
    648         if (NT_STATUS_IS_OK(status)) {
    649                 /* Return the context we're using for this encryption state. */
    650                 if (!(*pparam = SMB_MALLOC_ARRAY(unsigned char, 2))) {
    651                         return NT_STATUS_NO_MEMORY;
    652                 }
    653                 SSVAL(*pparam,0,ec->es->enc_ctx_num);
    654                 *p_param_size = 2;
    655         }
    656 
    657         /* Return the raw blob. */
    658         SAFE_FREE(*ppdata);
    659         *ppdata = (unsigned char *)memdup(response.data, response.length);
    660         if ((*ppdata) == NULL && response.length > 0)
    661                 return NT_STATUS_NO_MEMORY;
    662         *p_data_size = response.length;
    663         data_blob_free(&response);
    664         return status;
    665 }
    666 
    667 /******************************************************************************
    668  Do the SPNEGO encryption negotiation. Parameters are in/out.
    669 ******************************************************************************/
    670 
    671 NTSTATUS srv_request_encryption_setup(connection_struct *conn,
    672                                         unsigned char **ppdata,
    673                                         size_t *p_data_size,
    674                                         unsigned char **pparam,
    675                                         size_t *p_param_size)
    676 {
    677         unsigned char *pdata = *ppdata;
    678 
    679         SAFE_FREE(*pparam);
    680         *p_param_size = 0;
    681 
    682         if (*p_data_size < 1) {
     267        if (!gensec_have_feature(es->gensec_security, GENSEC_FEATURE_SEAL)) {
    683268                return NT_STATUS_INVALID_PARAMETER;
    684269        }
    685 
    686         if (pdata[0] == ASN1_APPLICATION(0)) {
    687                 /* its a negTokenTarg packet */
    688                 return srv_enc_spnego_negotiate(conn, ppdata, p_data_size, pparam, p_param_size);
    689         }
    690 
    691         if (pdata[0] == ASN1_CONTEXT(1)) {
    692                 /* It's an auth packet */
    693                 return srv_enc_spnego_ntlm_auth(conn, ppdata, p_data_size, pparam, p_param_size);
    694         }
    695 
    696         /* Maybe it's a raw unwrapped auth ? */
    697         if (*p_data_size < 7) {
    698                 return NT_STATUS_INVALID_PARAMETER;
    699         }
    700 
    701         if (strncmp((char *)pdata, "NTLMSSP", 7) == 0) {
    702                 return srv_enc_raw_ntlm_auth(conn, ppdata, p_data_size, pparam, p_param_size);
    703         }
    704 
    705         DEBUG(1,("srv_request_encryption_setup: Unknown packet\n"));
    706 
    707         return NT_STATUS_LOGON_FAILURE;
    708 }
    709 
    710 /******************************************************************************
    711  Negotiation was successful - turn on server-side encryption.
    712 ******************************************************************************/
    713 
    714 static NTSTATUS check_enc_good(struct smb_srv_trans_enc_ctx *ec)
    715 {
    716         if (!ec || !ec->es) {
    717                 return NT_STATUS_LOGON_FAILURE;
    718         }
    719 
    720         if (ec->es->smb_enc_type == SMB_TRANS_ENC_NTLM) {
    721                 if (!auth_ntlmssp_negotiated_sign((ec->auth_ntlmssp_state))) {
    722                         return NT_STATUS_INVALID_PARAMETER;
    723                 }
    724 
    725                 if (!auth_ntlmssp_negotiated_seal((ec->auth_ntlmssp_state))) {
    726                         return NT_STATUS_INVALID_PARAMETER;
    727                 }
    728         }
    729         /* Todo - check gssapi case. */
    730 
    731270        return NT_STATUS_OK;
    732271}
     
    746285        }
    747286        /* Throw away the context we're using currently (if any). */
    748         srv_free_encryption_context(&srv_trans_enc_ctx);
     287        TALLOC_FREE(srv_trans_enc_ctx);
    749288
    750289        /* Steal the partial pointer. Deliberate shallow copy. */
    751290        srv_trans_enc_ctx = partial_srv_trans_enc_ctx;
    752         srv_trans_enc_ctx->es->enc_on = true;
     291        srv_trans_enc_ctx->enc_on = true;
    753292
    754293        partial_srv_trans_enc_ctx = NULL;
     
    762301******************************************************************************/
    763302
    764 void server_encryption_shutdown(void)
    765 {
    766         srv_free_encryption_context(&partial_srv_trans_enc_ctx);
    767         srv_free_encryption_context(&srv_trans_enc_ctx);
    768 }
     303void server_encryption_shutdown(struct smbXsrv_connection *xconn)
     304{
     305        TALLOC_FREE(partial_srv_trans_enc_ctx);
     306        TALLOC_FREE(srv_trans_enc_ctx);
     307}
Note: See TracChangeset for help on using the changeset viewer.