aboutsummaryrefslogtreecommitdiffstats
path: root/addressbook/gui/component/openldap-extract.h
diff options
context:
space:
mode:
Diffstat (limited to 'addressbook/gui/component/openldap-extract.h')
-rw-r--r--addressbook/gui/component/openldap-extract.h1427
1 files changed, 0 insertions, 1427 deletions
diff --git a/addressbook/gui/component/openldap-extract.h b/addressbook/gui/component/openldap-extract.h
deleted file mode 100644
index 996bf370a8..0000000000
--- a/addressbook/gui/component/openldap-extract.h
+++ /dev/null
@@ -1,1427 +0,0 @@
-/* This is extracted from the OpenLDAP sources.
- *
- * Stuff that isn't used in e-book-backend-ldap.c was dropped, like
- * the LDAPSchemaExtensionItem stuff.
- *
- * This file basically has three parts:
- *
- * - some general macros from OpenLDAP that work as such on all
- * implementations.
- *
- * - ldap_str2objectclass()
- *
- * - ldap_url_parse()
- */
-
-/* This work is part of OpenLDAP Software <http://www.openldap.org/>.
- *
- * Copyright 1998-2005 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 in file COPYING.OPENLDAP in
- * the top-level directory of the distribution or, alternatively, at
- * <http://www.OpenLDAP.org/license.html>.
- */
-
-#include <string.h>
-#include <assert.h>
-
-/* from various header files */
-
-#define LDAP_CONST const
-
-#define LDAP_PORT 389 /* ldap:/// default LDAP port */
-#define LDAPS_PORT 636 /* ldaps:/// default LDAP over TLS port */
-
-#define LDAP_ROOT_DSE ""
-
-#define LDAP_SPACE(c) ((c) == ' ' || (c) == '\t' || (c) == '\n')
-#define LDAP_DIGIT(c) ((c) >= '0' && (c) <= '9')
-
-#define LDAP_EXOP_START_TLS "1.3.6.1.4.1.1466.20037" /* RFC 2830 */
-
-#define LDAP_MALLOC(n) malloc((n))
-#define LDAP_CALLOC(n,s) calloc((n),(s))
-#define LDAP_REALLOC(p,s) realloc((p),(s))
-#define LDAP_FREE(p) free((p))
-#define LDAP_VFREE(p) vfree((gpointer *)(p))
-#define LDAP_STRDUP(s) strdup((s))
-
-#define LDAP_RANGE(n,x,y) (((x) <= (n)) && ((n) <= (y)))
-#define LDAP_NAME_ERROR(n) LDAP_RANGE((n),0x20,0x24) /* 32-34,36 */
-
-#define ldap_msgtype(lm) (lm)->lm_msgtype
-#define ldap_msgid(lm) (lm)->lm_msgid
-
-#define LDAP_SCHERR_OUTOFMEM 1
-#define LDAP_SCHERR_UNEXPTOKEN 2
-#define LDAP_SCHERR_NOLEFTPAREN 3
-#define LDAP_SCHERR_NORIGHTPAREN 4
-#define LDAP_SCHERR_NODIGIT 5
-#define LDAP_SCHERR_BADNAME 6
-#define LDAP_SCHERR_BADDESC 7
-#define LDAP_SCHERR_BADSUP 8
-#define LDAP_SCHERR_DUPOPT 9
-#define LDAP_SCHERR_EMPTY 10
-#define LDAP_SCHERR_MISSING 11
-#define LDAP_SCHERR_OUT_OF_ORDER 12
-
-#define LDAP_SCHEMA_YES 1
-
-#define LDAP_SCHEMA_ABSTRACT 0
-#define LDAP_SCHEMA_STRUCTURAL 1
-#define LDAP_SCHEMA_AUXILIARY 2
-
-#define LDAP_SCHEMA_ALLOW_NONE 0x00U /* Strict parsing */
-#define LDAP_SCHEMA_ALLOW_NO_OID 0x01U /* Allow missing oid */
-#define LDAP_SCHEMA_ALLOW_QUOTED 0x02U /* Allow bogus extra quotes */
-#define LDAP_SCHEMA_ALLOW_DESCR 0x04U /* Allow descr instead of OID */
-#define LDAP_SCHEMA_ALLOW_DESCR_PREFIX 0x08U /* Allow descr as OID prefix */
-#define LDAP_SCHEMA_ALLOW_OID_MACRO 0x10U /* Allow OID macros in slapd */
-#define LDAP_SCHEMA_ALLOW_OUT_OF_ORDER_FIELDS 0x20U /* Allow fields in most any order */
-#define LDAP_SCHEMA_ALLOW_ALL 0x3fU /* Be very liberal in parsing */
-#define LDAP_SCHEMA_SKIP 0x80U /* Don't malloc any result */
-
-typedef struct ldap_objectclass {
- gchar *oc_oid; /* REQUIRED */
- gchar **oc_names; /* OPTIONAL */
- gchar *oc_desc; /* OPTIONAL */
- gint oc_obsolete; /* 0=no, 1=yes */
- gchar **oc_sup_oids; /* OPTIONAL */
- gint oc_kind; /* 0=ABSTRACT, 1=STRUCTURAL, 2=AUXILIARY */
- gchar **oc_at_oids_must; /* OPTIONAL */
- gchar **oc_at_oids_may; /* OPTIONAL */
-} LDAPObjectClass;
-
-
-static void
-vfree(gpointer *vec)
-{
- gint i;
-
- for (i = 0; vec[i] != NULL; i++)
- free(vec[i]);
-}
-
-/* from schema.c */
-
-/*
- * Now come the parsers. There is one parser for each entity type:
- * objectclasses, attributetypes, etc.
- *
- * Each of them is written as a recursive-descent parser, except that
- * none of them is really recursive. But the idea is kept: there
- * is one routine per non-terminal that eithers gobbles lexical tokens
- * or calls lower-level routines, etc.
- *
- * The scanner is implemented in the routine get_token. Actually,
- * get_token is more than a scanner and will return tokens that are
- * in fact non-terminals in the grammar. So you can see the whole
- * approach as the combination of a low-level bottom-up recognizer
- * combined with a scanner and a number of top-down parsers. Or just
- * consider that the real grammars recognized by the parsers are not
- * those of the standards. As a matter of fact, our parsers are more
- * liberal than the spec when there is no ambiguity.
- *
- * The difference is pretty academic (modulo bugs or incorrect
- * interpretation of the specs).
- */
-
-#define TK_NOENDQUOTE -2
-#define TK_OUTOFMEM -1
-#define TK_EOS 0
-#define TK_UNEXPCHAR 1
-#define TK_BAREWORD 2
-#define TK_QDSTRING 3
-#define TK_LEFTPAREN 4
-#define TK_RIGHTPAREN 5
-#define TK_DOLLAR 6
-#define TK_QDESCR TK_QDSTRING
-
-struct token {
- gint type;
- gchar *sval;
-};
-
-static gint
-get_token( const gchar ** sp, gchar ** token_val )
-{
- gint kind;
- const gchar * p;
- const gchar * q;
- gchar * res;
-
- *token_val = NULL;
- switch (**sp) {
- case '\0':
- kind = TK_EOS;
- (*sp)++;
- break;
- case '(':
- kind = TK_LEFTPAREN;
- (*sp)++;
- break;
- case ')':
- kind = TK_RIGHTPAREN;
- (*sp)++;
- break;
- case '$':
- kind = TK_DOLLAR;
- (*sp)++;
- break;
- case '\'':
- kind = TK_QDSTRING;
- (*sp)++;
- p = *sp;
- while ( **sp != '\'' && **sp != '\0' )
- (*sp)++;
- if ( **sp == '\'' ) {
- q = *sp;
- res = LDAP_MALLOC(q-p+1);
- if ( !res ) {
- kind = TK_OUTOFMEM;
- } else {
- strncpy(res,p,q-p);
- res[q-p] = '\0';
- *token_val = res;
- }
- (*sp)++;
- } else {
- kind = TK_NOENDQUOTE;
- }
- break;
- default:
- kind = TK_BAREWORD;
- p = *sp;
- while ( !LDAP_SPACE(**sp) &&
- **sp != '(' &&
- **sp != ')' &&
- **sp != '$' &&
- **sp != '\'' &&
- **sp != '\0' )
- (*sp)++;
- q = *sp;
- res = LDAP_MALLOC(q-p+1);
- if ( !res ) {
- kind = TK_OUTOFMEM;
- } else {
- strncpy(res,p,q-p);
- res[q-p] = '\0';
- *token_val = res;
- }
- break;
-/* kind = TK_UNEXPCHAR; */
-/* break; */
- }
-
- return kind;
-}
-
-/* Gobble optional whitespace */
-static void
-parse_whsp(const gchar **sp)
-{
- while (LDAP_SPACE(**sp))
- (*sp)++;
-}
-
-/* Parse a sequence of dot-separated decimal strings */
-static gchar *
-ldap_int_parse_numericoid(const gchar **sp, gint *code, const gint flags)
-{
- gchar * res = NULL;
- const gchar * start = *sp;
- gint len;
- gint quoted = 0;
-
- /* Netscape puts the SYNTAX value in quotes (incorrectly) */
- if ( flags & LDAP_SCHEMA_ALLOW_QUOTED && **sp == '\'' ) {
- quoted = 1;
- (*sp)++;
- start++;
- }
- /* Each iteration of this loop gets one decimal string */
- while (**sp) {
- if ( !LDAP_DIGIT(**sp) ) {
- /*
- * Initial gchar is not a digit or gchar after dot is
- * not a digit
- */
- *code = LDAP_SCHERR_NODIGIT;
- return NULL;
- }
- (*sp)++;
- while ( LDAP_DIGIT(**sp) )
- (*sp)++;
- if ( **sp != '.' )
- break;
- /* Otherwise, gobble the dot and loop again */
- (*sp)++;
- }
- /* Now *sp points at the gchar past the numericoid. Perfect. */
- len = *sp - start;
- if ( flags & LDAP_SCHEMA_ALLOW_QUOTED && quoted ) {
- if ( **sp == '\'' ) {
- (*sp)++;
- } else {
- *code = LDAP_SCHERR_UNEXPTOKEN;
- return NULL;
- }
- }
- if (flags & LDAP_SCHEMA_SKIP) {
- res = (gchar *)start;
- } else {
- res = LDAP_MALLOC(len+1);
- if (!res) {
- *code = LDAP_SCHERR_OUTOFMEM;
- return(NULL);
- }
- strncpy(res,start,len);
- res[len] = '\0';
- }
- return(res);
-}
-
-/* Parse a qdescr or a list of them enclosed in () */
-static gchar **
-parse_qdescrs(const gchar **sp, gint *code)
-{
- gchar ** res;
- gchar ** res1;
- gint kind;
- gchar * sval;
- gint size;
- gint pos;
-
- parse_whsp(sp);
- kind = get_token(sp,&sval);
- if ( kind == TK_LEFTPAREN ) {
- /* Let's presume there will be at least 2 entries */
- size = 3;
- res = LDAP_CALLOC(3,sizeof(gchar *));
- if ( !res ) {
- *code = LDAP_SCHERR_OUTOFMEM;
- return NULL;
- }
- pos = 0;
- while (1) {
- parse_whsp(sp);
- kind = get_token(sp,&sval);
- if ( kind == TK_RIGHTPAREN )
- break;
- if ( kind == TK_QDESCR ) {
- if ( pos == size-2 ) {
- size++;
- res1 = LDAP_REALLOC(res,size*sizeof(gchar *));
- if ( !res1 ) {
- LDAP_VFREE(res);
- LDAP_FREE(sval);
- *code = LDAP_SCHERR_OUTOFMEM;
- return(NULL);
- }
- res = res1;
- }
- res[pos++] = sval;
- res[pos] = NULL;
- parse_whsp(sp);
- } else {
- LDAP_VFREE(res);
- LDAP_FREE(sval);
- *code = LDAP_SCHERR_UNEXPTOKEN;
- return(NULL);
- }
- }
- parse_whsp(sp);
- return(res);
- } else if ( kind == TK_QDESCR ) {
- res = LDAP_CALLOC(2,sizeof(gchar *));
- if ( !res ) {
- *code = LDAP_SCHERR_OUTOFMEM;
- return NULL;
- }
- res[0] = sval;
- res[1] = NULL;
- parse_whsp(sp);
- return res;
- } else {
- LDAP_FREE(sval);
- *code = LDAP_SCHERR_BADNAME;
- return NULL;
- }
-}
-
-/* Parse a woid or a $-separated list of them enclosed in () */
-static gchar **
-parse_oids(const gchar **sp, gint *code, const gint allow_quoted)
-{
- gchar ** res;
- gchar ** res1;
- gint kind;
- gchar * sval;
- gint size;
- gint pos;
-
- /*
- * Strictly speaking, doing this here accepts whsp before the
- * ( at the begining of an oidlist, but this is harmless. Also,
- * we are very liberal in what we accept as an OID. Maybe
- * refine later.
- */
- parse_whsp(sp);
- kind = get_token(sp,&sval);
- if ( kind == TK_LEFTPAREN ) {
- /* Let's presume there will be at least 2 entries */
- size = 3;
- res = LDAP_CALLOC(3,sizeof(gchar *));
- if ( !res ) {
- *code = LDAP_SCHERR_OUTOFMEM;
- return NULL;
- }
- pos = 0;
- parse_whsp(sp);
- kind = get_token(sp,&sval);
- if ( kind == TK_BAREWORD ||
- ( allow_quoted && kind == TK_QDSTRING ) ) {
- res[pos++] = sval;
- res[pos] = NULL;
- } else {
- *code = LDAP_SCHERR_UNEXPTOKEN;
- LDAP_FREE(sval);
- LDAP_VFREE(res);
- return NULL;
- }
- parse_whsp(sp);
- while (1) {
- kind = get_token(sp,&sval);
- if ( kind == TK_RIGHTPAREN )
- break;
- if ( kind == TK_DOLLAR ) {
- parse_whsp(sp);
- kind = get_token(sp,&sval);
- if ( kind == TK_BAREWORD ||
- ( allow_quoted &&
- kind == TK_QDSTRING ) ) {
- if ( pos == size-2 ) {
- size++;
- res1 = LDAP_REALLOC(res,size*sizeof(gchar *));
- if ( !res1 ) {
- LDAP_FREE(sval);
- LDAP_VFREE(res);
- *code = LDAP_SCHERR_OUTOFMEM;
- return(NULL);
- }
- res = res1;
- }
- res[pos++] = sval;
- res[pos] = NULL;
- } else {
- *code = LDAP_SCHERR_UNEXPTOKEN;
- LDAP_FREE(sval);
- LDAP_VFREE(res);
- return NULL;
- }
- parse_whsp(sp);
- } else {
- *code = LDAP_SCHERR_UNEXPTOKEN;
- LDAP_FREE(sval);
- LDAP_VFREE(res);
- return NULL;
- }
- }
- parse_whsp(sp);
- return(res);
- } else if ( kind == TK_BAREWORD ||
- ( allow_quoted && kind == TK_QDSTRING ) ) {
- res = LDAP_CALLOC(2,sizeof(gchar *));
- if ( !res ) {
- LDAP_FREE(sval);
- *code = LDAP_SCHERR_OUTOFMEM;
- return NULL;
- }
- res[0] = sval;
- res[1] = NULL;
- parse_whsp(sp);
- return res;
- } else {
- LDAP_FREE(sval);
- *code = LDAP_SCHERR_BADNAME;
- return NULL;
- }
-}
-
-static void
-ldap_objectclass_free(LDAPObjectClass * oc)
-{
- LDAP_FREE(oc->oc_oid);
- if (oc->oc_names) LDAP_VFREE(oc->oc_names);
- if (oc->oc_desc) LDAP_FREE(oc->oc_desc);
- if (oc->oc_sup_oids) LDAP_VFREE(oc->oc_sup_oids);
- if (oc->oc_at_oids_must) LDAP_VFREE(oc->oc_at_oids_must);
- if (oc->oc_at_oids_may) LDAP_VFREE(oc->oc_at_oids_may);
- LDAP_FREE(oc);
-}
-
-static LDAPObjectClass *
-ldap_str2objectclass( LDAP_CONST gchar * s,
- gint * code,
- LDAP_CONST gchar ** errp,
- LDAP_CONST unsigned flags )
-{
- gint kind;
- const gchar * ss = s;
- gchar * sval;
- gint seen_name = 0;
- gint seen_desc = 0;
- gint seen_obsolete = 0;
- gint seen_sup = 0;
- gint seen_kind = 0;
- gint seen_must = 0;
- gint seen_may = 0;
- LDAPObjectClass * oc;
- gchar ** ext_vals;
- const gchar * savepos;
-
- if ( !s ) {
- *code = LDAP_SCHERR_EMPTY;
- *errp = "";
- return NULL;
- }
-
- *errp = s;
- oc = LDAP_CALLOC(1,sizeof(LDAPObjectClass));
-
- if ( !oc ) {
- *code = LDAP_SCHERR_OUTOFMEM;
- return NULL;
- }
- oc->oc_kind = LDAP_SCHEMA_STRUCTURAL;
-
- kind = get_token(&ss,&sval);
- if ( kind != TK_LEFTPAREN ) {
- *code = LDAP_SCHERR_NOLEFTPAREN;
- LDAP_FREE(sval);
- ldap_objectclass_free(oc);
- return NULL;
- }
-
- /*
- * Definitions MUST begin with an OID in the numericoid format.
- * However, this routine is used by clients to parse the response
- * from servers and very well known servers will provide an OID
- * in the wrong format or even no OID at all. We do our best to
- * extract info from those servers.
- */
- parse_whsp(&ss);
- savepos = ss;
- oc->oc_oid = ldap_int_parse_numericoid(&ss,code,0);
- if ( !oc->oc_oid ) {
- if ( (flags & LDAP_SCHEMA_ALLOW_ALL) && (ss == savepos) ) {
- /* Backtracking */
- ss = savepos;
- kind = get_token(&ss,&sval);
- if ( kind == TK_BAREWORD ) {
- if ( !strcasecmp(sval, "NAME") ||
- !strcasecmp(sval, "DESC") ||
- !strcasecmp(sval, "OBSOLETE") ||
- !strcasecmp(sval, "SUP") ||
- !strcasecmp(sval, "ABSTRACT") ||
- !strcasecmp(sval, "STRUCTURAL") ||
- !strcasecmp(sval, "AUXILIARY") ||
- !strcasecmp(sval, "MUST") ||
- !strcasecmp(sval, "MAY") ||
- !strncasecmp(sval, "X-", 2) ) {
- /* Missing OID, backtrack */
- ss = savepos;
- } else if ( flags &
- LDAP_SCHEMA_ALLOW_OID_MACRO ) {
- /* Non-numerical OID, ignore */
- gint len = ss-savepos;
- oc->oc_oid = LDAP_MALLOC(len+1);
- strncpy(oc->oc_oid, savepos, len);
- oc->oc_oid[len] = 0;
- }
- }
- LDAP_FREE(sval);
- } else {
- *errp = ss;
- ldap_objectclass_free(oc);
- return NULL;
- }
- }
- parse_whsp(&ss);
-
- /*
- * Beyond this point we will be liberal an accept the items
- * in any order.
- */
- while (1) {
- kind = get_token(&ss,&sval);
- switch (kind) {
- case TK_EOS:
- *code = LDAP_SCHERR_NORIGHTPAREN;
- *errp = ss;
- ldap_objectclass_free(oc);
- return NULL;
- case TK_RIGHTPAREN:
- return oc;
- case TK_BAREWORD:
- if ( !strcasecmp(sval,"NAME") ) {
- LDAP_FREE(sval);
- if ( seen_name ) {
- *code = LDAP_SCHERR_DUPOPT;
- *errp = ss;
- ldap_objectclass_free(oc);
- return(NULL);
- }
- seen_name = 1;
- oc->oc_names = parse_qdescrs(&ss,code);
- if ( !oc->oc_names ) {
- if ( *code != LDAP_SCHERR_OUTOFMEM )
- *code = LDAP_SCHERR_BADNAME;
- *errp = ss;
- ldap_objectclass_free(oc);
- return NULL;
- }
- } else if ( !strcasecmp(sval,"DESC") ) {
- LDAP_FREE(sval);
- if ( seen_desc ) {
- *code = LDAP_SCHERR_DUPOPT;
- *errp = ss;
- ldap_objectclass_free(oc);
- return(NULL);
- }
- seen_desc = 1;
- parse_whsp(&ss);
- kind = get_token(&ss,&sval);
- if ( kind != TK_QDSTRING ) {
- *code = LDAP_SCHERR_UNEXPTOKEN;
- *errp = ss;
- LDAP_FREE(sval);
- ldap_objectclass_free(oc);
- return NULL;
- }
- oc->oc_desc = sval;
- parse_whsp(&ss);
- } else if ( !strcasecmp(sval,"OBSOLETE") ) {
- LDAP_FREE(sval);
- if ( seen_obsolete ) {
- *code = LDAP_SCHERR_DUPOPT;
- *errp = ss;
- ldap_objectclass_free(oc);
- return(NULL);
- }
- seen_obsolete = 1;
- oc->oc_obsolete = LDAP_SCHEMA_YES;
- parse_whsp(&ss);
- } else if ( !strcasecmp(sval,"SUP") ) {
- LDAP_FREE(sval);
- if ( seen_sup ) {
- *code = LDAP_SCHERR_DUPOPT;
- *errp = ss;
- ldap_objectclass_free(oc);
- return(NULL);
- }
- seen_sup = 1;
- oc->oc_sup_oids = parse_oids(&ss,
- code,
- flags);
- if ( !oc->oc_sup_oids ) {
- *errp = ss;
- ldap_objectclass_free(oc);
- return NULL;
- }
- } else if ( !strcasecmp(sval,"ABSTRACT") ) {
- LDAP_FREE(sval);
- if ( seen_kind ) {
- *code = LDAP_SCHERR_DUPOPT;
- *errp = ss;
- ldap_objectclass_free(oc);
- return(NULL);
- }
- seen_kind = 1;
- oc->oc_kind = LDAP_SCHEMA_ABSTRACT;
- parse_whsp(&ss);
- } else if ( !strcasecmp(sval,"STRUCTURAL") ) {
- LDAP_FREE(sval);
- if ( seen_kind ) {
- *code = LDAP_SCHERR_DUPOPT;
- *errp = ss;
- ldap_objectclass_free(oc);
- return(NULL);
- }
- seen_kind = 1;
- oc->oc_kind = LDAP_SCHEMA_STRUCTURAL;
- parse_whsp(&ss);
- } else if ( !strcasecmp(sval,"AUXILIARY") ) {
- LDAP_FREE(sval);
- if ( seen_kind ) {
- *code = LDAP_SCHERR_DUPOPT;
- *errp = ss;
- ldap_objectclass_free(oc);
- return(NULL);
- }
- seen_kind = 1;
- oc->oc_kind = LDAP_SCHEMA_AUXILIARY;
- parse_whsp(&ss);
- } else if ( !strcasecmp(sval,"MUST") ) {
- LDAP_FREE(sval);
- if ( seen_must ) {
- *code = LDAP_SCHERR_DUPOPT;
- *errp = ss;
- ldap_objectclass_free(oc);
- return(NULL);
- }
- seen_must = 1;
- oc->oc_at_oids_must = parse_oids(&ss,code,0);
- if ( !oc->oc_at_oids_must ) {
- *errp = ss;
- ldap_objectclass_free(oc);
- return NULL;
- }
- parse_whsp(&ss);
- } else if ( !strcasecmp(sval,"MAY") ) {
- LDAP_FREE(sval);
- if ( seen_may ) {
- *code = LDAP_SCHERR_DUPOPT;
- *errp = ss;
- ldap_objectclass_free(oc);
- return(NULL);
- }
- seen_may = 1;
- oc->oc_at_oids_may = parse_oids(&ss,code,0);
- if ( !oc->oc_at_oids_may ) {
- *errp = ss;
- ldap_objectclass_free(oc);
- return NULL;
- }
- parse_whsp(&ss);
- } else if ( sval[0] == 'X' && sval[1] == '-' ) {
- /* Should be parse_qdstrings */
- ext_vals = parse_qdescrs(&ss, code);
- if ( !ext_vals ) {
- *errp = ss;
- ldap_objectclass_free(oc);
- return NULL;
- }
-#if 0
- if ( add_extension(&oc->oc_extensions,
- sval, ext_vals) ) {
- *code = LDAP_SCHERR_OUTOFMEM;
- *errp = ss;
- LDAP_FREE(sval);
- ldap_objectclass_free(oc);
- return NULL;
- }
-#endif
- } else {
- *code = LDAP_SCHERR_UNEXPTOKEN;
- *errp = ss;
- LDAP_FREE(sval);
- ldap_objectclass_free(oc);
- return NULL;
- }
- break;
- default:
- *code = LDAP_SCHERR_UNEXPTOKEN;
- *errp = ss;
- LDAP_FREE(sval);
- ldap_objectclass_free(oc);
- return NULL;
- }
- }
-}
-
-/* from utf-8.c */
-
-#define LDAP_UTF8_NEXT(p) g_utf8_next_char((p))
-#define LDAP_UTF8_INCR(p) ((p)=LDAP_UTF8_NEXT((p)))
-#define ldap_x_utf8_to_ucs4(str) g_utf8_get_char(str)
-
-static gchar *ldap_utf8_strchr( const gchar *str, const gchar *chr )
-{
- for(; *str != '\0'; LDAP_UTF8_INCR(str) ) {
- if( ldap_x_utf8_to_ucs4( str ) == ldap_x_utf8_to_ucs4( chr ) ) {
- return (gchar *) str;
- }
- }
-
- return NULL;
-}
-
-static gsize ldap_utf8_strcspn( const gchar *str, const gchar *set )
-{
- const gchar *cstr;
- const gchar *cset;
-
- for( cstr = str; *cstr != '\0'; LDAP_UTF8_INCR(cstr) ) {
- for( cset = set; *cset != '\0'; LDAP_UTF8_INCR(cset) ) {
- if( ldap_x_utf8_to_ucs4( cstr ) == ldap_x_utf8_to_ucs4( cset ) ) {
- return cstr - str;
- }
- }
- }
-
- return cstr - str;
-}
-
-static gsize ldap_utf8_strspn( const gchar *str, const gchar *set )
-{
- const gchar *cstr;
- const gchar *cset;
-
- for( cstr = str; *cstr != '\0'; LDAP_UTF8_INCR(cstr) ) {
- for( cset = set; ; LDAP_UTF8_INCR(cset) ) {
- if( *cset == '\0' ) {
- return cstr - str;
- }
-
- if( ldap_x_utf8_to_ucs4( cstr ) == ldap_x_utf8_to_ucs4( cset ) ) {
- break;
- }
- }
- }
-
- return cstr - str;
-}
-
-static gchar *ldap_utf8_strtok(gchar *str, const gchar *sep, gchar **last)
-{
- gchar *begin;
- gchar *end;
-
- if( last == NULL ) return NULL;
-
- begin = str ? str : *last;
-
- begin += ldap_utf8_strspn( begin, sep );
-
- if( *begin == '\0' ) {
- *last = NULL;
- return NULL;
- }
-
- end = &begin[ ldap_utf8_strcspn( begin, sep ) ];
-
- if( *end != '\0' ) {
- gchar *next = LDAP_UTF8_NEXT( end );
- *end = '\0';
- end = next;
- }
-
- *last = end;
- return begin;
-}
-
-/* from ldap.h */
-
-#define LDAP_URL_SUCCESS 0x00 /* Success */
-#define LDAP_URL_ERR_MEM 0x01 /* can't allocate memory space */
-#define LDAP_URL_ERR_PARAM 0x02 /* parameter is bad */
-
-#define LDAP_URL_ERR_BADSCHEME 0x03 /* URL doesn't begin with "ldap[si]://" */
-#define LDAP_URL_ERR_BADENCLOSURE 0x04 /* URL is missing trailing ">" */
-#define LDAP_URL_ERR_BADURL 0x05 /* URL is bad */
-#define LDAP_URL_ERR_BADHOST 0x06 /* host port is bad */
-#define LDAP_URL_ERR_BADATTRS 0x07 /* bad (or missing) attributes */
-#define LDAP_URL_ERR_BADSCOPE 0x08 /* scope string is invalid (or missing) */
-#define LDAP_URL_ERR_BADFILTER 0x09 /* bad or missing filter */
-#define LDAP_URL_ERR_BADEXTS 0x0a /* bad or missing extensions */
-
-#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)
-
-typedef struct ldap_url_desc {
- struct ldap_url_desc *lud_next;
- gchar *lud_scheme;
- gchar *lud_host;
- gint lud_port;
- gchar *lud_dn;
- gchar **lud_attrs;
- gint lud_scope;
- gchar *lud_filter;
- gchar **lud_exts;
- gint lud_crit_exts;
-} LDAPURLDesc;
-
-/* from url.c */
-
-static const gchar *
-skip_url_prefix(
- const gchar *url,
- gint *enclosedp,
- const gchar **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 gchar *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 );
- }
-
-#ifdef LDAP_CONNECTIONLESS
- /* check for "cldap://" prefix */
- if ( strncasecmp( p, LDAPC_URL_PREFIX, LDAPC_URL_PREFIX_LEN ) == 0 ) {
- /* skip over "cldap://" prefix and return success */
- p += LDAPC_URL_PREFIX_LEN;
- *scheme = "cldap";
- return( p );
- }
-#endif
-
- return( NULL );
-}
-
-static gint str2scope( const gchar *p )
-{
- if ( strcasecmp( p, "one" ) == 0 ) {
- return LDAP_SCOPE_ONELEVEL;
-
- } else if ( strcasecmp( p, "onelevel" ) == 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 void
-ldap_free_urldesc( LDAPURLDesc *ludp )
-{
- if ( ludp == NULL ) {
- return;
- }
-
- if ( ludp->lud_scheme != NULL ) {
- LDAP_FREE( ludp->lud_scheme );
- }
-
- if ( ludp->lud_host != NULL ) {
- LDAP_FREE( ludp->lud_host );
- }
-
- if ( ludp->lud_dn != NULL ) {
- LDAP_FREE( ludp->lud_dn );
- }
-
- if ( ludp->lud_filter != NULL ) {
- LDAP_FREE( ludp->lud_filter);
- }
-
- if ( ludp->lud_attrs != NULL ) {
- LDAP_VFREE( ludp->lud_attrs );
- }
-
- if ( ludp->lud_exts != NULL ) {
- LDAP_VFREE( ludp->lud_exts );
- }
-
- LDAP_FREE( ludp );
-}
-
-static gint
-ldap_int_unhex( gint c )
-{
- return( c >= '0' && c <= '9' ? c - '0'
- : c >= 'A' && c <= 'F' ? c - 'A' + 10
- : c - 'a' + 10 );
-}
-
-static void
-ldap_pvt_hex_unescape( gchar *s )
-{
- /*
- * Remove URL hex escapes from s... done in place. The basic concept for
- * this routine is borrowed from the WWW library HTUnEscape() routine.
- */
- gchar *p;
-
- for ( p = s; *s != '\0'; ++s ) {
- if ( *s == '%' ) {
- if ( *++s == '\0' ) {
- break;
- }
- *p = ldap_int_unhex( *s ) << 4;
- if ( *++s == '\0' ) {
- break;
- }
- *p++ += ldap_int_unhex( *s );
- } else {
- *p++ = *s;
- }
- }
-
- *p = '\0';
-}
-
-static gchar **
-ldap_str2charray( const gchar *str_in, const gchar *brkstr )
-{
- gchar **res;
- gchar *str, *s;
- gchar *lasts;
- gint i;
-
- /* protect the input string from strtok */
- str = LDAP_STRDUP( str_in );
- if( str == NULL ) {
- return NULL;
- }
-
- i = 1;
- for ( s = str; *s; s++ ) {
- if ( ldap_utf8_strchr( brkstr, s ) != NULL ) {
- i++;
- }
- }
-
- res = (gchar **) LDAP_MALLOC( (i + 1) * sizeof(gchar *) );
-
- if( res == NULL ) {
- LDAP_FREE( str );
- return NULL;
- }
-
- i = 0;
-
- for ( s = ldap_utf8_strtok( str, brkstr, &lasts );
- s != NULL;
- s = ldap_utf8_strtok( NULL, brkstr, &lasts ) )
- {
- res[i] = LDAP_STRDUP( s );
-
- if(res[i] == NULL) {
- for( --i; i >= 0; i-- ) {
- LDAP_FREE( res[i] );
- }
- LDAP_FREE( res );
- LDAP_FREE( str );
- return NULL;
- }
-
- i++;
- }
-
- res[i] = NULL;
-
- LDAP_FREE( str );
- return( res );
-}
-
-static gint
-ldap_url_parse_ext( LDAP_CONST gchar *url_in, LDAPURLDesc **ludpp )
-{
-/*
- * Pick apart the pieces of an LDAP URL.
- */
-
- LDAPURLDesc *ludp;
- gchar *p, *q, *r;
- gint i, enclosed;
- const gchar *scheme = NULL;
- const gchar *url_tmp;
- gchar *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;
- }
-
- assert( scheme );
-
- /* 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 = (LDAPURLDesc *)LDAP_CALLOC( 1, sizeof( LDAPURLDesc ));
-
- if ( ludp == NULL ) {
- LDAP_FREE( url );
- return LDAP_URL_ERR_MEM;
- }
-
- ludp->lud_next = NULL;
- ludp->lud_host = NULL;
- ludp->lud_port = 0;
- ludp->lud_dn = NULL;
- ludp->lud_attrs = NULL;
- ludp->lud_filter = NULL;
- ludp->lud_scope = LDAP_SCOPE_DEFAULT;
- ludp->lud_filter = NULL;
- ludp->lud_exts = NULL;
-
- ludp->lud_scheme = LDAP_STRDUP( scheme );
-
- if ( ludp->lud_scheme == NULL ) {
- LDAP_FREE( url );
- ldap_free_urldesc( ludp );
- return LDAP_URL_ERR_MEM;
- }
-
- /* 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 );
- ldap_free_urldesc( ludp );
- return LDAP_URL_ERR_BADURL;
- }
- *r++ = '\0';
- q = strchr( r, ':' );
- } else {
- q = strchr( url, ':' );
- }
-
- if ( q != NULL ) {
- gchar *next;
-
- *q++ = '\0';
- ldap_pvt_hex_unescape( q );
-
- if( *q == '\0' ) {
- LDAP_FREE( url );
- ldap_free_urldesc( ludp );
- return LDAP_URL_ERR_BADURL;
- }
-
- ludp->lud_port = strtol( q, &next, 10 );
- if ( next == NULL || next[0] != '\0' ) {
- LDAP_FREE( url );
- ldap_free_urldesc( ludp );
- return LDAP_URL_ERR_BADURL;
- }
- }
-
- 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 );
- ldap_free_urldesc( ludp );
- return LDAP_URL_ERR_MEM;
- }
-
- /*
- * Kludge. ldap://111.222.333.444:389??cn=abc,o=company
- *
- * On early Novell releases, search references/referrals were returned
- * in this format, i.e., the dn was kind of in the scope position,
- * but the required slash is missing. The whole thing is illegal syntax,
- * but we need to account for it. Fortunately it can't be confused with
- * anything real.
- */
- if( (p == NULL) && (q != NULL) && ((q = strchr( q, '?')) != NULL)) {
- q++;
- /* ? immediately followed by question */
- if( *q == '?') {
- q++;
- if( *q != '\0' ) {
- /* parse dn part */
- ldap_pvt_hex_unescape( q );
- ludp->lud_dn = LDAP_STRDUP( q );
- } else {
- ludp->lud_dn = LDAP_STRDUP( "" );
- }
-
- if( ludp->lud_dn == NULL ) {
- LDAP_FREE( url );
- ldap_free_urldesc( ludp );
- return LDAP_URL_ERR_MEM;
- }
- }
- }
-
- if( p == NULL ) {
- LDAP_FREE( url );
- *ludpp = ludp;
- return LDAP_URL_SUCCESS;
- }
-
- /* scan forward for '?' that may marks end of dn */
- q = strchr( p, '?' );
-
- if( q != NULL ) {
- /* terminate dn part */
- *q++ = '\0';
- }
-
- if( *p != '\0' ) {
- /* parse dn part */
- ldap_pvt_hex_unescape( p );
- ludp->lud_dn = LDAP_STRDUP( p );
- } else {
- ludp->lud_dn = LDAP_STRDUP( "" );
- }
-
- if( ludp->lud_dn == NULL ) {
- LDAP_FREE( url );
- ldap_free_urldesc( ludp );
- return LDAP_URL_ERR_MEM;
- }
-
- if( q == NULL ) {
- /* no more */
- LDAP_FREE( url );
- *ludpp = ludp;
- return LDAP_URL_SUCCESS;
- }
-
- /* scan forward for '?' that may marks end of attributes */
- p = q;
- q = strchr( p, '?' );
-
- if( q != NULL ) {
- /* terminate attributes part */
- *q++ = '\0';
- }
-
- if( *p != '\0' ) {
- /* parse attributes */
- ldap_pvt_hex_unescape( p );
- ludp->lud_attrs = ldap_str2charray( p, "," );
-
- if( ludp->lud_attrs == NULL ) {
- LDAP_FREE( url );
- ldap_free_urldesc( ludp );
- return LDAP_URL_ERR_BADATTRS;
- }
- }
-
- if ( q == NULL ) {
- /* no more */
- LDAP_FREE( url );
- *ludpp = ludp;
- return LDAP_URL_SUCCESS;
- }
-
- /* scan forward for '?' that may marks end of scope */
- p = q;
- q = strchr( p, '?' );
-
- if( q != NULL ) {
- /* terminate the scope part */
- *q++ = '\0';
- }
-
- if( *p != '\0' ) {
- /* parse the scope */
- ldap_pvt_hex_unescape( p );
- ludp->lud_scope = str2scope( p );
-
- if( ludp->lud_scope == -1 ) {
- LDAP_FREE( url );
- ldap_free_urldesc( ludp );
- return LDAP_URL_ERR_BADSCOPE;
- }
- }
-
- if ( q == NULL ) {
- /* no more */
- LDAP_FREE( url );
- *ludpp = ludp;
- return LDAP_URL_SUCCESS;
- }
-
- /* scan forward for '?' that may marks end of filter */
- p = q;
- q = strchr( p, '?' );
-
- if( q != NULL ) {
- /* terminate the filter part */
- *q++ = '\0';
- }
-
- if( *p != '\0' ) {
- /* parse the filter */
- ldap_pvt_hex_unescape( p );
-
- if( ! *p ) {
- /* missing filter */
- LDAP_FREE( url );
- ldap_free_urldesc( ludp );
- return LDAP_URL_ERR_BADFILTER;
- }
-
- LDAP_FREE( ludp->lud_filter );
- ludp->lud_filter = LDAP_STRDUP( p );
-
- if( ludp->lud_filter == NULL ) {
- LDAP_FREE( url );
- ldap_free_urldesc( ludp );
- return LDAP_URL_ERR_MEM;
- }
- }
-
- if ( q == NULL ) {
- /* no more */
- LDAP_FREE( url );
- *ludpp = ludp;
- return LDAP_URL_SUCCESS;
- }
-
- /* scan forward for '?' that may marks end of extensions */
- p = q;
- q = strchr( p, '?' );
-
- if( q != NULL ) {
- /* extra '?' */
- LDAP_FREE( url );
- ldap_free_urldesc( ludp );
- return LDAP_URL_ERR_BADURL;
- }
-
- /* parse the extensions */
- ludp->lud_exts = ldap_str2charray( p, "," );
-
- if( ludp->lud_exts == NULL ) {
- LDAP_FREE( url );
- ldap_free_urldesc( ludp );
- return LDAP_URL_ERR_BADEXTS;
- }
-
- for( i=0; ludp->lud_exts[i] != NULL; i++ ) {
- ldap_pvt_hex_unescape( ludp->lud_exts[i] );
-
- if( *ludp->lud_exts[i] == '!' ) {
- /* count the number of critical extensions */
- ludp->lud_crit_exts++;
- }
- }
-
- if( i == 0 ) {
- /* must have 1 or more */
- LDAP_FREE( url );
- ldap_free_urldesc( ludp );
- return LDAP_URL_ERR_BADEXTS;
- }
-
- /* no more */
- *ludpp = ludp;
- LDAP_FREE( url );
- return LDAP_URL_SUCCESS;
-}
-
-static gint
-ldap_url_parse( LDAP_CONST gchar *url_in, LDAPURLDesc **ludpp )
-{
- gint rc = ldap_url_parse_ext( url_in, ludpp );
-
- if( rc != LDAP_URL_SUCCESS ) {
- return rc;
- }
-
- if ((*ludpp)->lud_scope == LDAP_SCOPE_DEFAULT) {
- (*ludpp)->lud_scope = LDAP_SCOPE_BASE;
- }
-
- if ((*ludpp)->lud_host != NULL && *(*ludpp)->lud_host == '\0') {
- LDAP_FREE( (*ludpp)->lud_host );
- (*ludpp)->lud_host = NULL;
- }
-
- if ((*ludpp)->lud_port == 0) {
- if( strcmp((*ludpp)->lud_scheme, "ldap") == 0 ) {
- (*ludpp)->lud_port = LDAP_PORT;
-#ifdef LDAP_CONNECTIONLESS
- } else if( strcmp((*ludpp)->lud_scheme, "cldap") == 0 ) {
- (*ludpp)->lud_port = LDAP_PORT;
-#endif
- } else if( strcmp((*ludpp)->lud_scheme, "ldaps") == 0 ) {
- (*ludpp)->lud_port = LDAPS_PORT;
- }
- }
-
- return rc;
-}
-