/*
* Copyright (C) 1997-2003 Luke Howard. This file is part of the nss_ldap library. Contributed by Luke Howard, <lukeh@padl.com>, 1997.
*
* The nss_ldap library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version.
*
* The nss_ldap library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public License along with the nss_ldap library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*
* $Id: ldap-nss.h,v 1.1.1.1 2004/05/06 07:26:16 bushman Exp $
*/
#ifndef _LDAP_NSS_LDAP_LDAP_NSS_H
#define _LDAP_NSS_LDAP_LDAP_NSS_H
#ifdef HAVE_MALLOC_H
#include <malloc.h>
#endif
/* for glibc, use weak aliases to pthreads functions */
#ifdef HAVE_LIBC_LOCK_H
#include <libc-lock.h>
#elif defined(HAVE_BITS_LIBC_LOCK_H)
#include <bits/libc-lock.h>
#endif
#include <errno.h>
#include <time.h>
#include <sys/socket.h>
#include <netinet/in.h>
#ifndef __P
#if defined(__STDC__) || defined(__GNUC__)
#define __P(x) x
#else
#define __P(x) ()
#endif
#endif
#include <netdb.h>
#include <netinet/in.h>
#include <syslog.h>
#ifdef HAVE_NSSWITCH_H
#include <nss_common.h>
#include <nss_dbdefs.h>
#include <nsswitch.h>
#elif defined(HAVE_NSS_H)
#include <nss.h>
#elif defined(HAVE_IRS_H)
#include "irs-nss.h"
#endif
#include "ldap-schema.h"
/*
* Timeouts for reconnecting code. Similar to rebind logic in Darwin NetInfo. Some may find sleeping unacceptable, in which case you may wish to adjust the constants below.
*/
#define LDAP_NSS_TRIES 5 /* number of sleeping reconnect attempts */
#define LDAP_NSS_SLEEPTIME 4 /* seconds to sleep; doubled until max */
#define LDAP_NSS_MAXSLEEPTIME 64 /* maximum seconds to sleep */
#define LDAP_NSS_MAXCONNTRIES 2 /* reconnect attempts before sleeping */
#ifdef PAGE_RESULTS
#define LDAP_PAGESIZE 1000
#endif /* PAGE_RESULTS */
#ifndef LDAP_FILT_MAXSIZ
#define LDAP_FILT_MAXSIZ 1024
#endif /* !LDAP_FILT_MAXSIZE */
#ifndef debug
#define debug(fmt, args...) fprintf(stderr, "nss_ldap: " fmt "\n" , ## args)
#endif
#ifdef DEBUG
#ifdef DEBUG_SYSLOG
#ifdef HAVE_NSSWITCH_H
#define debug(fmt, args...) syslog(LOG_DEBUG, "nss_ldap: thread %u - " fmt, thr_self() , ## args)
#else
#define debug(fmt, args...) syslog(LOG_DEBUG, "nss_ldap: thread %u - " fmt, pthread_self() , ## args)
#endif /* HAVE_NSSWITCH_H */
#else
#ifndef __GNUC__
#include <stdarg.h>
#include <stdio.h>
static void
debug(char *fmt,...)
{
va_list ap;
va_start(ap, fmt);
fprintf(stderr, "nss_ldap: ");
vfprintf(stderr, fmt, ap);
va_end(ap);
fprintf(stderr, "\n");
}
#else
//#define debug(fmt, args...) fprintf(stderr, "nss_ldap: " fmt "\n" , ## args)
#endif /* __GNUC__ */
#endif /* DEBUG_SYSLOG */
#else
#ifndef __GNUC__
static void
debug(char *fmt,...)
{
}
#else
//#define debug(fmt, args...)
#endif /* __GNUC__ */
#endif /* DEBUG */
#ifdef __GNUC__
#define alignof(ptr) __alignof__(ptr)
#define INLINE inline
#elif defined(HAVE_ALIGNOF_H)
#include <alignof.h>
#define INLINE
#else
#define alignof(ptr) (sizeof(char *))
#define INLINE
#endif /* __GNUC__ */
#define align(ptr, blen, TYPE) do { \
char *qtr = ptr; \
ptr += alignof(TYPE) - 1; \
ptr -= ((ptr - (char *)NULL) % alignof(TYPE)); \
blen -= (ptr - qtr); \
} while (0)
/* worst case */
#define bytesleft(ptr, blen, TYPE) (blen - alignof(TYPE) + 1)
/* selectors for different maps */
enum ldap_map_selector {
LM_PASSWD,
LM_SHADOW,
LM_GROUP,
LM_HOSTS,
LM_SERVICES,
LM_NETWORKS,
LM_PROTOCOLS,
LM_RPC,
LM_ETHERS,
LM_NETMASKS,
LM_BOOTPARAMS,
LM_ALIASES,
LM_NETGROUP,
LM_NONE
};
typedef enum ldap_map_selector ldap_map_selector_t;
#ifdef AT_OC_MAP
enum ldap_userpassword_selector {
LU_RFC2307_USERPASSWORD,
LU_RFC3112_AUTHPASSWORD,
LU_OTHER_PASSWORD
};
typedef enum ldap_userpassword_selector ldap_userpassword_selector_t;
#endif /* AT_OC_MAP */
enum ldap_ssl_options {
SSL_OFF,
SSL_LDAPS,
SSL_START_TLS
};
typedef enum ldap_ssl_options ldap_ssl_options_t;
enum ldap_reconnect_policy {
LP_RECONNECT_HARD,
LP_RECONNECT_SOFT
};
typedef enum ldap_reconnect_policy ldap_reconnect_policy_t;
/*
* POSIX profile information (not used yet) see draft-joslin-config-schema-00.txt
*/
struct ldap_service_search_descriptor {
/* search base, qualified */
char *lsd_base;
/* scope */
int lsd_scope;
/* filter */
char *lsd_filter;
/* next */
struct ldap_service_search_descriptor *lsd_next;
};
typedef struct ldap_service_search_descriptor
ldap_service_search_descriptor_t;
/*
* linked list of configurations pointing to LDAP servers. The first which has a successful ldap_open() is used. Conceivably the rest could be used after a failed or exhausted search.
*/
struct ldap_config {
/* URI for a single server */
char *ldc_uri;
/* space delimited list of servers */
char *ldc_host;
/* port, expected to be common to all servers */
int ldc_port;
/* base DN, eg. dc=gnu,dc=org */
char *ldc_base;
/* scope for searches */
int ldc_scope;
/* dereference aliases/links */
int ldc_deref;
/* bind DN */
char *ldc_binddn;
/* bind cred */
char *ldc_bindpw;
/* sasl auth id */
char *ldc_saslid;
/* do we use sasl when binding? */
int ldc_usesasl;
/* shadow bind DN */
char *ldc_rootbinddn;
/* shadow bind cred */
char *ldc_rootbindpw;
/* shadow sasl auth id */
char *ldc_rootsaslid;
/* do we use sasl for root? */
int ldc_rootusesasl;
/* protocol version */
int ldc_version;
/* search timelimit */
int ldc_timelimit;
/* bind timelimit */
int ldc_bind_timelimit;
/* SSL enabled */
ldap_ssl_options_t ldc_ssl_on;
/* SSL certificate path */
char *ldc_sslpath;
/* Chase referrals */
int ldc_referrals;
int ldc_restart;
/* naming contexts */
ldap_service_search_descriptor_t *ldc_sds[LM_NONE];
/* tls check peer */
int ldc_tls_checkpeer;
/* tls ca certificate file */
char *ldc_tls_cacertfile;
/* tls ca certificate dir */
char *ldc_tls_cacertdir;
/* tls ciphersuite */
char *ldc_tls_ciphers;
/* tls certificate */
char *ldc_tls_cert;
/* tls key */
char *ldc_tls_key;
/* tls randfile */
char *ldc_tls_randfile;
/* idle timeout */
time_t ldc_idle_timelimit;
/* reconnect policy */
ldap_reconnect_policy_t ldc_reconnect_pol;
#ifdef AT_OC_MAP
/*
* attribute/objectclass maps relative to this config
*/
void *ldc_at_map;
void *ldc_oc_map;
/*
* is userPassword "userPassword" or not? ie. do we need {crypt} to be stripped
*/
ldap_userpassword_selector_t ldc_password_type;
#endif /* AT_OC_MAP */
/*
* attribute table for ldap search requensts
*/
const char **ldc_attrtab[LM_NONE];
char *ldc_template_homedir;
char *ldc_template_loginshell;
/* next configuration. loops back onto itself for last entry */
struct ldap_config *ldc_next;
};
typedef struct ldap_config ldap_config_t;
/*
* convenient wrapper around pointer into global config list, and a connection to an LDAP server.
*/
struct ldap_session {
/* the connection */
LDAP *ls_conn;
/* pointer into config table */
ldap_config_t *ls_config;
/* timestamp of last activity */
time_t ls_timestamp;
/* keep track of the LDAP sockets */
struct sockaddr ls_sockname;
struct sockaddr ls_peername;
};
typedef struct ldap_session ldap_session_t;
#ifndef HAVE_NSSWITCH_H
#ifndef UID_NOBODY
#define UID_NOBODY (-2)
#endif
#endif
#ifndef GID_NOBODY
#define GID_NOBODY UID_NOBODY
#endif
enum ldap_args_types {
LA_TYPE_STRING,
LA_TYPE_NUMBER,
LA_TYPE_STRING_AND_STRING,
LA_TYPE_NUMBER_AND_STRING
};
typedef enum ldap_args_types ldap_args_types_t;
struct ldap_args {
ldap_args_types_t la_type;
union {
const char *la_string;
long la_number;
}
la_arg1;
union {
const char *la_string;
}
la_arg2;
};
typedef struct ldap_args ldap_args_t;
#define LA_INIT(q) do { \
q.la_type = LA_TYPE_STRING; \
q.la_arg1.la_string = NULL; \
q.la_arg2.la_string = NULL; \
} while (0)
#define LA_TYPE(q) (q.la_type)
#define LA_STRING(q) (q.la_arg1.la_string)
#define LA_NUMBER(q) (q.la_arg1.la_number)
#define LA_STRING2(q) (q.la_arg2.la_string)
#include "ldap-parse.h"
/*
* the state consists of the desired attribute value or an offset into a list of values for the desired attribute. This is necessary to support services.
*
* Be aware of the arbitary distinction between state and context. Context is the enumeration state of a lookup subsystem (which may be per-subsystem, or per-subsystem/per-thread, depending on the OS). State is the state of a particular lookup, and is only concerned with resolving and enumerating services. State is represented as instances of ldap_state_t; context as instances of ent_context_t. The latter contains the former.
*/
struct ldap_state {
int ls_type;
int ls_retry;
#define LS_TYPE_KEY (0)
#define LS_TYPE_INDEX (1)
union {
/*
* ls_key is the requested attribute value. ls_index is the desired offset into the value list.
*/
const char *ls_key;
int ls_index;
}
ls_info;
};
typedef struct ldap_state ldap_state_t;
/*
* LS_INIT only used for enumeration contexts
*/
#define LS_INIT(state) do { state.ls_type = LS_TYPE_INDEX; state.ls_retry = 0; state.ls_info.ls_index = -1; } while (0)
/*
* thread specific context: result chain, and state data
*/
struct ent_context {
ldap_state_t ec_state; /* eg. for services */
int ec_msgid; /* message ID */
LDAPMessage *ec_res; /* result chain */
ldap_service_search_descriptor_t *ec_sd; /* current sd */
#ifdef PAGE_RESULTS
struct berval *ec_cookie; /* cookie for paged searches */
#endif /* PAGE_RESULTS */
};
typedef struct ent_context ent_context_t;
#ifdef HAVE_NSSWITCH_H
struct nss_ldap_backend {
nss_backend_op_t *ops;
int n_ops;
ent_context_t *state;
};
typedef struct nss_ldap_backend nss_ldap_backend_t;
typedef nss_status_t NSS_STATUS;
#define NSS_RETURN NSS_UNAVAIL
#elif defined(HAVE_IRS_H)
typedef enum {
NSS_TRYAGAIN = -2,
NSS_UNAVAIL,
NSS_NOTFOUND,
NSS_SUCCESS,
NSS_RETURN
} NSS_STATUS;
/* #define HAVE_NSS_H */
#elif defined(HAVE_NSS_H)
typedef enum nss_status NSS_STATUS;
#define NSS_SUCCESS NSS_STATUS_SUCCESS
#define NSS_NOTFOUND NSS_STATUS_NOTFOUND
#define NSS_UNAVAIL NSS_STATUS_UNAVAIL
#define NSS_TRYAGAIN NSS_STATUS_TRYAGAIN
#define NSS_RETURN NSS_STATUS_RETURN
/* to let us index a lookup table on NSS_STATUSes */
#define _NSS_LOOKUP_OFFSET NSS_STATUS_TRYAGAIN
#endif /* HAVE_NSSWITCH_H */
#ifndef _NSS_LOOKUP_OFFSET
#define _NSS_LOOKUP_OFFSET (0)
#endif
typedef NSS_STATUS(*parser_t) (LDAP *, LDAPMessage *, ldap_state_t *, void *, char *, size_t);
#ifdef HPUX
extern int __thread_mutex_lock(pthread_mutex_t *);
extern int __thread_mutex_unlock(pthread_mutex_t *);
#endif /* HPUX */
/*
* Portable locking macro.
*/
#ifdef HAVE_THREAD_H
#define NSS_LDAP_LOCK(m) mutex_lock(&m)
#define NSS_LDAP_UNLOCK(m) mutex_unlock(&m)
#define NSS_LDAP_DEFINE_LOCK(m) static mutex_t m = DEFAULTMUTEX
#elif defined(HAVE_LIBC_LOCK_H) || defined(HAVE_BITS_LIBC_LOCK_H)
#define NSS_LDAP_LOCK(m) __libc_lock_lock(m)
#define NSS_LDAP_UNLOCK(m) __libc_lock_unlock(m)
#define NSS_LDAP_DEFINE_LOCK(m) static pthread_mutex_t m = PTHREAD_MUTEX_INITIALIZER
#elif defined(HAVE_PTHREAD_H)
#ifdef HPUX
#define NSS_LDAP_LOCK(m) __thread_mutex_lock(&m)
#define NSS_LDAP_UNLOCK(m) __thread_mutex_unlock(&m)
#define NSS_LDAP_DEFINE_LOCK(m) static pthread_mutex_t m = PTHREAD_MUTEX_INITIALIZER
#else
#define NSS_LDAP_LOCK(m) pthread_mutex_lock(&m)
#define NSS_LDAP_UNLOCK(m) pthread_mutex_unlock(&m)
#define NSS_LDAP_DEFINE_LOCK(m) static pthread_mutex_t m = PTHREAD_MUTEX_INITIALIZER
#endif /* HPUX */
#else
#define NSS_LDAP_LOCK(m)
#define NSS_LDAP_UNLOCK(m)
#define NSS_LDAP_DEFINE_LOCK(m)
#endif
/*
* Acquire global nss_ldap lock and blocks SIGPIPE. Generally this should only be done within ldap-nss.c.
*/
void _nss_ldap_enter(void);
/*
* Release global nss_ldap lock and blocks SIGPIPE. Generally this should only be done within ldap-nss.c.
*/
void _nss_ldap_leave(void);
#ifdef LDAP_OPT_THREAD_FN_PTRS
/*
* Netscape's libldap is threadsafe, but we use a lock before it is initialized
*/
struct ldap_error {
int le_errno;
char *le_matched;
char *le_errmsg;
};
typedef struct ldap_error ldap_error_t;
#endif /* LDAP_OPT_THREAD_FN_PTRS */
#ifdef HAVE_NSSWITCH_H
NSS_STATUS _nss_ldap_default_destr(nss_backend_t *, void *);
#endif
/*
* context management routines. _nss_ldap_default_constr() is called once in the constructor
*/
#ifdef HAVE_NSSWITCH_H
NSS_STATUS _nss_ldap_default_constr(nss_ldap_backend_t * be);
#endif
/*
* do_ent_context_init() is called for each getXXent() call do_ent_context_release() is used to manually free a context
*/
ent_context_t *_nss_ldap_ent_context_init(ent_context_t **);
void _nss_ldap_ent_context_release(ent_context_t *);
/*
* these are helper functions for ldap-grp.c only on Solaris
*/
char **_nss_ldap_get_values(LDAPMessage * e, const char *attr);
char *_nss_ldap_get_dn(LDAPMessage * e);
LDAPMessage *_nss_ldap_first_entry(LDAPMessage * res);
LDAPMessage *_nss_ldap_next_entry(LDAPMessage * res);
/*
* Synchronous search cover (caller acquires lock).
*/
NSS_STATUS _nss_ldap_search_s(const ldap_args_t * args, /* IN */
const char *filterprot,/* IN */
ldap_map_selector_t sel, /* IN */
int sizelimit, /* IN */
LDAPMessage ** pRes /* OUT */ );
/*
* Asynchronous search cover (caller acquires lock).
*/
NSS_STATUS _nss_ldap_search(const ldap_args_t * args, /* IN */
const char *filterprot,/* IN */
ldap_map_selector_t sel, /* IN */
int sizelimit, /* IN */
int *pMsgid, /* OUT */
ldap_service_search_descriptor_t ** s /* IN/OUT */ );
/*
* Retrieve next result.
*/
NSS_STATUS _nss_ldap_result(ent_context_t * ctx);
/*
* Emulate X.500 read operation.
*/
NSS_STATUS _nss_ldap_read(const char *dn, /* IN */
const char **attributes, /* IN */
LDAPMessage ** pRes /* OUT */ );
/*
* common enumeration routine; uses asynchronous API.
*/
NSS_STATUS _nss_ldap_getent(ent_context_t ** key, /* IN/OUT */
void *result, /* IN/OUT */
char *buffer, /* IN */
size_t buflen, /* IN */
int *errnop, /* OUT */
const char *filterprot,/* IN */
ldap_map_selector_t sel, /* IN */
parser_t parser /* IN */ );
/*
* common lookup routine; uses synchronous API.
*/
NSS_STATUS _nss_ldap_getbyname(ldap_args_t * args, /* IN/OUT */
void *result, /* IN/OUT */
char *buffer, /* IN */
size_t buflen, /* IN */
int *errnop, /* OUT */
const char *filterprot,/* IN */
ldap_map_selector_t sel, /* IN */
parser_t parser /* IN */ );
/* parsing utility functions */
NSS_STATUS _nss_ldap_assign_attrvals(LDAP * ld, /* IN */
LDAPMessage * e, /* IN */
const char *attr, /* IN */
const char *omitvalue, /* IN */
char ***valptr, /* OUT */
char **buffer, /* IN/OUT */
size_t * buflen, /* IN/OUT */
size_t * pvalcount /* OUT */ );
NSS_STATUS _nss_ldap_assign_attrval(LDAP * ld, /* IN */
LDAPMessage * e, /* IN */
const char *attr, /* IN */
char **valptr, /* OUT */
char **buffer, /* IN/OUT */
size_t * buflen /* IN/OUT */ );
NSS_STATUS _nss_ldap_assign_userpassword(LDAP * ld, /* IN */
LDAPMessage * e, /* IN */
const char *attr, /* IN */
char **valptr, /* OUT */
char **buffer, /* IN/OUT */
size_t * buflen); /* IN/OUT */
NSS_STATUS _nss_ldap_oc_check(LDAP * ld, LDAPMessage * e, const char *oc);
#ifdef AT_OC_MAP
/**
* Functions for mapping attributes and objectclasses
* relative to an ldap_config as proposed by Luke Howard
* in his eMail from Nov 15 2000
*/
NSS_STATUS _nss_ldap_atmap_put(ldap_config_t * config,
const char *rfc2307attribute,
const char *attribute);
NSS_STATUS _nss_ldap_ocmap_put(ldap_config_t * config,
const char *rfc2307objectclass,
const char *objectclass);
NSS_STATUS _nss_ldap_atmap_get(ldap_config_t * config,
const char *rfc2307attribute,
const char **attribute);
NSS_STATUS _nss_ldap_ocmap_get(ldap_config_t * config,
const char *rfc2307objectclass,
const char **objectclass);
const char *_nss_ldap_map_at(const char *pChar);
const char *_nss_ldap_map_oc(const char *pChar);
#endif /* AT_OC_MAP */
/*
* Proxy bind support for AIX.
*/
struct ldap_proxy_bind_args {
char *binddn;
const char *bindpw;
};
typedef struct ldap_proxy_bind_args ldap_proxy_bind_args_t;
NSS_STATUS _nss_ldap_proxy_bind(const char *user, const char *password);
NSS_STATUS _nss_ldap_init(void);
void *_nss_hash_open(void);
#endif /* _LDAP_NSS_LDAP_LDAP_NSS_H */
syntax highlighted by Code2HTML, v. 0.9.1