#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>
#include <malloc.h>
#include <sys/types.h>
#include <netdb.h>
#include <pthread.h>
#include <unistd.h>
#include <string.h>
#include <libuutil.h>
#include <note.h>
#include "idmapd.h"
#include "directory.h"
#include "directory_private.h"
#include <rpcsvc/idmap_prot.h>
#include "directory_library_impl.h"
#include "directory_server_impl.h"
#include "sized_array.h"
extern struct directory_provider_static directory_provider_builtin;
extern struct directory_provider_static directory_provider_nsswitch;
extern struct directory_provider_static directory_provider_ad;
struct directory_provider_static *providers[] = {
&directory_provider_builtin,
&directory_provider_nsswitch,
&directory_provider_ad,
};
bool_t
directory_get_common_1_svc(
idmap_utf8str_list ids,
idmap_utf8str types,
idmap_utf8str_list attrs,
directory_results_rpc *result,
struct svc_req *req)
{
NOTE(ARGUNUSED(req))
int nids;
directory_entry_rpc *entries;
directory_error_t de;
int i;
nids = ids.idmap_utf8str_list_len;
entries = (directory_entry_rpc *)
calloc(nids, sizeof (directory_entry_rpc));
if (entries == NULL)
goto nomem;
result->directory_results_rpc_u.entries.entries_val = entries;
result->directory_results_rpc_u.entries.entries_len = nids;
result->failed = FALSE;
for (i = 0; i < nids; i++) {
if (strlen(ids.idmap_utf8str_list_val[i]) >
IDMAP_MAX_NAME_LEN) {
directory_entry_set_error(&entries[i],
directory_error("invalid_arg.id.too_long",
"Identifier too long", NULL));
}
}
for (i = 0; i < UU_NELEM(providers); i++) {
de = providers[i]->get(entries, &ids, types,
&attrs);
if (de != NULL)
goto err;
}
return (TRUE);
nomem:
de = directory_error("ENOMEM.get_common",
"Insufficient memory retrieving directory data", NULL);
err:
xdr_free(xdr_directory_results_rpc, (char *)result);
result->failed = TRUE;
return (
directory_error_to_rpc(&result->directory_results_rpc_u.err, de));
}
void
split_name(char *name, char *domain, char *id)
{
char *p;
if ((p = strchr(id, '@')) != NULL) {
(void) strlcpy(name, id, p - id + 1);
(void) strcpy(domain, p + 1);
} else if ((p = strchr(id, '\\')) != NULL) {
(void) strcpy(name, p + 1);
(void) strlcpy(domain, id, p - id + 1);
} else {
(void) strcpy(name, id);
(void) strcpy(domain, "");
}
}
directory_error_t
str_list_dav(directory_values_rpc *lvals, const char * const *str_list, int n)
{
directory_value_rpc *dav;
int i;
if (n == 0) {
for (n = 0; str_list[n] != NULL; n++)
;
}
dav = calloc(n, sizeof (directory_value_rpc));
if (dav == NULL)
goto nomem;
lvals->directory_values_rpc_u.values.values_val = dav;
lvals->directory_values_rpc_u.values.values_len = n;
lvals->found = TRUE;
for (i = 0; i < n; i++) {
int len;
len = strlen(str_list[i]);
dav[i].directory_value_rpc_val = uu_memdup(str_list[i], len);
if (dav[i].directory_value_rpc_val == NULL)
goto nomem;
dav[i].directory_value_rpc_len = len;
}
return (NULL);
nomem:
return (directory_error("ENOMEM.str_list_dav",
"Insufficient memory copying values"));
}
directory_error_t
uint_list_dav(directory_values_rpc *lvals, const unsigned int *array, int n)
{
directory_value_rpc *dav;
int i;
dav = calloc(n, sizeof (directory_value_rpc));
if (dav == NULL)
goto nomem;
lvals->directory_values_rpc_u.values.values_val = dav;
lvals->directory_values_rpc_u.values.values_len = n;
lvals->found = TRUE;
for (i = 0; i < n; i++) {
char buf[100];
int len;
(void) snprintf(buf, sizeof (buf), "%u", array[i]);
len = strlen(buf);
dav[i].directory_value_rpc_val = uu_memdup(buf, len);
if (dav[i].directory_value_rpc_val == NULL)
goto nomem;
dav[i].directory_value_rpc_len = len;
}
return (NULL);
nomem:
return (directory_error("ENOMEM.uint_list_dav",
"Insufficient memory copying values"));
}
directory_error_t
bin_list_dav(directory_values_rpc *lvals, const void *array, int n, size_t sz)
{
directory_value_rpc *dav;
char *inbuf = (char *)array;
int i;
dav = calloc(n, sizeof (directory_value_rpc));
if (dav == NULL)
goto nomem;
lvals->directory_values_rpc_u.values.values_val = dav;
lvals->directory_values_rpc_u.values.values_len = n;
lvals->found = TRUE;
for (i = 0; i < n; i++) {
dav[i].directory_value_rpc_val = uu_memdup(inbuf, sz);
if (dav[i].directory_value_rpc_val == NULL)
goto nomem;
dav[i].directory_value_rpc_len = sz;
inbuf += sz;
}
return (NULL);
nomem:
return (directory_error("ENOMEM.bin_list_dav",
"Insufficient memory copying values"));
}
void
directory_entry_set_error(directory_entry_rpc *ent, directory_error_t de)
{
xdr_free(xdr_directory_entry_rpc, (char *)&ent);
ent->status = DIRECTORY_ERROR;
(void) directory_error_to_rpc(&ent->directory_entry_rpc_u.err, de);
}