Changeset 745 for trunk/server/source4/auth/ntlm
- Timestamp:
- Nov 27, 2012, 4:43:17 PM (13 years ago)
- Location:
- trunk/server
- Files:
-
- 4 deleted
- 10 edited
- 2 copied
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 } -
trunk/server/source4/auth/ntlm/auth_anonymous.c
r414 r745 53 53 TALLOC_CTX *mem_ctx, 54 54 const struct auth_usersupplied_info *user_info, 55 struct auth_ serversupplied_info **_server_info)55 struct auth_user_info_dc **_user_info_dc) 56 56 { 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); 58 58 } 59 59 -
trunk/server/source4/auth/ntlm/auth_developer.c
r414 r745 24 24 #include "auth/ntlm/auth_proto.h" 25 25 #include "libcli/security/security.h" 26 #include "librpc/gen_ndr/ndr_samr.h"27 26 28 27 static NTSTATUS name_to_ntstatus_want_check(struct auth_method_context *ctx, … … 49 48 TALLOC_CTX *mem_ctx, 50 49 const struct auth_usersupplied_info *user_info, 51 struct auth_ serversupplied_info **_server_info)50 struct auth_user_info_dc **_user_info_dc) 52 51 { 53 52 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; 55 55 uint32_t error_num; 56 56 const char *user; … … 67 67 NT_STATUS_NOT_OK_RETURN(nt_status); 68 68 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); 81 77 82 78 /* annoying, but the Anonymous really does have a session key, 83 79 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; 129 128 130 129 return nt_status; … … 152 151 * @return NT_STATUS_UNSUCCESSFUL 153 152 **/ 154 static NTSTATUS fixed_challenge_get_challenge(struct auth_method_context *ctx, TALLOC_CTX *mem_ctx, DATA_BLOB *_blob) 155 { 156 DATA_BLOB blob; 153 static NTSTATUS fixed_challenge_get_challenge(struct auth_method_context *ctx, TALLOC_CTX *mem_ctx, uint8_t chal[8]) 154 { 157 155 const char *challenge = "I am a teapot"; 158 156 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 163 159 return NT_STATUS_OK; 164 160 } … … 175 171 TALLOC_CTX *mem_ctx, 176 172 const struct auth_usersupplied_info *user_info, 177 struct auth_ serversupplied_info **_server_info)173 struct auth_user_info_dc **_user_info_dc) 178 174 { 179 175 /* don't handle any users */ -
trunk/server/source4/auth/ntlm/auth_sam.c
r414 r745 21 21 22 22 #include "includes.h" 23 #include "librpc/gen_ndr/ndr_netlogon.h"24 23 #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" 27 27 #include "auth/auth.h" 28 28 #include "../libcli/auth/ntlm_check.h" … … 30 30 #include "auth/auth_sam.h" 31 31 #include "dsdb/samdb/samdb.h" 32 #include "libcli/security/security.h" 33 #include "libcli/ldap/ldap_ndr.h" 32 #include "dsdb/common/util.h" 34 33 #include "param/param.h" 34 #include "librpc/gen_ndr/ndr_irpc_c.h" 35 #include "lib/messaging/irpc.h" 35 36 36 37 extern const char *user_attrs[]; … … 49 50 50 51 /* 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)); 55 57 if (ret == LDB_ERR_NO_SUCH_OBJECT) { 56 58 DEBUG(3,("sam_search_user: Couldn't find user [%s] in samdb, under %s\n", … … 99 101 *user_sess_key = data_blob(NULL, 0); 100 102 status = hash_password_check(mem_ctx, 101 lp _lanman_auth(auth_context->lp_ctx),103 lpcfg_lanman_auth(auth_context->lp_ctx), 102 104 user_info->password.hash.lanman, 103 105 user_info->password.hash.nt, … … 109 111 case AUTH_PASSWORD_RESPONSE: 110 112 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), 113 115 user_info->logon_parameters, 114 116 &auth_context->challenge.data, … … 135 137 136 138 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 */ 143 static 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 137 170 138 171 static NTSTATUS authsam_authenticate(struct auth_context *auth_context, … … 146 179 NTSTATUS nt_status; 147 180 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); 149 182 150 183 /* Quit if the account was locked out. */ … … 165 198 NT_STATUS_NOT_OK_RETURN(nt_status); 166 199 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 167 219 nt_status = authsam_password_ok(auth_context, mem_ctx, 168 220 acct_flags, lm_pwd, nt_pwd, … … 170 222 NT_STATUS_NOT_OK_RETURN(nt_status); 171 223 172 nt_status = authsam_account_ok(mem_ctx, sam_ctx,224 nt_status = authsam_account_ok(mem_ctx, auth_context->sam_ctx, 173 225 user_info->logon_parameters, 174 226 domain_dn, … … 186 238 TALLOC_CTX *mem_ctx, 187 239 const struct auth_usersupplied_info *user_info, 188 struct auth_ serversupplied_info **server_info)240 struct auth_user_info_dc **user_info_dc) 189 241 { 190 242 NTSTATUS nt_status; 191 243 const char *account_name = user_info->mapped.account_name; 192 244 struct ldb_message *msg; 193 struct ldb_context *sam_ctx;194 245 struct ldb_dn *domain_dn; 195 246 DATA_BLOB user_sess_key, lm_sess_key; 196 247 TALLOC_CTX *tmp_ctx; 197 248 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 198 254 if (!account_name || !*account_name) { 199 255 /* 'not for me' */ … … 206 262 } 207 263 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); 215 265 if (domain_dn == NULL) { 216 266 talloc_free(tmp_ctx); … … 218 268 } 219 269 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); 221 271 if (!NT_STATUS_IS_OK(nt_status)) { 222 272 talloc_free(tmp_ctx); … … 224 274 } 225 275 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, 227 277 &user_sess_key, &lm_sess_key); 228 278 if (!NT_STATUS_IS_OK(nt_status)) { … … 231 281 } 232 282 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), 235 285 domain_dn, 236 286 msg, 237 287 user_sess_key, lm_sess_key, 238 server_info);288 user_info_dc); 239 289 if (!NT_STATUS_IS_OK(nt_status)) { 240 290 talloc_free(tmp_ctx); … … 242 292 } 243 293 244 talloc_steal(mem_ctx, * server_info);294 talloc_steal(mem_ctx, *user_info_dc); 245 295 talloc_free(tmp_ctx); 246 296 … … 272 322 } 273 323 274 is_local_name = lp _is_myname(ctx->auth_ctx->lp_ctx,324 is_local_name = lpcfg_is_myname(ctx->auth_ctx->lp_ctx, 275 325 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, 277 327 user_info->mapped.domain_name); 278 328 279 329 /* 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)) { 281 331 case ROLE_STANDALONE: 282 332 return NT_STATUS_OK; … … 299 349 } 300 350 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")); 302 352 return NT_STATUS_NOT_IMPLEMENTED; 303 353 } 304 354 305 355 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 */ 357 static 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 } 352 366 static const struct auth_operations sam_ignoredomain_ops = { 353 367 .name = "sam_ignoredomain", … … 355 369 .want_check = authsam_ignoredomain_want_check, 356 370 .check_password = authsam_check_password_internals, 357 .get_ server_info_principal = authsam_get_server_info_principal371 .get_user_info_dc_principal = authsam_get_user_info_dc_principal_wrapper 358 372 }; 359 373 … … 363 377 .want_check = authsam_want_check, 364 378 .check_password = authsam_check_password_internals, 365 .get_ server_info_principal = authsam_get_server_info_principal379 .get_user_info_dc_principal = authsam_get_user_info_dc_principal_wrapper 366 380 }; 367 381 -
trunk/server/source4/auth/ntlm/auth_server.c
r414 r745 22 22 #include "includes.h" 23 23 #include "auth/auth.h" 24 #include "auth/ntlm/auth_proto.h"25 24 #include "auth/credentials/credentials.h" 26 25 #include "libcli/security/security.h" 27 #include "librpc/gen_ndr/ndr_samr.h"28 26 #include "libcli/smb_composite/smb_composite.h" 29 27 #include "param/param.h" … … 43 41 * The challenge from the target server, when operating in security=server 44 42 **/ 45 static NTSTATUS server_get_challenge(struct auth_method_context *ctx, TALLOC_CTX *mem_ctx, DATA_BLOB *_blob)43 static NTSTATUS server_get_challenge(struct auth_method_context *ctx, TALLOC_CTX *mem_ctx, uint8_t chal[8]) 46 44 { 47 45 struct smb_composite_connect io; … … 52 50 /* Make a connection to the target server, found by 'password server' in smb.conf */ 53 51 54 lp _smbcli_options(ctx->auth_ctx->lp_ctx, &smb_options);52 lpcfg_smbcli_options(ctx->auth_ctx->lp_ctx, &smb_options); 55 53 56 54 /* Make a negprot, WITHOUT SPNEGO, so we get a challenge nice an easy */ … … 58 56 59 57 /* 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); 61 59 if (!host_list) { 62 60 return NT_STATUS_INTERNAL_ERROR; … … 66 64 return NT_STATUS_INTERNAL_ERROR; 67 65 } 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); 71 69 72 70 io.in.called_name = strupper_talloc(mem_ctx, io.in.dest_host); … … 75 73 io.in.credentials = cli_credentials_init_anon(mem_ctx); 76 74 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), 78 76 CRED_SPECIFIED); 79 77 … … 84 82 io.in.options = smb_options; 85 83 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), 90 87 ctx->auth_ctx->event_ctx); 91 88 NT_STATUS_NOT_OK_RETURN(status); 92 89 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); 94 94 ctx->private_data = talloc_steal(ctx, io.out.tree->session); 95 95 return NT_STATUS_OK; … … 112 112 TALLOC_CTX *mem_ctx, 113 113 const struct auth_usersupplied_info *user_info, 114 struct auth_ serversupplied_info **_server_info)114 struct auth_user_info_dc **_user_info_dc) 115 115 { 116 116 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; 118 119 struct cli_credentials *creds; 119 120 struct smb_composite_sesssetup session_setup; … … 148 149 session_setup.in.credentials = creds; 149 150 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); 151 152 152 153 /* Check password with remove server - this should be async some day */ … … 157 158 } 158 159 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); 171 169 172 170 /* annoying, but the Anonymous really does have a session key, 173 171 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; 212 213 213 214 return nt_status; -
trunk/server/source4/auth/ntlm/auth_simple.c
r414 r745 24 24 #include "includes.h" 25 25 #include "auth/auth.h" 26 #include "lib/events/events.h"27 #include "param/param.h"28 #include "auth/session_proto.h"29 26 30 27 /* … … 39 36 const char *nt4_username, 40 37 const char *password, 38 const uint32_t logon_parameters, 41 39 struct auth_session_info **session_info) 42 40 { 43 41 struct auth_context *auth_context; 44 42 struct auth_usersupplied_info *user_info; 45 struct auth_ serversupplied_info *server_info;43 struct auth_user_info_dc *user_info_dc; 46 44 NTSTATUS nt_status; 47 45 TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx); … … 60 58 } 61 59 62 user_info = talloc (tmp_ctx, struct auth_usersupplied_info);60 user_info = talloc_zero(tmp_ctx, struct auth_usersupplied_info); 63 61 if (!user_info) { 64 62 talloc_free(tmp_ctx); … … 82 80 USER_INFO_DONT_CHECK_UNIX_ACCOUNT; 83 81 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; 85 85 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); 87 87 if (!NT_STATUS_IS_OK(nt_status)) { 88 88 talloc_free(tmp_ctx); … … 91 91 92 92 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); 94 101 95 102 if (NT_STATUS_IS_OK(nt_status)) { -
trunk/server/source4/auth/ntlm/auth_unix.c
r414 r745 24 24 #include "auth/ntlm/auth_proto.h" 25 25 #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" 28 29 #include "param/param.h" 29 30 … … 31 32 * except in case USER_INFO_DONT_CHECK_UNIX_ACCOUNT is set 32 33 */ 33 static NTSTATUS authunix_make_ server_info(TALLOC_CTX *mem_ctx,34 static NTSTATUS authunix_make_user_info_dc(TALLOC_CTX *mem_ctx, 34 35 const char *netbios_name, 35 36 const struct auth_usersupplied_info *user_info, 36 37 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; 40 42 NTSTATUS status; 41 43 42 44 /* This is a real, real hack */ 43 45 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); 45 47 if (!NT_STATUS_IS_OK(status)) { 46 48 return status; 47 49 } 48 50 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); 51 56 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); 54 59 } 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); 57 62 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; 59 67 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); 62 70 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); 65 73 66 74 /* 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; 97 103 98 104 return NT_STATUS_OK; … … 430 436 } 431 437 432 static NTSTATUS check_unix_password(TALLOC_CTX *ctx, struct loadparm_context *lp_ctx, 438 static NTSTATUS check_unix_password(TALLOC_CTX *ctx, struct loadparm_context *lp_ctx, 433 439 const struct auth_usersupplied_info *user_info, struct passwd **pws) 434 440 { … … 459 465 */ 460 466 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); 462 469 if (!NT_STATUS_IS_OK(nt_status)) { 463 470 return nt_status; 464 471 } 465 472 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); 467 474 if (!NT_STATUS_IS_OK(nt_status)) { 468 475 smb_pam_end(pamh); … … 604 611 struct passwd *pws; 605 612 NTSTATUS nt_status; 606 int level = lp _passwordlevel(lp_ctx);613 int level = lpcfg_passwordlevel(lp_ctx); 607 614 608 615 *ret_passwd = NULL; … … 707 714 708 715 if (crypted[0] == '\0') { 709 if (!lp _null_passwords(lp_ctx)) {716 if (!lpcfg_null_passwords(lp_ctx)) { 710 717 DEBUG(2, ("Disallowing %s with null password\n", username)); 711 718 return NT_STATUS_LOGON_FAILURE; … … 792 799 TALLOC_CTX *mem_ctx, 793 800 const struct auth_usersupplied_info *user_info, 794 struct auth_ serversupplied_info **server_info)801 struct auth_user_info_dc **user_info_dc) 795 802 { 796 803 TALLOC_CTX *check_ctx; … … 813 820 } 814 821 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); 817 824 if (!NT_STATUS_IS_OK(nt_status)) { 818 825 talloc_free(check_ctx); -
trunk/server/source4/auth/ntlm/auth_util.c
r414 r745 24 24 #include "includes.h" 25 25 #include "auth/auth.h" 26 #include "auth/auth_proto.h"27 #include "libcli/security/security.h"28 26 #include "libcli/auth/libcli_auth.h" 29 #include "dsdb/samdb/samdb.h"30 #include "auth/credentials/credentials.h"31 27 #include "param/param.h" 32 28 … … 34 30 * which don't want to set a challenge 35 31 */ 36 NTSTATUS auth_get_challenge_not_implemented(struct auth_method_context *ctx, TALLOC_CTX *mem_ctx, DATA_BLOB *challenge)32 NTSTATUS auth_get_challenge_not_implemented(struct auth_method_context *ctx, TALLOC_CTX *mem_ctx, uint8_t chal[8]) 37 33 { 38 34 /* we don't want to set a challenge */ … … 79 75 } 80 76 81 *user_info_mapped = talloc (mem_ctx, struct auth_usersupplied_info);77 *user_info_mapped = talloc_zero(mem_ctx, struct auth_usersupplied_info); 82 78 if (!*user_info_mapped) { 83 79 return NT_STATUS_NO_MEMORY; … … 127 123 case AUTH_PASSWORD_HASH: 128 124 { 129 const uint8_t *challenge;125 uint8_t chal[8]; 130 126 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); 132 128 if (!user_info_temp) { 133 129 return NT_STATUS_NO_MEMORY; … … 139 135 user_info_temp->mapped_state = to_state; 140 136 141 nt_status = auth_get_challenge(auth_context, &challenge);137 nt_status = auth_get_challenge(auth_context, chal); 142 138 if (!NT_STATUS_IS_OK(nt_status)) { 143 139 return nt_status; 144 140 } 145 141 146 chall_blob = data_blob_talloc(mem_ctx, chal lenge, 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)); 149 145 DATA_BLOB lmv2_response, ntlmv2_response, lmv2_session_key, ntlmv2_session_key; 150 146 … … 167 163 } else { 168 164 DATA_BLOB blob = data_blob_talloc(mem_ctx, NULL, 24); 169 SMBOWFencrypt(user_info_in->password.hash.nt->hash, chal lenge, blob.data);165 SMBOWFencrypt(user_info_in->password.hash.nt->hash, chal, blob.data); 170 166 171 167 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) { 173 169 DATA_BLOB lm_blob = data_blob_talloc(mem_ctx, NULL, 24); 174 SMBOWFencrypt(user_info_in->password.hash.lanman->hash, chal lenge, blob.data);170 SMBOWFencrypt(user_info_in->password.hash.lanman->hash, chal, blob.data); 175 171 user_info_temp->password.response.lanman = lm_blob; 176 172 } else { … … 195 191 struct samr_Password nt; 196 192 197 user_info_temp = talloc (mem_ctx, struct auth_usersupplied_info);193 user_info_temp = talloc_zero(mem_ctx, struct auth_usersupplied_info); 198 194 if (!user_info_temp) { 199 195 return NT_STATUS_NO_MEMORY; … … 236 232 return NT_STATUS_OK; 237 233 } 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 users243 * are authenticating, NT replaces both NT_STATUS_NO_SUCH_USER and244 * NT_STATUS_WRONG_PASSWORD with NT_STATUS_LOGON_FAILURE in certain situations245 * (session setups in particular).246 *247 * @param nt_status NTSTATUS input for squashing.248 * @return the 'squashed' nt_status249 **/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 26 26 #include "auth/ntlm/auth_proto.h" 27 27 #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" 31 29 #include "lib/messaging/irpc.h" 32 30 #include "param/param.h" 33 31 #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" 58 33 59 34 static NTSTATUS get_info3_from_wbcAuthUserInfo(TALLOC_CTX *mem_ctx, 60 struct smb_iconv_convenience *ic,61 35 struct wbcAuthUserInfo *info, 62 36 struct netr_SamInfo3 *info3) … … 64 38 int i, j; 65 39 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; 66 45 67 46 info3->base.last_logon = info->logon_time; … … 103 82 } 104 83 105 dom_sid_split_rid(mem_ctx, (struct dom_sid2 *) &info->sids[0].sid,84 dom_sid_split_rid(mem_ctx, user_sid, 106 85 &info3->base.domain_sid, 107 86 &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, 109 88 &info3->base.primary_gid); 110 89 … … 117 96 118 97 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 119 101 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, 122 103 NULL, &rids[j].rid); 123 104 } … … 138 119 /* TODO: maybe limit the user scope to remote users only */ 139 120 return NT_STATUS_OK; 140 }141 142 /*143 Authenticate a user with a challenge/response144 using the samba3 winbind protocol145 */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;223 121 } 224 122 … … 234 132 TALLOC_CTX *mem_ctx, 235 133 const struct auth_usersupplied_info *user_info, 236 struct auth_ serversupplied_info **server_info)134 struct auth_user_info_dc **user_info_dc) 237 135 { 238 136 NTSTATUS status; 239 struct server_id *winbind_servers;137 struct dcerpc_binding_handle *irpc_handle; 240 138 struct winbind_check_password_state *s; 241 139 const struct auth_usersupplied_info *user_info_new; 242 140 struct netr_IdentityInfo *identity_info; 243 141 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 244 147 s = talloc(mem_ctx, struct winbind_check_password_state); 245 148 NT_STATUS_HAVE_NO_MEMORY(s); 246 149 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) { 249 154 DEBUG(0, ("Winbind authentication for [%s]\\[%s] failed, " 250 155 "no winbind_server running!\n", … … 272 177 } else { 273 178 struct netr_NetworkInfo *network_info; 274 const uint8_t *challenge;179 uint8_t chal[8]; 275 180 276 181 status = encrypt_user_info(s, ctx->auth_ctx, AUTH_PASSWORD_RESPONSE, … … 282 187 NT_STATUS_HAVE_NO_MEMORY(network_info); 283 188 284 status = auth_get_challenge(ctx->auth_ctx, &challenge);189 status = auth_get_challenge(ctx->auth_ctx, chal); 285 190 NT_STATUS_NOT_OK_RETURN(status); 286 191 287 memcpy(network_info->challenge, chal lenge, sizeof(network_info->challenge));192 memcpy(network_info->challenge, chal, sizeof(network_info->challenge)); 288 193 289 194 network_info->nt.length = user_info->password.response.nt.length; … … 307 212 s->req.in.validation_level = 3; 308 213 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); 312 215 NT_STATUS_NOT_OK_RETURN(status); 313 216 314 status = make_ server_info_netlogon_validation(mem_ctx,217 status = make_user_info_dc_netlogon_validation(mem_ctx, 315 218 user_info->client.account_name, 316 219 s->req.in.validation_level, 317 220 &s->req.out.validation, 318 server_info);221 user_info_dc); 319 222 NT_STATUS_NOT_OK_RETURN(status); 320 223 … … 329 232 TALLOC_CTX *mem_ctx, 330 233 const struct auth_usersupplied_info *user_info, 331 struct auth_ serversupplied_info **server_info)234 struct auth_user_info_dc **user_info_dc) 332 235 { 333 236 struct wbcAuthUserParams params; … … 382 285 383 286 wbc_status = wbcAuthenticateUserEx(¶ms, &info, &err); 384 if ( !WBC_ERROR_IS_OK(wbc_status)) {287 if (wbc_status == WBC_ERR_AUTH_ERROR) { 385 288 DEBUG(1, ("error was %s (0x%08x)\nerror message was '%s'\n", 386 289 err->nt_string, err->nt_status, err->display_string)); … … 389 292 wbcFreeMemory(err); 390 293 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); 395 300 wbcFreeMemory(info); 396 301 NT_STATUS_NOT_OK_RETURN(nt_status); 397 302 398 303 validation.sam3 = &info3; 399 nt_status = make_ server_info_netlogon_validation(mem_ctx,304 nt_status = make_user_info_dc_netlogon_validation(mem_ctx, 400 305 user_info->client.account_name, 401 3, &validation, server_info);306 3, &validation, user_info_dc); 402 307 return nt_status; 403 308 404 309 } 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_samba3411 };412 310 413 311 static const struct auth_operations winbind_ops = { … … 429 327 NTSTATUS ret; 430 328 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 437 329 ret = auth_register(&winbind_ops); 438 330 if (!NT_STATUS_IS_OK(ret)) {
Note:
See TracChangeset
for help on using the changeset viewer.