int DoRecursiveEditFiles(char *name,int level,struct Edit *ptr,struct stat *sb) { DIR *dirh; struct dirent *dirp; char pcwd[CF_BUFSIZE]; struct stat statbuf; int goback; if (level == -1) { return false; } Debug("RecursiveEditFiles(%s)\n",name); if (!DirPush(name,sb)) { return false; } if ((dirh = opendir(".")) == NULL) { return true; } for (dirp = readdir(dirh); dirp != NULL; dirp = readdir(dirh)) { if (!SensibleFile(dirp->d_name,name,NULL)) { continue; } if (IgnoreFile(name,dirp->d_name,ptr->ignores)) { continue; } strcpy(pcwd,name); /* Assemble pathname */ AddSlash(pcwd); if (BufferOverflow(pcwd,dirp->d_name)) { return true; } strcat(pcwd,dirp->d_name); if (!FileObjectFilter(pcwd,&statbuf,ptr->filters,editfiles)) { Verbose("Skipping filtered file %s\n",pcwd); continue; } if (TRAVLINKS) { if (lstat(dirp->d_name,&statbuf) == -1) { snprintf(OUTPUT,CF_BUFSIZE*2,"Can't stat %s\n",pcwd); CfLog(cferror,OUTPUT,"stat"); continue; } if (S_ISLNK(statbuf.st_mode) && (statbuf.st_mode != getuid())) { snprintf(OUTPUT,CF_BUFSIZE,"File %s is an untrusted link. cfagent will not follow it with a destructive operation (tidy)",pcwd); continue; } if (stat(dirp->d_name,&statbuf) == -1) { snprintf(OUTPUT,CF_BUFSIZE*2,"RecursiveCheck was working on %s when this happened:\n",pcwd); CfLog(cferror,OUTPUT,"stat"); continue; } } else { if (lstat(dirp->d_name,&statbuf) == -1) { snprintf(OUTPUT,CF_BUFSIZE*2,"RecursiveCheck was working in %s when this happened:\n",pcwd); CfLog(cferror,OUTPUT,"lstat"); continue; } } if (S_ISDIR(statbuf.st_mode)) { if (IsMountedFileSystem(&statbuf,pcwd,level)) { continue; } else { if ((ptr->recurse > 1) || (ptr->recurse == CF_INF_RECURSE)) { goback = DoRecursiveEditFiles(pcwd,level-1,ptr,&statbuf); DirPop(goback,name,sb); } else { WrapDoEditFile(ptr,pcwd); } } } else { WrapDoEditFile(ptr,pcwd); } } closedir(dirh); return true; }
void DoEditHomeFiles(struct Edit *ptr) { DIR *dirh, *dirh2; struct dirent *dirp, *dirp2; char *sp,homedir[CF_BUFSIZE],dest[CF_BUFSIZE]; struct passwd *pw; struct stat statbuf; struct Item *ip; uid_t uid; if (!MountPathDefined()) { CfLog(cfinform,"Mountpattern is undefined\n",""); return; } for (ip = VMOUNTLIST; ip != NULL; ip=ip->next) { if (IsExcluded(ip->classes)) { continue; } if ((dirh = opendir(ip->name)) == NULL) { snprintf(OUTPUT,CF_BUFSIZE*2,"Can't open directory %s\n",ip->name); CfLog(cferror,OUTPUT,"opendir"); return; } for (dirp = readdir(dirh); dirp != NULL; dirp = readdir(dirh)) { if (!SensibleFile(dirp->d_name,ip->name,NULL)) { continue; } strcpy(homedir,ip->name); AddSlash(homedir); strcat(homedir,dirp->d_name); if (! IsHomeDir(homedir)) { continue; } if ((dirh2 = opendir(homedir)) == NULL) { snprintf(OUTPUT,CF_BUFSIZE*2,"Can't open directory%s\n",homedir); CfLog(cferror,OUTPUT,"opendir"); return; } for (dirp2 = readdir(dirh2); dirp2 != NULL; dirp2 = readdir(dirh2)) { if (!SensibleFile(dirp2->d_name,homedir,NULL)) { continue; } strcpy(dest,homedir); AddSlash(dest); strcat(dest,dirp2->d_name); AddSlash(dest); sp = ptr->fname + strlen("home/"); strcat(dest,sp); if (stat(dest,&statbuf)) { EditVerbose("File %s doesn't exist for editing, skipping\n",dest); continue; } if ((pw = getpwnam(dirp2->d_name)) == NULL) { Debug2("cfengine: directory corresponds to no user %s - ignoring\n",dirp2->d_name); continue; } else { Debug2("(Setting user id to %s)\n",dirp2->d_name); } uid = statbuf.st_uid; WrapDoEditFile(ptr,dest); chown(dest,uid,CF_SAME_OWNER); } closedir(dirh2); } closedir(dirh); } }
int RecursiveLink(struct Link *lp,char *from,char *to,int maxrecurse) { struct stat statbuf; DIR *dirh; struct dirent *dirp; char newfrom[CF_BUFSIZE]; char newto[CF_BUFSIZE]; void *bug_check; int (*linkfiles)(char *from, char *to, struct Item *inclusions, struct Item *exclusions, struct Item *copy, short int nofile, struct Link *ptr); /* reached depth limit */ if (maxrecurse == 0) { Debug2("MAXRECURSE ran out, quitting at level %s with " "endlist = %d\n", to, lp->next); return false; } if (IgnoreFile(to,"",lp->ignores)) { Verbose("%s: Ignoring directory %s\n",g_vprefix,from); return false; } /* Check for root dir */ if (strlen(to) == 0) { to = "/"; } bug_check = lp->next; if ((dirh = opendir(to)) == NULL) { snprintf(g_output,CF_BUFSIZE*2,"Can't open directory [%s]\n",to); CfLog(cferror,g_output,"opendir"); return false; } if (lp->next != bug_check) { printf("%s: solaris BSD compat bug: opendir wrecked " "the heap memory!!", g_vprefix); printf("%s: in copy to %s, using workaround...\n",g_vprefix,from); lp->next = bug_check; } for (dirp = readdir(dirh); dirp != NULL; dirp = readdir(dirh)) { if (!SensibleFile(dirp->d_name,to,NULL)) { continue; } if (IgnoreFile(to,dirp->d_name,lp->ignores)) { continue; } /* Assemble pathname */ strcpy(newfrom,from); AddSlash(newfrom); strcpy(newto,to); AddSlash(newto); if (BufferOverflow(newfrom,dirp->d_name)) { closedir(dirh); return true; } strcat(newfrom,dirp->d_name); if (BufferOverflow(newto,dirp->d_name)) { closedir(dirh); return true; } strcat(newto,dirp->d_name); if (g_travlinks) { if (stat(newto,&statbuf) == -1) { snprintf(g_output,CF_BUFSIZE*2,"Can't stat %s\n",newto); CfLog(cfverbose,g_output,""); continue; } } else { if (lstat(newto,&statbuf) == -1) { snprintf(g_output,CF_BUFSIZE*2,"Can't stat %s\n",newto); CfLog(cfverbose,g_output,""); memset(g_vbuff,0,CF_BUFSIZE); if (readlink(newto,g_vbuff,CF_BUFSIZE-1) != -1) { Verbose("File is link to -> %s\n",g_vbuff); } continue; } } if (!FileObjectFilter(newto,&statbuf,lp->filters,links)) { Debug("Skipping filtered file %s\n",newto); continue; } if (S_ISDIR(statbuf.st_mode)) { RecursiveLink(lp,newfrom,newto,maxrecurse-1); } else { switch (lp->type) { case 's': linkfiles = LinkFiles; break; case 'r': linkfiles = RelativeLink; break; case 'a': linkfiles = AbsoluteLink; break; case 'h': linkfiles = HardLinkFiles; break; default: printf("cfagent: internal error, link type was [%c]\n",lp->type); continue; } (*linkfiles)(newfrom,newto,lp->inclusions,lp->exclusions, lp->copy,lp->nofile,lp); } } closedir(dirh); return true; }
int LinkChildFiles(char *from,char *to,char type, struct Item *inclusions, struct Item *exclusions, struct Item *copy, short nofile, struct Link *ptr) { DIR *dirh; struct dirent *dirp; char pcwdto[CF_BUFSIZE],pcwdfrom[CF_BUFSIZE]; struct stat statbuf; int (*linkfiles)(char *from, char *to, struct Item *inclusions, struct Item *exclusions, struct Item *copy, short int nofile, struct Link *ptr); Debug("LinkChildFiles(%s,%s)\n",from,to); if (stat(to,&statbuf) == -1) { /* no error warning, since the higher level routine uses this */ return(false); } if ((dirh = opendir(to)) == NULL) { snprintf(g_output,CF_BUFSIZE*2,"Can't open directory %s\n",to); CfLog(cferror,g_output,"opendir"); return false; } for (dirp = readdir(dirh); dirp != NULL; dirp = readdir(dirh)) { if (!SensibleFile(dirp->d_name,to,NULL)) { continue; } /* Assemble pathnames */ strcpy(pcwdto,to); AddSlash(pcwdto); if (BufferOverflow(pcwdto,dirp->d_name)) { FatalError("Can't build filename in LinkChildFiles"); } strcat(pcwdto,dirp->d_name); strcpy(pcwdfrom,from); AddSlash(pcwdfrom); if (BufferOverflow(pcwdfrom,dirp->d_name)) { FatalError("Can't build filename in LinkChildFiles"); } strcat(pcwdfrom,dirp->d_name); switch (type) { case 's': linkfiles = LinkFiles; break; case 'r': linkfiles = RelativeLink; break; case 'a': linkfiles = AbsoluteLink; break; case 'h': linkfiles = HardLinkFiles; break; default: printf("Internal error, link type was [%c]\n",type); continue; } (*linkfiles)(pcwdfrom,pcwdto,inclusions,exclusions,copy,nofile,ptr); } closedir(dirh); return true; }
void LinkChildren(char *path,char type,struct stat *rootstat,uid_t uid,gid_t gid, struct Item *inclusions,struct Item *exclusions,struct Item *copy, short nofile,struct Link *ptr) { char *sp; char lastlink[CF_BUFSIZE],server[CF_BUFSIZE]; char from[CF_BUFSIZE],to[CF_BUFSIZE]; char relpath[CF_BUFSIZE]; char odir[CF_BUFSIZE]; DIR *dirh; struct dirent *dirp; struct stat statbuf; int matched = false; int (*linkfiles)(char *from, char *to, struct Item *inclusions, struct Item *exclusions, struct Item *copy, short int nofile, struct Link *ptr); Debug("LinkChildren(%s)\n",path); if (! S_ISDIR(rootstat->st_mode)) { snprintf(g_output,CF_BUFSIZE*2, "File %s is not a directory: it has no children to link!\n", path); CfLog(cferror,g_output,""); return; } Verbose("Linking the children of %s\n",path); for (sp = path+strlen(path); sp != path-1; sp--) { if (*(sp-1) == '/') { relpath[0] = '\0'; sscanf(sp,"%[^/]%s", lastlink,relpath); if (MatchAFileSystem(server,lastlink)) { strcpy(odir,server); if (BufferOverflow(odir,relpath)) { FatalError("culprit: LinkChildren()"); } strcat(odir,relpath); if ((dirh = opendir(odir)) == NULL) { snprintf(g_output,CF_BUFSIZE*2, "Can't open directory %s\n",path); CfLog(cferror,g_output,"opendir"); return; } for (dirp = readdir(dirh); dirp != NULL; dirp = readdir(dirh)) { if (!SensibleFile(dirp->d_name,odir,NULL)) { continue; } strcpy(from,path); AddSlash(from); if (BufferOverflow(from,dirp->d_name)) { FatalError("culprit: LinkChildren()"); } strcat(from,dirp->d_name); strcpy(to,odir); AddSlash(to); if (BufferOverflow(to,dirp->d_name)) { FatalError("culprit: LinkChildren()"); } strcat(to,dirp->d_name); Debug2("LinkChild from = %s to = %s\n",from,to); if (stat(to,&statbuf) == -1) { continue; } else { switch (type) { case 's': linkfiles = LinkFiles; break; case 'r': linkfiles = RelativeLink; break; case 'a': linkfiles = AbsoluteLink; break; case 'h': linkfiles = HardLinkFiles; break; default: snprintf(g_output,CF_BUFSIZE*2, "Internal error, link type was [%c]\n",type); CfLog(cferror,g_output,""); continue; } matched = (*linkfiles)(from,to,inclusions, exclusions,copy,nofile,ptr); if (matched && !g_dontdo) { chown(from,uid,gid); } } } if (matched) return; } } } snprintf(g_output,CF_BUFSIZE*2, "Couldn't link the children of %s to anything because no\n",path); CfLog(cferror,g_output,""); snprintf(g_output, CF_BUFSIZE*2, "file system was found to " "mirror it in the defined binservers list.\n"); CfLog(cferror,g_output,""); }