LCOV - code coverage report
Current view: top level - source3/winbindd - winbindd_irpc.c (source / functions) Hit Total Coverage
Test: coverage report for master 2b515b7d Lines: 30 420 7.1 %
Date: 2024-02-28 12:06:22 Functions: 2 16 12.5 %

          Line data    Source code
       1             : /*
       2             :    Unix SMB/CIFS implementation.
       3             :    async implementation of commands submitted over IRPC
       4             :    Copyright (C) Volker Lendecke 2009
       5             :    Copyright (C) Guenther Deschner 2009
       6             :    Copyright (C) Andrew Bartlett 2014
       7             :    Copyright (C) Andrew Tridgell 2009
       8             : 
       9             :    This program is free software; you can redistribute it and/or modify
      10             :    it under the terms of the GNU General Public License as published by
      11             :    the Free Software Foundation; either version 3 of the License, or
      12             :    (at your option) any later version.
      13             : 
      14             :    This program is distributed in the hope that it will be useful,
      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      17             :    GNU General Public License for more details.
      18             : 
      19             :    You should have received a copy of the GNU General Public License
      20             :    along with this program.  If not, see <http://www.gnu.org/licenses/>.
      21             : */
      22             : 
      23             : #include "includes.h"
      24             : #include "winbindd.h"
      25             : #include "librpc/gen_ndr/ndr_winbind_c.h"
      26             : #include "source4/lib/messaging/irpc.h"
      27             : #include "librpc/gen_ndr/ndr_winbind.h"
      28             : #include "librpc/gen_ndr/ndr_lsa.h"
      29             : #include "librpc/gen_ndr/ndr_lsa_c.h"
      30             : #include "libcli/security/dom_sid.h"
      31             : #include "passdb/lookup_sid.h" /* only for LOOKUP_NAME_NO_NSS flag */
      32             : #include "librpc/gen_ndr/ndr_irpc.h"
      33             : #include "librpc/gen_ndr/ndr_netlogon.h"
      34             : #include "lib/global_contexts.h"
      35             : #include "lib/param/param.h"
      36             : #include "messages.h"
      37             : 
      38         450 : struct imessaging_context *winbind_imessaging_context(void)
      39             : {
      40           0 :         static struct imessaging_context *msg = NULL;
      41           0 :         struct messaging_context *msg_ctx;
      42           0 :         struct server_id myself;
      43           0 :         struct loadparm_context *lp_ctx;
      44             : 
      45         450 :         if (msg != NULL) {
      46         405 :                 return msg;
      47             :         }
      48             : 
      49          45 :         msg_ctx = global_messaging_context();
      50          45 :         if (msg_ctx == NULL) {
      51           0 :                 smb_panic("global_messaging_context failed\n");
      52             :         }
      53          45 :         myself = messaging_server_id(msg_ctx);
      54             : 
      55          45 :         lp_ctx = loadparm_init_s3(NULL, loadparm_s3_helpers());
      56          45 :         if (lp_ctx == NULL) {
      57           0 :                 smb_panic("Could not load smb.conf to init winbindd's imessaging context.\n");
      58             :         }
      59             : 
      60             :         /*
      61             :          * Note we MUST use the NULL context here, not the autofree context,
      62             :          * to avoid side effects in forked children exiting.
      63             :          */
      64          45 :         msg = imessaging_init(NULL, lp_ctx, myself, global_event_context());
      65          45 :         talloc_unlink(NULL, lp_ctx);
      66             : 
      67          45 :         if (msg == NULL) {
      68           0 :                 smb_panic("Could not init winbindd's messaging context.\n");
      69             :         }
      70          45 :         return msg;
      71             : }
      72             : 
      73             : struct wb_irpc_forward_state {
      74             :         struct irpc_message *msg;
      75             :         const char *opname;
      76             :         struct dcesrv_call_state *dce_call;
      77             : };
      78             : 
      79             : /*
      80             :   called when the forwarded rpc request is finished
      81             :  */
      82           0 : static void wb_irpc_forward_callback(struct tevent_req *subreq)
      83             : {
      84           0 :         struct wb_irpc_forward_state *st =
      85           0 :                 tevent_req_callback_data(subreq,
      86             :                 struct wb_irpc_forward_state);
      87           0 :         const char *opname = st->opname;
      88           0 :         NTSTATUS status;
      89             : 
      90           0 :         status = dcerpc_binding_handle_call_recv(subreq);
      91           0 :         TALLOC_FREE(subreq);
      92           0 :         if (!NT_STATUS_IS_OK(status)) {
      93           0 :                 DEBUG(0,("RPC callback failed for %s - %s\n",
      94             :                          opname, nt_errstr(status)));
      95           0 :                 irpc_send_reply(st->msg, status);
      96           0 :                 return;
      97             :         }
      98             : 
      99           0 :         irpc_send_reply(st->msg, status);
     100             : }
     101             : 
     102             : 
     103             : 
     104             : /**
     105             :  * Forward a RPC call using IRPC to another task
     106             :  */
     107             : 
     108           0 : static NTSTATUS wb_irpc_forward_rpc_call(struct irpc_message *msg, TALLOC_CTX *mem_ctx,
     109             :                                          struct tevent_context *ev,
     110             :                                          void *r, uint32_t callid,
     111             :                                          const char *opname,
     112             :                                          struct winbindd_domain *domain,
     113             :                                          uint32_t timeout)
     114             : {
     115           0 :         struct wb_irpc_forward_state *st;
     116           0 :         struct dcerpc_binding_handle *binding_handle;
     117           0 :         struct tevent_req *subreq;
     118             : 
     119           0 :         st = talloc(mem_ctx, struct wb_irpc_forward_state);
     120           0 :         if (st == NULL) {
     121           0 :                 return NT_STATUS_NO_MEMORY;
     122             :         }
     123             : 
     124           0 :         st->msg = msg;
     125           0 :         st->opname   = opname;
     126             : 
     127           0 :         binding_handle =  dom_child_handle(domain);
     128           0 :         if (binding_handle == NULL) {
     129           0 :                 DEBUG(0,("%s: Failed to forward request to winbind handler for %s\n",
     130             :                          opname, domain->name));
     131           0 :                 return NT_STATUS_UNSUCCESSFUL;
     132             :         }
     133             : 
     134             :         /* reset timeout for the handle */
     135           0 :         dcerpc_binding_handle_set_timeout(binding_handle, timeout);
     136             : 
     137             :         /* forward the call */
     138           0 :         subreq = dcerpc_binding_handle_call_send(st, ev,
     139             :                                                  binding_handle,
     140             :                                                  NULL, &ndr_table_winbind,
     141             :                                                  callid,
     142             :                                                  msg, r);
     143           0 :         if (subreq == NULL) {
     144           0 :                 DEBUG(0,("%s: Failed to forward request to winbind handler for %s\n",
     145             :                          opname, domain->name));
     146           0 :                 return NT_STATUS_UNSUCCESSFUL;
     147             :         }
     148             : 
     149             :         /* mark the request as replied async */
     150           0 :         msg->defer_reply = true;
     151             : 
     152             :         /* setup the callback */
     153           0 :         tevent_req_set_callback(subreq, wb_irpc_forward_callback, st);
     154           0 :         return NT_STATUS_OK;
     155             : }
     156             : 
     157           0 : static NTSTATUS wb_irpc_DsrUpdateReadOnlyServerDnsRecords(struct irpc_message *msg,
     158             :                                                    struct winbind_DsrUpdateReadOnlyServerDnsRecords *req)
     159             : {
     160           0 :         struct winbindd_domain *domain = find_our_domain();
     161           0 :         if (domain == NULL) {
     162           0 :                 return NT_STATUS_NO_SUCH_DOMAIN;
     163             :         }
     164             : 
     165           0 :         DEBUG(5, ("wb_irpc_DsrUpdateReadOnlyServerDnsRecords called\n"));
     166             : 
     167           0 :         return wb_irpc_forward_rpc_call(msg, msg,
     168             :                                         global_event_context(),
     169             :                                         req, NDR_WINBIND_DSRUPDATEREADONLYSERVERDNSRECORDS,
     170             :                                         "winbind_DsrUpdateReadOnlyServerDnsRecords",
     171             :                                         domain, IRPC_CALL_TIMEOUT);
     172             : }
     173             : 
     174           0 : static NTSTATUS wb_irpc_SamLogon(struct irpc_message *msg,
     175             :                                  struct winbind_SamLogon *req)
     176             : {
     177           0 :         struct winbindd_domain *domain;
     178           0 :         struct netr_IdentityInfo *identity_info;
     179           0 :         const char *target_domain_name = NULL;
     180           0 :         const char *account_name = NULL;
     181             : 
     182             :         /*
     183             :          * Make sure we start with authoritative=true,
     184             :          * it will only set to false if we don't know the
     185             :          * domain.
     186             :          */
     187           0 :         req->out.authoritative = true;
     188             : 
     189           0 :         switch (req->in.logon_level) {
     190           0 :         case NetlogonInteractiveInformation:
     191             :         case NetlogonServiceInformation:
     192             :         case NetlogonInteractiveTransitiveInformation:
     193             :         case NetlogonServiceTransitiveInformation:
     194           0 :                 if (req->in.logon.password == NULL) {
     195           0 :                         return NT_STATUS_REQUEST_NOT_ACCEPTED;
     196             :                 }
     197           0 :                 identity_info = &req->in.logon.password->identity_info;
     198           0 :                 break;
     199             : 
     200           0 :         case NetlogonNetworkInformation:
     201             :         case NetlogonNetworkTransitiveInformation:
     202           0 :                 if (req->in.logon.network == NULL) {
     203           0 :                         return NT_STATUS_REQUEST_NOT_ACCEPTED;
     204             :                 }
     205             : 
     206           0 :                 identity_info = &req->in.logon.network->identity_info;
     207           0 :                 break;
     208             : 
     209           0 :         case NetlogonGenericInformation:
     210           0 :                 if (req->in.logon.generic == NULL) {
     211           0 :                         return NT_STATUS_REQUEST_NOT_ACCEPTED;
     212             :                 }
     213             : 
     214           0 :                 identity_info = &req->in.logon.generic->identity_info;
     215           0 :                 break;
     216             : 
     217           0 :         default:
     218           0 :                 return NT_STATUS_REQUEST_NOT_ACCEPTED;
     219             :         }
     220             : 
     221           0 :         target_domain_name = identity_info->domain_name.string;
     222           0 :         if (target_domain_name == NULL) {
     223           0 :                 target_domain_name = "";
     224             :         }
     225             : 
     226           0 :         account_name = identity_info->account_name.string;
     227           0 :         if (account_name == NULL) {
     228           0 :                 account_name = "";
     229             :         }
     230             : 
     231           0 :         if (IS_DC && target_domain_name[0] == '\0') {
     232           0 :                 const char *p = NULL;
     233             : 
     234           0 :                 p = strchr_m(account_name, '@');
     235           0 :                 if (p != NULL) {
     236           0 :                         target_domain_name = p + 1;
     237             :                 }
     238             :         }
     239             : 
     240           0 :         if (IS_DC && target_domain_name[0] == '\0') {
     241           0 :                 DBG_ERR("target_domain[%s] account[%s]\n",
     242             :                         target_domain_name, account_name);
     243           0 :                 return NT_STATUS_REQUEST_NOT_ACCEPTED;
     244             :         }
     245             : 
     246           0 :         domain = find_auth_domain(0, target_domain_name);
     247           0 :         if (domain == NULL) {
     248           0 :                 DBG_INFO("target_domain[%s] for account[%s] not known\n",
     249             :                         target_domain_name, account_name);
     250           0 :                 req->out.result = NT_STATUS_NO_SUCH_USER;
     251           0 :                 req->out.authoritative = 0;
     252           0 :                 return NT_STATUS_OK;
     253             :         }
     254             : 
     255           0 :         DEBUG(5, ("wb_irpc_SamLogon called\n"));
     256             : 
     257           0 :         return wb_irpc_forward_rpc_call(msg, msg,
     258             :                                         global_event_context(),
     259             :                                         req, NDR_WINBIND_SAMLOGON,
     260             :                                         "winbind_SamLogon",
     261             :                                         domain, IRPC_CALL_TIMEOUT);
     262             : }
     263             : 
     264           0 : static NTSTATUS wb_irpc_LogonControl(struct irpc_message *msg,
     265             :                                      struct winbind_LogonControl *req)
     266             : {
     267           0 :         TALLOC_CTX *frame = talloc_stackframe();
     268           0 :         char *domain_name = NULL;
     269           0 :         struct winbindd_domain *domain = NULL;
     270             : 
     271           0 :         DEBUG(5, ("wb_irpc_LogonControl called\n"));
     272             : 
     273           0 :         switch (req->in.function_code) {
     274           0 :         case NETLOGON_CONTROL_REDISCOVER:
     275             :         case NETLOGON_CONTROL_TC_QUERY:
     276             :         case NETLOGON_CONTROL_CHANGE_PASSWORD:
     277             :         case NETLOGON_CONTROL_TC_VERIFY:
     278           0 :                 if (req->in.data->domain == NULL) {
     279           0 :                         TALLOC_FREE(frame);
     280           0 :                         return NT_STATUS_INVALID_PARAMETER;
     281             :                 }
     282             : 
     283           0 :                 domain_name = talloc_strdup(frame, req->in.data->domain);
     284           0 :                 if (domain_name == NULL) {
     285           0 :                         req->out.result = WERR_NOT_ENOUGH_MEMORY;
     286           0 :                         TALLOC_FREE(frame);
     287           0 :                         return NT_STATUS_OK;
     288             :                 }
     289             : 
     290           0 :                 break;
     291           0 :         default:
     292           0 :                 TALLOC_FREE(frame);
     293           0 :                 return NT_STATUS_NOT_IMPLEMENTED;
     294             :         }
     295             : 
     296           0 :         if (req->in.function_code == NETLOGON_CONTROL_REDISCOVER) {
     297           0 :                 char *p = NULL;
     298             : 
     299             :                 /*
     300             :                  * NETLOGON_CONTROL_REDISCOVER
     301             :                  * gets an optional \dcname appended to the domain name
     302             :                  */
     303           0 :                 p = strchr_m(domain_name, '\\');
     304           0 :                 if (p != NULL) {
     305           0 :                         *p = '\0';
     306             :                 }
     307             :         }
     308             : 
     309           0 :         domain = find_domain_from_name_noinit(domain_name);
     310           0 :         if (domain == NULL) {
     311           0 :                 req->out.result = WERR_NO_SUCH_DOMAIN;
     312           0 :                 TALLOC_FREE(frame);
     313           0 :                 return NT_STATUS_OK;
     314             :         }
     315             : 
     316           0 :         TALLOC_FREE(frame);
     317           0 :         return wb_irpc_forward_rpc_call(msg, msg,
     318             :                                         global_event_context(),
     319             :                                         req, NDR_WINBIND_LOGONCONTROL,
     320             :                                         "winbind_LogonControl",
     321             :                                         domain, 45 /* timeout */);
     322             : }
     323             : 
     324           0 : static NTSTATUS wb_irpc_GetForestTrustInformation(struct irpc_message *msg,
     325             :                                      struct winbind_GetForestTrustInformation *req)
     326             : {
     327           0 :         struct winbindd_domain *domain = NULL;
     328             : 
     329           0 :         if (req->in.trusted_domain_name == NULL) {
     330           0 :                 req->out.result = WERR_NO_SUCH_DOMAIN;
     331           0 :                 return NT_STATUS_OK;
     332             :         }
     333             : 
     334           0 :         domain = find_trust_from_name_noinit(req->in.trusted_domain_name);
     335           0 :         if (domain == NULL) {
     336           0 :                 req->out.result = WERR_NO_SUCH_DOMAIN;
     337           0 :                 return NT_STATUS_OK;
     338             :         }
     339             : 
     340             :         /*
     341             :          * checking for domain->internal and domain->primary
     342             :          * makes sure we only do some work when running as DC.
     343             :          */
     344             : 
     345           0 :         if (domain->internal) {
     346           0 :                 req->out.result = WERR_NO_SUCH_DOMAIN;
     347           0 :                 return NT_STATUS_OK;
     348             :         }
     349             : 
     350           0 :         if (domain->primary) {
     351           0 :                 req->out.result = WERR_NO_SUCH_DOMAIN;
     352           0 :                 return NT_STATUS_OK;
     353             :         }
     354             : 
     355           0 :         DEBUG(5, ("wb_irpc_GetForestTrustInformation called\n"));
     356             : 
     357           0 :         return wb_irpc_forward_rpc_call(msg, msg,
     358             :                                         global_event_context(),
     359             :                                         req, NDR_WINBIND_GETFORESTTRUSTINFORMATION,
     360             :                                         "winbind_GetForestTrustInformation",
     361             :                                         domain, 45 /* timeout */);
     362             : }
     363             : 
     364           0 : static NTSTATUS wb_irpc_SendToSam(struct irpc_message *msg,
     365             :                                   struct winbind_SendToSam *req)
     366             : {
     367             :         /* TODO make sure that it is RWDC */
     368           0 :         struct winbindd_domain *domain = find_our_domain();
     369           0 :         if (domain == NULL) {
     370           0 :                 return NT_STATUS_NO_SUCH_DOMAIN;
     371             :         }
     372             : 
     373           0 :         DEBUG(5, ("wb_irpc_SendToSam called\n"));
     374             : 
     375           0 :         return wb_irpc_forward_rpc_call(msg, msg,
     376             :                                         global_event_context(),
     377             :                                         req, NDR_WINBIND_SENDTOSAM,
     378             :                                         "winbind_SendToSam",
     379             :                                         domain, IRPC_CALL_TIMEOUT);
     380             : }
     381             : 
     382             : struct wb_irpc_lsa_LookupSids3_state {
     383             :         struct irpc_message *msg;
     384             :         struct lsa_LookupSids3 *req;
     385             : };
     386             : 
     387             : static void wb_irpc_lsa_LookupSids3_done(struct tevent_req *subreq);
     388             : 
     389           0 : static NTSTATUS wb_irpc_lsa_LookupSids3_call(struct irpc_message *msg,
     390             :                                              struct lsa_LookupSids3 *req)
     391             : {
     392           0 :         struct wb_irpc_lsa_LookupSids3_state *state = NULL;
     393           0 :         struct tevent_req *subreq = NULL;
     394           0 :         struct dom_sid *sids = NULL;
     395           0 :         uint32_t i;
     396             : 
     397           0 :         state = talloc_zero(msg, struct wb_irpc_lsa_LookupSids3_state);
     398           0 :         if (state == NULL) {
     399           0 :                 return NT_STATUS_NO_MEMORY;
     400             :         }
     401             : 
     402           0 :         state->msg = msg;
     403           0 :         state->req = req;
     404             : 
     405           0 :         state->req->out.domains = talloc_zero(state->msg,
     406             :                                         struct lsa_RefDomainList *);
     407           0 :         if (state->req->out.domains == NULL) {
     408           0 :                 return NT_STATUS_NO_MEMORY;
     409             :         }
     410           0 :         state->req->out.names = talloc_zero(state->msg,
     411             :                                             struct lsa_TransNameArray2);
     412           0 :         if (state->req->out.names == NULL) {
     413           0 :                 return NT_STATUS_NO_MEMORY;
     414             :         }
     415           0 :         state->req->out.count = talloc_zero(state->msg, uint32_t);
     416           0 :         if (state->req->out.count == NULL) {
     417           0 :                 return NT_STATUS_NO_MEMORY;
     418             :         }
     419             : 
     420           0 :         state->req->out.names->names = talloc_zero_array(state->msg,
     421             :                                                 struct lsa_TranslatedName2,
     422             :                                                 req->in.sids->num_sids);
     423           0 :         if (state->req->out.names->names == NULL) {
     424           0 :                 return NT_STATUS_NO_MEMORY;
     425             :         }
     426             : 
     427           0 :         sids = talloc_zero_array(state, struct dom_sid,
     428             :                                  req->in.sids->num_sids);
     429           0 :         if (sids == NULL) {
     430           0 :                 return NT_STATUS_NO_MEMORY;
     431             :         }
     432             : 
     433           0 :         for (i = 0; i < req->in.sids->num_sids; i++) {
     434           0 :                 if (req->in.sids->sids[i].sid == NULL) {
     435           0 :                         return NT_STATUS_REQUEST_NOT_ACCEPTED;
     436             :                 }
     437             : 
     438           0 :                 sids[i] = *req->in.sids->sids[i].sid;
     439             :         }
     440             : 
     441           0 :         subreq = wb_lookupsids_send(msg,
     442             :                                     global_event_context(),
     443           0 :                                     sids, req->in.sids->num_sids);
     444           0 :         if (subreq == NULL) {
     445           0 :                 return NT_STATUS_NO_MEMORY;
     446             :         }
     447           0 :         tevent_req_set_callback(subreq, wb_irpc_lsa_LookupSids3_done, state);
     448           0 :         msg->defer_reply = true;
     449             : 
     450           0 :         return NT_STATUS_OK;
     451             : }
     452             : 
     453           0 : static void wb_irpc_lsa_LookupSids3_done(struct tevent_req *subreq)
     454             : {
     455           0 :         struct wb_irpc_lsa_LookupSids3_state *state =
     456           0 :                 tevent_req_callback_data(subreq,
     457             :                 struct wb_irpc_lsa_LookupSids3_state);
     458           0 :         struct lsa_RefDomainList *domains = NULL;
     459           0 :         struct lsa_TransNameArray *names = NULL;
     460           0 :         NTSTATUS status;
     461           0 :         uint32_t i;
     462             : 
     463           0 :         status = wb_lookupsids_recv(subreq, state->msg,
     464             :                                     &domains, &names);
     465           0 :         TALLOC_FREE(subreq);
     466           0 :         if (!NT_STATUS_IS_OK(status)) {
     467           0 :                 DEBUG(0,("RPC callback failed for %s - %s\n",
     468             :                          __func__, nt_errstr(status)));
     469           0 :                 irpc_send_reply(state->msg, status);
     470           0 :                 return;
     471             :         }
     472             : 
     473           0 :         if (names->count > state->req->in.sids->num_sids) {
     474           0 :                 status = NT_STATUS_INTERNAL_ERROR;
     475           0 :                 DEBUG(0,("RPC callback failed for %s - %s\n",
     476             :                          __func__, nt_errstr(status)));
     477           0 :                 irpc_send_reply(state->msg, status);
     478           0 :                 return;
     479             :         }
     480             : 
     481           0 :         *state->req->out.domains = domains;
     482           0 :         for (i = 0; i < names->count; i++) {
     483           0 :                 struct lsa_TranslatedName2 *n2 =
     484           0 :                         &state->req->out.names->names[i];
     485             : 
     486           0 :                 n2->sid_type = names->names[i].sid_type;
     487           0 :                 n2->name = names->names[i].name;
     488           0 :                 n2->sid_index = names->names[i].sid_index;
     489           0 :                 n2->unknown = 0;
     490             : 
     491           0 :                 if (n2->sid_type != SID_NAME_UNKNOWN) {
     492           0 :                         (*state->req->out.count)++;
     493             :                 }
     494             :         }
     495           0 :         state->req->out.names->count = names->count;
     496             : 
     497           0 :         if (*state->req->out.count == 0) {
     498           0 :                 state->req->out.result = NT_STATUS_NONE_MAPPED;
     499           0 :         } else if (*state->req->out.count != names->count) {
     500           0 :                 state->req->out.result = NT_STATUS_SOME_NOT_MAPPED;
     501             :         } else {
     502           0 :                 state->req->out.result = NT_STATUS_OK;
     503             :         }
     504             : 
     505           0 :         irpc_send_reply(state->msg, NT_STATUS_OK);
     506           0 :         return;
     507             : }
     508             : 
     509             : struct wb_irpc_lsa_LookupNames4_name {
     510             :         void *state;
     511             :         uint32_t idx;
     512             :         const char *namespace;
     513             :         const char *domain;
     514             :         char *name;
     515             :         struct dom_sid sid;
     516             :         enum lsa_SidType type;
     517             :         struct dom_sid *authority_sid;
     518             : };
     519             : 
     520             : struct wb_irpc_lsa_LookupNames4_state {
     521             :         struct irpc_message *msg;
     522             :         struct lsa_LookupNames4 *req;
     523             :         struct wb_irpc_lsa_LookupNames4_name *names;
     524             :         uint32_t num_pending;
     525             :         uint32_t num_domain_sids;
     526             :         struct dom_sid *domain_sids;
     527             : };
     528             : 
     529             : static void wb_irpc_lsa_LookupNames4_done(struct tevent_req *subreq);
     530             : 
     531           0 : static NTSTATUS wb_irpc_lsa_LookupNames4_call(struct irpc_message *msg,
     532             :                                               struct lsa_LookupNames4 *req)
     533             : {
     534           0 :         struct wb_irpc_lsa_LookupNames4_state *state = NULL;
     535           0 :         struct tevent_req *subreq = NULL;
     536           0 :         uint32_t i;
     537             : 
     538             : 
     539           0 :         state = talloc_zero(msg, struct wb_irpc_lsa_LookupNames4_state);
     540           0 :         if (state == NULL) {
     541           0 :                 return NT_STATUS_NO_MEMORY;
     542             :         }
     543             : 
     544           0 :         state->msg = msg;
     545           0 :         state->req = req;
     546             : 
     547           0 :         state->req->out.domains = talloc_zero(state->msg,
     548             :                                         struct lsa_RefDomainList *);
     549           0 :         if (state->req->out.domains == NULL) {
     550           0 :                 return NT_STATUS_NO_MEMORY;
     551             :         }
     552           0 :         state->req->out.sids = talloc_zero(state->msg,
     553             :                                            struct lsa_TransSidArray3);
     554           0 :         if (state->req->out.sids == NULL) {
     555           0 :                 return NT_STATUS_NO_MEMORY;
     556             :         }
     557           0 :         state->req->out.count = talloc_zero(state->msg, uint32_t);
     558           0 :         if (state->req->out.count == NULL) {
     559           0 :                 return NT_STATUS_NO_MEMORY;
     560             :         }
     561             : 
     562           0 :         state->req->out.sids->sids = talloc_zero_array(state->msg,
     563             :                                                 struct lsa_TranslatedSid3,
     564             :                                                 req->in.num_names);
     565           0 :         if (state->req->out.sids->sids == NULL) {
     566           0 :                 return NT_STATUS_NO_MEMORY;
     567             :         }
     568             : 
     569           0 :         state->names = talloc_zero_array(state,
     570             :                                          struct wb_irpc_lsa_LookupNames4_name,
     571             :                                          req->in.num_names);
     572           0 :         if (state->names == NULL) {
     573           0 :                 return NT_STATUS_NO_MEMORY;
     574             :         }
     575             : 
     576           0 :         for (i = 0; i < req->in.num_names; i++) {
     577           0 :                 struct wb_irpc_lsa_LookupNames4_name *nstate =
     578           0 :                         &state->names[i];
     579           0 :                 char *p = NULL;
     580             : 
     581           0 :                 if (req->in.names[i].string == NULL) {
     582           0 :                         DBG_ERR("%s: name[%s] NT_STATUS_REQUEST_NOT_ACCEPTED.\n",
     583             :                                 __location__, req->in.names[i].string);
     584           0 :                         return NT_STATUS_REQUEST_NOT_ACCEPTED;
     585             :                 }
     586           0 :                 nstate->state = state;
     587           0 :                 nstate->idx = i;
     588           0 :                 nstate->name = talloc_strdup(state->names,
     589           0 :                                              req->in.names[i].string);
     590           0 :                 if (nstate->name == NULL) {
     591           0 :                         return NT_STATUS_NO_MEMORY;
     592             :                 }
     593           0 :                 nstate->type = SID_NAME_UNKNOWN;
     594             : 
     595             :                 /* cope with the name being a fully qualified name */
     596           0 :                 p = strchr(nstate->name, '\\');
     597           0 :                 if (p != NULL) {
     598           0 :                         *p = 0;
     599           0 :                         nstate->domain = nstate->name;
     600           0 :                         nstate->namespace = nstate->domain;
     601           0 :                         nstate->name = p+1;
     602           0 :                 } else if ((p = strchr(nstate->name, '@')) != NULL) {
     603             :                         /* upn */
     604           0 :                         nstate->domain = "";
     605           0 :                         nstate->namespace = p + 1;
     606             :                 } else {
     607             :                         /*
     608             :                          * TODO: select the domain based on
     609             :                          * req->in.level and req->in.client_revision
     610             :                          *
     611             :                          * For now we don't allow this.
     612             :                          */
     613           0 :                         DBG_ERR("%s: name[%s] NT_STATUS_REQUEST_NOT_ACCEPTED.\n",
     614             :                                 __location__, nstate->name);
     615           0 :                         return NT_STATUS_REQUEST_NOT_ACCEPTED;
     616             :                 }
     617             : 
     618           0 :                 subreq = wb_lookupname_send(msg,
     619             :                                             global_event_context(),
     620             :                                             nstate->namespace,
     621             :                                             nstate->domain,
     622           0 :                                             nstate->name,
     623             :                                             LOOKUP_NAME_NO_NSS);
     624           0 :                 if (subreq == NULL) {
     625           0 :                         return NT_STATUS_NO_MEMORY;
     626             :                 }
     627           0 :                 tevent_req_set_callback(subreq,
     628             :                                         wb_irpc_lsa_LookupNames4_done,
     629             :                                         nstate);
     630           0 :                 state->num_pending++;
     631             :         }
     632             : 
     633           0 :         msg->defer_reply = true;
     634             : 
     635           0 :         return NT_STATUS_OK;
     636             : }
     637             : 
     638             : static void wb_irpc_lsa_LookupNames4_domains_done(struct tevent_req *subreq);
     639             : 
     640           0 : static void wb_irpc_lsa_LookupNames4_done(struct tevent_req *subreq)
     641             : {
     642           0 :         struct wb_irpc_lsa_LookupNames4_name *nstate =
     643             :                 (struct wb_irpc_lsa_LookupNames4_name *)
     644           0 :                 tevent_req_callback_data_void(subreq);
     645           0 :         struct wb_irpc_lsa_LookupNames4_state *state =
     646           0 :                 talloc_get_type_abort(nstate->state,
     647             :                 struct wb_irpc_lsa_LookupNames4_state);
     648           0 :         struct dom_sid_buf buf;
     649           0 :         NTSTATUS status;
     650             : 
     651           0 :         SMB_ASSERT(state->num_pending > 0);
     652           0 :         state->num_pending--;
     653           0 :         status = wb_lookupname_recv(subreq, &nstate->sid, &nstate->type);
     654           0 :         TALLOC_FREE(subreq);
     655           0 :         if (!NT_STATUS_IS_OK(status)) {
     656           0 :                 DEBUG(0,("RPC callback failed for %s - %s\n",
     657             :                          __func__, nt_errstr(status)));
     658           0 :                 irpc_send_reply(state->msg, status);
     659           0 :                 return;
     660             :         }
     661             : 
     662           0 :         status = dom_sid_split_rid(state, &nstate->sid,
     663             :                                    &nstate->authority_sid, NULL);
     664           0 :         if (!NT_STATUS_IS_OK(status)) {
     665           0 :                 DBG_ERR("dom_sid_split_rid(%s) failed - %s\n",
     666             :                         dom_sid_str_buf(&nstate->sid, &buf),
     667             :                         nt_errstr(status));
     668           0 :                 irpc_send_reply(state->msg, status);
     669           0 :                 return;
     670             :         }
     671             : 
     672           0 :         status = add_sid_to_array_unique(state,
     673           0 :                                          nstate->authority_sid,
     674             :                                          &state->domain_sids,
     675             :                                          &state->num_domain_sids);
     676           0 :         if (!NT_STATUS_IS_OK(status)) {
     677           0 :                 DBG_ERR("add_sid_to_array_unique(%s) failed - %s\n",
     678             :                         dom_sid_str_buf(nstate->authority_sid, &buf),
     679             :                         nt_errstr(status));
     680           0 :                 irpc_send_reply(state->msg, status);
     681           0 :                 return;
     682             :         }
     683             : 
     684           0 :         if (state->num_pending > 0) {
     685             :                 /*
     686             :                  * wait for more...
     687             :                  */
     688           0 :                 return;
     689             :         }
     690             : 
     691             :         /*
     692             :          * Now resolve all domains back to a name
     693             :          * to get a good lsa_RefDomainList
     694             :          */
     695           0 :         subreq = wb_lookupsids_send(state,
     696             :                                     global_event_context(),
     697             :                                     state->domain_sids,
     698             :                                     state->num_domain_sids);
     699           0 :         if (subreq == NULL) {
     700           0 :                 status = NT_STATUS_NO_MEMORY;
     701           0 :                 DBG_ERR("wb_lookupsids_send - %s\n",
     702             :                         nt_errstr(status));
     703           0 :                 irpc_send_reply(state->msg, status);
     704           0 :                 return;
     705             :         }
     706           0 :         tevent_req_set_callback(subreq,
     707             :                                 wb_irpc_lsa_LookupNames4_domains_done,
     708             :                                 state);
     709             : 
     710           0 :         return;
     711             : }
     712             : 
     713           0 : static void wb_irpc_lsa_LookupNames4_domains_done(struct tevent_req *subreq)
     714             : {
     715           0 :         struct wb_irpc_lsa_LookupNames4_state *state =
     716           0 :                 tevent_req_callback_data(subreq,
     717             :                 struct wb_irpc_lsa_LookupNames4_state);
     718           0 :         struct lsa_RefDomainList *domains = NULL;
     719           0 :         struct lsa_TransNameArray *names = NULL;
     720           0 :         NTSTATUS status;
     721           0 :         uint32_t i;
     722             : 
     723           0 :         status = wb_lookupsids_recv(subreq, state->msg,
     724             :                                     &domains, &names);
     725           0 :         TALLOC_FREE(subreq);
     726           0 :         if (!NT_STATUS_IS_OK(status)) {
     727           0 :                 DEBUG(0,("RPC callback failed for %s - %s\n",
     728             :                          __func__, nt_errstr(status)));
     729           0 :                 irpc_send_reply(state->msg, status);
     730           0 :                 return;
     731             :         }
     732             : 
     733           0 :         *state->req->out.domains = domains;
     734           0 :         for (i = 0; i < state->req->in.num_names; i++) {
     735           0 :                 struct wb_irpc_lsa_LookupNames4_name *nstate =
     736           0 :                         &state->names[i];
     737           0 :                 struct lsa_TranslatedSid3 *s3 =
     738           0 :                         &state->req->out.sids->sids[i];
     739           0 :                 uint32_t di;
     740             : 
     741           0 :                 s3->sid_type = nstate->type;
     742           0 :                 if (s3->sid_type != SID_NAME_UNKNOWN) {
     743           0 :                         s3->sid = &nstate->sid;
     744             :                 } else {
     745           0 :                         s3->sid = NULL;
     746             :                 }
     747           0 :                 s3->sid_index = UINT32_MAX;
     748           0 :                 for (di = 0; di < domains->count; di++) {
     749           0 :                         bool match;
     750             : 
     751           0 :                         if (domains->domains[di].sid == NULL) {
     752           0 :                                 continue;
     753             :                         }
     754             : 
     755           0 :                         match = dom_sid_equal(nstate->authority_sid,
     756           0 :                                               domains->domains[di].sid);
     757           0 :                         if (match) {
     758           0 :                                 s3->sid_index = di;
     759           0 :                                 break;
     760             :                         }
     761             :                 }
     762           0 :                 if (s3->sid_type != SID_NAME_UNKNOWN) {
     763           0 :                         (*state->req->out.count)++;
     764             :                 }
     765             :         }
     766           0 :         state->req->out.sids->count = state->req->in.num_names;
     767             : 
     768           0 :         if (*state->req->out.count == 0) {
     769           0 :                 state->req->out.result = NT_STATUS_NONE_MAPPED;
     770           0 :         } else if (*state->req->out.count != state->req->in.num_names) {
     771           0 :                 state->req->out.result = NT_STATUS_SOME_NOT_MAPPED;
     772             :         } else {
     773           0 :                 state->req->out.result = NT_STATUS_OK;
     774             :         }
     775             : 
     776           0 :         irpc_send_reply(state->msg, NT_STATUS_OK);
     777           0 :         return;
     778             : }
     779             : 
     780             : struct wb_irpc_GetDCName_state {
     781             :         struct irpc_message *msg;
     782             :         struct wbint_DsGetDcName *req;
     783             : };
     784             : 
     785             : static void wb_irpc_GetDCName_done(struct tevent_req *subreq);
     786             : 
     787           0 : static NTSTATUS wb_irpc_GetDCName(struct irpc_message *msg,
     788             :                                   struct wbint_DsGetDcName *req)
     789             : {
     790             : 
     791           0 :         struct tevent_req *subreq = NULL;
     792           0 :         struct wb_irpc_GetDCName_state *state = NULL;
     793             : 
     794           0 :         state = talloc_zero(msg, struct wb_irpc_GetDCName_state);
     795           0 :         if (state == NULL) {
     796           0 :                 return NT_STATUS_NO_MEMORY;
     797             :         }
     798             : 
     799           0 :         state->msg = msg;
     800           0 :         state->req = req;
     801             : 
     802           0 :         subreq = wb_dsgetdcname_send(msg,
     803             :                                      global_event_context(),
     804             :                                      req->in.domain_name,
     805           0 :                                      req->in.domain_guid,
     806             :                                      req->in.site_name,
     807             :                                      req->in.flags);
     808           0 :         if (subreq == NULL) {
     809           0 :                 return NT_STATUS_NO_MEMORY;
     810             :         }
     811             : 
     812           0 :         tevent_req_set_callback(subreq,
     813             :                                 wb_irpc_GetDCName_done,
     814             :                                 state);
     815             : 
     816           0 :         msg->defer_reply = true;
     817             : 
     818           0 :         return NT_STATUS_OK;
     819             : }
     820             : 
     821           0 : static void wb_irpc_GetDCName_done(struct tevent_req *subreq)
     822             : {
     823           0 :         struct wb_irpc_GetDCName_state *state = tevent_req_callback_data(
     824             :                 subreq, struct wb_irpc_GetDCName_state);
     825           0 :         NTSTATUS status;
     826             : 
     827           0 :         status = wb_dsgetdcname_recv(subreq, state->msg,
     828           0 :                                      state->req->out.dc_info);
     829           0 :         TALLOC_FREE(subreq);
     830           0 :         if (!NT_STATUS_IS_OK(status)) {
     831           0 :                 DBG_INFO("RPC callback failed for %s - %s\n", "DSGETDCNAME",
     832             :                          nt_errstr(status));
     833             :         }
     834             : 
     835           0 :         state->req->out.result = status;
     836             : 
     837           0 :         irpc_send_reply(state->msg, NT_STATUS_OK);
     838           0 : }
     839             : 
     840          45 : NTSTATUS wb_irpc_register(void)
     841             : {
     842           0 :         NTSTATUS status;
     843             : 
     844          45 :         status = IRPC_REGISTER(winbind_imessaging_context(), winbind, WINBIND_DSRUPDATEREADONLYSERVERDNSRECORDS,
     845             :                                wb_irpc_DsrUpdateReadOnlyServerDnsRecords, NULL);
     846          45 :         if (!NT_STATUS_IS_OK(status)) {
     847           0 :                 return status;
     848             :         }
     849          45 :         status = IRPC_REGISTER(winbind_imessaging_context(), winbind, WINBIND_SAMLOGON,
     850             :                                wb_irpc_SamLogon, NULL);
     851          45 :         if (!NT_STATUS_IS_OK(status)) {
     852           0 :                 return status;
     853             :         }
     854          45 :         status = IRPC_REGISTER(winbind_imessaging_context(), winbind,
     855             :                                WINBIND_LOGONCONTROL,
     856             :                                wb_irpc_LogonControl, NULL);
     857          45 :         if (!NT_STATUS_IS_OK(status)) {
     858           0 :                 return status;
     859             :         }
     860          45 :         status = IRPC_REGISTER(winbind_imessaging_context(), winbind,
     861             :                                WINBIND_GETFORESTTRUSTINFORMATION,
     862             :                                wb_irpc_GetForestTrustInformation, NULL);
     863          45 :         if (!NT_STATUS_IS_OK(status)) {
     864           0 :                 return status;
     865             :         }
     866          45 :         status = IRPC_REGISTER(winbind_imessaging_context(), winbind, WINBIND_SENDTOSAM,
     867             :                                wb_irpc_SendToSam, NULL);
     868          45 :         if (!NT_STATUS_IS_OK(status)) {
     869           0 :                 return status;
     870             :         }
     871          45 :         status = IRPC_REGISTER(winbind_imessaging_context(),
     872             :                                lsarpc, LSA_LOOKUPSIDS3,
     873             :                                wb_irpc_lsa_LookupSids3_call, NULL);
     874          45 :         if (!NT_STATUS_IS_OK(status)) {
     875           0 :                 return status;
     876             :         }
     877          45 :         status = IRPC_REGISTER(winbind_imessaging_context(),
     878             :                                lsarpc, LSA_LOOKUPNAMES4,
     879             :                                wb_irpc_lsa_LookupNames4_call, NULL);
     880          45 :         if (!NT_STATUS_IS_OK(status)) {
     881           0 :                 return status;
     882             :         }
     883          45 :         status = IRPC_REGISTER(winbind_imessaging_context(),
     884             :                                winbind, WBINT_DSGETDCNAME,
     885             :                                wb_irpc_GetDCName, NULL);
     886          45 :         if (!NT_STATUS_IS_OK(status)) {
     887           0 :                 return status;
     888             :         }
     889             : 
     890          45 :         return NT_STATUS_OK;
     891             : }

Generated by: LCOV version 1.14