Changeset 745 for trunk/server/source4/auth/ntlm/auth.c
- Timestamp:
- Nov 27, 2012, 4:43:17 PM (13 years ago)
- Location:
- trunk/server
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/server
- Property svn:mergeinfo changed
/vendor/current merged: 581,587,591,594,597,600,615,618,740
- Property svn:mergeinfo changed
-
trunk/server/source4/auth/ntlm/auth.c
r414 r745 20 20 21 21 #include "includes.h" 22 #include <tevent.h> 23 #include "../lib/util/tevent_ntstatus.h" 22 24 #include "../lib/util/dlinklist.h" 23 25 #include "auth/auth.h" 24 26 #include "auth/ntlm/auth_proto.h" 25 #include "lib/events/events.h"26 27 #include "param/param.h" 28 #include "dsdb/samdb/samdb.h" 29 27 30 28 31 /*************************************************************************** … … 43 46 Set a fixed challenge 44 47 ***************************************************************************/ 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) 46 49 { 47 50 return auth_ctx->challenge.may_be_modified; … … 52 55 Returns a const char of length 8 bytes. 53 56 ****************************************************************************/ 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]) 55 58 { 56 59 NTSTATUS nt_status; 57 60 struct auth_method_context *method; 58 61 59 if (auth_ctx->challenge.data.length ) {62 if (auth_ctx->challenge.data.length == 8) { 60 63 DEBUG(5, ("auth_get_challenge: returning previous challenge by module %s (normal)\n", 61 64 auth_ctx->challenge.set_by)); 62 *_chal = auth_ctx->challenge.data.data;65 memcpy(chal, auth_ctx->challenge.data.data, 8); 63 66 return NT_STATUS_OK; 64 67 } 65 68 66 69 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); 70 71 if (NT_STATUS_EQUAL(nt_status, NT_STATUS_NOT_IMPLEMENTED)) { 71 72 continue; … … 74 75 NT_STATUS_NOT_OK_RETURN(nt_status); 75 76 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); 83 79 auth_ctx->challenge.set_by = method->ops->name; 84 80 … … 87 83 88 84 if (!auth_ctx->challenge.set_by) { 89 uint8_t chal[8];90 85 generate_random_buffer(chal, 8); 91 86 … … 100 95 auth_ctx->challenge.set_by)); 101 96 102 *_chal = auth_ctx->challenge.data.data;103 97 return NT_STATUS_OK; 104 98 } 105 99 106 100 /**************************************************************************** 107 Try to get a challenge out of the various authentication modules. 108 Returns a const char of length 8 bytes. 101 Used in the gensec_gssapi and gensec_krb5 server-side code, where the 102 PAC isn't available, and for tokenGroups in the DSDB stack. 103 104 Supply either a principal or a DN 109 105 ****************************************************************************/ 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) 114 111 { 115 112 NTSTATUS nt_status; … … 117 114 118 115 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) { 120 117 continue; 121 118 } 122 119 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); 124 121 if (NT_STATUS_EQUAL(nt_status, NT_STATUS_NOT_IMPLEMENTED)) { 125 122 continue; 126 123 } 127 124 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; 150 129 } 151 130 … … 155 134 * 156 135 * Check a user's password, as given in the user_info struct and return various 157 * interesting details in the server_infostruct.158 * 159 * The return value takes precedence over the contents of the server_info136 * interesting details in the user_info_dc struct. 137 * 138 * The return value takes precedence over the contents of the user_info_dc 160 139 * struct. When the return is other than NT_STATUS_OK the contents 161 140 * of that structure is undefined. … … 168 147 * @param user_info Contains the user supplied components, including the passwords. 169 148 * 170 * @param mem_ctx The parent memory context for the server_infostructure171 * 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, 173 152 * including a SAM_ACCOUNT struct describing the user. 174 153 * … … 180 159 TALLOC_CTX *mem_ctx, 181 160 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; 185 166 NTSTATUS status; 186 167 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 203 187 return status; 204 188 } 205 189 206 struct auth_check_password_ request{190 struct auth_check_password_state { 207 191 struct auth_context *auth_ctx; 208 192 const struct auth_usersupplied_info *user_info; 209 struct auth_ serversupplied_info *server_info;193 struct auth_user_info_dc *user_info_dc; 210 194 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;216 195 }; 217 196 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 197 static void auth_check_password_async_trigger(struct tevent_context *ev, 198 struct tevent_immediate *im, 199 void *private_data); 226 200 /** 227 201 * Check a user's Plaintext, LM or NTLM password. … … 229 203 * 230 204 * Check a user's password, as given in the user_info struct and return various 231 * interesting details in the server_infostruct.232 * 233 * The return value takes precedence over the contents of the server_info205 * interesting details in the user_info_dc struct. 206 * 207 * The return value takes precedence over the contents of the user_info_dc 234 208 * struct. When the return is other than NT_STATUS_OK the contents 235 209 * 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 236 214 * 237 215 * @param auth_ctx Supplies the challenges and some other data. … … 242 220 * @param user_info Contains the user supplied components, including the passwords. 243 221 * 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. 248 223 * 249 224 **/ 250 225 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; 256 233 /* if all the modules say 'not for me' this is reasonable */ 257 234 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 302 static 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; 258 311 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)) { 269 351 return; 270 352 } 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); 331 355 } 332 356 … … 335 359 * async receive function 336 360 * 337 * The return value takes precedence over the contents of the server_info361 * The return value takes precedence over the contents of the user_info_dc 338 362 * struct. When the return is other than NT_STATUS_OK the contents 339 363 * of that structure is undefined. 340 364 * 341 365 * 342 * @param req The async auth_check_password state, passes to the callers callback function343 * 344 * @param mem_ctx The parent memory context for the server_infostructure345 * 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, 347 371 * including a SAM_ACCOUNT struct describing the user. 348 372 * … … 351 375 **/ 352 376 353 _PUBLIC_ NTSTATUS auth_check_password_recv(struct auth_check_password_request*req,377 _PUBLIC_ NTSTATUS auth_check_password_recv(struct tevent_req *req, 354 378 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); 357 383 NTSTATUS status; 358 384 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 */ 411 static 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); 377 420 } 378 421 379 422 /*************************************************************************** 380 423 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 382 425 ***************************************************************************/ 383 426 _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) 388 432 { 389 433 int i; 390 434 struct auth_context *ctx; 391 435 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(); 398 437 399 438 if (!ev) { 400 439 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"));406 440 return NT_STATUS_INTERNAL_ERROR; 407 441 } … … 417 451 ctx->lp_ctx = lp_ctx; 418 452 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++) { 420 460 struct auth_method_context *method; 421 461 … … 434 474 } 435 475 436 if (!ctx->methods) {437 return NT_STATUS_INTERNAL_ERROR;438 }439 440 476 ctx->check_password = auth_check_password; 441 477 ctx->get_challenge = auth_get_challenge; 442 478 ctx->set_challenge = auth_context_set_challenge; 443 479 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; 445 482 446 483 *auth_ctx = ctx; … … 448 485 return NT_STATUS_OK; 449 486 } 487 488 const 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 450 505 /*************************************************************************** 451 506 Make a auth_info struct for the auth subsystem 452 507 - Uses default auth_methods, depending on server role and smb.conf settings 453 508 ***************************************************************************/ 454 _PUBLIC_ NTSTATUS auth_context_create(TALLOC_CTX *mem_ctx, 509 _PUBLIC_ NTSTATUS auth_context_create(TALLOC_CTX *mem_ctx, 455 510 struct tevent_context *ev, 456 511 struct messaging_context *msg, … … 458 513 struct auth_context **auth_ctx) 459 514 { 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 */ 536 NTSTATUS 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 } 475 556 476 557 /* the list of currently registered AUTH backends */ … … 545 626 sizeof(struct auth_context), 546 627 sizeof(struct auth_usersupplied_info), 547 sizeof(struct auth_ serversupplied_info)628 sizeof(struct auth_user_info_dc) 548 629 }; 549 630 … … 551 632 } 552 633 553 _PUBLIC_ NTSTATUS auth _init(void)634 _PUBLIC_ NTSTATUS auth4_init(void) 554 635 { 555 636 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 }; 564 640 565 641 if (initialized) return NT_STATUS_OK; … … 570 646 return NT_STATUS_OK; 571 647 } 572 573 NTSTATUS server_service_auth_init(void)574 {575 return auth_init();576 }
Note:
See TracChangeset
for help on using the changeset viewer.