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

Location:
vendor/current/source3/librpc
Files:
3 added
635 deleted
13 edited

Legend:

Unmodified
Added
Removed
  • vendor/current/source3/librpc/crypto/gse.c

    r746 r988  
    33 *  RPC Pipe client and server routines
    44 *  Copyright (C) Simo Sorce 2010.
     5 *  Copyright (C) Andrew Bartlett 2004-2011.
     6 *  Copyright (C) Stefan Metzmacher <metze@samba.org> 2004-2005
    57 *
    68 *  This program is free software; you can redistribute it and/or modify
     
    2224#include "includes.h"
    2325#include "gse.h"
    24 
    25 #if defined(HAVE_KRB5) \
    26         && defined(HAVE_GSSAPI_GSSAPI_EXT_H) \
    27         && defined(HAVE_GSS_WRAP_IOV) \
    28         && defined(HAVE_GSS_GET_NAME_ATTRIBUTE)
    29 
    30 #include "smb_krb5.h"
     26#include "libads/kerberos_proto.h"
     27#include "auth/common_auth.h"
     28#include "auth/gensec/gensec.h"
     29#include "auth/gensec/gensec_internal.h"
     30#include "auth/credentials/credentials.h"
     31#include "../librpc/gen_ndr/dcerpc.h"
     32
     33#if defined(HAVE_KRB5)
     34
     35#include "auth/kerberos/pac_utils.h"
     36#include "auth/kerberos/gssapi_helper.h"
    3137#include "gse_krb5.h"
    3238
    33 #include <gssapi/gssapi.h>
    34 #include <gssapi/gssapi_krb5.h>
    35 #include <gssapi/gssapi_ext.h>
    36 
    37 #ifndef GSS_KRB5_INQ_SSPI_SESSION_KEY_OID
    38 #define GSS_KRB5_INQ_SSPI_SESSION_KEY_OID_LENGTH 11
    39 #define GSS_KRB5_INQ_SSPI_SESSION_KEY_OID "\x2a\x86\x48\x86\xf7\x12\x01\x02\x02\x05\x05"
    40 #endif
    41 
    42 gss_OID_desc gse_sesskey_inq_oid = {
    43         GSS_KRB5_INQ_SSPI_SESSION_KEY_OID_LENGTH,
    44         (void *)GSS_KRB5_INQ_SSPI_SESSION_KEY_OID
    45 };
    46 
    47 #ifndef GSS_KRB5_SESSION_KEY_ENCTYPE_OID
    48 #define GSS_KRB5_SESSION_KEY_ENCTYPE_OID_LENGTH 10
    49 #define GSS_KRB5_SESSION_KEY_ENCTYPE_OID  "\x2a\x86\x48\x86\xf7\x12\x01\x02\x02\x04"
    50 #endif
    51 
    52 gss_OID_desc gse_sesskeytype_oid = {
    53         GSS_KRB5_SESSION_KEY_ENCTYPE_OID_LENGTH,
    54         (void *)GSS_KRB5_SESSION_KEY_ENCTYPE_OID
    55 };
    56 
    57 #define GSE_EXTRACT_RELEVANT_AUTHZ_DATA_OID_LENGTH 12
    58 /*                                          EXTRACTION OID                                 AUTHZ ID */
    59 #define GSE_EXTRACT_RELEVANT_AUTHZ_DATA_OID "\x2a\x86\x48\x86\xf7\x12\x01\x02\x02\x05\x0a" "\x01"
    60 
    61 gss_OID_desc gse_authz_data_oid = {
    62         GSE_EXTRACT_RELEVANT_AUTHZ_DATA_OID_LENGTH,
    63         (void *)GSE_EXTRACT_RELEVANT_AUTHZ_DATA_OID
    64 };
    65 
    66 #ifndef GSS_KRB5_EXTRACT_AUTHTIME_FROM_SEC_CONTEXT_OID
    67 #define GSS_KRB5_EXTRACT_AUTHTIME_FROM_SEC_CONTEXT_OID_LENGTH 11
    68 #define GSS_KRB5_EXTRACT_AUTHTIME_FROM_SEC_CONTEXT_OID "\x2a\x86\x48\x86\xf7\x12\x01\x02\x02\x05\x0c"
    69 #endif
    70 
    71 gss_OID_desc gse_authtime_oid = {
    72         GSS_KRB5_EXTRACT_AUTHTIME_FROM_SEC_CONTEXT_OID_LENGTH,
    73         (void *)GSS_KRB5_EXTRACT_AUTHTIME_FROM_SEC_CONTEXT_OID
    74 };
    75 
    7639static char *gse_errstr(TALLOC_CTX *mem_ctx, OM_uint32 maj, OM_uint32 min);
     40static size_t gensec_gse_sig_size(struct gensec_security *gensec_security,
     41                                  size_t data_size);
    7742
    7843struct gse_context {
     44        gss_ctx_id_t gssapi_context;
     45        gss_name_t server_name;
     46        gss_name_t client_name;
     47        OM_uint32 gss_want_flags, gss_got_flags;
     48        size_t max_wrap_buf_size;
     49        size_t sig_size;
     50
     51        gss_cred_id_t delegated_cred_handle;
     52
     53        NTTIME expire_time;
     54
     55        /* gensec_gse only */
    7956        krb5_context k5ctx;
    8057        krb5_ccache ccache;
    8158        krb5_keytab keytab;
    8259
    83         gss_ctx_id_t gss_ctx;
    84 
    8560        gss_OID_desc gss_mech;
    86         OM_uint32 gss_c_flags;
    8761        gss_cred_id_t creds;
    88         gss_name_t server_name;
    8962
    9063        gss_OID ret_mech;
    91         OM_uint32 ret_flags;
    92         gss_cred_id_t delegated_creds;
    93         gss_name_t client_name;
    94 
    95         bool more_processing;
    96         bool authenticated;
    9764};
    9865
     
    10168{
    10269        struct gse_context *gse_ctx;
    103         OM_uint32 gss_min, gss_maj;
     70        OM_uint32 gss_min;
    10471
    10572        gse_ctx = talloc_get_type_abort(ptr, struct gse_context);
     
    11683                gse_ctx->k5ctx = NULL;
    11784        }
    118         if (gse_ctx->gss_ctx != GSS_C_NO_CONTEXT) {
    119                 gss_maj = gss_delete_sec_context(&gss_min,
    120                                                  &gse_ctx->gss_ctx,
     85        if (gse_ctx->gssapi_context != GSS_C_NO_CONTEXT) {
     86                (void)gss_delete_sec_context(&gss_min,
     87                                                 &gse_ctx->gssapi_context,
    12188                                                 GSS_C_NO_BUFFER);
    12289        }
    12390        if (gse_ctx->server_name) {
    124                 gss_maj = gss_release_name(&gss_min,
     91                (void)gss_release_name(&gss_min,
    12592                                           &gse_ctx->server_name);
    12693        }
    12794        if (gse_ctx->client_name) {
    128                 gss_maj = gss_release_name(&gss_min,
     95                (void)gss_release_name(&gss_min,
    12996                                           &gse_ctx->client_name);
    13097        }
    13198        if (gse_ctx->creds) {
    132                 gss_maj = gss_release_cred(&gss_min,
     99                (void)gss_release_cred(&gss_min,
    133100                                           &gse_ctx->creds);
    134101        }
    135         if (gse_ctx->delegated_creds) {
    136                 gss_maj = gss_release_cred(&gss_min,
    137                                            &gse_ctx->delegated_creds);
    138         }
    139         if (gse_ctx->ret_mech) {
    140                 gss_maj = gss_release_oid(&gss_min,
    141                                           &gse_ctx->ret_mech);
    142         }
     102        if (gse_ctx->delegated_cred_handle) {
     103                (void)gss_release_cred(&gss_min,
     104                                           &gse_ctx->delegated_cred_handle);
     105        }
     106
     107        /* MIT and Heimdal differ as to if you can call
     108         * gss_release_oid() on this OID, generated by
     109         * gss_{accept,init}_sec_context().  However, as long as the
     110         * oid is gss_mech_krb5 (which it always is at the moment),
     111         * then this is a moot point, as both declare this particular
     112         * OID static, and so no memory is lost.  This assert is in
     113         * place to ensure that the programmer who wishes to extend
     114         * this code to EAP or other GSS mechanisms determines an
     115         * implementation-dependent way of releasing any dynamically
     116         * allocated OID */
     117        SMB_ASSERT(smb_gss_oid_equal(&gse_ctx->gss_mech, GSS_C_NO_OID) ||
     118                   smb_gss_oid_equal(&gse_ctx->gss_mech, gss_mech_krb5));
     119
    143120        return 0;
    144121}
     
    160137        talloc_set_destructor((TALLOC_CTX *)gse_ctx, gse_context_destructor);
    161138
     139        gse_ctx->expire_time = GENSEC_EXPIRE_TIME_INFINITY;
     140        gse_ctx->max_wrap_buf_size = UINT16_MAX;
     141
    162142        memcpy(&gse_ctx->gss_mech, gss_mech_krb5, sizeof(gss_OID_desc));
    163143
    164         gse_ctx->gss_c_flags = GSS_C_MUTUAL_FLAG |
     144        gse_ctx->gss_want_flags = GSS_C_MUTUAL_FLAG |
    165145                                GSS_C_DELEG_FLAG |
    166146                                GSS_C_DELEG_POLICY_FLAG |
     
    168148                                GSS_C_SEQUENCE_FLAG;
    169149        if (do_sign) {
    170                 gse_ctx->gss_c_flags |= GSS_C_INTEG_FLAG;
     150                gse_ctx->gss_want_flags |= GSS_C_INTEG_FLAG;
    171151        }
    172152        if (do_seal) {
    173                 gse_ctx->gss_c_flags |= GSS_C_CONF_FLAG;
    174         }
    175 
    176         gse_ctx->gss_c_flags |= add_gss_c_flags;
     153                gse_ctx->gss_want_flags |= GSS_C_INTEG_FLAG;
     154                gse_ctx->gss_want_flags |= GSS_C_CONF_FLAG;
     155        }
     156
     157        gse_ctx->gss_want_flags |= add_gss_c_flags;
    177158
    178159        /* Initialize Kerberos Context */
     
    211192}
    212193
    213 NTSTATUS gse_init_client(TALLOC_CTX *mem_ctx,
    214                           bool do_sign, bool do_seal,
    215                           const char *ccache_name,
    216                           const char *server,
    217                           const char *service,
    218                           const char *username,
    219                           const char *password,
    220                           uint32_t add_gss_c_flags,
    221                           struct gse_context **_gse_ctx)
     194static NTSTATUS gse_init_client(TALLOC_CTX *mem_ctx,
     195                                bool do_sign, bool do_seal,
     196                                const char *ccache_name,
     197                                const char *server,
     198                                const char *service,
     199                                const char *username,
     200                                const char *password,
     201                                uint32_t add_gss_c_flags,
     202                                struct gse_context **_gse_ctx)
    222203{
    223204        struct gse_context *gse_ctx;
    224205        OM_uint32 gss_maj, gss_min;
    225         gss_buffer_desc name_buffer = {0, NULL};
     206        gss_buffer_desc name_buffer = GSS_C_EMPTY_BUFFER;
    226207        gss_OID_set_desc mech_set;
     208#ifdef HAVE_GSS_KRB5_CRED_NO_CI_FLAGS_X
     209        gss_buffer_desc empty_buffer = GSS_C_EMPTY_BUFFER;
     210#endif
    227211        NTSTATUS status;
    228212
     
    238222        }
    239223
    240         name_buffer.value = talloc_asprintf(gse_ctx,
    241                                             "%s@%s", service, server);
     224        /* Guess the realm based on the supplied service, and avoid the GSS libs
     225           doing DNS lookups which may fail.
     226
     227           TODO: Loop with the KDC on some more combinations (local
     228           realm in particular), possibly falling back to
     229           GSS_C_NT_HOSTBASED_SERVICE
     230        */
     231        name_buffer.value = kerberos_get_principal_from_service_hostname(
     232                                        gse_ctx, service, server, lp_realm());
    242233        if (!name_buffer.value) {
    243234                status = NT_STATUS_NO_MEMORY;
     
    246237        name_buffer.length = strlen((char *)name_buffer.value);
    247238        gss_maj = gss_import_name(&gss_min, &name_buffer,
    248                                   GSS_C_NT_HOSTBASED_SERVICE,
     239                                  GSS_C_NT_USER_NAME,
    249240                                  &gse_ctx->server_name);
    250241        if (gss_maj) {
    251                 DEBUG(0, ("gss_import_name failed for %s, with [%s]\n",
     242                DEBUG(5, ("gss_import_name failed for %s, with [%s]\n",
    252243                          (char *)name_buffer.value,
    253244                          gse_errstr(gse_ctx, gss_maj, gss_min)));
     
    270261                                   NULL, NULL);
    271262        if (gss_maj) {
    272                 DEBUG(0, ("gss_acquire_creds failed for %s, with [%s]\n",
    273                           (char *)name_buffer.value,
     263                DEBUG(5, ("gss_acquire_creds failed for GSS_C_NO_NAME with [%s] -"
     264                          "the caller may retry after a kinit.\n",
    274265                          gse_errstr(gse_ctx, gss_maj, gss_min)));
    275266                status = NT_STATUS_INTERNAL_ERROR;
    276267                goto err_out;
    277268        }
     269
     270#ifdef HAVE_GSS_KRB5_CRED_NO_CI_FLAGS_X
     271        /*
     272         * Don't force GSS_C_CONF_FLAG and GSS_C_INTEG_FLAG.
     273         *
     274         * This allows us to disable SIGN and SEAL for
     275         * AUTH_LEVEL_CONNECT and AUTH_LEVEL_INTEGRITY.
     276         *
     277         * https://groups.yahoo.com/neo/groups/cat-ietf/conversations/topics/575
     278         * http://krbdev.mit.edu/rt/Ticket/Display.html?id=6938
     279         */
     280        gss_maj = gss_set_cred_option(&gss_min, &gse_ctx->creds,
     281                                      GSS_KRB5_CRED_NO_CI_FLAGS_X,
     282                                      &empty_buffer);
     283        if (gss_maj) {
     284                DEBUG(0, ("gss_set_cred_option(GSS_KRB5_CRED_NO_CI_FLAGS_X), "
     285                          "failed with [%s]\n",
     286                          gse_errstr(gse_ctx, gss_maj, gss_min)));
     287                status = NT_STATUS_INTERNAL_ERROR;
     288                goto err_out;
     289        }
     290#endif
    278291
    279292        *_gse_ctx = gse_ctx;
     
    287300}
    288301
    289 NTSTATUS gse_get_client_auth_token(TALLOC_CTX *mem_ctx,
    290                                    struct gse_context *gse_ctx,
    291                                   DATA_BLOB *token_in,
    292                                    DATA_BLOB *token_out)
     302static NTSTATUS gse_get_client_auth_token(TALLOC_CTX *mem_ctx,
     303                                          struct gse_context *gse_ctx,
     304                                          const DATA_BLOB *token_in,
     305                                          DATA_BLOB *token_out)
    293306{
    294307        OM_uint32 gss_maj, gss_min;
     
    297310        DATA_BLOB blob = data_blob_null;
    298311        NTSTATUS status;
     312        OM_uint32 time_rec = 0;
     313        struct timeval tv;
    299314
    300315        in_data.value = token_in->data;
     
    303318        gss_maj = gss_init_sec_context(&gss_min,
    304319                                        gse_ctx->creds,
    305                                         &gse_ctx->gss_ctx,
     320                                        &gse_ctx->gssapi_context,
    306321                                        gse_ctx->server_name,
    307322                                        &gse_ctx->gss_mech,
    308                                         gse_ctx->gss_c_flags,
     323                                        gse_ctx->gss_want_flags,
    309324                                        0, GSS_C_NO_CHANNEL_BINDINGS,
    310325                                        &in_data, NULL, &out_data,
    311                                         NULL, NULL);
     326                                        &gse_ctx->gss_got_flags, &time_rec);
    312327        switch (gss_maj) {
    313328        case GSS_S_COMPLETE:
    314329                /* we are done with it */
    315                 gse_ctx->more_processing = false;
     330                tv = timeval_current_ofs(time_rec, 0);
     331                gse_ctx->expire_time = timeval_to_nttime(&tv);
     332
    316333                status = NT_STATUS_OK;
    317334                break;
    318335        case GSS_S_CONTINUE_NEEDED:
    319336                /* we will need a third leg */
    320                 gse_ctx->more_processing = true;
    321                 /* status = NT_STATUS_MORE_PROCESSING_REQUIRED; */
    322                 status = NT_STATUS_OK;
     337                status = NT_STATUS_MORE_PROCESSING_REQUIRED;
    323338                break;
    324339        default:
     
    329344        }
    330345
    331         blob = data_blob_talloc(mem_ctx, out_data.value, out_data.length);
    332         if (!blob.data) {
    333                 status = NT_STATUS_NO_MEMORY;
    334         }
    335 
    336         gss_maj = gss_release_buffer(&gss_min, &out_data);
     346        /* we may be told to return nothing */
     347        if (out_data.length) {
     348                blob = data_blob_talloc(mem_ctx, out_data.value, out_data.length);
     349                if (!blob.data) {
     350                        status = NT_STATUS_NO_MEMORY;
     351                }
     352
     353                gss_maj = gss_release_buffer(&gss_min, &out_data);
     354        }
    337355
    338356done:
     
    341359}
    342360
    343 NTSTATUS gse_init_server(TALLOC_CTX *mem_ctx,
    344                          bool do_sign, bool do_seal,
    345                          uint32_t add_gss_c_flags,
    346                          const char *keytab_name,
    347                          struct gse_context **_gse_ctx)
     361static NTSTATUS gse_init_server(TALLOC_CTX *mem_ctx,
     362                                bool do_sign, bool do_seal,
     363                                uint32_t add_gss_c_flags,
     364                                struct gse_context **_gse_ctx)
    348365{
    349366        struct gse_context *gse_ctx;
    350367        OM_uint32 gss_maj, gss_min;
    351         gss_OID_set_desc mech_set;
    352368        krb5_error_code ret;
    353         const char *ktname;
    354369        NTSTATUS status;
    355370
     
    360375        }
    361376
    362         if (!keytab_name) {
    363                 ret = gse_krb5_get_server_keytab(gse_ctx->k5ctx,
    364                                                  &gse_ctx->keytab);
    365                 if (ret) {
    366                         status = NT_STATUS_INTERNAL_ERROR;
    367                         goto done;
    368                 }
    369                 ret = smb_krb5_keytab_name(gse_ctx, gse_ctx->k5ctx,
    370                                            gse_ctx->keytab, &ktname);
    371                 if (ret) {
    372                         status = NT_STATUS_INTERNAL_ERROR;
    373                         goto done;
    374                 }
    375         } else {
    376                 ktname = keytab_name;
    377         }
    378 
     377        ret = gse_krb5_get_server_keytab(gse_ctx->k5ctx,
     378                                         &gse_ctx->keytab);
     379        if (ret) {
     380                status = NT_STATUS_INTERNAL_ERROR;
     381                goto done;
     382        }
     383
     384#ifdef HAVE_GSS_KRB5_IMPORT_CRED
     385
     386        /* This creates a GSSAPI cred_id_t with the keytab set */
     387        gss_maj = gss_krb5_import_cred(&gss_min, NULL, NULL, gse_ctx->keytab,
     388                                       &gse_ctx->creds);
     389
     390        if (gss_maj != 0
     391            && gss_maj != (GSS_S_CALL_BAD_STRUCTURE|GSS_S_BAD_NAME)) {
     392                DEBUG(0, ("gss_krb5_import_cred failed with [%s]\n",
     393                          gse_errstr(gse_ctx, gss_maj, gss_min)));
     394                status = NT_STATUS_INTERNAL_ERROR;
     395                goto done;
     396
     397                /* This is the error the MIT krb5 1.9 gives when it
     398                 * implements the function, but we do not specify the
     399                 * principal.  However, when we specify the principal
     400                 * as host$@REALM the GSS acceptor fails with 'wrong
     401                 * principal in request'.  Work around the issue by
     402                 * falling back to the alternate approach below. */
     403        } else if (gss_maj == (GSS_S_CALL_BAD_STRUCTURE|GSS_S_BAD_NAME))
     404#endif
    379405        /* FIXME!!!
    380406         * This call sets the default keytab for the whole server, not
    381407         * just for this context. Need to find a way that does not alter
    382408         * the state of the whole server ... */
    383         ret = gsskrb5_register_acceptor_identity(ktname);
    384         if (ret) {
    385                 status = NT_STATUS_INTERNAL_ERROR;
    386                 goto done;
    387         }
    388 
    389         mech_set.count = 1;
    390         mech_set.elements = &gse_ctx->gss_mech;
    391 
    392         gss_maj = gss_acquire_cred(&gss_min,
     409        {
     410                const char *ktname;
     411                gss_OID_set_desc mech_set;
     412
     413                ret = smb_krb5_keytab_name(gse_ctx, gse_ctx->k5ctx,
     414                                   gse_ctx->keytab, &ktname);
     415                if (ret) {
     416                        status = NT_STATUS_INTERNAL_ERROR;
     417                        goto done;
     418                }
     419
     420                ret = gsskrb5_register_acceptor_identity(ktname);
     421                if (ret) {
     422                        status = NT_STATUS_INTERNAL_ERROR;
     423                        goto done;
     424                }
     425
     426                mech_set.count = 1;
     427                mech_set.elements = &gse_ctx->gss_mech;
     428
     429                gss_maj = gss_acquire_cred(&gss_min,
    393430                                   GSS_C_NO_NAME,
    394431                                   GSS_C_INDEFINITE,
     
    397434                                   &gse_ctx->creds,
    398435                                   NULL, NULL);
    399         if (gss_maj) {
    400                 DEBUG(0, ("gss_acquire_creds failed with [%s]\n",
    401                           gse_errstr(gse_ctx, gss_maj, gss_min)));
    402                 status = NT_STATUS_INTERNAL_ERROR;
    403                 goto done;
     436
     437                if (gss_maj) {
     438                        DEBUG(0, ("gss_acquire_creds failed with [%s]\n",
     439                                  gse_errstr(gse_ctx, gss_maj, gss_min)));
     440                        status = NT_STATUS_INTERNAL_ERROR;
     441                        goto done;
     442                }
    404443        }
    405444
     
    415454}
    416455
    417 NTSTATUS gse_get_server_auth_token(TALLOC_CTX *mem_ctx,
    418                                    struct gse_context *gse_ctx,
    419                                   DATA_BLOB *token_in,
    420                                    DATA_BLOB *token_out)
     456static NTSTATUS gse_get_server_auth_token(TALLOC_CTX *mem_ctx,
     457                                          struct gse_context *gse_ctx,
     458                                          const DATA_BLOB *token_in,
     459                                          DATA_BLOB *token_out)
    421460{
    422461        OM_uint32 gss_maj, gss_min;
     
    425464        DATA_BLOB blob = data_blob_null;
    426465        NTSTATUS status;
     466        OM_uint32 time_rec = 0;
     467        struct timeval tv;
    427468
    428469        in_data.value = token_in->data;
     
    430471
    431472        gss_maj = gss_accept_sec_context(&gss_min,
    432                                          &gse_ctx->gss_ctx,
     473                                         &gse_ctx->gssapi_context,
    433474                                         gse_ctx->creds,
    434475                                         &in_data,
     
    437478                                         &gse_ctx->ret_mech,
    438479                                         &out_data,
    439                                          &gse_ctx->ret_flags, NULL,
    440                                          &gse_ctx->delegated_creds);
     480                                         &gse_ctx->gss_got_flags,
     481                                         &time_rec,
     482                                         &gse_ctx->delegated_cred_handle);
    441483        switch (gss_maj) {
    442484        case GSS_S_COMPLETE:
    443485                /* we are done with it */
    444                 gse_ctx->more_processing = false;
    445                 gse_ctx->authenticated = true;
     486                tv = timeval_current_ofs(time_rec, 0);
     487                gse_ctx->expire_time = timeval_to_nttime(&tv);
     488
    446489                status = NT_STATUS_OK;
    447490                break;
    448491        case GSS_S_CONTINUE_NEEDED:
    449492                /* we will need a third leg */
    450                 gse_ctx->more_processing = true;
    451                 /* status = NT_STATUS_MORE_PROCESSING_REQUIRED; */
    452                 status = NT_STATUS_OK;
     493                status = NT_STATUS_MORE_PROCESSING_REQUIRED;
    453494                break;
    454495        default:
    455                 DEBUG(0, ("gss_init_sec_context failed with [%s]\n",
     496                DEBUG(1, ("gss_accept_sec_context failed with [%s]\n",
    456497                          gse_errstr(talloc_tos(), gss_maj, gss_min)));
    457498
    458                 if (gse_ctx->gss_ctx) {
     499                if (gse_ctx->gssapi_context) {
    459500                        gss_delete_sec_context(&gss_min,
    460                                                 &gse_ctx->gss_ctx,
     501                                                &gse_ctx->gssapi_context,
    461502                                                GSS_C_NO_BUFFER);
    462503                }
    463504
    464                 status = NT_STATUS_INTERNAL_ERROR;
    465                 goto done;
     505                /*
     506                 * If we got an output token, make Windows aware of it
     507                 * by telling it that more processing is needed
     508                 */
     509                if (out_data.length > 0) {
     510                        status = NT_STATUS_MORE_PROCESSING_REQUIRED;
     511                        /* Fall through to handle the out token */
     512                } else {
     513                        status = NT_STATUS_LOGON_FAILURE;
     514                        goto done;
     515                }
    466516        }
    467517
     
    481531}
    482532
    483 NTSTATUS gse_verify_server_auth_flags(struct gse_context *gse_ctx)
    484 {
    485         if (!gse_ctx->authenticated) {
    486                 return NT_STATUS_INVALID_HANDLE;
    487         }
    488 
    489         if (memcmp(gse_ctx->ret_mech,
    490                    gss_mech_krb5, sizeof(gss_OID_desc)) != 0) {
    491                 return NT_STATUS_ACCESS_DENIED;
    492         }
    493 
    494         /* GSS_C_MUTUAL_FLAG */
    495         if (gse_ctx->gss_c_flags & GSS_C_MUTUAL_FLAG) {
    496                 if (!(gse_ctx->ret_flags & GSS_C_MUTUAL_FLAG)) {
    497                         return NT_STATUS_ACCESS_DENIED;
    498                 }
    499         }
    500 
    501         /* GSS_C_DELEG_FLAG */
    502         /* GSS_C_DELEG_POLICY_FLAG */
    503         /* GSS_C_REPLAY_FLAG */
    504         /* GSS_C_SEQUENCE_FLAG */
    505 
    506         /* GSS_C_INTEG_FLAG */
    507         if (gse_ctx->gss_c_flags & GSS_C_INTEG_FLAG) {
    508                 if (!(gse_ctx->ret_flags & GSS_C_INTEG_FLAG)) {
    509                         return NT_STATUS_ACCESS_DENIED;
    510                 }
    511         }
    512 
    513         /* GSS_C_CONF_FLAG */
    514         if (gse_ctx->gss_c_flags & GSS_C_CONF_FLAG) {
    515                 if (!(gse_ctx->ret_flags & GSS_C_CONF_FLAG)) {
    516                         return NT_STATUS_ACCESS_DENIED;
    517                 }
    518         }
    519 
    520         return NT_STATUS_OK;
    521 }
    522 
    523533static char *gse_errstr(TALLOC_CTX *mem_ctx, OM_uint32 maj, OM_uint32 min)
    524534{
     
    536546                                     GSS_C_NO_OID, &msg_ctx, &msg_maj);
    537547        if (gss_maj) {
     548                goto done;
     549        }
     550        errstr = talloc_strndup(mem_ctx,
     551                                (char *)msg_maj.value,
     552                                        msg_maj.length);
     553        if (!errstr) {
    538554                goto done;
    539555        }
     
    545561        }
    546562
    547         errstr = talloc_strndup(mem_ctx,
    548                                 (char *)msg_maj.value,
    549                                         msg_maj.length);
    550         if (!errstr) {
    551                 goto done;
    552         }
    553563        errstr = talloc_strdup_append_buffer(errstr, ": ");
    554564        if (!errstr) {
     
    572582}
    573583
    574 bool gse_require_more_processing(struct gse_context *gse_ctx)
    575 {
    576         return gse_ctx->more_processing;
    577 }
    578 
    579 DATA_BLOB gse_get_session_key(TALLOC_CTX *mem_ctx,
    580                                 struct gse_context *gse_ctx)
    581 {
    582         OM_uint32 gss_min, gss_maj;
    583         gss_buffer_set_t set = GSS_C_NO_BUFFER_SET;
    584         DATA_BLOB ret;
    585 
    586         gss_maj = gss_inquire_sec_context_by_oid(
    587                                 &gss_min, gse_ctx->gss_ctx,
    588                                 &gse_sesskey_inq_oid, &set);
    589         if (gss_maj) {
    590                 DEBUG(0, ("gss_inquire_sec_context_by_oid failed [%s]\n",
    591                           gse_errstr(talloc_tos(), gss_maj, gss_min)));
    592                 return data_blob_null;
    593         }
    594 
    595         if ((set == GSS_C_NO_BUFFER_SET) ||
    596             (set->count != 2) ||
    597             (memcmp(set->elements[1].value,
    598                     gse_sesskeytype_oid.elements,
    599                     gse_sesskeytype_oid.length) != 0)) {
    600                 DEBUG(0, ("gss_inquire_sec_context_by_oid returned unknown "
    601                           "OID for data in results:\n"));
    602                 dump_data(1, (uint8_t *)set->elements[1].value,
    603                              set->elements[1].length);
    604                 return data_blob_null;
    605         }
    606 
    607         ret = data_blob_talloc(mem_ctx, set->elements[0].value,
    608                                         set->elements[0].length);
    609 
    610         gss_maj = gss_release_buffer_set(&gss_min, &set);
    611         return ret;
    612 }
    613 
    614 NTSTATUS gse_get_client_name(struct gse_context *gse_ctx,
    615                              TALLOC_CTX *mem_ctx, char **cli_name)
    616 {
    617         OM_uint32 gss_min, gss_maj;
    618         gss_buffer_desc name_buffer;
    619 
    620         if (!gse_ctx->authenticated) {
     584static NTSTATUS gensec_gse_client_start(struct gensec_security *gensec_security)
     585{
     586        struct gse_context *gse_ctx;
     587        struct cli_credentials *creds = gensec_get_credentials(gensec_security);
     588        NTSTATUS nt_status;
     589        OM_uint32 want_flags = 0;
     590        bool do_sign = false, do_seal = false;
     591        const char *hostname = gensec_get_target_hostname(gensec_security);
     592        const char *service = gensec_get_target_service(gensec_security);
     593        const char *username = cli_credentials_get_username(creds);
     594        const char *password = cli_credentials_get_password(creds);
     595
     596        if (!hostname) {
     597                DEBUG(1, ("Could not determine hostname for target computer, cannot use kerberos\n"));
     598                return NT_STATUS_INVALID_PARAMETER;
     599        }
     600        if (is_ipaddress(hostname)) {
     601                DEBUG(2, ("Cannot do GSE to an IP address\n"));
     602                return NT_STATUS_INVALID_PARAMETER;
     603        }
     604        if (strcmp(hostname, "localhost") == 0) {
     605                DEBUG(2, ("GSE to 'localhost' does not make sense\n"));
     606                return NT_STATUS_INVALID_PARAMETER;
     607        }
     608
     609        if (gensec_security->want_features & GENSEC_FEATURE_SESSION_KEY) {
     610                do_sign = true;
     611        }
     612        if (gensec_security->want_features & GENSEC_FEATURE_SIGN) {
     613                do_sign = true;
     614        }
     615        if (gensec_security->want_features & GENSEC_FEATURE_SEAL) {
     616                do_seal = true;
     617        }
     618        if (gensec_security->want_features & GENSEC_FEATURE_DCE_STYLE) {
     619                want_flags |= GSS_C_DCE_STYLE;
     620        }
     621
     622        nt_status = gse_init_client(gensec_security, do_sign, do_seal, NULL,
     623                                    hostname, service,
     624                                    username, password, want_flags,
     625                                    &gse_ctx);
     626        if (!NT_STATUS_IS_OK(nt_status)) {
     627                return nt_status;
     628        }
     629        gensec_security->private_data = gse_ctx;
     630        return NT_STATUS_OK;
     631}
     632
     633static NTSTATUS gensec_gse_server_start(struct gensec_security *gensec_security)
     634{
     635        struct gse_context *gse_ctx;
     636        NTSTATUS nt_status;
     637        OM_uint32 want_flags = 0;
     638        bool do_sign = false, do_seal = false;
     639
     640        if (gensec_security->want_features & GENSEC_FEATURE_SIGN) {
     641                do_sign = true;
     642        }
     643        if (gensec_security->want_features & GENSEC_FEATURE_SEAL) {
     644                do_seal = true;
     645        }
     646        if (gensec_security->want_features & GENSEC_FEATURE_DCE_STYLE) {
     647                want_flags |= GSS_C_DCE_STYLE;
     648        }
     649
     650        nt_status = gse_init_server(gensec_security, do_sign, do_seal, want_flags,
     651                                    &gse_ctx);
     652        if (!NT_STATUS_IS_OK(nt_status)) {
     653                return nt_status;
     654        }
     655        gensec_security->private_data = gse_ctx;
     656        return NT_STATUS_OK;
     657}
     658
     659/**
     660 * Next state function for the GSE GENSEC mechanism
     661 *
     662 * @param gensec_gse_state GSE State
     663 * @param mem_ctx The TALLOC_CTX for *out to be allocated on
     664 * @param in The request, as a DATA_BLOB
     665 * @param out The reply, as an talloc()ed DATA_BLOB, on *mem_ctx
     666 * @return Error, MORE_PROCESSING_REQUIRED if a reply is sent,
     667 *                or NT_STATUS_OK if the user is authenticated.
     668 */
     669
     670static NTSTATUS gensec_gse_update(struct gensec_security *gensec_security,
     671                                  TALLOC_CTX *mem_ctx,
     672                                  struct tevent_context *ev,
     673                                  const DATA_BLOB in, DATA_BLOB *out)
     674{
     675        NTSTATUS status;
     676        struct gse_context *gse_ctx =
     677                talloc_get_type_abort(gensec_security->private_data,
     678                struct gse_context);
     679
     680        switch (gensec_security->gensec_role) {
     681        case GENSEC_CLIENT:
     682                status = gse_get_client_auth_token(mem_ctx, gse_ctx,
     683                                                   &in, out);
     684                break;
     685        case GENSEC_SERVER:
     686                status = gse_get_server_auth_token(mem_ctx, gse_ctx,
     687                                                   &in, out);
     688                break;
     689        }
     690        if (!NT_STATUS_IS_OK(status)) {
     691                return status;
     692        }
     693
     694        return NT_STATUS_OK;
     695}
     696
     697static NTSTATUS gensec_gse_wrap(struct gensec_security *gensec_security,
     698                                TALLOC_CTX *mem_ctx,
     699                                const DATA_BLOB *in,
     700                                DATA_BLOB *out)
     701{
     702        struct gse_context *gse_ctx =
     703                talloc_get_type_abort(gensec_security->private_data,
     704                struct gse_context);
     705        OM_uint32 maj_stat, min_stat;
     706        gss_buffer_desc input_token, output_token;
     707        int conf_state;
     708        input_token.length = in->length;
     709        input_token.value = in->data;
     710
     711        maj_stat = gss_wrap(&min_stat,
     712                            gse_ctx->gssapi_context,
     713                            gensec_have_feature(gensec_security, GENSEC_FEATURE_SEAL),
     714                            GSS_C_QOP_DEFAULT,
     715                            &input_token,
     716                            &conf_state,
     717                            &output_token);
     718        if (GSS_ERROR(maj_stat)) {
     719                DEBUG(0, ("gensec_gse_wrap: GSS Wrap failed: %s\n",
     720                          gse_errstr(talloc_tos(), maj_stat, min_stat)));
    621721                return NT_STATUS_ACCESS_DENIED;
    622722        }
    623723
    624         if (!gse_ctx->client_name) {
    625                 return NT_STATUS_NOT_FOUND;
    626         }
    627 
    628         /* TODO: check OID matches KRB5 Principal Name OID ? */
    629 
    630         gss_maj = gss_display_name(&gss_min,
    631                                    gse_ctx->client_name,
    632                                    &name_buffer, NULL);
    633         if (gss_maj) {
    634                 DEBUG(0, ("gss_display_name failed [%s]\n",
    635                           gse_errstr(talloc_tos(), gss_maj, gss_min)));
    636                 return NT_STATUS_INTERNAL_ERROR;
    637         }
    638 
    639         *cli_name = talloc_strndup(talloc_tos(),
    640                                         (char *)name_buffer.value,
    641                                         name_buffer.length);
    642 
    643         gss_maj = gss_release_buffer(&gss_min, &name_buffer);
    644 
    645         if (!*cli_name) {
     724        *out = data_blob_talloc(mem_ctx, output_token.value, output_token.length);
     725        gss_release_buffer(&min_stat, &output_token);
     726
     727        if (gensec_have_feature(gensec_security, GENSEC_FEATURE_SEAL)
     728            && !conf_state) {
     729                return NT_STATUS_ACCESS_DENIED;
     730        }
     731        return NT_STATUS_OK;
     732}
     733
     734static NTSTATUS gensec_gse_unwrap(struct gensec_security *gensec_security,
     735                                     TALLOC_CTX *mem_ctx,
     736                                     const DATA_BLOB *in,
     737                                     DATA_BLOB *out)
     738{
     739        struct gse_context *gse_ctx =
     740                talloc_get_type_abort(gensec_security->private_data,
     741                struct gse_context);
     742        OM_uint32 maj_stat, min_stat;
     743        gss_buffer_desc input_token, output_token;
     744        int conf_state;
     745        gss_qop_t qop_state;
     746        input_token.length = in->length;
     747        input_token.value = in->data;
     748
     749        maj_stat = gss_unwrap(&min_stat,
     750                              gse_ctx->gssapi_context,
     751                              &input_token,
     752                              &output_token,
     753                              &conf_state,
     754                              &qop_state);
     755        if (GSS_ERROR(maj_stat)) {
     756                DEBUG(0, ("gensec_gse_unwrap: GSS UnWrap failed: %s\n",
     757                          gse_errstr(talloc_tos(), maj_stat, min_stat)));
     758                return NT_STATUS_ACCESS_DENIED;
     759        }
     760
     761        *out = data_blob_talloc(mem_ctx, output_token.value, output_token.length);
     762        gss_release_buffer(&min_stat, &output_token);
     763
     764        if (gensec_have_feature(gensec_security, GENSEC_FEATURE_SEAL)
     765            && !conf_state) {
     766                return NT_STATUS_ACCESS_DENIED;
     767        }
     768        return NT_STATUS_OK;
     769}
     770
     771static NTSTATUS gensec_gse_seal_packet(struct gensec_security *gensec_security,
     772                                       TALLOC_CTX *mem_ctx,
     773                                       uint8_t *data, size_t length,
     774                                       const uint8_t *whole_pdu, size_t pdu_length,
     775                                       DATA_BLOB *sig)
     776{
     777        struct gse_context *gse_ctx =
     778                talloc_get_type_abort(gensec_security->private_data,
     779                struct gse_context);
     780        bool hdr_signing = false;
     781        size_t sig_size = 0;
     782        NTSTATUS status;
     783
     784        if (gensec_security->want_features & GENSEC_FEATURE_SIGN_PKT_HEADER) {
     785                hdr_signing = true;
     786        }
     787
     788        sig_size = gensec_gse_sig_size(gensec_security, length);
     789
     790        status = gssapi_seal_packet(gse_ctx->gssapi_context,
     791                                    &gse_ctx->gss_mech,
     792                                    hdr_signing, sig_size,
     793                                    data, length,
     794                                    whole_pdu, pdu_length,
     795                                    mem_ctx, sig);
     796        if (!NT_STATUS_IS_OK(status)) {
     797                DEBUG(0, ("gssapi_seal_packet(hdr_signing=%u,sig_size=%zu,"
     798                          "data=%zu,pdu=%zu) failed: %s\n",
     799                          hdr_signing, sig_size, length, pdu_length,
     800                          nt_errstr(status)));
     801                return status;
     802        }
     803
     804        return NT_STATUS_OK;
     805}
     806
     807static NTSTATUS gensec_gse_unseal_packet(struct gensec_security *gensec_security,
     808                                         uint8_t *data, size_t length,
     809                                         const uint8_t *whole_pdu, size_t pdu_length,
     810                                         const DATA_BLOB *sig)
     811{
     812        struct gse_context *gse_ctx =
     813                talloc_get_type_abort(gensec_security->private_data,
     814                struct gse_context);
     815        bool hdr_signing = false;
     816        NTSTATUS status;
     817
     818        if (gensec_security->want_features & GENSEC_FEATURE_SIGN_PKT_HEADER) {
     819                hdr_signing = true;
     820        }
     821
     822        status = gssapi_unseal_packet(gse_ctx->gssapi_context,
     823                                      &gse_ctx->gss_mech,
     824                                      hdr_signing,
     825                                      data, length,
     826                                      whole_pdu, pdu_length,
     827                                      sig);
     828        if (!NT_STATUS_IS_OK(status)) {
     829                DEBUG(0, ("gssapi_unseal_packet(hdr_signing=%u,sig_size=%zu,"
     830                          "data=%zu,pdu=%zu) failed: %s\n",
     831                          hdr_signing, sig->length, length, pdu_length,
     832                          nt_errstr(status)));
     833                return status;
     834        }
     835
     836        return NT_STATUS_OK;
     837}
     838
     839static NTSTATUS gensec_gse_sign_packet(struct gensec_security *gensec_security,
     840                                       TALLOC_CTX *mem_ctx,
     841                                       const uint8_t *data, size_t length,
     842                                       const uint8_t *whole_pdu, size_t pdu_length,
     843                                       DATA_BLOB *sig)
     844{
     845        struct gse_context *gse_ctx =
     846                talloc_get_type_abort(gensec_security->private_data,
     847                struct gse_context);
     848        bool hdr_signing = false;
     849        NTSTATUS status;
     850
     851        if (gensec_security->want_features & GENSEC_FEATURE_SIGN_PKT_HEADER) {
     852                hdr_signing = true;
     853        }
     854
     855        status = gssapi_sign_packet(gse_ctx->gssapi_context,
     856                                    &gse_ctx->gss_mech,
     857                                    hdr_signing,
     858                                    data, length,
     859                                    whole_pdu, pdu_length,
     860                                    mem_ctx, sig);
     861        if (!NT_STATUS_IS_OK(status)) {
     862                DEBUG(0, ("gssapi_sign_packet(hdr_signing=%u,"
     863                          "data=%zu,pdu=%zu) failed: %s\n",
     864                          hdr_signing, length, pdu_length,
     865                          nt_errstr(status)));
     866                return status;
     867        }
     868
     869        return NT_STATUS_OK;
     870}
     871
     872static NTSTATUS gensec_gse_check_packet(struct gensec_security *gensec_security,
     873                                        const uint8_t *data, size_t length,
     874                                        const uint8_t *whole_pdu, size_t pdu_length,
     875                                        const DATA_BLOB *sig)
     876{
     877        struct gse_context *gse_ctx =
     878                talloc_get_type_abort(gensec_security->private_data,
     879                struct gse_context);
     880        bool hdr_signing = false;
     881        NTSTATUS status;
     882
     883        if (gensec_security->want_features & GENSEC_FEATURE_SIGN_PKT_HEADER) {
     884                hdr_signing = true;
     885        }
     886
     887        status = gssapi_check_packet(gse_ctx->gssapi_context,
     888                                     &gse_ctx->gss_mech,
     889                                     hdr_signing,
     890                                     data, length,
     891                                     whole_pdu, pdu_length,
     892                                     sig);
     893        if (!NT_STATUS_IS_OK(status)) {
     894                DEBUG(0, ("gssapi_check_packet(hdr_signing=%u,sig_size=%zu"
     895                          "data=%zu,pdu=%zu) failed: %s\n",
     896                          hdr_signing, sig->length, length, pdu_length,
     897                          nt_errstr(status)));
     898                return status;
     899        }
     900
     901        return NT_STATUS_OK;
     902}
     903
     904/* Try to figure out what features we actually got on the connection */
     905static bool gensec_gse_have_feature(struct gensec_security *gensec_security,
     906                                    uint32_t feature)
     907{
     908        struct gse_context *gse_ctx =
     909                talloc_get_type_abort(gensec_security->private_data,
     910                struct gse_context);
     911
     912        if (feature & GENSEC_FEATURE_SESSION_KEY) {
     913                return gse_ctx->gss_got_flags & GSS_C_INTEG_FLAG;
     914        }
     915        if (feature & GENSEC_FEATURE_SIGN) {
     916                return gse_ctx->gss_got_flags & GSS_C_INTEG_FLAG;
     917        }
     918        if (feature & GENSEC_FEATURE_SEAL) {
     919                return gse_ctx->gss_got_flags & GSS_C_CONF_FLAG;
     920        }
     921        if (feature & GENSEC_FEATURE_DCE_STYLE) {
     922                return gse_ctx->gss_got_flags & GSS_C_DCE_STYLE;
     923        }
     924        if (feature & GENSEC_FEATURE_NEW_SPNEGO) {
     925                NTSTATUS status;
     926                uint32_t keytype;
     927
     928                if (!(gse_ctx->gss_got_flags & GSS_C_INTEG_FLAG)) {
     929                        return false;
     930                }
     931
     932                status = gssapi_get_session_key(talloc_tos(),
     933                                                gse_ctx->gssapi_context, NULL, &keytype);
     934                /*
     935                 * We should do a proper sig on the mechListMic unless
     936                 * we know we have to be backwards compatible with
     937                 * earlier windows versions. 
     938                 *
     939                 * Negotiating a non-krb5
     940                 * mech for example should be regarded as having
     941                 * NEW_SPNEGO
     942                 */
     943                if (NT_STATUS_IS_OK(status)) {
     944                        switch (keytype) {
     945                        case ENCTYPE_DES_CBC_CRC:
     946                        case ENCTYPE_DES_CBC_MD5:
     947                        case ENCTYPE_ARCFOUR_HMAC:
     948                        case ENCTYPE_DES3_CBC_SHA1:
     949                                return false;
     950                        }
     951                }
     952                return true;
     953        }
     954        /* We can always do async (rather than strict request/reply) packets.  */
     955        if (feature & GENSEC_FEATURE_ASYNC_REPLIES) {
     956                return true;
     957        }
     958        if (feature & GENSEC_FEATURE_SIGN_PKT_HEADER) {
     959                if (gensec_security->want_features & GENSEC_FEATURE_SEAL) {
     960                        return true;
     961                }
     962
     963                if (gensec_security->want_features & GENSEC_FEATURE_SIGN) {
     964                        return true;
     965                }
     966
     967                return false;
     968        }
     969        return false;
     970}
     971
     972static NTTIME gensec_gse_expire_time(struct gensec_security *gensec_security)
     973{
     974        struct gse_context *gse_ctx =
     975                talloc_get_type_abort(gensec_security->private_data,
     976                struct gse_context);
     977
     978        return gse_ctx->expire_time;
     979}
     980
     981/*
     982 * Extract the 'sesssion key' needed by SMB signing and ncacn_np
     983 * (for encrypting some passwords).
     984 *
     985 * This breaks all the abstractions, but what do you expect...
     986 */
     987static NTSTATUS gensec_gse_session_key(struct gensec_security *gensec_security,
     988                                       TALLOC_CTX *mem_ctx,
     989                                       DATA_BLOB *session_key)
     990{
     991        struct gse_context *gse_ctx =
     992                talloc_get_type_abort(gensec_security->private_data,
     993                struct gse_context);
     994
     995        return gssapi_get_session_key(mem_ctx, gse_ctx->gssapi_context, session_key, NULL);
     996}
     997
     998/* Get some basic (and authorization) information about the user on
     999 * this session.  This uses either the PAC (if present) or a local
     1000 * database lookup */
     1001static NTSTATUS gensec_gse_session_info(struct gensec_security *gensec_security,
     1002                                        TALLOC_CTX *mem_ctx,
     1003                                        struct auth_session_info **_session_info)
     1004{
     1005        struct gse_context *gse_ctx =
     1006                talloc_get_type_abort(gensec_security->private_data,
     1007                struct gse_context);
     1008        NTSTATUS nt_status;
     1009        TALLOC_CTX *tmp_ctx;
     1010        struct auth_session_info *session_info = NULL;
     1011        OM_uint32 maj_stat, min_stat;
     1012        DATA_BLOB pac_blob, *pac_blob_ptr = NULL;
     1013
     1014        gss_buffer_desc name_token;
     1015        char *principal_string;
     1016
     1017        tmp_ctx = talloc_named(mem_ctx, 0, "gensec_gse_session_info context");
     1018        NT_STATUS_HAVE_NO_MEMORY(tmp_ctx);
     1019
     1020        maj_stat = gss_display_name(&min_stat,
     1021                                    gse_ctx->client_name,
     1022                                    &name_token,
     1023                                    NULL);
     1024        if (GSS_ERROR(maj_stat)) {
     1025                DEBUG(1, ("GSS display_name failed: %s\n",
     1026                          gse_errstr(talloc_tos(), maj_stat, min_stat)));
     1027                talloc_free(tmp_ctx);
     1028                return NT_STATUS_FOOBAR;
     1029        }
     1030
     1031        principal_string = talloc_strndup(tmp_ctx,
     1032                                          (const char *)name_token.value,
     1033                                          name_token.length);
     1034
     1035        gss_release_buffer(&min_stat, &name_token);
     1036
     1037        if (!principal_string) {
     1038                talloc_free(tmp_ctx);
    6461039                return NT_STATUS_NO_MEMORY;
    6471040        }
    6481041
     1042        nt_status = gssapi_obtain_pac_blob(tmp_ctx,  gse_ctx->gssapi_context,
     1043                                           gse_ctx->client_name,
     1044                                           &pac_blob);
     1045
     1046        /* IF we have the PAC - otherwise we need to get this
     1047         * data from elsewere
     1048         */
     1049        if (NT_STATUS_IS_OK(nt_status)) {
     1050                pac_blob_ptr = &pac_blob;
     1051        }
     1052        nt_status = gensec_generate_session_info_pac(tmp_ctx,
     1053                                                     gensec_security,
     1054                                                     NULL,
     1055                                                     pac_blob_ptr, principal_string,
     1056                                                     gensec_get_remote_address(gensec_security),
     1057                                                     &session_info);
     1058        if (!NT_STATUS_IS_OK(nt_status)) {
     1059                talloc_free(tmp_ctx);
     1060                return nt_status;
     1061        }
     1062
     1063        nt_status = gensec_gse_session_key(gensec_security, session_info,
     1064                                           &session_info->session_key);
     1065        if (!NT_STATUS_IS_OK(nt_status)) {
     1066                talloc_free(tmp_ctx);
     1067                return nt_status;
     1068        }
     1069
     1070        *_session_info = talloc_move(mem_ctx, &session_info);
     1071        talloc_free(tmp_ctx);
     1072
    6491073        return NT_STATUS_OK;
    6501074}
    6511075
    652 NTSTATUS gse_get_authz_data(struct gse_context *gse_ctx,
    653                             TALLOC_CTX *mem_ctx, DATA_BLOB *pac)
    654 {
    655         OM_uint32 gss_min, gss_maj;
    656         gss_buffer_set_t set = GSS_C_NO_BUFFER_SET;
    657 
    658         if (!gse_ctx->authenticated) {
    659                 return NT_STATUS_ACCESS_DENIED;
    660         }
    661 
    662         gss_maj = gss_inquire_sec_context_by_oid(
    663                                 &gss_min, gse_ctx->gss_ctx,
    664                                 &gse_authz_data_oid, &set);
    665         if (gss_maj) {
    666                 DEBUG(0, ("gss_inquire_sec_context_by_oid failed [%s]\n",
    667                           gse_errstr(talloc_tos(), gss_maj, gss_min)));
    668                 return NT_STATUS_NOT_FOUND;
    669         }
    670 
    671         if (set == GSS_C_NO_BUFFER_SET) {
    672                 DEBUG(0, ("gss_inquire_sec_context_by_oid returned unknown "
    673                           "data in results.\n"));
    674                 return NT_STATUS_INTERNAL_ERROR;
    675         }
    676 
    677         /* for now we just hope it is the first value */
    678         *pac = data_blob_talloc(mem_ctx,
    679                                 set->elements[0].value,
    680                                 set->elements[0].length);
    681 
    682         gss_maj = gss_release_buffer_set(&gss_min, &set);
    683 
    684         return NT_STATUS_OK;
    685 }
    686 
    687 NTSTATUS gse_get_pac_blob(struct gse_context *gse_ctx,
    688                           TALLOC_CTX *mem_ctx, DATA_BLOB *pac_blob)
    689 {
    690         OM_uint32 gss_min, gss_maj;
    691 /*
    692  * gss_get_name_attribute() in MIT krb5 1.10.0 can return unintialized pac_display_buffer
    693  * and later gss_release_buffer() will crash on attempting to release it.
    694  *
    695  * So always initialize the buffer descriptors.
    696  *
    697  * See following links for more details:
    698  * http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=658514
    699  * http://krbdev.mit.edu/rt/Ticket/Display.html?user=guest&pass=guest&id=7087
    700  */
    701         gss_buffer_desc pac_buffer = {
    702                 .value = NULL,
    703                 .length = 0
    704         };
    705         gss_buffer_desc pac_display_buffer = {
    706                 .value = NULL,
    707                 .length = 0
    708         };
    709         gss_buffer_desc pac_name = {
    710                 .value = discard_const_p(char, "urn:mspac:"),
    711                 .length = sizeof("urn:mspac:") - 1
    712         };
    713         int more = -1;
    714         int authenticated = false;
    715         int complete = false;
    716         NTSTATUS status;
    717 
    718         if (!gse_ctx->authenticated) {
    719                 return NT_STATUS_ACCESS_DENIED;
    720         }
    721 
    722         gss_maj = gss_get_name_attribute(&gss_min,
    723                                          gse_ctx->client_name, &pac_name,
    724                                          &authenticated, &complete,
    725                                          &pac_buffer, &pac_display_buffer,
    726                                          &more);
    727 
    728         if (gss_maj != 0) {
    729                 DEBUG(0, ("obtaining PAC via GSSAPI gss_get_name_attribute "
    730                           "failed: %s\n",
    731                           gse_errstr(mem_ctx, gss_maj, gss_min)));
    732                 return NT_STATUS_ACCESS_DENIED;
    733         }
    734 
    735         if (authenticated && complete) {
    736                 /* The PAC blob is returned directly */
    737                 *pac_blob = data_blob_talloc(mem_ctx,
    738                                              pac_buffer.value,
    739                                              pac_buffer.length);
    740                 if (!pac_blob->data) {
    741                         status = NT_STATUS_NO_MEMORY;
    742                 } else {
    743                         status = NT_STATUS_OK;
    744                 }
    745 
    746                 gss_maj = gss_release_buffer(&gss_min, &pac_buffer);
    747                 gss_maj = gss_release_buffer(&gss_min, &pac_display_buffer);
    748 
    749                 return status;
    750         }
    751 
    752         DEBUG(0, ("obtaining PAC via GSSAPI failed: authenticated: %s, "
    753                   "complete: %s, more: %s\n",
    754                   authenticated ? "true" : "false",
    755                   complete ? "true" : "false",
    756                   more ? "true" : "false"));
    757 
    758         return NT_STATUS_ACCESS_DENIED;
    759 }
    760 
    761 size_t gse_get_signature_length(struct gse_context *gse_ctx,
    762                                 int seal, size_t payload_size)
    763 {
    764         OM_uint32 gss_min, gss_maj;
    765         gss_iov_buffer_desc iov[2];
    766         uint8_t fakebuf[payload_size];
    767         int sealed;
    768 
    769         iov[0].type = GSS_IOV_BUFFER_TYPE_HEADER;
    770         iov[0].buffer.value = NULL;
    771         iov[0].buffer.length = 0;
    772         iov[1].type = GSS_IOV_BUFFER_TYPE_DATA;
    773         iov[1].buffer.value = fakebuf;
    774         iov[1].buffer.length = payload_size;
    775 
    776         gss_maj = gss_wrap_iov_length(&gss_min, gse_ctx->gss_ctx,
    777                                         seal, GSS_C_QOP_DEFAULT,
    778                                         &sealed, iov, 2);
    779         if (gss_maj) {
    780                 DEBUG(0, ("gss_wrap_iov_length failed with [%s]\n",
    781                           gse_errstr(talloc_tos(), gss_maj, gss_min)));
     1076static size_t gensec_gse_max_input_size(struct gensec_security *gensec_security)
     1077{
     1078        struct gse_context *gse_ctx =
     1079                talloc_get_type_abort(gensec_security->private_data,
     1080                struct gse_context);
     1081        OM_uint32 maj_stat, min_stat;
     1082        OM_uint32 max_input_size;
     1083
     1084        maj_stat = gss_wrap_size_limit(&min_stat,
     1085                                       gse_ctx->gssapi_context,
     1086                                       gensec_have_feature(gensec_security, GENSEC_FEATURE_SEAL),
     1087                                       GSS_C_QOP_DEFAULT,
     1088                                       gse_ctx->max_wrap_buf_size,
     1089                                       &max_input_size);
     1090        if (GSS_ERROR(maj_stat)) {
     1091                TALLOC_CTX *mem_ctx = talloc_new(NULL);
     1092                DEBUG(1, ("gensec_gssapi_max_input_size: determining signature size with gss_wrap_size_limit failed: %s\n",
     1093                          gse_errstr(mem_ctx, maj_stat, min_stat)));
     1094                talloc_free(mem_ctx);
    7821095                return 0;
    7831096        }
    7841097
    785         return iov[0].buffer.length;
    786 }
    787 
    788 NTSTATUS gse_seal(TALLOC_CTX *mem_ctx, struct gse_context *gse_ctx,
    789                   DATA_BLOB *data, DATA_BLOB *signature)
    790 {
    791         OM_uint32 gss_min, gss_maj;
    792         gss_iov_buffer_desc iov[2];
    793         int req_seal = 1; /* setting to 1 means we request sign+seal */
    794         int sealed;
    795         NTSTATUS status;
    796 
    797         /* allocate the memory ourselves so we do not need to talloc_memdup */
    798         signature->length = gse_get_signature_length(gse_ctx, 1, data->length);
    799         if (!signature->length) {
    800                 return NT_STATUS_INTERNAL_ERROR;
    801         }
    802         signature->data = (uint8_t *)talloc_size(mem_ctx, signature->length);
    803         if (!signature->data) {
    804                 return NT_STATUS_NO_MEMORY;
    805         }
    806         iov[0].type = GSS_IOV_BUFFER_TYPE_HEADER;
    807         iov[0].buffer.value = signature->data;
    808         iov[0].buffer.length = signature->length;
    809 
    810         /* data is encrypted in place, which is ok */
    811         iov[1].type = GSS_IOV_BUFFER_TYPE_DATA;
    812         iov[1].buffer.value = data->data;
    813         iov[1].buffer.length = data->length;
    814 
    815         gss_maj = gss_wrap_iov(&gss_min, gse_ctx->gss_ctx,
    816                                 req_seal, GSS_C_QOP_DEFAULT,
    817                                 &sealed, iov, 2);
    818         if (gss_maj) {
    819                 DEBUG(0, ("gss_wrap_iov failed with [%s]\n",
    820                           gse_errstr(talloc_tos(), gss_maj, gss_min)));
    821                 status = NT_STATUS_ACCESS_DENIED;
    822                 goto done;
    823         }
    824 
    825         if (!sealed) {
    826                 DEBUG(0, ("gss_wrap_iov says data was not sealed!\n"));
    827                 status = NT_STATUS_ACCESS_DENIED;
    828                 goto done;
    829         }
    830 
    831         status = NT_STATUS_OK;
    832 
    833         DEBUG(10, ("Sealed %d bytes, and got %d bytes header/signature.\n",
    834                    (int)iov[1].buffer.length, (int)iov[0].buffer.length));
    835 
    836 done:
    837         return status;
    838 }
    839 
    840 NTSTATUS gse_unseal(TALLOC_CTX *mem_ctx, struct gse_context *gse_ctx,
    841                     DATA_BLOB *data, DATA_BLOB *signature)
    842 {
    843         OM_uint32 gss_min, gss_maj;
    844         gss_iov_buffer_desc iov[2];
    845         int sealed;
    846         NTSTATUS status;
    847 
    848         iov[0].type = GSS_IOV_BUFFER_TYPE_HEADER;
    849         iov[0].buffer.value = signature->data;
    850         iov[0].buffer.length = signature->length;
    851 
    852         /* data is decrypted in place, which is ok */
    853         iov[1].type = GSS_IOV_BUFFER_TYPE_DATA;
    854         iov[1].buffer.value = data->data;
    855         iov[1].buffer.length = data->length;
    856 
    857         gss_maj = gss_unwrap_iov(&gss_min, gse_ctx->gss_ctx,
    858                                  &sealed, NULL, iov, 2);
    859         if (gss_maj) {
    860                 DEBUG(0, ("gss_unwrap_iov failed with [%s]\n",
    861                           gse_errstr(talloc_tos(), gss_maj, gss_min)));
    862                 status = NT_STATUS_ACCESS_DENIED;
    863                 goto done;
    864         }
    865 
    866         if (!sealed) {
    867                 DEBUG(0, ("gss_unwrap_iov says data is not sealed!\n"));
    868                 status = NT_STATUS_ACCESS_DENIED;
    869                 goto done;
    870         }
    871 
    872         status = NT_STATUS_OK;
    873 
    874         DEBUG(10, ("Unsealed %d bytes, with %d bytes header/signature.\n",
    875                    (int)iov[1].buffer.length, (int)iov[0].buffer.length));
    876 
    877 done:
    878         return status;
    879 }
    880 
    881 NTSTATUS gse_sign(TALLOC_CTX *mem_ctx, struct gse_context *gse_ctx,
    882                   DATA_BLOB *data, DATA_BLOB *signature)
    883 {
    884         OM_uint32 gss_min, gss_maj;
    885         gss_buffer_desc in_data = { 0, NULL };
    886         gss_buffer_desc out_data = { 0, NULL};
    887         NTSTATUS status;
    888 
    889         in_data.value = data->data;
    890         in_data.length = data->length;
    891 
    892         gss_maj = gss_get_mic(&gss_min, gse_ctx->gss_ctx,
    893                               GSS_C_QOP_DEFAULT,
    894                               &in_data, &out_data);
    895         if (gss_maj) {
    896                 DEBUG(0, ("gss_get_mic failed with [%s]\n",
    897                           gse_errstr(talloc_tos(), gss_maj, gss_min)));
    898                 status = NT_STATUS_ACCESS_DENIED;
    899                 goto done;
    900         }
    901 
    902         *signature = data_blob_talloc(mem_ctx,
    903                                         out_data.value, out_data.length);
    904         if (!signature->data) {
    905                 status = NT_STATUS_NO_MEMORY;
    906                 goto done;
    907         }
    908 
    909         status = NT_STATUS_OK;
    910 
    911 done:
    912         if (out_data.value) {
    913                 gss_maj = gss_release_buffer(&gss_min, &out_data);
    914         }
    915         return status;
    916 }
    917 
    918 NTSTATUS gse_sigcheck(TALLOC_CTX *mem_ctx, struct gse_context *gse_ctx,
    919                       DATA_BLOB *data, DATA_BLOB *signature)
    920 {
    921         OM_uint32 gss_min, gss_maj;
    922         gss_buffer_desc in_data = { 0, NULL };
    923         gss_buffer_desc in_token = { 0, NULL};
    924         NTSTATUS status;
    925 
    926         in_data.value = data->data;
    927         in_data.length = data->length;
    928         in_token.value = signature->data;
    929         in_token.length = signature->length;
    930 
    931         gss_maj = gss_verify_mic(&gss_min, gse_ctx->gss_ctx,
    932                                  &in_data, &in_token, NULL);
    933         if (gss_maj) {
    934                 DEBUG(0, ("gss_verify_mic failed with [%s]\n",
    935                           gse_errstr(talloc_tos(), gss_maj, gss_min)));
    936                 status = NT_STATUS_ACCESS_DENIED;
    937                 goto done;
    938         }
    939 
    940         status = NT_STATUS_OK;
    941 
    942 done:
    943         return status;
    944 }
    945 
    946 #else
    947 
    948 NTSTATUS gse_init_client(TALLOC_CTX *mem_ctx,
    949                           bool do_sign, bool do_seal,
    950                           const char *ccache_name,
    951                           const char *server,
    952                           const char *service,
    953                           const char *username,
    954                           const char *password,
    955                           uint32_t add_gss_c_flags,
    956                           struct gse_context **_gse_ctx)
    957 {
    958         return NT_STATUS_NOT_IMPLEMENTED;
    959 }
    960 
    961 NTSTATUS gse_get_client_auth_token(TALLOC_CTX *mem_ctx,
    962                                    struct gse_context *gse_ctx,
    963                                    DATA_BLOB *token_in,
    964                                    DATA_BLOB *token_out)
    965 {
    966         return NT_STATUS_NOT_IMPLEMENTED;
    967 }
    968 
    969 NTSTATUS gse_init_server(TALLOC_CTX *mem_ctx,
    970                          bool do_sign, bool do_seal,
    971                          uint32_t add_gss_c_flags,
    972                          const char *keytab,
    973                          struct gse_context **_gse_ctx)
    974 {
    975         return NT_STATUS_NOT_IMPLEMENTED;
    976 }
    977 
    978 NTSTATUS gse_get_server_auth_token(TALLOC_CTX *mem_ctx,
    979                                    struct gse_context *gse_ctx,
    980                                    DATA_BLOB *token_in,
    981                                    DATA_BLOB *token_out)
    982 {
    983         return NT_STATUS_NOT_IMPLEMENTED;
    984 }
    985 
    986 NTSTATUS gse_verify_server_auth_flags(struct gse_context *gse_ctx)
    987 {
    988         return NT_STATUS_NOT_IMPLEMENTED;
    989 }
    990 
    991 bool gse_require_more_processing(struct gse_context *gse_ctx)
    992 {
    993         return false;
    994 }
    995 
    996 DATA_BLOB gse_get_session_key(TALLOC_CTX *mem_ctx,
    997                               struct gse_context *gse_ctx)
    998 {
    999         return data_blob_null;
    1000 }
    1001 
    1002 NTSTATUS gse_get_client_name(struct gse_context *gse_ctx,
    1003                              TALLOC_CTX *mem_ctx, char **cli_name)
    1004 {
    1005         return NT_STATUS_NOT_IMPLEMENTED;
    1006 }
    1007 
    1008 NTSTATUS gse_get_authz_data(struct gse_context *gse_ctx,
    1009                             TALLOC_CTX *mem_ctx, DATA_BLOB *pac)
    1010 {
    1011         return NT_STATUS_NOT_IMPLEMENTED;
    1012 }
    1013 
    1014 NTSTATUS gse_get_pac_blob(struct gse_context *gse_ctx,
    1015                           TALLOC_CTX *mem_ctx, DATA_BLOB *pac)
    1016 {
    1017         return NT_STATUS_NOT_IMPLEMENTED;
    1018 }
    1019 
    1020 size_t gse_get_signature_length(struct gse_context *gse_ctx,
    1021                                 int seal, size_t payload_size)
    1022 {
    1023         return 0;
    1024 }
    1025 
    1026 NTSTATUS gse_seal(TALLOC_CTX *mem_ctx, struct gse_context *gse_ctx,
    1027                   DATA_BLOB *data, DATA_BLOB *signature)
    1028 {
    1029         return NT_STATUS_NOT_IMPLEMENTED;
    1030 }
    1031 
    1032 NTSTATUS gse_unseal(TALLOC_CTX *mem_ctx, struct gse_context *gse_ctx,
    1033                     DATA_BLOB *data, DATA_BLOB *signature)
    1034 {
    1035         return NT_STATUS_NOT_IMPLEMENTED;
    1036 }
    1037 
    1038 NTSTATUS gse_sign(TALLOC_CTX *mem_ctx, struct gse_context *gse_ctx,
    1039                   DATA_BLOB *data, DATA_BLOB *signature)
    1040 {
    1041         return NT_STATUS_NOT_IMPLEMENTED;
    1042 }
    1043 
    1044 NTSTATUS gse_sigcheck(TALLOC_CTX *mem_ctx, struct gse_context *gse_ctx,
    1045                       DATA_BLOB *data, DATA_BLOB *signature)
    1046 {
    1047         return NT_STATUS_NOT_IMPLEMENTED;
    1048 }
    1049 
    1050 #endif /* HAVE_KRB5 && HAVE_GSSAPI_EXT_H && HAVE_GSS_WRAP_IOV */
     1098        return max_input_size;
     1099}
     1100
     1101/* Find out the maximum output size negotiated on this connection */
     1102static size_t gensec_gse_max_wrapped_size(struct gensec_security *gensec_security)
     1103{
     1104        struct gse_context *gse_ctx =
     1105                talloc_get_type_abort(gensec_security->private_data,
     1106                struct gse_context);
     1107        return gse_ctx->max_wrap_buf_size;
     1108}
     1109
     1110static size_t gensec_gse_sig_size(struct gensec_security *gensec_security,
     1111                                  size_t data_size)
     1112{
     1113        struct gse_context *gse_ctx =
     1114                talloc_get_type_abort(gensec_security->private_data,
     1115                struct gse_context);
     1116
     1117        if (gse_ctx->sig_size > 0) {
     1118                return gse_ctx->sig_size;
     1119        }
     1120
     1121        gse_ctx->sig_size = gssapi_get_sig_size(gse_ctx->gssapi_context,
     1122                                                &gse_ctx->gss_mech,
     1123                                                gse_ctx->gss_want_flags,
     1124                                                data_size);
     1125        return gse_ctx->sig_size;
     1126}
     1127
     1128static const char *gensec_gse_krb5_oids[] = {
     1129        GENSEC_OID_KERBEROS5_OLD,
     1130        GENSEC_OID_KERBEROS5,
     1131        NULL
     1132};
     1133
     1134const struct gensec_security_ops gensec_gse_krb5_security_ops = {
     1135        .name           = "gse_krb5",
     1136        .auth_type      = DCERPC_AUTH_TYPE_KRB5,
     1137        .oid            = gensec_gse_krb5_oids,
     1138        .client_start   = gensec_gse_client_start,
     1139        .server_start   = gensec_gse_server_start,
     1140        .magic          = gensec_magic_check_krb5_oid,
     1141        .update         = gensec_gse_update,
     1142        .session_key    = gensec_gse_session_key,
     1143        .session_info   = gensec_gse_session_info,
     1144        .sig_size       = gensec_gse_sig_size,
     1145        .sign_packet    = gensec_gse_sign_packet,
     1146        .check_packet   = gensec_gse_check_packet,
     1147        .seal_packet    = gensec_gse_seal_packet,
     1148        .unseal_packet  = gensec_gse_unseal_packet,
     1149        .max_input_size   = gensec_gse_max_input_size,
     1150        .max_wrapped_size = gensec_gse_max_wrapped_size,
     1151        .wrap           = gensec_gse_wrap,
     1152        .unwrap         = gensec_gse_unwrap,
     1153        .have_feature   = gensec_gse_have_feature,
     1154        .expire_time    = gensec_gse_expire_time,
     1155        .enabled        = true,
     1156        .kerberos       = true,
     1157        .priority       = GENSEC_GSSAPI
     1158};
     1159
     1160#endif /* HAVE_KRB5 */
  • vendor/current/source3/librpc/crypto/gse.h

    r740 r988  
    2222struct gse_context;
    2323
    24 #ifndef GSS_C_DCE_STYLE
    25 #define GSS_C_DCE_STYLE 0x1000
    26 #endif
    27 
    28 NTSTATUS gse_init_client(TALLOC_CTX *mem_ctx,
    29                           bool do_sign, bool do_seal,
    30                           const char *ccache_name,
    31                           const char *server,
    32                           const char *service,
    33                           const char *username,
    34                           const char *password,
    35                           uint32_t add_gss_c_flags,
    36                           struct gse_context **_gse_ctx);
    37 NTSTATUS gse_get_client_auth_token(TALLOC_CTX *mem_ctx,
    38                                    struct gse_context *gse_ctx,
    39                                    DATA_BLOB *token_in,
    40                                    DATA_BLOB *token_out);
    41 
    42 NTSTATUS gse_init_server(TALLOC_CTX *mem_ctx,
    43                          bool do_sign, bool do_seal,
    44                          uint32_t add_gss_c_flags,
    45                          const char *keytab,
    46                          struct gse_context **_gse_ctx);
    47 NTSTATUS gse_get_server_auth_token(TALLOC_CTX *mem_ctx,
    48                                    struct gse_context *gse_ctx,
    49                                    DATA_BLOB *token_in,
    50                                    DATA_BLOB *token_out);
    51 NTSTATUS gse_verify_server_auth_flags(struct gse_context *gse_ctx);
    52 
    53 bool gse_require_more_processing(struct gse_context *gse_ctx);
    54 DATA_BLOB gse_get_session_key(TALLOC_CTX *mem_ctx,
    55                                 struct gse_context *gse_ctx);
    56 NTSTATUS gse_get_client_name(struct gse_context *gse_ctx,
    57                              TALLOC_CTX *mem_ctx, char **client_name);
    58 NTSTATUS gse_get_authz_data(struct gse_context *gse_ctx,
    59                             TALLOC_CTX *mem_ctx, DATA_BLOB *pac);
    60 NTSTATUS gse_get_pac_blob(struct gse_context *gse_ctx,
    61                           TALLOC_CTX *mem_ctx, DATA_BLOB *pac);
    62 
    63 size_t gse_get_signature_length(struct gse_context *gse_ctx,
    64                                 int seal, size_t payload_size);
    65 NTSTATUS gse_seal(TALLOC_CTX *mem_ctx, struct gse_context *gse_ctx,
    66                   DATA_BLOB *data, DATA_BLOB *signature);
    67 NTSTATUS gse_unseal(TALLOC_CTX *mem_ctx, struct gse_context *gse_ctx,
    68                     DATA_BLOB *data, DATA_BLOB *signature);
    69 NTSTATUS gse_sign(TALLOC_CTX *mem_ctx, struct gse_context *gse_ctx,
    70                   DATA_BLOB *data, DATA_BLOB *signature);
    71 NTSTATUS gse_sigcheck(TALLOC_CTX *mem_ctx, struct gse_context *gse_ctx,
    72                       DATA_BLOB *data, DATA_BLOB *signature);
     24extern const struct gensec_security_ops gensec_gse_krb5_security_ops;
    7325
    7426#endif /* _GSE_H_ */
  • vendor/current/source3/librpc/crypto/gse_krb5.c

    r740 r988  
    2222#include "secrets.h"
    2323#include "gse_krb5.h"
     24#include "lib/param/loadparm.h"
    2425
    2526#ifdef HAVE_KRB5
     
    9192        int err;
    9293
    93         err = asprintf(&host_princ_s, "%s$@%s", global_myname(), lp_realm());
     94        err = asprintf(&host_princ_s, "%s$@%s", lp_netbios_name(), lp_realm());
    9495        if (err == -1) {
    9596                return -1;
    9697        }
    9798
    98         strlower_m(host_princ_s);
     99        if (!strlower_m(host_princ_s)) {
     100                SAFE_FREE(host_princ_s);
     101                return -1;
     102        }
    99103        ret = smb_krb5_parse_name(krbctx, host_princ_s, host_princ);
    100104        if (ret) {
     
    170174#define CLEARTEXT_PRIV_ENCTYPE -99
    171175
    172 static krb5_error_code get_mem_keytab_from_secrets(krb5_context krbctx,
    173                                                    krb5_keytab *keytab)
     176static krb5_error_code fill_mem_keytab_from_secrets(krb5_context krbctx,
     177                                                    krb5_keytab *keytab)
    174178{
    175179        krb5_error_code ret;
     
    194198        }
    195199        pwd_len = strlen(pwd);
    196 
    197         if (*keytab == NULL) {
    198                 /* create memory keytab */
    199                 ret = krb5_kt_resolve(krbctx, SRV_MEM_KEYTAB_NAME, keytab);
    200                 if (ret) {
    201                         DEBUG(1, (__location__ ": Failed to get memory "
    202                                   "keytab!\n"));
    203                         return ret;
    204                 }
    205         }
    206200
    207201        ZERO_STRUCT(kt_entry);
     
    281275        }
    282276
    283         pwd_old = secrets_fetch_machine_password(lp_workgroup(), NULL, NULL);
     277        pwd_old = secrets_fetch_prev_machine_password(lp_workgroup());
    284278        if (!pwd_old) {
    285279                DEBUG(10, (__location__ ": no prev machine password\n"));
     
    332326        }
    333327
    334         if (ret) {
    335                 if (*keytab) {
    336                         krb5_kt_close(krbctx, *keytab);
    337                         *keytab = NULL;
    338                 }
    339         }
    340 
    341328        return ret;
    342329}
    343330
    344 static krb5_error_code get_mem_keytab_from_system_keytab(krb5_context krbctx,
    345                                                          krb5_keytab *keytab,
    346                                                          bool verify)
     331static krb5_error_code fill_mem_keytab_from_system_keytab(krb5_context krbctx,
     332                                                          krb5_keytab *mkeytab)
    347333{
    348         return KRB5_KT_NOTFOUND;
     334        krb5_error_code ret = 0;
     335        krb5_keytab keytab = NULL;
     336        krb5_kt_cursor kt_cursor;
     337        krb5_keytab_entry kt_entry;
     338        char *valid_princ_formats[7] = { NULL, NULL, NULL,
     339                                         NULL, NULL, NULL, NULL };
     340        char *entry_princ_s = NULL;
     341        fstring my_name, my_fqdn;
     342        int i;
     343        int err;
     344
     345        /* Generate the list of principal names which we expect
     346         * clients might want to use for authenticating to the file
     347         * service.  We allow name$,{host,cifs}/{name,fqdn,name.REALM}. */
     348
     349        fstrcpy(my_name, lp_netbios_name());
     350
     351        my_fqdn[0] = '\0';
     352        name_to_fqdn(my_fqdn, lp_netbios_name());
     353
     354        err = asprintf(&valid_princ_formats[0],
     355                        "%s$@%s", my_name, lp_realm());
     356        if (err == -1) {
     357                ret = ENOMEM;
     358                goto out;
     359        }
     360        err = asprintf(&valid_princ_formats[1],
     361                        "host/%s@%s", my_name, lp_realm());
     362        if (err == -1) {
     363                ret = ENOMEM;
     364                goto out;
     365        }
     366        err = asprintf(&valid_princ_formats[2],
     367                        "host/%s@%s", my_fqdn, lp_realm());
     368        if (err == -1) {
     369                ret = ENOMEM;
     370                goto out;
     371        }
     372        err = asprintf(&valid_princ_formats[3],
     373                        "host/%s.%s@%s", my_name, lp_realm(), lp_realm());
     374        if (err == -1) {
     375                ret = ENOMEM;
     376                goto out;
     377        }
     378        err = asprintf(&valid_princ_formats[4],
     379                        "cifs/%s@%s", my_name, lp_realm());
     380        if (err == -1) {
     381                ret = ENOMEM;
     382                goto out;
     383        }
     384        err = asprintf(&valid_princ_formats[5],
     385                        "cifs/%s@%s", my_fqdn, lp_realm());
     386        if (err == -1) {
     387                ret = ENOMEM;
     388                goto out;
     389        }
     390        err = asprintf(&valid_princ_formats[6],
     391                        "cifs/%s.%s@%s", my_name, lp_realm(), lp_realm());
     392        if (err == -1) {
     393                ret = ENOMEM;
     394                goto out;
     395        }
     396
     397        ZERO_STRUCT(kt_entry);
     398        ZERO_STRUCT(kt_cursor);
     399
     400        ret = smb_krb5_open_keytab(krbctx, NULL, false, &keytab);
     401        if (ret) {
     402                DEBUG(1, (__location__ ": smb_krb5_open_keytab failed (%s)\n",
     403                          error_message(ret)));
     404                goto out;
     405        }
     406
     407        /*
     408         * Iterate through the keytab.  For each key, if the principal
     409         * name case-insensitively matches one of the allowed formats,
     410         * copy it to the memory keytab.
     411         */
     412
     413        ret = krb5_kt_start_seq_get(krbctx, keytab, &kt_cursor);
     414        if (ret) {
     415                DEBUG(1, (__location__ ": krb5_kt_start_seq_get failed (%s)\n",
     416                          error_message(ret)));
     417                goto out;
     418        }
     419
     420        while ((krb5_kt_next_entry(krbctx, keytab,
     421                                   &kt_entry, &kt_cursor) == 0)) {
     422                ret = smb_krb5_unparse_name(talloc_tos(), krbctx,
     423                                            kt_entry.principal,
     424                                            &entry_princ_s);
     425                if (ret) {
     426                        DEBUG(1, (__location__ ": smb_krb5_unparse_name "
     427                                  "failed (%s)\n", error_message(ret)));
     428                        goto out;
     429                }
     430
     431                for (i = 0; i < ARRAY_SIZE(valid_princ_formats); i++) {
     432
     433                        if (!strequal(entry_princ_s, valid_princ_formats[i])) {
     434                                continue;
     435                        }
     436
     437                        ret = krb5_kt_add_entry(krbctx, *mkeytab, &kt_entry);
     438                        if (ret) {
     439                                DEBUG(1, (__location__ ": smb_krb5_unparse_name "
     440                                          "failed (%s)\n", error_message(ret)));
     441                                goto out;
     442                        }
     443                }
     444
     445                /* Free the name we parsed. */
     446                TALLOC_FREE(entry_princ_s);
     447
     448                /* Free the entry we just read. */
     449                smb_krb5_kt_free_entry(krbctx, &kt_entry);
     450                ZERO_STRUCT(kt_entry);
     451        }
     452        krb5_kt_end_seq_get(krbctx, keytab, &kt_cursor);
     453
     454        ZERO_STRUCT(kt_cursor);
     455
     456out:
     457
     458        for (i = 0; i < ARRAY_SIZE(valid_princ_formats); i++) {
     459                SAFE_FREE(valid_princ_formats[i]);
     460        }
     461
     462        TALLOC_FREE(entry_princ_s);
     463
     464        {
     465                krb5_keytab_entry zero_kt_entry;
     466                ZERO_STRUCT(zero_kt_entry);
     467                if (memcmp(&zero_kt_entry, &kt_entry,
     468                           sizeof(krb5_keytab_entry))) {
     469                        smb_krb5_kt_free_entry(krbctx, &kt_entry);
     470                }
     471        }
     472
     473        {
     474                krb5_kt_cursor zero_csr;
     475                ZERO_STRUCT(zero_csr);
     476                if ((memcmp(&kt_cursor, &zero_csr,
     477                            sizeof(krb5_kt_cursor)) != 0) && keytab) {
     478                        krb5_kt_end_seq_get(krbctx, keytab, &kt_cursor);
     479                }
     480        }
     481
     482        if (keytab) {
     483                krb5_kt_close(krbctx, keytab);
     484        }
     485
     486        return ret;
     487}
     488
     489static krb5_error_code fill_mem_keytab_from_dedicated_keytab(krb5_context krbctx,
     490                                                             krb5_keytab *mkeytab)
     491{
     492        krb5_error_code ret = 0;
     493        krb5_keytab keytab = NULL;
     494        krb5_kt_cursor kt_cursor;
     495        krb5_keytab_entry kt_entry;
     496
     497        ret = smb_krb5_open_keytab(krbctx, lp_dedicated_keytab_file(),
     498                                   false, &keytab);
     499        if (ret) {
     500                DEBUG(1, (__location__ ": smb_krb5_open_keytab failed (%s)\n",
     501                          error_message(ret)));
     502                return ret;
     503        }
     504
     505        /*
     506         * Iterate through the keytab.  For each key, if the principal
     507         * name case-insensitively matches one of the allowed formats,
     508         * copy it to the memory keytab.
     509         */
     510
     511        ret = krb5_kt_start_seq_get(krbctx, keytab, &kt_cursor);
     512        if (ret) {
     513                DEBUG(1, (__location__ ": krb5_kt_start_seq_get failed (%s)\n",
     514                          error_message(ret)));
     515                goto out;
     516        }
     517
     518        while ((krb5_kt_next_entry(krbctx, keytab,
     519                                   &kt_entry, &kt_cursor) == 0)) {
     520
     521                ret = krb5_kt_add_entry(krbctx, *mkeytab, &kt_entry);
     522
     523                /* Free the entry we just read. */
     524                smb_krb5_kt_free_entry(krbctx, &kt_entry);
     525
     526                if (ret) {
     527                        DEBUG(1, (__location__ ": smb_krb5_unparse_name "
     528                                  "failed (%s)\n", error_message(ret)));
     529                        break;
     530                }
     531        }
     532        krb5_kt_end_seq_get(krbctx, keytab, &kt_cursor);
     533
     534out:
     535       
     536        krb5_kt_close(krbctx, keytab);
     537
     538        return ret;
    349539}
    350540
     
    352542                                           krb5_keytab *keytab)
    353543{
    354         krb5_error_code ret;
     544        krb5_error_code ret = 0;
     545        krb5_error_code ret1 = 0;
     546        krb5_error_code ret2 = 0;
    355547
    356548        *keytab = NULL;
     549
     550        /* create memory keytab */
     551        ret = krb5_kt_resolve(krbctx, SRV_MEM_KEYTAB_NAME, keytab);
     552        if (ret) {
     553                DEBUG(1, (__location__ ": Failed to get memory "
     554                          "keytab!\n"));
     555                return ret;
     556        }
    357557
    358558        switch (lp_kerberos_method()) {
    359559        default:
    360560        case KERBEROS_VERIFY_SECRETS:
    361                 ret = get_mem_keytab_from_secrets(krbctx, keytab);
     561                ret = fill_mem_keytab_from_secrets(krbctx, keytab);
    362562                break;
    363563        case KERBEROS_VERIFY_SYSTEM_KEYTAB:
    364                 ret = get_mem_keytab_from_system_keytab(krbctx, keytab, true);
     564                ret = fill_mem_keytab_from_system_keytab(krbctx, keytab);
    365565                break;
    366566        case KERBEROS_VERIFY_DEDICATED_KEYTAB:
    367567                /* just use whatever keytab is configured */
    368                 ret = get_mem_keytab_from_system_keytab(krbctx, keytab, false);
     568                ret = fill_mem_keytab_from_dedicated_keytab(krbctx, keytab);
    369569                break;
    370570        case KERBEROS_VERIFY_SECRETS_AND_KEYTAB:
    371                 ret = get_mem_keytab_from_secrets(krbctx, keytab);
    372                 if (ret) {
     571                ret1 = fill_mem_keytab_from_secrets(krbctx, keytab);
     572                if (ret1) {
    373573                        DEBUG(3, (__location__ ": Warning! Unable to set mem "
    374574                                  "keytab from secrets!\n"));
    375575                }
    376576                /* Now append system keytab keys too */
    377                 ret = get_mem_keytab_from_system_keytab(krbctx, keytab, true);
    378                 if (ret) {
     577                ret2 = fill_mem_keytab_from_system_keytab(krbctx, keytab);
     578                if (ret2) {
    379579                        DEBUG(3, (__location__ ": Warning! Unable to set mem "
    380                                   "keytab from secrets!\n"));
     580                                  "keytab from system keytab!\n"));
     581                }
     582                if (ret1 == 0 || ret2 == 0) {
     583                        ret = 0;
     584                } else {
     585                        ret = ret1;
    381586                }
    382587                break;
     588        }
     589
     590        if (ret) {
     591                krb5_kt_close(krbctx, *keytab);
     592                *keytab = NULL;
     593                DEBUG(1,("%s: Error! Unable to set mem keytab - %d\n",
     594                         __location__, ret));
    383595        }
    384596
  • vendor/current/source3/librpc/idl/libnet_join.idl

    r740 r988  
    1616        typedef enum netr_SchannelType netr_SchannelType;
    1717
     18        typedef [public] enum {
     19                JoinDomNameTypeUnknown = 0,
     20                JoinDomNameTypeDNS = 1,
     21                JoinDomNameTypeNBT = 2
     22        } libnetjoin_JoinDomNameType;
     23
    1824        [nopush,nopull,noopnum] WERROR libnet_JoinCtx(
    1925                [in] string dc_name,
    2026                [in] string machine_name,
    2127                [in,ref] string *domain_name,
     28                [in] libnetjoin_JoinDomNameType domain_name_type,
    2229                [in] string account_ou,
    2330                [in] string admin_account,
     31                [in] string admin_domain,
    2432                [in,noprint] string admin_password,
    2533                [in] string machine_password,
     
    2735                [in] string os_version,
    2836                [in] string os_name,
     37                [in] string os_servicepack,
    2938                [in] boolean8 create_upn,
    3039                [in] string upn,
     
    3544                [in] netr_SchannelType secure_channel_type,
    3645                [in,noprint] messaging_context *msg_ctx,
     46                [in] uint32 desired_encryption_types,
    3747                [out] string account_name,
    3848                [out] string netbios_domain_name,
     
    4353                [out] boolean8 modified_config,
    4454                [out] string error_string,
    45                 [out] boolean8 domain_is_ad
     55                [out] boolean8 domain_is_ad,
     56                [out] uint32 set_encryption_types
    4657                );
    4758
     
    5263                [in] string account_ou,
    5364                [in] string admin_account,
     65                [in] string admin_domain,
    5466                [in,noprint] string admin_password,
    5567                [in] string machine_password,
  • vendor/current/source3/librpc/idl/libnetapi.idl

    r740 r988  
    778778
    779779        /*******************************************/
     780        /* NetWkstaGetInfo                         */
     781        /*******************************************/
     782
     783        [public] typedef struct {
     784                uint32 wki100_platform_id;
     785                string wki100_computername;
     786                string wki100_langroup;
     787                uint32 wki100_ver_major;
     788                uint32 wki100_ver_minor;
     789        } WKSTA_INFO_100;
     790
     791        [public] typedef struct {
     792                uint32 wki101_platform_id;
     793                string wki101_computername;
     794                string wki101_langroup;
     795                uint32 wki101_ver_major;
     796                uint32 wki101_ver_minor;
     797                string wki101_lanroot;
     798        } WKSTA_INFO_101;
     799
     800        [public] typedef struct {
     801                uint32 wki102_platform_id;
     802                string wki102_computername;
     803                string wki102_langroup;
     804                uint32 wki102_ver_major;
     805                uint32 wki102_ver_minor;
     806                string wki102_lanroot;
     807                uint32 wki102_logged_on_users;
     808        } WKSTA_INFO_102;
     809
     810        [nopush,nopull] NET_API_STATUS NetWkstaGetInfo(
     811                [in,unique] string *server_name,
     812                [in] uint32 level,
     813                [out] uint8 **buffer
     814                );
     815
     816        /*******************************************/
    780817        /* NetGetDCName                            */
    781818        /*******************************************/
     
    801838        /*******************************************/
    802839
    803         [public] typedef [v1_enum] enum {
     840        [public] typedef [bitmap32bit] bitmap {
    804841                DS_PDC_FLAG                     = 0x00000001,
    805842                DS_GC_FLAG                      = 0x00000004,
     
    814851                DS_SELECT_SECRET_DOMAIN_6_FLAG  = 0x00000800,
    815852                DS_FULL_SECRET_DOMAIN_6_FLAG    = 0x00001000,
     853                DS_WS_FLAG                      = 0x00002000,
     854                DS_DS_8_FLAG                    = 0x00004000,
    816855                DS_DNS_CONTROLLER_FLAG          = 0x20000000,
    817856                DS_DNS_DOMAIN_FLAG              = 0x40000000,
     
    17431782
    17441783        typedef struct {
     1784                string shi502_netname;
     1785                uint32 shi502_type;
     1786                string shi502_remark;
     1787                uint32 shi502_permissions;
     1788                uint32 shi502_max_uses;
     1789                uint32 shi502_current_uses;
     1790                string shi502_path;
     1791                string shi502_passwd;
     1792                uint32 shi502_reserved;
     1793                security_descriptor *shi502_security_descriptor;
     1794        } SHARE_INFO_502;
     1795
     1796        typedef struct {
    17451797                string shi1004_remark;
    17461798        } SHARE_INFO_1004;
  • vendor/current/source3/librpc/idl/perfcount.idl

    r414 r988  
    157157                uint32 Padding;
    158158                /* Now when I'm marshalling this, I'll need to call prs_align_uint64()
    159                    before I start encodint the uint64 structs */
     159                   before I start encoding the uint64 structs */
    160160                /* clock rate * seconds uptime */
    161161                hyper PerfTime;
  • vendor/current/source3/librpc/idl/secrets.idl

    r740 r988  
    2626        } TRUSTED_DOM_PASS;
    2727
     28        /*
     29         * s3 on-disc storage structure for lsa secrets, do not change !
     30         */
     31
     32        typedef [public] struct {
     33                DATA_BLOB *secret_current;
     34                NTTIME secret_current_lastchange;
     35                DATA_BLOB *secret_old;
     36                NTTIME secret_old_lastchange;
     37                security_descriptor *sd;
     38        } lsa_secret;
     39
    2840}
    2941
  • vendor/current/source3/librpc/idl/wscript_build

    r740 r988  
    66
    77bld.SAMBA_PIDL_LIST('PIDL',
    8                     '''messaging.idl libnetapi.idl notify.idl
    9                        perfcount.idl secrets.idl libnet_join.idl server_id.idl''',
     8                    '''libnetapi.idl open_files.idl
     9                       perfcount.idl secrets.idl libnet_join.idl
     10                       smbXsrv.idl
     11                       leases_db.idl
     12                    ''',
    1013                    options='--includedir=%s --header --ndr-parser' % topinclude,
    1114                    output_dir='../gen_ndr')
    12 
    13 bld.SAMBA_PIDL_LIST('PIDL',
    14                     'wbint.idl',
    15                     options='--includedir=%s --header --ndr-parser --samba3-ndr-server --client' % topinclude,
    16                     output_dir='../gen_ndr')
  • vendor/current/source3/librpc/rpc/dcerpc.h

    r919 r988  
    3434
    3535struct NL_AUTH_MESSAGE;
     36struct gensec_security;
    3637
    3738/* auth state for all bind types. */
     
    4041        enum dcerpc_AuthType auth_type;
    4142        enum dcerpc_AuthLevel auth_level;
     43        uint32_t auth_context_id;
     44        bool client_hdr_signing;
     45        bool hdr_signing;
    4246        bool verified_bitmask1;
    4347
    44         void *auth_ctx;
    45         uint32_t auth_context_id;
     48        struct gensec_security *auth_ctx;
    4649
    47         /* Only the client code uses these 3 for now */
    48         char *domain;
    49         char *user_name;
    50         DATA_BLOB user_session_key;
     50        /* Only the client code uses this for now */
     51        DATA_BLOB transport_session_key;
    5152};
    5253
     
    6364                                  struct ncacn_packet *r,
    6465                                  bool bigendian);
    65 NTSTATUS dcerpc_push_schannel_bind(TALLOC_CTX *mem_ctx,
    66                                    struct NL_AUTH_MESSAGE *r,
    67                                    DATA_BLOB *blob);
    6866NTSTATUS dcerpc_push_dcerpc_auth(TALLOC_CTX *mem_ctx,
    6967                                 enum dcerpc_AuthType auth_type,
     
    7573NTSTATUS dcerpc_guess_sizes(struct pipe_auth_data *auth,
    7674                            size_t header_len, size_t data_left,
    77                             size_t max_xmit_frag, size_t pad_alignment,
     75                            size_t max_xmit_frag,
    7876                            size_t *data_to_send, size_t *frag_len,
    7977                            size_t *auth_len, size_t *pad_len);
     
    8684                           DATA_BLOB *raw_pkt);
    8785
    88 /* The following definitions come from librpc/rpc/rpc_common.c  */
    89 
    90 bool smb_register_ndr_interface(const struct ndr_interface_table *interface);
    91 const struct ndr_interface_table *get_iface_from_syntax(
    92         const struct ndr_syntax_id *syntax);
    93 const char *get_pipe_name_from_syntax(TALLOC_CTX *mem_ctx,
    94                                      const struct ndr_syntax_id *syntax);
    95 
    9686#endif /* __S3_DCERPC_H__ */
  • vendor/current/source3/librpc/rpc/dcerpc_ep.c

    r917 r988  
    22 *  Endpoint Mapper Functions
    33 *  DCERPC local endpoint mapper client routines
    4  *  Copyright (c) 2010      Andreas Schneider.
     4 *  Copyright (c) 2010-2011 Andreas Schneider.
    55 *
    66 *  This program is free software; you can redistribute it and/or modify
     
    2525#include "auth.h"
    2626#include "rpc_server/rpc_ncacn_np.h"
     27#include "../lib/tsocket/tsocket.h"
     28#include "rpc_server/rpc_config.h"
    2729
    2830#define EPM_MAX_ANNOTATION_SIZE 64
    2931
    30 NTSTATUS dcerpc_binding_vector_create(TALLOC_CTX *mem_ctx,
    31                                       const struct ndr_interface_table *iface,
    32                                       uint16_t port,
    33                                       const char *ncalrpc,
    34                                       struct dcerpc_binding_vector **pbvec)
     32struct dcerpc_binding_vector {
     33        struct dcerpc_binding **bindings;
     34        uint32_t count;
     35        uint32_t allocated;
     36};
     37
     38static bool binding_vector_realloc(struct dcerpc_binding_vector *bvec)
     39{
     40        if (bvec->count >= bvec->allocated) {
     41                struct dcerpc_binding **tmp;
     42
     43                tmp = talloc_realloc(bvec,
     44                                     bvec->bindings,
     45                                     struct dcerpc_binding *,
     46                                     bvec->allocated * 2);
     47                if (tmp == NULL) {
     48                        return false;
     49                }
     50                bvec->bindings = tmp;
     51                bvec->allocated = bvec->allocated * 2;
     52        }
     53
     54        return true;
     55}
     56
     57NTSTATUS dcerpc_binding_vector_new(TALLOC_CTX *mem_ctx,
     58                                   struct dcerpc_binding_vector **pbvec)
    3559{
    3660        struct dcerpc_binding_vector *bvec;
    37         uint32_t ep_count;
    38         uint32_t count = 0;
    39         uint32_t i;
    4061        NTSTATUS status;
    4162        TALLOC_CTX *tmp_ctx;
     
    4566                return NT_STATUS_NO_MEMORY;
    4667        }
    47 
    48         ep_count = iface->endpoints->count;
    4968
    5069        bvec = talloc_zero(tmp_ctx, struct dcerpc_binding_vector);
     
    5473        }
    5574
    56         bvec->bindings = talloc_zero_array(bvec, struct dcerpc_binding, ep_count);
     75        bvec->bindings = talloc_zero_array(bvec,
     76                                           struct dcerpc_binding *,
     77                                           4);
    5778        if (bvec->bindings == NULL) {
    5879                status = NT_STATUS_NO_MEMORY;
     
    6081        }
    6182
    62         for (i = 0; i < ep_count; i++) {
    63                 struct dcerpc_binding *b;
    64 
    65                 b = talloc_zero(bvec->bindings, struct dcerpc_binding);
    66                 if (b == NULL) {
    67                         status = NT_STATUS_NO_MEMORY;
    68                         goto done;
    69                 }
    70 
    71                 status = dcerpc_parse_binding(b, iface->endpoints->names[i], &b);
    72                 if (!NT_STATUS_IS_OK(status)) {
    73                         status = NT_STATUS_UNSUCCESSFUL;
    74                         goto done;
    75                 }
    76 
    77                 b->object = iface->syntax_id;
    78 
    79                 switch (b->transport) {
    80                         case NCACN_NP:
    81                                 b->host = talloc_asprintf(b, "\\\\%s", global_myname());
    82                                 if (b->host == NULL) {
    83                                         status = NT_STATUS_NO_MEMORY;
    84                                         goto done;
    85                                 }
    86                                 break;
    87                         case NCACN_IP_TCP:
    88                                 if (port == 0) {
    89                                         talloc_free(b);
    90                                         continue;
    91                                 }
    92 
    93                                 b->endpoint = talloc_asprintf(b, "%u", port);
    94                                 if (b->endpoint == NULL) {
    95                                         status = NT_STATUS_NO_MEMORY;
    96                                         goto done;
    97                                 }
    98 
    99                                 break;
    100                         case NCALRPC:
    101                                 if (ncalrpc == NULL) {
    102                                         talloc_free(b);
    103                                         continue;
    104                                 }
    105 
    106                                 b->endpoint = talloc_asprintf(b,
    107                                                               "%s/%s",
    108                                                               lp_ncalrpc_dir(),
    109                                                               ncalrpc);
    110                                 if (b->endpoint == NULL) {
    111                                         status = NT_STATUS_NO_MEMORY;
    112                                         goto done;
    113                                 }
    114                                 break;
    115                         default:
    116                                 talloc_free(b);
    117                                 continue;
    118                 }
    119 
    120                 bvec->bindings[count] = *b;
    121                 count++;
    122         }
    123 
    124         bvec->count = count;
     83        bvec->allocated = 4;
     84        bvec->count = 0;
    12585
    12686        *pbvec = talloc_move(mem_ctx, &bvec);
     
    13393}
    13494
     95NTSTATUS dcerpc_binding_vector_add_np_default(const struct ndr_interface_table *iface,
     96                                              struct dcerpc_binding_vector *bvec)
     97{
     98        uint32_t ep_count = iface->endpoints->count;
     99        uint32_t i;
     100        NTSTATUS status;
     101        bool ok;
     102
     103        for (i = 0; i < ep_count; i++) {
     104                struct dcerpc_binding *b;
     105                enum dcerpc_transport_t transport;
     106                char *unc = NULL;
     107
     108                status = dcerpc_parse_binding(bvec->bindings,
     109                                              iface->endpoints->names[i],
     110                                              &b);
     111                if (!NT_STATUS_IS_OK(status)) {
     112                        return NT_STATUS_UNSUCCESSFUL;
     113                }
     114
     115                /* Only add the named pipes defined in the iface endpoints */
     116                transport = dcerpc_binding_get_transport(b);
     117                if (transport != NCACN_NP) {
     118                        talloc_free(b);
     119                        continue;
     120                }
     121
     122                status = dcerpc_binding_set_abstract_syntax(b, &iface->syntax_id);
     123                if (!NT_STATUS_IS_OK(status)) {
     124                        talloc_free(b);
     125                        return NT_STATUS_UNSUCCESSFUL;
     126                }
     127
     128                unc = talloc_asprintf(b, "\\\\%s", lp_netbios_name());
     129                if (unc == NULL) {
     130                        talloc_free(b);
     131                        return NT_STATUS_NO_MEMORY;
     132                }
     133
     134                status = dcerpc_binding_set_string_option(b, "host", unc);
     135                TALLOC_FREE(unc);
     136                if (!NT_STATUS_IS_OK(status)) {
     137                        talloc_free(b);
     138                        return NT_STATUS_NO_MEMORY;
     139                }
     140
     141                ok = binding_vector_realloc(bvec);
     142                if (!ok) {
     143                        talloc_free(b);
     144                        return NT_STATUS_NO_MEMORY;
     145                }
     146
     147                bvec->bindings[bvec->count] = b;
     148                bvec->count++;
     149        }
     150
     151        return NT_STATUS_OK;
     152}
     153
     154NTSTATUS dcerpc_binding_vector_add_port(const struct ndr_interface_table *iface,
     155                                        struct dcerpc_binding_vector *bvec,
     156                                        const char *host,
     157                                        uint16_t _port)
     158{
     159        uint32_t ep_count = iface->endpoints->count;
     160        uint32_t i;
     161        NTSTATUS status;
     162        bool ok;
     163        char port[6];
     164
     165        snprintf(port, sizeof(port), "%u", _port);
     166
     167        for (i = 0; i < ep_count; i++) {
     168                struct dcerpc_binding *b;
     169                enum dcerpc_transport_t transport;
     170
     171                status = dcerpc_parse_binding(bvec->bindings,
     172                                              iface->endpoints->names[i],
     173                                              &b);
     174                if (!NT_STATUS_IS_OK(status)) {
     175                        return NT_STATUS_UNSUCCESSFUL;
     176                }
     177
     178                transport = dcerpc_binding_get_transport(b);
     179                if (transport != NCACN_IP_TCP) {
     180                        talloc_free(b);
     181                        continue;
     182                }
     183
     184                status = dcerpc_binding_set_abstract_syntax(b, &iface->syntax_id);
     185                if (!NT_STATUS_IS_OK(status)) {
     186                        talloc_free(b);
     187                        return NT_STATUS_UNSUCCESSFUL;
     188                }
     189
     190                status = dcerpc_binding_set_string_option(b, "host", host);
     191                if (!NT_STATUS_IS_OK(status)) {
     192                        talloc_free(b);
     193                        return NT_STATUS_UNSUCCESSFUL;
     194                }
     195
     196                status = dcerpc_binding_set_string_option(b, "endpoint", port);
     197                if (!NT_STATUS_IS_OK(status)) {
     198                        talloc_free(b);
     199                        return NT_STATUS_UNSUCCESSFUL;
     200                }
     201
     202                ok = binding_vector_realloc(bvec);
     203                if (!ok) {
     204                        talloc_free(b);
     205                        return NT_STATUS_NO_MEMORY;
     206                }
     207
     208                bvec->bindings[bvec->count] = b;
     209                bvec->count++;
     210
     211                break;
     212        }
     213
     214        return NT_STATUS_OK;
     215}
     216
     217NTSTATUS dcerpc_binding_vector_add_unix(const struct ndr_interface_table *iface,
     218                                        struct dcerpc_binding_vector *bvec,
     219                                        const char *name)
     220{
     221        uint32_t ep_count = iface->endpoints->count;
     222        uint32_t i;
     223        NTSTATUS status;
     224        bool ok;
     225
     226        for (i = 0; i < ep_count; i++) {
     227                struct dcerpc_binding *b;
     228                enum dcerpc_transport_t transport;
     229                char *endpoint = NULL;
     230
     231                status = dcerpc_parse_binding(bvec->bindings,
     232                                              iface->endpoints->names[i],
     233                                              &b);
     234                if (!NT_STATUS_IS_OK(status)) {
     235                        return NT_STATUS_UNSUCCESSFUL;
     236                }
     237
     238                transport = dcerpc_binding_get_transport(b);
     239                if (transport != NCALRPC) {
     240                        talloc_free(b);
     241                        continue;
     242                }
     243
     244                status = dcerpc_binding_set_abstract_syntax(b, &iface->syntax_id);
     245                if (!NT_STATUS_IS_OK(status)) {
     246                        talloc_free(b);
     247                        return NT_STATUS_UNSUCCESSFUL;
     248                }
     249
     250                endpoint = talloc_asprintf(b,
     251                                           "%s/%s",
     252                                           lp_ncalrpc_dir(),
     253                                           name);
     254                if (endpoint == NULL) {
     255                        talloc_free(b);
     256                        return NT_STATUS_NO_MEMORY;
     257                }
     258
     259                status = dcerpc_binding_set_string_option(b, "endpoint", endpoint);
     260                TALLOC_FREE(endpoint);
     261                if (!NT_STATUS_IS_OK(status)) {
     262                        talloc_free(b);
     263                        return NT_STATUS_UNSUCCESSFUL;
     264                }
     265
     266                ok = binding_vector_realloc(bvec);
     267                if (!ok) {
     268                        talloc_free(b);
     269                        return NT_STATUS_NO_MEMORY;
     270                }
     271
     272                bvec->bindings[bvec->count] = b;
     273                bvec->count++;
     274
     275                break;
     276        }
     277
     278        return NT_STATUS_OK;
     279}
     280
     281NTSTATUS dcerpc_binding_vector_replace_iface(const struct ndr_interface_table *iface,
     282                                             struct dcerpc_binding_vector *v)
     283{
     284        uint32_t i;
     285
     286        for (i = 0; i < v->count; i++) {
     287                struct dcerpc_binding *b = v->bindings[i];
     288                NTSTATUS status;
     289
     290                status = dcerpc_binding_set_abstract_syntax(b,
     291                                                            &iface->syntax_id);
     292                if (!NT_STATUS_IS_OK(status)) {
     293                        return status;
     294                }
     295        }
     296
     297        return NT_STATUS_OK;
     298}
     299
     300struct dcerpc_binding_vector *dcerpc_binding_vector_dup(TALLOC_CTX *mem_ctx,
     301                                                        const struct dcerpc_binding_vector *bvec)
     302{
     303        struct dcerpc_binding_vector *v;
     304        uint32_t i;
     305
     306        v = talloc(mem_ctx, struct dcerpc_binding_vector);
     307        if (v == NULL) {
     308                return NULL;
     309        }
     310
     311        v->bindings = talloc_array(v, struct dcerpc_binding *, bvec->allocated);
     312        if (v->bindings == NULL) {
     313                talloc_free(v);
     314                return NULL;
     315        }
     316        v->allocated = bvec->allocated;
     317
     318        for (i = 0; i < bvec->count; i++) {
     319                struct dcerpc_binding *b;
     320
     321                b = dcerpc_binding_dup(v->bindings, bvec->bindings[i]);
     322                if (b == NULL) {
     323                        talloc_free(v);
     324                        return NULL;
     325                }
     326                v->bindings[i] = b;
     327        }
     328        v->count = bvec->count;
     329
     330        return v;
     331}
     332
    135333static NTSTATUS ep_register(TALLOC_CTX *mem_ctx,
     334                            struct messaging_context *msg_ctx,
    136335                            const struct ndr_interface_table *iface,
    137336                            const struct dcerpc_binding_vector *bind_vec,
     
    146345        struct pipe_auth_data *auth;
    147346        const char *ncalrpc_sock;
    148         const char *rpcsrv_type;
     347        enum rpc_service_mode_e epmd_mode;
    149348        struct epm_entry_t *entries;
    150349        uint32_t num_ents, i;
     
    166365        }
    167366
    168         rpcsrv_type = lp_parm_const_string(GLOBAL_SECTION_SNUM,
    169                                            "rpc_server", "epmapper",
    170                                            "none");
    171 
    172         if (StrCaseCmp(rpcsrv_type, "embedded") == 0) {
    173                 static struct client_address client_id;
    174 
    175                 strlcpy(client_id.addr, "localhost", sizeof(client_id.addr));
    176                 client_id.name = "localhost";
     367        epmd_mode = rpc_epmapper_mode();
     368
     369        if (epmd_mode == RPC_SERVICE_MODE_EMBEDDED) {
     370                struct tsocket_address *local;
     371                int rc;
     372
     373                rc = tsocket_address_inet_from_strings(tmp_ctx,
     374                                                       "ip",
     375                                                       "127.0.0.1",
     376                                                       0,
     377                                                       &local);
     378                if (rc < 0) {
     379                        return NT_STATUS_NO_MEMORY;
     380                }
    177381
    178382                status = rpcint_binding_handle(tmp_ctx,
    179383                                               &ndr_table_epmapper,
    180                                                &client_id,
     384                                               local,
    181385                                               get_session_info_system(),
    182                                                server_messaging_context(),
     386                                               msg_ctx,
    183387                                               &h);
    184388                if (!NT_STATUS_IS_OK(status)) {
     
    187391                        goto done;
    188392                }
    189         } else if (StrCaseCmp(rpcsrv_type, "daemon") == 0) {
     393        } else if (epmd_mode == RPC_SERVICE_MODE_EXTERNAL) {
    190394                /* Connect to the endpoint mapper locally */
    191395                ncalrpc_sock = talloc_asprintf(tmp_ctx,
     
    200404                status = rpc_pipe_open_ncalrpc(tmp_ctx,
    201405                                               ncalrpc_sock,
    202                                                &ndr_table_epmapper.syntax_id,
     406                                               &ndr_table_epmapper,
    203407                                               &cli);
    204408                if (!NT_STATUS_IS_OK(status)) {
     
    228432
    229433        for (i = 0; i < num_ents; i++) {
    230                 struct dcerpc_binding *map_binding = &bind_vec->bindings[i];
     434                struct dcerpc_binding *map_binding;
    231435                struct epm_twr_t *map_tower;
     436
     437                map_binding = dcerpc_binding_dup(entries, bind_vec->bindings[i]);
     438                if (map_binding == NULL) {
     439                        status = NT_STATUS_NO_MEMORY;
     440                        goto done;
     441                }
     442
     443                status = dcerpc_binding_set_abstract_syntax(map_binding,
     444                                                            &iface->syntax_id);
     445                if (!NT_STATUS_IS_OK(status)) {
     446                        goto done;
     447                }
    232448
    233449                map_tower = talloc_zero(entries, struct epm_twr_t);
     
    243459                        goto done;
    244460                }
     461
     462                TALLOC_FREE(map_binding);
    245463
    246464                entries[i].tower = map_tower;
     
    260478                        entries[i].object = *object_guid;
    261479                } else {
    262                         entries[i].object = map_binding->object.uuid;
     480                        ZERO_STRUCT(entries[i].object);
    263481                }
    264482        }
     
    302520
    303521NTSTATUS dcerpc_ep_register(TALLOC_CTX *mem_ctx,
     522                            struct messaging_context *msg_ctx,
    304523                            const struct ndr_interface_table *iface,
    305524                            const struct dcerpc_binding_vector *bind_vec,
     
    309528{
    310529        return ep_register(mem_ctx,
     530                           msg_ctx,
    311531                           iface,
    312532                           bind_vec,
     
    319539
    320540NTSTATUS dcerpc_ep_register_noreplace(TALLOC_CTX *mem_ctx,
     541                                      struct messaging_context *msg_ctx,
    321542                                      const struct ndr_interface_table *iface,
    322543                                      const struct dcerpc_binding_vector *bind_vec,
     
    326547{
    327548        return ep_register(mem_ctx,
     549                           msg_ctx,
    328550                           iface,
    329551                           bind_vec,
     
    335557}
    336558
    337 NTSTATUS dcerpc_ep_unregister(const struct ndr_interface_table *iface,
     559NTSTATUS dcerpc_ep_unregister(struct messaging_context *msg_ctx,
     560                              const struct ndr_interface_table *iface,
    338561                              const struct dcerpc_binding_vector *bind_vec,
    339562                              const struct GUID *object_guid)
    340563{
    341564        return ep_register(NULL,
     565                           msg_ctx,
    342566                           iface,
    343567                           bind_vec,
  • vendor/current/source3/librpc/rpc/dcerpc_ep.h

    r740 r988  
    22 *  Endpoint Mapper Functions
    33 *  DCERPC local endpoint mapper client routines
    4  *  Copyright (c) 2010      Andreas Schneider.
     4 *  Copyright (c) 2010-2011 Andreas Schneider.
    55 *
    66 *  This program is free software; you can redistribute it and/or modify
     
    2121#define _DCERPC_EP_H_
    2222
    23 struct dcerpc_binding_vector {
    24     struct dcerpc_binding *bindings;
    25     uint32_t count;
    26 };
     23struct dcerpc_binding_vector;
    2724
    28 NTSTATUS dcerpc_binding_vector_create(TALLOC_CTX *mem_ctx,
    29                                       const struct ndr_interface_table *iface,
    30                                       uint16_t port,
    31                                       const char *ncalrpc,
    32                                       struct dcerpc_binding_vector **pbvec);
     25/**
     26 * @brief Allocate a new binding vector.
     27 *
     28 * @param[in]  mem_ctx  The memory context to allocate the vector.
     29 *
     30 * @param[out] pbvec    A pointer to store the binding vector.
     31 *
     32 * @return              An NTSTATUS error code.
     33 */
     34NTSTATUS dcerpc_binding_vector_new(TALLOC_CTX *mem_ctx,
     35                                   struct dcerpc_binding_vector **pbvec);
     36
     37/**
     38 * @brief Add default named pipes to the binding vector.
     39 *
     40 * @param[in] iface     The rpc interface to add.
     41 *
     42 * @param[in] bvec      The binding vector to add the interface.
     43 *
     44 * @return              An NTSTATUS error code.
     45 */
     46NTSTATUS dcerpc_binding_vector_add_np_default(const struct ndr_interface_table *iface,
     47                                              struct dcerpc_binding_vector *bvec);
     48
     49/**
     50 * @brief Add a tcpip port to a binding vector.
     51 *
     52 * @param[in] iface     The rpc interface to add.
     53 *
     54 * @param[in] bvec      The binding vector to add the interface, host and port.
     55 *
     56 * @param[in] host      The ip address of the network interface bound.
     57 *
     58 * @param[in] port      The port bound.
     59 *
     60 * @return              An NTSTATUS error code.
     61 */
     62NTSTATUS dcerpc_binding_vector_add_port(const struct ndr_interface_table *iface,
     63                                        struct dcerpc_binding_vector *bvec,
     64                                        const char *host,
     65                                        uint16_t port);
     66
     67/**
     68 * @brief Add a unix socket (ncalrpc) to a binding vector.
     69 *
     70 * @param[in] iface     The rpc interface to add.
     71 *
     72 * @param[in] bvec      The binding vector to add the interface, host and port.
     73 *
     74 * @param[in] name      The name of the unix socket.
     75 *
     76 * @return              An NTSTATUS error code.
     77 */
     78NTSTATUS dcerpc_binding_vector_add_unix(const struct ndr_interface_table *iface,
     79                                        struct dcerpc_binding_vector *bvec,
     80                                        const char *name);
     81
     82/**
     83 * @brief Duplicate a dcerpc_binding_vector.
     84 *
     85 * @param[in] mem_ctx   The memory context to create the duplicate on.
     86 *
     87 * @param[in] bvec      The binding vector to duplicate.
     88 *
     89 * @return              The duplicated binding vector or NULL on error.
     90 */
     91struct dcerpc_binding_vector *dcerpc_binding_vector_dup(TALLOC_CTX *mem_ctx,
     92                                                        const struct dcerpc_binding_vector *bvec);
     93
     94/**
     95 * @brief Replace the interface of the bindings in the vector.
     96 *
     97 * @param[in] iface     The new interface identifier to use.
     98 *
     99 * @param[in] v         The binding vector to change.
     100 *
     101 * @return              An NTSTATUS error code.
     102 */
     103NTSTATUS dcerpc_binding_vector_replace_iface(const struct ndr_interface_table *iface,
     104                                             struct dcerpc_binding_vector *v);
    33105
    34106/**
     
    65137 */
    66138NTSTATUS dcerpc_ep_register(TALLOC_CTX *mem_ctx,
     139                            struct messaging_context *msg_ctx,
    67140                            const struct ndr_interface_table *iface,
    68141                            const struct dcerpc_binding_vector *bind_vec,
     
    72145
    73146NTSTATUS dcerpc_ep_register_noreplace(TALLOC_CTX *mem_ctx,
     147                                      struct messaging_context *msg_ctx,
    74148                                      const struct ndr_interface_table *iface,
    75149                                      const struct dcerpc_binding_vector *bind_vec,
     
    78152                                      struct dcerpc_binding_handle **ph);
    79153
    80 NTSTATUS dcerpc_ep_unregister(const struct ndr_interface_table *iface,
     154NTSTATUS dcerpc_ep_unregister(struct messaging_context *msg_ctx,
     155                              const struct ndr_interface_table *iface,
    81156                              const struct dcerpc_binding_vector *bind_vec,
    82157                              const struct GUID *object_guid);
  • vendor/current/source3/librpc/rpc/dcerpc_helpers.c

    r919 r988  
    2222#include "librpc/rpc/dcerpc.h"
    2323#include "librpc/gen_ndr/ndr_dcerpc.h"
    24 #include "librpc/gen_ndr/ndr_schannel.h"
    25 #include "../libcli/auth/schannel.h"
    26 #include "../libcli/auth/spnego.h"
    27 #include "../libcli/auth/ntlmssp.h"
    28 #include "ntlmssp_wrap.h"
    2924#include "librpc/crypto/gse.h"
    30 #include "librpc/crypto/spnego.h"
     25#include "auth/gensec/gensec.h"
    3126
    3227#undef DBGC_CLASS
     
    138133
    139134/**
    140 * @brief NDR Encodes a NL_AUTH_MESSAGE
    141 *
    142 * @param mem_ctx        The memory context the blob will be allocated on
    143 * @param r              The NL_AUTH_MESSAGE to encode
    144 * @param blob [out]     The encoded blob if successful
    145 *
    146 * @return a NTSTATUS error code
    147 */
    148 NTSTATUS dcerpc_push_schannel_bind(TALLOC_CTX *mem_ctx,
    149                                    struct NL_AUTH_MESSAGE *r,
    150                                    DATA_BLOB *blob)
    151 {
    152         enum ndr_err_code ndr_err;
    153 
    154         ndr_err = ndr_push_struct_blob(blob, mem_ctx, r,
    155                 (ndr_push_flags_fn_t)ndr_push_NL_AUTH_MESSAGE);
    156         if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
    157                 return ndr_map_error2ntstatus(ndr_err);
    158         }
    159 
    160         if (DEBUGLEVEL >= 10) {
    161                 NDR_PRINT_DEBUG(NL_AUTH_MESSAGE, r);
    162         }
    163 
    164         return NT_STATUS_OK;
    165 }
    166 
    167 /**
    168135* @brief NDR Encodes a dcerpc_auth structure
    169136*
     
    218185* @param data_left      The data left in the send buffer
    219186* @param max_xmit_frag  The max fragment size.
    220 * @param pad_alignment  The NDR padding size.
    221187* @param data_to_send   [out] The max data we will send in the pdu
    222188* @param frag_len       [out] The total length of the fragment
     
    228194NTSTATUS dcerpc_guess_sizes(struct pipe_auth_data *auth,
    229195                            size_t header_len, size_t data_left,
    230                             size_t max_xmit_frag, size_t pad_alignment,
     196                            size_t max_xmit_frag,
    231197                            size_t *data_to_send, size_t *frag_len,
    232198                            size_t *auth_len, size_t *pad_len)
     
    234200        size_t max_len;
    235201        size_t mod_len;
    236         struct schannel_state *schannel_auth;
    237         struct spnego_context *spnego_ctx;
    238         struct gse_context *gse_ctx;
    239         enum spnego_mech auth_type;
    240         void *auth_ctx;
    241         bool seal = false;
    242         NTSTATUS status;
     202        struct gensec_security *gensec_security;
    243203
    244204        /* no auth token cases first */
     
    255215
    256216        case DCERPC_AUTH_LEVEL_PRIVACY:
    257                 seal = true;
    258217                break;
    259218
     
    273232        switch (auth->auth_type) {
    274233        case DCERPC_AUTH_TYPE_SPNEGO:
    275                 spnego_ctx = talloc_get_type_abort(auth->auth_ctx,
    276                                                    struct spnego_context);
    277                 status = spnego_get_negotiated_mech(spnego_ctx,
    278                                                     &auth_type, &auth_ctx);
    279                 if (!NT_STATUS_IS_OK(status)) {
    280                         return status;
    281                 }
    282                 switch (auth_type) {
    283                 case SPNEGO_NTLMSSP:
    284                         *auth_len = NTLMSSP_SIG_SIZE;
    285                         break;
    286 
    287                 case SPNEGO_KRB5:
    288                         gse_ctx = talloc_get_type_abort(auth_ctx,
    289                                                         struct gse_context);
    290                         if (!gse_ctx) {
    291                                 return NT_STATUS_INVALID_PARAMETER;
    292                         }
    293                         *auth_len = gse_get_signature_length(gse_ctx,
    294                                                              seal, max_len);
    295                         break;
    296 
    297                 default:
    298                         return NT_STATUS_INVALID_PARAMETER;
    299                 }
    300                 break;
    301 
    302234        case DCERPC_AUTH_TYPE_NTLMSSP:
    303                 *auth_len = NTLMSSP_SIG_SIZE;
    304                 break;
    305 
     235        case DCERPC_AUTH_TYPE_KRB5:
    306236        case DCERPC_AUTH_TYPE_SCHANNEL:
    307                 schannel_auth = talloc_get_type_abort(auth->auth_ctx,
    308                                                       struct schannel_state);
    309                 *auth_len = netsec_outgoing_sig_size(schannel_auth);
    310                 break;
    311 
    312         case DCERPC_AUTH_TYPE_KRB5:
    313                 gse_ctx = talloc_get_type_abort(auth->auth_ctx,
    314                                                 struct gse_context);
    315                 *auth_len = gse_get_signature_length(gse_ctx,
    316                                                      seal, max_len);
    317                 break;
    318 
     237                gensec_security = auth->auth_ctx;
     238                mod_len = (max_len % DCERPC_AUTH_PAD_ALIGNMENT);
     239                *auth_len = gensec_sig_size(gensec_security, max_len - mod_len);
     240                if (*auth_len == 0) {
     241                        return NT_STATUS_INTERNAL_ERROR;
     242                }
     243                break;
    319244        default:
    320245                return NT_STATUS_INVALID_PARAMETER;
     
    322247
    323248        max_len -= *auth_len;
     249        mod_len = (max_len % DCERPC_AUTH_PAD_ALIGNMENT);
     250        max_len -= mod_len;
    324251
    325252        *data_to_send = MIN(max_len, data_left);
    326253
    327         mod_len = (header_len + *data_to_send) % pad_alignment;
    328         if (mod_len) {
    329                 *pad_len = pad_alignment - mod_len;
    330         } else {
    331                 *pad_len = 0;
    332         }
    333 
    334         if (*data_to_send + *pad_len > max_len) {
    335                 *data_to_send -= pad_alignment;
    336         }
     254        *pad_len = DCERPC_AUTH_PAD_LENGTH(*data_to_send);
    337255
    338256        *frag_len = header_len + *data_to_send + *pad_len
     
    346264 ********************************************************************/
    347265
    348 static NTSTATUS add_ntlmssp_auth_footer(struct auth_ntlmssp_state *auth_state,
     266static NTSTATUS add_generic_auth_footer(struct gensec_security *gensec_security,
    349267                                        enum dcerpc_AuthLevel auth_level,
    350268                                        DATA_BLOB *rpc_out)
     
    356274        NTSTATUS status;
    357275
    358         if (!auth_state) {
     276        if (!gensec_security) {
    359277                return NT_STATUS_INVALID_PARAMETER;
    360278        }
     
    363281        case DCERPC_AUTH_LEVEL_PRIVACY:
    364282                /* Data portion is encrypted. */
    365                 status = auth_ntlmssp_seal_packet(auth_state,
    366                                              rpc_out->data,
    367                                              rpc_out->data
    368                                                 + DCERPC_RESPONSE_LENGTH,
    369                                              data_and_pad_len,
    370                                              rpc_out->data,
    371                                              rpc_out->length,
    372                                              &auth_blob);
     283                status = gensec_seal_packet(gensec_security,
     284                                            rpc_out->data,
     285                                            rpc_out->data
     286                                            + DCERPC_RESPONSE_LENGTH,
     287                                            data_and_pad_len,
     288                                            rpc_out->data,
     289                                            rpc_out->length,
     290                                            &auth_blob);
    373291                if (!NT_STATUS_IS_OK(status)) {
    374292                        return status;
     
    378296        case DCERPC_AUTH_LEVEL_INTEGRITY:
    379297                /* Data is signed. */
    380                 status = auth_ntlmssp_sign_packet(auth_state,
    381                                              rpc_out->data,
    382                                              rpc_out->data
    383                                                 + DCERPC_RESPONSE_LENGTH,
    384                                              data_and_pad_len,
    385                                              rpc_out->data,
    386                                              rpc_out->length,
    387                                              &auth_blob);
     298                status = gensec_sign_packet(gensec_security,
     299                                            rpc_out->data,
     300                                            rpc_out->data
     301                                            + DCERPC_RESPONSE_LENGTH,
     302                                            data_and_pad_len,
     303                                            rpc_out->data,
     304                                            rpc_out->length,
     305                                            &auth_blob);
    388306                if (!NT_STATUS_IS_OK(status)) {
    389307                        return status;
     
    414332 ********************************************************************/
    415333
    416 static NTSTATUS get_ntlmssp_auth_footer(struct auth_ntlmssp_state *auth_state,
     334static NTSTATUS get_generic_auth_footer(struct gensec_security *gensec_security,
    417335                                        enum dcerpc_AuthLevel auth_level,
    418336                                        DATA_BLOB *data, DATA_BLOB *full_pkt,
    419337                                        DATA_BLOB *auth_token)
    420338{
     339        if (gensec_security == NULL) {
     340                return NT_STATUS_INVALID_PARAMETER;
     341        }
     342
    421343        switch (auth_level) {
    422344        case DCERPC_AUTH_LEVEL_PRIVACY:
    423345                /* Data portion is encrypted. */
    424                 return auth_ntlmssp_unseal_packet(auth_state,
    425                                                   data->data,
    426                                                   data->length,
    427                                                   full_pkt->data,
    428                                                   full_pkt->length,
    429                                                   auth_token);
     346                return gensec_unseal_packet(gensec_security,
     347                                            data->data,
     348                                            data->length,
     349                                            full_pkt->data,
     350                                            full_pkt->length,
     351                                            auth_token);
    430352
    431353        case DCERPC_AUTH_LEVEL_INTEGRITY:
    432354                /* Data is signed. */
    433                 return auth_ntlmssp_check_packet(auth_state,
    434                                                  data->data,
    435                                                  data->length,
    436                                                  full_pkt->data,
    437                                                  full_pkt->length,
    438                                                  auth_token);
    439 
    440         default:
    441                 return NT_STATUS_INVALID_PARAMETER;
    442         }
    443 }
    444 
    445 /*******************************************************************
    446  Create and add the schannel sign/seal auth data.
    447  ********************************************************************/
    448 
    449 static NTSTATUS add_schannel_auth_footer(struct schannel_state *sas,
    450                                         enum dcerpc_AuthLevel auth_level,
    451                                         DATA_BLOB *rpc_out)
    452 {
    453         uint8_t *data_p = rpc_out->data + DCERPC_RESPONSE_LENGTH;
    454         size_t data_and_pad_len = rpc_out->length
    455                                         - DCERPC_RESPONSE_LENGTH
    456                                         - DCERPC_AUTH_TRAILER_LENGTH;
    457         DATA_BLOB auth_blob;
    458         NTSTATUS status;
    459 
    460         if (!sas) {
    461                 return NT_STATUS_INVALID_PARAMETER;
    462         }
    463 
    464         DEBUG(10,("add_schannel_auth_footer: SCHANNEL seq_num=%d\n",
    465                         sas->seq_num));
    466 
    467         switch (auth_level) {
    468         case DCERPC_AUTH_LEVEL_PRIVACY:
    469                 status = netsec_outgoing_packet(sas,
    470                                                 rpc_out->data,
    471                                                 true,
    472                                                 data_p,
    473                                                 data_and_pad_len,
    474                                                 &auth_blob);
    475                 break;
    476         case DCERPC_AUTH_LEVEL_INTEGRITY:
    477                 status = netsec_outgoing_packet(sas,
    478                                                 rpc_out->data,
    479                                                 false,
    480                                                 data_p,
    481                                                 data_and_pad_len,
    482                                                 &auth_blob);
    483                 break;
    484         default:
    485                 status = NT_STATUS_INTERNAL_ERROR;
    486                 break;
    487         }
    488 
    489         if (!NT_STATUS_IS_OK(status)) {
    490                 DEBUG(1,("add_schannel_auth_footer: failed to process packet: %s\n",
    491                         nt_errstr(status)));
    492                 return status;
    493         }
    494 
    495         if (DEBUGLEVEL >= 10) {
    496                 dump_NL_AUTH_SIGNATURE(talloc_tos(), &auth_blob);
    497         }
    498 
    499         /* Finally attach the blob. */
    500         if (!data_blob_append(NULL, rpc_out,
    501                                 auth_blob.data, auth_blob.length)) {
    502                 return NT_STATUS_NO_MEMORY;
    503         }
    504         data_blob_free(&auth_blob);
    505 
    506         return NT_STATUS_OK;
    507 }
    508 
    509 /*******************************************************************
    510  Check/unseal the Schannel auth data. (Unseal in place).
    511  ********************************************************************/
    512 
    513 static NTSTATUS get_schannel_auth_footer(TALLOC_CTX *mem_ctx,
    514                                          struct schannel_state *auth_state,
    515                                          enum dcerpc_AuthLevel auth_level,
    516                                          DATA_BLOB *data, DATA_BLOB *full_pkt,
    517                                          DATA_BLOB *auth_token)
    518 {
    519         switch (auth_level) {
    520         case DCERPC_AUTH_LEVEL_PRIVACY:
    521                 /* Data portion is encrypted. */
    522                 return netsec_incoming_packet(auth_state,
    523                                                 mem_ctx, true,
    524                                                 data->data,
    525                                                 data->length,
    526                                                 auth_token);
    527 
    528         case DCERPC_AUTH_LEVEL_INTEGRITY:
    529                 /* Data is signed. */
    530                 return netsec_incoming_packet(auth_state,
    531                                                 mem_ctx, false,
    532                                                 data->data,
    533                                                 data->length,
    534                                                 auth_token);
    535 
    536         default:
    537                 return NT_STATUS_INVALID_PARAMETER;
    538         }
    539 }
    540 
    541 /*******************************************************************
    542  Create and add the gssapi sign/seal auth data.
    543  ********************************************************************/
    544 
    545 static NTSTATUS add_gssapi_auth_footer(struct gse_context *gse_ctx,
    546                                         enum dcerpc_AuthLevel auth_level,
    547                                         DATA_BLOB *rpc_out)
    548 {
    549         DATA_BLOB data;
    550         DATA_BLOB auth_blob;
    551         NTSTATUS status;
    552 
    553         if (!gse_ctx) {
    554                 return NT_STATUS_INVALID_PARAMETER;
    555         }
    556 
    557         data.data = rpc_out->data + DCERPC_RESPONSE_LENGTH;
    558         data.length = rpc_out->length - DCERPC_RESPONSE_LENGTH
    559                                         - DCERPC_AUTH_TRAILER_LENGTH;
    560 
    561         switch (auth_level) {
    562         case DCERPC_AUTH_LEVEL_PRIVACY:
    563                 status = gse_seal(talloc_tos(), gse_ctx, &data, &auth_blob);
    564                 break;
    565         case DCERPC_AUTH_LEVEL_INTEGRITY:
    566                 status = gse_sign(talloc_tos(), gse_ctx, &data, &auth_blob);
    567                 break;
    568         default:
    569                 status = NT_STATUS_INTERNAL_ERROR;
    570                 break;
    571         }
    572 
    573         if (!NT_STATUS_IS_OK(status)) {
    574                 DEBUG(1, ("Failed to process packet: %s\n",
    575                           nt_errstr(status)));
    576                 return status;
    577         }
    578 
    579         /* Finally attach the blob. */
    580         if (!data_blob_append(NULL, rpc_out,
    581                                 auth_blob.data, auth_blob.length)) {
    582                 return NT_STATUS_NO_MEMORY;
    583         }
    584 
    585         data_blob_free(&auth_blob);
    586 
    587         return NT_STATUS_OK;
    588 }
    589 
    590 /*******************************************************************
    591  Check/unseal the gssapi auth data. (Unseal in place).
    592  ********************************************************************/
    593 
    594 static NTSTATUS get_gssapi_auth_footer(TALLOC_CTX *mem_ctx,
    595                                         struct gse_context *gse_ctx,
    596                                         enum dcerpc_AuthLevel auth_level,
    597                                         DATA_BLOB *data, DATA_BLOB *full_pkt,
    598                                         DATA_BLOB *auth_token)
    599 {
    600         /* TODO: pass in full_pkt when
    601          * DCERPC_PFC_FLAG_SUPPORT_HEADER_SIGN is set */
    602         switch (auth_level) {
    603         case DCERPC_AUTH_LEVEL_PRIVACY:
    604                 /* Data portion is encrypted. */
    605                 return gse_unseal(mem_ctx, gse_ctx,
    606                                   data, auth_token);
    607 
    608         case DCERPC_AUTH_LEVEL_INTEGRITY:
    609                 /* Data is signed. */
    610                 return gse_sigcheck(mem_ctx, gse_ctx,
    611                                     data, auth_token);
    612         default:
    613                 return NT_STATUS_INVALID_PARAMETER;
    614         }
    615 }
    616 
    617 /*******************************************************************
    618  Create and add the spnego-negotiated sign/seal auth data.
    619  ********************************************************************/
    620 
    621 static NTSTATUS add_spnego_auth_footer(struct spnego_context *spnego_ctx,
    622                                         enum dcerpc_AuthLevel auth_level,
    623                                         DATA_BLOB *rpc_out)
    624 {
    625         DATA_BLOB auth_blob;
    626         DATA_BLOB rpc_data;
    627         NTSTATUS status;
    628 
    629         if (!spnego_ctx) {
    630                 return NT_STATUS_INVALID_PARAMETER;
    631         }
    632 
    633         rpc_data = data_blob_const(rpc_out->data
    634                                         + DCERPC_RESPONSE_LENGTH,
    635                                    rpc_out->length
    636                                         - DCERPC_RESPONSE_LENGTH
    637                                         - DCERPC_AUTH_TRAILER_LENGTH);
    638 
    639         switch (auth_level) {
    640         case DCERPC_AUTH_LEVEL_PRIVACY:
    641                 /* Data portion is encrypted. */
    642                 status = spnego_seal(rpc_out->data, spnego_ctx,
    643                                      &rpc_data, rpc_out, &auth_blob);
    644                 break;
    645 
    646                 if (!NT_STATUS_IS_OK(status)) {
    647                         return status;
    648                 }
    649                 break;
    650 
    651         case DCERPC_AUTH_LEVEL_INTEGRITY:
    652                 /* Data is signed. */
    653                 status = spnego_sign(rpc_out->data, spnego_ctx,
    654                                      &rpc_data, rpc_out, &auth_blob);
    655                 break;
    656 
    657                 if (!NT_STATUS_IS_OK(status)) {
    658                         return status;
    659                 }
    660                 break;
    661 
    662         default:
    663                 /* Can't happen. */
    664                 smb_panic("bad auth level");
    665                 /* Notreached. */
    666                 return NT_STATUS_INVALID_PARAMETER;
    667         }
    668 
    669         /* Finally attach the blob. */
    670         if (!data_blob_append(NULL, rpc_out,
    671                                 auth_blob.data, auth_blob.length)) {
    672                 DEBUG(0, ("Failed to add %u bytes auth blob.\n",
    673                           (unsigned int)auth_blob.length));
    674                 return NT_STATUS_NO_MEMORY;
    675         }
    676         data_blob_free(&auth_blob);
    677 
    678         return NT_STATUS_OK;
    679 }
    680 
    681 static NTSTATUS get_spnego_auth_footer(TALLOC_CTX *mem_ctx,
    682                                         struct spnego_context *sp_ctx,
    683                                         enum dcerpc_AuthLevel auth_level,
    684                                         DATA_BLOB *data, DATA_BLOB *full_pkt,
    685                                         DATA_BLOB *auth_token)
    686 {
    687         switch (auth_level) {
    688         case DCERPC_AUTH_LEVEL_PRIVACY:
    689                 /* Data portion is encrypted. */
    690                 return spnego_unseal(mem_ctx, sp_ctx,
    691                                      data, full_pkt, auth_token);
    692 
    693         case DCERPC_AUTH_LEVEL_INTEGRITY:
    694                 /* Data is signed. */
    695                 return spnego_sigcheck(mem_ctx, sp_ctx,
    696                                        data, full_pkt, auth_token);
     355                return gensec_check_packet(gensec_security,
     356                                           data->data,
     357                                           data->length,
     358                                           full_pkt->data,
     359                                           full_pkt->length,
     360                                           auth_token);
    697361
    698362        default:
     
    713377                                size_t pad_len, DATA_BLOB *rpc_out)
    714378{
    715         struct schannel_state *schannel_auth;
    716         struct auth_ntlmssp_state *ntlmssp_ctx;
    717         struct spnego_context *spnego_ctx;
    718         struct gse_context *gse_ctx;
    719         char pad[CLIENT_NDR_PADDING_SIZE] = { 0, };
     379        struct gensec_security *gensec_security;
     380        const char pad[DCERPC_AUTH_PAD_ALIGNMENT] = { 0, };
    720381        DATA_BLOB auth_info;
    721382        DATA_BLOB auth_blob;
    722383        NTSTATUS status;
    723384
    724         if (auth->auth_type == DCERPC_AUTH_TYPE_NONE ||
    725             auth->auth_type == DCERPC_AUTH_TYPE_NCALRPC_AS_SYSTEM) {
     385        if (auth->auth_type == DCERPC_AUTH_TYPE_NONE) {
    726386                return NT_STATUS_OK;
    727387        }
    728388
    729389        if (pad_len) {
     390                SMB_ASSERT(pad_len <= ARRAY_SIZE(pad));
     391
    730392                /* Copy the sign/seal padding data. */
    731393                if (!data_blob_append(NULL, rpc_out, pad, pad_len)) {
     
    761423        switch (auth->auth_type) {
    762424        case DCERPC_AUTH_TYPE_NONE:
    763         case DCERPC_AUTH_TYPE_NCALRPC_AS_SYSTEM:
    764425                status = NT_STATUS_OK;
    765426                break;
    766         case DCERPC_AUTH_TYPE_SPNEGO:
    767                 spnego_ctx = talloc_get_type_abort(auth->auth_ctx,
    768                                                    struct spnego_context);
    769                 status = add_spnego_auth_footer(spnego_ctx,
    770                                                 auth->auth_level, rpc_out);
    771                 break;
    772         case DCERPC_AUTH_TYPE_NTLMSSP:
    773                 ntlmssp_ctx = talloc_get_type_abort(auth->auth_ctx,
    774                                                 struct auth_ntlmssp_state);
    775                 status = add_ntlmssp_auth_footer(ntlmssp_ctx,
     427        default:
     428                gensec_security = auth->auth_ctx;
     429                status = add_generic_auth_footer(gensec_security,
    776430                                                 auth->auth_level,
    777431                                                 rpc_out);
    778                 break;
    779         case DCERPC_AUTH_TYPE_SCHANNEL:
    780                 schannel_auth = talloc_get_type_abort(auth->auth_ctx,
    781                                                       struct schannel_state);
    782                 status = add_schannel_auth_footer(schannel_auth,
    783                                                   auth->auth_level,
    784                                                   rpc_out);
    785                 break;
    786         case DCERPC_AUTH_TYPE_KRB5:
    787                 gse_ctx = talloc_get_type_abort(auth->auth_ctx,
    788                                                 struct gse_context);
    789                 status = add_gssapi_auth_footer(gse_ctx,
    790                                                 auth->auth_level,
    791                                                 rpc_out);
    792                 break;
    793         default:
    794                 status = NT_STATUS_INVALID_PARAMETER;
    795432                break;
    796433        }
     
    817454                           DATA_BLOB *raw_pkt)
    818455{
    819         struct schannel_state *schannel_auth;
    820         struct auth_ntlmssp_state *ntlmssp_ctx;
    821         struct spnego_context *spnego_ctx;
    822         struct gse_context *gse_ctx;
     456        struct gensec_security *gensec_security;
    823457        NTSTATUS status;
    824458        struct dcerpc_auth auth_info;
     
    894528        switch (auth->auth_type) {
    895529        case DCERPC_AUTH_TYPE_NONE:
    896         case DCERPC_AUTH_TYPE_NCALRPC_AS_SYSTEM:
    897530                return NT_STATUS_OK;
    898531
    899         case DCERPC_AUTH_TYPE_SPNEGO:
    900                 spnego_ctx = talloc_get_type_abort(auth->auth_ctx,
    901                                                    struct spnego_context);
    902                 status = get_spnego_auth_footer(pkt, spnego_ctx,
    903                                                 auth->auth_level,
    904                                                 &data, &full_pkt,
    905                                                 &auth_info.credentials);
    906                 if (!NT_STATUS_IS_OK(status)) {
    907                         return status;
    908                 }
    909                 break;
    910 
    911         case DCERPC_AUTH_TYPE_NTLMSSP:
    912 
    913                 DEBUG(10, ("NTLMSSP auth\n"));
    914 
    915                 ntlmssp_ctx = talloc_get_type_abort(auth->auth_ctx,
    916                                                 struct auth_ntlmssp_state);
    917                 status = get_ntlmssp_auth_footer(ntlmssp_ctx,
     532        default:
     533                DEBUG(10, ("GENSEC auth\n"));
     534
     535                gensec_security = auth->auth_ctx;
     536                status = get_generic_auth_footer(gensec_security,
    918537                                                 auth->auth_level,
    919538                                                 &data, &full_pkt,
     
    923542                }
    924543                break;
    925 
    926         case DCERPC_AUTH_TYPE_SCHANNEL:
    927 
    928                 DEBUG(10, ("SCHANNEL auth\n"));
    929 
    930                 schannel_auth = talloc_get_type_abort(auth->auth_ctx,
    931                                                       struct schannel_state);
    932                 status = get_schannel_auth_footer(pkt, schannel_auth,
    933                                                   auth->auth_level,
    934                                                   &data, &full_pkt,
    935                                                   &auth_info.credentials);
    936                 if (!NT_STATUS_IS_OK(status)) {
    937                         return status;
    938                 }
    939                 break;
    940 
    941         case DCERPC_AUTH_TYPE_KRB5:
    942 
    943                 DEBUG(10, ("KRB5 auth\n"));
    944 
    945                 gse_ctx = talloc_get_type_abort(auth->auth_ctx,
    946                                                 struct gse_context);
    947                 status = get_gssapi_auth_footer(pkt, gse_ctx,
    948                                                 auth->auth_level,
    949                                                 &data, &full_pkt,
    950                                                 &auth_info.credentials);
    951                 if (!NT_STATUS_IS_OK(status)) {
    952                         return status;
    953                 }
    954                 break;
    955 
    956         default:
    957                 DEBUG(0, ("process_request_pdu: "
    958                           "unknown auth type %u set.\n",
    959                           (unsigned int)auth->auth_type));
    960                 return NT_STATUS_INVALID_PARAMETER;
    961544        }
    962545
  • vendor/current/source3/librpc/wscript_build

    r740 r988  
    88bld.SAMBA3_SUBSYSTEM('NDR_LIBNET_JOIN',
    99        source='gen_ndr/ndr_libnet_join.c',
    10         public_deps='ndr'
     10        public_deps='ndr krb5samba'
    1111        )
    1212
    13 bld.SAMBA3_SUBSYSTEM('NDR_SERVER_ID',
    14         source='gen_ndr/ndr_server_id.c',
    15         public_deps='ndr'
     13bld.SAMBA3_SUBSYSTEM('NDR_OPEN_FILES',
     14        source='gen_ndr/ndr_open_files.c',
     15        public_deps='ndr NDR_SERVER_ID NDR_FILE_ID NDR_SECURITY NDR_SMB2_LEASE_STRUCT'
    1616        )
    1717
    18 bld.SAMBA3_SUBSYSTEM('NDR_MESSAGING',
    19         source='gen_ndr/ndr_messaging.c',
    20         public_deps='ndr NDR_SERVER_ID'
     18bld.SAMBA3_SUBSYSTEM('NDR_SMBXSRV',
     19        source='gen_ndr/ndr_smbXsrv.c',
     20        public_deps='ndr NDR_SERVER_ID NDR_SECURITY NDR_AUTH'
    2121        )
    2222
    23 bld.SAMBA3_SUBSYSTEM('NDR_NOTIFY3',
    24         source='gen_ndr/ndr_notify.c',
    25         public_deps='ndr NDR_FILE_ID NDR_SERVER_ID'
     23bld.SAMBA3_SUBSYSTEM('NDR_LEASES_DB',
     24        source='gen_ndr/ndr_leases_db.c',
     25        public_deps='ndr'
    2626        )
    2727
     
    3636        )
    3737
    38 bld.SAMBA3_SUBSYSTEM('NDR_WBINT',
    39         source='gen_ndr/ndr_wbint.c',
    40         public_deps='ndr'
    41         )
    42 
    43 bld.SAMBA3_SUBSYSTEM('RPC_NDR_WBINT',
    44         source='../librpc/gen_ndr/ndr_wbint_c.c',
    45         public_deps='dcerpc NDR_WBINT'
    46         )
    47 
    48 bld.SAMBA3_SUBSYSTEM('SRV_NDR_WBINT',
    49         source='../librpc/gen_ndr/srv_wbint.c',
    50         public_deps='NDR_WBINT'
    51         )
Note: See TracChangeset for help on using the changeset viewer.