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 ");
152 if (flags
& DS_WS_FLAG
)
154 if (flags
& DS_DS_8_FLAG
)
159 /****************************************************************
160 ****************************************************************/
162 static void print_dc_info(struct DOMAIN_CONTROLLER_INFO
*dc_info
)
164 if (dc_info
->flags
) {
165 printf(" DC: %s\n", dc_info
->domain_controller_name
);
166 printf(" Address: %s\n", dc_info
->domain_controller_address
);
167 /* printf(" Dom Guid: %s\n", X(domain_guid)); */
168 printf(" Dom Name: %s\n", dc_info
->domain_name
);
169 printf(" Forest Name: %s\n", dc_info
->dns_forest_name
);
170 printf(" Dc Site Name: %s\n", dc_info
->dc_site_name
);
171 printf("Our Site Name: %s\n", dc_info
->client_site_name
);
173 print_dc_info_flags(dc_info
->flags
);
175 printf(" DC: %s\n", dc_info
->domain_controller_name
);
176 printf(" Address: %s\n", dc_info
->domain_controller_address
);
177 printf(" Dom Name: %s\n", dc_info
->domain_name
);
181 /****************************************************************
182 ****************************************************************/
184 int main(int argc
, const char **argv
)
187 NET_API_STATUS status
;
188 struct libnetapi_ctx
*ctx
= NULL
;
189 char *opt_server
= NULL
;
190 char *opt_domain
= NULL
;
197 int opt_timeserv
= 0;
198 int opt_gtimeserv
= 0;
204 int opt_writable
= 0;
205 int opt_avoidself
= 0;
206 int opt_ldaponly
= 0;
209 int opt_try_next_closest_site
= 0;
210 char *opt_site
= NULL
;
211 char *opt_account
= NULL
;
213 int opt_ret_netbios
= 0;
214 int opt_dsregdns
= 0;
215 uint32_t query_level
= 0;
216 uint8_t *buffer
= NULL
;
218 struct DOMAIN_CONTROLLER_INFO
*dc_info
= NULL
;
221 struct poptOption long_options
[] = {
223 {"server", 0, POPT_ARG_STRING
, &opt_server
, OPT_SERVER
, "Servername", "SERVER"},
224 {"dbflag", 0, POPT_ARG_INT
, &opt_dbflag
, OPT_DBFLAG
, "New Debug Flag", "HEXFLAGS"},
225 {"sc_query", 0, POPT_ARG_STRING
, &opt_domain
, OPT_SC_QUERY
, "Query secure channel for domain on server", "DOMAIN"},
226 {"sc_reset", 0, POPT_ARG_STRING
, &opt_domain
, OPT_SC_RESET
, "Reset secure channel for domain on server to dcname", "DOMAIN"},
227 {"sc_verify", 0, POPT_ARG_STRING
, &opt_domain
, OPT_SC_VERIFY
, "Verify secure channel for domain on server", "DOMAIN"},
228 {"sc_change_pwd", 0, POPT_ARG_STRING
, &opt_domain
, OPT_SC_CHANGE_PWD
, "Change a secure channel password for domain on server", "DOMAIN"},
229 {"dsgetdc", 0, POPT_ARG_STRING
, &opt_domain
, OPT_DSGETDC
, "Call DsGetDcName", "DOMAIN"},
230 {"pdc", 0, POPT_ARG_NONE
, &opt_pdc
, OPT_PDC
, NULL
},
231 {"ds", 0, POPT_ARG_NONE
, &opt_ds
, OPT_DS
, NULL
},
232 {"dsp", 0, POPT_ARG_NONE
, &opt_dsp
, OPT_DSP
, NULL
},
233 {"gc", 0, POPT_ARG_NONE
, &opt_gc
, OPT_GC
, NULL
},
234 {"kdc", 0, POPT_ARG_NONE
, &opt_kdc
, OPT_KDC
, NULL
},
235 {"timeserv", 0, POPT_ARG_NONE
, &opt_timeserv
, OPT_TIMESERV
, NULL
},
236 {"gtimeserv", 0, POPT_ARG_NONE
, &opt_gtimeserv
, OPT_GTIMESERV
, NULL
},
237 {"ws", 0, POPT_ARG_NONE
, &opt_ws
, OPT_WS
, NULL
},
238 {"netbios", 0, POPT_ARG_NONE
, &opt_netbios
, OPT_NETBIOS
, NULL
},
239 {"dns", 0, POPT_ARG_NONE
, &opt_dns
, OPT_DNS
, NULL
},
240 {"ip", 0, POPT_ARG_NONE
, &opt_ip
, OPT_IP
, NULL
},
241 {"force", 0, POPT_ARG_NONE
, &opt_force
, OPT_FORCE
, NULL
},
242 {"writable", 0, POPT_ARG_NONE
, &opt_writable
, OPT_WRITABLE
, NULL
},
243 {"avoidself", 0, POPT_ARG_NONE
, &opt_avoidself
, OPT_AVOIDSELF
, NULL
},
244 {"ldaponly", 0, POPT_ARG_NONE
, &opt_ldaponly
, OPT_LDAPONLY
, NULL
},
245 {"backg", 0, POPT_ARG_NONE
, &opt_backg
, OPT_BACKG
, NULL
},
246 {"ds_6", 0, POPT_ARG_NONE
, &opt_ds_6
, OPT_DS_6
, NULL
},
247 {"try_next_closest_site", 0, POPT_ARG_NONE
, &opt_try_next_closest_site
, OPT_TRY_NEXT_CLOSEST_SITE
, NULL
},
248 {"site", 0, POPT_ARG_STRING
, &opt_site
, OPT_SITE
, "SITE"},
249 {"account", 0, POPT_ARG_STRING
, &opt_account
, OPT_ACCOUNT
, "ACCOUNT"},
250 {"ret_dns", 0, POPT_ARG_NONE
, &opt_ret_dns
, OPT_RET_DNS
, NULL
},
251 {"ret_netbios", 0, POPT_ARG_NONE
, &opt_ret_netbios
, OPT_RET_NETBIOS
, NULL
},
252 {"dsregdns", 0, POPT_ARG_NONE
, &opt_dsregdns
, OPT_DSREGDNS
, "Force registration of all DC-specific DNS records"},
253 POPT_COMMON_LIBNETAPI_EXAMPLES
257 status
= libnetapi_init(&ctx
);
262 pc
= poptGetContext("nltest", argc
, argv
, long_options
, 0);
264 poptSetOtherOptionHelp(pc
, "<options>");
265 while((opt
= poptGetNextOpt(pc
)) != -1) {
269 poptPrintHelp(pc
, stderr
, 0);
273 poptResetContext(pc
);
275 while ((opt
= poptGetNextOpt(pc
)) != -1) {
280 if ((opt_server
[0] == '/' && opt_server
[1] == '/') ||
281 (opt_server
[0] == '\\' && opt_server
[1] == '\\')) {
289 status
= I_NetLogonControl2(opt_server
,
290 NETLOGON_CONTROL_SET_DBFLAG
,
292 (uint8_t *)&opt_dbflag
,
295 fprintf(stderr
, "I_NetlogonControl failed: Status = %d 0x%x %s\n",
297 libnetapi_get_error_string(ctx
, status
));
301 print_netlogon_info_result(query_level
, buffer
);
306 status
= I_NetLogonControl2(opt_server
,
307 NETLOGON_CONTROL_TC_QUERY
,
309 (uint8_t *)opt_domain
,
312 fprintf(stderr
, "I_NetlogonControl failed: Status = %d 0x%x %s\n",
314 libnetapi_get_error_string(ctx
, status
));
318 print_netlogon_info_result(query_level
, buffer
);
323 status
= I_NetLogonControl2(opt_server
,
324 NETLOGON_CONTROL_TC_VERIFY
,
326 (uint8_t *)opt_domain
,
329 fprintf(stderr
, "I_NetlogonControl failed: Status = %d 0x%x %s\n",
331 libnetapi_get_error_string(ctx
, status
));
335 print_netlogon_info_result(query_level
, buffer
);
340 status
= I_NetLogonControl2(opt_server
,
341 NETLOGON_CONTROL_REDISCOVER
,
343 (uint8_t *)opt_domain
,
346 fprintf(stderr
, "I_NetlogonControl failed: Status = %d 0x%x %s\n",
348 libnetapi_get_error_string(ctx
, status
));
352 print_netlogon_info_result(query_level
, buffer
);
355 case OPT_SC_CHANGE_PWD
:
357 status
= I_NetLogonControl2(opt_server
,
358 NETLOGON_CONTROL_CHANGE_PASSWORD
,
360 (uint8_t *)opt_domain
,
363 fprintf(stderr
, "I_NetlogonControl failed: Status = %d 0x%x %s\n",
365 libnetapi_get_error_string(ctx
, status
));
369 print_netlogon_info_result(query_level
, buffer
);
374 status
= I_NetLogonControl2(opt_server
,
375 NETLOGON_CONTROL_FORCE_DNS_REG
,
380 fprintf(stderr
, "I_NetlogonControl failed: Status = %d 0x%x %s\n",
382 libnetapi_get_error_string(ctx
, status
));
386 print_netlogon_info_result(query_level
, buffer
);
391 flags
|= DS_PDC_REQUIRED
;
393 flags
|= DS_DIRECTORY_SERVICE_REQUIRED
;
395 flags
|= DS_DIRECTORY_SERVICE_PREFERRED
;
397 flags
|= DS_KDC_REQUIRED
;
399 flags
|= DS_TIMESERV_REQUIRED
;
401 flags
|= DS_GOOD_TIMESERV_PREFERRED
;
403 flags
|= DS_WEB_SERVICE_REQUIRED
;
405 flags
|= DS_IS_FLAT_NAME
;
407 flags
|= DS_IS_DNS_NAME
;
409 flags
|= DS_IP_REQUIRED
;
411 flags
|= DS_FORCE_REDISCOVERY
;
413 flags
|= DS_WRITABLE_REQUIRED
;
415 flags
|= DS_AVOID_SELF
;
417 flags
|= DS_ONLY_LDAP_NEEDED
;
419 flags
|= DS_BACKGROUND_ONLY
;
421 flags
|= DS_DIRECTORY_SERVICE_6_REQUIRED
;
422 if (opt_try_next_closest_site
)
423 flags
|= DS_TRY_NEXTCLOSEST_SITE
;
425 flags
|= DS_RETURN_DNS_NAME
;
427 flags
|= DS_RETURN_FLAT_NAME
;
429 status
= DsGetDcName(opt_server
,
431 NULL
, /* domain_guid */
436 fprintf(stderr
, "DsGetDcName failed: Status = %d 0x%x %s\n",
438 libnetapi_get_error_string(ctx
, status
));
442 print_dc_info(dc_info
);
450 printf("The command completed successfully\n");