[Date Prev][Date Next] [Chronological] [Thread] [Top]

Re: [PATCH-sorta] telephoneNumberMatch and an introduction



For indexing, only a few NULLs need to be replaced with appropriate
function pointers.

For better syntax validation, the telephoneNumberValidator() function
needs to be written.  IIRC, IA5 matching can be used on properly
validated strings to produce the proper result.

Kurt

At 11:01 AM 5/2/01, dg50@daimlerchrysler.com wrote:
>Hi folks,
>
>My name is Dennis Grant. I've been the chief LDAP codemonkey here at
>DaimlerChrysler since 1998 or so. I'm the guy who built the DCX corporate
>directory, all the various utilities that go with its daily operation, and
>I'm still the chief coal-shoveller when it comes to all things LDAP.
>
>Some of my utilities have made it into PerLDAP, I believe.
>
>Anyway, our infrastructure is based on the fine family of Netscape
>products, and will likely remain so for some time. However, we've come up
>with an expansion plan whereby replicas of the main Directory will be
>pushed out to all of our manufacturing plants. The plan is that these
>servers will be Linux boxen running OpenLDAP as the server software.
>
>Accordingly, my attention has become highly focussed on Netscape->OpenLDAP
>interoperability issues. I want - as much as possible - our Directory
>Services infrastructure server-neutral. The same utilities, the same
>configurations, the same LDIF core content on all servers, no matter if the
>platform is Netscape or OpenLDAP.
>
>Given that they share the same codebase (to a certain extent) this isn't as
>unrealistic as one might otherwise fear. ;)
>
>Failing that, I can live with conversion tools, so that (for example) when
>extending the schema, we edit the slapd.user_at.conf on the Netscape
>servers, and then run a utility that spits out an OpenLDAP .schema file -
>or even more useful, a tool that reads the Netscape ACIs from the Directory
>and spits out OpenLDAP ACI config files.
>
>I'm not afraid of coding, and I believe in sharing what we write, so as my
>itches get scratched, I will be forwarding them back here for inclusion
>into OpenLDAP.
>
>This is the first such itch. Our schema has a few attributes with the
>telephoneNumber syntax OID, and these attributes are indexed. However, the
>telephoneNumberMatch match type is not yet implimented. (As of OpenLDAP
>2.0.7 at least) Accordingly, the attempt to load our Directory into
>OpenLDAP barfed on the invalid equality indicies.
>
>So I had a look at the code, and figured I'd try tackling implementing it.
>
>WARNING: Although, once upon a time, I did a lot of C work, in the last 10
>years or so I've been living in a mostly perl world. Perl spoils you with
>things like variable-length strings and regular expressions. So my C code
>is a little... workmanlike. Perhaps even "basic".
>
>Attached is what I think is an implementation of the telephoneNumberMatch
>subroutine. It goes in slapd/schema_init.c It compiles. :)
>
>I'm sending it in for review (before I get too deep) and for further
>instructions on what do do next. The slapd code isn't as commented as I'd
>like, it's hard at times to see where all the flow points are. This much I
>figured out, so here's the patch. :)
>
>Assistance with how to go forward from this point would be greatly
>appreciated. Code critique - no matter how brutal - is also solicited. ;)
>
>Thanks,
>
>DG
>
>-------------------------------------
>Insert this into "schema_init.c"
>
>static int
>telephoneNumberMatch(
>     int *matchp,
>     slap_mask_t flags,
>     Syntax *syntax,
>     MatchingRule *mr,
>     struct berval *value,
>     void *assertedValue )
>{
>     /* Added May 02/2001 by DG (dg50@dcx.com)
>
>        Match a telephone number.
>
>        Strip out anything not a decimal digit, and then compare the
>        numbers that remain. Eliminates human-readable formatting
>        characters not germane to the actual number.
>
>        For example:
>
>        (604) 555-5555
>        (604) 555 5555
>        604 555 5555
>        604.555.5555
>
>        are all the same number, and should match.
>
>        FIXME: Maybe we could bake some more intelligence in here, should
>
>        1 (604) 555-5555
>           +1 604 555 5555
>           604.555.5555
>
>           all match? Would have to do some parsing and some DWIM processing.
>
>     PARAMETERS
>          *value         The actual value berval
>          *assertedValue The value we're checking against berval
>          *matchp        Result code (or something)
>
>     */
>
>     /* Buffers for the filtered strings */
>     char filtered_value[value->bv_len];
>     char filtered_assertedValue[((struct berval *) assertedValue)->bv_len];
>
>     /* counters */
>     int n = 0;
>     int i = 0;
>
>     /* match flag of some sort... not sure what nonzero means */
>     int match = 0;
>
>     /* Loop over the value string, copy over digits */
>     for (n = 0; n < value->bv_len; n++) {
>          if (isdigit(value->bv_val[n])) {
>               filtered_value[i] = value->bv_val[n];
>               i++;
>          }
>     }
>
>     /* Ditto the assertedValue string */
>     i = 0;
>     for (n = 0; n < ((struct berval *) assertedValue)->bv_len; n++) {
>          if (isdigit(((struct berval *) assertedValue)->bv_val[n])) {
>               filtered_assertedValue[i] = ((struct berval *) assertedValue)->bv_val[n];
>               i++;
>          }
>     }
>
>
>     /* if both filtered values are the same length, we can check them
>        otherwise, skip the check */
>
>     match = strlen(filtered_value) - strlen(filtered_assertedValue);
>
>     if( match == 0 ) {
>          /* same length! So check them.
>             FIXME: the counter i as the length argument to strncmp
>                    to save another strlen call. Is this valid?
>             FIXME: Why strncmp? Why not just strcmp? */
>
>          match = strncmp( filtered_value,
>                        filtered_assertedValue,
>                     i );
>     }
>
>     /* Not sure where this is defined, but all the other *Match routines
>        use it, so we'll Steal With Pride here */
>
>     *matchp = match;
>     return LDAP_SUCCESS;
>}