From: ianmdlvl Date: Wed, 2 Jul 2003 18:20:29 +0000 (+0000) Subject: stuff from chiark:/usr/local/src/misc/ (as found) X-Git-Tag: debian_version_3_99_1_0_4~9 X-Git-Url: http://www.chiark.greenend.org.uk/ucgi/~ian/git?p=chiark-utils.git;a=commitdiff_plain;h=c314690b25b449e079fce8b215a3e96924898578;ds=sidebyside stuff from chiark:/usr/local/src/misc/ (as found) --- diff --git a/cprogs/myopt.c b/cprogs/myopt.c new file mode 100644 index 0000000..ab89df8 --- /dev/null +++ b/cprogs/myopt.c @@ -0,0 +1,96 @@ +/* + * libdpkg - Debian packaging suite library routines + * myopt.c - my very own option parsing + * + * Copyright (C) 1994,1995 Ian Jackson + * + * This 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 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 file; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include +#include +#include +#include + +#include "myopt.h" + +void badusage(const char *fmt, ...) { + va_list al; + + va_start(al,fmt); + vfprintf(stderr,fmt,al); + va_end(al); + fputc('\n',stderr); + usagemessage(); + exit(-1); +} + +void myopt(const char *const **argvp, const struct cmdinfo *cmdinfos) { + const struct cmdinfo *cip; + const char *p, *value; + int l; + + ++(*argvp); + while ((p= **argvp) && *p == '-') { + ++(*argvp); + if (!strcmp(p,"--")) break; + if (*++p == '-') { + ++p; value=0; + for (cip= cmdinfos; + cip->olong || cip->oshort; + cip++) { + if (!cip->olong) continue; + if (!strcmp(p,cip->olong)) break; + l= strlen(cip->olong); + if (!strncmp(p,cip->olong,l) && + (p[l]== ((cip->takesvalue==2) ? '-' : '='))) { value=p+l+1; break; } + } + if (!cip->olong) badusage("unknown option --%s",p); + if (cip->takesvalue) { + if (!value) { + value= *(*argvp)++; + if (!value) badusage("--%s option takes a value",cip->olong); + } + if (cip->call) cip->call(cip,value); + else *cip->sassignto= value; + } else { + if (value) badusage("--%s option does not take a value",cip->olong); + if (cip->call) cip->call(cip,0); + else *cip->iassignto= cip->arg; + } + } else { + while (*p) { + for (cip= cmdinfos; (cip->olong || cip->oshort) && *p != cip->oshort; cip++); + if (!cip->oshort) badusage("unknown option -%c",*p); + p++; + if (cip->takesvalue) { + if (!*p) { + value= *(*argvp)++; + if (!value) badusage("-%c option takes a value",cip->oshort); + } else { + value= p; p=""; + if (*value == '=') value++; + } + if (cip->call) cip->call(cip,value); + else *cip->sassignto= value; + } else { + if (*p == '=') badusage("-%c option does not take a value",cip->oshort); + if (cip->call) cip->call(cip,0); + else *cip->iassignto= cip->arg; + } + } + } + } +} diff --git a/cprogs/myopt.c~ b/cprogs/myopt.c~ new file mode 100644 index 0000000..b3c2167 --- /dev/null +++ b/cprogs/myopt.c~ @@ -0,0 +1,84 @@ +/* + * libdpkg - Debian packaging suite library routines + * myopt.c - my very own option parsing + * + * Copyright (C) 1994,1995 Ian Jackson + * + * This 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 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 file; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include + +#include "config.h" +#include "myopt.h" +#include "dpkg.h" + +void myopt(const char *const **argvp, const struct cmdinfo *cmdinfos) { + const struct cmdinfo *cip; + const char *p, *value; + int l; + + ++(*argvp); + while ((p= **argvp) && *p == '-') { + ++(*argvp); + if (!strcmp(p,"--")) break; + if (*++p == '-') { + ++p; value=0; + for (cip= cmdinfos; + cip->olong || cip->oshort; + cip++) { + if (!cip->olong) continue; + if (!strcmp(p,cip->olong)) break; + l= strlen(cip->olong); + if (!strncmp(p,cip->olong,l) && + (p[l]== ((cip->takesvalue==2) ? '-' : '='))) { value=p+l+1; break; } + } + if (!cip->olong) badusage("unknown option --%s",p); + if (cip->takesvalue) { + if (!value) { + value= *(*argvp)++; + if (!value) badusage("--%s option takes a value",cip->olong); + } + if (cip->call) cip->call(cip,value); + else *cip->sassignto= value; + } else { + if (value) badusage("--%s option does not take a value",cip->olong); + if (cip->call) cip->call(cip,0); + else *cip->iassignto= cip->arg; + } + } else { + while (*p) { + for (cip= cmdinfos; (cip->olong || cip->oshort) && *p != cip->oshort; cip++); + if (!cip->oshort) badusage("unknown option -%c",*p); + p++; + if (cip->takesvalue) { + if (!*p) { + value= *(*argvp)++; + if (!value) badusage("-%c option takes a value",cip->oshort); + } else { + value= p; p=""; + if (*value == '=') value++; + } + if (cip->call) cip->call(cip,value); + else *cip->sassignto= value; + } else { + if (*p == '=') badusage("-%c option does not take a value",cip->oshort); + if (cip->call) cip->call(cip,0); + else *cip->iassignto= cip->arg; + } + } + } + } +} diff --git a/cprogs/myopt.h b/cprogs/myopt.h new file mode 100644 index 0000000..6e1200c --- /dev/null +++ b/cprogs/myopt.h @@ -0,0 +1,43 @@ +/* + * myopt.h - declarations for my very own option parsing + * + * Copyright (C) 1994,1995 Ian Jackson + * + * This 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 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 file; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#ifndef MYOPT_H +#define MYOPT_H + +extern void usagemessage(void); /* supply this */ + +typedef void (*voidfnp)(void); + +struct cmdinfo { + const char *olong; + char oshort; + int takesvalue; /* 0 = normal 1 = standard value 2 = option string cont */ + int *iassignto; + const char **sassignto; + void (*call)(const struct cmdinfo*, const char *value); + int arg; + void *parg; + voidfnp farg; +}; + +void myopt(const char *const **argvp, const struct cmdinfo *cmdinfos); +void badusage(const char *fmt, ...); + +#endif /* MYOPT_H */ diff --git a/cprogs/myopt.h~ b/cprogs/myopt.h~ new file mode 100644 index 0000000..0b28d09 --- /dev/null +++ b/cprogs/myopt.h~ @@ -0,0 +1,41 @@ +/* + * libdpkg - Debian packaging suite library routines + * myopt.h - declarations for my very own option parsing + * + * Copyright (C) 1994,1995 Ian Jackson + * + * This 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 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 file; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#ifndef MYOPT_H +#define MYOPT_H + +typedef void (*voidfnp)(void); + +struct cmdinfo { + const char *olong; + char oshort; + int takesvalue; /* 0 = normal 1 = standard value 2 = option string cont */ + int *iassignto; + const char **sassignto; + void (*call)(const struct cmdinfo*, const char *value); + int arg; + void *parg; + voidfnp farg; +}; + +void myopt(const char *const **argvp, const struct cmdinfo *cmdinfos); + +#endif /* MYOPT_H */ diff --git a/cprogs/really b/cprogs/really new file mode 100755 index 0000000..083f0ef Binary files /dev/null and b/cprogs/really differ diff --git a/cprogs/really-test b/cprogs/really-test new file mode 100755 index 0000000..d8d9b3e Binary files /dev/null and b/cprogs/really-test differ diff --git a/cprogs/really.c b/cprogs/really.c new file mode 100644 index 0000000..b240ea4 --- /dev/null +++ b/cprogs/really.c @@ -0,0 +1,210 @@ +/**/ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "myopt.h" + +void usagemessage(void) { + if (fputs("usage: really [] [ ...] [--]" + " [ [ ...]]\n" + "user-options:\n" + " if no options given, set the uid to 0;\n" + " -u|--user also sets their default group list\n" + " -i|--useronly } set the uid\n" + " -I|--uidonly } but inherits the group list\n" + "group-options:\n" + " -z|--groupsclear only groups specified are to be used\n" + " -g|--group } add this to\n" + " -G|--gid } the group list\n", + stderr) == EOF) { perror("write usage"); exit(-1); } +} + +static const char *opt_user, *opt_useronly; +static int opt_groupsclear= 0, opt_ngids= 0, opt_uidonly= -1; +static int opt_gids[512]; + +static void af_group(const struct cmdinfo *cip, const char *value) { + struct group *gr; + + if (opt_ngids >= sizeof(opt_gids)/sizeof(opt_gids[0])) + badusage("too many groups specified"); + gr= getgrnam(value); + if (!gr) { fprintf(stderr,"unknown group `%s'\n",value); exit(-1); } + opt_gids[opt_ngids++]= gr->gr_gid; +} + +static void af_gid(const struct cmdinfo *cip, const char *value) { + char *ep; + unsigned long ul; + + if (opt_ngids >= sizeof(opt_gids)/sizeof(opt_gids[0])) + badusage("too many gids specified"); + ul= strtoul(value,&ep,0); + if ((*ep) || (uid_t)ul != ul || ul>INT_MAX) badusage("bad gid `%s'",value); + opt_gids[opt_ngids++]= ul; +} + +static void af_help(const struct cmdinfo *cip, const char *value) { + usagemessage(); exit(0); +} + +static const struct cmdinfo cmdinfos[]= { + { "user", 'u', 1, 0, &opt_user, 0, }, + { "useronly", 'i', 1, 0, &opt_useronly, 0 }, + { "uidonly", 'I', 1, &opt_uidonly, 0, 0 }, + { "groupsclear", 'z', 0, &opt_groupsclear, 0, 0, 1 }, + { "group", 'g', 1, 0, 0, af_group }, + { "gid", 'G', 1, 0, 0, af_gid }, + { "help", 'h', 0, 0, 0, af_help }, + { 0, 0 } +}; + +#ifdef REALLY_CHECK_FILE +static void checkroot(void) { + int r; + r= access(REALLY_CHECK_FILE,W_OK); + if (r) { perror("sorry"); exit(-1); } +} +#endif +#ifdef REALLY_CHECK_GID +static void checkroot(void) { + gid_t groups[512]; + int r; + + r= getgid(); if (r==REALLY_CHECK_GID) return; + if (r<0) { perror("getgid check"); exit(-1); } + r= getgroups(sizeof(groups)/sizeof(groups[0]),groups); + if (r<0) { perror("getgroups check"); exit(-1); } + for (i=0; ipw_uid; + } + orgmaingid= getgid(); + orgmainuid= getuid(); + if (orgmaingid<0) { perror("getgid failed"); exit(-1); } + if (opt_user) { + r= initgroups(opt_user,pw->pw_gid); + if (r) { perror("initgroups failed"); exit(-1); } + maingid= pw->pw_gid; + } else { + maingid= -1; + } + if (opt_groupsclear) { + ngroups= 0; + if (opt_ngids > sizeof(groups)/sizeof(groups[0])) { + fputs("too many groups to set\n",stderr); + exit(-1); + } + } else { + ngroups= getgroups(0,0); + if (ngroups<0) { perror("getgroups(0,0) failed"); exit(-1); } + if (ngroups+opt_ngids > sizeof(groups)/sizeof(groups[0])) { + fputs("too many groups already set for total to fit\n",stderr); + exit(-1); + } + ngroups= getgroups(ngroups,groups); + if (ngroups<0) { perror("getgroups failed"); exit(-1); } + } + if (opt_ngids) { + maingid= opt_gids[0]; + } + if (opt_ngids || opt_groupsclear) { + ngroups_in= ngroups; ngroups= 0; + for (i=0; i=0) { fputs("could seteuid 0",stderr); exit(-1); } + if (errno != EPERM) { + perror("unexpected failure mode for seteuid 0"); exit(-1); + } + } + r= getuid(); if (r<0) { perror("getuid failed"); exit(-1); } + if (r != mainuid) { fputs("getuid mismatch",stderr); exit(-1); } + r= geteuid(); if (r<0) { perror("geteuid failed"); exit(-1); } + if (r != mainuid) { fputs("geteuid mismatch",stderr); exit(-1); } + if (maingid != -1) { + for (i=0; i=ngroups && maingid != orgmaingid) { + r= setgid(orgmaingid); + if (r>=0) { fputs("could setgid back",stderr); exit(-1); } + if (errno != EPERM) { + perror("unexpected failure mode for setgid back"); exit(-1); + } + } + r= getgid(); if (r<0) { perror("getgid failed"); exit(-1); } + if (r != maingid) { fputs("getgid mismatch",stderr); exit(-1); } + r= getegid(); if (r<0) { perror("getegid failed"); exit(-1); } + if (r != maingid) { fputs("getegid mismatch",stderr); exit(-1); } + } + if (!*argv) { + cp= getenv("SHELL"); + if (!cp) cp= "sh"; + execlp(cp,cp,"-i",(const char*)0); + } else { + execvp(argv[0],(char**)argv); + } + perror("exec failed"); + exit(-1); +} diff --git a/cprogs/really.c~ b/cprogs/really.c~ new file mode 100644 index 0000000..19e642e --- /dev/null +++ b/cprogs/really.c~ @@ -0,0 +1,209 @@ +/**/ + +#include +#include +#include +#include +#include +#include +#include + +#include "myopt.h" + +void usagemessage(void) { + if (fputs("usage: really [] [ ...] [--]" + " [ [ ...]]\n" + "user-options:\n" + " if no options given, set the uid to 0;\n" + " -u|--user also sets their default group list\n" + " -i|--useronly } set the uid\n" + " -I|--uidonly } but inherits the group list\n" + "group-options:\n" + " -z|--groupsclear only groups specified are to be used\n" + " -g|--group } add this to\n" + " -G|--gid } the group list\n", + stderr) == EOF) { perror("write usage"); exit(-1); } +} + +static const char *opt_user, *opt_useronly; +static int opt_groupsclear= 0, opt_ngids= 0, opt_uidonly= -1; +static int opt_gids[512]; + +static void af_group(const struct cmdinfo *cip, const char *value) { + struct group *gr; + + if (opt_ngids >= sizeof(opt_gids)/sizeof(opt_gids[0])) + badusage("too many groups specified"); + gr= getgrnam(value); + if (!gr) { fprintf(stderr,"unknown group `%s'\n",value); exit(-1); } + opt_gids[opt_ngids++]= gr->gr_gid; +} + +static void af_gid(const struct cmdinfo *cip, const char *value) { + char *ep; + unsigned long ul; + + if (opt_ngids >= sizeof(opt_gids)/sizeof(opt_gids[0])) + badusage("too many gids specified"); + ul= strtoul(value,&ep,0); + if ((*ep) || (uid_t)ul != ul || ul>INT_MAX) badusage("bad gid `%s'",value); + opt_gids[opt_ngids++]= ul; +} + +static void af_help(const struct cmdinfo *cip, const char *value) { + usagemessage(); exit(0); +} + +static const struct cmdinfo cmdinfos[]= { + { "user", 'u', 1, 0, &opt_user, 0, }, + { "useronly", 'i', 1, 0, &opt_useronly, 0 }, + { "uidonly", 'I', 1, &opt_uidonly, 0, 0 }, + { "groupsclear", 'z', 0, &opt_groupsclear, 0, 0, 1 }, + { "group", 'g', 1, 0, 0, af_group }, + { "gid", 'G', 1, 0, 0, af_gid }, + { "help", 'h', 0, 0, 0, af_help }, + { 0, 0 } +}; + +#ifdef REALLY_CHECK_FILE +void checkroot(void) { + int r; + r= access(REALLY_CHECK_FILE,W_OK); + if (r) { perror("sorry"); exit(-1); } +} +#endif +#ifdef REALLY_CHECK_GID +void checkroot(void) { + gid_t groups[512]; + int r; + + r= getgid(); if (r==REALLY_CHECK_GID) return; + if (r<0) { perror("getgid check"); exit(-1); } + r= getgroups(sizeof(groups)/sizeof(groups[0]),groups); + if (r<0) { perror("getgroups check"); exit(-1); } + for (i=0; ipw_uid; + } + orgmaingid= getgid(); + orgmainuid= getuid(); + if (orgmaingid<0) { perror("getgid failed"); exit(-1); } + if (opt_user) { + r= initgroups(opt_user,pw->pw_gid); + if (r) { perror("initgroups failed"); exit(-1); } + maingid= pw->pw_gid; + } else { + maingid= -1; + } + if (opt_groupsclear) { + ngroups= 0; + if (opt_ngids > sizeof(groups)/sizeof(groups[0])) { + fputs("too many groups to set\n",stderr); + exit(-1); + } + } else { + ngroups= getgroups(0,0); + if (ngroups<0) { perror("getgroups(0,0) failed"); exit(-1); } + if (ngroups+opt_ngids > sizeof(groups)/sizeof(groups[0])) { + fputs("too many groups already set for total to fit\n",stderr); + exit(-1); + } + ngroups= getgroups(ngroups,groups); + if (ngroups<0) { perror("getgroups failed"); exit(-1); } + } + if (opt_ngids) { + maingid= opt_gids[0]; + } + if (opt_ngids || opt_groupsclear) { + ngroups_in= ngroups; ngroups= 0; + for (i=0; i=0) { fputs("could seteuid 0",stderr); exit(-1); } + if (errno != EPERM) { + perror("unexpected failure mode for seteuid 0"); exit(-1); + } + } + r= getuid(); if (r<0) { perror("getuid failed"); exit(-1); } + if (r != mainuid) { fputs("getuid mismatch",stderr); exit(-1); } + r= geteuid(); if (r<0) { perror("geteuid failed"); exit(-1); } + if (r != mainuid) { fputs("geteuid mismatch",stderr); exit(-1); } + if (maingid != -1) { + for (i=0; i=ngroups && maingid != orgmaingid) { + r= setgid(orgmaingid); + if (r>=0) { fputs("could setgid back",stderr); exit(-1); } + if (errno != EPERM) { + perror("unexpected failure mode for setgid back"); exit(-1); + } + } + r= getgid(); if (r<0) { perror("getgid failed"); exit(-1); } + if (r != maingid) { fputs("getgid mismatch",stderr); exit(-1); } + r= getegid(); if (r<0) { perror("getegid failed"); exit(-1); } + if (r != maingid) { fputs("getegid mismatch",stderr); exit(-1); } + } + if (!*argv) { + cp= getenv("SHELL"); + if (!cp) cp= "sh"; + execlp(cp,cp,"-i",(const char*)0); + } else { + execvp(argv[0],(char**)argv); + } + perror("exec failed"); + exit(-1); +} diff --git a/cprogs/really.testcases b/cprogs/really.testcases new file mode 100755 index 0000000..153e47c --- /dev/null +++ b/cprogs/really.testcases @@ -0,0 +1,164 @@ +#!/usr/bin/perl + +$testuser= 'testac'; +$testgroup= 'testac'; +$testuid= 1000; +$testgid= 1000; +@testxgids= qw(1000); +$numgid= 50008; +$othergroup= 'daemon'; +$othergid= 1; + +sub parseid ($) { + my ($id) = @_; + my $orgid= $id; + my $out= ''; + my $part; + chomp($id); + $id =~ s/^uid=// or return $id =~ m/\n/ ? "ERROR: $`" : "ERROR: $id"; + $id =~ s/^(\d+)// or return $orgid; + $out= $1; + $id =~ s/^\([^\)]+\)//; $id =~ s/^\s+// or return $orgid; + $id =~ s/^gid=(\d+)// or return $orgid; + $out.= " $1"; + $id =~ s/^\([^\)]+\)//; $id =~ s/^\s+// or return $orgid; + $id =~ s/^groups=// or return $orgid; + for $part (split(/,/,$id)) { + $part =~ s/^(\d+)// or return $orgid; + $out.= " $1"; + $part =~ s/^\([^\)]+\)//; $part eq '' or return $orgid; + } + return $out; +} + +$org= `id`; +$org =~ m/^uid=\d+\(([^\)]+)\) gid=\d+\(([^\)]+)\) / or die "$org ?"; +$orguser= $1; $orggroup= $2; +$org= parseid($org); +$org =~ m/^\d+ \d+ / or die $org; +($orguid,$orggid,@orgxgids)= split(/ /,$org); + +$tests= <&1`; + $newout= parseid($out); + print("OK $tests[$i] ($tests[$i+2])\n"), next if $newout eq $tests[$i+1]; + die "$newout != $tests[$i+1] ($tests[$i]) $i"; +} diff --git a/cprogs/smtpallow.c b/cprogs/smtpallow.c new file mode 100644 index 0000000..d8c8532 --- /dev/null +++ b/cprogs/smtpallow.c @@ -0,0 +1,44 @@ +/**/ + +#include +#include +#include +#include + +_syscall2(long,socketcall,int,call,unsigned long *,args); + +int real_connect(int sockfd, const struct sockaddr *saddr, int addrlen) +{ + unsigned long args[3]; + + args[0] = sockfd; + args[1] = (unsigned long)saddr; + args[2] = addrlen; + return socketcall(SYS_CONNECT, args); +} + +int connect(int fd, const struct sockaddr *them_any, int addrlen) { + struct sockaddr_in *them= (struct sockaddr_in*)them_any; + int r,l,i; + struct sockaddr_in us; + + if (addrlen == sizeof(us) && + them->sin_family == AF_INET && + them->sin_port == htons(25)) { + memset(&us,0,sizeof(us)); + us.sin_port= 0; + us.sin_family= AF_INET; + us.sin_addr.s_addr= INADDR_ANY; + r= getsockname(fd,(struct sockaddr*)&us,&l); + if (r<0 && errno != EINVAL) return r; + if (!ntohs(us.sin_port)) { + for (i=1023; i>0; i--) { + us.sin_port= htons(i); + if (!bind(fd,(struct sockaddr*)&us,sizeof(us))) break; + if (errno != EADDRINUSE) return -1; + } + if (!i) return -1; + } else if (r<0) return r; + } + return real_connect(fd,them_any,addrlen); +} diff --git a/cprogs/smtpallow.c~ b/cprogs/smtpallow.c~ new file mode 100644 index 0000000..83d0fc4 --- /dev/null +++ b/cprogs/smtpallow.c~ @@ -0,0 +1,35 @@ +/**/ + +#include + +_syscall2(long,socketcall,int,call,unsigned long *,args); +int real_connect(int sockfd, const struct sockaddr *saddr, int addrlen) +{ + unsigned long args[3]; + + args[0] = sockfd; + args[1] = (unsigned long)saddr; + args[2] = addrlen; + return socketcall(SYS_CONNECT, args); +} + +int connect(int fd, struct sockaddr_in *them, int *addrlen) { + int r,l; + struct sockaddr_in us; + pid_t c; + + if (*addrlen == sizeof(us) && + them->sin_family == AF_INET && + them->sin_port == htons(13)) { + r= getsockname(fd,&us,&l); if (r<0) return r; + if (!ntohs(us.port)) { + for (i=1023; i>0; i++) { + us.port= htons(i); + if (!bind(fd,&us,sizeof(us))) break; + if (errno != EADDRINUSE) return -1; + } + if (!i) return -1; + } + } + return real_connect(fd,them,addrlen); +} diff --git a/cprogs/smtpallow.o b/cprogs/smtpallow.o new file mode 100644 index 0000000..3d66f7a Binary files /dev/null and b/cprogs/smtpallow.o differ diff --git a/cprogs/smtpallow.so b/cprogs/smtpallow.so new file mode 100755 index 0000000..3fa3346 Binary files /dev/null and b/cprogs/smtpallow.so differ diff --git a/cprogs/usernice.c b/cprogs/usernice.c new file mode 100644 index 0000000..1f05e19 --- /dev/null +++ b/cprogs/usernice.c @@ -0,0 +1,67 @@ +/**/ + +#include +#include +#include +#include +#include +#include +#include + +int main(int argc,char **argv) { + long l; + int mrenice,wrenice,newprio,eflag; + uid_t ruid; + char *ep; + struct passwd *pw; + + mrenice=0; + if (argc < 3) { + fputs("usernice: too few args\n" + " usage: usernice \n" + " usernice p ...\n" + " usernice u ...\n", + stderr); + exit(-1); + } + l= strtol(*++argv,&ep,10); + if (*ep == 'p' || *ep == 'u') { mrenice= *ep++; } + if (*ep) { fputs("usernice: priority not numeric or bad flags\n",stderr); exit(-1); } + if (l<-20 || l>20) + { fputs("usernice: priority must be -20 .. 20\n",stderr); exit(-1); } + newprio= l; + if (mrenice) { + eflag=0; + while (*++argv) { + if (mrenice == 'p') { + wrenice= PRIO_PROCESS; + l= strtoul(*argv,&ep,10); + if (*ep) { + fprintf(stderr,"usernice: pid `%s' not numeric\n",*argv); eflag=2; + continue; + } + } else { + wrenice= PRIO_USER; + l= strtoul(*argv,&ep,10); + if (*ep) { + pw= getpwnam(*argv); + if (!pw) { + fprintf(stderr,"usernice: unknown user `%s'\n",*argv); eflag=2; + continue; + } + l= pw->pw_uid; + } + } + if (setpriority(wrenice,l,newprio)) { + perror(*argv); if (!eflag) eflag=1; + } + } + exit(eflag); + } else { + if (setpriority(PRIO_PROCESS,0,newprio)) + { perror("usernice: setpriority"); exit(-1); } + ruid= getuid(); if (ruid == (uid_t)-1) { perror("usernice: getuid"); exit(-1); } + if (setreuid(ruid,ruid)) { perror("usernice: setreuid"); exit(-1); } + execvp(argv[1],argv+1); perror("usernice: exec"); exit(-1); + } +} diff --git a/cprogs/usr-local-src-misc-Makefile b/cprogs/usr-local-src-misc-Makefile new file mode 100644 index 0000000..a1a96f2 --- /dev/null +++ b/cprogs/usr-local-src-misc-Makefile @@ -0,0 +1,18 @@ +CFLAGS= -Wall -Wwrite-strings -Wmissing-prototypes -Wstrict-prototypes \ + -Wpointer-arith -O2 -g -DREALLY_CHECK_FILE='"/etc/inittab"' +LDFLAGS= + +TARGETS=really + +all: $(TARGETS) + +really: really.o myopt.o + +really-test: really Makefile + rm -f really-test + cp really really-test + really chown root.staff really-test + really chmod 4770 really-test + +really-check: really-test really.testcases + ./really.testcases diff --git a/cprogs/usr-local-src-misc-Makefile~ b/cprogs/usr-local-src-misc-Makefile~ new file mode 100644 index 0000000..edac912 --- /dev/null +++ b/cprogs/usr-local-src-misc-Makefile~ @@ -0,0 +1,9 @@ +CFLAGS= -Wall -Wwrite-strings -Wmissing-prototypes -Wstrict-prototypes \ + -Wpointer-arith -O2 -g -DREALLY_CHECK_FILE='"/etc/inittab"' +LDFLAGS= + +TARGETS=really + +all: $(TARGETS) + +really: really.o myopt.o diff --git a/debian/changelog b/debian/changelog index 56742a8..2574dfd 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,6 +1,11 @@ chiark-utils (3.99.1.0.2) unstable; urgency=low * foreign zones checked from delegation by default. + * from chiark:/usr/local/src/misc/ (as found): + really (incl. myopt) + usernice + cvsweb-list + smtpallow -- diff --git a/scripts/cvsweb-list b/scripts/cvsweb-list new file mode 100755 index 0000000..b5ac819 --- /dev/null +++ b/scripts/cvsweb-list @@ -0,0 +1,56 @@ +#!/usr/bin/perl + +print < +chiark public CVS + + + +

