LCOV - code coverage report
Current view: top level - source4/rpc_server/lsa - dcesrv_lsa.c (source / functions) Hit Total Coverage
Test: coverage report for master 469b22b8 Lines: 1458 2444 59.7 %
Date: 2024-06-10 12:05:21 Functions: 65 158 41.1 %

          Line data    Source code
       1             : /* need access mask/acl implementation */
       2             : 
       3             : /*
       4             :    Unix SMB/CIFS implementation.
       5             : 
       6             :    endpoint server for the lsarpc pipe
       7             : 
       8             :    Copyright (C) Andrew Tridgell 2004
       9             :    Copyright (C) Andrew Bartlett <abartlet@samba.org> 2004-2008
      10             : 
      11             :    This program is free software; you can redistribute it and/or modify
      12             :    it under the terms of the GNU General Public License as published by
      13             :    the Free Software Foundation; either version 3 of the License, or
      14             :    (at your option) any later version.
      15             : 
      16             :    This program is distributed in the hope that it will be useful,
      17             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
      18             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      19             :    GNU General Public License for more details.
      20             : 
      21             :    You should have received a copy of the GNU General Public License
      22             :    along with this program.  If not, see <http://www.gnu.org/licenses/>.
      23             : */
      24             : 
      25             : #include "rpc_server/lsa/lsa.h"
      26             : #include "system/kerberos.h"
      27             : #include "auth/kerberos/kerberos.h"
      28             : #include "librpc/gen_ndr/ndr_drsblobs.h"
      29             : #include "librpc/gen_ndr/ndr_lsa.h"
      30             : #include "lib/util/tsort.h"
      31             : #include "dsdb/common/util.h"
      32             : #include "libcli/security/session.h"
      33             : #include "libcli/lsarpc/util_lsarpc.h"
      34             : #include "lib/messaging/irpc.h"
      35             : #include "libds/common/roles.h"
      36             : #include "lib/util/smb_strtox.h"
      37             : #include "lib/param/loadparm.h"
      38             : #include "librpc/rpc/dcerpc_helper.h"
      39             : #include "librpc/rpc/dcerpc_lsa.h"
      40             : 
      41             : #include "lib/crypto/gnutls_helpers.h"
      42             : #include <gnutls/gnutls.h>
      43             : #include <gnutls/crypto.h>
      44             : 
      45             : #undef strcasecmp
      46             : 
      47             : #define DCESRV_INTERFACE_LSARPC_BIND(context, iface) \
      48             :        dcesrv_interface_lsarpc_bind(context, iface)
      49        3810 : static NTSTATUS dcesrv_interface_lsarpc_bind(struct dcesrv_connection_context *context,
      50             :                                              const struct dcesrv_interface *iface)
      51             : {
      52        3810 :         return dcesrv_interface_bind_reject_connect(context, iface);
      53             : }
      54             : 
      55             : static NTSTATUS lsarpc__op_init_server(struct dcesrv_context *dce_ctx,
      56             :                                        const struct dcesrv_endpoint_server *ep_server);
      57             : static const struct dcesrv_interface dcesrv_lsarpc_interface;
      58             : 
      59             : #define NCACN_NP_PIPE_NETLOGON "ncacn_np:[\\pipe\\netlogon]"
      60             : #define NCACN_NP_PIPE_LSASS "ncacn_np:[\\pipe\\lsass]"
      61             : #define DCESRV_INTERFACE_LSARPC_NCACN_NP_SECONDARY_ENDPOINT NCACN_NP_PIPE_LSASS
      62             : 
      63             : #define DCESRV_INTERFACE_LSARPC_INIT_SERVER     \
      64             :        dcesrv_interface_lsarpc_init_server
      65          64 : static NTSTATUS dcesrv_interface_lsarpc_init_server(struct dcesrv_context *dce_ctx,
      66             :                                                     const struct dcesrv_endpoint_server *ep_server)
      67             : {
      68          64 :         if (lpcfg_lsa_over_netlogon(dce_ctx->lp_ctx)) {
      69           9 :                 NTSTATUS ret = dcesrv_interface_register(dce_ctx,
      70             :                                                 NCACN_NP_PIPE_NETLOGON,
      71             :                                                 NCACN_NP_PIPE_LSASS,
      72             :                                                 &dcesrv_lsarpc_interface, NULL);
      73           9 :                 if (!NT_STATUS_IS_OK(ret)) {
      74           0 :                         DEBUG(1,("lsarpc_op_init_server: failed to register endpoint '\\pipe\\netlogon'\n"));
      75           0 :                         return ret;
      76             :                 }
      77             :         }
      78          64 :         return lsarpc__op_init_server(dce_ctx, ep_server);
      79             : }
      80             : 
      81             : /*
      82             :   this type allows us to distinguish handle types
      83             : */
      84             : 
      85             : /*
      86             :   state associated with a lsa_OpenAccount() operation
      87             : */
      88             : struct lsa_account_state {
      89             :         struct lsa_policy_state *policy;
      90             :         uint32_t access_mask;
      91             :         struct dom_sid *account_sid;
      92             : };
      93             : 
      94             : 
      95             : /*
      96             :   state associated with a lsa_OpenSecret() operation
      97             : */
      98             : struct lsa_secret_state {
      99             :         struct lsa_policy_state *policy;
     100             :         uint32_t access_mask;
     101             :         struct ldb_dn *secret_dn;
     102             :         struct ldb_context *sam_ldb;
     103             :         bool global;
     104             : };
     105             : 
     106             : /*
     107             :   state associated with a lsa_OpenTrustedDomain() operation
     108             : */
     109             : struct lsa_trusted_domain_state {
     110             :         struct lsa_policy_state *policy;
     111             :         uint32_t access_mask;
     112             :         struct ldb_dn *trusted_domain_dn;
     113             :         struct ldb_dn *trusted_domain_user_dn;
     114             : };
     115             : 
     116         123 : static bool dcesrc_lsa_valid_AccountRight(const char *right)
     117             : {
     118           0 :         enum sec_privilege priv_id;
     119           0 :         uint32_t right_bit;
     120             : 
     121         123 :         priv_id = sec_privilege_id(right);
     122         123 :         if (priv_id != SEC_PRIV_INVALID) {
     123         115 :                 return true;
     124             :         }
     125             : 
     126           8 :         right_bit = sec_right_bit(right);
     127           8 :         if (right_bit != 0) {
     128           8 :                 return true;
     129             :         }
     130             : 
     131           0 :         return false;
     132             : }
     133             : 
     134             : /*
     135             :   this is based on the samba3 function make_lsa_object_sd()
     136             :   It uses the same logic, but with samba4 helper functions
     137             :  */
     138           0 : static NTSTATUS dcesrv_build_lsa_sd(TALLOC_CTX *mem_ctx,
     139             :                                     struct security_descriptor **sd,
     140             :                                     struct dom_sid *sid,
     141             :                                     uint32_t sid_access)
     142             : {
     143           0 :         NTSTATUS status;
     144           0 :         uint32_t rid;
     145           0 :         struct dom_sid *domain_sid, *domain_admins_sid;
     146           0 :         const char *domain_admins_sid_str, *sidstr;
     147           0 :         TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx);
     148             : 
     149           0 :         status = dom_sid_split_rid(tmp_ctx, sid, &domain_sid, &rid);
     150           0 :         if (!NT_STATUS_IS_OK(status)) {
     151           0 :                 TALLOC_FREE(tmp_ctx);
     152           0 :                 return status;
     153             :         }
     154             : 
     155           0 :         domain_admins_sid = dom_sid_add_rid(tmp_ctx, domain_sid, DOMAIN_RID_ADMINS);
     156           0 :         if (domain_admins_sid == NULL) {
     157           0 :                 TALLOC_FREE(tmp_ctx);
     158           0 :                 return NT_STATUS_NO_MEMORY;
     159             :         }
     160             : 
     161           0 :         domain_admins_sid_str = dom_sid_string(tmp_ctx, domain_admins_sid);
     162           0 :         if (domain_admins_sid_str == NULL) {
     163           0 :                 TALLOC_FREE(tmp_ctx);
     164           0 :                 return NT_STATUS_NO_MEMORY;
     165             :         }
     166             : 
     167           0 :         sidstr = dom_sid_string(tmp_ctx, sid);
     168           0 :         if (sidstr == NULL) {
     169           0 :                 TALLOC_FREE(tmp_ctx);
     170           0 :                 return NT_STATUS_NO_MEMORY;
     171             :         }
     172             : 
     173           0 :         *sd = security_descriptor_dacl_create(mem_ctx,
     174             :                                               0, sidstr, NULL,
     175             : 
     176             :                                               SID_WORLD,
     177             :                                               SEC_ACE_TYPE_ACCESS_ALLOWED,
     178             :                                               SEC_GENERIC_EXECUTE | SEC_GENERIC_READ, 0,
     179             : 
     180             :                                               SID_BUILTIN_ADMINISTRATORS,
     181             :                                               SEC_ACE_TYPE_ACCESS_ALLOWED,
     182             :                                               SEC_GENERIC_ALL, 0,
     183             : 
     184             :                                               SID_BUILTIN_ACCOUNT_OPERATORS,
     185             :                                               SEC_ACE_TYPE_ACCESS_ALLOWED,
     186             :                                               SEC_GENERIC_ALL, 0,
     187             : 
     188             :                                               domain_admins_sid_str,
     189             :                                               SEC_ACE_TYPE_ACCESS_ALLOWED,
     190             :                                               SEC_GENERIC_ALL, 0,
     191             : 
     192             :                                               sidstr,
     193             :                                               SEC_ACE_TYPE_ACCESS_ALLOWED,
     194             :                                               sid_access, 0,
     195             : 
     196             :                                               NULL);
     197           0 :         talloc_free(tmp_ctx);
     198             : 
     199           0 :         NT_STATUS_HAVE_NO_MEMORY(*sd);
     200             : 
     201           0 :         return NT_STATUS_OK;
     202             : }
     203             : 
     204             : 
     205             : static NTSTATUS dcesrv_lsa_EnumAccountRights(struct dcesrv_call_state *dce_call,
     206             :                                       TALLOC_CTX *mem_ctx,
     207             :                                       struct lsa_EnumAccountRights *r);
     208             : 
     209             : static NTSTATUS dcesrv_lsa_AddRemoveAccountRights(struct dcesrv_call_state *dce_call,
     210             :                                            TALLOC_CTX *mem_ctx,
     211             :                                            struct lsa_policy_state *state,
     212             :                                            int ldb_flag,
     213             :                                            struct dom_sid *sid,
     214             :                                            const struct lsa_RightSet *rights);
     215             : 
     216             : /*
     217             :   lsa_Close
     218             : */
     219        1032 : static NTSTATUS dcesrv_lsa_Close(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
     220             :                           struct lsa_Close *r)
     221             : {
     222          36 :         enum dcerpc_transport_t transport =
     223        1032 :                 dcerpc_binding_get_transport(dce_call->conn->endpoint->ep_description);
     224          36 :         struct dcesrv_handle *h;
     225             : 
     226        1032 :         if (transport != NCACN_NP && transport != NCALRPC) {
     227           0 :                 DCESRV_FAULT(DCERPC_FAULT_ACCESS_DENIED);
     228             :         }
     229             : 
     230        1032 :         *r->out.handle = *r->in.handle;
     231             : 
     232        1032 :         DCESRV_PULL_HANDLE(h, r->in.handle, DCESRV_HANDLE_ANY);
     233             : 
     234         863 :         talloc_free(h);
     235             : 
     236         863 :         ZERO_STRUCTP(r->out.handle);
     237             : 
     238         863 :         return NT_STATUS_OK;
     239             : }
     240             : 
     241             : 
     242             : /*
     243             :   lsa_Delete
     244             : */
     245          33 : static NTSTATUS dcesrv_lsa_Delete(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
     246             :                            struct lsa_Delete *r)
     247             : {
     248          33 :         return NT_STATUS_NOT_SUPPORTED;
     249             : }
     250             : 
     251             : 
     252             : /*
     253             :   lsa_DeleteObject
     254             : */
     255        1569 : static NTSTATUS dcesrv_lsa_DeleteObject(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
     256             :                        struct lsa_DeleteObject *r)
     257             : {
     258           0 :         struct auth_session_info *session_info =
     259        1569 :                 dcesrv_call_session_info(dce_call);
     260           0 :         struct dcesrv_handle *h;
     261           0 :         int ret;
     262             : 
     263        1569 :         DCESRV_PULL_HANDLE(h, r->in.handle, DCESRV_HANDLE_ANY);
     264             : 
     265        1569 :         if (h->wire_handle.handle_type == LSA_HANDLE_SECRET) {
     266        1413 :                 struct lsa_secret_state *secret_state = h->data;
     267             : 
     268             :                 /* Ensure user is permitted to delete this... */
     269        1413 :                 switch (security_session_user_level(session_info, NULL))
     270             :                 {
     271        1413 :                 case SECURITY_SYSTEM:
     272             :                 case SECURITY_ADMINISTRATOR:
     273        1413 :                         break;
     274           0 :                 default:
     275             :                         /* Users and anonymous are not allowed to delete things */
     276           0 :                         return NT_STATUS_ACCESS_DENIED;
     277             :                 }
     278             : 
     279        1413 :                 ret = ldb_delete(secret_state->sam_ldb,
     280             :                                  secret_state->secret_dn);
     281        1413 :                 if (ret != LDB_SUCCESS) {
     282          18 :                         return NT_STATUS_INVALID_HANDLE;
     283             :                 }
     284             : 
     285        1395 :                 ZERO_STRUCTP(r->out.handle);
     286             : 
     287        1395 :                 return NT_STATUS_OK;
     288             : 
     289         156 :         } else if (h->wire_handle.handle_type == LSA_HANDLE_TRUSTED_DOMAIN) {
     290           0 :                 struct lsa_trusted_domain_state *trusted_domain_state =
     291         149 :                         talloc_get_type(h->data, struct lsa_trusted_domain_state);
     292         149 :                 ret = ldb_transaction_start(trusted_domain_state->policy->sam_ldb);
     293         149 :                 if (ret != LDB_SUCCESS) {
     294           0 :                         return NT_STATUS_INTERNAL_DB_CORRUPTION;
     295             :                 }
     296             : 
     297         149 :                 ret = ldb_delete(trusted_domain_state->policy->sam_ldb,
     298             :                                  trusted_domain_state->trusted_domain_dn);
     299         149 :                 if (ret != LDB_SUCCESS) {
     300           0 :                         ldb_transaction_cancel(trusted_domain_state->policy->sam_ldb);
     301           0 :                         return NT_STATUS_INVALID_HANDLE;
     302             :                 }
     303             : 
     304         149 :                 if (trusted_domain_state->trusted_domain_user_dn) {
     305          77 :                         ret = ldb_delete(trusted_domain_state->policy->sam_ldb,
     306             :                                          trusted_domain_state->trusted_domain_user_dn);
     307          77 :                         if (ret != LDB_SUCCESS) {
     308           0 :                                 ldb_transaction_cancel(trusted_domain_state->policy->sam_ldb);
     309           0 :                                 return NT_STATUS_INVALID_HANDLE;
     310             :                         }
     311             :                 }
     312             : 
     313         149 :                 ret = ldb_transaction_commit(trusted_domain_state->policy->sam_ldb);
     314         149 :                 if (ret != LDB_SUCCESS) {
     315           0 :                         return NT_STATUS_INTERNAL_DB_CORRUPTION;
     316             :                 }
     317             : 
     318         149 :                 ZERO_STRUCTP(r->out.handle);
     319             : 
     320         149 :                 return NT_STATUS_OK;
     321             : 
     322           7 :         } else if (h->wire_handle.handle_type == LSA_HANDLE_ACCOUNT) {
     323           0 :                 struct lsa_RightSet *rights;
     324           0 :                 struct lsa_account_state *astate;
     325           0 :                 struct lsa_EnumAccountRights r2;
     326           0 :                 NTSTATUS status;
     327             : 
     328           7 :                 rights = talloc(mem_ctx, struct lsa_RightSet);
     329             : 
     330           7 :                 DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_ACCOUNT);
     331             : 
     332           7 :                 astate = h->data;
     333             : 
     334           7 :                 r2.in.handle = &astate->policy->handle->wire_handle;
     335           7 :                 r2.in.sid = astate->account_sid;
     336           7 :                 r2.out.rights = rights;
     337             : 
     338             :                 /* dcesrv_lsa_EnumAccountRights takes a LSA_HANDLE_POLICY,
     339             :                    but we have a LSA_HANDLE_ACCOUNT here, so this call
     340             :                    will always fail */
     341           7 :                 status = dcesrv_lsa_EnumAccountRights(dce_call, mem_ctx, &r2);
     342           7 :                 if (NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
     343           3 :                         return NT_STATUS_OK;
     344             :                 }
     345             : 
     346           4 :                 if (!NT_STATUS_IS_OK(status)) {
     347           0 :                         return status;
     348             :                 }
     349             : 
     350           4 :                 status = dcesrv_lsa_AddRemoveAccountRights(dce_call, mem_ctx, astate->policy,
     351             :                                                     LDB_FLAG_MOD_DELETE, astate->account_sid,
     352           4 :                                                     r2.out.rights);
     353           4 :                 if (NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
     354           0 :                         return NT_STATUS_OK;
     355             :                 }
     356             : 
     357           4 :                 if (!NT_STATUS_IS_OK(status)) {
     358           0 :                         return status;
     359             :                 }
     360             : 
     361           4 :                 ZERO_STRUCTP(r->out.handle);
     362             : 
     363           4 :                 return NT_STATUS_OK;
     364             :         }
     365             : 
     366           0 :         return NT_STATUS_INVALID_HANDLE;
     367             : }
     368             : 
     369             : 
     370             : /*
     371             :   lsa_EnumPrivs
     372             : */
     373           3 : static NTSTATUS dcesrv_lsa_EnumPrivs(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
     374             :                               struct lsa_EnumPrivs *r)
     375             : {
     376           0 :         struct dcesrv_handle *h;
     377           0 :         uint32_t i;
     378           0 :         enum sec_privilege priv;
     379           0 :         const char *privname;
     380             : 
     381           3 :         DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
     382             : 
     383           3 :         i = *r->in.resume_handle;
     384             : 
     385          78 :         while (((priv = sec_privilege_from_index(i)) != SEC_PRIV_INVALID) &&
     386          75 :                r->out.privs->count < r->in.max_count) {
     387           0 :                 struct lsa_PrivEntry *e;
     388          75 :                 privname = sec_privilege_name(priv);
     389          75 :                 r->out.privs->privs = talloc_realloc(r->out.privs,
     390             :                                                        r->out.privs->privs,
     391             :                                                        struct lsa_PrivEntry,
     392             :                                                        r->out.privs->count+1);
     393          75 :                 if (r->out.privs->privs == NULL) {
     394           0 :                         return NT_STATUS_NO_MEMORY;
     395             :                 }
     396          75 :                 e = &r->out.privs->privs[r->out.privs->count];
     397          75 :                 e->luid.low = priv;
     398          75 :                 e->luid.high = 0;
     399          75 :                 e->name.string = privname;
     400          75 :                 r->out.privs->count++;
     401          75 :                 i++;
     402             :         }
     403             : 
     404           3 :         *r->out.resume_handle = i;
     405             : 
     406           3 :         return NT_STATUS_OK;
     407             : }
     408             : 
     409             : 
     410             : /*
     411             :   lsa_QuerySecObj
     412             : */
     413          48 : static NTSTATUS dcesrv_lsa_QuerySecurity(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
     414             :                                          struct lsa_QuerySecurity *r)
     415             : {
     416          12 :         struct auth_session_info *session_info =
     417          48 :                 dcesrv_call_session_info(dce_call);
     418          12 :         struct dcesrv_handle *h;
     419          48 :         const struct security_descriptor *sd = NULL;
     420          48 :         uint32_t access_granted = 0;
     421          48 :         struct sec_desc_buf *sdbuf = NULL;
     422          12 :         NTSTATUS status;
     423          12 :         struct dom_sid *sid;
     424             : 
     425          48 :         DCESRV_PULL_HANDLE(h, r->in.handle, DCESRV_HANDLE_ANY);
     426             : 
     427          48 :         sid = &session_info->security_token->sids[PRIMARY_USER_SID_INDEX];
     428             : 
     429          48 :         if (h->wire_handle.handle_type == LSA_HANDLE_POLICY) {
     430          48 :                 struct lsa_policy_state *pstate = h->data;
     431             : 
     432          48 :                 sd = pstate->sd;
     433          48 :                 access_granted = pstate->access_mask;
     434             : 
     435           0 :         } else if (h->wire_handle.handle_type == LSA_HANDLE_ACCOUNT) {
     436           0 :                 struct lsa_account_state *astate = h->data;
     437           0 :                 struct security_descriptor *_sd = NULL;
     438             : 
     439           0 :                 status = dcesrv_build_lsa_sd(mem_ctx, &_sd, sid,
     440             :                                              LSA_ACCOUNT_ALL_ACCESS);
     441           0 :                 if (!NT_STATUS_IS_OK(status)) {
     442           0 :                         return status;
     443             :                 }
     444           0 :                 sd = _sd;
     445           0 :                 access_granted = astate->access_mask;
     446             :         } else {
     447           0 :                 return NT_STATUS_INVALID_HANDLE;
     448             :         }
     449             : 
     450          48 :         sdbuf = talloc_zero(mem_ctx, struct sec_desc_buf);
     451          48 :         if (sdbuf == NULL) {
     452           0 :                 return NT_STATUS_NO_MEMORY;
     453             :         }
     454             : 
     455          48 :         status = security_descriptor_for_client(sdbuf, sd, r->in.sec_info,
     456             :                                                 access_granted, &sdbuf->sd);
     457          48 :         if (!NT_STATUS_IS_OK(status)) {
     458           0 :                 return status;
     459             :         }
     460             : 
     461          48 :         *r->out.sdbuf = sdbuf;
     462             : 
     463          48 :         return NT_STATUS_OK;
     464             : }
     465             : 
     466             : 
     467             : /*
     468             :   lsa_SetSecObj
     469             : */
     470           0 : static NTSTATUS dcesrv_lsa_SetSecObj(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
     471             :                               struct lsa_SetSecObj *r)
     472             : {
     473           0 :         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
     474             : }
     475             : 
     476             : 
     477             : /*
     478             :   lsa_ChangePassword
     479             : */
     480           0 : static NTSTATUS dcesrv_lsa_ChangePassword(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
     481             :                                    struct lsa_ChangePassword *r)
     482             : {
     483           0 :         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
     484             : }
     485             : 
     486             : /*
     487             :   dssetup_DsRoleGetPrimaryDomainInformation
     488             : 
     489             :   This is not an LSA call, but is the only call left on the DSSETUP
     490             :   pipe (after the pipe was truncated), and needs lsa_get_policy_state
     491             : */
     492         123 : static WERROR dcesrv_dssetup_DsRoleGetPrimaryDomainInformation(struct dcesrv_call_state *dce_call,
     493             :                                                  TALLOC_CTX *mem_ctx,
     494             :                                                  struct dssetup_DsRoleGetPrimaryDomainInformation *r)
     495             : {
     496           9 :         union dssetup_DsRoleInfo *info;
     497             : 
     498         123 :         info = talloc_zero(mem_ctx, union dssetup_DsRoleInfo);
     499         123 :         W_ERROR_HAVE_NO_MEMORY(info);
     500             : 
     501         123 :         switch (r->in.level) {
     502          63 :         case DS_ROLE_BASIC_INFORMATION:
     503             :         {
     504          63 :                 enum dssetup_DsRole role = DS_ROLE_STANDALONE_SERVER;
     505          63 :                 uint32_t flags = 0;
     506          63 :                 const char *domain = NULL;
     507          63 :                 const char *dns_domain = NULL;
     508          63 :                 const char *forest = NULL;
     509           3 :                 struct GUID domain_guid;
     510           3 :                 struct lsa_policy_state *state;
     511             : 
     512          63 :                 NTSTATUS status = dcesrv_lsa_get_policy_state(dce_call, mem_ctx,
     513             :                                                               0, /* we skip access checks */
     514             :                                                               &state);
     515          63 :                 if (!NT_STATUS_IS_OK(status)) {
     516           0 :                         return ntstatus_to_werror(status);
     517             :                 }
     518             : 
     519          63 :                 ZERO_STRUCT(domain_guid);
     520             : 
     521          63 :                 switch (lpcfg_server_role(dce_call->conn->dce_ctx->lp_ctx)) {
     522           0 :                 case ROLE_STANDALONE:
     523           0 :                         role            = DS_ROLE_STANDALONE_SERVER;
     524           0 :                         break;
     525           4 :                 case ROLE_DOMAIN_MEMBER:
     526           4 :                         role            = DS_ROLE_MEMBER_SERVER;
     527           4 :                         break;
     528          59 :                 case ROLE_ACTIVE_DIRECTORY_DC:
     529          59 :                         if (samdb_is_pdc(state->sam_ldb)) {
     530          56 :                                 role    = DS_ROLE_PRIMARY_DC;
     531             :                         } else {
     532           0 :                                 role    = DS_ROLE_BACKUP_DC;
     533             :                         }
     534          56 :                         break;
     535             :                 }
     536             : 
     537          63 :                 switch (lpcfg_server_role(dce_call->conn->dce_ctx->lp_ctx)) {
     538           0 :                 case ROLE_STANDALONE:
     539           0 :                         domain          = talloc_strdup(mem_ctx, lpcfg_workgroup(dce_call->conn->dce_ctx->lp_ctx));
     540           0 :                         W_ERROR_HAVE_NO_MEMORY(domain);
     541           0 :                         break;
     542           4 :                 case ROLE_DOMAIN_MEMBER:
     543           4 :                         domain          = talloc_strdup(mem_ctx, lpcfg_workgroup(dce_call->conn->dce_ctx->lp_ctx));
     544           4 :                         W_ERROR_HAVE_NO_MEMORY(domain);
     545             :                         /* TODO: what is with dns_domain and forest and guid? */
     546           4 :                         break;
     547          59 :                 case ROLE_ACTIVE_DIRECTORY_DC:
     548          59 :                         flags           = DS_ROLE_PRIMARY_DS_RUNNING;
     549             : 
     550          59 :                         if (state->mixed_domain == 1) {
     551           0 :                                 flags   |= DS_ROLE_PRIMARY_DS_MIXED_MODE;
     552             :                         }
     553             : 
     554          59 :                         domain          = state->domain_name;
     555          59 :                         dns_domain      = state->domain_dns;
     556          59 :                         forest          = state->forest_dns;
     557             : 
     558          59 :                         domain_guid     = state->domain_guid;
     559          59 :                         flags   |= DS_ROLE_PRIMARY_DOMAIN_GUID_PRESENT;
     560          59 :                         break;
     561             :                 }
     562             : 
     563          63 :                 info->basic.role        = role;
     564          63 :                 info->basic.flags       = flags;
     565          63 :                 info->basic.domain      = domain;
     566          63 :                 info->basic.dns_domain  = dns_domain;
     567          63 :                 info->basic.forest      = forest;
     568          63 :                 info->basic.domain_guid = domain_guid;
     569             : 
     570          63 :                 r->out.info = info;
     571          63 :                 return WERR_OK;
     572             :         }
     573          30 :         case DS_ROLE_UPGRADE_STATUS:
     574             :         {
     575          30 :                 info->upgrade.upgrading     = DS_ROLE_NOT_UPGRADING;
     576          30 :                 info->upgrade.previous_role = DS_ROLE_PREVIOUS_UNKNOWN;
     577             : 
     578          30 :                 r->out.info = info;
     579          30 :                 return WERR_OK;
     580             :         }
     581          30 :         case DS_ROLE_OP_STATUS:
     582             :         {
     583          30 :                 info->opstatus.status = DS_ROLE_OP_IDLE;
     584             : 
     585          30 :                 r->out.info = info;
     586          30 :                 return WERR_OK;
     587             :         }
     588           0 :         default:
     589           0 :                 return WERR_INVALID_PARAMETER;
     590             :         }
     591             : }
     592             : 
     593             : /*
     594             :   fill in the AccountDomain info
     595             : */
     596         755 : static NTSTATUS dcesrv_lsa_info_AccountDomain(struct lsa_policy_state *state, TALLOC_CTX *mem_ctx,
     597             :                                        struct lsa_DomainInfo *info)
     598             : {
     599         755 :         info->name.string = state->domain_name;
     600         755 :         info->sid         = state->domain_sid;
     601             : 
     602         755 :         return NT_STATUS_OK;
     603             : }
     604             : 
     605             : /*
     606             :   fill in the DNS domain info
     607             : */
     608         887 : static NTSTATUS dcesrv_lsa_info_DNS(struct lsa_policy_state *state, TALLOC_CTX *mem_ctx,
     609             :                              struct lsa_DnsDomainInfo *info)
     610             : {
     611         887 :         info->name.string = state->domain_name;
     612         887 :         info->sid         = state->domain_sid;
     613         887 :         info->dns_domain.string = state->domain_dns;
     614         887 :         info->dns_forest.string = state->forest_dns;
     615         887 :         info->domain_guid       = state->domain_guid;
     616             : 
     617         887 :         return NT_STATUS_OK;
     618             : }
     619             : 
     620             : /*
     621             :   lsa_QueryInfoPolicy2
     622             : */
     623        1858 : static NTSTATUS dcesrv_lsa_QueryInfoPolicy2(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
     624             :                                      struct lsa_QueryInfoPolicy2 *r)
     625             : {
     626         146 :         struct lsa_policy_state *state;
     627         146 :         struct dcesrv_handle *h;
     628         146 :         union lsa_PolicyInformation *info;
     629             : 
     630        1858 :         *r->out.info = NULL;
     631             : 
     632        1858 :         DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
     633             : 
     634        1858 :         state = h->data;
     635             : 
     636        1858 :         info = talloc_zero(mem_ctx, union lsa_PolicyInformation);
     637        1858 :         if (!info) {
     638           0 :                 return NT_STATUS_NO_MEMORY;
     639             :         }
     640        1858 :         *r->out.info = info;
     641             : 
     642        1858 :         switch (r->in.level) {
     643          24 :         case LSA_POLICY_INFO_AUDIT_LOG:
     644             :                 /* we don't need to fill in any of this */
     645          24 :                 ZERO_STRUCT(info->audit_log);
     646          24 :                 return NT_STATUS_OK;
     647          24 :         case LSA_POLICY_INFO_AUDIT_EVENTS:
     648             :                 /* we don't need to fill in any of this */
     649          24 :                 ZERO_STRUCT(info->audit_events);
     650          24 :                 return NT_STATUS_OK;
     651          24 :         case LSA_POLICY_INFO_PD:
     652             :                 /* we don't need to fill in any of this */
     653          24 :                 ZERO_STRUCT(info->pd);
     654          24 :                 return NT_STATUS_OK;
     655             : 
     656         563 :         case LSA_POLICY_INFO_DOMAIN:
     657         563 :                 return dcesrv_lsa_info_AccountDomain(state, mem_ctx, &info->domain);
     658         168 :         case LSA_POLICY_INFO_ACCOUNT_DOMAIN:
     659         168 :                 return dcesrv_lsa_info_AccountDomain(state, mem_ctx, &info->account_domain);
     660          24 :         case LSA_POLICY_INFO_L_ACCOUNT_DOMAIN:
     661          24 :                 return dcesrv_lsa_info_AccountDomain(state, mem_ctx, &info->l_account_domain);
     662             : 
     663          24 :         case LSA_POLICY_INFO_ROLE:
     664          24 :                 info->role.role = LSA_ROLE_PRIMARY;
     665          24 :                 return NT_STATUS_OK;
     666             : 
     667         863 :         case LSA_POLICY_INFO_DNS:
     668         863 :                 return dcesrv_lsa_info_DNS(state, mem_ctx, &info->dns);
     669          24 :         case LSA_POLICY_INFO_DNS_INT:
     670          24 :                 return dcesrv_lsa_info_DNS(state, mem_ctx, &info->dns_int);
     671             : 
     672          24 :         case LSA_POLICY_INFO_REPLICA:
     673          24 :                 ZERO_STRUCT(info->replica);
     674          24 :                 return NT_STATUS_OK;
     675             : 
     676          24 :         case LSA_POLICY_INFO_QUOTA:
     677          24 :                 ZERO_STRUCT(info->quota);
     678          24 :                 return NT_STATUS_OK;
     679             : 
     680          72 :         case LSA_POLICY_INFO_MOD:
     681             :         case LSA_POLICY_INFO_AUDIT_FULL_SET:
     682             :         case LSA_POLICY_INFO_AUDIT_FULL_QUERY:
     683             :                 /* windows gives INVALID_PARAMETER */
     684          72 :                 *r->out.info = NULL;
     685          72 :                 return NT_STATUS_INVALID_PARAMETER;
     686             :         }
     687             : 
     688           0 :         *r->out.info = NULL;
     689           0 :         return NT_STATUS_INVALID_INFO_CLASS;
     690             : }
     691             : 
     692             : /*
     693             :   lsa_QueryInfoPolicy
     694             : */
     695         851 : static NTSTATUS dcesrv_lsa_QueryInfoPolicy(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
     696             :                                     struct lsa_QueryInfoPolicy *r)
     697             : {
     698          72 :         struct lsa_QueryInfoPolicy2 r2;
     699          72 :         NTSTATUS status;
     700             : 
     701         851 :         ZERO_STRUCT(r2);
     702             : 
     703         851 :         r2.in.handle = r->in.handle;
     704         851 :         r2.in.level = r->in.level;
     705         851 :         r2.out.info = r->out.info;
     706             : 
     707         851 :         status = dcesrv_lsa_QueryInfoPolicy2(dce_call, mem_ctx, &r2);
     708             : 
     709         851 :         return status;
     710             : }
     711             : 
     712             : /*
     713             :   lsa_SetInfoPolicy
     714             : */
     715           0 : static NTSTATUS dcesrv_lsa_SetInfoPolicy(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
     716             :                                   struct lsa_SetInfoPolicy *r)
     717             : {
     718             :         /* need to support this */
     719           0 :         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
     720             : }
     721             : 
     722             : 
     723             : /*
     724             :   lsa_ClearAuditLog
     725             : */
     726           0 : static NTSTATUS dcesrv_lsa_ClearAuditLog(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
     727             :                                   struct lsa_ClearAuditLog *r)
     728             : {
     729           0 :         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
     730             : }
     731             : 
     732             : 
     733             : static const struct generic_mapping dcesrv_lsa_account_mapping = {
     734             :         LSA_ACCOUNT_READ,
     735             :         LSA_ACCOUNT_WRITE,
     736             :         LSA_ACCOUNT_EXECUTE,
     737             :         LSA_ACCOUNT_ALL_ACCESS
     738             : };
     739             : 
     740             : /*
     741             :   lsa_CreateAccount
     742             : 
     743             :   This call does not seem to have any long-term effects, hence no database operations
     744             : 
     745             :   we need to talk to the MS product group to find out what this account database means!
     746             : 
     747             :   answer is that the lsa database is totally separate from the SAM and
     748             :   ldap databases. We are going to need a separate ldb to store these
     749             :   accounts. The SIDs on this account bear no relation to the SIDs in
     750             :   AD
     751             : */
     752           3 : static NTSTATUS dcesrv_lsa_CreateAccount(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
     753             :                                   struct lsa_CreateAccount *r)
     754             : {
     755           0 :         struct lsa_account_state *astate;
     756             : 
     757           0 :         struct lsa_policy_state *state;
     758           0 :         struct dcesrv_handle *h, *ah;
     759             : 
     760           3 :         ZERO_STRUCTP(r->out.acct_handle);
     761             : 
     762           3 :         DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
     763             : 
     764           3 :         state = h->data;
     765             : 
     766           3 :         astate = talloc(dce_call->conn, struct lsa_account_state);
     767           3 :         if (astate == NULL) {
     768           0 :                 return NT_STATUS_NO_MEMORY;
     769             :         }
     770             : 
     771           3 :         astate->account_sid = dom_sid_dup(astate, r->in.sid);
     772           3 :         if (astate->account_sid == NULL) {
     773           0 :                 talloc_free(astate);
     774           0 :                 return NT_STATUS_NO_MEMORY;
     775             :         }
     776             : 
     777           3 :         astate->policy = talloc_reference(astate, state);
     778           3 :         astate->access_mask = r->in.access_mask;
     779             : 
     780             :         /*
     781             :          * For now we grant all requested access.
     782             :          *
     783             :          * We will fail at the ldb layer later.
     784             :          */
     785           3 :         if (astate->access_mask & SEC_FLAG_MAXIMUM_ALLOWED) {
     786           3 :                 astate->access_mask &= ~SEC_FLAG_MAXIMUM_ALLOWED;
     787           3 :                 astate->access_mask |= LSA_ACCOUNT_ALL_ACCESS;
     788             :         }
     789           3 :         se_map_generic(&astate->access_mask, &dcesrv_lsa_account_mapping);
     790             : 
     791           3 :         DEBUG(10,("%s: %s access desired[0x%08X] granted[0x%08X].\n",
     792             :                   __func__, dom_sid_string(mem_ctx, astate->account_sid),
     793             :                  (unsigned)r->in.access_mask,
     794             :                  (unsigned)astate->access_mask));
     795             : 
     796           3 :         ah = dcesrv_handle_create(dce_call, LSA_HANDLE_ACCOUNT);
     797           3 :         if (!ah) {
     798           0 :                 talloc_free(astate);
     799           0 :                 return NT_STATUS_NO_MEMORY;
     800             :         }
     801             : 
     802           3 :         ah->data = talloc_steal(ah, astate);
     803             : 
     804           3 :         *r->out.acct_handle = ah->wire_handle;
     805             : 
     806           3 :         return NT_STATUS_OK;
     807             : }
     808             : 
     809             : 
     810             : /*
     811             :   lsa_EnumAccounts
     812             : */
     813          18 : static NTSTATUS dcesrv_lsa_EnumAccounts(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
     814             :                                  struct lsa_EnumAccounts *r)
     815             : {
     816           0 :         struct dcesrv_handle *h;
     817           0 :         struct lsa_policy_state *state;
     818           0 :         int ret;
     819           0 :         struct ldb_message **res;
     820          18 :         const char * const attrs[] = { "objectSid", NULL};
     821           0 :         uint32_t count, i;
     822             : 
     823          18 :         DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
     824             : 
     825          18 :         state = h->data;
     826             : 
     827             :         /* NOTE: This call must only return accounts that have at least
     828             :            one privilege set
     829             :         */
     830          18 :         ret = gendb_search(state->pdb, mem_ctx, NULL, &res, attrs,
     831             :                            "(&(objectSid=*)(privilege=*))");
     832          18 :         if (ret < 0) {
     833           0 :                 return NT_STATUS_INTERNAL_DB_CORRUPTION;
     834             :         }
     835             : 
     836          18 :         if (*r->in.resume_handle >= ret) {
     837           3 :                 return NT_STATUS_NO_MORE_ENTRIES;
     838             :         }
     839             : 
     840          15 :         count = ret - *r->in.resume_handle;
     841          15 :         if (count > r->in.num_entries) {
     842           0 :                 count = r->in.num_entries;
     843             :         }
     844             : 
     845          15 :         if (count == 0) {
     846           0 :                 return NT_STATUS_NO_MORE_ENTRIES;
     847             :         }
     848             : 
     849          15 :         r->out.sids->sids = talloc_array(r->out.sids, struct lsa_SidPtr, count);
     850          15 :         if (r->out.sids->sids == NULL) {
     851           0 :                 return NT_STATUS_NO_MEMORY;
     852             :         }
     853             : 
     854         113 :         for (i=0;i<count;i++) {
     855         196 :                 r->out.sids->sids[i].sid =
     856          98 :                         samdb_result_dom_sid(r->out.sids->sids,
     857          98 :                                              res[i + *r->in.resume_handle],
     858             :                                              "objectSid");
     859          98 :                 NT_STATUS_HAVE_NO_MEMORY(r->out.sids->sids[i].sid);
     860             :         }
     861             : 
     862          15 :         r->out.sids->num_sids = count;
     863          15 :         *r->out.resume_handle = count + *r->in.resume_handle;
     864             : 
     865          15 :         return NT_STATUS_OK;
     866             : }
     867             : 
     868          59 : static NTSTATUS get_trustdom_auth_blob_aes(
     869             :         struct dcesrv_call_state *dce_call,
     870             :         TALLOC_CTX *mem_ctx,
     871             :         struct lsa_TrustDomainInfoAuthInfoInternalAES *auth_info,
     872             :         struct trustDomainPasswords *auth_struct)
     873             : {
     874          59 :         DATA_BLOB session_key = data_blob_null;
     875          59 :         DATA_BLOB salt = data_blob(auth_info->salt, sizeof(auth_info->salt));
     876          59 :         DATA_BLOB auth_blob = data_blob(auth_info->cipher.data,
     877             :                                         auth_info->cipher.size);
     878          59 :         DATA_BLOB ciphertext = data_blob_null;
     879           0 :         enum ndr_err_code ndr_err;
     880           0 :         NTSTATUS status;
     881             : 
     882             :         /*
     883             :          * The data blob starts with 512 bytes of random data and has two 32bit
     884             :          * size parameters.
     885             :          */
     886          59 :         if (auth_blob.length < 520) {
     887           0 :                 return NT_STATUS_INVALID_PARAMETER;
     888             :         }
     889             : 
     890          59 :         status = dcesrv_transport_session_key(dce_call, &session_key);
     891          59 :         if (!NT_STATUS_IS_OK(status)) {
     892           0 :                 return status;
     893             :         }
     894             : 
     895          59 :         status = samba_gnutls_aead_aes_256_cbc_hmac_sha512_decrypt(
     896             :                 mem_ctx,
     897             :                 &auth_blob,
     898             :                 &session_key,
     899             :                 &lsa_aes256_enc_key_salt,
     900             :                 &lsa_aes256_mac_key_salt,
     901             :                 &salt,
     902          59 :                 auth_info->auth_data,
     903             :                 &ciphertext);
     904          59 :         if (!NT_STATUS_IS_OK(status)) {
     905           0 :                 return status;
     906             :         }
     907             : 
     908          59 :         ndr_err = ndr_pull_struct_blob(
     909             :                         &ciphertext,
     910             :                         mem_ctx,
     911             :                         auth_struct,
     912             :                         (ndr_pull_flags_fn_t)ndr_pull_trustDomainPasswords);
     913          59 :         if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
     914           0 :                 return NT_STATUS_INVALID_PARAMETER;
     915             :         }
     916             : 
     917          59 :         return NT_STATUS_OK;
     918             : }
     919             : 
     920             : /* This decrypts and returns Trusted Domain Auth Information Internal data */
     921          44 : static NTSTATUS get_trustdom_auth_blob(struct dcesrv_call_state *dce_call,
     922             :                                        TALLOC_CTX *mem_ctx, DATA_BLOB *auth_blob,
     923             :                                        struct trustDomainPasswords *auth_struct)
     924             : {
     925          44 :         DATA_BLOB session_key = data_blob(NULL, 0);
     926           0 :         enum ndr_err_code ndr_err;
     927           0 :         NTSTATUS nt_status;
     928          44 :         gnutls_cipher_hd_t cipher_hnd = NULL;
     929           0 :         gnutls_datum_t _session_key;
     930           0 :         int rc;
     931           0 :         struct auth_session_info *session_info =
     932          44 :                 dcesrv_call_session_info(dce_call);
     933          44 :         struct loadparm_context *lp_ctx = dce_call->conn->dce_ctx->lp_ctx;
     934           0 :         bool encrypted;
     935             : 
     936           0 :         encrypted =
     937          44 :                 dcerpc_is_transport_encrypted(session_info);
     938          44 :         if (lpcfg_weak_crypto(lp_ctx) == SAMBA_WEAK_CRYPTO_DISALLOWED &&
     939           0 :             !encrypted) {
     940           0 :                 DBG_ERR("Transport isn't encrypted and weak crypto disallowed!\n");
     941           0 :                 return NT_STATUS_ACCESS_DENIED;
     942             :         }
     943             : 
     944             : 
     945          44 :         nt_status = dcesrv_transport_session_key(dce_call, &session_key);
     946          44 :         if (!NT_STATUS_IS_OK(nt_status)) {
     947           0 :                 return nt_status;
     948             :         }
     949             : 
     950          44 :         _session_key = (gnutls_datum_t) {
     951          44 :                 .data = session_key.data,
     952          44 :                 .size = session_key.length,
     953             :         };
     954             : 
     955          44 :         GNUTLS_FIPS140_SET_LAX_MODE();
     956          44 :         rc = gnutls_cipher_init(&cipher_hnd,
     957             :                                 GNUTLS_CIPHER_ARCFOUR_128,
     958             :                                 &_session_key,
     959             :                                 NULL);
     960          44 :         if (rc < 0) {
     961           0 :                 GNUTLS_FIPS140_SET_STRICT_MODE();
     962           0 :                 nt_status = gnutls_error_to_ntstatus(rc, NT_STATUS_CRYPTO_SYSTEM_INVALID);
     963           0 :                 goto out;
     964             :         }
     965             : 
     966          44 :         rc = gnutls_cipher_decrypt(cipher_hnd,
     967          44 :                                    auth_blob->data,
     968             :                                    auth_blob->length);
     969          44 :         gnutls_cipher_deinit(cipher_hnd);
     970          44 :         GNUTLS_FIPS140_SET_STRICT_MODE();
     971          44 :         if (rc < 0) {
     972           0 :                 nt_status = gnutls_error_to_ntstatus(rc, NT_STATUS_CRYPTO_SYSTEM_INVALID);
     973           0 :                 goto out;
     974             :         }
     975             : 
     976          44 :         ndr_err = ndr_pull_struct_blob(auth_blob, mem_ctx,
     977             :                                        auth_struct,
     978             :                                        (ndr_pull_flags_fn_t)ndr_pull_trustDomainPasswords);
     979          44 :         if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
     980           0 :                 return NT_STATUS_INVALID_PARAMETER;
     981             :         }
     982             : 
     983          44 :         nt_status = NT_STATUS_OK;
     984          44 : out:
     985          44 :         return nt_status;
     986             : }
     987             : 
     988         200 : static NTSTATUS get_trustauth_inout_blob(struct dcesrv_call_state *dce_call,
     989             :                                          TALLOC_CTX *mem_ctx,
     990             :                                          struct trustAuthInOutBlob *iopw,
     991             :                                          DATA_BLOB *trustauth_blob)
     992             : {
     993           0 :         enum ndr_err_code ndr_err;
     994             : 
     995         200 :         if (iopw->current.count != iopw->count) {
     996           0 :                 return NT_STATUS_INVALID_PARAMETER;
     997             :         }
     998             : 
     999         200 :         if (iopw->previous.count > iopw->current.count) {
    1000           0 :                 return NT_STATUS_INVALID_PARAMETER;
    1001             :         }
    1002             : 
    1003         200 :         if (iopw->previous.count == 0) {
    1004             :                 /*
    1005             :                  * If the previous credentials are not present
    1006             :                  * we need to make a copy.
    1007             :                  */
    1008          56 :                 iopw->previous = iopw->current;
    1009             :         }
    1010             : 
    1011         200 :         if (iopw->previous.count < iopw->current.count) {
    1012           0 :                 struct AuthenticationInformationArray *c = &iopw->current;
    1013           0 :                 struct AuthenticationInformationArray *p = &iopw->previous;
    1014             : 
    1015             :                 /*
    1016             :                  * The previous array needs to have the same size
    1017             :                  * as the current one.
    1018             :                  *
    1019             :                  * We may have to fill with TRUST_AUTH_TYPE_NONE
    1020             :                  * elements.
    1021             :                  */
    1022           0 :                 p->array = talloc_realloc(mem_ctx, p->array,
    1023             :                                    struct AuthenticationInformation,
    1024             :                                    c->count);
    1025           0 :                 if (p->array == NULL) {
    1026           0 :                         return NT_STATUS_NO_MEMORY;
    1027             :                 }
    1028             : 
    1029           0 :                 while (p->count < c->count) {
    1030           0 :                         struct AuthenticationInformation *a =
    1031           0 :                                 &p->array[p->count++];
    1032             : 
    1033           0 :                         *a = (struct AuthenticationInformation) {
    1034           0 :                                 .LastUpdateTime = p->array[0].LastUpdateTime,
    1035             :                                 .AuthType = TRUST_AUTH_TYPE_NONE,
    1036             :                         };
    1037             :                 }
    1038             :         }
    1039             : 
    1040         200 :         ndr_err = ndr_push_struct_blob(trustauth_blob, mem_ctx,
    1041             :                                        iopw,
    1042             :                                        (ndr_push_flags_fn_t)ndr_push_trustAuthInOutBlob);
    1043         200 :         if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
    1044           0 :                 return NT_STATUS_INVALID_PARAMETER;
    1045             :         }
    1046             : 
    1047         200 :         return NT_STATUS_OK;
    1048             : }
    1049             : 
    1050         100 : static NTSTATUS add_trust_user(TALLOC_CTX *mem_ctx,
    1051             :                                struct ldb_context *sam_ldb,
    1052             :                                struct ldb_dn *base_dn,
    1053             :                                const char *netbios_name,
    1054             :                                struct trustAuthInOutBlob *in,
    1055             :                                struct ldb_dn **user_dn)
    1056             : {
    1057           0 :         struct ldb_request *req;
    1058           0 :         struct ldb_message *msg;
    1059           0 :         struct ldb_dn *dn;
    1060           0 :         uint32_t i;
    1061           0 :         int ret;
    1062             : 
    1063         100 :         dn = ldb_dn_copy(mem_ctx, base_dn);
    1064         100 :         if (!dn) {
    1065           0 :                 return NT_STATUS_NO_MEMORY;
    1066             :         }
    1067         100 :         if (!ldb_dn_add_child_fmt(dn, "cn=%s$,cn=users", netbios_name)) {
    1068           0 :                 return NT_STATUS_NO_MEMORY;
    1069             :         }
    1070             : 
    1071         100 :         msg = ldb_msg_new(mem_ctx);
    1072         100 :         if (!msg) {
    1073           0 :                 return NT_STATUS_NO_MEMORY;
    1074             :         }
    1075         100 :         msg->dn = dn;
    1076             : 
    1077         100 :         ret = ldb_msg_add_string(msg, "objectClass", "user");
    1078         100 :         if (ret != LDB_SUCCESS) {
    1079           0 :                 return NT_STATUS_NO_MEMORY;
    1080             :         }
    1081             : 
    1082         100 :         ret = ldb_msg_add_fmt(msg, "samAccountName", "%s$", netbios_name);
    1083         100 :         if (ret != LDB_SUCCESS) {
    1084           0 :                 return NT_STATUS_NO_MEMORY;
    1085             :         }
    1086             : 
    1087         100 :         ret = samdb_msg_add_uint(sam_ldb, msg, msg, "userAccountControl",
    1088             :                                  UF_INTERDOMAIN_TRUST_ACCOUNT);
    1089         100 :         if (ret != LDB_SUCCESS) {
    1090           0 :                 return NT_STATUS_NO_MEMORY;
    1091             :         }
    1092             : 
    1093         176 :         for (i = 0; i < in->count; i++) {
    1094           0 :                 const char *attribute;
    1095           0 :                 struct ldb_val v;
    1096          76 :                 switch (in->current.array[i].AuthType) {
    1097           0 :                 case TRUST_AUTH_TYPE_NT4OWF:
    1098           0 :                         attribute = "unicodePwd";
    1099           0 :                         v.data = (uint8_t *)&in->current.array[i].AuthInfo.nt4owf.password;
    1100           0 :                         v.length = 16;
    1101           0 :                         break;
    1102          76 :                 case TRUST_AUTH_TYPE_CLEAR:
    1103          76 :                         attribute = "clearTextPassword";
    1104          76 :                         v.data = in->current.array[i].AuthInfo.clear.password;
    1105          76 :                         v.length = in->current.array[i].AuthInfo.clear.size;
    1106          76 :                         break;
    1107           0 :                 default:
    1108           0 :                         continue;
    1109             :                 }
    1110             : 
    1111          76 :                 ret = ldb_msg_add_value(msg, attribute, &v, NULL);
    1112          76 :                 if (ret != LDB_SUCCESS) {
    1113           0 :                         return NT_STATUS_NO_MEMORY;
    1114             :                 }
    1115             :         }
    1116             : 
    1117             :         /* create the trusted_domain user account */
    1118         100 :         ret = ldb_build_add_req(&req, sam_ldb, mem_ctx, msg, NULL, NULL,
    1119             :                                 ldb_op_default_callback, NULL);
    1120         100 :         if (ret != LDB_SUCCESS) {
    1121           0 :                 return NT_STATUS_NO_MEMORY;
    1122             :         }
    1123             : 
    1124         100 :         ret = ldb_request_add_control(req, DSDB_CONTROL_PERMIT_INTERDOMAIN_TRUST_UAC_OID,
    1125             :                                       false, NULL);
    1126         100 :         if (ret != LDB_SUCCESS) {
    1127           0 :                 return NT_STATUS_NO_MEMORY;
    1128             :         }
    1129             : 
    1130         100 :         ret = dsdb_autotransaction_request(sam_ldb, req);
    1131         100 :         if (ret != LDB_SUCCESS) {
    1132           0 :                 DEBUG(0,("Failed to create user record %s: %s\n",
    1133             :                          ldb_dn_get_linearized(msg->dn),
    1134             :                          ldb_errstring(sam_ldb)));
    1135             : 
    1136           0 :                 switch (ret) {
    1137           0 :                 case LDB_ERR_ENTRY_ALREADY_EXISTS:
    1138           0 :                         return NT_STATUS_DOMAIN_EXISTS;
    1139           0 :                 case LDB_ERR_INSUFFICIENT_ACCESS_RIGHTS:
    1140           0 :                         return NT_STATUS_ACCESS_DENIED;
    1141           0 :                 default:
    1142           0 :                         return NT_STATUS_INTERNAL_DB_CORRUPTION;
    1143             :                 }
    1144             :         }
    1145             : 
    1146         100 :         if (user_dn) {
    1147         100 :                 *user_dn = dn;
    1148             :         }
    1149         100 :         return NT_STATUS_OK;
    1150             : }
    1151             : 
    1152         175 : static NTSTATUS dcesrv_lsa_CreateTrustedDomain_precheck(
    1153             :         TALLOC_CTX *mem_ctx,
    1154             :         struct dcesrv_handle *policy_handle,
    1155             :         struct lsa_TrustDomainInfoInfoEx *info)
    1156             : {
    1157         175 :         struct lsa_policy_state *policy_state = policy_handle->data;
    1158         175 :         const char *netbios_name = NULL;
    1159         175 :         const char *dns_name = NULL;
    1160           0 :         bool ok;
    1161             : 
    1162         175 :         netbios_name = info->netbios_name.string;
    1163         175 :         if (netbios_name == NULL) {
    1164           0 :                 return NT_STATUS_INVALID_PARAMETER;
    1165             :         }
    1166             : 
    1167         175 :         dns_name = info->domain_name.string;
    1168         175 :         if (dns_name == NULL) {
    1169           0 :                 return NT_STATUS_INVALID_PARAMETER;
    1170             :         }
    1171             : 
    1172         175 :         if (info->sid == NULL) {
    1173           0 :                 return NT_STATUS_INVALID_SID;
    1174             :         }
    1175             : 
    1176             :         /*
    1177             :          * We expect S-1-5-21-A-B-C, but we don't
    1178             :          * allow S-1-5-21-0-0-0 as this is used
    1179             :          * for claims and compound identities.
    1180             :          */
    1181         175 :         ok = dom_sid_is_valid_account_domain(info->sid);
    1182         175 :         if (!ok) {
    1183           0 :                 return NT_STATUS_INVALID_PARAMETER;
    1184             :         }
    1185             : 
    1186         175 :         if (strcasecmp(netbios_name, "BUILTIN") == 0 ||
    1187         350 :             strcasecmp(dns_name, "BUILTIN") == 0 ||
    1188         175 :             dom_sid_in_domain(policy_state->builtin_sid, info->sid))
    1189             :         {
    1190           0 :                 return NT_STATUS_INVALID_PARAMETER;
    1191             :         }
    1192             : 
    1193         175 :         if (strcasecmp(netbios_name, policy_state->domain_name) == 0 ||
    1194         175 :             strcasecmp(netbios_name, policy_state->domain_dns) == 0 ||
    1195         175 :             strcasecmp(dns_name, policy_state->domain_dns) == 0 ||
    1196         350 :             strcasecmp(dns_name, policy_state->domain_name) == 0 ||
    1197         175 :             dom_sid_equal(policy_state->domain_sid, info->sid))
    1198             :         {
    1199           0 :                 return NT_STATUS_CURRENT_DOMAIN_NOT_ALLOWED;
    1200             :         }
    1201             : 
    1202         175 :         return NT_STATUS_OK;
    1203             : }
    1204             : 
    1205         175 : static NTSTATUS dcesrv_lsa_CreateTrustedDomain_common(struct dcesrv_call_state *dce_call,
    1206             :                                                     TALLOC_CTX *mem_ctx,
    1207             :                                                     struct dcesrv_handle *policy_handle,
    1208             :                                                     uint32_t access_mask,
    1209             :                                                     struct lsa_TrustDomainInfoInfoEx *info,
    1210             :                                                     struct trustDomainPasswords *auth_struct,
    1211             :                                                     struct policy_handle **ptrustdom_handle)
    1212             : {
    1213         175 :         struct lsa_policy_state *policy_state = policy_handle->data;
    1214         175 :         struct ldb_context *sam_ldb = policy_state->sam_ldb;
    1215         175 :         struct lsa_trusted_domain_state *trusted_domain_state = NULL;
    1216           0 :         struct ldb_message **msgs, *msg;
    1217         175 :         const char *attrs[] = {
    1218             :                 NULL
    1219             :         };
    1220         175 :         const char *netbios_name = info->netbios_name.string;
    1221         175 :         const char *dns_name = info->domain_name.string;
    1222         175 :         DATA_BLOB trustAuthIncoming = data_blob_null;
    1223         175 :         DATA_BLOB trustAuthOutgoing = data_blob_null;
    1224         175 :         struct dcesrv_handle *handle = NULL;
    1225         175 :         struct server_id *server_ids = NULL;
    1226         175 :         uint32_t num_server_ids = 0;
    1227         175 :         char *dns_encoded = NULL;
    1228         175 :         char *netbios_encoded = NULL;
    1229         175 :         char *sid_encoded = NULL;
    1230           0 :         struct imessaging_context *imsg_ctx =
    1231         175 :                 dcesrv_imessaging_context(dce_call->conn);
    1232           0 :         NTSTATUS status;
    1233           0 :         bool ok;
    1234           0 :         int ret;
    1235             : 
    1236         175 :         if (auth_struct->incoming.count) {
    1237         100 :                 status = get_trustauth_inout_blob(dce_call,
    1238             :                                                   mem_ctx,
    1239             :                                                   &auth_struct->incoming,
    1240             :                                                   &trustAuthIncoming);
    1241         100 :                 if (!NT_STATUS_IS_OK(status)) {
    1242           0 :                         return status;
    1243             :                 }
    1244             :         }
    1245             : 
    1246         175 :         if (auth_struct->outgoing.count) {
    1247         100 :                 status = get_trustauth_inout_blob(dce_call,
    1248             :                                                   mem_ctx,
    1249             :                                                   &auth_struct->outgoing,
    1250             :                                                   &trustAuthOutgoing);
    1251         100 :                 if (!NT_STATUS_IS_OK(status)) {
    1252           0 :                         return status;
    1253             :                 }
    1254             :         }
    1255             : 
    1256         175 :         dns_encoded = ldb_binary_encode_string(mem_ctx, dns_name);
    1257         175 :         if (dns_encoded == NULL) {
    1258           0 :                 return NT_STATUS_NO_MEMORY;
    1259             :         }
    1260         175 :         netbios_encoded = ldb_binary_encode_string(mem_ctx, netbios_name);
    1261         175 :         if (netbios_encoded == NULL) {
    1262           0 :                 return NT_STATUS_NO_MEMORY;
    1263             :         }
    1264         175 :         sid_encoded = ldap_encode_ndr_dom_sid(mem_ctx, info->sid);
    1265         175 :         if (sid_encoded == NULL) {
    1266           0 :                 return NT_STATUS_NO_MEMORY;
    1267             :         }
    1268             : 
    1269         175 :         trusted_domain_state = talloc_zero(mem_ctx,
    1270             :                                            struct lsa_trusted_domain_state);
    1271         175 :         if (trusted_domain_state == NULL) {
    1272           0 :                 return NT_STATUS_NO_MEMORY;
    1273             :         }
    1274         175 :         trusted_domain_state->policy = policy_state;
    1275             : 
    1276         175 :         ret = ldb_transaction_start(sam_ldb);
    1277         175 :         if (ret != LDB_SUCCESS) {
    1278           0 :                 return NT_STATUS_INTERNAL_DB_CORRUPTION;
    1279             :         }
    1280             : 
    1281             :         /* search for the trusted_domain record */
    1282         175 :         ret = gendb_search(sam_ldb,
    1283             :                            mem_ctx,
    1284             :                            policy_state->system_dn,
    1285             :                            &msgs,
    1286             :                            attrs,
    1287             :                            "(&(objectClass=trustedDomain)(|"
    1288             :                            "(flatname=%s)(trustPartner=%s)"
    1289             :                            "(flatname=%s)(trustPartner=%s)"
    1290             :                            "(securityIdentifier=%s)))",
    1291             :                            dns_encoded,
    1292             :                            dns_encoded,
    1293             :                            netbios_encoded,
    1294             :                            netbios_encoded,
    1295             :                            sid_encoded);
    1296         175 :         if (ret > 0) {
    1297           0 :                 ldb_transaction_cancel(sam_ldb);
    1298           0 :                 return NT_STATUS_OBJECT_NAME_COLLISION;
    1299             :         }
    1300         175 :         if (ret < 0) {
    1301           0 :                 ldb_transaction_cancel(sam_ldb);
    1302           0 :                 return NT_STATUS_INTERNAL_DB_CORRUPTION;
    1303             :         }
    1304             : 
    1305         175 :         msg = ldb_msg_new(mem_ctx);
    1306         175 :         if (msg == NULL) {
    1307           0 :                 return NT_STATUS_NO_MEMORY;
    1308             :         }
    1309             : 
    1310         175 :         msg->dn = ldb_dn_copy(mem_ctx, policy_state->system_dn);
    1311         175 :         if (msg->dn == NULL) {
    1312           0 :                 ldb_transaction_cancel(sam_ldb);
    1313           0 :                 return NT_STATUS_NO_MEMORY;
    1314             :         }
    1315             : 
    1316         175 :         ok = ldb_dn_add_child_fmt(msg->dn, "cn=%s", dns_name);
    1317         175 :         if (!ok) {
    1318           0 :                 ldb_transaction_cancel(sam_ldb);
    1319           0 :                 return NT_STATUS_NO_MEMORY;
    1320             :         }
    1321             : 
    1322         175 :         ret = ldb_msg_add_string(msg, "objectClass", "trustedDomain");
    1323         175 :         if (ret != LDB_SUCCESS) {
    1324           0 :                 ldb_transaction_cancel(sam_ldb);
    1325           0 :                 return NT_STATUS_NO_MEMORY;;
    1326             :         }
    1327             : 
    1328         175 :         ret = ldb_msg_add_string(msg, "flatname", netbios_name);
    1329         175 :         if (ret != LDB_SUCCESS) {
    1330           0 :                 ldb_transaction_cancel(sam_ldb);
    1331           0 :                 return NT_STATUS_NO_MEMORY;
    1332             :         }
    1333             : 
    1334         175 :         ret = ldb_msg_add_string(msg, "trustPartner", dns_name);
    1335         175 :         if (ret != LDB_SUCCESS) {
    1336           0 :                 ldb_transaction_cancel(sam_ldb);
    1337           0 :                 return NT_STATUS_NO_MEMORY;;
    1338             :         }
    1339             : 
    1340         175 :         ret = samdb_msg_add_dom_sid(
    1341         175 :                 sam_ldb, mem_ctx, msg, "securityIdentifier", info->sid);
    1342         175 :         if (ret != LDB_SUCCESS) {
    1343           0 :                 ldb_transaction_cancel(sam_ldb);
    1344           0 :                 return NT_STATUS_NO_MEMORY;;
    1345             :         }
    1346             : 
    1347         175 :         ret = samdb_msg_add_int(
    1348         175 :                 sam_ldb, mem_ctx, msg, "trustType", info->trust_type);
    1349         175 :         if (ret != LDB_SUCCESS) {
    1350           0 :                 ldb_transaction_cancel(sam_ldb);
    1351           0 :                 return NT_STATUS_NO_MEMORY;;
    1352             :         }
    1353             : 
    1354         175 :         ret = samdb_msg_add_int(sam_ldb,
    1355             :                                 mem_ctx,
    1356             :                                 msg,
    1357             :                                 "trustAttributes",
    1358         175 :                                 info->trust_attributes);
    1359         175 :         if (ret != LDB_SUCCESS) {
    1360           0 :                 ldb_transaction_cancel(sam_ldb);
    1361           0 :                 return NT_STATUS_NO_MEMORY;;
    1362             :         }
    1363             : 
    1364         175 :         ret = samdb_msg_add_int(sam_ldb,
    1365             :                                 mem_ctx,
    1366             :                                 msg,
    1367             :                                 "trustDirection",
    1368         175 :                                 info->trust_direction);
    1369         175 :         if (ret != LDB_SUCCESS) {
    1370           0 :                 ldb_transaction_cancel(sam_ldb);
    1371           0 :                 return NT_STATUS_NO_MEMORY;;
    1372             :         }
    1373             : 
    1374         175 :         if (trustAuthIncoming.length > 0) {
    1375         100 :                 ret = ldb_msg_add_value(msg,
    1376             :                                         "trustAuthIncoming",
    1377             :                                         &trustAuthIncoming,
    1378             :                                         NULL);
    1379         100 :                 if (ret != LDB_SUCCESS) {
    1380           0 :                         ldb_transaction_cancel(sam_ldb);
    1381           0 :                         return NT_STATUS_NO_MEMORY;
    1382             :                 }
    1383             :         }
    1384         175 :         if (trustAuthOutgoing.length > 0) {
    1385         100 :                 ret = ldb_msg_add_value(msg,
    1386             :                                         "trustAuthOutgoing",
    1387             :                                         &trustAuthOutgoing,
    1388             :                                         NULL);
    1389         100 :                 if (ret != LDB_SUCCESS) {
    1390           0 :                         ldb_transaction_cancel(sam_ldb);
    1391           0 :                         return NT_STATUS_NO_MEMORY;
    1392             :                 }
    1393             :         }
    1394             : 
    1395         175 :         trusted_domain_state->trusted_domain_dn = ldb_dn_copy(
    1396             :                 trusted_domain_state, msg->dn);
    1397             : 
    1398             :         /* create the trusted_domain */
    1399         175 :         ret = ldb_add(sam_ldb, msg);
    1400         175 :         switch (ret) {
    1401         175 :         case  LDB_SUCCESS:
    1402         175 :                 break;
    1403           0 :         case  LDB_ERR_ENTRY_ALREADY_EXISTS:
    1404           0 :                 ldb_transaction_cancel(sam_ldb);
    1405           0 :                 DEBUG(0,("Failed to create trusted domain record %s: %s\n",
    1406             :                          ldb_dn_get_linearized(msg->dn),
    1407             :                          ldb_errstring(sam_ldb)));
    1408           0 :                 return NT_STATUS_DOMAIN_EXISTS;
    1409           0 :         case  LDB_ERR_INSUFFICIENT_ACCESS_RIGHTS:
    1410           0 :                 ldb_transaction_cancel(sam_ldb);
    1411           0 :                 DEBUG(0,("Failed to create trusted domain record %s: %s\n",
    1412             :                          ldb_dn_get_linearized(msg->dn),
    1413             :                          ldb_errstring(sam_ldb)));
    1414           0 :                 return NT_STATUS_ACCESS_DENIED;
    1415           0 :         default:
    1416           0 :                 ldb_transaction_cancel(sam_ldb);
    1417           0 :                 DEBUG(0,("Failed to create user record %s: %s\n",
    1418             :                          ldb_dn_get_linearized(msg->dn),
    1419             :                          ldb_errstring(sam_ldb)));
    1420           0 :                 return NT_STATUS_INTERNAL_DB_CORRUPTION;
    1421             :         }
    1422             : 
    1423         175 :         if (info->trust_direction & LSA_TRUST_DIRECTION_INBOUND) {
    1424           0 :                 struct ldb_dn *user_dn;
    1425             :                 /* Inbound trusts must also create a cn=users object to match */
    1426         100 :                 status = add_trust_user(mem_ctx, sam_ldb,
    1427             :                                            policy_state->domain_dn,
    1428             :                                            netbios_name,
    1429             :                                            &auth_struct->incoming,
    1430             :                                            &user_dn);
    1431         100 :                 if (!NT_STATUS_IS_OK(status)) {
    1432           0 :                         ldb_transaction_cancel(sam_ldb);
    1433           0 :                         return status;
    1434             :                 }
    1435             : 
    1436             :                 /* save the trust user dn */
    1437           0 :                 trusted_domain_state->trusted_domain_user_dn
    1438         100 :                         = talloc_steal(trusted_domain_state, user_dn);
    1439             :         }
    1440             : 
    1441         175 :         ret = ldb_transaction_commit(sam_ldb);
    1442         175 :         if (ret != LDB_SUCCESS) {
    1443           0 :                 return NT_STATUS_INTERNAL_DB_CORRUPTION;
    1444             :         }
    1445             : 
    1446             :         /*
    1447             :          * Notify winbindd that we have a new trust
    1448             :          */
    1449         175 :         status = irpc_servers_byname(imsg_ctx,
    1450             :                                      mem_ctx,
    1451             :                                      "winbind_server",
    1452             :                                      &num_server_ids,
    1453             :                                      &server_ids);
    1454         175 :         if (NT_STATUS_IS_OK(status) && num_server_ids >= 1) {
    1455         175 :                 imessaging_send(imsg_ctx,
    1456             :                                 server_ids[0],
    1457             :                                 MSG_WINBIND_RELOAD_TRUSTED_DOMAINS,
    1458             :                                 NULL);
    1459             :         }
    1460         175 :         TALLOC_FREE(server_ids);
    1461             : 
    1462         175 :         handle = dcesrv_handle_create(dce_call, LSA_HANDLE_TRUSTED_DOMAIN);
    1463         175 :         if (handle == NULL) {
    1464           0 :                 return NT_STATUS_NO_MEMORY;
    1465             :         }
    1466             : 
    1467         175 :         handle->data = talloc_steal(handle, trusted_domain_state);
    1468             : 
    1469         175 :         trusted_domain_state->access_mask = access_mask;
    1470             : 
    1471             :         /* FIXME don't use talloc_reference */
    1472         175 :         trusted_domain_state->policy = talloc_reference(trusted_domain_state,
    1473             :                                                         policy_state);
    1474         175 :         NT_STATUS_HAVE_NO_MEMORY(trusted_domain_state->policy);
    1475             : 
    1476         175 :         *ptrustdom_handle = talloc_zero(mem_ctx, struct policy_handle);
    1477         175 :         NT_STATUS_HAVE_NO_MEMORY(*ptrustdom_handle);
    1478             : 
    1479         175 :         **ptrustdom_handle = handle->wire_handle;
    1480             : 
    1481         175 :         return NT_STATUS_OK;
    1482             : }
    1483             : 
    1484             : /*
    1485             :   lsa_CreateTrustedDomainEx2
    1486             : */
    1487          44 : static NTSTATUS dcesrv_lsa_CreateTrustedDomainEx2(struct dcesrv_call_state *dce_call,
    1488             :                                            TALLOC_CTX *mem_ctx,
    1489             :                                            struct lsa_CreateTrustedDomainEx2 *r)
    1490             : {
    1491          44 :         struct dcesrv_handle *policy_handle = NULL;
    1492          44 :         struct trustDomainPasswords auth_struct = {
    1493             :                 .incoming_size = 0,
    1494             :         };
    1495          44 :         DATA_BLOB auth_blob = data_blob_null;
    1496           0 :         NTSTATUS status;
    1497             : 
    1498          44 :         ZERO_STRUCTP(r->out.trustdom_handle);
    1499          44 :         DCESRV_PULL_HANDLE(policy_handle,
    1500             :                            r->in.policy_handle,
    1501             :                            LSA_HANDLE_POLICY);
    1502             : 
    1503          44 :         status = dcesrv_lsa_CreateTrustedDomain_precheck(mem_ctx,
    1504             :                                                          policy_handle,
    1505             :                                                          r->in.info);
    1506          44 :         if (!NT_STATUS_IS_OK(status)) {
    1507           0 :                 return status;
    1508             :         }
    1509             : 
    1510          44 :         auth_blob = data_blob_const(r->in.auth_info_internal->auth_blob.data,
    1511          44 :                                     r->in.auth_info_internal->auth_blob.size);
    1512             : 
    1513          44 :         status = get_trustdom_auth_blob(dce_call,
    1514             :                                         mem_ctx,
    1515             :                                         &auth_blob,
    1516             :                                         &auth_struct);
    1517          44 :         if (!NT_STATUS_IS_OK(status)) {
    1518           0 :                 return status;
    1519             :         }
    1520             : 
    1521          44 :         return dcesrv_lsa_CreateTrustedDomain_common(dce_call,
    1522             :                                                      mem_ctx,
    1523             :                                                      policy_handle,
    1524             :                                                      r->in.access_mask,
    1525             :                                                      r->in.info,
    1526             :                                                      &auth_struct,
    1527             :                                                      &r->out.trustdom_handle);
    1528             : }
    1529             : /*
    1530             :   lsa_CreateTrustedDomainEx
    1531             : */
    1532          36 : static NTSTATUS dcesrv_lsa_CreateTrustedDomainEx(struct dcesrv_call_state *dce_call,
    1533             :                                           TALLOC_CTX *mem_ctx,
    1534             :                                           struct lsa_CreateTrustedDomainEx *r)
    1535             : {
    1536             :         /*
    1537             :          * More investigation required here, do not create secrets for now.
    1538             :          */
    1539          36 :         struct trustDomainPasswords auth_struct = {
    1540             :                 .incoming_size = 0,
    1541             :         };
    1542          36 :         struct dcesrv_handle *policy_handle = NULL;
    1543           0 :         NTSTATUS status;
    1544             : 
    1545          36 :         ZERO_STRUCTP(r->out.trustdom_handle);
    1546          36 :         DCESRV_PULL_HANDLE(policy_handle,
    1547             :                            r->in.policy_handle,
    1548             :                            LSA_HANDLE_POLICY);
    1549             : 
    1550          36 :         status = dcesrv_lsa_CreateTrustedDomain_precheck(mem_ctx,
    1551             :                                                          policy_handle,
    1552             :                                                          r->in.info);
    1553          36 :         if (!NT_STATUS_IS_OK(status)) {
    1554           0 :                 return status;
    1555             :         }
    1556             : 
    1557          36 :         if (r->in.auth_info->incoming_count > 1) {
    1558           0 :                 return NT_STATUS_INVALID_PARAMETER;
    1559             :         }
    1560             : 
    1561          36 :         return dcesrv_lsa_CreateTrustedDomain_common(
    1562             :                 dce_call,
    1563             :                 mem_ctx,
    1564             :                 policy_handle,
    1565             :                 r->in.access_mask,
    1566             :                 r->in.info,
    1567             :                 &auth_struct,
    1568             :                 &r->out.trustdom_handle);
    1569             : }
    1570             : 
    1571             : /*
    1572             :   lsa_CreateTrustedDomain
    1573             : */
    1574          36 : static NTSTATUS dcesrv_lsa_CreateTrustedDomain(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
    1575             :                                         struct lsa_CreateTrustedDomain *r)
    1576             : {
    1577          36 :         struct trustDomainPasswords auth_struct = {
    1578             :                 .incoming_size = 0,
    1579             :         };
    1580          36 :         struct dcesrv_handle *policy_handle = NULL;
    1581          36 :         struct lsa_TrustDomainInfoInfoEx info = {
    1582          36 :                 .domain_name = r->in.info->name,
    1583          36 :                 .netbios_name = r->in.info->name,
    1584          36 :                 .sid = r->in.info->sid,
    1585             :                 .trust_direction = LSA_TRUST_DIRECTION_OUTBOUND,
    1586             :                 .trust_type = LSA_TRUST_TYPE_DOWNLEVEL,
    1587             :                 .trust_attributes = 0,
    1588             :         };
    1589           0 :         NTSTATUS status;
    1590             : 
    1591          36 :         ZERO_STRUCTP(r->out.trustdom_handle);
    1592          36 :         DCESRV_PULL_HANDLE(policy_handle,
    1593             :                            r->in.policy_handle,
    1594             :                            LSA_HANDLE_POLICY);
    1595             : 
    1596          36 :         status = dcesrv_lsa_CreateTrustedDomain_precheck(mem_ctx,
    1597             :                                                          policy_handle,
    1598             :                                                          &info);
    1599          36 :         if (!NT_STATUS_IS_OK(status)) {
    1600           0 :                 return status;
    1601             :         }
    1602             : 
    1603          36 :         return dcesrv_lsa_CreateTrustedDomain_common(
    1604             :                 dce_call,
    1605             :                 mem_ctx,
    1606             :                 policy_handle,
    1607             :                 r->in.access_mask,
    1608             :                 &info,
    1609             :                 &auth_struct,
    1610             :                 &r->out.trustdom_handle);
    1611             : }
    1612             : 
    1613        4470 : static NTSTATUS dcesrv_lsa_OpenTrustedDomain_common(
    1614             :                                         struct dcesrv_call_state *dce_call,
    1615             :                                         TALLOC_CTX *tmp_mem,
    1616             :                                         struct lsa_policy_state *policy_state,
    1617             :                                         const char *filter,
    1618             :                                         uint32_t access_mask,
    1619             :                                         struct dcesrv_handle **_handle)
    1620             : {
    1621           0 :         struct lsa_trusted_domain_state *trusted_domain_state;
    1622           0 :         struct dcesrv_handle *handle;
    1623           0 :         struct ldb_message **msgs;
    1624        4470 :         const char *attrs[] = {
    1625             :                 "trustDirection",
    1626             :                 "flatname",
    1627             :                 NULL
    1628             :         };
    1629           0 :         uint32_t direction;
    1630           0 :         int ret;
    1631             : 
    1632             :         /* TODO: perform access checks */
    1633             : 
    1634             :         /* search for the trusted_domain record */
    1635        4470 :         ret = gendb_search(policy_state->sam_ldb, tmp_mem,
    1636             :                            policy_state->system_dn,
    1637             :                            &msgs, attrs, "%s", filter);
    1638        4470 :         if (ret == 0) {
    1639          54 :                 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
    1640             :         }
    1641             : 
    1642        4416 :         if (ret != 1) {
    1643           0 :                 DEBUG(0,("Found %d records matching %s under %s\n", ret,
    1644             :                          filter,
    1645             :                          ldb_dn_get_linearized(policy_state->system_dn)));
    1646           0 :                 return NT_STATUS_INTERNAL_DB_CORRUPTION;
    1647             :         }
    1648             : 
    1649        4416 :         trusted_domain_state = talloc_zero(tmp_mem,
    1650             :                                            struct lsa_trusted_domain_state);
    1651        4416 :         if (!trusted_domain_state) {
    1652           0 :                 return NT_STATUS_NO_MEMORY;
    1653             :         }
    1654        4416 :         trusted_domain_state->policy = policy_state;
    1655             : 
    1656        4416 :         trusted_domain_state->trusted_domain_dn =
    1657        4416 :                 talloc_steal(trusted_domain_state, msgs[0]->dn);
    1658             : 
    1659        4416 :         direction = ldb_msg_find_attr_as_int(msgs[0], "trustDirection", 0);
    1660        4416 :         if (direction & LSA_TRUST_DIRECTION_INBOUND) {
    1661        2309 :                 const char *flatname = ldb_msg_find_attr_as_string(msgs[0],
    1662             :                                                         "flatname", NULL);
    1663             : 
    1664             :                 /* search for the trusted_domain account */
    1665        2309 :                 ret = gendb_search(policy_state->sam_ldb, tmp_mem,
    1666             :                                    policy_state->domain_dn,
    1667             :                                    &msgs, attrs,
    1668             :                                    "(&(samaccountname=%s$)(objectclass=user)"
    1669             :                                    "(userAccountControl:%s:=%u))",
    1670             :                                    flatname,
    1671             :                                    LDB_OID_COMPARATOR_AND,
    1672             :                                    UF_INTERDOMAIN_TRUST_ACCOUNT);
    1673        2309 :                 if (ret == 1) {
    1674        2309 :                         trusted_domain_state->trusted_domain_user_dn =
    1675        2309 :                                 talloc_steal(trusted_domain_state, msgs[0]->dn);
    1676             :                 }
    1677             :         }
    1678             : 
    1679        4416 :         handle = dcesrv_handle_create(dce_call, LSA_HANDLE_TRUSTED_DOMAIN);
    1680        4416 :         if (!handle) {
    1681           0 :                 return NT_STATUS_NO_MEMORY;
    1682             :         }
    1683             : 
    1684        4416 :         handle->data = talloc_steal(handle, trusted_domain_state);
    1685             : 
    1686        4416 :         trusted_domain_state->access_mask = access_mask;
    1687        4416 :         trusted_domain_state->policy = talloc_reference(trusted_domain_state,
    1688             :                                                         policy_state);
    1689             : 
    1690        4416 :         *_handle = handle;
    1691             : 
    1692        4416 :         return NT_STATUS_OK;
    1693             : }
    1694             : 
    1695             : /*
    1696             :   lsa_OpenTrustedDomain
    1697             : */
    1698        2166 : static NTSTATUS dcesrv_lsa_OpenTrustedDomain(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
    1699             :                                       struct lsa_OpenTrustedDomain *r)
    1700             : {
    1701           0 :         struct dcesrv_handle *policy_handle;
    1702           0 :         struct lsa_policy_state *policy_state;
    1703           0 :         struct dcesrv_handle *handle;
    1704           0 :         const char *sid_string;
    1705           0 :         char *filter;
    1706           0 :         NTSTATUS status;
    1707             : 
    1708        2166 :         DCESRV_PULL_HANDLE(policy_handle, r->in.handle, LSA_HANDLE_POLICY);
    1709        2166 :         ZERO_STRUCTP(r->out.trustdom_handle);
    1710        2166 :         policy_state = policy_handle->data;
    1711             : 
    1712        2166 :         sid_string = dom_sid_string(mem_ctx, r->in.sid);
    1713        2166 :         if (!sid_string) {
    1714           0 :                 return NT_STATUS_NO_MEMORY;
    1715             :         }
    1716             : 
    1717        2166 :         filter = talloc_asprintf(mem_ctx,
    1718             :                                  "(&(securityIdentifier=%s)"
    1719             :                                  "(objectclass=trustedDomain))",
    1720             :                                  sid_string);
    1721        2166 :         if (filter == NULL) {
    1722           0 :                 return NT_STATUS_NO_MEMORY;
    1723             :         }
    1724             : 
    1725        2166 :         status = dcesrv_lsa_OpenTrustedDomain_common(dce_call, mem_ctx,
    1726             :                                                      policy_state,
    1727             :                                                      filter,
    1728             :                                                      r->in.access_mask,
    1729             :                                                      &handle);
    1730        2166 :         if (!NT_STATUS_IS_OK(status)) {
    1731           1 :                 return status;
    1732             :         }
    1733             : 
    1734        2165 :         *r->out.trustdom_handle = handle->wire_handle;
    1735             : 
    1736        2165 :         return NT_STATUS_OK;
    1737             : }
    1738             : 
    1739             : 
    1740             : /*
    1741             :   lsa_OpenTrustedDomainByName
    1742             : */
    1743        2304 : static NTSTATUS dcesrv_lsa_OpenTrustedDomainByName(struct dcesrv_call_state *dce_call,
    1744             :                                             TALLOC_CTX *mem_ctx,
    1745             :                                             struct lsa_OpenTrustedDomainByName *r)
    1746             : {
    1747           0 :         struct dcesrv_handle *policy_handle;
    1748           0 :         struct lsa_policy_state *policy_state;
    1749           0 :         struct dcesrv_handle *handle;
    1750           0 :         char *td_name;
    1751           0 :         char *filter;
    1752           0 :         NTSTATUS status;
    1753             : 
    1754        2304 :         DCESRV_PULL_HANDLE(policy_handle, r->in.handle, LSA_HANDLE_POLICY);
    1755        2304 :         ZERO_STRUCTP(r->out.trustdom_handle);
    1756        2304 :         policy_state = policy_handle->data;
    1757             : 
    1758        2304 :         if (!r->in.name.string) {
    1759           0 :                 return NT_STATUS_INVALID_PARAMETER;
    1760             :         }
    1761             : 
    1762             :         /* search for the trusted_domain record */
    1763        2304 :         td_name = ldb_binary_encode_string(mem_ctx, r->in.name.string);
    1764        2304 :         if (td_name == NULL) {
    1765           0 :                 return NT_STATUS_NO_MEMORY;
    1766             :         }
    1767             : 
    1768        2304 :         filter = talloc_asprintf(mem_ctx,
    1769             :                            "(&(|(flatname=%s)(cn=%s)(trustPartner=%s))"
    1770             :                              "(objectclass=trustedDomain))",
    1771             :                            td_name, td_name, td_name);
    1772        2304 :         if (filter == NULL) {
    1773           0 :                 return NT_STATUS_NO_MEMORY;
    1774             :         }
    1775             : 
    1776        2304 :         status = dcesrv_lsa_OpenTrustedDomain_common(dce_call, mem_ctx,
    1777             :                                                      policy_state,
    1778             :                                                      filter,
    1779             :                                                      r->in.access_mask,
    1780             :                                                      &handle);
    1781        2304 :         if (!NT_STATUS_IS_OK(status)) {
    1782          53 :                 return status;
    1783             :         }
    1784             : 
    1785        2251 :         *r->out.trustdom_handle = handle->wire_handle;
    1786             : 
    1787        2251 :         return NT_STATUS_OK;
    1788             : }
    1789             : 
    1790             : 
    1791             : 
    1792             : /*
    1793             :   lsa_SetTrustedDomainInfo
    1794             : */
    1795           0 : static NTSTATUS dcesrv_lsa_SetTrustedDomainInfo(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
    1796             :                                          struct lsa_SetTrustedDomainInfo *r)
    1797             : {
    1798           0 :         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
    1799             : }
    1800             : 
    1801             : 
    1802             : 
    1803             : /* parameters 4 to 6 are optional if the dn is a dn of a TDO object,
    1804             :  * otherwise at least one must be provided */
    1805          46 : static NTSTATUS get_tdo(struct ldb_context *sam, TALLOC_CTX *mem_ctx,
    1806             :                         struct ldb_dn *basedn, const char *dns_domain,
    1807             :                         const char *netbios, struct dom_sid2 *sid,
    1808             :                         struct ldb_message ***msgs)
    1809             : {
    1810          46 :         const char *attrs[] = { "flatname", "trustPartner",
    1811             :                                 "securityIdentifier", "trustDirection",
    1812             :                                 "trustType", "trustAttributes",
    1813             :                                 "trustPosixOffset",
    1814             :                                 "msDs-supportedEncryptionTypes",
    1815             :                                 "msDS-TrustForestTrustInfo",
    1816             :                                 NULL
    1817             :         };
    1818          46 :         char *dns = NULL;
    1819          46 :         char *nbn = NULL;
    1820           0 :         char *filter;
    1821           0 :         int ret;
    1822             : 
    1823             : 
    1824          46 :         if (dns_domain || netbios || sid) {
    1825          24 :                 filter = talloc_strdup(mem_ctx,
    1826             :                                    "(&(objectclass=trustedDomain)(|");
    1827             :         } else {
    1828          22 :                 filter = talloc_strdup(mem_ctx,
    1829             :                                        "(objectclass=trustedDomain)");
    1830             :         }
    1831             : 
    1832          46 :         if (dns_domain) {
    1833          24 :                 dns = ldb_binary_encode_string(mem_ctx, dns_domain);
    1834          24 :                 if (!dns) {
    1835           0 :                         return NT_STATUS_NO_MEMORY;
    1836             :                 }
    1837          24 :                 talloc_asprintf_addbuf(&filter, "(trustPartner=%s)", dns);
    1838             :         }
    1839          46 :         if (netbios) {
    1840          24 :                 nbn = ldb_binary_encode_string(mem_ctx, netbios);
    1841          24 :                 if (!nbn) {
    1842           0 :                         return NT_STATUS_NO_MEMORY;
    1843             :                 }
    1844          24 :                 talloc_asprintf_addbuf(&filter, "(flatname=%s)", nbn);
    1845             :         }
    1846          46 :         if (sid) {
    1847           0 :                 struct dom_sid_buf buf;
    1848           6 :                 char *sidstr = dom_sid_str_buf(sid, &buf);
    1849           6 :                 talloc_asprintf_addbuf(
    1850             :                         &filter, "(securityIdentifier=%s)", sidstr);
    1851             :         }
    1852          46 :         if (dns_domain || netbios || sid) {
    1853          24 :                 talloc_asprintf_addbuf(&filter, "))");
    1854             :         }
    1855          46 :         if (filter == NULL) {
    1856           0 :                 return NT_STATUS_NO_MEMORY;
    1857             :         }
    1858             : 
    1859          46 :         ret = gendb_search(sam, mem_ctx, basedn, msgs, attrs, "%s", filter);
    1860          46 :         if (ret == 0) {
    1861           0 :                 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
    1862             :         }
    1863             : 
    1864          46 :         if (ret != 1) {
    1865           0 :                 return NT_STATUS_OBJECT_NAME_COLLISION;
    1866             :         }
    1867             : 
    1868          46 :         return NT_STATUS_OK;
    1869             : }
    1870             : 
    1871          43 : static NTSTATUS update_uint32_t_value(TALLOC_CTX *mem_ctx,
    1872             :                                       struct ldb_context *sam_ldb,
    1873             :                                       struct ldb_message *orig,
    1874             :                                       struct ldb_message *dest,
    1875             :                                       const char *attribute,
    1876             :                                       uint32_t value,
    1877             :                                       uint32_t *orig_value)
    1878             : {
    1879           0 :         const struct ldb_val *orig_val;
    1880          43 :         uint32_t orig_uint = 0;
    1881          43 :         unsigned int flags = 0;
    1882           0 :         int ret;
    1883          43 :         int error = 0;
    1884             : 
    1885          43 :         orig_val = ldb_msg_find_ldb_val(orig, attribute);
    1886          43 :         if (!orig_val || !orig_val->data) {
    1887             :                 /* add new attribute */
    1888          28 :                 flags = LDB_FLAG_MOD_ADD;
    1889             : 
    1890             :         } else {
    1891          15 :                 orig_uint = smb_strtoul((const char *)orig_val->data,
    1892             :                                         NULL,
    1893             :                                         0,
    1894             :                                         &error,
    1895             :                                         SMB_STR_STANDARD);
    1896          15 :                 if (error != 0 || orig_uint != value) {
    1897             :                         /* replace also if can't get value */
    1898           0 :                         flags = LDB_FLAG_MOD_REPLACE;
    1899             :                 }
    1900             :         }
    1901             : 
    1902          43 :         if (flags == 0) {
    1903             :                 /* stored value is identical, nothing to change */
    1904          15 :                 goto done;
    1905             :         }
    1906             : 
    1907          28 :         ret = samdb_msg_append_uint(sam_ldb, dest, dest, attribute, value, flags);
    1908          28 :         if (ret != LDB_SUCCESS) {
    1909           0 :                 return NT_STATUS_NO_MEMORY;
    1910             :         }
    1911             : 
    1912          28 : done:
    1913          43 :         if (orig_value) {
    1914          12 :                 *orig_value = orig_uint;
    1915             :         }
    1916          43 :         return NT_STATUS_OK;
    1917             : }
    1918             : 
    1919           0 : static NTSTATUS update_trust_user(TALLOC_CTX *mem_ctx,
    1920             :                                   struct ldb_context *sam_ldb,
    1921             :                                   struct ldb_dn *base_dn,
    1922             :                                   bool delete_user,
    1923             :                                   const char *netbios_name,
    1924             :                                   struct trustAuthInOutBlob *in)
    1925             : {
    1926           0 :         const char *attrs[] = { "userAccountControl", NULL };
    1927           0 :         struct ldb_message **msgs;
    1928           0 :         struct ldb_message *msg;
    1929           0 :         uint32_t uac;
    1930           0 :         uint32_t i;
    1931           0 :         int ret;
    1932             : 
    1933           0 :         ret = gendb_search(sam_ldb, mem_ctx,
    1934             :                            base_dn, &msgs, attrs,
    1935             :                            "samAccountName=%s$", netbios_name);
    1936           0 :         if (ret > 1) {
    1937           0 :                 return NT_STATUS_INTERNAL_DB_CORRUPTION;
    1938             :         }
    1939             : 
    1940           0 :         if (ret == 0) {
    1941           0 :                 if (delete_user) {
    1942           0 :                         return NT_STATUS_OK;
    1943             :                 }
    1944             : 
    1945             :                 /* ok no existing user, add it from scratch */
    1946           0 :                 return add_trust_user(mem_ctx, sam_ldb, base_dn,
    1947             :                                       netbios_name, in, NULL);
    1948             :         }
    1949             : 
    1950             :         /* check user is what we are looking for */
    1951           0 :         uac = ldb_msg_find_attr_as_uint(msgs[0],
    1952             :                                         "userAccountControl", 0);
    1953           0 :         if (!(uac & UF_INTERDOMAIN_TRUST_ACCOUNT)) {
    1954           0 :                 return NT_STATUS_OBJECT_NAME_COLLISION;
    1955             :         }
    1956             : 
    1957           0 :         if (delete_user) {
    1958           0 :                 ret = ldb_delete(sam_ldb, msgs[0]->dn);
    1959           0 :                 switch (ret) {
    1960           0 :                 case LDB_SUCCESS:
    1961           0 :                         return NT_STATUS_OK;
    1962           0 :                 case LDB_ERR_INSUFFICIENT_ACCESS_RIGHTS:
    1963           0 :                         return NT_STATUS_ACCESS_DENIED;
    1964           0 :                 default:
    1965           0 :                         return NT_STATUS_INTERNAL_DB_CORRUPTION;
    1966             :                 }
    1967             :         }
    1968             : 
    1969             :         /* entry exists, just modify secret if any */
    1970           0 :         if (in == NULL || in->count == 0) {
    1971           0 :                 return NT_STATUS_OK;
    1972             :         }
    1973             : 
    1974           0 :         msg = ldb_msg_new(mem_ctx);
    1975           0 :         if (!msg) {
    1976           0 :                 return NT_STATUS_NO_MEMORY;
    1977             :         }
    1978           0 :         msg->dn = msgs[0]->dn;
    1979             : 
    1980           0 :         for (i = 0; i < in->count; i++) {
    1981           0 :                 const char *attribute;
    1982           0 :                 struct ldb_val v;
    1983           0 :                 switch (in->current.array[i].AuthType) {
    1984           0 :                 case TRUST_AUTH_TYPE_NT4OWF:
    1985           0 :                         attribute = "unicodePwd";
    1986           0 :                         v.data = (uint8_t *)&in->current.array[i].AuthInfo.nt4owf.password;
    1987           0 :                         v.length = 16;
    1988           0 :                         break;
    1989           0 :                 case TRUST_AUTH_TYPE_CLEAR:
    1990           0 :                         attribute = "clearTextPassword";
    1991           0 :                         v.data = in->current.array[i].AuthInfo.clear.password;
    1992           0 :                         v.length = in->current.array[i].AuthInfo.clear.size;
    1993           0 :                         break;
    1994           0 :                 default:
    1995           0 :                         continue;
    1996             :                 }
    1997             : 
    1998           0 :                 ret = ldb_msg_append_value(msg, attribute, &v, LDB_FLAG_MOD_REPLACE);
    1999           0 :                 if (ret != LDB_SUCCESS) {
    2000           0 :                         return NT_STATUS_NO_MEMORY;
    2001             :                 }
    2002             :         }
    2003             : 
    2004             :         /* create the trusted_domain user account */
    2005           0 :         ret = ldb_modify(sam_ldb, msg);
    2006           0 :         if (ret != LDB_SUCCESS) {
    2007           0 :                 DEBUG(0,("Failed to create user record %s: %s\n",
    2008             :                          ldb_dn_get_linearized(msg->dn),
    2009             :                          ldb_errstring(sam_ldb)));
    2010             : 
    2011           0 :                 switch (ret) {
    2012           0 :                 case LDB_ERR_ENTRY_ALREADY_EXISTS:
    2013           0 :                         return NT_STATUS_DOMAIN_EXISTS;
    2014           0 :                 case LDB_ERR_INSUFFICIENT_ACCESS_RIGHTS:
    2015           0 :                         return NT_STATUS_ACCESS_DENIED;
    2016           0 :                 default:
    2017           0 :                         return NT_STATUS_INTERNAL_DB_CORRUPTION;
    2018             :                 }
    2019             :         }
    2020             : 
    2021           0 :         return NT_STATUS_OK;
    2022             : }
    2023             : 
    2024             : 
    2025          40 : static NTSTATUS setInfoTrustedDomain_base(struct dcesrv_call_state *dce_call,
    2026             :                                           struct lsa_policy_state *p_state,
    2027             :                                           TALLOC_CTX *mem_ctx,
    2028             :                                           struct ldb_message *dom_msg,
    2029             :                                           enum lsa_TrustDomInfoEnum level,
    2030             :                                           union lsa_TrustedDomainInfo *info)
    2031             : {
    2032          40 :         uint32_t *posix_offset = NULL;
    2033          40 :         struct lsa_TrustDomainInfoInfoEx *info_ex = NULL;
    2034          40 :         struct lsa_TrustDomainInfoAuthInfo *auth_info = NULL;
    2035          40 :         struct lsa_TrustDomainInfoAuthInfoInternal *auth_info_int = NULL;
    2036          40 :         uint32_t *enc_types = NULL;
    2037           0 :         DATA_BLOB trustAuthIncoming, trustAuthOutgoing, auth_blob;
    2038           0 :         struct trustDomainPasswords auth_struct;
    2039          40 :         struct trustAuthInOutBlob *current_passwords = NULL;
    2040           0 :         NTSTATUS nt_status;
    2041           0 :         struct ldb_message **msgs;
    2042           0 :         struct ldb_message *msg;
    2043          40 :         bool add_outgoing = false;
    2044          40 :         bool add_incoming = false;
    2045          40 :         bool del_outgoing = false;
    2046          40 :         bool del_incoming = false;
    2047          40 :         bool del_forest_info = false;
    2048          40 :         bool in_transaction = false;
    2049           0 :         int ret;
    2050           0 :         bool am_rodc;
    2051             : 
    2052          40 :         switch (level) {
    2053           3 :         case LSA_TRUSTED_DOMAIN_INFO_POSIX_OFFSET:
    2054           3 :                 posix_offset = &info->posix_offset.posix_offset;
    2055           3 :                 break;
    2056           3 :         case LSA_TRUSTED_DOMAIN_INFO_INFO_EX:
    2057           3 :                 info_ex = &info->info_ex;
    2058           3 :                 break;
    2059           0 :         case LSA_TRUSTED_DOMAIN_INFO_AUTH_INFO:
    2060           0 :                 auth_info = &info->auth_info;
    2061           0 :                 break;
    2062           3 :         case LSA_TRUSTED_DOMAIN_INFO_FULL_INFO:
    2063           3 :                 posix_offset = &info->full_info.posix_offset.posix_offset;
    2064           3 :                 info_ex = &info->full_info.info_ex;
    2065           3 :                 auth_info = &info->full_info.auth_info;
    2066           3 :                 break;
    2067           0 :         case LSA_TRUSTED_DOMAIN_INFO_AUTH_INFO_INTERNAL:
    2068           0 :                 auth_info_int = &info->auth_info_internal;
    2069           0 :                 break;
    2070           0 :         case LSA_TRUSTED_DOMAIN_INFO_FULL_INFO_INTERNAL:
    2071           0 :                 posix_offset = &info->full_info_internal.posix_offset.posix_offset;
    2072           0 :                 info_ex = &info->full_info_internal.info_ex;
    2073           0 :                 auth_info_int = &info->full_info_internal.auth_info;
    2074           0 :                 break;
    2075          25 :         case LSA_TRUSTED_DOMAIN_SUPPORTED_ENCRYPTION_TYPES:
    2076          25 :                 enc_types = &info->enc_types.enc_types;
    2077          25 :                 break;
    2078           6 :         default:
    2079           6 :                 return NT_STATUS_INVALID_PARAMETER;
    2080             :         }
    2081             : 
    2082          34 :         if (auth_info) {
    2083           3 :                 nt_status = auth_info_2_auth_blob(mem_ctx, auth_info,
    2084             :                                                   &trustAuthIncoming,
    2085             :                                                   &trustAuthOutgoing);
    2086           3 :                 if (!NT_STATUS_IS_OK(nt_status)) {
    2087           0 :                         return nt_status;
    2088             :                 }
    2089           3 :                 if (trustAuthIncoming.data) {
    2090             :                         /* This does the decode of some of this twice, but it is easier that way */
    2091           0 :                         nt_status = auth_info_2_trustauth_inout(mem_ctx,
    2092             :                                                                 auth_info->incoming_count,
    2093             :                                                                 auth_info->incoming_current_auth_info,
    2094             :                                                                 NULL,
    2095             :                                                                 &current_passwords);
    2096           0 :                         if (!NT_STATUS_IS_OK(nt_status)) {
    2097           0 :                                 return nt_status;
    2098             :                         }
    2099             :                 }
    2100             :         }
    2101             : 
    2102             :         /* decode auth_info_int if set */
    2103          34 :         if (auth_info_int) {
    2104             : 
    2105             :                 /* now decrypt blob */
    2106           0 :                 auth_blob = data_blob_const(auth_info_int->auth_blob.data,
    2107           0 :                                             auth_info_int->auth_blob.size);
    2108             : 
    2109           0 :                 nt_status = get_trustdom_auth_blob(dce_call, mem_ctx,
    2110             :                                                    &auth_blob, &auth_struct);
    2111           0 :                 if (!NT_STATUS_IS_OK(nt_status)) {
    2112           0 :                         return nt_status;
    2113             :                 }
    2114             :         }
    2115             : 
    2116          34 :         if (info_ex) {
    2117             :                 /* verify data matches */
    2118           6 :                 if (info_ex->trust_attributes &
    2119             :                     LSA_TRUST_ATTRIBUTE_FOREST_TRANSITIVE) {
    2120             :                         /* TODO: check what behavior level we have */
    2121           6 :                        if (strcasecmp_m(p_state->domain_dns,
    2122             :                                         p_state->forest_dns) != 0) {
    2123           0 :                                 return NT_STATUS_INVALID_DOMAIN_STATE;
    2124             :                         }
    2125             :                 }
    2126             : 
    2127           6 :                 ret = samdb_rodc(p_state->sam_ldb, &am_rodc);
    2128           6 :                 if (ret == LDB_SUCCESS && am_rodc) {
    2129           0 :                         return NT_STATUS_NO_SUCH_DOMAIN;
    2130             :                 }
    2131             : 
    2132             :                 /* verify only one object matches the dns/netbios/sid
    2133             :                  * triplet and that this is the one we already have */
    2134           6 :                 nt_status = get_tdo(p_state->sam_ldb, mem_ctx,
    2135             :                                     p_state->system_dn,
    2136             :                                     info_ex->domain_name.string,
    2137             :                                     info_ex->netbios_name.string,
    2138             :                                     info_ex->sid, &msgs);
    2139           6 :                 if (!NT_STATUS_IS_OK(nt_status)) {
    2140           0 :                         return nt_status;
    2141             :                 }
    2142           6 :                 if (ldb_dn_compare(dom_msg->dn, msgs[0]->dn) != 0) {
    2143           0 :                         return NT_STATUS_OBJECT_NAME_COLLISION;
    2144             :                 }
    2145           6 :                 talloc_free(msgs);
    2146             :         }
    2147             : 
    2148             :         /* TODO: should we fetch previous values from the existing entry
    2149             :          * and append them ? */
    2150          34 :         if (auth_info_int && auth_struct.incoming.count) {
    2151           0 :                 nt_status = get_trustauth_inout_blob(dce_call, mem_ctx,
    2152             :                                                      &auth_struct.incoming,
    2153             :                                                      &trustAuthIncoming);
    2154           0 :                 if (!NT_STATUS_IS_OK(nt_status)) {
    2155           0 :                         return nt_status;
    2156             :                 }
    2157             : 
    2158           0 :                 current_passwords = &auth_struct.incoming;
    2159             : 
    2160             :         } else {
    2161          34 :                 trustAuthIncoming = data_blob(NULL, 0);
    2162             :         }
    2163             : 
    2164          34 :         if (auth_info_int && auth_struct.outgoing.count) {
    2165           0 :                 nt_status = get_trustauth_inout_blob(dce_call, mem_ctx,
    2166             :                                                      &auth_struct.outgoing,
    2167             :                                                      &trustAuthOutgoing);
    2168           0 :                 if (!NT_STATUS_IS_OK(nt_status)) {
    2169           0 :                         return nt_status;
    2170             :                 }
    2171             :         } else {
    2172          34 :                 trustAuthOutgoing = data_blob(NULL, 0);
    2173             :         }
    2174             : 
    2175          34 :         msg = ldb_msg_new(mem_ctx);
    2176          34 :         if (msg == NULL) {
    2177           0 :                 return NT_STATUS_NO_MEMORY;
    2178             :         }
    2179          34 :         msg->dn = dom_msg->dn;
    2180             : 
    2181          34 :         if (posix_offset) {
    2182           6 :                 nt_status = update_uint32_t_value(mem_ctx, p_state->sam_ldb,
    2183             :                                                   dom_msg, msg,
    2184             :                                                   "trustPosixOffset",
    2185             :                                                   *posix_offset, NULL);
    2186           6 :                 if (!NT_STATUS_IS_OK(nt_status)) {
    2187           0 :                         return nt_status;
    2188             :                 }
    2189             :         }
    2190             : 
    2191          34 :         if (info_ex) {
    2192           0 :                 uint32_t origattrs;
    2193           0 :                 uint32_t changed_attrs;
    2194           0 :                 uint32_t origdir;
    2195           0 :                 int origtype;
    2196             : 
    2197           6 :                 nt_status = update_uint32_t_value(mem_ctx, p_state->sam_ldb,
    2198             :                                                   dom_msg, msg,
    2199             :                                                   "trustDirection",
    2200             :                                                   info_ex->trust_direction,
    2201             :                                                   &origdir);
    2202           6 :                 if (!NT_STATUS_IS_OK(nt_status)) {
    2203           0 :                         return nt_status;
    2204             :                 }
    2205             : 
    2206           6 :                 if (info_ex->trust_direction & LSA_TRUST_DIRECTION_INBOUND) {
    2207           6 :                         if (auth_info != NULL && trustAuthIncoming.length > 0) {
    2208           0 :                                 add_incoming = true;
    2209             :                         }
    2210             :                 }
    2211           6 :                 if (info_ex->trust_direction & LSA_TRUST_DIRECTION_OUTBOUND) {
    2212           6 :                         if (auth_info != NULL && trustAuthOutgoing.length > 0) {
    2213           0 :                                 add_outgoing = true;
    2214             :                         }
    2215             :                 }
    2216             : 
    2217           6 :                 if ((origdir & LSA_TRUST_DIRECTION_INBOUND) &&
    2218           6 :                     !(info_ex->trust_direction & LSA_TRUST_DIRECTION_INBOUND)) {
    2219           0 :                         del_incoming = true;
    2220             :                 }
    2221           6 :                 if ((origdir & LSA_TRUST_DIRECTION_OUTBOUND) &&
    2222           6 :                     !(info_ex->trust_direction & LSA_TRUST_DIRECTION_OUTBOUND)) {
    2223           0 :                         del_outgoing = true;
    2224             :                 }
    2225             : 
    2226           6 :                 origtype = ldb_msg_find_attr_as_int(dom_msg, "trustType", -1);
    2227           6 :                 if (origtype == -1 || origtype != info_ex->trust_type) {
    2228           0 :                         DEBUG(1, ("Attempted to change trust type! "
    2229             :                                   "Operation not handled\n"));
    2230           0 :                         return NT_STATUS_INVALID_PARAMETER;
    2231             :                 }
    2232             : 
    2233           6 :                 nt_status = update_uint32_t_value(mem_ctx, p_state->sam_ldb,
    2234             :                                                   dom_msg, msg,
    2235             :                                                   "trustAttributes",
    2236             :                                                   info_ex->trust_attributes,
    2237             :                                                   &origattrs);
    2238           6 :                 if (!NT_STATUS_IS_OK(nt_status)) {
    2239           0 :                         return nt_status;
    2240             :                 }
    2241             :                 /* TODO: check forestFunctionality from ldb opaque */
    2242             :                 /* TODO: check what is set makes sense */
    2243             : 
    2244           6 :                 changed_attrs = origattrs ^ info_ex->trust_attributes;
    2245           6 :                 if (changed_attrs & ~LSA_TRUST_ATTRIBUTE_FOREST_TRANSITIVE) {
    2246             :                         /*
    2247             :                          * For now we only allow
    2248             :                          * LSA_TRUST_ATTRIBUTE_FOREST_TRANSITIVE to be changed.
    2249             :                          *
    2250             :                          * TODO: we may need to support more attribute changes
    2251             :                          */
    2252           0 :                         DEBUG(1, ("Attempted to change trust attributes "
    2253             :                                   "(0x%08x != 0x%08x)! "
    2254             :                                   "Operation not handled yet...\n",
    2255             :                                   (unsigned)origattrs,
    2256             :                                   (unsigned)info_ex->trust_attributes));
    2257           0 :                         return NT_STATUS_INVALID_PARAMETER;
    2258             :                 }
    2259             : 
    2260           6 :                 if (!(info_ex->trust_attributes &
    2261             :                       LSA_TRUST_ATTRIBUTE_FOREST_TRANSITIVE))
    2262             :                 {
    2263           0 :                         struct ldb_message_element *orig_forest_el = NULL;
    2264             : 
    2265           0 :                         orig_forest_el = ldb_msg_find_element(dom_msg,
    2266             :                                                 "msDS-TrustForestTrustInfo");
    2267           0 :                         if (orig_forest_el != NULL) {
    2268           0 :                                 del_forest_info = true;
    2269             :                         }
    2270             :                 }
    2271             :         }
    2272             : 
    2273          34 :         if (enc_types) {
    2274          25 :                 nt_status = update_uint32_t_value(mem_ctx, p_state->sam_ldb,
    2275             :                                                   dom_msg, msg,
    2276             :                                                   "msDS-SupportedEncryptionTypes",
    2277             :                                                   *enc_types, NULL);
    2278          25 :                 if (!NT_STATUS_IS_OK(nt_status)) {
    2279           0 :                         return nt_status;
    2280             :                 }
    2281             :         }
    2282             : 
    2283          34 :         if (add_incoming || del_incoming) {
    2284           0 :                 if (add_incoming) {
    2285           0 :                         ret = ldb_msg_append_value(msg, "trustAuthIncoming",
    2286             :                                                    &trustAuthIncoming, LDB_FLAG_MOD_REPLACE);
    2287           0 :                         if (ret != LDB_SUCCESS) {
    2288           0 :                                 return NT_STATUS_NO_MEMORY;
    2289             :                         }
    2290             :                 } else {
    2291           0 :                         ret = ldb_msg_add_empty(msg, "trustAuthIncoming",
    2292             :                                                 LDB_FLAG_MOD_REPLACE, NULL);
    2293           0 :                         if (ret != LDB_SUCCESS) {
    2294           0 :                                 return NT_STATUS_NO_MEMORY;
    2295             :                         }
    2296             :                 }
    2297             :         }
    2298          34 :         if (add_outgoing || del_outgoing) {
    2299           0 :                 if (add_outgoing) {
    2300           0 :                         ret = ldb_msg_append_value(msg, "trustAuthOutgoing",
    2301             :                                                    &trustAuthOutgoing, LDB_FLAG_MOD_REPLACE);
    2302           0 :                         if (ret != LDB_SUCCESS) {
    2303           0 :                                 return NT_STATUS_NO_MEMORY;
    2304             :                         }
    2305             :                 } else {
    2306           0 :                         ret = ldb_msg_add_empty(msg, "trustAuthOutgoing",
    2307             :                                                 LDB_FLAG_MOD_REPLACE, NULL);
    2308           0 :                         if (ret != LDB_SUCCESS) {
    2309           0 :                                 return NT_STATUS_NO_MEMORY;
    2310             :                         }
    2311             :                 }
    2312             :         }
    2313          34 :         if (del_forest_info) {
    2314           0 :                 ret = ldb_msg_add_empty(msg, "msDS-TrustForestTrustInfo",
    2315             :                                         LDB_FLAG_MOD_REPLACE, NULL);
    2316           0 :                 if (ret != LDB_SUCCESS) {
    2317           0 :                         return NT_STATUS_NO_MEMORY;
    2318             :                 }
    2319             :         }
    2320             : 
    2321             :         /* start transaction */
    2322          34 :         ret = ldb_transaction_start(p_state->sam_ldb);
    2323          34 :         if (ret != LDB_SUCCESS) {
    2324           0 :                 return NT_STATUS_INTERNAL_DB_CORRUPTION;
    2325             :         }
    2326          34 :         in_transaction = true;
    2327             : 
    2328          34 :         if (msg->num_elements) {
    2329          28 :                 ret = ldb_modify(p_state->sam_ldb, msg);
    2330          28 :                 if (ret != LDB_SUCCESS) {
    2331           0 :                         DEBUG(1,("Failed to modify trusted domain record %s: %s\n",
    2332             :                                  ldb_dn_get_linearized(msg->dn),
    2333             :                                  ldb_errstring(p_state->sam_ldb)));
    2334           0 :                         nt_status = dsdb_ldb_err_to_ntstatus(ret);
    2335           0 :                         goto done;
    2336             :                 }
    2337             :         }
    2338             : 
    2339          34 :         if (add_incoming || del_incoming) {
    2340           0 :                 const char *netbios_name;
    2341             : 
    2342           0 :                 netbios_name = ldb_msg_find_attr_as_string(dom_msg,
    2343             :                                                            "flatname", NULL);
    2344           0 :                 if (!netbios_name) {
    2345           0 :                         nt_status = NT_STATUS_INVALID_DOMAIN_STATE;
    2346           0 :                         goto done;
    2347             :                 }
    2348             : 
    2349             :                 /* We use trustAuthIncoming.data to indicate that auth_struct.incoming is valid */
    2350           0 :                 nt_status = update_trust_user(mem_ctx,
    2351             :                                               p_state->sam_ldb,
    2352             :                                               p_state->domain_dn,
    2353             :                                               del_incoming,
    2354             :                                               netbios_name,
    2355             :                                               current_passwords);
    2356           0 :                 if (!NT_STATUS_IS_OK(nt_status)) {
    2357           0 :                         goto done;
    2358             :                 }
    2359             :         }
    2360             : 
    2361             :         /* ok, all fine, commit transaction and return */
    2362          34 :         ret = ldb_transaction_commit(p_state->sam_ldb);
    2363          34 :         if (ret != LDB_SUCCESS) {
    2364           0 :                 return NT_STATUS_INTERNAL_DB_CORRUPTION;
    2365             :         }
    2366          34 :         in_transaction = false;
    2367             : 
    2368          34 :         nt_status = NT_STATUS_OK;
    2369             : 
    2370          34 : done:
    2371          34 :         if (in_transaction) {
    2372           0 :                 ldb_transaction_cancel(p_state->sam_ldb);
    2373             :         }
    2374          34 :         return nt_status;
    2375             : }
    2376             : 
    2377             : /*
    2378             :   lsa_SetInformationTrustedDomain
    2379             : */
    2380          22 : static NTSTATUS dcesrv_lsa_SetInformationTrustedDomain(
    2381             :                                 struct dcesrv_call_state *dce_call,
    2382             :                                 TALLOC_CTX *mem_ctx,
    2383             :                                 struct lsa_SetInformationTrustedDomain *r)
    2384             : {
    2385           0 :         struct dcesrv_handle *h;
    2386           0 :         struct lsa_trusted_domain_state *td_state;
    2387           0 :         struct ldb_message **msgs;
    2388           0 :         NTSTATUS nt_status;
    2389             : 
    2390          22 :         DCESRV_PULL_HANDLE(h, r->in.trustdom_handle,
    2391             :                            LSA_HANDLE_TRUSTED_DOMAIN);
    2392             : 
    2393          22 :         td_state = talloc_get_type(h->data, struct lsa_trusted_domain_state);
    2394             : 
    2395             :         /* get the trusted domain object */
    2396          22 :         nt_status = get_tdo(td_state->policy->sam_ldb, mem_ctx,
    2397             :                             td_state->trusted_domain_dn,
    2398             :                             NULL, NULL, NULL, &msgs);
    2399          22 :         if (!NT_STATUS_IS_OK(nt_status)) {
    2400           0 :                 if (NT_STATUS_EQUAL(nt_status,
    2401             :                                     NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
    2402           0 :                         return nt_status;
    2403             :                 }
    2404           0 :                 return NT_STATUS_INTERNAL_DB_CORRUPTION;
    2405             :         }
    2406             : 
    2407          22 :         return setInfoTrustedDomain_base(dce_call, td_state->policy, mem_ctx,
    2408             :                                          msgs[0], r->in.level, r->in.info);
    2409             : }
    2410             : 
    2411             : 
    2412             : /*
    2413             :   lsa_DeleteTrustedDomain
    2414             : */
    2415         149 : static NTSTATUS dcesrv_lsa_DeleteTrustedDomain(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
    2416             :                                       struct lsa_DeleteTrustedDomain *r)
    2417             : {
    2418           0 :         NTSTATUS status;
    2419         149 :         struct lsa_OpenTrustedDomain opn = {{0},{0}};
    2420           0 :         struct lsa_DeleteObject del;
    2421           0 :         struct dcesrv_handle *h;
    2422             : 
    2423         149 :         opn.in.handle = r->in.handle;
    2424         149 :         opn.in.sid = r->in.dom_sid;
    2425         149 :         opn.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
    2426         149 :         opn.out.trustdom_handle = talloc(mem_ctx, struct policy_handle);
    2427         149 :         if (!opn.out.trustdom_handle) {
    2428           0 :                 return NT_STATUS_NO_MEMORY;
    2429             :         }
    2430         149 :         status = dcesrv_lsa_OpenTrustedDomain(dce_call, mem_ctx, &opn);
    2431         149 :         if (!NT_STATUS_IS_OK(status)) {
    2432           0 :                 return status;
    2433             :         }
    2434             : 
    2435         149 :         DCESRV_PULL_HANDLE(h, opn.out.trustdom_handle, DCESRV_HANDLE_ANY);
    2436         149 :         talloc_steal(mem_ctx, h);
    2437             : 
    2438         149 :         del.in.handle = opn.out.trustdom_handle;
    2439         149 :         del.out.handle = opn.out.trustdom_handle;
    2440         149 :         status = dcesrv_lsa_DeleteObject(dce_call, mem_ctx, &del);
    2441         149 :         if (!NT_STATUS_IS_OK(status)) {
    2442           0 :                 return status;
    2443             :         }
    2444         149 :         return NT_STATUS_OK;
    2445             : }
    2446             : 
    2447        2653 : static NTSTATUS fill_trust_domain_ex(TALLOC_CTX *mem_ctx,
    2448             :                                      struct ldb_message *msg,
    2449             :                                      struct lsa_TrustDomainInfoInfoEx *info_ex)
    2450             : {
    2451           0 :         info_ex->domain_name.string
    2452        2653 :                 = ldb_msg_find_attr_as_string(msg, "trustPartner", NULL);
    2453           0 :         info_ex->netbios_name.string
    2454        2653 :                 = ldb_msg_find_attr_as_string(msg, "flatname", NULL);
    2455           0 :         info_ex->sid
    2456        2653 :                 = samdb_result_dom_sid(mem_ctx, msg, "securityIdentifier");
    2457           0 :         info_ex->trust_direction
    2458        2653 :                 = ldb_msg_find_attr_as_int(msg, "trustDirection", 0);
    2459           0 :         info_ex->trust_type
    2460        2653 :                 = ldb_msg_find_attr_as_int(msg, "trustType", 0);
    2461           0 :         info_ex->trust_attributes
    2462        2653 :                 = ldb_msg_find_attr_as_int(msg, "trustAttributes", 0);
    2463        2653 :         return NT_STATUS_OK;
    2464             : }
    2465             : 
    2466             : /*
    2467             :   lsa_QueryTrustedDomainInfo
    2468             : */
    2469        7870 : static NTSTATUS dcesrv_lsa_QueryTrustedDomainInfo(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
    2470             :                                            struct lsa_QueryTrustedDomainInfo *r)
    2471             : {
    2472        7870 :         union lsa_TrustedDomainInfo *info = NULL;
    2473           0 :         struct dcesrv_handle *h;
    2474           0 :         struct lsa_trusted_domain_state *trusted_domain_state;
    2475           0 :         struct ldb_message *msg;
    2476           0 :         int ret;
    2477           0 :         struct ldb_message **res;
    2478        7870 :         const char *attrs[] = {
    2479             :                 "flatname",
    2480             :                 "trustPartner",
    2481             :                 "securityIdentifier",
    2482             :                 "trustDirection",
    2483             :                 "trustType",
    2484             :                 "trustAttributes",
    2485             :                 "msDs-supportedEncryptionTypes",
    2486             :                 NULL
    2487             :         };
    2488             : 
    2489        7870 :         DCESRV_PULL_HANDLE(h, r->in.trustdom_handle, LSA_HANDLE_TRUSTED_DOMAIN);
    2490             : 
    2491        7870 :         trusted_domain_state = talloc_get_type(h->data, struct lsa_trusted_domain_state);
    2492             : 
    2493             :         /* pull all the user attributes */
    2494        7870 :         ret = gendb_search_dn(trusted_domain_state->policy->sam_ldb, mem_ctx,
    2495             :                               trusted_domain_state->trusted_domain_dn, &res, attrs);
    2496        7870 :         if (ret != 1) {
    2497           0 :                 return NT_STATUS_INTERNAL_DB_CORRUPTION;
    2498             :         }
    2499        7870 :         msg = res[0];
    2500             : 
    2501        7870 :         info = talloc_zero(mem_ctx, union lsa_TrustedDomainInfo);
    2502        7870 :         if (!info) {
    2503           0 :                 return NT_STATUS_NO_MEMORY;
    2504             :         }
    2505        7870 :         *r->out.info = info;
    2506             : 
    2507        7870 :         switch (r->in.level) {
    2508         579 :         case LSA_TRUSTED_DOMAIN_INFO_NAME:
    2509           0 :                 info->name.netbios_name.string
    2510         579 :                         = ldb_msg_find_attr_as_string(msg, "flatname", NULL);
    2511         579 :                 break;
    2512         579 :         case LSA_TRUSTED_DOMAIN_INFO_POSIX_OFFSET:
    2513           0 :                 info->posix_offset.posix_offset
    2514         579 :                         = ldb_msg_find_attr_as_uint(msg, "posixOffset", 0);
    2515         579 :                 break;
    2516             : #if 0  /* Win2k3 doesn't implement this */
    2517             :         case LSA_TRUSTED_DOMAIN_INFO_BASIC:
    2518             :                 r->out.info->info_basic.netbios_name.string
    2519             :                         = ldb_msg_find_attr_as_string(msg, "flatname", NULL);
    2520             :                 r->out.info->info_basic.sid
    2521             :                         = samdb_result_dom_sid(mem_ctx, msg, "securityIdentifier");
    2522             :                 break;
    2523             : #endif
    2524         895 :         case LSA_TRUSTED_DOMAIN_INFO_INFO_EX:
    2525        6109 :                 return fill_trust_domain_ex(mem_ctx, msg, &info->info_ex);
    2526             : 
    2527         603 :         case LSA_TRUSTED_DOMAIN_INFO_FULL_INFO:
    2528         603 :                 ZERO_STRUCT(info->full_info);
    2529         603 :                 return fill_trust_domain_ex(mem_ctx, msg, &info->full_info.info_ex);
    2530         579 :         case LSA_TRUSTED_DOMAIN_INFO_FULL_INFO_2_INTERNAL:
    2531         579 :                 ZERO_STRUCT(info->full_info2_internal);
    2532           0 :                 info->full_info2_internal.posix_offset.posix_offset
    2533         579 :                         = ldb_msg_find_attr_as_uint(msg, "posixOffset", 0);
    2534         579 :                 return fill_trust_domain_ex(mem_ctx, msg, &info->full_info2_internal.info.info_ex);
    2535             : 
    2536         603 :         case LSA_TRUSTED_DOMAIN_SUPPORTED_ENCRYPTION_TYPES:
    2537           0 :                 info->enc_types.enc_types
    2538         603 :                         = ldb_msg_find_attr_as_uint(msg, "msDs-supportedEncryptionTypes", KERB_ENCTYPE_RC4_HMAC_MD5);
    2539         603 :                 break;
    2540             : 
    2541        1152 :         case LSA_TRUSTED_DOMAIN_INFO_CONTROLLERS:
    2542             :         case LSA_TRUSTED_DOMAIN_INFO_INFO_EX2_INTERNAL:
    2543             :                 /* oops, we don't want to return the info after all */
    2544        1152 :                 talloc_free(info);
    2545        1152 :                 *r->out.info = NULL;
    2546        1152 :                 return NT_STATUS_INVALID_PARAMETER;
    2547        2880 :         default:
    2548             :                 /* oops, we don't want to return the info after all */
    2549        2880 :                 talloc_free(info);
    2550        2880 :                 *r->out.info = NULL;
    2551        2880 :                 return NT_STATUS_INVALID_INFO_CLASS;
    2552             :         }
    2553             : 
    2554        1761 :         return NT_STATUS_OK;
    2555             : }
    2556             : 
    2557             : 
    2558             : /*
    2559             :   lsa_QueryTrustedDomainInfoBySid
    2560             : */
    2561        1873 : static NTSTATUS dcesrv_lsa_QueryTrustedDomainInfoBySid(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
    2562             :                                                 struct lsa_QueryTrustedDomainInfoBySid *r)
    2563             : {
    2564           0 :         NTSTATUS status;
    2565        1873 :         struct lsa_OpenTrustedDomain opn = {{0},{0}};
    2566           0 :         struct lsa_QueryTrustedDomainInfo query;
    2567           0 :         struct dcesrv_handle *h;
    2568             : 
    2569        1873 :         opn.in.handle = r->in.handle;
    2570        1873 :         opn.in.sid = r->in.dom_sid;
    2571        1873 :         opn.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
    2572        1873 :         opn.out.trustdom_handle = talloc(mem_ctx, struct policy_handle);
    2573        1873 :         if (!opn.out.trustdom_handle) {
    2574           0 :                 return NT_STATUS_NO_MEMORY;
    2575             :         }
    2576        1873 :         status = dcesrv_lsa_OpenTrustedDomain(dce_call, mem_ctx, &opn);
    2577        1873 :         if (!NT_STATUS_IS_OK(status)) {
    2578           1 :                 return status;
    2579             :         }
    2580             : 
    2581             :         /* Ensure this handle goes away at the end of this call */
    2582        1872 :         DCESRV_PULL_HANDLE(h, opn.out.trustdom_handle, DCESRV_HANDLE_ANY);
    2583        1872 :         talloc_steal(mem_ctx, h);
    2584             : 
    2585        1872 :         query.in.trustdom_handle = opn.out.trustdom_handle;
    2586        1872 :         query.in.level = r->in.level;
    2587        1872 :         query.out.info = r->out.info;
    2588        1872 :         status = dcesrv_lsa_QueryTrustedDomainInfo(dce_call, mem_ctx, &query);
    2589        1872 :         if (!NT_STATUS_IS_OK(status)) {
    2590        1008 :                 return status;
    2591             :         }
    2592             : 
    2593         864 :         return NT_STATUS_OK;
    2594             : }
    2595             : 
    2596             : /*
    2597             :   lsa_SetTrustedDomainInfoByName
    2598             : */
    2599          18 : static NTSTATUS dcesrv_lsa_SetTrustedDomainInfoByName(struct dcesrv_call_state *dce_call,
    2600             :                                                TALLOC_CTX *mem_ctx,
    2601             :                                                struct lsa_SetTrustedDomainInfoByName *r)
    2602             : {
    2603           0 :         struct dcesrv_handle *policy_handle;
    2604           0 :         struct lsa_policy_state *policy_state;
    2605           0 :         struct ldb_message **msgs;
    2606           0 :         NTSTATUS nt_status;
    2607             : 
    2608          18 :         DCESRV_PULL_HANDLE(policy_handle, r->in.handle, LSA_HANDLE_POLICY);
    2609          18 :         policy_state = policy_handle->data;
    2610             : 
    2611             :         /* get the trusted domain object */
    2612          18 :         nt_status = get_tdo(policy_state->sam_ldb, mem_ctx,
    2613             :                             policy_state->domain_dn,
    2614          18 :                             r->in.trusted_domain->string,
    2615          18 :                             r->in.trusted_domain->string,
    2616             :                             NULL, &msgs);
    2617          18 :         if (!NT_STATUS_IS_OK(nt_status)) {
    2618           0 :                 if (NT_STATUS_EQUAL(nt_status,
    2619             :                                     NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
    2620           0 :                         return nt_status;
    2621             :                 }
    2622           0 :                 return NT_STATUS_INTERNAL_DB_CORRUPTION;
    2623             :         }
    2624             : 
    2625          18 :         return setInfoTrustedDomain_base(dce_call, policy_state, mem_ctx,
    2626             :                                          msgs[0], r->in.level, r->in.info);
    2627             : }
    2628             : 
    2629             : /*
    2630             :    lsa_QueryTrustedDomainInfoByName
    2631             : */
    2632        2160 : static NTSTATUS dcesrv_lsa_QueryTrustedDomainInfoByName(struct dcesrv_call_state *dce_call,
    2633             :                                                  TALLOC_CTX *mem_ctx,
    2634             :                                                  struct lsa_QueryTrustedDomainInfoByName *r)
    2635             : {
    2636           0 :         NTSTATUS status;
    2637        2160 :         struct lsa_OpenTrustedDomainByName opn = {{0},{0}};
    2638           0 :         struct lsa_QueryTrustedDomainInfo query;
    2639           0 :         struct dcesrv_handle *h;
    2640             : 
    2641        2160 :         opn.in.handle = r->in.handle;
    2642        2160 :         opn.in.name = *r->in.trusted_domain;
    2643        2160 :         opn.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED;
    2644        2160 :         opn.out.trustdom_handle = talloc(mem_ctx, struct policy_handle);
    2645        2160 :         if (!opn.out.trustdom_handle) {
    2646           0 :                 return NT_STATUS_NO_MEMORY;
    2647             :         }
    2648        2160 :         status = dcesrv_lsa_OpenTrustedDomainByName(dce_call, mem_ctx, &opn);
    2649        2160 :         if (!NT_STATUS_IS_OK(status)) {
    2650          53 :                 return status;
    2651             :         }
    2652             : 
    2653             :         /* Ensure this handle goes away at the end of this call */
    2654        2107 :         DCESRV_PULL_HANDLE(h, opn.out.trustdom_handle, DCESRV_HANDLE_ANY);
    2655        2107 :         talloc_steal(mem_ctx, h);
    2656             : 
    2657        2107 :         query.in.trustdom_handle = opn.out.trustdom_handle;
    2658        2107 :         query.in.level = r->in.level;
    2659        2107 :         query.out.info = r->out.info;
    2660        2107 :         status = dcesrv_lsa_QueryTrustedDomainInfo(dce_call, mem_ctx, &query);
    2661        2107 :         if (!NT_STATUS_IS_OK(status)) {
    2662        1008 :                 return status;
    2663             :         }
    2664             : 
    2665        1099 :         return NT_STATUS_OK;
    2666             : }
    2667             : 
    2668             : /*
    2669             :   lsa_CloseTrustedDomainEx
    2670             : */
    2671         144 : static NTSTATUS dcesrv_lsa_CloseTrustedDomainEx(struct dcesrv_call_state *dce_call,
    2672             :                                          TALLOC_CTX *mem_ctx,
    2673             :                                          struct lsa_CloseTrustedDomainEx *r)
    2674             : {
    2675             :         /* The result of a bad hair day from an IDL programmer?  Not
    2676             :          * implemented in Win2k3.  You should always just lsa_Close
    2677             :          * anyway. */
    2678         144 :         return NT_STATUS_NOT_IMPLEMENTED;
    2679             : }
    2680             : 
    2681             : 
    2682             : /*
    2683             :   comparison function for sorting lsa_DomainInformation array
    2684             : */
    2685        1428 : static int compare_DomainInfo(struct lsa_DomainInfo *e1, struct lsa_DomainInfo *e2)
    2686             : {
    2687        1428 :         return strcasecmp_m(e1->name.string, e2->name.string);
    2688             : }
    2689             : 
    2690             : /*
    2691             :   lsa_EnumTrustDom
    2692             : */
    2693          78 : static NTSTATUS dcesrv_lsa_EnumTrustDom(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
    2694             :                                  struct lsa_EnumTrustDom *r)
    2695             : {
    2696           3 :         struct dcesrv_handle *policy_handle;
    2697           3 :         struct lsa_DomainInfo *entries;
    2698           3 :         struct lsa_policy_state *policy_state;
    2699           3 :         struct ldb_message **domains;
    2700          78 :         const char *attrs[] = {
    2701             :                 "flatname",
    2702             :                 "securityIdentifier",
    2703             :                 NULL
    2704             :         };
    2705             : 
    2706             : 
    2707           3 :         int count, i;
    2708             : 
    2709          78 :         *r->out.resume_handle = 0;
    2710             : 
    2711          78 :         r->out.domains->domains = NULL;
    2712          78 :         r->out.domains->count = 0;
    2713             : 
    2714          78 :         DCESRV_PULL_HANDLE(policy_handle, r->in.handle, LSA_HANDLE_POLICY);
    2715             : 
    2716          78 :         policy_state = policy_handle->data;
    2717             : 
    2718             :         /* search for all users in this domain. This could possibly be cached and
    2719             :            resumed based on resume_key */
    2720          78 :         count = gendb_search(policy_state->sam_ldb, mem_ctx, policy_state->system_dn, &domains, attrs,
    2721             :                              "objectclass=trustedDomain");
    2722          78 :         if (count < 0) {
    2723           0 :                 return NT_STATUS_INTERNAL_DB_CORRUPTION;
    2724             :         }
    2725             : 
    2726             :         /* convert to lsa_TrustInformation format */
    2727          78 :         entries = talloc_array(mem_ctx, struct lsa_DomainInfo, count);
    2728          78 :         if (!entries) {
    2729           0 :                 return NT_STATUS_NO_MEMORY;
    2730             :         }
    2731         654 :         for (i=0;i<count;i++) {
    2732         576 :                 entries[i].sid = samdb_result_dom_sid(mem_ctx, domains[i], "securityIdentifier");
    2733         576 :                 entries[i].name.string = ldb_msg_find_attr_as_string(domains[i], "flatname", NULL);
    2734             :         }
    2735             : 
    2736             :         /* sort the results by name */
    2737          78 :         TYPESAFE_QSORT(entries, count, compare_DomainInfo);
    2738             : 
    2739          78 :         if (*r->in.resume_handle >= count) {
    2740          30 :                 *r->out.resume_handle = -1;
    2741             : 
    2742          30 :                 return NT_STATUS_NO_MORE_ENTRIES;
    2743             :         }
    2744             : 
    2745             :         /* return the rest, limit by max_size. Note that we
    2746             :            use the w2k3 element size value of 60 */
    2747          48 :         r->out.domains->count = count - *r->in.resume_handle;
    2748          48 :         r->out.domains->count = MIN(r->out.domains->count,
    2749             :                                  1+(r->in.max_size/LSA_ENUM_TRUST_DOMAIN_MULTIPLIER));
    2750             : 
    2751          48 :         r->out.domains->domains = entries + *r->in.resume_handle;
    2752             : 
    2753          48 :         if (r->out.domains->count < count - *r->in.resume_handle) {
    2754          36 :                 *r->out.resume_handle = *r->in.resume_handle + r->out.domains->count;
    2755          36 :                 return STATUS_MORE_ENTRIES;
    2756             :         }
    2757             : 
    2758             :         /* according to MS-LSAD 3.1.4.7.8 output resume handle MUST
    2759             :          * always be larger than the previous input resume handle, in
    2760             :          * particular when hitting the last query it is vital to set the
    2761             :          * resume handle correctly to avoid infinite client loops, as
    2762             :          * seen e.g. with Windows XP SP3 when resume handle is 0 and
    2763             :          * status is NT_STATUS_OK - gd */
    2764             : 
    2765          12 :         *r->out.resume_handle = (uint32_t)-1;
    2766             : 
    2767          12 :         return NT_STATUS_OK;
    2768             : }
    2769             : 
    2770             : /*
    2771             :   comparison function for sorting lsa_DomainInformation array
    2772             : */
    2773        1428 : static int compare_TrustDomainInfoInfoEx(struct lsa_TrustDomainInfoInfoEx *e1, struct lsa_TrustDomainInfoInfoEx *e2)
    2774             : {
    2775        1428 :         return strcasecmp_m(e1->netbios_name.string, e2->netbios_name.string);
    2776             : }
    2777             : 
    2778             : /*
    2779             :   lsa_EnumTrustedDomainsEx
    2780             : */
    2781          54 : static NTSTATUS dcesrv_lsa_EnumTrustedDomainsEx(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
    2782             :                                         struct lsa_EnumTrustedDomainsEx *r)
    2783             : {
    2784           0 :         struct dcesrv_handle *policy_handle;
    2785           0 :         struct lsa_TrustDomainInfoInfoEx *entries;
    2786           0 :         struct lsa_policy_state *policy_state;
    2787           0 :         struct ldb_message **domains;
    2788          54 :         const char *attrs[] = {
    2789             :                 "flatname",
    2790             :                 "trustPartner",
    2791             :                 "securityIdentifier",
    2792             :                 "trustDirection",
    2793             :                 "trustType",
    2794             :                 "trustAttributes",
    2795             :                 NULL
    2796             :         };
    2797           0 :         NTSTATUS nt_status;
    2798             : 
    2799           0 :         int count, i;
    2800             : 
    2801          54 :         *r->out.resume_handle = 0;
    2802             : 
    2803          54 :         r->out.domains->domains = NULL;
    2804          54 :         r->out.domains->count = 0;
    2805             : 
    2806          54 :         DCESRV_PULL_HANDLE(policy_handle, r->in.handle, LSA_HANDLE_POLICY);
    2807             : 
    2808          54 :         policy_state = policy_handle->data;
    2809             : 
    2810             :         /* search for all users in this domain. This could possibly be cached and
    2811             :            resumed based on resume_key */
    2812          54 :         count = gendb_search(policy_state->sam_ldb, mem_ctx, policy_state->system_dn, &domains, attrs,
    2813             :                              "objectclass=trustedDomain");
    2814          54 :         if (count < 0) {
    2815           0 :                 return NT_STATUS_INTERNAL_DB_CORRUPTION;
    2816             :         }
    2817             : 
    2818             :         /* convert to lsa_DomainInformation format */
    2819          54 :         entries = talloc_array(mem_ctx, struct lsa_TrustDomainInfoInfoEx, count);
    2820          54 :         if (!entries) {
    2821           0 :                 return NT_STATUS_NO_MEMORY;
    2822             :         }
    2823         630 :         for (i=0;i<count;i++) {
    2824         576 :                 nt_status = fill_trust_domain_ex(mem_ctx, domains[i], &entries[i]);
    2825         576 :                 if (!NT_STATUS_IS_OK(nt_status)) {
    2826           0 :                         return nt_status;
    2827             :                 }
    2828             :         }
    2829             : 
    2830             :         /* sort the results by name */
    2831          54 :         TYPESAFE_QSORT(entries, count, compare_TrustDomainInfoInfoEx);
    2832             : 
    2833          54 :         if (*r->in.resume_handle >= count) {
    2834           6 :                 *r->out.resume_handle = -1;
    2835             : 
    2836           6 :                 return NT_STATUS_NO_MORE_ENTRIES;
    2837             :         }
    2838             : 
    2839             :         /* return the rest, limit by max_size. Note that we
    2840             :            use the w2k3 element size value of 60 */
    2841          48 :         r->out.domains->count = count - *r->in.resume_handle;
    2842          48 :         r->out.domains->count = MIN(r->out.domains->count,
    2843             :                                  1+(r->in.max_size/LSA_ENUM_TRUST_DOMAIN_EX_MULTIPLIER));
    2844             : 
    2845          48 :         r->out.domains->domains = entries + *r->in.resume_handle;
    2846             : 
    2847          48 :         if (r->out.domains->count < count - *r->in.resume_handle) {
    2848          36 :                 *r->out.resume_handle = *r->in.resume_handle + r->out.domains->count;
    2849          36 :                 return STATUS_MORE_ENTRIES;
    2850             :         }
    2851             : 
    2852          12 :         *r->out.resume_handle = *r->in.resume_handle + r->out.domains->count;
    2853             : 
    2854          12 :         return NT_STATUS_OK;
    2855             : }
    2856             : 
    2857             : 
    2858             : /*
    2859             :   lsa_OpenAccount
    2860             : */
    2861          26 : static NTSTATUS dcesrv_lsa_OpenAccount(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
    2862             :                                 struct lsa_OpenAccount *r)
    2863             : {
    2864           0 :         struct dcesrv_handle *h, *ah;
    2865           0 :         struct lsa_policy_state *state;
    2866           0 :         struct lsa_account_state *astate;
    2867             : 
    2868          26 :         ZERO_STRUCTP(r->out.acct_handle);
    2869             : 
    2870          26 :         DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
    2871             : 
    2872          26 :         state = h->data;
    2873             : 
    2874          26 :         astate = talloc(dce_call->conn, struct lsa_account_state);
    2875          26 :         if (astate == NULL) {
    2876           0 :                 return NT_STATUS_NO_MEMORY;
    2877             :         }
    2878             : 
    2879          26 :         astate->account_sid = dom_sid_dup(astate, r->in.sid);
    2880          26 :         if (astate->account_sid == NULL) {
    2881           0 :                 talloc_free(astate);
    2882           0 :                 return NT_STATUS_NO_MEMORY;
    2883             :         }
    2884             : 
    2885          26 :         astate->policy = talloc_reference(astate, state);
    2886          26 :         astate->access_mask = r->in.access_mask;
    2887             : 
    2888             :         /*
    2889             :          * For now we grant all requested access.
    2890             :          *
    2891             :          * We will fail at the ldb layer later.
    2892             :          */
    2893          26 :         if (astate->access_mask & SEC_FLAG_MAXIMUM_ALLOWED) {
    2894          26 :                 astate->access_mask &= ~SEC_FLAG_MAXIMUM_ALLOWED;
    2895          26 :                 astate->access_mask |= LSA_ACCOUNT_ALL_ACCESS;
    2896             :         }
    2897          26 :         se_map_generic(&astate->access_mask, &dcesrv_lsa_account_mapping);
    2898             : 
    2899          26 :         DEBUG(10,("%s: %s access desired[0x%08X] granted[0x%08X] - success.\n",
    2900             :                   __func__, dom_sid_string(mem_ctx, astate->account_sid),
    2901             :                  (unsigned)r->in.access_mask,
    2902             :                  (unsigned)astate->access_mask));
    2903             : 
    2904          26 :         ah = dcesrv_handle_create(dce_call, LSA_HANDLE_ACCOUNT);
    2905          26 :         if (!ah) {
    2906           0 :                 talloc_free(astate);
    2907           0 :                 return NT_STATUS_NO_MEMORY;
    2908             :         }
    2909             : 
    2910          26 :         ah->data = talloc_steal(ah, astate);
    2911             : 
    2912          26 :         *r->out.acct_handle = ah->wire_handle;
    2913             : 
    2914          26 :         return NT_STATUS_OK;
    2915             : }
    2916             : 
    2917             : 
    2918             : /*
    2919             :   lsa_EnumPrivsAccount
    2920             : */
    2921          18 : static NTSTATUS dcesrv_lsa_EnumPrivsAccount(struct dcesrv_call_state *dce_call,
    2922             :                                      TALLOC_CTX *mem_ctx,
    2923             :                                      struct lsa_EnumPrivsAccount *r)
    2924             : {
    2925           0 :         struct dcesrv_handle *h;
    2926           0 :         struct lsa_account_state *astate;
    2927           0 :         int ret;
    2928           0 :         unsigned int i, j;
    2929           0 :         struct ldb_message **res;
    2930          18 :         const char * const attrs[] = { "privilege", NULL};
    2931           0 :         struct ldb_message_element *el;
    2932           0 :         const char *sidstr;
    2933           0 :         struct lsa_PrivilegeSet *privs;
    2934             : 
    2935          18 :         DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_ACCOUNT);
    2936             : 
    2937          18 :         astate = h->data;
    2938             : 
    2939          18 :         privs = talloc(mem_ctx, struct lsa_PrivilegeSet);
    2940          18 :         if (privs == NULL) {
    2941           0 :                 return NT_STATUS_NO_MEMORY;
    2942             :         }
    2943          18 :         privs->count = 0;
    2944          18 :         privs->unknown = 0;
    2945          18 :         privs->set = NULL;
    2946             : 
    2947          18 :         *r->out.privs = privs;
    2948             : 
    2949          18 :         sidstr = ldap_encode_ndr_dom_sid(mem_ctx, astate->account_sid);
    2950          18 :         if (sidstr == NULL) {
    2951           0 :                 return NT_STATUS_NO_MEMORY;
    2952             :         }
    2953             : 
    2954          18 :         ret = gendb_search(astate->policy->pdb, mem_ctx, NULL, &res, attrs,
    2955             :                            "objectSid=%s", sidstr);
    2956          18 :         if (ret < 0) {
    2957           0 :                 return NT_STATUS_INTERNAL_DB_CORRUPTION;
    2958             :         }
    2959          18 :         if (ret != 1) {
    2960           0 :                 return NT_STATUS_OK;
    2961             :         }
    2962             : 
    2963          18 :         el = ldb_msg_find_element(res[0], "privilege");
    2964          18 :         if (el == NULL || el->num_values == 0) {
    2965           0 :                 return NT_STATUS_OK;
    2966             :         }
    2967             : 
    2968          18 :         privs->set = talloc_array(privs,
    2969             :                                   struct lsa_LUIDAttribute, el->num_values);
    2970          18 :         if (privs->set == NULL) {
    2971           0 :                 return NT_STATUS_NO_MEMORY;
    2972             :         }
    2973             : 
    2974          18 :         j = 0;
    2975         138 :         for (i=0;i<el->num_values;i++) {
    2976         120 :                 int id = sec_privilege_id((const char *)el->values[i].data);
    2977         120 :                 if (id == SEC_PRIV_INVALID) {
    2978             :                         /* Perhaps an account right, not a privilege */
    2979          24 :                         continue;
    2980             :                 }
    2981          96 :                 privs->set[j].attribute = 0;
    2982          96 :                 privs->set[j].luid.low = id;
    2983          96 :                 privs->set[j].luid.high = 0;
    2984          96 :                 j++;
    2985             :         }
    2986             : 
    2987          18 :         privs->count = j;
    2988             : 
    2989          18 :         return NT_STATUS_OK;
    2990             : }
    2991             : 
    2992             : /*
    2993             :   lsa_EnumAccountRights
    2994             : */
    2995          78 : static NTSTATUS dcesrv_lsa_EnumAccountRights(struct dcesrv_call_state *dce_call,
    2996             :                                       TALLOC_CTX *mem_ctx,
    2997             :                                       struct lsa_EnumAccountRights *r)
    2998             : {
    2999           0 :         struct dcesrv_handle *h;
    3000           0 :         struct lsa_policy_state *state;
    3001           0 :         int ret;
    3002           0 :         unsigned int i;
    3003           0 :         struct ldb_message **res;
    3004          78 :         const char * const attrs[] = { "privilege", NULL};
    3005           0 :         const char *sidstr;
    3006           0 :         struct ldb_message_element *el;
    3007             : 
    3008          78 :         DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
    3009             : 
    3010          78 :         state = h->data;
    3011             : 
    3012          78 :         sidstr = ldap_encode_ndr_dom_sid(mem_ctx, r->in.sid);
    3013          78 :         if (sidstr == NULL) {
    3014           0 :                 return NT_STATUS_NO_MEMORY;
    3015             :         }
    3016             : 
    3017          78 :         ret = gendb_search(state->pdb, mem_ctx, NULL, &res, attrs,
    3018             :                            "(&(objectSid=%s)(privilege=*))", sidstr);
    3019          78 :         if (ret == 0) {
    3020          17 :                 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
    3021             :         }
    3022          61 :         if (ret != 1) {
    3023           0 :                 DEBUG(3, ("searching for account rights for SID: %s failed: %s\n",
    3024             :                           dom_sid_string(mem_ctx, r->in.sid),
    3025             :                           ldb_errstring(state->pdb)));
    3026           0 :                 return NT_STATUS_INTERNAL_DB_CORRUPTION;
    3027             :         }
    3028             : 
    3029          61 :         el = ldb_msg_find_element(res[0], "privilege");
    3030          61 :         if (el == NULL || el->num_values == 0) {
    3031           0 :                 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
    3032             :         }
    3033             : 
    3034          61 :         r->out.rights->count = el->num_values;
    3035          61 :         r->out.rights->names = talloc_array(r->out.rights,
    3036             :                                             struct lsa_StringLarge, r->out.rights->count);
    3037          61 :         if (r->out.rights->names == NULL) {
    3038           0 :                 return NT_STATUS_NO_MEMORY;
    3039             :         }
    3040             : 
    3041         599 :         for (i=0;i<el->num_values;i++) {
    3042         538 :                 r->out.rights->names[i].string = (const char *)el->values[i].data;
    3043             :         }
    3044             : 
    3045          61 :         return NT_STATUS_OK;
    3046             : }
    3047             : 
    3048             : 
    3049             : 
    3050             : /*
    3051             :   helper for lsa_AddAccountRights and lsa_RemoveAccountRights
    3052             : */
    3053          44 : static NTSTATUS dcesrv_lsa_AddRemoveAccountRights(struct dcesrv_call_state *dce_call,
    3054             :                                            TALLOC_CTX *mem_ctx,
    3055             :                                            struct lsa_policy_state *state,
    3056             :                                            int ldb_flag,
    3057             :                                            struct dom_sid *sid,
    3058             :                                            const struct lsa_RightSet *rights)
    3059             : {
    3060           0 :         struct auth_session_info *session_info =
    3061          44 :                 dcesrv_call_session_info(dce_call);
    3062           0 :         const char *sidstr, *sidndrstr;
    3063           0 :         struct ldb_message *msg;
    3064           0 :         struct ldb_message_element *el;
    3065           0 :         int ret;
    3066           0 :         uint32_t i;
    3067           0 :         struct lsa_EnumAccountRights r2;
    3068           0 :         char *dnstr;
    3069             : 
    3070          44 :         if (security_session_user_level(session_info, NULL) <
    3071             :             SECURITY_ADMINISTRATOR) {
    3072           0 :                 DEBUG(0,("lsa_AddRemoveAccount refused for supplied security token\n"));
    3073           0 :                 return NT_STATUS_ACCESS_DENIED;
    3074             :         }
    3075             : 
    3076          44 :         msg = ldb_msg_new(mem_ctx);
    3077          44 :         if (msg == NULL) {
    3078           0 :                 return NT_STATUS_NO_MEMORY;
    3079             :         }
    3080             : 
    3081          44 :         sidndrstr = ldap_encode_ndr_dom_sid(msg, sid);
    3082          44 :         if (sidndrstr == NULL) {
    3083           0 :                 TALLOC_FREE(msg);
    3084           0 :                 return NT_STATUS_NO_MEMORY;
    3085             :         }
    3086             : 
    3087          44 :         sidstr = dom_sid_string(msg, sid);
    3088          44 :         if (sidstr == NULL) {
    3089           0 :                 TALLOC_FREE(msg);
    3090           0 :                 return NT_STATUS_NO_MEMORY;
    3091             :         }
    3092             : 
    3093          44 :         dnstr = talloc_asprintf(msg, "sid=%s", sidstr);
    3094          44 :         if (dnstr == NULL) {
    3095           0 :                 TALLOC_FREE(msg);
    3096           0 :                 return NT_STATUS_NO_MEMORY;
    3097             :         }
    3098             : 
    3099          44 :         msg->dn = ldb_dn_new(msg, state->pdb, dnstr);
    3100          44 :         if (msg->dn == NULL) {
    3101           0 :                 TALLOC_FREE(msg);
    3102           0 :                 return NT_STATUS_NO_MEMORY;
    3103             :         }
    3104             : 
    3105          44 :         if (LDB_FLAG_MOD_TYPE(ldb_flag) == LDB_FLAG_MOD_ADD) {
    3106           0 :                 NTSTATUS status;
    3107             : 
    3108          25 :                 r2.in.handle = &state->handle->wire_handle;
    3109          25 :                 r2.in.sid = sid;
    3110          25 :                 r2.out.rights = talloc(mem_ctx, struct lsa_RightSet);
    3111             : 
    3112          25 :                 status = dcesrv_lsa_EnumAccountRights(dce_call, mem_ctx, &r2);
    3113          25 :                 if (!NT_STATUS_IS_OK(status)) {
    3114           6 :                         ZERO_STRUCTP(r2.out.rights);
    3115             :                 }
    3116             :         }
    3117             : 
    3118          92 :         for (i=0;i<rights->count;i++) {
    3119           0 :                 bool ok;
    3120             : 
    3121          48 :                 ok = dcesrc_lsa_valid_AccountRight(rights->names[i].string);
    3122          48 :                 if (!ok) {
    3123           0 :                         talloc_free(msg);
    3124           0 :                         return NT_STATUS_NO_SUCH_PRIVILEGE;
    3125             :                 }
    3126             : 
    3127          48 :                 if (LDB_FLAG_MOD_TYPE(ldb_flag) == LDB_FLAG_MOD_ADD) {
    3128             :                         uint32_t j;
    3129         131 :                         for (j=0;j<r2.out.rights->count;j++) {
    3130         106 :                                 if (strcasecmp_m(r2.out.rights->names[j].string,
    3131         106 :                                                rights->names[i].string) == 0) {
    3132           0 :                                         break;
    3133             :                                 }
    3134             :                         }
    3135          25 :                         if (j != r2.out.rights->count) continue;
    3136             :                 }
    3137             : 
    3138          48 :                 ret = ldb_msg_add_string(msg, "privilege", rights->names[i].string);
    3139          48 :                 if (ret != LDB_SUCCESS) {
    3140           0 :                         talloc_free(msg);
    3141           0 :                         return NT_STATUS_NO_MEMORY;
    3142             :                 }
    3143             :         }
    3144             : 
    3145          44 :         el = ldb_msg_find_element(msg, "privilege");
    3146          44 :         if (!el) {
    3147           0 :                 talloc_free(msg);
    3148           0 :                 return NT_STATUS_OK;
    3149             :         }
    3150             : 
    3151          44 :         el->flags = ldb_flag;
    3152             : 
    3153          44 :         ret = ldb_modify(state->pdb, msg);
    3154          44 :         if (ret == LDB_ERR_NO_SUCH_OBJECT) {
    3155           6 :                 if (samdb_msg_add_dom_sid(state->pdb, msg, msg, "objectSid", sid) != LDB_SUCCESS) {
    3156           0 :                         talloc_free(msg);
    3157           0 :                         return NT_STATUS_NO_MEMORY;
    3158             :                 }
    3159           6 :                 ldb_msg_add_string(msg, "comment", "added via LSA");
    3160           6 :                 ret = ldb_add(state->pdb, msg);
    3161             :         }
    3162          44 :         if (ret != LDB_SUCCESS) {
    3163           0 :                 if (LDB_FLAG_MOD_TYPE(ldb_flag) == LDB_FLAG_MOD_DELETE && ret == LDB_ERR_NO_SUCH_ATTRIBUTE) {
    3164           0 :                         talloc_free(msg);
    3165           0 :                         return NT_STATUS_OK;
    3166             :                 }
    3167           0 :                 DEBUG(3, ("Could not %s attributes from %s: %s\n",
    3168             :                           LDB_FLAG_MOD_TYPE(ldb_flag) == LDB_FLAG_MOD_DELETE ? "delete" : "add",
    3169             :                           ldb_dn_get_linearized(msg->dn), ldb_errstring(state->pdb)));
    3170           0 :                 talloc_free(msg);
    3171           0 :                 return NT_STATUS_UNEXPECTED_IO_ERROR;
    3172             :         }
    3173             : 
    3174          44 :         talloc_free(msg);
    3175          44 :         return NT_STATUS_OK;
    3176             : }
    3177             : 
    3178             : /*
    3179             :   lsa_AddPrivilegesToAccount
    3180             : */
    3181          15 : static NTSTATUS dcesrv_lsa_AddPrivilegesToAccount(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
    3182             :                                            struct lsa_AddPrivilegesToAccount *r)
    3183             : {
    3184           0 :         struct lsa_RightSet rights;
    3185           0 :         struct dcesrv_handle *h;
    3186           0 :         struct lsa_account_state *astate;
    3187           0 :         uint32_t i;
    3188             : 
    3189          15 :         DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_ACCOUNT);
    3190             : 
    3191          15 :         astate = h->data;
    3192             : 
    3193          15 :         rights.count = r->in.privs->count;
    3194          15 :         rights.names = talloc_array(mem_ctx, struct lsa_StringLarge, rights.count);
    3195          15 :         if (rights.names == NULL) {
    3196           0 :                 return NT_STATUS_NO_MEMORY;
    3197             :         }
    3198          30 :         for (i=0;i<rights.count;i++) {
    3199          15 :                 int id = r->in.privs->set[i].luid.low;
    3200          15 :                 if (r->in.privs->set[i].luid.high) {
    3201           0 :                         return NT_STATUS_NO_SUCH_PRIVILEGE;
    3202             :                 }
    3203          15 :                 rights.names[i].string = sec_privilege_name(id);
    3204          15 :                 if (rights.names[i].string == NULL) {
    3205           0 :                         return NT_STATUS_NO_SUCH_PRIVILEGE;
    3206             :                 }
    3207             :         }
    3208             : 
    3209          15 :         return dcesrv_lsa_AddRemoveAccountRights(dce_call, mem_ctx, astate->policy,
    3210             :                                           LDB_FLAG_MOD_ADD, astate->account_sid,
    3211             :                                           &rights);
    3212             : }
    3213             : 
    3214             : 
    3215             : /*
    3216             :   lsa_RemovePrivilegesFromAccount
    3217             : */
    3218          15 : static NTSTATUS dcesrv_lsa_RemovePrivilegesFromAccount(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
    3219             :                                                 struct lsa_RemovePrivilegesFromAccount *r)
    3220             : {
    3221           0 :         struct lsa_RightSet *rights;
    3222           0 :         struct dcesrv_handle *h;
    3223           0 :         struct lsa_account_state *astate;
    3224           0 :         uint32_t i;
    3225             : 
    3226          15 :         DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_ACCOUNT);
    3227             : 
    3228          15 :         astate = h->data;
    3229             : 
    3230          15 :         rights = talloc(mem_ctx, struct lsa_RightSet);
    3231             : 
    3232          15 :         if (r->in.remove_all == 1 &&
    3233           0 :             r->in.privs == NULL) {
    3234           0 :                 struct lsa_EnumAccountRights r2;
    3235           0 :                 NTSTATUS status;
    3236             : 
    3237           0 :                 r2.in.handle = &astate->policy->handle->wire_handle;
    3238           0 :                 r2.in.sid = astate->account_sid;
    3239           0 :                 r2.out.rights = rights;
    3240             : 
    3241           0 :                 status = dcesrv_lsa_EnumAccountRights(dce_call, mem_ctx, &r2);
    3242           0 :                 if (!NT_STATUS_IS_OK(status)) {
    3243           0 :                         return status;
    3244             :                 }
    3245             : 
    3246           0 :                 return dcesrv_lsa_AddRemoveAccountRights(dce_call, mem_ctx, astate->policy,
    3247             :                                                   LDB_FLAG_MOD_DELETE, astate->account_sid,
    3248           0 :                                                   r2.out.rights);
    3249             :         }
    3250             : 
    3251          15 :         if (r->in.remove_all != 0) {
    3252           0 :                 return NT_STATUS_INVALID_PARAMETER;
    3253             :         }
    3254             : 
    3255          15 :         rights->count = r->in.privs->count;
    3256          15 :         rights->names = talloc_array(mem_ctx, struct lsa_StringLarge, rights->count);
    3257          15 :         if (rights->names == NULL) {
    3258           0 :                 return NT_STATUS_NO_MEMORY;
    3259             :         }
    3260          30 :         for (i=0;i<rights->count;i++) {
    3261          15 :                 int id = r->in.privs->set[i].luid.low;
    3262          15 :                 if (r->in.privs->set[i].luid.high) {
    3263           0 :                         return NT_STATUS_NO_SUCH_PRIVILEGE;
    3264             :                 }
    3265          15 :                 rights->names[i].string = sec_privilege_name(id);
    3266          15 :                 if (rights->names[i].string == NULL) {
    3267           0 :                         return NT_STATUS_NO_SUCH_PRIVILEGE;
    3268             :                 }
    3269             :         }
    3270             : 
    3271          15 :         return dcesrv_lsa_AddRemoveAccountRights(dce_call, mem_ctx, astate->policy,
    3272             :                                           LDB_FLAG_MOD_DELETE, astate->account_sid,
    3273             :                                           rights);
    3274             : }
    3275             : 
    3276             : 
    3277             : /*
    3278             :   lsa_GetQuotasForAccount
    3279             : */
    3280           0 : static NTSTATUS dcesrv_lsa_GetQuotasForAccount(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
    3281             :                        struct lsa_GetQuotasForAccount *r)
    3282             : {
    3283           0 :         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
    3284             : }
    3285             : 
    3286             : 
    3287             : /*
    3288             :   lsa_SetQuotasForAccount
    3289             : */
    3290           0 : static NTSTATUS dcesrv_lsa_SetQuotasForAccount(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
    3291             :                        struct lsa_SetQuotasForAccount *r)
    3292             : {
    3293           0 :         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
    3294             : }
    3295             : 
    3296             : 
    3297             : /*
    3298             :   lsa_GetSystemAccessAccount
    3299             : */
    3300          26 : static NTSTATUS dcesrv_lsa_GetSystemAccessAccount(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
    3301             :                        struct lsa_GetSystemAccessAccount *r)
    3302             : {
    3303           0 :         struct dcesrv_handle *h;
    3304           0 :         struct lsa_account_state *astate;
    3305           0 :         int ret;
    3306           0 :         unsigned int i;
    3307           0 :         struct ldb_message **res;
    3308          26 :         const char * const attrs[] = { "privilege", NULL};
    3309           0 :         struct ldb_message_element *el;
    3310           0 :         const char *sidstr;
    3311             : 
    3312          26 :         *(r->out.access_mask) = 0x00000000;
    3313             : 
    3314          26 :         DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_ACCOUNT);
    3315             : 
    3316          26 :         astate = h->data;
    3317             : 
    3318          26 :         sidstr = ldap_encode_ndr_dom_sid(mem_ctx, astate->account_sid);
    3319          26 :         if (sidstr == NULL) {
    3320           0 :                 return NT_STATUS_NO_MEMORY;
    3321             :         }
    3322             : 
    3323          26 :         ret = gendb_search(astate->policy->pdb, mem_ctx, NULL, &res, attrs,
    3324             :                            "objectSid=%s", sidstr);
    3325          26 :         if (ret < 0) {
    3326           0 :                 return NT_STATUS_INTERNAL_DB_CORRUPTION;
    3327             :         }
    3328          26 :         if (ret != 1) {
    3329           0 :                 return NT_STATUS_OK;
    3330             :         }
    3331             : 
    3332          26 :         el = ldb_msg_find_element(res[0], "privilege");
    3333          26 :         if (el == NULL || el->num_values == 0) {
    3334           0 :                 return NT_STATUS_OK;
    3335             :         }
    3336             : 
    3337         162 :         for (i=0;i<el->num_values;i++) {
    3338         136 :                 uint32_t right_bit = sec_right_bit((const char *)el->values[i].data);
    3339         136 :                 if (right_bit == 0) {
    3340             :                         /* Perhaps an privilege, not a right */
    3341         104 :                         continue;
    3342             :                 }
    3343          32 :                 *(r->out.access_mask) |= right_bit;
    3344             :         }
    3345             : 
    3346          26 :         return NT_STATUS_OK;
    3347             : }
    3348             : 
    3349             : 
    3350             : /*
    3351             :   lsa_SetSystemAccessAccount
    3352             : */
    3353           0 : static NTSTATUS dcesrv_lsa_SetSystemAccessAccount(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
    3354             :                        struct lsa_SetSystemAccessAccount *r)
    3355             : {
    3356           0 :         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
    3357             : }
    3358             : /*
    3359             :   lsa_CreateSecret
    3360             : */
    3361        1420 : static NTSTATUS dcesrv_lsa_CreateSecret(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
    3362             :                                  struct lsa_CreateSecret *r)
    3363             : {
    3364           0 :         struct auth_session_info *session_info =
    3365        1420 :                 dcesrv_call_session_info(dce_call);
    3366           0 :         struct dcesrv_handle *policy_handle;
    3367           0 :         struct lsa_policy_state *policy_state;
    3368           0 :         struct lsa_secret_state *secret_state;
    3369           0 :         struct dcesrv_handle *handle;
    3370           0 :         struct ldb_message **msgs, *msg;
    3371        1420 :         const char *attrs[] = {
    3372             :                 NULL
    3373             :         };
    3374             : 
    3375           0 :         const char *name;
    3376             : 
    3377           0 :         int ret;
    3378             : 
    3379        1420 :         DCESRV_PULL_HANDLE(policy_handle, r->in.handle, LSA_HANDLE_POLICY);
    3380        1420 :         ZERO_STRUCTP(r->out.sec_handle);
    3381             : 
    3382        1420 :         switch (security_session_user_level(session_info, NULL))
    3383             :         {
    3384        1420 :         case SECURITY_SYSTEM:
    3385             :         case SECURITY_ADMINISTRATOR:
    3386        1420 :                 break;
    3387           0 :         default:
    3388             :                 /* Users and anonymous are not allowed create secrets */
    3389           0 :                 return NT_STATUS_ACCESS_DENIED;
    3390             :         }
    3391             : 
    3392        1420 :         policy_state = policy_handle->data;
    3393             : 
    3394        1420 :         if (!r->in.name.string) {
    3395           0 :                 return NT_STATUS_INVALID_PARAMETER;
    3396             :         }
    3397             : 
    3398        1420 :         secret_state = talloc(mem_ctx, struct lsa_secret_state);
    3399        1420 :         NT_STATUS_HAVE_NO_MEMORY(secret_state);
    3400        1420 :         secret_state->policy = policy_state;
    3401             : 
    3402        1420 :         msg = ldb_msg_new(mem_ctx);
    3403        1420 :         if (msg == NULL) {
    3404           0 :                 return NT_STATUS_NO_MEMORY;
    3405             :         }
    3406             : 
    3407        1420 :         if (strncmp("G$", r->in.name.string, 2) == 0) {
    3408           0 :                 const char *name2;
    3409             : 
    3410          20 :                 secret_state->global = true;
    3411             : 
    3412          20 :                 name = &r->in.name.string[2];
    3413          20 :                 if (strlen(name) == 0) {
    3414           0 :                         return NT_STATUS_INVALID_PARAMETER;
    3415             :                 }
    3416             : 
    3417          20 :                 name2 = talloc_asprintf(mem_ctx, "%s Secret",
    3418             :                                         ldb_binary_encode_string(mem_ctx, name));
    3419          20 :                 NT_STATUS_HAVE_NO_MEMORY(name2);
    3420             : 
    3421             :                 /*
    3422             :                  * We need to connect to the database as system, as this is
    3423             :                  * one of the rare RPC calls that must read the secrets
    3424             :                  * (and this is denied otherwise)
    3425             :                  *
    3426             :                  * We also save the current remote session details so they can
    3427             :                  * used by the audit logging module. This allows the audit
    3428             :                  * logging to report the remote users details, rather than the
    3429             :                  * system users details.
    3430             :                  */
    3431          20 :                 secret_state->sam_ldb =
    3432          20 :                         dcesrv_samdb_connect_as_system(secret_state, dce_call);
    3433          20 :                 NT_STATUS_HAVE_NO_MEMORY(secret_state->sam_ldb);
    3434             : 
    3435             :                 /* search for the secret record */
    3436          20 :                 ret = gendb_search(secret_state->sam_ldb,
    3437             :                                    mem_ctx, policy_state->system_dn, &msgs, attrs,
    3438             :                                    "(&(cn=%s)(objectclass=secret))",
    3439             :                                    name2);
    3440          20 :                 if (ret > 0) {
    3441           9 :                         return NT_STATUS_OBJECT_NAME_COLLISION;
    3442             :                 }
    3443             : 
    3444          11 :                 if (ret < 0) {
    3445           0 :                         DEBUG(0,("Failure searching for CN=%s: %s\n",
    3446             :                                  name2, ldb_errstring(secret_state->sam_ldb)));
    3447           0 :                         return NT_STATUS_INTERNAL_DB_CORRUPTION;
    3448             :                 }
    3449             : 
    3450          11 :                 msg->dn = ldb_dn_copy(mem_ctx, policy_state->system_dn);
    3451          11 :                 NT_STATUS_HAVE_NO_MEMORY(msg->dn);
    3452          11 :                 if (!ldb_dn_add_child_fmt(msg->dn, "cn=%s", name2)) {
    3453           0 :                         return NT_STATUS_NO_MEMORY;
    3454             :                 }
    3455             : 
    3456          11 :                 ret = ldb_msg_add_string(msg, "cn", name2);
    3457          11 :                 if (ret != LDB_SUCCESS) return NT_STATUS_NO_MEMORY;
    3458             :         } else {
    3459        1400 :                 secret_state->global = false;
    3460             : 
    3461        1400 :                 name = r->in.name.string;
    3462        1400 :                 if (strlen(name) == 0) {
    3463           0 :                         return NT_STATUS_INVALID_PARAMETER;
    3464             :                 }
    3465             : 
    3466        2800 :                 secret_state->sam_ldb = secrets_db_connect(secret_state,
    3467        1400 :                                         dce_call->conn->dce_ctx->lp_ctx);
    3468        1400 :                 NT_STATUS_HAVE_NO_MEMORY(secret_state->sam_ldb);
    3469             : 
    3470             :                 /* search for the secret record */
    3471        1400 :                 ret = gendb_search(secret_state->sam_ldb, mem_ctx,
    3472             :                                    ldb_dn_new(mem_ctx, secret_state->sam_ldb, "cn=LSA Secrets"),
    3473             :                                    &msgs, attrs,
    3474             :                                    "(&(cn=%s)(objectclass=secret))",
    3475             :                                    ldb_binary_encode_string(mem_ctx, name));
    3476        1400 :                 if (ret > 0) {
    3477          12 :                         return NT_STATUS_OBJECT_NAME_COLLISION;
    3478             :                 }
    3479             : 
    3480        1388 :                 if (ret < 0) {
    3481           0 :                         DEBUG(0,("Failure searching for CN=%s: %s\n",
    3482             :                                  name, ldb_errstring(secret_state->sam_ldb)));
    3483           0 :                         return NT_STATUS_INTERNAL_DB_CORRUPTION;
    3484             :                 }
    3485             : 
    3486        1388 :                 msg->dn = ldb_dn_new_fmt(mem_ctx, secret_state->sam_ldb,
    3487             :                                          "cn=%s,cn=LSA Secrets", name);
    3488        1388 :                 NT_STATUS_HAVE_NO_MEMORY(msg->dn);
    3489        1388 :                 ret = ldb_msg_add_string(msg, "cn", name);
    3490        1388 :                 if (ret != LDB_SUCCESS) return NT_STATUS_NO_MEMORY;
    3491             :         }
    3492             : 
    3493        1399 :         ret = ldb_msg_add_string(msg, "objectClass", "secret");
    3494        1399 :         if (ret != LDB_SUCCESS) return NT_STATUS_NO_MEMORY;
    3495             : 
    3496        1399 :         secret_state->secret_dn = talloc_reference(secret_state, msg->dn);
    3497        1399 :         NT_STATUS_HAVE_NO_MEMORY(secret_state->secret_dn);
    3498             : 
    3499             :         /* create the secret */
    3500        1399 :         ret = ldb_add(secret_state->sam_ldb, msg);
    3501        1399 :         if (ret != LDB_SUCCESS) {
    3502           0 :                 DEBUG(0,("Failed to create secret record %s: %s\n",
    3503             :                          ldb_dn_get_linearized(msg->dn),
    3504             :                          ldb_errstring(secret_state->sam_ldb)));
    3505           0 :                 return NT_STATUS_ACCESS_DENIED;
    3506             :         }
    3507             : 
    3508        1399 :         handle = dcesrv_handle_create(dce_call, LSA_HANDLE_SECRET);
    3509        1399 :         NT_STATUS_HAVE_NO_MEMORY(handle);
    3510             : 
    3511        1399 :         handle->data = talloc_steal(handle, secret_state);
    3512             : 
    3513        1399 :         secret_state->access_mask = r->in.access_mask;
    3514        1399 :         secret_state->policy = talloc_reference(secret_state, policy_state);
    3515        1399 :         NT_STATUS_HAVE_NO_MEMORY(secret_state->policy);
    3516             : 
    3517        1399 :         *r->out.sec_handle = handle->wire_handle;
    3518             : 
    3519        1399 :         return NT_STATUS_OK;
    3520             : }
    3521             : 
    3522             : 
    3523             : /*
    3524             :   lsa_OpenSecret
    3525             : */
    3526          46 : static NTSTATUS dcesrv_lsa_OpenSecret(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
    3527             :                                struct lsa_OpenSecret *r)
    3528             : {
    3529           0 :         struct auth_session_info *session_info =
    3530          46 :                 dcesrv_call_session_info(dce_call);
    3531           0 :         struct dcesrv_handle *policy_handle;
    3532           0 :         struct lsa_policy_state *policy_state;
    3533           0 :         struct lsa_secret_state *secret_state;
    3534           0 :         struct dcesrv_handle *handle;
    3535           0 :         struct ldb_message **msgs;
    3536          46 :         const char *attrs[] = {
    3537             :                 NULL
    3538             :         };
    3539           0 :         const char *name;
    3540           0 :         int ret;
    3541             : 
    3542          46 :         DCESRV_PULL_HANDLE(policy_handle, r->in.handle, LSA_HANDLE_POLICY);
    3543          46 :         ZERO_STRUCTP(r->out.sec_handle);
    3544          46 :         policy_state = policy_handle->data;
    3545             : 
    3546          46 :         if (!r->in.name.string) {
    3547           0 :                 return NT_STATUS_INVALID_PARAMETER;
    3548             :         }
    3549             : 
    3550          46 :         switch (security_session_user_level(session_info, NULL))
    3551             :         {
    3552          46 :         case SECURITY_SYSTEM:
    3553             :         case SECURITY_ADMINISTRATOR:
    3554          46 :                 break;
    3555           0 :         default:
    3556             :                 /* Users and anonymous are not allowed to access secrets */
    3557           0 :                 return NT_STATUS_ACCESS_DENIED;
    3558             :         }
    3559             : 
    3560          46 :         secret_state = talloc(mem_ctx, struct lsa_secret_state);
    3561          46 :         if (!secret_state) {
    3562           0 :                 return NT_STATUS_NO_MEMORY;
    3563             :         }
    3564          46 :         secret_state->policy = policy_state;
    3565             : 
    3566          46 :         if (strncmp("G$", r->in.name.string, 2) == 0) {
    3567          25 :                 name = &r->in.name.string[2];
    3568             :                 /*
    3569             :                  * We need to connect to the database as system, as this is
    3570             :                  * one of the rare RPC calls that must read the secrets
    3571             :                  * (and this is denied otherwise)
    3572             :                  *
    3573             :                  * We also save the current remote session details so they can
    3574             :                  * used by the audit logging module. This allows the audit
    3575             :                  * logging to report the remote users details, rather than the
    3576             :                  * system users details.
    3577             :                  */
    3578          25 :                 secret_state->sam_ldb =
    3579          25 :                         dcesrv_samdb_connect_as_system(secret_state, dce_call);
    3580          25 :                 NT_STATUS_HAVE_NO_MEMORY(secret_state->sam_ldb);
    3581          25 :                 secret_state->global = true;
    3582             : 
    3583          25 :                 if (strlen(name) < 1) {
    3584           0 :                         return NT_STATUS_INVALID_PARAMETER;
    3585             :                 }
    3586             : 
    3587             :                 /* search for the secret record */
    3588          25 :                 ret = gendb_search(secret_state->sam_ldb,
    3589             :                                    mem_ctx, policy_state->system_dn, &msgs, attrs,
    3590             :                                    "(&(cn=%s Secret)(objectclass=secret))",
    3591             :                                    ldb_binary_encode_string(mem_ctx, name));
    3592          25 :                 if (ret == 0) {
    3593           9 :                         return NT_STATUS_OBJECT_NAME_NOT_FOUND;
    3594             :                 }
    3595             : 
    3596          16 :                 if (ret != 1) {
    3597           0 :                         DEBUG(0,("Found %d records matching DN %s\n", ret,
    3598             :                                  ldb_dn_get_linearized(policy_state->system_dn)));
    3599           0 :                         return NT_STATUS_INTERNAL_DB_CORRUPTION;
    3600             :                 }
    3601             :         } else {
    3602          21 :                 secret_state->global = false;
    3603          42 :                 secret_state->sam_ldb = secrets_db_connect(secret_state,
    3604          21 :                                         dce_call->conn->dce_ctx->lp_ctx);
    3605          21 :                 NT_STATUS_HAVE_NO_MEMORY(secret_state->sam_ldb);
    3606             : 
    3607          21 :                 name = r->in.name.string;
    3608          21 :                 if (strlen(name) < 1) {
    3609           0 :                         return NT_STATUS_INVALID_PARAMETER;
    3610             :                 }
    3611             : 
    3612             :                 /* search for the secret record */
    3613          21 :                 ret = gendb_search(secret_state->sam_ldb, mem_ctx,
    3614             :                                    ldb_dn_new(mem_ctx, secret_state->sam_ldb, "cn=LSA Secrets"),
    3615             :                                    &msgs, attrs,
    3616             :                                    "(&(cn=%s)(objectclass=secret))",
    3617             :                                    ldb_binary_encode_string(mem_ctx, name));
    3618          21 :                 if (ret == 0) {
    3619           9 :                         return NT_STATUS_OBJECT_NAME_NOT_FOUND;
    3620             :                 }
    3621             : 
    3622          12 :                 if (ret != 1) {
    3623           0 :                         DEBUG(0,("Found %d records matching CN=%s\n",
    3624             :                                  ret, ldb_binary_encode_string(mem_ctx, name)));
    3625           0 :                         return NT_STATUS_INTERNAL_DB_CORRUPTION;
    3626             :                 }
    3627             :         }
    3628             : 
    3629          28 :         secret_state->secret_dn = talloc_reference(secret_state, msgs[0]->dn);
    3630             : 
    3631          28 :         handle = dcesrv_handle_create(dce_call, LSA_HANDLE_SECRET);
    3632          28 :         if (!handle) {
    3633           0 :                 return NT_STATUS_NO_MEMORY;
    3634             :         }
    3635             : 
    3636          28 :         handle->data = talloc_steal(handle, secret_state);
    3637             : 
    3638          28 :         secret_state->access_mask = r->in.access_mask;
    3639          28 :         secret_state->policy = talloc_reference(secret_state, policy_state);
    3640             : 
    3641          28 :         *r->out.sec_handle = handle->wire_handle;
    3642             : 
    3643          28 :         return NT_STATUS_OK;
    3644             : }
    3645             : 
    3646             : 
    3647             : /*
    3648             :   lsa_SetSecret
    3649             : */
    3650        1992 : static NTSTATUS dcesrv_lsa_SetSecret(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
    3651             :                               struct lsa_SetSecret *r)
    3652             : {
    3653             : 
    3654           0 :         struct dcesrv_handle *h;
    3655           0 :         struct lsa_secret_state *secret_state;
    3656           0 :         struct ldb_message *msg;
    3657           0 :         DATA_BLOB session_key;
    3658           0 :         DATA_BLOB crypt_secret, secret;
    3659           0 :         struct ldb_val val;
    3660           0 :         int ret;
    3661        1992 :         NTSTATUS status = NT_STATUS_OK;
    3662             : 
    3663        1992 :         struct timeval now = timeval_current();
    3664        1992 :         NTTIME nt_now = timeval_to_nttime(&now);
    3665             : 
    3666        1992 :         DCESRV_PULL_HANDLE(h, r->in.sec_handle, LSA_HANDLE_SECRET);
    3667             : 
    3668        1992 :         secret_state = h->data;
    3669             : 
    3670        1992 :         msg = ldb_msg_new(mem_ctx);
    3671        1992 :         if (msg == NULL) {
    3672           0 :                 return NT_STATUS_NO_MEMORY;
    3673             :         }
    3674             : 
    3675        1992 :         msg->dn = talloc_reference(mem_ctx, secret_state->secret_dn);
    3676        1992 :         if (!msg->dn) {
    3677           0 :                 return NT_STATUS_NO_MEMORY;
    3678             :         }
    3679        1992 :         status = dcesrv_transport_session_key(dce_call, &session_key);
    3680        1992 :         if (!NT_STATUS_IS_OK(status)) {
    3681           0 :                 return status;
    3682             :         }
    3683             : 
    3684        1992 :         if (r->in.old_val) {
    3685             :                 /* Decrypt */
    3686          18 :                 crypt_secret.data = r->in.old_val->data;
    3687          18 :                 crypt_secret.length = r->in.old_val->size;
    3688             : 
    3689          18 :                 status = sess_decrypt_blob(mem_ctx, &crypt_secret, &session_key, &secret);
    3690          18 :                 if (!NT_STATUS_IS_OK(status)) {
    3691           0 :                         return status;
    3692             :                 }
    3693             : 
    3694          18 :                 val.data = secret.data;
    3695          18 :                 val.length = secret.length;
    3696             : 
    3697             :                 /* set value */
    3698          18 :                 if (ldb_msg_add_value(msg, "priorValue", &val, NULL) != LDB_SUCCESS) {
    3699           0 :                         return NT_STATUS_NO_MEMORY;
    3700             :                 }
    3701             : 
    3702             :                 /* set old value mtime */
    3703          18 :                 if (samdb_msg_add_uint64(secret_state->sam_ldb,
    3704             :                                          mem_ctx, msg, "priorSetTime", nt_now) != LDB_SUCCESS) {
    3705           0 :                         return NT_STATUS_NO_MEMORY;
    3706             :                 }
    3707             : 
    3708             :         } else {
    3709             :                 /* If the old value is not set, then migrate the
    3710             :                  * current value to the old value */
    3711           0 :                 const struct ldb_val *old_val;
    3712           0 :                 NTTIME last_set_time;
    3713           0 :                 struct ldb_message **res;
    3714        1974 :                 const char *attrs[] = {
    3715             :                         "currentValue",
    3716             :                         "lastSetTime",
    3717             :                         NULL
    3718             :                 };
    3719             : 
    3720             :                 /* search for the secret record */
    3721        1974 :                 ret = gendb_search_dn(secret_state->sam_ldb,mem_ctx,
    3722             :                                       secret_state->secret_dn, &res, attrs);
    3723        1974 :                 if (ret == 0) {
    3724           0 :                         return NT_STATUS_OBJECT_NAME_NOT_FOUND;
    3725             :                 }
    3726             : 
    3727        1974 :                 if (ret != 1) {
    3728           0 :                         DEBUG(0,("Found %d records matching dn=%s\n", ret,
    3729             :                                  ldb_dn_get_linearized(secret_state->secret_dn)));
    3730           0 :                         return NT_STATUS_INTERNAL_DB_CORRUPTION;
    3731             :                 }
    3732             : 
    3733        1974 :                 old_val = ldb_msg_find_ldb_val(res[0], "currentValue");
    3734        1974 :                 last_set_time = ldb_msg_find_attr_as_uint64(res[0], "lastSetTime", 0);
    3735             : 
    3736        1974 :                 if (old_val) {
    3737             :                         /* set old value */
    3738         996 :                         if (ldb_msg_add_value(msg, "priorValue",
    3739             :                                               old_val, NULL) != LDB_SUCCESS) {
    3740           0 :                                 return NT_STATUS_NO_MEMORY;
    3741             :                         }
    3742             :                 } else {
    3743         978 :                         if (samdb_msg_add_delete(secret_state->sam_ldb,
    3744             :                                                  mem_ctx, msg, "priorValue") != LDB_SUCCESS) {
    3745           0 :                                 return NT_STATUS_NO_MEMORY;
    3746             :                         }
    3747             :                 }
    3748             : 
    3749             :                 /* set old value mtime */
    3750        1974 :                 if (ldb_msg_find_ldb_val(res[0], "lastSetTime")) {
    3751         996 :                         if (samdb_msg_add_uint64(secret_state->sam_ldb,
    3752             :                                                  mem_ctx, msg, "priorSetTime", last_set_time) != LDB_SUCCESS) {
    3753           0 :                                 return NT_STATUS_NO_MEMORY;
    3754             :                         }
    3755             :                 } else {
    3756         978 :                         if (samdb_msg_add_uint64(secret_state->sam_ldb,
    3757             :                                                  mem_ctx, msg, "priorSetTime", nt_now) != LDB_SUCCESS) {
    3758           0 :                                 return NT_STATUS_NO_MEMORY;
    3759             :                         }
    3760             :                 }
    3761             :         }
    3762             : 
    3763        1992 :         if (r->in.new_val) {
    3764             :                 /* Decrypt */
    3765        1974 :                 crypt_secret.data = r->in.new_val->data;
    3766        1974 :                 crypt_secret.length = r->in.new_val->size;
    3767             : 
    3768        1974 :                 status = sess_decrypt_blob(mem_ctx, &crypt_secret, &session_key, &secret);
    3769        1974 :                 if (!NT_STATUS_IS_OK(status)) {
    3770         978 :                         return status;
    3771             :                 }
    3772             : 
    3773         996 :                 val.data = secret.data;
    3774         996 :                 val.length = secret.length;
    3775             : 
    3776             :                 /* set value */
    3777         996 :                 if (ldb_msg_add_value(msg, "currentValue", &val, NULL) != LDB_SUCCESS) {
    3778           0 :                         return NT_STATUS_NO_MEMORY;
    3779             :                 }
    3780             : 
    3781             :                 /* set new value mtime */
    3782         996 :                 if (samdb_msg_add_uint64(secret_state->sam_ldb,
    3783             :                                          mem_ctx, msg, "lastSetTime", nt_now) != LDB_SUCCESS) {
    3784           0 :                         return NT_STATUS_NO_MEMORY;
    3785             :                 }
    3786             :         } else {
    3787             :                 /* NULL out the NEW value */
    3788          18 :                 if (samdb_msg_add_uint64(secret_state->sam_ldb,
    3789             :                                          mem_ctx, msg, "lastSetTime", nt_now) != LDB_SUCCESS) {
    3790           0 :                         return NT_STATUS_NO_MEMORY;
    3791             :                 }
    3792          18 :                 if (samdb_msg_add_delete(secret_state->sam_ldb,
    3793             :                                          mem_ctx, msg, "currentValue") != LDB_SUCCESS) {
    3794           0 :                         return NT_STATUS_NO_MEMORY;
    3795             :                 }
    3796             :         }
    3797             : 
    3798             :         /* modify the samdb record */
    3799        1014 :         ret = dsdb_replace(secret_state->sam_ldb, msg, 0);
    3800        1014 :         if (ret != LDB_SUCCESS) {
    3801           0 :                 return dsdb_ldb_err_to_ntstatus(ret);
    3802             :         }
    3803             : 
    3804        1014 :         return NT_STATUS_OK;
    3805             : }
    3806             : 
    3807             : 
    3808             : /*
    3809             :   lsa_QuerySecret
    3810             : */
    3811        1020 : static NTSTATUS dcesrv_lsa_QuerySecret(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
    3812             :                                 struct lsa_QuerySecret *r)
    3813             : {
    3814           0 :         struct auth_session_info *session_info =
    3815        1020 :                 dcesrv_call_session_info(dce_call);
    3816           0 :         struct dcesrv_handle *h;
    3817           0 :         struct lsa_secret_state *secret_state;
    3818           0 :         struct ldb_message *msg;
    3819           0 :         DATA_BLOB session_key;
    3820           0 :         DATA_BLOB crypt_secret, secret;
    3821           0 :         int ret;
    3822           0 :         struct ldb_message **res;
    3823        1020 :         const char *attrs[] = {
    3824             :                 "currentValue",
    3825             :                 "priorValue",
    3826             :                 "lastSetTime",
    3827             :                 "priorSetTime",
    3828             :                 NULL
    3829             :         };
    3830             : 
    3831           0 :         NTSTATUS nt_status;
    3832             : 
    3833        1020 :         DCESRV_PULL_HANDLE(h, r->in.sec_handle, LSA_HANDLE_SECRET);
    3834             : 
    3835             :         /* Ensure user is permitted to read this... */
    3836        1020 :         switch (security_session_user_level(session_info, NULL))
    3837             :         {
    3838        1020 :         case SECURITY_SYSTEM:
    3839             :         case SECURITY_ADMINISTRATOR:
    3840        1020 :                 break;
    3841           0 :         default:
    3842             :                 /* Users and anonymous are not allowed to read secrets */
    3843           0 :                 return NT_STATUS_ACCESS_DENIED;
    3844             :         }
    3845             : 
    3846        1020 :         secret_state = h->data;
    3847             : 
    3848             :         /* pull all the user attributes */
    3849        1020 :         ret = gendb_search_dn(secret_state->sam_ldb, mem_ctx,
    3850             :                               secret_state->secret_dn, &res, attrs);
    3851        1020 :         if (ret != 1) {
    3852           0 :                 return NT_STATUS_INTERNAL_DB_CORRUPTION;
    3853             :         }
    3854        1020 :         msg = res[0];
    3855             : 
    3856        1020 :         nt_status = dcesrv_transport_session_key(dce_call, &session_key);
    3857        1020 :         if (!NT_STATUS_IS_OK(nt_status)) {
    3858           0 :                 return nt_status;
    3859             :         }
    3860             : 
    3861        1020 :         if (r->in.old_val) {
    3862           0 :                 const struct ldb_val *prior_val;
    3863          36 :                 r->out.old_val = talloc_zero(mem_ctx, struct lsa_DATA_BUF_PTR);
    3864          36 :                 if (!r->out.old_val) {
    3865           0 :                         return NT_STATUS_NO_MEMORY;
    3866             :                 }
    3867          36 :                 prior_val = ldb_msg_find_ldb_val(msg, "priorValue");
    3868             : 
    3869          36 :                 if (prior_val && prior_val->length) {
    3870          36 :                         secret.data = prior_val->data;
    3871          36 :                         secret.length = prior_val->length;
    3872             : 
    3873             :                         /* Encrypt */
    3874          36 :                         crypt_secret = sess_encrypt_blob(mem_ctx, &secret, &session_key);
    3875          36 :                         if (!crypt_secret.length) {
    3876           0 :                                 return NT_STATUS_NO_MEMORY;
    3877             :                         }
    3878          36 :                         r->out.old_val->buf = talloc(mem_ctx, struct lsa_DATA_BUF);
    3879          36 :                         if (!r->out.old_val->buf) {
    3880           0 :                                 return NT_STATUS_NO_MEMORY;
    3881             :                         }
    3882          36 :                         r->out.old_val->buf->size = crypt_secret.length;
    3883          36 :                         r->out.old_val->buf->length = crypt_secret.length;
    3884          36 :                         r->out.old_val->buf->data = crypt_secret.data;
    3885             :                 }
    3886             :         }
    3887             : 
    3888        1020 :         if (r->in.old_mtime) {
    3889          36 :                 r->out.old_mtime = talloc(mem_ctx, NTTIME);
    3890          36 :                 if (!r->out.old_mtime) {
    3891           0 :                         return NT_STATUS_NO_MEMORY;
    3892             :                 }
    3893          36 :                 *r->out.old_mtime = ldb_msg_find_attr_as_uint64(msg, "priorSetTime", 0);
    3894             :         }
    3895             : 
    3896        1020 :         if (r->in.new_val) {
    3897           0 :                 const struct ldb_val *new_val;
    3898        1020 :                 r->out.new_val = talloc_zero(mem_ctx, struct lsa_DATA_BUF_PTR);
    3899        1020 :                 if (!r->out.new_val) {
    3900           0 :                         return NT_STATUS_NO_MEMORY;
    3901             :                 }
    3902             : 
    3903        1020 :                 new_val = ldb_msg_find_ldb_val(msg, "currentValue");
    3904             : 
    3905        1020 :                 if (new_val && new_val->length) {
    3906        1002 :                         secret.data = new_val->data;
    3907        1002 :                         secret.length = new_val->length;
    3908             : 
    3909             :                         /* Encrypt */
    3910        1002 :                         crypt_secret = sess_encrypt_blob(mem_ctx, &secret, &session_key);
    3911        1002 :                         if (!crypt_secret.length) {
    3912           0 :                                 return NT_STATUS_NO_MEMORY;
    3913             :                         }
    3914        1002 :                         r->out.new_val->buf = talloc(mem_ctx, struct lsa_DATA_BUF);
    3915        1002 :                         if (!r->out.new_val->buf) {
    3916           0 :                                 return NT_STATUS_NO_MEMORY;
    3917             :                         }
    3918        1002 :                         r->out.new_val->buf->length = crypt_secret.length;
    3919        1002 :                         r->out.new_val->buf->size = crypt_secret.length;
    3920        1002 :                         r->out.new_val->buf->data = crypt_secret.data;
    3921             :                 }
    3922             :         }
    3923             : 
    3924        1020 :         if (r->in.new_mtime) {
    3925        1014 :                 r->out.new_mtime = talloc(mem_ctx, NTTIME);
    3926        1014 :                 if (!r->out.new_mtime) {
    3927           0 :                         return NT_STATUS_NO_MEMORY;
    3928             :                 }
    3929        1014 :                 *r->out.new_mtime = ldb_msg_find_attr_as_uint64(msg, "lastSetTime", 0);
    3930             :         }
    3931             : 
    3932        1020 :         return NT_STATUS_OK;
    3933             : }
    3934             : 
    3935             : 
    3936             : /*
    3937             :   lsa_LookupPrivValue
    3938             : */
    3939          77 : static NTSTATUS dcesrv_lsa_LookupPrivValue(struct dcesrv_call_state *dce_call,
    3940             :                                     TALLOC_CTX *mem_ctx,
    3941             :                                     struct lsa_LookupPrivValue *r)
    3942             : {
    3943           0 :         struct dcesrv_handle *h;
    3944           0 :         int id;
    3945             : 
    3946          77 :         DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
    3947             : 
    3948          77 :         id = sec_privilege_id(r->in.name->string);
    3949          77 :         if (id == SEC_PRIV_INVALID) {
    3950           0 :                 return NT_STATUS_NO_SUCH_PRIVILEGE;
    3951             :         }
    3952             : 
    3953          77 :         r->out.luid->low = id;
    3954          77 :         r->out.luid->high = 0;
    3955             : 
    3956          77 :         return NT_STATUS_OK;
    3957             : }
    3958             : 
    3959             : 
    3960             : /*
    3961             :   lsa_LookupPrivName
    3962             : */
    3963          96 : static NTSTATUS dcesrv_lsa_LookupPrivName(struct dcesrv_call_state *dce_call,
    3964             :                                    TALLOC_CTX *mem_ctx,
    3965             :                                    struct lsa_LookupPrivName *r)
    3966             : {
    3967           0 :         struct dcesrv_handle *h;
    3968           0 :         struct lsa_StringLarge *name;
    3969           0 :         const char *privname;
    3970             : 
    3971          96 :         DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
    3972             : 
    3973          96 :         if (r->in.luid->high != 0) {
    3974           0 :                 return NT_STATUS_NO_SUCH_PRIVILEGE;
    3975             :         }
    3976             : 
    3977          96 :         privname = sec_privilege_name(r->in.luid->low);
    3978          96 :         if (privname == NULL) {
    3979           0 :                 return NT_STATUS_NO_SUCH_PRIVILEGE;
    3980             :         }
    3981             : 
    3982          96 :         name = talloc(mem_ctx, struct lsa_StringLarge);
    3983          96 :         if (name == NULL) {
    3984           0 :                 return NT_STATUS_NO_MEMORY;
    3985             :         }
    3986             : 
    3987          96 :         name->string = privname;
    3988             : 
    3989          96 :         *r->out.name = name;
    3990             : 
    3991          96 :         return NT_STATUS_OK;
    3992             : }
    3993             : 
    3994             : 
    3995             : /*
    3996             :   lsa_LookupPrivDisplayName
    3997             : */
    3998          75 : static NTSTATUS dcesrv_lsa_LookupPrivDisplayName(struct dcesrv_call_state *dce_call,
    3999             :                                           TALLOC_CTX *mem_ctx,
    4000             :                                           struct lsa_LookupPrivDisplayName *r)
    4001             : {
    4002           0 :         struct dcesrv_handle *h;
    4003          75 :         struct lsa_StringLarge *disp_name = NULL;
    4004           0 :         enum sec_privilege id;
    4005             : 
    4006          75 :         DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
    4007             : 
    4008          75 :         id = sec_privilege_id(r->in.name->string);
    4009          75 :         if (id == SEC_PRIV_INVALID) {
    4010           0 :                 return NT_STATUS_NO_SUCH_PRIVILEGE;
    4011             :         }
    4012             : 
    4013          75 :         disp_name = talloc(mem_ctx, struct lsa_StringLarge);
    4014          75 :         if (disp_name == NULL) {
    4015           0 :                 return NT_STATUS_NO_MEMORY;
    4016             :         }
    4017             : 
    4018          75 :         disp_name->string = sec_privilege_display_name(id, &r->in.language_id);
    4019          75 :         if (disp_name->string == NULL) {
    4020           0 :                 return NT_STATUS_INTERNAL_ERROR;
    4021             :         }
    4022             : 
    4023          75 :         *r->out.disp_name = disp_name;
    4024          75 :         *r->out.returned_language_id = 0;
    4025             : 
    4026          75 :         return NT_STATUS_OK;
    4027             : }
    4028             : 
    4029             : 
    4030             : /*
    4031             :   lsa_EnumAccountsWithUserRight
    4032             : */
    4033          75 : static NTSTATUS dcesrv_lsa_EnumAccountsWithUserRight(struct dcesrv_call_state *dce_call,
    4034             :                                               TALLOC_CTX *mem_ctx,
    4035             :                                               struct lsa_EnumAccountsWithUserRight *r)
    4036             : {
    4037           0 :         struct dcesrv_handle *h;
    4038           0 :         struct lsa_policy_state *state;
    4039           0 :         int ret, i;
    4040           0 :         struct ldb_message **res;
    4041          75 :         const char * const attrs[] = { "objectSid", NULL};
    4042           0 :         const char *privname;
    4043           0 :         bool ok;
    4044             : 
    4045          75 :         DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
    4046             : 
    4047          75 :         state = h->data;
    4048             : 
    4049          75 :         if (r->in.name == NULL) {
    4050           0 :                 return NT_STATUS_NO_SUCH_PRIVILEGE;
    4051             :         }
    4052             : 
    4053          75 :         privname = r->in.name->string;
    4054             : 
    4055          75 :         ok = dcesrc_lsa_valid_AccountRight(privname);
    4056          75 :         if (!ok) {
    4057           0 :                 return NT_STATUS_NO_SUCH_PRIVILEGE;
    4058             :         }
    4059             : 
    4060          75 :         ret = gendb_search(state->pdb, mem_ctx, NULL, &res, attrs,
    4061             :                            "privilege=%s", privname);
    4062          75 :         if (ret < 0) {
    4063           0 :                 return NT_STATUS_INTERNAL_DB_CORRUPTION;
    4064             :         }
    4065          75 :         if (ret == 0) {
    4066          12 :                 return NT_STATUS_NO_MORE_ENTRIES;
    4067             :         }
    4068             : 
    4069          63 :         r->out.sids->sids = talloc_array(r->out.sids, struct lsa_SidPtr, ret);
    4070          63 :         if (r->out.sids->sids == NULL) {
    4071           0 :                 return NT_STATUS_NO_MEMORY;
    4072             :         }
    4073         159 :         for (i=0;i<ret;i++) {
    4074         192 :                 r->out.sids->sids[i].sid = samdb_result_dom_sid(r->out.sids->sids,
    4075          96 :                                                                 res[i], "objectSid");
    4076          96 :                 NT_STATUS_HAVE_NO_MEMORY(r->out.sids->sids[i].sid);
    4077             :         }
    4078          63 :         r->out.sids->num_sids = ret;
    4079             : 
    4080          63 :         return NT_STATUS_OK;
    4081             : }
    4082             : 
    4083             : 
    4084             : /*
    4085             :   lsa_AddAccountRights
    4086             : */
    4087          10 : static NTSTATUS dcesrv_lsa_AddAccountRights(struct dcesrv_call_state *dce_call,
    4088             :                                      TALLOC_CTX *mem_ctx,
    4089             :                                      struct lsa_AddAccountRights *r)
    4090             : {
    4091           0 :         struct dcesrv_handle *h;
    4092           0 :         struct lsa_policy_state *state;
    4093             : 
    4094          10 :         DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
    4095             : 
    4096          10 :         state = h->data;
    4097             : 
    4098          10 :         return dcesrv_lsa_AddRemoveAccountRights(dce_call, mem_ctx, state,
    4099             :                                           LDB_FLAG_MOD_ADD,
    4100          10 :                                           r->in.sid, r->in.rights);
    4101             : }
    4102             : 
    4103             : 
    4104             : /*
    4105             :   lsa_RemoveAccountRights
    4106             : */
    4107           0 : static NTSTATUS dcesrv_lsa_RemoveAccountRights(struct dcesrv_call_state *dce_call,
    4108             :                                         TALLOC_CTX *mem_ctx,
    4109             :                                         struct lsa_RemoveAccountRights *r)
    4110             : {
    4111           0 :         struct dcesrv_handle *h;
    4112           0 :         struct lsa_policy_state *state;
    4113             : 
    4114           0 :         DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
    4115             : 
    4116           0 :         state = h->data;
    4117             : 
    4118           0 :         return dcesrv_lsa_AddRemoveAccountRights(dce_call, mem_ctx, state,
    4119             :                                           LDB_FLAG_MOD_DELETE,
    4120           0 :                                           r->in.sid, r->in.rights);
    4121             : }
    4122             : 
    4123             : 
    4124             : /*
    4125             :   lsa_StorePrivateData
    4126             : */
    4127           0 : static NTSTATUS dcesrv_lsa_StorePrivateData(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
    4128             :                        struct lsa_StorePrivateData *r)
    4129             : {
    4130           0 :         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
    4131             : }
    4132             : 
    4133             : 
    4134             : /*
    4135             :   lsa_RetrievePrivateData
    4136             : */
    4137           0 : static NTSTATUS dcesrv_lsa_RetrievePrivateData(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
    4138             :                        struct lsa_RetrievePrivateData *r)
    4139             : {
    4140           0 :         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
    4141             : }
    4142             : 
    4143             : 
    4144             : /*
    4145             :   lsa_GetUserName
    4146             : */
    4147         519 : static NTSTATUS dcesrv_lsa_GetUserName(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
    4148             :                                 struct lsa_GetUserName *r)
    4149             : {
    4150          48 :         enum dcerpc_transport_t transport =
    4151         519 :                 dcerpc_binding_get_transport(dce_call->conn->endpoint->ep_description);
    4152          48 :         struct auth_session_info *session_info =
    4153         519 :                 dcesrv_call_session_info(dce_call);
    4154         519 :         NTSTATUS status = NT_STATUS_OK;
    4155          48 :         const char *account_name;
    4156          48 :         const char *authority_name;
    4157          48 :         struct lsa_String *_account_name;
    4158         519 :         struct lsa_String *_authority_name = NULL;
    4159             : 
    4160         519 :         if (transport != NCACN_NP && transport != NCALRPC) {
    4161           3 :                 DCESRV_FAULT(DCERPC_FAULT_ACCESS_DENIED);
    4162             :         }
    4163             : 
    4164             :         /* this is what w2k3 does */
    4165         516 :         r->out.account_name = r->in.account_name;
    4166         516 :         r->out.authority_name = r->in.authority_name;
    4167             : 
    4168         516 :         if (r->in.account_name
    4169         516 :             && *r->in.account_name
    4170             :             /* && *(*r->in.account_name)->string */
    4171             :             ) {
    4172           0 :                 return NT_STATUS_INVALID_PARAMETER;
    4173             :         }
    4174             : 
    4175         516 :         if (r->in.authority_name
    4176         468 :             && *r->in.authority_name
    4177             :             /* && *(*r->in.authority_name)->string */
    4178             :             ) {
    4179           0 :                 return NT_STATUS_INVALID_PARAMETER;
    4180             :         }
    4181             : 
    4182         516 :         account_name = talloc_reference(mem_ctx, session_info->info->account_name);
    4183         516 :         authority_name = talloc_reference(mem_ctx, session_info->info->domain_name);
    4184             : 
    4185         516 :         _account_name = talloc(mem_ctx, struct lsa_String);
    4186         516 :         NT_STATUS_HAVE_NO_MEMORY(_account_name);
    4187         516 :         _account_name->string = account_name;
    4188             : 
    4189         516 :         if (r->in.authority_name) {
    4190         468 :                 _authority_name = talloc(mem_ctx, struct lsa_String);
    4191         468 :                 NT_STATUS_HAVE_NO_MEMORY(_authority_name);
    4192         468 :                 _authority_name->string = authority_name;
    4193             :         }
    4194             : 
    4195         516 :         *r->out.account_name = _account_name;
    4196         516 :         if (r->out.authority_name) {
    4197         468 :                 *r->out.authority_name = _authority_name;
    4198             :         }
    4199             : 
    4200         516 :         return status;
    4201             : }
    4202             : 
    4203             : /*
    4204             :   lsa_SetInfoPolicy2
    4205             : */
    4206           0 : static NTSTATUS dcesrv_lsa_SetInfoPolicy2(struct dcesrv_call_state *dce_call,
    4207             :                                    TALLOC_CTX *mem_ctx,
    4208             :                                    struct lsa_SetInfoPolicy2 *r)
    4209             : {
    4210             :         /* need to support these */
    4211           0 :         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
    4212             : }
    4213             : 
    4214          12 : static void kdc_get_policy(TALLOC_CTX *mem_ctx,
    4215             :                            struct loadparm_context *lp_ctx,
    4216             :                            struct smb_krb5_context *smb_krb5_context,
    4217             :                            struct lsa_DomainInfoKerberos *k)
    4218             : {
    4219           0 :         time_t svc_tkt_lifetime;
    4220           0 :         time_t usr_tkt_lifetime;
    4221           0 :         time_t renewal_lifetime;
    4222             : 
    4223             :         /* Our KDC always re-validates the client */
    4224          12 :         k->authentication_options = LSA_POLICY_KERBEROS_VALIDATE_CLIENT;
    4225             : 
    4226          12 :         lpcfg_default_kdc_policy(mem_ctx, lp_ctx, &svc_tkt_lifetime,
    4227             :                                  &usr_tkt_lifetime, &renewal_lifetime);
    4228             : 
    4229          12 :         unix_to_nt_time(&k->service_tkt_lifetime, svc_tkt_lifetime);
    4230          12 :         unix_to_nt_time(&k->user_tkt_lifetime, usr_tkt_lifetime);
    4231          12 :         unix_to_nt_time(&k->user_tkt_renewaltime, renewal_lifetime);
    4232             : #ifdef SAMBA4_USES_HEIMDAL /* MIT lacks krb5_get_max_time_skew.
    4233             :         However in the parent function we basically just did a full
    4234             :         krb5_context init with the only purpose of getting a global
    4235             :         config option (the max skew), it would probably make more sense
    4236             :         to have a lp_ or ldb global option as the samba default */
    4237           9 :         if (smb_krb5_context) {
    4238           9 :                 unix_to_nt_time(&k->clock_skew,
    4239             :                                 krb5_get_max_time_skew(smb_krb5_context->krb5_context));
    4240             :         }
    4241             : #endif
    4242          12 :         k->reserved = 0;
    4243          12 : }
    4244             : /*
    4245             :   lsa_QueryDomainInformationPolicy
    4246             : */
    4247          24 : static NTSTATUS dcesrv_lsa_QueryDomainInformationPolicy(struct dcesrv_call_state *dce_call,
    4248             :                                                  TALLOC_CTX *mem_ctx,
    4249             :                                                  struct lsa_QueryDomainInformationPolicy *r)
    4250             : {
    4251           0 :         union lsa_DomainInformationPolicy *info;
    4252             : 
    4253          24 :         info = talloc_zero(r->out.info, union lsa_DomainInformationPolicy);
    4254          24 :         if (!info) {
    4255           0 :                 return NT_STATUS_NO_MEMORY;
    4256             :         }
    4257             : 
    4258          24 :         switch (r->in.level) {
    4259          12 :         case LSA_DOMAIN_INFO_POLICY_EFS:
    4260          12 :                 talloc_free(info);
    4261          12 :                 *r->out.info = NULL;
    4262          12 :                 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
    4263          12 :         case LSA_DOMAIN_INFO_POLICY_KERBEROS:
    4264             :         {
    4265          12 :                 struct lsa_DomainInfoKerberos *k = &info->kerberos_info;
    4266           0 :                 struct smb_krb5_context *smb_krb5_context;
    4267          12 :                 int ret = smb_krb5_init_context(mem_ctx,
    4268          12 :                                                         dce_call->conn->dce_ctx->lp_ctx,
    4269             :                                                         &smb_krb5_context);
    4270          12 :                 if (ret != 0) {
    4271           0 :                         talloc_free(info);
    4272           0 :                         *r->out.info = NULL;
    4273           0 :                         return NT_STATUS_INTERNAL_ERROR;
    4274             :                 }
    4275          12 :                 kdc_get_policy(mem_ctx, dce_call->conn->dce_ctx->lp_ctx,
    4276             :                                smb_krb5_context,
    4277             :                                k);
    4278          12 :                 talloc_free(smb_krb5_context);
    4279          12 :                 *r->out.info = info;
    4280          12 :                 return NT_STATUS_OK;
    4281             :         }
    4282           0 :         default:
    4283           0 :                 talloc_free(info);
    4284           0 :                 *r->out.info = NULL;
    4285           0 :                 return NT_STATUS_INVALID_INFO_CLASS;
    4286             :         }
    4287             : }
    4288             : 
    4289             : /*
    4290             :   lsa_SetDomInfoPolicy
    4291             : */
    4292           0 : static NTSTATUS dcesrv_lsa_SetDomainInformationPolicy(struct dcesrv_call_state *dce_call,
    4293             :                                               TALLOC_CTX *mem_ctx,
    4294             :                                               struct lsa_SetDomainInformationPolicy *r)
    4295             : {
    4296           0 :         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
    4297             : }
    4298             : 
    4299             : /*
    4300             :   lsa_TestCall
    4301             : */
    4302           0 : static NTSTATUS dcesrv_lsa_TestCall(struct dcesrv_call_state *dce_call,
    4303             :                              TALLOC_CTX *mem_ctx,
    4304             :                              struct lsa_TestCall *r)
    4305             : {
    4306           0 :         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
    4307             : }
    4308             : 
    4309             : /*
    4310             :   lsa_CREDRWRITE
    4311             : */
    4312           0 : static NTSTATUS dcesrv_lsa_CREDRWRITE(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
    4313             :                        struct lsa_CREDRWRITE *r)
    4314             : {
    4315           0 :         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
    4316             : }
    4317             : 
    4318             : 
    4319             : /*
    4320             :   lsa_CREDRREAD
    4321             : */
    4322           0 : static NTSTATUS dcesrv_lsa_CREDRREAD(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
    4323             :                        struct lsa_CREDRREAD *r)
    4324             : {
    4325           0 :         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
    4326             : }
    4327             : 
    4328             : 
    4329             : /*
    4330             :   lsa_CREDRENUMERATE
    4331             : */
    4332           0 : static NTSTATUS dcesrv_lsa_CREDRENUMERATE(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
    4333             :                        struct lsa_CREDRENUMERATE *r)
    4334             : {
    4335           0 :         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
    4336             : }
    4337             : 
    4338             : 
    4339             : /*
    4340             :   lsa_CREDRWRITEDOMAINCREDENTIALS
    4341             : */
    4342           0 : static NTSTATUS dcesrv_lsa_CREDRWRITEDOMAINCREDENTIALS(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
    4343             :                        struct lsa_CREDRWRITEDOMAINCREDENTIALS *r)
    4344             : {
    4345           0 :         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
    4346             : }
    4347             : 
    4348             : 
    4349             : /*
    4350             :   lsa_CREDRREADDOMAINCREDENTIALS
    4351             : */
    4352           0 : static NTSTATUS dcesrv_lsa_CREDRREADDOMAINCREDENTIALS(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
    4353             :                        struct lsa_CREDRREADDOMAINCREDENTIALS *r)
    4354             : {
    4355           0 :         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
    4356             : }
    4357             : 
    4358             : 
    4359             : /*
    4360             :   lsa_CREDRDELETE
    4361             : */
    4362           0 : static NTSTATUS dcesrv_lsa_CREDRDELETE(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
    4363             :                        struct lsa_CREDRDELETE *r)
    4364             : {
    4365           0 :         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
    4366             : }
    4367             : 
    4368             : 
    4369             : /*
    4370             :   lsa_CREDRGETTARGETINFO
    4371             : */
    4372           0 : static NTSTATUS dcesrv_lsa_CREDRGETTARGETINFO(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
    4373             :                        struct lsa_CREDRGETTARGETINFO *r)
    4374             : {
    4375           0 :         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
    4376             : }
    4377             : 
    4378             : 
    4379             : /*
    4380             :   lsa_CREDRPROFILELOADED
    4381             : */
    4382           0 : static NTSTATUS dcesrv_lsa_CREDRPROFILELOADED(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
    4383             :                        struct lsa_CREDRPROFILELOADED *r)
    4384             : {
    4385           0 :         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
    4386             : }
    4387             : 
    4388             : 
    4389             : /*
    4390             :   lsa_CREDRGETSESSIONTYPES
    4391             : */
    4392           0 : static NTSTATUS dcesrv_lsa_CREDRGETSESSIONTYPES(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
    4393             :                        struct lsa_CREDRGETSESSIONTYPES *r)
    4394             : {
    4395           0 :         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
    4396             : }
    4397             : 
    4398             : 
    4399             : /*
    4400             :   lsa_LSARREGISTERAUDITEVENT
    4401             : */
    4402           0 : static NTSTATUS dcesrv_lsa_LSARREGISTERAUDITEVENT(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
    4403             :                        struct lsa_LSARREGISTERAUDITEVENT *r)
    4404             : {
    4405           0 :         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
    4406             : }
    4407             : 
    4408             : 
    4409             : /*
    4410             :   lsa_LSARGENAUDITEVENT
    4411             : */
    4412           0 : static NTSTATUS dcesrv_lsa_LSARGENAUDITEVENT(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
    4413             :                        struct lsa_LSARGENAUDITEVENT *r)
    4414             : {
    4415           0 :         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
    4416             : }
    4417             : 
    4418             : 
    4419             : /*
    4420             :   lsa_LSARUNREGISTERAUDITEVENT
    4421             : */
    4422           0 : static NTSTATUS dcesrv_lsa_LSARUNREGISTERAUDITEVENT(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
    4423             :                        struct lsa_LSARUNREGISTERAUDITEVENT *r)
    4424             : {
    4425           0 :         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
    4426             : }
    4427             : 
    4428             : 
    4429             : /*
    4430             :   lsa_lsaRQueryForestTrustInformation
    4431             : */
    4432         164 : static NTSTATUS dcesrv_lsa_lsaRQueryForestTrustInformation(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
    4433             :                        struct lsa_lsaRQueryForestTrustInformation *r)
    4434             : {
    4435         164 :         struct dcesrv_handle *h = NULL;
    4436         164 :         struct lsa_policy_state *p_state = NULL;
    4437         164 :         int forest_level = DS_DOMAIN_FUNCTION_2000;
    4438         164 :         const char * const trust_attrs[] = {
    4439             :                 "securityIdentifier",
    4440             :                 "flatName",
    4441             :                 "trustPartner",
    4442             :                 "trustAttributes",
    4443             :                 "trustDirection",
    4444             :                 "trustType",
    4445             :                 "msDS-TrustForestTrustInfo",
    4446             :                 NULL
    4447             :         };
    4448         164 :         struct ldb_message *trust_tdo_msg = NULL;
    4449         164 :         struct lsa_TrustDomainInfoInfoEx *trust_tdo = NULL;
    4450         164 :         struct ForestTrustInfo *trust_fti = NULL;
    4451         164 :         struct lsa_ForestTrustInformation *trust_lfti = NULL;
    4452           0 :         NTSTATUS status;
    4453             : 
    4454         164 :         DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
    4455             : 
    4456         164 :         p_state = h->data;
    4457             : 
    4458         164 :         if (strcmp(p_state->domain_dns, p_state->forest_dns)) {
    4459           0 :                 return NT_STATUS_INVALID_DOMAIN_STATE;
    4460             :         }
    4461             : 
    4462         164 :         forest_level = dsdb_forest_functional_level(p_state->sam_ldb);
    4463         164 :         if (forest_level < DS_DOMAIN_FUNCTION_2003) {
    4464           0 :                 return NT_STATUS_INVALID_DOMAIN_STATE;
    4465             :         }
    4466             : 
    4467         164 :         if (r->in.trusted_domain_name->string == NULL) {
    4468           0 :                 return NT_STATUS_NO_SUCH_DOMAIN;
    4469             :         }
    4470             : 
    4471         164 :         status = dsdb_trust_search_tdo(p_state->sam_ldb,
    4472         164 :                                        r->in.trusted_domain_name->string,
    4473         164 :                                        r->in.trusted_domain_name->string,
    4474             :                                        trust_attrs, mem_ctx, &trust_tdo_msg);
    4475         164 :         if (NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
    4476           0 :                 return NT_STATUS_NO_SUCH_DOMAIN;
    4477             :         }
    4478         164 :         if (!NT_STATUS_IS_OK(status)) {
    4479           0 :                 return status;
    4480             :         }
    4481             : 
    4482         164 :         status = dsdb_trust_parse_tdo_info(mem_ctx, trust_tdo_msg, &trust_tdo);
    4483         164 :         if (!NT_STATUS_IS_OK(status)) {
    4484           0 :                 return status;
    4485             :         }
    4486             : 
    4487         164 :         if (!(trust_tdo->trust_attributes & LSA_TRUST_ATTRIBUTE_FOREST_TRANSITIVE)) {
    4488           0 :                 return NT_STATUS_INVALID_PARAMETER;
    4489             :         }
    4490             : 
    4491         164 :         if (r->in.highest_record_type >= LSA_FOREST_TRUST_RECORD_TYPE_LAST) {
    4492           0 :                 return NT_STATUS_INVALID_PARAMETER;
    4493             :         }
    4494             : 
    4495         164 :         status = dsdb_trust_parse_forest_info(mem_ctx,
    4496             :                                               trust_tdo_msg,
    4497             :                                               &trust_fti);
    4498         164 :         if (!NT_STATUS_IS_OK(status)) {
    4499           8 :                 return status;
    4500             :         }
    4501             : 
    4502         156 :         status = dsdb_trust_forest_info_to_lsa(mem_ctx, trust_fti,
    4503             :                                                &trust_lfti);
    4504         156 :         if (!NT_STATUS_IS_OK(status)) {
    4505           0 :                 return status;
    4506             :         }
    4507             : 
    4508         156 :         *r->out.forest_trust_info = trust_lfti;
    4509         156 :         return NT_STATUS_OK;
    4510             : }
    4511             : 
    4512             : /*
    4513             :   lsa_lsaRSetForestTrustInformation
    4514             : */
    4515          87 : static NTSTATUS dcesrv_lsa_lsaRSetForestTrustInformation(struct dcesrv_call_state *dce_call,
    4516             :                                                          TALLOC_CTX *mem_ctx,
    4517             :                                                          struct lsa_lsaRSetForestTrustInformation *r)
    4518             : {
    4519           0 :         struct dcesrv_handle *h;
    4520           0 :         struct lsa_policy_state *p_state;
    4521          87 :         const char * const trust_attrs[] = {
    4522             :                 "securityIdentifier",
    4523             :                 "flatName",
    4524             :                 "trustPartner",
    4525             :                 "trustAttributes",
    4526             :                 "trustDirection",
    4527             :                 "trustType",
    4528             :                 "msDS-TrustForestTrustInfo",
    4529             :                 NULL
    4530             :         };
    4531          87 :         struct ldb_message *trust_tdo_msg = NULL;
    4532          87 :         struct lsa_TrustDomainInfoInfoEx *trust_tdo = NULL;
    4533          87 :         struct lsa_ForestTrustInformation *step1_lfti = NULL;
    4534          87 :         struct lsa_ForestTrustInformation *step2_lfti = NULL;
    4535          87 :         struct ForestTrustInfo *trust_fti = NULL;
    4536          87 :         struct ldb_result *trusts_res = NULL;
    4537           0 :         unsigned int i;
    4538          87 :         struct lsa_TrustDomainInfoInfoEx *xref_tdo = NULL;
    4539          87 :         struct lsa_ForestTrustInformation *xref_lfti = NULL;
    4540          87 :         struct lsa_ForestTrustCollisionInfo *c_info = NULL;
    4541          87 :         DATA_BLOB ft_blob = {};
    4542          87 :         struct ldb_message *msg = NULL;
    4543          87 :         struct server_id *server_ids = NULL;
    4544          87 :         uint32_t num_server_ids = 0;
    4545           0 :         NTSTATUS status;
    4546           0 :         enum ndr_err_code ndr_err;
    4547           0 :         int ret;
    4548          87 :         bool in_transaction = false;
    4549           0 :         struct imessaging_context *imsg_ctx =
    4550          87 :                 dcesrv_imessaging_context(dce_call->conn);
    4551             : 
    4552          87 :         DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
    4553             : 
    4554          87 :         p_state = h->data;
    4555             : 
    4556          87 :         if (strcmp(p_state->domain_dns, p_state->forest_dns)) {
    4557           0 :                 return NT_STATUS_INVALID_DOMAIN_STATE;
    4558             :         }
    4559             : 
    4560          87 :         if (r->in.check_only == 0) {
    4561          79 :                 ret = ldb_transaction_start(p_state->sam_ldb);
    4562          79 :                 if (ret != LDB_SUCCESS) {
    4563           0 :                         return NT_STATUS_INTERNAL_DB_CORRUPTION;
    4564             :                 }
    4565          79 :                 in_transaction = true;
    4566             :         }
    4567             : 
    4568             :         /*
    4569             :          * abort if we are not a PDC
    4570             :          *
    4571             :          * In future we should use a function like IsEffectiveRoleOwner()
    4572             :          */
    4573          87 :         if (!samdb_is_pdc(p_state->sam_ldb)) {
    4574           0 :                 status = NT_STATUS_INVALID_DOMAIN_ROLE;
    4575           0 :                 goto done;
    4576             :         }
    4577             : 
    4578          87 :         if (r->in.trusted_domain_name->string == NULL) {
    4579           0 :                 status = NT_STATUS_NO_SUCH_DOMAIN;
    4580           0 :                 goto done;
    4581             :         }
    4582             : 
    4583          87 :         status = dsdb_trust_search_tdo(p_state->sam_ldb,
    4584          87 :                                        r->in.trusted_domain_name->string,
    4585          87 :                                        r->in.trusted_domain_name->string,
    4586             :                                        trust_attrs, mem_ctx, &trust_tdo_msg);
    4587          87 :         if (NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
    4588           0 :                 status = NT_STATUS_NO_SUCH_DOMAIN;
    4589           0 :                 goto done;
    4590             :         }
    4591          87 :         if (!NT_STATUS_IS_OK(status)) {
    4592           0 :                 goto done;
    4593             :         }
    4594             : 
    4595          87 :         status = dsdb_trust_parse_tdo_info(mem_ctx, trust_tdo_msg, &trust_tdo);
    4596          87 :         if (!NT_STATUS_IS_OK(status)) {
    4597           0 :                 goto done;
    4598             :         }
    4599             : 
    4600          87 :         if (!(trust_tdo->trust_attributes & LSA_TRUST_ATTRIBUTE_FOREST_TRANSITIVE)) {
    4601           0 :                 status = NT_STATUS_INVALID_PARAMETER;
    4602           0 :                 goto done;
    4603             :         }
    4604             : 
    4605          87 :         if (r->in.highest_record_type >= LSA_FOREST_TRUST_RECORD_TYPE_LAST) {
    4606           0 :                 status = NT_STATUS_INVALID_PARAMETER;
    4607           0 :                 goto done;
    4608             :         }
    4609             : 
    4610             :         /*
    4611             :          * verify and normalize the given forest trust info.
    4612             :          *
    4613             :          * Step1: doesn't reorder yet, so step1_lfti might contain
    4614             :          * NULL entries. This means dsdb_trust_verify_forest_info()
    4615             :          * can generate collision entries with the callers index.
    4616             :          */
    4617          87 :         status = dsdb_trust_normalize_forest_info_step1(mem_ctx,
    4618          87 :                                                         r->in.forest_trust_info,
    4619             :                                                         &step1_lfti);
    4620          87 :         if (!NT_STATUS_IS_OK(status)) {
    4621           0 :                 goto done;
    4622             :         }
    4623             : 
    4624          87 :         c_info = talloc_zero(r->out.collision_info,
    4625             :                              struct lsa_ForestTrustCollisionInfo);
    4626          87 :         if (c_info == NULL) {
    4627           0 :                 status = NT_STATUS_NO_MEMORY;
    4628           0 :                 goto done;
    4629             :         }
    4630             : 
    4631             :         /*
    4632             :          * First check our own forest, then other domains/forests
    4633             :          */
    4634             : 
    4635          87 :         status = dsdb_trust_xref_tdo_info(mem_ctx, p_state->sam_ldb,
    4636             :                                           &xref_tdo);
    4637          87 :         if (!NT_STATUS_IS_OK(status)) {
    4638           0 :                 goto done;
    4639             :         }
    4640          87 :         status = dsdb_trust_xref_forest_info(mem_ctx, p_state->sam_ldb,
    4641             :                                              &xref_lfti);
    4642          87 :         if (!NT_STATUS_IS_OK(status)) {
    4643           0 :                 goto done;
    4644             :         }
    4645             : 
    4646             :         /*
    4647             :          * The documentation proposed to generate
    4648             :          * LSA_FOREST_TRUST_COLLISION_XREF collisions.
    4649             :          * But Windows always uses LSA_FOREST_TRUST_COLLISION_TDO.
    4650             :          */
    4651          87 :         status = dsdb_trust_verify_forest_info(xref_tdo, xref_lfti,
    4652             :                                                LSA_FOREST_TRUST_COLLISION_TDO,
    4653             :                                                c_info, step1_lfti);
    4654          87 :         if (!NT_STATUS_IS_OK(status)) {
    4655           0 :                 goto done;
    4656             :         }
    4657             : 
    4658             :         /* fetch all other trusted domain objects */
    4659          87 :         status = dsdb_trust_search_tdos(p_state->sam_ldb,
    4660          87 :                                         trust_tdo->domain_name.string,
    4661             :                                         trust_attrs,
    4662             :                                         mem_ctx, &trusts_res);
    4663          87 :         if (!NT_STATUS_IS_OK(status)) {
    4664           0 :                 goto done;
    4665             :         }
    4666             : 
    4667             :         /*
    4668             :          * now check against the other domains.
    4669             :          * and generate LSA_FOREST_TRUST_COLLISION_TDO collisions.
    4670             :          */
    4671         121 :         for (i = 0; i < trusts_res->count; i++) {
    4672          34 :                 struct lsa_TrustDomainInfoInfoEx *tdo = NULL;
    4673          34 :                 struct ForestTrustInfo *fti = NULL;
    4674          34 :                 struct lsa_ForestTrustInformation *lfti = NULL;
    4675             : 
    4676          34 :                 status = dsdb_trust_parse_tdo_info(mem_ctx,
    4677          34 :                                                    trusts_res->msgs[i],
    4678             :                                                    &tdo);
    4679          34 :                 if (!NT_STATUS_IS_OK(status)) {
    4680           0 :                         goto done;
    4681             :                 }
    4682             : 
    4683          34 :                 status = dsdb_trust_parse_forest_info(tdo,
    4684          34 :                                                       trusts_res->msgs[i],
    4685             :                                                       &fti);
    4686          34 :                 if (NT_STATUS_EQUAL(status, NT_STATUS_NOT_FOUND)) {
    4687          34 :                         continue;
    4688             :                 }
    4689           0 :                 if (!NT_STATUS_IS_OK(status)) {
    4690           0 :                         goto done;
    4691             :                 }
    4692             : 
    4693           0 :                 status = dsdb_trust_forest_info_to_lsa(tdo, fti, &lfti);
    4694           0 :                 if (!NT_STATUS_IS_OK(status)) {
    4695           0 :                         goto done;
    4696             :                 }
    4697             : 
    4698           0 :                 status = dsdb_trust_verify_forest_info(tdo, lfti,
    4699             :                                                 LSA_FOREST_TRUST_COLLISION_TDO,
    4700             :                                                 c_info, step1_lfti);
    4701           0 :                 if (!NT_STATUS_IS_OK(status)) {
    4702           0 :                         goto done;
    4703             :                 }
    4704             : 
    4705           0 :                 TALLOC_FREE(tdo);
    4706             :         }
    4707             : 
    4708          87 :         if (r->in.check_only != 0) {
    4709           8 :                 status = NT_STATUS_OK;
    4710           8 :                 goto done;
    4711             :         }
    4712             : 
    4713             :         /*
    4714             :          * not just a check, write info back
    4715             :          */
    4716             : 
    4717             :         /*
    4718             :          * normalize the given forest trust info.
    4719             :          *
    4720             :          * Step2: adds TOP_LEVEL_NAME[_EX] in reverse order,
    4721             :          * followed by DOMAIN_INFO in reverse order. It also removes
    4722             :          * possible NULL entries from Step1.
    4723             :          */
    4724          79 :         status = dsdb_trust_normalize_forest_info_step2(mem_ctx, step1_lfti,
    4725             :                                                         &step2_lfti);
    4726          79 :         if (!NT_STATUS_IS_OK(status)) {
    4727           0 :                 goto done;
    4728             :         }
    4729             : 
    4730          79 :         status = dsdb_trust_forest_info_from_lsa(mem_ctx, step2_lfti,
    4731             :                                                  &trust_fti);
    4732          79 :         if (!NT_STATUS_IS_OK(status)) {
    4733           0 :                 goto done;
    4734             :         }
    4735             : 
    4736          79 :         ndr_err = ndr_push_struct_blob(&ft_blob, mem_ctx, trust_fti,
    4737             :                                        (ndr_push_flags_fn_t)ndr_push_ForestTrustInfo);
    4738          79 :         if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
    4739           0 :                 status = NT_STATUS_INVALID_PARAMETER;
    4740           0 :                 goto done;
    4741             :         }
    4742             : 
    4743          79 :         msg = ldb_msg_new(mem_ctx);
    4744          79 :         if (msg == NULL) {
    4745           0 :                 status = NT_STATUS_NO_MEMORY;
    4746           0 :                 goto done;
    4747             :         }
    4748             : 
    4749          79 :         msg->dn = ldb_dn_copy(mem_ctx, trust_tdo_msg->dn);
    4750          79 :         if (!msg->dn) {
    4751           0 :                 status = NT_STATUS_NO_MEMORY;
    4752           0 :                 goto done;
    4753             :         }
    4754             : 
    4755          79 :         ret = ldb_msg_append_value(msg, "msDS-TrustForestTrustInfo",
    4756             :                                    &ft_blob, LDB_FLAG_MOD_REPLACE);
    4757          79 :         if (ret != LDB_SUCCESS) {
    4758           0 :                 status = NT_STATUS_NO_MEMORY;
    4759           0 :                 goto done;
    4760             :         }
    4761             : 
    4762          79 :         ret = ldb_modify(p_state->sam_ldb, msg);
    4763          79 :         if (ret != LDB_SUCCESS) {
    4764           0 :                 status = dsdb_ldb_err_to_ntstatus(ret);
    4765             : 
    4766           0 :                 DEBUG(0, ("Failed to store Forest Trust Info: %s\n",
    4767             :                           ldb_errstring(p_state->sam_ldb)));
    4768             : 
    4769           0 :                 goto done;
    4770             :         }
    4771             : 
    4772             :         /* ok, all fine, commit transaction and return */
    4773          79 :         in_transaction = false;
    4774          79 :         ret = ldb_transaction_commit(p_state->sam_ldb);
    4775          79 :         if (ret != LDB_SUCCESS) {
    4776           0 :                 status = NT_STATUS_INTERNAL_DB_CORRUPTION;
    4777           0 :                 goto done;
    4778             :         }
    4779             : 
    4780             :         /*
    4781             :          * Notify winbindd that we have a acquired forest trust info
    4782             :          */
    4783          79 :         status = irpc_servers_byname(imsg_ctx,
    4784             :                                      mem_ctx,
    4785             :                                      "winbind_server",
    4786             :                                      &num_server_ids,
    4787             :                                      &server_ids);
    4788          79 :         if (!NT_STATUS_IS_OK(status)) {
    4789           0 :                 DBG_ERR("irpc_servers_byname failed\n");
    4790           0 :                 goto done;
    4791             :         }
    4792             : 
    4793          79 :         imessaging_send(imsg_ctx,
    4794             :                         server_ids[0],
    4795             :                         MSG_WINBIND_RELOAD_TRUSTED_DOMAINS,
    4796             :                         NULL);
    4797             : 
    4798          79 :         status = NT_STATUS_OK;
    4799             : 
    4800          87 : done:
    4801          87 :         if (NT_STATUS_IS_OK(status) && c_info->count != 0) {
    4802          20 :                 *r->out.collision_info = c_info;
    4803             :         }
    4804             : 
    4805          87 :         if (in_transaction) {
    4806           0 :                 ldb_transaction_cancel(p_state->sam_ldb);
    4807             :         }
    4808             : 
    4809          87 :         return status;
    4810             : }
    4811             : 
    4812             : /*
    4813             :   lsa_CREDRRENAME
    4814             : */
    4815           0 : static NTSTATUS dcesrv_lsa_CREDRRENAME(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
    4816             :                        struct lsa_CREDRRENAME *r)
    4817             : {
    4818           0 :         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
    4819             : }
    4820             : 
    4821             : 
    4822             : 
    4823             : /*
    4824             :   lsa_LSAROPENPOLICYSCE
    4825             : */
    4826           0 : static NTSTATUS dcesrv_lsa_LSAROPENPOLICYSCE(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
    4827             :                        struct lsa_LSAROPENPOLICYSCE *r)
    4828             : {
    4829           0 :         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
    4830             : }
    4831             : 
    4832             : 
    4833             : /*
    4834             :   lsa_LSARADTREGISTERSECURITYEVENTSOURCE
    4835             : */
    4836           0 : static NTSTATUS dcesrv_lsa_LSARADTREGISTERSECURITYEVENTSOURCE(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
    4837             :                        struct lsa_LSARADTREGISTERSECURITYEVENTSOURCE *r)
    4838             : {
    4839           0 :         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
    4840             : }
    4841             : 
    4842             : 
    4843             : /*
    4844             :   lsa_LSARADTUNREGISTERSECURITYEVENTSOURCE
    4845             : */
    4846           0 : static NTSTATUS dcesrv_lsa_LSARADTUNREGISTERSECURITYEVENTSOURCE(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
    4847             :                        struct lsa_LSARADTUNREGISTERSECURITYEVENTSOURCE *r)
    4848             : {
    4849           0 :         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
    4850             : }
    4851             : 
    4852             : 
    4853             : /*
    4854             :   lsa_LSARADTREPORTSECURITYEVENT
    4855             : */
    4856           0 : static NTSTATUS dcesrv_lsa_LSARADTREPORTSECURITYEVENT(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
    4857             :                        struct lsa_LSARADTREPORTSECURITYEVENT *r)
    4858             : {
    4859           0 :         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
    4860             : }
    4861             : 
    4862             : /*
    4863             :   lsa_Opnum82NotUsedOnWire
    4864             : */
    4865           0 : static void dcesrv_lsa_Opnum82NotUsedOnWire(struct dcesrv_call_state *dce_call,
    4866             :                                             TALLOC_CTX *mem_ctx,
    4867             :                                             struct lsa_Opnum82NotUsedOnWire *r)
    4868             : {
    4869           0 :         DCESRV_FAULT_VOID(DCERPC_FAULT_OP_RNG_ERROR);
    4870             : }
    4871             : 
    4872             : /*
    4873             :   lsa_Opnum83NotUsedOnWire
    4874             : */
    4875           0 : static void dcesrv_lsa_Opnum83NotUsedOnWire(struct dcesrv_call_state *dce_call,
    4876             :                                             TALLOC_CTX *mem_ctx,
    4877             :                                             struct lsa_Opnum83NotUsedOnWire *r)
    4878             : {
    4879           0 :         DCESRV_FAULT_VOID(DCERPC_FAULT_OP_RNG_ERROR);
    4880             : }
    4881             : 
    4882             : /*
    4883             :   lsa_Opnum84NotUsedOnWire
    4884             : */
    4885           0 : static void dcesrv_lsa_Opnum84NotUsedOnWire(struct dcesrv_call_state *dce_call,
    4886             :                                             TALLOC_CTX *mem_ctx,
    4887             :                                             struct lsa_Opnum84NotUsedOnWire *r)
    4888             : {
    4889           0 :         DCESRV_FAULT_VOID(DCERPC_FAULT_OP_RNG_ERROR);
    4890             : }
    4891             : 
    4892             : /*
    4893             :   lsa_Opnum85NotUsedOnWire
    4894             : */
    4895           0 : static void dcesrv_lsa_Opnum85NotUsedOnWire(struct dcesrv_call_state *dce_call,
    4896             :                                             TALLOC_CTX *mem_ctx,
    4897             :                                             struct lsa_Opnum85NotUsedOnWire *r)
    4898             : {
    4899           0 :         DCESRV_FAULT_VOID(DCERPC_FAULT_OP_RNG_ERROR);
    4900             : }
    4901             : 
    4902             : /*
    4903             :   lsa_Opnum86NotUsedOnWire
    4904             : */
    4905           0 : static void dcesrv_lsa_Opnum86NotUsedOnWire(struct dcesrv_call_state *dce_call,
    4906             :                                             TALLOC_CTX *mem_ctx,
    4907             :                                             struct lsa_Opnum86NotUsedOnWire *r)
    4908             : {
    4909           0 :         DCESRV_FAULT_VOID(DCERPC_FAULT_OP_RNG_ERROR);
    4910             : }
    4911             : 
    4912             : /*
    4913             :   lsa_Opnum87NotUsedOnWire
    4914             : */
    4915           0 : static void dcesrv_lsa_Opnum87NotUsedOnWire(struct dcesrv_call_state *dce_call,
    4916             :                                             TALLOC_CTX *mem_ctx,
    4917             :                                             struct lsa_Opnum87NotUsedOnWire *r)
    4918             : {
    4919           0 :         DCESRV_FAULT_VOID(DCERPC_FAULT_OP_RNG_ERROR);
    4920             : }
    4921             : 
    4922             : /*
    4923             :   lsa_Opnum88NotUsedOnWire
    4924             : */
    4925           0 : static void dcesrv_lsa_Opnum88NotUsedOnWire(struct dcesrv_call_state *dce_call,
    4926             :                                             TALLOC_CTX *mem_ctx,
    4927             :                                             struct lsa_Opnum88NotUsedOnWire *r)
    4928             : {
    4929           0 :         DCESRV_FAULT_VOID(DCERPC_FAULT_OP_RNG_ERROR);
    4930             : }
    4931             : 
    4932             : /*
    4933             :   lsa_Opnum89NotUsedOnWire
    4934             : */
    4935           0 : static void dcesrv_lsa_Opnum89NotUsedOnWire(struct dcesrv_call_state *dce_call,
    4936             :                                             TALLOC_CTX *mem_ctx,
    4937             :                                             struct lsa_Opnum89NotUsedOnWire *r)
    4938             : {
    4939           0 :         DCESRV_FAULT_VOID(DCERPC_FAULT_OP_RNG_ERROR);
    4940             : }
    4941             : 
    4942             : /*
    4943             :   lsa_Opnum90NotUsedOnWire
    4944             : */
    4945           0 : static void dcesrv_lsa_Opnum90NotUsedOnWire(struct dcesrv_call_state *dce_call,
    4946             :                                             TALLOC_CTX *mem_ctx,
    4947             :                                             struct lsa_Opnum90NotUsedOnWire *r)
    4948             : {
    4949           0 :         DCESRV_FAULT_VOID(DCERPC_FAULT_OP_RNG_ERROR);
    4950             : }
    4951             : 
    4952             : /*
    4953             :   lsa_Opnum91NotUsedOnWire
    4954             : */
    4955           0 : static void dcesrv_lsa_Opnum91NotUsedOnWire(struct dcesrv_call_state *dce_call,
    4956             :                                             TALLOC_CTX *mem_ctx,
    4957             :                                             struct lsa_Opnum91NotUsedOnWire *r)
    4958             : {
    4959           0 :         DCESRV_FAULT_VOID(DCERPC_FAULT_OP_RNG_ERROR);
    4960             : }
    4961             : 
    4962             : /*
    4963             :   lsa_Opnum92NotUsedOnWire
    4964             : */
    4965           0 : static void dcesrv_lsa_Opnum92NotUsedOnWire(struct dcesrv_call_state *dce_call,
    4966             :                                             TALLOC_CTX *mem_ctx,
    4967             :                                             struct lsa_Opnum92NotUsedOnWire *r)
    4968             : {
    4969           0 :         DCESRV_FAULT_VOID(DCERPC_FAULT_OP_RNG_ERROR);
    4970             : }
    4971             : 
    4972             : /*
    4973             :   lsa_Opnum93NotUsedOnWire
    4974             : */
    4975           0 : static void dcesrv_lsa_Opnum93NotUsedOnWire(struct dcesrv_call_state *dce_call,
    4976             :                                             TALLOC_CTX *mem_ctx,
    4977             :                                             struct lsa_Opnum93NotUsedOnWire *r)
    4978             : {
    4979           0 :         DCESRV_FAULT_VOID(DCERPC_FAULT_OP_RNG_ERROR);
    4980             : }
    4981             : 
    4982             : /*
    4983             :   lsa_Opnum94NotUsedOnWire
    4984             : */
    4985           0 : static void dcesrv_lsa_Opnum94NotUsedOnWire(struct dcesrv_call_state *dce_call,
    4986             :                                             TALLOC_CTX *mem_ctx,
    4987             :                                             struct lsa_Opnum94NotUsedOnWire *r)
    4988             : {
    4989           0 :         DCESRV_FAULT_VOID(DCERPC_FAULT_OP_RNG_ERROR);
    4990             : }
    4991             : 
    4992             : /*
    4993             :   lsa_Opnum95NotUsedOnWire
    4994             : */
    4995           0 : static void dcesrv_lsa_Opnum95NotUsedOnWire(struct dcesrv_call_state *dce_call,
    4996             :                                             TALLOC_CTX *mem_ctx,
    4997             :                                             struct lsa_Opnum95NotUsedOnWire *r)
    4998             : {
    4999           0 :         DCESRV_FAULT_VOID(DCERPC_FAULT_OP_RNG_ERROR);
    5000             : }
    5001             : 
    5002             : /*
    5003             :   lsa_Opnum96NotUsedOnWire
    5004             : */
    5005           0 : static void dcesrv_lsa_Opnum96NotUsedOnWire(struct dcesrv_call_state *dce_call,
    5006             :                                             TALLOC_CTX *mem_ctx,
    5007             :                                             struct lsa_Opnum96NotUsedOnWire *r)
    5008             : {
    5009           0 :         DCESRV_FAULT_VOID(DCERPC_FAULT_OP_RNG_ERROR);
    5010             : }
    5011             : 
    5012             : /*
    5013             :   lsa_Opnum97NotUsedOnWire
    5014             : */
    5015           0 : static void dcesrv_lsa_Opnum97NotUsedOnWire(struct dcesrv_call_state *dce_call,
    5016             :                                             TALLOC_CTX *mem_ctx,
    5017             :                                             struct lsa_Opnum97NotUsedOnWire *r)
    5018             : {
    5019           0 :         DCESRV_FAULT_VOID(DCERPC_FAULT_OP_RNG_ERROR);
    5020             : }
    5021             : 
    5022             : /*
    5023             :   lsa_Opnum98NotUsedOnWire
    5024             : */
    5025           0 : static void dcesrv_lsa_Opnum98NotUsedOnWire(struct dcesrv_call_state *dce_call,
    5026             :                                             TALLOC_CTX *mem_ctx,
    5027             :                                             struct lsa_Opnum98NotUsedOnWire *r)
    5028             : {
    5029           0 :         DCESRV_FAULT_VOID(DCERPC_FAULT_OP_RNG_ERROR);
    5030             : }
    5031             : 
    5032             : /*
    5033             :   lsa_Opnum99NotUsedOnWire
    5034             : */
    5035           0 : static void dcesrv_lsa_Opnum99NotUsedOnWire(struct dcesrv_call_state *dce_call,
    5036             :                                             TALLOC_CTX *mem_ctx,
    5037             :                                             struct lsa_Opnum99NotUsedOnWire *r)
    5038             : {
    5039           0 :         DCESRV_FAULT_VOID(DCERPC_FAULT_OP_RNG_ERROR);
    5040             : }
    5041             : 
    5042             : /*
    5043             :   lsa_Opnum100NotUsedOnWire
    5044             : */
    5045           0 : static void dcesrv_lsa_Opnum100NotUsedOnWire(struct dcesrv_call_state *dce_call,
    5046             :                                             TALLOC_CTX *mem_ctx,
    5047             :                                             struct lsa_Opnum100NotUsedOnWire *r)
    5048             : {
    5049           0 :         DCESRV_FAULT_VOID(DCERPC_FAULT_OP_RNG_ERROR);
    5050             : }
    5051             : 
    5052             : /*
    5053             :   lsa_Opnum101NotUsedOnWire
    5054             : */
    5055           0 : static void dcesrv_lsa_Opnum101NotUsedOnWire(struct dcesrv_call_state *dce_call,
    5056             :                                             TALLOC_CTX *mem_ctx,
    5057             :                                             struct lsa_Opnum101NotUsedOnWire *r)
    5058             : {
    5059           0 :         DCESRV_FAULT_VOID(DCERPC_FAULT_OP_RNG_ERROR);
    5060             : }
    5061             : 
    5062             : /*
    5063             :   lsa_Opnum102NotUsedOnWire
    5064             : */
    5065           0 : static void dcesrv_lsa_Opnum102NotUsedOnWire(struct dcesrv_call_state *dce_call,
    5066             :                                             TALLOC_CTX *mem_ctx,
    5067             :                                             struct lsa_Opnum102NotUsedOnWire *r)
    5068             : {
    5069           0 :         DCESRV_FAULT_VOID(DCERPC_FAULT_OP_RNG_ERROR);
    5070             : }
    5071             : 
    5072             : /*
    5073             :   lsa_Opnum103NotUsedOnWire
    5074             : */
    5075           0 : static void dcesrv_lsa_Opnum103NotUsedOnWire(struct dcesrv_call_state *dce_call,
    5076             :                                             TALLOC_CTX *mem_ctx,
    5077             :                                             struct lsa_Opnum103NotUsedOnWire *r)
    5078             : {
    5079           0 :         DCESRV_FAULT_VOID(DCERPC_FAULT_OP_RNG_ERROR);
    5080             : }
    5081             : 
    5082             : /*
    5083             :   lsa_Opnum104NotUsedOnWire
    5084             : */
    5085           0 : static void dcesrv_lsa_Opnum104NotUsedOnWire(struct dcesrv_call_state *dce_call,
    5086             :                                             TALLOC_CTX *mem_ctx,
    5087             :                                             struct lsa_Opnum104NotUsedOnWire *r)
    5088             : {
    5089           0 :         DCESRV_FAULT_VOID(DCERPC_FAULT_OP_RNG_ERROR);
    5090             : }
    5091             : 
    5092             : /*
    5093             :   lsa_Opnum105NotUsedOnWire
    5094             : */
    5095           0 : static void dcesrv_lsa_Opnum105NotUsedOnWire(struct dcesrv_call_state *dce_call,
    5096             :                                             TALLOC_CTX *mem_ctx,
    5097             :                                             struct lsa_Opnum105NotUsedOnWire *r)
    5098             : {
    5099           0 :         DCESRV_FAULT_VOID(DCERPC_FAULT_OP_RNG_ERROR);
    5100             : }
    5101             : 
    5102             : /*
    5103             :   lsa_Opnum106NotUsedOnWire
    5104             : */
    5105           0 : static void dcesrv_lsa_Opnum106NotUsedOnWire(struct dcesrv_call_state *dce_call,
    5106             :                                             TALLOC_CTX *mem_ctx,
    5107             :                                             struct lsa_Opnum106NotUsedOnWire *r)
    5108             : {
    5109           0 :         DCESRV_FAULT_VOID(DCERPC_FAULT_OP_RNG_ERROR);
    5110             : }
    5111             : 
    5112             : /*
    5113             :   lsa_Opnum107NotUsedOnWire
    5114             : */
    5115           0 : static void dcesrv_lsa_Opnum107NotUsedOnWire(struct dcesrv_call_state *dce_call,
    5116             :                                             TALLOC_CTX *mem_ctx,
    5117             :                                             struct lsa_Opnum107NotUsedOnWire *r)
    5118             : {
    5119           0 :         DCESRV_FAULT_VOID(DCERPC_FAULT_OP_RNG_ERROR);
    5120             : }
    5121             : 
    5122             : /*
    5123             :   lsa_Opnum108NotUsedOnWire
    5124             : */
    5125           0 : static void dcesrv_lsa_Opnum108NotUsedOnWire(struct dcesrv_call_state *dce_call,
    5126             :                                             TALLOC_CTX *mem_ctx,
    5127             :                                             struct lsa_Opnum108NotUsedOnWire *r)
    5128             : {
    5129           0 :         DCESRV_FAULT_VOID(DCERPC_FAULT_OP_RNG_ERROR);
    5130             : }
    5131             : 
    5132             : /*
    5133             :   lsa_Opnum109NotUsedOnWire
    5134             : */
    5135           0 : static void dcesrv_lsa_Opnum109NotUsedOnWire(struct dcesrv_call_state *dce_call,
    5136             :                                             TALLOC_CTX *mem_ctx,
    5137             :                                             struct lsa_Opnum109NotUsedOnWire *r)
    5138             : {
    5139           0 :         DCESRV_FAULT_VOID(DCERPC_FAULT_OP_RNG_ERROR);
    5140             : }
    5141             : 
    5142             : /*
    5143             :   lsa_Opnum110NotUsedOnWire
    5144             : */
    5145           0 : static void dcesrv_lsa_Opnum110NotUsedOnWire(struct dcesrv_call_state *dce_call,
    5146             :                                             TALLOC_CTX *mem_ctx,
    5147             :                                             struct lsa_Opnum110NotUsedOnWire *r)
    5148             : {
    5149           0 :         DCESRV_FAULT_VOID(DCERPC_FAULT_OP_RNG_ERROR);
    5150             : }
    5151             : 
    5152             : /*
    5153             :   lsa_Opnum111NotUsedOnWire
    5154             : */
    5155           0 : static void dcesrv_lsa_Opnum111NotUsedOnWire(struct dcesrv_call_state *dce_call,
    5156             :                                             TALLOC_CTX *mem_ctx,
    5157             :                                             struct lsa_Opnum111NotUsedOnWire *r)
    5158             : {
    5159           0 :         DCESRV_FAULT_VOID(DCERPC_FAULT_OP_RNG_ERROR);
    5160             : }
    5161             : 
    5162             : /*
    5163             :   lsa_Opnum112NotUsedOnWire
    5164             : */
    5165           0 : static void dcesrv_lsa_Opnum112NotUsedOnWire(struct dcesrv_call_state *dce_call,
    5166             :                                             TALLOC_CTX *mem_ctx,
    5167             :                                             struct lsa_Opnum112NotUsedOnWire *r)
    5168             : {
    5169           0 :         DCESRV_FAULT_VOID(DCERPC_FAULT_OP_RNG_ERROR);
    5170             : }
    5171             : 
    5172             : /*
    5173             :   lsa_Opnum113NotUsedOnWire
    5174             : */
    5175           0 : static void dcesrv_lsa_Opnum113NotUsedOnWire(struct dcesrv_call_state *dce_call,
    5176             :                                             TALLOC_CTX *mem_ctx,
    5177             :                                             struct lsa_Opnum113NotUsedOnWire *r)
    5178             : {
    5179           0 :         DCESRV_FAULT_VOID(DCERPC_FAULT_OP_RNG_ERROR);
    5180             : }
    5181             : 
    5182             : /*
    5183             :   lsa_Opnum114NotUsedOnWire
    5184             : */
    5185           0 : static void dcesrv_lsa_Opnum114NotUsedOnWire(struct dcesrv_call_state *dce_call,
    5186             :                                             TALLOC_CTX *mem_ctx,
    5187             :                                             struct lsa_Opnum114NotUsedOnWire *r)
    5188             : {
    5189           0 :         DCESRV_FAULT_VOID(DCERPC_FAULT_OP_RNG_ERROR);
    5190             : }
    5191             : 
    5192             : /*
    5193             :   lsa_Opnum115NotUsedOnWire
    5194             : */
    5195           0 : static void dcesrv_lsa_Opnum115NotUsedOnWire(struct dcesrv_call_state *dce_call,
    5196             :                                             TALLOC_CTX *mem_ctx,
    5197             :                                             struct lsa_Opnum115NotUsedOnWire *r)
    5198             : {
    5199           0 :         DCESRV_FAULT_VOID(DCERPC_FAULT_OP_RNG_ERROR);
    5200             : }
    5201             : 
    5202             : /*
    5203             :   lsa_Opnum116NotUsedOnWire
    5204             : */
    5205           0 : static void dcesrv_lsa_Opnum116NotUsedOnWire(struct dcesrv_call_state *dce_call,
    5206             :                                             TALLOC_CTX *mem_ctx,
    5207             :                                             struct lsa_Opnum116NotUsedOnWire *r)
    5208             : {
    5209           0 :         DCESRV_FAULT_VOID(DCERPC_FAULT_OP_RNG_ERROR);
    5210             : }
    5211             : 
    5212             : /*
    5213             :   lsa_Opnum117NotUsedOnWire
    5214             : */
    5215           0 : static void dcesrv_lsa_Opnum117NotUsedOnWire(struct dcesrv_call_state *dce_call,
    5216             :                                             TALLOC_CTX *mem_ctx,
    5217             :                                             struct lsa_Opnum117NotUsedOnWire *r)
    5218             : {
    5219           0 :         DCESRV_FAULT_VOID(DCERPC_FAULT_OP_RNG_ERROR);
    5220             : }
    5221             : 
    5222             : /*
    5223             :   lsa_Opnum118NotUsedOnWire
    5224             : */
    5225           0 : static void dcesrv_lsa_Opnum118NotUsedOnWire(struct dcesrv_call_state *dce_call,
    5226             :                                             TALLOC_CTX *mem_ctx,
    5227             :                                             struct lsa_Opnum118NotUsedOnWire *r)
    5228             : {
    5229           0 :         DCESRV_FAULT_VOID(DCERPC_FAULT_OP_RNG_ERROR);
    5230             : }
    5231             : 
    5232             : /*
    5233             :   lsa_Opnum119NotUsedOnWire
    5234             : */
    5235           0 : static void dcesrv_lsa_Opnum119NotUsedOnWire(struct dcesrv_call_state *dce_call,
    5236             :                                             TALLOC_CTX *mem_ctx,
    5237             :                                             struct lsa_Opnum119NotUsedOnWire *r)
    5238             : {
    5239           0 :         DCESRV_FAULT_VOID(DCERPC_FAULT_OP_RNG_ERROR);
    5240             : }
    5241             : 
    5242             : /*
    5243             :   lsa_Opnum120NotUsedOnWire
    5244             : */
    5245           0 : static void dcesrv_lsa_Opnum120NotUsedOnWire(struct dcesrv_call_state *dce_call,
    5246             :                                             TALLOC_CTX *mem_ctx,
    5247             :                                             struct lsa_Opnum120NotUsedOnWire *r)
    5248             : {
    5249           0 :         DCESRV_FAULT_VOID(DCERPC_FAULT_OP_RNG_ERROR);
    5250             : }
    5251             : 
    5252             : /*
    5253             :   lsa_Opnum121NotUsedOnWire
    5254             : */
    5255           0 : static void dcesrv_lsa_Opnum121NotUsedOnWire(struct dcesrv_call_state *dce_call,
    5256             :                                             TALLOC_CTX *mem_ctx,
    5257             :                                             struct lsa_Opnum121NotUsedOnWire *r)
    5258             : {
    5259           0 :         DCESRV_FAULT_VOID(DCERPC_FAULT_OP_RNG_ERROR);
    5260             : }
    5261             : 
    5262             : /*
    5263             :   lsa_Opnum122NotUsedOnWire
    5264             : */
    5265           0 : static void dcesrv_lsa_Opnum122NotUsedOnWire(struct dcesrv_call_state *dce_call,
    5266             :                                             TALLOC_CTX *mem_ctx,
    5267             :                                             struct lsa_Opnum122NotUsedOnWire *r)
    5268             : {
    5269           0 :         DCESRV_FAULT_VOID(DCERPC_FAULT_OP_RNG_ERROR);
    5270             : }
    5271             : 
    5272             : /*
    5273             :   lsa_Opnum123NotUsedOnWire
    5274             : */
    5275           0 : static void dcesrv_lsa_Opnum123NotUsedOnWire(struct dcesrv_call_state *dce_call,
    5276             :                                             TALLOC_CTX *mem_ctx,
    5277             :                                             struct lsa_Opnum123NotUsedOnWire *r)
    5278             : {
    5279           0 :         DCESRV_FAULT_VOID(DCERPC_FAULT_OP_RNG_ERROR);
    5280             : }
    5281             : 
    5282             : /*
    5283             :   lsa_Opnum124NotUsedOnWire
    5284             : */
    5285           0 : static void dcesrv_lsa_Opnum124NotUsedOnWire(struct dcesrv_call_state *dce_call,
    5286             :                                             TALLOC_CTX *mem_ctx,
    5287             :                                             struct lsa_Opnum124NotUsedOnWire *r)
    5288             : {
    5289           0 :         DCESRV_FAULT_VOID(DCERPC_FAULT_OP_RNG_ERROR);
    5290             : }
    5291             : 
    5292             : /*
    5293             :   lsa_Opnum125NotUsedOnWire
    5294             : */
    5295           0 : static void dcesrv_lsa_Opnum125NotUsedOnWire(struct dcesrv_call_state *dce_call,
    5296             :                                             TALLOC_CTX *mem_ctx,
    5297             :                                             struct lsa_Opnum125NotUsedOnWire *r)
    5298             : {
    5299           0 :         DCESRV_FAULT_VOID(DCERPC_FAULT_OP_RNG_ERROR);
    5300             : }
    5301             : 
    5302             : /*
    5303             :   lsa_Opnum126NotUsedOnWire
    5304             : */
    5305           0 : static void dcesrv_lsa_Opnum126NotUsedOnWire(struct dcesrv_call_state *dce_call,
    5306             :                                             TALLOC_CTX *mem_ctx,
    5307             :                                             struct lsa_Opnum126NotUsedOnWire *r)
    5308             : {
    5309           0 :         DCESRV_FAULT_VOID(DCERPC_FAULT_OP_RNG_ERROR);
    5310             : }
    5311             : 
    5312             : /*
    5313             :   lsa_Opnum127NotUsedOnWire
    5314             : */
    5315           0 : static void dcesrv_lsa_Opnum127NotUsedOnWire(struct dcesrv_call_state *dce_call,
    5316             :                                             TALLOC_CTX *mem_ctx,
    5317             :                                             struct lsa_Opnum127NotUsedOnWire *r)
    5318             : {
    5319           0 :         DCESRV_FAULT_VOID(DCERPC_FAULT_OP_RNG_ERROR);
    5320             : }
    5321             : 
    5322             : /*
    5323             :   lsa_Opnum128NotUsedOnWire
    5324             : */
    5325           0 : static void dcesrv_lsa_Opnum128NotUsedOnWire(struct dcesrv_call_state *dce_call,
    5326             :                                             TALLOC_CTX *mem_ctx,
    5327             :                                             struct lsa_Opnum128NotUsedOnWire *r)
    5328             : {
    5329           0 :         DCESRV_FAULT_VOID(DCERPC_FAULT_OP_RNG_ERROR);
    5330             : }
    5331             : 
    5332             : /*
    5333             :   lsa_CreateTrustedDomainEx3
    5334             : */
    5335          59 : static NTSTATUS dcesrv_lsa_CreateTrustedDomainEx3(struct dcesrv_call_state *dce_call,
    5336             :                                                   TALLOC_CTX *mem_ctx,
    5337             :                                                   struct lsa_CreateTrustedDomainEx3 *r)
    5338             : {
    5339          59 :         struct dcesrv_handle *policy_handle = NULL;
    5340          59 :         struct trustDomainPasswords auth_struct = {
    5341             :                 .incoming_size = 0,
    5342             :         };
    5343           0 :         NTSTATUS status;
    5344             : 
    5345          59 :         ZERO_STRUCTP(r->out.trustdom_handle);
    5346             : 
    5347          59 :         DCESRV_PULL_HANDLE(policy_handle,
    5348             :                            r->in.policy_handle,
    5349             :                            LSA_HANDLE_POLICY);
    5350             : 
    5351          59 :         status = dcesrv_lsa_CreateTrustedDomain_precheck(mem_ctx,
    5352             :                                                          policy_handle,
    5353             :                                                          r->in.info);
    5354          59 :         if (!NT_STATUS_IS_OK(status)) {
    5355           0 :                 return status;
    5356             :         }
    5357             : 
    5358          59 :         status = get_trustdom_auth_blob_aes(dce_call,
    5359             :                                             mem_ctx,
    5360             :                                             r->in.auth_info_internal,
    5361             :                                             &auth_struct);
    5362          59 :         if (!NT_STATUS_IS_OK(status)) {
    5363           0 :                 return status;
    5364             :         }
    5365             : 
    5366          59 :         status = dcesrv_lsa_CreateTrustedDomain_common(dce_call,
    5367             :                                                        mem_ctx,
    5368             :                                                        policy_handle,
    5369             :                                                        r->in.access_mask,
    5370             :                                                        r->in.info,
    5371             :                                                        &auth_struct,
    5372             :                                                        &r->out.trustdom_handle);
    5373          59 :         if (!NT_STATUS_IS_OK(status)) {
    5374           0 :                 return status;
    5375             :         }
    5376             : 
    5377          59 :         return NT_STATUS_OK;
    5378             : }
    5379             : 
    5380             : /*
    5381             :   lsa_Opnum131NotUsedOnWire
    5382             : */
    5383           0 : static void dcesrv_lsa_Opnum131NotUsedOnWire(struct dcesrv_call_state *dce_call,
    5384             :                                             TALLOC_CTX *mem_ctx,
    5385             :                                             struct lsa_Opnum131NotUsedOnWire *r)
    5386             : {
    5387           0 :         DCESRV_FAULT_VOID(DCERPC_FAULT_OP_RNG_ERROR);
    5388             : }
    5389             : 
    5390             : /*
    5391             :   lsa_lsaRQueryForestTrustInformation2
    5392             : */
    5393           0 : static NTSTATUS dcesrv_lsa_lsaRQueryForestTrustInformation2(
    5394             :                 struct dcesrv_call_state *dce_call,
    5395             :                 TALLOC_CTX *mem_ctx,
    5396             :                 struct lsa_lsaRQueryForestTrustInformation2 *r)
    5397             : {
    5398             :         /* TODO */
    5399           0 :         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
    5400             : }
    5401             : 
    5402             : /*
    5403             :   lsa_lsaRSetForestTrustInformation2
    5404             : */
    5405           0 : static NTSTATUS dcesrv_lsa_lsaRSetForestTrustInformation2(struct dcesrv_call_state *dce_call,
    5406             :                                                           TALLOC_CTX *mem_ctx,
    5407             :                                                           struct lsa_lsaRSetForestTrustInformation2 *r)
    5408             : {
    5409             :         /* TODO */
    5410           0 :         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
    5411             : }
    5412             : 
    5413             : /* include the generated boilerplate */
    5414             : #include "librpc/gen_ndr/ndr_lsa_s.c"
    5415             : 
    5416             : 
    5417             : 
    5418             : /*****************************************
    5419             : NOTE! The remaining calls below were
    5420             : removed in w2k3, so the DCESRV_FAULT()
    5421             : replies are the correct implementation. Do
    5422             : not try and fill these in with anything else
    5423             : ******************************************/
    5424             : 
    5425             : /*
    5426             :   dssetup_DsRoleDnsNameToFlatName
    5427             : */
    5428           0 : static WERROR dcesrv_dssetup_DsRoleDnsNameToFlatName(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
    5429             :                                         struct dssetup_DsRoleDnsNameToFlatName *r)
    5430             : {
    5431           0 :         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
    5432             : }
    5433             : 
    5434             : 
    5435             : /*
    5436             :   dssetup_DsRoleDcAsDc
    5437             : */
    5438           0 : static WERROR dcesrv_dssetup_DsRoleDcAsDc(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
    5439             :                              struct dssetup_DsRoleDcAsDc *r)
    5440             : {
    5441           0 :         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
    5442             : }
    5443             : 
    5444             : 
    5445             : /*
    5446             :   dssetup_DsRoleDcAsReplica
    5447             : */
    5448           0 : static WERROR dcesrv_dssetup_DsRoleDcAsReplica(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
    5449             :                                   struct dssetup_DsRoleDcAsReplica *r)
    5450             : {
    5451           0 :         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
    5452             : }
    5453             : 
    5454             : 
    5455             : /*
    5456             :   dssetup_DsRoleDemoteDc
    5457             : */
    5458           0 : static WERROR dcesrv_dssetup_DsRoleDemoteDc(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
    5459             :                                struct dssetup_DsRoleDemoteDc *r)
    5460             : {
    5461           0 :         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
    5462             : }
    5463             : 
    5464             : 
    5465             : /*
    5466             :   dssetup_DsRoleGetDcOperationProgress
    5467             : */
    5468           0 : static WERROR dcesrv_dssetup_DsRoleGetDcOperationProgress(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
    5469             :                                              struct dssetup_DsRoleGetDcOperationProgress *r)
    5470             : {
    5471           0 :         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
    5472             : }
    5473             : 
    5474             : 
    5475             : /*
    5476             :   dssetup_DsRoleGetDcOperationResults
    5477             : */
    5478           0 : static WERROR dcesrv_dssetup_DsRoleGetDcOperationResults(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
    5479             :                                             struct dssetup_DsRoleGetDcOperationResults *r)
    5480             : {
    5481           0 :         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
    5482             : }
    5483             : 
    5484             : 
    5485             : /*
    5486             :   dssetup_DsRoleCancel
    5487             : */
    5488           0 : static WERROR dcesrv_dssetup_DsRoleCancel(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
    5489             :                              struct dssetup_DsRoleCancel *r)
    5490             : {
    5491           0 :         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
    5492             : }
    5493             : 
    5494             : 
    5495             : /*
    5496             :   dssetup_DsRoleServerSaveStateForUpgrade
    5497             : */
    5498           0 : static WERROR dcesrv_dssetup_DsRoleServerSaveStateForUpgrade(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
    5499             :                                                 struct dssetup_DsRoleServerSaveStateForUpgrade *r)
    5500             : {
    5501           0 :         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
    5502             : }
    5503             : 
    5504             : 
    5505             : /*
    5506             :   dssetup_DsRoleUpgradeDownlevelServer
    5507             : */
    5508           0 : static WERROR dcesrv_dssetup_DsRoleUpgradeDownlevelServer(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
    5509             :                                              struct dssetup_DsRoleUpgradeDownlevelServer *r)
    5510             : {
    5511           0 :         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
    5512             : }
    5513             : 
    5514             : 
    5515             : /*
    5516             :   dssetup_DsRoleAbortDownlevelServerUpgrade
    5517             : */
    5518           0 : static WERROR dcesrv_dssetup_DsRoleAbortDownlevelServerUpgrade(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
    5519             :                                                   struct dssetup_DsRoleAbortDownlevelServerUpgrade *r)
    5520             : {
    5521           0 :         DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
    5522             : }
    5523             : 
    5524             : 
    5525             : /* include the generated boilerplate */
    5526             : #include "librpc/gen_ndr/ndr_dssetup_s.c"
    5527             : 
    5528          66 : NTSTATUS dcerpc_server_lsa_init(TALLOC_CTX *ctx)
    5529             : {
    5530           2 :         NTSTATUS ret;
    5531             : 
    5532          66 :         ret = dcerpc_server_dssetup_init(ctx);
    5533          66 :         if (!NT_STATUS_IS_OK(ret)) {
    5534           0 :                 return ret;
    5535             :         }
    5536          66 :         ret = dcerpc_server_lsarpc_init(ctx);
    5537          66 :         if (!NT_STATUS_IS_OK(ret)) {
    5538           0 :                 return ret;
    5539             :         }
    5540          66 :         return ret;
    5541             : }

Generated by: LCOV version 1.14