first pass at updating head branch to be to be the same as the SAMBA_2_0 branch
[bbaumbach/samba-autobuild/.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_SHARE && lp_revalidate(-1)) {
53                 printf("WARNING: the 'revalidate' parameter is ignored in all but \
54 'security=share' mode.\n");
55         }
56
57         if (lp_security() == SEC_DOMAIN && !lp_encrypted_passwords()) {
58                 printf("ERROR: in 'security=domain' mode the 'encrypt passwords' parameter must also be set to 'true'.\n");
59                 ret = 1;
60         }
61
62         if (lp_wins_support() && *lp_wins_server()) {
63                 printf("ERROR: both 'wins support = true' and 'wins server = <server>' \
64 cannot be set in the smb.conf file. nmbd will abort with this setting.\n");
65                 ret = 1;
66         }
67
68         if (!directory_exist(lp_lockdir(), &st)) {
69                 printf("ERROR: lock directory %s does not exist\n",
70                        lp_lockdir());
71                 ret = 1;
72         } else if ((st.st_mode & 0777) != 0755) {
73                 printf("WARNING: lock directory %s should have permissions 0755 for browsing to work\n",
74                        lp_lockdir());
75                 ret = 1;
76         }
77
78         /*
79          * Password server sanity checks.
80          */
81
82         if((lp_security() == SEC_SERVER || lp_security() == SEC_DOMAIN) && !lp_passwordserver()) {
83                 pstring sec_setting;
84                 if(lp_security() == SEC_SERVER)
85                         pstrcpy(sec_setting, "server");
86                 else if(lp_security() == SEC_DOMAIN)
87                         pstrcpy(sec_setting, "domain");
88
89                 printf("ERROR: The setting 'security=%s' requires the 'password server' parameter be set \
90 to a valid password server.\n", sec_setting );
91                 ret = 1;
92         }
93
94         /*
95          * Password chat sanity checks.
96          */
97
98         if(lp_security() == SEC_USER && lp_unix_password_sync()) {
99
100                 /*
101                  * Check that we have a valid lp_passwd_program().
102                  */
103
104                 if(lp_passwd_program() == NULL) {
105                         printf("ERROR: the 'unix password sync' parameter is set and there is no valid 'passwd program' \
106 parameter.\n" );
107                         ret = 1;
108                 } else {
109                         pstring passwd_prog;
110                         pstring truncated_prog;
111                         char *p;
112
113                         pstrcpy( passwd_prog, lp_passwd_program());
114                         p = passwd_prog;
115                         *truncated_prog = '\0';
116                         next_token(&p, truncated_prog, NULL, sizeof(pstring));
117
118                         if(access(truncated_prog, F_OK) == -1) {
119                                 printf("ERROR: the 'unix password sync' parameter is set and the 'passwd program' (%s) \
120 cannot be executed (error was %s).\n", truncated_prog, strerror(errno) );
121                                 ret = 1;
122                         }
123                 }
124
125                 if(lp_passwd_chat() == NULL) {
126                         printf("ERROR: the 'unix password sync' parameter is set and there is no valid 'passwd chat' \
127 parameter.\n");
128                         ret = 1;
129                 }
130
131                 /*
132                  * Check that we have a valid script and that it hasn't
133                  * been written to expect the old password.
134                  */
135
136                 if(lp_encrypted_passwords()) {
137                         if(strstr( lp_passwd_chat(), "%o")!=NULL) {
138                                 printf("ERROR: the 'passwd chat' script [%s] expects to use the old plaintext password \
139 via the %%o substitution. With encrypted passwords this is not possible.\n", lp_passwd_chat() );
140                                 ret = 1;
141                         }
142                 }
143         }
144
145         /*
146          * WINS server line sanity checks.
147          */
148
149         if(*lp_wins_server()) {
150                 fstring server;
151                 int count = 0;
152                 char *p = lp_wins_server();
153
154                 while(next_token(&p,server,LIST_SEP,sizeof(server)))
155                         count++;
156                 if(count > 1) {
157                         printf("ERROR: the 'wins server' parameter must only contain one WINS server.\n");
158                         ret = -1;
159                 }
160         }
161
162         return ret;
163 }   
164
165 static void usage(char *pname)
166 {
167         printf("Usage: %s [-sh] [-L servername] [configfilename] [hostname hostIP]\n", pname);
168         printf("\t-s                  Suppress prompt for enter\n");
169         printf("\t-h                  Print usage\n");
170         printf("\t-L servername       Set %%L macro to servername\n");
171         printf("\tconfigfilename      Configuration file to test\n");
172         printf("\thostname hostIP.    Hostname and Host IP address to test\n");
173         printf("\t                    against \"host allow\" and \"host deny\"\n");
174         printf("\n");
175 }
176
177
178 int main(int argc, char *argv[])
179 {
180   extern char *optarg;
181   extern int optind;
182   extern fstring local_machine;
183   pstring configfile;
184   int opt;
185   int s;
186   BOOL silent_mode = False;
187   int ret = 0;
188
189   TimeInit();
190
191   setup_logging(argv[0],True);
192   
193   charset_initialise();
194
195   while ((opt = getopt(argc, argv,"shL:")) != EOF) {
196   switch (opt) {
197     case 's':
198       silent_mode = True;
199       break;
200     case 'L':
201       fstrcpy(local_machine,optarg);
202       break;
203     case 'h':
204       usage(argv[0]);
205       exit(0);
206       break;
207     default:
208       printf("Incorrect program usage\n");
209       usage(argv[0]);
210       exit(1);
211       break;
212     }
213   }
214
215   argc += (1 - optind);
216
217   if ((argc == 1) || (argc == 3))
218     pstrcpy(configfile,CONFIGFILE);
219   else if ((argc == 2) || (argc == 4))
220     pstrcpy(configfile,argv[optind]);
221
222   dbf = stdout;
223   DEBUGLEVEL = 2;
224
225   printf("Load smb config files from %s\n",configfile);
226
227   if (!lp_load(configfile,False,True,False)) {
228       printf("Error loading services.\n");
229       return(1);
230   }
231
232   printf("Loaded services file OK.\n");
233
234   ret = do_global_checks();
235
236   for (s=0;s<1000;s++) {
237     if (VALID_SNUM(s))
238       if (strlen(lp_servicename(s)) > 8) {
239         printf("WARNING: You have some share names that are longer than 8 chars\n");
240         printf("These may give errors while browsing or may not be accessible\nto some older clients\n");
241         break;
242       }
243   }
244
245   for (s=0;s<1000;s++) {
246     if (VALID_SNUM(s)) {
247       char *deny_list = lp_hostsdeny(s);
248       char *allow_list = lp_hostsallow(s);
249       if(deny_list) {
250         char *hasstar = strchr(deny_list, '*');
251         char *hasquery = strchr(deny_list, '?');
252         if(hasstar || hasquery) {
253           printf("Invalid character %c in hosts deny list %s for service %s.\n",
254                  hasstar ? *hasstar : *hasquery, deny_list, lp_servicename(s) );
255         }
256       }
257
258       if(allow_list) {
259         char *hasstar = strchr(allow_list, '*');
260         char *hasquery = strchr(allow_list, '?');
261         if(hasstar || hasquery) {
262           printf("Invalid character %c in hosts allow list %s for service %s.\n",
263                  hasstar ? *hasstar : *hasquery, allow_list, lp_servicename(s) );
264         }
265       }
266
267       if(lp_level2_oplocks(s) && !lp_oplocks(s)) {
268         printf("Invalid combination of parameters for service %s. \
269 Level II oplocks can only be set if oplocks are also set.\n",
270                lp_servicename(s) );
271       }
272     }
273   }
274
275   if (argc < 3) {
276     if (!silent_mode) {
277       printf("Press enter to see a dump of your service definitions\n");
278       fflush(stdout);
279       getc(stdin);
280     }
281     lp_dump(stdout,True, lp_numservices());
282   }
283   
284   if (argc >= 3) {
285     char *cname;
286     char *caddr;
287       
288     if (argc == 3) {
289       cname = argv[optind];
290       caddr = argv[optind+1];
291     } else {
292       cname = argv[optind+1];
293       caddr = argv[optind+2];
294     }
295
296     /* this is totally ugly, a real `quick' hack */
297     for (s=0;s<1000;s++) {
298       if (VALID_SNUM(s)) {               
299         if (allow_access(lp_hostsdeny(s),lp_hostsallow(s),cname,caddr)) {
300           printf("Allow connection from %s (%s) to %s\n",
301                  cname,caddr,lp_servicename(s));
302         } else {
303           printf("Deny connection from %s (%s) to %s\n",
304                  cname,caddr,lp_servicename(s));
305         }
306       }
307     }
308   }
309   return(ret);
310 }