bug-cfengine
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

cfengine (sometimes) messes permissions with mode=; patch included


From: Martin Jost
Subject: cfengine (sometimes) messes permissions with mode=; patch included
Date: Mon, 16 Jul 2001 15:49:12 +0200

Hello,

I discovered an annoying problem with cfengine 1.6.3
(I had a look in the newest 2.x; this seems to be affected as well !)

I've attached my patch (for 1.6.3) and my log-entries for the problem.
(Ignore the revision-numbers, these are from my local CVS repository)

To apply the patch, go to the 'src'-Directory. Copy 'patch' there.
Then do
patch -p 2 < patch
(I've tested the patch against the unpatched 1.6.3 and done a diff to
verify the correctness)

[Sorry the patches are rather long. They include diffs to remove all
trailing blanks in the files I changed. (I've set up my emacs to
remove all trailing blanks on save, because cperl-mode 'barfs' at
them. I've tried to remove those diffs, but failed]

The patch fixes the following problems:
(see log for details)
- Using tcpwrapper fails, due to wrong service-name in call to
host_ctl()
- mode= with more than one '=' removes all permission-bits which
aren't in both '='
- mode= doesn't catch some misformed expressions

I hope this proves useful

Martin
Index: cfengine/src/cf.defs.h
diff -c cfengine/src/cf.defs.h:1.1.1.1 cfengine/src/cf.defs.h:1.2
*** cfengine/src/cf.defs.h:1.1.1.1      Tue Jul  3 13:21:55 2001
--- cfengine/src/cf.defs.h      Mon Jul 16 13:56:27 2001
***************
*** 1,26 ****
  /* cfengine for GNU
!  
          Copyright (C) 1995
          Free Software Foundation, Inc.
!  
!    This file is part of GNU cfengine - written and maintained 
     by Mark Burgess, Dept of Computing and Engineering, Oslo College,
     Dept. of Theoretical physics, University of Oslo
!  
     This program is free software; you can redistribute it and/or modify it
     under the terms of the GNU General Public License as published by the
     Free Software Foundation; either version 2, or (at your option) any
     later version.
!  
     This program is distributed in the hope that it will be useful,
     but WITHOUT ANY WARRANTY; without even the implied warranty of
     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     GNU General Public License for more details.
!  
     You should have received a copy of the GNU General Public License
     along with this program; if not, write to the Free Software
     Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
!  
  
  /*******************************************************************/
  /*                                                                 */
--- 1,26 ----
  /* cfengine for GNU
! 
          Copyright (C) 1995
          Free Software Foundation, Inc.
! 
!    This file is part of GNU cfengine - written and maintained
     by Mark Burgess, Dept of Computing and Engineering, Oslo College,
     Dept. of Theoretical physics, University of Oslo
! 
     This program is free software; you can redistribute it and/or modify it
     under the terms of the GNU General Public License as published by the
     Free Software Foundation; either version 2, or (at your option) any
     later version.
! 
     This program is distributed in the hope that it will be useful,
     but WITHOUT ANY WARRANTY; without even the implied warranty of
     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     GNU General Public License for more details.
! 
     You should have received a copy of the GNU General Public License
     along with this program; if not, write to the Free Software
     Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
! 
  
  /*******************************************************************/
  /*                                                                 */
***************
*** 316,322 ****
  #define DEV_BSIZE 4096
  #endif /* !BSIZE */
  #endif /* !DEV_BSIZE */
!  
  /* Extract or fake data from a `struct stat'.
     ST_BLKSIZE: Optimal I/O blocksize for the file, in bytes.
     ST_NBLOCKS: Number of 512-byte blocks in the file
--- 316,322 ----
  #define DEV_BSIZE 4096
  #endif /* !BSIZE */
  #endif /* !DEV_BSIZE */
! 
  /* Extract or fake data from a `struct stat'.
     ST_BLKSIZE: Optimal I/O blocksize for the file, in bytes.
     ST_NBLOCKS: Number of 512-byte blocks in the file
***************
*** 600,606 ****
  
  /*********************************************************************/
  
! enum vnames 
     {
     cffaculty,
     cfsite,
--- 600,606 ----
  
  /*********************************************************************/
  
! enum vnames
     {
     cffaculty,
     cfsite,
***************
*** 869,874 ****
--- 869,881 ----
     which
     };
  
+ enum modesort
+    {
+    unkown,
+    numeric,
+    symbolic
+    };
+ 
  /*******************************************************************/
  
  typedef char flag;
***************
*** 956,962 ****
     int                recurse;
     char               *path;
     struct TidyPattern *tidylist;
!    struct Tidy        *next;   
     };
  
     /**** SUB CLASS *********************************************/
--- 963,969 ----
     int                recurse;
     char               *path;
     struct TidyPattern *tidylist;
!    struct Tidy        *next;
     };
  
     /**** SUB CLASS *********************************************/
***************
*** 1030,1036 ****
     struct Item *exclusions;
     struct Item *inclusions;
     struct Item *filters;
!    struct Item    *ignores;      
     char   *classes;
     struct UidList *uid;
     struct GidList *gid;
--- 1037,1043 ----
     struct Item *exclusions;
     struct Item *inclusions;
     struct Item *filters;
!    struct Item    *ignores;
     char   *classes;
     struct UidList *uid;
     struct GidList *gid;
***************
*** 1106,1120 ****
     char   purge;
     struct Item *exclusions;
     struct Item *inclusions;
!    struct Item *filters;      
!    struct Item *ignores;            
     struct Item *symlink;
  
     struct cfstat *cache;                              /* stat cache */
     struct CompressedArray *inode_cache;              /* inode cache */
!  
     struct in_addr *dns;                      /* Cache gethostbyname */
!    
     struct Image *next;
     struct Item *acl_aliases;
     char   log;
--- 1113,1127 ----
     char   purge;
     struct Item *exclusions;
     struct Item *inclusions;
!    struct Item *filters;
!    struct Item *ignores;
     struct Item *symlink;
  
     struct cfstat *cache;                              /* stat cache */
     struct CompressedArray *inode_cache;              /* inode cache */
! 
     struct in_addr *dns;                      /* Cache gethostbyname */
! 
     struct Image *next;
     struct Item *acl_aliases;
     char   log;
***************
*** 1122,1128 ****
     char   typecheck;
     short  secure;
     u_long plus_flags;    /* for *BSD chflags */
!    u_long minus_flags;    /* for *BSD chflags */      
     };
  
  /*******************************************************************/
--- 1129,1135 ----
     char   typecheck;
     short  secure;
     u_long plus_flags;    /* for *BSD chflags */
!    u_long minus_flags;    /* for *BSD chflags */
     };
  
  /*******************************************************************/
***************
*** 1198,1204 ****
     int    recurse;
     struct Item *exclusions;
     struct Item *inclusions;
!    struct Item *ignores;            
     struct Item *copy;
     struct Link *next;
     char   log;
--- 1205,1211 ----
     int    recurse;
     struct Item *exclusions;
     struct Item *inclusions;
!    struct Item *ignores;
     struct Item *copy;
     struct Link *next;
     char   log;
***************
*** 1218,1225 ****
     char  binary;   /* t/f */
     struct Item *ignores;
     struct Item *exclusions;
!    struct Item *inclusions;      
!    struct Item  *filters;      
     struct Edlist *actions;
     struct Edit *next;
     };
--- 1225,1232 ----
     char  binary;   /* t/f */
     struct Item *ignores;
     struct Item *exclusions;
!    struct Item *inclusions;
!    struct Item  *filters;
     struct Edlist *actions;
     struct Edit *next;
     };
***************
*** 1266,1272 ****
     filterstatus,
     filtercmd,
     filterfromttime,
!    filtertottime,   
     filterfromstime,
     filtertostime,
     filtertty,
--- 1273,1279 ----
     filterstatus,
     filtercmd,
     filterfromttime,
!    filtertottime,
     filterfromstime,
     filtertostime,
     filtertty,
***************
*** 1284,1290 ****
     char context;  /* f=file, p=process */
  
     char *criteria[NoFilter];  /* array of strings */
!       
     struct Filter *next;
     };
  
--- 1291,1297 ----
     char context;  /* f=file, p=process */
  
     char *criteria[NoFilter];  /* array of strings */
! 
     struct Filter *next;
     };
  
***************
*** 1378,1389 ****
  #define S_IRUSR 00400
  #define S_IWUSR 00200
  #define S_IXUSR 00100
!  
  #define S_IRWXG 00070
  #define S_IRGRP 00040
  #define S_IWGRP 00020
  #define S_IXGRP 00010
!  
  #define S_IRWXO 00007
  #define S_IROTH 00004
  #define S_IWOTH 00002
--- 1385,1396 ----
  #define S_IRUSR 00400
  #define S_IWUSR 00200
  #define S_IXUSR 00100
! 
  #define S_IRWXG 00070
  #define S_IRGRP 00040
  #define S_IWGRP 00020
  #define S_IXGRP 00010
! 
  #define S_IRWXO 00007
  #define S_IROTH 00004
  #define S_IWOTH 00002
Index: cfengine/src/cfd.c
diff -c cfengine/src/cfd.c:1.1.1.1 cfengine/src/cfd.c:1.2
*** cfengine/src/cfd.c:1.1.1.1  Tue Jul  3 13:21:55 2001
--- cfengine/src/cfd.c  Wed Jul  4 15:04:34 2001
***************
*** 1,22 ****
! /* 
  
          Copyright (C) 1995,96,97,98
          Free Software Foundation, Inc.
  
!    This file is part of GNU cfengine - written and maintained 
     by Mark Burgess, Dept of Computing and Engineering, Oslo College,
     Dept. of Theoretical physics, University of Oslo
!  
     This program is free software; you can redistribute it and/or modify it
     under the terms of the GNU General Public License as published by the
     Free Software Foundation; either version 2, or (at your option) any
     later version.
!  
     This program is distributed in the hope that it will be useful,
     but WITHOUT ANY WARRANTY; without even the implied warranty of
     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     GNU General Public License for more details.
!  
    You should have received a copy of the GNU General Public License
    along with this program; if not, write to the Free Software
    Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA
--- 1,22 ----
! /*
  
          Copyright (C) 1995,96,97,98
          Free Software Foundation, Inc.
  
!    This file is part of GNU cfengine - written and maintained
     by Mark Burgess, Dept of Computing and Engineering, Oslo College,
     Dept. of Theoretical physics, University of Oslo
! 
     This program is free software; you can redistribute it and/or modify it
     under the terms of the GNU General Public License as published by the
     Free Software Foundation; either version 2, or (at your option) any
     later version.
! 
     This program is distributed in the hope that it will be useful,
     but WITHOUT ANY WARRANTY; without even the implied warranty of
     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     GNU General Public License for more details.
! 
    You should have received a copy of the GNU General Public License
    along with this program; if not, write to the Free Software
    Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA
***************
*** 108,114 ****
  {
  CheckOptsAndInit(argc,argv);
  GetNameInfo();
! GetInterfaceInfo(); 
  ParseInputFiles();
  CheckVariables();
  SummarizeParsing();
--- 108,114 ----
  {
  CheckOptsAndInit(argc,argv);
  GetNameInfo();
! GetInterfaceInfo();
  ParseInputFiles();
  CheckVariables();
  SummarizeParsing();
***************
*** 157,163 ****
        case 'f': strncpy(VINPUTFILE,optarg,bufsize-1);
                  break;
  
!       case 'd': 
  
                  switch ((optarg==NULL)?3:*optarg)
                     {
--- 157,163 ----
        case 'f': strncpy(VINPUTFILE,optarg,bufsize-1);
                  break;
  
!       case 'd':
  
                  switch ((optarg==NULL)?3:*optarg)
                     {
***************
*** 168,174 ****
                     default:  DEBUG = true;
                               break;
                     }
!               
                NO_FORK = true;
                printf("cfd: Debug mode: running in foreground\n");
                  break;
--- 168,174 ----
                     default:  DEBUG = true;
                               break;
                     }
! 
                NO_FORK = true;
                printf("cfd: Debug mode: running in foreground\n");
                  break;
***************
*** 199,206 ****
  
  
  LOGGING = true;                    /* Do output to syslog */
