Skip to content
GitLab
Projects
Groups
Snippets
/
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Sign in / Register
Toggle navigation
Menu
Open sidebar
openldap
OpenLDAP
Commits
9d594a11
Commit
9d594a11
authored
Mar 19, 2021
by
Lukas However
Committed by
Quanah Gibson-Mount
Mar 25, 2021
Browse files
ITS
#8847
Add SOCKET_BIND_ADDRESSES Option
parent
8ebd0650
Pipeline
#2238
canceled with stage
in 14 minutes and 9 seconds
Changes
10
Pipelines
2
Hide whitespace changes
Inline
Side-by-side
doc/man/man3/ldap_get_option.3
View file @
9d594a11
...
...
@@ -376,6 +376,21 @@ must be a
This is a read-only, handle-specific option.
This option is OpenLDAP specific.
.TP
.B LDAP_OPT_SOCKET_BIND_ADDRESSES
Sets/gets a space-separated list of IP Addresses used as binding interface
to remote server when trying to establish a connection. Only one valid IPv4
address and/or one valid IPv6 address are allowed in the list.
.BR outvalue
must be a
.BR "char **",
and the caller is responsible of freeing the returned string by calling
.BR ldap_memfree (3),
while
.BR invalue
must be a
.BR "const char *" ;
the library duplicates the corresponding string.
.TP
.B LDAP_OPT_TIMELIMIT
Sets/gets the value that defines the time limit after which
a search operation should be terminated by the server.
...
...
doc/man/man5/ldap.conf.5
View file @
9d594a11
...
...
@@ -213,6 +213,11 @@ specifies a request for unlimited search size. Please note that the server
may still apply any server-side limit on the amount of entries that can be
returned by a search operation.
.TP
.B SOCKET_BIND_ADDRESSES <IP>
Specifies the source bind IP to be used for connecting to target LDAP server.
Multiple IP addresses must be space separated. Only one valid IPv4
address and/or one valid IPv6 address are allowed in the list.
.TP
.B TIMELIMIT <integer>
Specifies a time limit (in seconds) to use when performing searches.
The number should be a non-negative integer. \fITIMELIMIT\fP of zero (0)
...
...
include/ldap.h
View file @
9d594a11
...
...
@@ -132,6 +132,7 @@ LDAP_BEGIN_DECL
#define LDAP_OPT_CONNECT_CB 0x5011
/* connection callbacks */
#define LDAP_OPT_SESSION_REFCNT 0x5012
/* session reference count */
#define LDAP_OPT_KEEPCONN 0x5013
/* keep the connection on read error or NoD */
#define LDAP_OPT_SOCKET_BIND_ADDRESSES 0x5014
/* user configured bind IPs */
/* OpenLDAP TLS options */
#define LDAP_OPT_X_TLS 0x6000
...
...
libraries/libldap/init.c
View file @
9d594a11
...
...
@@ -38,6 +38,7 @@
struct
ldapoptions
ldap_int_global_options
=
{
LDAP_UNINITIALIZED
,
LDAP_DEBUG_NONE
LDAP_LDO_NULLARG
LDAP_LDO_SOURCEIP_NULLARG
LDAP_LDO_CONNECTIONLESS_NULLARG
LDAP_LDO_TLS_NULLARG
LDAP_LDO_SASL_NULLARG
...
...
@@ -93,6 +94,7 @@ static const struct ol_attribute {
offsetof
(
struct
ldapoptions
,
ldo_defport
)},
{
0
,
ATTR_OPTION
,
"HOST"
,
NULL
,
LDAP_OPT_HOST_NAME
},
/* deprecated */
{
0
,
ATTR_OPTION
,
"URI"
,
NULL
,
LDAP_OPT_URI
},
/* replaces HOST/PORT */
{
0
,
ATTR_OPTION
,
"SOCKET_BIND_ADDRESSES"
,
NULL
,
LDAP_OPT_SOCKET_BIND_ADDRESSES
},
{
0
,
ATTR_BOOL
,
"REFERRALS"
,
NULL
,
LDAP_BOOL_REFERRALS
},
{
0
,
ATTR_INT
,
"KEEPALIVE_IDLE"
,
NULL
,
LDAP_OPT_X_KEEPALIVE_IDLE
},
{
0
,
ATTR_INT
,
"KEEPALIVE_PROBES"
,
NULL
,
LDAP_OPT_X_KEEPALIVE_PROBES
},
...
...
@@ -142,7 +144,7 @@ static const struct ol_attribute {
{
0
,
ATTR_NONE
,
NULL
,
NULL
,
0
}
};
#define MAX_LDAP_ATTR_LEN sizeof("
TLS_CIPHER_SUITE
")
#define MAX_LDAP_ATTR_LEN sizeof("
SOCKET_BIND_ADDRESSES
")
#define MAX_LDAP_ENV_PREFIX_LEN 8
static
int
...
...
@@ -519,6 +521,12 @@ ldap_int_destroy_global_options(void)
ldap_free_urllist
(
gopts
->
ldo_defludp
);
gopts
->
ldo_defludp
=
NULL
;
}
if
(
gopts
->
ldo_local_ip_addrs
.
local_ip_addrs
)
{
LDAP_FREE
(
gopts
->
ldo_local_ip_addrs
.
local_ip_addrs
);
gopts
->
ldo_local_ip_addrs
.
local_ip_addrs
=
NULL
;
}
#if defined(HAVE_WINSOCK) || defined(HAVE_WINSOCK2)
WSACleanup
(
);
#endif
...
...
@@ -558,6 +566,9 @@ void ldap_int_initialize_global_options( struct ldapoptions *gopts, int *dbglvl
gopts
->
ldo_tm_api
.
tv_sec
=
-
1
;
gopts
->
ldo_tm_net
.
tv_sec
=
-
1
;
memset
(
&
gopts
->
ldo_local_ip_addrs
,
0
,
sizeof
(
gopts
->
ldo_local_ip_addrs
)
);
/* ldo_defludp will be freed by the termination handler
*/
ldap_url_parselist
(
&
gopts
->
ldo_defludp
,
"ldap://localhost/"
);
...
...
libraries/libldap/ldap-int.h
View file @
9d594a11
...
...
@@ -45,9 +45,7 @@
/* for struct timeval */
#include
<ac/time.h>
#ifdef _WIN32
#include
<ac/socket.h>
#endif
#undef TV2MILLISEC
#define TV2MILLISEC(tv) (((tv)->tv_sec * 1000) + ((tv)->tv_usec/1000))
...
...
@@ -199,6 +197,19 @@ typedef struct ldaplist {
void
*
ll_data
;
}
ldaplist
;
/*
* LDAP Client Source IP structure
*/
typedef
struct
ldapsourceip
{
char
*
local_ip_addrs
;
struct
in_addr
ip4_addr
;
unsigned
short
has_ipv4
;
#ifdef LDAP_PF_INET6
struct
in6_addr
ip6_addr
;
unsigned
short
has_ipv6
;
#endif
}
ldapsourceip
;
/*
* structure representing get/set'able options
* which have global defaults.
...
...
@@ -256,6 +267,15 @@ struct ldapoptions {
#define LDAP_LDO_NULLARG ,0,0,0,0 ,{0},{0} ,0,0,0,0, 0,0,0,0, 0,0, 0,0,0,0,0,0, 0, 0
/* LDAP user configured bind IPs */
struct
ldapsourceip
ldo_local_ip_addrs
;
#ifdef LDAP_PF_INET6
#define LDAP_LDO_SOURCEIP_NULLARG ,{0,0,0,0,0}
#else
#define LDAP_LDO_SOURCEIP_NULLARG ,{0,0,0}
#endif
#ifdef LDAP_CONNECTIONLESS
#define LDAP_IS_UDP(ld) ((ld)->ld_options.ldo_is_udp)
void
*
ldo_peer
;
/* struct sockaddr* */
...
...
@@ -727,6 +747,9 @@ LDAP_F (void) ldap_clear_select_write( LDAP *ld, Sockbuf *sb );
LDAP_F
(
int
)
ldap_is_read_ready
(
LDAP
*
ld
,
Sockbuf
*
sb
);
LDAP_F
(
int
)
ldap_is_write_ready
(
LDAP
*
ld
,
Sockbuf
*
sb
);
LDAP_F
(
int
)
ldap_validate_and_fill_sourceip
(
char
**
source_ip_lst
,
ldapsourceip
*
temp_source_ip
);
LDAP_F
(
int
)
ldap_int_connect_cbs
(
LDAP
*
ld
,
Sockbuf
*
sb
,
ber_socket_t
*
s
,
LDAPURLDesc
*
srv
,
struct
sockaddr
*
addr
);
...
...
libraries/libldap/open.c
View file @
9d594a11
...
...
@@ -207,6 +207,14 @@ ldap_create( LDAP **ldp )
if
((
ld
->
ld_selectinfo
=
ldap_new_select_info
())
==
NULL
)
goto
nomem
;
ld
->
ld_options
.
ldo_local_ip_addrs
.
local_ip_addrs
=
NULL
;
if
(
gopts
->
ldo_local_ip_addrs
.
local_ip_addrs
)
{
ld
->
ld_options
.
ldo_local_ip_addrs
.
local_ip_addrs
=
LDAP_STRDUP
(
gopts
->
ldo_local_ip_addrs
.
local_ip_addrs
);
if
(
ld
->
ld_options
.
ldo_local_ip_addrs
.
local_ip_addrs
==
NULL
)
goto
nomem
;
}
ld
->
ld_lberoptions
=
LBER_USE_DER
;
ld
->
ld_sb
=
ber_sockbuf_alloc
(
);
...
...
libraries/libldap/options.c
View file @
9d594a11
...
...
@@ -258,6 +258,17 @@ ldap_get_option(
rc
=
LDAP_OPT_SUCCESS
;
break
;
case
LDAP_OPT_SOCKET_BIND_ADDRESSES
:
if
(
lo
->
ldo_local_ip_addrs
.
local_ip_addrs
==
NULL
)
{
*
(
void
**
)
outvalue
=
NULL
;
}
else
{
*
(
char
**
)
outvalue
=
LDAP_STRDUP
(
lo
->
ldo_local_ip_addrs
.
local_ip_addrs
);
}
rc
=
LDAP_OPT_SUCCESS
;
break
;
case
LDAP_OPT_URI
:
*
(
char
**
)
outvalue
=
ldap_url_list2urls
(
lo
->
ldo_defludp
);
rc
=
LDAP_OPT_SUCCESS
;
...
...
@@ -594,6 +605,43 @@ ldap_set_option(
break
;
}
case
LDAP_OPT_SOCKET_BIND_ADDRESSES
:
{
const
char
*
source_ip
=
(
const
char
*
)
invalue
;
char
**
source_ip_lst
=
NULL
;
ldapsourceip
temp_source_ip
;
memset
(
&
temp_source_ip
,
0
,
sizeof
(
ldapsourceip
)
);
rc
=
LDAP_OPT_SUCCESS
;
if
(
source_ip
==
NULL
)
{
if
(
ld
->
ld_options
.
ldo_local_ip_addrs
.
local_ip_addrs
)
{
LDAP_FREE
(
ld
->
ld_options
.
ldo_local_ip_addrs
.
local_ip_addrs
);
memset
(
&
ld
->
ld_options
.
ldo_local_ip_addrs
,
0
,
sizeof
(
ldapsourceip
)
);
}
}
else
{
source_ip_lst
=
ldap_str2charray
(
source_ip
,
" "
);
if
(
source_ip_lst
==
NULL
)
rc
=
LDAP_NO_MEMORY
;
if
(
rc
==
LDAP_OPT_SUCCESS
)
{
rc
=
ldap_validate_and_fill_sourceip
(
source_ip_lst
,
&
temp_source_ip
);
ldap_charray_free
(
source_ip_lst
);
}
if
(
rc
==
LDAP_OPT_SUCCESS
)
{
if
(
lo
->
ldo_local_ip_addrs
.
local_ip_addrs
!=
NULL
)
{
LDAP_FREE
(
lo
->
ldo_local_ip_addrs
.
local_ip_addrs
);
lo
->
ldo_local_ip_addrs
.
local_ip_addrs
=
NULL
;
}
lo
->
ldo_local_ip_addrs
=
temp_source_ip
;
lo
->
ldo_local_ip_addrs
.
local_ip_addrs
=
LDAP_STRDUP
(
source_ip
);
}
}
break
;
}
case
LDAP_OPT_URI
:
{
const
char
*
urls
=
(
const
char
*
)
invalue
;
LDAPURLDesc
*
ludlist
=
NULL
;
...
...
libraries/libldap/os-ip.c
View file @
9d594a11
...
...
@@ -475,6 +475,43 @@ ldap_pvt_inet_aton( const char *host, struct in_addr *in)
}
#endif
int
ldap_validate_and_fill_sourceip
(
char
**
source_ip_lst
,
ldapsourceip
*
temp_source_ip
)
{
int
i
=
0
;
int
rc
=
LDAP_PARAM_ERROR
;
for
(
i
=
0
;
source_ip_lst
[
i
]
!=
NULL
;
i
++
)
{
Debug1
(
LDAP_DEBUG_TRACE
,
"ldap_validate_and_fill_sourceip(%s)
\n
"
,
source_ip_lst
[
i
]
);
if
(
!
temp_source_ip
->
has_ipv4
)
{
if
(
inet_aton
(
source_ip_lst
[
i
],
&
temp_source_ip
->
ip4_addr
)
)
{
temp_source_ip
->
has_ipv4
=
1
;
rc
=
LDAP_OPT_SUCCESS
;
continue
;
}
}
#ifdef LDAP_PF_INET6
if
(
!
temp_source_ip
->
has_ipv6
)
{
if
(
inet_pton
(
AF_INET6
,
source_ip_lst
[
i
],
&
temp_source_ip
->
ip6_addr
)
)
{
temp_source_ip
->
has_ipv6
=
1
;
rc
=
LDAP_OPT_SUCCESS
;
continue
;
}
}
#endif
memset
(
temp_source_ip
,
0
,
sizeof
(
*
(
temp_source_ip
)
)
);
Debug1
(
LDAP_DEBUG_TRACE
,
"ldap_validate_and_fill_sourceip: validation failed for (%s)
\n
"
,
source_ip_lst
[
i
]
);
break
;
}
return
rc
;
}
int
ldap_int_connect_cbs
(
LDAP
*
ld
,
Sockbuf
*
sb
,
ber_socket_t
*
s
,
LDAPURLDesc
*
srv
,
struct
sockaddr
*
addr
)
{
...
...
@@ -607,6 +644,7 @@ ldap_connect_to_host(LDAP *ld, Sockbuf *sb,
rc
=
-
1
;
for
(
sai
=
res
;
sai
!=
NULL
;
sai
=
sai
->
ai_next
)
{
unsigned
short
bind_success
=
1
;
if
(
sai
->
ai_addr
==
NULL
)
{
Debug0
(
LDAP_DEBUG_TRACE
,
"ldap_connect_to_host: getaddrinfo "
...
...
@@ -638,6 +676,24 @@ ldap_connect_to_host(LDAP *ld, Sockbuf *sb,
Debug2
(
LDAP_DEBUG_TRACE
,
"ldap_connect_to_host: Trying %s %s
\n
"
,
addr
,
serv
);
if
(
ld
->
ld_options
.
ldo_local_ip_addrs
.
has_ipv6
)
{
struct
sockaddr_in6
ip6addr
;
char
bind_addr
[
INET6_ADDRSTRLEN
];
ip6addr
.
sin6_family
=
AF_INET6
;
ip6addr
.
sin6_addr
=
ld
->
ld_options
.
ldo_local_ip_addrs
.
ip6_addr
;
inet_ntop
(
AF_INET6
,
&
(
ip6addr
.
sin6_addr
),
bind_addr
,
sizeof
bind_addr
);
Debug1
(
LDAP_DEBUG_TRACE
,
"ldap_connect_to_host: From source address %s
\n
"
,
bind_addr
);
if
(
bind
(
s
,
(
struct
sockaddr
*
)
&
ip6addr
,
sizeof
ip6addr
)
!=
0
)
{
Debug1
(
LDAP_DEBUG_TRACE
,
"ldap_connect_to_host: Failed to bind source address %s
\n
"
,
bind_addr
);
bind_success
=
0
;
}
}
}
break
;
#endif
case
AF_INET
:
{
...
...
@@ -648,17 +704,36 @@ ldap_connect_to_host(LDAP *ld, Sockbuf *sb,
Debug2
(
LDAP_DEBUG_TRACE
,
"ldap_connect_to_host: Trying %s:%s
\n
"
,
addr
,
serv
);
if
(
ld
->
ld_options
.
ldo_local_ip_addrs
.
has_ipv4
)
{
struct
sockaddr_in
ip4addr
;
char
bind_addr
[
INET_ADDRSTRLEN
];
ip4addr
.
sin_family
=
AF_INET
;
ip4addr
.
sin_addr
=
ld
->
ld_options
.
ldo_local_ip_addrs
.
ip4_addr
;
inet_ntop
(
AF_INET
,
&
(
ip4addr
.
sin_addr
),
bind_addr
,
sizeof
bind_addr
);
Debug1
(
LDAP_DEBUG_TRACE
,
"ldap_connect_to_host: From source address %s
\n
"
,
bind_addr
);
if
(
bind
(
s
,
(
struct
sockaddr
*
)
&
ip4addr
,
sizeof
ip4addr
)
!=
0
)
{
Debug1
(
LDAP_DEBUG_TRACE
,
"ldap_connect_to_host: Failed to bind source address %s
\n
"
,
bind_addr
);
bind_success
=
0
;
}
}
}
break
;
}
rc
=
ldap_pvt_connect
(
ld
,
s
,
sai
->
ai_addr
,
sai
->
ai_addrlen
,
async
);
if
(
rc
==
0
||
rc
==
-
2
)
{
err
=
ldap_int_connect_cbs
(
ld
,
sb
,
&
s
,
srv
,
sai
->
ai_addr
);
if
(
err
)
rc
=
err
;
else
break
;
if
(
bind_success
)
{
rc
=
ldap_pvt_connect
(
ld
,
s
,
sai
->
ai_addr
,
sai
->
ai_addrlen
,
async
);
if
(
rc
==
0
||
rc
==
-
2
)
{
err
=
ldap_int_connect_cbs
(
ld
,
sb
,
&
s
,
srv
,
sai
->
ai_addr
);
if
(
err
)
rc
=
err
;
else
break
;
}
}
ldap_pvt_close_socket
(
ld
,
s
);
}
...
...
@@ -687,7 +762,14 @@ ldap_connect_to_host(LDAP *ld, Sockbuf *sb,
rc
=
s
=
-
1
;
for
(
i
=
0
;
!
use_hp
||
(
hp
->
h_addr_list
[
i
]
!=
0
);
++
i
,
rc
=
-
1
)
{
struct
sockaddr_in
sin
;
unsigned
short
bind_success
=
1
;
#ifdef HAVE_INET_NTOA_B
char
address
[
INET_ADDR_LEN
];
char
bind_addr
[
INET_ADDR_LEN
];
#else
char
*
address
;
char
*
bind_addr
;
#endif
s
=
ldap_int_socket
(
ld
,
PF_INET
,
socktype
);
if
(
s
==
AC_SOCKET_INVALID
)
{
/* use_hp ? continue : break; */
...
...
@@ -712,30 +794,45 @@ ldap_connect_to_host(LDAP *ld, Sockbuf *sb,
}
#ifdef HAVE_INET_NTOA_B
{
/* for VxWorks */
char
address
[
INET_ADDR_LEN
];
inet_ntoa_b
(
sin
.
sin_address
,
address
);
Debug2
(
LDAP_DEBUG_TRACE
,
"ldap_connect_to_host: Trying %s:%d
\n
"
,
address
,
port
);
}
/* for VxWorks */
inet_ntoa_b
(
sin
.
sin_address
,
address
);
#else
Debug2
(
LDAP_DEBUG_TRACE
,
"ldap_connect_to_host: Trying %s:%d
\n
"
,
inet_ntoa
(
sin
.
sin_addr
),
port
);
address
=
inet_ntoa
(
sin
.
sin_addr
);
#endif
rc
=
ldap_pvt_connect
(
ld
,
s
,
(
struct
sockaddr
*
)
&
sin
,
sizeof
(
sin
),
async
);
if
(
(
rc
==
0
)
||
(
rc
==
-
2
)
)
{
int
err
=
ldap_int_connect_cbs
(
ld
,
sb
,
&
s
,
srv
,
(
struct
sockaddr
*
)
&
sin
);
if
(
err
)
rc
=
err
;
else
break
;
Debug2
(
LDAP_DEBUG_TRACE
,
"ldap_connect_to_host: Trying %s:%d
\n
"
,
address
,
port
);
if
(
ld
->
ld_options
.
ldo_local_ip_addrs
.
has_ipv4
)
{
struct
sockaddr_in
ip4addr
;
ip4addr
.
sin_family
=
AF_INET
;
ip4addr
.
sin_addr
=
ld
->
ld_options
.
ldo_local_ip_addrs
.
ip4_addr
;
#ifdef HAVE_INET_NTOA_B
inet_ntoa_b
(
ip4addr
.
sin_address
,
bind_addr
);
#else
bind_addr
=
inet_ntoa
(
ip4addr
.
sin_addr
);
#endif
Debug1
(
LDAP_DEBUG_TRACE
,
"ldap_connect_to_host: From source address %s
\n
"
,
bind_addr
);
if
(
bind
(
s
,
(
struct
sockaddr
*
)
&
ip4addr
,
sizeof
ip4addr
)
!=
0
)
{
Debug1
(
LDAP_DEBUG_TRACE
,
"ldap_connect_to_host: Failed to bind source address %s
\n
"
,
bind_addr
);
bind_success
=
0
;
}
}
if
(
bind_success
)
{
rc
=
ldap_pvt_connect
(
ld
,
s
,
(
struct
sockaddr
*
)
&
sin
,
sizeof
(
sin
),
async
);
if
(
(
rc
==
0
)
||
(
rc
==
-
2
)
)
{
int
err
=
ldap_int_connect_cbs
(
ld
,
sb
,
&
s
,
srv
,
(
struct
sockaddr
*
)
&
sin
);
if
(
err
)
rc
=
err
;
else
break
;
}
}
ldap_pvt_close_socket
(
ld
,
s
);
...
...
libraries/libldap/unbind.c
View file @
9d594a11
...
...
@@ -175,6 +175,12 @@ ldap_ld_free(
ld
->
ld_options
.
ldo_defludp
=
NULL
;
}
if
(
ld
->
ld_options
.
ldo_local_ip_addrs
.
local_ip_addrs
)
{
LDAP_FREE
(
ld
->
ld_options
.
ldo_local_ip_addrs
.
local_ip_addrs
);
memset
(
&
ld
->
ld_options
.
ldo_local_ip_addrs
,
0
,
sizeof
(
ldapsourceip
)
);
}
#ifdef LDAP_CONNECTIONLESS
if
(
ld
->
ld_options
.
ldo_peer
!=
NULL
)
{
LDAP_FREE
(
ld
->
ld_options
.
ldo_peer
);
...
...
tests/progs/Makefile.in
View file @
9d594a11
...
...
@@ -57,7 +57,7 @@ slapd-bind: slapd-bind.o $(OBJS) $(XLIBS)
$(LTLINK)
-o
$@
slapd-bind.o
$(OBJS)
$(LIBS)
ldif-filter
:
ldif-filter.o $(XLIBS)
$(LTLINK)
-o
$@
ldif-filter.o
$(LIBS)
$(LTLINK)
-o
$@
ldif-filter.o
$(OBJS)
$(LIBS)
slapd-mtread
:
slapd-mtread.o $(OBJS) $(XLIBS)
$(LTLINK)
-o
$@
slapd-mtread.o
$(OBJS)
$(LIBS)
...
...
Write
Preview
Supports
Markdown
0%
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment