Skip to content
GitLab
Menu
Projects
Groups
Snippets
/
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Sign in / Register
Toggle navigation
Menu
Open sidebar
Robert Dubner
OpenLDAP
Commits
ee167d34
Commit
ee167d34
authored
Sep 10, 2021
by
Robert Dubner
Browse files
Drive everything with search URIs from slapd.conf
parent
66e0a504
Changes
3
Hide whitespace changes
Inline
Side-by-side
contrib/slapd-modules/radiusov/radius.c
View file @
ee167d34
...
...
@@ -306,8 +306,7 @@ build_ttls_challenge( RADIUS_PACKET *response,
}
static
int
process_eap_message_identity
(
void
*
ctx
,
RADIUS_INFO
*
radius_info
,
process_eap_message_identity
(
RADIUS_INFO
*
radius_info
,
int
udp_socket
,
struct
sockaddr_in
*
client_addr
,
search_descriptor
*
sd
,
...
...
@@ -378,8 +377,7 @@ process_eap_message_identity( void *ctx,
}
static
int
process_eap_message_legacy_nak
(
void
*
ctx
,
RADIUS_INFO
*
radius_info
,
process_eap_message_legacy_nak
(
RADIUS_INFO
*
radius_info
,
int
udp_socket
,
struct
sockaddr_in
*
client_addr
,
search_descriptor
*
sd
,
...
...
@@ -993,14 +991,14 @@ process_mschap_response(STATE *state)
// Fetch the password for username[] from the LDAP directory:
char
password
[
MAXIMUM_PASSWORD_CHARACTERS
+
1
];
int
bad_search
=
radiusov_get_password_from_uid
(
volatiles
->
radius_info
,
volatiles
->
sd
,
int
bad_search
=
radiusov_get_password_from_uid
(
volatiles
->
radius_info
,
p_username
,
password
,
sizeof
(
password
)
);
if
(
bad_search
)
{
Debug
(
LDAP_DEBUG_
TRACE
,
Debug
(
LDAP_DEBUG_
STATS
,
"Unable to find the password for %s in the LDAP directory
\n
"
,
p_username
);
}
...
...
@@ -1839,8 +1837,8 @@ respond_to_ttls_md5_challenge( EAP_MESSAGE *internal_eap_message,
char
password
[
MAXIMUM_PASSWORD_CHARACTERS
+
1
];
int
bad_search
=
radiusov_get_password_from_uid
(
volatiles
->
radius_info
,
volatiles
->
sd
,
int
bad_search
=
radiusov_get_password_from_uid
(
volatiles
->
radius_info
,
username
,
password
,
sizeof
(
password
));
...
...
@@ -2223,8 +2221,7 @@ process_peap_application_data(STATE *state)
}
static
int
process_eap_message_peap_or_ttls
(
void
*
ctx
,
RADIUS_INFO
*
radius_info
,
process_eap_message_peap_or_ttls
(
RADIUS_INFO
*
radius_info
,
int
udp_socket
,
struct
sockaddr_in
*
client_addr
,
search_descriptor
*
sd
,
...
...
@@ -2254,7 +2251,6 @@ process_eap_message_peap_or_ttls( void *ctx,
state
->
volatiles
=
ch_calloc
(
1
,
sizeof
(
STATE_VOLATILES
));
state
->
volatiles
->
ctx
=
ctx
;
state
->
volatiles
->
radius_info
=
radius_info
;
state
->
volatiles
->
udp_socket
=
udp_socket
;
state
->
volatiles
->
client_addr
=
client_addr
;
...
...
@@ -2483,8 +2479,7 @@ process_eap_message_peap_or_ttls( void *ctx,
}
static
int
process_access_request
(
void
*
ctx
,
RADIUS_INFO
*
radius_info
,
process_access_request
(
RADIUS_INFO
*
radius_info
,
int
udp_socket
,
struct
sockaddr_in
*
client_addr
,
search_descriptor
*
sd
,
...
...
@@ -2605,8 +2600,7 @@ process_access_request( void *ctx,
switch
(
eap_message
->
Type
)
{
case
EAP_MESSAGE_TYPE_IDENTITY
:
rc
=
process_eap_message_identity
(
ctx
,
radius_info
,
rc
=
process_eap_message_identity
(
radius_info
,
udp_socket
,
client_addr
,
sd
,
...
...
@@ -2615,8 +2609,7 @@ process_access_request( void *ctx,
break
;
case
EAP_MESSAGE_TYPE_LEGACY_NAK
:
rc
=
process_eap_message_legacy_nak
(
ctx
,
radius_info
,
rc
=
process_eap_message_legacy_nak
(
radius_info
,
udp_socket
,
client_addr
,
sd
,
...
...
@@ -2626,8 +2619,7 @@ process_access_request( void *ctx,
case
EAP_MESSAGE_TYPE_PEAP
:
case
EAP_MESSAGE_TYPE_TTLS
:
rc
=
process_eap_message_peap_or_ttls
(
ctx
,
radius_info
,
rc
=
process_eap_message_peap_or_ttls
(
radius_info
,
udp_socket
,
client_addr
,
sd
,
...
...
@@ -2676,8 +2668,7 @@ process_access_request( void *ctx,
}
int
radiusov_protocol
(
void
*
ctx
,
RADIUS_INFO
*
radius_info
,
radiusov_protocol
(
RADIUS_INFO
*
radius_info
,
int
udp_socket
,
struct
sockaddr_in
*
client_addr
,
search_descriptor
*
sd
,
...
...
@@ -2703,8 +2694,7 @@ radiusov_protocol( void *ctx,
switch
(
get_code
(
request
))
{
case
PC_Access_Request
:
rc
=
process_access_request
(
ctx
,
radius_info
,
rc
=
process_access_request
(
radius_info
,
udp_socket
,
client_addr
,
sd
,
...
...
contrib/slapd-modules/radiusov/radiusov.c
View file @
ee167d34
...
...
@@ -48,39 +48,9 @@ ldap_pvt_thread_mutex_t libradius_mutex;
// when working with a Wireless Access Point that insists on retrying while you
// are trapping through code in a multi-threaded environment.
//
// A negative value means just process everything
// A negative value means just process everything
without touching the counter
static
int
packet_eat_count
=
-
5
;
// For initial development, this is a static list. Eventually it will
// be established from a configuration file or database
static
search_descriptor
search_descriptors
[]
=
{
{
"127.0.0.1"
,
TEST_AND_DEVELOPMENT
,
LDAP_SCOPE_SUBTREE
,
"(uid=%s)"
,
"dc=renbud,dc=com"
,
""
,
},
{
"10.0.1.250"
,
RADIUS_PROTOCOL
,
LDAP_SCOPE_SUBTREE
,
"(uid=%s)"
,
"dc=renbud,dc=com"
,
"testing123"
,
},
{
NULL
,
// This entry ends the list
INVALID_SEARCH_METHOD
,
0
,
NULL
,
NULL
,
NULL
,
},
};
static
int
packet_eat_count
=
-
1
;
static
void
ber_lower
(
BerValue
*
bv
)
...
...
@@ -252,8 +222,9 @@ radiusov_generalized_database_fetch(BackendDB *be,
// This routine is designed for handling just one attribute.
// I am including that single attribute, although there doesn't seem to
// be any point.
ber_printf
(
ber
,
"{s}"
,
"userPassword"
);
// be any point: my observation is that even with this parameter, the
// callback routine gets all the attributes.
ber_printf
(
ber
,
"{s}"
,
attribute_name
);
ber_printf
(
ber
,
"}"
);
...
...
@@ -295,31 +266,58 @@ radiusov_generalized_database_fetch(BackendDB *be,
return
rc
;
}
static
int
radiusov_get_dn_from_uid
(
BackendDB
*
be
,
const
char
*
base
,
int
scope
,
char
*
pszUsername
,
struct
berval
*
dn_retval
,
size_t
len
)
static
void
convert_search_string
(
char
*
const
dest
,
size_t
len
,
const
char
*
uri_search_string
,
...)
{
Debug
(
LDAP_DEBUG_TRACE
,
"=> %s(). UID is %s
\n
"
,
__func__
,
pszUsername
);
char
*
d
=
dest
;
const
char
*
s
=
uri_search_string
;
size_t
bytes_left
=
len
-
1
;
int
rc
=
0
;
// Zero means Okay
va_list
the_parameters
;
va_start
(
the_parameters
,
uri_search_string
);
char
filter
[
1024
];
sprintf
(
filter
,
"(uid=%s)"
,
pszUsername
);
while
(
bytes_left
>
0
)
{
char
ch
=
*
s
++
;
bytes_left
-=
1
;
if
(
ch
==
'\0'
)
{
// We have copied over the whole search string
break
;
}
if
(
ch
==
'$'
)
{
// A dollar sign is the replacement flag. We are already past it.
// We are going to ignore any decimal digits that follow the dollar
// sign:
while
(
isdigit
(
*
s
)
)
{
s
+=
1
;
}
// And, in place of the dollar sign, tack on the next parameter
char
*
param
=
va_arg
(
the_parameters
,
char
*
);
while
(
*
param
&&
bytes_left
>
0
)
{
*
d
++
=
*
param
++
;
bytes_left
-=
1
;
}
}
else
{
// Because the character isn't a dollar sign, we just copy it
// to the destination:
*
d
++
=
ch
;
}
}
*
d
++
=
'\0'
;
va_end
(
the_parameters
);
rc
=
radiusov_generalized_database_fetch
(
be
,
base
,
scope
,
filter
,
"dn"
,
dn_retval
->
bv_val
,
len
);
dn_retval
->
bv_len
=
strlen
(
dn_retval
->
bv_val
);
return
rc
;
}
static
int
...
...
@@ -329,16 +327,28 @@ radiusov_verify_username_password( RADIUS_INFO *radius_info,
char
*
pszPassword
)
{
Debug
(
LDAP_DEBUG_TRACE
,
"=> %s()
\n
"
,
__func__
);
// Starting with username, find its DN
// This was used for development and test of a couple of things. We are
// going to use radius_info->lud_simple_test to get the dn (the URI has to
// be in the correct for for that). Once we have the URI, we'll do a bind
// operation to determine the validity of the password and that dn
char
achSearchString
[
256
];
convert_search_string
(
achSearchString
,
sizeof
(
achSearchString
),
radius_info
->
lud_simple_test
->
lud_filter
,
pszUsername
);
char
dnbuffer
[
1024
];
BerValue
dn
=
{
0
,
dnbuffer
};
int
rc
=
radiusov_get_dn_from_uid
(
radius_info
->
radius_db
,
sd
->
search_base
,
sd
->
search_scope
,
pszUsername
,
&
dn
,
sizeof
(
dnbuffer
)
);
int
rc
=
radiusov_generalized_database_fetch
(
radius_info
->
radius_db
,
radius_info
->
lud_simple_test
->
lud_dn
,
radius_info
->
lud_simple_test
->
lud_scope
,
achSearchString
,
radius_info
->
lud_simple_test
->
lud_attrs
[
0
],
dnbuffer
,
sizeof
(
dnbuffer
)
);
dn
.
bv_len
=
strlen
(
dnbuffer
);
if
(
rc
==
0
)
{
...
...
@@ -358,29 +368,32 @@ radiusov_verify_username_password( RADIUS_INFO *radius_info,
int
radiusov_get_password_from_uid
(
RADIUS_INFO
*
radius_info
,
search_descriptor
*
sd
,
char
*
pszUsername
,
char
*
password
,
size_t
len
)
size_t
password_
len
)
{
char
filter
[
1024
];
sprintf
(
filter
,
"(uid=%s)"
,
pszUsername
);
int
rc
=
radiusov_generalized_database_fetch
(
radius_info
->
radius_db
,
sd
->
search_base
,
sd
->
search_scope
,
filter
,
"userPassword"
,
password
,
len
);
int
rc
;
char
achSearchString
[
256
];
convert_search_string
(
achSearchString
,
sizeof
(
achSearchString
),
radius_info
->
lud_radius_user
->
lud_filter
,
pszUsername
);
rc
=
radiusov_generalized_database_fetch
(
radius_info
->
radius_db
,
radius_info
->
lud_radius_user
->
lud_dn
,
radius_info
->
lud_radius_user
->
lud_scope
,
achSearchString
,
radius_info
->
lud_radius_user
->
lud_attrs
[
0
],
password
,
password_len
);
return
rc
;
}
static
int
radiusov_test_and_development
(
void
*
ctx
,
RADIUS_INFO
*
radius_info
,
radiusov_test_and_development
(
RADIUS_INFO
*
radius_info
,
search_descriptor
*
sd
,
uint8_t
*
pszUsernamePassword_
)
{
...
...
@@ -539,42 +552,59 @@ radiusov_acceptconn(void *ctx, void *arg)
getsockname
(
radius_info
->
radius_udp_socket
,
(
struct
sockaddr
*
)
&
us
,
&
len
);
int
our_port
=
ntohs
(
us
.
sin_port
);
// Find our search_descriptor from the client_ipa and the our_port
// TODO: Ultimately this should be a map, not a linear search.
search_descriptor
*
sd
=
search_descriptors
;
while
(
sd
->
client_ipa
)
{
if
(
radius_info
->
radius_port_number
==
our_port
&&
strcmp
(
sd
->
client_ipa
,
client_ipa
)
==
0
)
{
// We have a match on our port number and the client's IP address
break
;
}
sd
+=
1
;
}
if
(
!
sd
->
client_ipa
)
Debug
(
LDAP_DEBUG_ARGS
,
"Incoming RADIUS client is %s on %d
\n
"
,
client_ipa
,
our_port
);
// We now search the directory tree for a RADIUS client device with
// this ip address and our port:
char
achOurPort
[
12
];
char
achSearchString
[
256
];
char
achSharedSecret
[
256
];
sprintf
(
achOurPort
,
"%d"
,
our_port
);
convert_search_string
(
achSearchString
,
sizeof
(
achSearchString
),
radius_info
->
lud_radius_client
->
lud_filter
,
client_ipa
,
achOurPort
);
rc
=
radiusov_generalized_database_fetch
(
radius_info
->
radius_db
,
radius_info
->
lud_radius_client
->
lud_dn
,
radius_info
->
lud_radius_client
->
lud_scope
,
achSearchString
,
radius_info
->
lud_radius_client
->
lud_attrs
[
0
],
achSharedSecret
,
sizeof
(
achSharedSecret
)
);
if
(
rc
)
{
Debug
(
LDAP_DEBUG_ANY
,
"radiusov: There is no search descriptor for %s and port %d
\n
"
,
client_ipa
,
our_port
)
;
Debug
(
LDAP_DEBUG_ARGS
,
"We couldn't find that IP Address / Port pair in the DIT
\n
"
);
return
NULL
;
}
// We have a good search_descriptor. At this point, we
// dispatch based on the search_method:
search_descriptor
sd_
;
search_descriptor
*
sd
=
&
sd_
;
sd
->
shared_secret
=
achSharedSecret
;
switch
(
sd
->
search_method
)
int
search_method
=
RADIUS_PROTOCOL
;
if
(
strcmp
(
achSharedSecret
,
"SpecialLocalTest"
)
==
0
)
{
search_method
=
TEST_AND_DEVELOPMENT
;
}
switch
(
search_method
)
{
case
TEST_AND_DEVELOPMENT
:
rc
=
radiusov_test_and_development
(
ctx
,
radius_info
,
sd
,
rc
=
radiusov_test_and_development
(
radius_info
,
sd
,
incoming_request
);
break
;
case
RADIUS_PROTOCOL
:
rc
=
radiusov_protocol
(
ctx
,
radius_info
,
rc
=
radiusov_protocol
(
radius_info
,
radius_info
->
radius_udp_socket
,
&
client_addr
,
sd
,
...
...
@@ -583,16 +613,6 @@ radiusov_acceptconn(void *ctx, void *arg)
// In general, that routine returns NO_RESPONSE_NECESSARY,
// because it will have handled the response itself.
break
;
default:
Debug
(
LDAP_DEBUG_ANY
,
"radiusov: The search descriptor for %s and "
"port %d has invalid search_method %d
\n
"
,
client_ipa
,
our_port
,
sd
->
search_method
)
;
return
NULL
;
break
;
}
switch
(
rc
)
...
...
@@ -724,6 +744,7 @@ enum
RADIUS_PORT
=
1
,
RADIUS_HOST
,
RADIUS_CLIENT_URI
,
RADIUS_USER_URI
,
RADIUS_TEST
,
};
...
...
@@ -771,13 +792,27 @@ static ConfigTable radiuscfg[] =
NULL
,
NULL
},
{
"radiususeruri"
,
"Search URI for a user's password"
,
2
,
2
,
0
,
ARG_MAGIC
|
RADIUS_USER_URI
,
radius_config_driver
,
"( OLcfgOvAt:"
OVERLAY_OID
".4 NAME 'olcRadiusUserUri' "
"DESC 'URL for searching for a users password' "
"EQUALITY caseIgnoreMatch "
"SYNTAX OMsDirectoryString "
")"
,
NULL
,
NULL
},
{
"radiustest"
,
"Search URI for simple testing"
,
2
,
2
,
0
,
ARG_MAGIC
|
RADIUS_TEST
,
radius_config_driver
,
"( OLcfgOvAt:"
OVERLAY_OID
".
4
NAME 'olcRadiusTest' "
"( OLcfgOvAt:"
OVERLAY_OID
".
5
NAME 'olcRadiusTest' "
"DESC 'URL for simple searches in the test environment' "
"EQUALITY caseIgnoreMatch "
"SYNTAX OMsDirectoryString "
...
...
@@ -830,6 +865,16 @@ radius_config_driver(ConfigArgs *config_args)
" radiusport is %d
\n
"
,
atoi
(
config_args
->
argv
[
1
]));
radius_info
->
radius_port_number
=
atoi
(
config_args
->
argv
[
1
]);
if
(
radius_info
->
radius_port_number
<=
0
||
radius_info
->
radius_port_number
>
65535
)
{
Debug
(
LDAP_DEBUG_ANY
,
"The RADIUS port number is %d, which makes no "
"sense; it has to be a 16-bit number
\n
"
,
radius_info
->
radius_port_number
);
return
1
;
}
}
break
;
...
...
@@ -860,6 +905,20 @@ radius_config_driver(ConfigArgs *config_args)
}
break
;
case
RADIUS_USER_URI
:
if
(
config_args
->
argc
>
1
)
{
if
(
ldap_url_parse
(
config_args
->
argv
[
1
],
&
radius_info
->
lud_radius_user
)
)
{
Debug
(
LDAP_DEBUG_ANY
,
"ldap_url_parse FAILED on %s
\n
"
,
config_args
->
argv
[
1
]);
rc
=
1
;
}
}
break
;
case
RADIUS_TEST
:
if
(
config_args
->
argc
>
1
)
{
...
...
@@ -940,6 +999,7 @@ radiusov_db_destroy(BackendDB *be, ConfigReply *cr )
ch_free
(
radius_info
->
openssl_configuration
);
ldap_free_urldesc
(
radius_info
->
lud_simple_test
);
ldap_free_urldesc
(
radius_info
->
lud_radius_client
);
ldap_free_urldesc
(
radius_info
->
lud_radius_user
);
ch_free
(
radius_info
);
...
...
@@ -958,17 +1018,6 @@ radiusov_db_open(BackendDB *be, ConfigReply *cr)
slap_overinst
*
radiusov
=
(
slap_overinst
*
)
be
->
bd_info
;
RADIUS_INFO
*
radius_info
=
radiusov
->
on_bi
.
bi_private
;
if
(
radius_info
->
radius_port_number
<=
0
||
radius_info
->
radius_port_number
>
65535
)
{
Debug
(
LDAP_DEBUG_ANY
,
"%s(): The first search_descriptor specifies RADIUS "
"port %d, which makes no sense
\n
"
,
__func__
,
radius_info
->
radius_port_number
);
return
1
;
}
if
(
slapMode
&
SLAP_SERVER_MODE
)
{
rc
=
radiusov_create_udp_port
(
be
,
...
...
contrib/slapd-modules/radiusov/radiusov.h
View file @
ee167d34
...
...
@@ -60,13 +60,12 @@
typedef
struct
_STATE_VOLATILES
{
void
*
ctx
;
struct
_RADIUS_INFO
*
radius_info
;
int
udp_socket
;
struct
sockaddr_in
*
client_addr
;
struct
_search_descriptor
*
sd
;
struct
_RADIUS_PACKET
*
request
;
struct
_EAP_MESSAGE
*
eap_message
;
int
udp_socket
;
struct
sockaddr_in
*
client_addr
;
struct
_search_descriptor
*
sd
;
struct
_RADIUS_PACKET
*
request
;
struct
_EAP_MESSAGE
*
eap_message
;
}
STATE_VOLATILES
;
typedef
struct
_STATE
...
...
@@ -114,7 +113,8 @@ typedef struct _RADIUS_INFO
int
radius_port_number
;
// From slapd.conf
char
radius_port_host
[
256
];
// From slapd.conf. Usually 127.0.0.1, but
// // we leave room for a fully qualified domain name
LDAPURLDesc
*
lud_radius_client
;
// From slapd.conf. The parsed search URI for RADIUS client shared secrete
LDAPURLDesc
*
lud_radius_client
;
// From slapd.conf. The parsed search URI for RADIUS client shared secret
LDAPURLDesc
*
lud_radius_user
;
// From slapd.conf. The parsed search URI for RADIUS user password
LDAPURLDesc
*
lud_simple_test
;
// From slapd.conf. The parsed search URI for simple testing
int
radius_udp_socket
;
...
...
@@ -127,23 +127,16 @@ typedef struct _RADIUS_INFO
typedef
enum
_search_methods
{
INVALID_SEARCH_METHOD
,
TEST_AND_DEVELOPMENT
,
// Expects a simple <username>,<password> in the input packet
RADIUS_PROTOCOL
,
// This is a formal RADIUS protocol implementation
}
search_methods
;
typedef
struct
_search_descriptor
{
char
*
client_ipa
;
search_methods
search_method
;
int
search_scope
;
char
*
search_filter_template
;
char
*
search_base
;
char
*
shared_secret
;
}
search_descriptor
;
int
radiusov_protocol
(
void
*
ctx
,
RADIUS_INFO
*
radius_info
,
int
radiusov_protocol
(
RADIUS_INFO
*
radius_info
,
int
udp_socket
,
struct
sockaddr_in
*
client_addr
,
search_descriptor
*
sd
,
...
...
@@ -190,7 +183,6 @@ void hmac_md5_final( MD5_CTX *context,
uint8_t
*
digest
);
int
radiusov_get_password_from_uid
(
RADIUS_INFO
*
radius_info
,
search_descriptor
*
sd
,
char
*
pszUsername
,
char
*
password
,
size_t
len
);
...
...
Write
Preview
Supports
Markdown
0%
Try again
or
attach a new file
.
Attach a 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