LCOV - code coverage report
Current view: top level - source3/rpc_server/netlogon - srv_netlog_nt.c (source / functions) Hit Total Coverage
Test: coverage report for abartlet/fix-coverage dd10fb34 Lines: 638 1282 49.8 %
Date: 2021-09-23 10:06:22 Functions: 19 64 29.7 %

          Line data    Source code
       1             : /*
       2             :  *  Unix SMB/CIFS implementation.
       3             :  *  RPC Pipe client / server routines
       4             :  *  Copyright (C) Andrew Tridgell              1992-1997,
       5             :  *  Copyright (C) Luke Kenneth Casson Leighton 1996-1997,
       6             :  *  Copyright (C) Paul Ashton                       1997.
       7             :  *  Copyright (C) Jeremy Allison               1998-2001.
       8             :  *  Copyright (C) Andrew Bartlett                   2001.
       9             :  *  Copyright (C) Guenther Deschner                 2008-2009.
      10             :  *
      11             :  *  This program is free software; you can redistribute it and/or modify
      12             :  *  it under the terms of the GNU General Public License as published by
      13             :  *  the Free Software Foundation; either version 3 of the License, or
      14             :  *  (at your option) any later version.
      15             :  *
      16             :  *  This program is distributed in the hope that it will be useful,
      17             :  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
      18             :  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      19             :  *  GNU General Public License for more details.
      20             :  *
      21             :  *  You should have received a copy of the GNU General Public License
      22             :  *  along with this program; if not, see <http://www.gnu.org/licenses/>.
      23             :  */
      24             : 
      25             : /* This is the implementation of the netlogon pipe. */
      26             : 
      27             : #include "includes.h"
      28             : #include "system/passwd.h" /* uid_wrapper */
      29             : #include "ntdomain.h"
      30             : #include "../libcli/auth/schannel.h"
      31             : #include "librpc/gen_ndr/ndr_netlogon.h"
      32             : #include "librpc/gen_ndr/ndr_netlogon_scompat.h"
      33             : #include "librpc/gen_ndr/ndr_samr_c.h"
      34             : #include "librpc/gen_ndr/ndr_lsa_c.h"
      35             : #include "rpc_client/cli_lsarpc.h"
      36             : #include "rpc_client/init_lsa.h"
      37             : #include "rpc_client/init_samr.h"
      38             : #include "rpc_server/rpc_ncacn_np.h"
      39             : #include "../libcli/security/security.h"
      40             : #include "../libcli/security/dom_sid.h"
      41             : #include "librpc/gen_ndr/ndr_drsblobs.h"
      42             : #include "lib/crypto/md4.h"
      43             : #include "nsswitch/libwbclient/wbclient.h"
      44             : #include "../libcli/registry/util_reg.h"
      45             : #include "passdb.h"
      46             : #include "auth.h"
      47             : #include "messages.h"
      48             : #include "../lib/tsocket/tsocket.h"
      49             : #include "lib/param/param.h"
      50             : #include "libsmb/dsgetdcname.h"
      51             : #include "lib/util/util_str_escape.h"
      52             : 
      53             : extern userdom_struct current_user_info;
      54             : 
      55             : #undef DBGC_CLASS
      56             : #define DBGC_CLASS DBGC_RPC_SRV
      57             : 
      58             : struct netlogon_server_pipe_state {
      59             :         struct netr_Credential client_challenge;
      60             :         struct netr_Credential server_challenge;
      61             : };
      62             : 
      63             : /*************************************************************************
      64             :  _netr_LogonControl
      65             :  *************************************************************************/
      66             : 
      67         260 : WERROR _netr_LogonControl(struct pipes_struct *p,
      68             :                           struct netr_LogonControl *r)
      69             : {
      70             :         struct netr_LogonControl2Ex l;
      71             : 
      72         260 :         switch (r->in.level) {
      73          64 :         case 1:
      74          64 :                 break;
      75          64 :         case 2:
      76          64 :                 return WERR_NOT_SUPPORTED;
      77         132 :         default:
      78         132 :                 return WERR_INVALID_LEVEL;
      79             :         }
      80             : 
      81          64 :         switch (r->in.function_code) {
      82          28 :         case NETLOGON_CONTROL_QUERY:
      83             :         case NETLOGON_CONTROL_REPLICATE:
      84             :         case NETLOGON_CONTROL_SYNCHRONIZE:
      85             :         case NETLOGON_CONTROL_PDC_REPLICATE:
      86             :         case NETLOGON_CONTROL_BREAKPOINT:
      87             :         case NETLOGON_CONTROL_BACKUP_CHANGE_LOG:
      88             :         case NETLOGON_CONTROL_TRUNCATE_LOG:
      89          28 :                 break;
      90          36 :         default:
      91          36 :                 return WERR_NOT_SUPPORTED;
      92             :         }
      93             : 
      94          28 :         l.in.logon_server       = r->in.logon_server;
      95          28 :         l.in.function_code      = r->in.function_code;
      96          28 :         l.in.level              = r->in.level;
      97          28 :         l.in.data               = NULL;
      98          28 :         l.out.query             = r->out.query;
      99             : 
     100          28 :         return _netr_LogonControl2Ex(p, &l);
     101             : }
     102             : 
     103             : /*************************************************************************
     104             :  _netr_LogonControl2
     105             :  *************************************************************************/
     106             : 
     107          56 : WERROR _netr_LogonControl2(struct pipes_struct *p,
     108             :                            struct netr_LogonControl2 *r)
     109             : {
     110             :         struct netr_LogonControl2Ex l;
     111             : 
     112          56 :         l.in.logon_server       = r->in.logon_server;
     113          56 :         l.in.function_code      = r->in.function_code;
     114          56 :         l.in.level              = r->in.level;
     115          56 :         l.in.data               = r->in.data;
     116          56 :         l.out.query             = r->out.query;
     117             : 
     118          56 :         return _netr_LogonControl2Ex(p, &l);
     119             : }
     120             : 
     121             : /*************************************************************************
     122             :  *************************************************************************/
     123             : 
     124           0 : static bool wb_change_trust_creds(const char *domain, WERROR *tc_status)
     125             : {
     126             :         wbcErr result;
     127           0 :         struct wbcAuthErrorInfo *error = NULL;
     128             : 
     129           0 :         result = wbcChangeTrustCredentials(domain, &error);
     130           0 :         switch (result) {
     131           0 :         case WBC_ERR_WINBIND_NOT_AVAILABLE:
     132           0 :                 return false;
     133           0 :         case WBC_ERR_DOMAIN_NOT_FOUND:
     134           0 :                 *tc_status = WERR_NO_SUCH_DOMAIN;
     135           0 :                 return true;
     136           0 :         case WBC_ERR_SUCCESS:
     137           0 :                 *tc_status = WERR_OK;
     138           0 :                 return true;
     139           0 :         default:
     140           0 :                 break;
     141             :         }
     142             : 
     143           0 :         if (error && error->nt_status != 0) {
     144           0 :                 *tc_status = ntstatus_to_werror(NT_STATUS(error->nt_status));
     145             :         } else {
     146           0 :                 *tc_status = WERR_TRUST_FAILURE;
     147             :         }
     148           0 :         wbcFreeMemory(error);
     149           0 :         return true;
     150             : }
     151             : 
     152             : /*************************************************************************
     153             :  *************************************************************************/
     154             : 
     155           0 : static bool wb_check_trust_creds(const char *domain, WERROR *tc_status)
     156             : {
     157             :         wbcErr result;
     158           0 :         struct wbcAuthErrorInfo *error = NULL;
     159             : 
     160           0 :         result = wbcCheckTrustCredentials(domain, &error);
     161           0 :         switch (result) {
     162           0 :         case WBC_ERR_WINBIND_NOT_AVAILABLE:
     163           0 :                 return false;
     164           0 :         case WBC_ERR_DOMAIN_NOT_FOUND:
     165           0 :                 *tc_status = WERR_NO_SUCH_DOMAIN;
     166           0 :                 return true;
     167           0 :         case WBC_ERR_SUCCESS:
     168           0 :                 *tc_status = WERR_OK;
     169           0 :                 return true;
     170           0 :         default:
     171           0 :                 break;
     172             :         }
     173             : 
     174           0 :         if (error && error->nt_status != 0) {
     175           0 :                 *tc_status = ntstatus_to_werror(NT_STATUS(error->nt_status));
     176             :         } else {
     177           0 :                 *tc_status = WERR_TRUST_FAILURE;
     178             :         }
     179           0 :         wbcFreeMemory(error);
     180           0 :         return true;
     181             : }
     182             : 
     183             : /****************************************************************
     184             :  _netr_LogonControl2Ex
     185             : ****************************************************************/
     186             : 
     187         140 : WERROR _netr_LogonControl2Ex(struct pipes_struct *p,
     188             :                              struct netr_LogonControl2Ex *r)
     189             : {
     190         140 :         uint32_t flags = 0x0;
     191         140 :         WERROR pdc_connection_status = WERR_OK;
     192         140 :         uint32_t logon_attempts = 0x0;
     193             :         WERROR tc_status;
     194             :         fstring dc_name2;
     195         140 :         const char *dc_name = NULL;
     196             :         struct sockaddr_storage dc_ss;
     197         140 :         const char *domain = NULL;
     198             :         struct netr_NETLOGON_INFO_1 *info1;
     199             :         struct netr_NETLOGON_INFO_2 *info2;
     200             :         struct netr_NETLOGON_INFO_3 *info3;
     201             :         struct netr_NETLOGON_INFO_4 *info4;
     202             :         const char *fn;
     203             :         NTSTATUS status;
     204             :         struct netr_DsRGetDCNameInfo *dc_info;
     205             : 
     206         140 :         switch (p->opnum) {
     207          28 :         case NDR_NETR_LOGONCONTROL:
     208          28 :                 fn = "_netr_LogonControl";
     209          28 :                 break;
     210          56 :         case NDR_NETR_LOGONCONTROL2:
     211          56 :                 fn = "_netr_LogonControl2";
     212          56 :                 break;
     213          56 :         case NDR_NETR_LOGONCONTROL2EX:
     214          56 :                 fn = "_netr_LogonControl2Ex";
     215          56 :                 break;
     216           0 :         default:
     217           0 :                 return WERR_INVALID_PARAMETER;
     218             :         }
     219             : 
     220         140 :         switch (r->in.level) {
     221         132 :         case 1:
     222             :         case 2:
     223             :         case 3:
     224             :         case 4:
     225         132 :                 break;
     226           8 :         default:
     227           8 :                 return WERR_INVALID_LEVEL;
     228             :         }
     229             : 
     230         132 :         switch (r->in.function_code) {
     231           4 :         case NETLOGON_CONTROL_QUERY:
     232           4 :                 break;
     233         128 :         default:
     234         192 :                 if ((geteuid() != sec_initial_uid()) &&
     235         128 :                     !nt_token_check_domain_rid(p->session_info->security_token, DOMAIN_RID_ADMINS) &&
     236          64 :                     !nt_token_check_sid(&global_sid_Builtin_Administrators, p->session_info->security_token))
     237             :                 {
     238          64 :                         return WERR_ACCESS_DENIED;
     239             :                 }
     240          64 :                 break;
     241             :         }
     242             : 
     243          68 :         tc_status = WERR_NO_SUCH_DOMAIN;
     244             : 
     245          68 :         switch (r->in.function_code) {
     246           4 :         case NETLOGON_CONTROL_QUERY:
     247           4 :                 switch (r->in.level) {
     248           4 :                 case 1:
     249             :                 case 3:
     250           4 :                         break;
     251           0 :                 default:
     252           0 :                         return WERR_INVALID_PARAMETER;
     253             :                 }
     254             : 
     255           4 :                 tc_status = WERR_OK;
     256           4 :                 break;
     257          24 :         case NETLOGON_CONTROL_REPLICATE:
     258             :         case NETLOGON_CONTROL_SYNCHRONIZE:
     259             :         case NETLOGON_CONTROL_PDC_REPLICATE:
     260             :         case NETLOGON_CONTROL_BACKUP_CHANGE_LOG:
     261             :         case NETLOGON_CONTROL_BREAKPOINT:
     262             :         case NETLOGON_CONTROL_TRUNCATE_LOG:
     263             :         case NETLOGON_CONTROL_TRANSPORT_NOTIFY:
     264             :         case NETLOGON_CONTROL_FORCE_DNS_REG:
     265             :         case NETLOGON_CONTROL_QUERY_DNS_REG:
     266          24 :                 return WERR_NOT_SUPPORTED;
     267             : 
     268           0 :         case NETLOGON_CONTROL_FIND_USER:
     269           0 :                 if (!r->in.data || !r->in.data->user) {
     270           0 :                         return WERR_NOT_SUPPORTED;
     271             :                 }
     272           0 :                 break;
     273          12 :         case NETLOGON_CONTROL_SET_DBFLAG:
     274          12 :                 if (!r->in.data) {
     275           0 :                         return WERR_NOT_SUPPORTED;
     276             :                 }
     277          12 :                 break;
     278           0 :         case NETLOGON_CONTROL_TC_VERIFY:
     279           0 :                 if (!r->in.data || !r->in.data->domain) {
     280           0 :                         return WERR_NOT_SUPPORTED;
     281             :                 }
     282             : 
     283           0 :                 if (!wb_check_trust_creds(r->in.data->domain, &tc_status)) {
     284           0 :                         return WERR_NOT_SUPPORTED;
     285             :                 }
     286           0 :                 break;
     287          12 :         case NETLOGON_CONTROL_TC_QUERY:
     288          12 :                 if (!r->in.data || !r->in.data->domain) {
     289           0 :                         return WERR_NOT_SUPPORTED;
     290             :                 }
     291             : 
     292          12 :                 domain = r->in.data->domain;
     293             : 
     294          12 :                 if (!is_trusted_domain(domain)) {
     295          12 :                         break;
     296             :                 }
     297             : 
     298           0 :                 if (!get_dc_name(domain, NULL, dc_name2, &dc_ss)) {
     299           0 :                         tc_status = WERR_NO_LOGON_SERVERS;
     300           0 :                         break;
     301             :                 }
     302             : 
     303           0 :                 dc_name = talloc_asprintf(p->mem_ctx, "\\\\%s", dc_name2);
     304           0 :                 if (!dc_name) {
     305           0 :                         return WERR_NOT_ENOUGH_MEMORY;
     306             :                 }
     307             : 
     308           0 :                 tc_status = WERR_OK;
     309             : 
     310           0 :                 break;
     311             : 
     312          12 :         case NETLOGON_CONTROL_REDISCOVER:
     313          12 :                 if (!r->in.data || !r->in.data->domain) {
     314           0 :                         return WERR_NOT_SUPPORTED;
     315             :                 }
     316             : 
     317          12 :                 domain = r->in.data->domain;
     318             : 
     319          12 :                 if (!is_trusted_domain(domain)) {
     320          12 :                         break;
     321             :                 }
     322             : 
     323           0 :                 status = dsgetdcname(p->mem_ctx, p->msg_ctx, domain, NULL, NULL,
     324             :                                      DS_FORCE_REDISCOVERY | DS_RETURN_FLAT_NAME,
     325             :                                      &dc_info);
     326           0 :                 if (!NT_STATUS_IS_OK(status)) {
     327           0 :                         tc_status = WERR_NO_LOGON_SERVERS;
     328           0 :                         break;
     329             :                 }
     330             : 
     331           0 :                 dc_name = talloc_asprintf(p->mem_ctx, "\\\\%s", dc_info->dc_unc);
     332           0 :                 if (!dc_name) {
     333           0 :                         return WERR_NOT_ENOUGH_MEMORY;
     334             :                 }
     335             : 
     336           0 :                 tc_status = WERR_OK;
     337             : 
     338           0 :                 break;
     339             : 
     340           0 :         case NETLOGON_CONTROL_CHANGE_PASSWORD:
     341           0 :                 if (!r->in.data || !r->in.data->domain) {
     342           0 :                         return WERR_NOT_SUPPORTED;
     343             :                 }
     344             : 
     345           0 :                 if (!wb_change_trust_creds(r->in.data->domain, &tc_status)) {
     346           0 :                         return WERR_NOT_SUPPORTED;
     347             :                 }
     348           0 :                 break;
     349             : 
     350           4 :         default:
     351             :                 /* no idea what this should be */
     352           4 :                 DEBUG(0,("%s: unimplemented function level [%d]\n",
     353             :                         fn, r->in.function_code));
     354           4 :                 return WERR_NOT_SUPPORTED;
     355             :         }
     356             : 
     357             :         /* prepare the response */
     358             : 
     359          40 :         switch (r->in.level) {
     360          16 :         case 1:
     361          16 :                 info1 = talloc_zero(p->mem_ctx, struct netr_NETLOGON_INFO_1);
     362          16 :                 W_ERROR_HAVE_NO_MEMORY(info1);
     363             : 
     364          16 :                 info1->flags                 = flags;
     365          16 :                 info1->pdc_connection_status = pdc_connection_status;
     366             : 
     367          16 :                 r->out.query->info1 = info1;
     368          16 :                 break;
     369          12 :         case 2:
     370          12 :                 info2 = talloc_zero(p->mem_ctx, struct netr_NETLOGON_INFO_2);
     371          12 :                 W_ERROR_HAVE_NO_MEMORY(info2);
     372             : 
     373          12 :                 info2->flags                 = flags;
     374          12 :                 info2->pdc_connection_status = pdc_connection_status;
     375          12 :                 info2->trusted_dc_name               = dc_name;
     376          12 :                 info2->tc_connection_status  = tc_status;
     377             : 
     378          12 :                 r->out.query->info2 = info2;
     379          12 :                 break;
     380          12 :         case 3:
     381          12 :                 info3 = talloc_zero(p->mem_ctx, struct netr_NETLOGON_INFO_3);
     382          12 :                 W_ERROR_HAVE_NO_MEMORY(info3);
     383             : 
     384          12 :                 info3->flags                 = flags;
     385          12 :                 info3->logon_attempts                = logon_attempts;
     386             : 
     387          12 :                 r->out.query->info3 = info3;
     388          12 :                 break;
     389           0 :         case 4:
     390           0 :                 info4 = talloc_zero(p->mem_ctx, struct netr_NETLOGON_INFO_4);
     391           0 :                 W_ERROR_HAVE_NO_MEMORY(info4);
     392             : 
     393           0 :                 info4->trusted_dc_name               = dc_name;
     394           0 :                 info4->trusted_domain_name   = r->in.data->domain;
     395             : 
     396           0 :                 r->out.query->info4 = info4;
     397           0 :                 break;
     398           0 :         default:
     399           0 :                 return WERR_INVALID_LEVEL;
     400             :         }
     401             : 
     402          40 :         return WERR_OK;
     403             : }
     404             : 
     405             : /*************************************************************************
     406             :  _netr_NetrEnumerateTrustedDomains
     407             :  *************************************************************************/
     408             : 
     409           0 : NTSTATUS _netr_NetrEnumerateTrustedDomains(struct pipes_struct *p,
     410             :                                            struct netr_NetrEnumerateTrustedDomains *r)
     411             : {
     412             :         NTSTATUS status;
     413           0 :         NTSTATUS result = NT_STATUS_OK;
     414             :         DATA_BLOB blob;
     415           0 :         size_t num_domains = 0;
     416           0 :         const char **trusted_domains = NULL;
     417             :         struct lsa_DomainList domain_list;
     418           0 :         struct dcerpc_binding_handle *h = NULL;
     419             :         struct policy_handle pol;
     420           0 :         uint32_t enum_ctx = 0;
     421           0 :         uint32_t max_size = (uint32_t)-1;
     422             : 
     423           0 :         ZERO_STRUCT(pol);
     424           0 :         DEBUG(6,("_netr_NetrEnumerateTrustedDomains: %d\n", __LINE__));
     425             : 
     426           0 :         status = rpcint_binding_handle(p->mem_ctx,
     427             :                                        &ndr_table_lsarpc,
     428             :                                        p->remote_address,
     429             :                                        p->local_address,
     430           0 :                                        p->session_info,
     431             :                                        p->msg_ctx,
     432             :                                        &h);
     433           0 :         if (!NT_STATUS_IS_OK(status)) {
     434           0 :                 return status;
     435             :         }
     436             : 
     437           0 :         status = dcerpc_lsa_open_policy2(h,
     438             :                                          p->mem_ctx,
     439             :                                          NULL,
     440             :                                          true,
     441             :                                          LSA_POLICY_VIEW_LOCAL_INFORMATION,
     442             :                                          &pol,
     443             :                                          &result);
     444           0 :         if (any_nt_status_not_ok(status, result, &status)) {
     445           0 :                 goto out;
     446             :         }
     447             : 
     448             :         do {
     449             :                 uint32_t i;
     450             : 
     451             :                 /* Lookup list of trusted domains */
     452           0 :                 status = dcerpc_lsa_EnumTrustDom(h,
     453             :                                                  p->mem_ctx,
     454             :                                                  &pol,
     455             :                                                  &enum_ctx,
     456             :                                                  &domain_list,
     457             :                                                  max_size,
     458             :                                                  &result);
     459           0 :                 if (!NT_STATUS_IS_OK(status)) {
     460           0 :                         goto out;
     461             :                 }
     462           0 :                 if (!NT_STATUS_IS_OK(result) &&
     463           0 :                     !NT_STATUS_EQUAL(result, NT_STATUS_NO_MORE_ENTRIES) &&
     464           0 :                     !NT_STATUS_EQUAL(result, STATUS_MORE_ENTRIES)) {
     465           0 :                         status = result;
     466           0 :                         goto out;
     467             :                 }
     468             : 
     469           0 :                 for (i = 0; i < domain_list.count; i++) {
     470           0 :                         if (!add_string_to_array(p->mem_ctx, domain_list.domains[i].name.string,
     471             :                                                  &trusted_domains, &num_domains)) {
     472           0 :                                 status = NT_STATUS_NO_MEMORY;
     473           0 :                                 goto out;
     474             :                         }
     475             :                 }
     476           0 :         } while (NT_STATUS_EQUAL(result, STATUS_MORE_ENTRIES));
     477             : 
     478           0 :         if (num_domains > 0) {
     479             :                 /* multi sz terminate */
     480           0 :                 trusted_domains = talloc_realloc(p->mem_ctx, trusted_domains, const char *, num_domains + 1);
     481           0 :                 if (trusted_domains == NULL) {
     482           0 :                         status = NT_STATUS_NO_MEMORY;
     483           0 :                         goto out;
     484             :                 }
     485             : 
     486           0 :                 trusted_domains[num_domains] = NULL;
     487             :         }
     488             : 
     489           0 :         if (!push_reg_multi_sz(trusted_domains, &blob, trusted_domains)) {
     490           0 :                 TALLOC_FREE(trusted_domains);
     491           0 :                 status = NT_STATUS_NO_MEMORY;
     492           0 :                 goto out;
     493             :         }
     494             : 
     495           0 :         r->out.trusted_domains_blob->data = blob.data;
     496           0 :         r->out.trusted_domains_blob->length = blob.length;
     497             : 
     498           0 :         DEBUG(6,("_netr_NetrEnumerateTrustedDomains: %d\n", __LINE__));
     499             : 
     500           0 :         status = NT_STATUS_OK;
     501             : 
     502           0 :  out:
     503           0 :         if (is_valid_policy_hnd(&pol)) {
     504           0 :                 dcerpc_lsa_Close(h, p->mem_ctx, &pol, &result);
     505             :         }
     506             : 
     507           0 :         return status;
     508             : }
     509             : 
     510             : /*************************************************************************
     511             :  *************************************************************************/
     512             : 
     513          50 : static NTSTATUS samr_find_machine_account(TALLOC_CTX *mem_ctx,
     514             :                                           struct dcerpc_binding_handle *b,
     515             :                                           const char *account_name,
     516             :                                           uint32_t access_mask,
     517             :                                           struct dom_sid2 **domain_sid_p,
     518             :                                           uint32_t *user_rid_p,
     519             :                                           struct policy_handle *user_handle)
     520             : {
     521             :         NTSTATUS status;
     522          50 :         NTSTATUS result = NT_STATUS_OK;
     523             :         struct policy_handle connect_handle;
     524          50 :         struct policy_handle domain_handle = { 0, };
     525             :         struct lsa_String domain_name;
     526             :         struct dom_sid2 *domain_sid;
     527             :         struct lsa_String names;
     528             :         struct samr_Ids rids;
     529             :         struct samr_Ids types;
     530             :         uint32_t rid;
     531             : 
     532          50 :         status = dcerpc_samr_Connect2(b, mem_ctx,
     533             :                                       lp_netbios_name(),
     534             :                                       SAMR_ACCESS_CONNECT_TO_SERVER |
     535             :                                       SAMR_ACCESS_ENUM_DOMAINS |
     536             :                                       SAMR_ACCESS_LOOKUP_DOMAIN,
     537             :                                       &connect_handle,
     538             :                                       &result);
     539          50 :         if (any_nt_status_not_ok(status, result, &status)) {
     540           0 :                 goto out;
     541             :         }
     542             : 
     543          50 :         init_lsa_String(&domain_name, get_global_sam_name());
     544             : 
     545          50 :         status = dcerpc_samr_LookupDomain(b, mem_ctx,
     546             :                                           &connect_handle,
     547             :                                           &domain_name,
     548             :                                           &domain_sid,
     549             :                                           &result);
     550          50 :         if (any_nt_status_not_ok(status, result, &status)) {
     551           0 :                 goto out;
     552             :         }
     553             : 
     554          50 :         status = dcerpc_samr_OpenDomain(b, mem_ctx,
     555             :                                         &connect_handle,
     556             :                                         SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT,
     557             :                                         domain_sid,
     558             :                                         &domain_handle,
     559             :                                         &result);
     560          50 :         if (any_nt_status_not_ok(status, result, &status)) {
     561           0 :                 goto out;
     562             :         }
     563             : 
     564          50 :         init_lsa_String(&names, account_name);
     565             : 
     566          50 :         status = dcerpc_samr_LookupNames(b, mem_ctx,
     567             :                                          &domain_handle,
     568             :                                          1,
     569             :                                          &names,
     570             :                                          &rids,
     571             :                                          &types,
     572             :                                          &result);
     573          50 :         if (any_nt_status_not_ok(status, result, &status)) {
     574           4 :                 goto out;
     575             :         }
     576             : 
     577          46 :         if (rids.count != 1) {
     578           0 :                 status = NT_STATUS_NO_SUCH_USER;
     579           0 :                 goto out;
     580             :         }
     581          46 :         if (types.count != 1) {
     582           0 :                 status = NT_STATUS_INVALID_PARAMETER;
     583           0 :                 goto out;
     584             :         }
     585          46 :         if (types.ids[0] != SID_NAME_USER) {
     586           0 :                 status = NT_STATUS_NO_SUCH_USER;
     587           0 :                 goto out;
     588             :         }
     589             : 
     590          46 :         rid = rids.ids[0];
     591             : 
     592          46 :         status = dcerpc_samr_OpenUser(b, mem_ctx,
     593             :                                       &domain_handle,
     594             :                                       access_mask,
     595             :                                       rid,
     596             :                                       user_handle,
     597             :                                       &result);
     598          46 :         if (any_nt_status_not_ok(status, result, &status)) {
     599           0 :                 goto out;
     600             :         }
     601             : 
     602          46 :         if (user_rid_p) {
     603          46 :                 *user_rid_p = rid;
     604             :         }
     605             : 
     606          46 :         if (domain_sid_p) {
     607          46 :                 *domain_sid_p = domain_sid;
     608             :         }
     609             : 
     610          50 :  out:
     611          50 :         if (is_valid_policy_hnd(&domain_handle)) {
     612          50 :                 dcerpc_samr_Close(b, mem_ctx, &domain_handle, &result);
     613             :         }
     614          50 :         if (is_valid_policy_hnd(&connect_handle)) {
     615          50 :                 dcerpc_samr_Close(b, mem_ctx, &connect_handle, &result);
     616             :         }
     617             : 
     618          50 :         return status;
     619             : }
     620             : 
     621             : /******************************************************************
     622             :  gets a machine password entry.  checks access rights of the host.
     623             :  ******************************************************************/
     624             : 
     625          50 : static NTSTATUS get_md4pw(struct samr_Password *md4pw, const char *mach_acct,
     626             :                           enum netr_SchannelType sec_chan_type,
     627             :                           struct dom_sid *sid,
     628             :                           struct messaging_context *msg_ctx)
     629             : {
     630             :         NTSTATUS status;
     631          50 :         NTSTATUS result = NT_STATUS_OK;
     632          50 :         TALLOC_CTX *mem_ctx = NULL;
     633          50 :         struct dcerpc_binding_handle *h = NULL;
     634          50 :         struct tsocket_address *local = NULL;
     635          50 :         struct policy_handle user_handle = { .handle_type = 0 };
     636          50 :         uint32_t user_rid = UINT32_MAX;
     637          50 :         struct dom_sid *domain_sid = NULL;
     638          50 :         uint32_t acct_ctrl = 0;
     639          50 :         union samr_UserInfo *info = NULL;
     640          50 :         struct auth_session_info *session_info = NULL;
     641             :         int rc;
     642             : 
     643             : #if 0
     644             : 
     645             :     /*
     646             :      * Currently this code is redundant as we already have a filter
     647             :      * by hostname list. What this code really needs to do is to
     648             :      * get a hosts allowed/hosts denied list from the SAM database
     649             :      * on a per user basis, and make the access decision there.
     650             :      * I will leave this code here for now as a reminder to implement
     651             :      * this at a later date. JRA.
     652             :      */
     653             : 
     654             :         if (!allow_access(lp_domain_hostsdeny(), lp_domain_hostsallow(),
     655             :                           p->client_id.name,
     656             :                           p->client_id.addr)) {
     657             :                 DEBUG(0,("get_md4pw: Workstation %s denied access to domain\n", mach_acct));
     658             :                 return False;
     659             :         }
     660             : #endif /* 0 */
     661             : 
     662          50 :         mem_ctx = talloc_stackframe();
     663             : 
     664          50 :         status = make_session_info_system(mem_ctx, &session_info);
     665          50 :         if (!NT_STATUS_IS_OK(status)) {
     666           0 :                 goto out;
     667             :         }
     668             : 
     669          50 :         ZERO_STRUCT(user_handle);
     670             : 
     671          50 :         rc = tsocket_address_inet_from_strings(mem_ctx,
     672             :                                                "ip",
     673             :                                                "127.0.0.1",
     674             :                                                0,
     675             :                                                &local);
     676          50 :         if (rc < 0) {
     677           0 :                 status = NT_STATUS_NO_MEMORY;
     678           0 :                 goto out;
     679             :         }
     680             : 
     681          50 :         status = rpcint_binding_handle(mem_ctx,
     682             :                                        &ndr_table_samr,
     683             :                                        local,
     684             :                                        NULL,
     685             :                                        session_info,
     686             :                                        msg_ctx,
     687             :                                        &h);
     688          50 :         if (!NT_STATUS_IS_OK(status)) {
     689           0 :                 goto out;
     690             :         }
     691             : 
     692          50 :         status = samr_find_machine_account(mem_ctx, h, mach_acct,
     693             :                                            SEC_FLAG_MAXIMUM_ALLOWED,
     694             :                                            &domain_sid, &user_rid,
     695             :                                            &user_handle);
     696          50 :         if (!NT_STATUS_IS_OK(status)) {
     697           4 :                 goto out;
     698             :         }
     699             : 
     700          46 :         status = dcerpc_samr_QueryUserInfo2(h,
     701             :                                             mem_ctx,
     702             :                                             &user_handle,
     703             :                                             UserControlInformation,
     704             :                                             &info,
     705             :                                             &result);
     706          46 :         if (any_nt_status_not_ok(status, result, &status)) {
     707           0 :                 goto out;
     708             :         }
     709             : 
     710          46 :         acct_ctrl = info->info16.acct_flags;
     711             : 
     712          46 :         if (acct_ctrl & ACB_DISABLED) {
     713           0 :                 DEBUG(0,("get_md4pw: Workstation %s: account is disabled\n", mach_acct));
     714           0 :                 status = NT_STATUS_ACCOUNT_DISABLED;
     715           0 :                 goto out;
     716             :         }
     717             : 
     718          65 :         if (!(acct_ctrl & ACB_SVRTRUST) &&
     719          19 :             !(acct_ctrl & ACB_WSTRUST) &&
     720           0 :             !(acct_ctrl & ACB_DOMTRUST))
     721             :         {
     722           0 :                 DEBUG(0,("get_md4pw: Workstation %s: account is not a trust account\n", mach_acct));
     723           0 :                 status = NT_STATUS_NO_TRUST_SAM_ACCOUNT;
     724           0 :                 goto out;
     725             :         }
     726             : 
     727          46 :         switch (sec_chan_type) {
     728          27 :                 case SEC_CHAN_BDC:
     729          27 :                         if (!(acct_ctrl & ACB_SVRTRUST)) {
     730           0 :                                 DEBUG(0,("get_md4pw: Workstation %s: BDC secure channel requested "
     731             :                                          "but not a server trust account\n", mach_acct));
     732           0 :                                 status = NT_STATUS_NO_TRUST_SAM_ACCOUNT;
     733           0 :                                 goto out;
     734             :                         }
     735          27 :                         break;
     736          19 :                 case SEC_CHAN_WKSTA:
     737          19 :                         if (!(acct_ctrl & ACB_WSTRUST)) {
     738           0 :                                 DEBUG(0,("get_md4pw: Workstation %s: WORKSTATION secure channel requested "
     739             :                                          "but not a workstation trust account\n", mach_acct));
     740           0 :                                 status = NT_STATUS_NO_TRUST_SAM_ACCOUNT;
     741           0 :                                 goto out;
     742             :                         }
     743          19 :                         break;
     744           0 :                 case SEC_CHAN_DOMAIN:
     745           0 :                         if (!(acct_ctrl & ACB_DOMTRUST)) {
     746           0 :                                 DEBUG(0,("get_md4pw: Workstation %s: DOMAIN secure channel requested "
     747             :                                          "but not a interdomain trust account\n", mach_acct));
     748           0 :                                 status = NT_STATUS_NO_TRUST_SAM_ACCOUNT;
     749           0 :                                 goto out;
     750             :                         }
     751           0 :                         break;
     752           0 :                 default:
     753           0 :                         break;
     754             :         }
     755             : 
     756          46 :         become_root();
     757          46 :         status = dcerpc_samr_QueryUserInfo2(h,
     758             :                                             mem_ctx,
     759             :                                             &user_handle,
     760             :                                             UserInternal1Information,
     761             :                                             &info,
     762             :                                             &result);
     763          46 :         unbecome_root();
     764          46 :         if (any_nt_status_not_ok(status, result, &status)) {
     765           0 :                 goto out;
     766             :         }
     767             : 
     768          46 :         if (info->info18.nt_pwd_active == 0) {
     769           0 :                 DEBUG(0,("get_md4pw: Workstation %s: account does not have a password\n", mach_acct));
     770           0 :                 status = NT_STATUS_LOGON_FAILURE;
     771           0 :                 goto out;
     772             :         }
     773             : 
     774             :         /* samr gives out nthash unencrypted (!) */
     775          46 :         memcpy(md4pw->hash, info->info18.nt_pwd.hash, 16);
     776             : 
     777          46 :         sid_compose(sid, domain_sid, user_rid);
     778             : 
     779          50 :  out:
     780          50 :         if (h && is_valid_policy_hnd(&user_handle)) {
     781          46 :                 dcerpc_samr_Close(h, mem_ctx, &user_handle, &result);
     782             :         }
     783             : 
     784          50 :         talloc_free(mem_ctx);
     785             : 
     786          50 :         return status;
     787             : }
     788             : 
     789             : /*************************************************************************
     790             :  _netr_ServerReqChallenge
     791             :  *************************************************************************/
     792             : 
     793         595 : NTSTATUS _netr_ServerReqChallenge(struct pipes_struct *p,
     794             :                                   struct netr_ServerReqChallenge *r)
     795             : {
     796         595 :         struct netlogon_server_pipe_state *pipe_state =
     797         595 :                 talloc_get_type(p->private_data, struct netlogon_server_pipe_state);
     798             : 
     799         595 :         if (pipe_state) {
     800         565 :                 DEBUG(10,("_netr_ServerReqChallenge: new challenge requested. Clearing old state.\n"));
     801         565 :                 talloc_free(pipe_state);
     802         565 :                 p->private_data = NULL;
     803             :         }
     804             : 
     805         595 :         pipe_state = talloc(p, struct netlogon_server_pipe_state);
     806         595 :         NT_STATUS_HAVE_NO_MEMORY(pipe_state);
     807             : 
     808         595 :         pipe_state->client_challenge = *r->in.credentials;
     809             : 
     810         595 :         netlogon_creds_random_challenge(&pipe_state->server_challenge);
     811             : 
     812         595 :         *r->out.return_credentials = pipe_state->server_challenge;
     813             : 
     814         595 :         p->private_data = pipe_state;
     815             : 
     816         595 :         return NT_STATUS_OK;
     817             : }
     818             : 
     819             : /*************************************************************************
     820             :  _netr_ServerAuthenticate
     821             :  Create the initial credentials.
     822             :  *************************************************************************/
     823             : 
     824           0 : NTSTATUS _netr_ServerAuthenticate(struct pipes_struct *p,
     825             :                                   struct netr_ServerAuthenticate *r)
     826             : {
     827             :         struct netr_ServerAuthenticate3 a;
     828           0 :         uint32_t negotiate_flags = 0;
     829             :         uint32_t rid;
     830             : 
     831           0 :         a.in.server_name                = r->in.server_name;
     832           0 :         a.in.account_name               = r->in.account_name;
     833           0 :         a.in.secure_channel_type        = r->in.secure_channel_type;
     834           0 :         a.in.computer_name              = r->in.computer_name;
     835           0 :         a.in.credentials                = r->in.credentials;
     836           0 :         a.in.negotiate_flags            = &negotiate_flags;
     837             : 
     838           0 :         a.out.return_credentials        = r->out.return_credentials;
     839           0 :         a.out.rid                       = &rid;
     840           0 :         a.out.negotiate_flags           = &negotiate_flags;
     841             : 
     842           0 :         return _netr_ServerAuthenticate3(p, &a);
     843             : 
     844             : }
     845             : 
     846             : /*************************************************************************
     847             :  _netr_ServerAuthenticate3
     848             :  *************************************************************************/
     849             : 
     850          50 : NTSTATUS _netr_ServerAuthenticate3(struct pipes_struct *p,
     851             :                                    struct netr_ServerAuthenticate3 *r)
     852             : {
     853             :         NTSTATUS status;
     854             :         uint32_t srv_flgs;
     855             :         /* r->in.negotiate_flags is an aliased pointer to r->out.negotiate_flags,
     856             :          * so use a copy to avoid destroying the client values. */
     857          50 :         uint32_t in_neg_flags = *r->in.negotiate_flags;
     858             :         const char *fn;
     859             :         struct loadparm_context *lp_ctx;
     860             :         struct dom_sid sid;
     861             :         struct samr_Password mach_pwd;
     862             :         struct netlogon_creds_CredentialState *creds;
     863          50 :         struct netlogon_server_pipe_state *pipe_state =
     864          50 :                 talloc_get_type(p->private_data, struct netlogon_server_pipe_state);
     865             : 
     866             :         /* According to Microsoft (see bugid #6099)
     867             :          * Windows 7 looks at the negotiate_flags
     868             :          * returned in this structure *even if the
     869             :          * call fails with access denied* ! So in order
     870             :          * to allow Win7 to connect to a Samba NT style
     871             :          * PDC we set the flags before we know if it's
     872             :          * an error or not.
     873             :          */
     874             : 
     875             :         /* 0x000001ff */
     876          50 :         srv_flgs = NETLOGON_NEG_ACCOUNT_LOCKOUT |
     877             :                    NETLOGON_NEG_PERSISTENT_SAMREPL |
     878             :                    NETLOGON_NEG_ARCFOUR |
     879             :                    NETLOGON_NEG_PROMOTION_COUNT |
     880             :                    NETLOGON_NEG_CHANGELOG_BDC |
     881             :                    NETLOGON_NEG_FULL_SYNC_REPL |
     882             :                    NETLOGON_NEG_MULTIPLE_SIDS |
     883             :                    NETLOGON_NEG_REDO |
     884             :                    NETLOGON_NEG_PASSWORD_CHANGE_REFUSAL |
     885             :                    NETLOGON_NEG_PASSWORD_SET2;
     886             : 
     887             :         /* Ensure we support strong (128-bit) keys. */
     888          50 :         if (in_neg_flags & NETLOGON_NEG_STRONG_KEYS) {
     889          50 :                 srv_flgs |= NETLOGON_NEG_STRONG_KEYS;
     890             :         }
     891             : 
     892          50 :         if (in_neg_flags & NETLOGON_NEG_SUPPORTS_AES) {
     893          25 :                 srv_flgs |= NETLOGON_NEG_SUPPORTS_AES;
     894             :         }
     895             : 
     896          50 :         if (in_neg_flags & NETLOGON_NEG_SCHANNEL) {
     897          50 :                 srv_flgs |= NETLOGON_NEG_SCHANNEL;
     898             :         }
     899             : 
     900             :         /*
     901             :          * Support authenticaten of trusted domains.
     902             :          *
     903             :          * These flags are the minimum required set which works with win2k3
     904             :          * and win2k8.
     905             :          */
     906          50 :         if (pdb_capabilities() & PDB_CAP_TRUSTED_DOMAINS_EX) {
     907           0 :                 srv_flgs |= NETLOGON_NEG_TRANSITIVE_TRUSTS |
     908             :                             NETLOGON_NEG_DNS_DOMAIN_TRUSTS |
     909             :                             NETLOGON_NEG_CROSS_FOREST_TRUSTS |
     910             :                             NETLOGON_NEG_NEUTRALIZE_NT4_EMULATION;
     911             :         }
     912             : 
     913             :         /*
     914             :          * If weak cryto is disabled, do not announce that we support RC4.
     915             :          */
     916          50 :         if (lp_weak_crypto() == SAMBA_WEAK_CRYPTO_DISALLOWED) {
     917           0 :                 srv_flgs &= ~NETLOGON_NEG_ARCFOUR;
     918             :         }
     919             : 
     920          50 :         switch (p->opnum) {
     921           0 :                 case NDR_NETR_SERVERAUTHENTICATE:
     922           0 :                         fn = "_netr_ServerAuthenticate";
     923           0 :                         break;
     924          42 :                 case NDR_NETR_SERVERAUTHENTICATE2:
     925          42 :                         fn = "_netr_ServerAuthenticate2";
     926          42 :                         break;
     927           8 :                 case NDR_NETR_SERVERAUTHENTICATE3:
     928           8 :                         fn = "_netr_ServerAuthenticate3";
     929           8 :                         break;
     930           0 :                 default:
     931           0 :                         return NT_STATUS_INTERNAL_ERROR;
     932             :         }
     933             : 
     934             :         /* We use this as the key to store the creds: */
     935             :         /* r->in.computer_name */
     936             : 
     937          50 :         if (!pipe_state) {
     938           0 :                 DEBUG(0,("%s: no challenge sent to client %s\n", fn,
     939             :                         r->in.computer_name));
     940           0 :                 status = NT_STATUS_ACCESS_DENIED;
     941           0 :                 goto out;
     942             :         }
     943             : 
     944          50 :         status = get_md4pw(&mach_pwd,
     945             :                            r->in.account_name,
     946             :                            r->in.secure_channel_type,
     947             :                            &sid, p->msg_ctx);
     948          50 :         if (!NT_STATUS_IS_OK(status)) {
     949           4 :                 DEBUG(0,("%s: failed to get machine password for "
     950             :                         "account %s: %s\n",
     951             :                         fn, r->in.account_name, nt_errstr(status) ));
     952             :                 /* always return NT_STATUS_ACCESS_DENIED */
     953           4 :                 status = NT_STATUS_ACCESS_DENIED;
     954           4 :                 goto out;
     955             :         }
     956             : 
     957             :         /* From the client / server challenges and md4 password, generate sess key */
     958             :         /* Check client credentials are valid. */
     959          92 :         creds = netlogon_creds_server_init(p->mem_ctx,
     960             :                                            r->in.account_name,
     961             :                                            r->in.computer_name,
     962          46 :                                            r->in.secure_channel_type,
     963          46 :                                            &pipe_state->client_challenge,
     964          46 :                                            &pipe_state->server_challenge,
     965             :                                            &mach_pwd,
     966          46 :                                            r->in.credentials,
     967             :                                            r->out.return_credentials,
     968             :                                            srv_flgs);
     969          46 :         if (!creds) {
     970           4 :                 DEBUG(0,("%s: netlogon_creds_server_check failed. Rejecting auth "
     971             :                         "request from client %s machine account %s\n",
     972             :                         fn, r->in.computer_name,
     973             :                         r->in.account_name));
     974           4 :                 status = NT_STATUS_ACCESS_DENIED;
     975           4 :                 goto out;
     976             :         }
     977             : 
     978          42 :         creds->sid = dom_sid_dup(creds, &sid);
     979          42 :         if (!creds->sid) {
     980           0 :                 status = NT_STATUS_NO_MEMORY;
     981           0 :                 goto out;
     982             :         }
     983             : 
     984          42 :         lp_ctx = loadparm_init_s3(p->mem_ctx, loadparm_s3_helpers());
     985          42 :         if (lp_ctx == NULL) {
     986           0 :                 DEBUG(10, ("loadparm_init_s3 failed\n"));
     987           0 :                 status = NT_STATUS_INTERNAL_ERROR;
     988           0 :                 goto out;
     989             :         }
     990             : 
     991             :         /* Store off the state so we can continue after client disconnect. */
     992          42 :         become_root();
     993          42 :         status = schannel_save_creds_state(p->mem_ctx, lp_ctx, creds);
     994          42 :         unbecome_root();
     995             : 
     996          42 :         talloc_unlink(p->mem_ctx, lp_ctx);
     997             : 
     998          42 :         if (!NT_STATUS_IS_OK(status)) {
     999           0 :                 ZERO_STRUCTP(r->out.return_credentials);
    1000           0 :                 goto out;
    1001             :         }
    1002             : 
    1003          42 :         sid_peek_rid(&sid, r->out.rid);
    1004             : 
    1005          42 :         status = NT_STATUS_OK;
    1006             : 
    1007          50 :   out:
    1008             : 
    1009          50 :         *r->out.negotiate_flags = srv_flgs;
    1010          50 :         return status;
    1011             : }
    1012             : 
    1013             : /*************************************************************************
    1014             :  _netr_ServerAuthenticate2
    1015             :  *************************************************************************/
    1016             : 
    1017          42 : NTSTATUS _netr_ServerAuthenticate2(struct pipes_struct *p,
    1018             :                                    struct netr_ServerAuthenticate2 *r)
    1019             : {
    1020             :         struct netr_ServerAuthenticate3 a;
    1021             :         uint32_t rid;
    1022             : 
    1023          42 :         a.in.server_name                = r->in.server_name;
    1024          42 :         a.in.account_name               = r->in.account_name;
    1025          42 :         a.in.secure_channel_type        = r->in.secure_channel_type;
    1026          42 :         a.in.computer_name              = r->in.computer_name;
    1027          42 :         a.in.credentials                = r->in.credentials;
    1028          42 :         a.in.negotiate_flags            = r->in.negotiate_flags;
    1029             : 
    1030          42 :         a.out.return_credentials        = r->out.return_credentials;
    1031          42 :         a.out.rid                       = &rid;
    1032          42 :         a.out.negotiate_flags           = r->out.negotiate_flags;
    1033             : 
    1034          42 :         return _netr_ServerAuthenticate3(p, &a);
    1035             : }
    1036             : 
    1037             : /*************************************************************************
    1038             :  *************************************************************************/
    1039             : 
    1040         273 : static NTSTATUS netr_creds_server_step_check(struct pipes_struct *p,
    1041             :                                              TALLOC_CTX *mem_ctx,
    1042             :                                              const char *computer_name,
    1043             :                                              struct netr_Authenticator *received_authenticator,
    1044             :                                              struct netr_Authenticator *return_authenticator,
    1045             :                                              struct netlogon_creds_CredentialState **creds_out)
    1046             : {
    1047             :         NTSTATUS status;
    1048         273 :         bool schannel_global_required = (lp_server_schannel() == true) ? true:false;
    1049         273 :         bool schannel_required = schannel_global_required;
    1050         273 :         const char *explicit_opt = NULL;
    1051             :         struct loadparm_context *lp_ctx;
    1052         273 :         struct netlogon_creds_CredentialState *creds = NULL;
    1053         273 :         enum dcerpc_AuthType auth_type = DCERPC_AUTH_TYPE_NONE;
    1054         273 :         uint16_t opnum = p->opnum;
    1055         273 :         const char *opname = "<unknown>";
    1056             :         static bool warned_global_once = false;
    1057             : 
    1058         273 :         if (creds_out != NULL) {
    1059         273 :                 *creds_out = NULL;
    1060             :         }
    1061             : 
    1062         273 :         if (opnum < ndr_table_netlogon.num_calls) {
    1063         273 :                 opname = ndr_table_netlogon.calls[opnum].name;
    1064             :         }
    1065             : 
    1066         273 :         auth_type = p->auth.auth_type;
    1067             : 
    1068         273 :         lp_ctx = loadparm_init_s3(mem_ctx, loadparm_s3_helpers());
    1069         273 :         if (lp_ctx == NULL) {
    1070           0 :                 DEBUG(0, ("loadparm_init_s3 failed\n"));
    1071           0 :                 return NT_STATUS_INTERNAL_ERROR;
    1072             :         }
    1073             : 
    1074         273 :         status = schannel_check_creds_state(mem_ctx, lp_ctx,
    1075             :                                             computer_name, received_authenticator,
    1076             :                                             return_authenticator, &creds);
    1077         273 :         talloc_unlink(mem_ctx, lp_ctx);
    1078             : 
    1079         273 :         if (!NT_STATUS_IS_OK(status)) {
    1080           0 :                 ZERO_STRUCTP(return_authenticator);
    1081           0 :                 return status;
    1082             :         }
    1083             : 
    1084             :         /*
    1085             :          * We don't use lp_parm_bool(), as we
    1086             :          * need the explicit_opt pointer in order to
    1087             :          * adjust the debug messages.
    1088             :          */
    1089             : 
    1090         273 :         explicit_opt = lp_parm_const_string(GLOBAL_SECTION_SNUM,
    1091             :                                             "server require schannel",
    1092         273 :                                             creds->account_name,
    1093             :                                             NULL);
    1094         273 :         if (explicit_opt != NULL) {
    1095           0 :                 schannel_required = lp_bool(explicit_opt);
    1096             :         }
    1097             : 
    1098         273 :         if (schannel_required) {
    1099           0 :                 if (auth_type == DCERPC_AUTH_TYPE_SCHANNEL) {
    1100           0 :                         *creds_out = creds;
    1101           0 :                         return NT_STATUS_OK;
    1102             :                 }
    1103             : 
    1104           0 :                 DBG_ERR("CVE-2020-1472(ZeroLogon): "
    1105             :                         "%s request (opnum[%u]) without schannel from "
    1106             :                         "client_account[%s] client_computer_name[%s]\n",
    1107             :                         opname, opnum,
    1108             :                         log_escape(mem_ctx, creds->account_name),
    1109             :                         log_escape(mem_ctx, creds->computer_name));
    1110           0 :                 DBG_ERR("CVE-2020-1472(ZeroLogon): Check if option "
    1111             :                         "'server require schannel:%s = no' is needed! \n",
    1112             :                         log_escape(mem_ctx, creds->account_name));
    1113           0 :                 TALLOC_FREE(creds);
    1114           0 :                 ZERO_STRUCTP(return_authenticator);
    1115           0 :                 return NT_STATUS_ACCESS_DENIED;
    1116             :         }
    1117             : 
    1118         273 :         if (!schannel_global_required && !warned_global_once) {
    1119             :                 /*
    1120             :                  * We want admins to notice their misconfiguration!
    1121             :                  */
    1122          26 :                 DBG_ERR("CVE-2020-1472(ZeroLogon): "
    1123             :                         "Please configure 'server schannel = yes', "
    1124             :                         "See https://bugzilla.samba.org/show_bug.cgi?id=14497\n");
    1125          26 :                 warned_global_once = true;
    1126             :         }
    1127             : 
    1128         273 :         if (auth_type == DCERPC_AUTH_TYPE_SCHANNEL) {
    1129         225 :                 DBG_ERR("CVE-2020-1472(ZeroLogon): "
    1130             :                         "%s request (opnum[%u]) WITH schannel from "
    1131             :                         "client_account[%s] client_computer_name[%s]\n",
    1132             :                         opname, opnum,
    1133             :                         log_escape(mem_ctx, creds->account_name),
    1134             :                         log_escape(mem_ctx, creds->computer_name));
    1135         225 :                 DBG_ERR("CVE-2020-1472(ZeroLogon): "
    1136             :                         "Option 'server require schannel:%s = no' not needed!?\n",
    1137             :                         log_escape(mem_ctx, creds->account_name));
    1138             : 
    1139         225 :                 *creds_out = creds;
    1140         225 :                 return NT_STATUS_OK;
    1141             :         }
    1142             : 
    1143          48 :         if (explicit_opt != NULL) {
    1144           0 :                 DBG_INFO("CVE-2020-1472(ZeroLogon): "
    1145             :                          "%s request (opnum[%u]) without schannel from "
    1146             :                          "client_account[%s] client_computer_name[%s]\n",
    1147             :                          opname, opnum,
    1148             :                          log_escape(mem_ctx, creds->account_name),
    1149             :                          log_escape(mem_ctx, creds->computer_name));
    1150           0 :                 DBG_INFO("CVE-2020-1472(ZeroLogon): "
    1151             :                          "Option 'server require schannel:%s = no' still needed!\n",
    1152             :                          log_escape(mem_ctx, creds->account_name));
    1153             :         } else {
    1154          48 :                 DBG_ERR("CVE-2020-1472(ZeroLogon): "
    1155             :                         "%s request (opnum[%u]) without schannel from "
    1156             :                         "client_account[%s] client_computer_name[%s]\n",
    1157             :                         opname, opnum,
    1158             :                         log_escape(mem_ctx, creds->account_name),
    1159             :                         log_escape(mem_ctx, creds->computer_name));
    1160          48 :                 DBG_ERR("CVE-2020-1472(ZeroLogon): Check if option "
    1161             :                         "'server require schannel:%s = no' might be needed!\n",
    1162             :                         log_escape(mem_ctx, creds->account_name));
    1163             :         }
    1164             : 
    1165          48 :         *creds_out = creds;
    1166          48 :         return NT_STATUS_OK;
    1167             : }
    1168             : 
    1169             : 
    1170             : /*************************************************************************
    1171             :  *************************************************************************/
    1172             : 
    1173           8 : static NTSTATUS samr_open_machine_account(
    1174             :         struct dcerpc_binding_handle *b,
    1175             :         const struct dom_sid *machine_sid,
    1176             :         uint32_t access_mask,
    1177             :         struct policy_handle *machine_handle)
    1178             : {
    1179           8 :         TALLOC_CTX *frame = talloc_stackframe();
    1180           8 :         struct policy_handle connect_handle = { .handle_type = 0 };
    1181           8 :         struct policy_handle domain_handle = { .handle_type = 0 };
    1182           8 :         struct dom_sid domain_sid = *machine_sid;
    1183             :         uint32_t machine_rid;
    1184           8 :         NTSTATUS result = NT_STATUS_OK;
    1185           8 :         NTSTATUS status = NT_STATUS_INVALID_PARAMETER;
    1186             :         bool ok;
    1187             : 
    1188           8 :         ok = sid_split_rid(&domain_sid, &machine_rid);
    1189           8 :         if (!ok) {
    1190           0 :                 goto out;
    1191             :         }
    1192             : 
    1193           8 :         status = dcerpc_samr_Connect2(
    1194             :                 b,
    1195             :                 frame,
    1196             :                 lp_netbios_name(),
    1197             :                 SAMR_ACCESS_CONNECT_TO_SERVER |
    1198             :                 SAMR_ACCESS_ENUM_DOMAINS |
    1199             :                 SAMR_ACCESS_LOOKUP_DOMAIN,
    1200             :                 &connect_handle,
    1201             :                 &result);
    1202           8 :         if (any_nt_status_not_ok(status, result, &status)) {
    1203           0 :                 goto out;
    1204             :         }
    1205             : 
    1206           8 :         status = dcerpc_samr_OpenDomain(
    1207             :                 b,
    1208             :                 frame,
    1209             :                 &connect_handle,
    1210             :                 SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT,
    1211             :                 &domain_sid,
    1212             :                 &domain_handle,
    1213             :                 &result);
    1214           8 :         if (any_nt_status_not_ok(status, result, &status)) {
    1215           0 :                 goto out;
    1216             :         }
    1217             : 
    1218           8 :         status = dcerpc_samr_OpenUser(
    1219             :                 b,
    1220             :                 frame,
    1221             :                 &domain_handle,
    1222             :                 SEC_FLAG_MAXIMUM_ALLOWED,
    1223             :                 machine_rid,
    1224             :                 machine_handle,
    1225             :                 &result);
    1226           8 :         if (any_nt_status_not_ok(status, result, &status)) {
    1227           0 :                 goto out;
    1228             :         }
    1229             : 
    1230          16 : out:
    1231           8 :         if ((b != NULL) && is_valid_policy_hnd(&domain_handle)) {
    1232           8 :                 dcerpc_samr_Close(b, frame, &domain_handle, &result);
    1233             :         }
    1234           8 :         if ((b != NULL) && is_valid_policy_hnd(&connect_handle)) {
    1235           8 :                 dcerpc_samr_Close(b, frame, &connect_handle, &result);
    1236             :         }
    1237           8 :         TALLOC_FREE(frame);
    1238           8 :         return status;
    1239             : }
    1240             : 
    1241             : struct _samr_Credentials_t {
    1242             :         enum {
    1243             :                 CRED_TYPE_NT_HASH,
    1244             :                 CRED_TYPE_PLAIN_TEXT,
    1245             :         } cred_type;
    1246             :         union {
    1247             :                 struct samr_Password *nt_hash;
    1248             :                 const char *password;
    1249             :         } creds;
    1250             : };
    1251             : 
    1252             : 
    1253           8 : static NTSTATUS netr_set_machine_account_password(
    1254             :         TALLOC_CTX *mem_ctx,
    1255             :         struct auth_session_info *session_info,
    1256             :         struct messaging_context *msg_ctx,
    1257             :         const struct dom_sid *machine_sid,
    1258             :         struct _samr_Credentials_t *cr)
    1259             : {
    1260             :         NTSTATUS status;
    1261           8 :         NTSTATUS result = NT_STATUS_OK;
    1262           8 :         struct dcerpc_binding_handle *h = NULL;
    1263             :         struct tsocket_address *local;
    1264           8 :         struct policy_handle user_handle = { .handle_type = 0 };
    1265             :         uint32_t acct_ctrl;
    1266             :         union samr_UserInfo *info;
    1267             :         struct samr_UserInfo18 info18;
    1268             :         struct samr_UserInfo26 info26;
    1269             :         DATA_BLOB in,out;
    1270             :         int rc;
    1271             :         DATA_BLOB session_key;
    1272             :         enum samr_UserInfoLevel infolevel;
    1273           8 :         TALLOC_CTX *frame = talloc_stackframe();
    1274             : 
    1275           8 :         status = session_extract_session_key(session_info,
    1276             :                                              &session_key,
    1277             :                                              KEY_USE_16BYTES);
    1278           8 :         if (!NT_STATUS_IS_OK(status)) {
    1279           0 :                 goto out;
    1280             :         }
    1281             : 
    1282           8 :         rc = tsocket_address_inet_from_strings(frame,
    1283             :                                                "ip",
    1284             :                                                "127.0.0.1",
    1285             :                                                0,
    1286             :                                                &local);
    1287           8 :         if (rc < 0) {
    1288           0 :                 status = NT_STATUS_NO_MEMORY;
    1289           0 :                 goto out;
    1290             :         }
    1291             : 
    1292           8 :         status = rpcint_binding_handle(frame,
    1293             :                                        &ndr_table_samr,
    1294             :                                        local,
    1295             :                                        NULL,
    1296             :                                        session_info,
    1297             :                                        msg_ctx,
    1298             :                                        &h);
    1299           8 :         if (!NT_STATUS_IS_OK(status)) {
    1300           0 :                 goto out;
    1301             :         }
    1302             : 
    1303           8 :         become_root();
    1304           8 :         status = samr_open_machine_account(
    1305             :                 h, machine_sid, SEC_FLAG_MAXIMUM_ALLOWED, &user_handle);
    1306           8 :         unbecome_root();
    1307           8 :         if (!NT_STATUS_IS_OK(status)) {
    1308           0 :                 goto out;
    1309             :         }
    1310             : 
    1311           8 :         status = dcerpc_samr_QueryUserInfo2(h,
    1312             :                                             frame,
    1313             :                                             &user_handle,
    1314             :                                             UserControlInformation,
    1315             :                                             &info,
    1316             :                                             &result);
    1317           8 :         if (any_nt_status_not_ok(status, result, &status)) {
    1318           0 :                 goto out;
    1319             :         }
    1320             : 
    1321           8 :         acct_ctrl = info->info16.acct_flags;
    1322             : 
    1323           8 :         if (!(acct_ctrl & ACB_WSTRUST ||
    1324           0 :               acct_ctrl & ACB_SVRTRUST ||
    1325           0 :               acct_ctrl & ACB_DOMTRUST)) {
    1326           0 :                 status = NT_STATUS_NO_SUCH_USER;
    1327           0 :                 goto out;
    1328             :         }
    1329             : 
    1330           8 :         if (acct_ctrl & ACB_DISABLED) {
    1331           0 :                 status = NT_STATUS_ACCOUNT_DISABLED;
    1332           0 :                 goto out;
    1333             :         }
    1334             : 
    1335           8 :         switch(cr->cred_type) {
    1336           8 :                 case CRED_TYPE_NT_HASH:
    1337           8 :                         ZERO_STRUCT(info18);
    1338             : 
    1339           8 :                         infolevel = UserInternal1Information;
    1340             : 
    1341           8 :                         in = data_blob_const(cr->creds.nt_hash, 16);
    1342           8 :                         out = data_blob_talloc_zero(frame, 16);
    1343           8 :                         if (out.data == NULL) {
    1344           0 :                                 status = NT_STATUS_NO_MEMORY;
    1345           0 :                                 goto out;
    1346             :                         }
    1347           8 :                         rc = sess_crypt_blob(&out, &in, &session_key, SAMBA_GNUTLS_ENCRYPT);
    1348           8 :                         if (rc != 0) {
    1349           0 :                                 status = gnutls_error_to_ntstatus(rc,
    1350             :                                                                   NT_STATUS_ACCESS_DISABLED_BY_POLICY_OTHER);
    1351           0 :                                 goto out;
    1352             :                         }
    1353           8 :                         memcpy(info18.nt_pwd.hash, out.data, out.length);
    1354             : 
    1355           8 :                         info18.nt_pwd_active = true;
    1356             : 
    1357           8 :                         info->info18 = info18;
    1358           8 :                 break;
    1359           0 :                 case CRED_TYPE_PLAIN_TEXT:
    1360           0 :                         ZERO_STRUCT(info26);
    1361             : 
    1362           0 :                         infolevel = UserInternal5InformationNew;
    1363             : 
    1364           0 :                         status = init_samr_CryptPasswordEx(cr->creds.password,
    1365             :                                                            &session_key,
    1366             :                                                            &info26.password);
    1367           0 :                         if (!NT_STATUS_IS_OK(status)) {
    1368           0 :                                 goto out;
    1369             :                         }
    1370             : 
    1371           0 :                         info26.password_expired = PASS_DONT_CHANGE_AT_NEXT_LOGON;
    1372           0 :                         info->info26 = info26;
    1373           0 :                 break;
    1374           0 :                 default:
    1375           0 :                         status = NT_STATUS_INTERNAL_ERROR;
    1376           0 :                         goto out;
    1377             :                 break;
    1378             :         }
    1379             : 
    1380           8 :         become_root();
    1381           8 :         status = dcerpc_samr_SetUserInfo2(h,
    1382             :                                           frame,
    1383             :                                           &user_handle,
    1384             :                                           infolevel,
    1385             :                                           info,
    1386             :                                           &result);
    1387           8 :         unbecome_root();
    1388           8 :         if (any_nt_status_not_ok(status, result, &status)) {
    1389           0 :                 goto out;
    1390             :         }
    1391             : 
    1392          16 :  out:
    1393           8 :         if (h && is_valid_policy_hnd(&user_handle)) {
    1394           8 :                 dcerpc_samr_Close(h, frame, &user_handle, &result);
    1395             :         }
    1396           8 :         TALLOC_FREE(frame);
    1397             : 
    1398           8 :         return status;
    1399             : }
    1400             : 
    1401             : /*************************************************************************
    1402             :  _netr_ServerPasswordSet
    1403             :  *************************************************************************/
    1404             : 
    1405           8 : NTSTATUS _netr_ServerPasswordSet(struct pipes_struct *p,
    1406             :                                  struct netr_ServerPasswordSet *r)
    1407             : {
    1408           8 :         NTSTATUS status = NT_STATUS_OK;
    1409             :         size_t i;
    1410           8 :         struct netlogon_creds_CredentialState *creds = NULL;
    1411           8 :         struct _samr_Credentials_t cr = { CRED_TYPE_NT_HASH, {0}};
    1412             : 
    1413           8 :         DEBUG(5,("_netr_ServerPasswordSet: %d\n", __LINE__));
    1414             : 
    1415           8 :         become_root();
    1416           8 :         status = netr_creds_server_step_check(p, p->mem_ctx,
    1417             :                                               r->in.computer_name,
    1418             :                                               r->in.credential,
    1419             :                                               r->out.return_authenticator,
    1420             :                                               &creds);
    1421           8 :         unbecome_root();
    1422             : 
    1423           8 :         if (!NT_STATUS_IS_OK(status)) {
    1424           0 :                 const char *computer_name = "<unknown>";
    1425             : 
    1426           0 :                 if (creds != NULL && creds->computer_name != NULL) {
    1427           0 :                         computer_name = creds->computer_name;
    1428             :                 }
    1429           0 :                 DEBUG(2,("_netr_ServerPasswordSet: netlogon_creds_server_step failed. Rejecting auth "
    1430             :                         "request from client %s machine account %s\n",
    1431             :                         r->in.computer_name, computer_name));
    1432           0 :                 TALLOC_FREE(creds);
    1433           0 :                 return status;
    1434             :         }
    1435             : 
    1436           8 :         DEBUG(3,("_netr_ServerPasswordSet: Server Password Set by remote machine:[%s] on account [%s]\n",
    1437             :                         r->in.computer_name, creds->computer_name));
    1438             : 
    1439           8 :         status = netlogon_creds_des_decrypt(creds, r->in.new_password);
    1440           8 :         if (!NT_STATUS_IS_OK(status)) {
    1441           0 :                 return status;
    1442             :         }
    1443             : 
    1444           8 :         DEBUG(100,("_netr_ServerPasswordSet: new given value was :\n"));
    1445         136 :         for(i = 0; i < sizeof(r->in.new_password->hash); i++)
    1446         128 :                 DEBUG(100,("%02X ", r->in.new_password->hash[i]));
    1447           8 :         DEBUG(100,("\n"));
    1448             : 
    1449           8 :         cr.creds.nt_hash = r->in.new_password;
    1450           8 :         status = netr_set_machine_account_password(p->mem_ctx,
    1451             :                                                    p->session_info,
    1452             :                                                    p->msg_ctx,
    1453           8 :                                                    creds->sid,
    1454             :                                                    &cr);
    1455           8 :         return status;
    1456             : }
    1457             : 
    1458             : /****************************************************************
    1459             :  _netr_ServerPasswordSet2
    1460             : ****************************************************************/
    1461             : 
    1462           8 : NTSTATUS _netr_ServerPasswordSet2(struct pipes_struct *p,
    1463             :                                   struct netr_ServerPasswordSet2 *r)
    1464             : {
    1465             :         NTSTATUS status;
    1466           8 :         struct netlogon_creds_CredentialState *creds = NULL;
    1467           8 :         DATA_BLOB plaintext = data_blob_null;
    1468           8 :         DATA_BLOB new_password = data_blob_null;
    1469             :         size_t confounder_len;
    1470           8 :         DATA_BLOB dec_blob = data_blob_null;
    1471           8 :         DATA_BLOB enc_blob = data_blob_null;
    1472             :         struct samr_CryptPassword password_buf;
    1473           8 :         struct _samr_Credentials_t cr = { CRED_TYPE_PLAIN_TEXT, {0}};
    1474             :         bool ok;
    1475             : 
    1476           8 :         become_root();
    1477           8 :         status = netr_creds_server_step_check(p, p->mem_ctx,
    1478             :                                               r->in.computer_name,
    1479             :                                               r->in.credential,
    1480             :                                               r->out.return_authenticator,
    1481             :                                               &creds);
    1482           8 :         unbecome_root();
    1483             : 
    1484           8 :         if (!NT_STATUS_IS_OK(status)) {
    1485           0 :                 const char *computer_name = "<unknown>";
    1486             : 
    1487           0 :                 if (creds && creds->computer_name) {
    1488           0 :                         computer_name = creds->computer_name;
    1489             :                 }
    1490           0 :                 DEBUG(2,("_netr_ServerPasswordSet2: netlogon_creds_server_step "
    1491             :                         "failed. Rejecting auth request from client %s machine account %s\n",
    1492             :                         r->in.computer_name, computer_name));
    1493           0 :                 TALLOC_FREE(creds);
    1494           0 :                 return status;
    1495             :         }
    1496             : 
    1497           8 :         DBG_NOTICE("Server Password Set2 by remote "
    1498             :                    "machine:[%s] on account [%s]\n",
    1499             :                    r->in.computer_name,
    1500             :                    creds->computer_name);
    1501             : 
    1502           8 :         memcpy(password_buf.data, r->in.new_password->data, 512);
    1503           8 :         SIVAL(password_buf.data, 512, r->in.new_password->length);
    1504             : 
    1505           8 :         if (creds->negotiate_flags & NETLOGON_NEG_SUPPORTS_AES) {
    1506           4 :                 status = netlogon_creds_aes_decrypt(creds,
    1507             :                                                     password_buf.data,
    1508             :                                                     516);
    1509             :         } else {
    1510           4 :                 status = netlogon_creds_arcfour_crypt(creds,
    1511             :                                                       password_buf.data,
    1512             :                                                       516);
    1513             :         }
    1514           8 :         if (!NT_STATUS_IS_OK(status)) {
    1515           0 :                 TALLOC_FREE(creds);
    1516           0 :                 return status;
    1517             :         }
    1518             : 
    1519           8 :         if (!extract_pw_from_buffer(p->mem_ctx, password_buf.data, &new_password)) {
    1520           0 :                 DEBUG(2,("_netr_ServerPasswordSet2: unable to extract password "
    1521             :                          "from a buffer. Rejecting auth request as a wrong password\n"));
    1522           0 :                 TALLOC_FREE(creds);
    1523           0 :                 return NT_STATUS_WRONG_PASSWORD;
    1524             :         }
    1525             : 
    1526             :         /*
    1527             :          * Make sure the length field was encrypted,
    1528             :          * otherwise we are under attack.
    1529             :          */
    1530           8 :         if (new_password.length == r->in.new_password->length) {
    1531           1 :                 DBG_WARNING("Length[%zu] field not encrypted\n",
    1532             :                         new_password.length);
    1533           1 :                 TALLOC_FREE(creds);
    1534           1 :                 return NT_STATUS_WRONG_PASSWORD;
    1535             :         }
    1536             : 
    1537             :         /*
    1538             :          * We don't allow empty passwords for machine accounts.
    1539             :          */
    1540           7 :         if (new_password.length < 2) {
    1541           2 :                 DBG_WARNING("Empty password Length[%zu]\n",
    1542             :                         new_password.length);
    1543           2 :                 TALLOC_FREE(creds);
    1544           2 :                 return NT_STATUS_WRONG_PASSWORD;
    1545             :         }
    1546             : 
    1547             :         /*
    1548             :          * Make sure the confounder part of CryptPassword
    1549             :          * buffer was encrypted, otherwise we are under attack.
    1550             :          */
    1551           5 :         confounder_len = 512 - new_password.length;
    1552           5 :         enc_blob = data_blob_const(r->in.new_password->data, confounder_len);
    1553           5 :         dec_blob = data_blob_const(password_buf.data, confounder_len);
    1554           5 :         if (confounder_len > 0 && data_blob_cmp(&dec_blob, &enc_blob) == 0) {
    1555           1 :                 DBG_WARNING("Confounder buffer not encrypted Length[%zu]\n",
    1556             :                             confounder_len);
    1557           1 :                 TALLOC_FREE(creds);
    1558           1 :                 return NT_STATUS_WRONG_PASSWORD;
    1559             :         }
    1560             : 
    1561             :         /*
    1562             :          * Check that the password part was actually encrypted,
    1563             :          * otherwise we are under attack.
    1564             :          */
    1565           4 :         enc_blob = data_blob_const(r->in.new_password->data + confounder_len,
    1566             :                                    new_password.length);
    1567           4 :         dec_blob = data_blob_const(password_buf.data + confounder_len,
    1568             :                                    new_password.length);
    1569           4 :         if (data_blob_cmp(&dec_blob, &enc_blob) == 0) {
    1570           2 :                 DBG_WARNING("Password buffer not encrypted Length[%zu]\n",
    1571             :                             new_password.length);
    1572           2 :                 TALLOC_FREE(creds);
    1573           2 :                 return NT_STATUS_WRONG_PASSWORD;
    1574             :         }
    1575             : 
    1576             :         /*
    1577             :          * don't allow zero buffers
    1578             :          */
    1579           2 :         if (all_zero(new_password.data, new_password.length)) {
    1580           1 :                 DBG_WARNING("Password zero buffer Length[%zu]\n",
    1581             :                             new_password.length);
    1582           1 :                 TALLOC_FREE(creds);
    1583           1 :                 return NT_STATUS_WRONG_PASSWORD;
    1584             :         }
    1585             : 
    1586             :         /* Convert from UTF16 -> plaintext. */
    1587           2 :         ok = convert_string_talloc(p->mem_ctx,
    1588             :                                 CH_UTF16,
    1589             :                                 CH_UNIX,
    1590           1 :                                 new_password.data,
    1591             :                                 new_password.length,
    1592             :                                 (void *)&plaintext.data,
    1593             :                                 &plaintext.length);
    1594           1 :         if (!ok) {
    1595           1 :                 DBG_WARNING("unable to extract password from a buffer. "
    1596             :                             "Rejecting auth request as a wrong password\n");
    1597           1 :                 TALLOC_FREE(creds);
    1598           1 :                 return NT_STATUS_WRONG_PASSWORD;
    1599             :         }
    1600             : 
    1601             :         /*
    1602             :          * We don't allow empty passwords for machine accounts.
    1603             :          */
    1604             : 
    1605           0 :         cr.creds.password = (const char*) plaintext.data;
    1606           0 :         if (strlen(cr.creds.password) == 0) {
    1607           0 :                 DBG_WARNING("Empty plaintext password\n");
    1608           0 :                 TALLOC_FREE(creds);
    1609           0 :                 return NT_STATUS_WRONG_PASSWORD;
    1610             :         }
    1611             : 
    1612           0 :         status = netr_set_machine_account_password(p->mem_ctx,
    1613             :                                                    p->session_info,
    1614             :                                                    p->msg_ctx,
    1615           0 :                                                    creds->sid,
    1616             :                                                    &cr);
    1617           0 :         TALLOC_FREE(creds);
    1618           0 :         return status;
    1619             : }
    1620             : 
    1621             : /*************************************************************************
    1622             :  _netr_LogonSamLogoff
    1623             :  *************************************************************************/
    1624             : 
    1625           0 : NTSTATUS _netr_LogonSamLogoff(struct pipes_struct *p,
    1626             :                               struct netr_LogonSamLogoff *r)
    1627             : {
    1628             :         NTSTATUS status;
    1629             :         struct netlogon_creds_CredentialState *creds;
    1630             : 
    1631           0 :         become_root();
    1632           0 :         status = netr_creds_server_step_check(p, p->mem_ctx,
    1633             :                                               r->in.computer_name,
    1634             :                                               r->in.credential,
    1635             :                                               r->out.return_authenticator,
    1636             :                                               &creds);
    1637           0 :         unbecome_root();
    1638             : 
    1639           0 :         return status;
    1640             : }
    1641             : 
    1642        1023 : static NTSTATUS _netr_LogonSamLogon_check(const struct netr_LogonSamLogonEx *r)
    1643             : {
    1644        1023 :         switch (r->in.logon_level) {
    1645         124 :         case NetlogonInteractiveInformation:
    1646             :         case NetlogonServiceInformation:
    1647             :         case NetlogonInteractiveTransitiveInformation:
    1648             :         case NetlogonServiceTransitiveInformation:
    1649         124 :                 if (r->in.logon->password == NULL) {
    1650           0 :                         return NT_STATUS_INVALID_PARAMETER;
    1651             :                 }
    1652             : 
    1653         124 :                 switch (r->in.validation_level) {
    1654          70 :                 case NetlogonValidationSamInfo:  /* 2 */
    1655             :                 case NetlogonValidationSamInfo2: /* 3 */
    1656          70 :                         break;
    1657          54 :                 case NetlogonValidationSamInfo4: /* 6 */
    1658          54 :                         if ((pdb_capabilities() & PDB_CAP_ADS) == 0) {
    1659          54 :                                 DEBUG(10,("Not adding validation info level 6 "
    1660             :                                    "without ADS passdb backend\n"));
    1661          54 :                                 return NT_STATUS_INVALID_INFO_CLASS;
    1662             :                         }
    1663           0 :                         break;
    1664           0 :                 default:
    1665           0 :                         return NT_STATUS_INVALID_INFO_CLASS;
    1666             :                 }
    1667             : 
    1668          70 :                 break;
    1669         771 :         case NetlogonNetworkInformation:
    1670             :         case NetlogonNetworkTransitiveInformation:
    1671         771 :                 if (r->in.logon->network == NULL) {
    1672           0 :                         return NT_STATUS_INVALID_PARAMETER;
    1673             :                 }
    1674             : 
    1675         771 :                 switch (r->in.validation_level) {
    1676         496 :                 case NetlogonValidationSamInfo:  /* 2 */
    1677             :                 case NetlogonValidationSamInfo2: /* 3 */
    1678         496 :                         break;
    1679         243 :                 case NetlogonValidationSamInfo4: /* 6 */
    1680         243 :                         if ((pdb_capabilities() & PDB_CAP_ADS) == 0) {
    1681         243 :                                 DEBUG(10,("Not adding validation info level 6 "
    1682             :                                    "without ADS passdb backend\n"));
    1683         243 :                                 return NT_STATUS_INVALID_INFO_CLASS;
    1684             :                         }
    1685           0 :                         break;
    1686          32 :                 default:
    1687          32 :                         return NT_STATUS_INVALID_INFO_CLASS;
    1688             :                 }
    1689             : 
    1690         496 :                 break;
    1691             : 
    1692           0 :         case NetlogonGenericInformation:
    1693           0 :                 if (r->in.logon->generic == NULL) {
    1694           0 :                         return NT_STATUS_INVALID_PARAMETER;
    1695             :                 }
    1696             : 
    1697             :                 /* we don't support this here */
    1698           0 :                 return NT_STATUS_INVALID_PARAMETER;
    1699             : #if 0
    1700             :                 switch (r->in.validation_level) {
    1701             :                 /* TODO: case NetlogonValidationGenericInfo: 4 */
    1702             :                 case NetlogonValidationGenericInfo2: /* 5 */
    1703             :                         break;
    1704             :                 default:
    1705             :                         return NT_STATUS_INVALID_INFO_CLASS;
    1706             :                 }
    1707             : 
    1708             :                 break;
    1709             : #endif
    1710         128 :         default:
    1711         128 :                 return NT_STATUS_INVALID_PARAMETER;
    1712             :         }
    1713             : 
    1714         566 :         return NT_STATUS_OK;
    1715             : }
    1716             : 
    1717             : /*************************************************************************
    1718             :  _netr_LogonSamLogon_base
    1719             :  *************************************************************************/
    1720             : 
    1721         558 : static NTSTATUS _netr_LogonSamLogon_base(struct pipes_struct *p,
    1722             :                                          struct netr_LogonSamLogonEx *r,
    1723             :                                          struct netlogon_creds_CredentialState *creds)
    1724             : {
    1725         558 :         NTSTATUS status = NT_STATUS_OK;
    1726         558 :         union netr_LogonLevel *logon = r->in.logon;
    1727             :         const char *nt_username, *nt_domain, *nt_workstation;
    1728         558 :         char *sanitized_username = NULL;
    1729         558 :         struct auth_usersupplied_info *user_info = NULL;
    1730         558 :         struct auth_serversupplied_info *server_info = NULL;
    1731         558 :         struct auth_context *auth_context = NULL;
    1732             :         const char *fn;
    1733             : 
    1734             : #ifdef DEBUG_PASSWORD
    1735         558 :         logon = netlogon_creds_shallow_copy_logon(p->mem_ctx,
    1736             :                                                   r->in.logon_level,
    1737         558 :                                                   r->in.logon);
    1738         558 :         if (logon == NULL) {
    1739           0 :                 logon = r->in.logon;
    1740             :         }
    1741             : #endif
    1742             : 
    1743         558 :         switch (p->opnum) {
    1744         224 :                 case NDR_NETR_LOGONSAMLOGON:
    1745         224 :                         fn = "_netr_LogonSamLogon";
    1746         224 :                         break;
    1747           0 :                 case NDR_NETR_LOGONSAMLOGONWITHFLAGS:
    1748           0 :                         fn = "_netr_LogonSamLogonWithFlags";
    1749           0 :                         break;
    1750         334 :                 case NDR_NETR_LOGONSAMLOGONEX:
    1751         334 :                         fn = "_netr_LogonSamLogonEx";
    1752         334 :                         break;
    1753           0 :                 default:
    1754           0 :                         return NT_STATUS_INTERNAL_ERROR;
    1755             :         }
    1756             : 
    1757         558 :         *r->out.authoritative = 1; /* authoritative response */
    1758             : 
    1759         558 :         switch (r->in.validation_level) {
    1760         136 :         case 2:
    1761         136 :                 r->out.validation->sam2 = talloc_zero(p->mem_ctx, struct netr_SamInfo2);
    1762         136 :                 if (!r->out.validation->sam2) {
    1763           0 :                         return NT_STATUS_NO_MEMORY;
    1764             :                 }
    1765         136 :                 break;
    1766         422 :         case 3:
    1767         422 :                 r->out.validation->sam3 = talloc_zero(p->mem_ctx, struct netr_SamInfo3);
    1768         422 :                 if (!r->out.validation->sam3) {
    1769           0 :                         return NT_STATUS_NO_MEMORY;
    1770             :                 }
    1771         422 :                 break;
    1772           0 :         case 6:
    1773           0 :                 r->out.validation->sam6 = talloc_zero(p->mem_ctx, struct netr_SamInfo6);
    1774           0 :                 if (!r->out.validation->sam6) {
    1775           0 :                         return NT_STATUS_NO_MEMORY;
    1776             :                 }
    1777           0 :                 break;
    1778           0 :         default:
    1779           0 :                 DEBUG(0,("%s: bad validation_level value %d.\n",
    1780             :                         fn, (int)r->in.validation_level));
    1781           0 :                 return NT_STATUS_INVALID_INFO_CLASS;
    1782             :         }
    1783             : 
    1784         558 :         switch (r->in.logon_level) {
    1785          70 :         case NetlogonInteractiveInformation:
    1786             :         case NetlogonServiceInformation:
    1787             :         case NetlogonInteractiveTransitiveInformation:
    1788             :         case NetlogonServiceTransitiveInformation:
    1789         140 :                 nt_username     = logon->password->identity_info.account_name.string ?
    1790          70 :                                   logon->password->identity_info.account_name.string : "";
    1791         140 :                 nt_domain       = logon->password->identity_info.domain_name.string ?
    1792          70 :                                   logon->password->identity_info.domain_name.string : "";
    1793         140 :                 nt_workstation  = logon->password->identity_info.workstation.string ?
    1794          70 :                                   logon->password->identity_info.workstation.string : "";
    1795             : 
    1796          70 :                 DEBUG(3,("SAM Logon (Interactive). Domain:[%s].  ", lp_workgroup()));
    1797          70 :                 break;
    1798         488 :         case NetlogonNetworkInformation:
    1799             :         case NetlogonNetworkTransitiveInformation:
    1800         976 :                 nt_username     = logon->network->identity_info.account_name.string ?
    1801         488 :                                   logon->network->identity_info.account_name.string : "";
    1802         976 :                 nt_domain       = logon->network->identity_info.domain_name.string ?
    1803         488 :                                   logon->network->identity_info.domain_name.string : "";
    1804         976 :                 nt_workstation  = logon->network->identity_info.workstation.string ?
    1805         488 :                                   logon->network->identity_info.workstation.string : "";
    1806             : 
    1807         488 :                 DEBUG(3,("SAM Logon (Network). Domain:[%s].  ", lp_workgroup()));
    1808         488 :                 break;
    1809           0 :         default:
    1810           0 :                 DEBUG(2,("SAM Logon: unsupported switch value\n"));
    1811           0 :                 return NT_STATUS_INVALID_INFO_CLASS;
    1812             :         } /* end switch */
    1813             : 
    1814         558 :         DEBUG(3,("User:[%s@%s] Requested Domain:[%s]\n", nt_username, nt_workstation, nt_domain));
    1815             : 
    1816         558 :         DEBUG(5,("Attempting validation level %d for unmapped username %s.\n",
    1817             :                 r->in.validation_level, nt_username));
    1818             : 
    1819         558 :         status = netlogon_creds_decrypt_samlogon_logon(creds,
    1820             :                                                        r->in.logon_level,
    1821             :                                                        logon);
    1822         558 :         if (!NT_STATUS_IS_OK(status)) {
    1823           0 :                 return status;
    1824             :         }
    1825             : 
    1826         558 :         status = make_auth3_context_for_netlogon(talloc_tos(), &auth_context);
    1827         558 :         if (!NT_STATUS_IS_OK(status)) {
    1828           0 :                 return status;
    1829             :         }
    1830             : 
    1831         558 :         switch (r->in.logon_level) {
    1832         488 :         case NetlogonNetworkInformation:
    1833             :         case NetlogonNetworkTransitiveInformation:
    1834             :         {
    1835         488 :                 const char *wksname = nt_workstation;
    1836         488 :                 const char *workgroup = lp_workgroup();
    1837             :                 bool ok;
    1838             : 
    1839         488 :                 ok = auth3_context_set_challenge(
    1840         488 :                         auth_context, logon->network->challenge, "fixed");
    1841         488 :                 if (!ok) {
    1842           0 :                         return NT_STATUS_NO_MEMORY;
    1843             :                 }
    1844             : 
    1845             :                 /* For a network logon, the workstation name comes in with two
    1846             :                  * backslashes in the front. Strip them if they are there. */
    1847             : 
    1848         488 :                 if (*wksname == '\\') wksname++;
    1849         488 :                 if (*wksname == '\\') wksname++;
    1850             : 
    1851             :                 /* Standard challenge/response authentication */
    1852        1464 :                 if (!make_user_info_netlogon_network(talloc_tos(),
    1853             :                                                      &user_info,
    1854             :                                                      nt_username, nt_domain,
    1855             :                                                      wksname,
    1856             :                                                      p->remote_address,
    1857             :                                                      p->local_address,
    1858         488 :                                                      logon->network->identity_info.parameter_control,
    1859         488 :                                                      logon->network->lm.data,
    1860         488 :                                                      logon->network->lm.length,
    1861         488 :                                                      logon->network->nt.data,
    1862         488 :                                                      logon->network->nt.length)) {
    1863           0 :                         status = NT_STATUS_NO_MEMORY;
    1864             :                 }
    1865             : 
    1866         488 :                 if (NT_STATUS_IS_OK(status)) {
    1867         976 :                         status = NTLMv2_RESPONSE_verify_netlogon_creds(
    1868         488 :                                                 user_info->client.account_name,
    1869         488 :                                                 user_info->client.domain_name,
    1870         488 :                                                 user_info->password.response.nt,
    1871             :                                                 creds, workgroup);
    1872             :                 }
    1873         488 :                 break;
    1874             :         }
    1875          70 :         case NetlogonInteractiveInformation:
    1876             :         case NetlogonServiceInformation:
    1877             :         case NetlogonInteractiveTransitiveInformation:
    1878             :         case NetlogonServiceTransitiveInformation:
    1879             : 
    1880             :                 /* 'Interactive' authentication, supplies the password in its
    1881             :                    MD4 form, encrypted with the session key.  We will convert
    1882             :                    this to challenge/response for the auth subsystem to chew
    1883             :                    on */
    1884             :         {
    1885             :                 uint8_t chal[8];
    1886             : 
    1887             : #ifdef DEBUG_PASSWORD
    1888          70 :                 if (logon != r->in.logon) {
    1889          70 :                         DEBUG(100,("lm owf password:"));
    1890          70 :                         dump_data(100,
    1891          70 :                                   r->in.logon->password->lmpassword.hash, 16);
    1892             : 
    1893          70 :                         DEBUG(100,("nt owf password:"));
    1894          70 :                         dump_data(100,
    1895          70 :                                   r->in.logon->password->ntpassword.hash, 16);
    1896             :                 }
    1897             : 
    1898          70 :                 DEBUG(100,("decrypt of lm owf password:"));
    1899          70 :                 dump_data(100, logon->password->lmpassword.hash, 16);
    1900             : 
    1901          70 :                 DEBUG(100,("decrypt of nt owf password:"));
    1902          70 :                 dump_data(100, logon->password->ntpassword.hash, 16);
    1903             : #endif
    1904             : 
    1905          70 :                 auth_get_ntlm_challenge(auth_context, chal);
    1906             : 
    1907          70 :                 if (!make_user_info_netlogon_interactive(talloc_tos(),
    1908             :                                                          &user_info,
    1909             :                                                          nt_username, nt_domain,
    1910             :                                                          nt_workstation,
    1911             :                                                          p->remote_address,
    1912             :                                                          p->local_address,
    1913          70 :                                                          logon->password->identity_info.parameter_control,
    1914             :                                                          chal,
    1915          70 :                                                          logon->password->lmpassword.hash,
    1916          70 :                                                          logon->password->ntpassword.hash)) {
    1917           0 :                         status = NT_STATUS_NO_MEMORY;
    1918             :                 }
    1919          70 :                 break;
    1920             :         }
    1921           0 :         default:
    1922           0 :                 DEBUG(2,("SAM Logon: unsupported switch value\n"));
    1923           0 :                 return NT_STATUS_INVALID_INFO_CLASS;
    1924             :         } /* end switch */
    1925             : 
    1926         558 :         if ( NT_STATUS_IS_OK(status) ) {
    1927         558 :                 status = auth_check_ntlm_password(p->mem_ctx,
    1928             :                                                   auth_context,
    1929             :                                                   user_info,
    1930             :                                                   &server_info,
    1931             :                                                   r->out.authoritative);
    1932             :         }
    1933             : 
    1934         558 :         TALLOC_FREE(auth_context);
    1935         558 :         TALLOC_FREE(user_info);
    1936             : 
    1937         558 :         DEBUG(5,("%s: check_password returned status %s\n",
    1938             :                   fn, nt_errstr(status)));
    1939             : 
    1940             :         /* Check account and password */
    1941             : 
    1942         558 :         if (!NT_STATUS_IS_OK(status)) {
    1943         232 :                 TALLOC_FREE(server_info);
    1944         232 :                 return status;
    1945             :         }
    1946             : 
    1947         326 :         if (server_info->guest) {
    1948             :                 /* We don't like guest domain logons... */
    1949           0 :                 DEBUG(5,("%s: Attempted domain logon as GUEST "
    1950             :                          "denied.\n", fn));
    1951           0 :                 TALLOC_FREE(server_info);
    1952           0 :                 return NT_STATUS_LOGON_FAILURE;
    1953             :         }
    1954             : 
    1955         326 :         sanitized_username = talloc_alpha_strcpy(talloc_tos(),
    1956             :                                                  nt_username,
    1957             :                                                  SAFE_NETBIOS_CHARS "$");
    1958         326 :         if (sanitized_username == NULL) {
    1959           0 :                 TALLOC_FREE(server_info);
    1960           0 :                 return NT_STATUS_NO_MEMORY;
    1961             :         }
    1962             : 
    1963         652 :         set_current_user_info(sanitized_username,
    1964         326 :                               server_info->unix_name,
    1965         326 :                               server_info->info3->base.logon_domain.string);
    1966         326 :         TALLOC_FREE(sanitized_username);
    1967             : 
    1968             :         /* This is the point at which, if the login was successful, that
    1969             :            the SAM Local Security Authority should record that the user is
    1970             :            logged in to the domain.  */
    1971             : 
    1972         326 :         switch (r->in.validation_level) {
    1973         136 :         case 2:
    1974         136 :                 status = serverinfo_to_SamInfo2(server_info,
    1975         136 :                                                 r->out.validation->sam2);
    1976         136 :                 break;
    1977         190 :         case 3:
    1978         190 :                 status = serverinfo_to_SamInfo3(server_info,
    1979         190 :                                                 r->out.validation->sam3);
    1980         190 :                 break;
    1981           0 :         case 6:
    1982             :                 /* Only allow this if the pipe is protected. */
    1983           0 :                 if (p->auth.auth_level < DCERPC_AUTH_LEVEL_PRIVACY) {
    1984           0 :                         DEBUG(0,("netr_Validation6: client %s not using privacy for netlogon\n",
    1985             :                                 get_remote_machine_name()));
    1986           0 :                         status = NT_STATUS_INVALID_PARAMETER;
    1987           0 :                         break;
    1988             :                 }
    1989             : 
    1990           0 :                 status = serverinfo_to_SamInfo6(server_info,
    1991           0 :                                                 r->out.validation->sam6);
    1992           0 :                 break;
    1993             :         }
    1994             : 
    1995         326 :         TALLOC_FREE(server_info);
    1996             : 
    1997         326 :         if (!NT_STATUS_IS_OK(status)) {
    1998           0 :                 return status;
    1999             :         }
    2000             : 
    2001         652 :         status = netlogon_creds_encrypt_samlogon_validation(creds,
    2002         326 :                                                             r->in.validation_level,
    2003             :                                                             r->out.validation);
    2004             : 
    2005         326 :         return status;
    2006             : }
    2007             : 
    2008             : /****************************************************************
    2009             :  _netr_LogonSamLogonWithFlags
    2010             : ****************************************************************/
    2011             : 
    2012         384 : NTSTATUS _netr_LogonSamLogonWithFlags(struct pipes_struct *p,
    2013             :                                       struct netr_LogonSamLogonWithFlags *r)
    2014             : {
    2015             :         NTSTATUS status;
    2016             :         struct netlogon_creds_CredentialState *creds;
    2017             :         struct netr_LogonSamLogonEx r2;
    2018             :         struct netr_Authenticator return_authenticator;
    2019             : 
    2020         384 :         *r->out.authoritative = true;
    2021             : 
    2022         384 :         r2.in.server_name       = r->in.server_name;
    2023         384 :         r2.in.computer_name     = r->in.computer_name;
    2024         384 :         r2.in.logon_level       = r->in.logon_level;
    2025         384 :         r2.in.logon             = r->in.logon;
    2026         384 :         r2.in.validation_level  = r->in.validation_level;
    2027         384 :         r2.in.flags             = r->in.flags;
    2028         384 :         r2.out.validation       = r->out.validation;
    2029         384 :         r2.out.authoritative    = r->out.authoritative;
    2030         384 :         r2.out.flags            = r->out.flags;
    2031             : 
    2032         384 :         status = _netr_LogonSamLogon_check(&r2);
    2033         384 :         if (!NT_STATUS_IS_OK(status)) {
    2034         160 :                 return status;
    2035             :         }
    2036             : 
    2037         224 :         become_root();
    2038         224 :         status = netr_creds_server_step_check(p, p->mem_ctx,
    2039             :                                               r->in.computer_name,
    2040             :                                               r->in.credential,
    2041             :                                               &return_authenticator,
    2042             :                                               &creds);
    2043         224 :         unbecome_root();
    2044         224 :         if (!NT_STATUS_IS_OK(status)) {
    2045           0 :                 return status;
    2046             :         }
    2047             : 
    2048         224 :         status = _netr_LogonSamLogon_base(p, &r2, creds);
    2049             : 
    2050         224 :         *r->out.return_authenticator = return_authenticator;
    2051             : 
    2052         224 :         return status;
    2053             : }
    2054             : 
    2055             : /*************************************************************************
    2056             :  _netr_LogonSamLogon
    2057             :  *************************************************************************/
    2058             : 
    2059         384 : NTSTATUS _netr_LogonSamLogon(struct pipes_struct *p,
    2060             :                              struct netr_LogonSamLogon *r)
    2061             : {
    2062             :         NTSTATUS status;
    2063             :         struct netr_LogonSamLogonWithFlags r2;
    2064         384 :         uint32_t flags = 0;
    2065             : 
    2066         384 :         r2.in.server_name               = r->in.server_name;
    2067         384 :         r2.in.computer_name             = r->in.computer_name;
    2068         384 :         r2.in.credential                = r->in.credential;
    2069         384 :         r2.in.logon_level               = r->in.logon_level;
    2070         384 :         r2.in.logon                     = r->in.logon;
    2071         384 :         r2.in.validation_level          = r->in.validation_level;
    2072         384 :         r2.in.return_authenticator      = r->in.return_authenticator;
    2073         384 :         r2.in.flags                     = &flags;
    2074         384 :         r2.out.validation               = r->out.validation;
    2075         384 :         r2.out.authoritative            = r->out.authoritative;
    2076         384 :         r2.out.flags                    = &flags;
    2077         384 :         r2.out.return_authenticator     = r->out.return_authenticator;
    2078             : 
    2079         384 :         status = _netr_LogonSamLogonWithFlags(p, &r2);
    2080             : 
    2081         384 :         return status;
    2082             : }
    2083             : 
    2084             : /*************************************************************************
    2085             :  _netr_LogonSamLogonEx
    2086             :  - no credential chaining. Map into net sam logon.
    2087             :  *************************************************************************/
    2088             : 
    2089         639 : NTSTATUS _netr_LogonSamLogonEx(struct pipes_struct *p,
    2090             :                                struct netr_LogonSamLogonEx *r)
    2091             : {
    2092             :         NTSTATUS status;
    2093         639 :         struct netlogon_creds_CredentialState *creds = NULL;
    2094             :         struct loadparm_context *lp_ctx;
    2095             : 
    2096         639 :         *r->out.authoritative = true;
    2097             : 
    2098         639 :         status = _netr_LogonSamLogon_check(r);
    2099         639 :         if (!NT_STATUS_IS_OK(status)) {
    2100         297 :                 return status;
    2101             :         }
    2102             : 
    2103             :         /* Only allow this if the pipe is protected. */
    2104         342 :         if (p->auth.auth_type != DCERPC_AUTH_TYPE_SCHANNEL) {
    2105           8 :                 DEBUG(0,("_netr_LogonSamLogonEx: client %s not using schannel for netlogon\n",
    2106             :                         get_remote_machine_name() ));
    2107           8 :                 return NT_STATUS_INVALID_PARAMETER;
    2108             :         }
    2109             : 
    2110         334 :         lp_ctx = loadparm_init_s3(p->mem_ctx, loadparm_s3_helpers());
    2111         334 :         if (lp_ctx == NULL) {
    2112           0 :                 DEBUG(0, ("loadparm_init_s3 failed\n"));
    2113           0 :                 return NT_STATUS_INTERNAL_ERROR;
    2114             :         }
    2115             : 
    2116         334 :         become_root();
    2117         334 :         status = schannel_get_creds_state(p->mem_ctx, lp_ctx,
    2118             :                                           r->in.computer_name, &creds);
    2119         334 :         unbecome_root();
    2120         334 :         talloc_unlink(p->mem_ctx, lp_ctx);
    2121             : 
    2122         334 :         if (!NT_STATUS_IS_OK(status)) {
    2123           0 :                 return status;
    2124             :         }
    2125             : 
    2126         334 :         status = _netr_LogonSamLogon_base(p, r, creds);
    2127         334 :         TALLOC_FREE(creds);
    2128             : 
    2129         334 :         return status;
    2130             : }
    2131             : 
    2132             : /*************************************************************************
    2133             :  _ds_enum_dom_trusts
    2134             :  *************************************************************************/
    2135             : #if 0   /* JERRY -- not correct */
    2136             :  NTSTATUS _ds_enum_dom_trusts(struct pipes_struct *p, DS_Q_ENUM_DOM_TRUSTS *q_u,
    2137             :                              DS_R_ENUM_DOM_TRUSTS *r_u)
    2138             : {
    2139             :         NTSTATUS status = NT_STATUS_OK;
    2140             : 
    2141             :         /* TODO: According to MSDN, the can only be executed against a
    2142             :            DC or domain member running Windows 2000 or later.  Need
    2143             :            to test against a standalone 2k server and see what it
    2144             :            does.  A windows 2000 DC includes its own domain in the
    2145             :            list.  --jerry */
    2146             : 
    2147             :         return status;
    2148             : }
    2149             : #endif  /* JERRY */
    2150             : 
    2151             : 
    2152             : /****************************************************************
    2153             : ****************************************************************/
    2154             : 
    2155           0 : WERROR _netr_LogonUasLogon(struct pipes_struct *p,
    2156             :                            struct netr_LogonUasLogon *r)
    2157             : {
    2158           0 :         p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
    2159           0 :         return WERR_NOT_SUPPORTED;
    2160             : }
    2161             : 
    2162             : /****************************************************************
    2163             : ****************************************************************/
    2164             : 
    2165           0 : WERROR _netr_LogonUasLogoff(struct pipes_struct *p,
    2166             :                             struct netr_LogonUasLogoff *r)
    2167             : {
    2168           0 :         p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
    2169           0 :         return WERR_NOT_SUPPORTED;
    2170             : }
    2171             : 
    2172             : /****************************************************************
    2173             : ****************************************************************/
    2174             : 
    2175           0 : NTSTATUS _netr_DatabaseDeltas(struct pipes_struct *p,
    2176             :                               struct netr_DatabaseDeltas *r)
    2177             : {
    2178           0 :         p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
    2179           0 :         return NT_STATUS_NOT_IMPLEMENTED;
    2180             : }
    2181             : 
    2182             : /****************************************************************
    2183             : ****************************************************************/
    2184             : 
    2185           0 : NTSTATUS _netr_DatabaseSync(struct pipes_struct *p,
    2186             :                             struct netr_DatabaseSync *r)
    2187             : {
    2188           0 :         p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
    2189           0 :         return NT_STATUS_NOT_IMPLEMENTED;
    2190             : }
    2191             : 
    2192             : /****************************************************************
    2193             : ****************************************************************/
    2194             : 
    2195           0 : NTSTATUS _netr_AccountDeltas(struct pipes_struct *p,
    2196             :                              struct netr_AccountDeltas *r)
    2197             : {
    2198           0 :         p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
    2199           0 :         return NT_STATUS_NOT_IMPLEMENTED;
    2200             : }
    2201             : 
    2202             : /****************************************************************
    2203             : ****************************************************************/
    2204             : 
    2205           0 : NTSTATUS _netr_AccountSync(struct pipes_struct *p,
    2206             :                            struct netr_AccountSync *r)
    2207             : {
    2208           0 :         p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
    2209           0 :         return NT_STATUS_NOT_IMPLEMENTED;
    2210             : }
    2211             : 
    2212             : /****************************************************************
    2213             : ****************************************************************/
    2214             : 
    2215           0 : static bool wb_getdcname(TALLOC_CTX *mem_ctx,
    2216             :                          const char *domain,
    2217             :                          const char **dcname,
    2218             :                          uint32_t flags,
    2219             :                          WERROR *werr)
    2220             : {
    2221             :         wbcErr result;
    2222           0 :         struct wbcDomainControllerInfo *dc_info = NULL;
    2223             : 
    2224           0 :         result = wbcLookupDomainController(domain,
    2225             :                                            flags,
    2226             :                                            &dc_info);
    2227           0 :         switch (result) {
    2228           0 :         case WBC_ERR_SUCCESS:
    2229           0 :                 break;
    2230           0 :         case WBC_ERR_WINBIND_NOT_AVAILABLE:
    2231           0 :                 return false;
    2232           0 :         case WBC_ERR_DOMAIN_NOT_FOUND:
    2233           0 :                 *werr = WERR_NO_SUCH_DOMAIN;
    2234           0 :                 return true;
    2235           0 :         default:
    2236           0 :                 *werr = WERR_DOMAIN_CONTROLLER_NOT_FOUND;
    2237           0 :                 return true;
    2238             :         }
    2239             : 
    2240           0 :         *dcname = talloc_strdup(mem_ctx, dc_info->dc_name);
    2241           0 :         wbcFreeMemory(dc_info);
    2242           0 :         if (!*dcname) {
    2243           0 :                 *werr = WERR_NOT_ENOUGH_MEMORY;
    2244           0 :                 return false;
    2245             :         }
    2246             : 
    2247           0 :         *werr = WERR_OK;
    2248             : 
    2249           0 :         return true;
    2250             : }
    2251             : 
    2252             : /****************************************************************
    2253             :  _netr_GetDcName
    2254             : ****************************************************************/
    2255             : 
    2256           0 : WERROR _netr_GetDcName(struct pipes_struct *p,
    2257             :                        struct netr_GetDcName *r)
    2258             : {
    2259             :         NTSTATUS status;
    2260             :         WERROR werr;
    2261             :         uint32_t flags;
    2262             :         struct netr_DsRGetDCNameInfo *info;
    2263             :         bool ret;
    2264             : 
    2265           0 :         ret = wb_getdcname(p->mem_ctx,
    2266             :                            r->in.domainname,
    2267             :                            r->out.dcname,
    2268             :                            WBC_LOOKUP_DC_IS_FLAT_NAME |
    2269             :                            WBC_LOOKUP_DC_RETURN_FLAT_NAME |
    2270             :                            WBC_LOOKUP_DC_PDC_REQUIRED,
    2271             :                            &werr);
    2272           0 :         if (ret == true) {
    2273           0 :                 return werr;
    2274             :         }
    2275             : 
    2276           0 :         flags = DS_PDC_REQUIRED | DS_IS_FLAT_NAME | DS_RETURN_FLAT_NAME;
    2277             : 
    2278           0 :         status = dsgetdcname(p->mem_ctx,
    2279             :                              p->msg_ctx,
    2280             :                              r->in.domainname,
    2281             :                              NULL,
    2282             :                              NULL,
    2283             :                              flags,
    2284             :                              &info);
    2285           0 :         if (!NT_STATUS_IS_OK(status)) {
    2286           0 :                 return ntstatus_to_werror(status);
    2287             :         }
    2288             : 
    2289           0 :         *r->out.dcname = talloc_strdup(p->mem_ctx, info->dc_unc);
    2290           0 :         talloc_free(info);
    2291           0 :         if (!*r->out.dcname) {
    2292           0 :                 return WERR_NOT_ENOUGH_MEMORY;
    2293             :         }
    2294             : 
    2295           0 :         return WERR_OK;
    2296             : }
    2297             : 
    2298             : /****************************************************************
    2299             :  _netr_GetAnyDCName
    2300             : ****************************************************************/
    2301             : 
    2302           0 : WERROR _netr_GetAnyDCName(struct pipes_struct *p,
    2303             :                           struct netr_GetAnyDCName *r)
    2304             : {
    2305             :         NTSTATUS status;
    2306             :         WERROR werr;
    2307             :         uint32_t flags;
    2308             :         struct netr_DsRGetDCNameInfo *info;
    2309             :         bool ret;
    2310             : 
    2311           0 :         ret = wb_getdcname(p->mem_ctx,
    2312             :                            r->in.domainname,
    2313             :                            r->out.dcname,
    2314             :                            WBC_LOOKUP_DC_IS_FLAT_NAME |
    2315             :                            WBC_LOOKUP_DC_RETURN_FLAT_NAME,
    2316             :                            &werr);
    2317           0 :         if (ret == true) {
    2318           0 :                 return werr;
    2319             :         }
    2320             : 
    2321           0 :         flags = DS_IS_FLAT_NAME | DS_RETURN_FLAT_NAME;
    2322             : 
    2323           0 :         status = dsgetdcname(p->mem_ctx,
    2324             :                              p->msg_ctx,
    2325             :                              r->in.domainname,
    2326             :                              NULL,
    2327             :                              NULL,
    2328             :                              flags,
    2329             :                              &info);
    2330           0 :         if (!NT_STATUS_IS_OK(status)) {
    2331           0 :                 return ntstatus_to_werror(status);
    2332             :         }
    2333             : 
    2334           0 :         *r->out.dcname = talloc_strdup(p->mem_ctx, info->dc_unc);
    2335           0 :         talloc_free(info);
    2336           0 :         if (!*r->out.dcname) {
    2337           0 :                 return WERR_NOT_ENOUGH_MEMORY;
    2338             :         }
    2339             : 
    2340           0 :         return WERR_OK;
    2341             : }
    2342             : 
    2343             : /****************************************************************
    2344             : ****************************************************************/
    2345             : 
    2346           0 : NTSTATUS _netr_DatabaseSync2(struct pipes_struct *p,
    2347             :                              struct netr_DatabaseSync2 *r)
    2348             : {
    2349           0 :         p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
    2350           0 :         return NT_STATUS_NOT_IMPLEMENTED;
    2351             : }
    2352             : 
    2353             : /****************************************************************
    2354             : ****************************************************************/
    2355             : 
    2356           0 : NTSTATUS _netr_DatabaseRedo(struct pipes_struct *p,
    2357             :                             struct netr_DatabaseRedo *r)
    2358             : {
    2359           0 :         p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
    2360           0 :         return NT_STATUS_NOT_IMPLEMENTED;
    2361             : }
    2362             : 
    2363             : /****************************************************************
    2364             : ****************************************************************/
    2365             : 
    2366           0 : WERROR _netr_DsRGetDCName(struct pipes_struct *p,
    2367             :                           struct netr_DsRGetDCName *r)
    2368             : {
    2369           0 :         p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
    2370           0 :         return WERR_NOT_SUPPORTED;
    2371             : }
    2372             : 
    2373             : /****************************************************************
    2374             : ****************************************************************/
    2375             : 
    2376          33 : NTSTATUS _netr_LogonGetCapabilities(struct pipes_struct *p,
    2377             :                                     struct netr_LogonGetCapabilities *r)
    2378             : {
    2379             :         struct netlogon_creds_CredentialState *creds;
    2380             :         NTSTATUS status;
    2381             : 
    2382          33 :         become_root();
    2383          33 :         status = netr_creds_server_step_check(p, p->mem_ctx,
    2384             :                                               r->in.computer_name,
    2385             :                                               r->in.credential,
    2386             :                                               r->out.return_authenticator,
    2387             :                                               &creds);
    2388          33 :         unbecome_root();
    2389          33 :         if (!NT_STATUS_IS_OK(status)) {
    2390           0 :                 return status;
    2391             :         }
    2392             : 
    2393          33 :         if (r->in.query_level != 1) {
    2394           0 :                 return NT_STATUS_NOT_SUPPORTED;
    2395             :         }
    2396             : 
    2397          33 :         r->out.capabilities->server_capabilities = creds->negotiate_flags;
    2398             : 
    2399          33 :         return NT_STATUS_OK;
    2400             : }
    2401             : 
    2402             : /****************************************************************
    2403             : ****************************************************************/
    2404             : 
    2405           0 : WERROR _netr_NETRLOGONSETSERVICEBITS(struct pipes_struct *p,
    2406             :                                      struct netr_NETRLOGONSETSERVICEBITS *r)
    2407             : {
    2408           0 :         p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
    2409           0 :         return WERR_NOT_SUPPORTED;
    2410             : }
    2411             : 
    2412             : /****************************************************************
    2413             : ****************************************************************/
    2414             : 
    2415           0 : WERROR _netr_LogonGetTrustRid(struct pipes_struct *p,
    2416             :                               struct netr_LogonGetTrustRid *r)
    2417             : {
    2418           0 :         p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
    2419           0 :         return WERR_NOT_SUPPORTED;
    2420             : }
    2421             : 
    2422             : /****************************************************************
    2423             : ****************************************************************/
    2424             : 
    2425           0 : WERROR _netr_NETRLOGONCOMPUTESERVERDIGEST(struct pipes_struct *p,
    2426             :                                           struct netr_NETRLOGONCOMPUTESERVERDIGEST *r)
    2427             : {
    2428           0 :         p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
    2429           0 :         return WERR_NOT_SUPPORTED;
    2430             : }
    2431             : 
    2432             : /****************************************************************
    2433             : ****************************************************************/
    2434             : 
    2435           0 : WERROR _netr_NETRLOGONCOMPUTECLIENTDIGEST(struct pipes_struct *p,
    2436             :                                           struct netr_NETRLOGONCOMPUTECLIENTDIGEST *r)
    2437             : {
    2438           0 :         p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
    2439           0 :         return WERR_NOT_SUPPORTED;
    2440             : }
    2441             : 
    2442             : /****************************************************************
    2443             : ****************************************************************/
    2444             : 
    2445           0 : WERROR _netr_DsRGetDCNameEx(struct pipes_struct *p,
    2446             :                             struct netr_DsRGetDCNameEx *r)
    2447             : {
    2448           0 :         p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
    2449           0 :         return WERR_NOT_SUPPORTED;
    2450             : }
    2451             : 
    2452             : /****************************************************************
    2453             : ****************************************************************/
    2454             : 
    2455           0 : WERROR _netr_DsRGetSiteName(struct pipes_struct *p,
    2456             :                             struct netr_DsRGetSiteName *r)
    2457             : {
    2458           0 :         p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
    2459           0 :         return WERR_NOT_SUPPORTED;
    2460             : }
    2461             : 
    2462             : /****************************************************************
    2463             : ****************************************************************/
    2464             : 
    2465           0 : NTSTATUS _netr_LogonGetDomainInfo(struct pipes_struct *p,
    2466             :                                   struct netr_LogonGetDomainInfo *r)
    2467             : {
    2468           0 :         p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
    2469           0 :         return NT_STATUS_NOT_IMPLEMENTED;
    2470             : }
    2471             : 
    2472             : /****************************************************************
    2473             : ****************************************************************/
    2474             : 
    2475           0 : NTSTATUS _netr_ServerPasswordGet(struct pipes_struct *p,
    2476             :                                  struct netr_ServerPasswordGet *r)
    2477             : {
    2478           0 :         p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
    2479           0 :         return NT_STATUS_NOT_SUPPORTED;
    2480             : }
    2481             : 
    2482             : /****************************************************************
    2483             : ****************************************************************/
    2484             : 
    2485           0 : NTSTATUS _netr_NetrLogonSendToSam(struct pipes_struct *p,
    2486             :                                 struct netr_NetrLogonSendToSam *r)
    2487             : {
    2488           0 :         p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
    2489           0 :         return NT_STATUS_NOT_IMPLEMENTED;
    2490             : }
    2491             : 
    2492             : /****************************************************************
    2493             : ****************************************************************/
    2494             : 
    2495           0 : WERROR _netr_DsRAddressToSitenamesW(struct pipes_struct *p,
    2496             :                                     struct netr_DsRAddressToSitenamesW *r)
    2497             : {
    2498           0 :         p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
    2499           0 :         return WERR_NOT_SUPPORTED;
    2500             : }
    2501             : 
    2502             : /****************************************************************
    2503             : ****************************************************************/
    2504             : 
    2505           0 : WERROR _netr_DsRGetDCNameEx2(struct pipes_struct *p,
    2506             :                              struct netr_DsRGetDCNameEx2 *r)
    2507             : {
    2508           0 :         p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
    2509           0 :         return WERR_NOT_SUPPORTED;
    2510             : }
    2511             : 
    2512             : /****************************************************************
    2513             : ****************************************************************/
    2514             : 
    2515           0 : WERROR _netr_NETRLOGONGETTIMESERVICEPARENTDOMAIN(struct pipes_struct *p,
    2516             :                                                  struct netr_NETRLOGONGETTIMESERVICEPARENTDOMAIN *r)
    2517             : {
    2518           0 :         p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
    2519           0 :         return WERR_NOT_SUPPORTED;
    2520             : }
    2521             : 
    2522             : /****************************************************************
    2523             : ****************************************************************/
    2524             : 
    2525           0 : WERROR _netr_NetrEnumerateTrustedDomainsEx(struct pipes_struct *p,
    2526             :                                            struct netr_NetrEnumerateTrustedDomainsEx *r)
    2527             : {
    2528           0 :         p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
    2529           0 :         return WERR_NOT_SUPPORTED;
    2530             : }
    2531             : 
    2532             : /****************************************************************
    2533             : ****************************************************************/
    2534             : 
    2535           0 : WERROR _netr_DsRAddressToSitenamesExW(struct pipes_struct *p,
    2536             :                                       struct netr_DsRAddressToSitenamesExW *r)
    2537             : {
    2538           0 :         p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
    2539           0 :         return WERR_NOT_SUPPORTED;
    2540             : }
    2541             : 
    2542             : /****************************************************************
    2543             : ****************************************************************/
    2544             : 
    2545           0 : WERROR _netr_DsrGetDcSiteCoverageW(struct pipes_struct *p,
    2546             :                                    struct netr_DsrGetDcSiteCoverageW *r)
    2547             : {
    2548           0 :         p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
    2549           0 :         return WERR_NOT_SUPPORTED;
    2550             : }
    2551             : 
    2552             : /****************************************************************
    2553             : ****************************************************************/
    2554             : 
    2555           0 : WERROR _netr_DsrEnumerateDomainTrusts(struct pipes_struct *p,
    2556             :                                       struct netr_DsrEnumerateDomainTrusts *r)
    2557             : {
    2558           0 :         p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
    2559           0 :         return WERR_NOT_SUPPORTED;
    2560             : }
    2561             : 
    2562             : /****************************************************************
    2563             : ****************************************************************/
    2564             : 
    2565           0 : WERROR _netr_DsrDeregisterDNSHostRecords(struct pipes_struct *p,
    2566             :                                          struct netr_DsrDeregisterDNSHostRecords *r)
    2567             : {
    2568           0 :         p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
    2569           0 :         return WERR_NOT_SUPPORTED;
    2570             : }
    2571             : 
    2572             : /****************************************************************
    2573             : ****************************************************************/
    2574             : 
    2575           0 : NTSTATUS _netr_ServerTrustPasswordsGet(struct pipes_struct *p,
    2576             :                                        struct netr_ServerTrustPasswordsGet *r)
    2577             : {
    2578           0 :         p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
    2579           0 :         return NT_STATUS_NOT_IMPLEMENTED;
    2580             : }
    2581             : 
    2582             : /****************************************************************
    2583             : ****************************************************************/
    2584             : 
    2585           0 : static NTSTATUS fill_forest_trust_array(TALLOC_CTX *mem_ctx,
    2586             :                                         struct lsa_ForestTrustInformation *info)
    2587             : {
    2588             :         struct lsa_ForestTrustRecord *e;
    2589             :         struct pdb_domain_info *dom_info;
    2590             :         struct lsa_ForestTrustDomainInfo *domain_info;
    2591           0 :         char **upn_suffixes = NULL;
    2592           0 :         uint32_t num_suffixes = 0;
    2593           0 :         uint32_t i = 0;
    2594             :         NTSTATUS status;
    2595             : 
    2596           0 :         dom_info = pdb_get_domain_info(mem_ctx);
    2597           0 :         if (dom_info == NULL) {
    2598           0 :                 return NT_STATUS_NO_MEMORY;
    2599             :         }
    2600             : 
    2601           0 :         info->count = 2;
    2602             : 
    2603           0 :         become_root();
    2604           0 :         status = pdb_enum_upn_suffixes(info, &num_suffixes, &upn_suffixes);
    2605           0 :         unbecome_root();
    2606           0 :         if (NT_STATUS_IS_OK(status) && (num_suffixes > 0)) {
    2607           0 :                 info->count += num_suffixes;
    2608             :         }
    2609             : 
    2610           0 :         info->entries = talloc_array(info, struct lsa_ForestTrustRecord *, info->count);
    2611           0 :         if (info->entries == NULL) {
    2612           0 :                 return NT_STATUS_NO_MEMORY;
    2613             :         }
    2614             : 
    2615           0 :         e = talloc(info, struct lsa_ForestTrustRecord);
    2616           0 :         if (e == NULL) {
    2617           0 :                 return NT_STATUS_NO_MEMORY;
    2618             :         }
    2619             : 
    2620           0 :         e->flags = 0;
    2621           0 :         e->type = LSA_FOREST_TRUST_TOP_LEVEL_NAME;
    2622           0 :         e->time = 0; /* so far always 0 in trces. */
    2623           0 :         e->forest_trust_data.top_level_name.string = talloc_steal(info,
    2624             :                                                                   dom_info->dns_forest);
    2625             : 
    2626           0 :         info->entries[0] = e;
    2627             : 
    2628           0 :         if (num_suffixes > 0) {
    2629           0 :                 for (i = 0; i < num_suffixes ; i++) {
    2630           0 :                         e = talloc(info, struct lsa_ForestTrustRecord);
    2631           0 :                         if (e == NULL) {
    2632           0 :                                 return NT_STATUS_NO_MEMORY;
    2633             :                         }
    2634             : 
    2635           0 :                         e->flags = 0;
    2636           0 :                         e->type = LSA_FOREST_TRUST_TOP_LEVEL_NAME;
    2637           0 :                         e->time = 0; /* so far always 0 in traces. */
    2638           0 :                         e->forest_trust_data.top_level_name.string = upn_suffixes[i];
    2639           0 :                         info->entries[1 + i] = e;
    2640             :                 }
    2641             :         }
    2642             : 
    2643           0 :         e = talloc(info, struct lsa_ForestTrustRecord);
    2644           0 :         if (e == NULL) {
    2645           0 :                 return NT_STATUS_NO_MEMORY;
    2646             :         }
    2647             : 
    2648             :         /* TODO: check if disabled and set flags accordingly */
    2649           0 :         e->flags = 0;
    2650           0 :         e->type = LSA_FOREST_TRUST_DOMAIN_INFO;
    2651           0 :         e->time = 0; /* so far always 0 in traces. */
    2652             : 
    2653           0 :         domain_info = &e->forest_trust_data.domain_info;
    2654           0 :         domain_info->domain_sid = dom_sid_dup(info, &dom_info->sid);
    2655             : 
    2656           0 :         domain_info->dns_domain_name.string = talloc_steal(info,
    2657             :                                                            dom_info->dns_domain);
    2658           0 :         domain_info->netbios_domain_name.string = talloc_steal(info,
    2659             :                                                                dom_info->name);
    2660             : 
    2661           0 :         info->entries[info->count - 1] = e;
    2662             : 
    2663           0 :         return NT_STATUS_OK;
    2664             : }
    2665             : 
    2666             : /****************************************************************
    2667             : ****************************************************************/
    2668             : 
    2669           0 : WERROR _netr_DsRGetForestTrustInformation(struct pipes_struct *p,
    2670             :                                           struct netr_DsRGetForestTrustInformation *r)
    2671             : {
    2672             :         NTSTATUS status;
    2673             :         struct lsa_ForestTrustInformation *info, **info_ptr;
    2674             :         enum security_user_level security_level;
    2675             : 
    2676           0 :         security_level = security_session_user_level(p->session_info, NULL);
    2677           0 :         if (security_level < SECURITY_USER) {
    2678           0 :                 return WERR_ACCESS_DENIED;
    2679             :         }
    2680             : 
    2681           0 :         if (r->in.flags & (~DS_GFTI_UPDATE_TDO)) {
    2682           0 :                 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
    2683           0 :                 return WERR_INVALID_FLAGS;
    2684             :         }
    2685             : 
    2686           0 :         if ((r->in.flags & DS_GFTI_UPDATE_TDO) && (lp_server_role() != ROLE_DOMAIN_PDC)) {
    2687           0 :                 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
    2688           0 :                 return WERR_NERR_NOTPRIMARY;
    2689             :         }
    2690             : 
    2691           0 :         if ((r->in.trusted_domain_name == NULL) && (r->in.flags & DS_GFTI_UPDATE_TDO)) {
    2692           0 :                 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
    2693           0 :                 return WERR_INVALID_PARAMETER;
    2694             :         }
    2695             : 
    2696             :         /* retrieve forest trust information and stop further processing */
    2697           0 :         if (r->in.trusted_domain_name == NULL) {
    2698           0 :                 info_ptr = talloc(p->mem_ctx, struct lsa_ForestTrustInformation *);
    2699           0 :                 if (info_ptr == NULL) {
    2700           0 :                         p->fault_state = DCERPC_FAULT_CANT_PERFORM;
    2701           0 :                         return WERR_NOT_ENOUGH_MEMORY;
    2702             :                 }
    2703           0 :                 info = talloc_zero(info_ptr, struct lsa_ForestTrustInformation);
    2704           0 :                 if (info == NULL) {
    2705           0 :                         p->fault_state = DCERPC_FAULT_CANT_PERFORM;
    2706           0 :                         return WERR_NOT_ENOUGH_MEMORY;
    2707             :                 }
    2708             : 
    2709             :                 /* Fill forest trust information and expand UPN suffixes list */
    2710           0 :                 status = fill_forest_trust_array(p->mem_ctx, info);
    2711           0 :                 if (!NT_STATUS_IS_OK(status)) {
    2712           0 :                         p->fault_state = DCERPC_FAULT_CANT_PERFORM;
    2713           0 :                         return WERR_NOT_ENOUGH_MEMORY;
    2714             :                 }
    2715             : 
    2716           0 :                 *info_ptr = info;
    2717           0 :                 r->out.forest_trust_info = info_ptr;
    2718             : 
    2719           0 :                 return WERR_OK;
    2720             : 
    2721             :         }
    2722             : 
    2723             :         /* TODO: implement remaining parts of DsrGetForestTrustInformation (opnum 43)
    2724             :          *       when trusted_domain_name is not NULL */
    2725             : 
    2726           0 :         p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
    2727           0 :         return WERR_NOT_SUPPORTED;
    2728             : }
    2729             : 
    2730             : /****************************************************************
    2731             :  _netr_GetForestTrustInformation
    2732             : ****************************************************************/
    2733             : 
    2734           0 : NTSTATUS _netr_GetForestTrustInformation(struct pipes_struct *p,
    2735             :                                          struct netr_GetForestTrustInformation *r)
    2736             : {
    2737             :         NTSTATUS status;
    2738             :         struct netlogon_creds_CredentialState *creds;
    2739             :         struct lsa_ForestTrustInformation *info, **info_ptr;
    2740             : 
    2741             :         /* TODO: check server name */
    2742             : 
    2743           0 :         become_root();
    2744           0 :         status = netr_creds_server_step_check(p, p->mem_ctx,
    2745             :                                               r->in.computer_name,
    2746             :                                               r->in.credential,
    2747             :                                               r->out.return_authenticator,
    2748             :                                               &creds);
    2749           0 :         unbecome_root();
    2750           0 :         if (!NT_STATUS_IS_OK(status)) {
    2751           0 :                 return status;
    2752             :         }
    2753             : 
    2754           0 :         if ((creds->secure_channel_type != SEC_CHAN_DNS_DOMAIN) &&
    2755           0 :             (creds->secure_channel_type != SEC_CHAN_DOMAIN)) {
    2756           0 :                 return NT_STATUS_NOT_IMPLEMENTED;
    2757             :         }
    2758             : 
    2759           0 :         info_ptr = talloc(p->mem_ctx, struct lsa_ForestTrustInformation *);
    2760           0 :         if (!info_ptr) {
    2761           0 :                 return NT_STATUS_NO_MEMORY;
    2762             :         }
    2763           0 :         info = talloc_zero(info_ptr, struct lsa_ForestTrustInformation);
    2764           0 :         if (!info) {
    2765           0 :                 return NT_STATUS_NO_MEMORY;
    2766             :         }
    2767             : 
    2768             :         /* Fill forest trust information, do expand UPN suffixes list */
    2769           0 :         status = fill_forest_trust_array(p->mem_ctx, info);
    2770           0 :         if (!NT_STATUS_IS_OK(status)) {
    2771           0 :                 return status;
    2772             :         }
    2773             : 
    2774           0 :         *info_ptr = info;
    2775           0 :         r->out.forest_trust_info = info_ptr;
    2776             : 
    2777           0 :         return NT_STATUS_OK;
    2778             : }
    2779             : 
    2780             : /****************************************************************
    2781             : ****************************************************************/
    2782             : 
    2783           0 : static NTSTATUS get_password_from_trustAuth(TALLOC_CTX *mem_ctx,
    2784             :                                             const DATA_BLOB *trustAuth_blob,
    2785             :                                             struct netlogon_creds_CredentialState *creds,
    2786             :                                             struct samr_Password *current_pw_enc,
    2787             :                                             struct samr_Password *previous_pw_enc)
    2788             : {
    2789             :         enum ndr_err_code ndr_err;
    2790             :         struct trustAuthInOutBlob trustAuth;
    2791             :         NTSTATUS status;
    2792             : 
    2793           0 :         ndr_err = ndr_pull_struct_blob_all(trustAuth_blob, mem_ctx, &trustAuth,
    2794             :                                            (ndr_pull_flags_fn_t)ndr_pull_trustAuthInOutBlob);
    2795           0 :         if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
    2796           0 :                 return NT_STATUS_UNSUCCESSFUL;
    2797             :         }
    2798             : 
    2799           0 :         if (trustAuth.count != 0 && trustAuth.current.count != 0 &&
    2800           0 :             trustAuth.current.array[0].AuthType == TRUST_AUTH_TYPE_CLEAR) {
    2801           0 :                 mdfour(current_pw_enc->hash,
    2802           0 :                        trustAuth.current.array[0].AuthInfo.clear.password,
    2803           0 :                        trustAuth.current.array[0].AuthInfo.clear.size);
    2804           0 :                 status = netlogon_creds_des_encrypt(creds, current_pw_enc);
    2805           0 :                 if (!NT_STATUS_IS_OK(status)) {
    2806           0 :                         return status;
    2807             :                 }
    2808             :         } else {
    2809           0 :                 return NT_STATUS_UNSUCCESSFUL;
    2810             :         }
    2811             : 
    2812             : 
    2813           0 :         if (trustAuth.previous.count != 0 &&
    2814           0 :             trustAuth.previous.array[0].AuthType == TRUST_AUTH_TYPE_CLEAR) {
    2815           0 :                 mdfour(previous_pw_enc->hash,
    2816           0 :                        trustAuth.previous.array[0].AuthInfo.clear.password,
    2817           0 :                        trustAuth.previous.array[0].AuthInfo.clear.size);
    2818           0 :                 status = netlogon_creds_des_encrypt(creds, previous_pw_enc);
    2819           0 :                 if (!NT_STATUS_IS_OK(status)) {
    2820           0 :                         return status;
    2821             :                 }
    2822             :         } else {
    2823           0 :                 ZERO_STRUCTP(previous_pw_enc);
    2824             :         }
    2825             : 
    2826           0 :         return NT_STATUS_OK;
    2827             : }
    2828             : 
    2829             : /****************************************************************
    2830             :  _netr_ServerGetTrustInfo
    2831             : ****************************************************************/
    2832             : 
    2833           0 : NTSTATUS _netr_ServerGetTrustInfo(struct pipes_struct *p,
    2834             :                                   struct netr_ServerGetTrustInfo *r)
    2835             : {
    2836             :         NTSTATUS status;
    2837             :         struct netlogon_creds_CredentialState *creds;
    2838             :         char *account_name;
    2839             :         size_t account_name_last;
    2840             :         bool trusted;
    2841             :         struct netr_TrustInfo *trust_info;
    2842             :         struct pdb_trusted_domain *td;
    2843             : 
    2844             :         /* TODO: check server name */
    2845             : 
    2846           0 :         become_root();
    2847           0 :         status = netr_creds_server_step_check(p, p->mem_ctx,
    2848             :                                               r->in.computer_name,
    2849             :                                               r->in.credential,
    2850             :                                               r->out.return_authenticator,
    2851             :                                               &creds);
    2852           0 :         unbecome_root();
    2853           0 :         if (!NT_STATUS_IS_OK(status)) {
    2854           0 :                 return status;
    2855             :         }
    2856             : 
    2857           0 :         account_name = talloc_strdup(p->mem_ctx, r->in.account_name);
    2858           0 :         if (account_name == NULL) {
    2859           0 :                 return NT_STATUS_NO_MEMORY;
    2860             :         }
    2861             : 
    2862           0 :         account_name_last = strlen(account_name);
    2863           0 :         if (account_name_last == 0) {
    2864           0 :                 return NT_STATUS_INVALID_PARAMETER;
    2865             :         }
    2866           0 :         account_name_last--;
    2867           0 :         if (account_name[account_name_last] == '.') {
    2868           0 :                 account_name[account_name_last] = '\0';
    2869             :         }
    2870             : 
    2871           0 :         if ((creds->secure_channel_type != SEC_CHAN_DNS_DOMAIN) &&
    2872           0 :             (creds->secure_channel_type != SEC_CHAN_DOMAIN)) {
    2873           0 :                 trusted = false;
    2874             :         } else {
    2875           0 :                 trusted = true;
    2876             :         }
    2877             : 
    2878             : 
    2879           0 :         if (trusted) {
    2880           0 :                 account_name_last = strlen(account_name);
    2881           0 :                 if (account_name_last == 0) {
    2882           0 :                         return NT_STATUS_INVALID_PARAMETER;
    2883             :                 }
    2884           0 :                 account_name_last--;
    2885           0 :                 if (account_name[account_name_last] == '$') {
    2886           0 :                         account_name[account_name_last] = '\0';
    2887             :                 }
    2888             : 
    2889           0 :                 status = pdb_get_trusted_domain(p->mem_ctx, account_name, &td);
    2890           0 :                 if (!NT_STATUS_IS_OK(status)) {
    2891           0 :                         return status;
    2892             :                 }
    2893             : 
    2894           0 :                 if (r->out.trust_info != NULL) {
    2895           0 :                         trust_info = talloc_zero(p->mem_ctx, struct netr_TrustInfo);
    2896           0 :                         if (trust_info == NULL) {
    2897           0 :                                 return NT_STATUS_NO_MEMORY;
    2898             :                         }
    2899           0 :                         trust_info->count = 1;
    2900             : 
    2901           0 :                         trust_info->data = talloc_array(trust_info, uint32_t, 1);
    2902           0 :                         if (trust_info->data == NULL) {
    2903           0 :                                 return NT_STATUS_NO_MEMORY;
    2904             :                         }
    2905           0 :                         trust_info->data[0] = td->trust_attributes;
    2906             : 
    2907           0 :                         *r->out.trust_info = trust_info;
    2908             :                 }
    2909             : 
    2910           0 :                 if (td->trust_auth_incoming.data == NULL) {
    2911           0 :                         return NT_STATUS_INVALID_PARAMETER;
    2912             :                 }
    2913             : 
    2914           0 :                 status = get_password_from_trustAuth(p->mem_ctx,
    2915           0 :                                                      &td->trust_auth_incoming,
    2916             :                                                      creds,
    2917             :                                                      r->out.new_owf_password,
    2918             :                                                      r->out.old_owf_password);
    2919             : 
    2920           0 :                 if (!NT_STATUS_IS_OK(status)) {
    2921           0 :                         return status;
    2922             :                 }
    2923             : 
    2924             :         } else {
    2925             : /* TODO: look for machine password */
    2926           0 :                 ZERO_STRUCTP(r->out.new_owf_password);
    2927           0 :                 ZERO_STRUCTP(r->out.old_owf_password);
    2928             : 
    2929           0 :                 return NT_STATUS_NOT_IMPLEMENTED;
    2930             :         }
    2931             : 
    2932           0 :         return NT_STATUS_OK;
    2933             : }
    2934             : 
    2935             : /****************************************************************
    2936             : ****************************************************************/
    2937             : 
    2938           0 : NTSTATUS _netr_Unused47(struct pipes_struct *p,
    2939             :                         struct netr_Unused47 *r)
    2940             : {
    2941           0 :         p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
    2942           0 :         return NT_STATUS_NOT_IMPLEMENTED;
    2943             : }
    2944             : 
    2945             : /****************************************************************
    2946             : ****************************************************************/
    2947             : 
    2948           0 : NTSTATUS _netr_DsrUpdateReadOnlyServerDnsRecords(struct pipes_struct *p,
    2949             :                                                  struct netr_DsrUpdateReadOnlyServerDnsRecords *r)
    2950             : {
    2951           0 :         p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
    2952           0 :         return NT_STATUS_NOT_IMPLEMENTED;
    2953             : }
    2954             : 
    2955             : /* include the generated boilerplate */
    2956             : #include "librpc/gen_ndr/ndr_netlogon_scompat.c"

Generated by: LCOV version 1.13