LCOV - code coverage report
Current view: top level - source3/winbindd - winbindd_samr.c (source / functions) Hit Total Coverage
Test: coverage report for v4-17-test 1498b464 Lines: 0 603 0.0 %
Date: 2024-06-13 04:01:37 Functions: 0 20 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             :         NTSTATUS status, result;
      66             :         struct policy_handle samr_connect_hnd;
      67             :         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             :         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 sychronous 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             :                 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             :         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             :         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             :         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             :         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             :         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             :         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             :         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             : /*********************************************************************
     492             :  BUILTIN specific functions.
     493             : *********************************************************************/
     494             : 
     495             : /* List all domain groups */
     496           0 : static NTSTATUS builtin_enum_dom_groups(struct winbindd_domain *domain,
     497             :                                 TALLOC_CTX *mem_ctx,
     498             :                                 uint32_t *num_entries,
     499             :                                 struct wb_acct_info **info)
     500             : {
     501             :         /* BUILTIN doesn't have domain groups */
     502           0 :         *num_entries = 0;
     503           0 :         *info = NULL;
     504           0 :         return NT_STATUS_OK;
     505             : }
     506             : 
     507             : /* Query display info for a domain */
     508           0 : static NTSTATUS builtin_query_user_list(struct winbindd_domain *domain,
     509             :                                 TALLOC_CTX *mem_ctx,
     510             :                                 uint32_t **rids)
     511             : {
     512             :         /* We don't have users */
     513           0 :         *rids = NULL;
     514           0 :         return NT_STATUS_OK;
     515             : }
     516             : 
     517             : /* get a list of trusted domains - builtin domain */
     518           0 : static NTSTATUS builtin_trusted_domains(struct winbindd_domain *domain,
     519             :                                         TALLOC_CTX *mem_ctx,
     520             :                                         struct netr_DomainTrustList *trusts)
     521             : {
     522           0 :         ZERO_STRUCTP(trusts);
     523           0 :         return NT_STATUS_OK;
     524             : }
     525             : 
     526             : /*********************************************************************
     527             :  COMMON functions.
     528             : *********************************************************************/
     529             : 
     530             : /* List all local groups (aliases) */
     531           0 : static NTSTATUS sam_enum_local_groups(struct winbindd_domain *domain,
     532             :                                       TALLOC_CTX *mem_ctx,
     533             :                                       uint32_t *pnum_info,
     534             :                                       struct wb_acct_info **pinfo)
     535             : {
     536             :         struct rpc_pipe_client *samr_pipe;
     537           0 :         struct policy_handle dom_pol = { 0 };
     538           0 :         struct wb_acct_info *info = NULL;
     539           0 :         uint32_t num_info = 0;
     540           0 :         TALLOC_CTX *tmp_ctx = talloc_stackframe();
     541             :         NTSTATUS status;
     542           0 :         bool retry = false;
     543             : 
     544           0 :         DEBUG(3,("samr: enum local groups\n"));
     545             : 
     546           0 :         if (pnum_info) {
     547           0 :                 *pnum_info = 0;
     548             :         }
     549             : 
     550           0 : again:
     551           0 :         status = open_cached_internal_pipe_conn(domain,
     552             :                                                 &samr_pipe,
     553             :                                                 &dom_pol,
     554             :                                                 NULL,
     555             :                                                 NULL);
     556           0 :         if (!NT_STATUS_IS_OK(status)) {
     557           0 :                 goto done;
     558             :         }
     559             : 
     560           0 :         status = rpc_enum_local_groups(mem_ctx,
     561             :                                        samr_pipe,
     562             :                                        &dom_pol,
     563             :                                        &num_info,
     564             : 
     565             :                                        &info);
     566           0 :         if (!retry && reset_connection_on_error(domain, samr_pipe, status)) {
     567           0 :                 retry = true;
     568           0 :                 goto again;
     569             :         }
     570             : 
     571           0 :         if (!NT_STATUS_IS_OK(status)) {
     572           0 :                 goto done;
     573             :         }
     574             : 
     575           0 :         if (pnum_info) {
     576           0 :                 *pnum_info = num_info;
     577             :         }
     578             : 
     579           0 :         if (pinfo) {
     580           0 :                 *pinfo = talloc_move(mem_ctx, &info);
     581             :         }
     582             : 
     583           0 : done:
     584           0 :         TALLOC_FREE(tmp_ctx);
     585           0 :         return status;
     586             : }
     587             : 
     588             : /* convert a single name to a sid in a domain */
     589           0 : static NTSTATUS sam_name_to_sid(struct winbindd_domain *domain,
     590             :                                    TALLOC_CTX *mem_ctx,
     591             :                                    const char *domain_name,
     592             :                                    const char *name,
     593             :                                    uint32_t flags,
     594             :                                    const char **pdom_name,
     595             :                                    struct dom_sid *psid,
     596             :                                    enum lsa_SidType *ptype)
     597             : {
     598           0 :         struct rpc_pipe_client *samr_pipe = NULL;
     599           0 :         struct dcerpc_binding_handle *h = NULL;
     600           0 :         struct policy_handle dom_pol = { .handle_type = 0, };
     601             :         struct dom_sid sid;
     602           0 :         const char *dom_name = domain_name;
     603           0 :         struct lsa_String lsa_name = { .string = name };
     604           0 :         struct samr_Ids rids = { .count = 0 };
     605           0 :         struct samr_Ids types = { .count = 0 };
     606             :         enum lsa_SidType type;
     607           0 :         TALLOC_CTX *tmp_ctx = talloc_stackframe();
     608           0 :         NTSTATUS status = NT_STATUS_NONE_MAPPED;
     609             :         NTSTATUS result;
     610           0 :         bool retry = false;
     611             :         bool ok;
     612             : 
     613           0 :         DBG_NOTICE("%s\\%s\n", domain_name, name);
     614             : 
     615           0 :         if (strequal(domain_name, unix_users_domain_name())) {
     616           0 :                 struct passwd *pwd = NULL;
     617             : 
     618           0 :                 if (name[0] == '\0') {
     619           0 :                         sid_copy(&sid, &global_sid_Unix_Users);
     620           0 :                         type = SID_NAME_DOMAIN;
     621           0 :                         goto done;
     622             :                 }
     623             : 
     624           0 :                 pwd = Get_Pwnam_alloc(tmp_ctx, name);
     625           0 :                 if (pwd == NULL) {
     626           0 :                         goto fail;
     627             :                 }
     628           0 :                 ok = sid_compose(&sid, &global_sid_Unix_Users, pwd->pw_uid);
     629           0 :                 if (!ok) {
     630           0 :                         status = NT_STATUS_INTERNAL_ERROR;
     631           0 :                         goto fail;
     632             :                 }
     633           0 :                 type = SID_NAME_USER;
     634           0 :                 goto done;
     635             :         }
     636             : 
     637           0 :         if (strequal(domain_name, unix_groups_domain_name())) {
     638           0 :                 struct group *grp = NULL;
     639             : 
     640           0 :                 if (name[0] == '\0') {
     641           0 :                         sid_copy(&sid, &global_sid_Unix_Groups);
     642           0 :                         type = SID_NAME_DOMAIN;
     643           0 :                         goto done;
     644             :                 }
     645             : 
     646           0 :                 grp = getgrnam(name);
     647           0 :                 if (grp == NULL) {
     648           0 :                         goto fail;
     649             :                 }
     650           0 :                 ok = sid_compose(&sid, &global_sid_Unix_Groups, grp->gr_gid);
     651           0 :                 if (!ok) {
     652           0 :                         status = NT_STATUS_INTERNAL_ERROR;
     653           0 :                         goto fail;
     654             :                 }
     655           0 :                 type = SID_NAME_DOM_GRP;
     656           0 :                 goto done;
     657             :         }
     658             : 
     659           0 :         if (name[0] == '\0') {
     660           0 :                 sid_copy(&sid, &domain->sid);
     661           0 :                 type = SID_NAME_DOMAIN;
     662           0 :                 goto done;
     663             :         }
     664             : 
     665           0 :         ok = lookup_wellknown_name(tmp_ctx, name, &sid, &dom_name);
     666           0 :         if (ok) {
     667           0 :                 type = SID_NAME_WKN_GRP;
     668           0 :                 goto done;
     669             :         }
     670             : 
     671             :         {
     672           0 :                 char *normalized = NULL;
     673           0 :                 NTSTATUS nstatus = normalize_name_unmap(
     674             :                         tmp_ctx, name, &normalized);
     675           0 :                 if (NT_STATUS_IS_OK(nstatus) ||
     676           0 :                     NT_STATUS_EQUAL(nstatus, NT_STATUS_FILE_RENAMED)) {
     677           0 :                         lsa_name.string = normalized;
     678             :                 }
     679             :         }
     680             : 
     681           0 : again:
     682           0 :         status = open_cached_internal_pipe_conn(
     683             :                 domain, &samr_pipe, &dom_pol, NULL, NULL);
     684           0 :         if (!NT_STATUS_IS_OK(status)) {
     685           0 :                 goto fail;
     686             :         }
     687           0 :         h = samr_pipe->binding_handle;
     688             : 
     689           0 :         status = dcerpc_samr_LookupNames(
     690             :                 h, tmp_ctx, &dom_pol, 1, &lsa_name, &rids, &types, &result);
     691             : 
     692           0 :         if (!retry && reset_connection_on_error(domain, samr_pipe, status)) {
     693           0 :                 retry = true;
     694           0 :                 goto again;
     695             :         }
     696             : 
     697           0 :         if (!NT_STATUS_IS_OK(status)) {
     698           0 :                 DBG_DEBUG("dcerpc_samr_LookupNames returned %s\n",
     699             :                           nt_errstr(status));
     700           0 :                 goto fail;
     701             :         }
     702           0 :         if (!NT_STATUS_IS_OK(result)) {
     703           0 :                 DBG_DEBUG("dcerpc_samr_LookupNames resulted in %s\n",
     704             :                           nt_errstr(status));
     705           0 :                 status = result;
     706           0 :                 goto fail;
     707             :         }
     708             : 
     709           0 :         sid_compose(&sid, &domain->sid, rids.ids[0]);
     710           0 :         type = types.ids[0];
     711             : 
     712           0 : done:
     713           0 :         if (pdom_name != NULL) {
     714           0 :                 *pdom_name = talloc_strdup(mem_ctx, dom_name);
     715           0 :                 if (*pdom_name == NULL) {
     716           0 :                         status = NT_STATUS_NO_MEMORY;
     717           0 :                         goto fail;
     718             :                 }
     719             :         }
     720             : 
     721           0 :         if (psid) {
     722           0 :                 sid_copy(psid, &sid);
     723             :         }
     724           0 :         if (ptype) {
     725           0 :                 *ptype = type;
     726             :         }
     727             : 
     728           0 :         status = NT_STATUS_OK;
     729           0 : fail:
     730           0 :         TALLOC_FREE(tmp_ctx);
     731           0 :         return status;
     732             : }
     733             : 
     734             : /* convert a domain SID to a user or group name */
     735           0 : static NTSTATUS sam_sid_to_name(struct winbindd_domain *domain,
     736             :                                 TALLOC_CTX *mem_ctx,
     737             :                                 const struct dom_sid *sid,
     738             :                                 char **pdomain_name,
     739             :                                 char **pname,
     740             :                                 enum lsa_SidType *ptype)
     741             : {
     742           0 :         struct rpc_pipe_client *samr_pipe = NULL;
     743           0 :         struct dcerpc_binding_handle *h = NULL;
     744           0 :         struct policy_handle dom_pol = { .handle_type = 0, };
     745           0 :         const char *domain_name = "";
     746           0 :         const char *name = "";
     747           0 :         enum lsa_SidType type = SID_NAME_USE_NONE;
     748           0 :         struct lsa_Strings names = { .count = 0, };
     749           0 :         struct samr_Ids types = { .count = 0 };
     750             :         struct dom_sid domain_sid;
     751             :         uint32_t rid;
     752           0 :         TALLOC_CTX *tmp_ctx = talloc_stackframe();
     753           0 :         NTSTATUS status = NT_STATUS_NONE_MAPPED;
     754             :         NTSTATUS result;
     755           0 :         bool retry = false;
     756             :         bool ok;
     757             : 
     758           0 :         DEBUG(3,("sam_sid_to_name\n"));
     759             : 
     760           0 :         if (sid_check_is_unix_users(sid)) {
     761           0 :                 domain_name = unix_users_domain_name();
     762           0 :                 type = SID_NAME_DOMAIN;
     763           0 :                 goto done;
     764             :         }
     765           0 :         if (sid_check_is_in_unix_users(sid)) {
     766           0 :                 struct passwd *pwd = NULL;
     767             : 
     768           0 :                 ok = sid_peek_rid(sid, &rid);
     769           0 :                 if (!ok) {
     770           0 :                         goto fail;
     771             :                 }
     772           0 :                 pwd = getpwuid(rid);
     773           0 :                 if (pwd == NULL) {
     774           0 :                         goto fail;
     775             :                 }
     776             : 
     777           0 :                 domain_name = unix_users_domain_name();
     778           0 :                 name = talloc_strdup(tmp_ctx, pwd->pw_name);
     779           0 :                 if (name == NULL) {
     780           0 :                         status = NT_STATUS_NO_MEMORY;
     781           0 :                         goto fail;
     782             :                 }
     783           0 :                 type = SID_NAME_USER;
     784           0 :                 goto done;
     785             :         }
     786             : 
     787           0 :         if (sid_check_is_unix_groups(sid)) {
     788           0 :                 domain_name = unix_groups_domain_name();
     789           0 :                 type = SID_NAME_DOMAIN;
     790           0 :                 goto done;
     791             :         }
     792           0 :         if (sid_check_is_in_unix_groups(sid)) {
     793           0 :                 struct group *grp = NULL;
     794             : 
     795           0 :                 ok = sid_peek_rid(sid, &rid);
     796           0 :                 if (!ok) {
     797           0 :                         goto fail;
     798             :                 }
     799           0 :                 grp = getgrgid(rid);
     800           0 :                 if (grp == NULL) {
     801           0 :                         goto fail;
     802             :                 }
     803             : 
     804           0 :                 domain_name = unix_groups_domain_name();
     805           0 :                 name = talloc_strdup(tmp_ctx, grp->gr_name);
     806           0 :                 if (name == NULL) {
     807           0 :                         status = NT_STATUS_NO_MEMORY;
     808           0 :                         goto fail;
     809             :                 }
     810           0 :                 type = SID_NAME_DOM_GRP;
     811           0 :                 goto done;
     812             :         }
     813             : 
     814           0 :         ok = lookup_wellknown_sid(tmp_ctx, sid, &domain_name, &name);
     815           0 :         if (ok) {
     816           0 :                 type = SID_NAME_WKN_GRP;
     817           0 :                 goto done;
     818             :         }
     819             : 
     820           0 :         if (dom_sid_equal(sid, &domain->sid)) {
     821           0 :                 domain_name = domain->name;
     822           0 :                 type = SID_NAME_DOMAIN;
     823           0 :                 goto done;
     824             :         }
     825             : 
     826           0 :         sid_copy(&domain_sid, sid);
     827           0 :         ok = sid_split_rid(&domain_sid, &rid);
     828           0 :         if (!ok) {
     829           0 :                 goto fail;
     830             :         }
     831             : 
     832           0 :         if (!dom_sid_equal(&domain_sid, &domain->sid)) {
     833           0 :                 goto fail;
     834             :         }
     835             : 
     836           0 : again:
     837           0 :         status = open_cached_internal_pipe_conn(
     838             :                 domain, &samr_pipe, &dom_pol, NULL, NULL);
     839           0 :         if (!NT_STATUS_IS_OK(status)) {
     840           0 :                 goto fail;
     841             :         }
     842           0 :         h = samr_pipe->binding_handle;
     843             : 
     844           0 :         status = dcerpc_samr_LookupRids(
     845             :                 h, tmp_ctx, &dom_pol, 1, &rid, &names, &types, &result);
     846             : 
     847           0 :         if (!retry && reset_connection_on_error(domain, samr_pipe, status)) {
     848           0 :                 retry = true;
     849           0 :                 goto again;
     850             :         }
     851             : 
     852           0 :         if (!NT_STATUS_IS_OK(status)) {
     853           0 :                 DBG_DEBUG("dcerpc_samr_LookupRids failed: %s\n",
     854             :                           nt_errstr(status));
     855           0 :                 goto fail;
     856             :         }
     857           0 :         if (!NT_STATUS_IS_OK(result)) {
     858           0 :                 DBG_DEBUG("dcerpc_samr_LookupRids resulted in %s\n",
     859             :                           nt_errstr(result));
     860           0 :                 status = result;
     861           0 :                 goto fail;
     862             :         }
     863             : 
     864           0 :         domain_name = domain->name;
     865           0 :         name = names.names[0].string;
     866           0 :         type = types.ids[0];
     867             : 
     868           0 :         if (name != NULL) {
     869           0 :                 char *normalized = NULL;
     870           0 :                 NTSTATUS nstatus = normalize_name_map(
     871             :                         tmp_ctx, domain_name, name, &normalized);
     872           0 :                 if (NT_STATUS_IS_OK(nstatus) ||
     873           0 :                     NT_STATUS_EQUAL(nstatus, NT_STATUS_FILE_RENAMED)) {
     874           0 :                         name = normalized;
     875             :                 }
     876             :         }
     877             : 
     878           0 : done:
     879           0 :         if (ptype) {
     880           0 :                 *ptype = type;
     881             :         }
     882             : 
     883           0 :         if (pname) {
     884           0 :                 *pname = talloc_strdup(mem_ctx, name);
     885           0 :                 if (*pname == NULL) {
     886           0 :                         status = NT_STATUS_NO_MEMORY;
     887           0 :                         goto fail;
     888             :                 }
     889             :         }
     890             : 
     891           0 :         if (pdomain_name) {
     892           0 :                 *pdomain_name = talloc_strdup(mem_ctx, domain_name);
     893           0 :                 if (*pdomain_name == NULL) {
     894           0 :                         status = NT_STATUS_NO_MEMORY;
     895           0 :                         goto fail;
     896             :                 }
     897             :         }
     898             : 
     899           0 :         status = NT_STATUS_OK;
     900           0 : fail:
     901           0 :         TALLOC_FREE(tmp_ctx);
     902           0 :         return status;
     903             : }
     904             : 
     905           0 : static NTSTATUS sam_rids_to_names(struct winbindd_domain *domain,
     906             :                                   TALLOC_CTX *mem_ctx,
     907             :                                   const struct dom_sid *domain_sid,
     908             :                                   uint32_t *rids,
     909             :                                   size_t num_rids,
     910             :                                   char **pdomain_name,
     911             :                                   char ***pnames,
     912             :                                   enum lsa_SidType **ptypes)
     913             : {
     914           0 :         struct rpc_pipe_client *samr_pipe = NULL;
     915           0 :         struct dcerpc_binding_handle *h = NULL;
     916           0 :         struct policy_handle dom_pol = { .handle_type = 0, };
     917           0 :         enum lsa_SidType *types = NULL;
     918           0 :         char **names = NULL;
     919           0 :         const char *domain_name = NULL;
     920           0 :         TALLOC_CTX *tmp_ctx = talloc_stackframe();
     921           0 :         NTSTATUS status = NT_STATUS_NO_MEMORY;
     922             :         NTSTATUS result;
     923           0 :         bool retry = false;
     924             :         uint32_t i;
     925             : 
     926           0 :         DEBUG(3,("sam_rids_to_names for %s\n", domain->name));
     927             : 
     928           0 :         types = talloc_array(tmp_ctx, enum lsa_SidType, num_rids);
     929           0 :         if (types == NULL) {
     930           0 :                 goto fail;
     931             :         }
     932             : 
     933           0 :         names = talloc_array(tmp_ctx, char *, num_rids);
     934           0 :         if (names == NULL) {
     935           0 :                 goto fail;
     936             :         }
     937             : 
     938           0 :         if (sid_check_is_unix_users(domain_sid)) {
     939           0 :                 domain_name = unix_users_domain_name();
     940           0 :                 domain_sid = &global_sid_Unix_Users;
     941             :         }
     942           0 :         if (sid_check_is_unix_groups(domain_sid)) {
     943           0 :                 domain_name = unix_groups_domain_name();
     944           0 :                 domain_sid = &global_sid_Unix_Groups;
     945             :         }
     946             : 
     947             :         /* Here we're only interested in the domain name being set */
     948           0 :         sid_check_is_wellknown_domain(domain_sid, &domain_name);
     949             : 
     950           0 :         if (domain_name != NULL) {
     951           0 :                 uint32_t num_mapped = 0;
     952             : 
     953             :                 /*
     954             :                  * Do unix users/groups and wkn in a loop. There is no
     955             :                  * getpwuids() call & friends anyway
     956             :                  */
     957             : 
     958           0 :                 for (i=0; i<num_rids; i++) {
     959             :                         struct dom_sid sid;
     960           0 :                         char *name = NULL;
     961             : 
     962           0 :                         sid_compose(&sid, domain_sid, rids[i]);
     963             : 
     964           0 :                         types[i] = SID_NAME_UNKNOWN;
     965           0 :                         names[i] = NULL;
     966             : 
     967           0 :                         status = sam_sid_to_name(
     968             :                                 domain,
     969             :                                 tmp_ctx,
     970             :                                 &sid,
     971             :                                 NULL,
     972             :                                 &name,
     973           0 :                                 &types[i]);
     974           0 :                         if (NT_STATUS_IS_OK(status)) {
     975           0 :                                 names[i] = talloc_move(names, &name);
     976           0 :                                 num_mapped += 1;
     977             :                         }
     978             :                 }
     979             : 
     980           0 :                 status = NT_STATUS_NONE_MAPPED;
     981           0 :                 if (num_mapped > 0) {
     982           0 :                         status = (num_mapped == num_rids) ?
     983           0 :                                 NT_STATUS_OK : STATUS_SOME_UNMAPPED;
     984             :                 }
     985           0 :                 goto done;
     986             :         }
     987             : 
     988           0 :         domain_name = domain->name;
     989             : 
     990           0 : again:
     991           0 :         status = open_cached_internal_pipe_conn(
     992             :                 domain, &samr_pipe, &dom_pol, NULL, NULL);
     993           0 :         if (!NT_STATUS_IS_OK(status)) {
     994           0 :                 goto done;
     995             :         }
     996           0 :         h = samr_pipe->binding_handle;
     997             : 
     998             :         /*
     999             :          * Magic number 1000 comes from samr.idl
    1000             :          */
    1001             : 
    1002           0 :         for (i = 0; i < num_rids; i += 1000) {
    1003           0 :                 uint32_t num_lookup_rids = MIN(num_rids - i, 1000);
    1004           0 :                 struct lsa_Strings lsa_names = {
    1005             :                         .count = 0,
    1006             :                 };
    1007           0 :                 struct samr_Ids samr_types = {
    1008             :                         .count = 0,
    1009             :                 };
    1010             :                 uint32_t j;
    1011             : 
    1012           0 :                 status = dcerpc_samr_LookupRids(h,
    1013             :                                                 tmp_ctx,
    1014             :                                                 &dom_pol,
    1015             :                                                 num_lookup_rids,
    1016           0 :                                                 &rids[i],
    1017             :                                                 &lsa_names,
    1018             :                                                 &samr_types,
    1019             :                                                 &result);
    1020             : 
    1021           0 :                 if (!retry &&
    1022           0 :                     reset_connection_on_error(domain, samr_pipe, status)) {
    1023           0 :                         retry = true;
    1024           0 :                         goto again;
    1025             :                 }
    1026             : 
    1027           0 :                 if (!NT_STATUS_IS_OK(status)) {
    1028           0 :                         DBG_DEBUG("dcerpc_samr_LookupRids failed: %s\n",
    1029             :                                   nt_errstr(status));
    1030           0 :                         goto fail;
    1031             :                 }
    1032           0 :                 if (!NT_STATUS_IS_OK(result) &&
    1033           0 :                     !NT_STATUS_EQUAL(result, STATUS_SOME_UNMAPPED)) {
    1034           0 :                         DBG_DEBUG("dcerpc_samr_LookupRids resulted in %s\n",
    1035             :                                   nt_errstr(result));
    1036           0 :                         status = result;
    1037           0 :                         goto fail;
    1038             :                 }
    1039             : 
    1040           0 :                 for (j = 0; j < num_lookup_rids; j++) {
    1041           0 :                         uint32_t dst = i + j;
    1042             : 
    1043           0 :                         types[dst] = samr_types.ids[j];
    1044           0 :                         names[dst] = talloc_move(
    1045             :                                 names,
    1046             :                                 discard_const_p(char *,
    1047             :                                                 &lsa_names.names[j].string));
    1048           0 :                         if (names[dst] != NULL) {
    1049           0 :                                 char *normalized = NULL;
    1050           0 :                                 NTSTATUS nstatus =
    1051           0 :                                         normalize_name_map(names,
    1052             :                                                            domain_name,
    1053           0 :                                                            names[dst],
    1054             :                                                            &normalized);
    1055           0 :                                 if (NT_STATUS_IS_OK(nstatus) ||
    1056           0 :                                     NT_STATUS_EQUAL(nstatus,
    1057             :                                                     NT_STATUS_FILE_RENAMED)) {
    1058           0 :                                         names[dst] = normalized;
    1059             :                                 }
    1060             :                         }
    1061             :                 }
    1062             : 
    1063           0 :                 TALLOC_FREE(samr_types.ids);
    1064           0 :                 TALLOC_FREE(lsa_names.names);
    1065             :         }
    1066             : 
    1067           0 : done:
    1068           0 :         if (pdomain_name) {
    1069           0 :                 *pdomain_name = talloc_strdup(mem_ctx, domain_name);
    1070           0 :                 if (*pdomain_name == NULL) {
    1071           0 :                         status = NT_STATUS_NO_MEMORY;
    1072           0 :                         goto fail;
    1073             :                 }
    1074             :         }
    1075             : 
    1076           0 :         if (ptypes) {
    1077           0 :                 *ptypes = talloc_move(mem_ctx, &types);
    1078             :         }
    1079             : 
    1080           0 :         if (pnames) {
    1081           0 :                 *pnames = talloc_move(mem_ctx, &names);
    1082             :         }
    1083             : 
    1084           0 : fail:
    1085           0 :         TALLOC_FREE(tmp_ctx);
    1086           0 :         return status;
    1087             : }
    1088             : 
    1089           0 : static NTSTATUS sam_lockout_policy(struct winbindd_domain *domain,
    1090             :                                    TALLOC_CTX *mem_ctx,
    1091             :                                    struct samr_DomInfo12 *lockout_policy)
    1092             : {
    1093             :         struct rpc_pipe_client *samr_pipe;
    1094           0 :         struct policy_handle dom_pol = { 0 };
    1095           0 :         union samr_DomainInfo *info = NULL;
    1096           0 :         TALLOC_CTX *tmp_ctx = talloc_stackframe();
    1097             :         NTSTATUS status, result;
    1098           0 :         struct dcerpc_binding_handle *b = NULL;
    1099           0 :         bool retry = false;
    1100             : 
    1101           0 :         DEBUG(3,("sam_lockout_policy\n"));
    1102             : 
    1103           0 : again:
    1104           0 :         status = open_cached_internal_pipe_conn(domain,
    1105             :                                                 &samr_pipe,
    1106             :                                                 &dom_pol,
    1107             :                                                 NULL,
    1108             :                                                 NULL);
    1109           0 :         if (!NT_STATUS_IS_OK(status)) {
    1110           0 :                 goto error;
    1111             :         }
    1112             : 
    1113           0 :         b = samr_pipe->binding_handle;
    1114             : 
    1115           0 :         status = dcerpc_samr_QueryDomainInfo(b,
    1116             :                                              mem_ctx,
    1117             :                                              &dom_pol,
    1118             :                                              DomainLockoutInformation,
    1119             :                                              &info,
    1120             :                                              &result);
    1121             : 
    1122           0 :         if (!retry && reset_connection_on_error(domain, samr_pipe, status)) {
    1123           0 :                 retry = true;
    1124           0 :                 goto again;
    1125             :         }
    1126             : 
    1127           0 :         if (!NT_STATUS_IS_OK(status)) {
    1128           0 :                 goto error;
    1129             :         }
    1130           0 :         if (!NT_STATUS_IS_OK(result)) {
    1131           0 :                 status = result;
    1132           0 :                 goto error;
    1133             :         }
    1134             : 
    1135           0 :         *lockout_policy = info->info12;
    1136             : 
    1137           0 : error:
    1138           0 :         TALLOC_FREE(tmp_ctx);
    1139           0 :         return status;
    1140             : }
    1141             : 
    1142           0 : static NTSTATUS sam_password_policy(struct winbindd_domain *domain,
    1143             :                                     TALLOC_CTX *mem_ctx,
    1144             :                                     struct samr_DomInfo1 *passwd_policy)
    1145             : {
    1146             :         struct rpc_pipe_client *samr_pipe;
    1147           0 :         struct policy_handle dom_pol = { 0 };
    1148           0 :         union samr_DomainInfo *info = NULL;
    1149           0 :         TALLOC_CTX *tmp_ctx = talloc_stackframe();
    1150             :         NTSTATUS status, result;
    1151           0 :         struct dcerpc_binding_handle *b = NULL;
    1152           0 :         bool retry = false;
    1153             : 
    1154           0 :         DEBUG(3,("sam_password_policy\n"));
    1155             : 
    1156           0 : again:
    1157           0 :         status = open_cached_internal_pipe_conn(domain,
    1158             :                                                 &samr_pipe,
    1159             :                                                 &dom_pol,
    1160             :                                                 NULL,
    1161             :                                                 NULL);
    1162           0 :         if (!NT_STATUS_IS_OK(status)) {
    1163           0 :                 goto error;
    1164             :         }
    1165             : 
    1166           0 :         b = samr_pipe->binding_handle;
    1167             : 
    1168           0 :         status = dcerpc_samr_QueryDomainInfo(b,
    1169             :                                              mem_ctx,
    1170             :                                              &dom_pol,
    1171             :                                              DomainPasswordInformation,
    1172             :                                              &info,
    1173             :                                              &result);
    1174             : 
    1175           0 :         if (!retry && reset_connection_on_error(domain, samr_pipe, status)) {
    1176           0 :                 retry = true;
    1177           0 :                 goto again;
    1178             :         }
    1179             : 
    1180           0 :         if (!NT_STATUS_IS_OK(status)) {
    1181           0 :                 goto error;
    1182             :         }
    1183           0 :         if (!NT_STATUS_IS_OK(result)) {
    1184           0 :                 status = result;
    1185           0 :                 goto error;
    1186             :         }
    1187             : 
    1188           0 :         *passwd_policy = info->info1;
    1189             : 
    1190           0 : error:
    1191           0 :         TALLOC_FREE(tmp_ctx);
    1192           0 :         return status;
    1193             : }
    1194             : 
    1195             : /* Lookup groups a user is a member of. */
    1196           0 : static NTSTATUS sam_lookup_usergroups(struct winbindd_domain *domain,
    1197             :                                       TALLOC_CTX *mem_ctx,
    1198             :                                       const struct dom_sid *user_sid,
    1199             :                                       uint32_t *pnum_groups,
    1200             :                                       struct dom_sid **puser_grpsids)
    1201             : {
    1202             :         struct rpc_pipe_client *samr_pipe;
    1203             :         struct policy_handle dom_pol;
    1204           0 :         struct dom_sid *user_grpsids = NULL;
    1205           0 :         uint32_t num_groups = 0;
    1206           0 :         TALLOC_CTX *tmp_ctx = talloc_stackframe();
    1207             :         NTSTATUS status;
    1208           0 :         bool retry = false;
    1209             : 
    1210           0 :         DEBUG(3,("sam_lookup_usergroups\n"));
    1211             : 
    1212           0 :         ZERO_STRUCT(dom_pol);
    1213             : 
    1214           0 :         if (pnum_groups) {
    1215           0 :                 *pnum_groups = 0;
    1216             :         }
    1217             : 
    1218           0 : again:
    1219           0 :         status = open_cached_internal_pipe_conn(domain,
    1220             :                                                 &samr_pipe,
    1221             :                                                 &dom_pol,
    1222             :                                                 NULL,
    1223             :                                                 NULL);
    1224           0 :         if (!NT_STATUS_IS_OK(status)) {
    1225           0 :                 goto done;
    1226             :         }
    1227             : 
    1228           0 :         status = rpc_lookup_usergroups(tmp_ctx,
    1229             :                                        samr_pipe,
    1230             :                                        &dom_pol,
    1231           0 :                                        &domain->sid,
    1232             :                                        user_sid,
    1233             :                                        &num_groups,
    1234             :                                        &user_grpsids);
    1235             : 
    1236           0 :         if (!retry && reset_connection_on_error(domain, samr_pipe, status)) {
    1237           0 :                 retry = true;
    1238           0 :                 goto again;
    1239             :         }
    1240             : 
    1241           0 :         if (!NT_STATUS_IS_OK(status)) {
    1242           0 :                 goto done;
    1243             :         }
    1244             : 
    1245           0 :         if (pnum_groups) {
    1246           0 :                 *pnum_groups = num_groups;
    1247             :         }
    1248             : 
    1249           0 :         if (puser_grpsids) {
    1250           0 :                 *puser_grpsids = talloc_move(mem_ctx, &user_grpsids);
    1251             :         }
    1252             : 
    1253           0 : done:
    1254             : 
    1255           0 :         TALLOC_FREE(tmp_ctx);
    1256           0 :         return status;
    1257             : }
    1258             : 
    1259           0 : static NTSTATUS sam_lookup_useraliases(struct winbindd_domain *domain,
    1260             :                                        TALLOC_CTX *mem_ctx,
    1261             :                                        uint32_t num_sids,
    1262             :                                        const struct dom_sid *sids,
    1263             :                                        uint32_t *pnum_aliases,
    1264             :                                        uint32_t **palias_rids)
    1265             : {
    1266             :         struct rpc_pipe_client *samr_pipe;
    1267           0 :         struct policy_handle dom_pol = { 0 };
    1268           0 :         uint32_t num_aliases = 0;
    1269           0 :         uint32_t *alias_rids = NULL;
    1270           0 :         TALLOC_CTX *tmp_ctx = talloc_stackframe();
    1271             :         NTSTATUS status;
    1272           0 :         bool retry = false;
    1273             : 
    1274           0 :         DEBUG(3,("sam_lookup_useraliases\n"));
    1275             : 
    1276           0 :         if (pnum_aliases) {
    1277           0 :                 *pnum_aliases = 0;
    1278             :         }
    1279             : 
    1280           0 : again:
    1281           0 :         status = open_cached_internal_pipe_conn(domain,
    1282             :                                                 &samr_pipe,
    1283             :                                                 &dom_pol,
    1284             :                                                 NULL,
    1285             :                                                 NULL);
    1286           0 :         if (!NT_STATUS_IS_OK(status)) {
    1287           0 :                 goto done;
    1288             :         }
    1289             : 
    1290           0 :         status = rpc_lookup_useraliases(tmp_ctx,
    1291             :                                         samr_pipe,
    1292             :                                         &dom_pol,
    1293             :                                         num_sids,
    1294             :                                         sids,
    1295             :                                         &num_aliases,
    1296             :                                         &alias_rids);
    1297             : 
    1298           0 :         if (!retry && reset_connection_on_error(domain, samr_pipe, status)) {
    1299           0 :                 retry = true;
    1300           0 :                 goto again;
    1301             :         }
    1302             : 
    1303           0 :         if (!NT_STATUS_IS_OK(status)) {
    1304           0 :                 goto done;
    1305             :         }
    1306             : 
    1307           0 :         if (pnum_aliases) {
    1308           0 :                 *pnum_aliases = num_aliases;
    1309             :         }
    1310             : 
    1311           0 :         if (palias_rids) {
    1312           0 :                 *palias_rids = talloc_move(mem_ctx, &alias_rids);
    1313             :         }
    1314             : 
    1315           0 : done:
    1316             : 
    1317           0 :         TALLOC_FREE(tmp_ctx);
    1318           0 :         return status;
    1319             : }
    1320             : 
    1321             : /* the rpc backend methods are exposed via this structure */
    1322             : struct winbindd_methods builtin_passdb_methods = {
    1323             :         .consistent            = false,
    1324             : 
    1325             :         .query_user_list       = builtin_query_user_list,
    1326             :         .enum_dom_groups       = builtin_enum_dom_groups,
    1327             :         .enum_local_groups     = sam_enum_local_groups,
    1328             :         .name_to_sid           = sam_name_to_sid,
    1329             :         .sid_to_name           = sam_sid_to_name,
    1330             :         .rids_to_names         = sam_rids_to_names,
    1331             :         .lookup_usergroups     = sam_lookup_usergroups,
    1332             :         .lookup_useraliases    = sam_lookup_useraliases,
    1333             :         .lookup_groupmem       = sam_lookup_groupmem,
    1334             :         .lockout_policy        = sam_lockout_policy,
    1335             :         .password_policy       = sam_password_policy,
    1336             :         .trusted_domains       = builtin_trusted_domains
    1337             : };
    1338             : 
    1339             : /* the rpc backend methods are exposed via this structure */
    1340             : struct winbindd_methods sam_passdb_methods = {
    1341             :         .consistent            = false,
    1342             : 
    1343             :         .query_user_list       = sam_query_user_list,
    1344             :         .enum_dom_groups       = sam_enum_dom_groups,
    1345             :         .enum_local_groups     = sam_enum_local_groups,
    1346             :         .name_to_sid           = sam_name_to_sid,
    1347             :         .sid_to_name           = sam_sid_to_name,
    1348             :         .rids_to_names         = sam_rids_to_names,
    1349             :         .lookup_usergroups     = sam_lookup_usergroups,
    1350             :         .lookup_useraliases    = sam_lookup_useraliases,
    1351             :         .lookup_groupmem       = sam_lookup_groupmem,
    1352             :         .lockout_policy        = sam_lockout_policy,
    1353             :         .password_policy       = sam_password_policy,
    1354             :         .trusted_domains       = sam_trusted_domains
    1355             : };

Generated by: LCOV version 1.13