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/ntlm/auth.c

    r414 r745  
    2020
    2121#include "includes.h"
     22#include <tevent.h>
     23#include "../lib/util/tevent_ntstatus.h"
    2224#include "../lib/util/dlinklist.h"
    2325#include "auth/auth.h"
    2426#include "auth/ntlm/auth_proto.h"
    25 #include "lib/events/events.h"
    2627#include "param/param.h"
     28#include "dsdb/samdb/samdb.h"
     29
    2730
    2831/***************************************************************************
     
    4346 Set a fixed challenge
    4447***************************************************************************/
    45 bool auth_challenge_may_be_modified(struct auth_context *auth_ctx)
     48_PUBLIC_ bool auth_challenge_may_be_modified(struct auth_context *auth_ctx)
    4649{
    4750        return auth_ctx->challenge.may_be_modified;
     
    5255 Returns a const char of length 8 bytes.
    5356****************************************************************************/
    54 _PUBLIC_ NTSTATUS auth_get_challenge(struct auth_context *auth_ctx, const uint8_t **_chal)
     57_PUBLIC_ NTSTATUS auth_get_challenge(struct auth_context *auth_ctx, uint8_t chal[8])
    5558{
    5659        NTSTATUS nt_status;
    5760        struct auth_method_context *method;
    5861
    59         if (auth_ctx->challenge.data.length) {
     62        if (auth_ctx->challenge.data.length == 8) {
    6063                DEBUG(5, ("auth_get_challenge: returning previous challenge by module %s (normal)\n",
    6164                          auth_ctx->challenge.set_by));
    62                 *_chal = auth_ctx->challenge.data.data;
     65                memcpy(chal, auth_ctx->challenge.data.data, 8);
    6366                return NT_STATUS_OK;
    6467        }
    6568
    6669        for (method = auth_ctx->methods; method; method = method->next) {
    67                 DATA_BLOB challenge = data_blob(NULL,0);
    68 
    69                 nt_status = method->ops->get_challenge(method, auth_ctx, &challenge);
     70                nt_status = method->ops->get_challenge(method, auth_ctx, chal);
    7071                if (NT_STATUS_EQUAL(nt_status, NT_STATUS_NOT_IMPLEMENTED)) {
    7172                        continue;
     
    7475                NT_STATUS_NOT_OK_RETURN(nt_status);
    7576
    76                 if (challenge.length != 8) {
    77                         DEBUG(0, ("auth_get_challenge: invalid challenge (length %u) by mothod [%s]\n",
    78                                 (unsigned)challenge.length, method->ops->name));
    79                         return NT_STATUS_INTERNAL_ERROR;
    80                 }
    81 
    82                 auth_ctx->challenge.data        = challenge;
     77                auth_ctx->challenge.data        = data_blob_talloc(auth_ctx, chal, 8);
     78                NT_STATUS_HAVE_NO_MEMORY(auth_ctx->challenge.data.data);
    8379                auth_ctx->challenge.set_by      = method->ops->name;
    8480
     
    8783
    8884        if (!auth_ctx->challenge.set_by) {
    89                 uint8_t chal[8];
    9085                generate_random_buffer(chal, 8);
    9186
     
    10095                 auth_ctx->challenge.set_by));
    10196
    102         *_chal = auth_ctx->challenge.data.data;
    10397        return NT_STATUS_OK;
    10498}
    10599
    106100/****************************************************************************
    107  Try to get a challenge out of the various authentication modules.
    108  Returns a const char of length 8 bytes.
     101Used in the gensec_gssapi and gensec_krb5 server-side code, where the
     102PAC isn't available, and for tokenGroups in the DSDB stack.
     103
     104 Supply either a principal or a DN
    109105****************************************************************************/
    110 _PUBLIC_ NTSTATUS auth_get_server_info_principal(TALLOC_CTX *mem_ctx,
    111                                                   struct auth_context *auth_ctx,
    112                                                   const char *principal,
    113                                                   struct auth_serversupplied_info **server_info)
     106_PUBLIC_ NTSTATUS auth_get_user_info_dc_principal(TALLOC_CTX *mem_ctx,
     107                                                 struct auth_context *auth_ctx,
     108                                                 const char *principal,
     109                                                 struct ldb_dn *user_dn,
     110                                                 struct auth_user_info_dc **user_info_dc)
    114111{
    115112        NTSTATUS nt_status;
     
    117114
    118115        for (method = auth_ctx->methods; method; method = method->next) {
    119                 if (!method->ops->get_server_info_principal) {
     116                if (!method->ops->get_user_info_dc_principal) {
    120117                        continue;
    121118                }
    122119
    123                 nt_status = method->ops->get_server_info_principal(mem_ctx, auth_ctx, principal, server_info);
     120                nt_status = method->ops->get_user_info_dc_principal(mem_ctx, auth_ctx, principal, user_dn, user_info_dc);
    124121                if (NT_STATUS_EQUAL(nt_status, NT_STATUS_NOT_IMPLEMENTED)) {
    125122                        continue;
    126123                }
    127124
    128                 NT_STATUS_NOT_OK_RETURN(nt_status);
    129 
    130                 break;
    131         }
    132 
    133         return NT_STATUS_OK;
    134 }
    135 
    136 struct auth_check_password_sync_state {
    137         bool finished;
    138         NTSTATUS status;
    139         struct auth_serversupplied_info *server_info;
    140 };
    141 
    142 static void auth_check_password_sync_callback(struct auth_check_password_request *req,
    143                                               void *private_data)
    144 {
    145         struct auth_check_password_sync_state *s = talloc_get_type(private_data,
    146                                                    struct auth_check_password_sync_state);
    147 
    148         s->finished = true;
    149         s->status = auth_check_password_recv(req, s, &s->server_info);
     125                return nt_status;
     126        }
     127
     128        return NT_STATUS_NOT_IMPLEMENTED;
    150129}
    151130
     
    155134 *
    156135 * Check a user's password, as given in the user_info struct and return various
    157  * interesting details in the server_info struct.
    158  *
    159  * The return value takes precedence over the contents of the server_info
     136 * interesting details in the user_info_dc struct.
     137 *
     138 * The return value takes precedence over the contents of the user_info_dc
    160139 * struct.  When the return is other than NT_STATUS_OK the contents
    161140 * of that structure is undefined.
     
    168147 * @param user_info Contains the user supplied components, including the passwords.
    169148 *
    170  * @param mem_ctx The parent memory context for the server_info structure
    171  *
    172  * @param server_info If successful, contains information about the authentication,
     149 * @param mem_ctx The parent memory context for the user_info_dc structure
     150 *
     151 * @param user_info_dc If successful, contains information about the authentication,
    173152 *                    including a SAM_ACCOUNT struct describing the user.
    174153 *
     
    180159                             TALLOC_CTX *mem_ctx,
    181160                             const struct auth_usersupplied_info *user_info,
    182                              struct auth_serversupplied_info **server_info)
    183 {
    184         struct auth_check_password_sync_state *sync_state;
     161                             struct auth_user_info_dc **user_info_dc)
     162{
     163        struct tevent_req *subreq;
     164        struct tevent_context *ev;
     165        bool ok;
    185166        NTSTATUS status;
    186167
    187         sync_state = talloc_zero(auth_ctx, struct auth_check_password_sync_state);
    188         NT_STATUS_HAVE_NO_MEMORY(sync_state);
    189 
    190         auth_check_password_send(auth_ctx, user_info, auth_check_password_sync_callback, sync_state);
    191 
    192         while (!sync_state->finished) {
    193                 event_loop_once(auth_ctx->event_ctx);
    194         }
    195 
    196         status = sync_state->status;
    197 
    198         if (NT_STATUS_IS_OK(status)) {
    199                 *server_info = talloc_steal(mem_ctx, sync_state->server_info);
    200         }
    201 
    202         talloc_free(sync_state);
     168        /*TODO: create a new event context here! */
     169        ev = auth_ctx->event_ctx;
     170
     171        subreq = auth_check_password_send(mem_ctx,
     172                                          ev,
     173                                          auth_ctx,
     174                                          user_info);
     175        if (subreq == NULL) {
     176                return NT_STATUS_NO_MEMORY;
     177        }
     178
     179        ok = tevent_req_poll(subreq, ev);
     180        if (!ok) {
     181                return NT_STATUS_INTERNAL_ERROR;
     182        }
     183
     184        status = auth_check_password_recv(subreq, mem_ctx, user_info_dc);
     185        TALLOC_FREE(subreq);
     186
    203187        return status;
    204188}
    205189
    206 struct auth_check_password_request {
     190struct auth_check_password_state {
    207191        struct auth_context *auth_ctx;
    208192        const struct auth_usersupplied_info *user_info;
    209         struct auth_serversupplied_info *server_info;
     193        struct auth_user_info_dc *user_info_dc;
    210194        struct auth_method_context *method;
    211         NTSTATUS status;
    212         struct {
    213                 void (*fn)(struct auth_check_password_request *req, void *private_data);
    214                 void *private_data;
    215         } callback;
    216195};
    217196
    218 static void auth_check_password_async_timed_handler(struct tevent_context *ev, struct tevent_timer *te,
    219                                                     struct timeval t, void *ptr)
    220 {
    221         struct auth_check_password_request *req = talloc_get_type(ptr, struct auth_check_password_request);
    222         req->status = req->method->ops->check_password(req->method, req, req->user_info, &req->server_info);
    223         req->callback.fn(req, req->callback.private_data);
    224 }
    225 
     197static void auth_check_password_async_trigger(struct tevent_context *ev,
     198                                              struct tevent_immediate *im,
     199                                              void *private_data);
    226200/**
    227201 * Check a user's Plaintext, LM or NTLM password.
     
    229203 *
    230204 * Check a user's password, as given in the user_info struct and return various
    231  * interesting details in the server_info struct.
    232  *
    233  * The return value takes precedence over the contents of the server_info
     205 * interesting details in the user_info_dc struct.
     206 *
     207 * The return value takes precedence over the contents of the user_info_dc
    234208 * struct.  When the return is other than NT_STATUS_OK the contents
    235209 * of that structure is undefined.
     210 *
     211 * @param mem_ctx The memory context the request should operate on
     212 *
     213 * @param ev The tevent context the request should operate on
    236214 *
    237215 * @param auth_ctx Supplies the challenges and some other data.
     
    242220 * @param user_info Contains the user supplied components, including the passwords.
    243221 *
    244  * @param callback A callback function which will be called when the operation is finished.
    245  *                 The callback function needs to call auth_check_password_recv() to get the return values
    246  *
    247  * @param private_data A private pointer which will ba passed to the callback function
     222 * @return The request handle or NULL on no memory error.
    248223 *
    249224 **/
    250225
    251 _PUBLIC_ void auth_check_password_send(struct auth_context *auth_ctx,
    252                               const struct auth_usersupplied_info *user_info,
    253                               void (*callback)(struct auth_check_password_request *req, void *private_data),
    254                               void *private_data)
    255 {
     226_PUBLIC_ struct tevent_req *auth_check_password_send(TALLOC_CTX *mem_ctx,
     227                                struct tevent_context *ev,
     228                                struct auth_context *auth_ctx,
     229                                const struct auth_usersupplied_info *user_info)
     230{
     231        struct tevent_req *req;
     232        struct auth_check_password_state *state;
    256233        /* if all the modules say 'not for me' this is reasonable */
    257234        NTSTATUS nt_status;
     235        uint8_t chal[8];
     236        struct auth_usersupplied_info *user_info_tmp;
     237        struct tevent_immediate *im;
     238
     239        DEBUG(3,("auth_check_password_send: "
     240                 "Checking password for unmapped user [%s]\\[%s]@[%s]\n",
     241                 user_info->client.domain_name, user_info->client.account_name,
     242                 user_info->workstation_name));
     243
     244        req = tevent_req_create(mem_ctx, &state,
     245                                struct auth_check_password_state);
     246        if (req == NULL) {
     247                return NULL;
     248        }
     249
     250        state->auth_ctx         = auth_ctx;
     251        state->user_info        = user_info;
     252
     253        if (!user_info->mapped_state) {
     254                nt_status = map_user_info(req, lpcfg_workgroup(auth_ctx->lp_ctx),
     255                                          user_info, &user_info_tmp);
     256                if (tevent_req_nterror(req, nt_status)) {
     257                        return tevent_req_post(req, ev);
     258                }
     259                user_info = user_info_tmp;
     260                state->user_info = user_info_tmp;
     261        }
     262
     263        DEBUGADD(3,("auth_check_password_send: "
     264                    "mapped user is: [%s]\\[%s]@[%s]\n",
     265                    user_info->mapped.domain_name,
     266                    user_info->mapped.account_name,
     267                    user_info->workstation_name));
     268
     269        nt_status = auth_get_challenge(auth_ctx, chal);
     270        if (tevent_req_nterror(req, nt_status)) {
     271                DEBUG(0,("auth_check_password_send: "
     272                         "Invalid challenge (length %u) stored for "
     273                         "this auth context set_by %s - cannot continue: %s\n",
     274                        (unsigned)auth_ctx->challenge.data.length,
     275                        auth_ctx->challenge.set_by,
     276                        nt_errstr(nt_status)));
     277                return tevent_req_post(req, ev);
     278        }
     279
     280        if (auth_ctx->challenge.set_by) {
     281                DEBUG(10,("auth_check_password_send: "
     282                          "auth_context challenge created by %s\n",
     283                          auth_ctx->challenge.set_by));
     284        }
     285
     286        DEBUG(10, ("auth_check_password_send: challenge is: \n"));
     287        dump_data(5, auth_ctx->challenge.data.data,
     288                  auth_ctx->challenge.data.length);
     289
     290        im = tevent_create_immediate(state);
     291        if (tevent_req_nomem(im, req)) {
     292                return tevent_req_post(req, ev);
     293        }
     294
     295        tevent_schedule_immediate(im,
     296                                  auth_ctx->event_ctx,
     297                                  auth_check_password_async_trigger,
     298                                  req);
     299        return req;
     300}
     301
     302static void auth_check_password_async_trigger(struct tevent_context *ev,
     303                                              struct tevent_immediate *im,
     304                                              void *private_data)
     305{
     306        struct tevent_req *req =
     307                talloc_get_type_abort(private_data, struct tevent_req);
     308        struct auth_check_password_state *state =
     309                tevent_req_data(req, struct auth_check_password_state);
     310        NTSTATUS status;
    258311        struct auth_method_context *method;
    259         const uint8_t *challenge;
    260         struct auth_usersupplied_info *user_info_tmp;
    261         struct auth_check_password_request *req = NULL;
    262 
    263         DEBUG(3,   ("auth_check_password_send:  Checking password for unmapped user [%s]\\[%s]@[%s]\n",
    264                     user_info->client.domain_name, user_info->client.account_name, user_info->workstation_name));
    265 
    266         req = talloc_zero(auth_ctx, struct auth_check_password_request);
    267         if (!req) {
    268                 callback(NULL, private_data);
     312
     313        status = NT_STATUS_OK;
     314
     315        for (method=state->auth_ctx->methods; method; method = method->next) {
     316
     317                /* we fill in state->method here so debug messages in
     318                   the callers know which method failed */
     319                state->method = method;
     320
     321                /* check if the module wants to check the password */
     322                status = method->ops->want_check(method, req, state->user_info);
     323                if (NT_STATUS_EQUAL(status, NT_STATUS_NOT_IMPLEMENTED)) {
     324                        DEBUG(11,("auth_check_password_send: "
     325                                  "%s had nothing to say\n",
     326                                  method->ops->name));
     327                        continue;
     328                }
     329
     330                if (tevent_req_nterror(req, status)) {
     331                        return;
     332                }
     333
     334                status = method->ops->check_password(method,
     335                                                     state,
     336                                                     state->user_info,
     337                                                     &state->user_info_dc);
     338                if (!NT_STATUS_EQUAL(status, NT_STATUS_NOT_IMPLEMENTED)) {
     339                        /* the backend has handled the request */
     340                        break;
     341                }
     342        }
     343
     344        if (NT_STATUS_EQUAL(status, NT_STATUS_NOT_IMPLEMENTED)) {
     345                /* don't expose the NT_STATUS_NOT_IMPLEMENTED
     346                   internals */
     347                status = NT_STATUS_NO_SUCH_USER;
     348        }
     349
     350        if (tevent_req_nterror(req, status)) {
    269351                return;
    270352        }
    271         req->auth_ctx                   = auth_ctx;
    272         req->user_info                  = user_info;
    273         req->callback.fn                = callback;
    274         req->callback.private_data      = private_data;
    275 
    276         if (!user_info->mapped_state) {
    277                 nt_status = map_user_info(req, lp_workgroup(auth_ctx->lp_ctx), user_info, &user_info_tmp);
    278                 if (!NT_STATUS_IS_OK(nt_status)) goto failed;
    279                 user_info = user_info_tmp;
    280                 req->user_info  = user_info_tmp;
    281         }
    282 
    283         DEBUGADD(3,("auth_check_password_send:  mapped user is: [%s]\\[%s]@[%s]\n",
    284                     user_info->mapped.domain_name, user_info->mapped.account_name, user_info->workstation_name));
    285 
    286         nt_status = auth_get_challenge(auth_ctx, &challenge);
    287         if (!NT_STATUS_IS_OK(nt_status)) {
    288                 DEBUG(0, ("auth_check_password_send:  Invalid challenge (length %u) stored for this auth context set_by %s - cannot continue: %s\n",
    289                         (unsigned)auth_ctx->challenge.data.length, auth_ctx->challenge.set_by, nt_errstr(nt_status)));
    290                 goto failed;
    291         }
    292 
    293         if (auth_ctx->challenge.set_by) {
    294                 DEBUG(10, ("auth_check_password_send: auth_context challenge created by %s\n",
    295                                         auth_ctx->challenge.set_by));
    296         }
    297 
    298         DEBUG(10, ("auth_check_password_send: challenge is: \n"));
    299         dump_data(5, auth_ctx->challenge.data.data, auth_ctx->challenge.data.length);
    300 
    301         nt_status = NT_STATUS_NO_SUCH_USER; /* If all the modules say 'not for me', then this is reasonable */
    302         for (method = auth_ctx->methods; method; method = method->next) {
    303                 NTSTATUS result;
    304                 struct tevent_timer *te = NULL;
    305 
    306                 /* check if the module wants to chek the password */
    307                 result = method->ops->want_check(method, req, user_info);
    308                 if (NT_STATUS_EQUAL(result, NT_STATUS_NOT_IMPLEMENTED)) {
    309                         DEBUG(11,("auth_check_password_send: %s had nothing to say\n", method->ops->name));
    310                         continue;
    311                 }
    312 
    313                 nt_status = result;
    314                 req->method     = method;
    315 
    316                 if (!NT_STATUS_IS_OK(nt_status)) break;
    317 
    318                 te = event_add_timed(auth_ctx->event_ctx, req,
    319                                      timeval_zero(),
    320                                      auth_check_password_async_timed_handler, req);
    321                 if (!te) {
    322                         nt_status = NT_STATUS_NO_MEMORY;
    323                         goto failed;
    324                 }
    325                 return;
    326         }
    327 
    328 failed:
    329         req->status = nt_status;
    330         req->callback.fn(req, req->callback.private_data);
     353
     354        tevent_req_done(req);
    331355}
    332356
     
    335359 * async receive function
    336360 *
    337  * The return value takes precedence over the contents of the server_info
     361 * The return value takes precedence over the contents of the user_info_dc
    338362 * struct.  When the return is other than NT_STATUS_OK the contents
    339363 * of that structure is undefined.
    340364 *
    341365 *
    342  * @param req The async auth_check_password state, passes to the callers callback function
    343  *
    344  * @param mem_ctx The parent memory context for the server_info structure
    345  *
    346  * @param server_info If successful, contains information about the authentication,
     366 * @param req The async request state
     367 *
     368 * @param mem_ctx The parent memory context for the user_info_dc structure
     369 *
     370 * @param user_info_dc If successful, contains information about the authentication,
    347371 *                    including a SAM_ACCOUNT struct describing the user.
    348372 *
     
    351375 **/
    352376
    353 _PUBLIC_ NTSTATUS auth_check_password_recv(struct auth_check_password_request *req,
     377_PUBLIC_ NTSTATUS auth_check_password_recv(struct tevent_req *req,
    354378                                  TALLOC_CTX *mem_ctx,
    355                                   struct auth_serversupplied_info **server_info)
    356 {
     379                                  struct auth_user_info_dc **user_info_dc)
     380{
     381        struct auth_check_password_state *state =
     382                tevent_req_data(req, struct auth_check_password_state);
    357383        NTSTATUS status;
    358384
    359         NT_STATUS_HAVE_NO_MEMORY(req);
    360 
    361         if (NT_STATUS_IS_OK(req->status)) {
    362                 DEBUG(5,("auth_check_password_recv: %s authentication for user [%s\\%s] succeeded\n",
    363                          req->method->ops->name, req->server_info->domain_name, req->server_info->account_name));
    364 
    365                 *server_info = talloc_steal(mem_ctx, req->server_info);
    366         } else {
    367                 DEBUG(2,("auth_check_password_recv: %s authentication for user [%s\\%s] FAILED with error %s\n",
    368                          (req->method ? req->method->ops->name : "NO_METHOD"),
    369                          req->user_info->mapped.domain_name,
    370                          req->user_info->mapped.account_name,
    371                          nt_errstr(req->status)));
    372         }
    373 
    374         status = req->status;
    375         talloc_free(req);
    376         return status;
     385        if (tevent_req_is_nterror(req, &status)) {
     386                DEBUG(2,("auth_check_password_recv: "
     387                         "%s authentication for user [%s\\%s] "
     388                         "FAILED with error %s\n",
     389                         (state->method ? state->method->ops->name : "NO_METHOD"),
     390                         state->user_info->mapped.domain_name,
     391                         state->user_info->mapped.account_name,
     392                         nt_errstr(status)));
     393                tevent_req_received(req);
     394                return status;
     395        }
     396
     397        DEBUG(5,("auth_check_password_recv: "
     398                 "%s authentication for user [%s\\%s] succeeded\n",
     399                 state->method->ops->name,
     400                 state->user_info_dc->info->domain_name,
     401                 state->user_info_dc->info->account_name));
     402
     403        *user_info_dc = talloc_move(mem_ctx, &state->user_info_dc);
     404
     405        tevent_req_received(req);
     406        return NT_STATUS_OK;
     407}
     408
     409/* Wrapper because we don't want to expose all callers to needing to
     410 * know that session_info is generated from the main ldb */
     411static NTSTATUS auth_generate_session_info_wrapper(TALLOC_CTX *mem_ctx,
     412                                                   struct auth_context *auth_context,
     413                                                   struct auth_user_info_dc *user_info_dc,
     414                                                   uint32_t session_info_flags,
     415                                                   struct auth_session_info **session_info)
     416{
     417        return auth_generate_session_info(mem_ctx, auth_context->lp_ctx,
     418                                          auth_context->sam_ctx, user_info_dc,
     419                                          session_info_flags, session_info);
    377420}
    378421
    379422/***************************************************************************
    380423 Make a auth_info struct for the auth subsystem
    381  - Allow the caller to specify the methods to use
     424 - Allow the caller to specify the methods to use, including optionally the SAM to use
    382425***************************************************************************/
    383426_PUBLIC_ NTSTATUS auth_context_create_methods(TALLOC_CTX *mem_ctx, const char **methods,
    384                                      struct tevent_context *ev,
    385                                      struct messaging_context *msg,
    386                                      struct loadparm_context *lp_ctx,
    387                                      struct auth_context **auth_ctx)
     427                                              struct tevent_context *ev,
     428                                              struct messaging_context *msg,
     429                                              struct loadparm_context *lp_ctx,
     430                                              struct ldb_context *sam_ctx,
     431                                              struct auth_context **auth_ctx)
    388432{
    389433        int i;
    390434        struct auth_context *ctx;
    391435
    392         auth_init();
    393 
    394         if (!methods) {
    395                 DEBUG(0,("auth_context_create: No auth method list!?\n"));
    396                 return NT_STATUS_INTERNAL_ERROR;
    397         }
     436        auth4_init();
    398437
    399438        if (!ev) {
    400439                DEBUG(0,("auth_context_create: called with out event context\n"));
    401                 return NT_STATUS_INTERNAL_ERROR;
    402         }
    403 
    404         if (!msg) {
    405                 DEBUG(0,("auth_context_create: called with out messaging context\n"));
    406440                return NT_STATUS_INTERNAL_ERROR;
    407441        }
     
    417451        ctx->lp_ctx                     = lp_ctx;
    418452
    419         for (i=0; methods[i] ; i++) {
     453        if (sam_ctx) {
     454                ctx->sam_ctx = sam_ctx;
     455        } else {
     456                ctx->sam_ctx = samdb_connect(ctx, ctx->event_ctx, ctx->lp_ctx, system_session(ctx->lp_ctx), 0);
     457        }
     458
     459        for (i=0; methods && methods[i] ; i++) {
    420460                struct auth_method_context *method;
    421461
     
    434474        }
    435475
    436         if (!ctx->methods) {
    437                 return NT_STATUS_INTERNAL_ERROR;
    438         }
    439 
    440476        ctx->check_password = auth_check_password;
    441477        ctx->get_challenge = auth_get_challenge;
    442478        ctx->set_challenge = auth_context_set_challenge;
    443479        ctx->challenge_may_be_modified = auth_challenge_may_be_modified;
    444         ctx->get_server_info_principal = auth_get_server_info_principal;
     480        ctx->get_user_info_dc_principal = auth_get_user_info_dc_principal;
     481        ctx->generate_session_info = auth_generate_session_info_wrapper;
    445482
    446483        *auth_ctx = ctx;
     
    448485        return NT_STATUS_OK;
    449486}
     487
     488const char **auth_methods_from_lp(TALLOC_CTX *mem_ctx, struct loadparm_context *lp_ctx)
     489{
     490        const char **auth_methods = NULL;
     491        switch (lpcfg_server_role(lp_ctx)) {
     492        case ROLE_STANDALONE:
     493                auth_methods = lpcfg_parm_string_list(mem_ctx, lp_ctx, NULL, "auth methods", "standalone", NULL);
     494                break;
     495        case ROLE_DOMAIN_MEMBER:
     496                auth_methods = lpcfg_parm_string_list(mem_ctx, lp_ctx, NULL, "auth methods", "member server", NULL);
     497                break;
     498        case ROLE_DOMAIN_CONTROLLER:
     499                auth_methods = lpcfg_parm_string_list(mem_ctx, lp_ctx, NULL, "auth methods", "domain controller", NULL);
     500                break;
     501        }
     502        return auth_methods;
     503}
     504
    450505/***************************************************************************
    451506 Make a auth_info struct for the auth subsystem
    452507 - Uses default auth_methods, depending on server role and smb.conf settings
    453508***************************************************************************/
    454 _PUBLIC_ NTSTATUS auth_context_create(TALLOC_CTX *mem_ctx, 
     509_PUBLIC_ NTSTATUS auth_context_create(TALLOC_CTX *mem_ctx,
    455510                             struct tevent_context *ev,
    456511                             struct messaging_context *msg,
     
    458513                             struct auth_context **auth_ctx)
    459514{
    460         const char **auth_methods = NULL;
    461         switch (lp_server_role(lp_ctx)) {
    462         case ROLE_STANDALONE:
    463                 auth_methods = lp_parm_string_list(mem_ctx, lp_ctx, NULL, "auth methods", "standalone", NULL);
    464                 break;
    465         case ROLE_DOMAIN_MEMBER:
    466                 auth_methods = lp_parm_string_list(mem_ctx, lp_ctx, NULL, "auth methods", "member server", NULL);
    467                 break;
    468         case ROLE_DOMAIN_CONTROLLER:
    469                 auth_methods = lp_parm_string_list(mem_ctx, lp_ctx, NULL, "auth methods", "domain controller", NULL);
    470                 break;
    471         }
    472         return auth_context_create_methods(mem_ctx, auth_methods, ev, msg, lp_ctx, auth_ctx);
    473 }
    474 
     515        NTSTATUS status;
     516        const char **auth_methods;
     517        TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx);
     518        if (!tmp_ctx) {
     519                return NT_STATUS_NO_MEMORY;
     520        }
     521
     522        auth_methods = auth_methods_from_lp(tmp_ctx, lp_ctx);
     523        if (!auth_methods) {
     524                return NT_STATUS_INVALID_PARAMETER;
     525        }
     526        status = auth_context_create_methods(mem_ctx, auth_methods, ev, msg, lp_ctx, NULL, auth_ctx);
     527        talloc_free(tmp_ctx);
     528        return status;
     529}
     530
     531/* Create an auth context from an open LDB.
     532
     533   This allows us not to re-open the LDB when we need to do a some authentication logic (such as tokenGroups)
     534
     535 */
     536NTSTATUS auth_context_create_from_ldb(TALLOC_CTX *mem_ctx, struct ldb_context *ldb, struct auth_context **auth_ctx)
     537{
     538        NTSTATUS status;
     539        const char **auth_methods;
     540        struct loadparm_context *lp_ctx = talloc_get_type_abort(ldb_get_opaque(ldb, "loadparm"), struct loadparm_context);
     541        struct tevent_context *ev = ldb_get_event_context(ldb);
     542
     543        TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx);
     544        if (!tmp_ctx) {
     545                return NT_STATUS_NO_MEMORY;
     546        }
     547
     548        auth_methods = auth_methods_from_lp(tmp_ctx, lp_ctx);
     549        if (!auth_methods) {
     550                return NT_STATUS_INVALID_PARAMETER;
     551        }
     552        status = auth_context_create_methods(mem_ctx, auth_methods, ev, NULL, lp_ctx, ldb, auth_ctx);
     553        talloc_free(tmp_ctx);
     554        return status;
     555}
    475556
    476557/* the list of currently registered AUTH backends */
     
    545626                sizeof(struct auth_context),
    546627                sizeof(struct auth_usersupplied_info),
    547                 sizeof(struct auth_serversupplied_info)
     628                sizeof(struct auth_user_info_dc)
    548629        };
    549630
     
    551632}
    552633
    553 _PUBLIC_ NTSTATUS auth_init(void)
     634_PUBLIC_ NTSTATUS auth4_init(void)
    554635{
    555636        static bool initialized = false;
    556         extern NTSTATUS auth_developer_init(void);
    557         extern NTSTATUS auth_winbind_init(void);
    558         extern NTSTATUS auth_anonymous_init(void);
    559         extern NTSTATUS auth_unix_init(void);
    560         extern NTSTATUS auth_sam_init(void);
    561         extern NTSTATUS auth_server_init(void);
    562 
    563         init_module_fn static_init[] = { STATIC_auth_MODULES };
     637#define _MODULE_PROTO(init) extern NTSTATUS init(void);
     638        STATIC_auth4_MODULES_PROTO;
     639        init_module_fn static_init[] = { STATIC_auth4_MODULES };
    564640       
    565641        if (initialized) return NT_STATUS_OK;
     
    570646        return NT_STATUS_OK;   
    571647}
    572 
    573 NTSTATUS server_service_auth_init(void)
    574 {
    575         return auth_init();
    576 }
Note: See TracChangeset for help on using the changeset viewer.