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 v4-17-test 1498b464 Lines: 248 1268 19.6 %
Date: 2024-06-13 04:01:37 Functions: 10 61 16.4 %

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

Generated by: LCOV version 1.13