Hello again,

On Fri, 2019-07-26 at 14:08 +0200, Jakub Hrozek wrote:
> On Fri, Jul 26, 2019 at 12:50:16PM +0200, Christian Lamparter wrote:
> > I'm currently setting up sssd (Debian 1.16.3) on Debian Buster 10.0
> > and I ran into a problem that I was able to trace down to the domain
> > permission/security settings that placed the users into a special OU
> > that machine accounts can't read.
> > 
> > First a bit of background:
> > Currently, there's a way to use winbind + friends in order to join
> > and auth users on the domain. But due to limitations (unreliable
> > no home directories, gid/uid mapping issues, etc.), I want to give
> > sssd a try and I tested this with both of the current Debian sssd
> > version 1.16.3 and 2.2.0-4 (from unstable / sid / rolling release).
> > 
> > I successfully used the "realm" utility to discover and setup the
> > sssd.conf
> > ===
> > # realm discover -v DOMAIN (named changed)
> >  * Resolving: _ldap._tcp.domain
> >  * Performing LDAP DSE lookup on: 1x.y.z.1
> >  * Performing LDAP DSE lookup on: 1z.a.b.c
> >  * Performing LDAP DSE lookup on: 1d.e.f.g
> >  * Successfully discovered: domain
> > domain
> >   type: kerberos
> >   realm-name: DOMAIN
> >   domain-name: domain
> >   configured: no
> >   server-software: active-directory
> >   client-software: sssd
> >   required-package: sssd-tools
> >   required-package: sssd
> >   required-package: libnss-sss
> >   required-package: libpam-sss
> >   required-package: adcli
> >   required-package: samba-common-bin
> > 
> > # realm join -v -U me@DOMAIN domain
> >  * Resolving: _ldap._tcp.domain
> >  * Performing LDAP DSE lookup on: 1x.y.z.1
> >  * Performing LDAP DSE lookup on: 1z.a.b.c
> >  * Performing LDAP DSE lookup on: 1d.e.f.g
> >  * Successfully discovered: domain
> > Password for me@DOMAIN: *******
> > * Unconditionally checking packages
> >  * Resolving required packages
> >  [...]
> >  * Generated 120 character computer password
> >  * Using keytab: FILE:/etc/krb5.keytab
> >  * Found computer account for COMPUTER
> >  * Set computer password
> >  * Retrieved kvno '14' for computer account in directory: ...
> >   * Modifying computer account: userAccountControl
> >  * Modifying computer account: operatingSystemVersion,
> > operatingSystemServicePack
> >  * Modifying computer account: userPrincipalName
> >  * Cleared old entries from keytab: FILE:/etc/krb5.keytab
> >  * Discovered which keytab salt to use
> >  * Added the entries to the keytab: ...
> >  * /usr/sbin/update-rc.d sssd enable
> >  * /usr/sbin/service sssd restart
> >  * Successfully enrolled machine in realm
> > ===
> > 
> > /etc/sssd/sssd.conf
> > 
> > [sssd]
> > domains = domain
> > config_file_version = 2
> > services = nss, pam, ifp # added ifp
> > 
> > [domain/domain]
> > ad_domain = domain
> > krb5_realm = DOMAIN
> > realmd_tags = manages-system joined-with-adcli
> > cache_credentials = True
> > id_provider = ad
> > krb5_store_password_if_offline = True
> > default_shell = /bin/bash
> > ldap_id_mapping = True
> > use_fully_qualified_names = True
> > fallback_homedir = /home/%u@%d
> > access_provider = ad
> > ===
> > 
> > klist shows a valid ticket and everything seemed to be working.
> > 
> > 
> > But when I was trying to login (yes, I made sure that my time is synced
> > and I made sure /etc/nssswitch.conf was correct) with my "me@domain"
> > login it never worked. I tried also id me@domain and sssctl (had to add
> > ifp, seems like realm doesn't add) but it wasn't working for my login.
> > 
> > After trying a lot of different combinations with different id,
> > auth_providers and ldap I discovered that the AD Server is setup
> > in such a way (probably due to DSVGO) that the Domain-PC Accounts
> > are not allowed to read from the OU where all the staff users are
> > placed. And indeed, when I copied the exact search query from the
> > sssd_domain log with debug-level 7 and instructed
> > ldapsearch to use GSSAPI with the Domain-PC ticket I always got a
> > "not found". However, when I used simple bind with "me@domain" +
> > password auth I got the request worked.
> > 
> > So, I wonder if it is possible to extend sssd in such a way that
> > id lookups could be performed with the provided either a provided
> > user secret instead of the machine secret?
> 
> Sorry, not right now. The AD provider presumes that a keytab is used.
> But there's nothing saying that the keytab must contain a machine
> account principal. I guess you could create a keytab for some user, even
> the one you used for the simple bind authentication and then instruct
> sssd with the help of ldap_sasl_authid to use your custom principal (by
> default sssd tries to search for principal based on the host name).
> 
> btw as a coincidence, I was looking into extending the IPA provider (which
> has pretty much the same issues as the AD provider) so that a client
> side certificate could be used. So in future this might also be
> possible, but not right now..

Ok, thanks. I got it working. what I did was to patch (see below, it was
for 1.16.3. But yeah I'll stick around since this has limitations) the
sdap_auth_send by adding another state parameter that can overwrite 
sasl_mech logic and instruct the code to instead use the simple ldap bind
with a ldap_default_bind_dn and ldap_default_authtok for the id lookups.
(sort of like the binddn/bindpw that nslcd has for (all) lookups).

(The ldap_sasl_authid did OK, but on reboot it broke. From what I can tell,
it has to do with Debian decision to make /tmp a ramfs and some secrets
get are stored there.)

Anyway onwards!

I can finally use login and friends with a twist. Just after the bash
banner there's now a "Invalid user name" (I assume it has something
to do with the "@domain.dc" in the user login, as well as the borked
full user name (it's a guid instead of a name). But ls -al and id,
getent passwd are all working. As well as the groups)

Huge Thanks!
Christian

---
From 2a0e3a178d9099b55f2d9c01c4aeb67c8bb1e050 Mon Sep 17 00:00:00 2001
From: Christian Lamparter <christian.lampar...@isd.uni-stuttgart.de>
Date: Tue, 30 Jul 2019 18:24:30 +0200
Subject: [PATCH] ad: make it possible to enumerate users behind locked OUs

This patch adds a switch to sdap_auth_send() which allows
it to fall back to the simple bind over SASL. This change
makes it possible to mitigate specific permission policy
that prevents machine accounts in this active directory
to directly enumerate the real users.
---
 src/providers/ipa/ipa_auth.c               |  4 ++--
 src/providers/ldap/ldap_auth.c             |  5 +++--
 src/providers/ldap/sdap_async.h            |  5 +++--
 src/providers/ldap/sdap_async_connection.c | 19 +++++++++++++++----
 src/providers/ldap/sdap_id_op.c            |  2 +-
 src/providers/ldap/sdap_online_check.c     |  2 +-
 6 files changed, 25 insertions(+), 12 deletions(-)

diff --git a/src/providers/ipa/ipa_auth.c b/src/providers/ipa/ipa_auth.c
index 1bd0177..e56a288 100644
--- a/src/providers/ipa/ipa_auth.c
+++ b/src/providers/ipa/ipa_auth.c
@@ -302,7 +302,7 @@ static void ipa_pam_auth_handler_flag_done(struct 
tevent_req *subreq)
                                        sdap_auth_ctx->opts,
                                        sdap_auth_ctx->be,
                                        sdap_auth_ctx->service,
-                                       true, CON_TLS_ON, true);
+                                       true, CON_TLS_ON, true, false);
         if (subreq == NULL) {
             state->pd->pam_status = PAM_SYSTEM_ERR;
             goto done;
@@ -362,7 +362,7 @@ static void ipa_pam_auth_handler_connect_done(struct 
tevent_req *subreq)
                              SDAP_OPT_TIMEOUT);
 
     subreq = sdap_auth_send(state, state->ev, sh, NULL, NULL, dn,
-                            state->pd->authtok, timeout);
+                            state->pd->authtok, timeout, false);
     if (subreq == NULL) {
         goto done;
     }
