Ignore:
Timestamp:
Nov 14, 2012, 12:59:34 PM (13 years ago)
Author:
Silvan Scherrer
Message:

Samba Server: update vendor to 3.6.0

Location:
vendor/current/source4/auth/gensec
Files:
3 added
4 deleted
11 edited

Legend:

Unmodified
Added
Removed
  • vendor/current/source4/auth/gensec/cyrus_sasl.c

    r414 r740  
    2121
    2222#include "includes.h"
    23 #include "auth/auth.h"
     23#include "lib/tsocket/tsocket.h"
    2424#include "auth/credentials/credentials.h"
    2525#include "auth/gensec/gensec.h"
    2626#include "auth/gensec/gensec_proto.h"
    27 #include "lib/socket/socket.h"
    2827#include <sasl/sasl.h>
    2928
     
    3130        sasl_conn_t *conn;
    3231        int step;
     32        bool wrap;
    3333};
    3434
     
    119119        const char *service = gensec_get_target_service(gensec_security);
    120120        const char *target_name = gensec_get_target_hostname(gensec_security);
    121         struct socket_address *local_socket_addr = gensec_get_my_addr(gensec_security);
    122         struct socket_address *remote_socket_addr = gensec_get_peer_addr(gensec_security);
     121        const struct tsocket_address *tlocal_addr = gensec_get_local_address(gensec_security);
     122        const struct tsocket_address *tremote_addr = gensec_get_remote_address(gensec_security);
    123123        char *local_addr = NULL;
    124124        char *remote_addr = NULL;
     
    127127        sasl_callback_t *callbacks;
    128128
    129         gensec_sasl_state = talloc(gensec_security, struct gensec_sasl_state);
     129        gensec_sasl_state = talloc_zero(gensec_security, struct gensec_sasl_state);
    130130        if (!gensec_sasl_state) {
    131131                return NT_STATUS_NO_MEMORY;
     
    155155        gensec_security->private_data = gensec_sasl_state;
    156156
    157         if (local_socket_addr) {
    158                 local_addr = talloc_asprintf(gensec_sasl_state, 
    159                                              "%s;%d",
    160                                              local_socket_addr->addr,
    161                                              local_socket_addr->port);
    162         }
    163 
    164         if (remote_socket_addr) {
    165                 remote_addr = talloc_asprintf(gensec_sasl_state, 
    166                                              "%s;%d",
    167                                              remote_socket_addr->addr,
    168                                              remote_socket_addr->port);
     157        if (tlocal_addr) {
     158                local_addr = talloc_asprintf(gensec_sasl_state,
     159                                "%s;%d",
     160                                tsocket_address_inet_addr_string(tlocal_addr, gensec_sasl_state),
     161                                tsocket_address_inet_port(tlocal_addr));
     162        }
     163
     164        if (tremote_addr) {
     165                remote_addr = talloc_asprintf(gensec_sasl_state,
     166                                "%s;%d",
     167                                tsocket_address_inet_addr_string(tremote_addr, gensec_sasl_state),
     168                                tsocket_address_inet_port(tremote_addr));
    169169        }
    170170        gensec_sasl_state->step = 0;
     
    175175                                   &gensec_sasl_state->conn);
    176176       
    177         if (sasl_ret == SASL_OK || sasl_ret == SASL_CONTINUE) {
     177        if (sasl_ret == SASL_OK) {
    178178                sasl_security_properties_t props;
    179179                talloc_set_destructor(gensec_sasl_state, gensec_sasl_dispose);
    180 
     180               
    181181                ZERO_STRUCT(props);
    182182                if (gensec_security->want_features & GENSEC_FEATURE_SIGN) {
    183183                        props.min_ssf = 1;
     184                        props.max_ssf = 1;
     185                        props.maxbufsize = 65536;
     186                        gensec_sasl_state->wrap = true;
    184187                }
    185188                if (gensec_security->want_features & GENSEC_FEATURE_SEAL) {
    186189                        props.min_ssf = 40;
    187                 }
    188                
    189                 props.max_ssf = UINT_MAX;
    190                 props.maxbufsize = 65536;
     190                        props.max_ssf = UINT_MAX;
     191                        props.maxbufsize = 65536;
     192                        gensec_sasl_state->wrap = true;
     193                }
     194
    191195                sasl_ret = sasl_setprop(gensec_sasl_state->conn, SASL_SEC_PROPS, &props);
    192                 if (sasl_ret != SASL_OK) {
    193                         return sasl_nt_status(sasl_ret);
    194                 }
    195 
    196         } else {
     196        }
     197        if (sasl_ret != SASL_OK) {
    197198                DEBUG(1, ("GENSEC SASL: client_new failed: %s\n", sasl_errdetail(gensec_sasl_state->conn)));
    198199        }
     
    263264        const char *out_data;
    264265        unsigned int out_len;
    265 
    266         int sasl_ret = sasl_encode(gensec_sasl_state->conn,
    267                                    (char*)in->data, in->length, &out_data,
    268                                    &out_len);
     266        unsigned len_permitted;
     267        int sasl_ret = sasl_getprop(gensec_sasl_state->conn, SASL_SSF,
     268                        (const void**)&len_permitted);
     269        if (sasl_ret != SASL_OK) {
     270                return sasl_nt_status(sasl_ret);
     271        }
     272        len_permitted = MIN(len_permitted, in->length);
     273
     274        sasl_ret = sasl_encode(gensec_sasl_state->conn,
     275                               (char*)in->data, len_permitted, &out_data,
     276                               &out_len);
    269277        if (sasl_ret == SASL_OK) {
    270278                *out = data_blob_talloc(out_mem_ctx, out_data, out_len);
     
    283291                                                                      struct gensec_sasl_state);
    284292        sasl_ssf_t ssf;
    285         int sasl_ret = sasl_getprop(gensec_sasl_state->conn, SASL_SSF,
     293        int sasl_ret;
     294
     295        /* If we did not elect to wrap, then we have neither sign nor seal, no matter what the SSF claims */
     296        if (!gensec_sasl_state->wrap) {
     297                return false;
     298        }
     299       
     300        sasl_ret = sasl_getprop(gensec_sasl_state->conn, SASL_SSF,
    286301                        (const void**)&ssf);
    287302        if (sasl_ret != SASL_OK) {
  • vendor/current/source4/auth/gensec/gensec.c

    r414 r740  
    2222
    2323#include "includes.h"
    24 #include "auth/auth.h"
     24#include "system/network.h"
    2525#include "lib/events/events.h"
     26#include "lib/socket/socket.h"
     27#include "lib/tsocket/tsocket.h"
     28#include "../lib/util/tevent_ntstatus.h"
    2629#include "librpc/rpc/dcerpc.h"
    2730#include "auth/credentials/credentials.h"
    2831#include "auth/gensec/gensec.h"
    29 #include "auth/gensec/gensec_proto.h"
     32#include "auth/auth.h"
     33#include "auth/system_session_proto.h"
    3034#include "param/param.h"
     35#include "lib/util/tsort.h"
    3136
    3237/* the list of currently registered GENSEC backends */
     
    4348bool gensec_security_ops_enabled(struct gensec_security_ops *ops, struct gensec_security *security)
    4449{
    45         return lp_parm_bool(security->settings->lp_ctx, NULL, "gensec", ops->name, ops->enabled);
     50        return lpcfg_parm_bool(security->settings->lp_ctx, NULL, "gensec", ops->name, ops->enabled);
    4651}
    4752
     
    503508  @param gensec_security Returned GENSEC context pointer.
    504509  @note  The mem_ctx is only a parent and may be NULL.
    505   @note, the auth context is moved to be a child of the
     510  @note, the auth context is moved to be a referenced pointer of the
    506511  @ gensec_security return
    507512*/
     
    517522        }
    518523
    519         (*gensec_security) = talloc(mem_ctx, struct gensec_security);
     524        (*gensec_security) = talloc_zero(mem_ctx, struct gensec_security);
    520525        NT_STATUS_HAVE_NO_MEMORY(*gensec_security);
    521 
    522         (*gensec_security)->ops = NULL;
    523         (*gensec_security)->private_data = NULL;
    524 
    525         ZERO_STRUCT((*gensec_security)->target);
    526         ZERO_STRUCT((*gensec_security)->peer_addr);
    527         ZERO_STRUCT((*gensec_security)->my_addr);
    528 
    529         (*gensec_security)->subcontext = false;
    530         (*gensec_security)->want_features = 0;
    531526
    532527        (*gensec_security)->event_ctx = ev;
    533528        SMB_ASSERT(settings->lp_ctx != NULL);
    534529        (*gensec_security)->settings = talloc_reference(*gensec_security, settings);
    535         (*gensec_security)->auth_context = talloc_steal(*gensec_security, auth_context);
     530
     531        /* We need to reference this, not steal, as the caller may be
     532         * python, which won't like it if we steal it's object away
     533         * from it */
     534        (*gensec_security)->auth_context = talloc_reference(*gensec_security, auth_context);
    536535
    537536        return NT_STATUS_OK;
     
    550549                                 struct gensec_security **gensec_security)
    551550{
    552         (*gensec_security) = talloc(mem_ctx, struct gensec_security);
     551        (*gensec_security) = talloc_zero(mem_ctx, struct gensec_security);
    553552        NT_STATUS_HAVE_NO_MEMORY(*gensec_security);
    554553
     
    593592        return status;
    594593}
     594
     595
    595596
    596597/**
     
    712713        return oid_string;
    713714}
    714        
    715 
    716 /**
    717  * Start a GENSEC sub-mechanism with a specifed mechansim structure, used in SPNEGO
     715
     716/**
     717 * Start a GENSEC sub-mechanism with a specified mechansim structure, used in SPNEGO
    718718 *
    719719 */
     
    982982}
    983983
    984 static void gensec_update_async_timed_handler(struct tevent_context *ev, struct tevent_timer *te,
    985                                               struct timeval t, void *ptr)
    986 {
    987         struct gensec_update_request *req = talloc_get_type(ptr, struct gensec_update_request);
    988         req->status = req->gensec_security->ops->update(req->gensec_security, req, req->in, &req->out);
    989         req->callback.fn(req, req->callback.private_data);
    990 }
    991 
     984struct gensec_update_state {
     985        struct tevent_immediate *im;
     986        struct gensec_security *gensec_security;
     987        DATA_BLOB in;
     988        DATA_BLOB out;
     989};
     990
     991static void gensec_update_async_trigger(struct tevent_context *ctx,
     992                                        struct tevent_immediate *im,
     993                                        void *private_data);
    992994/**
    993995 * Next state function for the GENSEC state machine async version
    994  *
     996 *
     997 * @param mem_ctx The memory context for the request
     998 * @param ev The event context for the request
    995999 * @param gensec_security GENSEC State
    9961000 * @param in The request, as a DATA_BLOB
    997  * @param callback The function that will be called when the operation is
    998  *                 finished, it should return gensec_update_recv() to get output
    999  * @param private_data A private pointer that will be passed to the callback function
    1000  */
    1001 
    1002 _PUBLIC_ void gensec_update_send(struct gensec_security *gensec_security, const DATA_BLOB in,
    1003                                  void (*callback)(struct gensec_update_request *req, void *private_data),
    1004                                  void *private_data)
    1005 {
    1006         struct gensec_update_request *req = NULL;
    1007         struct tevent_timer *te = NULL;
    1008 
    1009         req = talloc(gensec_security, struct gensec_update_request);
    1010         if (!req) goto failed;
    1011         req->gensec_security            = gensec_security;
    1012         req->in                         = in;
    1013         req->out                        = data_blob(NULL, 0);
    1014         req->callback.fn                = callback;
    1015         req->callback.private_data      = private_data;
    1016 
    1017         te = event_add_timed(gensec_security->event_ctx, req,
    1018                              timeval_zero(),
    1019                              gensec_update_async_timed_handler, req);
    1020         if (!te) goto failed;
    1021 
    1022         return;
    1023 
    1024 failed:
    1025         talloc_free(req);
    1026         callback(NULL, private_data);
     1001 *
     1002 * @return The request handle or NULL on no memory failure
     1003 */
     1004
     1005_PUBLIC_ struct tevent_req *gensec_update_send(TALLOC_CTX *mem_ctx,
     1006                                               struct tevent_context *ev,
     1007                                               struct gensec_security *gensec_security,
     1008                                               const DATA_BLOB in)
     1009{
     1010        struct tevent_req *req;
     1011        struct gensec_update_state *state = NULL;
     1012
     1013        req = tevent_req_create(mem_ctx, &state,
     1014                                struct gensec_update_state);
     1015        if (req == NULL) {
     1016                return NULL;
     1017        }
     1018
     1019        state->gensec_security          = gensec_security;
     1020        state->in                       = in;
     1021        state->out                      = data_blob(NULL, 0);
     1022        state->im                       = tevent_create_immediate(state);
     1023        if (tevent_req_nomem(state->im, req)) {
     1024                return tevent_req_post(req, ev);
     1025        }
     1026
     1027        tevent_schedule_immediate(state->im, ev,
     1028                                  gensec_update_async_trigger,
     1029                                  req);
     1030
     1031        return req;
     1032}
     1033
     1034static void gensec_update_async_trigger(struct tevent_context *ctx,
     1035                                        struct tevent_immediate *im,
     1036                                        void *private_data)
     1037{
     1038        struct tevent_req *req =
     1039                talloc_get_type_abort(private_data, struct tevent_req);
     1040        struct gensec_update_state *state =
     1041                tevent_req_data(req, struct gensec_update_state);
     1042        NTSTATUS status;
     1043
     1044        status = gensec_update(state->gensec_security, state,
     1045                               state->in, &state->out);
     1046        if (tevent_req_nterror(req, status)) {
     1047                return;
     1048        }
     1049
     1050        tevent_req_done(req);
    10271051}
    10281052
     
    10301054 * Next state function for the GENSEC state machine
    10311055 *
    1032  * @param req GENSEC update request state
     1056 * @param req request state
    10331057 * @param out_mem_ctx The TALLOC_CTX for *out to be allocated on
    10341058 * @param out The reply, as an talloc()ed DATA_BLOB, on *out_mem_ctx
     
    10361060 *                or NT_STATUS_OK if the user is authenticated.
    10371061 */
    1038 _PUBLIC_ NTSTATUS gensec_update_recv(struct gensec_update_request *req, TALLOC_CTX *out_mem_ctx, DATA_BLOB *out)
    1039 {
     1062_PUBLIC_ NTSTATUS gensec_update_recv(struct tevent_req *req,
     1063                                     TALLOC_CTX *out_mem_ctx,
     1064                                     DATA_BLOB *out)
     1065{
     1066        struct gensec_update_state *state =
     1067                tevent_req_data(req, struct gensec_update_state);
    10401068        NTSTATUS status;
    10411069
    1042         NT_STATUS_HAVE_NO_MEMORY(req);
    1043 
    1044         *out = req->out;
     1070        if (tevent_req_is_nterror(req, &status)) {
     1071                if (!NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
     1072                        tevent_req_received(req);
     1073                        return status;
     1074                }
     1075        } else {
     1076                status = NT_STATUS_OK;
     1077        }
     1078
     1079        *out = state->out;
    10451080        talloc_steal(out_mem_ctx, out->data);
    1046         status = req->status;
    1047 
    1048         talloc_free(req);
     1081
     1082        tevent_req_received(req);
    10491083        return status;
    10501084}
     
    11621196}
    11631197
    1164 /**
    1165  * Set (and talloc_reference) local and peer socket addresses onto a socket context on the GENSEC context
     1198/**
     1199 * Set (and talloc_reference) local and peer socket addresses onto a socket
     1200 * context on the GENSEC context.
    11661201 *
    11671202 * This is so that kerberos can include these addresses in
     
    11691204 */
    11701205
    1171 _PUBLIC_ NTSTATUS gensec_set_my_addr(struct gensec_security *gensec_security, struct socket_address *my_addr)
    1172 {
    1173         gensec_security->my_addr = my_addr;
    1174         if (my_addr && !talloc_reference(gensec_security, my_addr)) {
     1206/**
     1207 * @brief Set the local gensec address.
     1208 *
     1209 * @param  gensec_security   The gensec security context to use.
     1210 *
     1211 * @param  remote       The local address to set.
     1212 *
     1213 * @return              On success NT_STATUS_OK is returned or an NT_STATUS
     1214 *                      error.
     1215 */
     1216_PUBLIC_ NTSTATUS gensec_set_local_address(struct gensec_security *gensec_security,
     1217                const struct tsocket_address *local)
     1218{
     1219        TALLOC_FREE(gensec_security->local_addr);
     1220
     1221        if (local == NULL) {
     1222                return NT_STATUS_OK;
     1223        }
     1224
     1225        gensec_security->local_addr = tsocket_address_copy(local, gensec_security);
     1226        if (gensec_security->local_addr == NULL) {
    11751227                return NT_STATUS_NO_MEMORY;
    11761228        }
     1229
    11771230        return NT_STATUS_OK;
    11781231}
    11791232
    1180 _PUBLIC_ NTSTATUS gensec_set_peer_addr(struct gensec_security *gensec_security, struct socket_address *peer_addr)
    1181 {
    1182         gensec_security->peer_addr = peer_addr;
    1183         if (peer_addr && !talloc_reference(gensec_security, peer_addr)) {
     1233/**
     1234 * @brief Set the remote gensec address.
     1235 *
     1236 * @param  gensec_security   The gensec security context to use.
     1237 *
     1238 * @param  remote       The remote address to set.
     1239 *
     1240 * @return              On success NT_STATUS_OK is returned or an NT_STATUS
     1241 *                      error.
     1242 */
     1243_PUBLIC_ NTSTATUS gensec_set_remote_address(struct gensec_security *gensec_security,
     1244                const struct tsocket_address *remote)
     1245{
     1246        TALLOC_FREE(gensec_security->remote_addr);
     1247
     1248        if (remote == NULL) {
     1249                return NT_STATUS_OK;
     1250        }
     1251
     1252        gensec_security->remote_addr = tsocket_address_copy(remote, gensec_security);
     1253        if (gensec_security->remote_addr == NULL) {
    11841254                return NT_STATUS_NO_MEMORY;
    11851255        }
     1256
    11861257        return NT_STATUS_OK;
    11871258}
    11881259
    1189 struct socket_address *gensec_get_my_addr(struct gensec_security *gensec_security)
    1190 {
    1191         if (gensec_security->my_addr) {
    1192                 return gensec_security->my_addr;
    1193         }
    1194 
    1195         /* We could add a 'set sockaddr' call, and do a lookup.  This
    1196          * would avoid needing to do system calls if nothing asks. */
    1197         return NULL;
    1198 }
    1199 
    1200 _PUBLIC_ struct socket_address *gensec_get_peer_addr(struct gensec_security *gensec_security)
    1201 {
    1202         if (gensec_security->peer_addr) {
    1203                 return gensec_security->peer_addr;
    1204         }
    1205 
    1206         /* We could add a 'set sockaddr' call, and do a lookup.  This
    1207          * would avoid needing to do system calls if nothing asks.
    1208          * However, this is not appropriate for the peer addres on
    1209          * datagram sockets */
    1210         return NULL;
    1211 }
    1212 
    1213 
     1260/**
     1261 * @brief Get the local address from a gensec security context.
     1262 *
     1263 * @param  gensec_security   The security context to get the address from.
     1264 *
     1265 * @return              The address as tsocket_address which could be NULL if
     1266 *                      no address is set.
     1267 */
     1268_PUBLIC_ const struct tsocket_address *gensec_get_local_address(struct gensec_security *gensec_security)
     1269{
     1270        if (gensec_security == NULL) {
     1271                return NULL;
     1272        }
     1273        return gensec_security->local_addr;
     1274}
     1275
     1276/**
     1277 * @brief Get the remote address from a gensec security context.
     1278 *
     1279 * @param  gensec_security   The security context to get the address from.
     1280 *
     1281 * @return              The address as tsocket_address which could be NULL if
     1282 *                      no address is set.
     1283 */
     1284_PUBLIC_ const struct tsocket_address *gensec_get_remote_address(struct gensec_security *gensec_security)
     1285{
     1286        if (gensec_security == NULL) {
     1287                return NULL;
     1288        }
     1289        return gensec_security->remote_addr;
     1290}
    12141291
    12151292/**
     
    12191296 */
    12201297
    1221 NTSTATUS gensec_set_target_principal(struct gensec_security *gensec_security, const char *principal)
     1298_PUBLIC_ NTSTATUS gensec_set_target_principal(struct gensec_security *gensec_security, const char *principal)
    12221299{
    12231300        gensec_security->target.principal = talloc_strdup(gensec_security, principal);
     
    12351312
    12361313        return NULL;
     1314}
     1315
     1316NTSTATUS gensec_generate_session_info(TALLOC_CTX *mem_ctx,
     1317                                      struct gensec_security *gensec_security,
     1318                                      struct auth_user_info_dc *user_info_dc,
     1319                                      struct auth_session_info **session_info)
     1320{
     1321        NTSTATUS nt_status;
     1322        uint32_t flags = AUTH_SESSION_INFO_DEFAULT_GROUPS;
     1323        if (user_info_dc->info->authenticated) {
     1324                flags |= AUTH_SESSION_INFO_AUTHENTICATED;
     1325        }
     1326        if (gensec_security->auth_context) {
     1327                nt_status = gensec_security->auth_context->generate_session_info(mem_ctx, gensec_security->auth_context,
     1328                                                                                 user_info_dc,
     1329                                                                                 flags,
     1330                                                                                 session_info);
     1331        } else {
     1332                flags |= AUTH_SESSION_INFO_SIMPLE_PRIVILEGES;
     1333                nt_status = auth_generate_session_info(mem_ctx,
     1334                                                       NULL,
     1335                                                       NULL,
     1336                                                       user_info_dc, flags,
     1337                                                       session_info);
     1338        }
     1339        return nt_status;
    12371340}
    12381341
     
    12921395int gensec_setting_int(struct gensec_settings *settings, const char *mechanism, const char *name, int default_value)
    12931396{
    1294         return lp_parm_int(settings->lp_ctx, NULL, mechanism, name, default_value);
     1397        return lpcfg_parm_int(settings->lp_ctx, NULL, mechanism, name, default_value);
    12951398}
    12961399
    12971400bool gensec_setting_bool(struct gensec_settings *settings, const char *mechanism, const char *name, bool default_value)
    12981401{
    1299         return lp_parm_bool(settings->lp_ctx, NULL, mechanism, name, default_value);
     1402        return lpcfg_parm_bool(settings->lp_ctx, NULL, mechanism, name, default_value);
    13001403}
    13011404
     
    13061409{
    13071410        static bool initialized = false;
    1308         extern NTSTATUS gensec_sasl_init(void);
    1309         extern NTSTATUS gensec_krb5_init(void);
    1310         extern NTSTATUS gensec_schannel_init(void);
    1311         extern NTSTATUS gensec_spnego_init(void);
    1312         extern NTSTATUS gensec_gssapi_init(void);
    1313         extern NTSTATUS gensec_ntlmssp_init(void);
    1314 
     1411#define _MODULE_PROTO(init) extern NTSTATUS init(void);
     1412        STATIC_gensec_MODULES_PROTO;
    13151413        init_module_fn static_init[] = { STATIC_gensec_MODULES };
    13161414        init_module_fn *shared_init;
     
    13261424        talloc_free(shared_init);
    13271425
    1328         qsort(generic_security_ops, gensec_num_backends, sizeof(*generic_security_ops), QSORT_CAST sort_gensec);
     1426        TYPESAFE_QSORT(generic_security_ops, gensec_num_backends, sort_gensec);
    13291427       
    13301428        return NT_STATUS_OK;
  • vendor/current/source4/auth/gensec/gensec.h

    r414 r740  
    2727#include "libcli/util/ntstatus.h"
    2828
     29#define GENSEC_SASL_NAME_NTLMSSP "NTLM"
     30
    2931#define GENSEC_OID_NTLMSSP "1.3.6.1.4.1.311.2.2.10"
    3032#define GENSEC_OID_SPNEGO "1.3.6.1.5.5.2"
     
    7072struct gensec_settings;
    7173struct tevent_context;
    72 
    73 struct gensec_update_request {
    74         struct gensec_security *gensec_security;
    75         void *private_data;
    76         DATA_BLOB in;
    77         DATA_BLOB out;
    78         NTSTATUS status;
    79         struct {
    80                 void (*fn)(struct gensec_update_request *req, void *private_data);
    81                 void *private_data;
    82         } callback;
    83 };
     74struct tevent_req;
    8475
    8576struct gensec_settings {
    8677        struct loadparm_context *lp_ctx;
    87         struct smb_iconv_convenience *iconv_convenience;
    8878        const char *target_hostname;
    8979};
     
    170160        uint32_t want_features;
    171161        struct tevent_context *event_ctx;
    172         struct socket_address *my_addr, *peer_addr;
     162        struct tsocket_address *local_addr, *remote_addr;
    173163        struct gensec_settings *settings;
    174164       
     
    191181struct socket_context;
    192182struct auth_context;
     183struct auth_user_info_dc;
    193184
    194185NTSTATUS gensec_socket_init(struct gensec_security *gensec_security,
     
    232223NTSTATUS gensec_update(struct gensec_security *gensec_security, TALLOC_CTX *out_mem_ctx,
    233224                       const DATA_BLOB in, DATA_BLOB *out);
    234 void gensec_update_send(struct gensec_security *gensec_security, const DATA_BLOB in,
    235                                  void (*callback)(struct gensec_update_request *req, void *private_data),
    236                                  void *private_data);
    237 NTSTATUS gensec_update_recv(struct gensec_update_request *req, TALLOC_CTX *out_mem_ctx, DATA_BLOB *out);
     225struct tevent_req *gensec_update_send(TALLOC_CTX *mem_ctx,
     226                                      struct tevent_context *ev,
     227                                      struct gensec_security *gensec_security,
     228                                      const DATA_BLOB in);
     229NTSTATUS gensec_update_recv(struct tevent_req *req, TALLOC_CTX *out_mem_ctx, DATA_BLOB *out);
    238230void gensec_want_feature(struct gensec_security *gensec_security,
    239231                         uint32_t feature);
     
    251243const char *gensec_get_name_by_oid(struct gensec_security *gensec_security, const char *oid_string);
    252244struct cli_credentials *gensec_get_credentials(struct gensec_security *gensec_security);
    253 struct socket_address *gensec_get_peer_addr(struct gensec_security *gensec_security);
    254245NTSTATUS gensec_init(struct loadparm_context *lp_ctx);
    255246NTSTATUS gensec_unseal_packet(struct gensec_security *gensec_security,
     
    284275NTSTATUS gensec_session_info(struct gensec_security *gensec_security,
    285276                             struct auth_session_info **session_info);
    286 NTSTATUS auth_nt_status_squash(NTSTATUS nt_status);
     277NTSTATUS nt_status_squash(NTSTATUS nt_status);
    287278struct netlogon_creds_CredentialState;
    288279NTSTATUS dcerpc_schannel_creds(struct gensec_security *gensec_security,
    289280                               TALLOC_CTX *mem_ctx,
    290281                               struct netlogon_creds_CredentialState **creds);
    291 NTSTATUS gensec_set_peer_addr(struct gensec_security *gensec_security, struct socket_address *peer_addr);
    292 NTSTATUS gensec_set_my_addr(struct gensec_security *gensec_security, struct socket_address *my_addr);
     282
     283
     284NTSTATUS gensec_set_local_address(struct gensec_security *gensec_security,
     285                const struct tsocket_address *local);
     286NTSTATUS gensec_set_remote_address(struct gensec_security *gensec_security,
     287                const struct tsocket_address *remote);
     288const struct tsocket_address *gensec_get_local_address(struct gensec_security *gensec_security);
     289const struct tsocket_address *gensec_get_remote_address(struct gensec_security *gensec_security);
    293290
    294291NTSTATUS gensec_start_mech_by_name(struct gensec_security *gensec_security,
     
    316313bool gensec_setting_bool(struct gensec_settings *settings, const char *mechanism, const char *name, bool default_value);
    317314
     315NTSTATUS gensec_set_target_principal(struct gensec_security *gensec_security, const char *principal);
     316
    318317#endif /* __GENSEC_H__ */
  • vendor/current/source4/auth/gensec/gensec.pc.in

    r414 r740  
    77Name: gensec
    88Description: Generic Security Library
    9 Version: 0.0.1
    10 Libs: -L${libdir} -lgensec
     9Version: @PACKAGE_VERSION@
     10Libs: @LIB_RPATH@ -L${libdir} -lgensec
    1111Cflags: -I${includedir}  -DHAVE_IMMEDIATE_STRUCTURES=1
  • vendor/current/source4/auth/gensec/gensec_gssapi.c

    r414 r740  
    2828#include "librpc/gen_ndr/krb5pac.h"
    2929#include "auth/auth.h"
    30 #include "lib/ldb/include/ldb.h"
     30#include <ldb.h>
    3131#include "auth/auth_sam.h"
    3232#include "librpc/rpc/dcerpc.h"
     
    4141#include <gssapi/gssapi_spnego.h>
    4242#include "auth/gensec/gensec_gssapi.h"
     43#include "lib/util/util_net.h"
    4344
    4445static size_t gensec_gssapi_max_input_size(struct gensec_security *gensec_security);
     
    147148        struct gensec_gssapi_state *gensec_gssapi_state;
    148149        krb5_error_code ret;
    149         struct gsskrb5_send_to_kdc send_to_kdc;
    150 
    151         gensec_gssapi_state = talloc(gensec_security, struct gensec_gssapi_state);
     150        const char *realm;
     151
     152        gensec_gssapi_state = talloc_zero(gensec_security, struct gensec_gssapi_state);
    152153        if (!gensec_gssapi_state) {
    153154                return NT_STATUS_NO_MEMORY;
    154155        }
    155        
    156         gensec_gssapi_state->gss_exchange_count = 0;
    157         gensec_gssapi_state->max_wrap_buf_size
    158                 = gensec_setting_int(gensec_security->settings, "gensec_gssapi", "max wrap buf size", 65536);
    159                
    160         gensec_gssapi_state->sasl = false;
    161         gensec_gssapi_state->sasl_state = STAGE_GSS_NEG;
    162156
    163157        gensec_security->private_data = gensec_gssapi_state;
    164158
    165159        gensec_gssapi_state->gssapi_context = GSS_C_NO_CONTEXT;
     160
     161        /* TODO: Fill in channel bindings */
     162        gensec_gssapi_state->input_chan_bindings = GSS_C_NO_CHANNEL_BINDINGS;
     163
    166164        gensec_gssapi_state->server_name = GSS_C_NO_NAME;
    167165        gensec_gssapi_state->client_name = GSS_C_NO_NAME;
    168         gensec_gssapi_state->lucid = NULL;
    169 
    170         /* TODO: Fill in channel bindings */
    171         gensec_gssapi_state->input_chan_bindings = GSS_C_NO_CHANNEL_BINDINGS;
    172166       
    173167        gensec_gssapi_state->want_flags = 0;
     168
    174169        if (gensec_setting_bool(gensec_security->settings, "gensec_gssapi", "delegation_by_kdc_policy", true)) {
    175170                gensec_gssapi_state->want_flags |= GSS_C_DELEG_POLICY_FLAG;
     
    188183        }
    189184
    190         gensec_gssapi_state->got_flags = 0;
    191 
    192         gensec_gssapi_state->session_key = data_blob(NULL, 0);
    193         gensec_gssapi_state->pac = data_blob(NULL, 0);
    194 
    195         gensec_gssapi_state->delegated_cred_handle = GSS_C_NO_CREDENTIAL;
    196         gensec_gssapi_state->sig_size = 0;
    197 
    198         talloc_set_destructor(gensec_gssapi_state, gensec_gssapi_destructor);
    199 
    200185        if (gensec_security->want_features & GENSEC_FEATURE_SIGN) {
    201186                gensec_gssapi_state->want_flags |= GSS_C_INTEG_FLAG;
     
    207192                gensec_gssapi_state->want_flags |= GSS_C_DCE_STYLE;
    208193        }
     194
     195        gensec_gssapi_state->got_flags = 0;
    209196
    210197        switch (gensec_security->ops->auth_type) {
     
    218205        }
    219206
    220         send_to_kdc.func = smb_krb5_send_and_recv_func;
    221         send_to_kdc.ptr = gensec_security->event_ctx;
    222 
    223         ret = gsskrb5_set_send_to_kdc(&send_to_kdc);
    224         if (ret) {
    225                 DEBUG(1,("gensec_krb5_start: gsskrb5_set_send_to_kdc failed\n"));
    226                 talloc_free(gensec_gssapi_state);
    227                 return NT_STATUS_INTERNAL_ERROR;
    228         }
    229         if (lp_realm(gensec_security->settings->lp_ctx) && *lp_realm(gensec_security->settings->lp_ctx)) {
    230                 char *upper_realm = strupper_talloc(gensec_gssapi_state, lp_realm(gensec_security->settings->lp_ctx));
    231                 if (!upper_realm) {
    232                         DEBUG(1,("gensec_krb5_start: could not uppercase realm: %s\n", lp_realm(gensec_security->settings->lp_ctx)));
    233                         talloc_free(gensec_gssapi_state);
    234                         return NT_STATUS_NO_MEMORY;
    235                 }
    236                 ret = gsskrb5_set_default_realm(upper_realm);
    237                 talloc_free(upper_realm);
    238                 if (ret) {
    239                         DEBUG(1,("gensec_krb5_start: gsskrb5_set_default_realm failed\n"));
    240                         talloc_free(gensec_gssapi_state);
    241                         return NT_STATUS_INTERNAL_ERROR;
    242                 }
    243         }
    244 
    245         /* don't do DNS lookups of any kind, it might/will fail for a netbios name */
    246         ret = gsskrb5_set_dns_canonicalize(gensec_setting_bool(gensec_security->settings, "krb5", "set_dns_canonicalize", false));
    247         if (ret) {
    248                 DEBUG(1,("gensec_krb5_start: gsskrb5_set_dns_canonicalize failed\n"));
    249                 talloc_free(gensec_gssapi_state);
    250                 return NT_STATUS_INTERNAL_ERROR;
    251         }
    252 
    253         ret = smb_krb5_init_context(gensec_gssapi_state,
    254                                     gensec_security->event_ctx,
     207        gensec_gssapi_state->session_key = data_blob(NULL, 0);
     208        gensec_gssapi_state->pac = data_blob(NULL, 0);
     209
     210        ret = smb_krb5_init_context(gensec_gssapi_state,
     211                                    NULL,
    255212                                    gensec_security->settings->lp_ctx,
    256213                                    &gensec_gssapi_state->smb_krb5_context);
     
    261218                return NT_STATUS_INTERNAL_ERROR;
    262219        }
     220
     221        gensec_gssapi_state->client_cred = NULL;
     222        gensec_gssapi_state->server_cred = NULL;
     223
     224        gensec_gssapi_state->lucid = NULL;
     225
     226        gensec_gssapi_state->delegated_cred_handle = GSS_C_NO_CREDENTIAL;
     227
     228        gensec_gssapi_state->sasl = false;
     229        gensec_gssapi_state->sasl_state = STAGE_GSS_NEG;
     230        gensec_gssapi_state->sasl_protection = 0;
     231
     232        gensec_gssapi_state->max_wrap_buf_size
     233                = gensec_setting_int(gensec_security->settings, "gensec_gssapi", "max wrap buf size", 65536);
     234        gensec_gssapi_state->gss_exchange_count = 0;
     235        gensec_gssapi_state->sig_size = 0;
     236
     237        talloc_set_destructor(gensec_gssapi_state, gensec_gssapi_destructor);
     238
     239        realm = lpcfg_realm(gensec_security->settings->lp_ctx);
     240        if (realm != NULL) {
     241                ret = gsskrb5_set_default_realm(realm);
     242                if (ret) {
     243                        DEBUG(1,("gensec_krb5_start: gsskrb5_set_default_realm failed\n"));
     244                        talloc_free(gensec_gssapi_state);
     245                        return NT_STATUS_INTERNAL_ERROR;
     246                }
     247        }
     248
     249        /* don't do DNS lookups of any kind, it might/will fail for a netbios name */
     250        ret = gsskrb5_set_dns_canonicalize(gensec_setting_bool(gensec_security->settings, "krb5", "set_dns_canonicalize", false));
     251        if (ret) {
     252                DEBUG(1,("gensec_krb5_start: gsskrb5_set_dns_canonicalize failed\n"));
     253                talloc_free(gensec_gssapi_state);
     254                return NT_STATUS_INTERNAL_ERROR;
     255        }
     256
    263257        return NT_STATUS_OK;
    264258}
     
    286280        } else {
    287281                ret = cli_credentials_get_server_gss_creds(machine_account,
    288                                                            gensec_security->event_ctx,
    289282                                                           gensec_security->settings->lp_ctx, &gcc);
    290283                if (ret) {
     
    323316        OM_uint32 maj_stat, min_stat;
    324317        const char *hostname = gensec_get_target_hostname(gensec_security);
    325         const char *principal;
    326318        struct gssapi_creds_container *gcc;
     319        const char *error_string;
    327320
    328321        if (!hostname) {
     
    346339        gensec_gssapi_state = talloc_get_type(gensec_security->private_data, struct gensec_gssapi_state);
    347340
    348         principal = gensec_get_target_principal(gensec_security);
    349         if (principal && lp_client_use_spnego_principal(gensec_security->settings->lp_ctx)) {
     341        gensec_gssapi_state->target_principal = gensec_get_target_principal(gensec_security);
     342        if (gensec_gssapi_state->target_principal) {
    350343                name_type = GSS_C_NULL_OID;
    351344        } else {
    352                 principal = talloc_asprintf(gensec_gssapi_state, "%s@%s",
     345                gensec_gssapi_state->target_principal = talloc_asprintf(gensec_gssapi_state, "%s/%s@%s",
    353346                                            gensec_get_target_service(gensec_security),
    354                                             hostname);
    355 
    356                 name_type = GSS_C_NT_HOSTBASED_SERVICE;
    357         }               
    358         name_token.value  = discard_const_p(uint8_t, principal);
    359         name_token.length = strlen(principal);
     347                                            hostname, lpcfg_realm(gensec_security->settings->lp_ctx));
     348
     349                name_type = GSS_C_NT_USER_NAME;
     350        }
     351        name_token.value  = discard_const_p(uint8_t, gensec_gssapi_state->target_principal);
     352        name_token.length = strlen(gensec_gssapi_state->target_principal);
    360353
    361354
     
    373366        ret = cli_credentials_get_client_gss_creds(creds,
    374367                                                   gensec_security->event_ctx,
    375                                                    gensec_security->settings->lp_ctx, &gcc);
     368                                                   gensec_security->settings->lp_ctx, &gcc, &error_string);
    376369        switch (ret) {
    377370        case 0:
    378371                break;
    379372        case KRB5KDC_ERR_PREAUTH_FAILED:
     373        case KRB5KDC_ERR_C_PRINCIPAL_UNKNOWN:
     374                DEBUG(1, ("Wrong username or password: %s\n", error_string));
    380375                return NT_STATUS_LOGON_FAILURE;
    381376        case KRB5_KDC_UNREACH:
    382                 DEBUG(3, ("Cannot reach a KDC we require to contact %s\n", principal));
    383                 return NT_STATUS_INVALID_PARAMETER; /* Make SPNEGO ignore us, we can't go any further here */
     377                DEBUG(3, ("Cannot reach a KDC we require to contact %s : %s\n", gensec_gssapi_state->target_principal, error_string));
     378                return NT_STATUS_NO_LOGON_SERVERS;
     379        case KRB5_CC_NOTFOUND:
     380        case KRB5_CC_END:
     381                DEBUG(2, ("Error obtaining ticket we require to contact %s: (possibly due to clock skew between us and the KDC) %s\n", gensec_gssapi_state->target_principal, error_string));
     382                return NT_STATUS_TIME_DIFFERENCE_AT_DC;
    384383        default:
    385                 DEBUG(1, ("Aquiring initiator credentials failed\n"));
     384                DEBUG(1, ("Aquiring initiator credentials failed: %s\n", error_string));
    386385                return NT_STATUS_UNSUCCESSFUL;
    387386        }
     
    460459                case GENSEC_CLIENT:
    461460                {
     461                        struct gsskrb5_send_to_kdc send_to_kdc;
     462                        krb5_error_code ret;
     463                        send_to_kdc.func = smb_krb5_send_and_recv_func;
     464                        send_to_kdc.ptr = gensec_security->event_ctx;
     465
     466                        min_stat = gsskrb5_set_send_to_kdc(&send_to_kdc);
     467                        if (min_stat) {
     468                                DEBUG(1,("gensec_krb5_start: gsskrb5_set_send_to_kdc failed\n"));
     469                                return NT_STATUS_INTERNAL_ERROR;
     470                        }
     471
    462472                        maj_stat = gss_init_sec_context(&min_stat,
    463473                                                        gensec_gssapi_state->client_cred->creds,
     
    476486                                gensec_gssapi_state->gss_oid = gss_oid_p;
    477487                        }
     488
     489                        send_to_kdc.func = smb_krb5_send_and_recv_func;
     490                        send_to_kdc.ptr = NULL;
     491
     492                        ret = gsskrb5_set_send_to_kdc(&send_to_kdc);
     493                        if (ret) {
     494                                DEBUG(1,("gensec_krb5_start: gsskrb5_set_send_to_kdc failed\n"));
     495                                return NT_STATUS_INTERNAL_ERROR;
     496                        }
     497
    478498                        break;
    479499                }
     
    516536                         * is more work to do */
    517537                        if (gensec_gssapi_state->sasl) {
    518                                 /* Due to a very subtle interaction
    519                                  * with SASL and the LDAP libs, we
    520                                  * must ensure the data pointer is
    521                                  * != NULL, but the length is 0. 
    522                                  *
    523                                  * This ensures we send a 'zero
    524                                  * length' (rather than NULL) response
    525                                  */
    526                                
    527                                 if (!out->data) {
    528                                         out->data = (uint8_t *)talloc_strdup(out_mem_ctx, "\0");
    529                                 }
    530 
    531538                                gensec_gssapi_state->sasl_state = STAGE_SASL_SSF_NEG;
    532539                                return NT_STATUS_MORE_PROCESSING_REQUIRED;
     
    535542
    536543                                if (gensec_have_feature(gensec_security, GENSEC_FEATURE_SEAL)) {
    537                                         DEBUG(5, ("GSSAPI Connection will be cryptographicly sealed\n"));
     544                                        DEBUG(5, ("GSSAPI Connection will be cryptographically sealed\n"));
    538545                                } else if (gensec_have_feature(gensec_security, GENSEC_FEATURE_SIGN)) {
    539                                         DEBUG(5, ("GSSAPI Connection will be cryptographicly signed\n"));
     546                                        DEBUG(5, ("GSSAPI Connection will be cryptographically signed\n"));
    540547                                } else {
    541548                                        DEBUG(5, ("GSSAPI Connection will have no cryptographic protection\n"));
     
    551558                } else if (gss_oid_equal(gensec_gssapi_state->gss_oid, gss_mech_krb5)) {
    552559                        switch (min_stat) {
     560                        case KRB5KRB_AP_ERR_TKT_NYV:
     561                                DEBUG(1, ("Error with ticket to contact %s: possible clock skew between us and the KDC or target server: %s\n",
     562                                          gensec_gssapi_state->target_principal,
     563                                          gssapi_error_string(out_mem_ctx, maj_stat, min_stat, gensec_gssapi_state->gss_oid)));
     564                                return NT_STATUS_TIME_DIFFERENCE_AT_DC; /* Make SPNEGO ignore us, we can't go any further here */
     565                        case KRB5KRB_AP_ERR_TKT_EXPIRED:
     566                                DEBUG(1, ("Error with ticket to contact %s: ticket is expired, possible clock skew between us and the KDC or target server: %s\n",
     567                                          gensec_gssapi_state->target_principal,
     568                                          gssapi_error_string(out_mem_ctx, maj_stat, min_stat, gensec_gssapi_state->gss_oid)));
     569                                return NT_STATUS_INVALID_PARAMETER; /* Make SPNEGO ignore us, we can't go any further here */
    553570                        case KRB5_KDC_UNREACH:
    554                                 DEBUG(3, ("Cannot reach a KDC we require: %s\n",
    555                                           gssapi_error_string(gensec_gssapi_state, maj_stat, min_stat, gensec_gssapi_state->gss_oid)));
    556                                 return NT_STATUS_INVALID_PARAMETER; /* Make SPNEGO ignore us, we can't go any further here */
     571                                DEBUG(3, ("Cannot reach a KDC we require in order to obtain a ticetk to %s: %s\n",
     572                                          gensec_gssapi_state->target_principal,
     573                                          gssapi_error_string(out_mem_ctx, maj_stat, min_stat, gensec_gssapi_state->gss_oid)));
     574                                return NT_STATUS_NO_LOGON_SERVERS; /* Make SPNEGO ignore us, we can't go any further here */
    557575                        case KRB5KDC_ERR_S_PRINCIPAL_UNKNOWN:
    558                                 DEBUG(3, ("Server is not registered with our KDC: %s\n",
    559                                           gssapi_error_string(gensec_gssapi_state, maj_stat, min_stat, gensec_gssapi_state->gss_oid)));
     576                                DEBUG(3, ("Server %s is not registered with our KDC: %s\n",
     577                                          gensec_gssapi_state->target_principal,
     578                                          gssapi_error_string(out_mem_ctx, maj_stat, min_stat, gensec_gssapi_state->gss_oid)));
    560579                                return NT_STATUS_INVALID_PARAMETER; /* Make SPNEGO ignore us, we can't go any further here */
    561580                        case KRB5KRB_AP_ERR_MSG_TYPE:
     
    563582                                return NT_STATUS_INVALID_PARAMETER;
    564583                        default:
    565                                 DEBUG(1, ("GSS Update(krb5)(%d) Update failed: %s\n",
     584                                DEBUG(1, ("GSS %s Update(krb5)(%d) Update failed: %s\n",
     585                                          gensec_security->gensec_role == GENSEC_CLIENT ? "client" : "server",
    566586                                          gensec_gssapi_state->gss_exchange_count,
    567587                                          gssapi_error_string(out_mem_ctx, maj_stat, min_stat, gensec_gssapi_state->gss_oid)));
     
    569589                        }
    570590                } else {
    571                         DEBUG(1, ("GSS Update(%d) failed: %s\n",
     591                        DEBUG(1, ("GSS %s Update(%d) failed: %s\n",
     592                                  gensec_security->gensec_role == GENSEC_CLIENT ? "client" : "server",
    572593                                  gensec_gssapi_state->gss_exchange_count,
    573594                                  gssapi_error_string(out_mem_ctx, maj_stat, min_stat, gensec_gssapi_state->gss_oid)));
     
    623644                                                                     gensec_gssapi_state->max_wrap_buf_size);
    624645                        gensec_gssapi_state->sasl_protection = 0;
    625                         if (gensec_have_feature(gensec_security, GENSEC_FEATURE_SEAL)) {
    626                                 if (security_supported & NEG_SEAL) {
     646                        if (security_supported & NEG_SEAL) {
     647                                if (gensec_have_feature(gensec_security, GENSEC_FEATURE_SEAL)) {
    627648                                        gensec_gssapi_state->sasl_protection |= NEG_SEAL;
    628649                                }
    629                         } else if (gensec_have_feature(gensec_security, GENSEC_FEATURE_SIGN)) {
    630                                 if (security_supported & NEG_SIGN) {
     650                        }
     651                        if (security_supported & NEG_SIGN) {
     652                                if (gensec_have_feature(gensec_security, GENSEC_FEATURE_SIGN)) {
    631653                                        gensec_gssapi_state->sasl_protection |= NEG_SIGN;
    632654                                }
    633                         } else if (security_supported & NEG_NONE) {
     655                        }
     656                        if (security_supported & NEG_NONE) {
    634657                                gensec_gssapi_state->sasl_protection |= NEG_NONE;
    635                         } else {
    636                                 DEBUG(1, ("Remote server does not support unprotected connections"));
     658                        }
     659                        if (gensec_gssapi_state->sasl_protection == 0) {
     660                                DEBUG(1, ("Remote server does not support unprotected connections\n"));
    637661                                return NT_STATUS_ACCESS_DENIED;
    638662                        }
     
    667691
    668692                        if (gensec_have_feature(gensec_security, GENSEC_FEATURE_SEAL)) {
    669                                 DEBUG(3, ("SASL/GSSAPI Connection to server will be cryptographicly sealed\n"));
     693                                DEBUG(3, ("SASL/GSSAPI Connection to server will be cryptographically sealed\n"));
    670694                        } else if (gensec_have_feature(gensec_security, GENSEC_FEATURE_SIGN)) {
    671                                 DEBUG(3, ("SASL/GSSAPI Connection to server will be cryptographicly signed\n"));
     695                                DEBUG(3, ("SASL/GSSAPI Connection to server will be cryptographically signed\n"));
    672696                        } else {
    673                                 DEBUG(3, ("SASL/GSSAPI Connection to server will have no cryptographicly protection\n"));
     697                                DEBUG(3, ("SASL/GSSAPI Connection to server will have no cryptographically protection\n"));
    674698                        }
    675699
     
    768792                security_accepted = maxlength_accepted[0];
    769793                maxlength_accepted[0] = '\0';
    770                
     794
    771795                /* Rest is the proposed max wrap length */
    772796                gensec_gssapi_state->max_wrap_buf_size = MIN(RIVAL(maxlength_accepted, 0),
     
    774798
    775799                gensec_gssapi_state->sasl_protection = 0;
    776                 if (gensec_have_feature(gensec_security, GENSEC_FEATURE_SEAL)) {
    777                         if (security_accepted & NEG_SEAL) {
    778                                 gensec_gssapi_state->sasl_protection |= NEG_SEAL;
    779                         }
    780                 } else if (gensec_have_feature(gensec_security, GENSEC_FEATURE_SIGN)) {
    781                         if (security_accepted & NEG_SIGN) {
    782                                 gensec_gssapi_state->sasl_protection |= NEG_SIGN;
    783                         }
    784                 } else if (security_accepted & NEG_NONE) {
     800                if (security_accepted & NEG_SEAL) {
     801                        if (!gensec_have_feature(gensec_security, GENSEC_FEATURE_SEAL)) {
     802                                DEBUG(1, ("Remote client wanted seal, but gensec refused\n"));
     803                                return NT_STATUS_ACCESS_DENIED;
     804                        }
     805                        gensec_gssapi_state->sasl_protection |= NEG_SEAL;
     806                }
     807                if (security_accepted & NEG_SIGN) {
     808                        if (!gensec_have_feature(gensec_security, GENSEC_FEATURE_SIGN)) {
     809                                DEBUG(1, ("Remote client wanted sign, but gensec refused\n"));
     810                                return NT_STATUS_ACCESS_DENIED;
     811                        }
     812                        gensec_gssapi_state->sasl_protection |= NEG_SIGN;
     813                }
     814                if (security_accepted & NEG_NONE) {
    785815                        gensec_gssapi_state->sasl_protection |= NEG_NONE;
    786                 } else {
    787                         DEBUG(1, ("Remote client does not support unprotected connections, but we failed to negotiate anything better"));
    788                         return NT_STATUS_ACCESS_DENIED;
    789816                }
    790817
     
    792819                gensec_gssapi_state->sasl_state = STAGE_DONE;
    793820                if (gensec_have_feature(gensec_security, GENSEC_FEATURE_SEAL)) {
    794                         DEBUG(5, ("SASL/GSSAPI Connection from client will be cryptographicly sealed\n"));
     821                        DEBUG(5, ("SASL/GSSAPI Connection from client will be cryptographically sealed\n"));
    795822                } else if (gensec_have_feature(gensec_security, GENSEC_FEATURE_SIGN)) {
    796                         DEBUG(5, ("SASL/GSSAPI Connection from client will be cryptographicly signed\n"));
     823                        DEBUG(5, ("SASL/GSSAPI Connection from client will be cryptographically signed\n"));
    797824                } else {
    798825                        DEBUG(5, ("SASL/GSSAPI Connection from client will have no cryptographic protection\n"));
     
    12311258        struct gensec_gssapi_state *gensec_gssapi_state
    12321259                = talloc_get_type(gensec_security->private_data, struct gensec_gssapi_state);
    1233         struct auth_serversupplied_info *server_info = NULL;
     1260        struct auth_user_info_dc *user_info_dc = NULL;
    12341261        struct auth_session_info *session_info = NULL;
    12351262        OM_uint32 maj_stat, min_stat;
    12361263        gss_buffer_desc pac;
    12371264        DATA_BLOB pac_blob;
     1265        struct PAC_SIGNATURE_DATA *pac_srv_sig = NULL;
     1266        struct PAC_SIGNATURE_DATA *pac_kdc_sig = NULL;
    12381267       
    12391268        if ((gensec_gssapi_state->gss_oid->length != gss_mech_krb5->length)
     
    12661295         */
    12671296        if (pac_blob.length) {
    1268                 nt_status = kerberos_pac_blob_to_server_info(mem_ctx,
    1269                                                              gensec_security->settings->iconv_convenience,
    1270                                                              pac_blob,
    1271                                                              gensec_gssapi_state->smb_krb5_context->krb5_context,
    1272                                                              &server_info);
     1297                pac_srv_sig = talloc(mem_ctx, struct PAC_SIGNATURE_DATA);
     1298                if (!pac_srv_sig) {
     1299                        talloc_free(mem_ctx);
     1300                        return NT_STATUS_NO_MEMORY;
     1301                }
     1302                pac_kdc_sig = talloc(mem_ctx, struct PAC_SIGNATURE_DATA);
     1303                if (!pac_kdc_sig) {
     1304                        talloc_free(mem_ctx);
     1305                        return NT_STATUS_NO_MEMORY;
     1306                }
     1307
     1308                nt_status = kerberos_pac_blob_to_user_info_dc(mem_ctx,
     1309                                                              pac_blob,
     1310                                                              gensec_gssapi_state->smb_krb5_context->krb5_context,
     1311                                                              &user_info_dc,
     1312                                                              pac_srv_sig,
     1313                                                              pac_kdc_sig);
    12731314                if (!NT_STATUS_IS_OK(nt_status)) {
    12741315                        talloc_free(mem_ctx);
     
    13051346                        DEBUG(1, ("Unable to find PAC, resorting to local user lookup: %s\n",
    13061347                                  gssapi_error_string(mem_ctx, maj_stat, min_stat, gensec_gssapi_state->gss_oid)));
    1307                         nt_status = gensec_security->auth_context->get_server_info_principal(mem_ctx,
     1348                        nt_status = gensec_security->auth_context->get_user_info_dc_principal(mem_ctx,
    13081349                                                                                             gensec_security->auth_context,
    13091350                                                                                             principal_string,
    1310                                                                                              &server_info);
     1351                                                                                             NULL,
     1352                                                                                             &user_info_dc);
    13111353                       
    13121354                        if (!NT_STATUS_IS_OK(nt_status)) {
     
    13221364        }
    13231365
    1324         /* references the server_info into the session_info */
    1325         nt_status = auth_generate_session_info(mem_ctx, gensec_security->event_ctx,
    1326                                                gensec_security->settings->lp_ctx, server_info, &session_info);
     1366        /* references the user_info_dc into the session_info */
     1367        nt_status = gensec_generate_session_info(mem_ctx, gensec_security,
     1368                                                 user_info_dc, &session_info);
    13271369        if (!NT_STATUS_IS_OK(nt_status)) {
    13281370                talloc_free(mem_ctx);
     
    13361378        }
    13371379
     1380        /* Allow torture tests to check the PAC signatures */
     1381        if (session_info->torture) {
     1382                session_info->torture->pac_srv_sig = talloc_steal(session_info->torture, pac_srv_sig);
     1383                session_info->torture->pac_kdc_sig = talloc_steal(session_info->torture, pac_kdc_sig);
     1384        }
     1385
    13381386        if (!(gensec_gssapi_state->got_flags & GSS_C_DELEG_FLAG)) {
    13391387                DEBUG(10, ("gensec_gssapi: NO delegated credentials supplied by client\n"));
    13401388        } else {
    13411389                krb5_error_code ret;
     1390                const char *error_string;
     1391
    13421392                DEBUG(10, ("gensec_gssapi: delegated credentials supplied by client\n"));
    13431393                session_info->credentials = cli_credentials_init(session_info);
     
    13521402               
    13531403                ret = cli_credentials_set_client_gss_creds(session_info->credentials,
    1354                                                            gensec_security->event_ctx,
    1355                                                            gensec_security->settings->lp_ctx,
     1404                                                           gensec_security->settings->lp_ctx,
    13561405                                                           gensec_gssapi_state->delegated_cred_handle,
    1357                                                            CRED_SPECIFIED);
     1406                                                           CRED_SPECIFIED, &error_string);
    13581407                if (ret) {
    13591408                        talloc_free(mem_ctx);
     1409                        DEBUG(2,("Failed to get gss creds: %s\n", error_string));
    13601410                        return NT_STATUS_NO_MEMORY;
    13611411                }
  • vendor/current/source4/auth/gensec/gensec_gssapi.h

    r414 r740  
    6565        int gss_exchange_count;
    6666        size_t sig_size;
     67
     68        const char *target_principal;
    6769};
    6870
  • vendor/current/source4/auth/gensec/gensec_krb5.c

    r414 r740  
    2727#include "system/kerberos.h"
    2828#include "auth/kerberos/kerberos.h"
    29 #include "librpc/gen_ndr/krb5pac.h"
    3029#include "auth/auth.h"
    31 #include "lib/ldb/include/ldb.h"
    32 #include "auth/auth_sam.h"
    3330#include "lib/socket/socket.h"
     31#include "lib/tsocket/tsocket.h"
    3432#include "librpc/rpc/dcerpc.h"
    3533#include "auth/credentials/credentials.h"
    3634#include "auth/credentials/credentials_krb5.h"
     35#include "auth/kerberos/kerberos_credentials.h"
    3736#include "auth/gensec/gensec.h"
    3837#include "auth/gensec/gensec_proto.h"
    3938#include "param/param.h"
    40 #include "auth/session_proto.h"
    4139#include "auth/auth_sam_reply.h"
     40#include "lib/util/util_net.h"
    4241
    4342enum GENSEC_KRB5_STATE {
     
    9594        struct gensec_krb5_state *gensec_krb5_state;
    9695        struct cli_credentials *creds;
    97         const struct socket_address *my_addr, *peer_addr;
     96        const struct tsocket_address *tlocal_addr, *tremote_addr;
    9897        krb5_address my_krb5_addr, peer_krb5_addr;
    9998       
     
    121120
    122121        if (cli_credentials_get_krb5_context(creds,
    123                                              gensec_security->event_ctx,
    124122                                             gensec_security->settings->lp_ctx, &gensec_krb5_state->smb_krb5_context)) {
    125123                talloc_free(gensec_krb5_state);
     
    147145        }
    148146
    149         my_addr = gensec_get_my_addr(gensec_security);
    150         if (my_addr && my_addr->sockaddr) {
    151                 ret = krb5_sockaddr2address(gensec_krb5_state->smb_krb5_context->krb5_context,
    152                                             my_addr->sockaddr, &my_krb5_addr);
     147        tlocal_addr = gensec_get_local_address(gensec_security);
     148        if (tlocal_addr) {
     149                ssize_t socklen;
     150                struct sockaddr_storage ss;
     151
     152                socklen = tsocket_address_bsd_sockaddr(tlocal_addr,
     153                                (struct sockaddr *) &ss,
     154                                sizeof(struct sockaddr_storage));
     155                if (socklen < 0) {
     156                        talloc_free(gensec_krb5_state);
     157                        return NT_STATUS_INTERNAL_ERROR;
     158                }
     159                ret = krb5_sockaddr2address(gensec_krb5_state->smb_krb5_context->krb5_context,
     160                                (const struct sockaddr *) &ss, &my_krb5_addr);
    153161                if (ret) {
    154162                        DEBUG(1,("gensec_krb5_start: krb5_sockaddr2address (local) failed (%s)\n",
     
    160168        }
    161169
    162         peer_addr = gensec_get_peer_addr(gensec_security);
    163         if (peer_addr && peer_addr->sockaddr) {
    164                 ret = krb5_sockaddr2address(gensec_krb5_state->smb_krb5_context->krb5_context,
    165                                             peer_addr->sockaddr, &peer_krb5_addr);
     170        tremote_addr = gensec_get_remote_address(gensec_security);
     171        if (tremote_addr) {
     172                ssize_t socklen;
     173                struct sockaddr_storage ss;
     174
     175                socklen = tsocket_address_bsd_sockaddr(tremote_addr,
     176                                (struct sockaddr *) &ss,
     177                                sizeof(struct sockaddr_storage));
     178                if (socklen < 0) {
     179                        talloc_free(gensec_krb5_state);
     180                        return NT_STATUS_INTERNAL_ERROR;
     181                }
     182                ret = krb5_sockaddr2address(gensec_krb5_state->smb_krb5_context->krb5_context,
     183                                (const struct sockaddr *) &ss, &peer_krb5_addr);
    166184                if (ret) {
    167185                        DEBUG(1,("gensec_krb5_start: krb5_sockaddr2address (local) failed (%s)\n",
     
    175193        ret = krb5_auth_con_setaddrs(gensec_krb5_state->smb_krb5_context->krb5_context,
    176194                                     gensec_krb5_state->auth_context,
    177                                      my_addr ? &my_krb5_addr : NULL,
    178                                      peer_addr ? &peer_krb5_addr : NULL);
     195                                     tlocal_addr ? &my_krb5_addr : NULL,
     196                                     tremote_addr ? &peer_krb5_addr : NULL);
    179197        if (ret) {
    180198                DEBUG(1,("gensec_krb5_start: krb5_auth_con_setaddrs failed (%s)\n",
     
    221239        struct ccache_container *ccache_container;
    222240        const char *hostname;
    223 
     241        const char *error_string;
    224242        const char *principal;
    225243        krb5_data in_data;
     244        struct tevent_context *previous_ev;
    226245
    227246        hostname = gensec_get_target_hostname(gensec_security);
     
    264283        ret = cli_credentials_get_ccache(gensec_get_credentials(gensec_security),
    265284                                         gensec_security->event_ctx,
    266                                          gensec_security->settings->lp_ctx, &ccache_container);
     285                                         gensec_security->settings->lp_ctx, &ccache_container, &error_string);
    267286        switch (ret) {
    268287        case 0:
    269288                break;
    270289        case KRB5KDC_ERR_PREAUTH_FAILED:
     290        case KRB5KDC_ERR_C_PRINCIPAL_UNKNOWN:
    271291                return NT_STATUS_LOGON_FAILURE;
    272292        case KRB5_KDC_UNREACH:
    273                 DEBUG(3, ("Cannot reach a KDC we require to contact %s\n", principal));
     293                DEBUG(3, ("Cannot reach a KDC we require to contact %s: %s\n", principal, error_string));
     294                return NT_STATUS_INVALID_PARAMETER; /* Make SPNEGO ignore us, we can't go any further here */
     295        case KRB5_CC_NOTFOUND:
     296        case KRB5_CC_END:
     297                DEBUG(3, ("Error preparing credentials we require to contact %s : %s\n", principal, error_string));
    274298                return NT_STATUS_INVALID_PARAMETER; /* Make SPNEGO ignore us, we can't go any further here */
    275299        default:
    276                 DEBUG(1, ("gensec_krb5_start: Aquiring initiator credentials failed: %s\n", error_message(ret)));
     300                DEBUG(1, ("gensec_krb5_start: Aquiring initiator credentials failed: %s\n", error_string));
    277301                return NT_STATUS_UNSUCCESSFUL;
    278302        }
    279303        in_data.length = 0;
    280304       
    281         if (principal && lp_client_use_spnego_principal(gensec_security->settings->lp_ctx)) {
     305        /* Do this every time, in case we have weird recursive issues here */
     306        ret = smb_krb5_context_set_event_ctx(gensec_krb5_state->smb_krb5_context, gensec_security->event_ctx, &previous_ev);
     307        if (ret != 0) {
     308                DEBUG(1, ("gensec_krb5_start: Setting event context failed\n"));
     309                return NT_STATUS_NO_MEMORY;
     310        }
     311        if (principal) {
    282312                krb5_principal target_principal;
    283313                ret = krb5_parse_name(gensec_krb5_state->smb_krb5_context->krb5_context, principal,
     
    302332                                  &gensec_krb5_state->enc_ticket);
    303333        }
     334
     335        smb_krb5_context_remove_event_ctx(gensec_krb5_state->smb_krb5_context, previous_ev, gensec_security->event_ctx);
     336
    304337        switch (ret) {
    305338        case 0:
     
    459492                struct keytab_container *keytab;
    460493                krb5_principal server_in_keytab;
     494                const char *error_string;
     495                enum credentials_obtained obtained;
    461496
    462497                if (!in.data) {
     
    466501                /* Grab the keytab, however generated */
    467502                ret = cli_credentials_get_keytab(gensec_get_credentials(gensec_security),
    468                                                  gensec_security->event_ctx,
    469503                                                 gensec_security->settings->lp_ctx, &keytab);
    470504                if (ret) {
     
    475509                ret = principal_from_credentials(out_mem_ctx, gensec_get_credentials(gensec_security),
    476510                                                 gensec_krb5_state->smb_krb5_context,
    477                                                  &server_in_keytab);
     511                                                 &server_in_keytab, &obtained, &error_string);
    478512
    479513                if (ret) {
     514                        DEBUG(2,("Failed to make credentials from principal: %s\n", error_string));
    480515                        return NT_STATUS_CANT_ACCESS_DOMAIN_INFO;
    481516                }
     
    569604        struct gensec_krb5_state *gensec_krb5_state = (struct gensec_krb5_state *)gensec_security->private_data;
    570605        krb5_context context = gensec_krb5_state->smb_krb5_context->krb5_context;
    571         struct auth_serversupplied_info *server_info = NULL;
     606        struct auth_user_info_dc *user_info_dc = NULL;
    572607        struct auth_session_info *session_info = NULL;
    573608        struct PAC_LOGON_INFO *logon_info;
     
    601636                          smb_get_krb5_error_message(context,
    602637                                                     ret, mem_ctx)));
     638                krb5_free_principal(context, client_principal);
    603639                talloc_free(mem_ctx);
    604640                return NT_STATUS_NO_MEMORY;
     
    614650                          smb_get_krb5_error_message(context,
    615651                                                     ret, mem_ctx)));
     652                free(principal_string);
    616653                krb5_free_principal(context, client_principal);
    617                 free(principal_string);
     654                talloc_free(mem_ctx);
    618655                return NT_STATUS_ACCESS_DENIED;
    619656        } else if (ret) {
     
    627664                                  principal_string, smb_get_krb5_error_message(context,
    628665                                                     ret, mem_ctx)));
    629                         nt_status = gensec_security->auth_context->get_server_info_principal(mem_ctx,
     666                        nt_status = gensec_security->auth_context->get_user_info_dc_principal(mem_ctx,
    630667                                                                                             gensec_security->auth_context,
    631668                                                                                             principal_string,
    632                                                                                              &server_info);
     669                                                                                             NULL, &user_info_dc);
    633670                        if (!NT_STATUS_IS_OK(nt_status)) {
     671                                free(principal_string);
     672                                krb5_free_principal(context, client_principal);
    634673                                talloc_free(mem_ctx);
    635674                                return nt_status;
     
    638677                        DEBUG(1, ("Unable to find PAC in ticket from %s, failing to allow access\n",
    639678                                  principal_string));
     679                        free(principal_string);
     680                        krb5_free_principal(context, client_principal);
     681                        talloc_free(mem_ctx);
    640682                        return NT_STATUS_ACCESS_DENIED;
    641                 }
    642 
    643                 krb5_free_principal(context, client_principal);
    644                 free(principal_string);
    645                
    646                 if (!NT_STATUS_IS_OK(nt_status)) {
    647                         talloc_free(mem_ctx);
    648                         return nt_status;
    649683                }
    650684        } else {
    651685                /* Found pac */
    652686                union netr_Validation validation;
    653                 free(principal_string);
    654687
    655688                pac = data_blob_talloc(mem_ctx, pac_data.data, pac_data.length);
    656689                if (!pac.data) {
     690                        free(principal_string);
    657691                        krb5_free_principal(context, client_principal);
    658692                        talloc_free(mem_ctx);
     
    662696                /* decode and verify the pac */
    663697                nt_status = kerberos_pac_logon_info(gensec_krb5_state,
    664                                                     gensec_security->settings->iconv_convenience,
    665698                                                    &logon_info, pac,
    666699                                                    gensec_krb5_state->smb_krb5_context->krb5_context,
     
    668701                                                    client_principal,
    669702                                                    gensec_krb5_state->ticket->ticket.authtime, NULL);
    670                 krb5_free_principal(context, client_principal);
    671703
    672704                if (!NT_STATUS_IS_OK(nt_status)) {
     705                        free(principal_string);
     706                        krb5_free_principal(context, client_principal);
    673707                        talloc_free(mem_ctx);
    674708                        return nt_status;
     
    676710
    677711                validation.sam3 = &logon_info->info3;
    678                 nt_status = make_server_info_netlogon_validation(mem_ctx,
     712                nt_status = make_user_info_dc_netlogon_validation(mem_ctx,
    679713                                                                 NULL,
    680714                                                                 3, &validation,
    681                                                                  &server_info);
     715                                                                 &user_info_dc);
    682716                if (!NT_STATUS_IS_OK(nt_status)) {
     717                        free(principal_string);
     718                        krb5_free_principal(context, client_principal);
    683719                        talloc_free(mem_ctx);
    684720                        return nt_status;
     
    686722        }
    687723
    688         /* references the server_info into the session_info */
    689         nt_status = auth_generate_session_info(mem_ctx, gensec_security->event_ctx, gensec_security->settings->lp_ctx, server_info, &session_info);
     724        free(principal_string);
     725        krb5_free_principal(context, client_principal);
     726
     727        /* references the user_info_dc into the session_info */
     728        nt_status = gensec_generate_session_info(mem_ctx, gensec_security, user_info_dc, &session_info);
    690729
    691730        if (!NT_STATUS_IS_OK(nt_status)) {
  • vendor/current/source4/auth/gensec/pygensec.c

    r414 r740  
    1717*/
    1818
     19#include <Python.h>
    1920#include "includes.h"
    20 #include <Python.h>
    21 #include "param/param.h"
     21#include "param/pyparam.h"
    2222#include "auth/gensec/gensec.h"
     23#include "auth/credentials/pycredentials.h"
    2324#include "libcli/util/pyerrors.h"
    24 #include "pytalloc.h"
     25#include "scripting/python/modules.h"
     26#include "lib/talloc/pytalloc.h"
    2527#include <tevent.h>
    26 
    27 #ifndef Py_RETURN_NONE
    28 #define Py_RETURN_NONE return Py_INCREF(Py_None), Py_None
    29 #endif
     28#include "librpc/rpc/pyrpc_util.h"
    3029
    3130static PyObject *py_get_name_by_authtype(PyObject *self, PyObject *args)
     
    3837                return NULL;
    3938
    40         security = (struct gensec_security *)py_talloc_get_ptr(self);
     39        security = py_talloc_get_type(self, struct gensec_security);
    4140
    4241        name = gensec_get_name_by_authtype(security, type);
     
    4746}
    4847
    49 static struct gensec_settings *settings_from_object(PyObject *object)
    50 {
    51         return NULL; /* FIXME */
     48static struct gensec_settings *settings_from_object(TALLOC_CTX *mem_ctx, PyObject *object)
     49{
     50        struct gensec_settings *s;
     51        PyObject *py_hostname, *py_lp_ctx;
     52
     53        if (!PyDict_Check(object)) {
     54                PyErr_SetString(PyExc_ValueError, "settings should be a dictionary");
     55                return NULL;
     56        }
     57
     58        s = talloc_zero(mem_ctx, struct gensec_settings);
     59        if (!s) return NULL;
     60
     61        py_hostname = PyDict_GetItemString(object, "target_hostname");
     62        if (!py_hostname) {
     63                PyErr_SetString(PyExc_ValueError, "settings.target_hostname not found");
     64                return NULL;
     65        }
     66
     67        py_lp_ctx = PyDict_GetItemString(object, "lp_ctx");
     68        if (!py_lp_ctx) {
     69                PyErr_SetString(PyExc_ValueError, "settings.lp_ctx not found");
     70                return NULL;
     71        }
     72
     73        s->target_hostname = PyString_AsString(py_hostname);
     74        s->lp_ctx = lpcfg_from_py_object(s, py_lp_ctx);
     75        return s;
    5276}
    5377
     
    6084        PyObject *py_settings;
    6185        struct tevent_context *ev;
    62 
    63         if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O", kwnames, &py_settings))
    64                 return NULL;
    65 
    66         settings = settings_from_object(py_settings);
    67         if (settings == NULL)
    68                 return NULL;
    69        
     86        struct gensec_security *gensec;
     87
     88        if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|O", discard_const_p(char *, kwnames), &py_settings))
     89                return NULL;
     90
    7091        self = (py_talloc_Object*)type->tp_alloc(type, 0);
    7192        if (self == NULL) {
     
    7899                return NULL;
    79100        }
     101
     102        if (py_settings != Py_None) {
     103                settings = settings_from_object(self->talloc_ctx, py_settings);
     104                if (settings == NULL) {
     105                        PyObject_DEL(self);
     106                        return NULL;
     107                }
     108        } else {
     109                settings = talloc_zero(self->talloc_ctx, struct gensec_settings);
     110                if (settings == NULL) {
     111                        PyObject_DEL(self);
     112                        return NULL;
     113                }
     114
     115                settings->lp_ctx = loadparm_init_global(true);
     116        }
     117
    80118        ev = tevent_context_init(self->talloc_ctx);
    81119        if (ev == NULL) {
     
    84122                return NULL;
    85123        }
    86         status = gensec_client_start(self->talloc_ctx,
    87                 (struct gensec_security **)&self->ptr, ev, settings);
     124
     125        status = gensec_init(settings->lp_ctx);
    88126        if (!NT_STATUS_IS_OK(status)) {
    89127                PyErr_SetNTSTATUS(status);
     
    91129                return NULL;
    92130        }
     131
     132        status = gensec_client_start(self->talloc_ctx, &gensec, ev, settings);
     133        if (!NT_STATUS_IS_OK(status)) {
     134                PyErr_SetNTSTATUS(status);
     135                PyObject_DEL(self);
     136                return NULL;
     137        }
     138
     139        self->ptr = gensec;
     140
    93141        return (PyObject *)self;
    94142}
    95143
     144static PyObject *py_gensec_start_server(PyTypeObject *type, PyObject *args, PyObject *kwargs)
     145{
     146        NTSTATUS status;
     147        py_talloc_Object *self;
     148        struct gensec_settings *settings = NULL;
     149        const char *kwnames[] = { "settings", "auth_context", NULL };
     150        PyObject *py_settings = Py_None;
     151        PyObject *py_auth_context = Py_None;
     152        struct tevent_context *ev;
     153        struct gensec_security *gensec;
     154        struct auth_context *auth_context = NULL;
     155
     156        if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|OO", discard_const_p(char *, kwnames), &py_settings, &py_auth_context))
     157                return NULL;
     158
     159        self = (py_talloc_Object*)type->tp_alloc(type, 0);
     160        if (self == NULL) {
     161                PyErr_NoMemory();
     162                return NULL;
     163        }
     164        self->talloc_ctx = talloc_new(NULL);
     165        if (self->talloc_ctx == NULL) {
     166                PyErr_NoMemory();
     167                return NULL;
     168        }
     169
     170        if (py_settings != Py_None) {
     171                settings = settings_from_object(self->talloc_ctx, py_settings);
     172                if (settings == NULL) {
     173                        PyObject_DEL(self);
     174                        return NULL;
     175                }
     176        } else {
     177                settings = talloc_zero(self->talloc_ctx, struct gensec_settings);
     178                if (settings == NULL) {
     179                        PyObject_DEL(self);
     180                        return NULL;
     181                }
     182
     183                settings->lp_ctx = loadparm_init_global(true);
     184        }
     185
     186        ev = tevent_context_init(self->talloc_ctx);
     187        if (ev == NULL) {
     188                PyErr_NoMemory();
     189                PyObject_Del(self);
     190                return NULL;
     191        }
     192
     193        if (py_auth_context != Py_None) {
     194                auth_context = py_talloc_get_type(py_auth_context, struct auth_context);
     195                if (!auth_context) {
     196                        PyErr_Format(PyExc_TypeError,
     197                                     "Expected auth.AuthContext for auth_context argument, got %s",
     198                                     talloc_get_name(py_talloc_get_ptr(py_auth_context)));
     199                        return NULL;
     200                }
     201        }
     202
     203        status = gensec_init(settings->lp_ctx);
     204        if (!NT_STATUS_IS_OK(status)) {
     205                PyErr_SetNTSTATUS(status);
     206                PyObject_DEL(self);
     207                return NULL;
     208        }
     209
     210        status = gensec_server_start(self->talloc_ctx, ev, settings, auth_context, &gensec);
     211        if (!NT_STATUS_IS_OK(status)) {
     212                PyErr_SetNTSTATUS(status);
     213                PyObject_DEL(self);
     214                return NULL;
     215        }
     216
     217        self->ptr = gensec;
     218
     219        return (PyObject *)self;
     220}
     221
     222static PyObject *py_gensec_set_credentials(PyObject *self, PyObject *args)
     223{
     224        PyObject *py_creds = Py_None;
     225        struct cli_credentials *creds;
     226        struct gensec_security *security = py_talloc_get_type(self, struct gensec_security);
     227        NTSTATUS status;
     228
     229        if (!PyArg_ParseTuple(args, "O", &py_creds))
     230                return NULL;
     231
     232        creds = PyCredentials_AsCliCredentials(py_creds);
     233        if (!creds) {
     234                PyErr_Format(PyExc_TypeError,
     235                             "Expected samba.credentaials for credentials argument got  %s",
     236                             talloc_get_name(py_talloc_get_ptr(py_creds)));
     237        }
     238
     239        status = gensec_set_credentials(security, creds);
     240        if (!NT_STATUS_IS_OK(status)) {
     241                PyErr_SetNTSTATUS(status);
     242                return NULL;
     243        }
     244
     245        Py_RETURN_NONE;
     246}
     247
    96248static PyObject *py_gensec_session_info(PyObject *self)
    97249{
    98250        NTSTATUS status;
    99         struct gensec_security *security = (struct gensec_security *)py_talloc_get_ptr(self);
     251        PyObject *py_session_info;
     252        struct gensec_security *security = py_talloc_get_type(self, struct gensec_security);
    100253        struct auth_session_info *info;
     254        if (security->ops == NULL) {
     255                PyErr_SetString(PyExc_RuntimeError, "no mechanism selected");
     256                return NULL;
     257        }
    101258        status = gensec_session_info(security, &info);
    102259        if (NT_STATUS_IS_ERR(status)) {
     
    105262        }
    106263
    107         /* FIXME */
     264        py_session_info = py_return_ndr_struct("samba.auth", "AuthSession",
     265                                                 info, info);
     266        return py_session_info;
     267}
     268
     269static PyObject *py_gensec_start_mech_by_name(PyObject *self, PyObject *args)
     270{
     271        char *name;
     272        struct gensec_security *security = py_talloc_get_type(self, struct gensec_security);
     273        NTSTATUS status;
     274
     275        if (!PyArg_ParseTuple(args, "s", &name))
     276                return NULL;
     277
     278        status = gensec_start_mech_by_name(security, name);
     279        if (!NT_STATUS_IS_OK(status)) {
     280                PyErr_SetNTSTATUS(status);
     281                return NULL;
     282        }
     283
    108284        Py_RETURN_NONE;
     285}
     286
     287static PyObject *py_gensec_start_mech_by_sasl_name(PyObject *self, PyObject *args)
     288{
     289        char *sasl_name;
     290        struct gensec_security *security = py_talloc_get_type(self, struct gensec_security);
     291        NTSTATUS status;
     292
     293        if (!PyArg_ParseTuple(args, "s", &sasl_name))
     294                return NULL;
     295
     296        status = gensec_start_mech_by_sasl_name(security, sasl_name);
     297        if (!NT_STATUS_IS_OK(status)) {
     298                PyErr_SetNTSTATUS(status);
     299                return NULL;
     300        }
     301
     302        Py_RETURN_NONE;
     303}
     304
     305static PyObject *py_gensec_start_mech_by_authtype(PyObject *self, PyObject *args)
     306{
     307        int authtype, level;
     308        struct gensec_security *security = py_talloc_get_type(self, struct gensec_security);
     309        NTSTATUS status;
     310        if (!PyArg_ParseTuple(args, "ii", &authtype, &level))
     311                return NULL;
     312
     313        status = gensec_start_mech_by_authtype(security, authtype, level);
     314        if (!NT_STATUS_IS_OK(status)) {
     315                PyErr_SetNTSTATUS(status);
     316                return NULL;
     317        }
     318
     319        Py_RETURN_NONE;
     320}
     321
     322static PyObject *py_gensec_want_feature(PyObject *self, PyObject *args)
     323{
     324        int feature;
     325        struct gensec_security *security = py_talloc_get_type(self, struct gensec_security);
     326        /* This is i (and declared as an int above) by design, as they are handled as an integer in python */
     327        if (!PyArg_ParseTuple(args, "i", &feature))
     328                return NULL;
     329
     330        gensec_want_feature(security, feature);
     331
     332        Py_RETURN_NONE;
     333}
     334
     335static PyObject *py_gensec_have_feature(PyObject *self, PyObject *args)
     336{
     337        int feature;
     338        struct gensec_security *security = py_talloc_get_type(self, struct gensec_security);
     339        /* This is i (and declared as an int above) by design, as they are handled as an integer in python */
     340        if (!PyArg_ParseTuple(args, "i", &feature))
     341                return NULL;
     342
     343        if (gensec_have_feature(security, feature)) {
     344                return Py_True;
     345        }
     346        return Py_False;
     347}
     348
     349static PyObject *py_gensec_update(PyObject *self, PyObject *args)
     350{
     351        NTSTATUS status;
     352        TALLOC_CTX *mem_ctx;
     353        DATA_BLOB in, out;
     354        PyObject *ret, *py_in;
     355        struct gensec_security *security = py_talloc_get_type(self, struct gensec_security);
     356        PyObject *finished_processing;
     357
     358        if (!PyArg_ParseTuple(args, "O", &py_in))
     359                return NULL;
     360
     361        mem_ctx = talloc_new(NULL);
     362
     363        if (!PyString_Check(py_in)) {
     364                PyErr_Format(PyExc_TypeError, "expected a string");
     365                return NULL;
     366        }
     367
     368        in.data = (uint8_t *)PyString_AsString(py_in);
     369        in.length = PyString_Size(py_in);
     370
     371        status = gensec_update(security, mem_ctx, in, &out);
     372
     373        if (!NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)
     374            && !NT_STATUS_IS_OK(status)) {
     375                PyErr_SetNTSTATUS(status);
     376                talloc_free(mem_ctx);
     377                return NULL;
     378        }
     379        ret = PyString_FromStringAndSize((const char *)out.data, out.length);
     380        talloc_free(mem_ctx);
     381
     382        if (NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
     383                finished_processing = Py_False;
     384        } else {
     385                finished_processing = Py_True;
     386        }
     387
     388        return PyTuple_Pack(2, finished_processing, ret);
     389}
     390
     391static PyObject *py_gensec_wrap(PyObject *self, PyObject *args)
     392{
     393        NTSTATUS status;
     394
     395        TALLOC_CTX *mem_ctx;
     396        DATA_BLOB in, out;
     397        PyObject *ret, *py_in;
     398        struct gensec_security *security = py_talloc_get_type(self, struct gensec_security);
     399
     400        if (!PyArg_ParseTuple(args, "O", &py_in))
     401                return NULL;
     402
     403        mem_ctx = talloc_new(NULL);
     404
     405        if (!PyString_Check(py_in)) {
     406                PyErr_Format(PyExc_TypeError, "expected a string");
     407                return NULL;
     408        }
     409        in.data = (uint8_t *)PyString_AsString(py_in);
     410        in.length = PyString_Size(py_in);
     411
     412        status = gensec_wrap(security, mem_ctx, &in, &out);
     413
     414        if (!NT_STATUS_IS_OK(status)) {
     415                PyErr_SetNTSTATUS(status);
     416                talloc_free(mem_ctx);
     417                return NULL;
     418        }
     419
     420        ret = PyString_FromStringAndSize((const char *)out.data, out.length);
     421        talloc_free(mem_ctx);
     422        return ret;
     423}
     424
     425static PyObject *py_gensec_unwrap(PyObject *self, PyObject *args)
     426{
     427        NTSTATUS status;
     428
     429        TALLOC_CTX *mem_ctx;
     430        DATA_BLOB in, out;
     431        PyObject *ret, *py_in;
     432        struct gensec_security *security = py_talloc_get_type(self, struct gensec_security);
     433
     434        if (!PyArg_ParseTuple(args, "O", &py_in))
     435                return NULL;
     436
     437        mem_ctx = talloc_new(NULL);
     438
     439        if (!PyString_Check(py_in)) {
     440                PyErr_Format(PyExc_TypeError, "expected a string");
     441                return NULL;
     442        }
     443
     444        in.data = (uint8_t *)PyString_AsString(py_in);
     445        in.length = PyString_Size(py_in);
     446
     447        status = gensec_unwrap(security, mem_ctx, &in, &out);
     448
     449        if (!NT_STATUS_IS_OK(status)) {
     450                PyErr_SetNTSTATUS(status);
     451                talloc_free(mem_ctx);
     452                return NULL;
     453        }
     454
     455        ret = PyString_FromStringAndSize((const char *)out.data, out.length);
     456        talloc_free(mem_ctx);
     457        return ret;
    109458}
    110459
     
    112461        { "start_client", (PyCFunction)py_gensec_start_client, METH_VARARGS|METH_KEYWORDS|METH_CLASS,
    113462                "S.start_client(settings) -> gensec" },
    114 /*      { "start_server", (PyCFunction)py_gensec_start_server, METH_VARARGS|METH_KEYWORDS|METH_CLASS,
    115                 "S.start_server(auth_ctx, settings) -> gensec" },*/
     463        { "start_server", (PyCFunction)py_gensec_start_server, METH_VARARGS|METH_KEYWORDS|METH_CLASS,
     464                "S.start_server(auth_ctx, settings) -> gensec" },
     465        { "set_credentials", (PyCFunction)py_gensec_set_credentials, METH_VARARGS,
     466                "S.start_client(credentials)" },
    116467        { "session_info", (PyCFunction)py_gensec_session_info, METH_NOARGS,
    117                 "S.session_info() -> info" },
     468                "S.session_info() -> info" },
     469        { "start_mech_by_name", (PyCFunction)py_gensec_start_mech_by_name, METH_VARARGS,
     470        "S.start_mech_by_name(name)" },
     471        { "start_mech_by_sasl_name", (PyCFunction)py_gensec_start_mech_by_sasl_name, METH_VARARGS,
     472        "S.start_mech_by_sasl_name(name)" },
     473        { "start_mech_by_authtype", (PyCFunction)py_gensec_start_mech_by_authtype, METH_VARARGS, "S.start_mech_by_authtype(authtype, level)" },
    118474        { "get_name_by_authtype", (PyCFunction)py_get_name_by_authtype, METH_VARARGS,
    119475                "S.get_name_by_authtype(authtype) -> name\nLookup an auth type." },
     476        { "want_feature", (PyCFunction)py_gensec_want_feature, METH_VARARGS,
     477          "S.want_feature(feature)\n Request that GENSEC negotiate a particular feature." },
     478        { "have_feature", (PyCFunction)py_gensec_have_feature, METH_VARARGS,
     479          "S.have_feature()\n Return True if GENSEC negotiated a particular feature." },
     480        { "update",  (PyCFunction)py_gensec_update, METH_VARARGS,
     481                "S.update(blob_in) -> (finished, blob_out)\nPerform one step in a GENSEC dance.  Repeat with new packets until finished is true or exception." },
     482        { "wrap",  (PyCFunction)py_gensec_wrap, METH_VARARGS,
     483                "S.wrap(blob_in) -> blob_out\nPackage one clear packet into a wrapped GENSEC packet." },
     484        { "unwrap",  (PyCFunction)py_gensec_unwrap, METH_VARARGS,
     485                "S.unwrap(blob_in) -> blob_out\nPerform one wrapped GENSEC packet into a clear packet." },
     486
    120487        { NULL }
    121488};
     
    126493        .tp_methods = py_gensec_security_methods,
    127494        .tp_basicsize = sizeof(py_talloc_Object),
    128         .tp_dealloc = py_talloc_dealloc,
    129495};
    130496
     497void initgensec(void);
    131498void initgensec(void)
    132499{
    133500        PyObject *m;
     501
     502        Py_Security.tp_base = PyTalloc_GetObjectType();
     503        if (Py_Security.tp_base == NULL)
     504                return;
    134505
    135506        if (PyType_Ready(&Py_Security) < 0)
     
    140511                return;
    141512
     513        PyModule_AddObject(m, "FEATURE_SESSION_KEY",     PyInt_FromLong(GENSEC_FEATURE_SESSION_KEY));
     514        PyModule_AddObject(m, "FEATURE_SIGN",            PyInt_FromLong(GENSEC_FEATURE_SIGN));
     515        PyModule_AddObject(m, "FEATURE_SEAL",            PyInt_FromLong(GENSEC_FEATURE_SEAL));
     516        PyModule_AddObject(m, "FEATURE_DCE_STYLE",       PyInt_FromLong(GENSEC_FEATURE_DCE_STYLE));
     517        PyModule_AddObject(m, "FEATURE_ASYNC_REPLIES",   PyInt_FromLong(GENSEC_FEATURE_ASYNC_REPLIES));
     518        PyModule_AddObject(m, "FEATURE_DATAGRAM_MODE",   PyInt_FromLong(GENSEC_FEATURE_DATAGRAM_MODE));
     519        PyModule_AddObject(m, "FEATURE_SIGN_PKT_HEADER", PyInt_FromLong(GENSEC_FEATURE_SIGN_PKT_HEADER));
     520        PyModule_AddObject(m, "FEATURE_NEW_SPNEGO",      PyInt_FromLong(GENSEC_FEATURE_NEW_SPNEGO));
     521
    142522        Py_INCREF(&Py_Security);
    143523        PyModule_AddObject(m, "Security", (PyObject *)&Py_Security);
  • vendor/current/source4/auth/gensec/schannel.c

    r414 r740  
    2828#include "auth/gensec/gensec_proto.h"
    2929#include "../libcli/auth/schannel.h"
    30 #include "auth/gensec/schannel_state.h"
    3130#include "librpc/rpc/dcerpc.h"
    3231#include "param/param.h"
    33 #include "auth/session_proto.h"
    3432
    3533static size_t schannel_sig_size(struct gensec_security *gensec_security, size_t data_size)
    3634{
    37         return 32;
     35        struct schannel_state *state = (struct schannel_state *)gensec_security->private_data;
     36        uint32_t sig_size;
     37
     38        sig_size = netsec_outgoing_sig_size(state);
     39
     40        return sig_size;
    3841}
    3942
     
    5356        struct NL_AUTH_MESSAGE bind_schannel_ack;
    5457        struct netlogon_creds_CredentialState *creds;
    55         struct ldb_context *schannel_ldb;
    5658        const char *workstation;
    5759        const char *domain;
    58         uint32_t required_flags;
    5960
    6061        *out = data_blob(NULL, 0);
     
    9192#endif
    9293
    93                 ndr_err = ndr_push_struct_blob(out, out_mem_ctx,
    94                                                gensec_security->settings->iconv_convenience, &bind_schannel,
     94                ndr_err = ndr_push_struct_blob(out, out_mem_ctx, &bind_schannel,
    9595                                               (ndr_push_flags_fn_t)ndr_push_NL_AUTH_MESSAGE);
    9696                if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
     
    106106        case GENSEC_SERVER:
    107107
    108                 required_flags = NL_FLAG_OEM_NETBIOS_COMPUTER_NAME |
    109                                  NL_FLAG_OEM_NETBIOS_DOMAIN_NAME;
    110 
    111108                if (state->state != SCHANNEL_STATE_START) {
    112109                        /* no third leg on this protocol */
     
    115112
    116113                /* parse the schannel startup blob */
    117                 ndr_err = ndr_pull_struct_blob(&in, out_mem_ctx,
    118                         gensec_security->settings->iconv_convenience,
    119                         &bind_schannel,
     114                ndr_err = ndr_pull_struct_blob(&in, out_mem_ctx, &bind_schannel,
    120115                        (ndr_pull_flags_fn_t)ndr_pull_NL_AUTH_MESSAGE);
    121116                if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
     
    126121                }
    127122
    128                 if (!(required_flags == (bind_schannel.Flags & required_flags))) {
    129                         return NT_STATUS_INVALID_PARAMETER;
    130                 }
    131 
    132                 workstation = bind_schannel.oem_netbios_computer.a;
    133                 domain = bind_schannel.oem_netbios_domain.a;
    134 
    135                 if (strcasecmp_m(domain, lp_workgroup(gensec_security->settings->lp_ctx)) != 0) {
    136                         DEBUG(3, ("Request for schannel to incorrect domain: %s != our domain %s\n",
    137                                   domain, lp_workgroup(gensec_security->settings->lp_ctx)));
    138 
     123                if (bind_schannel.Flags & NL_FLAG_OEM_NETBIOS_DOMAIN_NAME) {
     124                        domain = bind_schannel.oem_netbios_domain.a;
     125                        if (strcasecmp_m(domain, lpcfg_workgroup(gensec_security->settings->lp_ctx)) != 0) {
     126                                DEBUG(3, ("Request for schannel to incorrect domain: %s != our domain %s\n",
     127                                          domain, lpcfg_workgroup(gensec_security->settings->lp_ctx)));
     128                                return NT_STATUS_LOGON_FAILURE;
     129                        }
     130                } else if (bind_schannel.Flags & NL_FLAG_UTF8_DNS_DOMAIN_NAME) {
     131                        domain = bind_schannel.utf8_dns_domain.u;
     132                        if (strcasecmp_m(domain, lpcfg_dnsdomain(gensec_security->settings->lp_ctx)) != 0) {
     133                                DEBUG(3, ("Request for schannel to incorrect domain: %s != our domain %s\n",
     134                                          domain, lpcfg_dnsdomain(gensec_security->settings->lp_ctx)));
     135                                return NT_STATUS_LOGON_FAILURE;
     136                        }
     137                } else {
     138                        DEBUG(3, ("Request for schannel to without domain\n"));
    139139                        return NT_STATUS_LOGON_FAILURE;
    140140                }
    141141
    142                 schannel_ldb = schannel_db_connect(out_mem_ctx, gensec_security->event_ctx,
    143                                                    gensec_security->settings->lp_ctx);
    144                 if (!schannel_ldb) {
    145                         return NT_STATUS_ACCESS_DENIED;
    146                 }
    147                 /* pull the session key for this client */
    148                 status = schannel_fetch_session_key_ldb(schannel_ldb,
    149                                                         out_mem_ctx, workstation, &creds);
    150                 talloc_free(schannel_ldb);
     142                if (bind_schannel.Flags & NL_FLAG_OEM_NETBIOS_COMPUTER_NAME) {
     143                        workstation = bind_schannel.oem_netbios_computer.a;
     144                } else if (bind_schannel.Flags & NL_FLAG_UTF8_NETBIOS_COMPUTER_NAME) {
     145                        workstation = bind_schannel.utf8_netbios_computer.u;
     146                } else {
     147                        DEBUG(3, ("Request for schannel to without netbios workstation\n"));
     148                        return NT_STATUS_LOGON_FAILURE;
     149                }
     150
     151                status = schannel_get_creds_state(out_mem_ctx,
     152                                                  lpcfg_private_dir(gensec_security->settings->lp_ctx),
     153                                                  workstation, &creds);
    151154                if (!NT_STATUS_IS_OK(status)) {
    152155                        DEBUG(3, ("Could not find session key for attempted schannel connection from %s: %s\n",
     
    158161                }
    159162
    160                 state->creds = talloc_reference(state, creds);
     163                state->creds = talloc_steal(state, creds);
    161164
    162165                bind_schannel_ack.MessageType = NL_NEGOTIATE_RESPONSE;
     
    167170                                                            * - gd */
    168171
    169                 ndr_err = ndr_push_struct_blob(out, out_mem_ctx,
    170                                                gensec_security->settings->iconv_convenience, &bind_schannel_ack,
     172                ndr_err = ndr_push_struct_blob(out, out_mem_ctx, &bind_schannel_ack,
    171173                                               (ndr_push_flags_fn_t)ndr_push_NL_AUTH_MESSAGE);
    172174                if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
     
    215217{
    216218        struct schannel_state *state = talloc_get_type(gensec_security->private_data, struct schannel_state);
    217         return auth_anonymous_session_info(state, gensec_security->event_ctx, gensec_security->settings->lp_ctx, _session_info);
     219        return auth_anonymous_session_info(state, gensec_security->settings->lp_ctx, _session_info);
    218220}
    219221
  • vendor/current/source4/auth/gensec/socket.c

    r414 r740  
    7878                                        &unwrapped, &wrapped);
    7979                if (!NT_STATUS_IS_OK(nt_status)) {
    80                         talloc_free(mem_ctx);
    8180                        return nt_status;
    8281                }
  • vendor/current/source4/auth/gensec/spnego.c

    r414 r740  
    2929#include "auth/gensec/gensec.h"
    3030#include "auth/gensec/gensec_proto.h"
     31#include "param/param.h"
    3132
    3233enum spnego_state_position {
     
    420421
    421422        if (spnego_state->state_position == SPNEGO_SERVER_START) {
    422                 for (i=0; all_sec && all_sec[i].op; i++) {
    423                         /* optomisitic token */
    424                         if (strcmp(all_sec[i].oid, mechType[0]) == 0) {
     423                uint32_t j;
     424                for (j=0; mechType && mechType[j]; j++) {
     425                        for (i=0; all_sec && all_sec[i].op; i++) {
    425426                                nt_status = gensec_subcontext_start(spnego_state,
    426427                                                                    gensec_security,
     
    437438                                        break;
    438439                                }
    439                                
     440
     441                                if (j > 0) {
     442                                        /* no optimistic token */
     443                                        spnego_state->neg_oid = all_sec[i].oid;
     444                                        *unwrapped_out = data_blob_null;
     445                                        nt_status = NT_STATUS_MORE_PROCESSING_REQUIRED;
     446                                        break;
     447                                }
     448
    440449                                nt_status = gensec_update(spnego_state->sub_sec_security,
    441450                                                          out_mem_ctx,
     
    456465                                break;
    457466                        }
    458                 }
    459         }
    460        
    461         /* Having tried any optomisitc token from the client (if we
     467                        if (spnego_state->sub_sec_security) {
     468                                break;
     469                        }
     470                }
     471
     472                if (!spnego_state->sub_sec_security) {
     473                        DEBUG(1, ("SPNEGO: Could not find a suitable mechtype in NEG_TOKEN_INIT\n"));
     474                        return NT_STATUS_INVALID_PARAMETER;
     475                }
     476        }
     477       
     478        /* Having tried any optimistic token from the client (if we
    462479         * were the server), if we didn't get anywhere, walk our list
    463480         * in our preference order */
     
    495512                        if (spnego_state->state_position != SPNEGO_SERVER_START) {
    496513                                if (NT_STATUS_EQUAL(nt_status, NT_STATUS_INVALID_PARAMETER) ||
     514                                    NT_STATUS_EQUAL(nt_status, NT_STATUS_NO_LOGON_SERVERS) ||
     515                                    NT_STATUS_EQUAL(nt_status, NT_STATUS_TIME_DIFFERENCE_AT_DC) ||
    497516                                    NT_STATUS_EQUAL(nt_status, NT_STATUS_CANT_ACCESS_DOMAIN_INFO)) {
    498517                                        /* Pretend we never started it (lets the first run find some incompatible demand) */
     
    566585        DATA_BLOB unwrapped_out = data_blob(NULL, 0);
    567586        const struct gensec_security_ops_wrapper *all_sec;
    568         const char *principal = NULL;
    569587
    570588        mechTypes = gensec_security_oids(gensec_security,
     
    633651               
    634652                if (spnego_state->state_position == SPNEGO_SERVER_START) {
    635                         /* server credentials */
    636                         struct cli_credentials *creds = gensec_get_credentials(gensec_security);
    637                         if (creds) {
    638                                 principal = cli_credentials_get_principal(creds, out_mem_ctx);
    639                         }
    640                 }
    641                 if (principal) {
    642653                        spnego_out.negTokenInit.mechListMIC
    643                                 = data_blob_string_const(principal);
     654                                = data_blob_string_const(ADS_IGNORE_PRINCIPAL);
    644655                } else {
    645656                        spnego_out.negTokenInit.mechListMIC = null_data_blob;
     
    825836                }
    826837
    827                 if (spnego.negTokenInit.targetPrincipal) {
     838                if (spnego.negTokenInit.targetPrincipal
     839                    && strcmp(spnego.negTokenInit.targetPrincipal, ADS_IGNORE_PRINCIPAL) != 0) {
    828840                        DEBUG(5, ("Server claims it's principal name is %s\n", spnego.negTokenInit.targetPrincipal));
    829                         gensec_set_target_principal(gensec_security, spnego.negTokenInit.targetPrincipal);
     841                        if (lpcfg_client_use_spnego_principal(gensec_security->settings->lp_ctx)) {
     842                                gensec_set_target_principal(gensec_security, spnego.negTokenInit.targetPrincipal);
     843                        }
    830844                }
    831845
Note: See TracChangeset for help on using the changeset viewer.