On Sun, Jun 24, 2018 at 05:58:09PM -0400, Rob Pierce wrote: > It looks like a BER problem found while testing the new ldap client (with an > empty password) was already addressed in snmpd back in 2010 by martinh. > > In LDAP under a CONTEXT class, 0 corresponds to LDAP_AUTH_SIMPLE. This is > currently interpreted as an EOC (end-of-content) and causes a > miscalculation of the length which results in unexpected behaviour. > > Reyk pointed me in the right direction, and after much messing around I came > up with a solution which was close to the following snmpd commit. > > From the src/usr.sbin/snmpd/ber.c commit log: > > ---------------------------- > revision 1.23 > date: 2010/09/20 08:30:13; author: martinh; state: Exp; lines: +3 -2; > Allow output of null values with a context class. This is used in SNMPv2 to > return an error exception value for a varbind result ("noSuchObject[0] > IMPLICIT NULL" in rfc1905). > ---------------------------- > > However, BER_TYPE_EOC only applies to the UNIVERSAL class, so I think an > explicit check against BER_CLASS_UNIVERSAL is a better solution and works > across both ldap and snmp. > > The following diff applies this change to ldap, ldapd, and ypldap, and brings > snmpd in line with this approach. > > Thoughts? > > Ok?
I think the analysis is correct (my BER knowledge is rusty) and the fix looks good. OK claudio@ > Index: usr.bin/ldap/ber.c > =================================================================== > RCS file: /cvs/src/usr.bin/ldap/ber.c,v > retrieving revision 1.1.1.1 > diff -u -p -r1.1.1.1 ber.c > --- usr.bin/ldap/ber.c 13 Jun 2018 15:45:57 -0000 1.1.1.1 > +++ usr.bin/ldap/ber.c 24 Jun 2018 21:37:39 -0000 > @@ -861,7 +861,8 @@ ber_calc_len(struct ber_element *root) > size += ber_calc_len(root->be_next); > > /* This is an empty element, do not use a minimal size */ > - if (root->be_type == BER_TYPE_EOC && root->be_len == 0) > + if (root->be_class == BER_CLASS_UNIVERSAL && > + root->be_type == BER_TYPE_EOC && root->be_len == 0) > return (0); > > return (root->be_len + size); > > Index: usr.sbin/ldapd/ber.c > =================================================================== > RCS file: /cvs/src/usr.sbin/ldapd/ber.c,v > retrieving revision 1.13 > diff -u -p -r1.13 ber.c > --- usr.sbin/ldapd/ber.c 8 Feb 2018 18:02:06 -0000 1.13 > +++ usr.sbin/ldapd/ber.c 24 Jun 2018 21:37:39 -0000 > @@ -874,7 +874,8 @@ ber_calc_len(struct ber_element *root) > size += ber_calc_len(root->be_next); > > /* This is an empty element, do not use a minimal size */ > - if (root->be_type == BER_TYPE_EOC && root->be_len == 0) > + if (root->be_class == BER_CLASS_UNIVERSAL && > + root->be_type == BER_TYPE_EOC && root->be_len == 0) > return (0); > > return (root->be_len + size); > > Index: usr.sbin/ypldap/ber.c > =================================================================== > RCS file: /cvs/src/usr.sbin/ypldap/ber.c,v > retrieving revision 1.13 > diff -u -p -r1.13 ber.c > --- usr.sbin/ypldap/ber.c 8 Feb 2018 18:02:06 -0000 1.13 > +++ usr.sbin/ypldap/ber.c 24 Jun 2018 21:37:39 -0000 > @@ -861,7 +861,8 @@ ber_calc_len(struct ber_element *root) > size += ber_calc_len(root->be_next); > > /* This is an empty element, do not use a minimal size */ > - if (root->be_type == BER_TYPE_EOC && root->be_len == 0) > + if (root->be_class == BER_CLASS_UNIVERSAL && > + root->be_type == BER_TYPE_EOC && root->be_len == 0) > return (0); > > return (root->be_len + size); > > Index: usr.sbin/snmpd/ber.c > =================================================================== > RCS file: /cvs/src/usr.sbin/snmpd/ber.c,v > retrieving revision 1.32 > diff -u -p -r1.32 ber.c > --- usr.sbin/snmpd/ber.c 8 Feb 2018 18:02:06 -0000 1.32 > +++ usr.sbin/snmpd/ber.c 24 Jun 2018 21:37:39 -0000 > @@ -880,7 +880,7 @@ ber_calc_len(struct ber_element *root) > size += ber_calc_len(root->be_next); > > /* This is an empty element, do not use a minimal size */ > - if (root->be_class != BER_CLASS_CONTEXT && > + if (root->be_class == BER_CLASS_UNIVERSAL && > root->be_type == BER_TYPE_EOC && root->be_len == 0) > return (0); > > -- :wq Claudio