Skip to content
GitLab
Explore
Sign in
Register
Primary navigation
Search or go to…
Project
O
OpenLDAP
Manage
Activity
Members
Labels
Plan
Wiki
Code
Merge requests
Repository
Branches
Commits
Tags
Repository graph
Compare revisions
Snippets
Locked files
Build
Pipelines
Jobs
Pipeline schedules
Artifacts
Deploy
Releases
Package registry
Container Registry
Model registry
Operate
Environments
Terraform modules
Analyze
Value stream analytics
Contributor analytics
CI/CD analytics
Repository analytics
Code review analytics
Insights
Model experiments
Help
Help
Support
GitLab documentation
Compare GitLab plans
Community forum
Contribute to GitLab
Provide feedback
Keyboard shortcuts
?
Snippets
Groups
Projects
Show more breadcrumbs
Christopher Ng
OpenLDAP
Commits
b2b3581b
Commit
b2b3581b
authored
25 years ago
by
Julio Sánchez Fernández
Browse files
Options
Downloads
Patches
Plain Diff
Initial incomplete and broken version.
parent
59865a5d
No related branches found
Branches containing commit
No related tags found
Tags containing commit
No related merge requests found
Changes
2
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
include/ldap_schema.h
+71
-0
71 additions, 0 deletions
include/ldap_schema.h
libraries/libldap/schema.c
+914
-0
914 additions, 0 deletions
libraries/libldap/schema.c
with
985 additions
and
0 deletions
include/ldap_schema.h
0 → 100644
+
71
−
0
View file @
b2b3581b
/*
* Copyright 1999 The OpenLDAP Foundation, Redwood City, California, USA
* All rights reserved.
*
* Redistribution and use in source and binary forms 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.
*/
/*
* ldap-schema.h - Header for basic schema handling functions that can be
* used by both clients and servers.
*/
#ifndef _LDAP_SCHEMA_H
#define _LDAP_SCHEMA_H 1
#include
<ldap_cdefs.h>
LDAP_BEGIN_DECL
/* Codes for parsing errors */
#define SCHEMA_ERR_OUTOFMEM 1
#define SCHEMA_ERR_UNEXPTOKEN 2
#define SCHEMA_ERR_NOLEFTPAREN 3
#define SCHEMA_ERR_NORIGHTPAREN 4
#define SCHEMA_ERR_NODIGIT 5
#define SCHEMA_ERR_BADNAME 6
#define SCHEMA_ERR_BADDESC 7
#define SCHEMA_ERR_BADSUP 8
#define SCHEMA_ERR_DUPOPT 9
typedef
struct
ldap_attributetype
{
char
*
at_oid
;
/* REQUIRED */
char
**
at_names
;
/* OPTIONAL */
char
*
at_desc
;
/* OPTIONAL */
int
at_obsolete
;
/* 0=no, 1=yes */
char
*
at_sup_oid
;
/* OPTIONAL */
char
*
at_equality_oid
;
/* OPTIONAL */
char
*
at_ordering_oid
;
/* OPTIONAL */
char
*
at_substr_oid
;
/* OPTIONAL */
char
*
at_syntax_oid
;
/* OPTIONAL */
int
at_syntax_len
;
/* OPTIONAL */
int
at_single_value
;
/* 0=no, 1=yes */
int
at_collective
;
/* 0=no, 1=yes */
int
at_no_user_mod
;
/* 0=no, 1=yes */
int
at_usage
;
/* 0=userApplications, 1=directoryOperation,
2=distributedOperation, 3=dSAOperation */
}
LDAP_ATTRIBUTE_TYPE
;
typedef
struct
ldap_objectclass
{
char
*
oc_oid
;
/* REQUIRED */
char
**
oc_names
;
/* OPTIONAL */
char
*
oc_desc
;
/* OPTIONAL */
int
oc_obsolete
;
/* 0=no, 1=yes */
char
**
oc_sup_oids
;
/* OPTIONAL */
int
oc_kind
;
/* 0=ABSTRACT, 1=STRUCTURAL, 2=AUXILIARY */
char
**
oc_at_oids_must
;
/* OPTIONAL */
char
**
oc_at_oids_may
;
/* MAY */
}
LDAP_OBJECT_CLASS
;
LDAP_F
(
LDAP_OBJECT_CLASS
*
)
ldap_str2objectclass
LDAP_P
((
char
*
s
,
int
*
code
,
char
**
errp
));
LDAP_F
(
LDAP_ATTRIBUTE_TYPE
)
ldap_str2attributetype
LDAP_P
((
char
*
sval
,
char
**
errp
));
LDAP_F
(
char
*
)
ldap_objectclass2str
LDAP_P
((
LDAP_OBJECT_CLASS
*
oc
));
LDAP_F
(
char
*
)
ldap_attributetype2str
LDAP_P
((
LDAP_ATTRIBUTE_TYPE
*
at
));
LDAP_END_DECL
#endif
This diff is collapsed.
Click to expand it.
libraries/libldap/schema.c
0 → 100644
+
914
−
0
View file @
b2b3581b
/*
* Copyright 1999 The OpenLDAP Foundation, All Rights Reserved.
* COPYING RESTRICTIONS APPLY, see COPYRIGHT file
*
* schema.c: parsing routines used by servers and clients to process
* schema definitions
*/
#include
"portable.h"
#include
<ac/ctype.h>
#include
<ac/string.h>
#ifdef HAVE_MALLOC_H
#include
<malloc.h>
#endif
#include
<lber.h>
#include
<ldap.h>
#include
<ldap_schema.h>
#include
<stdio.h>
/*
* 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 pretection layer that will let
* us blissfully ignore the error until the end. This layer is
* implemented with the help of the next type.
*/
typedef
struct
safe_string
{
char
*
val
;
int
size
;
int
pos
;
int
at_whsp
;
}
safe_string
;
static
safe_string
*
new_safe_string
(
int
size
)
{
safe_string
*
ss
;
ss
=
malloc
(
sizeof
(
safe_string
));
if
(
!
ss
)
return
(
NULL
);
ss
->
size
=
size
;
ss
->
pos
=
0
;
ss
->
val
=
malloc
(
size
);
ss
->
at_whsp
=
0
;
if
(
!
ss
->
val
)
{
free
(
ss
);
return
(
NULL
);
}
return
ss
;
}
void
safe_string_free
(
safe_string
*
ss
)
{
if
(
!
ss
)
return
;
ldap_memfree
(
ss
->
val
);
ldap_memfree
(
ss
);
}
static
char
*
safe_string_val
(
safe_string
*
ss
)
{
return
(
ss
->
val
);
}
static
int
append_to_safe_string
(
safe_string
*
ss
,
char
*
s
)
{
int
l
=
strlen
(
s
);
char
*
temp
;
/*
* Some runaway process is trying to append to a string that
* overflowed and we could not extend.
*/
if
(
!
ss
->
val
)
return
-
1
;
/* We always make sure there is at least one position available */
if
(
ss
->
pos
+
l
>=
ss
->
size
-
1
)
{
ss
->
size
*=
2
;
temp
=
realloc
(
ss
->
val
,
ss
->
size
);
if
(
!
temp
)
{
/* Trouble, out of memory */
free
(
ss
->
val
);
return
-
1
;
}
ss
->
val
=
temp
;
}
strncpy
(
&
ss
->
val
[
ss
->
pos
],
s
,
l
);
ss
->
pos
+=
l
;
if
(
ss
->
pos
>
0
&&
ss
->
val
[
ss
->
pos
-
1
]
==
' '
)
ss
->
at_whsp
=
1
;
else
ss
->
at_whsp
=
0
;
return
0
;
}
static
int
print_literal
(
safe_string
*
ss
,
char
*
s
)
{
return
(
append_to_safe_string
(
ss
,
s
));
}
static
int
print_whsp
(
safe_string
*
ss
)
{
if
(
ss
->
at_whsp
)
return
(
append_to_safe_string
(
ss
,
""
));
else
return
(
append_to_safe_string
(
ss
,
" "
));
}
static
int
print_numericoid
(
safe_string
*
ss
,
char
*
s
)
{
return
(
append_to_safe_string
(
ss
,
s
));
}
/* This one is identical to print_qdescr */
static
int
print_qdstring
(
safe_string
*
ss
,
char
*
s
)
{
print_whsp
(
ss
);
print_literal
(
ss
,
"'"
);
append_to_safe_string
(
ss
,
s
);
print_literal
(
ss
,
"'"
);
return
(
print_whsp
(
ss
));
}
static
int
print_qdescr
(
safe_string
*
ss
,
char
*
s
)
{
print_whsp
(
ss
);
print_literal
(
ss
,
"'"
);
append_to_safe_string
(
ss
,
s
);
print_literal
(
ss
,
"'"
);
return
(
print_whsp
(
ss
));
}
static
int
print_qdescrlist
(
safe_string
*
ss
,
char
**
sa
)
{
char
**
sp
;
int
ret
=
0
;
for
(
sp
=
sa
;
*
sp
;
sp
++
)
{
ret
=
print_qdescr
(
ss
,
*
sp
);
}
/* If the list was empty, we return zero that is potentially
* incorrect, but since we will still appending things, the
* overflow will be detected later. Maybe FIX.
*/
return
(
ret
);
}
static
int
print_qdescrs
(
safe_string
*
ss
,
char
**
sa
)
{
/* The only way to represent an empty list is as a qdescrlist
* so, if the list is empty we treat it as a long list.
* Really, this is what the syntax mandates.
*/
if
(
!
sa
[
0
]
||
(
sa
[
0
]
&&
sa
[
1
]
)
)
{
print_whsp
(
ss
);
print_literal
(
ss
,
"("
);
print_qdescrlist
(
ss
,
sa
);
print_literal
(
ss
,
")"
);
return
(
print_whsp
(
ss
));
}
else
{
return
(
print_qdescr
(
ss
,
*
sa
));
}
}
static
int
print_woid
(
safe_string
*
ss
,
char
*
s
)
{
print_whsp
(
ss
);
append_to_safe_string
(
ss
,
s
);
return
print_whsp
(
ss
);
}
static
int
print_oidlist
(
safe_string
*
ss
,
char
**
sa
)
{
char
**
sp
;
for
(
sp
=
sa
;
*
(
sp
+
1
);
sp
++
)
{
print_woid
(
ss
,
*
sp
);
print_literal
(
ss
,
"$"
);
}
return
(
print_woid
(
ss
,
*
sp
));
}
static
int
print_oids
(
safe_string
*
ss
,
char
**
sa
)
{
if
(
sa
[
0
]
&&
sa
[
1
]
)
{
print_literal
(
ss
,
"("
);
print_oidlist
(
ss
,
sa
);
print_whsp
(
ss
);
return
(
print_literal
(
ss
,
")"
));
}
else
{
return
(
print_woid
(
ss
,
*
sa
));
}
}
static
int
print_noidlen
(
safe_string
*
ss
,
char
*
s
,
int
l
)
{
char
buf
[
64
];
int
ret
;
ret
=
print_numericoid
(
ss
,
s
);
if
(
l
)
{
sprintf
(
buf
,
"{%d}"
,
l
);
ret
=
print_literal
(
ss
,
buf
);
}
return
(
ret
);
}
char
*
ldap_objectclass2str
(
LDAP_OBJECT_CLASS
*
oc
)
{
safe_string
*
ss
;
char
*
retstring
;
ss
=
new_safe_string
(
256
);
if
(
!
ss
)
return
NULL
;
print_literal
(
ss
,
"("
);
print_whsp
(
ss
);
print_numericoid
(
ss
,
oc
->
oc_oid
);
print_whsp
(
ss
);
if
(
oc
->
oc_names
)
{
print_literal
(
ss
,
"NAME"
);
print_qdescrs
(
ss
,
oc
->
oc_names
);
}
if
(
oc
->
oc_desc
)
{
print_literal
(
ss
,
"DESC"
);
print_qdstring
(
ss
,
oc
->
oc_desc
);
}
if
(
oc
->
oc_obsolete
)
{
print_literal
(
ss
,
"OBSOLETE"
);
print_whsp
(
ss
);
}
if
(
oc
->
oc_sup_oids
)
{
print_literal
(
ss
,
"SUP"
);
print_oids
(
ss
,
oc
->
oc_sup_oids
);
}
switch
(
oc
->
oc_kind
)
{
case
0
:
print_literal
(
ss
,
"ABSTRACT"
);
break
;
case
1
:
print_literal
(
ss
,
"STRUCTURAL"
);
break
;
case
2
:
print_literal
(
ss
,
"AUXILIARY"
);
break
;
default:
print_literal
(
ss
,
"KIND-UNKNOWN"
);
break
;
}
print_whsp
(
ss
);
if
(
oc
->
oc_at_oids_must
)
{
print_literal
(
ss
,
"MUST"
);
print_whsp
(
ss
);
print_oids
(
ss
,
oc
->
oc_at_oids_must
);
print_whsp
(
ss
);
}
if
(
oc
->
oc_at_oids_may
)
{
print_literal
(
ss
,
"MAY"
);
print_whsp
(
ss
);
print_oids
(
ss
,
oc
->
oc_at_oids_may
);
print_whsp
(
ss
);
}
print_whsp
(
ss
);
print_literal
(
ss
,
")"
);
retstring
=
safe_string_val
(
ss
);
safe_string_free
(
ss
);
return
(
retstring
);
}
char
*
ldap_attributetype2str
(
LDAP_ATTRIBUTE_TYPE
*
at
)
{
safe_string
*
ss
;
char
*
retstring
;
ss
=
new_safe_string
(
256
);
if
(
!
ss
)
return
NULL
;
print_literal
(
ss
,
"("
);
print_whsp
(
ss
);
print_numericoid
(
ss
,
at
->
at_oid
);
print_whsp
(
ss
);
if
(
at
->
at_names
)
{
print_literal
(
ss
,
"NAME"
);
print_qdescrs
(
ss
,
at
->
at_names
);
}
if
(
at
->
at_desc
)
{
print_literal
(
ss
,
"DESC"
);
print_qdstring
(
ss
,
at
->
at_desc
);
}
if
(
at
->
at_obsolete
)
{
print_literal
(
ss
,
"OBSOLETE"
);
print_whsp
(
ss
);
}
if
(
at
->
at_sup_oid
)
{
print_literal
(
ss
,
"SUP"
);
print_woid
(
ss
,
at
->
at_sup_oid
);
}
if
(
at
->
at_equality_oid
)
{
print_literal
(
ss
,
"EQUALITY"
);
print_woid
(
ss
,
at
->
at_equality_oid
);
}
if
(
at
->
at_ordering_oid
)
{
print_literal
(
ss
,
"ORDERING"
);
print_woid
(
ss
,
at
->
at_ordering_oid
);
}
if
(
at
->
at_substr_oid
)
{
print_literal
(
ss
,
"SUBSTR"
);
print_woid
(
ss
,
at
->
at_substr_oid
);
}
if
(
at
->
at_syntax_oid
)
{
print_literal
(
ss
,
"SYNTAX"
);
print_noidlen
(
ss
,
at
->
at_syntax_oid
,
at
->
at_syntax_len
);
}
if
(
at
->
at_single_value
)
{
print_literal
(
ss
,
"SINGLE-VALUE"
);
print_whsp
(
ss
);
}
if
(
at
->
at_collective
)
{
print_literal
(
ss
,
"COLLECTIVE"
);
print_whsp
(
ss
);
}
if
(
at
->
at_no_user_mod
)
{
print_literal
(
ss
,
"NO-USER-MODIFICATION"
);
print_whsp
(
ss
);
}
if
(
at
->
at_usage
)
{
print_literal
(
ss
,
"USAGE"
);
print_whsp
(
ss
);
switch
(
at
->
at_usage
)
{
case
1
:
print_literal
(
ss
,
"directoryOperation"
);
break
;
case
2
:
print_literal
(
ss
,
"distributedOperation"
);
break
;
case
3
:
print_literal
(
ss
,
"dSAOperation"
);
break
;
default:
print_literal
(
ss
,
"UNKNOWN"
);
break
;
}
}
print_whsp
(
ss
);
print_literal
(
ss
,
")"
);
retstring
=
safe_string_val
(
ss
);
safe_string_free
(
ss
);
return
(
retstring
);
}
/*
* This is ripped from servers/slapd/charray.c that should be promoted
* to -lldap or something so that it is used everywhere.
*/
static
void
charray_free
(
char
**
array
)
{
char
**
a
;
if
(
array
==
NULL
)
{
return
;
}
for
(
a
=
array
;
*
a
!=
NULL
;
a
++
)
{
if
(
*
a
!=
NULL
)
{
free
(
*
a
);
}
}
free
(
(
char
*
)
array
);
}
#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
{
int
type
;
char
*
sval
;
};
static
int
get_token
(
char
**
sp
,
char
**
token_val
)
{
int
kind
;
char
*
p
;
char
*
q
;
char
*
res
;
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
=
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
(
!
isspace
(
**
sp
)
&&
**
sp
!=
'\0'
)
(
*
sp
)
++
;
q
=
*
sp
;
res
=
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
(
char
**
sp
)
{
while
(
isspace
(
**
sp
))
(
*
sp
)
++
;
}
/* TBC:!!
* General note for all parsers: to guarantee the algorithm halts they
* must always advance the pointer even when an error is found. For
* this one is not that important since an error here is fatal at the
* upper layers, but it is a simple strategy that will not get in
* endless loops.
*/
/* Parse a sequence of dot-separated decimal strings */
static
char
*
parse_numericoid
(
char
**
sp
,
int
*
code
)
{
char
*
res
;
char
*
start
=
*
sp
;
int
len
;
/* Each iteration of this loops gets one decimal string */
while
(
**
sp
)
{
if
(
!
isdigit
(
**
sp
)
)
{
/* Initial char is not a digit or char after dot is not a digit */
*
code
=
SCHEMA_ERR_NODIGIT
;
return
NULL
;
}
(
*
sp
)
++
;
while
(
isdigit
(
**
sp
)
)
(
*
sp
)
++
;
if
(
**
sp
!=
'.'
)
break
;
/* Otherwise, gobble the dot and loop again */
(
*
sp
)
++
;
}
/* At this point, *sp points at the char past the numericoid. Perfect. */
len
=
*
sp
-
start
;
res
=
malloc
(
len
+
1
);
if
(
!
res
)
{
*
code
=
SCHEMA_ERR_OUTOFMEM
;
return
(
NULL
);
}
strncpy
(
res
,
start
,
len
);
res
[
len
]
=
'\0'
;
return
(
res
);
}
/* Parse a qdescr or a list of them enclosed in () */
static
char
**
parse_qdescrs
(
char
**
sp
,
int
*
code
)
{
char
**
res
;
char
**
res1
;
int
kind
;
char
*
sval
;
int
size
;
int
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
=
calloc
(
3
,
sizeof
(
char
*
));
if
(
!
res
)
{
*
code
=
SCHEMA_ERR_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
=
realloc
(
res
,
size
*
sizeof
(
char
*
));
if
(
!
res1
)
{
charray_free
(
res
);
*
code
=
SCHEMA_ERR_OUTOFMEM
;
return
(
NULL
);
}
res
=
res1
;
}
res
[
pos
]
=
sval
;
pos
++
;
parse_whsp
(
sp
);
}
else
{
charray_free
(
res
);
*
code
=
SCHEMA_ERR_UNEXPTOKEN
;
return
(
NULL
);
}
}
res
[
pos
]
=
NULL
;
parse_whsp
(
sp
);
return
(
res
);
}
else
if
(
kind
==
TK_QDESCR
)
{
res
=
calloc
(
2
,
sizeof
(
char
*
));
if
(
!
res
)
{
*
code
=
SCHEMA_ERR_OUTOFMEM
;
return
NULL
;
}
res
[
0
]
=
sval
;
res
[
1
]
=
NULL
;
parse_whsp
(
sp
);
return
res
;
}
else
{
*
code
=
SCHEMA_ERR_BADNAME
;
return
NULL
;
}
}
/* Parse a woid or a $-separated list of them enclosed in () */
static
char
**
parse_oids
(
char
**
sp
,
int
*
code
)
{
char
**
res
;
char
**
res1
;
int
kind
;
char
*
sval
;
int
size
;
int
pos
;
/*
* Strictly speaking, doing this here accepts whsp before the
* ( at the begining of an oidlist, but his 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
=
calloc
(
3
,
sizeof
(
char
*
));
if
(
!
res
)
{
*
code
=
SCHEMA_ERR_OUTOFMEM
;
return
NULL
;
}
pos
=
0
;
parse_whsp
(
sp
);
kind
=
get_token
(
sp
,
&
sval
);
if
(
kind
==
TK_BAREWORD
)
{
res
[
pos
]
=
sval
;
pos
++
;
}
else
{
*
code
=
SCHEMA_ERR_UNEXPTOKEN
;
charray_free
(
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
)
{
if
(
pos
==
size
-
2
)
{
size
++
;
res1
=
realloc
(
res
,
size
*
sizeof
(
char
*
));
if
(
!
res1
)
{
charray_free
(
res
);
*
code
=
SCHEMA_ERR_OUTOFMEM
;
return
(
NULL
);
}
res
=
res1
;
}
res
[
pos
]
=
sval
;
pos
++
;
}
else
{
*
code
=
SCHEMA_ERR_UNEXPTOKEN
;
charray_free
(
res
);
return
NULL
;
}
parse_whsp
(
sp
);
}
else
{
*
code
=
SCHEMA_ERR_UNEXPTOKEN
;
charray_free
(
res
);
return
NULL
;
}
}
res
[
pos
]
=
NULL
;
parse_whsp
(
sp
);
return
(
res
);
}
else
if
(
kind
==
TK_BAREWORD
)
{
res
=
calloc
(
2
,
sizeof
(
char
*
));
if
(
!
res
)
{
*
code
=
SCHEMA_ERR_OUTOFMEM
;
return
NULL
;
}
res
[
0
]
=
sval
;
res
[
1
]
=
NULL
;
parse_whsp
(
sp
);
return
res
;
}
else
{
*
code
=
SCHEMA_ERR_BADNAME
;
return
NULL
;
}
}
static
void
free_oc
(
LDAP_OBJECT_CLASS
*
oc
)
{
ldap_memfree
(
oc
->
oc_oid
);
charray_free
(
oc
->
oc_names
);
ldap_memfree
(
oc
->
oc_desc
);
charray_free
(
oc
->
oc_sup_oids
);
charray_free
(
oc
->
oc_at_oids_must
);
charray_free
(
oc
->
oc_at_oids_may
);
ldap_memfree
(
oc
);
}
LDAP_OBJECT_CLASS
*
ldap_str2objectclass
(
char
*
s
,
int
*
code
,
char
**
errp
)
{
int
kind
;
char
*
ss
=
s
;
char
*
sval
;
int
seen_name
=
0
;
int
seen_desc
=
0
;
int
seen_obsolete
=
0
;
int
seen_sup
=
0
;
int
seen_kind
=
0
;
int
seen_must
=
0
;
int
seen_may
=
0
;
LDAP_OBJECT_CLASS
*
oc
;
*
errp
=
s
;
oc
=
calloc
(
1
,
sizeof
(
LDAP_OBJECT_CLASS
));
if
(
!
oc
)
{
*
code
=
SCHEMA_ERR_OUTOFMEM
;
return
NULL
;
}
kind
=
get_token
(
&
ss
,
&
sval
);
if
(
kind
!=
TK_LEFTPAREN
)
{
*
code
=
SCHEMA_ERR_NOLEFTPAREN
;
free_oc
(
oc
);
return
NULL
;
}
parse_whsp
(
&
ss
);
oc
->
oc_oid
=
parse_numericoid
(
&
ss
,
code
);
if
(
!
oc
->
oc_oid
)
{
*
errp
=
ss
;
free_oc
(
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
=
SCHEMA_ERR_NORIGHTPAREN
;
*
errp
=
ss
;
free_oc
(
oc
);
return
NULL
;
case
TK_RIGHTPAREN
:
return
oc
;
case
TK_BAREWORD
:
if
(
!
strcmp
(
sval
,
"NAME"
)
)
{
if
(
seen_name
)
{
*
code
=
SCHEMA_ERR_DUPOPT
;
*
errp
=
ss
;
free_oc
(
oc
);
return
(
NULL
);
}
seen_name
=
1
;
oc
->
oc_names
=
parse_qdescrs
(
&
ss
,
code
);
if
(
!
oc
->
oc_names
)
{
if
(
*
code
!=
SCHEMA_ERR_OUTOFMEM
)
*
code
=
SCHEMA_ERR_BADNAME
;
*
errp
=
ss
;
free_oc
(
oc
);
return
NULL
;
}
}
else
if
(
!
strcmp
(
sval
,
"DESC"
)
)
{
if
(
seen_desc
)
{
*
code
=
SCHEMA_ERR_DUPOPT
;
*
errp
=
ss
;
free_oc
(
oc
);
return
(
NULL
);
}
seen_desc
=
1
;
parse_whsp
(
&
ss
);
kind
=
get_token
(
&
ss
,
&
sval
);
if
(
kind
!=
TK_QDSTRING
)
{
*
code
=
SCHEMA_ERR_UNEXPTOKEN
;
*
errp
=
ss
;
free
(
oc
);
return
NULL
;
}
oc
->
oc_desc
=
sval
;
parse_whsp
(
&
ss
);
}
else
if
(
!
strcmp
(
sval
,
"OBSOLETE"
)
)
{
if
(
seen_obsolete
)
{
*
code
=
SCHEMA_ERR_DUPOPT
;
*
errp
=
ss
;
free_oc
(
oc
);
return
(
NULL
);
}
seen_obsolete
=
1
;
oc
->
oc_obsolete
=
1
;
parse_whsp
(
&
ss
);
}
else
if
(
!
strcmp
(
sval
,
"SUP"
)
)
{
if
(
seen_sup
)
{
*
code
=
SCHEMA_ERR_DUPOPT
;
*
errp
=
ss
;
free_oc
(
oc
);
return
(
NULL
);
}
seen_sup
=
1
;
/* Netscape DS is broken or I have not
understood the syntax. */
/* oc->oc_sup_oids = parse_oids(&ss,code); */
oc
->
oc_sup_oids
=
parse_qdescrs
(
&
ss
,
code
);
if
(
!
oc
->
oc_sup_oids
)
{
*
errp
=
ss
;
free_oc
(
oc
);
return
NULL
;
}
}
else
if
(
!
strcmp
(
sval
,
"ABSTRACT"
)
)
{
if
(
seen_kind
)
{
*
code
=
SCHEMA_ERR_DUPOPT
;
*
errp
=
ss
;
free_oc
(
oc
);
return
(
NULL
);
}
seen_kind
=
1
;
oc
->
oc_kind
=
0
;
parse_whsp
(
&
ss
);
}
else
if
(
!
strcmp
(
sval
,
"STRUCTURAL"
)
)
{
if
(
seen_kind
)
{
*
code
=
SCHEMA_ERR_DUPOPT
;
*
errp
=
ss
;
free_oc
(
oc
);
return
(
NULL
);
}
seen_kind
=
1
;
oc
->
oc_kind
=
1
;
parse_whsp
(
&
ss
);
}
else
if
(
!
strcmp
(
sval
,
"AUXILIARY"
)
)
{
if
(
seen_kind
)
{
*
code
=
SCHEMA_ERR_DUPOPT
;
*
errp
=
ss
;
free_oc
(
oc
);
return
(
NULL
);
}
seen_kind
=
1
;
oc
->
oc_kind
=
2
;
parse_whsp
(
&
ss
);
}
else
if
(
!
strcmp
(
sval
,
"MUST"
)
)
{
if
(
seen_must
)
{
*
code
=
SCHEMA_ERR_DUPOPT
;
*
errp
=
ss
;
free_oc
(
oc
);
return
(
NULL
);
}
seen_must
=
1
;
oc
->
oc_at_oids_must
=
parse_oids
(
&
ss
,
code
);
if
(
!
oc
->
oc_at_oids_must
)
{
*
errp
=
ss
;
free_oc
(
oc
);
return
NULL
;
}
parse_whsp
(
&
ss
);
}
else
if
(
!
strcmp
(
sval
,
"MAY"
)
)
{
if
(
seen_may
)
{
*
code
=
SCHEMA_ERR_DUPOPT
;
*
errp
=
ss
;
free_oc
(
oc
);
return
(
NULL
);
}
seen_may
=
1
;
oc
->
oc_at_oids_may
=
parse_oids
(
&
ss
,
code
);
if
(
!
oc
->
oc_at_oids_may
)
{
*
errp
=
ss
;
free_oc
(
oc
);
return
NULL
;
}
parse_whsp
(
&
ss
);
}
else
{
*
code
=
SCHEMA_ERR_UNEXPTOKEN
;
*
errp
=
ss
;
free_oc
(
oc
);
return
NULL
;
}
break
;
default:
*
code
=
SCHEMA_ERR_UNEXPTOKEN
;
*
errp
=
ss
;
free_oc
(
oc
);
return
NULL
;
}
}
}
This diff is collapsed.
Click to expand it.
Preview
0%
Loading
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Save comment
Cancel
Please
register
or
sign in
to comment