⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 grpck.c

📁 pwdutils是一套密码管理工具
💻 C
📖 第 1 页 / 共 2 页
字号:
/* Copyright (C) 2004, 2005 Thorsten Kukuk   Author: Thorsten Kukuk <kukuk@suse.de>   This program is free software; you can redistribute it and/or modify   it under the terms of the GNU General Public License version 2 as   published by the Free Software Foundation.   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.  */#ifdef HAVE_CONFIG_H#include <config.h>#endif#define _GNU_SOURCE#include <time.h>#include <errno.h>#include <stdio.h>#include <string.h>#include <unistd.h>#include <getopt.h>#include <sys/types.h>#include <sys/stat.h>#include "i18n.h"#include "yesno.h"#include "public.h"#include "read-files.h"#define E_SUCCESS 0#define E_USAGE 1#define E_BAD_ENTRY 2#define E_NO_FILE 3#define E_PWDBUSY 4#define E_FAILURE 5#define SCALE DAYchar *files_etc_dir = "/etc";int readonly = 0;static voidprint_usage (FILE *stream, const char *program){  fprintf (stream, _("Usage: %s [-P path] [-q|-r]\n"),           program);}static voidprint_help (const char *program){  print_usage (stdout, program);  fprintf (stdout, _("%s - check integrity of group file\n\n"), program);  fputs (_("  -P path        Search passwd, shadow and group file in \"path\"\n"),         stdout);  fputs (_("  -q, --quiet    Don't print warnings, only errors\n"), stdout);  fputs (_("  -r, --read-only Run in read-only mode, don't make changes\n"),	 stdout);  fputs (_("  -s, --sort     Sort the group file, no checks are done\n"),	 stdout);  fputs (_("      --help     Give this help list\n"), stdout);  fputs (_("  -u, --usage    Give a short usage message\n"), stdout);  fputs (_("  -v, --version  Print program version\n"), stdout);}static intanswer_yes (void){  if (readonly)    {      printf (_("No\n"));      return 0;    }  else    return yesno ();}#define BLACKLIST_INITIAL_SIZE 512#define BLACKLIST_INCREMENT 256struct blacklist_t{  char *data;  int current;  int size;};/* returns TRUE if ent->blacklist contains name, else FALSE */static bool_tin_blacklist (const char *name, int namelen, struct blacklist_t *ent){  char buf[namelen + 3];  char *cp;  if (ent->data == NULL)    return FALSE;  buf[0] = '|';  cp = stpcpy (&buf[1], name);  *cp++ = '|';  *cp = '\0';  return strstr (ent->data, buf) != NULL;}/* Support routines for remembering login names. The names are stored   in a single string with `|' as separator. */static voidblacklist_store_name (const char *name, struct blacklist_t *ent){  int namelen = strlen (name);  char *tmp;  /* first call, setup cache */  if (ent->size == 0)    {      ent->size = MAX (BLACKLIST_INITIAL_SIZE, 2 * namelen);      ent->data = malloc (ent->size);      if (ent->data == NULL)        return;      ent->data[0] = '|';      ent->data[1] = '\0';      ent->current = 1;    }  else    {      if (in_blacklist (name, namelen, ent))        return;                 /* no duplicates */      if (ent->current + namelen + 1 >= ent->size)        {          ent->size += MAX (BLACKLIST_INCREMENT, 2 * namelen);          tmp = realloc (ent->data, ent->size);          if (tmp == NULL)            {              free (ent->data);              ent->size = 0;              return;            }          ent->data = tmp;        }    }  tmp = stpcpy (ent->data + ent->current, name);  *tmp++ = '|';  *tmp = '\0';  ent->current += namelen + 1;  return;}/* XXX move into the library.  */static struct passwd *files_getpwnam (const char *name){  enum nss_status status;  static int buflen = 256;  static char *buffer;  static struct passwd resultbuf;  if (buffer == NULL)    {      buffer = malloc (buflen);      if (buffer == NULL)	{	  fputs ("running out of memory!\n", stderr);	  exit (E_FAILURE);	}    }  while ((status =          files_getpwnam_r (name, &resultbuf, buffer, buflen,                            &errno)) == NSS_STATUS_TRYAGAIN         && errno == ERANGE)    {      errno = 0;      buflen *= 2;      buffer = realloc (buffer, buflen);    }  if (status == NSS_STATUS_SUCCESS)    return &resultbuf;  else    return NULL;}static intloop_over_group_file (int quiet){  struct stat group_stat;  FILE *input, *output;  int output_fd;  char *buf = NULL;  size_t buflen = 0;  struct group res;  int result = 0;  struct blacklist_t blacklist = {NULL, 0, 0};  int modified = 0;  long i;  char *inputname = alloca (strlen (files_etc_dir) + 8);  char *outputname = alloca (strlen (files_etc_dir) + 20);  int bufferlen = 512;  char *buffer = malloc (bufferlen);  if (buffer == NULL)    {      fputs ("running out of memory!\n", stderr);      exit (E_FAILURE);    }  strcpy (inputname, files_etc_dir);  strcat (inputname, "/group");  strcpy (outputname, files_etc_dir);  strcat (outputname, "/group.tmpXXXXXX");  if (!quiet)    printf (_("Checking `%s'\n"), inputname);  input = fopen (inputname, "r");  if (input == NULL)    {      fprintf (stderr, _("Can't open `%s': %m\n"), inputname);      return E_NO_FILE;    }  if (fstat (fileno (input), &group_stat) < 0)    {      fprintf (stderr, _("Can't stat `%s': %m\n"), inputname);      fclose (input);      return E_NO_FILE;    }#ifdef WITH_SELINUX  security_context_t prev_context;  if (set_default_context (inputname, &prev_context) < 0)    {      fclose (input);      return E_NO_FILE;    }#endif  /* Open a temp group file */  output_fd = mkstemp (outputname);#ifdef WITH_SELINUX  if (restore_default_context (prev_context) < 0)    {      if (output_fd >= 0)	close (output_fd);      fclose (input);      return E_FAILURE;    }#endif  if (output_fd == -1)    {      fprintf (stderr, _("Can't create `%s': %m\n"),	       inputname);      fclose (input);      return E_NO_FILE;    }  if (fchmod (output_fd, group_stat.st_mode) < 0)    {      fprintf (stderr,	       _("Cannot change permissions for `%s': %s\n"),	       outputname, strerror (errno));      fclose (input);      close (output_fd);      unlink (outputname);      return E_NO_FILE;    }  if (fchown (output_fd, group_stat.st_uid, group_stat.st_gid) < 0)    {      fprintf (stderr,	       _("Cannot change owner/group for `%s': %s\n"),	       outputname, strerror (errno));      fclose (input);      close (output_fd);      unlink (outputname);      return E_NO_FILE;    }  if (copy_xattr (inputname, outputname) != 0)    {      fclose (input);      close (output_fd);      unlink (outputname);      return E_NO_FILE;    }  output = fdopen (output_fd, "w+");  if (output == NULL)    {      fprintf (stderr, _("Can't open `%s': %m\n"), outputname);      fclose (input);      close (output_fd);      unlink (outputname);      return E_NO_FILE;    }  while (!feof (input))    {      char *cp;#if defined(HAVE_GETLINE)      ssize_t n = getline (&buf, &buflen, input);#elif defined (HAVE_GETDELIM)      ssize_t n = getdelim (&buf, &buflen, '\n', input);#else      ssize_t n;      if (buf == NULL)        {          buflen = 8096;          buf = malloc (buflen);        }      buf[0] = '\0';      fgets (buf, buflen - 1, input);      if (buf != NULL)        n = strlen (buf);      else        n = 0;#endif /* HAVE_GETLINE / HAVE_GETDELIM */      if (buf)	cp = strdup (buf);      else	cp = strdup (buf);      if (n < 1)	{	  if (feof (input))	    continue;	  result = E_BAD_ENTRY;	  printf (_("Invalid group entry.\n"));	  printf (_("Delete empty line? "));	  if (answer_yes ())	    {	      free (cp);	      modified = 1;	      continue;	    }	  else	    goto write_gr;	}      /* Remove trailing '\n'.  */      if (buf[strlen (buf) - 1] == '\n')	buf[strlen (buf) - 1] = '\0';      if (*cp == '+' || *cp == '-')	goto write_gr;      /* Comments are not allowed in /etc/group.  */      if (strchr (cp, '#') != NULL)	{	  result = E_BAD_ENTRY;	  printf (_("Invalid group entry with comment.\n"));	  printf (_("Delete line `%s'? "), cp);	  if (answer_yes ())	    {	      free (cp);	      modified = 1;	      continue;	    }	  else	    goto write_gr;	}      /* Parse string in strict mode and report error.  */      {	int status;	while ((status = parse_grent (buf, &res, buffer,				      bufferlen, &errno, 1)) == -1 &&	       errno == ERANGE)	  {	    errno = 0;	    bufferlen *= 2;	    buffer = realloc (buffer, bufferlen);	  }	if (status != 1)	  {	    result = E_BAD_ENTRY;	    printf (_("Invalid group entry.\n"));	    printf (_("Delete line `%s'? "), cp);	    if (answer_yes ())	      {		modified = 1;		free (cp);		continue;	      }	    else	      goto write_gr;	  }      }      /* Check for invalid characters in username.  */      if (check_name (res.gr_name) < 0)	{	  result = E_BAD_ENTRY;	  printf (_("Invalid group name `%s'.\n"), res.gr_name);	  printf (_("Delete line `%s'? "), cp);	  if (answer_yes ())	    {	      modified = 1;	      free (cp);	      continue;	    }	  else	    goto write_gr;	}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -