mirror of
https://git.openldap.org/openldap/openldap.git
synced 2026-01-31 10:59:33 -05:00
first cut at ditStructureRule and nameForm routines
This commit is contained in:
parent
c64d28aa4e
commit
63e7c9e796
2 changed files with 705 additions and 71 deletions
|
|
@ -28,12 +28,14 @@ LDAP_BEGIN_DECL
|
|||
#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_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
|
||||
|
||||
typedef struct ldap_schema_extension_item {
|
||||
char *lsei_name;
|
||||
|
|
@ -109,6 +111,27 @@ typedef struct ldap_contentrule {
|
|||
LDAPSchemaExtensionItem **cr_extensions; /* OPTIONAL */
|
||||
} LDAPContentRule;
|
||||
|
||||
typedef struct ldap_nameform {
|
||||
char *nf_oid; /* REQUIRED */
|
||||
char **nf_names; /* OPTIONAL */
|
||||
char *nf_desc; /* OPTIONAL */
|
||||
int nf_obsolete; /* 0=no, 1=yes */
|
||||
char *nf_objectclass; /* REQUIRED */
|
||||
char **nf_at_oids_must; /* REQUIRED */
|
||||
char **nf_at_oids_may; /* OPTIONAL */
|
||||
LDAPSchemaExtensionItem **nf_extensions; /* OPTIONAL */
|
||||
} LDAPNameForm;
|
||||
|
||||
typedef struct ldap_structurerule {
|
||||
int sr_ruleid; /* REQUIRED */
|
||||
char **sr_names; /* OPTIONAL */
|
||||
char *sr_desc; /* OPTIONAL */
|
||||
int sr_obsolete; /* 0=no, 1=yes */
|
||||
char *sr_nameform; /* REQUIRED */
|
||||
int sr_nsup_ruleids;/* number of sr_sup_ruleids */
|
||||
int *sr_sup_ruleids;/* OPTIONAL */
|
||||
LDAPSchemaExtensionItem **sr_extensions; /* OPTIONAL */
|
||||
} LDAPStructureRule;
|
||||
|
||||
/*
|
||||
* Misc macros
|
||||
|
|
@ -129,14 +152,16 @@ typedef struct ldap_contentrule {
|
|||
/*
|
||||
* Flags that control how liberal the parsing routines are.
|
||||
*/
|
||||
#define LDAP_SCHEMA_ALLOW_NONE 0x00 /* Strict parsing */
|
||||
#define LDAP_SCHEMA_ALLOW_NO_OID 0x01 /* Allow missing oid */
|
||||
#define LDAP_SCHEMA_ALLOW_QUOTED 0x02 /* Allow bogus extra quotes */
|
||||
#define LDAP_SCHEMA_ALLOW_DESCR 0x04 /* Allow descr instead of OID */
|
||||
#define LDAP_SCHEMA_ALLOW_DESCR_PREFIX 0x08 /* Allow descr as OID prefix */
|
||||
#define LDAP_SCHEMA_ALLOW_OID_MACRO 0x10 /* Allow OID macros in slapd */
|
||||
#define LDAP_SCHEMA_ALLOW_ALL 0x1f /* Be very liberal in parsing */
|
||||
#define LDAP_SCHEMA_SKIP 0x80 /* Don't malloc any result */
|
||||
#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 */
|
||||
|
||||
|
||||
LDAP_F( LDAP_CONST char * )
|
||||
ldap_syntax2name LDAP_P((
|
||||
|
|
@ -162,6 +187,14 @@ LDAP_F( LDAP_CONST char * )
|
|||
ldap_contentrule2name LDAP_P((
|
||||
LDAPContentRule * cr ));
|
||||
|
||||
LDAP_F( LDAP_CONST char * )
|
||||
ldap_nameform2name LDAP_P((
|
||||
LDAPNameForm * nf ));
|
||||
|
||||
LDAP_F( LDAP_CONST char * )
|
||||
ldap_structurerule2name LDAP_P((
|
||||
LDAPStructureRule * sr ));
|
||||
|
||||
LDAP_F( void )
|
||||
ldap_syntax_free LDAP_P((
|
||||
LDAPSyntax * syn ));
|
||||
|
|
@ -186,55 +219,85 @@ LDAP_F( void )
|
|||
ldap_contentrule_free LDAP_P((
|
||||
LDAPContentRule * cr ));
|
||||
|
||||
LDAP_F( LDAPObjectClass * )
|
||||
ldap_str2objectclass LDAP_P((
|
||||
LDAP_F( void )
|
||||
ldap_nameform_free LDAP_P((
|
||||
LDAPNameForm * nf ));
|
||||
|
||||
LDAP_F( void )
|
||||
ldap_structurerule_free LDAP_P((
|
||||
LDAPStructureRule * sr ));
|
||||
|
||||
LDAP_F( LDAPStructureRule * )
|
||||
ldap_str2structurerule LDAP_P((
|
||||
LDAP_CONST char * s,
|
||||
int * code,
|
||||
LDAP_CONST char ** errp,
|
||||
LDAP_CONST int flags ));
|
||||
LDAP_CONST unsigned flags ));
|
||||
|
||||
LDAP_F( LDAPNameForm * )
|
||||
ldap_str2nameform LDAP_P((
|
||||
LDAP_CONST char * s,
|
||||
int * code,
|
||||
LDAP_CONST char ** errp,
|
||||
LDAP_CONST unsigned flags ));
|
||||
|
||||
LDAP_F( LDAPContentRule * )
|
||||
ldap_str2contentrule LDAP_P((
|
||||
LDAP_CONST char * s,
|
||||
int * code,
|
||||
LDAP_CONST char ** errp,
|
||||
LDAP_CONST int flags ));
|
||||
LDAP_CONST unsigned flags ));
|
||||
|
||||
LDAP_F( LDAPObjectClass * )
|
||||
ldap_str2objectclass LDAP_P((
|
||||
LDAP_CONST char * s,
|
||||
int * code,
|
||||
LDAP_CONST char ** errp,
|
||||
LDAP_CONST unsigned flags ));
|
||||
|
||||
LDAP_F( LDAPAttributeType * )
|
||||
ldap_str2attributetype LDAP_P((
|
||||
LDAP_CONST char * s,
|
||||
int * code,
|
||||
LDAP_CONST char ** errp,
|
||||
LDAP_CONST int flags ));
|
||||
LDAP_CONST unsigned flags ));
|
||||
|
||||
LDAP_F( LDAPSyntax * )
|
||||
ldap_str2syntax LDAP_P((
|
||||
LDAP_CONST char * s,
|
||||
int * code,
|
||||
LDAP_CONST char ** errp,
|
||||
LDAP_CONST int flags ));
|
||||
LDAP_CONST unsigned flags ));
|
||||
|
||||
LDAP_F( LDAPMatchingRule * )
|
||||
ldap_str2matchingrule LDAP_P((
|
||||
LDAP_CONST char * s,
|
||||
int * code,
|
||||
LDAP_CONST char ** errp,
|
||||
LDAP_CONST int flags ));
|
||||
LDAP_CONST unsigned flags ));
|
||||
|
||||
LDAP_F( LDAPMatchingRuleUse * )
|
||||
ldap_str2matchingruleuse LDAP_P((
|
||||
LDAP_CONST char * s,
|
||||
int * code,
|
||||
LDAP_CONST char ** errp,
|
||||
LDAP_CONST int flags ));
|
||||
LDAP_CONST unsigned flags ));
|
||||
|
||||
LDAP_F( char * )
|
||||
ldap_objectclass2str LDAP_P((
|
||||
LDAPObjectClass * oc ));
|
||||
ldap_structurerule2str LDAP_P((
|
||||
LDAPStructureRule * sr ));
|
||||
|
||||
LDAP_F( struct berval * )
|
||||
ldap_objectclass2bv LDAP_P((
|
||||
LDAPObjectClass * oc, struct berval *bv ));
|
||||
ldap_structurerule2bv LDAP_P((
|
||||
LDAPStructureRule * sr, struct berval *bv ));
|
||||
|
||||
LDAP_F( char * )
|
||||
ldap_nameform2str LDAP_P((
|
||||
LDAPNameForm * nf ));
|
||||
|
||||
LDAP_F( struct berval * )
|
||||
ldap_nameform2bv LDAP_P((
|
||||
LDAPNameForm * nf, struct berval *bv ));
|
||||
|
||||
LDAP_F( char * )
|
||||
ldap_contentrule2str LDAP_P((
|
||||
|
|
@ -244,6 +307,14 @@ LDAP_F( struct berval * )
|
|||
ldap_contentrule2bv LDAP_P((
|
||||
LDAPContentRule * cr, struct berval *bv ));
|
||||
|
||||
LDAP_F( char * )
|
||||
ldap_objectclass2str LDAP_P((
|
||||
LDAPObjectClass * oc ));
|
||||
|
||||
LDAP_F( struct berval * )
|
||||
ldap_objectclass2bv LDAP_P((
|
||||
LDAPObjectClass * oc, struct berval *bv ));
|
||||
|
||||
LDAP_F( char * )
|
||||
ldap_attributetype2str LDAP_P((
|
||||
LDAPAttributeType * at ));
|
||||
|
|
|
|||
|
|
@ -23,7 +23,7 @@
|
|||
static const char *
|
||||
choose_name( char *names[], const char *fallback )
|
||||
{
|
||||
return( (names != NULL && names[0] != NULL) ? names[0] : fallback );
|
||||
return (names != NULL && names[0] != NULL) ? names[0] : fallback;
|
||||
}
|
||||
|
||||
LDAP_CONST char *
|
||||
|
|
@ -62,12 +62,24 @@ ldap_contentrule2name( LDAPContentRule * cr )
|
|||
return( choose_name( cr->cr_names, cr->cr_oid ) );
|
||||
}
|
||||
|
||||
LDAP_CONST char *
|
||||
ldap_nameform2name( LDAPNameForm * nf )
|
||||
{
|
||||
return( choose_name( nf->nf_names, nf->nf_oid ) );
|
||||
}
|
||||
|
||||
LDAP_CONST char *
|
||||
ldap_structurerule2name( LDAPStructureRule * sr )
|
||||
{
|
||||
return( choose_name( sr->sr_names, NULL ) );
|
||||
}
|
||||
|
||||
/*
|
||||
* When pretty printing the entities we will be appending to a buffer.
|
||||
* Since checking for overflow, realloc'ing and checking if no error
|
||||
* is extremely boring, we will use a protection layer that will let
|
||||
* us blissfully ignore the error until the end. This layer is
|
||||
* implemented with the help of the next type.
|
||||
* is extremely boring, we error until the end. This layer is
|
||||
* implemented with the he will use a protection layer that will let
|
||||
* us blissfully ignore thlp of the next type.
|
||||
*/
|
||||
|
||||
typedef struct safe_string {
|
||||
|
|
@ -292,6 +304,34 @@ print_noidlen(safe_string *ss, char *s, int l)
|
|||
return(ret);
|
||||
}
|
||||
|
||||
static int
|
||||
print_ruleid(safe_string *ss, int rid)
|
||||
{
|
||||
char buf[64];
|
||||
snprintf(buf, sizeof buf, "%d", rid);
|
||||
return print_literal(ss,buf);
|
||||
}
|
||||
|
||||
static int
|
||||
print_ruleids(safe_string *ss, int n, int *rids)
|
||||
{
|
||||
int i;
|
||||
|
||||
if( n == 1 ) {
|
||||
print_ruleid(ss,rids[0]);
|
||||
return print_whsp(ss);
|
||||
} else {
|
||||
print_literal(ss,"("/*)*/);
|
||||
for( i=0; i<n; i++ ) {
|
||||
print_whsp(ss);
|
||||
print_ruleid(ss,rids[i]);
|
||||
}
|
||||
print_whsp(ss);
|
||||
return print_literal(ss,/*(*/")");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
print_extensions(safe_string *ss, LDAPSchemaExtensionItem **extensions)
|
||||
{
|
||||
|
|
@ -639,6 +679,139 @@ ldap_contentrule2bv( LDAPContentRule * cr, struct berval *bv )
|
|||
return(bv);
|
||||
}
|
||||
|
||||
char *
|
||||
ldap_structurerule2str( LDAPStructureRule * sr )
|
||||
{
|
||||
struct berval bv;
|
||||
if (ldap_structurerule2bv( sr, &bv ))
|
||||
return(bv.bv_val);
|
||||
else
|
||||
return NULL;
|
||||
}
|
||||
|
||||
struct berval *
|
||||
ldap_structurerule2bv( LDAPStructureRule * sr, struct berval *bv )
|
||||
{
|
||||
safe_string * ss;
|
||||
|
||||
ss = new_safe_string(256);
|
||||
if ( !ss )
|
||||
return NULL;
|
||||
|
||||
print_literal(ss,"("/*)*/);
|
||||
print_whsp(ss);
|
||||
|
||||
print_ruleid(ss, sr->sr_ruleid);
|
||||
print_whsp(ss);
|
||||
|
||||
if ( sr->sr_names ) {
|
||||
print_literal(ss,"NAME");
|
||||
print_qdescrs(ss,sr->sr_names);
|
||||
}
|
||||
|
||||
if ( sr->sr_desc ) {
|
||||
print_literal(ss,"DESC");
|
||||
print_qdstring(ss,sr->sr_desc);
|
||||
}
|
||||
|
||||
if ( sr->sr_obsolete ) {
|
||||
print_literal(ss, "OBSOLETE");
|
||||
print_whsp(ss);
|
||||
}
|
||||
|
||||
print_literal(ss,"FORM");
|
||||
print_whsp(ss);
|
||||
print_woid(ss,sr->sr_nameform);
|
||||
print_whsp(ss);
|
||||
|
||||
if ( sr->sr_nsup_ruleids ) {
|
||||
print_literal(ss,"SUP");
|
||||
print_whsp(ss);
|
||||
print_ruleids(ss,sr->sr_nsup_ruleids,sr->sr_sup_ruleids);
|
||||
print_whsp(ss);
|
||||
}
|
||||
|
||||
print_whsp(ss);
|
||||
print_extensions(ss, sr->sr_extensions);
|
||||
|
||||
print_literal(ss, /*(*/")");
|
||||
|
||||
bv->bv_val = safe_strdup(ss);
|
||||
bv->bv_len = ss->pos;
|
||||
safe_string_free(ss);
|
||||
return(bv);
|
||||
}
|
||||
|
||||
|
||||
char *
|
||||
ldap_nameform2str( LDAPNameForm * nf )
|
||||
{
|
||||
struct berval bv;
|
||||
if (ldap_nameform2bv( nf, &bv ))
|
||||
return(bv.bv_val);
|
||||
else
|
||||
return NULL;
|
||||
}
|
||||
|
||||
struct berval *
|
||||
ldap_nameform2bv( LDAPNameForm * nf, struct berval *bv )
|
||||
{
|
||||
safe_string * ss;
|
||||
|
||||
ss = new_safe_string(256);
|
||||
if ( !ss )
|
||||
return NULL;
|
||||
|
||||
print_literal(ss,"("/*)*/);
|
||||
print_whsp(ss);
|
||||
|
||||
print_numericoid(ss, nf->nf_oid);
|
||||
print_whsp(ss);
|
||||
|
||||
if ( nf->nf_names ) {
|
||||
print_literal(ss,"NAME");
|
||||
print_qdescrs(ss,nf->nf_names);
|
||||
}
|
||||
|
||||
if ( nf->nf_desc ) {
|
||||
print_literal(ss,"DESC");
|
||||
print_qdstring(ss,nf->nf_desc);
|
||||
}
|
||||
|
||||
if ( nf->nf_obsolete ) {
|
||||
print_literal(ss, "OBSOLETE");
|
||||
print_whsp(ss);
|
||||
}
|
||||
|
||||
print_literal(ss,"OC");
|
||||
print_whsp(ss);
|
||||
print_woid(ss,nf->nf_objectclass);
|
||||
print_whsp(ss);
|
||||
|
||||
print_literal(ss,"MUST");
|
||||
print_whsp(ss);
|
||||
print_oids(ss,nf->nf_at_oids_must);
|
||||
print_whsp(ss);
|
||||
|
||||
|
||||
if ( nf->nf_at_oids_may ) {
|
||||
print_literal(ss,"MAY");
|
||||
print_whsp(ss);
|
||||
print_oids(ss,nf->nf_at_oids_may);
|
||||
print_whsp(ss);
|
||||
}
|
||||
|
||||
print_whsp(ss);
|
||||
print_extensions(ss, nf->nf_extensions);
|
||||
|
||||
print_literal(ss, /*(*/")");
|
||||
|
||||
bv->bv_val = safe_strdup(ss);
|
||||
bv->bv_len = ss->pos;
|
||||
safe_string_free(ss);
|
||||
return(bv);
|
||||
}
|
||||
|
||||
char *
|
||||
ldap_attributetype2str( LDAPAttributeType * at )
|
||||
{
|
||||
|
|
@ -937,6 +1110,28 @@ ldap_int_parse_numericoid(const char **sp, int *code, const int flags)
|
|||
return(res);
|
||||
}
|
||||
|
||||
/* Parse a sequence of dot-separated decimal strings */
|
||||
int
|
||||
ldap_int_parse_ruleid(const char **sp, int *code, const int flags, int *ruleid)
|
||||
{
|
||||
*ruleid=0;
|
||||
|
||||
if ( !LDAP_DIGIT(**sp) ) {
|
||||
*code = LDAP_SCHERR_NODIGIT;
|
||||
return -1;
|
||||
}
|
||||
*ruleid = (**sp) - '0';
|
||||
(*sp)++;
|
||||
|
||||
while ( LDAP_DIGIT(**sp) ) {
|
||||
*ruleid *= 10;
|
||||
*ruleid += (**sp) - '0';
|
||||
(*sp)++;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Parse a qdescr or a list of them enclosed in () */
|
||||
static char **
|
||||
parse_qdescrs(const char **sp, int *code)
|
||||
|
|
@ -1234,7 +1429,7 @@ LDAPSyntax *
|
|||
ldap_str2syntax( LDAP_CONST char * s,
|
||||
int * code,
|
||||
LDAP_CONST char ** errp,
|
||||
LDAP_CONST int flags )
|
||||
LDAP_CONST unsigned flags )
|
||||
{
|
||||
int kind;
|
||||
const char * ss = s;
|
||||
|
|
@ -1376,7 +1571,7 @@ LDAPMatchingRule *
|
|||
ldap_str2matchingrule( LDAP_CONST char * s,
|
||||
int * code,
|
||||
LDAP_CONST char ** errp,
|
||||
LDAP_CONST int flags )
|
||||
LDAP_CONST unsigned flags )
|
||||
{
|
||||
int kind;
|
||||
const char * ss = s;
|
||||
|
|
@ -1453,6 +1648,11 @@ ldap_str2matchingrule( LDAP_CONST char * s,
|
|||
ldap_matchingrule_free(mr);
|
||||
return NULL;
|
||||
case TK_RIGHTPAREN:
|
||||
if( !seen_syntax ) {
|
||||
*code = LDAP_SCHERR_MISSING;
|
||||
ldap_matchingrule_free(mr);
|
||||
return NULL;
|
||||
}
|
||||
return mr;
|
||||
case TK_BAREWORD:
|
||||
if ( !strcmp(sval,"NAME") ) {
|
||||
|
|
@ -1570,7 +1770,7 @@ LDAPMatchingRuleUse *
|
|||
ldap_str2matchingruleuse( LDAP_CONST char * s,
|
||||
int * code,
|
||||
LDAP_CONST char ** errp,
|
||||
LDAP_CONST int flags )
|
||||
LDAP_CONST unsigned flags )
|
||||
{
|
||||
int kind;
|
||||
const char * ss = s;
|
||||
|
|
@ -1647,6 +1847,11 @@ ldap_str2matchingruleuse( LDAP_CONST char * s,
|
|||
ldap_matchingruleuse_free(mru);
|
||||
return NULL;
|
||||
case TK_RIGHTPAREN:
|
||||
if( !seen_applies ) {
|
||||
*code = LDAP_SCHERR_MISSING;
|
||||
ldap_matchingruleuse_free(mru);
|
||||
return NULL;
|
||||
}
|
||||
return mru;
|
||||
case TK_BAREWORD:
|
||||
if ( !strcmp(sval,"NAME") ) {
|
||||
|
|
@ -1767,7 +1972,7 @@ LDAPAttributeType *
|
|||
ldap_str2attributetype( LDAP_CONST char * s,
|
||||
int * code,
|
||||
LDAP_CONST char ** errp,
|
||||
LDAP_CONST int flags )
|
||||
LDAP_CONST unsigned flags )
|
||||
{
|
||||
int kind;
|
||||
const char * ss = s;
|
||||
|
|
@ -2145,7 +2350,7 @@ LDAPObjectClass *
|
|||
ldap_str2objectclass( LDAP_CONST char * s,
|
||||
int * code,
|
||||
LDAP_CONST char ** errp,
|
||||
LDAP_CONST int flags )
|
||||
LDAP_CONST unsigned flags )
|
||||
{
|
||||
int kind;
|
||||
const char * ss = s;
|
||||
|
|
@ -2427,7 +2632,7 @@ LDAPContentRule *
|
|||
ldap_str2contentrule( LDAP_CONST char * s,
|
||||
int * code,
|
||||
LDAP_CONST char ** errp,
|
||||
LDAP_CONST int flags )
|
||||
LDAP_CONST unsigned flags )
|
||||
{
|
||||
int kind;
|
||||
const char * ss = s;
|
||||
|
|
@ -2467,45 +2672,14 @@ ldap_str2contentrule( LDAP_CONST char * s,
|
|||
|
||||
/*
|
||||
* 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;
|
||||
cr->cr_oid = ldap_int_parse_numericoid(&ss,code,0);
|
||||
if ( !cr->cr_oid ) {
|
||||
if ( (flags & LDAP_SCHEMA_ALLOW_ALL) && (ss == savepos) ) {
|
||||
/* Backtracking */
|
||||
ss = savepos;
|
||||
kind = get_token(&ss,&sval);
|
||||
if ( kind == TK_BAREWORD ) {
|
||||
if ( !strcmp(sval, "NAME") ||
|
||||
!strcmp(sval, "DESC") ||
|
||||
!strcmp(sval, "OBSOLETE") ||
|
||||
!strcmp(sval, "AUX") ||
|
||||
!strcmp(sval, "MUST") ||
|
||||
!strcmp(sval, "MAY") ||
|
||||
!strcmp(sval, "NOT") ||
|
||||
!strncmp(sval, "X-", 2) ) {
|
||||
/* Missing OID, backtrack */
|
||||
ss = savepos;
|
||||
} else if ( flags &
|
||||
LDAP_SCHEMA_ALLOW_OID_MACRO ) {
|
||||
/* Non-numerical OID, ignore */
|
||||
int len = ss-savepos;
|
||||
cr->cr_oid = LDAP_MALLOC(len+1);
|
||||
strncpy(cr->cr_oid, savepos, len);
|
||||
cr->cr_oid[len] = 0;
|
||||
}
|
||||
}
|
||||
LDAP_FREE(sval);
|
||||
} else {
|
||||
*errp = ss;
|
||||
ldap_contentrule_free(cr);
|
||||
return NULL;
|
||||
}
|
||||
*errp = ss;
|
||||
ldap_contentrule_free(cr);
|
||||
return NULL;
|
||||
}
|
||||
parse_whsp(&ss);
|
||||
|
||||
|
|
@ -2670,6 +2844,393 @@ ldap_str2contentrule( LDAP_CONST char * s,
|
|||
}
|
||||
}
|
||||
|
||||
void
|
||||
ldap_structurerule_free(LDAPStructureRule * sr)
|
||||
{
|
||||
if (sr->sr_names) LDAP_VFREE(sr->sr_names);
|
||||
if (sr->sr_desc) LDAP_FREE(sr->sr_desc);
|
||||
if (sr->sr_nameform) LDAP_FREE(sr->sr_nameform);
|
||||
if (sr->sr_sup_ruleids) LDAP_FREE(sr->sr_sup_ruleids);
|
||||
free_extensions(sr->sr_extensions);
|
||||
LDAP_FREE(sr);
|
||||
}
|
||||
|
||||
LDAPStructureRule *
|
||||
ldap_str2structurerule( LDAP_CONST char * s,
|
||||
int * code,
|
||||
LDAP_CONST char ** errp,
|
||||
LDAP_CONST unsigned flags )
|
||||
{
|
||||
int kind, ret;
|
||||
const char * ss = s;
|
||||
char * sval;
|
||||
int seen_name = 0;
|
||||
int seen_desc = 0;
|
||||
int seen_obsolete = 0;
|
||||
int seen_nameform = 0;
|
||||
int seen_ruleids = 0;
|
||||
LDAPStructureRule * sr;
|
||||
char ** ext_vals;
|
||||
const char * savepos;
|
||||
|
||||
if ( !s ) {
|
||||
*code = LDAP_SCHERR_EMPTY;
|
||||
*errp = "";
|
||||
return NULL;
|
||||
}
|
||||
|
||||
*errp = s;
|
||||
sr = LDAP_CALLOC(1,sizeof(LDAPStructureRule));
|
||||
|
||||
if ( !sr ) {
|
||||
*code = LDAP_SCHERR_OUTOFMEM;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
kind = get_token(&ss,&sval);
|
||||
if ( kind != TK_LEFTPAREN ) {
|
||||
*code = LDAP_SCHERR_NOLEFTPAREN;
|
||||
LDAP_FREE(sval);
|
||||
ldap_structurerule_free(sr);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
* Definitions MUST begin with a ruleid.
|
||||
*/
|
||||
parse_whsp(&ss);
|
||||
savepos = ss;
|
||||
ret = ldap_int_parse_ruleid(&ss,code,0,&sr->sr_ruleid);
|
||||
if ( ret ) {
|
||||
*errp = ss;
|
||||
ldap_structurerule_free(sr);
|
||||
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_structurerule_free(sr);
|
||||
return NULL;
|
||||
case TK_RIGHTPAREN:
|
||||
if( !seen_nameform ) {
|
||||
*code = LDAP_SCHERR_MISSING;
|
||||
ldap_structurerule_free(sr);
|
||||
return NULL;
|
||||
}
|
||||
return sr;
|
||||
case TK_BAREWORD:
|
||||
if ( !strcmp(sval,"NAME") ) {
|
||||
LDAP_FREE(sval);
|
||||
if ( seen_name ) {
|
||||
*code = LDAP_SCHERR_DUPOPT;
|
||||
*errp = ss;
|
||||
ldap_structurerule_free(sr);
|
||||
return(NULL);
|
||||
}
|
||||
seen_name = 1;
|
||||
sr->sr_names = parse_qdescrs(&ss,code);
|
||||
if ( !sr->sr_names ) {
|
||||
if ( *code != LDAP_SCHERR_OUTOFMEM )
|
||||
*code = LDAP_SCHERR_BADNAME;
|
||||
*errp = ss;
|
||||
ldap_structurerule_free(sr);
|
||||
return NULL;
|
||||
}
|
||||
} else if ( !strcmp(sval,"DESC") ) {
|
||||
LDAP_FREE(sval);
|
||||
if ( seen_desc ) {
|
||||
*code = LDAP_SCHERR_DUPOPT;
|
||||
*errp = ss;
|
||||
ldap_structurerule_free(sr);
|
||||
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_structurerule_free(sr);
|
||||
return NULL;
|
||||
}
|
||||
sr->sr_desc = sval;
|
||||
parse_whsp(&ss);
|
||||
} else if ( !strcmp(sval,"OBSOLETE") ) {
|
||||
LDAP_FREE(sval);
|
||||
if ( seen_obsolete ) {
|
||||
*code = LDAP_SCHERR_DUPOPT;
|
||||
*errp = ss;
|
||||
ldap_structurerule_free(sr);
|
||||
return(NULL);
|
||||
}
|
||||
seen_obsolete = 1;
|
||||
sr->sr_obsolete = LDAP_SCHEMA_YES;
|
||||
parse_whsp(&ss);
|
||||
} else if ( !strcmp(sval,"FORM") ) {
|
||||
LDAP_FREE(sval);
|
||||
if ( seen_nameform ) {
|
||||
*code = LDAP_SCHERR_DUPOPT;
|
||||
*errp = ss;
|
||||
ldap_structurerule_free(sr);
|
||||
return(NULL);
|
||||
}
|
||||
seen_nameform = 1;
|
||||
sr->sr_nameform = parse_woid(&ss,code);
|
||||
if ( !sr->sr_nameform ) {
|
||||
*errp = ss;
|
||||
ldap_structurerule_free(sr);
|
||||
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_structurerule_free(sr);
|
||||
return NULL;
|
||||
}
|
||||
if ( add_extension(&sr->sr_extensions,
|
||||
sval, ext_vals) ) {
|
||||
*code = LDAP_SCHERR_OUTOFMEM;
|
||||
*errp = ss;
|
||||
LDAP_FREE(sval);
|
||||
ldap_structurerule_free(sr);
|
||||
return NULL;
|
||||
}
|
||||
} else {
|
||||
*code = LDAP_SCHERR_UNEXPTOKEN;
|
||||
*errp = ss;
|
||||
LDAP_FREE(sval);
|
||||
ldap_structurerule_free(sr);
|
||||
return NULL;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
*code = LDAP_SCHERR_UNEXPTOKEN;
|
||||
*errp = ss;
|
||||
LDAP_FREE(sval);
|
||||
ldap_structurerule_free(sr);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
ldap_nameform_free(LDAPNameForm * nf)
|
||||
{
|
||||
LDAP_FREE(nf->nf_oid);
|
||||
if (nf->nf_names) LDAP_VFREE(nf->nf_names);
|
||||
if (nf->nf_desc) LDAP_FREE(nf->nf_desc);
|
||||
if (nf->nf_objectclass) LDAP_FREE(nf->nf_objectclass);
|
||||
if (nf->nf_at_oids_must) LDAP_VFREE(nf->nf_at_oids_must);
|
||||
if (nf->nf_at_oids_may) LDAP_VFREE(nf->nf_at_oids_may);
|
||||
free_extensions(nf->nf_extensions);
|
||||
LDAP_FREE(nf);
|
||||
}
|
||||
|
||||
LDAPNameForm *
|
||||
ldap_str2nameform( LDAP_CONST char * s,
|
||||
int * code,
|
||||
LDAP_CONST char ** errp,
|
||||
LDAP_CONST unsigned flags )
|
||||
{
|
||||
int kind;
|
||||
const char * ss = s;
|
||||
char * sval;
|
||||
int seen_name = 0;
|
||||
int seen_desc = 0;
|
||||
int seen_obsolete = 0;
|
||||
int seen_class = 0;
|
||||
int seen_must = 0;
|
||||
int seen_may = 0;
|
||||
LDAPNameForm * nf;
|
||||
char ** ext_vals;
|
||||
const char * savepos;
|
||||
|
||||
if ( !s ) {
|
||||
*code = LDAP_SCHERR_EMPTY;
|
||||
*errp = "";
|
||||
return NULL;
|
||||
}
|
||||
|
||||
*errp = s;
|
||||
nf = LDAP_CALLOC(1,sizeof(LDAPNameForm));
|
||||
|
||||
if ( !nf ) {
|
||||
*code = LDAP_SCHERR_OUTOFMEM;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
kind = get_token(&ss,&sval);
|
||||
if ( kind != TK_LEFTPAREN ) {
|
||||
*code = LDAP_SCHERR_NOLEFTPAREN;
|
||||
LDAP_FREE(sval);
|
||||
ldap_nameform_free(nf);
|
||||
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;
|
||||
nf->nf_oid = ldap_int_parse_numericoid(&ss,code,0);
|
||||
if ( !nf->nf_oid ) {
|
||||
*errp = ss;
|
||||
ldap_nameform_free(nf);
|
||||
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_nameform_free(nf);
|
||||
return NULL;
|
||||
case TK_RIGHTPAREN:
|
||||
if( !seen_class || !seen_must ) {
|
||||
*code = LDAP_SCHERR_MISSING;
|
||||
ldap_nameform_free(nf);
|
||||
return NULL;
|
||||
}
|
||||
return nf;
|
||||
case TK_BAREWORD:
|
||||
if ( !strcmp(sval,"NAME") ) {
|
||||
LDAP_FREE(sval);
|
||||
if ( seen_name ) {
|
||||
*code = LDAP_SCHERR_DUPOPT;
|
||||
*errp = ss;
|
||||
ldap_nameform_free(nf);
|
||||
return(NULL);
|
||||
}
|
||||
seen_name = 1;
|
||||
nf->nf_names = parse_qdescrs(&ss,code);
|
||||
if ( !nf->nf_names ) {
|
||||
if ( *code != LDAP_SCHERR_OUTOFMEM )
|
||||
*code = LDAP_SCHERR_BADNAME;
|
||||
*errp = ss;
|
||||
ldap_nameform_free(nf);
|
||||
return NULL;
|
||||
}
|
||||
} else if ( !strcmp(sval,"DESC") ) {
|
||||
LDAP_FREE(sval);
|
||||
if ( seen_desc ) {
|
||||
*code = LDAP_SCHERR_DUPOPT;
|
||||
*errp = ss;
|
||||
ldap_nameform_free(nf);
|
||||
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_nameform_free(nf);
|
||||
return NULL;
|
||||
}
|
||||
nf->nf_desc = sval;
|
||||
parse_whsp(&ss);
|
||||
} else if ( !strcmp(sval,"OBSOLETE") ) {
|
||||
LDAP_FREE(sval);
|
||||
if ( seen_obsolete ) {
|
||||
*code = LDAP_SCHERR_DUPOPT;
|
||||
*errp = ss;
|
||||
ldap_nameform_free(nf);
|
||||
return(NULL);
|
||||
}
|
||||
seen_obsolete = 1;
|
||||
nf->nf_obsolete = LDAP_SCHEMA_YES;
|
||||
parse_whsp(&ss);
|
||||
} else if ( !strcmp(sval,"MUST") ) {
|
||||
LDAP_FREE(sval);
|
||||
if ( seen_must ) {
|
||||
*code = LDAP_SCHERR_DUPOPT;
|
||||
*errp = ss;
|
||||
ldap_nameform_free(nf);
|
||||
return(NULL);
|
||||
}
|
||||
seen_must = 1;
|
||||
nf->nf_at_oids_must = parse_oids(&ss,code,0);
|
||||
if ( !nf->nf_at_oids_must ) {
|
||||
*errp = ss;
|
||||
ldap_nameform_free(nf);
|
||||
return NULL;
|
||||
}
|
||||
parse_whsp(&ss);
|
||||
} else if ( !strcmp(sval,"MAY") ) {
|
||||
LDAP_FREE(sval);
|
||||
if ( seen_may ) {
|
||||
*code = LDAP_SCHERR_DUPOPT;
|
||||
*errp = ss;
|
||||
ldap_nameform_free(nf);
|
||||
return(NULL);
|
||||
}
|
||||
seen_may = 1;
|
||||
nf->nf_at_oids_may = parse_oids(&ss,code,0);
|
||||
if ( !nf->nf_at_oids_may ) {
|
||||
*errp = ss;
|
||||
ldap_nameform_free(nf);
|
||||
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_nameform_free(nf);
|
||||
return NULL;
|
||||
}
|
||||
if ( add_extension(&nf->nf_extensions,
|
||||
sval, ext_vals) ) {
|
||||
*code = LDAP_SCHERR_OUTOFMEM;
|
||||
*errp = ss;
|
||||
LDAP_FREE(sval);
|
||||
ldap_nameform_free(nf);
|
||||
return NULL;
|
||||
}
|
||||
} else {
|
||||
*code = LDAP_SCHERR_UNEXPTOKEN;
|
||||
*errp = ss;
|
||||
LDAP_FREE(sval);
|
||||
ldap_nameform_free(nf);
|
||||
return NULL;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
*code = LDAP_SCHERR_UNEXPTOKEN;
|
||||
*errp = ss;
|
||||
LDAP_FREE(sval);
|
||||
ldap_nameform_free(nf);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static char *const err2text[] = {
|
||||
"Success",
|
||||
"Out of memory",
|
||||
|
|
@ -2681,7 +3242,9 @@ static char *const err2text[] = {
|
|||
"Bad description",
|
||||
"Bad superiors",
|
||||
"Duplicate option",
|
||||
"Unexpected end of data"
|
||||
"Unexpected end of data",
|
||||
"Missing required field",
|
||||
"Out of order field"
|
||||
};
|
||||
|
||||
char *
|
||||
|
|
|
|||
Loading…
Reference in a new issue