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
222962d2
Commit
222962d2
authored
25 years ago
by
Randy Kunkee
Browse files
Options
Downloads
Patches
Plain Diff
Update documentation. Add support for caching, sorting, enabling "all"
in searches, and experimental "trap" subcommand.
parent
4c7739e6
Branches
Branches containing commit
Tags
Tags containing commit
No related merge requests found
Changes
2
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
contrib/ldaptcl/ldap.n
+31
-27
31 additions, 27 deletions
contrib/ldaptcl/ldap.n
contrib/ldaptcl/neoXldap.c
+133
-18
133 additions, 18 deletions
contrib/ldaptcl/neoXldap.c
with
164 additions
and
45 deletions
contrib/ldaptcl/ldap.n
+
31
−
27
View file @
222962d2
...
...
@@ -26,7 +26,7 @@ A new command by the name of \fIcommand\fR will be created to access
the LDAP database at \fIhostlist\fR. \fIhostlist\fR may contain elements
of the format \fBhost:port\fR if a port other than the default LDAP port
of 389 is required. The LDAP library will attempt to connect to each
host in turn until it succeeds.
host in turn until it succeeds
or exhausts the list
.
.PP
The \fBexplode\fR form provides a means (via ldap_explode(3)) to explode a DN
into its component parts. \fB-nonames\fR strips off the attribute names,
...
...
@@ -64,9 +64,6 @@ deferred until we actually try to do something.
For the purposes of this example, we're going to assume that "foo" is the
command created by opening a connection using "ldap open".
Note: Karl is particularly dissatisfied with the syntax of this option,
so it is one of the most likely things to change in a subsequent release.
.SH BINDING
After a connection is made to an LDAP server, an LDAP bind operation must
...
...
@@ -74,11 +71,10 @@ be performed before other operations can be attempted over the connection.
Both simple authentication and kerberos authentication are available.
LDAP version 3 supports many new "SSL"-style authentication and encryption
systems, which are not currently supported by the
UMich
server, and
hence
by this interface package.
systems, which are not currently supported by the
OpenLDAP v1.2
server, and
hence
by this interface package.
Currently simple authentication, and kerberos-based authentication, are
supported.
Currently simple and kerberos-based authentication, are supported.
To use LDAP and still have reasonable security in a networked,
Internet/Intranet environment, secure shell can be used to setup
...
...
@@ -140,17 +136,19 @@ This creates a new distinguished name and defines zero or more attributes.
"attributePairList" is a list of key-value pairs, the same as would
be returned by "array get" if an array had been set up containing the
key-value pairs. Note that, right now, the sort of lowest-level pair
of the DN must also appear in the attributePairList, as in:
key-value pairs.
foo add "cn=karl, ou=People, o=NeoSoft Inc, c=US" {cn karl ...}
Some directory servers and/or their client SDKs will automatically
add the leaf attribute value for you.
Here is a more precise description of how an attributePairList looks:
{cn {karl {Karl Lehenbauer}} telephone 713-968-5800}
Note here that two cn values, "karl" and "Karl Lehenbauer", are added.
A comm
an
d
error
is
to write
Is it
an error to write
:
{cn {Karl Lehenbauer}}
...
...
@@ -161,11 +159,11 @@ typing hard-coded lists.
We have noticed that the Netscape server will automatically add the
left-most rdn portion of the DN (ie. cn=karl), whereas the University
of Michigan version do
es
not.
of Michigan
and OpenLDAP 1.2
version
s
do not.
.SH ADDING, DELETING, AND REPLACING OBJECT ATTRIBUTES
You can have multiple
occurrences of the same
attribute in a
record
.
You can have multiple
values for a given
attribute in a
n LDAP object
.
These are represented in search results, through the Tcl interface,
as a list.
...
...
@@ -173,21 +171,23 @@ as a list.
This adds key-value pairs to an existing DN. If an attribute being
added already exists, the new value will be appended to the list.
If a particular value being added to an attribute already exists in
the object a Tcl error is raised.
foo replace_attributes dn attributePairList
This replaces specified key-value pairs in an existing DN, leaving
unnamed ones untouched.
This replaces the specified attributes in an existing DN, leaving
unnamed ones untouched. Any previous values for the supplied attributes
(if any) are discarded.
foo delete_attributes dn attributePairList
This deletes attributes in the list. If a pair is "foo {bar snap}" and
you delete "foo bar", "foo" will still have "snap".
This deletes attributes in the list. If an attribute "foo" has the
value list {bar snap}, and you delete using the attributePairList "foo bar",
"foo" will still have "snap".
If you provide an empty string ("") for the value part of the key-value
pair, the entire attribute will be deleted. To reiterate, if you provide
a non-empty string for the value part, only that value will be removed
from the value list.
If you provide an empty string ("") for the value list,
the entire attribute will be deleted.
.SH SEARCHING
...
...
@@ -233,8 +233,8 @@ version.
.SH CACHING (Note: Netscape clients do not have caching interfaces).
The UMich
LDAP
librar
y
offers the client application fairly
fine-
grained control of caching of results retrieved from searches,
The UMich
and OpenLDAP client
librar
ies
offers the client application fairly
fine-
grained control of caching of results retrieved from searches,
offering significant performance improvement and reduced
network traffic.
...
...
@@ -272,7 +272,10 @@ To enable caching of data received from an LDAP connection,
This should be used, for example, after doing an add_attributes,
delete_attributes, or replace_attributes (ldap_modify(3))
involving the requested DN.
involving the requested DN. Generally this should not be needed,
as the Tcl interface automatically performs this operation on
any dn that is modified (add,replace,delete) while caching is
enabled.
foo cache no_errors
...
...
@@ -295,7 +298,8 @@ Because we used the new "Tcl object" C interfaces, this package only works
with Tcl 8.0 or above.
This package interfaces with the University of Michigan LDAP protocol
package, version 3.3, an implementation of version 2 of the LDAP protocol.
package, version 3.3, and OpenLDAP version 1.2, both of which are
implementations of version 2 of the LDAP protocol.
Although an LDAP client (or server) could be written in native Tcl 8.0,
as Tcl 8.0 and above can do binary I/O, and Tcl 8 and above have strings
...
...
@@ -334,8 +338,8 @@ related to LDAP services.
.SH AUTHORS
It was written by Karl Lehenbauer, of NeoSoft, Inc., in August and
September of 1997. Ldap explode, and numerous bug fixes
by Randy
Kunkee, also of NeoSoft, Inc., in 1998.
September of 1997. Ldap explode, and numerous bug fixes
and extensions
by Randy
Kunkee, also of NeoSoft, Inc., in 1998
-1999
.
.SH KEYWORDS
element, join, list, separator
...
...
This diff is collapsed.
Click to expand it.
contrib/ldaptcl/neoXldap.c
+
133
−
18
View file @
222962d2
...
...
@@ -107,6 +107,8 @@ typedef struct ldaptclobj {
int
caching
;
/* flag 1/0 if caching is enabled */
long
timeout
;
/* timeout from last cache enable */
long
maxmem
;
/* maxmem from last cache enable */
Tcl_Obj
*
trapCmdObj
;
/* error handler */
int
*
traplist
;
/* list of errorCodes to trap */
int
flags
;
}
LDAPTCL
;
...
...
@@ -118,7 +120,7 @@ typedef struct ldaptclobj {
static
LDAP_SetErrorCode
(
LDAPTCL
*
ldaptcl
,
int
code
,
Tcl_Interp
*
interp
)
{
char
shortbuf
[
6
];
char
shortbuf
[
1
6
];
char
*
errp
;
int
lderrno
;
...
...
@@ -132,6 +134,33 @@ LDAP_SetErrorCode(LDAPTCL *ldaptcl, int code, Tcl_Interp *interp)
errp
=
ldaptclerrorcode
[
code
];
Tcl_SetErrorCode
(
interp
,
errp
,
NULL
);
if
(
ldaptcl
->
trapCmdObj
)
{
int
*
i
;
Tcl_Obj
*
cmdObj
;
if
(
ldaptcl
->
traplist
!=
NULL
)
{
for
(
i
=
ldaptcl
->
traplist
;
*
i
&&
*
i
!=
code
;
i
++
)
;
if
(
*
i
==
0
)
return
;
}
(
void
)
Tcl_EvalObj
(
interp
,
ldaptcl
->
trapCmdObj
);
}
}
static
LDAP_ErrorStringToCode
(
Tcl_Interp
*
interp
,
char
*
s
)
{
int
offset
;
int
code
;
offset
=
(
strncasecmp
(
s
,
"LDAP_"
,
5
)
==
0
)
?
0
:
5
;
for
(
code
=
0
;
code
<
LDAPTCL_MAXERR
;
code
++
)
{
if
(
!
ldaptclerrorcode
[
code
])
continue
;
if
(
strcasecmp
(
s
,
ldaptclerrorcode
[
code
]
+
offset
)
==
0
)
return
code
;
}
Tcl_ResetResult
(
interp
);
Tcl_AppendResult
(
interp
,
s
,
" is an invalid code"
,
(
char
*
)
NULL
);
return
-
1
;
}
/*-----------------------------------------------------------------------------
...
...
@@ -179,6 +208,8 @@ LDAP_ProcessOneSearchResult (interp, ldap, entry, destArrayNameObj, evalCodeObj)
return
TCL_ERROR
;
ldap_memfree
(
dn
);
}
attributeNameObj
=
Tcl_NewObj
();
Tcl_IncrRefCount
(
attributeNameObj
);
for
(
attributeName
=
ldap_first_attribute
(
ldap
,
entry
,
&
ber
);
attributeName
!=
NULL
;
attributeName
=
ldap_next_attribute
(
ldap
,
entry
,
ber
))
{
...
...
@@ -192,13 +223,12 @@ LDAP_ProcessOneSearchResult (interp, ldap, entry, destArrayNameObj, evalCodeObj)
as an error, we ignore it to present a consistent interface
with Netscape's server
*/
attributeNameObj
=
Tcl_NewStringObj
(
attributeName
,
-
1
);
Tcl_IncrRefCount
(
attributeNameObj
);
attributeDataObj
=
Tcl_NewObj
();
Tcl_SetStringObj
(
attributeNameObj
,
attributeName
,
-
1
);
for
(
i
=
0
;
bvals
[
i
]
!=
NULL
;
i
++
)
{
Tcl_Obj
*
singleAttributeValueObj
;
singleAttributeValueObj
=
Tcl_NewStringObj
(
bvals
[
i
]
->
bv_val
,
-
1
);
singleAttributeValueObj
=
Tcl_NewStringObj
(
bvals
[
i
]
->
bv_val
,
bvals
[
i
]
->
bv_len
);
if
(
Tcl_ListObjAppendElement
(
interp
,
attributeDataObj
,
singleAttributeValueObj
)
...
...
@@ -217,9 +247,9 @@ LDAP_ProcessOneSearchResult (interp, ldap, entry, destArrayNameObj, evalCodeObj)
TCL_LEAVE_ERR_MSG
)
==
NULL
)
{
return
TCL_ERROR
;
}
Tcl_DecrRefCount
(
attributeNameObj
);
}
}
Tcl_DecrRefCount
(
attributeNameObj
);
return
Tcl_EvalObj
(
interp
,
evalCodeObj
);
}
...
...
@@ -268,8 +298,8 @@ LDAP_PerformSearch (interp, ldaptcl, base, scope, attrs, filtpatt, value,
int
abandon
;
int
tclResult
=
TCL_OK
;
int
msgid
;
LDAPMessage
*
resultMessage
;
LDAPMessage
*
entryMessage
;
LDAPMessage
*
resultMessage
=
0
;
LDAPMessage
*
entryMessage
=
0
;
char
*
sortKey
;
Tcl_Obj
*
resultObj
;
...
...
@@ -334,10 +364,13 @@ LDAP_PerformSearch (interp, ldaptcl, base, scope, attrs, filtpatt, value,
}
if
(
resultCode
==
LDAP_RES_SEARCH_RESULT
||
all
)
break
;
if
(
resultMessage
)
ldap_msgfree
(
resultMessage
);
resultMessage
=
NULL
;
}
if
(
abandon
)
{
ldap_msgfree
(
resultMessage
);
if
(
resultMessage
)
ldap_msgfree
(
resultMessage
);
if
(
resultCode
==
LDAP_RES_SEARCH_ENTRY
)
ldap_abandon
(
ldap
,
msgid
);
return
tclResult
;
...
...
@@ -367,10 +400,13 @@ LDAP_PerformSearch (interp, ldaptcl, base, scope, attrs, filtpatt, value,
"LDAP search error: "
,
ldap_err2string
(
errorCode
),
(
char
*
)
NULL
);
ldap_msgfree
(
resultMessage
);
if
(
resultMessage
)
ldap_msgfree
(
resultMessage
);
LDAP_SetErrorCode
(
ldaptcl
,
errorCode
,
interp
);
return
TCL_ERROR
;
}
if
(
resultMessage
)
ldap_msgfree
(
resultMessage
);
return
tclResult
;
}
...
...
@@ -607,11 +643,11 @@ NeoX_LdapTargetObjCmd (clientData, interp, objc, objv)
nPairs
=
attribObjc
/
2
;
modArray
=
(
LDAPMod
**
)
ck
alloc
(
sizeof
(
LDAPMod
*
)
*
(
nPairs
+
1
));
modArray
=
(
LDAPMod
**
)
m
alloc
(
sizeof
(
LDAPMod
*
)
*
(
nPairs
+
1
));
modArray
[
nPairs
]
=
(
LDAPMod
*
)
NULL
;
for
(
i
=
0
;
i
<
nPairs
;
i
++
)
{
mod
=
modArray
[
i
]
=
(
LDAPMod
*
)
ck
alloc
(
sizeof
(
LDAPMod
));
mod
=
modArray
[
i
]
=
(
LDAPMod
*
)
m
alloc
(
sizeof
(
LDAPMod
));
mod
->
mod_op
=
mod_op
;
mod
->
mod_type
=
Tcl_GetStringFromObj
(
attribObjv
[
i
*
2
],
NULL
);
...
...
@@ -621,7 +657,7 @@ NeoX_LdapTargetObjCmd (clientData, interp, objc, objv)
}
valPtrs
=
mod
->
mod_vals
.
modv_strvals
=
\
(
char
**
)
ck
alloc
(
sizeof
(
char
*
)
*
(
valuesObjc
+
1
));
(
char
**
)
m
alloc
(
sizeof
(
char
*
)
*
(
valuesObjc
+
1
));
valPtrs
[
valuesObjc
]
=
(
char
*
)
NULL
;
for
(
j
=
0
;
j
<
valuesObjc
;
j
++
)
{
...
...
@@ -631,7 +667,7 @@ NeoX_LdapTargetObjCmd (clientData, interp, objc, objv)
* value be NULL to indicate entire attribute is to be
* deleted */
if
((
*
valPtrs
[
j
]
==
'\0'
)
&&
(
mod
->
mod_op
==
LDAP_MOD_DELETE
))
{
&&
(
mod
->
mod_op
==
LDAP_MOD_DELETE
||
mod
->
mod_op
==
LDAP_MOD_REPLACE
))
{
valPtrs
[
j
]
=
NULL
;
}
}
...
...
@@ -647,10 +683,10 @@ NeoX_LdapTargetObjCmd (clientData, interp, objc, objv)
/* free the modArray elements, then the modArray itself. */
for
(
i
=
0
;
i
<
nPairs
;
i
++
)
{
ck
free
((
char
*
)
modArray
[
i
]
->
mod_vals
.
modv_strvals
);
ck
free
((
char
*
)
modArray
[
i
]);
free
((
char
*
)
modArray
[
i
]
->
mod_vals
.
modv_strvals
);
free
((
char
*
)
modArray
[
i
]);
}
ck
free
((
char
*
)
modArray
);
free
((
char
*
)
modArray
);
/* FIX: memory cleanup required all over the place here */
if
(
result
!=
LDAP_SUCCESS
)
{
...
...
@@ -848,6 +884,7 @@ NeoX_LdapTargetObjCmd (clientData, interp, objc, objv)
/* Caching control within the search: if the "cache" control array */
/* value is set, disable/enable caching accordingly */
#if 0
if (cacheThis >= 0 && ldaptcl->caching != cacheThis) {
if (cacheThis) {
if (ldaptcl->timeout == 0) {
...
...
@@ -859,6 +896,7 @@ NeoX_LdapTargetObjCmd (clientData, interp, objc, objv)
else
ldap_disable_cache(ldap);
}
#endif
tclResult
=
LDAP_PerformSearch
(
interp
,
ldaptcl
,
baseString
,
...
...
@@ -873,12 +911,14 @@ NeoX_LdapTargetObjCmd (clientData, interp, objc, objv)
sortattr
);
/* Following the search, if we changed the caching behavior, change */
/* it back. */
#if 0
if (cacheThis >= 0 && ldaptcl->caching != cacheThis) {
if (cacheThis)
ldap_disable_cache(ldap);
else
ldap_enable_cache(ldap, ldaptcl->timeout, ldaptcl->maxmem);
}
#endif
return
tclResult
;
}
...
...
@@ -993,6 +1033,75 @@ NeoX_LdapTargetObjCmd (clientData, interp, objc, objv)
return
TCL_ERROR
;
}
#endif
if
(
STREQU
(
subCommand
,
"trap"
))
{
Tcl_Obj
*
listObj
,
*
resultObj
;
int
*
p
,
l
,
i
,
code
;
if
(
objc
>
4
)
return
TclX_WrongArgs
(
interp
,
objv
[
0
],
"trap command ?errorCode-list?"
);
if
(
objc
==
2
)
{
if
(
!
ldaptcl
->
trapCmdObj
)
return
TCL_OK
;
resultObj
=
Tcl_NewListObj
(
0
,
NULL
);
Tcl_ListObjAppendElement
(
interp
,
resultObj
,
ldaptcl
->
trapCmdObj
);
if
(
ldaptcl
->
traplist
)
{
listObj
=
Tcl_NewObj
();
for
(
p
=
ldaptcl
->
traplist
;
*
p
;
p
++
)
{
Tcl_ListObjAppendElement
(
interp
,
listObj
,
Tcl_NewStringObj
(
ldaptclerrorcode
[
*
p
],
-
1
));
}
Tcl_ListObjAppendElement
(
interp
,
resultObj
,
listObj
);
}
Tcl_SetObjResult
(
interp
,
resultObj
);
return
TCL_OK
;
}
if
(
ldaptcl
->
trapCmdObj
)
{
Tcl_DecrRefCount
(
ldaptcl
->
trapCmdObj
);
ldaptcl
->
trapCmdObj
=
NULL
;
}
if
(
ldaptcl
->
traplist
)
{
free
(
ldaptcl
->
traplist
);
ldaptcl
->
traplist
=
NULL
;
}
Tcl_GetStringFromObj
(
objv
[
2
],
&
l
);
if
(
l
==
0
)
return
TCL_OK
;
/* just turn off trap */
ldaptcl
->
trapCmdObj
=
objv
[
2
];
Tcl_IncrRefCount
(
ldaptcl
->
trapCmdObj
);
if
(
objc
<
4
)
return
TCL_OK
;
/* no code list */
if
(
Tcl_ListObjLength
(
interp
,
objv
[
3
],
&
l
)
!=
TCL_OK
)
return
TCL_ERROR
;
if
(
l
==
0
)
return
TCL_OK
;
/* empty code list */
ldaptcl
->
traplist
=
malloc
(
sizeof
(
int
)
*
(
l
+
1
));
ldaptcl
->
traplist
[
l
]
=
0
;
for
(
i
=
0
;
i
<
l
;
i
++
)
{
Tcl_ListObjIndex
(
interp
,
objv
[
3
],
i
,
&
resultObj
);
code
=
LDAP_ErrorStringToCode
(
interp
,
Tcl_GetStringFromObj
(
resultObj
));
if
(
code
==
-
1
)
{
free
(
ldaptcl
->
traplist
);
ldaptcl
->
traplist
=
NULL
;
return
TCL_ERROR
;
}
ldaptcl
->
traplist
[
i
]
=
code
;
}
return
TCL_OK
;
}
if
(
STREQU
(
subCommand
,
"trapcodes"
))
{
int
code
;
Tcl_Obj
*
resultObj
;
Tcl_Obj
*
stringObj
;
resultObj
=
Tcl_GetObjResult
(
interp
);
for
(
code
=
0
;
code
<
LDAPTCL_MAXERR
;
code
++
)
{
if
(
!
ldaptclerrorcode
[
code
])
continue
;
Tcl_ListObjAppendElement
(
interp
,
resultObj
,
Tcl_NewStringObj
(
ldaptclerrorcode
[
code
],
-
1
));
}
return
TCL_OK
;
}
#ifdef LDAP_DEBUG
if
(
STREQU
(
subCommand
,
"debug"
))
{
if
(
objc
!=
3
)
{
...
...
@@ -1030,8 +1139,12 @@ NeoX_LdapObjDeleteCmd(clientData)
LDAPTCL
*
ldaptcl
=
(
LDAPTCL
*
)
clientData
;
LDAP
*
ldap
=
ldaptcl
->
ldap
;
if
(
ldaptcl
->
trapCmdObj
)
Tcl_DecrRefCount
(
ldaptcl
->
trapCmdObj
);
if
(
ldaptcl
->
traplist
)
free
(
ldaptcl
->
traplist
);
ldap_unbind
(
ldap
);
ck
free
((
char
*
)
ldaptcl
);
free
((
char
*
)
ldaptcl
);
}
/*-----------------------------------------------------------------------------
...
...
@@ -1163,11 +1276,13 @@ NeoX_LdapObjCmd (clientData, interp, objc, objv)
ldap
->
ld_deref
=
LDAP_DEREF_NEVER
;
/* Turn off alias dereferencing */
#endif
ldaptcl
=
(
LDAPTCL
*
)
ck
alloc
(
sizeof
(
LDAPTCL
));
ldaptcl
=
(
LDAPTCL
*
)
m
alloc
(
sizeof
(
LDAPTCL
));
ldaptcl
->
ldap
=
ldap
;
ldaptcl
->
caching
=
0
;
ldaptcl
->
timeout
=
0
;
ldaptcl
->
maxmem
=
0
;
ldaptcl
->
trapCmdObj
=
NULL
;
ldaptcl
->
traplist
=
NULL
;
ldaptcl
->
flags
=
0
;
Tcl_CreateObjCommand
(
interp
,
...
...
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