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 98b443d9 Lines: 981 2648 37.0 %
Date: 2024-05-31 13:13:24 Functions: 49 164 29.9 %

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

Generated by: LCOV version 1.14