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/*
cb174861876aea6950a7ab4ce944aff84b1914cdjoyce mcintosh * Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved.
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown */
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown/*
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown * Server-side support for directory information lookup functions.
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown */
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown
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>
cb174861876aea6950a7ab4ce944aff84b1914cdjoyce mcintosh#include <libuutil.h>
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown#include <note.h>
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown#include "idmapd.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 "directory_server_impl.h"
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown#include "sized_array.h"
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown/*
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown * Here's a list of all of the modules that provide directory
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown * information. In the fullness of time this should probably be
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown * a plugin-able switch mechanism.
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown * Note that the list is in precedence order.
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown */
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brownextern struct directory_provider_static directory_provider_builtin;
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brownextern struct directory_provider_static directory_provider_nsswitch;
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brownextern struct directory_provider_static directory_provider_ad;
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brownstruct directory_provider_static *providers[] = {
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown &directory_provider_builtin,
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown &directory_provider_nsswitch,
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown &directory_provider_ad,
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown};
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown/*
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown * This is the entry point for all directory lookup service requests.
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown */
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brownbool_t
1fcced4c370617db71610fecffd5451a5894ca5eJordan Browndirectory_get_common_1_svc(
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown idmap_utf8str_list ids,
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown idmap_utf8str types,
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown idmap_utf8str_list attrs,
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown directory_results_rpc *result,
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown struct svc_req *req)
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown{
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown NOTE(ARGUNUSED(req))
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown int nids;
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown directory_entry_rpc *entries;
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown directory_error_t de;
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown int i;
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown nids = ids.idmap_utf8str_list_len;
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown entries = (directory_entry_rpc *)
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown calloc(nids, sizeof (directory_entry_rpc));
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown if (entries == NULL)
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown goto nomem;
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown result->directory_results_rpc_u.entries.entries_val = entries;
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown result->directory_results_rpc_u.entries.entries_len = nids;
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown result->failed = FALSE;
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown for (i = 0; i < nids; i++) {
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown if (strlen(ids.idmap_utf8str_list_val[i]) >
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown IDMAP_MAX_NAME_LEN) {
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown directory_entry_set_error(&entries[i],
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown directory_error("invalid_arg.id.too_long",
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown "Identifier too long", NULL));
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown }
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown }
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown
cb174861876aea6950a7ab4ce944aff84b1914cdjoyce mcintosh for (i = 0; i < UU_NELEM(providers); i++) {
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown de = providers[i]->get(entries, &ids, types,
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown &attrs);
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown if (de != NULL)
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown goto err;
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown }
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown return (TRUE);
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brownnomem:
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown de = directory_error("ENOMEM.get_common",
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown "Insufficient memory retrieving directory data", NULL);
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brownerr:
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown xdr_free(xdr_directory_results_rpc, (char *)result);
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown result->failed = TRUE;
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown return (
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown directory_error_to_rpc(&result->directory_results_rpc_u.err, de));
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown}
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown/*
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown * Split name into {domain, name}.
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown * Suggest allocating name and domain on the stack, same size as id,
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown * using variable length arrays.
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown */
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brownvoid
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brownsplit_name(char *name, char *domain, char *id)
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown{
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown char *p;
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown if ((p = strchr(id, '@')) != NULL) {
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown (void) strlcpy(name, id, p - id + 1);
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown (void) strcpy(domain, p + 1);
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown } else if ((p = strchr(id, '\\')) != NULL) {
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown (void) strcpy(name, p + 1);
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown (void) strlcpy(domain, id, p - id + 1);
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown } else {
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown (void) strcpy(name, id);
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown (void) strcpy(domain, "");
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown }
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown}
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown/*
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown * Given a list of strings, return a set of directory attribute values.
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown *
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown * Mark that the attribute was found.
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown *
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown * Note that the terminating \0 is *not* included in the result, because
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown * that's the way that strings come from LDAP.
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown * (Note also that the client side stuff adds in a terminating \0.)
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown *
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown * Note that on error the array may have been partially populated and will
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown * need to be cleaned up by the caller. This is normally not a problem
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown * because the caller will need to clean up several such arrays.
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown */
1fcced4c370617db71610fecffd5451a5894ca5eJordan Browndirectory_error_t
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brownstr_list_dav(directory_values_rpc *lvals, const char * const *str_list, int n)
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown{
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown directory_value_rpc *dav;
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown int i;
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown if (n == 0) {
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown for (n = 0; str_list[n] != NULL; n++)
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown /* LOOP */;
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown }
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown dav = calloc(n, sizeof (directory_value_rpc));
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown if (dav == NULL)
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown goto nomem;
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown lvals->directory_values_rpc_u.values.values_val = dav;
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown lvals->directory_values_rpc_u.values.values_len = n;
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown lvals->found = TRUE;
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown for (i = 0; i < n; i++) {
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown int len;
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown len = strlen(str_list[i]);
cb174861876aea6950a7ab4ce944aff84b1914cdjoyce mcintosh dav[i].directory_value_rpc_val = uu_memdup(str_list[i], len);
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown if (dav[i].directory_value_rpc_val == NULL)
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown goto nomem;
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown dav[i].directory_value_rpc_len = len;
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown }
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown return (NULL);
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brownnomem:
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown return (directory_error("ENOMEM.str_list_dav",
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown "Insufficient memory copying values"));
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown}
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown/*
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown * Given a list of unsigned integers, return a set of string directory
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown * attribute values.
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown *
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown * Mark that the attribute was found.
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown *
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown * Note that the terminating \0 is *not* included in the result, because
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown * that's the way that strings come from LDAP.
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown * (Note also that the client side stuff adds in a terminating \0.)
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown *
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown * Note that on error the array may have been partially populated and will
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown * need to be cleaned up by the caller. This is normally not a problem
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown * because the caller will need to clean up several such arrays.
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown */
1fcced4c370617db71610fecffd5451a5894ca5eJordan Browndirectory_error_t
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brownuint_list_dav(directory_values_rpc *lvals, const unsigned int *array, int n)
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown{
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown directory_value_rpc *dav;
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown int i;
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown dav = calloc(n, sizeof (directory_value_rpc));
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown if (dav == NULL)
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown goto nomem;
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown lvals->directory_values_rpc_u.values.values_val = dav;
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown lvals->directory_values_rpc_u.values.values_len = n;
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown lvals->found = TRUE;
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown for (i = 0; i < n; i++) {
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown char buf[100]; /* larger than any integer */
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown int len;
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown (void) snprintf(buf, sizeof (buf), "%u", array[i]);
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown len = strlen(buf);
cb174861876aea6950a7ab4ce944aff84b1914cdjoyce mcintosh dav[i].directory_value_rpc_val = uu_memdup(buf, len);
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown if (dav[i].directory_value_rpc_val == NULL)
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown goto nomem;
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown dav[i].directory_value_rpc_len = len;
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown }
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown return (NULL);
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brownnomem:
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown return (directory_error("ENOMEM.uint_list_dav",
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown "Insufficient memory copying values"));
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown}
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown/*
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown * Given a list of fixed-length binary chunks, return a set of binary
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown * directory attribute values.
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown *
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown * Mark that the attribute was found.
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown *
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown * Note that on error the array may have been partially populated and will
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown * need to be cleaned up by the caller. This is normally not a problem
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown * because the caller will need to clean up several such arrays.
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown */
1fcced4c370617db71610fecffd5451a5894ca5eJordan Browndirectory_error_t
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brownbin_list_dav(directory_values_rpc *lvals, const void *array, int n, size_t sz)
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown{
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown directory_value_rpc *dav;
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown char *inbuf = (char *)array;
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown int i;
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown dav = calloc(n, sizeof (directory_value_rpc));
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown if (dav == NULL)
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown goto nomem;
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown lvals->directory_values_rpc_u.values.values_val = dav;
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown lvals->directory_values_rpc_u.values.values_len = n;
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown lvals->found = TRUE;
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown for (i = 0; i < n; i++) {
cb174861876aea6950a7ab4ce944aff84b1914cdjoyce mcintosh dav[i].directory_value_rpc_val = uu_memdup(inbuf, sz);
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown if (dav[i].directory_value_rpc_val == NULL)
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown goto nomem;
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown dav[i].directory_value_rpc_len = sz;
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown inbuf += sz;
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown }
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown return (NULL);
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brownnomem:
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown return (directory_error("ENOMEM.bin_list_dav",
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown "Insufficient memory copying values"));
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown}
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown/*
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown * Set up to return an error on a particular directory entry.
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown * Note that the caller need not (and in fact must not) free
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown * the directory_error_t; it will be freed when the directory entry
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown * list is freed.
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown */
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brownvoid
1fcced4c370617db71610fecffd5451a5894ca5eJordan Browndirectory_entry_set_error(directory_entry_rpc *ent, directory_error_t de)
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown{
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown xdr_free(xdr_directory_entry_rpc, (char *)&ent);
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown ent->status = DIRECTORY_ERROR;
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown (void) directory_error_to_rpc(&ent->directory_entry_rpc_u.err, de);
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown}