auth4: add a "winbind_rodc" backend
authorStefan Metzmacher <metze@samba.org>
Thu, 23 Mar 2017 10:57:49 +0000 (11:57 +0100)
committerStefan Metzmacher <metze@samba.org>
Fri, 24 Mar 2017 10:57:10 +0000 (11:57 +0100)
This is only active on a RODC.

The background for this is that we currently only ever
call the "winbind" module when we're an RODC,
otherwise everything is catched by "sam_ignoredomain" before.

BUG: https://bugzilla.samba.org/show_bug.cgi?id=2976
BUG: https://bugzilla.samba.org/show_bug.cgi?id=12709

Signed-off-by: Stefan Metzmacher <metze@samba.org>
Reviewed-by: Andrew Bartlett <abartlet@samba.org>
source4/auth/ntlm/auth_winbind.c

index 6f1976de723ef3805177b379326c43dacb9345c6..82a71f3bd133f541e824b02be7a0f40f44a28a30 100644 (file)
@@ -30,6 +30,7 @@
 #include "nsswitch/libwbclient/wbclient.h"
 #include "auth/auth_sam_reply.h"
 #include "libcli/security/security.h"
+#include "dsdb/samdb/samdb.h"
 
 _PUBLIC_ NTSTATUS auth4_winbind_init(void);
 
@@ -45,6 +46,48 @@ static NTSTATUS winbind_want_check(struct auth_method_context *ctx,
        return NT_STATUS_OK;
 }
 
+static NTSTATUS winbind_rodc_want_check(struct auth_method_context *ctx,
+                                       TALLOC_CTX *mem_ctx,
+                                       const struct auth_usersupplied_info *user_info)
+{
+       int ret;
+       bool am_rodc;
+
+       if (!user_info->mapped.account_name || !*user_info->mapped.account_name) {
+               return NT_STATUS_NOT_IMPLEMENTED;
+       }
+
+       if (ctx->auth_ctx->sam_ctx == NULL) {
+               DBG_ERR("ctx->auth_ctx->sam_ctx == NULL, don't check.\n");
+               return NT_STATUS_NOT_IMPLEMENTED;
+       }
+
+       ret = samdb_rodc(ctx->auth_ctx->sam_ctx, &am_rodc);
+       if (ret != LDB_SUCCESS) {
+               DBG_ERR("samdb_rodc() failed %d %s, don't check.\n",
+                       ret, ldb_errstring(ctx->auth_ctx->sam_ctx));
+               return NT_STATUS_NOT_IMPLEMENTED;
+       }
+
+       if (!am_rodc) {
+               /*
+                * We don't support trusts yet and we
+                * don't want to add them using the
+                * semi-async irpc call that uses
+                * a nested event loop.
+                */
+               return NT_STATUS_NOT_IMPLEMENTED;
+       }
+
+       /*
+        * We're a RODC, so we forward the request to our winbind.
+        * As the RODC is not yet production ready anyway, we keep
+        * the semi-async behavior with nested event loops in order
+        * to keep autobuild happy.
+        */
+       return NT_STATUS_OK;
+}
+
 struct winbind_check_password_state {
        struct winbind_SamLogon req;
 };
@@ -258,6 +301,12 @@ static const struct auth_operations winbind_ops = {
        .check_password = winbind_check_password
 };
 
+static const struct auth_operations winbind_rodc_ops = {
+       .name           = "winbind_rodc",
+       .want_check     = winbind_rodc_want_check,
+       .check_password = winbind_check_password
+};
+
 static const struct auth_operations winbind_wbclient_ops = {
        .name           = "winbind_wbclient",
        .want_check     = winbind_want_check,
@@ -274,6 +323,12 @@ _PUBLIC_ NTSTATUS auth4_winbind_init(void)
                return ret;
        }
 
+       ret = auth_register(&winbind_rodc_ops);
+       if (!NT_STATUS_IS_OK(ret)) {
+               DEBUG(0,("Failed to register 'winbind_rodc' auth backend!\n"));
+               return ret;
+       }
+
        ret = auth_register(&winbind_wbclient_ops);
        if (!NT_STATUS_IS_OK(ret)) {
                DEBUG(0,("Failed to register 'winbind_wbclient' auth backend!\n"));