!  
! sprintf(VPREFIX,"cfd:%s:",VUQNAME); 
  sprintf(VBUFF,"%s/test",LOCKFILEDIR);
  MakeDirectoriesFor(VBUFF);
  strncpy(VLOCKDIR,LOCKFILEDIR,bufsize-1);
--- 199,206 ----
  
  
  LOGGING = true;                    /* Do output to syslog */
! 
! sprintf(VPREFIX,"cfd:%s:",VUQNAME);
  sprintf(VBUFF,"%s/test",LOCKFILEDIR);
  MakeDirectoriesFor(VBUFF);
  strncpy(VLOCKDIR,LOCKFILEDIR,bufsize-1);
***************
*** 230,236 ****
  
  strncpy(VFQNAME,VSYSNAME.nodename,bufsize-1);
  LoadSecretKeys();
!  
  if ((CFDSTARTTIME = time((time_t *)NULL)) == -1)
     {
     printf("Couldn't read system clock\n");
--- 230,236 ----
  
  strncpy(VFQNAME,VSYSNAME.nodename,bufsize-1);
  LoadSecretKeys();
! 
  if ((CFDSTARTTIME = time((time_t *)NULL)) == -1)
     {
     printf("Couldn't read system clock\n");
***************
*** 245,256 ****
     {
     DENYBADCLOCKS = false;
     }
!  
  if (GetMacroValue("LogAllConnections") && 
(strcmp(GetMacroValue("LogAllConnections"),"on") == 0))
     {
     LOGCONNS = true;
     }
!  
  if (GetMacroValue("ChecksumDatabase"))
     {
     ExpandVarstring("$(ChecksumDatabase)",VBUFF,NULL);
--- 245,256 ----
     {
     DENYBADCLOCKS = false;
     }
! 
  if (GetMacroValue("LogAllConnections") && 
(strcmp(GetMacroValue("LogAllConnections"),"on") == 0))
     {
     LOGCONNS = true;
     }
! 
  if (GetMacroValue("ChecksumDatabase"))
     {
     ExpandVarstring("$(ChecksumDatabase)",VBUFF,NULL);
***************
*** 266,272 ****
     {
     CHECKSUMDB = strdup("");
     }
!  
  
  if (GetMacroValue("IfElapsed"))
     {
--- 266,272 ----
     {
     CHECKSUMDB = strdup("");
     }
! 
  
  if (GetMacroValue("IfElapsed"))
     {
***************
*** 284,290 ****
        Verbose("cfd: IfElapsed time: %d minutes\n",VIFELAPSED);
        }
     }
!   
  bzero(VBUFF,bufsize);
  
  if (GetMacroValue("cfrunCommand"))
--- 284,290 ----
        Verbose("cfd: IfElapsed time: %d minutes\n",VIFELAPSED);
        }
     }
! 
  bzero(VBUFF,bufsize);
  
  if (GetMacroValue("cfrunCommand"))
***************
*** 312,318 ****
     Debug("$(MaxConnections) Expanded to %s\n",VBUFF);
  
     CFD_MAXPROCESSES = atoi(VBUFF);
!    
     MAXTRIES = CFD_MAXPROCESSES / 3;  /* How many attempted connections over 
max
                                        before we commit suicide? */
     if ((CFD_MAXPROCESSES < 1) || (CFD_MAXPROCESSES > 1000))
--- 312,318 ----
     Debug("$(MaxConnections) Expanded to %s\n",VBUFF);
  
     CFD_MAXPROCESSES = atoi(VBUFF);
! 
     MAXTRIES = CFD_MAXPROCESSES / 3;  /* How many attempted connections over 
max
                                        before we commit suicide? */
     if ((CFD_MAXPROCESSES < 1) || (CFD_MAXPROCESSES > 1000))
***************
*** 348,369 ****
  Debug("AutoExecInterval = %d\n",CFD_INTERVAL);
  
  CHECKSUMUPDATES = true;
!  
  if (GetMacroValue("ChecksumUpdates") && 
(strcmp(GetMacroValue("ChecksumUpdates"),"off") == 0))
    {
    CHECKSUMUPDATES = false;
!   } 
!  
  i = 0;
  
  if (strstr(VSYSNAME.nodename,ToLowerStr(VDOMAIN)))
     {
     strncpy(VFQNAME,VSYSNAME.nodename,bufsize-1);
!    
     while(VSYSNAME.nodename[i++] != '.')
        {
        }
!    
     strncpy(VUQNAME,VSYSNAME.nodename,i-1);
     }
  else
--- 348,369 ----
  Debug("AutoExecInterval = %d\n",CFD_INTERVAL);
  
  CHECKSUMUPDATES = true;
! 
  if (GetMacroValue("ChecksumUpdates") && 
(strcmp(GetMacroValue("ChecksumUpdates"),"off") == 0))
    {
    CHECKSUMUPDATES = false;
!   }
! 
  i = 0;
  
  if (strstr(VSYSNAME.nodename,ToLowerStr(VDOMAIN)))
     {
     strncpy(VFQNAME,VSYSNAME.nodename,bufsize-1);
! 
     while(VSYSNAME.nodename[i++] != '.')
        {
        }
! 
     strncpy(VUQNAME,VSYSNAME.nodename,i-1);
     }
  else
***************
*** 379,385 ****
  
  { struct Auth *ptr;
    struct Item *ip,*ipr;
!   
  if (DEBUG || D2 || D3)
     {
     printf("ACCESS GRANTED ----------------------:\n\n");
--- 379,385 ----
  
  { struct Auth *ptr;
    struct Item *ip,*ipr;
! 
  if (DEBUG || D2 || D3)
     {
     printf("ACCESS GRANTED ----------------------:\n\n");
***************
*** 408,416 ****
        for (ip = ptr->accesslist; ip != NULL; ip=ip->next)
         {
         printf("   Deny: %s\n",ip->name);
!        }      
        }
!    
     printf("Host IPs allowed connection access :\n\n");
  
     for (ip = NONATTACKERLIST; ip != NULL; ip=ip->next)
--- 408,416 ----
        for (ip = ptr->accesslist; ip != NULL; ip=ip->next)
         {
         printf("   Deny: %s\n",ip->name);
!        }
        }
! 
     printf("Host IPs allowed connection access :\n\n");
  
     for (ip = NONATTACKERLIST; ip != NULL; ip=ip->next)
***************
*** 484,490 ****
  
  cflinger.l_onoff = 1;
  cflinger.l_linger = 60;
!   
  if ((!NO_FORK) && (fork() != 0))
     {
     sprintf(OUTPUT,"cfd: starting %.24s\n",ctime(&CFDSTARTTIME));
--- 484,490 ----
  
  cflinger.l_onoff = 1;
  cflinger.l_linger = 60;
! 
  if ((!NO_FORK) && (fork() != 0))
     {
     sprintf(OUTPUT,"cfd: starting %.24s\n",ctime(&CFDSTARTTIME));
***************
*** 496,502 ****
    {
  #ifdef HAVE_SETSID
    setsid();
! #endif 
    fclose (stdin);
    fclose (stdout);
    fclose (stderr);
--- 496,502 ----
    {
  #ifdef HAVE_SETSID
    setsid();
! #endif
    fclose (stdin);
    fclose (stdout);
    fclose (stderr);
***************
*** 510,523 ****
  
  
  SetAuto(CFD_INTERVAL);
!   
  port = CfenginePort();
!   
  bzero(&cin,sizeof(cin));
  
  sin.sin_port = (unsigned short)(port); /*  Service returns network byte order 
*/
  sin.sin_addr.s_addr = INADDR_ANY;
! sin.sin_family = AF_INET; 
  
  if ((sd = socket(AF_INET,SOCK_STREAM,0)) == -1)
     {
--- 510,523 ----
  
  
  SetAuto(CFD_INTERVAL);
! 
  port = CfenginePort();
! 
  bzero(&cin,sizeof(cin));
  
  sin.sin_port = (unsigned short)(port); /*  Service returns network byte order 
*/
  sin.sin_addr.s_addr = INADDR_ANY;
! sin.sin_family = AF_INET;
  
  if ((sd = socket(AF_INET,SOCK_STREAM,0)) == -1)
     {
***************
*** 565,571 ****
        {
        int result;
        int status;
!       
        result = waitpid(auto_pid, &status, WNOHANG);
        if (result == auto_pid)
         {
--- 565,571 ----
        {
        int result;
        int status;
! 
        result = waitpid(auto_pid, &status, WNOHANG);
        if (result == auto_pid)
         {
***************
*** 619,628 ****
         tv.tv_sec = timeout_secs;
         tv.tv_usec = 0;
         }
!       
        FD_ZERO(&rfds);
        FD_SET(sd,&rfds);
!       
        Debug("Going to sleep (select) for %d seconds\n", timeout_secs);
  
        ready = select(sd+1, &rfds, 0, 0, &tv);
--- 619,628 ----
         tv.tv_sec = timeout_secs;
         tv.tv_usec = 0;
         }
! 
        FD_ZERO(&rfds);
        FD_SET(sd,&rfds);
! 
        Debug("Going to sleep (select) for %d seconds\n", timeout_secs);
  
        ready = select(sd+1, &rfds, 0, 0, &tv);
***************
*** 653,661 ****
         CfLog(cferror,"Couldn't get socket address\n","getpeername");
         continue;
         }
!       
        sprintf(ipaddr,"%s",inet_ntoa(raddr.sin_addr));
!       
        if ((NONATTACKERLIST != NULL) && 
!IsFuzzyItemIn(NONATTACKERLIST,ipaddr))   /* Allowed Subnets */
         {
         sprintf(OUTPUT,"Denying connection from non-authorized IP 
%s\n",ipaddr);
--- 653,661 ----
         CfLog(cferror,"Couldn't get socket address\n","getpeername");
         continue;
         }
! 
        sprintf(ipaddr,"%s",inet_ntoa(raddr.sin_addr));
! 
        if ((NONATTACKERLIST != NULL) && 
!IsFuzzyItemIn(NONATTACKERLIST,ipaddr))   /* Allowed Subnets */
         {
         sprintf(OUTPUT,"Denying connection from non-authorized IP 
%s\n",ipaddr);
***************
*** 663,677 ****
         close(sd_reply);
         continue;
         }
!       
        if (IsFuzzyItemIn(ATTACKERLIST,ipaddr))   /* Denied Subnets */
         {
         sprintf(OUTPUT,"Denying connection from non-authorized IP 
%s\n",ipaddr);
         CfLog(cferror,OUTPUT,"");
         close(sd_reply);
         continue;
!        }      
!       
        if ((now = time((time_t *)NULL)) == -1)
         {
         printf("Couldn't read system clock\n");
--- 663,677 ----
         close(sd_reply);
         continue;
         }
! 
        if (IsFuzzyItemIn(ATTACKERLIST,ipaddr))   /* Denied Subnets */
         {
         sprintf(OUTPUT,"Denying connection from non-authorized IP 
%s\n",ipaddr);
         CfLog(cferror,OUTPUT,"");
         close(sd_reply);
         continue;
!        }
! 
        if ((now = time((time_t *)NULL)) == -1)
         {
         printf("Couldn't read system clock\n");
***************
*** 681,689 ****
         {
         sprintf(intime,"%d",(int)now);
         }
!       
        PurgeOldConnections(&CONNECTIONLIST,intime);
!       
        if (!IsFuzzyItemIn(MULTICONNLIST,ipaddr))
         {
         if (IsItemIn(CONNECTIONLIST,ipaddr))
--- 681,689 ----
         {
         sprintf(intime,"%d",(int)now);
         }
! 
        PurgeOldConnections(&CONNECTIONLIST,intime);
! 
        if (!IsFuzzyItemIn(MULTICONNLIST,ipaddr))
         {
         if (IsItemIn(CONNECTIONLIST,ipaddr))
***************
*** 792,798 ****
  /*#ifdef HAVE_PTHREAD_ATTR_SETSTACKSIZE This seems to cause problems on some 
OSes*/
  
pthread_attr_setstacksize(&PTHREADDEFAULTS,(size_t)(sysconf(_SC_THREAD_STACK_MIN)+100*1024));
  /*#endif*/
!  
  if (pthread_create(&tid,&PTHREADDEFAULTS,HandleConnection,(void *)conn) != 0)
     {
     CfLog(cferror,"pthread_create failed","create");
--- 792,798 ----
  /*#ifdef HAVE_PTHREAD_ATTR_SETSTACKSIZE This seems to cause problems on some 
OSes*/
  
pthread_attr_setstacksize(&PTHREADDEFAULTS,(size_t)(sysconf(_SC_THREAD_STACK_MIN)+100*1024));
  /*#endif*/
! 
  if (pthread_create(&tid,&PTHREADDEFAULTS,HandleConnection,(void *)conn) != 0)
     {
     CfLog(cferror,"pthread_create failed","create");
***************
*** 808,814 ****
  Debug("Single threaded...\n");
  
  HandleConnection(conn);
!  
  #endif
  }
  
--- 808,814 ----
  Debug("Single threaded...\n");
  
  HandleConnection(conn);
! 
  #endif
  }
  
***************
*** 825,838 ****
    char arg[maxshellargs][bufsize];
    FILE *pp;
    int i;
!   
  bzero(&newstat,sizeof(struct stat));
  bzero(filename,bufsize);
  
  if ((sp=getenv(CFINPUTSVAR)) != NULL)
     {
     if (! IsAbsoluteFileName(VINPUTFILE))     /* Don't prepend to absolute 
names */
!       { 
        strncpy(filename,sp,bufsize-1);
        AddSlash(filename);
        }
--- 825,838 ----
    char arg[maxshellargs][bufsize];
    FILE *pp;
    int i;
! 
  bzero(&newstat,sizeof(struct stat));
  bzero(filename,bufsize);
  
  if ((sp=getenv(CFINPUTSVAR)) != NULL)
     {
     if (! IsAbsoluteFileName(VINPUTFILE))     /* Don't prepend to absolute 
names */
!       {
        strncpy(filename,sp,bufsize-1);
        AddSlash(filename);
        }
***************
*** 862,868 ****
        CfLog(cferror,"pthread_mutex_lock failed","lock");
        }
  #endif
!    
     for (i = 0; i < hashtablesize; i++)
        {
        if (HASH[i] != NULL)
--- 862,868 ----
        CfLog(cferror,"pthread_mutex_lock failed","lock");
        }
  #endif
! 
     for (i = 0; i < hashtablesize; i++)
        {
        if (HASH[i] != NULL)
***************
*** 877,883 ****
     DeleteAuthList(VADMIT);
     DeleteAuthList(VDENY);
     strcpy(VDOMAIN,"undefined.domain");
!    
     VADMIT = VADMITTOP = NULL;
     VDENY  = VDENYTOP  = NULL;
     VHEAP  = VNEGHEAP  = NULL;
--- 877,883 ----
     DeleteAuthList(VADMIT);
     DeleteAuthList(VDENY);
     strcpy(VDOMAIN,"undefined.domain");
! 
     VADMIT = VADMITTOP = NULL;
     VDENY  = VDENYTOP  = NULL;
     VHEAP  = VNEGHEAP  = NULL;
***************
*** 893,899 ****
     if (pthread_mutex_unlock(&MUTEX_COUNT) != 0)
        {
        CfLog(cferror,"pthread_mutex_unlock failed","unlock");
!       }  
  #endif
     }
  }
--- 893,899 ----
     if (pthread_mutex_unlock(&MUTEX_COUNT) != 0)
        {
        CfLog(cferror,"pthread_mutex_unlock failed","unlock");
!       }
  #endif
     }
  }
***************
*** 912,920 ****
   sigset_t sigmask;
  
  sigemptyset(&sigmask);
! pthread_sigmask(SIG_BLOCK,&sigmask,NULL); 
  #endif
!  
  if (pthread_mutex_lock(&MUTEX_COUNT) != 0)
     {
     CfLog(cferror,"pthread_mutex_lock failed","pthread_mutex_lock");
--- 912,920 ----
   sigset_t sigmask;
  
  sigemptyset(&sigmask);
! pthread_sigmask(SIG_BLOCK,&sigmask,NULL);
  #endif
! 
  if (pthread_mutex_lock(&MUTEX_COUNT) != 0)
     {
     CfLog(cferror,"pthread_mutex_lock failed","pthread_mutex_lock");
***************
*** 927,933 ****
  if (pthread_mutex_unlock(&MUTEX_COUNT) != 0)
     {
     CfLog(cferror,"pthread_mutex_unlock failed","unlock");
!    }  
  
  if (ACTIVE_THREADS >= CFD_MAXPROCESSES)
     {
--- 927,933 ----
  if (pthread_mutex_unlock(&MUTEX_COUNT) != 0)
     {
     CfLog(cferror,"pthread_mutex_unlock failed","unlock");
!    }
  
  if (ACTIVE_THREADS >= CFD_MAXPROCESSES)
     {
***************
*** 937,945 ****
        DeleteConn(conn);
        return NULL;
        }
!    
     ACTIVE_THREADS--;
!    
     if (TRIES++ > MAXTRIES)  /* When to say we're hung / apoptosis threshold */
        {
        CfLog(cferror,"Seem to be paralyzed. Committing apoptosis...","");
--- 937,945 ----
        DeleteConn(conn);
        return NULL;
        }
! 
     ACTIVE_THREADS--;
! 
     if (TRIES++ > MAXTRIES)  /* When to say we're hung / apoptosis threshold */
        {
        CfLog(cferror,"Seem to be paralyzed. Committing apoptosis...","");
***************
*** 950,956 ****
        {
        CfLog(cferror,"pthread_mutex_unlock failed","unlock");
        }
!    
     CfLog(cfinform,"Too many threads","");
     DeleteConn(conn);
  
--- 950,956 ----
        {
        CfLog(cferror,"pthread_mutex_unlock failed","unlock");
        }
! 
     CfLog(cfinform,"Too many threads","");
     DeleteConn(conn);
  
***************
*** 958,976 ****
     }
  
  TRIES = 0;   /* As long as there is activity, we're not stuck */
!  
  #endif
!  
  while (BusyWithConnection(conn))
     {
     }
  
  DeleteConn(conn);
!  
  #ifdef HAVE_LIBPTHREAD
  
   Debug("Terminating thread...\n");
!  
  if (pthread_mutex_lock(&MUTEX_COUNT) != 0)
     {
     CfLog(cferror,"pthread_mutex_lock failed","pthread_mutex_lock");
--- 958,976 ----
     }
  
  TRIES = 0;   /* As long as there is activity, we're not stuck */
! 
  #endif
! 
  while (BusyWithConnection(conn))
     {
     }
  
  DeleteConn(conn);
! 
  #ifdef HAVE_LIBPTHREAD
  
   Debug("Terminating thread...\n");
! 
  if (pthread_mutex_lock(&MUTEX_COUNT) != 0)
     {
     CfLog(cferror,"pthread_mutex_lock failed","pthread_mutex_lock");
***************
*** 983,992 ****
     {
     CfLog(cferror,"pthread_mutex_unlock failed","unlock");
     }
!  
  #endif
  
! return NULL; 
  }
  
  /*********************************************************************/
--- 983,992 ----
     {
     CfLog(cferror,"pthread_mutex_unlock failed","unlock");
     }
! 
  #endif
  
! return NULL;
  }
  
  /*********************************************************************/
***************
*** 1000,1006 ****
    /* and extract the information from the message */
  
  { time_t tloc, trem = 0;
!   char recvbuffer[bufsize], sendbuffer[bufsize],check[bufsize];  
    char filename[bufsize],buffer[bufsize],args[bufsize],out[bufsize];
    long time_no_see = 0;
    int len=0, drift;
--- 1000,1006 ----
    /* and extract the information from the message */
  
  { time_t tloc, trem = 0;
!   char recvbuffer[bufsize], sendbuffer[bufsize],check[bufsize];
    char filename[bufsize],buffer[bufsize],args[bufsize],out[bufsize];
    long time_no_see = 0;
    int len=0, drift;
***************
*** 1013,1032 ****
     {
     CfLog(cferror,"Null conn in BusyWithConnection. Should not happen.","");
     }
!  
  if (RecvSocketStream(conn->sd_reply,recvbuffer,bufsize,0) == -1)
     {
     return false;
     }
  
  recvbuffer[bufsize-1] = '\0';
!  
  if (strlen(recvbuffer) == 0)
     {
     Debug("cfd: terminating NULL transmission!\n");
     return false;
     }
!   
  Debug("Received: [%s] on socket %d\n",recvbuffer,conn->sd_reply);
  
  switch (GetCommand(recvbuffer))
--- 1013,1032 ----
     {
     CfLog(cferror,"Null conn in BusyWithConnection. Should not happen.","");
     }
! 
  if (RecvSocketStream(conn->sd_reply,recvbuffer,bufsize,0) == -1)
     {
     return false;
     }
  
  recvbuffer[bufsize-1] = '\0';
! 
  if (strlen(recvbuffer) == 0)
     {
     Debug("cfd: terminating NULL transmission!\n");
     return false;
     }
! 
  Debug("Received: [%s] on socket %d\n",recvbuffer,conn->sd_reply);
  
  switch (GetCommand(recvbuffer))
***************
*** 1043,1049 ****
                     if (!AccessControl(CFRUNCOMMAND,conn,false))
                        {
                        RefuseAccess(conn,sendbuffer);
!                       return false;                   
                        }
  
                     if (!MatchClasses(conn))
--- 1043,1049 ----
                     if (!AccessControl(CFRUNCOMMAND,conn,false))
                        {
                        RefuseAccess(conn,sendbuffer);
!                       return false;
                        }
  
                     if (!MatchClasses(conn))
***************
*** 1061,1067 ****
     case cfd_auth:    sprintf (sendbuffer,"BAD: Old protocol, you need to 
upgrade to 1.5.x\n");
                       SendTransaction(conn,sendbuffer);
                       return false;
!                    
     case cfd_cauth:   conn->id_verified = VerifyConnection(conn,(char 
*)(recvbuffer+strlen("CAUTH ")));
                       if (! conn->id_verified)
                        {
--- 1061,1067 ----
     case cfd_auth:    sprintf (sendbuffer,"BAD: Old protocol, you need to 
upgrade to 1.5.x\n");
                       SendTransaction(conn,sendbuffer);
                       return false;
! 
     case cfd_cauth:   conn->id_verified = VerifyConnection(conn,(char 
*)(recvbuffer+strlen("CAUTH ")));
                       if (! conn->id_verified)
                        {
***************
*** 1087,1104 ****
                     if (!AccessControl(filename,conn,false))
                        {
                        RefuseAccess(conn,sendbuffer);
!                       return false;                   
                        }
  
                     bzero(sendbuffer,bufsize);
!                    
                     get_args.connect = conn;
                     get_args.secure = false;
                     get_args.replybuff = sendbuffer;
                     get_args.replyfile = filename;
!                    
                     CfGetFile(&get_args);
!                    
                     return true;
  
     case cfd_sget:    bzero(buffer,bufsize);
--- 1087,1104 ----
                     if (!AccessControl(filename,conn,false))
                        {
                        RefuseAccess(conn,sendbuffer);
!                       return false;
                        }
  
                     bzero(sendbuffer,bufsize);
! 
                     get_args.connect = conn;
                     get_args.secure = false;
                     get_args.replybuff = sendbuffer;
                     get_args.replyfile = filename;
! 
                     CfGetFile(&get_args);
! 
                     return true;
  
     case cfd_sget:    bzero(buffer,bufsize);
***************
*** 1111,1117 ****
                        }
                       bcopy(recvbuffer+31,out,bufsize-32);
                       cfdecrypt(out,buffer,CFDES1,CFDES2,CFDES3,len);
!                    
                       cfscanf(buffer,3,8,check,get_args.key,filename);
  
                     Debug("Buffer was %s\n",buffer);
--- 1111,1117 ----
                        }
                       bcopy(recvbuffer+31,out,bufsize-32);
                       cfdecrypt(out,buffer,CFDES1,CFDES2,CFDES3,len);
! 
                       cfscanf(buffer,3,8,check,get_args.key,filename);
  
                     Debug("Buffer was %s\n",buffer);
***************
*** 1127,1133 ****
                        RefuseAccess(conn,sendbuffer);
                        return false;
                        }
!                    
                     Debug("Confirm decryption, and thus validity of caller\n");
                     Debug("SGET %s with blocksize 
%d\n",filename,get_args.buf_size);
  
--- 1127,1133 ----
                        RefuseAccess(conn,sendbuffer);
                        return false;
                        }
! 
                     Debug("Confirm decryption, and thus validity of caller\n");
                     Debug("SGET %s with blocksize 
%d\n",filename,get_args.buf_size);
  
***************
*** 1140,1161 ****
                     if (!AccessControl(filename,conn,true))
                        {
                        RefuseAccess(conn,sendbuffer);
!                       return false;                   
                        }
  
                     bzero(sendbuffer,bufsize);
!                    
                     get_args.connect = conn;
                     get_args.secure = true;
                     get_args.replybuff = sendbuffer;
                     get_args.replyfile = filename;
!                    
                     CfGetFile(&get_args);
                     return true;
!                    
     case cfd_opendir: bzero(filename,bufsize);
                       sscanf(recvbuffer,"OPENDIR %[^\n]",filename);
!                    
                     if (! conn->id_verified)
                        {
                        RefuseAccess(conn,sendbuffer);
--- 1140,1161 ----
                     if (!AccessControl(filename,conn,true))
                        {
                        RefuseAccess(conn,sendbuffer);
!                       return false;
                        }
  
                     bzero(sendbuffer,bufsize);
! 
                     get_args.connect = conn;
                     get_args.secure = true;
                     get_args.replybuff = sendbuffer;
                     get_args.replyfile = filename;
! 
                     CfGetFile(&get_args);
                     return true;
! 
     case cfd_opendir: bzero(filename,bufsize);
                       sscanf(recvbuffer,"OPENDIR %[^\n]",filename);
! 
                     if (! conn->id_verified)
                        {
                        RefuseAccess(conn,sendbuffer);
***************
*** 1165,1172 ****
                     if (!AccessControl(filename,conn,true)) /* opendir don't 
care about security */
                        {
                        RefuseAccess(conn,sendbuffer);
!                       return false;                   
!                       }                    
  
                     CfOpenDirectory(conn,sendbuffer,filename);
                       return true;
--- 1165,1172 ----
                     if (!AccessControl(filename,conn,true)) /* opendir don't 
care about security */
                        {
                        RefuseAccess(conn,sendbuffer);
!                       return false;
!                       }
  
                     CfOpenDirectory(conn,sendbuffer,filename);
                       return true;
***************
*** 1189,1202 ****
                        return false;
                        }
                     /* roll through, no break */
!                    
     case cfd_synch:
                     if (! conn->id_verified)
                        {
                        RefuseAccess(conn,sendbuffer);
                        return false;
                        }
!                    
                       bzero(filename,bufsize);
                       sscanf(recvbuffer,"SYNCH %ld STAT 
%[^\n]",&time_no_see,filename);
  
--- 1189,1202 ----
                        return false;
                        }
                     /* roll through, no break */
! 
     case cfd_synch:
                     if (! conn->id_verified)
                        {
                        RefuseAccess(conn,sendbuffer);
                        return false;
                        }
! 
                       bzero(filename,bufsize);
                       sscanf(recvbuffer,"SYNCH %ld STAT 
%[^\n]",&time_no_see,filename);
  
***************
*** 1206,1212 ****
                        {
                        break;
                        }
!                    
                     if ((tloc = time((time_t *)NULL)) == -1)
                          {
                          sprintf(conn->output,"Couldn't read system clock\n");
--- 1206,1212 ----
                        {
                        break;
                        }
! 
                     if ((tloc = time((time_t *)NULL)) == -1)
                          {
                          sprintf(conn->output,"Couldn't read system clock\n");
***************
*** 1235,1248 ****
  
     case cfd_smd5:    bzero(buffer,bufsize);
                       sscanf(recvbuffer,"SMD5 %d",&len);
!                    
                     if (len < 0 || len > bufsize-24)
                        {
                        Debug("Bogus len received: %d\n",len);
                        RefuseAccess(conn,sendbuffer);
                        return false;
                        }
!                    
                       bcopy(recvbuffer+23,out,bufsize-24);
                       cfdecrypt(out,recvbuffer,CFDES1,CFDES2,CFDES3,len);
  
--- 1235,1248 ----
  
     case cfd_smd5:    bzero(buffer,bufsize);
                       sscanf(recvbuffer,"SMD5 %d",&len);
! 
                     if (len < 0 || len > bufsize-24)
                        {
                        Debug("Bogus len received: %d\n",len);
                        RefuseAccess(conn,sendbuffer);
                        return false;
                        }
! 
                       bcopy(recvbuffer+23,out,bufsize-24);
                       cfdecrypt(out,recvbuffer,CFDES1,CFDES2,CFDES3,len);
  
***************
*** 1252,1275 ****
                        return false;
                        }
                     /* roll through, no break */
!        
     case cfd_md5:
                     if (! conn->id_verified)
                        {
                        RefuseAccess(conn,sendbuffer);
                        return false;
                        }
!                    
                       bzero(filename,bufsize);
                     bzero(args,bufsize);
!                    
                       CompareLocalChecksum(conn,sendbuffer,recvbuffer);
!                    return true;                    
     }
  
  sprintf (sendbuffer,"BAD: Malformed protocol request\n");
  SendTransaction(conn,sendbuffer);
! CfLog(cfinform,"Closing connection\n",""); 
  return false;
  }
  
--- 1252,1275 ----
                        return false;
                        }
                     /* roll through, no break */
! 
     case cfd_md5:
                     if (! conn->id_verified)
                        {
                        RefuseAccess(conn,sendbuffer);
                        return false;
                        }
! 
                       bzero(filename,bufsize);
                     bzero(args,bufsize);
! 
                       CompareLocalChecksum(conn,sendbuffer,recvbuffer);
!                    return true;
     }
  
  sprintf (sendbuffer,"BAD: Malformed protocol request\n");
  SendTransaction(conn,sendbuffer);
! CfLog(cfinform,"Closing connection\n","");
  return false;
  }
  
***************
*** 1278,1290 ****
  void ExitCleanly()
  
  { int i;
!  
  sprintf(OUTPUT,"Exit -- (waiting for threads), pid = %d\n",getpid());
  CfLog(cfinform,OUTPUT,"");
  closelog();
  
  #ifdef HAVE_PTHREAD_H
! /* Do we care about this? 
  for (i = 0; i < MAXTHREAD ; i++)
     {
     if (THREADS[i] != NULL)
--- 1278,1290 ----
  void ExitCleanly()
  
  { int i;
! 
  sprintf(OUTPUT,"Exit -- (waiting for threads), pid = %d\n",getpid());
  CfLog(cfinform,OUTPUT,"");
  closelog();
  
  #ifdef HAVE_PTHREAD_H
! /* Do we care about this?
  for (i = 0; i < MAXTHREAD ; i++)
     {
     if (THREADS[i] != NULL)
***************
*** 1293,1300 ****
        }
     }
     */
! #endif 
!  
  exit(0);
  }
  
--- 1293,1300 ----
        }
     }
     */
! #endif
! 
  exit(0);
  }
  
***************
*** 1303,1315 ****
  void AutoExec()
  
  { char logbuffer[bufsize], line[bufsize], *sp;
!   FILE *pp; 
    int print;
!   
  VBUFF[0] = '\0';
  
  Debug("Autoexec time\n");
! SetAuto(CFD_INTERVAL); 
  ExpandVarstring("$(AutoExecCommand)",VBUFF,"");
  
  if (strlen(VBUFF) == 0)
--- 1303,1315 ----
  void AutoExec()
  
  { char logbuffer[bufsize], line[bufsize], *sp;
!   FILE *pp;
    int print;
! 
  VBUFF[0] = '\0';
  
  Debug("Autoexec time\n");
! SetAuto(CFD_INTERVAL);
  ExpandVarstring("$(AutoExecCommand)",VBUFF,"");
  
  if (strlen(VBUFF) == 0)
***************
*** 1319,1342 ****
     }
  
  /* Use same lock as for cfrun */
!  
   if (!GetLock("cfd","daemon",VIFELAPSED,VEXPIREAFTER,VUQNAME,CFSTARTTIME))
     {
     sprintf(OUTPUT,"cfd: Couldn't get a lock -- too soon: IfElapsed %d, 
ExpireAfter %d\n",VIFELAPSED,VEXPIREAFTER);
     CfLog(cferror,OUTPUT,"");
!    
     return;
     }
!  
  auto_pid = fork();
  if (auto_pid == 0)
     {
     signal(SIGPIPE,SIG_IGN);
!    
     ExpandVarstring("$(AutoExecCommand) --no-splay --inform",VBUFF,"");
  
     sprintf(OUTPUT,"Interval expired, executing command %s\n",VBUFF);
!    CfLog(cfinform,OUTPUT,""); 
  
     bzero(logbuffer,bufsize);
  
--- 1319,1342 ----
     }
  
  /* Use same lock as for cfrun */
! 
   if (!GetLock("cfd","daemon",VIFELAPSED,VEXPIREAFTER,VUQNAME,CFSTARTTIME))
     {
     sprintf(OUTPUT,"cfd: Couldn't get a lock -- too soon: IfElapsed %d, 
ExpireAfter %d\n",VIFELAPSED,VEXPIREAFTER);
     CfLog(cferror,OUTPUT,"");
! 
     return;
     }
! 
  auto_pid = fork();
  if (auto_pid == 0)
     {
     signal(SIGPIPE,SIG_IGN);
! 
     ExpandVarstring("$(AutoExecCommand) --no-splay --inform",VBUFF,"");
  
     sprintf(OUTPUT,"Interval expired, executing command %s\n",VBUFF);
!    CfLog(cfinform,OUTPUT,"");
  
     bzero(logbuffer,bufsize);
  
***************
*** 1347,1353 ****
  
        exit(1);
        }
!    
     while (!feof(pp))
        {
        if (ferror(pp))  /* abortable */
--- 1347,1353 ----
  
        exit(1);
        }
! 
     while (!feof(pp))
        {
        if (ferror(pp))  /* abortable */
***************
*** 1355,1373 ****
         fflush(pp);
         break;
         }
!       
        Debug("starting read line\n");
        ReadLine(line,bufsize,pp);
        Debug("finished read line\n");
!       
        if (ferror(pp))  /* abortable */
         {
         fflush(pp);
         break;
!        }       
!       
        print = false;
!       
        for (sp = line; *sp != '\0'; sp++)
         {
         if (! isspace(*sp))
--- 1355,1373 ----
         fflush(pp);
         break;
         }
! 
        Debug("starting read line\n");
        ReadLine(line,bufsize,pp);
        Debug("finished read line\n");
! 
        if (ferror(pp))  /* abortable */
         {
         fflush(pp);
         break;
!        }
! 
        print = false;
! 
        for (sp = line; *sp != '\0'; sp++)
         {
         if (! isspace(*sp))
***************
*** 1376,1389 ****
            break;
            }
         }
!       
        if (print)
         {
         sprintf(logbuffer,"%s\n",line);
         CfLog(cfinform,logbuffer,"");
         }
        }
!    
     cfpclose(pp);
     closelog();
     exit(0);
--- 1376,1389 ----
            break;
            }
         }
! 
        if (print)
         {
         sprintf(logbuffer,"%s\n",line);
         CfLog(cfinform,logbuffer,"");
         }
        }
! 
     cfpclose(pp);
     closelog();
     exit(0);
***************
*** 1411,1417 ****
  
     if (RecvSocketStream(conn->sd_reply,recvbuffer,bufsize,0) == -1)
        {
!       if (errno == EINTR) 
           {
           continue;
           }
--- 1411,1417 ----
  
     if (RecvSocketStream(conn->sd_reply,recvbuffer,bufsize,0) == -1)
        {
!       if (errno == EINTR)
           {
           continue;
           }
***************
*** 1426,1435 ****
         Debug("No classes were sent, assuming no restrictions...\n");
         return true;
         }
!       
        break;
        }
!    
     classlist = SplitStringAsItemList(recvbuffer,' ');
  
     for (ip = classlist; ip != NULL; ip=ip->next)
--- 1426,1435 ----
         Debug("No classes were sent, assuming no restrictions...\n");
         return true;
         }
! 
        break;
        }
! 
     classlist = SplitStringAsItemList(recvbuffer,' ');
  
     for (ip = classlist; ip != NULL; ip=ip->next)
***************
*** 1440,1446 ****
         DeleteItemList(classlist);
         return true;
         }
!       
        if (strcmp(ip->name,CFD_TERMINATOR) == 0)
         {
         Debug("No classes matched, rejecting....\n");
--- 1440,1446 ----
         DeleteItemList(classlist);
         return true;
         }
! 
        if (strcmp(ip->name,CFD_TERMINATOR) == 0)
         {
         Debug("No classes matched, rejecting....\n");
***************
*** 1536,1542 ****
     }
  
  sprintf(conn->output,"Executing command %s\n",buffer);
! CfLog(cfinform,conn->output,""); 
  
  bzero(sendbuffer,bufsize);
  
--- 1536,1542 ----
     }
  
  sprintf(conn->output,"Executing command %s\n",buffer);
! CfLog(cfinform,conn->output,"");
  
  bzero(sendbuffer,bufsize);
  
***************
*** 1560,1574 ****
        }
  
     ReadLine(line,bufsize,pp);
!    
     if (ferror(pp))  /* abortable */
        {
        fflush(pp);
        break;
!       }        
  
     print = false;
!        
     for (sp = line; *sp != '\0'; sp++)
        {
        if (! isspace(*sp))
--- 1560,1574 ----
        }
  
     ReadLine(line,bufsize,pp);
! 
     if (ferror(pp))  /* abortable */
        {
        fflush(pp);
        break;
!       }
  
     print = false;
! 
     for (sp = line; *sp != '\0'; sp++)
        {
        if (! isspace(*sp))
***************
*** 1577,1590 ****
         break;
         }
        }
!        
     if (print)
        {
        sprintf(sendbuffer,"%s\n",line);
        SendTransaction(conn,sendbuffer);
        }
    }
!       
  cfpclose(pp);
  ReleaseCurrentLock();
  }
--- 1577,1590 ----
         break;
         }
        }
! 
     if (print)
        {
        sprintf(sendbuffer,"%s\n",line);
        SendTransaction(conn,sendbuffer);
        }
    }
! 
  cfpclose(pp);
  ReleaseCurrentLock();
  }
***************
*** 1627,1638 ****
    char name1[256], name2[256], name3[256], rusername[256];
    struct hostent *hp;
    int len, i, j, found;
!    
  Debug("Connecting host identifies itself as %s\n",buf);
  
  bzero(ipstring,256);
  bzero(fqname,256);
! bzero(username,256); 
  
  sscanf(buf,"%255s %255s %255s %8s",ipstring,fqname,username,conn->signature);
  len = sizeof(struct sockaddr_in);
--- 1627,1638 ----
    char name1[256], name2[256], name3[256], rusername[256];
    struct hostent *hp;
    int len, i, j, found;
! 
  Debug("Connecting host identifies itself as %s\n",buf);
  
  bzero(ipstring,256);
  bzero(fqname,256);
! bzero(username,256);
  
  sscanf(buf,"%255s %255s %255s %8s",ipstring,fqname,username,conn->signature);
  len = sizeof(struct sockaddr_in);
***************
*** 1644,1650 ****
     }
  
  strcpy(name1,ToLowerStr(fqname));
! strcpy(name2,ToLowerStr(inet_ntoa(raddr.sin_addr))); 
  strcpy(name3,ToLowerStr(ipstring));
  strncpy(conn->ipaddr,name3,sizeof(conn->ipaddr)-1);
  
--- 1644,1650 ----
     }
  
  strcpy(name1,ToLowerStr(fqname));
! strcpy(name2,ToLowerStr(inet_ntoa(raddr.sin_addr)));
  strcpy(name3,ToLowerStr(ipstring));
  strncpy(conn->ipaddr,name3,sizeof(conn->ipaddr)-1);
  
***************
*** 1654,1660 ****
     CfLog(cfinform,OUTPUT,"");
     return true;
     }
