1 #include "utils.hpp"
2 
3 #include <arpa/inet.h>
4 #include <ldap.h>
5 #include <netdb.h>
6 
7 #include <boost/algorithm/string.hpp>
8 
9 #include <cstring>
10 #include <memory>
11 
12 namespace phosphor
13 {
14 namespace ldap
15 {
16 
isValidLDAPURI(const std::string & uri,const char * scheme)17 bool isValidLDAPURI(const std::string& uri, const char* scheme)
18 {
19     // Return false if the user tries to configure port 0
20     // This check is not done in line 42, because ldap_url_parse
21     // method internally converts port 0 to ldap port 389 and it
22     // will always return true (thus allowing the user to
23     // configure port 0)
24 
25     if (boost::algorithm::ends_with(uri, ":0"))
26     {
27         return false;
28     }
29 
30     LDAPURLDesc* ludpp = nullptr;
31     int res = LDAP_URL_ERR_BADURL;
32     res = ldap_url_parse(uri.c_str(), &ludpp);
33 
34     auto ludppCleanupFunc = [](LDAPURLDesc* ludpp) {
35         ldap_free_urldesc(ludpp);
36     };
37     std::unique_ptr<LDAPURLDesc, decltype(ludppCleanupFunc)> ludppPtr(
38         ludpp, ludppCleanupFunc);
39 
40     if (res != LDAP_URL_SUCCESS)
41     {
42         return false;
43     }
44     if (std::strcmp(scheme, ludppPtr->lud_scheme) != 0)
45     {
46         return false;
47     }
48     if (ludppPtr->lud_port < 0 || ludppPtr->lud_port > 65536)
49     {
50         return false;
51     }
52     addrinfo hints{};
53     addrinfo* servinfo = nullptr;
54     hints.ai_family = AF_UNSPEC;
55     hints.ai_socktype = SOCK_STREAM;
56     hints.ai_flags |= AI_CANONNAME;
57 
58     auto result = getaddrinfo(ludppPtr->lud_host, nullptr, &hints, &servinfo);
59     auto cleanupFunc = [](addrinfo* servinfo) { freeaddrinfo(servinfo); };
60     std::unique_ptr<addrinfo, decltype(cleanupFunc)> servinfoPtr(
61         servinfo, cleanupFunc);
62 
63     if (result)
64     {
65         return false;
66     }
67     return true;
68 }
69 
70 } // namespace ldap
71 } // namespace phosphor
72