1 /*
2  * adcli
3  *
4  * Copyright (C) 2013 Red Hat Inc.
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU Lesser General Public License as
8  * published by the Free Software Foundation; either version 2.1 of
9  * the License, or (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful, but
12  * WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with this program; if not, write to the Free Software
18  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
19  * MA 02110-1301 USA
20  *
21  * Author: Stef Walter <stefw@redhat.com>
22  */
23 
24 #include "config.h"
25 
26 #include "adcli.h"
27 #include "tools.h"
28 
29 #include <assert.h>
30 #include <err.h>
31 #include <stdio.h>
32 
33 typedef enum {
34 	/* Have short equivalents */
35 	opt_domain = 'D',
36 	opt_domain_controller = 'S',
37 	opt_verbose = 'v',
38 } Option;
39 
40 static adcli_tool_desc common_usages[] = {
41 	{ opt_domain, "active directory domain name" },
42 	{ opt_domain_controller, "domain controller to connect to" },
43 	{ opt_verbose, "show verbose progress and failure messages", },
44 	{ 0 },
45 };
46 
47 static void
print_info(adcli_disco * disco,int for_host)48 print_info (adcli_disco *disco,
49             int for_host)
50 {
51 	adcli_disco *other;
52 
53 	printf ("[domain]\n");
54 	if (disco->domain)
55 		printf ("domain-name = %s\n", disco->domain);
56 	if (disco->domain_short)
57 		printf ("domain-short = %s\n", disco->domain_short);
58 	if (disco->forest)
59 		printf ("domain-forest = %s\n", disco->forest);
60 	if (disco->host_name)
61 		printf ("domain-controller = %s\n", disco->host_name);
62 	if (disco->server_site)
63 		printf ("domain-controller-site = %s\n", disco->server_site);
64 	if (disco->flags) {
65 		printf ("domain-controller-flags =");
66 		if (disco->flags & ADCLI_DISCO_PDC) printf (" pdc");
67 		if (disco->flags & ADCLI_DISCO_GC) printf (" gc");
68 		if (disco->flags & ADCLI_DISCO_LDAP) printf (" ldap");
69 		if (disco->flags & ADCLI_DISCO_DS) printf (" ds");
70 		if (disco->flags & ADCLI_DISCO_KDC) printf (" kdc");
71 		if (disco->flags & ADCLI_DISCO_TIMESERV) printf (" timeserv");
72 		if (disco->flags & ADCLI_DISCO_CLOSEST) printf (" closest");
73 		if (disco->flags & ADCLI_DISCO_WRITABLE) printf (" writable");
74 		if (disco->flags & ADCLI_DISCO_GOOD_TIMESERV) printf (" good-timeserv");
75 		if (disco->flags & ADCLI_DISCO_NDNC) printf (" ndnc");
76 		if (disco->flags & ADCLI_DISCO_SELECT_SECRET_DOMAIN_6) printf (" select-secret");
77 		if (disco->flags & ADCLI_DISCO_FULL_SECRET_DOMAIN_6) printf (" full-secret");
78 		if (disco->flags & ADCLI_DISCO_ADS_WEB_SERVICE) printf (" ads-web");
79 		if (disco->flags & ADCLI_DISCO_HAS_DNS_NAME) printf (" dns-name");
80 		if (disco->flags & ADCLI_DISCO_IS_DEFAULT_NC) printf (" default-nc");
81 		if (disco->flags & ADCLI_DISCO_FOREST_ROOT) printf (" forest-root");
82 		printf ("\n");
83 	}
84 
85 	switch (adcli_disco_usable (disco)) {
86 	case ADCLI_DISCO_UNUSABLE:
87 		printf ("domain-controller-usable = no\n");
88 		break;
89 	case ADCLI_DISCO_MAYBE:
90 		printf ("domain-controller-usable = maybe\n");
91 		break;
92 	case ADCLI_DISCO_USABLE:
93 		printf ("domain-controller-usable = yes\n");
94 		break;
95 	default:
96 		break;
97 	}
98 
99 	if (!for_host && disco->host_name) {
100 		printf ("domain-controllers =");
101 		for (other = disco; other != NULL; other = other->next) {
102 			if (other->host_name)
103 				printf (" %s", other->host_name);
104 		}
105 		printf ("\n");
106 	}
107 
108 	printf ("[computer]\n");
109 	if (disco->client_site)
110 		printf ("computer-site = %s\n", disco->client_site);
111 
112 }
113 
114 int
adcli_tool_info(adcli_conn * unused,int argc,char * argv[])115 adcli_tool_info (adcli_conn *unused,
116                  int argc,
117                  char *argv[])
118 {
119 	const char *domain = NULL;
120 	const char *server = NULL;
121 	adcli_disco *disco = NULL;
122 	int for_host;
123 	int opt;
124 
125 	struct option options[] = {
126 		{ "domain", required_argument, NULL, opt_domain },
127 		{ "domain-controller", required_argument, NULL, opt_domain_controller },
128 		{ "verbose", no_argument, NULL, opt_verbose },
129 		{ "help", no_argument, NULL, 'h' },
130 		{ 0 },
131 	};
132 
133 	static adcli_tool_desc usages[] = {
134 		{ 0, "usage: adcli info <domain>" },
135 		{ 0 },
136 	};
137 
138 	while ((opt = adcli_tool_getopt (argc, argv, options)) != -1) {
139 		switch (opt) {
140 		case opt_domain:
141 			domain = optarg;
142 			break;
143 		case opt_domain_controller:
144 			server = optarg;
145 			break;
146 		case opt_verbose:
147 			break;
148 		case 'h':
149 		case '?':
150 		case ':':
151 			adcli_tool_usage (options, usages);
152 			adcli_tool_usage (options, common_usages);
153 			return opt == 'h' ? 0 : 2;
154 		default:
155 			assert (0 && "not reached");
156 			break;
157 		}
158 	}
159 
160 	argc -= optind;
161 	argv += optind;
162 
163 	if (argc == 1)
164 		domain = argv[0];
165 	else if (argc != 0) {
166 		warnx ("specify one user name to create");
167 		return 2;
168 	}
169 
170 	if (server) {
171 		adcli_disco_host (server, &disco);
172 		if (disco == NULL) {
173 			warnx ("couldn't discover domain controller: %s", server);
174 			return 1;
175 		}
176 		for_host = 1;
177 	} else if (domain) {
178 		adcli_disco_domain (domain, &disco);
179 		if (disco == NULL) {
180 			warnx ("couldn't discover domain: %s", domain);
181 			return 1;
182 		}
183 		for_host = 0;
184 	} else {
185 		warnx ("specify a domain to discover");
186 		return 2;
187 	}
188 
189 	print_info (disco, for_host);
190 	adcli_disco_free (disco);
191 
192 	return 0;
193 }
194