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

📄 pwck.c

📁 pwdutils是一套密码管理工具
💻 C
📖 第 1 页 / 共 2 页
字号:
      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 ("");      if (n < 1)	{	  if (feof (input))	    continue;	  result = E_BAD_ENTRY;	  printf (_("Invalid shadow entry.\n"));	  printf (_("Delete empty line? "));	  if (answer_yes ())	    {	      modified = 1;	      free (cp);	      continue;	    }	  else	    goto write_pw;	}      /* Remove trailing '\n'.  */      if (cp[strlen (cp) - 1] == '\n')	cp[strlen (cp) - 1] = '\0';      if (*cp == '+' || *cp == '-')	goto write_pw;      /* Comments are not allowed in /etc/shadow.  */      if (strchr (cp, '#') != NULL)	{	  result = E_BAD_ENTRY;	  printf (_("Invalid shadow entry with comment.\n"));	  printf (_("Delete line `%s'? "), cp);	  if (answer_yes ())	    {	      modified = 1;	      continue;	    }	  else	    goto write_pw;	}      /* Parse string in strict mode and report error.  */      if (parse_spent (buf, &res, 1) != 1)	{	  result = E_BAD_ENTRY;	  printf (_("Invalid shadow entry.\n"));	  printf (_("Delete line `%s'? "), cp);	  if (answer_yes ())	    {	      modified = 1;	      free (cp);	      continue;	    }	  else	    goto write_pw;	}      /* Check for invalid characters in username.  */      if (check_name (res.sp_namp) < 0)	{	  result = E_BAD_ENTRY;	  printf (_("Invalid account name `%s'.\n"), res.sp_namp);	  printf (_("Delete line `%s'? "), cp);	  if (answer_yes ())	    {	      modified = 1;	      free (cp);	      continue;	    }	  else	    goto write_pw;	}      /* Check, if we saw this user name already.  */      if (in_blacklist (res.sp_namp, strlen (res.sp_namp), &blacklist))	{	  result = E_BAD_ENTRY;	  printf (_("Duplicate shadow entry\n"));	  printf (_("Delete line `%s'? "), cp);	  if (answer_yes ())	    {	      modified = 1;	      free (cp);	      continue;	    }	  else	    goto write_pw;	}      /* Mark the username as seen, but after checking for duplicate!  */      blacklist_store_name (res.sp_namp, &blacklist);      /* Check, if a passwd entry exist.  */      if (files_getpwnam (res.sp_namp) == NULL)	{	  result = E_BAD_ENTRY;	  printf (_("No matching password file entry.\n"));	  printf (_("Delete line `%s'? "), cp);	  if (answer_yes ())	    {	      modified = 1;	      free (cp);	      continue;	    }	  else	    goto write_pw;	}      if (!quiet && res.sp_lstchg > time ((time_t *) 0) / SCALE)	{	  result = E_BAD_ENTRY;	  printf (_("User `%s': last password change in the future.\n"),		  res.sp_namp);	}    write_pw:      fprintf (output, "%s\n", cp);      free (cp);    }  fclose (input);  fclose (output);  if (modified)    {      char *oldname = alloca (strlen (files_etc_dir) + 20);      strcpy (oldname, files_etc_dir);      strcat (oldname, "/shadow.old");      unlink (oldname);      if (link (inputname, oldname) < 0)	fprintf (stderr,		 _("Warning: cannot create backup file `%s': %m\n"),                 oldname);      rename (outputname, inputname);    }  else    unlink (outputname);  return result;}/* XXX move n library.  */static struct passwd *files_getpwent (void){  enum nss_status status;  int buflen = 256;  char *buffer = NULL;  struct passwd *resultbuf = malloc (sizeof (struct passwd));  if (buffer == NULL)    buffer = malloc (buflen);  while ((status = files_getpwent_r (resultbuf, buffer, buflen, &errno))         == NSS_STATUS_TRYAGAIN && errno == ERANGE)    {      errno = 0;      buflen += 256;      buffer = realloc (buffer, buflen);    }  if (status == NSS_STATUS_SUCCESS)    return resultbuf;  else    return NULL;}struct passwd_list {  struct passwd *pwd;  struct passwd_list *next;};static intsort_passwd_file (void){  struct passwd *pwd;  struct passwd_list *ptr = NULL;  int retval = 0;  while ((pwd = files_getpwent ()))    {      if (pwd->pw_name[0] == '+' || pwd->pw_name[0] == '-')	break;      if (ptr == NULL)	{	  ptr = malloc (sizeof (struct passwd_list));	  if (ptr == NULL)	    {	      fputs ("running out of memory!\n", stderr);	      exit (E_FAILURE);	    }	  ptr->pwd = pwd;	  ptr->next = NULL;	}      else	{	  struct passwd_list *next = ptr;	  while (next->next && next->pwd->pw_uid < pwd->pw_uid)	    next = next->next;	  if (next->next == NULL)	    {	      next->next = malloc (sizeof (struct passwd_list));	      if (next->next == NULL)		{		  fputs ("running out of memory!\n", stderr);		  exit (E_FAILURE);		}	      next->next->next = NULL;	      if (pwd->pw_uid > next->pwd->pw_uid)		next->next->pwd = pwd;	      else		{		  next->next->pwd = next->pwd;		  next->pwd = pwd;		}	    }	  else	    {	      struct passwd_list *tmp;	      tmp = malloc (sizeof (struct passwd_list));	      if (tmp == NULL)		{		  fputs ("running out of memory!\n", stderr);		  exit (E_FAILURE);		}	      tmp->next = next->next;	      next->next = tmp;	      tmp->pwd = next->pwd;	      next->pwd = pwd;	    }	}    }  const char *file_tmp = "/passwd.tmpXXXXXX";  char *passwd_tmp = alloca (strlen (files_etc_dir) + strlen (file_tmp) + 1);  char *passwd_orig = alloca (strlen (files_etc_dir) + 8);  char *passwd_old = alloca (strlen (files_etc_dir) + 12);  struct stat passwd_stat;  FILE *oldgf, *newgf;  int newgf_fd;  char *cp;  cp = stpcpy (passwd_tmp, files_etc_dir);  strcpy (cp, file_tmp);  cp = stpcpy (passwd_orig, files_etc_dir);  strcpy (cp, "/passwd");  cp = stpcpy (passwd_old, passwd_orig);  strcpy (cp, ".old");  if ((oldgf = fopen (passwd_orig, "r")) == NULL)    {      fprintf (stderr, _("Can't open `%s': %m\n"), passwd_orig);      retval = -1;      goto error_passwd;    }  if (fstat (fileno (oldgf), &passwd_stat) < 0)    {      fprintf (stderr, _("Can't stat `%s': %m\n"), passwd_orig);      fclose (oldgf);      retval = -1;      goto error_passwd;    }#ifdef WITH_SELINUX  security_context_t prev_context;  if (set_default_context (passwd_orig, &prev_context) < 0)    {      fclose (oldgf);      retval = -1;      goto error_passwd;    }#endif  /* Open a temp passwd file */  newgf_fd = mkstemp (passwd_tmp);#ifdef WITH_SELINUX  if (restore_default_context (prev_context) < 0)    {      if (newgf_fd >= 0)	close (newgf_fd);      fclose (oldgf);      retval = -1;      goto error_passwd;    }#endif  if (newgf_fd == -1)    {      fprintf (stderr, _("Can't create `%s': %m\n"),	       passwd_orig);      fclose (oldgf);      retval = -1;      goto error_passwd;    }  if (fchmod (newgf_fd, passwd_stat.st_mode) < 0)    {      fprintf (stderr,	       _("Cannot change permissions for `%s': %s\n"),	       passwd_tmp, strerror (errno));      fclose (oldgf);      close (newgf_fd);      unlink (passwd_tmp);      retval = -1;      goto error_passwd;    }  if (fchown (newgf_fd, passwd_stat.st_uid, passwd_stat.st_gid) < 0)    {      fprintf (stderr,	       _("Cannot change owner/group for `%s': %s\n"),	       passwd_tmp, strerror (errno));      fclose (oldgf);      close (newgf_fd);      unlink (passwd_tmp);      retval = -1;      goto error_passwd;    }  if (copy_xattr (passwd_orig, passwd_tmp) != 0)    {      fclose (oldgf);      close (newgf_fd);      unlink (passwd_tmp);      retval = -1;      goto error_passwd;    }  newgf = fdopen (newgf_fd, "w+");  if (newgf == NULL)    {      fprintf (stderr, _("Can't open `%s': %m\n"), passwd_tmp);      fclose (oldgf);      close (newgf_fd);      unlink (passwd_tmp);      retval = -1;      goto error_passwd;    }  while (ptr != NULL)    {      /* write the passwd entry to tmp file */      if (putpwent (ptr->pwd, newgf) < 0)	goto write_error_passwd;      ptr = ptr->next;    }  /* Check if we have entries starting with +/- and copy     the rest of the passwd file without sorting it. */  if (pwd != NULL)    {      /* write the passwd entry to tmp file */      if (putpwent (pwd, newgf) < 0)	goto write_error_passwd;      while ((pwd = files_getpwent ()))      /* write the passwd entry to tmp file */      if (putpwent (pwd, newgf) < 0)	{	write_error_passwd:	  fprintf (stderr,		   _("Error while writing `%s': %m\n"),                   passwd_tmp);	  fclose (oldgf);	  fclose (newgf);	  retval = -1;	  goto error_passwd;	}    }  if (fclose (oldgf) != 0)    {      fprintf (stderr,	       _("Error while closing `%s': %m\n"), passwd_orig);      fclose (newgf);      retval = -1;      goto error_passwd;    }  if (fclose (newgf) != 0)    {      fprintf (stderr,	       _("Error while closing `%s': %m\n"), passwd_tmp);      retval = -1;      goto error_passwd;    }  unlink (passwd_old);  if (link (passwd_orig, passwd_old) < 0)    fprintf (stderr,	     _("Warning: cannot create backup file `%s': %m\n"),             passwd_old);  rename (passwd_tmp, passwd_orig); error_passwd:  unlink (passwd_tmp);  return retval;}intmain (int argc, char *argv[]){  const char *program = "pwck";  int quiet = 0;  int sort = 0;  setlocale(LC_ALL, "");  bindtextdomain(PACKAGE, LOCALEDIR);  textdomain(PACKAGE);  while (1)    {      int c;      int option_index = 0;      static struct option long_options[] = {	{"path",     required_argument, NULL, 'P'},        {"quiet",    no_argument,       NULL, 'q' },        {"readonly", no_argument,       NULL, 'r' },	{"sort",     no_argument,       NULL, 's' },        {"version",  no_argument,       NULL, 'v' },        {"usage",    no_argument,       NULL, 'u' },        {"help",     no_argument,       NULL, '\255' },        {NULL,       0,                 NULL, '\0'}      };      c = getopt_long (argc, argv, "P:qrsvu",                       long_options, &option_index);      if (c == (-1))        break;      switch (c)	{	case 'P':	  files_etc_dir = strdup (optarg);	  break;	case 'q':	  quiet = 1;	  break;	case 'r':	  readonly = 1;	  break;	case 's':	  sort = 1;	  break;	case '\255':          print_help (program);          return 0;        case 'v':          print_version (program, "2005");          return 0;        case 'u':          print_usage (stdout, program);	  return 0;	default:	  print_error (program);	  return E_USAGE;	}    }  argc -= optind;  argv += optind;  if (argc > 0)    {      fprintf (stderr, _("%s: Too many arguments.\n"), program);      print_error (program);      return E_USAGE;    }  else if (readonly && sort)    {      fprintf (stderr, _("%s: -s and -r are incompatibile.\n"),	       program);      return E_USAGE;    }  if (lock_database () != 0)    {      fprintf (stderr,	       _("Cannot lock password file: already locked.\n"));      return E_PWDBUSY;    }  if (sort)    return sort_passwd_file ();  else    {      int rp, rs;      rp = loop_over_passwd_file (quiet);      rs = loop_over_shadow_file (quiet);      if (rs == 0 || rs == E_NO_FILE)	return rp;      if (rp == 0 || rp == E_NO_FILE)	return rs;      if (rp > rs)	return rp;      else	return rs;    }}

⌨️ 快捷键说明

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