~ubuntu-branches/ubuntu/breezy/cvsd/breezy

« back to all changes in this revision

Viewing changes to cvsd.c

  • Committer: Bazaar Package Importer
  • Author(s): Arthur de Jong
  • Date: 2005-04-26 22:00:00 UTC
  • mfrom: (1.1.1 hoary)
  • Revision ID: james.westby@ubuntu.com-20050426220000-4jv1ah3wzkr0s2bf
Tags: 1.0.7
* improvements to the README
* fix bug in cvsd-buildroot correctly creating lib64 directory

Show diffs side-by-side

added added

removed removed

Lines of Context:
14
14
 
15
15
   Copyright (C) 1999 Chris Black.
16
16
   Copyright (C) 2000 Philippe Kehl.
17
 
   Copyright (C) 2001, 2002, 2003, 2004 Arthur de Jong.
 
17
   Copyright (C) 2001, 2002, 2003, 2004, 2005 Arthur de Jong.
18
18
 
19
19
   This program is free software; you can redistribute it and/or modify
20
20
   it under the terms of the GNU General Public License as published by
75
75
#ifdef HAVE_GRP_H
76
76
#include <grp.h>
77
77
#endif /* HAVE_GRP_H */
 
78
#ifdef USE_CAPABILITIES
 
79
#include <sys/capability.h>
 
80
#include <sys/prctl.h>
 
81
#endif /* USE_CAPABILITIES */
78
82
 
79
83
#include "xmalloc.h"
80
84
#ifdef HAVE_SETRLIMIT
89
93
extern char **environ;
90
94
 
91
95
 
92
 
/* the name by which this program was run. */
93
 
static char *program_name;
94
 
 
95
 
 
96
96
/* the number of children spawned */
97
97
static volatile int cvsd_numchildren=0;
98
98
 
123
123
{
124
124
  fprintf(fp,"%s\n",PACKAGE_STRING);
125
125
  fprintf(fp,"Written by Chris Black, Philippe Kehl and Arthur de Jong.\n\n");
126
 
  fprintf(fp,"Copyright (C) 1999,2000,2004 Chris Black, Philippe Kehl and Arthur de Jong.\n"
 
126
  fprintf(fp,"Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005 Chris Black,\n"
 
127
             "Philippe Kehl and Arthur de Jong.\n"
127
128
             "This is free software; see the source for copying conditions.  There is NO\n"
128
129
             "warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n");
129
130
}
130
131
 
131
132
 
132
133
/* display usage information to stdout and exit(status) */
133
 
static void display_usage(FILE *fp)
 
134
static void display_usage(FILE *fp, char *program_name)
134
135
{
135
136
  fprintf(fp,"Usage: %s [OPTION]...\n",program_name);
136
137
  fprintf(fp,"chroot wrapper to run `cvs pserver' more securely.\n");
167
168
      if (optarg[0]!='/')
168
169
      {
169
170
        fprintf(stderr,"%s: configfile '%s' must be an absolute path\n",
170
 
                program_name,optarg);
 
171
                argv[0],optarg);
171
172
        exit(1);
172
173
      }
173
174
      cfg->configfile=xstrdup(optarg);
177
178
      log_setdefaultloglevel(LOG_DEBUG);
178
179
      break;
179
180
    case 'h': /*     --help         display this help and exit */
180
 
      display_usage(stdout);
 
181
      display_usage(stdout,argv[0]);
181
182
      exit(0);
182
183
    case 'V': /*     --version      output version information and exit */
183
184
      display_version(stdout);
186
187
    case '?': /* unknown option character or extraneous parameter */
187
188
    default:
188
189
      fprintf(stderr,"Try `%s --help' for more information.\n",
189
 
              program_name);
 
190
              argv[0]);
190
191
      exit(1);
191
192
    }
192
193
  }
194
195
  if (optind<argc)
195
196
  {
196
197
    fprintf(stderr,"%s: unrecognized option `%s'\n",
197
 
            program_name,argv[optind]);
 
198
            argv[0],argv[optind]);
198
199
    fprintf(stderr,"Try `%s --help' for more information.\n",
199
 
            program_name);
 
200
            argv[0]);
200
201
    exit(1);
201
202
  }
202
203
}
663
664
  char *cvs_cmdline=NULL;
664
665
  struct cvsd_addrs *tmp,*nxt;
665
666
  struct cvsd_cfg *cfg;
 
667
#ifdef USE_CAPABILITIES
 
