LCOV - code coverage report
Current view: top level - source3/winbindd - winbindd_samr.c (source / functions) Hit Total Coverage
Test: coverage report for master 70ed9daf Lines: 0 668 0.0 %
Date: 2024-01-11 09:59:51 Functions: 0 21 0.0 %

          Line data    Source code
       1             : /*
       2             :  * Unix SMB/CIFS implementation.
       3             :  *
       4             :  * Winbind rpc backend functions
       5             :  *
       6             :  * Copyright (c) 2000-2003 Tim Potter
       7             :  * Copyright (c) 2001      Andrew Tridgell
       8             :  * Copyright (c) 2005      Volker Lendecke
       9             :  * Copyright (c) 2008      Guenther Deschner (pidl conversion)
      10             :  * Copyright (c) 2010      Andreas Schneider <asn@samba.org>
      11             :  *
      12             :  * This program is free software; you can redistribute it and/or modify
      13             :  * it under the terms of the GNU General Public License as published by
      14             :  * the Free Software Foundation; either version 3 of the License, or
      15             :  * (at your option) any later version.
      16             :  *
      17             :  * This program is distributed in the hope that it will be useful,
      18             :  * but WITHOUT ANY WARRANTY; without even the implied warranty of
      19             :  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      20             :  * GNU General Public License for more details.
      21             :  *
      22             :  * You should have received a copy of the GNU General Public License
      23             :  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
      24             :  */
      25             : 
      26             : #include "includes.h"
      27             : #include "winbindd.h"
      28             : #include "winbindd_rpc.h"
      29             : #include "lib/util_unixsids.h"
      30             : #include "rpc_client/rpc_client.h"
      31             : #include "rpc_client/cli_pipe.h"
      32             : #include "../librpc/gen_ndr/ndr_samr_c.h"
      33             : #include "rpc_client/cli_samr.h"
      34             : #include "../librpc/gen_ndr/ndr_lsa_c.h"
      35             : #include "rpc_client/cli_lsarpc.h"
      36             : #include "rpc_server/rpc_ncacn_np.h"
      37             : #include "../libcli/security/security.h"
      38             : #include "passdb/machine_sid.h"
      39             : #include "auth.h"
      40             : #include "source3/lib/global_contexts.h"
      41             : 
      42             : #undef DBGC_CLASS
      43             : #define DBGC_CLASS DBGC_WINBIND
      44             : 
      45             : /*
      46             :  * The other end of this won't go away easily, so we can trust it
      47             :  *
      48             :  * It is either a long-lived process with the same lifetime as
      49             :  * winbindd or a part of this process
      50             :  */
      51             : struct winbind_internal_pipes {
      52             :         struct tevent_timer *shutdown_timer;
      53             :         struct rpc_pipe_client *samr_pipe;
      54             :         struct policy_handle samr_domain_hnd;
      55             :         struct rpc_pipe_client *lsa_pipe;
      56             :         struct policy_handle lsa_hnd;
      57             : };
      58             : 
      59             : 
      60           0 : NTSTATUS open_internal_samr_conn(TALLOC_CTX *mem_ctx,
      61             :                                  struct winbindd_domain *domain,
      62             :                                  struct rpc_pipe_client **samr_pipe,
      63             :                                  struct policy_handle *samr_domain_hnd)
      64             : {
      65           0 :         NTSTATUS status, result;
      66           0 :         struct policy_handle samr_connect_hnd;
      67           0 :         struct dcerpc_binding_handle *b;
      68             : 
      69           0 :         status = wb_open_internal_pipe(mem_ctx, &ndr_table_samr, samr_pipe);
      70           0 :         if (!NT_STATUS_IS_OK(status)) {
      71           0 :                 DBG_ERR("Could not connect to %s pipe: %s\n",
      72             :                         ndr_table_samr.name, nt_errstr(status));
      73           0 :                 return status;
      74             :         }
      75             : 
      76           0 :         b = (*samr_pipe)->binding_handle;
      77             : 
      78           0 :         status = dcerpc_samr_Connect2(b, mem_ctx,
      79           0 :                                       (*samr_pipe)->desthost,
      80             :                                       SEC_FLAG_MAXIMUM_ALLOWED,
      81             :                                       &samr_connect_hnd,
      82             :                                       &result);
      83           0 :         if (!NT_STATUS_IS_OK(status)) {
      84           0 :                 return status;
      85             :         }
      86           0 :         if (!NT_STATUS_IS_OK(result)) {
      87           0 :                 return result;
      88             :         }
      89             : 
      90           0 :         status = dcerpc_samr_OpenDomain(b, mem_ctx,
      91             :                                         &samr_connect_hnd,
      92             :                                         SEC_FLAG_MAXIMUM_ALLOWED,
      93             :                                         &domain->sid,
      94             :                                         samr_domain_hnd,
      95             :                                         &result);
      96           0 :         if (!NT_STATUS_IS_OK(status)) {
      97           0 :                 return status;
      98             :         }
      99             : 
     100           0 :         return result;
     101             : }
     102             : 
     103           0 : NTSTATUS open_internal_lsa_conn(TALLOC_CTX *mem_ctx,
     104             :                                 struct rpc_pipe_client **lsa_pipe,
     105             :                                 struct policy_handle *lsa_hnd)
     106             : {
     107           0 :         NTSTATUS status;
     108             : 
     109           0 :         status = wb_open_internal_pipe(mem_ctx, &ndr_table_lsarpc, lsa_pipe);
     110           0 :         if (!NT_STATUS_IS_OK(status)) {
     111           0 :                 DBG_ERR("Could not connect to %s pipe: %s\n",
     112             :                         ndr_table_lsarpc.name, nt_errstr(status));
     113           0 :                 return status;
     114             :         }
     115             : 
     116           0 :         status = rpccli_lsa_open_policy((*lsa_pipe),
     117             :                                         mem_ctx,
     118             :                                         true,
     119             :                                         SEC_FLAG_MAXIMUM_ALLOWED,
     120             :                                         lsa_hnd);
     121             : 
     122           0 :         return status;
     123             : }
     124             : 
     125           0 : static void cached_internal_pipe_close(
     126             :         struct tevent_context *ev,
     127             :         struct tevent_timer *te,
     128             :         struct timeval current_time,
     129             :         void *private_data)
     130             : {
     131           0 :         struct winbindd_domain *domain = talloc_get_type_abort(
     132             :                 private_data, struct winbindd_domain);
     133             :         /*
     134             :          * Freeing samr_pipes closes the cached pipes.
     135             :          *
     136             :          * We can do a hard close because at the time of this commit
     137             :          * we only use synchronous calls to external pipes. So we can't
     138             :          * have any outstanding requests. Also, we don't set
     139             :          * dcerpc_binding_handle_set_sync_ev in winbind, so we don't
     140             :          * get nested event loops. Once we start to get async in
     141             :          * winbind children, we need to check for outstanding calls
     142             :          */
     143           0 :         TALLOC_FREE(domain->backend_data.samr_pipes);
     144           0 : }
     145             : 
     146           0 : static NTSTATUS open_cached_internal_pipe_conn(
     147             :         struct winbindd_domain *domain,
     148             :         struct rpc_pipe_client **samr_pipe,
     149             :         struct policy_handle *samr_domain_hnd,
     150             :         struct rpc_pipe_client **lsa_pipe,
     151             :         struct policy_handle *lsa_hnd)
     152             : {
     153           0 :         struct winbind_internal_pipes *internal_pipes =
     154             :                 domain->backend_data.samr_pipes;
     155             : 
     156           0 :         if (internal_pipes == NULL) {
     157           0 :                 TALLOC_CTX *frame = talloc_stackframe();
     158           0 :                 NTSTATUS status;
     159             : 
     160           0 :                 internal_pipes = talloc_zero(frame,
     161             :                                              struct winbind_internal_pipes);
     162             : 
     163           0 :                 status = open_internal_samr_conn(
     164             :                         internal_pipes,
     165             :                         domain,
     166             :                         &internal_pipes->samr_pipe,
     167             :                         &internal_pipes->samr_domain_hnd);
     168           0 :                 if (!NT_STATUS_IS_OK(status)) {
     169           0 :                         TALLOC_FREE(frame);
     170           0 :                         return status;
     171             :                 }
     172             : 
     173           0 :                 status = open_internal_lsa_conn(internal_pipes,
     174             :                                                 &internal_pipes->lsa_pipe,
     175             :                                                 &internal_pipes->lsa_hnd);
     176             : 
     177           0 :                 if (!NT_STATUS_IS_OK(status)) {
     178           0 :                         TALLOC_FREE(frame);
     179           0 :                         return status;
     180             :                 }
     181             : 
     182           0 :                 internal_pipes->shutdown_timer = tevent_add_timer(
     183             :                         global_event_context(),
     184             :                         internal_pipes,
     185             :                         timeval_current_ofs(5, 0),
     186             :                         cached_internal_pipe_close,
     187             :                         domain);
     188           0 :                 if (internal_pipes->shutdown_timer == NULL) {
     189           0 :                         TALLOC_FREE(frame);
     190           0 :                         return NT_STATUS_NO_MEMORY;
     191             :                 }
     192             : 
     193           0 :                 domain->backend_data.samr_pipes =
     194           0 :                         talloc_steal(domain, internal_pipes);
     195             : 
     196           0 :                 TALLOC_FREE(frame);
     197             :         }
     198             : 
     199           0 :         if (samr_domain_hnd) {
     200           0 :                 *samr_domain_hnd = internal_pipes->samr_domain_hnd;
     201             :         }
     202             : 
     203           0 :         if (samr_pipe) {
     204           0 :                 *samr_pipe = internal_pipes->samr_pipe;
     205             :         }
     206             : 
     207           0 :         if (lsa_hnd) {
     208           0 :                 *lsa_hnd = internal_pipes->lsa_hnd;
     209             :         }
     210             : 
     211           0 :         if (lsa_pipe) {
     212           0 :                 *lsa_pipe = internal_pipes->lsa_pipe;
     213             :         }
     214             : 
     215           0 :         tevent_update_timer(
     216             :                 internal_pipes->shutdown_timer,
     217             :                 timeval_current_ofs(5, 0));
     218             : 
     219           0 :         return NT_STATUS_OK;
     220             : }
     221             : 
     222           0 : static bool reset_connection_on_error(struct winbindd_domain *domain,
     223             :                                       struct rpc_pipe_client *p,
     224             :                                       NTSTATUS status)
     225             : {
     226           0 :         struct dcerpc_binding_handle *b = p->binding_handle;
     227             : 
     228           0 :         if (NT_STATUS_EQUAL(status, NT_STATUS_IO_TIMEOUT) ||
     229           0 :             NT_STATUS_EQUAL(status, NT_STATUS_IO_DEVICE_ERROR))
     230             :         {
     231           0 :                 TALLOC_FREE(domain->backend_data.samr_pipes);
     232           0 :                 return true;
     233             :         }
     234             : 
     235           0 :         if (!dcerpc_binding_handle_is_connected(b)) {
     236           0 :                 TALLOC_FREE(domain->backend_data.samr_pipes);
     237           0 :                 return true;
     238             :         }
     239             : 
     240           0 :         return false;
     241             : }
     242             : 
     243             : /*********************************************************************
     244             :  SAM specific functions.
     245             : *********************************************************************/
     246             : 
     247             : /* List all domain groups */
     248           0 : static NTSTATUS sam_enum_dom_groups(struct winbindd_domain *domain,
     249             :                                     TALLOC_CTX *mem_ctx,
     250             :                                     uint32_t *pnum_info,
     251             :                                     struct wb_acct_info **pinfo)
     252             : {
     253           0 :         struct rpc_pipe_client *samr_pipe;
     254           0 :         struct policy_handle dom_pol = { 0 };
     255           0 :         struct wb_acct_info *info = NULL;
     256           0 :         uint32_t num_info = 0;
     257           0 :         TALLOC_CTX *tmp_ctx = talloc_stackframe();
     258           0 :         NTSTATUS status;
     259           0 :         bool retry = false;
     260             : 
     261           0 :         DEBUG(3,("sam_enum_dom_groups\n"));
     262             : 
     263           0 :         if (pnum_info) {
     264           0 :                 *pnum_info = 0;
     265             :         }
     266             : 
     267           0 : again:
     268           0 :         status = open_cached_internal_pipe_conn(domain,
     269             :                                                 &samr_pipe,
     270             :                                                 &dom_pol,
     271             :                                                 NULL,
     272             :                                                 NULL);
     273           0 :         if (!NT_STATUS_IS_OK(status)) {
     274           0 :                 TALLOC_FREE(tmp_ctx);
     275           0 :                 return status;
     276             :         }
     277             : 
     278           0 :         status = rpc_enum_dom_groups(tmp_ctx,
     279             :                                      samr_pipe,
     280             :                                      &dom_pol,
     281             :                                      &num_info,
     282             :                                      &info);
     283             : 
     284           0 :         if (!retry && reset_connection_on_error(domain, samr_pipe, status)) {
     285           0 :                 retry = true;
     286           0 :                 goto again;
     287             :         }
     288             : 
     289           0 :         if (!NT_STATUS_IS_OK(status)) {
     290           0 :                 TALLOC_FREE(tmp_ctx);
     291           0 :                 return status;
     292             :         }
     293             : 
     294           0 :         if (pnum_info) {
     295           0 :                 *pnum_info = num_info;
     296             :         }
     297             : 
     298           0 :         if (pinfo) {
     299           0 :                 *pinfo = talloc_move(mem_ctx, &info);
     300             :         }
     301             : 
     302           0 :         TALLOC_FREE(tmp_ctx);
     303           0 :         return status;
     304             : }
     305             : 
     306             : /* Query display info for a domain */
     307           0 : static NTSTATUS sam_query_user_list(struct winbindd_domain *domain,
     308             :                                     TALLOC_CTX *mem_ctx,
     309             :                                     uint32_t **prids)
     310             : {
     311           0 :         struct rpc_pipe_client *samr_pipe = NULL;
     312           0 :         struct policy_handle dom_pol = { 0 };
     313           0 :         uint32_t *rids = NULL;
     314           0 :         TALLOC_CTX *tmp_ctx = talloc_stackframe();
     315           0 :         NTSTATUS status;
     316           0 :         bool retry = false;
     317             : 
     318           0 :         DEBUG(3,("samr_query_user_list\n"));
     319             : 
     320           0 : again:
     321           0 :         status = open_cached_internal_pipe_conn(domain,
     322             :                                                 &samr_pipe,
     323             :                                                 &dom_pol,
     324             :                                                 NULL,
     325             :                                                 NULL);
     326           0 :         if (!NT_STATUS_IS_OK(status)) {
     327           0 :                 goto done;
     328             :         }
     329             : 
     330           0 :         status = rpc_query_user_list(tmp_ctx,
     331             :                                      samr_pipe,
     332             :                                      &dom_pol,
     333           0 :                                      &domain->sid,
     334             :                                      &rids);
     335           0 :         if (!retry && reset_connection_on_error(domain, samr_pipe, status)) {
     336           0 :                 retry = true;
     337           0 :                 goto again;
     338             :         }
     339             : 
     340           0 :         if (!NT_STATUS_IS_OK(status)) {
     341           0 :                 goto done;
     342             :         }
     343             : 
     344           0 :         if (prids != NULL) {
     345           0 :                 *prids = talloc_move(mem_ctx, &rids);
     346             :         }
     347             : 
     348           0 : done:
     349           0 :         TALLOC_FREE(rids);
     350           0 :         TALLOC_FREE(tmp_ctx);
     351           0 :         return status;
     352             : }
     353             : 
     354             : /* get a list of trusted domains - builtin domain */
     355           0 : static NTSTATUS sam_trusted_domains(struct winbindd_domain *domain,
     356             :                                     TALLOC_CTX *mem_ctx,
     357             :                                     struct netr_DomainTrustList *ptrust_list)
     358             : {
     359           0 :         struct rpc_pipe_client *lsa_pipe;
     360           0 :         struct policy_handle lsa_policy = { 0 };
     361           0 :         struct netr_DomainTrust *trusts = NULL;
     362           0 :         uint32_t num_trusts = 0;
     363           0 :         TALLOC_CTX *tmp_ctx = talloc_stackframe();
     364           0 :         NTSTATUS status;
     365           0 :         bool retry = false;
     366             : 
     367           0 :         DEBUG(3,("samr: trusted domains\n"));
     368             : 
     369           0 :         if (ptrust_list) {
     370           0 :                 ZERO_STRUCTP(ptrust_list);
     371             :         }
     372             : 
     373           0 : again:
     374           0 :         status = open_cached_internal_pipe_conn(domain,
     375             :                                                 NULL,
     376             :                                                 NULL,
     377             :                                                 &lsa_pipe,
     378             :                                                 &lsa_policy);
     379           0 :         if (!NT_STATUS_IS_OK(status)) {
     380           0 :                 goto done;
     381             :         }
     382             : 
     383           0 :         status = rpc_trusted_domains(tmp_ctx,
     384             :                                      lsa_pipe,
     385             :                                      &lsa_policy,
     386             :                                      &num_trusts,
     387             :                                      &trusts);
     388             : 
     389           0 :         if (!retry && reset_connection_on_error(domain, lsa_pipe, status)) {
     390           0 :                 retry = true;
     391           0 :                 goto again;
     392             :         }
     393             : 
     394           0 :         if (!NT_STATUS_IS_OK(status)) {
     395           0 :                 goto done;
     396             :         }
     397             : 
     398           0 :         if (ptrust_list) {
     399           0 :                 ptrust_list->count = num_trusts;
     400           0 :                 ptrust_list->array = talloc_move(mem_ctx, &trusts);
     401             :         }
     402             : 
     403           0 : done:
     404           0 :         TALLOC_FREE(tmp_ctx);
     405           0 :         return status;
     406             : }
     407             : 
     408             : /* Lookup group membership given a rid.   */
     409           0 : static NTSTATUS sam_lookup_groupmem(struct winbindd_domain *domain,
     410             :                                     TALLOC_CTX *mem_ctx,
     411             :                                     const struct dom_sid *group_sid,
     412             :                                     enum lsa_SidType type,
     413             :                                     uint32_t *pnum_names,
     414             :                                     struct dom_sid **psid_mem,
     415             :                                     char ***pnames,
     416             :                                     uint32_t **pname_types)
     417             : {
     418           0 :         struct rpc_pipe_client *samr_pipe;
     419           0 :         struct policy_handle dom_pol = { 0 };
     420             : 
     421           0 :         uint32_t num_names = 0;
     422           0 :         struct dom_sid *sid_mem = NULL;
     423           0 :         char **names = NULL;
     424           0 :         uint32_t *name_types = NULL;
     425             : 
     426           0 :         TALLOC_CTX *tmp_ctx = talloc_stackframe();
     427           0 :         NTSTATUS status;
     428           0 :         bool retry = false;
     429             : 
     430           0 :         DEBUG(3,("sam_lookup_groupmem\n"));
     431             : 
     432             :         /* Paranoia check */
     433           0 :         if (sid_check_is_in_builtin(group_sid) && (type != SID_NAME_ALIAS)) {
     434             :                 /* There's no groups, only aliases in BUILTIN */
     435           0 :                 status = NT_STATUS_NO_SUCH_GROUP;
     436           0 :                 goto done;
     437             :         }
     438             : 
     439           0 :         if (pnum_names) {
     440           0 :                 *pnum_names = 0;
     441             :         }
     442             : 
     443           0 : again:
     444           0 :         status = open_cached_internal_pipe_conn(domain,
     445             :                                                 &samr_pipe,
     446             :                                                 &dom_pol,
     447             :                                                 NULL,
     448             :                                                 NULL);
     449           0 :         if (!NT_STATUS_IS_OK(status)) {
     450           0 :                 goto done;
     451             :         }
     452             : 
     453           0 :         status = rpc_lookup_groupmem(tmp_ctx,
     454             :                                      samr_pipe,
     455             :                                      &dom_pol,
     456           0 :                                      domain->name,
     457           0 :                                      &domain->sid,
     458             :                                      group_sid,
     459             :                                      type,
     460             :                                      &num_names,
     461             :                                      &sid_mem,
     462             :                                      &names,
     463             :                                      &name_types);
     464             : 
     465           0 :         if (!retry && reset_connection_on_error(domain, samr_pipe, status)) {
     466           0 :                 retry = true;
     467           0 :                 goto again;
     468             :         }
     469             : 
     470           0 :         if (pnum_names) {
     471           0 :                 *pnum_names = num_names;
     472             :         }
     473             : 
     474           0 :         if (pnames) {
     475           0 :                 *pnames = talloc_move(mem_ctx, &names);
     476             :         }
     477             : 
     478           0 :         if (pname_types) {
     479           0 :                 *pname_types = talloc_move(mem_ctx, &name_types);
     480             :         }
     481             : 
     482           0 :         if (psid_mem) {
     483           0 :                 *psid_mem = talloc_move(mem_ctx, &sid_mem);
     484             :         }
     485             : 
     486           0 : done:
     487           0 :         TALLOC_FREE(tmp_ctx);
     488           0 :         return status;
     489             : }
     490             : 
     491             : /* Lookup alias membership */
     492           0 : static NTSTATUS sam_lookup_aliasmem(struct winbindd_domain *domain,
     493             :                                     TALLOC_CTX *mem_ctx,
     494             :                                     const struct dom_sid *group_sid,
     495             :                                     enum lsa_SidType type,
     496             :                                     uint32_t *pnum_sids,
     497             :                                     struct dom_sid **psid_mem)
     498             : {
     499           0 :         struct rpc_pipe_client *samr_pipe;
     500           0 :         struct policy_handle dom_pol = {0};
     501             : 
     502           0 :         uint32_t num_sids = 0;
     503           0 :         struct dom_sid *sid_mem = NULL;
     504             : 
     505           0 :         TALLOC_CTX *tmp_ctx = talloc_stackframe();
     506           0 :         NTSTATUS status;
     507           0 :         bool retry = false;
     508             : 
     509           0 :         DBG_INFO("sam_lookup_aliasmem\n");
     510             : 
     511             :         /* Paranoia check */
     512           0 :         if (type != SID_NAME_ALIAS) {
     513           0 :                 status = NT_STATUS_NO_SUCH_ALIAS;
     514           0 :                 goto done;
     515             :         }
     516             : 
     517           0 :         if (pnum_sids) {
     518           0 :                 *pnum_sids = 0;
     519             :         }
     520             : 
     521           0 : again:
     522           0 :         status = open_cached_internal_pipe_conn(domain,
     523             :                                                 &samr_pipe,
     524             :                                                 &dom_pol,
     525             :                                                 NULL,
     526             :                                                 NULL);
     527           0 :         if (!NT_STATUS_IS_OK(status)) {
     528           0 :                 goto done;
     529             :         }
     530             : 
     531           0 :         status = rpc_lookup_aliasmem(tmp_ctx,
     532             :                                      samr_pipe,
     533             :                                      &dom_pol,
     534           0 :                                      &domain->sid,
     535             :                                      group_sid,
     536             :                                      type,
     537             :                                      &num_sids,
     538             :                                      &sid_mem);
     539             : 
     540           0 :         if (!retry && reset_connection_on_error(domain, samr_pipe, status)) {
     541           0 :                 retry = true;
     542           0 :                 goto again;
     543             :         }
     544             : 
     545           0 :         if (pnum_sids) {
     546           0 :                 *pnum_sids = num_sids;
     547             :         }
     548             : 
     549           0 :         if (psid_mem) {
     550           0 :                 *psid_mem = talloc_move(mem_ctx, &sid_mem);
     551             :         }
     552             : 
     553           0 : done:
     554           0 :         TALLOC_FREE(tmp_ctx);
     555           0 :         return status;
     556             : }
     557             : 
     558             : /*********************************************************************
     559             :  BUILTIN specific functions.
     560             : *********************************************************************/
     561             : 
     562             : /* List all domain groups */
     563           0 : static NTSTATUS builtin_enum_dom_groups(struct winbindd_domain *domain,
     564             :                                 TALLOC_CTX *mem_ctx,
     565             :                                 uint32_t *num_entries,
     566             :                                 struct wb_acct_info **info)
     567             : {
     568             :         /* BUILTIN doesn't have domain groups */
     569           0 :         *num_entries = 0;
     570           0 :         *info = NULL;
     571           0 :         return NT_STATUS_OK;
     572             : }
     573             : 
     574             : /* Query display info for a domain */
     575           0 : static NTSTATUS builtin_query_user_list(struct winbindd_domain *domain,
     576             :                                 TALLOC_CTX *mem_ctx,
     577             :                                 uint32_t **rids)
     578             : {
     579             :         /* We don't have users */
     580           0 :         *rids = NULL;
     581           0 :         return NT_STATUS_OK;
     582             : }
     583             : 
     584             : /* get a list of trusted domains - builtin domain */
     585           0 : static NTSTATUS builtin_trusted_domains(struct winbindd_domain *domain,
     586             :                                         TALLOC_CTX *mem_ctx,
     587             :                                         struct netr_DomainTrustList *trusts)
     588             : {
     589           0 :         ZERO_STRUCTP(trusts);
     590           0 :         return NT_STATUS_OK;
     591             : }
     592             : 
     593             : /*********************************************************************
     594             :  COMMON functions.
     595             : *********************************************************************/
     596             : 
     597             : /* List all local groups (aliases) */
     598           0 : static NTSTATUS sam_enum_local_groups(struct winbindd_domain *domain,
     599             :                                       TALLOC_CTX *mem_ctx,
     600             :                                       uint32_t *pnum_info,
     601             :                                       struct wb_acct_info **pinfo)
     602             : {
     603           0 :         struct rpc_pipe_client *samr_pipe;
     604           0 :         struct policy_handle dom_pol = { 0 };
     605           0 :         struct wb_acct_info *info = NULL;
     606           0 :         uint32_t num_info = 0;
     607           0 :         TALLOC_CTX *tmp_ctx = talloc_stackframe();
     608           0 :         NTSTATUS status;
     609           0 :         bool retry = false;
     610             : 
     611           0 :         DEBUG(3,("samr: enum local groups\n"));
     612             : 
     613           0 :         if (pnum_info) {
     614           0 :                 *pnum_info = 0;
     615             :         }
     616             : 
     617           0 : again:
     618           0 :         status = open_cached_internal_pipe_conn(domain,
     619             :                                                 &samr_pipe,
     620             :                                                 &dom_pol,
     621             :                                                 NULL,
     622             :                                                 NULL);
     623           0 :         if (!NT_STATUS_IS_OK(status)) {
     624           0 :                 goto done;
     625             :         }
     626             : 
     627           0 :         status = rpc_enum_local_groups(mem_ctx,
     628             :                                        samr_pipe,
     629             :                                        &dom_pol,
     630             :                                        &num_info,
     631             : 
     632             :                                        &info);
     633           0 :         if (!retry && reset_connection_on_error(domain, samr_pipe, status)) {
     634           0 :                 retry = true;
     635           0 :                 goto again;
     636             :         }
     637             : 
     638           0 :         if (!NT_STATUS_IS_OK(status)) {
     639           0 :                 goto done;
     640             :         }
     641             : 
     642           0 :         if (pnum_info) {
     643           0 :                 *pnum_info = num_info;
     644             :         }
     645             : 
     646           0 :         if (pinfo) {
     647           0 :                 *pinfo = talloc_move(mem_ctx, &info);
     648             :         }
     649             : 
     650           0 : done:
     651           0 :         TALLOC_FREE(tmp_ctx);
     652           0 :         return status;
     653             : }
     654             : 
     655             : /* convert a single name to a sid in a domain */
     656           0 : static NTSTATUS sam_name_to_sid(struct winbindd_domain *domain,
     657             :                                    TALLOC_CTX *mem_ctx,
     658             :                                    const char *domain_name,
     659             :                                    const char *name,
     660             :                                    uint32_t flags,
     661             :                                    const char **pdom_name,
     662             :                                    struct dom_sid *psid,
     663             :                                    enum lsa_SidType *ptype)
     664             : {
     665           0 :         struct rpc_pipe_client *samr_pipe = NULL;
     666           0 :         struct dcerpc_binding_handle *h = NULL;
     667           0 :         struct policy_handle dom_pol = { .handle_type = 0, };
     668           0 :         struct dom_sid sid;
     669           0 :         const char *dom_name = domain_name;
     670           0 :         struct lsa_String lsa_name = { .string = name };
     671           0 :         struct samr_Ids rids = { .count = 0 };
     672           0 :         struct samr_Ids types = { .count = 0 };
     673           0 :         enum lsa_SidType type;
     674           0 :         TALLOC_CTX *tmp_ctx = talloc_stackframe();
     675           0 :         NTSTATUS status = NT_STATUS_NONE_MAPPED;
     676           0 :         NTSTATUS result;
     677           0 :         bool retry = false;
     678           0 :         bool ok;
     679             : 
     680           0 :         DBG_NOTICE("%s\\%s\n", domain_name, name);
     681             : 
     682           0 :         if (strequal(domain_name, unix_users_domain_name())) {
     683           0 :                 struct passwd *pwd = NULL;
     684             : 
     685           0 :                 if (name[0] == '\0') {
     686           0 :                         sid_copy(&sid, &global_sid_Unix_Users);
     687           0 :                         type = SID_NAME_DOMAIN;
     688           0 :                         goto done;
     689             :                 }
     690             : 
     691           0 :                 pwd = Get_Pwnam_alloc(tmp_ctx, name);
     692           0 :                 if (pwd == NULL) {
     693           0 :                         goto fail;
     694             :                 }
     695           0 :                 ok = sid_compose(&sid, &global_sid_Unix_Users, pwd->pw_uid);
     696           0 :                 if (!ok) {
     697           0 :                         status = NT_STATUS_INTERNAL_ERROR;
     698           0 :                         goto fail;
     699             :                 }
     700           0 :                 type = SID_NAME_USER;
     701           0 :                 goto done;
     702             :         }
     703             : 
     704           0 :         if (strequal(domain_name, unix_groups_domain_name())) {
     705           0 :                 struct group *grp = NULL;
     706             : 
     707           0 :                 if (name[0] == '\0') {
     708           0 :                         sid_copy(&sid, &global_sid_Unix_Groups);
     709           0 :                         type = SID_NAME_DOMAIN;
     710           0 :                         goto done;
     711             :                 }
     712             : 
     713           0 :                 grp = getgrnam(name);
     714           0 :                 if (grp == NULL) {
     715           0 :                         goto fail;
     716             :                 }
     717           0 :                 ok = sid_compose(&sid, &global_sid_Unix_Groups, grp->gr_gid);
     718           0 :                 if (!ok) {
     719           0 :                         status = NT_STATUS_INTERNAL_ERROR;
     720           0 :                         goto fail;
     721             :                 }
     722           0 :                 type = SID_NAME_DOM_GRP;
     723           0 :                 goto done;
     724             :         }
     725             : 
     726           0 :         if (name[0] == '\0') {
     727           0 :                 sid_copy(&sid, &domain->sid);
     728           0 :                 type = SID_NAME_DOMAIN;
     729           0 :                 goto done;
     730             :         }
     731             : 
     732           0 :         ok = lookup_wellknown_name(tmp_ctx, name, &sid, &dom_name);
     733           0 :         if (ok) {
     734           0 :                 type = SID_NAME_WKN_GRP;
     735           0 :                 goto done;
     736             :         }
     737             : 
     738             :         {
     739           0 :                 char *normalized = NULL;
     740           0 :                 NTSTATUS nstatus = normalize_name_unmap(
     741             :                         tmp_ctx, name, &normalized);
     742           0 :                 if (NT_STATUS_IS_OK(nstatus) ||
     743           0 :                     NT_STATUS_EQUAL(nstatus, NT_STATUS_FILE_RENAMED)) {
     744           0 :                         lsa_name.string = normalized;
     745             :                 }
     746             :         }
     747             : 
     748           0 : again:
     749           0 :         status = open_cached_internal_pipe_conn(
     750             :                 domain, &samr_pipe, &dom_pol, NULL, NULL);
     751           0 :         if (!NT_STATUS_IS_OK(status)) {
     752           0 :                 goto fail;
     753             :         }
     754           0 :         h = samr_pipe->binding_handle;
     755             : 
     756           0 :         status = dcerpc_samr_LookupNames(
     757             :                 h, tmp_ctx, &dom_pol, 1, &lsa_name, &rids, &types, &result);
     758             : 
     759           0 :         if (!retry && reset_connection_on_error(domain, samr_pipe, status)) {
     760           0 :                 retry = true;
     761           0 :                 goto again;
     762             :         }
     763             : 
     764           0 :         if (!NT_STATUS_IS_OK(status)) {
     765           0 :                 DBG_DEBUG("dcerpc_samr_LookupNames returned %s\n",
     766             :                           nt_errstr(status));
     767           0 :                 goto fail;
     768             :         }
     769           0 :         if (!NT_STATUS_IS_OK(result)) {
     770           0 :                 DBG_DEBUG("dcerpc_samr_LookupNames resulted in %s\n",
     771             :                           nt_errstr(status));
     772           0 :                 status = result;
     773           0 :                 goto fail;
     774             :         }
     775             : 
     776           0 :         sid_compose(&sid, &domain->sid, rids.ids[0]);
     777           0 :         type = types.ids[0];
     778             : 
     779           0 : done:
     780           0 :         if (pdom_name != NULL) {
     781           0 :                 *pdom_name = talloc_strdup(mem_ctx, dom_name);
     782           0 :                 if (*pdom_name == NULL) {
     783           0 :                         status = NT_STATUS_NO_MEMORY;
     784           0 :                         goto fail;
     785             :                 }
     786             :         }
     787             : 
     788           0 :         if (psid) {
     789           0 :                 sid_copy(psid, &sid);
     790             :         }
     791           0 :         if (ptype) {
     792           0 :                 *ptype = type;
     793             :         }
     794             : 
     795           0 :         status = NT_STATUS_OK;
     796           0 : fail:
     797           0 :         TALLOC_FREE(tmp_ctx);
     798           0 :         return status;
     799             : }
     800             : 
     801             : /* convert a domain SID to a user or group name */
     802           0 : static NTSTATUS sam_sid_to_name(struct winbindd_domain *domain,
     803             :                                 TALLOC_CTX *mem_ctx,
     804             :                                 const struct dom_sid *sid,
     805             :                                 char **pdomain_name,
     806             :                                 char **pname,
     807             :                                 enum lsa_SidType *ptype)
     808             : {
     809           0 :         struct rpc_pipe_client *samr_pipe = NULL;
     810           0 :         struct dcerpc_binding_handle *h = NULL;
     811           0 :         struct policy_handle dom_pol = { .handle_type = 0, };
     812           0 :         const char *domain_name = "";
     813           0 :         const char *name = "";
     814           0 :         enum lsa_SidType type = SID_NAME_USE_NONE;
     815           0 :         struct lsa_Strings names = { .count = 0, };
     816           0 :         struct samr_Ids types = { .count = 0 };
     817           0 :         struct dom_sid domain_sid;
     818           0 :         uint32_t rid;
     819           0 :         TALLOC_CTX *tmp_ctx = talloc_stackframe();
     820           0 :         NTSTATUS status = NT_STATUS_NONE_MAPPED;
     821           0 :         NTSTATUS result;
     822           0 :         bool retry = false;
     823           0 :         bool ok;
     824             : 
     825           0 :         DEBUG(3,("sam_sid_to_name\n"));
     826             : 
     827           0 :         if (sid_check_is_unix_users(sid)) {
     828           0 :                 domain_name = unix_users_domain_name();
     829           0 :                 type = SID_NAME_DOMAIN;
     830           0 :                 goto done;
     831             :         }
     832           0 :         if (sid_check_is_in_unix_users(sid)) {
     833           0 :                 struct passwd *pwd = NULL;
     834             : 
     835           0 :                 ok = sid_peek_rid(sid, &rid);
     836           0 :                 if (!ok) {
     837           0 :                         goto fail;
     838             :                 }
     839           0 :                 pwd = getpwuid(rid);
     840           0 :                 if (pwd == NULL) {
     841           0 :                         goto fail;
     842             :                 }
     843             : 
     844           0 :                 domain_name = unix_users_domain_name();
     845           0 :                 name = talloc_strdup(tmp_ctx, pwd->pw_name);
     846           0 :                 if (name == NULL) {
     847           0 :                         status = NT_STATUS_NO_MEMORY;
     848           0 :                         goto fail;
     849             :                 }
     850           0 :                 type = SID_NAME_USER;
     851           0 :                 goto done;
     852             :         }
     853             : 
     854           0 :         if (sid_check_is_unix_groups(sid)) {
     855           0 :                 domain_name = unix_groups_domain_name();
     856           0 :                 type = SID_NAME_DOMAIN;
     857           0 :                 goto done;
     858             :         }
     859           0 :         if (sid_check_is_in_unix_groups(sid)) {
     860           0 :                 struct group *grp = NULL;
     861             : 
     862           0 :                 ok = sid_peek_rid(sid, &rid);
     863           0 :                 if (!ok) {
     864           0 :                         goto fail;
     865             :                 }
     866           0 :                 grp = getgrgid(rid);
     867           0 :                 if (grp == NULL) {
     868           0 :                         goto fail;
     869             :                 }
     870             : 
     871           0 :                 domain_name = unix_groups_domain_name();
     872           0 :                 name = talloc_strdup(tmp_ctx, grp->gr_name);
     873           0 :                 if (name == NULL) {
     874           0 :                         status = NT_STATUS_NO_MEMORY;
     875           0 :                         goto fail;
     876             :                 }
     877           0 :                 type = SID_NAME_DOM_GRP;
     878           0 :                 goto done;
     879             :         }
     880             : 
     881           0 :         ok = lookup_wellknown_sid(tmp_ctx, sid, &domain_name, &name);
     882           0 :         if (ok) {
     883           0 :                 type = SID_NAME_WKN_GRP;
     884           0 :                 goto done;
     885             :         }
     886             : 
     887           0 :         if (dom_sid_equal(sid, &domain->sid)) {
     888           0 :                 domain_name = domain->name;
     889           0 :                 type = SID_NAME_DOMAIN;
     890           0 :                 goto done;
     891             :         }
     892             : 
     893           0 :         sid_copy(&domain_sid, sid);
     894           0 :         ok = sid_split_rid(&domain_sid, &rid);
     895           0 :         if (!ok) {
     896           0 :                 goto fail;
     897             :         }
     898             : 
     899           0 :         if (!dom_sid_equal(&domain_sid, &domain->sid)) {
     900           0 :                 goto fail;
     901             :         }
     902             : 
     903           0 : again:
     904           0 :         status = open_cached_internal_pipe_conn(
     905             :                 domain, &samr_pipe, &dom_pol, NULL, NULL);
     906           0 :         if (!NT_STATUS_IS_OK(status)) {
     907           0 :                 goto fail;
     908             :         }
     909           0 :         h = samr_pipe->binding_handle;
     910             : 
     911           0 :         status = dcerpc_samr_LookupRids(
     912             :                 h, tmp_ctx, &dom_pol, 1, &rid, &names, &types, &result);
     913             : 
     914           0 :         if (!retry && reset_connection_on_error(domain, samr_pipe, status)) {
     915           0 :                 retry = true;
     916           0 :                 goto again;
     917             :         }
     918             : 
     919           0 :         if (!NT_STATUS_IS_OK(status)) {
     920           0 :                 DBG_DEBUG("dcerpc_samr_LookupRids failed: %s\n",
     921             :                           nt_errstr(status));
     922           0 :                 goto fail;
     923             :         }
     924           0 :         if (!NT_STATUS_IS_OK(result)) {
     925           0 :                 DBG_DEBUG("dcerpc_samr_LookupRids resulted in %s\n",
     926             :                           nt_errstr(result));
     927           0 :                 status = result;
     928           0 :                 goto fail;
     929             :         }
     930             : 
     931           0 :         domain_name = domain->name;
     932           0 :         name = names.names[0].string;
     933           0 :         type = types.ids[0];
     934             : 
     935           0 :         if (name != NULL) {
     936           0 :                 char *normalized = NULL;
     937           0 :                 NTSTATUS nstatus = normalize_name_map(
     938             :                         tmp_ctx, domain_name, name, &normalized);
     939           0 :                 if (NT_STATUS_IS_OK(nstatus) ||
     940           0 :                     NT_STATUS_EQUAL(nstatus, NT_STATUS_FILE_RENAMED)) {
     941           0 :                         name = normalized;
     942             :                 }
     943             :         }
     944             : 
     945           0 : done:
     946           0 :         if (ptype) {
     947           0 :                 *ptype = type;
     948             :         }
     949             : 
     950           0 :         if (pname) {
     951           0 :                 *pname = talloc_strdup(mem_ctx, name);
     952           0 :                 if (*pname == NULL) {
     953           0 :                         status = NT_STATUS_NO_MEMORY;
     954           0 :                         goto fail;
     955             :                 }
     956             :         }
     957             : 
     958           0 :         if (pdomain_name) {
     959           0 :                 *pdomain_name = talloc_strdup(mem_ctx, domain_name);
     960           0 :                 if (*pdomain_name == NULL) {
     961           0 :                         status = NT_STATUS_NO_MEMORY;
     962           0 :                         goto fail;
     963             :                 }
     964             :         }
     965             : 
     966           0 :         status = NT_STATUS_OK;
     967           0 : fail:
     968           0 :         TALLOC_FREE(tmp_ctx);
     969           0 :         return status;
     970             : }
     971             : 
     972           0 : static NTSTATUS sam_rids_to_names(struct winbindd_domain *domain,
     973             :                                   TALLOC_CTX *mem_ctx,
     974             :                                   const struct dom_sid *domain_sid,
     975             :                                   uint32_t *rids,
     976             :                                   size_t num_rids,
     977             :                                   char **pdomain_name,
     978             :                                   char ***pnames,
     979             :                                   enum lsa_SidType **ptypes)
     980             : {
     981           0 :         struct rpc_pipe_client *samr_pipe = NULL;
     982           0 :         struct dcerpc_binding_handle *h = NULL;
     983           0 :         struct policy_handle dom_pol = { .handle_type = 0, };
     984           0 :         enum lsa_SidType *types = NULL;
     985           0 :         char **names = NULL;
     986           0 :         const char *domain_name = NULL;
     987           0 :         TALLOC_CTX *tmp_ctx = talloc_stackframe();
     988           0 :         NTSTATUS status = NT_STATUS_NO_MEMORY;
     989           0 :         NTSTATUS result;
     990           0 :         bool retry = false;
     991           0 :         uint32_t i;
     992             : 
     993           0 :         DEBUG(3,("sam_rids_to_names for %s\n", domain->name));
     994             : 
     995           0 :         types = talloc_array(tmp_ctx, enum lsa_SidType, num_rids);
     996           0 :         if (types == NULL) {
     997           0 :                 goto fail;
     998             :         }
     999             : 
    1000           0 :         names = talloc_array(tmp_ctx, char *, num_rids);
    1001           0 :         if (names == NULL) {
    1002           0 :                 goto fail;
    1003             :         }
    1004             : 
    1005           0 :         if (sid_check_is_unix_users(domain_sid)) {
    1006           0 :                 domain_name = unix_users_domain_name();
    1007           0 :                 domain_sid = &global_sid_Unix_Users;
    1008             :         }
    1009           0 :         if (sid_check_is_unix_groups(domain_sid)) {
    1010           0 :                 domain_name = unix_groups_domain_name();
    1011           0 :                 domain_sid = &global_sid_Unix_Groups;
    1012             :         }
    1013             : 
    1014             :         /* Here we're only interested in the domain name being set */
    1015           0 :         sid_check_is_wellknown_domain(domain_sid, &domain_name);
    1016             : 
    1017           0 :         if (domain_name != NULL) {
    1018           0 :                 uint32_t num_mapped = 0;
    1019             : 
    1020             :                 /*
    1021             :                  * Do unix users/groups and wkn in a loop. There is no
    1022             :                  * getpwuids() call & friends anyway
    1023             :                  */
    1024             : 
    1025           0 :                 for (i=0; i<num_rids; i++) {
    1026           0 :                         struct dom_sid sid;
    1027           0 :                         char *name = NULL;
    1028             : 
    1029           0 :                         sid_compose(&sid, domain_sid, rids[i]);
    1030             : 
    1031           0 :                         types[i] = SID_NAME_UNKNOWN;
    1032           0 :                         names[i] = NULL;
    1033             : 
    1034           0 :                         status = sam_sid_to_name(
    1035             :                                 domain,
    1036             :                                 tmp_ctx,
    1037             :                                 &sid,
    1038             :                                 NULL,
    1039             :                                 &name,
    1040           0 :                                 &types[i]);
    1041           0 :                         if (NT_STATUS_IS_OK(status)) {
    1042           0 :                                 names[i] = talloc_move(names, &name);
    1043           0 :                                 num_mapped += 1;
    1044             :                         }
    1045             :                 }
    1046             : 
    1047           0 :                 status = NT_STATUS_NONE_MAPPED;
    1048           0 :                 if (num_mapped > 0) {
    1049           0 :                         status = (num_mapped == num_rids) ?
    1050           0 :                                 NT_STATUS_OK : STATUS_SOME_UNMAPPED;
    1051             :                 }
    1052           0 :                 goto done;
    1053             :         }
    1054             : 
    1055           0 :         domain_name = domain->name;
    1056             : 
    1057           0 : again:
    1058           0 :         status = open_cached_internal_pipe_conn(
    1059             :                 domain, &samr_pipe, &dom_pol, NULL, NULL);
    1060           0 :         if (!NT_STATUS_IS_OK(status)) {
    1061           0 :                 goto done;
    1062             :         }
    1063           0 :         h = samr_pipe->binding_handle;
    1064             : 
    1065             :         /*
    1066             :          * Magic number 1000 comes from samr.idl
    1067             :          */
    1068             : 
    1069           0 :         for (i = 0; i < num_rids; i += 1000) {
    1070           0 :                 uint32_t num_lookup_rids = MIN(num_rids - i, 1000);
    1071           0 :                 struct lsa_Strings lsa_names = {
    1072             :                         .count = 0,
    1073             :                 };
    1074           0 :                 struct samr_Ids samr_types = {
    1075             :                         .count = 0,
    1076             :                 };
    1077           0 :                 uint32_t j;
    1078             : 
    1079           0 :                 status = dcerpc_samr_LookupRids(h,
    1080             :                                                 tmp_ctx,
    1081             :                                                 &dom_pol,
    1082             :                                                 num_lookup_rids,
    1083           0 :                                                 &rids[i],
    1084             :                                                 &lsa_names,
    1085             :                                                 &samr_types,
    1086             :                                                 &result);
    1087             : 
    1088           0 :                 if (!retry &&
    1089           0 :                     reset_connection_on_error(domain, samr_pipe, status)) {
    1090           0 :                         retry = true;
    1091           0 :                         goto again;
    1092             :                 }
    1093             : 
    1094           0 :                 if (!NT_STATUS_IS_OK(status)) {
    1095           0 :                         DBG_DEBUG("dcerpc_samr_LookupRids failed: %s\n",
    1096             :                                   nt_errstr(status));
    1097           0 :                         goto fail;
    1098             :                 }
    1099           0 :                 if (!NT_STATUS_IS_OK(result) &&
    1100           0 :                     !NT_STATUS_EQUAL(result, STATUS_SOME_UNMAPPED)) {
    1101           0 :                         DBG_DEBUG("dcerpc_samr_LookupRids resulted in %s\n",
    1102             :                                   nt_errstr(result));
    1103           0 :                         status = result;
    1104           0 :                         goto fail;
    1105             :                 }
    1106             : 
    1107           0 :                 for (j = 0; j < num_lookup_rids; j++) {
    1108           0 :                         uint32_t dst = i + j;
    1109             : 
    1110           0 :                         types[dst] = samr_types.ids[j];
    1111           0 :                         names[dst] = talloc_move(
    1112             :                                 names,
    1113             :                                 discard_const_p(char *,
    1114             :                                                 &lsa_names.names[j].string));
    1115           0 :                         if (names[dst] != NULL) {
    1116           0 :                                 char *normalized = NULL;
    1117           0 :                                 NTSTATUS nstatus =
    1118           0 :                                         normalize_name_map(names,
    1119             :                                                            domain_name,
    1120           0 :                                                            names[dst],
    1121             :                                                            &normalized);
    1122           0 :                                 if (NT_STATUS_IS_OK(nstatus) ||
    1123           0 :                                     NT_STATUS_EQUAL(nstatus,
    1124             :                                                     NT_STATUS_FILE_RENAMED)) {
    1125           0 :                                         names[dst] = normalized;
    1126             :                                 }
    1127             :                         }
    1128             :                 }
    1129             : 
    1130           0 :                 TALLOC_FREE(samr_types.ids);
    1131           0 :                 TALLOC_FREE(lsa_names.names);
    1132             :         }
    1133             : 
    1134           0 : done:
    1135           0 :         if (pdomain_name) {
    1136           0 :                 *pdomain_name = talloc_strdup(mem_ctx, domain_name);
    1137           0 :                 if (*pdomain_name == NULL) {
    1138           0 :                         status = NT_STATUS_NO_MEMORY;
    1139           0 :                         goto fail;
    1140             :                 }
    1141             :         }
    1142             : 
    1143           0 :         if (ptypes) {
    1144           0 :                 *ptypes = talloc_move(mem_ctx, &types);
    1145             :         }
    1146             : 
    1147           0 :         if (pnames) {
    1148           0 :                 *pnames = talloc_move(mem_ctx, &names);
    1149             :         }
    1150             : 
    1151           0 : fail:
    1152           0 :         TALLOC_FREE(tmp_ctx);
    1153           0 :         return status;
    1154             : }
    1155             : 
    1156           0 : static NTSTATUS sam_lockout_policy(struct winbindd_domain *domain,
    1157             :                                    TALLOC_CTX *mem_ctx,
    1158             :                                    struct samr_DomInfo12 *lockout_policy)
    1159             : {
    1160           0 :         struct rpc_pipe_client *samr_pipe;
    1161           0 :         struct policy_handle dom_pol = { 0 };
    1162           0 :         union samr_DomainInfo *info = NULL;
    1163           0 :         TALLOC_CTX *tmp_ctx = talloc_stackframe();
    1164           0 :         NTSTATUS status, result;
    1165           0 :         struct dcerpc_binding_handle *b = NULL;
    1166           0 :         bool retry = false;
    1167             : 
    1168           0 :         DEBUG(3,("sam_lockout_policy\n"));
    1169             : 
    1170           0 : again:
    1171           0 :         status = open_cached_internal_pipe_conn(domain,
    1172             :                                                 &samr_pipe,
    1173             :                                                 &dom_pol,
    1174             :                                                 NULL,
    1175             :                                                 NULL);
    1176           0 :         if (!NT_STATUS_IS_OK(status)) {
    1177           0 :                 goto error;
    1178             :         }
    1179             : 
    1180           0 :         b = samr_pipe->binding_handle;
    1181             : 
    1182           0 :         status = dcerpc_samr_QueryDomainInfo(b,
    1183             :                                              mem_ctx,
    1184             :                                              &dom_pol,
    1185             :                                              DomainLockoutInformation,
    1186             :                                              &info,
    1187             :                                              &result);
    1188             : 
    1189           0 :         if (!retry && reset_connection_on_error(domain, samr_pipe, status)) {
    1190           0 :                 retry = true;
    1191           0 :                 goto again;
    1192             :         }
    1193             : 
    1194           0 :         if (!NT_STATUS_IS_OK(status)) {
    1195           0 :                 goto error;
    1196             :         }
    1197           0 :         if (!NT_STATUS_IS_OK(result)) {
    1198           0 :                 status = result;
    1199           0 :                 goto error;
    1200             :         }
    1201             : 
    1202           0 :         *lockout_policy = info->info12;
    1203             : 
    1204           0 : error:
    1205           0 :         TALLOC_FREE(tmp_ctx);
    1206           0 :         return status;
    1207             : }
    1208             : 
    1209           0 : static NTSTATUS sam_password_policy(struct winbindd_domain *domain,
    1210             :                                     TALLOC_CTX *mem_ctx,
    1211             :                                     struct samr_DomInfo1 *passwd_policy)
    1212             : {
    1213           0 :         struct rpc_pipe_client *samr_pipe;
    1214           0 :         struct policy_handle dom_pol = { 0 };
    1215           0 :         union samr_DomainInfo *info = NULL;
    1216           0 :         TALLOC_CTX *tmp_ctx = talloc_stackframe();
    1217           0 :         NTSTATUS status, result;
    1218           0 :         struct dcerpc_binding_handle *b = NULL;
    1219           0 :         bool retry = false;
    1220             : 
    1221           0 :         DEBUG(3,("sam_password_policy\n"));
    1222             : 
    1223           0 : again:
    1224           0 :         status = open_cached_internal_pipe_conn(domain,
    1225             :                                                 &samr_pipe,
    1226             :                                                 &dom_pol,
    1227             :                                                 NULL,
    1228             :                                                 NULL);
    1229           0 :         if (!NT_STATUS_IS_OK(status)) {
    1230           0 :                 goto error;
    1231             :         }
    1232             : 
    1233           0 :         b = samr_pipe->binding_handle;
    1234             : 
    1235           0 :         status = dcerpc_samr_QueryDomainInfo(b,
    1236             :                                              mem_ctx,
    1237             :                                              &dom_pol,
    1238             :                                              DomainPasswordInformation,
    1239             :                                              &info,
    1240             :                                              &result);
    1241             : 
    1242           0 :         if (!retry && reset_connection_on_error(domain, samr_pipe, status)) {
    1243           0 :                 retry = true;
    1244           0 :                 goto again;
    1245             :         }
    1246             : 
    1247           0 :         if (!NT_STATUS_IS_OK(status)) {
    1248           0 :                 goto error;
    1249             :         }
    1250           0 :         if (!NT_STATUS_IS_OK(result)) {
    1251           0 :                 status = result;
    1252           0 :                 goto error;
    1253             :         }
    1254             : 
    1255           0 :         *passwd_policy = info->info1;
    1256             : 
    1257           0 : error:
    1258           0 :         TALLOC_FREE(tmp_ctx);
    1259           0 :         return status;
    1260             : }
    1261             : 
    1262             : /* Lookup groups a user is a member of. */
    1263           0 : static NTSTATUS sam_lookup_usergroups(struct winbindd_domain *domain,
    1264             :                                       TALLOC_CTX *mem_ctx,
    1265             :                                       const struct dom_sid *user_sid,
    1266             :                                       uint32_t *pnum_groups,
    1267             :                                       struct dom_sid **puser_grpsids)
    1268             : {
    1269           0 :         struct rpc_pipe_client *samr_pipe;
    1270           0 :         struct policy_handle dom_pol;
    1271           0 :         struct dom_sid *user_grpsids = NULL;
    1272           0 :         uint32_t num_groups = 0;
    1273           0 :         TALLOC_CTX *tmp_ctx = talloc_stackframe();
    1274           0 :         NTSTATUS status;
    1275           0 :         bool retry = false;
    1276             : 
    1277           0 :         DEBUG(3,("sam_lookup_usergroups\n"));
    1278             : 
    1279           0 :         ZERO_STRUCT(dom_pol);
    1280             : 
    1281           0 :         if (pnum_groups) {
    1282           0 :                 *pnum_groups = 0;
    1283             :         }
    1284             : 
    1285           0 : again:
    1286           0 :         status = open_cached_internal_pipe_conn(domain,
    1287             :                                                 &samr_pipe,
    1288             :                                                 &dom_pol,
    1289             :                                                 NULL,
    1290             :                                                 NULL);
    1291           0 :         if (!NT_STATUS_IS_OK(status)) {
    1292           0 :                 goto done;
    1293             :         }
    1294             : 
    1295           0 :         status = rpc_lookup_usergroups(tmp_ctx,
    1296             :                                        samr_pipe,
    1297             :                                        &dom_pol,
    1298           0 :                                        &domain->sid,
    1299             :                                        user_sid,
    1300             :                                        &num_groups,
    1301             :                                        &user_grpsids);
    1302             : 
    1303           0 :         if (!retry && reset_connection_on_error(domain, samr_pipe, status)) {
    1304           0 :                 retry = true;
    1305           0 :                 goto again;
    1306             :         }
    1307             : 
    1308           0 :         if (!NT_STATUS_IS_OK(status)) {
    1309           0 :                 goto done;
    1310             :         }
    1311             : 
    1312           0 :         if (pnum_groups) {
    1313           0 :                 *pnum_groups = num_groups;
    1314             :         }
    1315             : 
    1316           0 :         if (puser_grpsids) {
    1317           0 :                 *puser_grpsids = talloc_move(mem_ctx, &user_grpsids);
    1318             :         }
    1319             : 
    1320           0 : done:
    1321             : 
    1322           0 :         TALLOC_FREE(tmp_ctx);
    1323           0 :         return status;
    1324             : }
    1325             : 
    1326           0 : static NTSTATUS sam_lookup_useraliases(struct winbindd_domain *domain,
    1327             :                                        TALLOC_CTX *mem_ctx,
    1328             :                                        uint32_t num_sids,
    1329             :                                        const struct dom_sid *sids,
    1330             :                                        uint32_t *pnum_aliases,
    1331             :                                        uint32_t **palias_rids)
    1332             : {
    1333           0 :         struct rpc_pipe_client *samr_pipe;
    1334           0 :         struct policy_handle dom_pol = { 0 };
    1335           0 :         uint32_t num_aliases = 0;
    1336           0 :         uint32_t *alias_rids = NULL;
    1337           0 :         TALLOC_CTX *tmp_ctx = talloc_stackframe();
    1338           0 :         NTSTATUS status;
    1339           0 :         bool retry = false;
    1340             : 
    1341           0 :         DEBUG(3,("sam_lookup_useraliases\n"));
    1342             : 
    1343           0 :         if (pnum_aliases) {
    1344           0 :                 *pnum_aliases = 0;
    1345             :         }
    1346             : 
    1347           0 : again:
    1348           0 :         status = open_cached_internal_pipe_conn(domain,
    1349             :                                                 &samr_pipe,
    1350             :                                                 &dom_pol,
    1351             :                                                 NULL,
    1352             :                                                 NULL);
    1353           0 :         if (!NT_STATUS_IS_OK(status)) {
    1354           0 :                 goto done;
    1355             :         }
    1356             : 
    1357           0 :         status = rpc_lookup_useraliases(tmp_ctx,
    1358             :                                         samr_pipe,
    1359             :                                         &dom_pol,
    1360             :                                         num_sids,
    1361             :                                         sids,
    1362             :                                         &num_aliases,
    1363             :                                         &alias_rids);
    1364             : 
    1365           0 :         if (!retry && reset_connection_on_error(domain, samr_pipe, status)) {
    1366           0 :                 retry = true;
    1367           0 :                 goto again;
    1368             :         }
    1369             : 
    1370           0 :         if (!NT_STATUS_IS_OK(status)) {
    1371           0 :                 goto done;
    1372             :         }
    1373             : 
    1374           0 :         if (pnum_aliases) {
    1375           0 :                 *pnum_aliases = num_aliases;
    1376             :         }
    1377             : 
    1378           0 :         if (palias_rids) {
    1379           0 :                 *palias_rids = talloc_move(mem_ctx, &alias_rids);
    1380             :         }
    1381             : 
    1382           0 : done:
    1383             : 
    1384           0 :         TALLOC_FREE(tmp_ctx);
    1385           0 :         return status;
    1386             : }
    1387             : 
    1388             : /* the rpc backend methods are exposed via this structure */
    1389             : struct winbindd_methods builtin_passdb_methods = {
    1390             :         .consistent            = false,
    1391             : 
    1392             :         .query_user_list       = builtin_query_user_list,
    1393             :         .enum_dom_groups       = builtin_enum_dom_groups,
    1394             :         .enum_local_groups     = sam_enum_local_groups,
    1395             :         .name_to_sid           = sam_name_to_sid,
    1396             :         .sid_to_name           = sam_sid_to_name,
    1397             :         .rids_to_names         = sam_rids_to_names,
    1398             :         .lookup_usergroups     = sam_lookup_usergroups,
    1399             :         .lookup_useraliases    = sam_lookup_useraliases,
    1400             :         .lookup_groupmem       = sam_lookup_groupmem,
    1401             :         .lookup_aliasmem       = sam_lookup_aliasmem,
    1402             :         .lockout_policy        = sam_lockout_policy,
    1403             :         .password_policy       = sam_password_policy,
    1404             :         .trusted_domains       = builtin_trusted_domains
    1405             : };
    1406             : 
    1407             : /* the rpc backend methods are exposed via this structure */
    1408             : struct winbindd_methods sam_passdb_methods = {
    1409             :         .consistent            = false,
    1410             : 
    1411             :         .query_user_list       = sam_query_user_list,
    1412             :         .enum_dom_groups       = sam_enum_dom_groups,
    1413             :         .enum_local_groups     = sam_enum_local_groups,
    1414             :         .name_to_sid           = sam_name_to_sid,
    1415             :         .sid_to_name           = sam_sid_to_name,
    1416             :         .rids_to_names         = sam_rids_to_names,
    1417             :         .lookup_usergroups     = sam_lookup_usergroups,
    1418             :         .lookup_useraliases    = sam_lookup_useraliases,
    1419             :         .lookup_groupmem       = sam_lookup_groupmem,
    1420             :         .lookup_aliasmem       = sam_lookup_aliasmem,
    1421             :         .lockout_policy        = sam_lockout_policy,
    1422             :         .password_policy       = sam_password_policy,
    1423             :         .trusted_domains       = sam_trusted_domains
    1424             : };

Generated by: LCOV version 1.14