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 support-claim-type-attributes 6b5c566e Lines: 956 2416 39.6 %
Date: 2023-11-21 12:31:41 Functions: 48 109 44.0 %

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

Generated by: LCOV version 1.14