The big character set handling changeover!
[ira/wip.git] / source3 / utils / testparm.c
1 /* 
2    Unix SMB/Netbios implementation.
3    Version 1.9.
4    Test validity of smb.conf
5    Copyright (C) Karl Auer 1993, 1994-1998
6
7    Extensively modified by Andrew Tridgell, 1995
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 2 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, write to the Free Software
21    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
22 */
23
24 /*
25  * Testbed for loadparm.c/params.c
26  *
27  * This module simply loads a specified configuration file and
28  * if successful, dumps it's contents to stdout. Note that the
29  * operation is performed with DEBUGLEVEL at 3.
30  *
31  * Useful for a quick 'syntax check' of a configuration file.
32  *
33  */
34
35 #include "includes.h"
36 #include "smb.h"
37
38 /* these live in util.c */
39 extern FILE *dbf;
40 extern int DEBUGLEVEL;
41
42 /***********************************************
43  Here we do a set of 'hard coded' checks for bad
44  configuration settings.
45 ************************************************/
46
47 static int do_global_checks(void)
48 {
49         int ret = 0;
50         SMB_STRUCT_STAT st;
51
52         if (lp_security() == SEC_DOMAIN && !lp_encrypted_passwords()) {
53                 printf("ERROR: in 'security=domain' mode the 'encrypt passwords' parameter must also be set to 'true'.\n");
54                 ret = 1;
55         }
56
57         if (lp_wins_support() && *lp_wins_server()) {
58                 printf("ERROR: both 'wins support = true' and 'wins server = <server>' \
59 cannot be set in the smb.conf file. nmbd will abort with this setting.\n");
60                 ret = 1;
61         }
62
63         if (!directory_exist(lp_lockdir(), &st)) {
64                 printf("ERROR: lock directory %s does not exist\n",
65                        lp_lockdir());
66                 ret = 1;
67         } else if ((st.st_mode & 0777) != 0755) {
68                 printf("WARNING: lock directory %s should have permissions 0755 for browsing to work\n",
69                        lp_lockdir());
70                 ret = 1;
71         }
72
73         /*
74          * Password server sanity checks.
75          */
76
77         if((lp_security() == SEC_SERVER || lp_security() == SEC_DOMAIN) && !lp_passwordserver()) {
78                 pstring sec_setting;
79                 if(lp_security() == SEC_SERVER)
80                         pstrcpy(sec_setting, "server");
81                 else if(lp_security() == SEC_DOMAIN)
82                         pstrcpy(sec_setting, "domain");
83
84                 printf("ERROR: The setting 'security=%s' requires the 'password server' parameter be set \
85 to a valid password server.\n", sec_setting );
86                 ret = 1;
87         }
88
89         /*
90          * Password chat sanity checks.
91          */
92
93         if(lp_security() == SEC_USER && lp_unix_password_sync()) {
94
95                 /*
96                  * Check that we have a valid lp_passwd_program() if not using pam.
97                  */
98
99 #ifdef WITH_PAM
100                 if (!lp_pam_password_change()) {
101 #endif
102
103                         if(lp_passwd_program() == NULL) {
104                                 printf("ERROR: the 'unix password sync' parameter is set and there is no valid 'passwd program' \
105 parameter.\n" );
106                                 ret = 1;
107                         } else {
108                                 pstring passwd_prog;
109                                 pstring truncated_prog;
110                                 char *p;
111
112                                 pstrcpy( passwd_prog, lp_passwd_program());
113                                 p = passwd_prog;
114                                 *truncated_prog = '\0';
115                                 next_token(&p, truncated_prog, NULL, sizeof(pstring));
116
117                                 if(access(truncated_prog, F_OK) == -1) {
118                                         printf("ERROR: the 'unix password sync' parameter is set and the 'passwd program' (%s) \
119 cannot be executed (error was %s).\n", truncated_prog, strerror(errno) );
120                                         ret = 1;
121                                 }
122                         }
123
124 #ifdef WITH_PAM
125                 }
126 #endif
127
128                 if(lp_passwd_chat() == NULL) {
129                         printf("ERROR: the 'unix password sync' parameter is set and there is no valid 'passwd chat' \
130 parameter.\n");
131                         ret = 1;
132                 }
133
134                 /*
135                  * Check that we have a valid script and that it hasn't
136                  * been written to expect the old password.
137                  */
138
139                 if(lp_encrypted_passwords()) {
140                         if(strstr( lp_passwd_chat(), "%o")!=NULL) {
141                                 printf("ERROR: the 'passwd chat' script [%s] expects to use the old plaintext password \
142 via the %%o substitution. With encrypted passwords this is not possible.\n", lp_passwd_chat() );
143                                 ret = 1;
144                         }
145                 }
146         }
147
148         return ret;
149 }   
150
151 static void usage(char *pname)
152 {
153         printf("Usage: %s [-sh] [-L servername] [configfilename] [hostname hostIP]\n", pname);
154         printf("\t-s                  Suppress prompt for enter\n");
155         printf("\t-h                  Print usage\n");
156         printf("\t-L servername       Set %%L macro to servername\n");
157         printf("\t-t encoding         Print parameters with encoding\n");
158         printf("\tconfigfilename      Configuration file to test\n");
159         printf("\thostname hostIP.    Hostname and Host IP address to test\n");
160         printf("\t                    against \"host allow\" and \"host deny\"\n");
161         printf("\n");
162 }
163
164
165 int main(int argc, char *argv[])
166 {
167   extern char *optarg;
168   extern int optind;
169   extern fstring local_machine;
170   pstring configfile;
171   int opt;
172   int s;
173   BOOL silent_mode = False;
174   int ret = 0;
175   pstring term_code;
176
177   *term_code = 0;
178
179   TimeInit();
180
181   setup_logging(argv[0],True);
182   
183   while ((opt = getopt(argc, argv,"shL:t:")) != EOF) {
184   switch (opt) {
185     case 's':
186       silent_mode = True;
187       break;
188     case 'L':
189       fstrcpy(local_machine,optarg);
190       break;
191     case 'h':
192       usage(argv[0]);
193       exit(0);
194       break;
195     case 't':
196       pstrcpy(term_code,optarg);
197       break;
198     default:
199       printf("Incorrect program usage\n");
200       usage(argv[0]);
201       exit(1);
202       break;
203     }
204   }
205
206   argc += (1 - optind);
207
208   if ((argc == 1) || (argc == 3))
209     pstrcpy(configfile,CONFIGFILE);
210   else if ((argc == 2) || (argc == 4))
211     pstrcpy(configfile,argv[optind]);
212
213   dbf = stdout;
214   DEBUGLEVEL = 2;
215
216   printf("Load smb config files from %s\n",configfile);
217
218   if (!lp_load(configfile,False,True,False)) {
219       printf("Error loading services.\n");
220       return(1);
221   }
222
223   printf("Loaded services file OK.\n");
224
225   ret = do_global_checks();
226
227   for (s=0;s<1000;s++) {
228     if (VALID_SNUM(s))
229       if (strlen(lp_servicename(s)) > 8) {
230         printf("WARNING: You have some share names that are longer than 8 chars\n");
231         printf("These may give errors while browsing or may not be accessible\nto some older clients\n");
232         break;
233       }
234   }
235
236   for (s=0;s<1000;s++) {
237     if (VALID_SNUM(s)) {
238       char **deny_list = lp_hostsdeny(s);
239       char **allow_list = lp_hostsallow(s);
240       int i;
241       if(deny_list) {
242         for (i=0; deny_list[i]; i++) {
243           char *hasstar = strchr(deny_list[i], '*');
244           char *hasquery = strchr(deny_list[i], '?');
245           if(hasstar || hasquery) {
246             printf("Invalid character %c in hosts deny list (%s) for service %s.\n",
247                  hasstar ? *hasstar : *hasquery, deny_list[i], lp_servicename(s) );
248           }
249         }
250       }
251
252       if(allow_list) {
253         for (i=0; allow_list[i]; i++) {
254           char *hasstar = strchr(allow_list[i], '*');
255           char *hasquery = strchr(allow_list[i], '?');
256           if(hasstar || hasquery) {
257             printf("Invalid character %c in hosts allow list (%s) for service %s.\n",
258                  hasstar ? *hasstar : *hasquery, allow_list[i], lp_servicename(s) );
259           }
260         }
261       }
262
263       if(lp_level2_oplocks(s) && !lp_oplocks(s)) {
264         printf("Invalid combination of parameters for service %s. \
265 Level II oplocks can only be set if oplocks are also set.\n",
266                lp_servicename(s) );
267       }
268     }
269   }
270
271   if (argc < 3) {
272     if (!silent_mode) {
273       printf("Press enter to see a dump of your service definitions\n");
274       fflush(stdout);
275       getc(stdin);
276     }
277     lp_dump(stdout,True, lp_numservices());
278   }
279   
280   if (argc >= 3) {
281     char *cname;
282     char *caddr;
283       
284     if (argc == 3) {
285       cname = argv[optind];
286       caddr = argv[optind+1];
287     } else {
288       cname = argv[optind+1];
289       caddr = argv[optind+2];
290     }
291
292     /* this is totally ugly, a real `quick' hack */
293     for (s=0;s<1000;s++) {
294       if (VALID_SNUM(s)) {               
295         if (allow_access(lp_hostsdeny(s),lp_hostsallow(s),cname,caddr)) {
296           printf("Allow connection from %s (%s) to %s\n",
297                  cname,caddr,lp_servicename(s));
298         } else {
299           printf("Deny connection from %s (%s) to %s\n",
300                  cname,caddr,lp_servicename(s));
301         }
302       }
303     }
304   }
305   return(ret);
306 }