⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 apr_ldap_url.c

📁 一套很值得分析的短信SMS开发源代码。是我今年早些时候从taobao上买来的。但我现在也没看完(先说清楚
💻 C
📖 第 1 页 / 共 2 页
字号:
/* Copyright 2000-2005 The Apache Software Foundation or its licensors, as
 * applicable.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

/* Portions Copyright 1998-2002 The OpenLDAP Foundation
 * All rights reserved.
 * 
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted only as authorized by the OpenLDAP
 * Public License.  A copy of this license is available at
 * http://www.OpenLDAP.org/license.html or in file LICENSE in the
 * top-level directory of the distribution.
 * 
 * OpenLDAP is a registered trademark of the OpenLDAP Foundation.
 * 
 * Individual files and/or contributed packages may be copyright by
 * other parties and subject to additional restrictions.
 * 
 * This work is derived from the University of Michigan LDAP v3.3
 * distribution.  Information concerning this software is available
 * at: http://www.umich.edu/~dirsvcs/ldap/
 * 
 * This work also contains materials derived from public sources.
 * 
 * Additional information about OpenLDAP can be obtained at:
 *     http://www.openldap.org/
 */

/* 
 * Portions Copyright (c) 1992-1996 Regents of the University of Michigan.
 * All rights reserved.
 * 
 * Redistribution and use in source and binary forms are permitted
 * provided that this notice is preserved and that due credit is given
 * to the University of Michigan at Ann Arbor. The name of the University
 * may not be used to endorse or promote products derived from this
 * software without specific prior written permission. This software
 * is provided ``as is'' without express or implied warranty.
 */

/*  apr_ldap_url.c -- LDAP URL (RFC 2255) related routines
 *
 *  Win32 and perhaps other non-OpenLDAP based ldap libraries may be
 *  missing ldap_url_* APIs.  We focus here on the one significant
 *  aspect, which is parsing.  We have [for the time being] omitted
 *  the ldap_url_search APIs.
 *
 *  LDAP URLs look like this:
 *    ldap[is]://host:port[/[dn[?[attributes][?[scope][?[filter][?exts]]]]]]
 *
 *  where:
 *   attributes is a comma separated list
 *   scope is one of these three strings:  base one sub (default=base)
 *   filter is an string-represented filter as in RFC 2254
 *
 *  e.g.,  ldap://host:port/dc=com?o,cn?base?o=openldap?extension
 *
 *  Tolerates URLs that look like: <ldapurl> and <URL:ldapurl>
 */

#include "apr_ldap.h"

#if APR_HAS_LDAP

#if !APR_HAS_LDAP_URL_PARSE

#include "apr_general.h"
#include "apr_strings.h"

#ifndef LDAPS_PORT
#define LDAPS_PORT              636  /* ldaps:/// default LDAP over TLS port */
#endif

#define LDAP_URL_PREFIX         "ldap://"
#define LDAP_URL_PREFIX_LEN     (sizeof(LDAP_URL_PREFIX)-1)
#define LDAPS_URL_PREFIX        "ldaps://"
#define LDAPS_URL_PREFIX_LEN    (sizeof(LDAPS_URL_PREFIX)-1)
#define LDAPI_URL_PREFIX        "ldapi://"
#define LDAPI_URL_PREFIX_LEN    (sizeof(LDAPI_URL_PREFIX)-1)
#define LDAP_URL_URLCOLON       "URL:"
#define LDAP_URL_URLCOLON_LEN   (sizeof(LDAP_URL_URLCOLON)-1)

#define LDAP_STRDUP(x) strdup(x)
#define LDAP_CALLOC(n, s) calloc(n, s)
#define LDAP_MALLOC(n) malloc(n)
#define LDAP_REALLOC(x, n) realloc(x, n)
#define LDAP_FREE(x) free(x)
#define LDAP_VFREE(a) ldap_charray_free(a)

#define ldap_utf8_strchr(x, s) strchr(x, *s)
#define ldap_utf8_strtok(x, s, l) apr_strtok(x, s, l)

/* local functions */
static const char* skip_url_prefix(const char *url, int *enclosedp,
                                   const char **scheme);

static void ldap_pvt_hex_unescape(char *s);

static int ldap_pvt_unhex(int c);

static void ldap_charray_free(char **a);

static char **ldap_str2charray(const char *str, const char *brkstr);

APU_DECLARE(int) apr_ldap_is_ldap_url(const char *url)
{
    int enclosed;
    const char * scheme;

    if( url == NULL ) {
        return 0;
    }

    if( skip_url_prefix( url, &enclosed, &scheme ) == NULL ) {
        return 0;
    }

    return 1;
}

APU_DECLARE(int) apr_ldap_is_ldaps_url(const char *url)
{
    int enclosed;
    const char * scheme;

    if( url == NULL ) {
        return 0;
    }

    if( skip_url_prefix( url, &enclosed, &scheme ) == NULL ) {
        return 0;
    }

    return strcmp(scheme, "ldaps") == 0;
}

APU_DECLARE(int) apr_ldap_is_ldapi_url(const char *url)
{
    int enclosed;
    const char * scheme;

    if( url == NULL ) {
        return 0;
    }

    if( skip_url_prefix( url, &enclosed, &scheme ) == NULL ) {
        return 0;
    }

    return strcmp(scheme, "ldapi") == 0;
}

static const char *skip_url_prefix(const char *url, int *enclosedp,
                                   const char **scheme)
{
    /*
     * return non-zero if this looks like a LDAP URL; zero if not
     * if non-zero returned, *urlp will be moved past "ldap://" part of URL
     */
    const char *p;

    if ( url == NULL ) {
        return( NULL );
    }

    p = url;

    /* skip leading '<' (if any) */
    if ( *p == '<' ) {
        *enclosedp = 1;
        ++p;
    } else {
        *enclosedp = 0;
    }

    /* skip leading "URL:" (if any) */
    if ( strncasecmp( p, LDAP_URL_URLCOLON, LDAP_URL_URLCOLON_LEN ) == 0 ) {
        p += LDAP_URL_URLCOLON_LEN;
    }

    /* check for "ldap://" prefix */
    if ( strncasecmp( p, LDAP_URL_PREFIX, LDAP_URL_PREFIX_LEN ) == 0 ) {
        /* skip over "ldap://" prefix and return success */
        p += LDAP_URL_PREFIX_LEN;
        *scheme = "ldap";
        return( p );
    }

    /* check for "ldaps://" prefix */
    if ( strncasecmp( p, LDAPS_URL_PREFIX, LDAPS_URL_PREFIX_LEN ) == 0 ) {
        /* skip over "ldaps://" prefix and return success */
        p += LDAPS_URL_PREFIX_LEN;
        *scheme = "ldaps";
        return( p );
    }

    /* check for "ldapi://" prefix */
    if ( strncasecmp( p, LDAPI_URL_PREFIX, LDAPI_URL_PREFIX_LEN ) == 0 ) {
        /* skip over "ldapi://" prefix and return success */
        p += LDAPI_URL_PREFIX_LEN;
        *scheme = "ldapi";
        return( p );
    }

    return( NULL );
}


static int str2scope(const char *p)
{
    if ( strcasecmp( p, "one" ) == 0 ) {
        return LDAP_SCOPE_ONELEVEL;

    } else if ( strcasecmp( p, "onetree" ) == 0 ) {
        return LDAP_SCOPE_ONELEVEL;

    } else if ( strcasecmp( p, "base" ) == 0 ) {
        return LDAP_SCOPE_BASE;

    } else if ( strcasecmp( p, "sub" ) == 0 ) {
        return LDAP_SCOPE_SUBTREE;

    } else if ( strcasecmp( p, "subtree" ) == 0 ) {
        return LDAP_SCOPE_SUBTREE;
    }

    return( -1 );
}


static int ldap_url_parse_ext(const char *url_in, 
                              apr_ldap_url_desc_t **ludpp)
{
/*
 *  Pick apart the pieces of an LDAP URL.
 */
    apr_ldap_url_desc_t *ludp;
    char        *p, *q, *r;
    int         i, enclosed;
    const char  *scheme = NULL;
    const char  *url_tmp;
    char        *url;

    if( url_in == NULL || ludpp == NULL ) {
        return LDAP_URL_ERR_PARAM;
    }

    *ludpp = NULL;  /* pessimistic */

    url_tmp = skip_url_prefix( url_in, &enclosed, &scheme );

    if ( url_tmp == NULL ) {
        return LDAP_URL_ERR_BADSCHEME;
    }

    /* make working copy of the remainder of the URL */
    url = LDAP_STRDUP( url_tmp );
    if ( url == NULL ) {
        return LDAP_URL_ERR_MEM;
    }

    if ( enclosed ) {
        p = &url[strlen(url)-1];

        if( *p != '>' ) {
            LDAP_FREE( url );
            return LDAP_URL_ERR_BADENCLOSURE;
        }

        *p = '\0';
    }

    /* allocate return struct */
    ludp = (apr_ldap_url_desc_t *)LDAP_CALLOC( 1, sizeof( apr_ldap_url_desc_t ));

    if ( ludp == NULL ) {
        LDAP_FREE( url );
        return LDAP_URL_ERR_MEM;
    }

    ludp->lud_next = NULL;
    ludp->lud_host = NULL;
    ludp->lud_port = LDAP_PORT;
    ludp->lud_dn = NULL;
    ludp->lud_attrs = NULL;
    ludp->lud_filter = NULL;
    ludp->lud_scope = -1;
    ludp->lud_filter = NULL;
    ludp->lud_exts = NULL;

    ludp->lud_scheme = LDAP_STRDUP( scheme );

    if ( ludp->lud_scheme == NULL ) {
        LDAP_FREE( url );
        apr_ldap_free_urldesc( ludp );
        return LDAP_URL_ERR_MEM;
    }

    if( strcasecmp( ludp->lud_scheme, "ldaps" ) == 0 ) {
        ludp->lud_port = LDAPS_PORT;
    }

    /* scan forward for '/' that marks end of hostport and begin. of dn */
    p = strchr( url, '/' );

    if( p != NULL ) {
        /* terminate hostport; point to start of dn */
        *p++ = '\0';
    }

    /* IPv6 syntax with [ip address]:port */
    if ( *url == '[' ) {
        r = strchr( url, ']' );
        if ( r == NULL ) {
            LDAP_FREE( url );
            apr_ldap_free_urldesc( ludp );
            return LDAP_URL_ERR_BADURL;
        }
        *r++ = '\0';
        q = strchr( r, ':' );
    } else {
        q = strchr( url, ':' );
    }

    if ( q != NULL ) {
        *q++ = '\0';
        ldap_pvt_hex_unescape( q );

        if( *q == '\0' ) {
            LDAP_FREE( url );
            apr_ldap_free_urldesc( ludp );
            return LDAP_URL_ERR_BADURL;
        }

        ludp->lud_port = atoi( q );
    }

    ldap_pvt_hex_unescape( url );

    /* If [ip address]:port syntax, url is [ip and we skip the [ */
    ludp->lud_host = LDAP_STRDUP( url + ( *url == '[' ) );

    if( ludp->lud_host == NULL ) {
        LDAP_FREE( url );
        apr_ldap_free_urldesc( ludp );
        return LDAP_URL_ERR_MEM;
    }

    /*
     * Kludge.  ldap://111.222.333.444:389??cn=abc,o=company

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -