2 * This file and its contents are supplied under the terms of the
3 * Common Development and Distribution License ("CDDL"), version 1.0.
4 * You may only use this file in accordance with the terms of version
7 * A full copy of the text of the CDDL should have accompanied this
8 * source. A copy of the CDDL is also available via the Internet at
9 * http://www.illumos.org/license/CDDL.
13 * Copyright 2014 Nexenta Systems, Inc. All rights reserved.
22 #include <ads/dsgetdc.h>
23 #include <smb/nterror.h>
24 #include <uuid/uuid.h>
27 static void dclist_usage(void);
28 static int cmd_dclist(char *);
29 static void dcname_usage(void);
30 static int cmd_dcname(char *);
31 static void dsgetdc_usage(void);
32 static int cmd_dsgetdc(char *);
33 static void dsgetdcname_usage(void);
34 static int cmd_dsgetdcname(char *);
35 static void kick_usage(void);
36 static int cmd_kick(char *);
37 static void help(void);
39 typedef int cmd_fn_t (char *);
40 typedef void cmd_usage_t (void);
43 static struct commands
{
44 const char *name
; /* name of subcommand */
45 cmd_fn_t
*fn
; /* pointer to subcommand handler function */
46 cmd_usage_t
*usage
; /* pointer to subcommand help function */
47 int optreq
; /* does this have a required optval */
49 {"dclist", cmd_dclist
, dclist_usage
, 0},
50 {"dcname", cmd_dcname
, dcname_usage
, 0},
51 {"dsgetdc", cmd_dsgetdc
, dsgetdc_usage
, 0},
52 {"dsgetdcname", cmd_dsgetdcname
, dsgetdcname_usage
, 0},
53 {"kick", cmd_kick
, kick_usage
, 0},
61 static struct commands
*
62 lookupcmd(const char *name
)
66 for (cmd
= commands
; cmd
->name
; cmd
++) {
67 if (strcasecmp(cmd
->name
, name
) == 0)
79 (void) printf(gettext("usage: nltest dclist... \n"));
85 cmd_dclist(char *optval
)
87 (void) printf("cmd_dclist() \n");
97 (void) printf(gettext("usage: nltest dcname... \n"));
103 cmd_dcname(char *optval
)
105 (void) printf("cmd_dcname() \n");
115 (void) printf(gettext("usage: nltest dsgetdc... \n"));
121 cmd_dsgetdc(char *optval
)
123 (void) printf("cmd_dsgetdc() \n");
131 dsgetdcname_usage(void)
133 (void) printf(gettext("usage: nltest dsgetdcname domainname \n"));
138 cmd_dsgetdcname(char *domname
)
140 char uuid_buf
[UUID_PRINTABLE_STRING_LENGTH
];
143 DOMAIN_CONTROLLER_INFO
*dcinfo
;
146 (void) printf(" Domain name supplied: %s \n", domname
);
148 err
= DsGetDcName(NULL
, domname
, NULL
, NULL
, 0, &dcinfo
);
153 case ERROR_NO_SUCH_DOMAIN
:
154 (void) printf("Domain controller not found.\n");
155 (void) printf("See: /var/run/idmap/discovery.log\n");
158 (void) printf("Unexpected error %d\n", err
);
162 switch (dcinfo
->DomainControllerAddressType
) {
163 case DS_INET_ADDRESS
:
166 case DS_NETBIOS_ADDRESS
:
174 uuid_unparse(dcinfo
->DomainGuid
, uuid_buf
);
176 (void) printf("Data Returned from DsGetDcName() call: \n");
177 (void) printf(" DC Name: %s \n", dcinfo
->DomainControllerName
);
178 (void) printf(" DC Addr: %s \n", dcinfo
->DomainControllerAddress
);
179 (void) printf(" DC Addr Type: %s \n", atype
);
180 (void) printf(" Domain Name: %s \n", dcinfo
->DomainName
);
181 (void) printf(" Domain GUID: %s \n", uuid_buf
);
182 (void) printf(" DNS Forest Name: %s \n", dcinfo
->DnsForestName
);
183 (void) printf(" Flags: 0x%x \n", dcinfo
->Flags
);
184 (void) printf(" DC Site Name: %s \n", dcinfo
->DcSiteName
);
185 (void) printf(" Client Site Name: %s \n", dcinfo
->ClientSiteName
);
196 (void) printf(gettext("usage: nltest /KICK \n"));
202 cmd_kick(char *domname
)
207 result
= _DsForceRediscovery(domname
, flags
);
220 * TODO: We may want to revise this help text. It's basically
222 * http://technet.microsoft.com/en-us/library/cc731935.aspx
224 (void) printf(gettext("usage: %s /subcommand\n"),
225 (char *)getexecname());
226 (void) printf(gettext("where subcommands are:\n"
228 " dclist Lists all domain controllers in the domain.\n"
229 " dcname Lists the PDC or PDC emulator.\n"
230 " dsgetdc Queries DNS server for list of DCs and"
231 " their IP addresses and contacts each DC to check"
232 " for connectivity.\n"
234 " dsgetdcname returns the name of a domain controller in a"
235 " specified domain\n"
236 " help display help on specified subcommand\n"
237 " kick trigger domain controller re-discovery\n"
243 main(int argc
, char *argv
[])
245 struct commands
*cmd
;
247 char *option_cmd
= NULL
;
258 while (optind
< argc
) {
263 /* Is this an option? */
269 * May have /optname:value
271 if ((p
= strchr(optname
, ':')) != NULL
) {
275 } else if (arg
[0] == '-' && arg
[1] == '-') {
280 * May have --optname=value
282 if ((p
= strchr(optname
, '=')) != NULL
) {
287 /* Not an option. Stop parsing. */
292 * Handle each optname (and maybe its optval)
293 * Might put this logic in a table of options.
294 * (including a flag for "optval required",
295 * so that check could be factored out)
297 for (cmd
= commands
; cmd
->name
; cmd
++) {
298 if (!strcasecmp(optname
, cmd
->name
)) {
299 /* cmd->name requires an optval */
300 if (optval
== NULL
&& optind
< argc
)
301 optval
= argv
[optind
++];
303 if (optval
== NULL
&& cmd
->optreq
> 0) {
304 (void) fprintf(stderr
,
305 "%s: option %s requires a value\n",
309 option_cmd
= optname
;
315 * Handle remaining non-option arguments
317 for (i
= optind
; i
< argc
; i
++) {
318 (void) printf("arg: %s\n", argv
[i
]);
321 if (option_cmd
== NULL
)
324 cmd
= lookupcmd(option_cmd
);
328 err
= cmd
->fn(optval
);