mirror of
https://git.openldap.org/openldap/openldap.git
synced 2025-12-25 00:59:45 -05:00
This commit includes many changes. All changes compile under NT but
have not been tested under UNIX.
A Summary of changes (likely incomplete):
NT changes:
Removed lint.
Clean up configuration support for "Debug", "Release", "SDebug",
and "SRelease" configurations.
Share output directories for clients, libraries,
and slapd. (maybe they should be combined further
and moved to build/{,S}{Debug,Release}).
Enable threading when _MT is defined.
Enable debuging when _DEBUG is defined.
Disable setting of NDEBUG under Release/SRelease. Asserts
are disabled in <ac/assert.h> when LDAP_DEBUG is not
defined.
Added 'build/main.dsp' Master project.
Removed non-slapd projects from slapd.dsp (see main.dsp).
Removed replaced many uses of _WIN32 macro with feature based
macros.
ldap_cdefs.h changes
#define LDAP_CONST const
(see below)
#define LDAP_F(type) LDAP_F_PRE type LDAP_F_POST
To allow specifiers to be added before and after
the type declaration. (For DLL handling)
LBER/LDAP changes
Namespace changes:
s/lber_/ber_/ for here and there.
s/NAME_ERROR/LDAP_NAME_ERROR/g
Deleted NULLMSG and other NULL* macros for namespace reasons.
"const" libraries. Installed headers (ie: lber.h, ldap.h)
use LDAP_CONST macro. Normally set to 'const' when
__STDC__. Can be set externally to enable/disable
'constification' of external interface. Internal
interface always uses 'const'. Did not fix warnings
in -lldif (in lieu of new LDIF parser).
Added _ext API implementations (excepting search and bind).
Need to implement ldap_int_get_controls() for reponses
with controls.
Added numberous assert() checks.
LDAP_R
_MT defines HAVE_NT_THREADS
Added numberous assert() checks.
Changed ldap_pthread_t back to unsigned long. Used cast
to HANDLE in _join().
LDBM
Replaced _WIN32 with HAVE_SYSLOG
ud
Added version string if MKVERSION is not defined. (MKVERSION
needs to be set under UNIX).
slapd
Made connection sockbuf field a pointer to a sockbuf. This
removed slap.h dependency on lber-int.h. lber-int.h now only
included by those files needing to mess with the sockbuf.
Used ber_* functions/macros to access sockbuf internals whenever
possible.
Added version string if MKVERSION is not defined. (MKVERSION
needs to be set under UNIX).
Removed FD_SET unsigned lint
slapd/tools
Used EXEEXT to added ".exe" to routines. Need to define EXEEXT
under UNIX.
ldappasswd
Added ldappasswd.dsp. Ported to NT. Used getpid() to seed rand().
nt_debug
Minor cleanup. Added "portable.h" include and used <ac/*.h> where
appropriate. Added const to char* format argument.
751 lines
16 KiB
C
751 lines
16 KiB
C
/*
|
|
* Copyright (c) 1994, Strata Software Limited, Ottawa, Ontario, Canada.
|
|
* All rights reserved.
|
|
*
|
|
* Redistribution and use in source and binary forms are permitted
|
|
* provided that this notice is preserved and that due credit is given
|
|
* to Eric Rosenquist and Strata Software Limited. The SSL name
|
|
* may not be used to endorse or promote products derived from this
|
|
* software without specific prior written permission. This software
|
|
* is provided "as is" without express or implied warranty.
|
|
*
|
|
*
|
|
* 'saucer' LDAP command-line client source code.
|
|
*
|
|
* Author: Eric Rosenquist, 1994.
|
|
*
|
|
* 07-Mar-1999 readline support added: O. Steffensen (oddbjorn@tricknology.org)
|
|
*/
|
|
|
|
#include "portable.h"
|
|
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
|
|
#ifdef HAVE_READLINE
|
|
# include <readline/readline.h>
|
|
# ifdef HAVE_READLINE_HISTORY_H
|
|
# include <readline/history.h>
|
|
# endif
|
|
#endif
|
|
|
|
#include <ac/ctype.h>
|
|
#include <ac/string.h>
|
|
#include <ac/unistd.h>
|
|
|
|
#include <lber.h>
|
|
#include <ldap.h>
|
|
#include <ldap_log.h>
|
|
|
|
#define DN_MAXLEN 4096
|
|
|
|
typedef struct {
|
|
const char *cmd;
|
|
int (*func) (char **, int);
|
|
const char *help_msg;
|
|
} CMDTABLE;
|
|
|
|
typedef enum {
|
|
CMD_HELP,
|
|
CMD_LIST,
|
|
CMD_MOVETO,
|
|
CMD_QUIT,
|
|
CMD_SEARCH,
|
|
CMD_SET,
|
|
CMD_SHOW
|
|
} COMMAND;
|
|
|
|
char *attrs_null[] = { "0.10", NULL };
|
|
char *credentials;
|
|
char default_dn[DN_MAXLEN];
|
|
char *hostname = "127.0.0.1";
|
|
LDAP *ld;
|
|
extern char *optarg;
|
|
extern int opterr;
|
|
extern int optind;
|
|
int option;
|
|
int portnum = LDAP_PORT;
|
|
char *progname;
|
|
char true_filter[] = "objectClass=*"; /* Always succeeds */
|
|
char *username;
|
|
|
|
int cmd_help(char **cmdargv, int cmdargc);
|
|
int cmd_list(char **cmdargv, int cmdargc);
|
|
int cmd_moveto(char **cmdargv, int cmdargc);
|
|
int cmd_quit(char **cmdargv, int cmdargc);
|
|
int cmd_search(char **cmdargv, int cmdargc);
|
|
int cmd_set(char **cmdargv, int cmdargc);
|
|
int cmd_show(char **cmdargv, int cmdargc);
|
|
|
|
int bind_user(void);
|
|
void display_search_results(LDAPMessage *result);
|
|
int do_command(char *cmd);
|
|
void do_commands(FILE *file);
|
|
int is_whitespace(register char *s);
|
|
char *make_dn(char *dn, int relative);
|
|
void show_syntax(unsigned int cmdnum);
|
|
char *skip_to_char(register char *s, register int c);
|
|
char *skip_to_whitespace(register char *s);
|
|
char *skip_whitespace(register char *s);
|
|
int table_lookup(const char *, const char *const *, int);
|
|
FILE *user_tailor(void);
|
|
|
|
static const char *const binary_attrs[] = {
|
|
"audio", "jpegPhoto", "personalSignature", "photo"
|
|
};
|
|
|
|
const CMDTABLE cmdtable[] = {
|
|
"help" , cmd_help , "[command]",
|
|
"list" , cmd_list , "[RDN-or-DN] [-absolute]",
|
|
"moveto", cmd_moveto, "[RDN-or-DN] [-absolute]",
|
|
"quit" , cmd_quit , "",
|
|
"search", cmd_search, "<filter> [-object RDN-or-DN] [-absolute]\n\t\t[-scope base|onelevel|subtree]",
|
|
"set" , cmd_set , "[-aliasderef never|search|find|always] [-sizelimit N] [-timelimit seconds]",
|
|
"show" , cmd_show , "[RDN-or-DN] [-absolute]"
|
|
};
|
|
|
|
|
|
int bind_user(void)
|
|
{
|
|
if (ldap_simple_bind_s(ld, username, credentials) != LDAP_SUCCESS) {
|
|
ldap_perror(ld, progname);
|
|
return 0;
|
|
}
|
|
if (username)
|
|
printf("Bound to ldap server as `%s' (%s authentication)\n", username,
|
|
credentials ? "simple" : "no");
|
|
else
|
|
puts("Bound anonymously to ldap server");
|
|
|
|
return 1;
|
|
}
|
|
|
|
int cmd_help(char **cmdargv, int cmdargc)
|
|
{
|
|
unsigned int i;
|
|
|
|
if (cmdargc == 2) {
|
|
for (i = 0; i < sizeof(cmdtable) / sizeof(cmdtable[0]); i++)
|
|
if (strncasecmp(cmdargv[1], cmdtable[i].cmd, strlen(cmdargv[1])) == 0) {
|
|
show_syntax(i);
|
|
return 0;
|
|
}
|
|
cmdargc = 1; /* Command not found - make it display the list of commands */
|
|
}
|
|
|
|
if (cmdargc == 1) {
|
|
puts("\nType 'help <command>' for help on a particular command.\n\n"
|
|
"Supported commands are:");
|
|
for (i = 0; i < sizeof(cmdtable) / sizeof(cmdtable[0]); i++)
|
|
printf(" %s\n", cmdtable[i].cmd);
|
|
puts("\nArguments to commands are separated by whitespace. Single (')\n"
|
|
"or double (\") quotes must be used around arguments that contain\n"
|
|
"embedded whitespace characters.\n");
|
|
} else
|
|
show_syntax(CMD_HELP);
|
|
|
|
return 0;
|
|
}
|
|
|
|
int cmd_list(char **cmdargv, int cmdargc)
|
|
{
|
|
char *dn = NULL;
|
|
int errflag = 0;
|
|
int i;
|
|
static const char *const opts[] = { "absolute" };
|
|
int relative = 1;
|
|
LDAPMessage *result;
|
|
|
|
for (i = 1; i < cmdargc; i++) {
|
|
if (cmdargv[i][0] == '-') {
|
|
switch (table_lookup(cmdargv[i] + 1, opts, sizeof(opts) / sizeof(opts[0]))) {
|
|
case 0:
|
|
relative = 0;
|
|
break;
|
|
default:
|
|
errflag = 1;
|
|
}
|
|
} else {
|
|
if (dn)
|
|
errflag = 1;
|
|
else
|
|
dn = cmdargv[i];
|
|
}
|
|
}
|
|
|
|
if (errflag) {
|
|
show_syntax(CMD_LIST);
|
|
return 0;
|
|
}
|
|
|
|
if (ldap_search(ld, make_dn(dn, relative), LDAP_SCOPE_ONELEVEL,
|
|
true_filter, attrs_null, 1) == -1) {
|
|
ldap_perror(ld, progname);
|
|
return 0;
|
|
}
|
|
|
|
if (ldap_result(ld, LDAP_RES_ANY, 1, (struct timeval *)0, &result) == -1) {
|
|
ldap_perror(ld, progname);
|
|
return 0;
|
|
}
|
|
|
|
display_search_results(result);
|
|
|
|
return 0;
|
|
}
|
|
|
|
int cmd_moveto(char **cmdargv, int cmdargc)
|
|
{
|
|
char *dn = NULL;
|
|
int errflag = 0;
|
|
char **exploded_dn;
|
|
int i;
|
|
static const char *const opts[] = { "absolute" };
|
|
int relative = 1;
|
|
|
|
for (i = 1; i < cmdargc; i++) {
|
|
if (cmdargv[i][0] == '-') {
|
|
switch (table_lookup(cmdargv[i] + 1, opts, sizeof(opts) / sizeof(opts[0]))) {
|
|
case 0:
|
|
relative = 0;
|
|
break;
|
|
default:
|
|
errflag = 1;
|
|
}
|
|
} else {
|
|
if (dn)
|
|
errflag = 1;
|
|
else
|
|
dn = cmdargv[i];
|
|
}
|
|
}
|
|
|
|
if (errflag) {
|
|
show_syntax(CMD_MOVETO);
|
|
return 0;
|
|
}
|
|
|
|
if (dn) {
|
|
if (is_whitespace(dn))
|
|
default_dn[0] = 0;
|
|
else {
|
|
if (strcmp(dn, "..") == 0) {
|
|
/* Move up one level */
|
|
if (exploded_dn = ldap_explode_dn(default_dn, 0)) {
|
|
if (exploded_dn[0]) {
|
|
char **rdn;
|
|
|
|
default_dn[0] = 0;
|
|
for (rdn = exploded_dn + 1; *rdn; rdn++) {
|
|
if (default_dn[0])
|
|
strcat(default_dn, ", ");
|
|
strcat(default_dn, *rdn);
|
|
}
|
|
}
|
|
ldap_value_free(exploded_dn);
|
|
}
|
|
} else {
|
|
/* Use ldap_explode_dn() to parse the string & test its syntax */
|
|
if (exploded_dn = ldap_explode_dn(dn, 1)) {
|
|
if (relative && !is_whitespace(default_dn)) {
|
|
char buf[DN_MAXLEN];
|
|
|
|
strcpy(default_dn, strcat(strcat(strcpy(buf, dn), ", "), default_dn));
|
|
} else
|
|
strcpy(default_dn, dn);
|
|
ldap_value_free(exploded_dn);
|
|
} else
|
|
puts("Invalid distinguished name.");
|
|
}
|
|
}
|
|
}
|
|
|
|
printf("Distinguished name suffix is `%s'\n", default_dn);
|
|
|
|
return 0;
|
|
}
|
|
|
|
int cmd_quit(char **cmdargv, int cmdargc)
|
|
{
|
|
return 1;
|
|
}
|
|
|
|
int cmd_search(char **cmdargv, int cmdargc)
|
|
{
|
|
char *dn = NULL;
|
|
int errflag = 0;
|
|
char *filter = NULL;
|
|
int i, j;
|
|
static const char *const opts[] = { "absolute", "object", "scope" };
|
|
int relative = 1;
|
|
LDAPMessage *result;
|
|
static const char *const scope_opts[]= { "base","onelevel","subtree" };
|
|
static const int scope_vals[] = { LDAP_SCOPE_BASE, LDAP_SCOPE_ONELEVEL, LDAP_SCOPE_SUBTREE };
|
|
static int search_scope = LDAP_SCOPE_ONELEVEL;
|
|
|
|
for (i = 1; i < cmdargc; i++) {
|
|
if (cmdargv[i][0] == '-') {
|
|
switch (table_lookup(cmdargv[i] + 1, opts, sizeof(opts) / sizeof(opts[0]))) {
|
|
case 0:
|
|
relative = 0;
|
|
break;
|
|
case 1:
|
|
if (++i < cmdargc)
|
|
dn = cmdargv[i];
|
|
else
|
|
errflag = 1;
|
|
break;
|
|
case 2:
|
|
if ((++i < cmdargc) &&
|
|
(j = table_lookup(cmdargv[i], scope_opts, sizeof(scope_opts) / sizeof(scope_opts[0]))) >= 0)
|
|
search_scope = scope_vals[j];
|
|
else
|
|
errflag = 1;
|
|
break;
|
|
default:
|
|
errflag = 1;
|
|
}
|
|
} else {
|
|
if (filter)
|
|
errflag = 1;
|
|
else
|
|
filter = cmdargv[i];
|
|
}
|
|
}
|
|
|
|
if (errflag || !filter) {
|
|
show_syntax(CMD_SEARCH);
|
|
return 0;
|
|
}
|
|
|
|
if (ldap_search(ld, make_dn(dn, relative), search_scope, filter, attrs_null, 0) == -1) {
|
|
ldap_perror(ld, progname);
|
|
return 0;
|
|
}
|
|
|
|
if (ldap_result(ld, LDAP_RES_ANY, 1, (struct timeval *)0, &result) == -1) {
|
|
ldap_perror(ld, progname);
|
|
return 0;
|
|
}
|
|
|
|
display_search_results(result);
|
|
|
|
return 0;
|
|
}
|
|
|
|
int cmd_set(char **cmdargv, int cmdargc)
|
|
{
|
|
static const char *const alias_opts[] = {
|
|
"never", "search", "find", "always"
|
|
};
|
|
int errflag = 0;
|
|
int i, j;
|
|
static const char *const opts[] = {
|
|
"aliasderef", "sizelimit", "timelimit"
|
|
};
|
|
|
|
for (i = 1; i < cmdargc; i++) {
|
|
if (cmdargv[i][0] == '-') {
|
|
switch (table_lookup(cmdargv[i] + 1, opts, sizeof(opts) / sizeof(opts[0]))) {
|
|
case 0:
|
|
if ((++i < cmdargc) &&
|
|
(j = table_lookup(cmdargv[i], alias_opts, sizeof(alias_opts) / sizeof(alias_opts[0]))) >= 0)
|
|
ldap_set_option(ld, LDAP_OPT_DEREF, &j);
|
|
else
|
|
errflag = 1;
|
|
break;
|
|
case 1:
|
|
if (++i < cmdargc) {
|
|
j = atoi(cmdargv[i]);
|
|
ldap_set_option(ld, LDAP_OPT_SIZELIMIT, &j);
|
|
} else
|
|
errflag = 1;
|
|
break;
|
|
case 2:
|
|
if (++i < cmdargc) {
|
|
j = atoi(cmdargv[i]);
|
|
ldap_set_option(ld, LDAP_OPT_TIMELIMIT, &j);
|
|
} else
|
|
errflag = 1;
|
|
break;
|
|
default:
|
|
errflag = 1;
|
|
}
|
|
} else
|
|
errflag = 1;
|
|
}
|
|
|
|
if (errflag)
|
|
show_syntax(CMD_SET);
|
|
else {
|
|
int opt_a, opt_s, opt_t;
|
|
ldap_get_option(ld, LDAP_OPT_DEREF, &opt_a);
|
|
ldap_get_option(ld, LDAP_OPT_SIZELIMIT, &opt_s);
|
|
ldap_get_option(ld, LDAP_OPT_TIMELIMIT, &opt_t);
|
|
printf("Alias dereferencing is %s, Sizelimit is %d entr%s, Timelimit is %d second%s.\n",
|
|
alias_opts[opt_a],
|
|
opt_s, opt_s == 1 ? "y" : "ies",
|
|
opt_t, opt_t == 1 ? "" : "s");
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
int cmd_show(char **cmdargv, int cmdargc)
|
|
{
|
|
char *dn = NULL;
|
|
int errflag = 0;
|
|
int i;
|
|
static const char *const opts[] = { "absolute" };
|
|
int relative = 1;
|
|
LDAPMessage *result;
|
|
|
|
for (i = 1; i < cmdargc; i++) {
|
|
if (cmdargv[i][0] == '-') {
|
|
switch (table_lookup(cmdargv[i] + 1, opts, sizeof(opts) / sizeof(opts[0]))) {
|
|
case 0:
|
|
relative = 0;
|
|
break;
|
|
default:
|
|
errflag = 1;
|
|
}
|
|
} else {
|
|
if (dn)
|
|
errflag = 1;
|
|
else
|
|
dn = cmdargv[i];
|
|
}
|
|
}
|
|
|
|
if (errflag) {
|
|
show_syntax(CMD_SHOW);
|
|
return 0;
|
|
}
|
|
|
|
if (ldap_search(ld, make_dn(dn, relative), LDAP_SCOPE_BASE, true_filter, NULL, 0) == -1) {
|
|
ldap_perror(ld, progname);
|
|
return 0;
|
|
}
|
|
|
|
if (ldap_result(ld, LDAP_RES_ANY, 1, (struct timeval *)0, &result) == -1) {
|
|
ldap_perror(ld, progname);
|
|
return 0;
|
|
}
|
|
|
|
display_search_results(result);
|
|
|
|
return 0;
|
|
}
|
|
|
|
void display_search_results(LDAPMessage *result)
|
|
{
|
|
BerElement *cookie;
|
|
int i;
|
|
LDAPMessage *entry;
|
|
int maxname;
|
|
char *s;
|
|
|
|
for (entry = ldap_first_entry(ld, result); entry; entry = ldap_next_entry(ld, entry)) {
|
|
if (s = ldap_get_dn(ld, entry)) {
|
|
printf(" %s\n", s);
|
|
ldap_memfree(s);
|
|
}
|
|
|
|
/* Make one pass to calculate the length of the longest attribute name */
|
|
maxname = 0;
|
|
for (s = ldap_first_attribute(ld, entry, &cookie); s; s = ldap_next_attribute(ld, entry, cookie))
|
|
if ((i = strlen(s)) > maxname)
|
|
maxname = i;
|
|
|
|
/* Now print the attributes and values */
|
|
for (s = ldap_first_attribute(ld, entry, &cookie); s; s = ldap_next_attribute(ld, entry, cookie)) {
|
|
char **values;
|
|
|
|
if (table_lookup(s, binary_attrs, sizeof(binary_attrs) / sizeof(binary_attrs[0])) >= 0)
|
|
continue; /* Skip this attribute - it's binary */
|
|
|
|
printf(" %-*s - ", maxname, s);
|
|
|
|
/* Now print each of the values for the given attribute */
|
|
if (values = ldap_get_values(ld, entry, s)) {
|
|
char **val;
|
|
|
|
for (val = values; *val; ) {
|
|
char *nl;
|
|
char *v = *val;
|
|
|
|
/* Watch out for values that have embedded \n characters */
|
|
while (nl = strchr(v, '\n')) {
|
|
*nl = 0;
|
|
puts(v);
|
|
v = nl + 1;
|
|
if (*v)
|
|
printf(" %*s", maxname + 3, "");
|
|
}
|
|
if (*v)
|
|
puts(v);
|
|
if (*++val)
|
|
printf(" %*s", maxname + 3, "");
|
|
}
|
|
ldap_value_free(values);
|
|
} else
|
|
putchar('\n');
|
|
}
|
|
}
|
|
|
|
if (ldap_result2error(ld, result, 0))
|
|
ldap_perror(ld, progname);
|
|
}
|
|
|
|
int do_command(char *cmd)
|
|
{
|
|
char *cmdargv[128];
|
|
int cmdargc = 0;
|
|
int i;
|
|
|
|
/* Tokenize the input command, allowing for quoting */
|
|
for (;;) {
|
|
cmd = skip_whitespace(cmd);
|
|
if (!cmd || !*cmd)
|
|
break; /* end of input */
|
|
|
|
cmdargv[cmdargc++] = cmd;
|
|
if (*cmd == '\'' || *cmd == '"') {
|
|
cmdargv[cmdargc - 1]++; /* Skip over the opening quote */
|
|
cmd = skip_to_char(cmd + 1, *cmd);
|
|
if (!cmd || !*cmd) {
|
|
puts("Command is missing a trailing quote");
|
|
return 0;
|
|
}
|
|
*cmd++ = 0;
|
|
} else {
|
|
cmd = skip_to_whitespace(cmd);
|
|
if (cmd && *cmd)
|
|
*cmd++ = 0;
|
|
}
|
|
}
|
|
|
|
#ifdef DEBUG
|
|
printf("cmdargc = %d\n", cmdargc);
|
|
for (i = 0; i < cmdargc; i++)
|
|
puts(cmdargv[i]);
|
|
#endif
|
|
|
|
if (cmdargv[0][0] == '?')
|
|
return cmd_help(cmdargv, cmdargc);
|
|
|
|
for (i = 0; i < sizeof(cmdtable) / sizeof(cmdtable[0]); i++)
|
|
if (strncasecmp(cmdargv[0], cmdtable[i].cmd, strlen(cmdargv[0])) == 0)
|
|
return (*cmdtable[i].func)(cmdargv, cmdargc);
|
|
|
|
if (!is_whitespace(cmdargv[0])) {
|
|
printf("Unrecognized command - %s\n", cmdargv[0]);
|
|
cmd_help(cmdargv, 1);
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
void do_commands(FILE *file)
|
|
{
|
|
char cmd_buf[BUFSIZ];
|
|
int tty = isatty(fileno(file));
|
|
char *buf = cmd_buf;
|
|
int status;
|
|
|
|
for (;;) {
|
|
if (tty)
|
|
{
|
|
char prompt[40];
|
|
sprintf(prompt, (strlen(default_dn) < 18
|
|
? "saucer dn=%s> "
|
|
: "saucer dn=%.15s..> "), default_dn);
|
|
#ifndef HAVE_READLINE
|
|
fputs (prompt, stdout);
|
|
#else
|
|
buf = readline (prompt);
|
|
if (!buf)
|
|
break;
|
|
add_history (buf);
|
|
#endif
|
|
}
|
|
#ifdef HAVE_READLINE
|
|
else
|
|
#endif
|
|
{
|
|
if (!fgets(cmd_buf, sizeof(cmd_buf), file))
|
|
break;
|
|
}
|
|
|
|
status = do_command(buf);
|
|
#ifdef HAVE_READLINE
|
|
if (tty)
|
|
free(buf);
|
|
#endif
|
|
if (status)
|
|
break;
|
|
}
|
|
}
|
|
|
|
int is_whitespace(register char *s)
|
|
{
|
|
if (!s)
|
|
return 1;
|
|
|
|
while (*s && isspace((unsigned char) *s))
|
|
++s;
|
|
|
|
return !*s;
|
|
}
|
|
|
|
int main(int argc, char **argv)
|
|
{
|
|
int error_flag = 0;
|
|
int tmp;
|
|
FILE *rc;
|
|
|
|
progname = argv[0];
|
|
while ((option = getopt(argc, argv, "h:p:u:c:d:")) != EOF)
|
|
switch (option) {
|
|
case 'c':
|
|
credentials = optarg;
|
|
break;
|
|
case 'd':
|
|
#ifdef LDAP_DEBUG
|
|
tmp = atoi(optarg);
|
|
ber_set_option(NULL, LBER_OPT_DEBUG_LEVEL, &tmp);
|
|
ldap_set_option(NULL, LDAP_OPT_DEBUG_LEVEL, &tmp);
|
|
#endif
|
|
break;
|
|
case 'h':
|
|
hostname = optarg;
|
|
break;
|
|
case 'p':
|
|
portnum = atoi(optarg);
|
|
break;
|
|
case 'u':
|
|
username = optarg;
|
|
break;
|
|
case '?':
|
|
error_flag = 1;
|
|
}
|
|
|
|
if (error_flag) {
|
|
fprintf(stderr, "usage: %s [-h host] [-p portnumber] [-u X500UserName]\n\t[-c credentials] [-d debug-level]\n",
|
|
progname);
|
|
exit(2);
|
|
}
|
|
|
|
rc = user_tailor();
|
|
|
|
if (!(ld = ldap_open(hostname, portnum))) {
|
|
fprintf(stderr, "%s: unable to connect to server at host `%s' on port %d\n",
|
|
progname, hostname, portnum);
|
|
exit(2);
|
|
}
|
|
|
|
if (!bind_user())
|
|
return 1;
|
|
|
|
if (rc) {
|
|
do_commands(rc);
|
|
fclose(rc);
|
|
}
|
|
do_commands(stdin);
|
|
|
|
ldap_unbind(ld);
|
|
|
|
return 0;
|
|
}
|
|
|
|
char *make_dn(char *dn, int relative)
|
|
{
|
|
static char dn_buf[DN_MAXLEN];
|
|
|
|
if (!dn)
|
|
dn = "";
|
|
|
|
if (!default_dn[0] || !relative)
|
|
return dn;
|
|
|
|
if (!dn[0])
|
|
return default_dn;
|
|
|
|
return strcat(strcat(strcpy(dn_buf, dn), ", "), default_dn);
|
|
}
|
|
|
|
void show_syntax(unsigned int cmdnum)
|
|
{
|
|
printf("Syntax: %s %s\n", cmdtable[cmdnum].cmd, cmdtable[cmdnum].help_msg);
|
|
}
|
|
|
|
char *skip_to_char(register char *s, register int c)
|
|
{
|
|
if (!s)
|
|
return s;
|
|
|
|
while (*s && *s != c)
|
|
++s;
|
|
|
|
return s;
|
|
}
|
|
|
|
char *skip_to_whitespace(register char *s)
|
|
{
|
|
if (!s)
|
|
return s;
|
|
|
|
while (*s && !isspace((unsigned char) *s))
|
|
++s;
|
|
|
|
return s;
|
|
}
|
|
|
|
char *skip_whitespace(register char *s)
|
|
{
|
|
if (!s)
|
|
return s;
|
|
|
|
while (*s && isspace((unsigned char) *s))
|
|
++s;
|
|
|
|
return s;
|
|
}
|
|
|
|
int table_lookup(const char *word, const char *const *table, int table_count)
|
|
{
|
|
register int i;
|
|
int wordlen;
|
|
|
|
if (!word || !*word)
|
|
return -1;
|
|
|
|
wordlen = strlen(word);
|
|
|
|
for (i = 0; i < table_count; i++)
|
|
if (strncasecmp(word, table[i], wordlen) == 0)
|
|
return i;
|
|
return -1;
|
|
}
|
|
|
|
FILE *user_tailor(void)
|
|
{
|
|
char rcfile[BUFSIZ];
|
|
|
|
rcfile[0] = 0;
|
|
|
|
#ifdef unix
|
|
{
|
|
#include <pwd.h>
|
|
struct passwd *pwent;
|
|
|
|
if (pwent = getpwuid(getuid()))
|
|
strcat(strcpy(rcfile, pwent->pw_dir), "/");
|
|
strcat(rcfile, ".saucerrc");
|
|
}
|
|
#else
|
|
strcpy(rcfile, "saucer.rc");
|
|
#endif
|
|
|
|
return fopen(rcfile, "r");
|
|
}
|