[Cfengine-2] / trunk / src / do.c Repository:
ViewVC logotype

Annotation of /trunk/src/do.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1 - (view) (download) (as text)

1 : root 1 /*
2 :    
3 :     Copyright (C) 1995-2000
4 :     Free Software Foundation, Inc.
5 :    
6 :     This file is part of GNU cfengine - written and maintained
7 :     by Mark Burgess, Dept of Computing and Engineering, Oslo College,
8 :     Dept. of Theoretical physics, University of Oslo
9 :    
10 :     This program is free software; you can redistribute it and/or modify it
11 :     under the terms of the GNU General Public License as published by the
12 :     Free Software Foundation; either version 2, or (at your option) any
13 :     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.
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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
22 :    
23 :     */
24 :    
25 :     /*****************************************************************************/
26 :     /* */
27 :     /* File: do.c */
28 :     /* */
29 :     /*****************************************************************************/
30 :    
31 :     #include "cf.defs.h"
32 :     #include "cf.extern.h"
33 :    
34 :     /*******************************************************************/
35 :    
36 :     void GetHomeInfo()
37 :    
38 :     { DIR *dirh;
39 :     struct dirent *dirp;
40 :     struct Item *ip;
41 :     char path[bufsize],mountitem[bufsize];
42 :    
43 :     if (!IsPrivileged())
44 :     {
45 :     Debug("Not root, so skipping GetHomeInfo()\n");
46 :     return;
47 :     }
48 :    
49 :     if (!MountPathDefined())
50 :     {
51 :     return;
52 :     }
53 :    
54 :    
55 :     for (ip = VMOUNTLIST; ip != NULL; ip=ip->next)
56 :     {
57 :     if (IsExcluded(ip->classes))
58 :     {
59 :     continue;
60 :     }
61 :    
62 :     if ((dirh = opendir(ip->name)) == NULL)
63 :     {
64 :     snprintf(OUTPUT,bufsize*2,"INFO: Host %s seems to have no (additional) local disks except the OS\n",VDEFAULTBINSERVER.name);
65 :     CfLog(cfverbose,OUTPUT,"");
66 :     snprintf(OUTPUT,bufsize*2," mounted under %s\n\n",ip->name);
67 :     CfLog(cfverbose,OUTPUT,"");
68 :     return;
69 :     }
70 :    
71 :     for (dirp = readdir(dirh); dirp != NULL; dirp = readdir(dirh))
72 :     {
73 :     if (!SensibleFile(dirp->d_name,ip->name,NULL))
74 :     {
75 :     continue;
76 :     }
77 :    
78 :     strcpy(VBUFF,ip->name);
79 :     AddSlash(VBUFF);
80 :     strcat(VBUFF,dirp->d_name);
81 :    
82 :     if (IsHomeDir(VBUFF))
83 :     {
84 :     snprintf(OUTPUT,bufsize*2,"Host defines a home directory %s\n",VBUFF);
85 :     CfLog(cfverbose,OUTPUT,"");
86 :     }
87 :     else
88 :     {
89 :     snprintf(OUTPUT,bufsize*2,"Host defines a potential mount point %s\n",VBUFF);
90 :     CfLog(cfverbose,OUTPUT,"");
91 :     }
92 :    
93 :     snprintf(path,bufsize,"%s%s",ip->name,dirp->d_name);
94 :     snprintf(mountitem,bufsize,"%s:%s",VDEFAULTBINSERVER.name,path);
95 :    
96 :     if (! IsItemIn(VMOUNTED,mountitem))
97 :     {
98 :     if ( MOUNTCHECK && ! RequiredFileSystemOkay(path) && VERBOSE)
99 :     {
100 :     snprintf(OUTPUT,bufsize*2,"Found a mountpoint %s but there was\n",path);
101 :     CfLog(cfinform,OUTPUT,"");
102 :     CfLog(cfinform,"nothing mounted on it.\n\n","");
103 :     }
104 :     }
105 :     }
106 :     closedir(dirh);
107 :     }
108 :     }
109 :    
110 :     /*******************************************************************/
111 :    
112 :     void GetMountInfo () /* This is, in fact, the most portable way to read the mount info! */
113 :     /* Depressing, isn't it? */
114 :     { FILE *pp;
115 :     char buf1[bufsize],buf2[bufsize],buf3[bufsize];
116 :     char host[maxvarsize], mounton[bufsize];
117 :     int i;
118 :    
119 :     if (!GetLock(ASUniqueName("mountinfo"),"",1,VEXPIREAFTER,VUQNAME,CFSTARTTIME))
120 :     {
121 :     return;
122 :     }
123 :    
124 :     /* sscanf(VMOUNTCOMM[VSYSTEMHARDCLASS],"%s",buf1); */
125 :     /* Old BSD scanf crashes here! Why!? workaround: */
126 :    
127 :     for (i=0; VMOUNTCOMM[VSYSTEMHARDCLASS][i] != ' '; i++)
128 :     {
129 :     buf1[i] = VMOUNTCOMM[VSYSTEMHARDCLASS][i];
130 :     }
131 :    
132 :     buf1[i] = '\0';
133 :    
134 :     signal(SIGALRM,(void *)TimeOut);
135 :     alarm(RPCTIMEOUT);
136 :    
137 :     if ((pp = cfpopen(buf1,"r")) == NULL)
138 :     {
139 :     snprintf(OUTPUT,bufsize*2,"%s: Can't open %s\n",VPREFIX,buf1);
140 :     CfLog(cferror,OUTPUT,"popen");
141 :     return;
142 :     }
143 :    
144 :     do
145 :     {
146 :     VBUFF[0] = buf1[0] = buf2[0] = buf3[0] = '\0';
147 :    
148 :     if (ferror(pp)) /* abortable */
149 :     {
150 :     GOTMOUNTINFO = false;
151 :     CfLog(cferror,"Error getting mount info\n","ferror");
152 :     break;
153 :     }
154 :    
155 :     ReadLine(VBUFF,bufsize,pp);
156 :    
157 :     if (ferror(pp)) /* abortable */
158 :     {
159 :     GOTMOUNTINFO = false;
160 :     CfLog(cferror,"Error getting mount info\n","ferror");
161 :     break;
162 :     }
163 :    
164 :     sscanf(VBUFF,"%s%s%s",buf1,buf2,buf3);
165 :    
166 :     if (VBUFF[0] == '\n')
167 :     {
168 :     break;
169 :     }
170 :    
171 :     if (strstr(VBUFF,"not responding"))
172 :     {
173 :     printf("%s: %s\n",VPREFIX,VBUFF);
174 :     }
175 :    
176 :     if (strstr(VBUFF,"be root"))
177 :     {
178 :     CfLog(cferror,"Mount access is denied. You must be root.\n","");
179 :     CfLog(cferror,"Use the -n option to run safely.","");
180 :     }
181 :    
182 :     if (strstr(VBUFF,"retrying") || strstr(VBUFF,"denied") || strstr(VBUFF,"backgrounding"))
183 :     {
184 :     continue;
185 :     }
186 :    
187 :     if (strstr(VBUFF,"exceeded") || strstr(VBUFF,"busy"))
188 :     {
189 :     continue;
190 :     }
191 :    
192 :     if (strstr(VBUFF,"RPC"))
193 :     {
194 :     if (! SILENT)
195 :     {
196 :     CfLog(cfinform,"There was an RPC timeout. Aborting mount operations.\n","");
197 :     CfLog(cfinform,"Session failed while trying to talk to remote host\n","");
198 :     snprintf(OUTPUT,bufsize*2,"%s\n",VBUFF);
199 :     CfLog(cfinform,OUTPUT,"");
200 :     }
201 :    
202 :     GOTMOUNTINFO = false;
203 :     ReleaseCurrentLock();
204 :     cfpclose(pp);
205 :     return;
206 :     }
207 :    
208 :     switch (VSYSTEMHARDCLASS)
209 :     {
210 :     case sun4:
211 :     case sun3:
212 :     case ultrx:
213 :     case irix:
214 :     case irix4:
215 :     case irix64:
216 :     case linuxx:
217 :     case GnU:
218 :     case unix_sv:
219 :     case freebsd:
220 :     case netbsd:
221 :     case openbsd:
222 :     case bsd_i:
223 :     case nextstep:
224 :     case bsd4_3:
225 :     case newsos:
226 :     case aos:
227 :     case osf:
228 :     case crayos:
229 :     if (buf1[0] == '/')
230 :     {
231 :     strcpy(host,VDEFAULTBINSERVER.name);
232 :     strcpy(mounton,buf3);
233 :     }
234 :     else
235 :     {
236 :     sscanf(buf1,"%[^:]",host);
237 :     strcpy(mounton,buf3);
238 :     }
239 :    
240 :     break;
241 :     case solaris:
242 :     case solarisx86:
243 :     case hp10:
244 :     case hp:
245 :     if (buf3[0] == '/')
246 :     {
247 :     strcpy(host,VDEFAULTBINSERVER.name);
248 :     strcpy(mounton,buf1);
249 :     }
250 :     else
251 :     {
252 :     sscanf(buf3,"%[^:]",host);
253 :     strcpy(mounton,buf1);
254 :     }
255 :    
256 :     break;
257 :     case aix:
258 :     /* skip header */
259 :    
260 :     if (buf1[0] == '/')
261 :     {
262 :     strcpy(host,VDEFAULTBINSERVER.name);
263 :     strcpy(mounton,buf2);
264 :     }
265 :     else
266 :     {
267 :     strcpy(host,buf1);
268 :     strcpy(mounton,buf3);
269 :     }
270 :     break;
271 :    
272 :     case cfnt: strcpy(mounton,buf2);
273 :     strcpy(host,buf1);
274 :     break;
275 :     case unused1:
276 :     case unused2:
277 :     case unused3:
278 :     break;
279 :    
280 :     case cfsco: CfLog(cferror,"Don't understand SCO mount format, no data","");
281 :    
282 :     default:
283 :     printf("cfengine software error: case %d = %s\n",VSYSTEMHARDCLASS,CLASSTEXT[VSYSTEMHARDCLASS]);
284 :     FatalError("System error in GetMountInfo - no such class!");
285 :     }
286 :    
287 :     InstallMountedItem(host,mounton);
288 :     }
289 :    
290 :     while (!feof(pp));
291 :    
292 :     alarm(0);
293 :     signal(SIGALRM,SIG_DFL);
294 :     ReleaseCurrentLock();
295 :     cfpclose(pp);
296 :     }
297 :    
298 :     /*******************************************************************/
299 :    
300 :     void MakePaths()
301 :    
302 :     { struct File *ptr;
303 :     struct Item *ip1,*ip2;
304 :     char pathbuff[bufsize],basename[bufsize];
305 :    
306 :     for (ptr = VMAKEPATH; ptr != NULL; ptr=ptr->next)
307 :     {
308 :     if (IsExcluded(ptr->classes))
309 :     {
310 :     continue;
311 :     }
312 :    
313 :     if (ptr->done == 'y')
314 :     {
315 :     continue;
316 :     }
317 :     else
318 :     {
319 :     ptr->done = 'y';
320 :     }
321 :    
322 :     ResetOutputRoute(ptr->log,ptr->inform);
323 :    
324 :     if (strncmp(ptr->path,"home/",5) == 0) /* home/subdir */
325 :     {
326 :     if (*(ptr->path+4) != '/')
327 :     {
328 :     snprintf(OUTPUT,bufsize*2,"Illegal use of home in directories: %s\n",ptr->path);
329 :     CfLog(cferror,OUTPUT,"");
330 :     continue;
331 :     }
332 :    
333 :     for (ip1 = VHOMEPATLIST; ip1 != NULL; ip1=ip1->next)
334 :     {
335 :     for (ip2 = VMOUNTLIST; ip2 != NULL; ip2=ip2->next)
336 :     {
337 :     if (IsExcluded(ip2->classes))
338 :     {
339 :     continue;
340 :     }
341 :    
342 :     pathbuff[0]='\0';
343 :     basename[0]='\0';
344 :    
345 :     strcpy(pathbuff,ip2->name);
346 :     AddSlash(pathbuff);
347 :     strcat(pathbuff,ip1->name);
348 :     AddSlash(pathbuff);
349 :     strcat(pathbuff,"*/");
350 :     strcat(pathbuff,ptr->path+5);
351 :    
352 :     ExpandWildCardsAndDo(pathbuff,basename,DirectoriesWrapper,ptr);
353 :     }
354 :     }
355 :     }
356 :     else
357 :     {
358 :     Verbose("MakePath(%s)\n",ptr->path);
359 :     pathbuff[0]='\0';
360 :     basename[0]='\0';
361 :    
362 :     ExpandWildCardsAndDo(ptr->path,basename,DirectoriesWrapper,ptr);
363 :     }
364 :     ResetOutputRoute('d','d');
365 :     }
366 :     }
367 :    
368 :     /*******************************************************************/
369 :    
370 :     void MakeChildLinks() /* <binserver> should expand to a best fit filesys */
371 :    
372 :     { struct Link *lp;
373 :     struct Item *ip;
374 :     int matched,varstring;
375 :     char to[bufsize],from[bufsize],path[bufsize];
376 :     struct stat statbuf;
377 :     short saveenforce;
378 :     short savesilent;
379 :    
380 :     if (NOLINKS)
381 :     {
382 :     return;
383 :     }
384 :    
385 :     ACTION = links;
386 :    
387 :     for (lp = VCHLINK; lp != NULL; lp = lp->next)
388 :     {
389 :     if (IsExcluded(lp->classes))
390 :     {
391 :     continue;
392 :     }
393 :    
394 :     if (lp->done == 'y')
395 :     {
396 :     continue;
397 :     }
398 :     else
399 :     {
400 :     lp->done = 'y';
401 :     }
402 :    
403 :     snprintf(VBUFF,bufsize,"%.50s.%.50s",lp->from,lp->to); /* Unique ID for copy locking */
404 :    
405 :     if (!GetLock(ASUniqueName("link"),CanonifyName(VBUFF),VIFELAPSED,VEXPIREAFTER,VUQNAME,CFSTARTTIME))
406 :     {
407 :     continue;
408 :     }
409 :    
410 :     ExpandVarstring(lp->from,from,NULL);
411 :     ExpandVarstring(lp->to,to,NULL);
412 :    
413 :     saveenforce = ENFORCELINKS;
414 :     ENFORCELINKS = ENFORCELINKS || (lp->force == 'y');
415 :    
416 :     savesilent = SILENT;
417 :     SILENT = SILENT || lp->silent;
418 :    
419 :     ResetOutputRoute(lp->log,lp->inform);
420 :    
421 :     matched = varstring = false;
422 :    
423 :     for(ip = VBINSERVERS; ip != NULL && (!matched); ip = ip->next)
424 :     {
425 :     path[0] = '\0';
426 :    
427 :     if (strcmp(to,"linkchildren") == 0) /* linkchildren */
428 :     {
429 :     if (stat(from,&statbuf) == -1)
430 :     {
431 :     snprintf(OUTPUT,bufsize*2,"Makechildlinks() can't stat %s\n",from);
432 :     CfLog(cferror,OUTPUT,"stat");
433 :     ResetOutputRoute('d','d');
434 :     continue;
435 :     }
436 :     LinkChildren(from,lp->type,&statbuf,0,0,lp->inclusions,lp->exclusions,lp->copy,lp->nofile,lp);
437 :     break;
438 :     }
439 :    
440 :     varstring = ExpandVarbinserv(to,path,ip->name);
441 :    
442 :     if (lp->recurse != 0)
443 :     {
444 :     matched = RecursiveLink(lp,from,path,lp->recurse);
445 :     }
446 :     else if (LinkChildFiles(from,path,lp->type,lp->inclusions,lp->exclusions,lp->copy,lp->nofile,lp))
447 :     {
448 :     matched = true;
449 :     }
450 :     else if (! varstring)
451 :     {
452 :     snprintf(OUTPUT,bufsize*2,"Error while trying to childlink %s -> %s\n",from,path);
453 :     CfLog(cferror,OUTPUT,"");
454 :     snprintf(OUTPUT,bufsize*2,"The directory %s does not exist. Can't link.\n",path);
455 :     CfLog(cferror,OUTPUT,"");
456 :     }
457 :    
458 :     if (! varstring) /* don't iterate over binservers if not var */
459 :     {
460 :     ReleaseCurrentLock();
461 :     break;
462 :     }
463 :     }
464 :    
465 :     ENFORCELINKS = saveenforce;
466 :     SILENT = savesilent;
467 :     ResetOutputRoute('d','d');
468 :    
469 :     if (matched == false && ip == NULL)
470 :     {
471 :     snprintf(OUTPUT,bufsize*2,"ChildLink didn't find any server to match %s -> %s\n",from,to);
472 :     CfLog(cferror,OUTPUT,"");
473 :     }
474 :    
475 :     ReleaseCurrentLock();
476 :     }
477 :     }
478 :    
479 :     /*******************************************************************/
480 :    
481 :     void MakeLinks() /* <binserver> should expand to a best fit filesys */
482 :    
483 :     { struct Link *lp;
484 :     char from[bufsize],to[bufsize],path[bufsize];
485 :     struct Item *ip;
486 :     int matched,varstring;
487 :     short saveenforce;
488 :     short savesilent;
489 :     int (*linkfiles) ARGLIST((char *from, char *to, struct Item *inclusions, struct Item *exclusions, struct Item *copy, short int nofile, struct Link *ptr));
490 :    
491 :     if (NOLINKS)
492 :     {
493 :     return;
494 :     }
495 :    
496 :     ACTION = links;
497 :    
498 :     for (lp = VLINK; lp != NULL; lp = lp->next)
499 :     {
500 :     if (IsExcluded(lp->classes))
501 :     {
502 :     continue;
503 :     }
504 :    
505 :     if (lp->done == 'y')
506 :     {
507 :     continue;
508 :     }
509 :     else
510 :     {
511 :     lp->done = 'y';
512 :     }
513 :    
514 :     snprintf(VBUFF,bufsize,"%.50s.%.50s",lp->from,lp->to); /* Unique ID for copy locking */
515 :    
516 :     if (!GetLock(ASUniqueName("link"),CanonifyName(VBUFF),VIFELAPSED,VEXPIREAFTER,VUQNAME,CFSTARTTIME))
517 :     {
518 :     continue;
519 :     }
520 :    
521 :     ExpandVarstring(lp->from,from,NULL);
522 :     ExpandVarstring(lp->to,to,NULL);
523 :    
524 :     ResetOutputRoute(lp->log,lp->inform);
525 :    
526 :     switch (lp->type)
527 :     {
528 :     case 's':
529 :     linkfiles = LinkFiles;
530 :     break;
531 :     case 'r':
532 :     linkfiles = RelativeLink;
533 :     break;
534 :     case 'a':
535 :     linkfiles = AbsoluteLink;
536 :     break;
537 :     case 'h':
538 :     linkfiles = HardLinkFiles;
539 :     break;
540 :     default:
541 :     printf("%s: internal error, link type was [%c]\n",VPREFIX,lp->type);
542 :     ReleaseCurrentLock();
543 :     continue;
544 :     }
545 :    
546 :     saveenforce = ENFORCELINKS;
547 :     ENFORCELINKS = ENFORCELINKS || (lp->force == 'y');
548 :    
549 :     savesilent = SILENT;
550 :     SILENT = SILENT || lp->silent;
551 :    
552 :     matched = varstring = false;
553 :    
554 :     for( ip = VBINSERVERS; ip != NULL && (!matched); ip = ip->next)
555 :     {
556 :     path[0] = '\0';
557 :    
558 :     varstring = ExpandVarbinserv(to,path,ip->name);
559 :    
560 :     if ((*linkfiles)(from,path,lp->inclusions,lp->exclusions,lp->copy,lp->nofile,lp))
561 :     {
562 :     matched = true;
563 :     }
564 :     else if (! varstring)
565 :     {
566 :     snprintf(OUTPUT,bufsize*2,"Error while trying to link %s -> %s\n",from,path);
567 :     CfLog(cfinform,OUTPUT,"");
568 :     }
569 :    
570 :     if (! varstring) /* don't iterate over binservers if not var */
571 :     {
572 :     break;
573 :     }
574 :     }
575 :    
576 :     ENFORCELINKS = saveenforce;
577 :     SILENT = savesilent;
578 :    
579 :     ResetOutputRoute('d','d');
580 :    
581 :     if (matched == false && ip == NULL)
582 :     {
583 :     snprintf(OUTPUT,bufsize*2,"Links didn't find any file to match %s -> %s\n",from,to);
584 :     CfLog(cferror,OUTPUT,"");
585 :     }
586 :    
587 :     ReleaseCurrentLock();
588 :     }
589 :     }
590 :    
591 :     /*******************************************************************/
592 :    
593 :     void MailCheck()
594 :    
595 :     { char mailserver[bufsize];
596 :     char mailhost[maxvarsize];
597 :     char rmailpath[maxvarsize];
598 :     char lmailpath[maxvarsize];
599 :    
600 :    
601 :     if (!GetLock("Mailcheck",CanonifyName(VFSTAB[VSYSTEMHARDCLASS]),0,VEXPIREAFTER,VUQNAME,CFSTARTTIME))
602 :     {
603 :     return;
604 :     }
605 :    
606 :     if (VMAILSERVER[0] == '\0')
607 :     {
608 :     FatalError("Program does not define a mailserver for this host");
609 :     }
610 :    
611 :     if (!IsPrivileged())
612 :     {
613 :     CfLog(cferror,"Only root can alter the mail configuration.\n","");
614 :     ReleaseCurrentLock();
615 :     return;
616 :     }
617 :    
618 :     sscanf (VMAILSERVER,"%[^:]:%s",mailhost,rmailpath);
619 :    
620 :     if (VMAILSERVER[0] == '\0')
621 :     {
622 :     CfLog(cfinform,"\n%s: Host has no defined mailserver!\n","");
623 :     ReleaseCurrentLock();
624 :     return;
625 :     }
626 :    
627 :     if (strcmp(VDEFAULTBINSERVER.name,mailhost) == 0) /* Is this the mailserver ?*/
628 :     {
629 :     ExpiredUserCheck(rmailpath,false);
630 :     ReleaseCurrentLock();
631 :     return;
632 :     }
633 :    
634 :     snprintf(lmailpath,bufsize,"%s:%s",mailhost,VMAILDIR[VSYSTEMHARDCLASS]);
635 :    
636 :    
637 :     if (IsItemIn(VMOUNTED,lmailpath)) /* Remote file system mounted on */
638 :     { /* local mail dir - correct */
639 :     Verbose("%s: Mail spool area looks ok\n",VPREFIX);
640 :     ReleaseCurrentLock();
641 :     return;
642 :     }
643 :    
644 :     strcpy(mailserver,VMAILDIR[VSYSTEMHARDCLASS]);
645 :     AddSlash(mailserver);
646 :     strcat(mailserver,".");
647 :    
648 :     MakeDirectoriesFor(mailserver,'n'); /* Check directory is in place */
649 :    
650 :     if (IsItemIn(VMOUNTED,VMAILSERVER))
651 :     {
652 :     if (!SILENT)
653 :     {
654 :     Verbose("%s: Warning - the mail directory seems to be mounted as on\n",VPREFIX);
655 :     Verbose("%s: the remote mailserver and not on the correct local directory\n",VPREFIX);
656 :     Verbose("%s: Should strictly mount on %s\n",VPREFIX,VMAILDIR[VSYSTEMHARDCLASS]);
657 :     }
658 :     ReleaseCurrentLock();
659 :     return;
660 :     }
661 :    
662 :     if (MatchStringInFstab("mail"))
663 :     {
664 :     if (!SILENT)
665 :     {
666 :     Verbose("%s: Warning - the mail directory seems to be mounted\n",VPREFIX);
667 :     Verbose("%s: in a funny way. I can find the string <mail> in %s\n",VPREFIX,VFSTAB[VSYSTEMHARDCLASS]);
668 :     Verbose("%s: but nothing is mounted on %s\n\n",VPREFIX,VMAILDIR[VSYSTEMHARDCLASS]);
669 :     }
670 :     ReleaseCurrentLock();
671 :     return;
672 :     }
673 :    
674 :     printf("\n%s: Trying to mount %s\n",VPREFIX,VMAILSERVER);
675 :    
676 :     if (! DONTDO)
677 :     {
678 :     AddToFstab(mailhost,rmailpath,VMAILDIR[VSYSTEMHARDCLASS],"rw",false);
679 :     }
680 :     else
681 :     {
682 :     printf("%s: Need to mount %s:%s on %s\n",VPREFIX,mailhost,rmailpath,mailserver);
683 :     }
684 :    
685 :     ReleaseCurrentLock();
686 :     }
687 :    
688 :     /*******************************************************************/
689 :    
690 :     void ExpiredUserCheck(spooldir,always)
691 :    
692 :     char *spooldir;
693 :     int always;
694 :    
695 :     {
696 :     Verbose("%s: Checking for expired users in %s\n",VPREFIX,spooldir);
697 :    
698 :     if (always || (strncmp(VMAILSERVER,VFQNAME,strlen(VMAILSERVER)) != 0))
699 :     { DIR *dirh;
700 :     struct dirent *dirp;
701 :     struct stat statbuf;
702 :    
703 :     if ((dirh = opendir(spooldir)) == NULL)
704 :     {
705 :     snprintf(OUTPUT,bufsize*2,"Can't open spool directory %s",spooldir);
706 :     CfLog(cfverbose,OUTPUT,"opendir");
707 :     return;
708 :     }
709 :    
710 :     for (dirp = readdir(dirh); dirp != NULL; dirp = readdir(dirh))
711 :     {
712 :     if (!SensibleFile(dirp->d_name,spooldir,NULL))
713 :     {
714 :     continue;
715 :     }
716 :    
717 :     strcpy(VBUFF,spooldir);
718 :     AddSlash(VBUFF);
719 :     strcat(VBUFF,dirp->d_name);
720 :    
721 :     if (stat(VBUFF,&statbuf) != -1)
722 :     {
723 :     if (getpwuid(statbuf.st_uid) == NULL)
724 :     {
725 :     if (TrueVar("WarnNonOwnerMail")||TrueVar("WarnNonOwnerFiles"))
726 :     {
727 :     snprintf(OUTPUT,bufsize*2,"File %s in spool dir %s is not owned by any user",dirp->d_name,spooldir);
728 :     CfLog(cferror,OUTPUT,"");
729 :     }
730 :    
731 :     if (TrueVar("DeleteNonOwnerMail")||TrueVar("DeleteNonOwnerFiles"))
732 :     {
733 :     if (DONTDO)
734 :     {
735 :     printf("%s: Delete file %s\n",VPREFIX,VBUFF);
736 :     }
737 :     else
738 :     {
739 :     snprintf(OUTPUT,bufsize*2,"Deleting file %s in spool dir %s not owned by any user",dirp->d_name,spooldir);
740 :     CfLog(cferror,OUTPUT,"");
741 :    
742 :     if (unlink(VBUFF) == -1)
743 :     {
744 :     CfLog(cferror,"","unlink");
745 :     }
746 :     }
747 :     }
748 :     }
749 :     }
750 :    
751 :     if (strstr(dirp->d_name,"lock") || strstr(dirp->d_name,".tmp"))
752 :     {
753 :     Verbose("Ignoring non-user file %s\n",dirp->d_name);
754 :     continue;
755 :     }
756 :    
757 :     if (getpwnam(dirp->d_name) == NULL)
758 :     {
759 :     if (TrueVar("WarnNonUserMail")||TrueVar("WarnNonUserFiles"))
760 :     {
761 :     snprintf(OUTPUT,bufsize*2,"File %s in spool dir %s is not the name of a user",dirp->d_name,spooldir);
762 :     CfLog(cferror,OUTPUT,"");
763 :     }
764 :    
765 :     if (TrueVar("DeleteNonUserMail")||TrueVar("DeleteNonUserFiles"))
766 :     {
767 :     if (DONTDO)
768 :     {
769 :     printf("%s: Delete file %s\n",VPREFIX,VBUFF);
770 :     }
771 :     else
772 :     {
773 :     snprintf(OUTPUT,bufsize*2,"Deleting file %s in spool dir %s (not a username)",dirp->d_name,spooldir);
774 :     CfLog(cferror,OUTPUT,"");
775 :    
776 :     if (unlink(VBUFF) == -1)
777 :     {
778 :     CfLog(cferror,"","unlink");
779 :     }
780 :     }
781 :     }
782 :     }
783 :     }
784 :     closedir(dirh);
785 :     Verbose("%s: Done checking spool directory %s\n",VPREFIX,spooldir);
786 :     }
787 :     }
788 :    
789 :     /*******************************************************************/
790 :    
791 :     void MountFileSystems()
792 :    
793 :     { FILE *pp;
794 :     int fd;
795 :     struct stat statbuf;
796 :    
797 :     if (! GOTMOUNTINFO || DONTDO)
798 :     {
799 :     return;
800 :     }
801 :    
802 :     if (!IsPrivileged())
803 :     {
804 :     CfLog(cferror,"Only root can mount filesystems.\n","");
805 :     return;
806 :     }
807 :    
808 :     signal(SIGALRM,(void *)TimeOut);
809 :     alarm(RPCTIMEOUT);
810 :    
811 :     if (VSYSTEMHARDCLASS == cfnt)
812 :     {
813 :     /* This is a shell script. Make sure it hasn't been compromised. */
814 :     if (stat("/etc/fstab",&statbuf) == -1)
815 :     {
816 :     if ((fd = creat("/etc/fstab",0755)) > 0)
817 :     {
818 :     write(fd,"#!/bin/sh\n\n",10);
819 :     close(fd);
820 :     }
821 :     else
822 :     {
823 :     if (statbuf.st_mode & (S_IWOTH | S_IWGRP))
824 :     {
825 :     CfLog(cferror,"File /etc/fstab was insecure. Cannot mount filesystems.\n","");
826 :     GOTMOUNTINFO = false;
827 :     return;
828 :     }
829 :     }
830 :     }
831 :     }
832 :    
833 :     if ((pp = cfpopen(VMOUNTCOMM[VSYSTEMHARDCLASS],"r")) == NULL)
834 :     {
835 :     snprintf(OUTPUT,bufsize*2,"Failed to open pipe from %s\n",VMOUNTCOMM[VSYSTEMHARDCLASS]);
836 :     CfLog(cferror,OUTPUT,"popen");
837 :     return;
838 :     }
839 :    
840 :     while (!feof(pp))
841 :     {
842 :     if (ferror(pp)) /* abortable */
843 :     {
844 :     CfLog(cferror,"Error mounting filesystems\n","ferror");
845 :     break;
846 :     }
847 :    
848 :     ReadLine(VBUFF,bufsize,pp);
849 :    
850 :     if (ferror(pp)) /* abortable */
851 :     {
852 :     CfLog(cferror,"Error mounting filesystems\n","ferror");
853 :     break;
854 :     }
855 :    
856 :     if (strstr(VBUFF,"already mounted") || strstr(VBUFF,"exceeded") || strstr(VBUFF,"determined"))
857 :     {
858 :     continue;
859 :     }
860 :    
861 :     if (strstr(VBUFF,"not supported"))
862 :     {
863 :     continue;
864 :     }
865 :    
866 :     if (strstr(VBUFF,"denied") || strstr(VBUFF,"RPC"))
867 :     {
868 :     CfLog(cferror,"There was a mount error, trying to mount one of the filesystems on this host.\n","");
869 :     snprintf(OUTPUT,bufsize*2,"%s\n",VBUFF);
870 :     CfLog(cferror,OUTPUT,"");
871 :     GOTMOUNTINFO = false;
872 :     break;
873 :     }
874 :    
875 :     if (strstr(VBUFF,"trying") && !strstr(VBUFF,"NFS version 2"))
876 :     {
877 :     CfLog(cferror,"Aborted because MountFileSystems() went into a retry loop.\n","");
878 :     GOTMOUNTINFO = false;
879 :     break;
880 :     }
881 :     }
882 :    
883 :     alarm(0);
884 :     signal(SIGALRM,SIG_DFL);
885 :     cfpclose(pp);
886 :     }
887 :    
888 :     /*******************************************************************/
889 :    
890 :     void CheckRequired()
891 :    
892 :     { struct Disk *rp;
893 :     struct Item *ip;
894 :     int matched,varstring,missing = 0;
895 :     char path[bufsize],expand[bufsize];
896 :    
897 :     ACTION=required;
898 :    
899 :     for (rp = VREQUIRED; rp != NULL; rp = rp->next)
900 :     {
901 :     if (IsExcluded(rp->classes))
902 :     {
903 :     continue;
904 :     }
905 :    
906 :     if (rp->done == 'y')
907 :     {
908 :     continue;
909 :     }
910 :     else
911 :     {
912 :     rp->done = 'y';
913 :     }
914 :    
915 :     if (!GetLock(ASUniqueName("disks"),rp->name,VIFELAPSED,VEXPIREAFTER,VUQNAME,CFSTARTTIME))
916 :     {
917 :     continue;
918 :     }
919 :    
920 :     ResetOutputRoute(rp->log,rp->inform);
921 :     matched = varstring = false;
922 :    
923 :     for(ip = VBINSERVERS; ip != NULL && (!matched); ip = ip->next)
924 :     {
925 :     path[0] = expand[0] = '\0';
926 :    
927 :     ExpandVarstring(rp->name,expand,NULL);
928 :     varstring = ExpandVarbinserv(expand,path,ip->name);
929 :    
930 :     if (RequiredFileSystemOkay(path)) /* simple or reduced item */
931 :     {
932 :     Verbose("Filesystem %s looks sensible\n",path);
933 :     matched = true;
934 :    
935 :     if (rp->freespace == -1)
936 :     {
937 :     AddMultipleClasses(rp->elsedef);
938 :     }
939 :     }
940 :     else if (! varstring)
941 :     {
942 :     snprintf(OUTPUT,bufsize*2,"The file %s does not exist or is suspicious.\n\n",path);
943 :     CfLog(cferror,OUTPUT,"");
944 :    
945 :     /* Define the class if there was no freespace option. */
946 :     if (rp->freespace == -1)
947 :     {
948 :     AddMultipleClasses(rp->define);
949 :     }
950 :     }
951 :    
952 :     if (! varstring) /* don't iterate over binservers if not var */
953 :     {
954 :     break;
955 :     }
956 :     }
957 :    
958 :     if ((rp->freespace != -1))
959 :     {
960 :     if (!CheckFreeSpace(path,rp->freespace))
961 :     {
962 :     Verbose("Free space below %d, defining %s\n",rp->freespace, rp->define);
963 :     AddMultipleClasses(rp->define);
964 :     }
965 :     else
966 :     {
967 :     Verbose("Free space above %d, defining %s\n",rp->freespace, rp->elsedef);
968 :     AddMultipleClasses(rp->elsedef);
969 :     }
970 :     }
971 :    
972 :     if (matched == false && ip == NULL)
973 :     {
974 :     printf(" didn't find any file to match the required filesystem %s\n",rp->name);
975 :     missing++;
976 :     }
977 :    
978 :     ReleaseCurrentLock();
979 :     }
980 :    
981 :     if (missing)
982 :    
983 :     { time_t tloc;;
984 :    
985 :     if ((tloc = time((time_t *)NULL)) == -1)
986 :     {
987 :     printf("Couldn't read system clock\n");
988 :     }
989 :     snprintf(OUTPUT,bufsize*2,"MESSAGE at %s\n\n",ctime(&tloc));
990 :     CfLog(cferror,OUTPUT,"");
991 :     snprintf(OUTPUT,bufsize*2,"There are %d required file(system)s missing on host <%s>\n",missing,VDEFAULTBINSERVER.name);
992 :     CfLog(cferror,OUTPUT,"");
993 :     CfLog(cferror,"even after all mounts have been attempted.\n","");
994 :     CfLog(cferror,"This may be caused by a failure to mount a network filesystem (check exports)\n","");
995 :     snprintf(OUTPUT,bufsize*2,"or because no valid server was specified in the program %s\n\n",VINPUTFILE);
996 :     CfLog(cferror,OUTPUT,"");
997 :    
998 :     ResetOutputRoute('d','d');
999 :     }
1000 :     }
1001 :    
1002 :     /*******************************************************************/
1003 :    
1004 :     void TidyFiles()
1005 :    
1006 :     /* Here we start by scanning for any absolute path wildcards */
1007 :     /* After that's finished, we go snooping around the homedirs */
1008 :    
1009 :     { char basename[bufsize],pathbuff[bufsize];
1010 :     struct TidyPattern *tlp;
1011 :     struct Tidy *tp;
1012 :     struct Item *ip1,*ip2;
1013 :     struct stat statbuf;
1014 :     int homesearch = 0;
1015 :    
1016 :     Banner("Tidying Spool Directories");
1017 :    
1018 :     for (ip1 = SPOOLDIRLIST; ip1 != NULL; ip1=ip1->next)
1019 :     {
1020 :     if (!IsExcluded(ip1->classes))
1021 :     {
1022 :     ExpiredUserCheck(ip1->name,true);
1023 :     }
1024 :     }
1025 :    
1026 :     Banner("Tidying by directory");
1027 :    
1028 :     for (tp = VTIDY; tp != NULL; tp=tp->next)
1029 :     {
1030 :     if (strncmp(tp->path,"home",4)==0)
1031 :     {
1032 :     for (tlp = tp->tidylist; tlp != NULL; tlp=tlp->next)
1033 :     {
1034 :     if (!IsExcluded(tlp->classes))
1035 :     {
1036 :     homesearch = 1;
1037 :     break;
1038 :     }
1039 :     }
1040 :     continue;
1041 :     }
1042 :    
1043 :     for (tlp = tp->tidylist; tlp != NULL; tlp=tlp->next)
1044 :     {
1045 :     if (IsExcluded(tlp->classes))
1046 :     {
1047 :     continue;
1048 :     }
1049 :    
1050 :     Verbose("Directory %s\n",tp->path);
1051 :     strcpy(VBUFF,tp->path);
1052 :     AddSlash(VBUFF);
1053 :     strcat(VBUFF,tlp->pattern);
1054 :    
1055 :     if (stat(VBUFF,&statbuf) != -1) /* not lstat - could confuse user */
1056 :     {
1057 :     if (S_ISDIR(statbuf.st_mode))
1058 :     {
1059 :     if (! tlp->rmdirs) /* Are we allowed to rm empty dirs? */
1060 :     {
1061 :     Verbose("%s: will not delete directories (matching %s)!\n",VPREFIX,tlp->pattern);
1062 :     Verbose("%s: Applies to %s\n",VPREFIX,VBUFF);
1063 :     DeleteTidyList(tp->tidylist);
1064 :     tp->tidylist = NULL;
1065 :     continue;
1066 :     }
1067 :     }
1068 :     }
1069 :     }
1070 :    
1071 :     basename[0] = '\0';
1072 :    
1073 :     ExpandWildCardsAndDo(tp->path,basename,TidyWrapper,tp);
1074 :    
1075 :     DeleteTidyList(tp->tidylist);
1076 :     tp->tidylist = NULL;
1077 :     }
1078 :    
1079 :    
1080 :     Debug2("End PATHTIDY:\n");
1081 :    
1082 :     if (!homesearch) /* If there are "home" wildcards */
1083 :     { /* Don't go rummaging around the disks */
1084 :     Verbose("No home patterns to search\n");
1085 :     return;
1086 :     }
1087 :    
1088 :     if (!IsPrivileged())
1089 :     {
1090 :     CfLog(cferror,"Only root can delete others' files.\n","");
1091 :     return;
1092 :     }
1093 :    
1094 :    
1095 :     Banner("Tidying home directories");
1096 :    
1097 :     if (!MountPathDefined())
1098 :     {
1099 :     return;
1100 :     }
1101 :    
1102 :     for (ip1 = VHOMEPATLIST; ip1 != NULL; ip1=ip1->next)
1103 :     {
1104 :     for (ip2 = VMOUNTLIST; ip2 != NULL; ip2=ip2->next)
1105 :     {
1106 :     if (IsExcluded(ip2->classes))
1107 :     {
1108 :     continue;
1109 :     }
1110 :     pathbuff[0]='\0';
1111 :     basename[0]='\0';
1112 :     strcpy(pathbuff,ip2->name);
1113 :     AddSlash(pathbuff);
1114 :     strcat(pathbuff,ip1->name);
1115 :    
1116 :     ExpandWildCardsAndDo(pathbuff,basename,RecHomeTidyWrapper,NULL);
1117 :     }
1118 :     }
1119 :    
1120 :     Verbose("Done with home directories\n");
1121 :     }
1122 :    
1123 :     /*******************************************************************/
1124 :    
1125 :     void Scripts()
1126 :    
1127 :     { struct ShellComm *ptr;
1128 :     char line[bufsize];
1129 :     char comm[20], *sp;
1130 :     char execstr[bufsize];
1131 :     int print;
1132 :     mode_t maskval = 0;
1133 :     FILE *pp;
1134 :     int preview = false;
1135 :    
1136 :     for (ptr = VSCRIPT; ptr != NULL; ptr=ptr->next)
1137 :     {
1138 :     preview = (ptr->preview == 'y');
1139 :    
1140 :     if (IsExcluded(ptr->classes))
1141 :     {
1142 :     continue;
1143 :     }
1144 :    
1145 :     if (ptr->done == 'y')
1146 :     {
1147 :     continue;
1148 :     }
1149 :     else
1150 :     {
1151 :     ptr->done = 'y';
1152 :     }
1153 :    
1154 :     ResetOutputRoute(ptr->log,ptr->inform);
1155 :    
1156 :     if (!GetLock(ASUniqueName("shellcommand"),CanonifyName(ptr->name),VIFELAPSED,VEXPIREAFTER,VUQNAME,CFSTARTTIME))
1157 :     {
1158 :     continue;
1159 :     }
1160 :    
1161 :     bzero(execstr,bufsize);
1162 :     ExpandVarstring(ptr->name,execstr,NULL);
1163 :    
1164 :     snprintf(OUTPUT,bufsize*2,"Executing script %s...(timeout=%d,uid=%d,gid=%d)\n",execstr,ptr->timeout,ptr->uid,ptr->gid);
1165 :     CfLog(cfinform,OUTPUT,"");
1166 :    
1167 :     if (DONTDO && preview != 'y')
1168 :     {
1169 :     printf("%s: execute script %s\n",VPREFIX,execstr);
1170 :     }
1171 :     else
1172 :     {
1173 :     for (sp = execstr; *sp != ' ' && *sp != '\0'; sp++)
1174 :     {
1175 :     }
1176 :    
1177 :     if (sp - 10 >= execstr)
1178 :     {
1179 :     sp -= 10; /* copy 15 most relevant characters of command */
1180 :     }
1181 :     else
1182 :     {
1183 :     sp = execstr;
1184 :     }
1185 :    
1186 :     bzero(comm,20);
1187 :     strncpy(comm,sp,15);
1188 :    
1189 :     if (ptr->timeout != 0)
1190 :     {
1191 :     signal(SIGALRM,(void *)TimeOut);
1192 :     alarm(ptr->timeout);
1193 :     }
1194 :    
1195 :     Verbose("(Setting umask to %o)\n",ptr->umask);
1196 :     maskval = umask(ptr->umask);
1197 :    
1198 :     if (ptr->umask == 0)
1199 :     {
1200 :     snprintf(OUTPUT,bufsize*2,"Programming %s running with umask 0! Use umask= to set\n",execstr);
1201 :     CfLog(cfsilent,OUTPUT,"");
1202 :     }
1203 :    
1204 :     switch (ptr->useshell)
1205 :     {
1206 :     case 'y': pp = cfpopen_shsetuid(execstr,"r",ptr->uid,ptr->gid,ptr->chdir,ptr->chroot);
1207 :     break;
1208 :     default: pp = cfpopensetuid(execstr,"r",ptr->uid,ptr->gid,ptr->chdir,ptr->chroot);
1209 :     break;
1210 :     }
1211 :    
1212 :     if (pp == NULL)
1213 :     {
1214 :     snprintf(OUTPUT,bufsize*2,"Couldn't open pipe to command %s\n",execstr);
1215 :     CfLog(cferror,OUTPUT,"popen");
1216 :     ResetOutputRoute('d','d');
1217 :     ReleaseCurrentLock();
1218 :     continue;
1219 :     }
1220 :    
1221 :     while (!feof(pp))
1222 :     {
1223 :     if (ferror(pp)) /* abortable */
1224 :     {
1225 :     snprintf(OUTPUT,bufsize*2,"Shell command pipe %s\n",execstr);
1226 :     CfLog(cferror,OUTPUT,"ferror");
1227 :     break;
1228 :     }
1229 :    
1230 :     ReadLine(line,bufsize,pp);
1231 :    
1232 :     if (strstr(line,"cfengine-die"))
1233 :     {
1234 :     break;
1235 :     }
1236 :    
1237 :     if (ferror(pp)) /* abortable */
1238 :     {
1239 :     snprintf(OUTPUT,bufsize*2,"Shell command pipe %s\n",execstr);
1240 :     CfLog(cferror,OUTPUT,"ferror");
1241 :     break;
1242 :     }
1243 :    
1244 :     if (preview)
1245 :     {
1246 :     /*
1247 :     * Preview script - try to parse line as log message. If line does
1248 :     * not parse, then log as error.
1249 :     */
1250 :    
1251 :     int i;
1252 :     int level = cferror;
1253 :     char *message = line;
1254 :    
1255 :     /*
1256 :     * Table matching cfoutputlevel enums to log prefixes.
1257 :     */
1258 :    
1259 :     char *prefixes[] =
1260 :     {
1261 :     ":silent:",
1262 :     ":inform:",
1263 :     ":verbose:",
1264 :     ":editverbose:",
1265 :     ":error:",
1266 :     ":logonly:",
1267 :     };
1268 :     int precount = sizeof(prefixes)/sizeof(char *);
1269 :    
1270 :     if (line[0] == ':')
1271 :     {
1272 :     /*
1273 :     * Line begins with colon - see if it matches a log prefix.
1274 :     */
1275 :    
1276 :     for (i=0; i<precount; i++)
1277 :     {
1278 :     int prelen = 0;
1279 :     prelen = strlen(prefixes[i]);
1280 :     if (strncmp(line, prefixes[i], prelen) == 0)
1281 :     {
1282 :     /*
1283 :     * Found log prefix - set logging level, and remove the
1284 :     * prefix from the log message.
1285 :     */
1286 :     level = i;
1287 :     message += prelen;
1288 :     break;
1289 :     }
1290 :     }
1291 :     }
1292 :     CfLog(level, message, "");
1293 :     }
1294 :     else
1295 :     {
1296 :     /*
1297 :     * Dumb script - echo non-empty lines to standard output.
1298 :     */
1299 :    
1300 :     print = false;
1301 :    
1302 :     for (sp = line; *sp != '\0'; sp++)
1303 :     {
1304 :     if (! isspace((int)*sp))
1305 :     {
1306 :     print = true;
1307 :     break;
1308 :     }
1309 :     }
1310 :    
1311 :     if (print)
1312 :     {
1313 :     printf("%s:%s: %s\n",VPREFIX,comm,line);
1314 :     }
1315 :     }
1316 :     }
1317 :    
1318 :     cfpclose_def(pp,ptr->defines,ptr->elsedef);
1319 :     }
1320 :    
1321 :     if (ptr->timeout != 0)
1322 :     {
1323 :     alarm(0);
1324 :     signal(SIGALRM,SIG_DFL);
1325 :     }
1326 :    
1327 :     umask(maskval);
1328 :    
1329 :     snprintf(OUTPUT,bufsize*2,"Finished script %s\n",execstr);
1330 :     CfLog(cfinform,OUTPUT,"");
1331 :    
1332 :     ResetOutputRoute('d','d');
1333 :     ReleaseCurrentLock();
1334 :     }
1335 :     }
1336 :    
1337 :     /*******************************************************************/
1338 :    
1339 :     void GetSetuidLog()
1340 :    
1341 :     { struct Item *filetop = NULL;
1342 :     struct Item *ip;
1343 :     FILE *fp;
1344 :     char *sp;
1345 :    
1346 :     if (!IsPrivileged()) /* Ignore this if not root */
1347 :     {
1348 :     return;
1349 :     }
1350 :    
1351 :     if ((fp = fopen(VSETUIDLOG,"r")) == NULL)
1352 :     {
1353 :     }
1354 :     else
1355 :     {
1356 :     while (!feof(fp))
1357 :     {
1358 :     ReadLine(VBUFF,bufsize,fp);
1359 :    
1360 :     if (strlen(VBUFF) == 0)
1361 :     {
1362 :     continue;
1363 :     }
1364 :    
1365 :     if ((ip = (struct Item *)malloc (sizeof(struct Item))) == NULL)
1366 :     {
1367 :     perror("malloc");
1368 :     FatalError("GetSetuidList() couldn't allocate memory #1");
1369 :     }
1370 :    
1371 :     if ((sp = malloc(strlen(VBUFF)+2)) == NULL)
1372 :     {
1373 :     perror("malloc");
1374 :     FatalError("GetSetuidList() couldn't allocate memory #2");
1375 :     }
1376 :    
1377 :     if (filetop == NULL)
1378 :     {
1379 :     VSETUIDLIST = filetop = ip;
1380 :     }
1381 :     else
1382 :     {
1383 :     filetop->next = ip;
1384 :     }
1385 :    
1386 :     Debug2("SETUID-LOG: %s\n",VBUFF);
1387 :    
1388 :     strcpy(sp,VBUFF);
1389 :     ip->name = sp;
1390 :     ip->next = NULL;
1391 :     filetop = ip;
1392 :     }
1393 :    
1394 :     fclose(fp);
1395 :     }
1396 :    
1397 :     }
1398 :    
1399 :     /*******************************************************************/
1400 :    
1401 :     void CheckFiles() /* Check through file systems */
1402 :    
1403 :     { struct File *ptr;
1404 :     char buffer[bufsize];
1405 :     short savetravlinks = TRAVLINKS;
1406 :     short savekilloldlinks = KILLOLDLINKS;
1407 :    
1408 :     if (TRAVLINKS && (VERBOSE || DEBUG || D2))
1409 :     {
1410 :     printf("(Default in switched to purge stale links...)\n");
1411 :     }
1412 :    
1413 :     for (ptr = VFILE; ptr != NULL; ptr=ptr->next)
1414 :     {
1415 :     if (IsExcluded(ptr->classes))
1416 :     {
1417 :     continue;
1418 :     }
1419 :    
1420 :     if (ptr->done == 'y')
1421 :     {
1422 :     continue;
1423 :     }
1424 :     else
1425 :     {
1426 :     ptr->done = 'y';
1427 :     }
1428 :    
1429 :     TRAVLINKS = savetravlinks;
1430 :    
1431 :     if (ptr->travlinks == 'T')
1432 :     {
1433 :     TRAVLINKS = true;
1434 :     }
1435 :     else if (ptr->travlinks == 'F')
1436 :     {
1437 :     TRAVLINKS = false;
1438 :     }
1439 :     else if (ptr->travlinks == 'K')
1440 :     {
1441 :     KILLOLDLINKS = true;
1442 :     }
1443 :    
1444 :     ResetOutputRoute(ptr->log,ptr->inform);
1445 :    
1446 :     if (strncmp(ptr->path,"home",4) == 0)
1447 :     {
1448 :     CheckHome(ptr);
1449 :     continue;
1450 :     }
1451 :    
1452 :     Verbose("Checking file(s) in %s\n",ptr->path);
1453 :    
1454 :     buffer[0] = '\0';
1455 :    
1456 :     ExpandWildCardsAndDo(ptr->path,buffer,CheckFileWrapper,ptr);
1457 :    
1458 :     ResetOutputRoute('d','d');
1459 :     TRAVLINKS = savetravlinks;
1460 :     KILLOLDLINKS = savekilloldlinks;
1461 :     }
1462 :     }
1463 :    
1464 :     /*******************************************************************/
1465 :    
1466 :     void SaveSetuidLog()
1467 :    
1468 :     { FILE *fp;
1469 :     struct Item *ip;
1470 :    
1471 :    
1472 :     if (!IsPrivileged()) /* Ignore this if not root */
1473 :     {
1474 :     return;
1475 :     }
1476 :    
1477 :     if (! DONTDO)
1478 :     {
1479 :     if ((fp = fopen(VSETUIDLOG,"w")) == NULL)
1480 :     {
1481 :     snprintf(OUTPUT,bufsize*2,"Can't open %s for writing\n",VSETUIDLOG);
1482 :     CfLog(cferror,OUTPUT,"fopen");
1483 :     return;
1484 :     }
1485 :    
1486 :     Verbose("Saving the setuid log in %s\n",VSETUIDLOG);
1487 :    
1488 :     for (ip = VSETUIDLIST; ip != NULL; ip=ip->next)
1489 :     {
1490 :     if (!isspace((int)*(ip->name)) && strlen(ip->name) != 0)
1491 :     {
1492 :     fprintf(fp,"%s\n",ip->name);
1493 :     Debug2("SAVE-SETUID-LOG: %s\n",ip->name);
1494 :     }
1495 :     }
1496 :    
1497 :     fclose(fp);
1498 :     chmod(VSETUIDLOG,0600);
1499 :     }
1500 :     }
1501 :    
1502 :     /*******************************************************************/
1503 :    
1504 :     void DisableFiles()
1505 :    
1506 :     { struct Disable *dp;
1507 :     struct stat statbuf;
1508 :     char workname[bufsize],path[bufsize];
1509 :    
1510 :     for (dp = VDISABLELIST; dp != NULL; dp=dp->next)
1511 :     {
1512 :     if (IsExcluded(dp->classes))
1513 :     {
1514 :     continue;
1515 :     }
1516 :    
1517 :     if (dp->done == 'y')
1518 :     {
1519 :     continue;
1520 :     }
1521 :     else
1522 :     {
1523 :     dp->done = 'y';
1524 :     }
1525 :    
1526 :     if (!GetLock(ASUniqueName("disable"),CanonifyName(dp->name),VIFELAPSED,VEXPIREAFTER,VUQNAME,CFSTARTTIME))
1527 :     {
1528 :     continue;
1529 :     }
1530 :    
1531 :     ExpandVarstring(dp->name,workname,NULL);
1532 :    
1533 :     ResetOutputRoute(dp->log,dp->inform);
1534 :    
1535 :     if (lstat(workname,&statbuf) == -1)
1536 :     {
1537 :     Verbose("Filetype %s, %s is not there - ok\n",dp->type,workname);
1538 :     AddMultipleClasses(dp->elsedef);
1539 :     ReleaseCurrentLock();
1540 :     continue;
1541 :     }
1542 :    
1543 :     if (S_ISDIR(statbuf.st_mode))
1544 :     {
1545 :     if ((strcmp(dp->type,"file") != 0) && (strcmp(dp->type,"link") != 0))
1546 :     {
1547 :     snprintf(OUTPUT,bufsize*2,"Warning %s is a directory.\n",workname);
1548 :     CfLog(cferror,OUTPUT,"");
1549 :     CfLog(cferror,"I refuse to rename/delete a directory!\n\n","");
1550 :     }
1551 :     else
1552 :     {
1553 :     Verbose("Filetype %s, %s is not there - ok\n",dp->type,workname);
1554 :     }
1555 :     ResetOutputRoute('d','d');
1556 :     ReleaseCurrentLock();
1557 :     continue;
1558 :     }
1559 :    
1560 :     Verbose("Disable checking %s\n",workname);
1561 :    
1562 :     if (S_ISLNK(statbuf.st_mode))
1563 :     {
1564 :     if (strcmp(dp->type,"file") == 0)
1565 :     {
1566 :     Verbose("%s: %s is a link, not disabling\n",VPREFIX,workname);
1567 :     ResetOutputRoute('d','d');
1568 :     ReleaseCurrentLock();
1569 :     continue;
1570 :     }
1571 :    
1572 :     bzero(VBUFF,bufsize);
1573 :    
1574 :     if (readlink(workname,VBUFF,bufsize-1) == -1)
1575 :     {
1576 :     snprintf(OUTPUT,bufsize*2,"DisableFiles() can't read link %s\n",workname);
1577 :     CfLog(cferror,OUTPUT,"readlink");
1578 :     ResetOutputRoute('d','d');
1579 :     ReleaseCurrentLock();
1580 :     continue;
1581 :     }
1582 :    
1583 :     if (dp->action == 'd')
1584 :     {
1585 :     printf("%s: Deleting link %s -> %s\n",VPREFIX,workname,VBUFF);
1586 :    
1587 :     if (! DONTDO)
1588 :     {
1589 :     if (unlink(workname) == -1)
1590 :     {
1591 :     snprintf(OUTPUT,bufsize*2,"Error while unlinking %s\n",workname);
1592 :     CfLog(cferror,OUTPUT,"unlink");
1593 :     ResetOutputRoute('d','d');
1594 :     ReleaseCurrentLock();
1595 :     continue;
1596 :     }
1597 :    
1598 :     AddMultipleClasses(dp->defines);
1599 :     }
1600 :     }
1601 :     else
1602 :     {
1603 :     snprintf(OUTPUT,bufsize,"Warning - file %s exists\n",workname);
1604 :     CfLog(cferror,OUTPUT,"");
1605 :     }
1606 :     }
1607 :     else
1608 :     {
1609 :     if (! S_ISREG(statbuf.st_mode))
1610 :     {
1611 :     Verbose("%s: %s is not a plain file - won't disable\n",VPREFIX,workname);
1612 :     ResetOutputRoute('d','d');
1613 :     ReleaseCurrentLock();
1614 :     continue;
1615 :     }
1616 :    
1617 :     if (strcmp(dp->type,"link") == 0)
1618 :     {
1619 :     Verbose("%s: %s is a file, not disabling\n",VPREFIX,workname);
1620 :     ResetOutputRoute('d','d');
1621 :     ReleaseCurrentLock();
1622 :     continue;
1623 :     }
1624 :    
1625 :     if (stat(workname,&statbuf) == -1)
1626 :     {
1627 :     CfLog(cferror,"Internal; error in Disable\n","");
1628 :     ResetOutputRoute('d','d');
1629 :     ReleaseCurrentLock();
1630 :     return;
1631 :     }
1632 :    
1633 :     if (dp->size != cfnosize)
1634 :     {
1635 :     switch (dp->comp)
1636 :     {
1637 :     case '<': if (statbuf.st_size < dp->size)
1638 :     {
1639 :     Verbose("cfengine %s is smaller than %d bytes\n",workname,dp->size);
1640 :     break;
1641 :     }
1642 :     Verbose("Size is okay\n");
1643 :     ResetOutputRoute('d','d');
1644 :     ReleaseCurrentLock();
1645 :     continue;
1646 :    
1647 :     case '=': if (statbuf.st_size == dp->size)
1648 :     {
1649 :     Verbose("cfengine %s is equal to %d bytes\n",workname,dp->size);
1650 :     break;
1651 :     }
1652 :     Verbose("Size is okay\n");
1653 :     ResetOutputRoute('d','d');
1654 :     ReleaseCurrentLock();
1655 :     continue;
1656 :    
1657 :     default: if (statbuf.st_size > dp->size)
1658 :     {
1659 :     Verbose("cfengine %s is larger than %d bytes\n",workname,dp->size);
1660 :     break;
1661 :     }
1662 :     Verbose("Size is okay\n");
1663 :     ResetOutputRoute('d','d');
1664 :     ReleaseCurrentLock();
1665 :     continue;
1666 :     }
1667 :     }
1668 :    
1669 :     if (dp->rotate == 0)
1670 :     {
1671 :     strcpy(path,workname);
1672 :     strcat(path,".cfdisabled");
1673 :    
1674 :     snprintf(OUTPUT,bufsize*2,"Disabling file %s\n",workname);
1675 :     CfLog(cfinform,OUTPUT,"");
1676 :    
1677 :     if (! DONTDO)
1678 :     {
1679 :     chmod(workname, (mode_t)0600);
1680 :    
1681 :     if (! IsItemIn(VREPOSLIST,path))
1682 :     {
1683 :     if (dp->action == 'd')
1684 :     {
1685 :     if (rename(workname,path) == -1)
1686 :     {
1687 :     snprintf(OUTPUT,bufsize*2,"Error occurred while renaming %s\n",workname);
1688 :     CfLog(cferror,OUTPUT,"rename");
1689 :     ResetOutputRoute('d','d');
1690 :     ReleaseCurrentLock();
1691 :     continue;
1692 :     }
1693 :    
1694 :     if (Repository(path,dp->repository))
1695 :     {
1696 :     unlink(path);
1697 :     }
1698 :    
1699 :     AddMultipleClasses(dp->defines);
1700 :     }
1701 :     else
1702 :     {
1703 :     snprintf(OUTPUT,bufsize,"Warning - file %s exists (need to disable)",workname);
1704 :     CfLog(cferror,OUTPUT,"");
1705 :     }
1706 :     }
1707 :     }
1708 :     }
1709 :     else if (dp->rotate == CF_TRUNCATE)
1710 :     {
1711 :     snprintf(OUTPUT,bufsize*2,"Truncating (emptying) %s\n",workname);
1712 :     CfLog(cfinform,OUTPUT,"");
1713 :    
1714 :     if (dp->action == 'd')
1715 :     {
1716 :     if (! DONTDO)
1717 :     {
1718 :     TruncateFile(workname);
1719 :     AddMultipleClasses(dp->defines);
1720 :     }
1721 :     }
1722 :     else
1723 :     {
1724 :     snprintf(OUTPUT,bufsize,"File %s needs emptying",workname);
1725 :     CfLog(cferror,OUTPUT,"");
1726 :     }
1727 :     }
1728 :     else
1729 :     {
1730 :     snprintf(OUTPUT,bufsize*2,"Rotating files %s by %d\n",workname,dp->rotate);
1731 :     CfLog(cfinform,OUTPUT,"");
1732 :    
1733 :     if (dp->action == 'd')
1734 :     {
1735 :     if (!DONTDO)
1736 :     {
1737 :     RotateFiles(workname,dp->rotate);
1738 :     AddMultipleClasses(dp->defines);
1739 :     }
1740 :     else
1741 :     {
1742 :     snprintf(OUTPUT,bufsize,"File %s needs rotating/emptying",workname);
1743 :     CfLog(cferror,OUTPUT,"");
1744 :     }
1745 :     }
1746 :     }
1747 :     }
1748 :     ResetOutputRoute('d','d');
1749 :     ReleaseCurrentLock();
1750 :     }
1751 :     }
1752 :    
1753 :     /*******************************************************************/
1754 :    
1755 :     void MountHomeBinServers()
1756 :    
1757 :     { struct Item *mp;
1758 :     char host[maxvarsize];
1759 :     char mountdir[bufsize];
1760 :     char maketo[bufsize];
1761 :    
1762 :     if (! GOTMOUNTINFO)
1763 :     {
1764 :     CfLog(cfinform,"Incomplete mount info due to RPC failure.\n","");
1765 :     snprintf(OUTPUT,bufsize*2,"%s will not be modified on this pass!\n\n",VFSTAB[VSYSTEMHARDCLASS]);
1766 :     CfLog(cfinform,OUTPUT,"");
1767 :     return;
1768 :     }
1769 :    
1770 :     if (!IsPrivileged())
1771 :     {
1772 :     CfLog(cferror,"Only root can mount filesystems.\n","");
1773 :     return;
1774 :     }
1775 :    
1776 :     Banner("Checking home and binservers");
1777 :    
1778 :     for (mp = VMOUNTABLES; mp != NULL; mp=mp->next)
1779 :     {
1780 :     sscanf(mp->name,"%[^:]:%s",host,mountdir);
1781 :    
1782 :     if (mp->done == 'y')
1783 :     {
1784 :     continue;
1785 :     }
1786 :     else
1787 :     {
1788 :     mp->done = 'y';
1789 :     }
1790 :    
1791 :     Debug("Mount: checking %s\n",mp->name);
1792 :    
1793 :     strcpy(maketo,mountdir);
1794 :    
1795 :     if (maketo[strlen(maketo)-1] == '/')
1796 :     {
1797 :     strcat(maketo,".");
1798 :     }
1799 :     else
1800 :     {
1801 :     strcat(maketo,"/.");
1802 :     }
1803 :    
1804 :     if (strcmp(host,VDEFAULTBINSERVER.name) == 0) /* A host never mounts itself nfs */
1805 :     {
1806 :     Debug("Skipping host %s\n",host);
1807 :     continue;
1808 :     }
1809 :    
1810 :     if (IsHomeDir(mountdir))
1811 :     {
1812 :     if (!IsItemIn(VMOUNTED,mp->name) && IsClassedItemIn(VHOMESERVERS,host))
1813 :     {
1814 :     MakeDirectoriesFor(maketo,'n');
1815 :     AddToFstab(host,mountdir,mountdir,"rw",false);
1816 :     }
1817 :     else if (IsClassedItemIn(VHOMESERVERS,host))
1818 :     {
1819 :     AddToFstab(host,mountdir,mountdir,"rw",true);
1820 :     }
1821 :     }
1822 :     else
1823 :     {
1824 :     if (!IsItemIn(VMOUNTED,mp->name) && IsClassedItemIn(VBINSERVERS,host))
1825 :     {
1826 :     MakeDirectoriesFor(maketo,'n');
1827 :     AddToFstab(host,mountdir,mountdir,"rw",false);
1828 :     }
1829 :     else if (IsClassedItemIn(VBINSERVERS,host))
1830 :     {
1831 :     AddToFstab(host,mountdir,mountdir,"rw",true);
1832 :     }
1833 :     }
1834 :     }
1835 :     }
1836 :    
1837 :    
1838 :     /*********************************************************************/
1839 :    
1840 :     void MountMisc()
1841 :    
1842 :     { struct MiscMount *mp;
1843 :     char host[maxvarsize];
1844 :     char mountdir[bufsize];
1845 :     char maketo[bufsize];
1846 :     char mtpt[bufsize];
1847 :    
1848 :     if (! GOTMOUNTINFO)
1849 :     {
1850 :     CfLog(cfinform,"Incomplete mount info due to RPC failure.\n","");
1851 :     snprintf(OUTPUT,bufsize*2,"%s will not be modified on this pass!\n\n",VFSTAB[VSYSTEMHARDCLASS]);
1852 :     CfLog(cfinform,OUTPUT,"");
1853 :     return;
1854 :     }
1855 :    
1856 :     if (!IsPrivileged())
1857 :     {
1858 :     CfLog(cferror,"Only root can mount filesystems.\n","");
1859 :     return;
1860 :     }
1861 :    
1862 :     Banner("Checking miscellaneous mountables:");
1863 :    
1864 :     for (mp = VMISCMOUNT; mp != NULL; mp=mp->next)
1865 :     {
1866 :     sscanf(mp->from,"%[^:]:%s",host,mountdir);
1867 :    
1868 :     if (mp->done == 'y')
1869 :     {
1870 :     continue;
1871 :     }
1872 :     else
1873 :     {
1874 :     mp->done = 'y';
1875 :     }
1876 :    
1877 :     strcpy(maketo,mp->onto);
1878 :    
1879 :     if (maketo[strlen(maketo)-1] == '/')
1880 :     {
1881 :     strcat(maketo,".");
1882 :     }
1883 :     else
1884 :     {
1885 :     strcat(maketo,"/.");
1886 :     }
1887 :    
1888 :     if (strcmp(host,VDEFAULTBINSERVER.name) == 0) /* A host never mounts itself nfs */
1889 :     {
1890 :     continue;
1891 :     }
1892 :    
1893 :     snprintf(mtpt,bufsize,"%s:%s",host,mp->onto);
1894 :    
1895 :     if (!IsItemIn(VMOUNTED,mtpt))
1896 :     {
1897 :     MakeDirectoriesFor(maketo,'n');
1898 :     AddToFstab(host,mountdir,mp->onto,mp->options,false);
1899 :     }
1900 :     else
1901 :     {
1902 :     AddToFstab(host,mountdir,mp->onto,mp->options,true);
1903 :     }
1904 :     }
1905 :     }
1906 :    
1907 :     /*********************************************************************/
1908 :    
1909 :     void Unmount()
1910 :    
1911 :     { struct UnMount *ptr;
1912 :     char comm[bufsize];
1913 :     char fs[bufsize];
1914 :     struct Item *filelist, *item;
1915 :     struct stat statbuf;
1916 :     FILE *pp;
1917 :    
1918 :     if (!IsPrivileged())
1919 :     {
1920 :     CfLog(cferror,"Only root can unmount filesystems.\n","");
1921 :     return;
1922 :     }
1923 :    
1924 :     filelist = NULL;
1925 :    
1926 :     if (! LoadItemList(&filelist,VFSTAB[VSYSTEMHARDCLASS]))
1927 :     {
1928 :     snprintf(OUTPUT,bufsize*2,"Couldn't open %s!\n",VFSTAB[VSYSTEMHARDCLASS]);
1929 :     CfLog(cferror,OUTPUT,"");
1930 :     return;
1931 :     }
1932 :    
1933 :     NUMBEROFEDITS = 0;
1934 :    
1935 :     for (ptr=VUNMOUNT; ptr != NULL; ptr=ptr->next)
1936 :     {
1937 :     if (IsExcluded(ptr->classes))
1938 :     {
1939 :     continue;
1940 :     }
1941 :    
1942 :     if (ptr->done == 'y')
1943 :     {
1944 :     continue;
1945 :     }
1946 :     else
1947 :     {
1948 :     ptr->done = 'y';
1949 :     }
1950 :    
1951 :     if (!GetLock(ASUniqueName("unmount"),CanonifyName(ptr->name),VIFELAPSED,VEXPIREAFTER,VUQNAME,CFSTARTTIME))
1952 :     {
1953 :     continue;
1954 :     }
1955 :    
1956 :     fs[0] = '\0';
1957 :    
1958 :     sscanf(ptr->name,"%*[^:]:%s",fs);
1959 :    
1960 :     if (strlen(fs) == 0)
1961 :     {
1962 :     ReleaseCurrentLock();
1963 :     continue;
1964 :     }
1965 :    
1966 :     snprintf(OUTPUT,bufsize*2,"Unmount filesystem %s on %s\n",fs,ptr->name);
1967 :     CfLog(cfverbose,OUTPUT,"");
1968 :    
1969 :     if (strcmp(fs,"/") == 0 || strcmp(fs,"/usr") == 0)
1970 :     {
1971 :     CfLog(cfinform,"Request to unmount / or /usr is refused!\n","");
1972 :     ReleaseCurrentLock();
1973 :     continue;
1974 :     }
1975 :    
1976 :     if (IsItemIn(VMOUNTED,ptr->name) && (! DONTDO))
1977 :     {
1978 :     snprintf(comm,bufsize,"%s %s",VUNMOUNTCOMM[VSYSTEMHARDCLASS],fs);
1979 :    
1980 :     if ((pp = cfpopen(comm,"r")) == NULL)
1981 :     {
1982 :     snprintf(OUTPUT,bufsize*2,"Failed to open pipe from %s\n",VUNMOUNTCOMM[VSYSTEMHARDCLASS]);
1983 :     CfLog(cferror,OUTPUT,"");
1984 :     ReleaseCurrentLock();
1985 :     return;
1986 :     }
1987 :    
1988 :     ReadLine(VBUFF,bufsize,pp);
1989 :    
1990 :     if (strstr(VBUFF,"busy") || strstr(VBUFF,"Busy"))
1991 :     {
1992 :     snprintf(OUTPUT,bufsize*2,"umount warned that the device under %s\n",ptr->name);
1993 :     CfLog(cfinform,OUTPUT,"");
1994 :     CfLog(cfinform,"was busy. Cannot unmount that device.\n","");
1995 :     /* don't delete the mount dir when unmount's failed */
1996 :     ptr->deletedir = ptr->deletefstab = 'n';
1997 :     }
1998 :     else
1999 :     {
2000 :     snprintf(OUTPUT,bufsize*2,"Unmounting %s\n",ptr->name);
2001 :     CfLog(cfinform,OUTPUT,"");
2002 :     DeleteItemStarting(&VMOUNTED,ptr->name); /* update mount record */
2003 :     }
2004 :    
2005 :     cfpclose(pp);
2006 :     }
2007 :    
2008 :     if (ptr->deletedir == 'y')
2009 :     {
2010 :     if (stat(fs,&statbuf) != -1)
2011 :     {
2012 :     if ( ! S_ISDIR(statbuf.st_mode))
2013 :     {
2014 :     snprintf(OUTPUT,bufsize*2,"Warning! %s was not a directory.\n",fs);
2015 :     CfLog(cfinform,OUTPUT,"");
2016 :     CfLog(cfinform,"(Unmount) will not delete this!\n","");
2017 :     KillOldLink(fs,NULL);
2018 :     }
2019 :     else if (! DONTDO)
2020 :     {
2021 :     if (rmdir(fs) == -1)
2022 :     {
2023 :     snprintf(OUTPUT,bufsize*2,"Unable to remove the directory %s\n",fs);
2024 :     CfLog(cferror,OUTPUT,"rmdir");
2025 :     }
2026 :     else
2027 :     {
2028 :     snprintf(OUTPUT,bufsize*2,"Removing directory %s\n",ptr->name);
2029 :     CfLog(cfinform,OUTPUT,"");
2030 :     }
2031 :     }
2032 :     }
2033 :     }
2034 :    
2035 :     if (ptr->deletefstab == 'y')
2036 :     {
2037 :     if (VSYSTEMHARDCLASS == aix)
2038 :     {
2039 :     strcpy (VBUFF,fs);
2040 :     strcat (VBUFF,":");
2041 :    
2042 :     item = LocateNextItemContaining(filelist,VBUFF);
2043 :    
2044 :     if (item->next == NULL)
2045 :     {
2046 :     snprintf(OUTPUT,bufsize*2,"Bad format in %s\n",VFSTAB[aix]);
2047 :     CfLog(cferror,OUTPUT,"");
2048 :     }
2049 :    
2050 :     DeleteItem(&filelist,item->next);
2051 :    
2052 :     while (strstr(item->next->name,"="))
2053 :     {
2054 :     DeleteItem(&filelist,item->next); /* DeleteItem(NULL) is harmless */
2055 :     }
2056 :     }
2057 :     else
2058 :     {
2059 :     Debug("Trying to delete filesystem %s from list\n",ptr->name);
2060 :    
2061 :     if (VSYSTEMHARDCLASS == ultrx) /* ensure name is not just a substring */
2062 :     {
2063 :     strcpy (VBUFF,ptr->name);
2064 :     strcat (VBUFF,":");
2065 :     DeleteItemContaining(&filelist,VBUFF);
2066 :     }
2067 :     else
2068 :     {
2069 :     switch (VSYSTEMHARDCLASS)
2070 :     {
2071 :     case unix_sv:
2072 :     case solarisx86:
2073 :     case solaris:
2074 :     /* find fs in proper context ("<host>:<remotepath> <-> <fs> ") */
2075 :     snprintf(VBUFF,bufsize,"[^:]+:[^ \t]+[ \t]+[^ \t]+[ \t]+%s[ \t]",fs);
2076 :     break;
2077 :     default:
2078 :     /* find fs in proper context ("<host>:<remotepath> <fs> ") */
2079 :     snprintf(VBUFF,bufsize,"[^:]+:[^ \t]+[ \t]+%s[ \t]",fs);
2080 :     break;
2081 :     }
2082 :     item = LocateItemContainingRegExp(filelist,VBUFF);
2083 :     DeleteItem(&filelist,item);
2084 :     }
2085 :     }
2086 :     }
2087 :    
2088 :     ReleaseCurrentLock();
2089 :     }
2090 :    
2091 :     if ((! DONTDO) && (NUMBEROFEDITS > 0))
2092 :     {
2093 :     SaveItemList(filelist,VFSTAB[VSYSTEMHARDCLASS],VREPOSITORY);
2094 :     }
2095 :    
2096 :     DeleteItemList(filelist);
2097 :     }
2098 :    
2099 :     /*********************************************************************/
2100 :    
2101 :     void EditFiles()
2102 :    
2103 :     { struct Edit *ptr;
2104 :     struct stat statbuf;
2105 :    
2106 :     Debug("Editfile()\n");
2107 :    
2108 :     for (ptr=VEDITLIST; ptr!=NULL; ptr=ptr->next)
2109 :     {
2110 :     if (ptr->done == 'y')
2111 :     {
2112 :     continue;
2113 :     }
2114 :    
2115 :     if (strncmp(ptr->fname,"home",4) == 0)
2116 :     {
2117 :     DoEditHomeFiles(ptr);
2118 :     }
2119 :     else
2120 :     {
2121 :     if (lstat(ptr->fname,&statbuf) != -1)
2122 :     {
2123 :     if (S_ISDIR(statbuf.st_mode))
2124 :     {
2125 :     DoRecursiveEditFiles(ptr->fname,ptr->recurse,ptr);
2126 :     }
2127 :     else
2128 :     {
2129 :     WrapDoEditFile(ptr,ptr->fname);
2130 :     }
2131 :     }
2132 :     else
2133 :     {
2134 :     DoEditFile(ptr,ptr->fname);
2135 :     }
2136 :     }
2137 :    
2138 :     /* ptr->done = 'y'; */
2139 :     }
2140 :    
2141 :     EDITVERBOSE = false;
2142 :     }
2143 :    
2144 :     /*******************************************************************/
2145 :    
2146 :     void CheckResolv()
2147 :    
2148 :     { struct Item *filebase = NULL, *referencefile = NULL;
2149 :     struct Item *ip;
2150 :     char ch;
2151 :     int fd, existed = true;
2152 :    
2153 :     Verbose("Checking config in %s\n",VRESOLVCONF[VSYSTEMHARDCLASS]);
2154 :    
2155 :     if (VDOMAIN == NULL)
2156 :     {
2157 :     CfLog(cferror,"Domain name not specified. Can't configure resolver\n","");
2158 :     return;
2159 :     }
2160 :    
2161 :     if (!IsPrivileged())
2162 :     {
2163 :     CfLog(cferror,"Only root can configure the resolver.\n","");
2164 :     return;
2165 :     }
2166 :    
2167 :     if (! LoadItemList(&referencefile,VRESOLVCONF[VSYSTEMHARDCLASS]))
2168 :     {
2169 :     snprintf(OUTPUT,bufsize*2,"Trying to create %s\n",VRESOLVCONF[VSYSTEMHARDCLASS]);
2170 :     CfLog(cfinform,OUTPUT,"");
2171 :     existed = false;
2172 :    
2173 :     if ((fd = creat(VRESOLVCONF[VSYSTEMHARDCLASS],0644)) == -1)
2174 :     {
2175 :     snprintf(OUTPUT,bufsize*2,"Unable to create file %s\n",VRESOLVCONF[VSYSTEMHARDCLASS]);
2176 :     CfLog(cferror,OUTPUT,"creat");
2177 :     return;
2178 :     }
2179 :     else
2180 :     {
2181 :     close(fd);
2182 :     }
2183 :     }
2184 :    
2185 :     if (existed)
2186 :     {
2187 :     LoadItemList(&filebase,VRESOLVCONF[VSYSTEMHARDCLASS]);
2188 :     }
2189 :    
2190 :     for (ip = filebase; ip != NULL; ip=ip->next)
2191 :     {
2192 :     if (strlen(ip->name) == 0)
2193 :     {
2194 :     continue;
2195 :     }
2196 :    
2197 :     ch = *(ip->name+strlen(ip->name)-2);
2198 :    
2199 :     if (isspace((int)ch))
2200 :     {
2201 :     snprintf(OUTPUT,bufsize*2,"Deleted line %s ended with a space in %s.\n",ip->name,VRESOLVCONF[VSYSTEMHARDCLASS]);
2202 :     CfLog(cfinform,OUTPUT,"");
2203 :     CfLog(cfinform,"The resolver doesn't understand this.\n","");
2204 :     DeleteItem(&filebase,ip);
2205 :     }
2206 :     else if (isspace((int)*(ip->name)))
2207 :     {
2208 :     snprintf(OUTPUT,bufsize*2,"Deleted line %s started with a space in %s.\n",ip->name,VRESOLVCONF[VSYSTEMHARDCLASS]);
2209 :     CfLog(cfinform,OUTPUT,"");
2210 :     CfLog(cfinform,"The resolver doesn't understand this.\n","");
2211 :     DeleteItem(&filebase,ip);
2212 :     }
2213 :     }
2214 :    
2215 :    
2216 :     snprintf(VBUFF,bufsize,"search %s",ToLowerStr(VDOMAIN));
2217 :     if (IsItemIn(filebase,VBUFF))
2218 :     {
2219 :     DeleteItemStarting(&filebase,VBUFF);
2220 :     }
2221 :     PrependItem(&filebase,VBUFF,NULL);
2222 :    
2223 :     DeleteItemStarting(&filebase,"domain");
2224 :     snprintf(VBUFF,bufsize,"domain %s",ToLowerStr(VDOMAIN));
2225 :     PrependItem(&filebase,VBUFF,NULL);
2226 :    
2227 :     if (GetMacroValue("EmptyResolvConf") && (strcmp(GetMacroValue("EmptyResolvConf"),"true") == 0))
2228 :     {
2229 :     while (DeleteItemStarting(&filebase,"nameserver "))
2230 :     {
2231 :     }
2232 :     }
2233 :    
2234 :     EditItemsInResolvConf(VRESOLVE,&filebase);
2235 :    
2236 :     if (DONTDO)
2237 :     {
2238 :     printf("Check %s for editing\n",VRESOLVCONF[VSYSTEMHARDCLASS]);
2239 :     }
2240 :     else if (!ItemListsEqual(filebase,referencefile))
2241 :     {
2242 :     SaveItemList(filebase,VRESOLVCONF[VSYSTEMHARDCLASS],VREPOSITORY);
2243 :     chmod(VRESOLVCONF[VSYSTEMHARDCLASS],DEFAULTSYSTEMMODE);
2244 :     }
2245 :     else
2246 :     {
2247 :     Verbose("cfengine: %s is okay\n",VRESOLVCONF[VSYSTEMHARDCLASS]);
2248 :     }
2249 :    
2250 :     DeleteItemList(filebase);
2251 :     DeleteItemList(referencefile);
2252 :     }
2253 :    
2254 :    
2255 :     /*******************************************************************/
2256 :    
2257 :     void MakeImages()
2258 :    
2259 :     { struct Image *ip;
2260 :     struct Item *svp;
2261 :     struct stat statbuf;
2262 :     struct servent *serverent;
2263 :     int savesilent;
2264 :     char path[bufsize];
2265 :     char destination[bufsize];
2266 :     char server[bufsize];
2267 :    
2268 :     if ((serverent = getservbyname(CFENGINE_SERVICE,"tcp")) == NULL)
2269 :     {
2270 :     CfLog(cfverbose,"Remember to register cfengine in /etc/services: cfengine 5308/tcp\n","getservbyname");
2271 :     PORTNUMBER = htons((unsigned short)5308);
2272 :     }
2273 :     else
2274 :     {
2275 :     PORTNUMBER = (unsigned short)(serverent->s_port); /* already in network order */
2276 :     }
2277 :    
2278 :     for (svp = VSERVERLIST; svp != NULL; svp=svp->next) /* order servers */
2279 :     {
2280 :     CONN = NewAgentConn(); /* Global input/output channel */
2281 :    
2282 :     if (CONN == NULL)
2283 :     {
2284 :     return;
2285 :     }
2286 :    
2287 :     for (ip = VIMAGE; ip != NULL; ip=ip->next)
2288 :     {
2289 :     if (strcmp(svp->name,ip->server) != 0) /* group together similar hosts so */
2290 :     { /* can can do multiple transactions */
2291 :     continue; /* on one connection */
2292 :     }
2293 :    
2294 :     if (IsExcluded(ip->classes))
2295 :     {
2296 :     continue;
2297 :     }
2298 :    
2299 :     if (ip->done == 'y')
2300 :     {
2301 :     continue;
2302 :     }
2303 :     else
2304 :     {
2305 :     ip->done = 'y';
2306 :     }
2307 :    
2308 :     if (!OpenServerConnection(ip))
2309 :     {
2310 :     snprintf(OUTPUT,bufsize*2,"Unable to establish connection with %s\n",svp->name);
2311 :     CfLog(cferror,OUTPUT,"");
2312 :     continue;
2313 :     }
2314 :    
2315 :     if (AUTHENTICATED)
2316 :     {
2317 :     Debug("Authentic connection verified\n");
2318 :     }
2319 :    
2320 :     IMAGEBACKUP = true;
2321 :    
2322 :     ExpandVarstring(ip->server,server,NULL);
2323 :     ExpandVarstring(ip->path,path,NULL);
2324 :     ExpandVarstring(ip->destination,destination,NULL);
2325 :    
2326 :     Verbose("Checking copy from %s:%s to %s\n",server,path,destination);
2327 :    
2328 :     savesilent = SILENT;
2329 :    
2330 :     if (strcmp(ip->action,"silent") == 0)
2331 :     {
2332 :     SILENT = true;
2333 :     }
2334 :    
2335 :     ResetOutputRoute(ip->log,ip->inform);
2336 :    
2337 :     snprintf(VBUFF,bufsize,"%.50s.%.50s",path,destination); /* Unique ID for copy locking */
2338 :    
2339 :     if (!GetLock(ASUniqueName("copy"),CanonifyName(VBUFF),VIFELAPSED,VEXPIREAFTER,VUQNAME,CFSTARTTIME))
2340 :     {
2341 :     SILENT = savesilent;
2342 :     ResetOutputRoute('d','d');
2343 :     continue;
2344 :     }
2345 :    
2346 :     IMAGEBACKUP = ip->backup;
2347 :    
2348 :     if (cfstat(path,&statbuf,ip) == -1)
2349 :     {
2350 :     snprintf(OUTPUT,bufsize*2,"Can't stat %s in copy\n",path);
2351 :     CfLog(cfinform,OUTPUT,"");
2352 :     ReleaseCurrentLock();
2353 :     SILENT = savesilent;
2354 :     ResetOutputRoute('d','d');
2355 :     continue;
2356 :     }
2357 :    
2358 :     if (strncmp(destination,"home",4) == 0)
2359 :     {
2360 :     HOMECOPY = true; /* Don't send home backups to repository */
2361 :     CheckHomeImages(ip);
2362 :     HOMECOPY = false;
2363 :     }
2364 :     else
2365 :     {
2366 :     if (S_ISDIR(statbuf.st_mode))
2367 :     {
2368 :     if (ip->purge == 'y')
2369 :     {
2370 :     Verbose("%s: (Destination purging enabled)\n",VPREFIX);
2371 :     }
2372 :     RecursiveImage(ip,path,destination,ip->recurse);
2373 :     }
2374 :     else
2375 :     {
2376 :     if (! MakeDirectoriesFor(destination,'n'))
2377 :     {
2378 :     ReleaseCurrentLock();
2379 :     SILENT = savesilent;
2380 :     ResetOutputRoute('d','d');
2381 :     continue;
2382 :     }
2383 :    
2384 :     CheckImage(path,destination,ip);
2385 :     }
2386 :     }
2387 :    
2388 :     ReleaseCurrentLock();
2389 :     SILENT = savesilent;
2390 :     ResetOutputRoute('d','d');
2391 :     }
2392 :    
2393 :     CloseServerConnection();
2394 :     DeleteAgentConn(CONN);
2395 :     }
2396 :     }
2397 :    
2398 :     /*******************************************************************/
2399 :    
2400 :     void ConfigureInterfaces()
2401 :    
2402 :     { struct Interface *ifp;
2403 :    
2404 :     if (GetLock("netconfig",VIFDEV[VSYSTEMHARDCLASS],VIFELAPSED,VEXPIREAFTER,VUQNAME,CFSTARTTIME))
2405 :     {
2406 :     if (strlen(VNETMASK) != 0)
2407 :     {
2408 :     IfConf(VIFDEV[VSYSTEMHARDCLASS],VNETMASK,VBROADCAST);
2409 :     }
2410 :    
2411 :     SetDefaultRoute();
2412 :     ReleaseCurrentLock();
2413 :     }
2414 :    
2415 :     for (ifp = VIFLIST; ifp != NULL; ifp=ifp->next)
2416 :     {
2417 :     if (!GetLock("netconfig",ifp->ifdev,VIFELAPSED,VEXPIREAFTER,VUQNAME,CFSTARTTIME))
2418 :     {
2419 :     continue;
2420 :     }
2421 :    
2422 :     if (ifp->done == 'y')
2423 :     {
2424 :     continue;
2425 :     }
2426 :     else
2427 :     {
2428 :     ifp->done = 'y';
2429 :     }
2430 :    
2431 :     IfConf(ifp->ifdev,ifp->netmask,ifp->broadcast);
2432 :     SetDefaultRoute();
2433 :     ReleaseCurrentLock();
2434 :     }
2435 :     }
2436 :    
2437 :     /*******************************************************************/
2438 :    
2439 :     void CheckTimeZone()
2440 :    
2441 :     { struct Item *ip;
2442 :     char tz[maxvarsize];
2443 :    
2444 :     if (VTIMEZONE == NULL)
2445 :     {
2446 :     CfLog(cferror,"Program does not define a timezone","");
2447 :     return;
2448 :     }
2449 :    
2450 :     for (ip = VTIMEZONE; ip != NULL; ip=ip->next)
2451 :     {
2452 :     #ifdef NT
2453 :    
2454 :     tzset();
2455 :     strcpy(tz,timezone());
2456 :    
2457 :     #else
2458 :     #ifndef AOS
2459 :     #ifndef SUN4
2460 :    
2461 :     tzset();
2462 :     strcpy(tz,tzname[0]);
2463 :    
2464 :     #else
2465 :    
2466 :     if ((tloc = time((time_t *)NULL)) == -1)
2467 :     {
2468 :     printf("Couldn't read system clock\n\n");
2469 :     }
2470 :     strcpy(tz,localtime(&tloc)->tm_zone);
2471 :    
2472 :     #endif /* SUN4 */
2473 :     #endif /* AOS */
2474 :     #endif /* NT */
2475 :    
2476 :     if (TZCheck(tz,ip->name))
2477 :     {
2478 :     return;
2479 :     }
2480 :     }
2481 :    
2482 :     snprintf(OUTPUT,bufsize*2,"Time zone was %s which is not in the list of acceptable values",tz);
2483 :     CfLog(cferror,OUTPUT,"");
2484 :     }
2485 :    
2486 :     /*******************************************************************/
2487 :    
2488 :     void CheckProcesses()
2489 :    
2490 :     { struct Process *pp;
2491 :     struct Item *procdata = NULL;
2492 :     char *psopts = VPSOPTS[VSYSTEMHARDCLASS];
2493 :    
2494 :     if (!GetLock(ASUniqueName("processes"),"allprocs",VIFELAPSED,VEXPIREAFTER,VUQNAME,CFSTARTTIME))
2495 :     {
2496 :     return;
2497 :     }
2498 :    
2499 :     if (!LoadProcessTable(&procdata,psopts))
2500 :     {
2501 :     CfLog(cferror,"Unable to read the process table\n","");
2502 :     return;
2503 :     }
2504 :    
2505 :     for (pp = VPROCLIST; pp != NULL; pp=pp->next)
2506 :     {
2507 :     if (IsExcluded(pp->classes))
2508 :     {
2509 :     continue;
2510 :     }
2511 :    
2512 :     if (pp->done == 'y')
2513 :     {
2514 :     continue;
2515 :     }
2516 :     else
2517 :     {
2518 :     pp->done = 'y';
2519 :     }
2520 :    
2521 :     ResetOutputRoute(pp->log,pp->inform);
2522 :    
2523 :     if (strcmp(pp->expr,"SetOptionString") == 0)
2524 :     {
2525 :     psopts = pp->restart;
2526 :     DeleteItemList(procdata);
2527 :     procdata = NULL;
2528 :     if (!LoadProcessTable(&procdata,psopts))
2529 :     {
2530 :     CfLog(cferror,"Unable to read the process table\n","");
2531 :     }
2532 :     }
2533 :     else
2534 :     {
2535 :     DoProcessCheck(pp,procdata);
2536 :     }
2537 :    
2538 :     ResetOutputRoute('d','d');
2539 :     }
2540 :    
2541 :     ReleaseCurrentLock();
2542 :     }
2543 :    
2544 :     /*******************************************************************/
2545 :    
2546 :     int RequiredFileSystemOkay (name)
2547 :    
2548 :     char *name;
2549 :    
2550 :     { struct stat statbuf, localstat;
2551 :     DIR *dirh;
2552 :     struct dirent *dirp;
2553 :     long sizeinbytes = 0, filecount = 0;
2554 :     char buff[bufsize];
2555 :    
2556 :     Debug2("Checking required filesystem %s\n",name);
2557 :    
2558 :     if (stat(name,&statbuf) == -1)
2559 :     {
2560 :     return(false);
2561 :     }
2562 :    
2563 :     if (S_ISLNK(statbuf.st_mode))
2564 :     {
2565 :     KillOldLink(name,NULL);
2566 :     return(true);
2567 :     }
2568 :    
2569 :     if (S_ISDIR(statbuf.st_mode))
2570 :     {
2571 :     if ((dirh = opendir(name)) == NULL)
2572 :     {
2573 :     snprintf(OUTPUT,bufsize*2,"Can't open directory %s which checking required/disk\n",name);
2574 :     CfLog(cferror,OUTPUT,"opendir");
2575 :     return false;
2576 :     }
2577 :    
2578 :     for (dirp = readdir(dirh); dirp != NULL; dirp = readdir(dirh))
2579 :     {
2580 :     if (!SensibleFile(dirp->d_name,name,NULL))
2581 :     {
2582 :     continue;
2583 :     }
2584 :    
2585 :     filecount++;
2586 :    
2587 :     strcpy(buff,name);
2588 :    
2589 :     if (buff[strlen(buff)] != '/')
2590 :     {
2591 :     strcat(buff,"/");
2592 :     }
2593 :    
2594 :     strcat(buff,dirp->d_name);
2595 :    
2596 :     if (lstat(buff,&localstat) == -1)
2597 :     {
2598 :     if (S_ISLNK(localstat.st_mode))
2599 :     {
2600 :     KillOldLink(buff,NULL);
2601 :     continue;
2602 :     }
2603 :    
2604 :     snprintf(OUTPUT,bufsize*2,"Can't stat %s in required/disk\n",buff);
2605 :     CfLog(cferror,OUTPUT,"lstat");
2606 :     continue;
2607 :     }
2608 :    
2609 :     sizeinbytes += localstat.st_size;
2610 :     }
2611 :    
2612 :     closedir(dirh);
2613 :    
2614 :     if (sizeinbytes < 0)
2615 :     {
2616 :     Verbose("Internal error: count of byte size was less than zero!\n");
2617 :     return true;
2618 :     }
2619 :    
2620 :     if (sizeinbytes < SENSIBLEFSSIZE)
2621 :     {
2622 :     snprintf(OUTPUT,bufsize*2,"File system %s is suspiciously small! (%d bytes)\n",name,sizeinbytes);
2623 :     CfLog(cferror,OUTPUT,"");
2624 :     return(false);
2625 :     }
2626 :    
2627 :     if (filecount < SENSIBLEFILECOUNT)
2628 :     {
2629 :     snprintf(OUTPUT,bufsize*2,"Filesystem %s has only %d files/directories.\n",name,filecount);
2630 :     CfLog(cferror,OUTPUT,"");
2631 :     return(false);
2632 :     }
2633 :     }
2634 :    
2635 :     return(true);
2636 :     }
2637 :    
2638 :    
2639 :     /*******************************************************************/
2640 :    
2641 :     void InstallMountedItem(host,mountdir)
2642 :    
2643 :     char *host, *mountdir;
2644 :    
2645 :     { char buf[bufsize];
2646 :    
2647 :     strcpy (buf,host);
2648 :     strcat (buf,":");
2649 :     strcat (buf,mountdir);
2650 :    
2651 :     if (IsItemIn(VMOUNTED,buf))
2652 :     {
2653 :     if (! SILENT || !WARNINGS)
2654 :     {
2655 :     snprintf(OUTPUT,bufsize*2,"WARNING mount item %s\n",buf);
2656 :     CfLog(cferror,OUTPUT,"");
2657 :     CfLog(cferror,"is mounted multiple times!\n","");
2658 :     }
2659 :     }
2660 :    
2661 :     AppendItem(&VMOUNTED,buf,NULL);
2662 :     }
2663 :    
2664 :     /*******************************************************************/
2665 :    
2666 :    
2667 :     void AddToFstab(host,rmountpt,mountpt,mode,ismounted)
2668 :    
2669 :     char *host, *mountpt, *rmountpt, *mode;
2670 :     int ismounted;
2671 :    
2672 :     { char fstab[bufsize];
2673 :     char *opts;
2674 :     FILE *fp;
2675 :    
2676 :     Debug("AddToFstab(%s)\n",mountpt);
2677 :    
2678 :     opts = VMOUNTOPTS[VSYSTEMHARDCLASS];
2679 :    
2680 :     switch (VSYSTEMHARDCLASS)
2681 :     {
2682 :     case osf:
2683 :     case bsd4_3:
2684 :     case irix:
2685 :     case irix4:
2686 :     case irix64:
2687 :     case sun3:
2688 :     case aos:
2689 :     case nextstep:
2690 :     case newsos:
2691 :     case sun4: snprintf(fstab,bufsize,"%s:%s \t %s %s\t%s,%s 0 0",host,rmountpt,mountpt,VNFSTYPE,mode,opts);
2692 :     break;
2693 :    
2694 :     case crayos:
2695 :     snprintf(fstab,bufsize,"%s:%s \t %s %s\t%s,%s",host,rmountpt,mountpt,ToUpperStr(VNFSTYPE),mode,opts);
2696 :     break;
2697 :     case ultrx: snprintf(fstab,bufsize,"%s@%s:%s:%s:0:0:%s:%s",rmountpt,host,mountpt,mode,VNFSTYPE,opts);
2698 :     break;
2699 :     case hp10:
2700 :     case hp: snprintf(fstab,bufsize,"%s:%s %s \t %s \t %s,%s 0 0",host,rmountpt,mountpt,VNFSTYPE,mode,opts);
2701 :     break;
2702 :     case aix: snprintf(fstab,bufsize,"%s:\n\tdev\t= %s\n\ttype\t= %s\n\tvfs\t= %s\n\tnodename\t= %s\n\tmount\t= true\n\toptions\t= %s,%s\n\taccount\t= false\n\n",mountpt,rmountpt,VNFSTYPE,VNFSTYPE,host,mode,opts);
2703 :     break;
2704 :     case GnU:
2705 :     case linuxx: snprintf(fstab,bufsize,"%s:%s \t %s \t %s \t %s,%s",host,rmountpt,mountpt,VNFSTYPE,mode,opts);
2706 :     break;
2707 :    
2708 :     case netbsd:
2709 :     case openbsd:
2710 :     case bsd_i:
2711 :     case freebsd: snprintf(fstab,bufsize,"%s:%s \t %s \t %s \t %s,%s 0 0",host,rmountpt,mountpt,VNFSTYPE,mode,opts);
2712 :     break;
2713 :    
2714 :     case unix_sv:
2715 :     case solarisx86:
2716 :     case solaris: snprintf(fstab,bufsize,"%s:%s - %s %s - yes %s,%s",host,rmountpt,mountpt,VNFSTYPE,mode,opts);
2717 :     break;
2718 :    
2719 :     case cfnt: snprintf(fstab,bufsize,"/bin/mount %s:%s %s",host,rmountpt,mountpt);
2720 :     break;
2721 :     case cfsco: CfLog(cferror,"Don't understand filesystem format on SCO, no data","");
2722 :     break;
2723 :     case unused1:
2724 :     case unused2:
2725 :     case unused3:
2726 :     default: FatalError("AddToFstab(): unknown hard class detected!\n");
2727 :     break;
2728 :     }
2729 :    
2730 :     if (MatchStringInFstab(mountpt))
2731 :     {
2732 :     /* if the fstab entry has changed, remove the old entry and update */
2733 :     if (!MatchStringInFstab(fstab))
2734 :     { struct UnMount *saved_VUNMOUNT = VUNMOUNT;
2735 :     char mountspec[MAXPATHLEN];
2736 :     struct Item *mntentry = NULL;
2737 :     struct UnMount cleaner;
2738 :    
2739 :     snprintf(OUTPUT,bufsize*2,"Removing \"%s\" entry from %s to allow update:\n",
2740 :     mountpt,VFSTAB[VSYSTEMHARDCLASS]);
2741 :     CfLog(cfinform,OUTPUT,"");
2742 :     CfLog(cfinform,"---------------------------------------------------","");
2743 :    
2744 :     /* delete current fstab entry and unmount if necessary */
2745 :     snprintf(mountspec,bufsize,".+:%s",mountpt);
2746 :     mntentry = LocateItemContainingRegExp(VMOUNTED,mountspec);
2747 :     if (mntentry)
2748 :     {
2749 :     sscanf(mntentry->name,"%[^:]:",mountspec); /* extract current host */
2750 :     strcat(mountspec,":");
2751 :     strcat(mountspec,mountpt);
2752 :     }
2753 :     else /* mountpt isn't mounted, so Unmount can use dummy host name */
2754 :     snprintf(mountspec,bufsize,"host:%s",mountpt);
2755 :    
2756 :     /* delete current fstab entry and unmount if necessary (don't rmdir) */
2757 :     cleaner.name = mountspec;
2758 :     cleaner.classes = NULL;
2759 :     cleaner.deletedir = 'n';
2760 :     cleaner.deletefstab = 'y';
2761 :     cleaner.force = 'n';
2762 :     cleaner.next = NULL;
2763 :    
2764 :     VUNMOUNT = &cleaner;
2765 :     Unmount();
2766 :     VUNMOUNT = saved_VUNMOUNT;
2767 :     CfLog(cfinform,"---------------------------------------------------","");
2768 :     }
2769 :     else /* no need to update fstab - this mount entry is already there */
2770 :     {
2771 :     /* warn if entry's already in the fstab but hasn't been mounted */
2772 :     if (!ismounted && !SILENT && !strstr(mountpt,"cdrom"))
2773 :     {
2774 :     snprintf(OUTPUT,bufsize*2,"Warning the file system %s seems to be in %s\n",mountpt,VFSTAB[VSYSTEMHARDCLASS]);
2775 :     CfLog(cfinform,OUTPUT,"");
2776 :     snprintf(OUTPUT,bufsize*2,"already, but I was not able to mount it.\n");
2777 :     CfLog(cfinform,OUTPUT,"");
2778 :     snprintf(OUTPUT,bufsize*2,"Check the exports file on host %s? Check for file with same name as dir?\n",host);
2779 :     CfLog(cfinform,OUTPUT,"");
2780 :     }
2781 :    
2782 :     return;
2783 :     }
2784 :     }
2785 :    
2786 :     if (DONTDO)
2787 :     {
2788 :     printf("%s: add filesystem to %s\n",VPREFIX,VFSTAB[VSYSTEMHARDCLASS]);
2789 :     printf("%s: %s\n",VPREFIX,fstab);
2790 :     }
2791 :     else
2792 :     {
2793 :     if ((fp = fopen(VFSTAB[VSYSTEMHARDCLASS],"a")) == NULL)
2794 :     {
2795 :     snprintf(OUTPUT,bufsize*2,"Can't open %s for appending\n",VFSTAB[VSYSTEMHARDCLASS]);
2796 :     CfLog(cferror,OUTPUT,"fopen");
2797 :     ReleaseCurrentLock();
2798 :     return;
2799 :     }
2800 :    
2801 :     snprintf(OUTPUT,bufsize*2,"Adding filesystem to %s\n",VFSTAB[VSYSTEMHARDCLASS]);
2802 :     CfLog(cfinform,OUTPUT,"");
2803 :     snprintf(OUTPUT,bufsize*2,"%s\n",fstab);
2804 :     CfLog(cfinform,OUTPUT,"");
2805 :     fprintf(fp,"%s\n",fstab);
2806 :     fclose(fp);
2807 :    
2808 :     chmod(VFSTAB[VSYSTEMHARDCLASS],DEFAULTSYSTEMMODE);
2809 :     }
2810 :     }
2811 :    
2812 :    
2813 :     /*******************************************************************/
2814 :    
2815 :     int CheckFreeSpace (file,kilobytes)
2816 :    
2817 :     char *file;
2818 :     int kilobytes;
2819 :    
2820 :     { struct stat statbuf;
2821 :     int free;
2822 :    
2823 :     if (stat(file,&statbuf) == -1)
2824 :     {
2825 :     snprintf(OUTPUT,bufsize*2,"Couldn't stat %s checking diskspace\n",file);
2826 :     CfLog(cferror,OUTPUT,"");
2827 :     return true;
2828 :     }
2829 :    
2830 :     if (IsMountedFileSystem(&statbuf,file,1)) /* only do this on server */
2831 :     {
2832 :     return true;
2833 :     }
2834 :    
2835 :     if (kilobytes < 0) /* percentage */
2836 :     {
2837 :     free = GetDiskUsage(file,cfpercent);
2838 :     kilobytes = -1 * kilobytes;
2839 :     if (free < kilobytes)
2840 :     {
2841 :     snprintf(OUTPUT,bufsize*2,"Free disk space is under %d%% for partition\n",kilobytes);
2842 :     CfLog(cfinform,OUTPUT,"");
2843 :     snprintf(OUTPUT,bufsize*2,"containing %s (%d%% free)\n",file,free);
2844 :     CfLog(cfinform,OUTPUT,"");
2845 :     return false;
2846 :     }
2847 :     }
2848 :     else
2849 :     {
2850 :     free = GetDiskUsage(file, cfabs);
2851 :    
2852 :     if (free < kilobytes)
2853 :     {
2854 :     snprintf(OUTPUT,bufsize*2,"Disk space under %d kB for partition\n",kilobytes);
2855 :     CfLog(cfinform,OUTPUT,"");
2856 :     snprintf(OUTPUT,bufsize*2,"containing %s (%d kB free)\n",file,free);
2857 :     CfLog(cfinform,OUTPUT,"");
2858 :     return false;
2859 :     }
2860 :     }
2861 :    
2862 :     return true;
2863 :     }
2864 :    
2865 :     /*******************************************************************/
2866 :    
2867 :     void CheckHome(ptr) /* iterate check over homedirs */
2868 :    
2869 :     struct File *ptr;
2870 :    
2871 :     { struct Item *ip1, *ip2;
2872 :     char basename[bufsize],pathbuff[bufsize];
2873 :    
2874 :     Debug("CheckHome(%s)\n",ptr->path);
2875 :    
2876 :     if (!IsPrivileged())
2877 :     {
2878 :     CfLog(cferror,"Only root can check others' files.\n","");
2879 :     return;
2880 :     }
2881 :    
2882 :     if (!MountPathDefined())
2883 :     {
2884 :     return;
2885 :     }
2886 :    
2887 :     for (ip1 = VHOMEPATLIST; ip1 != NULL; ip1=ip1->next)
2888 :     {
2889 :     for (ip2 = VMOUNTLIST; ip2 != NULL; ip2=ip2->next)
2890 :     {
2891 :     if (IsExcluded(ip2->classes))
2892 :     {
2893 :     continue;
2894 :     }
2895 :     pathbuff[0]='\0';
2896 :     basename[0]='\0';
2897 :     strcpy(pathbuff,ip2->name);
2898 :     AddSlash(pathbuff);
2899 :     strcat(pathbuff,ip1->name);
2900 :     AddSlash(pathbuff);
2901 :    
2902 :     if (strncmp(ptr->path,"home/",5) == 0) /* home/subdir */
2903 :     {
2904 :     strcat(pathbuff,"*");
2905 :     AddSlash(pathbuff);
2906 :    
2907 :     if (*(ptr->path+4) != '/')
2908 :     {
2909 :     snprintf(OUTPUT,bufsize*2,"Illegal use of home in files: %s\n",ptr->path);
2910 :     CfLog(cferror,OUTPUT,"");
2911 :     return;
2912 :     }
2913 :     else
2914 :     {
2915 :     strcat(pathbuff,ptr->path+5);
2916 :     }
2917 :    
2918 :     ExpandWildCardsAndDo(pathbuff,basename,RecFileCheck,ptr);
2919 :     }
2920 :     else
2921 :     {
2922 :     ExpandWildCardsAndDo(pathbuff,basename,RecFileCheck,ptr);
2923 :     }
2924 :     }
2925 :     }
2926 :     }
2927 :    
2928 :     /*******************************************************************/
2929 :    
2930 :     void EditItemsInResolvConf(from,list)
2931 :    
2932 :     struct Item *from, **list;
2933 :    
2934 :     { char buf[maxvarsize];
2935 :    
2936 :     if ((from != NULL) && !IsDefinedClass(from->classes))
2937 :     {
2938 :     return;
2939 :     }
2940 :    
2941 :     if (from == NULL)
2942 :     {
2943 :     return;
2944 :     }
2945 :     else
2946 :     {
2947 :     EditItemsInResolvConf(from->next,list);
2948 :     if (isdigit((int)*(from->name)))
2949 :     {
2950 :     snprintf(buf,bufsize,"nameserver %s",from->name);
2951 :     }
2952 :     else
2953 :     {
2954 :     strcpy(buf,from->name);
2955 :     }
2956 :    
2957 :     DeleteItemMatching(list,buf); /* del+prep = move to head of list */
2958 :     PrependItem(list,buf,NULL);
2959 :     return;
2960 :     }
2961 :     }
2962 :    
2963 :    
2964 :     /*******************************************************************/
2965 :    
2966 :     int TZCheck(tzsys,tzlist)
2967 :    
2968 :     char *tzsys,*tzlist;
2969 :    
2970 :     {
2971 :     if ((strncmp(tzsys,"GMT+",4) == 0) || (strncmp(tzsys,"GMT-",4) == 0))
2972 :     {
2973 :     return (strncmp(tzsys,tzlist,5) == 0); /* e.g. GMT+1 */
2974 :     }
2975 :     else
2976 :     {
2977 :     return (strncmp(tzsys,tzlist,3) == 0); /* e.g. MET or CET */
2978 :     }
2979 :     }
2980 :    
2981 :     /*******************************************************************/
2982 :    
2983 :     void ExpandWildCardsAndDo(wildpath,buffer,function,argptr)
2984 :    
2985 :     char *wildpath, *buffer;
2986 :     void (*function) ARGLIST((char *path, void *ptr));
2987 :     void *argptr;
2988 :    
2989 :     /* This function recursively expands a path containing wildcards */
2990 :     /* and executes the function pointed to by function for each */
2991 :     /* matching file or directory */
2992 :    
2993 :    
2994 :     { char *rest, extract[bufsize], construct[bufsize],varstring[bufsize], *work;
2995 :     struct stat statbuf;
2996 :     DIR *dirh;
2997 :     struct dirent *dp;
2998 :     int count, isdir = false;
2999 :    
3000 :     varstring[0] = '\0';
3001 :    
3002 :     ExpandVarstring(wildpath,varstring,NULL);
3003 :     work = varstring;
3004 :    
3005 :     Debug2("ExpandWildCardsAndDo(%s=%s)\n",wildpath,work);
3006 :    
3007 :     extract[0] = '\0';
3008 :    
3009 :     if (*work == '/')
3010 :     {
3011 :     work++;
3012 :     isdir = true;
3013 :     }
3014 :    
3015 :     sscanf(work,"%[^/]",extract);
3016 :     rest = work + strlen(extract);
3017 :    
3018 :     if (strlen(extract) == 0)
3019 :     {
3020 :     if (isdir)
3021 :     {
3022 :     strcat(buffer,"/");
3023 :     }
3024 :     (*function)(buffer,argptr);
3025 :     return;
3026 :     }
3027 :    
3028 :     if (! IsWildCard(extract))
3029 :     {
3030 :     strcat(buffer,"/");
3031 :     if (BufferOverflow(buffer,extract))
3032 :     {
3033 :     snprintf(OUTPUT,bufsize*2,"Culprit %s\n",extract);
3034 :     CfLog(cferror,OUTPUT,"");
3035 :     exit(0);
3036 :     }
3037 :     strcat(buffer,extract);
3038 :     ExpandWildCardsAndDo(rest,buffer,function,argptr);
3039 :     return;
3040 :     }
3041 :     else
3042 :     {
3043 :     strcat(buffer,"/");
3044 :    
3045 :     if ((dirh=opendir(buffer)) == NULL)
3046 :     {
3047 :     snprintf(OUTPUT,bufsize*2,"Can't open dir: %s\n",buffer);
3048 :     CfLog(cferror,OUTPUT,"opendir");
3049 :     return;
3050 :     }
3051 :    
3052 :     count = 0;
3053 :     strcpy(construct,buffer); /* save relative path */
3054 :    
3055 :     for (dp = readdir(dirh); dp != 0; dp = readdir(dirh))
3056 :     {
3057 :     if (!SensibleFile(dp->d_name,buffer,NULL))
3058 :     {
3059 :     continue;
3060 :     }
3061 :    
3062 :     count++;
3063 :     strcpy(buffer,construct);
3064 :     strcat(buffer,dp->d_name);
3065 :    
3066 :     if (stat(buffer,&statbuf) == -1)
3067 :     {
3068 :     snprintf(OUTPUT,bufsize*2,"Can't stat %s\n\n",buffer);
3069 :     CfLog(cferror,OUTPUT,"stat");
3070 :     continue;
3071 :     }
3072 :    
3073 :     if (S_ISDIR(statbuf.st_mode) && WildMatch(extract,dp->d_name))
3074 :     {
3075 :     ExpandWildCardsAndDo(rest,buffer,function,argptr);
3076 :     }
3077 :     }
3078 :    
3079 :     if (count == 0)
3080 :     {
3081 :     snprintf(OUTPUT,bufsize*2,"No directories matching %s in %s\n",extract,buffer);
3082 :     CfLog(cfinform,OUTPUT,"");
3083 :     return;
3084 :     }
3085 :     closedir(dirh);
3086 :     }
3087 :     }
3088 :    
3089 :    
3090 :     /*******************************************************************/
3091 :    
3092 :     int TouchDirectory(ptr) /* True if file path in /. */
3093 :    
3094 :     struct File *ptr;
3095 :    
3096 :     { char *sp;
3097 :    
3098 :     if (ptr->action == touch)
3099 :     {
3100 :     sp = ptr->path+strlen(ptr->path)-2;
3101 :    
3102 :     if (strcmp(sp,"/.") == 0)
3103 :     {
3104 :     return(true);
3105 :     }
3106 :     else
3107 :     {
3108 :     return false;
3109 :     }
3110 :     }
3111 :     else
3112 :     {
3113 :     return false;
3114 :     }
3115 :     }
3116 :    
3117 :    
3118 :     /*******************************************************************/
3119 :    
3120 :     void RecFileCheck(startpath,vp)
3121 :    
3122 :     char *startpath;
3123 :     void *vp;
3124 :    
3125 :     { struct File *ptr;
3126 :    
3127 :     ptr = (struct File *)vp;
3128 :    
3129 :     Verbose("%s: Checking files in %s...\n",VPREFIX,startpath);
3130 :    
3131 :     if (!GetLock(ASUniqueName("files"),startpath,VIFELAPSED,VEXPIREAFTER,VUQNAME,CFSTARTTIME))
3132 :     {
3133 :     return;
3134 :     }
3135 :    
3136 :     RecursiveCheck(startpath,ptr->plus,ptr->minus,ptr->action,ptr->uid,ptr->gid,ptr->recurse,0,ptr);
3137 :     ReleaseCurrentLock();
3138 :     }
3139 :    
3140 :     /*******************************************************************/
3141 :     /* Toolkit fstab */
3142 :     /*******************************************************************/
3143 :    
3144 :     int MatchStringInFstab(str)
3145 :    
3146 :     char *str;
3147 :    
3148 :     { FILE *fp;
3149 :    
3150 :     if ((fp = fopen(VFSTAB[VSYSTEMHARDCLASS],"r")) == NULL)
3151 :     {
3152 :     snprintf(OUTPUT,bufsize*2,"Can't open %s for reading\n",VFSTAB[VSYSTEMHARDCLASS]);
3153 :     CfLog(cferror,OUTPUT,"fopen");
3154 :     return true; /* write nothing */
3155 :     }
3156 :    
3157 :     while (!feof(fp))
3158 :     {
3159 :     ReadLine(VBUFF,bufsize,fp);
3160 :    
3161 :     if (VBUFF[0] == '#')
3162 :     {
3163 :     continue;
3164 :     }
3165 :    
3166 :     if (strstr(VBUFF,str))
3167 :     {
3168 :     fclose(fp);
3169 :     return true;
3170 :     }
3171 :     }
3172 :    
3173 :     fclose(fp);
3174 :     return(false);
3175 :     }
3176 :    
3177 :    

Administrator
ViewVC Help
Powered by ViewVC 1.0.3