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