668
  cap_t caps;
 
669
#endif /* USE_CAPABILITIES */
666
670
 
667
 
  /* save program name */
668
 
  program_name=argv[0];
669
 
  
670
671
  /* load the default configuration */
671
672
  cfg=cfg_new();
672
673
 
709
710
    log_log(LOG_ERR,"fatal error saving umask in environment (probably a bug)");
710
711
    exit(1);
711
712
  }
712
 
  log_log(LOG_DEBUG,"debug: cvsenv[CVSUMASK_IDX]: %s",cfg->cvsenv[CVSUMASK_IDX]);
 
713
 
 
714
  /* dump environment */
 
715
  for (i=0;cfg->cvsenv[i]!=NULL;i++)
 
716
    log_log(LOG_DEBUG,"debug: cvsenv[%d]: %s",i,cfg->cvsenv[i]);
713
717
 
714
718
  /* default address */
715
719
  if (cfg->addresses==NULL)
795
799
  log_log(LOG_DEBUG,"debug: setgroups() not available");
796
800
#endif /* not HAVE_SETGROUPS */
797
801
 
 
802
#ifdef USE_CAPABILITIES
 
803
  /* if there are any capabilities defined, set them to be kept
 
804
     across setuid() calls so we can limit them later on */
 
805
  if (cfg->capabilities!=NULL)
 
806
  {
 
807
    if (prctl(PR_SET_KEEPCAPS,1))
 
808
    {
 
809
      log_log(LOG_ERR,"cannot prctl(PR_SET_KEEPCAPS,1): %s",strerror(errno));
 
810
      exit(1);
 
811
    }
 
812
    log_log(LOG_DEBUG,"debug: prctl(PR_SET_KEEPCAPS,1) done");
 
813
    /* dump the current capabilities */
 
814
    caps=cap_get_proc();
 
815
    log_log(LOG_DEBUG,"debug: current capabilities: %s",cap_to_text(caps,NULL));
 
816
    cap_free(caps);
 
817
  }
 
818
#endif /* USE_CAPABILITIES */
 
819
 
798
820
  /* change to cvs gid */
799
821
  if (cfg->gid!=NOGID)
800
822
  {
817
839
    log_log(LOG_DEBUG,"debug: setuid(%d) done",cfg->uid);
818
840
  }
819
841
 
 
842
#ifdef USE_CAPABILITIES
 
843
  /* if there are any capabilities defined, limit them now */
 
844
  if (cfg->capabilities!=NULL)
 
845
  {
 
846
    /* dump the current capabilities */
 
847
    caps=cap_get_proc();
 
848
    log_log(LOG_DEBUG,"debug: current capabilities: %s",cap_to_text(caps,NULL));
 
849
    cap_free(caps);
 
850
    /* limit the capabilities */
 
851
    if (cap_set_proc(cfg->capabilities)!=0)
 
852
    {
 
853
      log_log(LOG_ERR,"cannot cap_set_proc(%s): %s",cap_to_text(cfg->capabilities,NULL),strerror(errno));
 
854
      exit(1);
 
855
    }
 
856
    log_log(LOG_DEBUG,"debug: cap_set_proc(%2) done",cap_to_text(cfg->capabilities,NULL));
 
857
    /* we no longer need this so we should free it */
 
858
    cap_free(cfg->capabilities);
 
859
    /* dump the current capabilities */
 
860
    caps=cap_get_proc();
 
861
    log_log(LOG_DEBUG,"debug: current capabilities: %s",cap_to_text(caps,NULL));
 
862
    cap_free(caps);
 
863
  }
 
864
#endif /* USE_CAPABILITIES */
 
865
 
820
866
  /* build cvs command line */
821
867
  j=strlen(cfg->cvscmd)+1;
822
868
  for (i=1;cfg->cvsargs[i]!=NULL;i++)
857
903
      /* wait for a new connection */
858
904
      acceptconnection(cfg);
859
905
      /* handle exiting child processes */
860
 
      reap_deadchildren();    
 
906
      reap_deadchildren();
861
907
    }
862
908
    else /* not ready for connection */
863
909
    {
869
915
        /* sleep unblocks on a signal */
870
916
        sleep(SLEEPSECS);
871
917
        /* handle exiting child processes */
872
 
        reap_deadchildren();    
 
918
        reap_deadchildren();
873
919
      }
874
920
      /* log that the connections are full */
875
921
      log_log(LOG_INFO,"resuming accepting new connections");