diff --git a/src/providers/ldap/ldap_auth.c b/src/providers/ldap/ldap_auth.c
index d40bc94..836bff6 100644
--- a/src/providers/ldap/ldap_auth.c
+++ b/src/providers/ldap/ldap_auth.c
@@ -693,7 +693,8 @@ static struct tevent_req *auth_connect_send(struct 
tevent_req *req)
     subreq = sdap_cli_connect_send(state, state->ev, state->ctx->opts,
                                    state->ctx->be,
                                    state->sdap_service, false,
-                                   use_tls ? CON_TLS_ON : CON_TLS_OFF, false);
+                                   use_tls ? CON_TLS_ON : CON_TLS_OFF, false,
+                                   false);
 
     if (subreq == NULL) {
         tevent_req_error(req, ENOMEM);
@@ -787,7 +788,7 @@ static void auth_do_bind(struct tevent_req *req)
                             NULL, NULL, state->dn,
                             state->authtok,
                             dp_opt_get_int(state->ctx->opts->basic,
-                                           SDAP_OPT_TIMEOUT));
+                                           SDAP_OPT_TIMEOUT), false);
     if (!subreq) {
         tevent_req_error(req, ENOMEM);
         return;
diff --git a/src/providers/ldap/sdap_async.h b/src/providers/ldap/sdap_async.h
index 6d09aca..c4e0043 100644
--- a/src/providers/ldap/sdap_async.h
+++ b/src/providers/ldap/sdap_async.h
@@ -145,7 +145,8 @@ struct tevent_req *sdap_auth_send(TALLOC_CTX *memctx,
                                   const char *sasl_user,
                                   const char *user_dn,
                                   struct sss_auth_token *authtok,
-                                  int simple_bind_timeout);
+                                  int simple_bind_timeout,
+                                  bool force_simple);
 
 errno_t sdap_auth_recv(struct tevent_req *req,
                        TALLOC_CTX *memctx,
@@ -196,7 +197,7 @@ struct tevent_req *sdap_cli_connect_send(TALLOC_CTX *memctx,
                                          struct sdap_service *service,
                                          bool skip_rootdse,
                                          enum connect_tls force_tls,
-                                         bool skip_auth);
+                                         bool skip_auth, bool use_simple);
 int sdap_cli_connect_recv(struct tevent_req *req,
                           TALLOC_CTX *memctx,
                           bool *can_retry,
diff --git a/src/providers/ldap/sdap_async_connection.c 
b/src/providers/ldap/sdap_async_connection.c
index 8aacd67..e51a9ee 100644
--- a/src/providers/ldap/sdap_async_connection.c
+++ b/src/providers/ldap/sdap_async_connection.c
@@ -1308,15 +1308,22 @@ struct tevent_req *sdap_auth_send(TALLOC_CTX *memctx,
                                   const char *sasl_user,
                                   const char *user_dn,
                                   struct sss_auth_token *authtok,
-                                  int simple_bind_timeout)
+                                  int simple_bind_timeout,
+                                  bool force_simple)
 {
     struct tevent_req *req, *subreq;
     struct sdap_auth_state *state;
+    bool override_mech = false;
 
     req = tevent_req_create(memctx, &state, struct sdap_auth_state);
     if (!req) return NULL;
 
-    if (sasl_mech) {
+    if (sasl_mech && force_simple && user_dn && strlen(user_dn)) {
+        DEBUG(SSSDBG_TRACE_FUNC,, "Overwrite sasl_mech to force simple 
bind.\n");
+        override_mech = true;
+    }
+
+    if (sasl_mech && !override_mech) {
         state->is_sasl = true;
         subreq = sasl_bind_send(state, ev, sh, sasl_mech, sasl_user, NULL);
         if (!subreq) {
@@ -1432,6 +1439,7 @@ struct sdap_cli_connect_state {
 
     enum connect_tls force_tls;
     bool do_auth;
+    bool force_simple;
     bool use_tls;
 };
 
@@ -1487,7 +1495,8 @@ struct tevent_req *sdap_cli_connect_send(TALLOC_CTX 
*memctx,
                                          struct sdap_service *service,
                                          bool skip_rootdse,
                                          enum connect_tls force_tls,
-                                         bool skip_auth)
+                                         bool skip_auth,
+                                         bool force_simple)
 {
     struct sdap_cli_connect_state *state;
     struct tevent_req *req;
@@ -1505,6 +1514,7 @@ struct tevent_req *sdap_cli_connect_send(TALLOC_CTX 
*memctx,
     state->use_rootdse = !skip_rootdse;
     state->force_tls = force_tls;
     state->do_auth = !skip_auth;
+    state->force_simple = force_simple;
 
     ret = sdap_cli_resolve_next(req);
     if (ret) {
@@ -1881,7 +1891,8 @@ static void sdap_cli_auth_step(struct tevent_req *req)
                                               SDAP_SASL_AUTHID),
                             user_dn, authtok,
                             dp_opt_get_int(state->opts->basic,
-                                           SDAP_OPT_TIMEOUT));
+                                           SDAP_OPT_TIMEOUT),
+                            state->force_simple);
     if (!subreq) {
         tevent_req_error(req, ENOMEM);
         return;
diff --git a/src/providers/ldap/sdap_id_op.c b/src/providers/ldap/sdap_id_op.c
index e7ff546..c7485f7 100644
--- a/src/providers/ldap/sdap_id_op.c
+++ b/src/providers/ldap/sdap_id_op.c
@@ -495,7 +495,7 @@ static int sdap_id_op_connect_step(struct tevent_req *req)
                                    state->id_conn->id_ctx->opts,
                                    state->id_conn->id_ctx->be,
                                    state->id_conn->service, false,
-                                   CON_TLS_DFL, false);
+                                   CON_TLS_DFL, false, true);
 
     if (!subreq) {
         ret = ENOMEM;
diff --git a/src/providers/ldap/sdap_online_check.c 
b/src/providers/ldap/sdap_online_check.c
index f721a5f..68b037a 100644
--- a/src/providers/ldap/sdap_online_check.c
+++ b/src/providers/ldap/sdap_online_check.c
@@ -54,7 +54,7 @@ static struct tevent_req *sdap_online_check_send(TALLOC_CTX 
*mem_ctx,
 
     subreq = sdap_cli_connect_send(state, be_ctx->ev, id_ctx->opts, be_ctx,
                                    id_ctx->conn->service, false,
-                                   CON_TLS_DFL, false);
+                                   CON_TLS_DFL, false, false);
     if (subreq == NULL) {
         ret = ENOMEM;
         goto immediately;
-- 
2.20.1
_______________________________________________
sssd-users mailing list -- sssd-users@lists.fedorahosted.org
To unsubscribe send an email to sssd-users-le...@lists.fedorahosted.org
Fedora Code of Conduct: 
https://docs.fedoraproject.org/en-US/project/code-of-conduct/
List Guidelines: https://fedoraproject.org/wiki/Mailing_list_guidelines
List Archives: 
https://lists.fedorahosted.org/archives/list/sssd-users@lists.fedorahosted.org

Reply via email to