Issue #1258 - Part 1: Import mailnews, ldap, and mork from comm-esr52.9.1

This commit is contained in:
Matt A. Tobin 2019-11-03 00:17:46 -04:00 • committed by Roy Tam
commit e400f4130a
1564 changed files with 510348 additions and 0 deletions

View file

@ -0,0 +1,379 @@
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is Mozilla Communicator client code, released
* March 31, 1998.
*
* The Initial Developer of the Original Code is
* Netscape Communications Corporation.
* Portions created by the Initial Developer are Copyright (C) 1998-1999
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
*
* Alternatively, the contents of this file may be used under the terms of
* either of the GNU General Public License Version 2 or later (the "GPL"),
* or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
/*
* Copyright (c) 1993, 1994 Regents of the University of Michigan.
* All rights reserved.
*
* Redistribution and use in source and binary forms are permitted
* provided that this notice is preserved and that due credit is given
* to the University of Michigan at Ann Arbor. The name of the University
* may not be used to endorse or promote products derived from this
* software without specific prior written permission. This software
* is provided ``as is'' without express or implied warranty.
*
* disptmpl.h: display template library defines
*/
#ifndef _DISPTMPL_H
#define _DISPTMPL_H
#ifdef __cplusplus
extern "C" {
#endif
/* calling conventions used by library */
#ifndef LDAP_CALL
#if defined( _WINDOWS ) || defined( _WIN32 )
#define LDAP_C __cdecl
#ifndef _WIN32
#define __stdcall _far _pascal
#define LDAP_CALLBACK _loadds
#else
#define LDAP_CALLBACK
#endif /* _WIN32 */
#define LDAP_PASCAL __stdcall
#define LDAP_CALL LDAP_PASCAL
#else /* _WINDOWS */
#define LDAP_C
#define LDAP_CALLBACK
#define LDAP_PASCAL
#define LDAP_CALL
#endif /* _WINDOWS */
#endif /* LDAP_CALL */
#define LDAP_TEMPLATE_VERSION 1
/*
* general types of items (confined to most significant byte)
*/
#define LDAP_SYN_TYPE_TEXT 0x01000000L
#define LDAP_SYN_TYPE_IMAGE 0x02000000L
#define LDAP_SYN_TYPE_BOOLEAN 0x04000000L
#define LDAP_SYN_TYPE_BUTTON 0x08000000L
#define LDAP_SYN_TYPE_ACTION 0x10000000L
/*
* syntax options (confined to second most significant byte)
*/
#define LDAP_SYN_OPT_DEFER 0x00010000L
/*
* display template item syntax ids (defined by common agreement)
* these are the valid values for the ti_syntaxid of the tmplitem
* struct (defined below). A general type is encoded in the
* most-significant 8 bits, and some options are encoded in the next
* 8 bits. The lower 16 bits are reserved for the distinct types.
*/
#define LDAP_SYN_CASEIGNORESTR ( 1 | LDAP_SYN_TYPE_TEXT )
#define LDAP_SYN_MULTILINESTR ( 2 | LDAP_SYN_TYPE_TEXT )
#define LDAP_SYN_DN ( 3 | LDAP_SYN_TYPE_TEXT )
#define LDAP_SYN_BOOLEAN ( 4 | LDAP_SYN_TYPE_BOOLEAN )
#define LDAP_SYN_JPEGIMAGE ( 5 | LDAP_SYN_TYPE_IMAGE )
#define LDAP_SYN_JPEGBUTTON ( 6 | LDAP_SYN_TYPE_BUTTON | LDAP_SYN_OPT_DEFER )
#define LDAP_SYN_FAXIMAGE ( 7 | LDAP_SYN_TYPE_IMAGE )
#define LDAP_SYN_FAXBUTTON ( 8 | LDAP_SYN_TYPE_BUTTON | LDAP_SYN_OPT_DEFER )
#define LDAP_SYN_AUDIOBUTTON ( 9 | LDAP_SYN_TYPE_BUTTON | LDAP_SYN_OPT_DEFER )
#define LDAP_SYN_TIME ( 10 | LDAP_SYN_TYPE_TEXT )
#define LDAP_SYN_DATE ( 11 | LDAP_SYN_TYPE_TEXT )
#define LDAP_SYN_LABELEDURL ( 12 | LDAP_SYN_TYPE_TEXT )
#define LDAP_SYN_SEARCHACTION ( 13 | LDAP_SYN_TYPE_ACTION )
#define LDAP_SYN_LINKACTION ( 14 | LDAP_SYN_TYPE_ACTION )
#define LDAP_SYN_ADDDNACTION ( 15 | LDAP_SYN_TYPE_ACTION )
#define LDAP_SYN_VERIFYDNACTION ( 16 | LDAP_SYN_TYPE_ACTION )
#define LDAP_SYN_RFC822ADDR ( 17 | LDAP_SYN_TYPE_TEXT )
/*
* handy macros
*/
#define LDAP_GET_SYN_TYPE( syid ) ((syid) & 0xFF000000UL )
#define LDAP_GET_SYN_OPTIONS( syid ) ((syid) & 0x00FF0000UL )
/*
* display options for output routines (used by entry2text and friends)
*/
/*
* use calculated label width (based on length of longest label in
* template) instead of contant width
*/
#define LDAP_DISP_OPT_AUTOLABELWIDTH 0x00000001L
#define LDAP_DISP_OPT_HTMLBODYONLY 0x00000002L
/*
* perform search actions (applies to ldap_entry2text_search only)
*/
#define LDAP_DISP_OPT_DOSEARCHACTIONS 0x00000002L
/*
* include additional info. relevant to "non leaf" entries only
* used by ldap_entry2html and ldap_entry2html_search to include "Browse"
* and "Move Up" HREFs
*/
#define LDAP_DISP_OPT_NONLEAF 0x00000004L
/*
* display template item options (may not apply to all types)
* if this bit is set in ti_options, it applies.
*/
#define LDAP_DITEM_OPT_READONLY 0x00000001L
#define LDAP_DITEM_OPT_SORTVALUES 0x00000002L
#define LDAP_DITEM_OPT_SINGLEVALUED 0x00000004L
#define LDAP_DITEM_OPT_HIDEIFEMPTY 0x00000008L
#define LDAP_DITEM_OPT_VALUEREQUIRED 0x00000010L
#define LDAP_DITEM_OPT_HIDEIFFALSE 0x00000020L /* booleans only */
/*
* display template item structure
*/
struct ldap_tmplitem {
unsigned long ti_syntaxid;
unsigned long ti_options;
char *ti_attrname;
char *ti_label;
char **ti_args;
struct ldap_tmplitem *ti_next_in_row;
struct ldap_tmplitem *ti_next_in_col;
void *ti_appdata;
};
#define NULLTMPLITEM ((struct ldap_tmplitem *)0)
#define LDAP_SET_TMPLITEM_APPDATA( ti, datap ) \
(ti)->ti_appdata = (void *)(datap)
#define LDAP_GET_TMPLITEM_APPDATA( ti, type ) \
(type)((ti)->ti_appdata)
#define LDAP_IS_TMPLITEM_OPTION_SET( ti, option ) \
(((ti)->ti_options & option ) != 0 )
/*
* object class array structure
*/
struct ldap_oclist {
char **oc_objclasses;
struct ldap_oclist *oc_next;
};
#define NULLOCLIST ((struct ldap_oclist *)0)
/*
* add defaults list
*/
struct ldap_adddeflist {
int ad_source;
#define LDAP_ADSRC_CONSTANTVALUE 1
#define LDAP_ADSRC_ADDERSDN 2
char *ad_attrname;
char *ad_value;
struct ldap_adddeflist *ad_next;
};
#define NULLADLIST ((struct ldap_adddeflist *)0)
/*
* display template global options
* if this bit is set in dt_options, it applies.
*/
/*
* users should be allowed to try to add objects of these entries
*/
#define LDAP_DTMPL_OPT_ADDABLE 0x00000001L
/*
* users should be allowed to do "modify RDN" operation of these entries
*/
#define LDAP_DTMPL_OPT_ALLOWMODRDN 0x00000002L
/*
* this template is an alternate view, not a primary view
*/
#define LDAP_DTMPL_OPT_ALTVIEW 0x00000004L
/*
* display template structure
*/
struct ldap_disptmpl {
char *dt_name;
char *dt_pluralname;
char *dt_iconname;
unsigned long dt_options;
char *dt_authattrname;
char *dt_defrdnattrname;
char *dt_defaddlocation;
struct ldap_oclist *dt_oclist;
struct ldap_adddeflist *dt_adddeflist;
struct ldap_tmplitem *dt_items;
void *dt_appdata;
struct ldap_disptmpl *dt_next;
};
#define NULLDISPTMPL ((struct ldap_disptmpl *)0)
#define LDAP_SET_DISPTMPL_APPDATA( dt, datap ) \
(dt)->dt_appdata = (void *)(datap)
#define LDAP_GET_DISPTMPL_APPDATA( dt, type ) \
(type)((dt)->dt_appdata)
#define LDAP_IS_DISPTMPL_OPTION_SET( dt, option ) \
(((dt)->dt_options & option ) != 0 )
#define LDAP_TMPL_ERR_VERSION 1
#define LDAP_TMPL_ERR_MEM 2
#define LDAP_TMPL_ERR_SYNTAX 3
#define LDAP_TMPL_ERR_FILE 4
/*
* buffer size needed for entry2text and vals2text
*/
#define LDAP_DTMPL_BUFSIZ 8192
typedef int (*writeptype)( void *writeparm, char *p, int len );
LDAP_API(int)
LDAP_CALL
ldap_init_templates( char *file, struct ldap_disptmpl **tmpllistp );
LDAP_API(int)
LDAP_CALL
ldap_init_templates_buf( char *buf, long buflen,
struct ldap_disptmpl **tmpllistp );
LDAP_API(void)
LDAP_CALL
ldap_free_templates( struct ldap_disptmpl *tmpllist );
LDAP_API(struct ldap_disptmpl *)
LDAP_CALL
ldap_first_disptmpl( struct ldap_disptmpl *tmpllist );
LDAP_API(struct ldap_disptmpl *)
LDAP_CALL
ldap_next_disptmpl( struct ldap_disptmpl *tmpllist,
struct ldap_disptmpl *tmpl );
LDAP_API(struct ldap_disptmpl *)
LDAP_CALL
ldap_name2template( char *name, struct ldap_disptmpl *tmpllist );
LDAP_API(struct ldap_disptmpl *)
LDAP_CALL
ldap_oc2template( char **oclist, struct ldap_disptmpl *tmpllist );
LDAP_API(char **)
LDAP_CALL
ldap_tmplattrs( struct ldap_disptmpl *tmpl, char **includeattrs, int exclude,
unsigned long syntaxmask );
LDAP_API(struct ldap_tmplitem *)
LDAP_CALL
ldap_first_tmplrow( struct ldap_disptmpl *tmpl );
LDAP_API(struct ldap_tmplitem *)
LDAP_CALL
ldap_next_tmplrow( struct ldap_disptmpl *tmpl, struct ldap_tmplitem *row );
LDAP_API(struct ldap_tmplitem *)
LDAP_CALL
ldap_first_tmplcol( struct ldap_disptmpl *tmpl, struct ldap_tmplitem *row );
LDAP_API(struct ldap_tmplitem *)
LDAP_CALL
ldap_next_tmplcol( struct ldap_disptmpl *tmpl, struct ldap_tmplitem *row,
struct ldap_tmplitem *col );
LDAP_API(int)
LDAP_CALL
ldap_entry2text( LDAP *ld, char *buf, LDAPMessage *entry,
struct ldap_disptmpl *tmpl, char **defattrs, char ***defvals,
writeptype writeproc, void *writeparm, char *eol, int rdncount,
unsigned long opts );
LDAP_API(int)
LDAP_CALL
ldap_vals2text( LDAP *ld, char *buf, char **vals, char *label, int labelwidth,
unsigned long syntaxid, writeptype writeproc, void *writeparm,
char *eol, int rdncount );
LDAP_API(int)
LDAP_CALL
ldap_entry2text_search( LDAP *ld, char *dn, char *base, LDAPMessage *entry,
struct ldap_disptmpl *tmpllist, char **defattrs, char ***defvals,
writeptype writeproc, void *writeparm, char *eol, int rdncount,
unsigned long opts );
LDAP_API(int)
LDAP_CALL
ldap_entry2html( LDAP *ld, char *buf, LDAPMessage *entry,
struct ldap_disptmpl *tmpl, char **defattrs, char ***defvals,
writeptype writeproc, void *writeparm, char *eol, int rdncount,
unsigned long opts, char *urlprefix, char *base );
LDAP_API(int)
LDAP_CALL
ldap_vals2html( LDAP *ld, char *buf, char **vals, char *label, int labelwidth,
unsigned long syntaxid, writeptype writeproc, void *writeparm,
char *eol, int rdncount, char *urlprefix );
LDAP_API(int)
LDAP_CALL
ldap_entry2html_search( LDAP *ld, char *dn, char *base, LDAPMessage *entry,
struct ldap_disptmpl *tmpllist, char **defattrs, char ***defvals,
writeptype writeproc, void *writeparm, char *eol, int rdncount,
unsigned long opts, char *urlprefix );
LDAP_API(char *)
LDAP_CALL
ldap_tmplerr2string( int err );
#ifdef __cplusplus
}
#endif
#endif /* _DISPTMPL_H */

View file

@ -0,0 +1,72 @@
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is Mozilla Communicator client code, released
* March 31, 1998.
*
* The Initial Developer of the Original Code is
* Netscape Communications Corporation.
* Portions created by the Initial Developer are Copyright (C) 1998-1999
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
*
* Alternatively, the contents of this file may be used under the terms of
* either of the GNU General Public License Version 2 or later (the "GPL"),
* or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
/*
* Interface for libiutil the innosoft migration library
*
*/
#ifndef _IUTIL_H
#define _IUTIL_H
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
/* from iutil-lock.c */
#ifdef _WINDOWS
#define LDAP_MUTEX_T HANDLE
extern char *ldap_strdup();
extern unsigned char *ldap_utf8_nextchar();
extern char **ldap_explode_ava();
extern int ldap_utf8_toupper();
int pthread_mutex_init( LDAP_MUTEX_T *mp, void *attr);
static void * pthread_mutex_alloc( void );
int pthread_mutex_destroy( LDAP_MUTEX_T *mp );
static void pthread_mutex_free( void *mutexp );
int pthread_mutex_lock( LDAP_MUTEX_T *mp );
int pthread_mutex_unlock( LDAP_MUTEX_T *mp );
#endif /* _WINDOWS */
#ifdef __cplusplus
}
#endif /* __cplusplus */
#endif /* _IUTIL_H */

339
ldap/c-sdk/include/lber.h Normal file
View file

@ -0,0 +1,339 @@
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is Mozilla Communicator client code, released
* March 31, 1998.
*
* The Initial Developer of the Original Code is
* Netscape Communications Corporation.
* Portions created by the Initial Developer are Copyright (C) 1998-1999
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
*
* Alternatively, the contents of this file may be used under the terms of
* either of the GNU General Public License Version 2 or later (the "GPL"),
* or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
/* lber.h - header file for ber_* functions */
#ifndef _LBER_H
#define _LBER_H
#ifdef __cplusplus
extern "C" {
#endif
#include <stdlib.h> /* to pick up size_t typedef */
/*
* Note that LBER_ERROR and LBER_DEFAULT are values that can never appear
* as valid BER tags, and so it is safe to use them to report errors. In
* fact, any tag for which the following is true is invalid:
* (( tag & 0x00000080 ) != 0 ) && (( tag & 0xFFFFFF00 ) != 0 )
*/
#define LBER_ERROR ((ber_tag_t) -1) /* 0xffffffffU */
#define LBER_DEFAULT ((ber_tag_t) -1) /* 0xffffffffU */
#define LBER_END_OF_SEQORSET ((ber_tag_t) -2) /* 0xfffffffeU */
#define LBER_OVERFLOW ((ber_tag_t) -3) /* 0xfffffffdU */
/* BER classes and mask */
#define LBER_CLASS_UNIVERSAL 0x00
#define LBER_CLASS_APPLICATION 0x40
#define LBER_CLASS_CONTEXT 0x80
#define LBER_CLASS_PRIVATE 0xc0
#define LBER_CLASS_MASK 0xc0
/* BER encoding type and mask */
#define LBER_PRIMITIVE 0x00
#define LBER_CONSTRUCTED 0x20
#define LBER_ENCODING_MASK 0x20
#define LBER_BIG_TAG_MASK 0x1f
#define LBER_MORE_TAG_MASK 0x80
/* general BER types we know about */
#define LBER_BOOLEAN 0x01
#define LBER_INTEGER 0x02
#define LBER_BITSTRING 0x03
#define LBER_OCTETSTRING 0x04
#define LBER_NULL 0x05
#define LBER_ENUMERATED 0x0a
#define LBER_SEQUENCE 0x30
#define LBER_SET 0x31
/* BerElement set/get options */
#define LBER_OPT_REMAINING_BYTES 0x01
#define LBER_OPT_TOTAL_BYTES 0x02
#define LBER_OPT_USE_DER 0x04
#define LBER_OPT_TRANSLATE_STRINGS 0x08
#define LBER_OPT_BYTES_TO_WRITE 0x10
#define LBER_OPT_MEMALLOC_FN_PTRS 0x20
#define LBER_OPT_DEBUG_LEVEL 0x40
#define LBER_OPT_BUFSIZE 0x80
/*
* LBER_USE_DER is defined for compatibility with the C LDAP API RFC.
* In our implementation, we recognize it (instead of the numerically
* identical LBER_OPT_REMAINING_BYTES) in calls to ber_alloc_t() and
* ber_init_w_nullchar() only. Callers of ber_set_option() or
* ber_get_option() must use LBER_OPT_USE_DER instead. Sorry!
*/
#define LBER_USE_DER 0x01
/* Sockbuf set/get options */
#define LBER_SOCKBUF_OPT_TO_FILE 0x001
#define LBER_SOCKBUF_OPT_TO_FILE_ONLY 0x002
#define LBER_SOCKBUF_OPT_MAX_INCOMING_SIZE 0x004
#define LBER_SOCKBUF_OPT_NO_READ_AHEAD 0x008
#define LBER_SOCKBUF_OPT_DESC 0x010
#define LBER_SOCKBUF_OPT_COPYDESC 0x020
#define LBER_SOCKBUF_OPT_READ_FN 0x040
#define LBER_SOCKBUF_OPT_WRITE_FN 0x080
#define LBER_SOCKBUF_OPT_EXT_IO_FNS 0x100
#define LBER_SOCKBUF_OPT_VALID_TAG 0x200
#define LBER_SOCKBUF_OPT_SOCK_ARG 0x400
#define LBER_OPT_ON ((void *) 1)
#define LBER_OPT_OFF ((void *) 0)
typedef unsigned int ber_len_t; /* for BER len */
typedef unsigned int ber_tag_t; /* for BER tags */
typedef int ber_int_t; /* for BER ints, enums, and Booleans */
typedef unsigned int ber_uint_t; /* unsigned equivalent of ber_int_t */
typedef int ber_slen_t; /* signed equivalent of ber_len_t */
typedef struct berval {
ber_len_t bv_len;
char *bv_val;
} BerValue;
typedef struct berelement BerElement;
typedef struct sockbuf Sockbuf;
typedef int (*BERTranslateProc)( char **bufp, ber_uint_t *buflenp,
int free_input );
#ifndef macintosh
#if defined( _WINDOWS ) || defined( _WIN32) || defined( _CONSOLE )
#include <winsock.h> /* for SOCKET */
typedef SOCKET LBER_SOCKET;
#else
typedef long LBER_SOCKET;
#endif /* _WINDOWS */
#else /* macintosh */
typedef void *LBER_SOCKET;
#endif /* macintosh */
/* calling conventions used by library */
#ifndef LDAP_CALL
#if defined( _WINDOWS ) || defined( _WIN32 )
#define LDAP_C __cdecl
#ifndef _WIN32
#define __stdcall _far _pascal
#define LDAP_CALLBACK _loadds
#else
#define LDAP_CALLBACK
#endif /* _WIN32 */
#define LDAP_PASCAL __stdcall
#define LDAP_CALL LDAP_PASCAL
#else /* _WINDOWS */
#define LDAP_C
#define LDAP_CALLBACK
#define LDAP_PASCAL
#define LDAP_CALL
#endif /* _WINDOWS */
#endif /* LDAP_CALL */
/*
* function prototypes for lber library
*/
#ifndef LDAP_API
#if defined( _WINDOWS ) || defined( _WIN32 )
#define LDAP_API(rt) rt
#else /* _WINDOWS */
#define LDAP_API(rt) rt
#endif /* _WINDOWS */
#endif /* LDAP_API */
struct lextiof_socket_private; /* Defined by the extended I/O */
/* callback functions */
struct lextiof_session_private; /* Defined by the extended I/O */
/* callback functions */
/* This is modeled after the PRIOVec that is passed to the NSPR
writev function! The void* is a char* in that struct */
typedef struct ldap_x_iovec {
char *ldapiov_base;
int ldapiov_len;
} ldap_x_iovec;
/*
* libldap read and write I/O function callbacks. The rest of the I/O callback
* types are defined in ldap.h
*/
typedef int (LDAP_C LDAP_CALLBACK LDAP_IOF_READ_CALLBACK)( LBER_SOCKET s,
void *buf, int bufsize );
typedef int (LDAP_C LDAP_CALLBACK LDAP_IOF_WRITE_CALLBACK)( LBER_SOCKET s,
const void *buf, int len );
typedef int (LDAP_C LDAP_CALLBACK LDAP_X_EXTIOF_READ_CALLBACK)( int s,
void *buf, int bufsize, struct lextiof_socket_private *socketarg );
typedef int (LDAP_C LDAP_CALLBACK LDAP_X_EXTIOF_WRITE_CALLBACK)( int s,
const void *buf, int len, struct lextiof_socket_private *socketarg );
typedef int (LDAP_C LDAP_CALLBACK LDAP_X_EXTIOF_WRITEV_CALLBACK)(int s,
const ldap_x_iovec iov[], int iovcnt, struct lextiof_socket_private *socketarg);
/*
* Structure for use with LBER_SOCKBUF_OPT_EXT_IO_FNS:
*/
struct lber_x_ext_io_fns {
/* lbextiofn_size should always be set to LBER_X_EXTIO_FNS_SIZE */
int lbextiofn_size;
LDAP_X_EXTIOF_READ_CALLBACK *lbextiofn_read;
LDAP_X_EXTIOF_WRITE_CALLBACK *lbextiofn_write;
struct lextiof_socket_private *lbextiofn_socket_arg;
LDAP_X_EXTIOF_WRITEV_CALLBACK *lbextiofn_writev;
};
#define LBER_X_EXTIO_FNS_SIZE sizeof(struct lber_x_ext_io_fns)
/*
* liblber memory allocation callback functions. These are global to all
* Sockbufs and BerElements. Install your own functions by using a call
* like this: ber_set_option( NULL, LBER_OPT_MEMALLOC_FN_PTRS, &memalloc_fns );
*/
typedef void * (LDAP_C LDAP_CALLBACK LDAP_MALLOC_CALLBACK)( size_t size );
typedef void * (LDAP_C LDAP_CALLBACK LDAP_CALLOC_CALLBACK)( size_t nelem,
size_t elsize );
typedef void * (LDAP_C LDAP_CALLBACK LDAP_REALLOC_CALLBACK)( void *ptr,
size_t size );
typedef void (LDAP_C LDAP_CALLBACK LDAP_FREE_CALLBACK)( void *ptr );
struct lber_memalloc_fns {
LDAP_MALLOC_CALLBACK *lbermem_malloc;
LDAP_CALLOC_CALLBACK *lbermem_calloc;
LDAP_REALLOC_CALLBACK *lbermem_realloc;
LDAP_FREE_CALLBACK *lbermem_free;
};
/*
* decode routines
*/
LDAP_API(ber_tag_t) LDAP_CALL ber_get_tag( BerElement *ber );
LDAP_API(ber_tag_t) LDAP_CALL ber_skip_tag( BerElement *ber,
ber_len_t *len );
LDAP_API(ber_tag_t) LDAP_CALL ber_peek_tag( BerElement *ber,
ber_len_t *len );
LDAP_API(ber_tag_t) LDAP_CALL ber_get_int( BerElement *ber, ber_int_t *num );
LDAP_API(ber_tag_t) LDAP_CALL ber_get_stringb( BerElement *ber, char *buf,
ber_len_t *len );
LDAP_API(ber_tag_t) LDAP_CALL ber_get_stringa( BerElement *ber,
char **buf );
LDAP_API(ber_tag_t) LDAP_CALL ber_get_stringal( BerElement *ber,
struct berval **bv );
LDAP_API(ber_tag_t) LDAP_CALL ber_get_bitstringa( BerElement *ber,
char **buf, ber_len_t *len );
LDAP_API(ber_tag_t) LDAP_CALL ber_get_null( BerElement *ber );
LDAP_API(ber_tag_t) LDAP_CALL ber_get_boolean( BerElement *ber,
ber_int_t *boolval );
LDAP_API(ber_tag_t) LDAP_CALL ber_first_element( BerElement *ber,
ber_len_t *len, char **last );
LDAP_API(ber_tag_t) LDAP_CALL ber_next_element( BerElement *ber,
ber_len_t *len, char *last );
LDAP_API(ber_tag_t) LDAP_C ber_scanf( BerElement *ber, const char *fmt,
... );
LDAP_API(void) LDAP_CALL ber_bvfree( struct berval *bv );
LDAP_API(void) LDAP_CALL ber_bvecfree( struct berval **bv );
LDAP_API(void) LDAP_CALL ber_svecfree( char **vals );
LDAP_API(struct berval *) LDAP_CALL ber_bvdup( const struct berval *bv );
LDAP_API(void) LDAP_CALL ber_set_string_translators( BerElement *ber,
BERTranslateProc encode_proc, BERTranslateProc decode_proc );
LDAP_API(BerElement *) LDAP_CALL ber_init( const struct berval *bv );
/*
* encoding routines
*/
LDAP_API(int) LDAP_CALL ber_put_enum( BerElement *ber, ber_int_t num,
ber_tag_t tag );
LDAP_API(int) LDAP_CALL ber_put_int( BerElement *ber, ber_int_t num,
ber_tag_t tag );
LDAP_API(int) LDAP_CALL ber_put_ostring( BerElement *ber, char *str,
ber_len_t len, ber_tag_t tag );
LDAP_API(int) LDAP_CALL ber_put_string( BerElement *ber, char *str,
ber_tag_t tag );
LDAP_API(int) LDAP_CALL ber_put_bitstring( BerElement *ber, char *str,
ber_len_t bitlen, ber_tag_t tag );
LDAP_API(int) LDAP_CALL ber_put_null( BerElement *ber, ber_tag_t tag );
LDAP_API(int) LDAP_CALL ber_put_boolean( BerElement *ber,
ber_int_t boolval, ber_tag_t tag );
LDAP_API(int) LDAP_CALL ber_start_seq( BerElement *ber, ber_tag_t tag );
LDAP_API(int) LDAP_CALL ber_start_set( BerElement *ber, ber_tag_t tag );
LDAP_API(int) LDAP_CALL ber_put_seq( BerElement *ber );
LDAP_API(int) LDAP_CALL ber_put_set( BerElement *ber );
LDAP_API(int) LDAP_C ber_printf( BerElement *ber, const char *fmt, ... );
LDAP_API(int) LDAP_CALL ber_flatten( BerElement *ber,
struct berval **bvPtr );
/*
* miscellaneous routines
*/
LDAP_API(void) LDAP_CALL ber_free( BerElement *ber, int freebuf );
LDAP_API(void) LDAP_CALL ber_special_free(void* buf, BerElement *ber);
LDAP_API(int) LDAP_CALL ber_flush( Sockbuf *sb, BerElement *ber, int freeit );
LDAP_API(BerElement*) LDAP_CALL ber_alloc( void );
LDAP_API(BerElement*) LDAP_CALL der_alloc( void );
LDAP_API(BerElement*) LDAP_CALL ber_alloc_t( int options );
LDAP_API(void*) LDAP_CALL ber_special_alloc(size_t size, BerElement **ppBer);
LDAP_API(BerElement*) LDAP_CALL ber_dup( BerElement *ber );
LDAP_API(ber_tag_t) LDAP_CALL ber_get_next( Sockbuf *sb, ber_len_t *len,
BerElement *ber );
LDAP_API(ber_tag_t) LDAP_CALL ber_get_next_buffer( void *buffer,
size_t buffer_size, ber_len_t *len, BerElement *ber,
ber_len_t *Bytes_Scanned );
LDAP_API(ber_tag_t) LDAP_CALL ber_get_next_buffer_ext( void *buffer,
size_t buffer_size, ber_len_t *len, BerElement *ber,
ber_len_t *Bytes_Scanned, Sockbuf *sb );
LDAP_API(ber_int_t) LDAP_CALL ber_read( BerElement *ber, char *buf,
ber_len_t len );
LDAP_API(ber_int_t) LDAP_CALL ber_write( BerElement *ber, char *buf,
ber_len_t len, int nosos );
LDAP_API(void) LDAP_CALL ber_init_w_nullchar( BerElement *ber, int options );
LDAP_API(void) LDAP_CALL ber_reset( BerElement *ber, int was_writing );
LDAP_API(size_t) LDAP_CALL ber_get_buf_datalen( BerElement *ber );
LDAP_API(int) LDAP_CALL ber_stack_init(BerElement *ber, int options,
char * buf, size_t size);
LDAP_API(char*) LDAP_CALL ber_get_buf_databegin (BerElement * ber);
LDAP_API(void) LDAP_CALL ber_sockbuf_free_data(Sockbuf *p);
LDAP_API(int) LDAP_CALL ber_set_option( BerElement *ber, int option,
void *value );
LDAP_API(int) LDAP_CALL ber_get_option( BerElement *ber, int option,
void *value );
LDAP_API(Sockbuf*) LDAP_CALL ber_sockbuf_alloc( void );
LDAP_API(void) LDAP_CALL ber_sockbuf_free( Sockbuf* p );
LDAP_API(int) LDAP_CALL ber_sockbuf_set_option( Sockbuf *sb, int option,
void *value );
LDAP_API(int) LDAP_CALL ber_sockbuf_get_option( Sockbuf *sb, int option,
void *value );
#ifdef __cplusplus
}
#endif
#endif /* _LBER_H */

View file

@ -0,0 +1,94 @@
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is Mozilla Communicator client code, released
* March 31, 1998.
*
* The Initial Developer of the Original Code is
* Netscape Communications Corporation.
* Portions created by the Initial Developer are Copyright (C) 1998-1999
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
*
* Alternatively, the contents of this file may be used under the terms of
* either of the GNU General Public License Version 2 or later (the "GPL"),
* or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
/* lcache.h - ldap persistent cache */
#ifndef _LCACHE_H
#define _LCACHE_H
#ifdef __cplusplus
extern "C" {
#endif
/* calling conventions used by library */
#ifndef LDAP_CALL
#if defined( _WINDOWS ) || defined( _WIN32 )
#define LDAP_C __cdecl
#ifndef _WIN32
#define __stdcall _far _pascal
#define LDAP_CALLBACK _loadds
#else
#define LDAP_CALLBACK
#endif /* _WIN32 */
#define LDAP_PASCAL __stdcall
#define LDAP_CALL LDAP_PASCAL
#else /* _WINDOWS */
#define LDAP_C
#define LDAP_CALLBACK
#define LDAP_PASCAL
#define LDAP_CALL
#endif /* _WINDOWS */
#endif /* LDAP_CALL */
LDAP_API(int) LDAP_C lcache_init( LDAP *ld, void *arg );
LDAP_API(int) LDAP_C lcache_bind( LDAP *ld, int msgid, unsigned long tag,
const char *dn, struct berval *cred, int method );
LDAP_API(int) LDAP_C lcache_unbind( LDAP *ld, int msgid, unsigned long tag );
LDAP_API(int) LDAP_C lcache_search( LDAP *ld, int msgid, unsigned long tag,
const char *dn, int scope, const char *filter, char **attrs,
int attrsonly );
LDAP_API(int) LDAP_C lcache_compare( LDAP *ld, int msgid, unsigned long tag,
const char *dn, const char *attr, struct berval *val );
LDAP_API(int) LDAP_C lcache_add( LDAP *ld, int msgid, unsigned long tag,
const char *dn, LDAPMod **entry );
LDAP_API(int) LDAP_C lcache_delete( LDAP *ld, int msgid, unsigned long tag,
const char *dn );
LDAP_API(int) LDAP_C lcache_rename( LDAP *ld, int msgid, unsigned long tag,
const char *dn, const char *newrdn, const char *newparent,
int deleteoldrdn );
LDAP_API(int) LDAP_C lcache_modify( LDAP *ld, int msgid, unsigned long tag,
const char *dn, LDAPMod **mods );
LDAP_API(int) LDAP_C lcache_modrdn( LDAP *ld, int msgid, unsigned long tag,
const char *dn, const char *newrdn, int deleteoldrdn );
LDAP_API(int) LDAP_C lcache_result( LDAP *ld, int msgid, int all,
struct timeval *timeout, LDAPMessage **result );
LDAP_API(int) LDAP_C lcache_flush( LDAP *ld, char *dn, char *filter );
#ifdef __cplusplus
}
#endif
#endif /* _LCACHE_H */

View file

@ -0,0 +1,201 @@
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is Mozilla Communicator client code, released
* March 31, 1998.
*
* The Initial Developer of the Original Code is
* Netscape Communications Corporation.
* Portions created by the Initial Developer are Copyright (C) 1998-1999
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
*
* Alternatively, the contents of this file may be used under the terms of
* either of the GNU General Public License Version 2 or later (the "GPL"),
* or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
/* ldap-deprecated.h - deprecated functions and declarations
*
* A deprecated API is an API that we recommend you no longer use,
* due to improvements in the LDAP C SDK. While deprecated APIs are
* currently still implemented, they may be removed in future
* implementations, and we recommend using other APIs.
*
* This file contain functions and declarations which have
* outlived their usefullness and have been deprecated. In many
* cases functions and declarations have been replaced with newer
* extended functions. In no way should applications rely on the
* declarations and defines within this files as they can and will
* disappear without any notice.
*/
#ifndef _LDAP_DEPRECATED_H
#define _LDAP_DEPRECATED_H
#ifdef __cplusplus
extern "C" {
#endif
/*
* establish an ldap session
*/
LDAP_API(LDAP *) LDAP_CALL ldap_open( const char *host, int port );
/*
* Authentication methods:
*/
#define LDAP_AUTH_NONE 0x00L
#define LDAP_AUTH_SIMPLE 0x80L
#define LDAP_AUTH_SASL 0xa3L
LDAP_API(int) LDAP_CALL ldap_bind( LDAP *ld, const char *who,
const char *passwd, int authmethod );
LDAP_API(int) LDAP_CALL ldap_bind_s( LDAP *ld, const char *who,
const char *cred, int method );
LDAP_API(int) LDAP_CALL ldap_modrdn( LDAP *ld, const char *dn,
const char *newrdn );
LDAP_API(int) LDAP_CALL ldap_modrdn_s( LDAP *ld, const char *dn,
const char *newrdn );
LDAP_API(int) LDAP_CALL ldap_modrdn2( LDAP *ld, const char *dn,
const char *newrdn, int deleteoldrdn );
LDAP_API(int) LDAP_CALL ldap_modrdn2_s( LDAP *ld, const char *dn,
const char *newrdn, int deleteoldrdn);
LDAP_API(void) LDAP_CALL ldap_perror( LDAP *ld, const char *s );
LDAP_API(int) LDAP_CALL ldap_result2error( LDAP *ld, LDAPMessage *r,
int freeit );
/*
* Preferred language and get_lang_values (an API extension --
* LDAP_API_FEATURE_X_GETLANGVALUES)
*
* The following two APIs are deprecated
*/
#define LDAP_OPT_PREFERRED_LANGUAGE 0x14 /* 20 - API extension */
LDAP_API(char **) LDAP_CALL ldap_get_lang_values( LDAP *ld, LDAPMessage *entry,
const char *target, char **type );
LDAP_API(struct berval **) LDAP_CALL ldap_get_lang_values_len( LDAP *ld,
LDAPMessage *entry, const char *target, char **type );
/*
* Asynchronous I/O (an API extension).
*/
/*
* This option enables completely asynchronous IO. It works by using ioctl()
* on the fd, (or tlook())
*/
#define LDAP_OPT_ASYNC_CONNECT 0x63 /* 99 - API extension */
/*
* functions and definitions that have been replaced by new improved ones
*/
/*
* Use ldap_get_option() with LDAP_OPT_API_INFO and an LDAPAPIInfo structure
* instead of ldap_version().
*/
typedef struct _LDAPVersion {
int sdk_version; /* Version of the SDK, * 100 */
int protocol_version; /* Highest protocol version supported, * 100 */
int SSL_version; /* SSL version if this SDK supports it, * 100 */
int security_level; /* highest level available */
int reserved[4];
} LDAPVersion;
#define LDAP_SECURITY_NONE 0
LDAP_API(int) LDAP_CALL ldap_version( LDAPVersion *ver );
/* use ldap_create_filter() instead of ldap_build_filter() */
LDAP_API(void) LDAP_CALL ldap_build_filter( char *buf, unsigned long buflen,
char *pattern, char *prefix, char *suffix, char *attr,
char *value, char **valwords );
/* use ldap_set_filter_additions() instead of ldap_setfilteraffixes() */
LDAP_API(void) LDAP_CALL ldap_setfilteraffixes( LDAPFiltDesc *lfdp,
char *prefix, char *suffix );
/* older result types a server can return -- use LDAP_RES_MODDN instead */
#define LDAP_RES_MODRDN LDAP_RES_MODDN
#define LDAP_RES_RENAME LDAP_RES_MODDN
/* older error messages */
#define LDAP_AUTH_METHOD_NOT_SUPPORTED LDAP_STRONG_AUTH_NOT_SUPPORTED
/*
* Generalized cache callback interface:
*/
#define LDAP_OPT_CACHE_FN_PTRS 0x0D /* 13 - API extension */
#define LDAP_OPT_CACHE_STRATEGY 0x0E /* 14 - API extension */
#define LDAP_OPT_CACHE_ENABLE 0x0F /* 15 - API extension */
/* cache strategies */
#define LDAP_CACHE_CHECK 0
#define LDAP_CACHE_POPULATE 1
#define LDAP_CACHE_LOCALDB 2
typedef int (LDAP_C LDAP_CALLBACK LDAP_CF_BIND_CALLBACK)( LDAP *ld, int msgid,
unsigned long tag, const char *dn, const struct berval *creds,
int method);
typedef int (LDAP_C LDAP_CALLBACK LDAP_CF_UNBIND_CALLBACK)( LDAP *ld,
int unused0, unsigned long unused1 );
typedef int (LDAP_C LDAP_CALLBACK LDAP_CF_SEARCH_CALLBACK)( LDAP *ld,
int msgid, unsigned long tag, const char *base, int scope,
const char LDAP_CALLBACK *filter, char **attrs, int attrsonly );
typedef int (LDAP_C LDAP_CALLBACK LDAP_CF_COMPARE_CALLBACK)( LDAP *ld,
int msgid, unsigned long tag, const char *dn, const char *attr,
const struct berval *value );
typedef int (LDAP_C LDAP_CALLBACK LDAP_CF_ADD_CALLBACK)( LDAP *ld,
int msgid, unsigned long tag, const char *dn, LDAPMod **attrs );
typedef int (LDAP_C LDAP_CALLBACK LDAP_CF_DELETE_CALLBACK)( LDAP *ld,
int msgid, unsigned long tag, const char *dn );
typedef int (LDAP_C LDAP_CALLBACK LDAP_CF_MODIFY_CALLBACK)( LDAP *ld,
int msgid, unsigned long tag, const char *dn, LDAPMod **mods );
typedef int (LDAP_C LDAP_CALLBACK LDAP_CF_MODRDN_CALLBACK)( LDAP *ld,
int msgid, unsigned long tag, const char *dn, const char *newrdn,
int deleteoldrdn );
typedef int (LDAP_C LDAP_CALLBACK LDAP_CF_RESULT_CALLBACK)( LDAP *ld,
int msgid, int all, struct timeval *timeout, LDAPMessage **result );
typedef int (LDAP_C LDAP_CALLBACK LDAP_CF_FLUSH_CALLBACK)( LDAP *ld,
const char *dn, const char *filter );
struct ldap_cache_fns {
void *lcf_private;
LDAP_CF_BIND_CALLBACK *lcf_bind;
LDAP_CF_UNBIND_CALLBACK *lcf_unbind;
LDAP_CF_SEARCH_CALLBACK *lcf_search;
LDAP_CF_COMPARE_CALLBACK *lcf_compare;
LDAP_CF_ADD_CALLBACK *lcf_add;
LDAP_CF_DELETE_CALLBACK *lcf_delete;
LDAP_CF_MODIFY_CALLBACK *lcf_modify;
LDAP_CF_MODRDN_CALLBACK *lcf_modrdn;
LDAP_CF_RESULT_CALLBACK *lcf_result;
LDAP_CF_FLUSH_CALLBACK *lcf_flush;
};
LDAP_API(int) LDAP_CALL ldap_cache_flush( LDAP *ld, const char *dn,
const char *filter );
#ifdef __cplusplus
}
#endif
#endif /* _LDAP_DEPRECATED_H */

View file

@ -0,0 +1,853 @@
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is Mozilla Communicator client code, released
* March 31, 1998.
*
* The Initial Developer of the Original Code is
* Netscape Communications Corporation.
* Portions created by the Initial Developer are Copyright (C) 1998-1999
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
*
* Alternatively, the contents of this file may be used under the terms of
* either of the GNU General Public License Version 2 or later (the "GPL"),
* or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
/* ldap-extension.h - extensions to the ldap c api specification */
#ifndef _LDAP_EXTENSION_H
#define _LDAP_EXTENSION_H
#ifdef __cplusplus
extern "C" {
#endif
#define LDAP_PORT_MAX 65535 /* API extension */
#define LDAP_VERSION1 1 /* API extension */
#define LDAP_VERSION LDAP_VERSION3 /* API extension */
/*
* C LDAP features we support that are not (yet) part of the LDAP C API
* Internet Draft. Use the ldap_get_option() call with an option value of
* LDAP_OPT_API_FEATURE_INFO to retrieve information about a feature.
*
* Note that this list is incomplete; it includes only the most widely
* used extensions. Also, the version is 1 for all of these for now.
*/
#define LDAP_API_FEATURE_SERVER_SIDE_SORT 1
#define LDAP_API_FEATURE_VIRTUAL_LIST_VIEW 1
#define LDAP_API_FEATURE_PERSISTENT_SEARCH 1
#define LDAP_API_FEATURE_PROXY_AUTHORIZATION 1
#define LDAP_API_FEATURE_X_LDERRNO 1
#define LDAP_API_FEATURE_X_MEMCACHE 1
#define LDAP_API_FEATURE_X_IO_FUNCTIONS 1
#define LDAP_API_FEATURE_X_EXTIO_FUNCTIONS 1
#define LDAP_API_FEATURE_X_DNS_FUNCTIONS 1
#define LDAP_API_FEATURE_X_MEMALLOC_FUNCTIONS 1
#define LDAP_API_FEATURE_X_THREAD_FUNCTIONS 1
#define LDAP_API_FEATURE_X_EXTHREAD_FUNCTIONS 1
#define LDAP_API_FEATURE_X_GETLANGVALUES 1
#define LDAP_API_FEATURE_X_CLIENT_SIDE_SORT 1
#define LDAP_API_FEATURE_X_URL_FUNCTIONS 1
#define LDAP_API_FEATURE_X_FILTER_FUNCTIONS 1
#define LDAP_ROOT_DSE "" /* API extension */
#define LDAP_OPT_DESC 0x01 /* 1 */
#define NULLMSG ((LDAPMessage *)0)
/*built-in SASL methods */
#define LDAP_SASL_EXTERNAL "EXTERNAL" /* TLS/SSL extension */
/* possible error codes we can be returned */
#define LDAP_PARTIAL_RESULTS 0x09 /* 9 (UMich LDAPv2 extn) */
#define NAME_ERROR(n) ((n & 0xf0) == 0x20)
#define LDAP_SORT_CONTROL_MISSING 0x3C /* 60 (server side sort extn) */
#define LDAP_INDEX_RANGE_ERROR 0x3D /* 61 (VLV extn) */
/*
* LDAPv3 server controls we know about
*/
#define LDAP_CONTROL_MANAGEDSAIT "2.16.840.1.113730.3.4.2"
#define LDAP_CONTROL_SORTREQUEST "1.2.840.113556.1.4.473"
#define LDAP_CONTROL_SORTRESPONSE "1.2.840.113556.1.4.474"
#define LDAP_CONTROL_PERSISTENTSEARCH "2.16.840.1.113730.3.4.3"
#define LDAP_CONTROL_ENTRYCHANGE "2.16.840.1.113730.3.4.7"
#define LDAP_CONTROL_VLVREQUEST "2.16.840.1.113730.3.4.9"
#define LDAP_CONTROL_VLVRESPONSE "2.16.840.1.113730.3.4.10"
#define LDAP_CONTROL_PROXYAUTH "2.16.840.1.113730.3.4.12" /* version 1
*/
#define LDAP_CONTROL_PROXIEDAUTH "2.16.840.1.113730.3.4.18" /* version 2
*/
/* Authorization Identity Request and Response Controls */
#define LDAP_CONTROL_AUTHZID_REQ "2.16.840.1.113730.3.4.16"
#define LDAP_CONTROL_AUTHZID_RES "2.16.840.1.113730.3.4.15"
/* Authentication request and response controls */
#define LDAP_CONTROL_AUTH_REQUEST LDAP_CONTROL_AUTHZID_REQ
#define LDAP_CONTROL_AUTH_RESPONSE LDAP_CONTROL_AUTHZID_RES
/* Password information sent back to client */
#define LDAP_CONTROL_PWEXPIRED "2.16.840.1.113730.3.4.4"
#define LDAP_CONTROL_PWEXPIRING "2.16.840.1.113730.3.4.5"
/* Password Policy Control */
#define LDAP_CONTROL_PASSWD_POLICY "1.3.6.1.4.1.42.2.27.8.5.1"
/* Password Policy Control compatibility macros */
#define LDAP_X_CONTROL_PWPOLICY_REQUEST LDAP_CONTROL_PASSWD_POLICY
#define LDAP_X_CONTROL_PWPOLICY_RESPONSE LDAP_CONTROL_PASSWD_POLICY
#define LDAP_CONTROL_PASSWORDPOLICYREQUEST LDAP_CONTROL_PASSWD_POLICY
#define LDAP_CONTROL_PASSWORDPOLICYRESPONSE LDAP_CONTROL_PASSWD_POLICY
/* Password Modify Extended Operation */
#define LDAP_EXOP_MODIFY_PASSWD "1.3.6.1.4.1.4203.1.11.1"
/* Suppress virtual/inherited attribute values */
#define LDAP_CONTROL_REAL_ATTRS_ONLY "2.16.840.1.113730.3.4.17"
/* Only return virtual/inherited attribute values */
#define LDAP_CONTROL_VIRTUAL_ATTRS_ONLY "2.16.840.1.113730.3.4.19"
/* getEffectiveRights request */
#define LDAP_CONTROL_GETEFFECTIVERIGHTS_REQUEST "1.3.6.1.4.1.42.2.27.9.5.2"
/* Password Policy Control to get account availability */
#define LDAP_CONTROL_ACCOUNT_USABLE "1.3.6.1.4.1.42.2.27.9.5.8"
/* "Who am I?" Extended Operation */
#define LDAP_EXOP_WHO_AM_I "1.3.6.1.4.1.4203.1.11.3"
LDAP_API(void) LDAP_CALL ldap_ber_free( BerElement *ber, int freebuf );
LDAP_API(LDAPControl *) LDAP_CALL ldap_find_control( const char *oid,
LDAPControl **ctrls );
/*
* Server side sorting of search results (an LDAPv3 extension --
* LDAP_API_FEATURE_SERVER_SIDE_SORT)
*/
typedef struct LDAPsortkey { /* structure for a sort-key */
char * sk_attrtype;
char * sk_matchruleoid;
int sk_reverseorder;
} LDAPsortkey;
/* where LDAP_CONTROL_ACCOUNT_USABLE control parse results */
typedef struct LDAPuserstatus { /* user account availability */
unsigned int us_available; /* availability status */
#define LDAP_US_ACCOUNT_USABLE 1
#define LDAP_US_ACCOUNT_NOT_USABLE 0
int us_expire; /* will expire in seconds */
int us_inactive; /* boolean inactivation status */
#define LDAP_US_ACCOUNT_ACTIVE 0
#define LDAP_US_ACCOUNT_INACTIVE 1
int us_reset; /* boolean password reset */
#define LDAP_US_ACCOUNT_NOT_RESET 0
#define LDAP_US_ACCOUNT_RESET 1
int us_expired; /* boolean password expired */
#define LDAP_US_ACCOUNT_NOT_EXPIRED 0
#define LDAP_US_ACCOUNT_EXPIRED 1
int us_remaining; /* remaining logins */
int us_seconds; /* will unlock in seconds */
} LDAPuserstatus;
/* LDAP_CONTROL_PASSWD_POLICY results */
typedef enum passpolicyerror_enum {
PP_passwordExpired = 0,
PP_accountLocked = 1,
PP_changeAfterReset = 2,
PP_passwordModNotAllowed = 3,
PP_mustSupplyOldPassword = 4,
PP_insufficientPasswordQuality = 5,
PP_passwordTooShort = 6,
PP_passwordTooYoung = 7,
PP_passwordInHistory = 8,
PP_noError = 65535
} LDAPPasswordPolicyError;
LDAP_API(int) LDAP_CALL ldap_create_sort_control( LDAP *ld,
LDAPsortkey **sortKeyList, const char ctl_iscritical,
LDAPControl **ctrlp );
LDAP_API(int) LDAP_CALL ldap_parse_sort_control( LDAP *ld,
LDAPControl **ctrls, ber_int_t *result, char **attribute );
LDAP_API(void) LDAP_CALL ldap_free_sort_keylist( LDAPsortkey **sortKeyList );
LDAP_API(int) LDAP_CALL ldap_create_sort_keylist( LDAPsortkey ***sortKeyList,
const char *string_rep );
LDAP_API(int) LDAP_CALL ldap_create_userstatus_control(
LDAP *ld, const char ctl_iscritical, LDAPControl **ctrlp );
LDAP_API(int) LDAP_CALL ldap_parse_userstatus_control( LDAP *ld,
LDAPControl **ctrlp, LDAPuserstatus *us );
LDAP_API(int) LDAP_CALL ldap_create_passwordpolicy_control( LDAP *ld,
LDAPControl **ctrlp );
LDAP_API(int) LDAP_CALL ldap_create_passwordpolicy_control_ext( LDAP *ld,
const char ctl_iscritical, LDAPControl **ctrlp );
LDAP_API(int) LDAP_CALL ldap_parse_passwordpolicy_control( LDAP *ld,
LDAPControl *ctrlp, ber_int_t *expirep, ber_int_t *gracep,
LDAPPasswordPolicyError *errorp );
LDAP_API(int) LDAP_CALL ldap_parse_passwordpolicy_control_ext ( LDAP *ld,
LDAPControl **ctrlp, ber_int_t *expirep, ber_int_t *gracep,
LDAPPasswordPolicyError *errorp );
LDAP_API(const char *) LDAP_CALL ldap_passwordpolicy_err2txt(
LDAPPasswordPolicyError err );
LDAP_API(int) LDAP_CALL ldap_create_authzid_control( LDAP *ld,
const char ctl_iscritical, LDAPControl **ctrlp );
LDAP_API(int) LDAP_CALL ldap_parse_authzid_control( LDAP *ld,
LDAPControl **ctrlp, char **authzid );
LDAP_API(int) LDAP_CALL ldap_whoami( LDAP *ld, LDAPControl **serverctrls,
LDAPControl **clientctrls, int *msgidp );
LDAP_API(int) LDAP_CALL ldap_whoami_s( LDAP *ld, struct berval **authzid,
LDAPControl **serverctrls, LDAPControl **clientctrls );
LDAP_API(int) LDAP_CALL ldap_parse_whoami( LDAP *ld, LDAPMessage *result,
struct berval **authzid );
LDAP_API(int) LDAP_CALL ldap_create_geteffectiveRights_control( LDAP *ld,
const char *authzid, const char **attrlist, const char ctl_iscritical,
LDAPControl **ctrlp );
/*
* Virtual list view (an LDAPv3 extension -- LDAP_API_FEATURE_VIRTUAL_LIST_VIEW)
*/
/*
* structure that describes a VirtualListViewRequest control.
* note that ldvlist_index and ldvlist_size are only relevant to
* ldap_create_virtuallist_control() if ldvlist_attrvalue is NULL.
*/
typedef struct ldapvirtuallist {
ber_int_t ldvlist_before_count; /* # entries before target */
ber_int_t ldvlist_after_count; /* # entries after target */
char *ldvlist_attrvalue; /* jump to this value */
ber_int_t ldvlist_index; /* list offset */
ber_int_t ldvlist_size; /* number of items in vlist */
void *ldvlist_extradata; /* for use by application */
} LDAPVirtualList;
/*
* VLV functions:
*/
LDAP_API(int) LDAP_CALL ldap_create_virtuallist_control( LDAP *ld,
LDAPVirtualList *ldvlistp, LDAPControl **ctrlp );
LDAP_API(int) LDAP_CALL ldap_parse_virtuallist_control( LDAP *ld,
LDAPControl **ctrls, ber_int_t *target_posp,
ber_int_t *list_sizep, int *errcodep );
/*
* Routines for creating persistent search controls and for handling
* "entry changed notification" controls (an LDAPv3 extension --
* LDAP_API_FEATURE_PERSISTENT_SEARCH)
*/
#define LDAP_CHANGETYPE_ADD 1
#define LDAP_CHANGETYPE_DELETE 2
#define LDAP_CHANGETYPE_MODIFY 4
#define LDAP_CHANGETYPE_MODDN 8
#define LDAP_CHANGETYPE_ANY (1|2|4|8)
LDAP_API(int) LDAP_CALL ldap_create_persistentsearch_control( LDAP *ld,
int changetypes, int changesonly, int return_echg_ctls,
char ctl_iscritical, LDAPControl **ctrlp );
LDAP_API(int) LDAP_CALL ldap_parse_entrychange_control( LDAP *ld,
LDAPControl **ctrls, ber_int_t *chgtypep, char **prevdnp,
int *chgnumpresentp, ber_int_t *chgnump );
/*
* Routines for creating Proxied Authorization controls (an LDAPv3
* extension -- LDAP_API_FEATURE_PROXY_AUTHORIZATION)
* ldap_create_proxyauth_control() is for the old (version 1) control.
* ldap_create_proxiedauth_control() is for the newer (version 2) control.
*/
LDAP_API(int) LDAP_CALL ldap_create_proxyauth_control( LDAP *ld,
const char *dn, const char ctl_iscritical, LDAPControl **ctrlp );
LDAP_API(int) LDAP_CALL ldap_create_proxiedauth_control( LDAP *ld,
const char *authzid, LDAPControl **ctrlp );
/*
* Functions to get and set LDAP error information (API extension --
* LDAP_API_FEATURE_X_LDERRNO )
*
* By using LDAP_OPT_THREAD_FN_PTRS, you can arrange for the error info. to
* be thread-specific.
*/
LDAP_API(int) LDAP_CALL ldap_get_lderrno( LDAP *ld, char **m, char **s );
LDAP_API(int) LDAP_CALL ldap_set_lderrno( LDAP *ld, int e, char *m, char *s );
/*
* LDAP URL functions and definitions (an API extension --
* LDAP_API_FEATURE_X_URL_FUNCTIONS)
*/
/*
* types for ldap URL handling
*/
typedef struct ldap_url_desc {
char *lud_host;
int lud_port;
char *lud_dn;
char **lud_attrs;
int lud_scope;
char *lud_filter;
unsigned long lud_options;
#define LDAP_URL_OPT_SECURE 0x01
char *lud_string; /* for internal use only */
} LDAPURLDesc;
#define NULLLDAPURLDESC ((LDAPURLDesc *)NULL)
/*
* possible errors returned by ldap_url_parse()
*/
#define LDAP_URL_ERR_NOTLDAP 1 /* URL doesn't begin with "ldap://" */
#define LDAP_URL_ERR_NODN 2 /* URL has no DN (required) */
#define LDAP_URL_ERR_BADSCOPE 3 /* URL scope string is invalid */
#define LDAP_URL_ERR_MEM 4 /* can't allocate memory space */
#define LDAP_URL_ERR_PARAM 5 /* bad parameter to an URL function */
#define LDAP_URL_UNRECOGNIZED_CRITICAL_EXTENSION 6
/*
* URL functions:
*/
LDAP_API(int) LDAP_CALL ldap_is_ldap_url( const char *url );
LDAP_API(int) LDAP_CALL ldap_url_parse( const char *url, LDAPURLDesc **ludpp );
LDAP_API(int) LDAP_CALL ldap_url_parse_no_defaults( const char *url,
LDAPURLDesc **ludpp, int dn_required);
LDAP_API(void) LDAP_CALL ldap_free_urldesc( LDAPURLDesc *ludp );
LDAP_API(int) LDAP_CALL ldap_url_search( LDAP *ld, const char *url,
int attrsonly );
LDAP_API(int) LDAP_CALL ldap_url_search_s( LDAP *ld, const char *url,
int attrsonly, LDAPMessage **res );
LDAP_API(int) LDAP_CALL ldap_url_search_st( LDAP *ld, const char *url,
int attrsonly, struct timeval *timeout, LDAPMessage **res );
/*
* Function to dispose of an array of LDAPMod structures (an API extension).
* Warning: don't use this unless the mods array was allocated using the
* same memory allocator as is being used by libldap.
*/
LDAP_API(void) LDAP_CALL ldap_mods_free( LDAPMod **mods, int freemods );
/*
* SSL option (an API extension):
*/
#define LDAP_OPT_SSL 0x0A /* 10 - API extension */
/*
* Referral hop limit (an API extension):
*/
#define LDAP_OPT_REFERRAL_HOP_LIMIT 0x10 /* 16 - API extension */
/*
* Rebind callback function (an API extension)
*/
#define LDAP_OPT_REBIND_FN 0x06 /* 6 - API extension */
#define LDAP_OPT_REBIND_ARG 0x07 /* 7 - API extension */
typedef int (LDAP_CALL LDAP_CALLBACK LDAP_REBINDPROC_CALLBACK)( LDAP *ld,
char **dnp, char **passwdp, int *authmethodp, int freeit, void *arg);
LDAP_API(void) LDAP_CALL ldap_set_rebind_proc( LDAP *ld,
LDAP_REBINDPROC_CALLBACK *rebindproc, void *arg );
/*
* Thread function callbacks (an API extension --
* LDAP_API_FEATURE_X_THREAD_FUNCTIONS).
*/
#define LDAP_OPT_THREAD_FN_PTRS 0x05 /* 5 - API extension */
/*
* Thread callback functions:
*/
typedef void *(LDAP_C LDAP_CALLBACK LDAP_TF_MUTEX_ALLOC_CALLBACK)( void );
typedef void (LDAP_C LDAP_CALLBACK LDAP_TF_MUTEX_FREE_CALLBACK)( void *m );
typedef int (LDAP_C LDAP_CALLBACK LDAP_TF_MUTEX_LOCK_CALLBACK)( void *m );
typedef int (LDAP_C LDAP_CALLBACK LDAP_TF_MUTEX_UNLOCK_CALLBACK)( void *m );
typedef int (LDAP_C LDAP_CALLBACK LDAP_TF_GET_ERRNO_CALLBACK)( void );
typedef void (LDAP_C LDAP_CALLBACK LDAP_TF_SET_ERRNO_CALLBACK)( int e );
typedef int (LDAP_C LDAP_CALLBACK LDAP_TF_GET_LDERRNO_CALLBACK)(
char **matchedp, char **errmsgp, void *arg );
typedef void (LDAP_C LDAP_CALLBACK LDAP_TF_SET_LDERRNO_CALLBACK)( int err,
char *matched, char *errmsg, void *arg );
/*
* Structure to hold thread function pointers:
*/
struct ldap_thread_fns {
LDAP_TF_MUTEX_ALLOC_CALLBACK *ltf_mutex_alloc;
LDAP_TF_MUTEX_FREE_CALLBACK *ltf_mutex_free;
LDAP_TF_MUTEX_LOCK_CALLBACK *ltf_mutex_lock;
LDAP_TF_MUTEX_UNLOCK_CALLBACK *ltf_mutex_unlock;
LDAP_TF_GET_ERRNO_CALLBACK *ltf_get_errno;
LDAP_TF_SET_ERRNO_CALLBACK *ltf_set_errno;
LDAP_TF_GET_LDERRNO_CALLBACK *ltf_get_lderrno;
LDAP_TF_SET_LDERRNO_CALLBACK *ltf_set_lderrno;
void *ltf_lderrno_arg;
};
/*
* Extended I/O function callbacks option (an API extension --
* LDAP_API_FEATURE_X_EXTIO_FUNCTIONS).
*/
#define LDAP_X_OPT_EXTIO_FN_PTRS (LDAP_OPT_PRIVATE_EXTENSION_BASE + 0x0F00)
/* 0x4000 + 0x0F00 = 0x4F00 = 20224 - API extension */
/* Additional Extended I/O function callback option (for Extended Socket Arg callback) */
#define LDAP_X_OPT_SOCKETARG (LDAP_OPT_PRIVATE_EXTENSION_BASE + 0x0F02)
/* 0x4000 + 0x0F02 = 0x4F02 = 20226 - API extension */
/*
* These extended I/O function callbacks echo the BSD socket API but accept
* an extra pointer parameter at the end of their argument list that can
* be used by client applications for their own needs. For some of the calls,
* the pointer is a session argument of type struct lextiof_session_private *
* that is associated with the LDAP session handle (LDAP *). For others, the
* pointer is a socket specific struct lextiof_socket_private * argument that
* is associated with a particular socket (a TCP connection).
*
* The lextiof_session_private and lextiof_socket_private structures are not
* defined by the LDAP C API; users of this extended I/O interface should
* define these themselves.
*
* The combination of the integer socket number (i.e., lpoll_fd, which is
* the value returned by the CONNECT callback) and the application specific
* socket argument (i.e., lpoll_socketarg, which is the value set in *sockargpp
* by the CONNECT callback) must be unique.
*
* The types for the extended READ and WRITE callbacks are actually in lber.h.
*
* The CONNECT callback gets passed both the session argument (sessionarg)
* and a pointer to a socket argument (socketargp) so it has the
* opportunity to set the socket-specific argument. The CONNECT callback
* also takes a timeout parameter whose value can be set by calling
* ldap_set_option( ld, LDAP_X_OPT_..., &val ). The units used for the
* timeout parameter are milliseconds.
*
* A POLL interface is provided instead of a select() one. The timeout is
* in milliseconds.
*
* A NEWHANDLE callback function is also provided. It is called right
* after the LDAP session handle is created, e.g., during ldap_init().
* If the NEWHANDLE callback returns anything other than LDAP_SUCCESS,
* the session handle allocation fails.
*
* A DISPOSEHANDLE callback function is also provided. It is called right
* before the LDAP session handle and its contents are destroyed, e.g.,
* during ldap_unbind().
*/
/*
* Special timeout values for poll and connect:
*/
#define LDAP_X_IO_TIMEOUT_NO_WAIT 0 /* return immediately */
#define LDAP_X_IO_TIMEOUT_NO_TIMEOUT (-1) /* block indefinitely */
/* LDAP poll()-like descriptor:
*/
typedef struct ldap_x_pollfd { /* used by LDAP_X_EXTIOF_POLL_CALLBACK */
int lpoll_fd; /* integer file descriptor / socket */
struct lextiof_socket_private
*lpoll_socketarg;
/* pointer socket and for use by */
/* application */
short lpoll_events; /* requested event */
short lpoll_revents; /* returned event */
} LDAP_X_PollFD;
/* Event flags for lpoll_events and lpoll_revents:
*/
#define LDAP_X_POLLIN 0x01 /* regular data ready for reading */
#define LDAP_X_POLLPRI 0x02 /* high priority data available */
#define LDAP_X_POLLOUT 0x04 /* ready for writing */
#define LDAP_X_POLLERR 0x08 /* error occurred -- only in lpoll_revents */
#define LDAP_X_POLLHUP 0x10 /* connection closed -- only in lpoll_revents */
#define LDAP_X_POLLNVAL 0x20 /* invalid lpoll_fd -- only in lpoll_revents */
/* Options passed to LDAP_X_EXTIOF_CONNECT_CALLBACK to modify socket behavior:
*/
#define LDAP_X_EXTIOF_OPT_NONBLOCKING 0x01 /* turn on non-blocking mode */
#define LDAP_X_EXTIOF_OPT_SECURE 0x02 /* turn on 'secure' mode */
/* extended I/O callback function prototypes:
*/
typedef int (LDAP_C LDAP_CALLBACK LDAP_X_EXTIOF_CONNECT_CALLBACK )(
const char *hostlist, int port, /* host byte order */
int timeout /* milliseconds */,
unsigned long options, /* bitmapped options */
struct lextiof_session_private *sessionarg,
struct lextiof_socket_private **socketargp );
typedef int (LDAP_C LDAP_CALLBACK LDAP_X_EXTIOF_CLOSE_CALLBACK )(
int s, struct lextiof_socket_private *socketarg );
typedef int (LDAP_C LDAP_CALLBACK LDAP_X_EXTIOF_POLL_CALLBACK)(
LDAP_X_PollFD fds[], int nfds, int timeout /* milliseconds */,
struct lextiof_session_private *sessionarg );
typedef int (LDAP_C LDAP_CALLBACK LDAP_X_EXTIOF_NEWHANDLE_CALLBACK)(
LDAP *ld, struct lextiof_session_private *sessionarg );
typedef void (LDAP_C LDAP_CALLBACK LDAP_X_EXTIOF_DISPOSEHANDLE_CALLBACK)(
LDAP *ld, struct lextiof_session_private *sessionarg );
/* Structure to hold extended I/O function pointers:
*/
struct ldap_x_ext_io_fns {
/* lextiof_size should always be set to LDAP_X_EXTIO_FNS_SIZE */
int lextiof_size;
LDAP_X_EXTIOF_CONNECT_CALLBACK *lextiof_connect;
LDAP_X_EXTIOF_CLOSE_CALLBACK *lextiof_close;
LDAP_X_EXTIOF_READ_CALLBACK *lextiof_read;
LDAP_X_EXTIOF_WRITE_CALLBACK *lextiof_write;
LDAP_X_EXTIOF_POLL_CALLBACK *lextiof_poll;
LDAP_X_EXTIOF_NEWHANDLE_CALLBACK *lextiof_newhandle;
LDAP_X_EXTIOF_DISPOSEHANDLE_CALLBACK *lextiof_disposehandle;
void *lextiof_session_arg;
LDAP_X_EXTIOF_WRITEV_CALLBACK *lextiof_writev;
};
#define LDAP_X_EXTIO_FNS_SIZE sizeof(struct ldap_x_ext_io_fns)
/*
* Utility functions for parsing space-separated host lists (useful for
* implementing an extended I/O CONNECT callback function).
*/
struct ldap_x_hostlist_status;
LDAP_API(int) LDAP_CALL ldap_x_hostlist_first( const char *hostlist,
int defport, char **hostp, int *portp /* host byte order */,
struct ldap_x_hostlist_status **statusp );
LDAP_API(int) LDAP_CALL ldap_x_hostlist_next( char **hostp,
int *portp /* host byte order */, struct ldap_x_hostlist_status *status
);
LDAP_API(void) LDAP_CALL ldap_x_hostlist_statusfree(
struct ldap_x_hostlist_status *status );
/*
* Client side sorting of entries (an API extension --
* LDAP_API_FEATURE_X_CLIENT_SIDE_SORT)
*/
/*
* Client side sorting callback functions:
*/
typedef const struct berval* (LDAP_C LDAP_CALLBACK
LDAP_KEYGEN_CALLBACK)( void *arg, LDAP *ld, LDAPMessage *entry );
typedef int (LDAP_C LDAP_CALLBACK
LDAP_KEYCMP_CALLBACK)( void *arg, const struct berval*,
const struct berval* );
typedef void (LDAP_C LDAP_CALLBACK
LDAP_KEYFREE_CALLBACK)( void *arg, const struct berval* );
typedef int (LDAP_C LDAP_CALLBACK
LDAP_CMP_CALLBACK)(const char *val1, const char *val2);
typedef int (LDAP_C LDAP_CALLBACK
LDAP_VALCMP_CALLBACK)(const char **val1p, const char **val2p);
/*
* Client side sorting functions:
*/
LDAP_API(int) LDAP_CALL ldap_keysort_entries( LDAP *ld, LDAPMessage **chain,
void *arg, LDAP_KEYGEN_CALLBACK *gen, LDAP_KEYCMP_CALLBACK *cmp,
LDAP_KEYFREE_CALLBACK *fre );
LDAP_API(int) LDAP_CALL ldap_multisort_entries( LDAP *ld, LDAPMessage **chain,
char **attr, LDAP_CMP_CALLBACK *cmp );
LDAP_API(int) LDAP_CALL ldap_sort_entries( LDAP *ld, LDAPMessage **chain,
char *attr, LDAP_CMP_CALLBACK *cmp );
LDAP_API(int) LDAP_CALL ldap_sort_values( LDAP *ld, char **vals,
LDAP_VALCMP_CALLBACK *cmp );
LDAP_API(int) LDAP_C LDAP_CALLBACK ldap_sort_strcasecmp( const char **a,
const char **b );
/*
* Filter functions and definitions (an API extension --
* LDAP_API_FEATURE_X_FILTER_FUNCTIONS)
*/
/*
* Structures, constants, and types for filter utility routines:
*/
typedef struct ldap_filt_info {
char *lfi_filter;
char *lfi_desc;
int lfi_scope; /* LDAP_SCOPE_BASE, etc */
int lfi_isexact; /* exact match filter? */
struct ldap_filt_info *lfi_next;
} LDAPFiltInfo;
#define LDAP_FILT_MAXSIZ 1024
typedef struct ldap_filt_list LDAPFiltList; /* opaque filter list handle */
typedef struct ldap_filt_desc LDAPFiltDesc; /* opaque filter desc handle */
/*
* Filter utility functions:
*/
LDAP_API(LDAPFiltDesc *) LDAP_CALL ldap_init_getfilter( char *fname );
LDAP_API(LDAPFiltDesc *) LDAP_CALL ldap_init_getfilter_buf( char *buf,
long buflen );
LDAP_API(LDAPFiltInfo *) LDAP_CALL ldap_getfirstfilter( LDAPFiltDesc *lfdp,
char *tagpat, char *value );
LDAP_API(LDAPFiltInfo *) LDAP_CALL ldap_getnextfilter( LDAPFiltDesc *lfdp );
LDAP_API(int) LDAP_CALL ldap_set_filter_additions( LDAPFiltDesc *lfdp,
char *prefix, char *suffix );
LDAP_API(int) LDAP_CALL ldap_create_filter( char *buf, unsigned long buflen,
char *pattern, char *prefix, char *suffix, char *attr,
char *value, char **valwords );
LDAP_API(void) LDAP_CALL ldap_getfilter_free( LDAPFiltDesc *lfdp );
/*
* Friendly mapping structure and routines (an API extension)
*/
typedef struct friendly {
char *f_unfriendly;
char *f_friendly;
} *FriendlyMap;
LDAP_API(char *) LDAP_CALL ldap_friendly_name( char *filename, char *name,
FriendlyMap *map );
LDAP_API(void) LDAP_CALL ldap_free_friendlymap( FriendlyMap *map );
/*
* In Memory Cache (an API extension -- LDAP_API_FEATURE_X_MEMCACHE)
*/
typedef struct ldapmemcache LDAPMemCache; /* opaque in-memory cache handle */
LDAP_API(int) LDAP_CALL ldap_memcache_init( unsigned long ttl,
unsigned long size, char **baseDNs, struct ldap_thread_fns *thread_fns,
LDAPMemCache **cachep );
LDAP_API(int) LDAP_CALL ldap_memcache_set( LDAP *ld, LDAPMemCache *cache );
LDAP_API(int) LDAP_CALL ldap_memcache_get( LDAP *ld, LDAPMemCache **cachep );
LDAP_API(void) LDAP_CALL ldap_memcache_flush( LDAPMemCache *cache, char *dn,
int scope );
LDAP_API(void) LDAP_CALL ldap_memcache_flush_results( LDAPMemCache *cache,
char *dn, int scope );
LDAP_API(void) LDAP_CALL ldap_memcache_destroy( LDAPMemCache *cache );
LDAP_API(void) LDAP_CALL ldap_memcache_update( LDAPMemCache *cache );
/*
* Timeout value for nonblocking connect call
*/
#define LDAP_X_OPT_CONNECT_TIMEOUT (LDAP_OPT_PRIVATE_EXTENSION_BASE + 0x0F01)
/* 0x4000 + 0x0F01 = 0x4F01 = 20225 - API extension */
/*
* Socket buffer structure associated to the LDAP connection
*/
#define LDAP_X_OPT_SOCKBUF (LDAP_OPT_PRIVATE_EXTENSION_BASE + 0x0F03)
/* 0x4000 + 0x0F03 = 0x4F03 = 20227 - API extension */
/*
* Memory allocation callback functions (an API extension --
* LDAP_API_FEATURE_X_MEMALLOC_FUNCTIONS). These are global and can
* not be set on a per-LDAP session handle basis. Install your own
* functions by making a call like this:
* ldap_set_option( NULL, LDAP_OPT_MEMALLOC_FN_PTRS, &memalloc_fns );
*
* look in lber.h for the function typedefs themselves.
*/
#define LDAP_OPT_MEMALLOC_FN_PTRS 0x61 /* 97 - API extension */
struct ldap_memalloc_fns {
LDAP_MALLOC_CALLBACK *ldapmem_malloc;
LDAP_CALLOC_CALLBACK *ldapmem_calloc;
LDAP_REALLOC_CALLBACK *ldapmem_realloc;
LDAP_FREE_CALLBACK *ldapmem_free;
};
/*
* Memory allocation functions (an API extension)
*/
void *ldap_x_malloc( size_t size );
void *ldap_x_calloc( size_t nelem, size_t elsize );
void *ldap_x_realloc( void *ptr, size_t size );
void ldap_x_free( void *ptr );
/*
* Server reconnect (an API extension).
*/
#define LDAP_OPT_RECONNECT 0x62 /* 98 - API extension */
/*
* Extra thread callback functions (an API extension --
* LDAP_API_FEATURE_X_EXTHREAD_FUNCTIONS)
*/
#define LDAP_OPT_EXTRA_THREAD_FN_PTRS 0x65 /* 101 - API extension */
/*
* When bind is called, don't bind if there's a connection open with the same DN
*/
#define LDAP_OPT_NOREBIND 0x66 /* 102 - API extension */
typedef int (LDAP_C LDAP_CALLBACK LDAP_TF_MUTEX_TRYLOCK_CALLBACK)( void *m );
typedef void *(LDAP_C LDAP_CALLBACK LDAP_TF_SEMA_ALLOC_CALLBACK)( void );
typedef void (LDAP_C LDAP_CALLBACK LDAP_TF_SEMA_FREE_CALLBACK)( void *s );
typedef int (LDAP_C LDAP_CALLBACK LDAP_TF_SEMA_WAIT_CALLBACK)( void *s );
typedef int (LDAP_C LDAP_CALLBACK LDAP_TF_SEMA_POST_CALLBACK)( void *s );
typedef void *(LDAP_C LDAP_CALLBACK LDAP_TF_THREADID_CALLBACK)(void);
struct ldap_extra_thread_fns {
LDAP_TF_MUTEX_TRYLOCK_CALLBACK *ltf_mutex_trylock;
LDAP_TF_SEMA_ALLOC_CALLBACK *ltf_sema_alloc;
LDAP_TF_SEMA_FREE_CALLBACK *ltf_sema_free;
LDAP_TF_SEMA_WAIT_CALLBACK *ltf_sema_wait;
LDAP_TF_SEMA_POST_CALLBACK *ltf_sema_post;
LDAP_TF_THREADID_CALLBACK *ltf_threadid_fn;
};
/*
* Debugging level (an API extension)
*/
#define LDAP_OPT_DEBUG_LEVEL 0x6E /* 110 - API extension */
/* On UNIX, there's only one copy of ldap_debug */
/* On NT, each dll keeps its own module_ldap_debug, which */
/* points to the process' ldap_debug and needs initializing after load */
#ifdef _WIN32
extern int *module_ldap_debug;
typedef void (*set_debug_level_fn_t)(int*);
#endif
#ifdef LDAP_DNS
#define LDAP_OPT_DNS 0x0C /* 12 - API extension */
#endif
/*
* UTF-8 routines (should these move into libnls?)
*/
/* number of bytes in character */
LDAP_API(int) LDAP_CALL ldap_utf8len( const char* );
/* find next character */
LDAP_API(char*) LDAP_CALL ldap_utf8next( char* );
/* find previous character */
LDAP_API(char*) LDAP_CALL ldap_utf8prev( char* );
/* copy one character */
LDAP_API(int) LDAP_CALL ldap_utf8copy( char* dst, const char* src );
/* total number of characters */
LDAP_API(size_t) LDAP_CALL ldap_utf8characters( const char* );
/* get one UCS-4 character, and move *src to the next character */
LDAP_API(unsigned long) LDAP_CALL ldap_utf8getcc( const char** src );
/* UTF-8 aware strtok_r() */
LDAP_API(char*) LDAP_CALL ldap_utf8strtok_r( char* src, const char* brk, char**
next);
/* like isalnum(*s) in the C locale */
LDAP_API(int) LDAP_CALL ldap_utf8isalnum( char* s );
/* like isalpha(*s) in the C locale */
LDAP_API(int) LDAP_CALL ldap_utf8isalpha( char* s );
/* like isdigit(*s) in the C locale */
LDAP_API(int) LDAP_CALL ldap_utf8isdigit( char* s );
/* like isxdigit(*s) in the C locale */
LDAP_API(int) LDAP_CALL ldap_utf8isxdigit(char* s );
/* like isspace(*s) in the C locale */
LDAP_API(int) LDAP_CALL ldap_utf8isspace( char* s );
#define LDAP_UTF8LEN(s) ((0x80 & *(unsigned char*)(s)) ? ldap_utf8len (s) : 1)
#define LDAP_UTF8NEXT(s) ((0x80 & *(unsigned char*)(s)) ? ldap_utf8next(s) : ( s)+1)
#define LDAP_UTF8INC(s) ((0x80 & *(unsigned char*)(s)) ? s=ldap_utf8next(s) : ++s)
#define LDAP_UTF8PREV(s) ldap_utf8prev(s)
#define LDAP_UTF8DEC(s) (s=ldap_utf8prev(s))
#define LDAP_UTF8COPY(d,s) ((0x80 & *(unsigned char*)(s)) ? ldap_utf8copy(d,s) : ((*(d) = *(s)), 1))
#define LDAP_UTF8GETCC(s) ((0x80 & *(unsigned char*)(s)) ? ldap_utf8getcc (&s) : *s++)
#define LDAP_UTF8GETC(s) ((0x80 & *(unsigned char*)(s)) ? ldap_utf8getcc ((const char**)&s) : *s++)
/* SASL options */
#define LDAP_OPT_X_SASL_MECH 0x6100
#define LDAP_OPT_X_SASL_REALM 0x6101
#define LDAP_OPT_X_SASL_AUTHCID 0x6102
#define LDAP_OPT_X_SASL_AUTHZID 0x6103
#define LDAP_OPT_X_SASL_SSF 0x6104 /* read-only */
#define LDAP_OPT_X_SASL_SSF_EXTERNAL 0x6105 /* write-only */
#define LDAP_OPT_X_SASL_SECPROPS 0x6106 /* write-only */
#define LDAP_OPT_X_SASL_SSF_MIN 0x6107
#define LDAP_OPT_X_SASL_SSF_MAX 0x6108
#define LDAP_OPT_X_SASL_MAXBUFSIZE 0x6109
/* ldap_interactive_bind_s Interaction flags
* Interactive: prompt always - REQUIRED
*/
#define LDAP_SASL_AUTOMATIC 0U /* only prompt for missing items not supplied as defaults */
#define LDAP_SASL_INTERACTIVE 1U /* prompt for everything and print defaults, if any */
#define LDAP_SASL_QUIET 2U /* no prompts - only use defaults (e.g. for non-interactive apps) */
/*
* V3 SASL Interaction Function Callback Prototype
* when using Cyrus SASL, interact is pointer to sasl_interact_t
* should likely passed in a control (and provided controls)
*/
typedef int (LDAP_SASL_INTERACT_PROC)
(LDAP *ld, unsigned flags, void* defaults, void *interact );
LDAP_API(int) LDAP_CALL ldap_sasl_interactive_bind_s (
LDAP *ld,
const char *dn, /* usually NULL */
const char *saslMechanism,
LDAPControl **serverControls,
LDAPControl **clientControls,
/* should be client controls */
unsigned flags,
LDAP_SASL_INTERACT_PROC *proc,
void *defaults );
LDAP_API(int) LDAP_CALL ldap_sasl_interactive_bind_ext_s (
LDAP *ld,
const char *dn, /* usually NULL */
const char *saslMechanism,
LDAPControl **serverControls,
LDAPControl **clientControls,
/* should be client controls */
unsigned flags,
LDAP_SASL_INTERACT_PROC *proc,
void *defaults,
LDAPControl ***responseControls );
/*
* Password modify functions
*/
LDAP_API(int) LDAP_CALL ldap_passwd( LDAP *ld, struct berval *userid,
struct berval *oldpasswd, struct berval *newpasswd,
LDAPControl **serverctrls, LDAPControl **clientctrls,
int *msgidp );
LDAP_API(int) LDAP_CALL ldap_passwd_s( LDAP *ld, struct berval *userid,
struct berval *oldpasswd, struct berval *newpasswd,
struct berval *genpasswd, LDAPControl **serverctrls,
LDAPControl **clientctrls );
LDAP_API(int) LDAP_CALL ldap_parse_passwd( LDAP *ld, LDAPMessage *result,
struct berval *genpasswd );
/*
* in reslist.c
*/
LDAP_API(LDAPMessage *) LDAP_CALL ldap_delete_result_entry( LDAPMessage **list, LDAPMessage *e );
LDAP_API(void) LDAP_CALL ldap_add_result_entry( LDAPMessage **list, LDAPMessage *e );
#ifdef __cplusplus
}
#endif
#endif /* _LDAP_EXTENSION_H */

View file

@ -0,0 +1,91 @@
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is Mozilla Communicator client code, released
* March 31, 1998.
*
* The Initial Developer of the Original Code is
* Netscape Communications Corporation.
* Portions created by the Initial Developer are Copyright (C) 1998-1999
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
*
* Alternatively, the contents of this file may be used under the terms of
* either of the GNU General Public License Version 2 or later (the "GPL"),
* or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
/* ldap-platform.h - platform transparency */
#ifndef _LDAP_PLATFORM_H
#define _LDAP_PLATFORM_H
#ifdef __cplusplus
extern "C" {
#endif
#if defined (WIN32) || defined (_WIN32) || defined( _CONSOLE )
#include <windows.h>
# if defined( _WINDOWS )
# include <winsock.h>
# endif
#elif defined(macintosh)
#ifndef LDAP_TYPE_TIMEVAL_DEFINED
#include <utime.h>
#endif
#ifndef LDAP_TYPE_SOCKET_DEFINED /* API extension */
#include "macsocket.h"
#endif
#else /* everything else, e.g., Unix */
#ifndef LDAP_TYPE_TIMEVAL_DEFINED
#include <sys/time.h>
#endif
#ifndef LDAP_TYPE_SOCKET_DEFINED /* API extension */
#include <sys/types.h>
#include <sys/socket.h>
#endif
#endif
#ifdef _AIX
#include <sys/select.h>
#endif /* _AIX */
#ifdef XP_OS2
#include <sys/select.h>
#endif /* XP_OS2 */
/*
* LDAP_API macro definition:
*/
#ifndef LDAP_API
#if defined( _WINDOWS ) || defined( _WIN32 )
#define LDAP_API(rt) rt
#else /* _WINDOWS */
#define LDAP_API(rt) rt
#endif /* _WINDOWS */
#endif /* LDAP_API */
#ifdef __cplusplus
}
#endif
#endif /* _LDAP_PLATFORM_H */

View file

@ -0,0 +1,457 @@
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is Mozilla Communicator client code, released
* March 31, 1998.
*
* The Initial Developer of the Original Code is
* Netscape Communications Corporation.
* Portions created by the Initial Developer are Copyright (C) 1998-1999
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
*
* Alternatively, the contents of this file may be used under the terms of
* either of the GNU General Public License Version 2 or later (the "GPL"),
* or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
/* ldap-standard.h - standards base header file for libldap */
/* This file contain the defines and function prototypes matching */
/* very closely to the latest LDAP C API draft */
#ifndef _LDAP_STANDARD_H
#define _LDAP_STANDARD_H
#ifdef __cplusplus
extern "C" {
#endif
#include "ldap-platform.h"
#include "lber.h"
#define LDAP_PORT 389
#define LDAPS_PORT 636
#define LDAP_VERSION2 2
#define LDAP_VERSION3 3
#define LDAP_VERSION_MIN LDAP_VERSION1
#define LDAP_VERSION_MAX LDAP_VERSION3
#define LDAP_VENDOR_VERSION 607 /* version # * 100 */
#define LDAP_VENDOR_NAME "mozilla.org"
/*
* The following will be an RFC number once the LDAP C API Internet Draft
* is published as a Proposed Standard RFC. For now we use 2000 + the
* draft revision number (currently 5) since we are close to compliance
* with revision 5 of the draft.
*/
#define LDAP_API_VERSION 2005
/* special values that may appear in the attributes field of a SearchRequest.
*/
#define LDAP_NO_ATTRS "1.1"
#define LDAP_ALL_USER_ATTRS "*"
/*
* Standard options (used with ldap_set_option() and ldap_get_option):
*/
#define LDAP_OPT_API_INFO 0x00 /* 0 */
#define LDAP_OPT_DEREF 0x02 /* 2 */
#define LDAP_OPT_SIZELIMIT 0x03 /* 3 */
#define LDAP_OPT_TIMELIMIT 0x04 /* 4 */
#define LDAP_OPT_REFERRALS 0x08 /* 8 */
#define LDAP_OPT_RESTART 0x09 /* 9 */
#define LDAP_OPT_PROTOCOL_VERSION 0x11 /* 17 */
#define LDAP_OPT_SERVER_CONTROLS 0x12 /* 18 */
#define LDAP_OPT_CLIENT_CONTROLS 0x13 /* 19 */
#define LDAP_OPT_API_FEATURE_INFO 0x15 /* 21 */
#define LDAP_OPT_HOST_NAME 0x30 /* 48 */
#define LDAP_OPT_ERROR_NUMBER 0x31 /* 49 */
#define LDAP_OPT_ERROR_STRING 0x32 /* 50 */
#define LDAP_OPT_MATCHED_DN 0x33 /* 51 */
/*
* Well-behaved private and experimental extensions will use option values
* between 0x4000 (16384) and 0x7FFF (32767) inclusive.
*/
#define LDAP_OPT_PRIVATE_EXTENSION_BASE 0x4000 /* to 0x7FFF inclusive */
/* for on/off options */
#define LDAP_OPT_ON ((void *)1)
#define LDAP_OPT_OFF ((void *)0)
typedef struct ldap LDAP; /* opaque connection handle */
typedef struct ldapmsg LDAPMessage; /* opaque result/entry handle */
/* structure representing an LDAP modification */
typedef struct ldapmod {
int mod_op; /* kind of mod + form of values*/
#define LDAP_MOD_ADD 0x00
#define LDAP_MOD_DELETE 0x01
#define LDAP_MOD_REPLACE 0x02
#define LDAP_MOD_BVALUES 0x80
char *mod_type; /* attribute name to modify */
union mod_vals_u {
char **modv_strvals;
struct berval **modv_bvals;
} mod_vals; /* values to add/delete/replace */
#define mod_values mod_vals.modv_strvals
#define mod_bvalues mod_vals.modv_bvals
} LDAPMod;
/*
* structure for holding ldapv3 controls
*/
typedef struct ldapcontrol {
char *ldctl_oid;
struct berval ldctl_value;
char ldctl_iscritical;
} LDAPControl;
/*
* LDAP API information. Can be retrieved by using a sequence like:
*
* LDAPAPIInfo ldai;
* ldai.ldapai_info_version = LDAP_API_INFO_VERSION;
* if ( ldap_get_option( NULL, LDAP_OPT_API_INFO, &ldia ) == 0 ) ...
*/
#define LDAP_API_INFO_VERSION 1
typedef struct ldapapiinfo {
int ldapai_info_version; /* version of this struct (1) */
int ldapai_api_version; /* revision of API supported */
int ldapai_protocol_version; /* highest LDAP version supported */
char **ldapai_extensions; /* names of API extensions */
char *ldapai_vendor_name; /* name of supplier */
int ldapai_vendor_version; /* supplier-specific version times 100 */
} LDAPAPIInfo;
/*
* LDAP API extended features info. Can be retrieved by using a sequence like:
*
* LDAPAPIFeatureInfo ldfi;
* ldfi.ldapaif_info_version = LDAP_FEATURE_INFO_VERSION;
* ldfi.ldapaif_name = "VIRTUAL_LIST_VIEW";
* if ( ldap_get_option( NULL, LDAP_OPT_API_FEATURE_INFO, &ldfi ) == 0 ) ...
*/
#define LDAP_FEATURE_INFO_VERSION 1
typedef struct ldap_apifeature_info {
int ldapaif_info_version; /* version of this struct (1) */
char *ldapaif_name; /* name of supported feature */
int ldapaif_version; /* revision of supported feature */
} LDAPAPIFeatureInfo;
/* possible result types a server can return */
#define LDAP_RES_BIND 0x61L /* 97 */
#define LDAP_RES_SEARCH_ENTRY 0x64L /* 100 */
#define LDAP_RES_SEARCH_RESULT 0x65L /* 101 */
#define LDAP_RES_MODIFY 0x67L /* 103 */
#define LDAP_RES_ADD 0x69L /* 105 */
#define LDAP_RES_DELETE 0x6BL /* 107 */
#define LDAP_RES_MODDN 0x6DL /* 109 */
#define LDAP_RES_COMPARE 0x6FL /* 111 */
#define LDAP_RES_SEARCH_REFERENCE 0x73L /* 115 */
#define LDAP_RES_EXTENDED 0x78L /* 120 */
/* Special values for ldap_result() "msgid" parameter */
#define LDAP_RES_ANY (-1)
#define LDAP_RES_UNSOLICITED 0
/* built-in SASL methods */
#define LDAP_SASL_SIMPLE 0 /* special value used for simple bind */
/* search scopes */
#define LDAP_SCOPE_BASE 0x00
#define LDAP_SCOPE_ONELEVEL 0x01
#define LDAP_SCOPE_SUBTREE 0x02
/* alias dereferencing */
#define LDAP_DEREF_NEVER 0x00
#define LDAP_DEREF_SEARCHING 0x01
#define LDAP_DEREF_FINDING 0x02
#define LDAP_DEREF_ALWAYS 0x03
/* predefined size/time limits */
#define LDAP_NO_LIMIT 0
/* allowed values for "all" ldap_result() parameter */
#define LDAP_MSG_ONE 0x00
#define LDAP_MSG_ALL 0x01
#define LDAP_MSG_RECEIVED 0x02
/* possible error codes we can be returned */
#define LDAP_SUCCESS 0x00 /* 0 */
#define LDAP_OPERATIONS_ERROR 0x01 /* 1 */
#define LDAP_PROTOCOL_ERROR 0x02 /* 2 */
#define LDAP_TIMELIMIT_EXCEEDED 0x03 /* 3 */
#define LDAP_SIZELIMIT_EXCEEDED 0x04 /* 4 */
#define LDAP_COMPARE_FALSE 0x05 /* 5 */
#define LDAP_COMPARE_TRUE 0x06 /* 6 */
#define LDAP_STRONG_AUTH_NOT_SUPPORTED 0x07 /* 7 */
#define LDAP_STRONG_AUTH_REQUIRED 0x08 /* 8 */
#define LDAP_REFERRAL 0x0a /* 10 - LDAPv3 */
#define LDAP_ADMINLIMIT_EXCEEDED 0x0b /* 11 - LDAPv3 */
#define LDAP_UNAVAILABLE_CRITICAL_EXTENSION 0x0c /* 12 - LDAPv3 */
#define LDAP_CONFIDENTIALITY_REQUIRED 0x0d /* 13 */
#define LDAP_SASL_BIND_IN_PROGRESS 0x0e /* 14 - LDAPv3 */
#define LDAP_NO_SUCH_ATTRIBUTE 0x10 /* 16 */
#define LDAP_UNDEFINED_TYPE 0x11 /* 17 */
#define LDAP_INAPPROPRIATE_MATCHING 0x12 /* 18 */
#define LDAP_CONSTRAINT_VIOLATION 0x13 /* 19 */
#define LDAP_TYPE_OR_VALUE_EXISTS 0x14 /* 20 */
#define LDAP_INVALID_SYNTAX 0x15 /* 21 */
#define LDAP_NO_SUCH_OBJECT 0x20 /* 32 */
#define LDAP_ALIAS_PROBLEM 0x21 /* 33 */
#define LDAP_INVALID_DN_SYNTAX 0x22 /* 34 */
#define LDAP_IS_LEAF 0x23 /* 35 (not used in LDAPv3) */
#define LDAP_ALIAS_DEREF_PROBLEM 0x24 /* 36 */
#define LDAP_INAPPROPRIATE_AUTH 0x30 /* 48 */
#define LDAP_INVALID_CREDENTIALS 0x31 /* 49 */
#define LDAP_INSUFFICIENT_ACCESS 0x32 /* 50 */
#define LDAP_BUSY 0x33 /* 51 */
#define LDAP_UNAVAILABLE 0x34 /* 52 */
#define LDAP_UNWILLING_TO_PERFORM 0x35 /* 53 */
#define LDAP_LOOP_DETECT 0x36 /* 54 */
#define LDAP_NAMING_VIOLATION 0x40 /* 64 */
#define LDAP_OBJECT_CLASS_VIOLATION 0x41 /* 65 */
#define LDAP_NOT_ALLOWED_ON_NONLEAF 0x42 /* 66 */
#define LDAP_NOT_ALLOWED_ON_RDN 0x43 /* 67 */
#define LDAP_ALREADY_EXISTS 0x44 /* 68 */
#define LDAP_NO_OBJECT_CLASS_MODS 0x45 /* 69 */
#define LDAP_RESULTS_TOO_LARGE 0x46 /* 70 - CLDAP */
#define LDAP_AFFECTS_MULTIPLE_DSAS 0x47 /* 71 */
#define LDAP_OTHER 0x50 /* 80 */
#define LDAP_SERVER_DOWN 0x51 /* 81 */
#define LDAP_LOCAL_ERROR 0x52 /* 82 */
#define LDAP_ENCODING_ERROR 0x53 /* 83 */
#define LDAP_DECODING_ERROR 0x54 /* 84 */
#define LDAP_TIMEOUT 0x55 /* 85 */
#define LDAP_AUTH_UNKNOWN 0x56 /* 86 */
#define LDAP_FILTER_ERROR 0x57 /* 87 */
#define LDAP_USER_CANCELLED 0x58 /* 88 */
#define LDAP_PARAM_ERROR 0x59 /* 89 */
#define LDAP_NO_MEMORY 0x5a /* 90 */
#define LDAP_CONNECT_ERROR 0x5b /* 91 */
#define LDAP_NOT_SUPPORTED 0x5c /* 92 - LDAPv3 */
#define LDAP_CONTROL_NOT_FOUND 0x5d /* 93 - LDAPv3 */
#define LDAP_NO_RESULTS_RETURNED 0x5e /* 94 - LDAPv3 */
#define LDAP_MORE_RESULTS_TO_RETURN 0x5f /* 95 - LDAPv3 */
#define LDAP_CLIENT_LOOP 0x60 /* 96 - LDAPv3 */
#define LDAP_REFERRAL_LIMIT_EXCEEDED 0x61 /* 97 - LDAPv3 */
/*
* LDAPv3 unsolicited notification messages we know about
*/
#define LDAP_NOTICE_OF_DISCONNECTION "1.3.6.1.4.1.1466.20036"
/*
* Client controls we know about
*/
#define LDAP_CONTROL_REFERRALS "1.2.840.113556.1.4.616"
/*
* Initializing an ldap sesssion, set session handle options, and
* closing an ldap session functions
*
* NOTE: If you want to use IPv6, you must use prldap creating a LDAP handle
* with prldap_init instead of ldap_init. Or install the NSPR functions
* by calling prldap_install_routines. (See the nspr samples in examples)
*/
LDAP_API(LDAP *) LDAP_CALL ldap_init( const char *defhost, int defport );
LDAP_API(int) LDAP_CALL ldap_set_option( LDAP *ld, int option,
const void *optdata );
LDAP_API(int) LDAP_CALL ldap_get_option( LDAP *ld, int option, void *optdata );
LDAP_API(int) LDAP_CALL ldap_unbind( LDAP *ld );
LDAP_API(int) LDAP_CALL ldap_unbind_s( LDAP *ld );
/*
* perform ldap operations
*/
LDAP_API(int) LDAP_CALL ldap_abandon( LDAP *ld, int msgid );
LDAP_API(int) LDAP_CALL ldap_add( LDAP *ld, const char *dn, LDAPMod **attrs );
LDAP_API(int) LDAP_CALL ldap_add_s( LDAP *ld, const char *dn, LDAPMod **attrs );
LDAP_API(int) LDAP_CALL ldap_simple_bind( LDAP *ld, const char *who,
const char *passwd );
LDAP_API(int) LDAP_CALL ldap_simple_bind_s( LDAP *ld, const char *who,
const char *passwd );
LDAP_API(int) LDAP_CALL ldap_modify( LDAP *ld, const char *dn, LDAPMod **mods );
LDAP_API(int) LDAP_CALL ldap_modify_s( LDAP *ld, const char *dn,
LDAPMod **mods );
LDAP_API(int) LDAP_CALL ldap_compare( LDAP *ld, const char *dn,
const char *attr, const char *value );
LDAP_API(int) LDAP_CALL ldap_compare_s( LDAP *ld, const char *dn,
const char *attr, const char *value );
LDAP_API(int) LDAP_CALL ldap_delete( LDAP *ld, const char *dn );
LDAP_API(int) LDAP_CALL ldap_delete_s( LDAP *ld, const char *dn );
LDAP_API(int) LDAP_CALL ldap_search( LDAP *ld, const char *base, int scope,
const char *filter, char **attrs, int attrsonly );
LDAP_API(int) LDAP_CALL ldap_search_s( LDAP *ld, const char *base, int scope,
const char *filter, char **attrs, int attrsonly, LDAPMessage **res );
LDAP_API(int) LDAP_CALL ldap_search_st( LDAP *ld, const char *base, int scope,
const char *filter, char **attrs, int attrsonly,
struct timeval *timeout, LDAPMessage **res );
/*
* obtain result from ldap operation
*/
LDAP_API(int) LDAP_CALL ldap_result( LDAP *ld, int msgid, int all,
struct timeval *timeout, LDAPMessage **result );
/*
* peeking inside LDAP Messages and deallocating LDAP Messages
*/
LDAP_API(int) LDAP_CALL ldap_msgfree( LDAPMessage *lm );
LDAP_API(int) LDAP_CALL ldap_msgid( LDAPMessage *lm );
LDAP_API(int) LDAP_CALL ldap_msgtype( LDAPMessage *lm );
/*
* Routines to parse/deal with results and errors returned
*/
LDAP_API(char *) LDAP_CALL ldap_err2string( int err );
LDAP_API(LDAPMessage *) LDAP_CALL ldap_first_entry( LDAP *ld,
LDAPMessage *chain );
LDAP_API(LDAPMessage *) LDAP_CALL ldap_next_entry( LDAP *ld,
LDAPMessage *entry );
LDAP_API(int) LDAP_CALL ldap_count_entries( LDAP *ld, LDAPMessage *chain );
LDAP_API(char *) LDAP_CALL ldap_get_dn( LDAP *ld, LDAPMessage *entry );
LDAP_API(char *) LDAP_CALL ldap_dn2ufn( const char *dn );
LDAP_API(char **) LDAP_CALL ldap_explode_dn( const char *dn,
const int notypes );
LDAP_API(char **) LDAP_CALL ldap_explode_rdn( const char *rdn,
const int notypes );
LDAP_API(char *) LDAP_CALL ldap_first_attribute( LDAP *ld, LDAPMessage *entry,
BerElement **ber );
LDAP_API(char *) LDAP_CALL ldap_next_attribute( LDAP *ld, LDAPMessage *entry,
BerElement *ber );
LDAP_API(char **) LDAP_CALL ldap_get_values( LDAP *ld, LDAPMessage *entry,
const char *target );
LDAP_API(struct berval **) LDAP_CALL ldap_get_values_len( LDAP *ld,
LDAPMessage *entry, const char *target );
LDAP_API(int) LDAP_CALL ldap_count_values( char **vals );
LDAP_API(int) LDAP_CALL ldap_count_values_len( struct berval **vals );
LDAP_API(void) LDAP_CALL ldap_value_free( char **vals );
LDAP_API(void) LDAP_CALL ldap_value_free_len( struct berval **vals );
LDAP_API(void) LDAP_CALL ldap_memfree( void *p );
/*
* LDAPv3 extended operation calls
*/
/*
* Note: all of the new asynchronous calls return an LDAP error code,
* not a message id. A message id is returned via the int *msgidp
* parameter (usually the last parameter) if appropriate.
*/
LDAP_API(int) LDAP_CALL ldap_abandon_ext( LDAP *ld, int msgid,
LDAPControl **serverctrls, LDAPControl **clientctrls );
LDAP_API(int) LDAP_CALL ldap_add_ext( LDAP *ld, const char *dn, LDAPMod **attrs,
LDAPControl **serverctrls, LDAPControl **clientctrls, int *msgidp );
LDAP_API(int) LDAP_CALL ldap_add_ext_s( LDAP *ld, const char *dn,
LDAPMod **attrs, LDAPControl **serverctrls, LDAPControl **clientctrls );
LDAP_API(int) LDAP_CALL ldap_sasl_bind( LDAP *ld, const char *dn,
const char *mechanism, const struct berval *cred,
LDAPControl **serverctrls, LDAPControl **clientctrls, int *msgidp );
LDAP_API(int) LDAP_CALL ldap_sasl_bind_s( LDAP *ld, const char *dn,
const char *mechanism, const struct berval *cred,
LDAPControl **serverctrls, LDAPControl **clientctrls,
struct berval **servercredp );
LDAP_API(int) LDAP_CALL ldap_modify_ext( LDAP *ld, const char *dn,
LDAPMod **mods, LDAPControl **serverctrls, LDAPControl **clientctrls,
int *msgidp );
LDAP_API(int) LDAP_CALL ldap_modify_ext_s( LDAP *ld, const char *dn,
LDAPMod **mods, LDAPControl **serverctrls, LDAPControl **clientctrls );
LDAP_API(int) LDAP_CALL ldap_rename( LDAP *ld, const char *dn,
const char *newrdn, const char *newparent, int deleteoldrdn,
LDAPControl **serverctrls, LDAPControl **clientctrls, int *msgidp );
LDAP_API(int) LDAP_CALL ldap_rename_s( LDAP *ld, const char *dn,
const char *newrdn, const char *newparent, int deleteoldrdn,
LDAPControl **serverctrls, LDAPControl **clientctrls );
LDAP_API(int) LDAP_CALL ldap_compare_ext( LDAP *ld, const char *dn,
const char *attr, const struct berval *bvalue,
LDAPControl **serverctrls, LDAPControl **clientctrls, int *msgidp );
LDAP_API(int) LDAP_CALL ldap_compare_ext_s( LDAP *ld, const char *dn,
const char *attr, const struct berval *bvalue,
LDAPControl **serverctrls, LDAPControl **clientctrls );
LDAP_API(int) LDAP_CALL ldap_delete_ext( LDAP *ld, const char *dn,
LDAPControl **serverctrls, LDAPControl **clientctrls, int *msgidp );
LDAP_API(int) LDAP_CALL ldap_delete_ext_s( LDAP *ld, const char *dn,
LDAPControl **serverctrls, LDAPControl **clientctrls );
LDAP_API(int) LDAP_CALL ldap_search_ext( LDAP *ld, const char *base,
int scope, const char *filter, char **attrs, int attrsonly,
LDAPControl **serverctrls, LDAPControl **clientctrls,
struct timeval *timeoutp, int sizelimit, int *msgidp );
LDAP_API(int) LDAP_CALL ldap_search_ext_s( LDAP *ld, const char *base,
int scope, const char *filter, char **attrs, int attrsonly,
LDAPControl **serverctrls, LDAPControl **clientctrls,
struct timeval *timeoutp, int sizelimit, LDAPMessage **res );
LDAP_API(int) LDAP_CALL ldap_extended_operation( LDAP *ld,
const char *requestoid, const struct berval *requestdata,
LDAPControl **serverctrls, LDAPControl **clientctrls, int *msgidp );
LDAP_API(int) LDAP_CALL ldap_extended_operation_s( LDAP *ld,
const char *requestoid, const struct berval *requestdata,
LDAPControl **serverctrls, LDAPControl **clientctrls,
char **retoidp, struct berval **retdatap );
LDAP_API(int) LDAP_CALL ldap_unbind_ext( LDAP *ld, LDAPControl **serverctrls,
LDAPControl **clientctrls );
/*
* LDAPv3 extended parsing / result handling calls
*/
LDAP_API(int) LDAP_CALL ldap_parse_sasl_bind_result( LDAP *ld,
LDAPMessage *res, struct berval **servercredp, int freeit );
LDAP_API(int) LDAP_CALL ldap_parse_result( LDAP *ld, LDAPMessage *res,
int *errcodep, char **matcheddnp, char **errmsgp, char ***referralsp,
LDAPControl ***serverctrlsp, int freeit );
LDAP_API(int) LDAP_CALL ldap_parse_extended_result( LDAP *ld, LDAPMessage *res,
char **retoidp, struct berval **retdatap, int freeit );
LDAP_API(LDAPMessage *) LDAP_CALL ldap_first_message( LDAP *ld,
LDAPMessage *res );
LDAP_API(LDAPMessage *) LDAP_CALL ldap_next_message( LDAP *ld,
LDAPMessage *msg );
LDAP_API(int) LDAP_CALL ldap_count_messages( LDAP *ld, LDAPMessage *res );
LDAP_API(LDAPMessage *) LDAP_CALL ldap_first_reference( LDAP *ld,
LDAPMessage *res );
LDAP_API(LDAPMessage *) LDAP_CALL ldap_next_reference( LDAP *ld,
LDAPMessage *ref );
LDAP_API(int) LDAP_CALL ldap_count_references( LDAP *ld, LDAPMessage *res );
LDAP_API(int) LDAP_CALL ldap_parse_reference( LDAP *ld, LDAPMessage *ref,
char ***referralsp, LDAPControl ***serverctrlsp, int freeit );
LDAP_API(int) LDAP_CALL ldap_get_entry_controls( LDAP *ld, LDAPMessage *entry,
LDAPControl ***serverctrlsp );
LDAP_API(void) LDAP_CALL ldap_control_free( LDAPControl *ctrl );
LDAP_API(void) LDAP_CALL ldap_controls_free( LDAPControl **ctrls );
#ifdef __cplusplus
}
#endif
#endif /* _LDAP_STANDARD_H */

View file

@ -0,0 +1,193 @@
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is Mozilla Communicator client code, released
* March 31, 1998.
*
* The Initial Developer of the Original Code is
* Netscape Communications Corporation.
* Portions created by the Initial Developer are Copyright (C) 1998-1999
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
*
* Alternatively, the contents of this file may be used under the terms of
* either of the GNU General Public License Version 2 or later (the "GPL"),
* or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
/* ldap-to-be-deprecated.h - functions and declaration which will be
* deprecated in a future release.
*
* A deprecated API is an API that we recommend you no longer use,
* due to improvements in the LDAP C SDK. While deprecated APIs are
* currently still implemented, they may be removed in future
* implementations, and we recommend using other APIs.
*
* This header file will act as a first warning before moving functions
* into an unsupported/deprecated state. If your favorite application
* depend on any declaration and defines, and there is a good reason
* for not porting to new functions, Speak up now or they may disappear
* in a future release
*/
#ifndef _LDAP_TOBE_DEPRECATED_H
#define _LDAP_TOBE_DEPRECATED_H
#ifdef __cplusplus
extern "C" {
#endif
/*
* I/O function callbacks option (an API extension --
* LDAP_API_FEATURE_X_IO_FUNCTIONS).
* Use of the extended I/O functions instead is recommended
*/
#define LDAP_OPT_IO_FN_PTRS 0x0B /* 11 - API extension */
/*
* I/O callback functions (note that types for the read and write callbacks
* are actually in lber.h):
*/
typedef int (LDAP_C LDAP_CALLBACK LDAP_IOF_SELECT_CALLBACK)( int nfds,
fd_set *readfds, fd_set *writefds, fd_set *errorfds,
struct timeval *timeout );
typedef LBER_SOCKET (LDAP_C LDAP_CALLBACK LDAP_IOF_SOCKET_CALLBACK)(
int domain, int type, int protocol );
typedef int (LDAP_C LDAP_CALLBACK LDAP_IOF_IOCTL_CALLBACK)( LBER_SOCKET s,
int option, ... );
typedef int (LDAP_C LDAP_CALLBACK LDAP_IOF_CONNECT_CALLBACK )(
LBER_SOCKET s, struct sockaddr *name, int namelen );
typedef int (LDAP_C LDAP_CALLBACK LDAP_IOF_CLOSE_CALLBACK )(
LBER_SOCKET s );
typedef int (LDAP_C LDAP_CALLBACK LDAP_IOF_SSL_ENABLE_CALLBACK )(
LBER_SOCKET s );
/*
* Structure to hold I/O function pointers:
*/
struct ldap_io_fns {
LDAP_IOF_READ_CALLBACK *liof_read;
LDAP_IOF_WRITE_CALLBACK *liof_write;
LDAP_IOF_SELECT_CALLBACK *liof_select;
LDAP_IOF_SOCKET_CALLBACK *liof_socket;
LDAP_IOF_IOCTL_CALLBACK *liof_ioctl;
LDAP_IOF_CONNECT_CALLBACK *liof_connect;
LDAP_IOF_CLOSE_CALLBACK *liof_close;
LDAP_IOF_SSL_ENABLE_CALLBACK *liof_ssl_enable;
};
/*
* DNS resolver callbacks (an API extension --LDAP_API_FEATURE_X_DNS_FUNCTIONS).
* Note that gethostbyaddr() is not currently used.
*/
#define LDAP_OPT_DNS_FN_PTRS 0x60 /* 96 - API extension */
typedef struct LDAPHostEnt {
char *ldaphe_name; /* official name of host */
char **ldaphe_aliases; /* alias list */
int ldaphe_addrtype; /* host address type */
int ldaphe_length; /* length of address */
char **ldaphe_addr_list; /* list of addresses from name server */
} LDAPHostEnt;
typedef LDAPHostEnt * (LDAP_C LDAP_CALLBACK LDAP_DNSFN_GETHOSTBYNAME)(
const char *name, LDAPHostEnt *result, char *buffer,
int buflen, int *statusp, void *extradata );
typedef LDAPHostEnt * (LDAP_C LDAP_CALLBACK LDAP_DNSFN_GETHOSTBYADDR)(
const char *addr, int length, int type, LDAPHostEnt *result,
char *buffer, int buflen, int *statusp, void *extradata );
typedef int (LDAP_C LDAP_CALLBACK LDAP_DNSFN_GETPEERNAME)(
LDAP *ld, struct sockaddr *netaddr, char *buffer, int buflen);
struct ldap_dns_fns {
void *lddnsfn_extradata;
int lddnsfn_bufsize;
LDAP_DNSFN_GETHOSTBYNAME *lddnsfn_gethostbyname;
LDAP_DNSFN_GETHOSTBYADDR *lddnsfn_gethostbyaddr;
LDAP_DNSFN_GETPEERNAME *lddnsfn_getpeername;
};
/*
* experimental DN format support
*/
LDAP_API(char **) LDAP_CALL ldap_explode_dns( const char *dn );
LDAP_API(int) LDAP_CALL ldap_is_dns_dn( const char *dn );
/*
* user friendly naming/searching routines
*/
typedef int (LDAP_C LDAP_CALLBACK LDAP_CANCELPROC_CALLBACK)( void *cl );
LDAP_API(int) LDAP_CALL ldap_ufn_search_c( LDAP *ld, char *ufn,
char **attrs, int attrsonly, LDAPMessage **res,
LDAP_CANCELPROC_CALLBACK *cancelproc, void *cancelparm );
LDAP_API(int) LDAP_CALL ldap_ufn_search_ct( LDAP *ld, char *ufn,
char **attrs, int attrsonly, LDAPMessage **res,
LDAP_CANCELPROC_CALLBACK *cancelproc, void *cancelparm,
char *tag1, char *tag2, char *tag3 );
LDAP_API(int) LDAP_CALL ldap_ufn_search_s( LDAP *ld, char *ufn,
char **attrs, int attrsonly, LDAPMessage **res );
LDAP_API(LDAPFiltDesc *) LDAP_CALL ldap_ufn_setfilter( LDAP *ld, char *fname );
LDAP_API(void) LDAP_CALL ldap_ufn_setprefix( LDAP *ld, char *prefix );
LDAP_API(int) LDAP_C ldap_ufn_timeout( void *tvparam );
/*
* utility routines
*/
LDAP_API(int) LDAP_CALL ldap_charray_add( char ***a, char *s );
LDAP_API(int) LDAP_CALL ldap_charray_merge( char ***a, char **s );
LDAP_API(void) LDAP_CALL ldap_charray_free( char **array );
LDAP_API(int) LDAP_CALL ldap_charray_inlist( char **a, char *s );
LDAP_API(char **) LDAP_CALL ldap_charray_dup( char **a );
LDAP_API(char **) LDAP_CALL ldap_str2charray( char *str, char *brkstr );
LDAP_API(int) LDAP_CALL ldap_charray_position( char **a, char *s );
/* from ldap_ssl.h - the pkcs function and declaration */
typedef int (LDAP_C LDAP_CALLBACK LDAP_PKCS_GET_TOKEN_CALLBACK)(void *context, char **tokenname);
typedef int (LDAP_C LDAP_CALLBACK LDAP_PKCS_GET_PIN_CALLBACK)(void *context, const char *tokenname, char **tokenpin);
typedef int (LDAP_C LDAP_CALLBACK LDAP_PKCS_GET_CERTPATH_CALLBACK)(void *context, char **certpath);
typedef int (LDAP_C LDAP_CALLBACK LDAP_PKCS_GET_KEYPATH_CALLBACK)(void *context,char **keypath);
typedef int (LDAP_C LDAP_CALLBACK LDAP_PKCS_GET_MODPATH_CALLBACK)(void *context, char **modulepath);
typedef int (LDAP_C LDAP_CALLBACK LDAP_PKCS_GET_CERTNAME_CALLBACK)(void *context, char **certname);
typedef int (LDAP_C LDAP_CALLBACK LDAP_PKCS_GET_DONGLEFILENAME_CALLBACK)(void *context, char **filename);
#define PKCS_STRUCTURE_ID 1
struct ldapssl_pkcs_fns {
int local_structure_id;
void *local_data;
LDAP_PKCS_GET_CERTPATH_CALLBACK *pkcs_getcertpath;
LDAP_PKCS_GET_CERTNAME_CALLBACK *pkcs_getcertname;
LDAP_PKCS_GET_KEYPATH_CALLBACK *pkcs_getkeypath;
LDAP_PKCS_GET_MODPATH_CALLBACK *pkcs_getmodpath;
LDAP_PKCS_GET_PIN_CALLBACK *pkcs_getpin;
LDAP_PKCS_GET_TOKEN_CALLBACK *pkcs_gettokenname;
LDAP_PKCS_GET_DONGLEFILENAME_CALLBACK *pkcs_getdonglefilename;
};
LDAP_API(int) LDAP_CALL ldapssl_pkcs_init( const struct ldapssl_pkcs_fns *pfns);
#ifdef __cplusplus
}
#endif
#endif /* _LDAP_TOBE_DEPRECATED_H */

62
ldap/c-sdk/include/ldap.h Normal file
View file

@ -0,0 +1,62 @@
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is Mozilla Communicator client code, released
* March 31, 1998.
*
* The Initial Developer of the Original Code is
* Netscape Communications Corporation.
* Portions created by the Initial Developer are Copyright (C) 1998-1999
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
*
* Alternatively, the contents of this file may be used under the terms of
* either of the GNU General Public License Version 2 or later (the "GPL"),
* or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
/* ldap.h - general header file for libldap */
#ifndef _LDAP_H
#define _LDAP_H
/* Standard LDAP API functions and declarations */
#include "ldap-standard.h"
/* Extensions to the LDAP standard */
#include "ldap-extension.h"
/* A deprecated API is an API that we recommend you no longer use,
* due to improvements in the LDAP C SDK. While deprecated APIs are
* currently still implemented, they may be removed in future
* implementations, and we recommend using other APIs.
*/
/* Soon-to-be deprecated functions and declarations */
#include "ldap-to-be-deprecated.h"
/* Deprecated functions and declarations */
#include "ldap-deprecated.h"
#endif /* _LDAP_H */

View file

@ -0,0 +1,254 @@
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is Mozilla Communicator client code, released
* March 31, 1998.
*
* The Initial Developer of the Original Code is
* Netscape Communications Corporation.
* Portions created by the Initial Developer are Copyright (C) 1998-1999
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
*
* Alternatively, the contents of this file may be used under the terms of
* either of the GNU General Public License Version 2 or later (the "GPL"),
* or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
#if !defined(LDAP_SSL_H)
#define LDAP_SSL_H
/* ldap_ssl.h - prototypes for LDAP over SSL functions */
#ifdef __cplusplus
extern "C" {
#endif
/*
* these three defines resolve the SSL strength
* setting auth weak, diables all cert checking
* the CNCHECK tests for the man in the middle hack
*/
#define LDAPSSL_AUTH_WEAK 0
#define LDAPSSL_AUTH_CERT 1
#define LDAPSSL_AUTH_CNCHECK 2
/*
* an ExtendedRequest [LDAPv3] specifying the OID for the
* Start TLS operation: RFC 2830
*/
#define LDAP_EXOP_START_TLS "1.3.6.1.4.1.1466.20037"
/*
* Initialize LDAP library for SSL
*/
LDAP * LDAP_CALL ldapssl_init( const char *defhost, int defport,
int defsecure );
/*
* Shutdown LDAP library for SSL :
* Perform necessary cleanup and attempt to shutdown NSS. All existing
* ld session handles should be ldap_unbind(ld) prior to calling this.
*/
int LDAP_CALL ldapssl_shutdown();
/* Initialize LDAP library for TLS(SSL) and sends StartTLS extended
* operation to the Directory Server.
* Returns LDAP_SUCCESS if all goes well.
*/
int LDAP_CALL ldap_start_tls_s( LDAP *ld, LDAPControl **serverctrls,
LDAPControl **clientctrls );
/*
* Install I/O routines to make SSL over LDAP possible.
* Use this after ldap_init() or just use ldapssl_init() instead.
* Returns 0 if all goes well.
*/
int LDAP_CALL ldapssl_install_routines( LDAP *ld );
/* The next four functions initialize the security code for SSL
* The first one ldapssl_client_init() does initialization for SSL only
* The next one supports server authentication using clientauth_init()
* and allows the caller to specify the ssl strength to use in order to
* verify the servers's certificate.
* The next one supports ldapssl_clientauth_init() intializes security
* for SSL for client authentication. The third function initializes
* security for doing SSL with client authentication, and PKCS, that is,
* the third function initializes the security module database (secmod.db).
* The parameters are as follows:
* const char *certdbpath - path to the cert file. This can be a shortcut
* to the directory name, if so cert7.db will be postfixed to the string.
* void *certdbhandle - Normally this is NULL. This memory will need
* to be freed.
* int needkeydb - boolean. Must be !=0 if client Authentification
* is required
* char *keydbpath - path to the key database. This can be a shortcut
* to the directory name, if so key3.db will be postfixed to the string.
* void *keydbhandle - Normally this is NULL, This memory will need
* to be freed
* int needsecmoddb - boolean. Must be !=0 to assure that the correct
* security module is loaded into memory
* char *secmodpath - path to the secmod. This can be a shortcut to the
* directory name, if so secmod.db will be postfixed to the string.
*
* These three functions are mutually exclusive. You can only call
* one. This means that, for a given process, you must call the
* appropriate initialization function for the life of the process.
*/
/*
* Initialize the secure parts (Security and SSL) of the runtime for use
* by a client application. This is only called once.
* Returns 0 if all goes well.
*/
int LDAP_CALL ldapssl_client_init(
const char *certdbpath, void *certdbhandle );
/*
* Initialize the secure parts (Security and SSL) of the runtime for use
* by a client application using server authentication. This is only
* called once.
*
* ldapssl_serverauth_init() is a server-authentication only version of
* ldapssl_clientauth_init(). This function allows the sslstrength
* to be passed in. The sslstrength can take one of the following
* values:
*
* LDAPSSL_AUTH_WEAK: indicate that you accept the server's
* certificate without checking the CA who
* issued the certificate
* LDAPSSL_AUTH_CERT: indicates that you accept the server's
* certificate only if you trust the CA who
* issued the certificate
* LDAPSSL_AUTH_CNCHECK:
* indicates that you accept the server's
* certificate only if you trust the CA who
* issued the certificate and if the value
* of the cn attribute is the DNS hostname
* of the server. If this option is selected,
* please ensure that the "defhost" parameter
* passed to ldapssl_init() consist of only
* one hostname and not a list of hosts.
* Furthermore, the port number must be passed
* via the "defport" parameter, and cannot
* be passed via a host:port option.
*
* Returns 0 if all goes well.
*/
int LDAP_CALL ldapssl_serverauth_init(
const char *certdbpath, void *certdbhandle, const int sslstrength );
/*
* Initialize the secure parts (Security and SSL) of the runtime for use
* by a client application that may want to do SSL client authentication.
* Returns 0 if all goes well.
*/
int LDAP_CALL ldapssl_clientauth_init(
const char *certdbpath, void *certdbhandle,
const int needkeydb, const char *keydbpath, void *keydbhandle );
/*
* Initialize the secure parts (Security and SSL) of the runtime for use
* by a client application that may want to do SSL client authentication.
*
* Please see the description of the sslstrength value in the
* ldapssl_serverauth_init() function above and note the potential
* problems which can be caused by passing in wrong host & portname
* values. The same warning applies to the ldapssl_advclientauth_init()
* function.
*
* Returns 0 if all goes well.
*/
int LDAP_CALL ldapssl_advclientauth_init(
const char *certdbpath, void *certdbhandle,
const int needkeydb, const char *keydbpath, void *keydbhandle,
const int needsecmoddb, const char *secmoddbpath,
const int sslstrength );
/*
* get a meaningful error string back from the security library
* this function should be called, if ldap_err2string doesn't
* identify the error code.
*/
const char * LDAP_CALL ldapssl_err2string( const int prerrno );
/*
* Enable SSL client authentication on the given ld.
* Returns 0 if all goes well.
*/
int LDAP_CALL ldapssl_enable_clientauth( LDAP *ld, char *keynickname,
char *keypasswd, char *certnickname );
/*
* Set the SSL strength for an existing SSL-enabled LDAP session handle.
*
* See the description of ldapssl_serverauth_init() above for valid
* sslstrength values. If ld is NULL, the default for new LDAP session
* handles is set.
*
* Returns 0 if all goes well.
*/
int LDAP_CALL ldapssl_set_strength( LDAP *ld, int sslstrength );
/*
* Set or get SSL options for an existing SSL-enabled LDAP session handle.
* If ld is NULL, the default options used for all future LDAP SSL sessions
* are the ones affected. The option values are specific to the underlying
* SSL provider; see ssl.h within the Network Security Services (NSS)
* distribution for the options supported by NSS (the default SSL provider).
*
* The ldapssl_set_option() function should be called before any LDAP
* connections are created.
*
* Both functions return 0 if all goes well.
*/
int LDAP_CALL ldapssl_set_option( LDAP *ld, int option, int on );
int LDAP_CALL ldapssl_get_option( LDAP *ld, int option, int *onp );
/*
* Import the file descriptor corresponding to the socket of an already
* open LDAP connection into SSL, and update the socket and session
* information accordingly. Returns 0 if all goes well.
*/
int LDAP_CALL ldapssl_import_fd ( LDAP *ld, int secure );
/*
* Reset an LDAP session from SSL to a non-secure status. Basically,
* this function undoes the work done by ldapssl_install_routines.
* Returns 0 if all goes well.
*/
int LDAP_CALL ldapssl_reset_to_nonsecure ( LDAP *ld );
#ifdef __cplusplus
}
#endif
#endif /* !defined(LDAP_SSL_H) */

View file

@ -0,0 +1,106 @@
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is Mozilla Communicator client code, released
* March 31, 1998.
*
* The Initial Developer of the Original Code is
* Netscape Communications Corporation.
* Portions created by the Initial Developer are Copyright (C) 1998-1999
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
*
* Alternatively, the contents of this file may be used under the terms of
* either of the GNU General Public License Version 2 or later (the "GPL"),
* or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
#ifndef _LDAPLOG_H
#define _LDAPLOG_H
#ifdef __cplusplus
extern "C" {
#endif
#define LDAP_DEBUG_TRACE 0x00001
#define LDAP_DEBUG_PACKETS 0x00002
#define LDAP_DEBUG_ARGS 0x00004
#define LDAP_DEBUG_CONNS 0x00008
#define LDAP_DEBUG_BER 0x00010
#define LDAP_DEBUG_FILTER 0x00020
#define LDAP_DEBUG_CONFIG 0x00040
#define LDAP_DEBUG_ACL 0x00080
#define LDAP_DEBUG_STATS 0x00100
#define LDAP_DEBUG_STATS2 0x00200
#define LDAP_DEBUG_SHELL 0x00400
#define LDAP_DEBUG_PARSE 0x00800
#define LDAP_DEBUG_HOUSE 0x01000
#define LDAP_DEBUG_REPL 0x02000
#define LDAP_DEBUG_ANY 0x04000
#define LDAP_DEBUG_CACHE 0x08000
#define LDAP_DEBUG_PLUGIN 0x10000
/* debugging stuff */
/* Disable by default */
#define LDAPDebug( level, fmt, arg1, arg2, arg3 )
#ifdef LDAP_DEBUG
# undef LDAPDebug
/* SLAPD_LOGGING should not be on for WINSOCK (16-bit Windows) */
# if defined(SLAPD_LOGGING)
# ifdef _WIN32
extern int *module_ldap_debug;
# define LDAPDebug( level, fmt, arg1, arg2, arg3 ) \
{ \
if ( *module_ldap_debug & level ) { \
slapd_log_error_proc( NULL, fmt, arg1, arg2, arg3 ); \
} \
}
# else /* _WIN32 */
extern int ldap_debug;
# define LDAPDebug( level, fmt, arg1, arg2, arg3 ) \
{ \
if ( ldap_debug & level ) { \
slapd_log_error_proc( NULL, fmt, arg1, arg2, arg3 ); \
} \
}
# endif /* Win32 */
# else /* no SLAPD_LOGGING */
extern void ber_err_print( char * );
extern int ldap_debug;
# define LDAPDebug( level, fmt, arg1, arg2, arg3 ) \
if ( ldap_debug & level ) { \
char msg[1024]; \
snprintf( msg, sizeof(msg), fmt, arg1, arg2, arg3 ); \
msg[sizeof(msg)-1] = '\0'; \
ber_err_print( msg ); \
}
# endif /* SLAPD_LOGGING */
#endif /* LDAP_DEBUG */
#ifdef __cplusplus
}
#endif
#endif /* _LDAP_H */

273
ldap/c-sdk/include/ldappr.h Normal file
View file

@ -0,0 +1,273 @@
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is Mozilla Communicator client code, released
* March 31, 1998.
*
* The Initial Developer of the Original Code is
* Netscape Communications Corporation.
* Portions created by the Initial Developer are Copyright (C) 1998-1999
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
*
* Alternatively, the contents of this file may be used under the terms of
* either of the GNU General Public License Version 2 or later (the "GPL"),
* or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
#ifndef LDAP_PR_H
#define LDAP_PR_H
#include "nspr.h"
/*
* ldappr.h - prototypes for functions that tie libldap into NSPR (Netscape
* Portable Runtime).
*/
#ifdef __cplusplus
extern "C" {
#endif
/*
* Function: prldap_init().
*
* Create a new LDAP session handle, but with NSPR I/O, threading, and DNS
* functions installed.
*
* Pass a non-zero value for the 'shared' parameter if you plan to use
* this LDAP * handle from more than one thread.
*
* Returns an LDAP session handle (or NULL if an error occurs).
*
* NOTE: If you want to use IPv6, you must use prldap creating a LDAP handle
* with this function prldap_init. Prldap_init installs the appropriate
* set of NSPR functions and prevents calling deprecated functions accidentally.
*/
LDAP * LDAP_CALL prldap_init( const char *defhost, int defport, int shared );
/*
* Function: prldap_install_routines().
*
* Install NSPR I/O, threading, and DNS functions so they will be used by
* 'ld'.
*
* If 'ld' is NULL, the functions are installed as the default functions
* for all new LDAP * handles).
*
* Pass a non-zero value for the 'shared' parameter if you plan to use
* this LDAP * handle from more than one thread.
*
* Returns an LDAP API error code (LDAP_SUCCESS if all goes well).
*/
int LDAP_CALL prldap_install_routines( LDAP *ld, int shared );
/*
* Function: prldap_set_session_option().
*
* Given an LDAP session handle or a session argument such is passed to
* CONNECT, POLL, NEWHANDLE, or DISPOSEHANDLE extended I/O callbacks, set
* an option that affects the prldap layer.
*
* If 'ld' and 'session" are both NULL, the option is set as the default
* for all new prldap sessions.
*
* Returns an LDAP API error code (LDAP_SUCCESS if all goes well).
*/
int LDAP_CALL prldap_set_session_option( LDAP *ld, void *sessionarg,
int option, ... );
/*
* Function: prldap_get_session_option().
*
* Given an LDAP session handle or a session argument such is passed to
* CONNECT, POLL, NEWHANDLE, or DISPOSEHANDLE extended I/O callbacks, retrieve
* the setting for an option that affects the prldap layer.
*
* If 'ld' and 'session" are both NULL, the default option value for all new
* new prldap sessions is retrieved.
*
* Returns an LDAP API error code (LDAP_SUCCESS if all goes well).
*/
int LDAP_CALL prldap_get_session_option( LDAP *ld, void *sessionarg,
int option, ... );
/*
* Available options.
*/
/*
* PRLDAP_OPT_IO_MAX_TIMEOUT: the maximum time in milliseconds to
* block waiting for a network I/O operation to complete.
*
* Data type: int.
*
* These two special values from ldap-extension.h can also be used;
*
* LDAP_X_IO_TIMEOUT_NO_TIMEOUT
* LDAP_X_IO_TIMEOUT_NO_WAIT
*/
#define PRLDAP_OPT_IO_MAX_TIMEOUT 1
/**
** Note: the types and functions below are only useful for developers
** who need to layer one or more custom extended I/O functions on top of
** the standard NSPR I/O functions installed by a call to prldap_init()
** or prldap_install_routines(). Layering can be accomplished after
** prldap_init() or prldap_install_routines() has completed successfully
** by:
**
** 1) Calling ldap_get_option( ..., LDAP_X_OPT_EXTIO_FN_PTRS, ... ).
**
** 2) Saving the function pointer of one or more of the standard functions.
**
** 3) Replacing one or more standard functions in the ldap_x_ext_io_fns
** struct with new functions that optionally do some preliminary work,
** call the standard function (via the function pointer saved in step 2),
** and optionally do some followup work.
*/
/*
* Data structure for session information.
* seinfo_size should be set to PRLDAP_SESSIONINFO_SIZE before use.
*/
struct prldap_session_private;
typedef struct prldap_session_info {
int seinfo_size;
struct prldap_session_private *seinfo_appdata;
} PRLDAPSessionInfo;
#define PRLDAP_SESSIONINFO_SIZE sizeof( PRLDAPSessionInfo )
/*
* Function: prldap_set_session_info().
*
* Given an LDAP session handle or a session argument such is passed to
* CONNECT, POLL, NEWHANDLE, or DISPOSEHANDLE extended I/O callbacks,
* set some application-specific data. If ld is NULL, arg is used. If
* both ld and arg are NULL, LDAP_PARAM_ERROR is returned.
*
* Returns an LDAP API error code (LDAP_SUCCESS if all goes well).
*/
int LDAP_CALL prldap_set_session_info( LDAP *ld, void *sessionarg,
PRLDAPSessionInfo *seip );
/*
* Function: prldap_get_session_info().
*
* Given an LDAP session handle or a session argument such is passed to
* CONNECT, POLL, NEWHANDLE, or DISPOSEHANDLE extended I/O callbacks,
* retrieve some application-specific data. If ld is NULL, arg is used. If
* both ld and arg are NULL, LDAP_PARAM_ERROR is returned.
*
* Returns an LDAP API error code (LDAP_SUCCESS if all goes well, in
* which case the fields in the structure that seip points to are filled in).
*/
int LDAP_CALL prldap_get_session_info( LDAP *ld, void *sessionarg,
PRLDAPSessionInfo *seip );
/*
* Data structure for socket specific information.
* Note: soinfo_size should be set to PRLDAP_SOCKETINFO_SIZE before use.
*/
struct prldap_socket_private;
typedef struct prldap_socket_info {
int soinfo_size;
PRFileDesc *soinfo_prfd;
struct prldap_socket_private *soinfo_appdata;
} PRLDAPSocketInfo;
#define PRLDAP_SOCKETINFO_SIZE sizeof( PRLDAPSocketInfo )
/*
* Function: prldap_set_socket_info().
*
* Given an integer fd and a socket argument such as those passed to the
* extended I/O callback functions, set socket specific information.
*
* Returns an LDAP API error code (LDAP_SUCCESS if all goes well).
*
* Note: it is only safe to change soinfo_prfd from within the CONNECT
* extended I/O callback function.
*/
int LDAP_CALL prldap_set_socket_info( int fd, void *socketarg,
PRLDAPSocketInfo *soip );
/*
* Function: prldap_get_socket_info().
*
* Given an integer fd and a socket argument such as those passed to the
* extended I/O callback functions, retrieve socket specific information.
*
* Returns an LDAP API error code (LDAP_SUCCESS if all goes well, in
* which case the fields in the structure that soip points to are filled in).
*/
int LDAP_CALL prldap_get_socket_info( int fd, void *socketarg,
PRLDAPSocketInfo *soip );
/*
* Function: prldap_get_default_socket_info().
*
* Given an LDAP session handle, retrieve socket specific information.
* If ld is NULL, LDAP_PARAM_ERROR is returned.
*
* Returns an LDAP API error code (LDAP_SUCCESS if all goes well, in
* which case the fields in the structure that soip points to are filled in).
*/
int LDAP_CALL prldap_get_default_socket_info( LDAP *ld, PRLDAPSocketInfo *soip );
/*
* Function: prldap_set_default_socket_info().
*
* Given an LDAP session handle, set socket specific information.
* If ld is NULL, LDAP_PARAM_ERROR is returned.
*
* Returns an LDAP API error code (LDAP_SUCCESS if all goes well, in
* which case the fields in the structure that soip points to are filled in).
*/
int LDAP_CALL prldap_set_default_socket_info( LDAP *ld, PRLDAPSocketInfo *soip );
/* Function: prldap_is_installed()
* Check if NSPR routine is installed
*/
PRBool prldap_is_installed( LDAP *ld );
/* Function: prldap_import_connection().
* Given a ldap handle with connection already done with ldap_init()
* installs NSPR routines and imports the original connection info.
*
* Returns an LDAP API error code (LDAP_SUCCESS if all goes well).
*/
int LDAP_CALL prldap_import_connection (LDAP *ld);
#ifdef __cplusplus
}
#endif
#endif /* !defined(LDAP_PR_H) */

View file

@ -0,0 +1,203 @@
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is Mozilla Communicator client code, released
* March 31, 1998.
*
* The Initial Developer of the Original Code is
* Netscape Communications Corporation.
* Portions created by the Initial Developer are Copyright (C) 1998-1999
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
*
* Alternatively, the contents of this file may be used under the terms of
* either of the GNU General Public License Version 2 or later (the "GPL"),
* or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
#ifndef _LDAPROT_H
#define _LDAPROT_H
#ifdef __cplusplus
extern "C" {
#endif
#define LDAP_VERSION1 1
#define LDAP_VERSION2 2
#define LDAP_VERSION3 3
#define LDAP_VERSION LDAP_VERSION3
#define COMPAT20
#define COMPAT30
#if defined(COMPAT20) || defined(COMPAT30)
#define COMPAT
#endif
#define LDAP_URL_PREFIX "ldap://"
#define LDAP_URL_PREFIX_LEN 7
#define LDAPS_URL_PREFIX "ldaps://"
#define LDAPS_URL_PREFIX_LEN 8
#define LDAP_REF_STR "Referral:\n"
#define LDAP_REF_STR_LEN 10
/*
* specific LDAP instantiations of BER types we know about
*/
/* general stuff */
#define LDAP_TAG_MESSAGE 0x30L /* tag is 16 + constructed bit */
#define OLD_LDAP_TAG_MESSAGE 0x10L /* forgot the constructed bit */
#define LDAP_TAG_MSGID 0x02L /* INTEGER */
#define LDAP_TAG_LDAPDN 0x04L /* OCTET STRING */
#define LDAP_TAG_CONTROLS 0xa0L /* context specific + constructed + 0 */
#define LDAP_TAG_REFERRAL 0xa3L /* context specific + constructed + 3 */
#define LDAP_TAG_NEWSUPERIOR 0x80L /* context specific + primitive + 0 */
#define LDAP_TAG_MRA_OID 0x81L /* context specific + primitive + 1 */
#define LDAP_TAG_MRA_TYPE 0x82L /* context specific + primitive + 2 */
#define LDAP_TAG_MRA_VALUE 0x83L /* context specific + primitive + 3 */
#define LDAP_TAG_MRA_DNATTRS 0x84L /* context specific + primitive + 4 */
#define LDAP_TAG_EXOP_REQ_OID 0x80L /* context specific + primitive + 0 */
#define LDAP_TAG_EXOP_REQ_VALUE 0x81L /* context specific + primitive + 1 */
#define LDAP_TAG_EXOP_RES_OID 0x8aL /* context specific + primitive + 10 */
#define LDAP_TAG_EXOP_RES_VALUE 0x8bL /* context specific + primitive + 11 */
#define LDAP_TAG_SK_MATCHRULE 0x80L /* context specific + primitive + 0 */
#define LDAP_TAG_SK_REVERSE 0x81L /* context specific + primitive + 1 */
#define LDAP_TAG_SR_ATTRTYPE 0x80L /* context specific + primitive + 0 */
#define LDAP_TAG_SASL_RES_CREDS 0x87L /* context specific + primitive + 7 */
#define LDAP_TAG_VLV_BY_INDEX 0xa0L /* context specific + constructed + 0 */
#define LDAP_TAG_VLV_BY_VALUE 0x81L /* context specific + primitive + 1 */
#define LDAP_TAG_PWP_WARNING 0xA0L /* context specific + constructed */
#define LDAP_TAG_PWP_SECSLEFT 0x80L /* context specific + primitive */
#define LDAP_TAG_PWP_GRCLOGINS 0x81L /* context specific + primitive + 1 */
#define LDAP_TAG_PWP_ERROR 0x81L /* context specific + primitive + 1 */
#define LDAP_TAG_PWDMOD_REQ_ID 0x80L /* context specific + primitive + 0 */
#define LDAP_TAG_PWDMOD_REQ_OLD 0x81L /* context specific + primitive + 1 */
#define LDAP_TAG_PWDMOD_REQ_NEW 0x82L /* context specific + primitive + 2 */
#define LDAP_TAG_PWDMOD_RES_GEN 0x80L /* context specific + primitive + 0 */
/* possible operations a client can invoke */
#define LDAP_REQ_BIND 0x60L /* application + constructed + 0 */
#define LDAP_REQ_UNBIND 0x42L /* application + primitive + 2 */
#define LDAP_REQ_SEARCH 0x63L /* application + constructed + 3 */
#define LDAP_REQ_MODIFY 0x66L /* application + constructed + 6 */
#define LDAP_REQ_ADD 0x68L /* application + constructed + 8 */
#define LDAP_REQ_DELETE 0x4aL /* application + primitive + 10 */
#define LDAP_REQ_MODRDN 0x6cL /* application + constructed + 12 */
#define LDAP_REQ_MODDN 0x6cL /* application + constructed + 12 */
#define LDAP_REQ_RENAME 0x6cL /* application + constructed + 12 */
#define LDAP_REQ_COMPARE 0x6eL /* application + constructed + 14 */
#define LDAP_REQ_ABANDON 0x50L /* application + primitive + 16 */
#define LDAP_REQ_EXTENDED 0x77L /* application + constructed + 23 */
/* U-M LDAP release 3.0 compatibility stuff */
#define LDAP_REQ_UNBIND_30 0x62L
#define LDAP_REQ_DELETE_30 0x6aL
#define LDAP_REQ_ABANDON_30 0x70L
/*
* old broken stuff for backwards compatibility - forgot application tag
* and constructed/primitive bit
*/
#define OLD_LDAP_REQ_BIND 0x00L
#define OLD_LDAP_REQ_UNBIND 0x02L
#define OLD_LDAP_REQ_SEARCH 0x03L
#define OLD_LDAP_REQ_MODIFY 0x06L
#define OLD_LDAP_REQ_ADD 0x08L
#define OLD_LDAP_REQ_DELETE 0x0aL
#define OLD_LDAP_REQ_MODRDN 0x0cL
#define OLD_LDAP_REQ_MODDN 0x0cL
#define OLD_LDAP_REQ_COMPARE 0x0eL
#define OLD_LDAP_REQ_ABANDON 0x10L
/* old broken stuff for backwards compatibility */
#define OLD_LDAP_RES_BIND 0x01L
#define OLD_LDAP_RES_SEARCH_ENTRY 0x04L
#define OLD_LDAP_RES_SEARCH_RESULT 0x05L
#define OLD_LDAP_RES_MODIFY 0x07L
#define OLD_LDAP_RES_ADD 0x09L
#define OLD_LDAP_RES_DELETE 0x0bL
#define OLD_LDAP_RES_MODRDN 0x0dL
#define OLD_LDAP_RES_MODDN 0x0dL
#define OLD_LDAP_RES_COMPARE 0x0fL
/* U-M LDAP 3.0 compatibility auth methods */
#define LDAP_AUTH_SIMPLE_30 0xa0L /* context specific + constructed */
#define LDAP_AUTH_KRBV41_30 0xa1L /* context specific + constructed */
#define LDAP_AUTH_KRBV42_30 0xa2L /* context specific + constructed */
/* old broken stuff */
#define OLD_LDAP_AUTH_SIMPLE 0x00L
#define OLD_LDAP_AUTH_KRBV4 0x01L
#define OLD_LDAP_AUTH_KRBV42 0x02L
/* U-M LDAP 3.0 compatibility filter types */
#define LDAP_FILTER_PRESENT_30 0xa7L /* context specific + constructed */
/* filter types */
#define LDAP_FILTER_AND 0xa0L /* context specific + constructed + 0 */
#define LDAP_FILTER_OR 0xa1L /* context specific + constructed + 1 */
#define LDAP_FILTER_NOT 0xa2L /* context specific + constructed + 2 */
#define LDAP_FILTER_EQUALITY 0xa3L /* context specific + constructed + 3 */
#define LDAP_FILTER_SUBSTRINGS 0xa4L /* context specific + constructed + 4 */
#define LDAP_FILTER_GE 0xa5L /* context specific + constructed + 5 */
#define LDAP_FILTER_LE 0xa6L /* context specific + constructed + 6 */
#define LDAP_FILTER_PRESENT 0x87L /* context specific + primitive + 7 */
#define LDAP_FILTER_APPROX 0xa8L /* context specific + constructed + 8 */
#define LDAP_FILTER_EXTENDED 0xa9L /* context specific + constructed + 0 */
/* old broken stuff */
#define OLD_LDAP_FILTER_AND 0x00L
#define OLD_LDAP_FILTER_OR 0x01L
#define OLD_LDAP_FILTER_NOT 0x02L
#define OLD_LDAP_FILTER_EQUALITY 0x03L
#define OLD_LDAP_FILTER_SUBSTRINGS 0x04L
#define OLD_LDAP_FILTER_GE 0x05L
#define OLD_LDAP_FILTER_LE 0x06L
#define OLD_LDAP_FILTER_PRESENT 0x07L
#define OLD_LDAP_FILTER_APPROX 0x08L
/* substring filter component types */
#define LDAP_SUBSTRING_INITIAL 0x80L /* context specific + primitive + 0 */
#define LDAP_SUBSTRING_ANY 0x81L /* context specific + primitive + 1 */
#define LDAP_SUBSTRING_FINAL 0x82L /* context specific + primitive + 2 */
/* extended filter component types */
#define LDAP_FILTER_EXTENDED_OID 0x81L /* context spec. + prim. + 1 */
#define LDAP_FILTER_EXTENDED_TYPE 0x82L /* context spec. + prim. + 2 */
#define LDAP_FILTER_EXTENDED_VALUE 0x83L /* context spec. + prim. + 3 */
#define LDAP_FILTER_EXTENDED_DNATTRS 0x84L /* context spec. + prim. + 4 */
/* U-M LDAP 3.0 compatibility substring filter component types */
#define LDAP_SUBSTRING_INITIAL_30 0xa0L /* context specific */
#define LDAP_SUBSTRING_ANY_30 0xa1L /* context specific */
#define LDAP_SUBSTRING_FINAL_30 0xa2L /* context specific */
/* old broken stuff */
#define OLD_LDAP_SUBSTRING_INITIAL 0x00L
#define OLD_LDAP_SUBSTRING_ANY 0x01L
#define OLD_LDAP_SUBSTRING_FINAL 0x02L
#ifdef __cplusplus
}
#endif
#endif /* _LDAPROT_H */

114
ldap/c-sdk/include/ldif.h Normal file
View file

@ -0,0 +1,114 @@
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is Mozilla Communicator client code, released
* March 31, 1998.
*
* The Initial Developer of the Original Code is
* Netscape Communications Corporation.
* Portions created by the Initial Developer are Copyright (C) 1998-1999
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
*
* Alternatively, the contents of this file may be used under the terms of
* either of the GNU General Public License Version 2 or later (the "GPL"),
* or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
/*
* Copyright (c) 1996 Regents of the University of Michigan.
* All rights reserved.
*
* Redistribution and use in source and binary forms are permitted
* provided that this notice is preserved and that due credit is given
* to the University of Michigan at Ann Arbor. The name of the University
* may not be used to endorse or promote products derived from this
* software without specific prior written permission. This software
* is provided ``as is'' without express or implied warranty.
*/
/* NOTE: As of mozldap version 6.0.1 the LDIF functions are now
publicly usable. The LDIF functions were originally designed for
"internal use only" purposes and as such the APIs are not very modern
or safe. For example, the caller needs to be careful to provide
adequately sized buffers and so on.
*/
#ifndef _LDIF_H
#define _LDIF_H
#ifdef __cplusplus
extern "C" {
#endif
#define LDIF_VERSION_ONE 1 /* LDIF standard version */
#define LDIF_MAX_LINE_WIDTH 76 /* maximum length of LDIF lines */
/*
* Macro to calculate maximum number of bytes that the base64 equivalent
* of an item that is "vlen" bytes long will take up. Base64 encoding
* uses one byte for every six bits in the value plus up to two pad bytes.
*/
#define LDIF_BASE64_LEN(vlen) (((vlen) * 4 / 3 ) + 3)
/*
* Macro to calculate maximum size that an LDIF-encoded type (length
* tlen) and value (length vlen) will take up: room for type + ":: " +
* first newline + base64 value + continued lines. Each continued line
* needs room for a newline and a leading space character.
*/
#define LDIF_SIZE_NEEDED(tlen,vlen) \
((tlen) + 4 + LDIF_BASE64_LEN(vlen) \
+ ((LDIF_BASE64_LEN(vlen) + tlen + 3) / LDIF_MAX_LINE_WIDTH * 2 ))
/*
* Options for ldif_put_type_and_value_with_options() and
* ldif_type_and_value_with_options().
*/
#define LDIF_OPT_NOWRAP 0x01UL
#define LDIF_OPT_VALUE_IS_URL 0x02UL
#define LDIF_OPT_MINIMAL_ENCODING 0x04UL
int ldif_parse_line( char *line, char **type, char **value, int *vlen);
char * ldif_getline( char **next );
void ldif_put_type_and_value( char **out, char *t, char *val, int vlen );
void ldif_put_type_and_value_nowrap( char **out, char *t, char *val, int vlen );
void ldif_put_type_and_value_with_options( char **out, char *t, char *val,
int vlen, unsigned long options );
char *ldif_type_and_value( char *type, char *val, int vlen );
char *ldif_type_and_value_nowrap( char *type, char *val, int vlen );
char *ldif_type_and_value_with_options( char *type, char *val, int vlen,
unsigned long options );
int ldif_base64_decode( char *src, unsigned char *dst );
int ldif_base64_encode( unsigned char *src, char *dst, int srclen,
int lenused );
int ldif_base64_encode_nowrap( unsigned char *src, char *dst, int srclen,
int lenused );
char *ldif_get_entry( FILE *fp, int *lineno );
#ifdef __cplusplus
}
#endif
#endif /* _LDIF_H */

View file

@ -0,0 +1,462 @@
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is Mozilla Communicator client code, released
* March 31, 1998.
*
* The Initial Developer of the Original Code is
* Netscape Communications Corporation.
* Portions created by the Initial Developer are Copyright (C) 1998-1999
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
*
* Alternatively, the contents of this file may be used under the terms of
* either of the GNU General Public License Version 2 or later (the "GPL"),
* or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
/*
* Copyright (c) 1994 Regents of the University of Michigan.
* All rights reserved.
*
* Redistribution and use in source and binary forms are permitted
* provided that this notice is preserved and that due credit is given
* to the University of Michigan at Ann Arbor. The name of the University
* may not be used to endorse or promote products derived from this
* software without specific prior written permission. This software
* is provided ``as is'' without express or implied warranty.
*/
#ifndef _PORTABLE_H
#define _PORTABLE_H
/*
* portable.h for LDAP -- this is where we define common stuff to make
* life easier on various Unix systems.
*
* Unless you are porting LDAP to a new platform, you should not need to
* edit this file.
*/
#ifndef SYSV
#if defined( hpux ) || defined( SOLARIS ) || defined ( sgi ) || defined( SVR4 )
#define SYSV
#endif
#endif
/*
* under System V, use sysconf() instead of getdtablesize
*/
#if !defined( USE_SYSCONF ) && defined( SYSV )
#define USE_SYSCONF
#endif
/*
* under System V, daemons should use setsid() instead of detaching from their
* tty themselves
*/
#if !defined( USE_SETSID ) && defined( SYSV )
#define USE_SETSID
#endif
/*
* System V has socket options in filio.h
*/
#if !defined( NEED_FILIO ) && defined( SYSV ) && !defined( hpux ) && !defined( AIX )
#define NEED_FILIO
#endif
/*
* use lockf() under System V
*/
#if !defined( USE_LOCKF ) && ( defined( SYSV ) || defined( aix ))
#define USE_LOCKF
#endif
/*
* on many systems, we should use waitpid() instead of waitN()
*/
#if !defined( USE_WAITPID ) && ( defined( SYSV ) || defined( sunos4 ) || defined( ultrix ) || defined( aix ))
#define USE_WAITPID
#endif
/*
* define the wait status argument type
*/
#if ( defined( SunOS ) && SunOS < 40 ) || defined( nextstep )
#define WAITSTATUSTYPE union wait
#else
#define WAITSTATUSTYPE int
#endif
/*
* defined the options for openlog (syslog)
*/
#ifdef ultrix
#define OPENLOG_OPTIONS LOG_PID
#else
#define OPENLOG_OPTIONS ( LOG_PID | LOG_NOWAIT )
#endif
/*
* some systems don't have the BSD re_comp and re_exec routines
*/
#ifndef NEED_BSDREGEX
#if ( defined( SYSV ) || defined( NETBSD ) || defined( FREEBSD ) || defined(__OpenBSD__) || defined( linux ) || defined( DARWIN )) && !defined(sgi)
#define NEED_BSDREGEX
#endif
#endif
/*
* many systems do not have the setpwfile() library routine... we just
* enable use for those systems we know have it.
*/
#ifndef HAVE_SETPWFILE
#if defined( sunos4 ) || defined( ultrix ) || defined( OSF1 )
#define HAVE_SETPWFILE
#endif
#endif
/*
* Are sys_errlist and sys_nerr declared in stdio.h?
*/
#ifndef SYSERRLIST_IN_STDIO
#if defined( freebsd )
#define SYSERRLIST_IN_STDIO
#endif
#endif
/*
* Is snprintf() part of the standard C runtime library?
*/
#if defined(_WINDOWS)
#define snprintf _snprintf
#endif
/*
* Async IO. Use a non blocking implementation of connect() and
* dns functions
*/
#if !defined(LDAP_ASYNC_IO)
#if !defined(_WINDOWS) && !defined(macintosh)
#define LDAP_ASYNC_IO
#endif /* _WINDOWS */
#endif
/*
* for select()
*/
#if !defined(WINSOCK) && !defined(_WINDOWS) && !defined(macintosh) && !defined(XP_OS2)
#if defined(hpux) || defined(LINUX) || defined(SUNOS4) || defined(XP_BEOS)
#include <sys/time.h>
#else
#include <sys/select.h>
#endif
#if !defined(FD_SET)
#define NFDBITS 32
#define FD_SETSIZE 32
#define FD_SET(n, p) ((p)->fds_bits[(n)/NFDBITS] |= (1 << ((n) % NFDBITS)))
#define FD_CLR(n, p) ((p)->fds_bits[(n)/NFDBITS] &= ~(1 << ((n) % NFDBITS)))
#define FD_ISSET(n, p) ((p)->fds_bits[(n)/NFDBITS] & (1 << ((n) % NFDBITS)))
#define FD_ZERO(p) bzero((char *)(p), sizeof(*(p)))
#endif /* !FD_SET */
#endif /* !WINSOCK && !_WINDOWS && !macintosh */
/*
* for connect() -- must we block signals when calling connect()? This
* is necessary on some buggy UNIXes.
*/
#if !defined(NSLDAPI_CONNECT_MUST_NOT_BE_INTERRUPTED) && \
( defined(AIX) || defined(IRIX) || defined(HPUX) || defined(SUNOS4) \
|| defined(SOLARIS) || defined(OSF1) ||defined(freebsd))
#define NSLDAPI_CONNECT_MUST_NOT_BE_INTERRUPTED
#endif
/*
* On most platforms, sigprocmask() works fine even in multithreaded code.
* But not everywhere.
*/
#ifdef AIX
#define NSLDAPI_MT_SAFE_SIGPROCMASK(h,s,o) sigthreadmask(h,s,o)
#else
#define NSLDAPI_MT_SAFE_SIGPROCMASK(h,s,o) sigprocmask(h,s,o)
#endif
/*
* toupper and tolower macros are different under bsd and sys v
*/
#if defined( SYSV ) && !defined( hpux )
#define TOUPPER(c) (isascii(c) && islower(c) ? _toupper(c) : c)
#define TOLOWER(c) (isascii(c) && isupper(c) ? _tolower(c) : c)
#else
#define TOUPPER(c) (isascii(c) && islower(c) ? toupper(c) : c)
#define TOLOWER(c) (isascii(c) && isupper(c) ? tolower(c) : c)
#endif
/*
* put a cover on the tty-related ioctl calls we need to use
*/
#if defined( NeXT ) || (defined(SunOS) && SunOS < 40)
#define TERMIO_TYPE struct sgttyb
#define TERMFLAG_TYPE int
#define GETATTR( fd, tiop ) ioctl((fd), TIOCGETP, (caddr_t)(tiop))
#define SETATTR( fd, tiop ) ioctl((fd), TIOCSETP, (caddr_t)(tiop))
#define GETFLAGS( tio ) (tio).sg_flags
#define SETFLAGS( tio, flags ) (tio).sg_flags = (flags)
#else
#define USE_TERMIOS
#define TERMIO_TYPE struct termios
#define TERMFLAG_TYPE tcflag_t
#define GETATTR( fd, tiop ) tcgetattr((fd), (tiop))
#define SETATTR( fd, tiop ) tcsetattr((fd), TCSANOW /* 0 */, (tiop))
#define GETFLAGS( tio ) (tio).c_lflag
#define SETFLAGS( tio, flags ) (tio).c_lflag = (flags)
#endif
#if ( !defined( HPUX9 )) && ( !defined( sunos4 )) && ( !defined( SNI )) && \
( !defined( HAVE_TIME_R ))
#define HAVE_TIME_R
#endif
#if defined(SNI) || defined(LINUX1_2)
int strcasecmp(const char *, const char *);
#ifdef SNI
int strncasecmp(const char *, const char *, int);
#endif /* SNI */
#ifdef LINUX1_2
int strncasecmp(const char *, const char *, size_t);
#endif /* LINUX1_2 */
#endif /* SNI || LINUX1_2 */
#if defined(_WINDOWS) || defined(macintosh) || defined(XP_OS2) || defined(DARWIN)
#define GETHOSTBYNAME( n, r, b, l, e ) gethostbyname( n )
#define NSLDAPI_CTIME( c, b, l ) ctime( c )
#define STRTOK( s1, s2, l ) strtok( s1, s2 )
#elif defined(XP_BEOS)
#define GETHOSTBYNAME( n, r, b, l, e ) gethostbyname( n )
#define NSLDAPI_CTIME( c, b, l ) ctime_r( c, b )
#define STRTOK( s1, s2, l ) strtok_r( s1, s2, l )
#define HAVE_STRTOK_R
#else /* UNIX */
#if (defined(AIX) && defined(_THREAD_SAFE)) || defined(OSF1)
#define NSLDAPI_NETDB_BUF_SIZE sizeof(struct protoent_data)
#else
#define NSLDAPI_NETDB_BUF_SIZE 1024
#endif
#if defined(sgi) || defined(HPUX9) || defined(SCOOS) || \
defined(UNIXWARE) || defined(SUNOS4) || defined(SNI) || defined(BSDI) || \
defined(NCR) || defined(OSF1) || defined(NEC) || defined(VMS) || \
( defined(HPUX10) && !defined(_REENTRANT)) || defined(HPUX11) || \
defined(UnixWare) || defined(NETBSD) || \
defined(FREEBSD) || defined(OPENBSD) || \
(defined(LINUX) && __GLIBC__ < 2) || \
(defined(AIX) && !defined(USE_REENTRANT_LIBC))
#define GETHOSTBYNAME( n, r, b, l, e ) gethostbyname( n )
#elif defined(AIX)
/* Maybe this is for another version of AIX?
Commenting out for AIX 4.1 for Nova
Replaced with following to lines, stolen from the #else below
#define GETHOSTBYNAME_BUF_T struct hostent_data
*/
typedef char GETHOSTBYNAME_buf_t [NSLDAPI_NETDB_BUF_SIZE];
#define GETHOSTBYNAME_BUF_T GETHOSTBYNAME_buf_t
#define GETHOSTBYNAME( n, r, b, l, e ) \
(memset (&b, 0, l), gethostbyname_r (n, r, &b) ? NULL : r)
#elif defined(HPUX10)
#define GETHOSTBYNAME_BUF_T struct hostent_data
#define GETHOSTBYNAME( n, r, b, l, e ) nsldapi_compat_gethostbyname_r( n, r, (char *)&b, l, e )
#elif defined(LINUX) || defined(DRAGONFLY)
typedef char GETHOSTBYNAME_buf_t [NSLDAPI_NETDB_BUF_SIZE];
#define GETHOSTBYNAME_BUF_T GETHOSTBYNAME_buf_t
#define GETHOSTBYNAME( n, r, b, l, rp, e ) gethostbyname_r( n, r, b, l, rp, e )
#define GETHOSTBYNAME_R_RETURNS_INT
#else
typedef char GETHOSTBYNAME_buf_t [NSLDAPI_NETDB_BUF_SIZE];
#define GETHOSTBYNAME_BUF_T GETHOSTBYNAME_buf_t
#define GETHOSTBYNAME( n, r, b, l, e ) gethostbyname_r( n, r, b, l, e )
#endif
#if defined(HPUX9) || defined(LINUX1_2) || defined(LINUX2_0) || \
defined(LINUX2_1) || defined(SUNOS4) || defined(SNI) || \
defined(SCOOS) || defined(BSDI) || defined(NCR) || \
defined(NEC) || ( defined(HPUX10) && !defined(_REENTRANT)) || \
(defined(AIX) && !defined(USE_REENTRANT_LIBC))
#define NSLDAPI_CTIME( c, b, l ) ctime( c )
#elif defined(HPUX10) && defined(_REENTRANT) && !defined(HPUX11)
#define NSLDAPI_CTIME( c, b, l ) nsldapi_compat_ctime_r( c, b, l )
#elif defined( IRIX6_2 ) || defined( IRIX6_3 ) || defined(UNIXWARE) \
|| defined(OSF1V4) || defined(AIX) || defined(UnixWare) \
|| defined(hpux) || defined(HPUX11) || defined(NETBSD) \
|| defined(IRIX6) || defined(FREEBSD) || defined(VMS) \
|| defined(NTO) || defined(OPENBSD) || defined(DRAGONFLY)
#define NSLDAPI_CTIME( c, b, l ) ctime_r( c, b )
#elif defined( OSF1V3 )
#define NSLDAPI_CTIME( c, b, l ) (ctime_r( c, b, l ) ? NULL : b)
#else
#define NSLDAPI_CTIME( c, b, l ) ctime_r( c, b, l )
#endif
#if defined(hpux9) || defined(SUNOS4) || defined(SNI) || \
defined(SCOOS) || defined(BSDI) || defined(NCR) || defined(VMS) || \
defined(NEC) || (defined(LINUX) && __GNU_LIBRARY__ != 6) || \
(defined(AIX) && !defined(USE_REENTRANT_LIBC))
#define STRTOK( s1, s2, l ) strtok( s1, s2 )
#else
#define HAVE_STRTOK_R
#ifndef strtok_r
char *strtok_r(char *, const char *, char **);
#endif
#define STRTOK( s1, s2, l ) (char *)strtok_r( s1, s2, l )
#endif /* STRTOK */
#endif /* UNIX */
#if defined( ultrix ) || defined( nextstep )
extern char *strdup();
#endif /* ultrix || nextstep */
#if defined( sunos4 ) || defined( OSF1 )
#define BSD_TIME 1 /* for servers/slapd/log.h */
#endif /* sunos4 || osf */
#if defined(XP_OS2)
#include <machine/endian.h> /* for htonl, et.al. */
#include <arpa/inet.h> /* for inet_addr() */
#elif !defined(_WINDOWS) && !defined(macintosh)
#include <netinet/in.h>
#if !defined(XP_BEOS)
#include <arpa/inet.h> /* for inet_addr() */
#endif
#endif
/*
* Define portable 32-bit integral types.
*/
#include <limits.h>
#if UINT_MAX >= 0xffffffffU /* an int holds at least 32 bits */
typedef signed int nsldapi_int_32;
typedef unsigned int nsldapi_uint_32;
#else /* ints are < 32 bits; use long instead */
typedef signed long nsldapi_int_32;
typedef unsigned long nsldapi_uint_32;
#endif
/*
* Define a portable type for IPv4 style Internet addresses (32 bits):
*/
#if defined(_IN_ADDR_T) || defined(aix) || defined(HPUX11) || defined(OSF1)
typedef in_addr_t nsldapi_in_addr_t;
#else
typedef nsldapi_uint_32 nsldapi_in_addr_t;
#endif
#ifdef SUNOS4
#include <pcfs/pc_dir.h> /* for toupper() */
int fprintf(FILE *, char *, ...);
int fseek(FILE *, long, int);
int fread(char *, int, int, FILE *);
int fclose(FILE *);
int fflush(FILE *);
int rewind(FILE *);
void *memmove(void *, const void *, size_t);
int strcasecmp(char *, char *);
int strncasecmp(char *, char *, int);
time_t time(time_t *);
void perror(char *);
int fputc(char, FILE *);
int fputs(char *, FILE *);
int re_exec(char *);
int socket(int, int, int);
void bzero(char *, int);
unsigned long inet_addr(char *);
char * inet_ntoa(struct in_addr);
int getdtablesize();
int connect(int, struct sockaddr *, int);
#endif /* SUNOS4 */
/* #if defined(SUNOS4) || defined(SNI) */
#if defined(SUNOS4)
int select(int, fd_set *, fd_set *, fd_set *, struct timeval *);
#endif /* SUNOS4 || SNI */
/*
* SAFEMEMCPY is an overlap-safe copy from s to d of n bytes
*/
#ifdef macintosh
#define SAFEMEMCPY( d, s, n ) BlockMoveData( (Ptr)s, (Ptr)d, n )
#else /* macintosh */
#ifdef sunos4
#define SAFEMEMCPY( d, s, n ) bcopy( s, d, n )
#else /* sunos4 */
#define SAFEMEMCPY( d, s, n ) memmove( d, s, n )
#endif /* sunos4 */
#endif /* macintosh */
#ifdef _WINDOWS
#define strcasecmp strcmpi
#define strncasecmp _strnicmp
#define bzero(a, b) memset( a, 0, b )
#define getpid _getpid
#define ioctl ioctlsocket
#define sleep(a) Sleep( a*1000 )
#define EMSGSIZE WSAEMSGSIZE
#define EWOULDBLOCK WSAEWOULDBLOCK
#define EHOSTUNREACH WSAEHOSTUNREACH
#ifndef MAXPATHLEN
#define MAXPATHLEN _MAX_PATH
#endif
/* We'd like this number to be prime for the hash
* into the Connection table */
#define DS_MAX_NT_SOCKET_CONNECTIONS 2003
#elif defined(XP_OS2)
#define strcasecmp stricmp
#define strncasecmp strnicmp
#define bzero(a, b) memset( a, 0, b )
#include <string.h> /*for strcmpi()*/
#include <time.h> /*for ctime()*/
#endif /* XP_OS2 */
/* Define a macro to support large files */
#ifdef _LARGEFILE64_SOURCE
#define NSLDAPI_FOPEN( filename, mode ) fopen64( filename, mode )
#else
#define NSLDAPI_FOPEN( filename, mode ) fopen( filename, mode )
#endif
#if defined(LINUX) || defined(AIX) || defined(HPUX) || defined(_WINDOWS)
size_t nsldapi_compat_strlcpy(char *dst, const char *src, size_t len);
#define STRLCPY nsldapi_compat_strlcpy
#else
#define STRLCPY strlcpy
#endif
#endif /* _PORTABLE_H */

View file

@ -0,0 +1,99 @@
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is Mozilla Communicator client code, released
* March 31, 1998.
*
* The Initial Developer of the Original Code is
* Netscape Communications Corporation.
* Portions created by the Initial Developer are Copyright (C) 1998-1999
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
*
* Alternatively, the contents of this file may be used under the terms of
* either of the GNU General Public License Version 2 or later (the "GPL"),
* or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
/******************************************************
*
* proto-ntutil.h - Prototypes for utility functions used
* throughout slapd on NT.
*
******************************************************/
#if defined( _WINDOWS )
#ifndef _PROTO_NTUTIL
#define _PROTO_NTUTIL
/*
*
* ntreg.c
*
*/
extern int SlapdGetRegSZ( LPTSTR lpszRegKey, LPSTR lpszValueName, LPTSTR lpszValue );
/*
*
* getopt.c
*
*/
extern int getopt (int argc, char *const *argv, const char *optstring);
/*
*
* ntevent.c
*
*/
extern BOOL MultipleInstances();
extern BOOL SlapdIsAService();
extern void InitializeSlapdLogging( LPTSTR lpszRegLocation, LPTSTR lpszEventLogName, LPTSTR lpszMessageFile );
extern void ReportSlapdEvent(WORD wEventType, DWORD dwIdEvent, WORD wNumInsertStrings,
char *pszStrings);
extern BOOL ReportSlapdStatusToSCMgr(
SERVICE_STATUS *serviceStatus,
SERVICE_STATUS_HANDLE serviceStatusHandle,
HANDLE Event,
DWORD dwCurrentState,
DWORD dwWin32ExitCode,
DWORD dwCheckPoint,
DWORD dwWaitHint);
extern void WINAPI SlapdServiceCtrlHandler(DWORD dwOpcode);
extern BOOL SlapdGetServerNameFromCmdline(char *szServerName, char *szCmdLine);
/*
*
* ntgetpassword.c
*
*/
#ifdef NET_SSL
extern char *Slapd_GetPassword();
#ifdef FORTEZZA
extern char *Slapd_GetFortezzaPIN();
#endif
extern void CenterDialog(HWND hwndParent, HWND hwndDialog);
#endif /* NET_SSL */
#endif /* _PROTO_NTUTIL */
#endif /* _WINDOWS */

View file

@ -0,0 +1,95 @@
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is Mozilla Communicator client code, released
* March 31, 1998.
*
* The Initial Developer of the Original Code is
* Netscape Communications Corporation.
* Portions created by the Initial Developer are Copyright (C) 1998-1999
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
*
* Alternatively, the contents of this file may be used under the terms of
* either of the GNU General Public License Version 2 or later (the "GPL"),
* or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
#if defined( macintosh ) || defined( DOS ) || defined( _WINDOWS ) || defined( NEED_BSDREGEX ) || defined( XP_OS2 )
/*
* Copyright (c) 1993 Regents of the University of Michigan.
* All rights reserved.
*
* Redistribution and use in source and binary forms are permitted
* provided that this notice is preserved and that due credit is given
* to the University of Michigan at Ann Arbor. The name of the University
* may not be used to endorse or promote products derived from this
* software without specific prior written permission. This software
* is provided ``as is'' without express or implied warranty.
*/
/*
* regex.h -- includes for regular expression matching routines
* 13 August 1993 Mark C Smith
*/
#ifdef __cplusplus
extern "C" {
#endif
#include "ldap.h"
#if !defined( NEEDPROTOS ) && defined( __STDC__ )
#define NEEDPROTOS
#endif
#ifdef _SLDAPD_H_ /* server build: no need to use LDAP_CALL stuff */
#ifdef LDAP_CALL
#undef LDAP_CALL
#define LDAP_CALL
#endif
#endif
#ifdef NEEDPROTOS
int re_init( void );
void re_lock( void );
int re_unlock( void );
char * LDAP_CALL re_comp( const char *pat );
int LDAP_CALL re_exec( const char *lp );
void LDAP_CALL re_modw( char *s );
int LDAP_CALL re_subs( char *src, char *dst );
#else /* NEEDPROTOS */
int re_init();
void re_lock();
int re_unlock();
char * LDAP_CALL re_comp();
int LDAP_CALL re_exec();
void LDAP_CALL re_modw();
int LDAP_CALL re_subs();
#endif /* NEEDPROTOS */
#define re_fail( m, p )
#ifdef __cplusplus
}
#endif
#endif /* macintosh or DOS or or _WIN32 or NEED_BSDREGEX */

View file

@ -0,0 +1,154 @@
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is Mozilla Communicator client code, released
* March 31, 1998.
*
* The Initial Developer of the Original Code is
* Netscape Communications Corporation.
* Portions created by the Initial Developer are Copyright (C) 1998-1999
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
*
* Alternatively, the contents of this file may be used under the terms of
* either of the GNU General Public License Version 2 or later (the "GPL"),
* or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
/*
* Copyright (c) 1993, 1994 Regents of the University of Michigan.
* All rights reserved.
*
* Redistribution and use in source and binary forms are permitted
* provided that this notice is preserved and that due credit is given
* to the University of Michigan at Ann Arbor. The name of the University
* may not be used to endorse or promote products derived from this
* software without specific prior written permission. This software
* is provided ``as is'' without express or implied warranty.
*
* searchpref.h: display template library defines
*/
#ifndef _SRCHPREF_H
#define _SRCHPREF_H
#ifdef __cplusplus
extern "C" {
#endif
/* calling conventions used by library */
#ifndef LDAP_CALL
#if defined( _WINDOWS ) || defined( _WIN32 )
#define LDAP_C __cdecl
#ifndef _WIN32
#define __stdcall _far _pascal
#define LDAP_CALLBACK _loadds
#else
#define LDAP_CALLBACK
#endif /* _WIN32 */
#define LDAP_PASCAL __stdcall
#define LDAP_CALL LDAP_PASCAL
#else /* _WINDOWS */
#define LDAP_C
#define LDAP_CALLBACK
#define LDAP_PASCAL
#define LDAP_CALL
#endif /* _WINDOWS */
#endif /* LDAP_CALL */
struct ldap_searchattr {
char *sa_attrlabel;
char *sa_attr;
/* max 32 matchtypes for now */
unsigned long sa_matchtypebitmap;
char *sa_selectattr;
char *sa_selecttext;
struct ldap_searchattr *sa_next;
};
struct ldap_searchmatch {
char *sm_matchprompt;
char *sm_filter;
struct ldap_searchmatch *sm_next;
};
struct ldap_searchobj {
char *so_objtypeprompt;
unsigned long so_options;
char *so_prompt;
short so_defaultscope;
char *so_filterprefix;
char *so_filtertag;
char *so_defaultselectattr;
char *so_defaultselecttext;
struct ldap_searchattr *so_salist;
struct ldap_searchmatch *so_smlist;
struct ldap_searchobj *so_next;
};
#define NULLSEARCHOBJ ((struct ldap_searchobj *)0)
/*
* global search object options
*/
#define LDAP_SEARCHOBJ_OPT_INTERNAL 0x00000001
#define LDAP_IS_SEARCHOBJ_OPTION_SET( so, option ) \
(((so)->so_options & option ) != 0 )
#define LDAP_SEARCHPREF_VERSION_ZERO 0
#define LDAP_SEARCHPREF_VERSION 1
#define LDAP_SEARCHPREF_ERR_VERSION 1
#define LDAP_SEARCHPREF_ERR_MEM 2
#define LDAP_SEARCHPREF_ERR_SYNTAX 3
#define LDAP_SEARCHPREF_ERR_FILE 4
LDAP_API(int)
LDAP_CALL
ldap_init_searchprefs( char *file, struct ldap_searchobj **solistp );
LDAP_API(int)
LDAP_CALL
ldap_init_searchprefs_buf( char *buf, long buflen,
struct ldap_searchobj **solistp );
LDAP_API(void)
LDAP_CALL
ldap_free_searchprefs( struct ldap_searchobj *solist );
LDAP_API(struct ldap_searchobj *)
LDAP_CALL
ldap_first_searchobj( struct ldap_searchobj *solist );
LDAP_API(struct ldap_searchobj *)
LDAP_CALL
ldap_next_searchobj( struct ldap_searchobj *sollist,
struct ldap_searchobj *so );
#ifdef __cplusplus
}
#endif
#endif /* _SRCHPREF_H */

View file

@ -0,0 +1,102 @@
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is Mozilla Communicator client code, released
* March 31, 1998.
*
* The Initial Developer of the Original Code is
* Netscape Communications Corporation.
* Portions created by the Initial Developer are Copyright (C) 1998-1999
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
*
* Alternatively, the contents of this file may be used under the terms of
* either of the GNU General Public License Version 2 or later (the "GPL"),
* or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
/* bprint.c - a printing utility for debuging output */
#include <string.h>
#include "lber-int.h"
#ifdef LDAP_DEBUG
/*
* Print arbitrary stuff, for debugging.
*/
#define BPLEN 48
void
lber_bprint( char *data, int len )
{
static char hexdig[] = "0123456789abcdef";
char out[ BPLEN ];
int i = 0;
memset( out, 0, BPLEN );
for ( ;; ) {
if ( len < 1 ) {
char msg[BPLEN + 80];
sprintf( msg, "\t%s\n", ( i == 0 ) ? "(end)" : out );
ber_err_print( msg );
break;
}
#ifndef HEX
if ( isgraph( (unsigned char)*data )) {
out[ i ] = ' ';
out[ i+1 ] = *data;
} else {
#endif
out[ i ] = hexdig[ ( *data & 0xf0 ) >> 4 ];
out[ i+1 ] = hexdig[ *data & 0x0f ];
#ifndef HEX
}
#endif
i += 2;
len--;
data++;
if ( i > BPLEN - 2 ) {
char msg[BPLEN + 80];
sprintf( msg, "\t%s\n", out );
ber_err_print( msg );
memset( out, 0, BPLEN );
i = 0;
continue;
}
out[ i++ ] = ' ';
}
}
#endif
void ber_err_print( char *data )
{
#ifdef USE_DEBUG_WIN
OutputDebugString( data );
#else
fputs( data, stderr );
fflush( stderr );
#endif
}

View file

@ -0,0 +1,833 @@
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is Mozilla Communicator client code, released
* March 31, 1998.
*
* The Initial Developer of the Original Code is
* Netscape Communications Corporation.
* Portions created by the Initial Developer are Copyright (C) 1998-1999
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
*
* Alternatively, the contents of this file may be used under the terms of
* either of the GNU General Public License Version 2 or later (the "GPL"),
* or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
/*
* Copyright (c) 1990 Regents of the University of Michigan.
* All rights reserved.
*
* Redistribution and use in source and binary forms are permitted
* provided that this notice is preserved and that due credit is given
* to the University of Michigan at Ann Arbor. The name of the University
* may not be used to endorse or promote products derived from this
* software without specific prior written permission. This software
* is provided ``as is'' without express or implied warranty.
*/
/* decode.c - ber input decoding routines */
#include "lber-int.h"
/*
* Note: ber_get_tag() only uses the ber_end and ber_ptr elements of ber.
* If that changes, the ber_peek_tag() and/or ber_skip_tag() implementations
* will need to be changed.
*/
/* return the tag - LBER_DEFAULT returned means trouble */
ber_tag_t
LDAP_CALL
ber_get_tag( BerElement *ber )
{
unsigned char xbyte;
ber_tag_t tag;
char *tagp;
int i;
if ( ber_read( ber, (char *) &xbyte, 1 ) != 1 )
return( LBER_DEFAULT );
if ( (xbyte & LBER_BIG_TAG_MASK) != LBER_BIG_TAG_MASK )
return( (ber_uint_t) xbyte );
tagp = (char *) &tag;
tagp[0] = xbyte;
for ( i = 1; i < sizeof(ber_int_t); i++ ) {
if ( ber_read( ber, (char *) &xbyte, 1 ) != 1 )
return( LBER_DEFAULT );
tagp[i] = xbyte;
if ( ! (xbyte & LBER_MORE_TAG_MASK) )
break;
}
/* tag too big! */
if ( i == sizeof(ber_int_t) )
return( LBER_DEFAULT );
/* want leading, not trailing 0's */
return( tag >> (sizeof(ber_int_t) - i - 1) );
}
/*
* Note: ber_skip_tag() only uses the ber_end and ber_ptr elements of ber.
* If that changes, the implementation of ber_peek_tag() will need to
* be changed.
*/
ber_tag_t
LDAP_CALL
ber_skip_tag( BerElement *ber, ber_len_t *len )
{
ber_tag_t tag;
unsigned char lc;
int noctets, diff;
ber_len_t netlen;
/*
* Any ber element looks like this: tag length contents.
* Assuming everything's ok, we return the tag byte (we
* can assume a single byte), and return the length in len.
*
* Assumptions:
* 1) definite lengths
* 2) primitive encodings used whenever possible
*/
/*
* First, we read the tag.
*/
if ( (tag = ber_get_tag( ber )) == LBER_DEFAULT )
return( LBER_DEFAULT );
/*
* Next, read the length. The first byte contains the length of
* the length. If bit 8 is set, the length is the long form,
* otherwise it's the short form. We don't allow a length that's
* greater than what we can hold in an unsigned long.
*/
*len = netlen = 0;
if ( ber_read( ber, (char *) &lc, 1 ) != 1 )
return( LBER_DEFAULT );
if ( lc & 0x80 ) {
noctets = (lc & 0x7f);
if ( noctets > sizeof(ber_uint_t) )
return( LBER_DEFAULT );
diff = sizeof(ber_int_t) - noctets;
if ( ber_read( ber, (char *) &netlen + diff, noctets )
!= noctets )
return( LBER_DEFAULT );
*len = LBER_NTOHL( netlen );
} else {
*len = lc;
}
return( tag );
}
/*
* Note: Previously, we passed the "ber" parameter directly to ber_skip_tag(),
* saving and restoring the ber_ptr element only. We now take advantage
* of the fact that the only ber structure elements touched by ber_skip_tag()
* are ber_end and ber_ptr. If that changes, this code must change too.
*/
ber_tag_t
LDAP_CALL
ber_peek_tag( BerElement *ber, ber_len_t *len )
{
BerElement bercopy;
bercopy.ber_end = ber->ber_end;
bercopy.ber_ptr = ber->ber_ptr;
return( ber_skip_tag( &bercopy, len ));
}
static int
ber_getnint( BerElement *ber, ber_int_t *num, ber_slen_t len )
{
int i;
ber_int_t value;
unsigned char buffer[sizeof(ber_int_t)];
/*
* The tag and length have already been stripped off. We should
* be sitting right before len bytes of 2's complement integer,
* ready to be read straight into an int. We may have to sign
* extend after we read it in.
*/
if ( len > sizeof(ber_slen_t) )
return( -1 );
/* read into the low-order bytes of netnum */
if ( ber_read( ber, (char *) buffer, len ) != len )
return( -1 );
/* This sets the required sign extension */
if ( len != 0) {
value = 0x80 & buffer[0] ? (-1) : 0;
} else {
value = 0;
}
for ( i = 0; i < len; i++ )
value = (value << 8) | buffer[i];
*num = value;
return( len );
}
ber_tag_t
LDAP_CALL
ber_get_int( BerElement *ber, ber_int_t *num )
{
ber_tag_t tag;
ber_len_t len;
if ( (tag = ber_skip_tag( ber, &len )) == LBER_DEFAULT )
return( LBER_DEFAULT );
/*
* len is being demoted to a long here -- possible conversion error
*/
if ( ber_getnint( ber, num, (int)len ) != (ber_slen_t)len )
return( LBER_DEFAULT );
else
return( tag );
}
ber_tag_t
LDAP_CALL
ber_get_stringb( BerElement *ber, char *buf, ber_len_t *len )
{
ber_len_t datalen;
ber_tag_t tag;
#ifdef STR_TRANSLATION
char *transbuf;
#endif /* STR_TRANSLATION */
if ( (tag = ber_skip_tag( ber, &datalen )) == LBER_DEFAULT )
return( LBER_DEFAULT );
if ( datalen > (*len - 1) )
return( LBER_DEFAULT );
/*
* datalen is being demoted to a long here -- possible conversion error
*/
if ( ber_read( ber, buf, datalen ) != (ber_slen_t) datalen )
return( LBER_DEFAULT );
buf[datalen] = '\0';
#ifdef STR_TRANSLATION
if ( datalen > 0 && ( ber->ber_options & LBER_OPT_TRANSLATE_STRINGS )
!= 0 && ber->ber_decode_translate_proc != NULL ) {
transbuf = buf;
++datalen;
if ( (*(ber->ber_decode_translate_proc))( &transbuf, &datalen,
0 ) != 0 ) {
return( LBER_DEFAULT );
}
if ( datalen > *len ) {
NSLBERI_FREE( transbuf );
return( LBER_DEFAULT );
}
SAFEMEMCPY( buf, transbuf, datalen );
NSLBERI_FREE( transbuf );
--datalen;
}
#endif /* STR_TRANSLATION */
*len = datalen;
return( tag );
}
ber_tag_t
LDAP_CALL
ber_get_stringa( BerElement *ber, char **buf )
{
ber_len_t datalen, ndatalen;
ber_tag_t tag;
if ( (tag = ber_skip_tag( ber, &datalen )) == LBER_DEFAULT )
return( LBER_DEFAULT );
if ( ((ndatalen = (size_t)datalen + 1) < (size_t) datalen) ||
( datalen > (ber->ber_end - ber->ber_ptr) ) ||
( (*buf = (char *)NSLBERI_MALLOC( (size_t)ndatalen )) == NULL ))
return( LBER_DEFAULT );
/*
* datalen is being demoted to a long here -- possible conversion error
*/
if ( ber_read( ber, *buf, datalen ) != (ber_slen_t) datalen ) {
NSLBERI_FREE( *buf );
*buf = NULL;
return( LBER_DEFAULT );
}
(*buf)[datalen] = '\0';
#ifdef STR_TRANSLATION
if ( datalen > 0 && ( ber->ber_options & LBER_OPT_TRANSLATE_STRINGS )
!= 0 && ber->ber_decode_translate_proc != NULL ) {
++datalen;
if ( (*(ber->ber_decode_translate_proc))( buf, &datalen, 1 )
!= 0 ) {
NSLBERI_FREE( *buf );
*buf = NULL;
return( LBER_DEFAULT );
}
}
#endif /* STR_TRANSLATION */
return( tag );
}
ber_tag_t
LDAP_CALL
ber_get_stringal( BerElement *ber, struct berval **bv )
{
ber_len_t len, nlen;
ber_tag_t tag;
if ( (*bv = (struct berval *)NSLBERI_MALLOC( sizeof(struct berval) ))
== NULL ) {
return( LBER_DEFAULT );
}
(*bv)->bv_val = NULL;
(*bv)->bv_len = 0;
if ( (tag = ber_skip_tag( ber, &len )) == LBER_DEFAULT ) {
NSLBERI_FREE( *bv );
*bv = NULL;
return( LBER_DEFAULT );
}
if ( ((nlen = (size_t) len + 1) < (size_t)len) ||
( len > (ber->ber_end - ber->ber_ptr) ) ||
(((*bv)->bv_val = (char *)NSLBERI_MALLOC( (size_t)nlen ))
== NULL )) {
NSLBERI_FREE( *bv );
*bv = NULL;
return( LBER_DEFAULT );
}
/*
* len is being demoted to a long here -- possible conversion error
*/
if ( ber_read( ber, (*bv)->bv_val, len ) != (ber_slen_t) len ) {
NSLBERI_FREE( (*bv)->bv_val );
(*bv)->bv_val = NULL;
NSLBERI_FREE( *bv );
*bv = NULL;
return( LBER_DEFAULT );
}
((*bv)->bv_val)[len] = '\0';
(*bv)->bv_len = len;
#ifdef STR_TRANSLATION
if ( len > 0 && ( ber->ber_options & LBER_OPT_TRANSLATE_STRINGS ) != 0
&& ber->ber_decode_translate_proc != NULL ) {
++len;
if ( (*(ber->ber_decode_translate_proc))( &((*bv)->bv_val),
&len, 1 ) != 0 ) {
NSLBERI_FREE( (*bv)->bv_val );
(*bv)->bv_val = NULL;
NSLBERI_FREE( *bv );
*bv = NULL;
return( LBER_DEFAULT );
}
(*bv)->bv_len = len - 1;
}
#endif /* STR_TRANSLATION */
return( tag );
}
ber_tag_t
LDAP_CALL
ber_get_bitstringa( BerElement *ber, char **buf, ber_len_t *blen )
{
ber_len_t datalen;
ber_tag_t tag;
unsigned char unusedbits;
if ( (tag = ber_skip_tag( ber, &datalen )) == LBER_DEFAULT )
return( LBER_DEFAULT );
--datalen;
if ( (datalen > (ber->ber_end - ber->ber_ptr)) ||
( (*buf = (char *)NSLBERI_MALLOC((size_t)datalen )) == NULL ) )
return( LBER_DEFAULT );
if ( ber_read( ber, (char *)&unusedbits, 1 ) != 1 ) {
NSLBERI_FREE( *buf );
*buf = NULL;
return( LBER_DEFAULT );
}
/*
* datalen is being demoted to a long here -- possible conversion error
*/
if ( ber_read( ber, *buf, datalen ) != (ber_slen_t) datalen ) {
NSLBERI_FREE( *buf );
*buf = NULL;
return( LBER_DEFAULT );
}
*blen = datalen * 8 - unusedbits;
return( tag );
}
ber_tag_t
LDAP_CALL
ber_get_null( BerElement *ber )
{
ber_len_t len;
ber_tag_t tag;
if ( (tag = ber_skip_tag( ber, &len )) == LBER_DEFAULT )
return( LBER_DEFAULT );
if ( len != 0 )
return( LBER_DEFAULT );
return( tag );
}
ber_tag_t
LDAP_CALL
ber_get_boolean( BerElement *ber, ber_int_t *boolval )
{
int rc;
rc = ber_get_int( ber, boolval );
return( rc );
}
ber_tag_t
LDAP_CALL
ber_first_element( BerElement *ber, ber_len_t *len, char **last )
{
/* skip the sequence header, use the len to mark where to stop */
if ( ber_skip_tag( ber, len ) == LBER_DEFAULT ) {
return( LBER_ERROR );
}
*last = ber->ber_ptr + *len;
if ( *last == ber->ber_ptr ) {
return( LBER_END_OF_SEQORSET );
}
return( ber_peek_tag( ber, len ) );
}
ber_tag_t
LDAP_CALL
ber_next_element( BerElement *ber, ber_len_t *len, char *last )
{
if ( ber->ber_ptr == last ) {
return( LBER_END_OF_SEQORSET );
}
return( ber_peek_tag( ber, len ) );
}
/* VARARGS */
ber_tag_t
LDAP_C
ber_scanf( BerElement *ber, const char *fmt, ... )
{
va_list ap;
char *last, *p;
char *s, **ss, ***sss;
struct berval ***bv, **bvp, *bval;
int *i, j;
ber_int_t *l, rc, tag;
ber_tag_t *t;
ber_len_t len;
size_t array_size;
va_start( ap, fmt );
#ifdef LDAP_DEBUG
if ( lber_debug & 64 ) {
char msg[80];
sprintf( msg, "ber_scanf fmt (%s) ber:\n", fmt );
ber_err_print( msg );
ber_dump( ber, 1 );
}
#endif
for ( rc = 0, p = (char *) fmt; *p && rc != LBER_DEFAULT; p++ ) {
switch ( *p ) {
case 'a': /* octet string - allocate storage as needed */
ss = va_arg( ap, char ** );
rc = ber_get_stringa( ber, ss );
break;
case 'b': /* boolean */
i = va_arg( ap, int * );
rc = ber_get_boolean( ber, i );
break;
case 'e': /* enumerated */
case 'i': /* int */
l = va_arg( ap, ber_slen_t * );
rc = ber_get_int( ber, l );
break;
case 'l': /* length of next item */
l = va_arg( ap, ber_slen_t * );
rc = ber_peek_tag( ber, (ber_len_t *)l );
break;
case 'n': /* null */
rc = ber_get_null( ber );
break;
case 's': /* octet string - in a buffer */
s = va_arg( ap, char * );
l = va_arg( ap, ber_slen_t * );
rc = ber_get_stringb( ber, s, (ber_len_t *)l );
break;
case 'o': /* octet string in a supplied berval */
bval = va_arg( ap, struct berval * );
ber_peek_tag( ber, &bval->bv_len );
rc = ber_get_stringa( ber, &bval->bv_val );
break;
case 'O': /* octet string - allocate & include length */
bvp = va_arg( ap, struct berval ** );
rc = ber_get_stringal( ber, bvp );
break;
case 'B': /* bit string - allocate storage as needed */
ss = va_arg( ap, char ** );
l = va_arg( ap, ber_slen_t * ); /* for length, in bits */
rc = ber_get_bitstringa( ber, ss, (ber_len_t *)l );
break;
case 't': /* tag of next item */
t = va_arg( ap, ber_tag_t * );
*t = rc = ber_peek_tag( ber, &len );
break;
case 'T': /* skip tag of next item */
t = va_arg( ap, ber_tag_t * );
*t = rc = ber_skip_tag( ber, &len );
break;
case 'v': /* sequence of strings */
sss = va_arg( ap, char *** );
*sss = NULL;
j = 0;
array_size = 0;
for ( tag = ber_first_element( ber, &len, &last );
tag != LBER_DEFAULT && tag != LBER_END_OF_SEQORSET
&& rc != LBER_DEFAULT;
tag = ber_next_element( ber, &len, last ) ) {
if ( *sss == NULL ) {
/* Make room for at least 15 strings */
*sss = (char **)NSLBERI_MALLOC(16 * sizeof(char *) );
if (!*sss) {
rc = LBER_DEFAULT;
break; /* out of memory - cannot continue */
}
array_size = 16;
} else {
char **save_sss = *sss;
if ( (size_t)(j+2) > array_size) {
/* We'v overflowed our buffer */
*sss = (char **)NSLBERI_REALLOC( *sss, (array_size * 2) * sizeof(char *) );
array_size = array_size * 2;
}
if (!*sss) {
rc = LBER_DEFAULT;
ber_svecfree(save_sss);
break; /* out of memory - cannot continue */
}
}
(*sss)[j] = NULL;
rc = ber_get_stringa( ber, &((*sss)[j]) );
j++;
}
if ( rc != LBER_DEFAULT &&
tag != LBER_END_OF_SEQORSET ) {
rc = LBER_DEFAULT;
}
if ( *sss && (j > 0) ) {
(*sss)[j] = NULL;
}
break;
case 'V': /* sequence of strings + lengths */
bv = va_arg( ap, struct berval *** );
*bv = NULL;
j = 0;
for ( tag = ber_first_element( ber, &len, &last );
tag != LBER_DEFAULT && tag != LBER_END_OF_SEQORSET
&& rc != LBER_DEFAULT;
tag = ber_next_element( ber, &len, last ) ) {
if ( *bv == NULL ) {
*bv = (struct berval **)NSLBERI_MALLOC(
2 * sizeof(struct berval *) );
if (!*bv) {
rc = LBER_DEFAULT;
break; /* out of memory - cannot continue */
}
} else {
struct berval **save_bv = *bv;
*bv = (struct berval **)NSLBERI_REALLOC(
*bv,
(j + 2) * sizeof(struct berval *) );
if (!*bv) {
rc = LBER_DEFAULT;
ber_bvecfree(save_bv);
break; /* out of memory - cannot continue */
}
}
rc = ber_get_stringal( ber, &((*bv)[j]) );
j++;
}
if ( rc != LBER_DEFAULT &&
tag != LBER_END_OF_SEQORSET ) {
rc = LBER_DEFAULT;
}
if ( *bv && (j > 0) ) {
(*bv)[j] = NULL;
}
break;
case 'x': /* skip the next element - whatever it is */
if ( (rc = ber_skip_tag( ber, &len )) == LBER_DEFAULT )
break;
ber->ber_ptr += len;
break;
case '{': /* begin sequence */
case '[': /* begin set */
if ( *(p + 1) != 'v' && *(p + 1) != 'V' )
rc = ber_skip_tag( ber, &len );
break;
case '}': /* end sequence */
case ']': /* end set */
break;
default:
{
char msg[80];
sprintf( msg, "unknown fmt %c\n", *p );
ber_err_print( msg );
}
rc = LBER_DEFAULT;
break;
}
}
va_end( ap );
if (rc == LBER_DEFAULT) {
va_start( ap, fmt );
for ( p--; fmt < p && *fmt; fmt++ ) {
switch ( *fmt ) {
case 'a': /* octet string - allocate storage as needed */
ss = va_arg( ap, char ** );
NSLBERI_FREE(*ss);
*ss = NULL;
break;
case 'b': /* boolean */
i = va_arg( ap, int * );
break;
case 'e': /* enumerated */
case 'i': /* int */
l = va_arg( ap, ber_slen_t * );
break;
case 'l': /* length of next item */
l = va_arg( ap, ber_slen_t * );
break;
case 'n': /* null */
break;
case 's': /* octet string - in a buffer */
s = va_arg( ap, char * );
l = va_arg( ap, ber_slen_t * );
break;
case 'o': /* octet string in a supplied berval */
bval = va_arg( ap, struct berval * );
if (bval->bv_val) NSLBERI_FREE(bval->bv_val);
memset(bval, 0, sizeof(struct berval));
break;
case 'O': /* octet string - allocate & include length */
bvp = va_arg( ap, struct berval ** );
ber_bvfree(*bvp);
bvp = NULL;
break;
case 'B': /* bit string - allocate storage as needed */
ss = va_arg( ap, char ** );
l = va_arg( ap, ber_slen_t * ); /* for length, in bits */
if (*ss) NSLBERI_FREE(*ss);
*ss = NULL;
break;
case 't': /* tag of next item */
t = va_arg( ap, ber_tag_t * );
break;
case 'T': /* skip tag of next item */
t = va_arg( ap, ber_tag_t * );
break;
case 'v': /* sequence of strings */
sss = va_arg( ap, char *** );
ber_svecfree(*sss);
*sss = NULL;
break;
case 'V': /* sequence of strings + lengths */
bv = va_arg( ap, struct berval *** );
ber_bvecfree(*bv);
*bv = NULL;
break;
case 'x': /* skip the next element - whatever it is */
break;
case '{': /* begin sequence */
case '[': /* begin set */
break;
case '}': /* end sequence */
case ']': /* end set */
break;
default:
break;
}
} /* for */
va_end( ap );
} /* if */
return( rc );
}
void
LDAP_CALL
ber_bvfree( struct berval *bv )
{
if ( bv != NULL ) {
if ( bv->bv_val != NULL ) {
NSLBERI_FREE( bv->bv_val );
}
NSLBERI_FREE( (char *) bv );
}
}
void
LDAP_CALL
ber_bvecfree( struct berval **bv )
{
int i;
if ( bv != NULL ) {
for ( i = 0; bv[i] != NULL; i++ ) {
ber_bvfree( bv[i] );
}
NSLBERI_FREE( (char *) bv );
}
}
struct berval *
LDAP_CALL
ber_bvdup( const struct berval *bv )
{
struct berval *new;
if ( (new = (struct berval *)NSLBERI_MALLOC( sizeof(struct berval) ))
== NULL ) {
return( NULL );
}
if ( bv->bv_val == NULL ) {
new->bv_val = NULL;
new->bv_len = 0;
} else {
if ( (new->bv_val = (char *)NSLBERI_MALLOC( bv->bv_len + 1 ))
== NULL ) {
NSLBERI_FREE( new );
new = NULL;
return( NULL );
}
SAFEMEMCPY( new->bv_val, bv->bv_val, (size_t) bv->bv_len );
new->bv_val[bv->bv_len] = '\0';
new->bv_len = bv->bv_len;
}
return( new );
}
void
LDAP_CALL
ber_svecfree( char **vals )
{
int i;
if ( vals == NULL )
return;
for ( i = 0; vals[i] != NULL; i++ )
NSLBERI_FREE( vals[i] );
NSLBERI_FREE( (char *) vals );
}
#ifdef STR_TRANSLATION
void
LDAP_CALL
ber_set_string_translators(
BerElement *ber,
BERTranslateProc encode_proc,
BERTranslateProc decode_proc
)
{
ber->ber_encode_translate_proc = encode_proc;
ber->ber_decode_translate_proc = decode_proc;
}
#endif /* STR_TRANSLATION */

View file

@ -0,0 +1,113 @@
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is Mozilla Communicator client code, released
* March 31, 1998.
*
* The Initial Developer of the Original Code is
* Netscape Communications Corporation.
* Portions created by the Initial Developer are Copyright (C) 1998-1999
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
*
* Alternatively, the contents of this file may be used under the terms of
* either of the GNU General Public License Version 2 or later (the "GPL"),
* or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
/*
* Copyright (c) 1990 Regents of the University of Michigan.
* All rights reserved.
*
* Redistribution and use in source and binary forms are permitted
* provided that this notice is preserved and that due credit is given
* to the University of Michigan at Ann Arbor. The name of the University
* may not be used to endorse or promote products derived from this
* software without specific prior written permission. This software
* is provided ``as is'' without express or implied warranty.
*/
/* dtest.c - lber decoding test program */
#include <stdio.h>
#include <string.h>
#ifdef MACOS
#include <stdlib.h>
#include <console.h>
#else /* MACOS */
#ifdef _WIN32
#include <windows.h>
#else
#include <sys/types.h>
#include <sys/socket.h>
#endif /* _WIN32 */
#endif /* MACOS */
#include "lber.h"
int
SSL_Recv( int s, char *b, unsigned l, int dummy )
{
return( read( s, b, l ) );
}
SSL_Send( int s, char *b, unsigned l, int dummy )
{
return( write( s, b, l ) );
}
static void usage( char *name )
{
fprintf( stderr, "usage: %s < berfile\n", name );
}
main( int argc, char **argv )
{
long i, fd;
ber_len_t len;
ber_tag_t tag;
BerElement *ber;
Sockbuf *sb;
extern int lber_debug;
lber_debug = 255;
if ( argc > 1 ) {
usage( argv[0] );
exit( 1 );
}
sb = ber_sockbuf_alloc();
fd = 0;
ber_sockbuf_set_option( sb, LBER_SOCKBUF_OPT_DESC, &fd );
if ( (ber = der_alloc()) == NULL ) {
perror( "ber_alloc" );
exit( 1 );
}
if ( (tag = ber_get_next( sb, &len, ber )) == LBER_ERROR ) {
perror( "ber_get_next" );
exit( 1 );
}
printf( "message has tag 0x%x and length %ld\n", tag, len );
return( 0 );
}

View file

@ -0,0 +1,699 @@
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is Mozilla Communicator client code, released
* March 31, 1998.
*
* The Initial Developer of the Original Code is
* Netscape Communications Corporation.
* Portions created by the Initial Developer are Copyright (C) 1998-1999
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
*
* Alternatively, the contents of this file may be used under the terms of
* either of the GNU General Public License Version 2 or later (the "GPL"),
* or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
/*
* Copyright (c) 1990 Regents of the University of Michigan.
* All rights reserved.
*
* Redistribution and use in source and binary forms are permitted
* provided that this notice is preserved and that due credit is given
* to the University of Michigan at Ann Arbor. The name of the University
* may not be used to endorse or promote products derived from this
* software without specific prior written permission. This software
* is provided ``as is'' without express or implied warranty.
*/
/* encode.c - ber output encoding routines */
#include "lber-int.h"
static int
ber_calc_taglen( ber_tag_t tag )
{
int i;
ber_int_t mask;
/* find the first non-all-zero byte in the tag */
for ( i = sizeof(ber_int_t) - 1; i > 0; i-- ) {
mask = (0xff << (i * 8));
/* not all zero */
if ( tag & mask )
break;
}
return( i + 1 );
}
static int
ber_put_tag( BerElement *ber, ber_tag_t tag, int nosos )
{
int taglen;
ber_tag_t ntag;
taglen = ber_calc_taglen( tag );
ntag = LBER_HTONL( tag );
return( ber_write( ber, ((char *) &ntag) + sizeof(ber_int_t) - taglen,
taglen, nosos ) );
}
static int
ber_calc_lenlen( ber_len_t len )
{
/*
* short len if it's less than 128 - one byte giving the len,
* with bit 8 0.
*/
if ( len <= 0x7F )
return( 1 );
/*
* long len otherwise - one byte with bit 8 set, giving the
* length of the length, followed by the length itself.
*/
if ( len <= 0xFF )
return( 2 );
if ( len <= 0xFFFF )
return( 3 );
if ( len <= 0xFFFFFF )
return( 4 );
return( 5 );
}
static int
ber_put_len( BerElement *ber, ber_len_t len, int nosos )
{
int i;
char lenlen;
ber_int_t mask;
ber_len_t netlen;
/*
* short len if it's less than 128 - one byte giving the len,
* with bit 8 0.
*/
if ( len <= 127 ) {
netlen = LBER_HTONL( len );
return( ber_write( ber, (char *) &netlen + sizeof(ber_int_t) - 1,
1, nosos ) );
}
/*
* long len otherwise - one byte with bit 8 set, giving the
* length of the length, followed by the length itself.
*/
/* find the first non-all-zero byte */
for ( i = sizeof(ber_int_t) - 1; i > 0; i-- ) {
mask = (0xff << (i * 8));
/* not all zero */
if ( len & mask )
break;
}
lenlen = ++i;
if ( lenlen > 4 )
return( -1 );
lenlen |= 0x80;
/* write the length of the length */
if ( ber_write( ber, &lenlen, 1, nosos ) != 1 )
return( -1 );
/* write the length itself */
netlen = LBER_HTONL( len );
if ( ber_write( ber, (char *) &netlen + (sizeof(ber_int_t) - i), i, nosos )
!= i )
return( -1 );
return( i + 1 );
}
static int
ber_put_int_or_enum( BerElement *ber, ber_int_t num, ber_tag_t tag )
{
int i, sign, taglen;
int len, lenlen;
ber_int_t netnum, mask;
sign = (num < 0);
/*
* high bit is set - look for first non-all-one byte
* high bit is clear - look for first non-all-zero byte
*/
for ( i = sizeof(ber_int_t) - 1; i > 0; i-- ) {
mask = (0xff << (i * 8));
if ( sign ) {
/* not all ones */
if ( (num & mask) != mask )
break;
} else {
/* not all zero */
if ( num & mask )
break;
}
}
/*
* we now have the "leading byte". if the high bit on this
* byte matches the sign bit, we need to "back up" a byte.
*/
mask = (num & (0x80 << (i * 8)));
if ( (mask && !sign) || (sign && !mask) )
i++;
len = i + 1;
if ( (taglen = ber_put_tag( ber, tag, 0 )) == -1 )
return( -1 );
if ( (lenlen = ber_put_len( ber, len, 0 )) == -1 )
return( -1 );
i++;
netnum = LBER_HTONL( num );
if ( ber_write( ber, (char *) &netnum + (sizeof(ber_int_t) - i), i, 0 )
== i)
/* length of tag + length + contents */
return( taglen + lenlen + i );
return( -1 );
}
int
LDAP_CALL
ber_put_enum( BerElement *ber, ber_int_t num, ber_tag_t tag )
{
if ( tag == LBER_DEFAULT )
tag = LBER_ENUMERATED;
return( ber_put_int_or_enum( ber, num, tag ) );
}
int
LDAP_CALL
ber_put_int( BerElement *ber, ber_int_t num, ber_tag_t tag )
{
if ( tag == LBER_DEFAULT )
tag = LBER_INTEGER;
return( ber_put_int_or_enum( ber, num, tag ) );
}
int
LDAP_CALL
ber_put_ostring( BerElement *ber, char *str, ber_len_t len,
ber_tag_t tag )
{
int taglen, lenlen, rc;
#ifdef STR_TRANSLATION
int free_str;
#endif /* STR_TRANSLATION */
if ( tag == LBER_DEFAULT )
tag = LBER_OCTETSTRING;
if ( (taglen = ber_put_tag( ber, tag, 0 )) == -1 )
return( -1 );
#ifdef STR_TRANSLATION
if ( len > 0 && ( ber->ber_options & LBER_OPT_TRANSLATE_STRINGS ) != 0
&& ber->ber_encode_translate_proc != NULL ) {
if ( (*(ber->ber_encode_translate_proc))( &str, &len, 0 )
!= 0 ) {
return( -1 );
}
free_str = 1;
} else {
free_str = 0;
}
#endif /* STR_TRANSLATION */
/*
* Note: below is a spot where we limit ber_write
* to signed long (instead of unsigned long)
*/
if ( (lenlen = ber_put_len( ber, len, 0 )) == -1 ||
ber_write( ber, str, len, 0 ) != (ber_int_t) len ) {
rc = -1;
} else {
/* return length of tag + length + contents */
rc = taglen + lenlen + len;
}
#ifdef STR_TRANSLATION
if ( free_str ) {
NSLBERI_FREE( str );
}
#endif /* STR_TRANSLATION */
return( rc );
}
int
LDAP_CALL
ber_put_string( BerElement *ber, char *str, ber_tag_t tag )
{
return( ber_put_ostring( ber, str, (ber_len_t) strlen( str ), tag ));
}
int
LDAP_CALL
ber_put_bitstring( BerElement *ber, char *str,
ber_len_t blen /* in bits */, ber_tag_t tag )
{
int taglen, lenlen, len;
unsigned char unusedbits;
if ( tag == LBER_DEFAULT )
tag = LBER_BITSTRING;
if ( (taglen = ber_put_tag( ber, tag, 0 )) == -1 )
return( -1 );
len = ( blen + 7 ) / 8;
unusedbits = (unsigned char) (len * 8 - blen);
if ( (lenlen = ber_put_len( ber, len + 1, 0 )) == -1 )
return( -1 );
if ( ber_write( ber, (char *)&unusedbits, 1, 0 ) != 1 )
return( -1 );
if ( ber_write( ber, str, len, 0 ) != len )
return( -1 );
/* return length of tag + length + unused bit count + contents */
return( taglen + 1 + lenlen + len );
}
int
LDAP_CALL
ber_put_null( BerElement *ber, ber_tag_t tag )
{
int taglen;
if ( tag == LBER_DEFAULT )
tag = LBER_NULL;
if ( (taglen = ber_put_tag( ber, tag, 0 )) == -1 )
return( -1 );
if ( ber_put_len( ber, 0, 0 ) != 1 )
return( -1 );
return( taglen + 1 );
}
int
LDAP_CALL
ber_put_boolean( BerElement *ber, ber_int_t boolval, ber_tag_t tag )
{
int taglen;
unsigned char trueval = 0xff;
unsigned char falseval = 0x00;
if ( tag == LBER_DEFAULT )
tag = LBER_BOOLEAN;
if ( (taglen = ber_put_tag( ber, tag, 0 )) == -1 )
return( -1 );
if ( ber_put_len( ber, 1, 0 ) != 1 )
return( -1 );
if ( ber_write( ber, (char *)(boolval ? &trueval : &falseval), 1, 0 )
!= 1 )
return( -1 );
return( taglen + 2 );
}
#define FOUR_BYTE_LEN 5
/* the idea here is roughly this: we maintain a stack of these Seqorset
* structures. This is pushed when we see the beginning of a new set or
* sequence. It is popped when we see the end of a set or sequence.
* Since we don't want to malloc and free these structures all the time,
* we pre-allocate a small set of them within the ber element structure.
* thus we need to spot when we've overflowed this stack and fall back to
* malloc'ing instead.
*/
static int
ber_start_seqorset( BerElement *ber, ber_tag_t tag )
{
Seqorset *new_sos;
/* can we fit into the local stack ? */
if (ber->ber_sos_stack_posn < SOS_STACK_SIZE) {
/* yes */
new_sos = &ber->ber_sos_stack[ber->ber_sos_stack_posn];
} else {
/* no */
if ( (new_sos = (Seqorset *)NSLBERI_MALLOC( sizeof(Seqorset)))
== NULLSEQORSET ) {
return( -1 );
}
}
ber->ber_sos_stack_posn++;
if ( ber->ber_sos == NULLSEQORSET )
new_sos->sos_first = ber->ber_ptr;
else
new_sos->sos_first = ber->ber_sos->sos_ptr;
/* Set aside room for a 4 byte length field */
new_sos->sos_ptr = new_sos->sos_first + ber_calc_taglen( tag ) + FOUR_BYTE_LEN;
new_sos->sos_tag = tag;
new_sos->sos_next = ber->ber_sos;
new_sos->sos_clen = 0;
ber->ber_sos = new_sos;
if (ber->ber_sos->sos_ptr > ber->ber_end) {
nslberi_ber_realloc(ber, ber->ber_sos->sos_ptr - ber->ber_end);
}
return( 0 );
}
int
LDAP_CALL
ber_start_seq( BerElement *ber, ber_tag_t tag )
{
if ( tag == LBER_DEFAULT )
tag = LBER_SEQUENCE;
return( ber_start_seqorset( ber, tag ) );
}
int
LDAP_CALL
ber_start_set( BerElement *ber, ber_tag_t tag )
{
if ( tag == LBER_DEFAULT )
tag = LBER_SET;
return( ber_start_seqorset( ber, tag ) );
}
static int
ber_put_seqorset( BerElement *ber )
{
ber_len_t len, netlen;
int taglen, lenlen;
unsigned char ltag = 0x80 + FOUR_BYTE_LEN - 1;
Seqorset *next;
Seqorset **sos = &ber->ber_sos;
if ( *sos == NULL ) {
/* No sequence or set to put... fatal error. */
return( -1 );
}
/*
* If this is the toplevel sequence or set, we need to actually
* write the stuff out. Otherwise, it's already been put in
* the appropriate buffer and will be written when the toplevel
* one is written. In this case all we need to do is update the
* length and tag.
*/
len = (*sos)->sos_clen;
netlen = LBER_HTONL( len );
if ( sizeof(ber_int_t) > 4 && len > 0xFFFFFFFF )
return( -1 );
if ( ber->ber_options & LBER_OPT_USE_DER ) {
lenlen = ber_calc_lenlen( len );
} else {
lenlen = FOUR_BYTE_LEN;
}
if ( (next = (*sos)->sos_next) == NULLSEQORSET ) {
/* write the tag */
if ( (taglen = ber_put_tag( ber, (*sos)->sos_tag, 1 )) == -1 )
return( -1 );
if ( ber->ber_options & LBER_OPT_USE_DER ) {
/* Write the length in the minimum # of octets */
if ( ber_put_len( ber, len, 1 ) == -1 )
return( -1 );
if (lenlen != FOUR_BYTE_LEN) {
/*
* We set aside FOUR_BYTE_LEN bytes for
* the length field. Move the data if
* we don't actually need that much
*/
SAFEMEMCPY( (*sos)->sos_first + taglen +
lenlen, (*sos)->sos_first + taglen +
FOUR_BYTE_LEN, len );
}
} else {
/* Fill FOUR_BYTE_LEN bytes for length field */
/* one byte of length length */
if ( ber_write( ber, (char *)&ltag, 1, 1 ) != 1 )
return( -1 );
/* the length itself */
if ( ber_write( ber, (char *) &netlen + sizeof(ber_int_t)
- (FOUR_BYTE_LEN - 1), FOUR_BYTE_LEN - 1, 1 )
!= FOUR_BYTE_LEN - 1 )
return( -1 );
}
/* The ber_ptr is at the set/seq start - move it to the end */
ber->ber_ptr += len;
} else {
ber_tag_t ntag;
/* the tag */
taglen = ber_calc_taglen( (*sos)->sos_tag );
ntag = LBER_HTONL( (*sos)->sos_tag );
SAFEMEMCPY( (*sos)->sos_first, (char *) &ntag +
sizeof(ber_int_t) - taglen, taglen );
if ( ber->ber_options & LBER_OPT_USE_DER ) {
ltag = (lenlen == 1) ? (unsigned char)len :
(unsigned char) (0x80 + (lenlen - 1));
}
/* one byte of length length */
SAFEMEMCPY( (*sos)->sos_first + 1, &ltag, 1 );
if ( ber->ber_options & LBER_OPT_USE_DER ) {
if (lenlen > 1) {
/* Write the length itself */
SAFEMEMCPY( (*sos)->sos_first + 2,
(char *)&netlen + sizeof(ber_uint_t) -
(lenlen - 1),
lenlen - 1 );
}
if (lenlen != FOUR_BYTE_LEN) {
/*
* We set aside FOUR_BYTE_LEN bytes for
* the length field. Move the data if
* we don't actually need that much
*/
SAFEMEMCPY( (*sos)->sos_first + taglen +
lenlen, (*sos)->sos_first + taglen +
FOUR_BYTE_LEN, len );
}
} else {
/* the length itself */
SAFEMEMCPY( (*sos)->sos_first + taglen + 1,
(char *) &netlen + sizeof(ber_int_t) -
(FOUR_BYTE_LEN - 1), FOUR_BYTE_LEN - 1 );
}
next->sos_clen += (taglen + lenlen + len);
next->sos_ptr += (taglen + lenlen + len);
}
/* we're done with this seqorset, so free it up */
/* was this one from the local stack ? */
if (ber->ber_sos_stack_posn <= SOS_STACK_SIZE) {
/* yes */
} else {
/* no */
NSLBERI_FREE( (char *) (*sos) );
}
ber->ber_sos_stack_posn--;
*sos = next;
return( taglen + lenlen + len );
}
int
LDAP_CALL
ber_put_seq( BerElement *ber )
{
return( ber_put_seqorset( ber ) );
}
int
LDAP_CALL
ber_put_set( BerElement *ber )
{
return( ber_put_seqorset( ber ) );
}
/* VARARGS */
int
LDAP_C
ber_printf( BerElement *ber, const char *fmt, ... )
{
va_list ap;
char *s, **ss;
struct berval *bval, **bv;
int rc, i;
ber_len_t len;
va_start( ap, fmt );
#ifdef LDAP_DEBUG
if ( lber_debug & 64 ) {
char msg[80];
sprintf( msg, "ber_printf fmt (%s)\n", fmt );
ber_err_print( msg );
}
#endif
for ( rc = 0; *fmt && rc != -1; fmt++ ) {
switch ( *fmt ) {
case 'b': /* boolean */
i = va_arg( ap, int );
rc = ber_put_boolean( ber, i, ber->ber_tag );
break;
case 'i': /* int */
i = va_arg( ap, int );
rc = ber_put_int( ber, (ber_int_t)i, ber->ber_tag );
break;
case 'e': /* enumeration */
i = va_arg( ap, int );
rc = ber_put_enum( ber, (ber_int_t)i, ber->ber_tag );
break;
case 'n': /* null */
rc = ber_put_null( ber, ber->ber_tag );
break;
case 'o': /* octet string (non-null terminated) */
s = va_arg( ap, char * );
len = va_arg( ap, int );
rc = ber_put_ostring( ber, s, len, ber->ber_tag );
break;
case 'O': /* berval octet string */
if( ( bval = va_arg( ap, struct berval * ) ) == NULL )
break;
if( bval->bv_len == 0 ) {
rc = ber_put_ostring( ber, "", 0, ber->ber_tag );
} else {
rc = ber_put_ostring( ber, bval->bv_val, bval->bv_len,
ber->ber_tag );
}
break;
case 's': /* string */
s = va_arg( ap, char * );
rc = ber_put_string( ber, s, ber->ber_tag );
break;
case 'B': /* bit string */
s = va_arg( ap, char * );
len = va_arg( ap, int ); /* in bits */
rc = ber_put_bitstring( ber, s, len, ber->ber_tag );
break;
case 't': /* tag for the next element */
ber->ber_tag = va_arg( ap, ber_tag_t );
ber->ber_usertag = 1;
break;
case 'v': /* vector of strings */
if ( (ss = va_arg( ap, char ** )) == NULL )
break;
for ( i = 0; ss[i] != NULL; i++ ) {
if ( (rc = ber_put_string( ber, ss[i],
ber->ber_tag )) == -1 )
break;
}
break;
case 'V': /* sequences of strings + lengths */
if ( (bv = va_arg( ap, struct berval ** )) == NULL )
break;
for ( i = 0; bv[i] != NULL; i++ ) {
if ( (rc = ber_put_ostring( ber, bv[i]->bv_val,
bv[i]->bv_len, ber->ber_tag )) == -1 )
break;
}
break;
case '{': /* begin sequence */
rc = ber_start_seq( ber, ber->ber_tag );
break;
case '}': /* end sequence */
rc = ber_put_seqorset( ber );
break;
case '[': /* begin set */
rc = ber_start_set( ber, ber->ber_tag );
break;
case ']': /* end set */
rc = ber_put_seqorset( ber );
break;
default: {
char msg[80];
sprintf( msg, "unknown fmt %c\n", *fmt );
ber_err_print( msg );
rc = -1;
break;
}
}
if ( ber->ber_usertag == 0 )
ber->ber_tag = LBER_DEFAULT;
else
ber->ber_usertag = 0;
}
va_end( ap );
return( rc );
}

View file

@ -0,0 +1,193 @@
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is Mozilla Communicator client code, released
* March 31, 1998.
*
* The Initial Developer of the Original Code is
* Netscape Communications Corporation.
* Portions created by the Initial Developer are Copyright (C) 1998-1999
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
*
* Alternatively, the contents of this file may be used under the terms of
* either of the GNU General Public License Version 2 or later (the "GPL"),
* or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
/*
* Copyright (c) 1990 Regents of the University of Michigan.
* All rights reserved.
* Redistribution and use in source and binary forms are permitted
* provided that this notice is preserved and that due credit is given
* to the University of Michigan at Ann Arbor. The name of the University
* may not be used to endorse or promote products derived from this
* software without specific prior written permission. This software
* is provided ``as is'' without express or implied warranty.
*/
/* test.c - lber encoding test program */
#include <stdio.h>
#include <string.h>
#ifdef MACOS
#include <stdlib.h>
#include <unix.h>
#include <fcntl.h>
#include <console.h>
#else /* MACOS */
#include <sys/types.h>
#ifdef _WIN32
#include <windows.h>
#else
#include <sys/socket.h>
#endif /* _WIN32 */
#endif /* MACOS */
#include "lber.h"
int
SSL_Recv( int s, char *b, unsigned l, int dummy )
{
return( read( s, b, l ) );
}
SSL_Send( int s, char *b, unsigned l, int dummy )
{
return( write( s, b, l ) );
}
int
getline( char *prompt, char c, char *buf, int bsize )
{
char *p;
if ( prompt != NULL ) {
fprintf( stderr, "%s: ", prompt );
} else {
fprintf( stderr, "enter value for '%c': ", c );
}
if ( fgets( buf, bsize, stdin ) == NULL ) {
return( -1 );
}
if ( (p = strchr( buf, '\n' )) != NULL ) {
*p = '\0';
}
return( 0 );
}
static void usage( char *name )
{
fprintf( stderr, "usage: %s fmtstring\n", name );
}
main( int argc, char **argv )
{
int rc, fd;
char *s, *p;
void *arg1, *arg2;
Sockbuf *sb;
BerElement *ber;
char fmt[2];
char buf[BUFSIZ];
extern int lber_debug;
lber_debug = 255;
if ( argc < 2 ) {
usage( argv[0] );
exit( 1 );
}
sb = ber_sockbuf_alloc();
fd = 1;
ber_sockbuf_set_option( sb, LBER_SOCKBUF_OPT_DESC, &fd );
if ( (ber = der_alloc()) == NULL ) {
perror( "ber_alloc" );
exit( 1 );
}
rc = 0;
fmt[1] = '\0';
for ( s = argv[1]; *s; s++ ) {
switch ( *s ) {
case 'i': /* int */
case 'b': /* boolean */
case 'e': /* enumeration */
getline( NULL, *s, buf, sizeof(buf) );
arg1 = (void *) atoi( buf );
break;
case 'n': /* null */
arg1 = NULL;
break;
case 'o': /* octet string (non-null terminated) */
getline( NULL, *s, buf, sizeof(buf) );
arg1 = (void *) buf;
arg2 = (void *) strlen( buf );
break;
case 's': /* string */
getline( NULL, *s, buf, sizeof(buf) );
arg1 = (void *) buf;
break;
case 'B': /* bit string */
getline( NULL, *s, buf, sizeof(buf) );
arg1 = (void *) buf;
arg2 = (void *) strlen( buf );
break;
case 't': /* tag for the next element */
getline( NULL, *s, buf, sizeof(buf) );
arg1 = (void *) buf;
break;
case '{': /* begin sequence */
case '}': /* end sequence */
case '[': /* begin set */
case ']': /* end set */
break;
default:
fprintf( stderr, "unknown fmt %c\n", *s );
rc = -1;
break;
}
fmt[0] = *s;
if ( ber_printf( ber, fmt, arg1, arg2 ) == -1 ) {
fprintf( stderr, "ber_printf\n" );
exit( 1 );
}
}
if ( ber_flush( sb, ber, 1 ) != 0 ) {
perror( "ber_flush" );
rc = -1;
}
return( rc );
}

View file

@ -0,0 +1,100 @@
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is Mozilla Communicator client code, released
* March 31, 1998.
*
* The Initial Developer of the Original Code is
* Netscape Communications Corporation.
* Portions created by the Initial Developer are Copyright (C) 1998-1999
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
*
* Alternatively, the contents of this file may be used under the terms of
* either of the GNU General Public License Version 2 or later (the "GPL"),
* or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
/*
* Copyright (c) 1990 Regents of the University of Michigan.
* All rights reserved.
*
* Redistribution and use in source and binary forms are permitted
* provided that this notice is preserved and that due credit is given
* to the University of Michigan at Ann Arbor. The name of the University
* may not be used to endorse or promote products derived from this
* software without specific prior written permission. This software
* is provided ``as is'' without express or implied warranty.
*/
/* idtest.c - ber decoding test program using isode libraries */
#include <stdio.h>
#include <psap.h>
#include <quipu/attr.h>
static usage( char *name )
{
fprintf( stderr, "usage: %s\n", name );
}
main( int argc, char **argv )
{
PE pe;
PS psin, psout, pserr;
/* read the pe from standard in */
if ( (psin = ps_alloc( std_open )) == NULLPS ) {
perror( "ps_alloc" );
exit( 1 );
}
if ( std_setup( psin, stdin ) == NOTOK ) {
perror( "std_setup" );
exit( 1 );
}
/* write the pe to standard out */
if ( (psout = ps_alloc( std_open )) == NULLPS ) {
perror( "ps_alloc" );
exit( 1 );
}
if ( std_setup( psout, stdout ) == NOTOK ) {
perror( "std_setup" );
exit( 1 );
}
/* pretty print it to standard error */
if ( (pserr = ps_alloc( std_open )) == NULLPS ) {
perror( "ps_alloc" );
exit( 1 );
}
if ( std_setup( pserr, stderr ) == NOTOK ) {
perror( "std_setup" );
exit( 1 );
}
while ( (pe = ps2pe( psin )) != NULLPE ) {
pe2pl( pserr, pe );
pe2ps( psout, pe );
}
exit( 0 );
}

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,305 @@
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is Mozilla Communicator client code, released
* March 31, 1998.
*
* The Initial Developer of the Original Code is
* Netscape Communications Corporation.
* Portions created by the Initial Developer are Copyright (C) 1998-1999
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
*
* Alternatively, the contents of this file may be used under the terms of
* either of the GNU General Public License Version 2 or later (the "GPL"),
* or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
/*
* Copyright (c) 1990 Regents of the University of Michigan.
* All rights reserved.
*
* Redistribution and use in source and binary forms are permitted
* provided that this notice is preserved and that due credit is given
* to the University of Michigan at Ann Arbor. The name of the University
* may not be used to endorse or promote products derived from this
* software without specific prior written permission. This software
* is provided ``as is'' without express or implied warranty.
*/
/* lbet-int.h - internal header file for liblber */
#ifndef _LBERINT_H
#define _LBERINT_H
#ifdef __cplusplus
extern "C" {
#endif
#include <stdio.h>
#include <ctype.h>
#include <stdarg.h>
#include <stdlib.h>
#ifdef macintosh
# include "ldap-macos.h"
#else /* macintosh */
#if !defined(BSDI) && !defined(DARWIN) && !defined(FREEBSD) && !defined(OPENBSD)
# include <malloc.h>
#endif
# include <errno.h>
# include <sys/types.h>
#if defined(SUNOS4) || defined(SCOOS)
# include <sys/time.h>
#endif
#if defined( _WINDOWS )
# define WIN32_LEAN_AND_MEAN
# include <windows.h>
# include <basetsd.h>
# define ssize_t SSIZE_T
# include <time.h>
/* No stderr in a 16-bit Windows DLL */
# if defined(_WINDLL) && !defined(_WIN32)
# define USE_DBG_WIN
# endif
# else
/* # include <sys/varargs.h> */
# include <sys/socket.h>
# include <netinet/in.h>
#if !defined(XP_OS2) && !defined(DARWIN)
# include <unistd.h>
#endif
# endif /* defined( _WINDOWS ) */
#endif /* macintosh */
#include <memory.h>
#include <string.h>
#include "portable.h"
#ifdef _WINDOWS
# if defined(FD_SETSIZE)
# else
# define FD_SETSIZE 256 /* set it before winsock sets it to 64! */
# endif
#include <winsock.h>
#include <io.h>
#endif /* _WINDOWS */
#ifdef XP_OS2
#include <io.h>
#endif /* XP_OS2 */
/* No stderr in a 16-bit Windows DLL */
#if defined(_WINDLL) && !defined(_WIN32)
#define stderr NULL
#endif
#include "lber.h"
#ifdef macintosh
#define NSLDAPI_LBER_SOCKET_IS_PTR
#endif
#define OLD_LBER_SEQUENCE 0x10 /* w/o constructed bit - broken */
#define OLD_LBER_SET 0x11 /* w/o constructed bit - broken */
#ifndef _IFP
#define _IFP
typedef int (LDAP_C LDAP_CALLBACK *IFP)();
#endif
typedef struct seqorset {
ber_len_t sos_clen;
ber_tag_t sos_tag;
char *sos_first;
char *sos_ptr;
struct seqorset *sos_next;
} Seqorset;
#define NULLSEQORSET ((Seqorset *) 0)
#define SOS_STACK_SIZE 8 /* depth of the pre-allocated sos structure stack */
#define MAX_TAG_SIZE (1 + sizeof(ber_int_t)) /* One byte for the length of the tag */
#define MAX_LEN_SIZE (1 + sizeof(ber_int_t)) /* One byte for the length of the length */
#define MAX_VALUE_PREFIX_SIZE (2 + sizeof(ber_int_t)) /* 1 byte for the tag and 1 for the len (msgid) */
#define BER_ARRAY_QUANTITY 7 /* 0:Tag 1:Length 2:Value-prefix 3:Value 4:Value-suffix */
#define BER_STRUCT_TAG 0 /* 5:ControlA 6:ControlB */
#define BER_STRUCT_LEN 1
#define BER_STRUCT_PRE 2
#define BER_STRUCT_VAL 3
#define BER_STRUCT_SUF 4
#define BER_STRUCT_CO1 5
#define BER_STRUCT_CO2 6
struct berelement {
ldap_x_iovec ber_struct[BER_ARRAY_QUANTITY]; /* See above */
char ber_tag_contents[MAX_TAG_SIZE];
char ber_len_contents[MAX_LEN_SIZE];
char ber_pre_contents[MAX_VALUE_PREFIX_SIZE];
char ber_suf_contents[MAX_LEN_SIZE+1];
char *ber_buf; /* update the value value when writing in case realloc is called */
char *ber_ptr;
char *ber_end;
struct seqorset *ber_sos;
ber_len_t ber_tag_len_read;
ber_tag_t ber_tag; /* Remove me someday */
ber_len_t ber_len; /* Remove me someday */
int ber_usertag;
char ber_options;
char *ber_rwptr;
BERTranslateProc ber_encode_translate_proc;
BERTranslateProc ber_decode_translate_proc;
int ber_flags;
#define LBER_FLAG_NO_FREE_BUFFER 1 /* don't free ber_buf */
unsigned int ber_buf_reallocs; /* realloc counter */
int ber_sos_stack_posn;
Seqorset ber_sos_stack[SOS_STACK_SIZE];
};
#define BER_CONTENTS_STRUCT_SIZE (sizeof(ldap_x_iovec) * BER_ARRAY_QUANTITY)
#define NULLBER ((BerElement *)NULL)
#ifdef LDAP_DEBUG
void ber_dump( BerElement *ber, int inout );
#endif
/*
* structure for read/write I/O callback functions.
*/
struct nslberi_io_fns {
LDAP_IOF_READ_CALLBACK *lbiof_read;
LDAP_IOF_WRITE_CALLBACK *lbiof_write;
};
/*
* Old structure for use with LBER_SOCKBUF_OPT_EXT_IO_FNS:
*/
struct lber_x_ext_io_fns_rev0 {
/* lbextiofn_size should always be set to LBER_X_EXTIO_FNS_SIZE */
int lbextiofn_size;
LDAP_X_EXTIOF_READ_CALLBACK *lbextiofn_read;
LDAP_X_EXTIOF_WRITE_CALLBACK *lbextiofn_write;
struct lextiof_socket_private *lbextiofn_socket_arg;
};
#define LBER_X_EXTIO_FNS_SIZE_REV0 sizeof(struct lber_x_ext_io_fns_rev0)
struct sockbuf {
LBER_SOCKET sb_sd;
BerElement sb_ber;
int sb_naddr; /* > 0 implies using CLDAP (UDP) */
void *sb_useaddr; /* pointer to sockaddr to use next */
void *sb_fromaddr; /* pointer to message source sockaddr */
void **sb_addrs; /* actually an array of pointers to
sockaddrs */
int sb_options; /* to support copying ber elements */
LBER_SOCKET sb_copyfd; /* for LBER_SOCKBUF_OPT_TO_FILE* opts */
ber_len_t sb_max_incoming;
ber_tag_t sb_valid_tag; /* valid tag to accept */
struct nslberi_io_fns
sb_io_fns; /* classic I/O callback functions */
struct lber_x_ext_io_fns
sb_ext_io_fns; /* extended I/O callback functions */
};
#define NULLSOCKBUF ((Sockbuf *)NULL)
/* needed by libldap, even in non-DEBUG builds */
void ber_err_print( char *data );
#ifndef NSLBERI_LBER_INT_FRIEND
/*
* Everything from this point on is excluded if NSLBERI_LBER_INT_FRIEND is
* defined. The code under ../libraries/libldap defines this.
*/
#define READBUFSIZ 8192
/*
* macros used to check validity of data structures and parameters
*/
#define NSLBERI_VALID_BERELEMENT_POINTER( ber ) \
( (ber) != NULLBER )
#define NSLBERI_VALID_SOCKBUF_POINTER( sb ) \
( (sb) != NULLSOCKBUF )
#define LBER_HTONL( l ) htonl( l )
#define LBER_NTOHL( l ) ntohl( l )
/* function prototypes */
#ifdef LDAP_DEBUG
void lber_bprint( char *data, int len );
#endif
void ber_err_print( char *data );
void *nslberi_malloc( size_t size );
void *nslberi_calloc( size_t nelem, size_t elsize );
void *nslberi_realloc( void *ptr, size_t size );
void nslberi_free( void *ptr );
int nslberi_ber_realloc( BerElement *ber, ber_len_t len );
/* blame: dboreham
* slapd spends much of its time doing memcpy's for the ber code.
* Most of these are single-byte, so we special-case those and speed
* things up considerably.
*/
#ifdef sunos4
#define THEMEMCPY( d, s, n ) bcopy( s, d, n )
#else /* sunos4 */
#define THEMEMCPY( d, s, n ) memmove( d, s, n )
#endif /* sunos4 */
#ifdef SAFEMEMCPY
#undef SAFEMEMCPY
#define SAFEMEMCPY(d,s,n) if (1 == n) *((char*)d) = *((char*)s); else THEMEMCPY(d,s,n);
#endif
/*
* Memory allocation done in liblber should all go through one of the
* following macros. This is so we can plug-in alternative memory
* allocators, etc. as the need arises.
*/
#define NSLBERI_MALLOC( size ) nslberi_malloc( size )
#define NSLBERI_CALLOC( nelem, elsize ) nslberi_calloc( nelem, elsize )
#define NSLBERI_REALLOC( ptr, size ) nslberi_realloc( ptr, size )
#define NSLBERI_FREE( ptr ) nslberi_free( ptr )
/* allow the library to access the debug variable */
extern int lber_debug;
#endif /* !NSLBERI_LBER_INT_FRIEND */
#ifdef __cplusplus
}
#endif
#endif /* _LBERINT_H */

View file

@ -0,0 +1,23 @@
# vim: set filetype=python:
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
include('/ldap/ldap-sdk.mozbuild')
Library('lber60')
SOURCES += [
'bprint.c',
'decode.c',
'encode.c',
'io.c',
]
DEFINES['USE_WAITPID'] = True
DEFINES['NEEDPROTOS'] = True
LOCAL_INCLUDES += [
'/ldap/c-sdk/include'
]

View file

@ -0,0 +1,303 @@
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is Mozilla Communicator client code, released
* March 31, 1998.
*
* The Initial Developer of the Original Code is
* Netscape Communications Corporation.
* Portions created by the Initial Developer are Copyright (C) 1998-1999
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
*
* Alternatively, the contents of this file may be used under the terms of
* either of the GNU General Public License Version 2 or later (the "GPL"),
* or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
/*
* Copyright (c) 1990 Regents of the University of Michigan.
* All rights reserved.
*/
/*
* abandon.c
*/
#if 0
#ifndef lint
static char copyright[] = "@(#) Copyright (c) 1990 Regents of the University of Michigan.\nAll rights reserved.\n";
#endif
#endif
#include "ldap-int.h"
static int do_abandon( LDAP *ld, int origid, int msgid,
LDAPControl **serverctrls, LDAPControl **clientctrls );
static int nsldapi_send_abandon_message( LDAP *ld, LDAPConn *lc,
BerElement *ber, int abandon_msgid );
/*
* ldap_abandon - perform an ldap abandon operation. Parameters:
*
* ld LDAP descriptor
* msgid The message id of the operation to abandon
*
* ldap_abandon returns 0 if everything went ok, -1 otherwise.
*
* Example:
* ldap_abandon( ld, msgid );
*/
int
LDAP_CALL
ldap_abandon( LDAP *ld, int msgid )
{
LDAPDebug( LDAP_DEBUG_TRACE, "ldap_abandon %d\n", msgid, 0, 0 );
LDAPDebug( LDAP_DEBUG_TRACE, "4e65747363617065\n", msgid, 0, 0 );
LDAPDebug( LDAP_DEBUG_TRACE, "466f726576657221\n", msgid, 0, 0 );
if ( ldap_abandon_ext( ld, msgid, NULL, NULL ) == LDAP_SUCCESS ) {
return( 0 );
}
return( -1 );
}
/*
* LDAPv3 extended abandon.
* Returns an LDAP error code.
*/
int
LDAP_CALL
ldap_abandon_ext( LDAP *ld, int msgid, LDAPControl **serverctrls,
LDAPControl **clientctrls )
{
int rc;
LDAPDebug( LDAP_DEBUG_TRACE, "ldap_abandon_ext %d\n", msgid, 0, 0 );
if ( !NSLDAPI_VALID_LDAP_POINTER( ld )) {
return( LDAP_PARAM_ERROR );
}
LDAP_MUTEX_LOCK( ld, LDAP_CONN_LOCK );
LDAP_MUTEX_LOCK( ld, LDAP_REQ_LOCK );
rc = do_abandon( ld, msgid, msgid, serverctrls, clientctrls );
/*
* XXXmcs should use cache function pointers to hook in memcache
*/
ldap_memcache_abandon( ld, msgid );
LDAP_MUTEX_UNLOCK( ld, LDAP_REQ_LOCK );
LDAP_MUTEX_UNLOCK( ld, LDAP_CONN_LOCK );
return( rc );
}
/*
* Abandon all outstanding requests for msgid (included child requests
* spawned when chasing referrals). This function calls itself recursively.
* No locking is done is this function so it must be done by the caller.
* Returns an LDAP error code and sets it in LDAP *ld as well
*/
static int
do_abandon( LDAP *ld, int origid, int msgid, LDAPControl **serverctrls,
LDAPControl **clientctrls )
{
BerElement *ber;
int i, bererr, lderr, sendabandon;
LDAPRequest *lr = NULL;
/*
* An abandon request looks like this:
* AbandonRequest ::= MessageID
*/
LDAPDebug( LDAP_DEBUG_TRACE, "do_abandon origid %d, msgid %d\n",
origid, msgid, 0 );
/* optimistic */
lderr = LDAP_SUCCESS;
/*
* Find the request that we are abandoning. Don't send an
* abandon message unless there is something to abandon.
*/
sendabandon = 0;
for ( lr = ld->ld_requests; lr != NULL; lr = lr->lr_next ) {
if ( lr->lr_msgid == msgid ) { /* this message */
if ( origid == msgid && lr->lr_parent != NULL ) {
/* don't let caller abandon child requests! */
lderr = LDAP_PARAM_ERROR;
goto set_errorcode_and_return;
}
if ( lr->lr_status == LDAP_REQST_INPROGRESS ) {
/*
* We only need to send an abandon message if
* the request is in progress.
*/
sendabandon = 1;
}
break;
}
if ( lr->lr_origid == msgid ) { /* child: abandon it */
(void)do_abandon( ld, msgid, lr->lr_msgid,
serverctrls, clientctrls );
/* we ignore errors from child abandons... */
}
}
if ( ldap_msgdelete( ld, msgid ) == 0 ) {
/* we had all the results and deleted them */
goto set_errorcode_and_return;
}
if ( lr != NULL && sendabandon ) {
/* create a message to send */
if (( lderr = nsldapi_alloc_ber_with_options( ld, &ber )) ==
LDAP_SUCCESS ) {
int abandon_msgid;
LDAP_MUTEX_LOCK( ld, LDAP_MSGID_LOCK );
abandon_msgid = ++ld->ld_msgid;
LDAP_MUTEX_UNLOCK( ld, LDAP_MSGID_LOCK );
#ifdef CLDAP
if ( ld->ld_dbp->sb_naddr > 0 ) {
bererr = ber_printf( ber, "{isti",
abandon_msgid, ld->ld_cldapdn,
LDAP_REQ_ABANDON, msgid );
} else {
#endif /* CLDAP */
bererr = ber_printf( ber, "{iti",
abandon_msgid, LDAP_REQ_ABANDON, msgid );
#ifdef CLDAP
}
#endif /* CLDAP */
if ( bererr == -1 ||
( lderr = nsldapi_put_controls( ld, serverctrls,
1, ber )) != LDAP_SUCCESS ) {
lderr = LDAP_ENCODING_ERROR;
ber_free( ber, 1 );
} else {
/* try to send the message */
lderr = nsldapi_send_abandon_message( ld,
lr->lr_conn, ber, abandon_msgid );
}
}
}
if ( lr != NULL ) {
/*
* Always call nsldapi_free_connection() so that the connection's
* ref count is correctly decremented. It is OK to always pass
* 1 for the "unbind" parameter because doing so will only affect
* connections that resulted from a child request (because the
* default connection's ref count never goes to zero).
*/
nsldapi_free_connection( ld, lr->lr_conn, NULL, NULL,
0 /* do not force */, 1 /* send unbind before closing */ );
/*
* Free the entire request chain if we finished abandoning everything.
*/
if ( origid == msgid ) {
nsldapi_free_request( ld, lr, 0 );
}
}
/*
* Record the abandoned message ID (used to discard any server responses
* that arrive later).
*/
LDAP_MUTEX_LOCK( ld, LDAP_ABANDON_LOCK );
if ( ld->ld_abandoned == NULL ) {
if ( (ld->ld_abandoned = (int *)NSLDAPI_MALLOC( 2
* sizeof(int) )) == NULL ) {
lderr = LDAP_NO_MEMORY;
LDAP_MUTEX_UNLOCK( ld, LDAP_ABANDON_LOCK );
goto set_errorcode_and_return;
}
i = 0;
} else {
for ( i = 0; ld->ld_abandoned[i] != -1; i++ )
; /* NULL */
if ( (ld->ld_abandoned = (int *)NSLDAPI_REALLOC( (char *)
ld->ld_abandoned, (i + 2) * sizeof(int) )) == NULL ) {
lderr = LDAP_NO_MEMORY;
LDAP_MUTEX_UNLOCK( ld, LDAP_ABANDON_LOCK );
goto set_errorcode_and_return;
}
}
ld->ld_abandoned[i] = msgid;
ld->ld_abandoned[i + 1] = -1;
LDAP_MUTEX_UNLOCK( ld, LDAP_ABANDON_LOCK );
set_errorcode_and_return:
LDAP_SET_LDERRNO( ld, lderr, NULL, NULL );
return( lderr );
}
/*
* Try to send the abandon message that is encoded in ber. Returns an
* LDAP result code.
*/
static int
nsldapi_send_abandon_message( LDAP *ld, LDAPConn *lc, BerElement *ber,
int abandon_msgid )
{
int lderr = LDAP_SUCCESS;
int err = 0;
err = nsldapi_send_ber_message( ld, lc->lconn_sb,
ber, 1 /* free ber */, 0 /* will not handle EPIPE */ );
if ( err == -2 ) {
/*
* "Would block" error. Queue the abandon as
* a pending request.
*/
LDAPRequest *lr;
lr = nsldapi_new_request( lc, ber, abandon_msgid,
0 /* no response expected */ );
if ( lr == NULL ) {
lderr = LDAP_NO_MEMORY;
ber_free( ber, 1 );
} else {
lr->lr_status = LDAP_REQST_WRITING;
nsldapi_queue_request_nolock( ld, lr );
++lc->lconn_pending_requests;
nsldapi_iostatus_interest_write( ld,
lc->lconn_sb );
}
} else if ( err != 0 ) {
/*
* Fatal error (not a "would block" error).
*/
lderr = LDAP_SERVER_DOWN;
ber_free( ber, 1 );
}
return( lderr );
}

View file

@ -0,0 +1,225 @@
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is Mozilla Communicator client code, released
* March 31, 1998.
*
* The Initial Developer of the Original Code is
* Netscape Communications Corporation.
* Portions created by the Initial Developer are Copyright (C) 1998-1999
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
*
* Alternatively, the contents of this file may be used under the terms of
* either of the GNU General Public License Version 2 or later (the "GPL"),
* or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
/*
* Copyright (c) 1990 Regents of the University of Michigan.
* All rights reserved.
*/
/*
* add.c
*/
#if 0
#ifndef lint
static char copyright[] = "@(#) Copyright (c) 1990 Regents of the University of Michigan.\nAll rights reserved.\n";
#endif
#endif
#include "ldap-int.h"
/*
* ldap_add - initiate an ldap add operation. Parameters:
*
* ld LDAP descriptor
* dn DN of the entry to add
* mods List of attributes for the entry. This is a null-
* terminated array of pointers to LDAPMod structures.
* only the type and values in the structures need be
* filled in.
*
* Example:
* LDAPMod *attrs[] = {
* { 0, "cn", { "babs jensen", "babs", 0 } },
* { 0, "sn", { "jensen", 0 } },
* { 0, "objectClass", { "person", 0 } },
* 0
* }
* msgid = ldap_add( ld, dn, attrs );
*/
int
LDAP_CALL
ldap_add( LDAP *ld, const char *dn, LDAPMod **attrs )
{
int msgid;
LDAPDebug( LDAP_DEBUG_TRACE, "ldap_add\n", 0, 0, 0 );
if ( ldap_add_ext( ld, dn, attrs, NULL, NULL, &msgid )
== LDAP_SUCCESS ) {
return( msgid );
} else {
return( -1 ); /* error is in ld handle */
}
}
/*
* LDAPv3 extended add.
* Returns an LDAP error code.
*/
int
LDAP_CALL
ldap_add_ext( LDAP *ld, const char *dn, LDAPMod **attrs,
LDAPControl **serverctrls, LDAPControl **clientctrls, int *msgidp )
{
BerElement *ber;
int i, rc, lderr;
/*
* An add request looks like this:
* AddRequest ::= SEQUENCE {
* entry DistinguishedName,
* attrs SEQUENCE OF SEQUENCE {
* type AttributeType,
* values SET OF AttributeValue
* }
* }
*/
LDAPDebug( LDAP_DEBUG_TRACE, "ldap_add_ext\n", 0, 0, 0 );
if ( !NSLDAPI_VALID_LDAP_POINTER( ld )) {
return( LDAP_PARAM_ERROR );
}
if ( !NSLDAPI_VALID_LDAPMESSAGE_POINTER( msgidp ))
{
LDAP_SET_LDERRNO( ld, LDAP_PARAM_ERROR, NULL, NULL );
return( LDAP_PARAM_ERROR );
}
if ( !NSLDAPI_VALID_NONEMPTY_LDAPMOD_ARRAY( attrs )
|| msgidp == NULL ) {
lderr = LDAP_PARAM_ERROR;
LDAP_SET_LDERRNO( ld, lderr, NULL, NULL );
return( lderr );
}
if ( dn == NULL ) {
dn = "";
}
LDAP_MUTEX_LOCK( ld, LDAP_MSGID_LOCK );
*msgidp = ++ld->ld_msgid;
LDAP_MUTEX_UNLOCK( ld, LDAP_MSGID_LOCK );
/* see if we should add to the cache */
if ( ld->ld_cache_on && ld->ld_cache_add != NULL ) {
LDAP_MUTEX_LOCK( ld, LDAP_CACHE_LOCK );
if ( (rc = (ld->ld_cache_add)( ld, *msgidp, LDAP_REQ_ADD, dn,
attrs )) != 0 ) {
*msgidp = rc;
LDAP_MUTEX_UNLOCK( ld, LDAP_CACHE_LOCK );
return( LDAP_SUCCESS );
}
LDAP_MUTEX_UNLOCK( ld, LDAP_CACHE_LOCK );
}
/* create a message to send */
if (( lderr = nsldapi_alloc_ber_with_options( ld, &ber ))
!= LDAP_SUCCESS ) {
return( lderr );
}
if ( ber_printf( ber, "{it{s{", *msgidp, LDAP_REQ_ADD, dn )
== -1 ) {
lderr = LDAP_ENCODING_ERROR;
LDAP_SET_LDERRNO( ld, lderr, NULL, NULL );
ber_free( ber, 1 );
return( lderr );
}
/* for each attribute in the entry... */
for ( i = 0; attrs[i] != NULL; i++ ) {
if ( ( attrs[i]->mod_op & LDAP_MOD_BVALUES) != 0 ) {
rc = ber_printf( ber, "{s[V]}", attrs[i]->mod_type,
attrs[i]->mod_bvalues );
} else {
rc = ber_printf( ber, "{s[v]}", attrs[i]->mod_type,
attrs[i]->mod_values );
}
if ( rc == -1 ) {
lderr = LDAP_ENCODING_ERROR;
LDAP_SET_LDERRNO( ld, lderr, NULL, NULL );
ber_free( ber, 1 );
return( lderr );
}
}
if ( ber_printf( ber, "}}" ) == -1 ) {
lderr = LDAP_ENCODING_ERROR;
LDAP_SET_LDERRNO( ld, lderr, NULL, NULL );
ber_free( ber, 1 );
return( lderr );
}
if (( lderr = nsldapi_put_controls( ld, serverctrls, 1, ber ))
!= LDAP_SUCCESS ) {
ber_free( ber, 1 );
return( lderr );
}
/* send the message */
rc = nsldapi_send_initial_request( ld, *msgidp, LDAP_REQ_ADD,
(char *) dn, ber );
*msgidp = rc;
return( rc < 0 ? LDAP_GET_LDERRNO( ld, NULL, NULL ) : LDAP_SUCCESS );
}
int
LDAP_CALL
ldap_add_s( LDAP *ld, const char *dn, LDAPMod **attrs )
{
return( ldap_add_ext_s( ld, dn, attrs, NULL, NULL ));
}
int LDAP_CALL
ldap_add_ext_s( LDAP *ld, const char *dn, LDAPMod **attrs,
LDAPControl **serverctrls, LDAPControl **clientctrls )
{
int err, msgid;
LDAPMessage *res;
if (( err = ldap_add_ext( ld, dn, attrs, serverctrls, clientctrls,
&msgid )) != LDAP_SUCCESS ) {
return( err );
}
if ( ldap_result( ld, msgid, 1, (struct timeval *)NULL, &res ) == -1 ) {
return( LDAP_GET_LDERRNO( ld, NULL, NULL ) );
}
return( ldap_result2error( ld, res, 1 ) );
}

View file

@ -0,0 +1,157 @@
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is Sun LDAP C SDK.
*
* The Initial Developer of the Original Code is Sun Microsystems, Inc.
*
* Portions created by Sun Microsystems, Inc are Copyright (C) 2005
* Sun Microsystems, Inc. All Rights Reserved.
*
* Contributor(s): abobrov@sun.com
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
#include "ldap-int.h"
/* ldap_create_authzid_control:
Parameters are
ld LDAP pointer to the desired connection
ctl_iscritical Indicates whether the control is critical of not.
If this field is non-zero, the operation will only be
carried out if the control is recognized by the server
and/or client
ctrlp the address of a place to put the constructed control
*/
int
LDAP_CALL
ldap_create_authzid_control (
LDAP *ld,
const char ctl_iscritical,
LDAPControl **ctrlp
)
{
int rc;
if ( !NSLDAPI_VALID_LDAP_POINTER( ld )) {
return( LDAP_PARAM_ERROR );
}
if ( ctrlp == NULL ) {
LDAP_SET_LDERRNO( ld, LDAP_PARAM_ERROR, NULL, NULL );
return ( LDAP_PARAM_ERROR );
}
rc = nsldapi_build_control( LDAP_CONTROL_AUTHZID_REQ,
NULL, 0, ctl_iscritical, ctrlp );
LDAP_SET_LDERRNO( ld, rc, NULL, NULL );
return( rc );
}
/* ldap_parse_authzid_control:
Parameters are
ld LDAP pointer to the desired connection
ctrlp An array of controls obtained from calling
ldap_parse_result on the set of results
returned by the server
authzid authorization identity, as defined in
RFC 2829, section 9.
*/
int
LDAP_CALL
ldap_parse_authzid_control (
LDAP *ld,
LDAPControl **ctrlp,
char **authzid
)
{
int i, foundAUTHZIDControl;
char *authzidp = NULL;
LDAPControl *AUTHZIDCtrlp = NULL;
if ( !NSLDAPI_VALID_LDAP_POINTER( ld ) ) {
return( LDAP_PARAM_ERROR );
}
/* find the control in the list of controls if it exists */
if ( ctrlp == NULL ) {
LDAP_SET_LDERRNO( ld, LDAP_CONTROL_NOT_FOUND, NULL, NULL );
return ( LDAP_CONTROL_NOT_FOUND );
}
foundAUTHZIDControl = 0;
for ( i = 0; (( ctrlp[i] != NULL ) && ( !foundAUTHZIDControl )); i++ ) {
foundAUTHZIDControl = !strcmp( ctrlp[i]->ldctl_oid,
LDAP_CONTROL_AUTHZID_RES );
}
/*
* The control is only included in a bind response if the resultCode
* for the bind operation is success.
*/
if ( !foundAUTHZIDControl ) {
LDAP_SET_LDERRNO( ld, LDAP_CONTROL_NOT_FOUND, NULL, NULL );
return ( LDAP_CONTROL_NOT_FOUND );
} else {
/* let local var point to the control */
AUTHZIDCtrlp = ctrlp[i-1];
}
/*
* If the bind request succeeded and resulted in an identity (not anonymous),
* the controlValue contains the authorization identity (authzid), as
* defined in [AUTH] section 9, granted to the requestor. If the bind
* request resulted in an anonymous association, the controlValue field
* is a string of zero length. If the bind request resulted in more
* than one authzid, the primary authzid is returned in the controlValue
* field.
*/
if ( AUTHZIDCtrlp && AUTHZIDCtrlp->ldctl_value.bv_val &&
AUTHZIDCtrlp->ldctl_value.bv_len ) {
authzidp = ( (char *)NSLDAPI_MALLOC(
( AUTHZIDCtrlp->ldctl_value.bv_len + 1 ) ) );
if ( authzidp == NULL ) {
LDAP_SET_LDERRNO( ld, LDAP_NO_MEMORY, NULL, NULL );
return( LDAP_NO_MEMORY );
}
STRLCPY( authzidp, AUTHZIDCtrlp->ldctl_value.bv_val,
( AUTHZIDCtrlp->ldctl_value.bv_len + 1 ) );
*authzid = authzidp;
} else {
authzid = NULL;
}
return( LDAP_SUCCESS );
}

View file

@ -0,0 +1,170 @@
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is Mozilla Communicator client code, released
* March 31, 1998.
*
* The Initial Developer of the Original Code is
* Netscape Communications Corporation.
* Portions created by the Initial Developer are Copyright (C) 1998-1999
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
*
* Alternatively, the contents of this file may be used under the terms of
* either of the GNU General Public License Version 2 or later (the "GPL"),
* or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
/*
* bind.c
*/
#if 0
#ifndef lint
static char copyright[] = "@(#) Copyright (c) 1990 Regents of the University of Michigan.\nAll rights reserved.\n";
#endif
#endif
#include "ldap-int.h"
/*
* ldap_bind - bind to the ldap server. The dn and password
* of the entry to which to bind are supplied, along with the authentication
* method to use. The msgid of the bind request is returned on success,
* -1 if there's trouble. Note, the kerberos support assumes the user already
* has a valid tgt for now. ldap_result() should be called to find out the
* outcome of the bind request.
*
* Example:
* ldap_bind( ld, "cn=manager, o=university of michigan, c=us", "secret",
* LDAP_AUTH_SIMPLE )
*/
int
LDAP_CALL
ldap_bind( LDAP *ld, const char *dn, const char *passwd, int authmethod )
{
/*
* The bind request looks like this:
* BindRequest ::= SEQUENCE {
* version INTEGER,
* name DistinguishedName, -- who
* authentication CHOICE {
* simple [0] OCTET STRING -- passwd
* }
* }
* all wrapped up in an LDAPMessage sequence.
*/
LDAPDebug( LDAP_DEBUG_TRACE, "ldap_bind\n", 0, 0, 0 );
if ( !NSLDAPI_VALID_LDAP_POINTER( ld )) {
return( -1 );
}
switch ( authmethod ) {
case LDAP_AUTH_SIMPLE:
return( ldap_simple_bind( ld, dn, passwd ) );
default:
LDAP_SET_LDERRNO( ld, LDAP_AUTH_UNKNOWN, NULL, NULL );
return( -1 );
}
}
/*
* ldap_bind_s - bind to the ldap server. The dn and password
* of the entry to which to bind are supplied, along with the authentication
* method to use. This routine just calls whichever bind routine is
* appropriate and returns the result of the bind (e.g. LDAP_SUCCESS or
* some other error indication). Note, the kerberos support assumes the
* user already has a valid tgt for now.
*
* Examples:
* ldap_bind_s( ld, "cn=manager, o=university of michigan, c=us",
* "secret", LDAP_AUTH_SIMPLE )
* ldap_bind_s( ld, "cn=manager, o=university of michigan, c=us",
* NULL, LDAP_AUTH_KRBV4 )
*/
int
LDAP_CALL
ldap_bind_s( LDAP *ld, const char *dn, const char *passwd, int authmethod )
{
int err;
LDAPDebug( LDAP_DEBUG_TRACE, "ldap_bind_s\n", 0, 0, 0 );
switch ( authmethod ) {
case LDAP_AUTH_SIMPLE:
return( ldap_simple_bind_s( ld, dn, passwd ) );
default:
err = LDAP_AUTH_UNKNOWN;
LDAP_SET_LDERRNO( ld, err, NULL, NULL );
return( err );
}
}
void
LDAP_CALL
ldap_set_rebind_proc( LDAP *ld, LDAP_REBINDPROC_CALLBACK *rebindproc,
void *arg )
{
if ( ld == NULL ) {
if ( !nsldapi_initialized ) {
nsldapi_initialize_defaults();
}
ld = &nsldapi_ld_defaults;
}
if ( NSLDAPI_VALID_LDAP_POINTER( ld )) {
LDAP_MUTEX_LOCK( ld, LDAP_OPTION_LOCK );
ld->ld_rebind_fn = rebindproc;
ld->ld_rebind_arg = arg;
LDAP_MUTEX_UNLOCK( ld, LDAP_OPTION_LOCK );
}
}
/*
* return a pointer to the bind DN for the default connection (a copy is
* not made). If there is no bind DN available, NULL is returned.
*/
char *
nsldapi_get_binddn( LDAP *ld )
{
char *binddn;
binddn = NULL; /* default -- assume they are not bound */
LDAP_MUTEX_LOCK( ld, LDAP_CONN_LOCK );
if ( NULL != ld->ld_defconn && LDAP_CONNST_CONNECTED ==
ld->ld_defconn->lconn_status && ld->ld_defconn->lconn_bound ) {
if (( binddn = ld->ld_defconn->lconn_binddn ) == NULL ) {
binddn = "";
}
}
LDAP_MUTEX_UNLOCK( ld, LDAP_CONN_LOCK );
return( binddn );
}

View file

@ -0,0 +1,145 @@
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is Mozilla Communicator client code, released
* March 31, 1998.
*
* The Initial Developer of the Original Code is
* Netscape Communications Corporation.
* Portions created by the Initial Developer are Copyright (C) 1998-1999
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
*
* Alternatively, the contents of this file may be used under the terms of
* either of the GNU General Public License Version 2 or later (the "GPL"),
* or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
/*
* Copyright (c) 1993 The Regents of the University of Michigan.
* All rights reserved.
*/
/*
* cache.c - generic caching support for LDAP
*/
#include "ldap-int.h"
/*
* ldap_cache_flush - flush part of the LDAP cache. returns an
* ldap error code (LDAP_SUCCESS, LDAP_NO_SUCH_OBJECT, etc.).
*/
int
LDAP_CALL
ldap_cache_flush( LDAP *ld, const char *dn, const char *filter )
{
if ( !NSLDAPI_VALID_LDAP_POINTER( ld )) {
return( LDAP_PARAM_ERROR );
}
if ( dn == NULL ) {
dn = "";
}
return( (ld->ld_cache_flush)( ld, dn, filter ) );
}
/*
* nsldapi_add_result_to_cache - add an ldap entry we just read off the network
* to the ldap cache. this routine parses the ber for the entry and
* constructs the appropriate add request. this routine calls the
* cache add routine to actually add the entry.
*/
void
nsldapi_add_result_to_cache( LDAP *ld, LDAPMessage *m )
{
char *dn;
LDAPMod **mods;
int i, max, rc;
char *a;
BerElement *ber;
char buf[50];
struct berval bv;
struct berval *bvp[2];
LDAPDebug( LDAP_DEBUG_TRACE, "=> nsldapi_add_result_to_cache id %d type %d\n",
m->lm_msgid, m->lm_msgtype, 0 );
if ( m->lm_msgtype != LDAP_RES_SEARCH_ENTRY ||
ld->ld_cache_add == NULL ) {
LDAPDebug( LDAP_DEBUG_TRACE,
"<= nsldapi_add_result_to_cache not added\n", 0, 0, 0 );
return;
}
#define GRABSIZE 5
dn = ldap_get_dn( ld, m );
mods = (LDAPMod **)NSLDAPI_MALLOC( GRABSIZE * sizeof(LDAPMod *) );
max = GRABSIZE;
for ( i = 0, a = ldap_first_attribute( ld, m, &ber ); a != NULL;
a = ldap_next_attribute( ld, m, ber ), i++ ) {
if ( i == (max - 1) ) {
max += GRABSIZE;
mods = (LDAPMod **)NSLDAPI_REALLOC( mods,
sizeof(LDAPMod *) * max );
}
mods[i] = (LDAPMod *)NSLDAPI_CALLOC( 1, sizeof(LDAPMod) );
mods[i]->mod_op = LDAP_MOD_BVALUES;
mods[i]->mod_type = a;
mods[i]->mod_bvalues = ldap_get_values_len( ld, m, a );
}
if ( ber != NULL ) {
ber_free( ber, 0 );
}
if (( rc = LDAP_GET_LDERRNO( ld, NULL, NULL )) != LDAP_SUCCESS ) {
LDAPDebug( LDAP_DEBUG_TRACE,
"<= nsldapi_add_result_to_cache error: failed to construct mod list (%s)\n",
ldap_err2string( rc ), 0, 0 );
ldap_mods_free( mods, 1 );
return;
}
/* update special cachedtime attribute */
if ( i == (max - 1) ) {
max++;
mods = (LDAPMod **)NSLDAPI_REALLOC( mods,
sizeof(LDAPMod *) * max );
}
mods[i] = (LDAPMod *)NSLDAPI_CALLOC( 1, sizeof(LDAPMod) );
mods[i]->mod_op = LDAP_MOD_BVALUES;
mods[i]->mod_type = "cachedtime";
sprintf( buf, "%ld", time( NULL ) );
bv.bv_val = buf;
bv.bv_len = strlen( buf );
bvp[0] = &bv;
bvp[1] = NULL;
mods[i]->mod_bvalues = bvp;
mods[++i] = NULL;
/* msgid of -1 means don't send the result */
rc = (ld->ld_cache_add)( ld, -1, m->lm_msgtype, dn, mods );
LDAPDebug( LDAP_DEBUG_TRACE,
"<= nsldapi_add_result_to_cache added (rc %d)\n", rc, 0, 0 );
}

View file

@ -0,0 +1,248 @@
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is Mozilla Communicator client code, released
* March 31, 1998.
*
* The Initial Developer of the Original Code is
* Netscape Communications Corporation.
* Portions created by the Initial Developer are Copyright (C) 1998-1999
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
*
* Alternatively, the contents of this file may be used under the terms of
* either of the GNU General Public License Version 2 or later (the "GPL"),
* or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
/* charray.c - routines for dealing with char * arrays */
#include "ldap-int.h"
/*
* Add s at the end of the array of strings *a.
* Return 0 for success, -1 for failure.
*/
int
LDAP_CALL
ldap_charray_add(
char ***a,
char *s
)
{
int n;
if ( *a == NULL ) {
*a = (char **)NSLDAPI_MALLOC( 2 * sizeof(char *) );
if ( *a == NULL ) {
return -1;
}
n = 0;
} else {
for ( n = 0; *a != NULL && (*a)[n] != NULL; n++ ) {
; /* NULL */
}
*a = (char **)NSLDAPI_REALLOC( (char *) *a,
(n + 2) * sizeof(char *) );
if ( *a == NULL ) {
return -1;
}
}
(*a)[n++] = s;
(*a)[n] = NULL;
return 0;
}
/*
* Add array of strings s at the end of the array of strings *a.
* Return 0 for success, -1 for failure.
*/
int
LDAP_CALL
ldap_charray_merge(
char ***a,
char **s
)
{
int i, n, nn;
if ( (s == NULL) || (s[0] == NULL) )
return 0;
for ( n = 0; *a != NULL && (*a)[n] != NULL; n++ ) {
; /* NULL */
}
for ( nn = 0; s[nn] != NULL; nn++ ) {
; /* NULL */
}
*a = (char **)NSLDAPI_REALLOC( (char *) *a,
(n + nn + 1) * sizeof(char *) );
if ( *a == NULL ) {
return -1;
}
for ( i = 0; i < nn; i++ ) {
(*a)[n + i] = s[i];
}
(*a)[n + nn] = NULL;
return 0;
}
void
LDAP_CALL
ldap_charray_free( char **array )
{
char **a;
if ( array == NULL ) {
return;
}
for ( a = array; *a != NULL; a++ ) {
if ( *a != NULL ) {
NSLDAPI_FREE( *a );
}
}
NSLDAPI_FREE( (char *) array );
}
int
LDAP_CALL
ldap_charray_inlist(
char **a,
char *s
)
{
int i;
if ( a == NULL )
return( 0 );
for ( i = 0; a[i] != NULL; i++ ) {
if ( strcasecmp( s, a[i] ) == 0 ) {
return( 1 );
}
}
return( 0 );
}
/*
* Duplicate the array of strings a, return NULL upon any memory failure.
*/
char **
LDAP_CALL
ldap_charray_dup( char **a )
{
int i;
char **new;
for ( i = 0; a[i] != NULL; i++ )
; /* NULL */
new = (char **)NSLDAPI_MALLOC( (i + 1) * sizeof(char *) );
if ( new == NULL ) {
return NULL;
}
for ( i = 0; a[i] != NULL; i++ ) {
new[i] = nsldapi_strdup( a[i] );
if ( new[i] == NULL ) {
int j;
for ( j = 0; j < i; j++ )
NSLDAPI_FREE( new[j] );
NSLDAPI_FREE( new );
return NULL;
}
}
new[i] = NULL;
return( new );
}
/*
* Tokenize the string str, return NULL upon any memory failure.
* XXX: on many platforms this function is not thread safe because it
* uses strtok().
*/
char **
LDAP_CALL
ldap_str2charray( char *str, char *brkstr )
/* This implementation fails if brkstr contains multibyte characters.
But it works OK if str is UTF-8 and brkstr is 7-bit ASCII.
*/
{
char **res;
char *s;
int i;
#ifdef HAVE_STRTOK_R /* defined in portable.h */
char *lasts;
#endif
i = 1;
for ( s = str; *s; s++ ) {
if ( strchr( brkstr, *s ) != NULL ) {
i++;
}
}
res = (char **)NSLDAPI_MALLOC( (i + 1) * sizeof(char *) );
if ( res == NULL ) {
return NULL;
}
i = 0;
for ( s = STRTOK( str, brkstr, &lasts ); s != NULL; s = STRTOK( NULL,
brkstr, &lasts ) ) {
res[i++] = nsldapi_strdup( s );
if ( res[i - 1] == NULL ) {
int j;
for ( j = 0; j < (i - 1); j++ )
NSLDAPI_FREE( res[j] );
NSLDAPI_FREE( res );
return NULL;
}
}
res[i] = NULL;
return( res );
}
int
LDAP_CALL
ldap_charray_position( char **a, char *s )
{
int i;
for ( i = 0; a[i] != NULL; i++ ) {
if ( strcasecmp( s, a[i] ) == 0 ) {
return( i );
}
}
return( -1 );
}

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,585 @@
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is Mozilla Communicator client code, released
* March 31, 1998.
*
* The Initial Developer of the Original Code is
* Netscape Communications Corporation.
* Portions created by the Initial Developer are Copyright (C) 1998-1999
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
*
* Alternatively, the contents of this file may be used under the terms of
* either of the GNU General Public License Version 2 or later (the "GPL"),
* or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
/*
* Copyright (c) 1990, 1994 Regents of the University of Michigan.
* All rights reserved.
*/
/*
* cldap.c - synchronous, retrying interface to the cldap protocol
*/
#ifdef CLDAP
XXX not MT-safe XXX
#ifndef lint
static char copyright[] = "@(#) Copyright (c) 1990, 1994 Regents of the University of Michigan.\nAll rights reserved.\n";
#endif
#include <stdio.h>
#include <string.h>
#include <errno.h>
#ifdef macintosh
#include <stdlib.h>
#include "macos.h"
#else /* macintosh */
#ifdef DOS
#include "msdos.h"
#else /* DOS */
#ifdef _WINDOWS
#include <windows.h>
#else /* _WINDOWS */
#include <sys/time.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>
#endif /* _WINDOWS */
#endif /* DOS */
#endif /* macintosh */
#include "ldap-int.h"
#define DEF_CLDAP_TIMEOUT 3
#define DEF_CLDAP_TRIES 4
#ifndef INADDR_LOOPBACK
#define INADDR_LOOPBACK ((unsigned long) 0x7f000001)
#endif
struct cldap_retinfo {
int cri_maxtries;
int cri_try;
int cri_useaddr;
long cri_timeout;
};
#ifdef NEEDPROTOS
static int add_addr( LDAP *ld, struct sockaddr *sap );
static int cldap_result( LDAP *ld, int msgid, LDAPMessage **res,
struct cldap_retinfo *crip, char *base );
static int cldap_parsemsg( LDAP *ld, int msgid, BerElement *ber,
LDAPMessage **res, char *base );
#else /* NEEDPROTOS */
static int add_addr();
static int cldap_result();
static int cldap_parsemsg();
#endif /* NEEDPROTOS */
/*
* cldap_open - initialize and connect to an ldap server. A magic cookie to
* be used for future communication is returned on success, NULL on failure.
*
* Example:
* LDAP *ld;
* ld = cldap_open( hostname, port );
*/
LDAP *
cldap_open( char *host, int port )
{
int s;
ldap_x_in_addr_t address;
struct sockaddr_in sock;
struct hostent *hp;
LDAP *ld;
char *p;
int i;
LDAPDebug( LDAP_DEBUG_TRACE, "cldap_open\n", 0, 0, 0 );
if ( port == 0 ) {
port = LDAP_PORT;
}
if ( (s = socket( AF_INET, SOCK_DGRAM, 0 )) < 0 ) {
return( NULL );
}
sock.sin_addr.s_addr = 0;
sock.sin_family = AF_INET;
sock.sin_port = 0;
if ( bind(s, (struct sockaddr *) &sock, sizeof(sock)) < 0) {
close( s );
return( NULL );
}
if (( ld = ldap_init( host, port )) == NULL ) {
close( s );
return( NULL );
}
if ( (ld->ld_sbp->sb_fromaddr = (void *)NSLDAPI_CALLOC( 1,
sizeof( struct sockaddr ))) == NULL ) {
NSLDAPI_FREE( ld );
close( s );
return( NULL );
}
ld->ld_sbp->sb_sd = s;
ld->ld_sbp->sb_naddr = 0;
ld->ld_version = LDAP_VERSION2;
sock.sin_family = AF_INET;
sock.sin_port = htons( port );
/*
* 'host' may be a space-separated list.
*/
if ( host != NULL ) {
for ( ; host != NULL; host = p ) {
if (( p = strchr( host, ' ' )) != NULL ) {
for (*p++ = '\0'; *p == ' '; p++) {
;
}
}
if ( (address = inet_addr( host )) == -1 ) {
/* XXXmcs: need to use DNS callbacks here XXX */
XXX
if ( (hp = gethostbyname( host )) == NULL ) {
LDAP_SET_ERRNO( ld, EHOSTUNREACH );
continue;
}
for ( i = 0; hp->h_addr_list[ i ] != 0; ++i ) {
SAFEMEMCPY( (char *)&sock.sin_addr.s_addr,
(char *)hp->h_addr_list[ i ],
sizeof(sock.sin_addr.s_addr));
if ( add_addr( ld, (struct sockaddr *)&sock ) < 0 ) {
close( s );
NSLDAPI_FREE( ld );
return( NULL );
}
}
} else {
sock.sin_addr.s_addr = address;
if ( add_addr( ld, (struct sockaddr *)&sock ) < 0 ) {
close( s );
NSLDAPI_FREE( ld );
return( NULL );
}
}
if ( ld->ld_host == NULL ) {
ld->ld_host = nsldapi_strdup( host );
}
}
} else {
address = INADDR_LOOPBACK;
sock.sin_addr.s_addr = htonl( address );
if ( add_addr( ld, (struct sockaddr *)&sock ) < 0 ) {
close( s );
NSLDAPI_FREE( ld );
return( NULL );
}
}
if ( ld->ld_sbp->sb_addrs == NULL
|| ( ld->ld_defconn = nsldapi_new_connection( ld, NULL, 1,0,0 )) == NULL ) {
NSLDAPI_FREE( ld );
return( NULL );
}
ld->ld_sbp->sb_useaddr = ld->ld_sbp->sb_addrs[ 0 ];
cldap_setretryinfo( ld, 0, 0 );
#ifdef LDAP_DEBUG
putchar( '\n' );
for ( i = 0; i < ld->ld_sbp->sb_naddr; ++i ) {
LDAPDebug( LDAP_DEBUG_TRACE, "end of cldap_open address %d is %s\n",
i, inet_ntoa( ((struct sockaddr_in *)
ld->ld_sbp->sb_addrs[ i ])->sin_addr ), 0 );
}
#endif
return( ld );
}
void
cldap_close( LDAP *ld )
{
ldap_ld_free( ld, NULL, NULL, 0 );
}
void
cldap_setretryinfo( LDAP *ld, int tries, int timeout )
{
ld->ld_cldaptries = ( tries <= 0 ) ? DEF_CLDAP_TRIES : tries;
ld->ld_cldaptimeout = ( timeout <= 0 ) ? DEF_CLDAP_TIMEOUT : timeout;
}
int
cldap_search_s( LDAP *ld, char *base, int scope, char *filter, char **attrs,
int attrsonly, LDAPMessage **res, char *logdn )
{
int ret, msgid;
struct cldap_retinfo cri;
*res = NULLMSG;
(void) memset( &cri, 0, sizeof( cri ));
if ( logdn != NULL ) {
ld->ld_cldapdn = logdn;
} else if ( ld->ld_cldapdn == NULL ) {
ld->ld_cldapdn = "";
}
do {
if ( cri.cri_try != 0 ) {
--ld->ld_msgid; /* use same id as before */
}
ld->ld_sbp->sb_useaddr = ld->ld_sbp->sb_addrs[ cri.cri_useaddr ];
LDAPDebug( LDAP_DEBUG_TRACE, "cldap_search_s try %d (to %s)\n",
cri.cri_try, inet_ntoa( ((struct sockaddr_in *)
ld->ld_sbp->sb_useaddr)->sin_addr ), 0 );
if ( (msgid = ldap_search( ld, base, scope, filter, attrs,
attrsonly )) == -1 ) {
return( LDAP_GET_LDERRNO( ld, NULL, NULL ) );
}
#ifndef NO_CACHE
if ( ld->ld_cache != NULL && ld->ld_responses != NULL ) {
LDAPDebug( LDAP_DEBUG_TRACE, "cldap_search_s res from cache\n",
0, 0, 0 );
*res = ld->ld_responses;
ld->ld_responses = ld->ld_responses->lm_next;
return( ldap_result2error( ld, *res, 0 ));
}
#endif /* NO_CACHE */
ret = cldap_result( ld, msgid, res, &cri, base );
} while (ret == -1);
return( ret );
}
static int
add_addr( LDAP *ld, struct sockaddr *sap )
{
struct sockaddr *newsap, **addrs;
if (( newsap = (struct sockaddr *)NSLDAPI_MALLOC(
sizeof( struct sockaddr ))) == NULL ) {
LDAP_SET_LDERRNO( ld, LDAP_NO_MEMORY, NULL, NULL );
return( -1 );
}
if ( ld->ld_sbp->sb_naddr == 0 ) {
addrs = (struct sockaddr **)NSLDAPI_MALLOC( sizeof(struct sockaddr *));
} else {
addrs = (struct sockaddr **)NSLDAPI_REALLOC( ld->ld_sbp->sb_addrs,
( ld->ld_sbp->sb_naddr + 1 ) * sizeof(struct sockaddr *));
}
if ( addrs == NULL ) {
NSLDAPI_FREE( newsap );
LDAP_SET_LDERRNO( ld, LDAP_NO_MEMORY, NULL, NULL );
return( -1 );
}
SAFEMEMCPY( (char *)newsap, (char *)sap, sizeof( struct sockaddr ));
addrs[ ld->ld_sbp->sb_naddr++ ] = newsap;
ld->ld_sbp->sb_addrs = (void **)addrs;
return( 0 );
}
static int
cldap_result( LDAP *ld, int msgid, LDAPMessage **res,
struct cldap_retinfo *crip, char *base )
{
Sockbuf *sb = ld->ld_sbp;
BerElement ber;
char *logdn;
int ret, fromaddr, i;
ber_int_t id;
struct timeval tv;
fromaddr = -1;
if ( crip->cri_try == 0 ) {
crip->cri_maxtries = ld->ld_cldaptries * sb->sb_naddr;
crip->cri_timeout = ld->ld_cldaptimeout;
crip->cri_useaddr = 0;
LDAPDebug( LDAP_DEBUG_TRACE, "cldap_result tries %d timeout %d\n",
ld->ld_cldaptries, ld->ld_cldaptimeout, 0 );
}
if ((tv.tv_sec = crip->cri_timeout / sb->sb_naddr) < 1 ) {
tv.tv_sec = 1;
}
tv.tv_usec = 0;
LDAPDebug( LDAP_DEBUG_TRACE,
"cldap_result waiting up to %d seconds for a response\n",
tv.tv_sec, 0, 0 );
ber_init_w_nullchar( &ber, 0 );
nsldapi_set_ber_options( ld, &ber );
if ( cldap_getmsg( ld, &tv, &ber ) == -1 ) {
ret = LDAP_GET_LDERRNO( ld, NULL, NULL );
LDAPDebug( LDAP_DEBUG_TRACE, "cldap_getmsg returned -1 (%d)\n",
ret, 0, 0 );
} else if ( LDAP_GET_LDERRNO( ld, NULL, NULL ) == LDAP_TIMEOUT ) {
LDAPDebug( LDAP_DEBUG_TRACE,
"cldap_result timed out\n", 0, 0, 0 );
/*
* It timed out; is it time to give up?
*/
if ( ++crip->cri_try >= crip->cri_maxtries ) {
ret = LDAP_TIMEOUT;
--crip->cri_try;
} else {
if ( ++crip->cri_useaddr >= sb->sb_naddr ) {
/*
* new round: reset address to first one and
* double the timeout
*/
crip->cri_useaddr = 0;
crip->cri_timeout <<= 1;
}
ret = -1;
}
} else {
/*
* Got a response. It should look like:
* { msgid, logdn, { searchresponse...}}
*/
logdn = NULL;
if ( ber_scanf( &ber, "ia", &id, &logdn ) == LBER_ERROR ) {
NSLDAPI_FREE( ber.ber_buf ); /* gack! */
ret = LDAP_DECODING_ERROR;
LDAPDebug( LDAP_DEBUG_TRACE,
"cldap_result: ber_scanf returned LBER_ERROR (%d)\n",
ret, 0, 0 );
} else if ( id != msgid ) {
NSLDAPI_FREE( ber.ber_buf ); /* gack! */
LDAPDebug( LDAP_DEBUG_TRACE,
"cldap_result: looking for msgid %d; got %ld\n",
msgid, id, 0 );
ret = -1; /* ignore and keep looking */
} else {
/*
* got a result: determine which server it came from
* decode into ldap message chain
*/
for ( fromaddr = 0; fromaddr < sb->sb_naddr; ++fromaddr ) {
if ( memcmp( &((struct sockaddr_in *)
sb->sb_addrs[ fromaddr ])->sin_addr,
&((struct sockaddr_in *)sb->sb_fromaddr)->sin_addr,
sizeof( struct in_addr )) == 0 ) {
break;
}
}
ret = cldap_parsemsg( ld, msgid, &ber, res, base );
NSLDAPI_FREE( ber.ber_buf ); /* gack! */
LDAPDebug( LDAP_DEBUG_TRACE,
"cldap_result got result (%d)\n", ret, 0, 0 );
}
if ( logdn != NULL ) {
NSLDAPI_FREE( logdn );
}
}
/*
* If we are giving up (successfully or otherwise) then
* abandon any outstanding requests.
*/
if ( ret != -1 ) {
i = crip->cri_try;
if ( i >= sb->sb_naddr ) {
i = sb->sb_naddr - 1;
}
for ( ; i >= 0; --i ) {
if ( i == fromaddr ) {
continue;
}
sb->sb_useaddr = sb->sb_addrs[ i ];
LDAPDebug( LDAP_DEBUG_TRACE, "cldap_result abandoning id %d (to %s)\n",
msgid, inet_ntoa( ((struct sockaddr_in *)
sb->sb_useaddr)->sin_addr ), 0 );
(void) ldap_abandon( ld, msgid );
}
}
LDAP_SET_LDERRNO( ld, ret, NULL, NULL );
return( ret );
}
static int
cldap_parsemsg( LDAP *ld, int msgid, BerElement *ber,
LDAPMessage **res, char *base )
{
ber_tag_t tag;
ber_len_t len;
int baselen, slen, rc;
char *dn, *p, *cookie;
LDAPMessage *chain, *prev, *ldm;
struct berval *bv;
rc = LDAP_DECODING_ERROR; /* pessimistic */
ldm = chain = prev = NULLMSG;
baselen = ( base == NULL ) ? 0 : strlen( base );
bv = NULL;
for ( tag = ber_first_element( ber, &len, &cookie );
tag != LBER_ERROR && tag != LBER_END_OF_SEQOFSET
&& rc != LDAP_SUCCESS;
tag = ber_next_element( ber, &len, cookie )) {
if (( ldm = (LDAPMessage *)NSLDAPI_CALLOC( 1, sizeof(LDAPMessage)))
== NULL ) {
rc = LDAP_NO_MEMORY;
break; /* return with error */
} else if (( rc = nsldapi_alloc_ber_with_options( ld, &ldm->lm_ber ))
!= LDAP_SUCCESS ) {
break; /* return with error*/
}
ldm->lm_msgid = msgid;
ldm->lm_msgtype = tag;
if ( tag == LDAP_RES_SEARCH_RESULT ) {
LDAPDebug( LDAP_DEBUG_TRACE, "cldap_parsemsg got search result\n",
0, 0, 0 );
if ( ber_get_stringal( ber, &bv ) == LBER_DEFAULT ) {
break; /* return w/error */
}
if ( ber_printf( ldm->lm_ber, "to", tag, bv->bv_val,
bv->bv_len ) == -1 ) {
break; /* return w/error */
}
ber_bvfree( bv );
bv = NULL;
rc = LDAP_SUCCESS;
} else if ( tag == LDAP_RES_SEARCH_ENTRY ) {
if ( ber_scanf( ber, "{aO", &dn, &bv ) == LBER_ERROR ) {
break; /* return w/error */
}
LDAPDebug( LDAP_DEBUG_TRACE, "cldap_parsemsg entry %s\n", dn, 0, 0 );
if ( dn != NULL && *(dn + ( slen = strlen(dn)) - 1) == '*' &&
baselen > 0 ) {
/*
* substitute original searchbase for trailing '*'
*/
if (( p = (char *)NSLDAPI_MALLOC( slen + baselen )) == NULL ) {
rc = LDAP_NO_MEMORY;
NSLDAPI_FREE( dn );
break; /* return w/error */
}
strcpy( p, dn );
strcpy( p + slen - 1, base );
NSLDAPI_FREE( dn );
dn = p;
}
if ( ber_printf( ldm->lm_ber, "t{so}", tag, dn, bv->bv_val,
bv->bv_len ) == -1 ) {
break; /* return w/error */
}
NSLDAPI_FREE( dn );
ber_bvfree( bv );
bv = NULL;
} else {
LDAPDebug( LDAP_DEBUG_TRACE, "cldap_parsemsg got unknown tag %d\n",
tag, 0, 0 );
rc = LDAP_PROTOCOL_ERROR;
break; /* return w/error */
}
/* Reset message ber so we can read from it later. Gack! */
ldm->lm_ber->ber_end = ldm->lm_ber->ber_ptr;
ldm->lm_ber->ber_ptr = ldm->lm_ber->ber_buf;
#ifdef LDAP_DEBUG
if ( ldap_debug & LDAP_DEBUG_PACKETS ) {
char msg[80];
sprintf( msg, "cldap_parsemsg add message id %d type %d:\n",
ldm->lm_msgid, ldm->lm_msgtype );
ber_err_print( msg );
ber_dump( ldm->lm_ber, 1 );
}
#endif /* LDAP_DEBUG */
#ifndef NO_CACHE
if ( ld->ld_cache != NULL ) {
nsldapi_add_result_to_cache( ld, ldm );
}
#endif /* NO_CACHE */
if ( chain == NULL ) {
chain = ldm;
} else {
prev->lm_chain = ldm;
}
prev = ldm;
ldm = NULL;
}
/* dispose of any leftovers */
if ( ldm != NULL ) {
if ( ldm->lm_ber != NULLBER ) {
ber_free( ldm->lm_ber, 1 );
}
NSLDAPI_FREE( ldm );
}
if ( bv != NULL ) {
ber_bvfree( bv );
}
/* return chain, calling result2error if we got anything at all */
*res = chain;
return(( *res == NULLMSG ) ? rc : ldap_result2error( ld, *res, 0 ));
}
#endif /* CLDAP */

View file

@ -0,0 +1,194 @@
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is Mozilla Communicator client code, released
* March 31, 1998.
*
* The Initial Developer of the Original Code is
* Netscape Communications Corporation.
* Portions created by the Initial Developer are Copyright (C) 1998-1999
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
*
* Alternatively, the contents of this file may be used under the terms of
* either of the GNU General Public License Version 2 or later (the "GPL"),
* or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
/*
* Copyright (c) 1990 Regents of the University of Michigan.
* All rights reserved.
*/
/*
* compare.c
*/
#if 0
#ifndef lint
static char copyright[] = "@(#) Copyright (c) 1990 Regents of the University of Michigan.\nAll rights reserved.\n";
#endif
#endif
#include "ldap-int.h"
/*
* ldap_compare - perform an ldap compare operation. The dn
* of the entry to compare to and the attribute and value to compare (in
* attr and value) are supplied. The msgid of the response is returned.
*
* Example:
* ldap_compare( ld, "c=us@cn=bob", "userPassword", "secret" )
*/
int
LDAP_CALL
ldap_compare( LDAP *ld, const char *dn, const char *attr, const char *value )
{
int msgid;
struct berval bv;
LDAPDebug( LDAP_DEBUG_TRACE, "ldap_compare\n", 0, 0, 0 );
bv.bv_val = (char *)value;
bv.bv_len = ( value == NULL ) ? 0 : strlen( value );
if ( ldap_compare_ext( ld, dn, attr, &bv, NULL, NULL, &msgid )
== LDAP_SUCCESS ) {
return( msgid );
} else {
return( -1 ); /* error is in ld handle */
}
}
int
LDAP_CALL
ldap_compare_ext( LDAP *ld, const char *dn, const char *attr,
const struct berval *bvalue, LDAPControl **serverctrls,
LDAPControl **clientctrls, int *msgidp )
{
BerElement *ber;
int rc, lderr;
/* The compare request looks like this:
* CompareRequest ::= SEQUENCE {
* entry DistinguishedName,
* ava SEQUENCE {
* type AttributeType,
* value AttributeValue
* }
* }
* and must be wrapped in an LDAPMessage.
*/
LDAPDebug( LDAP_DEBUG_TRACE, "ldap_compare_ext\n", 0, 0, 0 );
if ( !NSLDAPI_VALID_LDAP_POINTER( ld )) {
return( LDAP_PARAM_ERROR );
}
if ( attr == NULL || bvalue == NULL || bvalue->bv_len == 0
|| msgidp == NULL ) {
lderr = LDAP_PARAM_ERROR;
LDAP_SET_LDERRNO( ld, lderr, NULL, NULL );
return( lderr );
}
if ( dn == NULL ) {
dn = "";
}
LDAP_MUTEX_LOCK( ld, LDAP_MSGID_LOCK );
*msgidp = ++ld->ld_msgid;
LDAP_MUTEX_UNLOCK( ld, LDAP_MSGID_LOCK );
/* check the cache */
if ( ld->ld_cache_on && ld->ld_cache_compare != NULL ) {
LDAP_MUTEX_LOCK( ld, LDAP_CACHE_LOCK );
if ( (rc = (ld->ld_cache_compare)( ld, *msgidp,
LDAP_REQ_COMPARE, dn, attr, bvalue )) != 0 ) {
*msgidp = rc;
LDAP_MUTEX_UNLOCK( ld, LDAP_CACHE_LOCK );
return( LDAP_SUCCESS );
}
LDAP_MUTEX_UNLOCK( ld, LDAP_CACHE_LOCK );
}
/* create a message to send */
if (( lderr = nsldapi_alloc_ber_with_options( ld, &ber ))
!= LDAP_SUCCESS ) {
return( lderr );
}
if ( ber_printf( ber, "{it{s{so}}", *msgidp, LDAP_REQ_COMPARE, dn,
attr, bvalue->bv_val, bvalue->bv_len )
== -1 ) {
lderr = LDAP_ENCODING_ERROR;
LDAP_SET_LDERRNO( ld, lderr, NULL, NULL );
ber_free( ber, 1 );
return( lderr );
}
if (( lderr = nsldapi_put_controls( ld, serverctrls, 1, ber ))
!= LDAP_SUCCESS ) {
ber_free( ber, 1 );
return( lderr );
}
/* send the message */
rc = nsldapi_send_initial_request( ld, *msgidp, LDAP_REQ_COMPARE,
(char *)dn, ber );
*msgidp = rc;
return( rc < 0 ? LDAP_GET_LDERRNO( ld, NULL, NULL ) : LDAP_SUCCESS );
}
int
LDAP_CALL
ldap_compare_s( LDAP *ld, const char *dn, const char *attr,
const char *value )
{
struct berval bv;
bv.bv_val = (char *)value;
bv.bv_len = ( value == NULL ) ? 0 : strlen( value );
return( ldap_compare_ext_s( ld, dn, attr, &bv, NULL, NULL ));
}
int
LDAP_CALL
ldap_compare_ext_s( LDAP *ld, const char *dn, const char *attr,
const struct berval *bvalue, LDAPControl **serverctrls,
LDAPControl **clientctrls )
{
int err, msgid;
LDAPMessage *res;
if (( err = ldap_compare_ext( ld, dn, attr, bvalue, serverctrls,
clientctrls, &msgid )) != LDAP_SUCCESS ) {
return( err );
}
if ( ldap_result( ld, msgid, 1, (struct timeval *)NULL, &res )
== -1 ) {
return( LDAP_GET_LDERRNO( ld, NULL, NULL ) );
}
return( ldap_result2error( ld, res, 1 ) );
}

View file

@ -0,0 +1,108 @@
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is Mozilla Communicator client code, released
* March 31, 1998.
*
* The Initial Developer of the Original Code is
* Netscape Communications Corporation.
* Portions created by the Initial Developer are Copyright (C) 1998-1999
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
*
* Alternatively, the contents of this file may be used under the terms of
* either of the GNU General Public License Version 2 or later (the "GPL"),
* or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
/*
* Copyright (c) 1994 The Regents of the University of Michigan.
* All rights reserved.
*/
/*
* compat.c - compatibility routines.
*
*/
#if 0
#ifndef lint
static char copyright[] = "@(#) Copyright (c) 1994 The Regents of the University of Michigan.\nAll rights reserved.\n";
#endif
#endif
#include "ldap-int.h"
#if defined( HPUX10 ) && defined( _REENTRANT ) && !defined(HPUX11)
extern int h_errno;
struct hostent *
nsldapi_compat_gethostbyname_r( const char *name, struct hostent *result,
char *buffer, int buflen, int *h_errnop )
{
struct hostent_data *hep;
if ( buflen < sizeof(struct hostent_data)) { /* sanity check */
*h_errnop = NO_RECOVERY; /* XXX best error code to use? */
return( NULL );
}
hep = (struct hostent_data *)buffer;
hep->current = NULL;
if ( gethostbyname_r( name, result, hep ) == -1) {
*h_errnop = h_errno; /* XXX don't see anywhere else to get this */
return NULL;
}
return result;
}
char *
nsldapi_compat_ctime_r( const time_t *clock, char *buf, int buflen )
{
NSLDAPI_CTIME1( clock, buf, buflen );
return buf;
}
#endif /* HPUX10 && _REENTRANT && !HPUX11 */
#if defined(LINUX) || defined(AIX) || defined(HPUX) || defined(_WINDOWS)
/*
* Copies src to the dstsize buffer at dst. The copy will never
* overflow the destination buffer and the buffer will always be null
* terminated.
*/
size_t nsldapi_compat_strlcpy(char *dst, const char *src, size_t len)
{
size_t slen = strlen(src);
size_t copied;
if (len == 0)
return (slen);
if (slen >= len)
copied = len - 1;
else
copied = slen;
SAFEMEMCPY(dst, src, copied);
dst[copied] = '\0';
return (slen);
}
#endif

View file

@ -0,0 +1,559 @@
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is Mozilla Communicator client code, released
* March 31, 1998.
*
* The Initial Developer of the Original Code is
* Netscape Communications Corporation.
* Portions created by the Initial Developer are Copyright (C) 1998-1999
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
*
* Alternatively, the contents of this file may be used under the terms of
* either of the GNU General Public License Version 2 or later (the "GPL"),
* or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
/* control.c - routines to handle ldapv3 controls */
#include "ldap-int.h"
static LDAPControl *ldap_control_dup( LDAPControl *ctrl );
static int ldap_control_copy_contents( LDAPControl *ctrl_dst,
LDAPControl *ctrl_src );
/*
* Append a list of LDAPv3 controls to ber. If ctrls is NULL, use default
* set of controls from ld.
* Return an LDAP error code (LDAP_SUCCESS if all goes well).
* If closeseq is non-zero, we do an extra ber_put_seq() as well.
*/
int
nsldapi_put_controls( LDAP *ld, LDAPControl **ctrls, int closeseq,
BerElement *ber )
{
LDAPControl *c;
int rc, i;
rc = LDAP_ENCODING_ERROR; /* the most popular error */
/* if no controls were passed in, use global list from LDAP * */
LDAP_MUTEX_LOCK( ld, LDAP_CTRL_LOCK );
if ( ctrls == NULL ) {
ctrls = ld->ld_servercontrols;
}
/* if there are no controls then we are done */
if ( ctrls == NULL || ctrls[ 0 ] == NULL ) {
goto clean_exit;
}
/*
* If we're using LDAPv2 or earlier we can't send any controls, so
* we just ignore them unless one is marked critical, in which case
* we return an error.
*/
if ( NSLDAPI_LDAP_VERSION( ld ) < LDAP_VERSION3 ) {
for ( i = 0; ctrls != NULL && ctrls[i] != NULL; i++ ) {
if ( ctrls[i]->ldctl_iscritical ) {
rc = LDAP_NOT_SUPPORTED;
goto error_exit;
}
}
goto clean_exit;
}
/*
* encode the controls as a Sequence of Sequence
*/
if ( ber_printf( ber, "t{", LDAP_TAG_CONTROLS ) == -1 ) {
goto error_exit;
}
for ( i = 0; ctrls[i] != NULL; i++ ) {
c = ctrls[i];
if ( ber_printf( ber, "{s", c->ldctl_oid ) == -1 ) {
goto error_exit;
}
/* criticality is "BOOLEAN DEFAULT FALSE" */
/* therefore, it should only be encoded if it exists AND is TRUE */
if ( c->ldctl_iscritical ) {
if ( ber_printf( ber, "b", (int)c->ldctl_iscritical )
== -1 ) {
goto error_exit;
}
}
if ( c->ldctl_value.bv_val != NULL ) {
if ( ber_printf( ber, "o", c->ldctl_value.bv_val,
c->ldctl_value.bv_len )
== -1 ) {
goto error_exit;
}
}
if ( ber_put_seq( ber ) == -1 ) {
goto error_exit;
}
}
if ( ber_put_seq( ber ) == -1 ) {
goto error_exit;
}
clean_exit:
LDAP_MUTEX_UNLOCK( ld, LDAP_CTRL_LOCK );
if ( closeseq && ber_put_seq( ber ) == -1 ) {
goto error_exit;
}
return( LDAP_SUCCESS );
error_exit:
LDAP_MUTEX_UNLOCK( ld, LDAP_CTRL_LOCK );
LDAP_SET_LDERRNO( ld, rc, NULL, NULL );
return( rc );
}
/*
* Pull controls out of "ber" (if any present) and return them in "controlsp."
* Returns an LDAP error code.
*/
int
nsldapi_get_controls( BerElement *ber, LDAPControl ***controlsp )
{
LDAPControl *newctrl;
ber_tag_t tag;
ber_len_t len;
int rc, maxcontrols, curcontrols;
char *last;
/*
* Each LDAPMessage can have a set of controls appended
* to it. Controls are used to extend the functionality
* of an LDAP operation (e.g., add an attribute size limit
* to the search operation). These controls look like this:
*
* Controls ::= SEQUENCE OF Control
*
* Control ::= SEQUENCE {
* controlType LDAPOID,
* criticality BOOLEAN DEFAULT FALSE,
* controlValue OCTET STRING
* }
*/
LDAPDebug( LDAP_DEBUG_TRACE, "=> nsldapi_get_controls\n", 0, 0, 0 );
*controlsp = NULL;
/*
* check to see if controls were included
*/
if ( ber_get_option( ber, LBER_OPT_REMAINING_BYTES, &len ) != 0 ) {
return( LDAP_DECODING_ERROR ); /* unexpected error */
}
if ( len == 0 ) {
LDAPDebug( LDAP_DEBUG_TRACE,
"<= nsldapi_get_controls no controls\n", 0, 0, 0 );
return( LDAP_SUCCESS ); /* no controls */
}
if (( tag = ber_peek_tag( ber, &len )) != LDAP_TAG_CONTROLS ) {
if ( tag == LBER_ERROR ) {
LDAPDebug( LDAP_DEBUG_TRACE,
"<= nsldapi_get_controls LDAP_PROTOCOL_ERROR\n",
0, 0, 0 );
return( LDAP_DECODING_ERROR ); /* decoding error */
}
/*
* We found something other than controls. This should never
* happen in LDAPv3, but we don't treat this is a hard error --
* we just ignore the extra stuff.
*/
LDAPDebug( LDAP_DEBUG_TRACE,
"<= nsldapi_get_controls ignoring unrecognized data in message (tag 0x%x)\n",
tag, 0, 0 );
return( LDAP_SUCCESS );
}
maxcontrols = curcontrols = 0;
for ( tag = ber_first_element( ber, &len, &last );
tag != LBER_ERROR && tag != LBER_END_OF_SEQORSET;
tag = ber_next_element( ber, &len, last ) ) {
if ( curcontrols >= maxcontrols - 1 ) {
#define CONTROL_GRABSIZE 5
maxcontrols += CONTROL_GRABSIZE;
*controlsp = (struct ldapcontrol **)NSLDAPI_REALLOC(
(char *)*controlsp, maxcontrols *
sizeof(struct ldapcontrol *) );
if ( *controlsp == NULL ) {
rc = LDAP_NO_MEMORY;
goto free_and_return;
}
}
if (( newctrl = (struct ldapcontrol *)NSLDAPI_CALLOC( 1,
sizeof(LDAPControl))) == NULL ) {
rc = LDAP_NO_MEMORY;
goto free_and_return;
}
(*controlsp)[curcontrols++] = newctrl;
(*controlsp)[curcontrols] = NULL;
if ( ber_scanf( ber, "{a", &newctrl->ldctl_oid )
== LBER_ERROR ) {
rc = LDAP_DECODING_ERROR;
goto free_and_return;
}
/* the criticality is optional */
if ( ber_peek_tag( ber, &len ) == LBER_BOOLEAN ) {
int aint;
if ( ber_scanf( ber, "b", &aint ) == LBER_ERROR ) {
rc = LDAP_DECODING_ERROR;
goto free_and_return;
}
newctrl->ldctl_iscritical = (char)aint; /* XXX lossy cast */
} else {
/* absent is synonomous with FALSE */
newctrl->ldctl_iscritical = 0;
}
/* the control value is optional */
if ( ber_peek_tag( ber, &len ) == LBER_OCTETSTRING ) {
if ( ber_scanf( ber, "o", &newctrl->ldctl_value )
== LBER_ERROR ) {
rc = LDAP_DECODING_ERROR;
goto free_and_return;
}
} else {
(newctrl->ldctl_value).bv_val = NULL;
(newctrl->ldctl_value).bv_len = 0;
}
}
if ( tag == LBER_ERROR ) {
rc = LDAP_DECODING_ERROR;
goto free_and_return;
}
LDAPDebug( LDAP_DEBUG_TRACE,
"<= nsldapi_get_controls found %d controls\n", curcontrols, 0, 0 );
return( LDAP_SUCCESS );
free_and_return:;
ldap_controls_free( *controlsp );
*controlsp = NULL;
LDAPDebug( LDAP_DEBUG_TRACE,
"<= nsldapi_get_controls error 0x%x\n", rc, 0, 0 );
return( rc );
}
/*
* Skips forward in a ber to find a control tag, then calls on
* nsldapi_get_controls() to parse them into an LDAPControl list.
* Returns an LDAP error code.
*/
int
nsldapi_find_controls( BerElement *ber, LDAPControl ***controlsp )
{
ber_tag_t tag;
ber_len_t len;
if ( ber == NULLBER ) {
return( LDAP_DECODING_ERROR );
}
tag = ber_peek_tag( ber, &len );
while( tag != LDAP_TAG_CONTROLS && tag != LBER_DEFAULT ) {
tag = ber_skip_tag( ber, &len );
/* Skip ahead to the next sequence */
ber->ber_ptr += len;
tag = ber_peek_tag( ber, &len );
}
return( nsldapi_get_controls( ber, controlsp ) );
}
void
LDAP_CALL
ldap_control_free( LDAPControl *ctrl )
{
if ( ctrl != NULL ) {
if ( ctrl->ldctl_oid != NULL ) {
NSLDAPI_FREE( ctrl->ldctl_oid );
}
if ( ctrl->ldctl_value.bv_val != NULL ) {
NSLDAPI_FREE( ctrl->ldctl_value.bv_val );
}
NSLDAPI_FREE( (char *)ctrl );
}
}
void
LDAP_CALL
ldap_controls_free( LDAPControl **ctrls )
{
int i;
if ( ctrls != NULL ) {
for ( i = 0; ctrls[i] != NULL; i++ ) {
ldap_control_free( ctrls[i] );
}
NSLDAPI_FREE( (char *)ctrls );
}
}
LDAPControl *
LDAP_CALL
ldap_find_control( const char *oid, LDAPControl **ctrls )
{
int i, foundControl;
LDAPControl *Ctrlp = NULL;
/* find the control in the list of controls if it exists */
if ( ctrls == NULL ) {
return ( NULL );
}
foundControl = 0;
for ( i = 0; (( ctrls[i] != NULL ) && ( !foundControl )); i++ ) {
foundControl = !strcmp( ctrls[i]->ldctl_oid, oid );
}
if ( !foundControl ) {
return ( NULL );
} else {
/* let local var point to the control */
Ctrlp = ctrls[i-1];
}
return( Ctrlp );
}
#if 0
LDAPControl **
LDAP_CALL
ldap_control_append( LDAPControl **ctrl_src, LDAPControl *ctrl )
{
int nctrls = 0;
LDAPControl **ctrlp;
int i;
if ( NULL == ctrl )
return ( NULL );
/* Count the existing controls */
if ( NULL != ctrl_src ) {
while( NULL != ctrl_src[nctrls] ) {
nctrls++;
}
}
/* allocate the new control structure */
if ( ( ctrlp = (LDAPControl **)NSLDAPI_MALLOC( sizeof(LDAPControl *)
* (nctrls + 2) ) ) == NULL ) {
return( NULL );
}
memset( ctrlp, 0, sizeof(*ctrlp) * (nctrls + 2) );
for( i = 0; i < (nctrls + 1); i++ ) {
if ( i < nctrls ) {
ctrlp[i] = ldap_control_dup( ctrl_src[i] );
} else {
ctrlp[i] = ldap_control_dup( ctrl );
}
if ( NULL == ctrlp[i] ) {
ldap_controls_free( ctrlp );
return( NULL );
}
}
return ctrlp;
}
#endif /* 0 */
/*
* Replace *ldctrls with a copy of newctrls.
* returns 0 if successful.
* return -1 if not and set error code inside LDAP *ld.
*/
int
nsldapi_dup_controls( LDAP *ld, LDAPControl ***ldctrls, LDAPControl **newctrls )
{
int count;
if ( *ldctrls != NULL ) {
ldap_controls_free( *ldctrls );
}
if ( newctrls == NULL || newctrls[0] == NULL ) {
*ldctrls = NULL;
return( 0 );
}
for ( count = 0; newctrls[ count ] != NULL; ++count ) {
;
}
if (( *ldctrls = (LDAPControl **)NSLDAPI_MALLOC(( count + 1 ) *
sizeof( LDAPControl *))) == NULL ) {
LDAP_SET_LDERRNO( ld, LDAP_NO_MEMORY, NULL, NULL );
return( -1 );
}
(*ldctrls)[ count ] = NULL;
for ( count = 0; newctrls[ count ] != NULL; ++count ) {
if (( (*ldctrls)[ count ] =
ldap_control_dup( newctrls[ count ] )) == NULL ) {
ldap_controls_free( *ldctrls );
*ldctrls = NULL;
LDAP_SET_LDERRNO( ld, LDAP_NO_MEMORY, NULL, NULL );
return( -1 );
}
}
return( 0 );
}
/*
* return a malloc'd copy of "ctrl" (NULL if memory allocation fails)
*/
static LDAPControl *
/* LDAP_CALL */ /* keep this routine internal for now */
ldap_control_dup( LDAPControl *ctrl )
{
LDAPControl *rctrl;
if (( rctrl = (LDAPControl *)NSLDAPI_MALLOC( sizeof( LDAPControl )))
== NULL ) {
return( NULL );
}
if ( ldap_control_copy_contents( rctrl, ctrl ) != LDAP_SUCCESS ) {
NSLDAPI_FREE( rctrl );
return( NULL );
}
return( rctrl );
}
/*
* duplicate the contents of "ctrl_src" and place in "ctrl_dst"
*/
static int
/* LDAP_CALL */ /* keep this routine internal for now */
ldap_control_copy_contents( LDAPControl *ctrl_dst, LDAPControl *ctrl_src )
{
size_t len;
if ( NULL == ctrl_dst || NULL == ctrl_src ) {
return( LDAP_PARAM_ERROR );
}
ctrl_dst->ldctl_iscritical = ctrl_src->ldctl_iscritical;
/* fill in the fields of this new control */
if (( ctrl_dst->ldctl_oid = nsldapi_strdup( ctrl_src->ldctl_oid ))
== NULL ) {
return( LDAP_NO_MEMORY );
}
len = (size_t)(ctrl_src->ldctl_value).bv_len;
if ( ctrl_src->ldctl_value.bv_val == NULL || len <= 0 ) {
ctrl_dst->ldctl_value.bv_len = 0;
ctrl_dst->ldctl_value.bv_val = NULL;
} else {
ctrl_dst->ldctl_value.bv_len = len;
if (( ctrl_dst->ldctl_value.bv_val = NSLDAPI_MALLOC( len ))
== NULL ) {
NSLDAPI_FREE( ctrl_dst->ldctl_oid );
return( LDAP_NO_MEMORY );
}
SAFEMEMCPY( ctrl_dst->ldctl_value.bv_val,
ctrl_src->ldctl_value.bv_val, len );
}
return ( LDAP_SUCCESS );
}
/*
* build an allocated LDAPv3 control. Returns an LDAP error code.
*/
int
nsldapi_build_control( char *oid, BerElement *ber, int freeber, char iscritical,
LDAPControl **ctrlp )
{
int rc;
struct berval *bvp;
if ( ber == NULL ) {
bvp = NULL;
} else {
/* allocate struct berval with contents of the BER encoding */
rc = ber_flatten( ber, &bvp );
if ( freeber ) {
ber_free( ber, 1 );
}
if ( rc == -1 ) {
return( LDAP_NO_MEMORY );
}
}
/* allocate the new control structure */
if (( *ctrlp = (LDAPControl *)NSLDAPI_MALLOC( sizeof(LDAPControl)))
== NULL ) {
if ( bvp != NULL ) {
ber_bvfree( bvp );
}
return( LDAP_NO_MEMORY );
}
/* fill in the fields of this new control */
(*ctrlp)->ldctl_iscritical = iscritical;
if (( (*ctrlp)->ldctl_oid = nsldapi_strdup( oid )) == NULL ) {
NSLDAPI_FREE( *ctrlp );
if ( bvp != NULL ) {
ber_bvfree( bvp );
}
return( LDAP_NO_MEMORY );
}
if ( bvp == NULL ) {
(*ctrlp)->ldctl_value.bv_len = 0;
(*ctrlp)->ldctl_value.bv_val = NULL;
} else {
(*ctrlp)->ldctl_value = *bvp; /* struct copy */
NSLDAPI_FREE( bvp ); /* free container, not contents! */
}
return( LDAP_SUCCESS );
}

View file

@ -0,0 +1,67 @@
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is Mozilla Communicator client code, released
* March 31, 1998.
*
* The Initial Developer of the Original Code is
* Netscape Communications Corporation.
* Portions created by the Initial Developer are Copyright (C) 1998-1999
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
*
* Alternatively, the contents of this file may be used under the terms of
* either of the GNU General Public License Version 2 or later (the "GPL"),
* or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
/*
* Copyright (c) 1990 Regents of the University of Michigan.
* All rights reserved.
*/
/*
* countvalues.c
*/
#include "ldap-int.h"
int
LDAP_CALL
ldap_count_values( char **vals )
{
int i;
if ( vals == NULL )
return( 0 );
for ( i = 0; vals[i] != NULL; i++ )
; /* NULL */
return( i );
}
int
LDAP_CALL
ldap_count_values_len( struct berval **vals )
{
return( ldap_count_values( (char **) vals ) );
}

View file

@ -0,0 +1,169 @@
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is Mozilla Communicator client code, released
* March 31, 1998.
*
* The Initial Developer of the Original Code is
* Netscape Communications Corporation.
* Portions created by the Initial Developer are Copyright (C) 1998-1999
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
*
* Alternatively, the contents of this file may be used under the terms of
* either of the GNU General Public License Version 2 or later (the "GPL"),
* or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
/*
* delete.c
*/
#if 0
#ifndef lint
static char copyright[] = "@(#) Copyright (c) 1990 Regents of the University of Michigan.\nAll rights reserved.\n";
#endif
#endif
#include "ldap-int.h"
/*
* ldap_delete - initiate an ldap delete operation. Parameters:
*
* ld LDAP descriptor
* dn DN of the object to delete
*
* Example:
* msgid = ldap_delete( ld, dn );
*/
int
LDAP_CALL
ldap_delete( LDAP *ld, const char *dn )
{
int msgid;
LDAPDebug( LDAP_DEBUG_TRACE, "ldap_delete\n", 0, 0, 0 );
if ( ldap_delete_ext( ld, dn, NULL, NULL, &msgid ) == LDAP_SUCCESS ) {
return( msgid );
} else {
return( -1 ); /* error is in ld handle */
}
}
int
LDAP_CALL
ldap_delete_ext( LDAP *ld, const char *dn, LDAPControl **serverctrls,
LDAPControl **clientctrls, int *msgidp )
{
BerElement *ber;
int rc, lderr;
/*
* A delete request looks like this:
* DelRequet ::= DistinguishedName,
*/
LDAPDebug( LDAP_DEBUG_TRACE, "ldap_delete_ext\n", 0, 0, 0 );
if ( !NSLDAPI_VALID_LDAP_POINTER( ld )) {
return( LDAP_PARAM_ERROR );
}
if ( !NSLDAPI_VALID_LDAPMESSAGE_POINTER( msgidp ))
{
LDAP_SET_LDERRNO( ld, LDAP_PARAM_ERROR, NULL, NULL );
return( LDAP_PARAM_ERROR );
}
if ( dn == NULL ) {
dn = "";
}
LDAP_MUTEX_LOCK( ld, LDAP_MSGID_LOCK );
*msgidp = ++ld->ld_msgid;
LDAP_MUTEX_UNLOCK( ld, LDAP_MSGID_LOCK );
/* see if we should add to the cache */
if ( ld->ld_cache_on && ld->ld_cache_delete != NULL ) {
LDAP_MUTEX_LOCK( ld, LDAP_CACHE_LOCK );
if ( (rc = (ld->ld_cache_delete)( ld, *msgidp, LDAP_REQ_DELETE,
dn )) != 0 ) {
*msgidp = rc;
LDAP_MUTEX_UNLOCK( ld, LDAP_CACHE_LOCK );
return( LDAP_SUCCESS );
}
LDAP_MUTEX_UNLOCK( ld, LDAP_CACHE_LOCK );
}
/* create a message to send */
if (( lderr = nsldapi_alloc_ber_with_options( ld, &ber ))
!= LDAP_SUCCESS ) {
return( lderr );
}
if ( ber_printf( ber, "{its", *msgidp, LDAP_REQ_DELETE, dn )
== -1 ) {
lderr = LDAP_ENCODING_ERROR;
LDAP_SET_LDERRNO( ld, lderr, NULL, NULL );
ber_free( ber, 1 );
return( lderr );
}
if (( lderr = nsldapi_put_controls( ld, serverctrls, 1, ber ))
!= LDAP_SUCCESS ) {
ber_free( ber, 1 );
return( lderr );
}
/* send the message */
rc = nsldapi_send_initial_request( ld, *msgidp, LDAP_REQ_DELETE,
(char *)dn, ber );
*msgidp = rc;
return( rc < 0 ? LDAP_GET_LDERRNO( ld, NULL, NULL ) : LDAP_SUCCESS );
}
int
LDAP_CALL
ldap_delete_s( LDAP *ld, const char *dn )
{
return( ldap_delete_ext_s( ld, dn, NULL, NULL ));
}
int
LDAP_CALL
ldap_delete_ext_s( LDAP *ld, const char *dn, LDAPControl **serverctrls,
LDAPControl **clientctrls )
{
int err, msgid;
LDAPMessage *res;
if (( err = ldap_delete_ext( ld, dn, serverctrls, clientctrls,
&msgid )) != LDAP_SUCCESS ) {
return( err );
}
if ( ldap_result( ld, msgid, 1, (struct timeval *)NULL, &res ) == -1 ) {
return( LDAP_GET_LDERRNO( ld, NULL, NULL ) );
}
return( ldap_result2error( ld, res, 1 ) );
}

View file

@ -0,0 +1,770 @@
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is Mozilla Communicator client code, released
* March 31, 1998.
*
* The Initial Developer of the Original Code is
* Netscape Communications Corporation.
* Portions created by the Initial Developer are Copyright (C) 1998-1999
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
*
* Alternatively, the contents of this file may be used under the terms of
* either of the GNU General Public License Version 2 or later (the "GPL"),
* or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
/*
* Copyright (c) 1993, 1994 Regents of the University of Michigan.
* All rights reserved.
*
* Redistribution and use in source and binary forms are permitted
* provided that this notice is preserved and that due credit is given
* to the University of Michigan at Ann Arbor. The name of the University
* may not be used to endorse or promote products derived from this
* software without specific prior written permission. This software
* is provided ``as is'' without express or implied warranty.
*/
/*
* disptmpl.c: display template library routines for LDAP clients
*/
#include "ldap-int.h"
#include "disptmpl.h"
static void free_disptmpl( struct ldap_disptmpl *tmpl );
static int read_next_tmpl( char **bufp, long *blenp,
struct ldap_disptmpl **tmplp, int dtversion );
static char *tmploptions[] = {
"addable", "modrdn",
"altview",
NULL
};
static unsigned long tmploptvals[] = {
LDAP_DTMPL_OPT_ADDABLE, LDAP_DTMPL_OPT_ALLOWMODRDN,
LDAP_DTMPL_OPT_ALTVIEW,
};
static char *itemtypes[] = {
"cis", "mls", "dn",
"bool", "jpeg", "jpegbtn",
"fax", "faxbtn", "audiobtn",
"time", "date", "url",
"searchact", "linkact", "adddnact",
"addact", "verifyact", "mail",
NULL
};
static unsigned long itemsynids[] = {
LDAP_SYN_CASEIGNORESTR, LDAP_SYN_MULTILINESTR, LDAP_SYN_DN,
LDAP_SYN_BOOLEAN, LDAP_SYN_JPEGIMAGE, LDAP_SYN_JPEGBUTTON,
LDAP_SYN_FAXIMAGE, LDAP_SYN_FAXBUTTON, LDAP_SYN_AUDIOBUTTON,
LDAP_SYN_TIME, LDAP_SYN_DATE, LDAP_SYN_LABELEDURL,
LDAP_SYN_SEARCHACTION, LDAP_SYN_LINKACTION, LDAP_SYN_ADDDNACTION,
LDAP_SYN_ADDDNACTION, LDAP_SYN_VERIFYDNACTION,LDAP_SYN_RFC822ADDR,
};
static char *itemoptions[] = {
"ro", "sort",
"1val", "hide",
"required", "hideiffalse",
NULL
};
static unsigned long itemoptvals[] = {
LDAP_DITEM_OPT_READONLY, LDAP_DITEM_OPT_SORTVALUES,
LDAP_DITEM_OPT_SINGLEVALUED, LDAP_DITEM_OPT_HIDEIFEMPTY,
LDAP_DITEM_OPT_VALUEREQUIRED, LDAP_DITEM_OPT_HIDEIFFALSE,
};
#define ADDEF_CONSTANT "constant"
#define ADDEF_ADDERSDN "addersdn"
int
LDAP_CALL
ldap_init_templates( char *file, struct ldap_disptmpl **tmpllistp )
{
FILE *fp;
char *buf;
long rlen, len;
int rc, eof;
*tmpllistp = NULLDISPTMPL;
if (( fp = NSLDAPI_FOPEN( file, "r" )) == NULL ) {
return( LDAP_TMPL_ERR_FILE );
}
if ( fseek( fp, 0L, SEEK_END ) != 0 ) { /* move to end to get len */
fclose( fp );
return( LDAP_TMPL_ERR_FILE );
}
len = ftell( fp );
if ( fseek( fp, 0L, SEEK_SET ) != 0 ) { /* back to start of file */
fclose( fp );
return( LDAP_TMPL_ERR_FILE );
}
if (( buf = NSLDAPI_MALLOC( (size_t)len )) == NULL ) {
fclose( fp );
return( LDAP_TMPL_ERR_MEM );
}
rlen = fread( buf, 1, (size_t)len, fp );
eof = feof( fp );
fclose( fp );
if ( rlen != len && !eof ) { /* error: didn't get the whole file */
NSLDAPI_FREE( buf );
return( LDAP_TMPL_ERR_FILE );
}
rc = ldap_init_templates_buf( buf, rlen, tmpllistp );
NSLDAPI_FREE( buf );
return( rc );
}
int
LDAP_CALL
ldap_init_templates_buf( char *buf, long buflen,
struct ldap_disptmpl **tmpllistp )
{
int rc = 0, version;
char **toks;
struct ldap_disptmpl *prevtmpl, *tmpl;
*tmpllistp = prevtmpl = NULLDISPTMPL;
if ( nsldapi_next_line_tokens( &buf, &buflen, &toks ) != 2 ||
strcasecmp( toks[ 0 ], "version" ) != 0 ) {
nsldapi_free_strarray( toks );
return( LDAP_TMPL_ERR_SYNTAX );
}
version = atoi( toks[ 1 ] );
nsldapi_free_strarray( toks );
if ( version != LDAP_TEMPLATE_VERSION ) {
return( LDAP_TMPL_ERR_VERSION );
}
while ( buflen > 0 && ( rc = read_next_tmpl( &buf, &buflen, &tmpl,
version )) == 0 && tmpl != NULLDISPTMPL ) {
if ( prevtmpl == NULLDISPTMPL ) {
*tmpllistp = tmpl;
} else {
prevtmpl->dt_next = tmpl;
}
prevtmpl = tmpl;
}
if ( rc != 0 ) {
ldap_free_templates( *tmpllistp );
}
return( rc );
}
void
LDAP_CALL
ldap_free_templates( struct ldap_disptmpl *tmpllist )
{
struct ldap_disptmpl *tp, *nexttp;
if ( tmpllist != NULL ) {
for ( tp = tmpllist; tp != NULL; tp = nexttp ) {
nexttp = tp->dt_next;
free_disptmpl( tp );
}
}
}
static void
free_disptmpl( struct ldap_disptmpl *tmpl )
{
if ( tmpl != NULL ) {
if ( tmpl->dt_name != NULL ) {
NSLDAPI_FREE( tmpl->dt_name );
}
if ( tmpl->dt_pluralname != NULL ) {
NSLDAPI_FREE( tmpl->dt_pluralname );
}
if ( tmpl->dt_iconname != NULL ) {
NSLDAPI_FREE( tmpl->dt_iconname );
}
if ( tmpl->dt_authattrname != NULL ) {
NSLDAPI_FREE( tmpl->dt_authattrname );
}
if ( tmpl->dt_defrdnattrname != NULL ) {
NSLDAPI_FREE( tmpl->dt_defrdnattrname );
}
if ( tmpl->dt_defaddlocation != NULL ) {
NSLDAPI_FREE( tmpl->dt_defaddlocation );
}
if ( tmpl->dt_oclist != NULL ) {
struct ldap_oclist *ocp, *nextocp;
for ( ocp = tmpl->dt_oclist; ocp != NULL; ocp = nextocp ) {
nextocp = ocp->oc_next;
nsldapi_free_strarray( ocp->oc_objclasses );
NSLDAPI_FREE( ocp );
}
}
if ( tmpl->dt_adddeflist != NULL ) {
struct ldap_adddeflist *adp, *nextadp;
for ( adp = tmpl->dt_adddeflist; adp != NULL; adp = nextadp ) {
nextadp = adp->ad_next;
if( adp->ad_attrname != NULL ) {
NSLDAPI_FREE( adp->ad_attrname );
}
if( adp->ad_value != NULL ) {
NSLDAPI_FREE( adp->ad_value );
}
NSLDAPI_FREE( adp );
}
}
if ( tmpl->dt_items != NULL ) {
struct ldap_tmplitem *rowp, *nextrowp, *colp, *nextcolp;
for ( rowp = tmpl->dt_items; rowp != NULL; rowp = nextrowp ) {
nextrowp = rowp->ti_next_in_col;
for ( colp = rowp; colp != NULL; colp = nextcolp ) {
nextcolp = colp->ti_next_in_row;
if ( colp->ti_attrname != NULL ) {
NSLDAPI_FREE( colp->ti_attrname );
}
if ( colp->ti_label != NULL ) {
NSLDAPI_FREE( colp->ti_label );
}
if ( colp->ti_args != NULL ) {
nsldapi_free_strarray( colp->ti_args );
}
NSLDAPI_FREE( colp );
}
}
}
NSLDAPI_FREE( tmpl );
}
}
struct ldap_disptmpl *
LDAP_CALL
ldap_first_disptmpl( struct ldap_disptmpl *tmpllist )
{
return( tmpllist );
}
struct ldap_disptmpl *
LDAP_CALL
ldap_next_disptmpl( struct ldap_disptmpl *tmpllist,
struct ldap_disptmpl *tmpl )
{
return( tmpl == NULLDISPTMPL ? tmpl : tmpl->dt_next );
}
struct ldap_disptmpl *
LDAP_CALL
ldap_name2template( char *name, struct ldap_disptmpl *tmpllist )
{
struct ldap_disptmpl *dtp;
for ( dtp = ldap_first_disptmpl( tmpllist ); dtp != NULLDISPTMPL;
dtp = ldap_next_disptmpl( tmpllist, dtp )) {
if ( strcasecmp( name, dtp->dt_name ) == 0 ) {
return( dtp );
}
}
return( NULLDISPTMPL );
}
struct ldap_disptmpl *
LDAP_CALL
ldap_oc2template( char **oclist, struct ldap_disptmpl *tmpllist )
{
struct ldap_disptmpl *dtp;
struct ldap_oclist *oclp;
int i, j, needcnt, matchcnt;
if ( tmpllist == NULL || oclist == NULL || oclist[ 0 ] == NULL ) {
return( NULLDISPTMPL );
}
for ( dtp = ldap_first_disptmpl( tmpllist ); dtp != NULLDISPTMPL;
dtp = ldap_next_disptmpl( tmpllist, dtp )) {
for ( oclp = dtp->dt_oclist; oclp != NULLOCLIST;
oclp = oclp->oc_next ) {
needcnt = matchcnt = 0;
for ( i = 0; oclp->oc_objclasses[ i ] != NULL; ++i ) {
for ( j = 0; oclist[ j ] != NULL; ++j ) {
if ( strcasecmp( oclist[ j ], oclp->oc_objclasses[ i ] )
== 0 ) {
++matchcnt;
}
}
++needcnt;
}
if ( matchcnt == needcnt ) {
return( dtp );
}
}
}
return( NULLDISPTMPL );
}
struct ldap_tmplitem *
LDAP_CALL
ldap_first_tmplrow( struct ldap_disptmpl *tmpl )
{
return( tmpl->dt_items );
}
struct ldap_tmplitem *
LDAP_CALL
ldap_next_tmplrow( struct ldap_disptmpl *tmpl, struct ldap_tmplitem *row )
{
return( row == NULLTMPLITEM ? row : row->ti_next_in_col );
}
struct ldap_tmplitem *
LDAP_CALL
ldap_first_tmplcol( struct ldap_disptmpl *tmpl, struct ldap_tmplitem *row )
{
return( row );
}
struct ldap_tmplitem *
LDAP_CALL
ldap_next_tmplcol( struct ldap_disptmpl *tmpl, struct ldap_tmplitem *row,
struct ldap_tmplitem *col )
{
return( col == NULLTMPLITEM ? col : col->ti_next_in_row );
}
char **
LDAP_CALL
ldap_tmplattrs( struct ldap_disptmpl *tmpl, char **includeattrs,
int exclude, unsigned long syntaxmask )
{
/*
* this routine should filter out duplicate attributes...
*/
struct ldap_tmplitem *tirowp, *ticolp;
int i, attrcnt, memerr;
char **attrs;
attrcnt = 0;
memerr = 0;
if (( attrs = (char **)NSLDAPI_MALLOC( sizeof( char * ))) == NULL ) {
return( NULL );
}
if ( includeattrs != NULL ) {
for ( i = 0; !memerr && includeattrs[ i ] != NULL; ++i ) {
if (( attrs = (char **)NSLDAPI_REALLOC( attrs, ( attrcnt + 2 ) *
sizeof( char * ))) == NULL || ( attrs[ attrcnt++ ] =
nsldapi_strdup( includeattrs[ i ] )) == NULL ) {
memerr = 1;
} else {
attrs[ attrcnt ] = NULL;
}
}
}
for ( tirowp = ldap_first_tmplrow( tmpl );
!memerr && tirowp != NULLTMPLITEM;
tirowp = ldap_next_tmplrow( tmpl, tirowp )) {
for ( ticolp = ldap_first_tmplcol( tmpl, tirowp );
ticolp != NULLTMPLITEM;
ticolp = ldap_next_tmplcol( tmpl, tirowp, ticolp )) {
if ( syntaxmask != 0 ) {
if (( exclude &&
( syntaxmask & ticolp->ti_syntaxid ) != 0 ) ||
( !exclude &&
( syntaxmask & ticolp->ti_syntaxid ) == 0 )) {
continue;
}
}
if ( ticolp->ti_attrname != NULL ) {
if (( attrs = (char **)NSLDAPI_REALLOC( attrs, ( attrcnt + 2 )
* sizeof( char * ))) == NULL || ( attrs[ attrcnt++ ] =
nsldapi_strdup( ticolp->ti_attrname )) == NULL ) {
memerr = 1;
} else {
attrs[ attrcnt ] = NULL;
}
}
}
}
if ( memerr || attrcnt == 0 ) {
for ( i = 0; i < attrcnt; ++i ) {
if ( attrs[ i ] != NULL ) {
NSLDAPI_FREE( attrs[ i ] );
}
}
NSLDAPI_FREE( (char *)attrs );
return( NULL );
}
return( attrs );
}
static int
read_next_tmpl( char **bufp, long *blenp, struct ldap_disptmpl **tmplp,
int dtversion )
{
int i, j, tokcnt, samerow, adsource;
char **toks, *itemopts;
struct ldap_disptmpl *tmpl = NULL;
struct ldap_oclist *ocp = NULL, *prevocp = NULL;
struct ldap_adddeflist *adp = NULL, *prevadp = NULL;
struct ldap_tmplitem *rowp = NULL, *ip = NULL, *previp = NULL;
/*
* template name comes first
*/
if (( tokcnt = nsldapi_next_line_tokens( bufp, blenp, &toks )) != 1 ) {
nsldapi_free_strarray( toks );
return( tokcnt == 0 ? 0 : LDAP_TMPL_ERR_SYNTAX );
}
if (( tmpl = (struct ldap_disptmpl *)NSLDAPI_CALLOC( 1,
sizeof( struct ldap_disptmpl ))) == NULL ) {
nsldapi_free_strarray( toks );
return( LDAP_TMPL_ERR_MEM );
}
tmpl->dt_name = toks[ 0 ];
NSLDAPI_FREE( (char *)toks );
/*
* template plural name comes next
*/
if (( tokcnt = nsldapi_next_line_tokens( bufp, blenp, &toks )) != 1 ) {
nsldapi_free_strarray( toks );
free_disptmpl( tmpl );
return( LDAP_TMPL_ERR_SYNTAX );
}
tmpl->dt_pluralname = toks[ 0 ];
NSLDAPI_FREE( (char *)toks );
/*
* template icon name is next
*/
if (( tokcnt = nsldapi_next_line_tokens( bufp, blenp, &toks )) != 1 ) {
nsldapi_free_strarray( toks );
free_disptmpl( tmpl );
return( LDAP_TMPL_ERR_SYNTAX );
}
tmpl->dt_iconname = toks[ 0 ];
NSLDAPI_FREE( (char *)toks );
/*
* template options come next
*/
if (( tokcnt = nsldapi_next_line_tokens( bufp, blenp, &toks )) < 1 ) {
nsldapi_free_strarray( toks );
free_disptmpl( tmpl );
return( LDAP_TMPL_ERR_SYNTAX );
}
for ( i = 0; toks[ i ] != NULL; ++i ) {
for ( j = 0; tmploptions[ j ] != NULL; ++j ) {
if ( strcasecmp( toks[ i ], tmploptions[ j ] ) == 0 ) {
tmpl->dt_options |= tmploptvals[ j ];
}
}
}
nsldapi_free_strarray( toks );
/*
* object class list is next
*/
while (( tokcnt = nsldapi_next_line_tokens( bufp, blenp, &toks )) > 0 ) {
if (( ocp = (struct ldap_oclist *)NSLDAPI_CALLOC( 1,
sizeof( struct ldap_oclist ))) == NULL ) {
nsldapi_free_strarray( toks );
free_disptmpl( tmpl );
return( LDAP_TMPL_ERR_MEM );
}
ocp->oc_objclasses = toks;
if ( tmpl->dt_oclist == NULL ) {
tmpl->dt_oclist = ocp;
} else {
prevocp->oc_next = ocp;
}
prevocp = ocp;
}
if ( tokcnt < 0 ) {
free_disptmpl( tmpl );
return( LDAP_TMPL_ERR_SYNTAX );
}
/*
* read name of attribute to authenticate as
*/
if (( tokcnt = nsldapi_next_line_tokens( bufp, blenp, &toks )) != 1 ) {
nsldapi_free_strarray( toks );
free_disptmpl( tmpl );
return( LDAP_TMPL_ERR_SYNTAX );
}
if ( toks[ 0 ][ 0 ] != '\0' ) {
tmpl->dt_authattrname = toks[ 0 ];
} else {
NSLDAPI_FREE( toks[ 0 ] );
}
NSLDAPI_FREE( (char *)toks );
/*
* read default attribute to use for RDN
*/
if (( tokcnt = nsldapi_next_line_tokens( bufp, blenp, &toks )) != 1 ) {
nsldapi_free_strarray( toks );
free_disptmpl( tmpl );
return( LDAP_TMPL_ERR_SYNTAX );
}
tmpl->dt_defrdnattrname = toks[ 0 ];
NSLDAPI_FREE( (char *)toks );
/*
* read default location for new entries
*/
if (( tokcnt = nsldapi_next_line_tokens( bufp, blenp, &toks )) != 1 ) {
nsldapi_free_strarray( toks );
free_disptmpl( tmpl );
return( LDAP_TMPL_ERR_SYNTAX );
}
if ( toks[ 0 ][ 0 ] != '\0' ) {
tmpl->dt_defaddlocation = toks[ 0 ];
} else {
NSLDAPI_FREE( toks[ 0 ] );
}
NSLDAPI_FREE( (char *)toks );
/*
* read list of rules used to define default values for new entries
*/
while (( tokcnt = nsldapi_next_line_tokens( bufp, blenp, &toks )) > 0 ) {
if ( strcasecmp( ADDEF_CONSTANT, toks[ 0 ] ) == 0 ) {
adsource = LDAP_ADSRC_CONSTANTVALUE;
} else if ( strcasecmp( ADDEF_ADDERSDN, toks[ 0 ] ) == 0 ) {
adsource = LDAP_ADSRC_ADDERSDN;
} else {
adsource = 0;
}
if ( adsource == 0 || tokcnt < 2 ||
( adsource == LDAP_ADSRC_CONSTANTVALUE && tokcnt != 3 ) ||
( adsource == LDAP_ADSRC_ADDERSDN && tokcnt != 2 )) {
nsldapi_free_strarray( toks );
free_disptmpl( tmpl );
return( LDAP_TMPL_ERR_SYNTAX );
}
if (( adp = (struct ldap_adddeflist *)NSLDAPI_CALLOC( 1,
sizeof( struct ldap_adddeflist ))) == NULL ) {
nsldapi_free_strarray( toks );
free_disptmpl( tmpl );
return( LDAP_TMPL_ERR_MEM );
}
adp->ad_source = adsource;
adp->ad_attrname = toks[ 1 ];
if ( adsource == LDAP_ADSRC_CONSTANTVALUE ) {
adp->ad_value = toks[ 2 ];
}
NSLDAPI_FREE( toks[ 0 ] );
NSLDAPI_FREE( (char *)toks );
if ( tmpl->dt_adddeflist == NULL ) {
tmpl->dt_adddeflist = adp;
} else {
prevadp->ad_next = adp;
}
prevadp = adp;
}
/*
* item list is next
*/
samerow = 0;
while (( tokcnt = nsldapi_next_line_tokens( bufp, blenp, &toks )) > 0 ) {
if ( strcasecmp( toks[ 0 ], "item" ) == 0 ) {
if ( tokcnt < 4 ) {
nsldapi_free_strarray( toks );
free_disptmpl( tmpl );
return( LDAP_TMPL_ERR_SYNTAX );
}
if (( ip = (struct ldap_tmplitem *)NSLDAPI_CALLOC( 1,
sizeof( struct ldap_tmplitem ))) == NULL ) {
nsldapi_free_strarray( toks );
free_disptmpl( tmpl );
return( LDAP_TMPL_ERR_MEM );
}
/*
* find syntaxid from config file string
*/
while (( itemopts = strrchr( toks[ 1 ], ',' )) != NULL ) {
*itemopts++ = '\0';
for ( i = 0; itemoptions[ i ] != NULL; ++i ) {
if ( strcasecmp( itemopts, itemoptions[ i ] ) == 0 ) {
break;
}
}
if ( itemoptions[ i ] == NULL ) {
nsldapi_free_strarray( toks );
free_disptmpl( tmpl );
return( LDAP_TMPL_ERR_SYNTAX );
}
ip->ti_options |= itemoptvals[ i ];
}
for ( i = 0; itemtypes[ i ] != NULL; ++i ) {
if ( strcasecmp( toks[ 1 ], itemtypes[ i ] ) == 0 ) {
break;
}
}
if ( itemtypes[ i ] == NULL ) {
nsldapi_free_strarray( toks );
free_disptmpl( tmpl );
return( LDAP_TMPL_ERR_SYNTAX );
}
NSLDAPI_FREE( toks[ 0 ] );
NSLDAPI_FREE( toks[ 1 ] );
ip->ti_syntaxid = itemsynids[ i ];
ip->ti_label = toks[ 2 ];
if ( toks[ 3 ][ 0 ] == '\0' ) {
ip->ti_attrname = NULL;
NSLDAPI_FREE( toks[ 3 ] );
} else {
ip->ti_attrname = toks[ 3 ];
}
if ( toks[ 4 ] != NULL ) { /* extra args. */
for ( i = 0; toks[ i + 4 ] != NULL; ++i ) {
;
}
if (( ip->ti_args = (char **)NSLDAPI_CALLOC( i + 1,
sizeof( char * ))) == NULL ) {
free_disptmpl( tmpl );
return( LDAP_TMPL_ERR_MEM );
}
for ( i = 0; toks[ i + 4 ] != NULL; ++i ) {
ip->ti_args[ i ] = toks[ i + 4 ];
}
}
NSLDAPI_FREE( (char *)toks );
if ( tmpl->dt_items == NULL ) {
tmpl->dt_items = rowp = ip;
} else if ( samerow ) {
previp->ti_next_in_row = ip;
} else {
rowp->ti_next_in_col = ip;
rowp = ip;
}
previp = ip;
samerow = 0;
} else if ( strcasecmp( toks[ 0 ], "samerow" ) == 0 ) {
nsldapi_free_strarray( toks );
samerow = 1;
} else {
nsldapi_free_strarray( toks );
free_disptmpl( tmpl );
return( LDAP_TMPL_ERR_SYNTAX );
}
}
if ( tokcnt < 0 ) {
free_disptmpl( tmpl );
return( LDAP_TMPL_ERR_SYNTAX );
}
*tmplp = tmpl;
return( 0 );
}
struct tmplerror {
int e_code;
char *e_reason;
};
static struct tmplerror ldap_tmplerrlist[] = {
{ LDAP_TMPL_ERR_VERSION, "Bad template version" },
{ LDAP_TMPL_ERR_MEM, "Out of memory" },
{ LDAP_TMPL_ERR_SYNTAX, "Bad template syntax" },
{ LDAP_TMPL_ERR_FILE, "File error reading template" },
{ -1, 0 }
};
char *
LDAP_CALL
ldap_tmplerr2string( int err )
{
int i;
for ( i = 0; ldap_tmplerrlist[i].e_code != -1; i++ ) {
if ( err == ldap_tmplerrlist[i].e_code )
return( ldap_tmplerrlist[i].e_reason );
}
return( "Unknown error" );
}

View file

@ -0,0 +1,178 @@
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is Mozilla Communicator client code, released
* March 31, 1998.
*
* The Initial Developer of the Original Code is
* Netscape Communications Corporation.
* Portions created by the Initial Developer are Copyright (C) 1998-1999
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
*
* Alternatively, the contents of this file may be used under the terms of
* either of the GNU General Public License Version 2 or later (the "GPL"),
* or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
/*
* Microsoft Windows specifics for LIBLDAP DLL
*/
#include "ldap.h"
#include "lber.h"
#ifdef _WIN32
/* Lifted from Q125688
* How to Port a 16-bit DLL to a Win32 DLL
* on the MSVC 4.0 CD
*/
BOOL WINAPI DllMain (HANDLE hModule, DWORD fdwReason, LPVOID lpReserved)
{
switch (fdwReason)
{
case DLL_PROCESS_ATTACH:
/* Code from LibMain inserted here. Return TRUE to keep the
DLL loaded or return FALSE to fail loading the DLL.
You may have to modify the code in your original LibMain to
account for the fact that it may be called more than once.
You will get one DLL_PROCESS_ATTACH for each process that
loads the DLL. This is different from LibMain which gets
called only once when the DLL is loaded. The only time this
is critical is when you are using shared data sections.
If you are using shared data sections for statically
allocated data, you will need to be careful to initialize it
only once. Check your code carefully.
Certain one-time initializations may now need to be done for
each process that attaches. You may also not need code from
your original LibMain because the operating system may now
be doing it for you.
*/
/*
* 16 bit code calls UnlockData()
* which is mapped to UnlockSegment in windows.h
* in 32 bit world UnlockData is not defined anywhere
* UnlockSegment is mapped to GlobalUnfix in winbase.h
* and the docs for both UnlockSegment and GlobalUnfix say
* ".. function is oboslete. Segments have no meaning
* in the 32-bit environment". So we do nothing here.
*/
/* If we are building a version that includes the security libraries,
* we have to initialize Winsock here. If not, we can defer until the
* first real socket call is made (in mozock.c).
*/
#ifdef LINK_SSL
{
WSADATA wsaData;
WSAStartup(0x0101, &wsaData);
}
#endif
break;
case DLL_THREAD_ATTACH:
/* Called each time a thread is created in a process that has
already loaded (attached to) this DLL. Does not get called
for each thread that exists in the process before it loaded
the DLL.
Do thread-specific initialization here.
*/
break;
case DLL_THREAD_DETACH:
/* Same as above, but called when a thread in the process
exits.
Do thread-specific cleanup here.
*/
break;
case DLL_PROCESS_DETACH:
/* Code from _WEP inserted here. This code may (like the
LibMain) not be necessary. Check to make certain that the
operating system is not doing it for you.
*/
#ifdef LINK_SSL
WSACleanup();
#endif
break;
}
/* The return value is only used for DLL_PROCESS_ATTACH; all other
conditions are ignored. */
return TRUE; // successful DLL_PROCESS_ATTACH
}
#else
int CALLBACK
LibMain( HINSTANCE hinst, WORD wDataSeg, WORD cbHeapSize, LPSTR lpszCmdLine )
{
/*UnlockData( 0 );*/
return( 1 );
}
BOOL CALLBACK __loadds WEP(BOOL fSystemExit)
{
WSACleanup();
return TRUE;
}
#endif
#ifdef LDAP_DEBUG
#ifndef _WIN32
#include <stdarg.h>
#include <stdio.h>
void LDAP_C LDAPDebug( int level, char* fmt, ... )
{
static char debugBuf[1024];
if (ldap_debug & level)
{
va_list ap;
va_start (ap, fmt);
_snprintf (debugBuf, sizeof(debugBuf), fmt, ap);
va_end (ap);
OutputDebugString (debugBuf);
}
}
#endif
#endif
#ifndef _WIN32
/* The 16-bit version of the RTL does not implement perror() */
#include <stdio.h>
void perror( const char *msg )
{
char buf[128];
wsprintf( buf, "%s: error %d\n", msg, WSAGetLastError()) ;
OutputDebugString( buf );
}
#endif

View file

@ -0,0 +1,227 @@
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is Mozilla Communicator client code, released
* March 31, 1998.
*
* The Initial Developer of the Original Code is
* Netscape Communications Corporation.
* Portions created by the Initial Developer are Copyright (C) 1998-1999
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
*
* Alternatively, the contents of this file may be used under the terms of
* either of the GNU General Public License Version 2 or later (the "GPL"),
* or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
/*
* Copyright (c) 1993, 1994 Regents of the University of Michigan.
* All rights reserved.
*
* Redistribution and use in source and binary forms are permitted
* provided that this notice is preserved and that due credit is given
* to the University of Michigan at Ann Arbor. The name of the University
* may not be used to endorse or promote products derived from this
* software without specific prior written permission. This software
* is provided ``as is'' without express or implied warranty.
*/
/*
* dsparse.c: parsing routines used by display template and search
* preference file library routines for LDAP clients.
*
*/
#include "ldap-int.h"
static int next_line( char **bufp, long *blenp, char **linep );
static char *next_token( char ** sp );
int
nsldapi_next_line_tokens( char **bufp, long *blenp, char ***toksp )
{
char *p, *line, *token, **toks;
int rc, tokcnt;
*toksp = NULL;
if (( rc = next_line( bufp, blenp, &line )) <= 0 ) {
return( rc );
}
if (( toks = (char **)NSLDAPI_CALLOC( 1, sizeof( char * ))) == NULL ) {
NSLDAPI_FREE( line );
return( -1 );
}
tokcnt = 0;
p = line;
while (( token = next_token( &p )) != NULL ) {
if (( toks = (char **)NSLDAPI_REALLOC( toks, ( tokcnt + 2 ) *
sizeof( char * ))) == NULL ) {
NSLDAPI_FREE( (char *)toks );
NSLDAPI_FREE( line );
return( -1 );
}
toks[ tokcnt ] = token;
toks[ ++tokcnt ] = NULL;
}
if ( tokcnt == 1 && strcasecmp( toks[ 0 ], "END" ) == 0 ) {
tokcnt = 0;
nsldapi_free_strarray( toks );
toks = NULL;
}
NSLDAPI_FREE( line );
if ( tokcnt == 0 ) {
if ( toks != NULL ) {
NSLDAPI_FREE( (char *)toks );
}
} else {
*toksp = toks;
}
return( tokcnt );
}
static int
next_line( char **bufp, long *blenp, char **linep )
{
char *linestart, *line, *p;
long plen;
linestart = *bufp;
p = *bufp;
plen = *blenp;
do {
for ( linestart = p; plen > 0; ++p, --plen ) {
if ( *p == '\r' ) {
if ( plen > 1 && *(p+1) == '\n' ) {
++p;
--plen;
}
break;
}
if ( *p == '\n' ) {
if ( plen > 1 && *(p+1) == '\r' ) {
++p;
--plen;
}
break;
}
}
++p;
--plen;
} while ( plen > 0 && ( *linestart == '#' || linestart + 1 == p ));
*bufp = p;
*blenp = plen;
if ( plen <= 0 ) {
*linep = NULL;
return( 0 ); /* end of file */
}
if (( line = NSLDAPI_MALLOC( p - linestart )) == NULL ) {
*linep = NULL;
return( -1 ); /* fatal error */
}
SAFEMEMCPY( line, linestart, p - linestart );
line[ p - linestart - 1 ] = '\0';
*linep = line;
return( strlen( line ));
}
static char *
next_token( char **sp )
{
int in_quote = 0;
char *p, *tokstart, *t;
if ( **sp == '\0' ) {
return( NULL );
}
p = *sp;
while ( ldap_utf8isspace( p )) { /* skip leading white space */
++p;
}
if ( *p == '\0' ) {
return( NULL );
}
if ( *p == '\"' ) {
in_quote = 1;
++p;
}
t = tokstart = p;
for ( ;; ) {
if ( *p == '\0' || ( ldap_utf8isspace( p ) && !in_quote )) {
if ( *p != '\0' ) {
++p;
}
*t++ = '\0'; /* end of token */
break;
}
if ( *p == '\"' ) {
in_quote = !in_quote;
++p;
} else {
*t++ = *p++;
}
}
*sp = p;
if ( t == tokstart ) {
return( NULL );
}
return( nsldapi_strdup( tokstart ));
}
void
nsldapi_free_strarray( char **sap )
{
int i;
if ( sap != NULL ) {
for ( i = 0; sap[ i ] != NULL; ++i ) {
NSLDAPI_FREE( sap[ i ] );
}
NSLDAPI_FREE( (char *)sap );
}
}

View file

@ -0,0 +1,490 @@
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is Mozilla Communicator client code, released
* March 31, 1998.
*
* The Initial Developer of the Original Code is
* Netscape Communications Corporation.
* Portions created by the Initial Developer are Copyright (C) 1998-1999
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
*
* Alternatively, the contents of this file may be used under the terms of
* either of the GNU General Public License Version 2 or later (the "GPL"),
* or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
#include "ldap-int.h"
struct ldaperror {
int e_code;
char *e_reason;
};
static struct ldaperror ldap_errlist[] = {
{ LDAP_SUCCESS, "Success" },
{ LDAP_OPERATIONS_ERROR, "Operations error" },
{ LDAP_PROTOCOL_ERROR, "Protocol error" },
{ LDAP_TIMELIMIT_EXCEEDED, "Timelimit exceeded" },
{ LDAP_SIZELIMIT_EXCEEDED, "Sizelimit exceeded" },
{ LDAP_COMPARE_FALSE, "Compare false" },
{ LDAP_COMPARE_TRUE, "Compare true" },
{ LDAP_STRONG_AUTH_NOT_SUPPORTED, "Authentication method not supported" },
{ LDAP_STRONG_AUTH_REQUIRED, "Strong authentication required" },
{ LDAP_PARTIAL_RESULTS, "Partial results and referral received" },
{ LDAP_REFERRAL, "Referral received" },
{ LDAP_ADMINLIMIT_EXCEEDED, "Administrative limit exceeded" },
{ LDAP_UNAVAILABLE_CRITICAL_EXTENSION, "Unavailable critical extension" },
{ LDAP_CONFIDENTIALITY_REQUIRED, "Confidentiality required" },
{ LDAP_SASL_BIND_IN_PROGRESS, "SASL bind in progress" },
{ LDAP_NO_SUCH_ATTRIBUTE, "No such attribute" },
{ LDAP_UNDEFINED_TYPE, "Undefined attribute type" },
{ LDAP_INAPPROPRIATE_MATCHING, "Inappropriate matching" },
{ LDAP_CONSTRAINT_VIOLATION, "Constraint violation" },
{ LDAP_TYPE_OR_VALUE_EXISTS, "Type or value exists" },
{ LDAP_INVALID_SYNTAX, "Invalid syntax" },
{ LDAP_NO_SUCH_OBJECT, "No such object" },
{ LDAP_ALIAS_PROBLEM, "Alias problem" },
{ LDAP_INVALID_DN_SYNTAX, "Invalid DN syntax" },
{ LDAP_IS_LEAF, "Object is a leaf" },
{ LDAP_ALIAS_DEREF_PROBLEM, "Alias dereferencing problem" },
{ LDAP_INAPPROPRIATE_AUTH, "Inappropriate authentication" },
{ LDAP_INVALID_CREDENTIALS, "Invalid credentials" },
{ LDAP_INSUFFICIENT_ACCESS, "Insufficient access" },
{ LDAP_BUSY, "DSA is busy" },
{ LDAP_UNAVAILABLE, "DSA is unavailable" },
{ LDAP_UNWILLING_TO_PERFORM, "DSA is unwilling to perform" },
{ LDAP_LOOP_DETECT, "Loop detected" },
{ LDAP_SORT_CONTROL_MISSING, "Sort Control is missing" },
{ LDAP_INDEX_RANGE_ERROR, "Search results exceed the range specified by the offsets" },
{ LDAP_NAMING_VIOLATION, "Naming violation" },
{ LDAP_OBJECT_CLASS_VIOLATION, "Object class violation" },
{ LDAP_NOT_ALLOWED_ON_NONLEAF, "Operation not allowed on nonleaf" },
{ LDAP_NOT_ALLOWED_ON_RDN, "Operation not allowed on RDN" },
{ LDAP_ALREADY_EXISTS, "Already exists" },
{ LDAP_NO_OBJECT_CLASS_MODS, "Cannot modify object class" },
{ LDAP_RESULTS_TOO_LARGE, "Results too large" },
{ LDAP_AFFECTS_MULTIPLE_DSAS, "Affects multiple servers" },
{ LDAP_OTHER, "Unknown error" },
{ LDAP_SERVER_DOWN, "Can't contact LDAP server" },
{ LDAP_LOCAL_ERROR, "Local error" },
{ LDAP_ENCODING_ERROR, "Encoding error" },
{ LDAP_DECODING_ERROR, "Decoding error" },
{ LDAP_TIMEOUT, "Timed out" },
{ LDAP_AUTH_UNKNOWN, "Unknown authentication method" },
{ LDAP_FILTER_ERROR, "Bad search filter" },
{ LDAP_USER_CANCELLED, "User cancelled operation" },
{ LDAP_PARAM_ERROR, "Bad parameter to an ldap routine" },
{ LDAP_NO_MEMORY, "Out of memory" },
{ LDAP_CONNECT_ERROR, "Can't connect to the LDAP server" },
{ LDAP_NOT_SUPPORTED, "Not supported by this version of the LDAP protocol" },
{ LDAP_CONTROL_NOT_FOUND, "Requested LDAP control not found" },
{ LDAP_NO_RESULTS_RETURNED, "No results returned" },
{ LDAP_MORE_RESULTS_TO_RETURN, "More results to return" },
{ LDAP_CLIENT_LOOP, "Client detected loop" },
{ LDAP_REFERRAL_LIMIT_EXCEEDED, "Referral hop limit exceeded" },
{ -1, 0 }
};
char *
LDAP_CALL
ldap_err2string( int err )
{
int i;
LDAPDebug( LDAP_DEBUG_TRACE, "ldap_err2string\n", 0, 0, 0 );
for ( i = 0; ldap_errlist[i].e_code != -1; i++ ) {
if ( err == ldap_errlist[i].e_code )
return( ldap_errlist[i].e_reason );
}
return( "Unknown error" );
}
static char *
nsldapi_safe_strerror( int e )
{
char *s;
if (( s = strerror( e )) == NULL ) {
s = "unknown error";
}
return( s );
}
void
LDAP_CALL
ldap_perror( LDAP *ld, const char *s )
{
int i, err;
char *matched = NULL;
char *errmsg = NULL;
char *separator;
char msg[1024];
LDAPDebug( LDAP_DEBUG_TRACE, "ldap_perror\n", 0, 0, 0 );
if ( s == NULL ) {
s = separator = "";
} else {
separator = ": ";
}
if ( ld == NULL ) {
snprintf( msg, sizeof( msg ),
"%s%s%s", s, separator, nsldapi_safe_strerror( errno ) );
ber_err_print( msg );
return;
}
LDAP_MUTEX_LOCK( ld, LDAP_ERR_LOCK );
err = LDAP_GET_LDERRNO( ld, &matched, &errmsg );
for ( i = 0; ldap_errlist[i].e_code != -1; i++ ) {
if ( err == ldap_errlist[i].e_code ) {
snprintf( msg, sizeof( msg ),
"%s%s%s", s, separator, ldap_errlist[i].e_reason );
ber_err_print( msg );
if ( err == LDAP_CONNECT_ERROR ) {
ber_err_print( " - " );
ber_err_print( nsldapi_safe_strerror(
LDAP_GET_ERRNO( ld )));
}
ber_err_print( "\n" );
if ( matched != NULL && *matched != '\0' ) {
snprintf( msg, sizeof( msg ),
"%s%smatched: %s\n", s, separator, matched );
ber_err_print( msg );
}
if ( errmsg != NULL && *errmsg != '\0' ) {
snprintf( msg, sizeof( msg ),
"%s%sadditional info: %s\n", s, separator, errmsg );
ber_err_print( msg );
}
LDAP_MUTEX_UNLOCK( ld, LDAP_ERR_LOCK );
return;
}
}
snprintf( msg, sizeof( msg ),
"%s%sNot an LDAP errno %d\n", s, separator, err );
ber_err_print( msg );
LDAP_MUTEX_UNLOCK( ld, LDAP_ERR_LOCK );
}
int
LDAP_CALL
ldap_result2error( LDAP *ld, LDAPMessage *r, int freeit )
{
int lderr_parse, lderr;
lderr_parse = ldap_parse_result( ld, r, &lderr, NULL, NULL, NULL,
NULL, freeit );
if ( lderr_parse != LDAP_SUCCESS ) {
return( lderr_parse );
}
return( lderr );
}
int
LDAP_CALL
ldap_get_lderrno( LDAP *ld, char **m, char **s )
{
if ( !NSLDAPI_VALID_LDAP_POINTER( ld )) {
return( LDAP_PARAM_ERROR ); /* punt */
}
if ( ld->ld_get_lderrno_fn == NULL ) {
if ( m != NULL ) {
*m = ld->ld_matched;
}
if ( s != NULL ) {
*s = ld->ld_error;
}
return( ld->ld_errno );
} else {
return( ld->ld_get_lderrno_fn( m, s, ld->ld_lderrno_arg ) );
}
}
/*
* Note: there is no need for callers of ldap_set_lderrno() to lock the
* ld mutex. If applications intend to share an LDAP session handle
* between threads they *must* perform their own locking around the
* session handle or they must install a "set lderrno" thread callback
* function.
*
*/
int
LDAP_CALL
ldap_set_lderrno( LDAP *ld, int e, char *m, char *s )
{
if ( !NSLDAPI_VALID_LDAP_POINTER( ld )) {
return( LDAP_PARAM_ERROR );
}
if ( ld->ld_set_lderrno_fn != NULL ) {
ld->ld_set_lderrno_fn( e, m, s, ld->ld_lderrno_arg );
} else {
LDAP_MUTEX_LOCK( ld, LDAP_ERR_LOCK );
ld->ld_errno = e;
if ( ld->ld_matched ) {
NSLDAPI_FREE( ld->ld_matched );
}
ld->ld_matched = m;
if ( ld->ld_error ) {
NSLDAPI_FREE( ld->ld_error );
}
ld->ld_error = s;
LDAP_MUTEX_UNLOCK( ld, LDAP_ERR_LOCK );
}
return( LDAP_SUCCESS );
}
/*
* Returns an LDAP error that says whether parse succeeded. The error code
* from the LDAP result itself is returned in the errcodep result parameter.
* If any of the result params. (errcodep, matchednp, errmsgp, referralsp,
* or serverctrlsp) are NULL we don't return that info.
*/
int
LDAP_CALL
ldap_parse_result( LDAP *ld, LDAPMessage *res, int *errcodep, char **matchednp,
char **errmsgp, char ***referralsp, LDAPControl ***serverctrlsp,
int freeit )
{
LDAPMessage *lm;
int err, errcode;
char *m, *e;
m = e = NULL;
LDAPDebug( LDAP_DEBUG_TRACE, "ldap_parse_result\n", 0, 0, 0 );
if ( !NSLDAPI_VALID_LDAP_POINTER( ld ) ||
!NSLDAPI_VALID_LDAPMESSAGE_POINTER( res )) {
return( LDAP_PARAM_ERROR );
}
/* skip over entries and references to find next result in this chain */
for ( lm = res; lm != NULL; lm = lm->lm_chain ) {
if ( lm->lm_msgtype != LDAP_RES_SEARCH_ENTRY &&
lm->lm_msgtype != LDAP_RES_SEARCH_REFERENCE ) {
break;
}
}
if ( lm == NULL ) {
err = LDAP_NO_RESULTS_RETURNED;
LDAP_SET_LDERRNO( ld, err, NULL, NULL );
return( err );
}
err = nsldapi_parse_result( ld, lm->lm_msgtype, lm->lm_ber, &errcode,
&m, &e, referralsp, serverctrlsp );
if ( err == LDAP_SUCCESS ) {
if ( errcodep != NULL ) {
*errcodep = errcode;
}
if ( matchednp != NULL ) {
*matchednp = nsldapi_strdup( m );
}
if ( errmsgp != NULL ) {
*errmsgp = nsldapi_strdup( e );
}
/*
* if there are more result messages in the chain, arrange to
* return the special LDAP_MORE_RESULTS_TO_RETURN "error" code.
*/
for ( lm = lm->lm_chain; lm != NULL; lm = lm->lm_chain ) {
if ( lm->lm_msgtype != LDAP_RES_SEARCH_ENTRY &&
lm->lm_msgtype != LDAP_RES_SEARCH_REFERENCE ) {
err = LDAP_MORE_RESULTS_TO_RETURN;
break;
}
}
} else {
/* In this case, m and e were already freed by ber_scanf */
m = e = NULL;
}
if ( freeit ) {
ldap_msgfree( res );
}
LDAP_SET_LDERRNO( ld, ( err == LDAP_SUCCESS ) ? errcode : err, m, e );
/* nsldapi_parse_result set m and e, so we have to delete them if they exist.
Only delete them if they haven't been reused for matchednp or errmsgp.
if ( err == LDAP_SUCCESS ) {
if ( (m != NULL) && (matchednp == NULL) ) {
NSLDAPI_FREE( m );
}
if ( (e != NULL) && (errmsgp == NULL) ) {
NSLDAPI_FREE( e );
}
} */
return( err );
}
/*
* returns an LDAP error code indicating success or failure of parsing
* does NOT set any error information inside "ld"
*/
int
nsldapi_parse_result( LDAP *ld, int msgtype, BerElement *rber, int *errcodep,
char **matchednp, char **errmsgp, char ***referralsp,
LDAPControl ***serverctrlsp )
{
BerElement ber;
ber_len_t len;
ber_int_t errcode;
int berrc, err;
char *m, *e;
/*
* Parse the result message. LDAPv3 result messages look like this:
*
* LDAPResult ::= SEQUENCE {
* resultCode ENUMERATED { ... },
* matchedDN LDAPDN,
* errorMessage LDAPString,
* referral [3] Referral OPTIONAL
* opSpecificStuff OPTIONAL
* }
*
* all wrapped up in an LDAPMessage sequence which looks like this:
* LDAPMessage ::= SEQUENCE {
* messageID MessageID,
* LDAPResult CHOICE { ... }, // message type
* controls [0] Controls OPTIONAL
* }
*
* LDAPv2 messages don't include referrals or controls.
* LDAPv1 messages don't include matchedDN, referrals, or controls.
*
* ldap_result() pulls out the message id, so by the time a result
* message gets here we are sitting at the start of the LDAPResult.
*/
err = LDAP_SUCCESS; /* optimistic */
m = e = NULL;
if ( matchednp != NULL ) {
*matchednp = NULL;
}
if ( errmsgp != NULL ) {
*errmsgp = NULL;
}
if ( referralsp != NULL ) {
*referralsp = NULL;
}
if ( serverctrlsp != NULL ) {
*serverctrlsp = NULL;
}
ber = *rber; /* struct copy */
if ( NSLDAPI_LDAP_VERSION( ld ) < LDAP_VERSION2 ) {
berrc = ber_scanf( &ber, "{ia}", &errcode, &e );
} else {
if (( berrc = ber_scanf( &ber, "{iaa", &errcode, &m, &e ))
!= LBER_ERROR ) {
/* check for optional referrals */
if ( ber_peek_tag( &ber, &len ) == LDAP_TAG_REFERRAL ) {
if ( referralsp == NULL ) {
/* skip referrals */
berrc = ber_scanf( &ber, "x" );
} else {
/* suck out referrals */
berrc = ber_scanf( &ber, "v",
referralsp );
}
} else if ( referralsp != NULL ) {
*referralsp = NULL;
}
}
if ( berrc != LBER_ERROR ) {
/*
* skip past optional operation-specific elements:
* bind results - serverSASLcreds
* extendedop results - OID plus value
*/
if ( msgtype == LDAP_RES_BIND ) {
if ( ber_peek_tag( &ber, &len ) ==
LDAP_TAG_SASL_RES_CREDS ) {
berrc = ber_scanf( &ber, "x" );
}
} else if ( msgtype == LDAP_RES_EXTENDED ) {
if ( ber_peek_tag( &ber, &len ) ==
LDAP_TAG_EXOP_RES_OID ) {
berrc = ber_scanf( &ber, "x" );
}
if ( berrc != LBER_ERROR &&
ber_peek_tag( &ber, &len ) ==
LDAP_TAG_EXOP_RES_VALUE ) {
berrc = ber_scanf( &ber, "x" );
}
}
}
/* pull out controls (if requested and any are present) */
if ( berrc != LBER_ERROR && serverctrlsp != NULL &&
( berrc = ber_scanf( &ber, "}" )) != LBER_ERROR ) {
err = nsldapi_get_controls( &ber, serverctrlsp );
}
}
if ( berrc == LBER_ERROR && err == LDAP_SUCCESS ) {
err = LDAP_DECODING_ERROR;
}
if ( errcodep != NULL ) {
*errcodep = errcode;
}
if ( matchednp != NULL ) {
*matchednp = m;
} else if ( m != NULL ) {
NSLDAPI_FREE( m );
}
if ( errmsgp != NULL ) {
*errmsgp = e;
} else if ( e != NULL ) {
NSLDAPI_FREE( e );
}
return( err );
}

View file

@ -0,0 +1,275 @@
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is Mozilla Communicator client code, released
* March 31, 1998.
*
* The Initial Developer of the Original Code is
* Netscape Communications Corporation.
* Portions created by the Initial Developer are Copyright (C) 1998-1999
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
*
* Alternatively, the contents of this file may be used under the terms of
* either of the GNU General Public License Version 2 or later (the "GPL"),
* or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
#include "ldap-int.h"
/*
* ldap_extended_operation - initiate an arbitrary ldapv3 extended operation.
* the oid and data of the extended operation are supplied. Returns an
* LDAP error code.
*
* Example:
* struct berval exdata;
* char *exoid;
* int err, msgid;
* ... fill in oid and data ...
* err = ldap_extended_operation( ld, exoid, &exdata, NULL, NULL, &msgid );
*/
int
LDAP_CALL
ldap_extended_operation(
LDAP *ld,
const char *exoid,
const struct berval *exdata,
LDAPControl **serverctrls,
LDAPControl **clientctrls,
int *msgidp
)
{
BerElement *ber;
int rc, msgid;
/*
* the ldapv3 extended operation request looks like this:
*
* ExtendedRequest ::= [APPLICATION 23] SEQUENCE {
* requestName LDAPOID,
* requestValue OCTET STRING
* }
*
* all wrapped up in an LDAPMessage sequence.
*/
LDAPDebug( LDAP_DEBUG_TRACE, "ldap_extended_operation\n", 0, 0, 0 );
if ( !NSLDAPI_VALID_LDAP_POINTER( ld )) {
return( LDAP_PARAM_ERROR );
}
/* only ldapv3 or higher can do extended operations */
if ( NSLDAPI_LDAP_VERSION( ld ) < LDAP_VERSION3 ) {
rc = LDAP_NOT_SUPPORTED;
LDAP_SET_LDERRNO( ld, rc, NULL, NULL );
return( rc );
}
if ( msgidp == NULL || exoid == NULL || *exoid == '\0' ) {
rc = LDAP_PARAM_ERROR;
LDAP_SET_LDERRNO( ld, rc, NULL, NULL );
return( rc );
}
LDAP_MUTEX_LOCK( ld, LDAP_MSGID_LOCK );
msgid = ++ld->ld_msgid;
LDAP_MUTEX_UNLOCK( ld, LDAP_MSGID_LOCK );
#if 0
if ( ld->ld_cache_on && ld->ld_cache_extendedop != NULL ) {
LDAP_MUTEX_LOCK( ld, LDAP_CACHE_LOCK );
if ( (rc = (ld->ld_cache_extendedop)( ld, msgid,
LDAP_REQ_EXTENDED, exoid, cred )) != 0 ) {
LDAP_MUTEX_UNLOCK( ld, LDAP_CACHE_LOCK );
return( rc );
}
LDAP_MUTEX_UNLOCK( ld, LDAP_CACHE_LOCK );
}
#endif
/* create a message to send */
if (( rc = nsldapi_alloc_ber_with_options( ld, &ber ))
!= LDAP_SUCCESS ) {
return( rc );
}
/* fill it in */
if ( exdata ) {
if ( ber_printf( ber, "{it{tsto}", msgid, LDAP_REQ_EXTENDED,
LDAP_TAG_EXOP_REQ_OID, exoid, LDAP_TAG_EXOP_REQ_VALUE,
exdata->bv_val, exdata->bv_len ) == -1 ) {
rc = LDAP_ENCODING_ERROR;
LDAP_SET_LDERRNO( ld, rc, NULL, NULL );
ber_free( ber, 1 );
return( rc );
}
} else { /* some implementations are pretty strict on empty values */
if ( ber_printf( ber, "{it{ts}", msgid, LDAP_REQ_EXTENDED,
LDAP_TAG_EXOP_REQ_OID, exoid ) == -1 ) {
rc = LDAP_ENCODING_ERROR;
LDAP_SET_LDERRNO( ld, rc, NULL, NULL );
ber_free( ber, 1 );
return( rc );
}
}
if (( rc = nsldapi_put_controls( ld, serverctrls, 1, ber ))
!= LDAP_SUCCESS ) {
ber_free( ber, 1 );
return( rc );
}
/* send the message */
rc = nsldapi_send_initial_request( ld, msgid, LDAP_REQ_EXTENDED, NULL,
ber );
*msgidp = rc;
return( rc < 0 ? LDAP_GET_LDERRNO( ld, NULL, NULL ) : LDAP_SUCCESS );
}
/*
* ldap_extended_operation_s - perform an arbitrary ldapv3 extended operation.
* the oid and data of the extended operation are supplied. LDAP_SUCCESS
* is returned upon success, the ldap error code otherwise.
*
* Example:
* struct berval exdata, exretval;
* char *exoid;
* int rc;
* ... fill in oid and data ...
* rc = ldap_extended_operation_s( ld, exoid, &exdata, &exretval );
*/
int
LDAP_CALL
ldap_extended_operation_s(
LDAP *ld,
const char *requestoid,
const struct berval *requestdata,
LDAPControl **serverctrls,
LDAPControl **clientctrls,
char **retoidp,
struct berval **retdatap
)
{
int err, msgid;
LDAPMessage *result;
if (( err = ldap_extended_operation( ld, requestoid, requestdata,
serverctrls, clientctrls, &msgid )) != LDAP_SUCCESS ) {
return( err );
}
if ( ldap_result( ld, msgid, 1, (struct timeval *) 0, &result )
== -1 ) {
return( LDAP_GET_LDERRNO( ld, NULL, NULL ) );
}
if (( err = ldap_parse_extended_result( ld, result, retoidp, retdatap,
0 )) != LDAP_SUCCESS ) {
ldap_msgfree( result );
return( err );
}
return( ldap_result2error( ld, result, 1 ) );
}
/*
* Pull the oid returned by the server and the data out of an extended
* operation result. Return an LDAP error code.
*/
int
LDAP_CALL
ldap_parse_extended_result(
LDAP *ld,
LDAPMessage *res,
char **retoidp, /* may be NULL */
struct berval **retdatap, /* may be NULL */
int freeit
)
{
struct berelement ber;
ber_len_t len;
ber_int_t err;
char *m, *e, *roid;
struct berval *rdata;
LDAPDebug( LDAP_DEBUG_TRACE, "ldap_parse_extended_result\n", 0, 0, 0 );
if ( !NSLDAPI_VALID_LDAP_POINTER( ld )) {
return( LDAP_PARAM_ERROR );
}
if ( !NSLDAPI_VALID_LDAPMESSAGE_EXRESULT_POINTER( res )) {
return( LDAP_PARAM_ERROR );
}
m = e = NULL;
ber = *(res->lm_ber);
if ( NSLDAPI_LDAP_VERSION( ld ) < LDAP_VERSION3 ) {
LDAP_SET_LDERRNO( ld, LDAP_NOT_SUPPORTED, NULL, NULL );
return( LDAP_NOT_SUPPORTED );
}
if ( ber_scanf( &ber, "{iaa", &err, &m, &e ) == LBER_ERROR ) {
goto decoding_error;
}
roid = NULL;
if ( ber_peek_tag( &ber, &len ) == LDAP_TAG_EXOP_RES_OID ) {
if ( ber_scanf( &ber, "a", &roid ) == LBER_ERROR ) {
goto decoding_error;
}
}
if ( retoidp != NULL ) {
*retoidp = roid;
} else if ( roid != NULL ) {
NSLDAPI_FREE( roid );
}
rdata = NULL;
if ( ber_peek_tag( &ber, &len ) == LDAP_TAG_EXOP_RES_VALUE ) {
if ( ber_scanf( &ber, "O", &rdata ) == LBER_ERROR ) {
goto decoding_error;
}
}
if ( retdatap != NULL ) {
*retdatap = rdata;
} else if ( rdata != NULL ) {
ber_bvfree( rdata );
}
LDAP_SET_LDERRNO( ld, err, m, e );
if ( freeit ) {
ldap_msgfree( res );
}
return( LDAP_SUCCESS );
decoding_error:;
LDAP_SET_LDERRNO( ld, LDAP_DECODING_ERROR, NULL, NULL );
return( LDAP_DECODING_ERROR );
}

View file

@ -0,0 +1,156 @@
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is Mozilla Communicator client code, released
* March 31, 1998.
*
* The Initial Developer of the Original Code is
* Netscape Communications Corporation.
* Portions created by the Initial Developer are Copyright (C) 1998-1999
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
*
* Alternatively, the contents of this file may be used under the terms of
* either of the GNU General Public License Version 2 or later (the "GPL"),
* or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
/*
* Copyright (c) 1994 The Regents of the University of Michigan.
* All rights reserved.
*/
/*
* free.c - some free routines are included here to avoid having to
* link in lots of extra code when not using certain features
*/
#if 0
#ifndef lint
static char copyright[] = "@(#) Copyright (c) 1994 The Regents of the University of Michigan.\nAll rights reserved.\n";
#endif
#endif
#include "ldap-int.h"
void
LDAP_CALL
ldap_getfilter_free( LDAPFiltDesc *lfdp )
{
LDAPFiltList *flp, *nextflp;
LDAPFiltInfo *fip, *nextfip;
if ( lfdp == NULL ) {
return;
}
for ( flp = lfdp->lfd_filtlist; flp != NULL; flp = nextflp ) {
for ( fip = flp->lfl_ilist; fip != NULL; fip = nextfip ) {
nextfip = fip->lfi_next;
NSLDAPI_FREE( fip->lfi_filter );
NSLDAPI_FREE( fip->lfi_desc );
NSLDAPI_FREE( fip );
}
nextflp = flp->lfl_next;
NSLDAPI_FREE( flp->lfl_pattern );
NSLDAPI_FREE( flp->lfl_delims );
NSLDAPI_FREE( flp->lfl_tag );
NSLDAPI_FREE( flp );
}
if ( lfdp->lfd_curval != NULL ) {
NSLDAPI_FREE( lfdp->lfd_curval );
}
if ( lfdp->lfd_curvalcopy != NULL ) {
NSLDAPI_FREE( lfdp->lfd_curvalcopy );
}
if ( lfdp->lfd_curvalwords != NULL ) {
NSLDAPI_FREE( lfdp->lfd_curvalwords );
}
if ( lfdp->lfd_filtprefix != NULL ) {
NSLDAPI_FREE( lfdp->lfd_filtprefix );
}
if ( lfdp->lfd_filtsuffix != NULL ) {
NSLDAPI_FREE( lfdp->lfd_filtsuffix );
}
NSLDAPI_FREE( lfdp );
}
/*
* free a null-terminated array of pointers to mod structures. the
* structures are freed, not the array itself, unless the freemods
* flag is set.
*/
void
LDAP_CALL
ldap_mods_free( LDAPMod **mods, int freemods )
{
int i;
if ( !NSLDAPI_VALID_LDAPMOD_ARRAY( mods )) {
return;
}
for ( i = 0; mods[i] != NULL; i++ ) {
if ( mods[i]->mod_op & LDAP_MOD_BVALUES ) {
if ( mods[i]->mod_bvalues != NULL ) {
ber_bvecfree( mods[i]->mod_bvalues );
}
} else if ( mods[i]->mod_values != NULL ) {
ldap_value_free( mods[i]->mod_values );
}
if ( mods[i]->mod_type != NULL ) {
NSLDAPI_FREE( mods[i]->mod_type );
}
NSLDAPI_FREE( (char *) mods[i] );
}
if ( freemods )
NSLDAPI_FREE( (char *) mods );
}
/*
* ldap_memfree() is needed to ensure that memory allocated by the C runtime
* assocated with libldap is freed by the same runtime code.
*/
void
LDAP_CALL
ldap_memfree( void *s )
{
if ( s != NULL ) {
NSLDAPI_FREE( s );
}
}
/*
* ldap_ber_free() is just a cover for ber_free()
* ber_free() checks for ber == NULL, so we don't bother.
*/
void
LDAP_CALL
ldap_ber_free( BerElement *ber, int freebuf )
{
ber_free( ber, freebuf );
}

View file

@ -0,0 +1,73 @@
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is Mozilla Communicator client code, released
* March 31, 1998.
*
* The Initial Developer of the Original Code is
* Netscape Communications Corporation.
* Portions created by the Initial Developer are Copyright (C) 1998-1999
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
*
* Alternatively, the contents of this file may be used under the terms of
* either of the GNU General Public License Version 2 or later (the "GPL"),
* or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
/*
* Copyright (c) 1990 Regents of the University of Michigan.
* All rights reserved.
*/
/*
* freevalues.c
*/
#include "ldap-int.h"
void
LDAP_CALL
ldap_value_free( char **vals )
{
int i;
if ( vals == NULL )
return;
for ( i = 0; vals[i] != NULL; i++ )
NSLDAPI_FREE( vals[i] );
NSLDAPI_FREE( (char *) vals );
}
void
LDAP_CALL
ldap_value_free_len( struct berval **vals )
{
int i;
if ( vals == NULL )
return;
for ( i = 0; vals[i] != NULL; i++ ) {
NSLDAPI_FREE( vals[i]->bv_val );
NSLDAPI_FREE( vals[i] );
}
NSLDAPI_FREE( (char *) vals );
}

View file

@ -0,0 +1,151 @@
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is Mozilla Communicator client code, released
* March 31, 1998.
*
* The Initial Developer of the Original Code is
* Netscape Communications Corporation.
* Portions created by the Initial Developer are Copyright (C) 1998-1999
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
*
* Alternatively, the contents of this file may be used under the terms of
* either of the GNU General Public License Version 2 or later (the "GPL"),
* or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
/*
* Copyright (c) 1990 Regents of the University of Michigan.
* All rights reserved.
*/
/*
* friendly.c
*/
#if 0
#ifndef lint
static char copyright[] = "@(#) Copyright (c) 1993 Regents of the University of Michigan.\nAll rights reserved.\n";
#endif
#endif
#include "ldap-int.h"
char *
LDAP_CALL
ldap_friendly_name( char *filename, char *name, FriendlyMap *map )
{
int i, entries;
FILE *fp;
char *s;
char buf[BUFSIZ];
if ( map == NULL ) {
return( name );
}
if ( NULL == name)
{
return (name);
}
if ( *map == NULL ) {
if ( (fp = NSLDAPI_FOPEN( filename, "r" )) == NULL )
return( name );
entries = 0;
while ( fgets( buf, sizeof(buf), fp ) != NULL ) {
if ( buf[0] != '#' )
entries++;
}
rewind( fp );
if ( (*map = (FriendlyMap)NSLDAPI_MALLOC( (entries + 1) *
sizeof(struct friendly) )) == NULL ) {
fclose( fp );
return( name );
}
i = 0;
while ( fgets( buf, sizeof(buf), fp ) != NULL && i < entries ) {
if ( buf[0] == '#' )
continue;
if ( (s = strchr( buf, '\n' )) != NULL )
*s = '\0';
if ( (s = strchr( buf, '\t' )) == NULL )
continue;
*s++ = '\0';
if ( *s == '"' ) {
int esc = 0, found = 0;
for ( ++s; *s && !found; s++ ) {
switch ( *s ) {
case '\\':
esc = 1;
break;
case '"':
if ( !esc )
found = 1;
/* FALL */
default:
esc = 0;
break;
}
}
}
(*map)[i].f_unfriendly = nsldapi_strdup( buf );
(*map)[i].f_friendly = nsldapi_strdup( s );
i++;
}
fclose( fp );
(*map)[i].f_unfriendly = NULL;
}
for ( i = 0; (*map)[i].f_unfriendly != NULL; i++ ) {
if ( strcasecmp( name, (*map)[i].f_unfriendly ) == 0 )
return( (*map)[i].f_friendly );
}
return( name );
}
void
LDAP_CALL
ldap_free_friendlymap( FriendlyMap *map )
{
struct friendly* pF;
if ( map == NULL || *map == NULL ) {
return;
}
for ( pF = *map; pF->f_unfriendly; pF++ ) {
NSLDAPI_FREE( pF->f_unfriendly );
NSLDAPI_FREE( pF->f_friendly );
}
NSLDAPI_FREE( *map );
*map = NULL;
}

View file

@ -0,0 +1,150 @@
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is Mozilla Communicator client code, released
* March 31, 1998.
*
* The Initial Developer of the Original Code is
* Netscape Communications Corporation.
* Portions created by the Initial Developer are Copyright (C) 1998-1999
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
*
* Alternatively, the contents of this file may be used under the terms of
* either of the GNU General Public License Version 2 or later (the "GPL"),
* or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
/*
* Copyright (c) 1990 Regents of the University of Michigan.
* All rights reserved.
*/
/*
* getattr.c
*/
#if 0
#ifndef lint
static char copyright[] = "@(#) Copyright (c) 1990 Regents of the University of Michigan.\nAll rights reserved.\n";
#endif
#endif
#include "ldap-int.h"
static unsigned long
bytes_remaining( BerElement *ber )
{
ber_len_t len;
if ( ber_get_option( ber, LBER_OPT_REMAINING_BYTES, &len ) != 0 ) {
return( 0 ); /* not sure what else to do.... */
}
return( len );
}
char *
LDAP_CALL
ldap_first_attribute( LDAP *ld, LDAPMessage *entry, BerElement **ber )
{
char *attr;
int err;
ber_len_t seqlength;
LDAPDebug( LDAP_DEBUG_TRACE, "ldap_first_attribute\n", 0, 0, 0 );
if ( !NSLDAPI_VALID_LDAP_POINTER( ld )) {
return( NULL ); /* punt */
}
if ( ber == NULL || !NSLDAPI_VALID_LDAPMESSAGE_ENTRY_POINTER( entry )) {
LDAP_SET_LDERRNO( ld, LDAP_PARAM_ERROR, NULL, NULL );
return( NULL );
}
if ( nsldapi_alloc_ber_with_options( ld, ber ) != LDAP_SUCCESS ) {
return( NULL );
}
**ber = *entry->lm_ber;
attr = NULL; /* pessimistic */
err = LDAP_DECODING_ERROR; /* ditto */
/*
* Skip past the sequence, dn, and sequence of sequence.
* Reset number of bytes remaining so we confine the rest of our
* decoding to the current sequence.
*/
if ( ber_scanf( *ber, "{xl{", &seqlength ) != LBER_ERROR &&
ber_set_option( *ber, LBER_OPT_REMAINING_BYTES, &seqlength )
== 0 ) {
/* snarf the attribute type, and skip the set of values,
* leaving us positioned right before the next attribute
* type/value sequence.
*/
if ( ber_scanf( *ber, "{ax}", &attr ) != LBER_ERROR ||
bytes_remaining( *ber ) == 0 ) {
err = LDAP_SUCCESS;
}
}
LDAP_SET_LDERRNO( ld, err, NULL, NULL );
if ( attr == NULL || err != LDAP_SUCCESS ) {
ber_free( *ber, 0 );
*ber = NULL;
}
return( attr );
}
/* ARGSUSED */
char *
LDAP_CALL
ldap_next_attribute( LDAP *ld, LDAPMessage *entry, BerElement *ber )
{
char *attr;
int err;
LDAPDebug( LDAP_DEBUG_TRACE, "ldap_next_attribute\n", 0, 0, 0 );
if ( !NSLDAPI_VALID_LDAP_POINTER( ld )) {
return( NULL ); /* punt */
}
if ( ber == NULL || !NSLDAPI_VALID_LDAPMESSAGE_ENTRY_POINTER( entry )) {
LDAP_SET_LDERRNO( ld, LDAP_PARAM_ERROR, NULL, NULL );
return( NULL );
}
attr = NULL; /* pessimistic */
err = LDAP_DECODING_ERROR; /* ditto */
/* skip sequence, snarf attribute type, skip values */
if ( ber_scanf( ber, "{ax}", &attr ) != LBER_ERROR ||
bytes_remaining( ber ) == 0 ) {
err = LDAP_SUCCESS;
}
LDAP_SET_LDERRNO( ld, err, NULL, NULL );
return( attr );
}

View file

@ -0,0 +1,371 @@
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is Mozilla Communicator client code, released
* March 31, 1998.
*
* The Initial Developer of the Original Code is
* Netscape Communications Corporation.
* Portions created by the Initial Developer are Copyright (C) 1998-1999
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
*
* Alternatively, the contents of this file may be used under the terms of
* either of the GNU General Public License Version 2 or later (the "GPL"),
* or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
/*
* Copyright (c) 1994 Regents of the University of Michigan.
* All rights reserved.
*/
/*
* getdn.c
*/
#if 0
#ifndef lint
static char copyright[] = "@(#) Copyright (c) 1990 Regents of the University of Michigan.\nAll rights reserved.\n";
#endif
#endif
#include "ldap-int.h"
char *
LDAP_CALL
ldap_get_dn( LDAP *ld, LDAPMessage *entry )
{
char *dn;
struct berelement tmp;
LDAPDebug( LDAP_DEBUG_TRACE, "ldap_get_dn\n", 0, 0, 0 );
if ( !NSLDAPI_VALID_LDAP_POINTER( ld )) {
return( NULL ); /* punt */
}
if ( !NSLDAPI_VALID_LDAPMESSAGE_ENTRY_POINTER( entry )) {
LDAP_SET_LDERRNO( ld, LDAP_PARAM_ERROR, NULL, NULL );
return( NULL );
}
tmp = *entry->lm_ber; /* struct copy */
if ( ber_scanf( &tmp, "{a", &dn ) == LBER_ERROR ) {
LDAP_SET_LDERRNO( ld, LDAP_DECODING_ERROR, NULL, NULL );
return( NULL );
}
return( dn );
}
char *
LDAP_CALL
ldap_dn2ufn( const char *dn )
{
char *p, *ufn, *r;
size_t plen;
int state;
LDAPDebug( LDAP_DEBUG_TRACE, "ldap_dn2ufn\n", 0, 0, 0 );
if ( dn == NULL ) {
dn = "";
}
if ( ldap_is_dns_dn( dn ) || ( p = strchr( dn, '=' )) == NULL )
return( nsldapi_strdup( (char *)dn ));
ufn = nsldapi_strdup( ++p );
#define INQUOTE 1
#define OUTQUOTE 2
state = OUTQUOTE;
for ( p = ufn, r = ufn; *p; p += plen ) {
plen = 1;
switch ( *p ) {
case '\\':
if ( *++p == '\0' )
plen=0;
else {
*r++ = '\\';
r += (plen = LDAP_UTF8COPY(r,p));
}
break;
case '"':
if ( state == INQUOTE )
state = OUTQUOTE;
else
state = INQUOTE;
*r++ = *p;
break;
case ';':
case ',':
if ( state == OUTQUOTE )
*r++ = ',';
else
*r++ = *p;
break;
case '=':
if ( state == INQUOTE )
*r++ = *p;
else {
char *rsave = r;
LDAP_UTF8DEC(r);
*rsave = '\0';
while ( !ldap_utf8isspace( r ) && *r != ';'
&& *r != ',' && r > ufn )
LDAP_UTF8DEC(r);
LDAP_UTF8INC(r);
if ( strcasecmp( r, "c" )
&& strcasecmp( r, "o" )
&& strcasecmp( r, "ou" )
&& strcasecmp( r, "st" )
&& strcasecmp( r, "l" )
&& strcasecmp( r, "dc" )
&& strcasecmp( r, "uid" )
&& strcasecmp( r, "cn" ) ) {
r = rsave;
*r++ = '=';
}
}
break;
default:
r += (plen = LDAP_UTF8COPY(r,p));
break;
}
}
*r = '\0';
return( ufn );
}
char **
LDAP_CALL
ldap_explode_dns( const char *dn )
{
int ncomps, maxcomps;
char *s, *cpydn;
char **rdns;
#ifdef HAVE_STRTOK_R /* defined in portable.h */
char *lasts;
#endif
if ( dn == NULL ) {
dn = "";
}
if ( (rdns = (char **)NSLDAPI_MALLOC( 8 * sizeof(char *) )) == NULL ) {
return( NULL );
}
maxcomps = 8;
ncomps = 0;
cpydn = nsldapi_strdup( (char *)dn );
for ( s = STRTOK( cpydn, "@.", &lasts ); s != NULL;
s = STRTOK( NULL, "@.", &lasts ) ) {
if ( ncomps == maxcomps ) {
maxcomps *= 2;
if ( (rdns = (char **)NSLDAPI_REALLOC( rdns, maxcomps *
sizeof(char *) )) == NULL ) {
NSLDAPI_FREE( cpydn );
return( NULL );
}
}
rdns[ncomps++] = nsldapi_strdup( s );
}
rdns[ncomps] = NULL;
NSLDAPI_FREE( cpydn );
return( rdns );
}
#define LDAP_DN 1
#define LDAP_RDN 2
static char **
ldap_explode( const char *dn, const int notypes, const int nametype )
{
char *p, *q, *rdnstart, **rdns = NULL;
size_t plen = 0;
int state = 0;
int count = 0;
int startquote = 0;
int endquote = 0;
int len = 0;
int goteq = 0;
LDAPDebug( LDAP_DEBUG_TRACE, "ldap_explode\n", 0, 0, 0 );
if ( dn == NULL ) {
dn = "";
}
#if 0
if ( ldap_is_dns_dn( dn ) ) {
return( ldap_explode_dns( dn ) );
}
#endif
while ( ldap_utf8isspace( (char *)dn )) { /* ignore leading spaces */
++dn;
}
p = rdnstart = (char *) dn;
state = OUTQUOTE;
do {
p += plen;
plen = 1;
switch ( *p ) {
case '\\':
if ( *++p == '\0' )
p--;
else
plen = LDAP_UTF8LEN(p);
break;
case '"':
if ( state == INQUOTE )
state = OUTQUOTE;
else
state = INQUOTE;
break;
case '+': if ( nametype != LDAP_RDN ) break;
case ';':
case ',':
case '\0':
if ( state == OUTQUOTE ) {
/*
* semicolon and comma are not valid RDN
* separators.
*/
if ( nametype == LDAP_RDN &&
( *p == ';' || *p == ',' || !goteq)) {
ldap_charray_free( rdns );
return NULL;
}
if ( (*p == ',' || *p == ';') && !goteq ) {
/* If we get here, we have a case similar
* to <attr>=<value>,<string>,<attr>=<value>
* This is not a valid dn */
ldap_charray_free( rdns );
return NULL;
}
goteq = 0;
++count;
if ( rdns == NULL ) {
if (( rdns = (char **)NSLDAPI_MALLOC( 8
* sizeof( char *))) == NULL )
return( NULL );
} else if ( count >= 8 ) {
if (( rdns = (char **)NSLDAPI_REALLOC(
rdns, (count+1) *
sizeof( char *))) == NULL )
return( NULL );
}
rdns[ count ] = NULL;
endquote = 0;
if ( notypes ) {
for ( q = rdnstart;
q < p && *q != '='; ++q ) {
;
}
if ( q < p ) { /* *q == '=' */
rdnstart = ++q;
}
if ( *rdnstart == '"' ) {
startquote = 1;
++rdnstart;
}
if ( (*(p-1) == '"') && startquote ) {
endquote = 1;
--p;
}
}
len = p - rdnstart;
if (( rdns[ count-1 ] = (char *)NSLDAPI_CALLOC(
1, len + 1 )) != NULL ) {
SAFEMEMCPY( rdns[ count-1 ], rdnstart,
len );
if ( !endquote ) {
/* trim trailing spaces unless
* they are properly escaped */
while ( len > 0 &&
ldap_utf8isspace(
&rdns[count-1][len-1] ) &&
((len == 1) || (rdns[count-1][len-2] != '\\'))) {
--len;
}
}
rdns[ count-1 ][ len ] = '\0';
}
/*
* Don't forget to increment 'p' back to where
* it should be. If we don't, then we will
* never get past an "end quote."
*/
if ( endquote == 1 )
p++;
rdnstart = *p ? p + 1 : p;
while ( ldap_utf8isspace( rdnstart ))
++rdnstart;
}
break;
case '=':
if ( state == OUTQUOTE ) {
goteq = 1;
}
/* FALL */
default:
plen = LDAP_UTF8LEN(p);
break;
}
} while ( *p );
return( rdns );
}
char **
LDAP_CALL
ldap_explode_dn( const char *dn, const int notypes )
{
return( ldap_explode( dn, notypes, LDAP_DN ) );
}
char **
LDAP_CALL
ldap_explode_rdn( const char *rdn, const int notypes )
{
return( ldap_explode( rdn, notypes, LDAP_RDN ) );
}
int
LDAP_CALL
ldap_is_dns_dn( const char *dn )
{
return( dn != NULL && dn[ 0 ] != '\0' && strchr( dn, '=' ) == NULL &&
strchr( dn, ',' ) == NULL );
}

View file

@ -0,0 +1,279 @@
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is Mozilla Communicator client code, released
* March 31, 1998.
*
* The Initial Developer of the Original Code is
* Netscape Communications Corporation.
* Portions created by the Initial Developer are Copyright (C) 1998-1999
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
*
* Alternatively, the contents of this file may be used under the terms of
* either of the GNU General Public License Version 2 or later (the "GPL"),
* or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
/*
* Copyright (c) 1995 Regents of the University of Michigan.
* All rights reserved.
*/
/*
* nsldapi_getdxbyname - retrieve DX records from the DNS (from
* TXT records for now)
*/
#include <stdio.h>
#ifdef LDAP_DNS
XXX not MT-safe XXX
#include <string.h>
#include <ctype.h>
#ifdef macintosh
#include <stdlib.h>
#include "macos.h"
#endif /* macintosh */
#ifdef _WINDOWS
#include <windows.h>
#endif
#if !defined(macintosh) && !defined(DOS) && !defined( _WINDOWS )
#include <sys/types.h>
#include <netinet/in.h>
#include <arpa/nameser.h>
#include <sys/time.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netdb.h>
#include <resolv.h>
#endif
#include "ldap-int.h"
#if defined( DOS )
#include "msdos.h"
#endif /* DOS */
#ifdef NEEDPROTOS
static char ** decode_answer( unsigned char *answer, int len );
#else /* NEEDPROTOS */
static char **decode_answer();
#endif /* NEEDPROTOS */
extern int h_errno;
extern char *h_errlist[];
#define MAX_TO_SORT 32
/*
* nsldapi_getdxbyname - lookup DNS DX records for domain and return an ordered
* array.
*/
char **
nsldapi_getdxbyname( char *domain )
{
unsigned char buf[ PACKETSZ ];
char **dxs;
int rc;
LDAPDebug( LDAP_DEBUG_TRACE, "nsldapi_getdxbyname( %s )\n", domain, 0, 0 );
memset( buf, 0, sizeof( buf ));
/* XXX not MT safe XXX */
if (( rc = res_search( domain, C_IN, T_TXT, buf, sizeof( buf ))) < 0
|| ( rc > sizeof( buf ))
|| ( dxs = decode_answer( buf, rc )) == NULL ) {
/*
* punt: return list consisting of the original domain name only
*/
if (( dxs = (char **)NSLDAPI_MALLOC( 2 * sizeof( char * ))) == NULL ||
( dxs[ 0 ] = nsldapi_strdup( domain )) == NULL ) {
if ( dxs != NULL ) {
NSLDAPI_FREE( dxs );
}
dxs = NULL;
} else {
dxs[ 1 ] = NULL;
}
}
return( dxs );
}
static char **
decode_answer( unsigned char *answer, int len )
{
HEADER *hp;
char buf[ 256 ], **dxs;
unsigned char *eom, *p;
int ancount, err, rc, type, class, dx_count, rr_len;
int dx_pref[ MAX_TO_SORT ];
#ifdef LDAP_DEBUG
if ( ldap_debug & LDAP_DEBUG_PACKETS ) {
/* __p_query( answer ); */
}
#endif /* LDAP_DEBUG */
dxs = NULL;
hp = (HEADER *)answer;
eom = answer + len;
if ( len < sizeof( *hp ) ) {
h_errno = NO_RECOVERY;
return( NULL );
}
if ( ntohs( hp->qdcount ) != 1 ) {
h_errno = NO_RECOVERY;
return( NULL );
}
ancount = ntohs( hp->ancount );
if ( ancount < 1 ) {
h_errno = NO_DATA;
return( NULL );
}
/*
* skip over the query
*/
p = answer + HFIXEDSZ;
if (( rc = dn_expand( answer, eom, p, buf, sizeof( buf ))) < 0 ) {
h_errno = NO_RECOVERY;
return( NULL );
}
p += ( rc + QFIXEDSZ );
/*
* pull out the answers we are interested in
*/
err = dx_count = 0;
while ( ancount > 0 && err == 0 && p < eom ) {
if (( rc = dn_expand( answer, eom, p, buf, sizeof( buf ))) < 0 ) {
err = NO_RECOVERY;
continue;
}
p += rc; /* skip over name */
if ( p + 3 * INT16SZ + INT32SZ > eom ) {
err = NO_RECOVERY;
continue;
}
type = _getshort( p );
p += INT16SZ;
class = _getshort( p );
p += INT16SZ;
p += INT32SZ; /* skip over TTL */
rr_len = _getshort( p );
p += INT16SZ;
if ( p + rr_len > eom ) {
err = NO_RECOVERY;
continue;
}
if ( class == C_IN && type == T_TXT ) {
int i, n, pref, txt_len;
char *q, *r;
q = (char *)p;
while ( q < (char *)p + rr_len && err == 0 ) {
if ( *q >= 3 && strncasecmp( q + 1, "dx:", 3 ) == 0 ) {
txt_len = *q - 3;
r = q + 4;
while ( isspace( *r )) {
++r;
--txt_len;
}
pref = 0;
while ( isdigit( *r )) {
pref *= 10;
pref += ( *r - '0' );
++r;
--txt_len;
}
if ( dx_count < MAX_TO_SORT - 1 ) {
dx_pref[ dx_count ] = pref;
}
while ( isspace( *r )) {
++r;
--txt_len;
}
if ( dx_count == 0 ) {
dxs = (char **)NSLDAPI_MALLOC( 2 * sizeof( char * ));
} else {
dxs = (char **)NSLDAPI_REALLOC( dxs,
( dx_count + 2 ) * sizeof( char * ));
}
if ( dxs == NULL || ( dxs[ dx_count ] =
(char *)NSLDAPI_CALLOC( 1, txt_len + 1 ))
== NULL ) {
err = NO_RECOVERY;
continue;
}
SAFEMEMCPY( dxs[ dx_count ], r, txt_len );
dxs[ ++dx_count ] = NULL;
}
q += ( *q + 1 ); /* move past last TXT record */
}
}
p += rr_len;
}
if ( err == 0 ) {
if ( dx_count == 0 ) {
err = NO_DATA;
} else {
/*
* sort records based on associated preference value
*/
int i, j, sort_count, tmp_pref;
char *tmp_dx;
sort_count = ( dx_count < MAX_TO_SORT ) ? dx_count : MAX_TO_SORT;
for ( i = 0; i < sort_count; ++i ) {
for ( j = i + 1; j < sort_count; ++j ) {
if ( dx_pref[ i ] > dx_pref[ j ] ) {
tmp_pref = dx_pref[ i ];
dx_pref[ i ] = dx_pref[ j ];
dx_pref[ j ] = tmp_pref;
tmp_dx = dxs[ i ];
dxs[ i ] = dxs[ j ];
dxs[ j ] = tmp_dx;
}
}
}
}
}
h_errno = err;
return( dxs );
}
#endif /* LDAP_DNS */

View file

@ -0,0 +1,109 @@
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is Sun LDAP C SDK.
*
* The Initial Developer of the Original Code is Sun Microsystems, Inc.
*
* Portions created by Sun Microsystems, Inc are Copyright (C) 2005
* Sun Microsystems, Inc. All Rights Reserved.
*
* Contributor(s):
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
#include "ldap-int.h"
/* ldap_create_geteffectiveRights_control
Create Effective Rights control.
Parameters are
ld LDAP pointer to the desired connection
authzid RFC2829 section 9, eg "dn:<DN>".
NULL or empty string means get bound user's rights,
just "dn:" means get anonymous user's rights.
attrlist additional attributes for which rights info is
requrested. NULL means "just the ones returned
with the search operation".
ctl_iscritical Indicates whether the control is critical of not. If
this field is non-zero, the operation will only be car-
ried out if the control is recognized by the server
and/or client
ctrlp the address of a place to put the constructed control
*/
int
LDAP_CALL
ldap_create_geteffectiveRights_control (
LDAP *ld,
const char *authzid,
const char **attrlist,
const char ctl_iscritical,
LDAPControl **ctrlp
)
{
BerElement *ber;
int rc;
if ( !NSLDAPI_VALID_LDAP_POINTER( ld )) {
return( LDAP_PARAM_ERROR );
}
if ( ctrlp == NULL ) {
LDAP_SET_LDERRNO( ld, LDAP_PARAM_ERROR, NULL, NULL );
return ( LDAP_PARAM_ERROR );
}
if (NULL == authzid)
{
authzid = "";
}
/* create a ber package to hold the controlValue */
if ( ( nsldapi_alloc_ber_with_options( ld, &ber ) ) != LDAP_SUCCESS ) {
LDAP_SET_LDERRNO( ld, LDAP_NO_MEMORY, NULL, NULL );
return( LDAP_NO_MEMORY );
}
if ( LBER_ERROR == ber_printf( ber, "{s{v}}", authzid, attrlist ) ) {
LDAP_SET_LDERRNO( ld, LDAP_ENCODING_ERROR, NULL, NULL );
ber_free( ber, 1 );
return( LDAP_ENCODING_ERROR );
}
rc = nsldapi_build_control( LDAP_CONTROL_GETEFFECTIVERIGHTS_REQUEST, ber, 1,
ctl_iscritical, ctrlp );
LDAP_SET_LDERRNO( ld, rc, NULL, NULL );
return( rc );
}

View file

@ -0,0 +1,141 @@
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is Mozilla Communicator client code, released
* March 31, 1998.
*
* The Initial Developer of the Original Code is
* Netscape Communications Corporation.
* Portions created by the Initial Developer are Copyright (C) 1998-1999
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
*
* Alternatively, the contents of this file may be used under the terms of
* either of the GNU General Public License Version 2 or later (the "GPL"),
* or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
/*
* Copyright (c) 1990 Regents of the University of Michigan.
* All rights reserved.
*/
/*
* getentry.c
*/
#if 0
#ifndef lint
static char copyright[] = "@(#) Copyright (c) 1990 Regents of the University of Michigan.\nAll rights reserved.\n";
#endif
#endif
#include "ldap-int.h"
LDAPMessage *
LDAP_CALL
ldap_first_entry( LDAP *ld, LDAPMessage *chain )
{
if ( !NSLDAPI_VALID_LDAP_POINTER( ld ) || chain == NULLMSG ) {
return( NULLMSG );
}
if ( chain->lm_msgtype == LDAP_RES_SEARCH_ENTRY ) {
return( chain );
}
return( ldap_next_entry( ld, chain ));
}
LDAPMessage *
LDAP_CALL
ldap_next_entry( LDAP *ld, LDAPMessage *entry )
{
if ( !NSLDAPI_VALID_LDAP_POINTER( ld ) || entry == NULLMSG ) {
return( NULLMSG );
}
for ( entry = entry->lm_chain; entry != NULLMSG;
entry = entry->lm_chain ) {
if ( entry->lm_msgtype == LDAP_RES_SEARCH_ENTRY ) {
return( entry );
}
}
return( NULLMSG );
}
int
LDAP_CALL
ldap_count_entries( LDAP *ld, LDAPMessage *chain )
{
int i;
if ( !NSLDAPI_VALID_LDAP_POINTER( ld )) {
return( -1 );
}
for ( i = 0; chain != NULL; chain = chain->lm_chain ) {
if ( chain->lm_msgtype == LDAP_RES_SEARCH_ENTRY ) {
++i;
}
}
return( i );
}
int
LDAP_CALL
ldap_get_entry_controls( LDAP *ld, LDAPMessage *entry,
LDAPControl ***serverctrlsp )
{
int rc;
BerElement tmpber;
LDAPDebug( LDAP_DEBUG_TRACE, "ldap_get_entry_controls\n", 0, 0, 0 );
if ( !NSLDAPI_VALID_LDAP_POINTER( ld )) {
return( LDAP_PARAM_ERROR );
}
if ( !NSLDAPI_VALID_LDAPMESSAGE_ENTRY_POINTER( entry )
|| serverctrlsp == NULL ) {
rc = LDAP_PARAM_ERROR;
goto report_error_and_return;
}
*serverctrlsp = NULL;
tmpber = *entry->lm_ber; /* struct copy */
/* skip past dn and entire attribute/value list */
if ( ber_scanf( &tmpber, "{xx" ) == LBER_ERROR ) {
rc = LDAP_DECODING_ERROR;
goto report_error_and_return;
}
rc = nsldapi_get_controls( &tmpber, serverctrlsp );
report_error_and_return:
LDAP_SET_LDERRNO( ld, rc, NULL, NULL );
return( rc );
}

View file

@ -0,0 +1,553 @@
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is Mozilla Communicator client code, released
* March 31, 1998.
*
* The Initial Developer of the Original Code is
* Netscape Communications Corporation.
* Portions created by the Initial Developer are Copyright (C) 1998-1999
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
*
* Alternatively, the contents of this file may be used under the terms of
* either of the GNU General Public License Version 2 or later (the "GPL"),
* or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
/*
* Copyright (c) 1993 Regents of the University of Michigan.
* All rights reserved.
*/
/*
* getfilter.c -- optional add-on to libldap
*/
#if 0
#ifndef lint
static char copyright[] = "@(#) Copyright (c) 1993 Regents of the University of Michigan.\nAll rights reserved.\n";
#endif
#endif
#include "ldap-int.h"
#include "regex.h"
static int break_into_words( char *str, char *delims, char ***wordsp );
#if !defined( macintosh ) && !defined( DOS )
extern char * LDAP_CALL re_comp();
#endif
#define FILT_MAX_LINE_LEN 1024
LDAPFiltDesc *
LDAP_CALL
ldap_init_getfilter( char *fname )
{
FILE *fp;
char *buf;
long rlen, len;
int eof;
LDAPFiltDesc *lfdp;
if (( fp = NSLDAPI_FOPEN( fname, "r" )) == NULL ) {
return( NULL );
}
if ( fseek( fp, 0L, SEEK_END ) != 0 ) { /* move to end to get len */
fclose( fp );
return( NULL );
}
len = ftell( fp );
if ( fseek( fp, 0L, SEEK_SET ) != 0 ) { /* back to start of file */
fclose( fp );
return( NULL );
}
if (( buf = NSLDAPI_MALLOC( (size_t)len )) == NULL ) {
fclose( fp );
return( NULL );
}
rlen = fread( buf, 1, (size_t)len, fp );
eof = feof( fp );
fclose( fp );
if ( rlen != len && !eof ) { /* error: didn't get the whole file */
NSLDAPI_FREE( buf );
return( NULL );
}
lfdp = ldap_init_getfilter_buf( buf, rlen );
NSLDAPI_FREE( buf );
return( lfdp );
}
LDAPFiltDesc *
LDAP_CALL
ldap_init_getfilter_buf( char *buf, long buflen )
{
LDAPFiltDesc *lfdp;
LDAPFiltList *flp, *nextflp;
LDAPFiltInfo *fip, *nextfip;
char *errmsg, *tag, **tok;
int tokcnt, i;
if ( (buf == NULL) || (buflen < 0) ||
( lfdp = (LDAPFiltDesc *)NSLDAPI_CALLOC(1, sizeof( LDAPFiltDesc)))
== NULL ) {
return( NULL );
}
flp = nextflp = NULL;
fip = NULL;
tag = NULL;
while ( buflen > 0 && ( tokcnt = nsldapi_next_line_tokens( &buf, &buflen,
&tok )) > 0 ) {
switch( tokcnt ) {
case 1: /* tag line */
if ( tag != NULL ) {
NSLDAPI_FREE( tag );
}
tag = tok[ 0 ];
NSLDAPI_FREE( tok );
break;
case 4:
case 5: /* start of filter info. list */
if (( nextflp = (LDAPFiltList *)NSLDAPI_CALLOC( 1,
sizeof( LDAPFiltList ))) == NULL ) {
ldap_getfilter_free( lfdp );
return( NULL );
}
nextflp->lfl_tag = nsldapi_strdup( tag );
nextflp->lfl_pattern = tok[ 0 ];
if (( errmsg = re_comp( nextflp->lfl_pattern )) != NULL ) {
char msg[512];
ldap_getfilter_free( lfdp );
snprintf( msg, sizeof(msg),
"bad regular expression \"%s\" - %s\n",
nextflp->lfl_pattern, errmsg );
ber_err_print( msg );
nsldapi_free_strarray( tok );
return( NULL );
}
nextflp->lfl_delims = tok[ 1 ];
nextflp->lfl_ilist = NULL;
nextflp->lfl_next = NULL;
if ( flp == NULL ) { /* first one */
lfdp->lfd_filtlist = nextflp;
} else {
flp->lfl_next = nextflp;
}
flp = nextflp;
fip = NULL;
for ( i = 2; i < 5; ++i ) {
tok[ i - 2 ] = tok[ i ];
}
/* fall through */
case 2:
case 3: /* filter, desc, and optional search scope */
if ( nextflp != NULL ) { /* add to info list */
if (( nextfip = (LDAPFiltInfo *)NSLDAPI_CALLOC( 1,
sizeof( LDAPFiltInfo ))) == NULL ) {
ldap_getfilter_free( lfdp );
nsldapi_free_strarray( tok );
return( NULL );
}
if ( fip == NULL ) { /* first one */
nextflp->lfl_ilist = nextfip;
} else {
fip->lfi_next = nextfip;
}
fip = nextfip;
nextfip->lfi_next = NULL;
nextfip->lfi_filter = tok[ 0 ];
nextfip->lfi_desc = tok[ 1 ];
if ( tok[ 2 ] != NULL ) {
if ( strcasecmp( tok[ 2 ], "subtree" ) == 0 ) {
nextfip->lfi_scope = LDAP_SCOPE_SUBTREE;
} else if ( strcasecmp( tok[ 2 ], "onelevel" ) == 0 ) {
nextfip->lfi_scope = LDAP_SCOPE_ONELEVEL;
} else if ( strcasecmp( tok[ 2 ], "base" ) == 0 ) {
nextfip->lfi_scope = LDAP_SCOPE_BASE;
} else {
nsldapi_free_strarray( tok );
ldap_getfilter_free( lfdp );
return( NULL );
}
NSLDAPI_FREE( tok[ 2 ] );
tok[ 2 ] = NULL;
} else {
nextfip->lfi_scope = LDAP_SCOPE_SUBTREE; /* default */
}
nextfip->lfi_isexact = ( strchr( tok[ 0 ], '*' ) == NULL &&
strchr( tok[ 0 ], '~' ) == NULL );
NSLDAPI_FREE( tok );
}
break;
default:
nsldapi_free_strarray( tok );
ldap_getfilter_free( lfdp );
return( NULL );
}
}
if ( tag != NULL ) {
NSLDAPI_FREE( tag );
}
return( lfdp );
}
int
LDAP_CALL
ldap_set_filter_additions( LDAPFiltDesc *lfdp, char *prefix, char *suffix )
{
if ( lfdp == NULL ) {
return( LDAP_PARAM_ERROR );
}
if ( lfdp->lfd_filtprefix != NULL ) {
NSLDAPI_FREE( lfdp->lfd_filtprefix );
}
lfdp->lfd_filtprefix = ( prefix == NULL ) ? NULL : nsldapi_strdup( prefix );
if ( lfdp->lfd_filtsuffix != NULL ) {
NSLDAPI_FREE( lfdp->lfd_filtsuffix );
}
lfdp->lfd_filtsuffix = ( suffix == NULL ) ? NULL : nsldapi_strdup( suffix );
return( LDAP_SUCCESS );
}
/*
* ldap_setfilteraffixes() is deprecated -- use ldap_set_filter_additions()
*/
void
LDAP_CALL
ldap_setfilteraffixes( LDAPFiltDesc *lfdp, char *prefix, char *suffix )
{
(void)ldap_set_filter_additions( lfdp, prefix, suffix );
}
LDAPFiltInfo *
LDAP_CALL
ldap_getfirstfilter( LDAPFiltDesc *lfdp, char *tagpat, char *value )
{
LDAPFiltList *flp;
if ( lfdp == NULL || tagpat == NULL || value == NULL ) {
return( NULL ); /* punt */
}
if ( lfdp->lfd_curvalcopy != NULL ) {
NSLDAPI_FREE( lfdp->lfd_curvalcopy );
NSLDAPI_FREE( lfdp->lfd_curvalwords );
}
NSLDAPI_FREE(lfdp->lfd_curval);
if ((lfdp->lfd_curval = nsldapi_strdup(value)) == NULL) {
return( NULL );
}
lfdp->lfd_curfip = NULL;
for ( flp = lfdp->lfd_filtlist; flp != NULL; flp = flp->lfl_next ) {
if ( re_comp( tagpat ) == NULL && re_exec( flp->lfl_tag ) == 1
&& re_comp( flp->lfl_pattern ) == NULL
&& re_exec( lfdp->lfd_curval ) == 1 ) {
lfdp->lfd_curfip = flp->lfl_ilist;
break;
}
}
if ( lfdp->lfd_curfip == NULL ) {
return( NULL );
}
if (( lfdp->lfd_curvalcopy = nsldapi_strdup( value )) == NULL ) {
return( NULL );
}
if ( break_into_words( lfdp->lfd_curvalcopy, flp->lfl_delims,
&lfdp->lfd_curvalwords ) < 0 ) {
NSLDAPI_FREE( lfdp->lfd_curvalcopy );
lfdp->lfd_curvalcopy = NULL;
return( NULL );
}
return( ldap_getnextfilter( lfdp ));
}
LDAPFiltInfo *
LDAP_CALL
ldap_getnextfilter( LDAPFiltDesc *lfdp )
{
LDAPFiltInfo *fip;
if ( lfdp == NULL || ( fip = lfdp->lfd_curfip ) == NULL ) {
return( NULL );
}
lfdp->lfd_curfip = fip->lfi_next;
ldap_build_filter( lfdp->lfd_filter, LDAP_FILT_MAXSIZ, fip->lfi_filter,
lfdp->lfd_filtprefix, lfdp->lfd_filtsuffix, NULL,
lfdp->lfd_curval, lfdp->lfd_curvalwords );
lfdp->lfd_retfi.lfi_filter = lfdp->lfd_filter;
lfdp->lfd_retfi.lfi_desc = fip->lfi_desc;
lfdp->lfd_retfi.lfi_scope = fip->lfi_scope;
lfdp->lfd_retfi.lfi_isexact = fip->lfi_isexact;
return( &lfdp->lfd_retfi );
}
static char*
filter_add_strn( char *f, char *flimit, char *v, size_t vlen )
/* Copy v into f. If flimit is too small, return NULL;
* otherwise return (f + vlen).
*/
{
auto size_t flen = flimit - f;
if ( vlen > flen ) { /* flimit is too small */
if ( flen > 0 ) SAFEMEMCPY( f, v, flen );
return NULL;
}
if ( vlen > 0 ) SAFEMEMCPY( f, v, vlen );
return f + vlen;
}
static char*
filter_add_value( char *f, char *flimit, char *v, int escape_all )
/* Copy v into f, but with parentheses escaped. But only escape * and \
* if escape_all is non-zero so that either "*" or "\2a" can be used in
* v, with different meanings.
* If flimit is too small, return NULL; otherwise
* return (f + the number of bytes copied).
*/
{
auto char x[4];
auto size_t slen;
while ( f && *v ) {
switch ( *v ) {
case '*':
if ( escape_all ) {
f = filter_add_strn( f, flimit, "\\2a", 3 );
v++;
} else {
if ( f < flimit ) {
*f++ = *v++;
} else {
f = NULL; /* overflow */
}
}
break;
case '(':
case ')':
sprintf( x, "\\%02x", (unsigned)*v );
f = filter_add_strn( f, flimit, x, 3 );
v++;
break;
case '\\':
if ( escape_all ) {
f = filter_add_strn( f, flimit, "\\5c", 3 );
v++;
} else {
slen = (ldap_utf8isxdigit( v+1 ) &&
ldap_utf8isxdigit( v+2 )) ? 3 : (v[1] ? 2 : 1);
f = filter_add_strn( f, flimit, v, slen );
v += slen;
}
break;
default:
if ( f < flimit ) {
*f++ = *v++;
} else {
f = NULL; /* overflow */
}
break;
}
}
return f;
}
int
LDAP_CALL
ldap_create_filter( char *filtbuf, unsigned long buflen, char *pattern,
char *prefix, char *suffix, char *attr, char *value, char **valwords )
{
char *p, *f, *flimit;
int i, wordcount, wordnum, endwordnum, escape_all;
/*
* there is some confusion on what to create for a filter if
* attr or value are null pointers. For now we just leave them
* as TO BE DEALT with
*/
if ( filtbuf == NULL || buflen == 0 || pattern == NULL ){
return( LDAP_PARAM_ERROR );
}
if ( valwords == NULL ) {
wordcount = 0;
} else {
for ( wordcount = 0; valwords[ wordcount ] != NULL; ++wordcount ) {
;
}
}
f = filtbuf;
flimit = filtbuf + buflen - 1;
if ( prefix != NULL ) {
f = filter_add_strn( f, flimit, prefix, strlen( prefix ));
}
for ( p = pattern; f != NULL && *p != '\0'; ++p ) {
if ( *p == '%' ) {
++p;
if ( *p == 'v' || *p == 'e' ) {
escape_all = ( *p == 'e' );
if ( ldap_utf8isdigit( p+1 )) {
++p;
wordnum = *p - '1';
if ( *(p+1) == '-' ) {
++p;
if ( ldap_utf8isdigit( p+1 )) {
++p;
endwordnum = *p - '1'; /* e.g., "%v2-4" */
if ( endwordnum > wordcount - 1 ) {
endwordnum = wordcount - 1;
}
} else {
endwordnum = wordcount - 1; /* e.g., "%v2-" */
}
} else {
endwordnum = wordnum; /* e.g., "%v2" */
}
if ( wordcount > 0 ) {
for ( i = wordnum; i <= endwordnum; ++i ) {
if ( i > wordnum ) { /* add blank btw words */
f = filter_add_strn( f, flimit, " ", 1 );
if ( f == NULL ) break;
}
f = filter_add_value( f, flimit, valwords[ i ],
escape_all );
if ( f == NULL ) break;
}
}
} else if ( *(p+1) == '$' ) {
++p;
if ( wordcount > 0 ) {
wordnum = wordcount - 1;
f = filter_add_value( f, flimit,
valwords[ wordnum ], escape_all );
}
} else if ( value != NULL ) {
f = filter_add_value( f, flimit, value, escape_all );
}
} else if ( *p == 'a' && attr != NULL ) {
f = filter_add_strn( f, flimit, attr, strlen( attr ));
} else {
*f++ = *p;
}
} else {
*f++ = *p;
}
if ( f > flimit ) { /* overflow */
f = NULL;
}
}
if ( suffix != NULL && f != NULL) {
f = filter_add_strn( f, flimit, suffix, strlen( suffix ));
}
if ( f == NULL ) {
*flimit = '\0';
return( LDAP_SIZELIMIT_EXCEEDED );
}
*f = '\0';
return( LDAP_SUCCESS );
}
/*
* ldap_build_filter() is deprecated -- use ldap_create_filter() instead
*/
void
LDAP_CALL
ldap_build_filter( char *filtbuf, unsigned long buflen, char *pattern,
char *prefix, char *suffix, char *attr, char *value, char **valwords )
{
(void)ldap_create_filter( filtbuf, buflen, pattern, prefix, suffix, attr,
value, valwords );
}
static int
break_into_words( char *str, char *delims, char ***wordsp )
{
char *word, **words;
int count;
char *lasts;
if (( words = (char **)NSLDAPI_CALLOC( 1, sizeof( char * ))) == NULL ) {
return( -1 );
}
count = 0;
words[ count ] = NULL;
word = ldap_utf8strtok_r( str, delims, &lasts );
while ( word != NULL ) {
if (( words = (char **)NSLDAPI_REALLOC( words,
( count + 2 ) * sizeof( char * ))) == NULL ) {
return( -1 );
}
words[ count ] = word;
words[ ++count ] = NULL;
word = ldap_utf8strtok_r( NULL, delims, &lasts );
}
*wordsp = words;
return( count );
}

View file

@ -0,0 +1,475 @@
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is Mozilla Communicator client code, released
* March 31, 1998.
*
* The Initial Developer of the Original Code is
* Netscape Communications Corporation.
* Portions created by the Initial Developer are Copyright (C) 1998-1999
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
*
* Alternatively, the contents of this file may be used under the terms of
* either of the GNU General Public License Version 2 or later (the "GPL"),
* or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
#include "ldap-int.h"
#define LDAP_GET_BITOPT( ld, bit ) \
((ld)->ld_options & bit ) != 0 ? 1 : 0
static int nsldapi_get_api_info( LDAPAPIInfo *aip );
static int nsldapi_get_feature_info( LDAPAPIFeatureInfo *fip );
int
LDAP_CALL
ldap_get_option( LDAP *ld, int option, void *optdata )
{
int rc = 0;
if ( !nsldapi_initialized ) {
nsldapi_initialize_defaults();
}
/*
* optdata MUST be a valid pointer...
*/
if (NULL == optdata)
{
return(LDAP_PARAM_ERROR);
}
/*
* process global options (not associated with an LDAP session handle)
*/
if ( option == LDAP_OPT_MEMALLOC_FN_PTRS ) {
/* struct copy */
*((struct ldap_memalloc_fns *)optdata) = nsldapi_memalloc_fns;
return( 0 );
}
if ( option == LDAP_OPT_API_INFO ) {
rc = nsldapi_get_api_info( (LDAPAPIInfo *)optdata );
if ( rc != LDAP_SUCCESS ) {
if ( ld != NULL ) {
LDAP_SET_LDERRNO( ld, rc, NULL, NULL );
}
return( -1 );
}
return( 0 );
}
/*
* LDAP_OPT_DEBUG_LEVEL is global
*/
if (LDAP_OPT_DEBUG_LEVEL == option)
{
#ifdef LDAP_DEBUG
*((int *) optdata) = ldap_debug;
#endif /* LDAP_DEBUG */
return ( 0 );
}
/*
* if ld is NULL, arrange to return options from our default settings
*/
if ( ld == NULL ) {
ld = &nsldapi_ld_defaults;
}
if ( !NSLDAPI_VALID_LDAP_POINTER( ld )) {
return( -1 ); /* punt */
}
if (ld != &nsldapi_ld_defaults)
LDAP_MUTEX_LOCK( ld, LDAP_OPTION_LOCK );
switch( option ) {
#ifdef LDAP_DNS
case LDAP_OPT_DNS:
*((int *) optdata) = LDAP_GET_BITOPT( ld, LDAP_BITOPT_DNS );
break;
#endif
case LDAP_OPT_REFERRALS:
*((int *) optdata) =
LDAP_GET_BITOPT( ld, LDAP_BITOPT_REFERRALS );
break;
case LDAP_OPT_SSL:
*((int *) optdata) = LDAP_GET_BITOPT( ld, LDAP_BITOPT_SSL );
break;
case LDAP_OPT_RESTART:
*((int *) optdata) = LDAP_GET_BITOPT( ld, LDAP_BITOPT_RESTART );
break;
case LDAP_OPT_RECONNECT:
*((int *) optdata) =
LDAP_GET_BITOPT( ld, LDAP_BITOPT_RECONNECT );
break;
case LDAP_OPT_NOREBIND:
*((int *) optdata) =
LDAP_GET_BITOPT( ld, LDAP_BITOPT_NOREBIND );
break;
#ifdef LDAP_ASYNC_IO
case LDAP_OPT_ASYNC_CONNECT:
*((int *) optdata) =
LDAP_GET_BITOPT( ld, LDAP_BITOPT_ASYNC );
break;
#endif /* LDAP_ASYNC_IO */
/* stuff in the sockbuf */
case LDAP_X_OPT_SOCKBUF:
*((Sockbuf **) optdata) = ld->ld_sbp;
break;
case LDAP_OPT_DESC:
if ( ber_sockbuf_get_option( ld->ld_sbp,
LBER_SOCKBUF_OPT_DESC, optdata ) != 0 ) {
LDAP_SET_LDERRNO( ld, LDAP_LOCAL_ERROR, NULL, NULL );
rc = -1;
}
break;
/* fields in the LDAP structure */
case LDAP_OPT_DEREF:
*((int *) optdata) = ld->ld_deref;
break;
case LDAP_OPT_SIZELIMIT:
*((int *) optdata) = ld->ld_sizelimit;
break;
case LDAP_OPT_TIMELIMIT:
*((int *) optdata) = ld->ld_timelimit;
break;
case LDAP_OPT_REFERRAL_HOP_LIMIT:
*((int *) optdata) = ld->ld_refhoplimit;
break;
case LDAP_OPT_PROTOCOL_VERSION:
*((int *) optdata) = ld->ld_version;
break;
case LDAP_OPT_SERVER_CONTROLS:
/* fall through */
case LDAP_OPT_CLIENT_CONTROLS:
*((LDAPControl ***)optdata) = NULL;
/* nsldapi_dup_controls returns -1 and sets lderrno on error */
rc = nsldapi_dup_controls( ld, (LDAPControl ***)optdata,
( option == LDAP_OPT_SERVER_CONTROLS ) ?
ld->ld_servercontrols : ld->ld_clientcontrols );
break;
/* rebind proc */
case LDAP_OPT_REBIND_FN:
*((LDAP_REBINDPROC_CALLBACK **) optdata) = ld->ld_rebind_fn;
break;
case LDAP_OPT_REBIND_ARG:
*((void **) optdata) = ld->ld_rebind_arg;
break;
/* i/o function pointers */
case LDAP_OPT_IO_FN_PTRS:
if ( ld->ld_io_fns_ptr == NULL ) {
memset( optdata, 0, sizeof( struct ldap_io_fns ));
} else {
/* struct copy */
*((struct ldap_io_fns *)optdata) = *(ld->ld_io_fns_ptr);
}
break;
/* extended i/o function pointers */
case LDAP_X_OPT_EXTIO_FN_PTRS:
if ( ((struct ldap_x_ext_io_fns *) optdata)->lextiof_size == LDAP_X_EXTIO_FNS_SIZE_REV0) {
((struct ldap_x_ext_io_fns_rev0 *) optdata)->lextiof_close = ld->ld_extclose_fn;
((struct ldap_x_ext_io_fns_rev0 *) optdata)->lextiof_connect = ld->ld_extconnect_fn;
((struct ldap_x_ext_io_fns_rev0 *) optdata)->lextiof_read = ld->ld_extread_fn;
((struct ldap_x_ext_io_fns_rev0 *) optdata)->lextiof_write = ld->ld_extwrite_fn;
((struct ldap_x_ext_io_fns_rev0 *) optdata)->lextiof_poll = ld->ld_extpoll_fn;
((struct ldap_x_ext_io_fns_rev0 *) optdata)->lextiof_newhandle = ld->ld_extnewhandle_fn;
((struct ldap_x_ext_io_fns_rev0 *) optdata)->lextiof_disposehandle = ld->ld_extdisposehandle_fn;
((struct ldap_x_ext_io_fns_rev0 *) optdata)->lextiof_session_arg = ld->ld_ext_session_arg;
} else if ( ((struct ldap_x_ext_io_fns *) optdata)->lextiof_size ==
LDAP_X_EXTIO_FNS_SIZE ) {
/* struct copy */
*((struct ldap_x_ext_io_fns *) optdata) = ld->ld_ext_io_fns;
} else {
LDAP_SET_LDERRNO( ld, LDAP_PARAM_ERROR, NULL, NULL );
rc = -1;
}
break;
/* get socketargp in extended i/o function */
case LDAP_X_OPT_SOCKETARG:
if ( ber_sockbuf_get_option( ld->ld_sbp,LBER_SOCKBUF_OPT_SOCK_ARG, optdata)
!= 0 ) {
LDAP_SET_LDERRNO( ld, LDAP_LOCAL_ERROR, NULL, NULL );
rc = -1;
}
break;
/* thread function pointers */
case LDAP_OPT_THREAD_FN_PTRS:
/* struct copy */
*((struct ldap_thread_fns *) optdata) = ld->ld_thread;
break;
/* extra thread function pointers */
case LDAP_OPT_EXTRA_THREAD_FN_PTRS:
/* struct copy */
*((struct ldap_extra_thread_fns *) optdata) = ld->ld_thread2;
break;
/* DNS function pointers */
case LDAP_OPT_DNS_FN_PTRS:
/* struct copy */
*((struct ldap_dns_fns *) optdata) = ld->ld_dnsfn;
break;
/* cache function pointers */
case LDAP_OPT_CACHE_FN_PTRS:
/* struct copy */
*((struct ldap_cache_fns *) optdata) = ld->ld_cache;
break;
case LDAP_OPT_CACHE_STRATEGY:
*((int *) optdata) = ld->ld_cache_strategy;
break;
case LDAP_OPT_CACHE_ENABLE:
*((int *) optdata) = ld->ld_cache_on;
break;
case LDAP_OPT_ERROR_NUMBER:
*((int *) optdata) = LDAP_GET_LDERRNO( ld, NULL, NULL );
break;
case LDAP_OPT_ERROR_STRING:
(void)LDAP_GET_LDERRNO( ld, NULL, (char **)optdata );
*((char **) optdata) = nsldapi_strdup( *((char **) optdata ));
break;
case LDAP_OPT_MATCHED_DN:
(void)LDAP_GET_LDERRNO( ld, (char **)optdata, NULL );
*((char **) optdata) = nsldapi_strdup( *((char **) optdata ));
break;
case LDAP_OPT_PREFERRED_LANGUAGE:
if ( NULL != ld->ld_preferred_language ) {
*((char **) optdata) =
nsldapi_strdup(ld->ld_preferred_language);
} else {
*((char **) optdata) = NULL;
}
break;
case LDAP_OPT_API_FEATURE_INFO:
rc = nsldapi_get_feature_info( (LDAPAPIFeatureInfo *)optdata );
if ( rc != LDAP_SUCCESS ) {
LDAP_SET_LDERRNO( ld, rc, NULL, NULL );
rc = -1;
}
break;
case LDAP_OPT_HOST_NAME:
*((char **) optdata) = nsldapi_strdup( ld->ld_defhost );
break;
case LDAP_X_OPT_CONNECT_TIMEOUT:
*((int *) optdata) = ld->ld_connect_timeout;
break;
#ifdef LDAP_SASLIO_HOOKS
/* SASL options */
case LDAP_OPT_X_SASL_MECH:
*((char **) optdata) = nsldapi_strdup(ld->ld_def_sasl_mech);
break;
case LDAP_OPT_X_SASL_REALM:
*((char **) optdata) = nsldapi_strdup(ld->ld_def_sasl_realm);
break;
case LDAP_OPT_X_SASL_AUTHCID:
*((char **) optdata) = nsldapi_strdup(ld->ld_def_sasl_authcid);
break;
case LDAP_OPT_X_SASL_AUTHZID:
*((char **) optdata) = nsldapi_strdup(ld->ld_def_sasl_authzid);
break;
case LDAP_OPT_X_SASL_SSF:
{
int sc;
sasl_ssf_t *ssf;
sasl_conn_t *ctx;
if( ld->ld_defconn == NULL ) {
return -1;
}
ctx = (sasl_conn_t *)(ld->ld_defconn->lconn_sasl_ctx);
if ( ctx == NULL ) {
return -1;
}
sc = sasl_getprop( ctx, SASL_SSF, (const void **) &ssf );
if ( sc != SASL_OK ) {
return -1;
}
*((sasl_ssf_t *) optdata) = *ssf;
}
break;
case LDAP_OPT_X_SASL_SSF_MIN:
*((sasl_ssf_t *) optdata) = ld->ld_sasl_secprops.min_ssf;
break;
case LDAP_OPT_X_SASL_SSF_MAX:
*((sasl_ssf_t *) optdata) = ld->ld_sasl_secprops.max_ssf;
break;
case LDAP_OPT_X_SASL_MAXBUFSIZE:
*((sasl_ssf_t *) optdata) = ld->ld_sasl_secprops.maxbufsize;
break;
case LDAP_OPT_X_SASL_SSF_EXTERNAL:
case LDAP_OPT_X_SASL_SECPROPS:
/*
* These options are write only. Making these options
* read/write would expose semi-private interfaces of libsasl
* for which there are no cross platform/standardized
* definitions.
*/
LDAP_SET_LDERRNO( ld, LDAP_PARAM_ERROR, NULL, NULL );
rc = -1;
break;
#endif
default:
LDAP_SET_LDERRNO( ld, LDAP_PARAM_ERROR, NULL, NULL );
rc = -1;
}
if (ld != &nsldapi_ld_defaults)
LDAP_MUTEX_UNLOCK( ld, LDAP_OPTION_LOCK );
return( rc );
}
/*
* Table of extended API features we support.
* The first field is the version of the info. strcuture itself; we do not
* use the ones from this table so it is okay to leave as zero.
*/
static LDAPAPIFeatureInfo nsldapi_extensions[] = {
{ 0, "SERVER_SIDE_SORT", LDAP_API_FEATURE_SERVER_SIDE_SORT },
{ 0, "VIRTUAL_LIST_VIEW", LDAP_API_FEATURE_VIRTUAL_LIST_VIEW },
{ 0, "PERSISTENT_SEARCH", LDAP_API_FEATURE_PERSISTENT_SEARCH },
{ 0, "PROXY_AUTHORIZATION", LDAP_API_FEATURE_PROXY_AUTHORIZATION },
{ 0, "X_LDERRNO", LDAP_API_FEATURE_X_LDERRNO },
{ 0, "X_MEMCACHE", LDAP_API_FEATURE_X_MEMCACHE },
{ 0, "X_IO_FUNCTIONS", LDAP_API_FEATURE_X_IO_FUNCTIONS },
{ 0, "X_EXTIO_FUNCTIONS", LDAP_API_FEATURE_X_EXTIO_FUNCTIONS },
{ 0, "X_DNS_FUNCTIONS", LDAP_API_FEATURE_X_DNS_FUNCTIONS },
{ 0, "X_MEMALLOC_FUNCTIONS", LDAP_API_FEATURE_X_MEMALLOC_FUNCTIONS },
{ 0, "X_THREAD_FUNCTIONS", LDAP_API_FEATURE_X_THREAD_FUNCTIONS },
{ 0, "X_EXTHREAD_FUNCTIONS", LDAP_API_FEATURE_X_EXTHREAD_FUNCTIONS },
{ 0, "X_GETLANGVALUES", LDAP_API_FEATURE_X_GETLANGVALUES },
{ 0, "X_CLIENT_SIDE_SORT", LDAP_API_FEATURE_X_CLIENT_SIDE_SORT },
{ 0, "X_URL_FUNCTIONS", LDAP_API_FEATURE_X_URL_FUNCTIONS },
{ 0, "X_FILTER_FUNCTIONS", LDAP_API_FEATURE_X_FILTER_FUNCTIONS },
};
#define NSLDAPI_EXTENSIONS_COUNT \
(sizeof(nsldapi_extensions)/sizeof(LDAPAPIFeatureInfo))
/*
* Retrieve information about this implementation of the LDAP API.
* Returns an LDAP error code.
*/
static int
nsldapi_get_api_info( LDAPAPIInfo *aip )
{
int i;
if ( aip == NULL ) {
return( LDAP_PARAM_ERROR );
}
aip->ldapai_api_version = LDAP_API_VERSION;
if ( aip->ldapai_info_version != LDAP_API_INFO_VERSION ) {
aip->ldapai_info_version = LDAP_API_INFO_VERSION;
return( LDAP_PARAM_ERROR );
}
aip->ldapai_protocol_version = LDAP_VERSION_MAX;
aip->ldapai_vendor_version = LDAP_VENDOR_VERSION;
if (( aip->ldapai_vendor_name = nsldapi_strdup( LDAP_VENDOR_NAME ))
== NULL ) {
return( LDAP_NO_MEMORY );
}
if ( NSLDAPI_EXTENSIONS_COUNT < 1 ) {
aip->ldapai_extensions = NULL;
} else {
if (( aip->ldapai_extensions = NSLDAPI_CALLOC(
NSLDAPI_EXTENSIONS_COUNT + 1, sizeof(char *))) == NULL ) {
NSLDAPI_FREE( aip->ldapai_vendor_name );
aip->ldapai_vendor_name = NULL;
return( LDAP_NO_MEMORY );
}
for ( i = 0; i < NSLDAPI_EXTENSIONS_COUNT; ++i ) {
if (( aip->ldapai_extensions[i] = nsldapi_strdup(
nsldapi_extensions[i].ldapaif_name )) == NULL ) {
ldap_value_free( aip->ldapai_extensions );
NSLDAPI_FREE( aip->ldapai_vendor_name );
aip->ldapai_extensions = NULL;
aip->ldapai_vendor_name = NULL;
return( LDAP_NO_MEMORY );
}
}
}
return( LDAP_SUCCESS );
}
/*
* Retrieves information about a specific extended feature of the LDAP API/
* Returns an LDAP error code.
*/
static int
nsldapi_get_feature_info( LDAPAPIFeatureInfo *fip )
{
int i;
if ( fip == NULL || fip->ldapaif_name == NULL ) {
return( LDAP_PARAM_ERROR );
}
if ( fip->ldapaif_info_version != LDAP_FEATURE_INFO_VERSION ) {
fip->ldapaif_info_version = LDAP_FEATURE_INFO_VERSION;
return( LDAP_PARAM_ERROR );
}
for ( i = 0; i < NSLDAPI_EXTENSIONS_COUNT; ++i ) {
if ( strcmp( fip->ldapaif_name,
nsldapi_extensions[i].ldapaif_name ) == 0 ) {
fip->ldapaif_version =
nsldapi_extensions[i].ldapaif_version;
break;
}
}
return(( i < NSLDAPI_EXTENSIONS_COUNT ) ? LDAP_SUCCESS
: LDAP_PARAM_ERROR );
}

View file

@ -0,0 +1,480 @@
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is Mozilla Communicator client code, released
* March 31, 1998.
*
* The Initial Developer of the Original Code is
* Netscape Communications Corporation.
* Portions created by the Initial Developer are Copyright (C) 1998-1999
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
*
* Alternatively, the contents of this file may be used under the terms of
* either of the GNU General Public License Version 2 or later (the "GPL"),
* or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
/*
* Copyright (c) 1990 Regents of the University of Michigan.
* All rights reserved.
*/
/*
* getvalues.c
*/
#if 0
#ifndef lint
static char copyright[] = "@(#) Copyright (c) 1990 Regents of the University of Michigan.\nAll rights reserved.\n";
#endif
#endif
#include "ldap-int.h"
static void **
internal_ldap_get_values( LDAP *ld, LDAPMessage *entry, const char *target,
int lencall )
{
struct berelement ber;
char *attr;
int rc;
void **vals;
LDAPDebug( LDAP_DEBUG_TRACE, "ldap_get_values\n", 0, 0, 0 );
if ( !NSLDAPI_VALID_LDAP_POINTER( ld )) {
return( NULL ); /* punt */
}
if ( target == NULL ||
!NSLDAPI_VALID_LDAPMESSAGE_ENTRY_POINTER( entry )) {
LDAP_SET_LDERRNO( ld, LDAP_PARAM_ERROR, NULL, NULL );
return( NULL );
}
ber = *entry->lm_ber;
/* skip sequence, dn, sequence of, and snag the first attr */
if ( ber_scanf( &ber, "{x{{a", &attr ) == LBER_ERROR ) {
LDAP_SET_LDERRNO( ld, LDAP_DECODING_ERROR, NULL, NULL );
return( NULL );
}
rc = strcasecmp( (char *)target, attr );
NSLDAPI_FREE( attr );
if ( rc != 0 ) {
while ( 1 ) {
if ( ber_scanf( &ber, "x}{a", &attr ) == LBER_ERROR ) {
LDAP_SET_LDERRNO( ld, LDAP_DECODING_ERROR,
NULL, NULL );
return( NULL );
}
rc = strcasecmp( (char *)target, attr );
if ( rc == 0 ) {
NSLDAPI_FREE( attr );
break;
}
NSLDAPI_FREE( attr );
}
}
/*
* if we get this far, we've found the attribute and are sitting
* just before the set of values.
*/
if ( lencall ) {
rc = ber_scanf( &ber, "[V]", &vals );
} else {
rc = ber_scanf( &ber, "[v]", &vals );
}
if ( rc == LBER_ERROR ) {
rc = LDAP_DECODING_ERROR;
} else {
rc = LDAP_SUCCESS;
}
LDAP_SET_LDERRNO( ld, rc, NULL, NULL );
return(( rc == LDAP_SUCCESS ) ? vals : NULL );
}
/* For language-sensitive attribute matching, we are looking for a
language tag that looks like one of the following:
cn
cn;lang-en
cn;lang-en-us
cn;lang-ja
cn;lang-ja-JP-kanji
The base language specification consists of two letters following
"lang-". After that, there may be additional language-specific
narrowings preceded by a "-". In our processing we go from the
specific to the general, preferring a complete subtype match, but
accepting a partial one. For example:
For a request for "cn;lang-en-us", we would return cn;lang-en-us
if present, otherwise cn;lang-en if present, otherwise cn.
Besides the language subtype, there may be other subtypes:
cn;lang-ja;binary (Unlikely!)
cn;lang-ja;phonetic
If not in the target, they are ignored. If they are in the target,
they must be in the attribute to match.
*/
#define LANG_SUBTYPE_INDEX_NONE -1
#define LANG_SUBTYPE_INDEX_DUPLICATE -2
typedef struct {
int start;
int length;
} _SubStringIndex;
static int
parse_subtypes( const char *target, int *baseLenp, char **langp,
_SubStringIndex **subs, int *nsubtypes )
{
int nSubtypes = 0;
int ind = 0;
char *nextToken;
_SubStringIndex *result = NULL;
int langIndex;
int targetLen;
int subtypeStart;
langIndex = LANG_SUBTYPE_INDEX_NONE;
*subs = NULL;
*langp = NULL;
*baseLenp = 0;
*nsubtypes = 0;
targetLen = strlen( target );
/* Parse past base attribute */
nextToken = strchr( target, ';' );
if ( NULL != nextToken ) {
subtypeStart = nextToken - target + 1;
*baseLenp = subtypeStart - 1;
}
else {
subtypeStart = targetLen;
*baseLenp = subtypeStart;
}
ind = subtypeStart;
/* How many subtypes? */
nextToken = (char *)target + subtypeStart;
while ( nextToken && *nextToken ) {
char *thisToken = nextToken;
nextToken = strchr( thisToken, ';' );
if ( NULL != nextToken )
nextToken++;
if ( 0 == strncasecmp( thisToken, "lang-", 5 ) ) {
/* If there was a previous lang tag, this is illegal! */
if ( langIndex != LANG_SUBTYPE_INDEX_NONE ) {
langIndex = LANG_SUBTYPE_INDEX_DUPLICATE;
return langIndex;
}
else {
langIndex = nSubtypes;
}
} else {
nSubtypes++;
}
}
/* No language subtype? */
if ( langIndex < 0 )
return langIndex;
/* Allocate array of non-language subtypes */
if ( nSubtypes > 0 ) {
result = (_SubStringIndex *)NSLDAPI_MALLOC( sizeof(*result)
* nSubtypes );
memset( result, 0, sizeof(*result) * nSubtypes );
}
ind = 0;
nSubtypes = 0;
ind = subtypeStart;
nextToken = (char *)target + subtypeStart;
while ( nextToken && *nextToken ) {
char *thisToken = nextToken;
int len;
nextToken = strchr( thisToken, ';' );
if ( NULL != nextToken ) {
len = nextToken - thisToken;
nextToken++;
}
else {
nextToken = (char *)target + targetLen;
len = nextToken - thisToken;
}
if ( 0 == strncasecmp( thisToken, "lang-", 5 ) ) {
int i;
*langp = (char *)NSLDAPI_MALLOC( len + 1 );
for( i = 0; i < len; i++ )
(*langp)[i] = toupper( target[ind+i] );
(*langp)[len] = 0;
}
else {
result[nSubtypes].start = thisToken - target;
result[nSubtypes].length = len;
nSubtypes++;
}
}
*subs = result;
*nsubtypes = nSubtypes;
return langIndex;
}
static int
check_lang_match( const char *target, const char *baseTarget,
_SubStringIndex *targetTypes,
int ntargetTypes, char *targetLang, char *attr )
{
int langIndex;
_SubStringIndex *subtypes;
int baseLen;
char *lang;
int nsubtypes;
int mismatch = 0;
int match = -1;
int i;
/* Get all subtypes in the attribute name */
langIndex = parse_subtypes( attr, &baseLen, &lang, &subtypes, &nsubtypes );
/* Check if there any required non-language subtypes which are
not in this attribute */
for( i = 0; i < ntargetTypes; i++ ) {
char *t = (char *)target+targetTypes[i].start;
int tlen = targetTypes[i].length;
int j;
for( j = 0; j < nsubtypes; j++ ) {
char *a = attr + subtypes[j].start;
int alen = subtypes[j].length;
if ( (tlen == alen) && !strncasecmp( t, a, tlen ) )
break;
}
if ( j >= nsubtypes ) {
mismatch = 1;
break;
}
}
if ( mismatch ) {
if ( NULL != subtypes )
NSLDAPI_FREE( subtypes );
if ( NULL != lang )
NSLDAPI_FREE( lang );
return -1;
}
/* If there was no language subtype... */
if ( langIndex < 0 ) {
if ( NULL != subtypes )
NSLDAPI_FREE( subtypes );
if ( NULL != lang )
NSLDAPI_FREE( lang );
if ( LANG_SUBTYPE_INDEX_NONE == langIndex )
return 0;
else
return -1;
}
/* Okay, now check the language subtag */
i = 0;
while( targetLang[i] && lang[i] &&
(toupper(targetLang[i]) == toupper(lang[i])) )
i++;
/* The total length can't be longer than the requested subtype */
if ( !lang[i] || (lang[i] == ';') ) {
/* If the found subtype is shorter than the requested one, the next
character in the requested one should be "-" */
if ( !targetLang[i] || (targetLang[i] == '-') )
match = i;
}
return match;
}
static int check_base_match( const char *target, char *attr )
{
int i = 0;
int rc;
while( target[i] && attr[i] && (toupper(target[i]) == toupper(attr[i])) )
i++;
rc = ( !target[i] && (!attr[i] || (';' == attr[i])) );
return rc;
}
static void **
internal_ldap_get_lang_values( LDAP *ld, LDAPMessage *entry,
const char *target, char **type, int lencall )
{
struct berelement ber;
char *attr = NULL;
int rc;
void **vals = NULL;
int langIndex;
_SubStringIndex *subtypes;
int nsubtypes;
char *baseTarget = NULL;
int bestMatch = 0;
char *lang = NULL;
int len;
int firstAttr = 1;
char *bestType = NULL;
LDAPDebug( LDAP_DEBUG_TRACE, "ldap_get_values\n", 0, 0, 0 );
if ( !NSLDAPI_VALID_LDAP_POINTER( ld )) {
return( NULL );
}
if ( (target == NULL) ||
!NSLDAPI_VALID_LDAPMESSAGE_ENTRY_POINTER( entry )) {
LDAP_SET_LDERRNO( ld, LDAP_PARAM_ERROR, NULL, NULL );
return( NULL );
}
/* A language check was requested, so see if there really is a
language subtype in the attribute spec */
langIndex = parse_subtypes( target, &len, &lang,
&subtypes, &nsubtypes );
if ( langIndex < 0 ) {
if ( NULL != subtypes ) {
NSLDAPI_FREE( subtypes );
subtypes = NULL;
}
vals = internal_ldap_get_values( ld, entry, target, lencall );
if ( NULL != type )
*type = nsldapi_strdup( target );
return vals;
} else {
/* Get just the base attribute name */
baseTarget = (char *)NSLDAPI_MALLOC( len + 1 );
memcpy( baseTarget, target, len );
baseTarget[len] = 0;
}
ber = *entry->lm_ber;
/* Process all attributes in the entry */
while ( 1 ) {
int foundMatch = 0;
if ( NULL != attr )
NSLDAPI_FREE( attr );
if ( firstAttr ) {
firstAttr = 0;
/* skip sequence, dn, sequence of, and snag the first attr */
if ( ber_scanf( &ber, "{x{{a", &attr ) == LBER_ERROR ) {
break;
}
} else {
if ( ber_scanf( &ber, "{a", &attr ) == LBER_ERROR ) {
break;
}
}
if ( check_base_match( (const char *)baseTarget, attr ) ) {
int thisMatch = check_lang_match( target, baseTarget,
subtypes, nsubtypes, lang, attr );
if ( thisMatch > bestMatch ) {
if ( vals )
NSLDAPI_FREE( vals );
foundMatch = 1;
bestMatch = thisMatch;
if ( NULL != bestType )
NSLDAPI_FREE( bestType );
bestType = attr;
attr = NULL;
}
}
if ( foundMatch ) {
if ( lencall ) {
rc = ber_scanf( &ber, "[V]}", &vals );
} else {
rc = ber_scanf( &ber, "[v]}", &vals );
}
} else {
ber_scanf( &ber, "x}" );
}
}
NSLDAPI_FREE( lang );
NSLDAPI_FREE( baseTarget );
NSLDAPI_FREE( subtypes );
if ( NULL != type )
*type = bestType;
else if ( NULL != bestType )
NSLDAPI_FREE( bestType );
if ( NULL == vals ) {
rc = LDAP_DECODING_ERROR;
} else {
rc = LDAP_SUCCESS;
}
LDAP_SET_LDERRNO( ld, rc, NULL, NULL );
return( vals );
}
char **
LDAP_CALL
ldap_get_values( LDAP *ld, LDAPMessage *entry, const char *target )
{
return( (char **) internal_ldap_get_values( ld, entry, target, 0 ) );
}
struct berval **
LDAP_CALL
ldap_get_values_len( LDAP *ld, LDAPMessage *entry, const char *target )
{
return( (struct berval **) internal_ldap_get_values( ld, entry, target,
1 ) );
}
char **
LDAP_CALL
ldap_get_lang_values( LDAP *ld, LDAPMessage *entry, const char *target,
char **type )
{
return( (char **) internal_ldap_get_lang_values( ld, entry,
target, type, 0 ) );
}
struct berval **
LDAP_CALL
ldap_get_lang_values_len( LDAP *ld, LDAPMessage *entry, const char *target,
char **type )
{
return( (struct berval **) internal_ldap_get_lang_values( ld, entry,
target, type, 1 ) );
}

View file

@ -0,0 +1,888 @@
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is Mozilla Communicator client code, released
* March 31, 1998.
*
* The Initial Developer of the Original Code is
* Netscape Communications Corporation.
* Portions created by the Initial Developer are Copyright (C) 1998-1999
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
*
* Alternatively, the contents of this file may be used under the terms of
* either of the GNU General Public License Version 2 or later (the "GPL"),
* or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
#ifndef _LDAPINT_H
#define _LDAPINT_H
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <errno.h>
#include <time.h>
#include <fcntl.h>
#ifdef hpux
#include <strings.h>
#endif /* hpux */
#ifdef _WINDOWS
# define FD_SETSIZE 256 /* number of connections we support */
# define WIN32_LEAN_AND_MEAN
# include <windows.h>
#elif defined(macintosh)
#include "ldap-macos.h"
#else /* _WINDOWS */
# include <sys/time.h>
# include <sys/types.h>
# include <sys/socket.h>
# include <netinet/in.h>
#if !defined(XP_OS2) && !defined(XP_BEOS)
# include <arpa/inet.h>
#endif
# include <netdb.h>
#if !defined(hpux) && !defined(SUNOS4) && !defined(XP_BEOS)
# include <sys/select.h>
#endif /* !defined(hpux) and others */
#endif /* _WINDOWS */
#if defined(IRIX)
#include <bstring.h>
#endif /* IRIX */
#ifdef XP_BEOS
#define NSLDAPI_AVOID_OS_SOCKETS
#endif
#define NSLBERI_LBER_INT_FRIEND
#ifdef macintosh
#include "lber-int.h"
#else /* macintosh */
#include "../liblber/lber-int.h"
#endif /* macintosh */
#include "ldap.h"
#include "ldaprot.h"
#include "ldaplog.h"
#include "portable.h"
#ifdef LDAP_ASYNC_IO
#ifdef NEED_FILIO
#include <sys/filio.h> /* to get FIONBIO for ioctl() call */
#else /* NEED_FILIO */
#if !defined( _WINDOWS) && !defined (macintosh)
#include <sys/ioctl.h> /* to get FIONBIO for ioctl() call */
#endif /* _WINDOWS && macintosh */
#endif /* NEED_FILIO */
#endif /* LDAP_ASYNC_IO */
#ifdef USE_SYSCONF
# include <unistd.h>
#endif /* USE_SYSCONF */
#ifdef LDAP_SASLIO_HOOKS
#include <sasl.h>
#define SASL_MAX_BUFF_SIZE 65536
#define SASL_MIN_BUFF_SIZE 4096
#endif
#if !defined(_WINDOWS) && !defined(macintosh) && !defined(BSDI) && \
!defined(XP_OS2) && !defined(XP_BEOS) && !defined(NTO) && \
!defined(DARWIN)
#define NSLDAPI_HAVE_POLL 1
#endif
/* SSL version, or 0 if not built with SSL */
#if defined(NET_SSL)
# define SSL_VERSION 3
#else
# define SSL_VERSION 0
#endif
#define LDAP_URL_URLCOLON "URL:"
#define LDAP_URL_URLCOLON_LEN 4
#define LDAP_LDAP_REF_STR LDAP_URL_PREFIX
#define LDAP_LDAP_REF_STR_LEN LDAP_URL_PREFIX_LEN
#define LDAP_LDAPS_REF_STR LDAPS_URL_PREFIX
#define LDAP_LDAPS_REF_STR_LEN LDAPS_URL_PREFIX_LEN
/* default limit on nesting of referrals */
#define LDAP_DEFAULT_REFHOPLIMIT 5
#ifdef LDAP_DNS
#define LDAP_DX_REF_STR "dx://"
#define LDAP_DX_REF_STR_LEN 5
#endif /* LDAP_DNS */
typedef enum {
LDAP_CACHE_LOCK,
LDAP_MEMCACHE_LOCK,
LDAP_MSGID_LOCK,
LDAP_REQ_LOCK,
LDAP_RESP_LOCK,
LDAP_ABANDON_LOCK,
LDAP_CTRL_LOCK,
LDAP_OPTION_LOCK,
LDAP_ERR_LOCK,
LDAP_CONN_LOCK,
LDAP_IOSTATUS_LOCK, /* serializes access to ld->ld_iostatus */
LDAP_RESULT_LOCK,
LDAP_PEND_LOCK,
LDAP_THREADID_LOCK,
#ifdef LDAP_SASLIO_HOOKS
LDAP_SASL_LOCK,
#endif
LDAP_MAX_LOCK
} LDAPLock;
/*
* This structure represents both ldap messages and ldap responses.
* These are really the same, except in the case of search responses,
* where a response has multiple messages.
*/
struct ldapmsg {
int lm_msgid; /* the message id */
ber_tag_t lm_msgtype; /* the message type */
BerElement *lm_ber; /* the ber encoded message contents */
struct ldapmsg *lm_chain; /* for search - next msg in the resp */
struct ldapmsg *lm_next; /* next response */
int lm_fromcache; /* memcache: origin of message */
};
/*
* structure for tracking LDAP server host, ports, DNs, etc.
*/
typedef struct ldap_server {
char *lsrv_host;
char *lsrv_dn; /* if NULL, use default */
int lsrv_port;
unsigned long lsrv_options; /* boolean options */
#define LDAP_SRV_OPT_SECURE 0x01
struct ldap_server *lsrv_next;
} LDAPServer;
/*
* structure for representing an LDAP server connection
*/
typedef struct ldap_conn {
Sockbuf *lconn_sb;
BerElement *lconn_ber; /* non-NULL if in midst of msg. */
int lconn_version; /* LDAP protocol version */
int lconn_refcnt;
unsigned long lconn_lastused; /* time */
int lconn_status;
#define LDAP_CONNST_CONNECTING 2
#define LDAP_CONNST_CONNECTED 3
#define LDAP_CONNST_DEAD 4
LDAPServer *lconn_server;
char *lconn_binddn; /* DN of last successful bind */
int lconn_bound; /* has a bind been done? */
int lconn_pending_requests; /* count of unsent req*/
char *lconn_krbinstance;
#ifdef LDAP_SASLIO_HOOKS
sasl_conn_t *lconn_sasl_ctx; /* the sasl connection context */
#endif /* LDAP_SASLIO_HOOKS */
struct ldap_conn *lconn_next;
} LDAPConn;
/*
* structure used to track outstanding requests
*/
typedef struct ldapreq {
int lr_msgid; /* the message id */
int lr_status; /* status of request */
#define LDAP_REQST_INPROGRESS 1
#define LDAP_REQST_CHASINGREFS 2
#define LDAP_REQST_WRITING 4
#define LDAP_REQST_CONNDEAD 5 /* associated conn. has failed */
int lr_outrefcnt; /* count of outstanding referrals */
int lr_origid; /* original request's message id */
int lr_parentcnt; /* count of parent requests */
ber_tag_t lr_res_msgtype; /* result message type */
int lr_expect_resp; /* if non-zero, expect a response */
int lr_res_errno; /* result LDAP errno */
char *lr_res_error; /* result error string */
char *lr_res_matched;/* result matched DN string */
BerElement *lr_ber; /* ber encoded request contents */
LDAPConn *lr_conn; /* connection used to send request */
char *lr_binddn; /* request is a bind for this DN */
struct ldapreq *lr_parent; /* request that spawned this referral */
struct ldapreq *lr_child; /* list of requests we spawned */
struct ldapreq *lr_sibling; /* next referral spawned */
struct ldapreq *lr_prev; /* ld->ld_requests previous request */
struct ldapreq *lr_next; /* ld->ld_requests next request */
LDAPControl **lr_res_ctrls; /* result controls */
} LDAPRequest;
typedef struct ldappend {
void *lp_sema; /* semaphore to post */
int lp_msgid; /* message id */
LDAPMessage *lp_result; /* result storage */
struct ldappend *lp_prev; /* previous pending */
struct ldappend *lp_next; /* next pending */
} LDAPPend;
/*
* forward declaration for I/O status structure (defined in os-ip.c)
*/
typedef struct nsldapi_iostatus_info NSLDAPIIOStatus;
/*
* old extended IO structure (before writev callback was added)
*/
struct ldap_x_ext_io_fns_rev0 {
int lextiof_size;
LDAP_X_EXTIOF_CONNECT_CALLBACK *lextiof_connect;
LDAP_X_EXTIOF_CLOSE_CALLBACK *lextiof_close;
LDAP_X_EXTIOF_READ_CALLBACK *lextiof_read;
LDAP_X_EXTIOF_WRITE_CALLBACK *lextiof_write;
LDAP_X_EXTIOF_POLL_CALLBACK *lextiof_poll;
LDAP_X_EXTIOF_NEWHANDLE_CALLBACK *lextiof_newhandle;
LDAP_X_EXTIOF_DISPOSEHANDLE_CALLBACK *lextiof_disposehandle;
void *lextiof_session_arg;
};
#define LDAP_X_EXTIO_FNS_SIZE_REV0 sizeof(struct ldap_x_ext_io_fns_rev0)
/*
* Structure representing an ldap connection.
*
* This is an opaque struct; the fields are not visible to
* applications that use the LDAP API.
*/
struct ldap {
struct sockbuf *ld_sbp; /* pointer to socket desc. & buffer */
char *ld_host;
int ld_version; /* LDAP protocol version */
char ld_lberoptions;
int ld_deref;
int ld_timelimit;
int ld_sizelimit;
struct ldap_filt_desc *ld_filtd; /* from getfilter for ufn searches */
char *ld_ufnprefix; /* for incomplete ufn's */
int ld_errno;
char *ld_error;
char *ld_matched;
int ld_msgid;
/* Note: the ld_requests list is ordered old to new */
LDAPRequest *ld_requests; /* list of outstanding requests */
LDAPMessage *ld_responses; /* list of outstanding responses */
int *ld_abandoned; /* array of abandoned requests */
char *ld_cldapdn; /* DN used in connectionless search */
int ld_cldaptries; /* connectionless search retry count */
int ld_cldaptimeout;/* time between retries */
int ld_refhoplimit; /* limit on referral nesting */
unsigned long ld_options; /* boolean options */
#define LDAP_BITOPT_REFERRALS 0x80000000
#define LDAP_BITOPT_SSL 0x40000000
#define LDAP_BITOPT_DNS 0x20000000
#define LDAP_BITOPT_RESTART 0x10000000
#define LDAP_BITOPT_RECONNECT 0x08000000
#define LDAP_BITOPT_ASYNC 0x04000000
#define LDAP_BITOPT_NOREBIND 0x02000000
char *ld_defhost; /* full name of default server */
int ld_defport; /* port of default server */
BERTranslateProc ld_lber_encode_translate_proc;
BERTranslateProc ld_lber_decode_translate_proc;
LDAPConn *ld_defconn; /* default connection */
LDAPConn *ld_conns; /* list of all server connections */
NSLDAPIIOStatus *ld_iostatus; /* status info. about network sockets */
LDAP_REBINDPROC_CALLBACK *ld_rebind_fn;
void *ld_rebind_arg;
/* function pointers, etc. for extended I/O */
struct ldap_x_ext_io_fns ld_ext_io_fns;
#define ld_extio_size ld_ext_io_fns.lextiof_size
#define ld_extclose_fn ld_ext_io_fns.lextiof_close
#define ld_extconnect_fn ld_ext_io_fns.lextiof_connect
#define ld_extread_fn ld_ext_io_fns.lextiof_read
#define ld_extwrite_fn ld_ext_io_fns.lextiof_write
#define ld_extwritev_fn ld_ext_io_fns.lextiof_writev
#define ld_extpoll_fn ld_ext_io_fns.lextiof_poll
#define ld_extnewhandle_fn ld_ext_io_fns.lextiof_newhandle
#define ld_extdisposehandle_fn ld_ext_io_fns.lextiof_disposehandle
#define ld_ext_session_arg ld_ext_io_fns.lextiof_session_arg
/* allocated pointer for older I/O functions */
struct ldap_io_fns *ld_io_fns_ptr;
#define NSLDAPI_USING_CLASSIC_IO_FUNCTIONS( ld ) ((ld)->ld_io_fns_ptr != NULL)
/* function pointers, etc. for DNS */
struct ldap_dns_fns ld_dnsfn;
#define ld_dns_extradata ld_dnsfn.lddnsfn_extradata
#define ld_dns_bufsize ld_dnsfn.lddnsfn_bufsize
#define ld_dns_gethostbyname_fn ld_dnsfn.lddnsfn_gethostbyname
#define ld_dns_gethostbyaddr_fn ld_dnsfn.lddnsfn_gethostbyaddr
#define ld_dns_getpeername_fn ld_dnsfn.lddnsfn_getpeername
/* function pointers, etc. for threading */
struct ldap_thread_fns ld_thread;
#define ld_mutex_alloc_fn ld_thread.ltf_mutex_alloc
#define ld_mutex_free_fn ld_thread.ltf_mutex_free
#define ld_mutex_lock_fn ld_thread.ltf_mutex_lock
#define ld_mutex_unlock_fn ld_thread.ltf_mutex_unlock
#define ld_get_errno_fn ld_thread.ltf_get_errno
#define ld_set_errno_fn ld_thread.ltf_set_errno
#define ld_get_lderrno_fn ld_thread.ltf_get_lderrno
#define ld_set_lderrno_fn ld_thread.ltf_set_lderrno
#define ld_lderrno_arg ld_thread.ltf_lderrno_arg
void **ld_mutex;
/* function pointers, etc. for caching */
int ld_cache_on;
int ld_cache_strategy;
struct ldap_cache_fns ld_cache;
#define ld_cache_config ld_cache.lcf_config
#define ld_cache_bind ld_cache.lcf_bind
#define ld_cache_unbind ld_cache.lcf_unbind
#define ld_cache_search ld_cache.lcf_search
#define ld_cache_compare ld_cache.lcf_compare
#define ld_cache_add ld_cache.lcf_add
#define ld_cache_delete ld_cache.lcf_delete
#if 0
#define ld_cache_rename ld_cache.lcf_rename
#endif
#define ld_cache_modify ld_cache.lcf_modify
#define ld_cache_modrdn ld_cache.lcf_modrdn
#define ld_cache_abandon ld_cache.lcf_abandon
#define ld_cache_result ld_cache.lcf_result
#define ld_cache_flush ld_cache.lcf_flush
#define ld_cache_arg ld_cache.lcf_arg
/* ldapv3 controls */
LDAPControl **ld_servercontrols;
LDAPControl **ld_clientcontrols;
/* Preferred language */
char *ld_preferred_language;
/* MemCache */
LDAPMemCache *ld_memcache;
/* Pending results */
LDAPPend *ld_pend; /* list of pending results */
/* extra thread function pointers */
struct ldap_extra_thread_fns ld_thread2;
/*
* With the 4.0 and later versions of the LDAP SDK, the extra thread
* functions except for the ld_threadid_fn have been disabled.
* Look at the release notes for the full explanation.
*/
#define ld_mutex_trylock_fn ld_thread2.ltf_mutex_trylock
#define ld_sema_alloc_fn ld_thread2.ltf_sema_alloc
#define ld_sema_free_fn ld_thread2.ltf_sema_free
#define ld_sema_wait_fn ld_thread2.ltf_sema_wait
#define ld_sema_post_fn ld_thread2.ltf_sema_post
#define ld_threadid_fn ld_thread2.ltf_threadid_fn
/* extra data for mutex handling in referrals */
void *ld_mutex_threadid[LDAP_MAX_LOCK];
unsigned long ld_mutex_refcnt[LDAP_MAX_LOCK];
/* connect timeout value (milliseconds) */
int ld_connect_timeout;
#ifdef LDAP_SASLIO_HOOKS
/* SASL default option settings */
char *ld_def_sasl_mech;
char *ld_def_sasl_realm;
char *ld_def_sasl_authcid;
char *ld_def_sasl_authzid;
/* SASL Security properties */
struct sasl_security_properties ld_sasl_secprops;
#endif
};
/* allocate/free mutex */
#define LDAP_MUTEX_ALLOC( ld ) \
(((ld)->ld_mutex_alloc_fn != NULL) ? (ld)->ld_mutex_alloc_fn() : NULL)
/* allocate/free mutex */
#define LDAP_MUTEX_FREE( ld, m ) \
if ( (ld)->ld_mutex_free_fn != NULL && m != NULL ) { \
(ld)->ld_mutex_free_fn( m ); \
}
/* enter/exit critical sections */
/*
* The locks assume that the locks are thread safe. XXXmcs: which means???
*
* Note that we test for both ld_mutex_lock_fn != NULL AND ld_mutex != NULL.
* This is necessary because there is a window in ldap_init() between the
* time we set the ld_mutex_lock_fn pointer and the time we allocate the
* mutexes in which external code COULD be called which COULD make a call to
* something like ldap_get_option(), which uses LDAP_MUTEX_LOCK(). The
* libprldap code does this in its newhandle callback (prldap_newhandle).
*/
#define LDAP_MUTEX_LOCK(ld, lock) \
if ((ld)->ld_mutex_lock_fn != NULL && ld->ld_mutex != NULL) { \
if ((ld)->ld_threadid_fn != NULL) { \
if ((ld)->ld_mutex_threadid[lock] == (ld)->ld_threadid_fn()) { \
(ld)->ld_mutex_refcnt[lock]++; \
} else { \
(ld)->ld_mutex_lock_fn(ld->ld_mutex[lock]); \
(ld)->ld_mutex_threadid[lock] = ld->ld_threadid_fn(); \
(ld)->ld_mutex_refcnt[lock] = 1; \
} \
} else { \
(ld)->ld_mutex_lock_fn(ld->ld_mutex[lock]); \
} \
}
#define LDAP_MUTEX_UNLOCK(ld, lock) \
if ((ld)->ld_mutex_lock_fn != NULL && ld->ld_mutex != NULL) { \
if ((ld)->ld_threadid_fn != NULL) { \
if ((ld)->ld_mutex_threadid[lock] == (ld)->ld_threadid_fn()) { \
(ld)->ld_mutex_refcnt[lock]--; \
if ((ld)->ld_mutex_refcnt[lock] <= 0) { \
(ld)->ld_mutex_threadid[lock] = (void *) -1; \
(ld)->ld_mutex_refcnt[lock] = 0; \
(ld)->ld_mutex_unlock_fn(ld->ld_mutex[lock]); \
} \
} \
} else { \
ld->ld_mutex_unlock_fn(ld->ld_mutex[lock]); \
} \
}
/* Backward compatibility locks */
#define LDAP_MUTEX_BC_LOCK( ld, i ) \
/* the ld_mutex_trylock_fn is always set to NULL */ \
/* in setoption.c as the extra thread functions were */ \
/* turned off in the 4.0 SDK. This check will */ \
/* always be true */ \
if( (ld)->ld_mutex_trylock_fn == NULL ) { \
LDAP_MUTEX_LOCK( ld, i ) ; \
}
#define LDAP_MUTEX_BC_UNLOCK( ld, i ) \
/* the ld_mutex_trylock_fn is always set to NULL */ \
/* in setoption.c as the extra thread functions were */ \
/* turned off in the 4.0 SDK. This check will */ \
/* always be true */ \
if( (ld)->ld_mutex_trylock_fn == NULL ) { \
LDAP_MUTEX_UNLOCK( ld, i ) ; \
}
/* allocate/free semaphore */
#define LDAP_SEMA_ALLOC( ld ) \
(((ld)->ld_sema_alloc_fn != NULL) ? (ld)->ld_sema_alloc_fn() : NULL)
#define LDAP_SEMA_FREE( ld, m ) \
if ( (ld)->ld_sema_free_fn != NULL && m != NULL ) { \
(ld)->ld_sema_free_fn( m ); \
}
/* wait/post binary semaphore */
#define LDAP_SEMA_WAIT( ld, lp ) \
if ( (ld)->ld_sema_wait_fn != NULL ) { \
(ld)->ld_sema_wait_fn( lp->lp_sema ); \
}
#define LDAP_SEMA_POST( ld, lp ) \
if ( (ld)->ld_sema_post_fn != NULL ) { \
(ld)->ld_sema_post_fn( lp->lp_sema ); \
}
#define POST( ld, y, z ) \
/* the ld_mutex_trylock_fn is always set to NULL */ \
/* in setoption.c as the extra thread functions were */ \
/* turned off in the 4.0 SDK. This check will */ \
/* always be false */ \
if( (ld)->ld_mutex_trylock_fn != NULL ) { \
nsldapi_post_result( ld, y, z ); \
}
/* get/set errno */
#ifndef macintosh
#define LDAP_SET_ERRNO( ld, e ) \
if ( (ld)->ld_set_errno_fn != NULL ) { \
(ld)->ld_set_errno_fn( e ); \
} else { \
errno = e; \
}
#define LDAP_GET_ERRNO( ld ) \
(((ld)->ld_get_errno_fn != NULL) ? \
(ld)->ld_get_errno_fn() : errno)
#else /* macintosh */
#define LDAP_SET_ERRNO( ld, e ) \
if ( (ld)->ld_set_errno_fn != NULL ) { \
(ld)->ld_set_errno_fn( e ); \
}
#define LDAP_GET_ERRNO( ld ) \
(((ld)->ld_get_errno_fn != NULL) ? \
(ld)->ld_get_errno_fn() : 0)
#endif
/* get/set ldap-specific errno */
#define LDAP_SET_LDERRNO( ld, e, m, s ) ldap_set_lderrno( ld, e, m, s )
#define LDAP_GET_LDERRNO( ld, m, s ) ldap_get_lderrno( ld, m, s )
/*
* your standard "mimimum of two values" macro
*/
#define NSLDAPI_MIN(a, b) (((a) < (b)) ? (a) : (b))
/*
* handy macro to check whether LDAP struct is set up for CLDAP or not
*/
#define LDAP_IS_CLDAP( ld ) ( ld->ld_sbp->sb_naddr > 0 )
/*
* Some Unix error defs. Under CW 7, we can't define OTUNIXERRORS because
* it generates many conflicts with errno.h. Define what we need here.
* These need to be in sync with OpenTransport.h
*/
#if defined(macintosh)
#define EWOULDBLOCK 35
#define EHOSTUNREACH 65
#endif
/*
* handy macro to check errno "e" for an "in progress" sort of error
*/
#if defined(macintosh) || defined(_WINDOWS)
#define NSLDAPI_ERRNO_IO_INPROGRESS( e ) ((e) == EWOULDBLOCK || (e) == EAGAIN)
#else
#ifdef EAGAIN
#define NSLDAPI_ERRNO_IO_INPROGRESS( e ) ((e) == EWOULDBLOCK || (e) == EINPROGRESS || (e) == EAGAIN)
#else /* EAGAIN */
#define NSLDAPI_ERRNO_IO_INPROGRESS( e ) ((e) == EWOULDBLOCK || (e) == EINPROGRESS)
#endif /* EAGAIN */
#endif /* macintosh || _WINDOWS*/
/*
* macro to return the LDAP protocol version we are using
*/
#define NSLDAPI_LDAP_VERSION( ld ) ( (ld)->ld_defconn == NULL ? \
(ld)->ld_version : \
(ld)->ld_defconn->lconn_version )
/*
* Structures used for handling client filter lists.
*/
#define LDAP_FILT_MAXSIZ 1024
struct ldap_filt_list {
char *lfl_tag;
char *lfl_pattern;
char *lfl_delims;
struct ldap_filt_info *lfl_ilist;
struct ldap_filt_list *lfl_next;
};
struct ldap_filt_desc {
LDAPFiltList *lfd_filtlist;
LDAPFiltInfo *lfd_curfip;
LDAPFiltInfo lfd_retfi;
char lfd_filter[ LDAP_FILT_MAXSIZ ];
char *lfd_curval;
char *lfd_curvalcopy;
char **lfd_curvalwords;
char *lfd_filtprefix;
char *lfd_filtsuffix;
};
/*
* "internal" globals used to track defaults and memory allocation callbacks:
* (the actual definitions are in open.c)
*/
extern struct ldap nsldapi_ld_defaults;
extern struct ldap_memalloc_fns nsldapi_memalloc_fns;
extern int nsldapi_initialized;
/*
* Memory allocation done in liblber should all go through one of the
* following macros. This is so we can plug-in alternative memory
* allocators, etc. as the need arises.
*/
#define NSLDAPI_MALLOC( size ) ldap_x_malloc( size )
#define NSLDAPI_CALLOC( nelem, elsize ) ldap_x_calloc( nelem, elsize )
#define NSLDAPI_REALLOC( ptr, size ) ldap_x_realloc( ptr, size )
#define NSLDAPI_FREE( ptr ) ldap_x_free( ptr )
/*
* macros used to check validity of data structures and parameters
*/
#define NSLDAPI_VALID_LDAP_POINTER( ld ) \
( (ld) != NULL )
#define NSLDAPI_VALID_LDAPMESSAGE_POINTER( lm ) \
( (lm) != NULL )
#define NSLDAPI_VALID_LDAPMESSAGE_ENTRY_POINTER( lm ) \
( (lm) != NULL && (lm)->lm_msgtype == LDAP_RES_SEARCH_ENTRY )
#define NSLDAPI_VALID_LDAPMESSAGE_REFERENCE_POINTER( lm ) \
( (lm) != NULL && (lm)->lm_msgtype == LDAP_RES_SEARCH_REFERENCE )
#define NSLDAPI_VALID_LDAPMESSAGE_BINDRESULT_POINTER( lm ) \
( (lm) != NULL && (lm)->lm_msgtype == LDAP_RES_BIND )
#define NSLDAPI_VALID_LDAPMESSAGE_EXRESULT_POINTER( lm ) \
( (lm) != NULL && (lm)->lm_msgtype == LDAP_RES_EXTENDED )
#define NSLDAPI_VALID_LDAPMOD_ARRAY( mods ) \
( (mods) != NULL )
#define NSLDAPI_VALID_NONEMPTY_LDAPMOD_ARRAY( mods ) \
( (mods) != NULL && (mods)[0] != NULL )
#define NSLDAPI_IS_SEARCH_ENTRY( code ) \
((code) == LDAP_RES_SEARCH_ENTRY)
#define NSLDAPI_IS_SEARCH_RESULT( code ) \
((code) == LDAP_RES_SEARCH_RESULT)
#define NSLDAPI_SEARCH_RELATED_RESULT( code ) \
(NSLDAPI_IS_SEARCH_RESULT( code ) || NSLDAPI_IS_SEARCH_ENTRY( code ))
/*
* in bind.c
*/
char *nsldapi_get_binddn( LDAP *ld );
/*
* in cache.c
*/
void nsldapi_add_result_to_cache( LDAP *ld, LDAPMessage *result );
/*
* in dsparse.c
*/
int nsldapi_next_line_tokens( char **bufp, long *blenp, char ***toksp );
void nsldapi_free_strarray( char **sap );
/*
* in error.c
*/
int nsldapi_parse_result( LDAP *ld, int msgtype, BerElement *rber,
int *errcodep, char **matchednp, char **errmsgp, char ***referralsp,
LDAPControl ***serverctrlsp );
/*
* in open.c
*/
void nsldapi_initialize_defaults( void );
void nsldapi_mutex_alloc_all( LDAP *ld );
void nsldapi_mutex_free_all( LDAP *ld );
int nsldapi_open_ldap_defconn( LDAP *ld );
char *nsldapi_strdup( const char *s ); /* if s is NULL, returns NULL */
/*
* in os-ip.c
*/
int nsldapi_connect_to_host( LDAP *ld, Sockbuf *sb, const char *host,
int port, int secure, char **krbinstancep );
void nsldapi_close_connection( LDAP *ld, Sockbuf *sb );
int nsldapi_iostatus_poll( LDAP *ld, struct timeval *timeout );
void nsldapi_iostatus_free( LDAP *ld );
int nsldapi_iostatus_interest_write( LDAP *ld, Sockbuf *sb );
int nsldapi_iostatus_interest_read( LDAP *ld, Sockbuf *sb );
int nsldapi_iostatus_interest_clear( LDAP *ld, Sockbuf *sb );
int nsldapi_iostatus_is_read_ready( LDAP *ld, Sockbuf *sb );
int nsldapi_iostatus_is_write_ready( LDAP *ld, Sockbuf *sb );
int nsldapi_install_lber_extiofns( LDAP *ld, Sockbuf *sb );
int nsldapi_install_compat_io_fns( LDAP *ld, struct ldap_io_fns *iofns );
/*
* if referral.c
*/
int nsldapi_parse_reference( LDAP *ld, BerElement *rber, char ***referralsp,
LDAPControl ***serverctrlsp );
/*
* in result.c
*/
int ldap_msgdelete( LDAP *ld, int msgid );
int nsldapi_result_nolock( LDAP *ld, int msgid, int all, int unlock_permitted,
struct timeval *timeout, LDAPMessage **result );
int nsldapi_wait_result( LDAP *ld, int msgid, int all, struct timeval *timeout,
LDAPMessage **result );
int nsldapi_post_result( LDAP *ld, int msgid, LDAPMessage *result );
/*
* in request.c
*/
int nsldapi_send_initial_request( LDAP *ld, int msgid, unsigned long msgtype,
char *dn, BerElement *ber );
int nsldapi_send_pending_requests_nolock( LDAP *ld, LDAPConn *lc );
int nsldapi_alloc_ber_with_options( LDAP *ld, BerElement **berp );
void nsldapi_set_ber_options( LDAP *ld, BerElement *ber );
int nsldapi_send_ber_message( LDAP *ld, Sockbuf *sb, BerElement *ber,
int freeit, int epipe_handler );
int nsldapi_send_server_request( LDAP *ld, BerElement *ber, int msgid,
LDAPRequest *parentreq, LDAPServer *srvlist, LDAPConn *lc,
char *bindreqdn, int bind );
LDAPConn *nsldapi_new_connection( LDAP *ld, LDAPServer **srvlistp, int use_ldsb,
int connect, int bind );
LDAPRequest *nsldapi_find_request_by_msgid( LDAP *ld, int msgid );
LDAPRequest *nsldapi_new_request( LDAPConn *lc, BerElement *ber, int msgid,
int expect_resp );
void nsldapi_free_request( LDAP *ld, LDAPRequest *lr, int free_conn );
void nsldapi_queue_request_nolock( LDAP *ld, LDAPRequest *lr );
void nsldapi_free_connection( LDAP *ld, LDAPConn *lc,
LDAPControl **serverctrls, LDAPControl **clientctrls,
int force, int unbind );
void nsldapi_dump_connection( LDAP *ld, LDAPConn *lconns, int all );
void nsldapi_dump_requests_and_responses( LDAP *ld );
int nsldapi_chase_v2_referrals( LDAP *ld, LDAPRequest *lr, char **errstrp,
int *totalcountp, int *chasingcountp );
int nsldapi_chase_v3_refs( LDAP *ld, LDAPRequest *lr, char **refs,
int is_reference, int *totalcountp, int *chasingcountp );
int nsldapi_append_referral( LDAP *ld, char **referralsp, char *s );
void nsldapi_connection_lost_nolock( LDAP *ld, Sockbuf *sb );
#ifdef LDAP_SASLIO_HOOKS
/*
* in saslbind.c
*/
int nsldapi_sasl_is_inited();
int nsldapi_sasl_cvterrno( LDAP *ld, int err, char *msg );
int nsldapi_sasl_secprops( const char *in,
sasl_security_properties_t *secprops );
/*
* in saslio.c
*/
int nsldapi_sasl_install( LDAP *ld, LDAPConn *lconn );
int nsldapi_sasl_open( LDAP *ld, LDAPConn *lconn, sasl_conn_t **ctx, sasl_ssf_t ssf );
#endif /* LDAP_SASLIO_HOOKS */
/*
* in search.c
*/
int nsldapi_build_search_req( LDAP *ld, const char *base, int scope,
const char *filter, char **attrs, int attrsonly,
LDAPControl **serverctrls, LDAPControl **clientctrls,
int timelimit, int sizelimit, int msgid, BerElement **berp );
/*
* in unbind.c
*/
int ldap_ld_free( LDAP *ld, LDAPControl **serverctrls,
LDAPControl **clientctrls, int close );
int nsldapi_send_unbind( LDAP *ld, Sockbuf *sb, LDAPControl **serverctrls,
LDAPControl **clientctrls );
#ifdef LDAP_DNS
/*
* in getdxbyname.c
*/
char **nsldapi_getdxbyname( char *domain );
#endif /* LDAP_DNS */
/*
* in unescape.c
*/
void nsldapi_hex_unescape( char *s );
/*
* in compat.c
*/
#ifdef hpux
char *nsldapi_compat_ctime_r( const time_t *clock, char *buf, int buflen );
struct hostent *nsldapi_compat_gethostbyname_r( const char *name,
struct hostent *result, char *buffer, int buflen, int *h_errnop );
#endif /* hpux */
/*
* in control.c
*/
int nsldapi_put_controls( LDAP *ld, LDAPControl **ctrls, int closeseq,
BerElement *ber );
int nsldapi_get_controls( BerElement *ber, LDAPControl ***controlsp );
int nsldapi_find_controls( BerElement *ber, LDAPControl ***controlsp );
int nsldapi_dup_controls( LDAP *ld, LDAPControl ***ldctrls,
LDAPControl **newctrls );
int nsldapi_build_control( char *oid, BerElement *ber, int freeber,
char iscritical, LDAPControl **ctrlp );
/*
* in url.c
*/
int nsldapi_url_parse( const char *inurl, LDAPURLDesc **ludpp,
int dn_required );
/*
* in charset.c
*
* If we ever want to expose character set translation functionality to
* users of libldap, all of these prototypes will need to be moved to ldap.h
*/
#ifdef STR_TRANSLATION
void ldap_set_string_translators( LDAP *ld,
BERTranslateProc encode_proc, BERTranslateProc decode_proc );
int ldap_translate_from_t61( LDAP *ld, char **bufp,
unsigned long *lenp, int free_input );
int ldap_translate_to_t61( LDAP *ld, char **bufp,
unsigned long *lenp, int free_input );
void ldap_enable_translation( LDAP *ld, LDAPMessage *entry,
int enable );
#ifdef LDAP_CHARSET_8859
int ldap_t61_to_8859( char **bufp, unsigned long *buflenp,
int free_input );
int ldap_8859_to_t61( char **bufp, unsigned long *buflenp,
int free_input );
#endif /* LDAP_CHARSET_8859 */
#endif /* STR_TRANSLATION */
/*
* in memcache.h
*/
int ldap_memcache_createkey( LDAP *ld, const char *base, int scope,
const char *filter, char **attrs, int attrsonly,
LDAPControl **serverctrls, LDAPControl **clientctrls,
unsigned long *keyp );
int ldap_memcache_result( LDAP *ld, int msgid, unsigned long key );
int ldap_memcache_new( LDAP *ld, int msgid, unsigned long key,
const char *basedn );
int ldap_memcache_append( LDAP *ld, int msgid, int bLast, LDAPMessage *result );
int ldap_memcache_abandon( LDAP *ld, int msgid );
/*
* in sbind.c
*/
void nsldapi_handle_reconnect( LDAP *ld );
#endif /* _LDAPINT_H */

View file

@ -0,0 +1,352 @@
;
; ***** BEGIN LICENSE BLOCK *****
; Version: MPL 1.1/GPL 2.0/LGPL 2.
;
; The contents of this file are subject to the Mozilla Public License Version
; 1.1 (the "License"); you may not use this file except in compliance with
; the License. You may obtain a copy of the License at
; http://www.mozilla.org/MPL/
;
; Software distributed under the License is distributed on an "AS IS" basis,
; WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
; for the specific language governing rights and limitations under the
; License.
;
; The Original Code is Mozilla Communicator client code.
;
; The Initial Developer of the Original Code is
; Netscape Communications Corporation.
; Portions created by the Initial Developer are Copyright (C) 1996-1999
; the Initial Developer. All Rights Reserved.
;
; Contributor(s):
;
; Alternatively, the contents of this file may be used under the terms of
; either of the GNU General Public License Version 2 or later (the "GPL"),
; or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
; in which case the provisions of the GPL or the LGPL are applicable instead
; of those above. If you wish to allow use of your version of this file only
; under the terms of either the GPL or the LGPL, and not to allow others to
; use your version of this file under the terms of the MPL, indicate your
; decision by deleting the provisions above and replace them with the notice
; and other provisions required by the GPL or the LGPL. If you do not delete
; the provisions above, a recipient may use your version of this file under
; the terms of any one of the MPL, the GPL or the LGPL.
;
; ***** END LICENSE BLOCK *****
LIBRARY LDAP60
VERSION 6.0
HEAPSIZE 4096
EXPORTS
; exports list (generated by genexports.pl)
;
ldap_abandon
ldap_add
ldap_unbind
; ldap_enable_cache
; ldap_disable_cache
; ldap_destroy_cache
; ldap_flush_cache
; ldap_uncache_entry
ldap_compare
ldap_delete
ldap_result2error
ldap_err2string
ldap_modify
ldap_modrdn
ldap_open
ldap_first_entry
ldap_next_entry
ldap_get_dn
ldap_dn2ufn
ldap_first_attribute
ldap_next_attribute
ldap_get_values
ldap_get_values_len
ldap_count_entries
ldap_count_values
ldap_value_free
ldap_explode_dn
ldap_result
ldap_msgfree
ldap_search
ldap_add_s
ldap_bind_s
ldap_unbind_s
ldap_delete_s
ldap_modify_s
ldap_modrdn_s
ldap_search_s
ldap_search_st
ldap_compare_s
ldap_ufn_search_c
ldap_ufn_search_s
ldap_init_getfilter
ldap_getfilter_free
ldap_getfirstfilter
ldap_getnextfilter
ldap_simple_bind
ldap_simple_bind_s
ldap_bind
ldap_friendly_name
ldap_free_friendlymap
ldap_ufn_search_ct
; ldap_set_cache_options
; ldap_uncache_request
ldap_modrdn2
ldap_modrdn2_s
ldap_ufn_setfilter
ldap_ufn_setprefix
ldap_ufn_timeout
ldap_init_getfilter_buf
ldap_setfilteraffixes
ldap_sort_entries
ldap_sort_values
ldap_sort_strcasecmp
ldap_count_values_len
ldap_name2template
ldap_value_free_len
; manually comment and uncomment these five as necessary
; ldap_kerberos_bind1
; ldap_kerberos_bind2
; ldap_kerberos_bind_s
; ldap_kerberos_bind1_s
; ldap_kerberos_bind2_s
ldap_init
ldap_is_dns_dn
ldap_explode_dns
ldap_mods_free
ldap_is_ldap_url
ldap_free_urldesc
ldap_url_parse
ldap_url_search
ldap_url_search_s
ldap_url_search_st
ldap_set_rebind_proc
ber_skip_tag
ber_peek_tag
ber_get_int
ber_get_stringb
ber_get_stringa
ber_get_stringal
ber_get_bitstringa
ber_get_null
ber_get_boolean
ber_first_element
ber_next_element
ber_scanf
ber_bvfree
ber_bvecfree
ber_put_int
ber_put_ostring
ber_put_string
ber_put_bitstring
ber_put_null
ber_put_boolean
ber_start_seq
ber_start_set
ber_put_seq
ber_put_set
ber_printf
ber_read
ber_write
ber_free
ber_flush
ber_alloc
ber_dup
ber_get_next
ber_get_tag
ber_put_enum
der_alloc
ber_alloc_t
ber_bvdup
ber_init_w_nullchar
ber_reset
ber_get_option
ber_set_option
ber_sockbuf_alloc
ber_sockbuf_get_option
ber_sockbuf_set_option
ber_init
ber_flatten
ber_special_alloc
ber_special_free
ber_get_next_buffer
ber_err_print
ber_sockbuf_free
ber_get_next_buffer_ext
ber_svecfree
ber_get_buf_datalen
ber_get_buf_databegin
ber_stack_init
ber_sockbuf_free_data
ldap_memfree
ldap_ber_free
ldap_init_searchprefs
ldap_init_searchprefs_buf
ldap_free_searchprefs
ldap_first_searchobj
ldap_next_searchobj
ldap_build_filter
ldap_init_templates
ldap_init_templates_buf
ldap_free_templates
ldap_first_disptmpl
ldap_next_disptmpl
ldap_oc2template
ldap_tmplattrs
ldap_first_tmplrow
ldap_next_tmplrow
ldap_first_tmplcol
ldap_next_tmplcol
ldap_entry2text_search
ldap_entry2text
ldap_vals2text
ldap_entry2html
ldap_entry2html_search
ldap_vals2html
ldap_tmplerr2string
ldap_set_option
ldap_get_option
ldap_charray_merge
ldap_get_lderrno
ldap_set_lderrno
ldap_perror
ldap_set_filter_additions
ldap_create_filter
ldap_version
ldap_multisort_entries
ldap_msgid
ldap_explode_rdn
ldap_msgtype
ldap_cache_flush
ldap_str2charray
ldap_charray_add
ldap_charray_dup
ldap_charray_free
; Windows ordinals 450-469 are reserved for SSL routines
ldap_charray_inlist
ldap_charray_position
ldap_rename
ldap_rename_s
ldap_utf8len
ldap_utf8next
ldap_utf8prev
ldap_utf8copy
ldap_utf8characters
ldap_utf8strtok_r
ldap_utf8isalnum
ldap_utf8isalpha
ldap_utf8isdigit
ldap_utf8isxdigit
ldap_utf8isspace
ldap_control_free
ldap_controls_free
ldap_sasl_bind
ldap_sasl_bind_s
ldap_parse_sasl_bind_result
ldap_sasl_interactive_bind_s
ldap_sasl_interactive_bind_ext_s
; LDAPv3 simple paging controls are not supported by Netscape at this time.
; 490 ldap_create_page_control
; 491 ldap_parse_page_control
ldap_create_sort_control
ldap_parse_sort_control
; an LDAPv3 language control was proposed but then retracted.
; 494 ldap_create_language_control
ldap_get_lang_values
ldap_get_lang_values_len
ldap_free_sort_keylist
ldap_create_sort_keylist
ldap_utf8getcc
ldap_get_entry_controls
ldap_create_persistentsearch_control
ldap_parse_entrychange_control
ldap_parse_result
ldap_parse_extended_result
ldap_parse_reference
ldap_abandon_ext
ldap_add_ext
ldap_add_ext_s
ldap_modify_ext
ldap_modify_ext_s
ldap_first_message
ldap_next_message
ldap_compare_ext
ldap_compare_ext_s
ldap_delete_ext
ldap_delete_ext_s
ldap_search_ext
ldap_search_ext_s
ldap_extended_operation
ldap_extended_operation_s
ldap_first_reference
ldap_next_reference
ldap_count_references
ldap_count_messages
ldap_create_virtuallist_control
ldap_parse_virtuallist_control
ldap_create_proxyauth_control
ldap_unbind_ext
ldap_x_hostlist_first
ldap_x_hostlist_next
ldap_x_hostlist_statusfree
ldap_x_malloc
ldap_x_calloc
ldap_x_realloc
ldap_x_free
;
ldap_create_proxiedauth_control
;
ldap_create_geteffectiveRights_control
;
ldap_find_control
;
ldap_url_parse_no_defaults
;
ldap_create_userstatus_control
ldap_parse_userstatus_control
;
ldap_create_passwordpolicy_control
ldap_create_passwordpolicy_control_ext
ldap_parse_passwordpolicy_control
ldap_parse_passwordpolicy_control_ext
ldap_passwordpolicy_err2txt
;
ldap_passwd
ldap_parse_passwd
ldap_passwd_s
;
ldap_delete_result_entry
ldap_add_result_entry
;
ldap_whoami
ldap_parse_whoami
ldap_whoami_s
;
ldap_create_authzid_control
ldap_parse_authzid_control
;
ldap_memcache_init
ldap_memcache_set
ldap_memcache_get
ldap_memcache_flush
ldap_memcache_destroy
ldap_memcache_update
ldap_keysort_entries
;
; end of generated exports list.

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,105 @@
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is Mozilla Communicator client code, released
* March 31, 1998.
*
* The Initial Developer of the Original Code is
* Netscape Communications Corporation.
* Portions created by the Initial Developer are Copyright (C) 1998-1999
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
*
* Alternatively, the contents of this file may be used under the terms of
* either of the GNU General Public License Version 2 or later (the "GPL"),
* or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
#include "ldap-int.h"
int
LDAP_CALL
ldap_msgid( LDAPMessage *lm )
{
if ( !NSLDAPI_VALID_LDAPMESSAGE_POINTER( lm )) {
return( -1 );
}
return( lm->lm_msgid );
}
int
LDAP_CALL
ldap_msgtype( LDAPMessage *lm )
{
if ( !NSLDAPI_VALID_LDAPMESSAGE_POINTER( lm )) {
return( -1 );
}
return( lm->lm_msgtype );
}
LDAPMessage *
LDAP_CALL
ldap_first_message( LDAP *ld, LDAPMessage *chain )
{
if ( !NSLDAPI_VALID_LDAP_POINTER( ld )) {
return( NULLMSG ); /* punt */
}
return( chain );
}
LDAPMessage *
LDAP_CALL
ldap_next_message( LDAP *ld, LDAPMessage *msg )
{
if ( !NSLDAPI_VALID_LDAP_POINTER( ld )) {
return( NULLMSG ); /* punt */
}
if ( msg == NULLMSG || msg->lm_chain == NULLMSG ) {
return( NULLMSG );
}
return( msg->lm_chain );
}
int
LDAP_CALL
ldap_count_messages( LDAP *ld, LDAPMessage *chain )
{
int i;
if ( !NSLDAPI_VALID_LDAP_POINTER( ld )) {
return( -1 );
}
for ( i = 0; chain != NULL; chain = chain->lm_chain ) {
i++;
}
return( i );
}

View file

@ -0,0 +1,226 @@
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is Mozilla Communicator client code, released
* March 31, 1998.
*
* The Initial Developer of the Original Code is
* Netscape Communications Corporation.
* Portions created by the Initial Developer are Copyright (C) 1998-1999
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
*
* Alternatively, the contents of this file may be used under the terms of
* either of the GNU General Public License Version 2 or later (the "GPL"),
* or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
/*
* Copyright (c) 1990 Regents of the University of Michigan.
* All rights reserved.
*/
/*
* modify.c
*/
#if 0
#ifndef lint
static char copyright[] = "@(#) Copyright (c) 1990 Regents of the University of Michigan.\nAll rights reserved.\n";
#endif
#endif
#include "ldap-int.h"
/*
* ldap_modify - initiate an ldap modify operation. Parameters:
*
* ld LDAP descriptor
* dn DN of the object to modify
* mods List of modifications to make. This is null-terminated
* array of struct ldapmod's, specifying the modifications
* to perform.
*
* Example:
* LDAPMod *mods[] = {
* { LDAP_MOD_ADD, "cn", { "babs jensen", "babs", 0 } },
* { LDAP_MOD_REPLACE, "sn", { "jensen", 0 } },
* 0
* }
* msgid = ldap_modify( ld, dn, mods );
*/
int
LDAP_CALL
ldap_modify( LDAP *ld, const char *dn, LDAPMod **mods )
{
int msgid;
LDAPDebug( LDAP_DEBUG_TRACE, "ldap_modify\n", 0, 0, 0 );
if ( ldap_modify_ext( ld, dn, mods, NULL, NULL, &msgid )
== LDAP_SUCCESS ) {
return( msgid );
} else {
return( -1 ); /* error is in ld handle */
}
}
int
LDAP_CALL
ldap_modify_ext( LDAP *ld, const char *dn, LDAPMod **mods,
LDAPControl **serverctrls, LDAPControl **clientctrls, int *msgidp )
{
BerElement *ber;
int i, rc, lderr;
/*
* A modify request looks like this:
* ModifyRequet ::= SEQUENCE {
* object DistinguishedName,
* modifications SEQUENCE OF SEQUENCE {
* operation ENUMERATED {
* add (0),
* delete (1),
* replace (2)
* },
* modification SEQUENCE {
* type AttributeType,
* values SET OF AttributeValue
* }
* }
* }
*/
LDAPDebug( LDAP_DEBUG_TRACE, "ldap_modify_ext\n", 0, 0, 0 );
if ( !NSLDAPI_VALID_LDAP_POINTER( ld )) {
return( LDAP_PARAM_ERROR );
}
if ( !NSLDAPI_VALID_LDAPMESSAGE_POINTER( msgidp ))
{
LDAP_SET_LDERRNO( ld, LDAP_PARAM_ERROR, NULL, NULL );
return( LDAP_PARAM_ERROR );
}
if ( !NSLDAPI_VALID_NONEMPTY_LDAPMOD_ARRAY( mods )) {
lderr = LDAP_PARAM_ERROR;
LDAP_SET_LDERRNO( ld, lderr, NULL, NULL );
return( lderr );
}
if ( dn == NULL ) {
dn = "";
}
LDAP_MUTEX_LOCK( ld, LDAP_MSGID_LOCK );
*msgidp = ++ld->ld_msgid;
LDAP_MUTEX_UNLOCK( ld, LDAP_MSGID_LOCK );
/* see if we should add to the cache */
if ( ld->ld_cache_on && ld->ld_cache_modify != NULL ) {
LDAP_MUTEX_LOCK( ld, LDAP_CACHE_LOCK );
if ( (rc = (ld->ld_cache_modify)( ld, *msgidp, LDAP_REQ_MODIFY,
dn, mods )) != 0 ) {
*msgidp = rc;
LDAP_MUTEX_LOCK( ld, LDAP_CACHE_LOCK );
return( LDAP_SUCCESS );
}
LDAP_MUTEX_UNLOCK( ld, LDAP_CACHE_LOCK );
}
/* create a message to send */
if (( lderr = nsldapi_alloc_ber_with_options( ld, &ber ))
!= LDAP_SUCCESS ) {
return( lderr );
}
if ( ber_printf( ber, "{it{s{", *msgidp, LDAP_REQ_MODIFY, dn )
== -1 ) {
lderr = LDAP_ENCODING_ERROR;
LDAP_SET_LDERRNO( ld, lderr, NULL, NULL );
ber_free( ber, 1 );
return( lderr );
}
/* for each modification to be performed... */
for ( i = 0; mods[i] != NULL; i++ ) {
if (( mods[i]->mod_op & LDAP_MOD_BVALUES) != 0 ) {
rc = ber_printf( ber, "{e{s[V]}}",
mods[i]->mod_op & ~LDAP_MOD_BVALUES,
mods[i]->mod_type, mods[i]->mod_bvalues );
} else {
rc = ber_printf( ber, "{e{s[v]}}", mods[i]->mod_op,
mods[i]->mod_type, mods[i]->mod_values );
}
if ( rc == -1 ) {
lderr = LDAP_ENCODING_ERROR;
LDAP_SET_LDERRNO( ld, lderr, NULL, NULL );
ber_free( ber, 1 );
return( lderr );
}
}
if ( ber_printf( ber, "}}" ) == -1 ) {
lderr = LDAP_ENCODING_ERROR;
LDAP_SET_LDERRNO( ld, lderr, NULL, NULL );
ber_free( ber, 1 );
return( lderr );
}
if (( lderr = nsldapi_put_controls( ld, serverctrls, 1, ber ))
!= LDAP_SUCCESS ) {
ber_free( ber, 1 );
return( lderr );
}
/* send the message */
rc = nsldapi_send_initial_request( ld, *msgidp, LDAP_REQ_MODIFY,
(char *)dn, ber );
*msgidp = rc;
return( rc < 0 ? LDAP_GET_LDERRNO( ld, NULL, NULL ) : LDAP_SUCCESS );
}
int
LDAP_CALL
ldap_modify_s( LDAP *ld, const char *dn, LDAPMod **mods )
{
return( ldap_modify_ext_s( ld, dn, mods, NULL, NULL ));
}
int
LDAP_CALL
ldap_modify_ext_s( LDAP *ld, const char *dn, LDAPMod **mods,
LDAPControl **serverctrls, LDAPControl **clientctrls )
{
int msgid, err;
LDAPMessage *res;
if (( err = ldap_modify_ext( ld, dn, mods, serverctrls, clientctrls,
&msgid )) != LDAP_SUCCESS ) {
return( err );
}
if ( ldap_result( ld, msgid, 1, (struct timeval *)NULL, &res ) == -1 ) {
return( LDAP_GET_LDERRNO( ld, NULL, NULL ) );
}
return( ldap_result2error( ld, res, 1 ) );
}

View file

@ -0,0 +1,88 @@
# vim: set filetype=python:
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
include('/ldap/ldap-sdk.mozbuild')
SharedLibrary('ldap60')
SOURCES += [
'abandon.c',
'add.c',
'authzidctrl.c',
'bind.c',
'cache.c',
'charray.c',
'charset.c',
'compare.c',
'compat.c',
'control.c',
'countvalues.c',
'delete.c',
'disptmpl.c',
'dsparse.c',
'error.c',
'extendop.c',
'free.c',
'freevalues.c',
'friendly.c',
'getattr.c',
'getdn.c',
'getdxbyname.c',
'geteffectiverightsctrl.c',
'getentry.c',
'getfilter.c',
'getoption.c',
'getvalues.c',
'memcache.c',
'message.c',
'modify.c',
'open.c',
'os-ip.c',
'proxyauthctrl.c',
'psearch.c',
'pwmodext.c',
'pwpctrl.c',
'referral.c',
'regex.c',
'rename.c',
'request.c',
'reslist.c',
'result.c',
'saslbind.c',
'sbind.c',
'search.c',
'setoption.c',
'sort.c',
'sortctrl.c',
'srchpref.c',
'tmplout.c',
'ufn.c',
'unbind.c',
'unescape.c',
'url.c',
'userstatusctrl.c',
'utf8.c',
'vlistctrl.c',
'whoami.c',
]
if CONFIG['OS_TARGET'] == 'WINNT':
SOURCES += [
'dllmain.c',
'mozock.c',
]
DEFFILE = SRCDIR + '/libldap.def'
if CONFIG['OS_TARGET'] != 'WINNT':
DEFINES['USE_WAITPID'] = True
DEFINES['USE_PTHREADS'] = True
DEFINES['NEEDPROTOS'] = True
LOCAL_INCLUDES += [
'/ldap/c-sdk/include'
]
USE_LIBS += ['lber60']

View file

@ -0,0 +1,714 @@
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is Mozilla Communicator client code, released
* March 31, 1998.
*
* The Initial Developer of the Original Code is
* Netscape Communications Corporation.
* Portions created by the Initial Developer are Copyright (C) 1998-1999
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
*
* Alternatively, the contents of this file may be used under the terms of
* either of the GNU General Public License Version 2 or later (the "GPL"),
* or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
#ifdef _WINDOWS
#define FD_SETSIZE 30000
#endif
#include <windows.h>
#include <winsock.h>
#include <string.h>
// Purpose of this file is to implement an intermediate layer to our network
// services, the winsock.
// This intermediate layer will be able to function with and without a working
// winsock being present.
// The attempt to activate the winsock happens as would normally be expected,
// through the calling application's entry point to us, WSAStartup.
// Name of the winsock we would like to load.
// Diffs between OSs, Win32s is out in the cold if running 32 bits unless
// they also have a winsock name wsock32.dll.
#ifndef _WIN32
#define SZWINSOCK "winsock.dll"
#else
#define SZWINSOCK "wsock32.dll"
#endif
// Here is the enumeration for the winsock functions we have currently
// overridden (needed to run). Add more when needed.
// We use these to access proc addresses, and to hold a table of strings
// to obtain the proc addresses.
enum SockProc {
sp_WSAAsyncGetHostByName = 0,
sp_WSAAsyncSelect,
sp_WSACleanup,
sp_WSAGetLastError,
sp_WSASetLastError,
sp_WSAStartup,
sp___WSAFDIsSet,
sp_accept,
sp_bind,
sp_closesocket,
sp_connect,
sp_gethostbyname,
sp_gethostbyaddr,
sp_gethostname,
sp_getpeername,
sp_getsockname,
sp_getsockopt,
sp_getprotobyname,
sp_htonl,
sp_htons,
sp_inet_addr,
sp_ioctlsocket,
sp_listen,
sp_ntohl,
sp_ntohs,
sp_recv,
sp_select,
sp_send,
sp_setsockopt,
sp_shutdown,
sp_socket,
sp_inet_ntoa,
sp_MaxProcs // Total count.
};
// Array of function names used in GetProcAddress to fill in our
// proc array when needed.
// This array must match the enumerations exactly.
char *spName[(int)sp_MaxProcs] = {
"WSAAsyncGetHostByName",
"WSAAsyncSelect",
"WSACleanup",
"WSAGetLastError",
"WSASetLastError",
"WSAStartup",
"__WSAFDIsSet",
"accept",
"bind",
"closesocket",
"connect",
"gethostbyname",
"gethostbyaddr",
"gethostname",
"getpeername",
"getsockname",
"getsockopt",
"getprotobyname",
"htonl",
"htons",
"inet_addr",
"ioctlsocket",
"listen",
"ntohl",
"ntohs",
"recv",
"select",
"send",
"setsockopt",
"shutdown",
"socket",
"inet_ntoa"
};
// Array of proc addresses to the winsock functions.
// These can be NULL, indicating their absence (as in the case we couldn't
// load the winsock.dll or one of the functions wasn't loaded).
// The procs assigned in must corellate with the enumerations exactly.
FARPROC spArray[(int)sp_MaxProcs];
// Typedef all the different types of functions that we must cast the
// procs to in order to call without the compiler barfing.
// Prefix is always sp.
// Retval is next, spelled out.
// Parameters in their order are next, spelled out.
typedef int (PASCAL FAR *sp_int_WORD_LPWSADATA)(WORD, LPWSADATA);
typedef int (PASCAL FAR *sp_int_void)(void);
typedef HANDLE (PASCAL FAR *sp_HANDLE_HWND_uint_ccharFARp_charFARp_int)(HWND, unsigned int, const char FAR *, char FAR *, int);
typedef int (PASCAL FAR *sp_int_SOCKET_HWND_uint_long)(SOCKET, HWND, unsigned int, long);
typedef void (PASCAL FAR *sp_void_int)(int);
typedef int (PASCAL FAR *sp_int_SOCKET_fdsetFARp)(SOCKET, fd_set FAR *);
typedef SOCKET(PASCAL FAR *sp_SOCKET_SOCKET_sockaddrFARp_intFARp)(SOCKET, struct sockaddr FAR *, int FAR *);
typedef int (PASCAL FAR *sp_int_SOCKET_csockaddrFARp_int)(SOCKET, const struct sockaddr FAR *, int);
typedef int (PASCAL FAR *sp_int_SOCKET)(SOCKET);
typedef struct hostent FAR *(PASCAL FAR *sp_hostentFARp_ccharFARp)(const char FAR *);
typedef struct hostent FAR *(PASCAL FAR *sp_hostentFARp_ccharFARp_int_int)(const char FAR *, int, int);
typedef int (PASCAL FAR *sp_int_charFARp_int)(char FAR *, int);
typedef int (PASCAL FAR *sp_int_SOCKET_sockaddrFARp_intFARp)(SOCKET, struct sockaddr FAR *, int FAR *);
typedef int (PASCAL FAR *sp_int_SOCKET_int_int_charFARp_intFARp)(SOCKET, int, int, char FAR *, int FAR *);
typedef u_long (PASCAL FAR *sp_ulong_ulong)(u_long);
typedef u_short (PASCAL FAR *sp_ushort_ushort)(u_short);
typedef unsigned long (PASCAL FAR *sp_ulong_ccharFARp)(const char FAR *);
typedef int (PASCAL FAR *sp_int_SOCKET_long_ulongFARp)(SOCKET, long, u_long FAR *);
typedef int (PASCAL FAR *sp_int_SOCKET_int)(SOCKET, int);
typedef int (PASCAL FAR *sp_int_SOCKET_charFARp_int_int)(SOCKET, char FAR *, int, int);
typedef int (PASCAL FAR *sp_int_int_fdsetFARp_fdsetFARp_fdsetFARp_ctimevalFARp)(int,fd_set FAR *,fd_set FAR *,fd_set FAR *,const struct timeval FAR*);
typedef int (PASCAL FAR *sp_int_SOCKET_ccharFARp_int_int)(SOCKET, const char FAR *, int, int);
typedef int (PASCAL FAR *sp_int_SOCKET_int_int_ccharFARp_int)(SOCKET, int, int, const char FAR *, int);
typedef SOCKET (PASCAL FAR *sp_SOCKET_int_int_int)(int, int, int);
typedef char FAR * (PASCAL FAR *sp_charFARp_in_addr)(struct in_addr in);
typedef struct protoent FAR * (PASCAL FAR *sp_protoentFARcchar)(const char FAR *);
// Handle to the winsock, if loaded.
HINSTANCE hWinsock = NULL;
#ifndef _WIN32
// Last error code for the winsock.
int ispError = 0;
#endif
BOOL IsWinsockLoaded (int sp)
{
if (hWinsock == NULL)
{
WSADATA wsaData;
#ifdef _WIN32
static LONG sc_init = 0;
static DWORD sc_done = 0;
static CRITICAL_SECTION sc;
#endif
/* We need to wait here because another thread might be
in the routine already */
#ifdef _WIN32
if (0 == InterlockedExchange(&sc_init,1)) {
InitializeCriticalSection(&sc);
sc_done = 1;
}
while (0 == sc_done) Sleep(0);
EnterCriticalSection(&sc);
if (hWinsock == NULL) {
#endif
WSAStartup(0x0101, &wsaData);
#ifdef _WIN32
}
LeaveCriticalSection(&sc);
#endif
}
// Quick macro to tell if the winsock has actually loaded for a particular
// function.
// Debug version is a little more strict to make sure you get the names right.
#ifdef DEBUG
return hWinsock != NULL && spArray[(int)(sp)] != NULL;
#else // A little faster
return hWinsock != NULL;
#endif
}
// Here are the functions that we have taken over by not directly linking
// with the winsock import library or importing through the def file.
/* In win16 we simulate blocking commands as follows. Prior to issuing the
* command we make the socket not-blocking (WSAAsyncSelect does that).
* We then issue the command and see if it would have blocked. If so, we
* yield the processor and go to sleep until an event occurs that unblocks
* us (WSAAsyncSelect allowed us to register what that condition is). We
* keep repeating until we do not get a would-block indication when issuing
* the command. At that time we unregister the notification condition and
* return the result of the command to the caller.
*/
//#ifndef _WIN32
#if 0
#define NON_BLOCKING(command,condition,index,type) \
type iret; \
HWND hWndFrame = AfxGetApp()->m_pMainWnd->m_hWnd; \
while (TRUE) { \
if (WSAAsyncSelect(s, hWndFrame, msg_NetActivity, condition) \
== SOCKET_ERROR) { \
break; \
} \
if(IsWinsockLoaded(index)) { \
iret=command; \
if (!(iret==SOCKET_ERROR && WSAGetLastError()==WSAEWOULDBLOCK)) { \
WSAAsyncSelect(s, hWndFrame, msg_NetActivity, 0); \
return iret; \
} \
PR_Yield(); \
} else { \
break; \
} \
}
#else
#define NON_BLOCKING(command,condition,index,type) \
if(IsWinsockLoaded(index)) { \
return command; \
}
#endif
int PASCAL FAR WSAStartup(WORD wVersionRequested, LPWSADATA lpWSAData) {
// Our default return value is failure, though we change this regardless.
int iRetval = WSAVERNOTSUPPORTED;
HINSTANCE MyHandle;
// Before doing anything, clear out our proc array.
memset(spArray, 0, sizeof(spArray));
// attempt to load the real winsock.
MyHandle = LoadLibrary(SZWINSOCK);
#ifdef _WIN32
if(MyHandle != NULL) {
#else
if(MyHandle > HINSTANCE_ERROR) {
#endif
// Winsock was loaded.
// Get the proc addresses for each needed function next.
int spTraverse;
for(spTraverse = 0; spTraverse < (int)sp_MaxProcs; spTraverse++) {
spArray[spTraverse] = GetProcAddress(MyHandle, spName[spTraverse]);
if ( NULL == spArray[spTraverse] )
return iRetval;// Bad winsock? Bad function name?
}
hWinsock = MyHandle;
// AllRight, attempt to make our first proxied call.
if(IsWinsockLoaded(sp_WSAStartup)) {
iRetval = ((sp_int_WORD_LPWSADATA)spArray[sp_WSAStartup])(wVersionRequested, lpWSAData);
}
// If the return value is still an error at this point, we unload the DLL,
// so that we can act as though nothing happened and the user
// gets no network access.
if(iRetval != 0) {
// Clear out our proc array.
memset(spArray, 0, sizeof(spArray));
// Free up the winsock.
FreeLibrary(MyHandle);
MyHandle = NULL;
}
}
#ifndef _WIN32
else {
// Failed to load.
// Set this to NULL so it is clear.
hWinsock = NULL;
}
#endif
// Check our return value, if it isn't success, then we need to fake
// our own winsock implementation.
if(iRetval != 0) {
// We always return success.
iRetval = 0;
// Fill in the structure.
// Return the version requested as the version supported.
lpWSAData->wVersion = wVersionRequested;
lpWSAData->wHighVersion = wVersionRequested;
// Fill in a discription.
strcpy(lpWSAData->szDescription, "Mozock DLL internal implementation.");
strcpy(lpWSAData->szSystemStatus, "Winsock running, allowing no network access.");
// Report a nice round number for sockets and datagram sizes.
lpWSAData->iMaxSockets = 4096;
lpWSAData->iMaxUdpDg = 4096;
// No vendor information.
lpWSAData->lpVendorInfo = NULL;
}
return(iRetval);
}
int PASCAL FAR WSACleanup(void) {
int iRetval = 0;
// Handling normally or internally.
// When IsWinsockLoaded() is called and hWinsock is NULL, it winds up calling WSAStartup
// which wedges rpcrt4.dll on win95 with some winsock implementations. Bug: 81359.
if(hWinsock && IsWinsockLoaded(sp_WSACleanup)) {
// Call their cleanup routine.
// We could set the return value here, but it is meaning less.
// We always return success.
iRetval = ((sp_int_void)spArray[sp_WSACleanup])();
//ASSERT(iRetval == 0);
iRetval = 0;
}
// Wether or not it succeeded, we free off the library here.
// Clear out our proc table too.
memset(spArray, 0, sizeof(spArray));
if(hWinsock != NULL) {
FreeLibrary(hWinsock);
hWinsock = NULL;
}
return(iRetval);
}
HANDLE PASCAL FAR WSAAsyncGetHostByName(HWND hWnd, unsigned int wMsg, const char FAR *name, char FAR *buf, int buflen) {
// Normal or shim.
if(IsWinsockLoaded(sp_WSAAsyncGetHostByName)) {
return(((sp_HANDLE_HWND_uint_ccharFARp_charFARp_int)spArray[sp_WSAAsyncGetHostByName])(hWnd, wMsg, name, buf, buflen));
}
// Must return error here.
// Set our last error value to be that the net is down.
WSASetLastError(WSAENETDOWN);
return(NULL);
}
int PASCAL FAR WSAAsyncSelect(SOCKET s, HWND hWnd, unsigned int wMsg, long lEvent) {
// Normal or shim.
if(IsWinsockLoaded(sp_WSAAsyncSelect)) {
return(((sp_int_SOCKET_HWND_uint_long)spArray[sp_WSAAsyncSelect])(s, hWnd, wMsg, lEvent));
}
// Must return error here.
WSASetLastError(WSAENETDOWN);
return(SOCKET_ERROR);
}
int PASCAL FAR WSAGetLastError(void) {
// See if someone else can handle.
if(IsWinsockLoaded(sp_WSAGetLastError)) {
return(((sp_int_void)spArray[sp_WSAGetLastError])());
}
#ifndef _WIN32
{
// Fake it.
int iRetval = ispError;
ispError = 0;
return(iRetval);
}
#else
// Use default OS handler.
return(GetLastError());
#endif
}
void PASCAL FAR WSASetLastError(int iError) {
// See if someone else can handle.
if(IsWinsockLoaded(sp_WSASetLastError)) {
((sp_void_int)spArray[sp_WSASetLastError])(iError);
return;
}
#ifndef _WIN32
// Fake it.
ispError = iError;
return;
#else
// Use default OS handler.
SetLastError(iError);
return;
#endif
}
int PASCAL FAR __WSAFDIsSet(SOCKET fd, fd_set FAR *set) {
int i;
// See if someone else will handle.
if(IsWinsockLoaded(sp___WSAFDIsSet)) {
return(((sp_int_SOCKET_fdsetFARp)spArray[sp___WSAFDIsSet])(fd, set));
}
// Default implementation.
i = set->fd_count;
while (i--) {
if (set->fd_array[i] == fd) {
return 1;
}
}
return 0;
}
SOCKET PASCAL FAR accept(SOCKET s, struct sockaddr FAR *addr, int FAR *addrlen) {
// Internally or shim
NON_BLOCKING(
(((sp_SOCKET_SOCKET_sockaddrFARp_intFARp)spArray[sp_accept])(s, addr, addrlen)),
FD_ACCEPT, sp_accept, SOCKET);
// Fail.
WSASetLastError(WSAENETDOWN);
return(INVALID_SOCKET);
}
int PASCAL FAR bind(SOCKET s, const struct sockaddr FAR *name, int namelen) {
// Internally or shim
if(IsWinsockLoaded(sp_bind)) {
return(((sp_int_SOCKET_csockaddrFARp_int)spArray[sp_bind])(s, name, namelen));
}
// Fail.
WSASetLastError(WSAENETDOWN);
return(SOCKET_ERROR);
}
int PASCAL FAR closesocket(SOCKET s) {
// Internally or shim.
NON_BLOCKING(
(((sp_int_SOCKET)spArray[sp_closesocket])(s)),
FD_CLOSE, sp_closesocket, int);
// Error.
WSASetLastError(WSAENETDOWN);
return(SOCKET_ERROR);
}
int PASCAL FAR connect(SOCKET s, const struct sockaddr FAR *name, int namelen) {
// Internally or shim.
if(IsWinsockLoaded(sp_connect)) {
/* This could block and so it would seem that the NON_BLOCK
* macro should be used here. However it was causing a crash
* and so it was decided to allow blocking here instead
*/
return (((sp_int_SOCKET_csockaddrFARp_int)spArray[sp_connect])(s, name, namelen));
}
// Err.
WSASetLastError(WSAENETDOWN);
return(SOCKET_ERROR);
}
struct hostent FAR * PASCAL FAR gethostbyname(const char FAR *name) {
if(IsWinsockLoaded(sp_gethostbyname)) {
return(((sp_hostentFARp_ccharFARp)spArray[sp_gethostbyname])(name));
}
WSASetLastError(WSAENETDOWN);
return(NULL);
}
struct hostent FAR * PASCAL FAR gethostbyaddr(const char FAR *addr, int len, int type) {
if(IsWinsockLoaded(sp_gethostbyaddr)) {
return(((sp_hostentFARp_ccharFARp_int_int)spArray[sp_gethostbyaddr])(addr, len, type));
}
WSASetLastError(WSAENETDOWN);
return(NULL);
}
int PASCAL FAR gethostname(char FAR *name, int namelen) {
if(IsWinsockLoaded(sp_gethostname)) {
return(((sp_int_charFARp_int)spArray[sp_gethostname])(name, namelen));
}
WSASetLastError(WSAENETDOWN);
return(SOCKET_ERROR);
}
int PASCAL FAR getpeername(SOCKET s, struct sockaddr FAR *name, int FAR *namelen) {
if(IsWinsockLoaded(sp_getpeername)) {
return(((sp_int_SOCKET_sockaddrFARp_intFARp)spArray[sp_getpeername])(s, name, namelen));
}
WSASetLastError(WSAENETDOWN);
return(SOCKET_ERROR);
}
int PASCAL FAR getsockname(SOCKET s, struct sockaddr FAR *name, int FAR *namelen) {
if(IsWinsockLoaded(sp_getsockname)) {
return(((sp_int_SOCKET_sockaddrFARp_intFARp)spArray[sp_getsockname])(s, name, namelen));
}
WSASetLastError(WSAENETDOWN);
return(SOCKET_ERROR);
}
int PASCAL FAR getsockopt(SOCKET s, int level, int optname, char FAR *optval, int FAR *optlen) {
if(IsWinsockLoaded(sp_getsockopt)) {
return(((sp_int_SOCKET_int_int_charFARp_intFARp)spArray[sp_getsockopt])(s, level, optname, optval, optlen));
}
WSASetLastError(WSAENETDOWN);
return(SOCKET_ERROR);
}
struct protoent FAR * PASCAL getprotobyname(const char FAR * name) {
if(IsWinsockLoaded(sp_getprotobyname)) {
return(((sp_protoentFARcchar)spArray[sp_getprotobyname])(name));
}
WSASetLastError(WSAENETDOWN);
return NULL;
}
u_long PASCAL FAR htonl(u_long hostlong) {
if(IsWinsockLoaded(sp_htonl)) {
return(((sp_ulong_ulong)spArray[sp_htonl])(hostlong));
}
#ifndef _WIN32
return
(((hostlong&0xff)<<24) + ((hostlong&0xff00)<<8) +
((hostlong&0xff0000)>>8) + ((hostlong&0xff000000)>>24));
#else
// Just return what was passed in.
return(hostlong);
#endif
}
u_short PASCAL FAR htons(u_short hostshort) {
if(IsWinsockLoaded(sp_htons)) {
return(((sp_ushort_ushort)spArray[sp_htons])(hostshort));
}
#ifndef _WIN32
return (((hostshort&0xff)<<8) + ((hostshort&0xff00)>>8));
#else
// Just return what was passed in.
return(hostshort);
#endif
}
u_long PASCAL FAR ntohl(u_long hostlong) {
if(IsWinsockLoaded(sp_ntohl)) {
return(((sp_ulong_ulong)spArray[sp_ntohl])(hostlong));
}
#ifndef _WIN32
return
(((hostlong&0xff)<<24) + ((hostlong&0xff00)<<8) +
((hostlong&0xff0000)>>8) + ((hostlong&0xff000000)>>24));
#else
// Just return what was passed in.
return(hostlong);
#endif
}
u_short PASCAL FAR ntohs(u_short hostshort) {
if(IsWinsockLoaded(sp_ntohs)) {
return(((sp_ushort_ushort)spArray[sp_ntohs])(hostshort));
}
#ifndef _WIN32
return (((hostshort&0xff)<<8) + ((hostshort&0xff00)>>8));
#else
// Just return what was passed in.
return(hostshort);
#endif
}
unsigned long PASCAL FAR inet_addr(const char FAR *cp) {
if(IsWinsockLoaded(sp_inet_addr)) {
return(((sp_ulong_ccharFARp)spArray[sp_inet_addr])(cp));
}
return(INADDR_NONE);
}
int PASCAL FAR ioctlsocket(SOCKET s, long cmd, u_long FAR *argp) {
if(IsWinsockLoaded(sp_ioctlsocket)) {
return(((sp_int_SOCKET_long_ulongFARp)spArray[sp_ioctlsocket])(s, cmd, argp));
}
WSASetLastError(WSAENETDOWN);
return(SOCKET_ERROR);
}
int PASCAL FAR listen(SOCKET s, int backlog) {
if(IsWinsockLoaded(sp_listen)) {
return(((sp_int_SOCKET_int)spArray[sp_listen])(s, backlog));
}
WSASetLastError(WSAENETDOWN);
return(SOCKET_ERROR);
}
int PASCAL FAR recv(SOCKET s, char FAR *buf, int len, int flags) {
NON_BLOCKING(
(((sp_int_SOCKET_charFARp_int_int)spArray[sp_recv])(s, buf, len, flags)),
FD_READ, sp_recv, int);
WSASetLastError(WSAENETDOWN);
return(SOCKET_ERROR);
}
int PASCAL FAR select(int nfds, fd_set FAR *readfds, fd_set FAR *writefds, fd_set FAR *exceptfds, const struct timeval FAR *timeout) {
// If there's nothing to do, stop now before we go off into dll land.
// Optimization, boyz.
if((readfds && readfds->fd_count) || (writefds && writefds->fd_count) || (exceptfds && exceptfds->fd_count)) {
if(IsWinsockLoaded(sp_select)) {
return(((sp_int_int_fdsetFARp_fdsetFARp_fdsetFARp_ctimevalFARp)spArray[sp_select])(nfds,readfds,writefds,exceptfds,timeout));
}
WSASetLastError(WSAENETDOWN);
return(SOCKET_ERROR);
}
// No need to go to the DLL, there is nothing to do.
return(0);
}
int PASCAL FAR send(SOCKET s, const char FAR *buf, int len, int flags) {
NON_BLOCKING(
(((sp_int_SOCKET_ccharFARp_int_int)spArray[sp_send])(s, buf, len, flags)),
FD_WRITE, sp_send, int);
WSASetLastError(WSAENETDOWN);
return(SOCKET_ERROR);
}
int PASCAL FAR setsockopt(SOCKET s, int level, int optname, const char FAR *optval, int optlen) {
if(IsWinsockLoaded(sp_setsockopt)) {
return(((sp_int_SOCKET_int_int_ccharFARp_int)spArray[sp_setsockopt])(s, level, optname, optval, optlen));
}
WSASetLastError(WSAENETDOWN);
return(SOCKET_ERROR);
}
int PASCAL FAR shutdown(SOCKET s, int how) {
if(IsWinsockLoaded(sp_shutdown)) {
return(((sp_int_SOCKET_int)spArray[sp_shutdown])(s, how));
}
WSASetLastError(WSAENETDOWN);
return(SOCKET_ERROR);
}
SOCKET PASCAL FAR socket(int af, int type, int protocol) {
if(IsWinsockLoaded(sp_socket)) {
return(((sp_SOCKET_int_int_int)spArray[sp_socket])(af, type, protocol));
}
WSASetLastError(WSAENETDOWN);
return(INVALID_SOCKET);
}
char FAR * PASCAL FAR inet_ntoa(struct in_addr in) {
if(IsWinsockLoaded(sp_inet_ntoa)) {
return ((sp_charFARp_in_addr)spArray[sp_inet_ntoa])(in);
}
WSASetLastError(WSAENETDOWN);
return NULL;
}

View file

@ -0,0 +1,621 @@
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is Mozilla Communicator client code, released
* March 31, 1998.
*
* The Initial Developer of the Original Code is
* Netscape Communications Corporation.
* Portions created by the Initial Developer are Copyright (C) 1998-1999
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
*
* Alternatively, the contents of this file may be used under the terms of
* either of the GNU General Public License Version 2 or later (the "GPL"),
* or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
#include <nspr.h>
#include <stdio.h>
#include <ldap.h>
#define NAME "cn=Directory Manager"
#define PASSWORD "secret99"
#define BASE "dc=example,dc=com"
static int simplebind( LDAP *ld, char *msg, int tries );
static void search_thread( void * );
static void modify_thread( void * );
static void add_thread( void * );
static void delete_thread( void * );
static void set_ld_error();
static int get_ld_error();
static void set_errno();
static int get_errno();
static void tsd_setup();
static void *my_mutex_alloc( void );
static void my_mutex_free( void * );
static int my_mutex_lock( void * );
static int my_mutex_unlock( void * );
static LDAPHostEnt *my_gethostbyname( const char *name, LDAPHostEnt *result,
char *buffer, int buflen, int *statusp, void *extradata );
static LDAPHostEnt *my_gethostbyaddr( const char *addr, int length,
int type, LDAPHostEnt *result, char *buffer, int buflen,
int *statusp, void *extradata );
static LDAPHostEnt *copyPRHostEnt2LDAPHostEnt( LDAPHostEnt *ldhp,
PRHostEnt *prhp );
typedef struct ldapmsgwrapper {
LDAPMessage *lmw_messagep;
struct ldapmsgwrapper *lmw_next;
} ldapmsgwrapper;
#define CONNECTION_ERROR( lderr ) ( (lderr) == LDAP_SERVER_DOWN || \
(lderr) == LDAP_CONNECT_ERROR )
LDAP *ld;
PRUintn tsdindex;
#ifdef LDAP_MEMCACHE
LDAPMemCache *memcache = NULL;
#define MEMCACHE_SIZE (256*1024) /* 256K bytes */
#define MEMCACHE_TTL (15*60) /* 15 minutes */
#endif
main( int argc, char **argv )
{
PRThread *search_tid, *search_tid2, *search_tid3;
PRThread *search_tid4, *modify_tid, *add_tid;
PRThread *delete_tid;
struct ldap_thread_fns tfns;
struct ldap_dns_fns dnsfns;
int rc;
if ( argc != 3 ) {
fprintf( stderr, "usage: %s host port\n", argv[0] );
exit( 1 );
}
PR_Init( PR_USER_THREAD, PR_PRIORITY_NORMAL, 0 );
if ( PR_NewThreadPrivateIndex( &tsdindex, NULL ) != PR_SUCCESS ) {
perror( "PR_NewThreadPrivateIndex" );
exit( 1 );
}
tsd_setup(); /* for main thread */
if ( (ld = ldap_init( argv[1], atoi( argv[2] ) )) == NULL ) {
perror( "ldap_open" );
exit( 1 );
}
/* set thread function pointers */
memset( &tfns, '\0', sizeof(struct ldap_thread_fns) );
tfns.ltf_mutex_alloc = my_mutex_alloc;
tfns.ltf_mutex_free = my_mutex_free;
tfns.ltf_mutex_lock = my_mutex_lock;
tfns.ltf_mutex_unlock = my_mutex_unlock;
tfns.ltf_get_errno = get_errno;
tfns.ltf_set_errno = set_errno;
tfns.ltf_get_lderrno = get_ld_error;
tfns.ltf_set_lderrno = set_ld_error;
tfns.ltf_lderrno_arg = NULL;
if ( ldap_set_option( ld, LDAP_OPT_THREAD_FN_PTRS, (void *) &tfns )
!= 0 ) {
ldap_perror( ld, "ldap_set_option: thread functions" );
exit( 1 );
}
/* set DNS function pointers */
memset( &dnsfns, '\0', sizeof(struct ldap_dns_fns) );
dnsfns.lddnsfn_bufsize = PR_NETDB_BUF_SIZE;
dnsfns.lddnsfn_gethostbyname = my_gethostbyname;
dnsfns.lddnsfn_gethostbyaddr = my_gethostbyaddr;
if ( ldap_set_option( ld, LDAP_OPT_DNS_FN_PTRS, (void *)&dnsfns )
!= 0 ) {
ldap_perror( ld, "ldap_set_option: DNS functions" );
exit( 1 );
}
#ifdef LDAP_MEMCACHE
/* create the in-memory cache */
if (( rc = ldap_memcache_init( MEMCACHE_TTL, MEMCACHE_SIZE, NULL,
&tfns, &memcache )) != LDAP_SUCCESS ) {
fprintf( stderr, "ldap_memcache_init failed - %s\n",
ldap_err2string( rc ));
exit( 1 );
}
if (( rc = ldap_memcache_set( ld, memcache )) != LDAP_SUCCESS ) {
fprintf( stderr, "ldap_memcache_set failed - %s\n",
ldap_err2string( rc ));
exit( 1 );
}
#endif
/*
* set option so that the next call to ldap_simple_bind_s() after
* the server connection is lost will attempt to reconnect.
*/
if ( ldap_set_option( ld, LDAP_OPT_RECONNECT, LDAP_OPT_ON ) != 0 ) {
ldap_perror( ld, "ldap_set_option: reconnect" );
exit( 1 );
}
/* initial bind */
if ( simplebind( ld, "ldap_simple_bind_s/main", 1 ) != LDAP_SUCCESS ) {
exit( 1 );
}
/* create the operation threads */
if ( (search_tid = PR_CreateThread( PR_USER_THREAD, search_thread,
"1", PR_PRIORITY_NORMAL, PR_GLOBAL_THREAD, PR_UNJOINABLE_THREAD,
0 )) == NULL ) {
perror( "PR_CreateThread search_thread" );
exit( 1 );
}
if ( (modify_tid = PR_CreateThread( PR_USER_THREAD, modify_thread,
"2", PR_PRIORITY_NORMAL, PR_GLOBAL_THREAD, PR_UNJOINABLE_THREAD,
0 )) == NULL ) {
perror( "PR_CreateThread modify_thread" );
exit( 1 );
}
if ( (search_tid2 = PR_CreateThread( PR_USER_THREAD, search_thread,
"3", PR_PRIORITY_NORMAL, PR_GLOBAL_THREAD, PR_UNJOINABLE_THREAD,
0 )) == NULL ) {
perror( "PR_CreateThread search_thread 2" );
exit( 1 );
}
if ( (add_tid = PR_CreateThread( PR_USER_THREAD, add_thread,
"4", PR_PRIORITY_NORMAL, PR_GLOBAL_THREAD, PR_UNJOINABLE_THREAD,
0 )) == NULL ) {
perror( "PR_CreateThread add_thread" );
exit( 1 );
}
if ( (search_tid3 = PR_CreateThread( PR_USER_THREAD, search_thread,
"5", PR_PRIORITY_NORMAL, PR_GLOBAL_THREAD, PR_UNJOINABLE_THREAD,
0 )) == NULL ) {
perror( "PR_CreateThread search_thread 3" );
exit( 1 );
}
if ( (delete_tid = PR_CreateThread( PR_USER_THREAD, delete_thread,
"6", PR_PRIORITY_NORMAL, PR_GLOBAL_THREAD, PR_UNJOINABLE_THREAD,
0 )) == NULL ) {
perror( "PR_CreateThread delete_thread" );
exit( 1 );
}
if ( (search_tid4 = PR_CreateThread( PR_USER_THREAD, search_thread,
"7", PR_PRIORITY_NORMAL, PR_GLOBAL_THREAD, PR_UNJOINABLE_THREAD,
0 )) == NULL ) {
perror( "PR_CreateThread search_thread 4" );
exit( 1 );
}
PR_Cleanup();
return( 0 );
}
static int
simplebind( LDAP *ld, char *msg, int tries )
{
int rc;
while ( tries-- > 0 ) {
rc = ldap_simple_bind_s( ld, NAME, PASSWORD );
if ( rc != LDAP_SUCCESS ) {
ldap_perror( ld, msg );
}
if ( tries == 0 || !CONNECTION_ERROR( rc )) {
return( rc );
}
fprintf( stderr,
"%s: sleeping for 5 secs - will try %d more time(s)...\n",
msg, tries );
sleep( 5 );
}
return( rc );
}
static void
search_thread( void *arg1 )
{
LDAPMessage *res;
LDAPMessage *e;
char *a;
char **v;
char *dn;
BerElement *ber;
int i, rc, msgid;
void *tsd;
char *id = arg1;
printf( "search_thread\n" );
tsd_setup();
for ( ;; ) {
printf( "%sSearching...\n", id );
if ( (msgid = ldap_search( ld, BASE, LDAP_SCOPE_SUBTREE,
"(objectclass=*)", NULL, 0 )) == -1 ) {
ldap_perror( ld, "ldap_search_s" );
rc = ldap_get_lderrno( ld, NULL, NULL );
if ( CONNECTION_ERROR( rc ) && simplebind( ld,
"bind-search_thread", 5 ) != LDAP_SUCCESS ) {
return;
}
continue;
}
while ( (rc = ldap_result( ld, msgid, 0, NULL, &res ))
== LDAP_RES_SEARCH_ENTRY ) {
for ( e = ldap_first_entry( ld, res ); e != NULL;
e = ldap_next_entry( ld, e ) ) {
dn = ldap_get_dn( ld, e );
/* printf( "%sdn: %s\n", id, dn ); */
free( dn );
for ( a = ldap_first_attribute( ld, e, &ber );
a != NULL; a = ldap_next_attribute( ld, e,
ber ) ) {
v = ldap_get_values( ld, e, a );
for ( i = 0; v && v[i] != 0; i++ ) {
/*
printf( "%s%s: %s\n", id, a,
v[i] );
*/
}
ldap_value_free( v );
ldap_memfree( a );
}
if ( ber != NULL ) {
ber_free( ber, 0 );
}
}
ldap_msgfree( res );
/* printf( "%s\n", id ); */
}
if ( rc == -1 || ldap_result2error( ld, res, 0 ) !=
LDAP_SUCCESS ) {
ldap_perror( ld, "ldap_search" );
} else {
printf( "%sDone with one round\n", id );
}
if ( rc == -1 ) {
rc = ldap_get_lderrno( ld, NULL, NULL );
if ( CONNECTION_ERROR( rc ) && simplebind( ld,
"bind-search_thread", 5 ) != LDAP_SUCCESS ) {
return;
}
}
}
}
static void
modify_thread( void *arg1 )
{
LDAPMessage *res;
LDAPMessage *e;
int i, modentry, entries, msgid, rc;
LDAPMod mod;
LDAPMod *mods[2];
char *vals[2];
char *dn;
char *id = arg1;
ldapmsgwrapper *list, *lmwp, *lastlmwp;
printf( "modify_thread\n" );
tsd_setup();
if ( (msgid = ldap_search( ld, BASE, LDAP_SCOPE_SUBTREE,
"(objectclass=*)", NULL, 0 )) == -1 ) {
ldap_perror( ld, "ldap_search_s" );
exit( 1 );
}
entries = 0;
list = lastlmwp = NULL;
while ( (rc = ldap_result( ld, msgid, 0, NULL, &res ))
== LDAP_RES_SEARCH_ENTRY ) {
entries++;
if (( lmwp = (ldapmsgwrapper *)
malloc( sizeof( ldapmsgwrapper ))) == NULL ) {
perror( "modify_thread: malloc" );
exit( 1 );
}
lmwp->lmw_messagep = res;
lmwp->lmw_next = NULL;
if ( lastlmwp == NULL ) {
list = lastlmwp = lmwp;
} else {
lastlmwp->lmw_next = lmwp;
}
lastlmwp = lmwp;
}
if ( rc == -1 || ldap_result2error( ld, res, 0 ) != LDAP_SUCCESS ) {
ldap_perror( ld, "modify_thread: ldap_search" );
exit( 1 );
} else {
entries++;
printf( "%sModify got %d entries\n", id, entries );
}
mods[0] = &mod;
mods[1] = NULL;
vals[0] = "bar";
vals[1] = NULL;
for ( ;; ) {
modentry = rand() % entries;
for ( i = 0, lmwp = list; lmwp != NULL && i < modentry;
i++, lmwp = lmwp->lmw_next ) {
/* NULL */
}
if ( lmwp == NULL ) {
fprintf( stderr,
"%sModify could not find entry %d of %d\n",
id, modentry, entries );
continue;
}
e = lmwp->lmw_messagep;
printf( "%sPicked entry %d of %d\n", id, i, entries );
dn = ldap_get_dn( ld, e );
mod.mod_op = LDAP_MOD_REPLACE;
mod.mod_type = "description";
mod.mod_values = vals;
printf( "%sModifying (%s)\n", id, dn );
if (( rc = ldap_modify_s( ld, dn, mods )) != LDAP_SUCCESS ) {
ldap_perror( ld, "ldap_modify_s" );
if ( CONNECTION_ERROR( rc ) && simplebind( ld,
"bind-modify_thread", 5 ) != LDAP_SUCCESS ) {
return;
}
}
free( dn );
}
}
static void
add_thread( void *arg1 )
{
LDAPMod mod[5];
LDAPMod *mods[6];
char dn[BUFSIZ], name[40];
char *cnvals[2], *snvals[2], *ocvals[2];
int i, rc;
char *id = arg1;
printf( "add_thread\n" );
tsd_setup();
for ( i = 0; i < 5; i++ ) {
mods[i] = &mod[i];
}
mods[5] = NULL;
mod[0].mod_op = 0;
mod[0].mod_type = "cn";
mod[0].mod_values = cnvals;
cnvals[1] = NULL;
mod[1].mod_op = 0;
mod[1].mod_type = "sn";
mod[1].mod_values = snvals;
snvals[1] = NULL;
mod[2].mod_op = 0;
mod[2].mod_type = "objectclass";
mod[2].mod_values = ocvals;
ocvals[0] = "person";
ocvals[1] = NULL;
mods[3] = NULL;
for ( ;; ) {
sprintf( name, "%d", rand() );
sprintf( dn, "cn=%s, " BASE, name );
cnvals[0] = name;
snvals[0] = name;
printf( "%sAdding entry (%s)\n", id, dn );
if (( rc = ldap_add_s( ld, dn, mods )) != LDAP_SUCCESS ) {
ldap_perror( ld, "ldap_add_s" );
if ( CONNECTION_ERROR( rc ) && simplebind( ld,
"bind-add_thread", 5 ) != LDAP_SUCCESS ) {
return;
}
}
}
}
static void
delete_thread( void *arg1 )
{
LDAPMessage *res;
char dn[BUFSIZ], name[40];
int entries, msgid, rc;
char *id = arg1;
printf( "delete_thread\n" );
tsd_setup();
if ( (msgid = ldap_search( ld, BASE, LDAP_SCOPE_SUBTREE,
"(objectclass=*)", NULL, 0 )) == -1 ) {
ldap_perror( ld, "delete_thread: ldap_search_s" );
exit( 1 );
}
entries = 0;
while ( (rc = ldap_result( ld, msgid, 0, NULL, &res ))
== LDAP_RES_SEARCH_ENTRY ) {
entries++;
ldap_msgfree( res );
}
entries++;
if ( rc == -1 || ldap_result2error( ld, res, 1 ) != LDAP_SUCCESS ) {
ldap_perror( ld, "delete_thread: ldap_search" );
} else {
printf( "%sDelete got %d entries\n", id, entries );
}
for ( ;; ) {
sprintf( name, "%d", rand() );
sprintf( dn, "cn=%s, " BASE, name );
printf( "%sDeleting entry (%s)\n", id, dn );
if (( rc = ldap_delete_s( ld, dn )) != LDAP_SUCCESS ) {
ldap_perror( ld, "ldap_delete_s" );
if ( CONNECTION_ERROR( rc ) && simplebind( ld,
"bind-delete_thread", 5 ) != LDAP_SUCCESS ) {
return;
}
}
}
}
struct ldap_error {
int le_errno;
char *le_matched;
char *le_errmsg;
};
static void
tsd_setup()
{
void *tsd;
tsd = (void *) PR_GetThreadPrivate( tsdindex );
if ( tsd != NULL ) {
fprintf( stderr, "tsd non-null!\n" );
exit( 1 );
}
tsd = (void *) calloc( 1, sizeof(struct ldap_error) );
if ( PR_SetThreadPrivate( tsdindex, tsd ) != 0 ) {
perror( "PR_SetThreadPrivate" );
exit( 1 );
}
}
static void
set_ld_error( int err, char *matched, char *errmsg, void *dummy )
{
struct ldap_error *le;
le = (void *) PR_GetThreadPrivate( tsdindex );
le->le_errno = err;
if ( le->le_matched != NULL ) {
ldap_memfree( le->le_matched );
}
le->le_matched = matched;
if ( le->le_errmsg != NULL ) {
ldap_memfree( le->le_errmsg );
}
le->le_errmsg = errmsg;
}
static int
get_ld_error( char **matchedp, char **errmsgp, void *dummy )
{
struct ldap_error *le;
le = PR_GetThreadPrivate( tsdindex );
if ( matchedp != NULL ) {
*matchedp = le->le_matched;
}
if ( errmsgp != NULL ) {
*errmsgp = le->le_errmsg;
}
return( le->le_errno );
}
static void
set_errno( int oserrno )
{
/* XXXmcs: should this be PR_SetError( oserrno, 0 )? */
PR_SetError( PR_UNKNOWN_ERROR, oserrno );
}
static int
get_errno( void )
{
/* XXXmcs: should this be PR_GetError()? */
return( PR_GetOSError());
}
static void *
my_mutex_alloc( void )
{
return( (void *)PR_NewLock());
}
static void
my_mutex_free( void *mutex )
{
PR_DestroyLock( (PRLock *)mutex );
}
static int
my_mutex_lock( void *mutex )
{
PR_Lock( (PRLock *)mutex );
return( 0 );
}
static int
my_mutex_unlock( void *mutex )
{
if ( PR_Unlock( (PRLock *)mutex ) == PR_FAILURE ) {
return( -1 );
}
return( 0 );
}
static LDAPHostEnt *
my_gethostbyname( const char *name, LDAPHostEnt *result,
char *buffer, int buflen, int *statusp, void *extradata )
{
PRHostEnt prhent;
if ( PR_GetHostByName( name, buffer, buflen,
&prhent ) != PR_SUCCESS ) {
return( NULL );
}
return( copyPRHostEnt2LDAPHostEnt( result, &prhent ));
}
static LDAPHostEnt *
my_gethostbyaddr( const char *addr, int length, int type, LDAPHostEnt *result,
char *buffer, int buflen, int *statusp, void *extradata )
{
PRHostEnt prhent;
if ( PR_GetHostByAddr( (PRNetAddr *)addr, buffer, buflen,
&prhent ) != PR_SUCCESS ) {
return( NULL );
}
return( copyPRHostEnt2LDAPHostEnt( result, &prhent ));
}
static LDAPHostEnt *
copyPRHostEnt2LDAPHostEnt( LDAPHostEnt *ldhp, PRHostEnt *prhp )
{
ldhp->ldaphe_name = prhp->h_name;
ldhp->ldaphe_aliases = prhp->h_aliases;
ldhp->ldaphe_addrtype = prhp->h_addrtype;
ldhp->ldaphe_length = prhp->h_length;
ldhp->ldaphe_addr_list = prhp->h_addr_list;
return( ldhp );
}

View file

@ -0,0 +1,912 @@
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is Mozilla Communicator client code, released
* March 31, 1998.
*
* The Initial Developer of the Original Code is
* Netscape Communications Corporation.
* Portions created by the Initial Developer are Copyright (C) 1998-1999
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
*
* Alternatively, the contents of this file may be used under the terms of
* either of the GNU General Public License Version 2 or later (the "GPL"),
* or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
/*
* Copyright (c) 1995 Regents of the University of Michigan.
* All rights reserved.
*/
/*
* open.c
*/
#if 0
#ifndef lint
static char copyright[] = "@(#) Copyright (c) 1995 Regents of the University of Michigan.\nAll rights reserved.\n";
#endif
#endif
#include "ldap-int.h"
#ifdef LDAP_SASLIO_HOOKS
/* Valid for any ANSI C compiler */
#include <limits.h>
extern sasl_callback_t client_callbacks[];
#endif
#define VI_PRODUCTVERSION 3
#ifndef INADDR_LOOPBACK
#define INADDR_LOOPBACK ((unsigned long) 0x7f000001)
#endif
#ifdef LDAP_DEBUG
int ldap_debug = 0;
#endif
#ifdef _WINDOWS
#define USE_WINDOWS_TLS /* thread local storage */
#endif
/*
* global defaults for callbacks are stored here. callers of the API set
* these by passing a NULL "ld" to ldap_set_option(). Everything in
* nsldapi_ld_defaults can be overridden on a per-ld basis as well (the
* memory allocation functions are global to all ld's).
*/
struct ldap nsldapi_ld_defaults;
struct ldap_memalloc_fns nsldapi_memalloc_fns = { 0, 0, 0, 0 };
int nsldapi_initialized = 0;
#ifdef USE_PTHREADS
#include <pthread.h>
#ifdef VMS
/*
** pthread_self() is not a routine on OpenVMS; it's inline assembler code.
** Since we need a real address which we can stuff away into a table, we need
** to make sure that pthread_self maps to the real pthread_self routine (yes,
** we do have one fortunately).
*/
#undef pthread_self
#define pthread_self PTHREAD_SELF
extern pthread_t pthread_self (void);
#endif
static pthread_key_t nsldapi_key;
static pthread_mutex_t nsldapi_init_mutex = PTHREAD_MUTEX_INITIALIZER;
struct nsldapi_ldap_error {
int le_errno;
char *le_matched;
char *le_errmsg;
};
#elif defined (USE_WINDOWS_TLS)
static DWORD dwTlsIndex;
struct nsldapi_ldap_error {
int le_errno;
char *le_matched;
char *le_errmsg;
};
#elif defined (_WINDOWS) /* use static tls */
__declspec ( thread ) int nsldapi_gldaperrno;
__declspec ( thread ) char *nsldapi_gmatched = NULL;
__declspec ( thread ) char *nsldapi_gldaperror = NULL;
#endif /* USE_WINDOWS_TLS */
#ifdef _WINDOWS
#define LDAP_MUTEX_T HANDLE
static LDAP_MUTEX_T nsldapi_init_mutex;
int
pthread_mutex_init( LDAP_MUTEX_T *mp, void *attr)
{
if ( (*mp = CreateMutex(NULL, FALSE, NULL)) == NULL )
return( 1 );
else
return( 0 );
}
static void *
pthread_mutex_alloc( void )
{
LDAP_MUTEX_T *mutexp;
if ( (mutexp = malloc( sizeof(LDAP_MUTEX_T) )) != NULL ) {
pthread_mutex_init( mutexp, NULL );
}
return( mutexp );
}
int
pthread_mutex_destroy( LDAP_MUTEX_T *mp )
{
if ( !(CloseHandle(*mp)) )
return( 1 );
else
return( 0 );
}
static void
pthread_mutex_free( void *mutexp )
{
pthread_mutex_destroy( (LDAP_MUTEX_T *) mutexp );
free( mutexp );
}
int
pthread_mutex_lock( LDAP_MUTEX_T *mp )
{
if ( (WaitForSingleObject(*mp, INFINITE) != WAIT_OBJECT_0) )
return( 1 );
else
return( 0 );
}
int
pthread_mutex_unlock( LDAP_MUTEX_T *mp )
{
if ( !(ReleaseMutex(*mp)) )
return( 1 );
else
return( 0 );
}
static int
get_errno( void )
{
return errno;
}
static void
set_errno( int Errno )
{
errno = Errno;
}
#ifdef USE_WINDOWS_TLS
static void
set_ld_error( int err, char *matched, char *errmsg, void *dummy )
{
struct nsldapi_ldap_error *le;
void *tsd;
le = TlsGetValue( dwTlsIndex );
if (le == NULL) {
tsd = (void *)calloc(1, sizeof(struct nsldapi_ldap_error));
TlsSetValue( dwTlsIndex, tsd );
}
le = TlsGetValue ( dwTlsIndex );
if (le == NULL)
return;
le->le_errno = err;
if ( le->le_matched != NULL ) {
ldap_memfree( le->le_matched );
}
le->le_matched = matched;
if ( le->le_errmsg != NULL ) {
ldap_memfree( le->le_errmsg );
}
le->le_errmsg = errmsg;
}
static int
get_ld_error ( char **matched, char **errmsg, void *dummy )
{
struct nsldapi_ldap_error *le;
le = TlsGetValue( dwTlsIndex );
if ( matched != NULL ) {
*matched = le->le_matched;
}
if ( errmsg != NULL ) {
*errmsg = le->le_errmsg;
}
return( le->le_errno );
}
#else
static int
get_ld_error( char **LDMatched, char **LDError, void * Args )
{
if ( LDMatched != NULL )
{
*LDMatched = nsldapi_gmatched;
}
if ( LDError != NULL )
{
*LDError = nsldapi_gldaperror;
}
return nsldapi_gldaperrno;
}
static void
set_ld_error( int LDErrno, char * LDMatched, char * LDError,
void * Args )
{
/* Clean up any previous string storage. */
if ( nsldapi_gmatched != NULL )
{
ldap_memfree( nsldapi_gmatched );
}
if ( nsldapi_gldaperror != NULL )
{
ldap_memfree( nsldapi_gldaperror );
}
nsldapi_gldaperrno = LDErrno;
nsldapi_gmatched = LDMatched;
nsldapi_gldaperror = LDError;
}
#endif /* USE_WINDOWS_TLS */
#endif /* ! _WINDOWS */
#ifdef USE_PTHREADS
static void *
pthread_mutex_alloc( void )
{
pthread_mutex_t *mutexp;
if ( (mutexp = malloc( sizeof(pthread_mutex_t) )) != NULL ) {
pthread_mutex_init( mutexp, NULL );
}
return( mutexp );
}
static void
pthread_mutex_free( void *mutexp )
{
pthread_mutex_destroy( (pthread_mutex_t *) mutexp );
free( mutexp );
}
static void
set_ld_error( int err, char *matched, char *errmsg, void *dummy )
{
struct nsldapi_ldap_error *le;
void *tsd;
le = pthread_getspecific( nsldapi_key );
if (le == NULL) {
tsd = (void *)calloc(1, sizeof(struct nsldapi_ldap_error));
pthread_setspecific( nsldapi_key, tsd );
}
le = pthread_getspecific( nsldapi_key );
if (le == NULL)
return;
le->le_errno = err;
if ( le->le_matched != NULL ) {
ldap_memfree( le->le_matched );
}
le->le_matched = matched;
if ( le->le_errmsg != NULL ) {
ldap_memfree( le->le_errmsg );
}
le->le_errmsg = errmsg;
}
static int
get_ld_error( char **matched, char **errmsg, void *dummy )
{
struct nsldapi_ldap_error *le;
le = pthread_getspecific( nsldapi_key );
if (le == NULL)
return( LDAP_SUCCESS );
if ( matched != NULL ) {
*matched = le->le_matched;
}
if ( errmsg != NULL ) {
*errmsg = le->le_errmsg;
}
return( le->le_errno );
}
static void
set_errno( int err )
{
errno = err;
}
static int
get_errno( void )
{
return( errno );
}
#endif /* use_pthreads */
#if defined(USE_PTHREADS) || defined(_WINDOWS)
static struct ldap_thread_fns
nsldapi_default_thread_fns = {
(void *(*)(void))pthread_mutex_alloc,
(void (*)(void *))pthread_mutex_free,
(int (*)(void *))pthread_mutex_lock,
(int (*)(void *))pthread_mutex_unlock,
(int (*)(void))get_errno,
(void (*)(int))set_errno,
(int (*)(char **, char **, void *))get_ld_error,
(void (*)(int, char *, char *, void *))set_ld_error,
0 };
static struct ldap_extra_thread_fns
nsldapi_default_extra_thread_fns = {
0, 0, 0, 0, 0,
#ifdef _WINDOWS
0
#else
(void *(*)(void))pthread_self
#endif /* _WINDOWS */
};
#endif /* use_pthreads || _windows */
void
nsldapi_initialize_defaults( void )
{
#ifdef _WINDOWS
pthread_mutex_init( &nsldapi_init_mutex, NULL );
#endif /* _WINDOWS */
#if defined(USE_PTHREADS) || defined(_WINDOWS)
pthread_mutex_lock( &nsldapi_init_mutex );
if ( nsldapi_initialized ) {
pthread_mutex_unlock( &nsldapi_init_mutex );
return;
}
#else
if ( nsldapi_initialized ) {
return;
}
#endif /* use_pthreads || _windows */
#ifdef USE_PTHREADS
if ( pthread_key_create(&nsldapi_key, free ) != 0) {
perror("pthread_key_create");
}
#elif defined(USE_WINDOWS_TLS)
dwTlsIndex = TlsAlloc();
#endif /* USE_WINDOWS_TLS */
memset( &nsldapi_memalloc_fns, 0, sizeof( nsldapi_memalloc_fns ));
memset( &nsldapi_ld_defaults, 0, sizeof( nsldapi_ld_defaults ));
nsldapi_ld_defaults.ld_options = LDAP_BITOPT_REFERRALS;
nsldapi_ld_defaults.ld_version = LDAP_VERSION3;
nsldapi_ld_defaults.ld_lberoptions = LBER_OPT_USE_DER;
nsldapi_ld_defaults.ld_refhoplimit = LDAP_DEFAULT_REFHOPLIMIT;
#ifdef LDAP_SASLIO_HOOKS
/* SASL default option settings */
nsldapi_ld_defaults.ld_def_sasl_mech = NULL;
nsldapi_ld_defaults.ld_def_sasl_realm = NULL;
nsldapi_ld_defaults.ld_def_sasl_authcid = NULL;
nsldapi_ld_defaults.ld_def_sasl_authzid = NULL;
/* SASL Security properties */
nsldapi_ld_defaults.ld_sasl_secprops.max_ssf = UINT_MAX;
nsldapi_ld_defaults.ld_sasl_secprops.maxbufsize = SASL_MAX_BUFF_SIZE;
nsldapi_ld_defaults.ld_sasl_secprops.security_flags =
SASL_SEC_NOPLAINTEXT | SASL_SEC_NOANONYMOUS;
/* SASL mutex function callbacks */
sasl_set_mutex(
(sasl_mutex_alloc_t *)nsldapi_default_thread_fns.ltf_mutex_alloc,
(sasl_mutex_lock_t *)nsldapi_default_thread_fns.ltf_mutex_lock,
(sasl_mutex_unlock_t *)nsldapi_default_thread_fns.ltf_mutex_unlock,
(sasl_mutex_free_t *)nsldapi_default_thread_fns.ltf_mutex_free );
/* SASL memory allocation function callbacks */
sasl_set_alloc(
(sasl_malloc_t *)ldap_x_malloc,
(sasl_calloc_t *)ldap_x_calloc,
(sasl_realloc_t *)ldap_x_realloc,
(sasl_free_t *)ldap_x_free );
/* SASL library initialization */
if ( sasl_client_init( client_callbacks ) != SASL_OK ) {
nsldapi_initialized = 0;
pthread_mutex_unlock( &nsldapi_init_mutex );
return;
}
#endif
#if defined( STR_TRANSLATION ) && defined( LDAP_DEFAULT_CHARSET )
nsldapi_ld_defaults.ld_lberoptions |= LBER_OPT_TRANSLATE_STRINGS;
#if LDAP_CHARSET_8859 == LDAP_DEFAULT_CHARSET
ldap_set_string_translators( &nsldapi_ld_defaults, ldap_8859_to_t61,
ldap_t61_to_8859 );
#endif /* LDAP_CHARSET_8859 == LDAP_DEFAULT_CHARSET */
#endif /* STR_TRANSLATION && LDAP_DEFAULT_CHARSET */
/* set default connect timeout (in milliseconds) */
/* this was picked as it is the standard tcp timeout as well */
nsldapi_ld_defaults.ld_connect_timeout = LDAP_X_IO_TIMEOUT_NO_TIMEOUT;
#if defined(USE_PTHREADS) || defined(_WINDOWS)
/* load up default platform specific locking routines */
if (ldap_set_option( &nsldapi_ld_defaults, LDAP_OPT_THREAD_FN_PTRS,
(void *)&nsldapi_default_thread_fns) != LDAP_SUCCESS) {
nsldapi_initialized = 0;
pthread_mutex_unlock( &nsldapi_init_mutex );
return;
}
#ifndef _WINDOWS
/* load up default threadid function */
if (ldap_set_option( &nsldapi_ld_defaults, LDAP_OPT_EXTRA_THREAD_FN_PTRS,
(void *)&nsldapi_default_extra_thread_fns) != LDAP_SUCCESS) {
nsldapi_initialized = 0;
pthread_mutex_unlock( &nsldapi_init_mutex );
return;
}
#endif /* _WINDOWS */
nsldapi_initialized = 1;
pthread_mutex_unlock( &nsldapi_init_mutex );
#else
nsldapi_initialized = 1;
#endif /* use_pthreads || _windows */
}
/*
* ldap_version - report version levels for important properties
* This function is deprecated. Use ldap_get_option( ..., LDAP_OPT_API_INFO,
* ... ) instead.
*
* Example:
* LDAPVersion ver;
* ldap_version( &ver );
* if ( (ver.sdk_version < 100) || (ver.SSL_version < 300) )
* fprintf( stderr, "LDAP SDK level insufficient\n" );
*
* or:
* if ( ldap_version(NULL) < 100 )
* fprintf( stderr, "LDAP SDK level insufficient\n" );
*
*/
int
LDAP_CALL
ldap_version( LDAPVersion *ver )
{
if ( NULL != ver )
{
memset( ver, 0, sizeof(*ver) );
ver->sdk_version = (int)(VI_PRODUCTVERSION * 100);
ver->protocol_version = LDAP_VERSION_MAX * 100;
ver->SSL_version = SSL_VERSION * 100;
/*
* set security to none by default
*/
ver->security_level = LDAP_SECURITY_NONE;
#if defined(LINK_SSL)
#if defined(NS_DOMESTIC)
ver->security_level = 128;
#elif defined(NSS_EXPORT)
ver->security_level = 40;
#endif
#endif
}
return (int)(VI_PRODUCTVERSION * 100);
}
/*
* ldap_open - initialize and connect to an ldap server. A magic cookie to
* be used for future communication is returned on success, NULL on failure.
* "host" may be a space-separated list of hosts or IP addresses
*
* Example:
* LDAP *ld;
* ld = ldap_open( hostname, port );
*/
LDAP *
LDAP_CALL
ldap_open( const char *host, int port )
{
LDAP *ld;
LDAPDebug( LDAP_DEBUG_TRACE, "ldap_open\n", 0, 0, 0 );
if (( ld = ldap_init( host, port )) == NULL ) {
return( NULL );
}
LDAP_MUTEX_LOCK( ld, LDAP_CONN_LOCK );
if ( nsldapi_open_ldap_defconn( ld ) < 0 ) {
LDAP_MUTEX_UNLOCK( ld, LDAP_CONN_LOCK );
ldap_ld_free( ld, NULL, NULL, 0 );
return( NULL );
}
LDAP_MUTEX_UNLOCK( ld, LDAP_CONN_LOCK );
LDAPDebug( LDAP_DEBUG_TRACE, "ldap_open successful, ld_host is %s\n",
( ld->ld_host == NULL ) ? "(null)" : ld->ld_host, 0, 0 );
return( ld );
}
/*
* ldap_init - initialize the LDAP library. A magic cookie to be used for
* future communication is returned on success, NULL on failure.
* "defhost" may be a space-separated list of hosts or IP addresses
*
* NOTE: If you want to use IPv6, you must use prldap creating a LDAP handle
* with prldap_init instead of ldap_init. Or install the NSPR functions
* by calling prldap_install_routines. (See the nspr samples in examples)
*
* Example:
* LDAP *ld;
* ld = ldap_init( default_hostname, default_port );
*/
LDAP *
LDAP_CALL
ldap_init( const char *defhost, int defport )
{
LDAP *ld;
if ( !nsldapi_initialized ) {
nsldapi_initialize_defaults();
}
if ( defport < 0 || defport > LDAP_PORT_MAX ) {
LDAPDebug( LDAP_DEBUG_ANY,
"ldap_init: port %d is invalid (port numbers must range from 1 to %d)\n",
defport, LDAP_PORT_MAX, 0 );
#if !defined( macintosh ) && !defined( DOS ) && !defined( BEOS )
errno = EINVAL;
#endif
return( NULL );
}
LDAPDebug( LDAP_DEBUG_TRACE, "ldap_init\n", 0, 0, 0 );
if ( (ld = (LDAP*)NSLDAPI_MALLOC( sizeof(struct ldap) )) == NULL ) {
return( NULL );
}
/* copy defaults */
SAFEMEMCPY( ld, &nsldapi_ld_defaults, sizeof( struct ldap ));
if ( nsldapi_ld_defaults.ld_io_fns_ptr != NULL ) {
if (( ld->ld_io_fns_ptr = (struct ldap_io_fns *)NSLDAPI_MALLOC(
sizeof( struct ldap_io_fns ))) == NULL ) {
NSLDAPI_FREE( (char *)ld );
return( NULL );
}
/* struct copy */
*(ld->ld_io_fns_ptr) = *(nsldapi_ld_defaults.ld_io_fns_ptr);
}
/* call the new handle I/O callback if one is defined */
if ( ld->ld_extnewhandle_fn != NULL ) {
/*
* We always pass the session extended I/O argument to
* the new handle callback.
*/
if ( ld->ld_extnewhandle_fn( ld, ld->ld_ext_session_arg )
!= LDAP_SUCCESS ) {
NSLDAPI_FREE( (char*)ld );
return( NULL );
}
}
/* allocate session-specific resources */
if (( ld->ld_sbp = ber_sockbuf_alloc()) == NULL ||
( defhost != NULL &&
( ld->ld_defhost = nsldapi_strdup( defhost )) == NULL ) ||
((ld->ld_mutex = (void **) NSLDAPI_CALLOC( LDAP_MAX_LOCK, sizeof(void *))) == NULL )) {
if ( ld->ld_sbp != NULL ) {
ber_sockbuf_free( ld->ld_sbp );
}
if( ld->ld_mutex != NULL ) {
NSLDAPI_FREE( ld->ld_mutex );
}
NSLDAPI_FREE( (char*)ld );
return( NULL );
}
/* install Sockbuf I/O functions if set in LDAP * */
if ( ld->ld_extread_fn != NULL || ld->ld_extwrite_fn != NULL ) {
struct lber_x_ext_io_fns lberiofns;
memset( &lberiofns, 0, sizeof( lberiofns ));
lberiofns.lbextiofn_size = LBER_X_EXTIO_FNS_SIZE;
lberiofns.lbextiofn_read = ld->ld_extread_fn;
lberiofns.lbextiofn_write = ld->ld_extwrite_fn;
lberiofns.lbextiofn_writev = ld->ld_extwritev_fn;
lberiofns.lbextiofn_socket_arg = NULL;
ber_sockbuf_set_option( ld->ld_sbp, LBER_SOCKBUF_OPT_EXT_IO_FNS,
(void *)&lberiofns );
}
/* allocate mutexes */
nsldapi_mutex_alloc_all( ld );
/* set default port */
ld->ld_defport = ( defport == 0 ) ? LDAP_PORT : defport;
return( ld );
}
void
nsldapi_mutex_alloc_all( LDAP *ld )
{
int i;
if ( ld != &nsldapi_ld_defaults && ld->ld_mutex != NULL ) {
for ( i = 0; i<LDAP_MAX_LOCK; i++ ) {
ld->ld_mutex[i] = LDAP_MUTEX_ALLOC( ld );
ld->ld_mutex_threadid[i] = (void *) -1;
ld->ld_mutex_refcnt[i] = 0;
}
}
}
void
nsldapi_mutex_free_all( LDAP *ld )
{
int i;
if ( ld != &nsldapi_ld_defaults && ld->ld_mutex != NULL ) {
for ( i = 0; i<LDAP_MAX_LOCK; i++ ) {
LDAP_MUTEX_FREE( ld, ld->ld_mutex[i] );
}
}
}
/* returns 0 if connection opened and -1 if an error occurs */
int
nsldapi_open_ldap_defconn( LDAP *ld )
{
LDAPServer *srv;
if (( srv = (LDAPServer *)NSLDAPI_CALLOC( 1, sizeof( LDAPServer ))) ==
NULL || ( ld->ld_defhost != NULL && ( srv->lsrv_host =
nsldapi_strdup( ld->ld_defhost )) == NULL )) {
LDAP_SET_LDERRNO( ld, LDAP_NO_MEMORY, NULL, NULL );
return( -1 );
}
srv->lsrv_port = ld->ld_defport;
if (( ld->ld_options & LDAP_BITOPT_SSL ) != 0 ) {
srv->lsrv_options |= LDAP_SRV_OPT_SECURE;
}
if (( ld->ld_defconn = nsldapi_new_connection( ld, &srv, 1, 1, 0 ))
== NULL ) {
if ( ld->ld_defhost != NULL ) {
NSLDAPI_FREE( srv->lsrv_host );
}
NSLDAPI_FREE( (char *)srv );
return( -1 );
}
++ld->ld_defconn->lconn_refcnt; /* so it never gets closed/freed */
return( 0 );
}
struct ldap_x_hostlist_status {
char *lhs_hostlist;
char *lhs_nexthost;
int lhs_defport;
};
/*
* Return the first host and port in hostlist (setting *hostp and *portp).
* Return value is an LDAP API error code (LDAP_SUCCESS if all goes well).
* Note that a NULL or zero-length hostlist causes the host "127.0.0.1" to
* be returned.
*/
int LDAP_CALL
ldap_x_hostlist_first( const char *hostlist, int defport, char **hostp,
int *portp, struct ldap_x_hostlist_status **statusp )
{
if ( NULL == hostp || NULL == portp || NULL == statusp ) {
return( LDAP_PARAM_ERROR );
}
if ( NULL == hostlist || *hostlist == '\0' ) {
*hostp = nsldapi_strdup( "127.0.0.1" );
if ( NULL == *hostp ) {
return( LDAP_NO_MEMORY );
}
*portp = defport;
*statusp = NULL;
return( LDAP_SUCCESS );
}
*statusp = NSLDAPI_CALLOC( 1, sizeof( struct ldap_x_hostlist_status ));
if ( NULL == *statusp ) {
return( LDAP_NO_MEMORY );
}
(*statusp)->lhs_hostlist = nsldapi_strdup( hostlist );
if ( NULL == (*statusp)->lhs_hostlist ) {
return( LDAP_NO_MEMORY );
}
(*statusp)->lhs_nexthost = (*statusp)->lhs_hostlist;
(*statusp)->lhs_defport = defport;
return( ldap_x_hostlist_next( hostp, portp, *statusp ));
}
/*
* Return the next host and port in hostlist (setting *hostp and *portp).
* Return value is an LDAP API error code (LDAP_SUCCESS if all goes well).
* If no more hosts are available, LDAP_SUCCESS is returned but *hostp is set
* to NULL.
*/
int LDAP_CALL
ldap_x_hostlist_next( char **hostp, int *portp,
struct ldap_x_hostlist_status *status )
{
char *q;
int squarebrackets = 0;
if ( NULL == hostp || NULL == portp ) {
return( LDAP_PARAM_ERROR );
}
if ( NULL == status || NULL == status->lhs_nexthost ) {
*hostp = NULL;
return( LDAP_SUCCESS );
}
/*
* skip past leading '[' if present (IPv6 addresses may be surrounded
* with square brackets, e.g., [fe80::a00:20ff:fee5:c0b4]:389
*/
if ( status->lhs_nexthost[0] == '[' ) {
++status->lhs_nexthost;
squarebrackets = 1;
}
/* copy host into *hostp */
if ( NULL != ( q = strchr( status->lhs_nexthost, ' ' ))) {
size_t len = q - status->lhs_nexthost;
*hostp = NSLDAPI_MALLOC( len + 1 );
if ( NULL == *hostp ) {
return( LDAP_NO_MEMORY );
}
strncpy( *hostp, status->lhs_nexthost, len );
(*hostp)[len] = '\0';
status->lhs_nexthost += ( len + 1 );
} else { /* last host */
*hostp = nsldapi_strdup( status->lhs_nexthost );
if ( NULL == *hostp ) {
return( LDAP_NO_MEMORY );
}
status->lhs_nexthost = NULL;
}
/*
* Look for closing ']' and skip past it before looking for port.
*/
if ( squarebrackets && NULL != ( q = strchr( *hostp, ']' ))) {
*q++ = '\0';
} else {
q = *hostp;
}
/* determine and set port */
if ( NULL != ( q = strchr( q, ':' ))) {
*q++ = '\0';
*portp = atoi( q );
} else {
*portp = status->lhs_defport;
}
return( LDAP_SUCCESS );
}
void LDAP_CALL
ldap_x_hostlist_statusfree( struct ldap_x_hostlist_status *status )
{
if ( NULL != status ) {
if ( NULL != status->lhs_hostlist ) {
NSLDAPI_FREE( status->lhs_hostlist );
}
NSLDAPI_FREE( status );
}
}
/*
* memory allocation functions. we include these in open.c since every
* LDAP application is likely to pull the rest of the code in this file
* in anyways.
*/
void *
ldap_x_malloc( size_t size )
{
return( nsldapi_memalloc_fns.ldapmem_malloc == NULL ?
malloc( size ) :
nsldapi_memalloc_fns.ldapmem_malloc( size ));
}
void *
ldap_x_calloc( size_t nelem, size_t elsize )
{
return( nsldapi_memalloc_fns.ldapmem_calloc == NULL ?
calloc( nelem, elsize ) :
nsldapi_memalloc_fns.ldapmem_calloc( nelem, elsize ));
}
void *
ldap_x_realloc( void *ptr, size_t size )
{
return( nsldapi_memalloc_fns.ldapmem_realloc == NULL ?
realloc( ptr, size ) :
nsldapi_memalloc_fns.ldapmem_realloc( ptr, size ));
}
void
ldap_x_free( void *ptr )
{
if ( nsldapi_memalloc_fns.ldapmem_free == NULL ) {
free( ptr );
} else {
nsldapi_memalloc_fns.ldapmem_free( ptr );
}
}
/* if s is NULL, returns NULL */
char *
nsldapi_strdup( const char *s )
{
char *p;
if ( s == NULL ||
(p = (char *)NSLDAPI_MALLOC( strlen( s ) + 1 )) == NULL )
return( NULL );
strcpy( p, s );
return( p );
}

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,164 @@
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is Mozilla Communicator client code, released
* March 31, 1998.
*
* The Initial Developer of the Original Code is
* Netscape Communications Corporation.
* Portions created by the Initial Developer are Copyright (C) 1998-1999
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
*
* Alternatively, the contents of this file may be used under the terms of
* either of the GNU General Public License Version 2 or later (the "GPL"),
* or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
#include "ldap-int.h"
/* ldap_create_proxyauth_control
Create a "version 1" proxied authorization control.
Parameters are
ld LDAP pointer to the desired connection
dn The dn used in the proxy auth
ctl_iscritical Indicates whether the control is critical of not. If
this field is non-zero, the operation will only be car-
ried out if the control is recognized by the server
and/or client
ctrlp the address of a place to put the constructed control
*/
int
LDAP_CALL
ldap_create_proxyauth_control (
LDAP *ld,
const char *dn,
const char ctl_iscritical,
LDAPControl **ctrlp
)
{
BerElement *ber;
int rc;
if ( !NSLDAPI_VALID_LDAP_POINTER( ld )) {
return( LDAP_PARAM_ERROR );
}
if ( ctrlp == NULL ) {
LDAP_SET_LDERRNO( ld, LDAP_PARAM_ERROR, NULL, NULL );
return ( LDAP_PARAM_ERROR );
}
if (NULL == dn)
{
dn = "";
}
/* create a ber package to hold the controlValue */
if ( ( nsldapi_alloc_ber_with_options( ld, &ber ) ) != LDAP_SUCCESS ) {
LDAP_SET_LDERRNO( ld, LDAP_NO_MEMORY, NULL, NULL );
return( LDAP_NO_MEMORY );
}
if ( LBER_ERROR == ber_printf( ber,
"{s}",
dn ) )
{
LDAP_SET_LDERRNO( ld, LDAP_ENCODING_ERROR, NULL, NULL );
ber_free( ber, 1 );
return( LDAP_ENCODING_ERROR );
}
rc = nsldapi_build_control( LDAP_CONTROL_PROXYAUTH, ber, 1,
ctl_iscritical, ctrlp );
LDAP_SET_LDERRNO( ld, rc, NULL, NULL );
return( rc );
}
/* ldap_create_proxiedauth_control
Create a "version 2" proxied authorization control.
Parameters are
ld LDAP pointer to the desired connection
authzid The authorization identity used in the proxy auth,
e.g., dn:uid=bjensen,dc=example,dc=com
ctrlp the address of a place to put the constructed control
*/
int
LDAP_CALL
ldap_create_proxiedauth_control (
LDAP *ld,
const char *authzid,
LDAPControl **ctrlp
)
{
BerElement *ber;
int rc;
if ( !NSLDAPI_VALID_LDAP_POINTER( ld )) {
return( LDAP_PARAM_ERROR );
}
if ( ctrlp == NULL || authzid == NULL ) {
LDAP_SET_LDERRNO( ld, LDAP_PARAM_ERROR, NULL, NULL );
return ( LDAP_PARAM_ERROR );
}
/* create a ber package to hold the controlValue */
if ( ( nsldapi_alloc_ber_with_options( ld, &ber ) ) != LDAP_SUCCESS ) {
LDAP_SET_LDERRNO( ld, LDAP_NO_MEMORY, NULL, NULL );
return( LDAP_NO_MEMORY );
}
if ( LBER_ERROR == ber_printf( ber,
"s",
authzid ) )
{
LDAP_SET_LDERRNO( ld, LDAP_ENCODING_ERROR, NULL, NULL );
ber_free( ber, 1 );
return( LDAP_ENCODING_ERROR );
}
rc = nsldapi_build_control( LDAP_CONTROL_PROXIEDAUTH, ber, 1, 1, ctrlp );
LDAP_SET_LDERRNO( ld, rc, NULL, NULL );
return( rc );
}

View file

@ -0,0 +1,190 @@
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is Mozilla Communicator client code, released
* March 31, 1998.
*
* The Initial Developer of the Original Code is
* Netscape Communications Corporation.
* Portions created by the Initial Developer are Copyright (C) 1998-1999
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
*
* Alternatively, the contents of this file may be used under the terms of
* either of the GNU General Public License Version 2 or later (the "GPL"),
* or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
/*
* psearch.c - Persistent search and "Entry Change Notification" support.
*/
#include "ldap-int.h"
int
LDAP_CALL
ldap_create_persistentsearch_control( LDAP *ld, int changetypes,
int changesonly, int return_echg_ctls, char ctl_iscritical,
LDAPControl **ctrlp )
{
BerElement *ber;
int rc;
if ( !NSLDAPI_VALID_LDAP_POINTER( ld )) {
return( LDAP_PARAM_ERROR );
}
if ( ctrlp == NULL || ( changetypes & ~LDAP_CHANGETYPE_ANY ) != 0 ) {
rc = LDAP_PARAM_ERROR;
goto report_error_and_return;
}
/*
* create a Persistent Search control. The control value looks like this:
*
* PersistentSearch ::= SEQUENCE {
* changeTypes INTEGER,
* -- the changeTypes field is the logical OR of
* -- one or more of these values: add (1), delete (2),
* -- modify (4), modDN (8). It specifies which types of
* -- changes will cause an entry to be returned.
* changesOnly BOOLEAN, -- skip initial search?
* returnECs BOOLEAN, -- return "Entry Change" controls?
* }
*/
if (( nsldapi_alloc_ber_with_options( ld, &ber )) != LDAP_SUCCESS ) {
rc = LDAP_NO_MEMORY;
goto report_error_and_return;
}
if ( ber_printf( ber, "{ibb}", changetypes, changesonly,
return_echg_ctls ) == -1 ) {
ber_free( ber, 1 );
rc = LDAP_ENCODING_ERROR;
goto report_error_and_return;
}
rc = nsldapi_build_control( LDAP_CONTROL_PERSISTENTSEARCH, ber, 1,
ctl_iscritical, ctrlp );
report_error_and_return:
LDAP_SET_LDERRNO( ld, rc, NULL, NULL );
return( rc );
}
int
LDAP_CALL
ldap_parse_entrychange_control( LDAP *ld, LDAPControl **ctrls, ber_int_t *chgtypep,
char **prevdnp, int *chgnumpresentp, ber_int_t *chgnump )
{
BerElement *ber;
int rc, i;
ber_int_t changetype;
ber_len_t len;
ber_int_t along;
char *previousdn;
if ( !NSLDAPI_VALID_LDAP_POINTER( ld )) {
return( LDAP_PARAM_ERROR );
}
/*
* find the entry change notification in the list of controls
*/
for ( i = 0; ctrls != NULL && ctrls[i] != NULL; ++i ) {
if ( strcmp( ctrls[i]->ldctl_oid, LDAP_CONTROL_ENTRYCHANGE ) == 0 ) {
break;
}
}
if ( ctrls == NULL || ctrls[i] == NULL ) {
rc = LDAP_CONTROL_NOT_FOUND;
goto report_error_and_return;
}
/*
* allocate a BER element from the control value and parse it. The control
* value should look like this:
*
* EntryChangeNotification ::= SEQUENCE {
* changeType ENUMERATED {
* add (1), -- these values match the
* delete (2), -- values used for changeTypes
* modify (4), -- in the PersistentSearch control.
* modDN (8),
* },
* previousDN LDAPDN OPTIONAL, -- modDN ops. only
* changeNumber INTEGER OPTIONAL, -- if supported
* }
*/
if (( ber = ber_init( &(ctrls[i]->ldctl_value))) == NULL ) {
rc = LDAP_NO_MEMORY;
goto report_error_and_return;
}
if ( ber_scanf( ber, "{e", &along ) == LBER_ERROR ) {
ber_free( ber, 1 );
rc = LDAP_DECODING_ERROR;
goto report_error_and_return;
}
changetype = along;
if ( changetype == LDAP_CHANGETYPE_MODDN ) {
if ( ber_scanf( ber, "a", &previousdn ) == LBER_ERROR ) {
ber_free( ber, 1 );
rc = LDAP_DECODING_ERROR;
goto report_error_and_return;
}
} else {
previousdn = NULL;
}
if ( chgtypep != NULL ) {
*chgtypep = changetype;
}
if ( prevdnp != NULL ) {
*prevdnp = previousdn;
} else if ( previousdn != NULL ) {
NSLDAPI_FREE( previousdn );
}
if ( chgnump != NULL ) { /* check for optional changenumber */
if ( ber_peek_tag( ber, &len ) == LBER_INTEGER
&& ber_get_int( ber, chgnump ) != LBER_ERROR ) {
if ( chgnumpresentp != NULL ) {
*chgnumpresentp = 1;
}
} else {
if ( chgnumpresentp != NULL ) {
*chgnumpresentp = 0;
}
}
}
ber_free( ber, 1 );
rc = LDAP_SUCCESS;
report_error_and_return:
LDAP_SET_LDERRNO( ld, rc, NULL, NULL );
return( rc );
}

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,265 @@
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is Sun LDAP C SDK.
*
* The Initial Developer of the Original Code is Sun Microsystems, Inc.
*
* Portions created by Sun Microsystems, Inc are Copyright (C) 2005
* Sun Microsystems, Inc. All Rights Reserved.
*
* Contributor(s): abobrov
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
#include "ldap-int.h"
/* ldap_passwd */
int
LDAP_CALL
ldap_passwd (
LDAP *ld,
struct berval *userid,
struct berval *oldpasswd,
struct berval *newpasswd,
LDAPControl **serverctrls,
LDAPControl **clientctrls,
int *msgidp
)
{
int rc;
BerElement *ber = NULL;
struct berval *requestdata = NULL;
if ( !NSLDAPI_VALID_LDAP_POINTER( ld )) {
LDAP_SET_LDERRNO( ld, LDAP_PARAM_ERROR, NULL, NULL );
return( LDAP_PARAM_ERROR );
}
requestdata = NSLDAPI_MALLOC( sizeof( struct berval ) );
if ( requestdata == NULL ) {
LDAP_SET_LDERRNO( ld, LDAP_NO_MEMORY, NULL, NULL );
return( LDAP_NO_MEMORY );
}
/* If the requestValue field is provided, it SHALL contain a
* PasswdModifyRequestValue with one or more fields present.
*/
if ( userid || oldpasswd || newpasswd ) {
if ( ( nsldapi_alloc_ber_with_options( ld, &ber ) )
!= LDAP_SUCCESS ) {
LDAP_SET_LDERRNO( ld, LDAP_NO_MEMORY, NULL, NULL );
return( LDAP_NO_MEMORY );
}
/*
* PasswdModifyRequestValue ::= SEQUENCE {
* userIdentity [0] OCTET STRING OPTIONAL
* oldPasswd [1] OCTET STRING OPTIONAL
* newPasswd [2] OCTET STRING OPTIONAL }
*/
if ( LBER_ERROR == ( ber_printf( ber, "{" ) ) ) {
LDAP_SET_LDERRNO( ld, LDAP_ENCODING_ERROR, NULL, NULL );
ber_free( ber, 1 );
return( LDAP_ENCODING_ERROR );
}
if ( userid && userid->bv_val && userid->bv_len ) {
if ( LBER_ERROR == ( ber_printf( ber, "to", LDAP_TAG_PWDMOD_REQ_ID,
userid->bv_val, userid->bv_len ) ) ) {
LDAP_SET_LDERRNO( ld, LDAP_ENCODING_ERROR, NULL, NULL );
ber_free( ber, 1 );
return( LDAP_ENCODING_ERROR );
}
}
if ( oldpasswd && oldpasswd->bv_val && oldpasswd->bv_len ) {
if ( LBER_ERROR == ( ber_printf( ber, "to", LDAP_TAG_PWDMOD_REQ_OLD,
oldpasswd->bv_val, oldpasswd->bv_len ) ) ) {
LDAP_SET_LDERRNO( ld, LDAP_ENCODING_ERROR, NULL, NULL );
ber_free( ber, 1 );
return( LDAP_ENCODING_ERROR );
}
}
if ( newpasswd && newpasswd->bv_val && newpasswd->bv_len ) {
if ( LBER_ERROR == ( ber_printf( ber, "to", LDAP_TAG_PWDMOD_REQ_NEW,
newpasswd->bv_val, newpasswd->bv_len ) ) ) {
LDAP_SET_LDERRNO( ld, LDAP_ENCODING_ERROR, NULL, NULL );
ber_free( ber, 1 );
return( LDAP_ENCODING_ERROR );
}
}
if ( LBER_ERROR == ( ber_printf( ber, "}" ) ) ) {
LDAP_SET_LDERRNO( ld, LDAP_ENCODING_ERROR, NULL, NULL );
ber_free( ber, 1 );
return( LDAP_ENCODING_ERROR );
}
/* allocate struct berval with contents of the BER encoding */
rc = ber_flatten( ber, &requestdata );
if ( rc == -1 ) {
LDAP_SET_LDERRNO( ld, LDAP_NO_MEMORY, NULL, NULL );
ber_free( ber, 1 );
return( LDAP_NO_MEMORY );
}
} else {
requestdata = NULL;
}
rc = ldap_extended_operation( ld, LDAP_EXOP_MODIFY_PASSWD, requestdata,
serverctrls, clientctrls, msgidp );
/* the ber encoding is no longer needed */
if ( requestdata ) {
ber_bvfree( requestdata );
}
if ( ber ) {
ber_free( ber, 1 );
}
LDAP_SET_LDERRNO( ld, rc, NULL, NULL );
return( rc );
}
/* ldap_parse_passwd */
int
LDAP_CALL
ldap_parse_passwd (
LDAP *ld,
LDAPMessage *result,
struct berval *genpasswd
)
{
int rc;
char *retoidp = NULL;
struct berval *retdatap = NULL;
BerElement *ber = NULL;
ber_len_t len;
ber_tag_t tag;
if ( !NSLDAPI_VALID_LDAP_POINTER( ld )) {
LDAP_SET_LDERRNO( ld, LDAP_PARAM_ERROR, NULL, NULL );
return( LDAP_PARAM_ERROR );
}
if ( !result ) {
LDAP_SET_LDERRNO( ld, LDAP_PARAM_ERROR, NULL, NULL );
return( LDAP_PARAM_ERROR );
}
if ( !genpasswd ) {
LDAP_SET_LDERRNO( ld, LDAP_PARAM_ERROR, NULL, NULL );
return( LDAP_PARAM_ERROR );
}
rc = ldap_parse_extended_result( ld, result, &retoidp, &retdatap, 0 );
if ( rc != LDAP_SUCCESS ) {
return( rc );
}
rc = ldap_get_lderrno( ld, NULL, NULL );
if ( rc != LDAP_SUCCESS ) {
return( rc );
}
if ( retdatap ) {
/* allocate a Ber element with the contents of the
* berval from the response.
*/
if ( ( ber = ber_init( retdatap ) ) == NULL ) {
LDAP_SET_LDERRNO( ld, LDAP_NO_MEMORY, NULL, NULL );
return( LDAP_NO_MEMORY );
}
if ( ( tag = ber_skip_tag( ber, &len ) ) == LBER_ERROR ) {
LDAP_SET_LDERRNO( ld, LDAP_DECODING_ERROR, NULL, NULL );
ber_free( ber, 1 );
ldap_memfree( retoidp );
return( LDAP_DECODING_ERROR );
}
if ( ( ( tag = ber_peek_tag( ber, &len ) ) == LBER_ERROR ) ||
tag != LDAP_TAG_PWDMOD_RES_GEN ) {
LDAP_SET_LDERRNO( ld, LDAP_DECODING_ERROR, NULL, NULL );
ber_free( ber, 1 );
ldap_memfree( retoidp );
return( LDAP_DECODING_ERROR );
}
if ( ber_scanf( ber, "o}", genpasswd ) == LBER_ERROR ) {
LDAP_SET_LDERRNO( ld, LDAP_DECODING_ERROR, NULL, NULL );
ber_free( ber, 1 );
ldap_memfree( retoidp );
return( LDAP_DECODING_ERROR );
}
/* the ber encoding is no longer needed */
ber_free( ber,1 );
}
ldap_memfree( retoidp );
return( LDAP_SUCCESS );
}
/* ldap_passwd_s */
int
LDAP_CALL
ldap_passwd_s (
LDAP *ld,
struct berval *userid,
struct berval *oldpasswd,
struct berval *newpasswd,
struct berval *genpasswd,
LDAPControl **serverctrls,
LDAPControl **clientctrls
)
{
int rc, msgid;
LDAPMessage *result = NULL;
if ( !NSLDAPI_VALID_LDAP_POINTER( ld )) {
LDAP_SET_LDERRNO( ld, LDAP_PARAM_ERROR, NULL, NULL );
return( LDAP_PARAM_ERROR );
}
rc = ldap_passwd( ld, userid, oldpasswd, newpasswd, serverctrls,
clientctrls, &msgid );
if ( rc != LDAP_SUCCESS ) {
return( rc );
}
rc = ldap_result( ld, msgid, LDAP_MSG_ALL, NULL, &result );
if ( rc == -1 ) {
return( LDAP_GET_LDERRNO( ld, NULL, NULL ) );
}
rc = ldap_parse_passwd( ld, result, genpasswd );
ldap_msgfree( result );
return( rc );
}

View file

@ -0,0 +1,315 @@
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is Sun LDAP C SDK.
*
* The Initial Developer of the Original Code is Sun Microsystems, Inc.
*
* Portions created by Sun Microsystems, Inc are Copyright (C) 2005
* Sun Microsystems, Inc. All Rights Reserved.
*
* Contributor(s): abobrov@sun.com
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
#include "ldap-int.h"
/* ldap_create_passwordpolicy_control:
Parameters are
ld LDAP pointer to the desired connection
ctrlp the address of a place to put the constructed control
*/
int
LDAP_CALL
ldap_create_passwordpolicy_control (
LDAP *ld,
LDAPControl **ctrlp
)
{
int rc;
if ( !NSLDAPI_VALID_LDAP_POINTER( ld )) {
return( LDAP_PARAM_ERROR );
}
if ( ctrlp == NULL ) {
LDAP_SET_LDERRNO( ld, LDAP_PARAM_ERROR, NULL, NULL );
return ( LDAP_PARAM_ERROR );
}
rc = nsldapi_build_control( LDAP_CONTROL_PASSWD_POLICY,
NULL, 0, 0, ctrlp );
LDAP_SET_LDERRNO( ld, rc, NULL, NULL );
return( rc );
}
/* ldap_create_passwordpolicy_control_ext:
Parameters are
ld LDAP pointer to the desired connection
ctl_iscritical Indicates whether the control is critical of not. If
this field is non-zero, the operation will only be car-
ried out if the control is recognized by the server
and/or client
ctrlp the address of a place to put the constructed control
*/
int
LDAP_CALL
ldap_create_passwordpolicy_control_ext (
LDAP *ld,
const char ctl_iscritical,
LDAPControl **ctrlp
)
{
int rc;
if ( !NSLDAPI_VALID_LDAP_POINTER( ld )) {
return( LDAP_PARAM_ERROR );
}
if ( ctrlp == NULL ) {
LDAP_SET_LDERRNO( ld, LDAP_PARAM_ERROR, NULL, NULL );
return ( LDAP_PARAM_ERROR );
}
rc = nsldapi_build_control( LDAP_CONTROL_PASSWD_POLICY,
NULL, 0, ctl_iscritical, ctrlp );
LDAP_SET_LDERRNO( ld, rc, NULL, NULL );
return( rc );
}
/* ldap_parse_passwordpolicy_control:
Parameters are
ld LDAP pointer to the desired connection
ctrlp pointer to LDAPControl structure, obtained from
calling ldap_find_control() or by other means.
exptimep result parameter is filled in with the number of seconds before
the password will expire.
gracep result parameter is filled in with the number of grace logins
after the password has expired.
errorcodep result parameter is filled in with the error code of the
password operation.
*/
int
LDAP_CALL
ldap_parse_passwordpolicy_control (
LDAP *ld,
LDAPControl *ctrlp,
ber_int_t *expirep,
ber_int_t *gracep,
LDAPPasswordPolicyError *errorp
)
{
ber_len_t len;
ber_tag_t tag;
ber_int_t pp_exp = -1;
ber_int_t pp_grace = -1;
ber_int_t pp_warning = -1;
ber_int_t pp_err = PP_noError;
BerElement *ber = NULL;
if ( !NSLDAPI_VALID_LDAP_POINTER( ld ) ) {
return( LDAP_PARAM_ERROR );
}
if ( ctrlp == NULL ) {
LDAP_SET_LDERRNO( ld, LDAP_CONTROL_NOT_FOUND, NULL, NULL );
return ( LDAP_CONTROL_NOT_FOUND );
}
/* allocate a Ber element with the contents of the control's struct berval */
if ( ( ber = ber_init( &ctrlp->ldctl_value ) ) == NULL ) {
LDAP_SET_LDERRNO( ld, LDAP_NO_MEMORY, NULL, NULL );
return( LDAP_NO_MEMORY );
}
/*
* The control value should look like this:
*
* PasswordPolicyResponseValue ::= SEQUENCE {
* warning [0] CHOICE {
* timeBeforeExpiration [0] INTEGER (0 .. maxInt),
* graceLoginsRemaining [1] INTEGER (0 .. maxInt) } OPTIONAL
* error [1] ENUMERATED {
* passwordExpired (0),
* accountLocked (1),
* changeAfterReset (2),
* passwordModNotAllowed (3),
* mustSupplyOldPassword (4),
* insufficientPasswordQuality (5),
* passwordTooShort (6),
* passwordTooYoung (7),
* passwordInHistory (8) } OPTIONAL }
*/
if ( ber_scanf( ber, "{" ) == LBER_ERROR ) {
LDAP_SET_LDERRNO( ld, LDAP_DECODING_ERROR, NULL, NULL );
ber_free( ber, 1 );
return( LDAP_DECODING_ERROR );
}
tag = ber_peek_tag( ber, &len );
while ( (tag != LBER_ERROR) && (tag != LBER_END_OF_SEQORSET) ) {
if ( tag == ( LBER_CONSTRUCTED | LBER_CLASS_CONTEXT ) ) {
ber_skip_tag( ber, &len );
if ( ber_scanf( ber, "ti", &tag, &pp_warning ) == LBER_ERROR ) {
LDAP_SET_LDERRNO( ld, LDAP_DECODING_ERROR, NULL, NULL );
ber_free( ber, 1 );
return( LDAP_DECODING_ERROR );
}
if ( tag == LBER_CLASS_CONTEXT ) {
pp_exp = pp_warning;
} else if ( tag == ( LBER_CLASS_CONTEXT | 0x01 ) ) {
pp_grace = pp_warning;
}
} else if ( tag == ( LBER_CLASS_CONTEXT | 0x01 ) ) {
if ( ber_scanf( ber, "ti", &tag, &pp_err ) == LBER_ERROR ) {
LDAP_SET_LDERRNO( ld, LDAP_DECODING_ERROR, NULL, NULL );
ber_free( ber, 1 );
return( LDAP_DECODING_ERROR );
}
}
if ( tag == LBER_DEFAULT ) {
LDAP_SET_LDERRNO( ld, LDAP_DECODING_ERROR, NULL, NULL );
ber_free( ber, 1 );
return( LDAP_DECODING_ERROR );
}
tag = ber_skip_tag( ber, &len );
}
if (expirep) *expirep = pp_exp;
if (gracep) *gracep = pp_grace;
if (errorp) *errorp = pp_err;
/* the ber encoding is no longer needed */
ber_free( ber, 1 );
return( LDAP_SUCCESS );
}
/* ldap_parse_passwordpolicy_control_ext:
Parameters are
ld LDAP pointer to the desired connection
ctrlp An array of controls obtained from calling
ldap_parse_result on the set of results
returned by the server
exptimep result parameter is filled in with the number of seconds before
the password will expire.
gracep result parameter is filled in with the number of grace logins
after the password has expired.
errorcodep result parameter is filled in with the error code of the
password operation.
*/
int
LDAP_CALL
ldap_parse_passwordpolicy_control_ext (
LDAP *ld,
LDAPControl **ctrlp,
ber_int_t *expirep,
ber_int_t *gracep,
LDAPPasswordPolicyError *errorp
)
{
int i, foundPPControl;
LDAPControl *PPCtrlp = NULL;
if ( !NSLDAPI_VALID_LDAP_POINTER( ld ) ) {
return( LDAP_PARAM_ERROR );
}
/* find the control in the list of controls if it exists */
if ( ctrlp == NULL ) {
LDAP_SET_LDERRNO( ld, LDAP_CONTROL_NOT_FOUND, NULL, NULL );
return ( LDAP_CONTROL_NOT_FOUND );
}
foundPPControl = 0;
for ( i = 0; (( ctrlp[i] != NULL ) && ( !foundPPControl )); i++ ) {
foundPPControl = !strcmp( ctrlp[i]->ldctl_oid, LDAP_CONTROL_PASSWD_POLICY );
}
if ( !foundPPControl ) {
LDAP_SET_LDERRNO( ld, LDAP_CONTROL_NOT_FOUND, NULL, NULL );
return ( LDAP_CONTROL_NOT_FOUND );
} else {
/* let local var point to the control */
PPCtrlp = ctrlp[i-1];
}
return (
ldap_parse_passwordpolicy_control( ld, PPCtrlp, expirep, gracep, errorp ));
}
const char *
LDAP_CALL
ldap_passwordpolicy_err2txt( LDAPPasswordPolicyError err )
{
switch(err) {
case PP_passwordExpired:
return "Password expired";
case PP_accountLocked:
return "Account locked";
case PP_changeAfterReset:
return "Password must be changed";
case PP_passwordModNotAllowed:
return "Policy prevents password modification";
case PP_mustSupplyOldPassword:
return "Policy requires old password in order to change password";
case PP_insufficientPasswordQuality:
return "Password fails quality checks";
case PP_passwordTooShort:
return "Password is too short for policy";
case PP_passwordTooYoung:
return "Password has been changed too recently";
case PP_passwordInHistory:
return "New password is in list of old passwords";
case PP_noError:
return "No error";
default:
return "Unknown error code";
}
}

View file

@ -0,0 +1,177 @@
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is Mozilla Communicator client code, released
* March 31, 1998.
*
* The Initial Developer of the Original Code is
* Netscape Communications Corporation.
* Portions created by the Initial Developer are Copyright (C) 1998-1999
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
*
* Alternatively, the contents of this file may be used under the terms of
* either of the GNU General Public License Version 2 or later (the "GPL"),
* or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
/*
* referral.c - routines for handling LDAPv3 referrals and references.
*/
#include "ldap-int.h"
LDAPMessage *
LDAP_CALL
ldap_first_reference( LDAP *ld, LDAPMessage *res )
{
if ( !NSLDAPI_VALID_LDAP_POINTER( ld ) || res == NULLMSG ) {
return( NULLMSG );
}
if ( res->lm_msgtype == LDAP_RES_SEARCH_REFERENCE ) {
return( res );
}
return( ldap_next_reference( ld, res ));
}
LDAPMessage *
LDAP_CALL
ldap_next_reference( LDAP *ld, LDAPMessage *ref )
{
if ( !NSLDAPI_VALID_LDAP_POINTER( ld ) || ref == NULLMSG ) {
return( NULLMSG ); /* punt */
}
for ( ref = ref->lm_chain; ref != NULLMSG; ref = ref->lm_chain ) {
if ( ref->lm_msgtype == LDAP_RES_SEARCH_REFERENCE ) {
return( ref );
}
}
return( NULLMSG );
}
int
LDAP_CALL
ldap_count_references( LDAP *ld, LDAPMessage *res )
{
int i;
if ( !NSLDAPI_VALID_LDAP_POINTER( ld )) {
return( -1 );
}
for ( i = 0; res != NULL; res = res->lm_chain ) {
if ( res->lm_msgtype == LDAP_RES_SEARCH_REFERENCE ) {
++i;
}
}
return( i );
}
/*
* returns an LDAP error code.
*/
int
LDAP_CALL
ldap_parse_reference( LDAP *ld, LDAPMessage *ref, char ***referralsp,
LDAPControl ***serverctrlsp, int freeit )
{
int err;
if ( !NSLDAPI_VALID_LDAP_POINTER( ld ) ||
!NSLDAPI_VALID_LDAPMESSAGE_REFERENCE_POINTER( ref )) {
return( LDAP_PARAM_ERROR );
}
err = nsldapi_parse_reference( ld, ref->lm_ber, referralsp,
serverctrlsp );
LDAP_SET_LDERRNO( ld, err, NULL, NULL );
if ( freeit ) {
ldap_msgfree( ref );
}
return( err );
}
/*
* returns an LDAP error code indicating success or failure of parsing
* does NOT set any error information inside "ld"
*/
int
nsldapi_parse_reference( LDAP *ld, BerElement *rber, char ***referralsp,
LDAPControl ***serverctrlsp )
{
int err;
BerElement ber;
char **refs;
/*
* Parse a searchResultReference message. These are used in LDAPv3
* and beyond and look like this:
*
* SearchResultReference ::= [APPLICATION 19] SEQUENCE OF LDAPURL
*
* all wrapped up in an LDAPMessage sequence which looks like this:
*
* LDAPMessage ::= SEQUENCE {
* messageID MessageID,
* SearchResultReference
* controls [0] Controls OPTIONAL
* }
*
* ldap_result() pulls out the message id, so by the time a result
* message gets here we are conveniently sitting at the start of the
* SearchResultReference itself.
*/
err = LDAP_SUCCESS; /* optimistic */
ber = *rber; /* struct copy */
if ( ber_scanf( &ber, "{v", &refs ) == LBER_ERROR ) {
err = LDAP_DECODING_ERROR;
} else if ( serverctrlsp != NULL ) {
/* pull out controls (if requested and any are present) */
if ( ber_scanf( &ber, "}" ) == LBER_ERROR ) {
err = LDAP_DECODING_ERROR;
} else {
err = nsldapi_get_controls( &ber, serverctrlsp );
}
}
if ( referralsp == NULL ) {
ldap_value_free( refs );
} else {
*referralsp = refs;
}
return( err );
}

View file

@ -0,0 +1,920 @@
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is Mozilla Communicator client code, released
* March 31, 1998.
*
* The Initial Developer of the Original Code is
* Netscape Communications Corporation.
* Portions created by the Initial Developer are Copyright (C) 1998-1999
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
*
* Alternatively, the contents of this file may be used under the terms of
* either of the GNU General Public License Version 2 or later (the "GPL"),
* or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
#include "ldap-int.h"
#if defined( macintosh ) || defined( DOS ) || defined( _WINDOWS ) || defined( NEED_BSDREGEX ) || defined( XP_OS2)
#include "regex.h"
/*
* regex - Regular expression pattern matching and replacement
*
* By: Ozan S. Yigit (oz)
* Dept. of Computer Science
* York University
*
* These routines are the PUBLIC DOMAIN equivalents of regex
* routines as found in 4.nBSD UN*X, with minor extensions.
*
* These routines are derived from various implementations found
* in software tools books, and Conroy's grep. They are NOT derived
* from licensed/restricted software.
* For more interesting/academic/complicated implementations,
* see Henry Spencer's regexp routines, or GNU Emacs pattern
* matching module.
*
* Use the actual CCL code in the CLO
* section of pmatch. No need for a recursive
* pmatch call.
*
* Use a bitmap table to set char bits in an
* 8-bit chunk.
*
* Interfaces:
* re_comp: compile a regular expression into a NFA.
*
* char *re_comp(s)
* char *s;
*
* re_exec: execute the NFA to match a pattern.
*
* int re_exec(s)
* char *s;
*
* re_modw change re_exec's understanding of what a "word"
* looks like (for \< and \>) by adding into the
* hidden word-syntax table.
*
* void re_modw(s)
* char *s;
*
* re_subs: substitute the matched portions in a new string.
*
* int re_subs(src, dst)
* char *src;
* char *dst;
*
* re_fail: failure routine for re_exec.
*
* void re_fail(msg, op)
* char *msg;
* char op;
*
* Regular Expressions:
*
* [1] char matches itself, unless it is a special
* character (metachar): . \ [ ] * + ^ $
*
* [2] . matches any character.
*
* [3] \ matches the character following it, except
* when followed by a left or right round bracket,
* a digit 1 to 9 or a left or right angle bracket.
* (see [7], [8] and [9])
* It is used as an escape character for all
* other meta-characters, and itself. When used
* in a set ([4]), it is treated as an ordinary
* character.
*
* [4] [set] matches one of the characters in the set.
* If the first character in the set is "^",
* it matches a character NOT in the set, i.e.
* complements the set. A shorthand S-E is
* used to specify a set of characters S upto
* E, inclusive. The special characters "]" and
* "-" have no special meaning if they appear
* as the first chars in the set.
* examples: match:
*
* [a-z] any lowercase alpha
*
* [^]-] any char except ] and -
*
* [^A-Z] any char except uppercase
* alpha
*
* [a-zA-Z] any alpha
*
* [5] * any regular expression form [1] to [4], followed by
* closure char (*) matches zero or more matches of
* that form.
*
* [6] + same as [5], except it matches one or more.
*
* [7] a regular expression in the form [1] to [10], enclosed
* as \(form\) matches what form matches. The enclosure
* creates a set of tags, used for [8] and for
* pattern substution. The tagged forms are numbered
* starting from 1.
*
* [8] a \ followed by a digit 1 to 9 matches whatever a
* previously tagged regular expression ([7]) matched.
*
* [9] \< a regular expression starting with a \< construct
* \> and/or ending with a \> construct, restricts the
* pattern matching to the beginning of a word, and/or
* the end of a word. A word is defined to be a character
* string beginning and/or ending with the characters
* A-Z a-z 0-9 and _. It must also be preceded and/or
* followed by any character outside those mentioned.
*
* [10] a composite regular expression xy where x and y
* are in the form [1] to [10] matches the longest
* match of x followed by a match for y.
*
* [11] ^ a regular expression starting with a ^ character
* $ and/or ending with a $ character, restricts the
* pattern matching to the beginning of the line,
* or the end of line. [anchors] Elsewhere in the
* pattern, ^ and $ are treated as ordinary characters.
*
*
* Acknowledgements:
*
* HCR's Hugh Redelmeier has been most helpful in various
* stages of development. He convinced me to include BOW
* and EOW constructs, originally invented by Rob Pike at
* the University of Toronto.
*
* References:
* Software tools Kernighan & Plauger
* Software tools in Pascal Kernighan & Plauger
* Grep [rsx-11 C dist] David Conroy
* ed - text editor Un*x Programmer's Manual
* Advanced editing on Un*x B. W. Kernighan
* RegExp routines Henry Spencer
*
* Notes:
*
* This implementation uses a bit-set representation for character
* classes for speed and compactness. Each character is represented
* by one bit in a 128-bit block. Thus, CCL always takes a
* constant 16 bytes in the internal nfa, and re_exec does a single
* bit comparison to locate the character in the set.
*
* Examples:
*
* pattern: foo*.*
* compile: CHR f CHR o CLO CHR o END CLO ANY END END
* matches: fo foo fooo foobar fobar foxx ...
*
* pattern: fo[ob]a[rz]
* compile: CHR f CHR o CCL bitset CHR a CCL bitset END
* matches: fobar fooar fobaz fooaz
*
* pattern: foo\\+
* compile: CHR f CHR o CHR o CHR \ CLO CHR \ END END
* matches: foo\ foo\\ foo\\\ ...
*
* pattern: \(foo\)[1-3]\1 (same as foo[1-3]foo)
* compile: BOT 1 CHR f CHR o CHR o EOT 1 CCL bitset REF 1 END
* matches: foo1foo foo2foo foo3foo
*
* pattern: \(fo.*\)-\1
* compile: BOT 1 CHR f CHR o CLO ANY END EOT 1 CHR - REF 1 END
* matches: foo-foo fo-fo fob-fob foobar-foobar ...
*/
#define MAXNFA 1024
#define MAXTAG 10
#define OKP 1
#define NOP 0
#define CHR 1
#define ANY 2
#define CCL 3
#define BOL 4
#define EOL 5
#define BOT 6
#define EOT 7
#define BOW 8
#define EOW 9
#define REF 10
#define CLO 11
#define END 0
/*
* The following defines are not meant to be changeable.
* They are for readability only.
*/
#define MAXCHR 128
#define CHRBIT 8
#define BITBLK MAXCHR/CHRBIT
#define BLKIND 0170
#define BITIND 07
#define ASCIIB 0177
/* Plain char, on the other hand, may be signed or unsigned; it depends on
* the platform and perhaps a compiler option. A hard fact of life, in C.
*
* 6-April-1999 mcs@netscape.com: replaced CHAR with REGEXCHAR to avoid
* conflicts with system types on Win32. Changed typedef
* for REGEXCHAR to always be unsigned, which seems right.
*/
typedef unsigned char REGEXCHAR;
static int tagstk[MAXTAG]; /* subpat tag stack..*/
static REGEXCHAR nfa[MAXNFA]; /* automaton.. */
static int sta = NOP; /* status of lastpat */
static REGEXCHAR bittab[BITBLK]; /* bit table for CCL */
/* pre-set bits... */
static REGEXCHAR bitarr[] = {1,2,4,8,16,32,64,128};
static void
chset(REGEXCHAR c)
{
bittab[((c) & (unsigned)BLKIND) >> 3] |= bitarr[(c) & BITIND];
}
#define badpat(x) (*nfa = END, x)
#define store(x) *mp++ = x
char *
LDAP_CALL
re_comp( const char *pat )
{
register REGEXCHAR *p; /* pattern pointer */
register REGEXCHAR *mp=nfa; /* nfa pointer */
register REGEXCHAR *lp; /* saved pointer.. */
register REGEXCHAR *sp=nfa; /* another one.. */
register int tagi = 0; /* tag stack index */
register int tagc = 1; /* actual tag count */
register int n;
register REGEXCHAR mask; /* xor mask -CCL/NCL */
int c1, c2;
if (!pat || !*pat) {
if (sta) {
return 0;
} else {
return badpat("No previous regular expression");
}
}
sta = NOP;
for (p = (REGEXCHAR*)pat; *p; p++) {
lp = mp;
switch(*p) {
case '.': /* match any char.. */
store(ANY);
break;
case '^': /* match beginning.. */
if (p == (REGEXCHAR*)pat)
store(BOL);
else {
store(CHR);
store(*p);
}
break;
case '$': /* match endofline.. */
if (!*(p+1))
store(EOL);
else {
store(CHR);
store(*p);
}
break;
case '[': /* match char class..*/
store(CCL);
if (*++p == '^') {
mask = 0377;
p++;
}
else
mask = 0;
if (*p == '-') /* real dash */
chset(*p++);
if (*p == ']') /* real brac */
chset(*p++);
while (*p && *p != ']') {
if (*p == '-' && *(p+1) && *(p+1) != ']') {
p++;
c1 = *(p-2) + 1;
c2 = *p++;
while (c1 <= c2)
chset((REGEXCHAR)c1++);
}
#ifdef EXTEND
else if (*p == '\\' && *(p+1)) {
p++;
chset(*p++);
}
#endif
else
chset(*p++);
}
if (!*p)
return badpat("Missing ]");
for (n = 0; n < BITBLK; bittab[n++] = (REGEXCHAR) 0)
store(mask ^ bittab[n]);
break;
case '*': /* match 0 or more.. */
case '+': /* match 1 or more.. */
if (p == (REGEXCHAR*)pat)
return badpat("Empty closure");
lp = sp; /* previous opcode */
if (*lp == CLO) /* equivalence.. */
break;
switch(*lp) {
case BOL:
case BOT:
case EOT:
case BOW:
case EOW:
case REF:
return badpat("Illegal closure");
default:
break;
}
if (*p == '+')
for (sp = mp; lp < sp; lp++)
store(*lp);
store(END);
store(END);
sp = mp;
while (--mp > lp)
*mp = mp[-1];
store(CLO);
mp = sp;
break;
case '\\': /* tags, backrefs .. */
switch(*++p) {
case '(':
if (tagc < MAXTAG) {
tagstk[++tagi] = tagc;
store(BOT);
store(tagc++);
}
else
return badpat("Too many \\(\\) pairs");
break;
case ')':
if (*sp == BOT)
return badpat("Null pattern inside \\(\\)");
if (tagi > 0) {
store(EOT);
store(tagstk[tagi--]);
}
else
return badpat("Unmatched \\)");
break;
case '<':
store(BOW);
break;
case '>':
if (*sp == BOW)
return badpat("Null pattern inside \\<\\>");
store(EOW);
break;
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9':
n = *p-'0';
if (tagi > 0 && tagstk[tagi] == n)
return badpat("Cyclical reference");
if (tagc > n) {
store(REF);
store(n);
}
else
return badpat("Undetermined reference");
break;
#ifdef EXTEND
case 'b':
store(CHR);
store('\b');
break;
case 'n':
store(CHR);
store('\n');
break;
case 'f':
store(CHR);
store('\f');
break;
case 'r':
store(CHR);
store('\r');
break;
case 't':
store(CHR);
store('\t');
break;
#endif
default:
store(CHR);
store(*p);
}
break;
default : /* an ordinary char */
store(CHR);
store(*p);
break;
}
sp = lp;
}
if (tagi > 0)
return badpat("Unmatched \\(");
store(END);
sta = OKP;
return 0;
}
static REGEXCHAR *bol;
static REGEXCHAR *bopat[MAXTAG];
static REGEXCHAR *eopat[MAXTAG];
#ifdef NEEDPROTOS
static REGEXCHAR *pmatch( REGEXCHAR *lp, REGEXCHAR *ap );
#else /* NEEDPROTOS */
static REGEXCHAR *pmatch();
#endif /* NEEDPROTOS */
/*
* re_exec:
* execute nfa to find a match.
*
* special cases: (nfa[0])
* BOL
* Match only once, starting from the
* beginning.
* CHR
* First locate the character without
* calling pmatch, and if found, call
* pmatch for the remaining string.
* END
* re_comp failed, poor luser did not
* check for it. Fail fast.
*
* If a match is found, bopat[0] and eopat[0] are set
* to the beginning and the end of the matched fragment,
* respectively.
*
*/
int
LDAP_CALL
re_exec( const char *lp )
{
register REGEXCHAR c;
register REGEXCHAR *ep = 0;
register REGEXCHAR *ap = nfa;
bol = (REGEXCHAR*)lp;
bopat[0] = 0;
bopat[1] = 0;
bopat[2] = 0;
bopat[3] = 0;
bopat[4] = 0;
bopat[5] = 0;
bopat[6] = 0;
bopat[7] = 0;
bopat[8] = 0;
bopat[9] = 0;
switch(*ap) {
case BOL: /* anchored: match from BOL only */
ep = pmatch((REGEXCHAR*)lp,ap);
break;
case CHR: /* ordinary char: locate it fast */
c = *(ap+1);
while (*lp && *(REGEXCHAR*)lp != c)
lp++;
if (!*lp) /* if EOS, fail, else fall thru. */
return 0;
default: /* regular matching all the way. */
do {
if ((ep = pmatch((REGEXCHAR*)lp,ap)))
break;
lp++;
} while (*lp);
break;
case END: /* munged automaton. fail always */
return 0;
}
if (!ep)
return 0;
bopat[0] = (REGEXCHAR*)lp;
eopat[0] = ep;
return 1;
}
/*
* pmatch: internal routine for the hard part
*
* This code is partly snarfed from an early grep written by
* David Conroy. The backref and tag stuff, and various other
* innovations are by oz.
*
* special case optimizations: (nfa[n], nfa[n+1])
* CLO ANY
* We KNOW .* will match everything upto the
* end of line. Thus, directly go to the end of
* line, without recursive pmatch calls. As in
* the other closure cases, the remaining pattern
* must be matched by moving backwards on the
* string recursively, to find a match for xy
* (x is ".*" and y is the remaining pattern)
* where the match satisfies the LONGEST match for
* x followed by a match for y.
* CLO CHR
* We can again scan the string forward for the
* single char and at the point of failure, we
* execute the remaining nfa recursively, same as
* above.
*
* At the end of a successful match, bopat[n] and eopat[n]
* are set to the beginning and end of subpatterns matched
* by tagged expressions (n = 1 to 9).
*
*/
#ifndef re_fail
extern void re_fail();
#endif /* re_fail */
/*
* character classification table for word boundary operators BOW
* and EOW. the reason for not using ctype macros is that we can
* let the user add into our own table. see re_modw. This table
* is not in the bitset form, since we may wish to extend it in the
* future for other character classifications.
*
* TRUE for 0-9 A-Z a-z _
*/
static char chrtyp[MAXCHR] = {
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 0, 0,
0, 0, 0, 0, 0, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 0, 0, 0, 0, 1, 0, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 0, 0, 0, 0, 0
};
#define HIBIT 0200
#define inascii(x) (0177&(x))
#define iswordc(x) chrtyp[inascii(x)]
#define isinset(x,y) (((y)&HIBIT)?0:((x)[((y)&BLKIND)>>3] & bitarr[(y)&BITIND]))
/*
* skip values for CLO XXX to skip past the closure
*/
#define ANYSKIP 2 /* [CLO] ANY END ... */
#define CHRSKIP 3 /* [CLO] CHR chr END ... */
#define CCLSKIP 18 /* [CLO] CCL 16bytes END ... */
static REGEXCHAR *
pmatch( REGEXCHAR *lp, REGEXCHAR *ap)
{
register int op, c, n;
register REGEXCHAR *e; /* extra pointer for CLO */
register REGEXCHAR *bp; /* beginning of subpat.. */
register REGEXCHAR *ep; /* ending of subpat.. */
REGEXCHAR *are; /* to save the line ptr. */
while ((op = *ap++) != END)
switch(op) {
case CHR:
if (*lp++ != *ap++)
return 0;
break;
case ANY:
if (!*lp++)
return 0;
break;
case CCL:
c = *lp++;
if (!isinset(ap,c))
return 0;
ap += BITBLK;
break;
case BOL:
if (lp != bol)
return 0;
break;
case EOL:
if (*lp)
return 0;
break;
case BOT:
bopat[*ap++] = lp;
break;
case EOT:
eopat[*ap++] = lp;
break;
case BOW:
if ((lp!=bol && iswordc(lp[-1])) || !iswordc(*lp))
return 0;
break;
case EOW:
if (lp==bol || !iswordc(lp[-1]) || iswordc(*lp))
return 0;
break;
case REF:
n = *ap++;
bp = bopat[n];
ep = eopat[n];
while (bp < ep)
if (*bp++ != *lp++)
return 0;
break;
case CLO:
are = lp;
switch(*ap) {
case ANY:
while (*lp)
lp++;
n = ANYSKIP;
break;
case CHR:
c = *(ap+1);
while (*lp && c == *lp)
lp++;
n = CHRSKIP;
break;
case CCL:
while ((c = *lp) && isinset(ap+1,c))
lp++;
n = CCLSKIP;
break;
default:
re_fail("closure: bad nfa.", *ap);
return 0;
}
ap += n;
while (lp >= are) {
if ((e = pmatch(lp, ap)))
return e;
--lp;
}
return 0;
default:
re_fail("re_exec: bad nfa.", op);
return 0;
}
return lp;
}
/*
* re_modw:
* add new characters into the word table to change re_exec's
* understanding of what a word should look like. Note that we
* only accept additions into the word definition.
*
* If the string parameter is 0 or null string, the table is
* reset back to the default containing A-Z a-z 0-9 _. [We use
* the compact bitset representation for the default table]
*/
static REGEXCHAR deftab[16] = {
0, 0, 0, 0, 0, 0, 0377, 003, 0376, 0377, 0377, 0207,
0376, 0377, 0377, 007
};
void
LDAP_CALL
re_modw( char *s )
{
register int i;
if (!s || !*s) {
for (i = 0; i < MAXCHR; i++)
if (!isinset(deftab,i))
iswordc(i) = 0;
}
else
while(*s)
iswordc(*s++) = 1;
}
/*
* re_subs:
* substitute the matched portions of the src in dst.
*
* & substitute the entire matched pattern.
*
* \digit substitute a subpattern, with the given tag number.
* Tags are numbered from 1 to 9. If the particular
* tagged subpattern does not exist, null is substituted.
*/
int
LDAP_CALL
re_subs( char *src, char *dst)
{
register char c;
register int pin;
register REGEXCHAR *bp;
register REGEXCHAR *ep;
if (!*src || !bopat[0])
return 0;
while ((c = *src++)) {
switch(c) {
case '&':
pin = 0;
break;
case '\\':
c = *src++;
if (c >= '0' && c <= '9') {
pin = c - '0';
break;
}
default:
*dst++ = c;
continue;
}
if ((bp = bopat[pin]) && (ep = eopat[pin])) {
while (*bp && bp < ep)
*dst++ = *(char*)bp++;
if (bp < ep)
return 0;
}
}
*dst = (char) 0;
return 1;
}
#ifdef DEBUG
/* No printf or exit in 16-bit Windows */
#if defined( _WINDOWS ) && !defined( _WIN32 )
static int LDAP_C printf( const char* pszFormat, ...)
{
char buf[1024];
va_list arglist;
va_start(arglist, pszFormat);
vsprintf(buf, pszFormat, arglist);
va_end(arglist);
OutputDebugString(buf);
return 0;
}
#define exit(v) return
#endif /* 16-bit Windows */
#ifdef REGEX_DEBUG
static void nfadump( REGEXCHAR *ap);
/*
* symbolic - produce a symbolic dump of the nfa
*/
void
symbolic( char *s )
{
printf("pattern: %s\n", s);
printf("nfacode:\n");
nfadump(nfa);
}
static void
nfadump( REGEXCHAR *ap)
{
register int n;
while (*ap != END)
switch(*ap++) {
case CLO:
printf("CLOSURE");
nfadump(ap);
switch(*ap) {
case CHR:
n = CHRSKIP;
break;
case ANY:
n = ANYSKIP;
break;
case CCL:
n = CCLSKIP;
break;
}
ap += n;
break;
case CHR:
printf("\tCHR %c\n",*ap++);
break;
case ANY:
printf("\tANY .\n");
break;
case BOL:
printf("\tBOL -\n");
break;
case EOL:
printf("\tEOL -\n");
break;
case BOT:
printf("BOT: %d\n",*ap++);
break;
case EOT:
printf("EOT: %d\n",*ap++);
break;
case BOW:
printf("BOW\n");
break;
case EOW:
printf("EOW\n");
break;
case REF:
printf("REF: %d\n",*ap++);
break;
case CCL:
printf("\tCCL [");
for (n = 0; n < MAXCHR; n++)
if (isinset(ap,(REGEXCHAR)n)) {
if (n < ' ')
printf("^%c", n ^ 0x040);
else
printf("%c", n);
}
printf("]\n");
ap += BITBLK;
break;
default:
printf("bad nfa. opcode %o\n", ap[-1]);
exit(1);
break;
}
}
#endif /* REGEX_DEBUG */
#endif /* DEBUG */
#endif /* macintosh or DOS or _WINDOWS or NEED_BSDREGEX */

View file

@ -0,0 +1,265 @@
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is Mozilla Communicator client code, released
* March 31, 1998.
*
* The Initial Developer of the Original Code is
* Netscape Communications Corporation.
* Portions created by the Initial Developer are Copyright (C) 1998-1999
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
*
* Alternatively, the contents of this file may be used under the terms of
* either of the GNU General Public License Version 2 or later (the "GPL"),
* or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
/*
* Copyright (c) 1990 Regents of the University of Michigan.
* All rights reserved.
*/
/*
* rename.c
*/
#if 0
#ifndef lint
static char copyright[] = "@(#) Copyright (c) 1990 Regents of the University of Michigan.\nAll rights reserved.\n";
#endif
#endif
#include "ldap-int.h"
/*
* ldap_rename - initiate an ldap modifyDN operation. Parameters:
*
* ld LDAP descriptor
* dn DN of the object to modify
* newrdn RDN that will form leftmost component of entry's new name
* newparent if present, this is the Distinguished Name of the entry
* which becomes the immediate parent of the existing entry
* deleteoldrdn nonzero means to delete old rdn values from the entry
* while zero means to retain them as attributes of the entry
* serverctrls list of LDAP server controls
* clientctrls list of client controls
* msgidp this result parameter will be set to the message id of the
* request if the ldap_rename() call succeeds
*
* Example:
* int rc;
* rc = ldap_rename( ld, dn, newrdn, newparent, deleteoldrdn, serverctrls, clientctrls, &msgid );
*/
int
LDAP_CALL
ldap_rename(
LDAP *ld,
const char *dn,
const char *newrdn,
const char *newparent,
int deleteoldrdn,
LDAPControl **serverctrls,
LDAPControl **clientctrls, /* not used for anything yet */
int *msgidp
)
{
BerElement *ber;
int rc, err;
/*
* A modify dn request looks like this:
* ModifyDNRequest ::= SEQUENCE {
* entry LDAPDN,
* newrdn RelativeLDAPDN,
* newparent [0] LDAPDN OPTIONAL,
* deleteoldrdn BOOLEAN
* }
*/
LDAPDebug( LDAP_DEBUG_TRACE, "ldap_rename\n", 0, 0, 0 );
if ( !NSLDAPI_VALID_LDAP_POINTER( ld )) {
return( LDAP_PARAM_ERROR );
}
if ( NULL == newrdn) {
LDAP_SET_LDERRNO( ld, LDAP_PARAM_ERROR, NULL, NULL );
return( LDAP_PARAM_ERROR );
}
/* only ldapv3 or higher can do a proper rename
* (i.e. with non-NULL newparent and/or controls)
*/
if (( NSLDAPI_LDAP_VERSION( ld ) < LDAP_VERSION3 )
&& ((newparent != NULL) || (serverctrls != NULL)
|| (clientctrls != NULL))) {
LDAP_SET_LDERRNO( ld, LDAP_NOT_SUPPORTED, NULL, NULL );
return( LDAP_NOT_SUPPORTED );
}
if ( msgidp == NULL ) {
LDAP_SET_LDERRNO( ld, LDAP_PARAM_ERROR, NULL, NULL );
return( LDAP_PARAM_ERROR );
}
LDAP_MUTEX_LOCK( ld, LDAP_MSGID_LOCK );
*msgidp = ++ld->ld_msgid;
LDAP_MUTEX_UNLOCK( ld, LDAP_MSGID_LOCK );
/* see if modRDN or modDN is handled by the cache */
if ( ld->ld_cache_on ) {
if ( newparent == NULL && ld->ld_cache_modrdn != NULL ) {
LDAP_MUTEX_LOCK( ld, LDAP_CACHE_LOCK );
if ( (rc = (ld->ld_cache_modrdn)( ld, *msgidp,
LDAP_REQ_MODRDN, dn, newrdn, deleteoldrdn ))
!= 0 ) {
*msgidp = rc;
LDAP_MUTEX_UNLOCK( ld, LDAP_CACHE_LOCK );
return( LDAP_SUCCESS );
}
LDAP_MUTEX_UNLOCK( ld, LDAP_CACHE_LOCK );
#if 0
} else if ( ld->ld_cache_rename != NULL ) {
LDAP_MUTEX_LOCK( ld, LDAP_CACHE_LOCK );
if ( (rc = (ld->ld_cache_rename)( ld, *msgidp,
LDAP_REQ_MODDN, dn, newrdn, newparent,
deleteoldrdn )) != 0 ) {
*msgidp = rc;
return( LDAP_SUCCESS );
}
LDAP_MUTEX_UNLOCK( ld, LDAP_CACHE_LOCK );
#endif
}
}
/* create a message to send */
if (( err = nsldapi_alloc_ber_with_options( ld, &ber ))
!= LDAP_SUCCESS ) {
return( err );
}
/* fill it in */
if ( ber_printf( ber, "{it{ssb", *msgidp, LDAP_REQ_MODDN, dn,
newrdn, deleteoldrdn ) == -1 ) {
LDAP_SET_LDERRNO( ld, LDAP_ENCODING_ERROR, NULL, NULL );
ber_free( ber, 1 );
return( LDAP_ENCODING_ERROR );
}
if ( newparent == NULL ) {
if ( ber_printf( ber, "}" ) == -1 ) {
LDAP_SET_LDERRNO( ld, LDAP_ENCODING_ERROR, NULL, NULL );
ber_free( ber, 1 );
return( LDAP_ENCODING_ERROR );
}
} else {
if ( ber_printf( ber, "ts}", LDAP_TAG_NEWSUPERIOR, newparent )
== -1 ) {
LDAP_SET_LDERRNO( ld, LDAP_ENCODING_ERROR, NULL, NULL );
ber_free( ber, 1 );
return( LDAP_ENCODING_ERROR );
}
}
if (( rc = nsldapi_put_controls( ld, serverctrls, 1, ber ))
!= LDAP_SUCCESS ) {
ber_free( ber, 1 );
return( rc );
}
/* send the message */
rc = nsldapi_send_initial_request( ld, *msgidp, LDAP_REQ_MODDN,
(char *) dn, ber );
*msgidp = rc;
return( rc < 0 ? LDAP_GET_LDERRNO( ld, NULL, NULL ) : LDAP_SUCCESS );
}
int
LDAP_CALL
ldap_modrdn2( LDAP *ld, const char *dn, const char *newrdn, int deleteoldrdn )
{
int msgid;
if ( ldap_rename( ld, dn, newrdn, NULL, deleteoldrdn, NULL, NULL, &msgid ) == LDAP_SUCCESS ) {
return( msgid );
} else {
return( -1 ); /* error is in ld handle */
}
}
int
LDAP_CALL
ldap_modrdn( LDAP *ld, const char *dn, const char *newrdn )
{
return( ldap_modrdn2( ld, dn, newrdn, 1 ) );
}
int
LDAP_CALL
ldap_rename_s(
LDAP *ld,
const char *dn,
const char *newrdn,
const char *newparent,
int deleteoldrdn,
LDAPControl **serverctrls,
LDAPControl **clientctrls /* not used for anything yet */
)
{
int msgid;
LDAPMessage *res;
if ( ldap_rename( ld, dn, newrdn, newparent, deleteoldrdn, serverctrls, clientctrls, &msgid ) != LDAP_SUCCESS ) {
return( LDAP_GET_LDERRNO( ld, NULL, NULL ) );
}
if ( msgid == -1 )
return( LDAP_GET_LDERRNO( ld, NULL, NULL ) );
if ( ldap_result( ld, msgid, 1, (struct timeval *) NULL, &res ) == -1 )
return( LDAP_GET_LDERRNO( ld, NULL, NULL ) );
return( ldap_result2error( ld, res, 1 ) );
}
int
LDAP_CALL
ldap_modrdn2_s( LDAP *ld, const char *dn, const char *newrdn, int deleteoldrdn )
{
int msgid;
LDAPMessage *res;
if ( (msgid = ldap_modrdn2( ld, dn, newrdn, deleteoldrdn )) == -1 )
return( LDAP_GET_LDERRNO( ld, NULL, NULL ) );
if ( ldap_result( ld, msgid, 1, (struct timeval *) NULL, &res ) == -1 )
return( LDAP_GET_LDERRNO( ld, NULL, NULL ) );
return( ldap_result2error( ld, res, 1 ) );
}
int
LDAP_CALL
ldap_modrdn_s( LDAP *ld, const char *dn, const char *newrdn )
{
return( ldap_modrdn2_s( ld, dn, newrdn, 1 ) );
}

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,86 @@
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is Mozilla Communicator client code, released
* March 31, 1998.
*
* The Initial Developer of the Original Code is
* Netscape Communications Corporation.
* Portions created by the Initial Developer are Copyright (C) 1998-1999
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
*
* Alternatively, the contents of this file may be used under the terms of
* either of the GNU General Public License Version 2 or later (the "GPL"),
* or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
/*
* Copyright (c) 1990 Regents of the University of Michigan.
* All rights reserved.
*/
/*
* reslist.c
*/
#if 0
#ifndef lint
static char copyright[] = "@(#) Copyright (c) 1990 Regents of the University of Michigan.\nAll rights reserved.\n";
#endif
#endif
#include "ldap-int.h"
LDAPMessage *
LDAP_CALL
ldap_delete_result_entry( LDAPMessage **list, LDAPMessage *e )
{
LDAPMessage *tmp, *prev = NULL;
if ( list == NULL || e == NULL ) {
return( NULL );
}
for ( tmp = *list; tmp != NULL && tmp != e; tmp = tmp->lm_chain )
prev = tmp;
if ( tmp == NULL )
return( NULL );
if ( prev == NULL )
*list = tmp->lm_chain;
else
prev->lm_chain = tmp->lm_chain;
tmp->lm_chain = NULL;
return( tmp );
}
void
LDAP_CALL
ldap_add_result_entry( LDAPMessage **list, LDAPMessage *e )
{
if ( list != NULL && e != NULL ) {
e->lm_chain = *list;
*list = e;
}
}

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,877 @@
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is Mozilla Communicator client code, released
* March 31, 1998.
*
* The Initial Developer of the Original Code is
* Netscape Communications Corporation.
* Portions created by the Initial Developer are Copyright (C) 1998-1999
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
*
* Alternatively, the contents of this file may be used under the terms of
* either of the GNU General Public License Version 2 or later (the "GPL"),
* or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
#include "ldap-int.h"
#ifdef LDAP_SASLIO_HOOKS
/*
* Global SASL Init data
*/
static int
nsldapi_sasl_fail()
{
return( SASL_FAIL );
}
sasl_callback_t client_callbacks[] = {
{ SASL_CB_GETOPT, nsldapi_sasl_fail, NULL },
{ SASL_CB_GETREALM, NULL, NULL },
{ SASL_CB_USER, NULL, NULL },
{ SASL_CB_CANON_USER, NULL, NULL },
{ SASL_CB_AUTHNAME, NULL, NULL },
{ SASL_CB_PASS, NULL, NULL },
{ SASL_CB_ECHOPROMPT, NULL, NULL },
{ SASL_CB_NOECHOPROMPT, NULL, NULL },
{ SASL_CB_LIST_END, NULL, NULL }
};
int
nsldapi_sasl_cvterrno( LDAP *ld, int err, char *msg )
{
int rc = LDAP_LOCAL_ERROR;
switch (err) {
case SASL_OK:
rc = LDAP_SUCCESS;
break;
case SASL_NOMECH:
rc = LDAP_AUTH_UNKNOWN;
break;
case SASL_BADSERV:
rc = LDAP_CONNECT_ERROR;
break;
case SASL_DISABLED:
case SASL_ENCRYPT:
case SASL_EXPIRED:
case SASL_NOUSERPASS:
case SASL_NOVERIFY:
case SASL_PWLOCK:
case SASL_TOOWEAK:
case SASL_UNAVAIL:
case SASL_WEAKPASS:
rc = LDAP_INAPPROPRIATE_AUTH;
break;
case SASL_BADAUTH:
case SASL_NOAUTHZ:
rc = LDAP_INVALID_CREDENTIALS;
break;
case SASL_NOMEM:
rc = LDAP_NO_MEMORY;
break;
case SASL_NOUSER:
rc = LDAP_NO_SUCH_OBJECT;
break;
case SASL_CONTINUE:
case SASL_FAIL:
case SASL_INTERACT:
default:
rc = LDAP_LOCAL_ERROR;
break;
}
LDAP_SET_LDERRNO( ld, rc, NULL, msg );
return( rc );
}
#ifdef LDAP_SASLIO_GET_MECHS_FROM_SERVER
/*
* Get available SASL Mechanisms supported by the server
*/
static int
nsldapi_get_sasl_mechs ( LDAP *ld, char **pmech )
{
char *attr[] = { "supportedSASLMechanisms", NULL };
char **values, **v, *mech, *m;
LDAPMessage *res, *e;
struct timeval timeout;
int slen, rc;
if ( !NSLDAPI_VALID_LDAP_POINTER( ld )) {
return( LDAP_PARAM_ERROR );
}
timeout.tv_sec = SEARCH_TIMEOUT_SECS;
timeout.tv_usec = 0;
rc = ldap_search_st( ld, "", LDAP_SCOPE_BASE,
"objectclass=*", attr, 0, &timeout, &res );
if ( rc != LDAP_SUCCESS ) {
return( LDAP_GET_LDERRNO( ld, NULL, NULL ) );
}
e = ldap_first_entry( ld, res );
if ( e == NULL ) {
ldap_msgfree( res );
if ( ld->ld_errno == LDAP_SUCCESS ) {
LDAP_SET_LDERRNO( ld, LDAP_NO_SUCH_OBJECT, NULL, NULL );
}
return( LDAP_GET_LDERRNO( ld, NULL, NULL ) );
}
values = ldap_get_values( ld, e, "supportedSASLMechanisms" );
if ( values == NULL ) {
ldap_msgfree( res );
LDAP_SET_LDERRNO( ld, LDAP_NO_SUCH_ATTRIBUTE, NULL, NULL );
return( LDAP_NO_SUCH_ATTRIBUTE );
}
slen = 0;
for(v = values; *v != NULL; v++ ) {
slen += strlen(*v) + 1;
}
if ( (mech = NSLDAPI_CALLOC(1, slen)) == NULL) {
ldap_value_free( values );
ldap_msgfree( res );
LDAP_SET_LDERRNO( ld, LDAP_NO_MEMORY, NULL, NULL );
return( LDAP_NO_MEMORY );
}
m = mech;
for(v = values; *v; v++) {
if (v != values) {
*m++ = ' ';
}
slen = strlen(*v);
strncpy(m, *v, slen);
m += slen;
}
*m = '\0';
ldap_value_free( values );
ldap_msgfree( res );
*pmech = mech;
return( LDAP_SUCCESS );
}
#endif /* LDAP_SASLIO_GET_MECHS_FROM_SERVER */
int
nsldapi_sasl_secprops(
const char *in,
sasl_security_properties_t *secprops )
{
int i;
char **props = NULL;
char *inp;
unsigned sflags = 0;
sasl_ssf_t max_ssf = 0;
sasl_ssf_t min_ssf = 0;
unsigned maxbufsize = 0;
int got_sflags = 0;
int got_max_ssf = 0;
int got_min_ssf = 0;
int got_maxbufsize = 0;
if (in == NULL) {
return LDAP_PARAM_ERROR;
}
inp = nsldapi_strdup(in);
if (inp == NULL) {
return LDAP_PARAM_ERROR;
}
props = ldap_str2charray( inp, "," );
NSLDAPI_FREE( inp );
if( props == NULL || secprops == NULL ) {
return LDAP_PARAM_ERROR;
}
for( i=0; props[i]; i++ ) {
if( strcasecmp(props[i], "none") == 0 ) {
got_sflags++;
} else if( strcasecmp(props[i], "noactive") == 0 ) {
got_sflags++;
sflags |= SASL_SEC_NOACTIVE;
} else if( strcasecmp(props[i], "noanonymous") == 0 ) {
got_sflags++;
sflags |= SASL_SEC_NOANONYMOUS;
} else if( strcasecmp(props[i], "nodict") == 0 ) {
got_sflags++;
sflags |= SASL_SEC_NODICTIONARY;
} else if( strcasecmp(props[i], "noplain") == 0 ) {
got_sflags++;
sflags |= SASL_SEC_NOPLAINTEXT;
} else if( strcasecmp(props[i], "forwardsec") == 0 ) {
got_sflags++;
sflags |= SASL_SEC_FORWARD_SECRECY;
} else if( strcasecmp(props[i], "passcred") == 0 ) {
got_sflags++;
sflags |= SASL_SEC_PASS_CREDENTIALS;
} else if( strncasecmp(props[i],
"minssf=", sizeof("minssf")) == 0 ) {
if( isdigit( props[i][sizeof("minssf")] ) ) {
got_min_ssf++;
min_ssf = atoi( &props[i][sizeof("minssf")] );
} else {
return LDAP_NOT_SUPPORTED;
}
} else if( strncasecmp(props[i],
"maxssf=", sizeof("maxssf")) == 0 ) {
if( isdigit( props[i][sizeof("maxssf")] ) ) {
got_max_ssf++;
max_ssf = atoi( &props[i][sizeof("maxssf")] );
} else {
return LDAP_NOT_SUPPORTED;
}
} else if( strncasecmp(props[i],
"maxbufsize=", sizeof("maxbufsize")) == 0 ) {
if( isdigit( props[i][sizeof("maxbufsize")] ) ) {
got_maxbufsize++;
maxbufsize = atoi( &props[i][sizeof("maxbufsize")] );
if( maxbufsize &&
(( maxbufsize < SASL_MIN_BUFF_SIZE )
|| (maxbufsize > SASL_MAX_BUFF_SIZE ))) {
return( LDAP_PARAM_ERROR );
}
} else {
return( LDAP_NOT_SUPPORTED );
}
} else {
return( LDAP_NOT_SUPPORTED );
}
}
if(got_sflags) {
secprops->security_flags = sflags;
}
if(got_min_ssf) {
secprops->min_ssf = min_ssf;
}
if(got_max_ssf) {
secprops->max_ssf = max_ssf;
}
if(got_maxbufsize) {
secprops->maxbufsize = maxbufsize;
}
ldap_charray_free( props );
return( LDAP_SUCCESS );
}
#endif /* LDAP_SASLIO_HOOKS */
static int
nsldapi_sasl_bind_s(
LDAP *ld,
const char *dn,
const char *mechanism,
const struct berval *cred,
LDAPControl **serverctrls,
LDAPControl **clientctrls,
struct berval **servercredp,
LDAPControl ***responsectrls
)
{
int err, msgid;
LDAPMessage *result;
LDAPDebug( LDAP_DEBUG_TRACE, "nsldapi_sasl_bind_s\n", 0, 0, 0 );
if ( !NSLDAPI_VALID_LDAP_POINTER( ld )) {
return( LDAP_PARAM_ERROR );
}
if ( NSLDAPI_LDAP_VERSION( ld ) < LDAP_VERSION3 ) {
LDAP_SET_LDERRNO( ld, LDAP_NOT_SUPPORTED, NULL, NULL );
return( LDAP_NOT_SUPPORTED );
}
if ( ( err = ldap_sasl_bind( ld, dn, mechanism, cred, serverctrls,
clientctrls, &msgid )) != LDAP_SUCCESS )
return( err );
if ( ldap_result( ld, msgid, 1, (struct timeval *) 0, &result ) == -1 )
return( LDAP_GET_LDERRNO( ld, NULL, NULL ) );
/* Get the controls sent by the server if requested */
if ( responsectrls ) {
if ( ( err = ldap_parse_result( ld, result, &err, NULL, NULL,
NULL, responsectrls, 0 )) != LDAP_SUCCESS )
return( err );
}
err = ldap_parse_sasl_bind_result( ld, result, servercredp, 0 );
if (err != LDAP_SUCCESS && err != LDAP_SASL_BIND_IN_PROGRESS) {
ldap_msgfree( result );
return( err );
}
return( ldap_result2error( ld, result, 1 ) );
}
#ifdef LDAP_SASLIO_HOOKS
static int
nsldapi_sasl_do_bind( LDAP *ld, const char *dn,
const char *mechs, unsigned flags,
LDAP_SASL_INTERACT_PROC *callback, void *defaults,
LDAPControl **sctrl, LDAPControl **cctrl, LDAPControl ***rctrl )
{
sasl_interact_t *prompts = NULL;
sasl_conn_t *ctx = NULL;
sasl_ssf_t *ssf = NULL;
const char *mech = NULL;
int saslrc, rc;
struct berval ccred;
unsigned credlen;
int stepnum = 1;
char *sasl_username = NULL;
if (rctrl) {
/* init to NULL so we can call ldap_controls_free below */
*rctrl = NULL;
}
if (NSLDAPI_LDAP_VERSION( ld ) < LDAP_VERSION3) {
LDAP_SET_LDERRNO( ld, LDAP_NOT_SUPPORTED, NULL, NULL );
return( LDAP_NOT_SUPPORTED );
}
/* shouldn't happen */
if (callback == NULL) {
return( LDAP_LOCAL_ERROR );
}
if ( (rc = nsldapi_sasl_open(ld, NULL, &ctx, 0)) != LDAP_SUCCESS ) {
return( rc );
}
ccred.bv_val = NULL;
ccred.bv_len = 0;
LDAPDebug(LDAP_DEBUG_TRACE, "Starting SASL/%s authentication\n",
(mechs ? mechs : ""), 0, 0 );
do {
saslrc = sasl_client_start( ctx,
mechs,
&prompts,
(const char **)&ccred.bv_val,
&credlen,
&mech );
LDAPDebug(LDAP_DEBUG_TRACE, "Doing step %d of client start for SASL/%s authentication\n",
stepnum, (mech ? mech : ""), 0 );
stepnum++;
if( saslrc == SASL_INTERACT &&
(callback)(ld, flags, defaults, prompts) != LDAP_SUCCESS ) {
break;
}
} while ( saslrc == SASL_INTERACT );
ccred.bv_len = credlen;
if ( (saslrc != SASL_OK) && (saslrc != SASL_CONTINUE) ) {
return( nsldapi_sasl_cvterrno( ld, saslrc, nsldapi_strdup( sasl_errdetail( ctx ) ) ) );
}
stepnum = 1;
do {
struct berval *scred;
int clientstepnum = 1;
scred = NULL;
if (rctrl) {
/* if we're looping again, we need to free any controls set
during the previous loop */
/* NOTE that this assumes we only care about the controls
returned by the last call to nsldapi_sasl_bind_s - if
we care about _all_ controls, we will have to figure out
some way to append them each loop go round */
ldap_controls_free(*rctrl);
*rctrl = NULL;
}
LDAPDebug(LDAP_DEBUG_TRACE, "Doing step %d of bind for SASL/%s authentication\n",
stepnum, (mech ? mech : ""), 0 );
stepnum++;
/* notify server of a sasl bind step */
rc = nsldapi_sasl_bind_s(ld, dn, mech, &ccred,
sctrl, cctrl, &scred, rctrl);
if ( ccred.bv_val != NULL ) {
ccred.bv_val = NULL;
}
if ( rc != LDAP_SUCCESS && rc != LDAP_SASL_BIND_IN_PROGRESS ) {
ber_bvfree( scred );
return( rc );
}
if( rc == LDAP_SUCCESS && saslrc == SASL_OK ) {
/* we're done, no need to step */
if( scred ) {
if ( scred->bv_len == 0 ) { /* MS AD sends back empty screds */
LDAPDebug(LDAP_DEBUG_ANY,
"SASL BIND complete - ignoring empty credential response\n",
0, 0, 0);
ber_bvfree( scred );
} else {
/* but server provided us with data! */
LDAPDebug(LDAP_DEBUG_TRACE,
"SASL BIND complete but invalid because server responded with credentials - length [%u]\n",
scred->bv_len, 0, 0);
ber_bvfree( scred );
LDAP_SET_LDERRNO( ld, LDAP_LOCAL_ERROR,
NULL, "Error during SASL handshake - invalid server credential response" );
return( LDAP_LOCAL_ERROR );
}
}
break;
}
/* perform the next step of the sasl bind */
do {
LDAPDebug(LDAP_DEBUG_TRACE, "Doing client step %d of bind step %d for SASL/%s authentication\n",
clientstepnum, stepnum, (mech ? mech : "") );
clientstepnum++;
saslrc = sasl_client_step( ctx,
(scred == NULL) ? NULL : scred->bv_val,
(scred == NULL) ? 0 : scred->bv_len,
&prompts,
(const char **)&ccred.bv_val,
&credlen );
if( saslrc == SASL_INTERACT &&
(callback)(ld, flags, defaults, prompts)
!= LDAP_SUCCESS ) {
break;
}
} while ( saslrc == SASL_INTERACT );
ccred.bv_len = credlen;
ber_bvfree( scred );
if ( (saslrc != SASL_OK) && (saslrc != SASL_CONTINUE) ) {
return( nsldapi_sasl_cvterrno( ld, saslrc, nsldapi_strdup( sasl_errdetail( ctx ) ) ) );
}
} while ( rc == LDAP_SASL_BIND_IN_PROGRESS );
if ( rc != LDAP_SUCCESS ) {
return( rc );
}
if ( saslrc != SASL_OK ) {
return( nsldapi_sasl_cvterrno( ld, saslrc, nsldapi_strdup( sasl_errdetail( ctx ) ) ) );
}
saslrc = sasl_getprop( ctx, SASL_USERNAME, (const void **) &sasl_username );
if ( (saslrc == SASL_OK) && sasl_username ) {
LDAPDebug(LDAP_DEBUG_TRACE, "SASL identity: %s\n", sasl_username, 0, 0);
}
saslrc = sasl_getprop( ctx, SASL_SSF, (const void **) &ssf );
if( saslrc == SASL_OK ) {
if( ssf && *ssf ) {
LDAPDebug(LDAP_DEBUG_TRACE,
"SASL install encryption, for SSF: %lu\n",
(unsigned long) *ssf, 0, 0 );
nsldapi_sasl_install( ld, NULL );
}
}
return( rc );
}
#endif /* LDAP_SASLIO_HOOKS */
/*
* ldap_sasl_bind - authenticate to the ldap server. The dn, mechanism,
* and credentials of the entry to which to bind are supplied. An LDAP
* error code is returned and if LDAP_SUCCESS is returned *msgidp is set
* to the id of the request initiated.
*
* Example:
* struct berval creds;
* LDAPControl **ctrls;
* int err, msgid;
* ... fill in creds with credentials ...
* ... fill in ctrls with server controls ...
* err = ldap_sasl_bind( ld, "cn=manager, o=university of michigan, c=us",
* "mechanismname", &creds, ctrls, NULL, &msgid );
*/
int
LDAP_CALL
ldap_sasl_bind(
LDAP *ld,
const char *dn,
const char *mechanism,
const struct berval *cred,
LDAPControl **serverctrls,
LDAPControl **clientctrls,
int *msgidp
)
{
BerElement *ber;
int rc, simple, msgid, ldapversion;
/*
* The ldapv3 bind request looks like this:
* BindRequest ::= SEQUENCE {
* version INTEGER,
* name DistinguishedName, -- who
* authentication CHOICE {
* simple [0] OCTET STRING, -- passwd
* sasl [3] SaslCredentials -- v3 only
* }
* }
* SaslCredentials ::= SEQUENCE {
* mechanism LDAPString,
* credentials OCTET STRING
* }
* all wrapped up in an LDAPMessage sequence.
*/
LDAPDebug( LDAP_DEBUG_TRACE, "ldap_sasl_bind\n", 0, 0, 0 );
if ( !NSLDAPI_VALID_LDAP_POINTER( ld )) {
return( LDAP_PARAM_ERROR );
}
if ( msgidp == NULL ) {
LDAP_SET_LDERRNO( ld, LDAP_PARAM_ERROR, NULL, NULL );
return( LDAP_PARAM_ERROR );
}
if ( ( ld->ld_options & LDAP_BITOPT_RECONNECT ) != 0 ) {
nsldapi_handle_reconnect( ld );
}
simple = ( mechanism == LDAP_SASL_SIMPLE );
ldapversion = NSLDAPI_LDAP_VERSION( ld );
/* only ldapv3 or higher can do sasl binds */
if ( !simple && ldapversion < LDAP_VERSION3 ) {
LDAP_SET_LDERRNO( ld, LDAP_NOT_SUPPORTED, NULL, NULL );
return( LDAP_NOT_SUPPORTED );
}
LDAP_MUTEX_LOCK( ld, LDAP_MSGID_LOCK );
msgid = ++ld->ld_msgid;
LDAP_MUTEX_UNLOCK( ld, LDAP_MSGID_LOCK );
if ( dn == NULL )
dn = "";
if ( ld->ld_cache_on && ld->ld_cache_bind != NULL ) {
LDAP_MUTEX_LOCK( ld, LDAP_CACHE_LOCK );
if ( (rc = (ld->ld_cache_bind)( ld, msgid, LDAP_REQ_BIND, dn,
cred, LDAP_AUTH_SASL )) != 0 ) {
*msgidp = rc;
LDAP_MUTEX_UNLOCK( ld, LDAP_CACHE_LOCK );
return( LDAP_SUCCESS );
}
LDAP_MUTEX_UNLOCK( ld, LDAP_CACHE_LOCK );
}
/* create a message to send */
if (( rc = nsldapi_alloc_ber_with_options( ld, &ber ))
!= LDAP_SUCCESS ) {
return( rc );
}
/* fill it in */
if ( simple ) { /* simple bind; works in LDAPv2 or v3 */
struct berval tmpcred;
if ( cred == NULL ) {
tmpcred.bv_val = "";
tmpcred.bv_len = 0;
cred = &tmpcred;
}
rc = ber_printf( ber, "{it{isto}", msgid, LDAP_REQ_BIND,
ldapversion, dn, LDAP_AUTH_SIMPLE, cred->bv_val,
cred->bv_len );
} else { /* SASL bind; requires LDAPv3 or better */
if ( cred == NULL || cred->bv_val == NULL || cred->bv_len == 0) {
rc = ber_printf( ber, "{it{ist{s}}", msgid,
LDAP_REQ_BIND, ldapversion, dn, LDAP_AUTH_SASL,
mechanism );
} else {
rc = ber_printf( ber, "{it{ist{so}}", msgid,
LDAP_REQ_BIND, ldapversion, dn, LDAP_AUTH_SASL,
mechanism, cred->bv_val,
cred->bv_len );
}
}
if ( rc == -1 ) {
LDAP_SET_LDERRNO( ld, LDAP_ENCODING_ERROR, NULL, NULL );
ber_free( ber, 1 );
return( LDAP_ENCODING_ERROR );
}
if ( (rc = nsldapi_put_controls( ld, serverctrls, 1, ber ))
!= LDAP_SUCCESS ) {
ber_free( ber, 1 );
return( rc );
}
/* send the message */
rc = nsldapi_send_initial_request( ld, msgid, LDAP_REQ_BIND,
(char *)dn, ber );
*msgidp = rc;
return( rc < 0 ? LDAP_GET_LDERRNO( ld, NULL, NULL ) : LDAP_SUCCESS );
}
/*
* ldap_sasl_bind_s - bind to the ldap server using sasl authentication
* The dn, mechanism, and credentials of the entry to which to bind are
* supplied. LDAP_SUCCESS is returned upon success, the ldap error code
* otherwise.
*
* Example:
* struct berval creds;
* ... fill in creds with credentials ...
* ldap_sasl_bind_s( ld, "cn=manager, o=university of michigan, c=us",
* "mechanismname", &creds )
*/
int
LDAP_CALL
ldap_sasl_bind_s(
LDAP *ld,
const char *dn,
const char *mechanism,
const struct berval *cred,
LDAPControl **serverctrls,
LDAPControl **clientctrls,
struct berval **servercredp
)
{
return ( nsldapi_sasl_bind_s( ld, dn, mechanism, cred,
serverctrls, clientctrls, servercredp, NULL ) );
}
#ifdef LDAP_SASLIO_HOOKS
/*
* SASL Authentication Interface: ldap_sasl_interactive_bind_s
*
* This routine takes a DN, SASL mech list, and a SASL callback
* and performs the necessary sequencing to complete a SASL bind
* to the LDAP connection ld. The user provided callback can
* use an optionally provided set of default values to complete
* any necessary interactions.
*
* Currently imposes the following restrictions:
* A mech list must be provided
* LDAP_SASL_INTERACTIVE mode requires a callback
*/
int
LDAP_CALL
ldap_sasl_interactive_bind_s( LDAP *ld, const char *dn,
const char *saslMechanism,
LDAPControl **sctrl, LDAPControl **cctrl, unsigned flags,
LDAP_SASL_INTERACT_PROC *callback, void *defaults )
{
return ldap_sasl_interactive_bind_ext_s( ld, dn,
saslMechanism, sctrl, cctrl, flags, callback,
defaults, NULL );
}
/*
* ldap_sasl_interactive_bind_ext_s
*
* This function extends ldap_sasl_interactive_bind_s by allowing
* controls received from the server to be returned as rctrl. The
* caller must pass in a valid LDAPControl** pointer and free the
* array of controls when finished with them e.g.
* LDAPControl **retctrls = NULL;
* ...
* ldap_sasl_interactive_bind_ext_s(ld, ...., &retctrls);
* ...
* ldap_controls_free(retctrls);
* Only the controls from the server during the last bind step are returned -
* intermediate controls (if any, usually not) are discarded.
*/
int
LDAP_CALL
ldap_sasl_interactive_bind_ext_s( LDAP *ld, const char *dn,
const char *saslMechanism,
LDAPControl **sctrl, LDAPControl **cctrl, unsigned flags,
LDAP_SASL_INTERACT_PROC *callback, void *defaults, LDAPControl ***rctrl )
{
#ifdef LDAP_SASLIO_GET_MECHS_FROM_SERVER
char *smechs;
#endif
int rc;
LDAPDebug( LDAP_DEBUG_TRACE, "ldap_sasl_interactive_bind_s\n", 0, 0, 0 );
if ( !NSLDAPI_VALID_LDAP_POINTER( ld )) {
return( LDAP_PARAM_ERROR );
}
if ((flags == LDAP_SASL_INTERACTIVE) && (callback == NULL)) {
return( LDAP_PARAM_ERROR );
}
LDAP_MUTEX_LOCK(ld, LDAP_SASL_LOCK );
if( saslMechanism == NULL || *saslMechanism == '\0' ) {
#ifdef LDAP_SASLIO_GET_MECHS_FROM_SERVER
rc = nsldapi_get_sasl_mechs( ld, &smechs );
if( rc != LDAP_SUCCESS ) {
LDAP_MUTEX_UNLOCK(ld, LDAP_SASL_LOCK );
return( rc );
}
saslMechanism = smechs;
#else
LDAP_MUTEX_UNLOCK(ld, LDAP_SASL_LOCK );
return( LDAP_PARAM_ERROR );
#endif /* LDAP_SASLIO_GET_MECHS_FROM_SERVER */
}
rc = nsldapi_sasl_do_bind( ld, dn, saslMechanism,
flags, callback, defaults, sctrl, cctrl, rctrl);
LDAP_MUTEX_UNLOCK(ld, LDAP_SASL_LOCK );
return( rc );
}
#else /* LDAP_SASLIO_HOOKS */
/* stubs for platforms that do not support SASL */
int
LDAP_CALL
ldap_sasl_interactive_bind_s( LDAP *ld, const char *dn,
const char *saslMechanism,
LDAPControl **sctrl, LDAPControl **cctrl, unsigned flags,
LDAP_SASL_INTERACT_PROC *callback, void *defaults )
{
return LDAP_SUCCESS;
}
int
LDAP_CALL
ldap_sasl_interactive_bind_ext_s( LDAP *ld, const char *dn,
const char *saslMechanism,
LDAPControl **sctrl, LDAPControl **cctrl, unsigned flags,
LDAP_SASL_INTERACT_PROC *callback, void *defaults, LDAPControl ***rctrl )
{
return LDAP_SUCCESS;
}
#endif /* LDAP_SASLIO_HOOKS */
/* returns an LDAP error code that indicates if parse succeeded or not */
int
LDAP_CALL
ldap_parse_sasl_bind_result(
LDAP *ld,
LDAPMessage *res,
struct berval **servercredp,
int freeit
)
{
BerElement ber;
int rc, err;
ber_int_t along;
ber_len_t len;
char *m, *e;
LDAPDebug( LDAP_DEBUG_TRACE, "ldap_parse_sasl_bind_result\n", 0, 0, 0 );
/*
* the ldapv3 SASL bind response looks like this:
*
* BindResponse ::= [APPLICATION 1] SEQUENCE {
* COMPONENTS OF LDAPResult,
* serverSaslCreds [7] OCTET STRING OPTIONAL
* }
*
* all wrapped up in an LDAPMessage sequence.
*/
if ( !NSLDAPI_VALID_LDAP_POINTER( ld ) ||
!NSLDAPI_VALID_LDAPMESSAGE_BINDRESULT_POINTER( res )) {
return( LDAP_PARAM_ERROR );
}
/* only ldapv3 or higher can do sasl binds */
if ( NSLDAPI_LDAP_VERSION( ld ) < LDAP_VERSION3 ) {
LDAP_SET_LDERRNO( ld, LDAP_NOT_SUPPORTED, NULL, NULL );
return( LDAP_NOT_SUPPORTED );
}
if ( servercredp != NULL ) {
*servercredp = NULL;
}
ber = *(res->lm_ber); /* struct copy */
/* skip past message id, matched dn, error message ... */
rc = ber_scanf( &ber, "{iaa}", &along, &m, &e );
if ( rc != LBER_ERROR &&
ber_peek_tag( &ber, &len ) == LDAP_TAG_SASL_RES_CREDS ) {
rc = ber_get_stringal( &ber, servercredp );
}
if ( freeit ) {
ldap_msgfree( res );
}
if ( rc == LBER_ERROR ) {
err = LDAP_DECODING_ERROR;
} else {
err = (int) along;
}
LDAP_SET_LDERRNO( ld, err, m, e );
/* this is a little kludge for the 3.0 Barracuda/hammerhead relese */
/* the docs state that the return is either LDAP_DECODING_ERROR */
/* or LDAP_SUCCESS. Here we match the docs... it's cleaner in 3.1 */
if ( LDAP_DECODING_ERROR == err ) {
return (LDAP_DECODING_ERROR);
} else {
return( LDAP_SUCCESS );
}
}

View file

@ -0,0 +1,635 @@
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is Sun LDAP C SDK.
*
* The Initial Developer of the Original Code is Sun Microsystems, Inc.
*
* Portions created by Sun Microsystems, Inc are Copyright (C) 2005
* Sun Microsystems, Inc. All Rights Reserved.
*
* Contributor(s):
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
#ifdef LDAP_SASLIO_HOOKS
#include <assert.h>
#include "ldap-int.h"
#include "../liblber/lber-int.h"
#include <sasl.h>
/* Should be pulled in from lber-int.h */
#define READBUFSIZ 8192
#define SEARCH_TIMEOUT_SECS 120
#define NSLDAPI_SM_BUF 128
/*
* Data structures:
*/
/* data structure that populates the I/O callback socket-specific arg. */
typedef struct lextiof_socket_private {
struct ldap_x_ext_io_fns sess_io_fns; /* the saved layered ld fns from the layer we are "pushing" */
struct lber_x_ext_io_fns sock_io_fns; /* the saved layered ber fns from the layer we are "pushing" */
sasl_conn_t *sasl_ctx; /* the sasl context - pointer to the one from the connection */
char *sb_sasl_ibuf; /* sasl decrypted input buffer */
char *sb_sasl_iptr; /* current location in buffer */
int sb_sasl_bfsz; /* Alloc'd size of input buffer */
int sb_sasl_ilen; /* remaining length to process */
LDAP *ld; /* used to set errno */
Sockbuf *sb; /* pointer to our associated sockbuf */
} SASLIOSocketArg;
static void
destroy_SASLIOSocketArg(SASLIOSocketArg** sockarg)
{
if (sockarg && *sockarg) {
NSLDAPI_FREE((*sockarg)->sb_sasl_ibuf);
NSLDAPI_FREE((*sockarg));
*sockarg = NULL;
}
}
static SASLIOSocketArg*
new_SASLIOSocketArg(sasl_conn_t *ctx, int bufsiz, LDAP *ld, Sockbuf *sb)
{
SASLIOSocketArg *sockarg = NULL;
if (bufsiz <= 0) {
return sockarg;
}
sockarg = (SASLIOSocketArg*)NSLDAPI_CALLOC(1, sizeof(SASLIOSocketArg));
if (sockarg) {
sockarg->sasl_ctx = ctx;
sockarg->sb_sasl_ibuf = NSLDAPI_MALLOC(bufsiz);
if (!sockarg->sb_sasl_ibuf) {
destroy_SASLIOSocketArg(&sockarg);
return sockarg;
}
sockarg->sb_sasl_iptr = NULL;
sockarg->sb_sasl_bfsz = bufsiz;
sockarg->sb_sasl_ilen = 0;
sockarg->ld = ld;
sockarg->sb = sb;
}
return sockarg;
}
/*
* SASL Dependent routines
*
* SASL security and integrity options are supported through the
* use of the extended I/O functionality. Because the extended
* I/O functions may already be in use prior to enabling encryption,
* when SASL encryption si enabled, these routine interpose themselves
* over the exitng extended I/O routines and add an additional level
* of indirection.
* IE: Before SASL: client->libldap->lber->extio
* After SASL: client->libldap->lber->saslio->extio
* Any extio function are stilled used for the raw i/O [IE prldap]
* but SASL will decrypt before passing to lber.
* SASL cannot decrypt a stream so full packaets must be read
* before proceeding.
*/
/*
* Get the 4 octet header [size] for a sasl encrypted buffer.
* See RFC222 [section 3].
*/
static int
nsldapi_sasl_pktlen( char *buf, int maxbufsize )
{
int size;
#if defined( _WINDOWS ) || defined( _WIN32 )
size = ntohl(*(u_long *)buf);
#else
size = ntohl(*(uint32_t *)buf);
#endif
if ( size < 0 || size > maxbufsize ) {
return (-1 );
}
return( size + 4 ); /* include the first 4 bytes */
}
/*
* SASL encryption routines
*/
static int
nsldapi_sasl_read( int s, void *buf, int len,
struct lextiof_socket_private *arg)
{
LDAP *ld;
const char *dbuf;
char *cp;
int ret;
unsigned dlen, blen;
ld = (LDAP *)arg->ld;
/* Is there anything left in the existing buffer? */
if ((ret = arg->sb_sasl_ilen) > 0) {
ret = (ret > len ? len : ret);
SAFEMEMCPY( buf, arg->sb_sasl_iptr, ret );
if (ret == arg->sb_sasl_ilen) {
arg->sb_sasl_ilen = 0;
arg->sb_sasl_iptr = NULL;
} else {
arg->sb_sasl_ilen -= ret;
arg->sb_sasl_iptr += ret;
}
return( ret );
}
/* buffer is empty - fill it */
cp = arg->sb_sasl_ibuf;
dlen = 0;
/* Read the length of the packet */
while ( dlen < 4 ) {
if (arg->sock_io_fns.lbextiofn_read != NULL) {
ret = arg->sock_io_fns.lbextiofn_read(
s, cp, 4 - dlen,
arg->sock_io_fns.lbextiofn_socket_arg);
} else {
ret = read( s, cp, 4 - dlen );
}
#ifdef EINTR
if ( ( ret < 0 ) && ( LDAP_GET_ERRNO(ld) == EINTR ) )
continue;
#endif
if ( ret <= 0 )
return( ret );
cp += ret;
dlen += ret;
}
blen = 4;
ret = nsldapi_sasl_pktlen( arg->sb_sasl_ibuf, arg->sb_sasl_bfsz );
if (ret < 0) {
LDAP_SET_ERRNO(ld, EIO);
return( -1 );
}
dlen = ret - dlen;
/* read the rest of the encrypted packet */
while ( dlen > 0 ) {
if (arg->sock_io_fns.lbextiofn_read != NULL) {
ret = arg->sock_io_fns.lbextiofn_read(
s, cp, dlen,
arg->sock_io_fns.lbextiofn_socket_arg);
} else {
ret = read( s, cp, dlen );
}
#ifdef EINTR
if ( ( ret < 0 ) && ( LDAP_GET_ERRNO(ld) == EINTR ) )
continue;
#endif
if ( ret <= 0 )
return( ret );
cp += ret;
blen += ret;
dlen -= ret;
}
/* Decode the packet */
ret = sasl_decode( arg->sasl_ctx,
arg->sb_sasl_ibuf, blen,
&dbuf, &dlen);
if ( ret != SASL_OK ) {
/* sb_sasl_read: failed to decode packet, drop it, error */
arg->sb_sasl_iptr = NULL;
arg->sb_sasl_ilen = 0;
LDAP_SET_ERRNO(ld, EIO);
return( -1 );
}
/* copy decrypted packet to the input buffer */
SAFEMEMCPY( arg->sb_sasl_ibuf, dbuf, dlen );
arg->sb_sasl_iptr = arg->sb_sasl_ibuf;
arg->sb_sasl_ilen = dlen;
ret = (dlen > (unsigned) len ? len : dlen);
SAFEMEMCPY( buf, arg->sb_sasl_iptr, ret );
if (ret == arg->sb_sasl_ilen) {
arg->sb_sasl_ilen = 0;
arg->sb_sasl_iptr = NULL;
} else {
arg->sb_sasl_ilen -= ret;
arg->sb_sasl_iptr += ret;
}
return( ret );
}
static int
nsldapi_sasl_write( int s, const void *buf, int len,
struct lextiof_socket_private *arg)
{
int ret = 0;
const char *obuf, *optr, *cbuf = (const char *)buf;
unsigned olen, clen, tlen = 0;
unsigned *maxbuf;
ret = sasl_getprop(arg->sasl_ctx, SASL_MAXOUTBUF,
(const void **)&maxbuf);
if ( ret != SASL_OK ) {
/* just a sanity check, should never happen */
return( -1 );
}
while (len > 0) {
clen = (len > *maxbuf) ? *maxbuf : len;
/* encode the next packet. */
ret = sasl_encode( arg->sasl_ctx, cbuf, clen, &obuf, &olen);
if ( ret != SASL_OK ) {
/* XXX Log error? "sb_sasl_write: failed to encode packet..." */
return( -1 );
}
/* Write everything now, buffer is only good until next sasl_encode */
optr = obuf;
while (olen > 0) {
if (arg->sock_io_fns.lbextiofn_write != NULL) {
ret = arg->sock_io_fns.lbextiofn_write(
s, optr, olen,
arg->sock_io_fns.lbextiofn_socket_arg);
} else {
ret = write( s, optr, olen);
}
if ( ret < 0 )
return( ret );
optr += ret;
olen -= ret;
}
len -= clen;
cbuf += clen;
tlen += clen;
}
return( tlen );
}
/*
* What's all this then?
* First, take a look at os-ip.c:nsldapi_add_to_cb_pollfds(). When a new descriptor is
* added to the pollfds array, the lpoll_socketarg field is initialized to the value from
* the socketarg field - sb->sb_ext_io_fns.lbextiofn_socket_arg. In our case, since we
* override this with our sasl data (see below nsldapi_sasl_install), we need to restore
* the previous value so that the layer below us (i.e. prldap) can use the lpoll_socketarg
* which it sets.
* So how do which know which fds[i] is a "sasl" fd?
* We initialize the lextiof_session_private *arg (see nsldapi_sasl_install) to point to
* the socket_private data in sb->sb_ext_io_fns.lbextiofn_socket_arg for "sasl" sockets,
* which is then used to initialize lpoll_socketarg (see above).
* So, if the arg which gets passed into nsldapi_sasl_poll is the same as the
* fds[i].lpoll_socketarg, we know it is a "sasl" socket and we need to "pop" the sasl
* layer. We do this by replacing lpoll_socketarg with the one we saved when we "pushed"
* the sasl layer.
* So why the loop to restore the sasl lpoll_socketarg?
* The lower layer only uses lpoll_socketarg during poll(). See ldappr-io.c:prldap_poll()
* for more information about how that works. However, after the polling is done, there
* is some special magic in os-ip.c in the functions nsldapi_add_to_cb_pollfds(),
* nsldapi_clear_from_cb_pollfds(), and nsldapi_find_in_cb_pollfds() to find the correct
* Sockbuf to operate on. This is the macro NSLDAPI_CB_POLL_MATCH(). For the extended
* io function callbacks to work correctly, it is not sufficient to say that the file
* descriptor in the Sockbuf matches the one that poll says has activity - we also need
* to match the lpoll_socketarg with the sb->sb_ext_io_fns.lbextiofn_socket_arg to make
* sure this really is the Sockbuf we want to use. So we have to restore the
* lpoll_socketarg with the original one.
* Why have origarg and staticorigarg?
* To avoid malloc. The sizeof staticorigarg should be large enough to accomodate almost
* all clients without incurring too much additional overhead. However, if we need more
* room, origarg will grow to nfds. If this proves to be inadequate, the size of the
* staticorigarg is a good candidate for a #define set by configure.
*/
static int
nsldapi_sasl_poll(
LDAP_X_PollFD fds[], int nfds, int timeout,
struct lextiof_session_private *arg )
{
LDAP_X_EXTIOF_POLL_CALLBACK *origpoll; /* poll fn from the pushed layer */
struct lextiof_session_private *origsess = NULL; /* session arg from the pushed layer */
SASLIOSocketArg **origarg = NULL; /* list of saved original socket args */
SASLIOSocketArg *staticorigarg[1024]; /* default list to avoid malloc */
int origargsize = sizeof(staticorigarg)/sizeof(staticorigarg[0]);
int rc = -1; /* the return code - -1 means failure */
if (arg == NULL) { /* should not happen */
return( rc );
}
origarg = staticorigarg;
/* if the static array is not large enough, alloc a dynamic one */
if (origargsize < nfds) {
origarg = (SASLIOSocketArg **)NSLDAPI_MALLOC(nfds*sizeof(SASLIOSocketArg *));
}
if (fds && nfds > 0) {
int i;
for(i = 0; i < nfds; i++) {
/* save the original socket arg */
origarg[i] = fds[i].lpoll_socketarg;
if (arg == (struct lextiof_session_private *)fds[i].lpoll_socketarg) {
/* lpoll_socketarg is a sasl socket arg - we need to replace it
with the one from the layer we pushed (i.e. prldap) */
SASLIOSocketArg *sockarg = (SASLIOSocketArg *)fds[i].lpoll_socketarg;
/* reset to pushed layer's socket arg */
fds[i].lpoll_socketarg = sockarg->sock_io_fns.lbextiofn_socket_arg;
/* grab the pushed layers' poll fn and its session arg */
if (!origsess) {
origpoll = sockarg->sess_io_fns.lextiof_poll;
origsess = sockarg->sess_io_fns.lextiof_session_arg;
}
}
}
}
if (origsess == NULL) { /* should not happen */
goto done;
}
/* call the "real" poll function */
rc = origpoll( fds, nfds, timeout, origsess );
/* reset the lpoll_socketarg values to their original values because
they must match what's in sb->iofns->lbextiofn_socket_arg in order
for NSLDAPI_CB_POLL_MATCH to work - see os-ip.c */
if (fds && nfds > 0) {
int i;
for(i = 0; i < nfds; i++) {
if ((SASLIOSocketArg *)arg == origarg[i]) {
fds[i].lpoll_socketarg = origarg[i];
}
}
}
done:
/* if we had to use a dynamic array, free it */
if (origarg != staticorigarg) {
NSLDAPI_FREE(origarg);
}
return rc;
}
int
nsldapi_sasl_open( LDAP *ld, LDAPConn *lconn, sasl_conn_t **ctx, sasl_ssf_t ssf )
{
int saslrc;
char *host = NULL;
if ( !NSLDAPI_VALID_LDAP_POINTER( ld )) {
LDAP_SET_LDERRNO( ld, LDAP_LOCAL_ERROR, NULL, NULL );
return( LDAP_LOCAL_ERROR );
}
if ( lconn == NULL ) {
if ( ld->ld_defconn == NULL ||
ld->ld_defconn->lconn_status != LDAP_CONNST_CONNECTED) {
int rc = nsldapi_open_ldap_defconn( ld );
if( rc < 0 ) {
return( LDAP_GET_LDERRNO( ld, NULL, NULL ) );
}
}
lconn = ld->ld_defconn;
}
/* need to clear out the old context for this connection, if any */
/* client may have re-bind-ed this connection without closing first */
if (lconn->lconn_sasl_ctx) {
sasl_dispose(&lconn->lconn_sasl_ctx);
lconn->lconn_sasl_ctx = NULL;
}
if ( 0 != ldap_get_option( ld, LDAP_OPT_HOST_NAME, &host ) ) {
LDAP_SET_LDERRNO( ld, LDAP_LOCAL_ERROR, NULL, NULL );
return( LDAP_LOCAL_ERROR );
}
saslrc = sasl_client_new( "ldap", host,
NULL, NULL, /* iplocalport, ipremoteport - use defaults */
NULL, 0, ctx );
ldap_memfree(host);
if ( (saslrc != SASL_OK) || (!*ctx) ) {
return( nsldapi_sasl_cvterrno( ld, saslrc, NULL ) );
}
if( ssf ) {
sasl_ssf_t extprops;
memset(&extprops, 0L, sizeof(extprops));
extprops = ssf;
(void) sasl_setprop( *ctx, SASL_SSF_EXTERNAL,
(void *) &extprops );
}
/* (re)set security properties */
sasl_setprop( *ctx, SASL_SEC_PROPS, &ld->ld_sasl_secprops );
/* set the connection context */
lconn->lconn_sasl_ctx = *ctx;
return( LDAP_SUCCESS );
}
static int
nsldapi_sasl_close( struct lextiof_socket_private *arg )
{
/* undo function pointer interposing */
ldap_set_option( arg->ld, LDAP_X_OPT_EXTIO_FN_PTRS, &arg->sess_io_fns );
/* have to do this separately to make sure the socketarg is set correctly */
ber_sockbuf_set_option( arg->sb,
LBER_SOCKBUF_OPT_EXT_IO_FNS,
(void *)&arg->sock_io_fns );
destroy_SASLIOSocketArg(&arg);
return( LDAP_SUCCESS );
}
static int
nsldapi_sasl_close_socket(int s, struct lextiof_socket_private *arg )
{
LDAP_X_EXTIOF_CLOSE_CALLBACK *origclose;
struct lextiof_socket_private *origsock;
if (arg == NULL) {
return( -1 );
}
origclose = arg->sess_io_fns.lextiof_close;
origsock = arg->sock_io_fns.lbextiofn_socket_arg;
/* undo SASL */
nsldapi_sasl_close( arg );
arg = NULL;
/* arg is destroyed at this point - do not use it */
if (origclose )
return ( origclose( s, origsock ) );
else {
/* This is a copy of nsldapi_os_closesocket()
* from os-ip.c. It is declared static there,
* hence the copy of it.
*/
int rc;
#ifdef NSLDAPI_AVOID_OS_SOCKETS
rc = -1;
#else /* NSLDAPI_AVOID_OS_SOCKETS */
#ifdef _WINDOWS
rc = closesocket( s );
#else /* _WINDOWS */
rc = close( s );
#endif /* _WINDOWS */
#endif /* NSLDAPI_AVOID_OS_SOCKETS */
return( rc );
}
}
/*
* install encryption routines if security has been negotiated
*/
int
nsldapi_sasl_install( LDAP *ld, LDAPConn *lconn )
{
struct lber_x_ext_io_fns fns;
struct ldap_x_ext_io_fns iofns;
sasl_security_properties_t *secprops;
int rc, value;
int bufsiz;
Sockbuf *sb = NULL;
sasl_conn_t *ctx = NULL;
SASLIOSocketArg *sockarg = NULL;
if ( lconn == NULL ) {
lconn = ld->ld_defconn;
if ( lconn == NULL ) {
return( LDAP_LOCAL_ERROR );
}
}
if ( (sb = lconn->lconn_sb) == NULL ) {
return( LDAP_LOCAL_ERROR );
}
rc = ber_sockbuf_get_option( sb,
LBER_SOCKBUF_OPT_TO_FILE_ONLY,
(void *) &value);
if (rc != 0 || value != 0) {
return( LDAP_LOCAL_ERROR );
}
/* the sasl context in the lconn must have been set prior to this */
ctx = lconn->lconn_sasl_ctx;
rc = sasl_getprop( ctx, SASL_SEC_PROPS,
(const void **)&secprops );
if (rc != SASL_OK)
return( LDAP_LOCAL_ERROR );
bufsiz = secprops->maxbufsize;
if (bufsiz <= 0) {
return( LDAP_LOCAL_ERROR );
}
/* create our socket specific context */
sockarg = new_SASLIOSocketArg(ctx, bufsiz, ld, sb);
if (!sockarg) {
return( LDAP_LOCAL_ERROR );
}
/* save a copy of the existing io fns and the session arg */
memset( &sockarg->sess_io_fns, 0, LDAP_X_EXTIO_FNS_SIZE );
sockarg->sess_io_fns.lextiof_size = LDAP_X_EXTIO_FNS_SIZE;
rc = ldap_get_option( ld, LDAP_X_OPT_EXTIO_FN_PTRS,
&sockarg->sess_io_fns );
if (rc != 0) {
destroy_SASLIOSocketArg(&sockarg);
return( LDAP_LOCAL_ERROR );
}
/* save a copy of the existing ber io fns and the socket arg */
memset( &sockarg->sock_io_fns, 0, LBER_X_EXTIO_FNS_SIZE );
sockarg->sock_io_fns.lbextiofn_size = LBER_X_EXTIO_FNS_SIZE;
rc = ber_sockbuf_get_option( sb,
LBER_SOCKBUF_OPT_EXT_IO_FNS,
(void *)&sockarg->sock_io_fns);
if (rc != 0) {
destroy_SASLIOSocketArg(&sockarg);
return( LDAP_LOCAL_ERROR );
}
/* Always set the ext io close fn pointer to ensure we
* clean up our sockarg context */
memset( &iofns, 0, sizeof(iofns));
/* first, copy struct - sets defaults */
iofns = sockarg->sess_io_fns;
iofns.lextiof_close = nsldapi_sasl_close_socket;
iofns.lextiof_session_arg = sockarg; /* needed for close and poll */
/* Set new values for the other ext io funcs if there are any -
when using the native io fns (as opposed to prldap) there
won't be any */
if ( sockarg->sess_io_fns.lextiof_read != NULL ||
sockarg->sess_io_fns.lextiof_write != NULL ||
sockarg->sess_io_fns.lextiof_poll != NULL ||
sockarg->sess_io_fns.lextiof_connect != NULL ) {
/* next, just reset those functions we want to override */
iofns.lextiof_read = nsldapi_sasl_read;
iofns.lextiof_write = nsldapi_sasl_write;
iofns.lextiof_poll = nsldapi_sasl_poll;
}
/* set the ext io funcs */
rc = ldap_set_option( ld, LDAP_X_OPT_EXTIO_FN_PTRS, &iofns );
if (rc != 0) {
/* frees everything and resets fns above */
nsldapi_sasl_close(sockarg);
return( LDAP_LOCAL_ERROR );
}
/* set the new ber io funcs and socket arg */
(void) memset( &fns, 0, LBER_X_EXTIO_FNS_SIZE);
fns.lbextiofn_size = LBER_X_EXTIO_FNS_SIZE;
fns.lbextiofn_read = nsldapi_sasl_read;
fns.lbextiofn_write = nsldapi_sasl_write;
fns.lbextiofn_socket_arg = sockarg;
rc = ber_sockbuf_set_option( sb,
LBER_SOCKBUF_OPT_EXT_IO_FNS,
(void *)&fns);
if (rc != 0) {
/* frees everything and resets fns above */
nsldapi_sasl_close(sockarg);
return( LDAP_LOCAL_ERROR );
}
return( LDAP_SUCCESS );
}
#endif

View file

@ -0,0 +1,214 @@
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is Mozilla Communicator client code, released
* March 31, 1998.
*
* The Initial Developer of the Original Code is
* Netscape Communications Corporation.
* Portions created by the Initial Developer are Copyright (C) 1998-1999
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
*
* Alternatively, the contents of this file may be used under the terms of
* either of the GNU General Public License Version 2 or later (the "GPL"),
* or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
/*
* Copyright (c) 1993 Regents of the University of Michigan.
* All rights reserved.
*/
/*
* sbind.c
*/
#if 0
#ifndef lint
static char copyright[] = "@(#) Copyright (c) 1993 Regents of the University of Michigan.\nAll rights reserved.\n";
#endif
#endif
#include "ldap-int.h"
static int simple_bind_nolock( LDAP *ld, const char *dn, const char *passwd,
int unlock_permitted );
/*
* ldap_simple_bind - bind to the ldap server. The dn and
* password of the entry to which to bind are supplied. The message id
* of the request initiated is returned.
*
* Example:
* ldap_simple_bind( ld, "cn=manager, o=university of michigan, c=us",
* "secret" )
*/
int
LDAP_CALL
ldap_simple_bind( LDAP *ld, const char *dn, const char *passwd )
{
int rc;
LDAPDebug( LDAP_DEBUG_TRACE, "ldap_simple_bind\n", 0, 0, 0 );
if ( !NSLDAPI_VALID_LDAP_POINTER( ld )) {
return( LDAP_PARAM_ERROR );
}
if ( ( ld->ld_options & LDAP_BITOPT_RECONNECT ) != 0 ) {
nsldapi_handle_reconnect( ld );
}
rc = simple_bind_nolock( ld, dn, passwd, 1 );
return( rc );
}
static int
simple_bind_nolock( LDAP *ld, const char *dn, const char *passwd,
int unlock_permitted )
{
BerElement *ber;
int rc, msgid;
/*
* The bind request looks like this:
* BindRequest ::= SEQUENCE {
* version INTEGER,
* name DistinguishedName, -- who
* authentication CHOICE {
* simple [0] OCTET STRING -- passwd
* }
* }
* all wrapped up in an LDAPMessage sequence.
*/
LDAP_MUTEX_LOCK( ld, LDAP_MSGID_LOCK );
msgid = ++ld->ld_msgid;
LDAP_MUTEX_UNLOCK( ld, LDAP_MSGID_LOCK );
if ( dn == NULL )
dn = "";
if ( passwd == NULL )
passwd = "";
if ( ld->ld_cache_on && ld->ld_cache_bind != NULL ) {
struct berval bv;
bv.bv_val = (char *)passwd;
bv.bv_len = strlen( passwd );
/* if ( unlock_permitted ) LDAP_MUTEX_UNLOCK( ld ); */
LDAP_MUTEX_LOCK( ld, LDAP_CACHE_LOCK );
rc = (ld->ld_cache_bind)( ld, msgid, LDAP_REQ_BIND, dn, &bv,
LDAP_AUTH_SIMPLE );
LDAP_MUTEX_UNLOCK( ld, LDAP_CACHE_LOCK );
/* if ( unlock_permitted ) LDAP_MUTEX_LOCK( ld ); */
if ( rc != 0 ) {
return( rc );
}
}
/* create a message to send */
if (( rc = nsldapi_alloc_ber_with_options( ld, &ber ))
!= LDAP_SUCCESS ) {
return( -1 );
}
/* fill it in */
if ( ber_printf( ber, "{it{ists}", msgid, LDAP_REQ_BIND,
NSLDAPI_LDAP_VERSION( ld ), dn, LDAP_AUTH_SIMPLE, passwd ) == -1 ) {
LDAP_SET_LDERRNO( ld, LDAP_ENCODING_ERROR, NULL, NULL );
ber_free( ber, 1 );
return( -1 );
}
if ( nsldapi_put_controls( ld, NULL, 1, ber ) != LDAP_SUCCESS ) {
ber_free( ber, 1 );
return( -1 );
}
/* send the message */
return( nsldapi_send_initial_request( ld, msgid, LDAP_REQ_BIND,
(char *)dn, ber ));
}
/*
* ldap_simple_bind - bind to the ldap server using simple
* authentication. The dn and password of the entry to which to bind are
* supplied. LDAP_SUCCESS is returned upon success, the ldap error code
* otherwise.
*
* Example:
* ldap_simple_bind_s( ld, "cn=manager, o=university of michigan, c=us",
* "secret" )
*/
int
LDAP_CALL
ldap_simple_bind_s( LDAP *ld, const char *dn, const char *passwd )
{
int msgid;
LDAPMessage *result;
LDAPDebug( LDAP_DEBUG_TRACE, "ldap_simple_bind_s\n", 0, 0, 0 );
if ( !NSLDAPI_VALID_LDAP_POINTER( ld )) {
return( LDAP_PARAM_ERROR );
}
if ( (msgid = ldap_simple_bind( ld, dn, passwd )) == -1 )
return( LDAP_GET_LDERRNO( ld, NULL, NULL ) );
if ( ldap_result( ld, msgid, 1, (struct timeval *) 0, &result ) == -1 )
return( LDAP_GET_LDERRNO( ld, NULL, NULL ) );
return( ldap_result2error( ld, result, 1 ) );
}
void nsldapi_handle_reconnect( LDAP *ld )
{
LDAPDebug( LDAP_DEBUG_TRACE, "nsldapi_handle_reconnect\n", 0, 0, 0 );
/*
* if the default connection has been lost and is now marked dead,
* dispose of the default connection so it will get re-established.
*
* if not, clear the bind DN and status to ensure that we don't
* report the wrong bind DN to a different thread while waiting
* for our bind result to return from the server.
*/
LDAP_MUTEX_LOCK( ld, LDAP_CONN_LOCK );
if ( NULL != ld->ld_defconn ) {
if ( LDAP_CONNST_DEAD == ld->ld_defconn->lconn_status ) {
nsldapi_free_connection( ld, ld->ld_defconn, NULL, NULL, 1, 0 );
ld->ld_defconn = NULL;
} else if ( ld->ld_defconn->lconn_binddn != NULL ) {
NSLDAPI_FREE( ld->ld_defconn->lconn_binddn );
ld->ld_defconn->lconn_binddn = NULL;
ld->ld_defconn->lconn_bound = 0;
}
}
LDAP_MUTEX_UNLOCK( ld, LDAP_CONN_LOCK );
}

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,411 @@
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is Mozilla Communicator client code, released
* March 31, 1998.
*
* The Initial Developer of the Original Code is
* Netscape Communications Corporation.
* Portions created by the Initial Developer are Copyright (C) 1998-1999
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
*
* Alternatively, the contents of this file may be used under the terms of
* either of the GNU General Public License Version 2 or later (the "GPL"),
* or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
/*
* setoption.c - ldap_set_option implementation
*/
#include "ldap-int.h"
#define LDAP_SETCLR_BITOPT( ld, bit, optdata ) \
if ( optdata != NULL ) { \
(ld)->ld_options |= bit; \
} else { \
(ld)->ld_options &= ~bit; \
}
int
LDAP_CALL
ldap_set_option( LDAP *ld, int option, const void *optdata )
{
int rc, i;
char *matched, *errstr;
/*
* if ld is NULL, arrange to modify our default settings
*/
if ( ld == NULL ) {
if ( !nsldapi_initialized ) {
nsldapi_initialize_defaults();
}
ld = &nsldapi_ld_defaults;
}
/*
* process global options (not associated with an LDAP session handle)
*/
if ( option == LDAP_OPT_MEMALLOC_FN_PTRS ) {
struct lber_memalloc_fns memalloc_fns;
/* set libldap ones via a struct copy */
nsldapi_memalloc_fns = *((struct ldap_memalloc_fns *)optdata);
/* also set liblber memory allocation callbacks */
memalloc_fns.lbermem_malloc =
nsldapi_memalloc_fns.ldapmem_malloc;
memalloc_fns.lbermem_calloc =
nsldapi_memalloc_fns.ldapmem_calloc;
memalloc_fns.lbermem_realloc =
nsldapi_memalloc_fns.ldapmem_realloc;
memalloc_fns.lbermem_free =
nsldapi_memalloc_fns.ldapmem_free;
if ( ber_set_option( NULL, LBER_OPT_MEMALLOC_FN_PTRS,
&memalloc_fns ) != 0 ) {
return( -1 );
}
return( 0 );
}
/*
* LDAP_OPT_DEBUG_LEVEL is global
*/
if (LDAP_OPT_DEBUG_LEVEL == option)
{
#ifdef LDAP_DEBUG
ldap_debug = *((int *) optdata);
#endif
return 0;
}
/*
* process options that are associated with an LDAP session handle
*/
if ( !NSLDAPI_VALID_LDAP_POINTER( ld )) {
return( -1 ); /* punt */
}
rc = 0;
if ( ld != &nsldapi_ld_defaults
&& option != LDAP_OPT_EXTRA_THREAD_FN_PTRS
&& option != LDAP_OPT_THREAD_FN_PTRS ) {
LDAP_MUTEX_LOCK( ld, LDAP_OPTION_LOCK );
}
switch( option ) {
/* options that can be turned on and off */
#ifdef LDAP_DNS
case LDAP_OPT_DNS:
LDAP_SETCLR_BITOPT( ld, LDAP_BITOPT_DNS, optdata );
break;
#endif
case LDAP_OPT_REFERRALS:
LDAP_SETCLR_BITOPT( ld, LDAP_BITOPT_REFERRALS, optdata );
break;
case LDAP_OPT_SSL:
LDAP_SETCLR_BITOPT( ld, LDAP_BITOPT_SSL, optdata );
break;
case LDAP_OPT_RESTART:
LDAP_SETCLR_BITOPT( ld, LDAP_BITOPT_RESTART, optdata );
break;
case LDAP_OPT_RECONNECT:
LDAP_SETCLR_BITOPT( ld, LDAP_BITOPT_RECONNECT, optdata );
break;
case LDAP_OPT_NOREBIND:
LDAP_SETCLR_BITOPT( ld, LDAP_BITOPT_NOREBIND, optdata );
break;
#ifdef LDAP_ASYNC_IO
case LDAP_OPT_ASYNC_CONNECT:
LDAP_SETCLR_BITOPT(ld, LDAP_BITOPT_ASYNC, optdata );
break;
#endif /* LDAP_ASYNC_IO */
/* fields in the LDAP structure */
case LDAP_OPT_DEREF:
ld->ld_deref = *((int *) optdata);
break;
case LDAP_OPT_SIZELIMIT:
ld->ld_sizelimit = *((int *) optdata);
break;
case LDAP_OPT_TIMELIMIT:
ld->ld_timelimit = *((int *) optdata);
break;
case LDAP_OPT_REFERRAL_HOP_LIMIT:
ld->ld_refhoplimit = *((int *) optdata);
break;
case LDAP_OPT_PROTOCOL_VERSION:
ld->ld_version = *((int *) optdata);
if ( ld->ld_defconn != NULL ) { /* also set in default conn. */
ld->ld_defconn->lconn_version = ld->ld_version;
}
break;
case LDAP_OPT_SERVER_CONTROLS:
/* nsldapi_dup_controls returns -1 and sets lderrno on error */
rc = nsldapi_dup_controls( ld, &ld->ld_servercontrols,
(LDAPControl **)optdata );
break;
case LDAP_OPT_CLIENT_CONTROLS:
/* nsldapi_dup_controls returns -1 and sets lderrno on error */
rc = nsldapi_dup_controls( ld, &ld->ld_clientcontrols,
(LDAPControl **)optdata );
break;
/* rebind proc */
case LDAP_OPT_REBIND_FN:
ld->ld_rebind_fn = (LDAP_REBINDPROC_CALLBACK *) optdata;
break;
case LDAP_OPT_REBIND_ARG:
ld->ld_rebind_arg = (void *) optdata;
break;
/* i/o function pointers */
case LDAP_OPT_IO_FN_PTRS:
if (( rc = nsldapi_install_compat_io_fns( ld,
(struct ldap_io_fns *)optdata )) != LDAP_SUCCESS ) {
LDAP_SET_LDERRNO( ld, rc, NULL, NULL );
rc = -1;
}
break;
/* extended i/o function pointers */
case LDAP_X_OPT_EXTIO_FN_PTRS:
/* denotes use of old iofns struct (no writev) */
if (((struct ldap_x_ext_io_fns_rev0 *) optdata)->lextiof_size == LDAP_X_EXTIO_FNS_SIZE_REV0) {
ld->ld_extio_size = LDAP_X_EXTIO_FNS_SIZE;
ld->ld_extclose_fn = ((struct ldap_x_ext_io_fns_rev0 *) optdata)->lextiof_close;
ld->ld_extconnect_fn = ((struct ldap_x_ext_io_fns_rev0 *) optdata)->lextiof_connect;
ld->ld_extread_fn = ((struct ldap_x_ext_io_fns_rev0 *) optdata)->lextiof_read;
ld->ld_extwrite_fn = ((struct ldap_x_ext_io_fns_rev0 *) optdata)->lextiof_write;
ld->ld_extpoll_fn = ((struct ldap_x_ext_io_fns_rev0 *) optdata)->lextiof_poll;
ld->ld_extnewhandle_fn = ((struct ldap_x_ext_io_fns_rev0 *) optdata)->lextiof_newhandle;
ld->ld_extdisposehandle_fn = ((struct ldap_x_ext_io_fns_rev0 *) optdata)->lextiof_disposehandle;
ld->ld_ext_session_arg = ((struct ldap_x_ext_io_fns_rev0 *) optdata)->lextiof_session_arg;
ld->ld_extwritev_fn = NULL;
if ( ber_sockbuf_set_option( ld->ld_sbp, LBER_SOCKBUF_OPT_EXT_IO_FNS,
&(ld->ld_ext_io_fns) ) != 0 ) {
LDAP_SET_LDERRNO( ld, LDAP_LOCAL_ERROR, NULL, NULL );
rc = -1;
break;
}
}
else {
/* struct copy */
ld->ld_ext_io_fns = *((struct ldap_x_ext_io_fns *) optdata);
}
if (( rc = nsldapi_install_lber_extiofns( ld, ld->ld_sbp ))
!= LDAP_SUCCESS ) {
LDAP_SET_LDERRNO( ld, rc, NULL, NULL );
rc = -1;
}
break;
/* set Socket Arg in extended socket i/o functions*/
case LDAP_X_OPT_SOCKETARG:
if ( ber_sockbuf_set_option( ld->ld_sbp,
LBER_SOCKBUF_OPT_SOCK_ARG, (void *)optdata ) != 0 ) {
LDAP_SET_LDERRNO( ld, LDAP_LOCAL_ERROR, NULL, NULL );
rc = -1;
}
break;
/* thread function pointers */
case LDAP_OPT_THREAD_FN_PTRS:
/*
* It is only safe to set the thread function pointers
* when one thread is using the LDAP session handle.
*/
/* free existing mutexes (some are allocated by ldap_init()) */
nsldapi_mutex_free_all( ld );
/* struct copy */
ld->ld_thread = *((struct ldap_thread_fns *) optdata);
/* allocate new mutexes */
nsldapi_mutex_alloc_all( ld );
/* LDAP_OPTION_LOCK was never locked... so just return */
return (rc);
/* extra thread function pointers */
case LDAP_OPT_EXTRA_THREAD_FN_PTRS:
/* The extra thread funcs will only pick up the threadid */
ld->ld_thread2 = *((struct ldap_extra_thread_fns *) optdata);
/* Reset the rest of the structure preserving the threadid fn */
ld->ld_mutex_trylock_fn = (LDAP_TF_MUTEX_TRYLOCK_CALLBACK *)NULL;
ld->ld_sema_alloc_fn = (LDAP_TF_SEMA_ALLOC_CALLBACK *) NULL;
ld->ld_sema_free_fn = (LDAP_TF_SEMA_FREE_CALLBACK *) NULL;
ld->ld_sema_wait_fn = (LDAP_TF_SEMA_WAIT_CALLBACK *) NULL;
ld->ld_sema_post_fn = (LDAP_TF_SEMA_POST_CALLBACK *) NULL;
/* We assume that only one thread is active when replacing */
/* the threadid function. We will now proceed and reset all */
/* of the threadid/refcounts */
for( i=0; i<LDAP_MAX_LOCK; i++ ) {
ld->ld_mutex_threadid[i] = (void *) -1;
ld->ld_mutex_refcnt[i] = 0;
}
/* LDAP_OPTION_LOCK was never locked... so just return */
return (rc);
/* DNS function pointers */
case LDAP_OPT_DNS_FN_PTRS:
/* struct copy */
ld->ld_dnsfn = *((struct ldap_dns_fns *) optdata);
break;
/* cache function pointers */
case LDAP_OPT_CACHE_FN_PTRS:
/* struct copy */
ld->ld_cache = *((struct ldap_cache_fns *) optdata);
break;
case LDAP_OPT_CACHE_STRATEGY:
ld->ld_cache_strategy = *((int *) optdata);
break;
case LDAP_OPT_CACHE_ENABLE:
ld->ld_cache_on = *((int *) optdata);
break;
case LDAP_OPT_ERROR_NUMBER:
LDAP_GET_LDERRNO( ld, &matched, &errstr );
matched = nsldapi_strdup( matched );
errstr = nsldapi_strdup( errstr );
LDAP_SET_LDERRNO( ld, *((int *) optdata), matched, errstr );
break;
case LDAP_OPT_ERROR_STRING:
rc = LDAP_GET_LDERRNO( ld, &matched, NULL );
matched = nsldapi_strdup( matched );
LDAP_SET_LDERRNO( ld, rc, matched,
nsldapi_strdup((char *) optdata));
rc = LDAP_SUCCESS;
break;
case LDAP_OPT_MATCHED_DN:
rc = LDAP_GET_LDERRNO( ld, NULL, &errstr );
errstr = nsldapi_strdup( errstr );
LDAP_SET_LDERRNO( ld, rc,
nsldapi_strdup((char *) optdata), errstr );
rc = LDAP_SUCCESS;
break;
case LDAP_OPT_PREFERRED_LANGUAGE:
if ( NULL != ld->ld_preferred_language ) {
NSLDAPI_FREE(ld->ld_preferred_language);
}
ld->ld_preferred_language = nsldapi_strdup((char *) optdata);
break;
case LDAP_OPT_HOST_NAME:
if ( NULL != ld->ld_defhost ) {
NSLDAPI_FREE(ld->ld_defhost);
}
ld->ld_defhost = nsldapi_strdup((char *) optdata);
break;
case LDAP_X_OPT_CONNECT_TIMEOUT:
ld->ld_connect_timeout = *((int *) optdata);
break;
#ifdef LDAP_SASLIO_HOOKS
/* SASL options */
case LDAP_OPT_X_SASL_MECH:
NSLDAPI_FREE(ld->ld_def_sasl_mech);
ld->ld_def_sasl_mech = nsldapi_strdup((char *) optdata);
break;
case LDAP_OPT_X_SASL_REALM:
NSLDAPI_FREE(ld->ld_def_sasl_realm);
ld->ld_def_sasl_realm = nsldapi_strdup((char *) optdata);
break;
case LDAP_OPT_X_SASL_AUTHCID:
NSLDAPI_FREE(ld->ld_def_sasl_authcid);
ld->ld_def_sasl_authcid = nsldapi_strdup((char *) optdata);
break;
case LDAP_OPT_X_SASL_AUTHZID:
NSLDAPI_FREE(ld->ld_def_sasl_authzid);
ld->ld_def_sasl_authzid = nsldapi_strdup((char *) optdata);
break;
case LDAP_OPT_X_SASL_SSF_EXTERNAL:
{
int sc;
sasl_ssf_t extprops;
sasl_conn_t *ctx;
if( ld->ld_defconn == NULL ) {
return -1;
}
ctx = (sasl_conn_t *)(ld->ld_defconn->lconn_sasl_ctx);
if ( ctx == NULL ) {
return -1;
}
memset(&extprops, 0L, sizeof(extprops));
extprops = * ((sasl_ssf_t *) optdata);
sc = sasl_setprop( ctx, SASL_SSF_EXTERNAL,
(void *) &extprops );
if ( sc != SASL_OK ) {
return -1;
}
}
break;
case LDAP_OPT_X_SASL_SECPROPS:
{
int sc;
sc = nsldapi_sasl_secprops( (char *) optdata,
&ld->ld_sasl_secprops );
return sc == LDAP_SUCCESS ? 0 : -1;
}
break;
case LDAP_OPT_X_SASL_SSF_MIN:
ld->ld_sasl_secprops.min_ssf = *((sasl_ssf_t *) optdata);
break;
case LDAP_OPT_X_SASL_SSF_MAX:
ld->ld_sasl_secprops.max_ssf = *((sasl_ssf_t *) optdata);
break;
case LDAP_OPT_X_SASL_MAXBUFSIZE:
ld->ld_sasl_secprops.maxbufsize = *((sasl_ssf_t *) optdata);
break;
case LDAP_OPT_X_SASL_SSF: /* read only */
LDAP_SET_LDERRNO( ld, LDAP_PARAM_ERROR, NULL, NULL );
rc = -1;
break;
#endif
default:
LDAP_SET_LDERRNO( ld, LDAP_PARAM_ERROR, NULL, NULL );
rc = -1;
}
if ( ld != &nsldapi_ld_defaults ) {
LDAP_MUTEX_UNLOCK( ld, LDAP_OPTION_LOCK );
}
return( rc );
}

View file

@ -0,0 +1,355 @@
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is Mozilla Communicator client code, released
* March 31, 1998.
*
* The Initial Developer of the Original Code is
* Netscape Communications Corporation.
* Portions created by the Initial Developer are Copyright (C) 1998-1999
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
*
* Alternatively, the contents of this file may be used under the terms of
* either of the GNU General Public License Version 2 or later (the "GPL"),
* or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
/*
* Copyright (c) 1994 Regents of the University of Michigan.
* All rights reserved.
*
* Redistribution and use in source and binary forms are permitted
* provided that this notice is preserved and that due credit is given
* to the University of Michigan at Ann Arbor. The name of the University
* may not be used to endorse or promote products derived from this
* software without specific prior written permission. This software
* is provided ``as is'' without express or implied warranty.
*/
/*
* sort.c: LDAP library entry and value sort routines
*/
#include "ldap-int.h"
/* This xp_qsort fixes a memory problem (ABR) on Solaris for the client.
* Server is welcome to use it too, but I wasn't sure if it
* would be ok to use XP code here. -slamm
*
* We don't want to require use of libxp when linking with libldap, so
* I'll leave use of xp_qsort as a MOZILLA_CLIENT-only thing for now. --mcs
*/
#if defined(MOZILLA_CLIENT) && defined(SOLARIS)
#include "xp_qsort.h"
#else
#define XP_QSORT qsort
#endif
typedef struct keycmp {
void *kc_arg;
LDAP_KEYCMP_CALLBACK *kc_cmp;
} keycmp_t;
typedef struct keything {
keycmp_t *kt_cmp;
const struct berval *kt_key;
LDAPMessage *kt_msg;
} keything_t;
static int LDAP_C LDAP_CALLBACK
ldapi_keycmp( const void *Lv, const void *Rv )
{
auto keything_t **L = (keything_t**)Lv;
auto keything_t **R = (keything_t**)Rv;
auto keycmp_t *cmp = (*L)->kt_cmp;
return cmp->kc_cmp( cmp->kc_arg, (*L)->kt_key, (*R)->kt_key );
}
int
LDAP_CALL
ldap_keysort_entries(
LDAP *ld,
LDAPMessage **chain,
void *arg,
LDAP_KEYGEN_CALLBACK *gen,
LDAP_KEYCMP_CALLBACK *cmp,
LDAP_KEYFREE_CALLBACK *fre)
{
size_t count, i;
keycmp_t kc = {0};
keything_t **kt;
LDAPMessage *e, *last;
LDAPMessage **ep;
int scount;
if ( !NSLDAPI_VALID_LDAP_POINTER( ld )
|| chain == NULL || cmp == NULL ) {
return( LDAP_PARAM_ERROR );
}
scount = ldap_count_entries( ld, *chain );
if (scount < 0) { /* error */
return( LDAP_PARAM_ERROR );
}
count = scount;
if (count < 2) { /* nothing to sort */
return( 0 );
}
kt = (keything_t**)NSLDAPI_MALLOC( count * (sizeof(keything_t*) + sizeof(keything_t)) );
if ( kt == NULL ) {
LDAP_SET_LDERRNO( ld, LDAP_NO_MEMORY, NULL, NULL );
return( -1 );
}
for ( i = 0; i < count; i++ ) {
kt[i] = i + (keything_t*)(kt + count);
}
kc.kc_arg = arg;
kc.kc_cmp = cmp;
for ( e = *chain, i = 0; i < count; i++, e = e->lm_chain ) {
kt[i]->kt_msg = e;
kt[i]->kt_cmp = &kc;
kt[i]->kt_key = gen( arg, ld, e );
if ( kt[i]->kt_key == NULL ) {
if ( fre ) while ( i-- > 0 ) fre( arg, kt[i]->kt_key );
NSLDAPI_FREE( (char*)kt );
LDAP_SET_LDERRNO( ld, LDAP_NO_MEMORY, NULL, NULL );
return( -1 );
}
}
last = e;
XP_QSORT( (void*)kt, count, (size_t)sizeof(keything_t*), ldapi_keycmp );
ep = chain;
for ( i = 0; i < count; i++ ) {
*ep = kt[i]->kt_msg;
ep = &(*ep)->lm_chain;
if ( fre ) fre( arg, kt[i]->kt_key );
}
*ep = last;
NSLDAPI_FREE( (char*)kt );
return( 0 );
}
struct entrything {
char **et_vals;
LDAPMessage *et_msg;
};
typedef int (LDAP_C LDAP_CALLBACK LDAP_CHARCMP_CALLBACK)(char*, char*);
typedef int (LDAP_C LDAP_CALLBACK LDAP_VOIDCMP_CALLBACK)(const void*,
const void*);
static LDAP_CHARCMP_CALLBACK *et_cmp_fn;
static LDAP_VOIDCMP_CALLBACK et_cmp;
int
LDAP_C
LDAP_CALLBACK
ldap_sort_strcasecmp(
const char **a,
const char **b
)
{
/* XXXceb
* I am not 100% sure this is the way this should be handled.
* For now we will return a 0 on invalid.
*/
if (NULL == a || NULL == b)
return (0);
return( strcasecmp( (char *)*a, (char *)*b ) );
}
static int
LDAP_C
LDAP_CALLBACK
et_cmp(
const void *aa,
const void *bb
)
{
int i, rc;
struct entrything *a = (struct entrything *)aa;
struct entrything *b = (struct entrything *)bb;
if ( a->et_vals == NULL && b->et_vals == NULL )
return( 0 );
if ( a->et_vals == NULL )
return( -1 );
if ( b->et_vals == NULL )
return( 1 );
for ( i = 0; a->et_vals[i] && b->et_vals[i]; i++ ) {
if ( (rc = (*et_cmp_fn)( a->et_vals[i], b->et_vals[i] ))
!= 0 ) {
return( rc );
}
}
if ( a->et_vals[i] == NULL && b->et_vals[i] == NULL )
return( 0 );
if ( a->et_vals[i] == NULL )
return( -1 );
return( 1 );
}
int
LDAP_CALL
ldap_multisort_entries(
LDAP *ld,
LDAPMessage **chain,
char **attr, /* NULL => sort by DN */
LDAP_CMP_CALLBACK *cmp
)
{
int i, count;
struct entrything *et;
LDAPMessage *e, *last;
LDAPMessage **ep;
int scount;
if ( !NSLDAPI_VALID_LDAP_POINTER( ld )
|| chain == NULL || cmp == NULL ) {
return( LDAP_PARAM_ERROR );
}
scount = ldap_count_entries( ld, *chain );
if (scount < 0) { /* error, usually with bad ld or malloc */
return( LDAP_PARAM_ERROR );
}
count = scount;
if (count < 2) { /* nothing to sort */
return( 0 );
}
if ( (et = (struct entrything *)NSLDAPI_MALLOC( count *
sizeof(struct entrything) )) == NULL ) {
LDAP_SET_LDERRNO( ld, LDAP_NO_MEMORY, NULL, NULL );
return( -1 );
}
e = *chain;
for ( i = 0; i < count; i++ ) {
et[i].et_msg = e;
et[i].et_vals = NULL;
if ( attr == NULL ) {
char *dn;
dn = ldap_get_dn( ld, e );
et[i].et_vals = ldap_explode_dn( dn, 1 );
NSLDAPI_FREE( dn );
} else {
int attrcnt;
char **vals;
for ( attrcnt = 0; attr[attrcnt] != NULL; attrcnt++ ) {
vals = ldap_get_values( ld, e, attr[attrcnt] );
if ( ldap_charray_merge( &(et[i].et_vals), vals )
!= 0 ) {
int j;
/* XXX risky: ldap_value_free( vals ); */
for ( j = 0; j <= i; j++ )
ldap_value_free( et[j].et_vals );
NSLDAPI_FREE( (char *) et );
LDAP_SET_LDERRNO( ld, LDAP_NO_MEMORY, NULL,
NULL );
return( -1 );
}
if ( vals != NULL ) {
NSLDAPI_FREE( (char *)vals );
}
}
}
e = e->lm_chain;
}
last = e;
et_cmp_fn = (LDAP_CHARCMP_CALLBACK *)cmp;
XP_QSORT( (void *) et, (size_t) count,
(size_t) sizeof(struct entrything), et_cmp );
ep = chain;
for ( i = 0; i < count; i++ ) {
*ep = et[i].et_msg;
ep = &(*ep)->lm_chain;
ldap_value_free( et[i].et_vals );
}
*ep = last;
NSLDAPI_FREE( (char *) et );
return( 0 );
}
int
LDAP_CALL
ldap_sort_entries(
LDAP *ld,
LDAPMessage **chain,
char *attr, /* NULL => sort by DN */
LDAP_CMP_CALLBACK *cmp
)
{
char *attrs[2];
attrs[0] = attr;
attrs[1] = NULL;
return( ldap_multisort_entries( ld, chain, attr ? attrs : NULL, cmp ) );
}
int
LDAP_CALL
ldap_sort_values(
LDAP *ld,
char **vals,
LDAP_VALCMP_CALLBACK *cmp
)
{
int nel;
if ( !NSLDAPI_VALID_LDAP_POINTER( ld ) || cmp == NULL ) {
return( LDAP_PARAM_ERROR );
}
if ( NULL == vals)
{
LDAP_SET_LDERRNO( ld, LDAP_PARAM_ERROR, NULL, NULL );
return( LDAP_PARAM_ERROR );
}
for ( nel = 0; vals[nel] != NULL; nel++ )
; /* NULL */
XP_QSORT( vals, nel, sizeof(char *), (LDAP_VOIDCMP_CALLBACK *)cmp );
return( LDAP_SUCCESS );
}

View file

@ -0,0 +1,438 @@
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is Mozilla Communicator client code, released
* March 31, 1998.
*
* The Initial Developer of the Original Code is
* Netscape Communications Corporation.
* Portions created by the Initial Developer are Copyright (C) 1998-1999
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
*
* Alternatively, the contents of this file may be used under the terms of
* either of the GNU General Public License Version 2 or later (the "GPL"),
* or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
#include "ldap-int.h"
/* ldap_create_sort_control:
Parameters are
ld LDAP pointer to the desired connection
sortKeyList an array of sortkeys
ctl_iscritical Indicates whether the control is critical of not. If
this field is non-zero, the operation will only be car-
ried out if the control is recognized by the server
and/or client
ctrlp the address of a place to put the constructed control
*/
int
LDAP_CALL
ldap_create_sort_control (
LDAP *ld,
LDAPsortkey **sortKeyList,
const char ctl_iscritical,
LDAPControl **ctrlp
)
{
BerElement *ber;
int i, rc;
if ( !NSLDAPI_VALID_LDAP_POINTER( ld )) {
return( LDAP_PARAM_ERROR );
}
if ( sortKeyList == NULL || ctrlp == NULL ) {
LDAP_SET_LDERRNO( ld, LDAP_PARAM_ERROR, NULL, NULL );
return ( LDAP_PARAM_ERROR );
}
/* create a ber package to hold the controlValue */
if ( ( nsldapi_alloc_ber_with_options( ld, &ber ) ) != LDAP_SUCCESS ) {
LDAP_SET_LDERRNO( ld, LDAP_NO_MEMORY, NULL, NULL );
return( LDAP_NO_MEMORY );
}
/* encode the start of the sequence of sequences into the ber */
if ( ber_printf( ber, "{" ) == -1 ) {
goto encoding_error_exit;
}
/* the sort control value will be encoded as a sequence of sequences
which are each encoded as one of the following: {s} or {sts} or {stb} or {ststb}
since the orderingRule and reverseOrder flag are both optional */
for ( i = 0; sortKeyList[i] != NULL; i++ ) {
/* encode the attributeType into the ber */
if ( ber_printf( ber, "{s", (sortKeyList[i])->sk_attrtype )
== -1 ) {
goto encoding_error_exit;
}
/* encode the optional orderingRule into the ber */
if ( (sortKeyList[i])->sk_matchruleoid != NULL ) {
if ( ber_printf( ber, "ts", LDAP_TAG_SK_MATCHRULE,
(sortKeyList[i])->sk_matchruleoid )
== -1 ) {
goto encoding_error_exit;
}
}
/* Encode the optional reverseOrder flag into the ber. */
/* If the flag is false, it should be absent. */
if ( (sortKeyList[i])->sk_reverseorder ) {
if ( ber_printf( ber, "tb}", LDAP_TAG_SK_REVERSE,
(sortKeyList[i])->sk_reverseorder ) == -1 ) {
goto encoding_error_exit;
}
} else {
if ( ber_printf( ber, "}" ) == -1 ) {
goto encoding_error_exit;
}
}
}
/* encode the end of the sequence of sequences into the ber */
if ( ber_printf( ber, "}" ) == -1 ) {
goto encoding_error_exit;
}
rc = nsldapi_build_control( LDAP_CONTROL_SORTREQUEST, ber, 1,
ctl_iscritical, ctrlp );
LDAP_SET_LDERRNO( ld, rc, NULL, NULL );
return( rc );
encoding_error_exit:
LDAP_SET_LDERRNO( ld, LDAP_ENCODING_ERROR, NULL, NULL );
ber_free( ber, 1 );
return( LDAP_ENCODING_ERROR );
}
/* ldap_parse_sort_control:
Parameters are
ld LDAP pointer to the desired connection
ctrlp An array of controls obtained from calling
ldap_parse_result on the set of results returned by
the server
result the address of a place to put the result code
attribute the address of a place to put the name of the
attribute which cause the operation to fail, optionally
returned by the server */
int
LDAP_CALL
ldap_parse_sort_control (
LDAP *ld,
LDAPControl **ctrlp,
ber_int_t *result,
char **attribute
)
{
BerElement *ber;
int i, foundSortControl;
LDAPControl *sortCtrlp;
ber_len_t len;
ber_tag_t tag;
char *attr;
if ( !NSLDAPI_VALID_LDAP_POINTER( ld ) || result == NULL ||
attribute == NULL ) {
return( LDAP_PARAM_ERROR );
}
/* find the sortControl in the list of controls if it exists */
if ( ctrlp == NULL ) {
LDAP_SET_LDERRNO( ld, LDAP_CONTROL_NOT_FOUND, NULL, NULL );
return ( LDAP_CONTROL_NOT_FOUND );
}
foundSortControl = 0;
for ( i = 0; (( ctrlp[i] != NULL ) && ( !foundSortControl )); i++ ) {
foundSortControl = !strcmp( ctrlp[i]->ldctl_oid, LDAP_CONTROL_SORTRESPONSE );
}
if ( !foundSortControl ) {
LDAP_SET_LDERRNO( ld, LDAP_CONTROL_NOT_FOUND, NULL, NULL );
return ( LDAP_CONTROL_NOT_FOUND );
} else {
/* let local var point to the sortControl */
sortCtrlp = ctrlp[i-1];
}
/* allocate a Ber element with the contents of the sort_control's struct berval */
if ( ( ber = ber_init( &sortCtrlp->ldctl_value ) ) == NULL ) {
LDAP_SET_LDERRNO( ld, LDAP_NO_MEMORY, NULL, NULL );
return( LDAP_NO_MEMORY );
}
/* decode the result from the Berelement */
if ( ber_scanf( ber, "{i", result ) == LBER_ERROR ) {
LDAP_SET_LDERRNO( ld, LDAP_DECODING_ERROR, NULL, NULL );
ber_free( ber, 1 );
return( LDAP_DECODING_ERROR );
}
/* if the server returned one, decode the attribute from the Ber element */
if ( ber_peek_tag( ber, &len ) == LDAP_TAG_SR_ATTRTYPE ) {
if ( ber_scanf( ber, "ta", &tag, &attr ) == LBER_ERROR ) {
LDAP_SET_LDERRNO( ld, LDAP_DECODING_ERROR, NULL, NULL );
ber_free( ber, 1 );
return( LDAP_DECODING_ERROR );
}
*attribute = attr;
} else {
*attribute = NULL;
}
if ( ber_scanf( ber, "}" ) == LBER_ERROR ) {
LDAP_SET_LDERRNO( ld, LDAP_DECODING_ERROR, NULL, NULL );
ber_free( ber, 1 );
return( LDAP_DECODING_ERROR );
}
/* the ber encoding is no longer needed */
ber_free(ber,1);
return( LDAP_SUCCESS );
}
/* Routines for the manipulation of string-representations of sort control keylists */
static int count_tokens(const char *s)
{
int count = 0;
const char *p = s;
int whitespace = 1;
/* Loop along the string counting the number of times we see the
* beginning of non-whitespace. This tells us
* the number of tokens in the string
*/
while (*p != '\0') {
if (whitespace) {
if (!isspace(*p)) {
whitespace = 0;
count++;
}
} else {
if (isspace(*p)) {
whitespace = 1;
}
}
p++;
}
return count;
}
static int read_next_token(const char **s,LDAPsortkey **key)
{
char c = 0;
const char *pos = *s;
int retval = 0;
LDAPsortkey *new_key = NULL;
const char *matchrule_source = NULL;
int matchrule_size = 0;
const char *attrdesc_source = NULL;
int attrdesc_size = 0;
int reverse = 0;
int state = 0;
while ( ((c = *pos++) != '\0') && (state != 4) ) {
switch (state) {
case 0:
/* case where we've not seen the beginning of the attr yet */
/* If we still see whitespace, nothing to do */
if (!isspace(c)) {
/* Otherwise, something to look at */
/* Is it a minus sign ? */
if ('-' == c) {
reverse = 1;
} else {
attrdesc_source = pos - 1;
state = 1;
}
}
break;
case 1:
/* case where we've seen the beginning of the attr, but not the end */
/* Is this char either whitespace or a ';' ? */
if ( isspace(c) || (':' == c)) {
attrdesc_size = (pos - attrdesc_source) - 1;
if (':' == c) {
state = 2;
} else {
state = 4;
}
}
break;
case 2:
/* case where we've seen the end of the attr and want the beginning of match rule */
if (!isspace(c)) {
matchrule_source = pos - 1;
state = 3;
} else {
state = 4;
}
break;
case 3:
/* case where we've seen the beginning of match rule and want to find the end */
if (isspace(c)) {
matchrule_size = (pos - matchrule_source) - 1;
state = 4;
}
break;
default:
break;
}
}
if (3 == state) {
/* means we fell off the end of the string looking for the end of the marching rule */
matchrule_size = (pos - matchrule_source) - 1;
}
if (1 == state) {
/* means we fell of the end of the string looking for the end of the attribute */
attrdesc_size = (pos - attrdesc_source) - 1;
}
if (NULL == attrdesc_source) {
/* Didn't find anything */
return -1;
}
new_key = (LDAPsortkey*)NSLDAPI_MALLOC(sizeof(LDAPsortkey));
if (0 == new_key) {
return LDAP_NO_MEMORY;
}
/* Allocate the strings */
new_key->sk_attrtype = (char *)NSLDAPI_MALLOC(attrdesc_size + 1);
if (NULL != matchrule_source) {
new_key->sk_matchruleoid = (char *)NSLDAPI_MALLOC(
matchrule_size + 1);
} else {
new_key->sk_matchruleoid = NULL;
}
/* Copy over the strings */
memcpy(new_key->sk_attrtype,attrdesc_source,attrdesc_size);
*(new_key->sk_attrtype + attrdesc_size) = '\0';
if (NULL != matchrule_source) {
memcpy(new_key->sk_matchruleoid,matchrule_source,matchrule_size);
*(new_key->sk_matchruleoid + matchrule_size) = '\0';
}
new_key->sk_reverseorder = reverse;
*s = pos - 1;
*key = new_key;
return retval;
}
int
LDAP_CALL
ldap_create_sort_keylist (
LDAPsortkey ***sortKeyList,
const char *string_rep
)
{
int count = 0;
LDAPsortkey **pointer_array = NULL;
const char *current_position = NULL;
int retval = 0;
int i = 0;
/* Figure out how many there are */
if (NULL == string_rep) {
return LDAP_PARAM_ERROR;
}
if (NULL == sortKeyList) {
return LDAP_PARAM_ERROR;
}
count = count_tokens(string_rep);
if (0 == count) {
*sortKeyList = NULL;
return LDAP_PARAM_ERROR;
}
/* Allocate enough memory for the pointers */
pointer_array = (LDAPsortkey**)NSLDAPI_MALLOC(sizeof(LDAPsortkey*)
* (count + 1) );
if (NULL == pointer_array) {
return LDAP_NO_MEMORY;
}
/* Now walk along the string, allocating and filling in the LDAPsearchkey structure */
current_position = string_rep;
for (i = 0; i < count; i++) {
if (0 != (retval = read_next_token(&current_position,&(pointer_array[i])))) {
pointer_array[count] = NULL;
ldap_free_sort_keylist(pointer_array);
*sortKeyList = NULL;
return retval;
}
}
pointer_array[count] = NULL;
*sortKeyList = pointer_array;
return LDAP_SUCCESS;
}
void
LDAP_CALL
ldap_free_sort_keylist (
LDAPsortkey **sortKeyList
)
{
LDAPsortkey *this_one = NULL;
int i = 0;
if ( NULL == sortKeyList ) {
return;
}
/* Walk down the list freeing the LDAPsortkey structures */
for (this_one = sortKeyList[0]; this_one ; this_one = sortKeyList[++i]) {
/* Free the strings, if present */
if (NULL != this_one->sk_attrtype) {
NSLDAPI_FREE(this_one->sk_attrtype);
}
if (NULL != this_one->sk_matchruleoid) {
NSLDAPI_FREE(this_one->sk_matchruleoid);
}
NSLDAPI_FREE(this_one);
}
/* Free the pointer list */
NSLDAPI_FREE(sortKeyList);
}

View file

@ -0,0 +1,434 @@
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is Mozilla Communicator client code, released
* March 31, 1998.
*
* The Initial Developer of the Original Code is
* Netscape Communications Corporation.
* Portions created by the Initial Developer are Copyright (C) 1998-1999
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
*
* Alternatively, the contents of this file may be used under the terms of
* either of the GNU General Public License Version 2 or later (the "GPL"),
* or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
/*
* Copyright (c) 1993, 1994 Regents of the University of Michigan.
* All rights reserved.
*
* Redistribution and use in source and binary forms are permitted
* provided that this notice is preserved and that due credit is given
* to the University of Michigan at Ann Arbor. The name of the University
* may not be used to endorse or promote products derived from this
* software without specific prior written permission. This software
* is provided ``as is'' without express or implied warranty.
*
*/
/*
* searchpref.c: search preferences library routines for LDAP clients
*/
#include "ldap-int.h"
#include "srchpref.h"
static void free_searchobj( struct ldap_searchobj *so );
static int read_next_searchobj( char **bufp, long *blenp,
struct ldap_searchobj **sop, int soversion );
static char *sobjoptions[] = {
"internal",
NULL
};
static unsigned long sobjoptvals[] = {
LDAP_SEARCHOBJ_OPT_INTERNAL,
};
int
LDAP_CALL
ldap_init_searchprefs( char *file, struct ldap_searchobj **solistp )
{
FILE *fp;
char *buf;
long rlen, len;
int rc, eof;
if (( fp = NSLDAPI_FOPEN( file, "r" )) == NULL ) {
return( LDAP_SEARCHPREF_ERR_FILE );
}
if ( fseek( fp, 0L, SEEK_END ) != 0 ) { /* move to end to get len */
fclose( fp );
return( LDAP_SEARCHPREF_ERR_FILE );
}
len = ftell( fp );
if ( fseek( fp, 0L, SEEK_SET ) != 0 ) { /* back to start of file */
fclose( fp );
return( LDAP_SEARCHPREF_ERR_FILE );
}
if (( buf = NSLDAPI_MALLOC( (size_t)len )) == NULL ) {
fclose( fp );
return( LDAP_SEARCHPREF_ERR_MEM );
}
rlen = fread( buf, 1, (size_t)len, fp );
eof = feof( fp );
fclose( fp );
if ( rlen != len && !eof ) { /* error: didn't get the whole file */
NSLDAPI_FREE( buf );
return( LDAP_SEARCHPREF_ERR_FILE );
}
rc = ldap_init_searchprefs_buf( buf, rlen, solistp );
NSLDAPI_FREE( buf );
return( rc );
}
int
LDAP_CALL
ldap_init_searchprefs_buf( char *buf, long buflen,
struct ldap_searchobj **solistp )
{
int rc = 0, version;
char **toks;
struct ldap_searchobj *prevso, *so;
*solistp = prevso = NULLSEARCHOBJ;
if ( nsldapi_next_line_tokens( &buf, &buflen, &toks ) != 2 ||
strcasecmp( toks[ 0 ], "version" ) != 0 ) {
nsldapi_free_strarray( toks );
return( LDAP_SEARCHPREF_ERR_SYNTAX );
}
version = atoi( toks[ 1 ] );
nsldapi_free_strarray( toks );
if ( version != LDAP_SEARCHPREF_VERSION &&
version != LDAP_SEARCHPREF_VERSION_ZERO ) {
return( LDAP_SEARCHPREF_ERR_VERSION );
}
while ( buflen > 0 && ( rc = read_next_searchobj( &buf, &buflen, &so,
version )) == 0 && so != NULLSEARCHOBJ ) {
if ( prevso == NULLSEARCHOBJ ) {
*solistp = so;
} else {
prevso->so_next = so;
}
prevso = so;
}
if ( rc != 0 ) {
ldap_free_searchprefs( *solistp );
}
return( rc );
}
void
LDAP_CALL
ldap_free_searchprefs( struct ldap_searchobj *solist )
{
struct ldap_searchobj *so, *nextso;
if ( solist != NULL ) {
for ( so = solist; so != NULL; so = nextso ) {
nextso = so->so_next;
free_searchobj( so );
}
}
/* XXX XXX need to do some work here */
}
static void
free_searchobj( struct ldap_searchobj *so )
{
if ( so != NULL ) {
if ( so->so_objtypeprompt != NULL ) {
NSLDAPI_FREE( so->so_objtypeprompt );
}
if ( so->so_prompt != NULL ) {
NSLDAPI_FREE( so->so_prompt );
}
if ( so->so_filterprefix != NULL ) {
NSLDAPI_FREE( so->so_filterprefix );
}
if ( so->so_filtertag != NULL ) {
NSLDAPI_FREE( so->so_filtertag );
}
if ( so->so_defaultselectattr != NULL ) {
NSLDAPI_FREE( so->so_defaultselectattr );
}
if ( so->so_defaultselecttext != NULL ) {
NSLDAPI_FREE( so->so_defaultselecttext );
}
if ( so->so_salist != NULL ) {
struct ldap_searchattr *sa, *nextsa;
for ( sa = so->so_salist; sa != NULL; sa = nextsa ) {
nextsa = sa->sa_next;
if ( sa->sa_attrlabel != NULL ) {
NSLDAPI_FREE( sa->sa_attrlabel );
}
if ( sa->sa_attr != NULL ) {
NSLDAPI_FREE( sa->sa_attr );
}
if ( sa->sa_selectattr != NULL ) {
NSLDAPI_FREE( sa->sa_selectattr );
}
if ( sa->sa_selecttext != NULL ) {
NSLDAPI_FREE( sa->sa_selecttext );
}
NSLDAPI_FREE( sa );
}
}
if ( so->so_smlist != NULL ) {
struct ldap_searchmatch *sm, *nextsm;
for ( sm = so->so_smlist; sm != NULL; sm = nextsm ) {
nextsm = sm->sm_next;
if ( sm->sm_matchprompt != NULL ) {
NSLDAPI_FREE( sm->sm_matchprompt );
}
if ( sm->sm_filter != NULL ) {
NSLDAPI_FREE( sm->sm_filter );
}
NSLDAPI_FREE( sm );
}
}
NSLDAPI_FREE( so );
}
}
struct ldap_searchobj *
LDAP_CALL
ldap_first_searchobj( struct ldap_searchobj *solist )
{
return( solist );
}
struct ldap_searchobj *
LDAP_CALL
ldap_next_searchobj( struct ldap_searchobj *solist, struct ldap_searchobj *so )
{
return( so == NULLSEARCHOBJ ? so : so->so_next );
}
static int
read_next_searchobj( char **bufp, long *blenp, struct ldap_searchobj **sop,
int soversion )
{
int i, j, tokcnt;
char **toks;
struct ldap_searchobj *so;
struct ldap_searchattr **sa;
struct ldap_searchmatch **sm;
*sop = NULL;
/*
* Object type prompt comes first
*/
if (( tokcnt = nsldapi_next_line_tokens( bufp, blenp, &toks )) != 1 ) {
nsldapi_free_strarray( toks );
return( tokcnt == 0 ? 0 : LDAP_SEARCHPREF_ERR_SYNTAX );
}
if (( so = (struct ldap_searchobj *)NSLDAPI_CALLOC( 1,
sizeof( struct ldap_searchobj ))) == NULL ) {
nsldapi_free_strarray( toks );
return( LDAP_SEARCHPREF_ERR_MEM );
}
so->so_objtypeprompt = toks[ 0 ];
NSLDAPI_FREE( (char *)toks );
/*
* if this is post-version zero, options come next
*/
if ( soversion > LDAP_SEARCHPREF_VERSION_ZERO ) {
if (( tokcnt = nsldapi_next_line_tokens( bufp, blenp, &toks )) < 1 ) {
nsldapi_free_strarray( toks );
ldap_free_searchprefs( so );
return( LDAP_SEARCHPREF_ERR_SYNTAX );
}
for ( i = 0; toks[ i ] != NULL; ++i ) {
for ( j = 0; sobjoptions[ j ] != NULL; ++j ) {
if ( strcasecmp( toks[ i ], sobjoptions[ j ] ) == 0 ) {
so->so_options |= sobjoptvals[ j ];
}
}
}
nsldapi_free_strarray( toks );
}
/*
* "Fewer choices" prompt is next
*/
if (( tokcnt = nsldapi_next_line_tokens( bufp, blenp, &toks )) != 1 ) {
nsldapi_free_strarray( toks );
ldap_free_searchprefs( so );
return( LDAP_SEARCHPREF_ERR_SYNTAX );
}
so->so_prompt = toks[ 0 ];
NSLDAPI_FREE( (char *)toks );
/*
* Filter prefix for "More Choices" searching is next
*/
if (( tokcnt = nsldapi_next_line_tokens( bufp, blenp, &toks )) != 1 ) {
nsldapi_free_strarray( toks );
ldap_free_searchprefs( so );
return( LDAP_SEARCHPREF_ERR_SYNTAX );
}
so->so_filterprefix = toks[ 0 ];
NSLDAPI_FREE( (char *)toks );
/*
* "Fewer Choices" filter tag comes next
*/
if (( tokcnt = nsldapi_next_line_tokens( bufp, blenp, &toks )) != 1 ) {
nsldapi_free_strarray( toks );
ldap_free_searchprefs( so );
return( LDAP_SEARCHPREF_ERR_SYNTAX );
}
so->so_filtertag = toks[ 0 ];
NSLDAPI_FREE( (char *)toks );
/*
* Selection (disambiguation) attribute comes next
*/
if (( tokcnt = nsldapi_next_line_tokens( bufp, blenp, &toks )) != 1 ) {
nsldapi_free_strarray( toks );
ldap_free_searchprefs( so );
return( LDAP_SEARCHPREF_ERR_SYNTAX );
}
so->so_defaultselectattr = toks[ 0 ];
NSLDAPI_FREE( (char *)toks );
/*
* Label for selection (disambiguation) attribute
*/
if (( tokcnt = nsldapi_next_line_tokens( bufp, blenp, &toks )) != 1 ) {
nsldapi_free_strarray( toks );
ldap_free_searchprefs( so );
return( LDAP_SEARCHPREF_ERR_SYNTAX );
}
so->so_defaultselecttext = toks[ 0 ];
NSLDAPI_FREE( (char *)toks );
/*
* Search scope is next
*/
if (( tokcnt = nsldapi_next_line_tokens( bufp, blenp, &toks )) != 1 ) {
nsldapi_free_strarray( toks );
ldap_free_searchprefs( so );
return( LDAP_SEARCHPREF_ERR_SYNTAX );
}
if ( !strcasecmp(toks[ 0 ], "subtree" )) {
so->so_defaultscope = LDAP_SCOPE_SUBTREE;
} else if ( !strcasecmp(toks[ 0 ], "onelevel" )) {
so->so_defaultscope = LDAP_SCOPE_ONELEVEL;
} else if ( !strcasecmp(toks[ 0 ], "base" )) {
so->so_defaultscope = LDAP_SCOPE_BASE;
} else {
ldap_free_searchprefs( so );
return( LDAP_SEARCHPREF_ERR_SYNTAX );
}
nsldapi_free_strarray( toks );
/*
* "More Choices" search option list comes next
*/
sa = &( so->so_salist );
while (( tokcnt = nsldapi_next_line_tokens( bufp, blenp, &toks )) > 0 ) {
if ( tokcnt < 5 ) {
nsldapi_free_strarray( toks );
ldap_free_searchprefs( so );
return( LDAP_SEARCHPREF_ERR_SYNTAX );
}
if (( *sa = ( struct ldap_searchattr * )NSLDAPI_CALLOC( 1,
sizeof( struct ldap_searchattr ))) == NULL ) {
nsldapi_free_strarray( toks );
ldap_free_searchprefs( so );
return( LDAP_SEARCHPREF_ERR_MEM );
}
( *sa )->sa_attrlabel = toks[ 0 ];
( *sa )->sa_attr = toks[ 1 ];
( *sa )->sa_selectattr = toks[ 3 ];
( *sa )->sa_selecttext = toks[ 4 ];
/* Deal with bitmap */
( *sa )->sa_matchtypebitmap = 0;
for ( i = strlen( toks[ 2 ] ) - 1, j = 0; i >= 0; i--, j++ ) {
if ( toks[ 2 ][ i ] == '1' ) {
( *sa )->sa_matchtypebitmap |= (1 << j);
}
}
NSLDAPI_FREE( toks[ 2 ] );
NSLDAPI_FREE( ( char * ) toks );
sa = &(( *sa )->sa_next);
}
*sa = NULL;
/*
* Match types are last
*/
sm = &( so->so_smlist );
while (( tokcnt = nsldapi_next_line_tokens( bufp, blenp, &toks )) > 0 ) {
if ( tokcnt < 2 ) {
nsldapi_free_strarray( toks );
ldap_free_searchprefs( so );
return( LDAP_SEARCHPREF_ERR_SYNTAX );
}
if (( *sm = ( struct ldap_searchmatch * )NSLDAPI_CALLOC( 1,
sizeof( struct ldap_searchmatch ))) == NULL ) {
nsldapi_free_strarray( toks );
ldap_free_searchprefs( so );
return( LDAP_SEARCHPREF_ERR_MEM );
}
( *sm )->sm_matchprompt = toks[ 0 ];
( *sm )->sm_filter = toks[ 1 ];
NSLDAPI_FREE( ( char * ) toks );
sm = &(( *sm )->sm_next );
}
*sm = NULL;
*sop = so;
return( 0 );
}

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,319 @@
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is Mozilla Communicator client code, released
* March 31, 1998.
*
* The Initial Developer of the Original Code is
* Netscape Communications Corporation.
* Portions created by the Initial Developer are Copyright (C) 1998-1999
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
*
* Alternatively, the contents of this file may be used under the terms of
* either of the GNU General Public License Version 2 or later (the "GPL"),
* or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
/* tmpltest.c - implements a test/config templates. */
#include <stdio.h>
#include <sys/types.h>
#ifdef _WINDOWS
#include <windows.h>
#endif
#include "ldap-int.h"
#include "disptmpl.h"
#include "srchpref.h"
#ifdef MACOS
#include <stdlib.h>
#include <console.h>
#endif /* MACOS */
#ifdef NEEDPROTOS
void dump_tmpl( struct ldap_disptmpl *tmpl );
void dump_srchpref( struct ldap_searchobj *sp );
#else /* NEEDPROTOS */
void dump_tmpl();
void dump_srchpref();
#endif /* NEEDPROTOS */
#define NULLSTRINGIFNULL( s ) ( s == NULL ? "(null)" : s )
int
main( int argc, char **argv )
{
struct ldap_disptmpl *templates, *dtp;
struct ldap_searchobj *so, *sop;
int err;
#ifdef MACOS
ccommand( &argv );
for ( argc = 0; argv[ argc ] != NULL; ++argc ) {
;
}
cshow( stdout );
#endif /* MACOS */
if (( err = ldap_init_templates( "ldaptemplates.conf", &templates ))
!= 0 ) {
fprintf( stderr, "ldap_init_templates failed (%d)\n", err );
exit( 1 );
}
if (( err = ldap_init_searchprefs( "ldapsearchprefs.conf", &so ))
!= 0 ) {
fprintf( stderr, "ldap_init_searchprefs failed (%d)\n", err );
exit( 1 );
}
if ( argc == 1 ) {
printf( "*** Display Templates:\n" );
for ( dtp = ldap_first_disptmpl( templates ); dtp != NULLDISPTMPL;
dtp = ldap_next_disptmpl( templates, dtp )) {
dump_tmpl( dtp );
printf( "\n\n" );
}
printf( "\n\n*** Search Objects:\n" );
for ( sop = ldap_first_searchobj( so ); sop != NULLSEARCHOBJ;
sop = ldap_next_searchobj( so, sop )) {
dump_srchpref( sop );
printf( "\n\n" );
}
} else {
if (( dtp = ldap_oc2template( ++argv, templates )) == NULL ) {
fprintf( stderr, "no matching template found\n" );
} else {
dump_tmpl( dtp );
}
}
ldap_free_templates( templates );
ldap_free_searchprefs( so );
exit( 0 );
}
static char *syn_name[] = {
"?", "CIS", "MLS", "DN", "BOOL", "JPEG", "JPEGBTN", "FAX", "FAXBTN",
"AUDIOBTN", "TIME", "DATE", "URL", "SEARCHACT", "LINKACT", "ADDDNACT",
"VERIFYACT",
};
static char *syn_type[] = {
"?", "txt", "img", "?", "bool", "?", "?", "?", "btn",
"?", "?", "?", "?", "?", "?", "?",
"action", "?"
};
static char *includeattrs[] = { "objectClass", "sn", NULL };
static char *item_opts[] = {
"ro", "sort", "1val", "hide", "required", "hideiffalse", NULL
};
static unsigned long item_opt_vals[] = {
LDAP_DITEM_OPT_READONLY, LDAP_DITEM_OPT_SORTVALUES,
LDAP_DITEM_OPT_SINGLEVALUED, LDAP_DITEM_OPT_HIDEIFEMPTY,
LDAP_DITEM_OPT_VALUEREQUIRED, LDAP_DITEM_OPT_HIDEIFFALSE,
};
void
dump_tmpl( struct ldap_disptmpl *tmpl )
{
struct ldap_tmplitem *rowp, *colp;
int i, rowcnt, colcnt;
char **fetchattrs;
struct ldap_oclist *ocp;
struct ldap_adddeflist *adp;
printf( "** Template \"%s\" (plural \"%s\", icon \"%s\")\n",
NULLSTRINGIFNULL( tmpl->dt_name ),
NULLSTRINGIFNULL( tmpl->dt_pluralname ),
NULLSTRINGIFNULL( tmpl->dt_iconname ));
printf( "object class list:\n" );
for ( ocp = tmpl->dt_oclist; ocp != NULL; ocp = ocp->oc_next ) {
for ( i = 0; ocp->oc_objclasses[ i ] != NULL; ++i ) {
printf( "%s%s", i == 0 ? " " : " & ",
NULLSTRINGIFNULL( ocp->oc_objclasses[ i ] ));
}
putchar( '\n' );
}
putchar( '\n' );
printf( "template options: " );
if ( tmpl->dt_options == 0L ) {
printf( "NONE\n" );
} else {
printf( "%s %s %s\n", LDAP_IS_DISPTMPL_OPTION_SET( tmpl,
LDAP_DTMPL_OPT_ADDABLE ) ? "addable" : "",
LDAP_IS_DISPTMPL_OPTION_SET( tmpl, LDAP_DTMPL_OPT_ALLOWMODRDN )
? "modrdn" : "",
LDAP_IS_DISPTMPL_OPTION_SET( tmpl, LDAP_DTMPL_OPT_ALTVIEW )
? "altview" : "" );
}
printf( "authenticate as attribute: %s\n", tmpl->dt_authattrname != NULL ?
tmpl->dt_authattrname : "<default>" );
printf( "default RDN attribute: %s\n", tmpl->dt_defrdnattrname != NULL ?
tmpl->dt_defrdnattrname : "NONE" );
printf( "default add location: %s\n", tmpl->dt_defaddlocation != NULL ?
tmpl->dt_defaddlocation : "NONE" );
printf( "\nnew entry value default rules:\n" );
for ( adp = tmpl->dt_adddeflist; adp != NULL; adp = adp->ad_next ) {
if ( adp->ad_source == LDAP_ADSRC_CONSTANTVALUE ) {
printf( " attribute %s <-- constant value \"%s\"\n",
NULLSTRINGIFNULL( adp->ad_attrname),
NULLSTRINGIFNULL( adp->ad_value ));
} else {
printf( " attribute %s <-- adder's DN\n",
NULLSTRINGIFNULL( adp->ad_attrname ));
}
}
putchar( '\n' );
printf( "\nfetch attributes & values:\n" );
if (( fetchattrs = ldap_tmplattrs( tmpl, includeattrs, 1,
LDAP_SYN_OPT_DEFER )) == NULL ) {
printf( " <none>\n" );
} else {
for ( i = 0; fetchattrs[ i ] != NULL; ++i ) {
printf( " %s\n", fetchattrs[ i ] );
free( fetchattrs[ i ] );
}
free( (char *)fetchattrs );
}
printf( "\nfetch attributes only:\n" );
if (( fetchattrs = ldap_tmplattrs( tmpl, NULL, 0,
LDAP_SYN_OPT_DEFER )) == NULL ) {
printf( " <none>\n" );
} else {
for ( i = 0; fetchattrs[ i ] != NULL; ++i ) {
printf( " %s\n", fetchattrs[ i ] );
free( fetchattrs[ i ] );
}
free( (char *)fetchattrs );
}
printf( "\ntemplate items:\n" );
rowcnt = 0;
for ( rowp = ldap_first_tmplrow( tmpl ); rowp != NULLTMPLITEM;
rowp = ldap_next_tmplrow( tmpl, rowp )) {
++rowcnt;
colcnt = 0;
for ( colp = ldap_first_tmplcol( tmpl, rowp ); colp != NULLTMPLITEM;
colp = ldap_next_tmplcol( tmpl, rowp, colp )) {
++colcnt;
printf( " %2d-%d: %s (%s%s", rowcnt, colcnt,
syn_name[ colp->ti_syntaxid & 0x0000FFFF ],
syn_type[ LDAP_GET_SYN_TYPE( colp->ti_syntaxid ) >> 24 ],
(( LDAP_GET_SYN_OPTIONS( colp->ti_syntaxid ) &
LDAP_SYN_OPT_DEFER ) != 0 ) ? ",defer" : "" );
for ( i = 0; item_opts[ i ] != NULL; ++i ) {
if ( LDAP_IS_TMPLITEM_OPTION_SET( colp, item_opt_vals[ i ] )) {
printf( ",%s", NULLSTRINGIFNULL( item_opts[ i ] ));
}
}
printf( "), %s, %s", NULLSTRINGIFNULL( colp->ti_attrname ),
NULLSTRINGIFNULL( colp->ti_label ));
if ( colp->ti_args != NULL ) {
printf( ",args=" );
for ( i = 0; colp->ti_args[ i ] != NULL; ++i ) {
printf( "<%s>", NULLSTRINGIFNULL( colp->ti_args[ i ] ));
}
}
putchar( '\n' );
}
}
}
void
dump_srchpref( struct ldap_searchobj *so )
{
int i;
struct ldap_searchattr *sa;
struct ldap_searchmatch *sm;
printf( "Object type prompt: %s\n",
NULLSTRINGIFNULL( so->so_objtypeprompt ));
printf( "Options: %s\n",
LDAP_IS_SEARCHOBJ_OPTION_SET( so, LDAP_SEARCHOBJ_OPT_INTERNAL ) ?
"internal" : "NONE" );
printf( "Prompt: %s\n", NULLSTRINGIFNULL( so->so_prompt ));
printf( "Scope: " );
switch ( so->so_defaultscope ) {
case LDAP_SCOPE_BASE:
printf( "LDAP_SCOPE_BASE" );
break;
case LDAP_SCOPE_ONELEVEL:
printf( "LDAP_SCOPE_ONELEVEL" );
break;
case LDAP_SCOPE_SUBTREE:
printf( "LDAP_SCOPE_SUBTREE" );
break;
default:
printf("*** unknown!" );
}
puts( "\n" );
printf( "Filter prefix: %s\n",
NULLSTRINGIFNULL( so->so_filterprefix ));
printf( "Filter tag: %s\n",
NULLSTRINGIFNULL( so->so_filtertag ));
printf( "Default select attr: %s\n",
NULLSTRINGIFNULL( so->so_defaultselectattr ));
printf( "Default select text: %s\n",
NULLSTRINGIFNULL( so->so_defaultselecttext ));
printf( "Searchable attributes ---- \n" );
for ( sa = so->so_salist; sa != NULL; sa = sa->sa_next ) {
printf( " Label: %s\n", NULLSTRINGIFNULL( sa->sa_attrlabel ));
printf( " Attribute: %s\n", NULLSTRINGIFNULL( sa->sa_attr ));
printf( " Select attr: %s\n", NULLSTRINGIFNULL( sa->sa_selectattr ));
printf( " Select text: %s\n", NULLSTRINGIFNULL( sa->sa_selecttext ));
printf( " Match types ---- \n" );
for ( i = 0, sm = so->so_smlist; sm != NULL; i++, sm = sm->sm_next ) {
if (( sa->sa_matchtypebitmap >> i ) & 1 ) {
printf( " %s (%s)\n",
NULLSTRINGIFNULL( sm->sm_matchprompt ),
NULLSTRINGIFNULL( sm->sm_filter ));
}
}
}
}

View file

@ -0,0 +1,563 @@
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is Mozilla Communicator client code, released
* March 31, 1998.
*
* The Initial Developer of the Original Code is
* Netscape Communications Corporation.
* Portions created by the Initial Developer are Copyright (C) 1998-1999
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
*
* Alternatively, the contents of this file may be used under the terms of
* either of the GNU General Public License Version 2 or later (the "GPL"),
* or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
/*
* Copyright (c) 1990 Regents of the University of Michigan.
* All rights reserved.
*/
/*
* ufn.c
*/
#if 0
#ifndef lint
static char copyright[] = "@(#) Copyright (c) 1993 Regents of the University of Michigan.\nAll rights reserved.\n";
#endif
#endif
#include "ldap-int.h"
typedef int (LDAP_CALL *cancelptype)( void *cancelparm );
static int ldap_ufn_search_ctx( LDAP *ld, char **ufncomp, int ncomp,
char *prefix, char **attrs, int attrsonly,
LDAPMessage **res, LDAP_CANCELPROC_CALLBACK *cancelproc, void *cancelparm,
char *tag1, char *tag2, char *tag3 );
static LDAPMessage *ldap_msg_merge( LDAP *ld, LDAPMessage *a, LDAPMessage *b );
static LDAPMessage *ldap_ufn_expand( LDAP *ld,
LDAP_CANCELPROC_CALLBACK *cancelproc, void *cancelparm, char **dns,
char *filter, int scope, char **attrs, int aonly, int *err );
/*
* ldap_ufn_search_ctx - do user friendly searching; provide cancel feature;
* specify ldapfilter.conf tags for each phase of search
*
* ld LDAP descriptor
* ufncomp the exploded user friendly name to look for
* ncomp number of elements in ufncomp
* prefix where to start searching
* attrs list of attribute types to return for matches
* attrsonly 1 => attributes only 0 => attributes and values
* res will contain the result of the search
* cancelproc routine that returns non-zero if operation should be
* cancelled. This can be NULL. If it is non-NULL, the
* routine will be called periodically.
* cancelparm void * that is passed to cancelproc
* tag[123] the ldapfilter.conf tag that will be used in phases
* 1, 2, and 3 of the search, respectively
*
* Example:
* char *attrs[] = { "mail", "title", 0 };
* char *ufncomp[] = { "howes", "umich", "us", 0 }
* LDAPMessage *res;
* error = ldap_ufn_search_ctx( ld, ufncomp, 3, NULL, attrs, attrsonly,
* &res, acancelproc, along, "ufn first",
* "ufn intermediate", "ufn last" );
*/
static int
ldap_ufn_search_ctx(
LDAP *ld,
char **ufncomp,
int ncomp,
char *prefix,
char **attrs,
int attrsonly,
LDAPMessage **res,
LDAP_CANCELPROC_CALLBACK *cancelproc,
void *cancelparm,
char *tag1,
char *tag2,
char *tag3
)
{
char *dn, *ftag = NULL;
char **dns = NULL;
int max, i, err, scope = 0, phase, tries;
LDAPFiltInfo *fi;
LDAPMessage *tmpcand;
LDAPMessage *candidates;
static char *objattrs[] = { "objectClass", NULL };
/*
* look up ufn components from most to least significant.
* there are 3 phases.
* phase 1 search the root for orgs or countries
* phase 2 search for orgs
* phase 3 search for a person
* in phases 1 and 2, we are building a list of candidate DNs,
* below which we will search for the final component of the ufn.
* for each component we try the filters listed in the
* filterconfig file, first one-level (except the last compoment),
* then subtree. if any of them produce any results, we go on to
* the next component.
*/
*res = NULL;
candidates = NULL;
phase = 1;
for ( ncomp--; ncomp != -1; ncomp-- ) {
if ( *ufncomp[ncomp] == '"' ) {
char *quote;
if ( (quote = strrchr( ufncomp[ncomp], '"' )) != NULL )
*quote = '\0';
strcpy( ufncomp[ncomp], ufncomp[ncomp] + 1 );
}
if ( ncomp == 0 )
phase = 3;
switch ( phase ) {
case 1:
ftag = tag1;
scope = LDAP_SCOPE_ONELEVEL;
break;
case 2:
ftag = tag2;
scope = LDAP_SCOPE_ONELEVEL;
break;
case 3:
ftag = tag3;
scope = LDAP_SCOPE_SUBTREE;
break;
}
/*
* construct an array of DN's to search below from the
* list of candidates.
*/
if ( candidates == NULL ) {
if ( prefix != NULL ) {
if ( (dns = (char **)NSLDAPI_MALLOC(
sizeof(char *) * 2 )) == NULL ) {
err = LDAP_NO_MEMORY;
LDAP_SET_LDERRNO( ld, err, NULL, NULL );
return( err );
}
dns[0] = nsldapi_strdup( prefix );
dns[1] = NULL;
} else {
dns = NULL;
}
} else {
i = 0, max = 0;
for ( tmpcand = candidates; tmpcand != NULL &&
tmpcand->lm_msgtype != LDAP_RES_SEARCH_RESULT;
tmpcand = tmpcand->lm_chain )
{
if ( (dn = ldap_get_dn( ld, tmpcand )) == NULL )
continue;
if ( dns == NULL ) {
if ( (dns = (char **)NSLDAPI_MALLOC(
sizeof(char *) * 8 )) == NULL ) {
err = LDAP_NO_MEMORY;
LDAP_SET_LDERRNO( ld, err,
NULL, NULL );
return( err );
}
max = 8;
} else if ( i >= max ) {
if ( (dns = (char **)NSLDAPI_REALLOC(
dns, sizeof(char *) * 2 * max ))
== NULL ) {
err = LDAP_NO_MEMORY;
LDAP_SET_LDERRNO( ld, err,
NULL, NULL );
return( err );
}
max *= 2;
}
dns[i++] = dn;
dns[i] = NULL;
}
ldap_msgfree( candidates );
candidates = NULL;
}
tries = 0;
tryagain:
tries++;
for ( fi = ldap_getfirstfilter( ld->ld_filtd, ftag,
ufncomp[ncomp] ); fi != NULL;
fi = ldap_getnextfilter( ld->ld_filtd ) )
{
if ( (candidates = ldap_ufn_expand( ld, cancelproc,
cancelparm, dns, fi->lfi_filter, scope,
phase == 3 ? attrs : objattrs,
phase == 3 ? attrsonly : 1, &err )) != NULL )
{
break;
}
if ( err == -1 || err == LDAP_USER_CANCELLED ) {
if ( dns != NULL ) {
ldap_value_free( dns );
dns = NULL;
}
return( err );
}
}
if ( candidates == NULL ) {
if ( tries < 2 && phase != 3 ) {
scope = LDAP_SCOPE_SUBTREE;
goto tryagain;
} else {
if ( dns != NULL ) {
ldap_value_free( dns );
dns = NULL;
}
return( err );
}
}
/* go on to the next component */
if ( phase == 1 )
phase++;
if ( dns != NULL ) {
ldap_value_free( dns );
dns = NULL;
}
}
*res = candidates;
return( err );
}
int
LDAP_CALL
ldap_ufn_search_ct( LDAP *ld, char *ufn, char **attrs, int attrsonly,
LDAPMessage **res, LDAP_CANCELPROC_CALLBACK *cancelproc, void *cancelparm,
char *tag1, char *tag2, char *tag3 )
{
char **ufncomp, **prefixcomp;
char *pbuf;
int ncomp, pcomp, i, err = 0;
/* getfilter stuff must be inited before we are called */
if ( ld->ld_filtd == NULL ) {
err = LDAP_PARAM_ERROR;
LDAP_SET_LDERRNO( ld, err, NULL, NULL );
return( err );
}
/* call ldap_explode_dn() to break the ufn into its components */
if ( (ufncomp = ldap_explode_dn( ufn, 0 )) == NULL ) {
err = LDAP_LOCAL_ERROR;
LDAP_SET_LDERRNO( ld, err, NULL, NULL );
return( err );
}
for ( ncomp = 0; ufncomp[ncomp] != NULL; ncomp++ )
; /* NULL */
/* more than two components => try it fully qualified first */
if ( ncomp > 2 || ld->ld_ufnprefix == NULL ) {
err = ldap_ufn_search_ctx( ld, ufncomp, ncomp, NULL, attrs,
attrsonly, res, cancelproc, cancelparm, tag1, tag2, tag3 );
if ( ldap_count_entries( ld, *res ) > 0 ) {
ldap_value_free( ufncomp );
return( err );
} else {
ldap_msgfree( *res );
*res = NULL;
}
}
if ( ld->ld_ufnprefix == NULL ) {
ldap_value_free( ufncomp );
return( err );
}
/* if that failed, or < 2 components, use the prefix */
if ( (prefixcomp = ldap_explode_dn( ld->ld_ufnprefix, 0 )) == NULL ) {
ldap_value_free( ufncomp );
err = LDAP_LOCAL_ERROR;
LDAP_SET_LDERRNO( ld, err, NULL, NULL );
return( err );
}
for ( pcomp = 0; prefixcomp[pcomp] != NULL; pcomp++ )
; /* NULL */
if ( (pbuf = (char *)NSLDAPI_MALLOC( strlen( ld->ld_ufnprefix ) + 1 ))
== NULL ) {
ldap_value_free( ufncomp );
ldap_value_free( prefixcomp );
err = LDAP_NO_MEMORY;
LDAP_SET_LDERRNO( ld, err, NULL, NULL );
return( err );
}
for ( i = 0; i < pcomp; i++ ) {
int j;
*pbuf = '\0';
for ( j = i; j < pcomp; j++ ) {
strcat( pbuf, prefixcomp[j] );
if ( j + 1 < pcomp )
strcat( pbuf, "," );
}
err = ldap_ufn_search_ctx( ld, ufncomp, ncomp, pbuf, attrs,
attrsonly, res, cancelproc, cancelparm, tag1, tag2, tag3 );
if ( ldap_count_entries( ld, *res ) > 0 ) {
break;
} else {
ldap_msgfree( *res );
*res = NULL;
}
}
ldap_value_free( ufncomp );
ldap_value_free( prefixcomp );
NSLDAPI_FREE( pbuf );
return( err );
}
/*
* same as ldap_ufn_search_ct, except without the ability to specify
* ldapfilter.conf tags.
*/
int
LDAP_CALL
ldap_ufn_search_c( LDAP *ld, char *ufn, char **attrs, int attrsonly,
LDAPMessage **res, LDAP_CANCELPROC_CALLBACK *cancelproc, void *cancelparm )
{
return( ldap_ufn_search_ct( ld, ufn, attrs, attrsonly, res, cancelproc,
cancelparm, "ufn first", "ufn intermediate", "ufn last" ) );
}
/*
* same as ldap_ufn_search_c without the cancel function
*/
int
LDAP_CALL
ldap_ufn_search_s( LDAP *ld, char *ufn, char **attrs, int attrsonly,
LDAPMessage **res )
{
struct timeval tv;
tv.tv_sec = ld->ld_timelimit;
return( ldap_ufn_search_ct( ld, ufn, attrs, attrsonly, res,
ld->ld_timelimit ? ldap_ufn_timeout : NULL,
ld->ld_timelimit ? (void *) &tv : NULL,
"ufn first", "ufn intermediate", "ufn last" ) );
}
/*
* ldap_msg_merge - merge two ldap search result chains. the more
* serious of the two error result codes is kept.
*/
static LDAPMessage *
ldap_msg_merge( LDAP *ld, LDAPMessage *a, LDAPMessage *b )
{
LDAPMessage *end, *aprev, *aend, *bprev, *bend;
if ( a == NULL )
return( b );
if ( b == NULL )
return( a );
/* find the ends of the a and b chains */
aprev = NULL;
for ( aend = a; aend->lm_chain != NULL; aend = aend->lm_chain )
aprev = aend;
bprev = NULL;
for ( bend = b; bend->lm_chain != NULL; bend = bend->lm_chain )
bprev = bend;
/* keep result a */
if ( ldap_result2error( ld, aend, 0 ) != LDAP_SUCCESS ) {
/* remove result b */
ldap_msgfree( bend );
if ( bprev != NULL )
bprev->lm_chain = NULL;
else
b = NULL;
end = aend;
if ( aprev != NULL )
aprev->lm_chain = NULL;
else
a = NULL;
/* keep result b */
} else {
/* remove result a */
ldap_msgfree( aend );
if ( aprev != NULL )
aprev->lm_chain = NULL;
else
a = NULL;
end = bend;
if ( bprev != NULL )
bprev->lm_chain = NULL;
else
b = NULL;
}
if ( (a == NULL && b == NULL) || (a == NULL && bprev == NULL) ||
(b == NULL && aprev == NULL) )
return( end );
if ( a == NULL ) {
bprev->lm_chain = end;
return( b );
} else if ( b == NULL ) {
aprev->lm_chain = end;
return( a );
} else {
bprev->lm_chain = end;
aprev->lm_chain = b;
return( a );
}
}
static LDAPMessage *
ldap_ufn_expand( LDAP *ld, LDAP_CANCELPROC_CALLBACK *cancelproc,
void *cancelparm, char **dns, char *filter, int scope,
char **attrs, int aonly, int *err )
{
LDAPMessage *tmpcand, *tmpres;
char *dn;
int i, msgid;
struct timeval tv;
/* search for this component below the current candidates */
tmpcand = NULL;
i = 0;
do {
if ( dns != NULL )
dn = dns[i];
else
dn = "";
if (( msgid = ldap_search( ld, dn, scope, filter, attrs,
aonly )) == -1 ) {
ldap_msgfree( tmpcand );
tmpcand = NULL;
*err = LDAP_GET_LDERRNO( ld, NULL, NULL );
/*
* Compiling with gcc-4.2 on Mac:
* gcc-4.2 -arch ppc -c -o ufn.o -gdwarf-2 -01 ufn.c
* having a return NULL statement here causes gcc to
* hang. Therefore set tmpcand to null (above) and break
* out of this loop to make gcc happy.
*/
break;
}
tv.tv_sec = 0;
tv.tv_usec = 100000; /* 1/10 of a second */
do {
*err = ldap_result( ld, msgid, 1, &tv, &tmpres );
if ( *err == 0 && cancelproc != NULL &&
(*cancelproc)( cancelparm ) != 0 ) {
ldap_abandon( ld, msgid );
*err = LDAP_USER_CANCELLED;
LDAP_SET_LDERRNO( ld, *err, NULL, NULL );
}
} while ( *err == 0 );
if ( *err == LDAP_USER_CANCELLED || *err < 0 ||
( *err = ldap_result2error( ld, tmpres, 0 )) == -1 ) {
ldap_msgfree( tmpcand );
return( NULL );
}
tmpcand = ldap_msg_merge( ld, tmpcand, tmpres );
i++;
} while ( dns != NULL && dns[i] != NULL );
/* Catch the tmpcand = NULL case as required by breaking out the loop
* to prevent gcc-4.2 hanging on Mac.
*/
if (!tmpcand)
return NULL;
if ( ldap_count_entries( ld, tmpcand ) > 0 ) {
return( tmpcand );
} else {
ldap_msgfree( tmpcand );
return( NULL );
}
}
/*
* ldap_ufn_setfilter - set the filter config file used in ufn searching
*/
LDAPFiltDesc *
LDAP_CALL
ldap_ufn_setfilter( LDAP *ld, char *fname )
{
if ( ld->ld_filtd != NULL )
ldap_getfilter_free( ld->ld_filtd );
return( ld->ld_filtd = ldap_init_getfilter( fname ) );
}
void
LDAP_CALL
ldap_ufn_setprefix( LDAP *ld, char *prefix )
{
if ( ld->ld_ufnprefix != NULL )
NSLDAPI_FREE( ld->ld_ufnprefix );
ld->ld_ufnprefix = nsldapi_strdup( prefix );
}
int
LDAP_C
ldap_ufn_timeout( void *tvparam )
{
struct timeval *tv;
tv = (struct timeval *)tvparam;
if ( tv->tv_sec != 0 ) {
tv->tv_usec = tv->tv_sec * 1000000; /* sec => micro sec */
tv->tv_sec = 0;
}
tv->tv_usec -= 100000; /* 1/10 of a second */
return( tv->tv_usec <= 0 ? 1 : 0 );
}

View file

@ -0,0 +1,248 @@
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is Mozilla Communicator client code, released
* March 31, 1998.
*
* The Initial Developer of the Original Code is
* Netscape Communications Corporation.
* Portions created by the Initial Developer are Copyright (C) 1998-1999
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
*
* Alternatively, the contents of this file may be used under the terms of
* either of the GNU General Public License Version 2 or later (the "GPL"),
* or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
/*
* Copyright (c) 1990 Regents of the University of Michigan.
* All rights reserved.
*/
/*
* unbind.c
*/
#if 0
#ifndef lint
static char copyright[] = "@(#) Copyright (c) 1990 Regents of the University of Michigan.\nAll rights reserved.\n";
#endif
#endif
#include "ldap-int.h"
int
LDAP_CALL
ldap_unbind( LDAP *ld )
{
LDAPDebug( LDAP_DEBUG_TRACE, "ldap_unbind\n", 0, 0, 0 );
return( ldap_ld_free( ld, NULL, NULL, 1 ) );
}
int
LDAP_CALL
ldap_unbind_s( LDAP *ld )
{
return( ldap_ld_free( ld, NULL, NULL, 1 ));
}
int
LDAP_CALL
ldap_unbind_ext( LDAP *ld, LDAPControl **serverctrls,
LDAPControl **clientctrls )
{
return( ldap_ld_free( ld, serverctrls, clientctrls, 1 ));
}
/*
* Dispose of the LDAP session ld, including all associated connections
* and resources. If close is non-zero, an unbind() request is sent as well.
*/
int
ldap_ld_free( LDAP *ld, LDAPControl **serverctrls,
LDAPControl **clientctrls, int close )
{
LDAPMessage *lm, *next;
int err = LDAP_SUCCESS;
LDAPRequest *lr, *nextlr;
if ( !NSLDAPI_VALID_LDAP_POINTER( ld )) {
return( LDAP_PARAM_ERROR );
}
if ( ld->ld_sbp->sb_naddr == 0 ) {
LDAP_MUTEX_LOCK( ld, LDAP_REQ_LOCK );
/* free LDAP structure and outstanding requests/responses */
for ( lr = ld->ld_requests; lr != NULL; lr = nextlr ) {
nextlr = lr->lr_next;
nsldapi_free_request( ld, lr, 0 );
}
LDAP_MUTEX_UNLOCK( ld, LDAP_REQ_LOCK );
/* free and unbind from all open connections */
LDAP_MUTEX_LOCK( ld, LDAP_CONN_LOCK );
while ( ld->ld_conns != NULL ) {
nsldapi_free_connection( ld, ld->ld_conns, serverctrls,
clientctrls, 1, close );
}
LDAP_MUTEX_UNLOCK( ld, LDAP_CONN_LOCK );
} else {
int i;
for ( i = 0; i < ld->ld_sbp->sb_naddr; ++i ) {
NSLDAPI_FREE( ld->ld_sbp->sb_addrs[ i ] );
}
NSLDAPI_FREE( ld->ld_sbp->sb_addrs );
NSLDAPI_FREE( ld->ld_sbp->sb_fromaddr );
}
LDAP_MUTEX_LOCK( ld, LDAP_RESP_LOCK );
for ( lm = ld->ld_responses; lm != NULL; lm = next ) {
next = lm->lm_next;
ldap_msgfree( lm );
}
LDAP_MUTEX_UNLOCK( ld, LDAP_RESP_LOCK );
/* call cache unbind function to allow it to clean up after itself */
if ( ld->ld_cache_unbind != NULL ) {
LDAP_MUTEX_LOCK( ld, LDAP_CACHE_LOCK );
(void)ld->ld_cache_unbind( ld, 0, 0 );
LDAP_MUTEX_UNLOCK( ld, LDAP_CACHE_LOCK );
}
/* call the dispose handle I/O callback if one is defined */
if ( ld->ld_extdisposehandle_fn != NULL ) {
/*
* We always pass the session extended I/O argument to
* the dispose handle callback.
*/
ld->ld_extdisposehandle_fn( ld, ld->ld_ext_session_arg );
}
if ( ld->ld_error != NULL )
NSLDAPI_FREE( ld->ld_error );
if ( ld->ld_matched != NULL )
NSLDAPI_FREE( ld->ld_matched );
if ( ld->ld_host != NULL )
NSLDAPI_FREE( ld->ld_host );
if ( ld->ld_ufnprefix != NULL )
NSLDAPI_FREE( ld->ld_ufnprefix );
if ( ld->ld_filtd != NULL )
ldap_getfilter_free( ld->ld_filtd );
if ( ld->ld_abandoned != NULL )
NSLDAPI_FREE( ld->ld_abandoned );
if ( ld->ld_sbp != NULL )
ber_sockbuf_free( ld->ld_sbp );
if ( ld->ld_defhost != NULL )
NSLDAPI_FREE( ld->ld_defhost );
if ( ld->ld_servercontrols != NULL )
ldap_controls_free( ld->ld_servercontrols );
if ( ld->ld_clientcontrols != NULL )
ldap_controls_free( ld->ld_clientcontrols );
if ( ld->ld_preferred_language != NULL )
NSLDAPI_FREE( ld->ld_preferred_language );
nsldapi_iostatus_free( ld );
#ifdef LDAP_SASLIO_HOOKS
NSLDAPI_FREE( ld->ld_def_sasl_mech );
NSLDAPI_FREE( ld->ld_def_sasl_realm );
NSLDAPI_FREE( ld->ld_def_sasl_authcid );
NSLDAPI_FREE( ld->ld_def_sasl_authzid );
#endif
/*
* XXXmcs: should use cache function pointers to hook in memcache
*/
if ( ld->ld_memcache != NULL ) {
ldap_memcache_set( ld, NULL );
}
/* free all mutexes we have allocated */
nsldapi_mutex_free_all( ld );
NSLDAPI_FREE( ld->ld_mutex );
NSLDAPI_FREE( (char *) ld );
return( err );
}
int
nsldapi_send_unbind( LDAP *ld, Sockbuf *sb, LDAPControl **serverctrls,
LDAPControl **clientctrls )
{
BerElement *ber;
int err, msgid;
LDAPDebug( LDAP_DEBUG_TRACE, "nsldapi_send_unbind\n", 0, 0, 0 );
/* create a message to send */
if (( err = nsldapi_alloc_ber_with_options( ld, &ber ))
!= LDAP_SUCCESS ) {
return( err );
}
/* fill it in */
LDAP_MUTEX_LOCK( ld, LDAP_MSGID_LOCK );
msgid = ++ld->ld_msgid;
LDAP_MUTEX_UNLOCK( ld, LDAP_MSGID_LOCK );
if ( ber_printf( ber, "{itn", msgid, LDAP_REQ_UNBIND ) == -1 ) {
ber_free( ber, 1 );
err = LDAP_ENCODING_ERROR;
LDAP_SET_LDERRNO( ld, err, NULL, NULL );
return( err );
}
if (( err = nsldapi_put_controls( ld, serverctrls, 1, ber ))
!= LDAP_SUCCESS ) {
ber_free( ber, 1 );
return( err );
}
/* send the message */
err = nsldapi_send_ber_message( ld, sb, ber, 1 /* free ber */,
0 /* will not handle EPIPE */ );
if ( err != 0 ) {
ber_free( ber, 1 );
if (err != -2 ) {
/*
* Message could not be sent, and the reason is
* something other than a "would block" error.
* Note that we ignore "would block" errors because
* it is not critical that an UnBind request
* actually reach the LDAP server.
*/
err = LDAP_SERVER_DOWN;
LDAP_SET_LDERRNO( ld, err, NULL, NULL );
return( err );
}
}
return( LDAP_SUCCESS );
}

View file

@ -0,0 +1,84 @@
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is Mozilla Communicator client code, released
* March 31, 1998.
*
* The Initial Developer of the Original Code is
* Netscape Communications Corporation.
* Portions created by the Initial Developer are Copyright (C) 1998-1999
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
*
* Alternatively, the contents of this file may be used under the terms of
* either of the GNU General Public License Version 2 or later (the "GPL"),
* or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
/*
* LIBLDAP unescape.c -- LDAP URL un-escape routines
* We also tolerate URLs that look like: <ldapurl> and <URL:ldapurl>
*/
#include "ldap-int.h"
static int unhex( char c );
void
nsldapi_hex_unescape( char *s )
{
/*
* Remove URL hex escapes from s... done in place. The basic concept for
* this routine is borrowed from the WWW library HTUnEscape() routine.
*/
char *p;
for ( p = s; *s != '\0'; ++s ) {
if ( *s == '%' ) {
if ( *++s == '\0' ) {
break;
}
*p = unhex( *s ) << 4;
if ( *++s == '\0' ) {
break;
}
*p++ += unhex( *s );
} else {
*p++ = *s;
}
}
*p = '\0';
}
static int
unhex( char c )
{
return( c >= '0' && c <= '9' ? c - '0'
: c >= 'A' && c <= 'F' ? c - 'A' + 10
: c - 'a' + 10 );
}

View file

@ -0,0 +1,527 @@
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is Mozilla Communicator client code, released
* March 31, 1998.
*
* The Initial Developer of the Original Code is
* Netscape Communications Corporation.
* Portions created by the Initial Developer are Copyright (C) 1998-1999
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
*
* Alternatively, the contents of this file may be used under the terms of
* either of the GNU General Public License Version 2 or later (the "GPL"),
* or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
/*
* Copyright (c) 1996 Regents of the University of Michigan.
* All rights reserved.
*
*/
/* LIBLDAP url.c -- LDAP URL related routines
*
* LDAP URLs look like this:
* l d a p : / / [ hostport ] [ / dn [ ? [ attributes ] [ ? [ scope ]
* [ ? [ filter ] [ ? extensions ] ] ] ] ]
*
* where:
* hostport is a host or a host:port list that can be space-separated.
* attributes is a comma separated list
* scope is one of these three strings: base one sub (default=base)
* filter is a string-represented filter as in RFC 2254
* extensions is a comma-separated list of name=value pairs.
*
* e.g., ldap://ldap.itd.umich.edu/c=US?o,description?one?o=umich
*
* To accomodate IPv6 addresses, the host portion of a host that appears
* in hostport can be enclosed in square brackets, e.g
*
* e.g., ldap://[fe80::a00:20ff:fee5:c0b4]:3389/dc=siroe,dc=com
*
* We also tolerate URLs that look like: <ldapurl> and <URL:ldapurl>
*/
#if 0
#ifndef lint
static char copyright[] = "@(#) Copyright (c) 1996 Regents of the University of Michigan.\nAll rights reserved.\n";
#endif
#endif
#include "ldap-int.h"
static int skip_url_prefix( const char **urlp, int *enclosedp, int *securep );
int
LDAP_CALL
ldap_is_ldap_url( const char *url )
{
int enclosed, secure;
return( url != NULL
&& skip_url_prefix( &url, &enclosed, &secure ));
}
static int
skip_url_prefix( const char **urlp, int *enclosedp, int *securep )
{
/*
* 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
* The data that *urlp points to is not changed by this function.
*/
if ( *urlp == NULL ) {
return( 0 );
}
/* skip leading '<' (if any) */
if ( **urlp == '<' ) {
*enclosedp = 1;
++*urlp;
} else {
*enclosedp = 0;
}
/* skip leading "URL:" (if any) */
if ( strlen( *urlp ) >= LDAP_URL_URLCOLON_LEN && strncasecmp(
*urlp, LDAP_URL_URLCOLON, LDAP_URL_URLCOLON_LEN ) == 0 ) {
*urlp += LDAP_URL_URLCOLON_LEN;
}
/* check for an "ldap://" prefix */
if ( strlen( *urlp ) >= LDAP_URL_PREFIX_LEN && strncasecmp( *urlp,
LDAP_URL_PREFIX, LDAP_URL_PREFIX_LEN ) == 0 ) {
/* skip over URL prefix and return success */
*urlp += LDAP_URL_PREFIX_LEN;
*securep = 0;
return( 1 );
}
/* check for an "ldaps://" prefix */
if ( strlen( *urlp ) >= LDAPS_URL_PREFIX_LEN && strncasecmp( *urlp,
LDAPS_URL_PREFIX, LDAPS_URL_PREFIX_LEN ) == 0 ) {
/* skip over URL prefix and return success */
*urlp += LDAPS_URL_PREFIX_LEN;
*securep = 1;
return( 1 );
}
return( 0 ); /* not an LDAP URL */
}
int
LDAP_CALL
ldap_url_parse_no_defaults( const char *url, LDAPURLDesc **ludpp, int dn_required)
{
return( nsldapi_url_parse( url, ludpp, dn_required ) );
}
int
LDAP_CALL
ldap_url_parse( const char *url, LDAPURLDesc **ludpp )
{
/*
* Pick apart the pieces of an LDAP URL.
*/
int rc;
if (( rc = nsldapi_url_parse( url, ludpp, 1 )) == 0 ) {
if ( (*ludpp)->lud_scope == -1 ) {
(*ludpp)->lud_scope = LDAP_SCOPE_BASE;
}
if ( (*ludpp)->lud_filter == NULL ) {
(*ludpp)->lud_filter = "(objectclass=*)";
}
if ( *((*ludpp)->lud_dn) == '\0' ) {
(*ludpp)->lud_dn = NULL;
}
} else if ( rc == LDAP_URL_UNRECOGNIZED_CRITICAL_EXTENSION ) {
rc = LDAP_URL_ERR_PARAM; /* mapped for backwards compatibility */
}
return( rc );
}
/*
* like ldap_url_parse() with a few exceptions:
* 1) if dn_required is zero, a missing DN does not generate an error
* (we just leave the lud_dn field NULL)
* 2) no defaults are set for lud_scope and lud_filter (they are set to -1
* and NULL respectively if no SCOPE or FILTER are present in the URL).
* 3) when there is a zero-length DN in a URL we do not set lud_dn to NULL.
*
* note that LDAPv3 URL extensions are ignored unless they are marked
* critical, in which case an LDAP_URL_UNRECOGNIZED_CRITICAL_EXTENSION error
* is returned.
*/
int
nsldapi_url_parse( const char *url, LDAPURLDesc **ludpp, int dn_required )
{
LDAPURLDesc *ludp;
char *urlcopy, *attrs, *scope, *extensions = NULL, *p, *q;
int enclosed, secure, i, nattrs, at_start;
LDAPDebug( LDAP_DEBUG_TRACE, "nsldapi_url_parse(%s)\n", url, 0, 0 );
if ( url == NULL || ludpp == NULL ) {
return( LDAP_URL_ERR_PARAM );
}
*ludpp = NULL; /* pessimistic */
if ( !skip_url_prefix( &url, &enclosed, &secure )) {
return( LDAP_URL_ERR_NOTLDAP );
}
/* allocate return struct */
if (( ludp = (LDAPURLDesc *)NSLDAPI_CALLOC( 1, sizeof( LDAPURLDesc )))
== NULLLDAPURLDESC ) {
return( LDAP_URL_ERR_MEM );
}
if ( secure ) {
ludp->lud_options |= LDAP_URL_OPT_SECURE;
}
/* make working copy of the remainder of the URL */
if (( urlcopy = nsldapi_strdup( url )) == NULL ) {
ldap_free_urldesc( ludp );
return( LDAP_URL_ERR_MEM );
}
if ( enclosed && *((p = urlcopy + strlen( urlcopy ) - 1)) == '>' ) {
*p = '\0';
}
/* initialize scope and filter */
ludp->lud_scope = -1;
ludp->lud_filter = NULL;
/* lud_string is the only malloc'd string space we use */
ludp->lud_string = urlcopy;
/* scan forward for '/' that marks end of hostport and begin. of dn */
if (( ludp->lud_dn = strchr( urlcopy, '/' )) == NULL ) {
if ( dn_required ) {
ldap_free_urldesc( ludp );
return( LDAP_URL_ERR_NODN );
}
} else {
/* terminate hostport; point to start of dn */
*ludp->lud_dn++ = '\0';
}
if ( *urlcopy == '\0' ) {
ludp->lud_host = NULL;
} else {
ludp->lud_host = urlcopy;
nsldapi_hex_unescape( ludp->lud_host );
/*
* Locate and strip off optional port number (:#) in host
* portion of URL.
*
* If more than one space-separated host is listed, we only
* look for a port number within the right-most one since
* ldap_init() will handle host parameters that look like
* host:port anyway.
*/
if (( p = strrchr( ludp->lud_host, ' ' )) == NULL ) {
p = ludp->lud_host;
} else {
++p;
}
if ( *p == '[' && ( q = strchr( p, ']' )) != NULL ) {
/* square brackets present -- skip past them */
p = q++;
}
if (( p = strchr( p, ':' )) != NULL ) {
*p++ = '\0';
ludp->lud_port = atoi( p );
if ( *ludp->lud_host == '\0' ) {
ludp->lud_host = NULL; /* no hostname */
}
}
}
/* scan for '?' that marks end of dn and beginning of attributes */
attrs = NULL;
if ( ludp->lud_dn != NULL &&
( attrs = strchr( ludp->lud_dn, '?' )) != NULL ) {
/* terminate dn; point to start of attrs. */
*attrs++ = '\0';
/* scan for '?' that marks end of attrs and begin. of scope */
if (( p = strchr( attrs, '?' )) != NULL ) {
/*
* terminate attrs; point to start of scope and scan for
* '?' that marks end of scope and begin. of filter
*/
*p++ = '\0';
scope = p;
if (( p = strchr( scope, '?' )) != NULL ) {
/* terminate scope; point to start of filter */
*p++ = '\0';
if ( *p != '\0' ) {
ludp->lud_filter = p;
/*
* scan for the '?' that marks the end
* of the filter and the start of any
* extensions
*/
if (( p = strchr( ludp->lud_filter, '?' ))
!= NULL ) {
*p++ = '\0'; /* term. filter */
extensions = p;
}
if ( *ludp->lud_filter == '\0' ) {
ludp->lud_filter = NULL;
} else {
nsldapi_hex_unescape( ludp->lud_filter );
}
}
}
if ( strcasecmp( scope, "one" ) == 0 ) {
ludp->lud_scope = LDAP_SCOPE_ONELEVEL;
} else if ( strcasecmp( scope, "base" ) == 0 ) {
ludp->lud_scope = LDAP_SCOPE_BASE;
} else if ( strcasecmp( scope, "sub" ) == 0 ) {
ludp->lud_scope = LDAP_SCOPE_SUBTREE;
} else if ( *scope != '\0' ) {
ldap_free_urldesc( ludp );
return( LDAP_URL_ERR_BADSCOPE );
}
}
}
if ( ludp->lud_dn != NULL ) {
nsldapi_hex_unescape( ludp->lud_dn );
}
/*
* if attrs list was included, turn it into a null-terminated array
*/
if ( attrs != NULL && *attrs != '\0' ) {
nsldapi_hex_unescape( attrs );
for ( nattrs = 1, p = attrs; *p != '\0'; ++p ) {
if ( *p == ',' ) {
++nattrs;
}
}
if (( ludp->lud_attrs = (char **)NSLDAPI_CALLOC( nattrs + 1,
sizeof( char * ))) == NULL ) {
ldap_free_urldesc( ludp );
return( LDAP_URL_ERR_MEM );
}
for ( i = 0, p = attrs; i < nattrs; ++i ) {
ludp->lud_attrs[ i ] = p;
if (( p = strchr( p, ',' )) != NULL ) {
*p++ ='\0';
}
nsldapi_hex_unescape( ludp->lud_attrs[ i ] );
}
}
/* if extensions list was included, check for critical ones */
if ( extensions != NULL && *extensions != '\0' ) {
/* Note: at present, we do not recognize ANY extensions */
at_start = 1;
for ( p = extensions; *p != '\0'; ++p ) {
if ( at_start ) {
if ( *p == '!' ) { /* critical extension */
ldap_free_urldesc( ludp );
return( LDAP_URL_UNRECOGNIZED_CRITICAL_EXTENSION );
}
at_start = 0;
} else if ( *p == ',' ) {
at_start = 1;
}
}
}
*ludpp = ludp;
return( 0 );
}
void
LDAP_CALL
ldap_free_urldesc( LDAPURLDesc *ludp )
{
if ( ludp != NULLLDAPURLDESC ) {
if ( ludp->lud_string != NULL ) {
NSLDAPI_FREE( ludp->lud_string );
}
if ( ludp->lud_attrs != NULL ) {
NSLDAPI_FREE( ludp->lud_attrs );
}
NSLDAPI_FREE( ludp );
}
}
int
LDAP_CALL
ldap_url_search( LDAP *ld, const char *url, int attrsonly )
{
int err, msgid;
LDAPURLDesc *ludp;
BerElement *ber;
LDAPServer *srv;
char *host;
if ( !NSLDAPI_VALID_LDAP_POINTER( ld )) {
return( -1 ); /* punt */
}
if ( ldap_url_parse( url, &ludp ) != 0 ) {
LDAP_SET_LDERRNO( ld, LDAP_PARAM_ERROR, NULL, NULL );
return( -1 );
}
LDAP_MUTEX_LOCK( ld, LDAP_MSGID_LOCK );
msgid = ++ld->ld_msgid;
LDAP_MUTEX_UNLOCK( ld, LDAP_MSGID_LOCK );
if ( nsldapi_build_search_req( ld, ludp->lud_dn, ludp->lud_scope,
ludp->lud_filter, ludp->lud_attrs, attrsonly, NULL, NULL,
-1, -1, msgid, &ber ) != LDAP_SUCCESS ) {
return( -1 );
}
err = 0;
if ( ludp->lud_host == NULL ) {
host = ld->ld_defhost;
} else {
host = ludp->lud_host;
}
if (( srv = (LDAPServer *)NSLDAPI_CALLOC( 1, sizeof( LDAPServer )))
== NULL || ( host != NULL &&
( srv->lsrv_host = nsldapi_strdup( host )) == NULL )) {
if ( srv != NULL ) {
NSLDAPI_FREE( srv );
}
LDAP_SET_LDERRNO( ld, LDAP_NO_MEMORY, NULL, NULL );
err = -1;
} else {
if ( ludp->lud_port != 0 ) {
/* URL includes a port - use it */
srv->lsrv_port = ludp->lud_port;
} else if ( ludp->lud_host == NULL ) {
/* URL has no port or host - use port from ld */
srv->lsrv_port = ld->ld_defport;
} else if (( ludp->lud_options & LDAP_URL_OPT_SECURE ) == 0 ) {
/* ldap URL has a host but no port - use std. port */
srv->lsrv_port = LDAP_PORT;
} else {
/* ldaps URL has a host but no port - use std. port */
srv->lsrv_port = LDAPS_PORT;
}
}
if (( ludp->lud_options & LDAP_URL_OPT_SECURE ) != 0 ) {
srv->lsrv_options |= LDAP_SRV_OPT_SECURE;
}
if ( err != 0 ) {
ber_free( ber, 1 );
} else {
err = nsldapi_send_server_request( ld, ber, msgid, NULL, srv,
NULL, NULL, 1 );
}
ldap_free_urldesc( ludp );
return( err );
}
int
LDAP_CALL
ldap_url_search_st( LDAP *ld, const char *url, int attrsonly,
struct timeval *timeout, LDAPMessage **res )
{
int msgid;
/*
* It is an error to pass in a zero'd timeval.
*/
if ( timeout != NULL && timeout->tv_sec == 0 &&
timeout->tv_usec == 0 ) {
if ( ld != NULL ) {
LDAP_SET_LDERRNO( ld, LDAP_PARAM_ERROR, NULL, NULL );
}
if ( res != NULL ) {
*res = NULL;
}
return( LDAP_PARAM_ERROR );
}
if (( msgid = ldap_url_search( ld, url, attrsonly )) == -1 ) {
return( LDAP_GET_LDERRNO( ld, NULL, NULL ) );
}
if ( ldap_result( ld, msgid, 1, timeout, res ) == -1 ) {
return( LDAP_GET_LDERRNO( ld, NULL, NULL ) );
}
if ( LDAP_GET_LDERRNO( ld, NULL, NULL ) == LDAP_TIMEOUT ) {
(void) ldap_abandon( ld, msgid );
LDAP_SET_LDERRNO( ld, LDAP_TIMEOUT, NULL, NULL );
return( LDAP_TIMEOUT );
}
return( ldap_result2error( ld, *res, 0 ));
}
int
LDAP_CALL
ldap_url_search_s( LDAP *ld, const char *url, int attrsonly, LDAPMessage **res )
{
int msgid;
if (( msgid = ldap_url_search( ld, url, attrsonly )) == -1 ) {
return( LDAP_GET_LDERRNO( ld, NULL, NULL ) );
}
if ( ldap_result( ld, msgid, 1, (struct timeval *)NULL, res ) == -1 ) {
return( LDAP_GET_LDERRNO( ld, NULL, NULL ) );
}
return( ldap_result2error( ld, *res, 0 ));
}

View file

@ -0,0 +1,228 @@
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is Sun LDAP C SDK.
*
* The Initial Developer of the Original Code is Sun Microsystems, Inc.
*
* Portions created by Sun Microsystems, Inc are Copyright (C) 2005
* Sun Microsystems, Inc. All Rights Reserved.
*
* Contributor(s): abobrov@sun.com
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
#include "ldap-int.h"
/* ldap_create_userstatus_control:
Parameters are
ld LDAP pointer to the desired connection
ctl_iscritical Indicates whether the control is critical of not. If
this field is non-zero, the operation will only be car-
ried out if the control is recognized by the server
and/or client
ctrlp the address of a place to put the constructed control
*/
int
LDAP_CALL
ldap_create_userstatus_control (
LDAP *ld,
const char ctl_iscritical,
LDAPControl **ctrlp
)
{
int rc;
if ( !NSLDAPI_VALID_LDAP_POINTER( ld )) {
return( LDAP_PARAM_ERROR );
}
if ( ctrlp == NULL ) {
LDAP_SET_LDERRNO( ld, LDAP_PARAM_ERROR, NULL, NULL );
return ( LDAP_PARAM_ERROR );
}
rc = nsldapi_build_control( LDAP_CONTROL_ACCOUNT_USABLE,
NULL, 0, ctl_iscritical, ctrlp );
LDAP_SET_LDERRNO( ld, rc, NULL, NULL );
return( rc );
}
/* ldap_parse_userstatus_control:
Parameters are
ld LDAP pointer to the desired connection
ctrlp An array of controls obtained from calling
ldap_parse_result on the set of results
returned by the server
us the address of struct LDAPuserstatus
to parse control results to
*/
int
LDAP_CALL
ldap_parse_userstatus_control (
LDAP *ld,
LDAPControl **ctrlp,
LDAPuserstatus *us
)
{
BerElement *ber = NULL;
int i, foundUSControl;
LDAPControl *USCtrlp = NULL;
ber_tag_t tag;
if ( !NSLDAPI_VALID_LDAP_POINTER( ld ) || us == NULL ) {
return( LDAP_PARAM_ERROR );
}
/* find the control in the list of controls if it exists */
if ( ctrlp == NULL ) {
LDAP_SET_LDERRNO( ld, LDAP_CONTROL_NOT_FOUND, NULL, NULL );
return ( LDAP_CONTROL_NOT_FOUND );
}
foundUSControl = 0;
for ( i = 0; (( ctrlp[i] != NULL ) && ( !foundUSControl )); i++ ) {
foundUSControl = !strcmp( ctrlp[i]->ldctl_oid, LDAP_CONTROL_ACCOUNT_USABLE );
}
if ( !foundUSControl ) {
LDAP_SET_LDERRNO( ld, LDAP_CONTROL_NOT_FOUND, NULL, NULL );
return ( LDAP_CONTROL_NOT_FOUND );
} else {
/* let local var point to the control */
USCtrlp = ctrlp[i-1];
}
/* allocate a Ber element with the contents of the control's struct berval */
if ( ( ber = ber_init( &USCtrlp->ldctl_value ) ) == NULL ) {
LDAP_SET_LDERRNO( ld, LDAP_NO_MEMORY, NULL, NULL );
return( LDAP_NO_MEMORY );
}
memset( us, 0, sizeof(struct LDAPuserstatus) );
/*
* The control value should look like this:
*
* ACCOUNT_USABLE_RESPONSE::= CHOICE {
* is_available [0] INTEGER, ** seconds before expiration **
* is_not_available [1] More_info
* }
* More_info::= SEQUENCE {
* inactive [0] BOOLEAN DEFAULT FALSE,
* reset [1] BOOLEAN DEFAULT FALSE,
* expired [2] BOOLEAN DEFAULT FALSE,
* remaining_grace [3] INTEGER OPTIONAL,
* seconds_before_unlock [4] INTEGER OPTIONAL
* }
*/
if ( ( ber_scanf( ber, "t", &tag ) ) == LBER_ERROR ) {
LDAP_SET_LDERRNO( ld, LDAP_DECODING_ERROR, NULL, NULL );
ber_free( ber, 1 );
return( LDAP_DECODING_ERROR );
}
tag = (( tag & LBER_CONSTRUCTED ) == LBER_CONSTRUCTED ) ? 1 : 0;
if ( !tag ) {
us->us_available = 1;
if ( ber_scanf( ber, "i", &us->us_expire ) == LBER_ERROR ) {
LDAP_SET_LDERRNO( ld, LDAP_DECODING_ERROR, NULL, NULL );
ber_free( ber, 1 );
return( LDAP_DECODING_ERROR );
}
} else {
us->us_available = 0;
tag = 0;
if ( ( ber_scanf( ber, "{t", &tag ) ) == LBER_ERROR ) {
LDAP_SET_LDERRNO( ld, LDAP_DECODING_ERROR, NULL, NULL );
ber_free( ber, 1 );
return( LDAP_DECODING_ERROR );
}
while ( tag != LBER_ERROR && tag != LBER_END_OF_SEQORSET ) {
tag = tag & (~LBER_CLASS_CONTEXT);
switch (tag)
{
case 0:
if ( ber_scanf( ber, "b", &us->us_inactive ) == LBER_ERROR ) {
LDAP_SET_LDERRNO( ld, LDAP_DECODING_ERROR, NULL, NULL );
ber_free( ber, 1 );
return( LDAP_DECODING_ERROR );
}
us->us_inactive = ( us->us_inactive != 0 ) ? 1 : 0;
break;
case 1:
if ( ber_scanf( ber, "b", &us->us_reset ) == LBER_ERROR ) {
LDAP_SET_LDERRNO( ld, LDAP_DECODING_ERROR, NULL, NULL );
ber_free( ber, 1 );
return( LDAP_DECODING_ERROR );
}
us->us_reset = ( us->us_reset != 0 ) ? 1 : 0;
break;
case 2:
if ( ber_scanf( ber, "b", &us->us_expired ) == LBER_ERROR ) {
LDAP_SET_LDERRNO( ld, LDAP_DECODING_ERROR, NULL, NULL );
ber_free( ber, 1 );
return( LDAP_DECODING_ERROR );
}
us->us_expired = ( us->us_expired != 0 ) ? 1 : 0;
break;
case 3:
if ( ber_scanf( ber, "i", &us->us_remaining ) == LBER_ERROR ) {
LDAP_SET_LDERRNO( ld, LDAP_DECODING_ERROR, NULL, NULL );
ber_free( ber, 1 );
return( LDAP_DECODING_ERROR );
}
break;
case 4:
if ( ber_scanf( ber, "i", &us->us_seconds ) == LBER_ERROR ) {
LDAP_SET_LDERRNO( ld, LDAP_DECODING_ERROR, NULL, NULL );
ber_free( ber, 1 );
return( LDAP_DECODING_ERROR );
}
break;
default:
LDAP_SET_LDERRNO( ld, LDAP_DECODING_ERROR, NULL, NULL );
ber_free( ber, 1 );
return( LDAP_DECODING_ERROR );
}
ber_scanf( ber, "t", &tag );
}
}
/* the ber encoding is no longer needed */
ber_free( ber, 1 );
return( LDAP_SUCCESS );
}

View file

@ -0,0 +1,282 @@
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is Mozilla Communicator client code, released
* March 31, 1998.
*
* The Initial Developer of the Original Code is
* Netscape Communications Corporation.
* Portions created by the Initial Developer are Copyright (C) 1998-1999
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
*
* Alternatively, the contents of this file may be used under the terms of
* either of the GNU General Public License Version 2 or later (the "GPL"),
* or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
/* uft8.c - misc. utf8 "string" functions. */
#include "ldap-int.h"
static char UTF8len[64]
= {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 5, 6};
int
LDAP_CALL
ldap_utf8len (const char* s)
/* Return the number of char's in the character at *s. */
{
return ldap_utf8next((char*)s) - s;
}
char*
LDAP_CALL
ldap_utf8next (char* s)
/* Return a pointer to the character immediately following *s.
Handle any valid UTF-8 character, including '\0' and ASCII.
Try to handle a misaligned pointer or a malformed character.
*/
{
register unsigned char* next = (unsigned char*)s;
switch (UTF8len [(*next >> 2) & 0x3F]) {
case 0: /* erroneous: s points to the middle of a character. */
case 6: if ((*++next & 0xC0) != 0x80) break;
case 5: if ((*++next & 0xC0) != 0x80) break;
case 4: if ((*++next & 0xC0) != 0x80) break;
case 3: if ((*++next & 0xC0) != 0x80) break;
case 2: if ((*++next & 0xC0) != 0x80) break;
case 1: ++next;
}
return (char*) next;
}
char*
LDAP_CALL
ldap_utf8prev (char* s)
/* Return a pointer to the character immediately preceding *s.
Handle any valid UTF-8 character, including '\0' and ASCII.
Try to handle a misaligned pointer or a malformed character.
*/
{
register unsigned char* prev = (unsigned char*)s;
unsigned char* limit = prev - 6;
while (((*--prev & 0xC0) == 0x80) && (prev != limit)) {
;
}
return (char*) prev;
}
int
LDAP_CALL
ldap_utf8copy (char* dst, const char* src)
/* Copy a character from src to dst; return the number of char's copied.
Handle any valid UTF-8 character, including '\0' and ASCII.
Try to handle a misaligned pointer or a malformed character.
*/
{
register const unsigned char* s = (const unsigned char*)src;
switch (UTF8len [(*s >> 2) & 0x3F]) {
case 0: /* erroneous: s points to the middle of a character. */
case 6: *dst++ = *s++; if ((*s & 0xC0) != 0x80) break;
case 5: *dst++ = *s++; if ((*s & 0xC0) != 0x80) break;
case 4: *dst++ = *s++; if ((*s & 0xC0) != 0x80) break;
case 3: *dst++ = *s++; if ((*s & 0xC0) != 0x80) break;
case 2: *dst++ = *s++; if ((*s & 0xC0) != 0x80) break;
case 1: *dst = *s++;
}
return s - (const unsigned char*)src;
}
size_t
LDAP_CALL
ldap_utf8characters (const char* src)
/* Return the number of UTF-8 characters in the 0-terminated array s. */
{
register char* s = (char*)src;
size_t n;
for (n = 0; *s; LDAP_UTF8INC(s)) ++n;
return n;
}
unsigned long LDAP_CALL
ldap_utf8getcc( const char** src )
{
register unsigned long c = 0;
register const unsigned char* s = (const unsigned char*)*src;
switch (UTF8len [(*s >> 2) & 0x3F]) {
case 0: /* erroneous: s points to the middle of a character. */
c = (*s++) & 0x3F; goto more5;
case 1: c = (*s++); break;
case 2: c = (*s++) & 0x1F; goto more1;
case 3: c = (*s++) & 0x0F; goto more2;
case 4: c = (*s++) & 0x07; goto more3;
case 5: c = (*s++) & 0x03; goto more4;
case 6: c = (*s++) & 0x01; goto more5;
more5: if ((*s & 0xC0) != 0x80) break; c = (c << 6) | ((*s++) & 0x3F);
more4: if ((*s & 0xC0) != 0x80) break; c = (c << 6) | ((*s++) & 0x3F);
more3: if ((*s & 0xC0) != 0x80) break; c = (c << 6) | ((*s++) & 0x3F);
more2: if ((*s & 0xC0) != 0x80) break; c = (c << 6) | ((*s++) & 0x3F);
more1: if ((*s & 0xC0) != 0x80) break; c = (c << 6) | ((*s++) & 0x3F);
break;
}
*src = (const char*)s;
return c;
}
char*
LDAP_CALL
ldap_utf8strtok_r( char* sp, const char* brk, char** next)
{
const char *bp;
unsigned long sc, bc;
char *tok;
if (sp == NULL && (sp = *next) == NULL)
return NULL;
/* Skip leading delimiters; roughly, sp += strspn(sp, brk) */
cont:
sc = LDAP_UTF8GETC(sp);
for (bp = brk; (bc = LDAP_UTF8GETCC(bp)) != 0;) {
if (sc == bc)
goto cont;
}
if (sc == 0) { /* no non-delimiter characters */
*next = NULL;
return NULL;
}
tok = LDAP_UTF8PREV(sp);
/* Scan token; roughly, sp += strcspn(sp, brk)
* Note that brk must be 0-terminated; we stop if we see that, too.
*/
while (1) {
sc = LDAP_UTF8GETC(sp);
bp = brk;
do {
if ((bc = LDAP_UTF8GETCC(bp)) == sc) {
if (sc == 0) {
*next = NULL;
} else {
*next = sp;
*(LDAP_UTF8PREV(sp)) = 0;
}
return tok;
}
} while (bc != 0);
}
/* NOTREACHED */
}
int
LDAP_CALL
ldap_utf8isalnum( char* s )
{
register unsigned char c = *(unsigned char*)s;
if (0x80 & c) return 0;
if (c >= 'A' && c <= 'Z') return 1;
if (c >= 'a' && c <= 'z') return 1;
if (c >= '0' && c <= '9') return 1;
return 0;
}
int
LDAP_CALL
ldap_utf8isalpha( char* s )
{
register unsigned char c = *(unsigned char*)s;
if (0x80 & c) return 0;
if (c >= 'A' && c <= 'Z') return 1;
if (c >= 'a' && c <= 'z') return 1;
return 0;
}
int
LDAP_CALL
ldap_utf8isdigit( char* s )
{
register unsigned char c = *(unsigned char*)s;
if (0x80 & c) return 0;
if (c >= '0' && c <= '9') return 1;
return 0;
}
int
LDAP_CALL
ldap_utf8isxdigit( char* s )
{
register unsigned char c = *(unsigned char*)s;
if (0x80 & c) return 0;
if (c >= '0' && c <= '9') return 1;
if (c >= 'A' && c <= 'F') return 1;
if (c >= 'a' && c <= 'f') return 1;
return 0;
}
int
LDAP_CALL
ldap_utf8isspace( char* s )
{
register unsigned char *c = (unsigned char*)s;
int len = ldap_utf8len(s);
if (len == 0) {
return 0;
} else if (len == 1) {
switch (*c) {
case 0x09:
case 0x0A:
case 0x0B:
case 0x0C:
case 0x0D:
case 0x20:
return 1;
default:
return 0;
}
} else if (len == 2) {
if (*c == 0xc2) {
return *(c+1) == 0x80;
}
} else if (len == 3) {
if (*c == 0xE2) {
c++;
if (*c == 0x80) {
c++;
return (*c>=0x80 && *c<=0x8a);
}
} else if (*c == 0xE3) {
return (*(c+1)==0x80) && (*(c+2)==0x80);
} else if (*c==0xEF) {
return (*(c+1)==0xBB) && (*(c+2)==0xBF);
}
return 0;
}
/* should never reach here */
return 0;
}

View file

@ -0,0 +1,259 @@
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is Mozilla Communicator client code, released
* March 31, 1998.
*
* The Initial Developer of the Original Code is
* Netscape Communications Corporation.
* Portions created by the Initial Developer are Copyright (C) 1998-1999
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
*
* Alternatively, the contents of this file may be used under the terms of
* either of the GNU General Public License Version 2 or later (the "GPL"),
* or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
/* vlistctrl.c - virtual list control implementation. */
#include "ldap-int.h"
/*
* function to create a VirtualListViewRequest control that can be passed
* to ldap_search_ext() or ldap_search_ext_s(). *ctrlp will be set to a
* freshly allocated LDAPControl structure. Returns an LDAP error code
* (LDAP_SUCCESS if all goes well).
*
* Parameters
* ld LDAP pointer to the desired connection
*
* ldvlistp the control structure.
*
* ctrlp the address of a place to put the constructed control
The controlValue is an OCTET STRING
whose value is the BER-encoding of the following SEQUENCE:
VirtualListViewRequest ::= SEQUENCE {
beforeCount INTEGER (0 .. maxInt),
afterCount INTEGER (0 .. maxInt),
CHOICE {
byIndex [0] SEQUENCE {
index INTEGER (0 .. maxInt),
contentCount INTEGER (0 .. maxInt) }
byValue [1] greaterThanOrEqual assertionValue }
beforeCount indicates how many entries before the target entry the
client wants the server to send. afterCount indicates the number of
entries after the target entry the client wants the server to send.
index and contentCount identify the target entry
greaterThanOrEqual is an attribute assertion value defined in
[LDAPv3]. If present, the value supplied in greaterThanOrEqual is used
to determine the target entry by comparison with the values of the
attribute specified as the primary sort key. The first list entry who's
value is no less than the supplied value is the target entry.
*/
int
LDAP_CALL
ldap_create_virtuallist_control(
LDAP *ld,
LDAPVirtualList *ldvlistp,
LDAPControl **ctrlp
)
{
BerElement *ber;
int rc;
if (!NSLDAPI_VALID_LDAP_POINTER( ld )) {
return( LDAP_PARAM_ERROR );
}
if ( NULL == ctrlp || NULL == ldvlistp ) {
LDAP_SET_LDERRNO( ld, LDAP_PARAM_ERROR, NULL, NULL );
return ( LDAP_PARAM_ERROR );
}
/* create a ber package to hold the controlValue */
if ( LDAP_SUCCESS != nsldapi_alloc_ber_with_options( ld, &ber ) )
{
LDAP_SET_LDERRNO( ld, LDAP_NO_MEMORY, NULL, NULL );
return( LDAP_NO_MEMORY );
}
if ( LBER_ERROR == ber_printf( ber,
"{ii",
ldvlistp->ldvlist_before_count,
ldvlistp->ldvlist_after_count ))
/* XXX lossy casts */
{
LDAP_SET_LDERRNO( ld, LDAP_ENCODING_ERROR, NULL, NULL );
ber_free( ber, 1 );
return( LDAP_ENCODING_ERROR );
}
if (NULL == ldvlistp->ldvlist_attrvalue)
{
if ( LBER_ERROR == ber_printf( ber,
"t{ii}}",
LDAP_TAG_VLV_BY_INDEX,
ldvlistp->ldvlist_index,
ldvlistp->ldvlist_size ) )
/* XXX lossy casts */
{
LDAP_SET_LDERRNO( ld, LDAP_ENCODING_ERROR, NULL, NULL );
ber_free( ber, 1 );
return( LDAP_ENCODING_ERROR );
}
}
else
{
if ( LBER_ERROR == ber_printf( ber,
"to}",
LDAP_TAG_VLV_BY_VALUE,
ldvlistp->ldvlist_attrvalue,
(int)strlen( ldvlistp->ldvlist_attrvalue )) ) {
LDAP_SET_LDERRNO( ld, LDAP_ENCODING_ERROR, NULL, NULL );
ber_free( ber, 1 );
return( LDAP_ENCODING_ERROR );
}
}
rc = nsldapi_build_control( LDAP_CONTROL_VLVREQUEST ,
ber,
1,
1,
ctrlp );
LDAP_SET_LDERRNO( ld, rc, NULL, NULL );
return( rc );
}
/*
* function to find and parse a VirtualListViewResponse control contained in
* "ctrls" *target_posp, *list_sizep, and *errcodep are set based on its
* contents. Returns an LDAP error code that indicates whether the parsing
* itself was successful (LDAP_SUCCESS if all goes well).
The controlValue is an OCTET STRING, whose value
is the BER encoding of a value of the following SEQUENCE:
VirtualListViewResponse ::= SEQUENCE {
targetPosition INTEGER (0 .. maxInt),
contentCount INTEGER (0 .. maxInt),
virtualListViewResult ENUMERATED {
success (0),
operatonsError (1),
unwillingToPerform (53),
insufficientAccessRights (50),
busy (51),
timeLimitExceeded (3),
adminLimitExceeded (11),
sortControlMissing (60),
indexRangeError (61),
other (80) } }
*/
int
LDAP_CALL
ldap_parse_virtuallist_control
(
LDAP *ld,
LDAPControl **ctrls,
ber_int_t *target_posp,
ber_int_t *list_sizep,
int *errcodep
)
{
BerElement *ber;
int i, foundListControl;
ber_int_t errcode;
LDAPControl *listCtrlp;
ber_int_t target_pos, list_size;
if ( !NSLDAPI_VALID_LDAP_POINTER( ld )) {
return( LDAP_PARAM_ERROR );
}
/* only ldapv3 or higher can do virtual lists. */
if ( NSLDAPI_LDAP_VERSION( ld ) < LDAP_VERSION3 ) {
LDAP_SET_LDERRNO( ld, LDAP_NOT_SUPPORTED, NULL, NULL );
return( LDAP_NOT_SUPPORTED );
}
/* find the listControl in the list of controls if it exists */
if ( ctrls == NULL ) {
LDAP_SET_LDERRNO( ld, LDAP_CONTROL_NOT_FOUND, NULL, NULL );
return ( LDAP_CONTROL_NOT_FOUND );
}
foundListControl = 0;
for ( i = 0; (( ctrls[i] != NULL ) && ( !foundListControl )); i++ ) {
foundListControl = !strcmp( ctrls[i]->ldctl_oid,
LDAP_CONTROL_VLVRESPONSE );
}
if ( !foundListControl ) {
LDAP_SET_LDERRNO( ld, LDAP_CONTROL_NOT_FOUND, NULL, NULL );
return ( LDAP_CONTROL_NOT_FOUND );
} else {
/* let local var point to the listControl */
listCtrlp = ctrls[i-1];
}
/* allocate a Ber element with the contents of the list_control's struct berval */
if ( ( ber = ber_init( &listCtrlp->ldctl_value ) ) == NULL ) {
LDAP_SET_LDERRNO( ld, LDAP_NO_MEMORY, NULL, NULL );
return( LDAP_NO_MEMORY );
}
/* decode the result from the Berelement */
if ( LBER_ERROR == ber_scanf( ber, "{iie}", &target_pos, &list_size,
&errcode ) ) {
LDAP_SET_LDERRNO( ld, LDAP_DECODING_ERROR, NULL, NULL );
ber_free( ber, 1 );
return( LDAP_DECODING_ERROR );
}
if ( target_posp != NULL ) {
*target_posp = target_pos;
}
if ( list_sizep != NULL ) {
*list_sizep = list_size;
}
if ( errcodep != NULL ) {
*errcodep = (int)errcode;
}
/* the ber encoding is no longer needed */
ber_free(ber,1);
return(LDAP_SUCCESS);
}

View file

@ -0,0 +1,130 @@
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is Sun LDAP C SDK.
*
* The Initial Developer of the Original Code is Sun Microsystems, Inc.
*
* Portions created by Sun Microsystems, Inc are Copyright (C) 2005
* Sun Microsystems, Inc. All Rights Reserved.
*
* Contributor(s): abobrov@sun.com
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
#include "ldap-int.h"
/* ldap_whoami */
int
LDAP_CALL
ldap_whoami (
LDAP *ld,
LDAPControl **serverctrls,
LDAPControl **clientctrls,
int *msgidp
)
{
int rc;
struct berval *requestdata = NULL;
if ( !NSLDAPI_VALID_LDAP_POINTER( ld )) {
LDAP_SET_LDERRNO( ld, LDAP_PARAM_ERROR, NULL, NULL );
return( LDAP_PARAM_ERROR );
}
rc = ldap_extended_operation( ld, LDAP_EXOP_WHO_AM_I, requestdata,
serverctrls, clientctrls, msgidp );
return( rc );
}
/* ldap_parse_whoami */
int
LDAP_CALL
ldap_parse_whoami (
LDAP *ld,
LDAPMessage *result,
struct berval **authzid
)
{
int rc;
char *retoidp = NULL;
if ( !NSLDAPI_VALID_LDAP_POINTER( ld )) {
LDAP_SET_LDERRNO( ld, LDAP_PARAM_ERROR, NULL, NULL );
return( LDAP_PARAM_ERROR );
}
if ( !result ) {
LDAP_SET_LDERRNO( ld, LDAP_PARAM_ERROR, NULL, NULL );
return( LDAP_PARAM_ERROR );
}
*authzid = NULL;
rc = ldap_parse_extended_result( ld, result, &retoidp, authzid, 0 );
if ( rc != LDAP_SUCCESS ) {
return( rc );
}
ldap_memfree( retoidp );
return( LDAP_SUCCESS );
}
/* ldap_whoami_s */
int
LDAP_CALL
ldap_whoami_s (
LDAP *ld,
struct berval **authzid,
LDAPControl **serverctrls,
LDAPControl **clientctrls
)
{
int rc;
int msgid;
LDAPMessage *result = NULL;
if ( !NSLDAPI_VALID_LDAP_POINTER( ld )) {
LDAP_SET_LDERRNO( ld, LDAP_PARAM_ERROR, NULL, NULL );
return( LDAP_PARAM_ERROR );
}
rc = ldap_whoami( ld, serverctrls, clientctrls, &msgid );
if ( rc != LDAP_SUCCESS ) {
return( rc );
}
rc = ldap_result( ld, msgid, LDAP_MSG_ALL, NULL, &result );
if ( rc == -1 ) {
return( LDAP_GET_LDERRNO( ld, NULL, NULL ) );
}
rc = ldap_parse_whoami( ld, result, authzid );
ldap_msgfree( result );
return( rc );
}

View file

@ -0,0 +1,58 @@
;
; ***** BEGIN LICENSE BLOCK *****
; Version: MPL 1.1/GPL 2.0/LGPL 2.1
;
; The contents of this file are subject to the Mozilla Public License Version
; 1.1 (the "License"); you may not use this file except in compliance with
; the License. You may obtain a copy of the License at
; http://www.mozilla.org/MPL/
;
; Software distributed under the License is distributed on an "AS IS" basis,
; WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
; for the specific language governing rights and limitations under the
; License.
;
; The Original Code is Mozilla Communicator client code.
;
; The Initial Developer of the Original Code is
; Netscape Communications Corporation.
; Portions created by the Initial Developer are Copyright (C) 1996-1999
; the Initial Developer. All Rights Reserved.
;
; Contributor(s):
;
; Alternatively, the contents of this file may be used under the terms of
; either of the GNU General Public License Version 2 or later (the "GPL"),
; or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
; in which case the provisions of the GPL or the LGPL are applicable instead
; of those above. If you wish to allow use of your version of this file only
; under the terms of either the GPL or the LGPL, and not to allow others to
; use your version of this file under the terms of the MPL, indicate your
; decision by deleting the provisions above and replace them with the notice
; and other provisions required by the GPL or the LGPL. If you do not delete
; the provisions above, a recipient may use your version of this file under
; the terms of any one of the MPL, the GPL or the LGPL.
;
; ***** END LICENSE BLOCK *****
LIBRARY LDIF60
VERSION 6.0
HEAPSIZE 4096
EXPORTS
; exports list (generated by genexports.pl)
;
ldif_parse_line
ldif_getline
ldif_put_type_and_value
ldif_put_type_and_value_nowrap
ldif_put_type_and_value_with_options
ldif_type_and_value
ldif_type_and_value_nowrap
ldif_type_and_value_with_options
ldif_base64_decode
ldif_base64_encode
ldif_base64_encode_nowrap
ldif_get_entry
;
; end of generated exports list.

View file

@ -0,0 +1,612 @@
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is Mozilla Communicator client code, released
* March 31, 1998.
*
* The Initial Developer of the Original Code is
* Netscape Communications Corporation.
* Portions created by the Initial Developer are Copyright (C) 1998-1999
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
*
* Alternatively, the contents of this file may be used under the terms of
* either of the GNU General Public License Version 2 or later (the "GPL"),
* or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
/* line64.c - routines for dealing with the slapd line format */
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <ctype.h>
#ifndef macintosh
#include <sys/types.h>
#endif
#ifdef _WIN32
#include <windows.h>
#elif !defined( macintosh )
#include <sys/socket.h>
#endif
#include "ldaplog.h"
#include "ldif.h"
#ifndef isascii
#define isascii( c ) (!((c) & ~0177))
#endif
#define RIGHT2 0x03
#define RIGHT4 0x0f
#define CONTINUED_LINE_MARKER '\001'
#define ISBLANK(c) (c == ' ' || c == '\t' || c == '\n') /* not "\r\v\f" */
#define LDIF_OPT_ISSET( value, opt ) (((value) & (opt)) != 0 )
static char nib2b64[0x40f] =
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
static unsigned char b642nib[0x80] = {
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0x3e, 0xff, 0xff, 0xff, 0x3f,
0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x3b,
0x3c, 0x3d, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06,
0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e,
0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16,
0x17, 0x18, 0x19, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x20,
0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28,
0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, 0x30,
0x31, 0x32, 0x33, 0xff, 0xff, 0xff, 0xff, 0xff
};
static int ldif_base64_encode_internal( unsigned char *src, char *dst, int srclen,
int lenused, int wraplen );
/*
* ldif_parse_line - takes a line of the form "type:[:] value" and splits it
* into components "type" and "value". if a double colon separates type from
* value, then value is encoded in base 64, and parse_line un-decodes it
* (in place) before returning.
*/
int
ldif_parse_line(
char *line,
char **type,
char **value,
int *vlen
)
{
char *p, *s, *d;
int b64;
/* skip any leading space */
while ( ISBLANK( *line ) ) {
line++;
}
*type = line;
for ( s = line; *s && *s != ':'; s++ )
; /* NULL */
if ( *s == '\0' ) {
/* Comment-out while we address calling libldif from ns-back-ldbm
on NT. 1 of 3 */
#if defined( _WIN32 )
/*
#endif
LDAPDebug( LDAP_DEBUG_PARSE, "ldif_parse_line: missing ':' "
"on line \"%s\"\n", line, 0, 0 );
#if defined( _WIN32 )
*/
#endif
return( -1 );
}
/* trim any space between type and : */
for ( p = s - 1; p > line && ISBLANK( *p ); p-- ) {
*p = '\0';
}
*s++ = '\0';
/* check for double : - indicates base 64 encoded value */
if ( *s == ':' ) {
s++;
b64 = 1;
/* single : - normally encoded value */
} else {
b64 = 0;
}
/* skip space between : and value */
while ( ISBLANK( *s ) ) {
s++;
}
/*
* If no value is present, return a zero-length string for
* *value, with *vlen set to zero.
*/
if ( *s == '\0' ) {
*value = s;
*vlen = 0;
return( 0 );
}
/* check for continued line markers that should be deleted */
for ( p = s, d = s; *p; p++ ) {
if ( *p != CONTINUED_LINE_MARKER )
*d++ = *p;
}
*d = '\0';
*value = s;
if ( b64 ) {
if (( *vlen = ldif_base64_decode( s, (unsigned char *)s ))
< 0 ) {
/* Comment-out while we address calling libldif from ns-back-ldbm
on NT. 3 of 3 */
#if defined( _WIN32 )
/*
#endif
LDAPDebug( LDAP_DEBUG_ANY,
"ldif_parse_line: invalid base 64 char on line \"%s\"\n",
line, 0, 0 );
#if defined( _WIN32 )
*/
#endif
return( -1 );
}
s[ *vlen ] = '\0';
} else {
*vlen = (int) (d - s);
}
return( 0 );
}
/*
* ldif_base64_decode - take the BASE64-encoded characters in "src"
* (a zero-terminated string) and decode them into the the buffer "dst".
* "src" and "dst" can be the same if in-place decoding is desired.
* "dst" must be large enough to hold the decoded octets. No more than
* 3 * strlen( src ) / 4 bytes will be produced.
* "dst" may contain zero octets anywhere within it, but it is not
* zero-terminated by this function.
*
* The number of bytes copied to "dst" is returned if all goes well.
* -1 is returned if the BASE64 encoding in "src" is invalid.
*/
int
ldif_base64_decode( char *src, unsigned char *dst )
{
char *p, *stop;
unsigned char nib, *byte;
int i, len;
stop = strchr( src, '\0' );
byte = dst;
for ( p = src, len = 0; p < stop; p += 4, len += 3 ) {
for ( i = 0; i < 4; i++ ) {
if ( p[i] != '=' && (p[i] & 0x80 ||
b642nib[ p[i] & 0x7f ] > 0x3f) ) {
return( -1 );
}
}
/* first digit */
nib = b642nib[ p[0] & 0x7f ];
byte[0] = nib << 2;
/* second digit */
nib = b642nib[ p[1] & 0x7f ];
byte[0] |= nib >> 4;
/* third digit */
if ( p[2] == '=' ) {
len += 1;
break;
}
byte[1] = (nib & RIGHT4) << 4;
nib = b642nib[ p[2] & 0x7f ];
byte[1] |= nib >> 2;
/* fourth digit */
if ( p[3] == '=' ) {
len += 2;
break;
}
byte[2] = (nib & RIGHT2) << 6;
nib = b642nib[ p[3] & 0x7f ];
byte[2] |= nib;
byte += 3;
}
return( len );
}
/*
* ldif_getline - return the next "line" (minus newline) of input from a
* string buffer of lines separated by newlines, terminated by \n\n
* or \0. this routine handles continued lines, bundling them into
* a single big line before returning. if a line begins with a white
* space character, it is a continuation of the previous line. the white
* space character (nb: only one char), and preceeding newline are changed
* into CONTINUED_LINE_MARKER chars, to be deleted later by the
* ldif_parse_line() routine above.
*
* it takes a pointer to a pointer to the buffer on the first call,
* which it updates and must be supplied on subsequent calls.
*
* XXX need to update this function to also support <CR><LF> as EOL.
* XXX supports <CR><LF> as of 07/29/1998 (richm)
*/
char *
ldif_getline( char **next )
{
char *l;
char c;
char *p;
if ( *next == NULL || **next == '\n' || **next == '\0' ) {
return( NULL );
}
while ( **next == '#' ) { /* skip comment lines */
if (( *next = strchr( *next, '\n' )) == NULL ) {
return( NULL );
}
(*next)++;
}
l = *next;
while ( (*next = strchr( *next, '\n' )) != NULL ) {
p = *next - 1; /* pointer to character previous to the newline */
c = *(*next + 1); /* character after the newline */
if ( ISBLANK( c ) && c != '\n' ) {
/* DOS EOL is \r\n, so if the character before */
/* the \n is \r, continue it too */
if (*p == '\r')
*p = CONTINUED_LINE_MARKER;
**next = CONTINUED_LINE_MARKER;
*(*next+1) = CONTINUED_LINE_MARKER;
} else {
/* DOS EOL is \r\n, so if the character before */
/* the \n is \r, null it too */
if (*p == '\r')
*p = '\0';
*(*next)++ = '\0';
break;
}
(*next)++;
}
return( l );
}
#define LDIF_SAFE_CHAR( c ) ( (c) != '\r' && (c) != '\n' )
#define LDIF_CONSERVATIVE_CHAR( c ) ( LDIF_SAFE_CHAR(c) && isascii((c)) \
&& ( isprint((c)) || (c) == '\t' ))
#define LDIF_SAFE_INITCHAR( c ) ( LDIF_SAFE_CHAR(c) && (c) != ':' \
&& (c) != ' ' && (c) != '<' )
#define LDIF_CONSERVATIVE_INITCHAR( c ) ( LDIF_SAFE_INITCHAR( c ) && \
! ( isascii((c)) && isspace((c))))
#define LDIF_CONSERVATIVE_FINALCHAR( c ) ( (c) != ' ' )
void
ldif_put_type_and_value_with_options( char **out, char *t, char *val,
int vlen, unsigned long options )
{
unsigned char *p, *byte, *stop;
char *save;
int b64, len, savelen, wraplen;
len = 0;
if ( LDIF_OPT_ISSET( options, LDIF_OPT_NOWRAP )) {
wraplen = -1;
} else {
wraplen = LDIF_MAX_LINE_WIDTH;
}
/* put the type + ": " */
for ( p = (unsigned char *) t; *p; p++, len++ ) {
*(*out)++ = *p;
}
*(*out)++ = ':';
len++;
if ( LDIF_OPT_ISSET( options, LDIF_OPT_VALUE_IS_URL )) {
*(*out)++ = '<'; /* add '<' for URLs */
len++;
}
save = *out;
savelen = len;
b64 = 0;
stop = (unsigned char *)val;
if ( val && vlen > 0 ) {
*(*out)++ = ' ';
stop = (unsigned char *) (val + vlen);
if ( LDIF_OPT_ISSET( options, LDIF_OPT_MINIMAL_ENCODING )) {
if ( !LDIF_SAFE_INITCHAR( val[0] )) {
b64 = 1;
}
} else {
if ( !LDIF_CONSERVATIVE_INITCHAR( val[0] ) ||
!LDIF_CONSERVATIVE_FINALCHAR( val[vlen-1] )) {
b64 = 1;
}
}
}
if ( !b64 ) {
for ( byte = (unsigned char *) val; byte < stop;
byte++, len++ ) {
if ( LDIF_OPT_ISSET( options,
LDIF_OPT_MINIMAL_ENCODING )) {
if ( !LDIF_SAFE_CHAR( *byte )) {
b64 = 1;
break;
}
} else if ( !LDIF_CONSERVATIVE_CHAR( *byte )) {
b64 = 1;
break;
}
if ( wraplen != -1 && len > wraplen ) {
*(*out)++ = '\n';
*(*out)++ = ' ';
len = 1;
}
*(*out)++ = *byte;
}
}
if ( b64 ) {
*out = save;
*(*out)++ = ':';
*(*out)++ = ' ';
len = ldif_base64_encode_internal( (unsigned char *)val, *out, vlen,
savelen + 2, wraplen );
*out += len;
}
*(*out)++ = '\n';
}
void
ldif_put_type_and_value( char **out, char *t, char *val, int vlen )
{
ldif_put_type_and_value_with_options( out, t, val, vlen, 0 );
}
void
ldif_put_type_and_value_nowrap( char **out, char *t, char *val, int vlen )
{
ldif_put_type_and_value_with_options( out, t, val, vlen, LDIF_OPT_NOWRAP );
}
/*
* ldif_base64_encode_internal - encode "srclen" bytes in "src", place BASE64
* encoded bytes in "dst" and return the length of the BASE64
* encoded string. "dst" is also zero-terminated by this function.
*
* If "lenused" >= 0, newlines will be included in "dst" and "lenused" if
* appropriate. "lenused" should be a count of characters already used
* on the current line. The LDIF lines we create will contain at most
* "wraplen" characters on each line, unless "wraplen" is -1, in which
* case output line length is unlimited.
*
* If "lenused" < 0, no newlines will be included, and the LDIF_BASE64_LEN()
* macro can be used to determine how many bytes will be placed in "dst."
*/
static int
ldif_base64_encode_internal( unsigned char *src, char *dst, int srclen, int lenused, int wraplen )
{
unsigned char *byte, *stop;
unsigned char buf[3];
char *out;
unsigned long bits;
int i, pad, len;
len = 0;
out = dst;
stop = src + srclen;
/* convert to base 64 (3 bytes => 4 base 64 digits) */
for ( byte = src; byte < stop - 2; byte += 3 ) {
bits = (byte[0] & 0xff) << 16;
bits |= (byte[1] & 0xff) << 8;
bits |= (byte[2] & 0xff);
for ( i = 0; i < 4; i++, bits <<= 6 ) {
if ( wraplen != -1 && lenused >= 0 && lenused++ > wraplen ) {
*out++ = '\n';
*out++ = ' ';
lenused = 2;
}
/* get b64 digit from high order 6 bits */
*out++ = nib2b64[ (bits & 0xfc0000L) >> 18 ];
}
}
/* add padding if necessary */
if ( byte < stop ) {
for ( i = 0; byte + i < stop; i++ ) {
buf[i] = byte[i];
}
for ( pad = 0; i < 3; i++, pad++ ) {
buf[i] = '\0';
}
byte = buf;
bits = (byte[0] & 0xff) << 16;
bits |= (byte[1] & 0xff) << 8;
bits |= (byte[2] & 0xff);
for ( i = 0; i < 4; i++, bits <<= 6 ) {
if ( wraplen != -1 && lenused >= 0 && lenused++ > wraplen ) {
*out++ = '\n';
*out++ = ' ';
lenused = 2;
}
if (( i == 3 && pad > 0 ) || ( i == 2 && pad == 2 )) {
/* Pad as appropriate */
*out++ = '=';
} else {
/* get b64 digit from low order 6 bits */
*out++ = nib2b64[ (bits & 0xfc0000L) >> 18 ];
}
}
}
*out = '\0';
return( out - dst );
}
int
ldif_base64_encode( unsigned char *src, char *dst, int srclen, int lenused )
{
return ldif_base64_encode_internal( src, dst, srclen, lenused, LDIF_MAX_LINE_WIDTH );
}
int
ldif_base64_encode_nowrap( unsigned char *src, char *dst, int srclen, int lenused )
{
return ldif_base64_encode_internal( src, dst, srclen, lenused, -1 );
}
/*
* return malloc'd, zero-terminated LDIF line
*/
char *
ldif_type_and_value_with_options( char *type, char *val, int vlen,
unsigned long options )
{
char *buf, *p;
int tlen;
tlen = strlen( type );
if (( buf = (char *)malloc( LDIF_SIZE_NEEDED( tlen, vlen ) + 1 )) !=
NULL ) {
p = buf;
ldif_put_type_and_value_with_options( &p, type, val, vlen, options );
*p = '\0';
}
return( buf );
}
char *
ldif_type_and_value( char *type, char *val, int vlen )
{
return ldif_type_and_value_with_options( type, val, vlen, 0 );
}
char *
ldif_type_and_value_nowrap( char *type, char *val, int vlen )
{
return ldif_type_and_value_with_options( type, val, vlen, LDIF_OPT_NOWRAP );
}
/*
* ldif_get_entry - read the next ldif entry from the FILE referenced
* by fp. return a pointer to a malloc'd, null-terminated buffer. also
* returned is the last line number read, in *lineno.
*/
char *
ldif_get_entry( FILE *fp, int *lineno )
{
char line[BUFSIZ];
char *buf;
int max, cur, len, gotsome;
buf = NULL;
max = cur = gotsome = 0;
while ( fgets( line, sizeof(line), fp ) != NULL ) {
if ( lineno != NULL ) {
(*lineno)++;
}
/* ldif entries are terminated by a \n on a line by itself */
if ( line[0] == '\0' || line[0] == '\n'
#if !defined( XP_WIN32 )
|| ( line[0] == '\r' && line[1] == '\n' ) /* DOS format */
#endif
) {
if ( gotsome ) {
break;
} else {
continue;
}
} else if ( line[0] == '#' ) {
continue;
}
gotsome = 1;
len = strlen( line );
#if !defined( XP_WIN32 )
/* DOS format */
if ( len > 0 && line[len-1] == '\r' ) {
--len;
line[len] = '\0';
} else if ( len > 1 && line[len-2] == '\r' && line[len-1] == '\n' ) {
--len;
line[len-1] = line[len];
line[len] = '\0';
}
#endif
while ( cur + (len + 1) > max ) {
if ( buf == NULL ) {
max += BUFSIZ;
buf = (char *) malloc( max );
} else {
max *= 2;
buf = (char *) realloc( buf, max );
}
if ( buf == NULL ) {
return( NULL );
}
}
memcpy( buf + cur, line, len + 1 );
cur += len;
}
return( buf );
}

View file

@ -0,0 +1,23 @@
# vim: set filetype=python:
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
include('/ldap/ldap-sdk.mozbuild')
SharedLibrary('ldif60')
SOURCES += [
'line64.c'
]
LOCAL_INCLUDES += [
'/ldap/c-sdk/include'
]
if CONFIG['OS_ARCH'] == 'WINNT':
DEFFILE = SRCDIR + '/libldif.def'
DEFINES['USE_WAITPID'] = True
DEFINES['NEEDPROTOS'] = True

Some files were not shown because too many files have changed in this diff Show more