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 master 2b515b7d Lines: 981 2583 38.0 %
Date: 2024-02-28 12:06:22 Functions: 49 161 30.4 %

          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          60 : static void init_dom_query_3(struct lsa_DomainInfo *r,
     114             :                              const char *name,
     115             :                              struct dom_sid *sid)
     116             : {
     117          60 :         init_lsa_StringLarge(&r->name, name);
     118          60 :         r->sid = sid;
     119          60 : }
     120             : 
     121             : /***************************************************************************
     122             :  initialize a lsa_DomainInfo structure.
     123             :  ***************************************************************************/
     124             : 
     125         789 : static void init_dom_query_5(struct lsa_DomainInfo *r,
     126             :                              const char *name,
     127             :                              struct dom_sid *sid)
     128             : {
     129         789 :         init_lsa_StringLarge(&r->name, name);
     130         789 :         r->sid = sid;
     131         789 : }
     132             : 
     133             : /***************************************************************************
     134             :  lookup_lsa_rids. Must be called as root for lookup_name to work.
     135             :  ***************************************************************************/
     136             : 
     137         995 : 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         995 :         SMB_ASSERT(num_entries <= MAX_LOOKUP_SIDS);
     148             : 
     149         995 :         mapped_count = 0;
     150         995 :         *pmapped_count = 0;
     151             : 
     152        2208 :         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        1213 :                 if (name[i].string) {
     166        1211 :                         full_name = name[i].string;
     167             :                 } else {
     168           2 :                         full_name = "BUILTIN";
     169             :                 }
     170             : 
     171        1213 :                 DEBUG(5, ("lookup_lsa_rids: looking up name %s\n", full_name));
     172             : 
     173        1213 :                 if (!lookup_name(mem_ctx, full_name, flags, &domain, NULL,
     174             :                                  &sid, &type)) {
     175          16 :                         type = SID_NAME_UNKNOWN;
     176             :                 }
     177             : 
     178        1213 :                 switch (type) {
     179        1197 :                 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        1197 :                         DEBUG(5, ("init_lsa_rids: %s found\n", full_name));
     185             :                         /* Leave these unchanged */
     186        1197 :                         break;
     187          16 :                 default:
     188             :                         /* Don't hand out anything but the list above */
     189          16 :                         DEBUG(5, ("init_lsa_rids: %s not found\n", full_name));
     190          16 :                         type = SID_NAME_UNKNOWN;
     191          16 :                         break;
     192             :                 }
     193             : 
     194        1213 :                 rid = 0;
     195        1213 :                 dom_idx = -1;
     196             : 
     197        1213 :                 if (type != SID_NAME_UNKNOWN) {
     198        1197 :                         if (type == SID_NAME_DOMAIN) {
     199          20 :                                 rid = (uint32_t)-1;
     200             :                         } else {
     201        1177 :                                 sid_split_rid(&sid, &rid);
     202             :                         }
     203        1197 :                         dom_idx = init_lsa_ref_domain_list(mem_ctx, ref, domain, &sid);
     204        1197 :                         mapped_count++;
     205             :                 }
     206             : 
     207        1213 :                 prid[i].sid_type        = type;
     208        1213 :                 prid[i].rid             = rid;
     209        1213 :                 prid[i].sid_index       = dom_idx;
     210             :         }
     211             : 
     212         995 :         *pmapped_count = mapped_count;
     213         995 :         return NT_STATUS_OK;
     214             : }
     215             : 
     216             : /***************************************************************************
     217             :  lookup_lsa_sids. Must be called as root for lookup_name to work.
     218             :  ***************************************************************************/
     219             : 
     220          52 : 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          52 :         SMB_ASSERT(num_entries <= MAX_LOOKUP_SIDS);
     231             : 
     232          52 :         mapped_count = 0;
     233          52 :         *pmapped_count = 0;
     234             : 
     235        2466 :         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        2414 :                 ZERO_STRUCT(sid);
     244             : 
     245             :                 /* Split name into domain and user component */
     246             : 
     247        2414 :                 full_name = name[i].string;
     248        2414 :                 if (full_name == NULL) {
     249           0 :                         return NT_STATUS_NO_MEMORY;
     250             :                 }
     251             : 
     252        2414 :                 DEBUG(5, ("lookup_lsa_sids: looking up name %s\n", full_name));
     253             : 
     254        2414 :                 if (!lookup_name(mem_ctx, full_name, flags, &domain, NULL,
     255             :                                  &sid, &type)) {
     256           0 :                         type = SID_NAME_UNKNOWN;
     257             :                 }
     258             : 
     259        2414 :                 switch (type) {
     260        2414 :                 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        2414 :                         DEBUG(5, ("lookup_lsa_sids: %s found\n", full_name));
     266             :                         /* Leave these unchanged */
     267        2414 :                         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        2414 :                 rid = 0;
     276        2414 :                 dom_idx = -1;
     277             : 
     278        2414 :                 if (type != SID_NAME_UNKNOWN) {
     279           0 :                         struct dom_sid domain_sid;
     280        2414 :                         sid_copy(&domain_sid, &sid);
     281        2414 :                         sid_split_rid(&domain_sid, &rid);
     282        2414 :                         dom_idx = init_lsa_ref_domain_list(mem_ctx, ref, domain, &domain_sid);
     283        2414 :                         mapped_count++;
     284             :                 }
     285             : 
     286             :                 /* Initialize the lsa_TranslatedSid3 return. */
     287        2414 :                 trans_sids[i].sid_type = type;
     288        2414 :                 trans_sids[i].sid = dom_sid_dup(mem_ctx, &sid);
     289        2414 :                 trans_sids[i].sid_index = dom_idx;
     290             :         }
     291             : 
     292          52 :         *pmapped_count = mapped_count;
     293          52 :         return NT_STATUS_OK;
     294             : }
     295             : 
     296        6763 : 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        6763 :         size_t i = 0;
     303             : 
     304        6763 :         struct security_acl *psa = NULL;
     305             : 
     306             :         /* READ|EXECUTE access for Everyone */
     307             : 
     308        6763 :         init_sec_ace(&ace[i++], &global_sid_World, SEC_ACE_TYPE_ACCESS_ALLOWED,
     309        6763 :                         map->generic_execute | map->generic_read, 0);
     310             : 
     311             :         /* Add Full Access 'BUILTIN\Administrators' and 'BUILTIN\Account Operators */
     312             : 
     313        6763 :         init_sec_ace(&ace[i++], &global_sid_Builtin_Administrators,
     314        6763 :                         SEC_ACE_TYPE_ACCESS_ALLOWED, map->generic_all, 0);
     315        6763 :         init_sec_ace(&ace[i++], &global_sid_Builtin_Account_Operators,
     316        6763 :                         SEC_ACE_TYPE_ACCESS_ALLOWED, map->generic_all, 0);
     317             : 
     318             :         /* Add Full Access for Domain Admins */
     319        6763 :         sid_compose(&adm_sid, get_global_sam_sid(), DOMAIN_RID_ADMINS);
     320        6763 :         init_sec_ace(&ace[i++], &adm_sid, SEC_ACE_TYPE_ACCESS_ALLOWED,
     321        6763 :                         map->generic_all, 0);
     322             : 
     323             :         /* If we have a sid, give it some special access */
     324             : 
     325        6763 :         if (sid) {
     326          18 :                 init_sec_ace(&ace[i++], sid, SEC_ACE_TYPE_ACCESS_ALLOWED,
     327             :                         sid_access, 0);
     328             :         }
     329             : 
     330        6763 :         if((psa = make_sec_acl(mem_ctx, NT4_ACL_REVISION, i, ace)) == NULL)
     331           0 :                 return NT_STATUS_NO_MEMORY;
     332             : 
     333        6763 :         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        6763 :         return NT_STATUS_OK;
     339             : }
     340             : 
     341             : /***************************************************************************
     342             :  ***************************************************************************/
     343             : 
     344        6705 : 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        6705 :         ZERO_STRUCTP(handle);
     356             : 
     357        6705 :         info = talloc_zero(mem_ctx, struct lsa_info);
     358        6705 :         if (!info) {
     359           0 :                 return NT_STATUS_NO_MEMORY;
     360             :         }
     361             : 
     362        6705 :         info->type = type;
     363        6705 :         info->access = acc_granted;
     364             : 
     365        6705 :         if (sid) {
     366        6073 :                 sid_copy(&info->sid, sid);
     367             :         }
     368             : 
     369        6705 :         info->name = talloc_strdup(info, name);
     370             : 
     371        6705 :         if (sd != NULL) {
     372        6705 :                 info->sd = security_descriptor_copy(info, sd);
     373        6705 :                 if (info->sd == NULL) {
     374           0 :                         talloc_free(info);
     375           0 :                         return NT_STATUS_NO_MEMORY;
     376             :                 }
     377             :         }
     378             : 
     379        6705 :         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        6705 :         return NT_STATUS_OK;
     386             : }
     387             : 
     388             : /***************************************************************************
     389             :  _lsa_OpenPolicy2
     390             :  ***************************************************************************/
     391             : 
     392        5981 : NTSTATUS _lsa_OpenPolicy2(struct pipes_struct *p,
     393             :                           struct lsa_OpenPolicy2 *r)
     394             : {
     395        5981 :         struct dcesrv_call_state *dce_call = p->dce_call;
     396           0 :         struct auth_session_info *session_info =
     397        5981 :                 dcesrv_call_session_info(dce_call);
     398        5981 :         struct security_descriptor *psd = NULL;
     399           0 :         size_t sd_size;
     400        5981 :         uint32_t des_access = r->in.access_mask;
     401           0 :         uint32_t acc_granted;
     402           0 :         NTSTATUS status;
     403             : 
     404        5981 :         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        5977 :         map_max_allowed_access(session_info->security_token,
     411        5977 :                                session_info->unix_token,
     412             :                                &des_access);
     413             : 
     414             :         /* map the generic bits to the lsa policy ones */
     415        5977 :         se_map_generic(&des_access, &lsa_policy_mapping);
     416             : 
     417             :         /* get the generic lsa policy SD until we store it */
     418        5977 :         status = make_lsa_object_sd(p->mem_ctx, &psd, &sd_size, &lsa_policy_mapping,
     419             :                         NULL, 0);
     420        5977 :         if (!NT_STATUS_IS_OK(status)) {
     421           0 :                 return status;
     422             :         }
     423             : 
     424        5977 :         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        5977 :         if (!NT_STATUS_IS_OK(status)) {
     428           0 :                 return status;
     429             :         }
     430             : 
     431        5977 :         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        5977 :         if (!NT_STATUS_IS_OK(status)) {
     439           0 :                 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
     440             :         }
     441             : 
     442        5977 :         return NT_STATUS_OK;
     443             : }
     444             : 
     445             : /***************************************************************************
     446             :  _lsa_OpenPolicy
     447             :  ***************************************************************************/
     448             : 
     449        5101 : 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        5101 :         o.in.system_name        = NULL; /* should be ignored */
     457        5101 :         o.in.attr               = r->in.attr;
     458        5101 :         o.in.access_mask        = r->in.access_mask;
     459             : 
     460        5101 :         o.out.handle            = r->out.handle;
     461             : 
     462        5101 :         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         875 : NTSTATUS _lsa_QueryInfoPolicy(struct pipes_struct *p,
     550             :                               struct lsa_QueryInfoPolicy *r)
     551             : {
     552         875 :         NTSTATUS status = NT_STATUS_OK;
     553           0 :         struct lsa_info *handle;
     554           0 :         struct dom_sid domain_sid;
     555           0 :         const char *name;
     556         875 :         struct dom_sid *sid = NULL;
     557         875 :         union lsa_PolicyInformation *info = NULL;
     558         875 :         uint32_t acc_required = 0;
     559             : 
     560         875 :         handle = find_policy_by_hnd(p,
     561             :                                     r->in.handle,
     562             :                                     LSA_HANDLE_POLICY_TYPE,
     563             :                                     struct lsa_info,
     564           0 :                                     &status);
     565         875 :         if (!NT_STATUS_IS_OK(status)) {
     566           0 :                 return NT_STATUS_INVALID_HANDLE;
     567             :         }
     568             : 
     569         875 :         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          60 :         case LSA_POLICY_INFO_DOMAIN:
     575          60 :                 acc_required = LSA_POLICY_VIEW_LOCAL_INFORMATION;
     576          60 :                 break;
     577           2 :         case LSA_POLICY_INFO_PD:
     578           2 :                 acc_required = LSA_POLICY_GET_PRIVATE_INFORMATION;
     579           2 :                 break;
     580         789 :         case LSA_POLICY_INFO_ACCOUNT_DOMAIN:
     581         789 :                 acc_required = LSA_POLICY_VIEW_LOCAL_INFORMATION;
     582         789 :                 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         871 :         if (!(handle->access & acc_required)) {
     607             :                 /* return NT_STATUS_ACCESS_DENIED; */
     608           0 :         }
     609             : 
     610         871 :         info = talloc_zero(p->mem_ctx, union lsa_PolicyInformation);
     611         871 :         if (!info) {
     612           0 :                 return NT_STATUS_NO_MEMORY;
     613             :         }
     614             : 
     615         871 :         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          60 :         case LSA_POLICY_INFO_DOMAIN:
     681             :                 /* check if the user has enough rights */
     682          60 :                 if (!(handle->access & LSA_POLICY_VIEW_LOCAL_INFORMATION))
     683           0 :                         return NT_STATUS_ACCESS_DENIED;
     684             : 
     685             :                 /* Request PolicyPrimaryDomainInformation. */
     686          60 :                 switch (lp_server_role()) {
     687          60 :                         case ROLE_DOMAIN_PDC:
     688             :                         case ROLE_DOMAIN_BDC:
     689             :                         case ROLE_IPA_DC:
     690          60 :                                 name = get_global_sam_name();
     691          60 :                                 sid = dom_sid_dup(p->mem_ctx, get_global_sam_sid());
     692          60 :                                 if (!sid) {
     693           0 :                                         return NT_STATUS_NO_MEMORY;
     694             :                                 }
     695          60 :                                 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          60 :                 init_dom_query_3(&info->domain, name, sid);
     716          60 :                 break;
     717         789 :         case LSA_POLICY_INFO_ACCOUNT_DOMAIN:
     718             :                 /* check if the user has enough rights */
     719         789 :                 if (!(handle->access & LSA_POLICY_VIEW_LOCAL_INFORMATION))
     720           0 :                         return NT_STATUS_ACCESS_DENIED;
     721             : 
     722             :                 /* Request PolicyAccountDomainInformation. */
     723         789 :                 name = get_global_sam_name();
     724         789 :                 sid = get_global_sam_sid();
     725             : 
     726         789 :                 init_dom_query_5(&info->account_domain, name, sid);
     727         789 :                 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         869 :         *r->out.info = info;
     785             : 
     786         869 :         return status;
     787             : }
     788             : 
     789             : /***************************************************************************
     790             :  _lsa_QueryInfoPolicy2
     791             :  ***************************************************************************/
     792             : 
     793         190 : NTSTATUS _lsa_QueryInfoPolicy2(struct pipes_struct *p,
     794             :                                struct lsa_QueryInfoPolicy2 *r2)
     795             : {
     796           0 :         struct lsa_QueryInfoPolicy r;
     797             : 
     798         190 :         if ((pdb_capabilities() & PDB_CAP_ADS) == 0) {
     799         188 :                 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
     800         188 :                 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        6012 : 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        6012 :         const struct dom_sid **sids = NULL;
     827        6012 :         struct lsa_RefDomainList *ref = NULL;
     828        6012 :         uint32_t mapped_count = 0;
     829        6012 :         struct lsa_dom_info *dom_infos = NULL;
     830        6012 :         struct lsa_name_info *name_infos = NULL;
     831        6012 :         struct lsa_TranslatedName2 *names = NULL;
     832             : 
     833        6012 :         *pp_mapped_count = 0;
     834        6012 :         *pp_names = NULL;
     835        6012 :         *pp_ref = NULL;
     836             : 
     837        6012 :         if (num_sids == 0) {
     838           0 :                 return NT_STATUS_OK;
     839             :         }
     840             : 
     841        6012 :         sids = talloc_array(p->mem_ctx, const struct dom_sid *, num_sids);
     842        6012 :         ref = talloc_zero(p->mem_ctx, struct lsa_RefDomainList);
     843             : 
     844        6012 :         if (sids == NULL || ref == NULL) {
     845           0 :                 return NT_STATUS_NO_MEMORY;
     846             :         }
     847             : 
     848       14628 :         for (i=0; i<num_sids; i++) {
     849        8616 :                 sids[i] = sid[i].sid;
     850             :         }
     851             : 
     852        6012 :         status = lookup_sids(p->mem_ctx, num_sids, sids, level,
     853             :                                   &dom_infos, &name_infos);
     854             : 
     855        6012 :         if (!NT_STATUS_IS_OK(status)) {
     856           0 :                 return status;
     857             :         }
     858             : 
     859        6012 :         names = talloc_array(p->mem_ctx, struct lsa_TranslatedName2, num_sids);
     860        6012 :         if (names == NULL) {
     861           0 :                 return NT_STATUS_NO_MEMORY;
     862             :         }
     863             : 
     864       12028 :         for (i=0; i<LSA_REF_DOMAIN_LIST_MULTIPLIER; i++) {
     865             : 
     866       12028 :                 if (!dom_infos[i].valid) {
     867        6012 :                         break;
     868             :                 }
     869             : 
     870        6016 :                 if (init_lsa_ref_domain_list(mem_ctx, ref,
     871        6016 :                                              dom_infos[i].name,
     872        6016 :                                              &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       14628 :         for (i=0; i<num_sids; i++) {
     880        8616 :                 struct lsa_name_info *name = &name_infos[i];
     881             : 
     882        8616 :                 if (name->type == SID_NAME_UNKNOWN) {
     883         164 :                         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         164 :                         name->name = dom_sid_string(p->mem_ctx, sids[i]);
     891         164 :                         if (name->name == NULL) {
     892           0 :                                 return NT_STATUS_NO_MEMORY;
     893             :                         }
     894             :                 } else {
     895        8452 :                         mapped_count += 1;
     896             :                 }
     897             : 
     898        8616 :                 names[i].sid_type       = name->type;
     899        8616 :                 names[i].name.string    = name->name;
     900        8616 :                 names[i].sid_index      = name->dom_idx;
     901        8616 :                 names[i].unknown        = 0;
     902             :         }
     903             : 
     904        6012 :         status = NT_STATUS_NONE_MAPPED;
     905        6012 :         if (mapped_count > 0) {
     906        5858 :                 status = (mapped_count < num_sids) ?
     907           0 :                         STATUS_SOME_UNMAPPED : NT_STATUS_OK;
     908             :         }
     909             : 
     910        6012 :         DEBUG(10, ("num_sids %d, mapped_count %d, status %s\n",
     911             :                    num_sids, mapped_count, nt_errstr(status)));
     912             : 
     913        6012 :         *pp_mapped_count = mapped_count;
     914        6012 :         *pp_names = names;
     915        6012 :         *pp_ref = ref;
     916             : 
     917        6012 :         return status;
     918             : }
     919             : 
     920             : /***************************************************************************
     921             :  _lsa_LookupSids
     922             :  ***************************************************************************/
     923             : 
     924        5986 : NTSTATUS _lsa_LookupSids(struct pipes_struct *p,
     925             :                          struct lsa_LookupSids *r)
     926             : {
     927           0 :         NTSTATUS status;
     928           0 :         struct lsa_info *handle;
     929        5986 :         int num_sids = r->in.sids->num_sids;
     930        5986 :         uint32_t mapped_count = 0;
     931        5986 :         struct lsa_RefDomainList *domains = NULL;
     932        5986 :         struct lsa_TranslatedName *names_out = NULL;
     933        5986 :         struct lsa_TranslatedName2 *names = NULL;
     934           0 :         int i;
     935             : 
     936        5986 :         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        5986 :         if ((r->in.level < 1) || (r->in.level > 6)) {
     942           0 :                 return NT_STATUS_INVALID_PARAMETER;
     943             :         }
     944             : 
     945        5986 :         handle = find_policy_by_hnd(p,
     946             :                                     r->in.handle,
     947             :                                     LSA_HANDLE_POLICY_TYPE,
     948             :                                     struct lsa_info,
     949           0 :                                     &status);
     950        5986 :         if (!NT_STATUS_IS_OK(status)) {
     951           0 :                 return NT_STATUS_INVALID_HANDLE;
     952             :         }
     953             : 
     954             :         /* check if the user has enough rights */
     955        5986 :         if (!(handle->access & LSA_POLICY_LOOKUP_NAMES)) {
     956           0 :                 return NT_STATUS_ACCESS_DENIED;
     957             :         }
     958             : 
     959        5986 :         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        5986 :         status = _lsa_lookup_sids_internal(p,
     966             :                                            p->mem_ctx,
     967        5986 :                                            r->in.level,
     968             :                                            num_sids,
     969        5986 :                                            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        5986 :         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        5986 :         names_out = talloc_array(p->mem_ctx, struct lsa_TranslatedName,
     988             :                                  num_sids);
     989        5986 :         if (!names_out) {
     990           0 :                 return NT_STATUS_NO_MEMORY;
     991             :         }
     992             : 
     993       12190 :         for (i=0; i<num_sids; i++) {
     994        6204 :                 names_out[i].sid_type = names[i].sid_type;
     995        6204 :                 names_out[i].name = names[i].name;
     996        6204 :                 names_out[i].sid_index = names[i].sid_index;
     997             :         }
     998             : 
     999        5986 :         *r->out.domains = domains;
    1000        5986 :         r->out.names->count = num_sids;
    1001        5986 :         r->out.names->names = names_out;
    1002        5986 :         *r->out.count = mapped_count;
    1003             : 
    1004        5986 :         return status;
    1005             : }
    1006             : 
    1007          26 : static NTSTATUS _lsa_LookupSids_common(struct pipes_struct *p,
    1008             :                                 struct lsa_LookupSids2 *r)
    1009             : {
    1010          26 :         struct dcesrv_call_state *dce_call = p->dce_call;
    1011           0 :         NTSTATUS status;
    1012           0 :         struct lsa_info *handle;
    1013          26 :         int num_sids = r->in.sids->num_sids;
    1014          26 :         uint32_t mapped_count = 0;
    1015          26 :         struct lsa_RefDomainList *domains = NULL;
    1016          26 :         struct lsa_TranslatedName2 *names = NULL;
    1017          26 :         bool check_policy = true;
    1018             : 
    1019          26 :         switch (dce_call->pkt.u.request.opnum) {
    1020          24 :                 case NDR_LSA_LOOKUPSIDS3:
    1021          24 :                         check_policy = false;
    1022          24 :                         break;
    1023           2 :                 case NDR_LSA_LOOKUPSIDS2:
    1024             :                 default:
    1025           2 :                         check_policy = true;
    1026             :         }
    1027             : 
    1028          26 :         if ((r->in.level < 1) || (r->in.level > 6)) {
    1029           0 :                 return NT_STATUS_INVALID_PARAMETER;
    1030             :         }
    1031             : 
    1032          26 :         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          26 :         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          26 :         status = _lsa_lookup_sids_internal(p,
    1055             :                                            p->mem_ctx,
    1056          26 :                                            r->in.level,
    1057             :                                            num_sids,
    1058          26 :                                            r->in.sids->sids,
    1059             :                                            &domains,
    1060             :                                            &names,
    1061             :                                            &mapped_count);
    1062             : 
    1063          26 :         *r->out.domains = domains;
    1064          26 :         r->out.names->count = num_sids;
    1065          26 :         r->out.names->names = names;
    1066          26 :         *r->out.count = mapped_count;
    1067             : 
    1068          26 :         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          28 : NTSTATUS _lsa_LookupSids3(struct pipes_struct *p,
    1091             :                           struct lsa_LookupSids3 *r)
    1092             : {
    1093          28 :         struct dcesrv_call_state *dce_call = p->dce_call;
    1094          28 :         enum dcerpc_AuthType auth_type = DCERPC_AUTH_TYPE_NONE;
    1095          28 :         enum dcerpc_AuthLevel auth_level = DCERPC_AUTH_LEVEL_NONE;
    1096           0 :         struct lsa_LookupSids2 q;
    1097             : 
    1098          28 :         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          26 :         dcesrv_call_auth_info(dce_call, &auth_type, &auth_level);
    1104             : 
    1105             :         /* No policy handle on this call. Restrict to crypto connections. */
    1106          26 :         if (auth_type != DCERPC_AUTH_TYPE_SCHANNEL ||
    1107          24 :             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          24 :         q.in.handle             = NULL;
    1116          24 :         q.in.sids               = r->in.sids;
    1117          24 :         q.in.level              = r->in.level;
    1118          24 :         q.in.lookup_options     = r->in.lookup_options;
    1119          24 :         q.in.client_revision    = r->in.client_revision;
    1120          24 :         q.in.names              = r->in.names;
    1121          24 :         q.in.count              = r->in.count;
    1122             : 
    1123          24 :         q.out.domains           = r->out.domains;
    1124          24 :         q.out.names             = r->out.names;
    1125          24 :         q.out.count             = r->out.count;
    1126             : 
    1127          24 :         return _lsa_LookupSids_common(p, &q);
    1128             : }
    1129             : 
    1130             : /***************************************************************************
    1131             :  ***************************************************************************/
    1132             : 
    1133        1047 : static int lsa_lookup_level_to_flags(enum lsa_LookupNamesLevel level)
    1134             : {
    1135           0 :         int flags;
    1136             : 
    1137        1047 :         switch (level) {
    1138        1031 :                 case LSA_LOOKUP_NAMES_ALL: /* 1 */
    1139        1031 :                         flags = LOOKUP_NAME_ALL;
    1140        1031 :                         break;
    1141          16 :                 case LSA_LOOKUP_NAMES_DOMAINS_ONLY: /* 2 */
    1142          16 :                         flags = LOOKUP_NAME_DOMAIN|LOOKUP_NAME_REMOTE|LOOKUP_NAME_ISOLATED;
    1143          16 :                         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        1047 :         return flags;
    1157             : }
    1158             : 
    1159             : /***************************************************************************
    1160             :  _lsa_LookupNames
    1161             :  ***************************************************************************/
    1162             : 
    1163         995 : NTSTATUS _lsa_LookupNames(struct pipes_struct *p,
    1164             :                           struct lsa_LookupNames *r)
    1165             : {
    1166         995 :         NTSTATUS status = NT_STATUS_NONE_MAPPED;
    1167           0 :         struct lsa_info *handle;
    1168         995 :         struct lsa_String *names = r->in.names;
    1169         995 :         uint32_t num_entries = r->in.num_names;
    1170         995 :         struct lsa_RefDomainList *domains = NULL;
    1171         995 :         struct lsa_TranslatedSid *rids = NULL;
    1172         995 :         uint32_t mapped_count = 0;
    1173         995 :         int flags = 0;
    1174             : 
    1175         995 :         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         995 :         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         995 :         flags = lsa_lookup_level_to_flags(r->in.level);
    1187             : 
    1188         995 :         domains = talloc_zero(p->mem_ctx, struct lsa_RefDomainList);
    1189         995 :         if (!domains) {
    1190           0 :                 return NT_STATUS_NO_MEMORY;
    1191             :         }
    1192             : 
    1193         995 :         if (num_entries) {
    1194         995 :                 rids = talloc_zero_array(p->mem_ctx, struct lsa_TranslatedSid,
    1195             :                                          num_entries);
    1196         995 :                 if (!rids) {
    1197           0 :                         return NT_STATUS_NO_MEMORY;
    1198             :                 }
    1199             :         } else {
    1200           0 :                 rids = NULL;
    1201             :         }
    1202             : 
    1203         995 :         handle = find_policy_by_hnd(p,
    1204             :                                     r->in.handle,
    1205             :                                     LSA_HANDLE_POLICY_TYPE,
    1206             :                                     struct lsa_info,
    1207           0 :                                     &status);
    1208         995 :         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         995 :         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         995 :         become_root(); /* lookup_name can require root privs */
    1221         995 :         status = lookup_lsa_rids(p->mem_ctx, domains, rids, num_entries,
    1222             :                                  names, flags, &mapped_count);
    1223         995 :         unbecome_root();
    1224             : 
    1225         995 : done:
    1226             : 
    1227         995 :         if (NT_STATUS_IS_OK(status) && (num_entries != 0) ) {
    1228         995 :                 if (mapped_count == 0) {
    1229          16 :                         status = NT_STATUS_NONE_MAPPED;
    1230         979 :                 } else if (mapped_count != num_entries) {
    1231           0 :                         status = STATUS_SOME_UNMAPPED;
    1232             :                 }
    1233             :         }
    1234             : 
    1235         995 :         *r->out.count = mapped_count;
    1236         995 :         *r->out.domains = domains;
    1237         995 :         r->out.sids->sids = rids;
    1238         995 :         r->out.sids->count = num_entries;
    1239             : 
    1240         995 :         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          52 : static NTSTATUS _lsa_LookupNames_common(struct pipes_struct *p,
    1301             :                                         struct lsa_LookupNames3 *r)
    1302             : {
    1303          52 :         struct dcesrv_call_state *dce_call = p->dce_call;
    1304           0 :         NTSTATUS status;
    1305           0 :         struct lsa_info *handle;
    1306          52 :         struct lsa_String *names = r->in.names;
    1307          52 :         uint32_t num_entries = r->in.num_names;
    1308          52 :         struct lsa_RefDomainList *domains = NULL;
    1309          52 :         struct lsa_TranslatedSid3 *trans_sids = NULL;
    1310          52 :         uint32_t mapped_count = 0;
    1311          52 :         int flags = 0;
    1312          52 :         bool check_policy = true;
    1313             : 
    1314          52 :         switch (dce_call->pkt.u.request.opnum) {
    1315          48 :                 case NDR_LSA_LOOKUPNAMES4:
    1316          48 :                         check_policy = false;
    1317          48 :                         break;
    1318           4 :                 case NDR_LSA_LOOKUPNAMES3:
    1319             :                 default:
    1320           4 :                         check_policy = true;
    1321             :         }
    1322             : 
    1323          52 :         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          52 :         flags = lsa_lookup_level_to_flags(r->in.level);
    1329             : 
    1330          52 :         domains = talloc_zero(p->mem_ctx, struct lsa_RefDomainList);
    1331          52 :         if (!domains) {
    1332           0 :                 return NT_STATUS_NO_MEMORY;
    1333             :         }
    1334             : 
    1335          52 :         if (num_entries) {
    1336          28 :                 trans_sids = talloc_zero_array(p->mem_ctx, struct lsa_TranslatedSid3,
    1337             :                                                num_entries);
    1338          28 :                 if (!trans_sids) {
    1339           0 :                         return NT_STATUS_NO_MEMORY;
    1340             :                 }
    1341             :         } else {
    1342          24 :                 trans_sids = NULL;
    1343             :         }
    1344             : 
    1345          52 :         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          52 :         become_root(); /* lookup_name can require root privs */
    1366          52 :         status = lookup_lsa_sids(p->mem_ctx, domains, trans_sids, num_entries,
    1367             :                                  names, flags, &mapped_count);
    1368          52 :         unbecome_root();
    1369             : 
    1370          52 : done:
    1371             : 
    1372          52 :         if (NT_STATUS_IS_OK(status)) {
    1373          52 :                 if (mapped_count == 0) {
    1374          24 :                         status = NT_STATUS_NONE_MAPPED;
    1375          28 :                 } else if (mapped_count != num_entries) {
    1376           0 :                         status = STATUS_SOME_UNMAPPED;
    1377             :                 }
    1378             :         }
    1379             : 
    1380          52 :         *r->out.count = mapped_count;
    1381          52 :         *r->out.domains = domains;
    1382          52 :         r->out.sids->sids = trans_sids;
    1383          52 :         r->out.sids->count = num_entries;
    1384             : 
    1385          52 :         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          52 : NTSTATUS _lsa_LookupNames4(struct pipes_struct *p,
    1408             :                            struct lsa_LookupNames4 *r)
    1409             : {
    1410          52 :         struct dcesrv_call_state *dce_call = p->dce_call;
    1411          52 :         enum dcerpc_AuthType auth_type = DCERPC_AUTH_TYPE_NONE;
    1412          52 :         enum dcerpc_AuthLevel auth_level = DCERPC_AUTH_LEVEL_NONE;
    1413           0 :         struct lsa_LookupNames3 q;
    1414             : 
    1415          52 :         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          50 :         dcesrv_call_auth_info(dce_call, &auth_type, &auth_level);
    1421             : 
    1422             :         /* No policy handle on this call. Restrict to crypto connections. */
    1423          50 :         if (auth_type != DCERPC_AUTH_TYPE_SCHANNEL ||
    1424          48 :             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          48 :         q.in.handle             = NULL;
    1433          48 :         q.in.num_names          = r->in.num_names;
    1434          48 :         q.in.names              = r->in.names;
    1435          48 :         q.in.level              = r->in.level;
    1436          48 :         q.in.lookup_options     = r->in.lookup_options;
    1437          48 :         q.in.client_revision    = r->in.client_revision;
    1438          48 :         q.in.sids               = r->in.sids;
    1439          48 :         q.in.count              = r->in.count;
    1440             : 
    1441          48 :         q.out.domains           = r->out.domains;
    1442          48 :         q.out.sids              = r->out.sids;
    1443          48 :         q.out.count             = r->out.count;
    1444             : 
    1445          48 :         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        1009 : NTSTATUS _lsa_Close(struct pipes_struct *p, struct lsa_Close *r)
    1453             : {
    1454           0 :         NTSTATUS status;
    1455             : 
    1456        1009 :         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        1009 :         (void)find_policy_by_hnd(p,
    1462             :                                  r->in.handle,
    1463             :                                  DCESRV_HANDLE_ANY,
    1464             :                                  struct lsa_info,
    1465           0 :                                  &status);
    1466        1009 :         if (!NT_STATUS_IS_OK(status)) {
    1467          26 :                 return NT_STATUS_INVALID_HANDLE;
    1468             :         }
    1469             : 
    1470         983 :         close_policy_hnd(p, r->in.handle);
    1471         983 :         ZERO_STRUCTP(r->out.handle);
    1472         983 :         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 :         p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
    1985           0 :         return NT_STATUS_NOT_IMPLEMENTED;
    1986             : }
    1987             : 
    1988             : /***************************************************************************
    1989             :  _lsa_CreateTrustedDomain
    1990             :  ***************************************************************************/
    1991             : 
    1992           0 : NTSTATUS _lsa_CreateTrustedDomain(struct pipes_struct *p,
    1993             :                                   struct lsa_CreateTrustedDomain *r)
    1994             : {
    1995           0 :         p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
    1996           0 :         return NT_STATUS_NOT_IMPLEMENTED;
    1997             : }
    1998             : 
    1999             : /***************************************************************************
    2000             :  _lsa_DeleteTrustedDomain
    2001             :  ***************************************************************************/
    2002             : 
    2003           0 : NTSTATUS _lsa_DeleteTrustedDomain(struct pipes_struct *p,
    2004             :                                   struct lsa_DeleteTrustedDomain *r)
    2005             : {
    2006           0 :         NTSTATUS status;
    2007           0 :         struct lsa_info *handle;
    2008           0 :         struct pdb_trusted_domain *td;
    2009             : 
    2010             :         /* find the connection policy handle. */
    2011           0 :         handle = find_policy_by_hnd(p,
    2012             :                                     r->in.handle,
    2013             :                                     LSA_HANDLE_POLICY_TYPE,
    2014             :                                     struct lsa_info,
    2015           0 :                                     &status);
    2016           0 :         if (!NT_STATUS_IS_OK(status)) {
    2017           0 :                 return NT_STATUS_INVALID_HANDLE;
    2018             :         }
    2019             : 
    2020           0 :         if (!(handle->access & LSA_POLICY_TRUST_ADMIN)) {
    2021           0 :                 return NT_STATUS_ACCESS_DENIED;
    2022             :         }
    2023             : 
    2024           0 :         status = pdb_get_trusted_domain_by_sid(p->mem_ctx, r->in.dom_sid, &td);
    2025           0 :         if (!NT_STATUS_IS_OK(status)) {
    2026           0 :                 return status;
    2027             :         }
    2028             : 
    2029           0 :         if (td->netbios_name == NULL || *td->netbios_name == '\0') {
    2030           0 :                 struct dom_sid_buf buf;
    2031           0 :                 DEBUG(10, ("Missing netbios name for trusted domain %s.\n",
    2032             :                            dom_sid_str_buf(r->in.dom_sid, &buf)));
    2033           0 :                 return NT_STATUS_UNSUCCESSFUL;
    2034             :         }
    2035             : 
    2036           0 :         status = pdb_del_trusted_domain(td->netbios_name);
    2037           0 :         if (!NT_STATUS_IS_OK(status)) {
    2038           0 :                 return status;
    2039             :         }
    2040             : 
    2041           0 :         return NT_STATUS_OK;
    2042             : }
    2043             : 
    2044             : /***************************************************************************
    2045             :  _lsa_CloseTrustedDomainEx
    2046             :  ***************************************************************************/
    2047             : 
    2048           0 : NTSTATUS _lsa_CloseTrustedDomainEx(struct pipes_struct *p,
    2049             :                                    struct lsa_CloseTrustedDomainEx *r)
    2050             : {
    2051           0 :         return NT_STATUS_NOT_IMPLEMENTED;
    2052             : }
    2053             : 
    2054             : /***************************************************************************
    2055             :  _lsa_QueryTrustedDomainInfo
    2056             :  ***************************************************************************/
    2057             : 
    2058           0 : static NTSTATUS pdb_trusted_domain_2_info_ex(TALLOC_CTX *mem_ctx,
    2059             :                                       struct pdb_trusted_domain *td,
    2060             :                                       struct lsa_TrustDomainInfoInfoEx *info_ex)
    2061             : {
    2062           0 :         if (td->domain_name == NULL ||
    2063           0 :             td->netbios_name == NULL ||
    2064           0 :             is_null_sid(&td->security_identifier)) {
    2065           0 :                 return NT_STATUS_INVALID_PARAMETER;
    2066             :         }
    2067             : 
    2068           0 :         info_ex->domain_name.string = talloc_strdup(mem_ctx, td->domain_name);
    2069           0 :         info_ex->netbios_name.string = talloc_strdup(mem_ctx, td->netbios_name);
    2070           0 :         info_ex->sid = dom_sid_dup(mem_ctx, &td->security_identifier);
    2071           0 :         if (info_ex->domain_name.string == NULL ||
    2072           0 :             info_ex->netbios_name.string == NULL ||
    2073           0 :             info_ex->sid == NULL) {
    2074           0 :                 return NT_STATUS_NO_MEMORY;
    2075             :         }
    2076             : 
    2077           0 :         info_ex->trust_direction = td->trust_direction;
    2078           0 :         info_ex->trust_type = td->trust_type;
    2079           0 :         info_ex->trust_attributes = td->trust_attributes;
    2080             : 
    2081           0 :         return NT_STATUS_OK;
    2082             : }
    2083             : 
    2084           0 : NTSTATUS _lsa_QueryTrustedDomainInfo(struct pipes_struct *p,
    2085             :                                      struct lsa_QueryTrustedDomainInfo *r)
    2086             : {
    2087           0 :         NTSTATUS status;
    2088           0 :         struct lsa_info *handle;
    2089           0 :         union lsa_TrustedDomainInfo *info;
    2090           0 :         struct pdb_trusted_domain *td;
    2091           0 :         uint32_t acc_required;
    2092             : 
    2093             :         /* find the connection policy handle. */
    2094           0 :         handle = find_policy_by_hnd(p,
    2095             :                                     r->in.trustdom_handle,
    2096             :                                     LSA_HANDLE_TRUST_TYPE,
    2097             :                                     struct lsa_info,
    2098           0 :                                     &status);
    2099           0 :         if (!NT_STATUS_IS_OK(status)) {
    2100           0 :                 return NT_STATUS_INVALID_HANDLE;
    2101             :         }
    2102             : 
    2103           0 :         switch (r->in.level) {
    2104           0 :         case LSA_TRUSTED_DOMAIN_INFO_NAME:
    2105           0 :                 acc_required = LSA_TRUSTED_QUERY_DOMAIN_NAME;
    2106           0 :                 break;
    2107           0 :         case LSA_TRUSTED_DOMAIN_INFO_CONTROLLERS:
    2108           0 :                 acc_required = LSA_TRUSTED_QUERY_CONTROLLERS;
    2109           0 :                 break;
    2110           0 :         case LSA_TRUSTED_DOMAIN_INFO_POSIX_OFFSET:
    2111           0 :                 acc_required = LSA_TRUSTED_QUERY_POSIX;
    2112           0 :                 break;
    2113           0 :         case LSA_TRUSTED_DOMAIN_INFO_PASSWORD:
    2114           0 :                 acc_required = LSA_TRUSTED_QUERY_AUTH;
    2115           0 :                 break;
    2116           0 :         case LSA_TRUSTED_DOMAIN_INFO_BASIC:
    2117           0 :                 acc_required = LSA_TRUSTED_QUERY_DOMAIN_NAME;
    2118           0 :                 break;
    2119           0 :         case LSA_TRUSTED_DOMAIN_INFO_INFO_EX:
    2120           0 :                 acc_required = LSA_TRUSTED_QUERY_DOMAIN_NAME;
    2121           0 :                 break;
    2122           0 :         case LSA_TRUSTED_DOMAIN_INFO_AUTH_INFO:
    2123           0 :                 acc_required = LSA_TRUSTED_QUERY_AUTH;
    2124           0 :                 break;
    2125           0 :         case LSA_TRUSTED_DOMAIN_INFO_FULL_INFO:
    2126           0 :                 acc_required = LSA_TRUSTED_QUERY_DOMAIN_NAME |
    2127             :                                LSA_TRUSTED_QUERY_POSIX |
    2128             :                                LSA_TRUSTED_QUERY_AUTH;
    2129           0 :                 break;
    2130           0 :         case LSA_TRUSTED_DOMAIN_INFO_AUTH_INFO_INTERNAL:
    2131           0 :                 acc_required = LSA_TRUSTED_QUERY_AUTH;
    2132           0 :                 break;
    2133           0 :         case LSA_TRUSTED_DOMAIN_INFO_FULL_INFO_INTERNAL:
    2134           0 :                 acc_required = LSA_TRUSTED_QUERY_DOMAIN_NAME |
    2135             :                                LSA_TRUSTED_QUERY_POSIX |
    2136             :                                LSA_TRUSTED_QUERY_AUTH;
    2137           0 :                 break;
    2138           0 :         case LSA_TRUSTED_DOMAIN_INFO_INFO_EX2_INTERNAL:
    2139           0 :                 acc_required = LSA_TRUSTED_QUERY_DOMAIN_NAME;
    2140           0 :                 break;
    2141           0 :         case LSA_TRUSTED_DOMAIN_INFO_FULL_INFO_2_INTERNAL:
    2142           0 :                 acc_required = LSA_TRUSTED_QUERY_DOMAIN_NAME |
    2143             :                                LSA_TRUSTED_QUERY_POSIX |
    2144             :                                LSA_TRUSTED_QUERY_AUTH;
    2145           0 :                 break;
    2146           0 :         case LSA_TRUSTED_DOMAIN_SUPPORTED_ENCRYPTION_TYPES:
    2147           0 :                 acc_required = LSA_TRUSTED_QUERY_POSIX;
    2148           0 :                 break;
    2149           0 :         default:
    2150           0 :                 return NT_STATUS_INVALID_PARAMETER;
    2151             :         }
    2152             : 
    2153           0 :         if (!(handle->access & acc_required)) {
    2154           0 :                 return NT_STATUS_ACCESS_DENIED;
    2155             :         }
    2156             : 
    2157           0 :         status = pdb_get_trusted_domain_by_sid(p->mem_ctx, &handle->sid, &td);
    2158           0 :         if (!NT_STATUS_IS_OK(status)) {
    2159           0 :                 return status;
    2160             :         }
    2161             : 
    2162           0 :         info = talloc_zero(p->mem_ctx, union lsa_TrustedDomainInfo);
    2163           0 :         if (!info) {
    2164           0 :                 return NT_STATUS_NO_MEMORY;
    2165             :         }
    2166             : 
    2167           0 :         switch (r->in.level) {
    2168           0 :         case LSA_TRUSTED_DOMAIN_INFO_NAME:
    2169           0 :                 init_lsa_StringLarge(&info->name.netbios_name, td->netbios_name);
    2170           0 :                 break;
    2171           0 :         case LSA_TRUSTED_DOMAIN_INFO_CONTROLLERS:
    2172           0 :                 return NT_STATUS_INVALID_PARAMETER;
    2173           0 :         case LSA_TRUSTED_DOMAIN_INFO_POSIX_OFFSET:
    2174           0 :                 info->posix_offset.posix_offset = *td->trust_posix_offset;
    2175           0 :                 break;
    2176           0 :         case LSA_TRUSTED_DOMAIN_INFO_PASSWORD:
    2177           0 :                 return NT_STATUS_INVALID_INFO_CLASS;
    2178           0 :         case LSA_TRUSTED_DOMAIN_INFO_BASIC:
    2179           0 :                 return NT_STATUS_INVALID_PARAMETER;
    2180           0 :         case LSA_TRUSTED_DOMAIN_INFO_INFO_EX:
    2181           0 :                 status = pdb_trusted_domain_2_info_ex(info, td, &info->info_ex);
    2182           0 :                 if (!NT_STATUS_IS_OK(status)) {
    2183           0 :                         return status;
    2184             :                 }
    2185           0 :                 break;
    2186           0 :         case LSA_TRUSTED_DOMAIN_INFO_AUTH_INFO:
    2187           0 :                 return NT_STATUS_INVALID_INFO_CLASS;
    2188           0 :         case LSA_TRUSTED_DOMAIN_INFO_FULL_INFO:
    2189           0 :                 status = pdb_trusted_domain_2_info_ex(info, td,
    2190             :                                                       &info->full_info.info_ex);
    2191           0 :                 if (!NT_STATUS_IS_OK(status)) {
    2192           0 :                         return status;
    2193             :                 }
    2194           0 :                 info->full_info.posix_offset.posix_offset = *td->trust_posix_offset;
    2195           0 :                 status = auth_blob_2_auth_info(p->mem_ctx,
    2196           0 :                                                     td->trust_auth_incoming,
    2197           0 :                                                     td->trust_auth_outgoing,
    2198             :                                                     &info->full_info.auth_info);
    2199           0 :                 if (!NT_STATUS_IS_OK(status)) {
    2200           0 :                         return status;
    2201             :                 }
    2202           0 :                 break;
    2203           0 :         case LSA_TRUSTED_DOMAIN_INFO_AUTH_INFO_INTERNAL:
    2204           0 :                 return NT_STATUS_INVALID_INFO_CLASS;
    2205           0 :         case LSA_TRUSTED_DOMAIN_INFO_FULL_INFO_INTERNAL:
    2206           0 :                 return NT_STATUS_INVALID_INFO_CLASS;
    2207           0 :         case LSA_TRUSTED_DOMAIN_INFO_INFO_EX2_INTERNAL:
    2208           0 :                 return NT_STATUS_INVALID_PARAMETER;
    2209           0 :         case LSA_TRUSTED_DOMAIN_INFO_FULL_INFO_2_INTERNAL:
    2210           0 :                 info->full_info2_internal.posix_offset.posix_offset = *td->trust_posix_offset;
    2211           0 :                 status = auth_blob_2_auth_info(p->mem_ctx,
    2212           0 :                                           td->trust_auth_incoming,
    2213           0 :                                           td->trust_auth_outgoing,
    2214             :                                           &info->full_info2_internal.auth_info);
    2215           0 :                 if (!NT_STATUS_IS_OK(status)) {
    2216           0 :                         return status;
    2217             :                 }
    2218           0 :                 break;
    2219           0 :         case LSA_TRUSTED_DOMAIN_SUPPORTED_ENCRYPTION_TYPES:
    2220           0 :                 info->enc_types.enc_types = *td->supported_enc_type;
    2221           0 :                 break;
    2222           0 :         default:
    2223           0 :                 return NT_STATUS_INVALID_PARAMETER;
    2224             :         }
    2225             : 
    2226           0 :         *r->out.info = info;
    2227             : 
    2228           0 :         return NT_STATUS_OK;
    2229             : }
    2230             : 
    2231             : /***************************************************************************
    2232             :  _lsa_QueryTrustedDomainInfoBySid
    2233             :  ***************************************************************************/
    2234             : 
    2235           0 : NTSTATUS _lsa_QueryTrustedDomainInfoBySid(struct pipes_struct *p,
    2236             :                                           struct lsa_QueryTrustedDomainInfoBySid *r)
    2237             : {
    2238           0 :         NTSTATUS status;
    2239           0 :         struct policy_handle trustdom_handle;
    2240           0 :         struct lsa_OpenTrustedDomain o;
    2241           0 :         struct lsa_QueryTrustedDomainInfo q;
    2242           0 :         struct lsa_Close c;
    2243             : 
    2244           0 :         o.in.handle             = r->in.handle;
    2245           0 :         o.in.sid                = r->in.dom_sid;
    2246           0 :         o.in.access_mask        = SEC_FLAG_MAXIMUM_ALLOWED;
    2247           0 :         o.out.trustdom_handle   = &trustdom_handle;
    2248             : 
    2249           0 :         status = _lsa_OpenTrustedDomain(p, &o);
    2250           0 :         if (!NT_STATUS_IS_OK(status)) {
    2251           0 :                 return status;
    2252             :         }
    2253             : 
    2254           0 :         q.in.trustdom_handle    = &trustdom_handle;
    2255           0 :         q.in.level              = r->in.level;
    2256           0 :         q.out.info              = r->out.info;
    2257             : 
    2258           0 :         status = _lsa_QueryTrustedDomainInfo(p, &q);
    2259           0 :         if (!NT_STATUS_IS_OK(status)) {
    2260           0 :                 return status;
    2261             :         }
    2262             : 
    2263           0 :         c.in.handle             = &trustdom_handle;
    2264           0 :         c.out.handle            = &trustdom_handle;
    2265             : 
    2266           0 :         return _lsa_Close(p, &c);
    2267             : }
    2268             : 
    2269             : /***************************************************************************
    2270             :  _lsa_QueryTrustedDomainInfoByName
    2271             :  ***************************************************************************/
    2272             : 
    2273           0 : NTSTATUS _lsa_QueryTrustedDomainInfoByName(struct pipes_struct *p,
    2274             :                                            struct lsa_QueryTrustedDomainInfoByName *r)
    2275             : {
    2276           0 :         NTSTATUS status;
    2277           0 :         struct policy_handle trustdom_handle;
    2278           0 :         struct lsa_OpenTrustedDomainByName o;
    2279           0 :         struct lsa_QueryTrustedDomainInfo q;
    2280           0 :         struct lsa_Close c;
    2281             : 
    2282           0 :         o.in.handle             = r->in.handle;
    2283           0 :         o.in.name.string        = r->in.trusted_domain->string;
    2284           0 :         o.in.access_mask        = SEC_FLAG_MAXIMUM_ALLOWED;
    2285           0 :         o.out.trustdom_handle   = &trustdom_handle;
    2286             : 
    2287           0 :         status = _lsa_OpenTrustedDomainByName(p, &o);
    2288           0 :         if (!NT_STATUS_IS_OK(status)) {
    2289           0 :                 if (NT_STATUS_EQUAL(status, NT_STATUS_NO_SUCH_DOMAIN)) {
    2290           0 :                         return NT_STATUS_OBJECT_NAME_NOT_FOUND;
    2291             :                 }
    2292           0 :                 return status;
    2293             :         }
    2294             : 
    2295           0 :         q.in.trustdom_handle    = &trustdom_handle;
    2296           0 :         q.in.level              = r->in.level;
    2297           0 :         q.out.info              = r->out.info;
    2298             : 
    2299           0 :         status = _lsa_QueryTrustedDomainInfo(p, &q);
    2300           0 :         if (!NT_STATUS_IS_OK(status)) {
    2301           0 :                 return status;
    2302             :         }
    2303             : 
    2304           0 :         c.in.handle             = &trustdom_handle;
    2305           0 :         c.out.handle            = &trustdom_handle;
    2306             : 
    2307           0 :         return _lsa_Close(p, &c);
    2308             : }
    2309             : 
    2310             : /***************************************************************************
    2311             :  _lsa_CreateSecret
    2312             :  ***************************************************************************/
    2313             : 
    2314         632 : NTSTATUS _lsa_CreateSecret(struct pipes_struct *p,
    2315             :                            struct lsa_CreateSecret *r)
    2316             : {
    2317         632 :         struct dcesrv_call_state *dce_call = p->dce_call;
    2318           0 :         struct auth_session_info *session_info =
    2319         632 :                 dcesrv_call_session_info(dce_call);
    2320           0 :         NTSTATUS status;
    2321           0 :         struct lsa_info *handle;
    2322           0 :         uint32_t acc_granted;
    2323           0 :         struct security_descriptor *psd;
    2324           0 :         size_t sd_size;
    2325             : 
    2326             :         /* find the connection policy handle. */
    2327         632 :         handle = find_policy_by_hnd(p,
    2328             :                                     r->in.handle,
    2329             :                                     LSA_HANDLE_POLICY_TYPE,
    2330             :                                     struct lsa_info,
    2331           0 :                                     &status);
    2332         632 :         if (!NT_STATUS_IS_OK(status)) {
    2333           0 :                 return NT_STATUS_INVALID_HANDLE;
    2334             :         }
    2335             : 
    2336             :         /* check if the user has enough rights */
    2337             : 
    2338         632 :         if (!(handle->access & LSA_POLICY_CREATE_SECRET)) {
    2339           0 :                 return NT_STATUS_ACCESS_DENIED;
    2340             :         }
    2341             : 
    2342             :         /* Work out max allowed. */
    2343         632 :         map_max_allowed_access(session_info->security_token,
    2344         632 :                                session_info->unix_token,
    2345             :                                &r->in.access_mask);
    2346             : 
    2347             :         /* map the generic bits to the lsa policy ones */
    2348         632 :         se_map_generic(&r->in.access_mask, &lsa_secret_mapping);
    2349             : 
    2350         632 :         status = make_lsa_object_sd(p->mem_ctx, &psd, &sd_size,
    2351             :                                     &lsa_secret_mapping,
    2352             :                                     NULL, 0);
    2353         632 :         if (!NT_STATUS_IS_OK(status)) {
    2354           0 :                 return status;
    2355             :         }
    2356             : 
    2357         632 :         status = access_check_object(psd, session_info->security_token,
    2358             :                                      SEC_PRIV_INVALID, SEC_PRIV_INVALID, 0,
    2359             :                                      r->in.access_mask,
    2360             :                                      &acc_granted, "_lsa_CreateSecret");
    2361         632 :         if (!NT_STATUS_IS_OK(status)) {
    2362           0 :                 return status;
    2363             :         }
    2364             : 
    2365         632 :         if (!r->in.name.string) {
    2366           0 :                 return NT_STATUS_INVALID_PARAMETER;
    2367             :         }
    2368             : 
    2369         632 :         if (strlen(r->in.name.string) > 128) {
    2370           0 :                 return NT_STATUS_NAME_TOO_LONG;
    2371             :         }
    2372             : 
    2373         632 :         status = pdb_get_secret(p->mem_ctx, r->in.name.string,
    2374             :                                 NULL, NULL, NULL, NULL, NULL);
    2375         632 :         if (NT_STATUS_IS_OK(status)) {
    2376           4 :                 return NT_STATUS_OBJECT_NAME_COLLISION;
    2377             :         }
    2378             : 
    2379         628 :         status = pdb_set_secret(r->in.name.string, NULL, NULL, psd);
    2380         628 :         if (!NT_STATUS_IS_OK(status)) {
    2381           0 :                 return status;
    2382             :         }
    2383             : 
    2384         628 :         status = create_lsa_policy_handle(p->mem_ctx, p,
    2385             :                                           LSA_HANDLE_SECRET_TYPE,
    2386             :                                           acc_granted,
    2387             :                                           NULL,
    2388             :                                           r->in.name.string,
    2389             :                                           psd,
    2390             :                                           r->out.sec_handle);
    2391         628 :         if (!NT_STATUS_IS_OK(status)) {
    2392           0 :                 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
    2393             :         }
    2394             : 
    2395         628 :         return NT_STATUS_OK;
    2396             : }
    2397             : 
    2398             : /***************************************************************************
    2399             :  _lsa_SetSecret
    2400             :  ***************************************************************************/
    2401             : 
    2402         848 : NTSTATUS _lsa_SetSecret(struct pipes_struct *p,
    2403             :                         struct lsa_SetSecret *r)
    2404             : {
    2405         848 :         struct dcesrv_call_state *dce_call = p->dce_call;
    2406           0 :         struct auth_session_info *session_info =
    2407         848 :                 dcesrv_call_session_info(dce_call);
    2408           0 :         NTSTATUS status;
    2409         848 :         struct lsa_info *info = NULL;
    2410           0 :         DATA_BLOB blob_new, blob_old;
    2411         848 :         DATA_BLOB cleartext_blob_new = data_blob_null;
    2412         848 :         DATA_BLOB cleartext_blob_old = data_blob_null;
    2413         848 :         DATA_BLOB *cleartext_blob_new_p = NULL;
    2414         848 :         DATA_BLOB *cleartext_blob_old_p = NULL;
    2415           0 :         DATA_BLOB session_key;
    2416             : 
    2417         848 :         info = find_policy_by_hnd(p,
    2418             :                                   r->in.sec_handle,
    2419             :                                   LSA_HANDLE_SECRET_TYPE,
    2420             :                                   struct lsa_info,
    2421           0 :                                   &status);
    2422         848 :         if (!NT_STATUS_IS_OK(status)) {
    2423           0 :                 return NT_STATUS_INVALID_HANDLE;
    2424             :         }
    2425             : 
    2426         848 :         if (!(info->access & LSA_SECRET_SET_VALUE)) {
    2427           0 :                 return NT_STATUS_ACCESS_DENIED;
    2428             :         }
    2429             : 
    2430         848 :         status = session_extract_session_key(
    2431             :                 session_info, &session_key, KEY_USE_16BYTES);
    2432         848 :         if(!NT_STATUS_IS_OK(status)) {
    2433           0 :                 return status;
    2434             :         }
    2435             : 
    2436         848 :         if (r->in.new_val) {
    2437         844 :                 blob_new = data_blob_const(r->in.new_val->data,
    2438         844 :                                            r->in.new_val->length);
    2439             : 
    2440         844 :                 status = sess_decrypt_blob(p->mem_ctx, &blob_new,
    2441             :                                            &session_key,
    2442             :                                            &cleartext_blob_new);
    2443         844 :                 if (!NT_STATUS_IS_OK(status)) {
    2444         420 :                         return status;
    2445             :                 }
    2446             : 
    2447         424 :                 cleartext_blob_new_p = &cleartext_blob_new;
    2448             :         }
    2449             : 
    2450         428 :         if (r->in.old_val) {
    2451           4 :                 blob_old = data_blob_const(r->in.old_val->data,
    2452           4 :                                            r->in.old_val->length);
    2453             : 
    2454           4 :                 status = sess_decrypt_blob(p->mem_ctx, &blob_old,
    2455             :                                            &session_key,
    2456             :                                            &cleartext_blob_old);
    2457           4 :                 if (!NT_STATUS_IS_OK(status)) {
    2458           0 :                         return status;
    2459             :                 }
    2460             : 
    2461           4 :                 cleartext_blob_old_p = &cleartext_blob_old;
    2462             :         }
    2463             : 
    2464         428 :         status = pdb_set_secret(info->name, cleartext_blob_new_p, cleartext_blob_old_p, NULL);
    2465         428 :         if (!NT_STATUS_IS_OK(status)) {
    2466           0 :                 return status;
    2467             :         }
    2468             : 
    2469             : #ifdef DEBUG_PASSWORD
    2470         428 :         DEBUG(10,("_lsa_SetSecret: successfully set new secret\n"));
    2471         428 :         dump_data(10, cleartext_blob_new.data, cleartext_blob_new.length);
    2472         428 :         DEBUG(10,("_lsa_SetSecret: successfully set old secret\n"));
    2473         428 :         dump_data(10, cleartext_blob_old.data, cleartext_blob_old.length);
    2474             : #endif
    2475             : 
    2476         428 :         return NT_STATUS_OK;
    2477             : }
    2478             : 
    2479             : /***************************************************************************
    2480             :  _lsa_QuerySecret
    2481             :  ***************************************************************************/
    2482             : 
    2483         428 : NTSTATUS _lsa_QuerySecret(struct pipes_struct *p,
    2484             :                           struct lsa_QuerySecret *r)
    2485             : {
    2486         428 :         struct dcesrv_call_state *dce_call = p->dce_call;
    2487           0 :         struct auth_session_info *session_info =
    2488         428 :                 dcesrv_call_session_info(dce_call);
    2489         428 :         struct lsa_info *info = NULL;
    2490           0 :         DATA_BLOB blob_new, blob_old;
    2491           0 :         DATA_BLOB blob_new_crypt, blob_old_crypt;
    2492           0 :         DATA_BLOB session_key;
    2493           0 :         NTTIME nttime_new, nttime_old;
    2494           0 :         NTSTATUS status;
    2495             : 
    2496         428 :         info = find_policy_by_hnd(p,
    2497             :                                   r->in.sec_handle,
    2498             :                                   LSA_HANDLE_SECRET_TYPE,
    2499             :                                   struct lsa_info,
    2500           0 :                                   &status);
    2501         428 :         if (!NT_STATUS_IS_OK(status)) {
    2502           0 :                 return NT_STATUS_INVALID_HANDLE;
    2503             :         }
    2504             : 
    2505         428 :         if (!(info->access & LSA_SECRET_QUERY_VALUE)) {
    2506           0 :                 return NT_STATUS_ACCESS_DENIED;
    2507             :         }
    2508             : 
    2509         428 :         status = pdb_get_secret(p->mem_ctx, info->name,
    2510             :                                 &blob_new, &nttime_new,
    2511             :                                 &blob_old, &nttime_old,
    2512             :                                 NULL);
    2513         428 :         if (!NT_STATUS_IS_OK(status)) {
    2514           0 :                 return status;
    2515             :         }
    2516             : 
    2517         428 :         status = session_extract_session_key(
    2518             :                 session_info, &session_key, KEY_USE_16BYTES);
    2519         428 :         if(!NT_STATUS_IS_OK(status)) {
    2520           0 :                 return status;
    2521             :         }
    2522             : 
    2523         428 :         if (r->in.new_val) {
    2524         428 :                 if (blob_new.length) {
    2525         424 :                         if (!r->out.new_val->buf) {
    2526         424 :                                 r->out.new_val->buf = talloc_zero(p->mem_ctx, struct lsa_DATA_BUF);
    2527             :                         }
    2528         424 :                         if (!r->out.new_val->buf) {
    2529           0 :                                 return NT_STATUS_NO_MEMORY;
    2530             :                         }
    2531             : 
    2532         424 :                         blob_new_crypt = sess_encrypt_blob(p->mem_ctx, &blob_new,
    2533             :                                                            &session_key);
    2534         424 :                         if (!blob_new_crypt.length) {
    2535           0 :                                 return NT_STATUS_NO_MEMORY;
    2536             :                         }
    2537             : 
    2538         424 :                         r->out.new_val->buf->data      = blob_new_crypt.data;
    2539         424 :                         r->out.new_val->buf->length    = blob_new_crypt.length;
    2540         424 :                         r->out.new_val->buf->size      = blob_new_crypt.length;
    2541             :                 }
    2542             :         }
    2543             : 
    2544         428 :         if (r->in.old_val) {
    2545           8 :                 if (blob_old.length) {
    2546           8 :                         if (!r->out.old_val->buf) {
    2547           8 :                                 r->out.old_val->buf = talloc_zero(p->mem_ctx, struct lsa_DATA_BUF);
    2548             :                         }
    2549           8 :                         if (!r->out.old_val->buf) {
    2550           0 :                                 return NT_STATUS_NO_MEMORY;
    2551             :                         }
    2552             : 
    2553           8 :                         blob_old_crypt = sess_encrypt_blob(p->mem_ctx, &blob_old,
    2554             :                                                            &session_key);
    2555           8 :                         if (!blob_old_crypt.length) {
    2556           0 :                                 return NT_STATUS_NO_MEMORY;
    2557             :                         }
    2558             : 
    2559           8 :                         r->out.old_val->buf->data      = blob_old_crypt.data;
    2560           8 :                         r->out.old_val->buf->length    = blob_old_crypt.length;
    2561           8 :                         r->out.old_val->buf->size      = blob_old_crypt.length;
    2562             :                 }
    2563             :         }
    2564             : 
    2565         428 :         if (r->out.new_mtime) {
    2566         428 :                 *r->out.new_mtime = nttime_new;
    2567             :         }
    2568             : 
    2569         428 :         if (r->out.old_mtime) {
    2570           8 :                 *r->out.old_mtime = nttime_old;
    2571             :         }
    2572             : 
    2573         428 :         return NT_STATUS_OK;
    2574             : }
    2575             : 
    2576             : /***************************************************************************
    2577             :  _lsa_DeleteObject
    2578             :  ***************************************************************************/
    2579             : 
    2580         636 : NTSTATUS _lsa_DeleteObject(struct pipes_struct *p,
    2581             :                            struct lsa_DeleteObject *r)
    2582             : {
    2583           0 :         NTSTATUS status;
    2584         636 :         struct lsa_info *info = NULL;
    2585             : 
    2586         636 :         info = find_policy_by_hnd(p,
    2587             :                                   r->in.handle,
    2588             :                                   DCESRV_HANDLE_ANY,
    2589             :                                   struct lsa_info,
    2590           0 :                                   &status);
    2591         636 :         if (!NT_STATUS_IS_OK(status)) {
    2592           0 :                 return NT_STATUS_INVALID_HANDLE;
    2593             :         }
    2594             : 
    2595         636 :         if (!(info->access & SEC_STD_DELETE)) {
    2596           0 :                 return NT_STATUS_ACCESS_DENIED;
    2597             :         }
    2598             : 
    2599         636 :         switch (info->type) {
    2600           4 :         case LSA_HANDLE_ACCOUNT_TYPE:
    2601           4 :                 status = privilege_delete_account(&info->sid);
    2602           4 :                 if (!NT_STATUS_IS_OK(status)) {
    2603           0 :                         DEBUG(10,("_lsa_DeleteObject: privilege_delete_account gave: %s\n",
    2604             :                                 nt_errstr(status)));
    2605           4 :                         return status;
    2606             :                 }
    2607           4 :                 break;
    2608           0 :         case LSA_HANDLE_TRUST_TYPE:
    2609           0 :                 if (!pdb_del_trusteddom_pw(info->name)) {
    2610           0 :                         return NT_STATUS_OBJECT_NAME_NOT_FOUND;
    2611             :                 }
    2612           0 :                 status = NT_STATUS_OK;
    2613           0 :                 break;
    2614         632 :         case LSA_HANDLE_SECRET_TYPE:
    2615         632 :                 status = pdb_delete_secret(info->name);
    2616         632 :                 if (NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
    2617           4 :                         return NT_STATUS_INVALID_HANDLE;
    2618             :                 }
    2619         628 :                 break;
    2620           0 :         default:
    2621           0 :                 return NT_STATUS_INVALID_HANDLE;
    2622             :         }
    2623             : 
    2624         632 :         close_policy_hnd(p, r->in.handle);
    2625         632 :         ZERO_STRUCTP(r->out.handle);
    2626             : 
    2627         632 :         return status;
    2628             : }
    2629             : 
    2630             : /***************************************************************************
    2631             :  _lsa_EnumPrivs
    2632             :  ***************************************************************************/
    2633             : 
    2634           2 : NTSTATUS _lsa_EnumPrivs(struct pipes_struct *p,
    2635             :                         struct lsa_EnumPrivs *r)
    2636             : {
    2637           0 :         struct lsa_info *handle;
    2638           0 :         uint32_t i;
    2639           2 :         uint32_t enum_context = *r->in.resume_handle;
    2640           2 :         int num_privs = num_privileges_in_short_list();
    2641           2 :         struct lsa_PrivEntry *entries = NULL;
    2642           0 :         NTSTATUS status;
    2643             : 
    2644             :         /* remember that the enum_context starts at 0 and not 1 */
    2645             : 
    2646           2 :         if ( enum_context >= num_privs )
    2647           0 :                 return NT_STATUS_NO_MORE_ENTRIES;
    2648             : 
    2649           2 :         DEBUG(10,("_lsa_EnumPrivs: enum_context:%d total entries:%d\n",
    2650             :                 enum_context, num_privs));
    2651             : 
    2652           2 :         handle = find_policy_by_hnd(p,
    2653             :                                     r->in.handle,
    2654             :                                     LSA_HANDLE_POLICY_TYPE,
    2655             :                                     struct lsa_info,
    2656           0 :                                     &status);
    2657           2 :         if (!NT_STATUS_IS_OK(status)) {
    2658           0 :                 return NT_STATUS_INVALID_HANDLE;
    2659             :         }
    2660             : 
    2661             :         /* check if the user has enough rights
    2662             :            I don't know if it's the right one. not documented.  */
    2663             : 
    2664           2 :         if (!(handle->access & LSA_POLICY_VIEW_LOCAL_INFORMATION))
    2665           0 :                 return NT_STATUS_ACCESS_DENIED;
    2666             : 
    2667           2 :         if (num_privs) {
    2668           2 :                 entries = talloc_zero_array(p->mem_ctx, struct lsa_PrivEntry, num_privs);
    2669           2 :                 if (!entries) {
    2670           0 :                         return NT_STATUS_NO_MEMORY;
    2671             :                 }
    2672             :         } else {
    2673           0 :                 entries = NULL;
    2674             :         }
    2675             : 
    2676          20 :         for (i = 0; i < num_privs; i++) {
    2677          18 :                 if( i < enum_context) {
    2678             : 
    2679           0 :                         init_lsa_StringLarge(&entries[i].name, NULL);
    2680             : 
    2681           0 :                         entries[i].luid.low = 0;
    2682           0 :                         entries[i].luid.high = 0;
    2683             :                 } else {
    2684             : 
    2685          18 :                         init_lsa_StringLarge(&entries[i].name, sec_privilege_name_from_index(i));
    2686             : 
    2687          18 :                         entries[i].luid.low = sec_privilege_from_index(i);
    2688          18 :                         entries[i].luid.high = 0;
    2689             :                 }
    2690             :         }
    2691             : 
    2692           2 :         enum_context = num_privs;
    2693             : 
    2694           2 :         *r->out.resume_handle = enum_context;
    2695           2 :         r->out.privs->count = num_privs;
    2696           2 :         r->out.privs->privs = entries;
    2697             : 
    2698           2 :         return NT_STATUS_OK;
    2699             : }
    2700             : 
    2701             : /***************************************************************************
    2702             :  _lsa_LookupPrivDisplayName
    2703             :  ***************************************************************************/
    2704             : 
    2705          18 : NTSTATUS _lsa_LookupPrivDisplayName(struct pipes_struct *p,
    2706             :                                     struct lsa_LookupPrivDisplayName *r)
    2707             : {
    2708           0 :         struct lsa_info *handle;
    2709           0 :         const char *description;
    2710           0 :         struct lsa_StringLarge *lsa_name;
    2711           0 :         NTSTATUS status;
    2712             : 
    2713          18 :         handle = find_policy_by_hnd(p,
    2714             :                                     r->in.handle,
    2715             :                                     LSA_HANDLE_POLICY_TYPE,
    2716             :                                     struct lsa_info,
    2717           0 :                                     &status);
    2718          18 :         if (!NT_STATUS_IS_OK(status)) {
    2719           0 :                 return NT_STATUS_INVALID_HANDLE;
    2720             :         }
    2721             : 
    2722             :         /* check if the user has enough rights */
    2723             : 
    2724             :         /*
    2725             :          * I don't know if it's the right one. not documented.
    2726             :          */
    2727          18 :         if (!(handle->access & LSA_POLICY_VIEW_LOCAL_INFORMATION))
    2728           0 :                 return NT_STATUS_ACCESS_DENIED;
    2729             : 
    2730          18 :         DEBUG(10,("_lsa_LookupPrivDisplayName: name = %s\n", r->in.name->string));
    2731             : 
    2732          18 :         description = get_privilege_dispname(r->in.name->string);
    2733          18 :         if (!description) {
    2734           0 :                 DEBUG(10,("_lsa_LookupPrivDisplayName: doesn't exist\n"));
    2735           0 :                 return NT_STATUS_NO_SUCH_PRIVILEGE;
    2736             :         }
    2737             : 
    2738          18 :         DEBUG(10,("_lsa_LookupPrivDisplayName: display name = %s\n", description));
    2739             : 
    2740          18 :         lsa_name = talloc_zero(p->mem_ctx, struct lsa_StringLarge);
    2741          18 :         if (!lsa_name) {
    2742           0 :                 return NT_STATUS_NO_MEMORY;
    2743             :         }
    2744             : 
    2745          18 :         init_lsa_StringLarge(lsa_name, description);
    2746             : 
    2747          18 :         *r->out.returned_language_id = r->in.language_id;
    2748          18 :         *r->out.disp_name = lsa_name;
    2749             : 
    2750          18 :         return NT_STATUS_OK;
    2751             : }
    2752             : 
    2753             : /***************************************************************************
    2754             :  _lsa_EnumAccounts
    2755             :  ***************************************************************************/
    2756             : 
    2757          10 : NTSTATUS _lsa_EnumAccounts(struct pipes_struct *p,
    2758             :                            struct lsa_EnumAccounts *r)
    2759             : {
    2760           0 :         struct lsa_info *handle;
    2761           0 :         struct dom_sid *sid_list;
    2762           0 :         int i, j, num_entries;
    2763           0 :         NTSTATUS status;
    2764          10 :         struct lsa_SidPtr *sids = NULL;
    2765             : 
    2766          10 :         handle = find_policy_by_hnd(p,
    2767             :                                     r->in.handle,
    2768             :                                     LSA_HANDLE_POLICY_TYPE,
    2769             :                                     struct lsa_info,
    2770           0 :                                     &status);
    2771          10 :         if (!NT_STATUS_IS_OK(status)) {
    2772           0 :                 return NT_STATUS_INVALID_HANDLE;
    2773             :         }
    2774             : 
    2775          10 :         if (!(handle->access & LSA_POLICY_VIEW_LOCAL_INFORMATION))
    2776           0 :                 return NT_STATUS_ACCESS_DENIED;
    2777             : 
    2778          10 :         sid_list = NULL;
    2779          10 :         num_entries = 0;
    2780             : 
    2781             :         /* The only way we can currently find out all the SIDs that have been
    2782             :            privileged is to scan all privileges */
    2783             : 
    2784          10 :         status = privilege_enumerate_accounts(&sid_list, &num_entries);
    2785          10 :         if (!NT_STATUS_IS_OK(status)) {
    2786           0 :                 return status;
    2787             :         }
    2788             : 
    2789          10 :         if (*r->in.resume_handle >= num_entries) {
    2790           2 :                 return NT_STATUS_NO_MORE_ENTRIES;
    2791             :         }
    2792             : 
    2793           8 :         if (num_entries - *r->in.resume_handle) {
    2794           8 :                 sids = talloc_zero_array(p->mem_ctx, struct lsa_SidPtr,
    2795             :                                          num_entries - *r->in.resume_handle);
    2796           8 :                 if (!sids) {
    2797           0 :                         talloc_free(sid_list);
    2798           0 :                         return NT_STATUS_NO_MEMORY;
    2799             :                 }
    2800             : 
    2801          60 :                 for (i = *r->in.resume_handle, j = 0; i < num_entries; i++, j++) {
    2802          52 :                         sids[j].sid = dom_sid_dup(p->mem_ctx, &sid_list[i]);
    2803          52 :                         if (!sids[j].sid) {
    2804           0 :                                 talloc_free(sid_list);
    2805           0 :                                 return NT_STATUS_NO_MEMORY;
    2806             :                         }
    2807             :                 }
    2808             :         }
    2809             : 
    2810           8 :         talloc_free(sid_list);
    2811             : 
    2812           8 :         *r->out.resume_handle = num_entries;
    2813           8 :         r->out.sids->num_sids = num_entries;
    2814           8 :         r->out.sids->sids = sids;
    2815             : 
    2816           8 :         return NT_STATUS_OK;
    2817             : }
    2818             : 
    2819             : /***************************************************************************
    2820             :  _lsa_GetUserName
    2821             :  ***************************************************************************/
    2822             : 
    2823         389 : NTSTATUS _lsa_GetUserName(struct pipes_struct *p,
    2824             :                           struct lsa_GetUserName *r)
    2825             : {
    2826         389 :         struct dcesrv_call_state *dce_call = p->dce_call;
    2827           0 :         struct auth_session_info *session_info =
    2828         389 :                 dcesrv_call_session_info(dce_call);
    2829           0 :         const char *username, *domname;
    2830         389 :         struct lsa_String *account_name = NULL;
    2831         389 :         struct lsa_String *authority_name = NULL;
    2832             : 
    2833         389 :         if (p->transport != NCACN_NP && p->transport != NCALRPC) {
    2834           0 :                 p->fault_state = DCERPC_FAULT_ACCESS_DENIED;
    2835           0 :                 return NT_STATUS_ACCESS_DENIED;
    2836             :         }
    2837             : 
    2838         389 :         if (r->in.account_name &&
    2839         389 :            *r->in.account_name) {
    2840           0 :                 return NT_STATUS_INVALID_PARAMETER;
    2841             :         }
    2842             : 
    2843         389 :         if (r->in.authority_name &&
    2844         379 :            *r->in.authority_name) {
    2845           0 :                 return NT_STATUS_INVALID_PARAMETER;
    2846             :         }
    2847             : 
    2848         389 :         if (security_session_user_level(session_info, NULL) < SECURITY_USER) {
    2849             :                 /*
    2850             :                  * I'm 99% sure this is not the right place to do this,
    2851             :                  * global_sid_Anonymous should probably be put into the token
    2852             :                  * instead of the guest id -- vl
    2853             :                  */
    2854         142 :                 if (!lookup_sid(p->mem_ctx, &global_sid_Anonymous,
    2855             :                                 &domname, &username, NULL)) {
    2856           0 :                         return NT_STATUS_NO_MEMORY;
    2857             :                 }
    2858             :         } else {
    2859         247 :                 username = session_info->unix_info->sanitized_username;
    2860         247 :                 domname = session_info->info->domain_name;
    2861             :         }
    2862             : 
    2863         389 :         account_name = talloc(p->mem_ctx, struct lsa_String);
    2864         389 :         if (!account_name) {
    2865           0 :                 return NT_STATUS_NO_MEMORY;
    2866             :         }
    2867         389 :         init_lsa_String(account_name, username);
    2868             : 
    2869         389 :         if (r->out.authority_name) {
    2870         379 :                 authority_name = talloc(p->mem_ctx, struct lsa_String);
    2871         379 :                 if (!authority_name) {
    2872           0 :                         return NT_STATUS_NO_MEMORY;
    2873             :                 }
    2874         379 :                 init_lsa_String(authority_name, domname);
    2875             :         }
    2876             : 
    2877         389 :         *r->out.account_name = account_name;
    2878         389 :         if (r->out.authority_name) {
    2879         379 :                 *r->out.authority_name = authority_name;
    2880             :         }
    2881             : 
    2882         389 :         return NT_STATUS_OK;
    2883             : }
    2884             : 
    2885             : /***************************************************************************
    2886             :  _lsa_CreateAccount
    2887             :  ***************************************************************************/
    2888             : 
    2889           2 : NTSTATUS _lsa_CreateAccount(struct pipes_struct *p,
    2890             :                             struct lsa_CreateAccount *r)
    2891             : {
    2892           2 :         struct dcesrv_call_state *dce_call = p->dce_call;
    2893           0 :         struct auth_session_info *session_info =
    2894           2 :                 dcesrv_call_session_info(dce_call);
    2895           0 :         NTSTATUS status;
    2896           0 :         struct lsa_info *handle;
    2897           0 :         uint32_t acc_granted;
    2898           0 :         struct security_descriptor *psd;
    2899           0 :         size_t sd_size;
    2900           2 :         uint32_t owner_access = (LSA_ACCOUNT_ALL_ACCESS &
    2901             :                         ~(LSA_ACCOUNT_ADJUST_PRIVILEGES|
    2902             :                         LSA_ACCOUNT_ADJUST_SYSTEM_ACCESS|
    2903             :                         SEC_STD_DELETE));
    2904             : 
    2905             :         /* find the connection policy handle. */
    2906           2 :         handle = find_policy_by_hnd(p,
    2907             :                                     r->in.handle,
    2908             :                                     LSA_HANDLE_POLICY_TYPE,
    2909             :                                     struct lsa_info,
    2910           0 :                                     &status);
    2911           2 :         if (!NT_STATUS_IS_OK(status)) {
    2912           0 :                 return NT_STATUS_INVALID_HANDLE;
    2913             :         }
    2914             : 
    2915             :         /* check if the user has enough rights */
    2916             : 
    2917           2 :         if (!(handle->access & LSA_POLICY_CREATE_ACCOUNT)) {
    2918           0 :                 return NT_STATUS_ACCESS_DENIED;
    2919             :         }
    2920             : 
    2921             :         /* Work out max allowed. */
    2922           2 :         map_max_allowed_access(session_info->security_token,
    2923           2 :                                session_info->unix_token,
    2924             :                                &r->in.access_mask);
    2925             : 
    2926             :         /* map the generic bits to the lsa policy ones */
    2927           2 :         se_map_generic(&r->in.access_mask, &lsa_account_mapping);
    2928             : 
    2929           2 :         status = make_lsa_object_sd(p->mem_ctx, &psd, &sd_size,
    2930             :                                     &lsa_account_mapping,
    2931             :                                     r->in.sid, owner_access);
    2932           2 :         if (!NT_STATUS_IS_OK(status)) {
    2933           0 :                 return status;
    2934             :         }
    2935             : 
    2936           2 :         status = access_check_object(psd, session_info->security_token,
    2937             :                                      SEC_PRIV_INVALID, SEC_PRIV_INVALID, 0, r->in.access_mask,
    2938             :                                      &acc_granted, "_lsa_CreateAccount");
    2939           2 :         if (!NT_STATUS_IS_OK(status)) {
    2940           0 :                 return status;
    2941             :         }
    2942             : 
    2943           2 :         if ( is_privileged_sid( r->in.sid ) )
    2944           0 :                 return NT_STATUS_OBJECT_NAME_COLLISION;
    2945             : 
    2946           2 :         status = create_lsa_policy_handle(p->mem_ctx, p,
    2947             :                                           LSA_HANDLE_ACCOUNT_TYPE,
    2948             :                                           acc_granted,
    2949             :                                           r->in.sid,
    2950             :                                           NULL,
    2951             :                                           psd,
    2952             :                                           r->out.acct_handle);
    2953           2 :         if (!NT_STATUS_IS_OK(status)) {
    2954           0 :                 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
    2955             :         }
    2956             : 
    2957           2 :         return privilege_create_account(r->in.sid);
    2958             : }
    2959             : 
    2960             : /***************************************************************************
    2961             :  _lsa_OpenAccount
    2962             :  ***************************************************************************/
    2963             : 
    2964          16 : NTSTATUS _lsa_OpenAccount(struct pipes_struct *p,
    2965             :                           struct lsa_OpenAccount *r)
    2966             : {
    2967          16 :         struct dcesrv_call_state *dce_call = p->dce_call;
    2968           0 :         struct auth_session_info *session_info =
    2969          16 :                 dcesrv_call_session_info(dce_call);
    2970          16 :         struct security_descriptor *psd = NULL;
    2971           0 :         size_t sd_size;
    2972          16 :         uint32_t des_access = r->in.access_mask;
    2973           0 :         uint32_t acc_granted;
    2974          16 :         uint32_t owner_access = (LSA_ACCOUNT_ALL_ACCESS &
    2975             :                         ~(LSA_ACCOUNT_ADJUST_PRIVILEGES|
    2976             :                         LSA_ACCOUNT_ADJUST_SYSTEM_ACCESS|
    2977             :                         SEC_STD_DELETE));
    2978           0 :         NTSTATUS status;
    2979             : 
    2980             :         /* find the connection policy handle. */
    2981          16 :         (void)find_policy_by_hnd(p,
    2982             :                                  r->in.handle,
    2983             :                                  LSA_HANDLE_POLICY_TYPE,
    2984             :                                  struct lsa_info,
    2985           0 :                                  &status);
    2986          16 :         if (!NT_STATUS_IS_OK(status)) {
    2987           0 :                 return NT_STATUS_INVALID_HANDLE;
    2988             :         }
    2989             : 
    2990             :         /* des_access is for the account here, not the policy
    2991             :          * handle - so don't check against policy handle. */
    2992             : 
    2993             :         /* Work out max allowed. */
    2994          16 :         map_max_allowed_access(session_info->security_token,
    2995          16 :                                session_info->unix_token,
    2996             :                                &des_access);
    2997             : 
    2998             :         /* map the generic bits to the lsa account ones */
    2999          16 :         se_map_generic(&des_access, &lsa_account_mapping);
    3000             : 
    3001             :         /* get the generic lsa account SD until we store it */
    3002          16 :         status = make_lsa_object_sd(p->mem_ctx, &psd, &sd_size,
    3003             :                                 &lsa_account_mapping,
    3004             :                                 r->in.sid, owner_access);
    3005          16 :         if (!NT_STATUS_IS_OK(status)) {
    3006           0 :                 return status;
    3007             :         }
    3008             : 
    3009          16 :         status = access_check_object(psd, session_info->security_token,
    3010             :                                      SEC_PRIV_INVALID, SEC_PRIV_INVALID, 0, des_access,
    3011             :                                      &acc_granted, "_lsa_OpenAccount" );
    3012          16 :         if (!NT_STATUS_IS_OK(status)) {
    3013           0 :                 return status;
    3014             :         }
    3015             : 
    3016             :         /* TODO: Fis the parsing routine before reenabling this check! */
    3017             :         #if 0
    3018             :         if (!lookup_sid(&handle->sid, dom_name, name, &type))
    3019             :                 return NT_STATUS_ACCESS_DENIED;
    3020             :         #endif
    3021             : 
    3022          16 :         status = create_lsa_policy_handle(p->mem_ctx, p,
    3023             :                                           LSA_HANDLE_ACCOUNT_TYPE,
    3024             :                                           acc_granted,
    3025             :                                           r->in.sid,
    3026             :                                           NULL,
    3027             :                                           psd,
    3028             :                                           r->out.acct_handle);
    3029          16 :         if (!NT_STATUS_IS_OK(status)) {
    3030           0 :                 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
    3031             :         }
    3032             : 
    3033          16 :         return NT_STATUS_OK;
    3034             : }
    3035             : 
    3036             : /***************************************************************************
    3037             :  _lsa_EnumPrivsAccount
    3038             :  For a given SID, enumerate all the privilege this account has.
    3039             :  ***************************************************************************/
    3040             : 
    3041          28 : NTSTATUS _lsa_EnumPrivsAccount(struct pipes_struct *p,
    3042             :                                struct lsa_EnumPrivsAccount *r)
    3043             : {
    3044          28 :         NTSTATUS status = NT_STATUS_OK;
    3045          28 :         struct lsa_info *info=NULL;
    3046           0 :         PRIVILEGE_SET *privileges;
    3047          28 :         struct lsa_PrivilegeSet *priv_set = NULL;
    3048           0 :         struct dom_sid_buf buf;
    3049             : 
    3050             :         /* find the connection policy handle. */
    3051          28 :         info = find_policy_by_hnd(p,
    3052             :                                   r->in.handle,
    3053             :                                   LSA_HANDLE_ACCOUNT_TYPE,
    3054             :                                   struct lsa_info,
    3055           0 :                                   &status);
    3056          28 :         if (!NT_STATUS_IS_OK(status)) {
    3057           0 :                 return NT_STATUS_INVALID_HANDLE;
    3058             :         }
    3059             : 
    3060          28 :         if (!(info->access & LSA_ACCOUNT_VIEW))
    3061           0 :                 return NT_STATUS_ACCESS_DENIED;
    3062             : 
    3063          28 :         status = get_privileges_for_sid_as_set(p->mem_ctx, &privileges, &info->sid);
    3064          28 :         if (!NT_STATUS_IS_OK(status)) {
    3065           0 :                 return status;
    3066             :         }
    3067             : 
    3068          28 :         *r->out.privs = priv_set = talloc_zero(p->mem_ctx, struct lsa_PrivilegeSet);
    3069          28 :         if (!priv_set) {
    3070           0 :                 return NT_STATUS_NO_MEMORY;
    3071             :         }
    3072             : 
    3073          28 :         DEBUG(10,("_lsa_EnumPrivsAccount: %s has %d privileges\n",
    3074             :                   dom_sid_str_buf(&info->sid, &buf),
    3075             :                   privileges->count));
    3076             : 
    3077          28 :         priv_set->count = privileges->count;
    3078          28 :         priv_set->unknown = 0;
    3079          28 :         priv_set->set = talloc_move(priv_set, &privileges->set);
    3080             : 
    3081          28 :         return status;
    3082             : }
    3083             : 
    3084             : /***************************************************************************
    3085             :  _lsa_GetSystemAccessAccount
    3086             :  ***************************************************************************/
    3087             : 
    3088          16 : NTSTATUS _lsa_GetSystemAccessAccount(struct pipes_struct *p,
    3089             :                                      struct lsa_GetSystemAccessAccount *r)
    3090             : {
    3091           0 :         NTSTATUS status;
    3092          16 :         struct lsa_info *info = NULL;
    3093           0 :         struct lsa_EnumPrivsAccount e;
    3094           0 :         struct lsa_PrivilegeSet *privset;
    3095             : 
    3096             :         /* find the connection policy handle. */
    3097             : 
    3098          16 :         info = find_policy_by_hnd(p,
    3099             :                                   r->in.handle,
    3100             :                                   LSA_HANDLE_ACCOUNT_TYPE,
    3101             :                                   struct lsa_info,
    3102           0 :                                   &status);
    3103          16 :         if (!NT_STATUS_IS_OK(status)) {
    3104           0 :                 return NT_STATUS_INVALID_HANDLE;
    3105             :         }
    3106             : 
    3107          16 :         if (!(info->access & LSA_ACCOUNT_VIEW))
    3108           0 :                 return NT_STATUS_ACCESS_DENIED;
    3109             : 
    3110          16 :         privset = talloc_zero(p->mem_ctx, struct lsa_PrivilegeSet);
    3111          16 :         if (!privset) {
    3112           0 :                 return NT_STATUS_NO_MEMORY;
    3113             :         }
    3114             : 
    3115          16 :         e.in.handle = r->in.handle;
    3116          16 :         e.out.privs = &privset;
    3117             : 
    3118          16 :         status = _lsa_EnumPrivsAccount(p, &e);
    3119          16 :         if (!NT_STATUS_IS_OK(status)) {
    3120           0 :                 DEBUG(10,("_lsa_GetSystemAccessAccount: "
    3121             :                         "failed to call _lsa_EnumPrivsAccount(): %s\n",
    3122             :                         nt_errstr(status)));
    3123           0 :                 return status;
    3124             :         }
    3125             : 
    3126             :         /* Samba4 would iterate over the privset to merge the policy mode bits,
    3127             :          * not sure samba3 can do the same here, so just return what we did in
    3128             :          * the past - gd */
    3129             : 
    3130             :         /*
    3131             :           0x01 -> Log on locally
    3132             :           0x02 -> Access this computer from network
    3133             :           0x04 -> Log on as a batch job
    3134             :           0x10 -> Log on as a service
    3135             : 
    3136             :           they can be ORed together
    3137             :         */
    3138             : 
    3139          16 :         *r->out.access_mask = LSA_POLICY_MODE_INTERACTIVE |
    3140             :                               LSA_POLICY_MODE_NETWORK;
    3141             : 
    3142          16 :         return NT_STATUS_OK;
    3143             : }
    3144             : 
    3145             : /***************************************************************************
    3146             :   update the systemaccount information
    3147             :  ***************************************************************************/
    3148             : 
    3149           0 : NTSTATUS _lsa_SetSystemAccessAccount(struct pipes_struct *p,
    3150             :                                      struct lsa_SetSystemAccessAccount *r)
    3151             : {
    3152           0 :         struct lsa_info *info=NULL;
    3153           0 :         NTSTATUS status;
    3154           0 :         GROUP_MAP *map;
    3155             : 
    3156             :         /* find the connection policy handle. */
    3157           0 :         info = find_policy_by_hnd(p,
    3158             :                                   r->in.handle,
    3159             :                                   LSA_HANDLE_ACCOUNT_TYPE,
    3160             :                                   struct lsa_info,
    3161           0 :                                   &status);
    3162           0 :         if (!NT_STATUS_IS_OK(status)) {
    3163           0 :                 return NT_STATUS_INVALID_HANDLE;
    3164             :         }
    3165             : 
    3166           0 :         if (!(info->access & LSA_ACCOUNT_ADJUST_SYSTEM_ACCESS)) {
    3167           0 :                 return NT_STATUS_ACCESS_DENIED;
    3168             :         }
    3169             : 
    3170           0 :         map = talloc_zero(p->mem_ctx, GROUP_MAP);
    3171           0 :         if (!map) {
    3172           0 :                 return NT_STATUS_NO_MEMORY;
    3173             :         }
    3174             : 
    3175           0 :         if (!pdb_getgrsid(map, info->sid)) {
    3176           0 :                 TALLOC_FREE(map);
    3177           0 :                 return NT_STATUS_NO_SUCH_GROUP;
    3178             :         }
    3179             : 
    3180           0 :         status = pdb_update_group_mapping_entry(map);
    3181           0 :         TALLOC_FREE(map);
    3182           0 :         return status;
    3183             : }
    3184             : 
    3185             : /***************************************************************************
    3186             :  _lsa_AddPrivilegesToAccount
    3187             :  For a given SID, add some privileges.
    3188             :  ***************************************************************************/
    3189             : 
    3190           2 : NTSTATUS _lsa_AddPrivilegesToAccount(struct pipes_struct *p,
    3191             :                                      struct lsa_AddPrivilegesToAccount *r)
    3192             : {
    3193           2 :         struct lsa_info *info = NULL;
    3194           2 :         struct lsa_PrivilegeSet *set = NULL;
    3195           0 :         NTSTATUS status;
    3196             : 
    3197             :         /* find the connection policy handle. */
    3198           2 :         info = find_policy_by_hnd(p,
    3199             :                                   r->in.handle,
    3200             :                                   LSA_HANDLE_ACCOUNT_TYPE,
    3201             :                                   struct lsa_info,
    3202           0 :                                   &status);
    3203           2 :         if (!NT_STATUS_IS_OK(status)) {
    3204           0 :                 return NT_STATUS_INVALID_HANDLE;
    3205             :         }
    3206             : 
    3207           2 :         if (!(info->access & LSA_ACCOUNT_ADJUST_PRIVILEGES)) {
    3208           0 :                 return NT_STATUS_ACCESS_DENIED;
    3209             :         }
    3210             : 
    3211           2 :         set = r->in.privs;
    3212             : 
    3213           2 :         if ( !grant_privilege_set( &info->sid, set ) ) {
    3214           0 :                 struct dom_sid_buf buf;
    3215           0 :                 DEBUG(3,("_lsa_AddPrivilegesToAccount: grant_privilege_set(%s) failed!\n",
    3216             :                          dom_sid_str_buf(&info->sid, &buf)));
    3217           0 :                 return NT_STATUS_NO_SUCH_PRIVILEGE;
    3218             :         }
    3219             : 
    3220           2 :         return NT_STATUS_OK;
    3221             : }
    3222             : 
    3223             : /***************************************************************************
    3224             :  _lsa_RemovePrivilegesFromAccount
    3225             :  For a given SID, remove some privileges.
    3226             :  ***************************************************************************/
    3227             : 
    3228           2 : NTSTATUS _lsa_RemovePrivilegesFromAccount(struct pipes_struct *p,
    3229             :                                           struct lsa_RemovePrivilegesFromAccount *r)
    3230             : {
    3231           2 :         struct lsa_info *info = NULL;
    3232           2 :         struct lsa_PrivilegeSet *set = NULL;
    3233           0 :         NTSTATUS status;
    3234             : 
    3235             :         /* find the connection policy handle. */
    3236           2 :         info = find_policy_by_hnd(p,
    3237             :                                   r->in.handle,
    3238             :                                   LSA_HANDLE_ACCOUNT_TYPE,
    3239             :                                   struct lsa_info,
    3240           0 :                                   &status);
    3241           2 :         if (!NT_STATUS_IS_OK(status)) {
    3242           0 :                 return NT_STATUS_INVALID_HANDLE;
    3243             :         }
    3244             : 
    3245           2 :         if (!(info->access & LSA_ACCOUNT_ADJUST_PRIVILEGES)) {
    3246           0 :                 return NT_STATUS_ACCESS_DENIED;
    3247             :         }
    3248             : 
    3249           2 :         set = r->in.privs;
    3250             : 
    3251           2 :         if ( !revoke_privilege_set( &info->sid, set) ) {
    3252           0 :                 struct dom_sid_buf buf;
    3253           0 :                 DEBUG(3,("_lsa_RemovePrivilegesFromAccount: revoke_privilege(%s) failed!\n",
    3254             :                          dom_sid_str_buf(&info->sid, &buf)));
    3255           0 :                 return NT_STATUS_NO_SUCH_PRIVILEGE;
    3256             :         }
    3257             : 
    3258           2 :         return NT_STATUS_OK;
    3259             : }
    3260             : 
    3261             : /***************************************************************************
    3262             :  _lsa_LookupPrivName
    3263             :  ***************************************************************************/
    3264             : 
    3265          50 : NTSTATUS _lsa_LookupPrivName(struct pipes_struct *p,
    3266             :                              struct lsa_LookupPrivName *r)
    3267             : {
    3268          50 :         struct lsa_info *info = NULL;
    3269           0 :         const char *name;
    3270           0 :         struct lsa_StringLarge *lsa_name;
    3271           0 :         NTSTATUS status;
    3272             : 
    3273             :         /* find the connection policy handle. */
    3274          50 :         info = find_policy_by_hnd(p,
    3275             :                                   r->in.handle,
    3276             :                                   LSA_HANDLE_POLICY_TYPE,
    3277             :                                   struct lsa_info,
    3278           0 :                                   &status);
    3279          50 :         if (!NT_STATUS_IS_OK(status)) {
    3280           0 :                 return NT_STATUS_INVALID_HANDLE;
    3281             :         }
    3282             : 
    3283          50 :         if (!(info->access & LSA_POLICY_VIEW_LOCAL_INFORMATION)) {
    3284           0 :                 return NT_STATUS_ACCESS_DENIED;
    3285             :         }
    3286             : 
    3287          50 :         if (r->in.luid->high != 0) {
    3288           0 :                 return NT_STATUS_NO_SUCH_PRIVILEGE;
    3289             :         }
    3290             : 
    3291          50 :         name = sec_privilege_name(r->in.luid->low);
    3292          50 :         if (!name) {
    3293           0 :                 return NT_STATUS_NO_SUCH_PRIVILEGE;
    3294             :         }
    3295             : 
    3296          50 :         lsa_name = talloc_zero(p->mem_ctx, struct lsa_StringLarge);
    3297          50 :         if (!lsa_name) {
    3298           0 :                 return NT_STATUS_NO_MEMORY;
    3299             :         }
    3300             : 
    3301          50 :         lsa_name->string = talloc_strdup(lsa_name, name);
    3302          50 :         if (!lsa_name->string) {
    3303           0 :                 TALLOC_FREE(lsa_name);
    3304           0 :                 return NT_STATUS_NO_MEMORY;
    3305             :         }
    3306             : 
    3307          50 :         *r->out.name = lsa_name;
    3308             : 
    3309          50 :         return NT_STATUS_OK;
    3310             : }
    3311             : 
    3312             : /***************************************************************************
    3313             :  _lsa_QuerySecurity
    3314             :  ***************************************************************************/
    3315             : 
    3316          12 : NTSTATUS _lsa_QuerySecurity(struct pipes_struct *p,
    3317             :                             struct lsa_QuerySecurity *r)
    3318             : {
    3319          12 :         struct lsa_info *handle=NULL;
    3320          12 :         struct security_descriptor *psd = NULL;
    3321          12 :         size_t sd_size = 0;
    3322           0 :         NTSTATUS status;
    3323             : 
    3324             :         /* find the connection policy handle. */
    3325          12 :         handle = find_policy_by_hnd(p,
    3326             :                                     r->in.handle,
    3327             :                                     DCESRV_HANDLE_ANY,
    3328             :                                     struct lsa_info,
    3329           0 :                                     &status);
    3330          12 :         if (!NT_STATUS_IS_OK(status)) {
    3331           0 :                 return NT_STATUS_INVALID_HANDLE;
    3332             :         }
    3333             : 
    3334          12 :         switch (handle->type) {
    3335          12 :         case LSA_HANDLE_POLICY_TYPE:
    3336             :         case LSA_HANDLE_ACCOUNT_TYPE:
    3337             :         case LSA_HANDLE_TRUST_TYPE:
    3338             :         case LSA_HANDLE_SECRET_TYPE:
    3339          12 :                 psd = handle->sd;
    3340          12 :                 sd_size = ndr_size_security_descriptor(psd, 0);
    3341          12 :                 status = NT_STATUS_OK;
    3342          12 :                 break;
    3343           0 :         default:
    3344           0 :                 status = NT_STATUS_INVALID_HANDLE;
    3345           0 :                 break;
    3346             :         }
    3347             : 
    3348          12 :         if (!NT_STATUS_IS_OK(status)) {
    3349           0 :                 return status;
    3350             :         }
    3351             : 
    3352          12 :         *r->out.sdbuf = make_sec_desc_buf(p->mem_ctx, sd_size, psd);
    3353          12 :         if (!*r->out.sdbuf) {
    3354           0 :                 return NT_STATUS_NO_MEMORY;
    3355             :         }
    3356             : 
    3357          12 :         return status;
    3358             : }
    3359             : 
    3360             : /***************************************************************************
    3361             :  _lsa_AddAccountRights
    3362             :  ***************************************************************************/
    3363             : 
    3364          32 : NTSTATUS _lsa_AddAccountRights(struct pipes_struct *p,
    3365             :                                struct lsa_AddAccountRights *r)
    3366             : {
    3367          32 :         struct dcesrv_call_state *dce_call = p->dce_call;
    3368           0 :         struct auth_session_info *session_info =
    3369          32 :                 dcesrv_call_session_info(dce_call);
    3370          32 :         int i = 0;
    3371          32 :         uint32_t acc_granted = 0;
    3372          32 :         struct security_descriptor *psd = NULL;
    3373           0 :         size_t sd_size;
    3374           0 :         struct dom_sid sid;
    3375           0 :         NTSTATUS status;
    3376             : 
    3377             :         /* find the connection policy handle. */
    3378          32 :         (void)find_policy_by_hnd(p,
    3379             :                                  r->in.handle,
    3380             :                                  LSA_HANDLE_POLICY_TYPE,
    3381             :                                  struct lsa_info,
    3382           0 :                                  &status);
    3383          32 :         if (!NT_STATUS_IS_OK(status)) {
    3384           0 :                 return NT_STATUS_INVALID_HANDLE;
    3385             :         }
    3386             : 
    3387             :         /* get the generic lsa account SD for this SID until we store it */
    3388          32 :         status = make_lsa_object_sd(p->mem_ctx, &psd, &sd_size,
    3389             :                                 &lsa_account_mapping,
    3390             :                                 NULL, 0);
    3391          32 :         if (!NT_STATUS_IS_OK(status)) {
    3392           0 :                 return status;
    3393             :         }
    3394             : 
    3395             :         /*
    3396             :          * From the MS DOCs. If the sid doesn't exist, ask for LSA_POLICY_CREATE_ACCOUNT
    3397             :          * on the policy handle. If it does, ask for
    3398             :          * LSA_ACCOUNT_ADJUST_PRIVILEGES|LSA_ACCOUNT_ADJUST_SYSTEM_ACCESS|LSA_ACCOUNT_VIEW,
    3399             :          * on the account sid. We don't check here so just use the latter. JRA.
    3400             :          */
    3401             : 
    3402          32 :         status = access_check_object(psd, session_info->security_token,
    3403             :                                      SEC_PRIV_INVALID, SEC_PRIV_INVALID, 0,
    3404             :                                      LSA_ACCOUNT_ADJUST_PRIVILEGES|LSA_ACCOUNT_ADJUST_SYSTEM_ACCESS|LSA_ACCOUNT_VIEW,
    3405             :                                      &acc_granted, "_lsa_AddAccountRights" );
    3406          32 :         if (!NT_STATUS_IS_OK(status)) {
    3407           0 :                 return status;
    3408             :         }
    3409             : 
    3410             :         /* according to an NT4 PDC, you can add privileges to SIDs even without
    3411             :            call_lsa_create_account() first.  And you can use any arbitrary SID. */
    3412             : 
    3413          32 :         sid_copy( &sid, r->in.sid );
    3414             : 
    3415          62 :         for ( i=0; i < r->in.rights->count; i++ ) {
    3416             : 
    3417          32 :                 const char *privname = r->in.rights->names[i].string;
    3418             : 
    3419             :                 /* only try to add non-null strings */
    3420             : 
    3421          32 :                 if ( !privname )
    3422           0 :                         continue;
    3423             : 
    3424          32 :                 if ( !grant_privilege_by_name( &sid, privname ) ) {
    3425           2 :                         DEBUG(2,("_lsa_AddAccountRights: Failed to add privilege [%s]\n",
    3426             :                                 privname ));
    3427           2 :                         return NT_STATUS_NO_SUCH_PRIVILEGE;
    3428             :                 }
    3429             :         }
    3430             : 
    3431          30 :         return NT_STATUS_OK;
    3432             : }
    3433             : 
    3434             : /***************************************************************************
    3435             :  _lsa_RemoveAccountRights
    3436             :  ***************************************************************************/
    3437             : 
    3438          26 : NTSTATUS _lsa_RemoveAccountRights(struct pipes_struct *p,
    3439             :                                   struct lsa_RemoveAccountRights *r)
    3440             : {
    3441          26 :         struct dcesrv_call_state *dce_call = p->dce_call;
    3442           0 :         struct auth_session_info *session_info =
    3443          26 :                 dcesrv_call_session_info(dce_call);
    3444          26 :         int i = 0;
    3445          26 :         struct security_descriptor *psd = NULL;
    3446           0 :         size_t sd_size;
    3447           0 :         struct dom_sid sid;
    3448          26 :         const char *privname = NULL;
    3449          26 :         uint32_t acc_granted = 0;
    3450           0 :         NTSTATUS status;
    3451             : 
    3452             :         /* find the connection policy handle. */
    3453          26 :         (void)find_policy_by_hnd(p,
    3454             :                                  r->in.handle,
    3455             :                                  LSA_HANDLE_POLICY_TYPE,
    3456             :                                  struct lsa_info,
    3457           0 :                                  &status);
    3458          26 :         if (!NT_STATUS_IS_OK(status)) {
    3459           0 :                 return NT_STATUS_INVALID_HANDLE;
    3460             :         }
    3461             : 
    3462             :         /* get the generic lsa account SD for this SID until we store it */
    3463          26 :         status = make_lsa_object_sd(p->mem_ctx, &psd, &sd_size,
    3464             :                                 &lsa_account_mapping,
    3465             :                                 NULL, 0);
    3466          26 :         if (!NT_STATUS_IS_OK(status)) {
    3467           0 :                 return status;
    3468             :         }
    3469             : 
    3470             :         /*
    3471             :          * From the MS DOCs. We need
    3472             :          * LSA_ACCOUNT_ADJUST_PRIVILEGES|LSA_ACCOUNT_ADJUST_SYSTEM_ACCESS|LSA_ACCOUNT_VIEW
    3473             :          * and DELETE on the account sid.
    3474             :          */
    3475             : 
    3476          26 :         status = access_check_object(psd, session_info->security_token,
    3477             :                                      SEC_PRIV_INVALID, SEC_PRIV_INVALID, 0,
    3478             :                                      LSA_ACCOUNT_ADJUST_PRIVILEGES|LSA_ACCOUNT_ADJUST_SYSTEM_ACCESS|
    3479             :                                      LSA_ACCOUNT_VIEW|SEC_STD_DELETE,
    3480             :                                      &acc_granted, "_lsa_RemoveAccountRights");
    3481          26 :         if (!NT_STATUS_IS_OK(status)) {
    3482           0 :                 return status;
    3483             :         }
    3484             : 
    3485          26 :         sid_copy( &sid, r->in.sid );
    3486             : 
    3487          26 :         if ( r->in.remove_all ) {
    3488           0 :                 if ( !revoke_all_privileges( &sid ) )
    3489           0 :                         return NT_STATUS_ACCESS_DENIED;
    3490             : 
    3491           0 :                 return NT_STATUS_OK;
    3492             :         }
    3493             : 
    3494          52 :         for ( i=0; i < r->in.rights->count; i++ ) {
    3495             : 
    3496          26 :                 privname = r->in.rights->names[i].string;
    3497             : 
    3498             :                 /* only try to add non-null strings */
    3499             : 
    3500          26 :                 if ( !privname )
    3501           0 :                         continue;
    3502             : 
    3503          26 :                 if ( !revoke_privilege_by_name( &sid, privname ) ) {
    3504           0 :                         DEBUG(2,("_lsa_RemoveAccountRights: Failed to revoke privilege [%s]\n",
    3505             :                                 privname ));
    3506           0 :                         return NT_STATUS_NO_SUCH_PRIVILEGE;
    3507             :                 }
    3508             :         }
    3509             : 
    3510          26 :         return NT_STATUS_OK;
    3511             : }
    3512             : 
    3513             : /*******************************************************************
    3514             : ********************************************************************/
    3515             : 
    3516          16 : static NTSTATUS init_lsa_right_set(TALLOC_CTX *mem_ctx,
    3517             :                                    struct lsa_RightSet *r,
    3518             :                                    PRIVILEGE_SET *privileges)
    3519             : {
    3520           0 :         uint32_t i;
    3521           0 :         const char *privname;
    3522          16 :         const char **privname_array = NULL;
    3523          16 :         size_t num_priv = 0;
    3524             : 
    3525          70 :         for (i=0; i<privileges->count; i++) {
    3526          54 :                 if (privileges->set[i].luid.high) {
    3527           0 :                         continue;
    3528             :                 }
    3529          54 :                 privname = sec_privilege_name(privileges->set[i].luid.low);
    3530          54 :                 if (privname) {
    3531          54 :                         if (!add_string_to_array(mem_ctx, privname,
    3532             :                                                  &privname_array, &num_priv)) {
    3533           0 :                                 return NT_STATUS_NO_MEMORY;
    3534             :                         }
    3535             :                 }
    3536             :         }
    3537             : 
    3538          16 :         if (num_priv) {
    3539             : 
    3540           6 :                 r->names = talloc_zero_array(mem_ctx, struct lsa_StringLarge,
    3541             :                                              num_priv);
    3542           6 :                 if (!r->names) {
    3543           0 :                         return NT_STATUS_NO_MEMORY;
    3544             :                 }
    3545             : 
    3546          60 :                 for (i=0; i<num_priv; i++) {
    3547          54 :                         init_lsa_StringLarge(&r->names[i], privname_array[i]);
    3548             :                 }
    3549             : 
    3550           6 :                 r->count = num_priv;
    3551             :         }
    3552             : 
    3553          16 :         return NT_STATUS_OK;
    3554             : }
    3555             : 
    3556             : /***************************************************************************
    3557             :  _lsa_EnumAccountRights
    3558             :  ***************************************************************************/
    3559             : 
    3560         116 : NTSTATUS _lsa_EnumAccountRights(struct pipes_struct *p,
    3561             :                                 struct lsa_EnumAccountRights *r)
    3562             : {
    3563           0 :         NTSTATUS status;
    3564         116 :         struct lsa_info *info = NULL;
    3565           0 :         PRIVILEGE_SET *privileges;
    3566           0 :         struct dom_sid_buf buf;
    3567             : 
    3568             :         /* find the connection policy handle. */
    3569             : 
    3570         116 :         info = find_policy_by_hnd(p,
    3571             :                                   r->in.handle,
    3572             :                                   LSA_HANDLE_POLICY_TYPE,
    3573             :                                   struct lsa_info,
    3574           0 :                                   &status);
    3575         116 :         if (!NT_STATUS_IS_OK(status)) {
    3576           0 :                 return NT_STATUS_INVALID_HANDLE;
    3577             :         }
    3578             : 
    3579         116 :         if (!(info->access & LSA_ACCOUNT_VIEW)) {
    3580           0 :                 return NT_STATUS_ACCESS_DENIED;
    3581             :         }
    3582             : 
    3583             :         /* according to an NT4 PDC, you can add privileges to SIDs even without
    3584             :            call_lsa_create_account() first.  And you can use any arbitrary SID. */
    3585             : 
    3586             :         /* according to MS-LSAD 3.1.4.5.10 it is required to return
    3587             :          * NT_STATUS_OBJECT_NAME_NOT_FOUND if the account sid was not found in
    3588             :          * the lsa database */
    3589             : 
    3590         116 :         status = get_privileges_for_sid_as_set(p->mem_ctx, &privileges, r->in.sid);
    3591         116 :         if (!NT_STATUS_IS_OK(status)) {
    3592         100 :                 return status;
    3593             :         }
    3594             : 
    3595          16 :         DEBUG(10,("_lsa_EnumAccountRights: %s has %d privileges\n",
    3596             :                   dom_sid_str_buf(r->in.sid, &buf),
    3597             :                   privileges->count));
    3598             : 
    3599          16 :         status = init_lsa_right_set(p->mem_ctx, r->out.rights, privileges);
    3600             : 
    3601          16 :         return status;
    3602             : }
    3603             : 
    3604             : /***************************************************************************
    3605             :  _lsa_LookupPrivValue
    3606             :  ***************************************************************************/
    3607             : 
    3608          20 : NTSTATUS _lsa_LookupPrivValue(struct pipes_struct *p,
    3609             :                               struct lsa_LookupPrivValue *r)
    3610             : {
    3611          20 :         struct lsa_info *info = NULL;
    3612          20 :         const char *name = NULL;
    3613           0 :         NTSTATUS status;
    3614             : 
    3615             :         /* find the connection policy handle. */
    3616             : 
    3617          20 :         info = find_policy_by_hnd(p,
    3618             :                                   r->in.handle,
    3619             :                                   LSA_HANDLE_POLICY_TYPE,
    3620             :                                   struct lsa_info,
    3621           0 :                                   &status);
    3622          20 :         if (!NT_STATUS_IS_OK(status)) {
    3623           0 :                 return NT_STATUS_INVALID_HANDLE;
    3624             :         }
    3625             : 
    3626          20 :         if (!(info->access & LSA_POLICY_LOOKUP_NAMES))
    3627           0 :                 return NT_STATUS_ACCESS_DENIED;
    3628             : 
    3629          20 :         name = r->in.name->string;
    3630             : 
    3631          20 :         DEBUG(10,("_lsa_lookup_priv_value: name = %s\n", name));
    3632             : 
    3633          20 :         r->out.luid->low = sec_privilege_id(name);
    3634          20 :         r->out.luid->high = 0;
    3635          20 :         if (r->out.luid->low == SEC_PRIV_INVALID) {
    3636           0 :                 return NT_STATUS_NO_SUCH_PRIVILEGE;
    3637             :         }
    3638          20 :         return NT_STATUS_OK;
    3639             : }
    3640             : 
    3641             : /***************************************************************************
    3642             :  _lsa_EnumAccountsWithUserRight
    3643             :  ***************************************************************************/
    3644             : 
    3645          18 : NTSTATUS _lsa_EnumAccountsWithUserRight(struct pipes_struct *p,
    3646             :                                         struct lsa_EnumAccountsWithUserRight *r)
    3647             : {
    3648           0 :         NTSTATUS status;
    3649          18 :         struct lsa_info *info = NULL;
    3650          18 :         struct dom_sid *sids = NULL;
    3651          18 :         int num_sids = 0;
    3652           0 :         uint32_t i;
    3653           0 :         enum sec_privilege privilege;
    3654             : 
    3655          18 :         info = find_policy_by_hnd(p,
    3656             :                                   r->in.handle,
    3657             :                                   LSA_HANDLE_POLICY_TYPE,
    3658             :                                   struct lsa_info,
    3659           0 :                                   &status);
    3660          18 :         if (!NT_STATUS_IS_OK(status)) {
    3661           0 :                 return NT_STATUS_INVALID_HANDLE;
    3662             :         }
    3663             : 
    3664          18 :         if (!(info->access & LSA_POLICY_LOOKUP_NAMES)) {
    3665           0 :                 return NT_STATUS_ACCESS_DENIED;
    3666             :         }
    3667             : 
    3668          18 :         if (!r->in.name || !r->in.name->string) {
    3669           0 :                 return NT_STATUS_NO_SUCH_PRIVILEGE;
    3670             :         }
    3671             : 
    3672          18 :         privilege = sec_privilege_id(r->in.name->string);
    3673          18 :         if (privilege == SEC_PRIV_INVALID) {
    3674           0 :                 return NT_STATUS_NO_SUCH_PRIVILEGE;
    3675             :         }
    3676             : 
    3677          18 :         status = privilege_enum_sids(privilege, p->mem_ctx,
    3678             :                                      &sids, &num_sids);
    3679          18 :         if (!NT_STATUS_IS_OK(status)) {
    3680           0 :                 return status;
    3681             :         }
    3682             : 
    3683          18 :         r->out.sids->num_sids = num_sids;
    3684          18 :         r->out.sids->sids = talloc_array(p->mem_ctx, struct lsa_SidPtr,
    3685             :                                          r->out.sids->num_sids);
    3686             : 
    3687          36 :         for (i=0; i < r->out.sids->num_sids; i++) {
    3688          36 :                 r->out.sids->sids[i].sid = dom_sid_dup(r->out.sids->sids,
    3689          18 :                                                           &sids[i]);
    3690          18 :                 if (!r->out.sids->sids[i].sid) {
    3691           0 :                         TALLOC_FREE(r->out.sids->sids);
    3692           0 :                         r->out.sids->num_sids = 0;
    3693           0 :                         return NT_STATUS_NO_MEMORY;
    3694             :                 }
    3695             :         }
    3696             : 
    3697          18 :         return NT_STATUS_OK;
    3698             : }
    3699             : 
    3700             : /***************************************************************************
    3701             :  _lsa_Delete
    3702             :  ***************************************************************************/
    3703             : 
    3704           8 : NTSTATUS _lsa_Delete(struct pipes_struct *p,
    3705             :                      struct lsa_Delete *r)
    3706             : {
    3707           8 :         return NT_STATUS_NOT_SUPPORTED;
    3708             : }
    3709             : 
    3710           0 : static NTSTATUS info_ex_2_pdb_trusted_domain(
    3711             :                                       struct lsa_TrustDomainInfoInfoEx *info_ex,
    3712             :                                       struct pdb_trusted_domain *td)
    3713             : {
    3714           0 :         if (info_ex->domain_name.string == NULL ||
    3715           0 :             info_ex->netbios_name.string == NULL ||
    3716           0 :             info_ex->sid == NULL) {
    3717           0 :                 return NT_STATUS_INVALID_PARAMETER;
    3718             :         }
    3719             : 
    3720           0 :         td->domain_name = talloc_strdup(td, info_ex->domain_name.string);
    3721           0 :         td->netbios_name = talloc_strdup(td, info_ex->netbios_name.string);
    3722           0 :         sid_copy(&td->security_identifier, info_ex->sid);
    3723           0 :         if (td->domain_name == NULL ||
    3724           0 :             td->netbios_name == NULL ||
    3725           0 :             is_null_sid(&td->security_identifier)) {
    3726           0 :                 return NT_STATUS_NO_MEMORY;
    3727             :         }
    3728           0 :         td->trust_direction = info_ex->trust_direction;
    3729           0 :         td->trust_type = info_ex->trust_type;
    3730           0 :         td->trust_attributes = info_ex->trust_attributes;
    3731             : 
    3732           0 :         return NT_STATUS_OK;
    3733             : }
    3734             : 
    3735           0 : static NTSTATUS setInfoTrustedDomain_base(struct pipes_struct *p,
    3736             :                                           TALLOC_CTX *mem_ctx,
    3737             :                                           struct lsa_info *policy,
    3738             :                                           enum lsa_TrustDomInfoEnum level,
    3739             :                                           union lsa_TrustedDomainInfo *info)
    3740             : {
    3741           0 :         struct lsa_TrustDomainInfoAuthInfoInternal *auth_info_int = NULL;
    3742           0 :         DATA_BLOB auth_blob;
    3743           0 :         struct trustDomainPasswords auth_struct;
    3744           0 :         NTSTATUS nt_status;
    3745             : 
    3746           0 :         struct pdb_trusted_domain *td;
    3747           0 :         struct pdb_trusted_domain *orig_td;
    3748             : 
    3749           0 :         td = talloc_zero(mem_ctx, struct pdb_trusted_domain);
    3750           0 :         if (td == NULL) {
    3751           0 :                 return NT_STATUS_NO_MEMORY;
    3752             :         }
    3753             : 
    3754           0 :         switch (level) {
    3755           0 :         case LSA_TRUSTED_DOMAIN_INFO_POSIX_OFFSET:
    3756           0 :                 if (!(policy->access & LSA_TRUSTED_SET_POSIX)) {
    3757           0 :                         return NT_STATUS_ACCESS_DENIED;
    3758             :                 }
    3759           0 :                 td->trust_posix_offset = &info->posix_offset.posix_offset;
    3760           0 :                 break;
    3761           0 :         case LSA_TRUSTED_DOMAIN_INFO_INFO_EX:
    3762           0 :                 if (!(policy->access & LSA_TRUSTED_SET_POSIX)) {
    3763           0 :                         return NT_STATUS_ACCESS_DENIED;
    3764             :                 }
    3765           0 :                 nt_status = info_ex_2_pdb_trusted_domain(&info->info_ex, td);
    3766           0 :                 if (!NT_STATUS_IS_OK(nt_status)) {
    3767           0 :                         return nt_status;
    3768             :                 }
    3769           0 :                 break;
    3770           0 :         case LSA_TRUSTED_DOMAIN_INFO_AUTH_INFO:
    3771           0 :                 if (!(policy->access & LSA_TRUSTED_SET_AUTH)) {
    3772           0 :                         return NT_STATUS_ACCESS_DENIED;
    3773             :                 }
    3774           0 :                 nt_status = auth_info_2_auth_blob(td, &info->auth_info,
    3775             :                                                   &td->trust_auth_incoming,
    3776             :                                                   &td->trust_auth_outgoing);
    3777           0 :                 if (!NT_STATUS_IS_OK(nt_status)) {
    3778           0 :                         return nt_status;
    3779             :                 }
    3780           0 :                 break;
    3781           0 :         case LSA_TRUSTED_DOMAIN_INFO_FULL_INFO:
    3782           0 :                 if (!(policy->access & (LSA_TRUSTED_SET_AUTH | LSA_TRUSTED_SET_POSIX))) {
    3783           0 :                         return NT_STATUS_ACCESS_DENIED;
    3784             :                 }
    3785           0 :                 td->trust_posix_offset = &info->full_info.posix_offset.posix_offset;
    3786           0 :                 nt_status = info_ex_2_pdb_trusted_domain(&info->full_info.info_ex,
    3787             :                                                          td);
    3788           0 :                 if (!NT_STATUS_IS_OK(nt_status)) {
    3789           0 :                         return nt_status;
    3790             :                 }
    3791           0 :                 nt_status = auth_info_2_auth_blob(td,
    3792             :                                                   &info->full_info.auth_info,
    3793             :                                                   &td->trust_auth_incoming,
    3794             :                                                   &td->trust_auth_outgoing);
    3795           0 :                 if (!NT_STATUS_IS_OK(nt_status)) {
    3796           0 :                         return nt_status;
    3797             :                 }
    3798           0 :                 break;
    3799           0 :         case LSA_TRUSTED_DOMAIN_INFO_AUTH_INFO_INTERNAL:
    3800           0 :                 if (!(policy->access & LSA_TRUSTED_SET_AUTH)) {
    3801           0 :                         return NT_STATUS_ACCESS_DENIED;
    3802             :                 }
    3803           0 :                 auth_info_int = &info->auth_info_internal;
    3804           0 :                 break;
    3805           0 :         case LSA_TRUSTED_DOMAIN_INFO_FULL_INFO_INTERNAL:
    3806           0 :                 if (!(policy->access & (LSA_TRUSTED_SET_AUTH | LSA_TRUSTED_SET_POSIX))) {
    3807           0 :                         return NT_STATUS_ACCESS_DENIED;
    3808             :                 }
    3809           0 :                 td->trust_posix_offset = &info->full_info_internal.posix_offset.posix_offset;
    3810           0 :                 nt_status = info_ex_2_pdb_trusted_domain(&info->full_info_internal.info_ex,
    3811             :                                                          td);
    3812           0 :                 if (!NT_STATUS_IS_OK(nt_status)) {
    3813           0 :                         return nt_status;
    3814             :                 }
    3815           0 :                 auth_info_int = &info->full_info_internal.auth_info;
    3816           0 :                 break;
    3817           0 :         case LSA_TRUSTED_DOMAIN_SUPPORTED_ENCRYPTION_TYPES:
    3818           0 :                 if (!(policy->access & LSA_TRUSTED_SET_POSIX)) {
    3819           0 :                         return NT_STATUS_ACCESS_DENIED;
    3820             :                 }
    3821           0 :                 td->supported_enc_type = &info->enc_types.enc_types;
    3822           0 :                 break;
    3823           0 :         default:
    3824           0 :                 return NT_STATUS_INVALID_PARAMETER;
    3825             :         }
    3826             : 
    3827             :         /* decode auth_info_int if set */
    3828           0 :         if (auth_info_int) {
    3829             : 
    3830             :                 /* now decrypt blob */
    3831           0 :                 auth_blob = data_blob_const(auth_info_int->auth_blob.data,
    3832           0 :                                             auth_info_int->auth_blob.size);
    3833             : 
    3834           0 :                 nt_status = get_trustdom_auth_blob(p, mem_ctx,
    3835             :                                                    &auth_blob, &auth_struct);
    3836           0 :                 if (!NT_STATUS_IS_OK(nt_status)) {
    3837           0 :                         return nt_status;
    3838             :                 }
    3839             :         } else {
    3840           0 :             memset(&auth_struct, 0, sizeof(auth_struct));
    3841             :         }
    3842             : 
    3843             : /* TODO: verify only one object matches the dns/netbios/sid triplet and that
    3844             :  * this is the one we already have */
    3845             : 
    3846             : /* TODO: check if the trust direction is changed and we need to add or remove
    3847             :  * auth data */
    3848             : 
    3849             : /* TODO: check if trust type shall be changed and return an error in this case
    3850             :  * */
    3851           0 :         nt_status = pdb_get_trusted_domain_by_sid(p->mem_ctx, &policy->sid,
    3852             :                                                &orig_td);
    3853           0 :         if (!NT_STATUS_IS_OK(nt_status)) {
    3854           0 :                 return nt_status;
    3855             :         }
    3856             : 
    3857             : 
    3858             :         /* TODO: should we fetch previous values from the existing entry
    3859             :          * and append them ? */
    3860           0 :         if (auth_struct.incoming.count) {
    3861           0 :                 nt_status = get_trustauth_inout_blob(mem_ctx,
    3862             :                                                      &auth_struct.incoming,
    3863             :                                                      &td->trust_auth_incoming);
    3864           0 :                 if (!NT_STATUS_IS_OK(nt_status)) {
    3865           0 :                         return nt_status;
    3866             :                 }
    3867             :         } else {
    3868           0 :                 ZERO_STRUCT(td->trust_auth_incoming);
    3869             :         }
    3870             : 
    3871           0 :         if (auth_struct.outgoing.count) {
    3872           0 :                 nt_status = get_trustauth_inout_blob(mem_ctx,
    3873             :                                                      &auth_struct.outgoing,
    3874             :                                                      &td->trust_auth_outgoing);
    3875           0 :                 if (!NT_STATUS_IS_OK(nt_status)) {
    3876           0 :                         return nt_status;
    3877             :                 }
    3878             :         } else {
    3879           0 :                 ZERO_STRUCT(td->trust_auth_outgoing);
    3880             :         }
    3881             : 
    3882           0 :         nt_status = pdb_set_trusted_domain(orig_td->domain_name, td);
    3883           0 :         if (!NT_STATUS_IS_OK(nt_status)) {
    3884           0 :                 return nt_status;
    3885             :         }
    3886             : 
    3887           0 :         return NT_STATUS_OK;
    3888             : }
    3889             : 
    3890           0 : NTSTATUS _lsa_SetTrustedDomainInfo(struct pipes_struct *p,
    3891             :                                    struct lsa_SetTrustedDomainInfo *r)
    3892             : {
    3893           0 :         NTSTATUS status;
    3894           0 :         struct policy_handle trustdom_handle;
    3895           0 :         struct lsa_OpenTrustedDomain o;
    3896           0 :         struct lsa_SetInformationTrustedDomain s;
    3897           0 :         struct lsa_Close c;
    3898             : 
    3899           0 :         o.in.handle             = r->in.handle;
    3900           0 :         o.in.sid                = r->in.dom_sid;
    3901           0 :         o.in.access_mask        = SEC_FLAG_MAXIMUM_ALLOWED;
    3902           0 :         o.out.trustdom_handle   = &trustdom_handle;
    3903             : 
    3904           0 :         status = _lsa_OpenTrustedDomain(p, &o);
    3905           0 :         if (!NT_STATUS_IS_OK(status)) {
    3906           0 :                 return status;
    3907             :         }
    3908             : 
    3909           0 :         s.in.trustdom_handle    = &trustdom_handle;
    3910           0 :         s.in.level              = r->in.level;
    3911           0 :         s.in.info               = r->in.info;
    3912             : 
    3913           0 :         status = _lsa_SetInformationTrustedDomain(p, &s);
    3914           0 :         if (!NT_STATUS_IS_OK(status)) {
    3915           0 :                 return status;
    3916             :         }
    3917             : 
    3918           0 :         c.in.handle             = &trustdom_handle;
    3919           0 :         c.out.handle            = &trustdom_handle;
    3920             : 
    3921           0 :         return _lsa_Close(p, &c);
    3922             : }
    3923             : 
    3924           0 : NTSTATUS _lsa_SetTrustedDomainInfoByName(struct pipes_struct *p,
    3925             :                                          struct lsa_SetTrustedDomainInfoByName *r)
    3926             : {
    3927           0 :         NTSTATUS status;
    3928           0 :         struct policy_handle trustdom_handle;
    3929           0 :         struct lsa_OpenTrustedDomainByName o;
    3930           0 :         struct lsa_SetInformationTrustedDomain s;
    3931           0 :         struct lsa_Close c;
    3932             : 
    3933           0 :         o.in.handle             = r->in.handle;
    3934           0 :         o.in.name.string        = r->in.trusted_domain->string;
    3935           0 :         o.in.access_mask        = SEC_FLAG_MAXIMUM_ALLOWED;
    3936           0 :         o.out.trustdom_handle   = &trustdom_handle;
    3937             : 
    3938           0 :         status = _lsa_OpenTrustedDomainByName(p, &o);
    3939           0 :         if (!NT_STATUS_IS_OK(status)) {
    3940           0 :                 if (NT_STATUS_EQUAL(status, NT_STATUS_NO_SUCH_DOMAIN)) {
    3941           0 :                         return NT_STATUS_OBJECT_NAME_NOT_FOUND;
    3942             :                 }
    3943           0 :                 return status;
    3944             :         }
    3945             : 
    3946           0 :         s.in.trustdom_handle    = &trustdom_handle;
    3947           0 :         s.in.level              = r->in.level;
    3948           0 :         s.in.info               = r->in.info;
    3949             : 
    3950           0 :         status = _lsa_SetInformationTrustedDomain(p, &s);
    3951           0 :         if (!NT_STATUS_IS_OK(status)) {
    3952           0 :                 return status;
    3953             :         }
    3954             : 
    3955           0 :         c.in.handle             = &trustdom_handle;
    3956           0 :         c.out.handle            = &trustdom_handle;
    3957             : 
    3958           0 :         return _lsa_Close(p, &c);
    3959             : }
    3960             : 
    3961           0 : NTSTATUS _lsa_SetInformationTrustedDomain(struct pipes_struct *p,
    3962             :                                           struct lsa_SetInformationTrustedDomain *r)
    3963             : {
    3964           0 :         struct lsa_info *policy;
    3965           0 :         NTSTATUS status;
    3966             : 
    3967           0 :         policy = find_policy_by_hnd(p,
    3968             :                                     r->in.trustdom_handle,
    3969             :                                     LSA_HANDLE_TRUST_TYPE,
    3970             :                                     struct lsa_info,
    3971           0 :                                     &status);
    3972           0 :         if (!NT_STATUS_IS_OK(status)) {
    3973           0 :                 return NT_STATUS_INVALID_HANDLE;
    3974             :         }
    3975             : 
    3976           0 :         return setInfoTrustedDomain_base(p, p->mem_ctx, policy,
    3977             :                                          r->in.level, r->in.info);
    3978             : }
    3979             : 
    3980             : 
    3981             : /*
    3982             :  * From here on the server routines are just dummy ones to make smbd link with
    3983             :  * librpc/gen_ndr/srv_lsa.c. These routines are actually never called, we are
    3984             :  * pulling the server stubs across one by one.
    3985             :  */
    3986             : 
    3987           0 : NTSTATUS _lsa_SetSecObj(struct pipes_struct *p, struct lsa_SetSecObj *r)
    3988             : {
    3989           0 :         p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
    3990           0 :         return NT_STATUS_NOT_IMPLEMENTED;
    3991             : }
    3992             : 
    3993           0 : NTSTATUS _lsa_ChangePassword(struct pipes_struct *p,
    3994             :                              struct lsa_ChangePassword *r)
    3995             : {
    3996           0 :         p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
    3997           0 :         return NT_STATUS_NOT_IMPLEMENTED;
    3998             : }
    3999             : 
    4000           0 : NTSTATUS _lsa_SetInfoPolicy(struct pipes_struct *p, struct lsa_SetInfoPolicy *r)
    4001             : {
    4002           0 :         p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
    4003           0 :         return NT_STATUS_NOT_IMPLEMENTED;
    4004             : }
    4005             : 
    4006           0 : NTSTATUS _lsa_ClearAuditLog(struct pipes_struct *p, struct lsa_ClearAuditLog *r)
    4007             : {
    4008           0 :         p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
    4009           0 :         return NT_STATUS_NOT_IMPLEMENTED;
    4010             : }
    4011             : 
    4012           0 : NTSTATUS _lsa_GetQuotasForAccount(struct pipes_struct *p,
    4013             :                                   struct lsa_GetQuotasForAccount *r)
    4014             : {
    4015           0 :         p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
    4016           0 :         return NT_STATUS_NOT_IMPLEMENTED;
    4017             : }
    4018             : 
    4019           0 : NTSTATUS _lsa_SetQuotasForAccount(struct pipes_struct *p,
    4020             :                                   struct lsa_SetQuotasForAccount *r)
    4021             : {
    4022           0 :         p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
    4023           0 :         return NT_STATUS_NOT_IMPLEMENTED;
    4024             : }
    4025             : 
    4026           0 : NTSTATUS _lsa_StorePrivateData(struct pipes_struct *p,
    4027             :                                struct lsa_StorePrivateData *r)
    4028             : {
    4029           0 :         p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
    4030           0 :         return NT_STATUS_NOT_IMPLEMENTED;
    4031             : }
    4032             : 
    4033           0 : NTSTATUS _lsa_RetrievePrivateData(struct pipes_struct *p,
    4034             :                                   struct lsa_RetrievePrivateData *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_SetInfoPolicy2(struct pipes_struct *p,
    4041             :                              struct lsa_SetInfoPolicy2 *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_EnumTrustedDomainsEx(struct pipes_struct *p,
    4048             :                                    struct lsa_EnumTrustedDomainsEx *r)
    4049             : {
    4050           0 :         struct lsa_info *info;
    4051           0 :         uint32_t count;
    4052           0 :         struct pdb_trusted_domain **domains;
    4053           0 :         struct lsa_TrustDomainInfoInfoEx *entries;
    4054           0 :         int i;
    4055           0 :         NTSTATUS nt_status;
    4056             : 
    4057             :         /* bail out early if pdb backend is not capable of ex trusted domains,
    4058             :          * if we don't do that, the client might not call
    4059             :          * _lsa_EnumTrustedDomains() afterwards - gd */
    4060             : 
    4061           0 :         if (!(pdb_capabilities() & PDB_CAP_TRUSTED_DOMAINS_EX)) {
    4062           0 :                 p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
    4063           0 :                 return NT_STATUS_NOT_IMPLEMENTED;
    4064             :         }
    4065             : 
    4066           0 :         info = find_policy_by_hnd(p,
    4067             :                                   r->in.handle,
    4068             :                                   LSA_HANDLE_POLICY_TYPE,
    4069             :                                   struct lsa_info,
    4070           0 :                                   &nt_status);
    4071           0 :         if (!NT_STATUS_IS_OK(nt_status)) {
    4072           0 :                 return NT_STATUS_INVALID_HANDLE;
    4073             :         }
    4074             : 
    4075             :         /* check if the user has enough rights */
    4076           0 :         if (!(info->access & LSA_POLICY_VIEW_LOCAL_INFORMATION))
    4077           0 :                 return NT_STATUS_ACCESS_DENIED;
    4078             : 
    4079           0 :         become_root();
    4080           0 :         nt_status = pdb_enum_trusted_domains(p->mem_ctx, &count, &domains);
    4081           0 :         unbecome_root();
    4082             : 
    4083           0 :         if (!NT_STATUS_IS_OK(nt_status)) {
    4084           0 :                 return nt_status;
    4085             :         }
    4086             : 
    4087           0 :         entries = talloc_zero_array(p->mem_ctx, struct lsa_TrustDomainInfoInfoEx,
    4088             :                                     count);
    4089           0 :         if (!entries) {
    4090           0 :                 return NT_STATUS_NO_MEMORY;
    4091             :         }
    4092             : 
    4093           0 :         for (i=0; i<count; i++) {
    4094           0 :                 init_lsa_StringLarge(&entries[i].domain_name,
    4095           0 :                                      domains[i]->domain_name);
    4096           0 :                 init_lsa_StringLarge(&entries[i].netbios_name,
    4097           0 :                                      domains[i]->netbios_name);
    4098           0 :                 entries[i].sid = &domains[i]->security_identifier;
    4099           0 :                 entries[i].trust_direction = domains[i]->trust_direction;
    4100           0 :                 entries[i].trust_type = domains[i]->trust_type;
    4101           0 :                 entries[i].trust_attributes = domains[i]->trust_attributes;
    4102             :         }
    4103             : 
    4104           0 :         if (*r->in.resume_handle >= count) {
    4105           0 :                 *r->out.resume_handle = -1;
    4106           0 :                 TALLOC_FREE(entries);
    4107           0 :                 return NT_STATUS_NO_MORE_ENTRIES;
    4108             :         }
    4109             : 
    4110             :         /* return the rest, limit by max_size. Note that we
    4111             :            use the w2k3 element size value of 60 */
    4112           0 :         r->out.domains->count = count - *r->in.resume_handle;
    4113           0 :         r->out.domains->count = MIN(r->out.domains->count,
    4114             :                                     (r->in.max_size/LSA_ENUM_TRUST_DOMAIN_EX_MULTIPLIER));
    4115             : 
    4116           0 :         r->out.domains->domains = entries + *r->in.resume_handle;
    4117             : 
    4118           0 :         if (r->out.domains->count < count - *r->in.resume_handle) {
    4119           0 :                 *r->out.resume_handle = *r->in.resume_handle + r->out.domains->count;
    4120           0 :                 return STATUS_MORE_ENTRIES;
    4121             :         }
    4122             : 
    4123             :         /* according to MS-LSAD 3.1.4.7.8 output resume handle MUST
    4124             :          * always be larger than the previous input resume handle, in
    4125             :          * particular when hitting the last query it is vital to set the
    4126             :          * resume handle correctly to avoid infinite client loops, as
    4127             :          * seen e.g. with Windows XP SP3 when resume handle is 0 and
    4128             :          * status is NT_STATUS_OK - gd */
    4129             : 
    4130           0 :         *r->out.resume_handle = (uint32_t)-1;
    4131             : 
    4132           0 :         return NT_STATUS_OK;
    4133             : }
    4134             : 
    4135           0 : NTSTATUS _lsa_QueryDomainInformationPolicy(struct pipes_struct *p,
    4136             :                                            struct lsa_QueryDomainInformationPolicy *r)
    4137             : {
    4138           0 :         p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
    4139           0 :         return NT_STATUS_NOT_IMPLEMENTED;
    4140             : }
    4141             : 
    4142           0 : NTSTATUS _lsa_SetDomainInformationPolicy(struct pipes_struct *p,
    4143             :                                          struct lsa_SetDomainInformationPolicy *r)
    4144             : {
    4145           0 :         p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
    4146           0 :         return NT_STATUS_NOT_IMPLEMENTED;
    4147             : }
    4148             : 
    4149           0 : NTSTATUS _lsa_TestCall(struct pipes_struct *p, struct lsa_TestCall *r)
    4150             : {
    4151           0 :         p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
    4152           0 :         return NT_STATUS_NOT_IMPLEMENTED;
    4153             : }
    4154             : 
    4155           0 : NTSTATUS _lsa_CREDRWRITE(struct pipes_struct *p, struct lsa_CREDRWRITE *r)
    4156             : {
    4157           0 :         p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
    4158           0 :         return NT_STATUS_NOT_IMPLEMENTED;
    4159             : }
    4160             : 
    4161           0 : NTSTATUS _lsa_CREDRREAD(struct pipes_struct *p, struct lsa_CREDRREAD *r)
    4162             : {
    4163           0 :         p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
    4164           0 :         return NT_STATUS_NOT_IMPLEMENTED;
    4165             : }
    4166             : 
    4167           0 : NTSTATUS _lsa_CREDRENUMERATE(struct pipes_struct *p, struct lsa_CREDRENUMERATE *r)
    4168             : {
    4169           0 :         p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
    4170           0 :         return NT_STATUS_NOT_IMPLEMENTED;
    4171             : }
    4172             : 
    4173           0 : NTSTATUS _lsa_CREDRWRITEDOMAINCREDENTIALS(struct pipes_struct *p,
    4174             :                                           struct lsa_CREDRWRITEDOMAINCREDENTIALS *r)
    4175             : {
    4176           0 :         p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
    4177           0 :         return NT_STATUS_NOT_IMPLEMENTED;
    4178             : }
    4179             : 
    4180           0 : NTSTATUS _lsa_CREDRREADDOMAINCREDENTIALS(struct pipes_struct *p,
    4181             :                                          struct lsa_CREDRREADDOMAINCREDENTIALS *r)
    4182             : {
    4183           0 :         p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
    4184           0 :         return NT_STATUS_NOT_IMPLEMENTED;
    4185             : }
    4186             : 
    4187           0 : NTSTATUS _lsa_CREDRDELETE(struct pipes_struct *p, struct lsa_CREDRDELETE *r)
    4188             : {
    4189           0 :         p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
    4190           0 :         return NT_STATUS_NOT_IMPLEMENTED;
    4191             : }
    4192             : 
    4193           0 : NTSTATUS _lsa_CREDRGETTARGETINFO(struct pipes_struct *p,
    4194             :                                  struct lsa_CREDRGETTARGETINFO *r)
    4195             : {
    4196           0 :         p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
    4197           0 :         return NT_STATUS_NOT_IMPLEMENTED;
    4198             : }
    4199             : 
    4200           0 : NTSTATUS _lsa_CREDRPROFILELOADED(struct pipes_struct *p,
    4201             :                                  struct lsa_CREDRPROFILELOADED *r)
    4202             : {
    4203           0 :         p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
    4204           0 :         return NT_STATUS_NOT_IMPLEMENTED;
    4205             : }
    4206             : 
    4207           0 : NTSTATUS _lsa_CREDRGETSESSIONTYPES(struct pipes_struct *p,
    4208             :                                    struct lsa_CREDRGETSESSIONTYPES *r)
    4209             : {
    4210           0 :         p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
    4211           0 :         return NT_STATUS_NOT_IMPLEMENTED;
    4212             : }
    4213             : 
    4214           0 : NTSTATUS _lsa_LSARREGISTERAUDITEVENT(struct pipes_struct *p,
    4215             :                                      struct lsa_LSARREGISTERAUDITEVENT *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_LSARGENAUDITEVENT(struct pipes_struct *p,
    4222             :                                 struct lsa_LSARGENAUDITEVENT *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_LSARUNREGISTERAUDITEVENT(struct pipes_struct *p,
    4229             :                                        struct lsa_LSARUNREGISTERAUDITEVENT *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_lsaRQueryForestTrustInformation(struct pipes_struct *p,
    4236             :                                               struct lsa_lsaRQueryForestTrustInformation *r)
    4237             : {
    4238           0 :         p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
    4239           0 :         return NT_STATUS_NOT_IMPLEMENTED;
    4240             : }
    4241             : 
    4242             : #define DNS_CMP_MATCH 0
    4243             : #define DNS_CMP_FIRST_IS_CHILD 1
    4244             : #define DNS_CMP_SECOND_IS_CHILD 2
    4245             : #define DNS_CMP_NO_MATCH 3
    4246             : 
    4247             : /* this function assumes names are well formed DNS names.
    4248             :  * it doesn't validate them */
    4249           0 : static int dns_cmp(const char *s1, size_t l1,
    4250             :                    const char *s2, size_t l2)
    4251             : {
    4252           0 :         const char *p1, *p2;
    4253           0 :         size_t t1, t2;
    4254           0 :         int cret;
    4255             : 
    4256           0 :         if (l1 == l2) {
    4257           0 :                 if (strcasecmp_m(s1, s2) == 0) {
    4258           0 :                         return DNS_CMP_MATCH;
    4259             :                 }
    4260           0 :                 return DNS_CMP_NO_MATCH;
    4261             :         }
    4262             : 
    4263           0 :         if (l1 > l2) {
    4264           0 :                 p1 = s1;
    4265           0 :                 p2 = s2;
    4266           0 :                 t1 = l1;
    4267           0 :                 t2 = l2;
    4268           0 :                 cret = DNS_CMP_FIRST_IS_CHILD;
    4269             :         } else {
    4270           0 :                 p1 = s2;
    4271           0 :                 p2 = s1;
    4272           0 :                 t1 = l2;
    4273           0 :                 t2 = l1;
    4274           0 :                 cret = DNS_CMP_SECOND_IS_CHILD;
    4275             :         }
    4276             : 
    4277           0 :         if (p1[t1 - t2 - 1] != '.') {
    4278           0 :                 return DNS_CMP_NO_MATCH;
    4279             :         }
    4280             : 
    4281           0 :         if (strcasecmp_m(&p1[t1 - t2], p2) == 0) {
    4282           0 :                 return cret;
    4283             :         }
    4284             : 
    4285           0 :         return DNS_CMP_NO_MATCH;
    4286             : }
    4287             : 
    4288           0 : static NTSTATUS make_ft_info(TALLOC_CTX *mem_ctx,
    4289             :                              struct lsa_ForestTrustInformation *lfti,
    4290             :                              struct ForestTrustInfo *fti)
    4291             : {
    4292           0 :         struct lsa_ForestTrustRecord *lrec;
    4293           0 :         struct ForestTrustInfoRecord *rec;
    4294           0 :         struct lsa_StringLarge *tln;
    4295           0 :         struct lsa_ForestTrustDomainInfo *info;
    4296           0 :         uint32_t i;
    4297             : 
    4298           0 :         fti->version = 1;
    4299           0 :         fti->count = lfti->count;
    4300           0 :         fti->records = talloc_array(mem_ctx,
    4301             :                                     struct ForestTrustInfoRecordArmor,
    4302             :                                     fti->count);
    4303           0 :         if (!fti->records) {
    4304           0 :                 return NT_STATUS_NO_MEMORY;
    4305             :         }
    4306           0 :         for (i = 0; i < fti->count; i++) {
    4307           0 :                 lrec = lfti->entries[i];
    4308           0 :                 rec = &fti->records[i].record;
    4309             : 
    4310           0 :                 rec->flags = lrec->flags;
    4311           0 :                 rec->timestamp = lrec->time;
    4312           0 :                 rec->type = (enum ForestTrustInfoRecordType)lrec->type;
    4313             : 
    4314           0 :                 switch (lrec->type) {
    4315           0 :                 case LSA_FOREST_TRUST_TOP_LEVEL_NAME:
    4316             :                 case LSA_FOREST_TRUST_TOP_LEVEL_NAME_EX:
    4317           0 :                         tln = &lrec->forest_trust_data.top_level_name;
    4318           0 :                         rec->data.name.string =
    4319           0 :                                 talloc_strdup(mem_ctx, tln->string);
    4320           0 :                         if (!rec->data.name.string) {
    4321           0 :                                 return NT_STATUS_NO_MEMORY;
    4322             :                         }
    4323           0 :                         rec->data.name.size = strlen(rec->data.name.string);
    4324           0 :                         break;
    4325           0 :                 case LSA_FOREST_TRUST_DOMAIN_INFO:
    4326           0 :                         info = &lrec->forest_trust_data.domain_info;
    4327           0 :                         rec->data.info.sid = *info->domain_sid;
    4328           0 :                         rec->data.info.dns_name.string =
    4329           0 :                                 talloc_strdup(mem_ctx,
    4330             :                                             info->dns_domain_name.string);
    4331           0 :                         if (!rec->data.info.dns_name.string) {
    4332           0 :                                 return NT_STATUS_NO_MEMORY;
    4333             :                         }
    4334           0 :                         rec->data.info.dns_name.size =
    4335           0 :                                 strlen(rec->data.info.dns_name.string);
    4336           0 :                         rec->data.info.netbios_name.string =
    4337           0 :                                 talloc_strdup(mem_ctx,
    4338             :                                             info->netbios_domain_name.string);
    4339           0 :                         if (!rec->data.info.netbios_name.string) {
    4340           0 :                                 return NT_STATUS_NO_MEMORY;
    4341             :                         }
    4342           0 :                         rec->data.info.netbios_name.size =
    4343           0 :                                 strlen(rec->data.info.netbios_name.string);
    4344           0 :                         break;
    4345           0 :                 default:
    4346           0 :                         return NT_STATUS_INVALID_DOMAIN_STATE;
    4347             :                 }
    4348             :         }
    4349             : 
    4350           0 :         return NT_STATUS_OK;
    4351             : }
    4352             : 
    4353             : static NTSTATUS add_collision(struct lsa_ForestTrustCollisionInfo *c_info,
    4354             :                               uint32_t index, uint32_t collision_type,
    4355             :                               uint32_t conflict_type, const char *tdo_name);
    4356             : 
    4357           0 : static NTSTATUS check_ft_info(TALLOC_CTX *mem_ctx,
    4358             :                               const char *tdo_name,
    4359             :                               struct ForestTrustInfo *tdo_fti,
    4360             :                               struct ForestTrustInfo *new_fti,
    4361             :                               struct lsa_ForestTrustCollisionInfo *c_info)
    4362             : {
    4363           0 :         struct ForestTrustInfoRecord *nrec;
    4364           0 :         struct ForestTrustInfoRecord *trec;
    4365           0 :         const char *dns_name;
    4366           0 :         const char *nb_name = NULL;
    4367           0 :         struct dom_sid *sid = NULL;
    4368           0 :         const char *tname = NULL;
    4369           0 :         size_t dns_len = 0;
    4370           0 :         size_t tlen = 0;
    4371           0 :         uint32_t new_fti_idx;
    4372           0 :         uint32_t i;
    4373             :         /* use always TDO type, until we understand when Xref can be used */
    4374           0 :         uint32_t collision_type = LSA_FOREST_TRUST_COLLISION_TDO;
    4375           0 :         bool tln_conflict;
    4376           0 :         bool sid_conflict;
    4377           0 :         bool nb_conflict;
    4378           0 :         bool exclusion;
    4379           0 :         bool ex_rule = false;
    4380           0 :         int ret;
    4381             : 
    4382           0 :         for (new_fti_idx = 0; new_fti_idx < new_fti->count; new_fti_idx++) {
    4383             : 
    4384           0 :                 nrec = &new_fti->records[new_fti_idx].record;
    4385           0 :                 dns_name = NULL;
    4386           0 :                 tln_conflict = false;
    4387           0 :                 sid_conflict = false;
    4388           0 :                 nb_conflict = false;
    4389           0 :                 exclusion = false;
    4390             : 
    4391           0 :                 switch (nrec->type) {
    4392           0 :                 case LSA_FOREST_TRUST_TOP_LEVEL_NAME_EX:
    4393             :                         /* exclusions do not conflict by definition */
    4394           0 :                         break;
    4395             : 
    4396           0 :                 case FOREST_TRUST_TOP_LEVEL_NAME:
    4397           0 :                         dns_name = nrec->data.name.string;
    4398           0 :                         dns_len = nrec->data.name.size;
    4399           0 :                         break;
    4400             : 
    4401           0 :                 case LSA_FOREST_TRUST_DOMAIN_INFO:
    4402           0 :                         dns_name = nrec->data.info.dns_name.string;
    4403           0 :                         dns_len = nrec->data.info.dns_name.size;
    4404           0 :                         nb_name = nrec->data.info.netbios_name.string;
    4405           0 :                         sid = &nrec->data.info.sid;
    4406           0 :                         break;
    4407             :                 }
    4408             : 
    4409           0 :                 if (!dns_name) continue;
    4410             : 
    4411             :                 /* check if this is already taken and not excluded */
    4412           0 :                 for (i = 0; i < tdo_fti->count; i++) {
    4413           0 :                         trec = &tdo_fti->records[i].record;
    4414             : 
    4415           0 :                         switch (trec->type) {
    4416           0 :                         case FOREST_TRUST_TOP_LEVEL_NAME:
    4417           0 :                                 ex_rule = false;
    4418           0 :                                 tname = trec->data.name.string;
    4419           0 :                                 tlen = trec->data.name.size;
    4420           0 :                                 break;
    4421           0 :                         case FOREST_TRUST_TOP_LEVEL_NAME_EX:
    4422           0 :                                 ex_rule = true;
    4423           0 :                                 tname = trec->data.name.string;
    4424           0 :                                 tlen = trec->data.name.size;
    4425           0 :                                 break;
    4426           0 :                         case FOREST_TRUST_DOMAIN_INFO:
    4427           0 :                                 ex_rule = false;
    4428           0 :                                 tname = trec->data.info.dns_name.string;
    4429           0 :                                 tlen = trec->data.info.dns_name.size;
    4430           0 :                                 break;
    4431           0 :                         default:
    4432           0 :                                 return NT_STATUS_INVALID_PARAMETER;
    4433             :                         }
    4434           0 :                         ret = dns_cmp(dns_name, dns_len, tname, tlen);
    4435           0 :                         switch (ret) {
    4436           0 :                         case DNS_CMP_MATCH:
    4437             :                                 /* if it matches exclusion,
    4438             :                                  * it doesn't conflict */
    4439           0 :                                 if (ex_rule) {
    4440           0 :                                         exclusion = true;
    4441           0 :                                         break;
    4442             :                                 }
    4443             : 
    4444           0 :                                 FALL_THROUGH;
    4445             :                         case DNS_CMP_FIRST_IS_CHILD:
    4446             :                         case DNS_CMP_SECOND_IS_CHILD:
    4447           0 :                                 tln_conflict = true;
    4448             : 
    4449             :                                 FALL_THROUGH;
    4450           0 :                         default:
    4451           0 :                                 break;
    4452             :                         }
    4453             : 
    4454             :                         /* explicit exclusion, no dns name conflict here */
    4455           0 :                         if (exclusion) {
    4456           0 :                                 tln_conflict = false;
    4457             :                         }
    4458             : 
    4459           0 :                         if (trec->type != FOREST_TRUST_DOMAIN_INFO) {
    4460           0 :                                 continue;
    4461             :                         }
    4462             : 
    4463             :                         /* also test for domain info */
    4464           0 :                         if (!(trec->flags & LSA_SID_DISABLED_ADMIN) &&
    4465           0 :                             dom_sid_compare(&trec->data.info.sid, sid) == 0) {
    4466           0 :                                 sid_conflict = true;
    4467             :                         }
    4468           0 :                         if (!(trec->flags & LSA_NB_DISABLED_ADMIN) &&
    4469           0 :                             strcasecmp_m(trec->data.info.netbios_name.string,
    4470             :                                        nb_name) == 0) {
    4471           0 :                                 nb_conflict = true;
    4472             :                         }
    4473             :                 }
    4474             : 
    4475           0 :                 if (tln_conflict) {
    4476           0 :                         (void)add_collision(c_info, new_fti_idx,
    4477             :                                                   collision_type,
    4478             :                                                   LSA_TLN_DISABLED_CONFLICT,
    4479             :                                                   tdo_name);
    4480             :                 }
    4481           0 :                 if (sid_conflict) {
    4482           0 :                         (void)add_collision(c_info, new_fti_idx,
    4483             :                                                   collision_type,
    4484             :                                                   LSA_SID_DISABLED_CONFLICT,
    4485             :                                                   tdo_name);
    4486             :                 }
    4487           0 :                 if (nb_conflict) {
    4488           0 :                         (void)add_collision(c_info, new_fti_idx,
    4489             :                                                   collision_type,
    4490             :                                                   LSA_NB_DISABLED_CONFLICT,
    4491             :                                                   tdo_name);
    4492             :                 }
    4493             :         }
    4494             : 
    4495           0 :         return NT_STATUS_OK;
    4496             : }
    4497             : 
    4498           0 : static NTSTATUS add_collision(struct lsa_ForestTrustCollisionInfo *c_info,
    4499             :                               uint32_t idx, uint32_t collision_type,
    4500             :                               uint32_t conflict_type, const char *tdo_name)
    4501             : {
    4502           0 :         struct lsa_ForestTrustCollisionRecord **es;
    4503           0 :         uint32_t i = c_info->count;
    4504             : 
    4505           0 :         es = talloc_realloc(c_info, c_info->entries,
    4506             :                             struct lsa_ForestTrustCollisionRecord *, i + 1);
    4507           0 :         if (!es) {
    4508           0 :                 return NT_STATUS_NO_MEMORY;
    4509             :         }
    4510           0 :         c_info->entries = es;
    4511           0 :         c_info->count = i + 1;
    4512             : 
    4513           0 :         es[i] = talloc(es, struct lsa_ForestTrustCollisionRecord);
    4514           0 :         if (!es[i]) {
    4515           0 :                 return NT_STATUS_NO_MEMORY;
    4516             :         }
    4517             : 
    4518           0 :         es[i]->index = idx;
    4519           0 :         es[i]->type = collision_type;
    4520           0 :         es[i]->flags = conflict_type;
    4521           0 :         es[i]->name.string = talloc_strdup(es[i], tdo_name);
    4522           0 :         if (!es[i]->name.string) {
    4523           0 :                 return NT_STATUS_NO_MEMORY;
    4524             :         }
    4525           0 :         es[i]->name.size = strlen(es[i]->name.string);
    4526             : 
    4527           0 :         return NT_STATUS_OK;
    4528             : }
    4529             : 
    4530           0 : static NTSTATUS get_ft_info(TALLOC_CTX *mem_ctx,
    4531             :                             struct pdb_trusted_domain *td,
    4532             :                             struct ForestTrustInfo *info)
    4533             : {
    4534           0 :         enum ndr_err_code ndr_err;
    4535             : 
    4536           0 :         if (td->trust_forest_trust_info.length == 0 ||
    4537           0 :             td->trust_forest_trust_info.data == NULL) {
    4538           0 :                 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
    4539             :         }
    4540           0 :         ndr_err = ndr_pull_struct_blob_all(&td->trust_forest_trust_info, mem_ctx,
    4541             :                                            info,
    4542             :                                            (ndr_pull_flags_fn_t)ndr_pull_ForestTrustInfo);
    4543           0 :         if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
    4544           0 :                 return NT_STATUS_INVALID_DOMAIN_STATE;
    4545             :         }
    4546             : 
    4547           0 :         return NT_STATUS_OK;
    4548             : }
    4549             : 
    4550           0 : static NTSTATUS own_ft_info(struct pdb_domain_info *dom_info,
    4551             :                             struct ForestTrustInfo *fti)
    4552             : {
    4553           0 :         struct ForestTrustDataDomainInfo *info;
    4554           0 :         struct ForestTrustInfoRecord *rec;
    4555             : 
    4556           0 :         fti->version = 1;
    4557           0 :         fti->count = 2;
    4558           0 :         fti->records = talloc_array(fti,
    4559             :                                     struct ForestTrustInfoRecordArmor, 2);
    4560           0 :         if (!fti->records) {
    4561           0 :                 return NT_STATUS_NO_MEMORY;
    4562             :         }
    4563             : 
    4564             :         /* TLN info */
    4565           0 :         rec = &fti->records[0].record;
    4566             : 
    4567           0 :         rec->flags = 0;
    4568           0 :         rec->timestamp = 0;
    4569           0 :         rec->type = FOREST_TRUST_TOP_LEVEL_NAME;
    4570             : 
    4571           0 :         rec->data.name.string = talloc_strdup(fti, dom_info->dns_forest);
    4572           0 :         if (!rec->data.name.string) {
    4573           0 :                 return NT_STATUS_NO_MEMORY;
    4574             :         }
    4575           0 :         rec->data.name.size = strlen(rec->data.name.string);
    4576             : 
    4577             :         /* DOMAIN info */
    4578           0 :         rec = &fti->records[1].record;
    4579             : 
    4580           0 :         rec->flags = 0;
    4581           0 :         rec->timestamp = 0;
    4582           0 :         rec->type = FOREST_TRUST_DOMAIN_INFO;
    4583             : 
    4584           0 :         info = &rec->data.info;
    4585             : 
    4586           0 :         info->sid = dom_info->sid;
    4587           0 :         info->dns_name.string = talloc_strdup(fti, dom_info->dns_domain);
    4588           0 :         if (!info->dns_name.string) {
    4589           0 :                 return NT_STATUS_NO_MEMORY;
    4590             :         }
    4591           0 :         info->dns_name.size = strlen(info->dns_name.string);
    4592           0 :         info->netbios_name.string = talloc_strdup(fti, dom_info->name);
    4593           0 :         if (!info->netbios_name.string) {
    4594           0 :                 return NT_STATUS_NO_MEMORY;
    4595             :         }
    4596           0 :         info->netbios_name.size = strlen(info->netbios_name.string);
    4597             : 
    4598           0 :         return NT_STATUS_OK;
    4599             : }
    4600             : 
    4601           0 : NTSTATUS _lsa_lsaRSetForestTrustInformation(struct pipes_struct *p,
    4602             :                                             struct lsa_lsaRSetForestTrustInformation *r)
    4603             : {
    4604           0 :         NTSTATUS status;
    4605           0 :         int i;
    4606           0 :         int j;
    4607           0 :         struct lsa_info *handle;
    4608           0 :         uint32_t num_domains;
    4609           0 :         struct pdb_trusted_domain **domains;
    4610           0 :         struct ForestTrustInfo *nfti;
    4611           0 :         struct ForestTrustInfo *fti;
    4612           0 :         struct lsa_ForestTrustCollisionInfo *c_info;
    4613           0 :         struct pdb_domain_info *dom_info;
    4614           0 :         enum ndr_err_code ndr_err;
    4615             : 
    4616           0 :         if (!IS_DC) {
    4617           0 :                 return NT_STATUS_NOT_SUPPORTED;
    4618             :         }
    4619             : 
    4620           0 :         handle = find_policy_by_hnd(p,
    4621             :                                     r->in.handle,
    4622             :                                     LSA_HANDLE_TRUST_TYPE,
    4623             :                                     struct lsa_info,
    4624           0 :                                     &status);
    4625           0 :         if (!NT_STATUS_IS_OK(status)) {
    4626           0 :                 return NT_STATUS_INVALID_HANDLE;
    4627             :         }
    4628             : 
    4629           0 :         if (!(handle->access & LSA_TRUSTED_SET_AUTH)) {
    4630           0 :                 return NT_STATUS_ACCESS_DENIED;
    4631             :         }
    4632             : 
    4633           0 :         status = pdb_enum_trusted_domains(p->mem_ctx, &num_domains, &domains);
    4634           0 :         if (!NT_STATUS_IS_OK(status)) {
    4635           0 :                 return status;
    4636             :         }
    4637           0 :         if (num_domains == 0) {
    4638           0 :                 return NT_STATUS_NO_SUCH_DOMAIN;
    4639             :         }
    4640             : 
    4641           0 :         for (i = 0; i < num_domains; i++) {
    4642           0 :                 if (domains[i]->domain_name == NULL) {
    4643           0 :                         return NT_STATUS_INVALID_DOMAIN_STATE;
    4644             :                 }
    4645           0 :                 if (strcasecmp_m(domains[i]->domain_name,
    4646           0 :                                r->in.trusted_domain_name->string) == 0) {
    4647           0 :                         break;
    4648             :                 }
    4649             :         }
    4650           0 :         if (i >= num_domains) {
    4651           0 :                 return NT_STATUS_NO_SUCH_DOMAIN;
    4652             :         }
    4653             : 
    4654           0 :         if (!(domains[i]->trust_attributes &
    4655             :               LSA_TRUST_ATTRIBUTE_FOREST_TRANSITIVE)) {
    4656           0 :                 return NT_STATUS_INVALID_PARAMETER;
    4657             :         }
    4658             : 
    4659           0 :         if (r->in.highest_record_type >= LSA_FOREST_TRUST_RECORD_TYPE_LAST) {
    4660           0 :                 return NT_STATUS_INVALID_PARAMETER;
    4661             :         }
    4662             : 
    4663             :         /* The following section until COPY_END is a copy from
    4664             :          * source4/rpmc_server/lsa/scesrc_lsa.c */
    4665           0 :         nfti = talloc(p->mem_ctx, struct ForestTrustInfo);
    4666           0 :         if (!nfti) {
    4667           0 :                 return NT_STATUS_NO_MEMORY;
    4668             :         }
    4669             : 
    4670           0 :         status = make_ft_info(nfti, r->in.forest_trust_info, nfti);
    4671           0 :         if (!NT_STATUS_IS_OK(status)) {
    4672           0 :                 return status;
    4673             :         }
    4674             : 
    4675           0 :         c_info = talloc_zero(r->out.collision_info,
    4676             :                              struct lsa_ForestTrustCollisionInfo);
    4677           0 :         if (!c_info) {
    4678           0 :                 return NT_STATUS_NO_MEMORY;
    4679             :         }
    4680             : 
    4681             :         /* first check own info, then other domains */
    4682           0 :         fti = talloc(p->mem_ctx, struct ForestTrustInfo);
    4683           0 :         if (!fti) {
    4684           0 :                 return NT_STATUS_NO_MEMORY;
    4685             :         }
    4686             : 
    4687           0 :         dom_info = pdb_get_domain_info(p->mem_ctx);
    4688             : 
    4689           0 :         status = own_ft_info(dom_info, fti);
    4690           0 :         if (!NT_STATUS_IS_OK(status)) {
    4691           0 :                 return status;
    4692             :         }
    4693             : 
    4694           0 :         status = check_ft_info(c_info, dom_info->dns_domain, fti, nfti, c_info);
    4695           0 :         if (!NT_STATUS_IS_OK(status)) {
    4696           0 :                 return status;
    4697             :         }
    4698             : 
    4699           0 :         for (j = 0; j < num_domains; j++) {
    4700           0 :                 fti = talloc(p->mem_ctx, struct ForestTrustInfo);
    4701           0 :                 if (!fti) {
    4702           0 :                         return NT_STATUS_NO_MEMORY;
    4703             :                 }
    4704             : 
    4705           0 :                 status = get_ft_info(p->mem_ctx, domains[j], fti);
    4706           0 :                 if (!NT_STATUS_IS_OK(status)) {
    4707           0 :                         if (NT_STATUS_EQUAL(status,
    4708             :                             NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
    4709           0 :                                 continue;
    4710             :                         }
    4711           0 :                         return status;
    4712             :                 }
    4713             : 
    4714           0 :                 if (domains[j]->domain_name == NULL) {
    4715           0 :                         return NT_STATUS_INVALID_DOMAIN_STATE;
    4716             :                 }
    4717             : 
    4718           0 :                 status = check_ft_info(c_info, domains[j]->domain_name,
    4719             :                                        fti, nfti, c_info);
    4720           0 :                 if (!NT_STATUS_IS_OK(status)) {
    4721           0 :                         return status;
    4722             :                 }
    4723             :         }
    4724             : 
    4725           0 :         if (c_info->count != 0) {
    4726           0 :                 *r->out.collision_info = c_info;
    4727             :         }
    4728             : 
    4729           0 :         if (r->in.check_only != 0) {
    4730           0 :                 return NT_STATUS_OK;
    4731             :         }
    4732             : 
    4733             :         /* COPY_END */
    4734             : 
    4735           0 :         ndr_err = ndr_push_struct_blob(&domains[i]->trust_forest_trust_info,
    4736             :                                        p->mem_ctx, nfti,
    4737             :                                        (ndr_push_flags_fn_t)ndr_push_ForestTrustInfo);
    4738           0 :         if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
    4739           0 :                 return NT_STATUS_INVALID_PARAMETER;
    4740             :         }
    4741             : 
    4742           0 :         status = pdb_set_trusted_domain(domains[i]->domain_name, domains[i]);
    4743           0 :         if (!NT_STATUS_IS_OK(status)) {
    4744           0 :                 return status;
    4745             :         }
    4746             : 
    4747           0 :         return NT_STATUS_OK;
    4748             : }
    4749             : 
    4750           0 : NTSTATUS _lsa_CREDRRENAME(struct pipes_struct *p,
    4751             :                           struct lsa_CREDRRENAME *r)
    4752             : {
    4753           0 :         p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
    4754           0 :         return NT_STATUS_NOT_IMPLEMENTED;
    4755             : }
    4756             : 
    4757           0 : NTSTATUS _lsa_LSAROPENPOLICYSCE(struct pipes_struct *p,
    4758             :                                 struct lsa_LSAROPENPOLICYSCE *r)
    4759             : {
    4760           0 :         p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
    4761           0 :         return NT_STATUS_NOT_IMPLEMENTED;
    4762             : }
    4763             : 
    4764           0 : NTSTATUS _lsa_LSARADTREGISTERSECURITYEVENTSOURCE(struct pipes_struct *p,
    4765             :                                                  struct lsa_LSARADTREGISTERSECURITYEVENTSOURCE *r)
    4766             : {
    4767           0 :         p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
    4768           0 :         return NT_STATUS_NOT_IMPLEMENTED;
    4769             : }
    4770             : 
    4771           0 : NTSTATUS _lsa_LSARADTUNREGISTERSECURITYEVENTSOURCE(struct pipes_struct *p,
    4772             :                                                    struct lsa_LSARADTUNREGISTERSECURITYEVENTSOURCE *r)
    4773             : {
    4774           0 :         p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
    4775           0 :         return NT_STATUS_NOT_IMPLEMENTED;
    4776             : }
    4777             : 
    4778           0 : NTSTATUS _lsa_LSARADTREPORTSECURITYEVENT(struct pipes_struct *p,
    4779             :                                          struct lsa_LSARADTREPORTSECURITYEVENT *r)
    4780             : {
    4781           0 :         p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
    4782           0 :         return NT_STATUS_NOT_IMPLEMENTED;
    4783             : }
    4784             : 
    4785           0 : void _lsa_Opnum82NotUsedOnWire(struct pipes_struct *p,
    4786             :                                struct lsa_Opnum82NotUsedOnWire *r)
    4787             : {
    4788           0 :         p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
    4789           0 : }
    4790             : 
    4791           0 : void _lsa_Opnum83NotUsedOnWire(struct pipes_struct *p,
    4792             :                                struct lsa_Opnum83NotUsedOnWire *r)
    4793             : {
    4794           0 :         p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
    4795           0 : }
    4796             : 
    4797           0 : void _lsa_Opnum84NotUsedOnWire(struct pipes_struct *p,
    4798             :                                struct lsa_Opnum84NotUsedOnWire *r)
    4799             : {
    4800           0 :         p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
    4801           0 : }
    4802             : 
    4803           0 : void _lsa_Opnum85NotUsedOnWire(struct pipes_struct *p,
    4804             :                                struct lsa_Opnum85NotUsedOnWire *r)
    4805             : {
    4806           0 :         p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
    4807           0 : }
    4808             : 
    4809           0 : void _lsa_Opnum86NotUsedOnWire(struct pipes_struct *p,
    4810             :                                struct lsa_Opnum86NotUsedOnWire *r)
    4811             : {
    4812           0 :         p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
    4813           0 : }
    4814             : 
    4815           0 : void _lsa_Opnum87NotUsedOnWire(struct pipes_struct *p,
    4816             :                                struct lsa_Opnum87NotUsedOnWire *r)
    4817             : {
    4818           0 :         p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
    4819           0 : }
    4820             : 
    4821           0 : void _lsa_Opnum88NotUsedOnWire(struct pipes_struct *p,
    4822             :                                struct lsa_Opnum88NotUsedOnWire *r)
    4823             : {
    4824           0 :         p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
    4825           0 : }
    4826             : 
    4827           0 : void _lsa_Opnum89NotUsedOnWire(struct pipes_struct *p,
    4828             :                                struct lsa_Opnum89NotUsedOnWire *r)
    4829             : {
    4830           0 :         p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
    4831           0 : }
    4832             : 
    4833           0 : void _lsa_Opnum90NotUsedOnWire(struct pipes_struct *p,
    4834             :                                struct lsa_Opnum90NotUsedOnWire *r)
    4835             : {
    4836           0 :         p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
    4837           0 : }
    4838             : 
    4839           0 : void _lsa_Opnum91NotUsedOnWire(struct pipes_struct *p,
    4840             :                                struct lsa_Opnum91NotUsedOnWire *r)
    4841             : {
    4842           0 :         p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
    4843           0 : }
    4844             : 
    4845           0 : void _lsa_Opnum92NotUsedOnWire(struct pipes_struct *p,
    4846             :                                struct lsa_Opnum92NotUsedOnWire *r)
    4847             : {
    4848           0 :         p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
    4849           0 : }
    4850             : 
    4851           0 : void _lsa_Opnum93NotUsedOnWire(struct pipes_struct *p,
    4852             :                                struct lsa_Opnum93NotUsedOnWire *r)
    4853             : {
    4854           0 :         p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
    4855           0 : }
    4856             : 
    4857           0 : void _lsa_Opnum94NotUsedOnWire(struct pipes_struct *p,
    4858             :                                struct lsa_Opnum94NotUsedOnWire *r)
    4859             : {
    4860           0 :         p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
    4861           0 : }
    4862             : 
    4863           0 : void _lsa_Opnum95NotUsedOnWire(struct pipes_struct *p,
    4864             :                                struct lsa_Opnum95NotUsedOnWire *r)
    4865             : {
    4866           0 :         p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
    4867           0 : }
    4868             : 
    4869           0 : void _lsa_Opnum96NotUsedOnWire(struct pipes_struct *p,
    4870             :                                struct lsa_Opnum96NotUsedOnWire *r)
    4871             : {
    4872           0 :         p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
    4873           0 : }
    4874             : 
    4875           0 : void _lsa_Opnum97NotUsedOnWire(struct pipes_struct *p,
    4876             :                                struct lsa_Opnum97NotUsedOnWire *r)
    4877             : {
    4878           0 :         p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
    4879           0 : }
    4880             : 
    4881           0 : void _lsa_Opnum98NotUsedOnWire(struct pipes_struct *p,
    4882             :                                struct lsa_Opnum98NotUsedOnWire *r)
    4883             : {
    4884           0 :         p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
    4885           0 : }
    4886             : 
    4887           0 : void _lsa_Opnum99NotUsedOnWire(struct pipes_struct *p,
    4888             :                                struct lsa_Opnum99NotUsedOnWire *r)
    4889             : {
    4890           0 :         p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
    4891           0 : }
    4892             : 
    4893           0 : void _lsa_Opnum100NotUsedOnWire(struct pipes_struct *p,
    4894             :                                 struct lsa_Opnum100NotUsedOnWire *r)
    4895             : {
    4896           0 :         p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
    4897           0 : }
    4898             : 
    4899           0 : void _lsa_Opnum101NotUsedOnWire(struct pipes_struct *p,
    4900             :                                 struct lsa_Opnum101NotUsedOnWire *r)
    4901             : {
    4902           0 :         p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
    4903           0 : }
    4904             : 
    4905           0 : void _lsa_Opnum102NotUsedOnWire(struct pipes_struct *p,
    4906             :                                 struct lsa_Opnum102NotUsedOnWire *r)
    4907             : {
    4908           0 :         p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
    4909           0 : }
    4910             : 
    4911           0 : void _lsa_Opnum103NotUsedOnWire(struct pipes_struct *p,
    4912             :                                 struct lsa_Opnum103NotUsedOnWire *r)
    4913             : {
    4914           0 :         p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
    4915           0 : }
    4916             : 
    4917           0 : void _lsa_Opnum104NotUsedOnWire(struct pipes_struct *p,
    4918             :                                 struct lsa_Opnum104NotUsedOnWire *r)
    4919             : {
    4920           0 :         p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
    4921           0 : }
    4922             : 
    4923           0 : void _lsa_Opnum105NotUsedOnWire(struct pipes_struct *p,
    4924             :                                 struct lsa_Opnum105NotUsedOnWire *r)
    4925             : {
    4926           0 :         p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
    4927           0 : }
    4928             : 
    4929           0 : void _lsa_Opnum106NotUsedOnWire(struct pipes_struct *p,
    4930             :                                 struct lsa_Opnum106NotUsedOnWire *r)
    4931             : {
    4932           0 :         p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
    4933           0 : }
    4934             : 
    4935           0 : void _lsa_Opnum107NotUsedOnWire(struct pipes_struct *p,
    4936             :                                 struct lsa_Opnum107NotUsedOnWire *r)
    4937             : {
    4938           0 :         p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
    4939           0 : }
    4940             : 
    4941           0 : void _lsa_Opnum108NotUsedOnWire(struct pipes_struct *p,
    4942             :                                 struct lsa_Opnum108NotUsedOnWire *r)
    4943             : {
    4944           0 :         p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
    4945           0 : }
    4946             : 
    4947           0 : void _lsa_Opnum109NotUsedOnWire(struct pipes_struct *p,
    4948             :                                 struct lsa_Opnum109NotUsedOnWire *r)
    4949             : {
    4950           0 :         p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
    4951           0 : }
    4952             : 
    4953           0 : void _lsa_Opnum110NotUsedOnWire(struct pipes_struct *p,
    4954             :                                 struct lsa_Opnum110NotUsedOnWire *r)
    4955             : {
    4956           0 :         p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
    4957           0 : }
    4958             : 
    4959           0 : void _lsa_Opnum111NotUsedOnWire(struct pipes_struct *p,
    4960             :                                 struct lsa_Opnum111NotUsedOnWire *r)
    4961             : {
    4962           0 :         p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
    4963           0 : }
    4964             : 
    4965           0 : void _lsa_Opnum112NotUsedOnWire(struct pipes_struct *p,
    4966             :                                 struct lsa_Opnum112NotUsedOnWire *r)
    4967             : {
    4968           0 :         p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
    4969           0 : }
    4970             : 
    4971           0 : void _lsa_Opnum113NotUsedOnWire(struct pipes_struct *p,
    4972             :                                 struct lsa_Opnum113NotUsedOnWire *r)
    4973             : {
    4974           0 :         p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
    4975           0 : }
    4976             : 
    4977           0 : void _lsa_Opnum114NotUsedOnWire(struct pipes_struct *p,
    4978             :                                 struct lsa_Opnum114NotUsedOnWire *r)
    4979             : {
    4980           0 :         p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
    4981           0 : }
    4982             : 
    4983           0 : void _lsa_Opnum115NotUsedOnWire(struct pipes_struct *p,
    4984             :                                 struct lsa_Opnum115NotUsedOnWire *r)
    4985             : {
    4986           0 :         p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
    4987           0 : }
    4988             : 
    4989           0 : void _lsa_Opnum116NotUsedOnWire(struct pipes_struct *p,
    4990             :                                 struct lsa_Opnum116NotUsedOnWire *r)
    4991             : {
    4992           0 :         p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
    4993           0 : }
    4994             : 
    4995           0 : void _lsa_Opnum117NotUsedOnWire(struct pipes_struct *p,
    4996             :                                 struct lsa_Opnum117NotUsedOnWire *r)
    4997             : {
    4998           0 :         p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
    4999           0 : }
    5000             : 
    5001           0 : void _lsa_Opnum118NotUsedOnWire(struct pipes_struct *p,
    5002             :                                 struct lsa_Opnum118NotUsedOnWire *r)
    5003             : {
    5004           0 :         p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
    5005           0 : }
    5006             : 
    5007           0 : void _lsa_Opnum119NotUsedOnWire(struct pipes_struct *p,
    5008             :                                 struct lsa_Opnum119NotUsedOnWire *r)
    5009             : {
    5010           0 :         p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
    5011           0 : }
    5012             : 
    5013           0 : void _lsa_Opnum120NotUsedOnWire(struct pipes_struct *p,
    5014             :                                 struct lsa_Opnum120NotUsedOnWire *r)
    5015             : {
    5016           0 :         p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
    5017           0 : }
    5018             : 
    5019           0 : void _lsa_Opnum121NotUsedOnWire(struct pipes_struct *p,
    5020             :                                 struct lsa_Opnum121NotUsedOnWire *r)
    5021             : {
    5022           0 :         p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
    5023           0 : }
    5024             : 
    5025           0 : void _lsa_Opnum122NotUsedOnWire(struct pipes_struct *p,
    5026             :                                 struct lsa_Opnum122NotUsedOnWire *r)
    5027             : {
    5028           0 :         p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
    5029           0 : }
    5030             : 
    5031           0 : void _lsa_Opnum123NotUsedOnWire(struct pipes_struct *p,
    5032             :                                 struct lsa_Opnum123NotUsedOnWire *r)
    5033             : {
    5034           0 :         p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
    5035           0 : }
    5036             : 
    5037           0 : void _lsa_Opnum124NotUsedOnWire(struct pipes_struct *p,
    5038             :                                 struct lsa_Opnum124NotUsedOnWire *r)
    5039             : {
    5040           0 :         p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
    5041           0 : }
    5042             : 
    5043           0 : void _lsa_Opnum125NotUsedOnWire(struct pipes_struct *p,
    5044             :                                 struct lsa_Opnum125NotUsedOnWire *r)
    5045             : {
    5046           0 :         p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
    5047           0 : }
    5048             : 
    5049           0 : void _lsa_Opnum126NotUsedOnWire(struct pipes_struct *p,
    5050             :                                 struct lsa_Opnum126NotUsedOnWire *r)
    5051             : {
    5052           0 :         p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
    5053           0 : }
    5054             : 
    5055           0 : void _lsa_Opnum127NotUsedOnWire(struct pipes_struct *p,
    5056             :                                 struct lsa_Opnum127NotUsedOnWire *r)
    5057             : {
    5058           0 :         p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
    5059           0 : }
    5060             : 
    5061           0 : void _lsa_Opnum128NotUsedOnWire(struct pipes_struct *p,
    5062             :                                 struct lsa_Opnum128NotUsedOnWire *r)
    5063             : {
    5064           0 :         p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
    5065           0 : }
    5066             : 
    5067             : /***************************************************************************
    5068             :  _lsa_CreateTrustedDomainEx3
    5069             :  ***************************************************************************/
    5070             : 
    5071           0 : NTSTATUS _lsa_CreateTrustedDomainEx3(struct pipes_struct *p,
    5072             :                                      struct lsa_CreateTrustedDomainEx3 *r)
    5073             : {
    5074           0 :         p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
    5075           0 :         return NT_STATUS_NOT_IMPLEMENTED;
    5076             : }
    5077             : 
    5078             : /***************************************************************************
    5079             :  _lsa_OpenPolicy3
    5080             :  ***************************************************************************/
    5081             : 
    5082          80 : NTSTATUS _lsa_OpenPolicy3(struct pipes_struct *p,
    5083             :                           struct lsa_OpenPolicy3 *r)
    5084             : {
    5085          80 :         struct dcesrv_call_state *dce_call = p->dce_call;
    5086           0 :         struct auth_session_info *session_info =
    5087          80 :                 dcesrv_call_session_info(dce_call);
    5088          80 :         struct security_descriptor *psd = NULL;
    5089           0 :         size_t sd_size;
    5090          80 :         uint32_t des_access = r->in.access_mask;
    5091           0 :         uint32_t acc_granted;
    5092           0 :         NTSTATUS status;
    5093             : 
    5094          80 :         if (p->transport != NCACN_NP && p->transport != NCALRPC) {
    5095           2 :                 p->fault_state = DCERPC_FAULT_ACCESS_DENIED;
    5096           2 :                 return NT_STATUS_ACCESS_DENIED;
    5097             :         }
    5098             : 
    5099          78 :         ZERO_STRUCTP(r->out.handle);
    5100             : 
    5101             :         /*
    5102             :          * The attributes have no effect and MUST be ignored, except the
    5103             :          * root_dir which MUST be NULL.
    5104             :          */
    5105          78 :         if (r->in.attr != NULL && r->in.attr->root_dir != NULL) {
    5106           0 :                 return NT_STATUS_INVALID_PARAMETER;
    5107             :         }
    5108             : 
    5109          78 :         switch (r->in.in_version) {
    5110          78 :         case 1:
    5111          78 :                 *r->out.out_version = 1;
    5112             : 
    5113          78 :                 r->out.out_revision_info->info1.revision = 1;
    5114             :                 /* TODO: Enable as soon as we support it */
    5115             : #if 0
    5116             :                 r->out.out_revision_info->info1.supported_features =
    5117             :                         LSA_FEATURE_TDO_AUTH_INFO_AES_CIPHER;
    5118             : #endif
    5119             : 
    5120          78 :                 break;
    5121           0 :         default:
    5122           0 :                 return NT_STATUS_NOT_SUPPORTED;
    5123             :         }
    5124             : 
    5125             :         /* Work out max allowed. */
    5126          78 :         map_max_allowed_access(session_info->security_token,
    5127          78 :                                session_info->unix_token,
    5128             :                                &des_access);
    5129             : 
    5130             :         /* map the generic bits to the lsa policy ones */
    5131          78 :         se_map_generic(&des_access, &lsa_policy_mapping);
    5132             : 
    5133             :         /* get the generic lsa policy SD until we store it */
    5134          78 :         status = make_lsa_object_sd(p->mem_ctx,
    5135             :                                     &psd,
    5136             :                                     &sd_size,
    5137             :                                     &lsa_policy_mapping,
    5138             :                                     NULL,
    5139             :                                     0);
    5140          78 :         if (!NT_STATUS_IS_OK(status)) {
    5141           0 :                 return status;
    5142             :         }
    5143             : 
    5144          78 :         status = access_check_object(psd,
    5145             :                                      session_info->security_token,
    5146             :                                      SEC_PRIV_INVALID,
    5147             :                                      SEC_PRIV_INVALID,
    5148             :                                      0,
    5149             :                                      des_access,
    5150             :                                      &acc_granted,
    5151             :                                      "_lsa_OpenPolicy2");
    5152          78 :         if (!NT_STATUS_IS_OK(status)) {
    5153           0 :                 return status;
    5154             :         }
    5155             : 
    5156          78 :         status = create_lsa_policy_handle(p->mem_ctx,
    5157             :                                           p,
    5158             :                                           LSA_HANDLE_POLICY_TYPE,
    5159             :                                           acc_granted,
    5160             :                                           get_global_sam_sid(),
    5161             :                                           NULL,
    5162             :                                           psd,
    5163             :                                           r->out.handle);
    5164          78 :         if (!NT_STATUS_IS_OK(status)) {
    5165           0 :                 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
    5166             :         }
    5167             : 
    5168          78 :         return NT_STATUS_OK;
    5169             : }
    5170             : 
    5171           0 : void _lsa_Opnum131NotUsedOnWire(struct pipes_struct *p,
    5172             :                                 struct lsa_Opnum131NotUsedOnWire *r)
    5173             : {
    5174           0 :         p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
    5175           0 : }
    5176             : 
    5177           0 : NTSTATUS _lsa_lsaRQueryForestTrustInformation2(struct pipes_struct *p,
    5178             :                                                struct lsa_lsaRQueryForestTrustInformation2 *r)
    5179             : {
    5180           0 :         p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
    5181           0 :         return NT_STATUS_NOT_IMPLEMENTED;
    5182             : }
    5183             : 
    5184           0 : NTSTATUS _lsa_lsaRSetForestTrustInformation2(struct pipes_struct *p,
    5185             :                                             struct lsa_lsaRSetForestTrustInformation2 *r)
    5186             : {
    5187           0 :         p->fault_state = DCERPC_FAULT_OP_RNG_ERROR;
    5188           0 :         return NT_STATUS_NOT_IMPLEMENTED;
    5189             : }
    5190             : 
    5191             : #include "librpc/rpc/dcesrv_core.h"
    5192             : 
    5193             : #define DCESRV_INTERFACE_LSARPC_BIND(context, iface) \
    5194             :        dcesrv_interface_lsarpc_bind(context, iface)
    5195             : 
    5196        6340 : static NTSTATUS dcesrv_interface_lsarpc_bind(
    5197             :                         struct dcesrv_connection_context *context,
    5198             :                         const struct dcesrv_interface *iface)
    5199             : {
    5200        6340 :         return dcesrv_interface_bind_reject_connect(context, iface);
    5201             : }
    5202             : 
    5203             : static NTSTATUS lsarpc__op_init_server(struct dcesrv_context *dce_ctx,
    5204             :                         const struct dcesrv_endpoint_server *ep_server);
    5205             : static const struct dcesrv_interface dcesrv_lsarpc_interface;
    5206             : 
    5207             : #define NCACN_NP_PIPE_NETLOGON "ncacn_np:[\\pipe\\netlogon]"
    5208             : #define NCACN_NP_PIPE_LSASS "ncacn_np:[\\pipe\\lsass]"
    5209             : 
    5210             : #define DCESRV_INTERFACE_LSARPC_NCACN_NP_SECONDARY_ENDPOINT \
    5211             :         NCACN_NP_PIPE_LSASS
    5212             : 
    5213             : #define DCESRV_INTERFACE_LSARPC_INIT_SERVER \
    5214             :        dcesrv_interface_lsarpc_init_server
    5215             : 
    5216         215 : static NTSTATUS dcesrv_interface_lsarpc_init_server(
    5217             :                         struct dcesrv_context *dce_ctx,
    5218             :                         const struct dcesrv_endpoint_server *ep_server)
    5219             : {
    5220         215 :         NTSTATUS ret = dcesrv_interface_register(dce_ctx,
    5221             :                                                  NCACN_NP_PIPE_NETLOGON,
    5222             :                                                  NCACN_NP_PIPE_LSASS,
    5223             :                                                  &dcesrv_lsarpc_interface,
    5224             :                                                  NULL);
    5225         215 :         if (!NT_STATUS_IS_OK(ret)) {
    5226           0 :                 DBG_ERR("Failed to register endpoint "
    5227             :                         "'\\pipe\\netlogon'\n");
    5228           0 :                 return ret;
    5229             :         }
    5230             : 
    5231         215 :         return lsarpc__op_init_server(dce_ctx, ep_server);
    5232             : }
    5233             : 
    5234             : /* include the generated boilerplate */
    5235             : #include "librpc/gen_ndr/ndr_lsa_scompat.c"

Generated by: LCOV version 1.14