chiark users' public CVS

+
    +END + +open UL, "/etc/userlist" or die $!; +while (
      ) { + next if m/^\#/ or !m/\S/; + chomp($user= $_); + next unless readlink "/home/$user/public-cgi/cvsweb" + eq '/usr/local/lib/cvsweb'; + $hd= 0; + $pc= "/home/$user/public-CVS/"; + next unless opendir D, $pc; + while (defined($mod= readdir D)) { + next unless -d "$pc/$mod"; + next if $mod =~ m/^\./; + if (!$hd) { + print "
    • $user" or die $!; + print " (homepage)" or die $! + if -d "/home/$user/public-html"; + print ":" or die $!; + $hd= 1; + } else { + print "," or die $!; + } + print " $mod" or die $!; + } + next unless $hd; + print "
    • \n" or die $!; +} + +close UL or die $!; + +print < +
      +
      + maintained by + $ENV{SERVER_ADMIN}; + chiark home page +
      + +END + +exit 0 diff --git a/scripts/cvsweb-list~ b/scripts/cvsweb-list~ new file mode 100755 index 0000000..124235a --- /dev/null +++ b/scripts/cvsweb-list~ @@ -0,0 +1,55 @@ +#!/usr/bin/perl + +print < +chiark public CVS + + + +

      list of users exporting CVS repositories via cvsweb from chiark

      +
        +END + +open UL, "/etc/userlist" or die $!; +while (
          ) { + next if m/^\#/ or !m/\S/; + chomp($user= $_); + next unless readlink "/home/$user/public-cgi/cvsweb" + eq '/usr/local/lib/cvsweb'; + $hd= 0; + $pc= "/home/$user/public-CVS/"; + next unless opendir D, $pc; + while (defined($mod= readdir D)) { + next unless -d "$pc/$mod"; + next if $mod =~ m/^\./; + if (!$hd) { + print "
        • $user" or die $!; + print " (homepage)" or die $! + if -d "/home/$user/public-html"; + print ":" or die $!; + $hd= 1; + } else { + print "," or die $!; + } + print " $mod" or die $!; + } + next unless $hd; + print "
        • \n" or die $!; +} + +close UL or die $!; + +print < +
          +
          + maintained by + $ENV{SERVER_ADMIN}; + chiark home page +
          + +END + +exit 0