Ignore:
Timestamp:
Nov 24, 2016, 1:14:11 PM (9 years ago)
Author:
Silvan Scherrer
Message:

Samba Server: update vendor to version 4.4.3

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  
    55
    66   Copyright (C) Matthieu Patou <mat@samba.org> 2010
     7   Copyright (C) Andreas Schneider <asn@samba.org> 2015
    78
    89   This program is free software; you can redistribute it and/or modify
     
    2930#include "param/param.h"
    3031#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
    3434#include "../lib/tsocket/tsocket.h"
    3535#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)
     46static 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}
    4551
    4652static NTSTATUS set_lsa_secret(TALLOC_CTX *mem_ctx,
    4753                               struct ldb_context *ldb,
    4854                               const char *name,
    49                                const DATA_BLOB *secret)
     55                               const DATA_BLOB *lsa_secret)
    5056{
    5157        struct ldb_message *msg;
     
    134140                return NT_STATUS_NO_MEMORY;
    135141        }
    136         val.data = secret->data;
    137         val.length = secret->length;
     142        val.data = lsa_secret->data;
     143        val.length = lsa_secret->length;
    138144        ret = ldb_msg_add_value(msg, "currentValue", &val, NULL);
    139145        if (ret != LDB_SUCCESS) {
     
    169175                               struct ldb_context *ldb,
    170176                               const char *name,
    171                                DATA_BLOB *secret)
     177                               DATA_BLOB *lsa_secret)
    172178{
    173179        TALLOC_CTX *tmp_mem;
     
    183189        int ret;
    184190
    185         secret->data = NULL;
    186         secret->length = 0;
     191        lsa_secret->data = NULL;
     192        lsa_secret->length = 0;
    187193
    188194        domain_dn = ldb_get_default_basedn(ldb);
     
    206212                           ldb_binary_encode_string(tmp_mem, name));
    207213
    208         if (ret != LDB_SUCCESS || res->count == 0) {
     214        if (ret != LDB_SUCCESS) {
    209215                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);
    216220                return NT_STATUS_RESOURCE_NAME_NOT_FOUND;
    217221        }
    218 
    219222        if (res->count > 1) {
    220223                DEBUG(2, ("Secret %s collision\n", name));
     
    229232                 * The most common case is a RODC
    230233                 */
     234                *lsa_secret = data_blob_null;
    231235                talloc_free(tmp_mem);
    232                 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
     236                return NT_STATUS_OK;
    233237        }
    234238
    235239        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;
    238242
    239243        talloc_free(tmp_mem);
     
    241245}
    242246
    243 static DATA_BLOB *reverse_and_get_blob(TALLOC_CTX *mem_ctx, BIGNUM *bn)
     247static int reverse_and_get_bignum(TALLOC_CTX *mem_ctx,
     248                                  DATA_BLOB blob,
     249                                  gnutls_datum_t *datum)
    244250{
    245         DATA_BLOB blob;
    246         DATA_BLOB *rev = talloc(mem_ctx, DATA_BLOB);
    247251        uint32_t i;
    248252
    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;
    291264}
    292265
    293266static NTSTATUS get_pk_from_raw_keypair_params(TALLOC_CTX *ctx,
    294267                                struct bkrp_exported_RSA_key_pair *keypair,
    295                                 hx509_private_key *pk)
     268                                gnutls_privkey_t *pk)
    296269{
    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));
    305315                return NT_STATUS_INTERNAL_ERROR;
    306316        }
    307317
    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
    371353        return NT_STATUS_OK;
    372354}
     
    377359                                          uint8_t *access_check,
    378360                                          uint32_t access_check_len,
    379                                           struct dom_sid **access_sid)
     361                                          struct auth_session_info *session_info)
    380362{
    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;
    385365        DATA_BLOB blob_us;
    386         uint32_t key_len;
    387         uint32_t iv_len;
    388         int res;
    389366        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
    396374        switch (version) {
    397375        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;
    401377                break;
    402 
    403378        case 3:
    404                 key_len = 32;
    405                 iv_len = 16;
    406                 alg =hx509_crypto_aes256_cbc();
     379                cipher_algo = GNUTLS_CIPHER_AES_256_CBC;
    407380                break;
    408 
    409381        default:
    410382                return WERR_INVALID_DATA;
    411383        }
    412384
    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) {
    420394                return WERR_INVALID_DATA;
    421395        }
    422396
    423         res = 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));
    430404                return WERR_INVALID_DATA;
    431405        }
    432406
    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));
    442416                return WERR_INVALID_DATA;
    443417        }
    444418
    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        {
    451422                uint32_t hash_size = 20;
    452423                uint8_t hash[hash_size];
    453                 struct sha sctx;
     424                gnutls_hash_hd_t dig_ctx;
    454425                struct bkrp_access_check_v2 uncrypted_accesscheckv2;
    455426
     
    458429                if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
    459430                        /* Unable to unmarshall */
    460                         der_free_octet_string(&access_check_os);
    461431                        return WERR_INVALID_DATA;
    462432                }
    463433                if (uncrypted_accesscheckv2.magic != 0x1) {
    464434                        /* wrong magic */
    465                         der_free_octet_string(&access_check_os);
    466435                        return WERR_INVALID_DATA;
    467436                }
    468437
    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);
    473443                /*
    474444                 * We free it after the sha1 calculation because blob.data
     
    480450                        return WERR_INVALID_DATA;
    481451                }
    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        {
    490457                uint32_t hash_size = 64;
    491458                uint8_t hash[hash_size];
    492                 struct hc_sha512state sctx;
     459                gnutls_hash_hd_t dig_ctx;
    493460                struct bkrp_access_check_v3 uncrypted_accesscheckv3;
    494461
     
    497464                if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
    498465                        /* Unable to unmarshall */
    499                         der_free_octet_string(&access_check_os);
    500466                        return WERR_INVALID_DATA;
    501467                }
    502468                if (uncrypted_accesscheckv3.magic != 0x1) {
    503469                        /* wrong magic */
    504                         der_free_octet_string(&access_check_os);
    505470                        return WERR_INVALID_DATA;
    506471                }
    507472
    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
    512479                /*
    513480                 * We free it after the sha1 calculation because blob.data
     
    519486                        return WERR_INVALID_DATA;
    520487                }
    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;
    530502}
    531503
    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 */
     521static 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)
    536525{
    537526        struct bkrp_client_side_wrapped uncrypt_request;
     
    540529        char *guid_string;
    541530        char *cert_secret_name;
    542         DATA_BLOB secret;
    543         DATA_BLOB *uncrypted;
     531        DATA_BLOB lsa_secret;
     532        DATA_BLOB *uncrypted_data = NULL;
    544533        NTSTATUS status;
     534        uint32_t requested_version;
    545535
    546536        blob.data = r->in.data_in;
    547537        blob.length = r->in.data_in_len;
    548538
    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;
    551552        }
    552553
     
    557558        }
    558559
    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));
    564563                return WERR_INVALID_PARAMETER;
    565564        }
     
    580579                                ldb_ctx,
    581580                                cert_secret_name,
    582                                 &secret);
     581                                &lsa_secret);
    583582        if (!NT_STATUS_IS_OK(status)) {
    584583                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 {
    595589                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;
    603594                DATA_BLOB blob_us;
    604595                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);
    607599                if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
    608600                        DEBUG(2, ("Unable to parse the ndr encoded cert in key %s\n", cert_secret_name));
     
    610602                }
    611603
    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);
    613607                if (!NT_STATUS_IS_OK(status)) {
    614608                        return WERR_INTERNAL_ERROR;
     
    618612                                                    uncrypt_request.encrypted_secret_len);
    619613                if (reversed_secret.data == NULL) {
    620                         hx509_private_key_free(&pk);
     614                        gnutls_privkey_deinit(privkey);
    621615                        return WERR_NOMEM;
    622616                }
     
    628622                        reversed[i] = uncrypt[uncrypt_request.encrypted_secret_len - 1 - i];
    629623                }
    630                 reversed_secret.length = uncrypt_request.encrypted_secret_len;
     624                reversed_secret.size = uncrypt_request.encrypted_secret_len;
    631625
    632626                /*
     
    634628                 * we have the private key ...
    635629                 */
    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) {
    643636                        /* We are not able to decrypt the secret, looks like something is wrong */
    644                         return WERR_INVALID_DATA;
     637                        return WERR_INVALID_PARAMETER;
    645638                }
    646639                blob_us.data = uncrypted_secret.data;
    647                 blob_us.length = uncrypted_secret.length;
     640                blob_us.length = uncrypted_secret.size;
    648641
    649642                if (uncrypt_request.version == 2) {
     
    652645                        ndr_err = ndr_pull_struct_blob(&blob_us, mem_ctx, &uncrypted_secretv2,
    653646                                        (ndr_pull_flags_fn_t)ndr_pull_bkrp_encrypted_secret_v2);
    654                         der_free_octet_string(&uncrypted_secret);
     647                        gnutls_free(uncrypted_secret.data);
    655648                        if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
    656649                                /* Unable to unmarshall */
     
    666659                                                           uncrypt_request.access_check,
    667660                                                           uncrypt_request.access_check_len,
    668                                                            &access_sid);
     661                                                           dce_call->conn->auth_state.session_info);
    669662                        if (!W_ERROR_IS_OK(werr)) {
    670663                                return werr;
    671664                        }
    672                         uncrypted = talloc(mem_ctx, DATA_BLOB);
    673                         if (uncrypted == NULL) {
     665                        uncrypted_data = talloc(mem_ctx, DATA_BLOB);
     666                        if (uncrypted_data == NULL) {
    674667                                return WERR_INVALID_DATA;
    675668                        }
    676669
    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;
    679672                }
    680673                if (uncrypt_request.version == 3) {
     
    683676                        ndr_err = ndr_pull_struct_blob(&blob_us, mem_ctx, &uncrypted_secretv3,
    684677                                        (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);
    687679                        if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
    688680                                /* Unable to unmarshall */
     
    697689                        }
    698690
     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
    699700                        werr = get_and_verify_access_check(mem_ctx, 3,
    700701                                                           uncrypted_secretv3.payload_key,
    701702                                                           uncrypt_request.access_check,
    702703                                                           uncrypt_request.access_check_len,
    703                                                            &access_sid);
     704                                                           dce_call->conn->auth_state.session_info);
    704705                        if (!W_ERROR_IS_OK(werr)) {
    705706                                return werr;
    706707                        }
    707708
    708                         uncrypted = talloc(mem_ctx, DATA_BLOB);
    709                         if (uncrypted == NULL) {
     709                        uncrypted_data = talloc(mem_ctx, DATA_BLOB);
     710                        if (uncrypted_data == NULL) {
    710711                                return WERR_INVALID_DATA;
    711712                        }
    712713
    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;
    722716                }
    723717
     
    730724        }
    731725
    732         if (uncrypted->data == NULL) {
     726        if (uncrypted_data->data == NULL) {
    733727                return WERR_INVALID_DATA;
    734728        }
     
    739733         * work just prepending 4 bytes
    740734         */
    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);
    742736        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;
    745739
    746740        return WERR_OK;
    747741}
    748742
    749 static WERROR create_heimdal_rsa_key(TALLOC_CTX *ctx, hx509_context *hctx,
    750                                      hx509_private_key *pk, RSA **_rsa)
     743static DATA_BLOB *reverse_and_get_blob(TALLOC_CTX *mem_ctx,
     744                                       gnutls_datum_t *datum)
    751745{
    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
     772static WERROR create_privkey_rsa(gnutls_privkey_t *pk)
     773{
    757774        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));
    763783                return WERR_INTERNAL_ERROR;
    764784        }
    765785
    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);
    772794                return WERR_INTERNAL_ERROR;
    773795        }
    774796
    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);
    779802                return WERR_INTERNAL_ERROR;
    780803        }
    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);
    786812                return WERR_INTERNAL_ERROR;
    787813        }
    788814
    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
    816817        return WERR_OK;
    817818}
    818819
    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)
     820static 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)
    822826{
    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;
    908981
    909982        return WERR_OK;
    910983}
    911984
    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 */
     986static 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)
    914990{
    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;
    978996        DATA_BLOB blob;
    979997        DATA_BLOB blobkeypair;
    980998        DATA_BLOB *tmp;
    981         int ret;
    982999        bool ok = true;
    9831000        struct GUID guid = GUID_random();
     
    9861003        struct bkrp_exported_RSA_key_pair keypair;
    9871004        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;
    9891007
    9901008        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);
    9991015        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);
    10031017                return WERR_INVALID_DATA;
    10041018        }
    10051019
    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);
    10101028                return WERR_INVALID_DATA;
    10111029        }
    10121030
    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);
    10181037                return WERR_INVALID_DATA;
    10191038        }
    10201039
    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        }
    10231062
    10241063        /*
     
    10271066         * so we reverse the buffer to make it work
    10281067         */
    1029         tmp = reverse_and_get_blob(ctx, rsa->e);
     1068        tmp = reverse_and_get_blob(mem_ctx, &e);
    10301069        if (tmp == NULL) {
    10311070                ok = false;
    10321071        } else {
     1072                SMB_ASSERT(tmp->length <= 4);
    10331073                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);
    10521077        if (tmp == NULL) {
    10531078                ok = false;
     
    10561081        }
    10571082
    1058         tmp = reverse_and_get_blob(ctx,rsa->n);
     1083        tmp = reverse_and_get_blob(mem_ctx, &m);
    10591084        if (tmp == NULL) {
    10601085                ok = false;
     
    10631088        }
    10641089
    1065         tmp = reverse_and_get_blob(ctx,rsa->p);
     1090        tmp = reverse_and_get_blob(mem_ctx, &p);
    10661091        if (tmp == NULL) {
    10671092                ok = false;
     
    10701095        }
    10711096
    1072         tmp = reverse_and_get_blob(ctx,rsa->q);
     1097        tmp = reverse_and_get_blob(mem_ctx, &q);
    10731098        if (tmp == NULL) {
    10741099                ok = false;
     
    10771102        }
    10781103
    1079         tmp = reverse_and_get_blob(ctx,rsa->dmp1);
     1104        tmp = reverse_and_get_blob(mem_ctx, &e1);
    10801105        if (tmp == NULL) {
    10811106                ok = false;
     
    10841109        }
    10851110
    1086         tmp = reverse_and_get_blob(ctx,rsa->dmq1);
     1111        tmp = reverse_and_get_blob(mem_ctx, &e2);
    10871112        if (tmp == NULL) {
    10881113                ok = false;
     
    10911116        }
    10921117
    1093         tmp = reverse_and_get_blob(ctx,rsa->iqmp);
     1118        tmp = reverse_and_get_blob(mem_ctx, &u);
    10941119        if (tmp == NULL) {
    10951120                ok = false;
     
    11001125        /* One of the keypair allocation was wrong */
    11011126        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);
    11071128                return WERR_INVALID_DATA;
    11081129        }
     1130
    11091131        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);
    11111137        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);
    11171138                return WERR_INVALID_DATA;
    11181139        }
    11191140
    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));
    11211142        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);
    11271143                return WERR_OUTOFMEMORY;
    11281144        }
    11291145
    1130         status = set_lsa_secret(ctx, ldb_ctx, secret_name, &blobkeypair);
     1146        status = set_lsa_secret(mem_ctx, ldb_ctx, secret_name, &blobkeypair);
    11311147        if (!NT_STATUS_IS_OK(status)) {
    11321148                DEBUG(2, ("Failed to save the secret %s\n", secret_name));
     
    11341150        talloc_free(secret_name);
    11351151
    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);
    11381154        if (!NT_STATUS_IS_OK(status)) {
    11391155                DEBUG(2, ("Failed to save the secret BCKUPKEY_PREFERRED\n"));
    11401156        }
    11411157
    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);
    11471158        return WERR_OK;
    11481159}
    11491160
    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)
     1161static 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)
    11521163{
    11531164        struct GUID guid;
    11541165        char *guid_string;
    1155         DATA_BLOB secret;
     1166        DATA_BLOB lsa_secret;
    11561167        enum ndr_err_code ndr_err;
    11571168        NTSTATUS status;
     
    11651176                                ldb_ctx,
    11661177                                "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,
    11821190                                        ldb_ctx,
    11831191                                        "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 {
    12001207                char *cert_secret_name;
    12011208
    1202                 status = GUID_from_ndr_blob(&secret, &guid);
     1209                status = GUID_from_ndr_blob(&lsa_secret, &guid);
    12031210                if (!NT_STATUS_IS_OK(status)) {
    12041211                        return WERR_FILE_NOT_FOUND;
     
    12121219                        return WERR_FILE_NOT_FOUND;
    12131220                }
    1214                                
     1221
    12151222                cert_secret_name = talloc_asprintf(mem_ctx,
    12161223                                                        "BCKUPKEY_%s",
     
    12191226                                        ldb_ctx,
    12201227                                        cert_secret_name,
    1221                                         &secret);
     1228                                        &lsa_secret);
    12221229                if (!NT_STATUS_IS_OK(status)) {
    12231230                        return WERR_FILE_NOT_FOUND;
    12241231                }
    12251232
    1226                 if (secret.length != 0) {
     1233                if (lsa_secret.length != 0) {
    12271234                        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,
    12291236                                        (ndr_pull_flags_fn_t)ndr_pull_bkrp_exported_RSA_key_pair);
    12301237                        if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
     
    12361243                        return WERR_OK;
    12371244                } 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
     1253static 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
     1307static 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                 */
    12431322                return WERR_FILE_NOT_FOUND;
    12441323        }
    12451324
    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
     1359static 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
     1386static 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
     1545static 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
     1576static 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;
    12471750}
    12481751
     
    12571760        const int debuglevel = 4;
    12581761
     1762        gnutls_global_init();
     1763
    12591764        if (DEBUGLVL(debuglevel)) {
    12601765                const struct tsocket_address *remote_address;
     
    12661771        }
    12671772
    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) {
    12691774                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);
    12751775        }
    12761776
     
    12871787                if(strncasecmp(GUID_string(mem_ctx, r->in.guidActionAgent),
    12881788                        BACKUPKEY_RESTORE_GUID, strlen(BACKUPKEY_RESTORE_GUID)) == 0) {
    1289                         DEBUG(debuglevel, ("Client %s requested to decrypt a client side wrapped 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);
    12911791                }
    12921792
     
    12941794                        BACKUPKEY_RETRIEVE_BACKUP_KEY_GUID, strlen(BACKUPKEY_RETRIEVE_BACKUP_KEY_GUID)) == 0) {
    12951795                        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);
    12971809                }
    12981810        }
    12991811        /*else: I am a RODC so I don't handle backup key protocol */
    13001812
     1813        gnutls_global_deinit();
    13011814        talloc_unlink(mem_ctx, ldb_ctx);
    13021815        return error;
  • vendor/current/source4/rpc_server/common/reply.c

    r740 r988  
    6868                break;
    6969        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);
    7171                break;
    7272        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);
    7474                break;
    7575        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);
    7777                break;
    7878        }
     
    9898  return a dcerpc fault
    9999*/
    100 NTSTATUS dcesrv_fault(struct dcesrv_call_state *call, uint32_t fault_code)
     100NTSTATUS dcesrv_fault_with_flags(struct dcesrv_call_state *call,
     101                                 uint32_t fault_code,
     102                                 uint8_t extra_flags)
    101103{
    102104        struct ncacn_packet pkt;
    103105        struct data_blob_list_item *rep;
    104         uint8_t zeros[4];
     106        static const uint8_t zeros[4] = { 0, };
    105107        NTSTATUS status;
    106108
    107         /* setup a bind_ack */
     109        /* setup a fault */
    108110        dcesrv_init_hdr(&pkt, lpcfg_rpc_big_endian(call->conn->dce_ctx->lp_ctx));
    109111        pkt.auth_length = 0;
    110112        pkt.call_id = call->pkt.call_id;
    111113        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        }
    115130        pkt.u.fault.cancel_count = 0;
    116131        pkt.u.fault.status = fault_code;
    117 
    118         ZERO_STRUCT(zeros);
    119132        pkt.u.fault._pad = data_blob_const(zeros, sizeof(zeros));
    120133
    121         rep = talloc(call, struct data_blob_list_item);
     134        rep = talloc_zero(call, struct data_blob_list_item);
    122135        if (!rep) {
    123136                return NT_STATUS_NO_MEMORY;
     
    131144        dcerpc_set_frag_length(&rep->blob, rep->blob.length);
    132145
    133         DLIST_ADD_END(call->replies, rep, struct data_blob_list_item *);
     146        DLIST_ADD_END(call->replies, rep);
    134147        dcesrv_call_set_list(call, DCESRV_LIST_CALL_LIST);
    135148
     
    143156}
    144157
    145 
     158NTSTATUS dcesrv_fault(struct dcesrv_call_state *call, uint32_t fault_code)
     159{
     160        return dcesrv_fault_with_flags(call, fault_code, 0);
     161}
    146162
    147163_PUBLIC_ NTSTATUS dcesrv_reply(struct dcesrv_call_state *call)
     
    184200        /* we can write a full max_recv_frag size, minus the dcerpc
    185201           request header size */
    186         chunk_size = call->conn->cli_max_recv_frag;
     202        chunk_size = call->conn->max_xmit_frag;
    187203        chunk_size -= DCERPC_REQUEST_LENGTH;
    188         if (call->conn->auth_state.auth_info &&
     204        if (call->conn->auth_state.auth_finished &&
    189205            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
    190211                sig_size = gensec_sig_size(call->conn->auth_state.gensec_security,
    191                                            call->conn->cli_max_recv_frag);
     212                                           max_payload);
    192213                if (sig_size) {
    193214                        chunk_size -= DCERPC_AUTH_TRAILER_LENGTH;
     
    195216                }
    196217        }
    197         chunk_size -= (chunk_size % 16);
     218        chunk_size -= (chunk_size % DCERPC_AUTH_PAD_ALIGNMENT);
    198219
    199220        do {
     
    202223                struct ncacn_packet pkt;
    203224
    204                 rep = talloc(call, struct data_blob_list_item);
     225                rep = talloc_zero(call, struct data_blob_list_item);
    205226                NT_STATUS_HAVE_NO_MEMORY(rep);
    206227
     
    234255                dcerpc_set_frag_length(&rep->blob, rep->blob.length);
    235256
    236                 DLIST_ADD_END(call->replies, rep, struct data_blob_list_item *);
     257                DLIST_ADD_END(call->replies, rep);
    237258
    238259                stub.data += length;
     
    255276                                    DATA_BLOB *session_key)
    256277{
     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
    257285        return dcerpc_generic_session_key(NULL, session_key);
    258286}
  • vendor/current/source4/rpc_server/common/server_info.c

    r740 r988  
    2626#include "auth/auth.h"
    2727#include "param/param.h"
     28#include "rpc_server/common/common.h"
     29#include "rpc_server/common/share.h"
     30#include "libds/common/roles.h"
    2831
    2932/*
     
    6770        default_server_announce |= SV_TYPE_SERVER_UNIX;
    6871
    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;
    8574
    8675        switch (lpcfg_server_role(dce_ctx->lp_ctx)) {
     
    8877                        default_server_announce |= SV_TYPE_DOMAIN_MEMBER;
    8978                        break;
    90                 case ROLE_DOMAIN_CONTROLLER:
     79                case ROLE_ACTIVE_DIRECTORY_DC:
    9180                {
    9281                        struct ldb_context *samctx;
  • vendor/current/source4/rpc_server/common/share_info.c

    r414 r988  
    2424#include "librpc/gen_ndr/srvsvc.h"
    2525#include "rpc_server/dcerpc_server.h"
     26#include "rpc_server/common/share.h"
    2627
    2728/*
     
    5354         */
    5455        enum srvsvc_ShareType share_type = 0;
    55         const char *sharetype;
     56        char *sharetype;
    5657
    5758        if (!share_bool_option(scfg, SHARE_BROWSEABLE, SHARE_BROWSEABLE_DEFAULT)) {
     
    5960        }
    6061
    61         sharetype = share_string_option(scfg, SHARE_TYPE, SHARE_TYPE_DEFAULT);
     62        sharetype = share_string_option(mem_ctx, scfg, SHARE_TYPE, SHARE_TYPE_DEFAULT);
    6263        if (sharetype && strcasecmp(sharetype, "IPC") == 0) {
    6364                share_type |= STYPE_IPC;
     65                TALLOC_FREE(sharetype);
    6466                return share_type;
    6567        }
     
    6769        if (sharetype && strcasecmp(sharetype, "PRINTER") == 0) {
    6870                share_type |= STYPE_PRINTQ;
     71                TALLOC_FREE(sharetype);
    6972                return share_type;
    7073        }
    7174
     75        TALLOC_FREE(sharetype);
    7276        share_type |= STYPE_DISKTREE;
    7377
     
    7882const char *dcesrv_common_get_share_path(TALLOC_CTX *mem_ctx, struct dcesrv_context *dce_ctx, struct share_config *scfg)
    7983{
    80         const char *sharetype;
     84        char *sharetype;
    8185        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);
    8489       
    8590        if (sharetype && strcasecmp(sharetype, "IPC") == 0) {
     91                TALLOC_FREE(sharetype);
    8692                return talloc_strdup(mem_ctx, "");
    8793        }
    8894
    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, "");
    9098        if (!p) {
    9199                return NULL;
     
    96104        all_string_sub(p, "/", "\\", 0);
    97105       
    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;
    99109}
    100110
  • vendor/current/source4/rpc_server/dcerpc_server.c

    r740 r988  
    4040#include "lib/messaging/irpc.h"
    4141#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"
    4544
    4645extern const struct dcesrv_interface dcesrv_mgmt_interface;
     
    7372        assoc_group = dcesrv_assoc_group_find(dce_ctx, id);
    7473        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));
    7675                return NULL;
    7776        }
     
    126125                            const struct dcerpc_binding *ep2)
    127126{
    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) {
    129139                return false;
    130140        }
    131141
    132         if (!ep1->endpoint || !ep2->endpoint) {
    133                 return ep1->endpoint == ep2->endpoint;
    134         }
    135 
    136         if (strcasecmp(ep1->endpoint, ep2->endpoint) != 0)
     142        if (!e1 || !e2) {
     143                return e1 == e2;
     144        }
     145
     146        if (strcasecmp(e1, e2) != 0) {
    137147                return false;
     148        }
    138149
    139150        return true;
     
    256267         */
    257268        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);
    259270                if (!ep) {
    260271                        return NT_STATUS_NO_MEMORY;
    261272                }
    262273                ZERO_STRUCTP(ep);
    263                 ep->ep_description = talloc_reference(ep, binding);
     274                ep->ep_description = talloc_move(ep, &binding);
    264275                add_ep = true;
    265276
    266277                /* add mgmt interface */
    267                 ifl = talloc(dce_ctx, struct dcesrv_if_list);
     278                ifl = talloc_zero(ep, struct dcesrv_if_list);
    268279                if (!ifl) {
    269280                        return NT_STATUS_NO_MEMORY;
     
    284295
    285296        /* talloc a new interface list element */
    286         ifl = talloc(dce_ctx, struct dcesrv_if_list);
     297        ifl = talloc_zero(ep, struct dcesrv_if_list);
    287298        if (!ifl) {
    288299                return NT_STATUS_NO_MEMORY;
     
    300311                 */
    301312                if (ep->sd == NULL) {
    302                         ep->sd = security_descriptor_copy(dce_ctx, sd);
     313                        ep->sd = security_descriptor_copy(ep, sd);
    303314                }
    304315
     
    367378                                 struct auth_session_info *session_info,
    368379                                 struct tevent_context *event_ctx,
    369                                  struct messaging_context *msg_ctx,
     380                                 struct imessaging_context *msg_ctx,
    370381                                 struct server_id server_id,
    371382                                 uint32_t state_flags,
     
    378389        }
    379390
    380         p = talloc(mem_ctx, struct dcesrv_connection);
     391        p = talloc_zero(mem_ctx, struct dcesrv_connection);
    381392        NT_STATUS_HAVE_NO_MEMORY(p);
    382393
     
    388399        p->dce_ctx = dce_ctx;
    389400        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);
    399402        p->auth_state.session_info = session_info;
    400403        p->auth_state.session_key = dcesrv_generic_session_key;
     
    402405        p->msg_ctx = msg_ctx;
    403406        p->server_id = server_id;
    404         p->processing = false;
    405407        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;
    407411
    408412        *_p = p;
     
    436440                break;
    437441        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);
    439443                break;
    440444        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);
    442446                break;
    443447        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);
    445449                break;
    446450        }
    447451}
    448452
     453static 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}
    449470
    450471/*
     
    454475{
    455476        struct ncacn_packet pkt;
     477        struct dcerpc_bind_nak_version version;
    456478        struct data_blob_list_item *rep;
    457479        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");
    458487
    459488        /* setup a bind_nak */
     
    464493        pkt.pfc_flags = DCERPC_PFC_FLAG_FIRST | DCERPC_PFC_FLAG_LAST;
    465494        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);
    471502        if (!rep) {
    472503                return NT_STATUS_NO_MEMORY;
     
    480511        dcerpc_set_frag_length(&rep->blob, rep->blob.length);
    481512
    482         DLIST_ADD_END(call->replies, rep, struct data_blob_list_item *);
     513        DLIST_ADD_END(call->replies, rep);
    483514        dcesrv_call_set_list(call, DCESRV_LIST_CALL_LIST);
    484515
     
    492523}
    493524
     525static 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
    494538static int dcesrv_connection_context_destructor(struct dcesrv_connection_context *c)
    495539{
     
    498542        if (c->iface && c->iface->unbind) {
    499543                c->iface->unbind(c, c->iface);
     544                c->iface = NULL;
    500545        }
    501546
    502547        return 0;
     548}
     549
     550static 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
     577NTSTATUS 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
     588NTSTATUS 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;
    503657}
    504658
     
    517671        const struct dcesrv_interface *iface;
    518672        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;
    519710
    520711        /*
    521712          if provided, check the assoc_group is valid
    522713         */
    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);
    527724        }
    528725
     
    533730
    534731        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 
    541732        if_version = call->pkt.u.bind.ctx_list[0].abstract_syntax.if_version;
    542733        uuid = call->pkt.u.bind.ctx_list[0].abstract_syntax.uuid;
     
    544735        transfer_syntax_version = call->pkt.u.bind.ctx_list[0].transfer_syntaxes[0].if_version;
    545736        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) {
    548739                char *uuid_str = GUID_string(call, transfer_syntax_uuid);
    549740                /* we only do NDR encoded dcerpc */
     
    566757        if (iface) {
    567758                /* 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,
    569760                                                                   struct dcesrv_connection_context);
    570761                if (context == NULL) {
     
    574765                context->iface = iface;
    575766                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;
    587769                context->private_data = NULL;
    588770                DLIST_ADD(call->conn->contexts, context);
    589771                call->context = context;
    590772                talloc_set_destructor(context, dcesrv_connection_context_destructor);
     773
     774                dcesrv_prepare_context_auth(call);
    591775
    592776                status = iface->bind(call, iface, if_version);
     
    604788        }
    605789
    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;
    614798        }
    615799
    616800        /* handle any authentication that is being requested */
    617801        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);
    621816        }
    622817
     
    627822        pkt.ptype = DCERPC_PKT_BIND_ACK;
    628823        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;
    643827
    644828        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;
    649854        }
    650855        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);
    652857        if (!pkt.u.bind_ack.ctx_list) {
    653858                talloc_free(call->context);
     
    656861        }
    657862        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;
    660865        pkt.u.bind_ack.auth_info = data_blob(NULL, 0);
    661866
     
    667872        }
    668873
    669         rep = talloc(call, struct data_blob_list_item);
     874        rep = talloc_zero(call, struct data_blob_list_item);
    670875        if (!rep) {
    671876                talloc_free(call->context);
     
    675880
    676881        status = ncacn_push_auth(&rep->blob, call, &pkt,
    677                                                          call->conn->auth_state.auth_info);
     882                                 call->out_auth_info);
    678883        if (!NT_STATUS_IS_OK(status)) {
    679884                talloc_free(call->context);
     
    684889        dcerpc_set_frag_length(&rep->blob, rep->blob.length);
    685890
    686         DLIST_ADD_END(call->replies, rep, struct data_blob_list_item *);
     891        DLIST_ADD_END(call->replies, rep);
    687892        dcesrv_call_set_list(call, DCESRV_LIST_CALL_LIST);
    688893
     
    702907static NTSTATUS dcesrv_auth3(struct dcesrv_call_state *call)
    703908{
     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
    704935        /* handle the auth3 in the auth code */
    705936        if (!dcesrv_auth_auth3(call)) {
    706                 return dcesrv_fault(call, DCERPC_FAULT_OTHER);
     937                call->conn->auth_state.auth_invalid = true;
    707938        }
    708939
     
    731962        transfer_syntax_version = call->pkt.u.alter.ctx_list[0].transfer_syntaxes[0].if_version;
    732963        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) {
    735966                /* we only do NDR encoded dcerpc */
    736967                return NT_STATUS_RPC_PROTSEQ_NOT_SUPPORTED;
     
    746977
    747978        /* 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);
    749980        if (context == NULL) {
    750981                return NT_STATUS_NO_MEMORY;
     
    753984        context->iface = iface;
    754985        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;
    767988        context->private_data = NULL;
    768989        DLIST_ADD(call->conn->contexts, context);
    769990        call->context = context;
    770991        talloc_set_destructor(context, dcesrv_connection_context_destructor);
     992
     993        dcesrv_prepare_context_auth(call);
    771994
    772995        status = iface->bind(call, iface, if_version);
     
    7821005}
    7831006
    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 */
     1008static NTSTATUS dcesrv_alter_resp(struct dcesrv_call_state *call,
     1009                                uint32_t result,
     1010                                uint32_t reason)
    7891011{
    7901012        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;
    7921015        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
    8291017        dcesrv_init_hdr(&pkt, lpcfg_rpc_big_endian(call->conn->dce_ctx->lp_ctx));
    8301018        pkt.auth_length = 0;
    8311019        pkt.call_id = call->pkt.call_id;
    8321020        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;
    8361021        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;
    8411036        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);
    8431038        if (!pkt.u.alter_resp.ctx_list) {
    8441039                return NT_STATUS_NO_MEMORY;
    8451040        }
    8461041        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;
    8491044        pkt.u.alter_resp.auth_info = data_blob(NULL, 0);
    8501045        pkt.u.alter_resp.secondary_address = "";
     
    8521047        status = dcesrv_auth_alter_ack(call, &pkt);
    8531048        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);
    8641053        if (!rep) {
    8651054                return NT_STATUS_NO_MEMORY;
    8661055        }
    8671056
    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);
    8691058        if (!NT_STATUS_IS_OK(status)) {
    8701059                return status;
     
    8731062        dcerpc_set_frag_length(&rep->blob, rep->blob.length);
    8741063
    875         DLIST_ADD_END(call->replies, rep, struct data_blob_list_item *);
     1064        DLIST_ADD_END(call->replies, rep);
    8761065        dcesrv_call_set_list(call, DCESRV_LIST_CALL_LIST);
    8771066
     
    8831072
    8841073        return NT_STATUS_OK;
     1074}
     1075
     1076/*
     1077  handle a alter context request
     1078*/
     1079static 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);
    8851167}
    8861168
     
    9091191}
    9101192
     1193static 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        }
     1224done:
     1225        TALLOC_FREE(frame);
     1226        return status;
     1227}
     1228
    9111229/*
    9121230  handle a dcerpc request packet
     
    9141232static NTSTATUS dcesrv_request(struct dcesrv_call_state *call)
    9151233{
     1234        const struct dcesrv_endpoint *endpoint = call->conn->endpoint;
     1235        enum dcerpc_transport_t transport =
     1236                dcerpc_binding_get_transport(endpoint->ep_description);
    9161237        struct ndr_pull *pull;
    9171238        NTSTATUS status;
    9181239        struct dcesrv_connection_context *context;
     1240
     1241        if (!call->conn->allow_request) {
     1242                return dcesrv_fault_disconnect(call, DCERPC_NCA_S_PROTO_ERROR);
     1243        }
    9191244
    9201245        /* if authenticated, and the mech we use can't do async replies, don't use them... */
     
    9291254        }
    9301255
     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
    9311299        pull = ndr_pull_init_blob(&call->pkt.u.request.stub_and_verifier, call);
    9321300        NT_STATUS_HAVE_NO_MEMORY(pull);
     
    9391307        if (!(call->pkt.drep[0] & DCERPC_DREP_LE)) {
    9401308                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);
    9411320        }
    9421321
     
    10041383  process some input to a dcerpc endpoint server.
    10051384*/
    1006 NTSTATUS dcesrv_process_ncacn_packet(struct dcesrv_connection *dce_conn,
    1007                                      struct ncacn_packet *pkt,
    1008                                      DATA_BLOB blob)
     1385static NTSTATUS dcesrv_process_ncacn_packet(struct dcesrv_connection *dce_conn,
     1386                                            struct ncacn_packet *pkt,
     1387                                            DATA_BLOB blob)
    10091388{
    10101389        NTSTATUS status;
    10111390        struct dcesrv_call_state *call;
     1391        struct dcesrv_call_state *existing = NULL;
    10121392
    10131393        call = talloc_zero(dce_conn, struct dcesrv_call_state);
     
    10301410        talloc_set_destructor(call, dcesrv_call_dequeue);
    10311411
     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
    10321420        /* we have to check the signing here, before combining the
    10331421           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                }
    10371522        }
    10381523
    10391524        /* 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,
    10711562                                       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;
    10851579        }
    10861580
     
    10891583        if (call->pkt.ptype == DCERPC_PKT_REQUEST &&
    10901584            !(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                }
    10911593                dcesrv_call_set_list(call, DCESRV_LIST_FRAGMENTED_CALL_LIST);
    10921594                return NT_STATUS_OK;
     
    10981600        switch (call->pkt.ptype) {
    10991601        case DCERPC_PKT_BIND:
    1100                 status = dcesrv_bind(call);
     1602                status = dcesrv_bind_nak(call,
     1603                        DCERPC_BIND_NAK_REASON_NOT_SPECIFIED);
    11011604                break;
    11021605        case DCERPC_PKT_AUTH3:
     
    11101613                break;
    11111614        default:
    1112                 status = NT_STATUS_INVALID_PARAMETER;
     1615                status = dcesrv_fault_disconnect(call, DCERPC_NCA_S_PROTO_ERROR);
    11131616                break;
    11141617        }
     
    11371640        }
    11381641
    1139         dce_ctx = talloc(mem_ctx, struct dcesrv_context);
     1642        dce_ctx = talloc_zero(mem_ctx, struct dcesrv_context);
    11401643        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
    11411653        dce_ctx->endpoint_list  = NULL;
    11421654        dce_ctx->lp_ctx = lp_ctx;
    11431655        dce_ctx->assoc_groups_idr = idr_init(dce_ctx);
    11441656        NT_STATUS_HAVE_NO_MEMORY(dce_ctx->assoc_groups_idr);
     1657        dce_ctx->broken_connections = NULL;
    11451658
    11461659        for (i=0;endpoint_servers[i];i++) {
     
    12361749        initialized = true;
    12371750
    1238         shared_init = load_samba_modules(NULL, lp_ctx, "dcerpc_server");
     1751        shared_init = load_samba_modules(NULL, "dcerpc_server");
    12391752
    12401753        run_init_functions(static_init);
     
    12691782static void dcesrv_terminate_connection(struct dcesrv_connection *dce_conn, const char *reason)
    12701783{
     1784        struct dcesrv_context *dce_ctx = dce_conn->dce_ctx;
    12711785        struct stream_connection *srv_conn;
    12721786        srv_conn = talloc_get_type(dce_conn->transport.private_data,
    12731787                                   struct stream_connection);
    12741788
    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
     1815static 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
    12771840/* We need this include to be able to compile on some plateforms
    12781841 * (ie. freebsd 7.2) as it seems that <sys/uio.h> is not included
     
    12921855
    12931856static void dcesrv_sock_reply_done(struct tevent_req *subreq);
     1857static void dcesrv_call_terminate_step1(struct tevent_req *subreq);
    12941858
    12951859static void dcesrv_sock_report_output_data(struct dcesrv_connection *dce_conn)
     
    13071871                struct tevent_req *subreq;
    13081872
    1309                 substate = talloc(call, struct dcesrv_sock_reply_state);
     1873                substate = talloc_zero(call, struct dcesrv_sock_reply_state);
    13101874                if (!substate) {
    13111875                        dcesrv_terminate_connection(dce_conn, "no memory");
     
    13181882                DLIST_REMOVE(call->replies, rep);
    13191883
    1320                 if (call->replies == NULL) {
     1884                if (call->replies == NULL && call->terminate_reason == NULL) {
    13211885                        substate->call = call;
    13221886                }
     
    13381902        }
    13391903
     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
    13401918        DLIST_REMOVE(call->conn->call_list, call);
    13411919        call->list = DCESRV_LIST_NONE;
     
    13541932        TALLOC_FREE(subreq);
    13551933        if (ret == -1) {
    1356                 status = map_nt_error_from_unix(sys_errno);
     1934                status = map_nt_error_from_unix_common(sys_errno);
    13571935                dcesrv_terminate_connection(substate->dce_conn, nt_errstr(status));
    13581936                return;
     
    13651943}
    13661944
    1367 
    1368 
     1945static void dcesrv_call_terminate_step2(struct tevent_req *subreq);
     1946
     1947static 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
     1975static 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}
    13691990
    13701991struct dcesrv_socket_context {
     
    13812002        struct dcesrv_socket_context *dcesrv_sock =
    13822003                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);
    13832006        struct dcesrv_connection *dcesrv_conn = NULL;
    13842007        int ret;
    13852008        struct tevent_req *subreq;
    13862009        struct loadparm_context *lp_ctx = dcesrv_sock->dcesrv_ctx->lp_ctx;
     2010
     2011        dcesrv_cleanup_broken_connections(dcesrv_sock->dcesrv_ctx);
    13872012
    13882013        if (!srv_conn->session_info) {
     
    14282053        }
    14292054
    1430         if (dcesrv_sock->endpoint->ep_description->transport == NCACN_NP) {
     2055        if (transport == NCACN_NP) {
    14312056                dcesrv_conn->auth_state.session_key = dcesrv_inherited_session_key;
    14322057                dcesrv_conn->stream = talloc_move(dcesrv_conn,
     
    14372062                                                  &dcesrv_conn->stream);
    14382063                if (ret == -1) {
    1439                         status = map_nt_error_from_unix(errno);
     2064                        status = map_nt_error_from_unix_common(errno);
    14402065                        DEBUG(0, ("dcesrv_sock_accept: "
    14412066                                  "failed to setup tstream: %s\n",
     
    14492074        dcesrv_conn->local_address = srv_conn->local_address;
    14502075        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        }
    14512107
    14522108        srv_conn->private_data = dcesrv_conn;
     
    14732129        struct dcesrv_connection *dce_conn = tevent_req_callback_data(subreq,
    14742130                                             struct dcesrv_connection);
     2131        struct dcesrv_context *dce_ctx = dce_conn->dce_ctx;
    14752132        struct ncacn_packet *pkt;
    14762133        DATA_BLOB buffer;
    14772134        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);
    14782147
    14792148        status = dcerpc_read_ncacn_packet_recv(subreq, dce_conn,
     
    15322201        uint16_t port = 1;
    15332202        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);
    15362206        NT_STATUS_HAVE_NO_MEMORY(dcesrv_sock);
    15372207
     
    15402210        dcesrv_sock->dcesrv_ctx         = talloc_reference(dcesrv_sock, dce_ctx);
    15412211
     2212        endpoint = dcerpc_binding_get_string_option(e->ep_description, "endpoint");
     2213
    15422214        status = stream_setup_socket(dcesrv_sock, event_ctx, lp_ctx,
    15432215                                     model_ops, &dcesrv_stream_ops,
    1544                                      "unix", e->ep_description->endpoint, &port,
     2216                                     "unix", endpoint, &port,
    15452217                                     lpcfg_socket_options(lp_ctx),
    15462218                                     dcesrv_sock);
    15472219        if (!NT_STATUS_IS_OK(status)) {
    15482220                DEBUG(0,("service_setup_stream_socket(path=%s) failed - %s\n",
    1549                          e->ep_description->endpoint, nt_errstr(status)));
     2221                         endpoint, nt_errstr(status)));
    15502222        }
    15512223
     
    15622234        char *full_path;
    15632235        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                }
    15702256        }
    15712257
    15722258        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);
    15762262        NT_STATUS_HAVE_NO_MEMORY(dcesrv_sock);
    15772263
     
    15872273        if (!NT_STATUS_IS_OK(status)) {
    15882274                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)));
    15902276        }
    15912277        return status;
     
    15992285        struct dcesrv_socket_context *dcesrv_sock;
    16002286        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) {
    16032291                DEBUG(0, ("Endpoint mandatory for named pipes\n"));
    16042292                return NT_STATUS_INVALID_PARAMETER;
    16052293        }
    16062294
    1607         dcesrv_sock = talloc(event_ctx, struct dcesrv_socket_context);
     2295        dcesrv_sock = talloc_zero(event_ctx, struct dcesrv_socket_context);
    16082296        NT_STATUS_HAVE_NO_MEMORY(dcesrv_sock);
    16092297
     
    16142302        status = tstream_setup_named_pipe(dce_ctx, event_ctx, lp_ctx,
    16152303                                          model_ops, &dcesrv_stream_ops,
    1616                                           e->ep_description->endpoint,
     2304                                          endpoint,
    16172305                                          dcesrv_sock);
    16182306        if (!NT_STATUS_IS_OK(status)) {
    16192307                DEBUG(0,("stream_setup_named_pipe(pipe=%s) failed - %s\n",
    1620                          e->ep_description->endpoint, nt_errstr(status)));
     2308                         endpoint, nt_errstr(status)));
    16212309                return status;
    16222310        }
     
    16352323        uint16_t port = 0;
    16362324        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);
    16432334        NT_STATUS_HAVE_NO_MEMORY(dcesrv_sock);
    16442335
     
    16492340        status = stream_setup_socket(dcesrv_sock, event_ctx, dce_ctx->lp_ctx,
    16502341                                     model_ops, &dcesrv_stream_ops,
    1651                                      "ipv4", address, &port,
     2342                                     "ip", address, &port,
    16522343                                     lpcfg_socket_options(dce_ctx->lp_ctx),
    16532344                                     dcesrv_sock);
     
    16552346                DEBUG(0,("service_setup_stream_socket(address=%s,port=%u) failed - %s\n",
    16562347                         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;
    16642362}
    16652363
     
    16792377                struct interface *ifaces;
    16802378
    1681                 load_interfaces(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);
    16842382                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);
    16862384                        status = add_socket_rpc_tcp_iface(dce_ctx, e, event_ctx, model_ops, address);
    16872385                        NT_STATUS_NOT_OK_RETURN(status);
    16882386                }
    16892387        } 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                }
    16932403        }
    16942404
     
    17022412                       const struct model_ops *model_ops)
    17032413{
    1704         switch (e->ep_description->transport) {
     2414        enum dcerpc_transport_t transport =
     2415                dcerpc_binding_get_transport(e->ep_description);
     2416
     2417        switch (transport) {
    17052418        case NCACN_UNIX_STREAM:
    17062419                return dcesrv_add_ep_unix(dce_ctx, lp_ctx, e, event_ctx, model_ops);
  • vendor/current/source4/rpc_server/dcerpc_server.h

    r740 r988  
    2424#define SAMBA_DCERPC_SERVER_H
    2525
    26 #include "librpc/gen_ndr/server_id4.h"
     26#include "librpc/gen_ndr/server_id.h"
    2727#include "librpc/rpc/dcerpc.h"
    2828#include "librpc/ndr/libndr.h"
     
    102102#define DCESRV_CALL_STATE_FLAG_ASYNC (1<<0)
    103103#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)
    105106        uint32_t state_flags;
    106107
     
    112113
    113114        /* the message_context that will be used for async replies */
    114         struct messaging_context *msg_ctx;
     115        struct imessaging_context *msg_ctx;
    115116
    116117        /* this is the pointer to the allocated function struct */
     
    130131        /* this is used by the boilerplate code to generate DCERPC faults */
    131132        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;
    132141};
    133142
     
    146155/* hold the authentication state information */
    147156struct 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;
    149160        struct gensec_security *gensec_security;
    150161        struct auth_session_info *session_info;
    151162        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;
    152167};
    153168
     
    156171        uint32_t context_id;
    157172
     173        /* TODO: remove this legacy (for openchange) in master */
    158174        struct dcesrv_assoc_group *assoc_group;
    159175
     
    166182        /* private data for the interface implementation */
    167183        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;
    168190};
    169191
     
    171193/* the state associated with a dcerpc server connection */
    172194struct dcesrv_connection {
     195        /* for the broken_connections DLIST */
     196        struct dcesrv_connection *prev, *next;
     197
    173198        /* the top level context for this server */
    174199        struct dcesrv_context *dce_ctx;
     
    190215
    191216        /* 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;
    193219
    194220        DATA_BLOB partial_input;
    195221
    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;
    198231
    199232        /* the event_context that will be used for this connection */
     
    201234
    202235        /* the message_context that will be used for this connection */
    203         struct messaging_context *msg_ctx;
     236        struct imessaging_context *msg_ctx;
    204237
    205238        /* the server_id that will be used for this connection */
     
    209242        DATA_BLOB transport_session_key;
    210243
    211         bool processing;
     244        /* is this connection pending termination?  If so, why? */
     245        const char *terminate;
    212246
    213247        const char *packet_log_dir;
     
    226260        const struct tsocket_address *local_address;
    227261        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;
    228276};
    229277
     
    269317/* server-wide context information for the dcerpc server */
    270318struct 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
    271326        /* the list of endpoints that have registered
    272327         * by the configured endpoint servers
     
    289344
    290345        struct idr_context *assoc_groups_idr;
     346
     347        struct dcesrv_connection *broken_connections;
    291348};
    292349
     
    320377                                 struct auth_session_info *session_info,
    321378                                 struct tevent_context *event_ctx,
    322                                  struct messaging_context *msg_ctx,
     379                                 struct imessaging_context *msg_ctx,
    323380                                 struct server_id server_id,
    324381                                 uint32_t state_flags,
     
    399456_PUBLIC_ const char *dcesrv_call_account_name(struct dcesrv_call_state *dce_call);
    400457
     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);
    401466
    402467#endif /* SAMBA_DCERPC_SERVER_H */
  • vendor/current/source4/rpc_server/dcerpc_server.pc.in

    r740 r988  
    33libdir=@libdir@
    44includedir=@includedir@
     5modulesdir=@modulesdir@/dcerpc_server
    56
    67Name: dcerpc_server
  • vendor/current/source4/rpc_server/dcesrv_auth.c

    r919 r988  
    4040bool dcesrv_auth_bind(struct dcesrv_call_state *call)
    4141{
    42         struct cli_credentials *server_credentials;
     42        struct cli_credentials *server_credentials = NULL;
    4343        struct ncacn_packet *pkt = &call->pkt;
    4444        struct dcesrv_connection *dce_conn = call->conn;
     
    4848
    4949        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;
    5153                return true;
    5254        }
    5355
    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 
    5956        status = dcerpc_pull_auth_trailer(pkt, call, &pkt->u.bind.auth_info,
    60                                           dce_conn->auth_state.auth_info,
     57                                          &call->in_auth_info,
    6158                                          &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
    6291        server_credentials
    6392                = cli_credentials_init(call);
     
    7099        status = cli_credentials_set_machine_account(server_credentials, call->conn->dce_ctx->lp_ctx);
    71100        if (!NT_STATUS_IS_OK(status)) {
    72                 DEBUG(10, ("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;
    75104        }
    76105
     
    81110                                           NULL,
    82111                                           &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);
    87130        if (!NT_STATUS_IS_OK(status)) {
    88131                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,
    91134                          nt_errstr(status)));
    92135                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);
    97136        }
    98137
     
    108147        struct dcesrv_connection *dce_conn = call->conn;
    109148        NTSTATUS status;
     149        bool want_header_signing = false;
     150
     151        dce_conn->allow_alter = true;
     152        dce_conn->allow_auth3 = true;
    110153
    111154        if (call->pkt.auth_length == 0) {
     155                dce_conn->auth_state.auth_finished = true;
     156                dce_conn->allow_request = true;
    112157                return NT_STATUS_OK;
    113158        }
    114159
    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);
    119185       
    120186        if (NT_STATUS_IS_OK(status)) {
    121187                status = gensec_session_info(dce_conn->auth_state.gensec_security,
     188                                             dce_conn,
    122189                                             &dce_conn->auth_state.session_info);
    123190                if (!NT_STATUS_IS_OK(status)) {
     
    125192                        return status;
    126193                }
    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) {
    129204                        gensec_want_feature(dce_conn->auth_state.gensec_security,
    130205                                            GENSEC_FEATURE_SIGN_PKT_HEADER);
     206                        dce_conn->auth_state.hdr_signing = true;
     207                        pkt->pfc_flags |= DCERPC_PFC_FLAG_SUPPORT_HEADER_SIGN;
    131208                }
    132209
     
    135212                return NT_STATUS_OK;
    136213        } 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
    139227                return NT_STATUS_OK;
    140228        } else {
     
    160248        }
    161249
    162         if (!dce_conn->auth_state.auth_info) {
     250        if (dce_conn->auth_state.auth_finished) {
    163251                return false;
    164252        }
     
    170258
    171259        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;
    176283
    177284        /* 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);
    182289        if (NT_STATUS_IS_OK(status)) {
    183290                status = gensec_session_info(dce_conn->auth_state.gensec_security,
     291                                             dce_conn,
    184292                                             &dce_conn->auth_state.session_info);
    185293                if (!NT_STATUS_IS_OK(status)) {
     
    187295                        return false;
    188296                }
     297                dce_conn->auth_state.auth_finished = true;
     298                dce_conn->allow_request = true;
     299
    189300                /* Now that we are authenticated, go back to the generic session key... */
    190301                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                }
    191309                return true;
    192310        } else {
     
    211329        /* on a pure interface change there is no auth blob */
    212330        if (pkt->auth_length == 0) {
     331                if (!dce_conn->auth_state.auth_finished) {
     332                        return false;
     333                }
    213334                return true;
     335        }
     336
     337        if (dce_conn->auth_state.auth_finished) {
     338                return false;
    214339        }
    215340
     
    219344        }
    220345
    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 
    226346        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) {
    230361                return false;
    231362        }
     
    250381
    251382        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);
    259397
    260398        if (NT_STATUS_IS_OK(status)) {
    261399                status = gensec_session_info(dce_conn->auth_state.gensec_security,
     400                                             dce_conn,
    262401                                             &dce_conn->auth_state.session_info);
    263402                if (!NT_STATUS_IS_OK(status)) {
     
    265404                        return status;
    266405                }
     406                dce_conn->auth_state.auth_finished = true;
     407                dce_conn->allow_request = true;
    267408
    268409                /* Now that we are authenticated, got back to the generic session key... */
     
    270411                return NT_STATUS_OK;
    271412        } 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;
    274413                return NT_STATUS_OK;
    275414        }
     
    287426        struct ncacn_packet *pkt = &call->pkt;
    288427        struct dcesrv_connection *dce_conn = call->conn;
    289         struct dcerpc_auth auth;
    290428        NTSTATUS status;
    291429        uint32_t auth_length;
    292430        size_t hdr_size = DCERPC_REQUEST_LENGTH;
    293431
    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;
    297438        }
    298439
     
    301442        }
    302443
    303         switch (dce_conn->auth_state.auth_info->auth_level) {
     444        switch (dce_conn->auth_state.auth_level) {
    304445        case DCERPC_AUTH_LEVEL_PRIVACY:
    305446        case DCERPC_AUTH_LEVEL_INTEGRITY:
     
    321462        }
    322463
    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) {
    325465                return false;
    326466        }
     
    328468        status = dcerpc_pull_auth_trailer(pkt, call,
    329469                                          &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) {
    332484                return false;
    333485        }
     
    336488
    337489        /* check signature or unseal the packet */
    338         switch (dce_conn->auth_state.auth_info->auth_level) {
     490        switch (dce_conn->auth_state.auth_level) {
    339491        case DCERPC_AUTH_LEVEL_PRIVACY:
    340492                status = gensec_unseal_packet(dce_conn->auth_state.gensec_security,
    341                                               call,
    342493                                              full_packet->data + hdr_size,
    343494                                              pkt->u.request.stub_and_verifier.length,
    344495                                              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);
    347499                memcpy(pkt->u.request.stub_and_verifier.data,
    348500                       full_packet->data + hdr_size,
     
    352504        case DCERPC_AUTH_LEVEL_INTEGRITY:
    353505                status = gensec_check_packet(dce_conn->auth_state.gensec_security,
    354                                              call,
    355506                                             pkt->u.request.stub_and_verifier.data,
    356507                                             pkt->u.request.stub_and_verifier.length,
    357508                                             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);
    360512                break;
    361513
     
    371523
    372524        /* 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;
    377529
    378530        return NT_STATUS_IS_OK(status);
     
    394546        DATA_BLOB creds2;
    395547
    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) {
    403549        case DCERPC_AUTH_LEVEL_PRIVACY:
    404550        case DCERPC_AUTH_LEVEL_INTEGRITY:
     551                if (sig_size == 0) {
     552                        return false;
     553                }
     554
    405555                break;
    406556
     
    421571        }
    422572
     573        if (!dce_conn->auth_state.gensec_security) {
     574                return false;
     575        }
     576
    423577        ndr = ndr_push_init_ctx(call);
    424578        if (!ndr) {
     
    434588                return false;
    435589        }
     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;
    436597
    437598        /* pad to 16 byte multiple in the payload portion of the
     
    440601           whole packet, whereas w2k8 wants it relative to the start
    441602           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);
    446606        if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
    447607                return false;
     
    449609
    450610        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;
    455612
    456613        /* add the auth verifier */
    457614        ndr_err = ndr_push_dcerpc_auth(ndr, NDR_SCALARS|NDR_BUFFERS,
    458                                        dce_conn->auth_state.auth_info);
     615                                       call->out_auth_info);
    459616        if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
    460617                return false;
     
    474631
    475632        /* sign or seal the packet */
    476         switch (dce_conn->auth_state.auth_info->auth_level) {
     633        switch (dce_conn->auth_state.auth_level) {
    477634        case DCERPC_AUTH_LEVEL_PRIVACY:
    478635                status = gensec_seal_packet(dce_conn->auth_state.gensec_security,
     
    507664                DEBUG(3,("dcesrv_auth_response: creds2.length[%u] != sig_size[%u] pad[%u] stub[%u]\n",
    508665                         (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,
    510667                         (unsigned)pkt->u.response.stub_and_verifier.length));
    511668                dcerpc_set_frag_length(blob, blob->length + creds2.length);
  • vendor/current/source4/rpc_server/dcesrv_mgmt.c

    r414 r988  
    2323#include "rpc_server/dcerpc_server.h"
    2424#include "librpc/gen_ndr/ndr_mgmt.h"
     25
     26#define DCESRV_INTERFACE_MGMT_BIND(call, iface) \
     27       dcesrv_interface_mgmt_bind(call, iface)
     28static 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}
    2533
    2634/*
  • vendor/current/source4/rpc_server/drsuapi/addentry.c

    r740 r988  
    6262                                 dn, LDB_SCOPE_BASE, attrs,
    6363                                 "(objectClass=ntDSDSA)");
    64                 if (ret != LDB_SUCCESS || res->count < 1) {
     64                if (ret != LDB_SUCCESS) {
    6565                        DEBUG(0,(__location__ ": Failed to find dn '%s'\n", dn_string));
    6666                        return WERR_DS_DRA_INTERNAL_ERROR;
     67                }
     68
     69                if (res->count < 1) {
     70                        /* we only add SPNs for nTDSDSA objects */
     71                        continue;
    6772                }
    6873
     
    192197                                                    first_object,
    193198                                                    &num,
     199                                                    DSDB_REPL_FLAG_ADD_NCNAME,
    194200                                                    &ids);
    195201                if (!W_ERROR_IS_OK(status)) {
  • vendor/current/source4/rpc_server/drsuapi/dcesrv_drsuapi.c

    r740 r988  
    2626#include "rpc_server/common/common.h"
    2727#include "dsdb/samdb/samdb.h"
     28#include "dsdb/common/util.h"
    2829#include "libcli/security/security.h"
    2930#include "libcli/security/session.h"
     
    3839        DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR); \
    3940} while (0)
     41
     42#define DCESRV_INTERFACE_DRSUAPI_BIND(call, iface) \
     43        dcesrv_interface_drsuapi_bind(call, iface)
     44static 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}
    4049
    4150/*
     
    124133         * lookup the local servers Replication Epoch
    125134         */
    126         ntds_dn = samdb_ntds_settings_dn(b_state->sam_ctx);
     135        ntds_dn = samdb_ntds_settings_dn(b_state->sam_ctx, mem_ctx);
    127136        W_ERROR_HAVE_NO_MEMORY(ntds_dn);
    128137
     
    220229         * allocate the return bind_info
    221230         */
    222         bind_info = talloc(mem_ctx, struct drsuapi_DsBindInfoCtr);
     231        bind_info = talloc_zero(mem_ctx, struct drsuapi_DsBindInfoCtr);
    223232        W_ERROR_HAVE_NO_MEMORY(bind_info);
    224233
     
    430439                case 1: {
    431440                        switch(r->in.req->req1.format_offered){
    432                         case DRSUAPI_DS_NAME_FORMAT_UPN_AND_ALTSECID:
    433441                        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:
    437443                        case DRSUAPI_DS_NAME_FORMAT_STRING_SID_NAME:
    438444                        case DRSUAPI_DS_NAME_FORMAT_ALT_SECURITY_IDENTITIES_NAME:
     445                        case DRSUAPI_DS_NAME_FORMAT_MAP_SCHEMA_GUID:
    439446                        case DRSUAPI_DS_NAME_FORMAT_LIST_NCS:
    440447                        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:
    444450                        case DRSUAPI_DS_NAME_FORMAT_LIST_SERVERS_FOR_DOMAIN_IN_SITE:
    445451                        case DRSUAPI_DS_NAME_FORMAT_LIST_DOMAINS_IN_SITE:
    446452                        case DRSUAPI_DS_NAME_FORMAT_LIST_SERVERS_IN_SITE:
    447453                        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:
    448456                                DEBUG(0, ("DsCrackNames: Unsupported operation requested: %X",
    449457                                          r->in.req->req1.format_offered));
    450458                                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);
    451461                        case DRSUAPI_DS_NAME_FORMAT_LIST_ROLES:
    452462                                return dcesrv_drsuapi_ListRoles(b_state->sam_ctx, mem_ctx,
     
    503513
    504514                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);
    506516                        if (ret != LDB_SUCCESS) {
    507517                                return WERR_FOOBAR;
     
    576586
    577587        *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);
    579589        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         }
    585590
    586591        switch (*r->out.level_out) {
     
    598603        }
    599604
     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
    600610        ret = ldb_search(b_state->sam_ctx, mem_ctx, &res, sites_dn, LDB_SCOPE_SUBTREE, attrs,
    601                                  "objectClass=server");
     611                                 "(&(objectClass=server)(serverReference=*))");
    602612       
    603613        if (ret) {
     
    630640
    631641                        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);
    633645                        if (ret == LDB_SUCCESS && res_account->count == 1) {
    634646                                const char *errstr;
     
    770782                }
    771783                break;
     784        default:
     785                return WERR_UNKNOWN_LEVEL;
    772786        }
    773787        return WERR_OK;
     
    802816{
    803817        WERROR status;
     818        uint32_t timeout;
    804819        status = drs_security_level_check(dce_call, "DsExecuteKCC", SECURITY_DOMAIN_CONTROLLER, NULL);
    805820
     
    807822                return status;
    808823        }
     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        }
    809836
    810837        dcesrv_irpc_forward_rpc_call(dce_call, mem_ctx, r, NDR_DRSUAPI_DSEXECUTEKCC,
    811838                                     &ndr_table_drsuapi, "kccsrv", "DsExecuteKCC",
    812                                      IRPC_CALL_TIMEOUT);
     839                                     timeout);
     840        DEBUG(0, ("Forwarded the call to execute the KCC\n"));
    813841        return WERR_OK;
    814842}
  • vendor/current/source4/rpc_server/drsuapi/drsutil.c

    r740 r988  
    2727#include "param/param.h"
    2828#include "auth/session.h"
     29#include "rpc_server/drsuapi/dcesrv_drsuapi.h"
    2930
    3031int drsuapi_search_with_extended_dn(struct ldb_context *ldb,
     
    170171                return WERR_DS_DRA_ACCESS_DENIED;
    171172        } 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)));
    173174                return WERR_DS_DRA_INTERNAL_ERROR;
    174175        }
  • vendor/current/source4/rpc_server/drsuapi/getncchanges.c

    r740 r988  
    3838#include "dsdb/common/util.h"
    3939
     40/* state of a partially completed getncchanges call */
     41struct 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
     59static 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
    4079/*
    4180  build a DsReplicaObjectIdentifier from a ldb msg
     
    120159                                          struct drsuapi_DsPartialAttributeSet *partial_attribute_set,
    121160                                          struct drsuapi_DsReplicaCursorCtrEx *uptodateness_vector,
    122                                           enum drsuapi_DsExtendedOperation extended_op)
     161                                          enum drsuapi_DsExtendedOperation extended_op,
     162                                          bool force_object_return)
    123163{
    124164        const struct ldb_val *md_value;
     
    261301        /* ignore it if its an empty change. Note that renames always
    262302         * 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         */
    264310        if (n == 0 ||
    265             (n == 1 && attids[0] == DRSUAPI_ATTID_instanceType)) {
     311            (n == 1 &&
     312             attids[0] == DRSUAPI_ATTID_instanceType &&
     313             !force_object_return)) {
    266314                talloc_free(obj->meta_data_ctr);
    267315                obj->meta_data_ctr = NULL;
     
    275323        obj->object.attribute_ctr.attributes = talloc_array(obj, struct drsuapi_DsReplicaAttribute,
    276324                                                            obj->object.attribute_ctr.num_attributes);
     325        if (obj->object.attribute_ctr.attributes == NULL) {
     326                return WERR_NOMEM;
     327        }
    277328
    278329        /*
     
    303354                                                          &obj->object.attribute_ctr.attributes[i]);
    304355                        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)));
    307359                                return werr;
    308360                        }
     
    319371                                                         &obj->object.attribute_ctr.attributes[i]);
    320372                        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)));
    323376                                return werr;
    324377                        }
    325378                }
     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                }
    326389        }
    327390
    328391        return WERR_OK;
    329392}
    330 
    331393
    332394/*
     
    358420        active = (dsdb_dn_rmd_flags(dsdb_dn->dn) & DSDB_RMD_FLAG_DELETED) == 0;
    359421
     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        }
    360477        la->attid = sa->attributeID_id;
    361478        la->flags = active?DRSUAPI_DS_LINKED_ATTRIBUTE_FLAG_ACTIVE:0;
    362479
     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
    363505        status = dsdb_get_extended_dn_nttime(dsdb_dn->dn, &la->originating_add_time, "RMD_ADDTIME");
    364506        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;
    382509        }
    383510
     
    563690}
    564691
     692struct drsuapi_changed_objects {
     693        struct ldb_dn *dn;
     694        struct GUID guid;
     695        uint64_t usn;
     696};
    565697
    566698/*
    567699  sort the objects we send by tree order
    568700 */
    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);
     701static 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);
    572706}
    573707
     
    575709  sort the objects we send first by uSNChanged
    576710 */
    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;
     711static 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;
    592736}
    593737
     
    601745                                     struct drsuapi_DsGetNCChangesCtr6 *ctr6)
    602746{
    603         struct ldb_dn *rid_manager_dn, *fsmo_role_dn, *req_dn;
     747        struct ldb_dn *rid_manager_dn, *req_dn;
    604748        int ret;
    605749        struct ldb_context *ldb = b_state->sam_ctx;
    606750        struct ldb_result *ext_res;
    607         struct ldb_dn *base_dn;
    608751        struct dsdb_fsmo_extended_op *exop;
     752        bool is_us;
    609753
    610754        /*
     
    632776
    633777        /* 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);
    635779        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"));
    638781                ctr6->extended_ret = DRSUAPI_EXOP_ERR_FSMO_NOT_OWNER;
    639782                return WERR_DS_DRA_INTERNAL_ERROR;
    640783        }
    641784
    642         if (ldb_dn_compare(samdb_ntds_settings_dn(ldb), fsmo_role_dn) != 0) {
     785        if (!is_us) {
    643786                /* we're not the RID Manager - go away */
    644787                DEBUG(0,(__location__ ": RID Alloc request when not RID Manager\n"));
     
    685828
    686829        talloc_free(ext_res);
    687 
    688         base_dn = ldb_get_default_basedn(ldb);
    689830
    690831        DEBUG(2,("Allocated RID pool for server %s\n",
     
    802943                                       struct drsuapi_DsGetNCChangesRequest10 *req10,
    803944                                       struct dom_sid *user_sid,
    804                                        struct drsuapi_DsGetNCChangesCtr6 *ctr6)
     945                                       struct drsuapi_DsGetNCChangesCtr6 *ctr6,
     946                                       bool has_get_all_changes)
    805947{
    806948        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;
    808951        int ret;
    809952        const char *rodc_attrs[] = { "msDS-KrbTgtLink", "msDS-NeverRevealGroup", "msDS-RevealOnDemandGroup", NULL };
     
    817960
    818961        /*
    819          * we need to work out if we will allow this RODC to
     962         * we need to work out if we will allow this DC to
    820963         * replicate the secrets for this object
    821964         *
     
    828971                ctr6->extended_ret = DRSUAPI_EXOP_ERR_ACCESS_DENIED;
    829972                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;
    830997        }
    831998
     
    9011068        /* default deny */
    9021069denied:
    903         DEBUG(2,(__location__ ": Denied RODC secret replication for %s by RODC %s\n",
     1070        DEBUG(2,(__location__ ": Denied single object with secret replication for %s by RODC %s\n",
    9041071                 ldb_dn_get_linearized(obj_dn), ldb_dn_get_linearized(rodc_res->msgs[0]->dn)));
    9051072        ctr6->extended_ret = DRSUAPI_EXOP_ERR_NONE;
     
    9071074
    9081075allowed:
    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)));
    9111079        ctr6->extended_ret = DRSUAPI_EXOP_ERR_SUCCESS;
    9121080        req10->highwatermark.highest_usn = 0;
     
    9141082
    9151083failed:
    916         DEBUG(2,(__location__ ": Failed RODC secret replication for %s by RODC %s\n",
     1084        DEBUG(2,(__location__ ": Failed single secret replication for %s by RODC %s\n",
    9171085                 ldb_dn_get_linearized(obj_dn), dom_sid_string(mem_ctx, user_sid)));
    9181086        ctr6->extended_ret = DRSUAPI_EXOP_ERR_NONE;
     
    9361104
    9371105        ctr6->extended_ret = DRSUAPI_EXOP_ERR_SUCCESS;
    938         req10->highwatermark.highest_usn = 0;
    9391106        return WERR_OK;
    9401107}
     
    9511118                                         struct drsuapi_DsGetNCChangesCtr6 *ctr6)
    9521119{
    953         struct ldb_dn *fsmo_role_dn, *req_dn, *ntds_dn;
     1120        struct ldb_dn *req_dn, *ntds_dn;
    9541121        int ret;
    9551122        unsigned int i;
    9561123        struct ldb_context *ldb = b_state->sam_ctx;
    9571124        struct ldb_message *msg;
     1125        bool is_us;
    9581126
    9591127        /*
     
    9721140        }
    9731141
    974         /* retrieve the 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);
    9761144        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"));
    9791146                ctr6->extended_ret = DRSUAPI_EXOP_ERR_FSMO_NOT_OWNER;
    9801147                return WERR_DS_DRA_INTERNAL_ERROR;
    9811148        }
    9821149
    983         if (ldb_dn_compare(samdb_ntds_settings_dn(ldb), fsmo_role_dn) != 0) {
    984                 /* we're not the current owner - go away */
    985                 DEBUG(0,(__location__ ": FSMO transfer request when not owner\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"));
    9861153                ctr6->extended_ret = DRSUAPI_EXOP_ERR_FSMO_NOT_OWNER;
    9871154                return WERR_OK;
     
    9941161        W_ERROR_HAVE_NO_MEMORY(msg->dn);
    9951162
    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);
    9971165        if (ret != LDB_SUCCESS) {
    9981166                DEBUG(0, (__location__ ": Unable to find NTDS object for guid %s - %s\n",
    9991167                          GUID_string(mem_ctx, &req10->destination_dsa_guid), ldb_errstring(ldb)));
    10001168                talloc_free(msg);
    1001                 return WERR_DS_DRA_INTERNAL_ERROR;
     1169                ctr6->extended_ret = DRSUAPI_EXOP_ERR_UNKNOWN_CALLER;
     1170                return WERR_OK;
    10021171        }
    10031172
     
    10381207        return WERR_OK;
    10391208}
    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 };
    10571209
    10581210/*
     
    11131265        }
    11141266
     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 */
     1290static 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
    11151322        /* 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++) {
    11171324                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]);
    11191326                if (sa == NULL) {
    11201327                        return WERR_DS_DRA_SCHEMA_MISMATCH;
    11211328                }
    1122                 if (!dsdb_attr_in_rodc_fas(sa)) {
    1123                         *is_secret_request = true;
     1329                if (!sa->isMemberOfPartialAttributeSet) {
     1330                        *is_gc_pas_request = false;
    11241331                        return WERR_OK;
    11251332                }
    11261333        }
    11271334
    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;
    11291351        return WERR_OK;
    11301352}
     
    11621384
    11631385
     1386/**
     1387 * Collects object for normal replication cycle.
     1388 */
     1389static 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 */
     1452static 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
    11641471/*
    11651472  drsuapi_DsGetNCChanges
     
    11781485        NTSTATUS status;
    11791486        DATA_BLOB session_key;
    1180         const char *attrs[] = { "uSNChanged",
    1181                                 "objectGUID" ,
    1182                                 NULL };
    11831487        WERROR werr;
    11841488        struct dcesrv_handle *h;
     
    11981502        struct dom_sid *user_sid;
    11991503        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;
    12001511
    12011512        DCESRV_PULL_HANDLE_WERR(h, r->in.bind_handle, DRSUAPI_BIND_HANDLE);
     
    12031514
    12041515        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));
    12051518
    12061519        *r->out.level_out = 6;
     
    12601573        user_sid = &dce_call->conn->auth_state.session_info->security_token->sids[PRIMARY_USER_SID_INDEX];
    12611574
     1575        /* all clients must have GUID_DRS_GET_CHANGES */
    12621576        werr = drs_security_access_check_nc_root(b_state->sam_ctx,
    12631577                                                 mem_ctx,
     
    12671581        if (!W_ERROR_IS_OK(werr)) {
    12681582                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                }
    12691600        }
    12701601
     
    12811612                if (!W_ERROR_IS_OK(werr)) {
    12821613                        return werr;
    1283                 }
    1284         }
    1285 
     1614                } else {
     1615                        has_get_all_changes = true;
     1616                }
     1617        }
     1618
     1619allowed:
    12861620        /* for non-administrator replications, check that they have
    12871621           given the correct source_dsa_invocation_id */
     
    12991633                req10->uptodateness_vector = NULL;
    13001634        }
     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        }
    13011647
    13021648        getnc_state = b_state->getncchanges_state;
     
    13151661        }
    13161662
     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
    13171677        if (getnc_state == NULL) {
    13181678                getnc_state = talloc_zero(b_state, struct drsuapi_getncchanges_state);
     
    13271687                                     ldb_get_schema_basedn(b_state->sam_ctx));
    13281688                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                }
    13291693
    13301694                /*
     
    13431707                        break;
    13441708                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);
    13461713                        r->out.result = werr;
    13471714                        W_ERROR_NOT_OK_RETURN(werr);
     
    13921759
    13931760        if (getnc_state->guids == NULL) {
    1394                 char* search_filter;
    1395                 enum ldb_scope scope = LDB_SCOPE_SUBTREE;
    13961761                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;
    14031763
    14041764                extra_filter = lpcfg_parm_string(dce_call->conn->dce_ctx->lp_ctx, NULL, "drs", "object filter");
    14051765
    14061766                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);
    14441784                } 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);
    14491791
    14501792                /* extract out the GUIDs list */
    1451                 getnc_state->num_records = search_res->count;
     1793                getnc_state->num_records = search_res ? search_res->count : 0;
    14521794                getnc_state->guids = talloc_array(getnc_state, struct GUID, getnc_state->num_records);
    14531795                W_ERROR_HAVE_NO_MEMORY(getnc_state->guids);
    14541796
     1797                changes = talloc_array(getnc_state,
     1798                                       struct drsuapi_changed_objects,
     1799                                       getnc_state->num_records);
     1800                W_ERROR_HAVE_NO_MEMORY(changes);
     1801
    14551802                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;
    14571826                        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)));
    14591829                                return WERR_DS_DRA_INTERNAL_ERROR;
    14601830                        }
    14611831                }
    14621832
     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;
    14631836
    14641837                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);
    14731846        }
    14741847
     
    15171890        max_links = lpcfg_parm_int(dce_call->conn->dce_ctx->lp_ctx, NULL, "drs", "max link sync", 1500);
    15181891
     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);
    15191898        for (i=getnc_state->num_processed;
    15201899             i<getnc_state->num_records &&
    15211900                     !null_scope &&
    1522                      (r->out.ctr->ctr6.object_count < max_objects);
     1901                     (r->out.ctr->ctr6.object_count < max_objects)
     1902                     && !max_wait_reached;
    15231903            i++) {
    15241904                int uSN;
     
    15591939                msg = msg_res->msgs[0];
    15601940
     1941                max_wait_reached = (time(NULL) - start > max_wait);
     1942
    15611943                werr = get_nc_changes_build_object(obj, msg,
    15621944                                                   sam_ctx, getnc_state->ncRoot_dn,
     
    15651947                                                   req10->replica_flags,
    15661948                                                   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);
    15691952                if (!W_ERROR_IS_OK(werr)) {
    15701953                        return werr;
     
    15781961                                                &getnc_state->la_list,
    15791962                                                &getnc_state->la_count,
    1580                                                 getnc_state->uptodateness_vector);
     1963                                                req10->uptodateness_vector);
    15811964                if (!W_ERROR_IS_OK(werr)) {
    15821965                        return werr;
     
    15841967
    15851968                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                }
    15861981                if (uSN > r->out.ctr->ctr6.new_highwatermark.tmp_highest_usn) {
    15871982                        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;
    15911984                }
    15921985
     
    16041997                currentObject = &obj->next_object;
    16051998
     1999                DEBUG(8,(__location__ ": replicating object %s\n", ldb_dn_get_linearized(msg->dn)));
     2000
    16062001                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);
    16102003
    16112004                talloc_free(msg_res);
     
    16252018                         GUID_string(mem_ctx, &req10->destination_dsa_guid)));
    16262019                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);
    16302022                if (!ureq.dest_dsa_dns_name) {
    16312023                        return WERR_NOMEM;
     
    16432035                werr = drsuapi_UpdateRefs(b_state, mem_ctx, &ureq);
    16442036                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,
    16462039                                 win_errstr(werr)));
    16472040                }
     
    16892082                talloc_steal(mem_ctx, getnc_state->la_list);
    16902083
    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);
    16992087
    17002088                talloc_free(getnc_state);
    17012089                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;
    17022109        }
    17032110
     
    17062113                r->out.ctr->ctr6.nc_object_count = 0;
    17072114                ZERO_STRUCT(r->out.ctr->ctr6.new_highwatermark);
    1708                 r->out.ctr->ctr6.extended_ret = DRSUAPI_EXOP_ERR_SUCCESS;
    17092115        }
    17102116
  • vendor/current/source4/rpc_server/drsuapi/updaterefs.c

    r740 r988  
    5151
    5252        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)) {
    5555                        if (options & DRSUAPI_DRS_GETCHG_CHECK) {
    5656                                return WERR_OK;
     
    9898
    9999        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)) {
    101102                        if (i+1 < reps.count) {
    102103                                memmove(&reps.r[i], &reps.r[i+1], sizeof(reps.r[i])*(reps.count-(i+1)));
     
    121122}
    122123
    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 */
    126142WERROR drsuapi_UpdateRefs(struct drsuapi_bind_state *b_state, TALLOC_CTX *mem_ctx,
    127143                          struct drsuapi_DsReplicaUpdateRefsRequest1 *req)
    128144{
    129145        WERROR werr;
     146        int ret;
    130147        struct ldb_dn *dn;
     148        struct ldb_dn *nc_root;
    131149        struct ldb_context *sam_ctx = b_state->sam_ctx_system?b_state->sam_ctx_system:b_state->sam_ctx;
    132150
     
    136154                 drs_ObjectIdentifier_to_string(mem_ctx, req->naming_context)));
    137155
    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;
    141183        }
    142184
     
    144186                DEBUG(0,(__location__ ": Failed to start transaction on samdb: %s\n",
    145187                         ldb_errstring(sam_ctx)));
    146                 return WERR_DS_DRA_INTERNAL_ERROR;             
     188                return WERR_DS_DRA_INTERNAL_ERROR;
    147189        }
    148190
  • vendor/current/source4/rpc_server/drsuapi/writespn.c

    r740 r988  
    5858        krb5_error_code kerr;
    5959        krb5_principal principal;
     60        const krb5_data *component;
    6061        const char *dns_name, *dnsHostName;
    6162
     
    113114        }
    114115
    115         if (principal->name.name_string.len != 2) {
     116        if (krb5_princ_size(krb_ctx, principal) != 2) {
    116117                krb5_free_principal(krb_ctx, principal);
    117118                krb5_free_context(krb_ctx);
     
    120121        }
    121122
    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;
    123125
    124126        if (strcasecmp(dns_name, dnsHostName) != 0) {
     
    146148        struct drsuapi_bind_state *b_state;
    147149        struct dcesrv_handle *h;
    148         enum security_user_level level;
    149150
    150151        *r->out.level_out = r->in.level;
     
    155156        r->out.res = talloc(mem_ctx, union drsuapi_DsWriteAccountSpnResult);
    156157        W_ERROR_HAVE_NO_MEMORY(r->out.res);
    157 
    158         level = security_session_user_level(dce_call->conn->auth_state.session_info, NULL);
    159158
    160159        switch (r->in.level) {
  • vendor/current/source4/rpc_server/echo/rpc_echo.c

    r740 r988  
    2727#include "lib/events/events.h"
    2828
     29#define DCESRV_INTERFACE_RPCECHO_BIND(call, iface) \
     30       dcesrv_interface_rpcecho_bind(call, iface)
     31static 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}
    2936
    3037static NTSTATUS dcesrv_echo_AddOne(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx, struct echo_AddOne *r)
     
    193200        p->r            = r;
    194201
    195         event_add_timed(dce_call->event_ctx, p,
     202        tevent_add_timer(dce_call->event_ctx, p,
    196203                        timeval_add(&dce_call->time, r->in.seconds, 0),
    197204                        echo_TestSleep_handler, p);
  • vendor/current/source4/rpc_server/epmapper/rpc_epmapper.c

    r740 r988  
    2525#include "rpc_server/dcerpc_server.h"
    2626
     27#define DCESRV_INTERFACE_EPMAPPER_BIND(call, iface) \
     28       dcesrv_interface_epmapper_bind(call, iface)
     29static 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
    2735typedef uint32_t error_status_t;
    2836
     
    5159        for (d=endpoint_list; d; d=d->next) {
    5260                struct dcesrv_if_list *iface;
    53                 struct dcerpc_binding *description;
    5461
    5562                for (iface=d->interface_list;iface;iface=iface->next) {
     63                        struct dcerpc_binding *description;
     64
    5665                        (*eps) = talloc_realloc(mem_ctx,
    5766                                                  *eps,
     
    6372                        (*eps)[total].name = iface->iface.name;
    6473
    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                        }
    6784
    6885                        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)));
    7190                                continue;
    7291                        }
     
    202221
    203222        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) {
    206225                goto failed;
    207226        }
  • vendor/current/source4/rpc_server/handles.c

    r740 r988  
    4747        sid = &context->conn->auth_state.session_info->security_token->sids[PRIMARY_USER_SID_INDEX];
    4848
    49         h = talloc(context->assoc_group, struct dcesrv_handle);
     49        h = talloc_zero(context->conn->assoc_group, struct dcesrv_handle);
    5050        if (!h) {
    5151                return NULL;
     
    5757                return NULL;
    5858        }
    59         h->assoc_group = context->assoc_group;
     59        h->assoc_group = context->conn->assoc_group;
    6060        h->iface = context->iface;
    6161        h->wire_handle.handle_type = handle_type;
    6262        h->wire_handle.uuid = GUID_random();
    6363       
    64         DLIST_ADD(context->assoc_group->handles, h);
     64        DLIST_ADD(context->conn->assoc_group->handles, h);
    6565
    6666        talloc_set_destructor(h, dcesrv_handle_destructor);
     
    8383        sid = &context->conn->auth_state.session_info->security_token->sids[PRIMARY_USER_SID_INDEX];
    8484
    85         if (policy_handle_empty(p)) {
     85        if (ndr_policy_handle_empty(p)) {
    8686                /* TODO: we should probably return a NULL handle here */
    8787                return dcesrv_handle_new(context, handle_type);
    8888        }
    8989
    90         for (h=context->assoc_group->handles; h; h=h->next) {
     90        for (h=context->conn->assoc_group->handles; h; h=h->next) {
    9191                if (h->wire_handle.handle_type == p->handle_type &&
    9292                    GUID_equal(&p->uuid, &h->wire_handle.uuid)) {
  • vendor/current/source4/rpc_server/lsa/dcesrv_lsa.c

    r740 r988  
    88   Copyright (C) Andrew Tridgell 2004
    99   Copyright (C) Andrew Bartlett <abartlet@samba.org> 2004-2008
    10    
     10
    1111   This program is free software; you can redistribute it and/or modify
    1212   it under the terms of the GNU General Public License as published by
    1313   the Free Software Foundation; either version 3 of the License, or
    1414   (at your option) any later version.
    15    
     15
    1616   This program is distributed in the hope that it will be useful,
    1717   but WITHOUT ANY WARRANTY; without even the implied warranty of
    1818   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    1919   GNU General Public License for more details.
    20    
     20
    2121   You should have received a copy of the GNU General Public License
    2222   along with this program.  If not, see <http://www.gnu.org/licenses/>.
     
    3232#include "dsdb/common/util.h"
    3333#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)
     40static 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}
    3545
    3646/*
     
    7383  It uses the same logic, but with samba4 helper functions
    7484 */
    75 static NTSTATUS dcesrv_build_lsa_sd(TALLOC_CTX *mem_ctx, 
     85static NTSTATUS dcesrv_build_lsa_sd(TALLOC_CTX *mem_ctx,
    7686                                    struct security_descriptor **sd,
    77                                     struct dom_sid *sid, 
     87                                    struct dom_sid *sid,
    7888                                    uint32_t sid_access)
    7989{
     
    8595
    8696        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        }
    88101
    89102        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        }
    91107
    92108        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
    95114        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
    98120        *sd = security_descriptor_dacl_create(mem_ctx,
    99121                                              0, sidstr, NULL,
     
    102124                                              SEC_ACE_TYPE_ACCESS_ALLOWED,
    103125                                              SEC_GENERIC_EXECUTE | SEC_GENERIC_READ, 0,
    104                                              
     126
    105127                                              SID_BUILTIN_ADMINISTRATORS,
    106128                                              SEC_ACE_TYPE_ACCESS_ALLOWED,
    107129                                              SEC_GENERIC_ALL, 0,
    108                                              
     130
    109131                                              SID_BUILTIN_ACCOUNT_OPERATORS,
    110132                                              SEC_ACE_TYPE_ACCESS_ALLOWED,
    111133                                              SEC_GENERIC_ALL, 0,
    112                                              
     134
    113135                                              domain_admins_sid_str,
    114136                                              SEC_ACE_TYPE_ACCESS_ALLOWED,
     
    128150
    129151
    130 static NTSTATUS dcesrv_lsa_EnumAccountRights(struct dcesrv_call_state *dce_call, 
     152static NTSTATUS dcesrv_lsa_EnumAccountRights(struct dcesrv_call_state *dce_call,
    131153                                      TALLOC_CTX *mem_ctx,
    132154                                      struct lsa_EnumAccountRights *r);
    133155
    134 static NTSTATUS dcesrv_lsa_AddRemoveAccountRights(struct dcesrv_call_state *dce_call, 
     156static NTSTATUS dcesrv_lsa_AddRemoveAccountRights(struct dcesrv_call_state *dce_call,
    135157                                           TALLOC_CTX *mem_ctx,
    136158                                           struct lsa_policy_state *state,
     
    139161                                           const struct lsa_RightSet *rights);
    140162
    141 /* 
    142   lsa_Close 
     163/*
     164  lsa_Close
    143165*/
    144166static NTSTATUS dcesrv_lsa_Close(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
    145167                          struct lsa_Close *r)
    146168{
     169        enum dcerpc_transport_t transport =
     170                dcerpc_binding_get_transport(dce_call->conn->endpoint->ep_description);
    147171        struct dcesrv_handle *h;
    148172
     173        if (transport != NCACN_NP && transport != NCALRPC) {
     174                DCESRV_FAULT(DCERPC_FAULT_ACCESS_DENIED);
     175        }
     176
    149177        *r->out.handle = *r->in.handle;
    150178
     
    159187
    160188
    161 /* 
    162   lsa_Delete 
     189/*
     190  lsa_Delete
    163191*/
    164192static NTSTATUS dcesrv_lsa_Delete(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
     
    169197
    170198
    171 /* 
     199/*
    172200  lsa_DeleteObject
    173201*/
     
    194222                }
    195223
    196                 ret = ldb_delete(secret_state->sam_ldb, 
     224                ret = ldb_delete(secret_state->sam_ldb,
    197225                                 secret_state->secret_dn);
    198226                if (ret != LDB_SUCCESS) {
     
    205233
    206234        } 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 =
    208236                        talloc_get_type(h->data, struct lsa_trusted_domain_state);
    209237                ret = ldb_transaction_start(trusted_domain_state->policy->sam_ldb);
     
    212240                }
    213241
    214                 ret = ldb_delete(trusted_domain_state->policy->sam_ldb, 
     242                ret = ldb_delete(trusted_domain_state->policy->sam_ldb,
    215243                                 trusted_domain_state->trusted_domain_dn);
    216244                if (ret != LDB_SUCCESS) {
     
    220248
    221249                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,
    223251                                         trusted_domain_state->trusted_domain_user_dn);
    224252                        if (ret != LDB_SUCCESS) {
     
    246274
    247275                DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_ACCOUNT);
    248                
     276
    249277                astate = h->data;
    250278
     
    265293                }
    266294
    267                 status = dcesrv_lsa_AddRemoveAccountRights(dce_call, mem_ctx, astate->policy, 
     295                status = dcesrv_lsa_AddRemoveAccountRights(dce_call, mem_ctx, astate->policy,
    268296                                                    LDB_FLAG_MOD_DELETE, astate->account_sid,
    269297                                                    r2.out.rights);
     
    279307
    280308                return NT_STATUS_OK;
    281         } 
    282        
     309        }
     310
    283311        return NT_STATUS_INVALID_HANDLE;
    284312}
    285313
    286314
    287 /* 
    288   lsa_EnumPrivs 
     315/*
     316  lsa_EnumPrivs
    289317*/
    290318static NTSTATUS dcesrv_lsa_EnumPrivs(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
     
    292320{
    293321        struct dcesrv_handle *h;
    294         struct lsa_policy_state *state;
    295322        uint32_t i;
    296323        enum sec_privilege priv;
     
    298325
    299326        DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
    300 
    301         state = h->data;
    302327
    303328        i = *r->in.resume_handle;
     
    308333                privname = sec_privilege_name(priv);
    309334                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,
    312337                                                       r->out.privs->count+1);
    313338                if (r->out.privs->privs == NULL) {
     
    328353
    329354
    330 /* 
    331   lsa_QuerySecObj 
     355/*
     356  lsa_QuerySecObj
    332357*/
    333358static NTSTATUS dcesrv_lsa_QuerySecurity(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
     
    335360{
    336361        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;
    338365        NTSTATUS status;
    339366        struct dom_sid *sid;
     
    344371
    345372        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,
    349383                                             LSA_ACCOUNT_ALL_ACCESS);
     384                if (!NT_STATUS_IS_OK(status)) {
     385                        return status;
     386                }
     387                sd = _sd;
     388                access_granted = astate->access_mask;
    350389        } else {
    351390                return NT_STATUS_INVALID_HANDLE;
    352391        }
    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
    360406        return NT_STATUS_OK;
    361407}
    362408
    363409
    364 /* 
    365   lsa_SetSecObj 
     410/*
     411  lsa_SetSecObj
    366412*/
    367413static NTSTATUS dcesrv_lsa_SetSecObj(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
     
    372418
    373419
    374 /* 
    375   lsa_ChangePassword 
     420/*
     421  lsa_ChangePassword
    376422*/
    377423static NTSTATUS dcesrv_lsa_ChangePassword(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
     
    381427}
    382428
    383 /* 
    384   dssetup_DsRoleGetPrimaryDomainInformation 
     429/*
     430  dssetup_DsRoleGetPrimaryDomainInformation
    385431
    386432  This is not an LSA call, but is the only call left on the DSSETUP
    387433  pipe (after the pipe was truncated), and needs lsa_get_policy_state
    388434*/
    389 static WERROR dcesrv_dssetup_DsRoleGetPrimaryDomainInformation(struct dcesrv_call_state *dce_call, 
     435static WERROR dcesrv_dssetup_DsRoleGetPrimaryDomainInformation(struct dcesrv_call_state *dce_call,
    390436                                                 TALLOC_CTX *mem_ctx,
    391437                                                 struct dssetup_DsRoleGetPrimaryDomainInformation *r)
     
    407453                struct lsa_policy_state *state;
    408454
    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);
    410458                if (!NT_STATUS_IS_OK(status)) {
    411459                        return ntstatus_to_werror(status);
     
    421469                        role            = DS_ROLE_MEMBER_SERVER;
    422470                        break;
    423                 case ROLE_DOMAIN_CONTROLLER:
     471                case ROLE_ACTIVE_DIRECTORY_DC:
    424472                        if (samdb_is_pdc(state->sam_ldb)) {
    425473                                role    = DS_ROLE_PRIMARY_DC;
     
    440488                        /* TODO: what is with dns_domain and forest and guid? */
    441489                        break;
    442                 case ROLE_DOMAIN_CONTROLLER:
     490                case ROLE_ACTIVE_DIRECTORY_DC:
    443491                        flags           = DS_ROLE_PRIMARY_DS_RUNNING;
    444492
     
    446494                                flags   |= DS_ROLE_PRIMARY_DS_MIXED_MODE;
    447495                        }
    448                        
     496
    449497                        domain          = state->domain_name;
    450498                        dns_domain      = state->domain_dns;
     
    456504                }
    457505
    458                 info->basic.role        = role; 
     506                info->basic.role        = role;
    459507                info->basic.flags       = flags;
    460508                info->basic.domain      = domain;
     
    513561}
    514562
    515 /* 
     563/*
    516564  lsa_QueryInfoPolicy2
    517565*/
     
    584632}
    585633
    586 /* 
    587   lsa_QueryInfoPolicy 
     634/*
     635  lsa_QueryInfoPolicy
    588636*/
    589637static NTSTATUS dcesrv_lsa_QueryInfoPolicy(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
     
    598646        r2.in.level = r->in.level;
    599647        r2.out.info = r->out.info;
    600        
     648
    601649        status = dcesrv_lsa_QueryInfoPolicy2(dce_call, mem_ctx, &r2);
    602650
     
    604652}
    605653
    606 /* 
    607   lsa_SetInfoPolicy 
     654/*
     655  lsa_SetInfoPolicy
    608656*/
    609657static NTSTATUS dcesrv_lsa_SetInfoPolicy(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
     
    615663
    616664
    617 /* 
    618   lsa_ClearAuditLog 
     665/*
     666  lsa_ClearAuditLog
    619667*/
    620668static NTSTATUS dcesrv_lsa_ClearAuditLog(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
     
    625673
    626674
    627 /*
    628   lsa_CreateAccount
     675static 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
    629684
    630685  This call does not seem to have any long-term effects, hence no database operations
     
    661716                return NT_STATUS_NO_MEMORY;
    662717        }
    663        
     718
    664719        astate->policy = talloc_reference(astate, state);
    665720        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));
    666737
    667738        ah = dcesrv_handle_new(dce_call->context, LSA_HANDLE_ACCOUNT);
     
    679750
    680751
    681 /* 
    682   lsa_EnumAccounts 
     752/*
     753  lsa_EnumAccounts
    683754*/
    684755static NTSTATUS dcesrv_lsa_EnumAccounts(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
     
    697768
    698769        /* NOTE: This call must only return accounts that have at least
    699            one privilege set 
     770           one privilege set
    700771        */
    701         ret = gendb_search(state->pdb, mem_ctx, NULL, &res, attrs, 
     772        ret = gendb_search(state->pdb, mem_ctx, NULL, &res, attrs,
    702773                           "(&(objectSid=*)(privilege=*))");
    703774        if (ret < 0) {
     
    724795
    725796        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,
    728799                                             res[i + *r->in.resume_handle],
    729800                                             "objectSid");
     
    735806
    736807        return NT_STATUS_OK;
    737        
    738808}
    739809
     
    770840        enum ndr_err_code ndr_err;
    771841
     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
    772887        ndr_err = ndr_push_struct_blob(trustauth_blob, mem_ctx,
    773888                                       iopw,
     
    787902                               struct ldb_dn **user_dn)
    788903{
     904        struct ldb_request *req;
    789905        struct ldb_message *msg;
    790906        struct ldb_dn *dn;
     
    847963
    848964        /* 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);
    850978        if (ret != LDB_SUCCESS) {
    851979                DEBUG(0,("Failed to create user record %s: %s\n",
     
    8751003                                                    TALLOC_CTX *mem_ctx,
    8761004                                                    struct lsa_CreateTrustedDomainEx2 *r,
    877                                                     int op)
     1005                                                    int op,
     1006                                                    struct lsa_TrustDomainInfoAuthInfo *unencrypted_auth_info)
    8781007{
    8791008        struct dcesrv_handle *policy_handle;
     
    8871016        const char *netbios_name;
    8881017        const char *dns_name;
    889         const char *name;
    8901018        DATA_BLOB trustAuthIncoming, trustAuthOutgoing, auth_blob;
    8911019        struct trustDomainPasswords auth_struct;
     
    8931021        NTSTATUS nt_status;
    8941022        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;
    8951033
    8961034        DCESRV_PULL_HANDLE(policy_handle, r->in.policy_handle, LSA_HANDLE_POLICY);
     
    9061044
    9071045        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        }
    9081103
    9091104        trusted_domain_state = talloc_zero(mem_ctx, struct lsa_trusted_domain_state);
     
    9141109
    9151110        if (strcasecmp(netbios_name, "BUILTIN") == 0
    916             || (dns_name && strcasecmp(dns_name, "BUILTIN") == 0)
     1111            || (strcasecmp(dns_name, "BUILTIN") == 0)
    9171112            || (dom_sid_in_domain(policy_state->builtin_sid, r->in.info->sid))) {
    9181113                return NT_STATUS_INVALID_PARAMETER;
     
    9211116        if (strcasecmp(netbios_name, policy_state->domain_name) == 0
    9221117            || 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
    9251120            || (dom_sid_equal(policy_state->domain_sid, r->in.info->sid))) {
    9261121                return NT_STATUS_CURRENT_DOMAIN_NOT_ALLOWED;
     
    9321127                auth_struct.outgoing.count = 0;
    9331128                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);
    9371132                nt_status = get_trustdom_auth_blob(dce_call, mem_ctx,
    9381133                                                   &auth_blob, &auth_struct);
     
    9401135                        return nt_status;
    9411136                }
    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;
    9481149        }
    9491150
     
    9751176        }
    9761177
    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) {
    10031193                ldb_transaction_cancel(sam_ldb);
    10041194                return NT_STATUS_INTERNAL_DB_CORRUPTION;
    10051195        }
    10061196
    1007         name = dns_name ? dns_name : netbios_name;
    1008 
    10091197        msg = ldb_msg_new(mem_ctx);
    10101198        if (msg == NULL) {
     
    10131201
    10141202        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)) {
    10161204                        ldb_transaction_cancel(sam_ldb);
    10171205                return NT_STATUS_NO_MEMORY;
    10181206        }
    10191207
    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;;
    10401249        }
    10411250
     
    11051314        }
    11061315
     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
    11071336        handle = dcesrv_handle_new(dce_call->context, LSA_HANDLE_TRUSTED_DOMAIN);
    11081337        if (!handle) {
     
    11271356                                           struct lsa_CreateTrustedDomainEx2 *r)
    11281357{
    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);
    11301359}
    11311360/*
     
    11401369        r2.in.policy_handle = r->in.policy_handle;
    11411370        r2.in.info = r->in.info;
    1142         r2.in.auth_info = r->in.auth_info;
    11431371        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
    11491377*/
    11501378static NTSTATUS dcesrv_lsa_CreateTrustedDomain(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
     
    11591387        }
    11601388
    1161         r2.in.info->domain_name.string = NULL;
     1389        r2.in.info->domain_name = r->in.info->name;
    11621390        r2.in.info->netbios_name = r->in.info->name;
    11631391        r2.in.info->sid = r->in.info->sid;
     
    11651393        r2.in.info->trust_type = LSA_TRUST_TYPE_DOWNLEVEL;
    11661394        r2.in.info->trust_attributes = 0;
    1167        
     1395
    11681396        r2.in.access_mask = r->in.access_mask;
    11691397        r2.out.trustdom_handle = r->out.trustdom_handle;
    11701398
    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
     1402static 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{
    11841410        struct lsa_trusted_domain_state *trusted_domain_state;
    11851411        struct dcesrv_handle *handle;
     
    11901416                NULL
    11911417        };
    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*/
     1487static 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;
    11931493        const char *sid_string;
    1194         int ret;
     1494        char *filter;
     1495        NTSTATUS status;
    11951496
    11961497        DCESRV_PULL_HANDLE(policy_handle, r->in.handle, LSA_HANDLE_POLICY);
     
    11981499        policy_state = policy_handle->data;
    11991500
    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 
    12061501        sid_string = dom_sid_string(mem_ctx, r->in.sid);
    12071502        if (!sid_string) {
     
    12091504        }
    12101505
    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
    12511523        *r->out.trustdom_handle = handle->wire_handle;
    1252        
     1524
    12531525        return NT_STATUS_OK;
    12541526}
     
    12631535{
    12641536        struct dcesrv_handle *policy_handle;
    1265 
    12661537        struct lsa_policy_state *policy_state;
    1267         struct lsa_trusted_domain_state *trusted_domain_state;
    12681538        struct dcesrv_handle *handle;
    1269         struct ldb_message **msgs;
    1270         const char *attrs[] = {
    1271                 NULL
    1272         };
    12731539        char *td_name;
    1274         int ret;
     1540        char *filter;
     1541        NTSTATUS status;
    12751542
    12761543        DCESRV_PULL_HANDLE(policy_handle, r->in.handle, LSA_HANDLE_POLICY);
     
    12821549        }
    12831550
    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 
    12901551        /* search for the trusted_domain record */
    12911552        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,
    12941558                           "(&(|(flatname=%s)(cn=%s)(trustPartner=%s))"
    12951559                             "(objectclass=trustedDomain))",
    12961560                           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        }
    13201573
    13211574        *r->out.trustdom_handle = handle->wire_handle;
     
    13261579
    13271580
    1328 /* 
     1581/*
    13291582  lsa_SetTrustedDomainInfo
    13301583*/
     
    13481601                                "trustType", "trustAttributes",
    13491602                                "trustPosixOffset",
    1350                                 "msDs-supportedEncryptionTypes", NULL };
     1603                                "msDs-supportedEncryptionTypes",
     1604                                "msDS-TrustForestTrustInfo",
     1605                                NULL
     1606        };
    13511607        char *dns = NULL;
    13521608        char *nbn = NULL;
     
    14301686        const struct ldb_val *orig_val;
    14311687        uint32_t orig_uint = 0;
    1432         int flags = 0;
     1688        unsigned int flags = 0;
    14331689        int ret;
    14341690
     
    15201776
    15211777        /* entry exists, just modify secret if any */
    1522         if (in->count == 0) {
     1778        if (in == NULL || in->count == 0) {
    15231779                return NT_STATUS_OK;
    15241780        }
     
    15821838
    15831839static NTSTATUS setInfoTrustedDomain_base(struct dcesrv_call_state *dce_call,
    1584                                           struct dcesrv_handle *p_handle,
     1840                                          struct lsa_policy_state *p_state,
    15851841                                          TALLOC_CTX *mem_ctx,
    15861842                                          struct ldb_message *dom_msg,
     
    15881844                                          union lsa_TrustedDomainInfo *info)
    15891845{
    1590         struct lsa_policy_state *p_state = p_handle->data;
    15911846        uint32_t *posix_offset = NULL;
    15921847        struct lsa_TrustDomainInfoInfoEx *info_ex = NULL;
     
    15961851        DATA_BLOB trustAuthIncoming, trustAuthOutgoing, auth_blob;
    15971852        struct trustDomainPasswords auth_struct;
     1853        struct trustAuthInOutBlob *current_passwords = NULL;
    15981854        NTSTATUS nt_status;
    15991855        struct ldb_message **msgs;
     
    16031859        bool del_outgoing = false;
    16041860        bool del_incoming = false;
     1861        bool del_forest_info = false;
    16051862        bool in_transaction = false;
    16061863        int ret;
     
    16381895
    16391896        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                                                                &current_passwords);
     1910                        if (!NT_STATUS_IS_OK(nt_status)) {
     1911                                return nt_status;
     1912                        }
     1913                }
    16421914        }
    16431915
     
    16901962        /* TODO: should we fetch previous values from the existing entry
    16911963         * and append them ? */
    1692         if (auth_struct.incoming.count) {
     1964        if (auth_info_int && auth_struct.incoming.count) {
    16931965                nt_status = get_trustauth_inout_blob(dce_call, mem_ctx,
    16941966                                                     &auth_struct.incoming,
     
    16971969                        return nt_status;
    16981970                }
     1971
     1972                current_passwords = &auth_struct.incoming;
     1973
    16991974        } else {
    17001975                trustAuthIncoming = data_blob(NULL, 0);
    17011976        }
    17021977
    1703         if (auth_struct.outgoing.count) {
     1978        if (auth_info_int && auth_struct.outgoing.count) {
    17041979                nt_status = get_trustauth_inout_blob(dce_call, mem_ctx,
    17051980                                                     &auth_struct.outgoing,
     
    17302005        if (info_ex) {
    17312006                uint32_t origattrs;
     2007                uint32_t changed_attrs;
    17322008                uint32_t origdir;
    1733                 uint32_t tmp;
    17342009                int origtype;
    17352010
     
    17432018                }
    17442019
    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) {
    17502022                                add_incoming = true;
    17512023                        }
    17522024                }
    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) {
    17572027                                add_outgoing = true;
    17582028                        }
     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;
    17592038                }
    17602039
     
    17762055                /* TODO: check forestFunctionality from ldb opaque */
    17772056                /* 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));
    17832071                        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                        }
    17842084                }
    17852085        }
     
    17952095        }
    17962096
    1797         if (add_incoming && trustAuthIncoming.data) {
     2097        if (add_incoming || del_incoming) {
    17982098                ret = ldb_msg_add_empty(msg, "trustAuthIncoming",
    17992099                                        LDB_FLAG_MOD_REPLACE, NULL);
     
    18012101                        return NT_STATUS_NO_MEMORY;
    18022102                }
    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",
    18112113                                        LDB_FLAG_MOD_REPLACE, NULL);
    18122114                if (ret != LDB_SUCCESS) {
    18132115                        return NT_STATUS_NO_MEMORY;
    18142116                }
    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);
    18172128                if (ret != LDB_SUCCESS) {
    18182129                        return NT_STATUS_NO_MEMORY;
     
    18272138        in_transaction = true;
    18282139
    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                }
    18402149        }
    18412150
     
    18502159                }
    18512160
     2161                /* We use trustAuthIncoming.data to incidate that auth_struct.incoming is valid */
    18522162                nt_status = update_trust_user(mem_ctx,
    18532163                                              p_state->sam_ldb,
     
    18552165                                              del_incoming,
    18562166                                              netbios_name,
    1857                                               &auth_struct.incoming);
     2167                                              current_passwords);
    18582168                if (!NT_STATUS_IS_OK(nt_status)) {
    18592169                        goto done;
     
    19072217        }
    19082218
    1909         return setInfoTrustedDomain_base(dce_call, h, mem_ctx,
     2219        return setInfoTrustedDomain_base(dce_call, td_state->policy, mem_ctx,
    19102220                                         msgs[0], r->in.level, r->in.info);
    19112221}
    19122222
    19132223
    1914 /* 
     2224/*
    19152225  lsa_DeleteTrustedDomain
    19162226*/
     
    19192229{
    19202230        NTSTATUS status;
    1921         struct lsa_OpenTrustedDomain opn;
     2231        struct lsa_OpenTrustedDomain opn = {{0},{0}};
    19222232        struct lsa_DeleteObject del;
    19232233        struct dcesrv_handle *h;
     
    19472257}
    19482258
    1949 static NTSTATUS fill_trust_domain_ex(TALLOC_CTX *mem_ctx, 
    1950                                      struct ldb_message *msg, 
    1951                                      struct lsa_TrustDomainInfoInfoEx *info_ex) 
     2259static NTSTATUS fill_trust_domain_ex(TALLOC_CTX *mem_ctx,
     2260                                     struct ldb_message *msg,
     2261                                     struct lsa_TrustDomainInfoInfoEx *info_ex)
    19522262{
    19532263        info_ex->domain_name.string
     
    19552265        info_ex->netbios_name.string
    19562266                = ldb_msg_find_attr_as_string(msg, "flatname", NULL);
    1957         info_ex->sid 
     2267        info_ex->sid
    19582268                = samdb_result_dom_sid(mem_ctx, msg, "securityIdentifier");
    19592269        info_ex->trust_direction
     
    19622272                = ldb_msg_find_attr_as_int(msg, "trustType", 0);
    19632273        info_ex->trust_attributes
    1964                 = ldb_msg_find_attr_as_int(msg, "trustAttributes", 0); 
     2274                = ldb_msg_find_attr_as_int(msg, "trustAttributes", 0);
    19652275        return NT_STATUS_OK;
    19662276}
    19672277
    1968 /* 
     2278/*
    19692279  lsa_QueryTrustedDomainInfo
    19702280*/
     
    19792289        struct ldb_message **res;
    19802290        const char *attrs[] = {
    1981                 "flatname", 
     2291                "flatname",
    19822292                "trustPartner",
    19832293                "securityIdentifier",
    19842294                "trustDirection",
    19852295                "trustType",
    1986                 "trustAttributes", 
     2296                "trustAttributes",
    19872297                "msDs-supportedEncryptionTypes",
    19882298                NULL
     
    20002310        }
    20012311        msg = res[0];
    2002        
     2312
    20032313        info = talloc_zero(mem_ctx, union lsa_TrustedDomainInfo);
    20042314        if (!info) {
     
    20182328#if 0  /* Win2k3 doesn't implement this */
    20192329        case LSA_TRUSTED_DOMAIN_INFO_BASIC:
    2020                 r->out.info->info_basic.netbios_name.string 
     2330                r->out.info->info_basic.netbios_name.string
    20212331                        = ldb_msg_find_attr_as_string(msg, "flatname", NULL);
    20222332                r->out.info->info_basic.sid
     
    20352345                        = ldb_msg_find_attr_as_uint(msg, "posixOffset", 0);
    20362346                return fill_trust_domain_ex(mem_ctx, msg, &info->full_info2_internal.info.info_ex);
    2037                
     2347
    20382348        case LSA_TRUSTED_DOMAIN_SUPPORTED_ENCRYPTION_TYPES:
    20392349                info->enc_types.enc_types
     
    20582368
    20592369
    2060 /* 
     2370/*
    20612371  lsa_QueryTrustedDomainInfoBySid
    20622372*/
     
    20652375{
    20662376        NTSTATUS status;
    2067         struct lsa_OpenTrustedDomain opn;
     2377        struct lsa_OpenTrustedDomain opn = {{0},{0}};
    20682378        struct lsa_QueryTrustedDomainInfo query;
    20692379        struct dcesrv_handle *h;
     
    21252435        }
    21262436
    2127         return setInfoTrustedDomain_base(dce_call, policy_handle, mem_ctx,
     2437        return setInfoTrustedDomain_base(dce_call, policy_state, mem_ctx,
    21282438                                         msgs[0], r->in.level, r->in.info);
    21292439}
    21302440
    2131 /* 
     2441/*
    21322442   lsa_QueryTrustedDomainInfoByName
    21332443*/
     
    21372447{
    21382448        NTSTATUS status;
    2139         struct lsa_OpenTrustedDomainByName opn;
     2449        struct lsa_OpenTrustedDomainByName opn = {{0},{0}};
    21402450        struct lsa_QueryTrustedDomainInfo query;
    21412451        struct dcesrv_handle *h;
     
    21522462                return status;
    21532463        }
    2154        
     2464
    21552465        /* Ensure this handle goes away at the end of this call */
    21562466        DCESRV_PULL_HANDLE(h, opn.out.trustdom_handle, DCESRV_HANDLE_ANY);
     
    21642474                return status;
    21652475        }
    2166        
     2476
    21672477        return NT_STATUS_OK;
    21682478}
    21692479
    21702480/*
    2171   lsa_CloseTrustedDomainEx 
     2481  lsa_CloseTrustedDomainEx
    21722482*/
    21732483static NTSTATUS dcesrv_lsa_CloseTrustedDomainEx(struct dcesrv_call_state *dce_call,
     
    21902500}
    21912501
    2192 /* 
    2193   lsa_EnumTrustDom 
     2502/*
     2503  lsa_EnumTrustDom
    21942504*/
    21952505static NTSTATUS dcesrv_lsa_EnumTrustDom(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
     
    22012511        struct ldb_message **domains;
    22022512        const char *attrs[] = {
    2203                 "flatname", 
     2513                "flatname",
    22042514                "securityIdentifier",
    22052515                NULL
     
    22182528        policy_state = policy_handle->data;
    22192529
    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
    22212531           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,
    22232533                             "objectclass=trustedDomain");
    22242534        if (count < 0) {
     
    22452555        }
    22462556
    2247         /* return the rest, limit by max_size. Note that we 
     2557        /* return the rest, limit by max_size. Note that we
    22482558           use the w2k3 element size value of 60 */
    22492559        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,
    22512561                                 1+(r->in.max_size/LSA_ENUM_TRUST_DOMAIN_MULTIPLIER));
    22522562
     
    22792589}
    22802590
    2281 /* 
    2282   lsa_EnumTrustedDomainsEx 
     2591/*
     2592  lsa_EnumTrustedDomainsEx
    22832593*/
    22842594static NTSTATUS dcesrv_lsa_EnumTrustedDomainsEx(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
     
    22902600        struct ldb_message **domains;
    22912601        const char *attrs[] = {
    2292                 "flatname", 
     2602                "flatname",
    22932603                "trustPartner",
    22942604                "securityIdentifier",
    22952605                "trustDirection",
    22962606                "trustType",
    2297                 "trustAttributes", 
     2607                "trustAttributes",
    22982608                NULL
    22992609        };
     
    23112621        policy_state = policy_handle->data;
    23122622
    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
    23142624           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,
    23162626                             "objectclass=trustedDomain");
    23172627        if (count < 0) {
     
    23402650        }
    23412651
    2342         /* return the rest, limit by max_size. Note that we 
     2652        /* return the rest, limit by max_size. Note that we
    23432653           use the w2k3 element size value of 60 */
    23442654        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,
    23462656                                 1+(r->in.max_size/LSA_ENUM_TRUST_DOMAIN_EX_MULTIPLIER));
    23472657
     
    23542664        }
    23552665
     2666        *r->out.resume_handle = *r->in.resume_handle + r->out.domains->count;
     2667
    23562668        return NT_STATUS_OK;
    23572669}
    23582670
    23592671
    2360 /* 
    2361   lsa_OpenAccount 
     2672/*
     2673  lsa_OpenAccount
    23622674*/
    23632675static NTSTATUS dcesrv_lsa_OpenAccount(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
     
    23842696                return NT_STATUS_NO_MEMORY;
    23852697        }
    2386        
     2698
    23872699        astate->policy = talloc_reference(astate, state);
    23882700        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));
    23892717
    23902718        ah = dcesrv_handle_new(dce_call->context, LSA_HANDLE_ACCOUNT);
     
    24022730
    24032731
    2404 /* 
    2405   lsa_EnumPrivsAccount 
    2406 */
    2407 static NTSTATUS dcesrv_lsa_EnumPrivsAccount(struct dcesrv_call_state *dce_call, 
     2732/*
     2733  lsa_EnumPrivsAccount
     2734*/
     2735static NTSTATUS dcesrv_lsa_EnumPrivsAccount(struct dcesrv_call_state *dce_call,
    24082736                                     TALLOC_CTX *mem_ctx,
    24092737                                     struct lsa_EnumPrivsAccount *r)
     
    24382766        }
    24392767
    2440         ret = gendb_search(astate->policy->pdb, mem_ctx, NULL, &res, attrs, 
     2768        ret = gendb_search(astate->policy->pdb, mem_ctx, NULL, &res, attrs,
    24412769                           "objectSid=%s", sidstr);
    24422770        if (ret < 0) {
     
    24762804}
    24772805
    2478 /* 
    2479   lsa_EnumAccountRights 
    2480 */
    2481 static NTSTATUS dcesrv_lsa_EnumAccountRights(struct dcesrv_call_state *dce_call, 
     2806/*
     2807  lsa_EnumAccountRights
     2808*/
     2809static NTSTATUS dcesrv_lsa_EnumAccountRights(struct dcesrv_call_state *dce_call,
    24822810                                      TALLOC_CTX *mem_ctx,
    24832811                                      struct lsa_EnumAccountRights *r)
     
    25012829        }
    25022830
    2503         ret = gendb_search(state->pdb, mem_ctx, NULL, &res, attrs, 
     2831        ret = gendb_search(state->pdb, mem_ctx, NULL, &res, attrs,
    25042832                           "(&(objectSid=%s)(privilege=*))", sidstr);
    25052833        if (ret == 0) {
     
    25072835        }
    25082836        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",
    25102838                          dom_sid_string(mem_ctx, r->in.sid),
    25112839                          ldb_errstring(state->pdb)));
     
    25192847
    25202848        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,
    25222850                                            struct lsa_StringLarge, r->out.rights->count);
    25232851        if (r->out.rights->names == NULL) {
     
    25342862
    25352863
    2536 /* 
     2864/*
    25372865  helper for lsa_AddAccountRights and lsa_RemoveAccountRights
    25382866*/
    2539 static NTSTATUS dcesrv_lsa_AddRemoveAccountRights(struct dcesrv_call_state *dce_call, 
     2867static NTSTATUS dcesrv_lsa_AddRemoveAccountRights(struct dcesrv_call_state *dce_call,
    25402868                                           TALLOC_CTX *mem_ctx,
    25412869                                           struct lsa_policy_state *state,
     
    25642892
    25652893        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        }
    25672898
    25682899        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        }
    25702904
    25712905        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        }
    25732910
    25742911        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        }
    25762916
    25772917        if (LDB_FLAG_MOD_TYPE(ldb_flag) == LDB_FLAG_MOD_ADD) {
     
    26022942                        uint32_t j;
    26032943                        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,
    26052945                                               rights->names[i].string) == 0) {
    26062946                                        break;
     
    26322972                }
    26332973                ldb_msg_add_string(msg, "comment", "added via LSA");
    2634                 ret = ldb_add(state->pdb, msg);         
     2974                ret = ldb_add(state->pdb, msg);
    26352975        }
    26362976        if (ret != LDB_SUCCESS) {
     
    26392979                        return NT_STATUS_OK;
    26402980                }
    2641                 DEBUG(3, ("Could not %s attributes from %s: %s", 
     2981                DEBUG(3, ("Could not %s attributes from %s: %s",
    26422982                          LDB_FLAG_MOD_TYPE(ldb_flag) == LDB_FLAG_MOD_DELETE ? "delete" : "add",
    26432983                          ldb_dn_get_linearized(msg->dn), ldb_errstring(state->pdb)));
     
    26502990}
    26512991
    2652 /* 
     2992/*
    26532993  lsa_AddPrivilegesToAccount
    26542994*/
     
    26813021        }
    26823022
    2683         return dcesrv_lsa_AddRemoveAccountRights(dce_call, mem_ctx, astate->policy, 
     3023        return dcesrv_lsa_AddRemoveAccountRights(dce_call, mem_ctx, astate->policy,
    26843024                                          LDB_FLAG_MOD_ADD, astate->account_sid,
    26853025                                          &rights);
     
    26873027
    26883028
    2689 /* 
     3029/*
    26903030  lsa_RemovePrivilegesFromAccount
    26913031*/
     
    27043044        rights = talloc(mem_ctx, struct lsa_RightSet);
    27053045
    2706         if (r->in.remove_all == 1 && 
     3046        if (r->in.remove_all == 1 &&
    27073047            r->in.privs == NULL) {
    27083048                struct lsa_EnumAccountRights r2;
     
    27183058                }
    27193059
    2720                 return dcesrv_lsa_AddRemoveAccountRights(dce_call, mem_ctx, astate->policy, 
     3060                return dcesrv_lsa_AddRemoveAccountRights(dce_call, mem_ctx, astate->policy,
    27213061                                                  LDB_FLAG_MOD_DELETE, astate->account_sid,
    27223062                                                  r2.out.rights);
     
    27433083        }
    27443084
    2745         return dcesrv_lsa_AddRemoveAccountRights(dce_call, mem_ctx, astate->policy, 
     3085        return dcesrv_lsa_AddRemoveAccountRights(dce_call, mem_ctx, astate->policy,
    27463086                                          LDB_FLAG_MOD_DELETE, astate->account_sid,
    27473087                                          rights);
     
    27493089
    27503090
    2751 /* 
     3091/*
    27523092  lsa_GetQuotasForAccount
    27533093*/
     
    27593099
    27603100
    2761 /* 
     3101/*
    27623102  lsa_SetQuotasForAccount
    27633103*/
     
    27693109
    27703110
    2771 /* 
     3111/*
    27723112  lsa_GetSystemAccessAccount
    27733113*/
     
    27953135        }
    27963136
    2797         ret = gendb_search(astate->policy->pdb, mem_ctx, NULL, &res, attrs, 
     3137        ret = gendb_search(astate->policy->pdb, mem_ctx, NULL, &res, attrs,
    27983138                           "objectSid=%s", sidstr);
    27993139        if (ret < 0) {
     
    28223162
    28233163
    2824 /* 
     3164/*
    28253165  lsa_SetSystemAccessAccount
    28263166*/
     
    28323172
    28333173
    2834 /* 
    2835   lsa_CreateSecret 
     3174/*
     3175  lsa_CreateSecret
    28363176*/
    28373177static NTSTATUS dcesrv_lsa_CreateSecret(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
     
    28533193        DCESRV_PULL_HANDLE(policy_handle, r->in.handle, LSA_HANDLE_POLICY);
    28543194        ZERO_STRUCTP(r->out.sec_handle);
    2855        
     3195
    28563196        switch (security_session_user_level(dce_call->conn->auth_state.session_info, NULL))
    28573197        {
     
    28693209                return NT_STATUS_INVALID_PARAMETER;
    28703210        }
    2871        
     3211
    28723212        secret_state = talloc(mem_ctx, struct lsa_secret_state);
    28733213        NT_STATUS_HAVE_NO_MEMORY(secret_state);
     
    29033243                ret = gendb_search(secret_state->sam_ldb,
    29043244                                   mem_ctx, policy_state->system_dn, &msgs, attrs,
    2905                                    "(&(cn=%s)(objectclass=secret))", 
     3245                                   "(&(cn=%s)(objectclass=secret))",
    29063246                                   name2);
    29073247                if (ret > 0) {
    29083248                        return NT_STATUS_OBJECT_NAME_COLLISION;
    29093249                }
    2910                
     3250
    29113251                if (ret < 0) {
    2912                         DEBUG(0,("Failure searching for CN=%s: %s\n", 
     3252                        DEBUG(0,("Failure searching for CN=%s: %s\n",
    29133253                                 name2, ldb_errstring(secret_state->sam_ldb)));
    29143254                        return NT_STATUS_INTERNAL_DB_CORRUPTION;
     
    29313271                }
    29323272
    2933                 secret_state->sam_ldb = talloc_reference(secret_state, 
     3273                secret_state->sam_ldb = talloc_reference(secret_state,
    29343274                                                         secrets_db_connect(mem_ctx, dce_call->conn->dce_ctx->lp_ctx));
    29353275                NT_STATUS_HAVE_NO_MEMORY(secret_state->sam_ldb);
     
    29393279                                   ldb_dn_new(mem_ctx, secret_state->sam_ldb, "cn=LSA Secrets"),
    29403280                                   &msgs, attrs,
    2941                                    "(&(cn=%s)(objectclass=secret))", 
     3281                                   "(&(cn=%s)(objectclass=secret))",
    29423282                                   ldb_binary_encode_string(mem_ctx, name));
    29433283                if (ret > 0) {
    29443284                        return NT_STATUS_OBJECT_NAME_COLLISION;
    29453285                }
    2946                
     3286
    29473287                if (ret < 0) {
    2948                         DEBUG(0,("Failure searching for CN=%s: %s\n", 
     3288                        DEBUG(0,("Failure searching for CN=%s: %s\n",
    29493289                                 name, ldb_errstring(secret_state->sam_ldb)));
    29503290                        return NT_STATUS_INTERNAL_DB_CORRUPTION;
     
    29563296                ret = ldb_msg_add_string(msg, "cn", name);
    29573297                if (ret != LDB_SUCCESS) return NT_STATUS_NO_MEMORY;
    2958         } 
     3298        }
    29593299
    29603300        ret = ldb_msg_add_string(msg, "objectClass", "secret");
    29613301        if (ret != LDB_SUCCESS) return NT_STATUS_NO_MEMORY;
    2962        
     3302
    29633303        secret_state->secret_dn = talloc_reference(secret_state, msg->dn);
    29643304        NT_STATUS_HAVE_NO_MEMORY(secret_state->secret_dn);
     
    29683308        if (ret != LDB_SUCCESS) {
    29693309                DEBUG(0,("Failed to create secret record %s: %s\n",
    2970                          ldb_dn_get_linearized(msg->dn), 
     3310                         ldb_dn_get_linearized(msg->dn),
    29713311                         ldb_errstring(secret_state->sam_ldb)));
    29723312                return NT_STATUS_ACCESS_DENIED;
     
    29773317
    29783318        handle->data = talloc_steal(handle, secret_state);
    2979        
     3319
    29803320        secret_state->access_mask = r->in.access_mask;
    29813321        secret_state->policy = talloc_reference(secret_state, policy_state);
    29823322        NT_STATUS_HAVE_NO_MEMORY(secret_state->policy);
    2983        
     3323
    29843324        *r->out.sec_handle = handle->wire_handle;
    2985        
     3325
    29863326        return NT_STATUS_OK;
    29873327}
    29883328
    29893329
    2990 /* 
    2991   lsa_OpenSecret 
     3330/*
     3331  lsa_OpenSecret
    29923332*/
    29933333static NTSTATUS dcesrv_lsa_OpenSecret(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
     
    29953335{
    29963336        struct dcesrv_handle *policy_handle;
    2997        
     3337
    29983338        struct lsa_policy_state *policy_state;
    29993339        struct lsa_secret_state *secret_state;
     
    30153355                return NT_STATUS_INVALID_PARAMETER;
    30163356        }
    3017        
     3357
    30183358        switch (security_session_user_level(dce_call->conn->auth_state.session_info, NULL))
    30193359        {
     
    30353375                name = &r->in.name.string[2];
    30363376                /* 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,
    30383378                                                         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));
    30393379                secret_state->global = true;
     
    30463386                ret = gendb_search(secret_state->sam_ldb,
    30473387                                   mem_ctx, policy_state->system_dn, &msgs, attrs,
    3048                                    "(&(cn=%s Secret)(objectclass=secret))", 
     3388                                   "(&(cn=%s Secret)(objectclass=secret))",
    30493389                                   ldb_binary_encode_string(mem_ctx, name));
    30503390                if (ret == 0) {
    30513391                        return NT_STATUS_OBJECT_NAME_NOT_FOUND;
    30523392                }
    3053                
     3393
    30543394                if (ret != 1) {
    30553395                        DEBUG(0,("Found %d records matching DN %s\n", ret,
     
    30573397                        return NT_STATUS_INTERNAL_DB_CORRUPTION;
    30583398                }
    3059        
    30603399        } else {
    30613400                secret_state->global = false;
    3062                 secret_state->sam_ldb = talloc_reference(secret_state, 
     3401                secret_state->sam_ldb = talloc_reference(secret_state,
    30633402                                                         secrets_db_connect(mem_ctx, dce_call->conn->dce_ctx->lp_ctx));
    30643403
     
    30723411                                   ldb_dn_new(mem_ctx, secret_state->sam_ldb, "cn=LSA Secrets"),
    30733412                                   &msgs, attrs,
    3074                                    "(&(cn=%s)(objectclass=secret))", 
     3413                                   "(&(cn=%s)(objectclass=secret))",
    30753414                                   ldb_binary_encode_string(mem_ctx, name));
    30763415                if (ret == 0) {
    30773416                        return NT_STATUS_OBJECT_NAME_NOT_FOUND;
    30783417                }
    3079                
     3418
    30803419                if (ret != 1) {
    3081                         DEBUG(0,("Found %d records matching CN=%s\n", 
     3420                        DEBUG(0,("Found %d records matching CN=%s\n",
    30823421                                 ret, ldb_binary_encode_string(mem_ctx, name)));
    30833422                        return NT_STATUS_INTERNAL_DB_CORRUPTION;
    30843423                }
    3085         } 
     3424        }
    30863425
    30873426        secret_state->secret_dn = talloc_reference(secret_state, msgs[0]->dn);
    3088        
     3427
    30893428        handle = dcesrv_handle_new(dce_call->context, LSA_HANDLE_SECRET);
    30903429        if (!handle) {
    30913430                return NT_STATUS_NO_MEMORY;
    30923431        }
    3093        
     3432
    30943433        handle->data = talloc_steal(handle, secret_state);
    3095        
     3434
    30963435        secret_state->access_mask = r->in.access_mask;
    30973436        secret_state->policy = talloc_reference(secret_state, policy_state);
    3098        
     3437
    30993438        *r->out.sec_handle = handle->wire_handle;
    3100        
     3439
    31013440        return NT_STATUS_OK;
    31023441}
    31033442
    31043443
    3105 /* 
    3106   lsa_SetSecret 
     3444/*
     3445  lsa_SetSecret
    31073446*/
    31083447static NTSTATUS dcesrv_lsa_SetSecret(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
     
    31443483                crypt_secret.data = r->in.old_val->data;
    31453484                crypt_secret.length = r->in.old_val->size;
    3146                
     3485
    31473486                status = sess_decrypt_blob(mem_ctx, &crypt_secret, &session_key, &secret);
    31483487                if (!NT_STATUS_IS_OK(status)) {
    31493488                        return status;
    31503489                }
    3151                
     3490
    31523491                val.data = secret.data;
    31533492                val.length = secret.length;
    3154                
     3493
    31553494                /* set value */
    31563495                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
    31603499                /* set old value mtime */
    3161                 if (samdb_msg_add_uint64(secret_state->sam_ldb, 
     3500                if (samdb_msg_add_uint64(secret_state->sam_ldb,
    31623501                                         mem_ctx, msg, "priorSetTime", nt_now) != LDB_SUCCESS) {
    3163                         return NT_STATUS_NO_MEMORY; 
     3502                        return NT_STATUS_NO_MEMORY;
    31643503                }
    31653504
     
    31753514                        NULL
    31763515                };
    3177                
     3516
    31783517                /* search for the secret record */
    31793518                ret = gendb_search_dn(secret_state->sam_ldb,mem_ctx,
     
    31823521                        return NT_STATUS_OBJECT_NAME_NOT_FOUND;
    31833522                }
    3184                
     3523
    31853524                if (ret != 1) {
    31863525                        DEBUG(0,("Found %d records matching dn=%s\n", ret,
     
    31883527                        return NT_STATUS_INTERNAL_DB_CORRUPTION;
    31893528                }
    3190                
     3529
    31913530                old_val = ldb_msg_find_ldb_val(res[0], "currentValue");
    31923531                last_set_time = ldb_msg_find_attr_as_uint64(res[0], "lastSetTime", 0);
    3193                
     3532
    31943533                if (old_val) {
    31953534                        /* set old value */
    31963535                        if (ldb_msg_add_value(msg, "priorValue",
    31973536                                              old_val, NULL) != LDB_SUCCESS) {
    3198                                 return NT_STATUS_NO_MEMORY; 
     3537                                return NT_STATUS_NO_MEMORY;
    31993538                        }
    32003539                } else {
    3201                         if (samdb_msg_add_delete(secret_state->sam_ldb, 
     3540                        if (samdb_msg_add_delete(secret_state->sam_ldb,
    32023541                                                 mem_ctx, msg, "priorValue") != LDB_SUCCESS) {
    32033542                                return NT_STATUS_NO_MEMORY;
    32043543                        }
    3205                        
    3206                 }
    3207                
     3544                }
     3545
    32083546                /* set old value mtime */
    32093547                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,
    32113549                                                 mem_ctx, msg, "priorSetTime", last_set_time) != LDB_SUCCESS) {
    3212                                 return NT_STATUS_NO_MEMORY; 
     3550                                return NT_STATUS_NO_MEMORY;
    32133551                        }
    32143552                } else {
    3215                         if (samdb_msg_add_uint64(secret_state->sam_ldb, 
     3553                        if (samdb_msg_add_uint64(secret_state->sam_ldb,
    32163554                                                 mem_ctx, msg, "priorSetTime", nt_now) != LDB_SUCCESS) {
    3217                                 return NT_STATUS_NO_MEMORY; 
     3555                                return NT_STATUS_NO_MEMORY;
    32183556                        }
    32193557                }
     
    32243562                crypt_secret.data = r->in.new_val->data;
    32253563                crypt_secret.length = r->in.new_val->size;
    3226                
     3564
    32273565                status = sess_decrypt_blob(mem_ctx, &crypt_secret, &session_key, &secret);
    32283566                if (!NT_STATUS_IS_OK(status)) {
    32293567                        return status;
    32303568                }
    3231                
     3569
    32323570                val.data = secret.data;
    32333571                val.length = secret.length;
    3234                
     3572
    32353573                /* set value */
    32363574                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
    32403578                /* set new value mtime */
    3241                 if (samdb_msg_add_uint64(secret_state->sam_ldb, 
     3579                if (samdb_msg_add_uint64(secret_state->sam_ldb,
    32423580                                         mem_ctx, msg, "lastSetTime", nt_now) != LDB_SUCCESS) {
    3243                         return NT_STATUS_NO_MEMORY;
    3244                 }
    3245                
     3581                        return NT_STATUS_NO_MEMORY;
     3582                }
    32463583        } else {
    32473584                /* 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,
    32493586                                         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,
    32533590                                         mem_ctx, msg, "currentValue") != LDB_SUCCESS) {
    32543591                        return NT_STATUS_NO_MEMORY;
     
    32593596        ret = dsdb_replace(secret_state->sam_ldb, msg, 0);
    32603597        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);
    32633599        }
    32643600
     
    32673603
    32683604
    3269 /* 
    3270   lsa_QuerySecret 
     3605/*
     3606  lsa_QuerySecret
    32713607*/
    32723608static NTSTATUS dcesrv_lsa_QuerySecret(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
     
    32843620                "priorValue",
    32853621                "lastSetTime",
    3286                 "priorSetTime", 
     3622                "priorSetTime",
    32873623                NULL
    32883624        };
     
    33123648        }
    33133649        msg = res[0];
    3314        
     3650
    33153651        nt_status = dcesrv_fetch_session_key(dce_call->conn, &session_key);
    33163652        if (!NT_STATUS_IS_OK(nt_status)) {
    33173653                return nt_status;
    33183654        }
    3319        
     3655
    33203656        if (r->in.old_val) {
    33213657                const struct ldb_val *prior_val;
     
    33243660                        return NT_STATUS_NO_MEMORY;
    33253661                }
    3326                 prior_val = ldb_msg_find_ldb_val(res[0], "priorValue");
    3327                
     3662                prior_val = ldb_msg_find_ldb_val(msg, "priorValue");
     3663
    33283664                if (prior_val && prior_val->length) {
    33293665                        secret.data = prior_val->data;
    33303666                        secret.length = prior_val->length;
    3331                
     3667
    33323668                        /* Encrypt */
    33333669                        crypt_secret = sess_encrypt_blob(mem_ctx, &secret, &session_key);
     
    33443680                }
    33453681        }
    3346        
     3682
    33473683        if (r->in.old_mtime) {
    33483684                r->out.old_mtime = talloc(mem_ctx, NTTIME);
     
    33503686                        return NT_STATUS_NO_MEMORY;
    33513687                }
    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
    33553691        if (r->in.new_val) {
    33563692                const struct ldb_val *new_val;
     
    33603696                }
    33613697
    3362                 new_val = ldb_msg_find_ldb_val(res[0], "currentValue");
    3363                
     3698                new_val = ldb_msg_find_ldb_val(msg, "currentValue");
     3699
    33643700                if (new_val && new_val->length) {
    33653701                        secret.data = new_val->data;
    33663702                        secret.length = new_val->length;
    3367                
     3703
    33683704                        /* Encrypt */
    33693705                        crypt_secret = sess_encrypt_blob(mem_ctx, &secret, &session_key);
     
    33803716                }
    33813717        }
    3382        
     3718
    33833719        if (r->in.new_mtime) {
    33843720                r->out.new_mtime = talloc(mem_ctx, NTTIME);
     
    33863722                        return NT_STATUS_NO_MEMORY;
    33873723                }
    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
    33913727        return NT_STATUS_OK;
    33923728}
    33933729
    33943730
    3395 /* 
     3731/*
    33963732  lsa_LookupPrivValue
    33973733*/
    3398 static NTSTATUS dcesrv_lsa_LookupPrivValue(struct dcesrv_call_state *dce_call, 
     3734static NTSTATUS dcesrv_lsa_LookupPrivValue(struct dcesrv_call_state *dce_call,
    33993735                                    TALLOC_CTX *mem_ctx,
    34003736                                    struct lsa_LookupPrivValue *r)
    34013737{
    34023738        struct dcesrv_handle *h;
    3403         struct lsa_policy_state *state;
    34043739        int id;
    34053740
    34063741        DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
    3407 
    3408         state = h->data;
    34093742
    34103743        id = sec_privilege_id(r->in.name->string);
     
    34163749        r->out.luid->high = 0;
    34173750
    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*/
     3758static NTSTATUS dcesrv_lsa_LookupPrivName(struct dcesrv_call_state *dce_call,
    34263759                                   TALLOC_CTX *mem_ctx,
    34273760                                   struct lsa_LookupPrivName *r)
    34283761{
    34293762        struct dcesrv_handle *h;
    3430         struct lsa_policy_state *state;
    34313763        struct lsa_StringLarge *name;
    34323764        const char *privname;
    34333765
    34343766        DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
    3435 
    3436         state = h->data;
    34373767
    34383768        if (r->in.luid->high != 0) {
     
    34543784        *r->out.name = name;
    34553785
    3456         return NT_STATUS_OK;   
    3457 }
    3458 
    3459 
    3460 /* 
     3786        return NT_STATUS_OK;
     3787}
     3788
     3789
     3790/*
    34613791  lsa_LookupPrivDisplayName
    34623792*/
    3463 static NTSTATUS dcesrv_lsa_LookupPrivDisplayName(struct dcesrv_call_state *dce_call, 
     3793static NTSTATUS dcesrv_lsa_LookupPrivDisplayName(struct dcesrv_call_state *dce_call,
    34643794                                          TALLOC_CTX *mem_ctx,
    34653795                                          struct lsa_LookupPrivDisplayName *r)
    34663796{
    34673797        struct dcesrv_handle *h;
    3468         struct lsa_policy_state *state;
    34693798        struct lsa_StringLarge *disp_name = NULL;
    34703799        enum sec_privilege id;
    34713800
    34723801        DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
    3473 
    3474         state = h->data;
    34753802
    34763803        id = sec_privilege_id(r->in.name->string);
     
    34963823
    34973824
    3498 /* 
     3825/*
    34993826  lsa_EnumAccountsWithUserRight
    35003827*/
    3501 static NTSTATUS dcesrv_lsa_EnumAccountsWithUserRight(struct dcesrv_call_state *dce_call, 
     3828static NTSTATUS dcesrv_lsa_EnumAccountsWithUserRight(struct dcesrv_call_state *dce_call,
    35023829                                              TALLOC_CTX *mem_ctx,
    35033830                                              struct lsa_EnumAccountsWithUserRight *r)
     
    35163843        if (r->in.name == NULL) {
    35173844                return NT_STATUS_NO_SUCH_PRIVILEGE;
    3518         } 
     3845        }
    35193846
    35203847        privname = r->in.name->string;
     
    35233850        }
    35243851
    3525         ret = gendb_search(state->pdb, mem_ctx, NULL, &res, attrs, 
     3852        ret = gendb_search(state->pdb, mem_ctx, NULL, &res, attrs,
    35263853                           "privilege=%s", privname);
    35273854        if (ret < 0) {
     
    35473874
    35483875
    3549 /* 
     3876/*
    35503877  lsa_AddAccountRights
    35513878*/
    3552 static NTSTATUS dcesrv_lsa_AddAccountRights(struct dcesrv_call_state *dce_call, 
     3879static NTSTATUS dcesrv_lsa_AddAccountRights(struct dcesrv_call_state *dce_call,
    35533880                                     TALLOC_CTX *mem_ctx,
    35543881                                     struct lsa_AddAccountRights *r)
     
    35613888        state = h->data;
    35623889
    3563         return dcesrv_lsa_AddRemoveAccountRights(dce_call, mem_ctx, state, 
     3890        return dcesrv_lsa_AddRemoveAccountRights(dce_call, mem_ctx, state,
    35643891                                          LDB_FLAG_MOD_ADD,
    35653892                                          r->in.sid, r->in.rights);
     
    35673894
    35683895
    3569 /* 
     3896/*
    35703897  lsa_RemoveAccountRights
    35713898*/
    3572 static NTSTATUS dcesrv_lsa_RemoveAccountRights(struct dcesrv_call_state *dce_call, 
     3899static NTSTATUS dcesrv_lsa_RemoveAccountRights(struct dcesrv_call_state *dce_call,
    35733900                                        TALLOC_CTX *mem_ctx,
    35743901                                        struct lsa_RemoveAccountRights *r)
     
    35813908        state = h->data;
    35823909
    3583         return dcesrv_lsa_AddRemoveAccountRights(dce_call, mem_ctx, state, 
     3910        return dcesrv_lsa_AddRemoveAccountRights(dce_call, mem_ctx, state,
    35843911                                          LDB_FLAG_MOD_DELETE,
    35853912                                          r->in.sid, r->in.rights);
     
    35873914
    35883915
    3589 /* 
     3916/*
    35903917  lsa_StorePrivateData
    35913918*/
     
    35973924
    35983925
    3599 /* 
     3926/*
    36003927  lsa_RetrievePrivateData
    36013928*/
     
    36073934
    36083935
    3609 /* 
     3936/*
    36103937  lsa_GetUserName
    36113938*/
     
    36133940                                struct lsa_GetUserName *r)
    36143941{
     3942        enum dcerpc_transport_t transport =
     3943                dcerpc_binding_get_transport(dce_call->conn->endpoint->ep_description);
    36153944        NTSTATUS status = NT_STATUS_OK;
    36163945        const char *account_name;
     
    36193948        struct lsa_String *_authority_name = NULL;
    36203949
     3950        if (transport != NCACN_NP && transport != NCALRPC) {
     3951                DCESRV_FAULT(DCERPC_FAULT_ACCESS_DENIED);
     3952        }
     3953
    36213954        /* this is what w2k3 does */
    36223955        r->out.account_name = r->in.account_name;
     
    36694002}
    36704003
     4004static 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}
    36714035/*
    36724036  lsa_QueryDomainInformationPolicy
     
    36924056                struct lsa_DomainInfoKerberos *k = &info->kerberos_info;
    36934057                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,
    36964059                                                        dce_call->conn->dce_ctx->lp_ctx,
    36974060                                                        &smb_krb5_context);
     
    37354098}
    37364099
    3737 /* 
    3738   lsa_CREDRWRITE 
     4100/*
     4101  lsa_CREDRWRITE
    37394102*/
    37404103static NTSTATUS dcesrv_lsa_CREDRWRITE(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
     
    37454108
    37464109
    3747 /* 
    3748   lsa_CREDRREAD 
     4110/*
     4111  lsa_CREDRREAD
    37494112*/
    37504113static NTSTATUS dcesrv_lsa_CREDRREAD(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
     
    37554118
    37564119
    3757 /* 
    3758   lsa_CREDRENUMERATE 
     4120/*
     4121  lsa_CREDRENUMERATE
    37594122*/
    37604123static NTSTATUS dcesrv_lsa_CREDRENUMERATE(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
     
    37654128
    37664129
    3767 /* 
    3768   lsa_CREDRWRITEDOMAINCREDENTIALS 
     4130/*
     4131  lsa_CREDRWRITEDOMAINCREDENTIALS
    37694132*/
    37704133static NTSTATUS dcesrv_lsa_CREDRWRITEDOMAINCREDENTIALS(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
     
    37754138
    37764139
    3777 /* 
    3778   lsa_CREDRREADDOMAINCREDENTIALS 
     4140/*
     4141  lsa_CREDRREADDOMAINCREDENTIALS
    37794142*/
    37804143static NTSTATUS dcesrv_lsa_CREDRREADDOMAINCREDENTIALS(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
     
    37854148
    37864149
    3787 /* 
    3788   lsa_CREDRDELETE 
     4150/*
     4151  lsa_CREDRDELETE
    37894152*/
    37904153static NTSTATUS dcesrv_lsa_CREDRDELETE(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
     
    37954158
    37964159
    3797 /* 
    3798   lsa_CREDRGETTARGETINFO 
     4160/*
     4161  lsa_CREDRGETTARGETINFO
    37994162*/
    38004163static NTSTATUS dcesrv_lsa_CREDRGETTARGETINFO(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
     
    38054168
    38064169
    3807 /* 
    3808   lsa_CREDRPROFILELOADED 
     4170/*
     4171  lsa_CREDRPROFILELOADED
    38094172*/
    38104173static NTSTATUS dcesrv_lsa_CREDRPROFILELOADED(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
     
    38154178
    38164179
    3817 /* 
    3818   lsa_CREDRGETSESSIONTYPES 
     4180/*
     4181  lsa_CREDRGETSESSIONTYPES
    38194182*/
    38204183static NTSTATUS dcesrv_lsa_CREDRGETSESSIONTYPES(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
     
    38254188
    38264189
    3827 /* 
    3828   lsa_LSARREGISTERAUDITEVENT 
     4190/*
     4191  lsa_LSARREGISTERAUDITEVENT
    38294192*/
    38304193static NTSTATUS dcesrv_lsa_LSARREGISTERAUDITEVENT(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
     
    38354198
    38364199
    3837 /* 
    3838   lsa_LSARGENAUDITEVENT 
     4200/*
     4201  lsa_LSARGENAUDITEVENT
    38394202*/
    38404203static NTSTATUS dcesrv_lsa_LSARGENAUDITEVENT(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
     
    38454208
    38464209
    3847 /* 
    3848   lsa_LSARUNREGISTERAUDITEVENT 
     4210/*
     4211  lsa_LSARUNREGISTERAUDITEVENT
    38494212*/
    38504213static NTSTATUS dcesrv_lsa_LSARUNREGISTERAUDITEVENT(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
     
    38554218
    38564219
    3857 /* 
    3858   lsa_lsaRQueryForestTrustInformation 
     4220/*
     4221  lsa_lsaRQueryForestTrustInformation
    38594222*/
    38604223static NTSTATUS dcesrv_lsa_lsaRQueryForestTrustInformation(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
    38614224                       struct lsa_lsaRQueryForestTrustInformation *r)
    38624225{
    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)) {
    39284250                return NT_STATUS_INVALID_DOMAIN_STATE;
    39294251        }
    39304252
    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;
    42224300        return NT_STATUS_OK;
    42234301}
     
    42324310        struct dcesrv_handle *h;
    42334311        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;
    42464335        enum ndr_err_code ndr_err;
    4247         NTSTATUS nt_status;
    4248         bool am_rodc;
    42494336        int ret;
     4337        bool in_transaction = false;
    42504338
    42514339        DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
     
    42574345        }
    42584346
    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         */
    42604360        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;
    43014390        }
    43024391
    43034392        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;
    43154409        }
    43164410
    43174411        c_info = talloc_zero(r->out.collision_info,
    43184412                             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        }
    43684494
    43694495        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,
    43764524                                       (ndr_push_flags_fn_t)ndr_push_ForestTrustInfo);
    43774525        if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
    4378                 return NT_STATUS_INVALID_PARAMETER;
     4526                status = NT_STATUS_INVALID_PARAMETER;
     4527                goto done;
    43794528        }
    43804529
    43814530        msg = ldb_msg_new(mem_ctx);
    43824531        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);
    43874537        if (!msg->dn) {
    4388                 return NT_STATUS_NO_MEMORY;
     4538                status = NT_STATUS_NO_MEMORY;
     4539                goto done;
    43894540        }
    43904541
     
    43924543                                LDB_FLAG_MOD_REPLACE, NULL);
    43934544        if (ret != LDB_SUCCESS) {
    4394                 return NT_STATUS_NO_MEMORY;
     4545                status = NT_STATUS_NO_MEMORY;
     4546                goto done;
    43954547        }
    43964548        ret = ldb_msg_add_value(msg, "msDS-TrustForestTrustInfo",
    43974549                                &ft_blob, NULL);
    43984550        if (ret != LDB_SUCCESS) {
    4399                 return NT_STATUS_NO_MEMORY;
     4551                status = NT_STATUS_NO_MEMORY;
     4552                goto done;
    44004553        }
    44014554
    44024555        ret = ldb_modify(p_state->sam_ldb, msg);
    44034556        if (ret != LDB_SUCCESS) {
     4557                status = dsdb_ldb_err_to_ntstatus(ret);
     4558
    44044559                DEBUG(0, ("Failed to store Forest Trust Info: %s\n",
    44054560                          ldb_errstring(p_state->sam_ldb)));
    44064561
    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
     4575done:
     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
    44204589*/
    44214590static NTSTATUS dcesrv_lsa_CREDRRENAME(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
     
    44274596
    44284597
    4429 /* 
    4430   lsa_LSAROPENPOLICYSCE 
     4598/*
     4599  lsa_LSAROPENPOLICYSCE
    44314600*/
    44324601static NTSTATUS dcesrv_lsa_LSAROPENPOLICYSCE(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
     
    44374606
    44384607
    4439 /* 
    4440   lsa_LSARADTREGISTERSECURITYEVENTSOURCE 
     4608/*
     4609  lsa_LSARADTREGISTERSECURITYEVENTSOURCE
    44414610*/
    44424611static NTSTATUS dcesrv_lsa_LSARADTREGISTERSECURITYEVENTSOURCE(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
     
    44474616
    44484617
    4449 /* 
    4450   lsa_LSARADTUNREGISTERSECURITYEVENTSOURCE 
     4618/*
     4619  lsa_LSARADTUNREGISTERSECURITYEVENTSOURCE
    44514620*/
    44524621static NTSTATUS dcesrv_lsa_LSARADTUNREGISTERSECURITYEVENTSOURCE(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
     
    44574626
    44584627
    4459 /* 
    4460   lsa_LSARADTREPORTSECURITYEVENT 
     4628/*
     4629  lsa_LSARADTREPORTSECURITYEVENT
    44614630*/
    44624631static NTSTATUS dcesrv_lsa_LSARADTREPORTSECURITYEVENT(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
     
    44794648******************************************/
    44804649
    4481 /* 
    4482   dssetup_DsRoleDnsNameToFlatName 
     4650/*
     4651  dssetup_DsRoleDnsNameToFlatName
    44834652*/
    44844653static WERROR dcesrv_dssetup_DsRoleDnsNameToFlatName(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
     
    44894658
    44904659
    4491 /* 
    4492   dssetup_DsRoleDcAsDc 
     4660/*
     4661  dssetup_DsRoleDcAsDc
    44934662*/
    44944663static WERROR dcesrv_dssetup_DsRoleDcAsDc(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
     
    44994668
    45004669
    4501 /* 
    4502   dssetup_DsRoleDcAsReplica 
     4670/*
     4671  dssetup_DsRoleDcAsReplica
    45034672*/
    45044673static WERROR dcesrv_dssetup_DsRoleDcAsReplica(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
     
    45094678
    45104679
    4511 /* 
    4512   dssetup_DsRoleDemoteDc 
     4680/*
     4681  dssetup_DsRoleDemoteDc
    45134682*/
    45144683static WERROR dcesrv_dssetup_DsRoleDemoteDc(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
     
    45194688
    45204689
    4521 /* 
    4522   dssetup_DsRoleGetDcOperationProgress 
     4690/*
     4691  dssetup_DsRoleGetDcOperationProgress
    45234692*/
    45244693static WERROR dcesrv_dssetup_DsRoleGetDcOperationProgress(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
     
    45494718
    45504719
    4551 /* 
    4552   dssetup_DsRoleServerSaveStateForUpgrade 
     4720/*
     4721  dssetup_DsRoleServerSaveStateForUpgrade
    45534722*/
    45544723static WERROR dcesrv_dssetup_DsRoleServerSaveStateForUpgrade(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
     
    45594728
    45604729
    4561 /* 
    4562   dssetup_DsRoleUpgradeDownlevelServer 
     4730/*
     4731  dssetup_DsRoleUpgradeDownlevelServer
    45634732*/
    45644733static WERROR dcesrv_dssetup_DsRoleUpgradeDownlevelServer(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
     
    45694738
    45704739
    4571 /* 
    4572   dssetup_DsRoleAbortDownlevelServerUpgrade 
     4740/*
     4741  dssetup_DsRoleAbortDownlevelServerUpgrade
    45734742*/
    45744743static WERROR dcesrv_dssetup_DsRoleAbortDownlevelServerUpgrade(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
     
    45854754{
    45864755        NTSTATUS ret;
    4587        
     4756
    45884757        ret = dcerpc_server_dssetup_init();
    45894758        if (!NT_STATUS_IS_OK(ret)) {
  • vendor/current/source4/rpc_server/lsa/lsa.h

    r740 r988  
    4242        struct ldb_context *sam_ldb;
    4343        struct ldb_context *pdb;
    44         uint32_t access_mask;
    4544        struct ldb_dn *domain_dn;
    4645        struct ldb_dn *forest_dn;
     
    5756        struct dom_sid *world_domain_sid;
    5857        int mixed_domain;
     58        struct security_descriptor *sd;
     59        uint32_t access_mask;
    5960};
    6061
  • vendor/current/source4/rpc_server/lsa/lsa_init.c

    r740 r988  
    2323#include "rpc_server/lsa/lsa.h"
    2424
    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
     41static 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
     48NTSTATUS dcesrv_lsa_get_policy_state(struct dcesrv_call_state *dce_call,
     49                                     TALLOC_CTX *mem_ctx,
     50                                     uint32_t access_desired,
    2651                                     struct lsa_policy_state **_state)
    2752{
     53        struct auth_session_info *session_info = dce_call->conn->auth_state.session_info;
     54        enum security_user_level security_level;
    2855        struct lsa_policy_state *state;
    2956        struct ldb_result *dom_res;
     
    3865        int ret;
    3966
    40         state = talloc(mem_ctx, struct lsa_policy_state);
     67        state = talloc_zero(mem_ctx, struct lsa_policy_state);
    4168        if (!state) {
    4269                return NT_STATUS_NO_MEMORY;
     
    143170                return NT_STATUS_NO_SUCH_DOMAIN;               
    144171        }
     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));
    145215
    146216        *_state = state;
     
    155225                                struct lsa_OpenPolicy2 *r)
    156226{
     227        enum dcerpc_transport_t transport =
     228                dcerpc_binding_get_transport(dce_call->conn->endpoint->ep_description);
    157229        NTSTATUS status;
    158230        struct lsa_policy_state *state;
    159231        struct dcesrv_handle *handle;
     232
     233        if (transport != NCACN_NP && transport != NCALRPC) {
     234                DCESRV_FAULT(DCERPC_FAULT_ACCESS_DENIED);
     235        }
    160236
    161237        ZERO_STRUCTP(r->out.handle);
     
    167243        }
    168244
    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);
    170248        if (!NT_STATUS_IS_OK(status)) {
    171249                return status;
     
    179257        handle->data = talloc_steal(handle, state);
    180258
    181         /* need to check the access mask against - need ACLs - fails
    182            WSPP test */
    183         state->access_mask = r->in.access_mask;
    184259        state->handle = handle;
    185260        *r->out.handle = handle->wire_handle;
     
    199274                                struct lsa_OpenPolicy *r)
    200275{
     276        enum dcerpc_transport_t transport =
     277                dcerpc_binding_get_transport(dce_call->conn->endpoint->ep_description);
    201278        struct lsa_OpenPolicy2 r2;
     279
     280        if (transport != NCACN_NP && transport != NCALRPC) {
     281                DCESRV_FAULT(DCERPC_FAULT_ACCESS_DENIED);
     282        }
    202283
    203284        r2.in.system_name = NULL;
  • vendor/current/source4/rpc_server/lsa/lsa_lookup.c

    r740 r988  
    285285                        *authority_name = NAME_BUILTIN;
    286286                        *sid = dom_sid_parse_talloc(mem_ctx, SID_BUILTIN);
     287                        if (*sid == NULL) {
     288                                return NT_STATUS_NO_MEMORY;
     289                        }
    287290                        *rtype = SID_NAME_DOMAIN;
    288291                        *rid = 0xFFFFFFFF;
     
    293296                        *authority_name = NAME_NT_AUTHORITY;
    294297                        *sid =  dom_sid_parse_talloc(mem_ctx, SID_NT_AUTHORITY);
     298                        if (*sid == NULL) {
     299                                return NT_STATUS_NO_MEMORY;
     300                        }
    295301                        *rtype = SID_NAME_DOMAIN;
    296302                        dom_sid_split_rid(NULL, *sid, NULL, rid);
     
    300306                        *authority_name = NAME_BUILTIN;
    301307                        *sid = dom_sid_parse_talloc(mem_ctx, SID_BUILTIN);
     308                        if (*sid == NULL) {
     309                                return NT_STATUS_NO_MEMORY;
     310                        }
    302311                        *rtype = SID_NAME_DOMAIN;
    303312                        *rid = 0xFFFFFFFF;
     
    305314                }
    306315                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                        }
    309325                        *rtype = SID_NAME_DOMAIN;
    310326                        *rid = 0xFFFFFFFF;
     
    312328                }
    313329                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                        }
    316339                        *rtype = SID_NAME_DOMAIN;
    317340                        *rid = 0xFFFFFFFF;
    318341                        return NT_STATUS_OK;
    319342                }
    320                
     343
    321344                /* Perhaps this is a well known user? */
    322345                name = talloc_asprintf(mem_ctx, "%s\\%s", NAME_NT_AUTHORITY, username);
     
    354377                        *authority_name = NAME_NT_AUTHORITY;
    355378                        *sid = dom_sid_parse_talloc(mem_ctx, SID_NT_AUTHORITY);
     379                        if (*sid == NULL) {
     380                                return NT_STATUS_NO_MEMORY;
     381                        }
    356382                        *rtype = SID_NAME_DOMAIN;
    357383                        dom_sid_split_rid(NULL, *sid, NULL, rid);
     
    370396                domain_dn = state->builtin_dn;
    371397        } 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                }
    373403                domain_dn = state->domain_dn;
    374404        } 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                }
    376410                domain_dn = state->domain_dn;
    377411        } else {
     
    498532        }
    499533
     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
    500544        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                }
    502549                domain_dn = state->domain_dn;
    503550        } else if (dom_sid_in_domain(state->builtin_sid, sid)) {
     
    538585}
    539586
    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;
     587static 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{
    549592        struct lsa_RefDomainList *domains = NULL;
     593        NTSTATUS status = NT_STATUS_OK;
    550594        uint32_t i;
    551         NTSTATUS status = NT_STATUS_OK;
    552595
    553596        if (r->in.level < LSA_LOOKUP_NAMES_ALL ||
     
    563606           MS-DTYP 2.4.2
    564607        */
    565 
    566         status = dcesrv_lsa_get_policy_state(dce_call, mem_ctx, &state);
    567         if (!NT_STATUS_IS_OK(status)) {
    568                 return status;
    569         }
    570608
    571609        domains = talloc_zero(r->out.domains,  struct lsa_RefDomainList);
     
    639677        }
    640678
    641         return NT_STATUS_OK;
     679        return status;
     680}
     681
     682/*
     683  lsa_LookupSids2
     684*/
     685NTSTATUS 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);
    642706}
    643707
     
    653717                                struct lsa_LookupSids3 *r)
    654718{
    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;
    657724        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);
    673742        if (!NT_STATUS_IS_OK(status)) {
    674743                return status;
    675744        }
    676745
    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;
    696769
    697770        return status;
     
    705778                               struct lsa_LookupSids *r)
    706779{
     780        enum dcerpc_transport_t transport =
     781                dcerpc_binding_get_transport(dce_call->conn->endpoint->ep_description);
    707782        struct lsa_LookupSids2 r2;
    708783        NTSTATUS status;
    709784        uint32_t i;
     785
     786        if (transport != NCACN_NP && transport != NCALRPC) {
     787                DCESRV_FAULT(DCERPC_FAULT_ACCESS_DENIED);
     788        }
    710789
    711790        ZERO_STRUCT(r2);
     
    751830}
    752831
    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;
     832static 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{
    764837        struct loadparm_context *lp_ctx = dce_call->conn->dce_ctx->lp_ctx;
    765838        struct lsa_RefDomainList *domains;
    766 
    767         DCESRV_PULL_HANDLE(policy_handle, r->in.handle, LSA_HANDLE_POLICY);
     839        uint32_t i;
    768840
    769841        if (r->in.level < LSA_LOOKUP_NAMES_ALL ||
     
    771843                return NT_STATUS_INVALID_PARAMETER;
    772844        }
    773 
    774         policy_state = policy_handle->data;
    775845
    776846        *r->out.domains = NULL;
     
    840910}
    841911
     912/*
     913  lsa_LookupNames3
     914*/
     915NTSTATUS 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
    842938/*
    843939  lsa_LookupNames4
     
    849945                                 struct lsa_LookupNames4 *r)
    850946{
    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;
    853952        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);
    869970        if (!NT_STATUS_IS_OK(status)) {
    870971                return status;
    871972        }
    872973
    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
    8931000        return status;
    8941001}
     
    9011008                                 struct lsa_LookupNames2 *r)
    9021009{
     1010        enum dcerpc_transport_t transport =
     1011                dcerpc_binding_get_transport(dce_call->conn->endpoint->ep_description);
    9031012        struct lsa_policy_state *state;
    9041013        struct dcesrv_handle *h;
     
    9061015        struct loadparm_context *lp_ctx = dce_call->conn->dce_ctx->lp_ctx;
    9071016        struct lsa_RefDomainList *domains;
     1017
     1018        if (transport != NCACN_NP && transport != NCALRPC) {
     1019                DCESRV_FAULT(DCERPC_FAULT_ACCESS_DENIED);
     1020        }
    9081021
    9091022        *r->out.domains = NULL;
     
    9911104                       struct lsa_LookupNames *r)
    9921105{
     1106        enum dcerpc_transport_t transport =
     1107                dcerpc_binding_get_transport(dce_call->conn->endpoint->ep_description);
    9931108        struct lsa_LookupNames2 r2;
    9941109        NTSTATUS status;
    9951110        uint32_t i;
     1111
     1112        if (transport != NCACN_NP && transport != NCALRPC) {
     1113                DCESRV_FAULT(DCERPC_FAULT_ACCESS_DENIED);
     1114        }
    9961115
    9971116        ZERO_STRUCT(r2);
  • vendor/current/source4/rpc_server/netlogon/dcerpc_netlogon.c

    r740 r988  
    2828#include "dsdb/samdb/samdb.h"
    2929#include "../lib/util/util_ldb.h"
     30#include "../lib/util/memcache.h"
    3031#include "../libcli/auth/schannel.h"
    3132#include "libcli/security/security.h"
     
    3435#include "librpc/gen_ndr/ndr_irpc_c.h"
    3536#include "../libcli/ldap/ldap_ndr.h"
    36 #include "cldap_server/cldap_server.h"
     37#include "dsdb/samdb/ldb_modules/util.h"
    3738#include "lib/tsocket/tsocket.h"
    3839#include "librpc/gen_ndr/ndr_netlogon.h"
     40#include "librpc/gen_ndr/ndr_lsa.h"
     41#include "librpc/gen_ndr/ndr_samr.h"
    3942#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)
     49static 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
     55static struct memcache *global_challenge_table;
    4056
    4157struct netlogon_server_pipe_state {
     
    4965        struct netlogon_server_pipe_state *pipe_state =
    5066                talloc_get_type(dce_call->context->private_data, struct netlogon_server_pipe_state);
     67        DATA_BLOB key, val;
    5168
    5269        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        }
    5387
    5488        /* destroyed on pipe shutdown */
     
    71105        dce_call->context->private_data = pipe_state;
    72106
     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
    73112        return NT_STATUS_OK;
    74113}
     
    79118        struct netlogon_server_pipe_state *pipe_state =
    80119                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;
    81123        struct netlogon_creds_CredentialState *creds;
    82124        struct ldb_context *sam_ctx;
    83         struct samr_Password *mach_pwd;
     125        struct samr_Password *curNtHash = NULL;
     126        struct samr_Password *prevNtHash = NULL;
    84127        uint32_t user_account_control;
    85128        int num_records;
     
    88131        const char *attrs[] = {"unicodePwd", "userAccountControl",
    89132                               "objectSid", NULL};
    90 
    91         const char *trust_dom_attrs[] = {"flatname", NULL};
    92133        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);
    93141
    94142        ZERO_STRUCTP(r->out.return_credentials);
    95143        *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);
    96244
    97245        /*
     
    101249         * call fails with access denied!
    102250         */
    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        }
    127260
    128261        switch (r->in.secure_channel_type) {
     
    133266        case SEC_CHAN_RODC:
    134267                break;
     268        case SEC_CHAN_NULL:
     269                return NT_STATUS_INVALID_PARAMETER;
    135270        default:
    136271                DEBUG(1, ("Client asked for an invalid secure channel type: %d\n",
     
    145280        }
    146281
    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) {
    151308                        return NT_STATUS_NO_MEMORY;
    152309                }
    153310
    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) {
    168313                        return NT_STATUS_NO_TRUST_SAM_ACCOUNT;
    169314                }
    170315
    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) {
    179317                        return NT_STATUS_NO_TRUST_SAM_ACCOUNT;
    180318                }
     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
    181355                account_name = talloc_asprintf(mem_ctx, "%s$", flatname);
    182 
    183                 if (!account_name) {
     356                if (account_name == NULL) {
    184357                        return NT_STATUS_NO_MEMORY;
    185358                }
    186 
    187359        } else {
    188360                account_name = r->in.account_name;
     
    239411        }
    240412
    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) {
    246423                return NT_STATUS_ACCESS_DENIED;
    247424        }
    248425
    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));
    251431                return NT_STATUS_ACCESS_DENIED;
    252432        }
     
    256436                                           r->in.computer_name,
    257437                                           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,
    261441                                           r->in.credentials,
    262442                                           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) {
    266463                return NT_STATUS_ACCESS_DENIED;
    267464        }
     
    270467
    271468        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,
    273470                                              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;
    276480}
    277481
     
    333537 * If schannel is required for this call test that it actually is available.
    334538 */
    335 static NTSTATUS schannel_check_required(struct dcerpc_auth *auth_info,
     539static NTSTATUS schannel_check_required(const struct dcesrv_auth *auth_info,
    336540                                        const char *computer_name,
    337541                                        bool integrity, bool privacy)
     
    369573{
    370574        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);
    373577
    374578        if (schannel_global_required) {
    375                 nt_status = schannel_check_required(auth_info,
     579                nt_status = schannel_check_required(&dce_call->conn->auth_state,
    376580                                                    computer_name,
    377581                                                    true, false);
     
    382586
    383587        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,
    385589                                               computer_name,
    386590                                               received_authenticator,
     
    429633        }
    430634
    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);
    434638        if (!NT_STATUS_IS_OK(nt_status) || !oldNtHash) {
    435639                return NT_STATUS_WRONG_PASSWORD;
     
    439643        nt_status = samdb_set_password_sid(sam_ctx, mem_ctx,
    440644                                           creds->sid,
     645                                           NULL, /* Don't have version */
    441646                                           NULL, /* Don't have plaintext */
    442647                                           NULL, r->in.new_password,
     
    458663        struct ldb_message **res;
    459664        struct samr_Password *oldLmHash, *oldNtHash;
     665        struct NL_PASSWORD_VERSION version = {};
     666        const uint32_t *new_version = NULL;
    460667        NTSTATUS nt_status;
    461668        DATA_BLOB new_password;
    462669        int ret;
    463 
    464670        struct samr_CryptPassword password_buf;
    465671
     
    478684        memcpy(password_buf.data, r->in.new_password->data, 512);
    479685        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        }
    481715
    482716        if (!extract_pw_from_buffer(mem_ctx, password_buf.data, &new_password)) {
     
    494728        }
    495729
    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);
    499733        if (!NT_STATUS_IS_OK(nt_status) || (!oldLmHash && !oldNtHash)) {
    500734                return NT_STATUS_WRONG_PASSWORD;
     
    504738        nt_status = samdb_set_password_sid(sam_ctx, mem_ctx,
    505739                                           creds->sid,
     740                                           new_version,
    506741                                           &new_password, /* we have plaintext */
    507742                                           NULL, NULL,
     
    601836                                        struct netr_LogonSamLogonEx *r, struct netlogon_creds_CredentialState *creds)
    602837{
    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;
    604841        struct auth_usersupplied_info *user_info;
    605842        struct auth_user_info_dc *user_info_dc;
    606843        NTSTATUS nt_status;
    607         static const char zeros[16];
    608844        struct netr_SamBaseInfo *sam;
    609845        struct netr_SamInfo2 *sam2;
     
    615851        user_info = talloc_zero(mem_ctx, struct auth_usersupplied_info);
    616852        NT_STATUS_HAVE_NO_MEMORY(user_info);
     853
     854        netlogon_creds_decrypt_samlogon_logon(creds,
     855                                              r->in.logon_level,
     856                                              r->in.logon);
    617857
    618858        switch (r->in.logon_level) {
     
    621861        case NetlogonInteractiveTransitiveInformation:
    622862        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                 }
    634863
    635864                /* TODO: we need to deny anonymous access here */
     
    679908                user_info->password.response.nt = data_blob_talloc(mem_ctx, r->in.logon->network->nt.data, r->in.logon->network->nt.length);
    680909
     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
    681917                break;
    682918
     
    684920        case NetlogonGenericInformation:
    685921        {
    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 */
    689926                } else {
    690927                        /* Using DES to verify kerberos tickets makes no sense */
     
    717954                                                r->in.logon->generic->length);
    718955
     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);
    719962                        status = dcerpc_kdc_check_generic_kerberos_r(irpc_handle,
    720963                                                                     mem_ctx,
     
    7671010
    7681011        case 6:
     1012                if (dce_call->conn->auth_state.auth_level < DCERPC_AUTH_LEVEL_PRIVACY) {
     1013                        return NT_STATUS_INVALID_PARAMETER;
     1014                }
     1015
    7691016                nt_status = auth_convert_user_info_dc_saminfo3(mem_ctx,
    7701017                                                           user_info_dc,
     
    7931040        }
    7941041
    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);
    8201045
    8211046        /* TODO: Describe and deal with these flags */
     
    8391064
    8401065        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,
    8421067                                             r->in.computer_name, &creds);
    8431068        if (!NT_STATUS_IS_OK(nt_status)) {
     
    8451070        }
    8461071
    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) {
    8491073                return NT_STATUS_ACCESS_DENIED;
    8501074        }
     
    10561280                                       r->in.domainname);
    10571281        if (domain_dn == NULL) {
    1058                 return WERR_DS_UNAVAILABLE;
     1282                return WERR_NO_SUCH_DOMAIN;
    10591283        }
    10601284
     
    10761300}
    10771301
     1302struct 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
     1316static void dcesrv_netr_LogonControl_base_done(struct tevent_req *subreq);
     1317
     1318static 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
     1529static 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*/
     1567static 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*/
     1601static 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}
    10781631
    10791632/*
     
    10831636                       struct netr_LogonControl2Ex *r)
    10841637{
    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;
    10961639        WERROR werr;
    10971640
    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        }
    11361657
    11371658        return werr;
     
    12341755                       struct netr_LogonGetCapabilities *r)
    12351756{
    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;
    12381778}
    12391779
     
    12951835        }
    12961836
     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         */
    12971842        *r->out.site = samdb_server_site_name(sam_ctx, mem_ctx);
    12981843        W_ERROR_HAVE_NO_MEMORY(*r->out.site);
     
    16522197
    16532198                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);
    16552201
    16562202                r->out.info->domain_info = domain_info;
     
    16762222  netr_ServerPasswordGet
    16772223*/
    1678 static WERROR dcesrv_netr_ServerPasswordGet(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
     2224static NTSTATUS dcesrv_netr_ServerPasswordGet(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
    16792225                       struct netr_ServerPasswordGet *r)
    16802226{
     
    17032249        struct netr_DsRGetDCNameInfo *info;
    17042250        struct loadparm_context *lp_ctx = dce_call->conn->dce_ctx->lp_ctx;
     2251        const struct tsocket_address *local_address;
     2252        char *local_addr = NULL;
    17052253        const struct tsocket_address *remote_address;
    1706         char *addr = NULL;
     2254        char *remote_addr = NULL;
    17072255        const char *server_site_name;
    17082256        char *guid_str;
     
    17112259        const char *dc_name = NULL;
    17122260        const char *domain_name = NULL;
     2261        const char *pdc_ip;
    17132262
    17142263        ZERO_STRUCTP(r->out.info);
     
    17202269        }
    17212270
     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
    17222277        remote_address = dcesrv_connection_get_remote_address(dce_call->conn);
    17232278        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);
    17262281        }
    17272282
     
    17812336                                                 NULL, guid_str,
    17822337                                                 r->in.client_account,
    1783                                                  r->in.mask, addr,
     2338                                                 r->in.mask, remote_addr,
    17842339                                                 NETLOGON_NT_VERSION_5EX_WITH_IP,
    17852340                                                 lp_ctx, &response, true);
     
    17882343        }
    17892344
     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
    17902352        if (r->in.flags & DS_RETURN_DNS_NAME) {
    17912353                dc_name = response.data.nt5_ex.pdc_dns_name;
    17922354                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;
    17932362        } else if (r->in.flags & DS_RETURN_FLAT_NAME) {
    17942363                dc_name = response.data.nt5_ex.pdc_name;
     
    18142383        info = talloc(mem_ctx, struct netr_DsRGetDCNameInfo);
    18152384        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));
    18172388        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);
    18202395        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;
    18222397        info->domain_guid      = response.data.nt5_ex.domain_uuid;
    18232398        info->domain_name      = domain_name;
    18242399        info->forest_name      = response.data.nt5_ex.forest;
    18252400        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        }
    18262410        info->dc_site_name     = response.data.nt5_ex.server_site;
    18272411        info->client_site_name = response.data.nt5_ex.client_site;
     
    20612645
    20622646
    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 
    20782647static WERROR fill_trusted_domains_array(TALLOC_CTX *mem_ctx,
    20792648                                         struct ldb_context *sam_ctx,
     
    21312700                W_ERROR_HAVE_NO_MEMORY(trusts->array);
    21322701
    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));
    21372710
    21382711                trusts->array[n].trust_flags = flags;
     
    21502723                                                  "trustAttributes", 0);
    21512724
    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)) {
    21542727                        struct dom_sid zero_sid;
    21552728                        ZERO_STRUCT(zero_sid);
     
    22572830                /* we are always the root domain for now */
    22582831                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;
    22602833                trusts->array[n].trust_attributes = 0;
    22612834                trusts->array[n].sid = samdb_result_dom_sid(mem_ctx,
     
    22812854
    22822855
     2856static NTSTATUS dcesrv_netr_ServerGetTrustInfo(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
     2857                       struct netr_ServerGetTrustInfo *r);
     2858
    22832859/*
    22842860  netr_ServerTrustPasswordsGet
     
    22872863                       struct netr_ServerTrustPasswordsGet *r)
    22882864{
    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;
    23522887}
    23532888
     
    23552890  netr_DsRGetForestTrustInformation
    23562891*/
     2892struct dcesrv_netr_DsRGetForestTrustInformation_state {
     2893        struct dcesrv_call_state *dce_call;
     2894        TALLOC_CTX *mem_ctx;
     2895        struct netr_DsRGetForestTrustInformation *r;
     2896};
     2897
     2898static void dcesrv_netr_DsRGetForestTrustInformation_done(struct tevent_req *subreq);
     2899
    23572900static WERROR dcesrv_netr_DsRGetForestTrustInformation(struct dcesrv_call_state *dce_call,
    23582901                                                       TALLOC_CTX *mem_ctx,
     
    23602903{
    23612904        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        }
    23652921
    23662922        if (r->in.flags & 0xFFFFFFFE) {
     
    23742930        }
    23752931
     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
    23762952        if (r->in.flags & DS_GFTI_UPDATE_TDO) {
    23772953                if (!samdb_is_pdc(sam_ctx)) {
     
    23822958                        return WERR_INVALID_FLAGS;
    23832959                }
    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);
    24063018
    24073019        return WERR_OK;
    24083020}
    24093021
     3022static 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}
    24103046
    24113047/*
     
    24173053{
    24183054        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;
    24223061        NTSTATUS status;
    2423         WERROR werr;
    24243062
    24253063        status = dcesrv_netr_creds_server_step_check(dce_call,
     
    24413079                                dce_call->conn->auth_state.session_info, 0);
    24423080        if (sam_ctx == NULL) {
    2443                 return NT_STATUS_UNSUCCESSFUL;
     3081                return NT_STATUS_INTERNAL_ERROR;
    24443082        }
    24453083
    24463084        /* TODO: check r->in.server_name is our name */
    24473085
    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        }
    24643111
    24653112        return NT_STATUS_OK;
     
    24733120                       struct netr_ServerGetTrustInfo *r)
    24743121{
    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;
    24763274}
    24773275
  • vendor/current/source4/rpc_server/remote/dcesrv_remote.c

    r740 r988  
    2929#include "param/param.h"
    3030
     31NTSTATUS dcerpc_server_remote_init(void);
    3132
    3233struct dcesrv_remote_private {
     
    7172        domain = lpcfg_parm_string(dce_call->conn->dce_ctx->lp_ctx, NULL, "dceprc_remote", "domain");
    7273
    73         table = ndr_table_by_uuid(&iface->syntax_id.uuid); /* FIXME: What about if_version ? */
     74        table = ndr_table_by_syntax(&iface->syntax_id);
    7475        if (!table) {
    7576                dce_call->fault_code = DCERPC_FAULT_UNK_IF;
     
    115116                return status;
    116117        }
    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
    118137        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;
    126138
    127139        pipe_conn_req = dcerpc_pipe_connect_b_send(dce_call->context, b, table,
     
    137149        }
    138150
    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);
    141154        }
    142155
     
    157170
    158171        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) {
    159184                dce_call->fault_code = DCERPC_FAULT_OP_RNG_ERROR;
    160185                return NT_STATUS_NET_WRITE_FAULT;
     
    292317{
    293318        unsigned int i;
    294         const 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);
    295320
    296321        if (!ifaces) {
  • vendor/current/source4/rpc_server/samr/dcesrv_samr.c

    r740 r988  
    4242#include "libds/common/flag_mapping.h"
    4343
     44#define DCESRV_INTERFACE_SAMR_BIND(call, iface) \
     45       dcesrv_interface_samr_bind(call, iface)
     46static 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
    4452/* these query macros make samr_Query[User|Group|Alias]Info a bit easier to read */
    4553
     
    5866        info->field = samdb_result_force_password_change(sam_ctx, mem_ctx, \
    5967                                                         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);
    6071#define QUERY_LHOURS(msg, field, attr) \
    6172        info->field = samdb_result_logon_hours(mem_ctx, msg, attr);
    6273#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);
    6675
    6776
     
    110119} while (0)
    111120
    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 
    119121/* Set account flags, discarding flags that cannot be set with SAMR */
    120122#define SET_AFLAGS(msg, field, attr) do {                               \
    121123        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) { \
    130125                return NT_STATUS_NO_MEMORY;                             \
    131126        }                                                               \
     
    327322                                 struct samr_EnumDomains *r)
    328323{
    329         struct samr_connect_state *c_state;
    330324        struct dcesrv_handle *h;
    331325        struct samr_SamArray *array;
     
    337331
    338332        DCESRV_PULL_HANDLE(h, r->in.connect_handle, SAMR_HANDLE_CONNECT);
    339 
    340         c_state = h->data;
    341333
    342334        *r->out.resume_handle = 2;
     
    501493                                                 0);
    502494        switch (state->role) {
    503         case ROLE_DOMAIN_CONTROLLER:
     495        case ROLE_ACTIVE_DIRECTORY_DC:
    504496                /* This pulls the NetBIOS name from the
    505497                   cn=NTDS Settings,cn=<NETBIOS name of PDC>,....
     
    511503                }
    512504                break;
     505        case ROLE_DOMAIN_PDC:
     506        case ROLE_DOMAIN_BDC:
     507        case ROLE_AUTO:
     508                return NT_STATUS_INTERNAL_ERROR;
    513509        case ROLE_DOMAIN_MEMBER:
    514510                info->role = SAMR_ROLE_DOMAIN_MEMBER;
     
    604600
    605601        switch (state->role) {
    606         case ROLE_DOMAIN_CONTROLLER:
     602        case ROLE_ACTIVE_DIRECTORY_DC:
    607603                /* This pulls the NetBIOS name from the
    608604                   cn=NTDS Settings,cn=<NETBIOS name of PDC>,....
     
    614610                }
    615611                break;
     612        case ROLE_DOMAIN_PDC:
     613        case ROLE_DOMAIN_BDC:
     614        case ROLE_AUTO:
     615                return NT_STATUS_INTERNAL_ERROR;
    616616        case ROLE_DOMAIN_MEMBER:
    617617                info->role = SAMR_ROLE_DOMAIN_MEMBER;
     
    986986                         ldb_dn_get_linearized(d_state->domain_dn),
    987987                         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);
    991989        }
    992990
     
    12021200        }
    12031201
    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);
    12051204        if (!NT_STATUS_IS_OK(status)) {
    12061205                return status;
     
    12081207        a_state = talloc(mem_ctx, struct samr_account_state);
    12091208        if (!a_state) {
    1210                 ldb_transaction_cancel(d_state->sam_ctx);
    12111209                return NT_STATUS_NO_MEMORY;
    12121210        }
     
    12491247
    12501248        /* 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        };
    12581259
    12591260        return dcesrv_samr_CreateUser2(dce_call, mem_ctx, &r2);
     
    13061307                /* Check if a mask has been requested */
    13071308                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)) {
    13101310                        continue;
    13111311                }
     
    17551755
    17561756        /* 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        }
    17641773        if (ret == 0) {
    17651774                return NT_STATUS_NO_SUCH_GROUP;
     
    18851894        struct samr_account_state *g_state;
    18861895        struct ldb_message *msg;
    1887         struct ldb_context *sam_ctx;
    18881896        int ret;
    18891897
     
    18911899
    18921900        g_state = h->data;
    1893         sam_ctx = g_state->sam_ctx;
    18941901
    18951902        msg = ldb_msg_new(mem_ctx);
     
    19221929        ret = ldb_modify(g_state->sam_ctx, msg);
    19231930        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);
    19261932        }
    19271933
     
    19891995                                                                memberdn);
    19901996        if (ret != LDB_SUCCESS) {
    1991                 return NT_STATUS_UNSUCCESSFUL;
     1997                return dsdb_ldb_err_to_ntstatus(ret);
    19921998        }
    19931999
     
    20012007                return NT_STATUS_ACCESS_DENIED;
    20022008        default:
    2003                 return NT_STATUS_UNSUCCESSFUL;
     2009                return dsdb_ldb_err_to_ntstatus(ret);
    20042010        }
    20052011}
     
    20242030        ret = ldb_delete(a_state->sam_ctx, a_state->account_dn);
    20252031        if (ret != LDB_SUCCESS) {
    2026                 return NT_STATUS_UNSUCCESSFUL;
     2032                return dsdb_ldb_err_to_ntstatus(ret);
    20272033        }
    20282034
     
    21052111                return NT_STATUS_ACCESS_DENIED;
    21062112        default:
    2107                 return NT_STATUS_UNSUCCESSFUL;
     2113                return dsdb_ldb_err_to_ntstatus(ret);
    21082114        }
    21092115}
     
    23382344        struct samr_account_state *a_state;
    23392345        struct ldb_message *msg;
    2340         struct ldb_context *sam_ctx;
    23412346        int ret;
    23422347
     
    23442349
    23452350        a_state = h->data;
    2346         sam_ctx = a_state->sam_ctx;
    23472351
    23482352        msg = ldb_msg_new(mem_ctx);
     
    23722376        ret = ldb_modify(a_state->sam_ctx, msg);
    23732377        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);
    23762379        }
    23772380
     
    23982401        ret = ldb_delete(a_state->sam_ctx, a_state->account_dn);
    23992402        if (ret != LDB_SUCCESS) {
    2400                 return NT_STATUS_UNSUCCESSFUL;
     2403                return dsdb_ldb_err_to_ntstatus(ret);
    24012404        }
    24022405
     
    24622465                                 ldb_dn_alloc_linearized(mem_ctx, memberdn));
    24632466        if (ret != LDB_SUCCESS) {
    2464                 return NT_STATUS_UNSUCCESSFUL;
     2467                return dsdb_ldb_err_to_ntstatus(ret);
    24652468        }
    24662469
     
    24742477                return NT_STATUS_ACCESS_DENIED;
    24752478        default:
    2476                 return NT_STATUS_UNSUCCESSFUL;
     2479                return dsdb_ldb_err_to_ntstatus(ret);
    24772480        }
    24782481}
     
    25142517                                                                 memberdn);
    25152518        if (ret != LDB_SUCCESS) {
    2516                 return NT_STATUS_UNSUCCESSFUL;
     2519                return dsdb_ldb_err_to_ntstatus(ret);
    25172520        }
    25182521
     
    25262529                return NT_STATUS_ACCESS_DENIED;
    25272530        default:
    2528                 return NT_STATUS_UNSUCCESSFUL;
     2531                return dsdb_ldb_err_to_ntstatus(ret);
    25292532        }
    25302533}
     
    26772680                          ldb_dn_get_linearized(a_state->account_dn),
    26782681                          ldb_errstring(a_state->sam_ctx)));
    2679                 return NT_STATUS_UNSUCCESSFUL;
     2682                return dsdb_ldb_err_to_ntstatus(ret);
    26802683        }
    26812684
     
    27012704        const char * const *attrs = NULL;
    27022705        union samr_UserInfo *info;
     2706
     2707        NTSTATUS status;
    27032708
    27042709        *r->out.info = NULL;
     
    27472752                                                      "logonHours",
    27482753                                                      "badPwdCount",
     2754                                                      "badPasswordTime",
    27492755                                                      "logonCount",
    27502756                                                      "userAccountControl",
     2757                                                      "msDS-User-Account-Control-Computed",
    27512758                                                      NULL};
    27522759                attrs = attrs2;
     
    27762783                                                      "logonHours",
    27772784                                                      "badPwdCount",
     2785                                                      "badPasswordTime",
    27782786                                                      "logonCount",
    27792787                                                      "pwdLastSet",
    27802788                                                      "accountExpires",
    27812789                                                      "userAccountControl",
     2790                                                      "msDS-User-Account-Control-Computed",
    27822791                                                      NULL};
    27832792                attrs = attrs2;
     
    28522861        {
    28532862                static const char * const attrs2[] = {"userAccountControl",
     2863                                                      "msDS-User-Account-Control-Computed",
    28542864                                                      "pwdLastSet",
    28552865                                                      NULL};
     
    28942904                                                      "primaryGroupID",
    28952905                                                      "userAccountControl",
     2906                                                      "msDS-User-Account-Control-Computed",
    28962907                                                      "logonHours",
    28972908                                                      "badPwdCount",
     2909                                                      "badPasswordTime",
    28982910                                                      "logonCount",
    28992911                                                      "countryCode",
     
    29652977                QUERY_FPASSC(msg, info3.force_password_change, "pwdLastSet");
    29662978                QUERY_LHOURS(msg, info3.logon_hours,           "logonHours");
     2979                /* level 3 gives the raw badPwdCount value */
    29672980                QUERY_UINT  (msg, info3.bad_password_count,    "badPwdCount");
    29682981                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");
    29702983                break;
    29712984
     
    29883001                QUERY_UINT64(msg, info5.last_logoff,           "lastLogoff");
    29893002                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");
    29913004                QUERY_UINT  (msg, info5.logon_count,           "logonCount");
    29923005                QUERY_UINT64(msg, info5.last_password_change,  "pwdLastSet");
    29933006                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");
    29953008                break;
    29963009
     
    30343047
    30353048        case 16:
    3036                 QUERY_AFLAGS(msg, info16.acct_flags,    "userAccountControl");
     3049                QUERY_AFLAGS(msg, info16.acct_flags,    "msDS-User-Account-Control-Computed");
    30373050                break;
    30383051
     
    30423055
    30433056        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                }
    30453062                break;
    30463063
     
    30613078                QUERY_STRING(msg, info21.workstations,         "userWorkstations");
    30623079                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
    30643086                QUERY_RID   (msg, info21.rid,                  "objectSid");
    30653087                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");
    30673089                info->info21.fields_present = 0x08FFFFFF;
    30683090                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");
    30703092                QUERY_UINT  (msg, info21.logon_count,          "logonCount");
    30713093                if ((info->info21.acct_flags & ACB_PW_EXPIRED) != 0) {
     
    35093531
    35103532                if (r->in.info->info26.password_expired > 0) {
     3533                        NTTIME t = 0;
    35113534                        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) {
    35133541                                return NT_STATUS_NO_MEMORY;
    35143542                        }
     
    35353563                                 ldb_errstring(a_state->sam_ctx)));
    35363564
    3537                         /* we really need samdb.c to return NTSTATUS */
    3538                         return NT_STATUS_UNSUCCESSFUL;
     3565                        return dsdb_ldb_err_to_ntstatus(ret);
    35393566                }
    35403567        }
     
    35573584        struct samr_RidWithAttributeArray *array;
    35583585        int i, count;
     3586        char membersidstr[DOM_SID_STR_BUFLEN];
    35593587
    35603588        DCESRV_PULL_HANDLE(h, r->in.user_handle, SAMR_HANDLE_USER);
     
    35623590        a_state = h->data;
    35633591        d_state = a_state->domain_state;
     3592
     3593        dom_sid_string_buf(a_state->account_sid,
     3594                           membersidstr, sizeof(membersidstr)),
    35643595
    35653596        count = samdb_search_domain(a_state->sam_ctx, mem_ctx,
    35663597                                    d_state->domain_dn, &res,
    35673598                                    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,
    35703603                                    GTYPE_SECURITY_UNIVERSAL_GROUP,
    35713604                                    GTYPE_SECURITY_GLOBAL_GROUP);
     
    36663699        /* search for all requested objects in all domains. This could
    36673700           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),
    36693702                          LDB_SCOPE_SUBTREE, attrs, 0, "%s", filter);
    36703703        if (ret != LDB_SUCCESS) {
     
    37193752                                objectsid->sub_auths[objectsid->num_auths-1];
    37203753                        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);
    37253755                        entriesGeneral[count].account_name.string =
    37263756                                ldb_msg_find_attr_as_string(res->msgs[i],
     
    37403770                        /* No idea why we need to or in ACB_NORMAL here, but this is what Win2k3 seems to do... */
    37413771                        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;
    37463774                        entriesFull[count].account_name.string =
    37473775                                ldb_msg_find_attr_as_string(res->msgs[i],
     
    39353963        for (i=0; i<count; i++) {
    39363964                struct ldb_message *mod;
     3965                int ret;
    39373966
    39383967                mod = ldb_msg_new(mem_ctx);
     
    39473976                        return NT_STATUS_NO_MEMORY;
    39483977
    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);
    39523979                talloc_free(mod);
     3980                if (ret != LDB_SUCCESS) {
     3981                        return dsdb_ldb_err_to_ntstatus(ret);
     3982                }
    39533983        }
    39543984
     
    39904020        NTSTATUS status;
    39914021
    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        };
    39954027
    39964028        status = dcesrv_samr_QueryUserInfo(dce_call, mem_ctx, &r1);
     
    42884320        enum samr_ValidationStatus res;
    42894321        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        }
    42904332
    42914333        (*r->out.rep) = talloc_zero(mem_ctx, union samr_ValidatePasswordRep);
  • vendor/current/source4/rpc_server/samr/dcesrv_samr.h

    r740 r988  
    2121
    2222#include "param/param.h"
     23#include "libds/common/roles.h"
    2324
    2425/*
  • vendor/current/source4/rpc_server/samr/samr_password.c

    r860 r988  
    3030#include "libcli/auth/libcli_auth.h"
    3131#include "../lib/util/util_ldb.h"
     32#include "rpc_server/samr/proto.h"
     33#include "auth/auth_sam.h"
    3234
    3335/*
     
    6163        int ret;
    6264        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 };
    6470        struct samr_Password *lm_pwd;
    6571        DATA_BLOB lm_pwd_blob;
     
    6773        struct samr_Password lm_verifier;
    6874        size_t unicode_pw_len;
     75        size_t converted_size = 0;
    6976
    7077        if (pwbuf == NULL) {
     
    96103                           mem_ctx, NULL, &res, attrs,
    97104                           "(&(sAMAccountName=%s)(objectclass=user))",
    98                            r->in.account->string);
     105                           ldb_binary_encode_string(mem_ctx, r->in.account->string));
    99106        if (ret != 1) {
    100107                /* Don't give the game away:  (don't allow anonymous users to prove the existance of usernames) */
     
    106113        status = samdb_result_passwords(mem_ctx, dce_call->conn->dce_ctx->lp_ctx,
    107114                                        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) {
    109118                return NT_STATUS_WRONG_PASSWORD;
    110119        }
     
    117126        if (!extract_pw_from_buffer(mem_ctx, pwbuf->data, &new_password)) {
    118127                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),
    123133                                  CH_DOS, CH_UNIX,
    124134                                  (const char *)new_password.data,
    125135                                  new_password.length,
    126                                   (void **)&new_pass, NULL, false)) {
     136                                  (void **)&new_pass, &converted_size)) {
    127137                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),
    132143                                               CH_DOS, CH_UTF16,
    133144                                               (const char *)new_password.data,
    134145                                               new_password.length,
    135                                                (void **)&new_unicode_password.data, &unicode_pw_len, false)) {
     146                                               (void **)&new_unicode_password.data, &unicode_pw_len)) {
    136147                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));
    137149                return NT_STATUS_WRONG_PASSWORD;
    138150        }
     
    142154        E_old_pw_hash(new_lm_hash, lm_pwd->hash, lm_verifier.hash);
    143155        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));
    144157                return NT_STATUS_WRONG_PASSWORD;
    145158        }
     
    198211        DATA_BLOB new_password;
    199212        struct ldb_context *sam_ctx = NULL;
    200         struct ldb_dn *user_dn;
     213        struct ldb_dn *user_dn = NULL;
    201214        int ret;
    202215        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 };
    204221        struct samr_Password *nt_pwd, *lm_pwd;
    205222        DATA_BLOB nt_pwd_blob;
     
    233250                           mem_ctx, NULL, &res, attrs,
    234251                           "(&(sAMAccountName=%s)(objectclass=user))",
    235                            r->in.account->string);
     252                           ldb_binary_encode_string(mem_ctx, r->in.account->string));
    236253        if (ret != 1) {
    237254                /* Don't give the game away:  (don't allow anonymous users to prove the existance of usernames) */
     
    283300        if (lm_pwd && r->in.lm_verifier != NULL) {
    284301                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),
    286305                                          CH_UTF16, CH_UNIX,
    287306                                          (const char *)new_password.data,
    288307                                          new_password.length,
    289                                           (void **)&new_pass, NULL, false)) {
     308                                          (void **)&new_pass, &converted_size)) {
    290309                        E_deshash(new_pass, new_lm_hash);
    291310                        E_old_pw_hash(new_nt_hash, lm_pwd->hash, lm_verifier.hash);
     
    340359
    341360failed:
     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
    342366        reject = talloc_zero(mem_ctx, struct userPwdChangeFailureInformation);
    343367        if (reject != NULL) {
     
    396420        nt_status = dcesrv_fetch_session_key(dce_call->conn, &session_key);
    397421        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;
    399426        }
    400427
     
    435462        nt_status = dcesrv_fetch_session_key(dce_call->conn, &session_key);
    436463        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;
    438468        }
    439469
     
    477507{
    478508        struct samr_Password *d_lm_pwd_hash = NULL, *d_nt_pwd_hash = NULL;
     509        uint8_t random_session_key[16] = { 0, };
    479510        DATA_BLOB session_key = data_blob(NULL, 0);
    480511        DATA_BLOB in, out;
     
    482513
    483514        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        }
    484529        if (!NT_STATUS_IS_OK(nt_status)) {
    485530                return nt_status;
  • vendor/current/source4/rpc_server/service_rpc.c

    r740 r988  
    4040#include "smbd/process_model.h"
    4141
     42NTSTATUS server_service_rpc_init(void);
    4243
    4344/*
     
    7273
    7374        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
    7485                status = dcesrv_add_ep(dce_ctx, task->lp_ctx, e, task->event_ctx, model_ops);
    7586                if (!NT_STATUS_IS_OK(status)) goto failed;
    7687        }
    7788
     89        irpc_add_name(task->msg_ctx, "rpc_server");
    7890        return;
    7991failed:
  • vendor/current/source4/rpc_server/spoolss/dcesrv_spoolss.c

    r740 r988  
    221221
    222222        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);
    224224        NT_STATUS_NOT_OK_RETURN(status);
    225225
     
    270270        r2->in.devmode_ctr      = r->in.devmode_ctr;
    271271        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;
    275274        r2->out.handle          = r->out.handle;
    276275
     
    11581157{
    11591158        struct dcerpc_pipe *p;
     1159        char *binding_string;
    11601160        struct dcerpc_binding *binding;
    11611161        NTSTATUS status;
     
    11691169         * TODO: for now just open a connection to the client and drop it again
    11701170         *       to keep the w2k3 PrintServer
    1171          *       happy to allow to open the Add Printer GUI
     1171         *       happy to allow one to open the Add Printer GUI
    11721172         *       and the torture suite passing
    11731173         */
    11741174
    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)) {
    11791176                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        }
    11811189
    11821190        creds = cli_credentials_init_anon(mem_ctx); /* FIXME: Use machine credentials instead ? */
     
    15941602
    15951603/*
    1596   spoolss_61
    1597 */
    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*/
     1606static WERROR dcesrv_spoolss_RpcSendRecvBidiData(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
     1607                       struct spoolss_RpcSendRecvBidiData *r)
    16001608{
    16011609        DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
     
    17231731
    17241732
     1733/*
     1734  spoolss_RpcGetJobNamedPropertyValue
     1735*/
     1736static 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*/
     1746static 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*/
     1756static 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*/
     1765static 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}
    17251770
    17261771/* include the generated boilerplate */
  • vendor/current/source4/rpc_server/srvsvc/dcesrv_srvsvc.c

    r740 r988  
    623623                W_ERROR_HAVE_NO_MEMORY(info->info1->name);
    624624                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, "");
    626626                W_ERROR_HAVE_NO_MEMORY(info->info1->comment);
    627627
     
    633633                W_ERROR_HAVE_NO_MEMORY(info->info2->name);
    634634                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, "");
    636636                W_ERROR_HAVE_NO_MEMORY(info->info2->comment);
    637637                info->info2->permissions        = dcesrv_common_get_share_permissions(mem_ctx, dce_ctx, scfg);
     
    640640                info->info2->path               = dcesrv_common_get_share_path(mem_ctx, dce_ctx, scfg);
    641641                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);
    643643
    644644                return WERR_OK;
     
    649649                W_ERROR_HAVE_NO_MEMORY(info->info501->name);
    650650                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, "");
    652652                W_ERROR_HAVE_NO_MEMORY(info->info501->comment);
    653653                info->info501->csc_policy       = share_int_option(scfg, SHARE_CSC_POLICY, SHARE_CSC_POLICY_DEFAULT);
     
    660660                W_ERROR_HAVE_NO_MEMORY(info->info502->name);
    661661                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, "");
    663663                W_ERROR_HAVE_NO_MEMORY(info->info502->comment);
    664664                info->info502->permissions      = dcesrv_common_get_share_permissions(mem_ctx, dce_ctx, scfg);
     
    667667                info->info502->path             = dcesrv_common_get_share_path(mem_ctx, dce_ctx, scfg);
    668668                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);
    670670                info->info502->sd_buf.sd        = dcesrv_common_get_security_descriptor(mem_ctx, dce_ctx, scfg);
    671671
     
    13971397                        return ntstatus_to_werror(nterr);
    13981398                }
    1399                 path = share_string_option(scfg, SHARE_PATH, NULL);
     1399                path = share_string_option(mem_ctx, scfg, SHARE_PATH, NULL);
    14001400                if (!path) continue;
    14011401
    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);
    14041404                        if (!type) continue;
    14051405
     
    14651465                info101->version_minor  = server_info->version_minor;
    14661466                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);
    14681468                W_ERROR_HAVE_NO_MEMORY(info101->comment);
    14691469
     
    14851485                info102->version_minor  = server_info->version_minor;
    14861486                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);
    14881488                W_ERROR_HAVE_NO_MEMORY(info102->comment);
    14891489
  • vendor/current/source4/rpc_server/srvsvc/srvsvc_ntvfs.c

    r740 r988  
    2323#include "rpc_server/dcerpc_server.h"
    2424#include "param/param.h"
     25#include "rpc_server/srvsvc/proto.h"
    2526
    2627struct srvsvc_ntvfs_ctx {
     
    4546        struct share_context *sctx;
    4647        struct share_config *scfg;
    47         const char *sharetype;
     48        char *sharetype;
    4849        union smb_tcon tcon;
    4950        const struct tsocket_address *local_address;
     
    7172
    7273        /* 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);
    7475        if (sharetype && strcmp(sharetype, "IPC") == 0) {
    7576                type = NTVFS_IPC;
     
    7980                type = NTVFS_DISK;
    8081        }
     82
     83        TALLOC_FREE(sharetype);
    8184
    8285        c = talloc(mem_ctx, struct srvsvc_ntvfs_ctx);
  • vendor/current/source4/rpc_server/unixinfo/dcesrv_unixinfo.c

    r740 r988  
    2626#include "system/passwd.h"
    2727
    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_bind
    43 
    4428static NTSTATUS dcesrv_unixinfo_SidToUid(struct dcesrv_call_state *dce_call,
    4529                                  TALLOC_CTX *mem_ctx,
     
    4731{
    4832        NTSTATUS status;
    49         struct wbc_context *wbc_ctx = talloc_get_type_abort(
    50                                                 dce_call->context->private_data,
    51                                                 struct wbc_context);
    5233        struct id_map *ids;
    53         struct composite_context *ctx;
    5434
    5535        DEBUG(5, ("dcesrv_unixinfo_SidToUid called\n"));
     
    6141        ids->status = ID_UNKNOWN;
    6242        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);
    6744        NT_STATUS_NOT_OK_RETURN(status);
    6845
     
    8057                                  struct unixinfo_UidToSid *r)
    8158{
    82         struct wbc_context *wbc_ctx = talloc_get_type_abort(
    83                                                 dce_call->context->private_data,
    84                                                 struct wbc_context);
    8559        struct id_map *ids;
    86         struct composite_context *ctx;
    8760        uint32_t uid;
    8861        NTSTATUS status;
     
    10578        ids->xid.type = ID_TYPE_UID;
    10679
    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);
    11181        NT_STATUS_NOT_OK_RETURN(status);
    11282
     
    12090{
    12191        NTSTATUS status;
    122         struct wbc_context *wbc_ctx = talloc_get_type_abort(
    123                                                 dce_call->context->private_data,
    124                                                 struct wbc_context);
    12592        struct id_map *ids;
    126         struct composite_context *ctx;
    12793
    12894        DEBUG(5, ("dcesrv_unixinfo_SidToGid called\n"));
     
    134100        ids->status = ID_UNKNOWN;
    135101        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);
    140103        NT_STATUS_NOT_OK_RETURN(status);
    141104
     
    153116                                  struct unixinfo_GidToSid *r)
    154117{
    155         struct wbc_context *wbc_ctx = talloc_get_type_abort(
    156                                                 dce_call->context->private_data,
    157                                                 struct wbc_context);
    158118        struct id_map *ids;
    159         struct composite_context *ctx;
    160119        uint32_t gid;
    161120        NTSTATUS status;
     
    178137        ids->xid.type = ID_TYPE_GID;
    179138
    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);
    184140        NT_STATUS_NOT_OK_RETURN(status);
    185141
  • vendor/current/source4/rpc_server/winreg/rpc_winreg.c

    r740 r988  
    4343        if (!W_ERROR_IS_OK(err)) {
    4444                DEBUG(0, ("Error opening registry: %s\n", win_errstr(err)));
    45                 return NT_STATUS_UNSUCCESSFUL;
     45                return werror_to_ntstatus(err);
    4646        }
    4747
  • vendor/current/source4/rpc_server/wscript_build

    r740 r988  
    44        source='common/server_info.c common/share_info.c',
    55        autoproto='common/share.h',
    6         deps='ldb'
     6        deps='ldb',
     7        enabled=bld.AD_DC_BUILD_IS_ENABLED()
    78        )
    89
    910bld.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',
    1112        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()
    1315        )
    1416
     17bld.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        )
    1527
    1628bld.SAMBA_MODULE('dcerpc_rpcecho',
     
    6880        subsystem='dcerpc_server',
    6981        init_function='dcerpc_server_samr_init',
    70         deps='samdb DCERPC_COMMON ndr-standard'
     82        deps='samdb DCERPC_COMMON ndr-standard auth4_sam'
    7183        )
    7284
     
    8597        subsystem='dcerpc_server',
    8698        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'
    88100        )
    89101
     
    94106        subsystem='dcerpc_server',
    95107        init_function='dcerpc_server_lsa_init',
    96         deps='samdb DCERPC_COMMON ndr-standard LIBCLI_AUTH NDR_DSSETUP com_err security kdc-policy'
     108        deps='samdb DCERPC_COMMON ndr-standard LIBCLI_AUTH NDR_DSSETUP com_err samba-security UTIL_LSARPC'
    97109        )
    98110
    99111
    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         )
     112if 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                )
     120else:
     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                )
    107128
    108129
     
    120141        subsystem='dcerpc_server',
    121142        init_function='dcerpc_server_drsuapi_init',
    122         deps='samdb DCERPC_COMMON NDR_DRSUAPI security'
     143        deps='samdb DCERPC_COMMON NDR_DRSUAPI samba-security'
    123144        )
    124145
     
    138159        )
    139160
    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         )
     161bld.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
    149168
    150169bld.SAMBA_MODULE('service_dcerpc',
Note: See TracChangeset for help on using the changeset viewer.