Skip to content
GitLab
Menu
Projects
Groups
Snippets
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Sign in / Register
Toggle navigation
Menu
Open sidebar
Nadezhda Ivanova
OpenLDAP
Commits
ea39c4d9
Commit
ea39c4d9
authored
Oct 17, 2002
by
Kurt Zeilenga
Browse files
Add additional schema routines
parent
0e90cd9d
Changes
1
Hide whitespace changes
Inline
Side-by-side
libraries/libldap/schema.c
View file @
ea39c4d9
...
...
@@ -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 he
lp 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 th
lp 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