Ignore:
Timestamp:
Nov 27, 2012, 4:43:17 PM (13 years ago)
Author:
Silvan Scherrer
Message:

Samba Server: updated trunk to 3.6.0

Location:
trunk/server
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/server

  • trunk/server/source4/rpc_server/netlogon/dcerpc_netlogon.c

    r414 r745  
    1 /* 
     1/*
    22   Unix SMB/CIFS implementation.
    33
     
    66   Copyright (C) Andrew Bartlett <abartlet@samba.org> 2004-2008
    77   Copyright (C) Stefan Metzmacher <metze@samba.org>  2005
    8    Copyright (C) Matthias Dieter Wallnöfer            2009
    9    
     8   Copyright (C) Matthias Dieter Wallnöfer            2009-2010
     9
    1010   This program is free software; you can redistribute it and/or modify
    1111   it under the terms of the GNU General Public License as published by
    1212   the Free Software Foundation; either version 3 of the License, or
    1313   (at your option) any later version.
    14    
     14
    1515   This program is distributed in the hope that it will be useful,
    1616   but WITHOUT ANY WARRANTY; without even the implied warranty of
    1717   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    1818   GNU General Public License for more details.
    19    
     19
    2020   You should have received a copy of the GNU General Public License
    2121   along with this program.  If not, see <http://www.gnu.org/licenses/>.
     
    2929#include "../lib/util/util_ldb.h"
    3030#include "../libcli/auth/schannel.h"
    31 #include "auth/gensec/schannel_state.h"
    3231#include "libcli/security/security.h"
    3332#include "param/param.h"
    3433#include "lib/messaging/irpc.h"
     34#include "librpc/gen_ndr/ndr_irpc_c.h"
     35#include "../libcli/ldap/ldap_ndr.h"
     36#include "cldap_server/cldap_server.h"
     37#include "lib/tsocket/tsocket.h"
     38#include "librpc/gen_ndr/ndr_netlogon.h"
    3539#include "librpc/gen_ndr/ndr_irpc.h"
    3640
     
    4044};
    4145
    42 
    4346static NTSTATUS dcesrv_netr_ServerReqChallenge(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
    4447                                        struct netr_ServerReqChallenge *r)
     
    5558                dce_call->context->private_data = NULL;
    5659        }
    57        
     60
    5861        pipe_state = talloc(dce_call->context, struct netlogon_server_pipe_state);
    5962        NT_STATUS_HAVE_NO_MEMORY(pipe_state);
     
    6164        pipe_state->client_challenge = *r->in.credentials;
    6265
    63         generate_random_buffer(pipe_state->server_challenge.data, 
     66        generate_random_buffer(pipe_state->server_challenge.data,
    6467                               sizeof(pipe_state->server_challenge.data));
    6568
     
    7780                talloc_get_type(dce_call->context->private_data, struct netlogon_server_pipe_state);
    7881        struct netlogon_creds_CredentialState *creds;
    79         struct ldb_context *schannel_ldb;
    8082        struct ldb_context *sam_ctx;
    8183        struct samr_Password *mach_pwd;
     
    8486        struct ldb_message **msgs;
    8587        NTSTATUS nt_status;
    86         const char *attrs[] = {"unicodePwd", "userAccountControl", 
     88        const char *attrs[] = {"unicodePwd", "userAccountControl",
    8789                               "objectSid", NULL};
    8890
     
    124126                                  NETLOGON_NEG_AUTHENTICATED_RPC;
    125127
    126         if (!pipe_state) {
    127                 DEBUG(1, ("No challenge requested by client, cannot authenticate\n"));
    128                 return NT_STATUS_ACCESS_DENIED;
    129         }
    130 
    131         sam_ctx = samdb_connect(mem_ctx, dce_call->event_ctx, dce_call->conn->dce_ctx->lp_ctx,
    132                                 system_session(mem_ctx, dce_call->conn->dce_ctx->lp_ctx));
     128        switch (r->in.secure_channel_type) {
     129        case SEC_CHAN_WKSTA:
     130        case SEC_CHAN_DNS_DOMAIN:
     131        case SEC_CHAN_DOMAIN:
     132        case SEC_CHAN_BDC:
     133        case SEC_CHAN_RODC:
     134                break;
     135        default:
     136                DEBUG(1, ("Client asked for an invalid secure channel type: %d\n",
     137                          r->in.secure_channel_type));
     138                return NT_STATUS_INVALID_PARAMETER;
     139        }
     140
     141        sam_ctx = samdb_connect(mem_ctx, dce_call->event_ctx, dce_call->conn->dce_ctx->lp_ctx,
     142                                system_session(dce_call->conn->dce_ctx->lp_ctx), 0);
    133143        if (sam_ctx == NULL) {
    134144                return NT_STATUS_INVALID_SYSTEM_SERVICE;
     
    150160                num_records = gendb_search(sam_ctx, mem_ctx, NULL, &msgs,
    151161                                           trust_dom_attrs,
    152                                            "(&(trustPartner=%s)(objectclass=trustedDomain))", 
     162                                           "(&(trustPartner=%s)(objectclass=trustedDomain))",
    153163                                           encoded_account);
    154                
     164
    155165                if (num_records == 0) {
    156                         DEBUG(3,("Couldn't find trust [%s] in samdb.\n", 
     166                        DEBUG(3,("Couldn't find trust [%s] in samdb.\n",
    157167                                 encoded_account));
    158                         return NT_STATUS_ACCESS_DENIED;
    159                 }
    160                
     168                        return NT_STATUS_NO_TRUST_SAM_ACCOUNT;
     169                }
     170
    161171                if (num_records > 1) {
    162172                        DEBUG(0,("Found %d records matching user [%s]\n", num_records, r->in.account_name));
    163173                        return NT_STATUS_INTERNAL_DB_CORRUPTION;
    164174                }
    165                
     175
    166176                flatname = ldb_msg_find_attr_as_string(msgs[0], "flatname", NULL);
    167177                if (!flatname) {
    168178                        /* No flatname for this trust - we can't proceed */
    169                         return NT_STATUS_ACCESS_DENIED;
     179                        return NT_STATUS_NO_TRUST_SAM_ACCOUNT;
    170180                }
    171181                account_name = talloc_asprintf(mem_ctx, "%s$", flatname);
     
    174184                        return NT_STATUS_NO_MEMORY;
    175185                }
    176                
     186
    177187        } else {
    178188                account_name = r->in.account_name;
    179189        }
    180        
     190
    181191        /* pull the user attributes */
    182192        num_records = gendb_search(sam_ctx, mem_ctx, NULL, &msgs, attrs,
    183                                    "(&(sAMAccountName=%s)(objectclass=user))", 
     193                                   "(&(sAMAccountName=%s)(objectclass=user))",
    184194                                   ldb_binary_encode_string(mem_ctx, account_name));
    185195
    186196        if (num_records == 0) {
    187                 DEBUG(3,("Couldn't find user [%s] in samdb.\n", 
     197                DEBUG(3,("Couldn't find user [%s] in samdb.\n",
    188198                         r->in.account_name));
    189                 return NT_STATUS_ACCESS_DENIED;
     199                return NT_STATUS_NO_TRUST_SAM_ACCOUNT;
    190200        }
    191201
     
    195205        }
    196206
    197        
    198207        user_account_control = ldb_msg_find_attr_as_uint(msgs[0], "userAccountControl", 0);
    199208
    200209        if (user_account_control & UF_ACCOUNTDISABLE) {
    201210                DEBUG(1, ("Account [%s] is disabled\n", r->in.account_name));
    202                 return NT_STATUS_ACCESS_DENIED;
     211                return NT_STATUS_NO_TRUST_SAM_ACCOUNT;
    203212        }
    204213
     
    206215                if (!(user_account_control & UF_WORKSTATION_TRUST_ACCOUNT)) {
    207216                        DEBUG(1, ("Client asked for a workstation secure channel, but is not a workstation (member server) acb flags: 0x%x\n", user_account_control));
    208                         return NT_STATUS_ACCESS_DENIED;
    209                 }
    210         } else if (r->in.secure_channel_type == SEC_CHAN_DOMAIN || 
     217                        return NT_STATUS_NO_TRUST_SAM_ACCOUNT;
     218                }
     219        } else if (r->in.secure_channel_type == SEC_CHAN_DOMAIN ||
    211220                   r->in.secure_channel_type == SEC_CHAN_DNS_DOMAIN) {
    212221                if (!(user_account_control & UF_INTERDOMAIN_TRUST_ACCOUNT)) {
    213222                        DEBUG(1, ("Client asked for a trusted domain secure channel, but is not a trusted domain: acb flags: 0x%x\n", user_account_control));
    214                        
    215                         return NT_STATUS_ACCESS_DENIED;
     223
     224                        return NT_STATUS_NO_TRUST_SAM_ACCOUNT;
    216225                }
    217226        } else if (r->in.secure_channel_type == SEC_CHAN_BDC) {
    218227                if (!(user_account_control & UF_SERVER_TRUST_ACCOUNT)) {
    219228                        DEBUG(1, ("Client asked for a server secure channel, but is not a server (domain controller): acb flags: 0x%x\n", user_account_control));
    220                         return NT_STATUS_ACCESS_DENIED;
     229                        return NT_STATUS_NO_TRUST_SAM_ACCOUNT;
     230                }
     231        } else if (r->in.secure_channel_type == SEC_CHAN_RODC) {
     232                if (!(user_account_control & UF_PARTIAL_SECRETS_ACCOUNT)) {
     233                        DEBUG(1, ("Client asked for a RODC secure channel, but is not a RODC: acb flags: 0x%x\n", user_account_control));
     234                        return NT_STATUS_NO_TRUST_SAM_ACCOUNT;
    221235                }
    222236        } else {
    223                 DEBUG(1, ("Client asked for an invalid secure channel type: %d\n",
    224                           r->in.secure_channel_type));
    225                 return NT_STATUS_ACCESS_DENIED;
    226         }
    227 
    228         *r->out.rid = samdb_result_rid_from_sid(mem_ctx, msgs[0],
     237                /* we should never reach this */
     238                return NT_STATUS_INTERNAL_ERROR;
     239        }
     240
     241        *r->out.rid = samdb_result_rid_from_sid(mem_ctx, msgs[0],
    229242                                                "objectSid", 0);
    230243
     
    234247        }
    235248
    236         creds = netlogon_creds_server_init(mem_ctx,     
     249        if (!pipe_state) {
     250                DEBUG(1, ("No challenge requested by client, cannot authenticate\n"));
     251                return NT_STATUS_ACCESS_DENIED;
     252        }
     253
     254        creds = netlogon_creds_server_init(mem_ctx,
    237255                                           r->in.account_name,
    238256                                           r->in.computer_name,
    239257                                           r->in.secure_channel_type,
    240                                            &pipe_state->client_challenge, 
    241                                            &pipe_state->server_challenge, 
     258                                           &pipe_state->client_challenge,
     259                                           &pipe_state->server_challenge,
    242260                                           mach_pwd,
    243261                                           r->in.credentials,
    244262                                           r->out.return_credentials,
    245263                                           *r->in.negotiate_flags);
    246        
     264
    247265        if (!creds) {
    248266                return NT_STATUS_ACCESS_DENIED;
     
    251269        creds->sid = samdb_result_dom_sid(creds, msgs[0], "objectSid");
    252270
    253         schannel_ldb = schannel_db_connect(mem_ctx, dce_call->event_ctx, dce_call->conn->dce_ctx->lp_ctx);
    254         if (!schannel_ldb) {
    255                 return NT_STATUS_ACCESS_DENIED;
    256         }
    257 
    258         nt_status = schannel_store_session_key_ldb(schannel_ldb, mem_ctx, creds);
    259         talloc_free(schannel_ldb);
     271        nt_status = schannel_save_creds_state(mem_ctx,
     272                                              lpcfg_private_dir(dce_call->conn->dce_ctx->lp_ctx),
     273                                              creds);
    260274
    261275        return nt_status;
    262276}
    263                                                  
     277
    264278static NTSTATUS dcesrv_netr_ServerAuthenticate(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
    265279                                        struct netr_ServerAuthenticate *r)
     
    267281        struct netr_ServerAuthenticate3 a;
    268282        uint32_t rid;
    269         /* TODO: 
     283        /* TODO:
    270284         * negotiate_flags is used as an [in] parameter
    271285         * so it need to be initialised.
     
    305319        r3.out.negotiate_flags = r->out.negotiate_flags;
    306320        r3.out.rid = &rid;
    307        
     321
    308322        return dcesrv_netr_ServerAuthenticate3(dce_call, mem_ctx, &r3);
    309323}
    310324
    311325/*
    312   Validate an incoming authenticator against the credentials for the remote machine.
    313 
    314   The credentials are (re)read and from the schannel database, and
    315   written back after the caclulations are performed.
    316 
    317   The creds_out parameter (if not NULL) returns the credentials, if
    318   the caller needs some of that information.
    319 
    320 */
     326 * NOTE: The following functions are nearly identical to the ones available in
     327 * source3/rpc_server/srv_nelog_nt.c
     328 * The reason we keep 2 copies is that they use different structures to
     329 * represent the auth_info and the decrpc pipes.
     330 */
     331
     332/*
     333 * If schannel is required for this call test that it actually is available.
     334 */
     335static NTSTATUS schannel_check_required(struct dcerpc_auth *auth_info,
     336                                        const char *computer_name,
     337                                        bool integrity, bool privacy)
     338{
     339
     340        if (auth_info && auth_info->auth_type == DCERPC_AUTH_TYPE_SCHANNEL) {
     341                if (!privacy && !integrity) {
     342                        return NT_STATUS_OK;
     343                }
     344
     345                if ((!privacy && integrity) &&
     346                    auth_info->auth_level == DCERPC_AUTH_LEVEL_INTEGRITY) {
     347                        return NT_STATUS_OK;
     348                }
     349
     350                if ((privacy || integrity) &&
     351                    auth_info->auth_level == DCERPC_AUTH_LEVEL_PRIVACY) {
     352                        return NT_STATUS_OK;
     353                }
     354        }
     355
     356        /* test didn't pass */
     357        DEBUG(0, ("schannel_check_required: [%s] is not using schannel\n",
     358                  computer_name));
     359
     360        return NT_STATUS_ACCESS_DENIED;
     361}
     362
    321363static NTSTATUS dcesrv_netr_creds_server_step_check(struct dcesrv_call_state *dce_call,
    322                                                     TALLOC_CTX *mem_ctx, 
     364                                                    TALLOC_CTX *mem_ctx,
    323365                                                    const char *computer_name,
    324366                                                    struct netr_Authenticator *received_authenticator,
    325367                                                    struct netr_Authenticator *return_authenticator,
    326                                                     struct netlogon_creds_CredentialState **creds_out) 
     368                                                    struct netlogon_creds_CredentialState **creds_out)
    327369{
    328370        NTSTATUS nt_status;
    329         struct ldb_context *ldb;
    330         bool schannel_global_required = false; /* Should be lp_schannel_server() == true */
    331         bool schannel_in_use = dce_call->conn->auth_state.auth_info
    332                 && dce_call->conn->auth_state.auth_info->auth_type == DCERPC_AUTH_TYPE_SCHANNEL
    333                 && (dce_call->conn->auth_state.auth_info->auth_level == DCERPC_AUTH_LEVEL_INTEGRITY
    334                     || dce_call->conn->auth_state.auth_info->auth_level == DCERPC_AUTH_LEVEL_PRIVACY);
    335 
    336         ldb = schannel_db_connect(mem_ctx, dce_call->event_ctx, dce_call->conn->dce_ctx->lp_ctx);
    337         if (!ldb) {
    338                 return NT_STATUS_ACCESS_DENIED;
    339         }
    340         nt_status = schannel_creds_server_step_check_ldb(ldb, mem_ctx,
    341                                                          computer_name,
    342                                                          schannel_global_required,
    343                                                          schannel_in_use,
    344                                                         received_authenticator,
    345                                                          return_authenticator, creds_out);
    346         talloc_free(ldb);
     371        struct dcerpc_auth *auth_info = dce_call->conn->auth_state.auth_info;
     372        bool schannel_global_required = false; /* Should be lpcfg_schannel_server() == true */
     373
     374        if (schannel_global_required) {
     375                nt_status = schannel_check_required(auth_info,
     376                                                    computer_name,
     377                                                    true, false);
     378                if (!NT_STATUS_IS_OK(nt_status)) {
     379                        return nt_status;
     380                }
     381        }
     382
     383        nt_status = schannel_check_creds_state(mem_ctx,
     384                                               lpcfg_private_dir(dce_call->conn->dce_ctx->lp_ctx),
     385                                               computer_name,
     386                                              received_authenticator,
     387                                               return_authenticator,
     388                                               creds_out);
    347389        return nt_status;
    348390}
    349391
    350 /* 
     392/*
    351393  Change the machine account password for the currently connected
    352394  client.  Supplies only the NT#.
     
    358400        struct netlogon_creds_CredentialState *creds;
    359401        struct ldb_context *sam_ctx;
     402        const char * const attrs[] = { "unicodePwd", NULL };
     403        struct ldb_message **res;
     404        struct samr_Password *oldNtHash;
    360405        NTSTATUS nt_status;
     406        int ret;
    361407
    362408        nt_status = dcesrv_netr_creds_server_step_check(dce_call,
    363                                                         mem_ctx, 
    364                                                         r->in.computer_name, 
     409                                                        mem_ctx,
     410                                                        r->in.computer_name,
    365411                                                        r->in.credential, r->out.return_authenticator,
    366412                                                        &creds);
    367413        NT_STATUS_NOT_OK_RETURN(nt_status);
    368414
    369         sam_ctx = samdb_connect(mem_ctx, dce_call->event_ctx, dce_call->conn->dce_ctx->lp_ctx, system_session(mem_ctx, dce_call->conn->dce_ctx->lp_ctx));
     415        sam_ctx = samdb_connect(mem_ctx, dce_call->event_ctx, dce_call->conn->dce_ctx->lp_ctx, system_session(dce_call->conn->dce_ctx->lp_ctx), 0);
    370416        if (sam_ctx == NULL) {
    371417                return NT_STATUS_INVALID_SYSTEM_SERVICE;
     
    374420        netlogon_creds_des_decrypt(creds, r->in.new_password);
    375421
     422        /* fetch the old password hashes (the NT hash has to exist) */
     423
     424        ret = gendb_search(sam_ctx, mem_ctx, NULL, &res, attrs,
     425                           "(&(objectClass=user)(objectSid=%s))",
     426                           ldap_encode_ndr_dom_sid(mem_ctx, creds->sid));
     427        if (ret != 1) {
     428                return NT_STATUS_WRONG_PASSWORD;
     429        }
     430
     431        nt_status = samdb_result_passwords(mem_ctx,
     432                                           dce_call->conn->dce_ctx->lp_ctx,
     433                                           res[0], NULL, &oldNtHash);
     434        if (!NT_STATUS_IS_OK(nt_status) || !oldNtHash) {
     435                return NT_STATUS_WRONG_PASSWORD;
     436        }
     437
    376438        /* Using the sid for the account as the key, set the password */
    377         nt_status = samdb_set_password_sid(sam_ctx, mem_ctx, 
     439        nt_status = samdb_set_password_sid(sam_ctx, mem_ctx,
    378440                                           creds->sid,
    379441                                           NULL, /* Don't have plaintext */
    380442                                           NULL, r->in.new_password,
    381                                            true, /* Password change */
     443                                           NULL, oldNtHash, /* Password change */
    382444                                           NULL, NULL);
    383445        return nt_status;
    384446}
    385447
    386 /* 
     448/*
    387449  Change the machine account password for the currently connected
    388450  client.  Supplies new plaintext.
     
    393455        struct netlogon_creds_CredentialState *creds;
    394456        struct ldb_context *sam_ctx;
     457        const char * const attrs[] = { "dBCSPwd", "unicodePwd", NULL };
     458        struct ldb_message **res;
     459        struct samr_Password *oldLmHash, *oldNtHash;
    395460        NTSTATUS nt_status;
    396461        DATA_BLOB new_password;
     462        int ret;
    397463
    398464        struct samr_CryptPassword password_buf;
    399465
    400466        nt_status = dcesrv_netr_creds_server_step_check(dce_call,
    401                                                         mem_ctx, 
    402                                                         r->in.computer_name, 
     467                                                        mem_ctx,
     468                                                        r->in.computer_name,
    403469                                                        r->in.credential, r->out.return_authenticator,
    404470                                                        &creds);
    405471        NT_STATUS_NOT_OK_RETURN(nt_status);
    406472
    407         sam_ctx = samdb_connect(mem_ctx, dce_call->event_ctx, dce_call->conn->dce_ctx->lp_ctx, system_session(mem_ctx, dce_call->conn->dce_ctx->lp_ctx));
     473        sam_ctx = samdb_connect(mem_ctx, dce_call->event_ctx, dce_call->conn->dce_ctx->lp_ctx, system_session(dce_call->conn->dce_ctx->lp_ctx), 0);
    408474        if (sam_ctx == NULL) {
    409475                return NT_STATUS_INVALID_SYSTEM_SERVICE;
     
    418484                return NT_STATUS_WRONG_PASSWORD;
    419485        }
    420                
     486
     487        /* fetch the old password hashes (at least one of both has to exist) */
     488
     489        ret = gendb_search(sam_ctx, mem_ctx, NULL, &res, attrs,
     490                           "(&(objectClass=user)(objectSid=%s))",
     491                           ldap_encode_ndr_dom_sid(mem_ctx, creds->sid));
     492        if (ret != 1) {
     493                return NT_STATUS_WRONG_PASSWORD;
     494        }
     495
     496        nt_status = samdb_result_passwords(mem_ctx,
     497                                           dce_call->conn->dce_ctx->lp_ctx,
     498                                           res[0], &oldLmHash, &oldNtHash);
     499        if (!NT_STATUS_IS_OK(nt_status) || (!oldLmHash && !oldNtHash)) {
     500                return NT_STATUS_WRONG_PASSWORD;
     501        }
     502
    421503        /* Using the sid for the account as the key, set the password */
    422504        nt_status = samdb_set_password_sid(sam_ctx, mem_ctx,
     
    424506                                           &new_password, /* we have plaintext */
    425507                                           NULL, NULL,
    426                                            true, /* Password change */
     508                                           oldLmHash, oldNtHash, /* Password change */
    427509                                           NULL, NULL);
    428510        return nt_status;
     
    430512
    431513
    432 /* 
    433   netr_LogonUasLogon 
     514/*
     515  netr_LogonUasLogon
    434516*/
    435517static WERROR dcesrv_netr_LogonUasLogon(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
     
    440522
    441523
    442 /* 
    443   netr_LogonUasLogoff 
     524/*
     525  netr_LogonUasLogoff
    444526*/
    445527static WERROR dcesrv_netr_LogonUasLogoff(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
     
    450532
    451533
    452 /*
     534static NTSTATUS dcesrv_netr_LogonSamLogon_check(const struct netr_LogonSamLogonEx *r)
     535{
     536        switch (r->in.logon_level) {
     537        case NetlogonInteractiveInformation:
     538        case NetlogonServiceInformation:
     539        case NetlogonInteractiveTransitiveInformation:
     540        case NetlogonServiceTransitiveInformation:
     541                if (r->in.logon->password == NULL) {
     542                        return NT_STATUS_INVALID_PARAMETER;
     543                }
     544
     545                switch (r->in.validation_level) {
     546                case NetlogonValidationSamInfo:  /* 2 */
     547                case NetlogonValidationSamInfo2: /* 3 */
     548                case NetlogonValidationSamInfo4: /* 6 */
     549                        break;
     550                default:
     551                        return NT_STATUS_INVALID_INFO_CLASS;
     552                }
     553
     554                break;
     555        case NetlogonNetworkInformation:
     556        case NetlogonNetworkTransitiveInformation:
     557                if (r->in.logon->network == NULL) {
     558                        return NT_STATUS_INVALID_PARAMETER;
     559                }
     560
     561                switch (r->in.validation_level) {
     562                case NetlogonValidationSamInfo:  /* 2 */
     563                case NetlogonValidationSamInfo2: /* 3 */
     564                case NetlogonValidationSamInfo4: /* 6 */
     565                        break;
     566                default:
     567                        return NT_STATUS_INVALID_INFO_CLASS;
     568                }
     569
     570                break;
     571
     572        case NetlogonGenericInformation:
     573                if (r->in.logon->generic == NULL) {
     574                        return NT_STATUS_INVALID_PARAMETER;
     575                }
     576
     577                switch (r->in.validation_level) {
     578                /* TODO: case NetlogonValidationGenericInfo: 4 */
     579                case NetlogonValidationGenericInfo2: /* 5 */
     580                        break;
     581                default:
     582                        return NT_STATUS_INVALID_INFO_CLASS;
     583                }
     584
     585                break;
     586        default:
     587                return NT_STATUS_INVALID_PARAMETER;
     588        }
     589
     590        return NT_STATUS_OK;
     591}
     592
     593/*
    453594  netr_LogonSamLogon_base
    454595
     
    462603        struct auth_context *auth_context;
    463604        struct auth_usersupplied_info *user_info;
    464         struct auth_serversupplied_info *server_info;
     605        struct auth_user_info_dc *user_info_dc;
    465606        NTSTATUS nt_status;
    466607        static const char zeros[16];
     
    469610        struct netr_SamInfo3 *sam3;
    470611        struct netr_SamInfo6 *sam6;
    471        
    472         user_info = talloc(mem_ctx, struct auth_usersupplied_info);
     612
     613        *r->out.authoritative = 1;
     614
     615        user_info = talloc_zero(mem_ctx, struct auth_usersupplied_info);
    473616        NT_STATUS_HAVE_NO_MEMORY(user_info);
    474 
    475         user_info->flags = 0;
    476         user_info->mapped_state = false;
    477         user_info->remote_host = NULL;
    478617
    479618        switch (r->in.logon_level) {
     
    483622        case NetlogonServiceTransitiveInformation:
    484623                if (creds->negotiate_flags & NETLOGON_NEG_ARCFOUR) {
    485                         netlogon_creds_arcfour_crypt(creds, 
     624                        netlogon_creds_arcfour_crypt(creds,
    486625                                            r->in.logon->password->lmpassword.hash,
    487626                                            sizeof(r->in.logon->password->lmpassword.hash));
    488                         netlogon_creds_arcfour_crypt(creds, 
     627                        netlogon_creds_arcfour_crypt(creds,
    489628                                            r->in.logon->password->ntpassword.hash,
    490629                                            sizeof(r->in.logon->password->ntpassword.hash));
     
    495634
    496635                /* TODO: we need to deny anonymous access here */
    497                 nt_status = auth_context_create(mem_ctx, 
     636                nt_status = auth_context_create(mem_ctx,
    498637                                                dce_call->event_ctx, dce_call->msg_ctx,
    499638                                                dce_call->conn->dce_ctx->lp_ctx,
     
    505644                user_info->client.domain_name = r->in.logon->password->identity_info.domain_name.string;
    506645                user_info->workstation_name = r->in.logon->password->identity_info.workstation.string;
    507                
     646
    508647                user_info->flags |= USER_INFO_INTERACTIVE_LOGON;
    509648                user_info->password_state = AUTH_PASSWORD_HASH;
     
    522661
    523662                /* TODO: we need to deny anonymous access here */
    524                 nt_status = auth_context_create(mem_ctx, 
     663                nt_status = auth_context_create(mem_ctx,
    525664                                                dce_call->event_ctx, dce_call->msg_ctx,
    526665                                                dce_call->conn->dce_ctx->lp_ctx,
     
    535674                user_info->client.domain_name = r->in.logon->network->identity_info.domain_name.string;
    536675                user_info->workstation_name = r->in.logon->network->identity_info.workstation.string;
    537                
     676
    538677                user_info->password_state = AUTH_PASSWORD_RESPONSE;
    539678                user_info->password.response.lanman = data_blob_talloc(mem_ctx, r->in.logon->network->lm.data, r->in.logon->network->lm.length);
    540679                user_info->password.response.nt = data_blob_talloc(mem_ctx, r->in.logon->network->nt.data, r->in.logon->network->nt.length);
    541        
     680
    542681                break;
    543682
    544                
     683
    545684        case NetlogonGenericInformation:
    546685        {
    547686                if (creds->negotiate_flags & NETLOGON_NEG_ARCFOUR) {
    548                         netlogon_creds_arcfour_crypt(creds, 
     687                        netlogon_creds_arcfour_crypt(creds,
    549688                                            r->in.logon->generic->data, r->in.logon->generic->length);
    550689                } else {
     
    555694                if (strcmp(r->in.logon->generic->package_name.string, "Kerberos") == 0) {
    556695                        NTSTATUS status;
    557                         struct server_id *kdc;
     696                        struct dcerpc_binding_handle *irpc_handle;
    558697                        struct kdc_check_generic_kerberos check;
    559698                        struct netr_GenericInfo2 *generic = talloc_zero(mem_ctx, struct netr_GenericInfo2);
    560699                        NT_STATUS_HAVE_NO_MEMORY(generic);
    561700                        *r->out.authoritative = 1;
    562                        
     701
    563702                        /* TODO: Describe and deal with these flags */
    564703                        *r->out.flags = 0;
    565704
    566705                        r->out.validation->generic = generic;
    567        
    568                         kdc = irpc_servers_byname(dce_call->msg_ctx, mem_ctx, "kdc_server");
    569                         if ((kdc == NULL) || (kdc[0].id == 0)) {
     706
     707                        irpc_handle = irpc_binding_handle_by_name(mem_ctx,
     708                                                                  dce_call->msg_ctx,
     709                                                                  "kdc_server",
     710                                                                  &ndr_table_irpc);
     711                        if (irpc_handle == NULL) {
    570712                                return NT_STATUS_NO_LOGON_SERVERS;
    571713                        }
    572                        
    573                         check.in.generic_request = 
     714
     715                        check.in.generic_request =
    574716                                data_blob_const(r->in.logon->generic->data,
    575717                                                r->in.logon->generic->length);
    576                        
    577                         status = irpc_call(dce_call->msg_ctx, kdc[0],
    578                                            &ndr_table_irpc, NDR_KDC_CHECK_GENERIC_KERBEROS,
    579                                            &check, mem_ctx);
     718
     719                        status = dcerpc_kdc_check_generic_kerberos_r(irpc_handle,
     720                                                                     mem_ctx,
     721                                                                     &check);
    580722                        if (!NT_STATUS_IS_OK(status)) {
    581723                                return status;
     
    592734                return NT_STATUS_INVALID_PARAMETER;
    593735        }
    594        
    595         nt_status = auth_check_password(auth_context, mem_ctx, user_info, &server_info);
     736
     737        nt_status = auth_check_password(auth_context, mem_ctx, user_info, &user_info_dc);
     738        /* TODO: set *r->out.authoritative = 0 on specific errors */
    596739        NT_STATUS_NOT_OK_RETURN(nt_status);
    597740
    598         nt_status = auth_convert_server_info_sambaseinfo(mem_ctx, server_info, &sam);
    599         NT_STATUS_NOT_OK_RETURN(nt_status);
     741        switch (r->in.validation_level) {
     742        case 2:
     743                nt_status = auth_convert_user_info_dc_sambaseinfo(mem_ctx, user_info_dc, &sam);
     744                NT_STATUS_NOT_OK_RETURN(nt_status);
     745
     746                sam2 = talloc_zero(mem_ctx, struct netr_SamInfo2);
     747                NT_STATUS_HAVE_NO_MEMORY(sam2);
     748                sam2->base = *sam;
     749
     750                /* And put into the talloc tree */
     751                talloc_steal(sam2, sam);
     752                r->out.validation->sam2 = sam2;
     753
     754                sam = &sam2->base;
     755                break;
     756
     757        case 3:
     758                nt_status = auth_convert_user_info_dc_saminfo3(mem_ctx,
     759                                                              user_info_dc,
     760                                                              &sam3);
     761                NT_STATUS_NOT_OK_RETURN(nt_status);
     762
     763                r->out.validation->sam3 = sam3;
     764
     765                sam = &sam3->base;
     766                break;
     767
     768        case 6:
     769                nt_status = auth_convert_user_info_dc_saminfo3(mem_ctx,
     770                                                           user_info_dc,
     771                                                           &sam3);
     772                NT_STATUS_NOT_OK_RETURN(nt_status);
     773
     774                sam6 = talloc_zero(mem_ctx, struct netr_SamInfo6);
     775                NT_STATUS_HAVE_NO_MEMORY(sam6);
     776                sam6->base = sam3->base;
     777                sam = &sam6->base;
     778                sam6->sidcount = sam3->sidcount;
     779                sam6->sids = sam3->sids;
     780
     781                sam6->dns_domainname.string = lpcfg_dnsdomain(dce_call->conn->dce_ctx->lp_ctx);
     782                sam6->principle.string = talloc_asprintf(mem_ctx, "%s@%s",
     783                                                         sam->account_name.string, sam6->dns_domainname.string);
     784                NT_STATUS_HAVE_NO_MEMORY(sam6->principle.string);
     785                /* And put into the talloc tree */
     786                talloc_steal(sam6, sam3);
     787
     788                r->out.validation->sam6 = sam6;
     789                break;
     790
     791        default:
     792                return NT_STATUS_INVALID_INFO_CLASS;
     793        }
    600794
    601795        /* Don't crypt an all-zero key, it would give away the NETLOGON pipe session key */
     
    605799                /* This key is sent unencrypted without the ARCFOUR flag set */
    606800                if (creds->negotiate_flags & NETLOGON_NEG_ARCFOUR) {
    607                         netlogon_creds_arcfour_crypt(creds, 
    608                                             sam->key.key, 
     801                        netlogon_creds_arcfour_crypt(creds,
     802                                            sam->key.key,
    609803                                            sizeof(sam->key.key));
    610804                }
     
    616810            memcmp(sam->LMSessKey.key, zeros, sizeof(sam->LMSessKey.key)) != 0) {
    617811                if (creds->negotiate_flags & NETLOGON_NEG_ARCFOUR) {
    618                         netlogon_creds_arcfour_crypt(creds, 
    619                                             sam->LMSessKey.key, 
     812                        netlogon_creds_arcfour_crypt(creds,
     813                                            sam->LMSessKey.key,
    620814                                            sizeof(sam->LMSessKey.key));
    621815                } else {
    622                         netlogon_creds_des_encrypt_LMKey(creds, 
     816                        netlogon_creds_des_encrypt_LMKey(creds,
    623817                                                &sam->LMSessKey);
    624818                }
    625819        }
    626 
    627         switch (r->in.validation_level) {
    628         case 2:
    629                 sam2 = talloc_zero(mem_ctx, struct netr_SamInfo2);
    630                 NT_STATUS_HAVE_NO_MEMORY(sam2);
    631                 sam2->base = *sam;
    632                 r->out.validation->sam2 = sam2;
    633                 break;
    634 
    635         case 3:
    636                 sam3 = talloc_zero(mem_ctx, struct netr_SamInfo3);
    637                 NT_STATUS_HAVE_NO_MEMORY(sam3);
    638                 sam3->base = *sam;
    639                 r->out.validation->sam3 = sam3;
    640                 break;
    641 
    642         case 6:
    643                 sam6 = talloc_zero(mem_ctx, struct netr_SamInfo6);
    644                 NT_STATUS_HAVE_NO_MEMORY(sam6);
    645                 sam6->base = *sam;
    646                 sam6->forest.string = lp_realm(dce_call->conn->dce_ctx->lp_ctx);
    647                 sam6->principle.string = talloc_asprintf(mem_ctx, "%s@%s",
    648                                                          sam->account_name.string, sam6->forest.string);
    649                 NT_STATUS_HAVE_NO_MEMORY(sam6->principle.string);
    650                 r->out.validation->sam6 = sam6;
    651                 break;
    652 
    653         default:
    654                 break;
    655         }
    656 
    657         *r->out.authoritative = 1;
    658820
    659821        /* TODO: Describe and deal with these flags */
     
    664826
    665827static NTSTATUS dcesrv_netr_LogonSamLogonEx(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
    666                                      struct netr_LogonSamLogonEx *r) 
     828                                     struct netr_LogonSamLogonEx *r)
    667829{
    668830        NTSTATUS nt_status;
    669831        struct netlogon_creds_CredentialState *creds;
    670         struct ldb_context *ldb = schannel_db_connect(mem_ctx, dce_call->event_ctx, dce_call->conn->dce_ctx->lp_ctx);
    671         if (!ldb) {
    672                 return NT_STATUS_ACCESS_DENIED;
    673         }
    674        
    675         nt_status = schannel_fetch_session_key_ldb(ldb, mem_ctx, r->in.computer_name, &creds);
     832
     833        *r->out.authoritative = 1;
     834
     835        nt_status = dcesrv_netr_LogonSamLogon_check(r);
     836        if (!NT_STATUS_IS_OK(nt_status)) {
     837                return nt_status;
     838        }
     839
     840        nt_status = schannel_get_creds_state(mem_ctx,
     841                                             lpcfg_private_dir(dce_call->conn->dce_ctx->lp_ctx),
     842                                             r->in.computer_name, &creds);
    676843        if (!NT_STATUS_IS_OK(nt_status)) {
    677844                return nt_status;
     
    685852}
    686853
    687 /* 
     854/*
    688855  netr_LogonSamLogonWithFlags
    689856
     
    697864
    698865        struct netr_Authenticator *return_authenticator;
    699 
    700         return_authenticator = talloc(mem_ctx, struct netr_Authenticator);
    701         NT_STATUS_HAVE_NO_MEMORY(return_authenticator);
    702 
    703         nt_status = dcesrv_netr_creds_server_step_check(dce_call,
    704                                                         mem_ctx,
    705                                                         r->in.computer_name,
    706                                                         r->in.credential, return_authenticator,
    707                                                         &creds);
    708         NT_STATUS_NOT_OK_RETURN(nt_status);
    709866
    710867        ZERO_STRUCT(r2);
     
    720877        r2.out.flags            = r->out.flags;
    721878
     879        *r->out.authoritative = 1;
     880
     881        nt_status = dcesrv_netr_LogonSamLogon_check(&r2);
     882        if (!NT_STATUS_IS_OK(nt_status)) {
     883                return nt_status;
     884        }
     885
     886        return_authenticator = talloc(mem_ctx, struct netr_Authenticator);
     887        NT_STATUS_HAVE_NO_MEMORY(return_authenticator);
     888
     889        nt_status = dcesrv_netr_creds_server_step_check(dce_call,
     890                                                        mem_ctx,
     891                                                        r->in.computer_name,
     892                                                        r->in.credential, return_authenticator,
     893                                                        &creds);
     894        NT_STATUS_NOT_OK_RETURN(nt_status);
     895
    722896        nt_status = dcesrv_netr_LogonSamLogon_base(dce_call, mem_ctx, &r2, creds);
    723897
     
    727901}
    728902
    729 /* 
     903/*
    730904  netr_LogonSamLogon
    731905*/
     
    759933
    760934
    761 /* 
    762   netr_LogonSamLogoff 
     935/*
     936  netr_LogonSamLogoff
    763937*/
    764938static NTSTATUS dcesrv_netr_LogonSamLogoff(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
     
    770944
    771945
    772 /* 
    773   netr_DatabaseDeltas 
     946/*
     947  netr_DatabaseDeltas
    774948*/
    775949static NTSTATUS dcesrv_netr_DatabaseDeltas(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
     
    780954
    781955
    782 /* 
    783   netr_DatabaseSync2 
     956/*
     957  netr_DatabaseSync2
    784958*/
    785959static NTSTATUS dcesrv_netr_DatabaseSync2(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
     
    791965
    792966
    793 /* 
    794   netr_DatabaseSync 
     967/*
     968  netr_DatabaseSync
    795969*/
    796970static NTSTATUS dcesrv_netr_DatabaseSync(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
     
    818992
    819993
    820 /* 
    821   netr_AccountDeltas 
     994/*
     995  netr_AccountDeltas
    822996*/
    823997static NTSTATUS dcesrv_netr_AccountDeltas(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
     
    8291003
    8301004
    831 /* 
    832   netr_AccountSync 
     1005/*
     1006  netr_AccountSync
    8331007*/
    8341008static NTSTATUS dcesrv_netr_AccountSync(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
     
    8401014
    8411015
    842 /* 
    843   netr_GetDcName 
     1016/*
     1017  netr_GetDcName
    8441018*/
    8451019static WERROR dcesrv_netr_GetDcName(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
     
    8531027        const char *dcname;
    8541028
     1029        /*
     1030         * [MS-NRPC] 3.5.5.3.4 NetrGetDCName says
     1031         * that the domainname needs to be a valid netbios domain
     1032         * name, if it is not NULL.
     1033         */
     1034        if (r->in.domainname) {
     1035                const char *dot = strchr(r->in.domainname, '.');
     1036                size_t len = strlen(r->in.domainname);
     1037
     1038                if (dot || len > 15) {
     1039                        return WERR_DCNOTFOUND;
     1040                }
     1041
     1042                /*
     1043                 * TODO: Should we also varify that only valid
     1044                 *       netbios name characters are used?
     1045                 */
     1046        }
     1047
    8551048        sam_ctx = samdb_connect(mem_ctx, dce_call->event_ctx,
    8561049                                dce_call->conn->dce_ctx->lp_ctx,
    857                                 dce_call->conn->auth_state.session_info);
     1050                                dce_call->conn->auth_state.session_info, 0);
    8581051        if (sam_ctx == NULL) {
    8591052                return WERR_DS_UNAVAILABLE;
     
    8761069         */
    8771070        dcname = talloc_asprintf(mem_ctx, "\\\\%s",
    878                                  lp_netbios_name(dce_call->conn->dce_ctx->lp_ctx));
     1071                                 lpcfg_netbios_name(dce_call->conn->dce_ctx->lp_ctx));
    8791072        W_ERROR_HAVE_NO_MEMORY(dcname);
    8801073
     
    8841077
    8851078
    886 /* 
    887   netr_LogonControl2Ex 
     1079/*
     1080  netr_LogonControl2Ex
    8881081*/
    8891082static WERROR dcesrv_netr_LogonControl2Ex(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
     
    8941087
    8951088
    896 /* 
    897   netr_LogonControl 
     1089/*
     1090  netr_LogonControl
    8981091*/
    8991092static WERROR dcesrv_netr_LogonControl(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
     
    9231116
    9241117
    925 /* 
    926   netr_LogonControl2 
     1118/*
     1119  netr_LogonControl2
    9271120*/
    9281121static WERROR dcesrv_netr_LogonControl2(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
     
    9451138}
    9461139
    947 
    948 /*
    949   netr_GetAnyDCName
     1140static WERROR fill_trusted_domains_array(TALLOC_CTX *mem_ctx,
     1141                                         struct ldb_context *sam_ctx,
     1142                                         struct netr_DomainTrustList *trusts,
     1143                                         uint32_t trust_flags);
     1144
     1145/*
     1146  netr_GetAnyDCName
    9501147*/
    9511148static WERROR dcesrv_netr_GetAnyDCName(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
    9521149                       struct netr_GetAnyDCName *r)
    9531150{
    954         struct netr_GetDcName r2;
     1151        struct netr_DomainTrustList *trusts;
     1152        struct ldb_context *sam_ctx;
     1153        struct loadparm_context *lp_ctx = dce_call->conn->dce_ctx->lp_ctx;
     1154        uint32_t i;
    9551155        WERROR werr;
    9561156
    957         ZERO_STRUCT(r2);
    958 
    959         r2.in.logon_server      = r->in.logon_server;
    960         r2.in.domainname        = r->in.domainname;
    961         r2.out.dcname           = r->out.dcname;
    962 
    963         werr = dcesrv_netr_GetDcName(dce_call, mem_ctx, &r2);
    964 
    965         return werr;
    966 }
    967 
    968 
    969 /*
    970   netr_DatabaseRedo
     1157        *r->out.dcname = NULL;
     1158
     1159        if ((r->in.domainname == NULL) || (r->in.domainname[0] == '\0')) {
     1160                /* if the domainname parameter wasn't set assume our domain */
     1161                r->in.domainname = lpcfg_workgroup(lp_ctx);
     1162        }
     1163
     1164        sam_ctx = samdb_connect(mem_ctx, dce_call->event_ctx, lp_ctx,
     1165                                dce_call->conn->auth_state.session_info, 0);
     1166        if (sam_ctx == NULL) {
     1167                return WERR_DS_UNAVAILABLE;
     1168        }
     1169
     1170        if (strcasecmp(r->in.domainname, lpcfg_workgroup(lp_ctx)) == 0) {
     1171                /* well we asked for a DC of our own domain */
     1172                if (samdb_is_pdc(sam_ctx)) {
     1173                        /* we are the PDC of the specified domain */
     1174                        return WERR_NO_SUCH_DOMAIN;
     1175                }
     1176
     1177                *r->out.dcname = talloc_asprintf(mem_ctx, "\\%s",
     1178                                                lpcfg_netbios_name(lp_ctx));
     1179                W_ERROR_HAVE_NO_MEMORY(*r->out.dcname);
     1180
     1181                return WERR_OK;
     1182        }
     1183
     1184        /* Okay, now we have to consider the trusted domains */
     1185
     1186        trusts = talloc_zero(mem_ctx, struct netr_DomainTrustList);
     1187        W_ERROR_HAVE_NO_MEMORY(trusts);
     1188
     1189        trusts->count = 0;
     1190
     1191        werr = fill_trusted_domains_array(mem_ctx, sam_ctx, trusts,
     1192                                          NETR_TRUST_FLAG_INBOUND
     1193                                          | NETR_TRUST_FLAG_OUTBOUND);
     1194        W_ERROR_NOT_OK_RETURN(werr);
     1195
     1196        for (i = 0; i < trusts->count; i++) {
     1197                if (strcasecmp(r->in.domainname, trusts->array[i].netbios_name) == 0) {
     1198                        /* FIXME: Here we need to find a DC for the specified
     1199                         * trusted domain. */
     1200
     1201                        /* return WERR_OK; */
     1202                        return WERR_NO_SUCH_DOMAIN;
     1203                }
     1204        }
     1205
     1206        return WERR_NO_SUCH_DOMAIN;
     1207}
     1208
     1209
     1210/*
     1211  netr_DatabaseRedo
    9711212*/
    9721213static NTSTATUS dcesrv_netr_DatabaseRedo(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
     
    9771218
    9781219
    979 /* 
    980   netr_NetrEnumerateTurstedDomains
    981 */
    982 static WERROR dcesrv_netr_NetrEnumerateTrustedDomains(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
     1220/*
     1221  netr_NetrEnumerateTrustedDomains
     1222*/
     1223static NTSTATUS dcesrv_netr_NetrEnumerateTrustedDomains(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
    9831224                       struct netr_NetrEnumerateTrustedDomains *r)
    9841225{
     
    9871228
    9881229
    989 /* 
     1230/*
    9901231  netr_LogonGetCapabilities
    9911232*/
     
    9981239
    9991240
    1000 /* 
    1001   netr_NETRLOGONSETSERVICEBITS 
     1241/*
     1242  netr_NETRLOGONSETSERVICEBITS
    10021243*/
    10031244static WERROR dcesrv_netr_NETRLOGONSETSERVICEBITS(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
     
    10181259
    10191260
    1020 /* 
    1021   netr_NETRLOGONCOMPUTESERVERDIGEST 
     1261/*
     1262  netr_NETRLOGONCOMPUTESERVERDIGEST
    10221263*/
    10231264static WERROR dcesrv_netr_NETRLOGONCOMPUTESERVERDIGEST(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
     
    10281269
    10291270
    1030 /* 
    1031   netr_NETRLOGONCOMPUTECLIENTDIGEST 
     1271/*
     1272  netr_NETRLOGONCOMPUTECLIENTDIGEST
    10321273*/
    10331274static WERROR dcesrv_netr_NETRLOGONCOMPUTECLIENTDIGEST(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
     
    10391280
    10401281
    1041 /* 
     1282/*
    10421283  netr_DsRGetSiteName
    10431284*/
     
    10451286                                  struct netr_DsRGetSiteName *r)
    10461287{
    1047         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
     1288        struct ldb_context *sam_ctx;
     1289        struct loadparm_context *lp_ctx = dce_call->conn->dce_ctx->lp_ctx;
     1290
     1291        sam_ctx = samdb_connect(mem_ctx, dce_call->event_ctx, lp_ctx,
     1292                                dce_call->conn->auth_state.session_info, 0);
     1293        if (sam_ctx == NULL) {
     1294                return WERR_DS_UNAVAILABLE;
     1295        }
     1296
     1297        *r->out.site = samdb_server_site_name(sam_ctx, mem_ctx);
     1298        W_ERROR_HAVE_NO_MEMORY(*r->out.site);
     1299
     1300        return WERR_OK;
    10481301}
    10491302
     
    10651318                info->trust_extension.info = talloc_zero(mem_ctx, struct netr_trust_extension);
    10661319                info->trust_extension.length = 16;
    1067                 info->trust_extension.info->flags = 
     1320                info->trust_extension.info->flags =
    10681321                        NETR_TRUST_FLAG_TREEROOT |
    1069                         NETR_TRUST_FLAG_IN_FOREST | 
     1322                        NETR_TRUST_FLAG_IN_FOREST |
    10701323                        NETR_TRUST_FLAG_PRIMARY |
    10711324                        NETR_TRUST_FLAG_NATIVE;
     
    10811334                info->dns_forestname.string = NULL;
    10821335        } else {
    1083                 char *p;
    1084                 /* TODO: we need a common function for pulling the forest */
    1085                 info->dns_forestname.string = ldb_dn_canonical_string(info, ldb_get_root_basedn(sam_ctx));
    1086                 if (!info->dns_forestname.string) {
    1087                         return NT_STATUS_NO_SUCH_DOMAIN;               
    1088                 }
    1089                 p = strchr(info->dns_forestname.string, '/');
    1090                 if (p) {
    1091                         *p = '\0';
    1092                 }
     1336                info->dns_forestname.string = samdb_forest_name(sam_ctx, mem_ctx);
     1337                NT_STATUS_HAVE_NO_MEMORY(info->dns_forestname.string);
    10931338                info->dns_forestname.string = talloc_asprintf(mem_ctx, "%s.", info->dns_forestname.string);
    1094                                        
     1339                NT_STATUS_HAVE_NO_MEMORY(info->dns_forestname.string);
    10951340        }
    10961341
    10971342        if (is_local) {
    1098                 info->domainname.string = lp_sam_name(lp_ctx);
    1099                 info->dns_domainname.string = lp_realm(lp_ctx);
     1343                info->domainname.string = lpcfg_workgroup(lp_ctx);
     1344                info->dns_domainname.string = lpcfg_dnsdomain(lp_ctx);
    11001345                info->domain_guid = samdb_result_guid(res, "objectGUID");
    11011346                info->domain_sid = samdb_result_dom_sid(mem_ctx, res, "objectSid");
    11021347        } else {
    1103                 info->domainname.string = samdb_result_string(res, "flatName", NULL);
    1104                 info->dns_domainname.string = samdb_result_string(res, "trustPartner", NULL);
     1348                info->domainname.string = ldb_msg_find_attr_as_string(res, "flatName", NULL);
     1349                info->dns_domainname.string = ldb_msg_find_attr_as_string(res, "trustPartner", NULL);
    11051350                info->domain_guid = samdb_result_guid(res, "objectGUID");
    11061351                info->domain_sid = samdb_result_dom_sid(mem_ctx, res, "securityIdentifier");
     
    11131358}
    11141359
    1115 /* 
     1360/*
    11161361  netr_LogonGetDomainInfo
    11171362  this is called as part of the ADS domain logon procedure.
     
    11261371        const char * const attrs[] = { "objectSid", "objectGUID", "flatName",
    11271372                "securityIdentifier", "trustPartner", NULL };
    1128         const char *temp_str;
    1129         const char *old_dns_hostname;
     1373        const char * const attrs2[] = { "sAMAccountName", "dNSHostName",
     1374                "msDS-SupportedEncryptionTypes", NULL };
     1375        const char *sam_account_name, *old_dns_hostname, *prefix1, *prefix2;
    11301376        struct ldb_context *sam_ctx;
    1131         struct ldb_message **res1, **res2, *new_msg;
     1377        struct ldb_message **res1, **res2, **res3, *new_msg;
    11321378        struct ldb_dn *workstation_dn;
    11331379        struct netr_DomainInformation *domain_info;
    11341380        struct netr_LsaPolicyInformation *lsa_policy_info;
    1135         struct netr_OsVersionInfoEx *os_version;
    11361381        uint32_t default_supported_enc_types = 0xFFFFFFFF;
    1137         int ret1, ret2, i;
     1382        bool update_dns_hostname = true;
     1383        int ret, ret3, i;
    11381384        NTSTATUS status;
    11391385
    11401386        status = dcesrv_netr_creds_server_step_check(dce_call,
    1141                                                      mem_ctx, 
    1142                                                      r->in.computer_name, 
    1143                                                      r->in.credential, 
     1387                                                     mem_ctx,
     1388                                                     r->in.computer_name,
     1389                                                     r->in.credential,
    11441390                                                     r->out.return_authenticator,
    11451391                                                     &creds);
     
    11501396
    11511397        sam_ctx = samdb_connect(mem_ctx, dce_call->event_ctx,
    1152                 dce_call->conn->dce_ctx->lp_ctx,
    1153                 system_session(mem_ctx, dce_call->conn->dce_ctx->lp_ctx));
     1398                                dce_call->conn->dce_ctx->lp_ctx,
     1399                                system_session(dce_call->conn->dce_ctx->lp_ctx), 0);
    11541400        if (sam_ctx == NULL) {
    11551401                return NT_STATUS_INVALID_SYSTEM_SERVICE;
     
    11591405        case 1: /* Domain information */
    11601406
    1161                 /* TODO: check NTSTATUS results - and fail also on SAMDB
    1162                  * errors (needs some testing against Windows Server 2008) */
     1407                if (r->in.query->workstation_info == NULL) {
     1408                        return NT_STATUS_INVALID_PARAMETER;
     1409                }
     1410
     1411                /* Prepares the workstation DN */
     1412                workstation_dn = ldb_dn_new_fmt(mem_ctx, sam_ctx, "<SID=%s>",
     1413                                                dom_sid_string(mem_ctx, creds->sid));
     1414                NT_STATUS_HAVE_NO_MEMORY(workstation_dn);
     1415
     1416                /* Lookup for attributes in workstation object */
     1417                ret = gendb_search_dn(sam_ctx, mem_ctx, workstation_dn, &res1,
     1418                                      attrs2);
     1419                if (ret != 1) {
     1420                        return NT_STATUS_INTERNAL_DB_CORRUPTION;
     1421                }
     1422
     1423                /* Gets the sam account name which is checked against the DNS
     1424                 * hostname parameter. */
     1425                sam_account_name = ldb_msg_find_attr_as_string(res1[0],
     1426                                                               "sAMAccountName",
     1427                                                               NULL);
     1428                if (sam_account_name == NULL) {
     1429                        return NT_STATUS_INTERNAL_DB_CORRUPTION;
     1430                }
    11631431
    11641432                /*
    1165                  * Check that the computer name parameter matches as prefix with
    1166                  * the DNS hostname in the workstation info structure.
     1433                 * Checks that the sam account name without a possible "$"
     1434                 * matches as prefix with the DNS hostname in the workstation
     1435                 * info structure.
    11671436                 */
    1168                 temp_str = strndup(r->in.query->workstation_info->dns_hostname,
    1169                         strcspn(r->in.query->workstation_info->dns_hostname,
    1170                         "."));
    1171                 if (strcasecmp(r->in.computer_name, temp_str) != 0)
    1172                         return NT_STATUS_INVALID_PARAMETER;
    1173 
    1174                 workstation_dn = ldb_dn_new_fmt(mem_ctx, sam_ctx, "<SID=%s>",
    1175                         dom_sid_string(mem_ctx, creds->sid));
    1176                 NT_STATUS_HAVE_NO_MEMORY(workstation_dn);
     1437                prefix1 = talloc_strndup(mem_ctx, sam_account_name,
     1438                                         strcspn(sam_account_name, "$"));
     1439                NT_STATUS_HAVE_NO_MEMORY(prefix1);
     1440                if (r->in.query->workstation_info->dns_hostname != NULL) {
     1441                        prefix2 = talloc_strndup(mem_ctx,
     1442                                                 r->in.query->workstation_info->dns_hostname,
     1443                                                 strcspn(r->in.query->workstation_info->dns_hostname, "."));
     1444                        NT_STATUS_HAVE_NO_MEMORY(prefix2);
     1445
     1446                        if (strcasecmp(prefix1, prefix2) != 0) {
     1447                                update_dns_hostname = false;
     1448                        }
     1449                } else {
     1450                        update_dns_hostname = false;
     1451                }
    11771452
    11781453                /* Gets the old DNS hostname */
    1179                 old_dns_hostname = samdb_search_string(sam_ctx, mem_ctx,
    1180                                                         workstation_dn,
    1181                                                         "dNSHostName",
    1182                                                         NULL);
    1183 
    1184                 /* Gets host informations and put them in our directory */
     1454                old_dns_hostname = ldb_msg_find_attr_as_string(res1[0],
     1455                                                               "dNSHostName",
     1456                                                               NULL);
     1457
     1458                /*
     1459                 * Updates the DNS hostname when the client wishes that the
     1460                 * server should handle this for him
     1461                 * ("NETR_WS_FLAG_HANDLES_SPN_UPDATE" not set). And this is
     1462                 * obviously only checked when we do already have a
     1463                 * "dNSHostName".
     1464                 * See MS-NRPC section 3.5.4.3.9
     1465                 */
     1466                if ((old_dns_hostname != NULL) &&
     1467                    (r->in.query->workstation_info->workstation_flags
     1468                    & NETR_WS_FLAG_HANDLES_SPN_UPDATE) != 0) {
     1469                        update_dns_hostname = false;
     1470                }
     1471
     1472                /* Gets host information and put them into our directory */
     1473
    11851474                new_msg = ldb_msg_new(mem_ctx);
    11861475                NT_STATUS_HAVE_NO_MEMORY(new_msg);
     
    11881477                new_msg->dn = workstation_dn;
    11891478
    1190                 /* Deletes old OS version values */
    1191                 samdb_msg_add_delete(sam_ctx, mem_ctx, new_msg,
    1192                         "operatingSystemServicePack");
    1193                 samdb_msg_add_delete(sam_ctx, mem_ctx, new_msg,
    1194                         "operatingSystemVersion");
    1195 
    1196                 if (samdb_replace(sam_ctx, mem_ctx, new_msg) != LDB_SUCCESS) {
    1197                         DEBUG(3,("Impossible to update samdb: %s\n",
    1198                                 ldb_errstring(sam_ctx)));
    1199                 }
    1200 
    1201                 talloc_free(new_msg);
    1202 
    1203                 new_msg = ldb_msg_new(mem_ctx);
    1204                 NT_STATUS_HAVE_NO_MEMORY(new_msg);
    1205 
    1206                 new_msg->dn = workstation_dn;
    1207 
    12081479                /* Sets the OS name */
    1209                 samdb_msg_set_string(sam_ctx, mem_ctx, new_msg,
    1210                         "operatingSystem",
    1211                         r->in.query->workstation_info->os_name.string);
    1212 
    1213                 if (r->in.query->workstation_info->dns_hostname) {
    1214                         /* TODO: should this always be done? */
    1215                         samdb_msg_add_string(sam_ctx, mem_ctx, new_msg,
    1216                                              "dNSHostname",
    1217                                              r->in.query->workstation_info->dns_hostname);
     1480
     1481                if (r->in.query->workstation_info->os_name.string == NULL) {
     1482                        return NT_STATUS_INVALID_PARAMETER;
     1483                }
     1484
     1485                ret = ldb_msg_add_string(new_msg, "operatingSystem",
     1486                                         r->in.query->workstation_info->os_name.string);
     1487                if (ret != LDB_SUCCESS) {
     1488                        return NT_STATUS_NO_MEMORY;
    12181489                }
    12191490
    12201491                /*
    1221                  * Sets informations from "os_version". On a empty structure
     1492                 * Sets information from "os_version". On an empty structure
    12221493                 * the values are cleared.
    12231494                 */
    12241495                if (r->in.query->workstation_info->os_version.os != NULL) {
     1496                        struct netr_OsVersionInfoEx *os_version;
     1497                        const char *os_version_str;
     1498
    12251499                        os_version = &r->in.query->workstation_info->os_version.os->os;
    12261500
    1227                         samdb_msg_set_string(sam_ctx, mem_ctx, new_msg,
    1228                                              "operatingSystemServicePack",
    1229                                              os_version->CSDVersion);
    1230 
    1231                         samdb_msg_set_string(sam_ctx, mem_ctx, new_msg,
    1232                                 "operatingSystemVersion",
    1233                                 talloc_asprintf(mem_ctx, "%d.%d (%d)",
    1234                                         os_version->MajorVersion,
    1235                                         os_version->MinorVersion,
    1236                                         os_version->BuildNumber
    1237                                 )
    1238                         );
     1501                        if (os_version->CSDVersion == NULL) {
     1502                                return NT_STATUS_INVALID_PARAMETER;
     1503                        }
     1504
     1505                        os_version_str = talloc_asprintf(new_msg, "%u.%u (%u)",
     1506                                                         os_version->MajorVersion,
     1507                                                         os_version->MinorVersion,
     1508                                                         os_version->BuildNumber);
     1509                        NT_STATUS_HAVE_NO_MEMORY(os_version_str);
     1510
     1511                        ret = ldb_msg_add_string(new_msg,
     1512                                                 "operatingSystemServicePack",
     1513                                                 os_version->CSDVersion);
     1514                        if (ret != LDB_SUCCESS) {
     1515                                return NT_STATUS_NO_MEMORY;
     1516                        }
     1517
     1518                        ret = ldb_msg_add_string(new_msg,
     1519                                                 "operatingSystemVersion",
     1520                                                 os_version_str);
     1521                        if (ret != LDB_SUCCESS) {
     1522                                return NT_STATUS_NO_MEMORY;
     1523                        }
     1524                } else {
     1525                        ret = samdb_msg_add_delete(sam_ctx, mem_ctx, new_msg,
     1526                                                   "operatingSystemServicePack");
     1527                        if (ret != LDB_SUCCESS) {
     1528                                return NT_STATUS_NO_MEMORY;
     1529                        }
     1530
     1531                        ret = samdb_msg_add_delete(sam_ctx, mem_ctx, new_msg,
     1532                                                   "operatingSystemVersion");
     1533                        if (ret != LDB_SUCCESS) {
     1534                                return NT_STATUS_NO_MEMORY;
     1535                        }
    12391536                }
    12401537
    12411538                /*
    1242                  * Updates the "dNSHostname" and the "servicePrincipalName"s
    1243                  * since the client wishes that the server should handle this
    1244                  * for him ("NETR_WS_FLAG_HANDLES_SPN_UPDATE" not set).
    1245                  * See MS-NRPC section 3.5.4.3.9
     1539                 * If the boolean "update_dns_hostname" remained true, then we
     1540                 * are fine to start the update.
    12461541                 */
    1247                 if ((r->in.query->workstation_info->workstation_flags
    1248                         & NETR_WS_FLAG_HANDLES_SPN_UPDATE) == 0) {
    1249 
    1250                         samdb_msg_add_string(sam_ctx, mem_ctx, new_msg,
    1251                                 "servicePrincipalName",
    1252                                 talloc_asprintf(mem_ctx, "HOST/%s",
    1253                                 r->in.computer_name)
    1254                         );
    1255                         samdb_msg_add_string(sam_ctx, mem_ctx, new_msg,
    1256                                 "servicePrincipalName",
    1257                                 talloc_asprintf(mem_ctx, "HOST/%s",
    1258                                 r->in.query->workstation_info->dns_hostname)
    1259                         );
    1260                 }
    1261 
    1262                 if (samdb_replace(sam_ctx, mem_ctx, new_msg) != LDB_SUCCESS) {
     1542                if (update_dns_hostname) {
     1543                        ret = ldb_msg_add_string(new_msg,
     1544                                                 "dNSHostname",
     1545                                                 r->in.query->workstation_info->dns_hostname);
     1546                        if (ret != LDB_SUCCESS) {
     1547                                return NT_STATUS_NO_MEMORY;
     1548                        }
     1549
     1550                        /* This manual "servicePrincipalName" generation is
     1551                         * still needed! Since the update in the samldb LDB
     1552                         * module does only work if the entries already exist
     1553                         * which isn't always the case. */
     1554                        ret = ldb_msg_add_string(new_msg,
     1555                                                 "servicePrincipalName",
     1556                                                 talloc_asprintf(new_msg, "HOST/%s",
     1557                                                 r->in.computer_name));
     1558                        if (ret != LDB_SUCCESS) {
     1559                                return NT_STATUS_NO_MEMORY;
     1560                        }
     1561
     1562                        ret = ldb_msg_add_string(new_msg,
     1563                                                 "servicePrincipalName",
     1564                                                 talloc_asprintf(new_msg, "HOST/%s",
     1565                                                 r->in.query->workstation_info->dns_hostname));
     1566                        if (ret != LDB_SUCCESS) {
     1567                                return NT_STATUS_NO_MEMORY;
     1568                        }
     1569                }
     1570
     1571                if (dsdb_replace(sam_ctx, new_msg, 0) != LDB_SUCCESS) {
    12631572                        DEBUG(3,("Impossible to update samdb: %s\n",
    12641573                                ldb_errstring(sam_ctx)));
     
    12741583                   put the primary domain into the lists of returned trusts as
    12751584                   well. */
    1276                 ret1 = gendb_search_dn(sam_ctx, mem_ctx, samdb_base_dn(sam_ctx),
    1277                         &res1, attrs);
    1278                 if (ret1 != 1) {
     1585                ret = gendb_search_dn(sam_ctx, mem_ctx, ldb_get_default_basedn(sam_ctx),
     1586                        &res2, attrs);
     1587                if (ret != 1) {
    12791588                        return NT_STATUS_INTERNAL_DB_CORRUPTION;
    12801589                }
    12811590
    1282                 ret2 = gendb_search(sam_ctx, mem_ctx, NULL, &res2, attrs,
     1591                ret3 = gendb_search(sam_ctx, mem_ctx, NULL, &res3, attrs,
    12831592                        "(objectClass=trustedDomain)");
    1284                 if (ret2 == -1) {
     1593                if (ret3 == -1) {
    12851594                        return NT_STATUS_INTERNAL_DB_CORRUPTION;
    12861595                }
     
    12951604                status = fill_one_domain_info(mem_ctx,
    12961605                        dce_call->conn->dce_ctx->lp_ctx,
    1297                         sam_ctx, res1[0], &domain_info->primary_domain,
     1606                        sam_ctx, res2[0], &domain_info->primary_domain,
    12981607                        true, false);
    12991608                NT_STATUS_NOT_OK_RETURN(status);
    13001609
    1301                 domain_info->trusted_domain_count = ret2 + 1;
     1610                domain_info->trusted_domain_count = ret3 + 1;
    13021611                domain_info->trusted_domains = talloc_array(mem_ctx,
    13031612                        struct netr_OneDomainInfo,
     
    13051614                NT_STATUS_HAVE_NO_MEMORY(domain_info->trusted_domains);
    13061615
    1307                 for (i=0;i<ret2;i++) {
     1616                for (i=0;i<ret3;i++) {
    13081617                        status = fill_one_domain_info(mem_ctx,
    13091618                                dce_call->conn->dce_ctx->lp_ctx,
    1310                                 sam_ctx, res2[i],
     1619                                sam_ctx, res3[i],
    13111620                                &domain_info->trusted_domains[i],
    13121621                                false, true);
     
    13151624
    13161625                status = fill_one_domain_info(mem_ctx,
    1317                         dce_call->conn->dce_ctx->lp_ctx, sam_ctx, res1[0],
     1626                        dce_call->conn->dce_ctx->lp_ctx, sam_ctx, res2[0],
    13181627                        &domain_info->trusted_domains[i], true, true);
    13191628                NT_STATUS_NOT_OK_RETURN(status);
    13201629
    13211630                /* Sets the supported encryption types */
    1322                 domain_info->supported_enc_types = samdb_search_uint(
    1323                         sam_ctx, mem_ctx,
    1324                         default_supported_enc_types, workstation_dn,
    1325                         "msDS-SupportedEncryptionTypes", NULL);
    1326 
    1327                 /* Other host domain informations */
     1631                domain_info->supported_enc_types = ldb_msg_find_attr_as_uint(res1[0],
     1632                        "msDS-SupportedEncryptionTypes",
     1633                        default_supported_enc_types);
     1634
     1635                /* Other host domain information */
    13281636
    13291637                lsa_policy_info = talloc(mem_ctx,
     
    13341642                domain_info->lsa_policy = *lsa_policy_info;
    13351643
    1336                 domain_info->dns_hostname.string = old_dns_hostname;
     1644                /* The DNS hostname is only returned back when there is a chance
     1645                 * for a change. */
     1646                if ((r->in.query->workstation_info->workstation_flags
     1647                    & NETR_WS_FLAG_HANDLES_SPN_UPDATE) != 0) {
     1648                        domain_info->dns_hostname.string = old_dns_hostname;
     1649                } else {
     1650                        domain_info->dns_hostname.string = NULL;
     1651                }
     1652
    13371653                domain_info->workstation_flags =
    13381654                        r->in.query->workstation_info->workstation_flags;
     
    13571673
    13581674
    1359 
    13601675/*
    13611676  netr_ServerPasswordGet
     
    13681683
    13691684
    1370 /* 
    1371   netr_NETRLOGONSENDTOSAM 
     1685/*
     1686  netr_NETRLOGONSENDTOSAM
    13721687*/
    13731688static WERROR dcesrv_netr_NETRLOGONSENDTOSAM(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
     
    13781693
    13791694
    1380 /*
    1381   netr_DsRAddressToSitenamesW
    1382 */
    1383 static WERROR dcesrv_netr_DsRAddressToSitenamesW(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
    1384                        struct netr_DsRAddressToSitenamesW *r)
    1385 {
    1386         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
    1387 }
    1388 
    1389 
    1390 /*
     1695/*
    13911696  netr_DsRGetDCNameEx2
    13921697*/
    1393 static WERROR dcesrv_netr_DsRGetDCNameEx2(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
    1394                                    struct netr_DsRGetDCNameEx2 *r)
    1395 {
    1396         const char * const attrs[] = { "objectGUID", NULL };
     1698static WERROR dcesrv_netr_DsRGetDCNameEx2(struct dcesrv_call_state *dce_call,
     1699                                          TALLOC_CTX *mem_ctx,
     1700                                          struct netr_DsRGetDCNameEx2 *r)
     1701{
    13971702        struct ldb_context *sam_ctx;
    1398         struct ldb_message **res;
    1399         struct ldb_dn *domain_dn;
    1400         int ret;
    14011703        struct netr_DsRGetDCNameInfo *info;
     1704        struct loadparm_context *lp_ctx = dce_call->conn->dce_ctx->lp_ctx;
     1705        const struct tsocket_address *remote_address;
     1706        char *addr = NULL;
     1707        const char *server_site_name;
     1708        char *guid_str;
     1709        struct netlogon_samlogon_response response;
     1710        NTSTATUS status;
     1711        const char *dc_name = NULL;
     1712        const char *domain_name = NULL;
    14021713
    14031714        ZERO_STRUCTP(r->out.info);
    14041715
    1405         sam_ctx = samdb_connect(mem_ctx, dce_call->event_ctx, dce_call->conn->dce_ctx->lp_ctx, dce_call->conn->auth_state.session_info);
     1716        sam_ctx = samdb_connect(mem_ctx, dce_call->event_ctx, lp_ctx,
     1717                                dce_call->conn->auth_state.session_info, 0);
    14061718        if (sam_ctx == NULL) {
    14071719                return WERR_DS_UNAVAILABLE;
    14081720        }
    14091721
    1410         /* Win7-beta will send the domain name in the form the user typed, so we have to cope
    1411            with both the short and long form here */
    1412         if (r->in.domain_name != NULL && !lp_is_my_domain_or_realm(dce_call->conn->dce_ctx->lp_ctx,
    1413                                                                 r->in.domain_name)) {
     1722        remote_address = dcesrv_connection_get_remote_address(dce_call->conn);
     1723        if (tsocket_address_is_inet(remote_address, "ip")) {
     1724                addr = tsocket_address_inet_addr_string(remote_address, mem_ctx);
     1725                W_ERROR_HAVE_NO_MEMORY(addr);
     1726        }
     1727
     1728        /* "server_unc" is ignored by w2k3 */
     1729
     1730        if (r->in.flags & ~(DSGETDC_VALID_FLAGS)) {
     1731                return WERR_INVALID_FLAGS;
     1732        }
     1733
     1734        if (r->in.flags & DS_GC_SERVER_REQUIRED &&
     1735            r->in.flags & DS_PDC_REQUIRED &&
     1736            r->in.flags & DS_KDC_REQUIRED) {
     1737                return WERR_INVALID_FLAGS;
     1738        }
     1739        if (r->in.flags & DS_IS_FLAT_NAME &&
     1740            r->in.flags & DS_IS_DNS_NAME) {
     1741                return WERR_INVALID_FLAGS;
     1742        }
     1743        if (r->in.flags & DS_RETURN_DNS_NAME &&
     1744            r->in.flags & DS_RETURN_FLAT_NAME) {
     1745                return WERR_INVALID_FLAGS;
     1746        }
     1747        if (r->in.flags & DS_DIRECTORY_SERVICE_REQUIRED &&
     1748            r->in.flags & DS_DIRECTORY_SERVICE_6_REQUIRED) {
     1749                return WERR_INVALID_FLAGS;
     1750        }
     1751
     1752        if (r->in.flags & DS_GOOD_TIMESERV_PREFERRED &&
     1753            r->in.flags &
     1754            (DS_DIRECTORY_SERVICE_REQUIRED |
     1755             DS_DIRECTORY_SERVICE_PREFERRED |
     1756             DS_GC_SERVER_REQUIRED |
     1757             DS_PDC_REQUIRED |
     1758             DS_KDC_REQUIRED)) {
     1759                return WERR_INVALID_FLAGS;
     1760        }
     1761
     1762        if (r->in.flags & DS_TRY_NEXTCLOSEST_SITE &&
     1763            r->in.site_name) {
     1764                return WERR_INVALID_FLAGS;
     1765        }
     1766
     1767        /* Proof server site parameter "site_name" if it was specified */
     1768        server_site_name = samdb_server_site_name(sam_ctx, mem_ctx);
     1769        W_ERROR_HAVE_NO_MEMORY(server_site_name);
     1770        if ((r->in.site_name != NULL) && (strcasecmp(r->in.site_name,
     1771                                                     server_site_name) != 0)) {
    14141772                return WERR_NO_SUCH_DOMAIN;
    14151773        }
    14161774
    1417         domain_dn = ldb_get_default_basedn(sam_ctx);
    1418         if (domain_dn == NULL) {
    1419                 return WERR_DS_UNAVAILABLE;
    1420         }
    1421 
    1422         ret = gendb_search_dn(sam_ctx, mem_ctx,
    1423                               domain_dn, &res, attrs);
    1424         if (ret != 1) {
     1775        guid_str = r->in.domain_guid != NULL ?
     1776                 GUID_string(mem_ctx, r->in.domain_guid) : NULL;
     1777
     1778        status = fill_netlogon_samlogon_response(sam_ctx, mem_ctx,
     1779                                                 r->in.domain_name,
     1780                                                 r->in.domain_name,
     1781                                                 NULL, guid_str,
     1782                                                 r->in.client_account,
     1783                                                 r->in.mask, addr,
     1784                                                 NETLOGON_NT_VERSION_5EX_WITH_IP,
     1785                                                 lp_ctx, &response, true);
     1786        if (!NT_STATUS_IS_OK(status)) {
     1787                return ntstatus_to_werror(status);
     1788        }
     1789
     1790        if (r->in.flags & DS_RETURN_DNS_NAME) {
     1791                dc_name = response.data.nt5_ex.pdc_dns_name;
     1792                domain_name = response.data.nt5_ex.dns_domain;
     1793        } else if (r->in.flags & DS_RETURN_FLAT_NAME) {
     1794                dc_name = response.data.nt5_ex.pdc_name;
     1795                domain_name = response.data.nt5_ex.domain_name;
     1796        } else {
     1797
     1798                /*
     1799                 * TODO: autodetect what we need to return
     1800                 * based on the given arguments
     1801                 */
     1802                dc_name = response.data.nt5_ex.pdc_name;
     1803                domain_name = response.data.nt5_ex.domain_name;
     1804        }
     1805
     1806        if (!dc_name || !dc_name[0]) {
     1807                return WERR_NO_SUCH_DOMAIN;
     1808        }
     1809
     1810        if (!domain_name || !domain_name[0]) {
     1811                return WERR_NO_SUCH_DOMAIN;
    14251812        }
    14261813
    14271814        info = talloc(mem_ctx, struct netr_DsRGetDCNameInfo);
    14281815        W_ERROR_HAVE_NO_MEMORY(info);
    1429 
    1430         /* TODO: - return real IP address
    1431          *       - check all r->in.* parameters (server_unc is ignored by w2k3!)
    1432          */
    1433         info->dc_unc                    = talloc_asprintf(mem_ctx, "\\\\%s.%s",
    1434                                                           lp_netbios_name(dce_call->conn->dce_ctx->lp_ctx),
    1435                                                           lp_realm(dce_call->conn->dce_ctx->lp_ctx));
     1816        info->dc_unc           = talloc_asprintf(mem_ctx, "\\\\%s", dc_name);
    14361817        W_ERROR_HAVE_NO_MEMORY(info->dc_unc);
    1437         info->dc_address                = talloc_strdup(mem_ctx, "\\\\0.0.0.0");
     1818        info->dc_address = talloc_asprintf(mem_ctx, "\\\\%s",
     1819                                           response.data.nt5_ex.sockaddr.pdc_ip);
    14381820        W_ERROR_HAVE_NO_MEMORY(info->dc_address);
    1439         info->dc_address_type           = DS_ADDRESS_TYPE_INET;
    1440         info->domain_guid               = samdb_result_guid(res[0], "objectGUID");
    1441         info->domain_name               = lp_realm(dce_call->conn->dce_ctx->lp_ctx);
    1442         info->forest_name               = lp_realm(dce_call->conn->dce_ctx->lp_ctx);
    1443         info->dc_flags                  = DS_DNS_FOREST |
    1444                                           DS_DNS_DOMAIN |
    1445                                           DS_DNS_CONTROLLER |
    1446                                           DS_SERVER_WRITABLE |
    1447                                           DS_SERVER_CLOSEST |
    1448                                           DS_SERVER_TIMESERV |
    1449                                           DS_SERVER_KDC |
    1450                                           DS_SERVER_DS |
    1451                                           DS_SERVER_LDAP |
    1452                                           DS_SERVER_GC |
    1453                                           DS_SERVER_PDC;
    1454         info->dc_site_name      = talloc_strdup(mem_ctx, "Default-First-Site-Name");
    1455         W_ERROR_HAVE_NO_MEMORY(info->dc_site_name);
    1456         info->client_site_name  = talloc_strdup(mem_ctx, "Default-First-Site-Name");
    1457         W_ERROR_HAVE_NO_MEMORY(info->client_site_name);
     1821        info->dc_address_type  = DS_ADDRESS_TYPE_INET; /* TODO: make this dynamic? for ipv6 */
     1822        info->domain_guid      = response.data.nt5_ex.domain_uuid;
     1823        info->domain_name      = domain_name;
     1824        info->forest_name      = response.data.nt5_ex.forest;
     1825        info->dc_flags         = response.data.nt5_ex.server_type;
     1826        info->dc_site_name     = response.data.nt5_ex.server_site;
     1827        info->client_site_name = response.data.nt5_ex.client_site;
    14581828
    14591829        *r->out.info = info;
     
    14621832}
    14631833
    1464 /* 
     1834/*
    14651835  netr_DsRGetDCNameEx
    14661836*/
     
    14871857}
    14881858
    1489 /* 
     1859/*
    14901860  netr_DsRGetDCName
    14911861*/
     
    15031873        r2.in.domain_name = r->in.domain_name;
    15041874        r2.in.domain_guid = r->in.domain_guid;
    1505        
    1506         r2.in.site_name = NULL; /* should fill in from site GUID */
     1875
     1876        r2.in.site_name = NULL; /* this is correct, we should ignore site GUID */
    15071877        r2.in.flags = r->in.flags;
    15081878        r2.out.info = r->out.info;
     
    15121882        return werr;
    15131883}
    1514 /* 
    1515   netr_NETRLOGONGETTIMESERVICEPARENTDOMAIN 
     1884/*
     1885  netr_NETRLOGONGETTIMESERVICEPARENTDOMAIN
    15161886*/
    15171887static WERROR dcesrv_netr_NETRLOGONGETTIMESERVICEPARENTDOMAIN(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
     
    15321902
    15331903
    1534 /* 
    1535   netr_DsRAddressToSitenamesExW 
     1904/*
     1905  netr_DsRAddressToSitenamesExW
    15361906*/
    15371907static WERROR dcesrv_netr_DsRAddressToSitenamesExW(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
    15381908                                                   struct netr_DsRAddressToSitenamesExW *r)
    15391909{
     1910        struct ldb_context *sam_ctx;
    15401911        struct netr_DsRAddressToSitenamesExWCtr *ctr;
    1541         int i;
    1542 
    1543         /* we should map the provided IPs to site names, once we have
    1544          * sites support
    1545          */
     1912        struct loadparm_context *lp_ctx = dce_call->conn->dce_ctx->lp_ctx;
     1913        sa_family_t sin_family;
     1914        struct sockaddr_in *addr;
     1915#ifdef HAVE_IPV6
     1916        struct sockaddr_in6 *addr6;
     1917        char addr_str[INET6_ADDRSTRLEN];
     1918#else
     1919        char addr_str[INET_ADDRSTRLEN];
     1920#endif
     1921        char *subnet_name;
     1922        const char *res;
     1923        uint32_t i;
     1924
     1925        sam_ctx = samdb_connect(mem_ctx, dce_call->event_ctx, lp_ctx,
     1926                                dce_call->conn->auth_state.session_info, 0);
     1927        if (sam_ctx == NULL) {
     1928                return WERR_DS_UNAVAILABLE;
     1929        }
     1930
    15461931        ctr = talloc(mem_ctx, struct netr_DsRAddressToSitenamesExWCtr);
    15471932        W_ERROR_HAVE_NO_MEMORY(ctr);
     
    15561941
    15571942        for (i=0; i<ctr->count; i++) {
    1558                 ctr->sitename[i].string   = "Default-First-Site-Name";
     1943                ctr->sitename[i].string = NULL;
    15591944                ctr->subnetname[i].string = NULL;
     1945
     1946                if (r->in.addresses[i].size < sizeof(sa_family_t)) {
     1947                        continue;
     1948                }
     1949                /* The first two byte of the buffer are reserved for the
     1950                 * "sin_family" but for now only the first one is used. */
     1951                sin_family = r->in.addresses[i].buffer[0];
     1952
     1953                switch (sin_family) {
     1954                case AF_INET:
     1955                        if (r->in.addresses[i].size < sizeof(struct sockaddr_in)) {
     1956                                continue;
     1957                        }
     1958                        addr = (struct sockaddr_in *) r->in.addresses[i].buffer;
     1959                        res = inet_ntop(AF_INET, &addr->sin_addr,
     1960                                        addr_str, sizeof(addr_str));
     1961                        break;
     1962#ifdef HAVE_IPV6
     1963                case AF_INET6:
     1964                        if (r->in.addresses[i].size < sizeof(struct sockaddr_in6)) {
     1965                                continue;
     1966                        }
     1967                        addr6 = (struct sockaddr_in6 *) r->in.addresses[i].buffer;
     1968                        res = inet_ntop(AF_INET6, &addr6->sin6_addr,
     1969                                        addr_str, sizeof(addr_str));
     1970                        break;
     1971#endif
     1972                default:
     1973                        continue;
     1974                }
     1975
     1976                if (res == NULL) {
     1977                        continue;
     1978                }
     1979
     1980                ctr->sitename[i].string   = samdb_client_site_name(sam_ctx,
     1981                                                                   mem_ctx,
     1982                                                                   addr_str,
     1983                                                                   &subnet_name);
     1984                W_ERROR_HAVE_NO_MEMORY(ctr->sitename[i].string);
     1985                ctr->subnetname[i].string = subnet_name;
    15601986        }
    15611987
     
    15641990
    15651991
    1566 /*
     1992/*
     1993  netr_DsRAddressToSitenamesW
     1994*/
     1995static WERROR dcesrv_netr_DsRAddressToSitenamesW(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
     1996                       struct netr_DsRAddressToSitenamesW *r)
     1997{
     1998        struct netr_DsRAddressToSitenamesExW r2;
     1999        struct netr_DsRAddressToSitenamesWCtr *ctr;
     2000        uint32_t i;
     2001        WERROR werr;
     2002
     2003        ZERO_STRUCT(r2);
     2004
     2005        r2.in.server_name = r->in.server_name;
     2006        r2.in.count = r->in.count;
     2007        r2.in.addresses = r->in.addresses;
     2008
     2009        r2.out.ctr = talloc(mem_ctx, struct netr_DsRAddressToSitenamesExWCtr *);
     2010        W_ERROR_HAVE_NO_MEMORY(r2.out.ctr);
     2011
     2012        ctr = talloc(mem_ctx, struct netr_DsRAddressToSitenamesWCtr);
     2013        W_ERROR_HAVE_NO_MEMORY(ctr);
     2014
     2015        *r->out.ctr = ctr;
     2016
     2017        ctr->count = r->in.count;
     2018        ctr->sitename = talloc_array(ctr, struct lsa_String, ctr->count);
     2019        W_ERROR_HAVE_NO_MEMORY(ctr->sitename);
     2020
     2021        werr = dcesrv_netr_DsRAddressToSitenamesExW(dce_call, mem_ctx, &r2);
     2022
     2023        for (i=0; i<ctr->count; i++) {
     2024                ctr->sitename[i].string   = (*r2.out.ctr)->sitename[i].string;
     2025        }
     2026
     2027        return werr;
     2028}
     2029
     2030
     2031/*
    15672032  netr_DsrGetDcSiteCoverageW
    15682033*/
     
    15702035                       struct netr_DsrGetDcSiteCoverageW *r)
    15712036{
    1572         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
    1573 }
    1574 
    1575 
    1576 /*
    1577   netr_DsrEnumerateDomainTrusts
    1578 */
    1579 static WERROR dcesrv_netr_DsrEnumerateDomainTrusts(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
    1580                                               struct netr_DsrEnumerateDomainTrusts *r)
     2037        struct ldb_context *sam_ctx;
     2038        struct DcSitesCtr *ctr;
     2039        struct loadparm_context *lp_ctx = dce_call->conn->dce_ctx->lp_ctx;
     2040
     2041        sam_ctx = samdb_connect(mem_ctx, dce_call->event_ctx, lp_ctx,
     2042                                dce_call->conn->auth_state.session_info, 0);
     2043        if (sam_ctx == NULL) {
     2044                return WERR_DS_UNAVAILABLE;
     2045        }
     2046
     2047        ctr = talloc(mem_ctx, struct DcSitesCtr);
     2048        W_ERROR_HAVE_NO_MEMORY(ctr);
     2049
     2050        *r->out.ctr = ctr;
     2051
     2052        /* For now only return our default site */
     2053        ctr->num_sites = 1;
     2054        ctr->sites = talloc_array(ctr, struct lsa_String, ctr->num_sites);
     2055        W_ERROR_HAVE_NO_MEMORY(ctr->sites);
     2056        ctr->sites[0].string = samdb_server_site_name(sam_ctx, mem_ctx);
     2057        W_ERROR_HAVE_NO_MEMORY(ctr->sites[0].string);
     2058
     2059        return WERR_OK;
     2060}
     2061
     2062
     2063#define GET_CHECK_STR(dest, mem, msg, attr) \
     2064do {\
     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
     2078static WERROR fill_trusted_domains_array(TALLOC_CTX *mem_ctx,
     2079                                         struct ldb_context *sam_ctx,
     2080                                         struct netr_DomainTrustList *trusts,
     2081                                         uint32_t trust_flags)
     2082{
     2083        struct ldb_dn *system_dn;
     2084        struct ldb_message **dom_res = NULL;
     2085        const char *trust_attrs[] = { "flatname", "trustPartner",
     2086                                      "securityIdentifier", "trustDirection",
     2087                                      "trustType", "trustAttributes", NULL };
     2088        uint32_t n;
     2089        int i;
     2090        int ret;
     2091
     2092        if (!(trust_flags & (NETR_TRUST_FLAG_INBOUND |
     2093                             NETR_TRUST_FLAG_OUTBOUND))) {
     2094                return WERR_INVALID_FLAGS;
     2095        }
     2096
     2097        system_dn = samdb_search_dn(sam_ctx, mem_ctx,
     2098                                    ldb_get_default_basedn(sam_ctx),
     2099                                    "(&(objectClass=container)(cn=System))");
     2100        if (!system_dn) {
     2101                return WERR_GENERAL_FAILURE;
     2102        }
     2103
     2104        ret = gendb_search(sam_ctx, mem_ctx, system_dn,
     2105                           &dom_res, trust_attrs,
     2106                           "(objectclass=trustedDomain)");
     2107
     2108        for (i = 0; i < ret; i++) {
     2109                unsigned int trust_dir;
     2110                uint32_t flags = 0;
     2111
     2112                trust_dir = ldb_msg_find_attr_as_uint(dom_res[i],
     2113                                                      "trustDirection", 0);
     2114
     2115                if (trust_dir & LSA_TRUST_DIRECTION_INBOUND) {
     2116                        flags |= NETR_TRUST_FLAG_INBOUND;
     2117                }
     2118                if (trust_dir & LSA_TRUST_DIRECTION_OUTBOUND) {
     2119                        flags |= NETR_TRUST_FLAG_OUTBOUND;
     2120                }
     2121
     2122                if (!(flags & trust_flags)) {
     2123                        /* this trust direction was not requested */
     2124                        continue;
     2125                }
     2126
     2127                n = trusts->count;
     2128                trusts->array = talloc_realloc(trusts, trusts->array,
     2129                                               struct netr_DomainTrust,
     2130                                               n + 1);
     2131                W_ERROR_HAVE_NO_MEMORY(trusts->array);
     2132
     2133                GET_CHECK_STR(trusts->array[n].netbios_name, trusts,
     2134                              dom_res[i], "flatname");
     2135                GET_CHECK_STR(trusts->array[n].dns_name, trusts,
     2136                              dom_res[i], "trustPartner");
     2137
     2138                trusts->array[n].trust_flags = flags;
     2139                if ((trust_flags & NETR_TRUST_FLAG_IN_FOREST) &&
     2140                    !(flags & NETR_TRUST_FLAG_TREEROOT)) {
     2141                        /* TODO: find if we have parent in the list */
     2142                        trusts->array[n].parent_index = 0;
     2143                }
     2144
     2145                trusts->array[n].trust_type =
     2146                                ldb_msg_find_attr_as_uint(dom_res[i],
     2147                                                  "trustType", 0);
     2148                trusts->array[n].trust_attributes =
     2149                                ldb_msg_find_attr_as_uint(dom_res[i],
     2150                                                  "trustAttributes", 0);
     2151
     2152                if ((trusts->array[n].trust_type == NETR_TRUST_TYPE_MIT) ||
     2153                    (trusts->array[n].trust_type == NETR_TRUST_TYPE_DCE)) {
     2154                        struct dom_sid zero_sid;
     2155                        ZERO_STRUCT(zero_sid);
     2156                        trusts->array[n].sid =
     2157                                dom_sid_dup(trusts, &zero_sid);
     2158                } else {
     2159                        trusts->array[n].sid =
     2160                                samdb_result_dom_sid(trusts, dom_res[i],
     2161                                                     "securityIdentifier");
     2162                }
     2163                trusts->array[n].guid = GUID_zero();
     2164
     2165                trusts->count = n + 1;
     2166        }
     2167
     2168        talloc_free(dom_res);
     2169        return WERR_OK;
     2170}
     2171
     2172/*
     2173  netr_DsrEnumerateDomainTrusts
     2174*/
     2175static WERROR dcesrv_netr_DsrEnumerateDomainTrusts(struct dcesrv_call_state *dce_call,
     2176                                                   TALLOC_CTX *mem_ctx,
     2177                                                   struct netr_DsrEnumerateDomainTrusts *r)
    15812178{
    15822179        struct netr_DomainTrustList *trusts;
     
    15852182        struct ldb_message **dom_res;
    15862183        const char * const dom_attrs[] = { "objectSid", "objectGUID", NULL };
    1587 
    1588         ZERO_STRUCT(r->out);
    1589 
    1590         sam_ctx = samdb_connect(mem_ctx, dce_call->event_ctx, dce_call->conn->dce_ctx->lp_ctx, dce_call->conn->auth_state.session_info);
     2184        struct loadparm_context *lp_ctx = dce_call->conn->dce_ctx->lp_ctx;
     2185        const char *dnsdomain = lpcfg_dnsdomain(lp_ctx);
     2186        const char *p;
     2187        WERROR werr;
     2188
     2189        if (r->in.trust_flags & 0xFFFFFE00) {
     2190                return WERR_INVALID_FLAGS;
     2191        }
     2192
     2193        /* TODO: turn to hard check once we are sure this is 100% correct */
     2194        if (!r->in.server_name) {
     2195                DEBUG(3, ("Invalid domain! Expected name in domain [%s]. "
     2196                          "But received NULL!\n", dnsdomain));
     2197        } else {
     2198                p = strchr(r->in.server_name, '.');
     2199                if (!p) {
     2200                        DEBUG(3, ("Invalid domain! Expected name in domain "
     2201                                  "[%s]. But received [%s]!\n",
     2202                                  dnsdomain, r->in.server_name));
     2203                        p = r->in.server_name;
     2204                } else {
     2205                        p++;
     2206                }
     2207                if (strcasecmp(p, dnsdomain)) {
     2208                        DEBUG(3, ("Invalid domain! Expected name in domain "
     2209                                  "[%s]. But received [%s]!\n",
     2210                                  dnsdomain, r->in.server_name));
     2211                }
     2212        }
     2213
     2214        trusts = talloc_zero(mem_ctx, struct netr_DomainTrustList);
     2215        W_ERROR_HAVE_NO_MEMORY(trusts);
     2216
     2217        trusts->count = 0;
     2218        r->out.trusts = trusts;
     2219
     2220        sam_ctx = samdb_connect(mem_ctx, dce_call->event_ctx, lp_ctx,
     2221                                dce_call->conn->auth_state.session_info, 0);
    15912222        if (sam_ctx == NULL) {
    15922223                return WERR_GENERAL_FAILURE;
    15932224        }
    15942225
    1595         ret = gendb_search_dn(sam_ctx, mem_ctx, NULL,
    1596                               &dom_res, dom_attrs);
    1597         if (ret == -1) {
    1598                 return WERR_GENERAL_FAILURE;           
    1599         }
     2226        if ((r->in.trust_flags & NETR_TRUST_FLAG_INBOUND) ||
     2227            (r->in.trust_flags & NETR_TRUST_FLAG_OUTBOUND)) {
     2228
     2229                werr = fill_trusted_domains_array(mem_ctx, sam_ctx,
     2230                                                  trusts, r->in.trust_flags);
     2231                W_ERROR_NOT_OK_RETURN(werr);
     2232        }
     2233
     2234        /* NOTE: we currently are always the root of the forest */
     2235        if (r->in.trust_flags & NETR_TRUST_FLAG_IN_FOREST) {
     2236                uint32_t n = trusts->count;
     2237
     2238                ret = gendb_search_dn(sam_ctx, mem_ctx, NULL,
     2239                                      &dom_res, dom_attrs);
     2240                if (ret != 1) {
     2241                        return WERR_GENERAL_FAILURE;
     2242                }
     2243
     2244                trusts->count = n + 1;
     2245                trusts->array = talloc_realloc(trusts, trusts->array,
     2246                                               struct netr_DomainTrust,
     2247                                               trusts->count);
     2248                W_ERROR_HAVE_NO_MEMORY(trusts->array);
     2249
     2250                trusts->array[n].netbios_name = lpcfg_workgroup(lp_ctx);
     2251                trusts->array[n].dns_name = lpcfg_dnsdomain(lp_ctx);
     2252                trusts->array[n].trust_flags =
     2253                        NETR_TRUST_FLAG_NATIVE |
     2254                        NETR_TRUST_FLAG_TREEROOT |
     2255                        NETR_TRUST_FLAG_IN_FOREST |
     2256                        NETR_TRUST_FLAG_PRIMARY;
     2257                /* we are always the root domain for now */
     2258                trusts->array[n].parent_index = 0;
     2259                trusts->array[n].trust_type = NETR_TRUST_TYPE_UPLEVEL;
     2260                trusts->array[n].trust_attributes = 0;
     2261                trusts->array[n].sid = samdb_result_dom_sid(mem_ctx,
     2262                                                            dom_res[0],
     2263                                                            "objectSid");
     2264                trusts->array[n].guid = samdb_result_guid(dom_res[0],
     2265                                                          "objectGUID");
     2266                talloc_free(dom_res);
     2267        }
     2268
     2269        return WERR_OK;
     2270}
     2271
     2272
     2273/*
     2274  netr_DsrDeregisterDNSHostRecords
     2275*/
     2276static WERROR dcesrv_netr_DsrDeregisterDNSHostRecords(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
     2277                       struct netr_DsrDeregisterDNSHostRecords *r)
     2278{
     2279        DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
     2280}
     2281
     2282
     2283/*
     2284  netr_ServerTrustPasswordsGet
     2285*/
     2286static NTSTATUS dcesrv_netr_ServerTrustPasswordsGet(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
     2287                       struct netr_ServerTrustPasswordsGet *r)
     2288{
     2289        DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
     2290}
     2291
     2292
     2293static 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);
    16002332        if (ret != 1) {
    16012333                return WERR_GENERAL_FAILURE;
    16022334        }
    16032335
    1604         trusts = talloc(mem_ctx, struct netr_DomainTrustList);
    1605         W_ERROR_HAVE_NO_MEMORY(trusts);
    1606 
    1607         trusts->array = talloc_array(trusts, struct netr_DomainTrust, ret);
    1608         W_ERROR_HAVE_NO_MEMORY(trusts->array);
    1609 
    1610         trusts->count = 1; /* ?? */
    1611 
    1612         r->out.trusts = trusts;
    1613 
    1614         /* TODO: add filtering by trust_flags, and correct trust_type
    1615            and attributes */
    1616         trusts->array[0].netbios_name = lp_sam_name(dce_call->conn->dce_ctx->lp_ctx);
    1617         trusts->array[0].dns_name     = lp_realm(dce_call->conn->dce_ctx->lp_ctx);
    1618         trusts->array[0].trust_flags =
    1619                 NETR_TRUST_FLAG_TREEROOT |
    1620                 NETR_TRUST_FLAG_IN_FOREST |
    1621                 NETR_TRUST_FLAG_PRIMARY;
    1622         trusts->array[0].parent_index = 0;
    1623         trusts->array[0].trust_type = 2;
    1624         trusts->array[0].trust_attributes = 0;
    1625         trusts->array[0].sid  = samdb_result_dom_sid(mem_ctx, dom_res[0], "objectSid");
    1626         trusts->array[0].guid = samdb_result_guid(dom_res[0], "objectGUID");
     2336        /* TODO: check if disabled and set flags accordingly */
     2337        e->flags = 0;
     2338        e->type = LSA_FOREST_TRUST_DOMAIN_INFO;
     2339        e->time = 0; /* so far always 0 in traces. */
     2340
     2341        domain_info = &e->forest_trust_data.domain_info;
     2342        domain_info->domain_sid = samdb_result_dom_sid(info, dom_res[0],
     2343                                                       "objectSid");
     2344        domain_info->dns_domain_name.string = lpcfg_dnsdomain(lp_ctx);
     2345        domain_info->netbios_domain_name.string = lpcfg_workgroup(lp_ctx);
     2346
     2347        info->entries[1] = e;
     2348
     2349        talloc_free(dom_res);
    16272350
    16282351        return WERR_OK;
    16292352}
    16302353
    1631 
    1632 /*
    1633   netr_DsrDeregisterDNSHostRecords
    1634 */
    1635 static WERROR dcesrv_netr_DsrDeregisterDNSHostRecords(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
    1636                        struct netr_DsrDeregisterDNSHostRecords *r)
    1637 {
    1638         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
    1639 }
    1640 
    1641 
    1642 /*
    1643   netr_ServerTrustPasswordsGet
    1644 */
    1645 static NTSTATUS dcesrv_netr_ServerTrustPasswordsGet(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
    1646                        struct netr_ServerTrustPasswordsGet *r)
    1647 {
    1648         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
    1649 }
    1650 
    1651 
    1652 /*
    1653   netr_DsRGetForestTrustInformation
    1654 */
    1655 static WERROR dcesrv_netr_DsRGetForestTrustInformation(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
    1656                        struct netr_DsRGetForestTrustInformation *r)
    1657 {
    1658         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
     2354/*
     2355  netr_DsRGetForestTrustInformation
     2356*/
     2357static WERROR dcesrv_netr_DsRGetForestTrustInformation(struct dcesrv_call_state *dce_call,
     2358                                                       TALLOC_CTX *mem_ctx,
     2359                                                       struct netr_DsRGetForestTrustInformation *r)
     2360{
     2361        struct loadparm_context *lp_ctx = dce_call->conn->dce_ctx->lp_ctx;
     2362        struct lsa_ForestTrustInformation *info, **info_ptr;
     2363        struct ldb_context *sam_ctx;
     2364        WERROR werr;
     2365
     2366        if (r->in.flags & 0xFFFFFFFE) {
     2367                return WERR_INVALID_FLAGS;
     2368        }
     2369
     2370        sam_ctx = samdb_connect(mem_ctx, dce_call->event_ctx, lp_ctx,
     2371                                dce_call->conn->auth_state.session_info, 0);
     2372        if (sam_ctx == NULL) {
     2373                return WERR_GENERAL_FAILURE;
     2374        }
     2375
     2376        if (r->in.flags & DS_GFTI_UPDATE_TDO) {
     2377                if (!samdb_is_pdc(sam_ctx)) {
     2378                        return WERR_NERR_NOTPRIMARY;
     2379                }
     2380
     2381                if (r->in.trusted_domain_name == NULL) {
     2382                        return WERR_INVALID_FLAGS;
     2383                }
     2384
     2385                /* TODO: establish an schannel connection with
     2386                 * r->in.trusted_domain_name and perform a
     2387                 * netr_GetForestTrustInformation call against it */
     2388
     2389                /* for now return not implementd */
     2390                return WERR_CALL_NOT_IMPLEMENTED;
     2391        }
     2392
     2393        /* TODO: check r->in.server_name is our name */
     2394
     2395        info_ptr = talloc(mem_ctx, struct lsa_ForestTrustInformation *);
     2396        W_ERROR_HAVE_NO_MEMORY(info_ptr);
     2397
     2398        info = talloc_zero(info_ptr, struct lsa_ForestTrustInformation);
     2399        W_ERROR_HAVE_NO_MEMORY(info);
     2400
     2401        werr = fill_forest_trust_array(mem_ctx, sam_ctx, lp_ctx, info);
     2402        W_ERROR_NOT_OK_RETURN(werr);
     2403
     2404        *info_ptr = info;
     2405        r->out.forest_trust_info = info_ptr;
     2406
     2407        return WERR_OK;
    16592408}
    16602409
     
    16632412  netr_GetForestTrustInformation
    16642413*/
    1665 static WERROR dcesrv_netr_GetForestTrustInformation(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
    1666                        struct netr_GetForestTrustInformation *r)
    1667 {
    1668         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
     2414static NTSTATUS dcesrv_netr_GetForestTrustInformation(struct dcesrv_call_state *dce_call,
     2415                                                      TALLOC_CTX *mem_ctx,
     2416                                                      struct netr_GetForestTrustInformation *r)
     2417{
     2418        struct loadparm_context *lp_ctx = dce_call->conn->dce_ctx->lp_ctx;
     2419        struct netlogon_creds_CredentialState *creds;
     2420        struct lsa_ForestTrustInformation *info, **info_ptr;
     2421        struct ldb_context *sam_ctx;
     2422        NTSTATUS status;
     2423        WERROR werr;
     2424
     2425        status = dcesrv_netr_creds_server_step_check(dce_call,
     2426                                                     mem_ctx,
     2427                                                     r->in.computer_name,
     2428                                                     r->in.credential,
     2429                                                     r->out.return_authenticator,
     2430                                                     &creds);
     2431        if (!NT_STATUS_IS_OK(status)) {
     2432                return status;
     2433        }
     2434
     2435        if ((creds->secure_channel_type != SEC_CHAN_DNS_DOMAIN) &&
     2436            (creds->secure_channel_type != SEC_CHAN_DOMAIN)) {
     2437                return NT_STATUS_NOT_IMPLEMENTED;
     2438        }
     2439
     2440        sam_ctx = samdb_connect(mem_ctx, dce_call->event_ctx, lp_ctx,
     2441                                dce_call->conn->auth_state.session_info, 0);
     2442        if (sam_ctx == NULL) {
     2443                return NT_STATUS_UNSUCCESSFUL;
     2444        }
     2445
     2446        /* TODO: check r->in.server_name is our name */
     2447
     2448        info_ptr = talloc(mem_ctx, struct lsa_ForestTrustInformation *);
     2449        if (!info_ptr) {
     2450                return NT_STATUS_NO_MEMORY;
     2451        }
     2452        info = talloc_zero(info_ptr, struct lsa_ForestTrustInformation);
     2453        if (!info) {
     2454                return NT_STATUS_NO_MEMORY;
     2455        }
     2456
     2457        werr = fill_forest_trust_array(mem_ctx, sam_ctx, lp_ctx, info);
     2458        if (!W_ERROR_IS_OK(werr)) {
     2459                return werror_to_ntstatus(werr);
     2460        }
     2461
     2462        *info_ptr = info;
     2463        r->out.forest_trust_info = info_ptr;
     2464
     2465        return NT_STATUS_OK;
    16692466}
    16702467
     
    16792476}
    16802477
     2478/*
     2479  netr_Unused47
     2480*/
     2481static NTSTATUS dcesrv_netr_Unused47(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
     2482                                     struct netr_Unused47 *r)
     2483{
     2484        DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
     2485}
     2486
     2487
     2488struct netr_dnsupdate_RODC_state {
     2489        struct dcesrv_call_state *dce_call;
     2490        struct netr_DsrUpdateReadOnlyServerDnsRecords *r;
     2491        struct dnsupdate_RODC *r2;
     2492};
     2493
     2494/*
     2495  called when the forwarded RODC dns update request is finished
     2496 */
     2497static void netr_dnsupdate_RODC_callback(struct tevent_req *subreq)
     2498{
     2499        struct netr_dnsupdate_RODC_state *st =
     2500                tevent_req_callback_data(subreq,
     2501                                         struct netr_dnsupdate_RODC_state);
     2502        NTSTATUS status;
     2503
     2504        status = dcerpc_dnsupdate_RODC_r_recv(subreq, st->dce_call);
     2505        TALLOC_FREE(subreq);
     2506        if (!NT_STATUS_IS_OK(status)) {
     2507                DEBUG(0,(__location__ ": IRPC callback failed %s\n", nt_errstr(status)));
     2508                st->dce_call->fault_code = DCERPC_FAULT_CANT_PERFORM;
     2509        }
     2510
     2511        st->r->out.dns_names = talloc_steal(st->dce_call, st->r2->out.dns_names);
     2512
     2513        status = dcesrv_reply(st->dce_call);
     2514        if (!NT_STATUS_IS_OK(status)) {
     2515                DEBUG(0,(__location__ ": dcesrv_reply() failed - %s\n", nt_errstr(status)));
     2516        }
     2517}
     2518
     2519/*
     2520  netr_DsrUpdateReadOnlyServerDnsRecords
     2521*/
     2522static NTSTATUS dcesrv_netr_DsrUpdateReadOnlyServerDnsRecords(struct dcesrv_call_state *dce_call,
     2523                                                              TALLOC_CTX *mem_ctx,
     2524                                                              struct netr_DsrUpdateReadOnlyServerDnsRecords *r)
     2525{
     2526        struct netlogon_creds_CredentialState *creds;
     2527        NTSTATUS nt_status;
     2528        struct dcerpc_binding_handle *binding_handle;
     2529        struct netr_dnsupdate_RODC_state *st;
     2530        struct tevent_req *subreq;
     2531
     2532        nt_status = dcesrv_netr_creds_server_step_check(dce_call,
     2533                                                        mem_ctx,
     2534                                                        r->in.computer_name,
     2535                                                        r->in.credential,
     2536                                                        r->out.return_authenticator,
     2537                                                        &creds);
     2538        NT_STATUS_NOT_OK_RETURN(nt_status);
     2539
     2540        if (creds->secure_channel_type != SEC_CHAN_RODC) {
     2541                return NT_STATUS_ACCESS_DENIED;
     2542        }
     2543
     2544        st = talloc_zero(mem_ctx, struct netr_dnsupdate_RODC_state);
     2545        NT_STATUS_HAVE_NO_MEMORY(st);
     2546
     2547        st->dce_call = dce_call;
     2548        st->r = r;
     2549        st->r2 = talloc_zero(st, struct dnsupdate_RODC);
     2550        NT_STATUS_HAVE_NO_MEMORY(st->r2);
     2551
     2552        st->r2->in.dom_sid = creds->sid;
     2553        st->r2->in.site_name = r->in.site_name;
     2554        st->r2->in.dns_ttl = r->in.dns_ttl;
     2555        st->r2->in.dns_names = r->in.dns_names;
     2556        st->r2->out.dns_names = r->out.dns_names;
     2557
     2558        binding_handle = irpc_binding_handle_by_name(st, dce_call->msg_ctx,
     2559                                                     "dnsupdate", &ndr_table_irpc);
     2560        if (binding_handle == NULL) {
     2561                DEBUG(0,("Failed to get binding_handle for dnsupdate task\n"));
     2562                dce_call->fault_code = DCERPC_FAULT_CANT_PERFORM;
     2563                return NT_STATUS_INTERNAL_DB_CORRUPTION;
     2564        }
     2565
     2566        /* forward the call */
     2567        subreq = dcerpc_dnsupdate_RODC_r_send(st, dce_call->event_ctx,
     2568                                              binding_handle, st->r2);
     2569        NT_STATUS_HAVE_NO_MEMORY(subreq);
     2570
     2571        dce_call->state_flags |= DCESRV_CALL_STATE_FLAG_ASYNC;
     2572
     2573        /* setup the callback */
     2574        tevent_req_set_callback(subreq, netr_dnsupdate_RODC_callback, st);
     2575
     2576        return NT_STATUS_OK;
     2577}
     2578
    16812579
    16822580/* include the generated boilerplate */
Note: See TracChangeset for help on using the changeset viewer.