self-service-password
self-service-password copied to clipboard
allow more than one mail_attribute value
on one of my setups I use two attributes with mail, one is optional (personalMail) and the other one mandatory (mail).
I would like to use first if found and then second one. something similar to ldap_url attribute:
$mail_attribute = "personalMail mail";
thanks for your time
Hello,
this is not possible now. It needs some code in htdocs/sendtoken.php
See https://github.com/ltb-project/self-service-password/blob/master/htdocs/sendtoken.php#L120
I'm trying to configure this on a fresh test installation and I'm facing some problems.
https://self-service-password.readthedocs.io/en/latest/config_mail.html
docs here refers to $mail_attributes but in config.inc.php I only see $mail_attribute so I guess first one is a typo.
I use $mail_address_use_ldap = true; and I can use $mail_attribute = "mail"; but if I try to configure an array like this $mail_attribute = array('personalMail', 'mail'); I get a mailnomatch error: The email address does not match the submitted user name
and this appears in logs:
[Thu Sep 09 12:28:08.304621 2021] [php7:warn] [pid 15739] [client 172.16.236.12:52060] PHP Warning: ldap_get_values() expects parameter 3 to be string, array given in /var/www/html/ssp/htdocs/sendtoken.php on line 122, referer: http://xx.xx.xx.xx/ssp/index.php
[Thu Sep 09 12:28:08.304700 2021] [php7:warn] [pid 15739] [client 172.16.236.12:52060] PHP Warning: count(): Parameter must be an array or an object that implements Countable in /var/www/html/ssp/htdocs/sendtoken.php on line 138, referer: http://xx.xx.xx.xx/ssp/index.php
[Thu Sep 09 12:28:08.304731 2021] [php7:notice] [pid 15739] [client 172.16.236.12:52060] Mail not found for user XXXXX, referer: http://xx.xx.xx.xx/ssp/index.php
Is there any other configuration I'm missing?
let me know if you want me to open a new issue
Are you using code from master?
no, just downloaded zip from GH:
wget https://github.com/ltb-project/self-service-password/archive/refs/tags/v1.4.3.zip
As you can see, the fix is merged in master and will be available in 1.5
@faust64 there will be a need for an upgrade note, as we changed a configuration attribute name
oh! I see, I'll try master now to test it. sorry I missed 1.5 target.
works perfectly!
thanks for your time :)
sorry to resurface this, but I'm having strange behaviour.
I use two attributes: $mail_attributes = array('personalMail', 'mail');
first one is not always present but it should be used if exists. thing is I'm getting an error if first attribute is empty:
[Fri Sep 10 11:30:34.848908 2021] [php7:warn] [pid 17564] [client xx:54702] PHP Warning: ldap_get_values(): Cannot get the value(s) of attribute Decoding error in /var/www/html/clau/htdocs/sendtoken.php on line 123, referer: https://xx/clau/index.php
[Fri Sep 10 11:30:34.848999 2021] [php7:warn] [pid 17564] [client xx:54702] PHP Warning: count(): Parameter must be an array or an object that implements Countable in /var/www/html/clau/htdocs/sendtoken.php on line 137, referer: https://xx/clau/index.php
If I change the order to $mail_attributes = array( 'mail', 'personalMail'); it works, but I need it the other way around.
can you please check it?
I'm using master downloaded yesterday
Line 123 from sendtoken.php would be some $mailValues = ldap_get_values($ldap, $entry, $mail_attribute);
I'm not sure what's going on. Sounds like an issue with that ldap function -- or our input...
Have you looked at this: https://www.php.net/manual/en/function.ldap-get-values-len.php#103586 Or that one: https://stackoverflow.com/questions/32630706/php-ldap-get-values-for-more-than-1-value#comment53112241_32630706
Sounds like that error would show when requesting some invalid attribute name, somehow?
What's that personalMail attribute? Are you sure it's there? Check your schemas, maybe? Can you query its value using ldapsearch, and your self-service-password bind credentials?
If nothing helps, we might try to patch sendtoken.php, such as:
diff --git a/htdocs/sendtoken.php b/htdocs/sendtoken.php
index b7dac98..a436735 100644
--- a/htdocs/sendtoken.php
+++ b/htdocs/sendtoken.php
@@ -120,7 +120,9 @@ if ( $result === "" ) {
# Compare mail values
for ($match = false, $i = 0; $i < sizeof($mail_attributes) and ! $match; $i++) {
$mail_attribute = $mail_attributes[$i];
- $mailValues = ldap_get_values($ldap, $entry, $mail_attribute);
+ if (($mailValues = ldap_get_values($ldap, $entry, $mail_attribute)) == false) {
+ die("ldap_get_values error: ".ldap_error($ldap));
+ }
unset($mailValues["count"]);
if (! $mail_address_use_ldap) {
# Match with user submitted values
syn@sisyphe:~/git/worteks/self-service-password$
I don't really know about ldap functions, but the problems seems to be that it doesn'l like when one of the configured attributes returns no value, and for me it seems that it should be a very common scenario.
isn't there any more arrays that one of the elements return no value in the code?
my two attributes are mail and XXXpersonalMail. first one is standar, second one is a custom one with the name of a company (XXX) and isn't always there, some user objects have it and others don't.
sorry I can't be more helpfull here, I'll test it right away any solution you give me.
When ldap_get_values doesn't find anything for a given attribute, it doesn't throw an error. You would get an object, with a key count
, and its value: 0
.
There's something wrong going on. But I doubt it has to do with attribute not being present.
There's nothing much we can do, without more context on what you're querying. At that stage, ldap_get_values inspects the object returned by your LDAP/AD. Maybe the changes I pointed in my previous post would tell us more about what's going on. Not sure.
Otherwise, https://www.php.net/manual/en/function.ldap-get-values-len.php#103586 says
After using PHP to list the attributes of a particular record I noticed that the attribute userCertificate wasn't listed simply as userCertificate but userCertificate;binary instead.
Though this may not be your case, we could try to dump any attribute name returned for a given user object. Might tell us more about what's going on.
ok, I've found a very easy way to reproduce it, just use description as your other mail attribute:
$mail_attributes = array('description','mail');
if both attributtes are present it works. if first attribute is present it works, if first atribute is empty then it gives the error. so is not really related to my custom schema, it fails with any text attribute.
here's the log:
[Wed Sep 15 21:40:42.211089 2021] [php7:warn] [pid 24487] [client 172.26.69.1:33626] PHP Warning: ldap_get_values(): Cannot get the value(s) of attribute Decoding error in /var/www/html/clautest/htdocs/sendtoken.php on line 123, referer: http://172.26.66.17/clautest/index.php
[Wed Sep 15 21:40:42.211122 2021] [php7:warn] [pid 24487] [client 172.26.69.1:33626] PHP Warning: count(): Parameter must be an array or an object that implements Countable in /var/www/html/clautest/htdocs/sendtoken.php on line 137, referer: http://172.26.66.17/clautest/index.php
[Wed Sep 15 21:40:42.461256 2021] [php7:notice] [pid 24487] [client 172.26.69.1:33626] Send reset URL HIDDEN, referer: http://172.26.66.17/clautest/index.php
[Wed Sep 15 21:40:42.461274 2021] [php7:notice] [pid 24487] [client 172.26.69.1:33626] send_mail: no mail given, exiting..., referer: http://172.26.66.17/clautest/index.php
[Wed Sep 15 21:40:42.461280 2021] [php7:notice] [pid 24487] [client 172.26.69.1:33626] Error while sending token to (user pepet10), referer: http://172.26.66.17/clautest/index.php
any updates on this issue?
Could you try this patch:
diff --git a/htdocs/sendtoken.php b/htdocs/sendtoken.php
index b7dac98..a1ac1e2 100644
--- a/htdocs/sendtoken.php
+++ b/htdocs/sendtoken.php
@@ -120,6 +120,7 @@ if ( $result === "" ) {
# Compare mail values
for ($match = false, $i = 0; $i < sizeof($mail_attributes) and ! $match; $i++) {
$mail_attribute = $mail_attributes[$i];
+ if ( isset $entry[$mail_attribute] ) {
$mailValues = ldap_get_values($ldap, $entry, $mail_attribute);
unset($mailValues["count"]);
if (! $mail_address_use_ldap) {
@@ -143,6 +144,7 @@ if ( $result === "" ) {
$match = true;
}
}
+ }
}
if (! $match) {
there was some missing parentheses here:
if ( isset ($entry[$mail_attribute] )) {
anyway, it doesn't work, I get Mail not found for user XXX
This one should work:
diff --git a/htdocs/sendtoken.php b/htdocs/sendtoken.php
index b7dac98..e904ba0 100644
--- a/htdocs/sendtoken.php
+++ b/htdocs/sendtoken.php
@@ -121,6 +121,7 @@ if ( $result === "" ) {
for ($match = false, $i = 0; $i < sizeof($mail_attributes) and ! $match; $i++) {
$mail_attribute = $mail_attributes[$i];
$mailValues = ldap_get_values($ldap, $entry, $mail_attribute);
+ if ($mailValues) {
unset($mailValues["count"]);
if (! $mail_address_use_ldap) {
# Match with user submitted values
@@ -143,6 +144,7 @@ if ( $result === "" ) {
$match = true;
}
}
+ }
}
if (! $match) {
it works!
the only thing is that if first attribute is empty I receive a warning:
PHP Warning: ldap_get_values(): Cannot get the value(s) of attribute Decoding error in /var/www/html/clautest/htdocs/sendtoken.php on line 123
nothing critical for me.
Indeed, there is a warning. To avoid it we need to first check if the attribute is present in the entry before calling ldap_get_values
. I'll see what we can do.
@muzzol empty attributes are very uncommon and should be avoided since somehow a undefined behavior, you will hit many other problems with various ldap libraries. To be on the safe side empty attributes should just be removed fully.
i believe code that refused it with LDAP_DECODING_ERROR is in ( https://git.openldap.org/openldap/openldap.git ) in ldap_get_values_len function of getvalues.c code.
/*
* if we get this far, we've found the attribute and are sitting
* just before the set of values.
*/
if ( ber_scanf( &ber, "[V]", &vals ) == LBER_ERROR ) {
ld->ld_errno = LDAP_DECODING_ERROR;
return( NULL );
}
where a set of octet string sequence is expected, and something else is found. ( see man ber_scanf ).
I fear that to remove your error, you will have to patch yourself the openldap C library used to comple php ldap extension.
How did you create those empty attributes ?
@artlog the issue is not that the attribute exist and is empty, which is indeed not standard. Here the attribute does not exist in the entry, but our code does not test this before reading the value. So the solution to avoid these warning are to test if the attribute exist in the entry before calling ldap_get_values
Another idea to ease the migration between 1.4 and 1.5: if mail_attributes
is not defined and mail_attribute
exists, then initialize mail_attributes
like this:
$mail_attributes = array($mail_attribute);
Same should be done for mobile (#658)
@muzzol empty attributes are very uncommon and should be avoided since somehow a undefined behavior, you will hit many other problems with various ldap libraries. To be on the safe side empty attributes should just be removed fully.
as @coudot pointed out, my problem was with different attributes that can handle same information.
I think is a quite common issue on big companies, for example with mail (personal mail, recovery password mail), and telephone (extension, mobile, personal phone).
The way @coudot solved it was perfect for me, if one object is not there, just ignore it and go for the next one.
I'm not really sure what's your problem here, feel free to be more specific about your own issue so we can help.
thanks @muzzol & @coudot , i did reproduce it when referencing an un existing attribue ( ie description ). As @coudot wrote, actual testing that attribute exists withing ldap search entry content is the way to handle it properly, i will work on it.
Should be fixed with #676, if you have some time to test
No feedback, works on my side, so I close.