2 * Samba Unix/Linux SMB client library
3 * Distributed SMB/CIFS Server Management Utility
4 * Nltest netlogon testing tool
6 * Copyright (C) Guenther Deschner 2009
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 3 of the License, or
11 * (at your option) any later version.
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
18 * You should have received a copy of the GNU General Public License
19 * along with this program. If not, see <http://www.gnu.org/licenses/>.
22 #include <sys/types.h>
57 OPT_TRY_NEXT_CLOSEST_SITE
,
65 /****************************************************************
66 ****************************************************************/
68 static void print_netlogon_info_result(uint32_t level
,
71 struct NETLOGON_INFO_1
*i1
= NULL
;
72 struct NETLOGON_INFO_2
*i2
= NULL
;
73 struct NETLOGON_INFO_3
*i3
= NULL
;
74 struct NETLOGON_INFO_4
*i4
= NULL
;
82 i1
= (struct NETLOGON_INFO_1
*)buffer
;
84 printf("Flags: %x\n", i1
->netlog1_flags
);
85 printf("Connection Status Status = %d 0x%x %s\n",
86 i1
->netlog1_pdc_connection_status
,
87 i1
->netlog1_pdc_connection_status
,
88 libnetapi_errstr(i1
->netlog1_pdc_connection_status
));
92 i2
= (struct NETLOGON_INFO_2
*)buffer
;
94 printf("Flags: %x\n", i2
->netlog2_flags
);
95 printf("Trusted DC Name %s\n", i2
->netlog2_trusted_dc_name
);
96 printf("Trusted DC Connection Status Status = %d 0x%x %s\n",
97 i2
->netlog2_tc_connection_status
,
98 i2
->netlog2_tc_connection_status
,
99 libnetapi_errstr(i2
->netlog2_tc_connection_status
));
100 printf("Trust Verification Status Status = %d 0x%x %s\n",
101 i2
->netlog2_pdc_connection_status
,
102 i2
->netlog2_pdc_connection_status
,
103 libnetapi_errstr(i2
->netlog2_pdc_connection_status
));
107 i3
= (struct NETLOGON_INFO_3
*)buffer
;
109 printf("Flags: %x\n", i3
->netlog1_flags
);
110 printf("Logon Attempts: %d\n", i3
->netlog3_logon_attempts
);
114 i4
= (struct NETLOGON_INFO_4
*)buffer
;
116 printf("Trusted DC Name %s\n", i4
->netlog4_trusted_dc_name
);
117 printf("Trusted Domain Name %s\n", i4
->netlog4_trusted_domain_name
);
125 /****************************************************************
126 ****************************************************************/
128 static void print_dc_info_flags(uint32_t flags
)
130 if (flags
& DS_PDC_FLAG
)
132 if (flags
& DS_GC_FLAG
)
134 if (flags
& DS_DS_FLAG
)
136 if (flags
& DS_LDAP_FLAG
)
138 if (flags
& DS_KDC_FLAG
)
140 if (flags
& DS_TIMESERV_FLAG
)
142 if (flags
& DS_GOOD_TIMESERV_FLAG
)
143 printf("GTIMESERV ");
144 if (flags
& DS_WRITABLE_FLAG
)
146 if (flags
& DS_DNS_FOREST_FLAG
)
147 printf("DNS_FOREST ");
148 if (flags
& DS_CLOSEST_FLAG
)
149 printf("CLOSE_SITE ");
150 if (flags
& DS_FULL_SECRET_DOMAIN_6_FLAG
)
151 printf("FULL_SECRET ");
156 /****************************************************************
157 ****************************************************************/
159 static void print_dc_info(struct DOMAIN_CONTROLLER_INFO
*dc_info
)
161 if (dc_info
->flags
) {
162 printf(" DC: %s\n", dc_info
->domain_controller_name
);
163 printf(" Address: %s\n", dc_info
->domain_controller_address
);
164 /* printf(" Dom Guid: %s\n", X(domain_guid)); */
165 printf(" Dom Name: %s\n", dc_info
->domain_name
);
166 printf(" Forest Name: %s\n", dc_info
->dns_forest_name
);
167 printf(" Dc Site Name: %s\n", dc_info
->dc_site_name
);
168 printf("Our Site Name: %s\n", dc_info
->client_site_name
);
170 print_dc_info_flags(dc_info
->flags
);
172 printf(" DC: %s\n", dc_info
->domain_controller_name
);
173 printf(" Address: %s\n", dc_info
->domain_controller_address
);
174 printf(" Dom Name: %s\n", dc_info
->domain_name
);
178 /****************************************************************
179 ****************************************************************/
181 int main(int argc
, const char **argv
)
184 NET_API_STATUS status
;
185 struct libnetapi_ctx
*ctx
= NULL
;
186 char *opt_server
= NULL
;
187 char *opt_domain
= NULL
;
194 int opt_timeserv
= 0;
195 int opt_gtimeserv
= 0;
201 int opt_writable
= 0;
202 int opt_avoidself
= 0;
203 int opt_ldaponly
= 0;
206 int opt_try_next_closest_site
= 0;
207 char *opt_site
= NULL
;
208 char *opt_account
= NULL
;
210 int opt_ret_netbios
= 0;
211 int opt_dsregdns
= 0;
212 uint32_t query_level
= 0;
213 uint8_t *buffer
= NULL
;
215 struct DOMAIN_CONTROLLER_INFO
*dc_info
= NULL
;
218 struct poptOption long_options
[] = {
220 {"server", 0, POPT_ARG_STRING
, &opt_server
, OPT_SERVER
, "Servername", "SERVER"},
221 {"dbflag", 0, POPT_ARG_INT
, &opt_dbflag
, OPT_DBFLAG
, "New Debug Flag", "HEXFLAGS"},
222 {"sc_query", 0, POPT_ARG_STRING
, &opt_domain
, OPT_SC_QUERY
, "Query secure channel for domain on server", "DOMAIN"},
223 {"sc_reset", 0, POPT_ARG_STRING
, &opt_domain
, OPT_SC_RESET
, "Reset secure channel for domain on server to dcname", "DOMAIN"},
224 {"sc_verify", 0, POPT_ARG_STRING
, &opt_domain
, OPT_SC_VERIFY
, "Verify secure channel for domain on server", "DOMAIN"},
225 {"sc_change_pwd", 0, POPT_ARG_STRING
, &opt_domain
, OPT_SC_CHANGE_PWD
, "Change a secure channel password for domain on server", "DOMAIN"},
226 {"dsgetdc", 0, POPT_ARG_STRING
, &opt_domain
, OPT_DSGETDC
, "Call DsGetDcName", "DOMAIN"},
227 {"pdc", 0, POPT_ARG_NONE
, &opt_pdc
, OPT_PDC
, NULL
},
228 {"ds", 0, POPT_ARG_NONE
, &opt_ds
, OPT_DS
, NULL
},
229 {"dsp", 0, POPT_ARG_NONE
, &opt_dsp
, OPT_DSP
, NULL
},
230 {"gc", 0, POPT_ARG_NONE
, &opt_gc
, OPT_GC
, NULL
},
231 {"kdc", 0, POPT_ARG_NONE
, &opt_kdc
, OPT_KDC
, NULL
},
232 {"timeserv", 0, POPT_ARG_NONE
, &opt_timeserv
, OPT_TIMESERV
, NULL
},
233 {"gtimeserv", 0, POPT_ARG_NONE
, &opt_gtimeserv
, OPT_GTIMESERV
, NULL
},
234 {"ws", 0, POPT_ARG_NONE
, &opt_ws
, OPT_WS
, NULL
},
235 {"netbios", 0, POPT_ARG_NONE
, &opt_netbios
, OPT_NETBIOS
, NULL
},
236 {"dns", 0, POPT_ARG_NONE
, &opt_dns
, OPT_DNS
, NULL
},
237 {"ip", 0, POPT_ARG_NONE
, &opt_ip
, OPT_IP
, NULL
},
238 {"force", 0, POPT_ARG_NONE
, &opt_force
, OPT_FORCE
, NULL
},
239 {"writable", 0, POPT_ARG_NONE
, &opt_writable
, OPT_WRITABLE
, NULL
},
240 {"avoidself", 0, POPT_ARG_NONE
, &opt_avoidself
, OPT_AVOIDSELF
, NULL
},
241 {"ldaponly", 0, POPT_ARG_NONE
, &opt_ldaponly
, OPT_LDAPONLY
, NULL
},
242 {"backg", 0, POPT_ARG_NONE
, &opt_backg
, OPT_BACKG
, NULL
},
243 {"ds_6", 0, POPT_ARG_NONE
, &opt_ds_6
, OPT_DS_6
, NULL
},
244 {"try_next_closest_site", 0, POPT_ARG_NONE
, &opt_try_next_closest_site
, OPT_TRY_NEXT_CLOSEST_SITE
, NULL
},
245 {"site", 0, POPT_ARG_STRING
, &opt_site
, OPT_SITE
, "SITE"},
246 {"account", 0, POPT_ARG_STRING
, &opt_account
, OPT_ACCOUNT
, "ACCOUNT"},
247 {"ret_dns", 0, POPT_ARG_NONE
, &opt_ret_dns
, OPT_RET_DNS
, NULL
},
248 {"ret_netbios", 0, POPT_ARG_NONE
, &opt_ret_netbios
, OPT_RET_NETBIOS
, NULL
},
249 {"dsregdns", 0, POPT_ARG_NONE
, &opt_dsregdns
, OPT_DSREGDNS
, "Force registration of all DC-specific DNS records"},
250 POPT_COMMON_LIBNETAPI_EXAMPLES
254 status
= libnetapi_init(&ctx
);
259 pc
= poptGetContext("nltest", argc
, argv
, long_options
, 0);
261 poptSetOtherOptionHelp(pc
, "<options>");
262 while((opt
= poptGetNextOpt(pc
)) != -1) {
266 poptPrintHelp(pc
, stderr
, 0);
270 poptResetContext(pc
);
272 while ((opt
= poptGetNextOpt(pc
)) != -1) {
277 if ((opt_server
[0] == '/' && opt_server
[1] == '/') ||
278 (opt_server
[0] == '\\' && opt_server
[1] == '\\')) {
286 status
= I_NetLogonControl2(opt_server
,
287 NETLOGON_CONTROL_SET_DBFLAG
,
289 (uint8_t *)opt_dbflag
,
292 fprintf(stderr
, "I_NetlogonControl failed: Status = %d 0x%x %s\n",
294 libnetapi_get_error_string(ctx
, status
));
298 print_netlogon_info_result(query_level
, buffer
);
303 status
= I_NetLogonControl2(opt_server
,
304 NETLOGON_CONTROL_TC_QUERY
,
306 (uint8_t *)opt_domain
,
309 fprintf(stderr
, "I_NetlogonControl failed: Status = %d 0x%x %s\n",
311 libnetapi_get_error_string(ctx
, status
));
315 print_netlogon_info_result(query_level
, buffer
);
320 status
= I_NetLogonControl2(opt_server
,
321 NETLOGON_CONTROL_TC_VERIFY
,
323 (uint8_t *)opt_domain
,
326 fprintf(stderr
, "I_NetlogonControl failed: Status = %d 0x%x %s\n",
328 libnetapi_get_error_string(ctx
, status
));
332 print_netlogon_info_result(query_level
, buffer
);
337 status
= I_NetLogonControl2(opt_server
,
338 NETLOGON_CONTROL_REDISCOVER
,
340 (uint8_t *)opt_domain
,
343 fprintf(stderr
, "I_NetlogonControl failed: Status = %d 0x%x %s\n",
345 libnetapi_get_error_string(ctx
, status
));
349 print_netlogon_info_result(query_level
, buffer
);
352 case OPT_SC_CHANGE_PWD
:
354 status
= I_NetLogonControl2(opt_server
,
355 NETLOGON_CONTROL_CHANGE_PASSWORD
,
357 (uint8_t *)opt_domain
,
360 fprintf(stderr
, "I_NetlogonControl failed: Status = %d 0x%x %s\n",
362 libnetapi_get_error_string(ctx
, status
));
366 print_netlogon_info_result(query_level
, buffer
);
371 status
= I_NetLogonControl2(opt_server
,
372 NETLOGON_CONTROL_FORCE_DNS_REG
,
377 fprintf(stderr
, "I_NetlogonControl failed: Status = %d 0x%x %s\n",
379 libnetapi_get_error_string(ctx
, status
));
383 print_netlogon_info_result(query_level
, buffer
);
388 flags
|= DS_PDC_REQUIRED
;
390 flags
|= DS_DIRECTORY_SERVICE_REQUIRED
;
392 flags
|= DS_DIRECTORY_SERVICE_PREFERRED
;
394 flags
|= DS_KDC_REQUIRED
;
396 flags
|= DS_TIMESERV_REQUIRED
;
398 flags
|= DS_GOOD_TIMESERV_PREFERRED
;
400 flags
|= DS_WEB_SERVICE_REQUIRED
;
402 flags
|= DS_IS_FLAT_NAME
;
404 flags
|= DS_IS_DNS_NAME
;
406 flags
|= DS_IP_REQUIRED
;
408 flags
|= DS_FORCE_REDISCOVERY
;
410 flags
|= DS_WRITABLE_REQUIRED
;
412 flags
|= DS_AVOID_SELF
;
414 flags
|= DS_ONLY_LDAP_NEEDED
;
416 flags
|= DS_BACKGROUND_ONLY
;
418 flags
|= DS_DIRECTORY_SERVICE_6_REQUIRED
;
419 if (opt_try_next_closest_site
)
420 flags
|= DS_TRY_NEXTCLOSEST_SITE
;
422 flags
|= DS_RETURN_DNS_NAME
;
424 flags
|= DS_RETURN_FLAT_NAME
;
426 status
= DsGetDcName(opt_server
,
428 NULL
, /* domain_guid */
433 fprintf(stderr
, "DsGetDcName failed: Status = %d 0x%x %s\n",
435 libnetapi_get_error_string(ctx
, status
));
439 print_dc_info(dc_info
);
447 printf("The command completed successfully\n");