s3:client: Fix old-style function definition
[Samba.git] / source3 / utils / testparm.c
blobe0455b9d7b6b9c5f8781efc4cc8b9137060e19a9
1 /*
2 Unix SMB/CIFS implementation.
3 Test validity of smb.conf
4 Copyright (C) Karl Auer 1993, 1994-1998
6 Extensively modified by Andrew Tridgell, 1995
7 Converted to popt by Jelmer Vernooij (jelmer@nl.linux.org), 2002
9 This program is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation; either version 3 of the License, or
12 (at your option) any later version.
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
19 You should have received a copy of the GNU General Public License
20 along with this program. If not, see <http://www.gnu.org/licenses/>.
24 * Testbed for loadparm.c/params.c
26 * This module simply loads a specified configuration file and
27 * if successful, dumps it's contents to stdout. Note that the
28 * operation is performed with DEBUGLEVEL at 3.
30 * Useful for a quick 'syntax check' of a configuration file.
34 #include "includes.h"
35 #include "system/filesys.h"
36 #include "lib/cmdline/cmdline.h"
37 #include "lib/param/loadparm.h"
38 #include "lib/crypto/gnutls_helpers.h"
39 #include "cmdline_contexts.h"
41 #include <regex.h>
43 /*******************************************************************
44 Check if a directory exists.
45 ********************************************************************/
47 static bool directory_exist_stat(const char *dname,SMB_STRUCT_STAT *st)
49 SMB_STRUCT_STAT st2;
50 bool ret;
52 if (!st)
53 st = &st2;
55 if (sys_stat(dname, st, false) != 0)
56 return(False);
58 ret = S_ISDIR(st->st_ex_mode);
59 if(!ret)
60 errno = ENOTDIR;
61 return ret;
64 struct idmap_config {
65 const char *domain_name;
66 const char *backend;
67 uint32_t high;
68 uint32_t low;
71 struct idmap_domains {
72 struct idmap_config *c;
73 uint32_t count;
74 uint32_t size;
77 static bool lp_scan_idmap_found_domain(const char *string,
78 regmatch_t matches[],
79 void *private_data)
81 bool ok = false;
83 if (matches[1].rm_so == -1) {
84 fprintf(stderr, "Found match, but no name - invalid idmap config");
85 return false;
87 if (matches[1].rm_eo <= matches[1].rm_so) {
88 fprintf(stderr, "Invalid match - invalid idmap config");
89 return false;
93 struct idmap_domains *d = private_data;
94 struct idmap_config *c = &d->c[d->count];
95 regoff_t len = matches[1].rm_eo - matches[1].rm_so;
96 char domname[len + 1];
98 if (d->count >= d->size) {
99 return false;
102 memcpy(domname, string + matches[1].rm_so, len);
103 domname[len] = '\0';
105 c->domain_name = talloc_strdup_upper(d->c, domname);
106 if (c->domain_name == NULL) {
107 return false;
109 c->backend = talloc_strdup(d->c, lp_idmap_backend(domname));
110 if (c->backend == NULL) {
111 return false;
114 if (lp_server_role() != ROLE_ACTIVE_DIRECTORY_DC) {
115 ok = lp_idmap_range(domname, &c->low, &c->high);
116 if (!ok) {
117 fprintf(stderr,
118 "ERROR: Invalid idmap range for domain "
119 "%s!\n\n",
120 c->domain_name);
121 return false;
125 d->count++;
128 return false; /* Keep scanning */
131 static int idmap_config_int(const char *domname, const char *option, int def)
133 int len = snprintf(NULL, 0, "idmap config %s", domname);
135 if (len == -1) {
136 return def;
139 char config_option[len+1];
140 snprintf(config_option, sizeof(config_option),
141 "idmap config %s", domname);
142 return lp_parm_int(-1, config_option, option, def);
146 static bool do_idmap_check(void)
148 struct idmap_domains *d;
149 uint32_t i;
150 bool ok = false;
151 int rc;
153 d = talloc_zero(talloc_tos(), struct idmap_domains);
154 if (d == NULL) {
155 return false;
157 d->count = 0;
158 d->size = 32;
160 d->c = talloc_array(d, struct idmap_config, d->size);
161 if (d->c == NULL) {
162 goto done;
165 rc = lp_wi_scan_global_parametrics("idmapconfig\\(.*\\):backend",
167 lp_scan_idmap_found_domain,
169 if (rc != 0) {
170 fprintf(stderr,
171 "FATAL: wi_scan_global_parametrics failed: %d",
172 rc);
175 /* Check autorid backend */
176 if (strequal(lp_idmap_default_backend(), "autorid")) {
177 struct idmap_config *c = NULL;
178 bool found = false;
180 for (i = 0; i < d->count; i++) {
181 c = &d->c[i];
183 if (strequal(c->backend, "autorid")) {
184 found = true;
185 break;
189 if (found) {
190 uint32_t rangesize =
191 idmap_config_int("*", "rangesize", 100000);
192 uint32_t maxranges =
193 (c->high - c->low + 1) / rangesize;
195 if (maxranges < 2) {
196 fprintf(stderr,
197 "ERROR: The idmap autorid range "
198 "[%u-%u] needs to be at least twice as "
199 "big as the rangesize [%u]!"
200 "\n\n",
201 c->low,
202 c->high,
203 rangesize);
204 ok = false;
205 goto done;
210 /* Check for overlapping idmap ranges */
211 for (i = 0; i < d->count; i++) {
212 struct idmap_config *c = &d->c[i];
213 uint32_t j;
215 for (j = 0; j < d->count && j != i; j++) {
216 struct idmap_config *x = &d->c[j];
218 if ((c->low >= x->low && c->low <= x->high) ||
219 (c->high >= x->low && c->high <= x->high)) {
220 /* Allow overlapping ranges for idmap_ad */
221 ok = strequal(c->backend, x->backend);
222 if (ok) {
223 ok = strequal(c->backend, "ad");
224 if (ok) {
225 fprintf(stderr,
226 "NOTE: The idmap_ad "
227 "range for the domain "
228 "%s overlaps with the "
229 "range of %s.\n\n",
230 c->domain_name,
231 x->domain_name);
232 continue;
236 fprintf(stderr,
237 "ERROR: The idmap range for the domain "
238 "%s (%s) overlaps with the range of "
239 "%s (%s)!\n\n",
240 c->domain_name,
241 c->backend,
242 x->domain_name,
243 x->backend);
244 ok = false;
245 goto done;
250 ok = true;
251 done:
252 TALLOC_FREE(d);
253 return ok;
256 /***********************************************
257 Here we do a set of 'hard coded' checks for bad
258 configuration settings.
259 ************************************************/
261 static int do_global_checks(void)
263 int ret = 0;
264 SMB_STRUCT_STAT st;
265 const char *socket_options;
266 const struct loadparm_substitution *lp_sub =
267 loadparm_s3_global_substitution();
269 fprintf(stderr, "\n");
271 if (lp_security() >= SEC_DOMAIN && !lp_encrypt_passwords()) {
272 fprintf(stderr, "ERROR: in 'security=domain' mode the "
273 "'encrypt passwords' parameter must always be "
274 "set to 'true'.\n\n");
275 ret = 1;
278 if (lp_security() == SEC_ADS) {
279 const char *workgroup = lp_workgroup();
280 const char *realm = lp_realm();
282 if (workgroup == NULL || strlen(workgroup) == 0) {
283 fprintf(stderr,
284 "ERROR: The 'security=ADS' mode requires "
285 "'workgroup' parameter to be set!\n\n ");
286 ret = 1;
289 if (realm == NULL || strlen(realm) == 0) {
290 fprintf(stderr,
291 "ERROR: The 'security=ADS' mode requires "
292 "'realm' parameter to be set!\n\n ");
293 ret = 1;
298 if (lp_we_are_a_wins_server() && lp_wins_server_list()) {
299 fprintf(stderr, "ERROR: both 'wins support = true' and "
300 "'wins server = <server list>' cannot be set in "
301 "the smb.conf file. nmbd will abort with this "
302 "setting.\n\n");
303 ret = 1;
306 if (strequal(lp_workgroup(), lp_netbios_name())) {
307 fprintf(stderr, "WARNING: 'workgroup' and 'netbios name' "
308 "must differ.\n\n");
311 if (lp_client_ipc_signing() == SMB_SIGNING_IF_REQUIRED
312 || lp_client_ipc_signing() == SMB_SIGNING_OFF) {
313 fprintf(stderr, "WARNING: The 'client ipc signing' value "
314 "%s SMB signing is not used when contacting a "
315 "domain controller or other server. "
316 "This setting is not recommended; please be "
317 "aware of the security implications when using "
318 "this configuration setting.\n\n",
319 lp_client_ipc_signing() == SMB_SIGNING_OFF ?
320 "ensures" : "may mean");
323 if (strlen(lp_netbios_name()) > 15) {
324 fprintf(stderr, "WARNING: The 'netbios name' is too long "
325 "(max. 15 chars).\n\n");
328 if (!directory_exist_stat(lp_lock_directory(), &st)) {
329 fprintf(stderr, "ERROR: lock directory %s does not exist\n\n",
330 lp_lock_directory());
331 ret = 1;
332 } else if ((st.st_ex_mode & 0777) != 0755) {
333 fprintf(stderr, "WARNING: lock directory %s should have "
334 "permissions 0755 for browsing to work\n\n",
335 lp_lock_directory());
338 if (!directory_exist_stat(lp_state_directory(), &st)) {
339 fprintf(stderr, "ERROR: state directory %s does not exist\n\n",
340 lp_state_directory());
341 ret = 1;
342 } else if ((st.st_ex_mode & 0777) != 0755) {
343 fprintf(stderr, "WARNING: state directory %s should have "
344 "permissions 0755 for browsing to work\n\n",
345 lp_state_directory());
348 if (!directory_exist_stat(lp_cache_directory(), &st)) {
349 fprintf(stderr, "ERROR: cache directory %s does not exist\n\n",
350 lp_cache_directory());
351 ret = 1;
352 } else if ((st.st_ex_mode & 0777) != 0755) {
353 fprintf(stderr, "WARNING: cache directory %s should have "
354 "permissions 0755 for browsing to work\n\n",
355 lp_cache_directory());
358 if (!directory_exist_stat(lp_pid_directory(), &st)) {
359 fprintf(stderr, "ERROR: pid directory %s does not exist\n\n",
360 lp_pid_directory());
361 ret = 1;
364 if (lp_passdb_expand_explicit()) {
365 fprintf(stderr, "WARNING: passdb expand explicit = yes is "
366 "deprecated\n\n");
370 * Socket options.
372 socket_options = lp_socket_options();
373 if (socket_options != NULL &&
374 (strstr(socket_options, "SO_SNDBUF") ||
375 strstr(socket_options, "SO_RCVBUF") ||
376 strstr(socket_options, "SO_SNDLOWAT") ||
377 strstr(socket_options, "SO_RCVLOWAT")))
379 fprintf(stderr,
380 "WARNING: socket options = %s\n"
381 "This warning is printed because you set one of the\n"
382 "following options: SO_SNDBUF, SO_RCVBUF, SO_SNDLOWAT,\n"
383 "SO_RCVLOWAT\n"
384 "Modern server operating systems are tuned for\n"
385 "high network performance in the majority of situations;\n"
386 "when you set 'socket options' you are overriding those\n"
387 "settings.\n"
388 "Linux in particular has an auto-tuning mechanism for\n"
389 "buffer sizes (SO_SNDBUF, SO_RCVBUF) that will be\n"
390 "disabled if you specify a socket buffer size. This can\n"
391 "potentially cripple your TCP/IP stack.\n\n"
392 "Getting the 'socket options' correct can make a big\n"
393 "difference to your performance, but getting them wrong\n"
394 "can degrade it by just as much. As with any other low\n"
395 "level setting, if you must make changes to it, make\n "
396 "small changes and test the effect before making any\n"
397 "large changes.\n\n",
398 socket_options);
402 * Password server sanity checks.
405 if((lp_security() >= SEC_DOMAIN) && !*lp_password_server()) {
406 const char *sec_setting;
407 if(lp_security() == SEC_DOMAIN)
408 sec_setting = "domain";
409 else if(lp_security() == SEC_ADS)
410 sec_setting = "ads";
411 else
412 sec_setting = "";
414 fprintf(stderr, "ERROR: The setting 'security=%s' requires the "
415 "'password server' parameter be set to the "
416 "default value * or a valid password server.\n\n",
417 sec_setting );
418 ret = 1;
421 if((lp_security() >= SEC_DOMAIN) && (strcmp(lp_password_server(), "*") != 0)) {
422 const char *sec_setting;
423 if(lp_security() == SEC_DOMAIN)
424 sec_setting = "domain";
425 else if(lp_security() == SEC_ADS)
426 sec_setting = "ads";
427 else
428 sec_setting = "";
430 fprintf(stderr, "WARNING: The setting 'security=%s' should NOT "
431 "be combined with the 'password server' "
432 "parameter.\n"
433 "(by default Samba will discover the correct DC "
434 "to contact automatically).\n\n",
435 sec_setting );
439 * Password chat sanity checks.
442 if(lp_security() == SEC_USER && lp_unix_password_sync()) {
445 * Check that we have a valid lp_passwd_program() if not using pam.
448 #ifdef WITH_PAM
449 if (!lp_pam_password_change()) {
450 #endif
452 if((lp_passwd_program(talloc_tos(), lp_sub) == NULL) ||
453 (strlen(lp_passwd_program(talloc_tos(), lp_sub)) == 0))
455 fprintf(stderr,
456 "ERROR: the 'unix password sync' "
457 "parameter is set and there is no valid "
458 "'passwd program' parameter.\n\n");
459 ret = 1;
460 } else {
461 const char *passwd_prog;
462 char *truncated_prog = NULL;
463 const char *p;
465 passwd_prog = lp_passwd_program(talloc_tos(), lp_sub);
466 p = passwd_prog;
467 next_token_talloc(talloc_tos(),
469 &truncated_prog, NULL);
470 if (truncated_prog && access(truncated_prog, F_OK) == -1) {
471 fprintf(stderr,
472 "ERROR: the 'unix password sync' "
473 "parameter is set and the "
474 "'passwd program' (%s) cannot be "
475 "executed (error was %s).\n\n",
476 truncated_prog,
477 strerror(errno));
478 ret = 1;
482 #ifdef WITH_PAM
484 #endif
486 if(lp_passwd_chat(talloc_tos(), lp_sub) == NULL) {
487 fprintf(stderr,
488 "ERROR: the 'unix password sync' parameter is "
489 "set and there is no valid 'passwd chat' "
490 "parameter.\n\n");
491 ret = 1;
494 if ((lp_passwd_program(talloc_tos(), lp_sub) != NULL) &&
495 (strlen(lp_passwd_program(talloc_tos(), lp_sub)) > 0))
497 /* check if there's a %u parameter present */
498 if(strstr_m(lp_passwd_program(talloc_tos(), lp_sub), "%u") == NULL) {
499 fprintf(stderr,
500 "ERROR: the 'passwd program' (%s) "
501 "requires a '%%u' parameter.\n\n",
502 lp_passwd_program(talloc_tos(), lp_sub));
503 ret = 1;
508 * Check that we have a valid script and that it hasn't
509 * been written to expect the old password.
512 if(lp_encrypt_passwords()) {
513 if(strstr_m( lp_passwd_chat(talloc_tos(), lp_sub), "%o")!=NULL) {
514 fprintf(stderr,
515 "ERROR: the 'passwd chat' script [%s] "
516 "expects to use the old plaintext "
517 "password via the %%o substitution. With "
518 "encrypted passwords this is not "
519 "possible.\n\n",
520 lp_passwd_chat(talloc_tos(), lp_sub) );
521 ret = 1;
526 if (strlen(lp_winbind_separator()) != 1) {
527 fprintf(stderr, "ERROR: the 'winbind separator' parameter must "
528 "be a single character.\n\n");
529 ret = 1;
532 if (*lp_winbind_separator() == '+') {
533 fprintf(stderr, "'winbind separator = +' might cause problems "
534 "with group membership.\n\n");
537 if (lp_algorithmic_rid_base() < BASE_RID) {
538 /* Try to prevent admin foot-shooting, we can't put algorithmic
539 rids below 1000, that's the 'well known RIDs' on NT */
540 fprintf(stderr, "'algorithmic rid base' must be equal to or "
541 "above %lu\n\n", BASE_RID);
544 if (lp_algorithmic_rid_base() & 1) {
545 fprintf(stderr, "'algorithmic rid base' must be even.\n\n");
548 if (lp_server_role() != ROLE_STANDALONE) {
549 const char *default_backends[] = {
550 "tdb", "tdb2", "ldap", "autorid", "hash"
552 const char *idmap_backend;
553 bool valid_backend = false;
554 uint32_t i;
555 bool ok;
557 idmap_backend = lp_idmap_default_backend();
559 for (i = 0; i < ARRAY_SIZE(default_backends); i++) {
560 ok = strequal(idmap_backend, default_backends[i]);
561 if (ok) {
562 valid_backend = true;
566 if (!valid_backend) {
567 ret = 1;
568 fprintf(stderr, "ERROR: Do not use the '%s' backend "
569 "as the default idmap backend!\n\n",
570 idmap_backend);
573 ok = do_idmap_check();
574 if (!ok) {
575 ret = 1;
579 #ifndef HAVE_DLOPEN
580 if (lp_preload_modules()) {
581 fprintf(stderr, "WARNING: 'preload modules = ' set while loading "
582 "plugins not supported.\n\n");
584 #endif
586 if (!lp_passdb_backend()) {
587 fprintf(stderr, "ERROR: passdb backend must have a value or be "
588 "left out\n\n");
591 if (lp_os_level() > 255) {
592 fprintf(stderr, "WARNING: Maximum value for 'os level' is "
593 "255!\n\n");
596 if (strequal(lp_dos_charset(), "UTF8") || strequal(lp_dos_charset(), "UTF-8")) {
597 fprintf(stderr, "ERROR: 'dos charset' must not be UTF8\n\n");
598 ret = 1;
601 if (!lp_server_schannel()) {
602 fprintf(stderr,
603 "WARNING: You have configured 'server schannel = no'. "
604 "Your server is vulernable to \"ZeroLogon\" "
605 "(CVE-2020-1472)\n\n");
608 return ret;
612 * per-share logic tests
614 static void do_per_share_checks(int s)
616 const struct loadparm_substitution *lp_sub =
617 loadparm_s3_global_substitution();
618 const char **deny_list = lp_hosts_deny(s);
619 const char **allow_list = lp_hosts_allow(s);
620 const char **vfs_objects = NULL;
621 int i;
622 static bool uses_fruit;
623 static bool doesnt_use_fruit;
624 static bool fruit_mix_warned;
626 if(deny_list) {
627 for (i=0; deny_list[i]; i++) {
628 char *hasstar = strchr_m(deny_list[i], '*');
629 char *hasquery = strchr_m(deny_list[i], '?');
630 if(hasstar || hasquery) {
631 fprintf(stderr,
632 "Invalid character %c in hosts deny list "
633 "(%s) for service %s.\n\n",
634 hasstar ? *hasstar : *hasquery,
635 deny_list[i],
636 lp_servicename(talloc_tos(), lp_sub, s));
641 if(allow_list) {
642 for (i=0; allow_list[i]; i++) {
643 char *hasstar = strchr_m(allow_list[i], '*');
644 char *hasquery = strchr_m(allow_list[i], '?');
645 if(hasstar || hasquery) {
646 fprintf(stderr,
647 "Invalid character %c in hosts allow "
648 "list (%s) for service %s.\n\n",
649 hasstar ? *hasstar : *hasquery,
650 allow_list[i],
651 lp_servicename(talloc_tos(), lp_sub, s));
656 if(lp_level2_oplocks(s) && !lp_oplocks(s)) {
657 fprintf(stderr, "Invalid combination of parameters for service "
658 "%s. Level II oplocks can only be set if oplocks "
659 "are also set.\n\n",
660 lp_servicename(talloc_tos(), lp_sub, s));
663 if (!lp_store_dos_attributes(s) && lp_map_hidden(s)
664 && !(lp_create_mask(s) & S_IXOTH))
666 fprintf(stderr,
667 "Invalid combination of parameters for service %s. Map "
668 "hidden can only work if create mask includes octal "
669 "01 (S_IXOTH).\n\n",
670 lp_servicename(talloc_tos(), lp_sub, s));
672 if (!lp_store_dos_attributes(s) && lp_map_hidden(s)
673 && (lp_force_create_mode(s) & S_IXOTH))
675 fprintf(stderr,
676 "Invalid combination of parameters for service "
677 "%s. Map hidden can only work if force create mode "
678 "excludes octal 01 (S_IXOTH).\n\n",
679 lp_servicename(talloc_tos(), lp_sub, s));
681 if (!lp_store_dos_attributes(s) && lp_map_system(s)
682 && !(lp_create_mask(s) & S_IXGRP))
684 fprintf(stderr,
685 "Invalid combination of parameters for service "
686 "%s. Map system can only work if create mask includes "
687 "octal 010 (S_IXGRP).\n\n",
688 lp_servicename(talloc_tos(), lp_sub, s));
690 if (!lp_store_dos_attributes(s) && lp_map_system(s)
691 && (lp_force_create_mode(s) & S_IXGRP))
693 fprintf(stderr,
694 "Invalid combination of parameters for service "
695 "%s. Map system can only work if force create mode "
696 "excludes octal 010 (S_IXGRP).\n\n",
697 lp_servicename(talloc_tos(), lp_sub, s));
699 if (lp_printing(s) == PRINT_CUPS && *(lp_print_command(s)) != '\0') {
700 fprintf(stderr,
701 "Warning: Service %s defines a print command, but "
702 "parameter is ignored when using CUPS libraries.\n\n",
703 lp_servicename(talloc_tos(), lp_sub, s));
706 vfs_objects = lp_vfs_objects(s);
707 if (vfs_objects && str_list_check(vfs_objects, "fruit")) {
708 uses_fruit = true;
709 } else {
710 doesnt_use_fruit = true;
713 if (uses_fruit && doesnt_use_fruit && !fruit_mix_warned) {
714 fruit_mix_warned = true;
715 fprintf(stderr,
716 "WARNING: some services use vfs_fruit, others don't. Mounting them "
717 "in conjunction on OS X clients results in undefined behaviour.\n\n");
721 int main(int argc, const char *argv[])
723 const char *config_file = NULL;
724 const struct loadparm_substitution *lp_sub =
725 loadparm_s3_global_substitution();
726 int opt;
727 int s;
728 static int silent_mode = False;
729 static int show_all_parameters = False;
730 int ret = 0;
731 poptContext pc;
732 static char *parameter_name = NULL;
733 static const char *section_name = NULL;
734 const char *cname;
735 const char *caddr;
736 static int show_defaults;
737 static int skip_logic_checks = 0;
738 bool ok;
740 struct poptOption long_options[] = {
741 POPT_AUTOHELP
743 .longName = "suppress-prompt",
744 .shortName = 's',
745 .argInfo = POPT_ARG_VAL,
746 .arg = &silent_mode,
747 .val = 1,
748 .descrip = "Suppress prompt for enter",
751 .longName = "verbose",
752 .shortName = 'v',
753 .argInfo = POPT_ARG_NONE,
754 .arg = &show_defaults,
755 .val = 1,
756 .descrip = "Show default options too",
759 .longName = "skip-logic-checks",
760 .shortName = 'l',
761 .argInfo = POPT_ARG_NONE,
762 .arg = &skip_logic_checks,
763 .val = 1,
764 .descrip = "Skip the global checks",
767 .longName = "show-all-parameters",
768 .shortName = '\0',
769 .argInfo = POPT_ARG_VAL,
770 .arg = &show_all_parameters,
771 .val = True,
772 .descrip = "Show the parameters, type, possible "
773 "values",
776 .longName = "parameter-name",
777 .shortName = '\0',
778 .argInfo = POPT_ARG_STRING,
779 .arg = &parameter_name,
780 .val = 0,
781 .descrip = "Limit testparm to a named parameter",
784 .longName = "section-name",
785 .shortName = '\0',
786 .argInfo = POPT_ARG_STRING,
787 .arg = &section_name,
788 .val = 0,
789 .descrip = "Limit testparm to a named section",
791 POPT_COMMON_DEBUG_ONLY
792 POPT_COMMON_OPTION_ONLY
793 POPT_COMMON_VERSION
794 POPT_TABLEEND
797 TALLOC_CTX *frame = talloc_stackframe();
799 smb_init_locale();
801 ok = samba_cmdline_init(frame,
802 SAMBA_CMDLINE_CONFIG_NONE,
803 true /* require_smbconf */);
804 if (!ok) {
805 DBG_ERR("Failed to init cmdline parser!\n");
806 ret = 1;
807 goto done;
811 * Set the default debug level to 1.
812 * Allow it to be overridden by the command line,
813 * not by smb.conf.
815 lp_set_cmdline("log level", "1");
817 pc = samba_popt_get_context(getprogname(),
818 argc,
819 argv,
820 long_options,
822 if (pc == NULL) {
823 DBG_ERR("Failed to setup popt context!\n");
824 ret = 1;
825 goto done;
828 poptSetOtherOptionHelp(pc, "[OPTION...] <config-file> [host-name] [host-ip]");
830 while ((opt = poptGetNextOpt(pc)) != -1) {
831 switch (opt) {
832 case POPT_ERROR_BADOPT:
833 fprintf(stderr, "\nInvalid option %s: %s\n\n",
834 poptBadOption(pc, 0), poptStrerror(opt));
835 poptPrintUsage(pc, stderr, 0);
836 exit(1);
840 if (show_all_parameters) {
841 show_parameter_list();
842 exit(0);
845 if (poptPeekArg(pc)) {
846 config_file = talloc_strdup(frame, poptGetArg(pc));
847 if (config_file == NULL) {
848 DBG_ERR("out of memory\n");
849 TALLOC_FREE(frame);
850 exit(1);
852 } else {
853 config_file = get_dyn_CONFIGFILE();
856 cname = talloc_strdup(frame, poptGetArg(pc));
857 caddr = talloc_strdup(frame, poptGetArg(pc));
859 poptFreeContext(pc);
861 if ( cname && ! caddr ) {
862 printf ( "ERROR: You must specify both a machine name and an IP address.\n" );
863 ret = 1;
864 goto done;
867 fprintf(stderr,"Load smb config files from %s\n",config_file);
869 if (!lp_load_with_registry_shares(config_file)) {
870 fprintf(stderr,"Error loading services.\n");
871 ret = 1;
872 goto done;
875 fprintf(stderr,"Loaded services file OK.\n");
877 fprintf(stderr,
878 "Weak crypto is %sallowed by GnuTLS "
879 "(e.g. NTLM as a compatibility fallback)\n",
880 samba_gnutls_weak_crypto_allowed() ? "" : "dis");
882 if (skip_logic_checks == 0) {
883 ret = do_global_checks();
886 for (s=0;s<1000;s++) {
887 if (VALID_SNUM(s) && (skip_logic_checks == 0)) {
888 do_per_share_checks(s);
893 if (!section_name && !parameter_name) {
894 fprintf(stderr,
895 "Server role: %s\n\n",
896 server_role_str(lp_server_role()));
899 if (!cname) {
900 if (!silent_mode) {
901 fprintf(stderr,"Press enter to see a dump of your service definitions\n");
902 fflush(stdout);
903 getc(stdin);
905 if (parameter_name || section_name) {
906 bool isGlobal = False;
907 s = GLOBAL_SECTION_SNUM;
909 if (!section_name) {
910 section_name = GLOBAL_NAME;
911 isGlobal = True;
912 } else if ((isGlobal=!strwicmp(section_name, GLOBAL_NAME)) == 0 &&
913 (s=lp_servicenumber(section_name)) == -1) {
914 fprintf(stderr,"Unknown section %s\n",
915 section_name);
916 ret = 1;
917 goto done;
919 if (parameter_name) {
920 if (!dump_a_parameter( s, parameter_name, stdout, isGlobal)) {
921 fprintf(stderr,"Parameter %s unknown for section %s\n",
922 parameter_name, section_name);
923 ret = 1;
924 goto done;
926 } else {
927 if (isGlobal == True)
928 lp_dump(stdout, show_defaults, 0);
929 else
930 lp_dump_one(stdout, show_defaults, s);
932 goto done;
935 lp_dump(stdout, show_defaults, lp_numservices());
938 if(cname && caddr){
939 /* this is totally ugly, a real `quick' hack */
940 for (s=0;s<1000;s++) {
941 if (VALID_SNUM(s)) {
942 if (allow_access(lp_hosts_deny(-1), lp_hosts_allow(-1), cname, caddr)
943 && allow_access(lp_hosts_deny(s), lp_hosts_allow(s), cname, caddr)) {
944 fprintf(stderr,"Allow connection from %s (%s) to %s\n",
945 cname,caddr,lp_servicename(talloc_tos(), lp_sub, s));
946 } else {
947 fprintf(stderr,"Deny connection from %s (%s) to %s\n",
948 cname,caddr,lp_servicename(talloc_tos(), lp_sub, s));
954 done:
955 gfree_loadparm();
956 TALLOC_FREE(frame);
957 return ret;