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