/* * This file and its contents are supplied under the terms of the * Common Development and Distribution License ("CDDL"), version 1.0. * You may only use this file in accordance with the terms of version * 1.0 of the CDDL. * * A full copy of the text of the CDDL should have accompanied this * source. A copy of the CDDL is also available via the Internet at * http://www.illumos.org/license/CDDL. */ /* * Copyright 2014 Nexenta Systems, Inc. All rights reserved. * Copyright 2021 RackTop Systems, Inc. */ #include #include #include #include #include #include #include #include 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; /* name of subcommand */ cmd_fn_t *fn; /* pointer to subcommand handler function */ cmd_usage_t *usage; /* pointer to subcommand help function */ int optreq; /* does this have a required optval */ } 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} }; /* * lookupcmd */ 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); } /* * dclist */ static void dclist_usage(void) { (void) printf(gettext("usage: nltest dclist... \n")); exit(1); } /* ARGSUSED */ static int cmd_dclist(char *optval) { (void) printf("cmd_dclist() \n"); return (0); } /* * dcname */ static void dcname_usage(void) { (void) printf(gettext("usage: nltest dcname... \n")); exit(1); } /* ARGSUSED */ static int cmd_dcname(char *optval) { (void) printf("cmd_dcname() \n"); return (0); } /* * dsgetdc */ static void dsgetdc_usage(void) { (void) printf(gettext("usage: nltest dsgetdc... \n")); exit(1); } /* ARGSUSED */ static int cmd_dsgetdc(char *optval) { (void) printf("cmd_dsgetdc() \n"); return (0); } /* * dsgetdcname */ 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); } /* * kick */ 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); } /* * help functions */ static void help(void) { (void) printf("\n"); /* * TODO: We may want to revise this help text. It's basically * a copy-paste from: * http://technet.microsoft.com/en-us/library/cc731935.aspx */ (void) printf(gettext("usage: %s /subcommand\n"), (char *)getexecname()); (void) printf(gettext("where subcommands are:\n" #if 0 /* not yet */ " 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; /* * Parse options. */ while (optind < argc) { arg = argv[optind]; optname = NULL; optval = NULL; /* Is this an option? */ if (arg[0] == '/') { optname = arg + 1; optind++; /* * May have /optname:value */ if ((p = strchr(optname, ':')) != NULL) { *p++ = '\0'; optval = p; } } else if (arg[0] == '-' && arg[1] == '-') { optname = arg + 2; optind++; /* * May have --optname=value */ if ((p = strchr(optname, '=')) != NULL) { *p++ = '\0'; optval = p; } } else { /* Not an option. Stop parsing. */ break; } /* * Handle each optname (and maybe its optval) * Might put this logic in a table of options. * (including a flag for "optval required", * so that check could be factored out) */ for (cmd = commands; cmd->name; cmd++) { if (!strcasecmp(optname, cmd->name)) { /* cmd->name requires an optval */ 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; } } } /* * Handle remaining non-option arguments */ 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); }