]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
rgw ldap: fix ldap bindpw parsing 9527/head
authorMatt Benjamin <mbenjamin@redhat.com>
Mon, 6 Jun 2016 20:19:17 +0000 (16:19 -0400)
committerMatt Benjamin <mbenjamin@redhat.com>
Mon, 6 Jun 2016 21:50:32 +0000 (17:50 -0400)
Also add additional LDAP debugging output at 0, 10, and 15 to make
troubleshooting easier.

Fixes DN search issue using QE configuration of MS AD.

Signed-off-by: Matt Benjamin <mbenjamin@redhat.com>
src/rgw/librgw.cc
src/rgw/rgw_ldap.cc
src/rgw/rgw_ldap.h
src/rgw/rgw_rest_s3.cc
src/test/test_rgw_ldap.cc

index 37414fc831dbae453bc89ae30ce713aa34ed3bad..c47612907542eff0e84e83d2036c6763c02fdc11 100644 (file)
@@ -52,6 +52,7 @@
 #include <string.h>
 #include <mutex>
 
+
 #define dout_subsys ceph_subsys_rgw
 
 bool global_stop = false;
@@ -469,9 +470,10 @@ namespace rgw {
     const string& ldap_searchdn = store->ctx()->_conf->rgw_ldap_searchdn;
     const string& ldap_dnattr =
       store->ctx()->_conf->rgw_ldap_dnattr;
+    std::string ldap_bindpw = parse_rgw_ldap_bindpw(store->ctx());
 
-    ldh = new rgw::LDAPHelper(ldap_uri, ldap_binddn, ldap_searchdn,
-                             ldap_dnattr);
+    ldh = new rgw::LDAPHelper(ldap_uri, ldap_binddn, ldap_bindpw.c_str(),
+                             ldap_searchdn, ldap_dnattr);
     ldh->init();
     ldh->bind();
 
index ac420e3ee8ab82b8f9977cd2cb19b29af0c80efd..6cca3b8af1938639dc62f2c5d87cd23e343df3e5 100644 (file)
@@ -2,3 +2,38 @@
 // vim: ts=8 sw=2 smarttab
 
 #include "rgw_ldap.h"
+
+#include "common/ceph_context.h"
+#include "common/common_init.h"
+#include "common/dout.h"
+#include "common/safe_io.h"
+#include <boost/algorithm/string.hpp>
+
+#include "include/assert.h"
+
+#define dout_subsys ceph_subsys_rgw
+
+std::string parse_rgw_ldap_bindpw(CephContext* ctx)
+{
+  string ldap_bindpw;
+  string ldap_secret = ctx->_conf->rgw_ldap_secret;
+
+  if (ldap_secret.empty()) {
+    ldout(ctx, 10)
+      << __func__ << " LDAP auth no rgw_ldap_secret file found in conf"
+      << dendl;
+    } else {
+      char bindpw[1024];
+      memset(bindpw, 0, 1024);
+      int pwlen = safe_read_file("" /* base */, ldap_secret.c_str(),
+                                bindpw, 1023);
+    if (pwlen) {
+      ldap_bindpw = bindpw;
+      boost::algorithm::trim(ldap_bindpw);
+      if (ldap_bindpw.back() == '\n')
+       ldap_bindpw.pop_back();
+    }
+  }
+
+  return std::move(ldap_bindpw);
+}
index 02eb61e1f4b0b36078ecec702117e6b797c348b6..b29e33adc8adc56cb589073fc34d1f2c06def4ee 100644 (file)
@@ -23,27 +23,38 @@ namespace rgw {
   {
     std::string uri;
     std::string binddn;
+    std::string bindpw;
     std::string searchdn;
     std::string dnattr;
     LDAP *ldap;
+    bool msad = false; /* TODO: possible future specialization */
 
   public:
-    LDAPHelper(std::string _uri, std::string _binddn, std::string _searchdn,
-             std::string _dnattr)
-      : uri(std::move(_uri)), binddn(std::move(_binddn)), searchdn(_searchdn),
-       dnattr(_dnattr), ldap(nullptr) {
+    LDAPHelper(std::string _uri, std::string _binddn, std::string _bindpw,
+              std::string _searchdn, std::string _dnattr)
+      : uri(std::move(_uri)), binddn(std::move(_binddn)),
+       bindpw(std::move(_bindpw)), searchdn(_searchdn), dnattr(_dnattr),
+       ldap(nullptr) {
       // nothing
     }
 
     int init() {
       int ret;
       ret = ldap_initialize(&ldap, uri.c_str());
+      if (ret == LDAP_SUCCESS) {
+       unsigned long ldap_ver = LDAP_VERSION3;
+       ret = ldap_set_option(ldap, LDAP_OPT_PROTOCOL_VERSION,
+                             (void*) &ldap_ver);
+      }
+      if (ret == LDAP_SUCCESS) {
+       ret = ldap_set_option(ldap, LDAP_OPT_REFERRALS, LDAP_OPT_OFF); 
+      }
       return (ret == LDAP_SUCCESS) ? ret : -EINVAL;
     }
 
     int bind() {
       int ret;
-      ret = ldap_simple_bind_s(ldap, nullptr, nullptr);
+      ret = ldap_simple_bind_s(ldap, binddn.c_str(), bindpw.c_str());
       return (ret == LDAP_SUCCESS) ? ret : -EINVAL;
     }
 
@@ -60,11 +71,18 @@ namespace rgw {
     int auth(const std::string uid, const std::string pwd) {
       int ret;
       std::string filter;
-      filter = "(";
-      filter += dnattr;
-      filter += "=";
-      filter += uid;
-      filter += ")";
+      if (msad) {
+       filter = "(&(objectClass=user)(sAMAccountName=";
+       filter += uid;
+       filter += "))";
+      } else {
+       /* openldap */
+       filter = "(";
+       filter += dnattr;
+       filter += "=";
+       filter += uid;
+       filter += ")";
+      }
       char *attrs[] = { const_cast<char*>(dnattr.c_str()), nullptr };
       LDAPMessage *answer = nullptr, *entry = nullptr;
       ret = ldap_search_s(ldap, searchdn.c_str(), LDAP_SCOPE_SUBTREE,
@@ -95,8 +113,8 @@ namespace rgw {
   class LDAPHelper
   {
   public:
-    LDAPHelper(std::string _uri, std::string _binddn, std::string _searchdn,
-             std::string _dnattr)
+    LDAPHelper(std::string _uri, std::string _binddn, std::string _bindpw,
+              std::string _searchdn, std::string _dnattr)
       {}
 
     int init() {
@@ -117,7 +135,17 @@ namespace rgw {
 
 
 #endif /* HAVE_OPENLDAP */
-
+  
 } /* namespace rgw */
 
+#include "common/ceph_context.h"
+#include "common/common_init.h"
+#include "common/dout.h"
+#include "common/safe_io.h"
+#include <boost/algorithm/string.hpp>
+
+#include "include/assert.h"
+
+std::string parse_rgw_ldap_bindpw(CephContext* ctx);
+
 #endif /* RGW_LDAP_H */
index 79bf2df9a0d47cc75dca6a071cd0e9ae18e9cff4..81cc123821d34d13bcdd689a186d1a690dfdb9df 100644 (file)
@@ -8,6 +8,8 @@
 #include "common/Formatter.h"
 #include "common/utf8.h"
 #include "common/ceph_json.h"
+#include "common/safe_io.h"
+#include <boost/algorithm/string.hpp>
 
 #include "rgw_rest.h"
 #include "rgw_rest_s3.h"
@@ -1600,10 +1602,32 @@ int RGWPostObj_ObjStore_S3::get_policy()
          s->perm_mask = RGW_PERM_FULL_CONTROL;
        }
       } else if (store->ctx()->_conf->rgw_s3_auth_use_ldap &&
-               store->ctx()->_conf->rgw_ldap_uri.empty()) {
+                (! store->ctx()->_conf->rgw_ldap_uri.empty())) {
+
+       ldout(store->ctx(), 15)
+         << __func__ << " LDAP auth uri="
+         << store->ctx()->_conf->rgw_ldap_uri
+         << dendl;
+
        RGWToken token{from_base64(s3_access_key)};
+       if (! token.valid())
+         return -EACCES;
+
        rgw::LDAPHelper *ldh = RGW_Auth_S3::get_ldap_ctx(store);
-       if ((! token.valid()) || ldh->auth(token.id, token.key) != 0)
+       if (unlikely(!ldh)) {
+         ldout(store->ctx(), 0)
+           << __func__ << " RGW_Auth_S3::get_ldap_ctx() failed"
+           << dendl;
+         return -EACCES;
+       }
+
+       ldout(store->ctx(), 10)
+         << __func__ << " try LDAP auth uri="
+         << store->ctx()->_conf->rgw_ldap_uri
+         << " token.id=" << token.id
+         << dendl;
+
+       if (ldh->auth(token.id, token.key) != 0)
          return -EACCES;
 
        /* ok, succeeded */
@@ -2922,9 +2946,10 @@ void RGW_Auth_S3::init_impl(RGWRados* store)
   const string& ldap_searchdn = store->ctx()->_conf->rgw_ldap_searchdn;
   const string& ldap_dnattr =
     store->ctx()->_conf->rgw_ldap_dnattr;
+  std::string ldap_bindpw = parse_rgw_ldap_bindpw(store->ctx());
 
-  ldh = new rgw::LDAPHelper(ldap_uri, ldap_binddn, ldap_searchdn,
-                           ldap_dnattr);
+  ldh = new rgw::LDAPHelper(ldap_uri, ldap_binddn, ldap_bindpw,
+                           ldap_searchdn, ldap_dnattr);
 
   ldh->init();
   ldh->bind();
@@ -3720,29 +3745,45 @@ int RGW_Auth_S3::authorize_v2(RGWRados *store, struct req_state *s)
 
     RGW_Auth_S3::init(store);
 
+    ldout(store->ctx(), 15)
+      << __func__ << " LDAP auth uri="
+      << store->ctx()->_conf->rgw_ldap_uri
+      << dendl;
+
     RGWToken token{from_base64(auth_id)};
-    if ((! token.valid()) || ldh->auth(token.id, token.key) != 0)
+
+    if (! token.valid())
       external_auth_result = -EACCES;
     else {
-      /* ok, succeeded */
-      external_auth_result = 0;
+      ldout(store->ctx(), 10)
+       << __func__ << " try LDAP auth uri="
+       << store->ctx()->_conf->rgw_ldap_uri
+       << " token.id=" << token.id
+       << dendl;
+
+      if (ldh->auth(token.id, token.key) != 0)
+       external_auth_result = -EACCES;
+      else {
+       /* ok, succeeded */
+       external_auth_result = 0;
 
-      /* create local account, if none exists */
-      s->user->user_id = token.id;
-      s->user->display_name = token.id; // cn?
-      int ret = rgw_get_user_info_by_uid(store, s->user->user_id, *(s->user));
-      if (ret < 0) {
-       ret = rgw_store_user_info(store, *(s->user), nullptr, nullptr,
-                                 real_time(), true);
+       /* create local account, if none exists */
+       s->user->user_id = token.id;
+       s->user->display_name = token.id; // cn?
+       int ret = rgw_get_user_info_by_uid(store, s->user->user_id, *(s->user));
        if (ret < 0) {
-         dout(10) << "NOTICE: failed to store new user's info: ret=" << ret
-                  << dendl;
+         ret = rgw_store_user_info(store, *(s->user), nullptr, nullptr,
+                                   real_time(), true);
+         if (ret < 0) {
+           dout(10) << "NOTICE: failed to store new user's info: ret=" << ret
+                    << dendl;
+         }
        }
-      }
 
       /* set request perms */
       s->perm_mask = RGW_PERM_FULL_CONTROL;
-    } /* success */
+      } /* success */
+    } /* token */
   } /* ldap */
 
   /* keystone failed (or not enabled); check if we want to use rados backend */
index 8cbba51c5b77abbfe217184b671a009774047eb1..8a08d8fd52466ad7718f9306ecf7d0a766a6e8a7 100644 (file)
@@ -43,10 +43,12 @@ namespace {
 
   string ldap_uri = "ldaps://f23-kdc.rgw.com";
   string ldap_binddn = "uid=admin,cn=users,cn=accounts,dc=rgw,dc=com";
+  string ldap_bindpw = "supersecret";
   string ldap_searchdn = "cn=users,cn=accounts,dc=rgw,dc=com";
   string ldap_dnattr = "uid";
 
-  rgw::LDAPHelper ldh(ldap_uri, ldap_binddn, ldap_searchdn, ldap_dnattr);
+  rgw::LDAPHelper ldh(ldap_uri, ldap_binddn, ldap_bindpw, ldap_searchdn,
+                     ldap_dnattr);
 
 } /* namespace */