LCOV - code coverage report
Current view: top level - source3/rpc_server/lsa - srv_lsa_nt.c (source / functions) Hit Total Coverage
Test: coverage report for abartlet/fix-coverage dd10fb34 Lines: 782 2107 37.1 %
Date: 2021-09-23 10:06:22 Functions: 47 113 41.6 %

          Line data    Source code
       1             : /*
       2             :  *  Unix SMB/CIFS implementation.
       3             :  *  RPC Pipe client / server routines
       4             :  *  Copyright (C) Andrew Tridgell              1992-1997,
       5             :  *  Copyright (C) Luke Kenneth Casson Leighton 1996-1997,
       6             :  *  Copyright (C) Paul Ashton                       1997,
       7             :  *  Copyright (C) Jeremy Allison                    2001, 2006.
       8             :  *  Copyright (C) Rafal Szczesniak                  2002,
       9             :  *  Copyright (C) Jim McDonough <jmcd@us.ibm.com>   2002,
      10             :  *  Copyright (C) Simo Sorce                        2003.
      11             :  *  Copyright (C) Gerald (Jerry) Carter             2005.
      12             :  *  Copyright (C) Volker Lendecke                   2005.
      13             :  *  Copyright (C) Guenther Deschner                 2008.
      14             :  *  Copyright (C) Andrew Bartlett                   2010.
      15             :  *
      16             :  *  This program is free software; you can redistribute it and/or modify
      17             :  *  it under the terms of the GNU General Public License as published by
      18             :  *  the Free Software Foundation; either version 3 of the License, or
      19             :  *  (at your option) any later version.
      20             :  *
      21             :  *  This program is distributed in the hope that it will be useful,
      22             :  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
      23             :  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      24             :  *  GNU General Public License for more details.
      25             :  *
      26             :  *  You should have received a copy of the GNU General Public License
      27             :  *  along with this program; if not, see <http://www.gnu.org/licenses/>.
      28             :  */
      29             : 
      30             : /* This is the implementation of the lsa server code. */
      31             : 
      32             : #include "includes.h"
      33             : #include "ntdomain.h"
      34             : #include "librpc/gen_ndr/ndr_lsa.h"
      35             : #include "librpc/gen_ndr/ndr_lsa_scompat.h"
      36             : #include "secrets.h"
      37             : #include "../librpc/gen_ndr/netlogon.h"
      38             : #include "rpc_client/init_lsa.h"
      39             : #include "../libcli/security/security.h"
      40             : #include "../libcli/security/dom_sid.h"
      41             : #include "../librpc/gen_ndr/drsblobs.h"
      42             : #include "../librpc/gen_ndr/ndr_drsblobs.h"
      43             : #include "../libcli/security/dom_sid.h"
      44             : #include "../librpc/gen_ndr/ndr_security.h"
      45             : #include "passdb.h"
      46             : #include "auth.h"
      47             : #include "lib/privileges.h"
      48             : #include "rpc_server/srv_access_check.h"
      49             : #include "../librpc/gen_ndr/ndr_wkssvc.h"
      50             : #include "../libcli/auth/libcli_auth.h"
      51             : #include "../libcli/lsarpc/util_lsarpc.h"
      52             : #include "lsa.h"
      53             : #include "librpc/rpc/dcesrv_core.h"
      54             : #include "librpc/rpc/dcerpc_helper.h"
      55             : #include "lib/param/loadparm.h"
      56             : 
      57             : #include "lib/crypto/gnutls_helpers.h"
      58             : #include <gnutls/gnutls.h>
      59             : #include <gnutls/crypto.h>
      60             : 
      61             : #undef DBGC_CLASS
      62             : #define DBGC_CLASS DBGC_RPC_SRV
      63             : 
      64             : #define MAX_LOOKUP_SIDS 0x5000 /* 20480 */
      65             : 
      66             : enum lsa_handle_type {
      67             :         LSA_HANDLE_POLICY_TYPE = 1,
      68             :         LSA_HANDLE_ACCOUNT_TYPE = 2,
      69             :         LSA_HANDLE_TRUST_TYPE = 3,
      70             :         LSA_HANDLE_SECRET_TYPE = 4};
      71             : 
      72             : struct lsa_info {
      73             :         struct dom_sid sid;
      74             :         const char *name;
      75             :         uint32_t access;
      76             :         enum lsa_handle_type type;
      77             :         struct security_descriptor *sd;
      78             : };
      79             : 
      80             : const struct generic_mapping lsa_account_mapping = {
      81             :         LSA_ACCOUNT_READ,
      82             :         LSA_ACCOUNT_WRITE,
      83             :         LSA_ACCOUNT_EXECUTE,
      84             :         LSA_ACCOUNT_ALL_ACCESS
      85             : };
      86             : 
      87             : const struct generic_mapping lsa_policy_mapping = {
      88             :         LSA_POLICY_READ,
      89             :         LSA_POLICY_WRITE,
      90             :         LSA_POLICY_EXECUTE,
      91             :         LSA_POLICY_ALL_ACCESS
      92             : };
      93             : 
      94             : const struct generic_mapping lsa_secret_mapping = {
      95             :         LSA_SECRET_READ,
      96             :         LSA_SECRET_WRITE,
      97             :         LSA_SECRET_EXECUTE,
      98             :         LSA_SECRET_ALL_ACCESS
      99             : };
     100             : 
     101             : const struct generic_mapping lsa_trusted_domain_mapping = {
     102             :         LSA_TRUSTED_DOMAIN_READ,
     103             :         LSA_TRUSTED_DOMAIN_WRITE,
     104             :         LSA_TRUSTED_DOMAIN_EXECUTE,
     105             :         LSA_TRUSTED_DOMAIN_ALL_ACCESS
     106             : };
     107             : 
     108             : /***************************************************************************
     109             :  initialize a lsa_DomainInfo structure.
     110             :  ***************************************************************************/
     111             : 
     112          41 : static void init_dom_query_3(struct lsa_DomainInfo *r,
     113             :                              const char *name,
     114             :                              struct dom_sid *sid)
     115             : {
     116          41 :         init_lsa_StringLarge(&r->name, name);
     117          41 :         r->sid = sid;
     118          41 : }
     119             : 
     120             : /***************************************************************************
     121             :  initialize a lsa_DomainInfo structure.
     122             :  ***************************************************************************/
     123             : 
     124         617 : static void init_dom_query_5(struct lsa_DomainInfo *r,
     125             :                              const char *name,
     126             :                              struct dom_sid *sid)
     127             : {
     128         617 :         init_lsa_StringLarge(&r->name, name);
     129         617 :         r->sid = sid;
     130         617 : }
     131             : 
     132             : /***************************************************************************
     133             :  lookup_lsa_rids. Must be called as root for lookup_name to work.
     134             :  ***************************************************************************/
     135             : 
     136        1417 : static NTSTATUS lookup_lsa_rids(TALLOC_CTX *mem_ctx,
     137             :                                 struct lsa_RefDomainList *ref,
     138             :                                 struct lsa_TranslatedSid *prid,
     139             :                                 uint32_t num_entries,
     140             :                                 struct lsa_String *name,
     141             :                                 int flags,
     142             :                                 uint32_t *pmapped_count)
     143             : {
     144             :         uint32_t mapped_count, i;
     145             : 
     146        1417 :         SMB_ASSERT(num_entries <= MAX_LOOKUP_SIDS);
     147             : 
     148        1417 :         mapped_count = 0;
     149        1417 :         *pmapped_count = 0;
     150             : 
     151        2854 :         for (i = 0; i < num_entries; i++) {
     152             :                 struct dom_sid sid;
     153             :                 uint32_t rid;
     154             :                 int dom_idx;
     155             :                 const char *full_name;
     156             :                 const char *domain;
     157             :                 enum lsa_SidType type;
     158             : 
     159             :                 /* Split name into domain and user component */
     160             : 
     161             :                 /* follow w2k8 behavior and return the builtin domain when no
     162             :                  * input has been passed in */
     163             : 
     164        1437 :                 if (name[i].string) {
     165        1435 :                         full_name = name[i].string;
     166             :                 } else {
     167           2 :                         full_name = "BUILTIN";
     168             :                 }
     169             : 
     170        1437 :                 DEBUG(5, ("lookup_lsa_rids: looking up name %s\n", full_name));
     171             : 
     172        1437 :                 if (!lookup_name(mem_ctx, full_name, flags, &domain, NULL,
     173             :                                  &sid, &type)) {
     174           7 :                         type = SID_NAME_UNKNOWN;
     175             :                 }
     176             : 
     177        1437 :                 switch (type) {
     178        1430 :                 case SID_NAME_USER:
     179             :                 case SID_NAME_DOM_GRP:
     180             :                 case SID_NAME_DOMAIN:
     181             :                 case SID_NAME_ALIAS:
     182             :                 case SID_NAME_WKN_GRP:
     183        1430 :                         DEBUG(5, ("init_lsa_rids: %s found\n", full_name));
     184             :                         /* Leave these unchanged */
     185        1430 :                         break;
     186           7 :                 default:
     187             :                         /* Don't hand out anything but the list above */
     188           7 :                         DEBUG(5, ("init_lsa_rids: %s not found\n", full_name));
     189           7 :                         type = SID_NAME_UNKNOWN;
     190           7 :                         break;
     191             :                 }
     192             : 
     193        1437 :                 rid = 0;
     194        1437 :                 dom_idx = -1;
     195             : 
     196        1437 :                 if (type != SID_NAME_UNKNOWN) {
     197        1430 :                         if (type == SID_NAME_DOMAIN) {
     198          16 :                                 rid = (uint32_t)-1;
     199             :                         } else {
     200        1414 :                                 sid_split_rid(&sid, &rid);
     201             :                         }
     202        1430 :                         dom_idx = init_lsa_ref_domain_list(mem_ctx, ref, domain, &sid);
     203        1430 :                         mapped_count++;
     204             :                 }
     205             : 
     206        1437 :                 prid[i].sid_type        = type;
     207        1437 :                 prid[i].rid             = rid;
     208        1437 :                 prid[i].sid_index       = dom_idx;
     209             :         }
     210             : 
     211        1417 :         *pmapped_count = mapped_count;
     212        1417 :         return NT_STATUS_OK;
     213             : }
     214             : 
     215             : /***************************************************************************
     216             :  lookup_lsa_sids. Must be called as root for lookup_name to work.
     217             :  ***************************************************************************/
     218             : 
     219           8 : static NTSTATUS lookup_lsa_sids(TALLOC_CTX *mem_ctx,
     220             :                                 struct lsa_RefDomainList *ref,
     221             :                                 struct lsa_TranslatedSid3 *trans_sids,
     222             :                                 uint32_t num_entries,
     223             :                                 struct lsa_String *name,
     224             :                                 int flags,
     225             :                                 uint32_t *pmapped_count)
     226             : {
     227             :         uint32_t mapped_count, i;
     228             : 
     229           8 :         SMB_ASSERT(num_entries <= MAX_LOOKUP_SIDS);
     230             : 
     231           8 :         mapped_count = 0;
     232           8 :         *pmapped_count = 0;
     233             : 
     234         222 :         for (i = 0; i < num_entries; i++) {
     235             :                 struct dom_sid sid;
     236             :                 uint32_t rid;
     237             :                 int dom_idx;
     238             :                 const char *full_name;
     239             :                 const char *domain;
     240             :                 enum lsa_SidType type;
     241             : 
     242         214 :                 ZERO_STRUCT(sid);
     243             : 
     244             :                 /* Split name into domain and user component */
     245             : 
     246         214 :                 full_name = name[i].string;
     247         214 :                 if (full_name == NULL) {
     248           0 :                         return NT_STATUS_NO_MEMORY;
     249             :                 }
     250             : 
     251         214 :                 DEBUG(5, ("lookup_lsa_sids: looking up name %s\n", full_name));
     252             : 
     253         214 :                 if (!lookup_name(mem_ctx, full_name, flags, &domain, NULL,
     254             :                                  &sid, &type)) {
     255           0 :                         type = SID_NAME_UNKNOWN;
     256             :                 }
     257             : 
     258         214 :                 switch (type) {
     259         214 :                 case SID_NAME_USER:
     260             :                 case SID_NAME_DOM_GRP:
     261             :                 case SID_NAME_DOMAIN:
     262             :                 case SID_NAME_ALIAS:
     263             :                 case SID_NAME_WKN_GRP:
     264         214 :                         DEBUG(5, ("lookup_lsa_sids: %s found\n", full_name));
     265             :                         /* Leave these unchanged */
     266         214 :                         break;
     267           0 :                 default:
     268             :                         /* Don't hand out anything but the list above */
     269           0 :                         DEBUG(5, ("lookup_lsa_sids: %s not found\n", full_name));
     270           0 :                         type = SID_NAME_UNKNOWN;
     271           0 :                         break;
     272             :                 }
     273             : 
     274         214 :                 rid = 0;
     275         214 :                 dom_idx = -1;
     276             : 
     277         214 :                 if (type != SID_NAME_UNKNOWN) {
     278             :                         struct dom_sid domain_sid;
     279         214 :                         sid_copy(&domain_sid, &sid);
     280         214 :                         sid_split_rid(&domain_sid, &rid);
     281         214 :                         dom_idx = init_lsa_ref_domain_list(mem_ctx, ref, domain, &domain_sid);
     282         214 :                         mapped_count++;
     283             :                 }
     284             : 
     285             :                 /* Initialize the lsa_TranslatedSid3 return. */
     286         214 :                 trans_sids[i].sid_type = type;
     287         214 :                 trans_sids[i].sid = dom_sid_dup(mem_ctx, &sid);
     288         214 :                 trans_sids[i].sid_index = dom_idx;
     289             :         }
     290             : 
     291           8 :         *pmapped_count = mapped_count;
     292           8 :         return NT_STATUS_OK;
     293             : }
     294             : 
     295        8051 : static NTSTATUS make_lsa_object_sd(TALLOC_CTX *mem_ctx, struct security_descriptor **sd, size_t *sd_size,
     296             :                                         const struct generic_mapping *map,
     297             :                                         struct dom_sid *sid, uint32_t sid_access)
     298             : {
     299             :         struct dom_sid adm_sid;
     300             :         struct security_ace ace[5];
     301        8051 :         size_t i = 0;
     302             : 
     303        8051 :         struct security_acl *psa = NULL;
     304             : 
     305             :         /* READ|EXECUTE access for Everyone */
     306             : 
     307        8051 :         init_sec_ace(&ace[i++], &global_sid_World, SEC_ACE_TYPE_ACCESS_ALLOWED,
     308        8051 :                         map->generic_execute | map->generic_read, 0);
     309             : 
     310             :         /* Add Full Access 'BUILTIN\Administrators' and 'BUILTIN\Account Operators */
     311             : 
     312        8051 :         init_sec_ace(&ace[i++], &global_sid_Builtin_Administrators,
     313          10 :                         SEC_ACE_TYPE_ACCESS_ALLOWED, map->generic_all, 0);
     314        8051 :         init_sec_ace(&ace[i++], &global_sid_Builtin_Account_Operators,
     315          10 :                         SEC_ACE_TYPE_ACCESS_ALLOWED, map->generic_all, 0);
     316             : 
     317             :         /* Add Full Access for Domain Admins */
     318        8051 :         sid_compose(&adm_sid, get_global_sam_sid(), DOMAIN_RID_ADMINS);
     319        8051 :         init_sec_ace(&ace[i++], &adm_sid, SEC_ACE_TYPE_ACCESS_ALLOWED,
     320          10 :                         map->generic_all, 0);
     321             : 
     322             :         /* If we have a sid, give it some special access */
     323             : 
     324        8051 :         if (sid) {
     325          16 :                 init_sec_ace(&ace[i++], sid, SEC_ACE_TYPE_ACCESS_ALLOWED,
     326             :                         sid_access, 0);
     327             :         }
     328             : 
     329        8051 :         if((psa = make_sec_acl(mem_ctx, NT4_ACL_REVISION, i, ace)) == NULL)
     330           0 :                 return NT_STATUS_NO_MEMORY;
     331             : 
     332        8051 :         if((*sd = make_sec_desc(mem_ctx, SECURITY_DESCRIPTOR_REVISION_1,
     333             :                                 SEC_DESC_SELF_RELATIVE, &adm_sid, NULL, NULL,
     334             :                                 psa, sd_size)) == NULL)
     335           0 :                 return NT_STATUS_NO_MEMORY;
     336             : 
     337        8051 :         return NT_STATUS_OK;
     338             : }
     339             : 
     340             : /***************************************************************************
     341             :  ***************************************************************************/
     342             : 
     343        8012 : static NTSTATUS create_lsa_policy_handle(TALLOC_CTX *mem_ctx,
     344             :                                          struct pipes_struct *p,
     345             :                                          enum lsa_handle_type type,
     346             :                                          uint32_t acc_granted,
     347             :                                          struct dom_sid *sid,
     348             :                                          const char *name,
     349             :                                          const struct security_descriptor *sd,
     350             :                                          struct policy_handle *handle)
     351             : {
     352             :         struct lsa_info *info;
     353             : 
     354        8012 :         ZERO_STRUCTP(handle);
     355             : 
     356        8012 :         info = talloc_zero(mem_ctx, struct lsa_info);
     357        8012 :         if (!info) {
     358           0 :                 return NT_STATUS_NO_MEMORY;
     359             :         }
     360             : 
     361        8012 :         info->type = type;
     362        8012 :         info->access = acc_granted;
     363             : 
     364        8012 :         if (sid) {
     365        7964 :                 sid_copy(&info->sid, sid);
     366             :         }
     367             : 
     368        8012 :         info->name = talloc_strdup(info, name);
     369             : 
     370        8012 :         if (sd != NULL) {
     371        8012 :                 info->sd = security_descriptor_copy(info, sd);
     372        8012 :                 if (info->sd == NULL) {
     373           0 :                         talloc_free(info);
     374           0 :                         return NT_STATUS_NO_MEMORY;
     375             :                 }
     376             :         }
     377             : 
     378        8012 :         if (!create_policy_hnd(p, handle, type, info)) {
     379           0 :                 talloc_free(info);
     380           0 :                 ZERO_STRUCTP(handle);
     381           0 :                 return NT_STATUS_NO_MEMORY;
     382             :         }
     383             : 
     384        8012 :         return NT_STATUS_OK;
     385             : }
     386             : 
     387             : /***************************************************************************
     388             :  _lsa_OpenPolicy2
     389             :  ***************************************************************************/
     390             : 
     391        7948 : NTSTATUS _lsa_OpenPolicy2(struct pipes_struct *p,
     392             :                           struct lsa_OpenPolicy2 *r)
     393             : {
     394        7948 :         struct security_descriptor *psd = NULL;
     395             :         size_t sd_size;
     396        7948 :         uint32_t des_access = r->in.access_mask;
     397             :         uint32_t acc_granted;
     398             :         NTSTATUS status;
     399             : 
     400        7948 :         if (p->transport != NCACN_NP && p->transport != NCALRPC) {
     401           0 :                 p->fault_state = DCERPC_FAULT_ACCESS_DENIED;
     402           0 :                 return NT_STATUS_ACCESS_DENIED;
     403             :         }
     404             : 
     405             :         /* Work out max allowed. */
     406        7948 :         map_max_allowed_access(p->session_info->security_token,
     407        7948 :                                p->session_info->unix_token,
     408             :                                &des_access);
     409             : 
     410             :         /* map the generic bits to the lsa policy ones */
     411        7948 :         se_map_generic(&des_access, &lsa_policy_mapping);
     412             : 
     413             :         /* get the generic lsa policy SD until we store it */
     414        7948 :         status = make_lsa_object_sd(p->mem_ctx, &psd, &sd_size, &lsa_policy_mapping,
     415             :                         NULL, 0);
     416        7948 :         if (!NT_STATUS_IS_OK(status)) {
     417           0 :                 return status;
     418             :         }
     419             : 
     420        7948 :         status = access_check_object(psd, p->session_info->security_token,
     421             :                                      SEC_PRIV_INVALID, SEC_PRIV_INVALID, 0, des_access,
     422             :                                      &acc_granted, "_lsa_OpenPolicy2" );
     423        7948 :         if (!NT_STATUS_IS_OK(status)) {
     424           0 :                 return status;
     425             :         }
     426             : 
     427        7948 :         status = create_lsa_policy_handle(p->mem_ctx, p,
     428             :                                           LSA_HANDLE_POLICY_TYPE,
     429             :                                           acc_granted,
     430             :                                           get_global_sam_sid(),
     431             :                                           NULL,
     432             :                                           psd,
     433             :                                           r->out.handle);
     434        7948 :         if (!NT_STATUS_IS_OK(status)) {
     435           0 :                 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
     436             :         }
     437             : 
     438        7948 :         return NT_STATUS_OK;
     439             : }
     440             : 
     441             : /***************************************************************************
     442             :  _lsa_OpenPolicy
     443             :  ***************************************************************************/
     444             : 
     445        7746 : NTSTATUS _lsa_OpenPolicy(struct pipes_struct *p,
     446             :                          struct lsa_OpenPolicy *r)
     447             : {
     448             :         struct lsa_OpenPolicy2 o;
     449             : 
     450             :         /* _lsa_OpenPolicy2 will check if this is a NCACN_NP connection */
     451             : 
     452        7746 :         o.in.system_name        = NULL; /* should be ignored */
     453        7746 :         o.in.attr               = r->in.attr;
     454        7746 :         o.in.access_mask        = r->in.access_mask;
     455             : 
     456        7746 :         o.out.handle            = r->out.handle;
     457             : 
     458        7746 :         return _lsa_OpenPolicy2(p, &o);
     459             : }
     460             : 
     461             : /***************************************************************************
     462             :  _lsa_EnumTrustDom - this needs fixing to do more than return NULL ! JRA.
     463             :  ufff, done :)  mimir
     464             :  ***************************************************************************/
     465             : 
     466           0 : NTSTATUS _lsa_EnumTrustDom(struct pipes_struct *p,
     467             :                            struct lsa_EnumTrustDom *r)
     468             : {
     469             :         struct lsa_info *info;
     470             :         uint32_t count;
     471             :         struct trustdom_info **domains;
     472             :         struct lsa_DomainInfo *entries;
     473             :         int i;
     474             :         NTSTATUS nt_status;
     475             : 
     476           0 :         info = find_policy_by_hnd(p,
     477             :                                   r->in.handle,
     478             :                                   LSA_HANDLE_POLICY_TYPE,
     479             :                                   struct lsa_info,
     480             :                                   &nt_status);
     481           0 :         if (!NT_STATUS_IS_OK(nt_status)) {
     482           0 :                 return NT_STATUS_INVALID_HANDLE;
     483             :         }
     484             : 
     485             :         /* check if the user has enough rights */
     486           0 :         if (!(info->access & LSA_POLICY_VIEW_LOCAL_INFORMATION))
     487           0 :                 return NT_STATUS_ACCESS_DENIED;
     488             : 
     489           0 :         become_root();
     490           0 :         nt_status = pdb_enum_trusteddoms(p->mem_ctx, &count, &domains);
     491           0 :         unbecome_root();
     492             : 
     493           0 :         if (!NT_STATUS_IS_OK(nt_status)) {
     494           0 :                 return nt_status;
     495             :         }
     496             : 
     497           0 :         entries = talloc_zero_array(p->mem_ctx, struct lsa_DomainInfo, count);
     498           0 :         if (!entries) {
     499           0 :                 return NT_STATUS_NO_MEMORY;
     500             :         }
     501             : 
     502           0 :         for (i=0; i<count; i++) {
     503           0 :                 init_lsa_StringLarge(&entries[i].name, domains[i]->name);
     504           0 :                 entries[i].sid = &domains[i]->sid;
     505             :         }
     506             : 
     507           0 :         if (*r->in.resume_handle >= count) {
     508           0 :                 *r->out.resume_handle = -1;
     509           0 :                 TALLOC_FREE(entries);
     510           0 :                 return NT_STATUS_NO_MORE_ENTRIES;
     511             :         }
     512             : 
     513             :         /* return the rest, limit by max_size. Note that we
     514             :            use the w2k3 element size value of 60 */
     515           0 :         r->out.domains->count = count - *r->in.resume_handle;
     516           0 :         r->out.domains->count = MIN(r->out.domains->count,
     517             :                                  1+(r->in.max_size/LSA_ENUM_TRUST_DOMAIN_MULTIPLIER));
     518             : 
     519           0 :         r->out.domains->domains = entries + *r->in.resume_handle;
     520             : 
     521           0 :         if (r->out.domains->count < count - *r->in.resume_handle) {
     522           0 :                 *r->out.resume_handle = *r->in.resume_handle + r->out.domains->count;
     523           0 :                 return STATUS_MORE_ENTRIES;
     524             :         }
     525             : 
     526             :         /* according to MS-LSAD 3.1.4.7.8 output resume handle MUST
     527             :          * always be larger than the previous input resume handle, in
     528             :          * particular when hitting the last query it is vital to set the
     529             :          * resume handle correctly to avoid infinite client loops, as
     530             :          * seen e.g. with Windows XP SP3 when resume handle is 0 and
     531             :          * status is NT_STATUS_OK - gd */
     532             : 
     533           0 :         *r->out.resume_handle = (uint32_t)-1;
     534             : 
     535           0 :         return NT_STATUS_OK;
     536             : }
     537             : 
     538             : #define LSA_AUDIT_NUM_CATEGORIES_NT4    7
     539             : #define LSA_AUDIT_NUM_CATEGORIES_WIN2K  9
     540             : #define LSA_AUDIT_NUM_CATEGORIES LSA_AUDIT_NUM_CATEGORIES_NT4
     541             : 
     542             : /***************************************************************************
     543             :  _lsa_QueryInfoPolicy
     544             :  ***************************************************************************/
     545             : 
     546         658 : NTSTATUS _lsa_QueryInfoPolicy(struct pipes_struct *p,
     547             :                               struct lsa_QueryInfoPolicy *r)
     548             : {
     549         658 :         NTSTATUS status = NT_STATUS_OK;
     550             :         struct lsa_info *handle;
     551             :         struct dom_sid domain_sid;
     552             :         const char *name;
     553         658 :         struct dom_sid *sid = NULL;
     554         658 :         union lsa_PolicyInformation *info = NULL;
     555         658 :         uint32_t acc_required = 0;
     556             : 
     557         658 :         handle = find_policy_by_hnd(p,
     558             :                                     r->in.handle,
     559             :                                     LSA_HANDLE_POLICY_TYPE,
     560             :                                     struct lsa_info,
     561             :                                     &status);
     562         658 :         if (!NT_STATUS_IS_OK(status)) {
     563           0 :                 return NT_STATUS_INVALID_HANDLE;
     564             :         }
     565             : 
     566         658 :         switch (r->in.level) {
     567           0 :         case LSA_POLICY_INFO_AUDIT_LOG:
     568             :         case LSA_POLICY_INFO_AUDIT_EVENTS:
     569           0 :                 acc_required = LSA_POLICY_VIEW_AUDIT_INFORMATION;
     570           0 :                 break;
     571          41 :         case LSA_POLICY_INFO_DOMAIN:
     572          41 :                 acc_required = LSA_POLICY_VIEW_LOCAL_INFORMATION;
     573          41 :                 break;
     574           0 :         case LSA_POLICY_INFO_PD:
     575           0 :                 acc_required = LSA_POLICY_GET_PRIVATE_INFORMATION;
     576           0 :                 break;
     577         617 :         case LSA_POLICY_INFO_ACCOUNT_DOMAIN:
     578         617 :                 acc_required = LSA_POLICY_VIEW_LOCAL_INFORMATION;
     579         617 :                 break;
     580           0 :         case LSA_POLICY_INFO_ROLE:
     581             :         case LSA_POLICY_INFO_REPLICA:
     582           0 :                 acc_required = LSA_POLICY_VIEW_LOCAL_INFORMATION;
     583           0 :                 break;
     584           0 :         case LSA_POLICY_INFO_QUOTA:
     585           0 :                 acc_required = LSA_POLICY_VIEW_LOCAL_INFORMATION;
     586           0 :                 break;
     587           0 :         case LSA_POLICY_INFO_MOD:
     588             :         case LSA_POLICY_INFO_AUDIT_FULL_SET:
     589             :                 /* according to MS-LSAD 3.1.4.4.3 */
     590           0 :                 return NT_STATUS_INVALID_PARAMETER;
     591           0 :         case LSA_POLICY_INFO_AUDIT_FULL_QUERY:
     592           0 :                 acc_required = LSA_POLICY_VIEW_AUDIT_INFORMATION;
     593           0 :                 break;
     594           0 :         case LSA_POLICY_INFO_DNS:
     595             :         case LSA_POLICY_INFO_DNS_INT:
     596             :         case LSA_POLICY_INFO_L_ACCOUNT_DOMAIN:
     597           0 :                 acc_required = LSA_POLICY_VIEW_LOCAL_INFORMATION;
     598           0 :                 break;
     599           0 :         default:
     600           0 :                 break;
     601             :         }
     602             : 
     603         658 :         if (!(handle->access & acc_required)) {
     604             :                 /* return NT_STATUS_ACCESS_DENIED; */
     605             :         }
     606             : 
     607         658 :         info = talloc_zero(p->mem_ctx, union lsa_PolicyInformation);
     608         658 :         if (!info) {
     609           0 :                 return NT_STATUS_NO_MEMORY;
     610             :         }
     611             : 
     612         658 :         switch (r->in.level) {
     613             :         /* according to MS-LSAD 3.1.4.4.3 */
     614           0 :         case LSA_POLICY_INFO_MOD:
     615             :         case LSA_POLICY_INFO_AUDIT_FULL_SET:
     616             :         case LSA_POLICY_INFO_AUDIT_FULL_QUERY:
     617           0 :                 return NT_STATUS_INVALID_PARAMETER;
     618           0 :         case LSA_POLICY_INFO_AUDIT_LOG:
     619           0 :                 info->audit_log.percent_full         = 0;
     620           0 :                 info->audit_log.maximum_log_size     = 0;
     621           0 :                 info->audit_log.retention_time               = 0;
     622           0 :                 info->audit_log.shutdown_in_progress = 0;
     623           0 :                 info->audit_log.time_to_shutdown     = 0;
     624           0 :                 info->audit_log.next_audit_record    = 0;
     625           0 :                 status = NT_STATUS_OK;
     626           0 :                 break;
     627           0 :         case LSA_POLICY_INFO_PD:
     628           0 :                 info->pd.name.string                 = NULL;
     629           0 :                 status = NT_STATUS_OK;
     630           0 :                 break;
     631           0 :         case LSA_POLICY_INFO_REPLICA:
     632           0 :                 info->replica.source.string          = NULL;
     633           0 :                 info->replica.account.string         = NULL;
     634           0 :                 status = NT_STATUS_OK;
     635           0 :                 break;
     636           0 :         case LSA_POLICY_INFO_QUOTA:
     637           0 :                 info->quota.paged_pool                       = 0;
     638           0 :                 info->quota.non_paged_pool           = 0;
     639           0 :                 info->quota.min_wss                  = 0;
     640           0 :                 info->quota.max_wss                  = 0;
     641           0 :                 info->quota.pagefile                 = 0;
     642           0 :                 info->quota.unknown                  = 0;
     643           0 :                 status = NT_STATUS_OK;
     644           0 :                 break;
     645           0 :         case LSA_POLICY_INFO_AUDIT_EVENTS:
     646             :                 {
     647             : 
     648           0 :                 uint32_t policy_def = LSA_AUDIT_POLICY_ALL;
     649             : 
     650             :                 /* check if the user has enough rights */
     651           0 :                 if (!(handle->access & LSA_POLICY_VIEW_AUDIT_INFORMATION)) {
     652           0 :                         DEBUG(10,("_lsa_QueryInfoPolicy: insufficient access rights\n"));
     653           0 :                         return NT_STATUS_ACCESS_DENIED;
     654             :                 }
     655             : 
     656             :                 /* fake info: We audit everything. ;) */
     657             : 
     658           0 :                 info->audit_events.auditing_mode = true;
     659           0 :                 info->audit_events.count = LSA_AUDIT_NUM_CATEGORIES;
     660           0 :                 info->audit_events.settings = talloc_zero_array(p->mem_ctx,
     661             :                                                                 enum lsa_PolicyAuditPolicy,
     662             :                                                                 info->audit_events.count);
     663           0 :                 if (!info->audit_events.settings) {
     664           0 :                         return NT_STATUS_NO_MEMORY;
     665             :                 }
     666             : 
     667           0 :                 info->audit_events.settings[LSA_AUDIT_CATEGORY_ACCOUNT_MANAGEMENT] = policy_def;
     668           0 :                 info->audit_events.settings[LSA_AUDIT_CATEGORY_FILE_AND_OBJECT_ACCESS] = policy_def;
     669           0 :                 info->audit_events.settings[LSA_AUDIT_CATEGORY_LOGON] = policy_def;
     670           0 :                 info->audit_events.settings[LSA_AUDIT_CATEGORY_PROCCESS_TRACKING] = policy_def;
     671           0 :                 info->audit_events.settings[LSA_AUDIT_CATEGORY_SECURITY_POLICY_CHANGES] = policy_def;
     672           0 :                 info->audit_events.settings[LSA_AUDIT_CATEGORY_SYSTEM] = policy_def;
     673           0 :                 info->audit_events.settings[LSA_AUDIT_CATEGORY_USE_OF_USER_RIGHTS] = policy_def;
     674             : 
     675           0 :                 break;
     676             :                 }
     677          41 :         case LSA_POLICY_INFO_DOMAIN:
     678             :                 /* check if the user has enough rights */
     679          41 :                 if (!(handle->access & LSA_POLICY_VIEW_LOCAL_INFORMATION))
     680           0 :                         return NT_STATUS_ACCESS_DENIED;
     681             : 
     682             :                 /* Request PolicyPrimaryDomainInformation. */
     683          41 :                 switch (lp_server_role()) {
     684          41 :                         case ROLE_DOMAIN_PDC:
     685             :                         case ROLE_DOMAIN_BDC:
     686          41 :                                 name = get_global_sam_name();
     687          41 :                                 sid = dom_sid_dup(p->mem_ctx, get_global_sam_sid());
     688          41 :                                 if (!sid) {
     689           0 :                                         return NT_STATUS_NO_MEMORY;
     690             :                                 }
     691          41 :                                 break;
     692           0 :                         case ROLE_DOMAIN_MEMBER:
     693           0 :                                 name = lp_workgroup();
     694             :                                 /* We need to return the Domain SID here. */
     695           0 :                                 if (secrets_fetch_domain_sid(lp_workgroup(), &domain_sid)) {
     696           0 :                                         sid = dom_sid_dup(p->mem_ctx, &domain_sid);
     697           0 :                                         if (!sid) {
     698           0 :                                                 return NT_STATUS_NO_MEMORY;
     699             :                                         }
     700             :                                 } else {
     701           0 :                                         return NT_STATUS_CANT_ACCESS_DOMAIN_INFO;
     702             :                                 }
     703           0 :                                 break;
     704           0 :                         case ROLE_STANDALONE:
     705           0 :                                 name = lp_workgroup();
     706           0 :                                 sid = NULL;
     707           0 :                                 break;
     708           0 :                         default:
     709           0 :                                 return NT_STATUS_CANT_ACCESS_DOMAIN_INFO;
     710             :                 }
     711          41 :                 init_dom_query_3(&info->domain, name, sid);
     712          41 :                 break;
     713         617 :         case LSA_POLICY_INFO_ACCOUNT_DOMAIN:
     714             :                 /* check if the user has enough rights */
     715         617 :                 if (!(handle->access & LSA_POLICY_VIEW_LOCAL_INFORMATION))
     716           0 :                         return NT_STATUS_ACCESS_DENIED;
     717             : 
     718             :                 /* Request PolicyAccountDomainInformation. */
     719         617 :                 name = get_global_sam_name();
     720         617 :                 sid = get_global_sam_sid();
     721             : 
     722         617 :                 init_dom_query_5(&info->account_domain, name, sid);
     723         617 :                 break;
     724           0 :         case LSA_POLICY_INFO_ROLE:
     725             :                 /* check if the user has enough rights */
     726           0 :                 if (!(handle->access & LSA_POLICY_VIEW_LOCAL_INFORMATION))
     727           0 :                         return NT_STATUS_ACCESS_DENIED;
     728             : 
     729           0 :                 switch (lp_server_role()) {
     730           0 :                         case ROLE_DOMAIN_BDC:
     731             :                                 /*
     732             :                                  * only a BDC is a backup controller
     733             :                                  * of the domain, it controls.
     734             :                                  */
     735           0 :                                 info->role.role = LSA_ROLE_BACKUP;
     736           0 :                                 break;
     737           0 :                         default:
     738             :                                 /*
     739             :                                  * any other role is a primary
     740             :                                  * of the domain, it controls.
     741             :                                  */
     742           0 :                                 info->role.role = LSA_ROLE_PRIMARY;
     743           0 :                                 break;
     744             :                 }
     745           0 :                 break;
     746           0 :         case LSA_POLICY_INFO_DNS:
     747             :         case LSA_POLICY_INFO_DNS_INT: {
     748             :                 struct pdb_domain_info *dominfo;
     749             : 
     750           0 :                 if ((pdb_capabilities() & PDB_CAP_ADS) == 0) {
     751           0 :                         DEBUG(10, ("Not replying to LSA_POLICY_INFO_DNS "
     752             :                                    "without ADS passdb backend\n"));
     753           0 :                         status = NT_STATUS_INVALID_INFO_CLASS;
     754           0 :                         break;
     755             :                 }
     756             : 
     757           0 :                 dominfo = pdb_get_domain_info(info);
     758           0 :                 if (dominfo == NULL) {
     759           0 :                         status = NT_STATUS_NO_MEMORY;
     760           0 :                         break;
     761             :                 }
     762             : 
     763           0 :                 init_lsa_StringLarge(&info->dns.name,
     764           0 :                                      dominfo->name);
     765           0 :                 init_lsa_StringLarge(&info->dns.dns_domain,
     766           0 :                                      dominfo->dns_domain);
     767           0 :                 init_lsa_StringLarge(&info->dns.dns_forest,
     768           0 :                                      dominfo->dns_forest);
     769           0 :                 info->dns.domain_guid = dominfo->guid;
     770           0 :                 info->dns.sid = &dominfo->sid;
     771           0 :                 break;
     772             :         }
     773           0 :         default:
     774           0 :                 DEBUG(0,("_lsa_QueryInfoPolicy: unknown info level in Lsa Query: %d\n",
     775             :                         r->in.level));
     776           0 :                 status = NT_STATUS_INVALID_INFO_CLASS;
     777           0 :                 break;
     778             :         }
     779             : 
     780         658 :         *r->out.info = info;
     781             : 
     782         658 :         return status;
     783             : }
     784             : 
     785             : /***************************************************************************
     786             :  _lsa_QueryInfoPolicy2
     787             :  ***************************************************************************/
     788             : 
     789          42 : NTSTATUS _lsa_QueryInfoPolicy2(struct pipes_struct *p,
     790             :                                struct lsa_QueryInfoPolicy2 *r2)
     791             : {
     792             :         struct lsa_QueryInfoPolicy r;
     793             : 
     794          42 :         if ((pdb_capabilities() & PDB_CAP_ADS) == 0) {
     795          42 :                 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
     796          42 :                 return NT_STATUS_NOT_IMPLEMENTED;
     797             :         }
     798             : 
     799           0 :         ZERO_STRUCT(r);
     800           0 :         r.in.handle = r2->in.handle;
     801           0 :         r.in.level = r2->in.level;
     802           0 :         r.out.info = r2->out.info;
     803             : 
     804           0 :         return _lsa_QueryInfoPolicy(p, &r);
     805             : }
     806             : 
     807             : /***************************************************************************
     808             :  _lsa_lookup_sids_internal
     809             :  ***************************************************************************/
     810             : 
     811        6007 : static NTSTATUS _lsa_lookup_sids_internal(struct pipes_struct *p,
     812             :                                           TALLOC_CTX *mem_ctx,
     813             :                                           uint16_t level,                       /* input */
     814             :                                           int num_sids,                         /* input */
     815             :                                           struct lsa_SidPtr *sid,               /* input */
     816             :                                           struct lsa_RefDomainList **pp_ref,    /* input/output */
     817             :                                           struct lsa_TranslatedName2 **pp_names,/* input/output */
     818             :                                           uint32_t *pp_mapped_count)            /* input/output */
     819             : {
     820             :         NTSTATUS status;
     821             :         int i;
     822        6007 :         const struct dom_sid **sids = NULL;
     823        6007 :         struct lsa_RefDomainList *ref = NULL;
     824        6007 :         uint32_t mapped_count = 0;
     825        6007 :         struct lsa_dom_info *dom_infos = NULL;
     826        6007 :         struct lsa_name_info *name_infos = NULL;
     827        6007 :         struct lsa_TranslatedName2 *names = NULL;
     828             : 
     829        6007 :         *pp_mapped_count = 0;
     830        6007 :         *pp_names = NULL;
     831        6007 :         *pp_ref = NULL;
     832             : 
     833        6007 :         if (num_sids == 0) {
     834           0 :                 return NT_STATUS_OK;
     835             :         }
     836             : 
     837        6007 :         sids = talloc_array(p->mem_ctx, const struct dom_sid *, num_sids);
     838        6007 :         ref = talloc_zero(p->mem_ctx, struct lsa_RefDomainList);
     839             : 
     840        6007 :         if (sids == NULL || ref == NULL) {
     841           0 :                 return NT_STATUS_NO_MEMORY;
     842             :         }
     843             : 
     844       12233 :         for (i=0; i<num_sids; i++) {
     845        6226 :                 sids[i] = sid[i].sid;
     846             :         }
     847             : 
     848        6007 :         status = lookup_sids(p->mem_ctx, num_sids, sids, level,
     849             :                                   &dom_infos, &name_infos);
     850             : 
     851        6007 :         if (!NT_STATUS_IS_OK(status)) {
     852           0 :                 return status;
     853             :         }
     854             : 
     855        6007 :         names = talloc_array(p->mem_ctx, struct lsa_TranslatedName2, num_sids);
     856        6007 :         if (names == NULL) {
     857           0 :                 return NT_STATUS_NO_MEMORY;
     858             :         }
     859             : 
     860       12018 :         for (i=0; i<LSA_REF_DOMAIN_LIST_MULTIPLIER; i++) {
     861             : 
     862       12018 :                 if (!dom_infos[i].valid) {
     863        6007 :                         break;
     864             :                 }
     865             : 
     866       12012 :                 if (init_lsa_ref_domain_list(mem_ctx, ref,
     867        6011 :                                              dom_infos[i].name,
     868        6011 :                                              &dom_infos[i].sid) != i) {
     869           0 :                         DEBUG(0, ("Domain %s mentioned twice??\n",
     870             :                                   dom_infos[i].name));
     871           0 :                         return NT_STATUS_INTERNAL_ERROR;
     872             :                 }
     873             :         }
     874             : 
     875       12233 :         for (i=0; i<num_sids; i++) {
     876        6226 :                 struct lsa_name_info *name = &name_infos[i];
     877             : 
     878        6226 :                 if (name->type == SID_NAME_UNKNOWN) {
     879          60 :                         name->dom_idx = -1;
     880             :                         /* Unknown sids should return the string
     881             :                          * representation of the SID. Windows 2003 behaves
     882             :                          * rather erratic here, in many cases it returns the
     883             :                          * RID as 8 bytes hex, in others it returns the full
     884             :                          * SID. We (Jerry/VL) could not figure out which the
     885             :                          * hard cases are, so leave it with the SID.  */
     886          60 :                         name->name = dom_sid_string(p->mem_ctx, sids[i]);
     887          60 :                         if (name->name == NULL) {
     888           0 :                                 return NT_STATUS_NO_MEMORY;
     889             :                         }
     890             :                 } else {
     891        6166 :                         mapped_count += 1;
     892             :                 }
     893             : 
     894        6226 :                 names[i].sid_type       = name->type;
     895        6226 :                 names[i].name.string    = name->name;
     896        6226 :                 names[i].sid_index      = name->dom_idx;
     897        6226 :                 names[i].unknown        = 0;
     898             :         }
     899             : 
     900        6007 :         status = NT_STATUS_NONE_MAPPED;
     901        6007 :         if (mapped_count > 0) {
     902        5948 :                 status = (mapped_count < num_sids) ?
     903             :                         STATUS_SOME_UNMAPPED : NT_STATUS_OK;
     904             :         }
     905             : 
     906        6007 :         DEBUG(10, ("num_sids %d, mapped_count %d, status %s\n",
     907             :                    num_sids, mapped_count, nt_errstr(status)));
     908             : 
     909        6007 :         *pp_mapped_count = mapped_count;
     910        6007 :         *pp_names = names;
     911        6007 :         *pp_ref = ref;
     912             : 
     913        6007 :         return status;
     914             : }
     915             : 
     916             : /***************************************************************************
     917             :  _lsa_LookupSids
     918             :  ***************************************************************************/
     919             : 
     920        6003 : NTSTATUS _lsa_LookupSids(struct pipes_struct *p,
     921             :                          struct lsa_LookupSids *r)
     922             : {
     923             :         NTSTATUS status;
     924             :         struct lsa_info *handle;
     925        6003 :         int num_sids = r->in.sids->num_sids;
     926        6003 :         uint32_t mapped_count = 0;
     927        6003 :         struct lsa_RefDomainList *domains = NULL;
     928        6003 :         struct lsa_TranslatedName *names_out = NULL;
     929        6003 :         struct lsa_TranslatedName2 *names = NULL;
     930             :         int i;
     931             : 
     932        6003 :         if (p->transport != NCACN_NP && p->transport != NCALRPC) {
     933           0 :                 p->fault_state = DCERPC_FAULT_ACCESS_DENIED;
     934           0 :                 return NT_STATUS_ACCESS_DENIED;
     935             :         }
     936             : 
     937        6003 :         if ((r->in.level < 1) || (r->in.level > 6)) {
     938           0 :                 return NT_STATUS_INVALID_PARAMETER;
     939             :         }
     940             : 
     941        6003 :         handle = find_policy_by_hnd(p,
     942             :                                     r->in.handle,
     943             :                                     LSA_HANDLE_POLICY_TYPE,
     944             :                                     struct lsa_info,
     945             :                                     &status);
     946        6003 :         if (!NT_STATUS_IS_OK(status)) {
     947           0 :                 return NT_STATUS_INVALID_HANDLE;
     948             :         }
     949             : 
     950             :         /* check if the user has enough rights */
     951        6003 :         if (!(handle->access & LSA_POLICY_LOOKUP_NAMES)) {
     952           0 :                 return NT_STATUS_ACCESS_DENIED;
     953             :         }
     954             : 
     955        6003 :         if (num_sids >  MAX_LOOKUP_SIDS) {
     956           0 :                 DEBUG(5,("_lsa_LookupSids: limit of %d exceeded, requested %d\n",
     957             :                          MAX_LOOKUP_SIDS, num_sids));
     958           0 :                 return NT_STATUS_NONE_MAPPED;
     959             :         }
     960             : 
     961       11996 :         status = _lsa_lookup_sids_internal(p,
     962             :                                            p->mem_ctx,
     963        6003 :                                            r->in.level,
     964             :                                            num_sids,
     965        6003 :                                            r->in.sids->sids,
     966             :                                            &domains,
     967             :                                            &names,
     968             :                                            &mapped_count);
     969             : 
     970             :         /* Only return here when there is a real error.
     971             :            NT_STATUS_NONE_MAPPED is a special case as it indicates that none of
     972             :            the requested sids could be resolved. Older versions of XP (pre SP3)
     973             :            rely that we return with the string representations of those SIDs in
     974             :            that case. If we don't, XP crashes - Guenther
     975             :            */
     976             : 
     977        6052 :         if (NT_STATUS_IS_ERR(status) &&
     978          59 :             !NT_STATUS_EQUAL(status, NT_STATUS_NONE_MAPPED)) {
     979           0 :                 return status;
     980             :         }
     981             : 
     982             :         /* Convert from lsa_TranslatedName2 to lsa_TranslatedName */
     983        6003 :         names_out = talloc_array(p->mem_ctx, struct lsa_TranslatedName,
     984             :                                  num_sids);
     985        6003 :         if (!names_out) {
     986           0 :                 return NT_STATUS_NO_MEMORY;
     987             :         }
     988             : 
     989       12017 :         for (i=0; i<num_sids; i++) {
     990        6014 :                 names_out[i].sid_type = names[i].sid_type;
     991        6014 :                 names_out[i].name = names[i].name;
     992        6014 :                 names_out[i].sid_index = names[i].sid_index;
     993             :         }
     994             : 
     995        6003 :         *r->out.domains = domains;
     996        6003 :         r->out.names->count = num_sids;
     997        6003 :         r->out.names->names = names_out;
     998        6003 :         *r->out.count = mapped_count;
     999             : 
    1000        6003 :         return status;
    1001             : }
    1002             : 
    1003           4 : static NTSTATUS _lsa_LookupSids_common(struct pipes_struct *p,
    1004             :                                 struct lsa_LookupSids2 *r)
    1005             : {
    1006             :         NTSTATUS status;
    1007             :         struct lsa_info *handle;
    1008           4 :         int num_sids = r->in.sids->num_sids;
    1009           4 :         uint32_t mapped_count = 0;
    1010           4 :         struct lsa_RefDomainList *domains = NULL;
    1011           4 :         struct lsa_TranslatedName2 *names = NULL;
    1012           4 :         bool check_policy = true;
    1013             : 
    1014           4 :         switch (p->opnum) {
    1015           2 :                 case NDR_LSA_LOOKUPSIDS3:
    1016           2 :                         check_policy = false;
    1017           2 :                         break;
    1018           2 :                 case NDR_LSA_LOOKUPSIDS2:
    1019             :                 default:
    1020           2 :                         check_policy = true;
    1021             :         }
    1022             : 
    1023           4 :         if ((r->in.level < 1) || (r->in.level > 6)) {
    1024           0 :                 return NT_STATUS_INVALID_PARAMETER;
    1025             :         }
    1026             : 
    1027           4 :         if (check_policy) {
    1028           2 :                 handle = find_policy_by_hnd(p,
    1029             :                                             r->in.handle,
    1030             :                                             LSA_HANDLE_POLICY_TYPE,
    1031             :                                             struct lsa_info,
    1032             :                                             &status);
    1033           2 :                 if (!NT_STATUS_IS_OK(status)) {
    1034           0 :                         return NT_STATUS_INVALID_HANDLE;
    1035             :                 }
    1036             : 
    1037             :                 /* check if the user has enough rights */
    1038           2 :                 if (!(handle->access & LSA_POLICY_LOOKUP_NAMES)) {
    1039           0 :                         return NT_STATUS_ACCESS_DENIED;
    1040             :                 }
    1041             :         }
    1042             : 
    1043           4 :         if (num_sids >  MAX_LOOKUP_SIDS) {
    1044           0 :                 DEBUG(5,("_lsa_LookupSids2: limit of %d exceeded, requested %d\n",
    1045             :                          MAX_LOOKUP_SIDS, num_sids));
    1046           0 :                 return NT_STATUS_NONE_MAPPED;
    1047             :         }
    1048             : 
    1049           8 :         status = _lsa_lookup_sids_internal(p,
    1050             :                                            p->mem_ctx,
    1051           4 :                                            r->in.level,
    1052             :                                            num_sids,
    1053           4 :                                            r->in.sids->sids,
    1054             :                                            &domains,
    1055             :                                            &names,
    1056             :                                            &mapped_count);
    1057             : 
    1058           4 :         *r->out.domains = domains;
    1059           4 :         r->out.names->count = num_sids;
    1060           4 :         r->out.names->names = names;
    1061           4 :         *r->out.count = mapped_count;
    1062             : 
    1063           4 :         return status;
    1064             : }
    1065             : 
    1066             : /***************************************************************************
    1067             :  _lsa_LookupSids2
    1068             :  ***************************************************************************/
    1069             : 
    1070           2 : NTSTATUS _lsa_LookupSids2(struct pipes_struct *p,
    1071             :                           struct lsa_LookupSids2 *r)
    1072             : {
    1073           2 :         if (p->transport != NCACN_NP && p->transport != NCALRPC) {
    1074           0 :                 p->fault_state = DCERPC_FAULT_ACCESS_DENIED;
    1075           0 :                 return NT_STATUS_ACCESS_DENIED;
    1076             :         }
    1077             : 
    1078           2 :         return _lsa_LookupSids_common(p, r);
    1079             : }
    1080             : 
    1081             : /***************************************************************************
    1082             :  _lsa_LookupSids3
    1083             :  ***************************************************************************/
    1084             : 
    1085           2 : NTSTATUS _lsa_LookupSids3(struct pipes_struct *p,
    1086             :                           struct lsa_LookupSids3 *r)
    1087             : {
    1088             :         struct lsa_LookupSids2 q;
    1089             : 
    1090           2 :         if (p->transport != NCACN_IP_TCP) {
    1091           0 :                 p->fault_state = DCERPC_FAULT_ACCESS_DENIED;
    1092           0 :                 return NT_STATUS_ACCESS_DENIED;
    1093             :         }
    1094             : 
    1095             :         /* No policy handle on this call. Restrict to crypto connections. */
    1096           4 :         if (p->auth.auth_type != DCERPC_AUTH_TYPE_SCHANNEL ||
    1097           2 :             p->auth.auth_level < DCERPC_AUTH_LEVEL_INTEGRITY) {
    1098           0 :                 DEBUG(1, ("_lsa_LookupSids3: The client %s is not using "
    1099             :                           "a secure connection over netlogon\n",
    1100             :                           get_remote_machine_name() ));
    1101           0 :                 p->fault_state = DCERPC_FAULT_ACCESS_DENIED;
    1102           0 :                 return NT_STATUS_ACCESS_DENIED;
    1103             :         }
    1104             : 
    1105           2 :         q.in.handle             = NULL;
    1106           2 :         q.in.sids               = r->in.sids;
    1107           2 :         q.in.level              = r->in.level;
    1108           2 :         q.in.lookup_options     = r->in.lookup_options;
    1109           2 :         q.in.client_revision    = r->in.client_revision;
    1110           2 :         q.in.names              = r->in.names;
    1111           2 :         q.in.count              = r->in.count;
    1112             : 
    1113           2 :         q.out.domains           = r->out.domains;
    1114           2 :         q.out.names             = r->out.names;
    1115           2 :         q.out.count             = r->out.count;
    1116             : 
    1117           2 :         return _lsa_LookupSids_common(p, &q);
    1118             : }
    1119             : 
    1120             : /***************************************************************************
    1121             :  ***************************************************************************/
    1122             : 
    1123        1425 : static int lsa_lookup_level_to_flags(enum lsa_LookupNamesLevel level)
    1124             : {
    1125             :         int flags;
    1126             : 
    1127        1425 :         switch (level) {
    1128        1425 :                 case LSA_LOOKUP_NAMES_ALL: /* 1 */
    1129        1425 :                         flags = LOOKUP_NAME_ALL;
    1130        1425 :                         break;
    1131           0 :                 case LSA_LOOKUP_NAMES_DOMAINS_ONLY: /* 2 */
    1132           0 :                         flags = LOOKUP_NAME_DOMAIN|LOOKUP_NAME_REMOTE|LOOKUP_NAME_ISOLATED;
    1133           0 :                         break;
    1134           0 :                 case LSA_LOOKUP_NAMES_PRIMARY_DOMAIN_ONLY: /* 3 */
    1135           0 :                         flags = LOOKUP_NAME_DOMAIN|LOOKUP_NAME_ISOLATED;
    1136           0 :                         break;
    1137           0 :                 case LSA_LOOKUP_NAMES_UPLEVEL_TRUSTS_ONLY: /* 4 */
    1138             :                 case LSA_LOOKUP_NAMES_FOREST_TRUSTS_ONLY: /* 5 */
    1139             :                 case LSA_LOOKUP_NAMES_UPLEVEL_TRUSTS_ONLY2: /* 6 */
    1140             :                 case LSA_LOOKUP_NAMES_RODC_REFERRAL_TO_FULL_DC: /* 7 */
    1141             :                 default:
    1142           0 :                         flags = LOOKUP_NAME_NONE;
    1143           0 :                         break;
    1144             :         }
    1145             : 
    1146        1425 :         return flags;
    1147             : }
    1148             : 
    1149             : /***************************************************************************
    1150             :  _lsa_LookupNames
    1151             :  ***************************************************************************/
    1152             : 
    1153        1417 : NTSTATUS _lsa_LookupNames(struct pipes_struct *p,
    1154             :                           struct lsa_LookupNames *r)
    1155             : {
    1156        1417 :         NTSTATUS status = NT_STATUS_NONE_MAPPED;
    1157             :         struct lsa_info *handle;
    1158        1417 :         struct lsa_String *names = r->in.names;
    1159        1417 :         uint32_t num_entries = r->in.num_names;
    1160        1417 :         struct lsa_RefDomainList *domains = NULL;
    1161        1417 :         struct lsa_TranslatedSid *rids = NULL;
    1162        1417 :         uint32_t mapped_count = 0;
    1163        1417 :         int flags = 0;
    1164             : 
    1165        1417 :         if (p->transport != NCACN_NP && p->transport != NCALRPC) {
    1166           0 :                 p->fault_state = DCERPC_FAULT_ACCESS_DENIED;
    1167           0 :                 return NT_STATUS_ACCESS_DENIED;
    1168             :         }
    1169             : 
    1170        1417 :         if (num_entries >  MAX_LOOKUP_SIDS) {
    1171           0 :                 num_entries = MAX_LOOKUP_SIDS;
    1172           0 :                 DEBUG(5,("_lsa_LookupNames: truncating name lookup list to %d\n",
    1173             :                         num_entries));
    1174             :         }
    1175             : 
    1176        1417 :         flags = lsa_lookup_level_to_flags(r->in.level);
    1177             : 
    1178        1417 :         domains = talloc_zero(p->mem_ctx, struct lsa_RefDomainList);
    1179        1417 :         if (!domains) {
    1180           0 :                 return NT_STATUS_NO_MEMORY;
    1181             :         }
    1182             : 
    1183        1417 :         if (num_entries) {
    1184        1417 :                 rids = talloc_zero_array(p->mem_ctx, struct lsa_TranslatedSid,
    1185             :                                          num_entries);
    1186        1417 :                 if (!rids) {
    1187           0 :                         return NT_STATUS_NO_MEMORY;
    1188             :                 }
    1189             :         } else {
    1190           0 :                 rids = NULL;
    1191             :         }
    1192             : 
    1193        1417 :         handle = find_policy_by_hnd(p,
    1194             :                                     r->in.handle,
    1195             :                                     LSA_HANDLE_POLICY_TYPE,
    1196             :                                     struct lsa_info,
    1197             :                                     &status);
    1198        1417 :         if (!NT_STATUS_IS_OK(status)) {
    1199           0 :                 status = NT_STATUS_INVALID_HANDLE;
    1200           0 :                 goto done;
    1201             :         }
    1202             : 
    1203             :         /* check if the user has enough rights */
    1204        1417 :         if (!(handle->access & LSA_POLICY_LOOKUP_NAMES)) {
    1205           0 :                 status = NT_STATUS_ACCESS_DENIED;
    1206           0 :                 goto done;
    1207             :         }
    1208             : 
    1209             :         /* set up the LSA Lookup RIDs response */
    1210        1417 :         become_root(); /* lookup_name can require root privs */
    1211        1417 :         status = lookup_lsa_rids(p->mem_ctx, domains, rids, num_entries,
    1212             :                                  names, flags, &mapped_count);
    1213        1417 :         unbecome_root();
    1214             : 
    1215        1417 : done:
    1216             : 
    1217        1417 :         if (NT_STATUS_IS_OK(status) && (num_entries != 0) ) {
    1218        1417 :                 if (mapped_count == 0) {
    1219           7 :                         status = NT_STATUS_NONE_MAPPED;
    1220        1410 :                 } else if (mapped_count != num_entries) {
    1221           0 :                         status = STATUS_SOME_UNMAPPED;
    1222             :                 }
    1223             :         }
    1224             : 
    1225        1417 :         *r->out.count = mapped_count;
    1226        1417 :         *r->out.domains = domains;
    1227        1417 :         r->out.sids->sids = rids;
    1228        1417 :         r->out.sids->count = num_entries;
    1229             : 
    1230        1417 :         return status;
    1231             : }
    1232             : 
    1233             : /***************************************************************************
    1234             :  _lsa_LookupNames2
    1235             :  ***************************************************************************/
    1236             : 
    1237           4 : NTSTATUS _lsa_LookupNames2(struct pipes_struct *p,
    1238             :                            struct lsa_LookupNames2 *r)
    1239             : {
    1240             :         NTSTATUS status;
    1241             :         struct lsa_LookupNames q;
    1242           4 :         struct lsa_TransSidArray2 *sid_array2 = r->in.sids;
    1243           4 :         struct lsa_TransSidArray *sid_array = NULL;
    1244             :         uint32_t i;
    1245             : 
    1246           4 :         if (p->transport != NCACN_NP && p->transport != NCALRPC) {
    1247           0 :                 p->fault_state = DCERPC_FAULT_ACCESS_DENIED;
    1248           0 :                 return NT_STATUS_ACCESS_DENIED;
    1249             :         }
    1250             : 
    1251           4 :         sid_array = talloc_zero(p->mem_ctx, struct lsa_TransSidArray);
    1252           4 :         if (!sid_array) {
    1253           0 :                 return NT_STATUS_NO_MEMORY;
    1254             :         }
    1255             : 
    1256           4 :         q.in.handle             = r->in.handle;
    1257           4 :         q.in.num_names          = r->in.num_names;
    1258           4 :         q.in.names              = r->in.names;
    1259           4 :         q.in.level              = r->in.level;
    1260           4 :         q.in.sids               = sid_array;
    1261           4 :         q.in.count              = r->in.count;
    1262             :         /* we do not know what this is for */
    1263             :         /*                      = r->in.unknown1; */
    1264             :         /*                      = r->in.unknown2; */
    1265             : 
    1266           4 :         q.out.domains           = r->out.domains;
    1267           4 :         q.out.sids              = sid_array;
    1268           4 :         q.out.count             = r->out.count;
    1269             : 
    1270           4 :         status = _lsa_LookupNames(p, &q);
    1271             : 
    1272           4 :         sid_array2->count = sid_array->count;
    1273           4 :         sid_array2->sids = talloc_array(p->mem_ctx, struct lsa_TranslatedSid2, sid_array->count);
    1274           4 :         if (!sid_array2->sids) {
    1275           0 :                 return NT_STATUS_NO_MEMORY;
    1276             :         }
    1277             : 
    1278          18 :         for (i=0; i<sid_array->count; i++) {
    1279          14 :                 sid_array2->sids[i].sid_type  = sid_array->sids[i].sid_type;
    1280          14 :                 sid_array2->sids[i].rid       = sid_array->sids[i].rid;
    1281          14 :                 sid_array2->sids[i].sid_index = sid_array->sids[i].sid_index;
    1282          14 :                 sid_array2->sids[i].unknown   = 0;
    1283             :         }
    1284             : 
    1285           4 :         r->out.sids = sid_array2;
    1286             : 
    1287           4 :         return status;
    1288             : }
    1289             : 
    1290           8 : static NTSTATUS _lsa_LookupNames_common(struct pipes_struct *p,
    1291             :                                         struct lsa_LookupNames3 *r)
    1292             : {
    1293             :         NTSTATUS status;
    1294             :         struct lsa_info *handle;
    1295           8 :         struct lsa_String *names = r->in.names;
    1296           8 :         uint32_t num_entries = r->in.num_names;
    1297           8 :         struct lsa_RefDomainList *domains = NULL;
    1298           8 :         struct lsa_TranslatedSid3 *trans_sids = NULL;
    1299           8 :         uint32_t mapped_count = 0;
    1300           8 :         int flags = 0;
    1301           8 :         bool check_policy = true;
    1302             : 
    1303           8 :         switch (p->opnum) {
    1304           4 :                 case NDR_LSA_LOOKUPNAMES4:
    1305           4 :                         check_policy = false;
    1306           4 :                         break;
    1307           4 :                 case NDR_LSA_LOOKUPNAMES3:
    1308             :                 default:
    1309           4 :                         check_policy = true;
    1310             :         }
    1311             : 
    1312           8 :         if (num_entries >  MAX_LOOKUP_SIDS) {
    1313           0 :                 num_entries = MAX_LOOKUP_SIDS;
    1314           0 :                 DEBUG(5,("_lsa_LookupNames3: truncating name lookup list to %d\n", num_entries));
    1315             :         }
    1316             : 
    1317           8 :         flags = lsa_lookup_level_to_flags(r->in.level);
    1318             : 
    1319           8 :         domains = talloc_zero(p->mem_ctx, struct lsa_RefDomainList);
    1320           8 :         if (!domains) {
    1321           0 :                 return NT_STATUS_NO_MEMORY;
    1322             :         }
    1323             : 
    1324           8 :         if (num_entries) {
    1325           6 :                 trans_sids = talloc_zero_array(p->mem_ctx, struct lsa_TranslatedSid3,
    1326             :                                                num_entries);
    1327           6 :                 if (!trans_sids) {
    1328           0 :                         return NT_STATUS_NO_MEMORY;
    1329             :                 }
    1330             :         } else {
    1331           2 :                 trans_sids = NULL;
    1332             :         }
    1333             : 
    1334           8 :         if (check_policy) {
    1335             : 
    1336           4 :                 handle = find_policy_by_hnd(p,
    1337             :                                             r->in.handle,
    1338             :                                             LSA_HANDLE_POLICY_TYPE,
    1339             :                                             struct lsa_info,
    1340             :                                             &status);
    1341           4 :                 if (!NT_STATUS_IS_OK(status)) {
    1342           0 :                         status = NT_STATUS_INVALID_HANDLE;
    1343           0 :                         goto done;
    1344             :                 }
    1345             : 
    1346             :                 /* check if the user has enough rights */
    1347           4 :                 if (!(handle->access & LSA_POLICY_LOOKUP_NAMES)) {
    1348           0 :                         status = NT_STATUS_ACCESS_DENIED;
    1349           0 :                         goto done;
    1350             :                 }
    1351             :         }
    1352             : 
    1353             :         /* set up the LSA Lookup SIDs response */
    1354           8 :         become_root(); /* lookup_name can require root privs */
    1355           8 :         status = lookup_lsa_sids(p->mem_ctx, domains, trans_sids, num_entries,
    1356             :                                  names, flags, &mapped_count);
    1357           8 :         unbecome_root();
    1358             : 
    1359           8 : done:
    1360             : 
    1361           8 :         if (NT_STATUS_IS_OK(status)) {
    1362           8 :                 if (mapped_count == 0) {
    1363           2 :                         status = NT_STATUS_NONE_MAPPED;
    1364           6 :                 } else if (mapped_count != num_entries) {
    1365           0 :                         status = STATUS_SOME_UNMAPPED;
    1366             :                 }
    1367             :         }
    1368             : 
    1369           8 :         *r->out.count = mapped_count;
    1370           8 :         *r->out.domains = domains;
    1371           8 :         r->out.sids->sids = trans_sids;
    1372           8 :         r->out.sids->count = num_entries;
    1373             : 
    1374           8 :         return status;
    1375             : }
    1376             : 
    1377             : /***************************************************************************
    1378             :  _lsa_LookupNames3
    1379             :  ***************************************************************************/
    1380             : 
    1381           4 : NTSTATUS _lsa_LookupNames3(struct pipes_struct *p,
    1382             :                            struct lsa_LookupNames3 *r)
    1383             : {
    1384           4 :         if (p->transport != NCACN_NP && p->transport != NCALRPC) {
    1385           0 :                 p->fault_state = DCERPC_FAULT_ACCESS_DENIED;
    1386           0 :                 return NT_STATUS_ACCESS_DENIED;
    1387             :         }
    1388             : 
    1389           4 :         return _lsa_LookupNames_common(p, r);
    1390             : }
    1391             : 
    1392             : /***************************************************************************
    1393             :  _lsa_LookupNames4
    1394             :  ***************************************************************************/
    1395             : 
    1396           4 : NTSTATUS _lsa_LookupNames4(struct pipes_struct *p,
    1397             :                            struct lsa_LookupNames4 *r)
    1398             : {
    1399             :         struct lsa_LookupNames3 q;
    1400             : 
    1401           4 :         if (p->transport != NCACN_IP_TCP) {
    1402           0 :                 p->fault_state = DCERPC_FAULT_ACCESS_DENIED;
    1403           0 :                 return NT_STATUS_ACCESS_DENIED;
    1404             :         }
    1405             : 
    1406             :         /* No policy handle on this call. Restrict to crypto connections. */
    1407           8 :         if (p->auth.auth_type != DCERPC_AUTH_TYPE_SCHANNEL ||
    1408           4 :             p->auth.auth_level < DCERPC_AUTH_LEVEL_INTEGRITY) {
    1409           0 :                 DEBUG(1, ("_lsa_LookupNames4: The client %s is not using "
    1410             :                           "a secure connection over netlogon\n",
    1411             :                           get_remote_machine_name()));
    1412           0 :                 p->fault_state = DCERPC_FAULT_ACCESS_DENIED;
    1413           0 :                 return NT_STATUS_ACCESS_DENIED;
    1414             :         }
    1415             : 
    1416           4 :         q.in.handle             = NULL;
    1417           4 :         q.in.num_names          = r->in.num_names;
    1418           4 :         q.in.names              = r->in.names;
    1419           4 :         q.in.level              = r->in.level;
    1420           4 :         q.in.lookup_options     = r->in.lookup_options;
    1421           4 :         q.in.client_revision    = r->in.client_revision;
    1422           4 :         q.in.sids               = r->in.sids;
    1423           4 :         q.in.count              = r->in.count;
    1424             : 
    1425           4 :         q.out.domains           = r->out.domains;
    1426           4 :         q.out.sids              = r->out.sids;
    1427           4 :         q.out.count             = r->out.count;
    1428             : 
    1429           4 :         return _lsa_LookupNames_common(p, &q);
    1430             : }
    1431             : 
    1432             : /***************************************************************************
    1433             :  _lsa_close. Also weird - needs to check if lsa handle is correct. JRA.
    1434             :  ***************************************************************************/
    1435             : 
    1436         747 : NTSTATUS _lsa_Close(struct pipes_struct *p, struct lsa_Close *r)
    1437             : {
    1438             :         NTSTATUS status;
    1439             : 
    1440         747 :         if (p->transport != NCACN_NP && p->transport != NCALRPC) {
    1441           0 :                 p->fault_state = DCERPC_FAULT_ACCESS_DENIED;
    1442           0 :                 return NT_STATUS_ACCESS_DENIED;
    1443             :         }
    1444             : 
    1445         747 :         (void)find_policy_by_hnd(p,
    1446             :                                  r->in.handle,
    1447             :                                  DCESRV_HANDLE_ANY,
    1448             :                                  struct lsa_info,
    1449             :                                  &status);
    1450         747 :         if (!NT_STATUS_IS_OK(status)) {
    1451           6 :                 return NT_STATUS_INVALID_HANDLE;
    1452             :         }
    1453             : 
    1454         741 :         close_policy_hnd(p, r->in.handle);
    1455         741 :         ZERO_STRUCTP(r->out.handle);
    1456         741 :         return NT_STATUS_OK;
    1457             : }
    1458             : 
    1459             : /***************************************************************************
    1460             :  ***************************************************************************/
    1461             : 
    1462           0 : static NTSTATUS lsa_lookup_trusted_domain_by_sid(TALLOC_CTX *mem_ctx,
    1463             :                                                  const struct dom_sid *sid,
    1464             :                                                  struct trustdom_info **info)
    1465             : {
    1466             :         NTSTATUS status;
    1467           0 :         uint32_t num_domains = 0;
    1468           0 :         struct trustdom_info **domains = NULL;
    1469             :         int i;
    1470             : 
    1471           0 :         status = pdb_enum_trusteddoms(mem_ctx, &num_domains, &domains);
    1472           0 :         if (!NT_STATUS_IS_OK(status)) {
    1473           0 :                 return status;
    1474             :         }
    1475             : 
    1476           0 :         for (i=0; i < num_domains; i++) {
    1477           0 :                 if (dom_sid_equal(&domains[i]->sid, sid)) {
    1478           0 :                         break;
    1479             :                 }
    1480             :         }
    1481             : 
    1482           0 :         if (i == num_domains) {
    1483           0 :                 return NT_STATUS_INVALID_PARAMETER;
    1484             :         }
    1485             : 
    1486           0 :         *info = domains[i];
    1487             : 
    1488           0 :         return NT_STATUS_OK;
    1489             : }
    1490             : 
    1491             : /***************************************************************************
    1492             :  ***************************************************************************/
    1493             : 
    1494           0 : static NTSTATUS lsa_lookup_trusted_domain_by_name(TALLOC_CTX *mem_ctx,
    1495             :                                                   const char *netbios_domain_name,
    1496             :                                                   struct trustdom_info **info_p)
    1497             : {
    1498             :         NTSTATUS status;
    1499             :         struct trustdom_info *info;
    1500             :         struct pdb_trusted_domain *td;
    1501             : 
    1502           0 :         status = pdb_get_trusted_domain(mem_ctx, netbios_domain_name, &td);
    1503           0 :         if (!NT_STATUS_IS_OK(status)) {
    1504           0 :                 return status;
    1505             :         }
    1506             : 
    1507           0 :         info = talloc(mem_ctx, struct trustdom_info);
    1508           0 :         if (!info) {
    1509           0 :                 return NT_STATUS_NO_MEMORY;
    1510             :         }
    1511             : 
    1512           0 :         info->name   = talloc_strdup(info, netbios_domain_name);
    1513           0 :         NT_STATUS_HAVE_NO_MEMORY(info->name);
    1514             : 
    1515           0 :         sid_copy(&info->sid, &td->security_identifier);
    1516             : 
    1517           0 :         *info_p = info;
    1518             : 
    1519           0 :         return NT_STATUS_OK;
    1520             : }
    1521             : 
    1522             : /***************************************************************************
    1523             :  _lsa_OpenSecret
    1524             :  ***************************************************************************/
    1525             : 
    1526           0 : NTSTATUS _lsa_OpenSecret(struct pipes_struct *p,
    1527             :                          struct lsa_OpenSecret *r)
    1528             : {
    1529             :         struct security_descriptor *psd;
    1530             :         NTSTATUS status;
    1531             :         uint32_t acc_granted;
    1532             : 
    1533           0 :         (void)find_policy_by_hnd(p,
    1534             :                                 r->in.handle,
    1535             :                                 LSA_HANDLE_POLICY_TYPE,
    1536             :                                 struct lsa_info,
    1537             :                                 &status);
    1538           0 :         if (!NT_STATUS_IS_OK(status)) {
    1539           0 :                 return NT_STATUS_INVALID_HANDLE;
    1540             :         }
    1541             : 
    1542           0 :         if (!r->in.name.string) {
    1543           0 :                 return NT_STATUS_INVALID_PARAMETER;
    1544             :         }
    1545             : 
    1546             :         /* Work out max allowed. */
    1547           0 :         map_max_allowed_access(p->session_info->security_token,
    1548           0 :                                p->session_info->unix_token,
    1549             :                                &r->in.access_mask);
    1550             : 
    1551             :         /* map the generic bits to the lsa policy ones */
    1552           0 :         se_map_generic(&r->in.access_mask, &lsa_secret_mapping);
    1553             : 
    1554           0 :         status = pdb_get_secret(p->mem_ctx, r->in.name.string,
    1555             :                                 NULL,
    1556             :                                 NULL,
    1557             :                                 NULL,
    1558             :                                 NULL,
    1559             :                                 &psd);
    1560           0 :         if (!NT_STATUS_IS_OK(status)) {
    1561           0 :                 return status;
    1562             :         }
    1563             : 
    1564           0 :         status = access_check_object(psd, p->session_info->security_token,
    1565             :                                      SEC_PRIV_INVALID, SEC_PRIV_INVALID, 0,
    1566             :                                      r->in.access_mask,
    1567             :                                      &acc_granted, "_lsa_OpenSecret");
    1568           0 :         if (!NT_STATUS_IS_OK(status)) {
    1569           0 :                 return status;
    1570             :         }
    1571             : 
    1572           0 :         status = create_lsa_policy_handle(p->mem_ctx, p,
    1573             :                                           LSA_HANDLE_SECRET_TYPE,
    1574             :                                           acc_granted,
    1575             :                                           NULL,
    1576             :                                           r->in.name.string,
    1577             :                                           psd,
    1578             :                                           r->out.sec_handle);
    1579           0 :         if (!NT_STATUS_IS_OK(status)) {
    1580           0 :                 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
    1581             :         }
    1582             : 
    1583           0 :         return NT_STATUS_OK;
    1584             : }
    1585             : 
    1586             : /***************************************************************************
    1587             :  _lsa_OpenTrustedDomain_base
    1588             :  ***************************************************************************/
    1589             : 
    1590           0 : static NTSTATUS _lsa_OpenTrustedDomain_base(struct pipes_struct *p,
    1591             :                                             uint32_t access_mask,
    1592             :                                             struct trustdom_info *info,
    1593             :                                             struct policy_handle *handle)
    1594             : {
    1595           0 :         struct security_descriptor *psd = NULL;
    1596             :         size_t sd_size;
    1597             :         uint32_t acc_granted;
    1598             :         NTSTATUS status;
    1599             : 
    1600             :         /* des_access is for the account here, not the policy
    1601             :          * handle - so don't check against policy handle. */
    1602             : 
    1603             :         /* Work out max allowed. */
    1604           0 :         map_max_allowed_access(p->session_info->security_token,
    1605           0 :                                p->session_info->unix_token,
    1606             :                                &access_mask);
    1607             : 
    1608             :         /* map the generic bits to the lsa account ones */
    1609           0 :         se_map_generic(&access_mask, &lsa_trusted_domain_mapping);
    1610             : 
    1611             :         /* get the generic lsa account SD until we store it */
    1612           0 :         status = make_lsa_object_sd(p->mem_ctx, &psd, &sd_size,
    1613             :                                     &lsa_trusted_domain_mapping,
    1614             :                                     NULL, 0);
    1615           0 :         if (!NT_STATUS_IS_OK(status)) {
    1616           0 :                 return status;
    1617             :         }
    1618             : 
    1619           0 :         status = access_check_object(psd, p->session_info->security_token,
    1620             :                                      SEC_PRIV_INVALID, SEC_PRIV_INVALID, 0,
    1621             :                                      access_mask, &acc_granted,
    1622             :                                      "_lsa_OpenTrustedDomain");
    1623           0 :         if (!NT_STATUS_IS_OK(status)) {
    1624           0 :                 return status;
    1625             :         }
    1626             : 
    1627           0 :         status = create_lsa_policy_handle(p->mem_ctx, p,
    1628             :                                           LSA_HANDLE_TRUST_TYPE,
    1629             :                                           acc_granted,
    1630             :                                           &info->sid,
    1631           0 :                                           info->name,
    1632             :                                           psd,
    1633             :                                           handle);
    1634           0 :         if (!NT_STATUS_IS_OK(status)) {
    1635           0 :                 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
    1636             :         }
    1637             : 
    1638           0 :         return NT_STATUS_OK;
    1639             : }
    1640             : 
    1641             : /***************************************************************************
    1642             :  _lsa_OpenTrustedDomain
    1643             :  ***************************************************************************/
    1644             : 
    1645           0 : NTSTATUS _lsa_OpenTrustedDomain(struct pipes_struct *p,
    1646             :                                 struct lsa_OpenTrustedDomain *r)
    1647             : {
    1648           0 :         struct trustdom_info *info = NULL;
    1649             :         NTSTATUS status;
    1650             : 
    1651           0 :         (void)find_policy_by_hnd(p,
    1652             :                                  r->in.handle,
    1653             :                                  LSA_HANDLE_POLICY_TYPE,
    1654             :                                  struct lsa_info,
    1655             :                                  &status);
    1656           0 :         if (!NT_STATUS_IS_OK(status)) {
    1657           0 :                 return NT_STATUS_INVALID_HANDLE;
    1658             :         }
    1659             : 
    1660           0 :         status = lsa_lookup_trusted_domain_by_sid(p->mem_ctx,
    1661           0 :                                                   r->in.sid,
    1662             :                                                   &info);
    1663           0 :         if (!NT_STATUS_IS_OK(status)) {
    1664           0 :                 return status;
    1665             :         }
    1666             : 
    1667           0 :         return _lsa_OpenTrustedDomain_base(p, r->in.access_mask, info,
    1668             :                                            r->out.trustdom_handle);
    1669             : }
    1670             : 
    1671             : /***************************************************************************
    1672             :  _lsa_OpenTrustedDomainByName
    1673             :  ***************************************************************************/
    1674             : 
    1675           0 : NTSTATUS _lsa_OpenTrustedDomainByName(struct pipes_struct *p,
    1676             :                                       struct lsa_OpenTrustedDomainByName *r)
    1677             : {
    1678           0 :         struct trustdom_info *info = NULL;
    1679             :         NTSTATUS status;
    1680             : 
    1681           0 :         (void)find_policy_by_hnd(p,
    1682             :                                  r->in.handle,
    1683             :                                  LSA_HANDLE_POLICY_TYPE,
    1684             :                                  struct lsa_info,
    1685             :                                  &status);
    1686           0 :         if (!NT_STATUS_IS_OK(status)) {
    1687           0 :                 return NT_STATUS_INVALID_HANDLE;
    1688             :         }
    1689             : 
    1690           0 :         status = lsa_lookup_trusted_domain_by_name(p->mem_ctx,
    1691             :                                                    r->in.name.string,
    1692             :                                                    &info);
    1693           0 :         if (!NT_STATUS_IS_OK(status)) {
    1694           0 :                 return status;
    1695             :         }
    1696             : 
    1697           0 :         return _lsa_OpenTrustedDomain_base(p, r->in.access_mask, info,
    1698             :                                            r->out.trustdom_handle);
    1699             : }
    1700             : 
    1701           0 : static NTSTATUS get_trustdom_auth_blob(struct pipes_struct *p,
    1702             :                                        TALLOC_CTX *mem_ctx, DATA_BLOB *auth_blob,
    1703             :                                        struct trustDomainPasswords *auth_struct)
    1704             : {
    1705             :         enum ndr_err_code ndr_err;
    1706             :         DATA_BLOB lsession_key;
    1707           0 :         gnutls_cipher_hd_t cipher_hnd = NULL;
    1708             :         gnutls_datum_t my_session_key;
    1709             :         NTSTATUS status;
    1710             :         int rc;
    1711             :         bool encrypted;
    1712             : 
    1713           0 :         encrypted =
    1714           0 :                 dcerpc_is_transport_encrypted(p->session_info);
    1715           0 :         if (lp_weak_crypto() == SAMBA_WEAK_CRYPTO_DISALLOWED &&
    1716           0 :             !encrypted) {
    1717           0 :                 return NT_STATUS_ACCESS_DENIED;
    1718             :         }
    1719             : 
    1720           0 :         status = session_extract_session_key(p->session_info, &lsession_key, KEY_USE_16BYTES);
    1721           0 :         if (!NT_STATUS_IS_OK(status)) {
    1722           0 :                 return NT_STATUS_INVALID_PARAMETER;
    1723             :         }
    1724             : 
    1725           0 :         my_session_key = (gnutls_datum_t) {
    1726           0 :                 .data = lsession_key.data,
    1727           0 :                 .size = lsession_key.length,
    1728             :         };
    1729             : 
    1730           0 :         GNUTLS_FIPS140_SET_LAX_MODE();
    1731           0 :         rc = gnutls_cipher_init(&cipher_hnd,
    1732             :                                 GNUTLS_CIPHER_ARCFOUR_128,
    1733             :                                 &my_session_key,
    1734             :                                 NULL);
    1735           0 :         if (rc < 0) {
    1736           0 :                 GNUTLS_FIPS140_SET_STRICT_MODE();
    1737           0 :                 status = gnutls_error_to_ntstatus(rc, NT_STATUS_CRYPTO_SYSTEM_INVALID);
    1738           0 :                 goto out;
    1739             :         }
    1740             : 
    1741           0 :         rc = gnutls_cipher_decrypt(cipher_hnd,
    1742           0 :                                    auth_blob->data,
    1743             :                                    auth_blob->length);
    1744           0 :         gnutls_cipher_deinit(cipher_hnd);
    1745           0 :         GNUTLS_FIPS140_SET_STRICT_MODE();
    1746           0 :         if (rc < 0) {
    1747           0 :                 status = gnutls_error_to_ntstatus(rc, NT_STATUS_CRYPTO_SYSTEM_INVALID);
    1748           0 :                 goto out;
    1749             :         }
    1750             : 
    1751           0 :         ndr_err = ndr_pull_struct_blob(auth_blob, mem_ctx,
    1752             :                                        auth_struct,
    1753             :                                        (ndr_pull_flags_fn_t)ndr_pull_trustDomainPasswords);
    1754           0 :         if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
    1755           0 :                 status = NT_STATUS_INVALID_PARAMETER;
    1756           0 :                 goto out;
    1757             :         }
    1758             : 
    1759           0 :         status = NT_STATUS_OK;
    1760           0 : out:
    1761           0 :         return status;
    1762             : }
    1763             : 
    1764           0 : static NTSTATUS get_trustauth_inout_blob(TALLOC_CTX *mem_ctx,
    1765             :                                          struct trustAuthInOutBlob *iopw,
    1766             :                                          DATA_BLOB *trustauth_blob)
    1767             : {
    1768             :         enum ndr_err_code ndr_err;
    1769             : 
    1770           0 :         if (iopw->current.count != iopw->count) {
    1771           0 :                 return NT_STATUS_INVALID_PARAMETER;
    1772             :         }
    1773             : 
    1774           0 :         if (iopw->previous.count > iopw->current.count) {
    1775           0 :                 return NT_STATUS_INVALID_PARAMETER;
    1776             :         }
    1777             : 
    1778           0 :         if (iopw->previous.count == 0) {
    1779             :                 /*
    1780             :                  * If the previous credentials are not present
    1781             :                  * we need to make a copy.
    1782             :                  */
    1783           0 :                 iopw->previous = iopw->current;
    1784             :         }
    1785             : 
    1786           0 :         if (iopw->previous.count < iopw->current.count) {
    1787           0 :                 struct AuthenticationInformationArray *c = &iopw->current;
    1788           0 :                 struct AuthenticationInformationArray *p = &iopw->previous;
    1789             : 
    1790             :                 /*
    1791             :                  * The previous array needs to have the same size
    1792             :                  * as the current one.
    1793             :                  *
    1794             :                  * We may have to fill with TRUST_AUTH_TYPE_NONE
    1795             :                  * elements.
    1796             :                  */
    1797           0 :                 p->array = talloc_realloc(mem_ctx, p->array,
    1798             :                                    struct AuthenticationInformation,
    1799             :                                    c->count);
    1800           0 :                 if (p->array == NULL) {
    1801           0 :                         return NT_STATUS_NO_MEMORY;
    1802             :                 }
    1803             : 
    1804           0 :                 while (p->count < c->count) {
    1805           0 :                         struct AuthenticationInformation *a =
    1806           0 :                                 &p->array[p->count++];
    1807             : 
    1808           0 :                         *a = (struct AuthenticationInformation) {
    1809           0 :                                 .LastUpdateTime = p->array[0].LastUpdateTime,
    1810             :                                 .AuthType = TRUST_AUTH_TYPE_NONE,
    1811             :                         };
    1812             :                 }
    1813             :         }
    1814             : 
    1815           0 :         ndr_err = ndr_push_struct_blob(trustauth_blob, mem_ctx,
    1816             :                                        iopw,
    1817             :                                        (ndr_push_flags_fn_t)ndr_push_trustAuthInOutBlob);
    1818           0 :         if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
    1819           0 :                 return NT_STATUS_INVALID_PARAMETER;
    1820             :         }
    1821             : 
    1822           0 :         return NT_STATUS_OK;
    1823             : }
    1824             : 
    1825             : /***************************************************************************
    1826             :  _lsa_CreateTrustedDomainEx2
    1827             :  ***************************************************************************/
    1828             : 
    1829           0 : NTSTATUS _lsa_CreateTrustedDomainEx2(struct pipes_struct *p,
    1830             :                                      struct lsa_CreateTrustedDomainEx2 *r)
    1831             : {
    1832             :         struct lsa_info *policy;
    1833             :         NTSTATUS status;
    1834             :         uint32_t acc_granted;
    1835             :         struct security_descriptor *psd;
    1836             :         size_t sd_size;
    1837             :         struct pdb_trusted_domain td;
    1838             :         struct trustDomainPasswords auth_struct;
    1839             :         DATA_BLOB auth_blob;
    1840             : 
    1841           0 :         if (!IS_DC) {
    1842           0 :                 return NT_STATUS_NOT_SUPPORTED;
    1843             :         }
    1844             : 
    1845           0 :         policy = find_policy_by_hnd(p,
    1846             :                                     r->in.policy_handle,
    1847             :                                     LSA_HANDLE_POLICY_TYPE,
    1848             :                                     struct lsa_info,
    1849             :                                     &status);
    1850           0 :         if (!NT_STATUS_IS_OK(status)) {
    1851           0 :                 return NT_STATUS_INVALID_HANDLE;
    1852             :         }
    1853             : 
    1854           0 :         if (!(policy->access & LSA_POLICY_TRUST_ADMIN)) {
    1855           0 :                 return NT_STATUS_ACCESS_DENIED;
    1856             :         }
    1857             : 
    1858           0 :         if (p->session_info->unix_token->uid != sec_initial_uid() &&
    1859           0 :             !nt_token_check_domain_rid(p->session_info->security_token, DOMAIN_RID_ADMINS)) {
    1860           0 :                 return NT_STATUS_ACCESS_DENIED;
    1861             :         }
    1862             : 
    1863             :         /* Work out max allowed. */
    1864           0 :         map_max_allowed_access(p->session_info->security_token,
    1865           0 :                                p->session_info->unix_token,
    1866             :                                &r->in.access_mask);
    1867             : 
    1868             :         /* map the generic bits to the lsa policy ones */
    1869           0 :         se_map_generic(&r->in.access_mask, &lsa_account_mapping);
    1870             : 
    1871           0 :         status = make_lsa_object_sd(p->mem_ctx, &psd, &sd_size,
    1872             :                                     &lsa_trusted_domain_mapping,
    1873             :                                     NULL, 0);
    1874           0 :         if (!NT_STATUS_IS_OK(status)) {
    1875           0 :                 return status;
    1876             :         }
    1877             : 
    1878           0 :         status = access_check_object(psd, p->session_info->security_token,
    1879             :                                      SEC_PRIV_INVALID, SEC_PRIV_INVALID, 0,
    1880             :                                      r->in.access_mask, &acc_granted,
    1881             :                                      "_lsa_CreateTrustedDomainEx2");
    1882           0 :         if (!NT_STATUS_IS_OK(status)) {
    1883           0 :                 return status;
    1884             :         }
    1885             : 
    1886           0 :         ZERO_STRUCT(td);
    1887             : 
    1888           0 :         td.domain_name = talloc_strdup(p->mem_ctx,
    1889           0 :                                        r->in.info->domain_name.string);
    1890           0 :         if (td.domain_name == NULL) {
    1891           0 :                 return NT_STATUS_NO_MEMORY;
    1892             :         }
    1893           0 :         td.netbios_name = talloc_strdup(p->mem_ctx,
    1894           0 :                                         r->in.info->netbios_name.string);
    1895           0 :         if (td.netbios_name == NULL) {
    1896           0 :                 return NT_STATUS_NO_MEMORY;
    1897             :         }
    1898           0 :         sid_copy(&td.security_identifier, r->in.info->sid);
    1899           0 :         td.trust_direction = r->in.info->trust_direction;
    1900           0 :         td.trust_type = r->in.info->trust_type;
    1901           0 :         td.trust_attributes = r->in.info->trust_attributes;
    1902             : 
    1903           0 :         if (r->in.auth_info_internal->auth_blob.size != 0) {
    1904           0 :                 auth_blob.length = r->in.auth_info_internal->auth_blob.size;
    1905           0 :                 auth_blob.data = r->in.auth_info_internal->auth_blob.data;
    1906             : 
    1907           0 :                 status = get_trustdom_auth_blob(p, p->mem_ctx, &auth_blob, &auth_struct);
    1908           0 :                 if (!NT_STATUS_IS_OK(status)) {
    1909           0 :                         return NT_STATUS_UNSUCCESSFUL;
    1910             :                 }
    1911             : 
    1912           0 :                 status = get_trustauth_inout_blob(p->mem_ctx, &auth_struct.incoming, &td.trust_auth_incoming);
    1913           0 :                 if (!NT_STATUS_IS_OK(status)) {
    1914           0 :                         return NT_STATUS_UNSUCCESSFUL;
    1915             :                 }
    1916             : 
    1917           0 :                 status = get_trustauth_inout_blob(p->mem_ctx, &auth_struct.outgoing, &td.trust_auth_outgoing);
    1918           0 :                 if (!NT_STATUS_IS_OK(status)) {
    1919           0 :                         return NT_STATUS_UNSUCCESSFUL;
    1920             :                 }
    1921             :         } else {
    1922           0 :                 td.trust_auth_incoming.data = NULL;
    1923           0 :                 td.trust_auth_incoming.length = 0;
    1924           0 :                 td.trust_auth_outgoing.data = NULL;
    1925           0 :                 td.trust_auth_outgoing.length = 0;
    1926             :         }
    1927             : 
    1928           0 :         status = pdb_set_trusted_domain(r->in.info->domain_name.string, &td);
    1929           0 :         if (!NT_STATUS_IS_OK(status)) {
    1930           0 :                 return status;
    1931             :         }
    1932             : 
    1933           0 :         status = create_lsa_policy_handle(p->mem_ctx, p,
    1934             :                                           LSA_HANDLE_TRUST_TYPE,
    1935             :                                           acc_granted,
    1936           0 :                                           r->in.info->sid,
    1937           0 :                                           r->in.info->netbios_name.string,
    1938             :                                           psd,
    1939             :                                           r->out.trustdom_handle);
    1940           0 :         if (!NT_STATUS_IS_OK(status)) {
    1941           0 :                 pdb_del_trusted_domain(r->in.info->netbios_name.string);
    1942           0 :                 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
    1943             :         }
    1944             : 
    1945           0 :         return NT_STATUS_OK;
    1946             : }
    1947             : 
    1948             : /***************************************************************************
    1949             :  _lsa_CreateTrustedDomainEx
    1950             :  ***************************************************************************/
    1951             : 
    1952           0 : NTSTATUS _lsa_CreateTrustedDomainEx(struct pipes_struct *p,
    1953             :                                     struct lsa_CreateTrustedDomainEx *r)
    1954             : {
    1955             :         struct lsa_CreateTrustedDomainEx2 q;
    1956             :         struct lsa_TrustDomainInfoAuthInfoInternal auth_info;
    1957             : 
    1958           0 :         ZERO_STRUCT(auth_info);
    1959             : 
    1960           0 :         q.in.policy_handle      = r->in.policy_handle;
    1961           0 :         q.in.info               = r->in.info;
    1962           0 :         q.in.auth_info_internal = &auth_info;
    1963           0 :         q.in.access_mask        = r->in.access_mask;
    1964           0 :         q.out.trustdom_handle   = r->out.trustdom_handle;
    1965             : 
    1966           0 :         return _lsa_CreateTrustedDomainEx2(p, &q);
    1967             : }
    1968             : 
    1969             : /***************************************************************************
    1970             :  _lsa_CreateTrustedDomain
    1971             :  ***************************************************************************/
    1972             : 
    1973           0 : NTSTATUS _lsa_CreateTrustedDomain(struct pipes_struct *p,
    1974             :                                   struct lsa_CreateTrustedDomain *r)
    1975             : {
    1976             :         struct lsa_CreateTrustedDomainEx2 c;
    1977             :         struct lsa_TrustDomainInfoInfoEx info;
    1978             :         struct lsa_TrustDomainInfoAuthInfoInternal auth_info;
    1979             : 
    1980           0 :         ZERO_STRUCT(auth_info);
    1981             : 
    1982           0 :         info.domain_name        = r->in.info->name;
    1983           0 :         info.netbios_name       = r->in.info->name;
    1984           0 :         info.sid                = r->in.info->sid;
    1985           0 :         info.trust_direction    = LSA_TRUST_DIRECTION_OUTBOUND;
    1986           0 :         info.trust_type         = LSA_TRUST_TYPE_DOWNLEVEL;
    1987           0 :         info.trust_attributes   = 0;
    1988             : 
    1989           0 :         c.in.policy_handle      = r->in.policy_handle;
    1990           0 :         c.in.info               = &info;
    1991           0 :         c.in.auth_info_internal = &auth_info;
    1992           0 :         c.in.access_mask        = r->in.access_mask;
    1993           0 :         c.out.trustdom_handle   = r->out.trustdom_handle;
    1994             : 
    1995           0 :         return _lsa_CreateTrustedDomainEx2(p, &c);
    1996             : }
    1997             : 
    1998             : /***************************************************************************
    1999             :  _lsa_DeleteTrustedDomain
    2000             :  ***************************************************************************/
    2001             : 
    2002           0 : NTSTATUS _lsa_DeleteTrustedDomain(struct pipes_struct *p,
    2003             :                                   struct lsa_DeleteTrustedDomain *r)
    2004             : {
    2005             :         NTSTATUS status;
    2006             :         struct lsa_info *handle;
    2007             :         struct pdb_trusted_domain *td;
    2008             : 
    2009             :         /* find the connection policy handle. */
    2010           0 :         handle = find_policy_by_hnd(p,
    2011             :                                     r->in.handle,
    2012             :                                     LSA_HANDLE_POLICY_TYPE,
    2013             :                                     struct lsa_info,
    2014             :                                     &status);
    2015           0 :         if (!NT_STATUS_IS_OK(status)) {
    2016           0 :                 return NT_STATUS_INVALID_HANDLE;
    2017             :         }
    2018             : 
    2019           0 :         if (!(handle->access & LSA_POLICY_TRUST_ADMIN)) {
    2020           0 :                 return NT_STATUS_ACCESS_DENIED;
    2021             :         }
    2022             : 
    2023           0 :         status = pdb_get_trusted_domain_by_sid(p->mem_ctx, r->in.dom_sid, &td);
    2024           0 :         if (!NT_STATUS_IS_OK(status)) {
    2025           0 :                 return status;
    2026             :         }
    2027             : 
    2028           0 :         if (td->netbios_name == NULL || *td->netbios_name == '\0') {
    2029             :                 struct dom_sid_buf buf;
    2030           0 :                 DEBUG(10, ("Missing netbios name for for trusted domain %s.\n",
    2031             :                            dom_sid_str_buf(r->in.dom_sid, &buf)));
    2032           0 :                 return NT_STATUS_UNSUCCESSFUL;
    2033             :         }
    2034             : 
    2035           0 :         status = pdb_del_trusted_domain(td->netbios_name);
    2036           0 :         if (!NT_STATUS_IS_OK(status)) {
    2037           0 :                 return status;
    2038             :         }
    2039             : 
    2040           0 :         return NT_STATUS_OK;
    2041             : }
    2042             : 
    2043             : /***************************************************************************
    2044             :  _lsa_CloseTrustedDomainEx
    2045             :  ***************************************************************************/
    2046             : 
    2047           0 : NTSTATUS _lsa_CloseTrustedDomainEx(struct pipes_struct *p,
    2048             :                                    struct lsa_CloseTrustedDomainEx *r)
    2049             : {
    2050           0 :         return NT_STATUS_NOT_IMPLEMENTED;
    2051             : }
    2052             : 
    2053             : /***************************************************************************
    2054             :  _lsa_QueryTrustedDomainInfo
    2055             :  ***************************************************************************/
    2056             : 
    2057           0 : static NTSTATUS pdb_trusted_domain_2_info_ex(TALLOC_CTX *mem_ctx,
    2058             :                                       struct pdb_trusted_domain *td,
    2059             :                                       struct lsa_TrustDomainInfoInfoEx *info_ex)
    2060             : {
    2061           0 :         if (td->domain_name == NULL ||
    2062           0 :             td->netbios_name == NULL ||
    2063           0 :             is_null_sid(&td->security_identifier)) {
    2064           0 :                 return NT_STATUS_INVALID_PARAMETER;
    2065             :         }
    2066             : 
    2067           0 :         info_ex->domain_name.string = talloc_strdup(mem_ctx, td->domain_name);
    2068           0 :         info_ex->netbios_name.string = talloc_strdup(mem_ctx, td->netbios_name);
    2069           0 :         info_ex->sid = dom_sid_dup(mem_ctx, &td->security_identifier);
    2070           0 :         if (info_ex->domain_name.string == NULL ||
    2071           0 :             info_ex->netbios_name.string == NULL ||
    2072           0 :             info_ex->sid == NULL) {
    2073           0 :                 return NT_STATUS_NO_MEMORY;
    2074             :         }
    2075             : 
    2076           0 :         info_ex->trust_direction = td->trust_direction;
    2077           0 :         info_ex->trust_type = td->trust_type;
    2078           0 :         info_ex->trust_attributes = td->trust_attributes;
    2079             : 
    2080           0 :         return NT_STATUS_OK;
    2081             : }
    2082             : 
    2083           0 : NTSTATUS _lsa_QueryTrustedDomainInfo(struct pipes_struct *p,
    2084             :                                      struct lsa_QueryTrustedDomainInfo *r)
    2085             : {
    2086             :         NTSTATUS status;
    2087             :         struct lsa_info *handle;
    2088             :         union lsa_TrustedDomainInfo *info;
    2089             :         struct pdb_trusted_domain *td;
    2090             :         uint32_t acc_required;
    2091             : 
    2092             :         /* find the connection policy handle. */
    2093           0 :         handle = find_policy_by_hnd(p,
    2094             :                                     r->in.trustdom_handle,
    2095             :                                     LSA_HANDLE_TRUST_TYPE,
    2096             :                                     struct lsa_info,
    2097             :                                     &status);
    2098           0 :         if (!NT_STATUS_IS_OK(status)) {
    2099           0 :                 return NT_STATUS_INVALID_HANDLE;
    2100             :         }
    2101             : 
    2102           0 :         switch (r->in.level) {
    2103           0 :         case LSA_TRUSTED_DOMAIN_INFO_NAME:
    2104           0 :                 acc_required = LSA_TRUSTED_QUERY_DOMAIN_NAME;
    2105           0 :                 break;
    2106           0 :         case LSA_TRUSTED_DOMAIN_INFO_CONTROLLERS:
    2107           0 :                 acc_required = LSA_TRUSTED_QUERY_CONTROLLERS;
    2108           0 :                 break;
    2109           0 :         case LSA_TRUSTED_DOMAIN_INFO_POSIX_OFFSET:
    2110           0 :                 acc_required = LSA_TRUSTED_QUERY_POSIX;
    2111           0 :                 break;
    2112           0 :         case LSA_TRUSTED_DOMAIN_INFO_PASSWORD:
    2113           0 :                 acc_required = LSA_TRUSTED_QUERY_AUTH;
    2114           0 :                 break;
    2115           0 :         case LSA_TRUSTED_DOMAIN_INFO_BASIC:
    2116           0 :                 acc_required = LSA_TRUSTED_QUERY_DOMAIN_NAME;
    2117           0 :                 break;
    2118           0 :         case LSA_TRUSTED_DOMAIN_INFO_INFO_EX:
    2119           0 :                 acc_required = LSA_TRUSTED_QUERY_DOMAIN_NAME;
    2120           0 :                 break;
    2121           0 :         case LSA_TRUSTED_DOMAIN_INFO_AUTH_INFO:
    2122           0 :                 acc_required = LSA_TRUSTED_QUERY_AUTH;
    2123           0 :                 break;
    2124           0 :         case LSA_TRUSTED_DOMAIN_INFO_FULL_INFO:
    2125           0 :                 acc_required = LSA_TRUSTED_QUERY_DOMAIN_NAME |
    2126             :                                LSA_TRUSTED_QUERY_POSIX |
    2127             :                                LSA_TRUSTED_QUERY_AUTH;
    2128           0 :                 break;
    2129           0 :         case LSA_TRUSTED_DOMAIN_INFO_AUTH_INFO_INTERNAL:
    2130           0 :                 acc_required = LSA_TRUSTED_QUERY_AUTH;
    2131           0 :                 break;
    2132           0 :         case LSA_TRUSTED_DOMAIN_INFO_FULL_INFO_INTERNAL:
    2133           0 :                 acc_required = LSA_TRUSTED_QUERY_DOMAIN_NAME |
    2134             :                                LSA_TRUSTED_QUERY_POSIX |
    2135             :                                LSA_TRUSTED_QUERY_AUTH;
    2136           0 :                 break;
    2137           0 :         case LSA_TRUSTED_DOMAIN_INFO_INFO_EX2_INTERNAL:
    2138           0 :                 acc_required = LSA_TRUSTED_QUERY_DOMAIN_NAME;
    2139           0 :                 break;
    2140           0 :         case LSA_TRUSTED_DOMAIN_INFO_FULL_INFO_2_INTERNAL:
    2141           0 :                 acc_required = LSA_TRUSTED_QUERY_DOMAIN_NAME |
    2142             :                                LSA_TRUSTED_QUERY_POSIX |
    2143             :                                LSA_TRUSTED_QUERY_AUTH;
    2144           0 :                 break;
    2145           0 :         case LSA_TRUSTED_DOMAIN_SUPPORTED_ENCRYPTION_TYPES:
    2146           0 :                 acc_required = LSA_TRUSTED_QUERY_POSIX;
    2147           0 :                 break;
    2148           0 :         default:
    2149           0 :                 return NT_STATUS_INVALID_PARAMETER;
    2150             :         }
    2151             : 
    2152           0 :         if (!(handle->access & acc_required)) {
    2153           0 :                 return NT_STATUS_ACCESS_DENIED;
    2154             :         }
    2155             : 
    2156           0 :         status = pdb_get_trusted_domain_by_sid(p->mem_ctx, &handle->sid, &td);
    2157           0 :         if (!NT_STATUS_IS_OK(status)) {
    2158           0 :                 return status;
    2159             :         }
    2160             : 
    2161           0 :         info = talloc_zero(p->mem_ctx, union lsa_TrustedDomainInfo);
    2162           0 :         if (!info) {
    2163           0 :                 return NT_STATUS_NO_MEMORY;
    2164             :         }
    2165             : 
    2166           0 :         switch (r->in.level) {
    2167           0 :         case LSA_TRUSTED_DOMAIN_INFO_NAME:
    2168           0 :                 init_lsa_StringLarge(&info->name.netbios_name, td->netbios_name);
    2169           0 :                 break;
    2170           0 :         case LSA_TRUSTED_DOMAIN_INFO_CONTROLLERS:
    2171           0 :                 return NT_STATUS_INVALID_PARAMETER;
    2172           0 :         case LSA_TRUSTED_DOMAIN_INFO_POSIX_OFFSET:
    2173           0 :                 info->posix_offset.posix_offset = *td->trust_posix_offset;
    2174           0 :                 break;
    2175           0 :         case LSA_TRUSTED_DOMAIN_INFO_PASSWORD:
    2176           0 :                 return NT_STATUS_INVALID_INFO_CLASS;
    2177           0 :         case LSA_TRUSTED_DOMAIN_INFO_BASIC:
    2178           0 :                 return NT_STATUS_INVALID_PARAMETER;
    2179           0 :         case LSA_TRUSTED_DOMAIN_INFO_INFO_EX:
    2180           0 :                 status = pdb_trusted_domain_2_info_ex(info, td, &info->info_ex);
    2181           0 :                 if (!NT_STATUS_IS_OK(status)) {
    2182           0 :                         return status;
    2183             :                 }
    2184           0 :                 break;
    2185           0 :         case LSA_TRUSTED_DOMAIN_INFO_AUTH_INFO:
    2186           0 :                 return NT_STATUS_INVALID_INFO_CLASS;
    2187           0 :         case LSA_TRUSTED_DOMAIN_INFO_FULL_INFO:
    2188           0 :                 status = pdb_trusted_domain_2_info_ex(info, td,
    2189             :                                                       &info->full_info.info_ex);
    2190           0 :                 if (!NT_STATUS_IS_OK(status)) {
    2191           0 :                         return status;
    2192             :                 }
    2193           0 :                 info->full_info.posix_offset.posix_offset = *td->trust_posix_offset;
    2194           0 :                 status = auth_blob_2_auth_info(p->mem_ctx,
    2195           0 :                                                     td->trust_auth_incoming,
    2196           0 :                                                     td->trust_auth_outgoing,
    2197             :                                                     &info->full_info.auth_info);
    2198           0 :                 if (!NT_STATUS_IS_OK(status)) {
    2199           0 :                         return status;
    2200             :                 }
    2201           0 :                 break;
    2202           0 :         case LSA_TRUSTED_DOMAIN_INFO_AUTH_INFO_INTERNAL:
    2203           0 :                 return NT_STATUS_INVALID_INFO_CLASS;
    2204           0 :         case LSA_TRUSTED_DOMAIN_INFO_FULL_INFO_INTERNAL:
    2205           0 :                 return NT_STATUS_INVALID_INFO_CLASS;
    2206           0 :         case LSA_TRUSTED_DOMAIN_INFO_INFO_EX2_INTERNAL:
    2207           0 :                 return NT_STATUS_INVALID_PARAMETER;
    2208           0 :         case LSA_TRUSTED_DOMAIN_INFO_FULL_INFO_2_INTERNAL:
    2209           0 :                 info->full_info2_internal.posix_offset.posix_offset = *td->trust_posix_offset;
    2210           0 :                 status = auth_blob_2_auth_info(p->mem_ctx,
    2211           0 :                                           td->trust_auth_incoming,
    2212           0 :                                           td->trust_auth_outgoing,
    2213             :                                           &info->full_info2_internal.auth_info);
    2214           0 :                 if (!NT_STATUS_IS_OK(status)) {
    2215           0 :                         return status;
    2216             :                 }
    2217           0 :                 break;
    2218           0 :         case LSA_TRUSTED_DOMAIN_SUPPORTED_ENCRYPTION_TYPES:
    2219           0 :                 info->enc_types.enc_types = *td->supported_enc_type;
    2220           0 :                 break;
    2221           0 :         default:
    2222           0 :                 return NT_STATUS_INVALID_PARAMETER;
    2223             :         }
    2224             : 
    2225           0 :         *r->out.info = info;
    2226             : 
    2227           0 :         return NT_STATUS_OK;
    2228             : }
    2229             : 
    2230             : /***************************************************************************
    2231             :  _lsa_QueryTrustedDomainInfoBySid
    2232             :  ***************************************************************************/
    2233             : 
    2234           0 : NTSTATUS _lsa_QueryTrustedDomainInfoBySid(struct pipes_struct *p,
    2235             :                                           struct lsa_QueryTrustedDomainInfoBySid *r)
    2236             : {
    2237             :         NTSTATUS status;
    2238             :         struct policy_handle trustdom_handle;
    2239             :         struct lsa_OpenTrustedDomain o;
    2240             :         struct lsa_QueryTrustedDomainInfo q;
    2241             :         struct lsa_Close c;
    2242             : 
    2243           0 :         o.in.handle             = r->in.handle;
    2244           0 :         o.in.sid                = r->in.dom_sid;
    2245           0 :         o.in.access_mask        = SEC_FLAG_MAXIMUM_ALLOWED;
    2246           0 :         o.out.trustdom_handle   = &trustdom_handle;
    2247             : 
    2248           0 :         status = _lsa_OpenTrustedDomain(p, &o);
    2249           0 :         if (!NT_STATUS_IS_OK(status)) {
    2250           0 :                 return status;
    2251             :         }
    2252             : 
    2253           0 :         q.in.trustdom_handle    = &trustdom_handle;
    2254           0 :         q.in.level              = r->in.level;
    2255           0 :         q.out.info              = r->out.info;
    2256             : 
    2257           0 :         status = _lsa_QueryTrustedDomainInfo(p, &q);
    2258           0 :         if (!NT_STATUS_IS_OK(status)) {
    2259           0 :                 return status;
    2260             :         }
    2261             : 
    2262           0 :         c.in.handle             = &trustdom_handle;
    2263           0 :         c.out.handle            = &trustdom_handle;
    2264             : 
    2265           0 :         return _lsa_Close(p, &c);
    2266             : }
    2267             : 
    2268             : /***************************************************************************
    2269             :  _lsa_QueryTrustedDomainInfoByName
    2270             :  ***************************************************************************/
    2271             : 
    2272           0 : NTSTATUS _lsa_QueryTrustedDomainInfoByName(struct pipes_struct *p,
    2273             :                                            struct lsa_QueryTrustedDomainInfoByName *r)
    2274             : {
    2275             :         NTSTATUS status;
    2276             :         struct policy_handle trustdom_handle;
    2277             :         struct lsa_OpenTrustedDomainByName o;
    2278             :         struct lsa_QueryTrustedDomainInfo q;
    2279             :         struct lsa_Close c;
    2280             : 
    2281           0 :         o.in.handle             = r->in.handle;
    2282           0 :         o.in.name.string        = r->in.trusted_domain->string;
    2283           0 :         o.in.access_mask        = SEC_FLAG_MAXIMUM_ALLOWED;
    2284           0 :         o.out.trustdom_handle   = &trustdom_handle;
    2285             : 
    2286           0 :         status = _lsa_OpenTrustedDomainByName(p, &o);
    2287           0 :         if (!NT_STATUS_IS_OK(status)) {
    2288           0 :                 if (NT_STATUS_EQUAL(status, NT_STATUS_NO_SUCH_DOMAIN)) {
    2289           0 :                         return NT_STATUS_OBJECT_NAME_NOT_FOUND;
    2290             :                 }
    2291           0 :                 return status;
    2292             :         }
    2293             : 
    2294           0 :         q.in.trustdom_handle    = &trustdom_handle;
    2295           0 :         q.in.level              = r->in.level;
    2296           0 :         q.out.info              = r->out.info;
    2297             : 
    2298           0 :         status = _lsa_QueryTrustedDomainInfo(p, &q);
    2299           0 :         if (!NT_STATUS_IS_OK(status)) {
    2300           0 :                 return status;
    2301             :         }
    2302             : 
    2303           0 :         c.in.handle             = &trustdom_handle;
    2304           0 :         c.out.handle            = &trustdom_handle;
    2305             : 
    2306           0 :         return _lsa_Close(p, &c);
    2307             : }
    2308             : 
    2309             : /***************************************************************************
    2310             :  _lsa_CreateSecret
    2311             :  ***************************************************************************/
    2312             : 
    2313          48 : NTSTATUS _lsa_CreateSecret(struct pipes_struct *p,
    2314             :                            struct lsa_CreateSecret *r)
    2315             : {
    2316             :         NTSTATUS status;
    2317             :         struct lsa_info *handle;
    2318             :         uint32_t acc_granted;
    2319             :         struct security_descriptor *psd;
    2320             :         size_t sd_size;
    2321             : 
    2322             :         /* find the connection policy handle. */
    2323          48 :         handle = find_policy_by_hnd(p,
    2324             :                                     r->in.handle,
    2325             :                                     LSA_HANDLE_POLICY_TYPE,
    2326             :                                     struct lsa_info,
    2327             :                                     &status);
    2328          48 :         if (!NT_STATUS_IS_OK(status)) {
    2329           0 :                 return NT_STATUS_INVALID_HANDLE;
    2330             :         }
    2331             : 
    2332             :         /* check if the user has enough rights */
    2333             : 
    2334          48 :         if (!(handle->access & LSA_POLICY_CREATE_SECRET)) {
    2335           0 :                 return NT_STATUS_ACCESS_DENIED;
    2336             :         }
    2337             : 
    2338             :         /* Work out max allowed. */
    2339          96 :         map_max_allowed_access(p->session_info->security_token,
    2340          48 :                                p->session_info->unix_token,
    2341             :                                &r->in.access_mask);
    2342             : 
    2343             :         /* map the generic bits to the lsa policy ones */
    2344          48 :         se_map_generic(&r->in.access_mask, &lsa_secret_mapping);
    2345             : 
    2346          48 :         status = make_lsa_object_sd(p->mem_ctx, &psd, &sd_size,
    2347             :                                     &lsa_secret_mapping,
    2348             :                                     NULL, 0);
    2349          48 :         if (!NT_STATUS_IS_OK(status)) {
    2350           0 :                 return status;
    2351             :         }
    2352             : 
    2353          48 :         status = access_check_object(psd, p->session_info->security_token,
    2354             :                                      SEC_PRIV_INVALID, SEC_PRIV_INVALID, 0,
    2355             :                                      r->in.access_mask,
    2356             :                                      &acc_granted, "_lsa_CreateSecret");
    2357          48 :         if (!NT_STATUS_IS_OK(status)) {
    2358           0 :                 return status;
    2359             :         }
    2360             : 
    2361          48 :         if (!r->in.name.string) {
    2362           0 :                 return NT_STATUS_INVALID_PARAMETER;
    2363             :         }
    2364             : 
    2365          48 :         if (strlen(r->in.name.string) > 128) {
    2366           0 :                 return NT_STATUS_NAME_TOO_LONG;
    2367             :         }
    2368             : 
    2369          48 :         status = pdb_get_secret(p->mem_ctx, r->in.name.string,
    2370             :                                 NULL, NULL, NULL, NULL, NULL);
    2371          48 :         if (NT_STATUS_IS_OK(status)) {
    2372           0 :                 return NT_STATUS_OBJECT_NAME_COLLISION;
    2373             :         }
    2374             : 
    2375          48 :         status = pdb_set_secret(r->in.name.string, NULL, NULL, psd);
    2376          48 :         if (!NT_STATUS_IS_OK(status)) {
    2377           0 :                 return status;
    2378             :         }
    2379             : 
    2380          48 :         status = create_lsa_policy_handle(p->mem_ctx, p,
    2381             :                                           LSA_HANDLE_SECRET_TYPE,
    2382             :                                           acc_granted,
    2383             :                                           NULL,
    2384             :                                           r->in.name.string,
    2385             :                                           psd,
    2386             :                                           r->out.sec_handle);
    2387          48 :         if (!NT_STATUS_IS_OK(status)) {
    2388           0 :                 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
    2389             :         }
    2390             : 
    2391          48 :         return NT_STATUS_OK;
    2392             : }
    2393             : 
    2394             : /***************************************************************************
    2395             :  _lsa_SetSecret
    2396             :  ***************************************************************************/
    2397             : 
    2398          64 : NTSTATUS _lsa_SetSecret(struct pipes_struct *p,
    2399             :                         struct lsa_SetSecret *r)
    2400             : {
    2401             :         NTSTATUS status;
    2402          64 :         struct lsa_info *info = NULL;
    2403             :         DATA_BLOB blob_new, blob_old;
    2404          64 :         DATA_BLOB cleartext_blob_new = data_blob_null;
    2405          64 :         DATA_BLOB cleartext_blob_old = data_blob_null;
    2406          64 :         DATA_BLOB *cleartext_blob_new_p = NULL;
    2407          64 :         DATA_BLOB *cleartext_blob_old_p = NULL;
    2408             :         DATA_BLOB session_key;
    2409             : 
    2410          64 :         info = find_policy_by_hnd(p,
    2411             :                                   r->in.sec_handle,
    2412             :                                   LSA_HANDLE_SECRET_TYPE,
    2413             :                                   struct lsa_info,
    2414             :                                   &status);
    2415          64 :         if (!NT_STATUS_IS_OK(status)) {
    2416           0 :                 return NT_STATUS_INVALID_HANDLE;
    2417             :         }
    2418             : 
    2419          64 :         if (!(info->access & LSA_SECRET_SET_VALUE)) {
    2420           0 :                 return NT_STATUS_ACCESS_DENIED;
    2421             :         }
    2422             : 
    2423          64 :         status = session_extract_session_key(p->session_info, &session_key, KEY_USE_16BYTES);
    2424          64 :         if(!NT_STATUS_IS_OK(status)) {
    2425           0 :                 return status;
    2426             :         }
    2427             : 
    2428          64 :         if (r->in.new_val) {
    2429          64 :                 blob_new = data_blob_const(r->in.new_val->data,
    2430          64 :                                            r->in.new_val->length);
    2431             : 
    2432          64 :                 status = sess_decrypt_blob(p->mem_ctx, &blob_new,
    2433             :                                            &session_key,
    2434             :                                            &cleartext_blob_new);
    2435          64 :                 if (!NT_STATUS_IS_OK(status)) {
    2436          32 :                         return status;
    2437             :                 }
    2438             : 
    2439          32 :                 cleartext_blob_new_p = &cleartext_blob_new;
    2440             :         }
    2441             : 
    2442          32 :         if (r->in.old_val) {
    2443           0 :                 blob_old = data_blob_const(r->in.old_val->data,
    2444           0 :                                            r->in.old_val->length);
    2445             : 
    2446           0 :                 status = sess_decrypt_blob(p->mem_ctx, &blob_old,
    2447             :                                            &session_key,
    2448             :                                            &cleartext_blob_old);
    2449           0 :                 if (!NT_STATUS_IS_OK(status)) {
    2450           0 :                         return status;
    2451             :                 }
    2452             : 
    2453           0 :                 cleartext_blob_old_p = &cleartext_blob_old;
    2454             :         }
    2455             : 
    2456          32 :         status = pdb_set_secret(info->name, cleartext_blob_new_p, cleartext_blob_old_p, NULL);
    2457          32 :         if (!NT_STATUS_IS_OK(status)) {
    2458           0 :                 return status;
    2459             :         }
    2460             : 
    2461             : #ifdef DEBUG_PASSWORD
    2462          32 :         DEBUG(10,("_lsa_SetSecret: successfully set new secret\n"));
    2463          32 :         dump_data(10, cleartext_blob_new.data, cleartext_blob_new.length);
    2464          32 :         DEBUG(10,("_lsa_SetSecret: successfully set old secret\n"));
    2465          32 :         dump_data(10, cleartext_blob_old.data, cleartext_blob_old.length);
    2466             : #endif
    2467             : 
    2468          32 :         return NT_STATUS_OK;
    2469             : }
    2470             : 
    2471             : /***************************************************************************
    2472             :  _lsa_QuerySecret
    2473             :  ***************************************************************************/
    2474             : 
    2475          32 : NTSTATUS _lsa_QuerySecret(struct pipes_struct *p,
    2476             :                           struct lsa_QuerySecret *r)
    2477             : {
    2478          32 :         struct lsa_info *info = NULL;
    2479             :         DATA_BLOB blob_new, blob_old;
    2480             :         DATA_BLOB blob_new_crypt, blob_old_crypt;
    2481             :         DATA_BLOB session_key;
    2482             :         NTTIME nttime_new, nttime_old;
    2483             :         NTSTATUS status;
    2484             : 
    2485          32 :         info = find_policy_by_hnd(p,
    2486             :                                   r->in.sec_handle,
    2487             :                                   LSA_HANDLE_SECRET_TYPE,
    2488             :                                   struct lsa_info,
    2489             :                                   &status);
    2490          32 :         if (!NT_STATUS_IS_OK(status)) {
    2491           0 :                 return NT_STATUS_INVALID_HANDLE;
    2492             :         }
    2493             : 
    2494          32 :         if (!(info->access & LSA_SECRET_QUERY_VALUE)) {
    2495           0 :                 return NT_STATUS_ACCESS_DENIED;
    2496             :         }
    2497             : 
    2498          32 :         status = pdb_get_secret(p->mem_ctx, info->name,
    2499             :                                 &blob_new, &nttime_new,
    2500             :                                 &blob_old, &nttime_old,
    2501             :                                 NULL);
    2502          32 :         if (!NT_STATUS_IS_OK(status)) {
    2503           0 :                 return status;
    2504             :         }
    2505             : 
    2506          32 :         status = session_extract_session_key(p->session_info, &session_key, KEY_USE_16BYTES);
    2507          32 :         if(!NT_STATUS_IS_OK(status)) {
    2508           0 :                 return status;
    2509             :         }
    2510             : 
    2511          32 :         if (r->in.new_val) {
    2512          32 :                 if (blob_new.length) {
    2513          32 :                         if (!r->out.new_val->buf) {
    2514          32 :                                 r->out.new_val->buf = talloc_zero(p->mem_ctx, struct lsa_DATA_BUF);
    2515             :                         }
    2516          32 :                         if (!r->out.new_val->buf) {
    2517           0 :                                 return NT_STATUS_NO_MEMORY;
    2518             :                         }
    2519             : 
    2520          32 :                         blob_new_crypt = sess_encrypt_blob(p->mem_ctx, &blob_new,
    2521             :                                                            &session_key);
    2522          32 :                         if (!blob_new_crypt.length) {
    2523           0 :                                 return NT_STATUS_NO_MEMORY;
    2524             :                         }
    2525             : 
    2526          32 :                         r->out.new_val->buf->data      = blob_new_crypt.data;
    2527          32 :                         r->out.new_val->buf->length    = blob_new_crypt.length;
    2528          32 :                         r->out.new_val->buf->size      = blob_new_crypt.length;
    2529             :                 }
    2530             :         }
    2531             : 
    2532          32 :         if (r->in.old_val) {
    2533           0 :                 if (blob_old.length) {
    2534           0 :                         if (!r->out.old_val->buf) {
    2535           0 :                                 r->out.old_val->buf = talloc_zero(p->mem_ctx, struct lsa_DATA_BUF);
    2536             :                         }
    2537           0 :                         if (!r->out.old_val->buf) {
    2538           0 :                                 return NT_STATUS_NO_MEMORY;
    2539             :                         }
    2540             : 
    2541           0 :                         blob_old_crypt = sess_encrypt_blob(p->mem_ctx, &blob_old,
    2542             :                                                            &session_key);
    2543           0 :                         if (!blob_old_crypt.length) {
    2544           0 :                                 return NT_STATUS_NO_MEMORY;
    2545             :                         }
    2546             : 
    2547           0 :                         r->out.old_val->buf->data      = blob_old_crypt.data;
    2548           0 :                         r->out.old_val->buf->length    = blob_old_crypt.length;
    2549           0 :                         r->out.old_val->buf->size      = blob_old_crypt.length;
    2550             :                 }
    2551             :         }
    2552             : 
    2553          32 :         if (r->out.new_mtime) {
    2554          32 :                 *r->out.new_mtime = nttime_new;
    2555             :         }
    2556             : 
    2557          32 :         if (r->out.old_mtime) {
    2558           0 :                 *r->out.old_mtime = nttime_old;
    2559             :         }
    2560             : 
    2561          32 :         return NT_STATUS_OK;
    2562             : }
    2563             : 
    2564             : /***************************************************************************
    2565             :  _lsa_DeleteObject
    2566             :  ***************************************************************************/
    2567             : 
    2568          51 : NTSTATUS _lsa_DeleteObject(struct pipes_struct *p,
    2569             :                            struct lsa_DeleteObject *r)
    2570             : {
    2571             :         NTSTATUS status;
    2572          51 :         struct lsa_info *info = NULL;
    2573             : 
    2574          51 :         info = find_policy_by_hnd(p,
    2575             :                                   r->in.handle,
    2576             :                                   DCESRV_HANDLE_ANY,
    2577             :                                   struct lsa_info,
    2578             :                                   &status);
    2579          51 :         if (!NT_STATUS_IS_OK(status)) {
    2580           0 :                 return NT_STATUS_INVALID_HANDLE;
    2581             :         }
    2582             : 
    2583          51 :         if (!(info->access & SEC_STD_DELETE)) {
    2584           0 :                 return NT_STATUS_ACCESS_DENIED;
    2585             :         }
    2586             : 
    2587          51 :         switch (info->type) {
    2588           3 :         case LSA_HANDLE_ACCOUNT_TYPE:
    2589           3 :                 status = privilege_delete_account(&info->sid);
    2590           3 :                 if (!NT_STATUS_IS_OK(status)) {
    2591           0 :                         DEBUG(10,("_lsa_DeleteObject: privilege_delete_account gave: %s\n",
    2592             :                                 nt_errstr(status)));
    2593           0 :                         return status;
    2594             :                 }
    2595           3 :                 break;
    2596           0 :         case LSA_HANDLE_TRUST_TYPE:
    2597           0 :                 if (!pdb_del_trusteddom_pw(info->name)) {
    2598           0 :                         return NT_STATUS_OBJECT_NAME_NOT_FOUND;
    2599             :                 }
    2600           0 :                 status = NT_STATUS_OK;
    2601           0 :                 break;
    2602          48 :         case LSA_HANDLE_SECRET_TYPE:
    2603          48 :                 status = pdb_delete_secret(info->name);
    2604          48 :                 if (NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
    2605           0 :                         return NT_STATUS_INVALID_HANDLE;
    2606             :                 }
    2607          48 :                 break;
    2608           0 :         default:
    2609           0 :                 return NT_STATUS_INVALID_HANDLE;
    2610             :         }
    2611             : 
    2612          51 :         close_policy_hnd(p, r->in.handle);
    2613          51 :         ZERO_STRUCTP(r->out.handle);
    2614             : 
    2615          51 :         return status;
    2616             : }
    2617             : 
    2618             : /***************************************************************************
    2619             :  _lsa_EnumPrivs
    2620             :  ***************************************************************************/
    2621             : 
    2622           2 : NTSTATUS _lsa_EnumPrivs(struct pipes_struct *p,
    2623             :                         struct lsa_EnumPrivs *r)
    2624             : {
    2625             :         struct lsa_info *handle;
    2626             :         uint32_t i;
    2627           2 :         uint32_t enum_context = *r->in.resume_handle;
    2628           2 :         int num_privs = num_privileges_in_short_list();
    2629           2 :         struct lsa_PrivEntry *entries = NULL;
    2630             :         NTSTATUS status;
    2631             : 
    2632             :         /* remember that the enum_context starts at 0 and not 1 */
    2633             : 
    2634           2 :         if ( enum_context >= num_privs )
    2635           0 :                 return NT_STATUS_NO_MORE_ENTRIES;
    2636             : 
    2637           2 :         DEBUG(10,("_lsa_EnumPrivs: enum_context:%d total entries:%d\n",
    2638             :                 enum_context, num_privs));
    2639             : 
    2640           2 :         handle = find_policy_by_hnd(p,
    2641             :                                     r->in.handle,
    2642             :                                     LSA_HANDLE_POLICY_TYPE,
    2643             :                                     struct lsa_info,
    2644             :                                     &status);
    2645           2 :         if (!NT_STATUS_IS_OK(status)) {
    2646           0 :                 return NT_STATUS_INVALID_HANDLE;
    2647             :         }
    2648             : 
    2649             :         /* check if the user has enough rights
    2650             :            I don't know if it's the right one. not documented.  */
    2651             : 
    2652           2 :         if (!(handle->access & LSA_POLICY_VIEW_LOCAL_INFORMATION))
    2653           0 :                 return NT_STATUS_ACCESS_DENIED;
    2654             : 
    2655           2 :         if (num_privs) {
    2656           2 :                 entries = talloc_zero_array(p->mem_ctx, struct lsa_PrivEntry, num_privs);
    2657           2 :                 if (!entries) {
    2658           0 :                         return NT_STATUS_NO_MEMORY;
    2659             :                 }
    2660             :         } else {
    2661           0 :                 entries = NULL;
    2662             :         }
    2663             : 
    2664          20 :         for (i = 0; i < num_privs; i++) {
    2665          18 :                 if( i < enum_context) {
    2666             : 
    2667           0 :                         init_lsa_StringLarge(&entries[i].name, NULL);
    2668             : 
    2669           0 :                         entries[i].luid.low = 0;
    2670           0 :                         entries[i].luid.high = 0;
    2671             :                 } else {
    2672             : 
    2673          18 :                         init_lsa_StringLarge(&entries[i].name, sec_privilege_name_from_index(i));
    2674             : 
    2675          18 :                         entries[i].luid.low = sec_privilege_from_index(i);
    2676          18 :                         entries[i].luid.high = 0;
    2677             :                 }
    2678             :         }
    2679             : 
    2680           2 :         enum_context = num_privs;
    2681             : 
    2682           2 :         *r->out.resume_handle = enum_context;
    2683           2 :         r->out.privs->count = num_privs;
    2684           2 :         r->out.privs->privs = entries;
    2685             : 
    2686           2 :         return NT_STATUS_OK;
    2687             : }
    2688             : 
    2689             : /***************************************************************************
    2690             :  _lsa_LookupPrivDisplayName
    2691             :  ***************************************************************************/
    2692             : 
    2693          18 : NTSTATUS _lsa_LookupPrivDisplayName(struct pipes_struct *p,
    2694             :                                     struct lsa_LookupPrivDisplayName *r)
    2695             : {
    2696             :         struct lsa_info *handle;
    2697             :         const char *description;
    2698             :         struct lsa_StringLarge *lsa_name;
    2699             :         NTSTATUS status;
    2700             : 
    2701          18 :         handle = find_policy_by_hnd(p,
    2702             :                                     r->in.handle,
    2703             :                                     LSA_HANDLE_POLICY_TYPE,
    2704             :                                     struct lsa_info,
    2705             :                                     &status);
    2706          18 :         if (!NT_STATUS_IS_OK(status)) {
    2707           0 :                 return NT_STATUS_INVALID_HANDLE;
    2708             :         }
    2709             : 
    2710             :         /* check if the user has enough rights */
    2711             : 
    2712             :         /*
    2713             :          * I don't know if it's the right one. not documented.
    2714             :          */
    2715          18 :         if (!(handle->access & LSA_POLICY_VIEW_LOCAL_INFORMATION))
    2716           0 :                 return NT_STATUS_ACCESS_DENIED;
    2717             : 
    2718          18 :         DEBUG(10,("_lsa_LookupPrivDisplayName: name = %s\n", r->in.name->string));
    2719             : 
    2720          18 :         description = get_privilege_dispname(r->in.name->string);
    2721          18 :         if (!description) {
    2722           0 :                 DEBUG(10,("_lsa_LookupPrivDisplayName: doesn't exist\n"));
    2723           0 :                 return NT_STATUS_NO_SUCH_PRIVILEGE;
    2724             :         }
    2725             : 
    2726          18 :         DEBUG(10,("_lsa_LookupPrivDisplayName: display name = %s\n", description));
    2727             : 
    2728          18 :         lsa_name = talloc_zero(p->mem_ctx, struct lsa_StringLarge);
    2729          18 :         if (!lsa_name) {
    2730           0 :                 return NT_STATUS_NO_MEMORY;
    2731             :         }
    2732             : 
    2733          18 :         init_lsa_StringLarge(lsa_name, description);
    2734             : 
    2735          18 :         *r->out.returned_language_id = r->in.language_id;
    2736          18 :         *r->out.disp_name = lsa_name;
    2737             : 
    2738          18 :         return NT_STATUS_OK;
    2739             : }
    2740             : 
    2741             : /***************************************************************************
    2742             :  _lsa_EnumAccounts
    2743             :  ***************************************************************************/
    2744             : 
    2745           7 : NTSTATUS _lsa_EnumAccounts(struct pipes_struct *p,
    2746             :                            struct lsa_EnumAccounts *r)
    2747             : {
    2748             :         struct lsa_info *handle;
    2749             :         struct dom_sid *sid_list;
    2750             :         int i, j, num_entries;
    2751             :         NTSTATUS status;
    2752           7 :         struct lsa_SidPtr *sids = NULL;
    2753             : 
    2754           7 :         handle = find_policy_by_hnd(p,
    2755             :                                     r->in.handle,
    2756             :                                     LSA_HANDLE_POLICY_TYPE,
    2757             :                                     struct lsa_info,
    2758             :                                     &status);
    2759           7 :         if (!NT_STATUS_IS_OK(status)) {
    2760           0 :                 return NT_STATUS_INVALID_HANDLE;
    2761             :         }
    2762             : 
    2763           7 :         if (!(handle->access & LSA_POLICY_VIEW_LOCAL_INFORMATION))
    2764           0 :                 return NT_STATUS_ACCESS_DENIED;
    2765             : 
    2766           7 :         sid_list = NULL;
    2767           7 :         num_entries = 0;
    2768             : 
    2769             :         /* The only way we can currently find out all the SIDs that have been
    2770             :            privileged is to scan all privileges */
    2771             : 
    2772           7 :         status = privilege_enumerate_accounts(&sid_list, &num_entries);
    2773           7 :         if (!NT_STATUS_IS_OK(status)) {
    2774           0 :                 return status;
    2775             :         }
    2776             : 
    2777           7 :         if (*r->in.resume_handle >= num_entries) {
    2778           2 :                 return NT_STATUS_NO_MORE_ENTRIES;
    2779             :         }
    2780             : 
    2781           5 :         if (num_entries - *r->in.resume_handle) {
    2782           5 :                 sids = talloc_zero_array(p->mem_ctx, struct lsa_SidPtr,
    2783             :                                          num_entries - *r->in.resume_handle);
    2784           5 :                 if (!sids) {
    2785           0 :                         talloc_free(sid_list);
    2786           0 :                         return NT_STATUS_NO_MEMORY;
    2787             :                 }
    2788             : 
    2789          37 :                 for (i = *r->in.resume_handle, j = 0; i < num_entries; i++, j++) {
    2790          32 :                         sids[j].sid = dom_sid_dup(p->mem_ctx, &sid_list[i]);
    2791          32 :                         if (!sids[j].sid) {
    2792           0 :                                 talloc_free(sid_list);
    2793           0 :                                 return NT_STATUS_NO_MEMORY;
    2794             :                         }
    2795             :                 }
    2796             :         }
    2797             : 
    2798           5 :         talloc_free(sid_list);
    2799             : 
    2800           5 :         *r->out.resume_handle = num_entries;
    2801           5 :         r->out.sids->num_sids = num_entries;
    2802           5 :         r->out.sids->sids = sids;
    2803             : 
    2804           5 :         return NT_STATUS_OK;
    2805             : }
    2806             : 
    2807             : /***************************************************************************
    2808             :  _lsa_GetUserName
    2809             :  ***************************************************************************/
    2810             : 
    2811          86 : NTSTATUS _lsa_GetUserName(struct pipes_struct *p,
    2812             :                           struct lsa_GetUserName *r)
    2813             : {
    2814             :         const char *username, *domname;
    2815          86 :         struct lsa_String *account_name = NULL;
    2816          86 :         struct lsa_String *authority_name = NULL;
    2817             : 
    2818          86 :         if (p->transport != NCACN_NP && p->transport != NCALRPC) {
    2819           0 :                 p->fault_state = DCERPC_FAULT_ACCESS_DENIED;
    2820           0 :                 return NT_STATUS_ACCESS_DENIED;
    2821             :         }
    2822             : 
    2823         164 :         if (r->in.account_name &&
    2824          86 :            *r->in.account_name) {
    2825           0 :                 return NT_STATUS_INVALID_PARAMETER;
    2826             :         }
    2827             : 
    2828         162 :         if (r->in.authority_name &&
    2829          84 :            *r->in.authority_name) {
    2830           0 :                 return NT_STATUS_INVALID_PARAMETER;
    2831             :         }
    2832             : 
    2833          86 :         if (security_session_user_level(p->session_info, NULL) < SECURITY_USER) {
    2834             :                 /*
    2835             :                  * I'm 99% sure this is not the right place to do this,
    2836             :                  * global_sid_Anonymous should probably be put into the token
    2837             :                  * instead of the guest id -- vl
    2838             :                  */
    2839          11 :                 if (!lookup_sid(p->mem_ctx, &global_sid_Anonymous,
    2840             :                                 &domname, &username, NULL)) {
    2841           0 :                         return NT_STATUS_NO_MEMORY;
    2842             :                 }
    2843             :         } else {
    2844          75 :                 username = p->session_info->unix_info->sanitized_username;
    2845          75 :                 domname = p->session_info->info->domain_name;
    2846             :         }
    2847             : 
    2848          86 :         account_name = talloc(p->mem_ctx, struct lsa_String);
    2849          86 :         if (!account_name) {
    2850           0 :                 return NT_STATUS_NO_MEMORY;
    2851             :         }
    2852          86 :         init_lsa_String(account_name, username);
    2853             : 
    2854          86 :         if (r->out.authority_name) {
    2855          84 :                 authority_name = talloc(p->mem_ctx, struct lsa_String);
    2856          84 :                 if (!authority_name) {
    2857           0 :                         return NT_STATUS_NO_MEMORY;
    2858             :                 }
    2859          84 :                 init_lsa_String(authority_name, domname);
    2860             :         }
    2861             : 
    2862          86 :         *r->out.account_name = account_name;
    2863          86 :         if (r->out.authority_name) {
    2864          84 :                 *r->out.authority_name = authority_name;
    2865             :         }
    2866             : 
    2867          86 :         return NT_STATUS_OK;
    2868             : }
    2869             : 
    2870             : /***************************************************************************
    2871             :  _lsa_CreateAccount
    2872             :  ***************************************************************************/
    2873             : 
    2874           2 : NTSTATUS _lsa_CreateAccount(struct pipes_struct *p,
    2875             :                             struct lsa_CreateAccount *r)
    2876             : {
    2877             :         NTSTATUS status;
    2878             :         struct lsa_info *handle;
    2879             :         uint32_t acc_granted;
    2880             :         struct security_descriptor *psd;
    2881             :         size_t sd_size;
    2882           2 :         uint32_t owner_access = (LSA_ACCOUNT_ALL_ACCESS &
    2883             :                         ~(LSA_ACCOUNT_ADJUST_PRIVILEGES|
    2884             :                         LSA_ACCOUNT_ADJUST_SYSTEM_ACCESS|
    2885             :                         SEC_STD_DELETE));
    2886             : 
    2887             :         /* find the connection policy handle. */
    2888           2 :         handle = find_policy_by_hnd(p,
    2889             :                                     r->in.handle,
    2890             :                                     LSA_HANDLE_POLICY_TYPE,
    2891             :                                     struct lsa_info,
    2892             :                                     &status);
    2893           2 :         if (!NT_STATUS_IS_OK(status)) {
    2894           0 :                 return NT_STATUS_INVALID_HANDLE;
    2895             :         }
    2896             : 
    2897             :         /* check if the user has enough rights */
    2898             : 
    2899           2 :         if (!(handle->access & LSA_POLICY_CREATE_ACCOUNT)) {
    2900           0 :                 return NT_STATUS_ACCESS_DENIED;
    2901             :         }
    2902             : 
    2903             :         /* Work out max allowed. */
    2904           4 :         map_max_allowed_access(p->session_info->security_token,
    2905           2 :                                p->session_info->unix_token,
    2906             :                                &r->in.access_mask);
    2907             : 
    2908             :         /* map the generic bits to the lsa policy ones */
    2909           2 :         se_map_generic(&r->in.access_mask, &lsa_account_mapping);
    2910             : 
    2911           2 :         status = make_lsa_object_sd(p->mem_ctx, &psd, &sd_size,
    2912             :                                     &lsa_account_mapping,
    2913             :                                     r->in.sid, owner_access);
    2914           2 :         if (!NT_STATUS_IS_OK(status)) {
    2915           0 :                 return status;
    2916             :         }
    2917             : 
    2918           2 :         status = access_check_object(psd, p->session_info->security_token,
    2919             :                                      SEC_PRIV_INVALID, SEC_PRIV_INVALID, 0, r->in.access_mask,
    2920             :                                      &acc_granted, "_lsa_CreateAccount");
    2921           2 :         if (!NT_STATUS_IS_OK(status)) {
    2922           0 :                 return status;
    2923             :         }
    2924             : 
    2925           2 :         if ( is_privileged_sid( r->in.sid ) )
    2926           0 :                 return NT_STATUS_OBJECT_NAME_COLLISION;
    2927             : 
    2928           2 :         status = create_lsa_policy_handle(p->mem_ctx, p,
    2929             :                                           LSA_HANDLE_ACCOUNT_TYPE,
    2930             :                                           acc_granted,
    2931             :                                           r->in.sid,
    2932             :                                           NULL,
    2933             :                                           psd,
    2934             :                                           r->out.acct_handle);
    2935           2 :         if (!NT_STATUS_IS_OK(status)) {
    2936           0 :                 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
    2937             :         }
    2938             : 
    2939           2 :         return privilege_create_account(r->in.sid);
    2940             : }
    2941             : 
    2942             : /***************************************************************************
    2943             :  _lsa_OpenAccount
    2944             :  ***************************************************************************/
    2945             : 
    2946          14 : NTSTATUS _lsa_OpenAccount(struct pipes_struct *p,
    2947             :                           struct lsa_OpenAccount *r)
    2948             : {
    2949          14 :         struct security_descriptor *psd = NULL;
    2950             :         size_t sd_size;
    2951          14 :         uint32_t des_access = r->in.access_mask;
    2952             :         uint32_t acc_granted;
    2953          14 :         uint32_t owner_access = (LSA_ACCOUNT_ALL_ACCESS &
    2954             :                         ~(LSA_ACCOUNT_ADJUST_PRIVILEGES|
    2955             :                         LSA_ACCOUNT_ADJUST_SYSTEM_ACCESS|
    2956             :                         SEC_STD_DELETE));
    2957             :         NTSTATUS status;
    2958             : 
    2959             :         /* find the connection policy handle. */
    2960          14 :         (void)find_policy_by_hnd(p,
    2961             :                                  r->in.handle,
    2962             :                                  LSA_HANDLE_POLICY_TYPE,
    2963             :                                  struct lsa_info,
    2964             :                                  &status);
    2965          14 :         if (!NT_STATUS_IS_OK(status)) {
    2966           0 :                 return NT_STATUS_INVALID_HANDLE;
    2967             :         }
    2968             : 
    2969             :         /* des_access is for the account here, not the policy
    2970             :          * handle - so don't check against policy handle. */
    2971             : 
    2972             :         /* Work out max allowed. */
    2973          14 :         map_max_allowed_access(p->session_info->security_token,
    2974          14 :                                p->session_info->unix_token,
    2975             :                                &des_access);
    2976             : 
    2977             :         /* map the generic bits to the lsa account ones */
    2978          14 :         se_map_generic(&des_access, &lsa_account_mapping);
    2979             : 
    2980             :         /* get the generic lsa account SD until we store it */
    2981          14 :         status = make_lsa_object_sd(p->mem_ctx, &psd, &sd_size,
    2982             :                                 &lsa_account_mapping,
    2983             :                                 r->in.sid, owner_access);
    2984          14 :         if (!NT_STATUS_IS_OK(status)) {
    2985           0 :                 return status;
    2986             :         }
    2987             : 
    2988          14 :         status = access_check_object(psd, p->session_info->security_token,
    2989             :                                      SEC_PRIV_INVALID, SEC_PRIV_INVALID, 0, des_access,
    2990             :                                      &acc_granted, "_lsa_OpenAccount" );
    2991          14 :         if (!NT_STATUS_IS_OK(status)) {
    2992           0 :                 return status;
    2993             :         }
    2994             : 
    2995             :         /* TODO: Fis the parsing routine before reenabling this check! */
    2996             :         #if 0
    2997             :         if (!lookup_sid(&handle->sid, dom_name, name, &type))
    2998             :                 return NT_STATUS_ACCESS_DENIED;
    2999             :         #endif
    3000             : 
    3001          14 :         status = create_lsa_policy_handle(p->mem_ctx, p,
    3002             :                                           LSA_HANDLE_ACCOUNT_TYPE,
    3003             :                                           acc_granted,
    3004             :                                           r->in.sid,
    3005             :                                           NULL,
    3006             :                                           psd,
    3007             :                                           r->out.acct_handle);
    3008          14 :         if (!NT_STATUS_IS_OK(status)) {
    3009           0 :                 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
    3010             :         }
    3011             : 
    3012          14 :         return NT_STATUS_OK;
    3013             : }
    3014             : 
    3015             : /***************************************************************************
    3016             :  _lsa_EnumPrivsAccount
    3017             :  For a given SID, enumerate all the privilege this account has.
    3018             :  ***************************************************************************/
    3019             : 
    3020          26 : NTSTATUS _lsa_EnumPrivsAccount(struct pipes_struct *p,
    3021             :                                struct lsa_EnumPrivsAccount *r)
    3022             : {
    3023          26 :         NTSTATUS status = NT_STATUS_OK;
    3024          26 :         struct lsa_info *info=NULL;
    3025             :         PRIVILEGE_SET *privileges;
    3026          26 :         struct lsa_PrivilegeSet *priv_set = NULL;
    3027             :         struct dom_sid_buf buf;
    3028             : 
    3029             :         /* find the connection policy handle. */
    3030          26 :         info = find_policy_by_hnd(p,
    3031             :                                   r->in.handle,
    3032             :                                   LSA_HANDLE_ACCOUNT_TYPE,
    3033             :                                   struct lsa_info,
    3034             :                                   &status);
    3035          26 :         if (!NT_STATUS_IS_OK(status)) {
    3036           0 :                 return NT_STATUS_INVALID_HANDLE;
    3037             :         }
    3038             : 
    3039          26 :         if (!(info->access & LSA_ACCOUNT_VIEW))
    3040           0 :                 return NT_STATUS_ACCESS_DENIED;
    3041             : 
    3042          26 :         status = get_privileges_for_sid_as_set(p->mem_ctx, &privileges, &info->sid);
    3043          26 :         if (!NT_STATUS_IS_OK(status)) {
    3044           0 :                 return status;
    3045             :         }
    3046             : 
    3047          26 :         *r->out.privs = priv_set = talloc_zero(p->mem_ctx, struct lsa_PrivilegeSet);
    3048          26 :         if (!priv_set) {
    3049           0 :                 return NT_STATUS_NO_MEMORY;
    3050             :         }
    3051             : 
    3052          26 :         DEBUG(10,("_lsa_EnumPrivsAccount: %s has %d privileges\n",
    3053             :                   dom_sid_str_buf(&info->sid, &buf),
    3054             :                   privileges->count));
    3055             : 
    3056          26 :         priv_set->count = privileges->count;
    3057          26 :         priv_set->unknown = 0;
    3058          26 :         priv_set->set = talloc_move(priv_set, &privileges->set);
    3059             : 
    3060          26 :         return status;
    3061             : }
    3062             : 
    3063             : /***************************************************************************
    3064             :  _lsa_GetSystemAccessAccount
    3065             :  ***************************************************************************/
    3066             : 
    3067          14 : NTSTATUS _lsa_GetSystemAccessAccount(struct pipes_struct *p,
    3068             :                                      struct lsa_GetSystemAccessAccount *r)
    3069             : {
    3070             :         NTSTATUS status;
    3071          14 :         struct lsa_info *info = NULL;
    3072             :         struct lsa_EnumPrivsAccount e;
    3073             :         struct lsa_PrivilegeSet *privset;
    3074             : 
    3075             :         /* find the connection policy handle. */
    3076             : 
    3077          14 :         info = find_policy_by_hnd(p,
    3078             :                                   r->in.handle,
    3079             :                                   LSA_HANDLE_ACCOUNT_TYPE,
    3080             :                                   struct lsa_info,
    3081             :                                   &status);
    3082          14 :         if (!NT_STATUS_IS_OK(status)) {
    3083           0 :                 return NT_STATUS_INVALID_HANDLE;
    3084             :         }
    3085             : 
    3086          14 :         if (!(info->access & LSA_ACCOUNT_VIEW))
    3087           0 :                 return NT_STATUS_ACCESS_DENIED;
    3088             : 
    3089          14 :         privset = talloc_zero(p->mem_ctx, struct lsa_PrivilegeSet);
    3090          14 :         if (!privset) {
    3091           0 :                 return NT_STATUS_NO_MEMORY;
    3092             :         }
    3093             : 
    3094          14 :         e.in.handle = r->in.handle;
    3095          14 :         e.out.privs = &privset;
    3096             : 
    3097          14 :         status = _lsa_EnumPrivsAccount(p, &e);
    3098          14 :         if (!NT_STATUS_IS_OK(status)) {
    3099           0 :                 DEBUG(10,("_lsa_GetSystemAccessAccount: "
    3100             :                         "failed to call _lsa_EnumPrivsAccount(): %s\n",
    3101             :                         nt_errstr(status)));
    3102           0 :                 return status;
    3103             :         }
    3104             : 
    3105             :         /* Samba4 would iterate over the privset to merge the policy mode bits,
    3106             :          * not sure samba3 can do the same here, so just return what we did in
    3107             :          * the past - gd */
    3108             : 
    3109             :         /*
    3110             :           0x01 -> Log on locally
    3111             :           0x02 -> Access this computer from network
    3112             :           0x04 -> Log on as a batch job
    3113             :           0x10 -> Log on as a service
    3114             : 
    3115             :           they can be ORed together
    3116             :         */
    3117             : 
    3118          14 :         *r->out.access_mask = LSA_POLICY_MODE_INTERACTIVE |
    3119             :                               LSA_POLICY_MODE_NETWORK;
    3120             : 
    3121          14 :         return NT_STATUS_OK;
    3122             : }
    3123             : 
    3124             : /***************************************************************************
    3125             :   update the systemaccount information
    3126             :  ***************************************************************************/
    3127             : 
    3128           0 : NTSTATUS _lsa_SetSystemAccessAccount(struct pipes_struct *p,
    3129             :                                      struct lsa_SetSystemAccessAccount *r)
    3130             : {
    3131           0 :         struct lsa_info *info=NULL;
    3132             :         NTSTATUS status;
    3133             :         GROUP_MAP *map;
    3134             : 
    3135             :         /* find the connection policy handle. */
    3136           0 :         info = find_policy_by_hnd(p,
    3137             :                                   r->in.handle,
    3138             :                                   LSA_HANDLE_ACCOUNT_TYPE,
    3139             :                                   struct lsa_info,
    3140             :                                   &status);
    3141           0 :         if (!NT_STATUS_IS_OK(status)) {
    3142           0 :                 return NT_STATUS_INVALID_HANDLE;
    3143             :         }
    3144             : 
    3145           0 :         if (!(info->access & LSA_ACCOUNT_ADJUST_SYSTEM_ACCESS)) {
    3146           0 :                 return NT_STATUS_ACCESS_DENIED;
    3147             :         }
    3148             : 
    3149           0 :         map = talloc_zero(p->mem_ctx, GROUP_MAP);
    3150           0 :         if (!map) {
    3151           0 :                 return NT_STATUS_NO_MEMORY;
    3152             :         }
    3153             : 
    3154           0 :         if (!pdb_getgrsid(map, info->sid)) {
    3155           0 :                 TALLOC_FREE(map);
    3156           0 :                 return NT_STATUS_NO_SUCH_GROUP;
    3157             :         }
    3158             : 
    3159           0 :         status = pdb_update_group_mapping_entry(map);
    3160           0 :         TALLOC_FREE(map);
    3161           0 :         return status;
    3162             : }
    3163             : 
    3164             : /***************************************************************************
    3165             :  _lsa_AddPrivilegesToAccount
    3166             :  For a given SID, add some privileges.
    3167             :  ***************************************************************************/
    3168             : 
    3169           2 : NTSTATUS _lsa_AddPrivilegesToAccount(struct pipes_struct *p,
    3170             :                                      struct lsa_AddPrivilegesToAccount *r)
    3171             : {
    3172           2 :         struct lsa_info *info = NULL;
    3173           2 :         struct lsa_PrivilegeSet *set = NULL;
    3174             :         NTSTATUS status;
    3175             : 
    3176             :         /* find the connection policy handle. */
    3177           2 :         info = find_policy_by_hnd(p,
    3178             :                                   r->in.handle,
    3179             :                                   LSA_HANDLE_ACCOUNT_TYPE,
    3180             :                                   struct lsa_info,
    3181             :                                   &status);
    3182           2 :         if (!NT_STATUS_IS_OK(status)) {
    3183           0 :                 return NT_STATUS_INVALID_HANDLE;
    3184             :         }
    3185             : 
    3186           2 :         if (!(info->access & LSA_ACCOUNT_ADJUST_PRIVILEGES)) {
    3187           0 :                 return NT_STATUS_ACCESS_DENIED;
    3188             :         }
    3189             : 
    3190           2 :         set = r->in.privs;
    3191             : 
    3192           2 :         if ( !grant_privilege_set( &info->sid, set ) ) {
    3193             :                 struct dom_sid_buf buf;
    3194           0 :                 DEBUG(3,("_lsa_AddPrivilegesToAccount: grant_privilege_set(%s) failed!\n",
    3195             :                          dom_sid_str_buf(&info->sid, &buf)));
    3196           0 :                 return NT_STATUS_NO_SUCH_PRIVILEGE;
    3197             :         }
    3198             : 
    3199           2 :         return NT_STATUS_OK;
    3200             : }
    3201             : 
    3202             : /***************************************************************************
    3203             :  _lsa_RemovePrivilegesFromAccount
    3204             :  For a given SID, remove some privileges.
    3205             :  ***************************************************************************/
    3206             : 
    3207           2 : NTSTATUS _lsa_RemovePrivilegesFromAccount(struct pipes_struct *p,
    3208             :                                           struct lsa_RemovePrivilegesFromAccount *r)
    3209             : {
    3210           2 :         struct lsa_info *info = NULL;
    3211           2 :         struct lsa_PrivilegeSet *set = NULL;
    3212             :         NTSTATUS status;
    3213             : 
    3214             :         /* find the connection policy handle. */
    3215           2 :         info = find_policy_by_hnd(p,
    3216             :                                   r->in.handle,
    3217             :                                   LSA_HANDLE_ACCOUNT_TYPE,
    3218             :                                   struct lsa_info,
    3219             :                                   &status);
    3220           2 :         if (!NT_STATUS_IS_OK(status)) {
    3221           0 :                 return NT_STATUS_INVALID_HANDLE;
    3222             :         }
    3223             : 
    3224           2 :         if (!(info->access & LSA_ACCOUNT_ADJUST_PRIVILEGES)) {
    3225           0 :                 return NT_STATUS_ACCESS_DENIED;
    3226             :         }
    3227             : 
    3228           2 :         set = r->in.privs;
    3229             : 
    3230           2 :         if ( !revoke_privilege_set( &info->sid, set) ) {
    3231             :                 struct dom_sid_buf buf;
    3232           0 :                 DEBUG(3,("_lsa_RemovePrivilegesFromAccount: revoke_privilege(%s) failed!\n",
    3233             :                          dom_sid_str_buf(&info->sid, &buf)));
    3234           0 :                 return NT_STATUS_NO_SUCH_PRIVILEGE;
    3235             :         }
    3236             : 
    3237           2 :         return NT_STATUS_OK;
    3238             : }
    3239             : 
    3240             : /***************************************************************************
    3241             :  _lsa_LookupPrivName
    3242             :  ***************************************************************************/
    3243             : 
    3244          50 : NTSTATUS _lsa_LookupPrivName(struct pipes_struct *p,
    3245             :                              struct lsa_LookupPrivName *r)
    3246             : {
    3247          50 :         struct lsa_info *info = NULL;
    3248             :         const char *name;
    3249             :         struct lsa_StringLarge *lsa_name;
    3250             :         NTSTATUS status;
    3251             : 
    3252             :         /* find the connection policy handle. */
    3253          50 :         info = find_policy_by_hnd(p,
    3254             :                                   r->in.handle,
    3255             :                                   LSA_HANDLE_POLICY_TYPE,
    3256             :                                   struct lsa_info,
    3257             :                                   &status);
    3258          50 :         if (!NT_STATUS_IS_OK(status)) {
    3259           0 :                 return NT_STATUS_INVALID_HANDLE;
    3260             :         }
    3261             : 
    3262          50 :         if (!(info->access & LSA_POLICY_VIEW_LOCAL_INFORMATION)) {
    3263           0 :                 return NT_STATUS_ACCESS_DENIED;
    3264             :         }
    3265             : 
    3266          50 :         if (r->in.luid->high != 0) {
    3267           0 :                 return NT_STATUS_NO_SUCH_PRIVILEGE;
    3268             :         }
    3269             : 
    3270          50 :         name = sec_privilege_name(r->in.luid->low);
    3271          50 :         if (!name) {
    3272           0 :                 return NT_STATUS_NO_SUCH_PRIVILEGE;
    3273             :         }
    3274             : 
    3275          50 :         lsa_name = talloc_zero(p->mem_ctx, struct lsa_StringLarge);
    3276          50 :         if (!lsa_name) {
    3277           0 :                 return NT_STATUS_NO_MEMORY;
    3278             :         }
    3279             : 
    3280          50 :         lsa_name->string = talloc_strdup(lsa_name, name);
    3281          50 :         if (!lsa_name->string) {
    3282           0 :                 TALLOC_FREE(lsa_name);
    3283           0 :                 return NT_STATUS_NO_MEMORY;
    3284             :         }
    3285             : 
    3286          50 :         *r->out.name = lsa_name;
    3287             : 
    3288          50 :         return NT_STATUS_OK;
    3289             : }
    3290             : 
    3291             : /***************************************************************************
    3292             :  _lsa_QuerySecurity
    3293             :  ***************************************************************************/
    3294             : 
    3295          12 : NTSTATUS _lsa_QuerySecurity(struct pipes_struct *p,
    3296             :                             struct lsa_QuerySecurity *r)
    3297             : {
    3298          12 :         struct lsa_info *handle=NULL;
    3299          12 :         struct security_descriptor *psd = NULL;
    3300          12 :         size_t sd_size = 0;
    3301             :         NTSTATUS status;
    3302             : 
    3303             :         /* find the connection policy handle. */
    3304          12 :         handle = find_policy_by_hnd(p,
    3305             :                                     r->in.handle,
    3306             :                                     DCESRV_HANDLE_ANY,
    3307             :                                     struct lsa_info,
    3308             :                                     &status);
    3309          12 :         if (!NT_STATUS_IS_OK(status)) {
    3310           0 :                 return NT_STATUS_INVALID_HANDLE;
    3311             :         }
    3312             : 
    3313          12 :         switch (handle->type) {
    3314          12 :         case LSA_HANDLE_POLICY_TYPE:
    3315             :         case LSA_HANDLE_ACCOUNT_TYPE:
    3316             :         case LSA_HANDLE_TRUST_TYPE:
    3317             :         case LSA_HANDLE_SECRET_TYPE:
    3318          12 :                 psd = handle->sd;
    3319          12 :                 sd_size = ndr_size_security_descriptor(psd, 0);
    3320          12 :                 status = NT_STATUS_OK;
    3321          12 :                 break;
    3322           0 :         default:
    3323           0 :                 status = NT_STATUS_INVALID_HANDLE;
    3324           0 :                 break;
    3325             :         }
    3326             : 
    3327          12 :         if (!NT_STATUS_IS_OK(status)) {
    3328           0 :                 return status;
    3329             :         }
    3330             : 
    3331          12 :         *r->out.sdbuf = make_sec_desc_buf(p->mem_ctx, sd_size, psd);
    3332          12 :         if (!*r->out.sdbuf) {
    3333           0 :                 return NT_STATUS_NO_MEMORY;
    3334             :         }
    3335             : 
    3336          12 :         return status;
    3337             : }
    3338             : 
    3339             : /***************************************************************************
    3340             :  _lsa_AddAccountRights
    3341             :  ***************************************************************************/
    3342             : 
    3343          21 : NTSTATUS _lsa_AddAccountRights(struct pipes_struct *p,
    3344             :                                struct lsa_AddAccountRights *r)
    3345             : {
    3346          21 :         int i = 0;
    3347          21 :         uint32_t acc_granted = 0;
    3348          21 :         struct security_descriptor *psd = NULL;
    3349             :         size_t sd_size;
    3350             :         struct dom_sid sid;
    3351             :         NTSTATUS status;
    3352             : 
    3353             :         /* find the connection policy handle. */
    3354          21 :         (void)find_policy_by_hnd(p,
    3355             :                                  r->in.handle,
    3356             :                                  LSA_HANDLE_POLICY_TYPE,
    3357             :                                  struct lsa_info,
    3358             :                                  &status);
    3359          21 :         if (!NT_STATUS_IS_OK(status)) {
    3360           0 :                 return NT_STATUS_INVALID_HANDLE;
    3361             :         }
    3362             : 
    3363             :         /* get the generic lsa account SD for this SID until we store it */
    3364          21 :         status = make_lsa_object_sd(p->mem_ctx, &psd, &sd_size,
    3365             :                                 &lsa_account_mapping,
    3366             :                                 NULL, 0);
    3367          21 :         if (!NT_STATUS_IS_OK(status)) {
    3368           0 :                 return status;
    3369             :         }
    3370             : 
    3371             :         /*
    3372             :          * From the MS DOCs. If the sid doesn't exist, ask for LSA_POLICY_CREATE_ACCOUNT
    3373             :          * on the policy handle. If it does, ask for
    3374             :          * LSA_ACCOUNT_ADJUST_PRIVILEGES|LSA_ACCOUNT_ADJUST_SYSTEM_ACCESS|LSA_ACCOUNT_VIEW,
    3375             :          * on the account sid. We don't check here so just use the latter. JRA.
    3376             :          */
    3377             : 
    3378          21 :         status = access_check_object(psd, p->session_info->security_token,
    3379             :                                      SEC_PRIV_INVALID, SEC_PRIV_INVALID, 0,
    3380             :                                      LSA_ACCOUNT_ADJUST_PRIVILEGES|LSA_ACCOUNT_ADJUST_SYSTEM_ACCESS|LSA_ACCOUNT_VIEW,
    3381             :                                      &acc_granted, "_lsa_AddAccountRights" );
    3382          21 :         if (!NT_STATUS_IS_OK(status)) {
    3383           0 :                 return status;
    3384             :         }
    3385             : 
    3386             :         /* according to an NT4 PDC, you can add privileges to SIDs even without
    3387             :            call_lsa_create_account() first.  And you can use any arbitrary SID. */
    3388             : 
    3389          21 :         sid_copy( &sid, r->in.sid );
    3390             : 
    3391          41 :         for ( i=0; i < r->in.rights->count; i++ ) {
    3392             : 
    3393          21 :                 const char *privname = r->in.rights->names[i].string;
    3394             : 
    3395             :                 /* only try to add non-null strings */
    3396             : 
    3397          21 :                 if ( !privname )
    3398           0 :                         continue;
    3399             : 
    3400          21 :                 if ( !grant_privilege_by_name( &sid, privname ) ) {
    3401           1 :                         DEBUG(2,("_lsa_AddAccountRights: Failed to add privilege [%s]\n",
    3402             :                                 privname ));
    3403           1 :                         return NT_STATUS_NO_SUCH_PRIVILEGE;
    3404             :                 }
    3405             :         }
    3406             : 
    3407          20 :         return NT_STATUS_OK;
    3408             : }
    3409             : 
    3410             : /***************************************************************************
    3411             :  _lsa_RemoveAccountRights
    3412             :  ***************************************************************************/
    3413             : 
    3414          18 : NTSTATUS _lsa_RemoveAccountRights(struct pipes_struct *p,
    3415             :                                   struct lsa_RemoveAccountRights *r)
    3416             : {
    3417          18 :         int i = 0;
    3418          18 :         struct security_descriptor *psd = NULL;
    3419             :         size_t sd_size;
    3420             :         struct dom_sid sid;
    3421          18 :         const char *privname = NULL;
    3422          18 :         uint32_t acc_granted = 0;
    3423             :         NTSTATUS status;
    3424             : 
    3425             :         /* find the connection policy handle. */
    3426          18 :         (void)find_policy_by_hnd(p,
    3427             :                                  r->in.handle,
    3428             :                                  LSA_HANDLE_POLICY_TYPE,
    3429             :                                  struct lsa_info,
    3430             :                                  &status);
    3431          18 :         if (!NT_STATUS_IS_OK(status)) {
    3432           0 :                 return NT_STATUS_INVALID_HANDLE;
    3433             :         }
    3434             : 
    3435             :         /* get the generic lsa account SD for this SID until we store it */
    3436          18 :         status = make_lsa_object_sd(p->mem_ctx, &psd, &sd_size,
    3437             :                                 &lsa_account_mapping,
    3438             :                                 NULL, 0);
    3439          18 :         if (!NT_STATUS_IS_OK(status)) {
    3440           0 :                 return status;
    3441             :         }
    3442             : 
    3443             :         /*
    3444             :          * From the MS DOCs. We need
    3445             :          * LSA_ACCOUNT_ADJUST_PRIVILEGES|LSA_ACCOUNT_ADJUST_SYSTEM_ACCESS|LSA_ACCOUNT_VIEW
    3446             :          * and DELETE on the account sid.
    3447             :          */
    3448             : 
    3449          18 :         status = access_check_object(psd, p->session_info->security_token,
    3450             :                                      SEC_PRIV_INVALID, SEC_PRIV_INVALID, 0,
    3451             :                                      LSA_ACCOUNT_ADJUST_PRIVILEGES|LSA_ACCOUNT_ADJUST_SYSTEM_ACCESS|
    3452             :                                      LSA_ACCOUNT_VIEW|SEC_STD_DELETE,
    3453             :                                      &acc_granted, "_lsa_RemoveAccountRights");
    3454          18 :         if (!NT_STATUS_IS_OK(status)) {
    3455           0 :                 return status;
    3456             :         }
    3457             : 
    3458          18 :         sid_copy( &sid, r->in.sid );
    3459             : 
    3460          18 :         if ( r->in.remove_all ) {
    3461           0 :                 if ( !revoke_all_privileges( &sid ) )
    3462           0 :                         return NT_STATUS_ACCESS_DENIED;
    3463             : 
    3464           0 :                 return NT_STATUS_OK;
    3465             :         }
    3466             : 
    3467          36 :         for ( i=0; i < r->in.rights->count; i++ ) {
    3468             : 
    3469          18 :                 privname = r->in.rights->names[i].string;
    3470             : 
    3471             :                 /* only try to add non-null strings */
    3472             : 
    3473          18 :                 if ( !privname )
    3474           0 :                         continue;
    3475             : 
    3476          18 :                 if ( !revoke_privilege_by_name( &sid, privname ) ) {
    3477           0 :                         DEBUG(2,("_lsa_RemoveAccountRights: Failed to revoke privilege [%s]\n",
    3478             :                                 privname ));
    3479           0 :                         return NT_STATUS_NO_SUCH_PRIVILEGE;
    3480             :                 }
    3481             :         }
    3482             : 
    3483          18 :         return NT_STATUS_OK;
    3484             : }
    3485             : 
    3486             : /*******************************************************************
    3487             : ********************************************************************/
    3488             : 
    3489          14 : static NTSTATUS init_lsa_right_set(TALLOC_CTX *mem_ctx,
    3490             :                                    struct lsa_RightSet *r,
    3491             :                                    PRIVILEGE_SET *privileges)
    3492             : {
    3493             :         uint32_t i;
    3494             :         const char *privname;
    3495          14 :         const char **privname_array = NULL;
    3496          14 :         size_t num_priv = 0;
    3497             : 
    3498          66 :         for (i=0; i<privileges->count; i++) {
    3499          52 :                 if (privileges->set[i].luid.high) {
    3500           0 :                         continue;
    3501             :                 }
    3502          52 :                 privname = sec_privilege_name(privileges->set[i].luid.low);
    3503          52 :                 if (privname) {
    3504          52 :                         if (!add_string_to_array(mem_ctx, privname,
    3505             :                                                  &privname_array, &num_priv)) {
    3506           0 :                                 return NT_STATUS_NO_MEMORY;
    3507             :                         }
    3508             :                 }
    3509             :         }
    3510             : 
    3511          14 :         if (num_priv) {
    3512             : 
    3513           4 :                 r->names = talloc_zero_array(mem_ctx, struct lsa_StringLarge,
    3514             :                                              num_priv);
    3515           4 :                 if (!r->names) {
    3516           0 :                         return NT_STATUS_NO_MEMORY;
    3517             :                 }
    3518             : 
    3519          56 :                 for (i=0; i<num_priv; i++) {
    3520          52 :                         init_lsa_StringLarge(&r->names[i], privname_array[i]);
    3521             :                 }
    3522             : 
    3523           4 :                 r->count = num_priv;
    3524             :         }
    3525             : 
    3526          14 :         return NT_STATUS_OK;
    3527             : }
    3528             : 
    3529             : /***************************************************************************
    3530             :  _lsa_EnumAccountRights
    3531             :  ***************************************************************************/
    3532             : 
    3533          80 : NTSTATUS _lsa_EnumAccountRights(struct pipes_struct *p,
    3534             :                                 struct lsa_EnumAccountRights *r)
    3535             : {
    3536             :         NTSTATUS status;
    3537          80 :         struct lsa_info *info = NULL;
    3538             :         PRIVILEGE_SET *privileges;
    3539             :         struct dom_sid_buf buf;
    3540             : 
    3541             :         /* find the connection policy handle. */
    3542             : 
    3543          80 :         info = find_policy_by_hnd(p,
    3544             :                                   r->in.handle,
    3545             :                                   LSA_HANDLE_POLICY_TYPE,
    3546             :                                   struct lsa_info,
    3547             :                                   &status);
    3548          80 :         if (!NT_STATUS_IS_OK(status)) {
    3549           0 :                 return NT_STATUS_INVALID_HANDLE;
    3550             :         }
    3551             : 
    3552          80 :         if (!(info->access & LSA_ACCOUNT_VIEW)) {
    3553           0 :                 return NT_STATUS_ACCESS_DENIED;
    3554             :         }
    3555             : 
    3556             :         /* according to an NT4 PDC, you can add privileges to SIDs even without
    3557             :            call_lsa_create_account() first.  And you can use any arbitrary SID. */
    3558             : 
    3559             :         /* according to MS-LSAD 3.1.4.5.10 it is required to return
    3560             :          * NT_STATUS_OBJECT_NAME_NOT_FOUND if the account sid was not found in
    3561             :          * the lsa database */
    3562             : 
    3563          80 :         status = get_privileges_for_sid_as_set(p->mem_ctx, &privileges, r->in.sid);
    3564          80 :         if (!NT_STATUS_IS_OK(status)) {
    3565          66 :                 return status;
    3566             :         }
    3567             : 
    3568          14 :         DEBUG(10,("_lsa_EnumAccountRights: %s has %d privileges\n",
    3569             :                   dom_sid_str_buf(r->in.sid, &buf),
    3570             :                   privileges->count));
    3571             : 
    3572          14 :         status = init_lsa_right_set(p->mem_ctx, r->out.rights, privileges);
    3573             : 
    3574          14 :         return status;
    3575             : }
    3576             : 
    3577             : /***************************************************************************
    3578             :  _lsa_LookupPrivValue
    3579             :  ***************************************************************************/
    3580             : 
    3581          19 : NTSTATUS _lsa_LookupPrivValue(struct pipes_struct *p,
    3582             :                               struct lsa_LookupPrivValue *r)
    3583             : {
    3584          19 :         struct lsa_info *info = NULL;
    3585          19 :         const char *name = NULL;
    3586             :         NTSTATUS status;
    3587             : 
    3588             :         /* find the connection policy handle. */
    3589             : 
    3590          19 :         info = find_policy_by_hnd(p,
    3591             :                                   r->in.handle,
    3592             :                                   LSA_HANDLE_POLICY_TYPE,
    3593             :                                   struct lsa_info,
    3594             :                                   &status);
    3595          19 :         if (!NT_STATUS_IS_OK(status)) {
    3596           0 :                 return NT_STATUS_INVALID_HANDLE;
    3597             :         }
    3598             : 
    3599          19 :         if (!(info->access & LSA_POLICY_LOOKUP_NAMES))
    3600           0 :                 return NT_STATUS_ACCESS_DENIED;
    3601             : 
    3602          19 :         name = r->in.name->string;
    3603             : 
    3604          19 :         DEBUG(10,("_lsa_lookup_priv_value: name = %s\n", name));
    3605             : 
    3606          19 :         r->out.luid->low = sec_privilege_id(name);
    3607          19 :         r->out.luid->high = 0;
    3608          19 :         if (r->out.luid->low == SEC_PRIV_INVALID) {
    3609           0 :                 return NT_STATUS_NO_SUCH_PRIVILEGE;
    3610             :         }
    3611          19 :         return NT_STATUS_OK;
    3612             : }
    3613             : 
    3614             : /***************************************************************************
    3615             :  _lsa_EnumAccountsWithUserRight
    3616             :  ***************************************************************************/
    3617             : 
    3618          18 : NTSTATUS _lsa_EnumAccountsWithUserRight(struct pipes_struct *p,
    3619             :                                         struct lsa_EnumAccountsWithUserRight *r)
    3620             : {
    3621             :         NTSTATUS status;
    3622          18 :         struct lsa_info *info = NULL;
    3623          18 :         struct dom_sid *sids = NULL;
    3624          18 :         int num_sids = 0;
    3625             :         uint32_t i;
    3626             :         enum sec_privilege privilege;
    3627             : 
    3628          18 :         info = find_policy_by_hnd(p,
    3629             :                                   r->in.handle,
    3630             :                                   LSA_HANDLE_POLICY_TYPE,
    3631             :                                   struct lsa_info,
    3632             :                                   &status);
    3633          18 :         if (!NT_STATUS_IS_OK(status)) {
    3634           0 :                 return NT_STATUS_INVALID_HANDLE;
    3635             :         }
    3636             : 
    3637          18 :         if (!(info->access & LSA_POLICY_LOOKUP_NAMES)) {
    3638           0 :                 return NT_STATUS_ACCESS_DENIED;
    3639             :         }
    3640             : 
    3641          18 :         if (!r->in.name || !r->in.name->string) {
    3642           0 :                 return NT_STATUS_NO_SUCH_PRIVILEGE;
    3643             :         }
    3644             : 
    3645          18 :         privilege = sec_privilege_id(r->in.name->string);
    3646          18 :         if (privilege == SEC_PRIV_INVALID) {
    3647           0 :                 return NT_STATUS_NO_SUCH_PRIVILEGE;
    3648             :         }
    3649             : 
    3650          18 :         status = privilege_enum_sids(privilege, p->mem_ctx,
    3651             :                                      &sids, &num_sids);
    3652          18 :         if (!NT_STATUS_IS_OK(status)) {
    3653           0 :                 return status;
    3654             :         }
    3655             : 
    3656          18 :         r->out.sids->num_sids = num_sids;
    3657          18 :         r->out.sids->sids = talloc_array(p->mem_ctx, struct lsa_SidPtr,
    3658             :                                          r->out.sids->num_sids);
    3659             : 
    3660          36 :         for (i=0; i < r->out.sids->num_sids; i++) {
    3661          36 :                 r->out.sids->sids[i].sid = dom_sid_dup(r->out.sids->sids,
    3662          18 :                                                           &sids[i]);
    3663          18 :                 if (!r->out.sids->sids[i].sid) {
    3664           0 :                         TALLOC_FREE(r->out.sids->sids);
    3665           0 :                         r->out.sids->num_sids = 0;
    3666           0 :                         return NT_STATUS_NO_MEMORY;
    3667             :                 }
    3668             :         }
    3669             : 
    3670          18 :         return NT_STATUS_OK;
    3671             : }
    3672             : 
    3673             : /***************************************************************************
    3674             :  _lsa_Delete
    3675             :  ***************************************************************************/
    3676             : 
    3677           2 : NTSTATUS _lsa_Delete(struct pipes_struct *p,
    3678             :                      struct lsa_Delete *r)
    3679             : {
    3680           2 :         return NT_STATUS_NOT_SUPPORTED;
    3681             : }
    3682             : 
    3683           0 : static NTSTATUS info_ex_2_pdb_trusted_domain(
    3684             :                                       struct lsa_TrustDomainInfoInfoEx *info_ex,
    3685             :                                       struct pdb_trusted_domain *td)
    3686             : {
    3687           0 :         if (info_ex->domain_name.string == NULL ||
    3688           0 :             info_ex->netbios_name.string == NULL ||
    3689           0 :             info_ex->sid == NULL) {
    3690           0 :                 return NT_STATUS_INVALID_PARAMETER;
    3691             :         }
    3692             : 
    3693           0 :         td->domain_name = talloc_strdup(td, info_ex->domain_name.string);
    3694           0 :         td->netbios_name = talloc_strdup(td, info_ex->netbios_name.string);
    3695           0 :         sid_copy(&td->security_identifier, info_ex->sid);
    3696           0 :         if (td->domain_name == NULL ||
    3697           0 :             td->netbios_name == NULL ||
    3698           0 :             is_null_sid(&td->security_identifier)) {
    3699           0 :                 return NT_STATUS_NO_MEMORY;
    3700             :         }
    3701           0 :         td->trust_direction = info_ex->trust_direction;
    3702           0 :         td->trust_type = info_ex->trust_type;
    3703           0 :         td->trust_attributes = info_ex->trust_attributes;
    3704             : 
    3705           0 :         return NT_STATUS_OK;
    3706             : }
    3707             : 
    3708           0 : static NTSTATUS setInfoTrustedDomain_base(struct pipes_struct *p,
    3709             :                                           TALLOC_CTX *mem_ctx,
    3710             :                                           struct lsa_info *policy,
    3711             :                                           enum lsa_TrustDomInfoEnum level,
    3712             :                                           union lsa_TrustedDomainInfo *info)
    3713             : {
    3714           0 :         struct lsa_TrustDomainInfoAuthInfoInternal *auth_info_int = NULL;
    3715             :         DATA_BLOB auth_blob;
    3716             :         struct trustDomainPasswords auth_struct;
    3717             :         NTSTATUS nt_status;
    3718             : 
    3719             :         struct pdb_trusted_domain *td;
    3720             :         struct pdb_trusted_domain *orig_td;
    3721             : 
    3722           0 :         td = talloc_zero(mem_ctx, struct pdb_trusted_domain);
    3723           0 :         if (td == NULL) {
    3724           0 :                 return NT_STATUS_NO_MEMORY;
    3725             :         }
    3726             : 
    3727           0 :         switch (level) {
    3728           0 :         case LSA_TRUSTED_DOMAIN_INFO_POSIX_OFFSET:
    3729           0 :                 if (!(policy->access & LSA_TRUSTED_SET_POSIX)) {
    3730           0 :                         return NT_STATUS_ACCESS_DENIED;
    3731             :                 }
    3732           0 :                 td->trust_posix_offset = &info->posix_offset.posix_offset;
    3733           0 :                 break;
    3734           0 :         case LSA_TRUSTED_DOMAIN_INFO_INFO_EX:
    3735           0 :                 if (!(policy->access & LSA_TRUSTED_SET_POSIX)) {
    3736           0 :                         return NT_STATUS_ACCESS_DENIED;
    3737             :                 }
    3738           0 :                 nt_status = info_ex_2_pdb_trusted_domain(&info->info_ex, td);
    3739           0 :                 if (!NT_STATUS_IS_OK(nt_status)) {
    3740           0 :                         return nt_status;
    3741             :                 }
    3742           0 :                 break;
    3743           0 :         case LSA_TRUSTED_DOMAIN_INFO_AUTH_INFO:
    3744           0 :                 if (!(policy->access & LSA_TRUSTED_SET_AUTH)) {
    3745           0 :                         return NT_STATUS_ACCESS_DENIED;
    3746             :                 }
    3747           0 :                 nt_status = auth_info_2_auth_blob(td, &info->auth_info,
    3748             :                                                   &td->trust_auth_incoming,
    3749             :                                                   &td->trust_auth_outgoing);
    3750           0 :                 if (!NT_STATUS_IS_OK(nt_status)) {
    3751           0 :                         return nt_status;
    3752             :                 }
    3753           0 :                 break;
    3754           0 :         case LSA_TRUSTED_DOMAIN_INFO_FULL_INFO:
    3755           0 :                 if (!(policy->access & (LSA_TRUSTED_SET_AUTH | LSA_TRUSTED_SET_POSIX))) {
    3756           0 :                         return NT_STATUS_ACCESS_DENIED;
    3757             :                 }
    3758           0 :                 td->trust_posix_offset = &info->full_info.posix_offset.posix_offset;
    3759           0 :                 nt_status = info_ex_2_pdb_trusted_domain(&info->full_info.info_ex,
    3760             :                                                          td);
    3761           0 :                 if (!NT_STATUS_IS_OK(nt_status)) {
    3762           0 :                         return nt_status;
    3763             :                 }
    3764           0 :                 nt_status = auth_info_2_auth_blob(td,
    3765             :                                                   &info->full_info.auth_info,
    3766             :                                                   &td->trust_auth_incoming,
    3767             :                                                   &td->trust_auth_outgoing);
    3768           0 :                 if (!NT_STATUS_IS_OK(nt_status)) {
    3769           0 :                         return nt_status;
    3770             :                 }
    3771           0 :                 break;
    3772           0 :         case LSA_TRUSTED_DOMAIN_INFO_AUTH_INFO_INTERNAL:
    3773           0 :                 if (!(policy->access & LSA_TRUSTED_SET_AUTH)) {
    3774           0 :                         return NT_STATUS_ACCESS_DENIED;
    3775             :                 }
    3776           0 :                 auth_info_int = &info->auth_info_internal;
    3777           0 :                 break;
    3778           0 :         case LSA_TRUSTED_DOMAIN_INFO_FULL_INFO_INTERNAL:
    3779           0 :                 if (!(policy->access & (LSA_TRUSTED_SET_AUTH | LSA_TRUSTED_SET_POSIX))) {
    3780           0 :                         return NT_STATUS_ACCESS_DENIED;
    3781             :                 }
    3782           0 :                 td->trust_posix_offset = &info->full_info_internal.posix_offset.posix_offset;
    3783           0 :                 nt_status = info_ex_2_pdb_trusted_domain(&info->full_info_internal.info_ex,
    3784             :                                                          td);
    3785           0 :                 if (!NT_STATUS_IS_OK(nt_status)) {
    3786           0 :                         return nt_status;
    3787             :                 }
    3788           0 :                 auth_info_int = &info->full_info_internal.auth_info;
    3789           0 :                 break;
    3790           0 :         case LSA_TRUSTED_DOMAIN_SUPPORTED_ENCRYPTION_TYPES:
    3791           0 :                 if (!(policy->access & LSA_TRUSTED_SET_POSIX)) {
    3792           0 :                         return NT_STATUS_ACCESS_DENIED;
    3793             :                 }
    3794           0 :                 td->supported_enc_type = &info->enc_types.enc_types;
    3795           0 :                 break;
    3796           0 :         default:
    3797           0 :                 return NT_STATUS_INVALID_PARAMETER;
    3798             :         }
    3799             : 
    3800             :         /* decode auth_info_int if set */
    3801           0 :         if (auth_info_int) {
    3802             : 
    3803             :                 /* now decrypt blob */
    3804           0 :                 auth_blob = data_blob_const(auth_info_int->auth_blob.data,
    3805           0 :                                             auth_info_int->auth_blob.size);
    3806             : 
    3807           0 :                 nt_status = get_trustdom_auth_blob(p, mem_ctx,
    3808             :                                                    &auth_blob, &auth_struct);
    3809           0 :                 if (!NT_STATUS_IS_OK(nt_status)) {
    3810           0 :                         return nt_status;
    3811             :                 }
    3812             :         } else {
    3813           0 :             memset(&auth_struct, 0, sizeof(auth_struct));
    3814             :         }
    3815             : 
    3816             : /* TODO: verify only one object matches the dns/netbios/sid triplet and that
    3817             :  * this is the one we already have */
    3818             : 
    3819             : /* TODO: check if the trust direction is changed and we need to add or remove
    3820             :  * auth data */
    3821             : 
    3822             : /* TODO: check if trust type shall be changed and return an error in this case
    3823             :  * */
    3824           0 :         nt_status = pdb_get_trusted_domain_by_sid(p->mem_ctx, &policy->sid,
    3825             :                                                &orig_td);
    3826           0 :         if (!NT_STATUS_IS_OK(nt_status)) {
    3827           0 :                 return nt_status;
    3828             :         }
    3829             : 
    3830             : 
    3831             :         /* TODO: should we fetch previous values from the existing entry
    3832             :          * and append them ? */
    3833           0 :         if (auth_struct.incoming.count) {
    3834           0 :                 nt_status = get_trustauth_inout_blob(mem_ctx,
    3835             :                                                      &auth_struct.incoming,
    3836             :                                                      &td->trust_auth_incoming);
    3837           0 :                 if (!NT_STATUS_IS_OK(nt_status)) {
    3838           0 :                         return nt_status;
    3839             :                 }
    3840             :         } else {
    3841           0 :                 ZERO_STRUCT(td->trust_auth_incoming);
    3842             :         }
    3843             : 
    3844           0 :         if (auth_struct.outgoing.count) {
    3845           0 :                 nt_status = get_trustauth_inout_blob(mem_ctx,
    3846             :                                                      &auth_struct.outgoing,
    3847             :                                                      &td->trust_auth_outgoing);
    3848           0 :                 if (!NT_STATUS_IS_OK(nt_status)) {
    3849           0 :                         return nt_status;
    3850             :                 }
    3851             :         } else {
    3852           0 :                 ZERO_STRUCT(td->trust_auth_outgoing);
    3853             :         }
    3854             : 
    3855           0 :         nt_status = pdb_set_trusted_domain(orig_td->domain_name, td);
    3856           0 :         if (!NT_STATUS_IS_OK(nt_status)) {
    3857           0 :                 return nt_status;
    3858             :         }
    3859             : 
    3860           0 :         return NT_STATUS_OK;
    3861             : }
    3862             : 
    3863           0 : NTSTATUS _lsa_SetTrustedDomainInfo(struct pipes_struct *p,
    3864             :                                    struct lsa_SetTrustedDomainInfo *r)
    3865             : {
    3866             :         NTSTATUS status;
    3867             :         struct policy_handle trustdom_handle;
    3868             :         struct lsa_OpenTrustedDomain o;
    3869             :         struct lsa_SetInformationTrustedDomain s;
    3870             :         struct lsa_Close c;
    3871             : 
    3872           0 :         o.in.handle             = r->in.handle;
    3873           0 :         o.in.sid                = r->in.dom_sid;
    3874           0 :         o.in.access_mask        = SEC_FLAG_MAXIMUM_ALLOWED;
    3875           0 :         o.out.trustdom_handle   = &trustdom_handle;
    3876             : 
    3877           0 :         status = _lsa_OpenTrustedDomain(p, &o);
    3878           0 :         if (!NT_STATUS_IS_OK(status)) {
    3879           0 :                 return status;
    3880             :         }
    3881             : 
    3882           0 :         s.in.trustdom_handle    = &trustdom_handle;
    3883           0 :         s.in.level              = r->in.level;
    3884           0 :         s.in.info               = r->in.info;
    3885             : 
    3886           0 :         status = _lsa_SetInformationTrustedDomain(p, &s);
    3887           0 :         if (!NT_STATUS_IS_OK(status)) {
    3888           0 :                 return status;
    3889             :         }
    3890             : 
    3891           0 :         c.in.handle             = &trustdom_handle;
    3892           0 :         c.out.handle            = &trustdom_handle;
    3893             : 
    3894           0 :         return _lsa_Close(p, &c);
    3895             : }
    3896             : 
    3897           0 : NTSTATUS _lsa_SetTrustedDomainInfoByName(struct pipes_struct *p,
    3898             :                                          struct lsa_SetTrustedDomainInfoByName *r)
    3899             : {
    3900             :         NTSTATUS status;
    3901             :         struct policy_handle trustdom_handle;
    3902             :         struct lsa_OpenTrustedDomainByName o;
    3903             :         struct lsa_SetInformationTrustedDomain s;
    3904             :         struct lsa_Close c;
    3905             : 
    3906           0 :         o.in.handle             = r->in.handle;
    3907           0 :         o.in.name.string        = r->in.trusted_domain->string;
    3908           0 :         o.in.access_mask        = SEC_FLAG_MAXIMUM_ALLOWED;
    3909           0 :         o.out.trustdom_handle   = &trustdom_handle;
    3910             : 
    3911           0 :         status = _lsa_OpenTrustedDomainByName(p, &o);
    3912           0 :         if (!NT_STATUS_IS_OK(status)) {
    3913           0 :                 if (NT_STATUS_EQUAL(status, NT_STATUS_NO_SUCH_DOMAIN)) {
    3914           0 :                         return NT_STATUS_OBJECT_NAME_NOT_FOUND;
    3915             :                 }
    3916           0 :                 return status;
    3917             :         }
    3918             : 
    3919           0 :         s.in.trustdom_handle    = &trustdom_handle;
    3920           0 :         s.in.level              = r->in.level;
    3921           0 :         s.in.info               = r->in.info;
    3922             : 
    3923           0 :         status = _lsa_SetInformationTrustedDomain(p, &s);
    3924           0 :         if (!NT_STATUS_IS_OK(status)) {
    3925           0 :                 return status;
    3926             :         }
    3927             : 
    3928           0 :         c.in.handle             = &trustdom_handle;
    3929           0 :         c.out.handle            = &trustdom_handle;
    3930             : 
    3931           0 :         return _lsa_Close(p, &c);
    3932             : }
    3933             : 
    3934           0 : NTSTATUS _lsa_SetInformationTrustedDomain(struct pipes_struct *p,
    3935             :                                           struct lsa_SetInformationTrustedDomain *r)
    3936             : {
    3937             :         struct lsa_info *policy;
    3938             :         NTSTATUS status;
    3939             : 
    3940           0 :         policy = find_policy_by_hnd(p,
    3941             :                                     r->in.trustdom_handle,
    3942             :                                     LSA_HANDLE_TRUST_TYPE,
    3943             :                                     struct lsa_info,
    3944             :                                     &status);
    3945           0 :         if (!NT_STATUS_IS_OK(status)) {
    3946           0 :                 return NT_STATUS_INVALID_HANDLE;
    3947             :         }
    3948             : 
    3949           0 :         return setInfoTrustedDomain_base(p, p->mem_ctx, policy,
    3950             :                                          r->in.level, r->in.info);
    3951             : }
    3952             : 
    3953             : 
    3954             : /*
    3955             :  * From here on the server routines are just dummy ones to make smbd link with
    3956             :  * librpc/gen_ndr/srv_lsa.c. These routines are actually never called, we are
    3957             :  * pulling the server stubs across one by one.
    3958             :  */
    3959             : 
    3960           0 : NTSTATUS _lsa_SetSecObj(struct pipes_struct *p, struct lsa_SetSecObj *r)
    3961             : {
    3962           0 :         p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
    3963           0 :         return NT_STATUS_NOT_IMPLEMENTED;
    3964             : }
    3965             : 
    3966           0 : NTSTATUS _lsa_ChangePassword(struct pipes_struct *p,
    3967             :                              struct lsa_ChangePassword *r)
    3968             : {
    3969           0 :         p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
    3970           0 :         return NT_STATUS_NOT_IMPLEMENTED;
    3971             : }
    3972             : 
    3973           0 : NTSTATUS _lsa_SetInfoPolicy(struct pipes_struct *p, struct lsa_SetInfoPolicy *r)
    3974             : {
    3975           0 :         p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
    3976           0 :         return NT_STATUS_NOT_IMPLEMENTED;
    3977             : }
    3978             : 
    3979           0 : NTSTATUS _lsa_ClearAuditLog(struct pipes_struct *p, struct lsa_ClearAuditLog *r)
    3980             : {
    3981           0 :         p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
    3982           0 :         return NT_STATUS_NOT_IMPLEMENTED;
    3983             : }
    3984             : 
    3985           0 : NTSTATUS _lsa_GetQuotasForAccount(struct pipes_struct *p,
    3986             :                                   struct lsa_GetQuotasForAccount *r)
    3987             : {
    3988           0 :         p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
    3989           0 :         return NT_STATUS_NOT_IMPLEMENTED;
    3990             : }
    3991             : 
    3992           0 : NTSTATUS _lsa_SetQuotasForAccount(struct pipes_struct *p,
    3993             :                                   struct lsa_SetQuotasForAccount *r)
    3994             : {
    3995           0 :         p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
    3996           0 :         return NT_STATUS_NOT_IMPLEMENTED;
    3997             : }
    3998             : 
    3999           0 : NTSTATUS _lsa_StorePrivateData(struct pipes_struct *p,
    4000             :                                struct lsa_StorePrivateData *r)
    4001             : {
    4002           0 :         p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
    4003           0 :         return NT_STATUS_NOT_IMPLEMENTED;
    4004             : }
    4005             : 
    4006           0 : NTSTATUS _lsa_RetrievePrivateData(struct pipes_struct *p,
    4007             :                                   struct lsa_RetrievePrivateData *r)
    4008             : {
    4009           0 :         p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
    4010           0 :         return NT_STATUS_NOT_IMPLEMENTED;
    4011             : }
    4012             : 
    4013           0 : NTSTATUS _lsa_SetInfoPolicy2(struct pipes_struct *p,
    4014             :                              struct lsa_SetInfoPolicy2 *r)
    4015             : {
    4016           0 :         p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
    4017           0 :         return NT_STATUS_NOT_IMPLEMENTED;
    4018             : }
    4019             : 
    4020           0 : NTSTATUS _lsa_EnumTrustedDomainsEx(struct pipes_struct *p,
    4021             :                                    struct lsa_EnumTrustedDomainsEx *r)
    4022             : {
    4023             :         struct lsa_info *info;
    4024             :         uint32_t count;
    4025             :         struct pdb_trusted_domain **domains;
    4026             :         struct lsa_TrustDomainInfoInfoEx *entries;
    4027             :         int i;
    4028             :         NTSTATUS nt_status;
    4029             : 
    4030             :         /* bail out early if pdb backend is not capable of ex trusted domains,
    4031             :          * if we don't do that, the client might not call
    4032             :          * _lsa_EnumTrustedDomains() afterwards - gd */
    4033             : 
    4034           0 :         if (!(pdb_capabilities() & PDB_CAP_TRUSTED_DOMAINS_EX)) {
    4035           0 :                 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
    4036           0 :                 return NT_STATUS_NOT_IMPLEMENTED;
    4037             :         }
    4038             : 
    4039           0 :         info = find_policy_by_hnd(p,
    4040             :                                   r->in.handle,
    4041             :                                   LSA_HANDLE_POLICY_TYPE,
    4042             :                                   struct lsa_info,
    4043             :                                   &nt_status);
    4044           0 :         if (!NT_STATUS_IS_OK(nt_status)) {
    4045           0 :                 return NT_STATUS_INVALID_HANDLE;
    4046             :         }
    4047             : 
    4048             :         /* check if the user has enough rights */
    4049           0 :         if (!(info->access & LSA_POLICY_VIEW_LOCAL_INFORMATION))
    4050           0 :                 return NT_STATUS_ACCESS_DENIED;
    4051             : 
    4052           0 :         become_root();
    4053           0 :         nt_status = pdb_enum_trusted_domains(p->mem_ctx, &count, &domains);
    4054           0 :         unbecome_root();
    4055             : 
    4056           0 :         if (!NT_STATUS_IS_OK(nt_status)) {
    4057           0 :                 return nt_status;
    4058             :         }
    4059             : 
    4060           0 :         entries = talloc_zero_array(p->mem_ctx, struct lsa_TrustDomainInfoInfoEx,
    4061             :                                     count);
    4062           0 :         if (!entries) {
    4063           0 :                 return NT_STATUS_NO_MEMORY;
    4064             :         }
    4065             : 
    4066           0 :         for (i=0; i<count; i++) {
    4067           0 :                 init_lsa_StringLarge(&entries[i].domain_name,
    4068           0 :                                      domains[i]->domain_name);
    4069           0 :                 init_lsa_StringLarge(&entries[i].netbios_name,
    4070           0 :                                      domains[i]->netbios_name);
    4071           0 :                 entries[i].sid = &domains[i]->security_identifier;
    4072           0 :                 entries[i].trust_direction = domains[i]->trust_direction;
    4073           0 :                 entries[i].trust_type = domains[i]->trust_type;
    4074           0 :                 entries[i].trust_attributes = domains[i]->trust_attributes;
    4075             :         }
    4076             : 
    4077           0 :         if (*r->in.resume_handle >= count) {
    4078           0 :                 *r->out.resume_handle = -1;
    4079           0 :                 TALLOC_FREE(entries);
    4080           0 :                 return NT_STATUS_NO_MORE_ENTRIES;
    4081             :         }
    4082             : 
    4083             :         /* return the rest, limit by max_size. Note that we
    4084             :            use the w2k3 element size value of 60 */
    4085           0 :         r->out.domains->count = count - *r->in.resume_handle;
    4086           0 :         r->out.domains->count = MIN(r->out.domains->count,
    4087             :                                     (r->in.max_size/LSA_ENUM_TRUST_DOMAIN_EX_MULTIPLIER));
    4088             : 
    4089           0 :         r->out.domains->domains = entries + *r->in.resume_handle;
    4090             : 
    4091           0 :         if (r->out.domains->count < count - *r->in.resume_handle) {
    4092           0 :                 *r->out.resume_handle = *r->in.resume_handle + r->out.domains->count;
    4093           0 :                 return STATUS_MORE_ENTRIES;
    4094             :         }
    4095             : 
    4096             :         /* according to MS-LSAD 3.1.4.7.8 output resume handle MUST
    4097             :          * always be larger than the previous input resume handle, in
    4098             :          * particular when hitting the last query it is vital to set the
    4099             :          * resume handle correctly to avoid infinite client loops, as
    4100             :          * seen e.g. with Windows XP SP3 when resume handle is 0 and
    4101             :          * status is NT_STATUS_OK - gd */
    4102             : 
    4103           0 :         *r->out.resume_handle = (uint32_t)-1;
    4104             : 
    4105           0 :         return NT_STATUS_OK;
    4106             : }
    4107             : 
    4108           0 : NTSTATUS _lsa_QueryDomainInformationPolicy(struct pipes_struct *p,
    4109             :                                            struct lsa_QueryDomainInformationPolicy *r)
    4110             : {
    4111           0 :         p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
    4112           0 :         return NT_STATUS_NOT_IMPLEMENTED;
    4113             : }
    4114             : 
    4115           0 : NTSTATUS _lsa_SetDomainInformationPolicy(struct pipes_struct *p,
    4116             :                                          struct lsa_SetDomainInformationPolicy *r)
    4117             : {
    4118           0 :         p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
    4119           0 :         return NT_STATUS_NOT_IMPLEMENTED;
    4120             : }
    4121             : 
    4122           0 : NTSTATUS _lsa_TestCall(struct pipes_struct *p, struct lsa_TestCall *r)
    4123             : {
    4124           0 :         p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
    4125           0 :         return NT_STATUS_NOT_IMPLEMENTED;
    4126             : }
    4127             : 
    4128           0 : NTSTATUS _lsa_CREDRWRITE(struct pipes_struct *p, struct lsa_CREDRWRITE *r)
    4129             : {
    4130           0 :         p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
    4131           0 :         return NT_STATUS_NOT_IMPLEMENTED;
    4132             : }
    4133             : 
    4134           0 : NTSTATUS _lsa_CREDRREAD(struct pipes_struct *p, struct lsa_CREDRREAD *r)
    4135             : {
    4136           0 :         p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
    4137           0 :         return NT_STATUS_NOT_IMPLEMENTED;
    4138             : }
    4139             : 
    4140           0 : NTSTATUS _lsa_CREDRENUMERATE(struct pipes_struct *p, struct lsa_CREDRENUMERATE *r)
    4141             : {
    4142           0 :         p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
    4143           0 :         return NT_STATUS_NOT_IMPLEMENTED;
    4144             : }
    4145             : 
    4146           0 : NTSTATUS _lsa_CREDRWRITEDOMAINCREDENTIALS(struct pipes_struct *p,
    4147             :                                           struct lsa_CREDRWRITEDOMAINCREDENTIALS *r)
    4148             : {
    4149           0 :         p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
    4150           0 :         return NT_STATUS_NOT_IMPLEMENTED;
    4151             : }
    4152             : 
    4153           0 : NTSTATUS _lsa_CREDRREADDOMAINCREDENTIALS(struct pipes_struct *p,
    4154             :                                          struct lsa_CREDRREADDOMAINCREDENTIALS *r)
    4155             : {
    4156           0 :         p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
    4157           0 :         return NT_STATUS_NOT_IMPLEMENTED;
    4158             : }
    4159             : 
    4160           0 : NTSTATUS _lsa_CREDRDELETE(struct pipes_struct *p, struct lsa_CREDRDELETE *r)
    4161             : {
    4162           0 :         p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
    4163           0 :         return NT_STATUS_NOT_IMPLEMENTED;
    4164             : }
    4165             : 
    4166           0 : NTSTATUS _lsa_CREDRGETTARGETINFO(struct pipes_struct *p,
    4167             :                                  struct lsa_CREDRGETTARGETINFO *r)
    4168             : {
    4169           0 :         p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
    4170           0 :         return NT_STATUS_NOT_IMPLEMENTED;
    4171             : }
    4172             : 
    4173           0 : NTSTATUS _lsa_CREDRPROFILELOADED(struct pipes_struct *p,
    4174             :                                  struct lsa_CREDRPROFILELOADED *r)
    4175             : {
    4176           0 :         p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
    4177           0 :         return NT_STATUS_NOT_IMPLEMENTED;
    4178             : }
    4179             : 
    4180           0 : NTSTATUS _lsa_CREDRGETSESSIONTYPES(struct pipes_struct *p,
    4181             :                                    struct lsa_CREDRGETSESSIONTYPES *r)
    4182             : {
    4183           0 :         p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
    4184           0 :         return NT_STATUS_NOT_IMPLEMENTED;
    4185             : }
    4186             : 
    4187           0 : NTSTATUS _lsa_LSARREGISTERAUDITEVENT(struct pipes_struct *p,
    4188             :                                      struct lsa_LSARREGISTERAUDITEVENT *r)
    4189             : {
    4190           0 :         p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
    4191           0 :         return NT_STATUS_NOT_IMPLEMENTED;
    4192             : }
    4193             : 
    4194           0 : NTSTATUS _lsa_LSARGENAUDITEVENT(struct pipes_struct *p,
    4195             :                                 struct lsa_LSARGENAUDITEVENT *r)
    4196             : {
    4197           0 :         p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
    4198           0 :         return NT_STATUS_NOT_IMPLEMENTED;
    4199             : }
    4200             : 
    4201           0 : NTSTATUS _lsa_LSARUNREGISTERAUDITEVENT(struct pipes_struct *p,
    4202             :                                        struct lsa_LSARUNREGISTERAUDITEVENT *r)
    4203             : {
    4204           0 :         p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
    4205           0 :         return NT_STATUS_NOT_IMPLEMENTED;
    4206             : }
    4207             : 
    4208           0 : NTSTATUS _lsa_lsaRQueryForestTrustInformation(struct pipes_struct *p,
    4209             :                                               struct lsa_lsaRQueryForestTrustInformation *r)
    4210             : {
    4211           0 :         p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
    4212           0 :         return NT_STATUS_NOT_IMPLEMENTED;
    4213             : }
    4214             : 
    4215             : #define DNS_CMP_MATCH 0
    4216             : #define DNS_CMP_FIRST_IS_CHILD 1
    4217             : #define DNS_CMP_SECOND_IS_CHILD 2
    4218             : #define DNS_CMP_NO_MATCH 3
    4219             : 
    4220             : /* this function assumes names are well formed DNS names.
    4221             :  * it doesn't validate them */
    4222           0 : static int dns_cmp(const char *s1, size_t l1,
    4223             :                    const char *s2, size_t l2)
    4224             : {
    4225             :         const char *p1, *p2;
    4226             :         size_t t1, t2;
    4227             :         int cret;
    4228             : 
    4229           0 :         if (l1 == l2) {
    4230           0 :                 if (strcasecmp_m(s1, s2) == 0) {
    4231           0 :                         return DNS_CMP_MATCH;
    4232             :                 }
    4233           0 :                 return DNS_CMP_NO_MATCH;
    4234             :         }
    4235             : 
    4236           0 :         if (l1 > l2) {
    4237           0 :                 p1 = s1;
    4238           0 :                 p2 = s2;
    4239           0 :                 t1 = l1;
    4240           0 :                 t2 = l2;
    4241           0 :                 cret = DNS_CMP_FIRST_IS_CHILD;
    4242             :         } else {
    4243           0 :                 p1 = s2;
    4244           0 :                 p2 = s1;
    4245           0 :                 t1 = l2;
    4246           0 :                 t2 = l1;
    4247           0 :                 cret = DNS_CMP_SECOND_IS_CHILD;
    4248             :         }
    4249             : 
    4250           0 :         if (p1[t1 - t2 - 1] != '.') {
    4251           0 :                 return DNS_CMP_NO_MATCH;
    4252             :         }
    4253             : 
    4254           0 :         if (strcasecmp_m(&p1[t1 - t2], p2) == 0) {
    4255           0 :                 return cret;
    4256             :         }
    4257             : 
    4258           0 :         return DNS_CMP_NO_MATCH;
    4259             : }
    4260             : 
    4261           0 : static NTSTATUS make_ft_info(TALLOC_CTX *mem_ctx,
    4262             :                              struct lsa_ForestTrustInformation *lfti,
    4263             :                              struct ForestTrustInfo *fti)
    4264             : {
    4265             :         struct lsa_ForestTrustRecord *lrec;
    4266             :         struct ForestTrustInfoRecord *rec;
    4267             :         struct lsa_StringLarge *tln;
    4268             :         struct lsa_ForestTrustDomainInfo *info;
    4269             :         uint32_t i;
    4270             : 
    4271           0 :         fti->version = 1;
    4272           0 :         fti->count = lfti->count;
    4273           0 :         fti->records = talloc_array(mem_ctx,
    4274             :                                     struct ForestTrustInfoRecordArmor,
    4275             :                                     fti->count);
    4276           0 :         if (!fti->records) {
    4277           0 :                 return NT_STATUS_NO_MEMORY;
    4278             :         }
    4279           0 :         for (i = 0; i < fti->count; i++) {
    4280           0 :                 lrec = lfti->entries[i];
    4281           0 :                 rec = &fti->records[i].record;
    4282             : 
    4283           0 :                 rec->flags = lrec->flags;
    4284           0 :                 rec->timestamp = lrec->time;
    4285           0 :                 rec->type = (enum ForestTrustInfoRecordType)lrec->type;
    4286             : 
    4287           0 :                 switch (lrec->type) {
    4288           0 :                 case LSA_FOREST_TRUST_TOP_LEVEL_NAME:
    4289             :                 case LSA_FOREST_TRUST_TOP_LEVEL_NAME_EX:
    4290           0 :                         tln = &lrec->forest_trust_data.top_level_name;
    4291           0 :                         rec->data.name.string =
    4292           0 :                                 talloc_strdup(mem_ctx, tln->string);
    4293           0 :                         if (!rec->data.name.string) {
    4294           0 :                                 return NT_STATUS_NO_MEMORY;
    4295             :                         }
    4296           0 :                         rec->data.name.size = strlen(rec->data.name.string);
    4297           0 :                         break;
    4298           0 :                 case LSA_FOREST_TRUST_DOMAIN_INFO:
    4299           0 :                         info = &lrec->forest_trust_data.domain_info;
    4300           0 :                         rec->data.info.sid = *info->domain_sid;
    4301           0 :                         rec->data.info.dns_name.string =
    4302           0 :                                 talloc_strdup(mem_ctx,
    4303             :                                             info->dns_domain_name.string);
    4304           0 :                         if (!rec->data.info.dns_name.string) {
    4305           0 :                                 return NT_STATUS_NO_MEMORY;
    4306             :                         }
    4307           0 :                         rec->data.info.dns_name.size =
    4308           0 :                                 strlen(rec->data.info.dns_name.string);
    4309           0 :                         rec->data.info.netbios_name.string =
    4310           0 :                                 talloc_strdup(mem_ctx,
    4311             :                                             info->netbios_domain_name.string);
    4312           0 :                         if (!rec->data.info.netbios_name.string) {
    4313           0 :                                 return NT_STATUS_NO_MEMORY;
    4314             :                         }
    4315           0 :                         rec->data.info.netbios_name.size =
    4316           0 :                                 strlen(rec->data.info.netbios_name.string);
    4317           0 :                         break;
    4318           0 :                 default:
    4319           0 :                         return NT_STATUS_INVALID_DOMAIN_STATE;
    4320             :                 }
    4321             :         }
    4322             : 
    4323           0 :         return NT_STATUS_OK;
    4324             : }
    4325             : 
    4326             : static NTSTATUS add_collision(struct lsa_ForestTrustCollisionInfo *c_info,
    4327             :                               uint32_t index, uint32_t collision_type,
    4328             :                               uint32_t conflict_type, const char *tdo_name);
    4329             : 
    4330           0 : static NTSTATUS check_ft_info(TALLOC_CTX *mem_ctx,
    4331             :                               const char *tdo_name,
    4332             :                               struct ForestTrustInfo *tdo_fti,
    4333             :                               struct ForestTrustInfo *new_fti,
    4334             :                               struct lsa_ForestTrustCollisionInfo *c_info)
    4335             : {
    4336             :         struct ForestTrustInfoRecord *nrec;
    4337             :         struct ForestTrustInfoRecord *trec;
    4338             :         const char *dns_name;
    4339           0 :         const char *nb_name = NULL;
    4340           0 :         struct dom_sid *sid = NULL;
    4341           0 :         const char *tname = NULL;
    4342           0 :         size_t dns_len = 0;
    4343           0 :         size_t tlen = 0;
    4344             :         uint32_t new_fti_idx;
    4345             :         uint32_t i;
    4346             :         /* use always TDO type, until we understand when Xref can be used */
    4347           0 :         uint32_t collision_type = LSA_FOREST_TRUST_COLLISION_TDO;
    4348             :         bool tln_conflict;
    4349             :         bool sid_conflict;
    4350             :         bool nb_conflict;
    4351             :         bool exclusion;
    4352           0 :         bool ex_rule = false;
    4353             :         int ret;
    4354             : 
    4355           0 :         for (new_fti_idx = 0; new_fti_idx < new_fti->count; new_fti_idx++) {
    4356             : 
    4357           0 :                 nrec = &new_fti->records[new_fti_idx].record;
    4358           0 :                 dns_name = NULL;
    4359           0 :                 tln_conflict = false;
    4360           0 :                 sid_conflict = false;
    4361           0 :                 nb_conflict = false;
    4362           0 :                 exclusion = false;
    4363             : 
    4364           0 :                 switch (nrec->type) {
    4365           0 :                 case LSA_FOREST_TRUST_TOP_LEVEL_NAME_EX:
    4366             :                         /* exclusions do not conflict by definition */
    4367           0 :                         break;
    4368             : 
    4369           0 :                 case FOREST_TRUST_TOP_LEVEL_NAME:
    4370           0 :                         dns_name = nrec->data.name.string;
    4371           0 :                         dns_len = nrec->data.name.size;
    4372           0 :                         break;
    4373             : 
    4374           0 :                 case LSA_FOREST_TRUST_DOMAIN_INFO:
    4375           0 :                         dns_name = nrec->data.info.dns_name.string;
    4376           0 :                         dns_len = nrec->data.info.dns_name.size;
    4377           0 :                         nb_name = nrec->data.info.netbios_name.string;
    4378           0 :                         sid = &nrec->data.info.sid;
    4379           0 :                         break;
    4380             :                 }
    4381             : 
    4382           0 :                 if (!dns_name) continue;
    4383             : 
    4384             :                 /* check if this is already taken and not excluded */
    4385           0 :                 for (i = 0; i < tdo_fti->count; i++) {
    4386           0 :                         trec = &tdo_fti->records[i].record;
    4387             : 
    4388           0 :                         switch (trec->type) {
    4389           0 :                         case FOREST_TRUST_TOP_LEVEL_NAME:
    4390           0 :                                 ex_rule = false;
    4391           0 :                                 tname = trec->data.name.string;
    4392           0 :                                 tlen = trec->data.name.size;
    4393           0 :                                 break;
    4394           0 :                         case FOREST_TRUST_TOP_LEVEL_NAME_EX:
    4395           0 :                                 ex_rule = true;
    4396           0 :                                 tname = trec->data.name.string;
    4397           0 :                                 tlen = trec->data.name.size;
    4398           0 :                                 break;
    4399           0 :                         case FOREST_TRUST_DOMAIN_INFO:
    4400           0 :                                 ex_rule = false;
    4401           0 :                                 tname = trec->data.info.dns_name.string;
    4402           0 :                                 tlen = trec->data.info.dns_name.size;
    4403           0 :                                 break;
    4404           0 :                         default:
    4405           0 :                                 return NT_STATUS_INVALID_PARAMETER;
    4406             :                         }
    4407           0 :                         ret = dns_cmp(dns_name, dns_len, tname, tlen);
    4408           0 :                         switch (ret) {
    4409           0 :                         case DNS_CMP_MATCH:
    4410             :                                 /* if it matches exclusion,
    4411             :                                  * it doesn't conflict */
    4412           0 :                                 if (ex_rule) {
    4413           0 :                                         exclusion = true;
    4414           0 :                                         break;
    4415             :                                 }
    4416             : 
    4417             :                                 FALL_THROUGH;
    4418             :                         case DNS_CMP_FIRST_IS_CHILD:
    4419             :                         case DNS_CMP_SECOND_IS_CHILD:
    4420           0 :                                 tln_conflict = true;
    4421             : 
    4422             :                                 FALL_THROUGH;
    4423           0 :                         default:
    4424           0 :                                 break;
    4425             :                         }
    4426             : 
    4427             :                         /* explicit exclusion, no dns name conflict here */
    4428           0 :                         if (exclusion) {
    4429           0 :                                 tln_conflict = false;
    4430             :                         }
    4431             : 
    4432           0 :                         if (trec->type != FOREST_TRUST_DOMAIN_INFO) {
    4433           0 :                                 continue;
    4434             :                         }
    4435             : 
    4436             :                         /* also test for domain info */
    4437           0 :                         if (!(trec->flags & LSA_SID_DISABLED_ADMIN) &&
    4438           0 :                             dom_sid_compare(&trec->data.info.sid, sid) == 0) {
    4439           0 :                                 sid_conflict = true;
    4440             :                         }
    4441           0 :                         if (!(trec->flags & LSA_NB_DISABLED_ADMIN) &&
    4442           0 :                             strcasecmp_m(trec->data.info.netbios_name.string,
    4443             :                                        nb_name) == 0) {
    4444           0 :                                 nb_conflict = true;
    4445             :                         }
    4446             :                 }
    4447             : 
    4448           0 :                 if (tln_conflict) {
    4449           0 :                         (void)add_collision(c_info, new_fti_idx,
    4450             :                                                   collision_type,
    4451             :                                                   LSA_TLN_DISABLED_CONFLICT,
    4452             :                                                   tdo_name);
    4453             :                 }
    4454           0 :                 if (sid_conflict) {
    4455           0 :                         (void)add_collision(c_info, new_fti_idx,
    4456             :                                                   collision_type,
    4457             :                                                   LSA_SID_DISABLED_CONFLICT,
    4458             :                                                   tdo_name);
    4459             :                 }
    4460           0 :                 if (nb_conflict) {
    4461           0 :                         (void)add_collision(c_info, new_fti_idx,
    4462             :                                                   collision_type,
    4463             :                                                   LSA_NB_DISABLED_CONFLICT,
    4464             :                                                   tdo_name);
    4465             :                 }
    4466             :         }
    4467             : 
    4468           0 :         return NT_STATUS_OK;
    4469             : }
    4470             : 
    4471           0 : static NTSTATUS add_collision(struct lsa_ForestTrustCollisionInfo *c_info,
    4472             :                               uint32_t idx, uint32_t collision_type,
    4473             :                               uint32_t conflict_type, const char *tdo_name)
    4474             : {
    4475             :         struct lsa_ForestTrustCollisionRecord **es;
    4476           0 :         uint32_t i = c_info->count;
    4477             : 
    4478           0 :         es = talloc_realloc(c_info, c_info->entries,
    4479             :                             struct lsa_ForestTrustCollisionRecord *, i + 1);
    4480           0 :         if (!es) {
    4481           0 :                 return NT_STATUS_NO_MEMORY;
    4482             :         }
    4483           0 :         c_info->entries = es;
    4484           0 :         c_info->count = i + 1;
    4485             : 
    4486           0 :         es[i] = talloc(es, struct lsa_ForestTrustCollisionRecord);
    4487           0 :         if (!es[i]) {
    4488           0 :                 return NT_STATUS_NO_MEMORY;
    4489             :         }
    4490             : 
    4491           0 :         es[i]->index = idx;
    4492           0 :         es[i]->type = collision_type;
    4493           0 :         es[i]->flags = conflict_type;
    4494           0 :         es[i]->name.string = talloc_strdup(es[i], tdo_name);
    4495           0 :         if (!es[i]->name.string) {
    4496           0 :                 return NT_STATUS_NO_MEMORY;
    4497             :         }
    4498           0 :         es[i]->name.size = strlen(es[i]->name.string);
    4499             : 
    4500           0 :         return NT_STATUS_OK;
    4501             : }
    4502             : 
    4503           0 : static NTSTATUS get_ft_info(TALLOC_CTX *mem_ctx,
    4504             :                             struct pdb_trusted_domain *td,
    4505             :                             struct ForestTrustInfo *info)
    4506             : {
    4507             :         enum ndr_err_code ndr_err;
    4508             : 
    4509           0 :         if (td->trust_forest_trust_info.length == 0 ||
    4510           0 :             td->trust_forest_trust_info.data == NULL) {
    4511           0 :                 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
    4512             :         }
    4513           0 :         ndr_err = ndr_pull_struct_blob_all(&td->trust_forest_trust_info, mem_ctx,
    4514             :                                            info,
    4515             :                                            (ndr_pull_flags_fn_t)ndr_pull_ForestTrustInfo);
    4516           0 :         if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
    4517           0 :                 return NT_STATUS_INVALID_DOMAIN_STATE;
    4518             :         }
    4519             : 
    4520           0 :         return NT_STATUS_OK;
    4521             : }
    4522             : 
    4523           0 : static NTSTATUS own_ft_info(struct pdb_domain_info *dom_info,
    4524             :                             struct ForestTrustInfo *fti)
    4525             : {
    4526             :         struct ForestTrustDataDomainInfo *info;
    4527             :         struct ForestTrustInfoRecord *rec;
    4528             : 
    4529           0 :         fti->version = 1;
    4530           0 :         fti->count = 2;
    4531           0 :         fti->records = talloc_array(fti,
    4532             :                                     struct ForestTrustInfoRecordArmor, 2);
    4533           0 :         if (!fti->records) {
    4534           0 :                 return NT_STATUS_NO_MEMORY;
    4535             :         }
    4536             : 
    4537             :         /* TLN info */
    4538           0 :         rec = &fti->records[0].record;
    4539             : 
    4540           0 :         rec->flags = 0;
    4541           0 :         rec->timestamp = 0;
    4542           0 :         rec->type = FOREST_TRUST_TOP_LEVEL_NAME;
    4543             : 
    4544           0 :         rec->data.name.string = talloc_strdup(fti, dom_info->dns_forest);
    4545           0 :         if (!rec->data.name.string) {
    4546           0 :                 return NT_STATUS_NO_MEMORY;
    4547             :         }
    4548           0 :         rec->data.name.size = strlen(rec->data.name.string);
    4549             : 
    4550             :         /* DOMAIN info */
    4551           0 :         rec = &fti->records[1].record;
    4552             : 
    4553           0 :         rec->flags = 0;
    4554           0 :         rec->timestamp = 0;
    4555           0 :         rec->type = FOREST_TRUST_DOMAIN_INFO;
    4556             : 
    4557           0 :         info = &rec->data.info;
    4558             : 
    4559           0 :         info->sid = dom_info->sid;
    4560           0 :         info->dns_name.string = talloc_strdup(fti, dom_info->dns_domain);
    4561           0 :         if (!info->dns_name.string) {
    4562           0 :                 return NT_STATUS_NO_MEMORY;
    4563             :         }
    4564           0 :         info->dns_name.size = strlen(info->dns_name.string);
    4565           0 :         info->netbios_name.string = talloc_strdup(fti, dom_info->name);
    4566           0 :         if (!info->netbios_name.string) {
    4567           0 :                 return NT_STATUS_NO_MEMORY;
    4568             :         }
    4569           0 :         info->netbios_name.size = strlen(info->netbios_name.string);
    4570             : 
    4571           0 :         return NT_STATUS_OK;
    4572             : }
    4573             : 
    4574           0 : NTSTATUS _lsa_lsaRSetForestTrustInformation(struct pipes_struct *p,
    4575             :                                             struct lsa_lsaRSetForestTrustInformation *r)
    4576             : {
    4577             :         NTSTATUS status;
    4578             :         int i;
    4579             :         int j;
    4580             :         struct lsa_info *handle;
    4581             :         uint32_t num_domains;
    4582             :         struct pdb_trusted_domain **domains;
    4583             :         struct ForestTrustInfo *nfti;
    4584             :         struct ForestTrustInfo *fti;
    4585             :         struct lsa_ForestTrustCollisionInfo *c_info;
    4586             :         struct pdb_domain_info *dom_info;
    4587             :         enum ndr_err_code ndr_err;
    4588             : 
    4589           0 :         if (!IS_DC) {
    4590           0 :                 return NT_STATUS_NOT_SUPPORTED;
    4591             :         }
    4592             : 
    4593           0 :         handle = find_policy_by_hnd(p,
    4594             :                                     r->in.handle,
    4595             :                                     LSA_HANDLE_TRUST_TYPE,
    4596             :                                     struct lsa_info,
    4597             :                                     &status);
    4598           0 :         if (!NT_STATUS_IS_OK(status)) {
    4599           0 :                 return NT_STATUS_INVALID_HANDLE;
    4600             :         }
    4601             : 
    4602           0 :         if (!(handle->access & LSA_TRUSTED_SET_AUTH)) {
    4603           0 :                 return NT_STATUS_ACCESS_DENIED;
    4604             :         }
    4605             : 
    4606           0 :         status = pdb_enum_trusted_domains(p->mem_ctx, &num_domains, &domains);
    4607           0 :         if (!NT_STATUS_IS_OK(status)) {
    4608           0 :                 return status;
    4609             :         }
    4610           0 :         if (num_domains == 0) {
    4611           0 :                 return NT_STATUS_NO_SUCH_DOMAIN;
    4612             :         }
    4613             : 
    4614           0 :         for (i = 0; i < num_domains; i++) {
    4615           0 :                 if (domains[i]->domain_name == NULL) {
    4616           0 :                         return NT_STATUS_INVALID_DOMAIN_STATE;
    4617             :                 }
    4618           0 :                 if (strcasecmp_m(domains[i]->domain_name,
    4619           0 :                                r->in.trusted_domain_name->string) == 0) {
    4620           0 :                         break;
    4621             :                 }
    4622             :         }
    4623           0 :         if (i >= num_domains) {
    4624           0 :                 return NT_STATUS_NO_SUCH_DOMAIN;
    4625             :         }
    4626             : 
    4627           0 :         if (!(domains[i]->trust_attributes &
    4628             :               LSA_TRUST_ATTRIBUTE_FOREST_TRANSITIVE)) {
    4629           0 :                 return NT_STATUS_INVALID_PARAMETER;
    4630             :         }
    4631             : 
    4632           0 :         if (r->in.highest_record_type >= LSA_FOREST_TRUST_RECORD_TYPE_LAST) {
    4633           0 :                 return NT_STATUS_INVALID_PARAMETER;
    4634             :         }
    4635             : 
    4636             :         /* The following section until COPY_END is a copy from
    4637             :          * source4/rpmc_server/lsa/scesrc_lsa.c */
    4638           0 :         nfti = talloc(p->mem_ctx, struct ForestTrustInfo);
    4639           0 :         if (!nfti) {
    4640           0 :                 return NT_STATUS_NO_MEMORY;
    4641             :         }
    4642             : 
    4643           0 :         status = make_ft_info(nfti, r->in.forest_trust_info, nfti);
    4644           0 :         if (!NT_STATUS_IS_OK(status)) {
    4645           0 :                 return status;
    4646             :         }
    4647             : 
    4648           0 :         c_info = talloc_zero(r->out.collision_info,
    4649             :                              struct lsa_ForestTrustCollisionInfo);
    4650           0 :         if (!c_info) {
    4651           0 :                 return NT_STATUS_NO_MEMORY;
    4652             :         }
    4653             : 
    4654             :         /* first check own info, then other domains */
    4655           0 :         fti = talloc(p->mem_ctx, struct ForestTrustInfo);
    4656           0 :         if (!fti) {
    4657           0 :                 return NT_STATUS_NO_MEMORY;
    4658             :         }
    4659             : 
    4660           0 :         dom_info = pdb_get_domain_info(p->mem_ctx);
    4661             : 
    4662           0 :         status = own_ft_info(dom_info, fti);
    4663           0 :         if (!NT_STATUS_IS_OK(status)) {
    4664           0 :                 return status;
    4665             :         }
    4666             : 
    4667           0 :         status = check_ft_info(c_info, dom_info->dns_domain, fti, nfti, c_info);
    4668           0 :         if (!NT_STATUS_IS_OK(status)) {
    4669           0 :                 return status;
    4670             :         }
    4671             : 
    4672           0 :         for (j = 0; j < num_domains; j++) {
    4673           0 :                 fti = talloc(p->mem_ctx, struct ForestTrustInfo);
    4674           0 :                 if (!fti) {
    4675           0 :                         return NT_STATUS_NO_MEMORY;
    4676             :                 }
    4677             : 
    4678           0 :                 status = get_ft_info(p->mem_ctx, domains[j], fti);
    4679           0 :                 if (!NT_STATUS_IS_OK(status)) {
    4680           0 :                         if (NT_STATUS_EQUAL(status,
    4681             :                             NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
    4682           0 :                                 continue;
    4683             :                         }
    4684           0 :                         return status;
    4685             :                 }
    4686             : 
    4687           0 :                 if (domains[j]->domain_name == NULL) {
    4688           0 :                         return NT_STATUS_INVALID_DOMAIN_STATE;
    4689             :                 }
    4690             : 
    4691           0 :                 status = check_ft_info(c_info, domains[j]->domain_name,
    4692             :                                        fti, nfti, c_info);
    4693           0 :                 if (!NT_STATUS_IS_OK(status)) {
    4694           0 :                         return status;
    4695             :                 }
    4696             :         }
    4697             : 
    4698           0 :         if (c_info->count != 0) {
    4699           0 :                 *r->out.collision_info = c_info;
    4700             :         }
    4701             : 
    4702           0 :         if (r->in.check_only != 0) {
    4703           0 :                 return NT_STATUS_OK;
    4704             :         }
    4705             : 
    4706             :         /* COPY_END */
    4707             : 
    4708           0 :         ndr_err = ndr_push_struct_blob(&domains[i]->trust_forest_trust_info,
    4709             :                                        p->mem_ctx, nfti,
    4710             :                                        (ndr_push_flags_fn_t)ndr_push_ForestTrustInfo);
    4711           0 :         if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
    4712           0 :                 return NT_STATUS_INVALID_PARAMETER;
    4713             :         }
    4714             : 
    4715           0 :         status = pdb_set_trusted_domain(domains[i]->domain_name, domains[i]);
    4716           0 :         if (!NT_STATUS_IS_OK(status)) {
    4717           0 :                 return status;
    4718             :         }
    4719             : 
    4720           0 :         return NT_STATUS_OK;
    4721             : }
    4722             : 
    4723           0 : NTSTATUS _lsa_CREDRRENAME(struct pipes_struct *p,
    4724             :                           struct lsa_CREDRRENAME *r)
    4725             : {
    4726           0 :         p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
    4727           0 :         return NT_STATUS_NOT_IMPLEMENTED;
    4728             : }
    4729             : 
    4730           0 : NTSTATUS _lsa_LSAROPENPOLICYSCE(struct pipes_struct *p,
    4731             :                                 struct lsa_LSAROPENPOLICYSCE *r)
    4732             : {
    4733           0 :         p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
    4734           0 :         return NT_STATUS_NOT_IMPLEMENTED;
    4735             : }
    4736             : 
    4737           0 : NTSTATUS _lsa_LSARADTREGISTERSECURITYEVENTSOURCE(struct pipes_struct *p,
    4738             :                                                  struct lsa_LSARADTREGISTERSECURITYEVENTSOURCE *r)
    4739             : {
    4740           0 :         p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
    4741           0 :         return NT_STATUS_NOT_IMPLEMENTED;
    4742             : }
    4743             : 
    4744           0 : NTSTATUS _lsa_LSARADTUNREGISTERSECURITYEVENTSOURCE(struct pipes_struct *p,
    4745             :                                                    struct lsa_LSARADTUNREGISTERSECURITYEVENTSOURCE *r)
    4746             : {
    4747           0 :         p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
    4748           0 :         return NT_STATUS_NOT_IMPLEMENTED;
    4749             : }
    4750             : 
    4751           0 : NTSTATUS _lsa_LSARADTREPORTSECURITYEVENT(struct pipes_struct *p,
    4752             :                                          struct lsa_LSARADTREPORTSECURITYEVENT *r)
    4753             : {
    4754           0 :         p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
    4755           0 :         return NT_STATUS_NOT_IMPLEMENTED;
    4756             : }
    4757             : 
    4758             : #include "librpc/rpc/dcesrv_core.h"
    4759             : 
    4760             : #define DCESRV_INTERFACE_LSARPC_BIND(context, iface) \
    4761             :        dcesrv_interface_lsarpc_bind(context, iface)
    4762             : 
    4763        7994 : static NTSTATUS dcesrv_interface_lsarpc_bind(
    4764             :                         struct dcesrv_connection_context *context,
    4765             :                         const struct dcesrv_interface *iface)
    4766             : {
    4767        7994 :         return dcesrv_interface_bind_reject_connect(context, iface);
    4768             : }
    4769             : 
    4770             : static NTSTATUS lsarpc__op_init_server(struct dcesrv_context *dce_ctx,
    4771             :                         const struct dcesrv_endpoint_server *ep_server);
    4772             : static const struct dcesrv_interface dcesrv_lsarpc_interface;
    4773             : 
    4774             : #define NCACN_NP_PIPE_NETLOGON "ncacn_np:[\\pipe\\netlogon]"
    4775             : #define NCACN_NP_PIPE_LSASS "ncacn_np:[\\pipe\\lsass]"
    4776             : 
    4777             : #define DCESRV_INTERFACE_LSARPC_NCACN_NP_SECONDARY_ENDPOINT \
    4778             :         NCACN_NP_PIPE_LSASS
    4779             : 
    4780             : #define DCESRV_INTERFACE_LSARPC_INIT_SERVER \
    4781             :        dcesrv_interface_lsarpc_init_server
    4782             : 
    4783         101 : static NTSTATUS dcesrv_interface_lsarpc_init_server(
    4784             :                         struct dcesrv_context *dce_ctx,
    4785             :                         const struct dcesrv_endpoint_server *ep_server)
    4786             : {
    4787         101 :         NTSTATUS ret = dcesrv_interface_register(dce_ctx,
    4788             :                                                  NCACN_NP_PIPE_NETLOGON,
    4789             :                                                  NCACN_NP_PIPE_LSASS,
    4790             :                                                  &dcesrv_lsarpc_interface,
    4791             :                                                  NULL);
    4792         101 :         if (!NT_STATUS_IS_OK(ret)) {
    4793           0 :                 DBG_ERR("Failed to register endpoint "
    4794             :                         "'\\pipe\\netlogon'\n");
    4795           0 :                 return ret;
    4796             :         }
    4797             : 
    4798         101 :         return lsarpc__op_init_server(dce_ctx, ep_server);
    4799             : }
    4800             : 
    4801             : /* include the generated boilerplate */
    4802             : #include "librpc/gen_ndr/ndr_lsa_scompat.c"

Generated by: LCOV version 1.13