e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth/*
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth * CDDL HEADER START
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth *
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth * The contents of this file are subject to the terms of the
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth * Common Development and Distribution License (the "License").
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth * You may not use this file except in compliance with the License.
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth *
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth * or http://www.opensolaris.org/os/licensing.
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth * See the License for the specific language governing permissions
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth * and limitations under the License.
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth *
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth * When distributing Covered Code, include this CDDL HEADER in each
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth * If applicable, add the following below this CDDL HEADER, with the
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth * fields enclosed by brackets "[]" replaced with your own identifying
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth * information: Portions Copyright [yyyy] [name of copyright owner]
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth *
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth * CDDL HEADER END
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth */
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth/*
434c5a0685e933e08f535e85a50e4ba7e6816d38Milan Jurik * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth * Use is subject to license terms.
33f5ff17089e3a43e6e730bf80384c233123dbd9Milan Jurik * Copyright 2012 Milan Jurik. All rights reserved.
b3b48d8e61fb04617f1a22d673c555b155f02e64Hans Rosenfeld * Copyright 2012 Nexenta Systems, Inc. All rights reserved.
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth */
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth#define __STANDALONE_MODULE__
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth#include <stdio.h>
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth#include <sys/types.h>
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth#include <stdlib.h>
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth#include <libintl.h>
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth#include <string.h>
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth#include <ctype.h>
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth#include <sys/stat.h>
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth#include <fcntl.h>
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth#include <unistd.h>
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth#include <syslog.h>
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth#include <locale.h>
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth#include <errno.h>
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth#include <sys/time.h>
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth#include <arpa/inet.h>
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth#include <netdb.h>
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth#include <strings.h>
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth#include <thread.h>
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth#include <nsswitch.h>
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth#include <nss_dbdefs.h>
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth#include <nss.h>
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth#include "ns_cache_door.h"
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth#include "ns_internal.h"
ca190d8debe6672d99069a376a987adee0765d6cmichen#include "ns_connmgmt.h"
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57ethtypedef enum {
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth INFO_SERVER_JUST_INITED = -1,
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth INFO_SERVER_UNKNOWN = 0,
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth INFO_SERVER_CONNECTING = 1,
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth INFO_SERVER_UP = 2,
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth INFO_SERVER_ERROR = 3,
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth INFO_SERVER_REMOVED = 4
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth} dir_server_status_t;
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57ethtypedef enum {
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth INFO_STATUS_NEW = 2,
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth INFO_STATUS_OLD = 3
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth} dir_server_info_t;
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57ethtypedef struct dir_server {
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth char *ip;
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth char **controls;
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth char **saslMech;
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth dir_server_status_t status;
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth mutex_t updateStatus;
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth dir_server_info_t info;
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth} dir_server_t;
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57ethtypedef struct dir_server_list {
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth dir_server_t **nsServers;
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth rwlock_t listDestroyLock;
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth} dir_server_list_t;
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57ethstruct {
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth /* The local list of the directory servers' root DSEs. */
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth dir_server_list_t *list;
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth /* The flag indicating if libsldap is in the 'Standalone' mode. */
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth int standalone;
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth /*
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth * The mutex ensuring that only one thread performs
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth * the initialization of the list.
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth */
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth mutex_t listReplaceLock;
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth /*
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth * A flag indicating that a particular thread is
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth * in the 'ldap_cachemgr' mode. It is stored by thread as
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth * a thread specific data.
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth */
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth const int initFlag;
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth /*
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth * A thread specific key storing
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth * the the 'ldap_cachemgr' mode indicator.
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth */
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth thread_key_t standaloneInitKey;
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth} dir_servers = {NULL, 0, DEFAULTMUTEX, '1'};
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57ethtypedef struct switchDatabase {
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth char *conf;
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth uint32_t alloced;
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth} switch_database_t;
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57ethstatic thread_key_t switchConfigKey;
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth#pragma init(createStandaloneKey)
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth#define DONT_INCLUDE_ATTR_NAMES 0
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth#define INCLUDE_ATTR_NAMES 1
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth#define IS_PROFILE 1
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth#define NOT_PROFILE 0
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth/* INET6_ADDRSTRLEN + ":" + <5-digit port> + some round-up */
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth#define MAX_HOSTADDR_LEN (INET6_ADDRSTRLEN + 6 + 12)
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57ethstatic
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57ethvoid
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57ethswitch_conf_disposer(void *data)
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth{
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth switch_database_t *localData = (switch_database_t *)data;
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth free(localData->conf);
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth free(localData);
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth}
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth/*
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth * This function initializes an indication that a thread obtaining a root DSE
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth * will be switched to the 'ldap_cachemgr' mode. Within the thread libsldap
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth * will not invoke the __s_api_requestServer function. Instead, the library
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth * will establish a connection to the server specified by
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth * the __ns_ldap_getRootDSE function.
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth * Since ldap_cachmgr can obtain a DUAProfile and root DSEs at the same time
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth * and we do not want to affect a thread obtaining a DUAProfile,
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth * the 'ldap_cachemgr' mode is thread private.
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth * In addition, this function creates a key holding temporary configuration
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth * for the "hosts" and "ipnodes" databases which is used by the "SKIPDB"
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth * mechanism (__s_api_ip2hostname() & _s_api_hostname2ip()).
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth */
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57ethstatic
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57ethvoid
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57ethcreateStandaloneKey()
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth{
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth if (thr_keycreate(&dir_servers.standaloneInitKey, NULL) != 0) {
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth syslog(LOG_ERR, gettext("libsldap: unable to create a thread "
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth "key needed for sharing ldap connections"));
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth }
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth if (thr_keycreate(&switchConfigKey, switch_conf_disposer) != 0) {
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth syslog(LOG_ERR, gettext("libsldap: unable to create a thread "
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth "key containing current nsswitch configuration"));
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth }
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth}
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth/*
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth * This function sets the 'ldap_cachemgr' mode indication.
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth */
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57ethvoid
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth__s_api_setInitMode()
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth{
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth (void) thr_setspecific(dir_servers.standaloneInitKey,
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth (void *) &dir_servers.initFlag);
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth}
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth/*
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth * This function unset the 'ldap_cachemgr' mode indication.
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth */
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57ethvoid
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth__s_api_unsetInitMode()
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth{
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth (void) thr_setspecific(dir_servers.standaloneInitKey, NULL);
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth}
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth/*
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth * This function checks if the 'ldap_cachemgr' mode indication is set.
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth */
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57ethint
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth__s_api_isInitializing() {
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth int *flag = NULL;
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth (void) thr_getspecific(dir_servers.standaloneInitKey, (void **) &flag);
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth return (flag != NULL && *flag == dir_servers.initFlag);
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth}
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth/*
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth * This function checks if the process runs in the 'Standalone' mode.
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth * In this mode libsldap will check the local, process private list of root DSEs
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth * instead of requesting them via a door call to ldap_cachemgr.
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth */
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57ethint
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth__s_api_isStandalone()
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth{
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth int mode;
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth (void) mutex_lock(&dir_servers.listReplaceLock);
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth mode = dir_servers.standalone;
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth (void) mutex_unlock(&dir_servers.listReplaceLock);
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth return (mode);
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth}
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57ethstatic
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57ethint
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57ethremove_ldap(char *dst, char *src, int dst_buf_len)
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth{
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth int i = 0;
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth if (strlen(src) >= dst_buf_len)
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth return (0);
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth while (*src != '\0') {
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth /* Copy up to one space from source. */
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth if (isspace(*src)) {
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth dst[i++] = *src;
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth while (isspace(*src))
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth src++;
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth }
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth /* If not "ldap", just copy. */
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth if (strncmp(src, "ldap", 4) != 0) {
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth while (!isspace(*src)) {
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth dst[i++] = *src++;
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth /* At the end of string? */
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth if (dst[i-1] == '\0')
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth return (1);
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth }
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth /* Copy up to one space from source. */
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth if (isspace(*src)) {
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth dst[i++] = *src;
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth while (isspace(*src))
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth src++;
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth }
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth /* Copy also the criteria section */
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth if (*src == '[')
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth while (*src != ']') {
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth dst[i++] = *src++;
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth /* Shouln't happen if format is right */
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth if (dst[i-1] == '\0')
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth return (1);
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth }
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth }
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth /* If next part is ldap, skip over it ... */
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth if (strncmp(src, "ldap", 4) == 0) {
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth if (isspace(*(src+4)) || *(src+4) == '\0') {
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth src += 4;
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth while (isspace(*src))
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth src++;
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth if (*src == '[') {
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth while (*src++ != ']') {
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth /*
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth * See comment above about
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth * correct format.
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth */
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth if (*src == '\0') {
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth dst[i++] = '\0';
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth return (1);
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth }
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth }
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth }
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth while (isspace(*src))
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth src++;
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth }
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth }
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth if (*src == '\0')
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth dst[i++] = '\0';
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth }
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth return (1);
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth}
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57ethstatic
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57ethchar *
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57ethget_db(const char *db_name)
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth{
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth char *ptr;
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth switch_database_t *hostService = NULL;
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth FILE *fp = fopen(__NSW_CONFIG_FILE, "rF");
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth char *linep, line[NSS_BUFSIZ];
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth if (fp == NULL) {
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth syslog(LOG_WARNING, gettext("libsldap: can not read %s"),
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth __NSW_CONFIG_FILE);
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth return (NULL);
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth }
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth while ((linep = fgets(line, NSS_BUFSIZ, fp)) != NULL) {
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth while (isspace(*linep)) {
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth ++linep;
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth }
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth if (*linep == '#') {
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth continue;
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth }
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth if (strncmp(linep, db_name, strlen(db_name)) != 0) {
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth continue;
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth }
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth if ((linep = strchr(linep, ':')) != NULL) {
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth if (linep[strlen(linep) - 1] == '\n') {
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth linep[strlen(linep) - 1] = '\0';
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth }
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth while (isspace(*++linep))
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth ;
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth if ((ptr = strchr(linep, '#')) != NULL) {
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth while (--ptr >= linep && isspace(*ptr))
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth ;
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth *(ptr + 1) = '\0';
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth }
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth if (strlen(linep) == 0) {
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth continue;
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth }
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth break;
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth }
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth }
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth (void) fclose(fp);
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth if (linep == NULL) {
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth syslog(LOG_WARNING,
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth gettext("libsldap: the %s database "
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth "is missing from %s"),
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth db_name,
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth __NSW_CONFIG_FILE);
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth return (NULL);
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth }
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth (void) thr_getspecific(switchConfigKey, (void **) &hostService);
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth if (hostService == NULL) {
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth hostService = calloc(1, sizeof (switch_database_t));
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth if (hostService == NULL) {
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth return (NULL);
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth }
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth (void) thr_setspecific(switchConfigKey, hostService);
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth }
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth /*
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth * In a long-living process threads can perform several
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth * getXbyY requests. And the windows between those requests
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth * can be long. The nsswitch configuration can change from time
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth * to time. So instead of allocating/freeing memory every time
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth * the API is called, reallocate memory only when the current
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth * configuration for the database being used is longer than
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth * the previous one.
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth */
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth if (strlen(linep) >= hostService->alloced) {
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth ptr = (char *)realloc((void *)hostService->conf,
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth strlen(linep) + 1);
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth if (ptr == NULL) {
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth free((void *)hostService->conf);
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth hostService->conf = NULL;
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth hostService->alloced = 0;
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth return (NULL);
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth }
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth bzero(ptr, strlen(linep) + 1);
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth hostService->conf = ptr;
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth hostService->alloced = strlen(linep) + 1;
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth }
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth if (remove_ldap(hostService->conf, linep, hostService->alloced))
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth return (hostService->conf);
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth else
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth return (NULL);
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth}
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57ethstatic
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57ethvoid
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth_initf_ipnodes(nss_db_params_t *p)
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth{
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth char *services = get_db("ipnodes");
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth p->name = NSS_DBNAM_IPNODES;
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth p->flags |= NSS_USE_DEFAULT_CONFIG;
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth p->default_config = services == NULL ? "" : services;
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth}
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57ethstatic
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57ethvoid
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth_initf_hosts(nss_db_params_t *p)
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth{
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth char *services = get_db("hosts");
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth p->name = NSS_DBNAM_HOSTS;
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth p->flags |= NSS_USE_DEFAULT_CONFIG;
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth p->default_config = services == NULL ? "" : services;
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth}
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth/*
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth * This function is an analog of the standard gethostbyaddr_r()
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth * function with an exception that it removes the 'ldap' back-end
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth * (if any) from the host/ipnodes nsswitch's databases and then
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth * looks up using remaining back-ends.
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth */
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57ethstatic
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57ethstruct hostent *
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth_filter_gethostbyaddr_r(const char *addr, int len, int type,
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth struct hostent *result, char *buffer, int buflen,
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth int *h_errnop)
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth{
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth DEFINE_NSS_DB_ROOT(db_root_hosts);
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth DEFINE_NSS_DB_ROOT(db_root_ipnodes);
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth nss_XbyY_args_t arg;
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth nss_status_t res;
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth int (*str2ent)();
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth void (*nss_initf)();
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth nss_db_root_t *nss_db_root;
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth int dbop;
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth switch (type) {
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth case AF_INET:
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth str2ent = str2hostent;
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth nss_initf = _initf_hosts;
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth nss_db_root = &db_root_hosts;
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth dbop = NSS_DBOP_HOSTS_BYADDR;
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth break;
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth case AF_INET6:
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth str2ent = str2hostent6;
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth nss_initf = _initf_ipnodes;
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth nss_db_root = &db_root_ipnodes;
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth dbop = NSS_DBOP_IPNODES_BYADDR;
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth default:
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth return (NULL);
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth }
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth NSS_XbyY_INIT(&arg, result, buffer, buflen, str2ent);
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth arg.key.hostaddr.addr = addr;
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth arg.key.hostaddr.len = len;
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth arg.key.hostaddr.type = type;
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth arg.stayopen = 0;
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth arg.h_errno = NETDB_SUCCESS;
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth res = nss_search(nss_db_root, nss_initf, dbop, &arg);
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth arg.status = res;
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth *h_errnop = arg.h_errno;
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth return (struct hostent *)NSS_XbyY_FINI(&arg);
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth}
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth/*
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth * This routine is an analog of gethostbyaddr_r().
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth * But in addition __s_api_hostname2ip() performs the "LDAP SKIPDB" activity
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth * prior to querying the name services.
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth * If the buffer is not big enough to accommodate a returning data,
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth * NULL is returned and h_errnop is set to TRY_AGAIN.
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth */
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57ethstruct hostent *
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth__s_api_hostname2ip(const char *name,
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth struct hostent *result, char *buffer, int buflen,
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth int *h_errnop)
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth{
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth DEFINE_NSS_DB_ROOT(db_root_ipnodes);
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth DEFINE_NSS_DB_ROOT(db_root_hosts);
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth nss_XbyY_args_t arg;
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth nss_status_t res;
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth struct in_addr addr;
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth struct in6_addr addr6;
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth if (inet_pton(AF_INET, name, &addr) > 0) {
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth if (buflen < strlen(name) + 1 +
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth sizeof (char *) * 2 + /* The h_aliases member */
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth sizeof (struct in_addr) +
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth sizeof (struct in_addr *) * 2) {
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth *h_errnop = TRY_AGAIN;
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth return (NULL);
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth }
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth result->h_addrtype = AF_INET;
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth result->h_length = sizeof (struct in_addr);
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth (void) strncpy(buffer, name, buflen);
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth result->h_addr_list = (char **)ROUND_UP(
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth buffer + strlen(name) + 1,
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth sizeof (char *));
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth result->h_aliases = (char **)ROUND_UP(result->h_addr_list,
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth sizeof (char *));
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth result->h_aliases[0] = buffer;
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth result->h_aliases[1] = NULL;
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth bcopy(&addr,
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth buffer + buflen - sizeof (struct in_addr),
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth sizeof (struct in_addr));
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth result->h_addr_list[0] = buffer + buflen -
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth sizeof (struct in_addr);
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth result->h_addr_list[1] = NULL;
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth result->h_aliases = result->h_addr_list;
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth result->h_name = buffer;
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth *h_errnop = NETDB_SUCCESS;
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth return (result);
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth }
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth if (inet_pton(AF_INET6, name, &addr6) > 0) {
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth if (buflen < strlen(name) + 1 +
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth sizeof (char *) * 2 + /* The h_aliases member */
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth sizeof (struct in6_addr) +
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth sizeof (struct in6_addr *) * 2) {
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth *h_errnop = TRY_AGAIN;
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth return (NULL);
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth }
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth result->h_addrtype = AF_INET6;
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth result->h_length = sizeof (struct in6_addr);
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth (void) strncpy(buffer, name, buflen);
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth result->h_addr_list = (char **)ROUND_UP(
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth buffer + strlen(name) + 1,
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth sizeof (char *));
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth result->h_aliases = (char **)ROUND_UP(result->h_addr_list,
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth sizeof (char *));
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth result->h_aliases[0] = buffer;
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth result->h_aliases[1] = NULL;
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth bcopy(&addr6,
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth buffer + buflen - sizeof (struct in6_addr),
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth sizeof (struct in6_addr));
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth result->h_addr_list[0] = buffer + buflen -
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth sizeof (struct in6_addr);
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth result->h_addr_list[1] = NULL;
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth result->h_aliases = result->h_addr_list;
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth result->h_name = buffer;
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth *h_errnop = NETDB_SUCCESS;
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth return (result);
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth }
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth NSS_XbyY_INIT(&arg, result, buffer, buflen, str2hostent);
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth arg.key.name = name;
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth arg.stayopen = 0;
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth arg.h_errno = NETDB_SUCCESS;
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth res = nss_search(&db_root_ipnodes, _initf_ipnodes,
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth NSS_DBOP_IPNODES_BYNAME, &arg);
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth if (res == NSS_NOTFOUND || res == NSS_UNAVAIL) {
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth arg.h_errno = NETDB_SUCCESS;
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth res = nss_search(&db_root_hosts, _initf_hosts,
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth NSS_DBOP_HOSTS_BYNAME, &arg);
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth }
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth arg.status = res;
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth *h_errnop = arg.h_errno;
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth return ((struct hostent *)NSS_XbyY_FINI(&arg));
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth}
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth/*
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth * Convert an IP to a host name.
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth */
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57ethns_ldap_return_code
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth__s_api_ip2hostname(char *ipaddr, char **hostname) {
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth struct in_addr in;
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth struct in6_addr in6;
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth struct hostent *hp = NULL, hostEnt;
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth char buffer[NSS_BUFLEN_HOSTS];
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth int buflen = NSS_BUFLEN_HOSTS;
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth char *start = NULL,
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth *end = NULL,
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth delim = '\0';
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth char *port = NULL,
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth *addr = NULL;
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth int errorNum = 0,
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth len = 0;
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth if (ipaddr == NULL || hostname == NULL)
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth return (NS_LDAP_INVALID_PARAM);
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth *hostname = NULL;
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth if ((addr = strdup(ipaddr)) == NULL)
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth return (NS_LDAP_MEMORY);
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth if (addr[0] == '[') {
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth /*
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth * Assume it's [ipv6]:port
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth * Extract ipv6 IP
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth */
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth start = &addr[1];
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth if ((end = strchr(addr, ']')) != NULL) {
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth *end = '\0';
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth delim = ']';
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth if (*(end + 1) == ':')
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth /* extract port */
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth port = end + 2;
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth } else {
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth free(addr);
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth return (NS_LDAP_INVALID_PARAM);
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth }
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth } else if ((end = strchr(addr, ':')) != NULL) {
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth /* assume it's ipv4:port */
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth *end = '\0';
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth delim = ':';
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth start = addr;
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth port = end + 1;
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth } else
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth /* No port */
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth start = addr;
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth if (inet_pton(AF_INET, start, &in) == 1) {
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth /* IPv4 */
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth hp = _filter_gethostbyaddr_r((char *)&in,
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth sizeof (in.s_addr),
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth AF_INET,
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth &hostEnt,
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth buffer,
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth buflen,
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth &errorNum);
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth if (hp && hp->h_name) {
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth /* hostname + '\0' */
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth len = strlen(hp->h_name) + 1;
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth if (port)
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth /* ':' + port */
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth len += strlen(port) + 1;
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth if ((*hostname = malloc(len)) == NULL) {
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth free(addr);
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth return (NS_LDAP_MEMORY);
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth }
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth if (port)
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth (void) snprintf(*hostname, len, "%s:%s",
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth hp->h_name, port);
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth else
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth (void) strlcpy(*hostname, hp->h_name, len);
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth free(addr);
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth return (NS_LDAP_SUCCESS);
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth } else {
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth free(addr);
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth return (NS_LDAP_NOTFOUND);
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth }
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth } else if (inet_pton(AF_INET6, start, &in6) == 1) {
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth /* IPv6 */
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth hp = _filter_gethostbyaddr_r((char *)&in6,
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth sizeof (in6.s6_addr),
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth AF_INET6,
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth &hostEnt,
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth buffer,
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth buflen,
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth &errorNum);
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth if (hp && hp->h_name) {
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth /* hostname + '\0' */
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth len = strlen(hp->h_name) + 1;
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth if (port)
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth /* ':' + port */
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth len += strlen(port) + 1;
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth if ((*hostname = malloc(len)) == NULL) {
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth free(addr);
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth return (NS_LDAP_MEMORY);
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth }
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth if (port)
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth (void) snprintf(*hostname, len, "%s:%s",
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth hp->h_name, port);
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth else
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth (void) strlcpy(*hostname, hp->h_name, len);
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth free(addr);
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth return (NS_LDAP_SUCCESS);
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth } else {
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth free(addr);
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth return (NS_LDAP_NOTFOUND);
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth }
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth } else {
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth /*
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth * A hostname
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth * Return it as is
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth */
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth if (end)
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth *end = delim;
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth *hostname = addr;
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth return (NS_LDAP_SUCCESS);
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth }
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth}
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth/*
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth * This function obtains data returned by an LDAP search request and puts it
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth * in a string in the ldap_cachmgr(1) door call format.
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth *
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth * INPUT:
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth * ld - a pointer to an LDAP structure used for a search operation,
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth * result_msg - a pointer to an LDAPMessage returned by the search,
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth * include_names - if set to INCLUDE_ATTR_NAMES, the output buffer will
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth * contain attribute names.
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth * Otherwise, only values will be return.
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth *
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth * OUTPUT:
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth * a buffer containing server info in the following format:
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth * [<attribute name>=]value [DOORLINESEP [<attribute name>=]value ]...]
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth * Should be free'ed by the caller.
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth */
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57ethstatic
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57ethns_ldap_return_code
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57ethconvert_to_door_line(LDAP* ld,
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth LDAPMessage *result_msg,
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth int include_names,
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth int is_profile,
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth char **door_line)
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth{
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth uint32_t total_length = 0, attr_len = 0, i;
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth LDAPMessage *e;
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth char *a, **vals;
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth BerElement *ber;
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth int seen_objectclass = 0, rewind = 0;
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth if (!door_line) {
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth return (NS_LDAP_INVALID_PARAM);
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth }
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth *door_line = NULL;
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth if ((e = ldap_first_entry(ld, result_msg)) == NULL) {
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth return (NS_LDAP_NOTFOUND);
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth }
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth /* calculate length of received data */
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth for (a = ldap_first_attribute(ld, e, &ber);
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth a != NULL;
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth a = ldap_next_attribute(ld, e, ber)) {
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth if ((vals = ldap_get_values(ld, e, a)) != NULL) {
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth for (i = 0; vals[i] != NULL; i++) {
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth total_length += (include_names ?
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth strlen(a) : 0) +
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth strlen(vals[i]) +
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth strlen(DOORLINESEP) +1;
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth }
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth ldap_value_free(vals);
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth }
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth ldap_memfree(a);
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth }
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth if (ber != NULL) {
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth ber_free(ber, 0);
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth }
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth if (total_length == 0) {
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth return (NS_LDAP_NOTFOUND);
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth }
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth /* copy the data */
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth /* add 1 for the last '\0' */
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth *door_line = (char *)malloc(total_length + 1);
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth if (*door_line == NULL) {
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth return (NS_LDAP_MEMORY);
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth }
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth /* make it an empty string first */
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth **door_line = '\0';
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth a = ldap_first_attribute(ld, e, &ber);
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth while (a != NULL) {
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth if (is_profile) {
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth /*
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth * If we're processing DUAConfigProfile, we need to make
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth * sure we put objectclass attribute first.
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth * __s_api_create_config_door_str depends on that.
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth */
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth if (seen_objectclass) {
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth if (strcasecmp(a, "objectclass") == 0) {
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth /* Skip objectclass now. */
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth a = ldap_next_attribute(ld, e, ber);
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth continue;
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth }
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth } else {
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth if (strcasecmp(a, "objectclass") == 0) {
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth seen_objectclass = 1;
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth rewind = 1;
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth } else {
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth /* Skip all but objectclass first. */
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth a = ldap_next_attribute(ld, e, ber);
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth continue;
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth }
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth }
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth }
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth if ((vals = ldap_get_values(ld, e, a)) != NULL) {
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth for (i = 0; vals[i] != NULL; i++) {
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth if (include_names) {
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth attr_len += strlen(a);
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth }
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth attr_len += strlen(vals[i]) +
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth strlen(DOORLINESEP) + 2;
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth if (include_names) {
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth (void) snprintf(*door_line +
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth strlen(*door_line),
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth attr_len,
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth "%s=%s%s",
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth a, vals[i],
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth DOORLINESEP);
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth } else {
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth (void) snprintf(*door_line +
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth strlen(*door_line),
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth attr_len,
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth "%s%s",
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth vals[i],
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth DOORLINESEP);
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth }
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth }
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth ldap_value_free(vals);
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth }
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth ldap_memfree(a);
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth /* Rewind */
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth if (rewind) {
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth if (ber != NULL) {
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth ber_free(ber, 0);
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth }
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth a = ldap_first_attribute(ld, e, &ber);
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth rewind = 0;
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth } else {
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth a = ldap_next_attribute(ld, e, ber);
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth }
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth }
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth if (ber != NULL) {
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth ber_free(ber, 0);
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth }
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth if (e != result_msg) {
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth (void) ldap_msgfree(e);
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth }
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth return (NS_LDAP_SUCCESS);
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth}
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth/*
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth * This function looks up the base DN of a directory serving
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth * a specified domain name.
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth *
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth * INPUT:
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth * ld - a pointer to an LDAP structure used for the search operation,
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth * domain_name - the name of a domain.
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth *
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth * OUTPUT:
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth * a buffer containing a directory's base DN found.
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth * Should be free'ed by the caller.
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth */
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57ethstatic
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57ethns_ldap_return_code
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57ethgetDirBaseDN(LDAP *ld, const char *domain_name, char **dir_base_dn)
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth{
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth struct timeval tv = {NS_DEFAULT_SEARCH_TIMEOUT, 0};
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth char *attrs[2], *DNlist, *rest, *ptr;
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth char filter[BUFSIZ], *a = NULL;
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth int ldap_rc;
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth LDAPMessage *resultMsg = NULL;
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth ns_ldap_return_code ret_code;
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth /* Get the whole list of naming contexts residing on the server */
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth attrs[0] = "namingcontexts";
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth attrs[1] = NULL;
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth ldap_rc = ldap_search_ext_s(ld, "", LDAP_SCOPE_BASE, "(objectclass=*)",
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth attrs, 0, NULL, NULL, &tv, 0, &resultMsg);
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth switch (ldap_rc) {
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth /* If successful, the root DSE was found. */
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth case LDAP_SUCCESS:
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth break;
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth /*
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth * If the root DSE was not found, the server does
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth * not comply with the LDAP v3 protocol.
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth */
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth default:
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth if (resultMsg) {
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth (void) ldap_msgfree(resultMsg);
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth resultMsg = NULL;
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth }
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth return (NS_LDAP_OP_FAILED);
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth }
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth if ((ret_code = convert_to_door_line(ld,
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth resultMsg,
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth DONT_INCLUDE_ATTR_NAMES,
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth NOT_PROFILE,
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth &DNlist)) != NS_LDAP_SUCCESS) {
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth if (resultMsg) {
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth (void) ldap_msgfree(resultMsg);
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth resultMsg = NULL;
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth }
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth return (ret_code);
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth }
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth if (resultMsg) {
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth (void) ldap_msgfree(resultMsg);
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth resultMsg = NULL;
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth }
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth if (DNlist == NULL ||
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth (ptr = strtok_r(DNlist, DOORLINESEP, &rest)) == NULL) {
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth return (NS_LDAP_NOTFOUND);
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth }
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth attrs[0] = "dn";
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth do {
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth /*
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth * For each context try to find a NIS domain object
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth * which 'nisdomain' attribute's value matches the domain name
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth */
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth (void) snprintf(filter,
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth BUFSIZ,
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth "(&(objectclass=nisDomainObject)"
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth "(nisdomain=%s))",
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth domain_name);
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth ldap_rc = ldap_search_ext_s(ld,
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth ptr,
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth LDAP_SCOPE_SUBTREE,
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth filter,
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth attrs,
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth 0,
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth NULL,
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth NULL,
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth &tv,
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth 0,
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth &resultMsg);
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth if (ldap_rc != LDAP_SUCCESS) {
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth if (resultMsg) {
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth (void) ldap_msgfree(resultMsg);
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth resultMsg = NULL;
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth }
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth continue;
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth }
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth if ((a = ldap_get_dn(ld, resultMsg)) != NULL) {
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth *dir_base_dn = strdup(a);
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth ldap_memfree(a);
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth if (resultMsg) {
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth (void) ldap_msgfree(resultMsg);
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth resultMsg = NULL;
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth }
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth if (!*dir_base_dn) {
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth free(DNlist);
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth return (NS_LDAP_MEMORY);
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth }
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth break;
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth }
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth if (resultMsg) {
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth (void) ldap_msgfree(resultMsg);
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth resultMsg = NULL;
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth }
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth } while (ptr = strtok_r(NULL, DOORLINESEP, &rest));
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth free(DNlist);
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth if (!*dir_base_dn) {
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth return (NS_LDAP_NOTFOUND);
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth }
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth return (NS_LDAP_SUCCESS);
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth}
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth/*
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth * This function parses the results of a search operation
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth * requesting a DUAProfile.
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth *
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth * INPUT:
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth * ld - a pointer to an LDAP structure used for the search operation,
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth * dir_base_dn - the name of a directory's base DN,
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth * profile_name - the name of a DUAProfile to be obtained.
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth *
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth * OUTPUT:
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth * a buffer containing the DUAProfile in the following format:
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth * [<attribute name>=]value [DOORLINESEP [<attribute name>=]value ]...]
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth * Should be free'ed by the caller.
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth */
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57ethstatic
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57ethns_ldap_return_code
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57ethgetDUAProfile(LDAP *ld,
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth const char *dir_base_dn,
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth const char *profile_name,
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth char **profile)
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth{
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth char searchBaseDN[BUFSIZ], filter[BUFSIZ];
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth LDAPMessage *resultMsg = NULL;
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth struct timeval tv = {NS_DEFAULT_SEARCH_TIMEOUT, 0};
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth int ldap_rc;
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth ns_ldap_return_code ret_code;
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth (void) snprintf(searchBaseDN, BUFSIZ, "ou=profile,%s", dir_base_dn);
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth (void) snprintf(filter,
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth BUFSIZ,
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth _PROFILE_FILTER,
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth _PROFILE1_OBJECTCLASS,
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth _PROFILE2_OBJECTCLASS,
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth profile_name);
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth ldap_rc = ldap_search_ext_s(ld,
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth searchBaseDN,
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth LDAP_SCOPE_SUBTREE,
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth filter,
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth NULL,
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth 0,
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth NULL,
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth NULL,
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth &tv,
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth 0,
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth &resultMsg);
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth switch (ldap_rc) {
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth /* If successful, the DUA profile was found. */
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth case LDAP_SUCCESS:
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth break;
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth /*
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth * If the root DSE was not found, the server does
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth * not comply with the LDAP v3 protocol.
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth */
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth default:
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth if (resultMsg) {
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth (void) ldap_msgfree(resultMsg);
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth resultMsg = NULL;
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth }
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth return (NS_LDAP_OP_FAILED);
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth }
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth ret_code = convert_to_door_line(ld,
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth resultMsg,
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth INCLUDE_ATTR_NAMES,
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth IS_PROFILE,
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth profile);
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth if (resultMsg) {
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth (void) ldap_msgfree(resultMsg);
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth resultMsg = NULL;
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth }
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth return (ret_code);
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth}
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth/*
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth * This function derives the directory's base DN from a provided domain name.
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth *
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth * INPUT:
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth * domain_name - the name of a domain to be converted into a base DN,
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth * buffer - contains the derived base DN,
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth * buf_len - the length of the buffer.
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth *
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth * OUTPUT:
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth * The function returns the address of the buffer or NULL.
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth */
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57ethstatic
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57ethchar *
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57ethdomainname2baseDN(char *domain_name, char *buffer, uint16_t buf_len)
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth{
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth char *nextDC, *chr;
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth uint16_t i, length;
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth if (!domain_name || !buffer || buf_len == 0) {
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth return (NULL);
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth }
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth buffer[0] = '\0';
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth nextDC = chr = domain_name;
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth length = strlen(domain_name);
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth for (i = 0; i < length + 1; ++i, ++chr) {
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth /* Simply replace dots with "dc=" */
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth if (*chr != '.' && *chr != '\0') {
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth continue;
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth }
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth *chr = '\0';
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth if (strlcat(buffer, "dc=", buf_len) >= buf_len)
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth return (NULL);
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth if (strlcat(buffer, nextDC, buf_len) >= buf_len)
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth return (NULL);
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth if (i < length) {
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth /*
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth * The end of the domain name
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth * has not been reached yet
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth */
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth if (strlcat(buffer, ",", buf_len) >= buf_len)
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth return (NULL);
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth nextDC = chr + 1;
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth *chr = '.';
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth }
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth }
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth return (buffer);
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth}
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth/*
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth * This function obtains the directory's base DN and a DUAProfile
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth * from a specified server.
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth *
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth * INPUT:
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth * server - a structure describing a server to connect to and
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth * a DUAProfile to be obtained from the server,
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth * cred - credentials to be used during establishing connections to
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth * the server.
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth *
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth * OUTPUT:
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth * dua_profile - a buffer containing the DUAProfile in the following format:
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth * [<attribute name>=]value [DOORLINESEP [<attribute name>=]value ]...]
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth * dir_base_dn - a buffer containing the base DN,
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth * errorp - an error object describing an error, if any.
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth *
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth * All the output data structures should be free'ed by the caller.
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth */
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57ethns_ldap_return_code
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth__ns_ldap_getConnectionInfoFromDUA(const ns_dir_server_t *server,
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth const ns_cred_t *cred,
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth char **dua_profile,
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth char **dir_base_dn,
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth ns_ldap_error_t **errorp)
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth{
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth char serverAddr[MAX_HOSTADDR_LEN];
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth char *dirBaseDN = NULL, *duaProfile = NULL;
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth ns_cred_t default_cred;
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth ns_ldap_return_code ret_code;
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth ns_config_t *config_struct = __s_api_create_config();
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth ConnectionID sessionId = 0;
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth Connection *session = NULL;
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth char errmsg[MAXERROR];
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth char buffer[NSS_BUFLEN_HOSTS];
29836b1990ff03408750301a4ad20cfd233444b9michen ns_conn_user_t *cu = NULL;
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth if (errorp == NULL) {
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth __s_api_destroy_config(config_struct);
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth return (NS_LDAP_INVALID_PARAM);
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth }
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth *errorp = NULL;
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth if (server == NULL) {
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth __s_api_destroy_config(config_struct);
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth return (NS_LDAP_INVALID_PARAM);
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth }
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth if (config_struct == NULL) {
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth return (NS_LDAP_MEMORY);
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth }
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth /*
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth * If no credentials are specified, try to establish a connection
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth * as anonymous.
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth */
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth if (!cred) {
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth default_cred.cred.unix_cred.passwd = NULL;
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth default_cred.cred.unix_cred.userID = NULL;
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth default_cred.auth.type = NS_LDAP_AUTH_NONE;
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth }
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth /* Now create a default LDAP configuration */
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth (void) strncpy(buffer, server->server, sizeof (buffer));
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth if (__ns_ldap_setParamValue(config_struct, NS_LDAP_SERVERS_P, buffer,
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth errorp) != NS_LDAP_SUCCESS) {
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth __s_api_destroy_config(config_struct);
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth return (NS_LDAP_CONFIG);
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth }
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth /* Put together the address and the port specified by the user app. */
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth if (server->port > 0) {
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth (void) snprintf(serverAddr,
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth sizeof (serverAddr),
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth "%s:%hu",
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth buffer,
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth server->port);
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth } else {
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth (void) strncpy(serverAddr, buffer, sizeof (serverAddr));
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth }
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth /*
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth * There is no default value for the 'Default Search Base DN' attribute.
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth * Derive one from the domain name to make __s_api_crosscheck() happy.
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth */
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth if (domainname2baseDN(server->domainName ?
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth server->domainName : config_struct->domainName,
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth buffer, NSS_BUFLEN_HOSTS) == NULL) {
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth (void) snprintf(errmsg,
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth sizeof (errmsg),
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth gettext("Can not convert %s into a base DN name"),
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth server->domainName ?
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth server->domainName : config_struct->domainName);
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth MKERROR(LOG_ERR,
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth *errorp,
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth NS_LDAP_INTERNAL,
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth strdup(errmsg),
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth NS_LDAP_MEMORY);
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth __s_api_destroy_config(config_struct);
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth return (NS_LDAP_INTERNAL);
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth }
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth if (__ns_ldap_setParamValue(config_struct, NS_LDAP_SEARCH_BASEDN_P,
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth buffer, errorp) != NS_LDAP_SUCCESS) {
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth __s_api_destroy_config(config_struct);
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth return (NS_LDAP_CONFIG);
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth }
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth if (__s_api_crosscheck(config_struct, errmsg, B_FALSE) != NS_SUCCESS) {
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth __s_api_destroy_config(config_struct);
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth return (NS_LDAP_CONFIG);
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth }
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth __s_api_init_config(config_struct);
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth __s_api_setInitMode();
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth
29836b1990ff03408750301a4ad20cfd233444b9michen cu = __s_api_conn_user_init(NS_CONN_USER_SEARCH, NULL, B_FALSE);
29836b1990ff03408750301a4ad20cfd233444b9michen if (cu == NULL) {
29836b1990ff03408750301a4ad20cfd233444b9michen return (NS_LDAP_INTERNAL);
29836b1990ff03408750301a4ad20cfd233444b9michen }
29836b1990ff03408750301a4ad20cfd233444b9michen
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth if ((ret_code = __s_api_getConnection(serverAddr,
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth NS_LDAP_NEW_CONN,
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth cred ? cred : &default_cred,
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth &sessionId,
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth &session,
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth errorp,
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth 0,
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth 0,
29836b1990ff03408750301a4ad20cfd233444b9michen cu)) != NS_LDAP_SUCCESS) {
29836b1990ff03408750301a4ad20cfd233444b9michen __s_api_conn_user_free(cu);
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth __s_api_unsetInitMode();
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth return (ret_code);
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth }
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth __s_api_unsetInitMode();
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth if ((ret_code = getDirBaseDN(session->ld,
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth server->domainName ?
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth server->domainName :
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth config_struct->domainName,
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth &dirBaseDN)) != NS_LDAP_SUCCESS) {
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth (void) snprintf(errmsg,
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth sizeof (errmsg),
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth gettext("Can not find the "
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth "nisDomainObject for domain %s\n"),
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth server->domainName ?
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth server->domainName : config_struct->domainName);
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth MKERROR(LOG_ERR,
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth *errorp,
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth ret_code,
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth strdup(errmsg),
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth NS_LDAP_MEMORY);
29836b1990ff03408750301a4ad20cfd233444b9michen __s_api_conn_user_free(cu);
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth DropConnection(sessionId, NS_LDAP_NEW_CONN);
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth return (ret_code);
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth }
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth /*
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth * And here obtain a DUAProfile which will be used
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth * as a real configuration.
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth */
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth if ((ret_code = getDUAProfile(session->ld,
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth dirBaseDN,
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth server->profileName ?
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth server->profileName : "default",
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth &duaProfile)) != NS_LDAP_SUCCESS) {
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth (void) snprintf(errmsg,
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth sizeof (errmsg),
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth gettext("Can not find the "
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth "%s DUAProfile\n"),
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth server->profileName ?
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth server->profileName : "default");
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth MKERROR(LOG_ERR,
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth *errorp,
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth ret_code,
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth strdup(errmsg),
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth NS_LDAP_MEMORY);
29836b1990ff03408750301a4ad20cfd233444b9michen __s_api_conn_user_free(cu);
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth DropConnection(sessionId, NS_LDAP_NEW_CONN);
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth return (ret_code);
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth }
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth if (dir_base_dn) {
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth *dir_base_dn = dirBaseDN;
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth } else {
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth free(dirBaseDN);
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth }
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth if (dua_profile) {
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth *dua_profile = duaProfile;
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth } else {
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth free(duaProfile);
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth }
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth
29836b1990ff03408750301a4ad20cfd233444b9michen __s_api_conn_user_free(cu);
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth DropConnection(sessionId, NS_LDAP_NEW_CONN);
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth return (NS_LDAP_SUCCESS);
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth}
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth/*
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth * This function obtains the root DSE from a specified server.
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth *
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth * INPUT:
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth * server_addr - an adress of a server to be connected to.
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth *
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth * OUTPUT:
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth * root_dse - a buffer containing the root DSE in the following format:
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth * [<attribute name>=]value [DOORLINESEP [<attribute name>=]value ]...]
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth * For example: ( here | used as DOORLINESEP for visual purposes)
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth * supportedControl=1.1.1.1|supportedSASLmechanisms=EXTERNAL
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth * Should be free'ed by the caller.
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth */
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57ethns_ldap_return_code
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth__ns_ldap_getRootDSE(const char *server_addr,
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth char **root_dse,
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth ns_ldap_error_t **errorp,
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth int anon_fallback)
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth{
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth char errmsg[MAXERROR];
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth ns_ldap_return_code ret_code;
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth ConnectionID sessionId = 0;
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth Connection *session = NULL;
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth struct timeval tv = {NS_DEFAULT_SEARCH_TIMEOUT, 0};
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth char *attrs[3];
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth int ldap_rc, ldaperrno = 0;
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth LDAPMessage *resultMsg = NULL;
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth void **paramVal = NULL;
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth ns_cred_t anon;
29836b1990ff03408750301a4ad20cfd233444b9michen ns_conn_user_t *cu = NULL;
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth if (errorp == NULL) {
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth return (NS_LDAP_INVALID_PARAM);
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth }
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth *errorp = NULL;
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth if (!root_dse) {
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth return (NS_LDAP_INVALID_PARAM);
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth }
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth if (!server_addr) {
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth return (NS_LDAP_INVALID_PARAM);
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth }
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth __s_api_setInitMode();
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth
29836b1990ff03408750301a4ad20cfd233444b9michen cu = __s_api_conn_user_init(NS_CONN_USER_SEARCH, NULL, B_FALSE);
29836b1990ff03408750301a4ad20cfd233444b9michen if (cu == NULL) {
29836b1990ff03408750301a4ad20cfd233444b9michen return (NS_LDAP_INTERNAL);
29836b1990ff03408750301a4ad20cfd233444b9michen }
29836b1990ff03408750301a4ad20cfd233444b9michen
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth /*
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth * All the credentials will be taken from the current
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth * libsldap configuration.
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth */
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth if ((ret_code = __s_api_getConnection(server_addr,
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth NS_LDAP_NEW_CONN,
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth NULL,
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth &sessionId,
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth &session,
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth errorp,
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth 0,
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth 0,
29836b1990ff03408750301a4ad20cfd233444b9michen cu)) != NS_LDAP_SUCCESS) {
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth /* Fallback to anonymous mode is disabled. Stop. */
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth if (anon_fallback == 0) {
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth syslog(LOG_WARNING,
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth gettext("libsldap: can not get the root DSE from "
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth " the %s server: %s. "
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth "Falling back to anonymous disabled.\n"),
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth server_addr,
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth errorp && *errorp && (*errorp)->message ?
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth (*errorp)->message : "");
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth if (errorp != NULL && *errorp != NULL) {
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth (void) __ns_ldap_freeError(errorp);
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth }
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth __s_api_unsetInitMode();
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth return (ret_code);
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth }
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth /*
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth * Fallback to anonymous, non-SSL mode for backward
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth * compatibility reasons. This mode should only be used when
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth * this function (__ns_ldap_getRootDSE) is called from
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth * ldap_cachemgr(1M).
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth */
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth syslog(LOG_WARNING,
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth gettext("libsldap: Falling back to anonymous, non-SSL"
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth " mode for __ns_ldap_getRootDSE. %s\n"),
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth errorp && *errorp && (*errorp)->message ?
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth (*errorp)->message : "");
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth /* Setup the anon credential for anonymous connection. */
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth (void) memset(&anon, 0, sizeof (ns_cred_t));
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth anon.auth.type = NS_LDAP_AUTH_NONE;
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth if (*errorp != NULL) {
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth (void) __ns_ldap_freeError(errorp);
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth }
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth *errorp = NULL;
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth ret_code = __s_api_getConnection(server_addr,
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth NS_LDAP_NEW_CONN,
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth &anon,
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth &sessionId,
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth &session,
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth errorp,
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth 0,
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth 0,
29836b1990ff03408750301a4ad20cfd233444b9michen cu);
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth if (ret_code != NS_LDAP_SUCCESS) {
29836b1990ff03408750301a4ad20cfd233444b9michen __s_api_conn_user_free(cu);
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth __s_api_unsetInitMode();
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth return (ret_code);
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth }
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth }
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth __s_api_unsetInitMode();
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth /* get search timeout value */
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth (void) __ns_ldap_getParam(NS_LDAP_SEARCH_TIME_P, &paramVal, errorp);
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth if (paramVal != NULL && *paramVal != NULL) {
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth tv.tv_sec = **((int **)paramVal);
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth (void) __ns_ldap_freeParam(&paramVal);
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth }
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth if (*errorp != NULL) {
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth (void) __ns_ldap_freeError(errorp);
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth }
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth /* Get root DSE from the server specified by the caller. */
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth attrs[0] = "supportedControl";
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth attrs[1] = "supportedsaslmechanisms";
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth attrs[2] = NULL;
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth ldap_rc = ldap_search_ext_s(session->ld,
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth "",
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth LDAP_SCOPE_BASE,
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth "(objectclass=*)",
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth attrs,
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth 0,
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth NULL,
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth NULL,
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth &tv,
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth 0,
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth &resultMsg);
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth if (ldap_rc != LDAP_SUCCESS) {
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth /*
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth * If the root DSE was not found, the server does
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth * not comply with the LDAP v3 protocol.
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth */
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth (void) ldap_get_option(session->ld,
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth LDAP_OPT_ERROR_NUMBER,
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth &ldaperrno);
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth (void) snprintf(errmsg,
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth sizeof (errmsg),
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth gettext(ldap_err2string(ldaperrno)));
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth MKERROR(LOG_ERR,
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth *errorp,
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth NS_LDAP_OP_FAILED,
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth strdup(errmsg),
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth NS_LDAP_MEMORY);
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth if (resultMsg) {
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth (void) ldap_msgfree(resultMsg);
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth resultMsg = NULL;
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth }
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth
29836b1990ff03408750301a4ad20cfd233444b9michen __s_api_conn_user_free(cu);
b3b48d8e61fb04617f1a22d673c555b155f02e64Hans Rosenfeld DropConnection(sessionId, NS_LDAP_NEW_CONN);
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth return (NS_LDAP_OP_FAILED);
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth }
29836b1990ff03408750301a4ad20cfd233444b9michen __s_api_conn_user_free(cu);
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth ret_code = convert_to_door_line(session->ld,
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth resultMsg,
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth INCLUDE_ATTR_NAMES,
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth NOT_PROFILE,
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth root_dse);
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth if (ret_code == NS_LDAP_NOTFOUND) {
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth (void) snprintf(errmsg,
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth sizeof (errmsg),
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth gettext("No root DSE data "
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth "for server %s returned."),
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth server_addr);
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth MKERROR(LOG_ERR,
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth *errorp,
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth NS_LDAP_NOTFOUND,
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth strdup(errmsg),
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth NS_LDAP_MEMORY);
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth }
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth if (resultMsg) {
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth (void) ldap_msgfree(resultMsg);
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth resultMsg = NULL;
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth }
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth DropConnection(sessionId, NS_LDAP_NEW_CONN);
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth return (ret_code);
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth}
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth/*
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth * This function destroys the local list of root DSEs. The input parameter is
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth * a pointer to the list to be erased.
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth * The type of the pointer passed to this function should be
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth * (dir_server_list_t *).
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth */
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57ethstatic
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57ethvoid *
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57ethdisposeOfOldList(void *param)
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth{
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth dir_server_list_t *old_list = (dir_server_list_t *)param;
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth long i = 0, j;
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth (void) rw_wrlock(&old_list->listDestroyLock);
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth /* Destroy the old list */
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth while (old_list->nsServers[i]) {
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth free(old_list->nsServers[i]->ip);
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth j = 0;
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth while (old_list->nsServers[i]->controls &&
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth old_list->nsServers[i]->controls[j]) {
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth free(old_list->nsServers[i]->controls[j]);
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth ++j;
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth }
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth free(old_list->nsServers[i]->controls);
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth j = 0;
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth while (old_list->nsServers[i]->saslMech &&
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth old_list->nsServers[i]->saslMech[j]) {
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth free(old_list->nsServers[i]->saslMech[j]);
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth ++j;
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth }
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth free(old_list->nsServers[i]->saslMech);
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth ++i;
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth }
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth /*
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth * All the structures pointed by old_list->nsServers were allocated
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth * in one chunck. The nsServers[0] pointer points to the beginning
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth * of that chunck.
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth */
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth free(old_list->nsServers[0]);
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth free(old_list->nsServers);
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth (void) rw_unlock(&old_list->listDestroyLock);
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth (void) rwlock_destroy(&old_list->listDestroyLock);
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth free(old_list);
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth return (NULL);
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth}
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth/*
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth * This function cancels the Standalone mode and destroys the list of root DSEs.
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth */
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57ethvoid
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth__ns_ldap_cancelStandalone(void)
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth{
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth dir_server_list_t *old_list;
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth (void) mutex_lock(&dir_servers.listReplaceLock);
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth dir_servers.standalone = 0;
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth if (!dir_servers.list) {
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth (void) mutex_unlock(&dir_servers.listReplaceLock);
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth return;
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth }
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth old_list = dir_servers.list;
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth dir_servers.list = NULL;
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth (void) mutex_unlock(&dir_servers.listReplaceLock);
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth (void) disposeOfOldList(old_list);
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth}
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57ethstatic
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57ethvoid*
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57ethcreate_ns_servers_entry(void *param)
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth{
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth#define CHUNK_SIZE 16
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth dir_server_t *server = (dir_server_t *)param;
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth ns_ldap_return_code *retCode = calloc(1,
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth sizeof (ns_ldap_return_code));
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth uint32_t sc_counter = 0, sm_counter = 0;
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth uint32_t sc_mem_blocks = 1, sm_mem_blocks = 1;
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth char *rootDSE = NULL, *attr, *val, *rest, **ptr;
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth ns_ldap_error_t *error = NULL;
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth if (retCode == NULL) {
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth return (NULL);
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth }
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth /*
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth * We call this function in non anon-fallback mode because we
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth * want the whole procedure to fail as soon as possible to
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth * indicate there are problems with connecting to the server.
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth */
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth *retCode = __ns_ldap_getRootDSE(server->ip,
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth &rootDSE,
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth &error,
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth SA_ALLOW_FALLBACK);
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth if (*retCode == NS_LDAP_MEMORY) {
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth free(retCode);
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth return (NULL);
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth }
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth /*
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth * If the root DSE can not be obtained, log an error and keep the
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth * server.
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth */
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth if (*retCode != NS_LDAP_SUCCESS) {
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth server->status = INFO_SERVER_ERROR;
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth syslog(LOG_WARNING,
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth gettext("libsldap (\"standalone\" mode): "
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth "can not obtain the root DSE from %s. %s"),
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth server->ip,
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth error && error->message ? error->message : "");
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth if (error) {
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth (void) __ns_ldap_freeError(&error);
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth }
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth return (retCode);
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth }
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth /* Get the first attribute of the root DSE. */
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth attr = strtok_r(rootDSE, DOORLINESEP, &rest);
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth if (attr == NULL) {
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth free(rootDSE);
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth server->status = INFO_SERVER_ERROR;
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth syslog(LOG_WARNING,
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth gettext("libsldap (\"standalone\" mode): "
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth "the root DSE from %s is empty or corrupted."),
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth server->ip);
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth *retCode = NS_LDAP_INTERNAL;
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth return (retCode);
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth }
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth server->controls = (char **)calloc(CHUNK_SIZE, sizeof (char *));
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth server->saslMech = (char **)calloc(CHUNK_SIZE, sizeof (char *));
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth if (server->controls == NULL || server->saslMech == NULL) {
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth free(rootDSE);
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth free(retCode);
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth return (NULL);
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth }
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth do {
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth if ((val = strchr(attr, '=')) == NULL) {
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth continue;
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth }
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth ++val;
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth if (strncasecmp(attr,
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth _SASLMECHANISM,
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth _SASLMECHANISM_LEN) == 0) {
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth if (sm_counter == CHUNK_SIZE * sm_mem_blocks - 1) {
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth ptr = (char **)realloc(server->saslMech,
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth CHUNK_SIZE *
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth ++sm_mem_blocks *
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth sizeof (char *));
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth if (ptr == NULL) {
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth *retCode = NS_LDAP_MEMORY;
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth break;
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth }
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth bzero((char *)ptr +
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth (sm_counter + 1) *
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth sizeof (char *),
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth CHUNK_SIZE *
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth sm_mem_blocks *
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth sizeof (char *) -
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth (sm_counter + 1) *
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth sizeof (char *));
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth server->saslMech = ptr;
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth }
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth server->saslMech[sm_counter] = strdup(val);
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth if (server->saslMech[sm_counter] == NULL) {
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth *retCode = NS_LDAP_MEMORY;
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth break;
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth }
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth ++sm_counter;
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth continue;
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth }
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth if (strncasecmp(attr,
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth _SUPPORTEDCONTROL,
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth _SUPPORTEDCONTROL_LEN) == 0) {
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth if (sc_counter == CHUNK_SIZE * sc_mem_blocks - 1) {
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth ptr = (char **)realloc(server->controls,
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth CHUNK_SIZE *
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth ++sc_mem_blocks *
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth sizeof (char *));
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth if (ptr == NULL) {
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth *retCode = NS_LDAP_MEMORY;
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth break;
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth }
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth bzero((char *)ptr +
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth (sc_counter + 1) *
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth sizeof (char *),
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth CHUNK_SIZE *
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth sc_mem_blocks *
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth sizeof (char *) -
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth (sc_counter + 1) *
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth sizeof (char *));
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth server->controls = ptr;
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth }
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth server->controls[sc_counter] = strdup(val);
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth if (server->controls[sc_counter] == NULL) {
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth *retCode = NS_LDAP_MEMORY;
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth break;
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth }
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth ++sc_counter;
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth continue;
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth }
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth } while (attr = strtok_r(NULL, DOORLINESEP, &rest));
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth free(rootDSE);
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth if (*retCode == NS_LDAP_MEMORY) {
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth free(retCode);
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth return (NULL);
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth }
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth server->controls[sc_counter] = NULL;
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth server->saslMech[sm_counter] = NULL;
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth server->status = INFO_SERVER_UP;
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth return (retCode);
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth#undef CHUNK_SIZE
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth}
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth/*
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth * This function creates a new local list of root DSEs from all the servers
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth * mentioned in the DUAProfile (or local NS BEC) and returns
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth * a pointer to the list.
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth */
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57ethstatic
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57ethns_ldap_return_code
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57ethcreateDirServerList(dir_server_list_t **new_list,
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth ns_ldap_error_t **errorp)
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth{
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth char **serverList;
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth ns_ldap_return_code retCode = NS_LDAP_SUCCESS;
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth dir_server_t *tmpSrvArray;
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth long srvListLength, i;
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth thread_t *thrPool, thrID;
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth void *status = NULL;
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth if (errorp == NULL) {
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth return (NS_LDAP_INVALID_PARAM);
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth }
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth *errorp = NULL;
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth if (new_list == NULL) {
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth return (NS_LDAP_INVALID_PARAM);
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth }
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth retCode = __s_api_getServers(&serverList, errorp);
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth if (retCode != NS_LDAP_SUCCESS || serverList == NULL) {
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth return (retCode);
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth }
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth for (i = 0; serverList[i]; ++i) {
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth ;
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth }
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth srvListLength = i;
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth thrPool = calloc(srvListLength, sizeof (thread_t));
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth if (thrPool == NULL) {
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth __s_api_free2dArray(serverList);
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth return (NS_LDAP_MEMORY);
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth }
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth *new_list = (dir_server_list_t *)calloc(1,
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth sizeof (dir_server_list_t));
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth if (*new_list == NULL) {
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth __s_api_free2dArray(serverList);
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth free(thrPool);
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth return (NS_LDAP_MEMORY);
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth }
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth (void) rwlock_init(&(*new_list)->listDestroyLock, USYNC_THREAD, NULL);
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth (*new_list)->nsServers = (dir_server_t **)calloc(srvListLength + 1,
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth sizeof (dir_server_t *));
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth if ((*new_list)->nsServers == NULL) {
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth free(*new_list);
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth *new_list = NULL;
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth __s_api_free2dArray(serverList);
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth free(thrPool);
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth return (NS_LDAP_MEMORY);
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth }
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth /*
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth * Allocate a set of dir_server_t structures as an array,
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth * with one alloc call and then initialize the nsServers pointers
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth * with the addresses of the array's members.
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth */
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth tmpSrvArray = (dir_server_t *)calloc(srvListLength,
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth sizeof (dir_server_t));
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth for (i = 0; i < srvListLength; ++i) {
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth (*new_list)->nsServers[i] = &tmpSrvArray[i];
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth (*new_list)->nsServers[i]->info = INFO_STATUS_NEW;
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth (void) mutex_init(&(*new_list)->nsServers[i]->updateStatus,
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth USYNC_THREAD,
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth NULL);
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth (*new_list)->nsServers[i]->ip = strdup(serverList[i]);
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth if ((*new_list)->nsServers[i]->ip == NULL) {
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth retCode = NS_LDAP_MEMORY;
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth break;
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth }
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth (*new_list)->nsServers[i]->status = INFO_SERVER_CONNECTING;
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth switch (thr_create(NULL,
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth 0,
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth create_ns_servers_entry,
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth (*new_list)->nsServers[i],
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth 0,
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth &thrID)) {
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth case EAGAIN:
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth (*new_list)->nsServers[i]->status =
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth INFO_SERVER_ERROR;
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth continue;
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth case ENOMEM:
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth (*new_list)->nsServers[i]->status =
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth INFO_SERVER_ERROR;
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth continue;
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth default:
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth thrPool[i] = thrID;
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth continue;
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth }
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth }
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth for (i = 0; i < srvListLength; ++i) {
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth if (thrPool[i] != 0 &&
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth thr_join(thrPool[i], NULL, &status) == 0) {
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth if (status == NULL) {
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth /*
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth * Some memory allocation problems occured. Just
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth * ignore the server and hope there will be some
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth * other good ones.
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth */
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth (*new_list)->nsServers[i]->status =
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth INFO_SERVER_ERROR;
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth }
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth free(status);
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth }
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth }
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth __s_api_free2dArray(serverList);
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth free(thrPool);
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth if (retCode == NS_LDAP_MEMORY) {
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth (void) disposeOfOldList(*new_list);
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth return (NS_LDAP_MEMORY);
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth }
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth return (NS_LDAP_SUCCESS);
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth}
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth/*
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth * This functions replaces the local list of root DSEs with a new one and starts
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth * a thread destroying the old list. There is no need for other threads to wait
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth * until the old list will be destroyed.
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth * Since it is possible that more than one thread can start creating the list,
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth * this function should be protected by mutexes to be sure that only one thread
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth * performs the initialization.
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth */
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57ethstatic
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57ethns_ldap_return_code
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57ethinitGlobalList(ns_ldap_error_t **error)
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth{
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth dir_server_list_t *new_list, *old_list;
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth ns_ldap_return_code ret_code;
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth thread_t tid;
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth ret_code = createDirServerList(&new_list, error);
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth if (ret_code != NS_LDAP_SUCCESS) {
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth return (ret_code);
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth }
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth old_list = dir_servers.list;
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth dir_servers.list = new_list;
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth if (old_list) {
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth (void) thr_create(NULL,
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth 0,
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth disposeOfOldList,
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth old_list,
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth THR_DETACHED,
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth &tid);
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth }
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth return (NS_LDAP_SUCCESS);
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth}
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57ethstatic
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57ethstruct {
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth char *authMech;
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth ns_auth_t auth;
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth} authArray[] = {{"none", {NS_LDAP_AUTH_NONE,
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth NS_LDAP_TLS_NONE,
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth NS_LDAP_SASL_NONE,
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth NS_LDAP_SASLOPT_NONE}},
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth {"simple", {NS_LDAP_AUTH_SIMPLE,
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth NS_LDAP_TLS_NONE,
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth NS_LDAP_SASL_NONE,
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth NS_LDAP_SASLOPT_NONE}},
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth {"tls:simple", {NS_LDAP_AUTH_TLS,
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth NS_LDAP_TLS_SIMPLE,
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth NS_LDAP_SASL_NONE,
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth NS_LDAP_SASLOPT_NONE}},
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth {"tls:sasl/CRAM-MD5", {NS_LDAP_AUTH_TLS,
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth NS_LDAP_TLS_SASL,
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth NS_LDAP_SASL_CRAM_MD5,
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth NS_LDAP_SASLOPT_NONE}},
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth {"tls:sasl/DIGEST-MD5", {NS_LDAP_AUTH_TLS,
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth NS_LDAP_TLS_SASL,
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth NS_LDAP_SASL_DIGEST_MD5,
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth NS_LDAP_SASLOPT_NONE}},
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth {"sasl/CRAM-MD5", {NS_LDAP_AUTH_SASL,
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth NS_LDAP_TLS_SASL,
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth NS_LDAP_SASL_CRAM_MD5,
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth NS_LDAP_SASLOPT_NONE}},
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth {"sasl/DIGEST-MD5", {NS_LDAP_AUTH_SASL,
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth NS_LDAP_TLS_SASL,
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth NS_LDAP_SASL_DIGEST_MD5,
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth NS_LDAP_SASLOPT_NONE}},
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth {"sasl/GSSAPI", {NS_LDAP_AUTH_SASL,
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth NS_LDAP_TLS_SASL,
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth NS_LDAP_SASL_GSSAPI,
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth NS_LDAP_SASLOPT_PRIV | NS_LDAP_SASLOPT_INT}},
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth {NULL, {NS_LDAP_AUTH_NONE,
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth NS_LDAP_TLS_NONE,
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth NS_LDAP_SASL_NONE,
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth NS_LDAP_SASLOPT_NONE}}};
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57ethns_ldap_return_code
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth__ns_ldap_initAuth(const char *auth_mech,
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth ns_auth_t *auth,
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth ns_ldap_error_t **errorp)
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth{
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth uint32_t i;
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth char errmsg[MAXERROR];
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth if (auth_mech == NULL) {
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth (void) snprintf(errmsg,
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth sizeof (errmsg),
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth gettext("Invalid authentication method specified\n"));
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth MKERROR(LOG_WARNING,
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth *errorp,
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth NS_LDAP_INTERNAL,
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth strdup(errmsg),
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth NS_LDAP_MEMORY);
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth return (NS_LDAP_INTERNAL);
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth }
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth for (i = 0; authArray[i].authMech != NULL; ++i) {
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth if (strcasecmp(auth_mech, authArray[i].authMech) == 0) {
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth *auth = authArray[i].auth;
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth return (NS_LDAP_SUCCESS);
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth }
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth }
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth (void) snprintf(errmsg,
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth sizeof (errmsg),
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth gettext("Invalid authentication method specified\n"));
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth MKERROR(LOG_WARNING,
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth *errorp,
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth NS_LDAP_INTERNAL,
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth strdup(errmsg),
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth NS_LDAP_MEMORY);
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth return (NS_LDAP_INTERNAL);
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth}
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth/*
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth * This function "informs" libsldap that a client application has specified
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth * a directory to use. The function obtains a DUAProfile, credentials,
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth * and naming context. During all further operations on behalf
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth * of the application requested a standalone schema libsldap will use
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth * the information obtained by __ns_ldap_initStandalone() instead of
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth * door_call(3C)ing ldap_cachemgr(1M).
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth *
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth * INPUT:
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth * sa_conf - a structure describing where and in which way to obtain all
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth * the configuration describing how to communicate to
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth * a choosen LDAP directory,
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth * errorp - an error object describing an error occured.
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth */
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57ethns_ldap_return_code
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth__ns_ldap_initStandalone(const ns_standalone_conf_t *sa_conf,
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth ns_ldap_error_t **errorp) {
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth ns_cred_t user_cred = {{NS_LDAP_AUTH_NONE,
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth NS_LDAP_TLS_NONE,
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth NS_LDAP_SASL_NONE,
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth NS_LDAP_SASLOPT_NONE},
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth NULL,
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth {NULL, NULL}};
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth char *dua_profile = NULL;
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth char errmsg[MAXERROR];
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth ns_config_t *cfg;
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth int ret_code;
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth if (sa_conf->SA_BIND_DN == NULL && sa_conf->SA_BIND_PWD != NULL ||
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth sa_conf->SA_BIND_DN != NULL && sa_conf->SA_BIND_PWD == NULL) {
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth (void) snprintf(errmsg,
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth sizeof (errmsg),
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth gettext("Bind DN and bind password"
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth " must both be provided\n"));
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth MKERROR(LOG_ERR,
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth *errorp,
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth NS_CONFIG_NOTLOADED,
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth strdup(errmsg),
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth NS_LDAP_MEMORY);
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth return (NS_LDAP_INTERNAL);
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth }
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth switch (sa_conf->type) {
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth case NS_LDAP_SERVER:
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth if (sa_conf->SA_BIND_DN != NULL) {
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth user_cred.cred.unix_cred.userID = sa_conf->SA_BIND_DN;
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth user_cred.auth.type = NS_LDAP_AUTH_SIMPLE;
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth }
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth if (sa_conf->SA_BIND_PWD != NULL) {
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth user_cred.cred.unix_cred.passwd = sa_conf->SA_BIND_PWD;
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth }
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth if (sa_conf->SA_AUTH != NULL) {
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth user_cred.auth.type = sa_conf->SA_AUTH->type;
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth user_cred.auth.tlstype = sa_conf->SA_AUTH->tlstype;
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth user_cred.auth.saslmech = sa_conf->SA_AUTH->saslmech;
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth user_cred.auth.saslopt = sa_conf->SA_AUTH->saslopt;
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth }
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth if (sa_conf->SA_CERT_PATH != NULL) {
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth user_cred.hostcertpath = sa_conf->SA_CERT_PATH;
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth }
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth ret_code = __ns_ldap_getConnectionInfoFromDUA(
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth &sa_conf->ds_profile.server,
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth &user_cred,
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth &dua_profile,
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth NULL,
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth errorp);
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth if (ret_code != NS_LDAP_SUCCESS) {
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth return (ret_code);
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth }
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth cfg = __s_api_create_config_door_str(dua_profile, errorp);
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth if (cfg == NULL) {
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth free(dua_profile);
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth return (NS_LDAP_CONFIG);
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth }
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth if (sa_conf->SA_CERT_PATH != NULL) {
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth char *certPathAttr;
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth ParamIndexType type;
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth switch (cfg->version) {
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth case NS_LDAP_V1:
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth certPathAttr = "NS_LDAP_CERT_PATH";
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth break;
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth default: /* Version 2 */
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth certPathAttr = "NS_LDAP_HOST_CERTPATH";
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth break;
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth }
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth if (__s_api_get_versiontype(cfg,
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth certPathAttr,
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth &type) == 0 &&
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth (ret_code = __ns_ldap_setParamValue(cfg,
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth type,
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth sa_conf->SA_CERT_PATH,
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth errorp)) != NS_LDAP_SUCCESS) {
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth __s_api_destroy_config(cfg);
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth return (ret_code);
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth }
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth }
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth if (sa_conf->SA_BIND_DN != NULL &&
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth sa_conf->SA_BIND_PWD != NULL) {
434c5a0685e933e08f535e85a50e4ba7e6816d38Milan Jurik char *authMethods;
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth
434c5a0685e933e08f535e85a50e4ba7e6816d38Milan Jurik authMethods = __s_api_strValue(cfg, NS_LDAP_AUTH_P,
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth NS_FILE_FMT);
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth if (authMethods != NULL &&
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth strstr(authMethods, "sasl/GSSAPI") != NULL) {
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth /*
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth * The received DUAProfile specifies
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth * sasl/GSSAPI as an auth. mechanism.
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth * The bind DN and password will be
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth * ignored.
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth */
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth syslog(LOG_INFO, gettext("sasl/GSSAPI will be "
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth "used as an authentication method. "
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth "The bind DN and password will "
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth "be ignored.\n"));
434c5a0685e933e08f535e85a50e4ba7e6816d38Milan Jurik free(authMethods);
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth break;
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth }
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth
434c5a0685e933e08f535e85a50e4ba7e6816d38Milan Jurik if (authMethods != NULL)
434c5a0685e933e08f535e85a50e4ba7e6816d38Milan Jurik free(authMethods);
434c5a0685e933e08f535e85a50e4ba7e6816d38Milan Jurik
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth if (__ns_ldap_setParamValue(cfg,
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth NS_LDAP_BINDDN_P,
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth sa_conf->SA_BIND_DN,
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth errorp) != NS_LDAP_SUCCESS) {
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth __s_api_destroy_config(cfg);
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth return (NS_LDAP_CONFIG);
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth }
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth if (__ns_ldap_setParamValue(cfg,
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth NS_LDAP_BINDPASSWD_P,
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth sa_conf->SA_BIND_PWD,
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth errorp) != NS_LDAP_SUCCESS) {
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth __s_api_destroy_config(cfg);
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth return (NS_LDAP_CONFIG);
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth }
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth }
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth break;
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth default: /* NS_CACHEMGR */
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth return (NS_LDAP_SUCCESS);
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth }
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth __s_api_init_config(cfg);
ca190d8debe6672d99069a376a987adee0765d6cmichen /* Connection management should use the new config now. */
ca190d8debe6672d99069a376a987adee0765d6cmichen __s_api_reinit_conn_mgmt_new_config(cfg);
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth __ns_ldap_setServer(TRUE);
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth (void) mutex_lock(&dir_servers.listReplaceLock);
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth if ((ret_code = initGlobalList(errorp)) != NS_SUCCESS) {
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth (void) mutex_unlock(&dir_servers.listReplaceLock);
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth return (ret_code);
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth }
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth dir_servers.standalone = 1;
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth (void) mutex_unlock(&dir_servers.listReplaceLock);
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth return (NS_LDAP_SUCCESS);
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth}
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth/*
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth * INPUT:
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth * serverAddr is the address of a server and
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth * request is one of the following:
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth * NS_CACHE_NEW: get a new server address, addr is ignored.
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth * NS_CACHE_NORESP: get the next one, remove addr from list.
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth * NS_CACHE_NEXT: get the next one, keep addr on list.
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth * NS_CACHE_WRITE: get a non-replica server, if possible, if not, same
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth * as NS_CACHE_NEXT.
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth * addrType:
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth * NS_CACHE_ADDR_IP: return server address as is, this is default.
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth * NS_CACHE_ADDR_HOSTNAME: return server addess as FQDN format, only
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth * self credential case requires such format.
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth * OUTPUT:
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth * ret
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth *
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth * a structure of type ns_server_info_t containing the server address
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth * or name, server controls and supported SASL mechanisms.
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth * NOTE: Caller should allocate space for the structure and free
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth * all the space allocated by the function for the information contained
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth * in the structure.
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth *
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth * error - an error object describing an error, if any.
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth */
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57ethns_ldap_return_code
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth__s_api_findRootDSE(const char *request,
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth const char *serverAddr,
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth const char *addrType,
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth ns_server_info_t *ret,
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth ns_ldap_error_t **error)
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth{
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth dir_server_list_t *current_list = NULL;
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth ns_ldap_return_code ret_code;
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth long i = 0;
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth int matched = FALSE;
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth dir_server_t *server = NULL;
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth char errmsg[MAXERROR];
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth (void) mutex_lock(&dir_servers.listReplaceLock);
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth if (dir_servers.list == NULL) {
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth (void) mutex_unlock(&dir_servers.listReplaceLock);
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth (void) snprintf(errmsg,
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth sizeof (errmsg),
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth gettext("The list of root DSEs is empty: "
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth "the Standalone mode was not properly initialized"));
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth MKERROR(LOG_ERR,
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth *error,
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth NS_CONFIG_NOTLOADED,
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth strdup(errmsg),
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth NS_LDAP_MEMORY);
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth return (NS_LDAP_INTERNAL);
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth }
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth current_list = dir_servers.list;
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth (void) rw_rdlock(&current_list->listDestroyLock);
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth (void) mutex_unlock(&dir_servers.listReplaceLock);
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth /*
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth * The code below is mostly the clone of the
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth * ldap_cachemgr::cachemgr_getldap.c::getldap_get_serverInfo() function.
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth * Currently we have two different server lists: one is maintained
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth * by libsldap ('standalone' mode), the other is in ldap_cachemgr
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth * (a part of its standard functionality).
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth */
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth /*
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth * If NS_CACHE_NEW, or the server info is new,
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth * starts from the beginning of the list.
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth */
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth (void) mutex_lock(&current_list->nsServers[0]->updateStatus);
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth if (strcmp(request, NS_CACHE_NEW) == 0 ||
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth current_list->nsServers[0]->info == INFO_STATUS_NEW) {
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth matched = TRUE;
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth }
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth (void) mutex_unlock(&current_list->nsServers[i]->updateStatus);
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth for (i = 0; current_list->nsServers[i]; ++i) {
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth /*
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth * Lock the updateStatus mutex to
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth * make sure the server status stays the same
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth * while the data is being processed.
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth */
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth if (matched == FALSE &&
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth strcmp(current_list->nsServers[i]->ip,
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth serverAddr) == 0) {
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth matched = TRUE;
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth if (strcmp(request, NS_CACHE_NORESP) == 0) {
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth /*
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth * if the server has already been removed,
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth * don't bother.
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth */
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth (void) mutex_lock(&current_list->
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth nsServers[i]->updateStatus);
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth if (current_list->nsServers[i]->status ==
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth INFO_SERVER_REMOVED) {
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth (void) mutex_unlock(&current_list->
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth nsServers[i]->
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth updateStatus);
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth continue;
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth }
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth (void) mutex_unlock(&current_list->
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth nsServers[i]->
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth updateStatus);
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth /*
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth * if the information is new,
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth * give this server one more chance.
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth */
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth (void) mutex_lock(&current_list->
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth nsServers[i]->
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth updateStatus);
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth if (current_list->nsServers[i]->info ==
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth INFO_STATUS_NEW &&
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth current_list->nsServers[i]->status ==
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth INFO_SERVER_UP) {
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth server = current_list->nsServers[i];
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth (void) mutex_unlock(&current_list->
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth nsServers[i]->
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth updateStatus);
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth break;
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth } else {
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth /*
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth * it is recommended that
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth * before removing the
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth * server from the list,
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth * the server should be
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth * contacted one more time
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth * to make sure that it is
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth * really unavailable.
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth * For now, just trust the client
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth * (i.e., the sldap library)
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth * that it knows what it is
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth * doing and would not try
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth * to mess up the server
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth * list.
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth */
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth current_list->nsServers[i]->status =
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth INFO_SERVER_REMOVED;
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth (void) mutex_unlock(&current_list->
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth nsServers[i]->
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth updateStatus);
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth continue;
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth }
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth } else {
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth /*
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth * req == NS_CACHE_NEXT or NS_CACHE_WRITE
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth */
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth continue;
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth }
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth }
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth if (matched) {
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth if (strcmp(request, NS_CACHE_WRITE) == 0) {
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth /*
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth * ldap_cachemgr checks here if the server
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth * is not a non-replica server (a server
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth * of type INFO_RW_WRITEABLE). But currently
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth * it considers all the servers in its list
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth * as those.
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth */
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth (void) mutex_lock(&current_list->
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth nsServers[i]->
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth updateStatus);
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth if (current_list->nsServers[i]->status ==
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth INFO_SERVER_UP) {
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth (void) mutex_unlock(&current_list->
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth nsServers[i]->
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth updateStatus);
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth server = current_list->nsServers[i];
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth break;
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth }
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth } else {
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth (void) mutex_lock(&current_list->
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth nsServers[i]->
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth updateStatus);
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth if (current_list->nsServers[i]->status ==
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth INFO_SERVER_UP) {
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth (void) mutex_unlock(&current_list->
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth nsServers[i]->
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth updateStatus);
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth server = current_list->nsServers[i];
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth break;
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth }
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth }
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth (void) mutex_unlock(&current_list->
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth nsServers[i]->
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth updateStatus);
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth }
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth }
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth if (server == NULL) {
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth (void) rw_unlock(&current_list->listDestroyLock);
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth (void) snprintf(errmsg,
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth sizeof (errmsg),
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth gettext("No servers are available"));
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth MKERROR(LOG_ERR,
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth *error,
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth NS_CONFIG_NOTLOADED,
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth strdup(errmsg),
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth NS_LDAP_MEMORY);
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth return (NS_LDAP_NOTFOUND);
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth }
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth (void) mutex_lock(&server->updateStatus);
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth server->info = INFO_STATUS_OLD;
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth (void) mutex_unlock(&server->updateStatus);
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth if (ret == NULL) {
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth (void) rw_unlock(&current_list->listDestroyLock);
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth return (NS_LDAP_SUCCESS);
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth }
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth if (strcmp(addrType, NS_CACHE_ADDR_HOSTNAME) == 0) {
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth ret_code = __s_api_ip2hostname(server->ip, &ret->serverFQDN);
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth if (ret_code != NS_LDAP_SUCCESS) {
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth (void) snprintf(errmsg,
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth sizeof (errmsg),
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth gettext("The %s address "
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth "can not be resolved into "
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth "a host name. Returning "
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth "the address as it is."),
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth server->ip);
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth MKERROR(LOG_ERR,
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth *error,
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth NS_CONFIG_NOTLOADED,
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth strdup(errmsg),
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth NS_LDAP_MEMORY);
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth return (NS_LDAP_INTERNAL);
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth }
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth }
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth ret->server = strdup(server->ip);
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth ret->controls = __s_api_cp2dArray(server->controls);
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth ret->saslMechanisms = __s_api_cp2dArray(server->saslMech);
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth (void) rw_unlock(&current_list->listDestroyLock);
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth return (NS_LDAP_SUCCESS);
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth}
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth/*
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth * This function iterates through the list of the configured LDAP servers
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth * and "pings" those which are marked as removed or if any error occurred
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth * during the previous receiving of the server's root DSE. If the
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth * function is able to reach such a server and get its root DSE, it
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth * marks the server as on-line. Otherwise, the server's status is set
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth * to "Error".
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth * For each server the function tries to connect to, it fires up
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth * a separate thread and then waits until all the treads finish.
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth * The function returns NS_LDAP_INTERNAL if the Standalone mode was not
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth * initialized or was canceled prior to an invocation of
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth * __ns_ldap_pingOfflineServers().
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth */
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57ethns_ldap_return_code
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth__ns_ldap_pingOfflineServers(void)
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth{
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth dir_server_list_t *current_list = NULL;
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth ns_ldap_return_code retCode = NS_LDAP_SUCCESS;
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth long srvListLength, i = 0;
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth thread_t *thrPool, thrID;
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth void *status = NULL;
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth (void) mutex_lock(&dir_servers.listReplaceLock);
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth if (dir_servers.list == NULL) {
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth (void) mutex_unlock(&dir_servers.listReplaceLock);
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth return (NS_LDAP_INTERNAL);
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth }
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth current_list = dir_servers.list;
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth (void) rw_wrlock(&current_list->listDestroyLock);
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth (void) mutex_unlock(&dir_servers.listReplaceLock);
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth while (current_list->nsServers[i] != NULL) {
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth ++i;
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth }
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth srvListLength = i;
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth thrPool = calloc(srvListLength, sizeof (thread_t));
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth if (thrPool == NULL) {
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth (void) rw_unlock(&current_list->listDestroyLock);
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth return (NS_LDAP_MEMORY);
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth }
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth for (i = 0; i < srvListLength; ++i) {
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth if (current_list->nsServers[i]->status != INFO_SERVER_REMOVED &&
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth current_list->nsServers[i]->status != INFO_SERVER_ERROR) {
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth continue;
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth }
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth current_list->nsServers[i]->status = INFO_SERVER_CONNECTING;
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth current_list->nsServers[i]->info = INFO_STATUS_NEW;
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth __s_api_free2dArray(current_list->nsServers[i]->controls);
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth current_list->nsServers[i]->controls = NULL;
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth __s_api_free2dArray(current_list->nsServers[i]->saslMech);
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth current_list->nsServers[i]->saslMech = NULL;
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth switch (thr_create(NULL,
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth 0,
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth create_ns_servers_entry,
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth current_list->nsServers[i],
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth 0,
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth &thrID)) {
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth case EAGAIN:
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth current_list->nsServers[i]->status = INFO_SERVER_ERROR;
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth continue;
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth case ENOMEM:
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth current_list->nsServers[i]->status = INFO_SERVER_ERROR;
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth retCode = NS_LDAP_MEMORY;
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth break;
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth default:
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth thrPool[i] = thrID;
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth continue;
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth }
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth /* A memory allocation error has occured */
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth break;
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth }
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth for (i = 0; i < srvListLength; ++i) {
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth if (thrPool[i] != 0 &&
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth thr_join(thrPool[i], NULL, &status) == 0) {
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth if (status == NULL) {
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth current_list->nsServers[i]->status =
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth INFO_SERVER_ERROR;
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth retCode = NS_LDAP_MEMORY;
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth }
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth free(status);
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth }
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth }
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth (void) rw_unlock(&current_list->listDestroyLock);
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth free(thrPool);
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth return (retCode);
e1dd0a2f3a26050d1f183c1cafae42c4e3a0b57eth}