diff options
Diffstat (limited to 'ldap/clients/dsgw/dosearch.c')
-rw-r--r-- | ldap/clients/dsgw/dosearch.c | 352 |
1 files changed, 352 insertions, 0 deletions
diff --git a/ldap/clients/dsgw/dosearch.c b/ldap/clients/dsgw/dosearch.c new file mode 100644 index 00000000..01afe6c9 --- /dev/null +++ b/ldap/clients/dsgw/dosearch.c @@ -0,0 +1,352 @@ +/** + * PROPRIETARY/CONFIDENTIAL. Use of this product is subject to + * license terms. Copyright © 2001 Sun Microsystems, Inc. + * Some preexisting portions Copyright © 2001 Netscape Communications Corp. + * All rights reserved. + */ +/* + * dosearch.c -- CGI search handler -- HTTP gateway + * + * Copyright (c) 1996 Netscape Communications Corp. + * All rights reserved. + */ + +#include "dsgw.h" + +static void get_request(char* hostport, char *dn, char *ldapquery); +static void post_request(); + + +int main( argc, argv, env ) + int argc; + char *argv[]; +#ifdef DSGW_DEBUG + char *env[]; +#endif +{ + int reqmethod; + char *qs = NULL; + char *dn = NULL; + char *hostport = NULL; + char *ldapquery = NULL; +#ifndef __LP64__ +#ifdef HPUX + /* call the static constructors in libnls */ + _main(); +#endif +#endif + /* + * Parse out the GET args, if any. See the comments under + * get_request for an explanation of what's going on here + */ + if (( qs = getenv( "QUERY_STRING" )) != NULL && *qs != '\0' ) { + /* parse the query string: */ + auto char *p, *iter = NULL; + qs = dsgw_ch_strdup( qs ); + + for ( p = ldap_utf8strtok_r( qs, "&", &iter ); p != NULL; + p = ldap_utf8strtok_r( NULL, "&", &iter )) { + + /* + * Get the conf file name. It'll be translated + * into /dsgw/context/CONTEXT.conf if + * CONTEXT is all alphanumeric (no slahes, + * or dots). CONTEXT is passed into the cgi. + * if context=CONTEXT is not there, or PATH_INFO + * was used, then use dsgw.conf + */ + if ( !strncasecmp( p, "context=", 8 )) { + context = dsgw_ch_strdup( p + 8 ); + dsgw_form_unescape( context ); + continue; + } + + if ( !strncasecmp( p, "hp=", 3 )) { + hostport = dsgw_ch_strdup( p + 3 ); + dsgw_form_unescape( hostport ); + continue; + } + + if ( !strncasecmp( p, "ldq=", 4 )) { + ldapquery = dsgw_ch_strdup( p + 4 ); + dsgw_form_unescape( ldapquery ); + continue; + } + + if ( !strncasecmp( p, "dn=", 3 )) { + dn = dsgw_ch_strdup( p + 3 ); + dsgw_form_unescape( dn ); + continue; + } + + /* + * If it doesn't match any of the above, then + * tack it onto the end of ldapquery. + */ + if (ldapquery != NULL) { + ldapquery = dsgw_ch_realloc(ldapquery, sizeof(char *) * (strlen(ldapquery) + strlen(p) + 2)); + sprintf( ldapquery, "%s&%s", ldapquery, p ); + } + } + + free( qs ); qs = NULL; + } + + + reqmethod = dsgw_init( argc, argv, DSGW_METHOD_POST | DSGW_METHOD_GET ); + + /* + * Note: we don't call dsgw_send_header() here like we usually do because + * on a GET we may be asked to return a MIME type other than the default + * of text/html. For GET requests, we send the headers inside + * ldaputil.c:dsgw_ldapurl_search(). For POST requests, we send them + * below in post_request(). + */ + +#ifdef DSGW_DEBUG + dsgw_logstringarray( "env", env ); +#endif + + if ( reqmethod == DSGW_METHOD_GET ) { + get_request(hostport, dn, ldapquery); + } else { + post_request(); + } + + exit( 0 ); +} + + +static void +get_request(char* hostport, char *dn, char *ldapquery) +{ + int urllen = 0; + int argslen = 0; + char *p = NULL; + char *ldapurl = NULL; + + /* + * The following comment is kept here only as a reminder of the past. + * It is no longer relevant. See the next comment. - RJP + * + * On a GET request, we do an LDAP URL search (which will just display + * a single entry if all that is included is "host:port/DN"). + * The HTTP URL should be: + * .../dosearch[/host[:port]][?[dn=baseDN&][LDAPquery]] + * This will be converted to the LDAP URL: + * ldap://[host[:port]]/[baseDN][?LDAPquery] + * + * For compatibility with prior versions, the HTTP URL may be: + * .../dosearch/host[:port]/[baseDN][?LDAPquery] + * In this case, the host:port is required, since PATH_INFO can't + * start with a '/' (web server sees that as a different program). + * This older HTTP URL format is deprecated, because PATH_INFO is + * not 8-bit clean on Japanese Windows NT. + */ + + /* + * The only form supported now is: + * .../dosearch?context=BLAH[&hp=host[:port]][&dn=baseDN][&ldq=LDAPquery]] + * -RJP + */ + argslen = 0; + + /* get the length of all the args (dn, hostport, ldapquery)*/ + if (hostport != NULL) { + argslen += strlen(hostport); + } + + if (dn != NULL) { + argslen += strlen(dn); + } + + if (ldapquery != NULL) { + argslen += strlen(ldapquery); + } + + /* If nothing was supplied, exit*/ + if ( argslen == 0 ) { + dsgw_error( DSGW_ERR_MISSINGINPUT, NULL, DSGW_ERROPT_EXIT, 0, NULL ); + } + + /* Malloc the ldapurl*/ + urllen = LDAP_URL_PREFIX_LEN + argslen + 3; + p = ldapurl = (char *)dsgw_ch_malloc( urllen ); + + /*Slap on ldap:// */ + strcpy( p, LDAP_URL_PREFIX ); + p += LDAP_URL_PREFIX_LEN; + + /*Slap on host:port if there is one*/ + if ( hostport != NULL ) { + strcpy( p, hostport ); + } + + strcat( ldapurl, "/" ); + + /*Slap on /dn, if there is a dn */ + if ( dn != NULL ) { + strcat( ldapurl, dn ); + } + + /*Slap on ?ldapquery */ + if ( ldapquery != NULL ) { + sprintf( ldapurl + strlen( ldapurl ), "?%s", ldapquery ); + } + +#ifdef DSGW_DEBUG + dsgw_log( "get_request: processing LDAP URL \"%s\"\n", ldapurl ); +#endif + dsgw_ldapurl_search( NULL, ldapurl); +} + + +static void +post_request() +{ + char *modestr, *searchstring, *type, *base; + LDAP *ld; + LDAPFiltDesc *lfdp; + struct ldap_searchobj *solistp, *sop; + int authmode, mode, options; + + dsgw_send_header(); + + options = 0; + modestr = dsgw_get_cgi_var( "mode", DSGW_CGIVAR_REQUIRED ); + searchstring = dsgw_get_cgi_var( "searchstring", DSGW_CGIVAR_OPTIONAL ); + dsgw_remove_leading_and_trailing_spaces( &searchstring ); +#ifdef DSGW_DEBUG + if (searchstring) { + dsgw_log ("searchstring=\"%s\"\n", searchstring); + } else { + dsgw_log ("searchstring=NULL"); + } +#endif + + authmode = 0; + if ( strcasecmp( modestr, DSGW_SRCHMODE_AUTH ) == 0 ) { + /* + * treat authenticate as a variant of the smart search mode + */ + authmode = 1; + mode = DSGW_SRCHMODE_SMART_ID; + options |= DSGW_DISPLAY_OPT_AUTH; + } else if ( strcasecmp( modestr, DSGW_SRCHMODE_SMART ) == 0 ) { + mode = DSGW_SRCHMODE_SMART_ID; + } else if ( strcasecmp( modestr, DSGW_SRCHMODE_COMPLEX ) == 0 ) { + mode = DSGW_SRCHMODE_COMPLEX_ID; + } else if ( strcasecmp( modestr, DSGW_SRCHMODE_PATTERN ) == 0 ) { + mode = DSGW_SRCHMODE_PATTERN_ID; + } else { + dsgw_error( DSGW_ERR_SEARCHMODE, modestr, 0, 0, NULL ); + } + + if ( mode != DSGW_SRCHMODE_PATTERN_ID + && ( searchstring == NULL || *searchstring == '\0' )) { + dsgw_error( DSGW_ERR_NOSEARCHSTRING, NULL, DSGW_ERROPT_EXIT, 0, NULL ); + } + + if (( type = dsgw_get_cgi_var( "type", authmode ? DSGW_CGIVAR_OPTIONAL : + DSGW_CGIVAR_REQUIRED )) == NULL ) { + type = DSGW_SRCHTYPE_AUTH; + } + + if (( base = dsgw_get_cgi_var( "base", DSGW_CGIVAR_OPTIONAL )) == NULL ) { + base = gc->gc_ldapsearchbase; + } + + /* check for options (carried in boolean CGI variables) */ + if ( dsgw_get_boolean_var( "listifone", DSGW_CGIVAR_OPTIONAL, 0 )) { + options |= DSGW_DISPLAY_OPT_LIST_IF_ONE; + } + + if ( dsgw_get_boolean_var( "editable", DSGW_CGIVAR_OPTIONAL, 0 )) { + options |= DSGW_DISPLAY_OPT_EDITABLE; + } + + if ( dsgw_get_boolean_var( "link2edit", DSGW_CGIVAR_OPTIONAL, 0 )) { + options |= DSGW_DISPLAY_OPT_LINK2EDIT; + } + + if ( dsgw_get_boolean_var( "dnlist_js", DSGW_CGIVAR_OPTIONAL, 0 )) { + options |= DSGW_DISPLAY_OPT_DNLIST_JS; + } + + (void) dsgw_init_ldap( &ld, &lfdp, ( authmode == 1 ) ? 1 : 0, 0); + + if ( mode != DSGW_SRCHMODE_PATTERN_ID ) { + dsgw_init_searchprefs( &solistp ); + + if (( sop = dsgw_type2searchobj( solistp, type )) == NULL ) { + ldap_unbind( ld ); + dsgw_error( DSGW_ERR_UNKSRCHTYPE, type, DSGW_ERROPT_EXIT, 0, NULL ); + } + } + + switch( mode ) { + case DSGW_SRCHMODE_SMART_ID: + /* + * smart search mode -- try to do the right kind of search for the + * client based on what the user entered in the search box + */ + dsgw_smart_search( ld, sop, lfdp, base, searchstring, options ); + break; + + case DSGW_SRCHMODE_COMPLEX_ID: { + /* + * complex search mode -- construct a specific filter based on + * user's form selections + */ + int scope; + char *attrlabel, *matchprompt; + struct ldap_searchattr *sap; + struct ldap_searchmatch *smp; + + attrlabel = dsgw_get_cgi_var( "attr", DSGW_CGIVAR_REQUIRED ); + if (( sap = dsgw_label2searchattr( sop, attrlabel )) == NULL ) { + ldap_unbind( ld ); + dsgw_error( DSGW_ERR_UNKATTRLABEL, attrlabel, DSGW_ERROPT_EXIT, + 0, NULL ); + } + + matchprompt = dsgw_get_cgi_var( "match", DSGW_CGIVAR_REQUIRED ); + if (( smp = dsgw_prompt2searchmatch( sop, matchprompt )) == NULL ) { + ldap_unbind( ld ); + dsgw_error( DSGW_ERR_UNKMATCHPROMPT, matchprompt, + DSGW_ERROPT_EXIT, 0, NULL ); + } + + scope = dsgw_get_int_var( "scope", DSGW_CGIVAR_OPTIONAL, + sop->so_defaultscope ); + dsgw_pattern_search( ld, sop->so_objtypeprompt, + sap->sa_attrlabel, smp->sm_matchprompt, searchstring, + smp->sm_filter, sop->so_filterprefix, NULL, sap->sa_attr, + base, scope, searchstring, options ); + } + break; + + case DSGW_SRCHMODE_PATTERN_ID: { + /* + * pattern-based search mode (no searchprefs or filter file used) + */ + char *attr, *pattern, *prefix, *suffix, *searchdesc; + int scope; + + attr = dsgw_get_cgi_var( "attr", DSGW_CGIVAR_REQUIRED ); + pattern = dsgw_get_cgi_var( "filterpattern", DSGW_CGIVAR_REQUIRED ); + prefix = dsgw_get_cgi_var( "filterprefix", DSGW_CGIVAR_OPTIONAL ); + suffix = dsgw_get_cgi_var( "filtersuffix", DSGW_CGIVAR_OPTIONAL ); + scope = dsgw_get_int_var( "scope", DSGW_CGIVAR_OPTIONAL, + LDAP_SCOPE_SUBTREE ); + options |= DSGW_DISPLAY_OPT_CUSTOM_SEARCHDESC; + searchdesc = dsgw_get_cgi_var( "searchdesc", DSGW_CGIVAR_OPTIONAL ); + dsgw_pattern_search( ld, type, searchdesc, NULL, NULL, + pattern, prefix, suffix, attr, + base, scope, searchstring, options ); + } + break; + } + + ldap_unbind( ld ); +} |