!  
  if (strcmp(name2,name3) != 0)
     {
     Verbose("IP address mismatch between client's assertion and socket - 
untrustworthy connection\n");
--- 1654,1660 ----
     CfLog(cfinform,OUTPUT,"");
     return true;
     }
! 
  if (strcmp(name2,name3) != 0)
     {
     Verbose("IP address mismatch between client's assertion and socket - 
untrustworthy connection\n");
***************
*** 1662,1674 ****
     }
  
  Verbose("Socket caller address appears honest\n");
!  
  sprintf(conn->output,"Socket originates from %s=%s with signature 
%8s\n",name2,name1,conn->signature);
! CfLog(cfverbose,conn->output,""); 
  
  #if defined(HAVE_TCPD_H) && defined(HAVE_LIBWRAP)
  
! if (!hosts_ctl("cfd",name1,name2,username))
     {
     Verbose("TCPwrap(%s,%s,%s) rejects this packet\n",name1,name2,username);
     return false;
--- 1662,1674 ----
     }
  
  Verbose("Socket caller address appears honest\n");
! 
  sprintf(conn->output,"Socket originates from %s=%s with signature 
%8s\n",name2,name1,conn->signature);
! CfLog(cfverbose,conn->output,"");
  
  #if defined(HAVE_TCPD_H) && defined(HAVE_LIBWRAP)
  
! if (!hosts_ctl("cfengine",name1,name2,username))
     {
     Verbose("TCPwrap(%s,%s,%s) rejects this packet\n",name1,name2,username);
     return false;
***************
*** 1680,1692 ****
  
  Debug("Attempting to look up hostname %s\n",name1);
  
! #ifdef HAVE_PTHREAD_H 
  if (pthread_mutex_lock(&MUTEX_HOSTNAME) != 0)
     {
     CfLog(cferror,"pthread_mutex_lock failed","pthread_mutex_lock");
     return false;
     }
! #endif 
  
  if ((hp = gethostbyname(name1)) == NULL)
     {
--- 1680,1692 ----
  
  Debug("Attempting to look up hostname %s\n",name1);
  
! #ifdef HAVE_PTHREAD_H
  if (pthread_mutex_lock(&MUTEX_HOSTNAME) != 0)
     {
     CfLog(cferror,"pthread_mutex_lock failed","pthread_mutex_lock");
     return false;
     }
! #endif
  
  if ((hp = gethostbyname(name1)) == NULL)
     {
***************
*** 1695,1720 ****
     Verbose("     i.e. www.gnu.org, not just www. If you use NIS or 
/etc/hosts\n");
     Verbose("     make sure that the full form is registered too as an 
alias!\n");
  
! #ifdef HAVE_PTHREAD_H    
     if (pthread_mutex_unlock(&MUTEX_HOSTNAME) != 0)
        {
        CfLog(cferror,"pthread_mutex_unlock failed","unlock");
        }
! #endif 
!    
!       
     return false;
     }
!  
! #ifdef HAVE_PTHREAD_H  
  if (pthread_mutex_unlock(&MUTEX_HOSTNAME) != 0)
     {
     CfLog(cferror,"pthread_mutex_unlock failed","unlock");
     exit(1);
     }
! #endif 
  
-  
      /* Now let's verify that the ip which gave us this hostname
       * is really an ip for this hostname; or is someone trying to
       * break in? (THIS IS THE CRUCIAL STEP)
--- 1695,1720 ----
     Verbose("     i.e. www.gnu.org, not just www. If you use NIS or 
/etc/hosts\n");
     Verbose("     make sure that the full form is registered too as an 
alias!\n");
  
! #ifdef HAVE_PTHREAD_H
     if (pthread_mutex_unlock(&MUTEX_HOSTNAME) != 0)
        {
        CfLog(cferror,"pthread_mutex_unlock failed","unlock");
        }
! #endif
! 
! 
     return false;
     }
! 
! #ifdef HAVE_PTHREAD_H
  if (pthread_mutex_unlock(&MUTEX_HOSTNAME) != 0)
     {
     CfLog(cferror,"pthread_mutex_unlock failed","unlock");
     exit(1);
     }
! #endif
! 
  
      /* Now let's verify that the ip which gave us this hostname
       * is really an ip for this hostname; or is someone trying to
       * break in? (THIS IS THE CRUCIAL STEP)
***************
*** 1727,1739 ****
         break;                     /* name is good, keep it */
         }
      }
!  
   /* If we did not find it, your DNS is messed up or someone is trying
    * to pull a fast one on you. :(
    */
!  
   /*   Check even the aliases list. Work around for Solaris if dns goes over 
NIS */
!  
   if (!hp->h_addr_list[i])
      {
      for (j=0;hp->h_aliases[j]!=0;j++)
--- 1727,1739 ----
         break;                     /* name is good, keep it */
         }
      }
! 
   /* If we did not find it, your DNS is messed up or someone is trying
    * to pull a fast one on you. :(
    */
! 
   /*   Check even the aliases list. Work around for Solaris if dns goes over 
NIS */
! 
   if (!hp->h_addr_list[i])
      {
      for (j=0;hp->h_aliases[j]!=0;j++)
***************
*** 1744,1751 ****
          }
         }
      }
!  
!  
   if (!hp->h_addr_list[i] && !hp->h_aliases[j])
      {
      sprintf(conn->output,"Reverse hostname lookup failed, host claiming to be 
%s was %s\n",buf,inet_ntoa(raddr.sin_addr));
--- 1744,1751 ----
          }
         }
      }
! 
! 
   if (!hp->h_addr_list[i] && !hp->h_aliases[j])
      {
      sprintf(conn->output,"Reverse hostname lookup failed, host claiming to be 
%s was %s\n",buf,inet_ntoa(raddr.sin_addr));
***************
*** 1769,1777 ****
        Debug("Remote host got %s as username, local=%s\n",rusername,username);
        if (strcmp(ToLowerStr(username),ToLowerStr(rusername)) == 0)
         {
!        Debug("User ID confirmed as %s\n",username); 
         strncpy(conn->username,username,256);
!        return true;   
         }
        else
         {
--- 1769,1777 ----
        Debug("Remote host got %s as username, local=%s\n",rusername,username);
        if (strcmp(ToLowerStr(username),ToLowerStr(rusername)) == 0)
         {
!        Debug("User ID confirmed as %s\n",username);
         strncpy(conn->username,username,256);
!        return true;
         }
        else
         {
***************
*** 1781,1796 ****
         return false;
         }
        }
!    else       
        {
        CfLog(cferror,"RFC931 lookup failed on source host\n","");
        return false;
        }
     }
!  
! Debug("User ID seems to be %s\n",username); 
  strncpy(conn->username,username,256);
! return true;   
  }
  
  /**************************************************************/
--- 1781,1796 ----
         return false;
         }
        }
