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:
4 deleted
10 edited
2 copied

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 }
  • trunk/server/source4/auth/ntlm/auth_anonymous.c

    r414 r745  
    5353                                         TALLOC_CTX *mem_ctx,
    5454                                         const struct auth_usersupplied_info *user_info,
    55                                          struct auth_serversupplied_info **_server_info)
     55                                         struct auth_user_info_dc **_user_info_dc)
    5656{
    57         return auth_anonymous_server_info(mem_ctx, lp_netbios_name(ctx->auth_ctx->lp_ctx), _server_info);
     57        return auth_anonymous_user_info_dc(mem_ctx, lpcfg_netbios_name(ctx->auth_ctx->lp_ctx), _user_info_dc);
    5858}
    5959
  • trunk/server/source4/auth/ntlm/auth_developer.c

    r414 r745  
    2424#include "auth/ntlm/auth_proto.h"
    2525#include "libcli/security/security.h"
    26 #include "librpc/gen_ndr/ndr_samr.h"
    2726
    2827static NTSTATUS name_to_ntstatus_want_check(struct auth_method_context *ctx,
     
    4948                                                TALLOC_CTX *mem_ctx,
    5049                                                const struct auth_usersupplied_info *user_info,
    51                                                 struct auth_serversupplied_info **_server_info)
     50                                                struct auth_user_info_dc **_user_info_dc)
    5251{
    5352        NTSTATUS nt_status;
    54         struct auth_serversupplied_info *server_info;
     53        struct auth_user_info_dc *user_info_dc;
     54        struct auth_user_info *info;
    5555        uint32_t error_num;
    5656        const char *user;
     
    6767        NT_STATUS_NOT_OK_RETURN(nt_status);
    6868
    69         server_info = talloc(mem_ctx, struct auth_serversupplied_info);
    70         NT_STATUS_HAVE_NO_MEMORY(server_info);
    71 
    72         server_info->account_sid = dom_sid_parse_talloc(server_info, SID_NT_ANONYMOUS);
    73         NT_STATUS_HAVE_NO_MEMORY(server_info->account_sid);
    74 
    75         /* is this correct? */
    76         server_info->primary_group_sid = dom_sid_parse_talloc(server_info, SID_BUILTIN_GUESTS);
    77         NT_STATUS_HAVE_NO_MEMORY(server_info->primary_group_sid);
    78 
    79         server_info->n_domain_groups = 0;
    80         server_info->domain_groups = NULL;
     69        user_info_dc = talloc(mem_ctx, struct auth_user_info_dc);
     70        NT_STATUS_HAVE_NO_MEMORY(user_info_dc);
     71
     72        /* This returns a pointer to a struct dom_sid, which is the
     73         * same as a 1 element list of struct dom_sid */
     74        user_info_dc->num_sids = 1;
     75        user_info_dc->sids = dom_sid_parse_talloc(user_info_dc, SID_NT_ANONYMOUS);
     76        NT_STATUS_HAVE_NO_MEMORY(user_info_dc->sids);
    8177
    8278        /* annoying, but the Anonymous really does have a session key,
    8379           and it is all zeros! */
    84         server_info->user_session_key = data_blob_talloc(server_info, NULL, 16);
    85         NT_STATUS_HAVE_NO_MEMORY(server_info->user_session_key.data);
    86 
    87         server_info->lm_session_key = data_blob_talloc(server_info, NULL, 16);
    88         NT_STATUS_HAVE_NO_MEMORY(server_info->lm_session_key.data);
    89 
    90         data_blob_clear(&server_info->user_session_key);
    91         data_blob_clear(&server_info->lm_session_key);
    92 
    93         server_info->account_name = talloc_asprintf(server_info, "NAME TO NTSTATUS %s ANONYMOUS LOGON", user);
    94         NT_STATUS_HAVE_NO_MEMORY(server_info->account_name);
    95 
    96         server_info->domain_name = talloc_strdup(server_info, "NT AUTHORITY");
    97         NT_STATUS_HAVE_NO_MEMORY(server_info->domain_name);
    98 
    99         server_info->full_name = talloc_asprintf(server_info, "NAME TO NTSTATUS %s Anonymous Logon", user);
    100         NT_STATUS_HAVE_NO_MEMORY(server_info->full_name);
    101 
    102         server_info->logon_script = talloc_strdup(server_info, "");
    103         NT_STATUS_HAVE_NO_MEMORY(server_info->logon_script);
    104 
    105         server_info->profile_path = talloc_strdup(server_info, "");
    106         NT_STATUS_HAVE_NO_MEMORY(server_info->profile_path);
    107 
    108         server_info->home_directory = talloc_strdup(server_info, "");
    109         NT_STATUS_HAVE_NO_MEMORY(server_info->home_directory);
    110 
    111         server_info->home_drive = talloc_strdup(server_info, "");
    112         NT_STATUS_HAVE_NO_MEMORY(server_info->home_drive);
    113 
    114         server_info->last_logon = 0;
    115         server_info->last_logoff = 0;
    116         server_info->acct_expiry = 0;
    117         server_info->last_password_change = 0;
    118         server_info->allow_password_change = 0;
    119         server_info->force_password_change = 0;
    120 
    121         server_info->logon_count = 0;
    122         server_info->bad_password_count = 0;
    123 
    124         server_info->acct_flags = ACB_NORMAL;
    125 
    126         server_info->authenticated = false;
    127 
    128         *_server_info = server_info;
     80        user_info_dc->user_session_key = data_blob_talloc(user_info_dc, NULL, 16);
     81        NT_STATUS_HAVE_NO_MEMORY(user_info_dc->user_session_key.data);
     82
     83        user_info_dc->lm_session_key = data_blob_talloc(user_info_dc, NULL, 16);
     84        NT_STATUS_HAVE_NO_MEMORY(user_info_dc->lm_session_key.data);
     85
     86        data_blob_clear(&user_info_dc->user_session_key);
     87        data_blob_clear(&user_info_dc->lm_session_key);
     88
     89        user_info_dc->info = info = talloc_zero(user_info_dc, struct auth_user_info);
     90        NT_STATUS_HAVE_NO_MEMORY(user_info_dc->info);
     91
     92        info->account_name = talloc_asprintf(user_info_dc, "NAME TO NTSTATUS %s ANONYMOUS LOGON", user);
     93        NT_STATUS_HAVE_NO_MEMORY(info->account_name);
     94
     95        info->domain_name = talloc_strdup(user_info_dc, "NT AUTHORITY");
     96        NT_STATUS_HAVE_NO_MEMORY(info->domain_name);
     97
     98        info->full_name = talloc_asprintf(user_info_dc, "NAME TO NTSTATUS %s Anonymous Logon", user);
     99        NT_STATUS_HAVE_NO_MEMORY(info->full_name);
     100
     101        info->logon_script = talloc_strdup(user_info_dc, "");
     102        NT_STATUS_HAVE_NO_MEMORY(info->logon_script);
     103
     104        info->profile_path = talloc_strdup(user_info_dc, "");
     105        NT_STATUS_HAVE_NO_MEMORY(info->profile_path);
     106
     107        info->home_directory = talloc_strdup(user_info_dc, "");
     108        NT_STATUS_HAVE_NO_MEMORY(info->home_directory);
     109
     110        info->home_drive = talloc_strdup(user_info_dc, "");
     111        NT_STATUS_HAVE_NO_MEMORY(info->home_drive);
     112
     113        info->last_logon = 0;
     114        info->last_logoff = 0;
     115        info->acct_expiry = 0;
     116        info->last_password_change = 0;
     117        info->allow_password_change = 0;
     118        info->force_password_change = 0;
     119
     120        info->logon_count = 0;
     121        info->bad_password_count = 0;
     122
     123        info->acct_flags = ACB_NORMAL;
     124
     125        info->authenticated = true;
     126
     127        *_user_info_dc = user_info_dc;
    129128
    130129        return nt_status;
     
    152151 * @return NT_STATUS_UNSUCCESSFUL
    153152 **/
    154 static NTSTATUS fixed_challenge_get_challenge(struct auth_method_context *ctx, TALLOC_CTX *mem_ctx, DATA_BLOB *_blob)
    155 {
    156         DATA_BLOB blob;
     153static NTSTATUS fixed_challenge_get_challenge(struct auth_method_context *ctx, TALLOC_CTX *mem_ctx, uint8_t chal[8])
     154{
    157155        const char *challenge = "I am a teapot";
    158156
    159         blob = data_blob_talloc(mem_ctx, challenge, 8);
    160         NT_STATUS_HAVE_NO_MEMORY(blob.data);
    161 
    162         *_blob = blob;
     157        memcpy(chal, challenge, 8);
     158
    163159        return NT_STATUS_OK;
    164160}
     
    175171                                               TALLOC_CTX *mem_ctx,
    176172                                               const struct auth_usersupplied_info *user_info,
    177                                                struct auth_serversupplied_info **_server_info)
     173                                               struct auth_user_info_dc **_user_info_dc)
    178174{
    179175        /* don't handle any users */
  • trunk/server/source4/auth/ntlm/auth_sam.c

    r414 r745  
    2121
    2222#include "includes.h"
    23 #include "librpc/gen_ndr/ndr_netlogon.h"
    2423#include "system/time.h"
    25 #include "lib/ldb/include/ldb.h"
    26 #include "../lib/util/util_ldb.h"
     24#include <ldb.h>
     25#include "libcli/ldap/ldap_ndr.h"
     26#include "libcli/security/security.h"
    2727#include "auth/auth.h"
    2828#include "../libcli/auth/ntlm_check.h"
     
    3030#include "auth/auth_sam.h"
    3131#include "dsdb/samdb/samdb.h"
    32 #include "libcli/security/security.h"
    33 #include "libcli/ldap/ldap_ndr.h"
     32#include "dsdb/common/util.h"
    3433#include "param/param.h"
     34#include "librpc/gen_ndr/ndr_irpc_c.h"
     35#include "lib/messaging/irpc.h"
    3536
    3637extern const char *user_attrs[];
     
    4950
    5051        /* pull the user attributes */
    51         ret = gendb_search_single_extended_dn(sam_ctx, mem_ctx, domain_dn, LDB_SCOPE_SUBTREE,
    52                                               ret_msg, user_attrs,
    53                                               "(&(sAMAccountName=%s)(objectclass=user))",
    54                                               ldb_binary_encode_string(mem_ctx, account_name));
     52        ret = dsdb_search_one(sam_ctx, mem_ctx, ret_msg, domain_dn, LDB_SCOPE_SUBTREE,
     53                              user_attrs,
     54                              DSDB_SEARCH_SHOW_EXTENDED_DN,
     55                              "(&(sAMAccountName=%s)(objectclass=user))",
     56                              ldb_binary_encode_string(mem_ctx, account_name));
    5557        if (ret == LDB_ERR_NO_SUCH_OBJECT) {
    5658                DEBUG(3,("sam_search_user: Couldn't find user [%s] in samdb, under %s\n",
     
    99101                *user_sess_key = data_blob(NULL, 0);
    100102                status = hash_password_check(mem_ctx,
    101                                              lp_lanman_auth(auth_context->lp_ctx),
     103                                             lpcfg_lanman_auth(auth_context->lp_ctx),
    102104                                             user_info->password.hash.lanman,
    103105                                             user_info->password.hash.nt,
     
    109111        case AUTH_PASSWORD_RESPONSE:
    110112                status = ntlm_password_check(mem_ctx,
    111                                              lp_lanman_auth(auth_context->lp_ctx),
    112                                                  lp_ntlm_auth(auth_context->lp_ctx),
     113                                             lpcfg_lanman_auth(auth_context->lp_ctx),
     114                                                 lpcfg_ntlm_auth(auth_context->lp_ctx),
    113115                                             user_info->logon_parameters,
    114116                                             &auth_context->challenge.data,
     
    135137
    136138
     139/*
     140  send a message to the drepl server telling it to initiate a
     141  REPL_SECRET getncchanges extended op to fetch the users secrets
     142 */
     143static void auth_sam_trigger_repl_secret(TALLOC_CTX *mem_ctx, struct auth_context *auth_context,
     144                                         struct ldb_dn *user_dn)
     145{
     146        struct dcerpc_binding_handle *irpc_handle;
     147        struct drepl_trigger_repl_secret r;
     148        struct tevent_req *req;
     149
     150        irpc_handle = irpc_binding_handle_by_name(mem_ctx, auth_context->msg_ctx,
     151                                                  "dreplsrv",
     152                                                  &ndr_table_irpc);
     153        if (irpc_handle == NULL) {
     154                DEBUG(1,(__location__ ": Unable to get binding handle for dreplsrv\n"));
     155                return;
     156        }
     157
     158        r.in.user_dn = ldb_dn_get_linearized(user_dn);
     159
     160        req = dcerpc_drepl_trigger_repl_secret_r_send(mem_ctx,
     161                                                      auth_context->event_ctx,
     162                                                      irpc_handle,
     163                                                      &r);
     164
     165        /* we aren't interested in a reply */
     166        talloc_free(req);
     167        talloc_free(irpc_handle);
     168}
     169
    137170
    138171static NTSTATUS authsam_authenticate(struct auth_context *auth_context,
     
    146179        NTSTATUS nt_status;
    147180
    148         uint16_t acct_flags = samdb_result_acct_flags(sam_ctx, mem_ctx, msg, domain_dn);
     181        uint16_t acct_flags = samdb_result_acct_flags(auth_context->sam_ctx, mem_ctx, msg, domain_dn);
    149182       
    150183        /* Quit if the account was locked out. */
     
    165198        NT_STATUS_NOT_OK_RETURN(nt_status);
    166199
     200        if (lm_pwd == NULL && nt_pwd == NULL) {
     201                bool am_rodc;
     202                if (samdb_rodc(auth_context->sam_ctx, &am_rodc) == LDB_SUCCESS && am_rodc) {
     203                        /* we don't have passwords for this
     204                         * account. We are an RODC, and this account
     205                         * may be one for which we either are denied
     206                         * REPL_SECRET replication or we haven't yet
     207                         * done the replication. We return
     208                         * NT_STATUS_NOT_IMPLEMENTED which tells the
     209                         * auth code to try the next authentication
     210                         * mechanism. We also send a message to our
     211                         * drepl server to tell it to try and
     212                         * replicate the secrets for this account.
     213                         */
     214                        auth_sam_trigger_repl_secret(mem_ctx, auth_context, msg->dn);
     215                        return NT_STATUS_NOT_IMPLEMENTED;
     216                }
     217        }
     218
    167219        nt_status = authsam_password_ok(auth_context, mem_ctx,
    168220                                        acct_flags, lm_pwd, nt_pwd,
     
    170222        NT_STATUS_NOT_OK_RETURN(nt_status);
    171223
    172         nt_status = authsam_account_ok(mem_ctx, sam_ctx,
     224        nt_status = authsam_account_ok(mem_ctx, auth_context->sam_ctx,
    173225                                       user_info->logon_parameters,
    174226                                       domain_dn,
     
    186238                                                 TALLOC_CTX *mem_ctx,
    187239                                                 const struct auth_usersupplied_info *user_info,
    188                                                  struct auth_serversupplied_info **server_info)
     240                                                 struct auth_user_info_dc **user_info_dc)
    189241{
    190242        NTSTATUS nt_status;
    191243        const char *account_name = user_info->mapped.account_name;
    192244        struct ldb_message *msg;
    193         struct ldb_context *sam_ctx;
    194245        struct ldb_dn *domain_dn;
    195246        DATA_BLOB user_sess_key, lm_sess_key;
    196247        TALLOC_CTX *tmp_ctx;
    197248
     249        if (ctx->auth_ctx->sam_ctx == NULL) {
     250                DEBUG(0, ("No SAM available, cannot log in users\n"));
     251                return NT_STATUS_INVALID_SYSTEM_SERVICE;
     252        }
     253
    198254        if (!account_name || !*account_name) {
    199255                /* 'not for me' */
     
    206262        }
    207263
    208         sam_ctx = samdb_connect(tmp_ctx, ctx->auth_ctx->event_ctx, ctx->auth_ctx->lp_ctx, system_session(mem_ctx, ctx->auth_ctx->lp_ctx));
    209         if (sam_ctx == NULL) {
    210                 talloc_free(tmp_ctx);
    211                 return NT_STATUS_INVALID_SYSTEM_SERVICE;
    212         }
    213 
    214         domain_dn = ldb_get_default_basedn(sam_ctx);
     264        domain_dn = ldb_get_default_basedn(ctx->auth_ctx->sam_ctx);
    215265        if (domain_dn == NULL) {
    216266                talloc_free(tmp_ctx);
     
    218268        }
    219269
    220         nt_status = authsam_search_account(tmp_ctx, sam_ctx, account_name, domain_dn, &msg);
     270        nt_status = authsam_search_account(tmp_ctx, ctx->auth_ctx->sam_ctx, account_name, domain_dn, &msg);
    221271        if (!NT_STATUS_IS_OK(nt_status)) {
    222272                talloc_free(tmp_ctx);
     
    224274        }
    225275
    226         nt_status = authsam_authenticate(ctx->auth_ctx, tmp_ctx, sam_ctx, domain_dn, msg, user_info,
     276        nt_status = authsam_authenticate(ctx->auth_ctx, tmp_ctx, ctx->auth_ctx->sam_ctx, domain_dn, msg, user_info,
    227277                                         &user_sess_key, &lm_sess_key);
    228278        if (!NT_STATUS_IS_OK(nt_status)) {
     
    231281        }
    232282
    233         nt_status = authsam_make_server_info(tmp_ctx, sam_ctx, lp_netbios_name(ctx->auth_ctx->lp_ctx),
    234                                              lp_sam_name(ctx->auth_ctx->lp_ctx),
     283        nt_status = authsam_make_user_info_dc(tmp_ctx, ctx->auth_ctx->sam_ctx, lpcfg_netbios_name(ctx->auth_ctx->lp_ctx),
     284                                             lpcfg_sam_name(ctx->auth_ctx->lp_ctx),
    235285                                             domain_dn,
    236286                                             msg,
    237287                                             user_sess_key, lm_sess_key,
    238                                              server_info);
     288                                             user_info_dc);
    239289        if (!NT_STATUS_IS_OK(nt_status)) {
    240290                talloc_free(tmp_ctx);
     
    242292        }
    243293
    244         talloc_steal(mem_ctx, *server_info);
     294        talloc_steal(mem_ctx, *user_info_dc);
    245295        talloc_free(tmp_ctx);
    246296
     
    272322        }
    273323
    274         is_local_name = lp_is_myname(ctx->auth_ctx->lp_ctx,
     324        is_local_name = lpcfg_is_myname(ctx->auth_ctx->lp_ctx,
    275325                                  user_info->mapped.domain_name);
    276         is_my_domain  = lp_is_mydomain(ctx->auth_ctx->lp_ctx,
     326        is_my_domain  = lpcfg_is_mydomain(ctx->auth_ctx->lp_ctx,
    277327                                       user_info->mapped.domain_name);
    278328
    279329        /* check whether or not we service this domain/workgroup name */
    280         switch (lp_server_role(ctx->auth_ctx->lp_ctx)) {
     330        switch (lpcfg_server_role(ctx->auth_ctx->lp_ctx)) {
    281331                case ROLE_STANDALONE:
    282332                        return NT_STATUS_OK;
     
    299349        }
    300350
    301         DEBUG(6,("authsam_check_password: lp_server_role() has an undefined value\n"));
     351        DEBUG(6,("authsam_check_password: lpcfg_server_role() has an undefined value\n"));
    302352        return NT_STATUS_NOT_IMPLEMENTED;
    303353}
    304354
    305355                                   
    306 /* Used in the gensec_gssapi and gensec_krb5 server-side code, where the PAC isn't available */
    307 NTSTATUS authsam_get_server_info_principal(TALLOC_CTX *mem_ctx,
    308                                            struct auth_context *auth_context,
    309                                            const char *principal,
    310                                            struct auth_serversupplied_info **server_info)
    311 {
    312         NTSTATUS nt_status;
    313         DATA_BLOB user_sess_key = data_blob(NULL, 0);
    314         DATA_BLOB lm_sess_key = data_blob(NULL, 0);
    315 
    316         struct ldb_message *msg;
    317         struct ldb_context *sam_ctx;
    318         struct ldb_dn *domain_dn;
    319        
    320         TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx);
    321         if (!tmp_ctx) {
    322                 return NT_STATUS_NO_MEMORY;
    323         }
    324 
    325         sam_ctx = samdb_connect(tmp_ctx, auth_context->event_ctx, auth_context->lp_ctx,
    326                                 system_session(tmp_ctx, auth_context->lp_ctx));
    327         if (sam_ctx == NULL) {
    328                 talloc_free(tmp_ctx);
    329                 return NT_STATUS_INVALID_SYSTEM_SERVICE;
    330         }
    331 
    332         nt_status = sam_get_results_principal(sam_ctx, tmp_ctx, principal,
    333                                               user_attrs, &domain_dn, &msg);
    334         if (!NT_STATUS_IS_OK(nt_status)) {
    335                 return nt_status;
    336         }
    337 
    338         nt_status = authsam_make_server_info(tmp_ctx, sam_ctx,
    339                                              lp_netbios_name(auth_context->lp_ctx),
    340                                              lp_workgroup(auth_context->lp_ctx),
    341                                              domain_dn,
    342                                              msg,
    343                                              user_sess_key, lm_sess_key,
    344                                              server_info);
    345         if (NT_STATUS_IS_OK(nt_status)) {
    346                 talloc_steal(mem_ctx, *server_info);
    347         }
    348         talloc_free(tmp_ctx);
    349         return nt_status;
    350 }
    351 
     356/* Wrapper for the auth subsystem pointer */
     357static NTSTATUS authsam_get_user_info_dc_principal_wrapper(TALLOC_CTX *mem_ctx,
     358                                                          struct auth_context *auth_context,
     359                                                          const char *principal,
     360                                                          struct ldb_dn *user_dn,
     361                                                          struct auth_user_info_dc **user_info_dc)
     362{
     363        return authsam_get_user_info_dc_principal(mem_ctx, auth_context->lp_ctx, auth_context->sam_ctx,
     364                                                 principal, user_dn, user_info_dc);
     365}
    352366static const struct auth_operations sam_ignoredomain_ops = {
    353367        .name                      = "sam_ignoredomain",
     
    355369        .want_check                = authsam_ignoredomain_want_check,
    356370        .check_password            = authsam_check_password_internals,
    357         .get_server_info_principal = authsam_get_server_info_principal
     371        .get_user_info_dc_principal = authsam_get_user_info_dc_principal_wrapper
    358372};
    359373
     
    363377        .want_check                = authsam_want_check,
    364378        .check_password            = authsam_check_password_internals,
    365         .get_server_info_principal = authsam_get_server_info_principal
     379        .get_user_info_dc_principal = authsam_get_user_info_dc_principal_wrapper
    366380};
    367381
  • trunk/server/source4/auth/ntlm/auth_server.c

    r414 r745  
    2222#include "includes.h"
    2323#include "auth/auth.h"
    24 #include "auth/ntlm/auth_proto.h"
    2524#include "auth/credentials/credentials.h"
    2625#include "libcli/security/security.h"
    27 #include "librpc/gen_ndr/ndr_samr.h"
    2826#include "libcli/smb_composite/smb_composite.h"
    2927#include "param/param.h"
     
    4341 * The challenge from the target server, when operating in security=server
    4442 **/
    45 static NTSTATUS server_get_challenge(struct auth_method_context *ctx, TALLOC_CTX *mem_ctx, DATA_BLOB *_blob)
     43static NTSTATUS server_get_challenge(struct auth_method_context *ctx, TALLOC_CTX *mem_ctx, uint8_t chal[8])
    4644{
    4745        struct smb_composite_connect io;
     
    5250        /* Make a connection to the target server, found by 'password server' in smb.conf */
    5351       
    54         lp_smbcli_options(ctx->auth_ctx->lp_ctx, &smb_options);
     52        lpcfg_smbcli_options(ctx->auth_ctx->lp_ctx, &smb_options);
    5553
    5654        /* Make a negprot, WITHOUT SPNEGO, so we get a challenge nice an easy */
     
    5856
    5957        /* Hope we don't get * (the default), as this won't work... */
    60         host_list = lp_passwordserver(ctx->auth_ctx->lp_ctx);
     58        host_list = lpcfg_passwordserver(ctx->auth_ctx->lp_ctx);
    6159        if (!host_list) {
    6260                return NT_STATUS_INTERNAL_ERROR;
     
    6664                return NT_STATUS_INTERNAL_ERROR;
    6765        }
    68         io.in.dest_ports = lp_smb_ports(ctx->auth_ctx->lp_ctx);
    69         io.in.socket_options = lp_socket_options(ctx->auth_ctx->lp_ctx);
    70         io.in.gensec_settings = lp_gensec_settings(mem_ctx, ctx->auth_ctx->lp_ctx);
     66        io.in.dest_ports = lpcfg_smb_ports(ctx->auth_ctx->lp_ctx);
     67        io.in.socket_options = lpcfg_socket_options(ctx->auth_ctx->lp_ctx);
     68        io.in.gensec_settings = lpcfg_gensec_settings(mem_ctx, ctx->auth_ctx->lp_ctx);
    7169
    7270        io.in.called_name = strupper_talloc(mem_ctx, io.in.dest_host);
     
    7573        io.in.credentials = cli_credentials_init_anon(mem_ctx);
    7674        cli_credentials_set_workstation(io.in.credentials,
    77                                         lp_netbios_name(ctx->auth_ctx->lp_ctx),
     75                                        lpcfg_netbios_name(ctx->auth_ctx->lp_ctx),
    7876                                        CRED_SPECIFIED);
    7977
     
    8482        io.in.options = smb_options;
    8583       
    86         io.in.iconv_convenience = lp_iconv_convenience(ctx->auth_ctx->lp_ctx);
    87         lp_smbcli_session_options(ctx->auth_ctx->lp_ctx, &io.in.session_options);
    88 
    89         status = smb_composite_connect(&io, mem_ctx, lp_resolve_context(ctx->auth_ctx->lp_ctx),
     84        lpcfg_smbcli_session_options(ctx->auth_ctx->lp_ctx, &io.in.session_options);
     85
     86        status = smb_composite_connect(&io, mem_ctx, lpcfg_resolve_context(ctx->auth_ctx->lp_ctx),
    9087                                       ctx->auth_ctx->event_ctx);
    9188        NT_STATUS_NOT_OK_RETURN(status);
    9289
    93         *_blob = io.out.tree->session->transport->negotiate.secblob;
     90        if (io.out.tree->session->transport->negotiate.secblob.length != 8) {
     91                return NT_STATUS_INTERNAL_ERROR;
     92        }
     93        memcpy(chal, io.out.tree->session->transport->negotiate.secblob.data, 8);
    9494        ctx->private_data = talloc_steal(ctx, io.out.tree->session);
    9595        return NT_STATUS_OK;
     
    112112                                      TALLOC_CTX *mem_ctx,
    113113                                      const struct auth_usersupplied_info *user_info,
    114                                       struct auth_serversupplied_info **_server_info)
     114                                      struct auth_user_info_dc **_user_info_dc)
    115115{
    116116        NTSTATUS nt_status;
    117         struct auth_serversupplied_info *server_info;
     117        struct auth_user_info_dc *user_info_dc;
     118        struct auth_user_info *info;
    118119        struct cli_credentials *creds;
    119120        struct smb_composite_sesssetup session_setup;
     
    148149        session_setup.in.credentials = creds;
    149150        session_setup.in.workgroup = ""; /* Only used with SPNEGO, which we are not doing */
    150         session_setup.in.gensec_settings = lp_gensec_settings(session, ctx->auth_ctx->lp_ctx);
     151        session_setup.in.gensec_settings = lpcfg_gensec_settings(session, ctx->auth_ctx->lp_ctx);
    151152
    152153        /* Check password with remove server - this should be async some day */
     
    157158        }
    158159
    159         server_info = talloc(mem_ctx, struct auth_serversupplied_info);
    160         NT_STATUS_HAVE_NO_MEMORY(server_info);
    161 
    162         server_info->account_sid = dom_sid_parse_talloc(server_info, SID_NT_ANONYMOUS);
    163         NT_STATUS_HAVE_NO_MEMORY(server_info->account_sid);
    164 
    165         /* is this correct? */
    166         server_info->primary_group_sid = dom_sid_parse_talloc(server_info, SID_BUILTIN_GUESTS);
    167         NT_STATUS_HAVE_NO_MEMORY(server_info->primary_group_sid);
    168 
    169         server_info->n_domain_groups = 0;
    170         server_info->domain_groups = NULL;
     160        user_info_dc = talloc(mem_ctx, struct auth_user_info_dc);
     161        NT_STATUS_HAVE_NO_MEMORY(user_info_dc);
     162
     163        user_info_dc->num_sids = 1;
     164
     165        /* This returns a pointer to a struct dom_sid, which is the
     166         * same as a 1 element list of struct dom_sid */
     167        user_info_dc->sids = dom_sid_parse_talloc(user_info_dc, SID_NT_ANONYMOUS);
     168        NT_STATUS_HAVE_NO_MEMORY(user_info_dc->sids);
    171169
    172170        /* annoying, but the Anonymous really does have a session key,
    173171           and it is all zeros! */
    174         server_info->user_session_key = data_blob(NULL, 0);
    175         server_info->lm_session_key = data_blob(NULL, 0);
    176 
    177         server_info->account_name = talloc_strdup(server_info, user_info->client.account_name);
    178         NT_STATUS_HAVE_NO_MEMORY(server_info->account_name);
    179 
    180         server_info->domain_name = talloc_strdup(server_info, user_info->client.domain_name);
    181         NT_STATUS_HAVE_NO_MEMORY(server_info->domain_name);
    182 
    183         server_info->full_name = NULL;
    184 
    185         server_info->logon_script = talloc_strdup(server_info, "");
    186         NT_STATUS_HAVE_NO_MEMORY(server_info->logon_script);
    187 
    188         server_info->profile_path = talloc_strdup(server_info, "");
    189         NT_STATUS_HAVE_NO_MEMORY(server_info->profile_path);
    190 
    191         server_info->home_directory = talloc_strdup(server_info, "");
    192         NT_STATUS_HAVE_NO_MEMORY(server_info->home_directory);
    193 
    194         server_info->home_drive = talloc_strdup(server_info, "");
    195         NT_STATUS_HAVE_NO_MEMORY(server_info->home_drive);
    196 
    197         server_info->last_logon = 0;
    198         server_info->last_logoff = 0;
    199         server_info->acct_expiry = 0;
    200         server_info->last_password_change = 0;
    201         server_info->allow_password_change = 0;
    202         server_info->force_password_change = 0;
    203 
    204         server_info->logon_count = 0;
    205         server_info->bad_password_count = 0;
    206 
    207         server_info->acct_flags = ACB_NORMAL;
    208 
    209         server_info->authenticated = false;
    210 
    211         *_server_info = server_info;
     172        user_info_dc->user_session_key = data_blob(NULL, 0);
     173        user_info_dc->lm_session_key = data_blob(NULL, 0);
     174
     175        user_info_dc->info = info = talloc_zero(user_info_dc, struct auth_user_info);
     176        NT_STATUS_HAVE_NO_MEMORY(user_info_dc->info);
     177
     178        info->account_name = talloc_strdup(user_info_dc, user_info->client.account_name);
     179        NT_STATUS_HAVE_NO_MEMORY(info->account_name);
     180
     181        info->domain_name = talloc_strdup(user_info_dc, user_info->client.domain_name);
     182        NT_STATUS_HAVE_NO_MEMORY(info->domain_name);
     183
     184        info->full_name = NULL;
     185
     186        info->logon_script = talloc_strdup(user_info_dc, "");
     187        NT_STATUS_HAVE_NO_MEMORY(info->logon_script);
     188
     189        info->profile_path = talloc_strdup(user_info_dc, "");
     190        NT_STATUS_HAVE_NO_MEMORY(info->profile_path);
     191
     192        info->home_directory = talloc_strdup(user_info_dc, "");
     193        NT_STATUS_HAVE_NO_MEMORY(info->home_directory);
     194
     195        info->home_drive = talloc_strdup(user_info_dc, "");
     196        NT_STATUS_HAVE_NO_MEMORY(info->home_drive);
     197
     198        info->last_logon = 0;
     199        info->last_logoff = 0;
     200        info->acct_expiry = 0;
     201        info->last_password_change = 0;
     202        info->allow_password_change = 0;
     203        info->force_password_change = 0;
     204
     205        info->logon_count = 0;
     206        info->bad_password_count = 0;
     207
     208        info->acct_flags = ACB_NORMAL;
     209
     210        info->authenticated = false;
     211
     212        *_user_info_dc = user_info_dc;
    212213
    213214        return nt_status;
  • trunk/server/source4/auth/ntlm/auth_simple.c

    r414 r745  
    2424#include "includes.h"
    2525#include "auth/auth.h"
    26 #include "lib/events/events.h"
    27 #include "param/param.h"
    28 #include "auth/session_proto.h"
    2926
    3027/*
     
    3936                                           const char *nt4_username,
    4037                                           const char *password,
     38                                           const uint32_t logon_parameters,
    4139                                           struct auth_session_info **session_info)
    4240{
    4341        struct auth_context *auth_context;
    4442        struct auth_usersupplied_info *user_info;
    45         struct auth_serversupplied_info *server_info;
     43        struct auth_user_info_dc *user_info_dc;
    4644        NTSTATUS nt_status;
    4745        TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx);
     
    6058        }
    6159
    62         user_info = talloc(tmp_ctx, struct auth_usersupplied_info);
     60        user_info = talloc_zero(tmp_ctx, struct auth_usersupplied_info);
    6361        if (!user_info) {
    6462                talloc_free(tmp_ctx);
     
    8280                USER_INFO_DONT_CHECK_UNIX_ACCOUNT;
    8381
    84         user_info->logon_parameters = 0;
     82        user_info->logon_parameters = logon_parameters |
     83                MSV1_0_CLEARTEXT_PASSWORD_ALLOWED |
     84                MSV1_0_CLEARTEXT_PASSWORD_SUPPLIED;
    8585
    86         nt_status = auth_check_password(auth_context, tmp_ctx, user_info, &server_info);
     86        nt_status = auth_check_password(auth_context, tmp_ctx, user_info, &user_info_dc);
    8787        if (!NT_STATUS_IS_OK(nt_status)) {
    8888                talloc_free(tmp_ctx);
     
    9191
    9292        if (session_info) {
    93                 nt_status = auth_generate_session_info(tmp_ctx, ev, lp_ctx, server_info, session_info);
     93                uint32_t flags = AUTH_SESSION_INFO_DEFAULT_GROUPS;
     94                if (user_info_dc->info->authenticated) {
     95                        flags |= AUTH_SESSION_INFO_AUTHENTICATED;
     96                }
     97                nt_status = auth_context->generate_session_info(tmp_ctx, auth_context,
     98                                                                user_info_dc,
     99                                                                flags,
     100                                                                session_info);
    94101
    95102                if (NT_STATUS_IS_OK(nt_status)) {
  • trunk/server/source4/auth/ntlm/auth_unix.c

    r414 r745  
    2424#include "auth/ntlm/auth_proto.h"
    2525#include "system/passwd.h" /* needed by some systems for struct passwd */
    26 #include "lib/socket/socket.h"
    27 #include "auth/ntlm/pam_errors.h"
     26#include "lib/socket/socket.h"
     27#include "lib/tsocket/tsocket.h"
     28#include "../libcli/auth/pam_errors.h"
    2829#include "param/param.h"
    2930
     
    3132 * except in case USER_INFO_DONT_CHECK_UNIX_ACCOUNT is set
    3233 */
    33 static NTSTATUS authunix_make_server_info(TALLOC_CTX *mem_ctx,
     34static NTSTATUS authunix_make_user_info_dc(TALLOC_CTX *mem_ctx,
    3435                                          const char *netbios_name,
    3536                                          const struct auth_usersupplied_info *user_info,
    3637                                          struct passwd *pwd,
    37                                           struct auth_serversupplied_info **_server_info)
    38 {
    39         struct auth_serversupplied_info *server_info;
     38                                          struct auth_user_info_dc **_user_info_dc)
     39{
     40        struct auth_user_info_dc *user_info_dc;
     41        struct auth_user_info *info;
    4042        NTSTATUS status;
    4143
    4244        /* This is a real, real hack */
    4345        if (pwd->pw_uid == 0) {
    44                 status = auth_system_server_info(mem_ctx, netbios_name, &server_info);
     46                status = auth_system_user_info_dc(mem_ctx, netbios_name, &user_info_dc);
    4547                if (!NT_STATUS_IS_OK(status)) {
    4648                        return status;
    4749                }
    4850
    49                 server_info->account_name = talloc_steal(server_info, pwd->pw_name);
    50                 NT_STATUS_HAVE_NO_MEMORY(server_info->account_name);
     51                user_info_dc->info = info = talloc_zero(user_info_dc, struct auth_user_info);
     52                NT_STATUS_HAVE_NO_MEMORY(user_info_dc->info);
     53
     54                info->account_name = talloc_steal(info, pwd->pw_name);
     55                NT_STATUS_HAVE_NO_MEMORY(info->account_name);
    5156               
    52                 server_info->domain_name = talloc_strdup(server_info, "unix");
    53                 NT_STATUS_HAVE_NO_MEMORY(server_info->domain_name);
     57                info->domain_name = talloc_strdup(info, "unix");
     58                NT_STATUS_HAVE_NO_MEMORY(info->domain_name);
    5459        } else {
    55                 server_info = talloc(mem_ctx, struct auth_serversupplied_info);
    56                 NT_STATUS_HAVE_NO_MEMORY(server_info);
     60                user_info_dc = talloc(mem_ctx, struct auth_user_info_dc);
     61                NT_STATUS_HAVE_NO_MEMORY(user_info_dc);
    5762               
    58                 server_info->authenticated = true;
     63                user_info_dc->info = info = talloc_zero(user_info_dc, struct auth_user_info);
     64                NT_STATUS_HAVE_NO_MEMORY(user_info_dc->info);
     65
     66                info->authenticated = true;
    5967               
    60                 server_info->account_name = talloc_steal(server_info, pwd->pw_name);
    61                 NT_STATUS_HAVE_NO_MEMORY(server_info->account_name);
     68                info->account_name = talloc_steal(info, pwd->pw_name);
     69                NT_STATUS_HAVE_NO_MEMORY(info->account_name);
    6270               
    63                 server_info->domain_name = talloc_strdup(server_info, "unix");
    64                 NT_STATUS_HAVE_NO_MEMORY(server_info->domain_name);
     71                info->domain_name = talloc_strdup(info, "unix");
     72                NT_STATUS_HAVE_NO_MEMORY(info->domain_name);
    6573
    6674                /* This isn't in any way correct.. */
    67                 server_info->account_sid = NULL;
    68                 server_info->primary_group_sid = NULL;
    69                 server_info->n_domain_groups = 0;
    70                 server_info->domain_groups = NULL;
    71         }
    72         server_info->user_session_key = data_blob(NULL,0);
    73         server_info->lm_session_key = data_blob(NULL,0);
    74 
    75         server_info->full_name = talloc_steal(server_info, pwd->pw_gecos);
    76         NT_STATUS_HAVE_NO_MEMORY(server_info->full_name);
    77         server_info->logon_script = talloc_strdup(server_info, "");
    78         NT_STATUS_HAVE_NO_MEMORY(server_info->logon_script);
    79         server_info->profile_path = talloc_strdup(server_info, "");
    80         NT_STATUS_HAVE_NO_MEMORY(server_info->profile_path);
    81         server_info->home_directory = talloc_strdup(server_info, "");
    82         NT_STATUS_HAVE_NO_MEMORY(server_info->home_directory);
    83         server_info->home_drive = talloc_strdup(server_info, "");
    84         NT_STATUS_HAVE_NO_MEMORY(server_info->home_drive);
    85 
    86         server_info->last_logon = 0;
    87         server_info->last_logoff = 0;
    88         server_info->acct_expiry = 0;
    89         server_info->last_password_change = 0;
    90         server_info->allow_password_change = 0;
    91         server_info->force_password_change = 0;
    92         server_info->logon_count = 0;
    93         server_info->bad_password_count = 0;
    94         server_info->acct_flags = 0;
    95 
    96         *_server_info = server_info;
     75                user_info_dc->num_sids = 0;
     76                user_info_dc->sids = NULL;
     77        }
     78        user_info_dc->user_session_key = data_blob(NULL,0);
     79        user_info_dc->lm_session_key = data_blob(NULL,0);
     80
     81        info->full_name = talloc_steal(info, pwd->pw_gecos);
     82        NT_STATUS_HAVE_NO_MEMORY(info->full_name);
     83        info->logon_script = talloc_strdup(info, "");
     84        NT_STATUS_HAVE_NO_MEMORY(info->logon_script);
     85        info->profile_path = talloc_strdup(info, "");
     86        NT_STATUS_HAVE_NO_MEMORY(info->profile_path);
     87        info->home_directory = talloc_strdup(info, "");
     88        NT_STATUS_HAVE_NO_MEMORY(info->home_directory);
     89        info->home_drive = talloc_strdup(info, "");
     90        NT_STATUS_HAVE_NO_MEMORY(info->home_drive);
     91
     92        info->last_logon = 0;
     93        info->last_logoff = 0;
     94        info->acct_expiry = 0;
     95        info->last_password_change = 0;
     96        info->allow_password_change = 0;
     97        info->force_password_change = 0;
     98        info->logon_count = 0;
     99        info->bad_password_count = 0;
     100        info->acct_flags = 0;
     101
     102        *_user_info_dc = user_info_dc;
    97103
    98104        return NT_STATUS_OK;
     
    430436}
    431437
    432 static NTSTATUS check_unix_password(TALLOC_CTX *ctx, struct loadparm_context *lp_ctx, 
     438static NTSTATUS check_unix_password(TALLOC_CTX *ctx, struct loadparm_context *lp_ctx,
    433439                                    const struct auth_usersupplied_info *user_info, struct passwd **pws)
    434440{
     
    459465         */
    460466
    461         nt_status = smb_pam_start(&pamh, user_info->mapped.account_name, user_info->remote_host ? user_info->remote_host->addr : NULL, pamconv);
     467        nt_status = smb_pam_start(&pamh, user_info->mapped.account_name,
     468                        user_info->remote_host ? tsocket_address_inet_addr_string(user_info->remote_host, ctx) : NULL, pamconv);
    462469        if (!NT_STATUS_IS_OK(nt_status)) {
    463470                return nt_status;
    464471        }
    465472
    466         nt_status = smb_pam_auth(pamh, lp_null_passwords(lp_ctx), user_info->mapped.account_name);
     473        nt_status = smb_pam_auth(pamh, lpcfg_null_passwords(lp_ctx), user_info->mapped.account_name);
    467474        if (!NT_STATUS_IS_OK(nt_status)) {
    468475                smb_pam_end(pamh);
     
    604611        struct passwd *pws;
    605612        NTSTATUS nt_status;
    606         int level = lp_passwordlevel(lp_ctx);
     613        int level = lpcfg_passwordlevel(lp_ctx);
    607614
    608615        *ret_passwd = NULL;
     
    707714
    708715        if (crypted[0] == '\0') {
    709                 if (!lp_null_passwords(lp_ctx)) {
     716                if (!lpcfg_null_passwords(lp_ctx)) {
    710717                        DEBUG(2, ("Disallowing %s with null password\n", username));
    711718                        return NT_STATUS_LOGON_FAILURE;
     
    792799                                        TALLOC_CTX *mem_ctx,
    793800                                        const struct auth_usersupplied_info *user_info,
    794                                         struct auth_serversupplied_info **server_info)
     801                                        struct auth_user_info_dc **user_info_dc)
    795802{
    796803        TALLOC_CTX *check_ctx;
     
    813820        }
    814821
    815         nt_status = authunix_make_server_info(mem_ctx, lp_netbios_name(ctx->auth_ctx->lp_ctx),
    816                                               user_info, pwd, server_info);
     822        nt_status = authunix_make_user_info_dc(mem_ctx, lpcfg_netbios_name(ctx->auth_ctx->lp_ctx),
     823                                              user_info, pwd, user_info_dc);
    817824        if (!NT_STATUS_IS_OK(nt_status)) {
    818825                talloc_free(check_ctx);
  • trunk/server/source4/auth/ntlm/auth_util.c

    r414 r745  
    2424#include "includes.h"
    2525#include "auth/auth.h"
    26 #include "auth/auth_proto.h"
    27 #include "libcli/security/security.h"
    2826#include "libcli/auth/libcli_auth.h"
    29 #include "dsdb/samdb/samdb.h"
    30 #include "auth/credentials/credentials.h"
    3127#include "param/param.h"
    3228
     
    3430 * which don't want to set a challenge
    3531 */
    36 NTSTATUS auth_get_challenge_not_implemented(struct auth_method_context *ctx, TALLOC_CTX *mem_ctx, DATA_BLOB *challenge)
     32NTSTATUS auth_get_challenge_not_implemented(struct auth_method_context *ctx, TALLOC_CTX *mem_ctx, uint8_t chal[8])
    3733{
    3834        /* we don't want to set a challenge */
     
    7975        }
    8076
    81         *user_info_mapped = talloc(mem_ctx, struct auth_usersupplied_info);
     77        *user_info_mapped = talloc_zero(mem_ctx, struct auth_usersupplied_info);
    8278        if (!*user_info_mapped) {
    8379                return NT_STATUS_NO_MEMORY;
     
    127123                case AUTH_PASSWORD_HASH:
    128124                {
    129                         const uint8_t *challenge;
     125                        uint8_t chal[8];
    130126                        DATA_BLOB chall_blob;
    131                         user_info_temp = talloc(mem_ctx, struct auth_usersupplied_info);
     127                        user_info_temp = talloc_zero(mem_ctx, struct auth_usersupplied_info);
    132128                        if (!user_info_temp) {
    133129                                return NT_STATUS_NO_MEMORY;
     
    139135                        user_info_temp->mapped_state = to_state;
    140136                       
    141                         nt_status = auth_get_challenge(auth_context, &challenge);
     137                        nt_status = auth_get_challenge(auth_context, chal);
    142138                        if (!NT_STATUS_IS_OK(nt_status)) {
    143139                                return nt_status;
    144140                        }
    145141                       
    146                         chall_blob = data_blob_talloc(mem_ctx, challenge, 8);
    147                         if (lp_client_ntlmv2_auth(auth_context->lp_ctx)) {
    148                                 DATA_BLOB names_blob = NTLMv2_generate_names_blob(mem_ctx,  lp_netbios_name(auth_context->lp_ctx), lp_workgroup(auth_context->lp_ctx));
     142                        chall_blob = data_blob_talloc(mem_ctx, chal, 8);
     143                        if (lpcfg_client_ntlmv2_auth(auth_context->lp_ctx)) {
     144                                DATA_BLOB names_blob = NTLMv2_generate_names_blob(mem_ctx,  lpcfg_netbios_name(auth_context->lp_ctx), lpcfg_workgroup(auth_context->lp_ctx));
    149145                                DATA_BLOB lmv2_response, ntlmv2_response, lmv2_session_key, ntlmv2_session_key;
    150146                               
     
    167163                        } else {
    168164                                DATA_BLOB blob = data_blob_talloc(mem_ctx, NULL, 24);
    169                                 SMBOWFencrypt(user_info_in->password.hash.nt->hash, challenge, blob.data);
     165                                SMBOWFencrypt(user_info_in->password.hash.nt->hash, chal, blob.data);
    170166
    171167                                user_info_temp->password.response.nt = blob;
    172                                 if (lp_client_lanman_auth(auth_context->lp_ctx) && user_info_in->password.hash.lanman) {
     168                                if (lpcfg_client_lanman_auth(auth_context->lp_ctx) && user_info_in->password.hash.lanman) {
    173169                                        DATA_BLOB lm_blob = data_blob_talloc(mem_ctx, NULL, 24);
    174                                         SMBOWFencrypt(user_info_in->password.hash.lanman->hash, challenge, blob.data);
     170                                        SMBOWFencrypt(user_info_in->password.hash.lanman->hash, chal, blob.data);
    175171                                        user_info_temp->password.response.lanman = lm_blob;
    176172                                } else {
     
    195191                        struct samr_Password nt;
    196192                       
    197                         user_info_temp = talloc(mem_ctx, struct auth_usersupplied_info);
     193                        user_info_temp = talloc_zero(mem_ctx, struct auth_usersupplied_info);
    198194                        if (!user_info_temp) {
    199195                                return NT_STATUS_NO_MEMORY;
     
    236232        return NT_STATUS_OK;
    237233}
    238 
    239 
    240 /**
    241  * Squash an NT_STATUS in line with security requirements.
    242  * In an attempt to avoid giving the whole game away when users
    243  * are authenticating, NT replaces both NT_STATUS_NO_SUCH_USER and
    244  * NT_STATUS_WRONG_PASSWORD with NT_STATUS_LOGON_FAILURE in certain situations
    245  * (session setups in particular).
    246  *
    247  * @param nt_status NTSTATUS input for squashing.
    248  * @return the 'squashed' nt_status
    249  **/
    250 _PUBLIC_ NTSTATUS auth_nt_status_squash(NTSTATUS nt_status)
    251 {
    252         if NT_STATUS_EQUAL(nt_status, NT_STATUS_NO_SUCH_USER) {
    253                 /* Match WinXP and don't give the game away */
    254                 return NT_STATUS_LOGON_FAILURE;
    255         } else if NT_STATUS_EQUAL(nt_status, NT_STATUS_WRONG_PASSWORD) {
    256                 /* Match WinXP and don't give the game away */
    257                 return NT_STATUS_LOGON_FAILURE;
    258         }
    259 
    260         return nt_status;
    261 }
  • trunk/server/source4/auth/ntlm/auth_winbind.c

    r414 r745  
    2626#include "auth/ntlm/auth_proto.h"
    2727#include "auth/auth_sam_reply.h"
    28 #include "nsswitch/winbind_client.h"
    29 #include "librpc/gen_ndr/ndr_netlogon.h"
    30 #include "librpc/gen_ndr/ndr_winbind.h"
     28#include "librpc/gen_ndr/ndr_winbind_c.h"
    3129#include "lib/messaging/irpc.h"
    3230#include "param/param.h"
    3331#include "nsswitch/libwbclient/wbclient.h"
    34 #include "libcli/security/dom_sid.h"
    35 
    36 static NTSTATUS get_info3_from_ndr(TALLOC_CTX *mem_ctx, struct smb_iconv_convenience *iconv_convenience, struct winbindd_response *response, struct netr_SamInfo3 *info3)
    37 {
    38         size_t len = response->length - sizeof(struct winbindd_response);
    39         if (len > 4) {
    40                 enum ndr_err_code ndr_err;
    41                 DATA_BLOB blob;
    42                 blob.length = len - 4;
    43                 blob.data = (uint8_t *)(((char *)response->extra_data.data) + 4);
    44 
    45                 ndr_err = ndr_pull_struct_blob(&blob, mem_ctx,
    46                                iconv_convenience, info3,
    47                               (ndr_pull_flags_fn_t)ndr_pull_netr_SamInfo3);
    48                 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
    49                         return ndr_map_error2ntstatus(ndr_err);
    50                 }
    51 
    52                 return NT_STATUS_OK;
    53         } else {
    54                 DEBUG(2, ("get_info3_from_ndr: No info3 struct found!\n"));
    55                 return NT_STATUS_UNSUCCESSFUL;
    56         }
    57 }
     32#include "libcli/security/security.h"
    5833
    5934static NTSTATUS get_info3_from_wbcAuthUserInfo(TALLOC_CTX *mem_ctx,
    60                                                struct smb_iconv_convenience *ic,
    6135                                               struct wbcAuthUserInfo *info,
    6236                                               struct netr_SamInfo3 *info3)
     
    6438        int i, j;
    6539        struct samr_RidWithAttribute *rids = NULL;
     40        struct dom_sid *user_sid;
     41        struct dom_sid *group_sid;
     42
     43        user_sid = (struct dom_sid *)(void *)&info->sids[0].sid;
     44        group_sid = (struct dom_sid *)(void *)&info->sids[1].sid;
    6645
    6746        info3->base.last_logon = info->logon_time;
     
    10382        }
    10483
    105         dom_sid_split_rid(mem_ctx, (struct dom_sid2 *) &info->sids[0].sid,
     84        dom_sid_split_rid(mem_ctx, user_sid,
    10685                          &info3->base.domain_sid,
    10786                          &info3->base.rid);
    108         dom_sid_split_rid(mem_ctx, (struct dom_sid2 *) &info->sids[1].sid, NULL,
     87        dom_sid_split_rid(mem_ctx, group_sid, NULL,
    10988                          &info3->base.primary_gid);
    11089
     
    11796
    11897        for (i = 2, j = 0; i < info->num_sids; ++i, ++j) {
     98                struct dom_sid *tmp_sid;
     99                tmp_sid = (struct dom_sid *)(void *)&info->sids[1].sid;
     100
    119101                rids[j].attributes = info->sids[i].attributes;
    120                 dom_sid_split_rid(mem_ctx,
    121                                   (struct dom_sid2 *) &info->sids[i].sid,
     102                dom_sid_split_rid(mem_ctx, tmp_sid,
    122103                                  NULL, &rids[j].rid);
    123104        }
     
    138119        /* TODO: maybe limit the user scope to remote users only */
    139120        return NT_STATUS_OK;
    140 }
    141 
    142 /*
    143  Authenticate a user with a challenge/response
    144  using the samba3 winbind protocol
    145 */
    146 static NTSTATUS winbind_check_password_samba3(struct auth_method_context *ctx,
    147                                               TALLOC_CTX *mem_ctx,
    148                                               const struct auth_usersupplied_info *user_info,
    149                                               struct auth_serversupplied_info **server_info)
    150 {
    151         struct winbindd_request request;
    152         struct winbindd_response response;
    153         NSS_STATUS result;
    154         NTSTATUS nt_status;
    155         struct netr_SamInfo3 info3;             
    156 
    157         /* Send off request */
    158         const struct auth_usersupplied_info *user_info_temp;   
    159         nt_status = encrypt_user_info(mem_ctx, ctx->auth_ctx,
    160                                       AUTH_PASSWORD_RESPONSE,
    161                                       user_info, &user_info_temp);
    162         if (!NT_STATUS_IS_OK(nt_status)) {
    163                 return nt_status;
    164         }
    165         user_info = user_info_temp;
    166 
    167         ZERO_STRUCT(request);
    168         ZERO_STRUCT(response);
    169         request.flags = WBFLAG_PAM_INFO3_NDR;
    170 
    171         request.data.auth_crap.logon_parameters = user_info->logon_parameters;
    172 
    173         safe_strcpy(request.data.auth_crap.user,
    174                        user_info->client.account_name, sizeof(fstring));
    175         safe_strcpy(request.data.auth_crap.domain,
    176                        user_info->client.domain_name, sizeof(fstring));
    177         safe_strcpy(request.data.auth_crap.workstation,
    178                        user_info->workstation_name, sizeof(fstring));
    179 
    180         memcpy(request.data.auth_crap.chal, ctx->auth_ctx->challenge.data.data, sizeof(request.data.auth_crap.chal));
    181 
    182         request.data.auth_crap.lm_resp_len = MIN(user_info->password.response.lanman.length,
    183                                                  sizeof(request.data.auth_crap.lm_resp));
    184         request.data.auth_crap.nt_resp_len = MIN(user_info->password.response.nt.length,
    185                                                  sizeof(request.data.auth_crap.nt_resp));
    186 
    187         memcpy(request.data.auth_crap.lm_resp, user_info->password.response.lanman.data,
    188                request.data.auth_crap.lm_resp_len);
    189         memcpy(request.data.auth_crap.nt_resp, user_info->password.response.nt.data,
    190                request.data.auth_crap.nt_resp_len);
    191 
    192         result = winbindd_request_response(WINBINDD_PAM_AUTH_CRAP, &request, &response);
    193 
    194         nt_status = NT_STATUS(response.data.auth.nt_status);
    195         NT_STATUS_NOT_OK_RETURN(nt_status);
    196 
    197         if (result == NSS_STATUS_SUCCESS && response.extra_data.data) {
    198                 union netr_Validation validation;
    199 
    200                 nt_status = get_info3_from_ndr(mem_ctx, lp_iconv_convenience(ctx->auth_ctx->lp_ctx), &response, &info3);
    201                 SAFE_FREE(response.extra_data.data);
    202                 NT_STATUS_NOT_OK_RETURN(nt_status);
    203 
    204                 validation.sam3 = &info3;
    205                 nt_status = make_server_info_netlogon_validation(mem_ctx,
    206                                                                  user_info->client.account_name,
    207                                                                  3, &validation,
    208                                                                  server_info);
    209                 return nt_status;
    210         } else if (result == NSS_STATUS_SUCCESS && !response.extra_data.data) {
    211                 DEBUG(0, ("Winbindd authenticated the user [%s]\\[%s], "
    212                           "but did not include the required info3 reply!\n",
    213                           user_info->client.domain_name, user_info->client.account_name));
    214                 return NT_STATUS_INSUFFICIENT_LOGON_INFO;
    215         } else if (NT_STATUS_IS_OK(nt_status)) {
    216                 DEBUG(1, ("Winbindd authentication for [%s]\\[%s] failed, "
    217                           "but no error code is available!\n",
    218                           user_info->client.domain_name, user_info->client.account_name));
    219                 return NT_STATUS_NO_LOGON_SERVERS;
    220         }
    221 
    222         return nt_status;
    223121}
    224122
     
    234132                                       TALLOC_CTX *mem_ctx,
    235133                                       const struct auth_usersupplied_info *user_info,
    236                                        struct auth_serversupplied_info **server_info)
     134                                       struct auth_user_info_dc **user_info_dc)
    237135{
    238136        NTSTATUS status;
    239         struct server_id *winbind_servers;
     137        struct dcerpc_binding_handle *irpc_handle;
    240138        struct winbind_check_password_state *s;
    241139        const struct auth_usersupplied_info *user_info_new;
    242140        struct netr_IdentityInfo *identity_info;
    243141
     142        if (!ctx->auth_ctx->msg_ctx) {
     143                DEBUG(0,("winbind_check_password: auth_context_create was called with out messaging context\n"));
     144                return NT_STATUS_INTERNAL_ERROR;
     145        }
     146
    244147        s = talloc(mem_ctx, struct winbind_check_password_state);
    245148        NT_STATUS_HAVE_NO_MEMORY(s);
    246149
    247         winbind_servers = irpc_servers_byname(ctx->auth_ctx->msg_ctx, s, "winbind_server");
    248         if ((winbind_servers == NULL) || (winbind_servers[0].id == 0)) {
     150        irpc_handle = irpc_binding_handle_by_name(s, ctx->auth_ctx->msg_ctx,
     151                                                  "winbind_server",
     152                                                  &ndr_table_winbind);
     153        if (irpc_handle == NULL) {
    249154                DEBUG(0, ("Winbind authentication for [%s]\\[%s] failed, "
    250155                          "no winbind_server running!\n",
     
    272177        } else {
    273178                struct netr_NetworkInfo *network_info;
    274                 const uint8_t *challenge;
     179                uint8_t chal[8];
    275180
    276181                status = encrypt_user_info(s, ctx->auth_ctx, AUTH_PASSWORD_RESPONSE,
     
    282187                NT_STATUS_HAVE_NO_MEMORY(network_info);
    283188
    284                 status = auth_get_challenge(ctx->auth_ctx, &challenge);
     189                status = auth_get_challenge(ctx->auth_ctx, chal);
    285190                NT_STATUS_NOT_OK_RETURN(status);
    286191
    287                 memcpy(network_info->challenge, challenge, sizeof(network_info->challenge));
     192                memcpy(network_info->challenge, chal, sizeof(network_info->challenge));
    288193
    289194                network_info->nt.length = user_info->password.response.nt.length;
     
    307212        s->req.in.validation_level      = 3;
    308213
    309         status = IRPC_CALL(ctx->auth_ctx->msg_ctx, winbind_servers[0],
    310                            winbind, WINBIND_SAMLOGON,
    311                            &s->req, s);
     214        status = dcerpc_winbind_SamLogon_r(irpc_handle, s, &s->req);
    312215        NT_STATUS_NOT_OK_RETURN(status);
    313216
    314         status = make_server_info_netlogon_validation(mem_ctx,
     217        status = make_user_info_dc_netlogon_validation(mem_ctx,
    315218                                                      user_info->client.account_name,
    316219                                                      s->req.in.validation_level,
    317220                                                      &s->req.out.validation,
    318                                                       server_info);
     221                                                      user_info_dc);
    319222        NT_STATUS_NOT_OK_RETURN(status);
    320223
     
    329232                                                TALLOC_CTX *mem_ctx,
    330233                                                const struct auth_usersupplied_info *user_info,
    331                                                 struct auth_serversupplied_info **server_info)
     234                                                struct auth_user_info_dc **user_info_dc)
    332235{
    333236        struct wbcAuthUserParams params;
     
    382285
    383286        wbc_status = wbcAuthenticateUserEx(&params, &info, &err);
    384         if (!WBC_ERROR_IS_OK(wbc_status)) {
     287        if (wbc_status == WBC_ERR_AUTH_ERROR) {
    385288                DEBUG(1, ("error was %s (0x%08x)\nerror message was '%s'\n",
    386289                      err->nt_string, err->nt_status, err->display_string));
     
    389292                wbcFreeMemory(err);
    390293                NT_STATUS_NOT_OK_RETURN(nt_status);
    391         }
    392         nt_status = get_info3_from_wbcAuthUserInfo(mem_ctx,
    393                                 lp_iconv_convenience(ctx->auth_ctx->lp_ctx),
    394                                 info, &info3);
     294        } else if (!WBC_ERROR_IS_OK(wbc_status)) {
     295                DEBUG(1, ("wbcAuthenticateUserEx: failed with %u - %s\n",
     296                        wbc_status, wbcErrorString(wbc_status)));
     297                return NT_STATUS_LOGON_FAILURE;
     298        }
     299        nt_status = get_info3_from_wbcAuthUserInfo(mem_ctx, info, &info3);
    395300        wbcFreeMemory(info);
    396301        NT_STATUS_NOT_OK_RETURN(nt_status);
    397302
    398303        validation.sam3 = &info3;
    399         nt_status = make_server_info_netlogon_validation(mem_ctx,
     304        nt_status = make_user_info_dc_netlogon_validation(mem_ctx,
    400305                                        user_info->client.account_name,
    401                                         3, &validation, server_info);
     306                                        3, &validation, user_info_dc);
    402307        return nt_status;
    403308
    404309}
    405 
    406 static const struct auth_operations winbind_samba3_ops = {
    407         .name           = "winbind_samba3",
    408         .get_challenge  = auth_get_challenge_not_implemented,
    409         .want_check     = winbind_want_check,
    410         .check_password = winbind_check_password_samba3
    411 };
    412310
    413311static const struct auth_operations winbind_ops = {
     
    429327        NTSTATUS ret;
    430328
    431         ret = auth_register(&winbind_samba3_ops);
    432         if (!NT_STATUS_IS_OK(ret)) {
    433                 DEBUG(0,("Failed to register 'winbind_samba3' auth backend!\n"));
    434                 return ret;
    435         }
    436 
    437329        ret = auth_register(&winbind_ops);
    438330        if (!NT_STATUS_IS_OK(ret)) {
Note: See TracChangeset for help on using the changeset viewer.