s4:rpc_server: only pass context to op_bind() hooks
[gd/samba-autobuild/.git] / source4 / rpc_server / lsa / dcesrv_lsa.c
index 41311ed87cf2b67c9e61216c9aadbedfd0348d39..ec3be02bf876e307579ba3fa635233e5878704b8 100644 (file)
 #include "lib/messaging/irpc.h"
 #include "libds/common/roles.h"
 
-#define DCESRV_INTERFACE_LSARPC_BIND(call, iface) \
-       dcesrv_interface_lsarpc_bind(call, iface)
-static NTSTATUS dcesrv_interface_lsarpc_bind(struct dcesrv_call_state *dce_call,
+#define DCESRV_INTERFACE_LSARPC_BIND(context, iface) \
+       dcesrv_interface_lsarpc_bind(context, iface)
+static NTSTATUS dcesrv_interface_lsarpc_bind(struct dcesrv_connection_context *context,
                                             const struct dcesrv_interface *iface)
 {
-       return dcesrv_interface_bind_reject_connect(dce_call, iface);
+       return dcesrv_interface_bind_reject_connect(context, iface);
+}
+
+static NTSTATUS lsarpc__op_init_server(struct dcesrv_context *dce_ctx,
+                                      const struct dcesrv_endpoint_server *ep_server);
+static const struct dcesrv_interface dcesrv_lsarpc_interface;
+
+#define DCESRV_INTERFACE_LSARPC_INIT_SERVER    \
+       dcesrv_interface_lsarpc_init_server
+static NTSTATUS dcesrv_interface_lsarpc_init_server(struct dcesrv_context *dce_ctx,
+                                                   const struct dcesrv_endpoint_server *ep_server)
+{
+       if (lpcfg_lsa_over_netlogon(dce_ctx->lp_ctx)) {
+               NTSTATUS ret = dcesrv_interface_register(dce_ctx,
+                                               "ncacn_np:[\\pipe\\netlogon]",
+                                               &dcesrv_lsarpc_interface, NULL);
+               if (!NT_STATUS_IS_OK(ret)) {
+                       DEBUG(1,("lsarpc_op_init_server: failed to register endpoint '\\pipe\\netlogon'\n"));
+                       return ret;
+               }
+       }
+       return lsarpc__op_init_server(dce_ctx, ep_server);
 }
 
 /*
@@ -78,6 +99,24 @@ struct lsa_trusted_domain_state {
        struct ldb_dn *trusted_domain_user_dn;
 };
 
+static bool dcesrc_lsa_valid_AccountRight(const char *right)
+{
+       enum sec_privilege priv_id;
+       uint32_t right_bit;
+
+       priv_id = sec_privilege_id(right);
+       if (priv_id != SEC_PRIV_INVALID) {
+               return true;
+       }
+
+       right_bit = sec_right_bit(right);
+       if (right_bit != 0) {
+               return true;
+       }
+
+       return false;
+}
+
 /*
   this is based on the samba3 function make_lsa_object_sd()
   It uses the same logic, but with samba4 helper functions
@@ -202,6 +241,8 @@ static NTSTATUS dcesrv_lsa_Delete(struct dcesrv_call_state *dce_call, TALLOC_CTX
 static NTSTATUS dcesrv_lsa_DeleteObject(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
                       struct lsa_DeleteObject *r)
 {
+       struct auth_session_info *session_info =
+               dcesrv_call_session_info(dce_call);
        struct dcesrv_handle *h;
        int ret;
 
@@ -211,7 +252,7 @@ static NTSTATUS dcesrv_lsa_DeleteObject(struct dcesrv_call_state *dce_call, TALL
                struct lsa_secret_state *secret_state = h->data;
 
                /* Ensure user is permitted to delete this... */
-               switch (security_session_user_level(dce_call->conn->auth_state.session_info, NULL))
+               switch (security_session_user_level(session_info, NULL))
                {
                case SECURITY_SYSTEM:
                case SECURITY_ADMINISTRATOR:
@@ -358,6 +399,8 @@ static NTSTATUS dcesrv_lsa_EnumPrivs(struct dcesrv_call_state *dce_call, TALLOC_
 static NTSTATUS dcesrv_lsa_QuerySecurity(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
                                         struct lsa_QuerySecurity *r)
 {
+       struct auth_session_info *session_info =
+               dcesrv_call_session_info(dce_call);
        struct dcesrv_handle *h;
        const struct security_descriptor *sd = NULL;
        uint32_t access_granted = 0;
@@ -367,7 +410,7 @@ static NTSTATUS dcesrv_lsa_QuerySecurity(struct dcesrv_call_state *dce_call, TAL
 
        DCESRV_PULL_HANDLE(h, r->in.handle, DCESRV_HANDLE_ANY);
 
-       sid = &dce_call->conn->auth_state.session_info->security_token->sids[PRIMARY_USER_SID_INDEX];
+       sid = &session_info->security_token->sids[PRIMARY_USER_SID_INDEX];
 
        if (h->wire_handle.handle_type == LSA_HANDLE_POLICY) {
                struct lsa_policy_state *pstate = h->data;
@@ -529,7 +572,7 @@ static WERROR dcesrv_dssetup_DsRoleGetPrimaryDomainInformation(struct dcesrv_cal
                return WERR_OK;
        }
        default:
-               return WERR_INVALID_PARAM;
+               return WERR_INVALID_PARAMETER;
        }
 }
 
@@ -735,7 +778,7 @@ static NTSTATUS dcesrv_lsa_CreateAccount(struct dcesrv_call_state *dce_call, TAL
                 (unsigned)r->in.access_mask,
                 (unsigned)astate->access_mask));
 
-       ah = dcesrv_handle_new(dce_call->context, LSA_HANDLE_ACCOUNT);
+       ah = dcesrv_handle_create(dce_call, LSA_HANDLE_ACCOUNT);
        if (!ah) {
                talloc_free(astate);
                return NT_STATUS_NO_MEMORY;
@@ -816,7 +859,7 @@ static NTSTATUS get_trustdom_auth_blob(struct dcesrv_call_state *dce_call,
        enum ndr_err_code ndr_err;
        NTSTATUS nt_status;
 
-       nt_status = dcesrv_fetch_session_key(dce_call->conn, &session_key);
+       nt_status = dcesrv_transport_session_key(dce_call, &session_key);
        if (!NT_STATUS_IS_OK(nt_status)) {
                return nt_status;
        }
@@ -1023,9 +1066,6 @@ static NTSTATUS dcesrv_lsa_CreateTrustedDomain_base(struct dcesrv_call_state *dc
        struct server_id *server_ids = NULL;
        uint32_t num_server_ids = 0;
        NTSTATUS status;
-       struct dom_sid *tmp_sid1;
-       struct dom_sid *tmp_sid2;
-       uint32_t tmp_rid;
        bool ok;
        char *dns_encoded = NULL;
        char *netbios_encoded = NULL;
@@ -1055,35 +1095,8 @@ static NTSTATUS dcesrv_lsa_CreateTrustedDomain_base(struct dcesrv_call_state *dc
         * We expect S-1-5-21-A-B-C, but we don't
         * allow S-1-5-21-0-0-0 as this is used
         * for claims and compound identities.
-        *
-        * So we call dom_sid_split_rid() 3 times
-        * and compare the result to S-1-5-21
         */
-       status = dom_sid_split_rid(mem_ctx, r->in.info->sid, &tmp_sid1, &tmp_rid);
-       if (!NT_STATUS_IS_OK(status)) {
-               return status;
-       }
-       status = dom_sid_split_rid(mem_ctx, tmp_sid1, &tmp_sid2, &tmp_rid);
-       if (!NT_STATUS_IS_OK(status)) {
-               return status;
-       }
-       status = dom_sid_split_rid(mem_ctx, tmp_sid2, &tmp_sid1, &tmp_rid);
-       if (!NT_STATUS_IS_OK(status)) {
-               return status;
-       }
-       ok = dom_sid_parse("S-1-5-21", tmp_sid2);
-       if (!ok) {
-               return NT_STATUS_INTERNAL_ERROR;
-       }
-       ok = dom_sid_equal(tmp_sid1, tmp_sid2);
-       if (!ok) {
-               return NT_STATUS_INVALID_PARAMETER;
-       }
-       ok = dom_sid_parse("S-1-5-21-0-0-0", tmp_sid2);
-       if (!ok) {
-               return NT_STATUS_INTERNAL_ERROR;
-       }
-       ok = !dom_sid_equal(r->in.info->sid, tmp_sid2);
+       ok = dom_sid_is_valid_account_domain(r->in.info->sid);
        if (!ok) {
                return NT_STATUS_INVALID_PARAMETER;
        }
@@ -1321,19 +1334,12 @@ static NTSTATUS dcesrv_lsa_CreateTrustedDomain_base(struct dcesrv_call_state *dc
                                     "winbind_server",
                                     &num_server_ids, &server_ids);
        if (NT_STATUS_IS_OK(status) && num_server_ids >= 1) {
-               enum ndr_err_code ndr_err;
-               DATA_BLOB b = {};
-
-               ndr_err = ndr_push_struct_blob(&b, mem_ctx, r->in.info,
-                       (ndr_push_flags_fn_t)ndr_push_lsa_TrustDomainInfoInfoEx);
-               if (NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
-                       imessaging_send(dce_call->msg_ctx, server_ids[0],
-                               MSG_WINBIND_NEW_TRUSTED_DOMAIN, &b);
-               }
+               imessaging_send(dce_call->msg_ctx, server_ids[0],
+                               MSG_WINBIND_RELOAD_TRUSTED_DOMAINS, NULL);
        }
        TALLOC_FREE(server_ids);
 
-       handle = dcesrv_handle_new(dce_call->context, LSA_HANDLE_TRUSTED_DOMAIN);
+       handle = dcesrv_handle_create(dce_call, LSA_HANDLE_TRUSTED_DOMAIN);
        if (!handle) {
                return NT_STATUS_NO_MEMORY;
        }
@@ -1465,7 +1471,7 @@ static NTSTATUS dcesrv_lsa_OpenTrustedDomain_common(
                }
        }
 
-       handle = dcesrv_handle_new(dce_call->context, LSA_HANDLE_TRUSTED_DOMAIN);
+       handle = dcesrv_handle_create(dce_call, LSA_HANDLE_TRUSTED_DOMAIN);
        if (!handle) {
                return NT_STATUS_NO_MEMORY;
        }
@@ -2561,7 +2567,6 @@ static NTSTATUS dcesrv_lsa_EnumTrustDom(struct dcesrv_call_state *dce_call, TALL
                                 1+(r->in.max_size/LSA_ENUM_TRUST_DOMAIN_MULTIPLIER));
 
        r->out.domains->domains = entries + *r->in.resume_handle;
-       r->out.domains->count = r->out.domains->count;
 
        if (r->out.domains->count < count - *r->in.resume_handle) {
                *r->out.resume_handle = *r->in.resume_handle + r->out.domains->count;
@@ -2656,7 +2661,6 @@ static NTSTATUS dcesrv_lsa_EnumTrustedDomainsEx(struct dcesrv_call_state *dce_ca
                                 1+(r->in.max_size/LSA_ENUM_TRUST_DOMAIN_EX_MULTIPLIER));
 
        r->out.domains->domains = entries + *r->in.resume_handle;
-       r->out.domains->count = r->out.domains->count;
 
        if (r->out.domains->count < count - *r->in.resume_handle) {
                *r->out.resume_handle = *r->in.resume_handle + r->out.domains->count;
@@ -2715,7 +2719,7 @@ static NTSTATUS dcesrv_lsa_OpenAccount(struct dcesrv_call_state *dce_call, TALLO
                 (unsigned)r->in.access_mask,
                 (unsigned)astate->access_mask));
 
-       ah = dcesrv_handle_new(dce_call->context, LSA_HANDLE_ACCOUNT);
+       ah = dcesrv_handle_create(dce_call, LSA_HANDLE_ACCOUNT);
        if (!ah) {
                talloc_free(astate);
                return NT_STATUS_NO_MEMORY;
@@ -2871,6 +2875,8 @@ static NTSTATUS dcesrv_lsa_AddRemoveAccountRights(struct dcesrv_call_state *dce_
                                           struct dom_sid *sid,
                                           const struct lsa_RightSet *rights)
 {
+       struct auth_session_info *session_info =
+               dcesrv_call_session_info(dce_call);
        const char *sidstr, *sidndrstr;
        struct ldb_message *msg;
        struct ldb_message_element *el;
@@ -2879,7 +2885,7 @@ static NTSTATUS dcesrv_lsa_AddRemoveAccountRights(struct dcesrv_call_state *dce_
        struct lsa_EnumAccountRights r2;
        char *dnstr;
 
-       if (security_session_user_level(dce_call->conn->auth_state.session_info, NULL) <
+       if (security_session_user_level(session_info, NULL) <
            SECURITY_ADMINISTRATOR) {
                DEBUG(0,("lsa_AddRemoveAccount refused for supplied security token\n"));
                return NT_STATUS_ACCESS_DENIED;
@@ -2928,12 +2934,10 @@ static NTSTATUS dcesrv_lsa_AddRemoveAccountRights(struct dcesrv_call_state *dce_
        }
 
        for (i=0;i<rights->count;i++) {
-               if (sec_privilege_id(rights->names[i].string) == SEC_PRIV_INVALID) {
-                       if (sec_right_bit(rights->names[i].string) == 0) {
-                               talloc_free(msg);
-                               return NT_STATUS_NO_SUCH_PRIVILEGE;
-                       }
+               bool ok;
 
+               ok = dcesrc_lsa_valid_AccountRight(rights->names[i].string);
+               if (!ok) {
                        talloc_free(msg);
                        return NT_STATUS_NO_SUCH_PRIVILEGE;
                }
@@ -3169,19 +3173,20 @@ static NTSTATUS dcesrv_lsa_SetSystemAccessAccount(struct dcesrv_call_state *dce_
 {
        DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
 }
-
-
 /*
   lsa_CreateSecret
 */
 static NTSTATUS dcesrv_lsa_CreateSecret(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
                                 struct lsa_CreateSecret *r)
 {
+       struct auth_session_info *session_info =
+               dcesrv_call_session_info(dce_call);
        struct dcesrv_handle *policy_handle;
        struct lsa_policy_state *policy_state;
        struct lsa_secret_state *secret_state;
        struct dcesrv_handle *handle;
        struct ldb_message **msgs, *msg;
+       struct ldb_context *samdb = NULL;
        const char *attrs[] = {
                NULL
        };
@@ -3193,7 +3198,7 @@ static NTSTATUS dcesrv_lsa_CreateSecret(struct dcesrv_call_state *dce_call, TALL
        DCESRV_PULL_HANDLE(policy_handle, r->in.handle, LSA_HANDLE_POLICY);
        ZERO_STRUCTP(r->out.sec_handle);
 
-       switch (security_session_user_level(dce_call->conn->auth_state.session_info, NULL))
+       switch (security_session_user_level(session_info, NULL))
        {
        case SECURITY_SYSTEM:
        case SECURITY_ADMINISTRATOR:
@@ -3232,11 +3237,18 @@ static NTSTATUS dcesrv_lsa_CreateSecret(struct dcesrv_call_state *dce_call, TALL
                                        ldb_binary_encode_string(mem_ctx, name));
                NT_STATUS_HAVE_NO_MEMORY(name2);
 
-               /* We need to connect to the database as system, as this is one
-                * of the rare RPC calls that must read the secrets (and this
-                * is denied otherwise) */
-               secret_state->sam_ldb = talloc_reference(secret_state,
-                                                        samdb_connect(mem_ctx, dce_call->event_ctx, dce_call->conn->dce_ctx->lp_ctx, system_session(dce_call->conn->dce_ctx->lp_ctx), 0));
+               /*
+                * We need to connect to the database as system, as this is
+                * one of the rare RPC calls that must read the secrets
+                * (and this is denied otherwise)
+                *
+                * We also save the current remote session details so they can
+                * used by the audit logging module. This allows the audit
+                * logging to report the remote users details, rather than the
+                * system users details.
+                */
+               samdb = dcesrv_samdb_connect_as_system(mem_ctx, dce_call);
+               secret_state->sam_ldb = talloc_reference(secret_state, samdb);
                NT_STATUS_HAVE_NO_MEMORY(secret_state->sam_ldb);
 
                /* search for the secret record */
@@ -3312,7 +3324,7 @@ static NTSTATUS dcesrv_lsa_CreateSecret(struct dcesrv_call_state *dce_call, TALL
                return NT_STATUS_ACCESS_DENIED;
        }
 
-       handle = dcesrv_handle_new(dce_call->context, LSA_HANDLE_SECRET);
+       handle = dcesrv_handle_create(dce_call, LSA_HANDLE_SECRET);
        NT_STATUS_HAVE_NO_MEMORY(handle);
 
        handle->data = talloc_steal(handle, secret_state);
@@ -3333,18 +3345,18 @@ static NTSTATUS dcesrv_lsa_CreateSecret(struct dcesrv_call_state *dce_call, TALL
 static NTSTATUS dcesrv_lsa_OpenSecret(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
                               struct lsa_OpenSecret *r)
 {
+       struct auth_session_info *session_info =
+               dcesrv_call_session_info(dce_call);
        struct dcesrv_handle *policy_handle;
-
        struct lsa_policy_state *policy_state;
        struct lsa_secret_state *secret_state;
        struct dcesrv_handle *handle;
        struct ldb_message **msgs;
+       struct ldb_context *samdb = NULL;
        const char *attrs[] = {
                NULL
        };
-
        const char *name;
-
        int ret;
 
        DCESRV_PULL_HANDLE(policy_handle, r->in.handle, LSA_HANDLE_POLICY);
@@ -3355,7 +3367,7 @@ static NTSTATUS dcesrv_lsa_OpenSecret(struct dcesrv_call_state *dce_call, TALLOC
                return NT_STATUS_INVALID_PARAMETER;
        }
 
-       switch (security_session_user_level(dce_call->conn->auth_state.session_info, NULL))
+       switch (security_session_user_level(session_info, NULL))
        {
        case SECURITY_SYSTEM:
        case SECURITY_ADMINISTRATOR:
@@ -3373,9 +3385,18 @@ static NTSTATUS dcesrv_lsa_OpenSecret(struct dcesrv_call_state *dce_call, TALLOC
 
        if (strncmp("G$", r->in.name.string, 2) == 0) {
                name = &r->in.name.string[2];
-               /* We need to connect to the database as system, as this is one of the rare RPC calls that must read the secrets (and this is denied otherwise) */
-               secret_state->sam_ldb = talloc_reference(secret_state,
-                                                        samdb_connect(mem_ctx, dce_call->event_ctx, dce_call->conn->dce_ctx->lp_ctx, system_session(dce_call->conn->dce_ctx->lp_ctx), 0));
+               /*
+                * We need to connect to the database as system, as this is
+                * one of the rare RPC calls that must read the secrets
+                * (and this is denied otherwise)
+                *
+                * We also save the current remote session details so they can
+                * used by the audit logging module. This allows the audit
+                * logging to report the remote users details, rather than the
+                * system users details.
+                */
+               samdb = dcesrv_samdb_connect_as_system(mem_ctx, dce_call);
+               secret_state->sam_ldb = talloc_reference(secret_state, samdb);
                secret_state->global = true;
 
                if (strlen(name) < 1) {
@@ -3425,7 +3446,7 @@ static NTSTATUS dcesrv_lsa_OpenSecret(struct dcesrv_call_state *dce_call, TALLOC
 
        secret_state->secret_dn = talloc_reference(secret_state, msgs[0]->dn);
 
-       handle = dcesrv_handle_new(dce_call->context, LSA_HANDLE_SECRET);
+       handle = dcesrv_handle_create(dce_call, LSA_HANDLE_SECRET);
        if (!handle) {
                return NT_STATUS_NO_MEMORY;
        }
@@ -3473,7 +3494,7 @@ static NTSTATUS dcesrv_lsa_SetSecret(struct dcesrv_call_state *dce_call, TALLOC_
        if (!msg->dn) {
                return NT_STATUS_NO_MEMORY;
        }
-       status = dcesrv_fetch_session_key(dce_call->conn, &session_key);
+       status = dcesrv_transport_session_key(dce_call, &session_key);
        if (!NT_STATUS_IS_OK(status)) {
                return status;
        }
@@ -3608,6 +3629,8 @@ static NTSTATUS dcesrv_lsa_SetSecret(struct dcesrv_call_state *dce_call, TALLOC_
 static NTSTATUS dcesrv_lsa_QuerySecret(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
                                struct lsa_QuerySecret *r)
 {
+       struct auth_session_info *session_info =
+               dcesrv_call_session_info(dce_call);
        struct dcesrv_handle *h;
        struct lsa_secret_state *secret_state;
        struct ldb_message *msg;
@@ -3628,7 +3651,7 @@ static NTSTATUS dcesrv_lsa_QuerySecret(struct dcesrv_call_state *dce_call, TALLO
        DCESRV_PULL_HANDLE(h, r->in.sec_handle, LSA_HANDLE_SECRET);
 
        /* Ensure user is permitted to read this... */
-       switch (security_session_user_level(dce_call->conn->auth_state.session_info, NULL))
+       switch (security_session_user_level(session_info, NULL))
        {
        case SECURITY_SYSTEM:
        case SECURITY_ADMINISTRATOR:
@@ -3648,7 +3671,7 @@ static NTSTATUS dcesrv_lsa_QuerySecret(struct dcesrv_call_state *dce_call, TALLO
        }
        msg = res[0];
 
-       nt_status = dcesrv_fetch_session_key(dce_call->conn, &session_key);
+       nt_status = dcesrv_transport_session_key(dce_call, &session_key);
        if (!NT_STATUS_IS_OK(nt_status)) {
                return nt_status;
        }
@@ -3835,6 +3858,7 @@ static NTSTATUS dcesrv_lsa_EnumAccountsWithUserRight(struct dcesrv_call_state *d
        struct ldb_message **res;
        const char * const attrs[] = { "objectSid", NULL};
        const char *privname;
+       bool ok;
 
        DCESRV_PULL_HANDLE(h, r->in.handle, LSA_HANDLE_POLICY);
 
@@ -3845,7 +3869,9 @@ static NTSTATUS dcesrv_lsa_EnumAccountsWithUserRight(struct dcesrv_call_state *d
        }
 
        privname = r->in.name->string;
-       if (sec_privilege_id(privname) == SEC_PRIV_INVALID && sec_right_bit(privname) == 0) {
+
+       ok = dcesrc_lsa_valid_AccountRight(privname);
+       if (!ok) {
                return NT_STATUS_NO_SUCH_PRIVILEGE;
        }
 
@@ -3941,6 +3967,8 @@ static NTSTATUS dcesrv_lsa_GetUserName(struct dcesrv_call_state *dce_call, TALLO
 {
        enum dcerpc_transport_t transport =
                dcerpc_binding_get_transport(dce_call->conn->endpoint->ep_description);
+       struct auth_session_info *session_info =
+               dcesrv_call_session_info(dce_call);
        NTSTATUS status = NT_STATUS_OK;
        const char *account_name;
        const char *authority_name;
@@ -3969,8 +3997,8 @@ static NTSTATUS dcesrv_lsa_GetUserName(struct dcesrv_call_state *dce_call, TALLO
                return NT_STATUS_INVALID_PARAMETER;
        }
 
-       account_name = talloc_reference(mem_ctx, dce_call->conn->auth_state.session_info->info->account_name);
-       authority_name = talloc_reference(mem_ctx, dce_call->conn->auth_state.session_info->info->domain_name);
+       account_name = talloc_reference(mem_ctx, session_info->info->account_name);
+       authority_name = talloc_reference(mem_ctx, session_info->info->domain_name);
 
        _account_name = talloc(mem_ctx, struct lsa_String);
        NT_STATUS_HAVE_NO_MEMORY(_account_name);
@@ -4001,7 +4029,8 @@ static NTSTATUS dcesrv_lsa_SetInfoPolicy2(struct dcesrv_call_state *dce_call,
        DCESRV_FAULT(DCERPC_FAULT_OP_RNG_ERROR);
 }
 
-static void kdc_get_policy(struct loadparm_context *lp_ctx,
+static void kdc_get_policy(TALLOC_CTX *mem_ctx,
+                          struct loadparm_context *lp_ctx,
                           struct smb_krb5_context *smb_krb5_context,
                           struct lsa_DomainInfoKerberos *k)
 {
@@ -4009,12 +4038,10 @@ static void kdc_get_policy(struct loadparm_context *lp_ctx,
        time_t usr_tkt_lifetime;
        time_t renewal_lifetime;
 
-       /* These should be set and stored via Group Policy, but until then, some defaults are in order */
-
        /* Our KDC always re-validates the client */
        k->authentication_options = LSA_POLICY_KERBEROS_VALIDATE_CLIENT;
 
-       lpcfg_default_kdc_policy(lp_ctx, &svc_tkt_lifetime,
+       lpcfg_default_kdc_policy(mem_ctx, lp_ctx, &svc_tkt_lifetime,
                                 &usr_tkt_lifetime, &renewal_lifetime);
 
        unix_to_nt_time(&k->service_tkt_lifetime, svc_tkt_lifetime);
@@ -4063,7 +4090,7 @@ static NTSTATUS dcesrv_lsa_QueryDomainInformationPolicy(struct dcesrv_call_state
                        *r->out.info = NULL;
                        return NT_STATUS_INTERNAL_ERROR;
                }
-               kdc_get_policy(dce_call->conn->dce_ctx->lp_ctx,
+               kdc_get_policy(mem_ctx, dce_call->conn->dce_ctx->lp_ctx,
                               smb_krb5_context,
                               k);
                talloc_free(smb_krb5_context);
@@ -4331,6 +4358,8 @@ static NTSTATUS dcesrv_lsa_lsaRSetForestTrustInformation(struct dcesrv_call_stat
        struct lsa_ForestTrustCollisionInfo *c_info = NULL;
        DATA_BLOB ft_blob = {};
        struct ldb_message *msg = NULL;
+       struct server_id *server_ids = NULL;
+       uint32_t num_server_ids = 0;
        NTSTATUS status;
        enum ndr_err_code ndr_err;
        int ret;
@@ -4570,6 +4599,21 @@ static NTSTATUS dcesrv_lsa_lsaRSetForestTrustInformation(struct dcesrv_call_stat
                goto done;
        }
 
+       /*
+        * Notify winbindd that we have a acquired forest trust info
+        */
+       status = irpc_servers_byname(dce_call->msg_ctx,
+                                    mem_ctx,
+                                    "winbind_server",
+                                    &num_server_ids, &server_ids);
+       if (!NT_STATUS_IS_OK(status)) {
+               DBG_ERR("irpc_servers_byname failed\n");
+               goto done;
+       }
+
+       imessaging_send(dce_call->msg_ctx, server_ids[0],
+                       MSG_WINBIND_RELOAD_TRUSTED_DOMAINS, NULL);
+
        status = NT_STATUS_OK;
 
 done:
@@ -4750,15 +4794,15 @@ static WERROR dcesrv_dssetup_DsRoleAbortDownlevelServerUpgrade(struct dcesrv_cal
 /* include the generated boilerplate */
 #include "librpc/gen_ndr/ndr_dssetup_s.c"
 
-NTSTATUS dcerpc_server_lsa_init(void)
+NTSTATUS dcerpc_server_lsa_init(TALLOC_CTX *ctx)
 {
        NTSTATUS ret;
 
-       ret = dcerpc_server_dssetup_init();
+       ret = dcerpc_server_dssetup_init(ctx);
        if (!NT_STATUS_IS_OK(ret)) {
                return ret;
        }
-       ret = dcerpc_server_lsarpc_init();
+       ret = dcerpc_server_lsarpc_init(ctx);
        if (!NT_STATUS_IS_OK(ret)) {
                return ret;
        }