1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown/*
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown * CDDL HEADER START
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown *
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown * The contents of this file are subject to the terms of the
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown * Common Development and Distribution License (the "License").
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown * You may not use this file except in compliance with the License.
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown *
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown * or http://www.opensolaris.org/os/licensing.
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown * See the License for the specific language governing permissions
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown * and limitations under the License.
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown *
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown * When distributing Covered Code, include this CDDL HEADER in each
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown * If applicable, add the following below this CDDL HEADER, with the
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown * fields enclosed by brackets "[]" replaced with your own identifying
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown * information: Portions Copyright [yyyy] [name of copyright owner]
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown *
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown * CDDL HEADER END
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown */
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown/*
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown * Use is subject to license terms.
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown */
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown/*
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown * Directory lookup functions. These are shims that translate from the API
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown * into the RPC protocol.
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown */
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown#include <assert.h>
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown#include <stdio.h>
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown#include <stdlib.h>
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown#include <stdarg.h>
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown#include <malloc.h>
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown#include <sys/types.h>
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown#include <netdb.h>
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown#include <pthread.h>
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown#include <unistd.h>
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown#include <string.h>
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown#include "directory.h"
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown#include "directory_private.h"
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown#include <rpcsvc/idmap_prot.h>
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown#include "directory_library_impl.h"
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown#include "sized_array.h"
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brownstatic directory_error_t copy_directory_attribute_value(
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown directory_attribute_value_t *dav,
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown directory_values_rpc *dav_rpc);
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brownstatic directory_error_t copy_directory_entry(directory_entry_t *ent,
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown directory_entry_rpc *ent_rpc);
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brownstatic void directory_results_free(directory_results_rpc *dr);
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brownstatic directory_datum_t directory_datum(void *data, size_t len);
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brownstatic void directory_datum_free(directory_datum_t d);
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown/*
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown * This is the actual implementation of the opaque directory_t structure.
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown */
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brownstruct directory {
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown CLIENT *client;
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown};
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown/*
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown * Set up a directory search context.
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown */
1fcced4c370617db71610fecffd5451a5894ca5eJordan Browndirectory_error_t
1fcced4c370617db71610fecffd5451a5894ca5eJordan Browndirectory_open(directory_t *ret)
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown{
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown directory_t d;
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown directory_error_t de;
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown char host[] = "localhost";
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown *ret = NULL;
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown d = calloc(1, sizeof (*d));
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown if (d == NULL)
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown goto nomem;
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown d->client = clnt_door_create(IDMAP_PROG, IDMAP_V1, 0);
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown if (d->client == NULL) {
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown de = directory_error("clnt_create.directory_open",
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown "Error: %1",
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown clnt_spcreateerror(host),
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown NULL);
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown goto err;
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown }
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown *ret = d;
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown return (NULL);
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brownnomem:
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown de = directory_error("ENOMEM.directory_open",
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown "Insufficient memory setting up directory access", NULL);
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brownerr:
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown directory_close(d);
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown return (de);
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown}
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown/*
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown * Tear down a directory search context.
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown *
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown * Does nothing if d==NULL.
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown */
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brownvoid
1fcced4c370617db71610fecffd5451a5894ca5eJordan Browndirectory_close(directory_t d)
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown{
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown if (d == NULL)
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown return;
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown if (d->client != NULL)
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown clnt_destroy(d->client);
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown free(d);
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown}
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown/*
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown * Given a list of identifiers, a list of their types, and a list of attributes,
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown * return the information.
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown */
1fcced4c370617db71610fecffd5451a5894ca5eJordan Browndirectory_error_t
1fcced4c370617db71610fecffd5451a5894ca5eJordan Browndirectory_get_v(
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown directory_t d,
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown directory_entry_list_t *ret,
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown char **ids,
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown int nids,
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown char *types,
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown char **attr_list)
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown{
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown int nattrs;
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown directory_entry_list_t del;
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown directory_error_t de;
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown directory_results_rpc dr;
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown idmap_utf8str_list sl_ids;
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown idmap_utf8str_list sl_attrs;
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown directory_entry_rpc *users;
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown int i;
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown enum clnt_stat cs;
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown *ret = NULL;
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown del = NULL;
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown if (nids == 0) {
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown for (nids = 0; ids[nids] != NULL; nids++)
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown /* LOOP */;
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown }
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown for (nattrs = 0; attr_list[nattrs] != NULL; nattrs++)
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown /* LOOP */;
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown sl_ids.idmap_utf8str_list_len = nids;
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown sl_ids.idmap_utf8str_list_val = ids;
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown sl_attrs.idmap_utf8str_list_len = nattrs;
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown sl_attrs.idmap_utf8str_list_val = attr_list;
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown (void) memset(&dr, 0, sizeof (dr));
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown cs = directory_get_common_1(sl_ids, types, sl_attrs, &dr, d->client);
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown if (cs != RPC_SUCCESS) {
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown char errbuf[100]; /* well long enough for any integer */
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown (void) sprintf(errbuf, "%d", cs);
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown de = directory_error("RPC.Get_common",
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown "Get_common RPC (%1)%2", errbuf,
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown clnt_sperror(d->client, ""), NULL);
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown goto err;
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown }
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown if (dr.failed) {
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown de = directory_error_from_rpc(
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown &dr.directory_results_rpc_u.err);
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown goto err;
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown }
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown assert(dr.directory_results_rpc_u.entries.entries_len == nids);
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown users = dr.directory_results_rpc_u.entries.entries_val;
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown del = sized_array(nids, sizeof (directory_entry_t));
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown for (i = 0; i < nids; i++) {
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown de = copy_directory_entry(&del[i], &users[i]);
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown if (de != NULL)
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown goto err;
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown }
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown directory_results_free(&dr);
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown *ret = del;
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown return (NULL);
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brownerr:
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown directory_results_free(&dr);
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown directory_free(del);
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown return (de);
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown}
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown/*
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown * Free the results from a directory_get_*() request.
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown */
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brownvoid
1fcced4c370617db71610fecffd5451a5894ca5eJordan Browndirectory_free(directory_entry_list_t del)
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown{
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown directory_entry_t *ent;
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown directory_attribute_value_t dav;
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown int i;
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown int j;
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown int k;
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown if (del == NULL)
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown return;
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown /* For each directory entry returned */
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown for (i = 0; i < sized_array_n(del); i++) {
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown ent = &del[i];
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown if (ent->attrs != NULL) {
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown /* For each attribute */
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown for (j = 0; j < sized_array_n(ent->attrs); j++) {
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown dav = ent->attrs[j];
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown if (dav != NULL) {
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown for (k = 0; k < sized_array_n(dav); k++)
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown directory_datum_free(dav[k]);
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown sized_array_free(dav);
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown }
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown }
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown sized_array_free(ent->attrs);
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown }
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown directory_error_free(ent->err);
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown }
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown sized_array_free(del);
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown}
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown/*
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown * Create a directory datum. Note that we allocate an extra byte and
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown * zero it, so that strings get null-terminated. Return NULL on error.
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown */
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brownstatic
1fcced4c370617db71610fecffd5451a5894ca5eJordan Browndirectory_datum_t
1fcced4c370617db71610fecffd5451a5894ca5eJordan Browndirectory_datum(void *data, size_t len)
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown{
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown void *p;
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown p = sized_array(len + 1, 1);
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown if (p == NULL)
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown return (NULL);
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown (void) memcpy(p, data, len);
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown *((char *)p + len) = '\0';
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown return (p);
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown}
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown/*
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown * Return the size of a directory_datum_t. Note that this does not include
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown * the terminating \0, so it represents the value as returned by LDAP.
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown */
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brownsize_t
1fcced4c370617db71610fecffd5451a5894ca5eJordan Browndirectory_datum_len(directory_datum_t d)
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown{
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown /*
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown * Deduct the terminal \0, so that binary data gets the
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown * expected length.
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown */
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown return (sized_array_n(d) - 1);
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown}
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brownstatic
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brownvoid
1fcced4c370617db71610fecffd5451a5894ca5eJordan Browndirectory_datum_free(directory_datum_t d)
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown{
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown sized_array_free(d);
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown}
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown/*
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown * Unmarshall an RPC directory entry into an API directory entry.
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown */
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brownstatic
1fcced4c370617db71610fecffd5451a5894ca5eJordan Browndirectory_error_t
1fcced4c370617db71610fecffd5451a5894ca5eJordan Browncopy_directory_entry(
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown directory_entry_t *ent,
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown directory_entry_rpc *ent_rpc)
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown{
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown int nattrs;
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown int i;
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown directory_error_t de;
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown /* If the entry wasn't found, leave the entry attrs and err NULL. */
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown if (ent_rpc->status == DIRECTORY_NOT_FOUND)
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown return (NULL);
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown if (ent_rpc->status == DIRECTORY_ERROR) {
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown ent->err = directory_error_from_rpc(
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown &ent_rpc->directory_entry_rpc_u.err);
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown return (NULL);
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown }
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown nattrs = ent_rpc->directory_entry_rpc_u.attrs.attrs_len;
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown ent->attrs = sized_array(nattrs, sizeof (directory_attribute_value_t));
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown if (ent->attrs == NULL) {
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown return (directory_error("ENOMEM.copy_directory_entry",
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown "Insufficient memory copying directory entry", NULL));
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown }
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown for (i = 0; i < nattrs; i++) {
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown de = copy_directory_attribute_value(&ent->attrs[i],
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown &ent_rpc->directory_entry_rpc_u.attrs.attrs_val[i]);
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown if (de != NULL)
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown return (de);
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown }
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown return (NULL);
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown}
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown/*
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown * Unmarshall an RPC directory attribute value into the API equivalent.
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown *
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown * Note that on error some entries may have been copied, and so
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown * the caller needs to clean up dav. This is normally not a problem
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown * since the caller will have called this function several times and
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown * will need to clean up the results from the other calls too.
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown */
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brownstatic
1fcced4c370617db71610fecffd5451a5894ca5eJordan Browndirectory_error_t
1fcced4c370617db71610fecffd5451a5894ca5eJordan Browncopy_directory_attribute_value(
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown directory_attribute_value_t *dav,
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown directory_values_rpc *dav_rpc)
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown{
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown int i;
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown int nvals;
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown directory_value_rpc *vals;
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown /* If it wasn't found, leave the corresponding entry NULL */
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown if (!dav_rpc->found)
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown return (NULL);
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown nvals = dav_rpc->directory_values_rpc_u.values.values_len;
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown *dav = sized_array(nvals + 1, sizeof (directory_datum_t));
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown if (*dav == NULL) {
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown return (directory_error("ENOMEM.copy_directory_attribute_value",
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown "Insufficient memory copying directory entry", NULL));
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown }
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown vals = dav_rpc->directory_values_rpc_u.values.values_val;
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown for (i = 0; i < nvals; i++) {
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown (*dav)[i] = directory_datum(vals[i].directory_value_rpc_val,
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown vals[i].directory_value_rpc_len);
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown if ((*dav)[i] == NULL) {
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown return (directory_error(
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown "ENOMEM.copy_directory_attribute_value",
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown "Insufficient memory copying directory entry",
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown NULL));
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown }
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown }
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown return (NULL);
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown}
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown/*
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown * Free the results of a directory RPC request.
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown */
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brownstatic
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brownvoid
1fcced4c370617db71610fecffd5451a5894ca5eJordan Browndirectory_results_free(directory_results_rpc *dr)
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown{
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown xdr_free(xdr_directory_results_rpc, (char *)&dr);
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown}