43#define EDUI_PROGRAM_NAME "ext_edirectory_userip_acl"
44#define EDUI_PROGRAM_VERSION "2.1"
59#ifdef HAVE_ARPA_INET_H
62#define LDAP_DEPRECATED 1
72#ifdef HAVE_SYS_SOCKET_H
73#include <sys/socket.h>
75#ifdef HAVE_NETINET_IN_H
76#include <netinet/in.h>
79#ifdef HELPER_INPUT_BUFFER
80#define EDUI_MAXLEN HELPER_INPUT_BUFFER
82#define EDUI_MAXLEN 4096
96# define LDAP_AUTH_TLS ((ber_tag_t) 0xb3U)
101#define EDUI_MODE_INIT 0x01
102#define EDUI_MODE_DEBUG 0x02
103#define EDUI_MODE_TLS 0x04
104#define EDUI_MODE_IPV4 0x08
105#define EDUI_MODE_IPV6 0x10
106#define EDUI_MODE_GROUP 0x20
107#define EDUI_MODE_PERSIST 0x40
108#define EDUI_MODE_KILL 0x80
127#define LDAP_INIT_S 0x0001
128#define LDAP_OPEN_S 0x0002
129#define LDAP_BIND_S 0x0004
130#define LDAP_SEARCH_S 0x0008
131#define LDAP_VAL_S 0x0010
132#define LDAP_CLOSE_S 0x0020
133#define LDAP_PERSIST_S 0x0040
134#define LDAP_IDLE_S 0x0080
135#define LDAP_SSL_S 0x0100
136#define LDAP_TLS_S 0x0200
137#define LDAP_IPV4_S 0x0400
138#define LDAP_IPV6_S 0x0800
141#define LDAP_ERR_NULL -1
142#define LDAP_ERR_POINTER -2
143#define LDAP_ERR_PARAM -3
144#define LDAP_ERR_INIT -4
145#define LDAP_ERR_OPEN -5
146#define LDAP_ERR_CONNECT -6
147#define LDAP_ERR_BIND -7
148#define LDAP_ERR_SEARCHED -8
149#define LDAP_ERR_NOT_SEARCHED -9
150#define LDAP_ERR_INVALID -10
151#define LDAP_ERR_OOB -11
152#define LDAP_ERR_PERSIST -12
153#define LDAP_ERR_DATA -13
154#define LDAP_ERR_NOTFOUND -14
155#define LDAP_ERR_OTHER -15
156#define LDAP_ERR_FAILED -16
157#define LDAP_ERR_SUCCESS -17
184static int StringSplit(
char *,
char,
char *,
size_t);
185static int BinarySplit(
void *,
size_t,
char,
void *,
size_t);
204const char *
search_attrib[] = {
"cn",
"uid",
"networkAddress",
"groupMembership",
nullptr };
229 if (msg ==
nullptr) {
231 debug(
"local_printfx() FAILURE, no data.\n");
236 x = vsnprintf(dbuf, sz, msg, ap);
245 debug(
"local_printfx() FAILURE: %zu\n", x);
262 if ((In_Str ==
nullptr) || (Out_Str ==
nullptr))
265 size_t In_Len = strlen(In_Str) + 1;
269 while (*p != chr && *p !=
'\0' && (In_Str+In_Len) > p) {
273 size_t i = (p-In_Str);
280 memset(Out_Str+i, 0, Out_Sz-i);
282 memcpy(Out_Str, In_Str, i);
290 memset(In_Str, 0, In_Len);
297 memmove(In_Str, p, In_Len-i);
299 memset(In_Str+In_Len-i, 0, i);
311BinarySplit(
void *In_Obj,
size_t In_Sz,
char chr,
void *Out_Obj,
size_t Out_Sz)
314 if ((In_Obj ==
nullptr) || (Out_Obj ==
nullptr))
317 char *in =
static_cast<char*
>(In_Obj);
318 char *out =
static_cast<char*
>(Out_Obj);
321 char *p =
static_cast<char*
>(In_Obj);
322 while (*p != chr && (in+In_Sz) > p) {
333 memset(out+i, 0, Out_Sz-i);
335 memcpy(Out_Obj, In_Obj, i);
343 memset(In_Obj, 0, In_Sz);
350 memmove(In_Obj, p, In_Sz-i);
352 memset(in+In_Sz-i, 0, i);
370 local_printfx(
" -H <host> -p <port> [-Z] [-P] [-v 3] -b <basedn> -s <scope>\n");
371 local_printfx(
" -D <binddn> -W <bindpass> -F <search-filter> [-G] \n\n");
373 local_printfx(
" -4 : Force Addresses to be in IPv4 (127.0.0.1 format).\n");
374 local_printfx(
" -6 : Force Addresses to be in IPv6 (::1 format).\n");
375 local_printfx(
" -H <host> : Specify hostname/ip of server.\n");
376 local_printfx(
" -p <port> : Specify port number. (Range 1-65535)\n");
379 local_printfx(
" -t <sec> : Timeout factor for persistent connections. (Default is 60 sec, set to 0 for never timeout)\n");
380 local_printfx(
" -v <1,2,3> : Set LDAP version to 1, 2, or 3.\n");
381 local_printfx(
" -b <base> : Specify Base DN. (ie. \"o=ORG\")\n");
382 local_printfx(
" -s <scope> : Specify LDAP Search Scope (base, one, sub; defaults to 'one').\n");
383 local_printfx(
" -D <dn> : Specify Binding DN. (ie. cn=squid,o=ORG)\n");
385 local_printfx(
" -u <attrib> : Set userid attribute (Defaults to \"cn\").\n");
386 local_printfx(
" -F <filter> : Specify LDAP search filter. (ie. \"(objectClass=User)\")\n");
387 local_printfx(
" -G : Specify if LDAP search group is required. (ie. \"groupMembership=\")\n");
486 local_printfx(
" Search Filter: (&(objectClass=User)(networkAddress=*))\n");
502 if (l ==
nullptr)
return;
505 if (l->
lm !=
nullptr)
507 if (l->
val !=
nullptr)
508 ldap_value_free_len(l->
val);
566 if (l->
port == LDAPS_PORT)
575 if (l->
lp ==
nullptr) {
576 l->
err = LDAP_CONNECT_ERROR;
582 l->
err = LDAP_SUCCESS;
601 if (l->
lm !=
nullptr) {
605 if (l->
val !=
nullptr) {
606 ldap_value_free_len(l->
val);
611 s = ldap_unbind(l->
lp);
612 if (s == LDAP_SUCCESS) {
640 x = ldap_set_option(l->
lp, LDAP_OPT_PROTOCOL_VERSION, &v);
641 if (x == LDAP_SUCCESS) {
668 if (strlen(dn) >=
sizeof(l->
dn))
671 if ((l->
basedn[0] !=
'\0') && (strstr(dn, l->
basedn) ==
nullptr)) {
673 const int x = snprintf(l->
dn,
sizeof(l->
dn)-1,
"%s,%s", dn, l->
basedn);
674 if (x < 0 ||
static_cast<size_t>(x) >=
sizeof(l->
dn))
687 case LDAP_AUTH_SIMPLE:
693#ifdef LDAP_AUTH_KRBV4
694 case LDAP_AUTH_KRBV4:
698#ifdef LDAP_AUTH_KRBV41
699 case LDAP_AUTH_KRBV41:
703#ifdef LDAP_AUTH_KRBV42
704 case LDAP_AUTH_KRBV42:
714 l->
type = LDAP_AUTH_NONE;
719#if defined(LDAP_AUTH_TLS) && defined(NETSCAPE_SSL) && HAVE_LDAP_START_TLS_S
721 s = ldap_start_tls_s(l->
lp,
nullptr,
nullptr);
725 if (s == LDAP_SUCCESS) {
743static struct addrinfo *
746 struct addrinfo want;
747 memset(&want, 0,
sizeof(want));
748 want.ai_flags = AI_NUMERICHOST;
750 struct addrinfo *dst =
nullptr;
751 if (getaddrinfo(src,
nullptr, &want, &dst) != 0) {
771makeHexString(
char *dst,
const int dstSize,
const char *src,
const int srcLen)
774 if ((srcLen*2) >= dstSize)
779 for (
int k = 0; k < srcLen; ++k) {
780 int c =
static_cast<int>(src[k]);
784 const int hlen = snprintf(hexc,
sizeof(hexc),
"%02X", c);
785 if (hlen < 0 ||
static_cast<size_t>(hlen) >
sizeof(hexc))
810 if ((y !=
nullptr) && (z !=
nullptr)) {
818 }
else if (y !=
nullptr) {
829 }
else if (z !=
nullptr) {
840 if (dst->ai_family == AF_INET6) {
841 struct sockaddr_in6 *sia =
reinterpret_cast<struct sockaddr_in6 *
>(dst->ai_addr);
842 const char *ia =
reinterpret_cast<const char *
>(sia->sin6_addr.s6_addr);
845 }
else if (dst->ai_family == AF_INET) {
846 struct sockaddr_in *sia =
reinterpret_cast<struct sockaddr_in *
>(dst->ai_addr);
847 const char *ia =
reinterpret_cast<const char *
>(&(sia->sin_addr));
879 if (l->
lm !=
nullptr) {
883 if (l->
val !=
nullptr) {
884 ldap_value_free_len(l->
val);
895 l->
err = LDAP_SUCCESS;
918 memset(bufa,
'\0',
sizeof(bufa));
929 for (i = 0; i < s; ++i) {
942 if (group ==
nullptr) {
946 const int ln = snprintf(bufd,
sizeof(bufd),
"(networkAddress=8\\23\\00\\00%s)(networkAddress=9\\23\\00\\00%s)", bufc, bufc);
947 if (ln < 0 ||
static_cast<size_t>(ln) >=
sizeof(bufd))
951 const int ln = snprintf(bufd,
sizeof(bufd),
"(networkAddress=10\\23\\00\\00%s)(networkAddress=11\\23\\00\\00%s)", bufc, bufc);
952 if (ln < 0 ||
static_cast<size_t>(ln) >=
sizeof(bufd))
955 const int x = snprintf(bufa,
sizeof(bufa),
"(&%s(|(networkAddress=1\\23%s)%s))",
edui_conf.
search_filter, bufc, bufd);
956 if (x < 0 ||
static_cast<size_t>(x) >=
sizeof(bufa))
962 if ((l->
basedn[0] !=
'\0') && (strstr(group, l->
basedn) ==
nullptr)) {
963 const int ln = snprintf(bufg,
sizeof(bufg),
",%s", l->
basedn);
964 if (ln < 0 ||
static_cast<size_t>(ln) >=
sizeof(bufd))
969 const int ln = snprintf(bufd,
sizeof(bufd),
"(networkAddress=8\\23\\00\\00%s)(networkAddress=9\\23\\00\\00%s)", bufc, bufc);
970 if (ln < 0 ||
static_cast<size_t>(ln) >=
sizeof(bufd))
973 const int ln = snprintf(bufd,
sizeof(bufd),
"(networkAddress=10\\23\\00\\00%s)(networkAddress=11\\23\\00\\00%s)", bufc, bufc);
974 if (ln < 0 ||
static_cast<size_t>(ln) >=
sizeof(bufd))
977 const int x = snprintf(bufa,
sizeof(bufa),
"(&(&%s(groupMembership=%s%s)(|(networkAddress=1\\23%s)%s)))",
edui_conf.
search_filter, group, bufg, bufc, bufd);
978 if (x < 0 ||
static_cast<size_t>(x) >=
sizeof(bufa))
1006 if (l->
lm !=
nullptr)
1007 ldap_msgfree(l->
lm);
1014 s = ldap_search_s(l->
lp, l->
basedn, LDAP_SCOPE_BASE, ft, attrs, 0, &(l->
lm));
1017 s = ldap_search_s(l->
lp, l->
basedn, LDAP_SCOPE_ONELEVEL, ft, attrs, 0, &(l->
lm));
1020 s = ldap_search_s(l->
lp, l->
basedn, LDAP_SCOPE_SUBTREE, ft, attrs, 0, &(l->
lm));
1024 s = ldap_search_s(l->
lp, l->
basedn, LDAP_SCOPE_ONELEVEL, ft, attrs, 0, &(l->
lm));
1027 if (s == LDAP_SUCCESS) {
1066 if (l->
val !=
nullptr)
1067 ldap_value_free_len(l->
val);
1075 struct berval **ber =
nullptr;
1076 for (ent = ldap_first_entry(l->
lp, l->
lm); ent !=
nullptr; ent = ldap_next_entry(l->
lp, ent)) {
1077 l->
val = ldap_get_values_len(l->
lp, ent,
"networkAddress");
1079 if (l->
val !=
nullptr) {
1080 x = ldap_count_values_len(l->
val);
1084 for (i = 0; i < x; ++i) {
1085 j = l->
val[i]->bv_len;
1086 memcpy(bufa, l->
val[i]->bv_val, j);
1087 z =
BinarySplit(bufa, j,
'#', bufb,
sizeof(bufb));
1112 const int blen =
makeHexString(bufb,
sizeof(bufb), bufa, z);
1116 if (memcmp(l->
search_ip, bufb, blen) == 0) {
1118 z = ldap_count_values_len(ber);
1119 for (j = 0; j < z; ++j) {
1124 ldap_value_free_len(l->
val);
1126 ldap_value_free_len(ber);
1129 l->
err = LDAP_SUCCESS;
1134 }
else if ((j == 8) || (j == 9)) {
1139 const int blen =
makeHexString(bufb,
sizeof(bufb), &bufa[2], z);
1143 if (memcmp(l->
search_ip, bufb, blen) == 0) {
1145 z = ldap_count_values_len(ber);
1146 for (j = 0; j < z; ++j) {
1151 ldap_value_free_len(l->
val);
1153 ldap_value_free_len(ber);
1156 l->
err = LDAP_SUCCESS;
1161 }
else if ((j == 10) || (j == 11)) {
1166 const int blen =
makeHexString(bufb,
sizeof(bufb), &bufa[2], z);
1170 if (memcmp(l->
search_ip, bufb, blen) == 0) {
1172 z = ldap_count_values_len(ber);
1173 for (j = 0; j < z; ++j) {
1178 ldap_value_free_len(l->
val);
1180 ldap_value_free_len(ber);
1183 l->
err = LDAP_SUCCESS;
1193 if (ber !=
nullptr) {
1194 ldap_value_free_len(ber);
1198 ldap_value_free_len(l->
val);
1201 if (ber !=
nullptr) {
1202 ldap_value_free_len(ber);
1208 if (l->
val !=
nullptr) {
1209 ldap_value_free_len(l->
val);
1212 if (l->
lm !=
nullptr) {
1213 ldap_msgfree(l->
lm);
1218 l->
err = LDAP_NO_SUCH_OBJECT;
1234 return "Null pointer provided";
1236 return "Null LDAP pointer";
1238 return "Null or Missing parameter(s)";
1240 return "LDAP data not initialized";
1242 return "LDAP connection is not active";
1244 return "Unable to connect to LDAP host";
1246 return "LDAP connection is not bound";
1248 return "LDAP connection has already been searched";
1250 return "LDAP connection has not been searched";
1252 return "Invalid parameters";
1254 return "Parameter is out of bounds";
1256 return "Persistent mode is not active";
1258 return "Required data has not been found";
1260 return "Item or object has not been found";
1262 return "An unknown error has occurred";
1264 return "Operation has failed";
1266 return "Operation is successful";
1268 return "An unknown error has occurred";
1288 debug(
"Terminating, Signal: %d\n", s);
1307 struct sigaction sv;
1311 memset(bufa,
'\0',
sizeof(bufa));
1312 memset(bufb,
'\0',
sizeof(bufb));
1313 memset(bufc,
'\0',
sizeof(bufc));
1314 memset(sfmod,
'\0',
sizeof(sfmod));
1315 memset(&sv, 0,
sizeof(sv));
1324 for (i = 1; i < k; ++i) {
1326 if (!strcmp(argv[i],
"--help")) {
1329 }
else if (!strcmp(argv[i],
"--usage")) {
1332 }
else if (!strcmp(argv[i],
"--version")) {
1335 }
else if (argv[i][0] ==
'-') {
1336 s = strlen(argv[i]);
1337 for (j = 1; j < s; ++j) {
1338 switch (argv[i][j]) {
1368 if (argv[i] !=
nullptr) {
1382 if (argv[i] !=
nullptr) {
1394 if (argv[i] !=
nullptr)
1404 if (argv[i] !=
nullptr)
1414 if (argv[i] !=
nullptr)
1424 if (argv[i] !=
nullptr)
1434 if (argv[i] !=
nullptr)
1444 if (argv[i] !=
nullptr)
1458 if (argv[i] !=
nullptr) {
1459 if (!strncmp(argv[i],
"base", 4))
1461 else if (!strncmp(argv[i],
"one", 4))
1463 else if (!strncmp(argv[i],
"sub", 4))
1475 if (argv[i] !=
nullptr) {
1520 local_printfx(
"FATAL: No '-b' option provided (Base DN).\n");
1525 sigemptyset(&sv.sa_mask);
1527 sigaction(SIGTERM, &sv,
nullptr);
1529 sigaction(SIGHUP, &sv,
nullptr);
1531 sigaction(SIGABRT, &sv,
nullptr);
1533 sigaction(SIGINT, &sv,
nullptr);
1535 sigaction(SIGSEGV, &sv,
nullptr);
1544 while (fgets(bufa,
sizeof(bufa), stdin) !=
nullptr) {
1562 p = strchr(bufa,
'\n');
1565 p = strchr(bufa,
'\r');
1568 p = strchr(bufa,
' ');
1572 debug(
"while() -> Search group is missing. (required)\n");
1640 debug(
"BindLDAP(-, -, -, (LDAP_AUTH_NONE)) -> %s\n",
ErrLDAP(x));
1663 debug(
"StringSplit(%s, ' ', %s, %zu)\n", bufa, bufb,
sizeof(bufb));
1666 debug(
"StringSplit(%s, %s) done. Result: %zu\n", bufa, bufb, i);
1682 debug(
"SearchFilterLDAP(-, %s) -> Length: %u\n", bufa, x);
1703 memset(bufc,
'\0',
sizeof(bufc));
1707 debug(
"StringSplit() -> Error: %zu\n", i);
1708 local_printfx(
"BH message=\"(StringSplit Error %zu)\"\n", i);
1725 debug(
"SearchFilterLDAP(-, nullptr) -> Length: %u\n", x);
1728 debug(
"SearchLDAP() -> %s (LDAP: %s)\n",
ErrLDAP(x), ldap_err2string(x));
1747 memset(bufc,
'\0',
sizeof(bufc));
1753 memset(bufa,
'\0',
sizeof(bufa));
1760 debug(
"Terminating.\n");
void debug(const char *format,...)
static int makeHexString(char *dst, const int dstSize, const char *src, const int srcLen)
static int ResetLDAP(edui_ldap_t *)
static void local_printfx(const char *,...)
static int ConvertIP(edui_ldap_t *, char *)
static int SetVerLDAP(edui_ldap_t *, int)
#define EDUI_MODE_PERSIST
static int CloseLDAP(edui_ldap_t *)
#define LDAP_ERR_NOT_SEARCHED
static int SearchFilterLDAP(edui_ldap_t *, char *)
const char * ErrLDAP(int)
static int BindLDAP(edui_ldap_t *, char *, char *, unsigned int)
#define EDUI_PROGRAM_VERSION
static int OpenLDAP(edui_ldap_t *, char *, unsigned int)
#define LDAP_ERR_SEARCHED
static edui_ldap_t edui_ldap
static void DisplayVersion()
static void InitLDAP(edui_ldap_t *)
static int SearchLDAP(edui_ldap_t *, int, char *, char **)
#define LDAP_ERR_NOTFOUND
static int MainSafe(int argc, char **argv)
static int BinarySplit(void *, size_t, char, void *, size_t)
static int StringSplit(char *, char, char *, size_t)
const char * search_attrib[]
static struct addrinfo * makeIpBinary(const char *src)
static int SearchIPLDAP(edui_ldap_t *)
static void DisplayConf()
#define EDUI_PROGRAM_NAME
static void DisplayUsage()
static edui_conf_t edui_conf
static const char * basedn
char search_filter[EDUI_MAXLEN]
char program[EDUI_MAXLEN]
char search_ip[EDUI_MAXLEN]
char search_filter[EDUI_MAXLEN]
char * xstrncpy(char *dst, const char *src, size_t n)