#include <stdio.h>
#include <libintl.h>
#include <stdlib.h>
#include <strings.h>
#include <err.h>
#include <ads/dsgetdc.h>
#include <smb/nterror.h>
#include <uuid/uuid.h>
static void dclist_usage(void);
static int cmd_dclist(char *);
static void dcname_usage(void);
static int cmd_dcname(char *);
static void dsgetdc_usage(void);
static int cmd_dsgetdc(char *);
static void dsgetdcname_usage(void);
static int cmd_dsgetdcname(char *);
static void kick_usage(void);
static int cmd_kick(char *);
static void help(void);
typedef int cmd_fn_t (char *);
typedef void cmd_usage_t (void);
static struct commands {
const char *name;
cmd_fn_t *fn;
cmd_usage_t *usage;
int optreq;
} commands[] = {
{"dclist", cmd_dclist, dclist_usage, 0},
{"dcname", cmd_dcname, dcname_usage, 0},
{"dsgetdc", cmd_dsgetdc, dsgetdc_usage, 0},
{"dsgetdcname", cmd_dsgetdcname, dsgetdcname_usage, 0},
{"kick", cmd_kick, kick_usage, 0},
{NULL, NULL, NULL, 0}
};
static struct commands *
lookupcmd(const char *name)
{
struct commands *cmd;
for (cmd = commands; cmd->name; cmd++) {
if (strcasecmp(cmd->name, name) == 0)
return (cmd);
}
return (NULL);
}
static void
dclist_usage(void)
{
(void) printf(gettext("usage: nltest dclist... \n"));
exit(1);
}
static int
cmd_dclist(char *optval)
{
(void) printf("cmd_dclist() \n");
return (0);
}
static void
dcname_usage(void)
{
(void) printf(gettext("usage: nltest dcname... \n"));
exit(1);
}
static int
cmd_dcname(char *optval)
{
(void) printf("cmd_dcname() \n");
return (0);
}
static void
dsgetdc_usage(void)
{
(void) printf(gettext("usage: nltest dsgetdc... \n"));
exit(1);
}
static int
cmd_dsgetdc(char *optval)
{
(void) printf("cmd_dsgetdc() \n");
return (0);
}
static void
dsgetdcname_usage(void)
{
(void) printf(gettext("usage: nltest dsgetdcname domainname \n"));
exit(1);
}
static int
cmd_dsgetdcname(char *domname)
{
char uuid_buf[UUID_PRINTABLE_STRING_LENGTH];
int err = 0;
char *atype;
DOMAIN_CONTROLLER_INFO *dcinfo;
if (domname != NULL)
(void) printf(" Domain name supplied: %s \n", domname);
err = DsGetDcName(NULL, domname, NULL, NULL, 0, &dcinfo);
switch (err) {
case 0:
break;
case ERROR_NO_SUCH_DOMAIN:
(void) printf("Domain controller not found.\n");
(void) printf("See: /var/run/idmap/discovery.log\n");
exit(1);
default:
(void) printf("Unexpected error %d\n", err);
exit(1);
}
switch (dcinfo->DomainControllerAddressType) {
case DS_INET_ADDRESS:
atype = "inet";
break;
case DS_NETBIOS_ADDRESS:
atype = "netbios";
break;
default:
atype = "?";
break;
}
uuid_unparse(dcinfo->DomainGuid, uuid_buf);
(void) printf("Data Returned from DsGetDcName() call: \n");
(void) printf(" DC Name: %s \n", dcinfo->DomainControllerName);
(void) printf(" DC Addr: %s \n", dcinfo->DomainControllerAddress);
(void) printf(" DC Addr Type: %s \n", atype);
(void) printf(" Domain Name: %s \n", dcinfo->DomainName);
(void) printf(" Domain GUID: %s \n", uuid_buf);
(void) printf(" DNS Forest Name: %s \n", dcinfo->DnsForestName);
(void) printf(" Flags: 0x%x \n", dcinfo->Flags);
(void) printf(" DC Site Name: %s \n", dcinfo->DcSiteName);
(void) printf(" Client Site Name: %s \n", dcinfo->ClientSiteName);
DsFreeDcInfo(dcinfo);
return (0);
}
static void
kick_usage(void)
{
(void) printf(gettext("usage: nltest /KICK \n"));
exit(1);
}
static int
cmd_kick(char *domname)
{
int flags = 0;
int result;
result = _DsForceRediscovery(domname, flags);
return (result);
}
static void
help(void)
{
(void) printf("\n");
(void) printf(gettext("usage: %s /subcommand\n"),
(char *)getexecname());
(void) printf(gettext("where subcommands are:\n"
#if 0
" dclist Lists all domain controllers in the domain.\n"
" dcname Lists the PDC or PDC emulator.\n"
" dsgetdc Queries DNS server for list of DCs and"
" their IP addresses and contacts each DC to check"
" for connectivity.\n"
#endif
" dsgetdcname returns the name of a domain controller in a"
" specified domain\n"
" help display help on specified subcommand\n"
" kick trigger domain controller re-discovery\n"
"\n"));
exit(1);
}
int
main(int argc, char *argv[])
{
struct commands *cmd;
int err = 0;
char *option_cmd = NULL;
char *arg;
char *p;
char *optname;
char *optval = NULL;
int i;
int optind = 1;
while (optind < argc) {
arg = argv[optind];
optname = NULL;
optval = NULL;
if (arg[0] == '/') {
optname = arg + 1;
optind++;
if ((p = strchr(optname, ':')) != NULL) {
*p++ = '\0';
optval = p;
}
} else if (arg[0] == '-' && arg[1] == '-') {
optname = arg + 2;
optind++;
if ((p = strchr(optname, '=')) != NULL) {
*p++ = '\0';
optval = p;
}
} else {
break;
}
for (cmd = commands; cmd->name; cmd++) {
if (!strcasecmp(optname, cmd->name)) {
if (optval == NULL && optind < argc)
optval = argv[optind++];
if (optval == NULL && cmd->optreq > 0) {
(void) fprintf(stderr,
"%s: option %s requires a value\n",
argv[0], optname);
return (1);
}
option_cmd = optname;
}
}
}
for (i = optind; i < argc; i++) {
(void) printf("arg: %s\n", argv[i]);
}
if (option_cmd == NULL)
help();
cmd = lookupcmd(option_cmd);
if (cmd == NULL)
err = 1;
else
err = cmd->fn(optval);
return (err);
}