Skip to content
Snippets Groups Projects
Commit 5e7336fc authored by Kurt Zeilenga's avatar Kurt Zeilenga
Browse files

Move saucer to the Attic. Has not been updated to support LDAPv3.

parent 9b35077e
No related branches found
No related tags found
No related merge requests found
......@@ -2657,8 +2657,6 @@ servers/slapd/tools/Makefile:build/top.mk:servers/slapd/tools/Makefile.in \
servers/slurpd/Makefile:build/top.mk:servers/slurpd/Makefile.in:build/srv.mk \
tests/Makefile:build/top.mk:tests/Makefile.in:build/dir.mk \
tests/progs/Makefile:build/top.mk:tests/progs/Makefile.in:build/rules.mk \
contrib/Makefile:build/top.mk:contrib/Makefile.in:build/dir.mk \
contrib/saucer/Makefile:build/top.mk:contrib/saucer/Makefile.in:build/rules.mk \
,[
date > stamp-h
echo Please \"make depend\" to build dependencies
......
# $OpenLDAP$
## Copyright 1998-2000 The OpenLDAP Foundation, All Rights Reserved.
## COPYING RESTRICTIONS APPLY, See COPYRIGHT file
##
## contrib Makefile.in for OpenLDAP
SUBDIRS= saucer web_ldap
......@@ -14,12 +14,6 @@ Current contributions:
ldaptcl
TCL API from NeoSoft
saucer
General purpose command-line LDAP client, modeled
after ISODE's DISH (DIrectory SHell) client.
Contributed by Eric Rosenquist. See saucer/README
and its man page for more information.
Please submit your contributions using the OpenLDAP Issue
Tracking System <http://www.openldap.org/>.
......
PROGRAMS= saucer
SRCS= main.c
OBJS= main.o
LDAP_INCDIR= ../../include
LDAP_LIBDIR= ../../libraries
READLINE_LIBS = @READLINE_LIBS@
XLIBS = -lldap -llber -llutil
XXLIBS = $(SECURITY_LIBS) $(LUTIL_LIBS) $(READLINE_LIBS) $(TERMCAP_LIBS)
MANDIR=$(mandir)/man1
saucer: ${OBJS} $(LDAP_LIBDEPEND)
$(LTLINK) -o $@ $(OBJS) $(LIBS)
install-local: $(PROGRAMS) FORCE
-$(MKDIR) $(DESTDIR)$(bindir)
$(LTINSTALL) $(INSTALLFLAGS) -m 755 saucer $(DESTDIR)$(bindir)
-$(MKDIR) $(DESTDIR)$(MANDIR)
$(INSTALL) $(INSTALLFLAGS) -m 644 $(srcdir)/saucer.1 $(DESTDIR)$(MANDIR)/saucer.1
This directory contains a set of files that build a simple LDAP client
program. The program is command-line oriented and uses a syntax and
command set roughly similar to ISODE's DISH program, hence it is
named "saucer" (i.e. a very small "dish" :-)
To build saucer, you must first build OpenLDAP, and then say
cd contrib/saucer
make depend
make
You can then install it by doing an "su" and typing "make install".
This will copy the binary to the directory you specified for LDAP
binaries, and the man page will be placed in the appropriate man
directory.
If you wish saucer to use GNU Readline, you must have set CPPFLAGS and
LDFLAGS so that <readline/readline.h> and -lreadline will be found when
you configured OpenLDAP, e.g.
env CPPFLAGS="-I/usr/gnu/include" LDFLAGS="-L/usr/gnu/lib" ./configure
Saucer runs from the Unix command line with the following arguments:
saucer [-h host] [-p portnumber] [-u 'X500UserName']
[-c credentials] [-d debug-level]
If no options are given, saucer will attempt to connect to an LDAP
daemon on the local host and default port (389), and will attempt to
bind anonymously.
Typing "help" at saucer's command prompt will yield:
saucer dn=> help
Supported commands are:
help
list
moveto
quit
search
set
show
You can get syntactical help for a command by typing "help <command>".
Detailed instructions are available from the saucer man page.
Any comments or questions should be directed to:
Eric.Rosenquist@strataware.com
or to an OpenLDAP mailinglist, see <URL:http://www.openldap.org/lists/>.
/*
* 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 <ac/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( EXIT_FAILURE );
}
rc = user_tailor();
if (!(ld = ldap_init(hostname, portnum))) {
fprintf(stderr, "%s: unable to initialize LDAP session (%s:%d)\n",
progname, hostname, portnum);
exit( EXIT_FAILURE );
}
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");
}
set -aliasderef always -sizelimit 25 -timelimit 30
moveto "o=Enterprise Solutions Limited, c=CA"
.TH SAUCER 1 "March 1999" "OpenLDAP"
.UC 6
.SH NAME
saucer \- interactive X.500 Directory client program
.SH SYNOPSIS
\fBsaucer\fR [-h \fIhost\fR] [-p \fIportnumber\fR] [-u \fIX500UserName\fR]
[-c \fIcredentials\fR] [-d \fIdebug-level\fR]
.SH DESCRIPTION
\fIsaucer\fR is used to navigate and perform searches on an X.500
Directory via the Lightweight Directory Access Protocol (LDAP).
.SH OPTIONS
.TP 5
.B \-h hostname
Used to specify the name or IP number of an LDAP host to which saucer
should connect. If this flag is omitted, \fI127.0.0.1\fR is used.
.TP 5
.B \-p portnumber
Used to specify the TCP port number of the LDAP daemon on the server
host. If this flag is omitted, the LDAP default port number
(\fI389\fR) is used.
.TP 5
.B \-u X500UserName
Specifies the X.500 name to be used when binding to the directory
server. It must be in the form specified by RFC 1485, for example:
\fB"cn=George Castanza, o=Vandelay Industries, c=US"\fR
Don't forget to put quotes around the name if it contains blanks.
.TP 5
.B \-c credentials
Specifies the credentials, i.e. the password, to be used when binding
to the directory server. If this flag is omitted but a name is given
with the \fB-u\fR flag, an unauthenticated bind will be attempted. If
neither flag is given, an anonymous bind will be attempted.
.TP 5
.B \-d debug-level
Sets the LDAP debug mask to the numeric value specified. This flag is
only used if saucer was compiled with the LDAP_DEBUG flag.
.SH COMMANDS
\fIsaucer\fR commands consist of a keyword followed by zero or more
arguments. Commands and arguments can be shortened to any number of
characters; the entered text is matched against the available keywords
in ascending alphabetical order. For example, entering the command
\fB"s"\fR will be interpreted by \fIsaucer\fR as the \fBsearch\fR
command, and \fB"sh"\fR will be interpreted as the \fBshow\fR command.
The \fBset\fR command cannot be abbreviated since both \fB"s"\fR and
\fB"se"\fR will be interpreted as the \fBsearch\fR command.
Arguments to commands are separated by whitespace (blanks or tabs), so
any values that contain whitespace (such as X.500 names) need to be
enclosed in single or double quotes.
Arguments can be entered in any order. If the same argument appears
more than once in a command, the last value is used and the others are
ignored.
Directory names are by default assumed to be relative to the
\fIcurrent location\fR, which is set with the \fBmoveto\fR command.
All commands that accept a directory name have an optional
\fI-absolute\fR flag which causes \fIsaucer\fR to interpret the name
as a complete X.500 name rather than one that is relative to the
current location.
.SS "help [command]"
Provides brief online help giving the available commands and their syntax.
If \fIcommand\fR is specified, the syntax for the command is shown.
``help'' by itself simply provides a list of the available commands.
.SS "list [RDN/DN] [-absolute]"
Displays the names of a directory node's subordinates.
If an \fIRDN/DN\fR is given, it specifies the entry whose subordinates
are to be listed. In its absence, the current location (see the
\fBmoveto\fR command) is used. The \fI-absolute\fR argument controls
whether the \fIRDN/DN\fR is a complete directory name or is relative
to the current location.
.SS "moveto [RDN/DN] [-absolute]"
Displays or modifies \fIsaucer\fR's \fIcurrent location\fR in the
directory. Without arguments, the current location is displayed.
If an \fIRDN/DN\fR is given, the current location is modified
and the new value is displayed.
The \fI-absolute\fR flag causes \fIsaucer\fR to treat the entered
\fIRDN/DN\fR as a complete directory name and to use it as the
new current location. Without the \fI-absolute\fR flag, the
name is assumed to be relative to the previous location.
The special value \fB".."\fR is recognized by \fIsaucer\fR as a
valid name and causes the current location to be moved one level
up (towards the root) in the directory.
.SS quit
Unbinds from the directory and exits \fIsaucer\fR.
.SS "search <filter> [-object RDN/DN] [-absolute] [-scope <scope>]"
Searches the directory for entries which match the \fI<filter>\fR
expression. For more information on the syntax of the \fI<filter>\fR
argument, see "RFC 1588 - A String Representation of LDAP Search
Filters".
If the \fI-object\fR argument is used, it specifies the base of the
directory search. In its absence, the current location (see the
\fBmoveto\fR command) is used as the search base. The \fI-absolute\fR
argument controls whether the \fIRDN/DN\fR given with the
\fI-object\fR flag is a complete directory name or is relative to the
current location.
The \fI-scope\fR argument controls the depth of the search. It
accepts one of the keywords \fIbase\fR, \fIonelevel\fR, or
\fIsubtree\fR to search within the base object, its immediate
children, or all of its subordinates respectively. The search depth
is preserved across commands, so subsequent searches will use the
previously entered depth setting if a new one is not given.
\fISaucer\fR defaults to a \fIonelevel\fR search depth at startup.
.SS "set [-aliasderef <deref>] [-sizelimit N] [-timelimit seconds]"
Displays or modifies settings which apply to all directory operations
issued by \fIsaucer\fR. Without arguments, the current settings are
displayed. If options are given, the settings are changed and the new
values are displayed.
The \fI-aliasderef <deref>\fR argument controls how the directory
handles alias entries that it encounters. The value of \fI<deref>\fR
must be one of \fInever\fR, \fIsearch\fR, \fIfind\fR, or \fIalways\fR.
A value of \fInever\fR tells the directory not to follow through any
aliases it encounters.
A value of \fIfind\fR tells the directory to follow through an alias
if it occurs as the base of a \fBlist\fR, \fBsearch\fR, or \fBshow\fR
command.
A value of \fIsearch\fR tells the directory to follow through an alias
when performing a \fBsearch\fR command. In other words, when
performing a search, the attributes of the entry an alias points to
will be tested against the filter expression rather than the alias
itself.
A value of \fIalways\fR combines the meanings of the \fIfind\fR and
\fIsearch\fR values, i.e., aliases are always dereferenced before
being acted upon.
The \fI-sizelimit N\fR argument sets the maximum number of entries
that will be returned by directory for \fBlist\fR and \fBsearch\fR
commands to \fIN\fR. The directory server itself may impose a limit,
in which case the lesser of the two limits is used. A value of
\fI0\fR may be used to request as many entries as possible.
The \fI-timelimit seconds\fR argument sets the maximum amount of time
allowed for a \fBlist\fR, \fBsearch\fR, or \fBshow\fR command. Note
that this value is simply passed to the directory server, so the
enforcement of the time limit is up to the server. A value of \fI0\fR
may be used to request no time limit.
.SS "show [RDN/DN] [-absolute]"
Displays the attributes of a directory entry.
If an \fIRDN/DN\fR is given, it specifies the entry whose attributes
are to be shown. In its absence, the current location (see the
\fBmoveto\fR command) is used. The \fI-absolute\fR argument controls
whether the \fIRDN/DN\fR is a complete directory name or is relative
to the current location.
The attributes \fIaudio\fR, \fIjpegPhoto\fR, \fIpersonalSignature\fR,
and \fIphoto\fR are known by \fIsaucer\fR to be binary values and are
therefore not displayed. Other attributes which have binary encodings
will be displayed by \fIsaucer\fR and will probably appear as garbage
on the screen.
.SH FILES
~/.saucerrc The saucer startup command file.
.SH "SEE ALSO"
ldap(3), RFC 1485, RFC 1588
.SH DIAGNOSTICS
\fIsaucer\fR uses the ldap_perror() routine to print a message
whenever an error is returned by the Directory server or the LDAP
library.
.SH "TO DO"
The new LDAP 3.1 ldap_XXX2text() routines should be used instead of
the code built into saucer.
The ability to read the X500UserName and credentials from the
~/.saucerrc file should be added. There should also be a way to have
saucer prompt the user for their password.
Attribute types which are binary are hard-coded into saucer. Ideally
saucer should also try to detect which ones aren't displayable at
runtime.
.SH AUTHOR
Eric Rosenquist, Enterprise Solutions Limited.
.br
Eric.Rosenquist@esltd.com
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment