diff options
author | Andrew Tridgell <tridge@samba.org> | 2010-09-12 10:06:39 +1000 |
---|---|---|
committer | Andrew Tridgell <tridge@samba.org> | 2010-09-15 15:39:34 +1000 |
commit | 13a8745cae2b38c8071b182a4c020305c76e62b8 (patch) | |
tree | d0ab513cd0367dbc9c4f7bd65663883791a9d6f0 | |
parent | f6d85be52830d17dbf6e7b01bf854a49dccbc7f8 (diff) | |
download | samba-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.c | 52 | ||||
-rw-r--r-- | source4/dsdb/repl/drepl_service.c | 14 | ||||
-rw-r--r-- | source4/librpc/idl/irpc.idl | 7 |
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 + ); } |