Changeset 988 for vendor/current/source4/rpc_server
- Timestamp:
- Nov 24, 2016, 1:14:11 PM (9 years ago)
- Location:
- vendor/current/source4/rpc_server
- Files:
-
- 8 added
- 34 edited
Legend:
- Unmodified
- Added
- Removed
-
vendor/current/source4/rpc_server/backupkey/dcesrv_backupkey.c
r740 r988 5 5 6 6 Copyright (C) Matthieu Patou <mat@samba.org> 2010 7 Copyright (C) Andreas Schneider <asn@samba.org> 2015 7 8 8 9 This program is free software; you can redistribute it and/or modify … … 29 30 #include "param/param.h" 30 31 #include "auth/session.h" 31 #include "heimdal/lib/hx509/hx_locl.h" 32 #include "heimdal/lib/hcrypto/rsa.h" 33 #include "heimdal/lib/hcrypto/bn.h" 32 #include "system/network.h" 33 34 34 #include "../lib/tsocket/tsocket.h" 35 35 #include "../libcli/security/security.h" 36 37 #define BACKUPKEY_MIN_VERSION 2 38 #define BACKUPKEY_MAX_VERSION 3 39 40 static const unsigned rsa_with_var_num[] = { 1, 2, 840, 113549, 1, 1, 1 }; 41 /* Equivalent to asn1_oid_id_pkcs1_rsaEncryption*/ 42 static const AlgorithmIdentifier _hx509_signature_rsa_with_var_num = { 43 { 7, discard_const_p(unsigned, rsa_with_var_num) }, NULL 44 }; 36 #include "librpc/gen_ndr/ndr_security.h" 37 #include "libds/common/roles.h" 38 39 #include <gnutls/gnutls.h> 40 #include <gnutls/x509.h> 41 #include <gnutls/crypto.h> 42 #include <gnutls/abstract.h> 43 44 #define DCESRV_INTERFACE_BACKUPKEY_BIND(call, iface) \ 45 dcesrv_interface_backupkey_bind(call, iface) 46 static NTSTATUS dcesrv_interface_backupkey_bind(struct dcesrv_call_state *dce_call, 47 const struct dcesrv_interface *iface) 48 { 49 return dcesrv_interface_bind_require_privacy(dce_call, iface); 50 } 45 51 46 52 static NTSTATUS set_lsa_secret(TALLOC_CTX *mem_ctx, 47 53 struct ldb_context *ldb, 48 54 const char *name, 49 const DATA_BLOB * secret)55 const DATA_BLOB *lsa_secret) 50 56 { 51 57 struct ldb_message *msg; … … 134 140 return NT_STATUS_NO_MEMORY; 135 141 } 136 val.data = secret->data;137 val.length = secret->length;142 val.data = lsa_secret->data; 143 val.length = lsa_secret->length; 138 144 ret = ldb_msg_add_value(msg, "currentValue", &val, NULL); 139 145 if (ret != LDB_SUCCESS) { … … 169 175 struct ldb_context *ldb, 170 176 const char *name, 171 DATA_BLOB * secret)177 DATA_BLOB *lsa_secret) 172 178 { 173 179 TALLOC_CTX *tmp_mem; … … 183 189 int ret; 184 190 185 secret->data = NULL;186 secret->length = 0;191 lsa_secret->data = NULL; 192 lsa_secret->length = 0; 187 193 188 194 domain_dn = ldb_get_default_basedn(ldb); … … 206 212 ldb_binary_encode_string(tmp_mem, name)); 207 213 208 if (ret != LDB_SUCCESS || res->count == 0) {214 if (ret != LDB_SUCCESS) { 209 215 talloc_free(tmp_mem); 210 /* 211 * Important NOT to use NT_STATUS_OBJECT_NAME_NOT_FOUND 212 * as this return value is used to detect the case 213 * when we have the secret but without the currentValue 214 * (case RODC) 215 */ 216 return NT_STATUS_INTERNAL_DB_CORRUPTION; 217 } 218 if (res->count == 0) { 219 talloc_free(tmp_mem); 216 220 return NT_STATUS_RESOURCE_NAME_NOT_FOUND; 217 221 } 218 219 222 if (res->count > 1) { 220 223 DEBUG(2, ("Secret %s collision\n", name)); … … 229 232 * The most common case is a RODC 230 233 */ 234 *lsa_secret = data_blob_null; 231 235 talloc_free(tmp_mem); 232 return NT_STATUS_O BJECT_NAME_NOT_FOUND;236 return NT_STATUS_OK; 233 237 } 234 238 235 239 data = val->data; 236 secret->data = talloc_move(mem_ctx, &data);237 secret->length = val->length;240 lsa_secret->data = talloc_move(mem_ctx, &data); 241 lsa_secret->length = val->length; 238 242 239 243 talloc_free(tmp_mem); … … 241 245 } 242 246 243 static DATA_BLOB *reverse_and_get_blob(TALLOC_CTX *mem_ctx, BIGNUM *bn) 247 static int reverse_and_get_bignum(TALLOC_CTX *mem_ctx, 248 DATA_BLOB blob, 249 gnutls_datum_t *datum) 244 250 { 245 DATA_BLOB blob;246 DATA_BLOB *rev = talloc(mem_ctx, DATA_BLOB);247 251 uint32_t i; 248 252 249 blob.length = BN_num_bytes(bn); 250 blob.data = talloc_array(mem_ctx, uint8_t, blob.length); 251 252 if (blob.data == NULL) { 253 return NULL; 254 } 255 256 BN_bn2bin(bn, blob.data); 257 258 rev->data = talloc_array(mem_ctx, uint8_t, blob.length); 259 if (rev->data == NULL) { 260 return NULL; 261 } 262 263 for(i=0; i < blob.length; i++) { 264 rev->data[i] = blob.data[blob.length - i -1]; 265 } 266 rev->length = blob.length; 267 talloc_free(blob.data); 268 return rev; 269 } 270 271 static BIGNUM *reverse_and_get_bignum(TALLOC_CTX *mem_ctx, DATA_BLOB *blob) 272 { 273 BIGNUM *ret; 274 DATA_BLOB rev; 275 uint32_t i; 276 277 rev.data = talloc_array(mem_ctx, uint8_t, blob->length); 278 if (rev.data == NULL) { 279 return NULL; 280 } 281 282 for(i=0; i < blob->length; i++) { 283 rev.data[i] = blob->data[blob->length - i -1]; 284 } 285 rev.length = blob->length; 286 287 ret = BN_bin2bn(rev.data, rev.length, NULL); 288 talloc_free(rev.data); 289 290 return ret; 253 datum->data = talloc_array(mem_ctx, uint8_t, blob.length); 254 if (datum->data == NULL) { 255 return -1; 256 } 257 258 for(i = 0; i < blob.length; i++) { 259 datum->data[i] = blob.data[blob.length - i - 1]; 260 } 261 datum->size = blob.length; 262 263 return 0; 291 264 } 292 265 293 266 static NTSTATUS get_pk_from_raw_keypair_params(TALLOC_CTX *ctx, 294 267 struct bkrp_exported_RSA_key_pair *keypair, 295 hx509_private_key*pk)268 gnutls_privkey_t *pk) 296 269 { 297 hx509_context hctx; 298 RSA *rsa; 299 struct hx509_private_key_ops *ops; 300 301 hx509_context_init(&hctx); 302 ops = hx509_find_private_alg(&_hx509_signature_rsa_with_var_num.algorithm); 303 if (ops == NULL) { 304 DEBUG(2, ("Not supported algorithm\n")); 270 gnutls_x509_privkey_t x509_privkey = NULL; 271 gnutls_privkey_t privkey = NULL; 272 gnutls_datum_t m, e, d, p, q, u, e1, e2; 273 int rc; 274 275 rc = reverse_and_get_bignum(ctx, keypair->modulus, &m); 276 if (rc != 0) { 277 return NT_STATUS_INVALID_PARAMETER; 278 } 279 rc = reverse_and_get_bignum(ctx, keypair->public_exponent, &e); 280 if (rc != 0) { 281 return NT_STATUS_INVALID_PARAMETER; 282 } 283 rc = reverse_and_get_bignum(ctx, keypair->private_exponent, &d); 284 if (rc != 0) { 285 return NT_STATUS_INVALID_PARAMETER; 286 } 287 288 rc = reverse_and_get_bignum(ctx, keypair->prime1, &p); 289 if (rc != 0) { 290 return NT_STATUS_INVALID_PARAMETER; 291 } 292 rc = reverse_and_get_bignum(ctx, keypair->prime2, &q); 293 if (rc != 0) { 294 return NT_STATUS_INVALID_PARAMETER; 295 } 296 297 rc = reverse_and_get_bignum(ctx, keypair->coefficient, &u); 298 if (rc != 0) { 299 return NT_STATUS_INVALID_PARAMETER; 300 } 301 302 rc = reverse_and_get_bignum(ctx, keypair->exponent1, &e1); 303 if (rc != 0) { 304 return NT_STATUS_INVALID_PARAMETER; 305 } 306 rc = reverse_and_get_bignum(ctx, keypair->exponent2, &e2); 307 if (rc != 0) { 308 return NT_STATUS_INVALID_PARAMETER; 309 } 310 311 rc = gnutls_x509_privkey_init(&x509_privkey); 312 if (rc != GNUTLS_E_SUCCESS) { 313 DBG_ERR("gnutls_x509_privkey_init failed - %s\n", 314 gnutls_strerror(rc)); 305 315 return NT_STATUS_INTERNAL_ERROR; 306 316 } 307 317 308 if (hx509_private_key_init(pk, ops, NULL) != 0) { 309 hx509_context_free(&hctx); 310 return NT_STATUS_NO_MEMORY; 311 } 312 313 rsa = RSA_new(); 314 if (rsa ==NULL) { 315 hx509_context_free(&hctx); 316 return NT_STATUS_INVALID_PARAMETER; 317 } 318 319 rsa->n = reverse_and_get_bignum(ctx, &(keypair->modulus)); 320 if (rsa->n == NULL) { 321 RSA_free(rsa); 322 hx509_context_free(&hctx); 323 return NT_STATUS_INVALID_PARAMETER; 324 } 325 rsa->d = reverse_and_get_bignum(ctx, &(keypair->private_exponent)); 326 if (rsa->d == NULL) { 327 RSA_free(rsa); 328 hx509_context_free(&hctx); 329 return NT_STATUS_INVALID_PARAMETER; 330 } 331 rsa->p = reverse_and_get_bignum(ctx, &(keypair->prime1)); 332 if (rsa->p == NULL) { 333 RSA_free(rsa); 334 hx509_context_free(&hctx); 335 return NT_STATUS_INVALID_PARAMETER; 336 } 337 rsa->q = reverse_and_get_bignum(ctx, &(keypair->prime2)); 338 if (rsa->q == NULL) { 339 RSA_free(rsa); 340 hx509_context_free(&hctx); 341 return NT_STATUS_INVALID_PARAMETER; 342 } 343 rsa->dmp1 = reverse_and_get_bignum(ctx, &(keypair->exponent1)); 344 if (rsa->dmp1 == NULL) { 345 RSA_free(rsa); 346 hx509_context_free(&hctx); 347 return NT_STATUS_INVALID_PARAMETER; 348 } 349 rsa->dmq1 = reverse_and_get_bignum(ctx, &(keypair->exponent2)); 350 if (rsa->dmq1 == NULL) { 351 RSA_free(rsa); 352 hx509_context_free(&hctx); 353 return NT_STATUS_INVALID_PARAMETER; 354 } 355 rsa->iqmp = reverse_and_get_bignum(ctx, &(keypair->coefficient)); 356 if (rsa->iqmp == NULL) { 357 RSA_free(rsa); 358 hx509_context_free(&hctx); 359 return NT_STATUS_INVALID_PARAMETER; 360 } 361 rsa->e = reverse_and_get_bignum(ctx, &(keypair->public_exponent)); 362 if (rsa->e == NULL) { 363 RSA_free(rsa); 364 hx509_context_free(&hctx); 365 return NT_STATUS_INVALID_PARAMETER; 366 } 367 368 hx509_private_key_assign_rsa(*pk, rsa); 369 370 hx509_context_free(&hctx); 318 rc = gnutls_x509_privkey_import_rsa_raw2(x509_privkey, 319 &m, 320 &e, 321 &d, 322 &p, 323 &q, 324 &u, 325 &e1, 326 &e2); 327 if (rc != GNUTLS_E_SUCCESS) { 328 DBG_ERR("gnutls_x509_privkey_import_rsa_raw2 failed - %s\n", 329 gnutls_strerror(rc)); 330 return NT_STATUS_INTERNAL_ERROR; 331 } 332 333 rc = gnutls_privkey_init(&privkey); 334 if (rc != GNUTLS_E_SUCCESS) { 335 DBG_ERR("gnutls_privkey_init failed - %s\n", 336 gnutls_strerror(rc)); 337 gnutls_x509_privkey_deinit(x509_privkey); 338 return NT_STATUS_INTERNAL_ERROR; 339 } 340 341 rc = gnutls_privkey_import_x509(privkey, 342 x509_privkey, 343 GNUTLS_PRIVKEY_IMPORT_AUTO_RELEASE); 344 if (rc != GNUTLS_E_SUCCESS) { 345 DBG_ERR("gnutls_privkey_import_x509 failed - %s\n", 346 gnutls_strerror(rc)); 347 gnutls_x509_privkey_deinit(x509_privkey); 348 return NT_STATUS_INTERNAL_ERROR; 349 } 350 351 *pk = privkey; 352 371 353 return NT_STATUS_OK; 372 354 } … … 377 359 uint8_t *access_check, 378 360 uint32_t access_check_len, 379 struct dom_sid **access_sid)361 struct auth_session_info *session_info) 380 362 { 381 heim_octet_string iv; 382 heim_octet_string access_check_os; 383 hx509_crypto crypto; 384 363 gnutls_cipher_hd_t cipher_handle = { 0 }; 364 gnutls_cipher_algorithm_t cipher_algo; 385 365 DATA_BLOB blob_us; 386 uint32_t key_len;387 uint32_t iv_len;388 int res;389 366 enum ndr_err_code ndr_err; 390 hx509_context hctx; 391 392 /* This one should not be freed */ 393 const AlgorithmIdentifier *alg; 394 395 *access_sid = NULL; 367 gnutls_datum_t key; 368 gnutls_datum_t iv; 369 370 struct dom_sid *access_sid = NULL; 371 struct dom_sid *caller_sid = NULL; 372 int rc; 373 396 374 switch (version) { 397 375 case 2: 398 key_len = 24; 399 iv_len = 8; 400 alg = hx509_crypto_des_rsdi_ede3_cbc(); 376 cipher_algo = GNUTLS_CIPHER_3DES_CBC; 401 377 break; 402 403 378 case 3: 404 key_len = 32; 405 iv_len = 16; 406 alg =hx509_crypto_aes256_cbc(); 379 cipher_algo = GNUTLS_CIPHER_AES_256_CBC; 407 380 break; 408 409 381 default: 410 382 return WERR_INVALID_DATA; 411 383 } 412 384 413 hx509_context_init(&hctx); 414 res = hx509_crypto_init(hctx, NULL, 415 &(alg->algorithm), 416 &crypto); 417 hx509_context_free(&hctx); 418 419 if (res != 0) { 385 key.data = key_and_iv; 386 key.size = gnutls_cipher_get_key_size(cipher_algo); 387 388 iv.data = key_and_iv + key.size; 389 iv.size = gnutls_cipher_get_iv_size(cipher_algo); 390 391 /* Allocate data structure for the plaintext */ 392 blob_us = data_blob_talloc_zero(sub_ctx, access_check_len); 393 if (blob_us.data == NULL) { 420 394 return WERR_INVALID_DATA; 421 395 } 422 396 423 r es = hx509_crypto_set_key_data(crypto, key_and_iv, key_len);424 425 iv.data = talloc_memdup(sub_ctx, key_len + key_and_iv, iv_len);426 iv.length = iv_len;427 428 if (res != 0) {429 hx509_crypto_destroy(crypto);397 rc = gnutls_cipher_init(&cipher_handle, 398 cipher_algo, 399 &key, 400 &iv); 401 if (rc < 0) { 402 DBG_ERR("gnutls_cipher_init failed: %s\n", 403 gnutls_strerror(rc)); 430 404 return WERR_INVALID_DATA; 431 405 } 432 406 433 hx509_crypto_set_padding(crypto, HX509_CRYPTO_PADDING_NONE);434 res = hx509_crypto_decrypt(crypto,435 access_check,436 access_check_len,437 &iv,438 &access_check_os);439 440 if (res != 0) {441 hx509_crypto_destroy(crypto);407 rc = gnutls_cipher_decrypt2(cipher_handle, 408 access_check, 409 access_check_len, 410 blob_us.data, 411 blob_us.length); 412 gnutls_cipher_deinit(cipher_handle); 413 if (rc < 0) { 414 DBG_ERR("gnutls_cipher_decrypt2 failed: %s\n", 415 gnutls_strerror(rc)); 442 416 return WERR_INVALID_DATA; 443 417 } 444 418 445 blob_us.data = access_check_os.data; 446 blob_us.length = access_check_os.length; 447 448 hx509_crypto_destroy(crypto); 449 450 if (version == 2) { 419 switch (version) { 420 case 2: 421 { 451 422 uint32_t hash_size = 20; 452 423 uint8_t hash[hash_size]; 453 struct sha sctx;424 gnutls_hash_hd_t dig_ctx; 454 425 struct bkrp_access_check_v2 uncrypted_accesscheckv2; 455 426 … … 458 429 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { 459 430 /* Unable to unmarshall */ 460 der_free_octet_string(&access_check_os);461 431 return WERR_INVALID_DATA; 462 432 } 463 433 if (uncrypted_accesscheckv2.magic != 0x1) { 464 434 /* wrong magic */ 465 der_free_octet_string(&access_check_os);466 435 return WERR_INVALID_DATA; 467 436 } 468 437 469 SHA1_Init(&sctx); 470 SHA1_Update(&sctx, blob_us.data, blob_us.length - hash_size); 471 SHA1_Final(hash, &sctx); 472 der_free_octet_string(&access_check_os); 438 gnutls_hash_init(&dig_ctx, GNUTLS_DIG_SHA1); 439 gnutls_hash(dig_ctx, 440 blob_us.data, 441 blob_us.length - hash_size); 442 gnutls_hash_deinit(dig_ctx, hash); 473 443 /* 474 444 * We free it after the sha1 calculation because blob.data … … 480 450 return WERR_INVALID_DATA; 481 451 } 482 *access_sid = dom_sid_dup(sub_ctx, &(uncrypted_accesscheckv2.sid)); 483 if (*access_sid == NULL) { 484 return WERR_NOMEM; 485 } 486 return WERR_OK; 487 } 488 489 if (version == 3) { 452 access_sid = &(uncrypted_accesscheckv2.sid); 453 break; 454 } 455 case 3: 456 { 490 457 uint32_t hash_size = 64; 491 458 uint8_t hash[hash_size]; 492 struct hc_sha512state sctx;459 gnutls_hash_hd_t dig_ctx; 493 460 struct bkrp_access_check_v3 uncrypted_accesscheckv3; 494 461 … … 497 464 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { 498 465 /* Unable to unmarshall */ 499 der_free_octet_string(&access_check_os);500 466 return WERR_INVALID_DATA; 501 467 } 502 468 if (uncrypted_accesscheckv3.magic != 0x1) { 503 469 /* wrong magic */ 504 der_free_octet_string(&access_check_os);505 470 return WERR_INVALID_DATA; 506 471 } 507 472 508 SHA512_Init(&sctx); 509 SHA512_Update(&sctx, blob_us.data, blob_us.length - hash_size); 510 SHA512_Final(hash, &sctx); 511 der_free_octet_string(&access_check_os); 473 gnutls_hash_init(&dig_ctx, GNUTLS_DIG_SHA512); 474 gnutls_hash(dig_ctx, 475 blob_us.data, 476 blob_us.length - hash_size); 477 gnutls_hash_deinit(dig_ctx, hash); 478 512 479 /* 513 480 * We free it after the sha1 calculation because blob.data … … 519 486 return WERR_INVALID_DATA; 520 487 } 521 *access_sid = dom_sid_dup(sub_ctx, &(uncrypted_accesscheckv3.sid)); 522 if (*access_sid == NULL) { 523 return WERR_NOMEM; 524 } 525 return WERR_OK; 526 } 527 528 /* Never reached normally as we filtered at the switch / case level */ 529 return WERR_INVALID_DATA; 488 access_sid = &(uncrypted_accesscheckv3.sid); 489 break; 490 } 491 default: 492 /* Never reached normally as we filtered at the switch / case level */ 493 return WERR_INVALID_DATA; 494 } 495 496 caller_sid = &session_info->security_token->sids[PRIMARY_USER_SID_INDEX]; 497 498 if (!dom_sid_equal(caller_sid, access_sid)) { 499 return WERR_INVALID_ACCESS; 500 } 501 return WERR_OK; 530 502 } 531 503 532 static WERROR bkrp_do_uncrypt_client_wrap_key(struct dcesrv_call_state *dce_call, 533 TALLOC_CTX *mem_ctx, 534 struct bkrp_BackupKey *r, 535 struct ldb_context *ldb_ctx) 504 /* 505 * We have some data, such as saved website or IMAP passwords that the 506 * client has in profile on-disk. This needs to be decrypted. This 507 * version gives the server the data over the network (protected by 508 * the X.509 certificate and public key encryption, and asks that it 509 * be decrypted returned for short-term use, protected only by the 510 * negotiated transport encryption. 511 * 512 * The data is NOT stored in the LSA, but a X.509 certificate, public 513 * and private keys used to encrypt the data will be stored. There is 514 * only one active encryption key pair and certificate per domain, it 515 * is pointed at with G$BCKUPKEY_PREFERRED in the LSA secrets store. 516 * 517 * The potentially multiple valid decrypting key pairs are in turn 518 * stored in the LSA secrets store as G$BCKUPKEY_keyGuidString. 519 * 520 */ 521 static WERROR bkrp_client_wrap_decrypt_data(struct dcesrv_call_state *dce_call, 522 TALLOC_CTX *mem_ctx, 523 struct bkrp_BackupKey *r, 524 struct ldb_context *ldb_ctx) 536 525 { 537 526 struct bkrp_client_side_wrapped uncrypt_request; … … 540 529 char *guid_string; 541 530 char *cert_secret_name; 542 DATA_BLOB secret;543 DATA_BLOB *uncrypted ;531 DATA_BLOB lsa_secret; 532 DATA_BLOB *uncrypted_data = NULL; 544 533 NTSTATUS status; 534 uint32_t requested_version; 545 535 546 536 blob.data = r->in.data_in; 547 537 blob.length = r->in.data_in_len; 548 538 549 if (r->in.data_in_len == 0 || r->in.data_in == NULL) { 550 return WERR_INVALID_PARAM; 539 if (r->in.data_in_len < 4 || r->in.data_in == NULL) { 540 return WERR_INVALID_PARAM; 541 } 542 543 /* 544 * We check for the version here, so we can actually print the 545 * message as we are unlikely to parse it with NDR. 546 */ 547 requested_version = IVAL(r->in.data_in, 0); 548 if ((requested_version != BACKUPKEY_CLIENT_WRAP_VERSION2) 549 && (requested_version != BACKUPKEY_CLIENT_WRAP_VERSION3)) { 550 DEBUG(1, ("Request for unknown BackupKey sub-protocol %d\n", requested_version)); 551 return WERR_INVALID_PARAMETER; 551 552 } 552 553 … … 557 558 } 558 559 559 if (uncrypt_request.version < BACKUPKEY_MIN_VERSION) { 560 return WERR_INVALID_PARAMETER; 561 } 562 563 if (uncrypt_request.version > BACKUPKEY_MAX_VERSION) { 560 if ((uncrypt_request.version != BACKUPKEY_CLIENT_WRAP_VERSION2) 561 && (uncrypt_request.version != BACKUPKEY_CLIENT_WRAP_VERSION3)) { 562 DEBUG(1, ("Request for unknown BackupKey sub-protocol %d\n", uncrypt_request.version)); 564 563 return WERR_INVALID_PARAMETER; 565 564 } … … 580 579 ldb_ctx, 581 580 cert_secret_name, 582 & secret);581 &lsa_secret); 583 582 if (!NT_STATUS_IS_OK(status)) { 584 583 DEBUG(10, ("Error while fetching secret %s\n", cert_secret_name)); 585 if (NT_STATUS_EQUAL(status,NT_STATUS_OBJECT_NAME_NOT_FOUND)) { 586 /* we do not have the real secret attribute */ 587 return WERR_INVALID_PARAMETER; 588 } else { 589 return WERR_FILE_NOT_FOUND; 590 } 591 } 592 593 if (secret.length != 0) { 594 hx509_context hctx; 584 return WERR_INVALID_DATA; 585 } else if (lsa_secret.length == 0) { 586 /* we do not have the real secret attribute, like if we are an RODC */ 587 return WERR_INVALID_PARAMETER; 588 } else { 595 589 struct bkrp_exported_RSA_key_pair keypair; 596 hx509_private_key pk; 597 uint32_t i, res; 598 struct dom_sid *access_sid = NULL; 599 heim_octet_string reversed_secret; 600 heim_octet_string uncrypted_secret; 601 AlgorithmIdentifier alg; 602 struct dom_sid *caller_sid; 590 gnutls_privkey_t privkey = NULL; 591 gnutls_datum_t reversed_secret; 592 gnutls_datum_t uncrypted_secret; 593 uint32_t i; 603 594 DATA_BLOB blob_us; 604 595 WERROR werr; 605 606 ndr_err = ndr_pull_struct_blob(&secret, mem_ctx, &keypair, (ndr_pull_flags_fn_t)ndr_pull_bkrp_exported_RSA_key_pair); 596 int rc; 597 598 ndr_err = ndr_pull_struct_blob(&lsa_secret, mem_ctx, &keypair, (ndr_pull_flags_fn_t)ndr_pull_bkrp_exported_RSA_key_pair); 607 599 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { 608 600 DEBUG(2, ("Unable to parse the ndr encoded cert in key %s\n", cert_secret_name)); … … 610 602 } 611 603 612 status = get_pk_from_raw_keypair_params(mem_ctx, &keypair, &pk); 604 status = get_pk_from_raw_keypair_params(mem_ctx, 605 &keypair, 606 &privkey); 613 607 if (!NT_STATUS_IS_OK(status)) { 614 608 return WERR_INTERNAL_ERROR; … … 618 612 uncrypt_request.encrypted_secret_len); 619 613 if (reversed_secret.data == NULL) { 620 hx509_private_key_free(&pk);614 gnutls_privkey_deinit(privkey); 621 615 return WERR_NOMEM; 622 616 } … … 628 622 reversed[i] = uncrypt[uncrypt_request.encrypted_secret_len - 1 - i]; 629 623 } 630 reversed_secret. length= uncrypt_request.encrypted_secret_len;624 reversed_secret.size = uncrypt_request.encrypted_secret_len; 631 625 632 626 /* … … 634 628 * we have the private key ... 635 629 */ 636 hx509_context_init(&hctx); 637 res = hx509_private_key_private_decrypt(hctx, &reversed_secret, 638 &alg.algorithm, pk, 639 &uncrypted_secret); 640 hx509_context_free(&hctx); 641 hx509_private_key_free(&pk); 642 if (res != 0) { 630 rc = gnutls_privkey_decrypt_data(privkey, 631 0, 632 &reversed_secret, 633 &uncrypted_secret); 634 gnutls_privkey_deinit(privkey); 635 if (rc != GNUTLS_E_SUCCESS) { 643 636 /* We are not able to decrypt the secret, looks like something is wrong */ 644 return WERR_INVALID_ DATA;637 return WERR_INVALID_PARAMETER; 645 638 } 646 639 blob_us.data = uncrypted_secret.data; 647 blob_us.length = uncrypted_secret. length;640 blob_us.length = uncrypted_secret.size; 648 641 649 642 if (uncrypt_request.version == 2) { … … 652 645 ndr_err = ndr_pull_struct_blob(&blob_us, mem_ctx, &uncrypted_secretv2, 653 646 (ndr_pull_flags_fn_t)ndr_pull_bkrp_encrypted_secret_v2); 654 der_free_octet_string(&uncrypted_secret);647 gnutls_free(uncrypted_secret.data); 655 648 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { 656 649 /* Unable to unmarshall */ … … 666 659 uncrypt_request.access_check, 667 660 uncrypt_request.access_check_len, 668 &access_sid);661 dce_call->conn->auth_state.session_info); 669 662 if (!W_ERROR_IS_OK(werr)) { 670 663 return werr; 671 664 } 672 uncrypted = talloc(mem_ctx, DATA_BLOB);673 if (uncrypted == NULL) {665 uncrypted_data = talloc(mem_ctx, DATA_BLOB); 666 if (uncrypted_data == NULL) { 674 667 return WERR_INVALID_DATA; 675 668 } 676 669 677 uncrypted ->data = uncrypted_secretv2.secret;678 uncrypted ->length = uncrypted_secretv2.secret_len;670 uncrypted_data->data = uncrypted_secretv2.secret; 671 uncrypted_data->length = uncrypted_secretv2.secret_len; 679 672 } 680 673 if (uncrypt_request.version == 3) { … … 683 676 ndr_err = ndr_pull_struct_blob(&blob_us, mem_ctx, &uncrypted_secretv3, 684 677 (ndr_pull_flags_fn_t)ndr_pull_bkrp_encrypted_secret_v3); 685 686 der_free_octet_string(&uncrypted_secret); 678 gnutls_free(uncrypted_secret.data); 687 679 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { 688 680 /* Unable to unmarshall */ … … 697 689 } 698 690 691 /* 692 * Confirm that the caller is permitted to 693 * read this particular data. Because one key 694 * pair is used per domain, the caller could 695 * have stolen the profile data on-disk and 696 * would otherwise be able to read the 697 * passwords. 698 */ 699 699 700 werr = get_and_verify_access_check(mem_ctx, 3, 700 701 uncrypted_secretv3.payload_key, 701 702 uncrypt_request.access_check, 702 703 uncrypt_request.access_check_len, 703 &access_sid);704 dce_call->conn->auth_state.session_info); 704 705 if (!W_ERROR_IS_OK(werr)) { 705 706 return werr; 706 707 } 707 708 708 uncrypted = talloc(mem_ctx, DATA_BLOB);709 if (uncrypted == NULL) {709 uncrypted_data = talloc(mem_ctx, DATA_BLOB); 710 if (uncrypted_data == NULL) { 710 711 return WERR_INVALID_DATA; 711 712 } 712 713 713 uncrypted->data = uncrypted_secretv3.secret; 714 uncrypted->length = uncrypted_secretv3.secret_len; 715 } 716 717 caller_sid = &dce_call->conn->auth_state.session_info->security_token->sids[PRIMARY_USER_SID_INDEX]; 718 719 if (!dom_sid_equal(caller_sid, access_sid)) { 720 talloc_free(uncrypted); 721 return WERR_INVALID_ACCESS; 714 uncrypted_data->data = uncrypted_secretv3.secret; 715 uncrypted_data->length = uncrypted_secretv3.secret_len; 722 716 } 723 717 … … 730 724 } 731 725 732 if (uncrypted ->data == NULL) {726 if (uncrypted_data->data == NULL) { 733 727 return WERR_INVALID_DATA; 734 728 } … … 739 733 * work just prepending 4 bytes 740 734 */ 741 *(r->out.data_out) = talloc_zero_array(mem_ctx, uint8_t, uncrypted ->length + 4);735 *(r->out.data_out) = talloc_zero_array(mem_ctx, uint8_t, uncrypted_data->length + 4); 742 736 W_ERROR_HAVE_NO_MEMORY(*(r->out.data_out)); 743 memcpy(4+*(r->out.data_out), uncrypted ->data, uncrypted->length);744 *(r->out.data_out_len) = uncrypted ->length + 4;737 memcpy(4+*(r->out.data_out), uncrypted_data->data, uncrypted_data->length); 738 *(r->out.data_out_len) = uncrypted_data->length + 4; 745 739 746 740 return WERR_OK; 747 741 } 748 742 749 static WERROR create_heimdal_rsa_key(TALLOC_CTX *ctx, hx509_context *hctx,750 hx509_private_key *pk, RSA **_rsa)743 static DATA_BLOB *reverse_and_get_blob(TALLOC_CTX *mem_ctx, 744 gnutls_datum_t *datum) 751 745 { 752 BIGNUM *pub_expo; 753 RSA *rsa; 754 int ret; 755 uint8_t *p0, *p; 756 size_t len; 746 DATA_BLOB *blob; 747 size_t i; 748 749 blob = talloc(mem_ctx, DATA_BLOB); 750 if (blob == NULL) { 751 return NULL; 752 } 753 754 blob->length = datum->size; 755 if (datum->data[0] == '\0') { 756 /* The datum has a leading byte zero, skip it */ 757 blob->length = datum->size - 1; 758 } 759 blob->data = talloc_zero_array(mem_ctx, uint8_t, blob->length); 760 if (blob->data == NULL) { 761 talloc_free(blob); 762 return NULL; 763 } 764 765 for (i = 0; i < blob->length; i++) { 766 blob->data[i] = datum->data[datum->size - i - 1]; 767 } 768 769 return blob; 770 } 771 772 static WERROR create_privkey_rsa(gnutls_privkey_t *pk) 773 { 757 774 int bits = 2048; 758 759 *_rsa = NULL; 760 761 pub_expo = BN_new(); 762 if(pub_expo == NULL) { 775 gnutls_x509_privkey_t x509_privkey = NULL; 776 gnutls_privkey_t privkey = NULL; 777 int rc; 778 779 rc = gnutls_x509_privkey_init(&x509_privkey); 780 if (rc != GNUTLS_E_SUCCESS) { 781 DBG_ERR("gnutls_x509_privkey_init failed - %s\n", 782 gnutls_strerror(rc)); 763 783 return WERR_INTERNAL_ERROR; 764 784 } 765 785 766 /* set the public expo to 65537 like everyone */ 767 BN_set_word(pub_expo, 0x10001); 768 769 rsa = RSA_new(); 770 if(rsa == NULL) { 771 BN_free(pub_expo); 786 rc = gnutls_x509_privkey_generate(x509_privkey, 787 GNUTLS_PK_RSA, 788 bits, 789 0); 790 if (rc != GNUTLS_E_SUCCESS) { 791 DBG_ERR("gnutls_x509_privkey_generate failed - %s\n", 792 gnutls_strerror(rc)); 793 gnutls_x509_privkey_deinit(x509_privkey); 772 794 return WERR_INTERNAL_ERROR; 773 795 } 774 796 775 ret = RSA_generate_key_ex(rsa, bits, pub_expo, NULL); 776 if(ret != 1) { 777 RSA_free(rsa); 778 BN_free(pub_expo); 797 rc = gnutls_privkey_init(&privkey); 798 if (rc != GNUTLS_E_SUCCESS) { 799 DBG_ERR("gnutls_privkey_init failed - %s\n", 800 gnutls_strerror(rc)); 801 gnutls_x509_privkey_deinit(x509_privkey); 779 802 return WERR_INTERNAL_ERROR; 780 803 } 781 BN_free(pub_expo); 782 783 len = i2d_RSAPrivateKey(rsa, NULL); 784 if (len < 1) { 785 RSA_free(rsa); 804 805 rc = gnutls_privkey_import_x509(privkey, 806 x509_privkey, 807 GNUTLS_PRIVKEY_IMPORT_AUTO_RELEASE); 808 if (rc != GNUTLS_E_SUCCESS) { 809 DBG_ERR("gnutls_privkey_import_x509 failed - %s\n", 810 gnutls_strerror(rc)); 811 gnutls_x509_privkey_deinit(x509_privkey); 786 812 return WERR_INTERNAL_ERROR; 787 813 } 788 814 789 p0 = p = talloc_array(ctx, uint8_t, len); 790 if (p == NULL) { 791 RSA_free(rsa); 792 return WERR_INTERNAL_ERROR; 793 } 794 795 len = i2d_RSAPrivateKey(rsa, &p); 796 if (len < 1) { 797 RSA_free(rsa); 798 talloc_free(p0); 799 return WERR_INTERNAL_ERROR; 800 } 801 802 /* 803 * To dump the key we can use : 804 * rk_dumpdata("h5lkey", p0, len); 805 */ 806 ret = hx509_parse_private_key(*hctx, &_hx509_signature_rsa_with_var_num , 807 p0, len, HX509_KEY_FORMAT_DER, pk); 808 memset(p0, 0, len); 809 talloc_free(p0); 810 if (ret !=0) { 811 RSA_free(rsa); 812 return WERR_INTERNAL_ERROR; 813 } 814 815 *_rsa = rsa; 815 *pk = privkey; 816 816 817 return WERR_OK; 817 818 } 818 819 819 static WERROR self_sign_cert(TALLOC_CTX *ctx, hx509_context *hctx, hx509_request *req, 820 time_t lifetime, hx509_private_key *private_key, 821 hx509_cert *cert, DATA_BLOB *guidblob) 820 static WERROR self_sign_cert(TALLOC_CTX *mem_ctx, 821 time_t lifetime, 822 const char *dn, 823 gnutls_privkey_t issuer_privkey, 824 gnutls_x509_crt_t *certificate, 825 DATA_BLOB *guidblob) 822 826 { 823 SubjectPublicKeyInfo spki; 824 hx509_name subject = NULL; 825 hx509_ca_tbs tbs; 826 struct heim_bit_string uniqueid; 827 int ret; 828 829 uniqueid.data = talloc_memdup(ctx, guidblob->data, guidblob->length); 830 /* uniqueid is a bit string in which each byte represent 1 bit (1 or 0) 831 * so as 1 byte is 8 bits we need to provision 8 times more space as in the 832 * blob 833 */ 834 uniqueid.length = 8 * guidblob->length; 835 836 memset(&spki, 0, sizeof(spki)); 837 838 ret = hx509_request_get_name(*hctx, *req, &subject); 839 if (ret !=0) { 840 talloc_free(uniqueid.data); 841 return WERR_INTERNAL_ERROR; 842 } 843 ret = hx509_request_get_SubjectPublicKeyInfo(*hctx, *req, &spki); 844 if (ret !=0) { 845 talloc_free(uniqueid.data); 846 hx509_name_free(&subject); 847 return WERR_INTERNAL_ERROR; 848 } 849 850 ret = hx509_ca_tbs_init(*hctx, &tbs); 851 if (ret !=0) { 852 talloc_free(uniqueid.data); 853 hx509_name_free(&subject); 854 free_SubjectPublicKeyInfo(&spki); 855 return WERR_INTERNAL_ERROR; 856 } 857 858 ret = hx509_ca_tbs_set_spki(*hctx, tbs, &spki); 859 if (ret !=0) { 860 talloc_free(uniqueid.data); 861 hx509_name_free(&subject); 862 free_SubjectPublicKeyInfo(&spki); 863 return WERR_INTERNAL_ERROR; 864 } 865 ret = hx509_ca_tbs_set_subject(*hctx, tbs, subject); 866 if (ret !=0) { 867 talloc_free(uniqueid.data); 868 hx509_name_free(&subject); 869 free_SubjectPublicKeyInfo(&spki); 870 hx509_ca_tbs_free(&tbs); 871 return WERR_INTERNAL_ERROR; 872 } 873 ret = hx509_ca_tbs_set_ca(*hctx, tbs, 1); 874 if (ret !=0) { 875 talloc_free(uniqueid.data); 876 hx509_name_free(&subject); 877 free_SubjectPublicKeyInfo(&spki); 878 hx509_ca_tbs_free(&tbs); 879 return WERR_INTERNAL_ERROR; 880 } 881 ret = hx509_ca_tbs_set_notAfter_lifetime(*hctx, tbs, lifetime); 882 if (ret !=0) { 883 talloc_free(uniqueid.data); 884 hx509_name_free(&subject); 885 free_SubjectPublicKeyInfo(&spki); 886 hx509_ca_tbs_free(&tbs); 887 return WERR_INTERNAL_ERROR; 888 } 889 ret = hx509_ca_tbs_set_unique(*hctx, tbs, &uniqueid, &uniqueid); 890 if (ret !=0) { 891 talloc_free(uniqueid.data); 892 hx509_name_free(&subject); 893 free_SubjectPublicKeyInfo(&spki); 894 hx509_ca_tbs_free(&tbs); 895 return WERR_INTERNAL_ERROR; 896 } 897 ret = hx509_ca_sign_self(*hctx, tbs, *private_key, cert); 898 if (ret !=0) { 899 talloc_free(uniqueid.data); 900 hx509_name_free(&subject); 901 free_SubjectPublicKeyInfo(&spki); 902 hx509_ca_tbs_free(&tbs); 903 return WERR_INTERNAL_ERROR; 904 } 905 hx509_name_free(&subject); 906 free_SubjectPublicKeyInfo(&spki); 907 hx509_ca_tbs_free(&tbs); 827 gnutls_datum_t unique_id; 828 gnutls_datum_t serial_number; 829 gnutls_x509_crt_t issuer_cert; 830 gnutls_x509_privkey_t x509_issuer_privkey; 831 time_t activation = time(NULL); 832 time_t expiry = activation + lifetime; 833 const char *error_string; 834 uint8_t *reversed; 835 size_t i; 836 int rc; 837 838 unique_id.size = guidblob->length; 839 unique_id.data = talloc_memdup(mem_ctx, 840 guidblob->data, 841 guidblob->length); 842 if (unique_id.data == NULL) { 843 return WERR_NOMEM; 844 } 845 846 reversed = talloc_array(mem_ctx, uint8_t, guidblob->length); 847 if (reversed == NULL) { 848 talloc_free(unique_id.data); 849 return WERR_NOMEM; 850 } 851 852 /* Native AD generates certificates with serialnumber in reversed notation */ 853 for (i = 0; i < guidblob->length; i++) { 854 uint8_t *uncrypt = guidblob->data; 855 reversed[i] = uncrypt[guidblob->length - i - 1]; 856 } 857 serial_number.size = guidblob->length; 858 serial_number.data = reversed; 859 860 /* Create certificate to sign */ 861 rc = gnutls_x509_crt_init(&issuer_cert); 862 if (rc != GNUTLS_E_SUCCESS) { 863 DBG_ERR("gnutls_x509_crt_init failed - %s\n", 864 gnutls_strerror(rc)); 865 return WERR_NOMEM; 866 } 867 868 rc = gnutls_x509_crt_set_dn(issuer_cert, dn, &error_string); 869 if (rc != GNUTLS_E_SUCCESS) { 870 DBG_ERR("gnutls_x509_crt_set_dn failed - %s (%s)\n", 871 gnutls_strerror(rc), 872 error_string); 873 gnutls_x509_crt_deinit(issuer_cert); 874 return WERR_INVALID_PARAM; 875 } 876 877 rc = gnutls_x509_crt_set_issuer_dn(issuer_cert, dn, &error_string); 878 if (rc != GNUTLS_E_SUCCESS) { 879 DBG_ERR("gnutls_x509_crt_set_issuer_dn failed - %s (%s)\n", 880 gnutls_strerror(rc), 881 error_string); 882 gnutls_x509_crt_deinit(issuer_cert); 883 return WERR_INVALID_PARAM; 884 } 885 886 /* Get x509 privkey for subjectPublicKeyInfo */ 887 rc = gnutls_x509_privkey_init(&x509_issuer_privkey); 888 if (rc != GNUTLS_E_SUCCESS) { 889 DBG_ERR("gnutls_x509_privkey_init failed - %s\n", 890 gnutls_strerror(rc)); 891 gnutls_x509_crt_deinit(issuer_cert); 892 return WERR_INVALID_PARAM; 893 } 894 895 rc = gnutls_privkey_export_x509(issuer_privkey, 896 &x509_issuer_privkey); 897 if (rc != GNUTLS_E_SUCCESS) { 898 DBG_ERR("gnutls_x509_privkey_init failed - %s\n", 899 gnutls_strerror(rc)); 900 gnutls_x509_privkey_deinit(x509_issuer_privkey); 901 gnutls_x509_crt_deinit(issuer_cert); 902 return WERR_INVALID_PARAM; 903 } 904 905 /* Set subjectPublicKeyInfo */ 906 rc = gnutls_x509_crt_set_key(issuer_cert, x509_issuer_privkey); 907 gnutls_x509_privkey_deinit(x509_issuer_privkey); 908 if (rc != GNUTLS_E_SUCCESS) { 909 DBG_ERR("gnutls_x509_crt_set_pubkey failed - %s\n", 910 gnutls_strerror(rc)); 911 gnutls_x509_crt_deinit(issuer_cert); 912 return WERR_INVALID_PARAM; 913 } 914 915 rc = gnutls_x509_crt_set_activation_time(issuer_cert, activation); 916 if (rc != GNUTLS_E_SUCCESS) { 917 DBG_ERR("gnutls_x509_crt_set_activation_time failed - %s\n", 918 gnutls_strerror(rc)); 919 gnutls_x509_crt_deinit(issuer_cert); 920 return WERR_INVALID_PARAM; 921 } 922 923 rc = gnutls_x509_crt_set_expiration_time(issuer_cert, expiry); 924 if (rc != GNUTLS_E_SUCCESS) { 925 DBG_ERR("gnutls_x509_crt_set_expiration_time failed - %s\n", 926 gnutls_strerror(rc)); 927 gnutls_x509_crt_deinit(issuer_cert); 928 return WERR_INVALID_PARAM; 929 } 930 931 rc = gnutls_x509_crt_set_version(issuer_cert, 3); 932 if (rc != GNUTLS_E_SUCCESS) { 933 DBG_ERR("gnutls_x509_crt_set_version failed - %s\n", 934 gnutls_strerror(rc)); 935 gnutls_x509_crt_deinit(issuer_cert); 936 return WERR_INVALID_PARAM; 937 } 938 939 rc = gnutls_x509_crt_set_subject_unique_id(issuer_cert, 940 unique_id.data, 941 unique_id.size); 942 if (rc != GNUTLS_E_SUCCESS) { 943 DBG_ERR("gnutls_x509_crt_set_subject_key_id failed - %s\n", 944 gnutls_strerror(rc)); 945 gnutls_x509_crt_deinit(issuer_cert); 946 return WERR_INVALID_PARAM; 947 } 948 949 rc = gnutls_x509_crt_set_issuer_unique_id(issuer_cert, 950 unique_id.data, 951 unique_id.size); 952 if (rc != GNUTLS_E_SUCCESS) { 953 DBG_ERR("gnutls_x509_crt_set_issuer_unique_id failed - %s\n", 954 gnutls_strerror(rc)); 955 gnutls_x509_crt_deinit(issuer_cert); 956 return WERR_INVALID_PARAM; 957 } 958 959 rc = gnutls_x509_crt_set_serial(issuer_cert, 960 serial_number.data, 961 serial_number.size); 962 if (rc != GNUTLS_E_SUCCESS) { 963 DBG_ERR("gnutls_x509_crt_set_serial failed - %s\n", 964 gnutls_strerror(rc)); 965 gnutls_x509_crt_deinit(issuer_cert); 966 return WERR_INVALID_PARAM; 967 } 968 969 rc = gnutls_x509_crt_privkey_sign(issuer_cert, 970 issuer_cert, 971 issuer_privkey, 972 GNUTLS_DIG_SHA1, 973 0); 974 if (rc != GNUTLS_E_SUCCESS) { 975 DBG_ERR("gnutls_x509_crt_privkey_sign failed - %s\n", 976 gnutls_strerror(rc)); 977 return WERR_INVALID_PARAM; 978 } 979 980 *certificate = issuer_cert; 908 981 909 982 return WERR_OK; 910 983 } 911 984 912 static WERROR create_req(TALLOC_CTX *ctx, hx509_context *hctx, hx509_request *req, 913 hx509_private_key *signer,RSA **rsa, const char *dn) 985 /* Return an error when we fail to generate a certificate */ 986 static WERROR generate_bkrp_cert(TALLOC_CTX *mem_ctx, 987 struct dcesrv_call_state *dce_call, 988 struct ldb_context *ldb_ctx, 989 const char *dn) 914 990 { 915 int ret; 916 SubjectPublicKeyInfo key; 917 918 hx509_name name; 919 WERROR w_err; 920 921 w_err = create_heimdal_rsa_key(ctx, hctx, signer, rsa); 922 if (!W_ERROR_IS_OK(w_err)) { 923 return w_err; 924 } 925 926 hx509_request_init(*hctx, req); 927 ret = hx509_parse_name(*hctx, dn, &name); 928 if (ret != 0) { 929 RSA_free(*rsa); 930 hx509_private_key_free(signer); 931 hx509_request_free(req); 932 hx509_name_free(&name); 933 return WERR_INTERNAL_ERROR; 934 } 935 936 ret = hx509_request_set_name(*hctx, *req, name); 937 if (ret != 0) { 938 RSA_free(*rsa); 939 hx509_private_key_free(signer); 940 hx509_request_free(req); 941 hx509_name_free(&name); 942 return WERR_INTERNAL_ERROR; 943 } 944 hx509_name_free(&name); 945 946 ret = hx509_private_key2SPKI(*hctx, *signer, &key); 947 if (ret != 0) { 948 RSA_free(*rsa); 949 hx509_private_key_free(signer); 950 hx509_request_free(req); 951 return WERR_INTERNAL_ERROR; 952 } 953 ret = hx509_request_set_SubjectPublicKeyInfo(*hctx, *req, &key); 954 if (ret != 0) { 955 RSA_free(*rsa); 956 hx509_private_key_free(signer); 957 free_SubjectPublicKeyInfo(&key); 958 hx509_request_free(req); 959 return WERR_INTERNAL_ERROR; 960 } 961 962 free_SubjectPublicKeyInfo(&key); 963 964 return WERR_OK; 965 } 966 967 /* Return an error when we fail to generate a certificate */ 968 static WERROR generate_bkrp_cert(TALLOC_CTX *ctx, struct dcesrv_call_state *dce_call, struct ldb_context *ldb_ctx, const char *dn) 969 { 970 971 struct heim_octet_string data; 972 WERROR w_err; 973 RSA *rsa; 974 hx509_context hctx; 975 hx509_private_key pk; 976 hx509_request req; 977 hx509_cert cert; 991 WERROR werr; 992 gnutls_privkey_t issuer_privkey = NULL; 993 gnutls_x509_crt_t cert = NULL; 994 gnutls_datum_t cert_blob; 995 gnutls_datum_t m, e, d, p, q, u, e1, e2; 978 996 DATA_BLOB blob; 979 997 DATA_BLOB blobkeypair; 980 998 DATA_BLOB *tmp; 981 int ret;982 999 bool ok = true; 983 1000 struct GUID guid = GUID_random(); … … 986 1003 struct bkrp_exported_RSA_key_pair keypair; 987 1004 enum ndr_err_code ndr_err; 988 uint32_t nb_days_validity = 365; 1005 time_t nb_seconds_validity = 3600 * 24 * 365; 1006 int rc; 989 1007 990 1008 DEBUG(6, ("Trying to generate a certificate\n")); 991 hx509_context_init(&hctx); 992 w_err = create_req(ctx, &hctx, &req, &pk, &rsa, dn); 993 if (!W_ERROR_IS_OK(w_err)) { 994 hx509_context_free(&hctx); 995 return w_err; 996 } 997 998 status = GUID_to_ndr_blob(&guid, ctx, &blob); 1009 werr = create_privkey_rsa(&issuer_privkey); 1010 if (!W_ERROR_IS_OK(werr)) { 1011 return werr; 1012 } 1013 1014 status = GUID_to_ndr_blob(&guid, mem_ctx, &blob); 999 1015 if (!NT_STATUS_IS_OK(status)) { 1000 hx509_context_free(&hctx); 1001 hx509_private_key_free(&pk); 1002 RSA_free(rsa); 1016 gnutls_privkey_deinit(issuer_privkey); 1003 1017 return WERR_INVALID_DATA; 1004 1018 } 1005 1019 1006 w_err = self_sign_cert(ctx, &hctx, &req, nb_days_validity, &pk, &cert, &blob); 1007 if (!W_ERROR_IS_OK(w_err)) { 1008 hx509_private_key_free(&pk); 1009 hx509_context_free(&hctx); 1020 werr = self_sign_cert(mem_ctx, 1021 nb_seconds_validity, 1022 dn, 1023 issuer_privkey, 1024 &cert, 1025 &blob); 1026 if (!W_ERROR_IS_OK(werr)) { 1027 gnutls_privkey_deinit(issuer_privkey); 1010 1028 return WERR_INVALID_DATA; 1011 1029 } 1012 1030 1013 ret = hx509_cert_binary(hctx, cert, &data); 1014 if (ret !=0) { 1015 hx509_cert_free(cert); 1016 hx509_private_key_free(&pk); 1017 hx509_context_free(&hctx); 1031 rc = gnutls_x509_crt_export2(cert, GNUTLS_X509_FMT_DER, &cert_blob); 1032 if (rc != GNUTLS_E_SUCCESS) { 1033 DBG_ERR("gnutls_x509_crt_export2 failed - %s\n", 1034 gnutls_strerror(rc)); 1035 gnutls_privkey_deinit(issuer_privkey); 1036 gnutls_x509_crt_deinit(cert); 1018 1037 return WERR_INVALID_DATA; 1019 1038 } 1020 1039 1021 keypair.cert.data = talloc_memdup(ctx, data.data, data.length); 1022 keypair.cert.length = data.length; 1040 keypair.cert.length = cert_blob.size; 1041 keypair.cert.data = talloc_memdup(mem_ctx, cert_blob.data, cert_blob.size); 1042 gnutls_x509_crt_deinit(cert); 1043 gnutls_free(cert_blob.data); 1044 if (keypair.cert.data == NULL) { 1045 gnutls_privkey_deinit(issuer_privkey); 1046 return WERR_NOMEM; 1047 } 1048 1049 rc = gnutls_privkey_export_rsa_raw(issuer_privkey, 1050 &m, 1051 &e, 1052 &d, 1053 &p, 1054 &q, 1055 &u, 1056 &e1, 1057 &e2); 1058 if (rc != GNUTLS_E_SUCCESS) { 1059 gnutls_privkey_deinit(issuer_privkey); 1060 return WERR_INVALID_DATA; 1061 } 1023 1062 1024 1063 /* … … 1027 1066 * so we reverse the buffer to make it work 1028 1067 */ 1029 tmp = reverse_and_get_blob( ctx, rsa->e);1068 tmp = reverse_and_get_blob(mem_ctx, &e); 1030 1069 if (tmp == NULL) { 1031 1070 ok = false; 1032 1071 } else { 1072 SMB_ASSERT(tmp->length <= 4); 1033 1073 keypair.public_exponent = *tmp; 1034 SMB_ASSERT(tmp->length <= 4); 1035 /* 1036 * The value is now in little endian but if can happen that the length is 1037 * less than 4 bytes. 1038 * So if we have less than 4 bytes we pad with zeros so that it correctly 1039 * fit into the structure. 1040 */ 1041 if (tmp->length < 4) { 1042 /* 1043 * We need the expo to fit 4 bytes 1044 */ 1045 keypair.public_exponent.data = talloc_zero_array(ctx, uint8_t, 4); 1046 memcpy(keypair.public_exponent.data, tmp->data, tmp->length); 1047 keypair.public_exponent.length = 4; 1048 } 1049 } 1050 1051 tmp = reverse_and_get_blob(ctx,rsa->d); 1074 } 1075 1076 tmp = reverse_and_get_blob(mem_ctx, &d); 1052 1077 if (tmp == NULL) { 1053 1078 ok = false; … … 1056 1081 } 1057 1082 1058 tmp = reverse_and_get_blob( ctx,rsa->n);1083 tmp = reverse_and_get_blob(mem_ctx, &m); 1059 1084 if (tmp == NULL) { 1060 1085 ok = false; … … 1063 1088 } 1064 1089 1065 tmp = reverse_and_get_blob( ctx,rsa->p);1090 tmp = reverse_and_get_blob(mem_ctx, &p); 1066 1091 if (tmp == NULL) { 1067 1092 ok = false; … … 1070 1095 } 1071 1096 1072 tmp = reverse_and_get_blob( ctx,rsa->q);1097 tmp = reverse_and_get_blob(mem_ctx, &q); 1073 1098 if (tmp == NULL) { 1074 1099 ok = false; … … 1077 1102 } 1078 1103 1079 tmp = reverse_and_get_blob( ctx,rsa->dmp1);1104 tmp = reverse_and_get_blob(mem_ctx, &e1); 1080 1105 if (tmp == NULL) { 1081 1106 ok = false; … … 1084 1109 } 1085 1110 1086 tmp = reverse_and_get_blob( ctx,rsa->dmq1);1111 tmp = reverse_and_get_blob(mem_ctx, &e2); 1087 1112 if (tmp == NULL) { 1088 1113 ok = false; … … 1091 1116 } 1092 1117 1093 tmp = reverse_and_get_blob( ctx,rsa->iqmp);1118 tmp = reverse_and_get_blob(mem_ctx, &u); 1094 1119 if (tmp == NULL) { 1095 1120 ok = false; … … 1100 1125 /* One of the keypair allocation was wrong */ 1101 1126 if (ok == false) { 1102 der_free_octet_string(&data); 1103 hx509_cert_free(cert); 1104 hx509_private_key_free(&pk); 1105 hx509_context_free(&hctx); 1106 RSA_free(rsa); 1127 gnutls_privkey_deinit(issuer_privkey); 1107 1128 return WERR_INVALID_DATA; 1108 1129 } 1130 1109 1131 keypair.certificate_len = keypair.cert.length; 1110 ndr_err = ndr_push_struct_blob(&blobkeypair, ctx, &keypair, (ndr_push_flags_fn_t)ndr_push_bkrp_exported_RSA_key_pair); 1132 ndr_err = ndr_push_struct_blob(&blobkeypair, 1133 mem_ctx, 1134 &keypair, 1135 (ndr_push_flags_fn_t)ndr_push_bkrp_exported_RSA_key_pair); 1136 gnutls_privkey_deinit(issuer_privkey); 1111 1137 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { 1112 der_free_octet_string(&data);1113 hx509_cert_free(cert);1114 hx509_private_key_free(&pk);1115 hx509_context_free(&hctx);1116 RSA_free(rsa);1117 1138 return WERR_INVALID_DATA; 1118 1139 } 1119 1140 1120 secret_name = talloc_asprintf( ctx, "BCKUPKEY_%s", GUID_string(ctx, &guid));1141 secret_name = talloc_asprintf(mem_ctx, "BCKUPKEY_%s", GUID_string(mem_ctx, &guid)); 1121 1142 if (secret_name == NULL) { 1122 der_free_octet_string(&data);1123 hx509_cert_free(cert);1124 hx509_private_key_free(&pk);1125 hx509_context_free(&hctx);1126 RSA_free(rsa);1127 1143 return WERR_OUTOFMEMORY; 1128 1144 } 1129 1145 1130 status = set_lsa_secret( ctx, ldb_ctx, secret_name, &blobkeypair);1146 status = set_lsa_secret(mem_ctx, ldb_ctx, secret_name, &blobkeypair); 1131 1147 if (!NT_STATUS_IS_OK(status)) { 1132 1148 DEBUG(2, ("Failed to save the secret %s\n", secret_name)); … … 1134 1150 talloc_free(secret_name); 1135 1151 1136 GUID_to_ndr_blob(&guid, ctx, &blob);1137 status = set_lsa_secret( ctx, ldb_ctx, "BCKUPKEY_PREFERRED", &blob);1152 GUID_to_ndr_blob(&guid, mem_ctx, &blob); 1153 status = set_lsa_secret(mem_ctx, ldb_ctx, "BCKUPKEY_PREFERRED", &blob); 1138 1154 if (!NT_STATUS_IS_OK(status)) { 1139 1155 DEBUG(2, ("Failed to save the secret BCKUPKEY_PREFERRED\n")); 1140 1156 } 1141 1157 1142 der_free_octet_string(&data);1143 hx509_cert_free(cert);1144 hx509_private_key_free(&pk);1145 hx509_context_free(&hctx);1146 RSA_free(rsa);1147 1158 return WERR_OK; 1148 1159 } 1149 1160 1150 static WERROR bkrp_ do_retreive_client_wrap_key(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,1151 struct bkrp_BackupKey *r ,struct ldb_context *ldb_ctx)1161 static WERROR bkrp_retrieve_client_wrap_key(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, 1162 struct bkrp_BackupKey *r, struct ldb_context *ldb_ctx) 1152 1163 { 1153 1164 struct GUID guid; 1154 1165 char *guid_string; 1155 DATA_BLOB secret;1166 DATA_BLOB lsa_secret; 1156 1167 enum ndr_err_code ndr_err; 1157 1168 NTSTATUS status; … … 1165 1176 ldb_ctx, 1166 1177 "BCKUPKEY_PREFERRED", 1167 &secret); 1168 if (!NT_STATUS_IS_OK(status)) { 1169 DEBUG(10, ("Error while fetching secret BCKUPKEY_PREFERRED\n")); 1170 if (!NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) { 1171 /* Ok we can be in this case if there was no certs */ 1172 struct loadparm_context *lp_ctx = dce_call->conn->dce_ctx->lp_ctx; 1173 char *dn = talloc_asprintf(mem_ctx, "CN=%s.%s", 1174 lpcfg_netbios_name(lp_ctx), 1175 lpcfg_realm(lp_ctx)); 1176 1177 WERROR werr = generate_bkrp_cert(mem_ctx, dce_call, ldb_ctx, dn); 1178 if (!W_ERROR_IS_OK(werr)) { 1179 return WERR_INVALID_PARAMETER; 1180 } 1181 status = get_lsa_secret(mem_ctx, 1178 &lsa_secret); 1179 if (NT_STATUS_EQUAL(status, NT_STATUS_RESOURCE_NAME_NOT_FOUND)) { 1180 /* Ok we can be in this case if there was no certs */ 1181 struct loadparm_context *lp_ctx = dce_call->conn->dce_ctx->lp_ctx; 1182 char *dn = talloc_asprintf(mem_ctx, "CN=%s", 1183 lpcfg_realm(lp_ctx)); 1184 1185 WERROR werr = generate_bkrp_cert(mem_ctx, dce_call, ldb_ctx, dn); 1186 if (!W_ERROR_IS_OK(werr)) { 1187 return WERR_INVALID_PARAMETER; 1188 } 1189 status = get_lsa_secret(mem_ctx, 1182 1190 ldb_ctx, 1183 1191 "BCKUPKEY_PREFERRED", 1184 &secret); 1185 1186 if (!NT_STATUS_IS_OK(status)) { 1187 /* Ok we really don't manage to get this certs ...*/ 1188 DEBUG(2, ("Unable to locate BCKUPKEY_PREFERRED after cert generation\n")); 1189 return WERR_FILE_NOT_FOUND; 1190 } 1191 } else { 1192 /* In theory we should NEVER reach this point as it 1193 should only appear in a rodc server */ 1194 /* we do not have the real secret attribute */ 1195 return WERR_INVALID_PARAMETER; 1196 } 1197 } 1198 1199 if (secret.length != 0) { 1192 &lsa_secret); 1193 1194 if (!NT_STATUS_IS_OK(status)) { 1195 /* Ok we really don't manage to get this certs ...*/ 1196 DEBUG(2, ("Unable to locate BCKUPKEY_PREFERRED after cert generation\n")); 1197 return WERR_FILE_NOT_FOUND; 1198 } 1199 } else if (!NT_STATUS_IS_OK(status)) { 1200 return WERR_INTERNAL_ERROR; 1201 } 1202 1203 if (lsa_secret.length == 0) { 1204 DEBUG(1, ("No secret in BCKUPKEY_PREFERRED, are we an undetected RODC?\n")); 1205 return WERR_INTERNAL_ERROR; 1206 } else { 1200 1207 char *cert_secret_name; 1201 1208 1202 status = GUID_from_ndr_blob(& secret, &guid);1209 status = GUID_from_ndr_blob(&lsa_secret, &guid); 1203 1210 if (!NT_STATUS_IS_OK(status)) { 1204 1211 return WERR_FILE_NOT_FOUND; … … 1212 1219 return WERR_FILE_NOT_FOUND; 1213 1220 } 1214 1221 1215 1222 cert_secret_name = talloc_asprintf(mem_ctx, 1216 1223 "BCKUPKEY_%s", … … 1219 1226 ldb_ctx, 1220 1227 cert_secret_name, 1221 & secret);1228 &lsa_secret); 1222 1229 if (!NT_STATUS_IS_OK(status)) { 1223 1230 return WERR_FILE_NOT_FOUND; 1224 1231 } 1225 1232 1226 if ( secret.length != 0) {1233 if (lsa_secret.length != 0) { 1227 1234 struct bkrp_exported_RSA_key_pair keypair; 1228 ndr_err = ndr_pull_struct_blob(& secret, mem_ctx, &keypair,1235 ndr_err = ndr_pull_struct_blob(&lsa_secret, mem_ctx, &keypair, 1229 1236 (ndr_pull_flags_fn_t)ndr_pull_bkrp_exported_RSA_key_pair); 1230 1237 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { … … 1236 1243 return WERR_OK; 1237 1244 } else { 1238 DEBUG(10, ("No or broken secret called %s\n", cert_secret_name)); 1239 return WERR_FILE_NOT_FOUND; 1240 } 1241 } else { 1242 DEBUG(10, ("No secret BCKUPKEY_PREFERRED\n")); 1245 DEBUG(1, ("No or broken secret called %s\n", cert_secret_name)); 1246 return WERR_INTERNAL_ERROR; 1247 } 1248 } 1249 1250 return WERR_NOT_SUPPORTED; 1251 } 1252 1253 static WERROR generate_bkrp_server_wrap_key(TALLOC_CTX *ctx, struct ldb_context *ldb_ctx) 1254 { 1255 struct GUID guid = GUID_random(); 1256 enum ndr_err_code ndr_err; 1257 DATA_BLOB blob_wrap_key, guid_blob; 1258 struct bkrp_dc_serverwrap_key wrap_key; 1259 NTSTATUS status; 1260 char *secret_name; 1261 TALLOC_CTX *frame = talloc_stackframe(); 1262 1263 generate_random_buffer(wrap_key.key, sizeof(wrap_key.key)); 1264 1265 ndr_err = ndr_push_struct_blob(&blob_wrap_key, ctx, &wrap_key, (ndr_push_flags_fn_t)ndr_push_bkrp_dc_serverwrap_key); 1266 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { 1267 TALLOC_FREE(frame); 1268 return WERR_INVALID_DATA; 1269 } 1270 1271 secret_name = talloc_asprintf(frame, "BCKUPKEY_%s", GUID_string(ctx, &guid)); 1272 if (secret_name == NULL) { 1273 TALLOC_FREE(frame); 1274 return WERR_NOMEM; 1275 } 1276 1277 status = set_lsa_secret(frame, ldb_ctx, secret_name, &blob_wrap_key); 1278 if (!NT_STATUS_IS_OK(status)) { 1279 DEBUG(2, ("Failed to save the secret %s\n", secret_name)); 1280 TALLOC_FREE(frame); 1281 return WERR_INTERNAL_ERROR; 1282 } 1283 1284 status = GUID_to_ndr_blob(&guid, frame, &guid_blob); 1285 if (!NT_STATUS_IS_OK(status)) { 1286 DEBUG(2, ("Failed to save the secret %s\n", secret_name)); 1287 TALLOC_FREE(frame); 1288 } 1289 1290 status = set_lsa_secret(frame, ldb_ctx, "BCKUPKEY_P", &guid_blob); 1291 if (!NT_STATUS_IS_OK(status)) { 1292 DEBUG(2, ("Failed to save the secret %s\n", secret_name)); 1293 TALLOC_FREE(frame); 1294 return WERR_INTERNAL_ERROR; 1295 } 1296 1297 TALLOC_FREE(frame); 1298 1299 return WERR_OK; 1300 } 1301 1302 /* 1303 * Find the specified decryption keys from the LSA secrets store as 1304 * G$BCKUPKEY_keyGuidString. 1305 */ 1306 1307 static WERROR bkrp_do_retrieve_server_wrap_key(TALLOC_CTX *mem_ctx, struct ldb_context *ldb_ctx, 1308 struct bkrp_dc_serverwrap_key *server_key, 1309 struct GUID *guid) 1310 { 1311 NTSTATUS status; 1312 DATA_BLOB lsa_secret; 1313 char *secret_name; 1314 char *guid_string; 1315 enum ndr_err_code ndr_err; 1316 1317 guid_string = GUID_string(mem_ctx, guid); 1318 if (guid_string == NULL) { 1319 /* We return file not found because the client 1320 * expect this error 1321 */ 1243 1322 return WERR_FILE_NOT_FOUND; 1244 1323 } 1245 1324 1246 return WERR_NOT_SUPPORTED; 1325 secret_name = talloc_asprintf(mem_ctx, "BCKUPKEY_%s", guid_string); 1326 if (secret_name == NULL) { 1327 return WERR_NOMEM; 1328 } 1329 1330 status = get_lsa_secret(mem_ctx, ldb_ctx, secret_name, &lsa_secret); 1331 if (!NT_STATUS_IS_OK(status)) { 1332 DEBUG(10, ("Error while fetching secret %s\n", secret_name)); 1333 return WERR_INVALID_DATA; 1334 } 1335 if (lsa_secret.length == 0) { 1336 /* RODC case, we do not have secrets locally */ 1337 DEBUG(1, ("Unable to fetch value for secret %s, are we an undetected RODC?\n", 1338 secret_name)); 1339 return WERR_INTERNAL_ERROR; 1340 } 1341 ndr_err = ndr_pull_struct_blob(&lsa_secret, mem_ctx, server_key, 1342 (ndr_pull_flags_fn_t)ndr_pull_bkrp_dc_serverwrap_key); 1343 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { 1344 DEBUG(2, ("Unable to parse the ndr encoded server wrap key %s\n", secret_name)); 1345 return WERR_INVALID_DATA; 1346 } 1347 1348 return WERR_OK; 1349 } 1350 1351 /* 1352 * Find the current, preferred ServerWrap Key by looking at 1353 * G$BCKUPKEY_P in the LSA secrets store. 1354 * 1355 * Then find the current decryption keys from the LSA secrets store as 1356 * G$BCKUPKEY_keyGuidString. 1357 */ 1358 1359 static WERROR bkrp_do_retrieve_default_server_wrap_key(TALLOC_CTX *mem_ctx, 1360 struct ldb_context *ldb_ctx, 1361 struct bkrp_dc_serverwrap_key *server_key, 1362 struct GUID *returned_guid) 1363 { 1364 NTSTATUS status; 1365 DATA_BLOB guid_binary; 1366 1367 status = get_lsa_secret(mem_ctx, ldb_ctx, "BCKUPKEY_P", &guid_binary); 1368 if (!NT_STATUS_IS_OK(status)) { 1369 DEBUG(10, ("Error while fetching secret BCKUPKEY_P to find current GUID\n")); 1370 return WERR_FILE_NOT_FOUND; 1371 } else if (guid_binary.length == 0) { 1372 /* RODC case, we do not have secrets locally */ 1373 DEBUG(1, ("Unable to fetch value for secret BCKUPKEY_P, are we an undetected RODC?\n")); 1374 return WERR_INTERNAL_ERROR; 1375 } 1376 1377 status = GUID_from_ndr_blob(&guid_binary, returned_guid); 1378 if (!NT_STATUS_IS_OK(status)) { 1379 return WERR_FILE_NOT_FOUND; 1380 } 1381 1382 return bkrp_do_retrieve_server_wrap_key(mem_ctx, ldb_ctx, 1383 server_key, returned_guid); 1384 } 1385 1386 static WERROR bkrp_server_wrap_decrypt_data(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, 1387 struct bkrp_BackupKey *r ,struct ldb_context *ldb_ctx) 1388 { 1389 WERROR werr; 1390 struct bkrp_server_side_wrapped decrypt_request; 1391 DATA_BLOB sid_blob, encrypted_blob; 1392 DATA_BLOB blob; 1393 enum ndr_err_code ndr_err; 1394 struct bkrp_dc_serverwrap_key server_key; 1395 struct bkrp_rc4encryptedpayload rc4payload; 1396 struct dom_sid *caller_sid; 1397 uint8_t symkey[20]; /* SHA-1 hash len */ 1398 uint8_t mackey[20]; /* SHA-1 hash len */ 1399 uint8_t mac[20]; /* SHA-1 hash len */ 1400 gnutls_hmac_hd_t hmac_hnd; 1401 gnutls_cipher_hd_t cipher_hnd; 1402 gnutls_datum_t cipher_key; 1403 int rc; 1404 1405 blob.data = r->in.data_in; 1406 blob.length = r->in.data_in_len; 1407 1408 if (r->in.data_in_len == 0 || r->in.data_in == NULL) { 1409 return WERR_INVALID_PARAM; 1410 } 1411 1412 ndr_err = ndr_pull_struct_blob_all(&blob, mem_ctx, &decrypt_request, 1413 (ndr_pull_flags_fn_t)ndr_pull_bkrp_server_side_wrapped); 1414 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { 1415 return WERR_INVALID_PARAM; 1416 } 1417 1418 if (decrypt_request.magic != BACKUPKEY_SERVER_WRAP_VERSION) { 1419 return WERR_INVALID_PARAM; 1420 } 1421 1422 werr = bkrp_do_retrieve_server_wrap_key(mem_ctx, ldb_ctx, &server_key, 1423 &decrypt_request.guid); 1424 if (!W_ERROR_IS_OK(werr)) { 1425 return werr; 1426 } 1427 1428 dump_data_pw("server_key: \n", server_key.key, sizeof(server_key.key)); 1429 1430 dump_data_pw("r2: \n", decrypt_request.r2, sizeof(decrypt_request.r2)); 1431 1432 /* 1433 * This is *not* the leading 64 bytes, as indicated in MS-BKRP 3.1.4.1.1 1434 * BACKUPKEY_BACKUP_GUID, it really is the whole key 1435 */ 1436 1437 gnutls_hmac_init(&hmac_hnd, 1438 GNUTLS_MAC_SHA1, 1439 server_key.key, 1440 sizeof(server_key.key)); 1441 gnutls_hmac(hmac_hnd, 1442 decrypt_request.r2, 1443 sizeof(decrypt_request.r2)); 1444 gnutls_hmac_output(hmac_hnd, symkey); 1445 1446 dump_data_pw("symkey: \n", symkey, sizeof(symkey)); 1447 1448 /* rc4 decrypt sid and secret using sym key */ 1449 cipher_key.data = symkey; 1450 cipher_key.size = sizeof(symkey); 1451 1452 encrypted_blob = data_blob_const(decrypt_request.rc4encryptedpayload, 1453 decrypt_request.ciphertext_length); 1454 1455 rc = gnutls_cipher_init(&cipher_hnd, 1456 GNUTLS_CIPHER_ARCFOUR_128, 1457 &cipher_key, 1458 NULL); 1459 if (rc != GNUTLS_E_SUCCESS) { 1460 DBG_ERR("gnutls_cipher_init failed - %s\n", 1461 gnutls_strerror(rc)); 1462 return WERR_INVALID_PARAM; 1463 } 1464 rc = gnutls_cipher_encrypt2(cipher_hnd, 1465 encrypted_blob.data, 1466 encrypted_blob.length, 1467 encrypted_blob.data, 1468 encrypted_blob.length); 1469 gnutls_cipher_deinit(cipher_hnd); 1470 if (rc != GNUTLS_E_SUCCESS) { 1471 DBG_ERR("gnutls_cipher_encrypt2 failed - %s\n", 1472 gnutls_strerror(rc)); 1473 return WERR_INVALID_PARAM; 1474 } 1475 1476 ndr_err = ndr_pull_struct_blob_all(&encrypted_blob, mem_ctx, &rc4payload, 1477 (ndr_pull_flags_fn_t)ndr_pull_bkrp_rc4encryptedpayload); 1478 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { 1479 return WERR_INVALID_PARAM; 1480 } 1481 1482 if (decrypt_request.payload_length != rc4payload.secret_data.length) { 1483 return WERR_INVALID_PARAM; 1484 } 1485 1486 dump_data_pw("r3: \n", rc4payload.r3, sizeof(rc4payload.r3)); 1487 1488 /* 1489 * This is *not* the leading 64 bytes, as indicated in MS-BKRP 3.1.4.1.1 1490 * BACKUPKEY_BACKUP_GUID, it really is the whole key 1491 */ 1492 gnutls_hmac(hmac_hnd, 1493 rc4payload.r3, 1494 sizeof(rc4payload.r3)); 1495 gnutls_hmac_deinit(hmac_hnd, mackey); 1496 1497 dump_data_pw("mackey: \n", mackey, sizeof(mackey)); 1498 1499 ndr_err = ndr_push_struct_blob(&sid_blob, mem_ctx, &rc4payload.sid, 1500 (ndr_push_flags_fn_t)ndr_push_dom_sid); 1501 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { 1502 return WERR_INTERNAL_ERROR; 1503 } 1504 1505 gnutls_hmac_init(&hmac_hnd, 1506 GNUTLS_MAC_SHA1, 1507 mackey, 1508 sizeof(mackey)); 1509 /* SID field */ 1510 gnutls_hmac(hmac_hnd, 1511 sid_blob.data, 1512 sid_blob.length); 1513 /* Secret field */ 1514 gnutls_hmac(hmac_hnd, 1515 rc4payload.secret_data.data, 1516 rc4payload.secret_data.length); 1517 gnutls_hmac_deinit(hmac_hnd, mac); 1518 1519 dump_data_pw("mac: \n", mac, sizeof(mac)); 1520 dump_data_pw("rc4payload.mac: \n", rc4payload.mac, sizeof(rc4payload.mac)); 1521 1522 if (memcmp(mac, rc4payload.mac, sizeof(mac)) != 0) { 1523 return WERR_INVALID_ACCESS; 1524 } 1525 1526 caller_sid = &dce_call->conn->auth_state.session_info->security_token->sids[PRIMARY_USER_SID_INDEX]; 1527 1528 if (!dom_sid_equal(&rc4payload.sid, caller_sid)) { 1529 return WERR_INVALID_ACCESS; 1530 } 1531 1532 *(r->out.data_out) = rc4payload.secret_data.data; 1533 *(r->out.data_out_len) = rc4payload.secret_data.length; 1534 1535 return WERR_OK; 1536 } 1537 1538 /* 1539 * For BACKUPKEY_RESTORE_GUID we need to check the first 4 bytes to 1540 * determine what type of restore is wanted. 1541 * 1542 * See MS-BKRP 3.1.4.1.4 BACKUPKEY_RESTORE_GUID point 1. 1543 */ 1544 1545 static WERROR bkrp_generic_decrypt_data(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, 1546 struct bkrp_BackupKey *r, struct ldb_context *ldb_ctx) 1547 { 1548 if (r->in.data_in_len < 4 || r->in.data_in == NULL) { 1549 return WERR_INVALID_PARAM; 1550 } 1551 1552 if (IVAL(r->in.data_in, 0) == BACKUPKEY_SERVER_WRAP_VERSION) { 1553 return bkrp_server_wrap_decrypt_data(dce_call, mem_ctx, r, ldb_ctx); 1554 } 1555 1556 return bkrp_client_wrap_decrypt_data(dce_call, mem_ctx, r, ldb_ctx); 1557 } 1558 1559 /* 1560 * We have some data, such as saved website or IMAP passwords that the 1561 * client would like to put into the profile on-disk. This needs to 1562 * be encrypted. This version gives the server the data over the 1563 * network (protected only by the negotiated transport encryption), 1564 * and asks that it be encrypted and returned for long-term storage. 1565 * 1566 * The data is NOT stored in the LSA, but a key to encrypt the data 1567 * will be stored. There is only one active encryption key per domain, 1568 * it is pointed at with G$BCKUPKEY_P in the LSA secrets store. 1569 * 1570 * The potentially multiple valid decryptiong keys (and the encryption 1571 * key) are in turn stored in the LSA secrets store as 1572 * G$BCKUPKEY_keyGuidString. 1573 * 1574 */ 1575 1576 static WERROR bkrp_server_wrap_encrypt_data(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, 1577 struct bkrp_BackupKey *r ,struct ldb_context *ldb_ctx) 1578 { 1579 DATA_BLOB sid_blob, encrypted_blob, server_wrapped_blob; 1580 WERROR werr; 1581 struct dom_sid *caller_sid; 1582 uint8_t symkey[20]; /* SHA-1 hash len */ 1583 uint8_t mackey[20]; /* SHA-1 hash len */ 1584 struct bkrp_rc4encryptedpayload rc4payload; 1585 gnutls_hmac_hd_t hmac_hnd; 1586 struct bkrp_dc_serverwrap_key server_key; 1587 enum ndr_err_code ndr_err; 1588 struct bkrp_server_side_wrapped server_side_wrapped; 1589 struct GUID guid; 1590 gnutls_cipher_hd_t cipher_hnd; 1591 gnutls_datum_t cipher_key; 1592 int rc; 1593 1594 if (r->in.data_in_len == 0 || r->in.data_in == NULL) { 1595 return WERR_INVALID_PARAM; 1596 } 1597 1598 werr = bkrp_do_retrieve_default_server_wrap_key(mem_ctx, 1599 ldb_ctx, &server_key, 1600 &guid); 1601 1602 if (!W_ERROR_IS_OK(werr)) { 1603 if (W_ERROR_EQUAL(werr, WERR_FILE_NOT_FOUND)) { 1604 /* Generate the server wrap key since one wasn't found */ 1605 werr = generate_bkrp_server_wrap_key(mem_ctx, 1606 ldb_ctx); 1607 if (!W_ERROR_IS_OK(werr)) { 1608 return WERR_INVALID_PARAMETER; 1609 } 1610 werr = bkrp_do_retrieve_default_server_wrap_key(mem_ctx, 1611 ldb_ctx, 1612 &server_key, 1613 &guid); 1614 1615 if (W_ERROR_EQUAL(werr, WERR_FILE_NOT_FOUND)) { 1616 /* Ok we really don't manage to get this secret ...*/ 1617 return WERR_FILE_NOT_FOUND; 1618 } 1619 } else { 1620 /* In theory we should NEVER reach this point as it 1621 should only appear in a rodc server */ 1622 /* we do not have the real secret attribute */ 1623 return WERR_INVALID_PARAMETER; 1624 } 1625 } 1626 1627 caller_sid = &dce_call->conn->auth_state.session_info->security_token->sids[PRIMARY_USER_SID_INDEX]; 1628 1629 dump_data_pw("server_key: \n", server_key.key, sizeof(server_key.key)); 1630 1631 /* 1632 * This is the key derivation step, so that the HMAC and RC4 1633 * operations over the user-supplied data are not able to 1634 * disclose the master key. By using random data, the symkey 1635 * and mackey values are unique for this operation, and 1636 * discovering these (by reversing the RC4 over the 1637 * attacker-controlled data) does not return something able to 1638 * be used to decyrpt the encrypted data of other users 1639 */ 1640 generate_random_buffer(server_side_wrapped.r2, sizeof(server_side_wrapped.r2)); 1641 1642 dump_data_pw("r2: \n", server_side_wrapped.r2, sizeof(server_side_wrapped.r2)); 1643 1644 generate_random_buffer(rc4payload.r3, sizeof(rc4payload.r3)); 1645 1646 dump_data_pw("r3: \n", rc4payload.r3, sizeof(rc4payload.r3)); 1647 1648 1649 /* 1650 * This is *not* the leading 64 bytes, as indicated in MS-BKRP 3.1.4.1.1 1651 * BACKUPKEY_BACKUP_GUID, it really is the whole key 1652 */ 1653 gnutls_hmac_init(&hmac_hnd, 1654 GNUTLS_MAC_SHA1, 1655 server_key.key, 1656 sizeof(server_key.key)); 1657 gnutls_hmac(hmac_hnd, 1658 server_side_wrapped.r2, 1659 sizeof(server_side_wrapped.r2)); 1660 gnutls_hmac_output(hmac_hnd, symkey); 1661 1662 dump_data_pw("symkey: \n", symkey, sizeof(symkey)); 1663 1664 /* 1665 * This is *not* the leading 64 bytes, as indicated in MS-BKRP 3.1.4.1.1 1666 * BACKUPKEY_BACKUP_GUID, it really is the whole key 1667 */ 1668 gnutls_hmac(hmac_hnd, 1669 rc4payload.r3, 1670 sizeof(rc4payload.r3)); 1671 gnutls_hmac_deinit(hmac_hnd, mackey); 1672 1673 dump_data_pw("mackey: \n", mackey, sizeof(mackey)); 1674 1675 ndr_err = ndr_push_struct_blob(&sid_blob, mem_ctx, caller_sid, 1676 (ndr_push_flags_fn_t)ndr_push_dom_sid); 1677 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { 1678 return WERR_INTERNAL_ERROR; 1679 } 1680 1681 rc4payload.secret_data.data = r->in.data_in; 1682 rc4payload.secret_data.length = r->in.data_in_len; 1683 1684 gnutls_hmac_init(&hmac_hnd, 1685 GNUTLS_MAC_SHA1, 1686 mackey, 1687 sizeof(mackey)); 1688 /* SID field */ 1689 gnutls_hmac(hmac_hnd, 1690 sid_blob.data, 1691 sid_blob.length); 1692 /* Secret field */ 1693 gnutls_hmac(hmac_hnd, 1694 rc4payload.secret_data.data, 1695 rc4payload.secret_data.length); 1696 gnutls_hmac_deinit(hmac_hnd, rc4payload.mac); 1697 1698 dump_data_pw("rc4payload.mac: \n", rc4payload.mac, sizeof(rc4payload.mac)); 1699 1700 rc4payload.sid = *caller_sid; 1701 1702 ndr_err = ndr_push_struct_blob(&encrypted_blob, mem_ctx, &rc4payload, 1703 (ndr_push_flags_fn_t)ndr_push_bkrp_rc4encryptedpayload); 1704 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { 1705 return WERR_INTERNAL_ERROR; 1706 } 1707 1708 /* rc4 encrypt sid and secret using sym key */ 1709 cipher_key.data = symkey; 1710 cipher_key.size = sizeof(symkey); 1711 1712 rc = gnutls_cipher_init(&cipher_hnd, 1713 GNUTLS_CIPHER_ARCFOUR_128, 1714 &cipher_key, 1715 NULL); 1716 if (rc != GNUTLS_E_SUCCESS) { 1717 DBG_ERR("gnutls_cipher_init failed - %s\n", 1718 gnutls_strerror(rc)); 1719 return WERR_INVALID_PARAM; 1720 } 1721 rc = gnutls_cipher_encrypt2(cipher_hnd, 1722 encrypted_blob.data, 1723 encrypted_blob.length, 1724 encrypted_blob.data, 1725 encrypted_blob.length); 1726 gnutls_cipher_deinit(cipher_hnd); 1727 if (rc != GNUTLS_E_SUCCESS) { 1728 DBG_ERR("gnutls_cipher_encrypt2 failed - %s\n", 1729 gnutls_strerror(rc)); 1730 return WERR_INVALID_PARAM; 1731 } 1732 1733 /* create server wrap structure */ 1734 1735 server_side_wrapped.payload_length = rc4payload.secret_data.length; 1736 server_side_wrapped.ciphertext_length = encrypted_blob.length; 1737 server_side_wrapped.guid = guid; 1738 server_side_wrapped.rc4encryptedpayload = encrypted_blob.data; 1739 1740 ndr_err = ndr_push_struct_blob(&server_wrapped_blob, mem_ctx, &server_side_wrapped, 1741 (ndr_push_flags_fn_t)ndr_push_bkrp_server_side_wrapped); 1742 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { 1743 return WERR_INTERNAL_ERROR; 1744 } 1745 1746 *(r->out.data_out) = server_wrapped_blob.data; 1747 *(r->out.data_out_len) = server_wrapped_blob.length; 1748 1749 return WERR_OK; 1247 1750 } 1248 1751 … … 1257 1760 const int debuglevel = 4; 1258 1761 1762 gnutls_global_init(); 1763 1259 1764 if (DEBUGLVL(debuglevel)) { 1260 1765 const struct tsocket_address *remote_address; … … 1266 1771 } 1267 1772 1268 if (lpcfg_server_role(dce_call->conn->dce_ctx->lp_ctx) != ROLE_ DOMAIN_CONTROLLER) {1773 if (lpcfg_server_role(dce_call->conn->dce_ctx->lp_ctx) != ROLE_ACTIVE_DIRECTORY_DC) { 1269 1774 return WERR_NOT_SUPPORTED; 1270 }1271 1272 if (!dce_call->conn->auth_state.auth_info ||1273 dce_call->conn->auth_state.auth_info->auth_level != DCERPC_AUTH_LEVEL_PRIVACY) {1274 DCESRV_FAULT(DCERPC_FAULT_ACCESS_DENIED);1275 1775 } 1276 1776 … … 1287 1787 if(strncasecmp(GUID_string(mem_ctx, r->in.guidActionAgent), 1288 1788 BACKUPKEY_RESTORE_GUID, strlen(BACKUPKEY_RESTORE_GUID)) == 0) { 1289 DEBUG(debuglevel, ("Client %s requested to decrypt a client sidewrapped secret\n", addr));1290 error = bkrp_ do_uncrypt_client_wrap_key(dce_call, mem_ctx, r, ldb_ctx);1789 DEBUG(debuglevel, ("Client %s requested to decrypt a wrapped secret\n", addr)); 1790 error = bkrp_generic_decrypt_data(dce_call, mem_ctx, r, ldb_ctx); 1291 1791 } 1292 1792 … … 1294 1794 BACKUPKEY_RETRIEVE_BACKUP_KEY_GUID, strlen(BACKUPKEY_RETRIEVE_BACKUP_KEY_GUID)) == 0) { 1295 1795 DEBUG(debuglevel, ("Client %s requested certificate for client wrapped secret\n", addr)); 1296 error = bkrp_do_retreive_client_wrap_key(dce_call, mem_ctx, r, ldb_ctx); 1796 error = bkrp_retrieve_client_wrap_key(dce_call, mem_ctx, r, ldb_ctx); 1797 } 1798 1799 if (strncasecmp(GUID_string(mem_ctx, r->in.guidActionAgent), 1800 BACKUPKEY_RESTORE_GUID_WIN2K, strlen(BACKUPKEY_RESTORE_GUID_WIN2K)) == 0) { 1801 DEBUG(debuglevel, ("Client %s requested to decrypt a server side wrapped secret\n", addr)); 1802 error = bkrp_server_wrap_decrypt_data(dce_call, mem_ctx, r, ldb_ctx); 1803 } 1804 1805 if (strncasecmp(GUID_string(mem_ctx, r->in.guidActionAgent), 1806 BACKUPKEY_BACKUP_GUID, strlen(BACKUPKEY_BACKUP_GUID)) == 0) { 1807 DEBUG(debuglevel, ("Client %s requested a server wrapped secret\n", addr)); 1808 error = bkrp_server_wrap_encrypt_data(dce_call, mem_ctx, r, ldb_ctx); 1297 1809 } 1298 1810 } 1299 1811 /*else: I am a RODC so I don't handle backup key protocol */ 1300 1812 1813 gnutls_global_deinit(); 1301 1814 talloc_unlink(mem_ctx, ldb_ctx); 1302 1815 return error; -
vendor/current/source4/rpc_server/common/reply.c
r740 r988 68 68 break; 69 69 case DCESRV_LIST_CALL_LIST: 70 DLIST_ADD_END(call->conn->call_list, call , struct dcesrv_call_state *);70 DLIST_ADD_END(call->conn->call_list, call); 71 71 break; 72 72 case DCESRV_LIST_FRAGMENTED_CALL_LIST: 73 DLIST_ADD_END(call->conn->incoming_fragmented_call_list, call , struct dcesrv_call_state *);73 DLIST_ADD_END(call->conn->incoming_fragmented_call_list, call); 74 74 break; 75 75 case DCESRV_LIST_PENDING_CALL_LIST: 76 DLIST_ADD_END(call->conn->pending_call_list, call , struct dcesrv_call_state *);76 DLIST_ADD_END(call->conn->pending_call_list, call); 77 77 break; 78 78 } … … 98 98 return a dcerpc fault 99 99 */ 100 NTSTATUS dcesrv_fault(struct dcesrv_call_state *call, uint32_t fault_code) 100 NTSTATUS dcesrv_fault_with_flags(struct dcesrv_call_state *call, 101 uint32_t fault_code, 102 uint8_t extra_flags) 101 103 { 102 104 struct ncacn_packet pkt; 103 105 struct data_blob_list_item *rep; 104 uint8_t zeros[4];106 static const uint8_t zeros[4] = { 0, }; 105 107 NTSTATUS status; 106 108 107 /* setup a bind_ack*/109 /* setup a fault */ 108 110 dcesrv_init_hdr(&pkt, lpcfg_rpc_big_endian(call->conn->dce_ctx->lp_ctx)); 109 111 pkt.auth_length = 0; 110 112 pkt.call_id = call->pkt.call_id; 111 113 pkt.ptype = DCERPC_PKT_FAULT; 112 pkt.pfc_flags = DCERPC_PFC_FLAG_FIRST | DCERPC_PFC_FLAG_LAST; 113 pkt.u.fault.alloc_hint = 0; 114 pkt.u.fault.context_id = 0; 114 pkt.pfc_flags = DCERPC_PFC_FLAG_FIRST | DCERPC_PFC_FLAG_LAST | extra_flags; 115 pkt.u.fault.alloc_hint = 24; 116 switch (call->pkt.ptype) { 117 case DCERPC_PKT_REQUEST: 118 pkt.u.fault.context_id = call->pkt.u.request.context_id; 119 break; 120 default: 121 pkt.u.fault.context_id = 0; 122 break; 123 } 124 if (fault_code == DCERPC_NCA_S_PROTO_ERROR) { 125 /* 126 * context_id = 0 is forced on protocol errors. 127 */ 128 pkt.u.fault.context_id = 0; 129 } 115 130 pkt.u.fault.cancel_count = 0; 116 131 pkt.u.fault.status = fault_code; 117 118 ZERO_STRUCT(zeros);119 132 pkt.u.fault._pad = data_blob_const(zeros, sizeof(zeros)); 120 133 121 rep = talloc (call, struct data_blob_list_item);134 rep = talloc_zero(call, struct data_blob_list_item); 122 135 if (!rep) { 123 136 return NT_STATUS_NO_MEMORY; … … 131 144 dcerpc_set_frag_length(&rep->blob, rep->blob.length); 132 145 133 DLIST_ADD_END(call->replies, rep , struct data_blob_list_item *);146 DLIST_ADD_END(call->replies, rep); 134 147 dcesrv_call_set_list(call, DCESRV_LIST_CALL_LIST); 135 148 … … 143 156 } 144 157 145 158 NTSTATUS dcesrv_fault(struct dcesrv_call_state *call, uint32_t fault_code) 159 { 160 return dcesrv_fault_with_flags(call, fault_code, 0); 161 } 146 162 147 163 _PUBLIC_ NTSTATUS dcesrv_reply(struct dcesrv_call_state *call) … … 184 200 /* we can write a full max_recv_frag size, minus the dcerpc 185 201 request header size */ 186 chunk_size = call->conn-> cli_max_recv_frag;202 chunk_size = call->conn->max_xmit_frag; 187 203 chunk_size -= DCERPC_REQUEST_LENGTH; 188 if (call->conn->auth_state.auth_ info&&204 if (call->conn->auth_state.auth_finished && 189 205 call->conn->auth_state.gensec_security) { 206 size_t max_payload = chunk_size; 207 208 max_payload -= DCERPC_AUTH_TRAILER_LENGTH; 209 max_payload -= (max_payload % DCERPC_AUTH_PAD_ALIGNMENT); 210 190 211 sig_size = gensec_sig_size(call->conn->auth_state.gensec_security, 191 call->conn->cli_max_recv_frag);212 max_payload); 192 213 if (sig_size) { 193 214 chunk_size -= DCERPC_AUTH_TRAILER_LENGTH; … … 195 216 } 196 217 } 197 chunk_size -= (chunk_size % 16);218 chunk_size -= (chunk_size % DCERPC_AUTH_PAD_ALIGNMENT); 198 219 199 220 do { … … 202 223 struct ncacn_packet pkt; 203 224 204 rep = talloc (call, struct data_blob_list_item);225 rep = talloc_zero(call, struct data_blob_list_item); 205 226 NT_STATUS_HAVE_NO_MEMORY(rep); 206 227 … … 234 255 dcerpc_set_frag_length(&rep->blob, rep->blob.length); 235 256 236 DLIST_ADD_END(call->replies, rep , struct data_blob_list_item *);257 DLIST_ADD_END(call->replies, rep); 237 258 238 259 stub.data += length; … … 255 276 DATA_BLOB *session_key) 256 277 { 278 enum dcerpc_transport_t transport = 279 dcerpc_binding_get_transport(c->endpoint->ep_description); 280 281 if (transport != NCALRPC && transport != NCACN_UNIX_STREAM) { 282 return NT_STATUS_NO_USER_SESSION_KEY; 283 } 284 257 285 return dcerpc_generic_session_key(NULL, session_key); 258 286 } -
vendor/current/source4/rpc_server/common/server_info.c
r740 r988 26 26 #include "auth/auth.h" 27 27 #include "param/param.h" 28 #include "rpc_server/common/common.h" 29 #include "rpc_server/common/share.h" 30 #include "libds/common/roles.h" 28 31 29 32 /* … … 67 70 default_server_announce |= SV_TYPE_SERVER_UNIX; 68 71 69 switch (lpcfg_announce_as(dce_ctx->lp_ctx)) { 70 case ANNOUNCE_AS_NT_SERVER: 71 default_server_announce |= SV_TYPE_SERVER_NT; 72 /* fall through... */ 73 case ANNOUNCE_AS_NT_WORKSTATION: 74 default_server_announce |= SV_TYPE_NT; 75 break; 76 case ANNOUNCE_AS_WIN95: 77 default_server_announce |= SV_TYPE_WIN95_PLUS; 78 break; 79 case ANNOUNCE_AS_WFW: 80 default_server_announce |= SV_TYPE_WFW; 81 break; 82 default: 83 break; 84 } 72 default_server_announce |= SV_TYPE_SERVER_NT; 73 default_server_announce |= SV_TYPE_NT; 85 74 86 75 switch (lpcfg_server_role(dce_ctx->lp_ctx)) { … … 88 77 default_server_announce |= SV_TYPE_DOMAIN_MEMBER; 89 78 break; 90 case ROLE_ DOMAIN_CONTROLLER:79 case ROLE_ACTIVE_DIRECTORY_DC: 91 80 { 92 81 struct ldb_context *samctx; -
vendor/current/source4/rpc_server/common/share_info.c
r414 r988 24 24 #include "librpc/gen_ndr/srvsvc.h" 25 25 #include "rpc_server/dcerpc_server.h" 26 #include "rpc_server/common/share.h" 26 27 27 28 /* … … 53 54 */ 54 55 enum srvsvc_ShareType share_type = 0; 55 c onst char *sharetype;56 char *sharetype; 56 57 57 58 if (!share_bool_option(scfg, SHARE_BROWSEABLE, SHARE_BROWSEABLE_DEFAULT)) { … … 59 60 } 60 61 61 sharetype = share_string_option( scfg, SHARE_TYPE, SHARE_TYPE_DEFAULT);62 sharetype = share_string_option(mem_ctx, scfg, SHARE_TYPE, SHARE_TYPE_DEFAULT); 62 63 if (sharetype && strcasecmp(sharetype, "IPC") == 0) { 63 64 share_type |= STYPE_IPC; 65 TALLOC_FREE(sharetype); 64 66 return share_type; 65 67 } … … 67 69 if (sharetype && strcasecmp(sharetype, "PRINTER") == 0) { 68 70 share_type |= STYPE_PRINTQ; 71 TALLOC_FREE(sharetype); 69 72 return share_type; 70 73 } 71 74 75 TALLOC_FREE(sharetype); 72 76 share_type |= STYPE_DISKTREE; 73 77 … … 78 82 const char *dcesrv_common_get_share_path(TALLOC_CTX *mem_ctx, struct dcesrv_context *dce_ctx, struct share_config *scfg) 79 83 { 80 c onst char *sharetype;84 char *sharetype; 81 85 char *p; 82 83 sharetype = share_string_option(scfg, SHARE_TYPE, SHARE_TYPE_DEFAULT); 86 char *path; 87 88 sharetype = share_string_option(mem_ctx, scfg, SHARE_TYPE, SHARE_TYPE_DEFAULT); 84 89 85 90 if (sharetype && strcasecmp(sharetype, "IPC") == 0) { 91 TALLOC_FREE(sharetype); 86 92 return talloc_strdup(mem_ctx, ""); 87 93 } 88 94 89 p = talloc_strdup(mem_ctx, share_string_option(scfg, SHARE_PATH, "")); 95 TALLOC_FREE(sharetype); 96 97 p = share_string_option(mem_ctx, scfg, SHARE_PATH, ""); 90 98 if (!p) { 91 99 return NULL; … … 96 104 all_string_sub(p, "/", "\\", 0); 97 105 98 return talloc_asprintf(mem_ctx, "C:%s", p); 106 path = talloc_asprintf(mem_ctx, "C:%s", p); 107 TALLOC_FREE(p); 108 return path; 99 109 } 100 110 -
vendor/current/source4/rpc_server/dcerpc_server.c
r740 r988 40 40 #include "lib/messaging/irpc.h" 41 41 #include "librpc/rpc/rpc_common.h" 42 43 /* this is only used when the client asks for an unknown interface */ 44 #define DUMMY_ASSOC_GROUP 0x0FFFFFFF 42 #include "lib/util/samba_modules.h" 43 #include "librpc/gen_ndr/ndr_dcerpc.h" 45 44 46 45 extern const struct dcesrv_interface dcesrv_mgmt_interface; … … 73 72 assoc_group = dcesrv_assoc_group_find(dce_ctx, id); 74 73 if (assoc_group == NULL) { 75 DEBUG( 0,(__location__ ": Failed to find assoc_group 0x%08x\n", id));74 DEBUG(2,(__location__ ": Failed to find assoc_group 0x%08x\n", id)); 76 75 return NULL; 77 76 } … … 126 125 const struct dcerpc_binding *ep2) 127 126 { 128 if (ep1->transport != ep2->transport) { 127 enum dcerpc_transport_t t1; 128 enum dcerpc_transport_t t2; 129 const char *e1; 130 const char *e2; 131 132 t1 = dcerpc_binding_get_transport(ep1); 133 t2 = dcerpc_binding_get_transport(ep2); 134 135 e1 = dcerpc_binding_get_string_option(ep1, "endpoint"); 136 e2 = dcerpc_binding_get_string_option(ep2, "endpoint"); 137 138 if (t1 != t2) { 129 139 return false; 130 140 } 131 141 132 if (!e p1->endpoint || !ep2->endpoint) {133 return e p1->endpoint == ep2->endpoint;134 } 135 136 if (strcasecmp(e p1->endpoint, ep2->endpoint) != 0)142 if (!e1 || !e2) { 143 return e1 == e2; 144 } 145 146 if (strcasecmp(e1, e2) != 0) { 137 147 return false; 148 } 138 149 139 150 return true; … … 256 267 */ 257 268 if ((ep=find_endpoint(dce_ctx, binding))==NULL) { 258 ep = talloc (dce_ctx, struct dcesrv_endpoint);269 ep = talloc_zero(dce_ctx, struct dcesrv_endpoint); 259 270 if (!ep) { 260 271 return NT_STATUS_NO_MEMORY; 261 272 } 262 273 ZERO_STRUCTP(ep); 263 ep->ep_description = talloc_ reference(ep,binding);274 ep->ep_description = talloc_move(ep, &binding); 264 275 add_ep = true; 265 276 266 277 /* add mgmt interface */ 267 ifl = talloc (dce_ctx, struct dcesrv_if_list);278 ifl = talloc_zero(ep, struct dcesrv_if_list); 268 279 if (!ifl) { 269 280 return NT_STATUS_NO_MEMORY; … … 284 295 285 296 /* talloc a new interface list element */ 286 ifl = talloc (dce_ctx, struct dcesrv_if_list);297 ifl = talloc_zero(ep, struct dcesrv_if_list); 287 298 if (!ifl) { 288 299 return NT_STATUS_NO_MEMORY; … … 300 311 */ 301 312 if (ep->sd == NULL) { 302 ep->sd = security_descriptor_copy( dce_ctx, sd);313 ep->sd = security_descriptor_copy(ep, sd); 303 314 } 304 315 … … 367 378 struct auth_session_info *session_info, 368 379 struct tevent_context *event_ctx, 369 struct messaging_context *msg_ctx,380 struct imessaging_context *msg_ctx, 370 381 struct server_id server_id, 371 382 uint32_t state_flags, … … 378 389 } 379 390 380 p = talloc (mem_ctx, struct dcesrv_connection);391 p = talloc_zero(mem_ctx, struct dcesrv_connection); 381 392 NT_STATUS_HAVE_NO_MEMORY(p); 382 393 … … 388 399 p->dce_ctx = dce_ctx; 389 400 p->endpoint = ep; 390 p->contexts = NULL; 391 p->call_list = NULL; 392 p->packet_log_dir = lpcfg_lockdir(dce_ctx->lp_ctx); 393 p->incoming_fragmented_call_list = NULL; 394 p->pending_call_list = NULL; 395 p->cli_max_recv_frag = 0; 396 p->partial_input = data_blob(NULL, 0); 397 p->auth_state.auth_info = NULL; 398 p->auth_state.gensec_security = NULL; 401 p->packet_log_dir = lpcfg_lock_directory(dce_ctx->lp_ctx); 399 402 p->auth_state.session_info = session_info; 400 403 p->auth_state.session_key = dcesrv_generic_session_key; … … 402 405 p->msg_ctx = msg_ctx; 403 406 p->server_id = server_id; 404 p->processing = false;405 407 p->state_flags = state_flags; 406 ZERO_STRUCT(p->transport); 408 p->allow_bind = true; 409 p->max_recv_frag = 5840; 410 p->max_xmit_frag = 5840; 407 411 408 412 *_p = p; … … 436 440 break; 437 441 case DCESRV_LIST_CALL_LIST: 438 DLIST_ADD_END(call->conn->call_list, call , struct dcesrv_call_state *);442 DLIST_ADD_END(call->conn->call_list, call); 439 443 break; 440 444 case DCESRV_LIST_FRAGMENTED_CALL_LIST: 441 DLIST_ADD_END(call->conn->incoming_fragmented_call_list, call , struct dcesrv_call_state *);445 DLIST_ADD_END(call->conn->incoming_fragmented_call_list, call); 442 446 break; 443 447 case DCESRV_LIST_PENDING_CALL_LIST: 444 DLIST_ADD_END(call->conn->pending_call_list, call , struct dcesrv_call_state *);448 DLIST_ADD_END(call->conn->pending_call_list, call); 445 449 break; 446 450 } 447 451 } 448 452 453 static void dcesrv_call_disconnect_after(struct dcesrv_call_state *call, 454 const char *reason) 455 { 456 if (call->conn->terminate != NULL) { 457 return; 458 } 459 460 call->conn->allow_bind = false; 461 call->conn->allow_alter = false; 462 call->conn->allow_auth3 = false; 463 call->conn->allow_request = false; 464 465 call->terminate_reason = talloc_strdup(call, reason); 466 if (call->terminate_reason == NULL) { 467 call->terminate_reason = __location__; 468 } 469 } 449 470 450 471 /* … … 454 475 { 455 476 struct ncacn_packet pkt; 477 struct dcerpc_bind_nak_version version; 456 478 struct data_blob_list_item *rep; 457 479 NTSTATUS status; 480 static const uint8_t _pad[3] = { 0, }; 481 482 /* 483 * We add the call to the pending_call_list 484 * in order to defer the termination. 485 */ 486 dcesrv_call_disconnect_after(call, "dcesrv_bind_nak"); 458 487 459 488 /* setup a bind_nak */ … … 464 493 pkt.pfc_flags = DCERPC_PFC_FLAG_FIRST | DCERPC_PFC_FLAG_LAST; 465 494 pkt.u.bind_nak.reject_reason = reason; 466 if (pkt.u.bind_nak.reject_reason == DECRPC_BIND_PROTOCOL_VERSION_NOT_SUPPORTED) { 467 pkt.u.bind_nak.versions.v.num_versions = 0; 468 } 469 470 rep = talloc(call, struct data_blob_list_item); 495 version.rpc_vers = 5; 496 version.rpc_vers_minor = 0; 497 pkt.u.bind_nak.num_versions = 1; 498 pkt.u.bind_nak.versions = &version; 499 pkt.u.bind_nak._pad = data_blob_const(_pad, sizeof(_pad)); 500 501 rep = talloc_zero(call, struct data_blob_list_item); 471 502 if (!rep) { 472 503 return NT_STATUS_NO_MEMORY; … … 480 511 dcerpc_set_frag_length(&rep->blob, rep->blob.length); 481 512 482 DLIST_ADD_END(call->replies, rep , struct data_blob_list_item *);513 DLIST_ADD_END(call->replies, rep); 483 514 dcesrv_call_set_list(call, DCESRV_LIST_CALL_LIST); 484 515 … … 492 523 } 493 524 525 static NTSTATUS dcesrv_fault_disconnect(struct dcesrv_call_state *call, 526 uint32_t fault_code) 527 { 528 /* 529 * We add the call to the pending_call_list 530 * in order to defer the termination. 531 */ 532 dcesrv_call_disconnect_after(call, "dcesrv_fault_disconnect"); 533 534 return dcesrv_fault_with_flags(call, fault_code, 535 DCERPC_PFC_FLAG_DID_NOT_EXECUTE); 536 } 537 494 538 static int dcesrv_connection_context_destructor(struct dcesrv_connection_context *c) 495 539 { … … 498 542 if (c->iface && c->iface->unbind) { 499 543 c->iface->unbind(c, c->iface); 544 c->iface = NULL; 500 545 } 501 546 502 547 return 0; 548 } 549 550 static void dcesrv_prepare_context_auth(struct dcesrv_call_state *dce_call) 551 { 552 struct loadparm_context *lp_ctx = dce_call->conn->dce_ctx->lp_ctx; 553 const struct dcesrv_endpoint *endpoint = dce_call->conn->endpoint; 554 enum dcerpc_transport_t transport = 555 dcerpc_binding_get_transport(endpoint->ep_description); 556 struct dcesrv_connection_context *context = dce_call->context; 557 const struct dcesrv_interface *iface = context->iface; 558 559 context->min_auth_level = DCERPC_AUTH_LEVEL_NONE; 560 561 if (transport == NCALRPC) { 562 context->allow_connect = true; 563 return; 564 } 565 566 /* 567 * allow overwrite per interface 568 * allow dcerpc auth level connect:<interface> 569 */ 570 context->allow_connect = lpcfg_allow_dcerpc_auth_level_connect(lp_ctx); 571 context->allow_connect = lpcfg_parm_bool(lp_ctx, NULL, 572 "allow dcerpc auth level connect", 573 iface->name, 574 context->allow_connect); 575 } 576 577 NTSTATUS dcesrv_interface_bind_require_integrity(struct dcesrv_call_state *dce_call, 578 const struct dcesrv_interface *iface) 579 { 580 if (dce_call->context == NULL) { 581 return NT_STATUS_INTERNAL_ERROR; 582 } 583 584 dce_call->context->min_auth_level = DCERPC_AUTH_LEVEL_INTEGRITY; 585 return NT_STATUS_OK; 586 } 587 588 NTSTATUS dcesrv_interface_bind_require_privacy(struct dcesrv_call_state *dce_call, 589 const struct dcesrv_interface *iface) 590 { 591 if (dce_call->context == NULL) { 592 return NT_STATUS_INTERNAL_ERROR; 593 } 594 595 dce_call->context->min_auth_level = DCERPC_AUTH_LEVEL_PRIVACY; 596 return NT_STATUS_OK; 597 } 598 599 _PUBLIC_ NTSTATUS dcesrv_interface_bind_reject_connect(struct dcesrv_call_state *dce_call, 600 const struct dcesrv_interface *iface) 601 { 602 struct loadparm_context *lp_ctx = dce_call->conn->dce_ctx->lp_ctx; 603 const struct dcesrv_endpoint *endpoint = dce_call->conn->endpoint; 604 enum dcerpc_transport_t transport = 605 dcerpc_binding_get_transport(endpoint->ep_description); 606 struct dcesrv_connection_context *context = dce_call->context; 607 608 if (context == NULL) { 609 return NT_STATUS_INTERNAL_ERROR; 610 } 611 612 if (transport == NCALRPC) { 613 context->allow_connect = true; 614 return NT_STATUS_OK; 615 } 616 617 /* 618 * allow overwrite per interface 619 * allow dcerpc auth level connect:<interface> 620 */ 621 context->allow_connect = false; 622 context->allow_connect = lpcfg_parm_bool(lp_ctx, NULL, 623 "allow dcerpc auth level connect", 624 iface->name, 625 context->allow_connect); 626 return NT_STATUS_OK; 627 } 628 629 _PUBLIC_ NTSTATUS dcesrv_interface_bind_allow_connect(struct dcesrv_call_state *dce_call, 630 const struct dcesrv_interface *iface) 631 { 632 struct loadparm_context *lp_ctx = dce_call->conn->dce_ctx->lp_ctx; 633 const struct dcesrv_endpoint *endpoint = dce_call->conn->endpoint; 634 enum dcerpc_transport_t transport = 635 dcerpc_binding_get_transport(endpoint->ep_description); 636 struct dcesrv_connection_context *context = dce_call->context; 637 638 if (context == NULL) { 639 return NT_STATUS_INTERNAL_ERROR; 640 } 641 642 if (transport == NCALRPC) { 643 context->allow_connect = true; 644 return NT_STATUS_OK; 645 } 646 647 /* 648 * allow overwrite per interface 649 * allow dcerpc auth level connect:<interface> 650 */ 651 context->allow_connect = true; 652 context->allow_connect = lpcfg_parm_bool(lp_ctx, NULL, 653 "allow dcerpc auth level connect", 654 iface->name, 655 context->allow_connect); 656 return NT_STATUS_OK; 503 657 } 504 658 … … 517 671 const struct dcesrv_interface *iface; 518 672 uint32_t extra_flags = 0; 673 uint16_t max_req = 0; 674 uint16_t max_rep = 0; 675 const char *ep_prefix = ""; 676 const char *endpoint = NULL; 677 678 status = dcerpc_verify_ncacn_packet_header(&call->pkt, 679 DCERPC_PKT_BIND, 680 call->pkt.u.bind.auth_info.length, 681 0, /* required flags */ 682 DCERPC_PFC_FLAG_FIRST | 683 DCERPC_PFC_FLAG_LAST | 684 DCERPC_PFC_FLAG_SUPPORT_HEADER_SIGN | 685 0x08 | /* this is not defined, but should be ignored */ 686 DCERPC_PFC_FLAG_CONC_MPX | 687 DCERPC_PFC_FLAG_DID_NOT_EXECUTE | 688 DCERPC_PFC_FLAG_MAYBE | 689 DCERPC_PFC_FLAG_OBJECT_UUID); 690 if (!NT_STATUS_IS_OK(status)) { 691 return dcesrv_bind_nak(call, 692 DCERPC_BIND_NAK_REASON_PROTOCOL_VERSION_NOT_SUPPORTED); 693 } 694 695 /* max_recv_frag and max_xmit_frag result always in the same value! */ 696 max_req = MIN(call->pkt.u.bind.max_xmit_frag, 697 call->pkt.u.bind.max_recv_frag); 698 /* 699 * The values are between 2048 and 5840 tested against Windows 2012R2 700 * via ncacn_ip_tcp on port 135. 701 */ 702 max_req = MAX(2048, max_req); 703 max_rep = MIN(max_req, call->conn->max_recv_frag); 704 /* They are truncated to an 8 byte boundary. */ 705 max_rep &= 0xFFF8; 706 707 /* max_recv_frag and max_xmit_frag result always in the same value! */ 708 call->conn->max_recv_frag = max_rep; 709 call->conn->max_xmit_frag = max_rep; 519 710 520 711 /* 521 712 if provided, check the assoc_group is valid 522 713 */ 523 if (call->pkt.u.bind.assoc_group_id != 0 && 524 lpcfg_parm_bool(call->conn->dce_ctx->lp_ctx, NULL, "dcesrv","assoc group checking", true) && 525 dcesrv_assoc_group_find(call->conn->dce_ctx, call->pkt.u.bind.assoc_group_id) == NULL) { 526 return dcesrv_bind_nak(call, 0); 714 if (call->pkt.u.bind.assoc_group_id != 0) { 715 call->conn->assoc_group = dcesrv_assoc_group_reference(call->conn, 716 call->conn->dce_ctx, 717 call->pkt.u.bind.assoc_group_id); 718 } else { 719 call->conn->assoc_group = dcesrv_assoc_group_new(call->conn, 720 call->conn->dce_ctx); 721 } 722 if (call->conn->assoc_group == NULL) { 723 return dcesrv_bind_nak(call, 0); 527 724 } 528 725 … … 533 730 534 731 context_id = call->pkt.u.bind.ctx_list[0].context_id; 535 536 /* you can't bind twice on one context */537 if (dcesrv_find_context(call->conn, context_id) != NULL) {538 return dcesrv_bind_nak(call, 0);539 }540 541 732 if_version = call->pkt.u.bind.ctx_list[0].abstract_syntax.if_version; 542 733 uuid = call->pkt.u.bind.ctx_list[0].abstract_syntax.uuid; … … 544 735 transfer_syntax_version = call->pkt.u.bind.ctx_list[0].transfer_syntaxes[0].if_version; 545 736 transfer_syntax_uuid = &call->pkt.u.bind.ctx_list[0].transfer_syntaxes[0].uuid; 546 if (!GUID_equal(&ndr_transfer_syntax .uuid, transfer_syntax_uuid) != 0 ||547 ndr_transfer_syntax .if_version != transfer_syntax_version) {737 if (!GUID_equal(&ndr_transfer_syntax_ndr.uuid, transfer_syntax_uuid) != 0 || 738 ndr_transfer_syntax_ndr.if_version != transfer_syntax_version) { 548 739 char *uuid_str = GUID_string(call, transfer_syntax_uuid); 549 740 /* we only do NDR encoded dcerpc */ … … 566 757 if (iface) { 567 758 /* add this context to the list of available context_ids */ 568 struct dcesrv_connection_context *context = talloc (call->conn,759 struct dcesrv_connection_context *context = talloc_zero(call->conn, 569 760 struct dcesrv_connection_context); 570 761 if (context == NULL) { … … 574 765 context->iface = iface; 575 766 context->context_id = context_id; 576 if (call->pkt.u.bind.assoc_group_id != 0) { 577 context->assoc_group = dcesrv_assoc_group_reference(context, 578 call->conn->dce_ctx, 579 call->pkt.u.bind.assoc_group_id); 580 } else { 581 context->assoc_group = dcesrv_assoc_group_new(context, call->conn->dce_ctx); 582 } 583 if (context->assoc_group == NULL) { 584 talloc_free(context); 585 return dcesrv_bind_nak(call, 0); 586 } 767 /* legacy for openchange dcesrv_mapiproxy.c */ 768 context->assoc_group = call->conn->assoc_group; 587 769 context->private_data = NULL; 588 770 DLIST_ADD(call->conn->contexts, context); 589 771 call->context = context; 590 772 talloc_set_destructor(context, dcesrv_connection_context_destructor); 773 774 dcesrv_prepare_context_auth(call); 591 775 592 776 status = iface->bind(call, iface, if_version); … … 604 788 } 605 789 606 if ( call->conn->cli_max_recv_frag == 0) {607 call->conn->cli_max_recv_frag = MIN(0x2000, call->pkt.u.bind.max_recv_frag);608 }609 610 if ((call->pkt.pfc_flags & DCERPC_PFC_FLAG_SUPPORT_HEADER_SIGN) &&611 lpcfg_parm_bool(call->conn->dce_ctx->lp_ctx, NULL, "dcesrv","header signing", false)) { 612 call->conn->state_flags |= DCESRV_CALL_STATE_FLAG_HEADER_SIGNING;613 extra_flags |= DCERPC_PFC_FLAG_SUPPORT_HEADER_SIGN;790 if ((call->pkt.pfc_flags & DCERPC_PFC_FLAG_CONC_MPX) && 791 (call->state_flags & DCESRV_CALL_STATE_FLAG_MULTIPLEXED)) { 792 call->context->conn->state_flags |= DCESRV_CALL_STATE_FLAG_MULTIPLEXED; 793 extra_flags |= DCERPC_PFC_FLAG_CONC_MPX; 794 } 795 796 if (call->state_flags & DCESRV_CALL_STATE_FLAG_PROCESS_PENDING_CALL) { 797 call->context->conn->state_flags |= DCESRV_CALL_STATE_FLAG_PROCESS_PENDING_CALL; 614 798 } 615 799 616 800 /* handle any authentication that is being requested */ 617 801 if (!dcesrv_auth_bind(call)) { 618 talloc_free(call->context); 619 call->context = NULL; 620 return dcesrv_bind_nak(call, DCERPC_BIND_REASON_INVALID_AUTH_TYPE); 802 struct dcesrv_auth *auth = &call->conn->auth_state; 803 804 TALLOC_FREE(call->context); 805 806 if (auth->auth_level != DCERPC_AUTH_LEVEL_NONE) { 807 /* 808 * We only give INVALID_AUTH_TYPE if the auth_level was 809 * valid. 810 */ 811 return dcesrv_bind_nak(call, 812 DCERPC_BIND_NAK_REASON_INVALID_AUTH_TYPE); 813 } 814 return dcesrv_bind_nak(call, 815 DCERPC_BIND_NAK_REASON_NOT_SPECIFIED); 621 816 } 622 817 … … 627 822 pkt.ptype = DCERPC_PKT_BIND_ACK; 628 823 pkt.pfc_flags = DCERPC_PFC_FLAG_FIRST | DCERPC_PFC_FLAG_LAST | extra_flags; 629 pkt.u.bind_ack.max_xmit_frag = call->conn->cli_max_recv_frag; 630 pkt.u.bind_ack.max_recv_frag = 0x2000; 631 632 /* 633 make it possible for iface->bind() to specify the assoc_group_id 634 This helps the openchange mapiproxy plugin to work correctly. 635 636 metze 637 */ 638 if (call->context) { 639 pkt.u.bind_ack.assoc_group_id = call->context->assoc_group->id; 640 } else { 641 pkt.u.bind_ack.assoc_group_id = DUMMY_ASSOC_GROUP; 642 } 824 pkt.u.bind_ack.max_xmit_frag = call->conn->max_xmit_frag; 825 pkt.u.bind_ack.max_recv_frag = call->conn->max_recv_frag; 826 pkt.u.bind_ack.assoc_group_id = call->conn->assoc_group->id; 643 827 644 828 if (iface) { 645 /* FIXME: Use pipe name as specified by endpoint instead of interface name */ 646 pkt.u.bind_ack.secondary_address = talloc_asprintf(call, "\\PIPE\\%s", iface->name); 647 } else { 648 pkt.u.bind_ack.secondary_address = ""; 829 endpoint = dcerpc_binding_get_string_option( 830 call->conn->endpoint->ep_description, 831 "endpoint"); 832 } 833 834 if (endpoint == NULL) { 835 endpoint = ""; 836 } 837 838 if (strncasecmp(endpoint, "\\pipe\\", 6) == 0) { 839 /* 840 * TODO: check if this is really needed 841 * 842 * Or if we should fix this in our idl files. 843 */ 844 ep_prefix = "\\PIPE\\"; 845 endpoint += 6; 846 } 847 848 pkt.u.bind_ack.secondary_address = talloc_asprintf(call, "%s%s", 849 ep_prefix, 850 endpoint); 851 if (pkt.u.bind_ack.secondary_address == NULL) { 852 TALLOC_FREE(call->context); 853 return NT_STATUS_NO_MEMORY; 649 854 } 650 855 pkt.u.bind_ack.num_results = 1; 651 pkt.u.bind_ack.ctx_list = talloc (call, struct dcerpc_ack_ctx);856 pkt.u.bind_ack.ctx_list = talloc_zero(call, struct dcerpc_ack_ctx); 652 857 if (!pkt.u.bind_ack.ctx_list) { 653 858 talloc_free(call->context); … … 656 861 } 657 862 pkt.u.bind_ack.ctx_list[0].result = result; 658 pkt.u.bind_ack.ctx_list[0].reason = reason;659 pkt.u.bind_ack.ctx_list[0].syntax = ndr_transfer_syntax ;863 pkt.u.bind_ack.ctx_list[0].reason.value = reason; 864 pkt.u.bind_ack.ctx_list[0].syntax = ndr_transfer_syntax_ndr; 660 865 pkt.u.bind_ack.auth_info = data_blob(NULL, 0); 661 866 … … 667 872 } 668 873 669 rep = talloc (call, struct data_blob_list_item);874 rep = talloc_zero(call, struct data_blob_list_item); 670 875 if (!rep) { 671 876 talloc_free(call->context); … … 675 880 676 881 status = ncacn_push_auth(&rep->blob, call, &pkt, 677 call->conn->auth_state.auth_info);882 call->out_auth_info); 678 883 if (!NT_STATUS_IS_OK(status)) { 679 884 talloc_free(call->context); … … 684 889 dcerpc_set_frag_length(&rep->blob, rep->blob.length); 685 890 686 DLIST_ADD_END(call->replies, rep , struct data_blob_list_item *);891 DLIST_ADD_END(call->replies, rep); 687 892 dcesrv_call_set_list(call, DCESRV_LIST_CALL_LIST); 688 893 … … 702 907 static NTSTATUS dcesrv_auth3(struct dcesrv_call_state *call) 703 908 { 909 NTSTATUS status; 910 911 if (!call->conn->allow_auth3) { 912 return dcesrv_fault_disconnect(call, DCERPC_NCA_S_PROTO_ERROR); 913 } 914 915 if (call->conn->auth_state.auth_finished) { 916 return dcesrv_fault_disconnect(call, DCERPC_NCA_S_PROTO_ERROR); 917 } 918 919 status = dcerpc_verify_ncacn_packet_header(&call->pkt, 920 DCERPC_PKT_AUTH3, 921 call->pkt.u.auth3.auth_info.length, 922 0, /* required flags */ 923 DCERPC_PFC_FLAG_FIRST | 924 DCERPC_PFC_FLAG_LAST | 925 DCERPC_PFC_FLAG_SUPPORT_HEADER_SIGN | 926 0x08 | /* this is not defined, but should be ignored */ 927 DCERPC_PFC_FLAG_CONC_MPX | 928 DCERPC_PFC_FLAG_DID_NOT_EXECUTE | 929 DCERPC_PFC_FLAG_MAYBE | 930 DCERPC_PFC_FLAG_OBJECT_UUID); 931 if (!NT_STATUS_IS_OK(status)) { 932 return dcesrv_fault_disconnect(call, DCERPC_NCA_S_PROTO_ERROR); 933 } 934 704 935 /* handle the auth3 in the auth code */ 705 936 if (!dcesrv_auth_auth3(call)) { 706 return dcesrv_fault(call, DCERPC_FAULT_OTHER);937 call->conn->auth_state.auth_invalid = true; 707 938 } 708 939 … … 731 962 transfer_syntax_version = call->pkt.u.alter.ctx_list[0].transfer_syntaxes[0].if_version; 732 963 transfer_syntax_uuid = &call->pkt.u.alter.ctx_list[0].transfer_syntaxes[0].uuid; 733 if (!GUID_equal(transfer_syntax_uuid, &ndr_transfer_syntax .uuid) ||734 ndr_transfer_syntax .if_version != transfer_syntax_version) {964 if (!GUID_equal(transfer_syntax_uuid, &ndr_transfer_syntax_ndr.uuid) || 965 ndr_transfer_syntax_ndr.if_version != transfer_syntax_version) { 735 966 /* we only do NDR encoded dcerpc */ 736 967 return NT_STATUS_RPC_PROTSEQ_NOT_SUPPORTED; … … 746 977 747 978 /* add this context to the list of available context_ids */ 748 context = talloc (call->conn, struct dcesrv_connection_context);979 context = talloc_zero(call->conn, struct dcesrv_connection_context); 749 980 if (context == NULL) { 750 981 return NT_STATUS_NO_MEMORY; … … 753 984 context->iface = iface; 754 985 context->context_id = context_id; 755 if (call->pkt.u.alter.assoc_group_id != 0) { 756 context->assoc_group = dcesrv_assoc_group_reference(context, 757 call->conn->dce_ctx, 758 call->pkt.u.alter.assoc_group_id); 759 } else { 760 context->assoc_group = dcesrv_assoc_group_new(context, call->conn->dce_ctx); 761 } 762 if (context->assoc_group == NULL) { 763 talloc_free(context); 764 call->context = NULL; 765 return NT_STATUS_NO_MEMORY; 766 } 986 /* legacy for openchange dcesrv_mapiproxy.c */ 987 context->assoc_group = call->conn->assoc_group; 767 988 context->private_data = NULL; 768 989 DLIST_ADD(call->conn->contexts, context); 769 990 call->context = context; 770 991 talloc_set_destructor(context, dcesrv_connection_context_destructor); 992 993 dcesrv_prepare_context_auth(call); 771 994 772 995 status = iface->bind(call, iface, if_version); … … 782 1005 } 783 1006 784 785 /* 786 handle a alter context request 787 */ 788 static NTSTATUS dcesrv_alter(struct dcesrv_call_state *call) 1007 /* setup and send an alter_resp */ 1008 static NTSTATUS dcesrv_alter_resp(struct dcesrv_call_state *call, 1009 uint32_t result, 1010 uint32_t reason) 789 1011 { 790 1012 struct ncacn_packet pkt; 791 struct data_blob_list_item *rep; 1013 uint32_t extra_flags = 0; 1014 struct data_blob_list_item *rep = NULL; 792 1015 NTSTATUS status; 793 uint32_t result=0, reason=0; 794 uint32_t context_id; 795 796 /* handle any authentication that is being requested */ 797 if (!dcesrv_auth_alter(call)) { 798 /* TODO: work out the right reject code */ 799 result = DCERPC_BIND_PROVIDER_REJECT; 800 reason = DCERPC_BIND_REASON_ASYNTAX; 801 } 802 803 context_id = call->pkt.u.alter.ctx_list[0].context_id; 804 805 /* see if they are asking for a new interface */ 806 if (result == 0) { 807 call->context = dcesrv_find_context(call->conn, context_id); 808 if (!call->context) { 809 status = dcesrv_alter_new_context(call, context_id); 810 if (!NT_STATUS_IS_OK(status)) { 811 result = DCERPC_BIND_PROVIDER_REJECT; 812 reason = DCERPC_BIND_REASON_ASYNTAX; 813 } 814 } 815 } 816 817 if (result == 0 && 818 call->pkt.u.alter.assoc_group_id != 0 && 819 lpcfg_parm_bool(call->conn->dce_ctx->lp_ctx, NULL, "dcesrv","assoc group checking", true) && 820 call->pkt.u.alter.assoc_group_id != call->context->assoc_group->id) { 821 DEBUG(0,(__location__ ": Failed attempt to use new assoc_group in alter context (0x%08x 0x%08x)\n", 822 call->context->assoc_group->id, call->pkt.u.alter.assoc_group_id)); 823 /* TODO: can they ask for a new association group? */ 824 result = DCERPC_BIND_PROVIDER_REJECT; 825 reason = DCERPC_BIND_REASON_ASYNTAX; 826 } 827 828 /* setup a alter_resp */ 1016 829 1017 dcesrv_init_hdr(&pkt, lpcfg_rpc_big_endian(call->conn->dce_ctx->lp_ctx)); 830 1018 pkt.auth_length = 0; 831 1019 pkt.call_id = call->pkt.call_id; 832 1020 pkt.ptype = DCERPC_PKT_ALTER_RESP; 833 pkt.pfc_flags = DCERPC_PFC_FLAG_FIRST | DCERPC_PFC_FLAG_LAST;834 pkt.u.alter_resp.max_xmit_frag = 0x2000;835 pkt.u.alter_resp.max_recv_frag = 0x2000;836 1021 if (result == 0) { 837 pkt.u.alter_resp.assoc_group_id = call->context->assoc_group->id; 838 } else { 839 pkt.u.alter_resp.assoc_group_id = 0; 840 } 1022 if ((call->pkt.pfc_flags & DCERPC_PFC_FLAG_CONC_MPX) && 1023 call->context->conn->state_flags & 1024 DCESRV_CALL_STATE_FLAG_MULTIPLEXED) { 1025 extra_flags |= DCERPC_PFC_FLAG_CONC_MPX; 1026 } 1027 if (call->state_flags & DCESRV_CALL_STATE_FLAG_PROCESS_PENDING_CALL) { 1028 call->context->conn->state_flags |= 1029 DCESRV_CALL_STATE_FLAG_PROCESS_PENDING_CALL; 1030 } 1031 } 1032 pkt.pfc_flags = DCERPC_PFC_FLAG_FIRST | DCERPC_PFC_FLAG_LAST | extra_flags; 1033 pkt.u.alter_resp.max_xmit_frag = call->conn->max_xmit_frag; 1034 pkt.u.alter_resp.max_recv_frag = call->conn->max_recv_frag; 1035 pkt.u.alter_resp.assoc_group_id = call->conn->assoc_group->id; 841 1036 pkt.u.alter_resp.num_results = 1; 842 pkt.u.alter_resp.ctx_list = talloc_ array(call, struct dcerpc_ack_ctx, 1);1037 pkt.u.alter_resp.ctx_list = talloc_zero(call, struct dcerpc_ack_ctx); 843 1038 if (!pkt.u.alter_resp.ctx_list) { 844 1039 return NT_STATUS_NO_MEMORY; 845 1040 } 846 1041 pkt.u.alter_resp.ctx_list[0].result = result; 847 pkt.u.alter_resp.ctx_list[0].reason = reason;848 pkt.u.alter_resp.ctx_list[0].syntax = ndr_transfer_syntax ;1042 pkt.u.alter_resp.ctx_list[0].reason.value = reason; 1043 pkt.u.alter_resp.ctx_list[0].syntax = ndr_transfer_syntax_ndr; 849 1044 pkt.u.alter_resp.auth_info = data_blob(NULL, 0); 850 1045 pkt.u.alter_resp.secondary_address = ""; … … 852 1047 status = dcesrv_auth_alter_ack(call, &pkt); 853 1048 if (!NT_STATUS_IS_OK(status)) { 854 if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED) 855 || NT_STATUS_EQUAL(status, NT_STATUS_LOGON_FAILURE) 856 || NT_STATUS_EQUAL(status, NT_STATUS_NO_SUCH_USER) 857 || NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) { 858 return dcesrv_fault(call, DCERPC_FAULT_ACCESS_DENIED); 859 } 860 return dcesrv_fault(call, 0); 861 } 862 863 rep = talloc(call, struct data_blob_list_item); 1049 return dcesrv_fault_disconnect(call, DCERPC_FAULT_SEC_PKG_ERROR); 1050 } 1051 1052 rep = talloc_zero(call, struct data_blob_list_item); 864 1053 if (!rep) { 865 1054 return NT_STATUS_NO_MEMORY; 866 1055 } 867 1056 868 status = ncacn_push_auth(&rep->blob, call, &pkt, call-> conn->auth_state.auth_info);1057 status = ncacn_push_auth(&rep->blob, call, &pkt, call->out_auth_info); 869 1058 if (!NT_STATUS_IS_OK(status)) { 870 1059 return status; … … 873 1062 dcerpc_set_frag_length(&rep->blob, rep->blob.length); 874 1063 875 DLIST_ADD_END(call->replies, rep , struct data_blob_list_item *);1064 DLIST_ADD_END(call->replies, rep); 876 1065 dcesrv_call_set_list(call, DCESRV_LIST_CALL_LIST); 877 1066 … … 883 1072 884 1073 return NT_STATUS_OK; 1074 } 1075 1076 /* 1077 handle a alter context request 1078 */ 1079 static NTSTATUS dcesrv_alter(struct dcesrv_call_state *call) 1080 { 1081 NTSTATUS status; 1082 const struct dcerpc_ctx_list *ctx = NULL; 1083 bool auth_ok = false; 1084 1085 if (!call->conn->allow_alter) { 1086 return dcesrv_fault_disconnect(call, DCERPC_NCA_S_PROTO_ERROR); 1087 } 1088 1089 status = dcerpc_verify_ncacn_packet_header(&call->pkt, 1090 DCERPC_PKT_ALTER, 1091 call->pkt.u.alter.auth_info.length, 1092 0, /* required flags */ 1093 DCERPC_PFC_FLAG_FIRST | 1094 DCERPC_PFC_FLAG_LAST | 1095 DCERPC_PFC_FLAG_SUPPORT_HEADER_SIGN | 1096 0x08 | /* this is not defined, but should be ignored */ 1097 DCERPC_PFC_FLAG_CONC_MPX | 1098 DCERPC_PFC_FLAG_DID_NOT_EXECUTE | 1099 DCERPC_PFC_FLAG_MAYBE | 1100 DCERPC_PFC_FLAG_OBJECT_UUID); 1101 if (!NT_STATUS_IS_OK(status)) { 1102 return dcesrv_fault_disconnect(call, DCERPC_NCA_S_PROTO_ERROR); 1103 } 1104 1105 auth_ok = dcesrv_auth_alter(call); 1106 if (!auth_ok) { 1107 if (call->in_auth_info.auth_type == DCERPC_AUTH_TYPE_NONE) { 1108 return dcesrv_fault_disconnect(call, 1109 DCERPC_FAULT_ACCESS_DENIED); 1110 } 1111 } 1112 1113 if (call->pkt.u.alter.num_contexts < 1) { 1114 return dcesrv_fault_disconnect(call, DCERPC_NCA_S_PROTO_ERROR); 1115 } 1116 ctx = &call->pkt.u.alter.ctx_list[0]; 1117 if (ctx->num_transfer_syntaxes < 1) { 1118 return dcesrv_fault_disconnect(call, DCERPC_NCA_S_PROTO_ERROR); 1119 } 1120 1121 /* see if they are asking for a new interface */ 1122 call->context = dcesrv_find_context(call->conn, ctx->context_id); 1123 if (!call->context) { 1124 status = dcesrv_alter_new_context(call, ctx->context_id); 1125 if (!NT_STATUS_IS_OK(status)) { 1126 return dcesrv_alter_resp(call, 1127 DCERPC_BIND_PROVIDER_REJECT, 1128 DCERPC_BIND_REASON_ASYNTAX); 1129 } 1130 } else { 1131 bool ok; 1132 1133 ok = ndr_syntax_id_equal(&ctx->abstract_syntax, 1134 &call->context->iface->syntax_id); 1135 if (!ok) { 1136 return dcesrv_fault_disconnect(call, 1137 DCERPC_NCA_S_PROTO_ERROR); 1138 } 1139 1140 if (ctx->num_transfer_syntaxes != 1) { 1141 return dcesrv_fault_disconnect(call, 1142 DCERPC_NCA_S_PROTO_ERROR); 1143 } 1144 1145 ok = ndr_syntax_id_equal(&ctx->transfer_syntaxes[0], 1146 &ndr_transfer_syntax_ndr); 1147 if (!ok) { 1148 return dcesrv_fault_disconnect(call, 1149 DCERPC_NCA_S_PROTO_ERROR); 1150 } 1151 } 1152 1153 /* handle any authentication that is being requested */ 1154 if (!auth_ok) { 1155 if (call->in_auth_info.auth_type != 1156 call->conn->auth_state.auth_type) 1157 { 1158 return dcesrv_fault_disconnect(call, 1159 DCERPC_FAULT_SEC_PKG_ERROR); 1160 } 1161 return dcesrv_fault_disconnect(call, DCERPC_FAULT_ACCESS_DENIED); 1162 } 1163 1164 return dcesrv_alter_resp(call, 1165 DCERPC_BIND_ACK_RESULT_ACCEPTANCE, 1166 DCERPC_BIND_ACK_REASON_NOT_SPECIFIED); 885 1167 } 886 1168 … … 909 1191 } 910 1192 1193 static NTSTATUS dcesrv_check_verification_trailer(struct dcesrv_call_state *call) 1194 { 1195 TALLOC_CTX *frame = talloc_stackframe(); 1196 const uint32_t bitmask1 = call->conn->auth_state.client_hdr_signing ? 1197 DCERPC_SEC_VT_CLIENT_SUPPORTS_HEADER_SIGNING : 0; 1198 const struct dcerpc_sec_vt_pcontext pcontext = { 1199 .abstract_syntax = call->context->iface->syntax_id, 1200 .transfer_syntax = ndr_transfer_syntax_ndr, 1201 }; 1202 const struct dcerpc_sec_vt_header2 header2 = 1203 dcerpc_sec_vt_header2_from_ncacn_packet(&call->pkt); 1204 enum ndr_err_code ndr_err; 1205 struct dcerpc_sec_verification_trailer *vt = NULL; 1206 NTSTATUS status = NT_STATUS_OK; 1207 bool ok; 1208 1209 SMB_ASSERT(call->pkt.ptype == DCERPC_PKT_REQUEST); 1210 1211 ndr_err = ndr_pop_dcerpc_sec_verification_trailer(call->ndr_pull, 1212 frame, &vt); 1213 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { 1214 status = ndr_map_error2ntstatus(ndr_err); 1215 goto done; 1216 } 1217 1218 ok = dcerpc_sec_verification_trailer_check(vt, &bitmask1, 1219 &pcontext, &header2); 1220 if (!ok) { 1221 status = NT_STATUS_ACCESS_DENIED; 1222 goto done; 1223 } 1224 done: 1225 TALLOC_FREE(frame); 1226 return status; 1227 } 1228 911 1229 /* 912 1230 handle a dcerpc request packet … … 914 1232 static NTSTATUS dcesrv_request(struct dcesrv_call_state *call) 915 1233 { 1234 const struct dcesrv_endpoint *endpoint = call->conn->endpoint; 1235 enum dcerpc_transport_t transport = 1236 dcerpc_binding_get_transport(endpoint->ep_description); 916 1237 struct ndr_pull *pull; 917 1238 NTSTATUS status; 918 1239 struct dcesrv_connection_context *context; 1240 1241 if (!call->conn->allow_request) { 1242 return dcesrv_fault_disconnect(call, DCERPC_NCA_S_PROTO_ERROR); 1243 } 919 1244 920 1245 /* if authenticated, and the mech we use can't do async replies, don't use them... */ … … 929 1254 } 930 1255 1256 switch (call->conn->auth_state.auth_level) { 1257 case DCERPC_AUTH_LEVEL_NONE: 1258 case DCERPC_AUTH_LEVEL_INTEGRITY: 1259 case DCERPC_AUTH_LEVEL_PRIVACY: 1260 break; 1261 default: 1262 if (!context->allow_connect) { 1263 char *addr; 1264 1265 addr = tsocket_address_string(call->conn->remote_address, 1266 call); 1267 1268 DEBUG(2, ("%s: restrict auth_level_connect access " 1269 "to [%s] with auth[type=0x%x,level=0x%x] " 1270 "on [%s] from [%s]\n", 1271 __func__, context->iface->name, 1272 call->conn->auth_state.auth_type, 1273 call->conn->auth_state.auth_level, 1274 derpc_transport_string_by_transport(transport), 1275 addr)); 1276 return dcesrv_fault(call, DCERPC_FAULT_ACCESS_DENIED); 1277 } 1278 break; 1279 } 1280 1281 if (call->conn->auth_state.auth_level < context->min_auth_level) { 1282 char *addr; 1283 1284 addr = tsocket_address_string(call->conn->remote_address, call); 1285 1286 DEBUG(2, ("%s: restrict access by min_auth_level[0x%x] " 1287 "to [%s] with auth[type=0x%x,level=0x%x] " 1288 "on [%s] from [%s]\n", 1289 __func__, 1290 context->min_auth_level, 1291 context->iface->name, 1292 call->conn->auth_state.auth_type, 1293 call->conn->auth_state.auth_level, 1294 derpc_transport_string_by_transport(transport), 1295 addr)); 1296 return dcesrv_fault(call, DCERPC_FAULT_ACCESS_DENIED); 1297 } 1298 931 1299 pull = ndr_pull_init_blob(&call->pkt.u.request.stub_and_verifier, call); 932 1300 NT_STATUS_HAVE_NO_MEMORY(pull); … … 939 1307 if (!(call->pkt.drep[0] & DCERPC_DREP_LE)) { 940 1308 pull->flags |= LIBNDR_FLAG_BIGENDIAN; 1309 } 1310 1311 status = dcesrv_check_verification_trailer(call); 1312 if (!NT_STATUS_IS_OK(status)) { 1313 uint32_t faultcode = DCERPC_FAULT_OTHER; 1314 if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) { 1315 faultcode = DCERPC_FAULT_ACCESS_DENIED; 1316 } 1317 DEBUG(10, ("dcesrv_check_verification_trailer failed: %s\n", 1318 nt_errstr(status))); 1319 return dcesrv_fault(call, faultcode); 941 1320 } 942 1321 … … 1004 1383 process some input to a dcerpc endpoint server. 1005 1384 */ 1006 NTSTATUS dcesrv_process_ncacn_packet(struct dcesrv_connection *dce_conn,1007 1008 1385 static NTSTATUS dcesrv_process_ncacn_packet(struct dcesrv_connection *dce_conn, 1386 struct ncacn_packet *pkt, 1387 DATA_BLOB blob) 1009 1388 { 1010 1389 NTSTATUS status; 1011 1390 struct dcesrv_call_state *call; 1391 struct dcesrv_call_state *existing = NULL; 1012 1392 1013 1393 call = talloc_zero(dce_conn, struct dcesrv_call_state); … … 1030 1410 talloc_set_destructor(call, dcesrv_call_dequeue); 1031 1411 1412 if (call->conn->allow_bind) { 1413 /* 1414 * Only one bind is possible per connection 1415 */ 1416 call->conn->allow_bind = false; 1417 return dcesrv_bind(call); 1418 } 1419 1032 1420 /* we have to check the signing here, before combining the 1033 1421 pdus */ 1034 if (call->pkt.ptype == DCERPC_PKT_REQUEST && 1035 !dcesrv_auth_request(call, &blob)) { 1036 return dcesrv_fault(call, DCERPC_FAULT_ACCESS_DENIED); 1422 if (call->pkt.ptype == DCERPC_PKT_REQUEST) { 1423 if (!call->conn->allow_request) { 1424 return dcesrv_fault_disconnect(call, 1425 DCERPC_NCA_S_PROTO_ERROR); 1426 } 1427 1428 status = dcerpc_verify_ncacn_packet_header(&call->pkt, 1429 DCERPC_PKT_REQUEST, 1430 call->pkt.u.request.stub_and_verifier.length, 1431 0, /* required_flags */ 1432 DCERPC_PFC_FLAG_FIRST | 1433 DCERPC_PFC_FLAG_LAST | 1434 DCERPC_PFC_FLAG_PENDING_CANCEL | 1435 0x08 | /* this is not defined, but should be ignored */ 1436 DCERPC_PFC_FLAG_CONC_MPX | 1437 DCERPC_PFC_FLAG_DID_NOT_EXECUTE | 1438 DCERPC_PFC_FLAG_MAYBE | 1439 DCERPC_PFC_FLAG_OBJECT_UUID); 1440 if (!NT_STATUS_IS_OK(status)) { 1441 return dcesrv_fault_disconnect(call, 1442 DCERPC_NCA_S_PROTO_ERROR); 1443 } 1444 1445 if (call->pkt.frag_length > DCERPC_FRAG_MAX_SIZE) { 1446 /* 1447 * We don't use dcesrv_fault_disconnect() 1448 * here, because we don't want to set 1449 * DCERPC_PFC_FLAG_DID_NOT_EXECUTE 1450 * 1451 * Note that we don't check against the negotiated 1452 * max_recv_frag, but a hard coded value. 1453 */ 1454 dcesrv_call_disconnect_after(call, 1455 "dcesrv_auth_request - frag_length too large"); 1456 return dcesrv_fault(call, 1457 DCERPC_NCA_S_PROTO_ERROR); 1458 } 1459 1460 if (call->pkt.pfc_flags & DCERPC_PFC_FLAG_FIRST) { 1461 /* only one request is possible in the fragmented list */ 1462 if (dce_conn->incoming_fragmented_call_list != NULL) { 1463 TALLOC_FREE(call); 1464 call = dce_conn->incoming_fragmented_call_list; 1465 dcesrv_call_disconnect_after(call, 1466 "dcesrv_auth_request - " 1467 "existing fragmented call"); 1468 return dcesrv_fault(call, 1469 DCERPC_NCA_S_PROTO_ERROR); 1470 } 1471 if (call->pkt.pfc_flags & DCERPC_PFC_FLAG_PENDING_CANCEL) { 1472 return dcesrv_fault_disconnect(call, 1473 DCERPC_FAULT_NO_CALL_ACTIVE); 1474 } 1475 } else { 1476 const struct dcerpc_request *nr = &call->pkt.u.request; 1477 const struct dcerpc_request *er = NULL; 1478 int cmp; 1479 1480 existing = dcesrv_find_fragmented_call(dce_conn, 1481 call->pkt.call_id); 1482 if (existing == NULL) { 1483 dcesrv_call_disconnect_after(call, 1484 "dcesrv_auth_request - " 1485 "no existing fragmented call"); 1486 return dcesrv_fault(call, 1487 DCERPC_NCA_S_PROTO_ERROR); 1488 } 1489 er = &existing->pkt.u.request; 1490 1491 if (call->pkt.ptype != existing->pkt.ptype) { 1492 /* trying to play silly buggers are we? */ 1493 return dcesrv_fault_disconnect(existing, 1494 DCERPC_NCA_S_PROTO_ERROR); 1495 } 1496 cmp = memcmp(call->pkt.drep, existing->pkt.drep, 1497 sizeof(pkt->drep)); 1498 if (cmp != 0) { 1499 return dcesrv_fault_disconnect(existing, 1500 DCERPC_NCA_S_PROTO_ERROR); 1501 } 1502 if (nr->context_id != er->context_id) { 1503 return dcesrv_fault_disconnect(existing, 1504 DCERPC_NCA_S_PROTO_ERROR); 1505 } 1506 if (nr->opnum != er->opnum) { 1507 return dcesrv_fault_disconnect(existing, 1508 DCERPC_NCA_S_PROTO_ERROR); 1509 } 1510 } 1511 1512 if (!dcesrv_auth_request(call, &blob)) { 1513 /* 1514 * We don't use dcesrv_fault_disconnect() 1515 * here, because we don't want to set 1516 * DCERPC_PFC_FLAG_DID_NOT_EXECUTE 1517 */ 1518 dcesrv_call_disconnect_after(call, 1519 "dcesrv_auth_request - failed"); 1520 return dcesrv_fault(call, DCERPC_FAULT_ACCESS_DENIED); 1521 } 1037 1522 } 1038 1523 1039 1524 /* see if this is a continued packet */ 1040 if (call->pkt.ptype == DCERPC_PKT_REQUEST && 1041 !(call->pkt.pfc_flags & DCERPC_PFC_FLAG_FIRST)) { 1042 struct dcesrv_call_state *call2 = call; 1043 uint32_t alloc_size; 1044 1045 /* we only allow fragmented requests, no other packet types */ 1046 if (call->pkt.ptype != DCERPC_PKT_REQUEST) { 1047 return dcesrv_fault(call2, DCERPC_FAULT_OTHER); 1048 } 1049 1050 /* this is a continuation of an existing call - find the call 1051 then tack it on the end */ 1052 call = dcesrv_find_fragmented_call(dce_conn, call2->pkt.call_id); 1053 if (!call) { 1054 return dcesrv_fault(call2, DCERPC_FAULT_OTHER); 1055 } 1056 1057 if (call->pkt.ptype != call2->pkt.ptype) { 1058 /* trying to play silly buggers are we? */ 1059 return dcesrv_fault(call2, DCERPC_FAULT_OTHER); 1060 } 1061 1062 alloc_size = call->pkt.u.request.stub_and_verifier.length + 1063 call2->pkt.u.request.stub_and_verifier.length; 1064 if (call->pkt.u.request.alloc_hint > alloc_size) { 1065 alloc_size = call->pkt.u.request.alloc_hint; 1066 } 1067 1068 call->pkt.u.request.stub_and_verifier.data = 1069 talloc_realloc(call, 1070 call->pkt.u.request.stub_and_verifier.data, 1525 if (existing != NULL) { 1526 struct dcerpc_request *er = &existing->pkt.u.request; 1527 const struct dcerpc_request *nr = &call->pkt.u.request; 1528 size_t available; 1529 size_t alloc_size; 1530 size_t alloc_hint; 1531 1532 /* 1533 * Up to 4 MByte are allowed by all fragments 1534 */ 1535 available = DCERPC_NCACN_PAYLOAD_MAX_SIZE; 1536 if (er->stub_and_verifier.length > available) { 1537 dcesrv_call_disconnect_after(existing, 1538 "dcesrv_auth_request - existing payload too large"); 1539 return dcesrv_fault(existing, DCERPC_FAULT_ACCESS_DENIED); 1540 } 1541 available -= er->stub_and_verifier.length; 1542 if (nr->alloc_hint > available) { 1543 dcesrv_call_disconnect_after(existing, 1544 "dcesrv_auth_request - alloc hint too large"); 1545 return dcesrv_fault(existing, DCERPC_FAULT_ACCESS_DENIED); 1546 } 1547 if (nr->stub_and_verifier.length > available) { 1548 dcesrv_call_disconnect_after(existing, 1549 "dcesrv_auth_request - new payload too large"); 1550 return dcesrv_fault(existing, DCERPC_FAULT_ACCESS_DENIED); 1551 } 1552 alloc_hint = er->stub_and_verifier.length + nr->alloc_hint; 1553 /* allocate at least 1 byte */ 1554 alloc_hint = MAX(alloc_hint, 1); 1555 alloc_size = er->stub_and_verifier.length + 1556 nr->stub_and_verifier.length; 1557 alloc_size = MAX(alloc_size, alloc_hint); 1558 1559 er->stub_and_verifier.data = 1560 talloc_realloc(existing, 1561 er->stub_and_verifier.data, 1071 1562 uint8_t, alloc_size); 1072 if (!call->pkt.u.request.stub_and_verifier.data) { 1073 return dcesrv_fault(call2, DCERPC_FAULT_OTHER); 1074 } 1075 memcpy(call->pkt.u.request.stub_and_verifier.data + 1076 call->pkt.u.request.stub_and_verifier.length, 1077 call2->pkt.u.request.stub_and_verifier.data, 1078 call2->pkt.u.request.stub_and_verifier.length); 1079 call->pkt.u.request.stub_and_verifier.length += 1080 call2->pkt.u.request.stub_and_verifier.length; 1081 1082 call->pkt.pfc_flags |= (call2->pkt.pfc_flags & DCERPC_PFC_FLAG_LAST); 1083 1084 talloc_free(call2); 1563 if (er->stub_and_verifier.data == NULL) { 1564 TALLOC_FREE(call); 1565 return dcesrv_fault_with_flags(existing, 1566 DCERPC_FAULT_OUT_OF_RESOURCES, 1567 DCERPC_PFC_FLAG_DID_NOT_EXECUTE); 1568 } 1569 memcpy(er->stub_and_verifier.data + 1570 er->stub_and_verifier.length, 1571 nr->stub_and_verifier.data, 1572 nr->stub_and_verifier.length); 1573 er->stub_and_verifier.length += nr->stub_and_verifier.length; 1574 1575 existing->pkt.pfc_flags |= (call->pkt.pfc_flags & DCERPC_PFC_FLAG_LAST); 1576 1577 TALLOC_FREE(call); 1578 call = existing; 1085 1579 } 1086 1580 … … 1089 1583 if (call->pkt.ptype == DCERPC_PKT_REQUEST && 1090 1584 !(call->pkt.pfc_flags & DCERPC_PFC_FLAG_LAST)) { 1585 /* 1586 * Up to 4 MByte are allowed by all fragments 1587 */ 1588 if (call->pkt.u.request.alloc_hint > DCERPC_NCACN_PAYLOAD_MAX_SIZE) { 1589 dcesrv_call_disconnect_after(call, 1590 "dcesrv_auth_request - initial alloc hint too large"); 1591 return dcesrv_fault(call, DCERPC_FAULT_ACCESS_DENIED); 1592 } 1091 1593 dcesrv_call_set_list(call, DCESRV_LIST_FRAGMENTED_CALL_LIST); 1092 1594 return NT_STATUS_OK; … … 1098 1600 switch (call->pkt.ptype) { 1099 1601 case DCERPC_PKT_BIND: 1100 status = dcesrv_bind(call); 1602 status = dcesrv_bind_nak(call, 1603 DCERPC_BIND_NAK_REASON_NOT_SPECIFIED); 1101 1604 break; 1102 1605 case DCERPC_PKT_AUTH3: … … 1110 1613 break; 1111 1614 default: 1112 status = NT_STATUS_INVALID_PARAMETER;1615 status = dcesrv_fault_disconnect(call, DCERPC_NCA_S_PROTO_ERROR); 1113 1616 break; 1114 1617 } … … 1137 1640 } 1138 1641 1139 dce_ctx = talloc (mem_ctx, struct dcesrv_context);1642 dce_ctx = talloc_zero(mem_ctx, struct dcesrv_context); 1140 1643 NT_STATUS_HAVE_NO_MEMORY(dce_ctx); 1644 1645 if (uid_wrapper_enabled()) { 1646 setenv("UID_WRAPPER_MYUID", "1", 1); 1647 } 1648 dce_ctx->initial_euid = geteuid(); 1649 if (uid_wrapper_enabled()) { 1650 unsetenv("UID_WRAPPER_MYUID"); 1651 } 1652 1141 1653 dce_ctx->endpoint_list = NULL; 1142 1654 dce_ctx->lp_ctx = lp_ctx; 1143 1655 dce_ctx->assoc_groups_idr = idr_init(dce_ctx); 1144 1656 NT_STATUS_HAVE_NO_MEMORY(dce_ctx->assoc_groups_idr); 1657 dce_ctx->broken_connections = NULL; 1145 1658 1146 1659 for (i=0;endpoint_servers[i];i++) { … … 1236 1749 initialized = true; 1237 1750 1238 shared_init = load_samba_modules(NULL, lp_ctx,"dcerpc_server");1751 shared_init = load_samba_modules(NULL, "dcerpc_server"); 1239 1752 1240 1753 run_init_functions(static_init); … … 1269 1782 static void dcesrv_terminate_connection(struct dcesrv_connection *dce_conn, const char *reason) 1270 1783 { 1784 struct dcesrv_context *dce_ctx = dce_conn->dce_ctx; 1271 1785 struct stream_connection *srv_conn; 1272 1786 srv_conn = talloc_get_type(dce_conn->transport.private_data, 1273 1787 struct stream_connection); 1274 1788 1275 stream_terminate_connection(srv_conn, reason); 1276 } 1789 dce_conn->allow_bind = false; 1790 dce_conn->allow_auth3 = false; 1791 dce_conn->allow_alter = false; 1792 dce_conn->allow_request = false; 1793 1794 if (dce_conn->pending_call_list == NULL) { 1795 char *full_reason = talloc_asprintf(dce_conn, "dcesrv: %s", reason); 1796 1797 DLIST_REMOVE(dce_ctx->broken_connections, dce_conn); 1798 stream_terminate_connection(srv_conn, full_reason ? full_reason : reason); 1799 return; 1800 } 1801 1802 if (dce_conn->terminate != NULL) { 1803 return; 1804 } 1805 1806 DEBUG(3,("dcesrv: terminating connection due to '%s' defered due to pending calls\n", 1807 reason)); 1808 dce_conn->terminate = talloc_strdup(dce_conn, reason); 1809 if (dce_conn->terminate == NULL) { 1810 dce_conn->terminate = "dcesrv: defered terminating connection - no memory"; 1811 } 1812 DLIST_ADD_END(dce_ctx->broken_connections, dce_conn); 1813 } 1814 1815 static void dcesrv_cleanup_broken_connections(struct dcesrv_context *dce_ctx) 1816 { 1817 struct dcesrv_connection *cur, *next; 1818 1819 next = dce_ctx->broken_connections; 1820 while (next != NULL) { 1821 cur = next; 1822 next = cur->next; 1823 1824 if (cur->state_flags & DCESRV_CALL_STATE_FLAG_PROCESS_PENDING_CALL) { 1825 struct dcesrv_connection_context *context_cur, *context_next; 1826 1827 context_next = cur->contexts; 1828 while (context_next != NULL) { 1829 context_cur = context_next; 1830 context_next = context_cur->next; 1831 1832 dcesrv_connection_context_destructor(context_cur); 1833 } 1834 } 1835 1836 dcesrv_terminate_connection(cur, cur->terminate); 1837 } 1838 } 1839 1277 1840 /* We need this include to be able to compile on some plateforms 1278 1841 * (ie. freebsd 7.2) as it seems that <sys/uio.h> is not included … … 1292 1855 1293 1856 static void dcesrv_sock_reply_done(struct tevent_req *subreq); 1857 static void dcesrv_call_terminate_step1(struct tevent_req *subreq); 1294 1858 1295 1859 static void dcesrv_sock_report_output_data(struct dcesrv_connection *dce_conn) … … 1307 1871 struct tevent_req *subreq; 1308 1872 1309 substate = talloc (call, struct dcesrv_sock_reply_state);1873 substate = talloc_zero(call, struct dcesrv_sock_reply_state); 1310 1874 if (!substate) { 1311 1875 dcesrv_terminate_connection(dce_conn, "no memory"); … … 1318 1882 DLIST_REMOVE(call->replies, rep); 1319 1883 1320 if (call->replies == NULL ) {1884 if (call->replies == NULL && call->terminate_reason == NULL) { 1321 1885 substate->call = call; 1322 1886 } … … 1338 1902 } 1339 1903 1904 if (call->terminate_reason != NULL) { 1905 struct tevent_req *subreq; 1906 1907 subreq = tevent_queue_wait_send(call, 1908 dce_conn->event_ctx, 1909 dce_conn->send_queue); 1910 if (!subreq) { 1911 dcesrv_terminate_connection(dce_conn, __location__); 1912 return; 1913 } 1914 tevent_req_set_callback(subreq, dcesrv_call_terminate_step1, 1915 call); 1916 } 1917 1340 1918 DLIST_REMOVE(call->conn->call_list, call); 1341 1919 call->list = DCESRV_LIST_NONE; … … 1354 1932 TALLOC_FREE(subreq); 1355 1933 if (ret == -1) { 1356 status = map_nt_error_from_unix (sys_errno);1934 status = map_nt_error_from_unix_common(sys_errno); 1357 1935 dcesrv_terminate_connection(substate->dce_conn, nt_errstr(status)); 1358 1936 return; … … 1365 1943 } 1366 1944 1367 1368 1945 static void dcesrv_call_terminate_step2(struct tevent_req *subreq); 1946 1947 static void dcesrv_call_terminate_step1(struct tevent_req *subreq) 1948 { 1949 struct dcesrv_call_state *call = tevent_req_callback_data(subreq, 1950 struct dcesrv_call_state); 1951 bool ok; 1952 struct timeval tv; 1953 1954 /* make sure we stop send queue before removing subreq */ 1955 tevent_queue_stop(call->conn->send_queue); 1956 1957 ok = tevent_queue_wait_recv(subreq); 1958 TALLOC_FREE(subreq); 1959 if (!ok) { 1960 dcesrv_terminate_connection(call->conn, __location__); 1961 return; 1962 } 1963 1964 /* disconnect after 200 usecs */ 1965 tv = timeval_current_ofs_usec(200); 1966 subreq = tevent_wakeup_send(call, call->conn->event_ctx, tv); 1967 if (subreq == NULL) { 1968 dcesrv_terminate_connection(call->conn, __location__); 1969 return; 1970 } 1971 tevent_req_set_callback(subreq, dcesrv_call_terminate_step2, 1972 call); 1973 } 1974 1975 static void dcesrv_call_terminate_step2(struct tevent_req *subreq) 1976 { 1977 struct dcesrv_call_state *call = tevent_req_callback_data(subreq, 1978 struct dcesrv_call_state); 1979 bool ok; 1980 1981 ok = tevent_wakeup_recv(subreq); 1982 TALLOC_FREE(subreq); 1983 if (!ok) { 1984 dcesrv_terminate_connection(call->conn, __location__); 1985 return; 1986 } 1987 1988 dcesrv_terminate_connection(call->conn, call->terminate_reason); 1989 } 1369 1990 1370 1991 struct dcesrv_socket_context { … … 1381 2002 struct dcesrv_socket_context *dcesrv_sock = 1382 2003 talloc_get_type(srv_conn->private_data, struct dcesrv_socket_context); 2004 enum dcerpc_transport_t transport = 2005 dcerpc_binding_get_transport(dcesrv_sock->endpoint->ep_description); 1383 2006 struct dcesrv_connection *dcesrv_conn = NULL; 1384 2007 int ret; 1385 2008 struct tevent_req *subreq; 1386 2009 struct loadparm_context *lp_ctx = dcesrv_sock->dcesrv_ctx->lp_ctx; 2010 2011 dcesrv_cleanup_broken_connections(dcesrv_sock->dcesrv_ctx); 1387 2012 1388 2013 if (!srv_conn->session_info) { … … 1428 2053 } 1429 2054 1430 if ( dcesrv_sock->endpoint->ep_description->transport == NCACN_NP) {2055 if (transport == NCACN_NP) { 1431 2056 dcesrv_conn->auth_state.session_key = dcesrv_inherited_session_key; 1432 2057 dcesrv_conn->stream = talloc_move(dcesrv_conn, … … 1437 2062 &dcesrv_conn->stream); 1438 2063 if (ret == -1) { 1439 status = map_nt_error_from_unix (errno);2064 status = map_nt_error_from_unix_common(errno); 1440 2065 DEBUG(0, ("dcesrv_sock_accept: " 1441 2066 "failed to setup tstream: %s\n", … … 1449 2074 dcesrv_conn->local_address = srv_conn->local_address; 1450 2075 dcesrv_conn->remote_address = srv_conn->remote_address; 2076 2077 if (transport == NCALRPC) { 2078 uid_t uid; 2079 gid_t gid; 2080 2081 ret = getpeereid(socket_get_fd(srv_conn->socket), &uid, &gid); 2082 if (ret == -1) { 2083 status = map_nt_error_from_unix_common(errno); 2084 DEBUG(0, ("dcesrv_sock_accept: " 2085 "getpeereid() failed for NCALRPC: %s\n", 2086 nt_errstr(status))); 2087 stream_terminate_connection(srv_conn, nt_errstr(status)); 2088 return; 2089 } 2090 if (uid == dcesrv_conn->dce_ctx->initial_euid) { 2091 struct tsocket_address *r = NULL; 2092 2093 ret = tsocket_address_unix_from_path(dcesrv_conn, 2094 "/root/ncalrpc_as_system", 2095 &r); 2096 if (ret == -1) { 2097 status = map_nt_error_from_unix_common(errno); 2098 DEBUG(0, ("dcesrv_sock_accept: " 2099 "tsocket_address_unix_from_path() failed for NCALRPC: %s\n", 2100 nt_errstr(status))); 2101 stream_terminate_connection(srv_conn, nt_errstr(status)); 2102 return; 2103 } 2104 dcesrv_conn->remote_address = r; 2105 } 2106 } 1451 2107 1452 2108 srv_conn->private_data = dcesrv_conn; … … 1473 2129 struct dcesrv_connection *dce_conn = tevent_req_callback_data(subreq, 1474 2130 struct dcesrv_connection); 2131 struct dcesrv_context *dce_ctx = dce_conn->dce_ctx; 1475 2132 struct ncacn_packet *pkt; 1476 2133 DATA_BLOB buffer; 1477 2134 NTSTATUS status; 2135 2136 if (dce_conn->terminate) { 2137 /* 2138 * if the current connection is broken 2139 * we need to clean it up before any other connection 2140 */ 2141 dcesrv_terminate_connection(dce_conn, dce_conn->terminate); 2142 dcesrv_cleanup_broken_connections(dce_ctx); 2143 return; 2144 } 2145 2146 dcesrv_cleanup_broken_connections(dce_ctx); 1478 2147 1479 2148 status = dcerpc_read_ncacn_packet_recv(subreq, dce_conn, … … 1532 2201 uint16_t port = 1; 1533 2202 NTSTATUS status; 1534 1535 dcesrv_sock = talloc(event_ctx, struct dcesrv_socket_context); 2203 const char *endpoint; 2204 2205 dcesrv_sock = talloc_zero(event_ctx, struct dcesrv_socket_context); 1536 2206 NT_STATUS_HAVE_NO_MEMORY(dcesrv_sock); 1537 2207 … … 1540 2210 dcesrv_sock->dcesrv_ctx = talloc_reference(dcesrv_sock, dce_ctx); 1541 2211 2212 endpoint = dcerpc_binding_get_string_option(e->ep_description, "endpoint"); 2213 1542 2214 status = stream_setup_socket(dcesrv_sock, event_ctx, lp_ctx, 1543 2215 model_ops, &dcesrv_stream_ops, 1544 "unix", e ->ep_description->endpoint, &port,2216 "unix", endpoint, &port, 1545 2217 lpcfg_socket_options(lp_ctx), 1546 2218 dcesrv_sock); 1547 2219 if (!NT_STATUS_IS_OK(status)) { 1548 2220 DEBUG(0,("service_setup_stream_socket(path=%s) failed - %s\n", 1549 e ->ep_description->endpoint, nt_errstr(status)));2221 endpoint, nt_errstr(status))); 1550 2222 } 1551 2223 … … 1562 2234 char *full_path; 1563 2235 NTSTATUS status; 1564 1565 if (!e->ep_description->endpoint) { 1566 /* No identifier specified: use DEFAULT. 1567 * DO NOT hardcode this value anywhere else. Rather, specify 1568 * no endpoint and let the epmapper worry about it. */ 1569 e->ep_description->endpoint = talloc_strdup(dce_ctx, "DEFAULT"); 2236 const char *endpoint; 2237 2238 endpoint = dcerpc_binding_get_string_option(e->ep_description, "endpoint"); 2239 2240 if (endpoint == NULL) { 2241 /* 2242 * No identifier specified: use DEFAULT. 2243 * 2244 * TODO: DO NOT hardcode this value anywhere else. Rather, specify 2245 * no endpoint and let the epmapper worry about it. 2246 */ 2247 endpoint = "DEFAULT"; 2248 status = dcerpc_binding_set_string_option(e->ep_description, 2249 "endpoint", 2250 endpoint); 2251 if (!NT_STATUS_IS_OK(status)) { 2252 DEBUG(0,("dcerpc_binding_set_string_option() failed - %s\n", 2253 nt_errstr(status))); 2254 return status; 2255 } 1570 2256 } 1571 2257 1572 2258 full_path = talloc_asprintf(dce_ctx, "%s/%s", lpcfg_ncalrpc_dir(lp_ctx), 1573 e ->ep_description->endpoint);1574 1575 dcesrv_sock = talloc (event_ctx, struct dcesrv_socket_context);2259 endpoint); 2260 2261 dcesrv_sock = talloc_zero(event_ctx, struct dcesrv_socket_context); 1576 2262 NT_STATUS_HAVE_NO_MEMORY(dcesrv_sock); 1577 2263 … … 1587 2273 if (!NT_STATUS_IS_OK(status)) { 1588 2274 DEBUG(0,("service_setup_stream_socket(identifier=%s,path=%s) failed - %s\n", 1589 e ->ep_description->endpoint, full_path, nt_errstr(status)));2275 endpoint, full_path, nt_errstr(status))); 1590 2276 } 1591 2277 return status; … … 1599 2285 struct dcesrv_socket_context *dcesrv_sock; 1600 2286 NTSTATUS status; 1601 1602 if (e->ep_description->endpoint == NULL) { 2287 const char *endpoint; 2288 2289 endpoint = dcerpc_binding_get_string_option(e->ep_description, "endpoint"); 2290 if (endpoint == NULL) { 1603 2291 DEBUG(0, ("Endpoint mandatory for named pipes\n")); 1604 2292 return NT_STATUS_INVALID_PARAMETER; 1605 2293 } 1606 2294 1607 dcesrv_sock = talloc (event_ctx, struct dcesrv_socket_context);2295 dcesrv_sock = talloc_zero(event_ctx, struct dcesrv_socket_context); 1608 2296 NT_STATUS_HAVE_NO_MEMORY(dcesrv_sock); 1609 2297 … … 1614 2302 status = tstream_setup_named_pipe(dce_ctx, event_ctx, lp_ctx, 1615 2303 model_ops, &dcesrv_stream_ops, 1616 e ->ep_description->endpoint,2304 endpoint, 1617 2305 dcesrv_sock); 1618 2306 if (!NT_STATUS_IS_OK(status)) { 1619 2307 DEBUG(0,("stream_setup_named_pipe(pipe=%s) failed - %s\n", 1620 e ->ep_description->endpoint, nt_errstr(status)));2308 endpoint, nt_errstr(status))); 1621 2309 return status; 1622 2310 } … … 1635 2323 uint16_t port = 0; 1636 2324 NTSTATUS status; 1637 1638 if (e->ep_description->endpoint) { 1639 port = atoi(e->ep_description->endpoint); 1640 } 1641 1642 dcesrv_sock = talloc(event_ctx, struct dcesrv_socket_context); 2325 const char *endpoint; 2326 char port_str[6]; 2327 2328 endpoint = dcerpc_binding_get_string_option(e->ep_description, "endpoint"); 2329 if (endpoint != NULL) { 2330 port = atoi(endpoint); 2331 } 2332 2333 dcesrv_sock = talloc_zero(event_ctx, struct dcesrv_socket_context); 1643 2334 NT_STATUS_HAVE_NO_MEMORY(dcesrv_sock); 1644 2335 … … 1649 2340 status = stream_setup_socket(dcesrv_sock, event_ctx, dce_ctx->lp_ctx, 1650 2341 model_ops, &dcesrv_stream_ops, 1651 "ip v4", address, &port,2342 "ip", address, &port, 1652 2343 lpcfg_socket_options(dce_ctx->lp_ctx), 1653 2344 dcesrv_sock); … … 1655 2346 DEBUG(0,("service_setup_stream_socket(address=%s,port=%u) failed - %s\n", 1656 2347 address, port, nt_errstr(status))); 1657 } 1658 1659 if (e->ep_description->endpoint == NULL) { 1660 e->ep_description->endpoint = talloc_asprintf(dce_ctx, "%d", port); 1661 } 1662 1663 return status; 2348 return status; 2349 } 2350 2351 snprintf(port_str, sizeof(port_str), "%u", port); 2352 2353 status = dcerpc_binding_set_string_option(e->ep_description, 2354 "endpoint", port_str); 2355 if (!NT_STATUS_IS_OK(status)) { 2356 DEBUG(0,("dcerpc_binding_set_string_option(endpoint, %s) failed - %s\n", 2357 port_str, nt_errstr(status))); 2358 return status; 2359 } 2360 2361 return NT_STATUS_OK; 1664 2362 } 1665 2363 … … 1679 2377 struct interface *ifaces; 1680 2378 1681 load_interface s(dce_ctx, lpcfg_interfaces(lp_ctx), &ifaces);1682 1683 num_interfaces = iface_ count(ifaces);2379 load_interface_list(dce_ctx, lp_ctx, &ifaces); 2380 2381 num_interfaces = iface_list_count(ifaces); 1684 2382 for(i = 0; i < num_interfaces; i++) { 1685 const char *address = iface_ n_ip(ifaces, i);2383 const char *address = iface_list_n_ip(ifaces, i); 1686 2384 status = add_socket_rpc_tcp_iface(dce_ctx, e, event_ctx, model_ops, address); 1687 2385 NT_STATUS_NOT_OK_RETURN(status); 1688 2386 } 1689 2387 } else { 1690 status = add_socket_rpc_tcp_iface(dce_ctx, e, event_ctx, model_ops, 1691 lpcfg_socket_address(lp_ctx)); 1692 NT_STATUS_NOT_OK_RETURN(status); 2388 char **wcard; 2389 int i; 2390 int num_binds = 0; 2391 wcard = iface_list_wildcard(dce_ctx); 2392 NT_STATUS_HAVE_NO_MEMORY(wcard); 2393 for (i=0; wcard[i]; i++) { 2394 status = add_socket_rpc_tcp_iface(dce_ctx, e, event_ctx, model_ops, wcard[i]); 2395 if (NT_STATUS_IS_OK(status)) { 2396 num_binds++; 2397 } 2398 } 2399 talloc_free(wcard); 2400 if (num_binds == 0) { 2401 return NT_STATUS_INVALID_PARAMETER_MIX; 2402 } 1693 2403 } 1694 2404 … … 1702 2412 const struct model_ops *model_ops) 1703 2413 { 1704 switch (e->ep_description->transport) { 2414 enum dcerpc_transport_t transport = 2415 dcerpc_binding_get_transport(e->ep_description); 2416 2417 switch (transport) { 1705 2418 case NCACN_UNIX_STREAM: 1706 2419 return dcesrv_add_ep_unix(dce_ctx, lp_ctx, e, event_ctx, model_ops); -
vendor/current/source4/rpc_server/dcerpc_server.h
r740 r988 24 24 #define SAMBA_DCERPC_SERVER_H 25 25 26 #include "librpc/gen_ndr/server_id 4.h"26 #include "librpc/gen_ndr/server_id.h" 27 27 #include "librpc/rpc/dcerpc.h" 28 28 #include "librpc/ndr/libndr.h" … … 102 102 #define DCESRV_CALL_STATE_FLAG_ASYNC (1<<0) 103 103 #define DCESRV_CALL_STATE_FLAG_MAY_ASYNC (1<<1) 104 #define DCESRV_CALL_STATE_FLAG_HEADER_SIGNING (1<<2) 104 #define DCESRV_CALL_STATE_FLAG_MULTIPLEXED (1<<3) 105 #define DCESRV_CALL_STATE_FLAG_PROCESS_PENDING_CALL (1<<4) 105 106 uint32_t state_flags; 106 107 … … 112 113 113 114 /* the message_context that will be used for async replies */ 114 struct messaging_context *msg_ctx;115 struct imessaging_context *msg_ctx; 115 116 116 117 /* this is the pointer to the allocated function struct */ … … 130 131 /* this is used by the boilerplate code to generate DCERPC faults */ 131 132 uint32_t fault_code; 133 134 /* the reason why we terminate the connection after sending a response */ 135 const char *terminate_reason; 136 137 /* temporary auth_info fields */ 138 struct dcerpc_auth in_auth_info; 139 struct dcerpc_auth _out_auth_info; 140 struct dcerpc_auth *out_auth_info; 132 141 }; 133 142 … … 146 155 /* hold the authentication state information */ 147 156 struct dcesrv_auth { 148 struct dcerpc_auth *auth_info; 157 enum dcerpc_AuthType auth_type; 158 enum dcerpc_AuthLevel auth_level; 159 uint32_t auth_context_id; 149 160 struct gensec_security *gensec_security; 150 161 struct auth_session_info *session_info; 151 162 NTSTATUS (*session_key)(struct dcesrv_connection *, DATA_BLOB *session_key); 163 bool client_hdr_signing; 164 bool hdr_signing; 165 bool auth_finished; 166 bool auth_invalid; 152 167 }; 153 168 … … 156 171 uint32_t context_id; 157 172 173 /* TODO: remove this legacy (for openchange) in master */ 158 174 struct dcesrv_assoc_group *assoc_group; 159 175 … … 166 182 /* private data for the interface implementation */ 167 183 void *private_data; 184 185 /* 186 * the minimum required auth level for this interface 187 */ 188 enum dcerpc_AuthLevel min_auth_level; 189 bool allow_connect; 168 190 }; 169 191 … … 171 193 /* the state associated with a dcerpc server connection */ 172 194 struct dcesrv_connection { 195 /* for the broken_connections DLIST */ 196 struct dcesrv_connection *prev, *next; 197 173 198 /* the top level context for this server */ 174 199 struct dcesrv_context *dce_ctx; … … 190 215 191 216 /* the maximum size the client wants to receive */ 192 uint32_t cli_max_recv_frag; 217 uint16_t max_recv_frag; 218 uint16_t max_xmit_frag; 193 219 194 220 DATA_BLOB partial_input; 195 221 196 /* the current authentication state */ 197 struct dcesrv_auth auth_state; 222 /* This can be removed in master... */ 223 struct { 224 struct dcerpc_auth *auth_info; 225 struct gensec_security *gensec_security; 226 struct auth_session_info *session_info; 227 NTSTATUS (*session_key)(struct dcesrv_connection *, DATA_BLOB *session_key); 228 bool client_hdr_signing; 229 bool hdr_signing; 230 } _unused_auth_state; 198 231 199 232 /* the event_context that will be used for this connection */ … … 201 234 202 235 /* the message_context that will be used for this connection */ 203 struct messaging_context *msg_ctx;236 struct imessaging_context *msg_ctx; 204 237 205 238 /* the server_id that will be used for this connection */ … … 209 242 DATA_BLOB transport_session_key; 210 243 211 bool processing; 244 /* is this connection pending termination? If so, why? */ 245 const char *terminate; 212 246 213 247 const char *packet_log_dir; … … 226 260 const struct tsocket_address *local_address; 227 261 const struct tsocket_address *remote_address; 262 263 /* the current authentication state */ 264 struct dcesrv_auth auth_state; 265 266 /* 267 * remember which pdu types are allowed 268 */ 269 bool allow_bind; 270 bool allow_auth3; 271 bool allow_alter; 272 bool allow_request; 273 274 /* the association group the connection belongs to */ 275 struct dcesrv_assoc_group *assoc_group; 228 276 }; 229 277 … … 269 317 /* server-wide context information for the dcerpc server */ 270 318 struct dcesrv_context { 319 /* 320 * The euid at startup time. 321 * 322 * This is required for DCERPC_AUTH_TYPE_NCALRPC_AS_SYSTEM 323 */ 324 uid_t initial_euid; 325 271 326 /* the list of endpoints that have registered 272 327 * by the configured endpoint servers … … 289 344 290 345 struct idr_context *assoc_groups_idr; 346 347 struct dcesrv_connection *broken_connections; 291 348 }; 292 349 … … 320 377 struct auth_session_info *session_info, 321 378 struct tevent_context *event_ctx, 322 struct messaging_context *msg_ctx,379 struct imessaging_context *msg_ctx, 323 380 struct server_id server_id, 324 381 uint32_t state_flags, … … 399 456 _PUBLIC_ const char *dcesrv_call_account_name(struct dcesrv_call_state *dce_call); 400 457 458 _PUBLIC_ NTSTATUS dcesrv_interface_bind_require_integrity(struct dcesrv_call_state *dce_call, 459 const struct dcesrv_interface *iface); 460 _PUBLIC_ NTSTATUS dcesrv_interface_bind_require_privacy(struct dcesrv_call_state *dce_call, 461 const struct dcesrv_interface *iface); 462 _PUBLIC_ NTSTATUS dcesrv_interface_bind_reject_connect(struct dcesrv_call_state *dce_call, 463 const struct dcesrv_interface *iface); 464 _PUBLIC_ NTSTATUS dcesrv_interface_bind_allow_connect(struct dcesrv_call_state *dce_call, 465 const struct dcesrv_interface *iface); 401 466 402 467 #endif /* SAMBA_DCERPC_SERVER_H */ -
vendor/current/source4/rpc_server/dcerpc_server.pc.in
r740 r988 3 3 libdir=@libdir@ 4 4 includedir=@includedir@ 5 modulesdir=@modulesdir@/dcerpc_server 5 6 6 7 Name: dcerpc_server -
vendor/current/source4/rpc_server/dcesrv_auth.c
r919 r988 40 40 bool dcesrv_auth_bind(struct dcesrv_call_state *call) 41 41 { 42 struct cli_credentials *server_credentials ;42 struct cli_credentials *server_credentials = NULL; 43 43 struct ncacn_packet *pkt = &call->pkt; 44 44 struct dcesrv_connection *dce_conn = call->conn; … … 48 48 49 49 if (pkt->auth_length == 0) { 50 dce_conn->auth_state.auth_info = NULL; 50 auth->auth_type = DCERPC_AUTH_TYPE_NONE; 51 auth->auth_level = DCERPC_AUTH_LEVEL_NONE; 52 auth->auth_context_id = 0; 51 53 return true; 52 54 } 53 55 54 dce_conn->auth_state.auth_info = talloc(dce_conn, struct dcerpc_auth);55 if (!dce_conn->auth_state.auth_info) {56 return false;57 }58 59 56 status = dcerpc_pull_auth_trailer(pkt, call, &pkt->u.bind.auth_info, 60 dce_conn->auth_state.auth_info,57 &call->in_auth_info, 61 58 &auth_length, false); 59 if (!NT_STATUS_IS_OK(status)) { 60 return false; 61 } 62 63 switch (call->in_auth_info.auth_level) { 64 case DCERPC_AUTH_LEVEL_CONNECT: 65 case DCERPC_AUTH_LEVEL_CALL: 66 case DCERPC_AUTH_LEVEL_PACKET: 67 case DCERPC_AUTH_LEVEL_INTEGRITY: 68 case DCERPC_AUTH_LEVEL_PRIVACY: 69 /* 70 * We evaluate auth_type only if auth_level was valid 71 */ 72 break; 73 default: 74 /* 75 * Setting DCERPC_AUTH_LEVEL_NONE, 76 * gives the caller a chance to decide what 77 * reject_reason to use 78 * 79 * Note: DCERPC_AUTH_LEVEL_NONE == 1 80 */ 81 auth->auth_type = DCERPC_AUTH_TYPE_NONE; 82 auth->auth_level = DCERPC_AUTH_LEVEL_NONE; 83 auth->auth_context_id = 0; 84 return false; 85 } 86 87 auth->auth_type = call->in_auth_info.auth_type; 88 auth->auth_level = call->in_auth_info.auth_level; 89 auth->auth_context_id = call->in_auth_info.auth_context_id; 90 62 91 server_credentials 63 92 = cli_credentials_init(call); … … 70 99 status = cli_credentials_set_machine_account(server_credentials, call->conn->dce_ctx->lp_ctx); 71 100 if (!NT_STATUS_IS_OK(status)) { 72 DEBUG(1 0, ("Failed to obtain server credentials, perhaps a standalone server?: %s\n", nt_errstr(status)));73 talloc_free(server_credentials);74 server_credentials = NULL;101 DEBUG(1, ("Failed to obtain server credentials: %s\n", 102 nt_errstr(status))); 103 return false; 75 104 } 76 105 … … 81 110 NULL, 82 111 &auth->gensec_security); 83 84 status = gensec_start_mech_by_authtype(auth->gensec_security, auth->auth_info->auth_type, 85 auth->auth_info->auth_level); 86 112 if (!NT_STATUS_IS_OK(status)) { 113 DEBUG(1, ("Failed to call samba_server_gensec_start %s\n", 114 nt_errstr(status))); 115 return false; 116 } 117 118 if (call->conn->remote_address != NULL) { 119 status = gensec_set_remote_address(auth->gensec_security, 120 call->conn->remote_address); 121 if (!NT_STATUS_IS_OK(status)) { 122 DEBUG(1, ("Failed to call gensec_set_remote_address() %s\n", 123 nt_errstr(status))); 124 return false; 125 } 126 } 127 128 status = gensec_start_mech_by_authtype(auth->gensec_security, auth->auth_type, 129 auth->auth_level); 87 130 if (!NT_STATUS_IS_OK(status)) { 88 131 DEBUG(3, ("Failed to start GENSEC mechanism for DCERPC server: auth_type=%d, auth_level=%d: %s\n", 89 (int)auth->auth_ info->auth_type,90 (int)auth->auth_ info->auth_level,132 (int)auth->auth_type, 133 (int)auth->auth_level, 91 134 nt_errstr(status))); 92 135 return false; 93 }94 95 if (call->conn->state_flags & DCESRV_CALL_STATE_FLAG_HEADER_SIGNING) {96 gensec_want_feature(auth->gensec_security, GENSEC_FEATURE_SIGN_PKT_HEADER);97 136 } 98 137 … … 108 147 struct dcesrv_connection *dce_conn = call->conn; 109 148 NTSTATUS status; 149 bool want_header_signing = false; 150 151 dce_conn->allow_alter = true; 152 dce_conn->allow_auth3 = true; 110 153 111 154 if (call->pkt.auth_length == 0) { 155 dce_conn->auth_state.auth_finished = true; 156 dce_conn->allow_request = true; 112 157 return NT_STATUS_OK; 113 158 } 114 159 115 status = gensec_update(dce_conn->auth_state.gensec_security, 116 call, 117 dce_conn->auth_state.auth_info->credentials, 118 &dce_conn->auth_state.auth_info->credentials); 160 /* We can't work without an existing gensec state */ 161 if (!call->conn->auth_state.gensec_security) { 162 return NT_STATUS_INTERNAL_ERROR; 163 } 164 165 if (call->pkt.pfc_flags & DCERPC_PFC_FLAG_SUPPORT_HEADER_SIGN) { 166 dce_conn->auth_state.client_hdr_signing = true; 167 want_header_signing = true; 168 } 169 170 if (!lpcfg_parm_bool(call->conn->dce_ctx->lp_ctx, NULL, "dcesrv","header signing", true)) { 171 want_header_signing = false; 172 } 173 174 call->_out_auth_info = (struct dcerpc_auth) { 175 .auth_type = dce_conn->auth_state.auth_type, 176 .auth_level = dce_conn->auth_state.auth_level, 177 .auth_context_id = dce_conn->auth_state.auth_context_id, 178 }; 179 call->out_auth_info = &call->_out_auth_info; 180 181 status = gensec_update_ev(dce_conn->auth_state.gensec_security, 182 call, call->event_ctx, 183 call->in_auth_info.credentials, 184 &call->out_auth_info->credentials); 119 185 120 186 if (NT_STATUS_IS_OK(status)) { 121 187 status = gensec_session_info(dce_conn->auth_state.gensec_security, 188 dce_conn, 122 189 &dce_conn->auth_state.session_info); 123 190 if (!NT_STATUS_IS_OK(status)) { … … 125 192 return status; 126 193 } 127 128 if (dce_conn->state_flags & DCESRV_CALL_STATE_FLAG_HEADER_SIGNING) { 194 dce_conn->auth_state.auth_finished = true; 195 dce_conn->allow_request = true; 196 197 if (!gensec_have_feature(dce_conn->auth_state.gensec_security, 198 GENSEC_FEATURE_SIGN_PKT_HEADER)) 199 { 200 want_header_signing = false; 201 } 202 203 if (want_header_signing) { 129 204 gensec_want_feature(dce_conn->auth_state.gensec_security, 130 205 GENSEC_FEATURE_SIGN_PKT_HEADER); 206 dce_conn->auth_state.hdr_signing = true; 207 pkt->pfc_flags |= DCERPC_PFC_FLAG_SUPPORT_HEADER_SIGN; 131 208 } 132 209 … … 135 212 return NT_STATUS_OK; 136 213 } else if (NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) { 137 dce_conn->auth_state.auth_info->auth_pad_length = 0; 138 dce_conn->auth_state.auth_info->auth_reserved = 0; 214 if (!gensec_have_feature(dce_conn->auth_state.gensec_security, 215 GENSEC_FEATURE_SIGN_PKT_HEADER)) 216 { 217 want_header_signing = false; 218 } 219 220 if (want_header_signing) { 221 gensec_want_feature(dce_conn->auth_state.gensec_security, 222 GENSEC_FEATURE_SIGN_PKT_HEADER); 223 dce_conn->auth_state.hdr_signing = true; 224 pkt->pfc_flags |= DCERPC_PFC_FLAG_SUPPORT_HEADER_SIGN; 225 } 226 139 227 return NT_STATUS_OK; 140 228 } else { … … 160 248 } 161 249 162 if ( !dce_conn->auth_state.auth_info) {250 if (dce_conn->auth_state.auth_finished) { 163 251 return false; 164 252 } … … 170 258 171 259 status = dcerpc_pull_auth_trailer(pkt, call, &pkt->u.auth3.auth_info, 172 dce_conn->auth_state.auth_info, &auth_length, true); 173 if (!NT_STATUS_IS_OK(status)) { 174 return false; 175 } 260 &call->in_auth_info, &auth_length, true); 261 if (!NT_STATUS_IS_OK(status)) { 262 return false; 263 } 264 265 if (call->in_auth_info.auth_type != dce_conn->auth_state.auth_type) { 266 return false; 267 } 268 269 if (call->in_auth_info.auth_level != dce_conn->auth_state.auth_level) { 270 return false; 271 } 272 273 if (call->in_auth_info.auth_context_id != dce_conn->auth_state.auth_context_id) { 274 return false; 275 } 276 277 call->_out_auth_info = (struct dcerpc_auth) { 278 .auth_type = dce_conn->auth_state.auth_type, 279 .auth_level = dce_conn->auth_state.auth_level, 280 .auth_context_id = dce_conn->auth_state.auth_context_id, 281 }; 282 call->out_auth_info = &call->_out_auth_info; 176 283 177 284 /* Pass the extra data we got from the client down to gensec for processing */ 178 status = gensec_update (dce_conn->auth_state.gensec_security,179 call, 180 dce_conn->auth_state.auth_info->credentials,181 & dce_conn->auth_state.auth_info->credentials);285 status = gensec_update_ev(dce_conn->auth_state.gensec_security, 286 call, call->event_ctx, 287 call->in_auth_info.credentials, 288 &call->out_auth_info->credentials); 182 289 if (NT_STATUS_IS_OK(status)) { 183 290 status = gensec_session_info(dce_conn->auth_state.gensec_security, 291 dce_conn, 184 292 &dce_conn->auth_state.session_info); 185 293 if (!NT_STATUS_IS_OK(status)) { … … 187 295 return false; 188 296 } 297 dce_conn->auth_state.auth_finished = true; 298 dce_conn->allow_request = true; 299 189 300 /* Now that we are authenticated, go back to the generic session key... */ 190 301 dce_conn->auth_state.session_key = dcesrv_generic_session_key; 302 303 if (call->out_auth_info->credentials.length != 0) { 304 305 DEBUG(4, ("GENSEC produced output token (len=%u) at bind_auth3\n", 306 (unsigned)call->out_auth_info->credentials.length)); 307 return false; 308 } 191 309 return true; 192 310 } else { … … 211 329 /* on a pure interface change there is no auth blob */ 212 330 if (pkt->auth_length == 0) { 331 if (!dce_conn->auth_state.auth_finished) { 332 return false; 333 } 213 334 return true; 335 } 336 337 if (dce_conn->auth_state.auth_finished) { 338 return false; 214 339 } 215 340 … … 219 344 } 220 345 221 dce_conn->auth_state.auth_info = talloc(dce_conn, struct dcerpc_auth);222 if (!dce_conn->auth_state.auth_info) {223 return false;224 }225 226 346 status = dcerpc_pull_auth_trailer(pkt, call, &pkt->u.alter.auth_info, 227 dce_conn->auth_state.auth_info, 228 &auth_length, true); 229 if (!NT_STATUS_IS_OK(status)) { 347 &call->in_auth_info, &auth_length, true); 348 if (!NT_STATUS_IS_OK(status)) { 349 return false; 350 } 351 352 if (call->in_auth_info.auth_type != dce_conn->auth_state.auth_type) { 353 return false; 354 } 355 356 if (call->in_auth_info.auth_level != dce_conn->auth_state.auth_level) { 357 return false; 358 } 359 360 if (call->in_auth_info.auth_context_id != dce_conn->auth_state.auth_context_id) { 230 361 return false; 231 362 } … … 250 381 251 382 if (!call->conn->auth_state.gensec_security) { 252 return NT_STATUS_INVALID_PARAMETER; 253 } 254 255 status = gensec_update(dce_conn->auth_state.gensec_security, 256 call, 257 dce_conn->auth_state.auth_info->credentials, 258 &dce_conn->auth_state.auth_info->credentials); 383 return NT_STATUS_INTERNAL_ERROR; 384 } 385 386 call->_out_auth_info = (struct dcerpc_auth) { 387 .auth_type = dce_conn->auth_state.auth_type, 388 .auth_level = dce_conn->auth_state.auth_level, 389 .auth_context_id = dce_conn->auth_state.auth_context_id, 390 }; 391 call->out_auth_info = &call->_out_auth_info; 392 393 status = gensec_update_ev(dce_conn->auth_state.gensec_security, 394 call, call->event_ctx, 395 call->in_auth_info.credentials, 396 &call->out_auth_info->credentials); 259 397 260 398 if (NT_STATUS_IS_OK(status)) { 261 399 status = gensec_session_info(dce_conn->auth_state.gensec_security, 400 dce_conn, 262 401 &dce_conn->auth_state.session_info); 263 402 if (!NT_STATUS_IS_OK(status)) { … … 265 404 return status; 266 405 } 406 dce_conn->auth_state.auth_finished = true; 407 dce_conn->allow_request = true; 267 408 268 409 /* Now that we are authenticated, got back to the generic session key... */ … … 270 411 return NT_STATUS_OK; 271 412 } else if (NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) { 272 dce_conn->auth_state.auth_info->auth_pad_length = 0;273 dce_conn->auth_state.auth_info->auth_reserved = 0;274 413 return NT_STATUS_OK; 275 414 } … … 287 426 struct ncacn_packet *pkt = &call->pkt; 288 427 struct dcesrv_connection *dce_conn = call->conn; 289 struct dcerpc_auth auth;290 428 NTSTATUS status; 291 429 uint32_t auth_length; 292 430 size_t hdr_size = DCERPC_REQUEST_LENGTH; 293 431 294 if (!dce_conn->auth_state.auth_info || 295 !dce_conn->auth_state.gensec_security) { 296 return true; 432 if (!dce_conn->allow_request) { 433 return false; 434 } 435 436 if (dce_conn->auth_state.auth_invalid) { 437 return false; 297 438 } 298 439 … … 301 442 } 302 443 303 switch (dce_conn->auth_state.auth_ info->auth_level) {444 switch (dce_conn->auth_state.auth_level) { 304 445 case DCERPC_AUTH_LEVEL_PRIVACY: 305 446 case DCERPC_AUTH_LEVEL_INTEGRITY: … … 321 462 } 322 463 323 if (pkt->auth_length == 0) { 324 DEBUG(1,("dcesrv_auth_request: unexpected auth_length of 0\n")); 464 if (!dce_conn->auth_state.gensec_security) { 325 465 return false; 326 466 } … … 328 468 status = dcerpc_pull_auth_trailer(pkt, call, 329 469 &pkt->u.request.stub_and_verifier, 330 &auth, &auth_length, false); 331 if (!NT_STATUS_IS_OK(status)) { 470 &call->in_auth_info, &auth_length, false); 471 if (!NT_STATUS_IS_OK(status)) { 472 return false; 473 } 474 475 if (call->in_auth_info.auth_type != dce_conn->auth_state.auth_type) { 476 return false; 477 } 478 479 if (call->in_auth_info.auth_level != dce_conn->auth_state.auth_level) { 480 return false; 481 } 482 483 if (call->in_auth_info.auth_context_id != dce_conn->auth_state.auth_context_id) { 332 484 return false; 333 485 } … … 336 488 337 489 /* check signature or unseal the packet */ 338 switch (dce_conn->auth_state.auth_ info->auth_level) {490 switch (dce_conn->auth_state.auth_level) { 339 491 case DCERPC_AUTH_LEVEL_PRIVACY: 340 492 status = gensec_unseal_packet(dce_conn->auth_state.gensec_security, 341 call,342 493 full_packet->data + hdr_size, 343 494 pkt->u.request.stub_and_verifier.length, 344 495 full_packet->data, 345 full_packet->length-auth.credentials.length, 346 &auth.credentials); 496 full_packet->length- 497 call->in_auth_info.credentials.length, 498 &call->in_auth_info.credentials); 347 499 memcpy(pkt->u.request.stub_and_verifier.data, 348 500 full_packet->data + hdr_size, … … 352 504 case DCERPC_AUTH_LEVEL_INTEGRITY: 353 505 status = gensec_check_packet(dce_conn->auth_state.gensec_security, 354 call,355 506 pkt->u.request.stub_and_verifier.data, 356 507 pkt->u.request.stub_and_verifier.length, 357 508 full_packet->data, 358 full_packet->length-auth.credentials.length, 359 &auth.credentials); 509 full_packet->length- 510 call->in_auth_info.credentials.length, 511 &call->in_auth_info.credentials); 360 512 break; 361 513 … … 371 523 372 524 /* remove the indicated amount of padding */ 373 if (pkt->u.request.stub_and_verifier.length < auth.auth_pad_length) {374 return false; 375 } 376 pkt->u.request.stub_and_verifier.length -= auth.auth_pad_length;525 if (pkt->u.request.stub_and_verifier.length < call->in_auth_info.auth_pad_length) { 526 return false; 527 } 528 pkt->u.request.stub_and_verifier.length -= call->in_auth_info.auth_pad_length; 377 529 378 530 return NT_STATUS_IS_OK(status); … … 394 546 DATA_BLOB creds2; 395 547 396 /* non-signed packets are simple */ 397 if (sig_size == 0) { 398 status = ncacn_push_auth(blob, call, pkt, NULL); 399 return NT_STATUS_IS_OK(status); 400 } 401 402 switch (dce_conn->auth_state.auth_info->auth_level) { 548 switch (dce_conn->auth_state.auth_level) { 403 549 case DCERPC_AUTH_LEVEL_PRIVACY: 404 550 case DCERPC_AUTH_LEVEL_INTEGRITY: 551 if (sig_size == 0) { 552 return false; 553 } 554 405 555 break; 406 556 … … 421 571 } 422 572 573 if (!dce_conn->auth_state.gensec_security) { 574 return false; 575 } 576 423 577 ndr = ndr_push_init_ctx(call); 424 578 if (!ndr) { … … 434 588 return false; 435 589 } 590 591 call->_out_auth_info = (struct dcerpc_auth) { 592 .auth_type = dce_conn->auth_state.auth_type, 593 .auth_level = dce_conn->auth_state.auth_level, 594 .auth_context_id = dce_conn->auth_state.auth_context_id, 595 }; 596 call->out_auth_info = &call->_out_auth_info; 436 597 437 598 /* pad to 16 byte multiple in the payload portion of the … … 440 601 whole packet, whereas w2k8 wants it relative to the start 441 602 of the stub */ 442 dce_conn->auth_state.auth_info->auth_pad_length = 443 (16 - (pkt->u.response.stub_and_verifier.length & 15)) & 15; 444 ndr_err = ndr_push_zero(ndr, 445 dce_conn->auth_state.auth_info->auth_pad_length); 603 call->out_auth_info->auth_pad_length = 604 DCERPC_AUTH_PAD_LENGTH(pkt->u.response.stub_and_verifier.length); 605 ndr_err = ndr_push_zero(ndr, call->out_auth_info->auth_pad_length); 446 606 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { 447 607 return false; … … 449 609 450 610 payload_length = pkt->u.response.stub_and_verifier.length + 451 dce_conn->auth_state.auth_info->auth_pad_length; 452 453 /* we start without signature, it will appended later */ 454 dce_conn->auth_state.auth_info->credentials = data_blob(NULL, 0); 611 call->out_auth_info->auth_pad_length; 455 612 456 613 /* add the auth verifier */ 457 614 ndr_err = ndr_push_dcerpc_auth(ndr, NDR_SCALARS|NDR_BUFFERS, 458 dce_conn->auth_state.auth_info);615 call->out_auth_info); 459 616 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { 460 617 return false; … … 474 631 475 632 /* sign or seal the packet */ 476 switch (dce_conn->auth_state.auth_ info->auth_level) {633 switch (dce_conn->auth_state.auth_level) { 477 634 case DCERPC_AUTH_LEVEL_PRIVACY: 478 635 status = gensec_seal_packet(dce_conn->auth_state.gensec_security, … … 507 664 DEBUG(3,("dcesrv_auth_response: creds2.length[%u] != sig_size[%u] pad[%u] stub[%u]\n", 508 665 (unsigned)creds2.length, (uint32_t)sig_size, 509 (unsigned) dce_conn->auth_state.auth_info->auth_pad_length,666 (unsigned)call->out_auth_info->auth_pad_length, 510 667 (unsigned)pkt->u.response.stub_and_verifier.length)); 511 668 dcerpc_set_frag_length(blob, blob->length + creds2.length); -
vendor/current/source4/rpc_server/dcesrv_mgmt.c
r414 r988 23 23 #include "rpc_server/dcerpc_server.h" 24 24 #include "librpc/gen_ndr/ndr_mgmt.h" 25 26 #define DCESRV_INTERFACE_MGMT_BIND(call, iface) \ 27 dcesrv_interface_mgmt_bind(call, iface) 28 static NTSTATUS dcesrv_interface_mgmt_bind(struct dcesrv_call_state *dce_call, 29 const struct dcesrv_interface *iface) 30 { 31 return dcesrv_interface_bind_allow_connect(dce_call, iface); 32 } 25 33 26 34 /* -
vendor/current/source4/rpc_server/drsuapi/addentry.c
r740 r988 62 62 dn, LDB_SCOPE_BASE, attrs, 63 63 "(objectClass=ntDSDSA)"); 64 if (ret != LDB_SUCCESS || res->count < 1) {64 if (ret != LDB_SUCCESS) { 65 65 DEBUG(0,(__location__ ": Failed to find dn '%s'\n", dn_string)); 66 66 return WERR_DS_DRA_INTERNAL_ERROR; 67 } 68 69 if (res->count < 1) { 70 /* we only add SPNs for nTDSDSA objects */ 71 continue; 67 72 } 68 73 … … 192 197 first_object, 193 198 &num, 199 DSDB_REPL_FLAG_ADD_NCNAME, 194 200 &ids); 195 201 if (!W_ERROR_IS_OK(status)) { -
vendor/current/source4/rpc_server/drsuapi/dcesrv_drsuapi.c
r740 r988 26 26 #include "rpc_server/common/common.h" 27 27 #include "dsdb/samdb/samdb.h" 28 #include "dsdb/common/util.h" 28 29 #include "libcli/security/security.h" 29 30 #include "libcli/security/session.h" … … 38 39 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR); \ 39 40 } while (0) 41 42 #define DCESRV_INTERFACE_DRSUAPI_BIND(call, iface) \ 43 dcesrv_interface_drsuapi_bind(call, iface) 44 static NTSTATUS dcesrv_interface_drsuapi_bind(struct dcesrv_call_state *dce_call, 45 const struct dcesrv_interface *iface) 46 { 47 return dcesrv_interface_bind_require_privacy(dce_call, iface); 48 } 40 49 41 50 /* … … 124 133 * lookup the local servers Replication Epoch 125 134 */ 126 ntds_dn = samdb_ntds_settings_dn(b_state->sam_ctx );135 ntds_dn = samdb_ntds_settings_dn(b_state->sam_ctx, mem_ctx); 127 136 W_ERROR_HAVE_NO_MEMORY(ntds_dn); 128 137 … … 220 229 * allocate the return bind_info 221 230 */ 222 bind_info = talloc (mem_ctx, struct drsuapi_DsBindInfoCtr);231 bind_info = talloc_zero(mem_ctx, struct drsuapi_DsBindInfoCtr); 223 232 W_ERROR_HAVE_NO_MEMORY(bind_info); 224 233 … … 430 439 case 1: { 431 440 switch(r->in.req->req1.format_offered){ 432 case DRSUAPI_DS_NAME_FORMAT_UPN_AND_ALTSECID:433 441 case DRSUAPI_DS_NAME_FORMAT_NT4_ACCOUNT_NAME_SANS_DOMAIN_EX: 434 case DRSUAPI_DS_NAME_FORMAT_LIST_GLOBAL_CATALOG_SERVERS: 435 case DRSUAPI_DS_NAME_FORMAT_UPN_FOR_LOGON: 436 case DRSUAPI_DS_NAME_FORMAT_LIST_SERVERS_WITH_DCS_IN_SITE: 442 case DRSUAPI_DS_NAME_FORMAT_NT4_ACCOUNT_NAME_SANS_DOMAIN: 437 443 case DRSUAPI_DS_NAME_FORMAT_STRING_SID_NAME: 438 444 case DRSUAPI_DS_NAME_FORMAT_ALT_SECURITY_IDENTITIES_NAME: 445 case DRSUAPI_DS_NAME_FORMAT_MAP_SCHEMA_GUID: 439 446 case DRSUAPI_DS_NAME_FORMAT_LIST_NCS: 440 447 case DRSUAPI_DS_NAME_FORMAT_LIST_DOMAINS: 441 case DRSUAPI_DS_NAME_FORMAT_MAP_SCHEMA_GUID: 442 case DRSUAPI_DS_NAME_FORMAT_NT4_ACCOUNT_NAME_SANS_DOMAIN: 443 case DRSUAPI_DS_NAME_FORMAT_LIST_INFO_FOR_SERVER: 448 case DRSUAPI_DS_NAME_FORMAT_LIST_GLOBAL_CATALOG_SERVERS: 449 case DRSUAPI_DS_NAME_FORMAT_LIST_SERVERS_WITH_DCS_IN_SITE: 444 450 case DRSUAPI_DS_NAME_FORMAT_LIST_SERVERS_FOR_DOMAIN_IN_SITE: 445 451 case DRSUAPI_DS_NAME_FORMAT_LIST_DOMAINS_IN_SITE: 446 452 case DRSUAPI_DS_NAME_FORMAT_LIST_SERVERS_IN_SITE: 447 453 case DRSUAPI_DS_NAME_FORMAT_LIST_SITES: 454 case DRSUAPI_DS_NAME_FORMAT_UPN_AND_ALTSECID: 455 case DRSUAPI_DS_NAME_FORMAT_UPN_FOR_LOGON: 448 456 DEBUG(0, ("DsCrackNames: Unsupported operation requested: %X", 449 457 r->in.req->req1.format_offered)); 450 458 return WERR_OK; 459 case DRSUAPI_DS_NAME_FORMAT_LIST_INFO_FOR_SERVER: 460 return dcesrv_drsuapi_ListInfoServer(b_state->sam_ctx, mem_ctx, &r->in.req->req1, &r->out.ctr->ctr1); 451 461 case DRSUAPI_DS_NAME_FORMAT_LIST_ROLES: 452 462 return dcesrv_drsuapi_ListRoles(b_state->sam_ctx, mem_ctx, … … 503 513 504 514 if (r->in.req->req1.commit) { 505 ret = ldb_delete(b_state->sam_ctx, ntds_dn);515 ret = dsdb_delete(b_state->sam_ctx, ntds_dn, DSDB_TREE_DELETE); 506 516 if (ret != LDB_SUCCESS) { 507 517 return WERR_FOOBAR; … … 576 586 577 587 *r->out.level_out = r->in.req->req1.level; 578 r->out.ctr = talloc (mem_ctx, union drsuapi_DsGetDCInfoCtr);588 r->out.ctr = talloc_zero(mem_ctx, union drsuapi_DsGetDCInfoCtr); 579 589 W_ERROR_HAVE_NO_MEMORY(r->out.ctr); 580 581 sites_dn = samdb_sites_dn(b_state->sam_ctx, mem_ctx);582 if (!sites_dn) {583 return WERR_DS_OBJ_NOT_FOUND;584 }585 590 586 591 switch (*r->out.level_out) { … … 598 603 } 599 604 605 sites_dn = samdb_sites_dn(b_state->sam_ctx, mem_ctx); 606 if (!sites_dn) { 607 return WERR_DS_OBJ_NOT_FOUND; 608 } 609 600 610 ret = ldb_search(b_state->sam_ctx, mem_ctx, &res, sites_dn, LDB_SCOPE_SUBTREE, attrs, 601 " objectClass=server");611 "(&(objectClass=server)(serverReference=*))"); 602 612 603 613 if (ret) { … … 630 640 631 641 ret = ldb_search(b_state->sam_ctx, mem_ctx, &res_account, ref_dn, 632 LDB_SCOPE_BASE, attrs_account_1, "objectClass=computer"); 642 LDB_SCOPE_BASE, attrs_account_1, 643 "(&(objectClass=computer)(userAccountControl:1.2.840.113556.1.4.803:=%u))", 644 UF_SERVER_TRUST_ACCOUNT); 633 645 if (ret == LDB_SUCCESS && res_account->count == 1) { 634 646 const char *errstr; … … 770 782 } 771 783 break; 784 default: 785 return WERR_UNKNOWN_LEVEL; 772 786 } 773 787 return WERR_OK; … … 802 816 { 803 817 WERROR status; 818 uint32_t timeout; 804 819 status = drs_security_level_check(dce_call, "DsExecuteKCC", SECURITY_DOMAIN_CONTROLLER, NULL); 805 820 … … 807 822 return status; 808 823 } 824 if (r->in.req->ctr1.taskID != 0) { 825 return WERR_INVALID_PARAM; 826 } 827 if (r->in.req->ctr1.flags & DRSUAPI_DS_EXECUTE_KCC_ASYNCHRONOUS_OPERATION) { 828 timeout = IRPC_CALL_TIMEOUT; 829 } else { 830 /* 831 * use Infinite time for timeout in case 832 * the caller made a sync call 833 */ 834 timeout = IRPC_CALL_TIMEOUT_INF; 835 } 809 836 810 837 dcesrv_irpc_forward_rpc_call(dce_call, mem_ctx, r, NDR_DRSUAPI_DSEXECUTEKCC, 811 838 &ndr_table_drsuapi, "kccsrv", "DsExecuteKCC", 812 IRPC_CALL_TIMEOUT); 839 timeout); 840 DEBUG(0, ("Forwarded the call to execute the KCC\n")); 813 841 return WERR_OK; 814 842 } -
vendor/current/source4/rpc_server/drsuapi/drsutil.c
r740 r988 27 27 #include "param/param.h" 28 28 #include "auth/session.h" 29 #include "rpc_server/drsuapi/dcesrv_drsuapi.h" 29 30 30 31 int drsuapi_search_with_extended_dn(struct ldb_context *ldb, … … 170 171 return WERR_DS_DRA_ACCESS_DENIED; 171 172 } else if (ret != LDB_SUCCESS) { 172 DEBUG(1,("Failed to perform access check on %s \n", ldb_dn_get_linearized(dn)));173 DEBUG(1,("Failed to perform access check on %s: %s\n", ldb_dn_get_linearized(dn), ldb_strerror(ret))); 173 174 return WERR_DS_DRA_INTERNAL_ERROR; 174 175 } -
vendor/current/source4/rpc_server/drsuapi/getncchanges.c
r740 r988 38 38 #include "dsdb/common/util.h" 39 39 40 /* state of a partially completed getncchanges call */ 41 struct drsuapi_getncchanges_state { 42 struct GUID *guids; 43 uint32_t num_records; 44 uint32_t num_processed; 45 struct ldb_dn *ncRoot_dn; 46 bool is_schema_nc; 47 uint64_t min_usn; 48 uint64_t max_usn; 49 struct drsuapi_DsReplicaHighWaterMark last_hwm; 50 struct ldb_dn *last_dn; 51 struct drsuapi_DsReplicaHighWaterMark final_hwm; 52 struct drsuapi_DsReplicaCursor2CtrEx *final_udv; 53 struct drsuapi_DsReplicaLinkedAttribute *la_list; 54 uint32_t la_count; 55 bool la_sorted; 56 uint32_t la_idx; 57 }; 58 59 static int drsuapi_DsReplicaHighWaterMark_cmp(const struct drsuapi_DsReplicaHighWaterMark *h1, 60 const struct drsuapi_DsReplicaHighWaterMark *h2) 61 { 62 if (h1->highest_usn < h2->highest_usn) { 63 return -1; 64 } else if (h1->highest_usn > h2->highest_usn) { 65 return 1; 66 } else if (h1->tmp_highest_usn < h2->tmp_highest_usn) { 67 return -1; 68 } else if (h1->tmp_highest_usn > h2->tmp_highest_usn) { 69 return 1; 70 } else if (h1->reserved_usn < h2->reserved_usn) { 71 return -1; 72 } else if (h1->reserved_usn > h2->reserved_usn) { 73 return 1; 74 } 75 76 return 0; 77 } 78 40 79 /* 41 80 build a DsReplicaObjectIdentifier from a ldb msg … … 120 159 struct drsuapi_DsPartialAttributeSet *partial_attribute_set, 121 160 struct drsuapi_DsReplicaCursorCtrEx *uptodateness_vector, 122 enum drsuapi_DsExtendedOperation extended_op) 161 enum drsuapi_DsExtendedOperation extended_op, 162 bool force_object_return) 123 163 { 124 164 const struct ldb_val *md_value; … … 261 301 /* ignore it if its an empty change. Note that renames always 262 302 * change the 'name' attribute, so they won't be ignored by 263 * this */ 303 * this 304 305 * the force_object_return check is used to force an empty 306 * object return when we timeout in the getncchanges loop. 307 * This allows us to return an empty object, which keeps the 308 * client happy while preventing timeouts 309 */ 264 310 if (n == 0 || 265 (n == 1 && attids[0] == DRSUAPI_ATTID_instanceType)) { 311 (n == 1 && 312 attids[0] == DRSUAPI_ATTID_instanceType && 313 !force_object_return)) { 266 314 talloc_free(obj->meta_data_ctr); 267 315 obj->meta_data_ctr = NULL; … … 275 323 obj->object.attribute_ctr.attributes = talloc_array(obj, struct drsuapi_DsReplicaAttribute, 276 324 obj->object.attribute_ctr.num_attributes); 325 if (obj->object.attribute_ctr.attributes == NULL) { 326 return WERR_NOMEM; 327 } 277 328 278 329 /* … … 303 354 &obj->object.attribute_ctr.attributes[i]); 304 355 if (!W_ERROR_IS_OK(werr)) { 305 DEBUG(0,("Unable to convert %s to DRS object - %s\n", 306 sa->lDAPDisplayName, win_errstr(werr))); 356 DEBUG(0,("Unable to convert %s on %s to DRS object - %s\n", 357 sa->lDAPDisplayName, ldb_dn_get_linearized(msg->dn), 358 win_errstr(werr))); 307 359 return werr; 308 360 } … … 319 371 &obj->object.attribute_ctr.attributes[i]); 320 372 if (!W_ERROR_IS_OK(werr)) { 321 DEBUG(0,("Unable to encrypt %s in DRS object - %s\n", 322 sa->lDAPDisplayName, win_errstr(werr))); 373 DEBUG(0,("Unable to encrypt %s on %s in DRS object - %s\n", 374 sa->lDAPDisplayName, ldb_dn_get_linearized(msg->dn), 375 win_errstr(werr))); 323 376 return werr; 324 377 } 325 378 } 379 if (attids[i] != obj->object.attribute_ctr.attributes[i].attid) { 380 DEBUG(0, ("Unable to replicate attribute %s on %s via DRS, incorrect attributeID: " 381 "0x%08x vs 0x%08x " 382 "Run dbcheck!\n", 383 sa->lDAPDisplayName, 384 ldb_dn_get_linearized(msg->dn), 385 attids[i], 386 obj->object.attribute_ctr.attributes[i].attid)); 387 return WERR_DS_DATABASE_ERROR; 388 } 326 389 } 327 390 328 391 return WERR_OK; 329 392 } 330 331 393 332 394 /* … … 358 420 active = (dsdb_dn_rmd_flags(dsdb_dn->dn) & DSDB_RMD_FLAG_DELETED) == 0; 359 421 422 if (!active) { 423 /* We have to check that the inactive link still point to an existing object */ 424 struct GUID guid; 425 struct ldb_dn *tdn; 426 int ret; 427 const char *v; 428 429 v = ldb_msg_find_attr_as_string(msg, "isDeleted", "FALSE"); 430 if (strncmp(v, "TRUE", 4) == 0) { 431 /* 432 * Note: we skip the transmition of the deleted link even if the other part used to 433 * know about it because when we transmit the deletion of the object, the link will 434 * be deleted too due to deletion of object where link points and Windows do so. 435 */ 436 if (dsdb_functional_level(sam_ctx) >= DS_DOMAIN_FUNCTION_2008_R2) { 437 v = ldb_msg_find_attr_as_string(msg, "isRecycled", "FALSE"); 438 /* 439 * On Windows 2008R2 isRecycled is always present even if FL or DL are < FL 2K8R2 440 * if it join an existing domain with deleted objets, it firsts impose to have a 441 * schema with the is-Recycled object and for all deleted objects it adds the isRecycled 442 * either during initial replication or after the getNCChanges. 443 * Behavior of samba has been changed to always have this attribute if it's present in the schema. 444 * 445 * So if FL <2K8R2 isRecycled might be here or not but we don't care, it's meaning less. 446 * If FL >=2K8R2 we are sure that this attribute will be here. 447 * For this kind of forest level we do not return the link if the object is recycled 448 * (isRecycled = true). 449 */ 450 if (strncmp(v, "TRUE", 4) == 0) { 451 DEBUG(2, (" object %s is recycled, not returning linked attribute !\n", 452 ldb_dn_get_linearized(msg->dn))); 453 return WERR_OK; 454 } 455 } else { 456 return WERR_OK; 457 } 458 } 459 status = dsdb_get_extended_dn_guid(dsdb_dn->dn, &guid, "GUID"); 460 if (!NT_STATUS_IS_OK(status)) { 461 DEBUG(0,(__location__ " Unable to extract GUID in linked attribute '%s' in '%s'\n", 462 sa->lDAPDisplayName, ldb_dn_get_linearized(msg->dn))); 463 return ntstatus_to_werror(status); 464 } 465 ret = dsdb_find_dn_by_guid(sam_ctx, mem_ctx, &guid, 0, &tdn); 466 if (ret == LDB_ERR_NO_SUCH_OBJECT) { 467 DEBUG(2, (" Search of guid %s returned 0 objects, skipping it !\n", 468 GUID_string(mem_ctx, &guid))); 469 return WERR_OK; 470 } else if (ret != LDB_SUCCESS) { 471 DEBUG(0, (__location__ " Search of guid %s failed with error code %d\n", 472 GUID_string(mem_ctx, &guid), 473 ret)); 474 return WERR_OK; 475 } 476 } 360 477 la->attid = sa->attributeID_id; 361 478 la->flags = active?DRSUAPI_DS_LINKED_ATTRIBUTE_FLAG_ACTIVE:0; 362 479 480 status = dsdb_get_extended_dn_uint32(dsdb_dn->dn, &la->meta_data.version, "RMD_VERSION"); 481 if (!NT_STATUS_IS_OK(status)) { 482 DEBUG(0,(__location__ " No RMD_VERSION in linked attribute '%s' in '%s'\n", 483 sa->lDAPDisplayName, ldb_dn_get_linearized(msg->dn))); 484 return ntstatus_to_werror(status); 485 } 486 status = dsdb_get_extended_dn_nttime(dsdb_dn->dn, &la->meta_data.originating_change_time, "RMD_CHANGETIME"); 487 if (!NT_STATUS_IS_OK(status)) { 488 DEBUG(0,(__location__ " No RMD_CHANGETIME in linked attribute '%s' in '%s'\n", 489 sa->lDAPDisplayName, ldb_dn_get_linearized(msg->dn))); 490 return ntstatus_to_werror(status); 491 } 492 status = dsdb_get_extended_dn_guid(dsdb_dn->dn, &la->meta_data.originating_invocation_id, "RMD_INVOCID"); 493 if (!NT_STATUS_IS_OK(status)) { 494 DEBUG(0,(__location__ " No RMD_INVOCID in linked attribute '%s' in '%s'\n", 495 sa->lDAPDisplayName, ldb_dn_get_linearized(msg->dn))); 496 return ntstatus_to_werror(status); 497 } 498 status = dsdb_get_extended_dn_uint64(dsdb_dn->dn, &la->meta_data.originating_usn, "RMD_ORIGINATING_USN"); 499 if (!NT_STATUS_IS_OK(status)) { 500 DEBUG(0,(__location__ " No RMD_ORIGINATING_USN in linked attribute '%s' in '%s'\n", 501 sa->lDAPDisplayName, ldb_dn_get_linearized(msg->dn))); 502 return ntstatus_to_werror(status); 503 } 504 363 505 status = dsdb_get_extended_dn_nttime(dsdb_dn->dn, &la->originating_add_time, "RMD_ADDTIME"); 364 506 if (!NT_STATUS_IS_OK(status)) { 365 return ntstatus_to_werror(status); 366 } 367 status = dsdb_get_extended_dn_uint32(dsdb_dn->dn, &la->meta_data.version, "RMD_VERSION"); 368 if (!NT_STATUS_IS_OK(status)) { 369 return ntstatus_to_werror(status); 370 } 371 status = dsdb_get_extended_dn_nttime(dsdb_dn->dn, &la->meta_data.originating_change_time, "RMD_CHANGETIME"); 372 if (!NT_STATUS_IS_OK(status)) { 373 return ntstatus_to_werror(status); 374 } 375 status = dsdb_get_extended_dn_guid(dsdb_dn->dn, &la->meta_data.originating_invocation_id, "RMD_INVOCID"); 376 if (!NT_STATUS_IS_OK(status)) { 377 return ntstatus_to_werror(status); 378 } 379 status = dsdb_get_extended_dn_uint64(dsdb_dn->dn, &la->meta_data.originating_usn, "RMD_ORIGINATING_USN"); 380 if (!NT_STATUS_IS_OK(status)) { 381 return ntstatus_to_werror(status); 507 /* this is possible for upgraded links */ 508 la->originating_add_time = la->meta_data.originating_change_time; 382 509 } 383 510 … … 563 690 } 564 691 692 struct drsuapi_changed_objects { 693 struct ldb_dn *dn; 694 struct GUID guid; 695 uint64_t usn; 696 }; 565 697 566 698 /* 567 699 sort the objects we send by tree order 568 700 */ 569 static int site_res_cmp_parent_order(struct ldb_message **m1, struct ldb_message **m2) 570 { 571 return ldb_dn_compare((*m2)->dn, (*m1)->dn); 701 static int site_res_cmp_anc_order(struct drsuapi_changed_objects *m1, 702 struct drsuapi_changed_objects *m2, 703 struct drsuapi_getncchanges_state *getnc_state) 704 { 705 return ldb_dn_compare(m2->dn, m1->dn); 572 706 } 573 707 … … 575 709 sort the objects we send first by uSNChanged 576 710 */ 577 static int site_res_cmp_usn_order(struct ldb_message **m1, struct ldb_message **m2) 578 { 579 unsigned usnchanged1, usnchanged2; 580 unsigned cn1, cn2; 581 cn1 = ldb_dn_get_comp_num((*m1)->dn); 582 cn2 = ldb_dn_get_comp_num((*m2)->dn); 583 if (cn1 != cn2) { 584 return cn1 > cn2 ? 1 : -1; 585 } 586 usnchanged1 = ldb_msg_find_attr_as_uint(*m1, "uSNChanged", 0); 587 usnchanged2 = ldb_msg_find_attr_as_uint(*m2, "uSNChanged", 0); 588 if (usnchanged1 == usnchanged2) { 589 return 0; 590 } 591 return usnchanged1 > usnchanged2 ? 1 : -1; 711 static int site_res_cmp_usn_order(struct drsuapi_changed_objects *m1, 712 struct drsuapi_changed_objects *m2, 713 struct drsuapi_getncchanges_state *getnc_state) 714 { 715 int ret; 716 717 ret = ldb_dn_compare(getnc_state->ncRoot_dn, m1->dn); 718 if (ret == 0) { 719 return -1; 720 } 721 722 ret = ldb_dn_compare(getnc_state->ncRoot_dn, m2->dn); 723 if (ret == 0) { 724 return 1; 725 } 726 727 if (m1->usn == m2->usn) { 728 return ldb_dn_compare(m2->dn, m1->dn); 729 } 730 731 if (m1->usn < m2->usn) { 732 return -1; 733 } 734 735 return 1; 592 736 } 593 737 … … 601 745 struct drsuapi_DsGetNCChangesCtr6 *ctr6) 602 746 { 603 struct ldb_dn *rid_manager_dn, * fsmo_role_dn, *req_dn;747 struct ldb_dn *rid_manager_dn, *req_dn; 604 748 int ret; 605 749 struct ldb_context *ldb = b_state->sam_ctx; 606 750 struct ldb_result *ext_res; 607 struct ldb_dn *base_dn;608 751 struct dsdb_fsmo_extended_op *exop; 752 bool is_us; 609 753 610 754 /* … … 632 776 633 777 /* find the DN of the RID Manager */ 634 ret = samdb_reference_dn (ldb, mem_ctx, rid_manager_dn, "fSMORoleOwner", &fsmo_role_dn);778 ret = samdb_reference_dn_is_our_ntdsa(ldb, rid_manager_dn, "fSMORoleOwner", &is_us); 635 779 if (ret != LDB_SUCCESS) { 636 DEBUG(0,(__location__ ": Failed to find fSMORoleOwner in RID Manager object - %s\n", 637 ldb_errstring(ldb))); 780 DEBUG(0,("Failed to find fSMORoleOwner in RID Manager object\n")); 638 781 ctr6->extended_ret = DRSUAPI_EXOP_ERR_FSMO_NOT_OWNER; 639 782 return WERR_DS_DRA_INTERNAL_ERROR; 640 783 } 641 784 642 if ( ldb_dn_compare(samdb_ntds_settings_dn(ldb), fsmo_role_dn) != 0) {785 if (!is_us) { 643 786 /* we're not the RID Manager - go away */ 644 787 DEBUG(0,(__location__ ": RID Alloc request when not RID Manager\n")); … … 685 828 686 829 talloc_free(ext_res); 687 688 base_dn = ldb_get_default_basedn(ldb);689 830 690 831 DEBUG(2,("Allocated RID pool for server %s\n", … … 802 943 struct drsuapi_DsGetNCChangesRequest10 *req10, 803 944 struct dom_sid *user_sid, 804 struct drsuapi_DsGetNCChangesCtr6 *ctr6) 945 struct drsuapi_DsGetNCChangesCtr6 *ctr6, 946 bool has_get_all_changes) 805 947 { 806 948 struct drsuapi_DsReplicaObjectIdentifier *ncRoot = req10->naming_context; 807 struct ldb_dn *obj_dn, *rodc_dn, *krbtgt_link_dn; 949 struct ldb_dn *obj_dn = NULL; 950 struct ldb_dn *rodc_dn, *krbtgt_link_dn; 808 951 int ret; 809 952 const char *rodc_attrs[] = { "msDS-KrbTgtLink", "msDS-NeverRevealGroup", "msDS-RevealOnDemandGroup", NULL }; … … 817 960 818 961 /* 819 * we need to work out if we will allow this RODC to962 * we need to work out if we will allow this DC to 820 963 * replicate the secrets for this object 821 964 * … … 828 971 ctr6->extended_ret = DRSUAPI_EXOP_ERR_ACCESS_DENIED; 829 972 return WERR_DS_DRA_SOURCE_DISABLED; 973 } 974 975 /* 976 * In MS-DRSR.pdf 5.99 IsGetNCChangesPermissionGranted 977 * 978 * The pseudo code indicate 979 * revealsecrets = true 980 * if IsRevealSecretRequest(msgIn) then 981 * if AccessCheckCAR(ncRoot, Ds-Replication-Get-Changes-All) = false 982 * then 983 * if (msgIn.ulExtendedOp = EXOP_REPL_SECRETS) then 984 * <... check if this account is ok to be replicated on this DC ...> 985 * <... and if not reveal secrets = no ...> 986 * else 987 * reveal secrets = false 988 * endif 989 * endif 990 * endif 991 * 992 * Which basically means that if you have GET_ALL_CHANGES rights (~== RWDC) 993 * then you can do EXOP_REPL_SECRETS 994 */ 995 if (has_get_all_changes) { 996 goto allowed; 830 997 } 831 998 … … 901 1068 /* default deny */ 902 1069 denied: 903 DEBUG(2,(__location__ ": Denied RODCsecret replication for %s by RODC %s\n",1070 DEBUG(2,(__location__ ": Denied single object with secret replication for %s by RODC %s\n", 904 1071 ldb_dn_get_linearized(obj_dn), ldb_dn_get_linearized(rodc_res->msgs[0]->dn))); 905 1072 ctr6->extended_ret = DRSUAPI_EXOP_ERR_NONE; … … 907 1074 908 1075 allowed: 909 DEBUG(2,(__location__ ": Allowed RODC secret replication for %s by RODC %s\n", 910 ldb_dn_get_linearized(obj_dn), ldb_dn_get_linearized(rodc_res->msgs[0]->dn))); 1076 DEBUG(2,(__location__ ": Allowed single object with secret replication for %s by %s %s\n", 1077 ldb_dn_get_linearized(obj_dn), has_get_all_changes?"RWDC":"RODC", 1078 ldb_dn_get_linearized(rodc_res->msgs[0]->dn))); 911 1079 ctr6->extended_ret = DRSUAPI_EXOP_ERR_SUCCESS; 912 1080 req10->highwatermark.highest_usn = 0; … … 914 1082 915 1083 failed: 916 DEBUG(2,(__location__ ": Failed RODCsecret replication for %s by RODC %s\n",1084 DEBUG(2,(__location__ ": Failed single secret replication for %s by RODC %s\n", 917 1085 ldb_dn_get_linearized(obj_dn), dom_sid_string(mem_ctx, user_sid))); 918 1086 ctr6->extended_ret = DRSUAPI_EXOP_ERR_NONE; … … 936 1104 937 1105 ctr6->extended_ret = DRSUAPI_EXOP_ERR_SUCCESS; 938 req10->highwatermark.highest_usn = 0;939 1106 return WERR_OK; 940 1107 } … … 951 1118 struct drsuapi_DsGetNCChangesCtr6 *ctr6) 952 1119 { 953 struct ldb_dn * fsmo_role_dn, *req_dn, *ntds_dn;1120 struct ldb_dn *req_dn, *ntds_dn; 954 1121 int ret; 955 1122 unsigned int i; 956 1123 struct ldb_context *ldb = b_state->sam_ctx; 957 1124 struct ldb_message *msg; 1125 bool is_us; 958 1126 959 1127 /* … … 972 1140 } 973 1141 974 /* retrievethe current role owner */975 ret = samdb_reference_dn (ldb, mem_ctx, req_dn, "fSMORoleOwner", &fsmo_role_dn);1142 /* find the DN of the current role owner */ 1143 ret = samdb_reference_dn_is_our_ntdsa(ldb, req_dn, "fSMORoleOwner", &is_us); 976 1144 if (ret != LDB_SUCCESS) { 977 DEBUG(0,(__location__ ": Failed to find fSMORoleOwner in context - %s\n", 978 ldb_errstring(ldb))); 1145 DEBUG(0,("Failed to find fSMORoleOwner in RID Manager object\n")); 979 1146 ctr6->extended_ret = DRSUAPI_EXOP_ERR_FSMO_NOT_OWNER; 980 1147 return WERR_DS_DRA_INTERNAL_ERROR; 981 1148 } 982 1149 983 if ( ldb_dn_compare(samdb_ntds_settings_dn(ldb), fsmo_role_dn) != 0) {984 /* we're not the currentowner - go away */985 DEBUG(0,(__location__ ": FSMO transfer request when notowner\n"));1150 if (!is_us) { 1151 /* we're not the RID Manager or role owner - go away */ 1152 DEBUG(0,(__location__ ": FSMO role or RID manager transfer owner request when not role owner\n")); 986 1153 ctr6->extended_ret = DRSUAPI_EXOP_ERR_FSMO_NOT_OWNER; 987 1154 return WERR_OK; … … 994 1161 W_ERROR_HAVE_NO_MEMORY(msg->dn); 995 1162 996 ret = dsdb_find_dn_by_guid(ldb, msg, &req10->destination_dsa_guid, &ntds_dn); 1163 /* TODO: make sure ntds_dn is a valid nTDSDSA object */ 1164 ret = dsdb_find_dn_by_guid(ldb, msg, &req10->destination_dsa_guid, 0, &ntds_dn); 997 1165 if (ret != LDB_SUCCESS) { 998 1166 DEBUG(0, (__location__ ": Unable to find NTDS object for guid %s - %s\n", 999 1167 GUID_string(mem_ctx, &req10->destination_dsa_guid), ldb_errstring(ldb))); 1000 1168 talloc_free(msg); 1001 return WERR_DS_DRA_INTERNAL_ERROR; 1169 ctr6->extended_ret = DRSUAPI_EXOP_ERR_UNKNOWN_CALLER; 1170 return WERR_OK; 1002 1171 } 1003 1172 … … 1038 1207 return WERR_OK; 1039 1208 } 1040 1041 /* state of a partially completed getncchanges call */1042 struct drsuapi_getncchanges_state {1043 struct GUID *guids;1044 uint32_t num_records;1045 uint32_t num_processed;1046 struct ldb_dn *ncRoot_dn;1047 bool is_schema_nc;1048 uint64_t min_usn;1049 uint64_t highest_usn;1050 struct ldb_dn *last_dn;1051 struct drsuapi_DsReplicaLinkedAttribute *la_list;1052 uint32_t la_count;1053 bool la_sorted;1054 uint32_t la_idx;1055 struct drsuapi_DsReplicaCursorCtrEx *uptodateness_vector;1056 };1057 1209 1058 1210 /* … … 1113 1265 } 1114 1266 1267 if (req10->partial_attribute_set_ex) { 1268 /* check the extended attributes they asked for */ 1269 for (i=0; i<req10->partial_attribute_set_ex->num_attids; i++) { 1270 const struct dsdb_attribute *sa; 1271 sa = dsdb_attribute_by_attributeID_id(schema, req10->partial_attribute_set_ex->attids[i]); 1272 if (sa == NULL) { 1273 return WERR_DS_DRA_SCHEMA_MISMATCH; 1274 } 1275 if (!dsdb_attr_in_rodc_fas(sa)) { 1276 *is_secret_request = true; 1277 return WERR_OK; 1278 } 1279 } 1280 } 1281 1282 *is_secret_request = false; 1283 return WERR_OK; 1284 } 1285 1286 /* 1287 see if this getncchanges request is only for attributes in the GC 1288 partial attribute set 1289 */ 1290 static WERROR dcesrv_drsuapi_is_gc_pas_request(struct drsuapi_bind_state *b_state, 1291 struct drsuapi_DsGetNCChangesRequest10 *req10, 1292 bool *is_gc_pas_request) 1293 { 1294 enum drsuapi_DsExtendedOperation exop; 1295 uint32_t i; 1296 struct dsdb_schema *schema; 1297 1298 exop = req10->extended_op; 1299 1300 switch (exop) { 1301 case DRSUAPI_EXOP_FSMO_REQ_ROLE: 1302 case DRSUAPI_EXOP_FSMO_RID_ALLOC: 1303 case DRSUAPI_EXOP_FSMO_RID_REQ_ROLE: 1304 case DRSUAPI_EXOP_FSMO_REQ_PDC: 1305 case DRSUAPI_EXOP_FSMO_ABANDON_ROLE: 1306 case DRSUAPI_EXOP_REPL_SECRET: 1307 *is_gc_pas_request = false; 1308 return WERR_OK; 1309 case DRSUAPI_EXOP_REPL_OBJ: 1310 case DRSUAPI_EXOP_NONE: 1311 break; 1312 } 1313 1314 if (req10->partial_attribute_set == NULL) { 1315 /* they want it all */ 1316 *is_gc_pas_request = false; 1317 return WERR_OK; 1318 } 1319 1320 schema = dsdb_get_schema(b_state->sam_ctx, NULL); 1321 1115 1322 /* check the attributes they asked for */ 1116 for (i=0; i<req10->partial_attribute_set _ex->num_attids; i++) {1323 for (i=0; i<req10->partial_attribute_set->num_attids; i++) { 1117 1324 const struct dsdb_attribute *sa; 1118 sa = dsdb_attribute_by_attributeID_id(schema, req10->partial_attribute_set _ex->attids[i]);1325 sa = dsdb_attribute_by_attributeID_id(schema, req10->partial_attribute_set->attids[i]); 1119 1326 if (sa == NULL) { 1120 1327 return WERR_DS_DRA_SCHEMA_MISMATCH; 1121 1328 } 1122 if (! dsdb_attr_in_rodc_fas(sa)) {1123 *is_ secret_request = true;1329 if (!sa->isMemberOfPartialAttributeSet) { 1330 *is_gc_pas_request = false; 1124 1331 return WERR_OK; 1125 1332 } 1126 1333 } 1127 1334 1128 *is_secret_request = false; 1335 if (req10->partial_attribute_set_ex) { 1336 /* check the extended attributes they asked for */ 1337 for (i=0; i<req10->partial_attribute_set_ex->num_attids; i++) { 1338 const struct dsdb_attribute *sa; 1339 sa = dsdb_attribute_by_attributeID_id(schema, req10->partial_attribute_set_ex->attids[i]); 1340 if (sa == NULL) { 1341 return WERR_DS_DRA_SCHEMA_MISMATCH; 1342 } 1343 if (!sa->isMemberOfPartialAttributeSet) { 1344 *is_gc_pas_request = false; 1345 return WERR_OK; 1346 } 1347 } 1348 } 1349 1350 *is_gc_pas_request = true; 1129 1351 return WERR_OK; 1130 1352 } … … 1162 1384 1163 1385 1386 /** 1387 * Collects object for normal replication cycle. 1388 */ 1389 static WERROR getncchanges_collect_objects(struct drsuapi_bind_state *b_state, 1390 TALLOC_CTX *mem_ctx, 1391 struct drsuapi_DsGetNCChangesRequest10 *req10, 1392 struct ldb_dn *search_dn, 1393 const char *extra_filter, 1394 struct ldb_result **search_res) 1395 { 1396 int ret; 1397 char* search_filter; 1398 enum ldb_scope scope = LDB_SCOPE_SUBTREE; 1399 //const char *extra_filter; 1400 struct drsuapi_getncchanges_state *getnc_state = b_state->getncchanges_state; 1401 const char *attrs[] = { "uSNChanged", 1402 "objectGUID" , 1403 NULL }; 1404 1405 if (req10->extended_op == DRSUAPI_EXOP_REPL_OBJ || 1406 req10->extended_op == DRSUAPI_EXOP_REPL_SECRET) { 1407 scope = LDB_SCOPE_BASE; 1408 } 1409 1410 //extra_filter = lpcfg_parm_string(dce_call->conn->dce_ctx->lp_ctx, NULL, "drs", "object filter"); 1411 1412 //getnc_state->min_usn = req10->highwatermark.highest_usn; 1413 1414 /* Construct response. */ 1415 search_filter = talloc_asprintf(mem_ctx, 1416 "(uSNChanged>=%llu)", 1417 (unsigned long long)(getnc_state->min_usn+1)); 1418 1419 if (extra_filter) { 1420 search_filter = talloc_asprintf(mem_ctx, "(&%s(%s))", search_filter, extra_filter); 1421 } 1422 1423 if (req10->replica_flags & DRSUAPI_DRS_CRITICAL_ONLY) { 1424 search_filter = talloc_asprintf(mem_ctx, 1425 "(&%s(isCriticalSystemObject=TRUE))", 1426 search_filter); 1427 } 1428 1429 if (req10->replica_flags & DRSUAPI_DRS_ASYNC_REP) { 1430 scope = LDB_SCOPE_BASE; 1431 } 1432 1433 if (!search_dn) { 1434 search_dn = getnc_state->ncRoot_dn; 1435 } 1436 1437 DEBUG(2,(__location__ ": getncchanges on %s using filter %s\n", 1438 ldb_dn_get_linearized(getnc_state->ncRoot_dn), search_filter)); 1439 ret = drsuapi_search_with_extended_dn(b_state->sam_ctx, getnc_state, search_res, 1440 search_dn, scope, attrs, 1441 search_filter); 1442 if (ret != LDB_SUCCESS) { 1443 return WERR_DS_DRA_INTERNAL_ERROR; 1444 } 1445 1446 return WERR_OK; 1447 } 1448 1449 /** 1450 * Collects object for normal replication cycle. 1451 */ 1452 static WERROR getncchanges_collect_objects_exop(struct drsuapi_bind_state *b_state, 1453 TALLOC_CTX *mem_ctx, 1454 struct drsuapi_DsGetNCChangesRequest10 *req10, 1455 struct drsuapi_DsGetNCChangesCtr6 *ctr6, 1456 struct ldb_dn *search_dn, 1457 const char *extra_filter, 1458 struct ldb_result **search_res) 1459 { 1460 /* we have nothing to do in case of ex-op failure */ 1461 if (ctr6->extended_ret != DRSUAPI_EXOP_ERR_SUCCESS) { 1462 return WERR_OK; 1463 } 1464 1465 /* TODO: implement extended op specific collection 1466 * of objects. Right now we just normal procedure 1467 * for collecting objects */ 1468 return getncchanges_collect_objects(b_state, mem_ctx, req10, search_dn, extra_filter, search_res); 1469 } 1470 1164 1471 /* 1165 1472 drsuapi_DsGetNCChanges … … 1178 1485 NTSTATUS status; 1179 1486 DATA_BLOB session_key; 1180 const char *attrs[] = { "uSNChanged",1181 "objectGUID" ,1182 NULL };1183 1487 WERROR werr; 1184 1488 struct dcesrv_handle *h; … … 1198 1502 struct dom_sid *user_sid; 1199 1503 bool is_secret_request; 1504 bool is_gc_pas_request; 1505 struct drsuapi_changed_objects *changes; 1506 time_t max_wait; 1507 time_t start = time(NULL); 1508 bool max_wait_reached = false; 1509 bool has_get_all_changes = false; 1510 struct GUID invocation_id; 1200 1511 1201 1512 DCESRV_PULL_HANDLE_WERR(h, r->in.bind_handle, DRSUAPI_BIND_HANDLE); … … 1203 1514 1204 1515 sam_ctx = b_state->sam_ctx_system?b_state->sam_ctx_system:b_state->sam_ctx; 1516 1517 invocation_id = *(samdb_ntds_invocation_id(sam_ctx)); 1205 1518 1206 1519 *r->out.level_out = 6; … … 1260 1573 user_sid = &dce_call->conn->auth_state.session_info->security_token->sids[PRIMARY_USER_SID_INDEX]; 1261 1574 1575 /* all clients must have GUID_DRS_GET_CHANGES */ 1262 1576 werr = drs_security_access_check_nc_root(b_state->sam_ctx, 1263 1577 mem_ctx, … … 1267 1581 if (!W_ERROR_IS_OK(werr)) { 1268 1582 return werr; 1583 } 1584 1585 /* allowed if the GC PAS and client has 1586 GUID_DRS_GET_FILTERED_ATTRIBUTES */ 1587 werr = dcesrv_drsuapi_is_gc_pas_request(b_state, req10, &is_gc_pas_request); 1588 if (!W_ERROR_IS_OK(werr)) { 1589 return werr; 1590 } 1591 if (is_gc_pas_request) { 1592 werr = drs_security_access_check_nc_root(b_state->sam_ctx, 1593 mem_ctx, 1594 dce_call->conn->auth_state.session_info->security_token, 1595 req10->naming_context, 1596 GUID_DRS_GET_FILTERED_ATTRIBUTES); 1597 if (W_ERROR_IS_OK(werr)) { 1598 goto allowed; 1599 } 1269 1600 } 1270 1601 … … 1281 1612 if (!W_ERROR_IS_OK(werr)) { 1282 1613 return werr; 1283 } 1284 } 1285 1614 } else { 1615 has_get_all_changes = true; 1616 } 1617 } 1618 1619 allowed: 1286 1620 /* for non-administrator replications, check that they have 1287 1621 given the correct source_dsa_invocation_id */ … … 1299 1633 req10->uptodateness_vector = NULL; 1300 1634 } 1635 1636 if (GUID_all_zero(&req10->source_dsa_invocation_id)) { 1637 req10->source_dsa_invocation_id = invocation_id; 1638 } 1639 1640 if (!GUID_equal(&req10->source_dsa_invocation_id, &invocation_id)) { 1641 /* 1642 * The given highwatermark is only valid relative to the 1643 * specified source_dsa_invocation_id. 1644 */ 1645 ZERO_STRUCT(req10->highwatermark); 1646 } 1301 1647 1302 1648 getnc_state = b_state->getncchanges_state; … … 1315 1661 } 1316 1662 1663 if (getnc_state) { 1664 ret = drsuapi_DsReplicaHighWaterMark_cmp(&getnc_state->last_hwm, 1665 &req10->highwatermark); 1666 if (ret != 0) { 1667 DEBUG(0,(__location__ ": DsGetNCChanges 2nd replication " 1668 "on DN %s %s highwatermark (last_dn %s)\n", 1669 ldb_dn_get_linearized(getnc_state->ncRoot_dn), 1670 (ret > 0) ? "older" : "newer", 1671 ldb_dn_get_linearized(getnc_state->last_dn))); 1672 talloc_free(getnc_state); 1673 getnc_state = NULL; 1674 } 1675 } 1676 1317 1677 if (getnc_state == NULL) { 1318 1678 getnc_state = talloc_zero(b_state, struct drsuapi_getncchanges_state); … … 1327 1687 ldb_get_schema_basedn(b_state->sam_ctx)); 1328 1688 getnc_state->is_schema_nc = (0 == ret); 1689 1690 if (req10->extended_op != DRSUAPI_EXOP_NONE) { 1691 r->out.ctr->ctr6.extended_ret = DRSUAPI_EXOP_ERR_SUCCESS; 1692 } 1329 1693 1330 1694 /* … … 1343 1707 break; 1344 1708 case DRSUAPI_EXOP_REPL_SECRET: 1345 werr = getncchanges_repl_secret(b_state, mem_ctx, req10, user_sid, &r->out.ctr->ctr6); 1709 werr = getncchanges_repl_secret(b_state, mem_ctx, req10, 1710 user_sid, 1711 &r->out.ctr->ctr6, 1712 has_get_all_changes); 1346 1713 r->out.result = werr; 1347 1714 W_ERROR_NOT_OK_RETURN(werr); … … 1392 1759 1393 1760 if (getnc_state->guids == NULL) { 1394 char* search_filter;1395 enum ldb_scope scope = LDB_SCOPE_SUBTREE;1396 1761 const char *extra_filter; 1397 struct ldb_result *search_res; 1398 1399 if (req10->extended_op == DRSUAPI_EXOP_REPL_OBJ || 1400 req10->extended_op == DRSUAPI_EXOP_REPL_SECRET) { 1401 scope = LDB_SCOPE_BASE; 1402 } 1762 struct ldb_result *search_res = NULL; 1403 1763 1404 1764 extra_filter = lpcfg_parm_string(dce_call->conn->dce_ctx->lp_ctx, NULL, "drs", "object filter"); 1405 1765 1406 1766 getnc_state->min_usn = req10->highwatermark.highest_usn; 1407 1408 /* Construct response. */ 1409 search_filter = talloc_asprintf(mem_ctx, 1410 "(uSNChanged>=%llu)", 1411 (unsigned long long)(getnc_state->min_usn+1)); 1412 1413 if (extra_filter) { 1414 search_filter = talloc_asprintf(mem_ctx, "(&%s(%s))", search_filter, extra_filter); 1415 } 1416 1417 if (req10->replica_flags & DRSUAPI_DRS_CRITICAL_ONLY) { 1418 search_filter = talloc_asprintf(mem_ctx, 1419 "(&%s(isCriticalSystemObject=TRUE))", 1420 search_filter); 1421 } 1422 1423 if (req10->replica_flags & DRSUAPI_DRS_ASYNC_REP) { 1424 scope = LDB_SCOPE_BASE; 1425 } 1426 1427 if (!search_dn) { 1428 search_dn = getnc_state->ncRoot_dn; 1429 } 1430 1431 DEBUG(2,(__location__ ": getncchanges on %s using filter %s\n", 1432 ldb_dn_get_linearized(getnc_state->ncRoot_dn), search_filter)); 1433 ret = drsuapi_search_with_extended_dn(sam_ctx, getnc_state, &search_res, 1434 search_dn, scope, attrs, 1435 search_filter); 1436 if (ret != LDB_SUCCESS) { 1437 return WERR_DS_DRA_INTERNAL_ERROR; 1438 } 1439 1440 if (req10->replica_flags & DRSUAPI_DRS_GET_ANC) { 1441 TYPESAFE_QSORT(search_res->msgs, 1442 search_res->count, 1443 site_res_cmp_parent_order); 1767 getnc_state->max_usn = getnc_state->min_usn; 1768 1769 getnc_state->final_udv = talloc_zero(getnc_state, 1770 struct drsuapi_DsReplicaCursor2CtrEx); 1771 if (getnc_state->final_udv == NULL) { 1772 return WERR_NOMEM; 1773 } 1774 werr = get_nc_changes_udv(sam_ctx, getnc_state->ncRoot_dn, 1775 getnc_state->final_udv); 1776 if (!W_ERROR_IS_OK(werr)) { 1777 return werr; 1778 } 1779 1780 if (req10->extended_op == DRSUAPI_EXOP_NONE) { 1781 werr = getncchanges_collect_objects(b_state, mem_ctx, req10, 1782 search_dn, extra_filter, 1783 &search_res); 1444 1784 } else { 1445 TYPESAFE_QSORT(search_res->msgs, 1446 search_res->count, 1447 site_res_cmp_usn_order); 1448 } 1785 werr = getncchanges_collect_objects_exop(b_state, mem_ctx, req10, 1786 &r->out.ctr->ctr6, 1787 search_dn, extra_filter, 1788 &search_res); 1789 } 1790 W_ERROR_NOT_OK_RETURN(werr); 1449 1791 1450 1792 /* extract out the GUIDs list */ 1451 getnc_state->num_records = search_res ->count;1793 getnc_state->num_records = search_res ? search_res->count : 0; 1452 1794 getnc_state->guids = talloc_array(getnc_state, struct GUID, getnc_state->num_records); 1453 1795 W_ERROR_HAVE_NO_MEMORY(getnc_state->guids); 1454 1796 1797 changes = talloc_array(getnc_state, 1798 struct drsuapi_changed_objects, 1799 getnc_state->num_records); 1800 W_ERROR_HAVE_NO_MEMORY(changes); 1801 1455 1802 for (i=0; i<getnc_state->num_records; i++) { 1456 getnc_state->guids[i] = samdb_result_guid(search_res->msgs[i], "objectGUID"); 1803 changes[i].dn = search_res->msgs[i]->dn; 1804 changes[i].guid = samdb_result_guid(search_res->msgs[i], "objectGUID"); 1805 changes[i].usn = ldb_msg_find_attr_as_uint64(search_res->msgs[i], "uSNChanged", 0); 1806 1807 if (changes[i].usn > getnc_state->max_usn) { 1808 getnc_state->max_usn = changes[i].usn; 1809 } 1810 } 1811 1812 if (req10->replica_flags & DRSUAPI_DRS_GET_ANC) { 1813 LDB_TYPESAFE_QSORT(changes, 1814 getnc_state->num_records, 1815 getnc_state, 1816 site_res_cmp_anc_order); 1817 } else { 1818 LDB_TYPESAFE_QSORT(changes, 1819 getnc_state->num_records, 1820 getnc_state, 1821 site_res_cmp_usn_order); 1822 } 1823 1824 for (i=0; i < getnc_state->num_records; i++) { 1825 getnc_state->guids[i] = changes[i].guid; 1457 1826 if (GUID_all_zero(&getnc_state->guids[i])) { 1458 DEBUG(2,("getncchanges: bad objectGUID from %s\n", ldb_dn_get_linearized(search_res->msgs[i]->dn))); 1827 DEBUG(2,("getncchanges: bad objectGUID from %s\n", 1828 ldb_dn_get_linearized(search_res->msgs[i]->dn))); 1459 1829 return WERR_DS_DRA_INTERNAL_ERROR; 1460 1830 } 1461 1831 } 1462 1832 1833 getnc_state->final_hwm.tmp_highest_usn = getnc_state->max_usn; 1834 getnc_state->final_hwm.reserved_usn = 0; 1835 getnc_state->final_hwm.highest_usn = getnc_state->max_usn; 1463 1836 1464 1837 talloc_free(search_res); 1465 1466 getnc_state->uptodateness_vector = talloc_steal(getnc_state, req10->uptodateness_vector);1467 if (getnc_state->uptodateness_vector) { 1468 /* make sure its sorted */1469 TYPESAFE_QSORT(getnc_state->uptodateness_vector->cursors,1470 getnc_state->uptodateness_vector->count,1471 drsuapi_DsReplicaCursor_compare);1472 }1838 talloc_free(changes); 1839 } 1840 1841 if (req10->uptodateness_vector) { 1842 /* make sure its sorted */ 1843 TYPESAFE_QSORT(req10->uptodateness_vector->cursors, 1844 req10->uptodateness_vector->count, 1845 drsuapi_DsReplicaCursor_compare); 1473 1846 } 1474 1847 … … 1517 1890 max_links = lpcfg_parm_int(dce_call->conn->dce_ctx->lp_ctx, NULL, "drs", "max link sync", 1500); 1518 1891 1892 /* 1893 * Maximum time that we can spend in a getncchanges 1894 * in order to avoid timeout of the other part. 1895 * 10 seconds by default. 1896 */ 1897 max_wait = lpcfg_parm_int(dce_call->conn->dce_ctx->lp_ctx, NULL, "drs", "max work time", 10); 1519 1898 for (i=getnc_state->num_processed; 1520 1899 i<getnc_state->num_records && 1521 1900 !null_scope && 1522 (r->out.ctr->ctr6.object_count < max_objects); 1901 (r->out.ctr->ctr6.object_count < max_objects) 1902 && !max_wait_reached; 1523 1903 i++) { 1524 1904 int uSN; … … 1559 1939 msg = msg_res->msgs[0]; 1560 1940 1941 max_wait_reached = (time(NULL) - start > max_wait); 1942 1561 1943 werr = get_nc_changes_build_object(obj, msg, 1562 1944 sam_ctx, getnc_state->ncRoot_dn, … … 1565 1947 req10->replica_flags, 1566 1948 req10->partial_attribute_set, 1567 getnc_state->uptodateness_vector, 1568 req10->extended_op); 1949 req10->uptodateness_vector, 1950 req10->extended_op, 1951 max_wait_reached); 1569 1952 if (!W_ERROR_IS_OK(werr)) { 1570 1953 return werr; … … 1578 1961 &getnc_state->la_list, 1579 1962 &getnc_state->la_count, 1580 getnc_state->uptodateness_vector);1963 req10->uptodateness_vector); 1581 1964 if (!W_ERROR_IS_OK(werr)) { 1582 1965 return werr; … … 1584 1967 1585 1968 uSN = ldb_msg_find_attr_as_int(msg, "uSNChanged", -1); 1969 if (uSN > getnc_state->max_usn) { 1970 /* 1971 * Only report the max_usn we had at the start 1972 * of the replication cycle. 1973 * 1974 * If this object has changed lately we better 1975 * let the destination dsa refetch the change. 1976 * This is better than the risk of loosing some 1977 * objects or linked attributes. 1978 */ 1979 uSN = 0; 1980 } 1586 1981 if (uSN > r->out.ctr->ctr6.new_highwatermark.tmp_highest_usn) { 1587 1982 r->out.ctr->ctr6.new_highwatermark.tmp_highest_usn = uSN; 1588 } 1589 if (uSN > getnc_state->highest_usn) { 1590 getnc_state->highest_usn = uSN; 1983 r->out.ctr->ctr6.new_highwatermark.reserved_usn = 0; 1591 1984 } 1592 1985 … … 1604 1997 currentObject = &obj->next_object; 1605 1998 1999 DEBUG(8,(__location__ ": replicating object %s\n", ldb_dn_get_linearized(msg->dn))); 2000 1606 2001 talloc_free(getnc_state->last_dn); 1607 getnc_state->last_dn = ldb_dn_copy(getnc_state, msg->dn); 1608 1609 DEBUG(8,(__location__ ": replicating object %s\n", ldb_dn_get_linearized(msg->dn))); 2002 getnc_state->last_dn = talloc_move(getnc_state, &msg->dn); 1610 2003 1611 2004 talloc_free(msg_res); … … 1625 2018 GUID_string(mem_ctx, &req10->destination_dsa_guid))); 1626 2019 ureq.naming_context = ncRoot; 1627 ureq.dest_dsa_dns_name = talloc_asprintf(mem_ctx, "%s._msdcs.%s", 1628 GUID_string(mem_ctx, &req10->destination_dsa_guid), 1629 lpcfg_dnsdomain(dce_call->conn->dce_ctx->lp_ctx)); 2020 ureq.dest_dsa_dns_name = samdb_ntds_msdcs_dns_name(b_state->sam_ctx, mem_ctx, 2021 &req10->destination_dsa_guid); 1630 2022 if (!ureq.dest_dsa_dns_name) { 1631 2023 return WERR_NOMEM; … … 1643 2035 werr = drsuapi_UpdateRefs(b_state, mem_ctx, &ureq); 1644 2036 if (!W_ERROR_IS_OK(werr)) { 1645 DEBUG(0,(__location__ ": Failed UpdateRefs in DsGetNCChanges - %s\n", 2037 DEBUG(0,(__location__ ": Failed UpdateRefs on %s for %s in DsGetNCChanges - %s\n", 2038 drs_ObjectIdentifier_to_string(mem_ctx, ncRoot), ureq.dest_dsa_dns_name, 1646 2039 win_errstr(werr))); 1647 2040 } … … 1689 2082 talloc_steal(mem_ctx, getnc_state->la_list); 1690 2083 1691 r->out.ctr->ctr6.uptodateness_vector = talloc(mem_ctx, struct drsuapi_DsReplicaCursor2CtrEx); 1692 r->out.ctr->ctr6.new_highwatermark.highest_usn = r->out.ctr->ctr6.new_highwatermark.tmp_highest_usn; 1693 1694 werr = get_nc_changes_udv(sam_ctx, getnc_state->ncRoot_dn, 1695 r->out.ctr->ctr6.uptodateness_vector); 1696 if (!W_ERROR_IS_OK(werr)) { 1697 return werr; 1698 } 2084 r->out.ctr->ctr6.new_highwatermark = getnc_state->final_hwm; 2085 r->out.ctr->ctr6.uptodateness_vector = talloc_move(mem_ctx, 2086 &getnc_state->final_udv); 1699 2087 1700 2088 talloc_free(getnc_state); 1701 2089 b_state->getncchanges_state = NULL; 2090 } else { 2091 ret = drsuapi_DsReplicaHighWaterMark_cmp(&r->out.ctr->ctr6.old_highwatermark, 2092 &r->out.ctr->ctr6.new_highwatermark); 2093 if (ret == 0) { 2094 /* 2095 * We need to make sure that we never return the 2096 * same highwatermark within the same replication 2097 * cycle more than once. Otherwise we cannot detect 2098 * when the client uses an unexptected highwatermark. 2099 * 2100 * This is a HACK which is needed because our 2101 * object ordering is wrong and set tmp_highest_usn 2102 * to a value that is higher than what we already 2103 * sent to the client (destination dsa). 2104 */ 2105 r->out.ctr->ctr6.new_highwatermark.reserved_usn += 1; 2106 } 2107 2108 getnc_state->last_hwm = r->out.ctr->ctr6.new_highwatermark; 1702 2109 } 1703 2110 … … 1706 2113 r->out.ctr->ctr6.nc_object_count = 0; 1707 2114 ZERO_STRUCT(r->out.ctr->ctr6.new_highwatermark); 1708 r->out.ctr->ctr6.extended_ret = DRSUAPI_EXOP_ERR_SUCCESS;1709 2115 } 1710 2116 -
vendor/current/source4/rpc_server/drsuapi/updaterefs.c
r740 r988 51 51 52 52 for (i=0; i<reps.count; i++) { 53 if (GUID_ compare(&dest->source_dsa_obj_guid,54 &reps.r[i].ctr.ctr1.source_dsa_obj_guid) == 0) {53 if (GUID_equal(&dest->source_dsa_obj_guid, 54 &reps.r[i].ctr.ctr1.source_dsa_obj_guid)) { 55 55 if (options & DRSUAPI_DRS_GETCHG_CHECK) { 56 56 return WERR_OK; … … 98 98 99 99 for (i=0; i<reps.count; i++) { 100 if (GUID_compare(dest_guid, &reps.r[i].ctr.ctr1.source_dsa_obj_guid) == 0) { 100 if (GUID_equal(dest_guid, 101 &reps.r[i].ctr.ctr1.source_dsa_obj_guid)) { 101 102 if (i+1 < reps.count) { 102 103 memmove(&reps.r[i], &reps.r[i+1], sizeof(reps.r[i])*(reps.count-(i+1))); … … 121 122 } 122 123 123 /* 124 drsuapi_DsReplicaUpdateRefs - a non RPC version callable from getncchanges 125 */ 124 /** 125 * @brief Update the references for the given NC and the destination DSA object 126 * 127 * This function is callable from non RPC functions (ie. getncchanges), it 128 * will validate the request to update reference and then will add/del a repsTo 129 * to the specified server referenced by its DSA GUID in the request. 130 * 131 * @param[in] b_state A bind_state object 132 * 133 * @param[in] mem_ctx A talloc context for memory allocation 134 * 135 * @param[in] req A drsuapi_DsReplicaUpdateRefsRequest1 136 * object which NC, which server and which 137 * action (add/delete) should be performed 138 * 139 * @return WERR_OK is success, different error 140 * otherwise. 141 */ 126 142 WERROR drsuapi_UpdateRefs(struct drsuapi_bind_state *b_state, TALLOC_CTX *mem_ctx, 127 143 struct drsuapi_DsReplicaUpdateRefsRequest1 *req) 128 144 { 129 145 WERROR werr; 146 int ret; 130 147 struct ldb_dn *dn; 148 struct ldb_dn *nc_root; 131 149 struct ldb_context *sam_ctx = b_state->sam_ctx_system?b_state->sam_ctx_system:b_state->sam_ctx; 132 150 … … 136 154 drs_ObjectIdentifier_to_string(mem_ctx, req->naming_context))); 137 155 138 dn = ldb_dn_new(mem_ctx, sam_ctx, req->naming_context->dn); 139 if (dn == NULL) { 140 return WERR_DS_INVALID_DN_SYNTAX; 156 /* 157 * 4.1.26.2 Server Behavior of the IDL_DRSUpdateRefs Method 158 * Implements the input validation checks 159 */ 160 if (GUID_all_zero(&req->dest_dsa_guid)) { 161 return WERR_DS_DRA_INVALID_PARAMETER; 162 } 163 164 /* FIXME it seems that we should check the length of the stuff too*/ 165 if (req->dest_dsa_dns_name == NULL) { 166 return WERR_DS_DRA_INVALID_PARAMETER; 167 } 168 169 if (!(req->options & (DRSUAPI_DRS_DEL_REF|DRSUAPI_DRS_ADD_REF))) { 170 return WERR_DS_DRA_INVALID_PARAMETER; 171 } 172 173 dn = drs_ObjectIdentifier_to_dn(mem_ctx, sam_ctx, req->naming_context); 174 W_ERROR_HAVE_NO_MEMORY(dn); 175 ret = dsdb_find_nc_root(sam_ctx, dn, dn, &nc_root); 176 if (ret != LDB_SUCCESS) { 177 DEBUG(2, ("Didn't find a nc for %s\n", ldb_dn_get_linearized(dn))); 178 return WERR_DS_DRA_BAD_NC; 179 } 180 if (ldb_dn_compare(dn, nc_root) != 0) { 181 DEBUG(2, ("dn %s is not equal to %s\n", ldb_dn_get_linearized(dn), ldb_dn_get_linearized(nc_root))); 182 return WERR_DS_DRA_BAD_NC; 141 183 } 142 184 … … 144 186 DEBUG(0,(__location__ ": Failed to start transaction on samdb: %s\n", 145 187 ldb_errstring(sam_ctx))); 146 return WERR_DS_DRA_INTERNAL_ERROR; 188 return WERR_DS_DRA_INTERNAL_ERROR; 147 189 } 148 190 -
vendor/current/source4/rpc_server/drsuapi/writespn.c
r740 r988 58 58 krb5_error_code kerr; 59 59 krb5_principal principal; 60 const krb5_data *component; 60 61 const char *dns_name, *dnsHostName; 61 62 … … 113 114 } 114 115 115 if ( principal->name.name_string.len!= 2) {116 if (krb5_princ_size(krb_ctx, principal) != 2) { 116 117 krb5_free_principal(krb_ctx, principal); 117 118 krb5_free_context(krb_ctx); … … 120 121 } 121 122 122 dns_name = principal->name.name_string.val[1]; 123 component = krb5_princ_component(krb_ctx, principal, 1); 124 dns_name = (const char *)component->data; 123 125 124 126 if (strcasecmp(dns_name, dnsHostName) != 0) { … … 146 148 struct drsuapi_bind_state *b_state; 147 149 struct dcesrv_handle *h; 148 enum security_user_level level;149 150 150 151 *r->out.level_out = r->in.level; … … 155 156 r->out.res = talloc(mem_ctx, union drsuapi_DsWriteAccountSpnResult); 156 157 W_ERROR_HAVE_NO_MEMORY(r->out.res); 157 158 level = security_session_user_level(dce_call->conn->auth_state.session_info, NULL);159 158 160 159 switch (r->in.level) { -
vendor/current/source4/rpc_server/echo/rpc_echo.c
r740 r988 27 27 #include "lib/events/events.h" 28 28 29 #define DCESRV_INTERFACE_RPCECHO_BIND(call, iface) \ 30 dcesrv_interface_rpcecho_bind(call, iface) 31 static NTSTATUS dcesrv_interface_rpcecho_bind(struct dcesrv_call_state *dce_call, 32 const struct dcesrv_interface *iface) 33 { 34 return dcesrv_interface_bind_allow_connect(dce_call, iface); 35 } 29 36 30 37 static NTSTATUS dcesrv_echo_AddOne(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, struct echo_AddOne *r) … … 193 200 p->r = r; 194 201 195 event_add_timed(dce_call->event_ctx, p,202 tevent_add_timer(dce_call->event_ctx, p, 196 203 timeval_add(&dce_call->time, r->in.seconds, 0), 197 204 echo_TestSleep_handler, p); -
vendor/current/source4/rpc_server/epmapper/rpc_epmapper.c
r740 r988 25 25 #include "rpc_server/dcerpc_server.h" 26 26 27 #define DCESRV_INTERFACE_EPMAPPER_BIND(call, iface) \ 28 dcesrv_interface_epmapper_bind(call, iface) 29 static NTSTATUS dcesrv_interface_epmapper_bind(struct dcesrv_call_state *dce_call, 30 const struct dcesrv_interface *iface) 31 { 32 return dcesrv_interface_bind_allow_connect(dce_call, iface); 33 } 34 27 35 typedef uint32_t error_status_t; 28 36 … … 51 59 for (d=endpoint_list; d; d=d->next) { 52 60 struct dcesrv_if_list *iface; 53 struct dcerpc_binding *description;54 61 55 62 for (iface=d->interface_list;iface;iface=iface->next) { 63 struct dcerpc_binding *description; 64 56 65 (*eps) = talloc_realloc(mem_ctx, 57 66 *eps, … … 63 72 (*eps)[total].name = iface->iface.name; 64 73 65 description = d->ep_description; 66 description->object = iface->iface.syntax_id; 74 description = dcerpc_binding_dup(*eps, d->ep_description); 75 if (description == NULL) { 76 return 0; 77 } 78 79 status = dcerpc_binding_set_abstract_syntax(description, 80 &iface->iface.syntax_id); 81 if (!NT_STATUS_IS_OK(status)) { 82 return 0; 83 } 67 84 68 85 status = dcerpc_binding_build_tower(*eps, description, &(*eps)[total].ep); 69 if (NT_STATUS_IS_ERR(status)) { 70 DEBUG(1, ("Unable to build tower for %s\n", iface->iface.name)); 86 TALLOC_FREE(description); 87 if (!NT_STATUS_IS_OK(status)) { 88 DEBUG(1, ("Unable to build tower for %s - %s\n", 89 iface->iface.name, nt_errstr(status))); 71 90 continue; 72 91 } … … 202 221 203 222 if (floors[1].lhs.protocol != EPM_PROTOCOL_UUID || 204 !GUID_equal(&ndr_syntax.uuid, &ndr_transfer_syntax .uuid) ||205 ndr_syntax.if_version != ndr_transfer_syntax .if_version) {223 !GUID_equal(&ndr_syntax.uuid, &ndr_transfer_syntax_ndr.uuid) || 224 ndr_syntax.if_version != ndr_transfer_syntax_ndr.if_version) { 206 225 goto failed; 207 226 } -
vendor/current/source4/rpc_server/handles.c
r740 r988 47 47 sid = &context->conn->auth_state.session_info->security_token->sids[PRIMARY_USER_SID_INDEX]; 48 48 49 h = talloc (context->assoc_group, struct dcesrv_handle);49 h = talloc_zero(context->conn->assoc_group, struct dcesrv_handle); 50 50 if (!h) { 51 51 return NULL; … … 57 57 return NULL; 58 58 } 59 h->assoc_group = context-> assoc_group;59 h->assoc_group = context->conn->assoc_group; 60 60 h->iface = context->iface; 61 61 h->wire_handle.handle_type = handle_type; 62 62 h->wire_handle.uuid = GUID_random(); 63 63 64 DLIST_ADD(context-> assoc_group->handles, h);64 DLIST_ADD(context->conn->assoc_group->handles, h); 65 65 66 66 talloc_set_destructor(h, dcesrv_handle_destructor); … … 83 83 sid = &context->conn->auth_state.session_info->security_token->sids[PRIMARY_USER_SID_INDEX]; 84 84 85 if ( policy_handle_empty(p)) {85 if (ndr_policy_handle_empty(p)) { 86 86 /* TODO: we should probably return a NULL handle here */ 87 87 return dcesrv_handle_new(context, handle_type); 88 88 } 89 89 90 for (h=context-> assoc_group->handles; h; h=h->next) {90 for (h=context->conn->assoc_group->handles; h; h=h->next) { 91 91 if (h->wire_handle.handle_type == p->handle_type && 92 92 GUID_equal(&p->uuid, &h->wire_handle.uuid)) { -
vendor/current/source4/rpc_server/lsa/dcesrv_lsa.c
r740 r988 8 8 Copyright (C) Andrew Tridgell 2004 9 9 Copyright (C) Andrew Bartlett <abartlet@samba.org> 2004-2008 10 10 11 11 This program is free software; you can redistribute it and/or modify 12 12 it under the terms of the GNU General Public License as published by 13 13 the Free Software Foundation; either version 3 of the License, or 14 14 (at your option) any later version. 15 15 16 16 This program is distributed in the hope that it will be useful, 17 17 but WITHOUT ANY WARRANTY; without even the implied warranty of 18 18 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 19 19 GNU General Public License for more details. 20 20 21 21 You should have received a copy of the GNU General Public License 22 22 along with this program. If not, see <http://www.gnu.org/licenses/>. … … 32 32 #include "dsdb/common/util.h" 33 33 #include "libcli/security/session.h" 34 #include "kdc/kdc-policy.h" 34 #include "libcli/lsarpc/util_lsarpc.h" 35 #include "lib/messaging/irpc.h" 36 #include "libds/common/roles.h" 37 38 #define DCESRV_INTERFACE_LSARPC_BIND(call, iface) \ 39 dcesrv_interface_lsarpc_bind(call, iface) 40 static NTSTATUS dcesrv_interface_lsarpc_bind(struct dcesrv_call_state *dce_call, 41 const struct dcesrv_interface *iface) 42 { 43 return dcesrv_interface_bind_reject_connect(dce_call, iface); 44 } 35 45 36 46 /* … … 73 83 It uses the same logic, but with samba4 helper functions 74 84 */ 75 static NTSTATUS dcesrv_build_lsa_sd(TALLOC_CTX *mem_ctx, 85 static NTSTATUS dcesrv_build_lsa_sd(TALLOC_CTX *mem_ctx, 76 86 struct security_descriptor **sd, 77 struct dom_sid *sid, 87 struct dom_sid *sid, 78 88 uint32_t sid_access) 79 89 { … … 85 95 86 96 status = dom_sid_split_rid(tmp_ctx, sid, &domain_sid, &rid); 87 NT_STATUS_NOT_OK_RETURN_AND_FREE(status, tmp_ctx); 97 if (!NT_STATUS_IS_OK(status)) { 98 TALLOC_FREE(tmp_ctx); 99 return status; 100 } 88 101 89 102 domain_admins_sid = dom_sid_add_rid(tmp_ctx, domain_sid, DOMAIN_RID_ADMINS); 90 NT_STATUS_HAVE_NO_MEMORY_AND_FREE(domain_admins_sid, tmp_ctx); 103 if (domain_admins_sid == NULL) { 104 TALLOC_FREE(tmp_ctx); 105 return NT_STATUS_NO_MEMORY; 106 } 91 107 92 108 domain_admins_sid_str = dom_sid_string(tmp_ctx, domain_admins_sid); 93 NT_STATUS_HAVE_NO_MEMORY_AND_FREE(domain_admins_sid_str, tmp_ctx); 94 109 if (domain_admins_sid_str == NULL) { 110 TALLOC_FREE(tmp_ctx); 111 return NT_STATUS_NO_MEMORY; 112 } 113 95 114 sidstr = dom_sid_string(tmp_ctx, sid); 96 NT_STATUS_HAVE_NO_MEMORY_AND_FREE(sidstr, tmp_ctx); 97 115 if (sidstr == NULL) { 116 TALLOC_FREE(tmp_ctx); 117 return NT_STATUS_NO_MEMORY; 118 } 119 98 120 *sd = security_descriptor_dacl_create(mem_ctx, 99 121 0, sidstr, NULL, … … 102 124 SEC_ACE_TYPE_ACCESS_ALLOWED, 103 125 SEC_GENERIC_EXECUTE | SEC_GENERIC_READ, 0, 104 126 105 127 SID_BUILTIN_ADMINISTRATORS, 106 128 SEC_ACE_TYPE_ACCESS_ALLOWED, 107 129 SEC_GENERIC_ALL, 0, 108 130 109 131 SID_BUILTIN_ACCOUNT_OPERATORS, 110 132 SEC_ACE_TYPE_ACCESS_ALLOWED, 111 133 SEC_GENERIC_ALL, 0, 112 134 113 135 domain_admins_sid_str, 114 136 SEC_ACE_TYPE_ACCESS_ALLOWED, … … 128 150 129 151 130 static NTSTATUS dcesrv_lsa_EnumAccountRights(struct dcesrv_call_state *dce_call, 152 static NTSTATUS dcesrv_lsa_EnumAccountRights(struct dcesrv_call_state *dce_call, 131 153 TALLOC_CTX *mem_ctx, 132 154 struct lsa_EnumAccountRights *r); 133 155 134 static NTSTATUS dcesrv_lsa_AddRemoveAccountRights(struct dcesrv_call_state *dce_call, 156 static NTSTATUS dcesrv_lsa_AddRemoveAccountRights(struct dcesrv_call_state *dce_call, 135 157 TALLOC_CTX *mem_ctx, 136 158 struct lsa_policy_state *state, … … 139 161 const struct lsa_RightSet *rights); 140 162 141 /* 142 lsa_Close 163 /* 164 lsa_Close 143 165 */ 144 166 static NTSTATUS dcesrv_lsa_Close(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, 145 167 struct lsa_Close *r) 146 168 { 169 enum dcerpc_transport_t transport = 170 dcerpc_binding_get_transport(dce_call->conn->endpoint->ep_description); 147 171 struct dcesrv_handle *h; 148 172 173 if (transport != NCACN_NP && transport != NCALRPC) { 174 DCESRV_FAULT(DCERPC_FAULT_ACCESS_DENIED); 175 } 176 149 177 *r->out.handle = *r->in.handle; 150 178 … … 159 187 160 188 161 /* 162 lsa_Delete 189 /* 190 lsa_Delete 163 191 */ 164 192 static NTSTATUS dcesrv_lsa_Delete(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, … … 169 197 170 198 171 /* 199 /* 172 200 lsa_DeleteObject 173 201 */ … … 194 222 } 195 223 196 ret = ldb_delete(secret_state->sam_ldb, 224 ret = ldb_delete(secret_state->sam_ldb, 197 225 secret_state->secret_dn); 198 226 if (ret != LDB_SUCCESS) { … … 205 233 206 234 } else if (h->wire_handle.handle_type == LSA_HANDLE_TRUSTED_DOMAIN) { 207 struct lsa_trusted_domain_state *trusted_domain_state = 235 struct lsa_trusted_domain_state *trusted_domain_state = 208 236 talloc_get_type(h->data, struct lsa_trusted_domain_state); 209 237 ret = ldb_transaction_start(trusted_domain_state->policy->sam_ldb); … … 212 240 } 213 241 214 ret = ldb_delete(trusted_domain_state->policy->sam_ldb, 242 ret = ldb_delete(trusted_domain_state->policy->sam_ldb, 215 243 trusted_domain_state->trusted_domain_dn); 216 244 if (ret != LDB_SUCCESS) { … … 220 248 221 249 if (trusted_domain_state->trusted_domain_user_dn) { 222 ret = ldb_delete(trusted_domain_state->policy->sam_ldb, 250 ret = ldb_delete(trusted_domain_state->policy->sam_ldb, 223 251 trusted_domain_state->trusted_domain_user_dn); 224 252 if (ret != LDB_SUCCESS) { … … 246 274 247 275 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_ACCOUNT); 248 276 249 277 astate = h->data; 250 278 … … 265 293 } 266 294 267 status = dcesrv_lsa_AddRemoveAccountRights(dce_call, mem_ctx, astate->policy, 295 status = dcesrv_lsa_AddRemoveAccountRights(dce_call, mem_ctx, astate->policy, 268 296 LDB_FLAG_MOD_DELETE, astate->account_sid, 269 297 r2.out.rights); … … 279 307 280 308 return NT_STATUS_OK; 281 } 282 309 } 310 283 311 return NT_STATUS_INVALID_HANDLE; 284 312 } 285 313 286 314 287 /* 288 lsa_EnumPrivs 315 /* 316 lsa_EnumPrivs 289 317 */ 290 318 static NTSTATUS dcesrv_lsa_EnumPrivs(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, … … 292 320 { 293 321 struct dcesrv_handle *h; 294 struct lsa_policy_state *state;295 322 uint32_t i; 296 323 enum sec_privilege priv; … … 298 325 299 326 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY); 300 301 state = h->data;302 327 303 328 i = *r->in.resume_handle; … … 308 333 privname = sec_privilege_name(priv); 309 334 r->out.privs->privs = talloc_realloc(r->out.privs, 310 r->out.privs->privs, 311 struct lsa_PrivEntry, 335 r->out.privs->privs, 336 struct lsa_PrivEntry, 312 337 r->out.privs->count+1); 313 338 if (r->out.privs->privs == NULL) { … … 328 353 329 354 330 /* 331 lsa_QuerySecObj 355 /* 356 lsa_QuerySecObj 332 357 */ 333 358 static NTSTATUS dcesrv_lsa_QuerySecurity(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, … … 335 360 { 336 361 struct dcesrv_handle *h; 337 struct security_descriptor *sd; 362 const struct security_descriptor *sd = NULL; 363 uint32_t access_granted = 0; 364 struct sec_desc_buf *sdbuf = NULL; 338 365 NTSTATUS status; 339 366 struct dom_sid *sid; … … 344 371 345 372 if (h->wire_handle.handle_type == LSA_HANDLE_POLICY) { 346 status = dcesrv_build_lsa_sd(mem_ctx, &sd, sid, 0); 347 } else if (h->wire_handle.handle_type == LSA_HANDLE_ACCOUNT) { 348 status = dcesrv_build_lsa_sd(mem_ctx, &sd, sid, 373 struct lsa_policy_state *pstate = h->data; 374 375 sd = pstate->sd; 376 access_granted = pstate->access_mask; 377 378 } else if (h->wire_handle.handle_type == LSA_HANDLE_ACCOUNT) { 379 struct lsa_account_state *astate = h->data; 380 struct security_descriptor *_sd = NULL; 381 382 status = dcesrv_build_lsa_sd(mem_ctx, &_sd, sid, 349 383 LSA_ACCOUNT_ALL_ACCESS); 384 if (!NT_STATUS_IS_OK(status)) { 385 return status; 386 } 387 sd = _sd; 388 access_granted = astate->access_mask; 350 389 } else { 351 390 return NT_STATUS_INVALID_HANDLE; 352 391 } 353 NT_STATUS_NOT_OK_RETURN(status); 354 355 (*r->out.sdbuf) = talloc(mem_ctx, struct sec_desc_buf); 356 NT_STATUS_HAVE_NO_MEMORY(*r->out.sdbuf); 357 358 (*r->out.sdbuf)->sd = sd; 359 392 393 sdbuf = talloc_zero(mem_ctx, struct sec_desc_buf); 394 if (sdbuf == NULL) { 395 return NT_STATUS_NO_MEMORY; 396 } 397 398 status = security_descriptor_for_client(sdbuf, sd, r->in.sec_info, 399 access_granted, &sdbuf->sd); 400 if (!NT_STATUS_IS_OK(status)) { 401 return status; 402 } 403 404 *r->out.sdbuf = sdbuf; 405 360 406 return NT_STATUS_OK; 361 407 } 362 408 363 409 364 /* 365 lsa_SetSecObj 410 /* 411 lsa_SetSecObj 366 412 */ 367 413 static NTSTATUS dcesrv_lsa_SetSecObj(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, … … 372 418 373 419 374 /* 375 lsa_ChangePassword 420 /* 421 lsa_ChangePassword 376 422 */ 377 423 static NTSTATUS dcesrv_lsa_ChangePassword(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, … … 381 427 } 382 428 383 /* 384 dssetup_DsRoleGetPrimaryDomainInformation 429 /* 430 dssetup_DsRoleGetPrimaryDomainInformation 385 431 386 432 This is not an LSA call, but is the only call left on the DSSETUP 387 433 pipe (after the pipe was truncated), and needs lsa_get_policy_state 388 434 */ 389 static WERROR dcesrv_dssetup_DsRoleGetPrimaryDomainInformation(struct dcesrv_call_state *dce_call, 435 static WERROR dcesrv_dssetup_DsRoleGetPrimaryDomainInformation(struct dcesrv_call_state *dce_call, 390 436 TALLOC_CTX *mem_ctx, 391 437 struct dssetup_DsRoleGetPrimaryDomainInformation *r) … … 407 453 struct lsa_policy_state *state; 408 454 409 NTSTATUS status = dcesrv_lsa_get_policy_state(dce_call, mem_ctx, &state); 455 NTSTATUS status = dcesrv_lsa_get_policy_state(dce_call, mem_ctx, 456 0, /* we skip access checks */ 457 &state); 410 458 if (!NT_STATUS_IS_OK(status)) { 411 459 return ntstatus_to_werror(status); … … 421 469 role = DS_ROLE_MEMBER_SERVER; 422 470 break; 423 case ROLE_ DOMAIN_CONTROLLER:471 case ROLE_ACTIVE_DIRECTORY_DC: 424 472 if (samdb_is_pdc(state->sam_ldb)) { 425 473 role = DS_ROLE_PRIMARY_DC; … … 440 488 /* TODO: what is with dns_domain and forest and guid? */ 441 489 break; 442 case ROLE_ DOMAIN_CONTROLLER:490 case ROLE_ACTIVE_DIRECTORY_DC: 443 491 flags = DS_ROLE_PRIMARY_DS_RUNNING; 444 492 … … 446 494 flags |= DS_ROLE_PRIMARY_DS_MIXED_MODE; 447 495 } 448 496 449 497 domain = state->domain_name; 450 498 dns_domain = state->domain_dns; … … 456 504 } 457 505 458 info->basic.role = role; 506 info->basic.role = role; 459 507 info->basic.flags = flags; 460 508 info->basic.domain = domain; … … 513 561 } 514 562 515 /* 563 /* 516 564 lsa_QueryInfoPolicy2 517 565 */ … … 584 632 } 585 633 586 /* 587 lsa_QueryInfoPolicy 634 /* 635 lsa_QueryInfoPolicy 588 636 */ 589 637 static NTSTATUS dcesrv_lsa_QueryInfoPolicy(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, … … 598 646 r2.in.level = r->in.level; 599 647 r2.out.info = r->out.info; 600 648 601 649 status = dcesrv_lsa_QueryInfoPolicy2(dce_call, mem_ctx, &r2); 602 650 … … 604 652 } 605 653 606 /* 607 lsa_SetInfoPolicy 654 /* 655 lsa_SetInfoPolicy 608 656 */ 609 657 static NTSTATUS dcesrv_lsa_SetInfoPolicy(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, … … 615 663 616 664 617 /* 618 lsa_ClearAuditLog 665 /* 666 lsa_ClearAuditLog 619 667 */ 620 668 static NTSTATUS dcesrv_lsa_ClearAuditLog(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, … … 625 673 626 674 627 /* 628 lsa_CreateAccount 675 static const struct generic_mapping dcesrv_lsa_account_mapping = { 676 LSA_ACCOUNT_READ, 677 LSA_ACCOUNT_WRITE, 678 LSA_ACCOUNT_EXECUTE, 679 LSA_ACCOUNT_ALL_ACCESS 680 }; 681 682 /* 683 lsa_CreateAccount 629 684 630 685 This call does not seem to have any long-term effects, hence no database operations … … 661 716 return NT_STATUS_NO_MEMORY; 662 717 } 663 718 664 719 astate->policy = talloc_reference(astate, state); 665 720 astate->access_mask = r->in.access_mask; 721 722 /* 723 * For now we grant all requested access. 724 * 725 * We will fail at the ldb layer later. 726 */ 727 if (astate->access_mask & SEC_FLAG_MAXIMUM_ALLOWED) { 728 astate->access_mask &= ~SEC_FLAG_MAXIMUM_ALLOWED; 729 astate->access_mask |= LSA_ACCOUNT_ALL_ACCESS; 730 } 731 se_map_generic(&astate->access_mask, &dcesrv_lsa_account_mapping); 732 733 DEBUG(10,("%s: %s access desired[0x%08X] granted[0x%08X].\n", 734 __func__, dom_sid_string(mem_ctx, astate->account_sid), 735 (unsigned)r->in.access_mask, 736 (unsigned)astate->access_mask)); 666 737 667 738 ah = dcesrv_handle_new(dce_call->context, LSA_HANDLE_ACCOUNT); … … 679 750 680 751 681 /* 682 lsa_EnumAccounts 752 /* 753 lsa_EnumAccounts 683 754 */ 684 755 static NTSTATUS dcesrv_lsa_EnumAccounts(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, … … 697 768 698 769 /* NOTE: This call must only return accounts that have at least 699 one privilege set 770 one privilege set 700 771 */ 701 ret = gendb_search(state->pdb, mem_ctx, NULL, &res, attrs, 772 ret = gendb_search(state->pdb, mem_ctx, NULL, &res, attrs, 702 773 "(&(objectSid=*)(privilege=*))"); 703 774 if (ret < 0) { … … 724 795 725 796 for (i=0;i<count;i++) { 726 r->out.sids->sids[i].sid = 727 samdb_result_dom_sid(r->out.sids->sids, 797 r->out.sids->sids[i].sid = 798 samdb_result_dom_sid(r->out.sids->sids, 728 799 res[i + *r->in.resume_handle], 729 800 "objectSid"); … … 735 806 736 807 return NT_STATUS_OK; 737 738 808 } 739 809 … … 770 840 enum ndr_err_code ndr_err; 771 841 842 if (iopw->current.count != iopw->count) { 843 return NT_STATUS_INVALID_PARAMETER; 844 } 845 846 if (iopw->previous.count > iopw->current.count) { 847 return NT_STATUS_INVALID_PARAMETER; 848 } 849 850 if (iopw->previous.count == 0) { 851 /* 852 * If the previous credentials are not present 853 * we need to make a copy. 854 */ 855 iopw->previous = iopw->current; 856 } 857 858 if (iopw->previous.count < iopw->current.count) { 859 struct AuthenticationInformationArray *c = &iopw->current; 860 struct AuthenticationInformationArray *p = &iopw->previous; 861 862 /* 863 * The previous array needs to have the same size 864 * as the current one. 865 * 866 * We may have to fill with TRUST_AUTH_TYPE_NONE 867 * elements. 868 */ 869 p->array = talloc_realloc(mem_ctx, p->array, 870 struct AuthenticationInformation, 871 c->count); 872 if (p->array == NULL) { 873 return NT_STATUS_NO_MEMORY; 874 } 875 876 while (p->count < c->count) { 877 struct AuthenticationInformation *a = 878 &p->array[p->count++]; 879 880 *a = (struct AuthenticationInformation) { 881 .LastUpdateTime = p->array[0].LastUpdateTime, 882 .AuthType = TRUST_AUTH_TYPE_NONE, 883 }; 884 } 885 } 886 772 887 ndr_err = ndr_push_struct_blob(trustauth_blob, mem_ctx, 773 888 iopw, … … 787 902 struct ldb_dn **user_dn) 788 903 { 904 struct ldb_request *req; 789 905 struct ldb_message *msg; 790 906 struct ldb_dn *dn; … … 847 963 848 964 /* create the trusted_domain user account */ 849 ret = ldb_add(sam_ldb, msg); 965 ret = ldb_build_add_req(&req, sam_ldb, mem_ctx, msg, NULL, NULL, 966 ldb_op_default_callback, NULL); 967 if (ret != LDB_SUCCESS) { 968 return NT_STATUS_NO_MEMORY; 969 } 970 971 ret = ldb_request_add_control(req, DSDB_CONTROL_PERMIT_INTERDOMAIN_TRUST_UAC_OID, 972 false, NULL); 973 if (ret != LDB_SUCCESS) { 974 return NT_STATUS_NO_MEMORY; 975 } 976 977 ret = dsdb_autotransaction_request(sam_ldb, req); 850 978 if (ret != LDB_SUCCESS) { 851 979 DEBUG(0,("Failed to create user record %s: %s\n", … … 875 1003 TALLOC_CTX *mem_ctx, 876 1004 struct lsa_CreateTrustedDomainEx2 *r, 877 int op) 1005 int op, 1006 struct lsa_TrustDomainInfoAuthInfo *unencrypted_auth_info) 878 1007 { 879 1008 struct dcesrv_handle *policy_handle; … … 887 1016 const char *netbios_name; 888 1017 const char *dns_name; 889 const char *name;890 1018 DATA_BLOB trustAuthIncoming, trustAuthOutgoing, auth_blob; 891 1019 struct trustDomainPasswords auth_struct; … … 893 1021 NTSTATUS nt_status; 894 1022 struct ldb_context *sam_ldb; 1023 struct server_id *server_ids = NULL; 1024 uint32_t num_server_ids = 0; 1025 NTSTATUS status; 1026 struct dom_sid *tmp_sid1; 1027 struct dom_sid *tmp_sid2; 1028 uint32_t tmp_rid; 1029 bool ok; 1030 char *dns_encoded = NULL; 1031 char *netbios_encoded = NULL; 1032 char *sid_encoded = NULL; 895 1033 896 1034 DCESRV_PULL_HANDLE(policy_handle, r->in.policy_handle, LSA_HANDLE_POLICY); … … 906 1044 907 1045 dns_name = r->in.info->domain_name.string; 1046 if (dns_name == NULL) { 1047 return NT_STATUS_INVALID_PARAMETER; 1048 } 1049 1050 if (r->in.info->sid == NULL) { 1051 return NT_STATUS_INVALID_SID; 1052 } 1053 1054 /* 1055 * We expect S-1-5-21-A-B-C, but we don't 1056 * allow S-1-5-21-0-0-0 as this is used 1057 * for claims and compound identities. 1058 * 1059 * So we call dom_sid_split_rid() 3 times 1060 * and compare the result to S-1-5-21 1061 */ 1062 status = dom_sid_split_rid(mem_ctx, r->in.info->sid, &tmp_sid1, &tmp_rid); 1063 if (!NT_STATUS_IS_OK(status)) { 1064 return status; 1065 } 1066 status = dom_sid_split_rid(mem_ctx, tmp_sid1, &tmp_sid2, &tmp_rid); 1067 if (!NT_STATUS_IS_OK(status)) { 1068 return status; 1069 } 1070 status = dom_sid_split_rid(mem_ctx, tmp_sid2, &tmp_sid1, &tmp_rid); 1071 if (!NT_STATUS_IS_OK(status)) { 1072 return status; 1073 } 1074 ok = dom_sid_parse("S-1-5-21", tmp_sid2); 1075 if (!ok) { 1076 return NT_STATUS_INTERNAL_ERROR; 1077 } 1078 ok = dom_sid_equal(tmp_sid1, tmp_sid2); 1079 if (!ok) { 1080 return NT_STATUS_INVALID_PARAMETER; 1081 } 1082 ok = dom_sid_parse("S-1-5-21-0-0-0", tmp_sid2); 1083 if (!ok) { 1084 return NT_STATUS_INTERNAL_ERROR; 1085 } 1086 ok = !dom_sid_equal(r->in.info->sid, tmp_sid2); 1087 if (!ok) { 1088 return NT_STATUS_INVALID_PARAMETER; 1089 } 1090 1091 dns_encoded = ldb_binary_encode_string(mem_ctx, dns_name); 1092 if (dns_encoded == NULL) { 1093 return NT_STATUS_NO_MEMORY; 1094 } 1095 netbios_encoded = ldb_binary_encode_string(mem_ctx, netbios_name); 1096 if (netbios_encoded == NULL) { 1097 return NT_STATUS_NO_MEMORY; 1098 } 1099 sid_encoded = ldap_encode_ndr_dom_sid(mem_ctx, r->in.info->sid); 1100 if (sid_encoded == NULL) { 1101 return NT_STATUS_NO_MEMORY; 1102 } 908 1103 909 1104 trusted_domain_state = talloc_zero(mem_ctx, struct lsa_trusted_domain_state); … … 914 1109 915 1110 if (strcasecmp(netbios_name, "BUILTIN") == 0 916 || ( dns_name &&strcasecmp(dns_name, "BUILTIN") == 0)1111 || (strcasecmp(dns_name, "BUILTIN") == 0) 917 1112 || (dom_sid_in_domain(policy_state->builtin_sid, r->in.info->sid))) { 918 1113 return NT_STATUS_INVALID_PARAMETER; … … 921 1116 if (strcasecmp(netbios_name, policy_state->domain_name) == 0 922 1117 || strcasecmp(netbios_name, policy_state->domain_dns) == 0 923 || (dns_name && strcasecmp(dns_name, policy_state->domain_dns) == 0)924 || (dns_name && strcasecmp(dns_name, policy_state->domain_name) == 0)1118 || strcasecmp(dns_name, policy_state->domain_dns) == 0 1119 || strcasecmp(dns_name, policy_state->domain_name) == 0 925 1120 || (dom_sid_equal(policy_state->domain_sid, r->in.info->sid))) { 926 1121 return NT_STATUS_CURRENT_DOMAIN_NOT_ALLOWED; … … 932 1127 auth_struct.outgoing.count = 0; 933 1128 auth_struct.incoming.count = 0; 934 } else {935 auth_blob = data_blob_const(r->in.auth_info ->auth_blob.data,936 r->in.auth_info ->auth_blob.size);1129 } else if (op == NDR_LSA_CREATETRUSTEDDOMAINEX2) { 1130 auth_blob = data_blob_const(r->in.auth_info_internal->auth_blob.data, 1131 r->in.auth_info_internal->auth_blob.size); 937 1132 nt_status = get_trustdom_auth_blob(dce_call, mem_ctx, 938 1133 &auth_blob, &auth_struct); … … 940 1135 return nt_status; 941 1136 } 942 943 if (op == NDR_LSA_CREATETRUSTEDDOMAINEX) { 944 if (auth_struct.incoming.count > 1) { 945 return NT_STATUS_INVALID_PARAMETER; 946 } 947 } 1137 } else if (op == NDR_LSA_CREATETRUSTEDDOMAINEX) { 1138 1139 if (unencrypted_auth_info->incoming_count > 1) { 1140 return NT_STATUS_INVALID_PARAMETER; 1141 } 1142 1143 /* more investigation required here, do not create secrets for 1144 * now */ 1145 auth_struct.outgoing.count = 0; 1146 auth_struct.incoming.count = 0; 1147 } else { 1148 return NT_STATUS_INVALID_PARAMETER; 948 1149 } 949 1150 … … 975 1176 } 976 1177 977 if (dns_name) { 978 char *dns_encoded = ldb_binary_encode_string(mem_ctx, netbios_name); 979 char *netbios_encoded = ldb_binary_encode_string(mem_ctx, netbios_name); 980 /* search for the trusted_domain record */ 981 ret = gendb_search(sam_ldb, 982 mem_ctx, policy_state->system_dn, &msgs, attrs, 983 "(&(|(flatname=%s)(cn=%s)(trustPartner=%s)(flatname=%s)(cn=%s)(trustPartner=%s))(objectclass=trustedDomain))", 984 dns_encoded, dns_encoded, dns_encoded, netbios_encoded, netbios_encoded, netbios_encoded); 985 if (ret > 0) { 986 ldb_transaction_cancel(sam_ldb); 987 return NT_STATUS_OBJECT_NAME_COLLISION; 988 } 989 } else { 990 char *netbios_encoded = ldb_binary_encode_string(mem_ctx, netbios_name); 991 /* search for the trusted_domain record */ 992 ret = gendb_search(sam_ldb, 993 mem_ctx, policy_state->system_dn, &msgs, attrs, 994 "(&(|(flatname=%s)(cn=%s)(trustPartner=%s))(objectclass=trustedDomain))", 995 netbios_encoded, netbios_encoded, netbios_encoded); 996 if (ret > 0) { 997 ldb_transaction_cancel(sam_ldb); 998 return NT_STATUS_OBJECT_NAME_COLLISION; 999 } 1000 } 1001 1002 if (ret < 0 ) { 1178 /* search for the trusted_domain record */ 1179 ret = gendb_search(sam_ldb, 1180 mem_ctx, policy_state->system_dn, &msgs, attrs, 1181 "(&(objectClass=trustedDomain)(|" 1182 "(flatname=%s)(trustPartner=%s)" 1183 "(flatname=%s)(trustPartner=%s)" 1184 "(securityIdentifier=%s)))", 1185 dns_encoded, dns_encoded, 1186 netbios_encoded, netbios_encoded, 1187 sid_encoded); 1188 if (ret > 0) { 1189 ldb_transaction_cancel(sam_ldb); 1190 return NT_STATUS_OBJECT_NAME_COLLISION; 1191 } 1192 if (ret < 0) { 1003 1193 ldb_transaction_cancel(sam_ldb); 1004 1194 return NT_STATUS_INTERNAL_DB_CORRUPTION; 1005 1195 } 1006 1196 1007 name = dns_name ? dns_name : netbios_name;1008 1009 1197 msg = ldb_msg_new(mem_ctx); 1010 1198 if (msg == NULL) { … … 1013 1201 1014 1202 msg->dn = ldb_dn_copy(mem_ctx, policy_state->system_dn); 1015 if ( ! ldb_dn_add_child_fmt(msg->dn, "cn=%s", name)) {1203 if ( ! ldb_dn_add_child_fmt(msg->dn, "cn=%s", dns_name)) { 1016 1204 ldb_transaction_cancel(sam_ldb); 1017 1205 return NT_STATUS_NO_MEMORY; 1018 1206 } 1019 1207 1020 ldb_msg_add_string(msg, "flatname", netbios_name); 1021 1022 if (r->in.info->sid) { 1023 ret = samdb_msg_add_dom_sid(sam_ldb, mem_ctx, msg, "securityIdentifier", r->in.info->sid); 1024 if (ret != LDB_SUCCESS) { 1025 ldb_transaction_cancel(sam_ldb); 1026 return NT_STATUS_INVALID_PARAMETER; 1027 } 1028 } 1029 1030 ldb_msg_add_string(msg, "objectClass", "trustedDomain"); 1031 1032 samdb_msg_add_int(sam_ldb, mem_ctx, msg, "trustType", r->in.info->trust_type); 1033 1034 samdb_msg_add_int(sam_ldb, mem_ctx, msg, "trustAttributes", r->in.info->trust_attributes); 1035 1036 samdb_msg_add_int(sam_ldb, mem_ctx, msg, "trustDirection", r->in.info->trust_direction); 1037 1038 if (dns_name) { 1039 ldb_msg_add_string(msg, "trustPartner", dns_name); 1208 ret = ldb_msg_add_string(msg, "objectClass", "trustedDomain"); 1209 if (ret != LDB_SUCCESS) { 1210 ldb_transaction_cancel(sam_ldb); 1211 return NT_STATUS_NO_MEMORY;; 1212 } 1213 1214 ret = ldb_msg_add_string(msg, "flatname", netbios_name); 1215 if (ret != LDB_SUCCESS) { 1216 ldb_transaction_cancel(sam_ldb); 1217 return NT_STATUS_NO_MEMORY; 1218 } 1219 1220 ret = ldb_msg_add_string(msg, "trustPartner", dns_name); 1221 if (ret != LDB_SUCCESS) { 1222 ldb_transaction_cancel(sam_ldb); 1223 return NT_STATUS_NO_MEMORY;; 1224 } 1225 1226 ret = samdb_msg_add_dom_sid(sam_ldb, mem_ctx, msg, "securityIdentifier", 1227 r->in.info->sid); 1228 if (ret != LDB_SUCCESS) { 1229 ldb_transaction_cancel(sam_ldb); 1230 return NT_STATUS_NO_MEMORY;; 1231 } 1232 1233 ret = samdb_msg_add_int(sam_ldb, mem_ctx, msg, "trustType", r->in.info->trust_type); 1234 if (ret != LDB_SUCCESS) { 1235 ldb_transaction_cancel(sam_ldb); 1236 return NT_STATUS_NO_MEMORY;; 1237 } 1238 1239 ret = samdb_msg_add_int(sam_ldb, mem_ctx, msg, "trustAttributes", r->in.info->trust_attributes); 1240 if (ret != LDB_SUCCESS) { 1241 ldb_transaction_cancel(sam_ldb); 1242 return NT_STATUS_NO_MEMORY;; 1243 } 1244 1245 ret = samdb_msg_add_int(sam_ldb, mem_ctx, msg, "trustDirection", r->in.info->trust_direction); 1246 if (ret != LDB_SUCCESS) { 1247 ldb_transaction_cancel(sam_ldb); 1248 return NT_STATUS_NO_MEMORY;; 1040 1249 } 1041 1250 … … 1105 1314 } 1106 1315 1316 /* 1317 * Notify winbindd that we have a new trust 1318 */ 1319 status = irpc_servers_byname(dce_call->msg_ctx, 1320 mem_ctx, 1321 "winbind_server", 1322 &num_server_ids, &server_ids); 1323 if (NT_STATUS_IS_OK(status) && num_server_ids >= 1) { 1324 enum ndr_err_code ndr_err; 1325 DATA_BLOB b = {}; 1326 1327 ndr_err = ndr_push_struct_blob(&b, mem_ctx, r->in.info, 1328 (ndr_push_flags_fn_t)ndr_push_lsa_TrustDomainInfoInfoEx); 1329 if (NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { 1330 imessaging_send(dce_call->msg_ctx, server_ids[0], 1331 MSG_WINBIND_NEW_TRUSTED_DOMAIN, &b); 1332 } 1333 } 1334 TALLOC_FREE(server_ids); 1335 1107 1336 handle = dcesrv_handle_new(dce_call->context, LSA_HANDLE_TRUSTED_DOMAIN); 1108 1337 if (!handle) { … … 1127 1356 struct lsa_CreateTrustedDomainEx2 *r) 1128 1357 { 1129 return dcesrv_lsa_CreateTrustedDomain_base(dce_call, mem_ctx, r, NDR_LSA_CREATETRUSTEDDOMAINEX2 );1358 return dcesrv_lsa_CreateTrustedDomain_base(dce_call, mem_ctx, r, NDR_LSA_CREATETRUSTEDDOMAINEX2, NULL); 1130 1359 } 1131 1360 /* … … 1140 1369 r2.in.policy_handle = r->in.policy_handle; 1141 1370 r2.in.info = r->in.info; 1142 r2.in.auth_info = r->in.auth_info;1143 1371 r2.out.trustdom_handle = r->out.trustdom_handle; 1144 return dcesrv_lsa_CreateTrustedDomain_base(dce_call, mem_ctx, &r2, NDR_LSA_CREATETRUSTEDDOMAINEX );1145 } 1146 1147 /* 1148 lsa_CreateTrustedDomain 1372 return dcesrv_lsa_CreateTrustedDomain_base(dce_call, mem_ctx, &r2, NDR_LSA_CREATETRUSTEDDOMAINEX, r->in.auth_info); 1373 } 1374 1375 /* 1376 lsa_CreateTrustedDomain 1149 1377 */ 1150 1378 static NTSTATUS dcesrv_lsa_CreateTrustedDomain(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, … … 1159 1387 } 1160 1388 1161 r2.in.info->domain_name .string = NULL;1389 r2.in.info->domain_name = r->in.info->name; 1162 1390 r2.in.info->netbios_name = r->in.info->name; 1163 1391 r2.in.info->sid = r->in.info->sid; … … 1165 1393 r2.in.info->trust_type = LSA_TRUST_TYPE_DOWNLEVEL; 1166 1394 r2.in.info->trust_attributes = 0; 1167 1395 1168 1396 r2.in.access_mask = r->in.access_mask; 1169 1397 r2.out.trustdom_handle = r->out.trustdom_handle; 1170 1398 1171 return dcesrv_lsa_CreateTrustedDomain_base(dce_call, mem_ctx, &r2, NDR_LSA_CREATETRUSTEDDOMAIN); 1172 1173 } 1174 1175 /* 1176 lsa_OpenTrustedDomain 1177 */ 1178 static NTSTATUS dcesrv_lsa_OpenTrustedDomain(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, 1179 struct lsa_OpenTrustedDomain *r) 1180 { 1181 struct dcesrv_handle *policy_handle; 1182 1183 struct lsa_policy_state *policy_state; 1399 return dcesrv_lsa_CreateTrustedDomain_base(dce_call, mem_ctx, &r2, NDR_LSA_CREATETRUSTEDDOMAIN, NULL); 1400 } 1401 1402 static NTSTATUS dcesrv_lsa_OpenTrustedDomain_common( 1403 struct dcesrv_call_state *dce_call, 1404 TALLOC_CTX *tmp_mem, 1405 struct lsa_policy_state *policy_state, 1406 const char *filter, 1407 uint32_t access_mask, 1408 struct dcesrv_handle **_handle) 1409 { 1184 1410 struct lsa_trusted_domain_state *trusted_domain_state; 1185 1411 struct dcesrv_handle *handle; … … 1190 1416 NULL 1191 1417 }; 1192 1418 uint32_t direction; 1419 int ret; 1420 1421 /* TODO: perform access checks */ 1422 1423 /* search for the trusted_domain record */ 1424 ret = gendb_search(policy_state->sam_ldb, tmp_mem, 1425 policy_state->system_dn, 1426 &msgs, attrs, "%s", filter); 1427 if (ret == 0) { 1428 return NT_STATUS_OBJECT_NAME_NOT_FOUND; 1429 } 1430 1431 if (ret != 1) { 1432 DEBUG(0,("Found %d records matching %s under %s\n", ret, 1433 filter, 1434 ldb_dn_get_linearized(policy_state->system_dn))); 1435 return NT_STATUS_INTERNAL_DB_CORRUPTION; 1436 } 1437 1438 trusted_domain_state = talloc_zero(tmp_mem, 1439 struct lsa_trusted_domain_state); 1440 if (!trusted_domain_state) { 1441 return NT_STATUS_NO_MEMORY; 1442 } 1443 trusted_domain_state->policy = policy_state; 1444 1445 trusted_domain_state->trusted_domain_dn = 1446 talloc_steal(trusted_domain_state, msgs[0]->dn); 1447 1448 direction = ldb_msg_find_attr_as_int(msgs[0], "trustDirection", 0); 1449 if (direction & LSA_TRUST_DIRECTION_INBOUND) { 1450 const char *flatname = ldb_msg_find_attr_as_string(msgs[0], 1451 "flatname", NULL); 1452 1453 /* search for the trusted_domain account */ 1454 ret = gendb_search(policy_state->sam_ldb, tmp_mem, 1455 policy_state->domain_dn, 1456 &msgs, attrs, 1457 "(&(samaccountname=%s$)(objectclass=user)" 1458 "(userAccountControl:%s:=%u))", 1459 flatname, 1460 LDB_OID_COMPARATOR_AND, 1461 UF_INTERDOMAIN_TRUST_ACCOUNT); 1462 if (ret == 1) { 1463 trusted_domain_state->trusted_domain_user_dn = 1464 talloc_steal(trusted_domain_state, msgs[0]->dn); 1465 } 1466 } 1467 1468 handle = dcesrv_handle_new(dce_call->context, LSA_HANDLE_TRUSTED_DOMAIN); 1469 if (!handle) { 1470 return NT_STATUS_NO_MEMORY; 1471 } 1472 1473 handle->data = talloc_steal(handle, trusted_domain_state); 1474 1475 trusted_domain_state->access_mask = access_mask; 1476 trusted_domain_state->policy = talloc_reference(trusted_domain_state, 1477 policy_state); 1478 1479 *_handle = handle; 1480 1481 return NT_STATUS_OK; 1482 } 1483 1484 /* 1485 lsa_OpenTrustedDomain 1486 */ 1487 static NTSTATUS dcesrv_lsa_OpenTrustedDomain(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, 1488 struct lsa_OpenTrustedDomain *r) 1489 { 1490 struct dcesrv_handle *policy_handle; 1491 struct lsa_policy_state *policy_state; 1492 struct dcesrv_handle *handle; 1193 1493 const char *sid_string; 1194 int ret; 1494 char *filter; 1495 NTSTATUS status; 1195 1496 1196 1497 DCESRV_PULL_HANDLE(policy_handle, r->in.handle, LSA_HANDLE_POLICY); … … 1198 1499 policy_state = policy_handle->data; 1199 1500 1200 trusted_domain_state = talloc_zero(mem_ctx, struct lsa_trusted_domain_state);1201 if (!trusted_domain_state) {1202 return NT_STATUS_NO_MEMORY;1203 }1204 trusted_domain_state->policy = policy_state;1205 1206 1501 sid_string = dom_sid_string(mem_ctx, r->in.sid); 1207 1502 if (!sid_string) { … … 1209 1504 } 1210 1505 1211 /* search for the trusted_domain record */ 1212 ret = gendb_search(trusted_domain_state->policy->sam_ldb, 1213 mem_ctx, policy_state->system_dn, &msgs, attrs, 1214 "(&(securityIdentifier=%s)(objectclass=trustedDomain))", 1215 sid_string); 1216 if (ret == 0) { 1217 return NT_STATUS_OBJECT_NAME_NOT_FOUND; 1218 } 1219 1220 if (ret != 1) { 1221 DEBUG(0,("Found %d records matching DN %s\n", ret, 1222 ldb_dn_get_linearized(policy_state->system_dn))); 1223 return NT_STATUS_INTERNAL_DB_CORRUPTION; 1224 } 1225 1226 trusted_domain_state->trusted_domain_dn = talloc_reference(trusted_domain_state, msgs[0]->dn); 1227 1228 trusted_domain_state->trusted_domain_user_dn = NULL; 1229 1230 if (ldb_msg_find_attr_as_int(msgs[0], "trustDirection", 0) & LSA_TRUST_DIRECTION_INBOUND) { 1231 const char *flatname = ldb_binary_encode_string(mem_ctx, ldb_msg_find_attr_as_string(msgs[0], "flatname", NULL)); 1232 /* search for the trusted_domain record */ 1233 ret = gendb_search(trusted_domain_state->policy->sam_ldb, 1234 mem_ctx, policy_state->domain_dn, &msgs, attrs, 1235 "(&(samaccountname=%s$)(objectclass=user)(userAccountControl:1.2.840.113556.1.4.803:=%u))", 1236 flatname, UF_INTERDOMAIN_TRUST_ACCOUNT); 1237 if (ret == 1) { 1238 trusted_domain_state->trusted_domain_user_dn = talloc_steal(trusted_domain_state, msgs[0]->dn); 1239 } 1240 } 1241 handle = dcesrv_handle_new(dce_call->context, LSA_HANDLE_TRUSTED_DOMAIN); 1242 if (!handle) { 1243 return NT_STATUS_NO_MEMORY; 1244 } 1245 1246 handle->data = talloc_steal(handle, trusted_domain_state); 1247 1248 trusted_domain_state->access_mask = r->in.access_mask; 1249 trusted_domain_state->policy = talloc_reference(trusted_domain_state, policy_state); 1250 1506 filter = talloc_asprintf(mem_ctx, 1507 "(&(securityIdentifier=%s)" 1508 "(objectclass=trustedDomain))", 1509 sid_string); 1510 if (filter == NULL) { 1511 return NT_STATUS_NO_MEMORY; 1512 } 1513 1514 status = dcesrv_lsa_OpenTrustedDomain_common(dce_call, mem_ctx, 1515 policy_state, 1516 filter, 1517 r->in.access_mask, 1518 &handle); 1519 if (!NT_STATUS_IS_OK(status)) { 1520 return status; 1521 } 1522 1251 1523 *r->out.trustdom_handle = handle->wire_handle; 1252 1524 1253 1525 return NT_STATUS_OK; 1254 1526 } … … 1263 1535 { 1264 1536 struct dcesrv_handle *policy_handle; 1265 1266 1537 struct lsa_policy_state *policy_state; 1267 struct lsa_trusted_domain_state *trusted_domain_state;1268 1538 struct dcesrv_handle *handle; 1269 struct ldb_message **msgs;1270 const char *attrs[] = {1271 NULL1272 };1273 1539 char *td_name; 1274 int ret; 1540 char *filter; 1541 NTSTATUS status; 1275 1542 1276 1543 DCESRV_PULL_HANDLE(policy_handle, r->in.handle, LSA_HANDLE_POLICY); … … 1282 1549 } 1283 1550 1284 trusted_domain_state = talloc_zero(mem_ctx, struct lsa_trusted_domain_state);1285 if (!trusted_domain_state) {1286 return NT_STATUS_NO_MEMORY;1287 }1288 trusted_domain_state->policy = policy_state;1289 1290 1551 /* search for the trusted_domain record */ 1291 1552 td_name = ldb_binary_encode_string(mem_ctx, r->in.name.string); 1292 ret = gendb_search(trusted_domain_state->policy->sam_ldb, 1293 mem_ctx, policy_state->system_dn, &msgs, attrs, 1553 if (td_name == NULL) { 1554 return NT_STATUS_NO_MEMORY; 1555 } 1556 1557 filter = talloc_asprintf(mem_ctx, 1294 1558 "(&(|(flatname=%s)(cn=%s)(trustPartner=%s))" 1295 1559 "(objectclass=trustedDomain))", 1296 1560 td_name, td_name, td_name); 1297 if (ret == 0) { 1298 return NT_STATUS_OBJECT_NAME_NOT_FOUND; 1299 } 1300 1301 if (ret != 1) { 1302 DEBUG(0,("Found %d records matching DN %s\n", ret, 1303 ldb_dn_get_linearized(policy_state->system_dn))); 1304 return NT_STATUS_INTERNAL_DB_CORRUPTION; 1305 } 1306 1307 /* TODO: perform access checks */ 1308 1309 trusted_domain_state->trusted_domain_dn = talloc_reference(trusted_domain_state, msgs[0]->dn); 1310 1311 handle = dcesrv_handle_new(dce_call->context, LSA_HANDLE_TRUSTED_DOMAIN); 1312 if (!handle) { 1313 return NT_STATUS_NO_MEMORY; 1314 } 1315 1316 handle->data = talloc_steal(handle, trusted_domain_state); 1317 1318 trusted_domain_state->access_mask = r->in.access_mask; 1319 trusted_domain_state->policy = talloc_reference(trusted_domain_state, policy_state); 1561 if (filter == NULL) { 1562 return NT_STATUS_NO_MEMORY; 1563 } 1564 1565 status = dcesrv_lsa_OpenTrustedDomain_common(dce_call, mem_ctx, 1566 policy_state, 1567 filter, 1568 r->in.access_mask, 1569 &handle); 1570 if (!NT_STATUS_IS_OK(status)) { 1571 return status; 1572 } 1320 1573 1321 1574 *r->out.trustdom_handle = handle->wire_handle; … … 1326 1579 1327 1580 1328 /* 1581 /* 1329 1582 lsa_SetTrustedDomainInfo 1330 1583 */ … … 1348 1601 "trustType", "trustAttributes", 1349 1602 "trustPosixOffset", 1350 "msDs-supportedEncryptionTypes", NULL }; 1603 "msDs-supportedEncryptionTypes", 1604 "msDS-TrustForestTrustInfo", 1605 NULL 1606 }; 1351 1607 char *dns = NULL; 1352 1608 char *nbn = NULL; … … 1430 1686 const struct ldb_val *orig_val; 1431 1687 uint32_t orig_uint = 0; 1432 int flags = 0;1688 unsigned int flags = 0; 1433 1689 int ret; 1434 1690 … … 1520 1776 1521 1777 /* entry exists, just modify secret if any */ 1522 if (in ->count == 0) {1778 if (in == NULL || in->count == 0) { 1523 1779 return NT_STATUS_OK; 1524 1780 } … … 1582 1838 1583 1839 static NTSTATUS setInfoTrustedDomain_base(struct dcesrv_call_state *dce_call, 1584 struct dcesrv_handle *p_handle,1840 struct lsa_policy_state *p_state, 1585 1841 TALLOC_CTX *mem_ctx, 1586 1842 struct ldb_message *dom_msg, … … 1588 1844 union lsa_TrustedDomainInfo *info) 1589 1845 { 1590 struct lsa_policy_state *p_state = p_handle->data;1591 1846 uint32_t *posix_offset = NULL; 1592 1847 struct lsa_TrustDomainInfoInfoEx *info_ex = NULL; … … 1596 1851 DATA_BLOB trustAuthIncoming, trustAuthOutgoing, auth_blob; 1597 1852 struct trustDomainPasswords auth_struct; 1853 struct trustAuthInOutBlob *current_passwords = NULL; 1598 1854 NTSTATUS nt_status; 1599 1855 struct ldb_message **msgs; … … 1603 1859 bool del_outgoing = false; 1604 1860 bool del_incoming = false; 1861 bool del_forest_info = false; 1605 1862 bool in_transaction = false; 1606 1863 int ret; … … 1638 1895 1639 1896 if (auth_info) { 1640 /* FIXME: not handled yet */ 1641 return NT_STATUS_INVALID_PARAMETER; 1897 nt_status = auth_info_2_auth_blob(mem_ctx, auth_info, 1898 &trustAuthIncoming, 1899 &trustAuthOutgoing); 1900 if (!NT_STATUS_IS_OK(nt_status)) { 1901 return nt_status; 1902 } 1903 if (trustAuthIncoming.data) { 1904 /* This does the decode of some of this twice, but it is easier that way */ 1905 nt_status = auth_info_2_trustauth_inout(mem_ctx, 1906 auth_info->incoming_count, 1907 auth_info->incoming_current_auth_info, 1908 NULL, 1909 ¤t_passwords); 1910 if (!NT_STATUS_IS_OK(nt_status)) { 1911 return nt_status; 1912 } 1913 } 1642 1914 } 1643 1915 … … 1690 1962 /* TODO: should we fetch previous values from the existing entry 1691 1963 * and append them ? */ 1692 if (auth_ struct.incoming.count) {1964 if (auth_info_int && auth_struct.incoming.count) { 1693 1965 nt_status = get_trustauth_inout_blob(dce_call, mem_ctx, 1694 1966 &auth_struct.incoming, … … 1697 1969 return nt_status; 1698 1970 } 1971 1972 current_passwords = &auth_struct.incoming; 1973 1699 1974 } else { 1700 1975 trustAuthIncoming = data_blob(NULL, 0); 1701 1976 } 1702 1977 1703 if (auth_ struct.outgoing.count) {1978 if (auth_info_int && auth_struct.outgoing.count) { 1704 1979 nt_status = get_trustauth_inout_blob(dce_call, mem_ctx, 1705 1980 &auth_struct.outgoing, … … 1730 2005 if (info_ex) { 1731 2006 uint32_t origattrs; 2007 uint32_t changed_attrs; 1732 2008 uint32_t origdir; 1733 uint32_t tmp;1734 2009 int origtype; 1735 2010 … … 1743 2018 } 1744 2019 1745 tmp = info_ex->trust_direction ^ origdir; 1746 if (tmp & LSA_TRUST_DIRECTION_INBOUND) { 1747 if (origdir & LSA_TRUST_DIRECTION_INBOUND) { 1748 del_incoming = true; 1749 } else { 2020 if (info_ex->trust_direction & LSA_TRUST_DIRECTION_INBOUND) { 2021 if (auth_info != NULL && trustAuthIncoming.length > 0) { 1750 2022 add_incoming = true; 1751 2023 } 1752 2024 } 1753 if (tmp & LSA_TRUST_DIRECTION_OUTBOUND) { 1754 if (origdir & LSA_TRUST_DIRECTION_OUTBOUND) { 1755 del_outgoing = true; 1756 } else { 2025 if (info_ex->trust_direction & LSA_TRUST_DIRECTION_OUTBOUND) { 2026 if (auth_info != NULL && trustAuthOutgoing.length > 0) { 1757 2027 add_outgoing = true; 1758 2028 } 2029 } 2030 2031 if ((origdir & LSA_TRUST_DIRECTION_INBOUND) && 2032 !(info_ex->trust_direction & LSA_TRUST_DIRECTION_INBOUND)) { 2033 del_incoming = true; 2034 } 2035 if ((origdir & LSA_TRUST_DIRECTION_OUTBOUND) && 2036 !(info_ex->trust_direction & LSA_TRUST_DIRECTION_OUTBOUND)) { 2037 del_outgoing = true; 1759 2038 } 1760 2039 … … 1776 2055 /* TODO: check forestFunctionality from ldb opaque */ 1777 2056 /* TODO: check what is set makes sense */ 1778 /* for now refuse changes */ 1779 if (origattrs == -1 || 1780 origattrs != info_ex->trust_attributes) { 1781 DEBUG(1, ("Attempted to change trust attributes! " 1782 "Operation not handled\n")); 2057 2058 changed_attrs = origattrs ^ info_ex->trust_attributes; 2059 if (changed_attrs & ~LSA_TRUST_ATTRIBUTE_FOREST_TRANSITIVE) { 2060 /* 2061 * For now we only allow 2062 * LSA_TRUST_ATTRIBUTE_FOREST_TRANSITIVE to be changed. 2063 * 2064 * TODO: we may need to support more attribute changes 2065 */ 2066 DEBUG(1, ("Attempted to change trust attributes " 2067 "(0x%08x != 0x%08x)! " 2068 "Operation not handled yet...\n", 2069 (unsigned)origattrs, 2070 (unsigned)info_ex->trust_attributes)); 1783 2071 return NT_STATUS_INVALID_PARAMETER; 2072 } 2073 2074 if (!(info_ex->trust_attributes & 2075 LSA_TRUST_ATTRIBUTE_FOREST_TRANSITIVE)) 2076 { 2077 struct ldb_message_element *orig_forest_el = NULL; 2078 2079 orig_forest_el = ldb_msg_find_element(dom_msg, 2080 "msDS-TrustForestTrustInfo"); 2081 if (orig_forest_el != NULL) { 2082 del_forest_info = true; 2083 } 1784 2084 } 1785 2085 } … … 1795 2095 } 1796 2096 1797 if (add_incoming && trustAuthIncoming.data) {2097 if (add_incoming || del_incoming) { 1798 2098 ret = ldb_msg_add_empty(msg, "trustAuthIncoming", 1799 2099 LDB_FLAG_MOD_REPLACE, NULL); … … 1801 2101 return NT_STATUS_NO_MEMORY; 1802 2102 } 1803 ret = ldb_msg_add_value(msg, "trustAuthIncoming", 1804 &trustAuthIncoming, NULL); 1805 if (ret != LDB_SUCCESS) { 1806 return NT_STATUS_NO_MEMORY; 1807 } 1808 } 1809 if (add_outgoing && trustAuthOutgoing.data) { 1810 ret = ldb_msg_add_empty(msg, "trustAuthIncoming", 2103 if (add_incoming) { 2104 ret = ldb_msg_add_value(msg, "trustAuthIncoming", 2105 &trustAuthIncoming, NULL); 2106 if (ret != LDB_SUCCESS) { 2107 return NT_STATUS_NO_MEMORY; 2108 } 2109 } 2110 } 2111 if (add_outgoing || del_outgoing) { 2112 ret = ldb_msg_add_empty(msg, "trustAuthOutgoing", 1811 2113 LDB_FLAG_MOD_REPLACE, NULL); 1812 2114 if (ret != LDB_SUCCESS) { 1813 2115 return NT_STATUS_NO_MEMORY; 1814 2116 } 1815 ret = ldb_msg_add_value(msg, "trustAuthOutgoing", 1816 &trustAuthOutgoing, NULL); 2117 if (add_outgoing) { 2118 ret = ldb_msg_add_value(msg, "trustAuthOutgoing", 2119 &trustAuthOutgoing, NULL); 2120 if (ret != LDB_SUCCESS) { 2121 return NT_STATUS_NO_MEMORY; 2122 } 2123 } 2124 } 2125 if (del_forest_info) { 2126 ret = ldb_msg_add_empty(msg, "msDS-TrustForestTrustInfo", 2127 LDB_FLAG_MOD_REPLACE, NULL); 1817 2128 if (ret != LDB_SUCCESS) { 1818 2129 return NT_STATUS_NO_MEMORY; … … 1827 2138 in_transaction = true; 1828 2139 1829 ret = ldb_modify(p_state->sam_ldb, msg); 1830 if (ret != LDB_SUCCESS) { 1831 DEBUG(1,("Failed to modify trusted domain record %s: %s\n", 1832 ldb_dn_get_linearized(msg->dn), 1833 ldb_errstring(p_state->sam_ldb))); 1834 if (ret == LDB_ERR_INSUFFICIENT_ACCESS_RIGHTS) { 1835 nt_status = NT_STATUS_ACCESS_DENIED; 1836 } else { 1837 nt_status = NT_STATUS_INTERNAL_DB_CORRUPTION; 1838 } 1839 goto done; 2140 if (msg->num_elements) { 2141 ret = ldb_modify(p_state->sam_ldb, msg); 2142 if (ret != LDB_SUCCESS) { 2143 DEBUG(1,("Failed to modify trusted domain record %s: %s\n", 2144 ldb_dn_get_linearized(msg->dn), 2145 ldb_errstring(p_state->sam_ldb))); 2146 nt_status = dsdb_ldb_err_to_ntstatus(ret); 2147 goto done; 2148 } 1840 2149 } 1841 2150 … … 1850 2159 } 1851 2160 2161 /* We use trustAuthIncoming.data to incidate that auth_struct.incoming is valid */ 1852 2162 nt_status = update_trust_user(mem_ctx, 1853 2163 p_state->sam_ldb, … … 1855 2165 del_incoming, 1856 2166 netbios_name, 1857 &auth_struct.incoming);2167 current_passwords); 1858 2168 if (!NT_STATUS_IS_OK(nt_status)) { 1859 2169 goto done; … … 1907 2217 } 1908 2218 1909 return setInfoTrustedDomain_base(dce_call, h, mem_ctx,2219 return setInfoTrustedDomain_base(dce_call, td_state->policy, mem_ctx, 1910 2220 msgs[0], r->in.level, r->in.info); 1911 2221 } 1912 2222 1913 2223 1914 /* 2224 /* 1915 2225 lsa_DeleteTrustedDomain 1916 2226 */ … … 1919 2229 { 1920 2230 NTSTATUS status; 1921 struct lsa_OpenTrustedDomain opn ;2231 struct lsa_OpenTrustedDomain opn = {{0},{0}}; 1922 2232 struct lsa_DeleteObject del; 1923 2233 struct dcesrv_handle *h; … … 1947 2257 } 1948 2258 1949 static NTSTATUS fill_trust_domain_ex(TALLOC_CTX *mem_ctx, 1950 struct ldb_message *msg, 1951 struct lsa_TrustDomainInfoInfoEx *info_ex) 2259 static NTSTATUS fill_trust_domain_ex(TALLOC_CTX *mem_ctx, 2260 struct ldb_message *msg, 2261 struct lsa_TrustDomainInfoInfoEx *info_ex) 1952 2262 { 1953 2263 info_ex->domain_name.string … … 1955 2265 info_ex->netbios_name.string 1956 2266 = ldb_msg_find_attr_as_string(msg, "flatname", NULL); 1957 info_ex->sid 2267 info_ex->sid 1958 2268 = samdb_result_dom_sid(mem_ctx, msg, "securityIdentifier"); 1959 2269 info_ex->trust_direction … … 1962 2272 = ldb_msg_find_attr_as_int(msg, "trustType", 0); 1963 2273 info_ex->trust_attributes 1964 = ldb_msg_find_attr_as_int(msg, "trustAttributes", 0); 2274 = ldb_msg_find_attr_as_int(msg, "trustAttributes", 0); 1965 2275 return NT_STATUS_OK; 1966 2276 } 1967 2277 1968 /* 2278 /* 1969 2279 lsa_QueryTrustedDomainInfo 1970 2280 */ … … 1979 2289 struct ldb_message **res; 1980 2290 const char *attrs[] = { 1981 "flatname", 2291 "flatname", 1982 2292 "trustPartner", 1983 2293 "securityIdentifier", 1984 2294 "trustDirection", 1985 2295 "trustType", 1986 "trustAttributes", 2296 "trustAttributes", 1987 2297 "msDs-supportedEncryptionTypes", 1988 2298 NULL … … 2000 2310 } 2001 2311 msg = res[0]; 2002 2312 2003 2313 info = talloc_zero(mem_ctx, union lsa_TrustedDomainInfo); 2004 2314 if (!info) { … … 2018 2328 #if 0 /* Win2k3 doesn't implement this */ 2019 2329 case LSA_TRUSTED_DOMAIN_INFO_BASIC: 2020 r->out.info->info_basic.netbios_name.string 2330 r->out.info->info_basic.netbios_name.string 2021 2331 = ldb_msg_find_attr_as_string(msg, "flatname", NULL); 2022 2332 r->out.info->info_basic.sid … … 2035 2345 = ldb_msg_find_attr_as_uint(msg, "posixOffset", 0); 2036 2346 return fill_trust_domain_ex(mem_ctx, msg, &info->full_info2_internal.info.info_ex); 2037 2347 2038 2348 case LSA_TRUSTED_DOMAIN_SUPPORTED_ENCRYPTION_TYPES: 2039 2349 info->enc_types.enc_types … … 2058 2368 2059 2369 2060 /* 2370 /* 2061 2371 lsa_QueryTrustedDomainInfoBySid 2062 2372 */ … … 2065 2375 { 2066 2376 NTSTATUS status; 2067 struct lsa_OpenTrustedDomain opn ;2377 struct lsa_OpenTrustedDomain opn = {{0},{0}}; 2068 2378 struct lsa_QueryTrustedDomainInfo query; 2069 2379 struct dcesrv_handle *h; … … 2125 2435 } 2126 2436 2127 return setInfoTrustedDomain_base(dce_call, policy_ handle, mem_ctx,2437 return setInfoTrustedDomain_base(dce_call, policy_state, mem_ctx, 2128 2438 msgs[0], r->in.level, r->in.info); 2129 2439 } 2130 2440 2131 /* 2441 /* 2132 2442 lsa_QueryTrustedDomainInfoByName 2133 2443 */ … … 2137 2447 { 2138 2448 NTSTATUS status; 2139 struct lsa_OpenTrustedDomainByName opn ;2449 struct lsa_OpenTrustedDomainByName opn = {{0},{0}}; 2140 2450 struct lsa_QueryTrustedDomainInfo query; 2141 2451 struct dcesrv_handle *h; … … 2152 2462 return status; 2153 2463 } 2154 2464 2155 2465 /* Ensure this handle goes away at the end of this call */ 2156 2466 DCESRV_PULL_HANDLE(h, opn.out.trustdom_handle, DCESRV_HANDLE_ANY); … … 2164 2474 return status; 2165 2475 } 2166 2476 2167 2477 return NT_STATUS_OK; 2168 2478 } 2169 2479 2170 2480 /* 2171 lsa_CloseTrustedDomainEx 2481 lsa_CloseTrustedDomainEx 2172 2482 */ 2173 2483 static NTSTATUS dcesrv_lsa_CloseTrustedDomainEx(struct dcesrv_call_state *dce_call, … … 2190 2500 } 2191 2501 2192 /* 2193 lsa_EnumTrustDom 2502 /* 2503 lsa_EnumTrustDom 2194 2504 */ 2195 2505 static NTSTATUS dcesrv_lsa_EnumTrustDom(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, … … 2201 2511 struct ldb_message **domains; 2202 2512 const char *attrs[] = { 2203 "flatname", 2513 "flatname", 2204 2514 "securityIdentifier", 2205 2515 NULL … … 2218 2528 policy_state = policy_handle->data; 2219 2529 2220 /* search for all users in this domain. This could possibly be cached and 2530 /* search for all users in this domain. This could possibly be cached and 2221 2531 resumed based on resume_key */ 2222 count = gendb_search(policy_state->sam_ldb, mem_ctx, policy_state->system_dn, &domains, attrs, 2532 count = gendb_search(policy_state->sam_ldb, mem_ctx, policy_state->system_dn, &domains, attrs, 2223 2533 "objectclass=trustedDomain"); 2224 2534 if (count < 0) { … … 2245 2555 } 2246 2556 2247 /* return the rest, limit by max_size. Note that we 2557 /* return the rest, limit by max_size. Note that we 2248 2558 use the w2k3 element size value of 60 */ 2249 2559 r->out.domains->count = count - *r->in.resume_handle; 2250 r->out.domains->count = MIN(r->out.domains->count, 2560 r->out.domains->count = MIN(r->out.domains->count, 2251 2561 1+(r->in.max_size/LSA_ENUM_TRUST_DOMAIN_MULTIPLIER)); 2252 2562 … … 2279 2589 } 2280 2590 2281 /* 2282 lsa_EnumTrustedDomainsEx 2591 /* 2592 lsa_EnumTrustedDomainsEx 2283 2593 */ 2284 2594 static NTSTATUS dcesrv_lsa_EnumTrustedDomainsEx(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, … … 2290 2600 struct ldb_message **domains; 2291 2601 const char *attrs[] = { 2292 "flatname", 2602 "flatname", 2293 2603 "trustPartner", 2294 2604 "securityIdentifier", 2295 2605 "trustDirection", 2296 2606 "trustType", 2297 "trustAttributes", 2607 "trustAttributes", 2298 2608 NULL 2299 2609 }; … … 2311 2621 policy_state = policy_handle->data; 2312 2622 2313 /* search for all users in this domain. This could possibly be cached and 2623 /* search for all users in this domain. This could possibly be cached and 2314 2624 resumed based on resume_key */ 2315 count = gendb_search(policy_state->sam_ldb, mem_ctx, policy_state->system_dn, &domains, attrs, 2625 count = gendb_search(policy_state->sam_ldb, mem_ctx, policy_state->system_dn, &domains, attrs, 2316 2626 "objectclass=trustedDomain"); 2317 2627 if (count < 0) { … … 2340 2650 } 2341 2651 2342 /* return the rest, limit by max_size. Note that we 2652 /* return the rest, limit by max_size. Note that we 2343 2653 use the w2k3 element size value of 60 */ 2344 2654 r->out.domains->count = count - *r->in.resume_handle; 2345 r->out.domains->count = MIN(r->out.domains->count, 2655 r->out.domains->count = MIN(r->out.domains->count, 2346 2656 1+(r->in.max_size/LSA_ENUM_TRUST_DOMAIN_EX_MULTIPLIER)); 2347 2657 … … 2354 2664 } 2355 2665 2666 *r->out.resume_handle = *r->in.resume_handle + r->out.domains->count; 2667 2356 2668 return NT_STATUS_OK; 2357 2669 } 2358 2670 2359 2671 2360 /* 2361 lsa_OpenAccount 2672 /* 2673 lsa_OpenAccount 2362 2674 */ 2363 2675 static NTSTATUS dcesrv_lsa_OpenAccount(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, … … 2384 2696 return NT_STATUS_NO_MEMORY; 2385 2697 } 2386 2698 2387 2699 astate->policy = talloc_reference(astate, state); 2388 2700 astate->access_mask = r->in.access_mask; 2701 2702 /* 2703 * For now we grant all requested access. 2704 * 2705 * We will fail at the ldb layer later. 2706 */ 2707 if (astate->access_mask & SEC_FLAG_MAXIMUM_ALLOWED) { 2708 astate->access_mask &= ~SEC_FLAG_MAXIMUM_ALLOWED; 2709 astate->access_mask |= LSA_ACCOUNT_ALL_ACCESS; 2710 } 2711 se_map_generic(&astate->access_mask, &dcesrv_lsa_account_mapping); 2712 2713 DEBUG(10,("%s: %s access desired[0x%08X] granted[0x%08X] - success.\n", 2714 __func__, dom_sid_string(mem_ctx, astate->account_sid), 2715 (unsigned)r->in.access_mask, 2716 (unsigned)astate->access_mask)); 2389 2717 2390 2718 ah = dcesrv_handle_new(dce_call->context, LSA_HANDLE_ACCOUNT); … … 2402 2730 2403 2731 2404 /* 2405 lsa_EnumPrivsAccount 2406 */ 2407 static NTSTATUS dcesrv_lsa_EnumPrivsAccount(struct dcesrv_call_state *dce_call, 2732 /* 2733 lsa_EnumPrivsAccount 2734 */ 2735 static NTSTATUS dcesrv_lsa_EnumPrivsAccount(struct dcesrv_call_state *dce_call, 2408 2736 TALLOC_CTX *mem_ctx, 2409 2737 struct lsa_EnumPrivsAccount *r) … … 2438 2766 } 2439 2767 2440 ret = gendb_search(astate->policy->pdb, mem_ctx, NULL, &res, attrs, 2768 ret = gendb_search(astate->policy->pdb, mem_ctx, NULL, &res, attrs, 2441 2769 "objectSid=%s", sidstr); 2442 2770 if (ret < 0) { … … 2476 2804 } 2477 2805 2478 /* 2479 lsa_EnumAccountRights 2480 */ 2481 static NTSTATUS dcesrv_lsa_EnumAccountRights(struct dcesrv_call_state *dce_call, 2806 /* 2807 lsa_EnumAccountRights 2808 */ 2809 static NTSTATUS dcesrv_lsa_EnumAccountRights(struct dcesrv_call_state *dce_call, 2482 2810 TALLOC_CTX *mem_ctx, 2483 2811 struct lsa_EnumAccountRights *r) … … 2501 2829 } 2502 2830 2503 ret = gendb_search(state->pdb, mem_ctx, NULL, &res, attrs, 2831 ret = gendb_search(state->pdb, mem_ctx, NULL, &res, attrs, 2504 2832 "(&(objectSid=%s)(privilege=*))", sidstr); 2505 2833 if (ret == 0) { … … 2507 2835 } 2508 2836 if (ret != 1) { 2509 DEBUG(3, ("searching for account rights for SID: %s failed: %s", 2837 DEBUG(3, ("searching for account rights for SID: %s failed: %s", 2510 2838 dom_sid_string(mem_ctx, r->in.sid), 2511 2839 ldb_errstring(state->pdb))); … … 2519 2847 2520 2848 r->out.rights->count = el->num_values; 2521 r->out.rights->names = talloc_array(r->out.rights, 2849 r->out.rights->names = talloc_array(r->out.rights, 2522 2850 struct lsa_StringLarge, r->out.rights->count); 2523 2851 if (r->out.rights->names == NULL) { … … 2534 2862 2535 2863 2536 /* 2864 /* 2537 2865 helper for lsa_AddAccountRights and lsa_RemoveAccountRights 2538 2866 */ 2539 static NTSTATUS dcesrv_lsa_AddRemoveAccountRights(struct dcesrv_call_state *dce_call, 2867 static NTSTATUS dcesrv_lsa_AddRemoveAccountRights(struct dcesrv_call_state *dce_call, 2540 2868 TALLOC_CTX *mem_ctx, 2541 2869 struct lsa_policy_state *state, … … 2564 2892 2565 2893 sidndrstr = ldap_encode_ndr_dom_sid(msg, sid); 2566 NT_STATUS_HAVE_NO_MEMORY_AND_FREE(sidndrstr, msg); 2894 if (sidndrstr == NULL) { 2895 TALLOC_FREE(msg); 2896 return NT_STATUS_NO_MEMORY; 2897 } 2567 2898 2568 2899 sidstr = dom_sid_string(msg, sid); 2569 NT_STATUS_HAVE_NO_MEMORY_AND_FREE(sidstr, msg); 2900 if (sidstr == NULL) { 2901 TALLOC_FREE(msg); 2902 return NT_STATUS_NO_MEMORY; 2903 } 2570 2904 2571 2905 dnstr = talloc_asprintf(msg, "sid=%s", sidstr); 2572 NT_STATUS_HAVE_NO_MEMORY_AND_FREE(dnstr, msg); 2906 if (dnstr == NULL) { 2907 TALLOC_FREE(msg); 2908 return NT_STATUS_NO_MEMORY; 2909 } 2573 2910 2574 2911 msg->dn = ldb_dn_new(msg, state->pdb, dnstr); 2575 NT_STATUS_HAVE_NO_MEMORY_AND_FREE(msg->dn, msg); 2912 if (msg->dn == NULL) { 2913 TALLOC_FREE(msg); 2914 return NT_STATUS_NO_MEMORY; 2915 } 2576 2916 2577 2917 if (LDB_FLAG_MOD_TYPE(ldb_flag) == LDB_FLAG_MOD_ADD) { … … 2602 2942 uint32_t j; 2603 2943 for (j=0;j<r2.out.rights->count;j++) { 2604 if (strcasecmp_m(r2.out.rights->names[j].string, 2944 if (strcasecmp_m(r2.out.rights->names[j].string, 2605 2945 rights->names[i].string) == 0) { 2606 2946 break; … … 2632 2972 } 2633 2973 ldb_msg_add_string(msg, "comment", "added via LSA"); 2634 ret = ldb_add(state->pdb, msg); 2974 ret = ldb_add(state->pdb, msg); 2635 2975 } 2636 2976 if (ret != LDB_SUCCESS) { … … 2639 2979 return NT_STATUS_OK; 2640 2980 } 2641 DEBUG(3, ("Could not %s attributes from %s: %s", 2981 DEBUG(3, ("Could not %s attributes from %s: %s", 2642 2982 LDB_FLAG_MOD_TYPE(ldb_flag) == LDB_FLAG_MOD_DELETE ? "delete" : "add", 2643 2983 ldb_dn_get_linearized(msg->dn), ldb_errstring(state->pdb))); … … 2650 2990 } 2651 2991 2652 /* 2992 /* 2653 2993 lsa_AddPrivilegesToAccount 2654 2994 */ … … 2681 3021 } 2682 3022 2683 return dcesrv_lsa_AddRemoveAccountRights(dce_call, mem_ctx, astate->policy, 3023 return dcesrv_lsa_AddRemoveAccountRights(dce_call, mem_ctx, astate->policy, 2684 3024 LDB_FLAG_MOD_ADD, astate->account_sid, 2685 3025 &rights); … … 2687 3027 2688 3028 2689 /* 3029 /* 2690 3030 lsa_RemovePrivilegesFromAccount 2691 3031 */ … … 2704 3044 rights = talloc(mem_ctx, struct lsa_RightSet); 2705 3045 2706 if (r->in.remove_all == 1 && 3046 if (r->in.remove_all == 1 && 2707 3047 r->in.privs == NULL) { 2708 3048 struct lsa_EnumAccountRights r2; … … 2718 3058 } 2719 3059 2720 return dcesrv_lsa_AddRemoveAccountRights(dce_call, mem_ctx, astate->policy, 3060 return dcesrv_lsa_AddRemoveAccountRights(dce_call, mem_ctx, astate->policy, 2721 3061 LDB_FLAG_MOD_DELETE, astate->account_sid, 2722 3062 r2.out.rights); … … 2743 3083 } 2744 3084 2745 return dcesrv_lsa_AddRemoveAccountRights(dce_call, mem_ctx, astate->policy, 3085 return dcesrv_lsa_AddRemoveAccountRights(dce_call, mem_ctx, astate->policy, 2746 3086 LDB_FLAG_MOD_DELETE, astate->account_sid, 2747 3087 rights); … … 2749 3089 2750 3090 2751 /* 3091 /* 2752 3092 lsa_GetQuotasForAccount 2753 3093 */ … … 2759 3099 2760 3100 2761 /* 3101 /* 2762 3102 lsa_SetQuotasForAccount 2763 3103 */ … … 2769 3109 2770 3110 2771 /* 3111 /* 2772 3112 lsa_GetSystemAccessAccount 2773 3113 */ … … 2795 3135 } 2796 3136 2797 ret = gendb_search(astate->policy->pdb, mem_ctx, NULL, &res, attrs, 3137 ret = gendb_search(astate->policy->pdb, mem_ctx, NULL, &res, attrs, 2798 3138 "objectSid=%s", sidstr); 2799 3139 if (ret < 0) { … … 2822 3162 2823 3163 2824 /* 3164 /* 2825 3165 lsa_SetSystemAccessAccount 2826 3166 */ … … 2832 3172 2833 3173 2834 /* 2835 lsa_CreateSecret 3174 /* 3175 lsa_CreateSecret 2836 3176 */ 2837 3177 static NTSTATUS dcesrv_lsa_CreateSecret(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, … … 2853 3193 DCESRV_PULL_HANDLE(policy_handle, r->in.handle, LSA_HANDLE_POLICY); 2854 3194 ZERO_STRUCTP(r->out.sec_handle); 2855 3195 2856 3196 switch (security_session_user_level(dce_call->conn->auth_state.session_info, NULL)) 2857 3197 { … … 2869 3209 return NT_STATUS_INVALID_PARAMETER; 2870 3210 } 2871 3211 2872 3212 secret_state = talloc(mem_ctx, struct lsa_secret_state); 2873 3213 NT_STATUS_HAVE_NO_MEMORY(secret_state); … … 2903 3243 ret = gendb_search(secret_state->sam_ldb, 2904 3244 mem_ctx, policy_state->system_dn, &msgs, attrs, 2905 "(&(cn=%s)(objectclass=secret))", 3245 "(&(cn=%s)(objectclass=secret))", 2906 3246 name2); 2907 3247 if (ret > 0) { 2908 3248 return NT_STATUS_OBJECT_NAME_COLLISION; 2909 3249 } 2910 3250 2911 3251 if (ret < 0) { 2912 DEBUG(0,("Failure searching for CN=%s: %s\n", 3252 DEBUG(0,("Failure searching for CN=%s: %s\n", 2913 3253 name2, ldb_errstring(secret_state->sam_ldb))); 2914 3254 return NT_STATUS_INTERNAL_DB_CORRUPTION; … … 2931 3271 } 2932 3272 2933 secret_state->sam_ldb = talloc_reference(secret_state, 3273 secret_state->sam_ldb = talloc_reference(secret_state, 2934 3274 secrets_db_connect(mem_ctx, dce_call->conn->dce_ctx->lp_ctx)); 2935 3275 NT_STATUS_HAVE_NO_MEMORY(secret_state->sam_ldb); … … 2939 3279 ldb_dn_new(mem_ctx, secret_state->sam_ldb, "cn=LSA Secrets"), 2940 3280 &msgs, attrs, 2941 "(&(cn=%s)(objectclass=secret))", 3281 "(&(cn=%s)(objectclass=secret))", 2942 3282 ldb_binary_encode_string(mem_ctx, name)); 2943 3283 if (ret > 0) { 2944 3284 return NT_STATUS_OBJECT_NAME_COLLISION; 2945 3285 } 2946 3286 2947 3287 if (ret < 0) { 2948 DEBUG(0,("Failure searching for CN=%s: %s\n", 3288 DEBUG(0,("Failure searching for CN=%s: %s\n", 2949 3289 name, ldb_errstring(secret_state->sam_ldb))); 2950 3290 return NT_STATUS_INTERNAL_DB_CORRUPTION; … … 2956 3296 ret = ldb_msg_add_string(msg, "cn", name); 2957 3297 if (ret != LDB_SUCCESS) return NT_STATUS_NO_MEMORY; 2958 } 3298 } 2959 3299 2960 3300 ret = ldb_msg_add_string(msg, "objectClass", "secret"); 2961 3301 if (ret != LDB_SUCCESS) return NT_STATUS_NO_MEMORY; 2962 3302 2963 3303 secret_state->secret_dn = talloc_reference(secret_state, msg->dn); 2964 3304 NT_STATUS_HAVE_NO_MEMORY(secret_state->secret_dn); … … 2968 3308 if (ret != LDB_SUCCESS) { 2969 3309 DEBUG(0,("Failed to create secret record %s: %s\n", 2970 ldb_dn_get_linearized(msg->dn), 3310 ldb_dn_get_linearized(msg->dn), 2971 3311 ldb_errstring(secret_state->sam_ldb))); 2972 3312 return NT_STATUS_ACCESS_DENIED; … … 2977 3317 2978 3318 handle->data = talloc_steal(handle, secret_state); 2979 3319 2980 3320 secret_state->access_mask = r->in.access_mask; 2981 3321 secret_state->policy = talloc_reference(secret_state, policy_state); 2982 3322 NT_STATUS_HAVE_NO_MEMORY(secret_state->policy); 2983 3323 2984 3324 *r->out.sec_handle = handle->wire_handle; 2985 3325 2986 3326 return NT_STATUS_OK; 2987 3327 } 2988 3328 2989 3329 2990 /* 2991 lsa_OpenSecret 3330 /* 3331 lsa_OpenSecret 2992 3332 */ 2993 3333 static NTSTATUS dcesrv_lsa_OpenSecret(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, … … 2995 3335 { 2996 3336 struct dcesrv_handle *policy_handle; 2997 3337 2998 3338 struct lsa_policy_state *policy_state; 2999 3339 struct lsa_secret_state *secret_state; … … 3015 3355 return NT_STATUS_INVALID_PARAMETER; 3016 3356 } 3017 3357 3018 3358 switch (security_session_user_level(dce_call->conn->auth_state.session_info, NULL)) 3019 3359 { … … 3035 3375 name = &r->in.name.string[2]; 3036 3376 /* We need to connect to the database as system, as this is one of the rare RPC calls that must read the secrets (and this is denied otherwise) */ 3037 secret_state->sam_ldb = talloc_reference(secret_state, 3377 secret_state->sam_ldb = talloc_reference(secret_state, 3038 3378 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)); 3039 3379 secret_state->global = true; … … 3046 3386 ret = gendb_search(secret_state->sam_ldb, 3047 3387 mem_ctx, policy_state->system_dn, &msgs, attrs, 3048 "(&(cn=%s Secret)(objectclass=secret))", 3388 "(&(cn=%s Secret)(objectclass=secret))", 3049 3389 ldb_binary_encode_string(mem_ctx, name)); 3050 3390 if (ret == 0) { 3051 3391 return NT_STATUS_OBJECT_NAME_NOT_FOUND; 3052 3392 } 3053 3393 3054 3394 if (ret != 1) { 3055 3395 DEBUG(0,("Found %d records matching DN %s\n", ret, … … 3057 3397 return NT_STATUS_INTERNAL_DB_CORRUPTION; 3058 3398 } 3059 3060 3399 } else { 3061 3400 secret_state->global = false; 3062 secret_state->sam_ldb = talloc_reference(secret_state, 3401 secret_state->sam_ldb = talloc_reference(secret_state, 3063 3402 secrets_db_connect(mem_ctx, dce_call->conn->dce_ctx->lp_ctx)); 3064 3403 … … 3072 3411 ldb_dn_new(mem_ctx, secret_state->sam_ldb, "cn=LSA Secrets"), 3073 3412 &msgs, attrs, 3074 "(&(cn=%s)(objectclass=secret))", 3413 "(&(cn=%s)(objectclass=secret))", 3075 3414 ldb_binary_encode_string(mem_ctx, name)); 3076 3415 if (ret == 0) { 3077 3416 return NT_STATUS_OBJECT_NAME_NOT_FOUND; 3078 3417 } 3079 3418 3080 3419 if (ret != 1) { 3081 DEBUG(0,("Found %d records matching CN=%s\n", 3420 DEBUG(0,("Found %d records matching CN=%s\n", 3082 3421 ret, ldb_binary_encode_string(mem_ctx, name))); 3083 3422 return NT_STATUS_INTERNAL_DB_CORRUPTION; 3084 3423 } 3085 } 3424 } 3086 3425 3087 3426 secret_state->secret_dn = talloc_reference(secret_state, msgs[0]->dn); 3088 3427 3089 3428 handle = dcesrv_handle_new(dce_call->context, LSA_HANDLE_SECRET); 3090 3429 if (!handle) { 3091 3430 return NT_STATUS_NO_MEMORY; 3092 3431 } 3093 3432 3094 3433 handle->data = talloc_steal(handle, secret_state); 3095 3434 3096 3435 secret_state->access_mask = r->in.access_mask; 3097 3436 secret_state->policy = talloc_reference(secret_state, policy_state); 3098 3437 3099 3438 *r->out.sec_handle = handle->wire_handle; 3100 3439 3101 3440 return NT_STATUS_OK; 3102 3441 } 3103 3442 3104 3443 3105 /* 3106 lsa_SetSecret 3444 /* 3445 lsa_SetSecret 3107 3446 */ 3108 3447 static NTSTATUS dcesrv_lsa_SetSecret(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, … … 3144 3483 crypt_secret.data = r->in.old_val->data; 3145 3484 crypt_secret.length = r->in.old_val->size; 3146 3485 3147 3486 status = sess_decrypt_blob(mem_ctx, &crypt_secret, &session_key, &secret); 3148 3487 if (!NT_STATUS_IS_OK(status)) { 3149 3488 return status; 3150 3489 } 3151 3490 3152 3491 val.data = secret.data; 3153 3492 val.length = secret.length; 3154 3493 3155 3494 /* set value */ 3156 3495 if (ldb_msg_add_value(msg, "priorValue", &val, NULL) != LDB_SUCCESS) { 3157 return NT_STATUS_NO_MEMORY; 3158 } 3159 3496 return NT_STATUS_NO_MEMORY; 3497 } 3498 3160 3499 /* set old value mtime */ 3161 if (samdb_msg_add_uint64(secret_state->sam_ldb, 3500 if (samdb_msg_add_uint64(secret_state->sam_ldb, 3162 3501 mem_ctx, msg, "priorSetTime", nt_now) != LDB_SUCCESS) { 3163 return NT_STATUS_NO_MEMORY; 3502 return NT_STATUS_NO_MEMORY; 3164 3503 } 3165 3504 … … 3175 3514 NULL 3176 3515 }; 3177 3516 3178 3517 /* search for the secret record */ 3179 3518 ret = gendb_search_dn(secret_state->sam_ldb,mem_ctx, … … 3182 3521 return NT_STATUS_OBJECT_NAME_NOT_FOUND; 3183 3522 } 3184 3523 3185 3524 if (ret != 1) { 3186 3525 DEBUG(0,("Found %d records matching dn=%s\n", ret, … … 3188 3527 return NT_STATUS_INTERNAL_DB_CORRUPTION; 3189 3528 } 3190 3529 3191 3530 old_val = ldb_msg_find_ldb_val(res[0], "currentValue"); 3192 3531 last_set_time = ldb_msg_find_attr_as_uint64(res[0], "lastSetTime", 0); 3193 3532 3194 3533 if (old_val) { 3195 3534 /* set old value */ 3196 3535 if (ldb_msg_add_value(msg, "priorValue", 3197 3536 old_val, NULL) != LDB_SUCCESS) { 3198 return NT_STATUS_NO_MEMORY; 3537 return NT_STATUS_NO_MEMORY; 3199 3538 } 3200 3539 } else { 3201 if (samdb_msg_add_delete(secret_state->sam_ldb, 3540 if (samdb_msg_add_delete(secret_state->sam_ldb, 3202 3541 mem_ctx, msg, "priorValue") != LDB_SUCCESS) { 3203 3542 return NT_STATUS_NO_MEMORY; 3204 3543 } 3205 3206 } 3207 3544 } 3545 3208 3546 /* set old value mtime */ 3209 3547 if (ldb_msg_find_ldb_val(res[0], "lastSetTime")) { 3210 if (samdb_msg_add_uint64(secret_state->sam_ldb, 3548 if (samdb_msg_add_uint64(secret_state->sam_ldb, 3211 3549 mem_ctx, msg, "priorSetTime", last_set_time) != LDB_SUCCESS) { 3212 return NT_STATUS_NO_MEMORY; 3550 return NT_STATUS_NO_MEMORY; 3213 3551 } 3214 3552 } else { 3215 if (samdb_msg_add_uint64(secret_state->sam_ldb, 3553 if (samdb_msg_add_uint64(secret_state->sam_ldb, 3216 3554 mem_ctx, msg, "priorSetTime", nt_now) != LDB_SUCCESS) { 3217 return NT_STATUS_NO_MEMORY; 3555 return NT_STATUS_NO_MEMORY; 3218 3556 } 3219 3557 } … … 3224 3562 crypt_secret.data = r->in.new_val->data; 3225 3563 crypt_secret.length = r->in.new_val->size; 3226 3564 3227 3565 status = sess_decrypt_blob(mem_ctx, &crypt_secret, &session_key, &secret); 3228 3566 if (!NT_STATUS_IS_OK(status)) { 3229 3567 return status; 3230 3568 } 3231 3569 3232 3570 val.data = secret.data; 3233 3571 val.length = secret.length; 3234 3572 3235 3573 /* set value */ 3236 3574 if (ldb_msg_add_value(msg, "currentValue", &val, NULL) != LDB_SUCCESS) { 3237 return NT_STATUS_NO_MEMORY; 3238 } 3239 3575 return NT_STATUS_NO_MEMORY; 3576 } 3577 3240 3578 /* set new value mtime */ 3241 if (samdb_msg_add_uint64(secret_state->sam_ldb, 3579 if (samdb_msg_add_uint64(secret_state->sam_ldb, 3242 3580 mem_ctx, msg, "lastSetTime", nt_now) != LDB_SUCCESS) { 3243 return NT_STATUS_NO_MEMORY; 3244 } 3245 3581 return NT_STATUS_NO_MEMORY; 3582 } 3246 3583 } else { 3247 3584 /* NULL out the NEW value */ 3248 if (samdb_msg_add_uint64(secret_state->sam_ldb, 3585 if (samdb_msg_add_uint64(secret_state->sam_ldb, 3249 3586 mem_ctx, msg, "lastSetTime", nt_now) != LDB_SUCCESS) { 3250 return NT_STATUS_NO_MEMORY; 3251 } 3252 if (samdb_msg_add_delete(secret_state->sam_ldb, 3587 return NT_STATUS_NO_MEMORY; 3588 } 3589 if (samdb_msg_add_delete(secret_state->sam_ldb, 3253 3590 mem_ctx, msg, "currentValue") != LDB_SUCCESS) { 3254 3591 return NT_STATUS_NO_MEMORY; … … 3259 3596 ret = dsdb_replace(secret_state->sam_ldb, msg, 0); 3260 3597 if (ret != LDB_SUCCESS) { 3261 /* we really need samdb.c to return NTSTATUS */ 3262 return NT_STATUS_UNSUCCESSFUL; 3598 return dsdb_ldb_err_to_ntstatus(ret); 3263 3599 } 3264 3600 … … 3267 3603 3268 3604 3269 /* 3270 lsa_QuerySecret 3605 /* 3606 lsa_QuerySecret 3271 3607 */ 3272 3608 static NTSTATUS dcesrv_lsa_QuerySecret(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, … … 3284 3620 "priorValue", 3285 3621 "lastSetTime", 3286 "priorSetTime", 3622 "priorSetTime", 3287 3623 NULL 3288 3624 }; … … 3312 3648 } 3313 3649 msg = res[0]; 3314 3650 3315 3651 nt_status = dcesrv_fetch_session_key(dce_call->conn, &session_key); 3316 3652 if (!NT_STATUS_IS_OK(nt_status)) { 3317 3653 return nt_status; 3318 3654 } 3319 3655 3320 3656 if (r->in.old_val) { 3321 3657 const struct ldb_val *prior_val; … … 3324 3660 return NT_STATUS_NO_MEMORY; 3325 3661 } 3326 prior_val = ldb_msg_find_ldb_val( res[0], "priorValue");3327 3662 prior_val = ldb_msg_find_ldb_val(msg, "priorValue"); 3663 3328 3664 if (prior_val && prior_val->length) { 3329 3665 secret.data = prior_val->data; 3330 3666 secret.length = prior_val->length; 3331 3667 3332 3668 /* Encrypt */ 3333 3669 crypt_secret = sess_encrypt_blob(mem_ctx, &secret, &session_key); … … 3344 3680 } 3345 3681 } 3346 3682 3347 3683 if (r->in.old_mtime) { 3348 3684 r->out.old_mtime = talloc(mem_ctx, NTTIME); … … 3350 3686 return NT_STATUS_NO_MEMORY; 3351 3687 } 3352 *r->out.old_mtime = ldb_msg_find_attr_as_uint64( res[0], "priorSetTime", 0);3353 } 3354 3688 *r->out.old_mtime = ldb_msg_find_attr_as_uint64(msg, "priorSetTime", 0); 3689 } 3690 3355 3691 if (r->in.new_val) { 3356 3692 const struct ldb_val *new_val; … … 3360 3696 } 3361 3697 3362 new_val = ldb_msg_find_ldb_val( res[0], "currentValue");3363 3698 new_val = ldb_msg_find_ldb_val(msg, "currentValue"); 3699 3364 3700 if (new_val && new_val->length) { 3365 3701 secret.data = new_val->data; 3366 3702 secret.length = new_val->length; 3367 3703 3368 3704 /* Encrypt */ 3369 3705 crypt_secret = sess_encrypt_blob(mem_ctx, &secret, &session_key); … … 3380 3716 } 3381 3717 } 3382 3718 3383 3719 if (r->in.new_mtime) { 3384 3720 r->out.new_mtime = talloc(mem_ctx, NTTIME); … … 3386 3722 return NT_STATUS_NO_MEMORY; 3387 3723 } 3388 *r->out.new_mtime = ldb_msg_find_attr_as_uint64( res[0], "lastSetTime", 0);3389 } 3390 3724 *r->out.new_mtime = ldb_msg_find_attr_as_uint64(msg, "lastSetTime", 0); 3725 } 3726 3391 3727 return NT_STATUS_OK; 3392 3728 } 3393 3729 3394 3730 3395 /* 3731 /* 3396 3732 lsa_LookupPrivValue 3397 3733 */ 3398 static NTSTATUS dcesrv_lsa_LookupPrivValue(struct dcesrv_call_state *dce_call, 3734 static NTSTATUS dcesrv_lsa_LookupPrivValue(struct dcesrv_call_state *dce_call, 3399 3735 TALLOC_CTX *mem_ctx, 3400 3736 struct lsa_LookupPrivValue *r) 3401 3737 { 3402 3738 struct dcesrv_handle *h; 3403 struct lsa_policy_state *state;3404 3739 int id; 3405 3740 3406 3741 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY); 3407 3408 state = h->data;3409 3742 3410 3743 id = sec_privilege_id(r->in.name->string); … … 3416 3749 r->out.luid->high = 0; 3417 3750 3418 return NT_STATUS_OK; 3419 } 3420 3421 3422 /* 3423 lsa_LookupPrivName 3424 */ 3425 static NTSTATUS dcesrv_lsa_LookupPrivName(struct dcesrv_call_state *dce_call, 3751 return NT_STATUS_OK; 3752 } 3753 3754 3755 /* 3756 lsa_LookupPrivName 3757 */ 3758 static NTSTATUS dcesrv_lsa_LookupPrivName(struct dcesrv_call_state *dce_call, 3426 3759 TALLOC_CTX *mem_ctx, 3427 3760 struct lsa_LookupPrivName *r) 3428 3761 { 3429 3762 struct dcesrv_handle *h; 3430 struct lsa_policy_state *state;3431 3763 struct lsa_StringLarge *name; 3432 3764 const char *privname; 3433 3765 3434 3766 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY); 3435 3436 state = h->data;3437 3767 3438 3768 if (r->in.luid->high != 0) { … … 3454 3784 *r->out.name = name; 3455 3785 3456 return NT_STATUS_OK; 3457 } 3458 3459 3460 /* 3786 return NT_STATUS_OK; 3787 } 3788 3789 3790 /* 3461 3791 lsa_LookupPrivDisplayName 3462 3792 */ 3463 static NTSTATUS dcesrv_lsa_LookupPrivDisplayName(struct dcesrv_call_state *dce_call, 3793 static NTSTATUS dcesrv_lsa_LookupPrivDisplayName(struct dcesrv_call_state *dce_call, 3464 3794 TALLOC_CTX *mem_ctx, 3465 3795 struct lsa_LookupPrivDisplayName *r) 3466 3796 { 3467 3797 struct dcesrv_handle *h; 3468 struct lsa_policy_state *state;3469 3798 struct lsa_StringLarge *disp_name = NULL; 3470 3799 enum sec_privilege id; 3471 3800 3472 3801 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY); 3473 3474 state = h->data;3475 3802 3476 3803 id = sec_privilege_id(r->in.name->string); … … 3496 3823 3497 3824 3498 /* 3825 /* 3499 3826 lsa_EnumAccountsWithUserRight 3500 3827 */ 3501 static NTSTATUS dcesrv_lsa_EnumAccountsWithUserRight(struct dcesrv_call_state *dce_call, 3828 static NTSTATUS dcesrv_lsa_EnumAccountsWithUserRight(struct dcesrv_call_state *dce_call, 3502 3829 TALLOC_CTX *mem_ctx, 3503 3830 struct lsa_EnumAccountsWithUserRight *r) … … 3516 3843 if (r->in.name == NULL) { 3517 3844 return NT_STATUS_NO_SUCH_PRIVILEGE; 3518 } 3845 } 3519 3846 3520 3847 privname = r->in.name->string; … … 3523 3850 } 3524 3851 3525 ret = gendb_search(state->pdb, mem_ctx, NULL, &res, attrs, 3852 ret = gendb_search(state->pdb, mem_ctx, NULL, &res, attrs, 3526 3853 "privilege=%s", privname); 3527 3854 if (ret < 0) { … … 3547 3874 3548 3875 3549 /* 3876 /* 3550 3877 lsa_AddAccountRights 3551 3878 */ 3552 static NTSTATUS dcesrv_lsa_AddAccountRights(struct dcesrv_call_state *dce_call, 3879 static NTSTATUS dcesrv_lsa_AddAccountRights(struct dcesrv_call_state *dce_call, 3553 3880 TALLOC_CTX *mem_ctx, 3554 3881 struct lsa_AddAccountRights *r) … … 3561 3888 state = h->data; 3562 3889 3563 return dcesrv_lsa_AddRemoveAccountRights(dce_call, mem_ctx, state, 3890 return dcesrv_lsa_AddRemoveAccountRights(dce_call, mem_ctx, state, 3564 3891 LDB_FLAG_MOD_ADD, 3565 3892 r->in.sid, r->in.rights); … … 3567 3894 3568 3895 3569 /* 3896 /* 3570 3897 lsa_RemoveAccountRights 3571 3898 */ 3572 static NTSTATUS dcesrv_lsa_RemoveAccountRights(struct dcesrv_call_state *dce_call, 3899 static NTSTATUS dcesrv_lsa_RemoveAccountRights(struct dcesrv_call_state *dce_call, 3573 3900 TALLOC_CTX *mem_ctx, 3574 3901 struct lsa_RemoveAccountRights *r) … … 3581 3908 state = h->data; 3582 3909 3583 return dcesrv_lsa_AddRemoveAccountRights(dce_call, mem_ctx, state, 3910 return dcesrv_lsa_AddRemoveAccountRights(dce_call, mem_ctx, state, 3584 3911 LDB_FLAG_MOD_DELETE, 3585 3912 r->in.sid, r->in.rights); … … 3587 3914 3588 3915 3589 /* 3916 /* 3590 3917 lsa_StorePrivateData 3591 3918 */ … … 3597 3924 3598 3925 3599 /* 3926 /* 3600 3927 lsa_RetrievePrivateData 3601 3928 */ … … 3607 3934 3608 3935 3609 /* 3936 /* 3610 3937 lsa_GetUserName 3611 3938 */ … … 3613 3940 struct lsa_GetUserName *r) 3614 3941 { 3942 enum dcerpc_transport_t transport = 3943 dcerpc_binding_get_transport(dce_call->conn->endpoint->ep_description); 3615 3944 NTSTATUS status = NT_STATUS_OK; 3616 3945 const char *account_name; … … 3619 3948 struct lsa_String *_authority_name = NULL; 3620 3949 3950 if (transport != NCACN_NP && transport != NCALRPC) { 3951 DCESRV_FAULT(DCERPC_FAULT_ACCESS_DENIED); 3952 } 3953 3621 3954 /* this is what w2k3 does */ 3622 3955 r->out.account_name = r->in.account_name; … … 3669 4002 } 3670 4003 4004 static void kdc_get_policy(struct loadparm_context *lp_ctx, 4005 struct smb_krb5_context *smb_krb5_context, 4006 struct lsa_DomainInfoKerberos *k) 4007 { 4008 time_t svc_tkt_lifetime; 4009 time_t usr_tkt_lifetime; 4010 time_t renewal_lifetime; 4011 4012 /* These should be set and stored via Group Policy, but until then, some defaults are in order */ 4013 4014 /* Our KDC always re-validates the client */ 4015 k->authentication_options = LSA_POLICY_KERBEROS_VALIDATE_CLIENT; 4016 4017 lpcfg_default_kdc_policy(lp_ctx, &svc_tkt_lifetime, 4018 &usr_tkt_lifetime, &renewal_lifetime); 4019 4020 unix_to_nt_time(&k->service_tkt_lifetime, svc_tkt_lifetime); 4021 unix_to_nt_time(&k->user_tkt_lifetime, usr_tkt_lifetime); 4022 unix_to_nt_time(&k->user_tkt_renewaltime, renewal_lifetime); 4023 #ifdef SAMBA4_USES_HEIMDAL /* MIT lacks krb5_get_max_time_skew. 4024 However in the parent function we basically just did a full 4025 krb5_context init with the only purpose of getting a global 4026 config option (the max skew), it would probably make more sense 4027 to have a lp_ or ldb global option as the samba default */ 4028 if (smb_krb5_context) { 4029 unix_to_nt_time(&k->clock_skew, 4030 krb5_get_max_time_skew(smb_krb5_context->krb5_context)); 4031 } 4032 #endif 4033 k->reserved = 0; 4034 } 3671 4035 /* 3672 4036 lsa_QueryDomainInformationPolicy … … 3692 4056 struct lsa_DomainInfoKerberos *k = &info->kerberos_info; 3693 4057 struct smb_krb5_context *smb_krb5_context; 3694 int ret = smb_krb5_init_context(mem_ctx, 3695 dce_call->event_ctx, 4058 int ret = smb_krb5_init_context(mem_ctx, 3696 4059 dce_call->conn->dce_ctx->lp_ctx, 3697 4060 &smb_krb5_context); … … 3735 4098 } 3736 4099 3737 /* 3738 lsa_CREDRWRITE 4100 /* 4101 lsa_CREDRWRITE 3739 4102 */ 3740 4103 static NTSTATUS dcesrv_lsa_CREDRWRITE(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, … … 3745 4108 3746 4109 3747 /* 3748 lsa_CREDRREAD 4110 /* 4111 lsa_CREDRREAD 3749 4112 */ 3750 4113 static NTSTATUS dcesrv_lsa_CREDRREAD(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, … … 3755 4118 3756 4119 3757 /* 3758 lsa_CREDRENUMERATE 4120 /* 4121 lsa_CREDRENUMERATE 3759 4122 */ 3760 4123 static NTSTATUS dcesrv_lsa_CREDRENUMERATE(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, … … 3765 4128 3766 4129 3767 /* 3768 lsa_CREDRWRITEDOMAINCREDENTIALS 4130 /* 4131 lsa_CREDRWRITEDOMAINCREDENTIALS 3769 4132 */ 3770 4133 static NTSTATUS dcesrv_lsa_CREDRWRITEDOMAINCREDENTIALS(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, … … 3775 4138 3776 4139 3777 /* 3778 lsa_CREDRREADDOMAINCREDENTIALS 4140 /* 4141 lsa_CREDRREADDOMAINCREDENTIALS 3779 4142 */ 3780 4143 static NTSTATUS dcesrv_lsa_CREDRREADDOMAINCREDENTIALS(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, … … 3785 4148 3786 4149 3787 /* 3788 lsa_CREDRDELETE 4150 /* 4151 lsa_CREDRDELETE 3789 4152 */ 3790 4153 static NTSTATUS dcesrv_lsa_CREDRDELETE(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, … … 3795 4158 3796 4159 3797 /* 3798 lsa_CREDRGETTARGETINFO 4160 /* 4161 lsa_CREDRGETTARGETINFO 3799 4162 */ 3800 4163 static NTSTATUS dcesrv_lsa_CREDRGETTARGETINFO(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, … … 3805 4168 3806 4169 3807 /* 3808 lsa_CREDRPROFILELOADED 4170 /* 4171 lsa_CREDRPROFILELOADED 3809 4172 */ 3810 4173 static NTSTATUS dcesrv_lsa_CREDRPROFILELOADED(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, … … 3815 4178 3816 4179 3817 /* 3818 lsa_CREDRGETSESSIONTYPES 4180 /* 4181 lsa_CREDRGETSESSIONTYPES 3819 4182 */ 3820 4183 static NTSTATUS dcesrv_lsa_CREDRGETSESSIONTYPES(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, … … 3825 4188 3826 4189 3827 /* 3828 lsa_LSARREGISTERAUDITEVENT 4190 /* 4191 lsa_LSARREGISTERAUDITEVENT 3829 4192 */ 3830 4193 static NTSTATUS dcesrv_lsa_LSARREGISTERAUDITEVENT(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, … … 3835 4198 3836 4199 3837 /* 3838 lsa_LSARGENAUDITEVENT 4200 /* 4201 lsa_LSARGENAUDITEVENT 3839 4202 */ 3840 4203 static NTSTATUS dcesrv_lsa_LSARGENAUDITEVENT(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, … … 3845 4208 3846 4209 3847 /* 3848 lsa_LSARUNREGISTERAUDITEVENT 4210 /* 4211 lsa_LSARUNREGISTERAUDITEVENT 3849 4212 */ 3850 4213 static NTSTATUS dcesrv_lsa_LSARUNREGISTERAUDITEVENT(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, … … 3855 4218 3856 4219 3857 /* 3858 lsa_lsaRQueryForestTrustInformation 4220 /* 4221 lsa_lsaRQueryForestTrustInformation 3859 4222 */ 3860 4223 static NTSTATUS dcesrv_lsa_lsaRQueryForestTrustInformation(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, 3861 4224 struct lsa_lsaRQueryForestTrustInformation *r) 3862 4225 { 3863 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR); 3864 } 3865 3866 #define DNS_CMP_MATCH 0 3867 #define DNS_CMP_FIRST_IS_CHILD 1 3868 #define DNS_CMP_SECOND_IS_CHILD 2 3869 #define DNS_CMP_NO_MATCH 3 3870 3871 /* this function assumes names are well formed DNS names. 3872 * it doesn't validate them */ 3873 static int dns_cmp(const char *s1, size_t l1, 3874 const char *s2, size_t l2) 3875 { 3876 const char *p1, *p2; 3877 size_t t1, t2; 3878 int cret; 3879 3880 if (l1 == l2) { 3881 if (strcasecmp_m(s1, s2) == 0) { 3882 return DNS_CMP_MATCH; 3883 } 3884 return DNS_CMP_NO_MATCH; 3885 } 3886 3887 if (l1 > l2) { 3888 p1 = s1; 3889 p2 = s2; 3890 t1 = l1; 3891 t2 = l2; 3892 cret = DNS_CMP_FIRST_IS_CHILD; 3893 } else { 3894 p1 = s2; 3895 p2 = s1; 3896 t1 = l2; 3897 t2 = l1; 3898 cret = DNS_CMP_SECOND_IS_CHILD; 3899 } 3900 3901 if (p1[t1 - t2 - 1] != '.') { 3902 return DNS_CMP_NO_MATCH; 3903 } 3904 3905 if (strcasecmp_m(&p1[t1 - t2], p2) == 0) { 3906 return cret; 3907 } 3908 3909 return DNS_CMP_NO_MATCH; 3910 } 3911 3912 /* decode all TDOs forest trust info blobs */ 3913 static NTSTATUS get_ft_info(TALLOC_CTX *mem_ctx, 3914 struct ldb_message *msg, 3915 struct ForestTrustInfo *info) 3916 { 3917 const struct ldb_val *ft_blob; 3918 enum ndr_err_code ndr_err; 3919 3920 ft_blob = ldb_msg_find_ldb_val(msg, "msDS-TrustForestTrustInfo"); 3921 if (!ft_blob || !ft_blob->data) { 3922 return NT_STATUS_OBJECT_NAME_NOT_FOUND; 3923 } 3924 /* ldb_val is equivalent to DATA_BLOB */ 3925 ndr_err = ndr_pull_struct_blob_all(ft_blob, mem_ctx, info, 3926 (ndr_pull_flags_fn_t)ndr_pull_ForestTrustInfo); 3927 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { 4226 struct dcesrv_handle *h = NULL; 4227 struct lsa_policy_state *p_state = NULL; 4228 int forest_level = DS_DOMAIN_FUNCTION_2000; 4229 const char * const trust_attrs[] = { 4230 "securityIdentifier", 4231 "flatName", 4232 "trustPartner", 4233 "trustAttributes", 4234 "trustDirection", 4235 "trustType", 4236 "msDS-TrustForestTrustInfo", 4237 NULL 4238 }; 4239 struct ldb_message *trust_tdo_msg = NULL; 4240 struct lsa_TrustDomainInfoInfoEx *trust_tdo = NULL; 4241 struct ForestTrustInfo *trust_fti = NULL; 4242 struct lsa_ForestTrustInformation *trust_lfti = NULL; 4243 NTSTATUS status; 4244 4245 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY); 4246 4247 p_state = h->data; 4248 4249 if (strcmp(p_state->domain_dns, p_state->forest_dns)) { 3928 4250 return NT_STATUS_INVALID_DOMAIN_STATE; 3929 4251 } 3930 4252 3931 return NT_STATUS_OK; 3932 } 3933 3934 static NTSTATUS own_ft_info(struct lsa_policy_state *ps, 3935 struct ForestTrustInfo *fti) 3936 { 3937 struct ForestTrustDataDomainInfo *info; 3938 struct ForestTrustInfoRecord *rec; 3939 3940 fti->version = 1; 3941 fti->count = 2; 3942 fti->records = talloc_array(fti, 3943 struct ForestTrustInfoRecordArmor, 2); 3944 if (!fti->records) { 3945 return NT_STATUS_NO_MEMORY; 3946 } 3947 3948 /* TLN info */ 3949 rec = &fti->records[0].record; 3950 3951 rec->flags = 0; 3952 rec->timestamp = 0; 3953 rec->type = LSA_FOREST_TRUST_TOP_LEVEL_NAME; 3954 3955 rec->data.name.string = talloc_strdup(fti, ps->forest_dns); 3956 if (!rec->data.name.string) { 3957 return NT_STATUS_NO_MEMORY; 3958 } 3959 rec->data.name.size = strlen(rec->data.name.string); 3960 3961 /* DOMAIN info */ 3962 rec = &fti->records[1].record; 3963 3964 rec->flags = 0; 3965 rec->timestamp = 0; 3966 rec->type = LSA_FOREST_TRUST_DOMAIN_INFO; 3967 3968 info = &rec->data.info; 3969 3970 info->sid = *ps->domain_sid; 3971 info->dns_name.string = talloc_strdup(fti, ps->domain_dns); 3972 if (!info->dns_name.string) { 3973 return NT_STATUS_NO_MEMORY; 3974 } 3975 info->dns_name.size = strlen(info->dns_name.string); 3976 info->netbios_name.string = talloc_strdup(fti, ps->domain_name); 3977 if (!info->netbios_name.string) { 3978 return NT_STATUS_NO_MEMORY; 3979 } 3980 info->netbios_name.size = strlen(info->netbios_name.string); 3981 3982 return NT_STATUS_OK; 3983 } 3984 3985 static NTSTATUS make_ft_info(TALLOC_CTX *mem_ctx, 3986 struct lsa_ForestTrustInformation *lfti, 3987 struct ForestTrustInfo *fti) 3988 { 3989 struct lsa_ForestTrustRecord *lrec; 3990 struct ForestTrustInfoRecord *rec; 3991 struct lsa_StringLarge *tln; 3992 struct lsa_ForestTrustDomainInfo *info; 3993 uint32_t i; 3994 3995 fti->version = 1; 3996 fti->count = lfti->count; 3997 fti->records = talloc_array(mem_ctx, 3998 struct ForestTrustInfoRecordArmor, 3999 fti->count); 4000 if (!fti->records) { 4001 return NT_STATUS_NO_MEMORY; 4002 } 4003 for (i = 0; i < fti->count; i++) { 4004 lrec = lfti->entries[i]; 4005 rec = &fti->records[i].record; 4006 4007 rec->flags = lrec->flags; 4008 rec->timestamp = lrec->time; 4009 rec->type = lrec->type; 4010 4011 switch (lrec->type) { 4012 case LSA_FOREST_TRUST_TOP_LEVEL_NAME: 4013 case LSA_FOREST_TRUST_TOP_LEVEL_NAME_EX: 4014 tln = &lrec->forest_trust_data.top_level_name; 4015 rec->data.name.string = 4016 talloc_strdup(mem_ctx, tln->string); 4017 if (!rec->data.name.string) { 4018 return NT_STATUS_NO_MEMORY; 4019 } 4020 rec->data.name.size = strlen(rec->data.name.string); 4021 break; 4022 case LSA_FOREST_TRUST_DOMAIN_INFO: 4023 info = &lrec->forest_trust_data.domain_info; 4024 rec->data.info.sid = *info->domain_sid; 4025 rec->data.info.dns_name.string = 4026 talloc_strdup(mem_ctx, 4027 info->dns_domain_name.string); 4028 if (!rec->data.info.dns_name.string) { 4029 return NT_STATUS_NO_MEMORY; 4030 } 4031 rec->data.info.dns_name.size = 4032 strlen(rec->data.info.dns_name.string); 4033 rec->data.info.netbios_name.string = 4034 talloc_strdup(mem_ctx, 4035 info->netbios_domain_name.string); 4036 if (!rec->data.info.netbios_name.string) { 4037 return NT_STATUS_NO_MEMORY; 4038 } 4039 rec->data.info.netbios_name.size = 4040 strlen(rec->data.info.netbios_name.string); 4041 break; 4042 default: 4043 return NT_STATUS_INVALID_DOMAIN_STATE; 4044 } 4045 } 4046 4047 return NT_STATUS_OK; 4048 } 4049 4050 static NTSTATUS add_collision(struct lsa_ForestTrustCollisionInfo *c_info, 4051 uint32_t idx, uint32_t collision_type, 4052 uint32_t conflict_type, const char *tdo_name); 4053 4054 static NTSTATUS check_ft_info(TALLOC_CTX *mem_ctx, 4055 const char *tdo_name, 4056 struct ForestTrustInfo *tdo_fti, 4057 struct ForestTrustInfo *new_fti, 4058 struct lsa_ForestTrustCollisionInfo *c_info) 4059 { 4060 struct ForestTrustInfoRecord *nrec; 4061 struct ForestTrustInfoRecord *trec; 4062 const char *dns_name; 4063 const char *nb_name; 4064 struct dom_sid *sid; 4065 const char *tname; 4066 size_t dns_len; 4067 size_t nb_len; 4068 size_t tlen; 4069 NTSTATUS nt_status; 4070 uint32_t new_fti_idx; 4071 uint32_t i; 4072 /* use always TDO type, until we understand when Xref can be used */ 4073 uint32_t collision_type = LSA_FOREST_TRUST_COLLISION_TDO; 4074 bool tln_conflict; 4075 bool sid_conflict; 4076 bool nb_conflict; 4077 bool exclusion; 4078 bool ex_rule; 4079 int ret; 4080 4081 for (new_fti_idx = 0; new_fti_idx < new_fti->count; new_fti_idx++) { 4082 4083 nrec = &new_fti->records[new_fti_idx].record; 4084 dns_name = NULL; 4085 tln_conflict = false; 4086 sid_conflict = false; 4087 nb_conflict = false; 4088 exclusion = false; 4089 4090 switch (nrec->type) { 4091 case LSA_FOREST_TRUST_TOP_LEVEL_NAME_EX: 4092 /* exclusions do not conflict by definition */ 4093 break; 4094 4095 case FOREST_TRUST_TOP_LEVEL_NAME: 4096 dns_name = nrec->data.name.string; 4097 dns_len = nrec->data.name.size; 4098 break; 4099 4100 case LSA_FOREST_TRUST_DOMAIN_INFO: 4101 dns_name = nrec->data.info.dns_name.string; 4102 dns_len = nrec->data.info.dns_name.size; 4103 nb_name = nrec->data.info.netbios_name.string; 4104 nb_len = nrec->data.info.netbios_name.size; 4105 sid = &nrec->data.info.sid; 4106 break; 4107 } 4108 4109 if (!dns_name) continue; 4110 4111 /* check if this is already taken and not excluded */ 4112 for (i = 0; i < tdo_fti->count; i++) { 4113 trec = &tdo_fti->records[i].record; 4114 4115 switch (trec->type) { 4116 case FOREST_TRUST_TOP_LEVEL_NAME: 4117 ex_rule = false; 4118 tname = trec->data.name.string; 4119 tlen = trec->data.name.size; 4120 break; 4121 case FOREST_TRUST_TOP_LEVEL_NAME_EX: 4122 ex_rule = true; 4123 tname = trec->data.name.string; 4124 tlen = trec->data.name.size; 4125 break; 4126 case FOREST_TRUST_DOMAIN_INFO: 4127 ex_rule = false; 4128 tname = trec->data.info.dns_name.string; 4129 tlen = trec->data.info.dns_name.size; 4130 } 4131 ret = dns_cmp(dns_name, dns_len, tname, tlen); 4132 switch (ret) { 4133 case DNS_CMP_MATCH: 4134 /* if it matches exclusion, 4135 * it doesn't conflict */ 4136 if (ex_rule) { 4137 exclusion = true; 4138 break; 4139 } 4140 /* fall through */ 4141 case DNS_CMP_FIRST_IS_CHILD: 4142 case DNS_CMP_SECOND_IS_CHILD: 4143 tln_conflict = true; 4144 /* fall through */ 4145 default: 4146 break; 4147 } 4148 4149 /* explicit exclusion, no dns name conflict here */ 4150 if (exclusion) { 4151 tln_conflict = false; 4152 } 4153 4154 if (trec->type != FOREST_TRUST_DOMAIN_INFO) { 4155 continue; 4156 } 4157 4158 /* also test for domain info */ 4159 if (!(trec->flags & LSA_SID_DISABLED_ADMIN) && 4160 dom_sid_compare(&trec->data.info.sid, sid) == 0) { 4161 sid_conflict = true; 4162 } 4163 if (!(trec->flags & LSA_NB_DISABLED_ADMIN) && 4164 strcasecmp_m(trec->data.info.netbios_name.string, 4165 nb_name) == 0) { 4166 nb_conflict = true; 4167 } 4168 } 4169 4170 if (tln_conflict) { 4171 nt_status = add_collision(c_info, new_fti_idx, 4172 collision_type, 4173 LSA_TLN_DISABLED_CONFLICT, 4174 tdo_name); 4175 } 4176 if (sid_conflict) { 4177 nt_status = add_collision(c_info, new_fti_idx, 4178 collision_type, 4179 LSA_SID_DISABLED_CONFLICT, 4180 tdo_name); 4181 } 4182 if (nb_conflict) { 4183 nt_status = add_collision(c_info, new_fti_idx, 4184 collision_type, 4185 LSA_NB_DISABLED_CONFLICT, 4186 tdo_name); 4187 } 4188 } 4189 4190 return NT_STATUS_OK; 4191 } 4192 4193 static NTSTATUS add_collision(struct lsa_ForestTrustCollisionInfo *c_info, 4194 uint32_t idx, uint32_t collision_type, 4195 uint32_t conflict_type, const char *tdo_name) 4196 { 4197 struct lsa_ForestTrustCollisionRecord **es; 4198 uint32_t i = c_info->count; 4199 4200 es = talloc_realloc(c_info, c_info->entries, 4201 struct lsa_ForestTrustCollisionRecord *, i + 1); 4202 if (!es) { 4203 return NT_STATUS_NO_MEMORY; 4204 } 4205 c_info->entries = es; 4206 c_info->count = i + 1; 4207 4208 es[i] = talloc(es, struct lsa_ForestTrustCollisionRecord); 4209 if (!es[i]) { 4210 return NT_STATUS_NO_MEMORY; 4211 } 4212 4213 es[i]->index = idx; 4214 es[i]->type = collision_type; 4215 es[i]->flags.flags = conflict_type; 4216 es[i]->name.string = talloc_strdup(es[i], tdo_name); 4217 if (!es[i]->name.string) { 4218 return NT_STATUS_NO_MEMORY; 4219 } 4220 es[i]->name.size = strlen(es[i]->name.string); 4221 4253 forest_level = dsdb_forest_functional_level(p_state->sam_ldb); 4254 if (forest_level < DS_DOMAIN_FUNCTION_2003) { 4255 return NT_STATUS_INVALID_DOMAIN_STATE; 4256 } 4257 4258 if (r->in.trusted_domain_name->string == NULL) { 4259 return NT_STATUS_NO_SUCH_DOMAIN; 4260 } 4261 4262 status = dsdb_trust_search_tdo(p_state->sam_ldb, 4263 r->in.trusted_domain_name->string, 4264 r->in.trusted_domain_name->string, 4265 trust_attrs, mem_ctx, &trust_tdo_msg); 4266 if (NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) { 4267 return NT_STATUS_NO_SUCH_DOMAIN; 4268 } 4269 if (!NT_STATUS_IS_OK(status)) { 4270 return status; 4271 } 4272 4273 status = dsdb_trust_parse_tdo_info(mem_ctx, trust_tdo_msg, &trust_tdo); 4274 if (!NT_STATUS_IS_OK(status)) { 4275 return status; 4276 } 4277 4278 if (!(trust_tdo->trust_attributes & LSA_TRUST_ATTRIBUTE_FOREST_TRANSITIVE)) { 4279 return NT_STATUS_INVALID_PARAMETER; 4280 } 4281 4282 if (r->in.highest_record_type >= LSA_FOREST_TRUST_RECORD_TYPE_LAST) { 4283 return NT_STATUS_INVALID_PARAMETER; 4284 } 4285 4286 status = dsdb_trust_parse_forest_info(mem_ctx, 4287 trust_tdo_msg, 4288 &trust_fti); 4289 if (!NT_STATUS_IS_OK(status)) { 4290 return status; 4291 } 4292 4293 status = dsdb_trust_forest_info_to_lsa(mem_ctx, trust_fti, 4294 &trust_lfti); 4295 if (!NT_STATUS_IS_OK(status)) { 4296 return status; 4297 } 4298 4299 *r->out.forest_trust_info = trust_lfti; 4222 4300 return NT_STATUS_OK; 4223 4301 } … … 4232 4310 struct dcesrv_handle *h; 4233 4311 struct lsa_policy_state *p_state; 4234 const char *trust_attrs[] = { "trustPartner", "trustAttributes", 4235 "msDS-TrustForestTrustInfo", NULL }; 4236 struct ldb_message **dom_res = NULL; 4237 struct ldb_dn *tdo_dn; 4238 struct ldb_message *msg; 4239 int num_res, i; 4240 const char *td_name; 4241 uint32_t trust_attributes; 4242 struct lsa_ForestTrustCollisionInfo *c_info; 4243 struct ForestTrustInfo *nfti; 4244 struct ForestTrustInfo *fti; 4245 DATA_BLOB ft_blob; 4312 const char * const trust_attrs[] = { 4313 "securityIdentifier", 4314 "flatName", 4315 "trustPartner", 4316 "trustAttributes", 4317 "trustDirection", 4318 "trustType", 4319 "msDS-TrustForestTrustInfo", 4320 NULL 4321 }; 4322 struct ldb_message *trust_tdo_msg = NULL; 4323 struct lsa_TrustDomainInfoInfoEx *trust_tdo = NULL; 4324 struct lsa_ForestTrustInformation *step1_lfti = NULL; 4325 struct lsa_ForestTrustInformation *step2_lfti = NULL; 4326 struct ForestTrustInfo *trust_fti = NULL; 4327 struct ldb_result *trusts_res = NULL; 4328 unsigned int i; 4329 struct lsa_TrustDomainInfoInfoEx *xref_tdo = NULL; 4330 struct lsa_ForestTrustInformation *xref_lfti = NULL; 4331 struct lsa_ForestTrustCollisionInfo *c_info = NULL; 4332 DATA_BLOB ft_blob = {}; 4333 struct ldb_message *msg = NULL; 4334 NTSTATUS status; 4246 4335 enum ndr_err_code ndr_err; 4247 NTSTATUS nt_status;4248 bool am_rodc;4249 4336 int ret; 4337 bool in_transaction = false; 4250 4338 4251 4339 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY); … … 4257 4345 } 4258 4346 4259 /* abort if we are not a PDC */ 4347 if (r->in.check_only == 0) { 4348 ret = ldb_transaction_start(p_state->sam_ldb); 4349 if (ret != LDB_SUCCESS) { 4350 return NT_STATUS_INTERNAL_DB_CORRUPTION; 4351 } 4352 in_transaction = true; 4353 } 4354 4355 /* 4356 * abort if we are not a PDC 4357 * 4358 * In future we should use a function like IsEffectiveRoleOwner() 4359 */ 4260 4360 if (!samdb_is_pdc(p_state->sam_ldb)) { 4261 return NT_STATUS_INVALID_DOMAIN_ROLE; 4262 } 4263 4264 ret = samdb_rodc(p_state->sam_ldb, &am_rodc); 4265 if (ret == LDB_SUCCESS && am_rodc) { 4266 return NT_STATUS_NO_SUCH_DOMAIN; 4267 } 4268 4269 /* check caller has TRUSTED_SET_AUTH */ 4270 4271 /* fetch all trusted domain objects */ 4272 num_res = gendb_search(p_state->sam_ldb, mem_ctx, 4273 p_state->system_dn, 4274 &dom_res, trust_attrs, 4275 "(objectclass=trustedDomain)"); 4276 if (num_res == 0) { 4277 return NT_STATUS_NO_SUCH_DOMAIN; 4278 } 4279 4280 for (i = 0; i < num_res; i++) { 4281 td_name = ldb_msg_find_attr_as_string(dom_res[i], 4282 "trustPartner", NULL); 4283 if (!td_name) { 4284 return NT_STATUS_INVALID_DOMAIN_STATE; 4285 } 4286 if (strcasecmp_m(td_name, 4287 r->in.trusted_domain_name->string) == 0) { 4288 break; 4289 } 4290 } 4291 if (i >= num_res) { 4292 return NT_STATUS_NO_SUCH_DOMAIN; 4293 } 4294 4295 tdo_dn = dom_res[i]->dn; 4296 4297 trust_attributes = ldb_msg_find_attr_as_uint(dom_res[i], 4298 "trustAttributes", 0); 4299 if (!(trust_attributes & NETR_TRUST_ATTRIBUTE_FOREST_TRANSITIVE)) { 4300 return NT_STATUS_INVALID_PARAMETER; 4361 status = NT_STATUS_INVALID_DOMAIN_ROLE; 4362 goto done; 4363 } 4364 4365 if (r->in.trusted_domain_name->string == NULL) { 4366 status = NT_STATUS_NO_SUCH_DOMAIN; 4367 goto done; 4368 } 4369 4370 status = dsdb_trust_search_tdo(p_state->sam_ldb, 4371 r->in.trusted_domain_name->string, 4372 r->in.trusted_domain_name->string, 4373 trust_attrs, mem_ctx, &trust_tdo_msg); 4374 if (NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) { 4375 status = NT_STATUS_NO_SUCH_DOMAIN; 4376 goto done; 4377 } 4378 if (!NT_STATUS_IS_OK(status)) { 4379 goto done; 4380 } 4381 4382 status = dsdb_trust_parse_tdo_info(mem_ctx, trust_tdo_msg, &trust_tdo); 4383 if (!NT_STATUS_IS_OK(status)) { 4384 goto done; 4385 } 4386 4387 if (!(trust_tdo->trust_attributes & LSA_TRUST_ATTRIBUTE_FOREST_TRANSITIVE)) { 4388 status = NT_STATUS_INVALID_PARAMETER; 4389 goto done; 4301 4390 } 4302 4391 4303 4392 if (r->in.highest_record_type >= LSA_FOREST_TRUST_RECORD_TYPE_LAST) { 4304 return NT_STATUS_INVALID_PARAMETER; 4305 } 4306 4307 nfti = talloc(mem_ctx, struct ForestTrustInfo); 4308 if (!nfti) { 4309 return NT_STATUS_NO_MEMORY; 4310 } 4311 4312 nt_status = make_ft_info(nfti, r->in.forest_trust_info, nfti); 4313 if (!NT_STATUS_IS_OK(nt_status)) { 4314 return nt_status; 4393 status = NT_STATUS_INVALID_PARAMETER; 4394 goto done; 4395 } 4396 4397 /* 4398 * verify and normalize the given forest trust info. 4399 * 4400 * Step1: doesn't reorder yet, so step1_lfti might contain 4401 * NULL entries. This means dsdb_trust_verify_forest_info() 4402 * can generate collision entries with the callers index. 4403 */ 4404 status = dsdb_trust_normalize_forest_info_step1(mem_ctx, 4405 r->in.forest_trust_info, 4406 &step1_lfti); 4407 if (!NT_STATUS_IS_OK(status)) { 4408 goto done; 4315 4409 } 4316 4410 4317 4411 c_info = talloc_zero(r->out.collision_info, 4318 4412 struct lsa_ForestTrustCollisionInfo); 4319 if (!c_info) { 4320 return NT_STATUS_NO_MEMORY; 4321 } 4322 4323 /* first check own info, then other domains */ 4324 fti = talloc(mem_ctx, struct ForestTrustInfo); 4325 if (!fti) { 4326 return NT_STATUS_NO_MEMORY; 4327 } 4328 4329 nt_status = own_ft_info(p_state, fti); 4330 if (!NT_STATUS_IS_OK(nt_status)) { 4331 return nt_status; 4332 } 4333 4334 nt_status = check_ft_info(c_info, p_state->domain_dns, 4335 fti, nfti, c_info); 4336 if (!NT_STATUS_IS_OK(nt_status)) { 4337 return nt_status; 4338 } 4339 4340 for (i = 0; i < num_res; i++) { 4341 fti = talloc(mem_ctx, struct ForestTrustInfo); 4342 if (!fti) { 4343 return NT_STATUS_NO_MEMORY; 4344 } 4345 4346 nt_status = get_ft_info(mem_ctx, dom_res[i], fti); 4347 if (!NT_STATUS_IS_OK(nt_status)) { 4348 if (NT_STATUS_EQUAL(nt_status, 4349 NT_STATUS_OBJECT_NAME_NOT_FOUND)) { 4350 continue; 4351 } 4352 return nt_status; 4353 } 4354 4355 td_name = ldb_msg_find_attr_as_string(dom_res[i], 4356 "trustPartner", NULL); 4357 if (!td_name) { 4358 return NT_STATUS_INVALID_DOMAIN_STATE; 4359 } 4360 4361 nt_status = check_ft_info(c_info, td_name, fti, nfti, c_info); 4362 if (!NT_STATUS_IS_OK(nt_status)) { 4363 return nt_status; 4364 } 4365 } 4366 4367 *r->out.collision_info = c_info; 4413 if (c_info == NULL) { 4414 status = NT_STATUS_NO_MEMORY; 4415 goto done; 4416 } 4417 4418 /* 4419 * First check our own forest, then other domains/forests 4420 */ 4421 4422 status = dsdb_trust_xref_tdo_info(mem_ctx, p_state->sam_ldb, 4423 &xref_tdo); 4424 if (!NT_STATUS_IS_OK(status)) { 4425 goto done; 4426 } 4427 status = dsdb_trust_xref_forest_info(mem_ctx, p_state->sam_ldb, 4428 &xref_lfti); 4429 if (!NT_STATUS_IS_OK(status)) { 4430 goto done; 4431 } 4432 4433 /* 4434 * The documentation proposed to generate 4435 * LSA_FOREST_TRUST_COLLISION_XREF collisions. 4436 * But Windows always uses LSA_FOREST_TRUST_COLLISION_TDO. 4437 */ 4438 status = dsdb_trust_verify_forest_info(xref_tdo, xref_lfti, 4439 LSA_FOREST_TRUST_COLLISION_TDO, 4440 c_info, step1_lfti); 4441 if (!NT_STATUS_IS_OK(status)) { 4442 goto done; 4443 } 4444 4445 /* fetch all other trusted domain objects */ 4446 status = dsdb_trust_search_tdos(p_state->sam_ldb, 4447 trust_tdo->domain_name.string, 4448 trust_attrs, 4449 mem_ctx, &trusts_res); 4450 if (!NT_STATUS_IS_OK(status)) { 4451 goto done; 4452 } 4453 4454 /* 4455 * now check against the other domains. 4456 * and generate LSA_FOREST_TRUST_COLLISION_TDO collisions. 4457 */ 4458 for (i = 0; i < trusts_res->count; i++) { 4459 struct lsa_TrustDomainInfoInfoEx *tdo = NULL; 4460 struct ForestTrustInfo *fti = NULL; 4461 struct lsa_ForestTrustInformation *lfti = NULL; 4462 4463 status = dsdb_trust_parse_tdo_info(mem_ctx, 4464 trusts_res->msgs[i], 4465 &tdo); 4466 if (!NT_STATUS_IS_OK(status)) { 4467 goto done; 4468 } 4469 4470 status = dsdb_trust_parse_forest_info(tdo, 4471 trusts_res->msgs[i], 4472 &fti); 4473 if (NT_STATUS_EQUAL(status, NT_STATUS_NOT_FOUND)) { 4474 continue; 4475 } 4476 if (!NT_STATUS_IS_OK(status)) { 4477 goto done; 4478 } 4479 4480 status = dsdb_trust_forest_info_to_lsa(tdo, fti, &lfti); 4481 if (!NT_STATUS_IS_OK(status)) { 4482 goto done; 4483 } 4484 4485 status = dsdb_trust_verify_forest_info(tdo, lfti, 4486 LSA_FOREST_TRUST_COLLISION_TDO, 4487 c_info, step1_lfti); 4488 if (!NT_STATUS_IS_OK(status)) { 4489 goto done; 4490 } 4491 4492 TALLOC_FREE(tdo); 4493 } 4368 4494 4369 4495 if (r->in.check_only != 0) { 4370 return NT_STATUS_OK; 4371 } 4372 4373 /* not just a check, write info back */ 4374 4375 ndr_err = ndr_push_struct_blob(&ft_blob, mem_ctx, nfti, 4496 status = NT_STATUS_OK; 4497 goto done; 4498 } 4499 4500 /* 4501 * not just a check, write info back 4502 */ 4503 4504 /* 4505 * normalize the given forest trust info. 4506 * 4507 * Step2: adds TOP_LEVEL_NAME[_EX] in reverse order, 4508 * followed by DOMAIN_INFO in reverse order. It also removes 4509 * possible NULL entries from Step1. 4510 */ 4511 status = dsdb_trust_normalize_forest_info_step2(mem_ctx, step1_lfti, 4512 &step2_lfti); 4513 if (!NT_STATUS_IS_OK(status)) { 4514 goto done; 4515 } 4516 4517 status = dsdb_trust_forest_info_from_lsa(mem_ctx, step2_lfti, 4518 &trust_fti); 4519 if (!NT_STATUS_IS_OK(status)) { 4520 goto done; 4521 } 4522 4523 ndr_err = ndr_push_struct_blob(&ft_blob, mem_ctx, trust_fti, 4376 4524 (ndr_push_flags_fn_t)ndr_push_ForestTrustInfo); 4377 4525 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { 4378 return NT_STATUS_INVALID_PARAMETER; 4526 status = NT_STATUS_INVALID_PARAMETER; 4527 goto done; 4379 4528 } 4380 4529 4381 4530 msg = ldb_msg_new(mem_ctx); 4382 4531 if (msg == NULL) { 4383 return NT_STATUS_NO_MEMORY; 4384 } 4385 4386 msg->dn = ldb_dn_copy(mem_ctx, tdo_dn); 4532 status = NT_STATUS_NO_MEMORY; 4533 goto done; 4534 } 4535 4536 msg->dn = ldb_dn_copy(mem_ctx, trust_tdo_msg->dn); 4387 4537 if (!msg->dn) { 4388 return NT_STATUS_NO_MEMORY; 4538 status = NT_STATUS_NO_MEMORY; 4539 goto done; 4389 4540 } 4390 4541 … … 4392 4543 LDB_FLAG_MOD_REPLACE, NULL); 4393 4544 if (ret != LDB_SUCCESS) { 4394 return NT_STATUS_NO_MEMORY; 4545 status = NT_STATUS_NO_MEMORY; 4546 goto done; 4395 4547 } 4396 4548 ret = ldb_msg_add_value(msg, "msDS-TrustForestTrustInfo", 4397 4549 &ft_blob, NULL); 4398 4550 if (ret != LDB_SUCCESS) { 4399 return NT_STATUS_NO_MEMORY; 4551 status = NT_STATUS_NO_MEMORY; 4552 goto done; 4400 4553 } 4401 4554 4402 4555 ret = ldb_modify(p_state->sam_ldb, msg); 4403 4556 if (ret != LDB_SUCCESS) { 4557 status = dsdb_ldb_err_to_ntstatus(ret); 4558 4404 4559 DEBUG(0, ("Failed to store Forest Trust Info: %s\n", 4405 4560 ldb_errstring(p_state->sam_ldb))); 4406 4561 4407 switch (ret) { 4408 case LDB_ERR_INSUFFICIENT_ACCESS_RIGHTS: 4409 return NT_STATUS_ACCESS_DENIED; 4410 default: 4411 return NT_STATUS_INTERNAL_DB_CORRUPTION; 4412 } 4413 } 4414 4415 return NT_STATUS_OK; 4416 } 4417 4418 /* 4419 lsa_CREDRRENAME 4562 goto done; 4563 } 4564 4565 /* ok, all fine, commit transaction and return */ 4566 in_transaction = false; 4567 ret = ldb_transaction_commit(p_state->sam_ldb); 4568 if (ret != LDB_SUCCESS) { 4569 status = NT_STATUS_INTERNAL_DB_CORRUPTION; 4570 goto done; 4571 } 4572 4573 status = NT_STATUS_OK; 4574 4575 done: 4576 if (NT_STATUS_IS_OK(status) && c_info->count != 0) { 4577 *r->out.collision_info = c_info; 4578 } 4579 4580 if (in_transaction) { 4581 ldb_transaction_cancel(p_state->sam_ldb); 4582 } 4583 4584 return status; 4585 } 4586 4587 /* 4588 lsa_CREDRRENAME 4420 4589 */ 4421 4590 static NTSTATUS dcesrv_lsa_CREDRRENAME(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, … … 4427 4596 4428 4597 4429 /* 4430 lsa_LSAROPENPOLICYSCE 4598 /* 4599 lsa_LSAROPENPOLICYSCE 4431 4600 */ 4432 4601 static NTSTATUS dcesrv_lsa_LSAROPENPOLICYSCE(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, … … 4437 4606 4438 4607 4439 /* 4440 lsa_LSARADTREGISTERSECURITYEVENTSOURCE 4608 /* 4609 lsa_LSARADTREGISTERSECURITYEVENTSOURCE 4441 4610 */ 4442 4611 static NTSTATUS dcesrv_lsa_LSARADTREGISTERSECURITYEVENTSOURCE(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, … … 4447 4616 4448 4617 4449 /* 4450 lsa_LSARADTUNREGISTERSECURITYEVENTSOURCE 4618 /* 4619 lsa_LSARADTUNREGISTERSECURITYEVENTSOURCE 4451 4620 */ 4452 4621 static NTSTATUS dcesrv_lsa_LSARADTUNREGISTERSECURITYEVENTSOURCE(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, … … 4457 4626 4458 4627 4459 /* 4460 lsa_LSARADTREPORTSECURITYEVENT 4628 /* 4629 lsa_LSARADTREPORTSECURITYEVENT 4461 4630 */ 4462 4631 static NTSTATUS dcesrv_lsa_LSARADTREPORTSECURITYEVENT(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, … … 4479 4648 ******************************************/ 4480 4649 4481 /* 4482 dssetup_DsRoleDnsNameToFlatName 4650 /* 4651 dssetup_DsRoleDnsNameToFlatName 4483 4652 */ 4484 4653 static WERROR dcesrv_dssetup_DsRoleDnsNameToFlatName(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, … … 4489 4658 4490 4659 4491 /* 4492 dssetup_DsRoleDcAsDc 4660 /* 4661 dssetup_DsRoleDcAsDc 4493 4662 */ 4494 4663 static WERROR dcesrv_dssetup_DsRoleDcAsDc(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, … … 4499 4668 4500 4669 4501 /* 4502 dssetup_DsRoleDcAsReplica 4670 /* 4671 dssetup_DsRoleDcAsReplica 4503 4672 */ 4504 4673 static WERROR dcesrv_dssetup_DsRoleDcAsReplica(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, … … 4509 4678 4510 4679 4511 /* 4512 dssetup_DsRoleDemoteDc 4680 /* 4681 dssetup_DsRoleDemoteDc 4513 4682 */ 4514 4683 static WERROR dcesrv_dssetup_DsRoleDemoteDc(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, … … 4519 4688 4520 4689 4521 /* 4522 dssetup_DsRoleGetDcOperationProgress 4690 /* 4691 dssetup_DsRoleGetDcOperationProgress 4523 4692 */ 4524 4693 static WERROR dcesrv_dssetup_DsRoleGetDcOperationProgress(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, … … 4549 4718 4550 4719 4551 /* 4552 dssetup_DsRoleServerSaveStateForUpgrade 4720 /* 4721 dssetup_DsRoleServerSaveStateForUpgrade 4553 4722 */ 4554 4723 static WERROR dcesrv_dssetup_DsRoleServerSaveStateForUpgrade(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, … … 4559 4728 4560 4729 4561 /* 4562 dssetup_DsRoleUpgradeDownlevelServer 4730 /* 4731 dssetup_DsRoleUpgradeDownlevelServer 4563 4732 */ 4564 4733 static WERROR dcesrv_dssetup_DsRoleUpgradeDownlevelServer(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, … … 4569 4738 4570 4739 4571 /* 4572 dssetup_DsRoleAbortDownlevelServerUpgrade 4740 /* 4741 dssetup_DsRoleAbortDownlevelServerUpgrade 4573 4742 */ 4574 4743 static WERROR dcesrv_dssetup_DsRoleAbortDownlevelServerUpgrade(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, … … 4585 4754 { 4586 4755 NTSTATUS ret; 4587 4756 4588 4757 ret = dcerpc_server_dssetup_init(); 4589 4758 if (!NT_STATUS_IS_OK(ret)) { -
vendor/current/source4/rpc_server/lsa/lsa.h
r740 r988 42 42 struct ldb_context *sam_ldb; 43 43 struct ldb_context *pdb; 44 uint32_t access_mask;45 44 struct ldb_dn *domain_dn; 46 45 struct ldb_dn *forest_dn; … … 57 56 struct dom_sid *world_domain_sid; 58 57 int mixed_domain; 58 struct security_descriptor *sd; 59 uint32_t access_mask; 59 60 }; 60 61 -
vendor/current/source4/rpc_server/lsa/lsa_init.c
r740 r988 23 23 #include "rpc_server/lsa/lsa.h" 24 24 25 NTSTATUS dcesrv_lsa_get_policy_state(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, 25 /* 26 * This matches a Windows 2012R2 dc in 27 * a domain with function level 2012R2. 28 */ 29 #define DCESRV_LSA_POLICY_SD_SDDL \ 30 "O:BAG:SY" \ 31 "D:" \ 32 "(D;;0x00000800;;;AN)" \ 33 "(A;;GA;;;BA)" \ 34 "(A;;GX;;;WD)" \ 35 "(A;;0x00000801;;;AN)" \ 36 "(A;;0x00001000;;;LS)" \ 37 "(A;;0x00001000;;;NS)" \ 38 "(A;;0x00001000;;;IS)" \ 39 "(A;;0x00000801;;;S-1-15-2-1)" 40 41 static const struct generic_mapping dcesrv_lsa_policy_mapping = { 42 LSA_POLICY_READ, 43 LSA_POLICY_WRITE, 44 LSA_POLICY_EXECUTE, 45 LSA_POLICY_ALL_ACCESS 46 }; 47 48 NTSTATUS dcesrv_lsa_get_policy_state(struct dcesrv_call_state *dce_call, 49 TALLOC_CTX *mem_ctx, 50 uint32_t access_desired, 26 51 struct lsa_policy_state **_state) 27 52 { 53 struct auth_session_info *session_info = dce_call->conn->auth_state.session_info; 54 enum security_user_level security_level; 28 55 struct lsa_policy_state *state; 29 56 struct ldb_result *dom_res; … … 38 65 int ret; 39 66 40 state = talloc (mem_ctx, struct lsa_policy_state);67 state = talloc_zero(mem_ctx, struct lsa_policy_state); 41 68 if (!state) { 42 69 return NT_STATUS_NO_MEMORY; … … 143 170 return NT_STATUS_NO_SUCH_DOMAIN; 144 171 } 172 173 state->sd = sddl_decode(state, DCESRV_LSA_POLICY_SD_SDDL, 174 state->domain_sid); 175 if (state->sd == NULL) { 176 return NT_STATUS_NO_MEMORY; 177 } 178 state->sd->dacl->revision = SECURITY_ACL_REVISION_NT4; 179 180 se_map_generic(&access_desired, &dcesrv_lsa_policy_mapping); 181 security_acl_map_generic(state->sd->dacl, &dcesrv_lsa_policy_mapping); 182 183 security_level = security_session_user_level(session_info, NULL); 184 if (security_level >= SECURITY_SYSTEM) { 185 /* 186 * The security descriptor doesn't allow system, 187 * but we want to allow system via ncalrpc as root. 188 */ 189 state->access_mask = access_desired; 190 if (state->access_mask & SEC_FLAG_MAXIMUM_ALLOWED) { 191 state->access_mask &= ~SEC_FLAG_MAXIMUM_ALLOWED; 192 state->access_mask |= LSA_POLICY_ALL_ACCESS; 193 } 194 } else { 195 NTSTATUS status; 196 197 status = se_access_check(state->sd, 198 session_info->security_token, 199 access_desired, 200 &state->access_mask); 201 if (!NT_STATUS_IS_OK(status)) { 202 DEBUG(2,("%s: access desired[0x%08X] rejected[0x%08X] - %s\n", 203 __func__, 204 (unsigned)access_desired, 205 (unsigned)state->access_mask, 206 nt_errstr(status))); 207 return status; 208 } 209 } 210 211 DEBUG(10,("%s: access desired[0x%08X] granted[0x%08X] - success.\n", 212 __func__, 213 (unsigned)access_desired, 214 (unsigned)state->access_mask)); 145 215 146 216 *_state = state; … … 155 225 struct lsa_OpenPolicy2 *r) 156 226 { 227 enum dcerpc_transport_t transport = 228 dcerpc_binding_get_transport(dce_call->conn->endpoint->ep_description); 157 229 NTSTATUS status; 158 230 struct lsa_policy_state *state; 159 231 struct dcesrv_handle *handle; 232 233 if (transport != NCACN_NP && transport != NCALRPC) { 234 DCESRV_FAULT(DCERPC_FAULT_ACCESS_DENIED); 235 } 160 236 161 237 ZERO_STRUCTP(r->out.handle); … … 167 243 } 168 244 169 status = dcesrv_lsa_get_policy_state(dce_call, mem_ctx, &state); 245 status = dcesrv_lsa_get_policy_state(dce_call, mem_ctx, 246 r->in.access_mask, 247 &state); 170 248 if (!NT_STATUS_IS_OK(status)) { 171 249 return status; … … 179 257 handle->data = talloc_steal(handle, state); 180 258 181 /* need to check the access mask against - need ACLs - fails182 WSPP test */183 state->access_mask = r->in.access_mask;184 259 state->handle = handle; 185 260 *r->out.handle = handle->wire_handle; … … 199 274 struct lsa_OpenPolicy *r) 200 275 { 276 enum dcerpc_transport_t transport = 277 dcerpc_binding_get_transport(dce_call->conn->endpoint->ep_description); 201 278 struct lsa_OpenPolicy2 r2; 279 280 if (transport != NCACN_NP && transport != NCALRPC) { 281 DCESRV_FAULT(DCERPC_FAULT_ACCESS_DENIED); 282 } 202 283 203 284 r2.in.system_name = NULL; -
vendor/current/source4/rpc_server/lsa/lsa_lookup.c
r740 r988 285 285 *authority_name = NAME_BUILTIN; 286 286 *sid = dom_sid_parse_talloc(mem_ctx, SID_BUILTIN); 287 if (*sid == NULL) { 288 return NT_STATUS_NO_MEMORY; 289 } 287 290 *rtype = SID_NAME_DOMAIN; 288 291 *rid = 0xFFFFFFFF; … … 293 296 *authority_name = NAME_NT_AUTHORITY; 294 297 *sid = dom_sid_parse_talloc(mem_ctx, SID_NT_AUTHORITY); 298 if (*sid == NULL) { 299 return NT_STATUS_NO_MEMORY; 300 } 295 301 *rtype = SID_NAME_DOMAIN; 296 302 dom_sid_split_rid(NULL, *sid, NULL, rid); … … 300 306 *authority_name = NAME_BUILTIN; 301 307 *sid = dom_sid_parse_talloc(mem_ctx, SID_BUILTIN); 308 if (*sid == NULL) { 309 return NT_STATUS_NO_MEMORY; 310 } 302 311 *rtype = SID_NAME_DOMAIN; 303 312 *rid = 0xFFFFFFFF; … … 305 314 } 306 315 if (strcasecmp_m(username, state->domain_dns) == 0) { 307 *authority_name = state->domain_name; 308 *sid = state->domain_sid; 316 *authority_name = talloc_strdup(mem_ctx, 317 state->domain_name); 318 if (*authority_name == NULL) { 319 return NT_STATUS_NO_MEMORY; 320 } 321 *sid = dom_sid_dup(mem_ctx, state->domain_sid); 322 if (*sid == NULL) { 323 return NT_STATUS_NO_MEMORY; 324 } 309 325 *rtype = SID_NAME_DOMAIN; 310 326 *rid = 0xFFFFFFFF; … … 312 328 } 313 329 if (strcasecmp_m(username, state->domain_name) == 0) { 314 *authority_name = state->domain_name; 315 *sid = state->domain_sid; 330 *authority_name = talloc_strdup(mem_ctx, 331 state->domain_name); 332 if (*authority_name == NULL) { 333 return NT_STATUS_NO_MEMORY; 334 } 335 *sid = dom_sid_dup(mem_ctx, state->domain_sid); 336 if (*sid == NULL) { 337 return NT_STATUS_NO_MEMORY; 338 } 316 339 *rtype = SID_NAME_DOMAIN; 317 340 *rid = 0xFFFFFFFF; 318 341 return NT_STATUS_OK; 319 342 } 320 343 321 344 /* Perhaps this is a well known user? */ 322 345 name = talloc_asprintf(mem_ctx, "%s\\%s", NAME_NT_AUTHORITY, username); … … 354 377 *authority_name = NAME_NT_AUTHORITY; 355 378 *sid = dom_sid_parse_talloc(mem_ctx, SID_NT_AUTHORITY); 379 if (*sid == NULL) { 380 return NT_STATUS_NO_MEMORY; 381 } 356 382 *rtype = SID_NAME_DOMAIN; 357 383 dom_sid_split_rid(NULL, *sid, NULL, rid); … … 370 396 domain_dn = state->builtin_dn; 371 397 } else if (strcasecmp_m(domain, state->domain_dns) == 0) { 372 *authority_name = state->domain_name; 398 *authority_name = talloc_strdup(mem_ctx, 399 state->domain_name); 400 if (*authority_name == NULL) { 401 return NT_STATUS_NO_MEMORY; 402 } 373 403 domain_dn = state->domain_dn; 374 404 } else if (strcasecmp_m(domain, state->domain_name) == 0) { 375 *authority_name = state->domain_name; 405 *authority_name = talloc_strdup(mem_ctx, 406 state->domain_name); 407 if (*authority_name == NULL) { 408 return NT_STATUS_NO_MEMORY; 409 } 376 410 domain_dn = state->domain_dn; 377 411 } else { … … 498 532 } 499 533 534 if (dom_sid_equal(state->domain_sid, sid)) { 535 *authority_name = talloc_strdup(mem_ctx, state->domain_name); 536 if (*authority_name == NULL) { 537 return NT_STATUS_NO_MEMORY; 538 } 539 *name = NULL; 540 *rtype = SID_NAME_DOMAIN; 541 return NT_STATUS_OK; 542 } 543 500 544 if (dom_sid_in_domain(state->domain_sid, sid)) { 501 *authority_name = state->domain_name; 545 *authority_name = talloc_strdup(mem_ctx, state->domain_name); 546 if (*authority_name == NULL) { 547 return NT_STATUS_NO_MEMORY; 548 } 502 549 domain_dn = state->domain_dn; 503 550 } else if (dom_sid_in_domain(state->builtin_sid, sid)) { … … 538 585 } 539 586 540 541 /* 542 lsa_LookupSids2 543 */ 544 NTSTATUS dcesrv_lsa_LookupSids2(struct dcesrv_call_state *dce_call, 545 TALLOC_CTX *mem_ctx, 546 struct lsa_LookupSids2 *r) 547 { 548 struct lsa_policy_state *state; 587 static NTSTATUS dcesrv_lsa_LookupSids_common(struct dcesrv_call_state *dce_call, 588 TALLOC_CTX *mem_ctx, 589 struct lsa_policy_state *state, 590 struct lsa_LookupSids2 *r) 591 { 549 592 struct lsa_RefDomainList *domains = NULL; 593 NTSTATUS status = NT_STATUS_OK; 550 594 uint32_t i; 551 NTSTATUS status = NT_STATUS_OK;552 595 553 596 if (r->in.level < LSA_LOOKUP_NAMES_ALL || … … 563 606 MS-DTYP 2.4.2 564 607 */ 565 566 status = dcesrv_lsa_get_policy_state(dce_call, mem_ctx, &state);567 if (!NT_STATUS_IS_OK(status)) {568 return status;569 }570 608 571 609 domains = talloc_zero(r->out.domains, struct lsa_RefDomainList); … … 639 677 } 640 678 641 return NT_STATUS_OK; 679 return status; 680 } 681 682 /* 683 lsa_LookupSids2 684 */ 685 NTSTATUS dcesrv_lsa_LookupSids2(struct dcesrv_call_state *dce_call, 686 TALLOC_CTX *mem_ctx, 687 struct lsa_LookupSids2 *r) 688 { 689 enum dcerpc_transport_t transport = 690 dcerpc_binding_get_transport(dce_call->conn->endpoint->ep_description); 691 struct lsa_policy_state *state; 692 struct dcesrv_handle *h; 693 694 if (transport != NCACN_NP && transport != NCALRPC) { 695 DCESRV_FAULT(DCERPC_FAULT_ACCESS_DENIED); 696 } 697 698 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY); 699 700 state = h->data; 701 702 return dcesrv_lsa_LookupSids_common(dce_call, 703 mem_ctx, 704 state, 705 r); 642 706 } 643 707 … … 653 717 struct lsa_LookupSids3 *r) 654 718 { 655 struct lsa_LookupSids2 r2; 656 struct lsa_OpenPolicy2 pol; 719 enum dcerpc_transport_t transport = 720 dcerpc_binding_get_transport(dce_call->conn->endpoint->ep_description); 721 const struct dcesrv_auth *auth = &dce_call->conn->auth_state; 722 struct lsa_policy_state *policy_state; 723 struct lsa_LookupSids2 q; 657 724 NTSTATUS status; 658 struct dcesrv_handle *h; 659 660 ZERO_STRUCT(r2); 661 662 /* No policy handle on the wire, so make one up here */ 663 r2.in.handle = talloc(mem_ctx, struct policy_handle); 664 if (!r2.in.handle) { 665 return NT_STATUS_NO_MEMORY; 666 } 667 668 pol.out.handle = r2.in.handle; 669 pol.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED; 670 pol.in.attr = NULL; 671 pol.in.system_name = NULL; 672 status = dcesrv_lsa_OpenPolicy2(dce_call, mem_ctx, &pol); 725 726 if (transport != NCACN_IP_TCP) { 727 DCESRV_FAULT(DCERPC_FAULT_ACCESS_DENIED); 728 } 729 730 /* 731 * We don't have policy handles on this call. So this must be restricted 732 * to crypto connections only. 733 */ 734 if (auth->auth_type != DCERPC_AUTH_TYPE_SCHANNEL || 735 auth->auth_level < DCERPC_AUTH_LEVEL_INTEGRITY) { 736 DCESRV_FAULT(DCERPC_FAULT_ACCESS_DENIED); 737 } 738 739 status = dcesrv_lsa_get_policy_state(dce_call, mem_ctx, 740 0, /* we skip access checks */ 741 &policy_state); 673 742 if (!NT_STATUS_IS_OK(status)) { 674 743 return status; 675 744 } 676 745 677 /* ensure this handle goes away at the end of this call */ 678 DCESRV_PULL_HANDLE(h, r2.in.handle, LSA_HANDLE_POLICY); 679 talloc_steal(mem_ctx, h); 680 681 r2.in.sids = r->in.sids; 682 r2.in.names = r->in.names; 683 r2.in.level = r->in.level; 684 r2.in.count = r->in.count; 685 r2.in.lookup_options = r->in.lookup_options; 686 r2.in.client_revision = r->in.client_revision; 687 r2.out.count = r->out.count; 688 r2.out.names = r->out.names; 689 r2.out.domains = r->out.domains; 690 691 status = dcesrv_lsa_LookupSids2(dce_call, mem_ctx, &r2); 692 693 r->out.domains = r2.out.domains; 694 r->out.names = r2.out.names; 695 r->out.count = r2.out.count; 746 ZERO_STRUCT(q); 747 748 q.in.handle = NULL; 749 q.in.sids = r->in.sids; 750 q.in.names = r->in.names; 751 q.in.level = r->in.level; 752 q.in.count = r->in.count; 753 q.in.lookup_options = r->in.lookup_options; 754 q.in.client_revision = r->in.client_revision; 755 q.out.count = r->out.count; 756 q.out.names = r->out.names; 757 q.out.domains = r->out.domains; 758 759 status = dcesrv_lsa_LookupSids_common(dce_call, 760 mem_ctx, 761 policy_state, 762 &q); 763 764 talloc_free(policy_state); 765 766 r->out.count = q.out.count; 767 r->out.names = q.out.names; 768 r->out.domains = q.out.domains; 696 769 697 770 return status; … … 705 778 struct lsa_LookupSids *r) 706 779 { 780 enum dcerpc_transport_t transport = 781 dcerpc_binding_get_transport(dce_call->conn->endpoint->ep_description); 707 782 struct lsa_LookupSids2 r2; 708 783 NTSTATUS status; 709 784 uint32_t i; 785 786 if (transport != NCACN_NP && transport != NCALRPC) { 787 DCESRV_FAULT(DCERPC_FAULT_ACCESS_DENIED); 788 } 710 789 711 790 ZERO_STRUCT(r2); … … 751 830 } 752 831 753 754 /* 755 lsa_LookupNames3 756 */ 757 NTSTATUS dcesrv_lsa_LookupNames3(struct dcesrv_call_state *dce_call, 758 TALLOC_CTX *mem_ctx, 759 struct lsa_LookupNames3 *r) 760 { 761 struct lsa_policy_state *policy_state; 762 struct dcesrv_handle *policy_handle; 763 uint32_t i; 832 static NTSTATUS dcesrv_lsa_LookupNames_common(struct dcesrv_call_state *dce_call, 833 TALLOC_CTX *mem_ctx, 834 struct lsa_policy_state *policy_state, 835 struct lsa_LookupNames3 *r) 836 { 764 837 struct loadparm_context *lp_ctx = dce_call->conn->dce_ctx->lp_ctx; 765 838 struct lsa_RefDomainList *domains; 766 767 DCESRV_PULL_HANDLE(policy_handle, r->in.handle, LSA_HANDLE_POLICY); 839 uint32_t i; 768 840 769 841 if (r->in.level < LSA_LOOKUP_NAMES_ALL || … … 771 843 return NT_STATUS_INVALID_PARAMETER; 772 844 } 773 774 policy_state = policy_handle->data;775 845 776 846 *r->out.domains = NULL; … … 840 910 } 841 911 912 /* 913 lsa_LookupNames3 914 */ 915 NTSTATUS dcesrv_lsa_LookupNames3(struct dcesrv_call_state *dce_call, 916 TALLOC_CTX *mem_ctx, 917 struct lsa_LookupNames3 *r) 918 { 919 enum dcerpc_transport_t transport = 920 dcerpc_binding_get_transport(dce_call->conn->endpoint->ep_description); 921 struct lsa_policy_state *policy_state; 922 struct dcesrv_handle *policy_handle; 923 924 if (transport != NCACN_NP && transport != NCALRPC) { 925 DCESRV_FAULT(DCERPC_FAULT_ACCESS_DENIED); 926 } 927 928 DCESRV_PULL_HANDLE(policy_handle, r->in.handle, LSA_HANDLE_POLICY); 929 930 policy_state = policy_handle->data; 931 932 return dcesrv_lsa_LookupNames_common(dce_call, 933 mem_ctx, 934 policy_state, 935 r); 936 } 937 842 938 /* 843 939 lsa_LookupNames4 … … 849 945 struct lsa_LookupNames4 *r) 850 946 { 851 struct lsa_LookupNames3 r2; 852 struct lsa_OpenPolicy2 pol; 947 enum dcerpc_transport_t transport = 948 dcerpc_binding_get_transport(dce_call->conn->endpoint->ep_description); 949 const struct dcesrv_auth *auth = &dce_call->conn->auth_state; 950 struct lsa_policy_state *policy_state; 951 struct lsa_LookupNames3 q; 853 952 NTSTATUS status; 854 struct dcesrv_handle *h; 855 856 ZERO_STRUCT(r2); 857 858 /* No policy handle on the wire, so make one up here */ 859 r2.in.handle = talloc(mem_ctx, struct policy_handle); 860 if (!r2.in.handle) { 861 return NT_STATUS_NO_MEMORY; 862 } 863 864 pol.out.handle = r2.in.handle; 865 pol.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED; 866 pol.in.attr = NULL; 867 pol.in.system_name = NULL; 868 status = dcesrv_lsa_OpenPolicy2(dce_call, mem_ctx, &pol); 953 954 if (transport != NCACN_IP_TCP) { 955 DCESRV_FAULT(DCERPC_FAULT_ACCESS_DENIED); 956 } 957 958 /* 959 * We don't have policy handles on this call. So this must be restricted 960 * to crypto connections only. 961 */ 962 if (auth->auth_type != DCERPC_AUTH_TYPE_SCHANNEL || 963 auth->auth_level < DCERPC_AUTH_LEVEL_INTEGRITY) { 964 DCESRV_FAULT(DCERPC_FAULT_ACCESS_DENIED); 965 } 966 967 status = dcesrv_lsa_get_policy_state(dce_call, mem_ctx, 968 0, /* we skip access checks */ 969 &policy_state); 869 970 if (!NT_STATUS_IS_OK(status)) { 870 971 return status; 871 972 } 872 973 873 /* ensure this handle goes away at the end of this call */ 874 DCESRV_PULL_HANDLE(h, r2.in.handle, LSA_HANDLE_POLICY); 875 talloc_steal(mem_ctx, h); 876 877 r2.in.num_names = r->in.num_names; 878 r2.in.names = r->in.names; 879 r2.in.level = r->in.level; 880 r2.in.sids = r->in.sids; 881 r2.in.count = r->in.count; 882 r2.in.lookup_options = r->in.lookup_options; 883 r2.in.client_revision = r->in.client_revision; 884 r2.out.domains = r->out.domains; 885 r2.out.sids = r->out.sids; 886 r2.out.count = r->out.count; 887 888 status = dcesrv_lsa_LookupNames3(dce_call, mem_ctx, &r2); 889 890 r->out.domains = r2.out.domains; 891 r->out.sids = r2.out.sids; 892 r->out.count = r2.out.count; 974 ZERO_STRUCT(q); 975 976 q.in.handle = NULL; 977 q.in.num_names = r->in.num_names; 978 q.in.names = r->in.names; 979 q.in.level = r->in.level; 980 q.in.sids = r->in.sids; 981 q.in.count = r->in.count; 982 q.in.lookup_options = r->in.lookup_options; 983 q.in.client_revision = r->in.client_revision; 984 985 q.out.count = r->out.count; 986 q.out.sids = r->out.sids; 987 q.out.domains = r->out.domains; 988 989 status = dcesrv_lsa_LookupNames_common(dce_call, 990 mem_ctx, 991 policy_state, 992 &q); 993 994 talloc_free(policy_state); 995 996 r->out.count = q.out.count; 997 r->out.sids = q.out.sids; 998 r->out.domains = q.out.domains; 999 893 1000 return status; 894 1001 } … … 901 1008 struct lsa_LookupNames2 *r) 902 1009 { 1010 enum dcerpc_transport_t transport = 1011 dcerpc_binding_get_transport(dce_call->conn->endpoint->ep_description); 903 1012 struct lsa_policy_state *state; 904 1013 struct dcesrv_handle *h; … … 906 1015 struct loadparm_context *lp_ctx = dce_call->conn->dce_ctx->lp_ctx; 907 1016 struct lsa_RefDomainList *domains; 1017 1018 if (transport != NCACN_NP && transport != NCALRPC) { 1019 DCESRV_FAULT(DCERPC_FAULT_ACCESS_DENIED); 1020 } 908 1021 909 1022 *r->out.domains = NULL; … … 991 1104 struct lsa_LookupNames *r) 992 1105 { 1106 enum dcerpc_transport_t transport = 1107 dcerpc_binding_get_transport(dce_call->conn->endpoint->ep_description); 993 1108 struct lsa_LookupNames2 r2; 994 1109 NTSTATUS status; 995 1110 uint32_t i; 1111 1112 if (transport != NCACN_NP && transport != NCALRPC) { 1113 DCESRV_FAULT(DCERPC_FAULT_ACCESS_DENIED); 1114 } 996 1115 997 1116 ZERO_STRUCT(r2); -
vendor/current/source4/rpc_server/netlogon/dcerpc_netlogon.c
r740 r988 28 28 #include "dsdb/samdb/samdb.h" 29 29 #include "../lib/util/util_ldb.h" 30 #include "../lib/util/memcache.h" 30 31 #include "../libcli/auth/schannel.h" 31 32 #include "libcli/security/security.h" … … 34 35 #include "librpc/gen_ndr/ndr_irpc_c.h" 35 36 #include "../libcli/ldap/ldap_ndr.h" 36 #include " cldap_server/cldap_server.h"37 #include "dsdb/samdb/ldb_modules/util.h" 37 38 #include "lib/tsocket/tsocket.h" 38 39 #include "librpc/gen_ndr/ndr_netlogon.h" 40 #include "librpc/gen_ndr/ndr_lsa.h" 41 #include "librpc/gen_ndr/ndr_samr.h" 39 42 #include "librpc/gen_ndr/ndr_irpc.h" 43 #include "librpc/gen_ndr/ndr_winbind.h" 44 #include "librpc/gen_ndr/ndr_winbind_c.h" 45 #include "lib/socket/netif.h" 46 47 #define DCESRV_INTERFACE_NETLOGON_BIND(call, iface) \ 48 dcesrv_interface_netlogon_bind(call, iface) 49 static NTSTATUS dcesrv_interface_netlogon_bind(struct dcesrv_call_state *dce_call, 50 const struct dcesrv_interface *iface) 51 { 52 return dcesrv_interface_bind_reject_connect(dce_call, iface); 53 } 54 55 static struct memcache *global_challenge_table; 40 56 41 57 struct netlogon_server_pipe_state { … … 49 65 struct netlogon_server_pipe_state *pipe_state = 50 66 talloc_get_type(dce_call->context->private_data, struct netlogon_server_pipe_state); 67 DATA_BLOB key, val; 51 68 52 69 ZERO_STRUCTP(r->out.return_credentials); 70 71 if (global_challenge_table == NULL) { 72 /* 73 * We maintain a global challenge table 74 * with a fixed size (8k) 75 * 76 * This is required for the strange clients 77 * which use different connections for 78 * netr_ServerReqChallenge() and netr_ServerAuthenticate3() 79 * 80 */ 81 global_challenge_table = memcache_init(talloc_autofree_context(), 82 8192); 83 if (global_challenge_table == NULL) { 84 return NT_STATUS_NO_MEMORY; 85 } 86 } 53 87 54 88 /* destroyed on pipe shutdown */ … … 71 105 dce_call->context->private_data = pipe_state; 72 106 107 key = data_blob_string_const(r->in.computer_name); 108 val = data_blob_const(pipe_state, sizeof(*pipe_state)); 109 110 memcache_add(global_challenge_table, SINGLETON_CACHE, key, val); 111 73 112 return NT_STATUS_OK; 74 113 } … … 79 118 struct netlogon_server_pipe_state *pipe_state = 80 119 talloc_get_type(dce_call->context->private_data, struct netlogon_server_pipe_state); 120 DATA_BLOB challenge_key; 121 bool challenge_valid = false; 122 struct netlogon_server_pipe_state challenge; 81 123 struct netlogon_creds_CredentialState *creds; 82 124 struct ldb_context *sam_ctx; 83 struct samr_Password *mach_pwd; 125 struct samr_Password *curNtHash = NULL; 126 struct samr_Password *prevNtHash = NULL; 84 127 uint32_t user_account_control; 85 128 int num_records; … … 88 131 const char *attrs[] = {"unicodePwd", "userAccountControl", 89 132 "objectSid", NULL}; 90 91 const char *trust_dom_attrs[] = {"flatname", NULL};92 133 const char *account_name; 134 uint32_t server_flags = 0; 135 uint32_t negotiate_flags = 0; 136 bool allow_nt4_crypto = lpcfg_allow_nt4_crypto(dce_call->conn->dce_ctx->lp_ctx); 137 bool reject_des_client = !allow_nt4_crypto; 138 bool reject_md5_client = lpcfg_reject_md5_clients(dce_call->conn->dce_ctx->lp_ctx); 139 int schannel = lpcfg_server_schannel(dce_call->conn->dce_ctx->lp_ctx); 140 bool reject_none_rpc = (schannel == true); 93 141 94 142 ZERO_STRUCTP(r->out.return_credentials); 95 143 *r->out.rid = 0; 144 145 challenge_key = data_blob_string_const(r->in.computer_name); 146 if (pipe_state != NULL) { 147 dce_call->context->private_data = NULL; 148 149 /* 150 * If we had a challenge remembered on the connection 151 * consider this for usage. This can't be cleanup 152 * by other clients. 153 * 154 * This is the default code path for typical clients 155 * which call netr_ServerReqChallenge() and 156 * netr_ServerAuthenticate3() on the same dcerpc connection. 157 */ 158 challenge = *pipe_state; 159 TALLOC_FREE(pipe_state); 160 challenge_valid = true; 161 } else { 162 DATA_BLOB val; 163 bool ok; 164 165 /* 166 * Fallback and try to get the challenge from 167 * the global cache. 168 * 169 * If too many clients are using this code path, 170 * they may destroy their cache entries as the 171 * global_challenge_table memcache has a fixed size. 172 * 173 * Note: this handles global_challenge_table == NULL fine 174 */ 175 ok = memcache_lookup(global_challenge_table, SINGLETON_CACHE, 176 challenge_key, &val); 177 if (ok && val.length == sizeof(challenge)) { 178 memcpy(&challenge, val.data, sizeof(challenge)); 179 challenge_valid = true; 180 } else { 181 ZERO_STRUCT(challenge); 182 } 183 } 184 185 server_flags = NETLOGON_NEG_ACCOUNT_LOCKOUT | 186 NETLOGON_NEG_PERSISTENT_SAMREPL | 187 NETLOGON_NEG_ARCFOUR | 188 NETLOGON_NEG_PROMOTION_COUNT | 189 NETLOGON_NEG_CHANGELOG_BDC | 190 NETLOGON_NEG_FULL_SYNC_REPL | 191 NETLOGON_NEG_MULTIPLE_SIDS | 192 NETLOGON_NEG_REDO | 193 NETLOGON_NEG_PASSWORD_CHANGE_REFUSAL | 194 NETLOGON_NEG_SEND_PASSWORD_INFO_PDC | 195 NETLOGON_NEG_GENERIC_PASSTHROUGH | 196 NETLOGON_NEG_CONCURRENT_RPC | 197 NETLOGON_NEG_AVOID_ACCOUNT_DB_REPL | 198 NETLOGON_NEG_AVOID_SECURITYAUTH_DB_REPL | 199 NETLOGON_NEG_STRONG_KEYS | 200 NETLOGON_NEG_TRANSITIVE_TRUSTS | 201 NETLOGON_NEG_DNS_DOMAIN_TRUSTS | 202 NETLOGON_NEG_PASSWORD_SET2 | 203 NETLOGON_NEG_GETDOMAININFO | 204 NETLOGON_NEG_CROSS_FOREST_TRUSTS | 205 NETLOGON_NEG_NEUTRALIZE_NT4_EMULATION | 206 NETLOGON_NEG_RODC_PASSTHROUGH | 207 NETLOGON_NEG_SUPPORTS_AES | 208 NETLOGON_NEG_AUTHENTICATED_RPC_LSASS | 209 NETLOGON_NEG_AUTHENTICATED_RPC; 210 211 negotiate_flags = *r->in.negotiate_flags & server_flags; 212 213 if (negotiate_flags & NETLOGON_NEG_AUTHENTICATED_RPC) { 214 reject_none_rpc = false; 215 } 216 217 if (negotiate_flags & NETLOGON_NEG_STRONG_KEYS) { 218 reject_des_client = false; 219 } 220 221 if (negotiate_flags & NETLOGON_NEG_SUPPORTS_AES) { 222 reject_des_client = false; 223 reject_md5_client = false; 224 } 225 226 if (reject_des_client || reject_md5_client) { 227 /* 228 * Here we match Windows 2012 and return no flags. 229 */ 230 *r->out.negotiate_flags = 0; 231 return NT_STATUS_DOWNGRADE_DETECTED; 232 } 233 234 /* 235 * At this point we can cleanup the cache entry, 236 * if we fail the client needs to call netr_ServerReqChallenge 237 * again. 238 * 239 * Note: this handles global_challenge_table == NULL 240 * and also a non existing record just fine. 241 */ 242 memcache_delete(global_challenge_table, 243 SINGLETON_CACHE, challenge_key); 96 244 97 245 /* … … 101 249 * call fails with access denied! 102 250 */ 103 *r->out.negotiate_flags = NETLOGON_NEG_ACCOUNT_LOCKOUT | 104 NETLOGON_NEG_PERSISTENT_SAMREPL | 105 NETLOGON_NEG_ARCFOUR | 106 NETLOGON_NEG_PROMOTION_COUNT | 107 NETLOGON_NEG_CHANGELOG_BDC | 108 NETLOGON_NEG_FULL_SYNC_REPL | 109 NETLOGON_NEG_MULTIPLE_SIDS | 110 NETLOGON_NEG_REDO | 111 NETLOGON_NEG_PASSWORD_CHANGE_REFUSAL | 112 NETLOGON_NEG_SEND_PASSWORD_INFO_PDC | 113 NETLOGON_NEG_GENERIC_PASSTHROUGH | 114 NETLOGON_NEG_CONCURRENT_RPC | 115 NETLOGON_NEG_AVOID_ACCOUNT_DB_REPL | 116 NETLOGON_NEG_AVOID_SECURITYAUTH_DB_REPL | 117 NETLOGON_NEG_STRONG_KEYS | 118 NETLOGON_NEG_TRANSITIVE_TRUSTS | 119 NETLOGON_NEG_DNS_DOMAIN_TRUSTS | 120 NETLOGON_NEG_PASSWORD_SET2 | 121 NETLOGON_NEG_GETDOMAININFO | 122 NETLOGON_NEG_CROSS_FOREST_TRUSTS | 123 NETLOGON_NEG_NEUTRALIZE_NT4_EMULATION | 124 NETLOGON_NEG_RODC_PASSTHROUGH | 125 NETLOGON_NEG_AUTHENTICATED_RPC_LSASS | 126 NETLOGON_NEG_AUTHENTICATED_RPC; 251 *r->out.negotiate_flags = negotiate_flags; 252 253 if (reject_none_rpc) { 254 /* schannel must be used, but client did not offer it. */ 255 DEBUG(0,("%s: schannel required but client failed " 256 "to offer it. Client was %s\n", 257 __func__, r->in.account_name)); 258 return NT_STATUS_ACCESS_DENIED; 259 } 127 260 128 261 switch (r->in.secure_channel_type) { … … 133 266 case SEC_CHAN_RODC: 134 267 break; 268 case SEC_CHAN_NULL: 269 return NT_STATUS_INVALID_PARAMETER; 135 270 default: 136 271 DEBUG(1, ("Client asked for an invalid secure channel type: %d\n", … … 145 280 } 146 281 147 if (r->in.secure_channel_type == SEC_CHAN_DNS_DOMAIN) { 148 char *encoded_account = ldb_binary_encode_string(mem_ctx, r->in.account_name); 149 const char *flatname; 150 if (!encoded_account) { 282 if (r->in.secure_channel_type == SEC_CHAN_DOMAIN || 283 r->in.secure_channel_type == SEC_CHAN_DNS_DOMAIN) 284 { 285 struct ldb_message *tdo_msg = NULL; 286 const char * const tdo_attrs[] = { 287 "trustAuthIncoming", 288 "trustAttributes", 289 "flatName", 290 NULL 291 }; 292 char *encoded_name = NULL; 293 size_t len; 294 const char *flatname = NULL; 295 char trailer = '$'; 296 bool require_trailer = true; 297 const char *netbios = NULL; 298 const char *dns = NULL; 299 300 if (r->in.secure_channel_type == SEC_CHAN_DNS_DOMAIN) { 301 trailer = '.'; 302 require_trailer = false; 303 } 304 305 encoded_name = ldb_binary_encode_string(mem_ctx, 306 r->in.account_name); 307 if (encoded_name == NULL) { 151 308 return NT_STATUS_NO_MEMORY; 152 309 } 153 310 154 /* Kill the trailing dot */ 155 if (encoded_account[strlen(encoded_account)-1] == '.') { 156 encoded_account[strlen(encoded_account)-1] = '\0'; 157 } 158 159 /* pull the user attributes */ 160 num_records = gendb_search(sam_ctx, mem_ctx, NULL, &msgs, 161 trust_dom_attrs, 162 "(&(trustPartner=%s)(objectclass=trustedDomain))", 163 encoded_account); 164 165 if (num_records == 0) { 166 DEBUG(3,("Couldn't find trust [%s] in samdb.\n", 167 encoded_account)); 311 len = strlen(encoded_name); 312 if (len < 2) { 168 313 return NT_STATUS_NO_TRUST_SAM_ACCOUNT; 169 314 } 170 315 171 if (num_records > 1) { 172 DEBUG(0,("Found %d records matching user [%s]\n", num_records, r->in.account_name)); 173 return NT_STATUS_INTERNAL_DB_CORRUPTION; 174 } 175 176 flatname = ldb_msg_find_attr_as_string(msgs[0], "flatname", NULL); 177 if (!flatname) { 178 /* No flatname for this trust - we can't proceed */ 316 if (require_trailer && encoded_name[len - 1] != trailer) { 179 317 return NT_STATUS_NO_TRUST_SAM_ACCOUNT; 180 318 } 319 encoded_name[len - 1] = '\0'; 320 321 if (r->in.secure_channel_type == SEC_CHAN_DNS_DOMAIN) { 322 dns = encoded_name; 323 } else { 324 netbios = encoded_name; 325 } 326 327 nt_status = dsdb_trust_search_tdo(sam_ctx, 328 netbios, dns, 329 tdo_attrs, mem_ctx, &tdo_msg); 330 if (NT_STATUS_EQUAL(nt_status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) { 331 DEBUG(2, ("Client asked for a trusted domain secure channel, " 332 "but there's no tdo for [%s] => [%s] \n", 333 r->in.account_name, encoded_name)); 334 return NT_STATUS_NO_TRUST_SAM_ACCOUNT; 335 } 336 if (!NT_STATUS_IS_OK(nt_status)) { 337 return nt_status; 338 } 339 340 nt_status = dsdb_trust_get_incoming_passwords(tdo_msg, mem_ctx, 341 &curNtHash, 342 &prevNtHash); 343 if (NT_STATUS_EQUAL(nt_status, NT_STATUS_ACCOUNT_DISABLED)) { 344 return NT_STATUS_NO_TRUST_SAM_ACCOUNT; 345 } 346 if (!NT_STATUS_IS_OK(nt_status)) { 347 return nt_status; 348 } 349 350 flatname = ldb_msg_find_attr_as_string(tdo_msg, "flatName", NULL); 351 if (flatname == NULL) { 352 return NT_STATUS_NO_TRUST_SAM_ACCOUNT; 353 } 354 181 355 account_name = talloc_asprintf(mem_ctx, "%s$", flatname); 182 183 if (!account_name) { 356 if (account_name == NULL) { 184 357 return NT_STATUS_NO_MEMORY; 185 358 } 186 187 359 } else { 188 360 account_name = r->in.account_name; … … 239 411 } 240 412 241 *r->out.rid = samdb_result_rid_from_sid(mem_ctx, msgs[0], 242 "objectSid", 0); 243 244 mach_pwd = samdb_result_hash(mem_ctx, msgs[0], "unicodePwd"); 245 if (mach_pwd == NULL) { 413 if (!(user_account_control & UF_INTERDOMAIN_TRUST_ACCOUNT)) { 414 nt_status = samdb_result_passwords_no_lockout(mem_ctx, 415 dce_call->conn->dce_ctx->lp_ctx, 416 msgs[0], NULL, &curNtHash); 417 if (!NT_STATUS_IS_OK(nt_status)) { 418 return NT_STATUS_ACCESS_DENIED; 419 } 420 } 421 422 if (curNtHash == NULL) { 246 423 return NT_STATUS_ACCESS_DENIED; 247 424 } 248 425 249 if (!pipe_state) { 250 DEBUG(1, ("No challenge requested by client, cannot authenticate\n")); 426 if (!challenge_valid) { 427 DEBUG(1, ("No challenge requested by client [%s/%s], " 428 "cannot authenticate\n", 429 r->in.computer_name, 430 r->in.account_name)); 251 431 return NT_STATUS_ACCESS_DENIED; 252 432 } … … 256 436 r->in.computer_name, 257 437 r->in.secure_channel_type, 258 & pipe_state->client_challenge,259 & pipe_state->server_challenge,260 mach_pwd,438 &challenge.client_challenge, 439 &challenge.server_challenge, 440 curNtHash, 261 441 r->in.credentials, 262 442 r->out.return_credentials, 263 *r->in.negotiate_flags); 264 265 if (!creds) { 443 negotiate_flags); 444 if (creds == NULL && prevNtHash != NULL) { 445 /* 446 * We fallback to the previous password for domain trusts. 447 * 448 * Note that lpcfg_old_password_allowed_period() doesn't 449 * apply here. 450 */ 451 creds = netlogon_creds_server_init(mem_ctx, 452 r->in.account_name, 453 r->in.computer_name, 454 r->in.secure_channel_type, 455 &challenge.client_challenge, 456 &challenge.server_challenge, 457 prevNtHash, 458 r->in.credentials, 459 r->out.return_credentials, 460 negotiate_flags); 461 } 462 if (creds == NULL) { 266 463 return NT_STATUS_ACCESS_DENIED; 267 464 } … … 270 467 271 468 nt_status = schannel_save_creds_state(mem_ctx, 272 lpcfg_private_dir(dce_call->conn->dce_ctx->lp_ctx),469 dce_call->conn->dce_ctx->lp_ctx, 273 470 creds); 274 275 return nt_status; 471 if (!NT_STATUS_IS_OK(nt_status)) { 472 ZERO_STRUCTP(r->out.return_credentials); 473 return nt_status; 474 } 475 476 *r->out.rid = samdb_result_rid_from_sid(mem_ctx, msgs[0], 477 "objectSid", 0); 478 479 return NT_STATUS_OK; 276 480 } 277 481 … … 333 537 * If schannel is required for this call test that it actually is available. 334 538 */ 335 static NTSTATUS schannel_check_required( struct dcerpc_auth *auth_info,539 static NTSTATUS schannel_check_required(const struct dcesrv_auth *auth_info, 336 540 const char *computer_name, 337 541 bool integrity, bool privacy) … … 369 573 { 370 574 NTSTATUS nt_status; 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 */575 int schannel = lpcfg_server_schannel(dce_call->conn->dce_ctx->lp_ctx); 576 bool schannel_global_required = (schannel == true); 373 577 374 578 if (schannel_global_required) { 375 nt_status = schannel_check_required( auth_info,579 nt_status = schannel_check_required(&dce_call->conn->auth_state, 376 580 computer_name, 377 581 true, false); … … 382 586 383 587 nt_status = schannel_check_creds_state(mem_ctx, 384 lpcfg_private_dir(dce_call->conn->dce_ctx->lp_ctx),588 dce_call->conn->dce_ctx->lp_ctx, 385 589 computer_name, 386 590 received_authenticator, … … 429 633 } 430 634 431 nt_status = samdb_result_passwords (mem_ctx,432 dce_call->conn->dce_ctx->lp_ctx,433 res[0], NULL, &oldNtHash);635 nt_status = samdb_result_passwords_no_lockout(mem_ctx, 636 dce_call->conn->dce_ctx->lp_ctx, 637 res[0], NULL, &oldNtHash); 434 638 if (!NT_STATUS_IS_OK(nt_status) || !oldNtHash) { 435 639 return NT_STATUS_WRONG_PASSWORD; … … 439 643 nt_status = samdb_set_password_sid(sam_ctx, mem_ctx, 440 644 creds->sid, 645 NULL, /* Don't have version */ 441 646 NULL, /* Don't have plaintext */ 442 647 NULL, r->in.new_password, … … 458 663 struct ldb_message **res; 459 664 struct samr_Password *oldLmHash, *oldNtHash; 665 struct NL_PASSWORD_VERSION version = {}; 666 const uint32_t *new_version = NULL; 460 667 NTSTATUS nt_status; 461 668 DATA_BLOB new_password; 462 669 int ret; 463 464 670 struct samr_CryptPassword password_buf; 465 671 … … 478 684 memcpy(password_buf.data, r->in.new_password->data, 512); 479 685 SIVAL(password_buf.data, 512, r->in.new_password->length); 480 netlogon_creds_arcfour_crypt(creds, password_buf.data, 516); 686 687 if (creds->negotiate_flags & NETLOGON_NEG_SUPPORTS_AES) { 688 netlogon_creds_aes_decrypt(creds, password_buf.data, 516); 689 } else { 690 netlogon_creds_arcfour_crypt(creds, password_buf.data, 516); 691 } 692 693 switch (creds->secure_channel_type) { 694 case SEC_CHAN_DOMAIN: 695 case SEC_CHAN_DNS_DOMAIN: { 696 uint32_t len = IVAL(password_buf.data, 512); 697 if (len <= 500) { 698 uint32_t ofs = 500 - len; 699 uint8_t *p; 700 701 p = password_buf.data + ofs; 702 703 version.ReservedField = IVAL(p, 0); 704 version.PasswordVersionNumber = IVAL(p, 4); 705 version.PasswordVersionPresent = IVAL(p, 8); 706 707 if (version.PasswordVersionPresent == NETLOGON_PASSWORD_VERSION_NUMBER_PRESENT) { 708 new_version = &version.PasswordVersionNumber; 709 } 710 }} 711 break; 712 default: 713 break; 714 } 481 715 482 716 if (!extract_pw_from_buffer(mem_ctx, password_buf.data, &new_password)) { … … 494 728 } 495 729 496 nt_status = samdb_result_passwords (mem_ctx,497 dce_call->conn->dce_ctx->lp_ctx,498 res[0], &oldLmHash, &oldNtHash);730 nt_status = samdb_result_passwords_no_lockout(mem_ctx, 731 dce_call->conn->dce_ctx->lp_ctx, 732 res[0], &oldLmHash, &oldNtHash); 499 733 if (!NT_STATUS_IS_OK(nt_status) || (!oldLmHash && !oldNtHash)) { 500 734 return NT_STATUS_WRONG_PASSWORD; … … 504 738 nt_status = samdb_set_password_sid(sam_ctx, mem_ctx, 505 739 creds->sid, 740 new_version, 506 741 &new_password, /* we have plaintext */ 507 742 NULL, NULL, … … 601 836 struct netr_LogonSamLogonEx *r, struct netlogon_creds_CredentialState *creds) 602 837 { 603 struct auth_context *auth_context; 838 struct loadparm_context *lp_ctx = dce_call->conn->dce_ctx->lp_ctx; 839 const char *workgroup = lpcfg_workgroup(lp_ctx); 840 struct auth4_context *auth_context; 604 841 struct auth_usersupplied_info *user_info; 605 842 struct auth_user_info_dc *user_info_dc; 606 843 NTSTATUS nt_status; 607 static const char zeros[16];608 844 struct netr_SamBaseInfo *sam; 609 845 struct netr_SamInfo2 *sam2; … … 615 851 user_info = talloc_zero(mem_ctx, struct auth_usersupplied_info); 616 852 NT_STATUS_HAVE_NO_MEMORY(user_info); 853 854 netlogon_creds_decrypt_samlogon_logon(creds, 855 r->in.logon_level, 856 r->in.logon); 617 857 618 858 switch (r->in.logon_level) { … … 621 861 case NetlogonInteractiveTransitiveInformation: 622 862 case NetlogonServiceTransitiveInformation: 623 if (creds->negotiate_flags & NETLOGON_NEG_ARCFOUR) {624 netlogon_creds_arcfour_crypt(creds,625 r->in.logon->password->lmpassword.hash,626 sizeof(r->in.logon->password->lmpassword.hash));627 netlogon_creds_arcfour_crypt(creds,628 r->in.logon->password->ntpassword.hash,629 sizeof(r->in.logon->password->ntpassword.hash));630 } else {631 netlogon_creds_des_decrypt(creds, &r->in.logon->password->lmpassword);632 netlogon_creds_des_decrypt(creds, &r->in.logon->password->ntpassword);633 }634 863 635 864 /* TODO: we need to deny anonymous access here */ … … 679 908 user_info->password.response.nt = data_blob_talloc(mem_ctx, r->in.logon->network->nt.data, r->in.logon->network->nt.length); 680 909 910 nt_status = NTLMv2_RESPONSE_verify_netlogon_creds( 911 user_info->client.account_name, 912 user_info->client.domain_name, 913 user_info->password.response.nt, 914 creds, workgroup); 915 NT_STATUS_NOT_OK_RETURN(nt_status); 916 681 917 break; 682 918 … … 684 920 case NetlogonGenericInformation: 685 921 { 686 if (creds->negotiate_flags & NETLOGON_NEG_ARCFOUR) { 687 netlogon_creds_arcfour_crypt(creds, 688 r->in.logon->generic->data, r->in.logon->generic->length); 922 if (creds->negotiate_flags & NETLOGON_NEG_SUPPORTS_AES) { 923 /* OK */ 924 } else if (creds->negotiate_flags & NETLOGON_NEG_ARCFOUR) { 925 /* OK */ 689 926 } else { 690 927 /* Using DES to verify kerberos tickets makes no sense */ … … 717 954 r->in.logon->generic->length); 718 955 956 /* 957 * TODO: make this async and avoid 958 * dcerpc_binding_handle_set_sync_ev() 959 */ 960 dcerpc_binding_handle_set_sync_ev(irpc_handle, 961 dce_call->event_ctx); 719 962 status = dcerpc_kdc_check_generic_kerberos_r(irpc_handle, 720 963 mem_ctx, … … 767 1010 768 1011 case 6: 1012 if (dce_call->conn->auth_state.auth_level < DCERPC_AUTH_LEVEL_PRIVACY) { 1013 return NT_STATUS_INVALID_PARAMETER; 1014 } 1015 769 1016 nt_status = auth_convert_user_info_dc_saminfo3(mem_ctx, 770 1017 user_info_dc, … … 793 1040 } 794 1041 795 /* Don't crypt an all-zero key, it would give away the NETLOGON pipe session key */ 796 /* It appears that level 6 is not individually encrypted */ 797 if ((r->in.validation_level != 6) && 798 memcmp(sam->key.key, zeros, sizeof(sam->key.key)) != 0) { 799 /* This key is sent unencrypted without the ARCFOUR flag set */ 800 if (creds->negotiate_flags & NETLOGON_NEG_ARCFOUR) { 801 netlogon_creds_arcfour_crypt(creds, 802 sam->key.key, 803 sizeof(sam->key.key)); 804 } 805 } 806 807 /* Don't crypt an all-zero key, it would give away the NETLOGON pipe session key */ 808 /* It appears that level 6 is not individually encrypted */ 809 if ((r->in.validation_level != 6) && 810 memcmp(sam->LMSessKey.key, zeros, sizeof(sam->LMSessKey.key)) != 0) { 811 if (creds->negotiate_flags & NETLOGON_NEG_ARCFOUR) { 812 netlogon_creds_arcfour_crypt(creds, 813 sam->LMSessKey.key, 814 sizeof(sam->LMSessKey.key)); 815 } else { 816 netlogon_creds_des_encrypt_LMKey(creds, 817 &sam->LMSessKey); 818 } 819 } 1042 netlogon_creds_encrypt_samlogon_validation(creds, 1043 r->in.validation_level, 1044 r->out.validation); 820 1045 821 1046 /* TODO: Describe and deal with these flags */ … … 839 1064 840 1065 nt_status = schannel_get_creds_state(mem_ctx, 841 lpcfg_private_dir(dce_call->conn->dce_ctx->lp_ctx),1066 dce_call->conn->dce_ctx->lp_ctx, 842 1067 r->in.computer_name, &creds); 843 1068 if (!NT_STATUS_IS_OK(nt_status)) { … … 845 1070 } 846 1071 847 if (!dce_call->conn->auth_state.auth_info || 848 dce_call->conn->auth_state.auth_info->auth_type != DCERPC_AUTH_TYPE_SCHANNEL) { 1072 if (dce_call->conn->auth_state.auth_type != DCERPC_AUTH_TYPE_SCHANNEL) { 849 1073 return NT_STATUS_ACCESS_DENIED; 850 1074 } … … 1056 1280 r->in.domainname); 1057 1281 if (domain_dn == NULL) { 1058 return WERR_ DS_UNAVAILABLE;1282 return WERR_NO_SUCH_DOMAIN; 1059 1283 } 1060 1284 … … 1076 1300 } 1077 1301 1302 struct dcesrv_netr_LogonControl_base_state { 1303 struct dcesrv_call_state *dce_call; 1304 1305 TALLOC_CTX *mem_ctx; 1306 1307 struct netr_LogonControl2Ex r; 1308 1309 struct { 1310 struct netr_LogonControl *l; 1311 struct netr_LogonControl2 *l2; 1312 struct netr_LogonControl2Ex *l2ex; 1313 } _r; 1314 }; 1315 1316 static void dcesrv_netr_LogonControl_base_done(struct tevent_req *subreq); 1317 1318 static WERROR dcesrv_netr_LogonControl_base_call(struct dcesrv_netr_LogonControl_base_state *state) 1319 { 1320 struct dcesrv_connection *conn = state->dce_call->conn; 1321 struct loadparm_context *lp_ctx = state->dce_call->conn->dce_ctx->lp_ctx; 1322 struct auth_session_info *session_info = conn->auth_state.session_info; 1323 enum security_user_level security_level; 1324 struct dcerpc_binding_handle *irpc_handle; 1325 struct tevent_req *subreq; 1326 bool ok; 1327 1328 /* TODO: check for WERR_INVALID_COMPUTERNAME ? */ 1329 1330 if (state->_r.l != NULL) { 1331 /* 1332 * netr_LogonControl 1333 */ 1334 if (state->r.in.level == 0x00000002) { 1335 return WERR_NOT_SUPPORTED; 1336 } else if (state->r.in.level != 0x00000001) { 1337 return WERR_INVALID_LEVEL; 1338 } 1339 1340 switch (state->r.in.function_code) { 1341 case NETLOGON_CONTROL_QUERY: 1342 case NETLOGON_CONTROL_REPLICATE: 1343 case NETLOGON_CONTROL_SYNCHRONIZE: 1344 case NETLOGON_CONTROL_PDC_REPLICATE: 1345 case NETLOGON_CONTROL_BREAKPOINT: 1346 case NETLOGON_CONTROL_BACKUP_CHANGE_LOG: 1347 case NETLOGON_CONTROL_TRUNCATE_LOG: 1348 break; 1349 default: 1350 return WERR_NOT_SUPPORTED; 1351 } 1352 } 1353 1354 if (state->r.in.level < 0x00000001) { 1355 return WERR_INVALID_LEVEL; 1356 } 1357 1358 if (state->r.in.level > 0x00000004) { 1359 return WERR_INVALID_LEVEL; 1360 } 1361 1362 if (state->r.in.function_code == NETLOGON_CONTROL_QUERY) { 1363 struct netr_NETLOGON_INFO_1 *info1 = NULL; 1364 struct netr_NETLOGON_INFO_3 *info3 = NULL; 1365 1366 switch (state->r.in.level) { 1367 case 0x00000001: 1368 info1 = talloc_zero(state->mem_ctx, 1369 struct netr_NETLOGON_INFO_1); 1370 if (info1 == NULL) { 1371 return WERR_NOMEM; 1372 } 1373 state->r.out.query->info1 = info1; 1374 return WERR_OK; 1375 1376 case 0x00000003: 1377 info3 = talloc_zero(state->mem_ctx, 1378 struct netr_NETLOGON_INFO_3); 1379 if (info3 == NULL) { 1380 return WERR_NOMEM; 1381 } 1382 state->r.out.query->info3 = info3; 1383 return WERR_OK; 1384 1385 default: 1386 return WERR_INVALID_PARAMETER; 1387 } 1388 } 1389 1390 /* 1391 * Some validations are done before the access check 1392 * and some after the access check 1393 */ 1394 security_level = security_session_user_level(session_info, NULL); 1395 if (security_level < SECURITY_ADMINISTRATOR) { 1396 return WERR_ACCESS_DENIED; 1397 } 1398 1399 if (state->_r.l2 != NULL) { 1400 /* 1401 * netr_LogonControl2 1402 */ 1403 if (state->r.in.level == 0x00000004) { 1404 return WERR_INVALID_LEVEL; 1405 } 1406 } 1407 1408 switch (state->r.in.level) { 1409 case 0x00000001: 1410 break; 1411 1412 case 0x00000002: 1413 switch (state->r.in.function_code) { 1414 case NETLOGON_CONTROL_REDISCOVER: 1415 case NETLOGON_CONTROL_TC_QUERY: 1416 case NETLOGON_CONTROL_TC_VERIFY: 1417 break; 1418 default: 1419 return WERR_INVALID_PARAMETER; 1420 } 1421 1422 break; 1423 1424 case 0x00000003: 1425 break; 1426 1427 case 0x00000004: 1428 if (state->r.in.function_code != NETLOGON_CONTROL_FIND_USER) { 1429 return WERR_INVALID_PARAMETER; 1430 } 1431 1432 break; 1433 1434 default: 1435 return WERR_INVALID_LEVEL; 1436 } 1437 1438 switch (state->r.in.function_code) { 1439 case NETLOGON_CONTROL_REDISCOVER: 1440 case NETLOGON_CONTROL_TC_QUERY: 1441 case NETLOGON_CONTROL_TC_VERIFY: 1442 if (state->r.in.level != 2) { 1443 return WERR_INVALID_PARAMETER; 1444 } 1445 1446 if (state->r.in.data == NULL) { 1447 return WERR_INVALID_PARAMETER; 1448 } 1449 1450 if (state->r.in.data->domain == NULL) { 1451 return WERR_INVALID_PARAMETER; 1452 } 1453 1454 break; 1455 1456 case NETLOGON_CONTROL_CHANGE_PASSWORD: 1457 if (state->r.in.level != 1) { 1458 return WERR_INVALID_PARAMETER; 1459 } 1460 1461 if (state->r.in.data == NULL) { 1462 return WERR_INVALID_PARAMETER; 1463 } 1464 1465 if (state->r.in.data->domain == NULL) { 1466 return WERR_INVALID_PARAMETER; 1467 } 1468 1469 ok = lpcfg_is_my_domain_or_realm(lp_ctx, 1470 state->r.in.data->domain); 1471 if (!ok) { 1472 struct ldb_context *sam_ctx; 1473 1474 sam_ctx = samdb_connect(state, state->dce_call->event_ctx, 1475 lp_ctx, system_session(lp_ctx), 0); 1476 if (sam_ctx == NULL) { 1477 return WERR_DS_UNAVAILABLE; 1478 } 1479 1480 /* 1481 * Secrets for trusted domains can only be triggered on 1482 * the PDC. 1483 */ 1484 ok = samdb_is_pdc(sam_ctx); 1485 TALLOC_FREE(sam_ctx); 1486 if (!ok) { 1487 return WERR_INVALID_DOMAIN_ROLE; 1488 } 1489 } 1490 1491 break; 1492 default: 1493 return WERR_NOT_SUPPORTED; 1494 } 1495 1496 irpc_handle = irpc_binding_handle_by_name(state, 1497 state->dce_call->msg_ctx, 1498 "winbind_server", 1499 &ndr_table_winbind); 1500 if (irpc_handle == NULL) { 1501 DEBUG(0,("Failed to get binding_handle for winbind_server task\n")); 1502 state->dce_call->fault_code = DCERPC_FAULT_CANT_PERFORM; 1503 return WERR_SERVICE_NOT_FOUND; 1504 } 1505 1506 /* 1507 * 60 seconds timeout should be enough 1508 */ 1509 dcerpc_binding_handle_set_timeout(irpc_handle, 60); 1510 1511 subreq = dcerpc_winbind_LogonControl_send(state, 1512 state->dce_call->event_ctx, 1513 irpc_handle, 1514 state->r.in.function_code, 1515 state->r.in.level, 1516 state->r.in.data, 1517 state->r.out.query); 1518 if (subreq == NULL) { 1519 return WERR_NOMEM; 1520 } 1521 state->dce_call->state_flags |= DCESRV_CALL_STATE_FLAG_ASYNC; 1522 tevent_req_set_callback(subreq, 1523 dcesrv_netr_LogonControl_base_done, 1524 state); 1525 1526 return WERR_OK; 1527 } 1528 1529 static void dcesrv_netr_LogonControl_base_done(struct tevent_req *subreq) 1530 { 1531 struct dcesrv_netr_LogonControl_base_state *state = 1532 tevent_req_callback_data(subreq, 1533 struct dcesrv_netr_LogonControl_base_state); 1534 NTSTATUS status; 1535 1536 status = dcerpc_winbind_LogonControl_recv(subreq, state->mem_ctx, 1537 &state->r.out.result); 1538 TALLOC_FREE(subreq); 1539 if (NT_STATUS_EQUAL(status, NT_STATUS_IO_TIMEOUT)) { 1540 state->r.out.result = WERR_TIMEOUT; 1541 } else if (!NT_STATUS_IS_OK(status)) { 1542 state->dce_call->fault_code = DCERPC_FAULT_CANT_PERFORM; 1543 DEBUG(0,(__location__ ": IRPC callback failed %s\n", 1544 nt_errstr(status))); 1545 } 1546 1547 if (state->_r.l2ex != NULL) { 1548 struct netr_LogonControl2Ex *r = state->_r.l2ex; 1549 r->out.result = state->r.out.result; 1550 } else if (state->_r.l2 != NULL) { 1551 struct netr_LogonControl2 *r = state->_r.l2; 1552 r->out.result = state->r.out.result; 1553 } else if (state->_r.l != NULL) { 1554 struct netr_LogonControl *r = state->_r.l; 1555 r->out.result = state->r.out.result; 1556 } 1557 1558 status = dcesrv_reply(state->dce_call); 1559 if (!NT_STATUS_IS_OK(status)) { 1560 DEBUG(0,(__location__ ": dcesrv_reply() failed - %s\n", nt_errstr(status))); 1561 } 1562 } 1563 1564 /* 1565 netr_LogonControl 1566 */ 1567 static WERROR dcesrv_netr_LogonControl(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, 1568 struct netr_LogonControl *r) 1569 { 1570 struct dcesrv_netr_LogonControl_base_state *state; 1571 WERROR werr; 1572 1573 state = talloc_zero(mem_ctx, struct dcesrv_netr_LogonControl_base_state); 1574 if (state == NULL) { 1575 return WERR_NOMEM; 1576 } 1577 1578 state->dce_call = dce_call; 1579 state->mem_ctx = mem_ctx; 1580 1581 state->r.in.logon_server = r->in.logon_server; 1582 state->r.in.function_code = r->in.function_code; 1583 state->r.in.level = r->in.level; 1584 state->r.in.data = NULL; 1585 state->r.out.query = r->out.query; 1586 1587 state->_r.l = r; 1588 1589 werr = dcesrv_netr_LogonControl_base_call(state); 1590 1591 if (dce_call->state_flags & DCESRV_CALL_STATE_FLAG_ASYNC) { 1592 return werr; 1593 } 1594 1595 return werr; 1596 } 1597 1598 /* 1599 netr_LogonControl2 1600 */ 1601 static WERROR dcesrv_netr_LogonControl2(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, 1602 struct netr_LogonControl2 *r) 1603 { 1604 struct dcesrv_netr_LogonControl_base_state *state; 1605 WERROR werr; 1606 1607 state = talloc_zero(mem_ctx, struct dcesrv_netr_LogonControl_base_state); 1608 if (state == NULL) { 1609 return WERR_NOMEM; 1610 } 1611 1612 state->dce_call = dce_call; 1613 state->mem_ctx = mem_ctx; 1614 1615 state->r.in.logon_server = r->in.logon_server; 1616 state->r.in.function_code = r->in.function_code; 1617 state->r.in.level = r->in.level; 1618 state->r.in.data = r->in.data; 1619 state->r.out.query = r->out.query; 1620 1621 state->_r.l2 = r; 1622 1623 werr = dcesrv_netr_LogonControl_base_call(state); 1624 1625 if (dce_call->state_flags & DCESRV_CALL_STATE_FLAG_ASYNC) { 1626 return werr; 1627 } 1628 1629 return werr; 1630 } 1078 1631 1079 1632 /* … … 1083 1636 struct netr_LogonControl2Ex *r) 1084 1637 { 1085 return WERR_NOT_SUPPORTED; 1086 } 1087 1088 1089 /* 1090 netr_LogonControl 1091 */ 1092 static WERROR dcesrv_netr_LogonControl(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, 1093 struct netr_LogonControl *r) 1094 { 1095 struct netr_LogonControl2Ex r2; 1638 struct dcesrv_netr_LogonControl_base_state *state; 1096 1639 WERROR werr; 1097 1640 1098 if (r->in.level == 0x00000001) { 1099 ZERO_STRUCT(r2); 1100 1101 r2.in.logon_server = r->in.logon_server; 1102 r2.in.function_code = r->in.function_code; 1103 r2.in.level = r->in.level; 1104 r2.in.data = NULL; 1105 r2.out.query = r->out.query; 1106 1107 werr = dcesrv_netr_LogonControl2Ex(dce_call, mem_ctx, &r2); 1108 } else if (r->in.level == 0x00000002) { 1109 werr = WERR_NOT_SUPPORTED; 1110 } else { 1111 werr = WERR_UNKNOWN_LEVEL; 1112 } 1113 1114 return werr; 1115 } 1116 1117 1118 /* 1119 netr_LogonControl2 1120 */ 1121 static WERROR dcesrv_netr_LogonControl2(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, 1122 struct netr_LogonControl2 *r) 1123 { 1124 struct netr_LogonControl2Ex r2; 1125 WERROR werr; 1126 1127 ZERO_STRUCT(r2); 1128 1129 r2.in.logon_server = r->in.logon_server; 1130 r2.in.function_code = r->in.function_code; 1131 r2.in.level = r->in.level; 1132 r2.in.data = r->in.data; 1133 r2.out.query = r->out.query; 1134 1135 werr = dcesrv_netr_LogonControl2Ex(dce_call, mem_ctx, &r2); 1641 state = talloc_zero(mem_ctx, struct dcesrv_netr_LogonControl_base_state); 1642 if (state == NULL) { 1643 return WERR_NOMEM; 1644 } 1645 1646 state->dce_call = dce_call; 1647 state->mem_ctx = mem_ctx; 1648 1649 state->r = *r; 1650 state->_r.l2ex = r; 1651 1652 werr = dcesrv_netr_LogonControl_base_call(state); 1653 1654 if (dce_call->state_flags & DCESRV_CALL_STATE_FLAG_ASYNC) { 1655 return werr; 1656 } 1136 1657 1137 1658 return werr; … … 1234 1755 struct netr_LogonGetCapabilities *r) 1235 1756 { 1236 /* we don't support AES yet */ 1237 return NT_STATUS_NOT_IMPLEMENTED; 1757 struct netlogon_creds_CredentialState *creds; 1758 NTSTATUS status; 1759 1760 status = dcesrv_netr_creds_server_step_check(dce_call, 1761 mem_ctx, 1762 r->in.computer_name, 1763 r->in.credential, 1764 r->out.return_authenticator, 1765 &creds); 1766 if (!NT_STATUS_IS_OK(status)) { 1767 DEBUG(0,(__location__ " Bad credentials - error\n")); 1768 } 1769 NT_STATUS_NOT_OK_RETURN(status); 1770 1771 if (r->in.query_level != 1) { 1772 return NT_STATUS_NOT_SUPPORTED; 1773 } 1774 1775 r->out.capabilities->server_capabilities = creds->negotiate_flags; 1776 1777 return NT_STATUS_OK; 1238 1778 } 1239 1779 … … 1295 1835 } 1296 1836 1837 /* 1838 * We assume to be a DC when we get called over NETLOGON. Hence we 1839 * get our site name always by using "samdb_server_site_name()" 1840 * and not "samdb_client_site_name()". 1841 */ 1297 1842 *r->out.site = samdb_server_site_name(sam_ctx, mem_ctx); 1298 1843 W_ERROR_HAVE_NO_MEMORY(*r->out.site); … … 1652 2197 1653 2198 domain_info->workstation_flags = 1654 r->in.query->workstation_info->workstation_flags; 2199 r->in.query->workstation_info->workstation_flags & ( 2200 NETR_WS_FLAG_HANDLES_SPN_UPDATE | NETR_WS_FLAG_HANDLES_INBOUND_TRUSTS); 1655 2201 1656 2202 r->out.info->domain_info = domain_info; … … 1676 2222 netr_ServerPasswordGet 1677 2223 */ 1678 static WERRORdcesrv_netr_ServerPasswordGet(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,2224 static NTSTATUS dcesrv_netr_ServerPasswordGet(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, 1679 2225 struct netr_ServerPasswordGet *r) 1680 2226 { … … 1703 2249 struct netr_DsRGetDCNameInfo *info; 1704 2250 struct loadparm_context *lp_ctx = dce_call->conn->dce_ctx->lp_ctx; 2251 const struct tsocket_address *local_address; 2252 char *local_addr = NULL; 1705 2253 const struct tsocket_address *remote_address; 1706 char * addr = NULL;2254 char *remote_addr = NULL; 1707 2255 const char *server_site_name; 1708 2256 char *guid_str; … … 1711 2259 const char *dc_name = NULL; 1712 2260 const char *domain_name = NULL; 2261 const char *pdc_ip; 1713 2262 1714 2263 ZERO_STRUCTP(r->out.info); … … 1720 2269 } 1721 2270 2271 local_address = dcesrv_connection_get_local_address(dce_call->conn); 2272 if (tsocket_address_is_inet(local_address, "ip")) { 2273 local_addr = tsocket_address_inet_addr_string(local_address, mem_ctx); 2274 W_ERROR_HAVE_NO_MEMORY(local_addr); 2275 } 2276 1722 2277 remote_address = dcesrv_connection_get_remote_address(dce_call->conn); 1723 2278 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);2279 remote_addr = tsocket_address_inet_addr_string(remote_address, mem_ctx); 2280 W_ERROR_HAVE_NO_MEMORY(remote_addr); 1726 2281 } 1727 2282 … … 1781 2336 NULL, guid_str, 1782 2337 r->in.client_account, 1783 r->in.mask, addr,2338 r->in.mask, remote_addr, 1784 2339 NETLOGON_NT_VERSION_5EX_WITH_IP, 1785 2340 lp_ctx, &response, true); … … 1788 2343 } 1789 2344 2345 /* 2346 * According to MS-NRPC 2.2.1.2.1 we should set the "DS_DNS_FOREST_ROOT" 2347 * (O) flag when the returned forest name is in DNS format. This is here 2348 * always the case (see below). 2349 */ 2350 response.data.nt5_ex.server_type |= DS_DNS_FOREST_ROOT; 2351 1790 2352 if (r->in.flags & DS_RETURN_DNS_NAME) { 1791 2353 dc_name = response.data.nt5_ex.pdc_dns_name; 1792 2354 domain_name = response.data.nt5_ex.dns_domain; 2355 /* 2356 * According to MS-NRPC 2.2.1.2.1 we should set the 2357 * "DS_DNS_CONTROLLER" (M) and "DS_DNS_DOMAIN" (N) flags when 2358 * the returned information is in DNS form. 2359 */ 2360 response.data.nt5_ex.server_type |= 2361 DS_DNS_CONTROLLER | DS_DNS_DOMAIN; 1793 2362 } else if (r->in.flags & DS_RETURN_FLAT_NAME) { 1794 2363 dc_name = response.data.nt5_ex.pdc_name; … … 1814 2383 info = talloc(mem_ctx, struct netr_DsRGetDCNameInfo); 1815 2384 W_ERROR_HAVE_NO_MEMORY(info); 1816 info->dc_unc = talloc_asprintf(mem_ctx, "\\\\%s", dc_name); 2385 info->dc_unc = talloc_asprintf(mem_ctx, "%s%s", 2386 dc_name[0] != '\\'? "\\\\":"", 2387 talloc_strdup(mem_ctx, dc_name)); 1817 2388 W_ERROR_HAVE_NO_MEMORY(info->dc_unc); 1818 info->dc_address = talloc_asprintf(mem_ctx, "\\\\%s", 1819 response.data.nt5_ex.sockaddr.pdc_ip); 2389 2390 pdc_ip = local_addr; 2391 if (pdc_ip == NULL) { 2392 pdc_ip = "127.0.0.1"; 2393 } 2394 info->dc_address = talloc_asprintf(mem_ctx, "\\\\%s", pdc_ip); 1820 2395 W_ERROR_HAVE_NO_MEMORY(info->dc_address); 1821 info->dc_address_type = DS_ADDRESS_TYPE_INET; /* TODO: make this dynamic? for ipv6 */2396 info->dc_address_type = DS_ADDRESS_TYPE_INET; 1822 2397 info->domain_guid = response.data.nt5_ex.domain_uuid; 1823 2398 info->domain_name = domain_name; 1824 2399 info->forest_name = response.data.nt5_ex.forest; 1825 2400 info->dc_flags = response.data.nt5_ex.server_type; 2401 if (r->in.flags & DS_RETURN_DNS_NAME) { 2402 /* As MS-NRPC.pdf in 2.2.1.2.1 the DS_DNS_CONTROLLER flag should be 2403 * returned if we are returning info->dc_unc containing a FQDN. 2404 * This attribute is called DomainControllerName in the specs, 2405 * it seems that we decide to return FQDN or netbios depending on 2406 * DS_RETURN_DNS_NAME. 2407 */ 2408 info->dc_flags |= DS_DNS_CONTROLLER; 2409 } 1826 2410 info->dc_site_name = response.data.nt5_ex.server_site; 1827 2411 info->client_site_name = response.data.nt5_ex.client_site; … … 2061 2645 2062 2646 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 2647 static WERROR fill_trusted_domains_array(TALLOC_CTX *mem_ctx, 2079 2648 struct ldb_context *sam_ctx, … … 2131 2700 W_ERROR_HAVE_NO_MEMORY(trusts->array); 2132 2701 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"); 2702 trusts->array[n].netbios_name = talloc_steal(trusts->array, ldb_msg_find_attr_as_string(dom_res[i], "flatname", NULL)); 2703 if (!trusts->array[n].netbios_name) { 2704 DEBUG(0, ("DB Error, TrustedDomain entry (%s) " 2705 "without flatname\n", 2706 ldb_dn_get_linearized(dom_res[i]->dn))); 2707 } 2708 2709 trusts->array[n].dns_name = talloc_steal(trusts->array, ldb_msg_find_attr_as_string(dom_res[i], "trustPartner", NULL)); 2137 2710 2138 2711 trusts->array[n].trust_flags = flags; … … 2150 2723 "trustAttributes", 0); 2151 2724 2152 if ((trusts->array[n].trust_type == NETR_TRUST_TYPE_MIT) ||2153 (trusts->array[n].trust_type == NETR_TRUST_TYPE_DCE)) {2725 if ((trusts->array[n].trust_type == LSA_TRUST_TYPE_MIT) || 2726 (trusts->array[n].trust_type == LSA_TRUST_TYPE_DCE)) { 2154 2727 struct dom_sid zero_sid; 2155 2728 ZERO_STRUCT(zero_sid); … … 2257 2830 /* we are always the root domain for now */ 2258 2831 trusts->array[n].parent_index = 0; 2259 trusts->array[n].trust_type = NETR_TRUST_TYPE_UPLEVEL;2832 trusts->array[n].trust_type = LSA_TRUST_TYPE_UPLEVEL; 2260 2833 trusts->array[n].trust_attributes = 0; 2261 2834 trusts->array[n].sid = samdb_result_dom_sid(mem_ctx, … … 2281 2854 2282 2855 2856 static NTSTATUS dcesrv_netr_ServerGetTrustInfo(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, 2857 struct netr_ServerGetTrustInfo *r); 2858 2283 2859 /* 2284 2860 netr_ServerTrustPasswordsGet … … 2287 2863 struct netr_ServerTrustPasswordsGet *r) 2288 2864 { 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); 2332 if (ret != 1) { 2333 return WERR_GENERAL_FAILURE; 2334 } 2335 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); 2350 2351 return WERR_OK; 2865 struct netr_ServerGetTrustInfo r2 = {}; 2866 struct netr_TrustInfo *_ti = NULL; 2867 NTSTATUS status; 2868 2869 r2.in.server_name = r->in.server_name; 2870 r2.in.account_name = r->in.account_name; 2871 r2.in.secure_channel_type = r->in.secure_channel_type; 2872 r2.in.computer_name = r->in.computer_name; 2873 r2.in.credential = r->in.credential; 2874 2875 r2.out.return_authenticator = r->out.return_authenticator; 2876 r2.out.new_owf_password = r->out.new_owf_password; 2877 r2.out.old_owf_password = r->out.old_owf_password; 2878 r2.out.trust_info = &_ti; 2879 2880 status = dcesrv_netr_ServerGetTrustInfo(dce_call, mem_ctx, &r2); 2881 2882 r->out.return_authenticator = r2.out.return_authenticator; 2883 r->out.new_owf_password = r2.out.new_owf_password; 2884 r->out.old_owf_password = r2.out.old_owf_password; 2885 2886 return status; 2352 2887 } 2353 2888 … … 2355 2890 netr_DsRGetForestTrustInformation 2356 2891 */ 2892 struct dcesrv_netr_DsRGetForestTrustInformation_state { 2893 struct dcesrv_call_state *dce_call; 2894 TALLOC_CTX *mem_ctx; 2895 struct netr_DsRGetForestTrustInformation *r; 2896 }; 2897 2898 static void dcesrv_netr_DsRGetForestTrustInformation_done(struct tevent_req *subreq); 2899 2357 2900 static WERROR dcesrv_netr_DsRGetForestTrustInformation(struct dcesrv_call_state *dce_call, 2358 2901 TALLOC_CTX *mem_ctx, … … 2360 2903 { 2361 2904 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; 2905 struct dcesrv_connection *conn = dce_call->conn; 2906 struct auth_session_info *session_info = conn->auth_state.session_info; 2907 enum security_user_level security_level; 2908 struct ldb_context *sam_ctx = NULL; 2909 struct dcesrv_netr_DsRGetForestTrustInformation_state *state = NULL; 2910 struct dcerpc_binding_handle *irpc_handle = NULL; 2911 struct tevent_req *subreq = NULL; 2912 struct ldb_dn *domain_dn = NULL; 2913 struct ldb_dn *forest_dn = NULL; 2914 int cmp; 2915 int forest_level; 2916 2917 security_level = security_session_user_level(session_info, NULL); 2918 if (security_level < SECURITY_USER) { 2919 return WERR_ACCESS_DENIED; 2920 } 2365 2921 2366 2922 if (r->in.flags & 0xFFFFFFFE) { … … 2374 2930 } 2375 2931 2932 domain_dn = ldb_get_default_basedn(sam_ctx); 2933 if (domain_dn == NULL) { 2934 return WERR_GENERAL_FAILURE; 2935 } 2936 2937 forest_dn = ldb_get_root_basedn(sam_ctx); 2938 if (forest_dn == NULL) { 2939 return WERR_GENERAL_FAILURE; 2940 } 2941 2942 cmp = ldb_dn_compare(domain_dn, forest_dn); 2943 if (cmp != 0) { 2944 return WERR_NERR_ACFNOTLOADED; 2945 } 2946 2947 forest_level = dsdb_forest_functional_level(sam_ctx); 2948 if (forest_level < DS_DOMAIN_FUNCTION_2003) { 2949 return WERR_INVALID_FUNCTION; 2950 } 2951 2376 2952 if (r->in.flags & DS_GFTI_UPDATE_TDO) { 2377 2953 if (!samdb_is_pdc(sam_ctx)) { … … 2382 2958 return WERR_INVALID_FLAGS; 2383 2959 } 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; 2960 } 2961 2962 if (r->in.trusted_domain_name == NULL) { 2963 NTSTATUS status; 2964 2965 /* 2966 * information about our own domain 2967 */ 2968 status = dsdb_trust_xref_forest_info(mem_ctx, sam_ctx, 2969 r->out.forest_trust_info); 2970 if (!NT_STATUS_IS_OK(status)) { 2971 return ntstatus_to_werror(status); 2972 } 2973 2974 return WERR_OK; 2975 } 2976 2977 /* 2978 * Forward the request to winbindd 2979 */ 2980 2981 state = talloc_zero(mem_ctx, 2982 struct dcesrv_netr_DsRGetForestTrustInformation_state); 2983 if (state == NULL) { 2984 return WERR_NOMEM; 2985 } 2986 state->dce_call = dce_call; 2987 state->mem_ctx = mem_ctx; 2988 state->r = r; 2989 2990 irpc_handle = irpc_binding_handle_by_name(state, 2991 state->dce_call->msg_ctx, 2992 "winbind_server", 2993 &ndr_table_winbind); 2994 if (irpc_handle == NULL) { 2995 DEBUG(0,("Failed to get binding_handle for winbind_server task\n")); 2996 state->dce_call->fault_code = DCERPC_FAULT_CANT_PERFORM; 2997 return WERR_SERVICE_NOT_FOUND; 2998 } 2999 3000 /* 3001 * 60 seconds timeout should be enough 3002 */ 3003 dcerpc_binding_handle_set_timeout(irpc_handle, 60); 3004 3005 subreq = dcerpc_winbind_GetForestTrustInformation_send(state, 3006 state->dce_call->event_ctx, 3007 irpc_handle, 3008 r->in.trusted_domain_name, 3009 r->in.flags, 3010 r->out.forest_trust_info); 3011 if (subreq == NULL) { 3012 return WERR_NOMEM; 3013 } 3014 state->dce_call->state_flags |= DCESRV_CALL_STATE_FLAG_ASYNC; 3015 tevent_req_set_callback(subreq, 3016 dcesrv_netr_DsRGetForestTrustInformation_done, 3017 state); 2406 3018 2407 3019 return WERR_OK; 2408 3020 } 2409 3021 3022 static void dcesrv_netr_DsRGetForestTrustInformation_done(struct tevent_req *subreq) 3023 { 3024 struct dcesrv_netr_DsRGetForestTrustInformation_state *state = 3025 tevent_req_callback_data(subreq, 3026 struct dcesrv_netr_DsRGetForestTrustInformation_state); 3027 NTSTATUS status; 3028 3029 status = dcerpc_winbind_GetForestTrustInformation_recv(subreq, 3030 state->mem_ctx, 3031 &state->r->out.result); 3032 TALLOC_FREE(subreq); 3033 if (NT_STATUS_EQUAL(status, NT_STATUS_IO_TIMEOUT)) { 3034 state->r->out.result = WERR_TIMEOUT; 3035 } else if (!NT_STATUS_IS_OK(status)) { 3036 state->dce_call->fault_code = DCERPC_FAULT_CANT_PERFORM; 3037 DEBUG(0,(__location__ ": IRPC callback failed %s\n", 3038 nt_errstr(status))); 3039 } 3040 3041 status = dcesrv_reply(state->dce_call); 3042 if (!NT_STATUS_IS_OK(status)) { 3043 DEBUG(0,(__location__ ": dcesrv_reply() failed - %s\n", nt_errstr(status))); 3044 } 3045 } 2410 3046 2411 3047 /* … … 2417 3053 { 2418 3054 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; 3055 struct netlogon_creds_CredentialState *creds = NULL; 3056 struct ldb_context *sam_ctx = NULL; 3057 struct ldb_dn *domain_dn = NULL; 3058 struct ldb_dn *forest_dn = NULL; 3059 int cmp; 3060 int forest_level; 2422 3061 NTSTATUS status; 2423 WERROR werr;2424 3062 2425 3063 status = dcesrv_netr_creds_server_step_check(dce_call, … … 2441 3079 dce_call->conn->auth_state.session_info, 0); 2442 3080 if (sam_ctx == NULL) { 2443 return NT_STATUS_ UNSUCCESSFUL;3081 return NT_STATUS_INTERNAL_ERROR; 2444 3082 } 2445 3083 2446 3084 /* TODO: check r->in.server_name is our name */ 2447 3085 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; 3086 domain_dn = ldb_get_default_basedn(sam_ctx); 3087 if (domain_dn == NULL) { 3088 return NT_STATUS_INTERNAL_ERROR; 3089 } 3090 3091 forest_dn = ldb_get_root_basedn(sam_ctx); 3092 if (forest_dn == NULL) { 3093 return NT_STATUS_INTERNAL_ERROR; 3094 } 3095 3096 cmp = ldb_dn_compare(domain_dn, forest_dn); 3097 if (cmp != 0) { 3098 return NT_STATUS_INVALID_DOMAIN_STATE; 3099 } 3100 3101 forest_level = dsdb_forest_functional_level(sam_ctx); 3102 if (forest_level < DS_DOMAIN_FUNCTION_2003) { 3103 return NT_STATUS_INVALID_DOMAIN_STATE; 3104 } 3105 3106 status = dsdb_trust_xref_forest_info(mem_ctx, sam_ctx, 3107 r->out.forest_trust_info); 3108 if (!NT_STATUS_IS_OK(status)) { 3109 return status; 3110 } 2464 3111 2465 3112 return NT_STATUS_OK; … … 2473 3120 struct netr_ServerGetTrustInfo *r) 2474 3121 { 2475 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR); 3122 struct loadparm_context *lp_ctx = dce_call->conn->dce_ctx->lp_ctx; 3123 struct netlogon_creds_CredentialState *creds = NULL; 3124 struct ldb_context *sam_ctx = NULL; 3125 const char * const attrs[] = { 3126 "unicodePwd", 3127 "sAMAccountName", 3128 "userAccountControl", 3129 NULL 3130 }; 3131 struct ldb_message **res = NULL; 3132 struct samr_Password *curNtHash = NULL, *prevNtHash = NULL; 3133 NTSTATUS nt_status; 3134 int ret; 3135 const char *asid = NULL; 3136 uint32_t uac = 0; 3137 const char *aname = NULL; 3138 struct ldb_message *tdo_msg = NULL; 3139 const char * const tdo_attrs[] = { 3140 "trustAuthIncoming", 3141 "trustAttributes", 3142 NULL 3143 }; 3144 struct netr_TrustInfo *trust_info = NULL; 3145 3146 ZERO_STRUCTP(r->out.new_owf_password); 3147 ZERO_STRUCTP(r->out.old_owf_password); 3148 3149 nt_status = dcesrv_netr_creds_server_step_check(dce_call, 3150 mem_ctx, 3151 r->in.computer_name, 3152 r->in.credential, 3153 r->out.return_authenticator, 3154 &creds); 3155 if (!NT_STATUS_IS_OK(nt_status)) { 3156 return nt_status; 3157 } 3158 3159 /* TODO: check r->in.server_name is our name */ 3160 3161 if (strcasecmp_m(r->in.account_name, creds->account_name) != 0) { 3162 return NT_STATUS_INVALID_PARAMETER; 3163 } 3164 3165 if (r->in.secure_channel_type != creds->secure_channel_type) { 3166 return NT_STATUS_INVALID_PARAMETER; 3167 } 3168 3169 if (strcasecmp_m(r->in.computer_name, creds->computer_name) != 0) { 3170 return NT_STATUS_INVALID_PARAMETER; 3171 } 3172 3173 sam_ctx = samdb_connect(mem_ctx, dce_call->event_ctx, 3174 lp_ctx, system_session(lp_ctx), 0); 3175 if (sam_ctx == NULL) { 3176 return NT_STATUS_INVALID_SYSTEM_SERVICE; 3177 } 3178 3179 asid = ldap_encode_ndr_dom_sid(mem_ctx, creds->sid); 3180 if (asid == NULL) { 3181 return NT_STATUS_NO_MEMORY; 3182 } 3183 3184 ret = gendb_search(sam_ctx, mem_ctx, NULL, &res, attrs, 3185 "(&(objectClass=user)(objectSid=%s))", 3186 asid); 3187 if (ret != 1) { 3188 return NT_STATUS_ACCOUNT_DISABLED; 3189 } 3190 3191 switch (creds->secure_channel_type) { 3192 case SEC_CHAN_DNS_DOMAIN: 3193 case SEC_CHAN_DOMAIN: 3194 uac = ldb_msg_find_attr_as_uint(res[0], "userAccountControl", 0); 3195 3196 if (uac & UF_ACCOUNTDISABLE) { 3197 return NT_STATUS_ACCOUNT_DISABLED; 3198 } 3199 3200 if (!(uac & UF_INTERDOMAIN_TRUST_ACCOUNT)) { 3201 return NT_STATUS_ACCOUNT_DISABLED; 3202 } 3203 3204 aname = ldb_msg_find_attr_as_string(res[0], "sAMAccountName", NULL); 3205 if (aname == NULL) { 3206 return NT_STATUS_ACCOUNT_DISABLED; 3207 } 3208 3209 nt_status = dsdb_trust_search_tdo_by_type(sam_ctx, 3210 SEC_CHAN_DOMAIN, aname, 3211 tdo_attrs, mem_ctx, &tdo_msg); 3212 if (NT_STATUS_EQUAL(nt_status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) { 3213 return NT_STATUS_ACCOUNT_DISABLED; 3214 } 3215 if (!NT_STATUS_IS_OK(nt_status)) { 3216 return nt_status; 3217 } 3218 3219 nt_status = dsdb_trust_get_incoming_passwords(tdo_msg, mem_ctx, 3220 &curNtHash, 3221 &prevNtHash); 3222 if (!NT_STATUS_IS_OK(nt_status)) { 3223 return nt_status; 3224 } 3225 3226 trust_info = talloc_zero(mem_ctx, struct netr_TrustInfo); 3227 if (trust_info == NULL) { 3228 return NT_STATUS_NO_MEMORY; 3229 } 3230 3231 trust_info->count = 1; 3232 trust_info->data = talloc_array(trust_info, uint32_t, 3233 trust_info->count); 3234 if (trust_info->data == NULL) { 3235 return NT_STATUS_NO_MEMORY; 3236 } 3237 3238 trust_info->data[0] = ldb_msg_find_attr_as_uint(tdo_msg, 3239 "trustAttributes", 3240 0); 3241 break; 3242 3243 default: 3244 nt_status = samdb_result_passwords_no_lockout(mem_ctx, lp_ctx, 3245 res[0], 3246 NULL, &curNtHash); 3247 if (!NT_STATUS_IS_OK(nt_status)) { 3248 return nt_status; 3249 } 3250 3251 prevNtHash = talloc(mem_ctx, struct samr_Password); 3252 if (prevNtHash == NULL) { 3253 return NT_STATUS_NO_MEMORY; 3254 } 3255 3256 E_md4hash("", prevNtHash->hash); 3257 break; 3258 } 3259 3260 if (curNtHash != NULL) { 3261 *r->out.new_owf_password = *curNtHash; 3262 netlogon_creds_des_encrypt(creds, r->out.new_owf_password); 3263 } 3264 if (prevNtHash != NULL) { 3265 *r->out.old_owf_password = *prevNtHash; 3266 netlogon_creds_des_encrypt(creds, r->out.old_owf_password); 3267 } 3268 3269 if (trust_info != NULL) { 3270 *r->out.trust_info = trust_info; 3271 } 3272 3273 return NT_STATUS_OK; 2476 3274 } 2477 3275 -
vendor/current/source4/rpc_server/remote/dcesrv_remote.c
r740 r988 29 29 #include "param/param.h" 30 30 31 NTSTATUS dcerpc_server_remote_init(void); 31 32 32 33 struct dcesrv_remote_private { … … 71 72 domain = lpcfg_parm_string(dce_call->conn->dce_ctx->lp_ctx, NULL, "dceprc_remote", "domain"); 72 73 73 table = ndr_table_by_ uuid(&iface->syntax_id.uuid); /* FIXME: What about if_version ? */74 table = ndr_table_by_syntax(&iface->syntax_id); 74 75 if (!table) { 75 76 dce_call->fault_code = DCERPC_FAULT_UNK_IF; … … 115 116 return status; 116 117 } 117 118 119 /* If we already have a remote association group ID, then use that */ 120 if (dce_call->conn->assoc_group->proxied_id != 0) { 121 status = dcerpc_binding_set_assoc_group_id(b, 122 dce_call->conn->assoc_group->proxied_id); 123 if (!NT_STATUS_IS_OK(status)) { 124 DEBUG(0, ("dcerpc_binding_set_assoc_group_id() - %s'\n", 125 nt_errstr(status))); 126 return status; 127 } 128 } 129 130 status = dcerpc_binding_set_abstract_syntax(b, &iface->syntax_id); 131 if (!NT_STATUS_IS_OK(status)) { 132 DEBUG(0, ("dcerpc_binding_set_abstract_syntax() - %s'\n", 133 nt_errstr(status))); 134 return status; 135 } 136 118 137 DEBUG(3, ("Using binding %s\n", dcerpc_binding_string(dce_call->context, b))); 119 120 /* If we already have a remote association group ID, then use that */121 if (dce_call->context->assoc_group->proxied_id != 0) {122 b->assoc_group_id = dce_call->context->assoc_group->proxied_id;123 }124 125 b->object.if_version = if_version;126 138 127 139 pipe_conn_req = dcerpc_pipe_connect_b_send(dce_call->context, b, table, … … 137 149 } 138 150 139 if (dce_call->context->assoc_group->proxied_id == 0) { 140 dce_call->context->assoc_group->proxied_id = priv->c_pipe->assoc_group_id; 151 if (dce_call->conn->assoc_group->proxied_id == 0) { 152 dce_call->conn->assoc_group->proxied_id = 153 dcerpc_binding_get_assoc_group_id(priv->c_pipe->binding); 141 154 } 142 155 … … 157 170 158 171 if (opnum >= table->num_calls) { 172 dce_call->fault_code = DCERPC_FAULT_OP_RNG_ERROR; 173 return NT_STATUS_NET_WRITE_FAULT; 174 } 175 176 /* 177 * We don't have support for calls with pipes. 178 */ 179 if (table->calls[opnum].in_pipes.num_pipes != 0) { 180 dce_call->fault_code = DCERPC_FAULT_OP_RNG_ERROR; 181 return NT_STATUS_NET_WRITE_FAULT; 182 } 183 if (table->calls[opnum].out_pipes.num_pipes != 0) { 159 184 dce_call->fault_code = DCERPC_FAULT_OP_RNG_ERROR; 160 185 return NT_STATUS_NET_WRITE_FAULT; … … 292 317 { 293 318 unsigned int i; 294 c onst char **ifaces = (const char **)str_list_make(dce_ctx, lpcfg_parm_string(dce_ctx->lp_ctx, NULL, "dcerpc_remote", "interfaces"),NULL);319 char **ifaces = str_list_make(dce_ctx, lpcfg_parm_string(dce_ctx->lp_ctx, NULL, "dcerpc_remote", "interfaces"),NULL); 295 320 296 321 if (!ifaces) { -
vendor/current/source4/rpc_server/samr/dcesrv_samr.c
r740 r988 42 42 #include "libds/common/flag_mapping.h" 43 43 44 #define DCESRV_INTERFACE_SAMR_BIND(call, iface) \ 45 dcesrv_interface_samr_bind(call, iface) 46 static NTSTATUS dcesrv_interface_samr_bind(struct dcesrv_call_state *dce_call, 47 const struct dcesrv_interface *iface) 48 { 49 return dcesrv_interface_bind_reject_connect(dce_call, iface); 50 } 51 44 52 /* these query macros make samr_Query[User|Group|Alias]Info a bit easier to read */ 45 53 … … 58 66 info->field = samdb_result_force_password_change(sam_ctx, mem_ctx, \ 59 67 a_state->domain_state->domain_dn, msg); 68 #define QUERY_BPWDCT(msg, field, attr) \ 69 info->field = samdb_result_effective_badPwdCount(sam_ctx, mem_ctx, \ 70 a_state->domain_state->domain_dn, msg); 60 71 #define QUERY_LHOURS(msg, field, attr) \ 61 72 info->field = samdb_result_logon_hours(mem_ctx, msg, attr); 62 73 #define QUERY_AFLAGS(msg, field, attr) \ 63 info->field = samdb_result_acct_flags(sam_ctx, mem_ctx, msg, a_state->domain_state->domain_dn); 64 #define QUERY_PARAMETERS(msg, field, attr) \ 65 info->field = samdb_result_parameters(mem_ctx, msg, attr); 74 info->field = samdb_result_acct_flags(msg, attr); 66 75 67 76 … … 110 119 } while (0) 111 120 112 #define CHECK_FOR_MULTIPLES(value, flag, poss_flags) \113 do { \114 if ((value & flag) && ((value & flag) != (value & (poss_flags)))) { \115 return NT_STATUS_INVALID_PARAMETER; \116 } \117 } while (0) \118 119 121 /* Set account flags, discarding flags that cannot be set with SAMR */ 120 122 #define SET_AFLAGS(msg, field, attr) do { \ 121 123 struct ldb_message_element *set_el; \ 122 if ((r->in.info->field & (ACB_NORMAL | ACB_DOMTRUST | ACB_WSTRUST | ACB_SVRTRUST)) == 0) { \ 123 return NT_STATUS_INVALID_PARAMETER; \ 124 } \ 125 CHECK_FOR_MULTIPLES(r->in.info->field, ACB_NORMAL, ACB_NORMAL | ACB_DOMTRUST | ACB_WSTRUST | ACB_SVRTRUST); \ 126 CHECK_FOR_MULTIPLES(r->in.info->field, ACB_DOMTRUST, ACB_NORMAL | ACB_DOMTRUST | ACB_WSTRUST | ACB_SVRTRUST); \ 127 CHECK_FOR_MULTIPLES(r->in.info->field, ACB_WSTRUST, ACB_NORMAL | ACB_DOMTRUST | ACB_WSTRUST | ACB_SVRTRUST); \ 128 CHECK_FOR_MULTIPLES(r->in.info->field, ACB_SVRTRUST, ACB_NORMAL | ACB_DOMTRUST | ACB_WSTRUST | ACB_SVRTRUST); \ 129 if (samdb_msg_add_acct_flags(sam_ctx, mem_ctx, msg, attr, (r->in.info->field & ~(ACB_AUTOLOCK|ACB_PW_EXPIRED))) != 0) { \ 124 if (samdb_msg_add_acct_flags(sam_ctx, mem_ctx, msg, attr, r->in.info->field) != 0) { \ 130 125 return NT_STATUS_NO_MEMORY; \ 131 126 } \ … … 327 322 struct samr_EnumDomains *r) 328 323 { 329 struct samr_connect_state *c_state;330 324 struct dcesrv_handle *h; 331 325 struct samr_SamArray *array; … … 337 331 338 332 DCESRV_PULL_HANDLE(h, r->in.connect_handle, SAMR_HANDLE_CONNECT); 339 340 c_state = h->data;341 333 342 334 *r->out.resume_handle = 2; … … 501 493 0); 502 494 switch (state->role) { 503 case ROLE_ DOMAIN_CONTROLLER:495 case ROLE_ACTIVE_DIRECTORY_DC: 504 496 /* This pulls the NetBIOS name from the 505 497 cn=NTDS Settings,cn=<NETBIOS name of PDC>,.... … … 511 503 } 512 504 break; 505 case ROLE_DOMAIN_PDC: 506 case ROLE_DOMAIN_BDC: 507 case ROLE_AUTO: 508 return NT_STATUS_INTERNAL_ERROR; 513 509 case ROLE_DOMAIN_MEMBER: 514 510 info->role = SAMR_ROLE_DOMAIN_MEMBER; … … 604 600 605 601 switch (state->role) { 606 case ROLE_ DOMAIN_CONTROLLER:602 case ROLE_ACTIVE_DIRECTORY_DC: 607 603 /* This pulls the NetBIOS name from the 608 604 cn=NTDS Settings,cn=<NETBIOS name of PDC>,.... … … 614 610 } 615 611 break; 612 case ROLE_DOMAIN_PDC: 613 case ROLE_DOMAIN_BDC: 614 case ROLE_AUTO: 615 return NT_STATUS_INTERNAL_ERROR; 616 616 case ROLE_DOMAIN_MEMBER: 617 617 info->role = SAMR_ROLE_DOMAIN_MEMBER; … … 986 986 ldb_dn_get_linearized(d_state->domain_dn), 987 987 ldb_errstring(sam_ctx))); 988 989 /* we really need samdb.c to return NTSTATUS */ 990 return NT_STATUS_UNSUCCESSFUL; 988 return dsdb_ldb_err_to_ntstatus(ret); 991 989 } 992 990 … … 1202 1200 } 1203 1201 1204 status = dsdb_add_user(d_state->sam_ctx, mem_ctx, account_name, r->in.acct_flags, &sid, &dn); 1202 status = dsdb_add_user(d_state->sam_ctx, mem_ctx, account_name, r->in.acct_flags, NULL, 1203 &sid, &dn); 1205 1204 if (!NT_STATUS_IS_OK(status)) { 1206 1205 return status; … … 1208 1207 a_state = talloc(mem_ctx, struct samr_account_state); 1209 1208 if (!a_state) { 1210 ldb_transaction_cancel(d_state->sam_ctx);1211 1209 return NT_STATUS_NO_MEMORY; 1212 1210 } … … 1249 1247 1250 1248 /* a simple wrapper around samr_CreateUser2 works nicely */ 1251 r2.in.domain_handle = r->in.domain_handle; 1252 r2.in.account_name = r->in.account_name; 1253 r2.in.acct_flags = ACB_NORMAL; 1254 r2.in.access_mask = r->in.access_mask; 1255 r2.out.user_handle = r->out.user_handle; 1256 r2.out.access_granted = &access_granted; 1257 r2.out.rid = r->out.rid; 1249 1250 r2 = (struct samr_CreateUser2) { 1251 .in.domain_handle = r->in.domain_handle, 1252 .in.account_name = r->in.account_name, 1253 .in.acct_flags = ACB_NORMAL, 1254 .in.access_mask = r->in.access_mask, 1255 .out.user_handle = r->out.user_handle, 1256 .out.access_granted = &access_granted, 1257 .out.rid = r->out.rid 1258 }; 1258 1259 1259 1260 return dcesrv_samr_CreateUser2(dce_call, mem_ctx, &r2); … … 1306 1307 /* Check if a mask has been requested */ 1307 1308 if (r->in.acct_flags 1308 && ((samdb_result_acct_flags(d_state->sam_ctx, mem_ctx, 1309 res[i], d_state->domain_dn) & r->in.acct_flags) == 0)) { 1309 && ((samdb_result_acct_flags(res[i], NULL) & r->in.acct_flags) == 0)) { 1310 1310 continue; 1311 1311 } … … 1755 1755 1756 1756 /* search for the group record */ 1757 ret = gendb_search(d_state->sam_ctx, 1758 mem_ctx, d_state->domain_dn, &msgs, attrs, 1759 "(&(objectSid=%s)(objectClass=group)" 1760 "(|(groupType=%d)(groupType=%d)))", 1761 ldap_encode_ndr_dom_sid(mem_ctx, sid), 1762 GTYPE_SECURITY_UNIVERSAL_GROUP, 1763 GTYPE_SECURITY_GLOBAL_GROUP); 1757 if (d_state->builtin) { 1758 ret = gendb_search(d_state->sam_ctx, 1759 mem_ctx, d_state->domain_dn, &msgs, attrs, 1760 "(&(objectSid=%s)(objectClass=group)" 1761 "(groupType=%d))", 1762 ldap_encode_ndr_dom_sid(mem_ctx, sid), 1763 GTYPE_SECURITY_BUILTIN_LOCAL_GROUP); 1764 } else { 1765 ret = gendb_search(d_state->sam_ctx, 1766 mem_ctx, d_state->domain_dn, &msgs, attrs, 1767 "(&(objectSid=%s)(objectClass=group)" 1768 "(|(groupType=%d)(groupType=%d)))", 1769 ldap_encode_ndr_dom_sid(mem_ctx, sid), 1770 GTYPE_SECURITY_UNIVERSAL_GROUP, 1771 GTYPE_SECURITY_GLOBAL_GROUP); 1772 } 1764 1773 if (ret == 0) { 1765 1774 return NT_STATUS_NO_SUCH_GROUP; … … 1885 1894 struct samr_account_state *g_state; 1886 1895 struct ldb_message *msg; 1887 struct ldb_context *sam_ctx;1888 1896 int ret; 1889 1897 … … 1891 1899 1892 1900 g_state = h->data; 1893 sam_ctx = g_state->sam_ctx;1894 1901 1895 1902 msg = ldb_msg_new(mem_ctx); … … 1922 1929 ret = ldb_modify(g_state->sam_ctx, msg); 1923 1930 if (ret != LDB_SUCCESS) { 1924 /* we really need samdb.c to return NTSTATUS */ 1925 return NT_STATUS_UNSUCCESSFUL; 1931 return dsdb_ldb_err_to_ntstatus(ret); 1926 1932 } 1927 1933 … … 1989 1995 memberdn); 1990 1996 if (ret != LDB_SUCCESS) { 1991 return NT_STATUS_UNSUCCESSFUL;1997 return dsdb_ldb_err_to_ntstatus(ret); 1992 1998 } 1993 1999 … … 2001 2007 return NT_STATUS_ACCESS_DENIED; 2002 2008 default: 2003 return NT_STATUS_UNSUCCESSFUL;2009 return dsdb_ldb_err_to_ntstatus(ret); 2004 2010 } 2005 2011 } … … 2024 2030 ret = ldb_delete(a_state->sam_ctx, a_state->account_dn); 2025 2031 if (ret != LDB_SUCCESS) { 2026 return NT_STATUS_UNSUCCESSFUL;2032 return dsdb_ldb_err_to_ntstatus(ret); 2027 2033 } 2028 2034 … … 2105 2111 return NT_STATUS_ACCESS_DENIED; 2106 2112 default: 2107 return NT_STATUS_UNSUCCESSFUL;2113 return dsdb_ldb_err_to_ntstatus(ret); 2108 2114 } 2109 2115 } … … 2338 2344 struct samr_account_state *a_state; 2339 2345 struct ldb_message *msg; 2340 struct ldb_context *sam_ctx;2341 2346 int ret; 2342 2347 … … 2344 2349 2345 2350 a_state = h->data; 2346 sam_ctx = a_state->sam_ctx;2347 2351 2348 2352 msg = ldb_msg_new(mem_ctx); … … 2372 2376 ret = ldb_modify(a_state->sam_ctx, msg); 2373 2377 if (ret != LDB_SUCCESS) { 2374 /* we really need samdb.c to return NTSTATUS */ 2375 return NT_STATUS_UNSUCCESSFUL; 2378 return dsdb_ldb_err_to_ntstatus(ret); 2376 2379 } 2377 2380 … … 2398 2401 ret = ldb_delete(a_state->sam_ctx, a_state->account_dn); 2399 2402 if (ret != LDB_SUCCESS) { 2400 return NT_STATUS_UNSUCCESSFUL;2403 return dsdb_ldb_err_to_ntstatus(ret); 2401 2404 } 2402 2405 … … 2462 2465 ldb_dn_alloc_linearized(mem_ctx, memberdn)); 2463 2466 if (ret != LDB_SUCCESS) { 2464 return NT_STATUS_UNSUCCESSFUL;2467 return dsdb_ldb_err_to_ntstatus(ret); 2465 2468 } 2466 2469 … … 2474 2477 return NT_STATUS_ACCESS_DENIED; 2475 2478 default: 2476 return NT_STATUS_UNSUCCESSFUL;2479 return dsdb_ldb_err_to_ntstatus(ret); 2477 2480 } 2478 2481 } … … 2514 2517 memberdn); 2515 2518 if (ret != LDB_SUCCESS) { 2516 return NT_STATUS_UNSUCCESSFUL;2519 return dsdb_ldb_err_to_ntstatus(ret); 2517 2520 } 2518 2521 … … 2526 2529 return NT_STATUS_ACCESS_DENIED; 2527 2530 default: 2528 return NT_STATUS_UNSUCCESSFUL;2531 return dsdb_ldb_err_to_ntstatus(ret); 2529 2532 } 2530 2533 } … … 2677 2680 ldb_dn_get_linearized(a_state->account_dn), 2678 2681 ldb_errstring(a_state->sam_ctx))); 2679 return NT_STATUS_UNSUCCESSFUL;2682 return dsdb_ldb_err_to_ntstatus(ret); 2680 2683 } 2681 2684 … … 2701 2704 const char * const *attrs = NULL; 2702 2705 union samr_UserInfo *info; 2706 2707 NTSTATUS status; 2703 2708 2704 2709 *r->out.info = NULL; … … 2747 2752 "logonHours", 2748 2753 "badPwdCount", 2754 "badPasswordTime", 2749 2755 "logonCount", 2750 2756 "userAccountControl", 2757 "msDS-User-Account-Control-Computed", 2751 2758 NULL}; 2752 2759 attrs = attrs2; … … 2776 2783 "logonHours", 2777 2784 "badPwdCount", 2785 "badPasswordTime", 2778 2786 "logonCount", 2779 2787 "pwdLastSet", 2780 2788 "accountExpires", 2781 2789 "userAccountControl", 2790 "msDS-User-Account-Control-Computed", 2782 2791 NULL}; 2783 2792 attrs = attrs2; … … 2852 2861 { 2853 2862 static const char * const attrs2[] = {"userAccountControl", 2863 "msDS-User-Account-Control-Computed", 2854 2864 "pwdLastSet", 2855 2865 NULL}; … … 2894 2904 "primaryGroupID", 2895 2905 "userAccountControl", 2906 "msDS-User-Account-Control-Computed", 2896 2907 "logonHours", 2897 2908 "badPwdCount", 2909 "badPasswordTime", 2898 2910 "logonCount", 2899 2911 "countryCode", … … 2965 2977 QUERY_FPASSC(msg, info3.force_password_change, "pwdLastSet"); 2966 2978 QUERY_LHOURS(msg, info3.logon_hours, "logonHours"); 2979 /* level 3 gives the raw badPwdCount value */ 2967 2980 QUERY_UINT (msg, info3.bad_password_count, "badPwdCount"); 2968 2981 QUERY_UINT (msg, info3.logon_count, "logonCount"); 2969 QUERY_AFLAGS(msg, info3.acct_flags, " userAccountControl");2982 QUERY_AFLAGS(msg, info3.acct_flags, "msDS-User-Account-Control-Computed"); 2970 2983 break; 2971 2984 … … 2988 3001 QUERY_UINT64(msg, info5.last_logoff, "lastLogoff"); 2989 3002 QUERY_LHOURS(msg, info5.logon_hours, "logonHours"); 2990 QUERY_ UINT(msg, info5.bad_password_count, "badPwdCount");3003 QUERY_BPWDCT(msg, info5.bad_password_count, "badPwdCount"); 2991 3004 QUERY_UINT (msg, info5.logon_count, "logonCount"); 2992 3005 QUERY_UINT64(msg, info5.last_password_change, "pwdLastSet"); 2993 3006 QUERY_UINT64(msg, info5.acct_expiry, "accountExpires"); 2994 QUERY_AFLAGS(msg, info5.acct_flags, " userAccountControl");3007 QUERY_AFLAGS(msg, info5.acct_flags, "msDS-User-Account-Control-Computed"); 2995 3008 break; 2996 3009 … … 3034 3047 3035 3048 case 16: 3036 QUERY_AFLAGS(msg, info16.acct_flags, " userAccountControl");3049 QUERY_AFLAGS(msg, info16.acct_flags, "msDS-User-Account-Control-Computed"); 3037 3050 break; 3038 3051 … … 3042 3055 3043 3056 case 20: 3044 QUERY_PARAMETERS(msg, info20.parameters, "userParameters"); 3057 status = samdb_result_parameters(mem_ctx, msg, "userParameters", &info->info20.parameters); 3058 if (!NT_STATUS_IS_OK(status)) { 3059 talloc_free(info); 3060 return status; 3061 } 3045 3062 break; 3046 3063 … … 3061 3078 QUERY_STRING(msg, info21.workstations, "userWorkstations"); 3062 3079 QUERY_STRING(msg, info21.comment, "comment"); 3063 QUERY_PARAMETERS(msg, info21.parameters, "userParameters"); 3080 status = samdb_result_parameters(mem_ctx, msg, "userParameters", &info->info21.parameters); 3081 if (!NT_STATUS_IS_OK(status)) { 3082 talloc_free(info); 3083 return status; 3084 } 3085 3064 3086 QUERY_RID (msg, info21.rid, "objectSid"); 3065 3087 QUERY_UINT (msg, info21.primary_gid, "primaryGroupID"); 3066 QUERY_AFLAGS(msg, info21.acct_flags, " userAccountControl");3088 QUERY_AFLAGS(msg, info21.acct_flags, "msDS-User-Account-Control-Computed"); 3067 3089 info->info21.fields_present = 0x08FFFFFF; 3068 3090 QUERY_LHOURS(msg, info21.logon_hours, "logonHours"); 3069 QUERY_ UINT(msg, info21.bad_password_count, "badPwdCount");3091 QUERY_BPWDCT(msg, info21.bad_password_count, "badPwdCount"); 3070 3092 QUERY_UINT (msg, info21.logon_count, "logonCount"); 3071 3093 if ((info->info21.acct_flags & ACB_PW_EXPIRED) != 0) { … … 3509 3531 3510 3532 if (r->in.info->info26.password_expired > 0) { 3533 NTTIME t = 0; 3511 3534 struct ldb_message_element *set_el; 3512 if (samdb_msg_add_uint64(sam_ctx, mem_ctx, msg, "pwdLastSet", 0) != LDB_SUCCESS) { 3535 if (r->in.info->info26.password_expired 3536 == PASS_DONT_CHANGE_AT_NEXT_LOGON) { 3537 unix_to_nt_time(&t, time(NULL)); 3538 } 3539 if (samdb_msg_add_uint64(sam_ctx, mem_ctx, msg, 3540 "pwdLastSet", t) != LDB_SUCCESS) { 3513 3541 return NT_STATUS_NO_MEMORY; 3514 3542 } … … 3535 3563 ldb_errstring(a_state->sam_ctx))); 3536 3564 3537 /* we really need samdb.c to return NTSTATUS */ 3538 return NT_STATUS_UNSUCCESSFUL; 3565 return dsdb_ldb_err_to_ntstatus(ret); 3539 3566 } 3540 3567 } … … 3557 3584 struct samr_RidWithAttributeArray *array; 3558 3585 int i, count; 3586 char membersidstr[DOM_SID_STR_BUFLEN]; 3559 3587 3560 3588 DCESRV_PULL_HANDLE(h, r->in.user_handle, SAMR_HANDLE_USER); … … 3562 3590 a_state = h->data; 3563 3591 d_state = a_state->domain_state; 3592 3593 dom_sid_string_buf(a_state->account_sid, 3594 membersidstr, sizeof(membersidstr)), 3564 3595 3565 3596 count = samdb_search_domain(a_state->sam_ctx, mem_ctx, 3566 3597 d_state->domain_dn, &res, 3567 3598 attrs, d_state->domain_sid, 3568 "(&(member=%s)(|(grouptype=%d)(grouptype=%d))(objectclass=group))", 3569 ldb_dn_get_linearized(a_state->account_dn), 3599 "(&(member=<SID=%s>)" 3600 "(|(grouptype=%d)(grouptype=%d))" 3601 "(objectclass=group))", 3602 membersidstr, 3570 3603 GTYPE_SECURITY_UNIVERSAL_GROUP, 3571 3604 GTYPE_SECURITY_GLOBAL_GROUP); … … 3666 3699 /* search for all requested objects in all domains. This could 3667 3700 possibly be cached and resumed based on resume_key */ 3668 ret = dsdb_search(d_state->sam_ctx, mem_ctx, &res, NULL,3701 ret = dsdb_search(d_state->sam_ctx, mem_ctx, &res, ldb_get_default_basedn(d_state->sam_ctx), 3669 3702 LDB_SCOPE_SUBTREE, attrs, 0, "%s", filter); 3670 3703 if (ret != LDB_SUCCESS) { … … 3719 3752 objectsid->sub_auths[objectsid->num_auths-1]; 3720 3753 entriesGeneral[count].acct_flags = 3721 samdb_result_acct_flags(d_state->sam_ctx, 3722 mem_ctx, 3723 res->msgs[i], 3724 d_state->domain_dn); 3754 samdb_result_acct_flags(res->msgs[i], NULL); 3725 3755 entriesGeneral[count].account_name.string = 3726 3756 ldb_msg_find_attr_as_string(res->msgs[i], … … 3740 3770 /* No idea why we need to or in ACB_NORMAL here, but this is what Win2k3 seems to do... */ 3741 3771 entriesFull[count].acct_flags = 3742 samdb_result_acct_flags(d_state->sam_ctx, 3743 mem_ctx, 3744 res->msgs[i], 3745 d_state->domain_dn) | ACB_NORMAL; 3772 samdb_result_acct_flags(res->msgs[i], 3773 NULL) | ACB_NORMAL; 3746 3774 entriesFull[count].account_name.string = 3747 3775 ldb_msg_find_attr_as_string(res->msgs[i], … … 3935 3963 for (i=0; i<count; i++) { 3936 3964 struct ldb_message *mod; 3965 int ret; 3937 3966 3938 3967 mod = ldb_msg_new(mem_ctx); … … 3947 3976 return NT_STATUS_NO_MEMORY; 3948 3977 3949 if (ldb_modify(d_state->sam_ctx, mod) != LDB_SUCCESS) 3950 return NT_STATUS_UNSUCCESSFUL; 3951 3978 ret = ldb_modify(d_state->sam_ctx, mod); 3952 3979 talloc_free(mod); 3980 if (ret != LDB_SUCCESS) { 3981 return dsdb_ldb_err_to_ntstatus(ret); 3982 } 3953 3983 } 3954 3984 … … 3990 4020 NTSTATUS status; 3991 4021 3992 r1.in.user_handle = r->in.user_handle; 3993 r1.in.level = r->in.level; 3994 r1.out.info = r->out.info; 4022 r1 = (struct samr_QueryUserInfo) { 4023 .in.user_handle = r->in.user_handle, 4024 .in.level = r->in.level, 4025 .out.info = r->out.info 4026 }; 3995 4027 3996 4028 status = dcesrv_samr_QueryUserInfo(dce_call, mem_ctx, &r1); … … 4288 4320 enum samr_ValidationStatus res; 4289 4321 NTSTATUS status; 4322 enum dcerpc_transport_t transport = 4323 dcerpc_binding_get_transport(dce_call->conn->endpoint->ep_description); 4324 4325 if (transport != NCACN_IP_TCP && transport != NCALRPC) { 4326 DCESRV_FAULT(DCERPC_FAULT_ACCESS_DENIED); 4327 } 4328 4329 if (dce_call->conn->auth_state.auth_level != DCERPC_AUTH_LEVEL_PRIVACY) { 4330 DCESRV_FAULT(DCERPC_FAULT_ACCESS_DENIED); 4331 } 4290 4332 4291 4333 (*r->out.rep) = talloc_zero(mem_ctx, union samr_ValidatePasswordRep); -
vendor/current/source4/rpc_server/samr/dcesrv_samr.h
r740 r988 21 21 22 22 #include "param/param.h" 23 #include "libds/common/roles.h" 23 24 24 25 /* -
vendor/current/source4/rpc_server/samr/samr_password.c
r860 r988 30 30 #include "libcli/auth/libcli_auth.h" 31 31 #include "../lib/util/util_ldb.h" 32 #include "rpc_server/samr/proto.h" 33 #include "auth/auth_sam.h" 32 34 33 35 /* … … 61 63 int ret; 62 64 struct ldb_message **res; 63 const char * const attrs[] = { "objectSid", "dBCSPwd", NULL }; 65 const char * const attrs[] = { "objectSid", "dBCSPwd", 66 "userAccountControl", 67 "msDS-User-Account-Control-Computed", 68 "badPwdCount", "badPasswordTime", 69 NULL }; 64 70 struct samr_Password *lm_pwd; 65 71 DATA_BLOB lm_pwd_blob; … … 67 73 struct samr_Password lm_verifier; 68 74 size_t unicode_pw_len; 75 size_t converted_size = 0; 69 76 70 77 if (pwbuf == NULL) { … … 96 103 mem_ctx, NULL, &res, attrs, 97 104 "(&(sAMAccountName=%s)(objectclass=user))", 98 r->in.account->string);105 ldb_binary_encode_string(mem_ctx, r->in.account->string)); 99 106 if (ret != 1) { 100 107 /* Don't give the game away: (don't allow anonymous users to prove the existance of usernames) */ … … 106 113 status = samdb_result_passwords(mem_ctx, dce_call->conn->dce_ctx->lp_ctx, 107 114 res[0], &lm_pwd, NULL); 108 if (!NT_STATUS_IS_OK(status) || !lm_pwd) { 115 if (!NT_STATUS_IS_OK(status)) { 116 return status; 117 } else if (!lm_pwd) { 109 118 return NT_STATUS_WRONG_PASSWORD; 110 119 } … … 117 126 if (!extract_pw_from_buffer(mem_ctx, pwbuf->data, &new_password)) { 118 127 DEBUG(3,("samr: failed to decode password buffer\n")); 119 return NT_STATUS_WRONG_PASSWORD; 120 } 121 122 if (!convert_string_talloc_convenience(mem_ctx, lpcfg_iconv_convenience(dce_call->conn->dce_ctx->lp_ctx), 128 authsam_update_bad_pwd_count(sam_ctx, res[0], ldb_get_default_basedn(sam_ctx)); 129 return NT_STATUS_WRONG_PASSWORD; 130 } 131 132 if (!convert_string_talloc_handle(mem_ctx, lpcfg_iconv_handle(dce_call->conn->dce_ctx->lp_ctx), 123 133 CH_DOS, CH_UNIX, 124 134 (const char *)new_password.data, 125 135 new_password.length, 126 (void **)&new_pass, NULL, false)) {136 (void **)&new_pass, &converted_size)) { 127 137 DEBUG(3,("samr: failed to convert incoming password buffer to unix charset\n")); 128 return NT_STATUS_WRONG_PASSWORD; 129 } 130 131 if (!convert_string_talloc_convenience(mem_ctx, lpcfg_iconv_convenience(dce_call->conn->dce_ctx->lp_ctx), 138 authsam_update_bad_pwd_count(sam_ctx, res[0], ldb_get_default_basedn(sam_ctx)); 139 return NT_STATUS_WRONG_PASSWORD; 140 } 141 142 if (!convert_string_talloc_handle(mem_ctx, lpcfg_iconv_handle(dce_call->conn->dce_ctx->lp_ctx), 132 143 CH_DOS, CH_UTF16, 133 144 (const char *)new_password.data, 134 145 new_password.length, 135 (void **)&new_unicode_password.data, &unicode_pw_len , false)) {146 (void **)&new_unicode_password.data, &unicode_pw_len)) { 136 147 DEBUG(3,("samr: failed to convert incoming password buffer to UTF16 charset\n")); 148 authsam_update_bad_pwd_count(sam_ctx, res[0], ldb_get_default_basedn(sam_ctx)); 137 149 return NT_STATUS_WRONG_PASSWORD; 138 150 } … … 142 154 E_old_pw_hash(new_lm_hash, lm_pwd->hash, lm_verifier.hash); 143 155 if (memcmp(lm_verifier.hash, r->in.hash->hash, 16) != 0) { 156 authsam_update_bad_pwd_count(sam_ctx, res[0], ldb_get_default_basedn(sam_ctx)); 144 157 return NT_STATUS_WRONG_PASSWORD; 145 158 } … … 198 211 DATA_BLOB new_password; 199 212 struct ldb_context *sam_ctx = NULL; 200 struct ldb_dn *user_dn ;213 struct ldb_dn *user_dn = NULL; 201 214 int ret; 202 215 struct ldb_message **res; 203 const char * const attrs[] = { "unicodePwd", "dBCSPwd", NULL }; 216 const char * const attrs[] = { "unicodePwd", "dBCSPwd", 217 "userAccountControl", 218 "msDS-User-Account-Control-Computed", 219 "badPwdCount", "badPasswordTime", 220 "objectSid", NULL }; 204 221 struct samr_Password *nt_pwd, *lm_pwd; 205 222 DATA_BLOB nt_pwd_blob; … … 233 250 mem_ctx, NULL, &res, attrs, 234 251 "(&(sAMAccountName=%s)(objectclass=user))", 235 r->in.account->string);252 ldb_binary_encode_string(mem_ctx, r->in.account->string)); 236 253 if (ret != 1) { 237 254 /* Don't give the game away: (don't allow anonymous users to prove the existance of usernames) */ … … 283 300 if (lm_pwd && r->in.lm_verifier != NULL) { 284 301 char *new_pass; 285 if (!convert_string_talloc_convenience(mem_ctx, lpcfg_iconv_convenience(dce_call->conn->dce_ctx->lp_ctx), 302 size_t converted_size = 0; 303 304 if (!convert_string_talloc_handle(mem_ctx, lpcfg_iconv_handle(dce_call->conn->dce_ctx->lp_ctx), 286 305 CH_UTF16, CH_UNIX, 287 306 (const char *)new_password.data, 288 307 new_password.length, 289 (void **)&new_pass, NULL, false)) {308 (void **)&new_pass, &converted_size)) { 290 309 E_deshash(new_pass, new_lm_hash); 291 310 E_old_pw_hash(new_nt_hash, lm_pwd->hash, lm_verifier.hash); … … 340 359 341 360 failed: 361 /* Only update the badPwdCount if we found the user */ 362 if (user_dn != NULL && NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) { 363 authsam_update_bad_pwd_count(sam_ctx, res[0], ldb_get_default_basedn(sam_ctx)); 364 } 365 342 366 reject = talloc_zero(mem_ctx, struct userPwdChangeFailureInformation); 343 367 if (reject != NULL) { … … 396 420 nt_status = dcesrv_fetch_session_key(dce_call->conn, &session_key); 397 421 if (!NT_STATUS_IS_OK(nt_status)) { 398 return nt_status; 422 DEBUG(3,("samr: failed to get session key: %s " 423 "=> NT_STATUS_WRONG_PASSWORD\n", 424 nt_errstr(nt_status))); 425 return NT_STATUS_WRONG_PASSWORD; 399 426 } 400 427 … … 435 462 nt_status = dcesrv_fetch_session_key(dce_call->conn, &session_key); 436 463 if (!NT_STATUS_IS_OK(nt_status)) { 437 return nt_status; 464 DEBUG(3,("samr: failed to get session key: %s " 465 "=> NT_STATUS_WRONG_PASSWORD\n", 466 nt_errstr(nt_status))); 467 return NT_STATUS_WRONG_PASSWORD; 438 468 } 439 469 … … 477 507 { 478 508 struct samr_Password *d_lm_pwd_hash = NULL, *d_nt_pwd_hash = NULL; 509 uint8_t random_session_key[16] = { 0, }; 479 510 DATA_BLOB session_key = data_blob(NULL, 0); 480 511 DATA_BLOB in, out; … … 482 513 483 514 nt_status = dcesrv_fetch_session_key(dce_call->conn, &session_key); 515 if (NT_STATUS_EQUAL(nt_status, NT_STATUS_NO_USER_SESSION_KEY)) { 516 DEBUG(3,("samr: failed to get session key: %s " 517 "=> use a random session key\n", 518 nt_errstr(nt_status))); 519 520 /* 521 * Windows just uses a random key 522 */ 523 generate_random_buffer(random_session_key, 524 sizeof(random_session_key)); 525 session_key = data_blob_const(random_session_key, 526 sizeof(random_session_key)); 527 nt_status = NT_STATUS_OK; 528 } 484 529 if (!NT_STATUS_IS_OK(nt_status)) { 485 530 return nt_status; -
vendor/current/source4/rpc_server/service_rpc.c
r740 r988 40 40 #include "smbd/process_model.h" 41 41 42 NTSTATUS server_service_rpc_init(void); 42 43 43 44 /* … … 72 73 73 74 for (e=dce_ctx->endpoint_list;e;e=e->next) { 75 enum dcerpc_transport_t transport = 76 dcerpc_binding_get_transport(e->ep_description); 77 78 if (transport == NCACN_HTTP) { 79 /* 80 * We don't support ncacn_http yet 81 */ 82 continue; 83 } 84 74 85 status = dcesrv_add_ep(dce_ctx, task->lp_ctx, e, task->event_ctx, model_ops); 75 86 if (!NT_STATUS_IS_OK(status)) goto failed; 76 87 } 77 88 89 irpc_add_name(task->msg_ctx, "rpc_server"); 78 90 return; 79 91 failed: -
vendor/current/source4/rpc_server/spoolss/dcesrv_spoolss.c
r740 r988 221 221 222 222 status = ntptr_init_context(dce_call->context, dce_call->conn->event_ctx, dce_call->conn->dce_ctx->lp_ctx, 223 lpcfg_ntptr_providor(dce_call->conn->dce_ctx->lp_ctx), &ntptr);223 "simple_ldb", &ntptr); 224 224 NT_STATUS_NOT_OK_RETURN(status); 225 225 … … 270 270 r2->in.devmode_ctr = r->in.devmode_ctr; 271 271 r2->in.access_mask = r->in.access_mask; 272 r2->in.level = 1; 273 r2->in.userlevel.level1 = NULL; 274 272 r2->in.userlevel_ctr.level = 1; 273 r2->in.userlevel_ctr.user_info.level1 = NULL; 275 274 r2->out.handle = r->out.handle; 276 275 … … 1158 1157 { 1159 1158 struct dcerpc_pipe *p; 1159 char *binding_string; 1160 1160 struct dcerpc_binding *binding; 1161 1161 NTSTATUS status; … … 1169 1169 * TODO: for now just open a connection to the client and drop it again 1170 1170 * to keep the w2k3 PrintServer 1171 * happy to allow to open the Add Printer GUI1171 * happy to allow one to open the Add Printer GUI 1172 1172 * and the torture suite passing 1173 1173 */ 1174 1174 1175 binding = talloc_zero(mem_ctx, struct dcerpc_binding); 1176 1177 binding->transport = NCACN_NP; 1178 if (strncmp(r->in.local_machine, "\\\\", 2)) 1175 if (strncmp(r->in.local_machine, "\\\\", 2)) { 1179 1176 return WERR_INVALID_COMPUTERNAME; 1180 binding->host = r->in.local_machine+2; 1177 } 1178 1179 binding_string = talloc_asprintf(mem_ctx, "ncacn_np:%s", 1180 r->in.local_machine+2); 1181 if (binding_string == NULL) { 1182 return WERR_NOMEM; 1183 } 1184 1185 status = dcerpc_parse_binding(mem_ctx, binding_string, &binding); 1186 if (!NT_STATUS_IS_OK(status)) { 1187 return ntstatus_to_werror(status); 1188 } 1181 1189 1182 1190 creds = cli_credentials_init_anon(mem_ctx); /* FIXME: Use machine credentials instead ? */ … … 1594 1602 1595 1603 /* 1596 spoolss_ 611597 */ 1598 static WERROR dcesrv_spoolss_ 61(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,1599 struct spoolss_ 61*r)1604 spoolss_RpcSendRecvBidiData 1605 */ 1606 static WERROR dcesrv_spoolss_RpcSendRecvBidiData(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, 1607 struct spoolss_RpcSendRecvBidiData *r) 1600 1608 { 1601 1609 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR); … … 1723 1731 1724 1732 1733 /* 1734 spoolss_RpcGetJobNamedPropertyValue 1735 */ 1736 static WERROR dcesrv_spoolss_RpcGetJobNamedPropertyValue(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, 1737 struct spoolss_RpcGetJobNamedPropertyValue *r) 1738 { 1739 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR); 1740 } 1741 1742 1743 /* 1744 spoolss_RpcSetJobNamedProperty 1745 */ 1746 static WERROR dcesrv_spoolss_RpcSetJobNamedProperty(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, 1747 struct spoolss_RpcSetJobNamedProperty *r) 1748 { 1749 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR); 1750 } 1751 1752 1753 /* 1754 spoolss_RpcDeleteJobNamedProperty 1755 */ 1756 static WERROR dcesrv_spoolss_RpcDeleteJobNamedProperty(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, 1757 struct spoolss_RpcDeleteJobNamedProperty *r) 1758 { 1759 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR); 1760 } 1761 1762 /* 1763 spoolss_RpcEnumJobNamedProperties 1764 */ 1765 static WERROR dcesrv_spoolss_RpcEnumJobNamedProperties(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, 1766 struct spoolss_RpcEnumJobNamedProperties *r) 1767 { 1768 DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR); 1769 } 1725 1770 1726 1771 /* include the generated boilerplate */ -
vendor/current/source4/rpc_server/srvsvc/dcesrv_srvsvc.c
r740 r988 623 623 W_ERROR_HAVE_NO_MEMORY(info->info1->name); 624 624 info->info1->type = dcesrv_common_get_share_type(mem_ctx, dce_ctx, scfg); 625 info->info1->comment = talloc_strdup(mem_ctx, share_string_option(scfg, SHARE_COMMENT, ""));625 info->info1->comment = share_string_option(mem_ctx, scfg, SHARE_COMMENT, ""); 626 626 W_ERROR_HAVE_NO_MEMORY(info->info1->comment); 627 627 … … 633 633 W_ERROR_HAVE_NO_MEMORY(info->info2->name); 634 634 info->info2->type = dcesrv_common_get_share_type(mem_ctx, dce_ctx, scfg); 635 info->info2->comment = talloc_strdup(mem_ctx, share_string_option(scfg, SHARE_COMMENT, ""));635 info->info2->comment = share_string_option(mem_ctx, scfg, SHARE_COMMENT, ""); 636 636 W_ERROR_HAVE_NO_MEMORY(info->info2->comment); 637 637 info->info2->permissions = dcesrv_common_get_share_permissions(mem_ctx, dce_ctx, scfg); … … 640 640 info->info2->path = dcesrv_common_get_share_path(mem_ctx, dce_ctx, scfg); 641 641 W_ERROR_HAVE_NO_MEMORY(info->info2->path); 642 info->info2->password = talloc_strdup(mem_ctx, share_string_option(scfg, SHARE_PASSWORD, NULL));642 info->info2->password = share_string_option(mem_ctx, scfg, SHARE_PASSWORD, NULL); 643 643 644 644 return WERR_OK; … … 649 649 W_ERROR_HAVE_NO_MEMORY(info->info501->name); 650 650 info->info501->type = dcesrv_common_get_share_type(mem_ctx, dce_ctx, scfg); 651 info->info501->comment = talloc_strdup(mem_ctx, share_string_option(scfg, SHARE_COMMENT, ""));651 info->info501->comment = share_string_option(mem_ctx, scfg, SHARE_COMMENT, ""); 652 652 W_ERROR_HAVE_NO_MEMORY(info->info501->comment); 653 653 info->info501->csc_policy = share_int_option(scfg, SHARE_CSC_POLICY, SHARE_CSC_POLICY_DEFAULT); … … 660 660 W_ERROR_HAVE_NO_MEMORY(info->info502->name); 661 661 info->info502->type = dcesrv_common_get_share_type(mem_ctx, dce_ctx, scfg); 662 info->info502->comment = talloc_strdup(mem_ctx, share_string_option(scfg, SHARE_COMMENT, ""));662 info->info502->comment = share_string_option(mem_ctx, scfg, SHARE_COMMENT, ""); 663 663 W_ERROR_HAVE_NO_MEMORY(info->info502->comment); 664 664 info->info502->permissions = dcesrv_common_get_share_permissions(mem_ctx, dce_ctx, scfg); … … 667 667 info->info502->path = dcesrv_common_get_share_path(mem_ctx, dce_ctx, scfg); 668 668 W_ERROR_HAVE_NO_MEMORY(info->info502->path); 669 info->info502->password = talloc_strdup(mem_ctx, share_string_option(scfg, SHARE_PASSWORD, NULL));669 info->info502->password = share_string_option(mem_ctx, scfg, SHARE_PASSWORD, NULL); 670 670 info->info502->sd_buf.sd = dcesrv_common_get_security_descriptor(mem_ctx, dce_ctx, scfg); 671 671 … … 1397 1397 return ntstatus_to_werror(nterr); 1398 1398 } 1399 path = share_string_option( scfg, SHARE_PATH, NULL);1399 path = share_string_option(mem_ctx, scfg, SHARE_PATH, NULL); 1400 1400 if (!path) continue; 1401 1401 1402 if (strcmp(device, path) == 0) { 1403 type = share_string_option( scfg, SHARE_TYPE, NULL);1402 if (strcmp(device, path) == 0) { 1403 type = share_string_option(mem_ctx, scfg, SHARE_TYPE, NULL); 1404 1404 if (!type) continue; 1405 1405 … … 1465 1465 info101->version_minor = server_info->version_minor; 1466 1466 info101->server_type = dcesrv_common_get_server_type(mem_ctx, dce_call->event_ctx, dce_ctx); 1467 info101->comment = talloc_strdup(mem_ctx, lpcfg_serverstring(dce_ctx->lp_ctx));1467 info101->comment = lpcfg_server_string(dce_ctx->lp_ctx, mem_ctx); 1468 1468 W_ERROR_HAVE_NO_MEMORY(info101->comment); 1469 1469 … … 1485 1485 info102->version_minor = server_info->version_minor; 1486 1486 info102->server_type = dcesrv_common_get_server_type(mem_ctx, dce_call->event_ctx, dce_ctx); 1487 info102->comment = talloc_strdup(mem_ctx, lpcfg_serverstring(dce_ctx->lp_ctx));1487 info102->comment = lpcfg_server_string(dce_ctx->lp_ctx, mem_ctx); 1488 1488 W_ERROR_HAVE_NO_MEMORY(info102->comment); 1489 1489 -
vendor/current/source4/rpc_server/srvsvc/srvsvc_ntvfs.c
r740 r988 23 23 #include "rpc_server/dcerpc_server.h" 24 24 #include "param/param.h" 25 #include "rpc_server/srvsvc/proto.h" 25 26 26 27 struct srvsvc_ntvfs_ctx { … … 45 46 struct share_context *sctx; 46 47 struct share_config *scfg; 47 c onst char *sharetype;48 char *sharetype; 48 49 union smb_tcon tcon; 49 50 const struct tsocket_address *local_address; … … 71 72 72 73 /* work out what sort of connection this is */ 73 sharetype = share_string_option( scfg, SHARE_TYPE, SHARE_TYPE_DEFAULT);74 sharetype = share_string_option(mem_ctx, scfg, SHARE_TYPE, SHARE_TYPE_DEFAULT); 74 75 if (sharetype && strcmp(sharetype, "IPC") == 0) { 75 76 type = NTVFS_IPC; … … 79 80 type = NTVFS_DISK; 80 81 } 82 83 TALLOC_FREE(sharetype); 81 84 82 85 c = talloc(mem_ctx, struct srvsvc_ntvfs_ctx); -
vendor/current/source4/rpc_server/unixinfo/dcesrv_unixinfo.c
r740 r988 26 26 #include "system/passwd.h" 27 27 28 static NTSTATUS dcerpc_unixinfo_bind(struct dcesrv_call_state *dce_call,29 const struct dcesrv_interface *iface)30 {31 struct wbc_context *wbc_ctx;32 33 wbc_ctx = wbc_init(dce_call->context, dce_call->msg_ctx,34 dce_call->event_ctx);35 NT_STATUS_HAVE_NO_MEMORY(wbc_ctx);36 37 dce_call->context->private_data = wbc_ctx;38 39 return NT_STATUS_OK;40 }41 42 #define DCESRV_INTERFACE_UNIXINFO_BIND dcerpc_unixinfo_bind43 44 28 static NTSTATUS dcesrv_unixinfo_SidToUid(struct dcesrv_call_state *dce_call, 45 29 TALLOC_CTX *mem_ctx, … … 47 31 { 48 32 NTSTATUS status; 49 struct wbc_context *wbc_ctx = talloc_get_type_abort(50 dce_call->context->private_data,51 struct wbc_context);52 33 struct id_map *ids; 53 struct composite_context *ctx;54 34 55 35 DEBUG(5, ("dcesrv_unixinfo_SidToUid called\n")); … … 61 41 ids->status = ID_UNKNOWN; 62 42 ZERO_STRUCT(ids->xid); 63 ctx = wbc_sids_to_xids_send(wbc_ctx, ids, 1, ids); 64 NT_STATUS_HAVE_NO_MEMORY(ctx); 65 66 status = wbc_sids_to_xids_recv(ctx, &ids); 43 status = wbc_sids_to_xids(dce_call->event_ctx, ids, 1); 67 44 NT_STATUS_NOT_OK_RETURN(status); 68 45 … … 80 57 struct unixinfo_UidToSid *r) 81 58 { 82 struct wbc_context *wbc_ctx = talloc_get_type_abort(83 dce_call->context->private_data,84 struct wbc_context);85 59 struct id_map *ids; 86 struct composite_context *ctx;87 60 uint32_t uid; 88 61 NTSTATUS status; … … 105 78 ids->xid.type = ID_TYPE_UID; 106 79 107 ctx = wbc_xids_to_sids_send(wbc_ctx, ids, 1, ids); 108 NT_STATUS_HAVE_NO_MEMORY(ctx); 109 110 status = wbc_xids_to_sids_recv(ctx, &ids); 80 status = wbc_xids_to_sids(dce_call->event_ctx, ids, 1); 111 81 NT_STATUS_NOT_OK_RETURN(status); 112 82 … … 120 90 { 121 91 NTSTATUS status; 122 struct wbc_context *wbc_ctx = talloc_get_type_abort(123 dce_call->context->private_data,124 struct wbc_context);125 92 struct id_map *ids; 126 struct composite_context *ctx;127 93 128 94 DEBUG(5, ("dcesrv_unixinfo_SidToGid called\n")); … … 134 100 ids->status = ID_UNKNOWN; 135 101 ZERO_STRUCT(ids->xid); 136 ctx = wbc_sids_to_xids_send(wbc_ctx, ids, 1, ids); 137 NT_STATUS_HAVE_NO_MEMORY(ctx); 138 139 status = wbc_sids_to_xids_recv(ctx, &ids); 102 status = wbc_sids_to_xids(dce_call->event_ctx, ids, 1); 140 103 NT_STATUS_NOT_OK_RETURN(status); 141 104 … … 153 116 struct unixinfo_GidToSid *r) 154 117 { 155 struct wbc_context *wbc_ctx = talloc_get_type_abort(156 dce_call->context->private_data,157 struct wbc_context);158 118 struct id_map *ids; 159 struct composite_context *ctx;160 119 uint32_t gid; 161 120 NTSTATUS status; … … 178 137 ids->xid.type = ID_TYPE_GID; 179 138 180 ctx = wbc_xids_to_sids_send(wbc_ctx, ids, 1, ids); 181 NT_STATUS_HAVE_NO_MEMORY(ctx); 182 183 status = wbc_xids_to_sids_recv(ctx, &ids); 139 status = wbc_xids_to_sids(dce_call->event_ctx, ids, 1); 184 140 NT_STATUS_NOT_OK_RETURN(status); 185 141 -
vendor/current/source4/rpc_server/winreg/rpc_winreg.c
r740 r988 43 43 if (!W_ERROR_IS_OK(err)) { 44 44 DEBUG(0, ("Error opening registry: %s\n", win_errstr(err))); 45 return NT_STATUS_UNSUCCESSFUL;45 return werror_to_ntstatus(err); 46 46 } 47 47 -
vendor/current/source4/rpc_server/wscript_build
r740 r988 4 4 source='common/server_info.c common/share_info.c', 5 5 autoproto='common/share.h', 6 deps='ldb' 6 deps='ldb', 7 enabled=bld.AD_DC_BUILD_IS_ENABLED() 7 8 ) 8 9 9 10 bld.SAMBA_SUBSYSTEM('DCERPC_COMMON', 10 source='common/forward.c common/reply.c dcesrv_auth.c ',11 source='common/forward.c common/reply.c dcesrv_auth.c common/loadparm.c', 11 12 autoproto='common/proto.h', 12 deps='ldb DCERPC_SHARE samba_server_gensec' 13 deps='ldb DCERPC_SHARE samba_server_gensec', 14 enabled=bld.AD_DC_BUILD_IS_ENABLED() 13 15 ) 14 16 17 bld.SAMBA_LIBRARY('dcerpc_server', 18 source='dcerpc_server.c dcesrv_mgmt.c handles.c', 19 pc_files='dcerpc_server.pc', 20 deps='LIBCLI_AUTH ndr samba_server_gensec dcerpc_remote service auth', 21 public_deps='dcerpc', 22 autoproto='dcerpc_server_proto.h', 23 public_headers='dcerpc_server.h', 24 vnum='0.0.1', 25 enabled=bld.AD_DC_BUILD_IS_ENABLED() 26 ) 15 27 16 28 bld.SAMBA_MODULE('dcerpc_rpcecho', … … 68 80 subsystem='dcerpc_server', 69 81 init_function='dcerpc_server_samr_init', 70 deps='samdb DCERPC_COMMON ndr-standard '82 deps='samdb DCERPC_COMMON ndr-standard auth4_sam' 71 83 ) 72 84 … … 85 97 subsystem='dcerpc_server', 86 98 init_function='dcerpc_server_netlogon_init', 87 deps='DCERPC_COMMON RPC_NDR_IRPC COMMON_SCHANNEL ndr-standard auth4_sam samba-hostconfig CLDAPD'99 deps='DCERPC_COMMON RPC_NDR_IRPC COMMON_SCHANNEL ndr-standard auth4_sam samba-hostconfig DSDB_MODULE_HELPERS' 88 100 ) 89 101 … … 94 106 subsystem='dcerpc_server', 95 107 init_function='dcerpc_server_lsa_init', 96 deps='samdb DCERPC_COMMON ndr-standard LIBCLI_AUTH NDR_DSSETUP com_err s ecurity kdc-policy'108 deps='samdb DCERPC_COMMON ndr-standard LIBCLI_AUTH NDR_DSSETUP com_err samba-security UTIL_LSARPC' 97 109 ) 98 110 99 111 100 bld.SAMBA_MODULE('dcerpc_backupkey', 101 source='backupkey/dcesrv_backupkey.c ', 102 autoproto='backupkey/proto.h', 103 subsystem='dcerpc_server', 104 init_function='dcerpc_server_backupkey_init', 105 deps='samdb DCERPC_COMMON NDR_BACKUPKEY RPC_NDR_BACKUPKEY' 106 ) 112 if bld.CONFIG_SET('HAVE_GNUTLS_3_4_7'): 113 bld.SAMBA_MODULE('dcerpc_backupkey', 114 source='backupkey/dcesrv_backupkey.c ', 115 autoproto='backupkey/proto.h', 116 subsystem='dcerpc_server', 117 init_function='dcerpc_server_backupkey_init', 118 deps='samdb DCERPC_COMMON NDR_BACKUPKEY RPC_NDR_BACKUPKEY gnutls', 119 ) 120 else: 121 bld.SAMBA_MODULE('dcerpc_backupkey', 122 source='backupkey/dcesrv_backupkey_heimdal.c ', 123 autoproto='backupkey/proto.h', 124 subsystem='dcerpc_server', 125 init_function='dcerpc_server_backupkey_init', 126 deps='samdb DCERPC_COMMON NDR_BACKUPKEY RPC_NDR_BACKUPKEY krb5 hx509 hcrypto gnutls gcrypt', 127 ) 107 128 108 129 … … 120 141 subsystem='dcerpc_server', 121 142 init_function='dcerpc_server_drsuapi_init', 122 deps='samdb DCERPC_COMMON NDR_DRSUAPI s ecurity'143 deps='samdb DCERPC_COMMON NDR_DRSUAPI samba-security' 123 144 ) 124 145 … … 138 159 ) 139 160 140 bld.SAMBA_LIBRARY('dcerpc_server', 141 source='dcerpc_server.c dcesrv_mgmt.c handles.c', 142 pc_files='dcerpc_server.pc', 143 deps='LIBCLI_AUTH ndr samba_server_gensec dcerpc_remote service', 144 public_deps='dcerpc', 145 autoproto='dcerpc_server_proto.h', 146 public_headers='dcerpc_server.h', 147 vnum='0.0.1' 148 ) 161 bld.SAMBA_MODULE('dcerpc_dnsserver', 162 source='dnsserver/dcerpc_dnsserver.c dnsserver/dnsutils.c dnsserver/dnsdata.c dnsserver/dnsdb.c', 163 subsystem='dcerpc_server', 164 init_function='dcerpc_server_dnsserver_init', 165 deps='DCERPC_COMMON' 166 ) 167 149 168 150 169 bld.SAMBA_MODULE('service_dcerpc',
Note:
See TracChangeset
for help on using the changeset viewer.