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

Generated by: LCOV version 1.14