gpo: Apply kerberos settings
[nivanova/samba-autobuild/.git] / source4 / kdc / db-glue.c
index 14512c8e160ddd542bfc3a8bea9d71e623b0d3dc..69c54b00c5ba82b9bf3b7b96013883db30bb3c00 100644 (file)
@@ -35,6 +35,9 @@
 #include "kdc/sdb.h"
 #include "kdc/samba_kdc.h"
 #include "kdc/db-glue.h"
+#include "librpc/gen_ndr/ndr_irpc_c.h"
+#include "lib/messaging/irpc.h"
+
 
 #define SAMBA_KVNO_GET_KRBTGT(kvno) \
        ((uint16_t)(((uint32_t)kvno) >> 16))
@@ -65,6 +68,52 @@ static const char *trust_attrs[] = {
        NULL
 };
 
+/*
+  send a message to the drepl server telling it to initiate a
+  REPL_SECRET getncchanges extended op to fetch the users secrets
+ */
+static void auth_sam_trigger_repl_secret(TALLOC_CTX *mem_ctx,
+                                  struct imessaging_context *msg_ctx,
+                                  struct tevent_context *event_ctx,
+                                  struct ldb_dn *user_dn)
+{
+        struct dcerpc_binding_handle *irpc_handle;
+        struct drepl_trigger_repl_secret r;
+        struct tevent_req *req;
+        TALLOC_CTX *tmp_ctx;
+
+        tmp_ctx = talloc_new(mem_ctx);
+        if (tmp_ctx == NULL) {
+                return;
+        }
+
+        irpc_handle = irpc_binding_handle_by_name(tmp_ctx, msg_ctx,
+                                                  "dreplsrv",
+                                                  &ndr_table_irpc);
+        if (irpc_handle == NULL) {
+                DEBUG(1,(__location__ ": Unable to get binding handle for dreplsrv\n"));
+                TALLOC_FREE(tmp_ctx);
+                return;
+        }
+
+        r.in.user_dn = ldb_dn_get_linearized(user_dn);
+
+        /*
+         * This seem to rely on the current IRPC implementation,
+         * which delivers the message in the _send function.
+         *
+         * TODO: we need a ONE_WAY IRPC handle and register
+         * a callback and wait for it to be triggered!
+         */
+        req = dcerpc_drepl_trigger_repl_secret_r_send(tmp_ctx,
+                                                      event_ctx,
+                                                      irpc_handle,
+                                                      &r);
+
+        /* we aren't interested in a reply */
+        talloc_free(req);
+        TALLOC_FREE(tmp_ctx);
+}
 
 static time_t ldb_msg_find_krb5time_ldap_time(struct ldb_message *msg, const char *attr, time_t default_val)
 {
@@ -236,9 +285,8 @@ static int samba_kdc_sort_encryption_keys(struct sdb_entry_ex *entry_ex)
                for (j = 0; j < keys_size; j++) {
                        const struct sdb_key skey = keys[j];
 
-                       /* Paranoia: Do not overflow the key_data array */
-                       if (idx > keys_size) {
-                               return -1;
+                       if (idx == keys_size) {
+                               break;
                        }
 
                        if (KRB5_KEY_TYPE(&skey.key) == etype_list[i]) {
@@ -249,7 +297,8 @@ static int samba_kdc_sort_encryption_keys(struct sdb_entry_ex *entry_ex)
        }
 
        /* Paranoia: Something went wrong during data copy */
-       if (idx < keys_size) {
+       if (idx != keys_size) {
+               free(sorted_keys);
                return -1;
        }
 
@@ -504,7 +553,8 @@ static krb5_error_code samba_kdc_message2entry_keys(krb5_context context,
        if (allocated_keys == 0) {
                if (kdc_db_ctx->rodc) {
                        /* We are on an RODC, but don't have keys for this account.  Signal this to the caller */
-                       /* TODO:  We need to call a generalised version of auth_sam_trigger_repl_secret from here */
+                       auth_sam_trigger_repl_secret(kdc_db_ctx, kdc_db_ctx->msg_ctx,
+                                                    kdc_db_ctx->ev_ctx, msg->dn);
                        return SDB_ERR_NOT_FOUND_HERE;
                }
 
@@ -736,7 +786,6 @@ static krb5_error_code samba_kdc_message2entry(krb5_context context,
        struct loadparm_context *lp_ctx = kdc_db_ctx->lp_ctx;
        uint32_t userAccountControl;
        uint32_t msDS_User_Account_Control_Computed;
-       unsigned int i;
        krb5_error_code ret = 0;
        krb5_boolean is_computer = FALSE;
 
@@ -1088,24 +1137,6 @@ static krb5_error_code samba_kdc_message2entry(krb5_context context,
                goto out;
        }
 
-       entry_ex->entry.etypes = malloc(sizeof(*(entry_ex->entry.etypes)));
-       if (entry_ex->entry.etypes == NULL) {
-               krb5_clear_error_message(context);
-               ret = ENOMEM;
-               goto out;
-       }
-       entry_ex->entry.etypes->len = entry_ex->entry.keys.len;
-       entry_ex->entry.etypes->val = calloc(entry_ex->entry.etypes->len, sizeof(int));
-       if (entry_ex->entry.etypes->val == NULL) {
-               krb5_clear_error_message(context);
-               ret = ENOMEM;
-               goto out;
-       }
-       for (i=0; i < entry_ex->entry.etypes->len; i++) {
-               entry_ex->entry.etypes->val[i] = KRB5_KEY_TYPE(&entry_ex->entry.keys.val[i].key);
-       }
-
-
        p->msg = talloc_steal(p, msg);
 
 out:
@@ -1499,23 +1530,6 @@ static krb5_error_code samba_kdc_trust_message2entry(krb5_context context,
                goto out;
        }
 
-       entry_ex->entry.etypes = malloc(sizeof(*(entry_ex->entry.etypes)));
-       if (entry_ex->entry.etypes == NULL) {
-               krb5_clear_error_message(context);
-               ret = ENOMEM;
-               goto out;
-       }
-       entry_ex->entry.etypes->len = entry_ex->entry.keys.len;
-       entry_ex->entry.etypes->val = calloc(entry_ex->entry.etypes->len, sizeof(int));
-       if (entry_ex->entry.etypes->val == NULL) {
-               krb5_clear_error_message(context);
-               ret = ENOMEM;
-               goto out;
-       }
-       for (i=0; i < entry_ex->entry.etypes->len; i++) {
-               entry_ex->entry.etypes->val[i] = KRB5_KEY_TYPE(&entry_ex->entry.keys.val[i].key);
-       }
-
        p->msg = talloc_steal(p, msg);
 
 out:
@@ -2713,9 +2727,11 @@ NTSTATUS samba_kdc_setup_db_ctx(TALLOC_CTX *mem_ctx, struct samba_kdc_base_conte
        }
        kdc_db_ctx->ev_ctx = base_ctx->ev_ctx;
        kdc_db_ctx->lp_ctx = base_ctx->lp_ctx;
+       kdc_db_ctx->msg_ctx = base_ctx->msg_ctx;
 
        /* get default kdc policy */
-       lpcfg_default_kdc_policy(base_ctx->lp_ctx,
+       lpcfg_default_kdc_policy(mem_ctx,
+                                base_ctx->lp_ctx,
                                 &kdc_db_ctx->policy.svc_tkt_lifetime,
                                 &kdc_db_ctx->policy.usr_tkt_lifetime,
                                 &kdc_db_ctx->policy.renewal_lifetime);