!    else
        {
        CfLog(cferror,"RFC931 lookup failed on source host\n","");
        return false;
        }
     }
! 
! Debug("User ID seems to be %s\n",username);
  strncpy(conn->username,username,256);
! return true;
  }
  
  /**************************************************************/
***************
*** 1801,1807 ****
  char *sendbuffer;
  
  { char *hostname, *username, *ipaddr;
!   static char *def = "?"; 
  
  if (conn->hostname == NULL)
     {
--- 1801,1807 ----
  char *sendbuffer;
  
  { char *hostname, *username, *ipaddr;
!   static char *def = "?";
  
  if (conn->hostname == NULL)
     {
***************
*** 1829,1835 ****
     {
     ipaddr = conn->ipaddr;
     }
!  
  sprintf(sendbuffer,"%s",CFFAILEDSTR);
  CfLog(cfinform,"Host authentication failed or access denied\n","");
  SendTransaction(conn,sendbuffer);
--- 1829,1835 ----
     {
     ipaddr = conn->ipaddr;
     }
! 
  sprintf(sendbuffer,"%s",CFFAILEDSTR);
  CfLog(cfinform,"Host authentication failed or access denied\n","");
  SendTransaction(conn,sendbuffer);
***************
*** 1863,1869 ****
  #else
  CompressPath(realname,filename); /* in links.c */
  #endif
!   
  Debug("AccessControl(%s,%s) secure=%d\n",realname,conn->hostname,secure);
  
  #if defined HAVE_PTHREAD_H && defined HAVE_LIBPTHREAD
--- 1863,1869 ----
  #else
  CompressPath(realname,filename); /* in links.c */
  #endif
! 
  Debug("AccessControl(%s,%s) secure=%d\n",realname,conn->hostname,secure);
  
  #if defined HAVE_PTHREAD_H && defined HAVE_LIBPTHREAD
***************
*** 1872,1878 ****
        CfLog(cferror,"pthread_mutex_unlock failed","lock");
        }
  #endif
!  
  if (VADMIT == NULL)
     {
     Verbose("cfd: access list is empty, no files are visible\n");
--- 1872,1878 ----
        CfLog(cferror,"pthread_mutex_unlock failed","lock");
        }
  #endif
! 
  if (VADMIT == NULL)
     {
     Verbose("cfd: access list is empty, no files are visible\n");
***************
*** 1880,1886 ****
     }
  
  conn->maproot = false;
!  
  for (ap = VADMIT; ap != NULL; ap=ap->next)
     {
     if (strncmp(ap->path,realname,strlen(ap->path)) == 0)
--- 1880,1886 ----
     }
  
  conn->maproot = false;
! 
  for (ap = VADMIT; ap != NULL; ap=ap->next)
     {
     if (strncmp(ap->path,realname,strlen(ap->path)) == 0)
***************
*** 1890,1896 ****
         Verbose("Warning cannot stat file object %s in 
admit/grant\n",ap->path);
         continue;
         }
!       
        if (!secure && (ap->secure == true))
         {
         Debug("File requires secure connection...will not serve\n");
--- 1890,1896 ----
         Verbose("Warning cannot stat file object %s in 
admit/grant\n",ap->path);
         continue;
         }
! 
        if (!secure && (ap->secure == true))
         {
         Debug("File requires secure connection...will not serve\n");
***************
*** 1946,1954 ****
  if (pthread_mutex_unlock(&MUTEX_COUNT) != 0)
     {
     CfLog(cferror,"pthread_mutex_unlock failed","unlock");
!    }  
  #endif
!  
  return access;
  }
  
--- 1946,1954 ----
  if (pthread_mutex_unlock(&MUTEX_COUNT) != 0)
     {
     CfLog(cferror,"pthread_mutex_unlock failed","unlock");
!    }
  #endif
! 
  return access;
  }
  
***************
*** 1970,1976 ****
    Debug("StatFile(%s)\n",filename);
  
  bzero(&cfst,sizeof(struct cfstat));
!   
  if (strlen(filename) > maxlinksize)
     {
     sprintf(sendbuffer,"BAD: Filename suspiciously long\n");
--- 1970,1976 ----
    Debug("StatFile(%s)\n",filename);
  
  bzero(&cfst,sizeof(struct cfstat));
! 
  if (strlen(filename) > maxlinksize)
     {
     sprintf(sendbuffer,"BAD: Filename suspiciously long\n");
***************
*** 1998,2004 ****
     cfst.cf_type = cf_link;                   /* pointless - overwritten */
     cfst.cf_lmode = statbuf.st_mode & 07777;
     cfst.cf_nlink = statbuf.st_nlink;
!        
     if (readlink(filename,linkbuf,bufsize-1) == -1)
        {
        sprintf(sendbuffer,"BAD: unable to read link\n");
--- 1998,2004 ----
     cfst.cf_type = cf_link;                   /* pointless - overwritten */
     cfst.cf_lmode = statbuf.st_mode & 07777;
     cfst.cf_nlink = statbuf.st_nlink;
! 
     if (readlink(filename,linkbuf,bufsize-1) == -1)
        {
        sprintf(sendbuffer,"BAD: unable to read link\n");
***************
*** 2101,2107 ****
     CfLog(cferror,"Buffer overflow in stat protocol - crack?","");
     ExitCleanly();
     }
!  
  SendTransaction(conn,sendbuffer);
  bzero(sendbuffer,bufsize);
  
--- 2101,2107 ----
     CfLog(cferror,"Buffer overflow in stat protocol - crack?","");
     ExitCleanly();
     }
! 
  SendTransaction(conn,sendbuffer);
  bzero(sendbuffer,bufsize);
  
***************
*** 2151,2157 ****
  stat(filename,&statbuf);
  Debug("CfGetFile(%s on sd=%d), size=%d\n",filename,sd,statbuf.st_size);
  
! size_at_start = statbuf.st_size; 
  
  /* Now check to see if we have remote permission */
  
--- 2151,2157 ----
  stat(filename,&statbuf);
  Debug("CfGetFile(%s on sd=%d), size=%d\n",filename,sd,statbuf.st_size);
  
! size_at_start = statbuf.st_size;
  
  /* Now check to see if we have remote permission */
  
***************
*** 2213,2221 ****
         { int save = statbuf.st_size;
  
         /* This can happen with log files /databases etc */
!        
         stat(filename,&statbuf);
!        
         if (statbuf.st_size != save)
            {
            sprintf(sendbuffer,"BAD:File %s changed while copying",filename);
--- 2213,2221 ----
         { int save = statbuf.st_size;
  
         /* This can happen with log files /databases etc */
! 
         stat(filename,&statbuf);
! 
         if (statbuf.st_size != save)
            {
            sprintf(sendbuffer,"BAD:File %s changed while copying",filename);
***************
*** 2223,2235 ****
               {
               CfLog(cferror,"Send failed in GetFile","send");
               }
!           
            Debug("Aborting transfer after %d: file is changing rapidly at 
source.\n",total);
!           close(fd);     
            break;
            }
         }
!       
        total += n_read;
  
        if (args->secure)
--- 2223,2235 ----
               {
               CfLog(cferror,"Send failed in GetFile","send");
               }
! 
            Debug("Aborting transfer after %d: file is changing rapidly at 
source.\n",total);
!           close(fd);
            break;
            }
         }
! 
        total += n_read;
  
        if (args->secure)
***************
*** 2239,2245 ****
  
         /* Need to pad out to buf_size rather than stop at n_read
            because encryption requires an 8-byte divisible block  */
!        
         if (send(sd,out,args->buf_size,0) == -1)
            {
            close(fd);
--- 2239,2245 ----
  
         /* Need to pad out to buf_size rather than stop at n_read
            because encryption requires an 8-byte divisible block  */
! 
         if (send(sd,out,args->buf_size,0) == -1)
            {
            close(fd);
***************
*** 2259,2265 ****
        }
     }
  
! Debug("Done with GetFile()\n"); 
  }
  
  /**************************************************************/
--- 2259,2265 ----
        }
     }
  
! Debug("Done with GetFile()\n");
  }
  
  /**************************************************************/
***************
*** 2286,2292 ****
     digest[i] = (char) atoi(num);
     sp += strlen((char *)num) + 1;
     }
!  
  Debug("CompareLocalChecksums(%s)\n",cfMDPrint(digest));
  bzero(sendbuffer,bufsize);
  
--- 2286,2292 ----
     digest[i] = (char) atoi(num);
     sp += strlen((char *)num) + 1;
     }
! 
  Debug("CompareLocalChecksums(%s)\n",cfMDPrint(digest));
  bzero(sendbuffer,bufsize);
  
***************
*** 2317,2323 ****
    int offset;
  
  Debug("CfOpenDirectory(%s)\n",dirname);
!   
  if (*dirname != '/')
     {
     sprintf(sendbuffer,"BAD: request to access a non-absolute filename\n");
--- 2317,2323 ----
    int offset;
  
  Debug("CfOpenDirectory(%s)\n",dirname);
! 
  if (*dirname != '/')
     {
     sprintf(sendbuffer,"BAD: request to access a non-absolute filename\n");
***************
*** 2418,2432 ****
      }
  
   /* Identify ourselves with this address */
!  
   bind(sd,(struct sockaddr *)laddr,sizeof(laddr));
  
   setsockopt(sd,SOL_SOCKET,SO_REUSEADDR,(char *)&yes,sizeof(int));
!  
   saddr.sin_family = AF_INET;
   saddr.sin_port = htons(RFC931_PORT);
   saddr.sin_addr.s_addr = raddr->s_addr;
!  
   if (connect(sd,(struct sockaddr *)&saddr,sizeof(saddr)) == -1)
      {
      CfLog(cferror,"Couldn't connect to verify RFC931\n","connect");
--- 2418,2432 ----
      }
  
   /* Identify ourselves with this address */
! 
   bind(sd,(struct sockaddr *)laddr,sizeof(laddr));
  
   setsockopt(sd,SOL_SOCKET,SO_REUSEADDR,(char *)&yes,sizeof(int));
! 
   saddr.sin_family = AF_INET;
   saddr.sin_port = htons(RFC931_PORT);
   saddr.sin_addr.s_addr = raddr->s_addr;
! 
   if (connect(sd,(struct sockaddr *)&saddr,sizeof(saddr)) == -1)
      {
      CfLog(cferror,"Couldn't connect to verify RFC931\n","connect");
***************
*** 2451,2457 ****
      close(sd);
      return false;
      }
!  
  close(sd);
  
  Debug("AUTH server returned %s\n",recvbuffer);
--- 2451,2457 ----
      close(sd);
      return false;
      }
! 
  close(sd);
  
  Debug("AUTH server returned %s\n",recvbuffer);
***************
*** 2469,2489 ****
     }
  
  sp++;
!  
  while (*sp != ':')
     {
     sp++;
!    } 
  
  sp++;
  
  sendbuffer[0] = '\0';
  username[0] = '\0';
! Debug("Checking %s\n",sp); 
  sscanf(sp,"%255s %*[:] %255s",sendbuffer,username);
  
  Debug("Operating system type of remote host was %s and user was 
%s\n",sendbuffer,username);
! return true; 
  }
  
  
--- 2469,2489 ----
     }
  
  sp++;
