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 support-claim-type-attributes 6b5c566e Lines: 649 1375 47.2 %
Date: 2023-11-21 12:31:41 Functions: 19 61 31.1 %

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

Generated by: LCOV version 1.14