Fix some bugs when testing opensds ansible
[stor4nfv.git] / src / ceph / src / rgw / rgw_ldap.cc
1 // -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
2 // vim: ts=8 sw=2 smarttab
3
4 #include "rgw_ldap.h"
5
6 #include "common/ceph_context.h"
7 #include "common/common_init.h"
8 #include "common/dout.h"
9 #include "common/safe_io.h"
10 #include <boost/algorithm/string.hpp>
11
12 #include "include/assert.h"
13
14 #define dout_subsys ceph_subsys_rgw
15
16 std::string parse_rgw_ldap_bindpw(CephContext* ctx)
17 {
18   string ldap_bindpw;
19   string ldap_secret = ctx->_conf->rgw_ldap_secret;
20
21   if (ldap_secret.empty()) {
22     ldout(ctx, 10)
23       << __func__ << " LDAP auth no rgw_ldap_secret file found in conf"
24       << dendl;
25     } else {
26       char bindpw[1024];
27       memset(bindpw, 0, 1024);
28       int pwlen = safe_read_file("" /* base */, ldap_secret.c_str(),
29                                  bindpw, 1023);
30     if (pwlen) {
31       ldap_bindpw = bindpw;
32       boost::algorithm::trim(ldap_bindpw);
33       if (ldap_bindpw.back() == '\n')
34         ldap_bindpw.pop_back();
35     }
36   }
37
38   return ldap_bindpw;
39 }
40
41 #if defined(HAVE_OPENLDAP)
42 namespace rgw {
43
44   int LDAPHelper::auth(const std::string uid, const std::string pwd) {
45     int ret;
46     std::string filter;
47     if (msad) {
48       filter = "(&(objectClass=user)(sAMAccountName=";
49       filter += uid;
50       filter += "))";
51     } else {
52       /* openldap */
53       if (searchfilter.empty()) {
54         /* no search filter provided in config, we construct our own */
55         filter = "(";
56         filter += dnattr;
57         filter += "=";
58         filter += uid;
59         filter += ")";
60       } else {
61         if (searchfilter.find("@USERNAME@") != std::string::npos) {
62         /* we need to substitute the @USERNAME@ placeholder */
63           filter = searchfilter;
64           filter.replace(searchfilter.find("@USERNAME@"), std::string("@USERNAME@").length(), uid);
65         } else {
66         /* no placeholder for username, so we need to append our own username filter to the custom searchfilter */
67           filter = "(&(";
68           filter += searchfilter;
69           filter += ")(";
70           filter += dnattr;
71           filter += "=";
72           filter += uid;
73           filter += "))";
74         }
75       }
76     }
77     ldout(g_ceph_context, 12)
78       << __func__ << " search filter: " << filter
79       << dendl;
80     char *attrs[] = { const_cast<char*>(dnattr.c_str()), nullptr };
81     LDAPMessage *answer = nullptr, *entry = nullptr;
82     bool once = true;
83
84     lock_guard guard(mtx);
85
86   retry_bind:
87     ret = ldap_search_s(ldap, searchdn.c_str(), LDAP_SCOPE_SUBTREE,
88                         filter.c_str(), attrs, 0, &answer);
89     if (ret == LDAP_SUCCESS) {
90       entry = ldap_first_entry(ldap, answer);
91       if (entry) {
92         char *dn = ldap_get_dn(ldap, entry);
93         ret = simple_bind(dn, pwd);
94         if (ret != LDAP_SUCCESS) {
95           ldout(g_ceph_context, 10)
96             << __func__ << " simple_bind failed uid=" << uid
97             << "ldap err=" << ret
98             << dendl;
99         }
100         ldap_memfree(dn);
101       } else {
102         ldout(g_ceph_context, 12)
103           << __func__ << " ldap_search_s no user matching uid=" << uid
104           << dendl;
105         ret = LDAP_NO_SUCH_ATTRIBUTE; // fixup result
106       }
107       ldap_msgfree(answer);
108     } else {
109       ldout(g_ceph_context, 5)
110         << __func__ << " ldap_search_s error uid=" << uid
111         << " ldap err=" << ret
112         << dendl;
113       /* search should never fail--try to rebind */
114       if (once) {
115         rebind();
116         once = false;
117         goto retry_bind;
118       }
119     }
120     return (ret == LDAP_SUCCESS) ? ret : -EACCES;
121   } /* LDAPHelper::auth */
122 }
123
124 #endif /* defined(HAVE_OPENLDAP) */