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

📄 pwunconv.c

📁 pwdutils是一套密码管理工具
💻 C
字号:
/* 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 <pwd.h>#include <time.h>#include <fcntl.h>#include <errno.h>#include <stdio.h>#include <unistd.h>#include <string.h>#include <getopt.h>#include <sys/stat.h>#ifdef HAVE_LIBNSCD_H#include <libnscd.h>#endif#include "i18n.h"#include "public.h"#include "logindefs.h"#include "read-files.h"#include "error_codes.h"static voidprint_usage (FILE *stream, const char *program){  fprintf (stream, _("Usage: %s\n"), program);}static voidprint_help (const char *program){  print_usage (stdout, program);  fprintf (stdout, _("%s - convert from shadow account\n\n"),	   program);  fputs (_("  -P path        Search passwd and shadow file in \"path\"\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 struct spwd *files_getspent (void){  enum nss_status status;  static int buflen = 256;  static char *buffer = NULL;  static struct spwd resultbuf;  if (buffer == NULL)    buffer = malloc (buflen);  while ((status = files_getspent_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;}intmain (int argc, char *argv[]){  struct spwd *sp;  char *program;  char *cp;  char *tmppasswd = NULL;  char *shadow_path;  setlocale(LC_ALL, "");  bindtextdomain(PACKAGE, LOCALEDIR);  textdomain(PACKAGE);  /* determine name of binary, which specifies edit mode.  */  program = ((cp = strrchr (*argv, '/')) ? cp + 1 : *argv);  while (1)    {      int c;      int option_index = 0;      static struct option long_options[] = {	{"path",    required_argument, NULL, 'P'},        {"version", no_argument, NULL, 'v' },        {"usage",   no_argument, NULL, 'u' },        {"help",    no_argument, NULL, '\255' },        {NULL,      0,           NULL, '\0'}      };      c = getopt_long (argc, argv, "vuP:",                       long_options, &option_index);      if (c == (-1))        break;      switch (c)	{        case 'P':          files_etc_dir = strdup (optarg);	  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    {      /* Check, if /etc/shadow file exist. If not, exit.  */      char *path;      struct stat st;      if (asprintf (&shadow_path, "%s/shadow", files_etc_dir) < 0)        {          fputs ("running out of memory!\n", stderr);          return E_FAILURE;        }      if (lstat (shadow_path, &st) < 0)	{	  /* ENOENT means, the file does not exist and we have	     to create it. Else report an error and abort.  */	  if (errno == ENOENT)	    {	      fprintf (stderr, _("%s: No shadow file found.\n"),		       program);	      return E_FAILURE;	    }	  else	    {	      fprintf (stderr, _("Can't stat `%s': %m\n"), shadow_path);	      return E_FAILURE;	    }	}      /* Now create a copy of the original passwd file.  */      if (asprintf (&path, "%s/passwd", files_etc_dir) < 0)	{	  fputs ("running out of memory!\n", stderr);	  return E_FAILURE;	}      if (asprintf (&tmppasswd, "%s/passwd.pwunconv", files_etc_dir) < 0)	{	  fputs ("running out of memory!\n", stderr);	  return E_FAILURE;	}      if (link (path, tmppasswd) < 0)	{	  fprintf (stderr, _("Cannot create backup file `%s': %m\n"),		   tmppasswd);	  return E_FAILURE;	}      free (path);    }  /* Step through /etc/shadow and move the password into the passwd     file.  */  while ((sp = files_getspent ()) != NULL)    {      user_t *pw_data = do_getpwnam (sp->sp_namp, NULL);      /* Only change password in passwd file, if we have a	 corresponding passwd entry and this is 'x'.  */      if (pw_data != NULL && pw_data->service != S_NONE &&	  strcmp (pw_data->pw.pw_passwd, "x") == 0)	{	  /* Tell backend to ignore shadow file.  */	  pw_data->use_shadow = 0;	  pw_data->newpassword = strdup (sp->sp_pwdp);	  if (write_user_data (pw_data, 0) != 0)	    {	      fprintf (stderr,		       _("Error while moving password for `%s'.\n"),		       pw_data->pw.pw_name);	      free (pw_data);	      return E_FAILURE;	    }	}      free_user_t (pw_data);    }#ifdef HAVE_NSCD_FLUSH_CACHE  nscd_flush_cache ("passwd");#endif  /* Rename original shadow file to shadow.old.  */  {    char *oldshadow;    if (asprintf (&oldshadow, "%s/shadow.old", files_etc_dir) < 0)      {	fputs ("running out of memory!\n", stderr);	return E_FAILURE;      }    unlink (oldshadow);    rename (shadow_path, oldshadow);    free (oldshadow);    free (shadow_path);  }  /* Rename our own copy to passwd.old. As result, /etc/passwd.old     will have the contents of /etc/passwd when starting this program.  */  if (tmppasswd)    {      char *oldpasswd;      if (asprintf (&oldpasswd, "%s/passwd.old", files_etc_dir) < 0)	{	  fputs ("running out of memory!\n", stderr);	  return E_FAILURE;	}      unlink (oldpasswd);      rename (tmppasswd, oldpasswd);      free (oldpasswd);      free (tmppasswd);    }  return E_SUCCESS;}

⌨️ 快捷键说明

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