📄 libldap.c
字号:
/* Copyright (C) 2003, 2004, 2005 Thorsten Kukuk The basis of this code is from the pam_ldap-148 package written by Luke Howard. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License version 2 as published by the Free Software Foundation. This program 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 General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */#ifdef HAVE_CONFIG_H#include <config.h>#endif#ifdef USE_LDAP#define _GNU_SOURCE#include <grp.h>#include <pwd.h>#include <stdio.h>#include <stdlib.h>#include <string.h>#include <sys/time.h>#include <sys/param.h>#include <unistd.h>#include <syslog.h>#include <netdb.h>#include <errno.h>#ifdef HAVE_LBER_H#include <lber.h>#endif#ifdef HAVE_LDAP_H#include <ldap.h>#endif#ifdef HAVE_LDAP_SSL_H#include <ldap_ssl.h>#endif#include "i18n.h"#define _INCLUDED_FROM_LIBLDAP_C_#include "libldap.h"#ifndef HAVE_LDAP_MEMFREE#define ldap_memfree(x) free(x)#endif#if LDAP_SET_REBIND_PROC_ARGS < 3static ldap_session_t *global_session = 0;#endif#ifndef HAVE_LDAP_GET_LDERRNOstatic intldap_get_lderrno (LDAP *ld, char **m, char **s){#ifdef HAVE_LDAP_GET_OPTION int rc;#endif int lderrno;#if defined(HAVE_LDAP_GET_OPTION) && defined(LDAP_OPT_ERROR_NUMBER) /* is this needed? */ rc = ldap_get_option (ld, LDAP_OPT_ERROR_NUMBER, &lderrno); if (rc != LDAP_SUCCESS) return rc;#else lderrno = ld->ld_errno;#endif if (s != NULL) {#if defined(HAVE_LDAP_GET_OPTION) && defined(LDAP_OPT_ERROR_STRING) rc = ldap_get_option (ld, LDAP_OPT_ERROR_STRING, s); if (rc != LDAP_SUCCESS) return rc;#else *s = ld->ld_error;#endif } if (s != NULL) {#if defined(HAVE_LDAP_GET_OPTION) && defined(LDAP_OPT_MATCHED_DN) rc = ldap_get_option (ld, LDAP_OPT_MATCHED_DN, m); if (rc != LDAP_SUCCESS) return rc;#else *m = ld->ld_matched;#endif } return lderrno;}#endifvoidfree_ldap_config (ldap_config_t **pconfig){ ldap_config_t *c; c = *pconfig; if (c == NULL) return; if (c->host != NULL) free (c->host); if (c->base != NULL) free (c->base); if (c->binddn != NULL) free (c->binddn); if (c->bindpw != NULL) { memset (c->bindpw, 0, strlen (c->bindpw)); free (c->bindpw); } if (c->rootbinddn != NULL) free (c->rootbinddn); if (c->rootbindpw != NULL) { memset (c->rootbindpw, 0, strlen (c->rootbindpw)); free (c->rootbindpw); } if (c->sslpath != NULL) free (c->sslpath); if (c->tmplattr != NULL) free (c->tmplattr); if (c->tmpluser != NULL) free (c->tmpluser); if (c->groupattr != NULL) free (c->groupattr); if (c->groupdn != NULL) free (c->groupdn); memset (c, 0, sizeof (*c)); free (c); *pconfig = NULL; return;}#if 0 /* XXX */static voidfree_bind_info (bind_info_t **info){ if (*info == NULL) return; if ((*info)->dn != NULL) free ((*info)->dn); if ((*info)->pw) { memset ((*info)->pw, 0, strlen ((*info)->pw)); free((*info)->pw); } if ((*info)->user) free ((*info)->user); free (*info); *info = NULL; return;}#endifstatic ldap_config_t *alloc_ldap_config (void){ ldap_config_t *result = (ldap_config_t *) calloc (1, sizeof (*result)); if (result == NULL) { errno = ENOMEM; return NULL; } result->scope = LDAP_SCOPE_SUBTREE; result->deref = LDAP_DEREF_NEVER; result->host = NULL; result->base = NULL; result->port = 0; result->binddn = NULL; result->bindpw = NULL; result->rootbinddn = NULL; result->rootbindpw = NULL; result->ssl_on = SSL_OFF; result->sslpath = NULL; result->groupattr = NULL; result->groupdn = NULL; result->getpolicy = 0; result->checkhostattr = 0;#ifdef LDAP_VERSION3 result->version = LDAP_VERSION3;#else result->version = LDAP_VERSION2;#endif /* LDAP_VERSION2 */ result->timelimit = LDAP_NO_LIMIT; result->bind_timelimit = 10; result->referrals = 1; result->restart = 1; result->password_type = PASSWORD_CLEAR; result->tmplattr = NULL; result->tmpluser = NULL; result->tls_checkpeer = 0; result->tls_cacertfile = NULL; result->tls_cacertdir = NULL; result->tls_ciphers = NULL; result->tls_cert = NULL; result->tls_key = NULL; return result;}#define CHECKPOINTER(ptr) do { if ((ptr) == NULL) { \ fclose(fp); \ free_ldap_config (&result); \ return NULL; \} \} while (0)static ldap_config_t *read_ldap_config (const char *configFile){ /* this is the same configuration file as for nss_ldap and pam_ldap */ FILE *fp; char b[BUFSIZ]; char *defaultBase, *passwdBase; int defaultScope, passwdScope; ldap_config_t *result; if ((result = alloc_ldap_config ()) == NULL) return NULL; /* configuration file location is configurable; default /etc/ldap.conf */ if (configFile == NULL) configFile = LDAP_PATH_CONF; fp = fopen (configFile, "r"); if (fp == NULL) { if (isatty (fileno(stderr))) fprintf (stderr, "missing file \"%s\".\n", configFile); else syslog (LOG_ERR, "missing file \"%s\"", configFile); return NULL; } defaultBase = NULL; defaultScope = LDAP_SCOPE_SUBTREE; passwdBase = NULL; passwdScope = -1; while (fgets (b, sizeof (b), fp) != NULL) { char *k, *v; int len; if (*b == '\n' || *b == '#') continue; k = b; v = k; while (*v != '\0' && *v != ' ' && *v != '\t') v++; if (*v == '\0') continue; *(v++) = '\0'; /* skip all whitespaces between keyword and value */ /* Lars Oergel <lars.oergel@innominate.de>, 05.10.2000 */ while (*v == ' ' || *v == '\t') v++; /* kick off all whitespaces and newline at the end of value */ /* Bob Guo <bob@mail.ied.ac.cn>, 08.10.2001 */ len = strlen (v) - 1; while (v[len] == ' ' || v[len] == '\t' || v[len] == '\n') --len; v[len + 1] = '\0'; if (!strcasecmp (k, "host")) { CHECKPOINTER (result->host = strdup (v)); } else if (!strcasecmp (k, "uri")) { CHECKPOINTER (result->uri = strdup (v)); } else if (!strcasecmp (k, "base")) { CHECKPOINTER (defaultBase = strdup (v)); } else if (!strcasecmp (k, "binddn")) { CHECKPOINTER (result->binddn = strdup (v)); } else if (!strcasecmp (k, "bindpw")) { CHECKPOINTER (result->bindpw = strdup (v)); } else if (!strcasecmp (k, "rootbinddn")) { CHECKPOINTER (result->rootbinddn = strdup (v)); } else if (!strcasecmp (k, "scope")) { if (!strncasecmp (v, "sub", 3)) result->scope = LDAP_SCOPE_SUBTREE; else if (!strncasecmp (v, "one", 3)) result->scope = LDAP_SCOPE_ONELEVEL; else if (!strncasecmp (v, "base", 4)) result->scope = LDAP_SCOPE_BASE; } else if (!strcasecmp (k, "deref")) { if (!strcasecmp (v, "never")) result->deref = LDAP_DEREF_NEVER; else if (!strcasecmp (v, "searching")) result->deref = LDAP_DEREF_SEARCHING; else if (!strcasecmp (v, "finding")) result->deref = LDAP_DEREF_FINDING; else if (!strcasecmp (v, "always")) result->deref = LDAP_DEREF_ALWAYS; } else if (!strcasecmp (k, "pam_password")) { if (!strcasecmp (v, "clear")) result->password_type = PASSWORD_CLEAR; else if (!strcasecmp (v, "crypt")) result->password_type = PASSWORD_CRYPT; else if (!strcasecmp (v, "md5")) result->password_type = PASSWORD_MD5; else if (!strcasecmp (v, "nds")) result->password_type = PASSWORD_NDS; else if (!strcasecmp (v, "ad")) result->password_type = PASSWORD_AD; else if (!strcasecmp (v, "exop")) result->password_type = PASSWORD_EXOP; } else if (!strcasecmp (k, "pam_crypt")) { /* * we still support this even though it is * deprecated, as it could be a security * hole to change this behaviour on * unsuspecting users of pam_ldap. */ if (!strcasecmp (v, "local")) result->password_type = PASSWORD_CRYPT; else result->password_type = PASSWORD_CLEAR; } else if (!strcasecmp (k, "port")) { result->port = atoi (v); } else if (!strcasecmp (k, "timelimit")) { result->timelimit = atoi (v); } else if (!strcasecmp (k, "bind_timelimit")) { result->bind_timelimit = atoi (v); } else if (!strcasecmp (k, "ldap_version")) { result->version = atoi (v); } else if (!strcasecmp (k, "sslpath")) { CHECKPOINTER (result->sslpath = strdup (v)); } else if (!strcasecmp (k, "ssl")) { if (!strcasecmp (v, "on") || !strcasecmp (v, "yes") || !strcasecmp (v, "true")) { result->ssl_on = SSL_LDAPS; } else if (!strcasecmp (v, "start_tls")) { result->ssl_on = SSL_START_TLS; } } else if (!strcasecmp (k, "referrals")) { result->referrals = (!strcasecmp (v, "on") || !strcasecmp (v, "yes") || !strcasecmp (v, "true")); } else if (!strcasecmp (k, "restart")) { result->restart = (!strcasecmp (v, "on") || !strcasecmp (v, "yes") || !strcasecmp (v, "true")); } else if (!strcasecmp (k, "pam_template_login_attribute")) { CHECKPOINTER (result->tmplattr = strdup (v)); } else if (!strcasecmp (k, "pam_template_login")) { CHECKPOINTER (result->tmpluser = strdup (v)); } else if (!strcasecmp (k, "pam_lookup_policy")) { result->getpolicy = !strcasecmp (v, "yes"); } else if (!strcasecmp (k, "pam_check_host_attr")) { result->checkhostattr = !strcasecmp (v, "yes"); } else if (!strcasecmp (k, "pam_groupdn")) { CHECKPOINTER (result->groupdn = strdup (v)); } else if (!strcasecmp (k, "pam_member_attribute")) { CHECKPOINTER (result->groupattr = strdup (v)); } else if (!strcasecmp (k, "tls_checkpeer")) { if (!strcasecmp (v, "on") || !strcasecmp (v, "yes") || !strcasecmp (v, "true")) { result->tls_checkpeer = 1; } else if (!strcasecmp (v, "off") || !strcasecmp (v, "no") || !strcasecmp (v, "false")) { result->tls_checkpeer = 0; } } else if (!strcasecmp (k, "tls_cacertfile")) { CHECKPOINTER (result->tls_cacertfile = strdup (v)); } else if (!strcasecmp (k, "tls_cacertdir")) { CHECKPOINTER (result->tls_cacertdir = strdup (v)); } else if (!strcasecmp (k, "tls_ciphers")) { CHECKPOINTER (result->tls_ciphers = strdup (v)); } else if (!strcasecmp (k, "tls_cert")) { CHECKPOINTER (result->tls_cert = strdup (v)); } else if (!strcasecmp (k, "tls_key")) { CHECKPOINTER (result->tls_key = strdup (v)); } } if (passwdBase != NULL) { if (defaultBase != NULL) { size_t len = strlen (passwdBase); if (passwdBase[len - 1] == ',') { char *p; p = (char *) malloc (len + strlen (defaultBase) + 1); if (p == NULL) { fclose (fp); free (defaultBase); /* leak the rest... */ free_ldap_config (&result); return NULL; } strcpy (p, passwdBase); strcpy (&p[len], defaultBase); free (passwdBase); passwdBase = p; }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -