r22942 MediaWiki - Code Review archive

Repository:MediaWiki
Revision:r22941‎ | r22942 | r22943 >
Date:00:52, 13 June 2007
Author:river
Status:old
Tags:
Comment:
- pwtool: allow users to change their shell and gecos (add)
- watcherd: fix compile error with gcc
Modified paths:
  • /trunk/tools/tsutils/Makefile (modified) (history)
  • /trunk/tools/tsutils/config.mk (modified) (history)
  • /trunk/tools/tsutils/pwtool (added) (history)
  • /trunk/tools/tsutils/pwtool/Makefile (added) (history)
  • /trunk/tools/tsutils/pwtool/pwtool.c (added) (history)
  • /trunk/tools/tsutils/watcherd/watcherd.c (modified) (history)

Diff [purge]

Index: trunk/tools/tsutils/watcherd/watcherd.c
@@ -44,7 +44,6 @@
4545 static void read_configuration(void);
4646 static int run_check(void);
4747 static void notify_query(char const *id, char const *user, char const *db, char const *query, int t);
48 -static int seen_query(int64_t);
4948 static void clean_seen_queries(void);
5049 static void add_seen_query(int64_t);
5150 static int has_warned(int64_t);
@@ -345,17 +344,6 @@
346345 querylist.q_next = q;
347346 }
348347
349 -static int
350 -seen_query(qid)
351 - int64_t qid;
352 -{
353 -query *q;
354 - for (q = querylist.q_next; q; q = q->q_next)
355 - if (q->q_id == qid)
356 - return 1;
357 - return 0;
358 -}
359 -
360348 static void
361349 set_warned(qid)
362350 int64_t qid;
Index: trunk/tools/tsutils/pwtool/pwtool.c
@@ -0,0 +1,254 @@
 2+/* Copyright (c) 2007 River Tarnell <river@attenuate.org>. */
 3+/*
 4+ * Permission is granted to anyone to use this software for any purpose,
 5+ * including commercial applications, and to alter it and redistribute it
 6+ * freely. This software is provided 'as-is', without any express or implied
 7+ * warranty.
 8+ */
 9+
 10+/* $Id$ */
 11+
 12+/*
 13+ * pwtool: allow users to edit their shell and realname.
 14+ */
 15+
 16+#define _GNU_SOURCE
 17+
 18+#include <sys/types.h>
 19+#include <sys/stat.h>
 20+#include <sys/capability.h>
 21+#include <stdio.h>
 22+#include <string.h>
 23+#include <errno.h>
 24+#include <pwd.h>
 25+#include <fcntl.h>
 26+#include <unistd.h>
 27+#include <ctype.h>
 28+#include <stdlib.h>
 29+#include <signal.h>
 30+
 31+#define PASSWD "/etc/passwd"
 32+#define TMPFILE "/etc/passwd.tmp"
 33+
 34+static int isvalidshell(char const *);
 35+static int isvalidgecos(char const *);
 36+static void cleanup(void);
 37+
 38+static int outfd = -1;
 39+
 40+cap_t caps;
 41+
 42+int
 43+main(argc, argv)
 44+ int argc;
 45+ char *argv[];
 46+{
 47+int infd;
 48+FILE *inf, *outf;
 49+struct stat st;
 50+struct passwd *pwd;
 51+uid_t me;
 52+int c;
 53+char *newshell = NULL, *newgecos = NULL;
 54+cap_value_t wantcaps[] = { CAP_CHOWN };
 55+
 56+ (void) umask(022);
 57+
 58+ if ((caps = cap_init()) == NULL) {
 59+ (void) fprintf(stderr, "cannot initialise capabilities: %s\n",
 60+ strerror(errno));
 61+ return 1;
 62+ }
 63+
 64+ /*
 65+ * Drop all capabilities from our effective and inheritable sets.
 66+ * Leave CAP_CHOWN in permitted because we need it for fchown later.
 67+ */
 68+ cap_clear(caps);
 69+ cap_set_flag(caps, CAP_PERMITTED, sizeof(wantcaps) / sizeof(*wantcaps), wantcaps, CAP_SET);
 70+
 71+ if (cap_set_proc(caps) == -1) {
 72+ (void) fprintf(stderr, "cannot set capabilities: %s\n",
 73+ strerror(errno));
 74+ return 1;
 75+ }
 76+
 77+ while ((c = getopt(argc, argv, "s:g:h")) != -1) {
 78+ switch (c) {
 79+ case 's':
 80+ newshell = optarg;
 81+ break;
 82+
 83+ case 'g':
 84+ newgecos = optarg;
 85+ break;
 86+
 87+ case 'h':
 88+ (void) fprintf(stderr, "usage: pwtool [-h] [-s shell] [-g gecos]\n");
 89+ return 0;
 90+
 91+ default:
 92+ return 1;
 93+ }
 94+ }
 95+ argc -= optind;
 96+ argv += optind;
 97+
 98+ if (argc != 0) {
 99+ (void) fprintf(stderr, "usage: pwtool [-s shell] [-g gecos]\n");
 100+ return 1;
 101+ }
 102+
 103+ if (!newgecos && !newshell)
 104+ return 0;
 105+
 106+
 107+ if (newshell && !isvalidshell(newshell)) {
 108+ (void) fprintf(stderr, "pwtool: \"%s\" is not a valid login shell\n",
 109+ newshell);
 110+ return 1;
 111+ }
 112+
 113+ if (newgecos && !isvalidgecos(newgecos)) {
 114+ (void) fprintf(stderr, "pwtool: GECOS may only contain ASCII alphanumerics and whitespace\n");
 115+ return 1;
 116+ }
 117+
 118+ me = getuid();
 119+
 120+ if ((infd = open(PASSWD, O_RDONLY)) == -1) {
 121+ (void) fprintf(stderr, "pwtool: cannot open %s: %s\n", PASSWD, strerror(errno));
 122+ return 1;
 123+ }
 124+
 125+ if ((inf = fdopen(infd, "r")) == NULL) {
 126+ (void) fprintf(stderr, "pwtool: cannot open %s: %s\n", PASSWD, strerror(errno));
 127+ return 1;
 128+ }
 129+
 130+ if (fstat(infd, &st) == -1) {
 131+ (void) fprintf(stderr, "pwtool: cannot fstat %s: %s\n", PASSWD, strerror(errno));
 132+ return 1;
 133+ }
 134+
 135+ atexit(cleanup);
 136+ signal(SIGINT, SIG_IGN);
 137+ signal(SIGTERM, SIG_IGN);
 138+ signal(SIGQUIT, SIG_IGN);
 139+
 140+ if ((outfd = open(TMPFILE, O_WRONLY | O_EXCL | O_CREAT, st.st_mode)) == -1) {
 141+ (void) fprintf(stderr, "pwtool: cannot open %s: %s\n", TMPFILE, strerror(errno));
 142+ return 1;
 143+ }
 144+
 145+ /*
 146+ * CAP_CHOWN is needed to change the owner of the tmp file correctly.
 147+ */
 148+ cap_set_flag(caps, CAP_EFFECTIVE, sizeof(wantcaps) / sizeof(*wantcaps), wantcaps, CAP_SET);
 149+
 150+ if (cap_set_proc(caps) == -1) {
 151+ (void) fprintf(stderr, "cannot set capabilities: %s\n",
 152+ strerror(errno));
 153+ return 1;
 154+ }
 155+
 156+ if (fchown(outfd, st.st_uid, st.st_gid) == -1) {
 157+ (void) fprintf(stderr, "pwtool: cannot chown %s: %s\n", TMPFILE, strerror(errno));
 158+ return 1;
 159+ }
 160+
 161+ /*
 162+ * Now we can drop CAP_CHOWN from both permitted and effective.
 163+ */
 164+ cap_set_flag(caps, CAP_PERMITTED, sizeof(wantcaps) / sizeof(*wantcaps), wantcaps, CAP_CLEAR);
 165+ cap_set_flag(caps, CAP_EFFECTIVE, sizeof(wantcaps) / sizeof(*wantcaps), wantcaps, CAP_CLEAR);
 166+
 167+ if (cap_set_proc(caps) == -1) {
 168+ (void) fprintf(stderr, "cannot set capabilities: %s\n",
 169+ strerror(errno));
 170+ return 1;
 171+ }
 172+
 173+ if ((outf = fdopen(outfd, "w")) == NULL) {
 174+ (void) fprintf(stderr, "pwtool: cannot open %s: %s\n", TMPFILE, strerror(errno));
 175+ return 1;
 176+ }
 177+
 178+ while ((pwd = fgetpwent(inf)) != NULL) {
 179+ if (pwd->pw_uid == me) {
 180+ if (newgecos)
 181+ pwd->pw_gecos = newgecos;
 182+ if (newshell)
 183+ pwd->pw_shell = newshell;
 184+ }
 185+
 186+ if (putpwent(pwd, outf) == -1) {
 187+ (void) fprintf(stderr, "pwtool: error writing to %s: %s",
 188+ TMPFILE, strerror(errno));
 189+ return 1;
 190+ }
 191+ }
 192+
 193+ if (ferror(inf)) {
 194+ (void) fprintf(stderr, "pwtool: error reading %s: %s\n",
 195+ PASSWD, strerror(errno));
 196+ return 1;
 197+ }
 198+
 199+ if (fsync(fileno(outf)) == -1) {
 200+ (void) fprintf(stderr, "pwtool: error syncing %s: %s\n",
 201+ TMPFILE, strerror(errno));
 202+ return 1;
 203+ }
 204+
 205+ if (fclose(outf) == EOF) {
 206+ (void) fprintf(stderr, "pwtool: error closing %s: %s\n",
 207+ TMPFILE, strerror(errno));
 208+ outfd = -1;
 209+ return 1;
 210+ }
 211+
 212+ outfd = -1;
 213+ fclose(inf);
 214+
 215+ if (rename(TMPFILE, PASSWD) == -1) {
 216+ (void) fprintf(stderr, "pwtool: cannot rename %s to %s: %s\n",
 217+ TMPFILE, PASSWD, strerror(errno));
 218+ return 1;
 219+ }
 220+
 221+ return 0;
 222+}
 223+
 224+static int
 225+isvalidshell(sh)
 226+ char const *sh;
 227+{
 228+char const *s;
 229+ setusershell();
 230+ while ((s = getusershell()) != NULL)
 231+ if (!strcmp(s, sh))
 232+ return 1;
 233+ return 0;
 234+}
 235+
 236+static int
 237+isvalidgecos(ge)
 238+ char const *ge;
 239+{
 240+ while (*ge) {
 241+ if (!isascii(*ge) || !(isalnum(*ge) || isblank(*ge)))
 242+ return 0;
 243+
 244+ ge++;
 245+ }
 246+
 247+ return 1;
 248+}
 249+
 250+static void
 251+cleanup()
 252+{
 253+ if (outfd != -1)
 254+ (void) unlink(TMPFILE);
 255+}
Index: trunk/tools/tsutils/pwtool/Makefile
@@ -0,0 +1,8 @@
 2+PROG = pwtool
 3+BINMODE = 4755
 4+
 5+SRCS = pwtool.c
 6+OBJS = $(SRCS:.c=.o)
 7+LIBS = -lcap
 8+
 9+include ../mk/prog.mk
Index: trunk/tools/tsutils/config.mk
@@ -1,7 +1,7 @@
2 -LINT = lint
3 -CC = suncc
4 -CFLAGS = -m64 -O -g -errwarn -xc99=none
5 -LINTFLAGS = -axsm -u -errtags=yes -s -Xc99=%none -Xarch=amd64 -errsecurity=core -erroff=E_INCONS_ARG_DECL2
 2+#LINT = lint
 3+#CC = suncc
 4+#CFLAGS = -m64 -O -g -errwarn -xc99=all
 5+#LINTFLAGS = -axsm -u -errtags=yes -s -Xc99=%none -Xarch=amd64 -errsecurity=core -erroff=E_INCONS_ARG_DECL2
66
7 -# CC = gcc
8 -# CFLAGS = -W -Wall -Werror
 7+CC = gcc
 8+CFLAGS = -W -Wall -Werror
Index: trunk/tools/tsutils/Makefile
@@ -1,4 +1,4 @@
2 -SUBDIRS = libtsutils watcherd acctexp listlogins lsexp whodo
 2+SUBDIRS = libtsutils watcherd acctexp listlogins lsexp whodo whinequota pwtool
33 MAKEFLAGS = --no-print-directory
44
55 all clean depend install lint:

Status & tagging log