Changeset 745 for trunk/server/source4/rpc_server/netlogon
- 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/rpc_server/netlogon/dcerpc_netlogon.c
r414 r745 1 /* 1 /* 2 2 Unix SMB/CIFS implementation. 3 3 … … 6 6 Copyright (C) Andrew Bartlett <abartlet@samba.org> 2004-2008 7 7 Copyright (C) Stefan Metzmacher <metze@samba.org> 2005 8 Copyright (C) Matthias Dieter Wallnöfer 2009 9 8 Copyright (C) Matthias Dieter Wallnöfer 2009-2010 9 10 10 This program is free software; you can redistribute it and/or modify 11 11 it under the terms of the GNU General Public License as published by 12 12 the Free Software Foundation; either version 3 of the License, or 13 13 (at your option) any later version. 14 14 15 15 This program is distributed in the hope that it will be useful, 16 16 but WITHOUT ANY WARRANTY; without even the implied warranty of 17 17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 18 GNU General Public License for more details. 19 19 20 20 You should have received a copy of the GNU General Public License 21 21 along with this program. If not, see <http://www.gnu.org/licenses/>. … … 29 29 #include "../lib/util/util_ldb.h" 30 30 #include "../libcli/auth/schannel.h" 31 #include "auth/gensec/schannel_state.h"32 31 #include "libcli/security/security.h" 33 32 #include "param/param.h" 34 33 #include "lib/messaging/irpc.h" 34 #include "librpc/gen_ndr/ndr_irpc_c.h" 35 #include "../libcli/ldap/ldap_ndr.h" 36 #include "cldap_server/cldap_server.h" 37 #include "lib/tsocket/tsocket.h" 38 #include "librpc/gen_ndr/ndr_netlogon.h" 35 39 #include "librpc/gen_ndr/ndr_irpc.h" 36 40 … … 40 44 }; 41 45 42 43 46 static NTSTATUS dcesrv_netr_ServerReqChallenge(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, 44 47 struct netr_ServerReqChallenge *r) … … 55 58 dce_call->context->private_data = NULL; 56 59 } 57 60 58 61 pipe_state = talloc(dce_call->context, struct netlogon_server_pipe_state); 59 62 NT_STATUS_HAVE_NO_MEMORY(pipe_state); … … 61 64 pipe_state->client_challenge = *r->in.credentials; 62 65 63 generate_random_buffer(pipe_state->server_challenge.data, 66 generate_random_buffer(pipe_state->server_challenge.data, 64 67 sizeof(pipe_state->server_challenge.data)); 65 68 … … 77 80 talloc_get_type(dce_call->context->private_data, struct netlogon_server_pipe_state); 78 81 struct netlogon_creds_CredentialState *creds; 79 struct ldb_context *schannel_ldb;80 82 struct ldb_context *sam_ctx; 81 83 struct samr_Password *mach_pwd; … … 84 86 struct ldb_message **msgs; 85 87 NTSTATUS nt_status; 86 const char *attrs[] = {"unicodePwd", "userAccountControl", 88 const char *attrs[] = {"unicodePwd", "userAccountControl", 87 89 "objectSid", NULL}; 88 90 … … 124 126 NETLOGON_NEG_AUTHENTICATED_RPC; 125 127 126 if (!pipe_state) { 127 DEBUG(1, ("No challenge requested by client, cannot authenticate\n")); 128 return NT_STATUS_ACCESS_DENIED; 129 } 130 131 sam_ctx = samdb_connect(mem_ctx, dce_call->event_ctx, dce_call->conn->dce_ctx->lp_ctx, 132 system_session(mem_ctx, dce_call->conn->dce_ctx->lp_ctx)); 128 switch (r->in.secure_channel_type) { 129 case SEC_CHAN_WKSTA: 130 case SEC_CHAN_DNS_DOMAIN: 131 case SEC_CHAN_DOMAIN: 132 case SEC_CHAN_BDC: 133 case SEC_CHAN_RODC: 134 break; 135 default: 136 DEBUG(1, ("Client asked for an invalid secure channel type: %d\n", 137 r->in.secure_channel_type)); 138 return NT_STATUS_INVALID_PARAMETER; 139 } 140 141 sam_ctx = samdb_connect(mem_ctx, dce_call->event_ctx, dce_call->conn->dce_ctx->lp_ctx, 142 system_session(dce_call->conn->dce_ctx->lp_ctx), 0); 133 143 if (sam_ctx == NULL) { 134 144 return NT_STATUS_INVALID_SYSTEM_SERVICE; … … 150 160 num_records = gendb_search(sam_ctx, mem_ctx, NULL, &msgs, 151 161 trust_dom_attrs, 152 "(&(trustPartner=%s)(objectclass=trustedDomain))", 162 "(&(trustPartner=%s)(objectclass=trustedDomain))", 153 163 encoded_account); 154 164 155 165 if (num_records == 0) { 156 DEBUG(3,("Couldn't find trust [%s] in samdb.\n", 166 DEBUG(3,("Couldn't find trust [%s] in samdb.\n", 157 167 encoded_account)); 158 return NT_STATUS_ ACCESS_DENIED;159 } 160 168 return NT_STATUS_NO_TRUST_SAM_ACCOUNT; 169 } 170 161 171 if (num_records > 1) { 162 172 DEBUG(0,("Found %d records matching user [%s]\n", num_records, r->in.account_name)); 163 173 return NT_STATUS_INTERNAL_DB_CORRUPTION; 164 174 } 165 175 166 176 flatname = ldb_msg_find_attr_as_string(msgs[0], "flatname", NULL); 167 177 if (!flatname) { 168 178 /* No flatname for this trust - we can't proceed */ 169 return NT_STATUS_ ACCESS_DENIED;179 return NT_STATUS_NO_TRUST_SAM_ACCOUNT; 170 180 } 171 181 account_name = talloc_asprintf(mem_ctx, "%s$", flatname); … … 174 184 return NT_STATUS_NO_MEMORY; 175 185 } 176 186 177 187 } else { 178 188 account_name = r->in.account_name; 179 189 } 180 190 181 191 /* pull the user attributes */ 182 192 num_records = gendb_search(sam_ctx, mem_ctx, NULL, &msgs, attrs, 183 "(&(sAMAccountName=%s)(objectclass=user))", 193 "(&(sAMAccountName=%s)(objectclass=user))", 184 194 ldb_binary_encode_string(mem_ctx, account_name)); 185 195 186 196 if (num_records == 0) { 187 DEBUG(3,("Couldn't find user [%s] in samdb.\n", 197 DEBUG(3,("Couldn't find user [%s] in samdb.\n", 188 198 r->in.account_name)); 189 return NT_STATUS_ ACCESS_DENIED;199 return NT_STATUS_NO_TRUST_SAM_ACCOUNT; 190 200 } 191 201 … … 195 205 } 196 206 197 198 207 user_account_control = ldb_msg_find_attr_as_uint(msgs[0], "userAccountControl", 0); 199 208 200 209 if (user_account_control & UF_ACCOUNTDISABLE) { 201 210 DEBUG(1, ("Account [%s] is disabled\n", r->in.account_name)); 202 return NT_STATUS_ ACCESS_DENIED;211 return NT_STATUS_NO_TRUST_SAM_ACCOUNT; 203 212 } 204 213 … … 206 215 if (!(user_account_control & UF_WORKSTATION_TRUST_ACCOUNT)) { 207 216 DEBUG(1, ("Client asked for a workstation secure channel, but is not a workstation (member server) acb flags: 0x%x\n", user_account_control)); 208 return NT_STATUS_ ACCESS_DENIED;209 } 210 } else if (r->in.secure_channel_type == SEC_CHAN_DOMAIN || 217 return NT_STATUS_NO_TRUST_SAM_ACCOUNT; 218 } 219 } else if (r->in.secure_channel_type == SEC_CHAN_DOMAIN || 211 220 r->in.secure_channel_type == SEC_CHAN_DNS_DOMAIN) { 212 221 if (!(user_account_control & UF_INTERDOMAIN_TRUST_ACCOUNT)) { 213 222 DEBUG(1, ("Client asked for a trusted domain secure channel, but is not a trusted domain: acb flags: 0x%x\n", user_account_control)); 214 215 return NT_STATUS_ ACCESS_DENIED;223 224 return NT_STATUS_NO_TRUST_SAM_ACCOUNT; 216 225 } 217 226 } else if (r->in.secure_channel_type == SEC_CHAN_BDC) { 218 227 if (!(user_account_control & UF_SERVER_TRUST_ACCOUNT)) { 219 228 DEBUG(1, ("Client asked for a server secure channel, but is not a server (domain controller): acb flags: 0x%x\n", user_account_control)); 220 return NT_STATUS_ACCESS_DENIED; 229 return NT_STATUS_NO_TRUST_SAM_ACCOUNT; 230 } 231 } else if (r->in.secure_channel_type == SEC_CHAN_RODC) { 232 if (!(user_account_control & UF_PARTIAL_SECRETS_ACCOUNT)) { 233 DEBUG(1, ("Client asked for a RODC secure channel, but is not a RODC: acb flags: 0x%x\n", user_account_control)); 234 return NT_STATUS_NO_TRUST_SAM_ACCOUNT; 221 235 } 222 236 } else { 223 DEBUG(1, ("Client asked for an invalid secure channel type: %d\n", 224 r->in.secure_channel_type)); 225 return NT_STATUS_ACCESS_DENIED; 226 } 227 228 *r->out.rid = samdb_result_rid_from_sid(mem_ctx, msgs[0], 237 /* we should never reach this */ 238 return NT_STATUS_INTERNAL_ERROR; 239 } 240 241 *r->out.rid = samdb_result_rid_from_sid(mem_ctx, msgs[0], 229 242 "objectSid", 0); 230 243 … … 234 247 } 235 248 236 creds = netlogon_creds_server_init(mem_ctx, 249 if (!pipe_state) { 250 DEBUG(1, ("No challenge requested by client, cannot authenticate\n")); 251 return NT_STATUS_ACCESS_DENIED; 252 } 253 254 creds = netlogon_creds_server_init(mem_ctx, 237 255 r->in.account_name, 238 256 r->in.computer_name, 239 257 r->in.secure_channel_type, 240 &pipe_state->client_challenge, 241 &pipe_state->server_challenge, 258 &pipe_state->client_challenge, 259 &pipe_state->server_challenge, 242 260 mach_pwd, 243 261 r->in.credentials, 244 262 r->out.return_credentials, 245 263 *r->in.negotiate_flags); 246 264 247 265 if (!creds) { 248 266 return NT_STATUS_ACCESS_DENIED; … … 251 269 creds->sid = samdb_result_dom_sid(creds, msgs[0], "objectSid"); 252 270 253 schannel_ldb = schannel_db_connect(mem_ctx, dce_call->event_ctx, dce_call->conn->dce_ctx->lp_ctx); 254 if (!schannel_ldb) { 255 return NT_STATUS_ACCESS_DENIED; 256 } 257 258 nt_status = schannel_store_session_key_ldb(schannel_ldb, mem_ctx, creds); 259 talloc_free(schannel_ldb); 271 nt_status = schannel_save_creds_state(mem_ctx, 272 lpcfg_private_dir(dce_call->conn->dce_ctx->lp_ctx), 273 creds); 260 274 261 275 return nt_status; 262 276 } 263 277 264 278 static NTSTATUS dcesrv_netr_ServerAuthenticate(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, 265 279 struct netr_ServerAuthenticate *r) … … 267 281 struct netr_ServerAuthenticate3 a; 268 282 uint32_t rid; 269 /* TODO: 283 /* TODO: 270 284 * negotiate_flags is used as an [in] parameter 271 285 * so it need to be initialised. … … 305 319 r3.out.negotiate_flags = r->out.negotiate_flags; 306 320 r3.out.rid = &rid; 307 321 308 322 return dcesrv_netr_ServerAuthenticate3(dce_call, mem_ctx, &r3); 309 323 } 310 324 311 325 /* 312 Validate an incoming authenticator against the credentials for the remote machine. 313 314 The credentials are (re)read and from the schannel database, and 315 written back after the caclulations are performed. 316 317 The creds_out parameter (if not NULL) returns the credentials, if 318 the caller needs some of that information. 319 320 */ 326 * NOTE: The following functions are nearly identical to the ones available in 327 * source3/rpc_server/srv_nelog_nt.c 328 * The reason we keep 2 copies is that they use different structures to 329 * represent the auth_info and the decrpc pipes. 330 */ 331 332 /* 333 * If schannel is required for this call test that it actually is available. 334 */ 335 static NTSTATUS schannel_check_required(struct dcerpc_auth *auth_info, 336 const char *computer_name, 337 bool integrity, bool privacy) 338 { 339 340 if (auth_info && auth_info->auth_type == DCERPC_AUTH_TYPE_SCHANNEL) { 341 if (!privacy && !integrity) { 342 return NT_STATUS_OK; 343 } 344 345 if ((!privacy && integrity) && 346 auth_info->auth_level == DCERPC_AUTH_LEVEL_INTEGRITY) { 347 return NT_STATUS_OK; 348 } 349 350 if ((privacy || integrity) && 351 auth_info->auth_level == DCERPC_AUTH_LEVEL_PRIVACY) { 352 return NT_STATUS_OK; 353 } 354 } 355 356 /* test didn't pass */ 357 DEBUG(0, ("schannel_check_required: [%s] is not using schannel\n", 358 computer_name)); 359 360 return NT_STATUS_ACCESS_DENIED; 361 } 362 321 363 static NTSTATUS dcesrv_netr_creds_server_step_check(struct dcesrv_call_state *dce_call, 322 TALLOC_CTX *mem_ctx, 364 TALLOC_CTX *mem_ctx, 323 365 const char *computer_name, 324 366 struct netr_Authenticator *received_authenticator, 325 367 struct netr_Authenticator *return_authenticator, 326 struct netlogon_creds_CredentialState **creds_out) 368 struct netlogon_creds_CredentialState **creds_out) 327 369 { 328 370 NTSTATUS nt_status; 329 struct ldb_context *ldb;330 bool schannel_global_required = false; /* Should be lp _schannel_server() == true */331 bool schannel_in_use = dce_call->conn->auth_state.auth_info 332 && dce_call->conn->auth_state.auth_info->auth_type == DCERPC_AUTH_TYPE_SCHANNEL333 && (dce_call->conn->auth_state.auth_info->auth_level == DCERPC_AUTH_LEVEL_INTEGRITY334 || dce_call->conn->auth_state.auth_info->auth_level == DCERPC_AUTH_LEVEL_PRIVACY);335 336 ldb = schannel_db_connect(mem_ctx, dce_call->event_ctx, dce_call->conn->dce_ctx->lp_ctx);337 if (!ldb) {338 return NT_STATUS_ACCESS_DENIED;339 } 340 nt_status = schannel_creds_server_step_check_ldb(ldb, mem_ctx, 341 computer_name,342 schannel_global_required,343 schannel_in_use,344 345 return_authenticator, creds_out);346 talloc_free(ldb);371 struct dcerpc_auth *auth_info = dce_call->conn->auth_state.auth_info; 372 bool schannel_global_required = false; /* Should be lpcfg_schannel_server() == true */ 373 374 if (schannel_global_required) { 375 nt_status = schannel_check_required(auth_info, 376 computer_name, 377 true, false); 378 if (!NT_STATUS_IS_OK(nt_status)) { 379 return nt_status; 380 } 381 } 382 383 nt_status = schannel_check_creds_state(mem_ctx, 384 lpcfg_private_dir(dce_call->conn->dce_ctx->lp_ctx), 385 computer_name, 386 received_authenticator, 387 return_authenticator, 388 creds_out); 347 389 return nt_status; 348 390 } 349 391 350 /* 392 /* 351 393 Change the machine account password for the currently connected 352 394 client. Supplies only the NT#. … … 358 400 struct netlogon_creds_CredentialState *creds; 359 401 struct ldb_context *sam_ctx; 402 const char * const attrs[] = { "unicodePwd", NULL }; 403 struct ldb_message **res; 404 struct samr_Password *oldNtHash; 360 405 NTSTATUS nt_status; 406 int ret; 361 407 362 408 nt_status = dcesrv_netr_creds_server_step_check(dce_call, 363 mem_ctx, 364 r->in.computer_name, 409 mem_ctx, 410 r->in.computer_name, 365 411 r->in.credential, r->out.return_authenticator, 366 412 &creds); 367 413 NT_STATUS_NOT_OK_RETURN(nt_status); 368 414 369 sam_ctx = samdb_connect(mem_ctx, dce_call->event_ctx, dce_call->conn->dce_ctx->lp_ctx, system_session( mem_ctx, dce_call->conn->dce_ctx->lp_ctx));415 sam_ctx = samdb_connect(mem_ctx, dce_call->event_ctx, dce_call->conn->dce_ctx->lp_ctx, system_session(dce_call->conn->dce_ctx->lp_ctx), 0); 370 416 if (sam_ctx == NULL) { 371 417 return NT_STATUS_INVALID_SYSTEM_SERVICE; … … 374 420 netlogon_creds_des_decrypt(creds, r->in.new_password); 375 421 422 /* fetch the old password hashes (the NT hash has to exist) */ 423 424 ret = gendb_search(sam_ctx, mem_ctx, NULL, &res, attrs, 425 "(&(objectClass=user)(objectSid=%s))", 426 ldap_encode_ndr_dom_sid(mem_ctx, creds->sid)); 427 if (ret != 1) { 428 return NT_STATUS_WRONG_PASSWORD; 429 } 430 431 nt_status = samdb_result_passwords(mem_ctx, 432 dce_call->conn->dce_ctx->lp_ctx, 433 res[0], NULL, &oldNtHash); 434 if (!NT_STATUS_IS_OK(nt_status) || !oldNtHash) { 435 return NT_STATUS_WRONG_PASSWORD; 436 } 437 376 438 /* Using the sid for the account as the key, set the password */ 377 nt_status = samdb_set_password_sid(sam_ctx, mem_ctx, 439 nt_status = samdb_set_password_sid(sam_ctx, mem_ctx, 378 440 creds->sid, 379 441 NULL, /* Don't have plaintext */ 380 442 NULL, r->in.new_password, 381 true, /* Password change */443 NULL, oldNtHash, /* Password change */ 382 444 NULL, NULL); 383 445 return nt_status; 384 446 } 385 447 386 /* 448 /* 387 449 Change the machine account password for the currently connected 388 450 client. Supplies new plaintext. … … 393 455 struct netlogon_creds_CredentialState *creds; 394 456 struct ldb_context *sam_ctx; 457 const char * const attrs[] = { "dBCSPwd", "unicodePwd", NULL }; 458 struct ldb_message **res; 459 struct samr_Password *oldLmHash, *oldNtHash; 395 460 NTSTATUS nt_status; 396 461 DATA_BLOB new_password; 462 int ret; 397 463 398 464 struct samr_CryptPassword password_buf; 399 465 400 466 nt_status = dcesrv_netr_creds_server_step_check(dce_call, 401 mem_ctx, 402 r->in.computer_name, 467 mem_ctx, 468 r->in.computer_name, 403 469 r->in.credential, r->out.return_authenticator, 404 470 &creds); 405 471 NT_STATUS_NOT_OK_RETURN(nt_status); 406 472 407 sam_ctx = samdb_connect(mem_ctx, dce_call->event_ctx, dce_call->conn->dce_ctx->lp_ctx, system_session( mem_ctx, dce_call->conn->dce_ctx->lp_ctx));473 sam_ctx = samdb_connect(mem_ctx, dce_call->event_ctx, dce_call->conn->dce_ctx->lp_ctx, system_session(dce_call->conn->dce_ctx->lp_ctx), 0); 408 474 if (sam_ctx == NULL) { 409 475 return NT_STATUS_INVALID_SYSTEM_SERVICE; … … 418 484 return NT_STATUS_WRONG_PASSWORD; 419 485 } 420 486 487 /* fetch the old password hashes (at least one of both has to exist) */ 488 489 ret = gendb_search(sam_ctx, mem_ctx, NULL, &res, attrs, 490 "(&(objectClass=user)(objectSid=%s))", 491 ldap_encode_ndr_dom_sid(mem_ctx, creds->sid)); 492 if (ret != 1) { 493 return NT_STATUS_WRONG_PASSWORD; 494 } 495 496 nt_status = samdb_result_passwords(mem_ctx, 497 dce_call->conn->dce_ctx->lp_ctx, 498 res[0], &oldLmHash, &oldNtHash); 499 if (!NT_STATUS_IS_OK(nt_status) || (!oldLmHash && !oldNtHash)) { 500 return NT_STATUS_WRONG_PASSWORD; 501 } 502 421 503 /* Using the sid for the account as the key, set the password */ 422 504 nt_status = samdb_set_password_sid(sam_ctx, mem_ctx, … … 424 506 &new_password, /* we have plaintext */ 425 507 NULL, NULL, 426 true, /* Password change */508 oldLmHash, oldNtHash, /* Password change */ 427 509 NULL, NULL); 428 510 return nt_status; … … 430 512 431 513 432 /* 433 netr_LogonUasLogon 514 /* 515 netr_LogonUasLogon 434 516 */ 435 517 static WERROR dcesrv_netr_LogonUasLogon(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, … … 440 522 441 523 442 /* 443 netr_LogonUasLogoff 524 /* 525 netr_LogonUasLogoff 444 526 */ 445 527 static WERROR dcesrv_netr_LogonUasLogoff(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, … … 450 532 451 533 452 /* 534 static NTSTATUS dcesrv_netr_LogonSamLogon_check(const struct netr_LogonSamLogonEx *r) 535 { 536 switch (r->in.logon_level) { 537 case NetlogonInteractiveInformation: 538 case NetlogonServiceInformation: 539 case NetlogonInteractiveTransitiveInformation: 540 case NetlogonServiceTransitiveInformation: 541 if (r->in.logon->password == NULL) { 542 return NT_STATUS_INVALID_PARAMETER; 543 } 544 545 switch (r->in.validation_level) { 546 case NetlogonValidationSamInfo: /* 2 */ 547 case NetlogonValidationSamInfo2: /* 3 */ 548 case NetlogonValidationSamInfo4: /* 6 */ 549 break; 550 default: 551 return NT_STATUS_INVALID_INFO_CLASS; 552 } 553 554 break; 555 case NetlogonNetworkInformation: 556 case NetlogonNetworkTransitiveInformation: 557 if (r->in.logon->network == NULL) { 558 return NT_STATUS_INVALID_PARAMETER; 559 } 560 561 switch (r->in.validation_level) { 562 case NetlogonValidationSamInfo: /* 2 */ 563 case NetlogonValidationSamInfo2: /* 3 */ 564 case NetlogonValidationSamInfo4: /* 6 */ 565 break; 566 default: 567 return NT_STATUS_INVALID_INFO_CLASS; 568 } 569 570 break; 571 572 case NetlogonGenericInformation: 573 if (r->in.logon->generic == NULL) { 574 return NT_STATUS_INVALID_PARAMETER; 575 } 576 577 switch (r->in.validation_level) { 578 /* TODO: case NetlogonValidationGenericInfo: 4 */ 579 case NetlogonValidationGenericInfo2: /* 5 */ 580 break; 581 default: 582 return NT_STATUS_INVALID_INFO_CLASS; 583 } 584 585 break; 586 default: 587 return NT_STATUS_INVALID_PARAMETER; 588 } 589 590 return NT_STATUS_OK; 591 } 592 593 /* 453 594 netr_LogonSamLogon_base 454 595 … … 462 603 struct auth_context *auth_context; 463 604 struct auth_usersupplied_info *user_info; 464 struct auth_ serversupplied_info *server_info;605 struct auth_user_info_dc *user_info_dc; 465 606 NTSTATUS nt_status; 466 607 static const char zeros[16]; … … 469 610 struct netr_SamInfo3 *sam3; 470 611 struct netr_SamInfo6 *sam6; 471 472 user_info = talloc(mem_ctx, struct auth_usersupplied_info); 612 613 *r->out.authoritative = 1; 614 615 user_info = talloc_zero(mem_ctx, struct auth_usersupplied_info); 473 616 NT_STATUS_HAVE_NO_MEMORY(user_info); 474 475 user_info->flags = 0;476 user_info->mapped_state = false;477 user_info->remote_host = NULL;478 617 479 618 switch (r->in.logon_level) { … … 483 622 case NetlogonServiceTransitiveInformation: 484 623 if (creds->negotiate_flags & NETLOGON_NEG_ARCFOUR) { 485 netlogon_creds_arcfour_crypt(creds, 624 netlogon_creds_arcfour_crypt(creds, 486 625 r->in.logon->password->lmpassword.hash, 487 626 sizeof(r->in.logon->password->lmpassword.hash)); 488 netlogon_creds_arcfour_crypt(creds, 627 netlogon_creds_arcfour_crypt(creds, 489 628 r->in.logon->password->ntpassword.hash, 490 629 sizeof(r->in.logon->password->ntpassword.hash)); … … 495 634 496 635 /* TODO: we need to deny anonymous access here */ 497 nt_status = auth_context_create(mem_ctx, 636 nt_status = auth_context_create(mem_ctx, 498 637 dce_call->event_ctx, dce_call->msg_ctx, 499 638 dce_call->conn->dce_ctx->lp_ctx, … … 505 644 user_info->client.domain_name = r->in.logon->password->identity_info.domain_name.string; 506 645 user_info->workstation_name = r->in.logon->password->identity_info.workstation.string; 507 646 508 647 user_info->flags |= USER_INFO_INTERACTIVE_LOGON; 509 648 user_info->password_state = AUTH_PASSWORD_HASH; … … 522 661 523 662 /* TODO: we need to deny anonymous access here */ 524 nt_status = auth_context_create(mem_ctx, 663 nt_status = auth_context_create(mem_ctx, 525 664 dce_call->event_ctx, dce_call->msg_ctx, 526 665 dce_call->conn->dce_ctx->lp_ctx, … … 535 674 user_info->client.domain_name = r->in.logon->network->identity_info.domain_name.string; 536 675 user_info->workstation_name = r->in.logon->network->identity_info.workstation.string; 537 676 538 677 user_info->password_state = AUTH_PASSWORD_RESPONSE; 539 678 user_info->password.response.lanman = data_blob_talloc(mem_ctx, r->in.logon->network->lm.data, r->in.logon->network->lm.length); 540 679 user_info->password.response.nt = data_blob_talloc(mem_ctx, r->in.logon->network->nt.data, r->in.logon->network->nt.length); 541 680 542 681 break; 543 682 544 683 545 684 case NetlogonGenericInformation: 546 685 { 547 686 if (creds->negotiate_flags & NETLOGON_NEG_ARCFOUR) { 548 netlogon_creds_arcfour_crypt(creds, 687 netlogon_creds_arcfour_crypt(creds, 549 688 r->in.logon->generic->data, r->in.logon->generic->length); 550 689 } else { … … 555 694 if (strcmp(r->in.logon->generic->package_name.string, "Kerberos") == 0) { 556 695 NTSTATUS status; 557 struct server_id *kdc;696 struct dcerpc_binding_handle *irpc_handle; 558 697 struct kdc_check_generic_kerberos check; 559 698 struct netr_GenericInfo2 *generic = talloc_zero(mem_ctx, struct netr_GenericInfo2); 560 699 NT_STATUS_HAVE_NO_MEMORY(generic); 561 700 *r->out.authoritative = 1; 562 701 563 702 /* TODO: Describe and deal with these flags */ 564 703 *r->out.flags = 0; 565 704 566 705 r->out.validation->generic = generic; 567 568 kdc = irpc_servers_byname(dce_call->msg_ctx, mem_ctx, "kdc_server"); 569 if ((kdc == NULL) || (kdc[0].id == 0)) { 706 707 irpc_handle = irpc_binding_handle_by_name(mem_ctx, 708 dce_call->msg_ctx, 709 "kdc_server", 710 &ndr_table_irpc); 711 if (irpc_handle == NULL) { 570 712 return NT_STATUS_NO_LOGON_SERVERS; 571 713 } 572 573 check.in.generic_request = 714 715 check.in.generic_request = 574 716 data_blob_const(r->in.logon->generic->data, 575 717 r->in.logon->generic->length); 576 577 status = irpc_call(dce_call->msg_ctx, kdc[0],578 &ndr_table_irpc, NDR_KDC_CHECK_GENERIC_KERBEROS,579 &check, mem_ctx);718 719 status = dcerpc_kdc_check_generic_kerberos_r(irpc_handle, 720 mem_ctx, 721 &check); 580 722 if (!NT_STATUS_IS_OK(status)) { 581 723 return status; … … 592 734 return NT_STATUS_INVALID_PARAMETER; 593 735 } 594 595 nt_status = auth_check_password(auth_context, mem_ctx, user_info, &server_info); 736 737 nt_status = auth_check_password(auth_context, mem_ctx, user_info, &user_info_dc); 738 /* TODO: set *r->out.authoritative = 0 on specific errors */ 596 739 NT_STATUS_NOT_OK_RETURN(nt_status); 597 740 598 nt_status = auth_convert_server_info_sambaseinfo(mem_ctx, server_info, &sam); 599 NT_STATUS_NOT_OK_RETURN(nt_status); 741 switch (r->in.validation_level) { 742 case 2: 743 nt_status = auth_convert_user_info_dc_sambaseinfo(mem_ctx, user_info_dc, &sam); 744 NT_STATUS_NOT_OK_RETURN(nt_status); 745 746 sam2 = talloc_zero(mem_ctx, struct netr_SamInfo2); 747 NT_STATUS_HAVE_NO_MEMORY(sam2); 748 sam2->base = *sam; 749 750 /* And put into the talloc tree */ 751 talloc_steal(sam2, sam); 752 r->out.validation->sam2 = sam2; 753 754 sam = &sam2->base; 755 break; 756 757 case 3: 758 nt_status = auth_convert_user_info_dc_saminfo3(mem_ctx, 759 user_info_dc, 760 &sam3); 761 NT_STATUS_NOT_OK_RETURN(nt_status); 762 763 r->out.validation->sam3 = sam3; 764 765 sam = &sam3->base; 766 break; 767 768 case 6: 769 nt_status = auth_convert_user_info_dc_saminfo3(mem_ctx, 770 user_info_dc, 771 &sam3); 772 NT_STATUS_NOT_OK_RETURN(nt_status); 773 774 sam6 = talloc_zero(mem_ctx, struct netr_SamInfo6); 775 NT_STATUS_HAVE_NO_MEMORY(sam6); 776 sam6->base = sam3->base; 777 sam = &sam6->base; 778 sam6->sidcount = sam3->sidcount; 779 sam6->sids = sam3->sids; 780 781 sam6->dns_domainname.string = lpcfg_dnsdomain(dce_call->conn->dce_ctx->lp_ctx); 782 sam6->principle.string = talloc_asprintf(mem_ctx, "%s@%s", 783 sam->account_name.string, sam6->dns_domainname.string); 784 NT_STATUS_HAVE_NO_MEMORY(sam6->principle.string); 785 /* And put into the talloc tree */ 786 talloc_steal(sam6, sam3); 787 788 r->out.validation->sam6 = sam6; 789 break; 790 791 default: 792 return NT_STATUS_INVALID_INFO_CLASS; 793 } 600 794 601 795 /* Don't crypt an all-zero key, it would give away the NETLOGON pipe session key */ … … 605 799 /* This key is sent unencrypted without the ARCFOUR flag set */ 606 800 if (creds->negotiate_flags & NETLOGON_NEG_ARCFOUR) { 607 netlogon_creds_arcfour_crypt(creds, 608 sam->key.key, 801 netlogon_creds_arcfour_crypt(creds, 802 sam->key.key, 609 803 sizeof(sam->key.key)); 610 804 } … … 616 810 memcmp(sam->LMSessKey.key, zeros, sizeof(sam->LMSessKey.key)) != 0) { 617 811 if (creds->negotiate_flags & NETLOGON_NEG_ARCFOUR) { 618 netlogon_creds_arcfour_crypt(creds, 619 sam->LMSessKey.key, 812 netlogon_creds_arcfour_crypt(creds, 813 sam->LMSessKey.key, 620 814 sizeof(sam->LMSessKey.key)); 621 815 } else { 622 netlogon_creds_des_encrypt_LMKey(creds, 816 netlogon_creds_des_encrypt_LMKey(creds, 623 817 &sam->LMSessKey); 624 818 } 625 819 } 626 627 switch (r->in.validation_level) {628 case 2:629 sam2 = talloc_zero(mem_ctx, struct netr_SamInfo2);630 NT_STATUS_HAVE_NO_MEMORY(sam2);631 sam2->base = *sam;632 r->out.validation->sam2 = sam2;633 break;634 635 case 3:636 sam3 = talloc_zero(mem_ctx, struct netr_SamInfo3);637 NT_STATUS_HAVE_NO_MEMORY(sam3);638 sam3->base = *sam;639 r->out.validation->sam3 = sam3;640 break;641 642 case 6:643 sam6 = talloc_zero(mem_ctx, struct netr_SamInfo6);644 NT_STATUS_HAVE_NO_MEMORY(sam6);645 sam6->base = *sam;646 sam6->forest.string = lp_realm(dce_call->conn->dce_ctx->lp_ctx);647 sam6->principle.string = talloc_asprintf(mem_ctx, "%s@%s",648 sam->account_name.string, sam6->forest.string);649 NT_STATUS_HAVE_NO_MEMORY(sam6->principle.string);650 r->out.validation->sam6 = sam6;651 break;652 653 default:654 break;655 }656 657 *r->out.authoritative = 1;658 820 659 821 /* TODO: Describe and deal with these flags */ … … 664 826 665 827 static NTSTATUS dcesrv_netr_LogonSamLogonEx(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, 666 struct netr_LogonSamLogonEx *r) 828 struct netr_LogonSamLogonEx *r) 667 829 { 668 830 NTSTATUS nt_status; 669 831 struct netlogon_creds_CredentialState *creds; 670 struct ldb_context *ldb = schannel_db_connect(mem_ctx, dce_call->event_ctx, dce_call->conn->dce_ctx->lp_ctx); 671 if (!ldb) { 672 return NT_STATUS_ACCESS_DENIED; 673 } 674 675 nt_status = schannel_fetch_session_key_ldb(ldb, mem_ctx, r->in.computer_name, &creds); 832 833 *r->out.authoritative = 1; 834 835 nt_status = dcesrv_netr_LogonSamLogon_check(r); 836 if (!NT_STATUS_IS_OK(nt_status)) { 837 return nt_status; 838 } 839 840 nt_status = schannel_get_creds_state(mem_ctx, 841 lpcfg_private_dir(dce_call->conn->dce_ctx->lp_ctx), 842 r->in.computer_name, &creds); 676 843 if (!NT_STATUS_IS_OK(nt_status)) { 677 844 return nt_status; … … 685 852 } 686 853 687 /* 854 /* 688 855 netr_LogonSamLogonWithFlags 689 856 … … 697 864 698 865 struct netr_Authenticator *return_authenticator; 699 700 return_authenticator = talloc(mem_ctx, struct netr_Authenticator);701 NT_STATUS_HAVE_NO_MEMORY(return_authenticator);702 703 nt_status = dcesrv_netr_creds_server_step_check(dce_call,704 mem_ctx,705 r->in.computer_name,706 r->in.credential, return_authenticator,707 &creds);708 NT_STATUS_NOT_OK_RETURN(nt_status);709 866 710 867 ZERO_STRUCT(r2); … … 720 877 r2.out.flags = r->out.flags; 721 878 879 *r->out.authoritative = 1; 880 881 nt_status = dcesrv_netr_LogonSamLogon_check(&r2); 882 if (!NT_STATUS_IS_OK(nt_status)) { 883 return nt_status; 884 } 885 886 return_authenticator = talloc(mem_ctx, struct netr_Authenticator); 887 NT_STATUS_HAVE_NO_MEMORY(return_authenticator); 888 889 nt_status = dcesrv_netr_creds_server_step_check(dce_call, 890 mem_ctx, 891 r->in.computer_name, 892 r->in.credential, return_authenticator, 893 &creds); 894 NT_STATUS_NOT_OK_RETURN(nt_status); 895 722 896 nt_status = dcesrv_netr_LogonSamLogon_base(dce_call, mem_ctx, &r2, creds); 723 897 … … 727 901 } 728 902 729 /* 903 /* 730 904 netr_LogonSamLogon 731 905 */ … … 759 933 760 934 761 /* 762 netr_LogonSamLogoff 935 /* 936 netr_LogonSamLogoff 763 937 */ 764 938 static NTSTATUS dcesrv_netr_LogonSamLogoff(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, … … 770 944 771 945 772 /* 773 netr_DatabaseDeltas 946 /* 947 netr_DatabaseDeltas 774 948 */ 775 949 static NTSTATUS dcesrv_netr_DatabaseDeltas(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, … … 780 954 781 955 782 /* 783 netr_DatabaseSync2 956 /* 957 netr_DatabaseSync2 784 958 */ 785 959 static NTSTATUS dcesrv_netr_DatabaseSync2(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, … … 791 965 792 966 793 /* 794 netr_DatabaseSync 967 /* 968 netr_DatabaseSync 795 969 */ 796 970 static NTSTATUS dcesrv_netr_DatabaseSync(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, … … 818 992 819 993 820 /* 821 netr_AccountDeltas 994 /* 995 netr_AccountDeltas 822 996 */ 823 997 static NTSTATUS dcesrv_netr_AccountDeltas(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, … … 829 1003 830 1004 831 /* 832 netr_AccountSync 1005 /* 1006 netr_AccountSync 833 1007 */ 834 1008 static NTSTATUS dcesrv_netr_AccountSync(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, … … 840 1014 841 1015 842 /* 843 netr_GetDcName 1016 /* 1017 netr_GetDcName 844 1018 */ 845 1019 static WERROR dcesrv_netr_GetDcName(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, … … 853 1027 const char *dcname; 854 1028 1029 /* 1030 * [MS-NRPC] 3.5.5.3.4 NetrGetDCName says 1031 * that the domainname needs to be a valid netbios domain 1032 * name, if it is not NULL. 1033 */ 1034 if (r->in.domainname) { 1035 const char *dot = strchr(r->in.domainname, '.'); 1036 size_t len = strlen(r->in.domainname); 1037 1038 if (dot || len > 15) { 1039 return WERR_DCNOTFOUND; 1040 } 1041 1042 /* 1043 * TODO: Should we also varify that only valid 1044 * netbios name characters are used? 1045 */ 1046 } 1047 855 1048 sam_ctx = samdb_connect(mem_ctx, dce_call->event_ctx, 856 1049 dce_call->conn->dce_ctx->lp_ctx, 857 dce_call->conn->auth_state.session_info );1050 dce_call->conn->auth_state.session_info, 0); 858 1051 if (sam_ctx == NULL) { 859 1052 return WERR_DS_UNAVAILABLE; … … 876 1069 */ 877 1070 dcname = talloc_asprintf(mem_ctx, "\\\\%s", 878 lp _netbios_name(dce_call->conn->dce_ctx->lp_ctx));1071 lpcfg_netbios_name(dce_call->conn->dce_ctx->lp_ctx)); 879 1072 W_ERROR_HAVE_NO_MEMORY(dcname); 880 1073 … … 884 1077 885 1078 886 /* 887 netr_LogonControl2Ex 1079 /* 1080 netr_LogonControl2Ex 888 1081 */ 889 1082 static WERROR dcesrv_netr_LogonControl2Ex(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, … … 894 1087 895 1088 896 /* 897 netr_LogonControl 1089 /* 1090 netr_LogonControl 898 1091 */ 899 1092 static WERROR dcesrv_netr_LogonControl(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, … … 923 1116 924 1117 925 /* 926 netr_LogonControl2 1118 /* 1119 netr_LogonControl2 927 1120 */ 928 1121 static WERROR dcesrv_netr_LogonControl2(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, … … 945 1138 } 946 1139 947 948 /* 949 netr_GetAnyDCName 1140 static WERROR fill_trusted_domains_array(TALLOC_CTX *mem_ctx, 1141 struct ldb_context *sam_ctx, 1142 struct netr_DomainTrustList *trusts, 1143 uint32_t trust_flags); 1144 1145 /* 1146 netr_GetAnyDCName 950 1147 */ 951 1148 static WERROR dcesrv_netr_GetAnyDCName(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, 952 1149 struct netr_GetAnyDCName *r) 953 1150 { 954 struct netr_GetDcName r2; 1151 struct netr_DomainTrustList *trusts; 1152 struct ldb_context *sam_ctx; 1153 struct loadparm_context *lp_ctx = dce_call->conn->dce_ctx->lp_ctx; 1154 uint32_t i; 955 1155 WERROR werr; 956 1156 957 ZERO_STRUCT(r2); 958 959 r2.in.logon_server = r->in.logon_server; 960 r2.in.domainname = r->in.domainname; 961 r2.out.dcname = r->out.dcname; 962 963 werr = dcesrv_netr_GetDcName(dce_call, mem_ctx, &r2); 964 965 return werr; 966 } 967 968 969 /* 970 netr_DatabaseRedo 1157 *r->out.dcname = NULL; 1158 1159 if ((r->in.domainname == NULL) || (r->in.domainname[0] == '\0')) { 1160 /* if the domainname parameter wasn't set assume our domain */ 1161 r->in.domainname = lpcfg_workgroup(lp_ctx); 1162 } 1163 1164 sam_ctx = samdb_connect(mem_ctx, dce_call->event_ctx, lp_ctx, 1165 dce_call->conn->auth_state.session_info, 0); 1166 if (sam_ctx == NULL) { 1167 return WERR_DS_UNAVAILABLE; 1168 } 1169 1170 if (strcasecmp(r->in.domainname, lpcfg_workgroup(lp_ctx)) == 0) { 1171 /* well we asked for a DC of our own domain */ 1172 if (samdb_is_pdc(sam_ctx)) { 1173 /* we are the PDC of the specified domain */ 1174 return WERR_NO_SUCH_DOMAIN; 1175 } 1176 1177 *r->out.dcname = talloc_asprintf(mem_ctx, "\\%s", 1178 lpcfg_netbios_name(lp_ctx)); 1179 W_ERROR_HAVE_NO_MEMORY(*r->out.dcname); 1180 1181 return WERR_OK; 1182 } 1183 1184 /* Okay, now we have to consider the trusted domains */ 1185 1186 trusts = talloc_zero(mem_ctx, struct netr_DomainTrustList); 1187 W_ERROR_HAVE_NO_MEMORY(trusts); 1188 1189 trusts->count = 0; 1190 1191 werr = fill_trusted_domains_array(mem_ctx, sam_ctx, trusts, 1192 NETR_TRUST_FLAG_INBOUND 1193 | NETR_TRUST_FLAG_OUTBOUND); 1194 W_ERROR_NOT_OK_RETURN(werr); 1195 1196 for (i = 0; i < trusts->count; i++) { 1197 if (strcasecmp(r->in.domainname, trusts->array[i].netbios_name) == 0) { 1198 /* FIXME: Here we need to find a DC for the specified 1199 * trusted domain. */ 1200 1201 /* return WERR_OK; */ 1202 return WERR_NO_SUCH_DOMAIN; 1203 } 1204 } 1205 1206 return WERR_NO_SUCH_DOMAIN; 1207 } 1208 1209 1210 /* 1211 netr_DatabaseRedo 971 1212 */ 972 1213 static NTSTATUS dcesrv_netr_DatabaseRedo(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, … … 977 1218 978 1219 979 /* 980 netr_NetrEnumerateT urstedDomains981 */ 982 static WERRORdcesrv_netr_NetrEnumerateTrustedDomains(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,1220 /* 1221 netr_NetrEnumerateTrustedDomains 1222 */ 1223 static NTSTATUS dcesrv_netr_NetrEnumerateTrustedDomains(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, 983 1224 struct netr_NetrEnumerateTrustedDomains *r) 984 1225 { … … 987 1228 988 1229 989 /* 1230 /* 990 1231 netr_LogonGetCapabilities 991 1232 */ … … 998 1239 999 1240 1000 /* 1001 netr_NETRLOGONSETSERVICEBITS 1241 /* 1242 netr_NETRLOGONSETSERVICEBITS 1002 1243 */ 1003 1244 static WERROR dcesrv_netr_NETRLOGONSETSERVICEBITS(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, … … 1018 1259 1019 1260 1020 /* 1021 netr_NETRLOGONCOMPUTESERVERDIGEST 1261 /* 1262 netr_NETRLOGONCOMPUTESERVERDIGEST 1022 1263 */ 1023 1264 static WERROR dcesrv_netr_NETRLOGONCOMPUTESERVERDIGEST(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, … … 1028 1269 1029 1270 1030 /* 1031 netr_NETRLOGONCOMPUTECLIENTDIGEST 1271 /* 1272 netr_NETRLOGONCOMPUTECLIENTDIGEST 1032 1273 */ 1033 1274 static WERROR dcesrv_netr_NETRLOGONCOMPUTECLIENTDIGEST(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, … … 1039 1280 1040 1281 1041 /* 1282 /* 1042 1283 netr_DsRGetSiteName 1043 1284 */ … … 1045 1286 struct netr_DsRGetSiteName *r) 1046 1287 { 1047 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR); 1288 struct ldb_context *sam_ctx; 1289 struct loadparm_context *lp_ctx = dce_call->conn->dce_ctx->lp_ctx; 1290 1291 sam_ctx = samdb_connect(mem_ctx, dce_call->event_ctx, lp_ctx, 1292 dce_call->conn->auth_state.session_info, 0); 1293 if (sam_ctx == NULL) { 1294 return WERR_DS_UNAVAILABLE; 1295 } 1296 1297 *r->out.site = samdb_server_site_name(sam_ctx, mem_ctx); 1298 W_ERROR_HAVE_NO_MEMORY(*r->out.site); 1299 1300 return WERR_OK; 1048 1301 } 1049 1302 … … 1065 1318 info->trust_extension.info = talloc_zero(mem_ctx, struct netr_trust_extension); 1066 1319 info->trust_extension.length = 16; 1067 info->trust_extension.info->flags = 1320 info->trust_extension.info->flags = 1068 1321 NETR_TRUST_FLAG_TREEROOT | 1069 NETR_TRUST_FLAG_IN_FOREST | 1322 NETR_TRUST_FLAG_IN_FOREST | 1070 1323 NETR_TRUST_FLAG_PRIMARY | 1071 1324 NETR_TRUST_FLAG_NATIVE; … … 1081 1334 info->dns_forestname.string = NULL; 1082 1335 } else { 1083 char *p; 1084 /* TODO: we need a common function for pulling the forest */ 1085 info->dns_forestname.string = ldb_dn_canonical_string(info, ldb_get_root_basedn(sam_ctx)); 1086 if (!info->dns_forestname.string) { 1087 return NT_STATUS_NO_SUCH_DOMAIN; 1088 } 1089 p = strchr(info->dns_forestname.string, '/'); 1090 if (p) { 1091 *p = '\0'; 1092 } 1336 info->dns_forestname.string = samdb_forest_name(sam_ctx, mem_ctx); 1337 NT_STATUS_HAVE_NO_MEMORY(info->dns_forestname.string); 1093 1338 info->dns_forestname.string = talloc_asprintf(mem_ctx, "%s.", info->dns_forestname.string); 1094 1339 NT_STATUS_HAVE_NO_MEMORY(info->dns_forestname.string); 1095 1340 } 1096 1341 1097 1342 if (is_local) { 1098 info->domainname.string = lp _sam_name(lp_ctx);1099 info->dns_domainname.string = lp _realm(lp_ctx);1343 info->domainname.string = lpcfg_workgroup(lp_ctx); 1344 info->dns_domainname.string = lpcfg_dnsdomain(lp_ctx); 1100 1345 info->domain_guid = samdb_result_guid(res, "objectGUID"); 1101 1346 info->domain_sid = samdb_result_dom_sid(mem_ctx, res, "objectSid"); 1102 1347 } else { 1103 info->domainname.string = samdb_result_string(res, "flatName", NULL);1104 info->dns_domainname.string = samdb_result_string(res, "trustPartner", NULL);1348 info->domainname.string = ldb_msg_find_attr_as_string(res, "flatName", NULL); 1349 info->dns_domainname.string = ldb_msg_find_attr_as_string(res, "trustPartner", NULL); 1105 1350 info->domain_guid = samdb_result_guid(res, "objectGUID"); 1106 1351 info->domain_sid = samdb_result_dom_sid(mem_ctx, res, "securityIdentifier"); … … 1113 1358 } 1114 1359 1115 /* 1360 /* 1116 1361 netr_LogonGetDomainInfo 1117 1362 this is called as part of the ADS domain logon procedure. … … 1126 1371 const char * const attrs[] = { "objectSid", "objectGUID", "flatName", 1127 1372 "securityIdentifier", "trustPartner", NULL }; 1128 const char *temp_str; 1129 const char *old_dns_hostname; 1373 const char * const attrs2[] = { "sAMAccountName", "dNSHostName", 1374 "msDS-SupportedEncryptionTypes", NULL }; 1375 const char *sam_account_name, *old_dns_hostname, *prefix1, *prefix2; 1130 1376 struct ldb_context *sam_ctx; 1131 struct ldb_message **res1, **res2, * new_msg;1377 struct ldb_message **res1, **res2, **res3, *new_msg; 1132 1378 struct ldb_dn *workstation_dn; 1133 1379 struct netr_DomainInformation *domain_info; 1134 1380 struct netr_LsaPolicyInformation *lsa_policy_info; 1135 struct netr_OsVersionInfoEx *os_version;1136 1381 uint32_t default_supported_enc_types = 0xFFFFFFFF; 1137 int ret1, ret2, i; 1382 bool update_dns_hostname = true; 1383 int ret, ret3, i; 1138 1384 NTSTATUS status; 1139 1385 1140 1386 status = dcesrv_netr_creds_server_step_check(dce_call, 1141 mem_ctx, 1142 r->in.computer_name, 1143 r->in.credential, 1387 mem_ctx, 1388 r->in.computer_name, 1389 r->in.credential, 1144 1390 r->out.return_authenticator, 1145 1391 &creds); … … 1150 1396 1151 1397 sam_ctx = samdb_connect(mem_ctx, dce_call->event_ctx, 1152 dce_call->conn->dce_ctx->lp_ctx,1153 system_session(mem_ctx, dce_call->conn->dce_ctx->lp_ctx));1398 dce_call->conn->dce_ctx->lp_ctx, 1399 system_session(dce_call->conn->dce_ctx->lp_ctx), 0); 1154 1400 if (sam_ctx == NULL) { 1155 1401 return NT_STATUS_INVALID_SYSTEM_SERVICE; … … 1159 1405 case 1: /* Domain information */ 1160 1406 1161 /* TODO: check NTSTATUS results - and fail also on SAMDB 1162 * errors (needs some testing against Windows Server 2008) */ 1407 if (r->in.query->workstation_info == NULL) { 1408 return NT_STATUS_INVALID_PARAMETER; 1409 } 1410 1411 /* Prepares the workstation DN */ 1412 workstation_dn = ldb_dn_new_fmt(mem_ctx, sam_ctx, "<SID=%s>", 1413 dom_sid_string(mem_ctx, creds->sid)); 1414 NT_STATUS_HAVE_NO_MEMORY(workstation_dn); 1415 1416 /* Lookup for attributes in workstation object */ 1417 ret = gendb_search_dn(sam_ctx, mem_ctx, workstation_dn, &res1, 1418 attrs2); 1419 if (ret != 1) { 1420 return NT_STATUS_INTERNAL_DB_CORRUPTION; 1421 } 1422 1423 /* Gets the sam account name which is checked against the DNS 1424 * hostname parameter. */ 1425 sam_account_name = ldb_msg_find_attr_as_string(res1[0], 1426 "sAMAccountName", 1427 NULL); 1428 if (sam_account_name == NULL) { 1429 return NT_STATUS_INTERNAL_DB_CORRUPTION; 1430 } 1163 1431 1164 1432 /* 1165 * Check that the computer name parameter matches as prefix with 1166 * the DNS hostname in the workstation info structure. 1433 * Checks that the sam account name without a possible "$" 1434 * matches as prefix with the DNS hostname in the workstation 1435 * info structure. 1167 1436 */ 1168 temp_str = strndup(r->in.query->workstation_info->dns_hostname, 1169 strcspn(r->in.query->workstation_info->dns_hostname, 1170 ".")); 1171 if (strcasecmp(r->in.computer_name, temp_str) != 0) 1172 return NT_STATUS_INVALID_PARAMETER; 1173 1174 workstation_dn = ldb_dn_new_fmt(mem_ctx, sam_ctx, "<SID=%s>", 1175 dom_sid_string(mem_ctx, creds->sid)); 1176 NT_STATUS_HAVE_NO_MEMORY(workstation_dn); 1437 prefix1 = talloc_strndup(mem_ctx, sam_account_name, 1438 strcspn(sam_account_name, "$")); 1439 NT_STATUS_HAVE_NO_MEMORY(prefix1); 1440 if (r->in.query->workstation_info->dns_hostname != NULL) { 1441 prefix2 = talloc_strndup(mem_ctx, 1442 r->in.query->workstation_info->dns_hostname, 1443 strcspn(r->in.query->workstation_info->dns_hostname, ".")); 1444 NT_STATUS_HAVE_NO_MEMORY(prefix2); 1445 1446 if (strcasecmp(prefix1, prefix2) != 0) { 1447 update_dns_hostname = false; 1448 } 1449 } else { 1450 update_dns_hostname = false; 1451 } 1177 1452 1178 1453 /* Gets the old DNS hostname */ 1179 old_dns_hostname = samdb_search_string(sam_ctx, mem_ctx, 1180 workstation_dn, 1181 "dNSHostName", 1182 NULL); 1183 1184 /* Gets host informations and put them in our directory */ 1454 old_dns_hostname = ldb_msg_find_attr_as_string(res1[0], 1455 "dNSHostName", 1456 NULL); 1457 1458 /* 1459 * Updates the DNS hostname when the client wishes that the 1460 * server should handle this for him 1461 * ("NETR_WS_FLAG_HANDLES_SPN_UPDATE" not set). And this is 1462 * obviously only checked when we do already have a 1463 * "dNSHostName". 1464 * See MS-NRPC section 3.5.4.3.9 1465 */ 1466 if ((old_dns_hostname != NULL) && 1467 (r->in.query->workstation_info->workstation_flags 1468 & NETR_WS_FLAG_HANDLES_SPN_UPDATE) != 0) { 1469 update_dns_hostname = false; 1470 } 1471 1472 /* Gets host information and put them into our directory */ 1473 1185 1474 new_msg = ldb_msg_new(mem_ctx); 1186 1475 NT_STATUS_HAVE_NO_MEMORY(new_msg); … … 1188 1477 new_msg->dn = workstation_dn; 1189 1478 1190 /* Deletes old OS version values */1191 samdb_msg_add_delete(sam_ctx, mem_ctx, new_msg,1192 "operatingSystemServicePack");1193 samdb_msg_add_delete(sam_ctx, mem_ctx, new_msg,1194 "operatingSystemVersion");1195 1196 if (samdb_replace(sam_ctx, mem_ctx, new_msg) != LDB_SUCCESS) {1197 DEBUG(3,("Impossible to update samdb: %s\n",1198 ldb_errstring(sam_ctx)));1199 }1200 1201 talloc_free(new_msg);1202 1203 new_msg = ldb_msg_new(mem_ctx);1204 NT_STATUS_HAVE_NO_MEMORY(new_msg);1205 1206 new_msg->dn = workstation_dn;1207 1208 1479 /* Sets the OS name */ 1209 samdb_msg_set_string(sam_ctx, mem_ctx, new_msg, 1210 "operatingSystem",1211 r ->in.query->workstation_info->os_name.string);1212 1213 if (r->in.query->workstation_info->dns_hostname) { 1214 /* TODO: should this always be done? */1215 samdb_msg_add_string(sam_ctx, mem_ctx, new_msg,1216 "dNSHostname",1217 r->in.query->workstation_info->dns_hostname);1480 1481 if (r->in.query->workstation_info->os_name.string == NULL) { 1482 return NT_STATUS_INVALID_PARAMETER; 1483 } 1484 1485 ret = ldb_msg_add_string(new_msg, "operatingSystem", 1486 r->in.query->workstation_info->os_name.string); 1487 if (ret != LDB_SUCCESS) { 1488 return NT_STATUS_NO_MEMORY; 1218 1489 } 1219 1490 1220 1491 /* 1221 * Sets information s from "os_version". On aempty structure1492 * Sets information from "os_version". On an empty structure 1222 1493 * the values are cleared. 1223 1494 */ 1224 1495 if (r->in.query->workstation_info->os_version.os != NULL) { 1496 struct netr_OsVersionInfoEx *os_version; 1497 const char *os_version_str; 1498 1225 1499 os_version = &r->in.query->workstation_info->os_version.os->os; 1226 1500 1227 samdb_msg_set_string(sam_ctx, mem_ctx, new_msg, 1228 "operatingSystemServicePack", 1229 os_version->CSDVersion); 1230 1231 samdb_msg_set_string(sam_ctx, mem_ctx, new_msg, 1232 "operatingSystemVersion", 1233 talloc_asprintf(mem_ctx, "%d.%d (%d)", 1234 os_version->MajorVersion, 1235 os_version->MinorVersion, 1236 os_version->BuildNumber 1237 ) 1238 ); 1501 if (os_version->CSDVersion == NULL) { 1502 return NT_STATUS_INVALID_PARAMETER; 1503 } 1504 1505 os_version_str = talloc_asprintf(new_msg, "%u.%u (%u)", 1506 os_version->MajorVersion, 1507 os_version->MinorVersion, 1508 os_version->BuildNumber); 1509 NT_STATUS_HAVE_NO_MEMORY(os_version_str); 1510 1511 ret = ldb_msg_add_string(new_msg, 1512 "operatingSystemServicePack", 1513 os_version->CSDVersion); 1514 if (ret != LDB_SUCCESS) { 1515 return NT_STATUS_NO_MEMORY; 1516 } 1517 1518 ret = ldb_msg_add_string(new_msg, 1519 "operatingSystemVersion", 1520 os_version_str); 1521 if (ret != LDB_SUCCESS) { 1522 return NT_STATUS_NO_MEMORY; 1523 } 1524 } else { 1525 ret = samdb_msg_add_delete(sam_ctx, mem_ctx, new_msg, 1526 "operatingSystemServicePack"); 1527 if (ret != LDB_SUCCESS) { 1528 return NT_STATUS_NO_MEMORY; 1529 } 1530 1531 ret = samdb_msg_add_delete(sam_ctx, mem_ctx, new_msg, 1532 "operatingSystemVersion"); 1533 if (ret != LDB_SUCCESS) { 1534 return NT_STATUS_NO_MEMORY; 1535 } 1239 1536 } 1240 1537 1241 1538 /* 1242 * Updates the "dNSHostname" and the "servicePrincipalName"s 1243 * since the client wishes that the server should handle this 1244 * for him ("NETR_WS_FLAG_HANDLES_SPN_UPDATE" not set). 1245 * See MS-NRPC section 3.5.4.3.9 1539 * If the boolean "update_dns_hostname" remained true, then we 1540 * are fine to start the update. 1246 1541 */ 1247 if ((r->in.query->workstation_info->workstation_flags 1248 & NETR_WS_FLAG_HANDLES_SPN_UPDATE) == 0) { 1249 1250 samdb_msg_add_string(sam_ctx, mem_ctx, new_msg, 1251 "servicePrincipalName", 1252 talloc_asprintf(mem_ctx, "HOST/%s", 1253 r->in.computer_name) 1254 ); 1255 samdb_msg_add_string(sam_ctx, mem_ctx, new_msg, 1256 "servicePrincipalName", 1257 talloc_asprintf(mem_ctx, "HOST/%s", 1258 r->in.query->workstation_info->dns_hostname) 1259 ); 1260 } 1261 1262 if (samdb_replace(sam_ctx, mem_ctx, new_msg) != LDB_SUCCESS) { 1542 if (update_dns_hostname) { 1543 ret = ldb_msg_add_string(new_msg, 1544 "dNSHostname", 1545 r->in.query->workstation_info->dns_hostname); 1546 if (ret != LDB_SUCCESS) { 1547 return NT_STATUS_NO_MEMORY; 1548 } 1549 1550 /* This manual "servicePrincipalName" generation is 1551 * still needed! Since the update in the samldb LDB 1552 * module does only work if the entries already exist 1553 * which isn't always the case. */ 1554 ret = ldb_msg_add_string(new_msg, 1555 "servicePrincipalName", 1556 talloc_asprintf(new_msg, "HOST/%s", 1557 r->in.computer_name)); 1558 if (ret != LDB_SUCCESS) { 1559 return NT_STATUS_NO_MEMORY; 1560 } 1561 1562 ret = ldb_msg_add_string(new_msg, 1563 "servicePrincipalName", 1564 talloc_asprintf(new_msg, "HOST/%s", 1565 r->in.query->workstation_info->dns_hostname)); 1566 if (ret != LDB_SUCCESS) { 1567 return NT_STATUS_NO_MEMORY; 1568 } 1569 } 1570 1571 if (dsdb_replace(sam_ctx, new_msg, 0) != LDB_SUCCESS) { 1263 1572 DEBUG(3,("Impossible to update samdb: %s\n", 1264 1573 ldb_errstring(sam_ctx))); … … 1274 1583 put the primary domain into the lists of returned trusts as 1275 1584 well. */ 1276 ret 1 = gendb_search_dn(sam_ctx, mem_ctx, samdb_base_dn(sam_ctx),1277 &res 1, attrs);1278 if (ret 1!= 1) {1585 ret = gendb_search_dn(sam_ctx, mem_ctx, ldb_get_default_basedn(sam_ctx), 1586 &res2, attrs); 1587 if (ret != 1) { 1279 1588 return NT_STATUS_INTERNAL_DB_CORRUPTION; 1280 1589 } 1281 1590 1282 ret 2 = gendb_search(sam_ctx, mem_ctx, NULL, &res2, attrs,1591 ret3 = gendb_search(sam_ctx, mem_ctx, NULL, &res3, attrs, 1283 1592 "(objectClass=trustedDomain)"); 1284 if (ret 2== -1) {1593 if (ret3 == -1) { 1285 1594 return NT_STATUS_INTERNAL_DB_CORRUPTION; 1286 1595 } … … 1295 1604 status = fill_one_domain_info(mem_ctx, 1296 1605 dce_call->conn->dce_ctx->lp_ctx, 1297 sam_ctx, res 1[0], &domain_info->primary_domain,1606 sam_ctx, res2[0], &domain_info->primary_domain, 1298 1607 true, false); 1299 1608 NT_STATUS_NOT_OK_RETURN(status); 1300 1609 1301 domain_info->trusted_domain_count = ret 2+ 1;1610 domain_info->trusted_domain_count = ret3 + 1; 1302 1611 domain_info->trusted_domains = talloc_array(mem_ctx, 1303 1612 struct netr_OneDomainInfo, … … 1305 1614 NT_STATUS_HAVE_NO_MEMORY(domain_info->trusted_domains); 1306 1615 1307 for (i=0;i<ret 2;i++) {1616 for (i=0;i<ret3;i++) { 1308 1617 status = fill_one_domain_info(mem_ctx, 1309 1618 dce_call->conn->dce_ctx->lp_ctx, 1310 sam_ctx, res 2[i],1619 sam_ctx, res3[i], 1311 1620 &domain_info->trusted_domains[i], 1312 1621 false, true); … … 1315 1624 1316 1625 status = fill_one_domain_info(mem_ctx, 1317 dce_call->conn->dce_ctx->lp_ctx, sam_ctx, res 1[0],1626 dce_call->conn->dce_ctx->lp_ctx, sam_ctx, res2[0], 1318 1627 &domain_info->trusted_domains[i], true, true); 1319 1628 NT_STATUS_NOT_OK_RETURN(status); 1320 1629 1321 1630 /* Sets the supported encryption types */ 1322 domain_info->supported_enc_types = samdb_search_uint( 1323 sam_ctx, mem_ctx, 1324 default_supported_enc_types, workstation_dn, 1325 "msDS-SupportedEncryptionTypes", NULL); 1326 1327 /* Other host domain informations */ 1631 domain_info->supported_enc_types = ldb_msg_find_attr_as_uint(res1[0], 1632 "msDS-SupportedEncryptionTypes", 1633 default_supported_enc_types); 1634 1635 /* Other host domain information */ 1328 1636 1329 1637 lsa_policy_info = talloc(mem_ctx, … … 1334 1642 domain_info->lsa_policy = *lsa_policy_info; 1335 1643 1336 domain_info->dns_hostname.string = old_dns_hostname; 1644 /* The DNS hostname is only returned back when there is a chance 1645 * for a change. */ 1646 if ((r->in.query->workstation_info->workstation_flags 1647 & NETR_WS_FLAG_HANDLES_SPN_UPDATE) != 0) { 1648 domain_info->dns_hostname.string = old_dns_hostname; 1649 } else { 1650 domain_info->dns_hostname.string = NULL; 1651 } 1652 1337 1653 domain_info->workstation_flags = 1338 1654 r->in.query->workstation_info->workstation_flags; … … 1357 1673 1358 1674 1359 1360 1675 /* 1361 1676 netr_ServerPasswordGet … … 1368 1683 1369 1684 1370 /* 1371 netr_NETRLOGONSENDTOSAM 1685 /* 1686 netr_NETRLOGONSENDTOSAM 1372 1687 */ 1373 1688 static WERROR dcesrv_netr_NETRLOGONSENDTOSAM(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, … … 1378 1693 1379 1694 1380 /* 1381 netr_DsRAddressToSitenamesW 1382 */ 1383 static WERROR dcesrv_netr_DsRAddressToSitenamesW(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, 1384 struct netr_DsRAddressToSitenamesW *r) 1385 { 1386 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR); 1387 } 1388 1389 1390 /* 1695 /* 1391 1696 netr_DsRGetDCNameEx2 1392 1697 */ 1393 static WERROR dcesrv_netr_DsRGetDCNameEx2(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,1394 struct netr_DsRGetDCNameEx2 *r)1395 { 1396 const char * const attrs[] = { "objectGUID", NULL }; 1698 static WERROR dcesrv_netr_DsRGetDCNameEx2(struct dcesrv_call_state *dce_call, 1699 TALLOC_CTX *mem_ctx, 1700 struct netr_DsRGetDCNameEx2 *r) 1701 { 1397 1702 struct ldb_context *sam_ctx; 1398 struct ldb_message **res;1399 struct ldb_dn *domain_dn;1400 int ret;1401 1703 struct netr_DsRGetDCNameInfo *info; 1704 struct loadparm_context *lp_ctx = dce_call->conn->dce_ctx->lp_ctx; 1705 const struct tsocket_address *remote_address; 1706 char *addr = NULL; 1707 const char *server_site_name; 1708 char *guid_str; 1709 struct netlogon_samlogon_response response; 1710 NTSTATUS status; 1711 const char *dc_name = NULL; 1712 const char *domain_name = NULL; 1402 1713 1403 1714 ZERO_STRUCTP(r->out.info); 1404 1715 1405 sam_ctx = samdb_connect(mem_ctx, dce_call->event_ctx, dce_call->conn->dce_ctx->lp_ctx, dce_call->conn->auth_state.session_info); 1716 sam_ctx = samdb_connect(mem_ctx, dce_call->event_ctx, lp_ctx, 1717 dce_call->conn->auth_state.session_info, 0); 1406 1718 if (sam_ctx == NULL) { 1407 1719 return WERR_DS_UNAVAILABLE; 1408 1720 } 1409 1721 1410 /* Win7-beta will send the domain name in the form the user typed, so we have to cope 1411 with both the short and long form here */ 1412 if (r->in.domain_name != NULL && !lp_is_my_domain_or_realm(dce_call->conn->dce_ctx->lp_ctx, 1413 r->in.domain_name)) { 1722 remote_address = dcesrv_connection_get_remote_address(dce_call->conn); 1723 if (tsocket_address_is_inet(remote_address, "ip")) { 1724 addr = tsocket_address_inet_addr_string(remote_address, mem_ctx); 1725 W_ERROR_HAVE_NO_MEMORY(addr); 1726 } 1727 1728 /* "server_unc" is ignored by w2k3 */ 1729 1730 if (r->in.flags & ~(DSGETDC_VALID_FLAGS)) { 1731 return WERR_INVALID_FLAGS; 1732 } 1733 1734 if (r->in.flags & DS_GC_SERVER_REQUIRED && 1735 r->in.flags & DS_PDC_REQUIRED && 1736 r->in.flags & DS_KDC_REQUIRED) { 1737 return WERR_INVALID_FLAGS; 1738 } 1739 if (r->in.flags & DS_IS_FLAT_NAME && 1740 r->in.flags & DS_IS_DNS_NAME) { 1741 return WERR_INVALID_FLAGS; 1742 } 1743 if (r->in.flags & DS_RETURN_DNS_NAME && 1744 r->in.flags & DS_RETURN_FLAT_NAME) { 1745 return WERR_INVALID_FLAGS; 1746 } 1747 if (r->in.flags & DS_DIRECTORY_SERVICE_REQUIRED && 1748 r->in.flags & DS_DIRECTORY_SERVICE_6_REQUIRED) { 1749 return WERR_INVALID_FLAGS; 1750 } 1751 1752 if (r->in.flags & DS_GOOD_TIMESERV_PREFERRED && 1753 r->in.flags & 1754 (DS_DIRECTORY_SERVICE_REQUIRED | 1755 DS_DIRECTORY_SERVICE_PREFERRED | 1756 DS_GC_SERVER_REQUIRED | 1757 DS_PDC_REQUIRED | 1758 DS_KDC_REQUIRED)) { 1759 return WERR_INVALID_FLAGS; 1760 } 1761 1762 if (r->in.flags & DS_TRY_NEXTCLOSEST_SITE && 1763 r->in.site_name) { 1764 return WERR_INVALID_FLAGS; 1765 } 1766 1767 /* Proof server site parameter "site_name" if it was specified */ 1768 server_site_name = samdb_server_site_name(sam_ctx, mem_ctx); 1769 W_ERROR_HAVE_NO_MEMORY(server_site_name); 1770 if ((r->in.site_name != NULL) && (strcasecmp(r->in.site_name, 1771 server_site_name) != 0)) { 1414 1772 return WERR_NO_SUCH_DOMAIN; 1415 1773 } 1416 1774 1417 domain_dn = ldb_get_default_basedn(sam_ctx); 1418 if (domain_dn == NULL) { 1419 return WERR_DS_UNAVAILABLE; 1420 } 1421 1422 ret = gendb_search_dn(sam_ctx, mem_ctx, 1423 domain_dn, &res, attrs); 1424 if (ret != 1) { 1775 guid_str = r->in.domain_guid != NULL ? 1776 GUID_string(mem_ctx, r->in.domain_guid) : NULL; 1777 1778 status = fill_netlogon_samlogon_response(sam_ctx, mem_ctx, 1779 r->in.domain_name, 1780 r->in.domain_name, 1781 NULL, guid_str, 1782 r->in.client_account, 1783 r->in.mask, addr, 1784 NETLOGON_NT_VERSION_5EX_WITH_IP, 1785 lp_ctx, &response, true); 1786 if (!NT_STATUS_IS_OK(status)) { 1787 return ntstatus_to_werror(status); 1788 } 1789 1790 if (r->in.flags & DS_RETURN_DNS_NAME) { 1791 dc_name = response.data.nt5_ex.pdc_dns_name; 1792 domain_name = response.data.nt5_ex.dns_domain; 1793 } else if (r->in.flags & DS_RETURN_FLAT_NAME) { 1794 dc_name = response.data.nt5_ex.pdc_name; 1795 domain_name = response.data.nt5_ex.domain_name; 1796 } else { 1797 1798 /* 1799 * TODO: autodetect what we need to return 1800 * based on the given arguments 1801 */ 1802 dc_name = response.data.nt5_ex.pdc_name; 1803 domain_name = response.data.nt5_ex.domain_name; 1804 } 1805 1806 if (!dc_name || !dc_name[0]) { 1807 return WERR_NO_SUCH_DOMAIN; 1808 } 1809 1810 if (!domain_name || !domain_name[0]) { 1811 return WERR_NO_SUCH_DOMAIN; 1425 1812 } 1426 1813 1427 1814 info = talloc(mem_ctx, struct netr_DsRGetDCNameInfo); 1428 1815 W_ERROR_HAVE_NO_MEMORY(info); 1429 1430 /* TODO: - return real IP address 1431 * - check all r->in.* parameters (server_unc is ignored by w2k3!) 1432 */ 1433 info->dc_unc = talloc_asprintf(mem_ctx, "\\\\%s.%s", 1434 lp_netbios_name(dce_call->conn->dce_ctx->lp_ctx), 1435 lp_realm(dce_call->conn->dce_ctx->lp_ctx)); 1816 info->dc_unc = talloc_asprintf(mem_ctx, "\\\\%s", dc_name); 1436 1817 W_ERROR_HAVE_NO_MEMORY(info->dc_unc); 1437 info->dc_address = talloc_strdup(mem_ctx, "\\\\0.0.0.0"); 1818 info->dc_address = talloc_asprintf(mem_ctx, "\\\\%s", 1819 response.data.nt5_ex.sockaddr.pdc_ip); 1438 1820 W_ERROR_HAVE_NO_MEMORY(info->dc_address); 1439 info->dc_address_type = DS_ADDRESS_TYPE_INET; 1440 info->domain_guid = samdb_result_guid(res[0], "objectGUID"); 1441 info->domain_name = lp_realm(dce_call->conn->dce_ctx->lp_ctx); 1442 info->forest_name = lp_realm(dce_call->conn->dce_ctx->lp_ctx); 1443 info->dc_flags = DS_DNS_FOREST | 1444 DS_DNS_DOMAIN | 1445 DS_DNS_CONTROLLER | 1446 DS_SERVER_WRITABLE | 1447 DS_SERVER_CLOSEST | 1448 DS_SERVER_TIMESERV | 1449 DS_SERVER_KDC | 1450 DS_SERVER_DS | 1451 DS_SERVER_LDAP | 1452 DS_SERVER_GC | 1453 DS_SERVER_PDC; 1454 info->dc_site_name = talloc_strdup(mem_ctx, "Default-First-Site-Name"); 1455 W_ERROR_HAVE_NO_MEMORY(info->dc_site_name); 1456 info->client_site_name = talloc_strdup(mem_ctx, "Default-First-Site-Name"); 1457 W_ERROR_HAVE_NO_MEMORY(info->client_site_name); 1821 info->dc_address_type = DS_ADDRESS_TYPE_INET; /* TODO: make this dynamic? for ipv6 */ 1822 info->domain_guid = response.data.nt5_ex.domain_uuid; 1823 info->domain_name = domain_name; 1824 info->forest_name = response.data.nt5_ex.forest; 1825 info->dc_flags = response.data.nt5_ex.server_type; 1826 info->dc_site_name = response.data.nt5_ex.server_site; 1827 info->client_site_name = response.data.nt5_ex.client_site; 1458 1828 1459 1829 *r->out.info = info; … … 1462 1832 } 1463 1833 1464 /* 1834 /* 1465 1835 netr_DsRGetDCNameEx 1466 1836 */ … … 1487 1857 } 1488 1858 1489 /* 1859 /* 1490 1860 netr_DsRGetDCName 1491 1861 */ … … 1503 1873 r2.in.domain_name = r->in.domain_name; 1504 1874 r2.in.domain_guid = r->in.domain_guid; 1505 1506 r2.in.site_name = NULL; /* should fill in fromsite GUID */1875 1876 r2.in.site_name = NULL; /* this is correct, we should ignore site GUID */ 1507 1877 r2.in.flags = r->in.flags; 1508 1878 r2.out.info = r->out.info; … … 1512 1882 return werr; 1513 1883 } 1514 /* 1515 netr_NETRLOGONGETTIMESERVICEPARENTDOMAIN 1884 /* 1885 netr_NETRLOGONGETTIMESERVICEPARENTDOMAIN 1516 1886 */ 1517 1887 static WERROR dcesrv_netr_NETRLOGONGETTIMESERVICEPARENTDOMAIN(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, … … 1532 1902 1533 1903 1534 /* 1535 netr_DsRAddressToSitenamesExW 1904 /* 1905 netr_DsRAddressToSitenamesExW 1536 1906 */ 1537 1907 static WERROR dcesrv_netr_DsRAddressToSitenamesExW(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, 1538 1908 struct netr_DsRAddressToSitenamesExW *r) 1539 1909 { 1910 struct ldb_context *sam_ctx; 1540 1911 struct netr_DsRAddressToSitenamesExWCtr *ctr; 1541 int i; 1542 1543 /* we should map the provided IPs to site names, once we have 1544 * sites support 1545 */ 1912 struct loadparm_context *lp_ctx = dce_call->conn->dce_ctx->lp_ctx; 1913 sa_family_t sin_family; 1914 struct sockaddr_in *addr; 1915 #ifdef HAVE_IPV6 1916 struct sockaddr_in6 *addr6; 1917 char addr_str[INET6_ADDRSTRLEN]; 1918 #else 1919 char addr_str[INET_ADDRSTRLEN]; 1920 #endif 1921 char *subnet_name; 1922 const char *res; 1923 uint32_t i; 1924 1925 sam_ctx = samdb_connect(mem_ctx, dce_call->event_ctx, lp_ctx, 1926 dce_call->conn->auth_state.session_info, 0); 1927 if (sam_ctx == NULL) { 1928 return WERR_DS_UNAVAILABLE; 1929 } 1930 1546 1931 ctr = talloc(mem_ctx, struct netr_DsRAddressToSitenamesExWCtr); 1547 1932 W_ERROR_HAVE_NO_MEMORY(ctr); … … 1556 1941 1557 1942 for (i=0; i<ctr->count; i++) { 1558 ctr->sitename[i].string = "Default-First-Site-Name";1943 ctr->sitename[i].string = NULL; 1559 1944 ctr->subnetname[i].string = NULL; 1945 1946 if (r->in.addresses[i].size < sizeof(sa_family_t)) { 1947 continue; 1948 } 1949 /* The first two byte of the buffer are reserved for the 1950 * "sin_family" but for now only the first one is used. */ 1951 sin_family = r->in.addresses[i].buffer[0]; 1952 1953 switch (sin_family) { 1954 case AF_INET: 1955 if (r->in.addresses[i].size < sizeof(struct sockaddr_in)) { 1956 continue; 1957 } 1958 addr = (struct sockaddr_in *) r->in.addresses[i].buffer; 1959 res = inet_ntop(AF_INET, &addr->sin_addr, 1960 addr_str, sizeof(addr_str)); 1961 break; 1962 #ifdef HAVE_IPV6 1963 case AF_INET6: 1964 if (r->in.addresses[i].size < sizeof(struct sockaddr_in6)) { 1965 continue; 1966 } 1967 addr6 = (struct sockaddr_in6 *) r->in.addresses[i].buffer; 1968 res = inet_ntop(AF_INET6, &addr6->sin6_addr, 1969 addr_str, sizeof(addr_str)); 1970 break; 1971 #endif 1972 default: 1973 continue; 1974 } 1975 1976 if (res == NULL) { 1977 continue; 1978 } 1979 1980 ctr->sitename[i].string = samdb_client_site_name(sam_ctx, 1981 mem_ctx, 1982 addr_str, 1983 &subnet_name); 1984 W_ERROR_HAVE_NO_MEMORY(ctr->sitename[i].string); 1985 ctr->subnetname[i].string = subnet_name; 1560 1986 } 1561 1987 … … 1564 1990 1565 1991 1566 /* 1992 /* 1993 netr_DsRAddressToSitenamesW 1994 */ 1995 static WERROR dcesrv_netr_DsRAddressToSitenamesW(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, 1996 struct netr_DsRAddressToSitenamesW *r) 1997 { 1998 struct netr_DsRAddressToSitenamesExW r2; 1999 struct netr_DsRAddressToSitenamesWCtr *ctr; 2000 uint32_t i; 2001 WERROR werr; 2002 2003 ZERO_STRUCT(r2); 2004 2005 r2.in.server_name = r->in.server_name; 2006 r2.in.count = r->in.count; 2007 r2.in.addresses = r->in.addresses; 2008 2009 r2.out.ctr = talloc(mem_ctx, struct netr_DsRAddressToSitenamesExWCtr *); 2010 W_ERROR_HAVE_NO_MEMORY(r2.out.ctr); 2011 2012 ctr = talloc(mem_ctx, struct netr_DsRAddressToSitenamesWCtr); 2013 W_ERROR_HAVE_NO_MEMORY(ctr); 2014 2015 *r->out.ctr = ctr; 2016 2017 ctr->count = r->in.count; 2018 ctr->sitename = talloc_array(ctr, struct lsa_String, ctr->count); 2019 W_ERROR_HAVE_NO_MEMORY(ctr->sitename); 2020 2021 werr = dcesrv_netr_DsRAddressToSitenamesExW(dce_call, mem_ctx, &r2); 2022 2023 for (i=0; i<ctr->count; i++) { 2024 ctr->sitename[i].string = (*r2.out.ctr)->sitename[i].string; 2025 } 2026 2027 return werr; 2028 } 2029 2030 2031 /* 1567 2032 netr_DsrGetDcSiteCoverageW 1568 2033 */ … … 1570 2035 struct netr_DsrGetDcSiteCoverageW *r) 1571 2036 { 1572 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR); 1573 } 1574 1575 1576 /* 1577 netr_DsrEnumerateDomainTrusts 1578 */ 1579 static WERROR dcesrv_netr_DsrEnumerateDomainTrusts(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, 1580 struct netr_DsrEnumerateDomainTrusts *r) 2037 struct ldb_context *sam_ctx; 2038 struct DcSitesCtr *ctr; 2039 struct loadparm_context *lp_ctx = dce_call->conn->dce_ctx->lp_ctx; 2040 2041 sam_ctx = samdb_connect(mem_ctx, dce_call->event_ctx, lp_ctx, 2042 dce_call->conn->auth_state.session_info, 0); 2043 if (sam_ctx == NULL) { 2044 return WERR_DS_UNAVAILABLE; 2045 } 2046 2047 ctr = talloc(mem_ctx, struct DcSitesCtr); 2048 W_ERROR_HAVE_NO_MEMORY(ctr); 2049 2050 *r->out.ctr = ctr; 2051 2052 /* For now only return our default site */ 2053 ctr->num_sites = 1; 2054 ctr->sites = talloc_array(ctr, struct lsa_String, ctr->num_sites); 2055 W_ERROR_HAVE_NO_MEMORY(ctr->sites); 2056 ctr->sites[0].string = samdb_server_site_name(sam_ctx, mem_ctx); 2057 W_ERROR_HAVE_NO_MEMORY(ctr->sites[0].string); 2058 2059 return WERR_OK; 2060 } 2061 2062 2063 #define GET_CHECK_STR(dest, mem, msg, attr) \ 2064 do {\ 2065 const char *s; \ 2066 s = ldb_msg_find_attr_as_string(msg, attr, NULL); \ 2067 if (!s) { \ 2068 DEBUG(0, ("DB Error, TustedDomain entry (%s) " \ 2069 "without flatname\n", \ 2070 ldb_dn_get_linearized(msg->dn))); \ 2071 continue; \ 2072 } \ 2073 dest = talloc_strdup(mem, s); \ 2074 W_ERROR_HAVE_NO_MEMORY(dest); \ 2075 } while(0) 2076 2077 2078 static WERROR fill_trusted_domains_array(TALLOC_CTX *mem_ctx, 2079 struct ldb_context *sam_ctx, 2080 struct netr_DomainTrustList *trusts, 2081 uint32_t trust_flags) 2082 { 2083 struct ldb_dn *system_dn; 2084 struct ldb_message **dom_res = NULL; 2085 const char *trust_attrs[] = { "flatname", "trustPartner", 2086 "securityIdentifier", "trustDirection", 2087 "trustType", "trustAttributes", NULL }; 2088 uint32_t n; 2089 int i; 2090 int ret; 2091 2092 if (!(trust_flags & (NETR_TRUST_FLAG_INBOUND | 2093 NETR_TRUST_FLAG_OUTBOUND))) { 2094 return WERR_INVALID_FLAGS; 2095 } 2096 2097 system_dn = samdb_search_dn(sam_ctx, mem_ctx, 2098 ldb_get_default_basedn(sam_ctx), 2099 "(&(objectClass=container)(cn=System))"); 2100 if (!system_dn) { 2101 return WERR_GENERAL_FAILURE; 2102 } 2103 2104 ret = gendb_search(sam_ctx, mem_ctx, system_dn, 2105 &dom_res, trust_attrs, 2106 "(objectclass=trustedDomain)"); 2107 2108 for (i = 0; i < ret; i++) { 2109 unsigned int trust_dir; 2110 uint32_t flags = 0; 2111 2112 trust_dir = ldb_msg_find_attr_as_uint(dom_res[i], 2113 "trustDirection", 0); 2114 2115 if (trust_dir & LSA_TRUST_DIRECTION_INBOUND) { 2116 flags |= NETR_TRUST_FLAG_INBOUND; 2117 } 2118 if (trust_dir & LSA_TRUST_DIRECTION_OUTBOUND) { 2119 flags |= NETR_TRUST_FLAG_OUTBOUND; 2120 } 2121 2122 if (!(flags & trust_flags)) { 2123 /* this trust direction was not requested */ 2124 continue; 2125 } 2126 2127 n = trusts->count; 2128 trusts->array = talloc_realloc(trusts, trusts->array, 2129 struct netr_DomainTrust, 2130 n + 1); 2131 W_ERROR_HAVE_NO_MEMORY(trusts->array); 2132 2133 GET_CHECK_STR(trusts->array[n].netbios_name, trusts, 2134 dom_res[i], "flatname"); 2135 GET_CHECK_STR(trusts->array[n].dns_name, trusts, 2136 dom_res[i], "trustPartner"); 2137 2138 trusts->array[n].trust_flags = flags; 2139 if ((trust_flags & NETR_TRUST_FLAG_IN_FOREST) && 2140 !(flags & NETR_TRUST_FLAG_TREEROOT)) { 2141 /* TODO: find if we have parent in the list */ 2142 trusts->array[n].parent_index = 0; 2143 } 2144 2145 trusts->array[n].trust_type = 2146 ldb_msg_find_attr_as_uint(dom_res[i], 2147 "trustType", 0); 2148 trusts->array[n].trust_attributes = 2149 ldb_msg_find_attr_as_uint(dom_res[i], 2150 "trustAttributes", 0); 2151 2152 if ((trusts->array[n].trust_type == NETR_TRUST_TYPE_MIT) || 2153 (trusts->array[n].trust_type == NETR_TRUST_TYPE_DCE)) { 2154 struct dom_sid zero_sid; 2155 ZERO_STRUCT(zero_sid); 2156 trusts->array[n].sid = 2157 dom_sid_dup(trusts, &zero_sid); 2158 } else { 2159 trusts->array[n].sid = 2160 samdb_result_dom_sid(trusts, dom_res[i], 2161 "securityIdentifier"); 2162 } 2163 trusts->array[n].guid = GUID_zero(); 2164 2165 trusts->count = n + 1; 2166 } 2167 2168 talloc_free(dom_res); 2169 return WERR_OK; 2170 } 2171 2172 /* 2173 netr_DsrEnumerateDomainTrusts 2174 */ 2175 static WERROR dcesrv_netr_DsrEnumerateDomainTrusts(struct dcesrv_call_state *dce_call, 2176 TALLOC_CTX *mem_ctx, 2177 struct netr_DsrEnumerateDomainTrusts *r) 1581 2178 { 1582 2179 struct netr_DomainTrustList *trusts; … … 1585 2182 struct ldb_message **dom_res; 1586 2183 const char * const dom_attrs[] = { "objectSid", "objectGUID", NULL }; 1587 1588 ZERO_STRUCT(r->out); 1589 1590 sam_ctx = samdb_connect(mem_ctx, dce_call->event_ctx, dce_call->conn->dce_ctx->lp_ctx, dce_call->conn->auth_state.session_info); 2184 struct loadparm_context *lp_ctx = dce_call->conn->dce_ctx->lp_ctx; 2185 const char *dnsdomain = lpcfg_dnsdomain(lp_ctx); 2186 const char *p; 2187 WERROR werr; 2188 2189 if (r->in.trust_flags & 0xFFFFFE00) { 2190 return WERR_INVALID_FLAGS; 2191 } 2192 2193 /* TODO: turn to hard check once we are sure this is 100% correct */ 2194 if (!r->in.server_name) { 2195 DEBUG(3, ("Invalid domain! Expected name in domain [%s]. " 2196 "But received NULL!\n", dnsdomain)); 2197 } else { 2198 p = strchr(r->in.server_name, '.'); 2199 if (!p) { 2200 DEBUG(3, ("Invalid domain! Expected name in domain " 2201 "[%s]. But received [%s]!\n", 2202 dnsdomain, r->in.server_name)); 2203 p = r->in.server_name; 2204 } else { 2205 p++; 2206 } 2207 if (strcasecmp(p, dnsdomain)) { 2208 DEBUG(3, ("Invalid domain! Expected name in domain " 2209 "[%s]. But received [%s]!\n", 2210 dnsdomain, r->in.server_name)); 2211 } 2212 } 2213 2214 trusts = talloc_zero(mem_ctx, struct netr_DomainTrustList); 2215 W_ERROR_HAVE_NO_MEMORY(trusts); 2216 2217 trusts->count = 0; 2218 r->out.trusts = trusts; 2219 2220 sam_ctx = samdb_connect(mem_ctx, dce_call->event_ctx, lp_ctx, 2221 dce_call->conn->auth_state.session_info, 0); 1591 2222 if (sam_ctx == NULL) { 1592 2223 return WERR_GENERAL_FAILURE; 1593 2224 } 1594 2225 1595 ret = gendb_search_dn(sam_ctx, mem_ctx, NULL, 1596 &dom_res, dom_attrs); 1597 if (ret == -1) { 1598 return WERR_GENERAL_FAILURE; 1599 } 2226 if ((r->in.trust_flags & NETR_TRUST_FLAG_INBOUND) || 2227 (r->in.trust_flags & NETR_TRUST_FLAG_OUTBOUND)) { 2228 2229 werr = fill_trusted_domains_array(mem_ctx, sam_ctx, 2230 trusts, r->in.trust_flags); 2231 W_ERROR_NOT_OK_RETURN(werr); 2232 } 2233 2234 /* NOTE: we currently are always the root of the forest */ 2235 if (r->in.trust_flags & NETR_TRUST_FLAG_IN_FOREST) { 2236 uint32_t n = trusts->count; 2237 2238 ret = gendb_search_dn(sam_ctx, mem_ctx, NULL, 2239 &dom_res, dom_attrs); 2240 if (ret != 1) { 2241 return WERR_GENERAL_FAILURE; 2242 } 2243 2244 trusts->count = n + 1; 2245 trusts->array = talloc_realloc(trusts, trusts->array, 2246 struct netr_DomainTrust, 2247 trusts->count); 2248 W_ERROR_HAVE_NO_MEMORY(trusts->array); 2249 2250 trusts->array[n].netbios_name = lpcfg_workgroup(lp_ctx); 2251 trusts->array[n].dns_name = lpcfg_dnsdomain(lp_ctx); 2252 trusts->array[n].trust_flags = 2253 NETR_TRUST_FLAG_NATIVE | 2254 NETR_TRUST_FLAG_TREEROOT | 2255 NETR_TRUST_FLAG_IN_FOREST | 2256 NETR_TRUST_FLAG_PRIMARY; 2257 /* we are always the root domain for now */ 2258 trusts->array[n].parent_index = 0; 2259 trusts->array[n].trust_type = NETR_TRUST_TYPE_UPLEVEL; 2260 trusts->array[n].trust_attributes = 0; 2261 trusts->array[n].sid = samdb_result_dom_sid(mem_ctx, 2262 dom_res[0], 2263 "objectSid"); 2264 trusts->array[n].guid = samdb_result_guid(dom_res[0], 2265 "objectGUID"); 2266 talloc_free(dom_res); 2267 } 2268 2269 return WERR_OK; 2270 } 2271 2272 2273 /* 2274 netr_DsrDeregisterDNSHostRecords 2275 */ 2276 static WERROR dcesrv_netr_DsrDeregisterDNSHostRecords(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, 2277 struct netr_DsrDeregisterDNSHostRecords *r) 2278 { 2279 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR); 2280 } 2281 2282 2283 /* 2284 netr_ServerTrustPasswordsGet 2285 */ 2286 static NTSTATUS dcesrv_netr_ServerTrustPasswordsGet(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, 2287 struct netr_ServerTrustPasswordsGet *r) 2288 { 2289 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR); 2290 } 2291 2292 2293 static WERROR fill_forest_trust_array(TALLOC_CTX *mem_ctx, 2294 struct ldb_context *sam_ctx, 2295 struct loadparm_context *lp_ctx, 2296 struct lsa_ForestTrustInformation *info) 2297 { 2298 struct lsa_ForestTrustDomainInfo *domain_info; 2299 struct lsa_ForestTrustRecord *e; 2300 struct ldb_message **dom_res; 2301 const char * const dom_attrs[] = { "objectSid", NULL }; 2302 int ret; 2303 2304 /* we need to provide 2 entries: 2305 * 1. the Root Forest name 2306 * 2. the Domain Information 2307 */ 2308 2309 info->count = 2; 2310 info->entries = talloc_array(info, struct lsa_ForestTrustRecord *, 2); 2311 W_ERROR_HAVE_NO_MEMORY(info->entries); 2312 2313 /* Forest root info */ 2314 e = talloc(info, struct lsa_ForestTrustRecord); 2315 W_ERROR_HAVE_NO_MEMORY(e); 2316 2317 e->flags = 0; 2318 e->type = LSA_FOREST_TRUST_TOP_LEVEL_NAME; 2319 e->time = 0; /* so far always 0 in trces. */ 2320 e->forest_trust_data.top_level_name.string = samdb_forest_name(sam_ctx, 2321 mem_ctx); 2322 W_ERROR_HAVE_NO_MEMORY(e->forest_trust_data.top_level_name.string); 2323 2324 info->entries[0] = e; 2325 2326 /* Domain info */ 2327 e = talloc(info, struct lsa_ForestTrustRecord); 2328 W_ERROR_HAVE_NO_MEMORY(e); 2329 2330 /* get our own domain info */ 2331 ret = gendb_search_dn(sam_ctx, mem_ctx, NULL, &dom_res, dom_attrs); 1600 2332 if (ret != 1) { 1601 2333 return WERR_GENERAL_FAILURE; 1602 2334 } 1603 2335 1604 trusts = talloc(mem_ctx, struct netr_DomainTrustList); 1605 W_ERROR_HAVE_NO_MEMORY(trusts); 1606 1607 trusts->array = talloc_array(trusts, struct netr_DomainTrust, ret); 1608 W_ERROR_HAVE_NO_MEMORY(trusts->array); 1609 1610 trusts->count = 1; /* ?? */ 1611 1612 r->out.trusts = trusts; 1613 1614 /* TODO: add filtering by trust_flags, and correct trust_type 1615 and attributes */ 1616 trusts->array[0].netbios_name = lp_sam_name(dce_call->conn->dce_ctx->lp_ctx); 1617 trusts->array[0].dns_name = lp_realm(dce_call->conn->dce_ctx->lp_ctx); 1618 trusts->array[0].trust_flags = 1619 NETR_TRUST_FLAG_TREEROOT | 1620 NETR_TRUST_FLAG_IN_FOREST | 1621 NETR_TRUST_FLAG_PRIMARY; 1622 trusts->array[0].parent_index = 0; 1623 trusts->array[0].trust_type = 2; 1624 trusts->array[0].trust_attributes = 0; 1625 trusts->array[0].sid = samdb_result_dom_sid(mem_ctx, dom_res[0], "objectSid"); 1626 trusts->array[0].guid = samdb_result_guid(dom_res[0], "objectGUID"); 2336 /* TODO: check if disabled and set flags accordingly */ 2337 e->flags = 0; 2338 e->type = LSA_FOREST_TRUST_DOMAIN_INFO; 2339 e->time = 0; /* so far always 0 in traces. */ 2340 2341 domain_info = &e->forest_trust_data.domain_info; 2342 domain_info->domain_sid = samdb_result_dom_sid(info, dom_res[0], 2343 "objectSid"); 2344 domain_info->dns_domain_name.string = lpcfg_dnsdomain(lp_ctx); 2345 domain_info->netbios_domain_name.string = lpcfg_workgroup(lp_ctx); 2346 2347 info->entries[1] = e; 2348 2349 talloc_free(dom_res); 1627 2350 1628 2351 return WERR_OK; 1629 2352 } 1630 2353 1631 1632 /* 1633 netr_DsrDeregisterDNSHostRecords 1634 */ 1635 static WERROR dcesrv_netr_DsrDeregisterDNSHostRecords(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, 1636 struct netr_DsrDeregisterDNSHostRecords *r) 1637 { 1638 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR); 1639 } 1640 1641 1642 /* 1643 netr_ServerTrustPasswordsGet 1644 */ 1645 static NTSTATUS dcesrv_netr_ServerTrustPasswordsGet(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, 1646 struct netr_ServerTrustPasswordsGet *r) 1647 { 1648 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR); 1649 } 1650 1651 1652 /* 1653 netr_DsRGetForestTrustInformation 1654 */ 1655 static WERROR dcesrv_netr_DsRGetForestTrustInformation(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, 1656 struct netr_DsRGetForestTrustInformation *r) 1657 { 1658 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR); 2354 /* 2355 netr_DsRGetForestTrustInformation 2356 */ 2357 static WERROR dcesrv_netr_DsRGetForestTrustInformation(struct dcesrv_call_state *dce_call, 2358 TALLOC_CTX *mem_ctx, 2359 struct netr_DsRGetForestTrustInformation *r) 2360 { 2361 struct loadparm_context *lp_ctx = dce_call->conn->dce_ctx->lp_ctx; 2362 struct lsa_ForestTrustInformation *info, **info_ptr; 2363 struct ldb_context *sam_ctx; 2364 WERROR werr; 2365 2366 if (r->in.flags & 0xFFFFFFFE) { 2367 return WERR_INVALID_FLAGS; 2368 } 2369 2370 sam_ctx = samdb_connect(mem_ctx, dce_call->event_ctx, lp_ctx, 2371 dce_call->conn->auth_state.session_info, 0); 2372 if (sam_ctx == NULL) { 2373 return WERR_GENERAL_FAILURE; 2374 } 2375 2376 if (r->in.flags & DS_GFTI_UPDATE_TDO) { 2377 if (!samdb_is_pdc(sam_ctx)) { 2378 return WERR_NERR_NOTPRIMARY; 2379 } 2380 2381 if (r->in.trusted_domain_name == NULL) { 2382 return WERR_INVALID_FLAGS; 2383 } 2384 2385 /* TODO: establish an schannel connection with 2386 * r->in.trusted_domain_name and perform a 2387 * netr_GetForestTrustInformation call against it */ 2388 2389 /* for now return not implementd */ 2390 return WERR_CALL_NOT_IMPLEMENTED; 2391 } 2392 2393 /* TODO: check r->in.server_name is our name */ 2394 2395 info_ptr = talloc(mem_ctx, struct lsa_ForestTrustInformation *); 2396 W_ERROR_HAVE_NO_MEMORY(info_ptr); 2397 2398 info = talloc_zero(info_ptr, struct lsa_ForestTrustInformation); 2399 W_ERROR_HAVE_NO_MEMORY(info); 2400 2401 werr = fill_forest_trust_array(mem_ctx, sam_ctx, lp_ctx, info); 2402 W_ERROR_NOT_OK_RETURN(werr); 2403 2404 *info_ptr = info; 2405 r->out.forest_trust_info = info_ptr; 2406 2407 return WERR_OK; 1659 2408 } 1660 2409 … … 1663 2412 netr_GetForestTrustInformation 1664 2413 */ 1665 static WERROR dcesrv_netr_GetForestTrustInformation(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, 1666 struct netr_GetForestTrustInformation *r) 1667 { 1668 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR); 2414 static NTSTATUS dcesrv_netr_GetForestTrustInformation(struct dcesrv_call_state *dce_call, 2415 TALLOC_CTX *mem_ctx, 2416 struct netr_GetForestTrustInformation *r) 2417 { 2418 struct loadparm_context *lp_ctx = dce_call->conn->dce_ctx->lp_ctx; 2419 struct netlogon_creds_CredentialState *creds; 2420 struct lsa_ForestTrustInformation *info, **info_ptr; 2421 struct ldb_context *sam_ctx; 2422 NTSTATUS status; 2423 WERROR werr; 2424 2425 status = dcesrv_netr_creds_server_step_check(dce_call, 2426 mem_ctx, 2427 r->in.computer_name, 2428 r->in.credential, 2429 r->out.return_authenticator, 2430 &creds); 2431 if (!NT_STATUS_IS_OK(status)) { 2432 return status; 2433 } 2434 2435 if ((creds->secure_channel_type != SEC_CHAN_DNS_DOMAIN) && 2436 (creds->secure_channel_type != SEC_CHAN_DOMAIN)) { 2437 return NT_STATUS_NOT_IMPLEMENTED; 2438 } 2439 2440 sam_ctx = samdb_connect(mem_ctx, dce_call->event_ctx, lp_ctx, 2441 dce_call->conn->auth_state.session_info, 0); 2442 if (sam_ctx == NULL) { 2443 return NT_STATUS_UNSUCCESSFUL; 2444 } 2445 2446 /* TODO: check r->in.server_name is our name */ 2447 2448 info_ptr = talloc(mem_ctx, struct lsa_ForestTrustInformation *); 2449 if (!info_ptr) { 2450 return NT_STATUS_NO_MEMORY; 2451 } 2452 info = talloc_zero(info_ptr, struct lsa_ForestTrustInformation); 2453 if (!info) { 2454 return NT_STATUS_NO_MEMORY; 2455 } 2456 2457 werr = fill_forest_trust_array(mem_ctx, sam_ctx, lp_ctx, info); 2458 if (!W_ERROR_IS_OK(werr)) { 2459 return werror_to_ntstatus(werr); 2460 } 2461 2462 *info_ptr = info; 2463 r->out.forest_trust_info = info_ptr; 2464 2465 return NT_STATUS_OK; 1669 2466 } 1670 2467 … … 1679 2476 } 1680 2477 2478 /* 2479 netr_Unused47 2480 */ 2481 static NTSTATUS dcesrv_netr_Unused47(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, 2482 struct netr_Unused47 *r) 2483 { 2484 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR); 2485 } 2486 2487 2488 struct netr_dnsupdate_RODC_state { 2489 struct dcesrv_call_state *dce_call; 2490 struct netr_DsrUpdateReadOnlyServerDnsRecords *r; 2491 struct dnsupdate_RODC *r2; 2492 }; 2493 2494 /* 2495 called when the forwarded RODC dns update request is finished 2496 */ 2497 static void netr_dnsupdate_RODC_callback(struct tevent_req *subreq) 2498 { 2499 struct netr_dnsupdate_RODC_state *st = 2500 tevent_req_callback_data(subreq, 2501 struct netr_dnsupdate_RODC_state); 2502 NTSTATUS status; 2503 2504 status = dcerpc_dnsupdate_RODC_r_recv(subreq, st->dce_call); 2505 TALLOC_FREE(subreq); 2506 if (!NT_STATUS_IS_OK(status)) { 2507 DEBUG(0,(__location__ ": IRPC callback failed %s\n", nt_errstr(status))); 2508 st->dce_call->fault_code = DCERPC_FAULT_CANT_PERFORM; 2509 } 2510 2511 st->r->out.dns_names = talloc_steal(st->dce_call, st->r2->out.dns_names); 2512 2513 status = dcesrv_reply(st->dce_call); 2514 if (!NT_STATUS_IS_OK(status)) { 2515 DEBUG(0,(__location__ ": dcesrv_reply() failed - %s\n", nt_errstr(status))); 2516 } 2517 } 2518 2519 /* 2520 netr_DsrUpdateReadOnlyServerDnsRecords 2521 */ 2522 static NTSTATUS dcesrv_netr_DsrUpdateReadOnlyServerDnsRecords(struct dcesrv_call_state *dce_call, 2523 TALLOC_CTX *mem_ctx, 2524 struct netr_DsrUpdateReadOnlyServerDnsRecords *r) 2525 { 2526 struct netlogon_creds_CredentialState *creds; 2527 NTSTATUS nt_status; 2528 struct dcerpc_binding_handle *binding_handle; 2529 struct netr_dnsupdate_RODC_state *st; 2530 struct tevent_req *subreq; 2531 2532 nt_status = dcesrv_netr_creds_server_step_check(dce_call, 2533 mem_ctx, 2534 r->in.computer_name, 2535 r->in.credential, 2536 r->out.return_authenticator, 2537 &creds); 2538 NT_STATUS_NOT_OK_RETURN(nt_status); 2539 2540 if (creds->secure_channel_type != SEC_CHAN_RODC) { 2541 return NT_STATUS_ACCESS_DENIED; 2542 } 2543 2544 st = talloc_zero(mem_ctx, struct netr_dnsupdate_RODC_state); 2545 NT_STATUS_HAVE_NO_MEMORY(st); 2546 2547 st->dce_call = dce_call; 2548 st->r = r; 2549 st->r2 = talloc_zero(st, struct dnsupdate_RODC); 2550 NT_STATUS_HAVE_NO_MEMORY(st->r2); 2551 2552 st->r2->in.dom_sid = creds->sid; 2553 st->r2->in.site_name = r->in.site_name; 2554 st->r2->in.dns_ttl = r->in.dns_ttl; 2555 st->r2->in.dns_names = r->in.dns_names; 2556 st->r2->out.dns_names = r->out.dns_names; 2557 2558 binding_handle = irpc_binding_handle_by_name(st, dce_call->msg_ctx, 2559 "dnsupdate", &ndr_table_irpc); 2560 if (binding_handle == NULL) { 2561 DEBUG(0,("Failed to get binding_handle for dnsupdate task\n")); 2562 dce_call->fault_code = DCERPC_FAULT_CANT_PERFORM; 2563 return NT_STATUS_INTERNAL_DB_CORRUPTION; 2564 } 2565 2566 /* forward the call */ 2567 subreq = dcerpc_dnsupdate_RODC_r_send(st, dce_call->event_ctx, 2568 binding_handle, st->r2); 2569 NT_STATUS_HAVE_NO_MEMORY(subreq); 2570 2571 dce_call->state_flags |= DCESRV_CALL_STATE_FLAG_ASYNC; 2572 2573 /* setup the callback */ 2574 tevent_req_set_callback(subreq, netr_dnsupdate_RODC_callback, st); 2575 2576 return NT_STATUS_OK; 2577 } 2578 1681 2579 1682 2580 /* include the generated boilerplate */
Note:
See TracChangeset
for help on using the changeset viewer.