Ignore:
Timestamp:
Nov 27, 2012, 4:43:17 PM (13 years ago)
Author:
Silvan Scherrer
Message:

Samba Server: updated trunk to 3.6.0

Location:
trunk/server
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/server

  • trunk/server/source4/auth/gensec/gensec.c

    r414 r745  
    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;
Note: See TracChangeset for help on using the changeset viewer.