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

📄 chpasswd.c

📁 pwdutils是一套密码管理工具
💻 C
字号:
/* Copyright (C) 2003, 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 <fcntl.h>#include <errno.h>#include <stdio.h>#include <string.h>#include <unistd.h>#include <getopt.h>#if defined(HAVE_XCRYPT_H)#include <xcrypt.h>#elif defined(HAVE_CRYPT_H)#include <crypt.h>#endif#include <sys/stat.h>#include <sys/types.h>#ifdef HAVE_LIBNSCD_H#include <libnscd.h>#endif#include "i18n.h"#include "public.h"#include "logging.h"#include "logindefs.h"#include "read-files.h"#include "error_codes.h"#include "parse_crypt_arg.h"#ifdef USE_LDAP#include "libldap.h"#endif /* USE_LDAP */#ifndef _#define _(String) gettext (String)#endifstatic voidprint_usage (FILE *stream, const char *program){  fprintf (stream, _("Usage: %s [-D binddn] [-P path] [-e] [-c des|md5|blowfish] [file]\n"),           program);}static voidprint_help (const char *program){  print_usage (stdout, program);  fprintf (stdout, _("%s - update password entries in batch\n\n"), program);#ifdef USE_LDAP  fputs (_("  -D binddn      Use dn \"binddn\" to bind to the LDAP directory\n"),         stdout);#endif  fputs (_("  -P path        Search passwd and shadow file in \"path\"\n"),         stdout);  fputs (_("  -c, --crypt    Password should be encrypted with DES, MD5 or blowfish\n"),	 stdout);  fputs (_("  -e, --encrypted The passwords are in encrypted form\n"),	 stdout);  fputs (_("  --service srv  Use nameservice 'srv'\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);  fputs (_("Valid services are: files, nis, nisplus, ldap\n"), stdout);}intmain (int argc, char *argv[]){  FILE *input = NULL;  const char *program = "chpasswd";  crypt_t use_crypt;  int encrypted = 0;  char *buf = NULL;  size_t buflen = 0;  unsigned long line = 0, errors = 0;  char *use_service = NULL;#ifdef USE_LDAP  char *oldclearpwd = NULL;  char *binddn = NULL;#endif  setlocale(LC_ALL, "");  bindtextdomain(PACKAGE, LOCALEDIR);  textdomain(PACKAGE);  open_sec_log (program);  use_crypt = parse_crypt_arg (getlogindefs_str ("CRYPT", "des"));  while (1)    {      int c;      int option_index = 0;      static struct option long_options[] = {#ifdef USE_LDAP        {"binddn",  required_argument, NULL, 'D' },#endif        {"path",    required_argument, NULL, 'P' },        {"crypt",   no_argument, NULL, 'c' },        {"encrypt", no_argument, NULL, 'e' },        {"service", required_argument, NULL, '\254' },        {"version", no_argument, NULL, 'v' },        {"usage",   no_argument, NULL, 'u' },        {"help",    no_argument, NULL, '\255' },        {NULL,      0,           NULL, '\0'}      };      c = getopt_long (argc, argv, "D:P:c:evu",                       long_options, &option_index);      if (c == (-1))        break;      switch (c)	{#ifdef USE_LDAP	case 'D':	  binddn = optarg;	  break;#endif	case 'P':	  files_etc_dir = strdup (optarg);          break;	case 'c':	  use_crypt = parse_crypt_arg (optarg);	  break;	case 'e':	  ++encrypted;	  break;        case '\254':          if (use_service != NULL)            {              print_usage (stderr, program);              return E_BAD_ARG;            }          if (strcasecmp (optarg, "yp") == 0 ||              strcasecmp (optarg, "nis") == 0)            use_service = "nis";          else if (strcasecmp (optarg, "nis+") == 0 ||                   strcasecmp (optarg, "nisplus") == 0)            use_service = "nisplus";          else if (strcasecmp (optarg, "files") == 0)            use_service = "files";#ifdef USE_LDAP          else if (strcasecmp (optarg, "ldap") == 0)            use_service = "ldap";#endif          else            {              fprintf (stderr, _("Service `%s' not supported.\n"), optarg);              print_usage (stderr, program);              return E_BAD_ARG;            }	  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)    input = stdin;  else if (argc == 1)    {      input = fopen (argv[0], "r");      if (input == NULL)	{	  fprintf (stderr, "%s: %s: %s\n", program, argv[0],		   strerror (errno));	  return E_BAD_ARG;	}    }  else if (argc > 1)    {      fprintf (stderr, _("%s: Too many arguments.\n"), program);      print_error (program);      return E_USAGE;    }#ifdef USE_LDAP  if (binddn)    {      /* A user tries to change data stored in a LDAP database and	 knows the Manager dn, now we need the password from him.  */      ldap_session_t *session = create_ldap_session (LDAP_PATH_CONF);      char *cp;      if (session == NULL)	return E_FAILURE;      cp = getpass (_("Enter LDAP Password:"));      if (open_ldap_session (session) != 0)	return E_FAILURE;      if (ldap_authentication (session, NULL, binddn, cp) != 0)	return E_NOPERM;      close_ldap_session (session);      oldclearpwd = strdup (cp);    }#endif /* USE_LDAP */  /* Read each line, separating login from the password. The password     entry for each user will be looked up in the appropriate place,     defined through the search order in /etc/nsswitch.conf.  */  while (!feof (input))    {      char *tmp, *cp;      user_t *pw_data;      time_t now;#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 */      ++line;      cp = buf;      if (n < 1)	break;      tmp = strchr (cp, ':');      if (tmp)	*tmp = '\0';      else	{	  fprintf (stderr,_("%s: line %ld: missing new password\n"),		   program, line);	  ++errors;	  continue;	}      pw_data = do_getpwnam (cp, use_service);      if (pw_data == NULL || pw_data->service == S_NONE)	{	  fprintf (stderr, _("%s: line %ld: unknown user %s\n"),		   program, line, cp);	  ++errors;	  continue;	}      cp = tmp+1;      tmp = strchr (cp, '\n');      if (tmp)	*tmp = '\0';      if (encrypted)	pw_data->newpassword = strdup (cp);      else	{          char *salt;	  struct crypt_data output;	  memset (&output, 0, sizeof (output));	  switch (use_crypt)	    {	    case DES:	      /* If we don't support passwords longer 8 characters,		 truncate them */	      if (strlen (cp) > 8)		cp[8] = '\0';	      salt =  make_crypt_salt ("", 0);	      if (salt != NULL)	        pw_data->newpassword = strdup (crypt_r (cp, salt, &output));	      else		{		  fprintf (stderr, _("Cannot create salt for standard crypt"));		  ++errors;		  continue;		}	      free (salt);	      break;	    case MD5:	      /* MD5 has a limit of 127 characters */	      if (strlen (cp) > 127)		cp[127] = '\0';	      salt = make_crypt_salt ("$1$", 0);	      if (salt != NULL)		pw_data->newpassword = strdup (crypt_r (cp, salt, &output));	      else		{		  fprintf (stderr, _("Cannot create salt for MD5 crypt"));		  ++errors;		  continue;		}	      free (salt);	      break;	    case BLOWFISH:#if defined(HAVE_CRYPT_GENSALT_RN)	      /* blowfish has a limit of 72 characters */	      if (use_crypt == BLOWFISH && strlen (cp) > 72)		cp[72] = '\0';	      salt = make_crypt_salt ("$2a$", 0 /* XXX crypt_rounds */);	      if (salt != NULL)		pw_data->newpassword = strdup (crypt_r (cp, salt, &output));	      else		{		  fprintf (stderr, _("Cannot create salt for blowfish crypt"));		  ++errors;		  continue;		}	      free (salt);#endif	      break;	    default:	      abort();	    }	}      time (&now);      pw_data->spn.sp_lstchg = (long int)now / (24L*3600L);      pw_data->sp_changed = TRUE;#ifdef USE_LDAP      /* Add binddn data if user is stored in LDAP database and	 we know the binddn.  */      if (pw_data->service == S_LDAP)	{	  if (binddn)	    pw_data->binddn = strdup (binddn);	  if (oldclearpwd)	    pw_data->oldclearpwd = strdup (oldclearpwd);	}#endif      if (write_user_data (pw_data, 0) != 0)	{	  fprintf (stderr,		   _("%s: line %ld: cannot update password entry\n"),		   program, line);	  ++errors;	  continue;	}      free_user_t (pw_data);    }#ifdef HAVE_NSCD_FLUSH_CACHE  nscd_flush_cache ("passwd");#endif  if (errors)    {      fprintf (stderr, _("%s: errors occured, %ld passwords not updated\n"),	       program, errors);    }  if (input != stdin)    fclose (input);  return E_SUCCESS;}

⌨️ 快捷键说明

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