s3:utils: Do not report an invalid range for AD DC role
[metze/samba/wip.git] / source3 / utils / testparm.c
1 /*
2    Unix SMB/CIFS implementation.
3    Test validity of smb.conf
4    Copyright (C) Karl Auer 1993, 1994-1998
5
6    Extensively modified by Andrew Tridgell, 1995
7    Converted to popt by Jelmer Vernooij (jelmer@nl.linux.org), 2002
8
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.
13
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.
18
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/>.
21 */
22
23 /*
24  * Testbed for loadparm.c/params.c
25  *
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.
29  *
30  * Useful for a quick 'syntax check' of a configuration file.
31  *
32  */
33
34 #include "includes.h"
35 #include "system/filesys.h"
36 #include "popt_common.h"
37 #include "lib/param/loadparm.h"
38
39 #include <regex.h>
40
41 /*******************************************************************
42  Check if a directory exists.
43 ********************************************************************/
44
45 static bool directory_exist_stat(const char *dname,SMB_STRUCT_STAT *st)
46 {
47         SMB_STRUCT_STAT st2;
48         bool ret;
49
50         if (!st)
51                 st = &st2;
52
53         if (sys_stat(dname, st, false) != 0)
54                 return(False);
55
56         ret = S_ISDIR(st->st_ex_mode);
57         if(!ret)
58                 errno = ENOTDIR;
59         return ret;
60 }
61
62 struct idmap_config {
63         const char *domain_name;
64         const char *backend;
65         uint32_t high;
66         uint32_t low;
67 };
68
69 struct idmap_domains {
70         struct idmap_config *c;
71         uint32_t count;
72         uint32_t size;
73 };
74
75 static bool lp_scan_idmap_found_domain(const char *string,
76                                        regmatch_t matches[],
77                                        void *private_data)
78 {
79         bool ok = false;
80
81         if (matches[1].rm_so == -1) {
82                 fprintf(stderr, "Found match, but no name - invalid idmap config");
83                 return false;
84         }
85         if (matches[1].rm_eo <= matches[1].rm_so) {
86                 fprintf(stderr, "Invalid match - invalid idmap config");
87                 return false;
88         }
89
90         {
91                 struct idmap_domains *d = private_data;
92                 struct idmap_config *c = &d->c[d->count];
93                 regoff_t len = matches[1].rm_eo - matches[1].rm_so;
94                 char domname[len + 1];
95
96                 if (d->count >= d->size) {
97                         return false;
98                 }
99
100                 memcpy(domname, string + matches[1].rm_so, len);
101                 domname[len] = '\0';
102
103                 c->domain_name = talloc_strdup_upper(d->c, domname);
104                 if (c->domain_name == NULL) {
105                         return false;
106                 }
107                 c->backend = talloc_strdup(d->c, lp_idmap_backend(domname));
108                 if (c->backend == NULL) {
109                         return false;
110                 }
111
112                 if (lp_server_role() != ROLE_ACTIVE_DIRECTORY_DC) {
113                         ok = lp_idmap_range(domname, &c->low, &c->high);
114                         if (!ok) {
115                                 fprintf(stderr,
116                                         "ERROR: Invalid idmap range for domain "
117                                         "%s!\n\n",
118                                         c->domain_name);
119                                 return false;
120                         }
121                 }
122
123                 d->count++;
124         }
125
126         return false; /* Keep scanning */
127 }
128
129 static bool do_idmap_check(void)
130 {
131         struct idmap_domains *d;
132         uint32_t i;
133         bool ok = false;
134         int rc;
135
136         d = talloc_zero(talloc_tos(), struct idmap_domains);
137         if (d == NULL) {
138                 return false;
139         }
140         d->count = 0;
141         d->size = 32;
142
143         d->c = talloc_array(d, struct idmap_config, d->size);
144         if (d->c == NULL) {
145                 goto done;
146         }
147
148         rc = lp_wi_scan_global_parametrics("idmapconfig\\(.*\\):backend",
149                                            2,
150                                            lp_scan_idmap_found_domain,
151                                            d);
152         if (rc != 0) {
153                 fprintf(stderr,
154                         "FATAL: wi_scan_global_parametrics failed: %d",
155                         rc);
156         }
157
158         for (i = 0; i < d->count; i++) {
159                 struct idmap_config *c = &d->c[i];
160                 uint32_t j;
161
162                 for (j = 0; j < d->count && j != i; j++) {
163                         struct idmap_config *x = &d->c[j];
164
165                         if ((c->low >= x->low && c->low <= x->high) ||
166                             (c->high >= x->low && c->high <= x->high)) {
167                                 /* Allow overlapping ranges for idmap_ad */
168                                 ok = strequal(c->backend, x->backend);
169                                 if (ok) {
170                                         ok = strequal(c->backend, "ad");
171                                         if (ok) {
172                                                 fprintf(stderr,
173                                                         "NOTE: The idmap_ad "
174                                                         "range for the domain "
175                                                         "%s overlaps with the "
176                                                         "range of %s.\n\n",
177                                                         c->domain_name,
178                                                         x->domain_name);
179                                                 continue;
180                                         }
181                                 }
182
183                                 fprintf(stderr,
184                                         "ERROR: The idmap range for the domain "
185                                         "%s (%s) overlaps with the range of "
186                                         "%s (%s)!\n\n",
187                                         c->domain_name,
188                                         c->backend,
189                                         x->domain_name,
190                                         x->backend);
191                                 ok = false;
192                                 goto done;
193                         }
194                 }
195         }
196
197         ok = true;
198 done:
199         TALLOC_FREE(d);
200         return ok;
201 }
202
203 /***********************************************
204  Here we do a set of 'hard coded' checks for bad
205  configuration settings.
206 ************************************************/
207
208 static int do_global_checks(void)
209 {
210         int ret = 0;
211         SMB_STRUCT_STAT st;
212         const char *socket_options;
213
214         if (lp_security() >= SEC_DOMAIN && !lp_encrypt_passwords()) {
215                 fprintf(stderr, "ERROR: in 'security=domain' mode the "
216                                 "'encrypt passwords' parameter must always be "
217                                 "set to 'true'.\n\n");
218                 ret = 1;
219         }
220
221         if (lp_we_are_a_wins_server() && lp_wins_server_list()) {
222                 fprintf(stderr, "ERROR: both 'wins support = true' and "
223                                 "'wins server = <server list>' cannot be set in "
224                                 "the smb.conf file. nmbd will abort with this "
225                                 "setting.\n\n");
226                 ret = 1;
227         }
228
229         if (strequal(lp_workgroup(), lp_netbios_name())) {
230                 fprintf(stderr, "WARNING: 'workgroup' and 'netbios name' "
231                                 "must differ.\n\n");
232         }
233
234         if (lp_client_ipc_signing() == SMB_SIGNING_IF_REQUIRED
235          || lp_client_ipc_signing() == SMB_SIGNING_OFF) {
236                 fprintf(stderr, "WARNING: The 'client ipc signing' value "
237                         "%s SMB signing is not used when contacting a "
238                         "domain controller or other server. "
239                         "This setting is not recommended; please be "
240                         "aware of the security implications when using "
241                         "this configuration setting.\n\n",
242                         lp_client_ipc_signing() == SMB_SIGNING_OFF ?
243                         "ensures" : "may mean");
244         }
245
246         if (strlen(lp_netbios_name()) > 15) {
247                 fprintf(stderr, "WARNING: The 'netbios name' is too long "
248                                 "(max. 15 chars).\n\n");
249         }
250
251         if (!directory_exist_stat(lp_lock_directory(), &st)) {
252                 fprintf(stderr, "ERROR: lock directory %s does not exist\n\n",
253                        lp_lock_directory());
254                 ret = 1;
255         } else if ((st.st_ex_mode & 0777) != 0755) {
256                 fprintf(stderr, "WARNING: lock directory %s should have "
257                                 "permissions 0755 for browsing to work\n\n",
258                        lp_lock_directory());
259         }
260
261         if (!directory_exist_stat(lp_state_directory(), &st)) {
262                 fprintf(stderr, "ERROR: state directory %s does not exist\n\n",
263                        lp_state_directory());
264                 ret = 1;
265         } else if ((st.st_ex_mode & 0777) != 0755) {
266                 fprintf(stderr, "WARNING: state directory %s should have "
267                                 "permissions 0755 for browsing to work\n\n",
268                        lp_state_directory());
269         }
270
271         if (!directory_exist_stat(lp_cache_directory(), &st)) {
272                 fprintf(stderr, "ERROR: cache directory %s does not exist\n\n",
273                        lp_cache_directory());
274                 ret = 1;
275         } else if ((st.st_ex_mode & 0777) != 0755) {
276                 fprintf(stderr, "WARNING: cache directory %s should have "
277                                 "permissions 0755 for browsing to work\n\n",
278                        lp_cache_directory());
279         }
280
281         if (!directory_exist_stat(lp_pid_directory(), &st)) {
282                 fprintf(stderr, "ERROR: pid directory %s does not exist\n\n",
283                        lp_pid_directory());
284                 ret = 1;
285         }
286
287         if (lp_passdb_expand_explicit()) {
288                 fprintf(stderr, "WARNING: passdb expand explicit = yes is "
289                                 "deprecated\n\n");
290         }
291
292         /*
293          * Socket options.
294          */
295         socket_options = lp_socket_options();
296         if (socket_options != NULL &&
297             (strstr(socket_options, "SO_SNDBUF") ||
298              strstr(socket_options, "SO_RCVBUF") ||
299              strstr(socket_options, "SO_SNDLOWAT") ||
300              strstr(socket_options, "SO_RCVLOWAT")))
301         {
302                 fprintf(stderr,
303                         "WARNING: socket options = %s\n"
304                         "This warning is printed because you set one of the\n"
305                         "following options: SO_SNDBUF, SO_RCVBUF, SO_SNDLOWAT,\n"
306                         "SO_RCVLOWAT\n"
307                         "Modern server operating systems are tuned for\n"
308                         "high network performance in the majority of situations;\n"
309                         "when you set 'socket options' you are overriding those\n"
310                         "settings.\n"
311                         "Linux in particular has an auto-tuning mechanism for\n"
312                         "buffer sizes (SO_SNDBUF, SO_RCVBUF) that will be\n"
313                         "disabled if you specify a socket buffer size. This can\n"
314                         "potentially cripple your TCP/IP stack.\n\n"
315                         "Getting the 'socket options' correct can make a big\n"
316                         "difference to your performance, but getting them wrong\n"
317                         "can degrade it by just as much. As with any other low\n"
318                         "level setting, if you must make changes to it, make\n "
319                         "small changes and test the effect before making any\n"
320                         "large changes.\n\n",
321                         socket_options);
322         }
323
324         /*
325          * Password server sanity checks.
326          */
327
328         if((lp_security() >= SEC_DOMAIN) && !*lp_password_server()) {
329                 const char *sec_setting;
330                 if(lp_security() == SEC_DOMAIN)
331                         sec_setting = "domain";
332                 else if(lp_security() == SEC_ADS)
333                         sec_setting = "ads";
334                 else
335                         sec_setting = "";
336
337                 fprintf(stderr, "ERROR: The setting 'security=%s' requires the "
338                                 "'password server' parameter be set to the "
339                                 "default value * or a valid password server.\n\n",
340                                 sec_setting );
341                 ret = 1;
342         }
343
344         if((lp_security() >= SEC_DOMAIN) && (strcmp(lp_password_server(), "*") != 0)) {
345                 const char *sec_setting;
346                 if(lp_security() == SEC_DOMAIN)
347                         sec_setting = "domain";
348                 else if(lp_security() == SEC_ADS)
349                         sec_setting = "ads";
350                 else
351                         sec_setting = "";
352
353                 fprintf(stderr, "WARNING: The setting 'security=%s' should NOT "
354                                 "be combined with the 'password server' "
355                                 "parameter.\n"
356                                 "(by default Samba will discover the correct DC "
357                                 "to contact automatically).\n\n",
358                                 sec_setting );
359         }
360
361         /*
362          * Password chat sanity checks.
363          */
364
365         if(lp_security() == SEC_USER && lp_unix_password_sync()) {
366
367                 /*
368                  * Check that we have a valid lp_passwd_program() if not using pam.
369                  */
370
371 #ifdef WITH_PAM
372                 if (!lp_pam_password_change()) {
373 #endif
374
375                         if((lp_passwd_program(talloc_tos()) == NULL) ||
376                            (strlen(lp_passwd_program(talloc_tos())) == 0))
377                         {
378                                 fprintf(stderr,
379                                         "ERROR: the 'unix password sync' "
380                                         "parameter is set and there is no valid "
381                                         "'passwd program' parameter.\n\n");
382                                 ret = 1;
383                         } else {
384                                 const char *passwd_prog;
385                                 char *truncated_prog = NULL;
386                                 const char *p;
387
388                                 passwd_prog = lp_passwd_program(talloc_tos());
389                                 p = passwd_prog;
390                                 next_token_talloc(talloc_tos(),
391                                                 &p,
392                                                 &truncated_prog, NULL);
393                                 if (truncated_prog && access(truncated_prog, F_OK) == -1) {
394                                         fprintf(stderr,
395                                                 "ERROR: the 'unix password sync' "
396                                                 "parameter is set and the "
397                                                 "'passwd program' (%s) cannot be "
398                                                 "executed (error was %s).\n\n",
399                                                 truncated_prog,
400                                                 strerror(errno));
401                                         ret = 1;
402                                 }
403                         }
404
405 #ifdef WITH_PAM
406                 }
407 #endif
408
409                 if(lp_passwd_chat(talloc_tos()) == NULL) {
410                         fprintf(stderr,
411                                 "ERROR: the 'unix password sync' parameter is "
412                                 "set and there is no valid 'passwd chat' "
413                                 "parameter.\n\n");
414                         ret = 1;
415                 }
416
417                 if ((lp_passwd_program(talloc_tos()) != NULL) &&
418                     (strlen(lp_passwd_program(talloc_tos())) > 0))
419                 {
420                         /* check if there's a %u parameter present */
421                         if(strstr_m(lp_passwd_program(talloc_tos()), "%u") == NULL) {
422                                 fprintf(stderr,
423                                         "ERROR: the 'passwd program' (%s) "
424                                         "requires a '%%u' parameter.\n\n",
425                                         lp_passwd_program(talloc_tos()));
426                                 ret = 1;
427                         }
428                 }
429
430                 /*
431                  * Check that we have a valid script and that it hasn't
432                  * been written to expect the old password.
433                  */
434
435                 if(lp_encrypt_passwords()) {
436                         if(strstr_m( lp_passwd_chat(talloc_tos()), "%o")!=NULL) {
437                                 fprintf(stderr,
438                                         "ERROR: the 'passwd chat' script [%s] "
439                                         "expects to use the old plaintext "
440                                         "password via the %%o substitution. With "
441                                         "encrypted passwords this is not "
442                                         "possible.\n\n",
443                                         lp_passwd_chat(talloc_tos()) );
444                                 ret = 1;
445                         }
446                 }
447         }
448
449         if (strlen(lp_winbind_separator()) != 1) {
450                 fprintf(stderr, "ERROR: the 'winbind separator' parameter must "
451                                 "be a single character.\n\n");
452                 ret = 1;
453         }
454
455         if (*lp_winbind_separator() == '+') {
456                 fprintf(stderr, "'winbind separator = +' might cause problems "
457                                 "with group membership.\n\n");
458         }
459
460         if (lp_algorithmic_rid_base() < BASE_RID) {
461                 /* Try to prevent admin foot-shooting, we can't put algorithmic
462                    rids below 1000, that's the 'well known RIDs' on NT */
463                 fprintf(stderr, "'algorithmic rid base' must be equal to or "
464                                 "above %lu\n\n", BASE_RID);
465         }
466
467         if (lp_algorithmic_rid_base() & 1) {
468                 fprintf(stderr, "'algorithmic rid base' must be even.\n\n");
469         }
470
471         if (lp_server_role() != ROLE_STANDALONE) {
472                 const char *default_backends[] = {
473                         "tdb", "tdb2", "ldap", "autorid", "hash"
474                 };
475                 const char *idmap_backend;
476                 bool valid_backend = false;
477                 uint32_t i;
478                 bool ok;
479
480                 idmap_backend = lp_idmap_default_backend();
481
482                 for (i = 0; i < ARRAY_SIZE(default_backends); i++) {
483                         ok = strequal(idmap_backend, default_backends[i]);
484                         if (ok) {
485                                 valid_backend = true;
486                         }
487                 }
488
489                 if (!valid_backend) {
490                         ret = 1;
491                         fprintf(stderr, "ERROR: Do not use the '%s' backend "
492                                         "as the default idmap backend!\n\n",
493                                         idmap_backend);
494                 }
495
496                 ok = do_idmap_check();
497                 if (!ok) {
498                         ret = 1;
499                 }
500         }
501
502 #ifndef HAVE_DLOPEN
503         if (lp_preload_modules()) {
504                 fprintf(stderr, "WARNING: 'preload modules = ' set while loading "
505                                 "plugins not supported.\n\n");
506         }
507 #endif
508
509         if (!lp_passdb_backend()) {
510                 fprintf(stderr, "ERROR: passdb backend must have a value or be "
511                                 "left out\n\n");
512         }
513
514         if (lp_os_level() > 255) {
515                 fprintf(stderr, "WARNING: Maximum value for 'os level' is "
516                                 "255!\n\n");
517         }
518
519         if (strequal(lp_dos_charset(), "UTF8") || strequal(lp_dos_charset(), "UTF-8")) {
520                 fprintf(stderr, "ERROR: 'dos charset' must not be UTF8\n\n");
521                 ret = 1;
522         }
523
524         return ret;
525 }
526
527 /**
528  * per-share logic tests
529  */
530 static void do_per_share_checks(int s)
531 {
532         const char **deny_list = lp_hosts_deny(s);
533         const char **allow_list = lp_hosts_allow(s);
534         const char **vfs_objects = NULL;
535         int i;
536         static bool uses_fruit;
537         static bool doesnt_use_fruit;
538         static bool fruit_mix_warned;
539
540         if(deny_list) {
541                 for (i=0; deny_list[i]; i++) {
542                         char *hasstar = strchr_m(deny_list[i], '*');
543                         char *hasquery = strchr_m(deny_list[i], '?');
544                         if(hasstar || hasquery) {
545                                 fprintf(stderr,
546                                         "Invalid character %c in hosts deny list "
547                                         "(%s) for service %s.\n\n",
548                                         hasstar ? *hasstar : *hasquery,
549                                         deny_list[i],
550                                         lp_servicename(talloc_tos(), s));
551                         }
552                 }
553         }
554
555         if(allow_list) {
556                 for (i=0; allow_list[i]; i++) {
557                         char *hasstar = strchr_m(allow_list[i], '*');
558                         char *hasquery = strchr_m(allow_list[i], '?');
559                         if(hasstar || hasquery) {
560                                 fprintf(stderr,
561                                         "Invalid character %c in hosts allow "
562                                         "list (%s) for service %s.\n\n",
563                                         hasstar ? *hasstar : *hasquery,
564                                         allow_list[i],
565                                         lp_servicename(talloc_tos(), s));
566                         }
567                 }
568         }
569
570         if(lp_level2_oplocks(s) && !lp_oplocks(s)) {
571                 fprintf(stderr, "Invalid combination of parameters for service "
572                                 "%s. Level II oplocks can only be set if oplocks "
573                                 "are also set.\n\n",
574                                 lp_servicename(talloc_tos(), s));
575         }
576
577         if (!lp_store_dos_attributes(s) && lp_map_hidden(s)
578             && !(lp_create_mask(s) & S_IXOTH))
579         {
580                 fprintf(stderr,
581                         "Invalid combination of parameters for service %s. Map "
582                         "hidden can only work if create mask includes octal "
583                         "01 (S_IXOTH).\n\n",
584                         lp_servicename(talloc_tos(), s));
585         }
586         if (!lp_store_dos_attributes(s) && lp_map_hidden(s)
587             && (lp_force_create_mode(s) & S_IXOTH))
588         {
589                 fprintf(stderr,
590                         "Invalid combination of parameters for service "
591                         "%s. Map hidden can only work if force create mode "
592                         "excludes octal 01 (S_IXOTH).\n\n",
593                         lp_servicename(talloc_tos(), s));
594         }
595         if (!lp_store_dos_attributes(s) && lp_map_system(s)
596             && !(lp_create_mask(s) & S_IXGRP))
597         {
598                 fprintf(stderr,
599                         "Invalid combination of parameters for service "
600                         "%s. Map system can only work if create mask includes "
601                         "octal 010 (S_IXGRP).\n\n",
602                         lp_servicename(talloc_tos(), s));
603         }
604         if (!lp_store_dos_attributes(s) && lp_map_system(s)
605             && (lp_force_create_mode(s) & S_IXGRP))
606         {
607                 fprintf(stderr,
608                         "Invalid combination of parameters for service "
609                         "%s. Map system can only work if force create mode "
610                         "excludes octal 010 (S_IXGRP).\n\n",
611                         lp_servicename(talloc_tos(), s));
612         }
613         if (lp_printing(s) == PRINT_CUPS && *(lp_print_command(talloc_tos(), s)) != '\0') {
614                 fprintf(stderr,
615                         "Warning: Service %s defines a print command, but "
616                         "parameter is ignored when using CUPS libraries.\n\n",
617                         lp_servicename(talloc_tos(), s));
618         }
619
620         vfs_objects = lp_vfs_objects(s);
621         if (vfs_objects && str_list_check(vfs_objects, "fruit")) {
622                 uses_fruit = true;
623         } else {
624                 doesnt_use_fruit = true;
625         }
626
627         if (uses_fruit && doesnt_use_fruit && !fruit_mix_warned) {
628                 fruit_mix_warned = true;
629                 fprintf(stderr,
630                         "WARNING: some services use vfs_fruit, others don't. Mounting them "
631                         "in conjunction on OS X clients results in undefined behaviour.\n\n");
632         }
633 }
634
635  int main(int argc, const char *argv[])
636 {
637         const char *config_file = get_dyn_CONFIGFILE();
638         int s;
639         static int silent_mode = False;
640         static int show_all_parameters = False;
641         int ret = 0;
642         poptContext pc;
643         static char *parameter_name = NULL;
644         static const char *section_name = NULL;
645         const char *cname;
646         const char *caddr;
647         static int show_defaults;
648         static int skip_logic_checks = 0;
649
650         struct poptOption long_options[] = {
651                 POPT_AUTOHELP
652                 {"suppress-prompt", 's', POPT_ARG_VAL, &silent_mode, 1, "Suppress prompt for enter"},
653                 {"verbose", 'v', POPT_ARG_NONE, &show_defaults, 1, "Show default options too"},
654                 {"skip-logic-checks", 'l', POPT_ARG_NONE, &skip_logic_checks, 1, "Skip the global checks"},
655                 {"show-all-parameters", '\0', POPT_ARG_VAL, &show_all_parameters, True, "Show the parameters, type, possible values" },
656                 {"parameter-name", '\0', POPT_ARG_STRING, &parameter_name, 0, "Limit testparm to a named parameter" },
657                 {"section-name", '\0', POPT_ARG_STRING, &section_name, 0, "Limit testparm to a named section" },
658                 POPT_COMMON_VERSION
659                 POPT_COMMON_DEBUGLEVEL
660                 POPT_COMMON_OPTION
661                 POPT_TABLEEND
662         };
663
664         TALLOC_CTX *frame = talloc_stackframe();
665
666         smb_init_locale();
667         /*
668          * Set the default debug level to 2.
669          * Allow it to be overridden by the command line,
670          * not by smb.conf.
671          */
672         lp_set_cmdline("log level", "2");
673
674         pc = poptGetContext(NULL, argc, argv, long_options,
675                             POPT_CONTEXT_KEEP_FIRST);
676         poptSetOtherOptionHelp(pc, "[OPTION...] <config-file> [host-name] [host-ip]");
677
678         while(poptGetNextOpt(pc) != -1);
679
680         if (show_all_parameters) {
681                 show_parameter_list();
682                 exit(0);
683         }
684
685         setup_logging(poptGetArg(pc), DEBUG_STDERR);
686
687         if (poptPeekArg(pc))
688                 config_file = poptGetArg(pc);
689
690         cname = poptGetArg(pc);
691         caddr = poptGetArg(pc);
692
693         poptFreeContext(pc);
694
695         if ( cname && ! caddr ) {
696                 printf ( "ERROR: You must specify both a machine name and an IP address.\n" );
697                 ret = 1;
698                 goto done;
699         }
700
701         fprintf(stderr,"Load smb config files from %s\n",config_file);
702
703         if (!lp_load_with_registry_shares(config_file)) {
704                 fprintf(stderr,"Error loading services.\n");
705                 ret = 1;
706                 goto done;
707         }
708
709         fprintf(stderr,"Loaded services file OK.\n");
710
711         if (skip_logic_checks == 0) {
712                 ret = do_global_checks();
713         }
714
715         for (s=0;s<1000;s++) {
716                 if (VALID_SNUM(s))
717                         if (strlen(lp_servicename(talloc_tos(), s)) > 12) {
718                                 fprintf(stderr, "WARNING: You have some share names that are longer than 12 characters.\n" );
719                                 fprintf(stderr, "These may not be accessible to some older clients.\n" );
720                                 fprintf(stderr, "(Eg. Windows9x, WindowsMe, and smbclient prior to Samba 3.0.)\n" );
721                                 break;
722                         }
723         }
724
725         for (s=0;s<1000;s++) {
726                 if (VALID_SNUM(s) && (skip_logic_checks == 0)) {
727                         do_per_share_checks(s);
728                 }
729         }
730
731
732         if (!section_name && !parameter_name) {
733                 fprintf(stderr,
734                         "Server role: %s\n\n",
735                         server_role_str(lp_server_role()));
736         }
737
738         if (!cname) {
739                 if (!silent_mode) {
740                         fprintf(stderr,"Press enter to see a dump of your service definitions\n");
741                         fflush(stdout);
742                         getc(stdin);
743                 }
744                 if (parameter_name || section_name) {
745                         bool isGlobal = False;
746                         s = GLOBAL_SECTION_SNUM;
747
748                         if (!section_name) {
749                                 section_name = GLOBAL_NAME;
750                                 isGlobal = True;
751                         } else if ((isGlobal=!strwicmp(section_name, GLOBAL_NAME)) == 0 &&
752                                  (s=lp_servicenumber(section_name)) == -1) {
753                                         fprintf(stderr,"Unknown section %s\n",
754                                                 section_name);
755                                         ret = 1;
756                                         goto done;
757                         }
758                         if (parameter_name) {
759                                 if (!dump_a_parameter( s, parameter_name, stdout, isGlobal)) {
760                                         fprintf(stderr,"Parameter %s unknown for section %s\n",
761                                                 parameter_name, section_name);
762                                         ret = 1;
763                                         goto done;
764                                 }
765                         } else {
766                                 if (isGlobal == True)
767                                         lp_dump(stdout, show_defaults, 0);
768                                 else
769                                         lp_dump_one(stdout, show_defaults, s);
770                         }
771                         goto done;
772                 }
773
774                 lp_dump(stdout, show_defaults, lp_numservices());
775         }
776
777         if(cname && caddr){
778                 /* this is totally ugly, a real `quick' hack */
779                 for (s=0;s<1000;s++) {
780                         if (VALID_SNUM(s)) {
781                                 if (allow_access(lp_hosts_deny(-1), lp_hosts_allow(-1), cname, caddr)
782                                     && allow_access(lp_hosts_deny(s), lp_hosts_allow(s), cname, caddr)) {
783                                         fprintf(stderr,"Allow connection from %s (%s) to %s\n",
784                                                    cname,caddr,lp_servicename(talloc_tos(), s));
785                                 } else {
786                                         fprintf(stderr,"Deny connection from %s (%s) to %s\n",
787                                                    cname,caddr,lp_servicename(talloc_tos(), s));
788                                 }
789                         }
790                 }
791         }
792
793 done:
794         gfree_loadparm();
795         TALLOC_FREE(frame);
796         return ret;
797 }
798