2N/A/*
2N/A * CDDL HEADER START
2N/A *
2N/A * The contents of this file are subject to the terms of the
2N/A * Common Development and Distribution License (the "License").
2N/A * You may not use this file except in compliance with the License.
2N/A *
2N/A * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
2N/A * or http://www.opensolaris.org/os/licensing.
2N/A * See the License for the specific language governing permissions
2N/A * and limitations under the License.
2N/A *
2N/A * When distributing Covered Code, include this CDDL HEADER in each
2N/A * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
2N/A * If applicable, add the following below this CDDL HEADER, with the
2N/A * fields enclosed by brackets "[]" replaced with your own identifying
2N/A * information: Portions Copyright [yyyy] [name of copyright owner]
2N/A *
2N/A * CDDL HEADER END
2N/A */
2N/A
2N/A/*
2N/A * Copyright (c) 2011, 2012, Oracle and/or its affiliates. All rights reserved.
2N/A */
2N/A
2N/A#include <stdio.h>
2N/A#include <stdlib.h>
2N/A#include <string.h>
2N/A#include <strings.h>
2N/A#include <synch.h>
2N/A#include <lber.h>
2N/A#include <ldap.h>
2N/A#include <nfs/fedfs.h>
2N/A#include "fedfs_impl.h"
2N/A#include <syslog.h>
2N/A
2N/A/*
2N/A * Return the number of fsn UUIDs provided in 'locations'.
2N/A * The caller should free this allocated memory with free_fsns().
2N/A *
2N/A * Return values: the number of FSNs in the array (may be zero),
2N/A * or -1 in the case of communications errors.
2N/A */
2N/Aint
2N/Alist_fsns(char *host, int port, char *nce, char ***locations)
2N/A{
2N/A LDAP *ld;
2N/A LDAPMessage *result, *e;
2N/A BerElement *ber;
2N/A struct berval **vals;
2N/A char *a;
2N/A char *attribs[2];
2N/A int n;
2N/A#ifdef DEBUG
2N/A int i;
2N/A#endif
2N/A char **entries;
2N/A
2N/A /* Sanity */
2N/A if (host == NULL || nce == NULL || locations == NULL)
2N/A return (-1);
2N/A
2N/A /*
2N/A * Connect and bind to the directory anonymously
2N/A */
2N/A ld = nsdb_connect(host, port, NULL, NULL);
2N/A if (ld == NULL) {
2N/A#ifdef DEBUG
2N/A perror("list_fsns");
2N/A#endif
2N/A return (-1);
2N/A }
2N/A
2N/A attribs[0] = "fedfsFsnUuid";
2N/A attribs[1] = NULL;
2N/A
2N/A n = 0;
2N/A entries = calloc(sizeof (char *), n + 1);
2N/A
2N/A /*
2N/A * Perform search for a select set of attributes from above
2N/A */
2N/A if (ldap_search_s(ld, nce, LDAP_SCOPE_SUBTREE,
2N/A NULL, attribs, 0, &result) != LDAP_SUCCESS) {
2N/A#ifdef DEBUG
2N/A fprintf(stderr,
2N/A "Warning: Unable to search the directory\n");
2N/A ldap_perror(ld, "ldap_search_s");
2N/A#endif
2N/A free(entries);
2N/A return (-1);
2N/A }
2N/A
2N/A /*
2N/A * For each entry collect attributes and values
2N/A */
2N/A for (e = ldap_first_entry(ld, result); e != NULL;
2N/A e = ldap_next_entry(ld, e)) {
2N/A
2N/A /* Walk FSL attributes */
2N/A for (a = ldap_first_attribute(ld, e, &ber);
2N/A a != NULL; a = ldap_next_attribute(ld, e, ber)) {
2N/A
2N/A#ifdef DEBUG
2N/A fprintf(stderr, "attribute %s\n", a);
2N/A#endif
2N/A vals = ldap_get_values_len(ld, e, a);
2N/A if (vals == NULL)
2N/A break;
2N/A
2N/A#ifdef DEBUG
2N/A for (i = 0; vals[i] != NULL; i++)
2N/A fprintf(stderr, "val %s: len %d\n",
2N/A vals[i]->bv_val, vals[i]->bv_len);
2N/A#endif
2N/A if ((strcasecmp("fedfsFsnUuid", a) == 0)) {
2N/A#ifdef DEBUG
2N/A fprintf(stderr, "fedfsFsnUuid is %s\n",
2N/A vals[0]->bv_val);
2N/A#endif
2N/A if (n > 0 && strcmp(entries[n - 1],
2N/A vals[0]->bv_val) == 0)
2N/A continue;
2N/A entries[n] =
2N/A strdup(vals[0]->bv_val);
2N/A n++;
2N/A entries = realloc(entries,
2N/A sizeof (char *) * (n + 1));
2N/A entries[n] = NULL;
2N/A }
2N/A
2N/A if (ber != NULL)
2N/A ber_free(ber, 0);
2N/A ldap_value_free_len(vals);
2N/A ldap_memfree(a);
2N/A }
2N/A
2N/A }
2N/A
2N/A (void) ldap_msgfree(result);
2N/A (void) ldap_unbind(ld);
2N/A
2N/A#ifdef DEBUG
2N/A for (i = 0; i < n; i++) {
2N/A fprintf(stderr, "list_fsns(): location %d: %s\n", i,
2N/A entries[i]);
2N/A }
2N/A#endif
2N/A
2N/A *locations = entries;
2N/A return (n);
2N/A}
2N/A
2N/A/*
2N/A * Free memory allocated by nsdb_lookup().
2N/A */
2N/Avoid
2N/Afree_fsns(int n, char **entries)
2N/A{
2N/A int i;
2N/A
2N/A if (n == 0 || entries == NULL)
2N/A return;
2N/A for (i = 0; i < n; i++)
2N/A free(entries[i]);
2N/A free(entries);
2N/A}