summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrew Tridgell <tridge@samba.org>2010-09-12 10:06:39 +1000
committerAndrew Tridgell <tridge@samba.org>2010-09-15 15:39:34 +1000
commit13a8745cae2b38c8071b182a4c020305c76e62b8 (patch)
treed0ab513cd0367dbc9c4f7bd65663883791a9d6f0
parentf6d85be52830d17dbf6e7b01bf854a49dccbc7f8 (diff)
downloadsamba-13a8745cae2b38c8071b182a4c020305c76e62b8.tar.gz
samba-13a8745cae2b38c8071b182a4c020305c76e62b8.tar.bz2
samba-13a8745cae2b38c8071b182a4c020305c76e62b8.zip
s4-rodc: add a trigger message for REPL_SECRET to auth_sam
when an RODC tries to authenticate against an account and the account has no password information it needs to send a message to the drepl server to tell it to try and replicate the secret information from a writeable DC Pair-Programmed-With: Andrew Bartlett <abartlet@samba.org>
-rw-r--r--source4/auth/ntlm/auth_sam.c52
-rw-r--r--source4/dsdb/repl/drepl_service.c14
-rw-r--r--source4/librpc/idl/irpc.idl7
3 files changed, 73 insertions, 0 deletions
diff --git a/source4/auth/ntlm/auth_sam.c b/source4/auth/ntlm/auth_sam.c
index fdcc5bd90e..8de33ffa78 100644
--- a/source4/auth/ntlm/auth_sam.c
+++ b/source4/auth/ntlm/auth_sam.c
@@ -32,6 +32,8 @@
#include "dsdb/samdb/samdb.h"
#include "dsdb/common/util.h"
#include "param/param.h"
+#include "librpc/gen_ndr/ndr_irpc_c.h"
+#include "lib/messaging/irpc.h"
extern const char *user_attrs[];
extern const char *domain_ref_attrs[];
@@ -135,6 +137,37 @@ static NTSTATUS authsam_password_ok(struct auth_context *auth_context,
}
+/*
+ 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 auth_context *auth_context,
+ struct ldb_dn *user_dn)
+{
+ struct dcerpc_binding_handle *irpc_handle;
+ struct drepl_trigger_repl_secret r;
+ struct tevent_req *req;
+
+ irpc_handle = irpc_binding_handle_by_name(mem_ctx, auth_context->msg_ctx,
+ "dreplsrv",
+ &ndr_table_irpc);
+ if (irpc_handle == NULL) {
+ DEBUG(1,(__location__ ": Unable to get binding handle for dreplsrv\n"));
+ return;
+ }
+
+ r.in.user_dn = ldb_dn_get_linearized(user_dn);
+
+ req = dcerpc_drepl_trigger_repl_secret_r_send(mem_ctx,
+ auth_context->event_ctx,
+ irpc_handle,
+ &r);
+
+ /* we aren't interested in a reply */
+ talloc_free(req);
+ talloc_free(irpc_handle);
+}
+
static NTSTATUS authsam_authenticate(struct auth_context *auth_context,
TALLOC_CTX *mem_ctx, struct ldb_context *sam_ctx,
@@ -165,6 +198,25 @@ static NTSTATUS authsam_authenticate(struct auth_context *auth_context,
nt_status = samdb_result_passwords(mem_ctx, auth_context->lp_ctx, msg, &lm_pwd, &nt_pwd);
NT_STATUS_NOT_OK_RETURN(nt_status);
+ if (lm_pwd == NULL && nt_pwd == NULL) {
+ bool am_rodc;
+ if (samdb_rodc(auth_context->sam_ctx, &am_rodc) == LDB_SUCCESS && am_rodc) {
+ /* we don't have passwords for this
+ * account. We are an RODC, and this account
+ * may be one for which we either are denied
+ * REPL_SECRET replication or we haven't yet
+ * done the replication. We return
+ * NT_STATUS_NOT_IMPLEMENTED which tells the
+ * auth code to try the next authentication
+ * mechanism. We also send a message to our
+ * drepl server to tell it to try and
+ * replicate the secrets for this account.
+ */
+ auth_sam_trigger_repl_secret(mem_ctx, auth_context, msg->dn);
+ return NT_STATUS_NOT_IMPLEMENTED;
+ }
+ }
+
nt_status = authsam_password_ok(auth_context, mem_ctx,
acct_flags, lm_pwd, nt_pwd,
user_info, user_sess_key, lm_sess_key);
diff --git a/source4/dsdb/repl/drepl_service.c b/source4/dsdb/repl/drepl_service.c
index 2c436172f1..9a353b0c1f 100644
--- a/source4/dsdb/repl/drepl_service.c
+++ b/source4/dsdb/repl/drepl_service.c
@@ -351,6 +351,19 @@ static NTSTATUS drepl_take_FSMO_role(struct irpc_message *msg,
return NT_STATUS_OK;
}
+/**
+ * Called when the auth code wants us to try and replicate
+ * a users secrets
+ */
+static NTSTATUS drepl_trigger_repl_secret(struct irpc_message *msg,
+ struct drepl_trigger_repl_secret *r)
+{
+ /* we are not going to be sending a reply to this request */
+ msg->no_reply = true;
+ DEBUG(0,(__location__ ": got drepl_trigger_repl_secret with %s\n", r->in.user_dn));
+ return NT_STATUS_OK;
+}
+
/*
startup the dsdb replicator service task
*/
@@ -441,6 +454,7 @@ static void dreplsrv_task_init(struct task_server *task)
IRPC_REGISTER(task->msg_ctx, irpc, DREPLSRV_REFRESH, dreplsrv_refresh, service);
IRPC_REGISTER(task->msg_ctx, drsuapi, DRSUAPI_DSREPLICASYNC, drepl_replica_sync, service);
IRPC_REGISTER(task->msg_ctx, irpc, DREPL_TAKEFSMOROLE, drepl_take_FSMO_role, service);
+ IRPC_REGISTER(task->msg_ctx, irpc, DREPL_TRIGGER_REPL_SECRET, drepl_trigger_repl_secret, service);
messaging_register(task->msg_ctx, service, MSG_DREPL_ALLOCATE_RID, dreplsrv_allocate_rid);
}
diff --git a/source4/librpc/idl/irpc.idl b/source4/librpc/idl/irpc.idl
index 1639d49138..d6c4f84db9 100644
--- a/source4/librpc/idl/irpc.idl
+++ b/source4/librpc/idl/irpc.idl
@@ -173,4 +173,11 @@ import "misc.idl", "security.idl", "nbt.idl";
[in] uint32 role
);
+ /*
+ * message to tell the drepl server to initiate a REPL_SECRET
+ * replication of a users secrets
+ */
+ void drepl_trigger_repl_secret(
+ [in] astring user_dn
+ );
}