! 
  while (*sp != ':')
     {
     sp++;
!    }
  
  sp++;
  
  sendbuffer[0] = '\0';
  username[0] = '\0';
! Debug("Checking %s\n",sp);
  sscanf(sp,"%255s %*[:] %255s",sendbuffer,username);
  
  Debug("Operating system type of remote host was %s and user was 
%s\n",sendbuffer,username);
! return true;
  }
  
  
***************
*** 2520,2531 ****
     CfLog(cferror,"Unable to allocate conn","malloc");
     ExitCleanly();
     }
!  
  conn->sd_reply = sd;
  conn->id_verified = false;
! conn->hostname[0] = '\0'; 
  Debug("***New socket %d\n",sd);
!  
  return conn;
  }
  
--- 2520,2531 ----
     CfLog(cferror,"Unable to allocate conn","malloc");
     ExitCleanly();
     }
! 
  conn->sd_reply = sd;
  conn->id_verified = false;
! conn->hostname[0] = '\0';
  Debug("***New socket %d\n",sd);
! 
  return conn;
  }
  
***************
*** 2537,2544 ****
  
  {
  Debug("***Closing socket %d from %s\n",conn->sd_reply,conn->ipaddr);
!  
! DeleteItemStarting(&CONNECTIONLIST,conn->ipaddr); 
  
  close(conn->sd_reply);
  free ((char *)conn);
--- 2537,2544 ----
  
  {
  Debug("***Closing socket %d from %s\n",conn->sd_reply,conn->ipaddr);
! 
! DeleteItemStarting(&CONNECTIONLIST,conn->ipaddr);
  
  close(conn->sd_reply);
  free ((char *)conn);
***************
*** 2577,2616 ****
  int seconds;
  
  {
! sprintf(OUTPUT,"Setting autorun time to %d seconds\n",seconds); 
! CfLog(cfinform,OUTPUT,""); 
  next_auto = (seconds) + time((time_t *) NULL);
  }
!  
  /***************************************************************/
  /* ERS                                                         */
  /***************************************************************/
  
  int cfscanf(in,len1,len2,out1,out2,out3)
!    
  char *in,*out1,*out2,*out3;
  int len1, len2;
!    
! {  
  int len3=0;
  char *sp;
!    
!    
  sp = in;
  bcopy(sp,out1,len1);
  out1[len1]='\0';
!    
  sp += len1 + 1;
  bcopy(sp,out2,len2);
!    
  sp += len2 + 1;
  len3=strlen(sp);
  bcopy(sp,out3,len3);
  out3[len3]='\0';
!    
  return (len1 + len2 + len3 + 2);
! }  
!    
  
  /* EOF */
  
--- 2577,2616 ----
  int seconds;
  
  {
! sprintf(OUTPUT,"Setting autorun time to %d seconds\n",seconds);
! CfLog(cfinform,OUTPUT,"");
  next_auto = (seconds) + time((time_t *) NULL);
  }
! 
  /***************************************************************/
  /* ERS                                                         */
  /***************************************************************/
  
  int cfscanf(in,len1,len2,out1,out2,out3)
! 
  char *in,*out1,*out2,*out3;
  int len1, len2;
! 
! {
  int len3=0;
  char *sp;
! 
! 
  sp = in;
  bcopy(sp,out1,len1);
  out1[len1]='\0';
! 
  sp += len1 + 1;
  bcopy(sp,out2,len2);
! 
  sp += len2 + 1;
  len3=strlen(sp);
  bcopy(sp,out3,len3);
  out3[len3]='\0';
! 
  return (len1 + len2 + len3 + 2);
! }
! 
  
  /* EOF */
  
Index: cfengine/src/modes.c
diff -c cfengine/src/modes.c:1.1.1.1 cfengine/src/modes.c:1.2
*** cfengine/src/modes.c:1.1.1.1        Tue Jul  3 13:21:54 2001
--- cfengine/src/modes.c        Mon Jul 16 13:56:48 2001
***************
*** 1,28 ****
  /* cfengine for GNU
!  
          Copyright (C) 1995
          Free Software Foundation, Inc.
!  
!    This file is part of GNU cfengine - written and maintained 
     by Mark Burgess, Dept of Computing and Engineering, Oslo College,
     Dept. of Theoretical physics, University of Oslo
!  
     This program is free software; you can redistribute it and/or modify it
     under the terms of the GNU General Public License as published by the
     Free Software Foundation; either version 2, or (at your option) any
     later version.
!  
     This program is distributed in the hope that it will be useful,
     but WITHOUT ANY WARRANTY; without even the implied warranty of
     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     GNU General Public License for more details.
!  
    You should have received a copy of the GNU General Public License
    along with this program; if not, write to the Free Software
    Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA
  
  */
!  
  
  #include "cf.defs.h"
  #include "cf.extern.h"
--- 1,28 ----
  /* cfengine for GNU
! 
          Copyright (C) 1995
          Free Software Foundation, Inc.
! 
!    This file is part of GNU cfengine - written and maintained
     by Mark Burgess, Dept of Computing and Engineering, Oslo College,
     Dept. of Theoretical physics, University of Oslo
! 
     This program is free software; you can redistribute it and/or modify it
     under the terms of the GNU General Public License as published by the
     Free Software Foundation; either version 2, or (at your option) any
     later version.
! 
     This program is distributed in the hope that it will be useful,
     but WITHOUT ANY WARRANTY; without even the implied warranty of
     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     GNU General Public License for more details.
! 
    You should have received a copy of the GNU General Public License
    along with this program; if not, write to the Free Software
    Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA
  
  */
! 
  
  #include "cf.defs.h"
  #include "cf.extern.h"
***************
*** 37,46 ****
  char *modestring;
  mode_t *plusmask, *minusmask;
  
! { char modebuffer[maxvarsize], *sp; 
!  int affected = 0, value = 0, gotaction;
!   char action = '=';
!   enum modestate state = who;
  
  if (modestring == NULL)
     {
--- 37,49 ----
  char *modestring;
  mode_t *plusmask, *minusmask;
  
! { char modebuffer[maxvarsize], *sp;
!  int affected = 0, value = 0, gotaction, gotwho;
!  char action = '=';
!  enum modestate state = who;
!  enum modesort found_sort = unkown; /* Already found "sort" of mode */
!  enum modesort sort = unkown; /* Sort of started but not yet finished mode */
! 
  
  if (modestring == NULL)
     {
***************
*** 49,75 ****
  
  Debug1("ParseModeString(%s)\n",modestring);
  
! gotaction = false;
  *plusmask = *minusmask = 0;
  
  for (sp = modestring; true ; *sp++)
     {
     switch (*sp)
        {
!       case 'a': CheckModeState(who,state,*sp);
                  affected |= 07777;
                  break;
  
!       case 'u': CheckModeState(who,state,*sp);
                  affected |= 04700;
                  break;
  
!       case 'g': CheckModeState(who,state,*sp);
                  affected |= 02070;
                  break;
  
!       case 'o': CheckModeState(who,state,*sp);
                  affected |= 00007;
                  break;
  
        case '+':
--- 52,86 ----
  
  Debug1("ParseModeString(%s)\n",modestring);
  
! gotaction = gotwho = false;
  *plusmask = *minusmask = 0;
  
  for (sp = modestring; true ; *sp++)
     {
     switch (*sp)
        {
!       case 'a': CheckModeState(who,state,symbolic,sort,*sp);
                  affected |= 07777;
+               sort = symbolic;
+               gotwho = true;
                  break;
  
!       case 'u': CheckModeState(who,state,symbolic,sort,*sp);
                  affected |= 04700;
+               sort = symbolic;
+               gotwho = true;
                  break;
  
!       case 'g': CheckModeState(who,state,symbolic,sort,*sp);
                  affected |= 02070;
+               sort = symbolic;
+               gotwho = true;
                  break;
  
!       case 'o': CheckModeState(who,state,symbolic,sort,*sp);
                  affected |= 00007;
+               sort = symbolic;
+               gotwho = true;
                  break;
  
        case '+':
***************
*** 78,106 ****
                     {
                     yyerror("Too many +-= in mode string");
                     }
                  action = *sp;
                  state = which;
                  gotaction = true;
                  break;
  
!       case 'r': CheckModeState(which,state,*sp);
                  value |= 0444 & affected;
                  break;
  
!       case 'w': CheckModeState(which,state,*sp);
                  value |= 0222 & affected;
                  break;
  
!       case 'x': CheckModeState(which,state,*sp);
                  value |= 0111 & affected;
                  break;
  
!       case 's': CheckModeState(which,state,*sp);
                  value |= 06000 & affected;
                  break;
  
!       case 't': CheckModeState(which,state,*sp);
                  value |= 01000;
                  break;
  
        case '0':
--- 89,130 ----
                     {
                     yyerror("Too many +-= in mode string");
                     }
+ 
+                       if (!gotwho)
+                 {
+                   yyerror("No 'who (ugoa)'-expression before 'action 
(+-=)'-expression found");
+                 }
+ 
+                       CheckModeState(who,state,symbolic,sort,*sp);
                  action = *sp;
                  state = which;
                  gotaction = true;
+               sort = symbolic;
                  break;
  
!       case 'r': CheckModeState(which,state,symbolic,sort,*sp);
                  value |= 0444 & affected;
+               sort = symbolic;
                  break;
  
!       case 'w': CheckModeState(which,state,symbolic,sort,*sp);
                  value |= 0222 & affected;
+               sort = symbolic;
                  break;
  
!       case 'x': CheckModeState(which,state,symbolic,sort,*sp);
                  value |= 0111 & affected;
+               sort = symbolic;
                  break;
  
!       case 's': CheckModeState(which,state,symbolic,sort,*sp);
                  value |= 06000 & affected;
+               sort = symbolic;
                  break;
  
!       case 't': CheckModeState(which,state,symbolic,sort,*sp);
                  value |= 01000;
+               sort = symbolic;
                  break;
  
        case '0':
***************
*** 110,117 ****
        case '4':
        case '5':
        case '6':
!       case '7': state = which;
                  sscanf(sp,"%o",&value);
                  while (isdigit(*sp) && (*sp != '\0'))
                   {
                     sp++;
--- 134,153 ----
        case '4':
        case '5':
        case '6':
!       case '7': CheckModeState(who,state,numeric,sort,*sp);
!               sort = numeric;
!               gotaction = true;
!               state = which;
!               affected = 07777; /* TODO: Hard-coded; see below */
                  sscanf(sp,"%o",&value);
+               if (value > 07777) /* TODO: Hardcoded !
+                                     Is this correct for all sorts of Unix ?
+                                     What about NT ?
+                                     Any (POSIX)-constants ??
+                                  */
+                    {
+                  yyerror("Mode-Value too big !\n");
+                    }
                  while (isdigit(*sp) && (*sp != '\0'))
                   {
                     sp++;
***************
*** 120,130 ****
                  break;
  
        case ',':
!                 SetMask(action,value,plusmask,minusmask);
                  action = '=';
                  affected = 0;
                  value = 0;
                  gotaction = false;
                  state = who;
                  break;
  
--- 156,173 ----
                  break;
  
        case ',':
!                 SetMask(action,value,affected,plusmask,minusmask);
!               if (found_sort != unkown && found_sort != sort)
!                 {
!                   Warning("Symbolic and numeric form for modes mixed");
!                 }
!               found_sort = sort;
!               sort = unkown;
                  action = '=';
                  affected = 0;
                  value = 0;
                  gotaction = false;
+               gotwho = false;
                  state = who;
                  break;
  
***************
*** 137,143 ****
                           }
                     }
  
!                 SetMask(action,value,plusmask,minusmask);
                  Debug1("[PLUS=%o][MINUS=%o]\n",*plusmask,*minusmask);
                  return;
  
--- 180,190 ----
                           }
                     }
  
!                 SetMask(action,value,affected,plusmask,minusmask);
!               if (found_sort != unkown && found_sort != sort)
!                 {
!                   Warning("Symbolic and numeric form for modes mixed");
!                 }
                  Debug1("[PLUS=%o][MINUS=%o]\n",*plusmask,*minusmask);
                  return;
  
***************
*** 149,158 ****
  
  /*********************************************************/
  
! void CheckModeState(stateA,stateB,ch)
  
  enum modestate stateA;
  int stateB;
  char ch;
  
  {
--- 196,206 ----
  
  /*********************************************************/
  
! void CheckModeState(stateA,stateB,sortA,sortB,ch)
  
  enum modestate stateA;
  int stateB;
+ enum modesort sortA, sortB;
  char ch;
  
  {
***************
*** 161,179 ****
     sprintf(VBUFF,"Mode string constant (%c) used out of context",ch);
     yyerror(VBUFF);
     }
  return;
  }
  
  /*********************************************************/
  
! void SetMask(action,value,p,m)
  
  char action;
! int value;
  mode_t *p,*m;
  
  {
! Debug1("SetMask(%c%o)\n",action,value);
  
  switch(action)
     {
--- 209,232 ----
     sprintf(VBUFF,"Mode string constant (%c) used out of context",ch);
     yyerror(VBUFF);
     }
+ 
+ if ((sortA != unkown) && (sortB != unkown) && (sortA != sortB))
+    {
+    yyerror("Symbolic and numeric filemodes mixed within expression");
+    }
  return;
  }
  
  /*********************************************************/
  
! void SetMask(action,value,affected,p,m)
  
  char action;
! int value, affected;
  mode_t *p,*m;
  
  {
! Debug1("SetMask(%c%o,%o)\n",action,value,affected);
  
  switch(action)
     {
***************
*** 187,193 ****
               return;
     case '=':
               *p |= value;
!              *m |= (~value) & 07777;
               return;
     default:
               sprintf(VBUFF,"Mode directive %c is unknown",action);
--- 240,246 ----
               return;
     case '=':
               *p |= value;
!              *m |= ((~value) & 07777 & affected);
               return;
     default:
               sprintf(VBUFF,"Mode directive %c is unknown",action);
Index: cfengine/src/prototypes.h
diff -c cfengine/src/prototypes.h:1.1.1.1 cfengine/src/prototypes.h:1.2
*** cfengine/src/prototypes.h:1.1.1.1   Tue Jul  3 13:21:55 2001
--- cfengine/src/prototypes.h   Mon Jul 16 13:57:04 2001
***************
*** 1,26 ****
  /* cfengine for GNU
!  
          Copyright (C) 1995
          Free Software Foundation, Inc.
!  
!    This file is part of GNU cfengine - written and maintained 
     by Mark Burgess, Dept of Computing and Engineering, Oslo College,
     Dept. of Theoretical physics, University of Oslo
!  
     This program is free software; you can redistribute it and/or modify it
     under the terms of the GNU General Public License as published by the
     Free Software Foundation; either version 2, or (at your option) any
     later version.
!  
     This program is distributed in the hope that it will be useful,
     but WITHOUT ANY WARRANTY; without even the implied warranty of
     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     GNU General Public License for more details.
!  
     You should have received a copy of the GNU General Public License
     along with this program; if not, write to the Free Software
     Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
!  
  
  /*******************************************************************/
  /*                                                                 */
--- 1,26 ----
  /* cfengine for GNU
! 
          Copyright (C) 1995
          Free Software Foundation, Inc.
! 
!    This file is part of GNU cfengine - written and maintained
     by Mark Burgess, Dept of Computing and Engineering, Oslo College,
     Dept. of Theoretical physics, University of Oslo
! 
     This program is free software; you can redistribute it and/or modify it
     under the terms of the GNU General Public License as published by the
     Free Software Foundation; either version 2, or (at your option) any
     later version.
! 
     This program is distributed in the hope that it will be useful,
     but WITHOUT ANY WARRANTY; without even the implied warranty of
     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     GNU General Public License for more details.
! 
     You should have received a copy of the GNU General Public License
     along with this program; if not, write to the Free Software
     Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
! 
  
  /*******************************************************************/
  /*                                                                 */
***************
*** 90,104 ****
  
  int CheckPosixACE ARGLIST((struct CFACE *aces, char method, char *filename, 
enum fileactions action));
  
! /* cfd.c 
  
!   Function prototypes for cfd.c are in cfd.c itself, 
    since they are not called from elsewhere.
  */
  
  /* cfengine.c
  
!   Function prototypes for cfengine.c are in cfengine.c itself, 
    since they are not called from elsewhere.
  */
  
--- 90,104 ----
  
  int CheckPosixACE ARGLIST((struct CFACE *aces, char method, char *filename, 
enum fileactions action));
  
! /* cfd.c
  
!   Function prototypes for cfd.c are in cfd.c itself,
    since they are not called from elsewhere.
  */
  
  /* cfengine.c
  
!   Function prototypes for cfengine.c are in cfengine.c itself,
    since they are not called from elsewhere.
  */
  
***************
*** 113,119 ****
  
  /* cfrun.c
  
!   Function prototypes for cfrun.c are in cfrun.c itself, 
    since they are not called from elsewhere.
  */
  
--- 113,119 ----
  
  /* cfrun.c
  
!   Function prototypes for cfrun.c are in cfrun.c itself,
    since they are not called from elsewhere.
  */
  
***************
*** 564,571 ****
  /* modes.c */
  
  void ParseModeString ARGLIST((char *modestring, mode_t *plusmask, mode_t 
*minusmask));
! void CheckModeState ARGLIST((enum modestate stateA, int stateB, char ch));
! void SetMask ARGLIST((char action, int value, mode_t *p, mode_t *m));
  
  /* mount.c */
  
--- 564,572 ----
  /* modes.c */
  
  void ParseModeString ARGLIST((char *modestring, mode_t *plusmask, mode_t 
*minusmask));
! void CheckModeState ARGLIST((enum modestate stateA, int stateB, \
!                            enum modesort modeA, enum modesort modeB, char 
ch));
! void SetMask ARGLIST((char action, int value, int affected, mode_t *p, mode_t 
*m));
  
  /* mount.c */
  
RCS file: /home/pd/cvs/cfengine/src/cf.defs.h,v
Working file: src/cf.defs.h
head: 1.2
branch:
locks: strict
access list:
symbolic names:
        cfengine1_6_3_p1: 1.2
        cfengine1_6_3: 1.1.1.1
        GNU: 1.1.1
keyword substitution: kv
total revisions: 3;     selected revisions: 3
description:
----------------------------
revision 1.2
date: 2001/07/14 16:54:44;  author: pd;  state: Exp;  lines: +30 -23
"enum modesort" added; records type (numerical or symbolic) for mode-Strings
----------------------------


RCS file: /home/pd/cvs/cfengine/src/modes.c,v
Working file: src/modes.c
head: 1.2
branch:
locks: strict
access list:
symbolic names:
        cfengine1_6_3_p1: 1.2
        cfengine1_6_3: 1.1.1.1
        GNU: 1.1.1
keyword substitution: kv
total revisions: 3;     selected revisions: 3
description:
----------------------------
revision 1.2
date: 2001/07/14 17:37:48;  author: pd;  state: Exp;  lines: +82 -29
Fixed problems:
(Remark: It seems that the 2.x-release contains the same problems)
Symbolic Mode with more than one '=' got wrong results
("u=rwx,og=rx" would wipe out all permission-bits, see below)

A bunch of pathologic (or outright illegal) cases didn't raise an
error or warning.
E.g.:
Mixing symbolic and numerical mode within an expression (error)
[u=755]
Mixing symbolic and numerical mode (warning, but handled correctly by
interpretation from left to right)
[u=rw,755]
Symbolic expresssions without a 'who'-part (error)
[mode=u=rwx,=rw]
Too big numerical values (error)
[mode=777777]

Variables added:
- gotwho
  becomes 'true', whenever a "who"-part seen, reset on ',';
  if 'gotwho' is _not_ set when one of '+-=' is found, this is an error.
- sort
  sort (numerical or symbolic) of mode which is just processed
  Used to trigger an error in CheckModeState() when both sorts are mixed up
- found_sort
  sort (numerical or symbolic); set whenever ',' is found
  used to trigger a warning when both sorts a used in combination

CheckModeState() now takes two additional arguments auf Type "enum mode sort"
An error is raised if both are != 'unkown' and _not_ equal
("Symbolic and numeric filemodes mixed within expression")
Called in addition after one of '+-=' have been found.

SetMask() takes an additional argument 'affected' carrying a bit-mask
of the affected bits.
This is needed to get the '='-case right. Only the _not_ affected bits
may be added to 'minus' (*m).
Without this wrong bits are cleared.
E.g. 'mode=u=rwx,go=rw' will wipe out all (!) bits.
("----------")
[u=rwx would give (only looking at the lower 9 bits)
'value=700' thus ~value=077;
go=rw would give 'value=055' thus ~value=722;
Both '~value's ored together would yield '777' for minus -> all bits
dead]



RCS file: /home/pd/cvs/cfengine/src/prototypes.h,v
Working file: src/prototypes.h
head: 1.2
branch:
locks: strict
access list:
symbolic names:
        cfengine1_6_3_p1: 1.2
        cfengine1_6_3: 1.1.1.1
        GNU: 1.1.1
keyword substitution: kv
total revisions: 3;     selected revisions: 3
description:
----------------------------
revision 1.2
date: 2001/07/14 16:56:09;  author: pd;  state: Exp;  lines: +14 -13
Prototype for CheckModeState() and SetMask() changed
(see modes.c)
----------------------------
revision 1.1
date: 2001/07/14 12:33:27;  author: pd;  state: Exp;
branches:  1.1.1;
Initial revision
----------------------------
revision 1.1.1.1
date: 2001/07/14 12:33:27;  author: pd;  state: Exp;  lines: +0 -0
cfengine 1.6.3
=============================================================================


reply via email to

[Prev in Thread] Current Thread [Next in Thread]