xref: /titanic_51/usr/src/cmd/idmap/nltest/nltest.c (revision b3700b074e637f8c6991b70754c88a2cfffb246b)
1*b3700b07SGordon Ross /*
2*b3700b07SGordon Ross  * This file and its contents are supplied under the terms of the
3*b3700b07SGordon Ross  * Common Development and Distribution License ("CDDL"), version 1.0.
4*b3700b07SGordon Ross  * You may only use this file in accordance with the terms of version
5*b3700b07SGordon Ross  * 1.0 of the CDDL.
6*b3700b07SGordon Ross  *
7*b3700b07SGordon Ross  * A full copy of the text of the CDDL should have accompanied this
8*b3700b07SGordon Ross  * source.  A copy of the CDDL is also available via the Internet at
9*b3700b07SGordon Ross  * http://www.illumos.org/license/CDDL.
10*b3700b07SGordon Ross  */
11*b3700b07SGordon Ross 
12*b3700b07SGordon Ross /*
13*b3700b07SGordon Ross  * Copyright 2014 Nexenta Systems, Inc.  All rights reserved.
14*b3700b07SGordon Ross  */
15*b3700b07SGordon Ross 
16*b3700b07SGordon Ross 
17*b3700b07SGordon Ross #include <stdio.h>
18*b3700b07SGordon Ross #include <libintl.h>
19*b3700b07SGordon Ross #include <stdlib.h>
20*b3700b07SGordon Ross #include <strings.h>
21*b3700b07SGordon Ross #include <err.h>
22*b3700b07SGordon Ross #include <ads/dsgetdc.h>
23*b3700b07SGordon Ross #include <smb/nterror.h>
24*b3700b07SGordon Ross #include <uuid/uuid.h>
25*b3700b07SGordon Ross 
26*b3700b07SGordon Ross 
27*b3700b07SGordon Ross static void dclist_usage(void);
28*b3700b07SGordon Ross static int cmd_dclist(char *);
29*b3700b07SGordon Ross static void dcname_usage(void);
30*b3700b07SGordon Ross static int cmd_dcname(char *);
31*b3700b07SGordon Ross static void dsgetdc_usage(void);
32*b3700b07SGordon Ross static int cmd_dsgetdc(char *);
33*b3700b07SGordon Ross static void dsgetdcname_usage(void);
34*b3700b07SGordon Ross static int cmd_dsgetdcname(char *);
35*b3700b07SGordon Ross static void kick_usage(void);
36*b3700b07SGordon Ross static int cmd_kick(char *);
37*b3700b07SGordon Ross static void help(void);
38*b3700b07SGordon Ross 
39*b3700b07SGordon Ross typedef int cmd_fn_t (char *);
40*b3700b07SGordon Ross typedef void cmd_usage_t (void);
41*b3700b07SGordon Ross 
42*b3700b07SGordon Ross 
43*b3700b07SGordon Ross static struct commands {
44*b3700b07SGordon Ross 	const char	*name;	/* name of subcommand */
45*b3700b07SGordon Ross 	cmd_fn_t	*fn;	/* pointer to subcommand handler function */
46*b3700b07SGordon Ross 	cmd_usage_t	*usage;	/* pointer to subcommand help function */
47*b3700b07SGordon Ross 	int		optreq; /* does this have a required optval */
48*b3700b07SGordon Ross } commands[] = {
49*b3700b07SGordon Ross 	{"dclist", cmd_dclist, dclist_usage, 0},
50*b3700b07SGordon Ross 	{"dcname", cmd_dcname, dcname_usage, 0},
51*b3700b07SGordon Ross 	{"dsgetdc", cmd_dsgetdc, dsgetdc_usage, 0},
52*b3700b07SGordon Ross 	{"dsgetdcname", cmd_dsgetdcname, dsgetdcname_usage, 0},
53*b3700b07SGordon Ross 	{"kick", cmd_kick, kick_usage, 0},
54*b3700b07SGordon Ross 	{NULL, NULL, NULL, 0}
55*b3700b07SGordon Ross };
56*b3700b07SGordon Ross 
57*b3700b07SGordon Ross 
58*b3700b07SGordon Ross /*
59*b3700b07SGordon Ross  * lookupcmd
60*b3700b07SGordon Ross  */
61*b3700b07SGordon Ross static struct commands *
62*b3700b07SGordon Ross lookupcmd(const char *name)
63*b3700b07SGordon Ross {
64*b3700b07SGordon Ross 	struct commands *cmd;
65*b3700b07SGordon Ross 
66*b3700b07SGordon Ross 	for (cmd = commands; cmd->name; cmd++) {
67*b3700b07SGordon Ross 		if (strcasecmp(cmd->name, name) == 0)
68*b3700b07SGordon Ross 			return (cmd);
69*b3700b07SGordon Ross 	}
70*b3700b07SGordon Ross 	return (NULL);
71*b3700b07SGordon Ross }
72*b3700b07SGordon Ross 
73*b3700b07SGordon Ross /*
74*b3700b07SGordon Ross  * dclist
75*b3700b07SGordon Ross  */
76*b3700b07SGordon Ross static void
77*b3700b07SGordon Ross dclist_usage(void)
78*b3700b07SGordon Ross {
79*b3700b07SGordon Ross 	(void) printf(gettext("usage: nltest dclist... \n"));
80*b3700b07SGordon Ross 	exit(1);
81*b3700b07SGordon Ross }
82*b3700b07SGordon Ross 
83*b3700b07SGordon Ross /* ARGSUSED */
84*b3700b07SGordon Ross static int
85*b3700b07SGordon Ross cmd_dclist(char *optval)
86*b3700b07SGordon Ross {
87*b3700b07SGordon Ross 	(void) printf("cmd_dclist() \n");
88*b3700b07SGordon Ross 	return (0);
89*b3700b07SGordon Ross }
90*b3700b07SGordon Ross 
91*b3700b07SGordon Ross /*
92*b3700b07SGordon Ross  * dcname
93*b3700b07SGordon Ross  */
94*b3700b07SGordon Ross static void
95*b3700b07SGordon Ross dcname_usage(void)
96*b3700b07SGordon Ross {
97*b3700b07SGordon Ross 	(void) printf(gettext("usage: nltest dcname... \n"));
98*b3700b07SGordon Ross 	exit(1);
99*b3700b07SGordon Ross }
100*b3700b07SGordon Ross 
101*b3700b07SGordon Ross /* ARGSUSED */
102*b3700b07SGordon Ross static int
103*b3700b07SGordon Ross cmd_dcname(char *optval)
104*b3700b07SGordon Ross {
105*b3700b07SGordon Ross 	(void) printf("cmd_dcname() \n");
106*b3700b07SGordon Ross 	return (0);
107*b3700b07SGordon Ross }
108*b3700b07SGordon Ross 
109*b3700b07SGordon Ross /*
110*b3700b07SGordon Ross  * dsgetdc
111*b3700b07SGordon Ross  */
112*b3700b07SGordon Ross static void
113*b3700b07SGordon Ross dsgetdc_usage(void)
114*b3700b07SGordon Ross {
115*b3700b07SGordon Ross 	(void) printf(gettext("usage: nltest dsgetdc... \n"));
116*b3700b07SGordon Ross 	exit(1);
117*b3700b07SGordon Ross }
118*b3700b07SGordon Ross 
119*b3700b07SGordon Ross /* ARGSUSED */
120*b3700b07SGordon Ross static int
121*b3700b07SGordon Ross cmd_dsgetdc(char *optval)
122*b3700b07SGordon Ross {
123*b3700b07SGordon Ross 	(void) printf("cmd_dsgetdc() \n");
124*b3700b07SGordon Ross 	return (0);
125*b3700b07SGordon Ross }
126*b3700b07SGordon Ross 
127*b3700b07SGordon Ross /*
128*b3700b07SGordon Ross  * dsgetdcname
129*b3700b07SGordon Ross  */
130*b3700b07SGordon Ross static void
131*b3700b07SGordon Ross dsgetdcname_usage(void)
132*b3700b07SGordon Ross {
133*b3700b07SGordon Ross 	(void) printf(gettext("usage: nltest dsgetdcname domainname \n"));
134*b3700b07SGordon Ross 	exit(1);
135*b3700b07SGordon Ross }
136*b3700b07SGordon Ross 
137*b3700b07SGordon Ross static int
138*b3700b07SGordon Ross cmd_dsgetdcname(char *domname)
139*b3700b07SGordon Ross {
140*b3700b07SGordon Ross 	char uuid_buf[UUID_PRINTABLE_STRING_LENGTH];
141*b3700b07SGordon Ross 	int err = 0;
142*b3700b07SGordon Ross 	char *atype;
143*b3700b07SGordon Ross 	DOMAIN_CONTROLLER_INFO *dcinfo;
144*b3700b07SGordon Ross 
145*b3700b07SGordon Ross 	if (domname != NULL)
146*b3700b07SGordon Ross 		(void) printf("  Domain name supplied:  %s \n", domname);
147*b3700b07SGordon Ross 
148*b3700b07SGordon Ross 	err = DsGetDcName(NULL, domname, NULL, NULL, 0, &dcinfo);
149*b3700b07SGordon Ross 
150*b3700b07SGordon Ross 	switch (err) {
151*b3700b07SGordon Ross 	case 0:
152*b3700b07SGordon Ross 		break;
153*b3700b07SGordon Ross 	case ERROR_NO_SUCH_DOMAIN:
154*b3700b07SGordon Ross 		(void) printf("Domain controller not found.\n");
155*b3700b07SGordon Ross 		(void) printf("See: /var/run/idmap/discovery.log\n");
156*b3700b07SGordon Ross 		exit(1);
157*b3700b07SGordon Ross 	default:
158*b3700b07SGordon Ross 		(void) printf("Unexpected error %d\n", err);
159*b3700b07SGordon Ross 		exit(1);
160*b3700b07SGordon Ross 	}
161*b3700b07SGordon Ross 
162*b3700b07SGordon Ross 	switch (dcinfo->DomainControllerAddressType) {
163*b3700b07SGordon Ross 	case DS_INET_ADDRESS:
164*b3700b07SGordon Ross 		atype = "inet";
165*b3700b07SGordon Ross 		break;
166*b3700b07SGordon Ross 	case DS_NETBIOS_ADDRESS:
167*b3700b07SGordon Ross 		atype = "netbios";
168*b3700b07SGordon Ross 		break;
169*b3700b07SGordon Ross 	default:
170*b3700b07SGordon Ross 		atype = "?";
171*b3700b07SGordon Ross 		break;
172*b3700b07SGordon Ross 	}
173*b3700b07SGordon Ross 
174*b3700b07SGordon Ross 	uuid_unparse(dcinfo->DomainGuid, uuid_buf);
175*b3700b07SGordon Ross 
176*b3700b07SGordon Ross 	(void) printf("Data Returned from DsGetDcName() call: \n");
177*b3700b07SGordon Ross 	(void) printf("  DC Name:  %s \n", dcinfo->DomainControllerName);
178*b3700b07SGordon Ross 	(void) printf("  DC Addr:  %s \n", dcinfo->DomainControllerAddress);
179*b3700b07SGordon Ross 	(void) printf("  DC Addr Type:  %s \n", atype);
180*b3700b07SGordon Ross 	(void) printf("  Domain Name:  %s \n", dcinfo->DomainName);
181*b3700b07SGordon Ross 	(void) printf("  Domain GUID:  %s \n", uuid_buf);
182*b3700b07SGordon Ross 	(void) printf("  DNS Forest Name:  %s \n", dcinfo->DnsForestName);
183*b3700b07SGordon Ross 	(void) printf("  Flags:  0x%x \n", dcinfo->Flags);
184*b3700b07SGordon Ross 	(void) printf("  DC Site Name:  %s \n", dcinfo->DcSiteName);
185*b3700b07SGordon Ross 	(void) printf("  Client Site Name:  %s \n", dcinfo->ClientSiteName);
186*b3700b07SGordon Ross 
187*b3700b07SGordon Ross 	return (0);
188*b3700b07SGordon Ross }
189*b3700b07SGordon Ross 
190*b3700b07SGordon Ross /*
191*b3700b07SGordon Ross  * kick
192*b3700b07SGordon Ross  */
193*b3700b07SGordon Ross static void
194*b3700b07SGordon Ross kick_usage(void)
195*b3700b07SGordon Ross {
196*b3700b07SGordon Ross 	(void) printf(gettext("usage: nltest /KICK \n"));
197*b3700b07SGordon Ross 	exit(1);
198*b3700b07SGordon Ross }
199*b3700b07SGordon Ross 
200*b3700b07SGordon Ross 
201*b3700b07SGordon Ross static int
202*b3700b07SGordon Ross cmd_kick(char *domname)
203*b3700b07SGordon Ross {
204*b3700b07SGordon Ross 	int flags = 0;
205*b3700b07SGordon Ross 	int result;
206*b3700b07SGordon Ross 
207*b3700b07SGordon Ross 	result = _DsForceRediscovery(domname, flags);
208*b3700b07SGordon Ross 
209*b3700b07SGordon Ross 	return (result);
210*b3700b07SGordon Ross }
211*b3700b07SGordon Ross 
212*b3700b07SGordon Ross /*
213*b3700b07SGordon Ross  * help functions
214*b3700b07SGordon Ross  */
215*b3700b07SGordon Ross 
216*b3700b07SGordon Ross static void
217*b3700b07SGordon Ross help(void) {
218*b3700b07SGordon Ross 	(void) printf("\n");
219*b3700b07SGordon Ross 	/*
220*b3700b07SGordon Ross 	 * TODO: We may want to revise this help text.  It's basically
221*b3700b07SGordon Ross 	 * a copy-paste from:
222*b3700b07SGordon Ross 	 *   http://technet.microsoft.com/en-us/library/cc731935.aspx
223*b3700b07SGordon Ross 	 */
224*b3700b07SGordon Ross 	(void) printf(gettext("usage: %s /subcommand\n"),
225*b3700b07SGordon Ross 	    (char *)getexecname());
226*b3700b07SGordon Ross 	(void) printf(gettext("where subcommands are:\n"
227*b3700b07SGordon Ross #if 0	/* not yet */
228*b3700b07SGordon Ross 		" dclist        Lists all domain controllers in the domain.\n"
229*b3700b07SGordon Ross 		" dcname        Lists the PDC or PDC emulator.\n"
230*b3700b07SGordon Ross 		" dsgetdc       Queries DNS server for list of DCs and"
231*b3700b07SGordon Ross 			" their IP addresses and contacts each DC to check"
232*b3700b07SGordon Ross 			" for connectivity.\n"
233*b3700b07SGordon Ross #endif
234*b3700b07SGordon Ross 		" dsgetdcname   returns the name of a domain controller in a"
235*b3700b07SGordon Ross 			" specified domain\n"
236*b3700b07SGordon Ross 		" help          display help on specified subcommand\n"
237*b3700b07SGordon Ross 		" kick          trigger domain controller re-discovery\n"
238*b3700b07SGordon Ross 		"\n"));
239*b3700b07SGordon Ross 	exit(1);
240*b3700b07SGordon Ross }
241*b3700b07SGordon Ross 
242*b3700b07SGordon Ross int
243*b3700b07SGordon Ross main(int argc, char *argv[])
244*b3700b07SGordon Ross {
245*b3700b07SGordon Ross 	struct commands *cmd;
246*b3700b07SGordon Ross 	int err = 0;
247*b3700b07SGordon Ross 	char *option_cmd = NULL;
248*b3700b07SGordon Ross 	char *arg;
249*b3700b07SGordon Ross 	char *p;
250*b3700b07SGordon Ross 	char *optname;
251*b3700b07SGordon Ross 	char *optval = NULL;
252*b3700b07SGordon Ross 	int i;
253*b3700b07SGordon Ross 	int optind = 1;
254*b3700b07SGordon Ross 
255*b3700b07SGordon Ross 	/*
256*b3700b07SGordon Ross 	 * Parse options.
257*b3700b07SGordon Ross 	 */
258*b3700b07SGordon Ross 	while (optind < argc) {
259*b3700b07SGordon Ross 		arg = argv[optind];
260*b3700b07SGordon Ross 		optname = NULL;
261*b3700b07SGordon Ross 		optval = NULL;
262*b3700b07SGordon Ross 
263*b3700b07SGordon Ross 		/* Is this an option? */
264*b3700b07SGordon Ross 		if (arg[0] == '/') {
265*b3700b07SGordon Ross 			optname = arg + 1;
266*b3700b07SGordon Ross 			optind++;
267*b3700b07SGordon Ross 
268*b3700b07SGordon Ross 			/*
269*b3700b07SGordon Ross 			 * May have  /optname:value
270*b3700b07SGordon Ross 			 */
271*b3700b07SGordon Ross 			if ((p = strchr(optname, ':')) != NULL) {
272*b3700b07SGordon Ross 				*p++ = '\0';
273*b3700b07SGordon Ross 				optval = p;
274*b3700b07SGordon Ross 			}
275*b3700b07SGordon Ross 		} else if (arg[0] == '-' && arg[1] == '-') {
276*b3700b07SGordon Ross 			optname = arg + 2;
277*b3700b07SGordon Ross 			optind++;
278*b3700b07SGordon Ross 
279*b3700b07SGordon Ross 			/*
280*b3700b07SGordon Ross 			 * May have  --optname=value
281*b3700b07SGordon Ross 			 */
282*b3700b07SGordon Ross 			if ((p = strchr(optname, '=')) != NULL) {
283*b3700b07SGordon Ross 				*p++ = '\0';
284*b3700b07SGordon Ross 				optval = p;
285*b3700b07SGordon Ross 			}
286*b3700b07SGordon Ross 		} else {
287*b3700b07SGordon Ross 			/* Not an option.  Stop parsing. */
288*b3700b07SGordon Ross 			break;
289*b3700b07SGordon Ross 		}
290*b3700b07SGordon Ross 
291*b3700b07SGordon Ross 		/*
292*b3700b07SGordon Ross 		 * Handle each optname (and maybe its optval)
293*b3700b07SGordon Ross 		 * Might put this logic in a table of options.
294*b3700b07SGordon Ross 		 * (including a flag for "optval required",
295*b3700b07SGordon Ross 		 * so that check could be factored out)
296*b3700b07SGordon Ross 		 */
297*b3700b07SGordon Ross 		for (cmd = commands; cmd->name; cmd++) {
298*b3700b07SGordon Ross 			if (!strcasecmp(optname, cmd->name)) {
299*b3700b07SGordon Ross 				/* cmd->name  requires an optval */
300*b3700b07SGordon Ross 				if (optval == NULL && optind < argc)
301*b3700b07SGordon Ross 					optval = argv[optind++];
302*b3700b07SGordon Ross 
303*b3700b07SGordon Ross 				if (optval == NULL && cmd->optreq > 0) {
304*b3700b07SGordon Ross 					(void) fprintf(stderr,
305*b3700b07SGordon Ross 					    "%s: option %s requires a value\n",
306*b3700b07SGordon Ross 					    argv[0], optname);
307*b3700b07SGordon Ross 					return (1);
308*b3700b07SGordon Ross 				}
309*b3700b07SGordon Ross 				option_cmd = optname;
310*b3700b07SGordon Ross 			}
311*b3700b07SGordon Ross 		}
312*b3700b07SGordon Ross 	}
313*b3700b07SGordon Ross 
314*b3700b07SGordon Ross 	/*
315*b3700b07SGordon Ross 	 * Handle remaining non-option arguments
316*b3700b07SGordon Ross 	 */
317*b3700b07SGordon Ross 	for (i = optind; i < argc; i++) {
318*b3700b07SGordon Ross 		(void) printf("arg: %s\n", argv[i]);
319*b3700b07SGordon Ross 	}
320*b3700b07SGordon Ross 
321*b3700b07SGordon Ross 	if (option_cmd == NULL)
322*b3700b07SGordon Ross 		help();
323*b3700b07SGordon Ross 
324*b3700b07SGordon Ross 	cmd = lookupcmd(option_cmd);
325*b3700b07SGordon Ross 	if (cmd == NULL)
326*b3700b07SGordon Ross 		err = 1;
327*b3700b07SGordon Ross 	else
328*b3700b07SGordon Ross 		err = cmd->fn(optval);
329*b3700b07SGordon Ross 
330*b3700b07SGordon Ross 	return (err);
331*b3700b07SGordon Ross }
332