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

📄 gpasswd.c

📁 pwdutils是一套密码管理工具
💻 C
字号:
/* Copyright (C) 2002, 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.  */#if defined(HAVE_CONFIG_H)#include "config.h"#endif#define _GNU_SOURCE#include <grp.h>#include <time.h>#include <errno.h>#include <stdio.h>#include <fcntl.h>#include <stdlib.h>#include <string.h>#include <unistd.h>#include <getopt.h>#include <signal.h>#include <sys/resource.h>#if defined(HAVE_XCRYPT_H)#include <xcrypt.h>#elif defined(HAVE_CRYPT_H)#include <crypt.h>#endif#ifdef HAVE_LIBNSCD_H#include <libnscd.h>#endif#ifndef _#define _(String) gettext (String)#endif#include "i18n.h"#include "group.h"#include "logging.h"#include "logindefs.h"#include "read-files.h"#include "error_codes.h"#include "parse_crypt_arg.h"#define MAX_PASSWD_TRIES 3static voidprint_usage (FILE *stream, const char *program){  fprintf (stream, _("Usage: %s [-r] group\n"), program);}static voidprint_help (const char *program){  print_usage (stdout, program);  fprintf (stdout, _("%s - change group password\n\n"), program);  fputs (_("  -r             Remove the password for this group\n"), stdout);  fputs (_("  --service srv  Use nameservice 'srv'\n"), stdout);  fputs (_("  -D binddn      Use dn \"binddn\" to bind to the LDAP directory\n"),	 stdout);  fputs (_("  -P path        Search group file in \"path\"\n"),	 stdout);  fputs (_("  --help         Give this help list\n"), stdout);  fputs (_("  --usage        Give a short usage message\n"), stdout);  fputs (_("  --version      Print program version\n"), stdout);  fputs (_("Valid services for -r are: files, nis, nisplus, ldap\n"), stdout);}intmain (int argc, char **argv){  const char *program = "gpasswd";  char *group;  const char *crypt_str;  crypt_t use_crypt;  int remove_password = 0;  char *binddn = NULL;  int P_flag = 0;  group_t *gr_data;  char *caller_name;  char *use_service = NULL;  setlocale(LC_ALL, "");  bindtextdomain(PACKAGE, LOCALEDIR);  textdomain(PACKAGE);  open_sec_log (program);  /* Before going any further, raise the ulimit and ignore     signals.  */  init_environment ();  crypt_str = getlogindefs_str ("GROUP_CRYPT", NULL);  if (crypt_str == NULL)    crypt_str = getlogindefs_str ("CRYPT", "des");  use_crypt = parse_crypt_arg (crypt_str);  /* Parse program arguments */  while (1)    {      int c;      int option_index = 0;      static struct option long_options[] =	{	  {"remove", required_argument, NULL, 'r'},	  {"binddn", required_argument, NULL, 'D'},	  {"path", required_argument, NULL, 'P'},	  {"service", required_argument, NULL, '\252'},	  {"version", no_argument, NULL, '\255'},	  {"usage", no_argument, NULL, '\254'},	  {"help", no_argument, NULL, '\253'},	  {NULL, 0, NULL, '\0'}	};      c = getopt_long (argc, argv, "rD:P:", long_options,                       &option_index);      if (c == EOF)        break;      switch (c)	{        case 'D':          binddn = optarg;          break;        case 'r':	  remove_password = 1;          break;        case '\252':          if (use_service != NULL)            {              print_error (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 'P':	  P_flag = 1;	  files_etc_dir = strdup (optarg);	  break;	case '\253':          print_help (program);          return 0;        case '\255':          print_version (program, "2005");          return 0;        case '\254':          print_usage (stdout, program);          return E_USAGE;        default:          print_error (program);          return E_BAD_ARG;        }    }  argc -= optind;  argv += optind;  /* We have more than one groupname. */  if (argc > 1)    {      fprintf (stderr, _("%s: Too many arguments.\n"), program);      print_error (program);      return E_USAGE;    }  /* We need a group name.  */  if (argc == 0)    {      fprintf (stderr, _("%s: Group argument missing.\n"), program);      print_error (program);      return E_USAGE;    }  else    {      int buflen = 256;      char *buffer = alloca (buflen);      struct passwd resultbuf;      struct passwd *pw;      /* Determine our own user name for authentication.  */      while (getpwuid_r (getuid (), &resultbuf, buffer, buflen, &pw) != 0	     && errno == ERANGE)	{	  errno = 0;	  buflen += 256;	  buffer = alloca (buflen);	}      if (!pw)	{	  sec_log (program, MSG_NO_ACCOUNT_FOUND, getuid ());	  fprintf (stderr, _("%s: Cannot determine your user name.\n"),		   program);	  return E_NOPERM;	}      caller_name = strdupa (pw->pw_name);      group = argv[0];      gr_data = find_group_data (group, 0, use_service);      if (gr_data == NULL || gr_data->service == S_NONE)        {          if (use_service)            fprintf (stderr,		     _("%s: Group `%s' is not known to service `%s'.\n"),                     program, group, use_service);          else            fprintf (stderr, _("%s: Unknown group `%s'.\n"), program,		     group);	  sec_log (program, MSG_UNKNOWN_GROUP, group, getuid ());          return E_NOPERM;        }    }  /* Only root is allowed to change password for local groups. */  if ((gr_data->service == S_LOCAL && getuid () != 0) ||      (gr_data->service == S_LDAP && binddn == NULL) ||      (gr_data->service != S_LOCAL && gr_data->service != S_LDAP))    {      sec_log (program, MSG_PERMISSION_DENIED,	       gr_data->gr.gr_name, gr_data->gr.gr_gid, getuid ());      fprintf (stderr, _("%s: Permission denied.\n"), program);      free_group_t (gr_data);      return E_NOPERM;    }  if (remove_password)    {      gr_data->newpassword = strdup ("");    }  else    {      char *p1, *p2;      int try;      sec_log (program, MSG_CHANGING_GROUP_PASSWORD, group, getuid ());      fprintf (stdout, _("Changing the password for group %s.\n"), group);      for (try = 0; try < MAX_PASSWD_TRIES; try++)	{	  p1 = getpass (_("New Password: "));	  if (p1 == NULL || *p1 == '\0')	    {	      fputs ("\n", stderr);	    abort_change:	      sec_log (program, MSG_PASSWORD_CHANGE_ABORTED,		       group, getuid ());	      fprintf (stderr, _("Password change aborted.\n"));	      return E_FAILURE;	    }	  p2 = getpass (_("Re-enter new password: "));	  if (p2 == NULL || *p2 == '\0')	    {	      fputs ("\n", stderr);	      goto abort_change;	    }	  if (strcmp (p1, p2) != 0)	    fprintf (stderr, _("Sorry, passwords do not match.\n"));	  else	    break;	}      if (try == MAX_PASSWD_TRIES)	{	  fprintf (stderr, _("%s: Try again later.\n"), program);	  sec_log (program, MSG_MAX_GROUP_PASSWD_TRIES, group, getuid ());	  goto abort_change;        }      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 (p1) > 8)                p1[8] = '\0';              salt =  make_crypt_salt ("", 0);              if (salt != NULL)                gr_data->newpassword = strdup (crypt_r (p1, salt, &output));              else                {                  fprintf (stderr, _("Cannot create salt for standard crypt"));		  goto abort_change;                }              free (salt);              break;            case BLOWFISH:#if defined(HAVE_CRYPT_GENSALT_RN)	      /* blowfish has a limit of 72 characters */	      if (use_crypt == BLOWFISH && strlen (p1) > 72)		p1[72] = '\0';              salt = make_crypt_salt ("$2a$", 0 /* XXX crypt_rounds */);              if (salt != NULL)                gr_data->newpassword = strdup (crypt_r (p1, salt, &output));              else                {                  fprintf (stderr, _("Cannot create salt for blowfish crypt"));		  goto abort_change;                }              free (salt);              break;#else	      fprintf (stderr,		       _("No support for blowfish compiled in. Using MD5\n"));#endif            case MD5:              /* MD5 has a limit of 127 characters */              if (strlen (p1) > 127)                p1[127] = '\0';              salt = make_crypt_salt ("$1$", 0);              if (salt != NULL)                gr_data->newpassword = strdup (crypt_r (p1, salt, &output));              else                {                  fprintf (stderr, _("Cannot create salt for MD5 crypt"));		  goto abort_change;                }              free (salt);              break;            default:              abort();            }        }    }  gr_data->todo = DO_MODIFY;  if (write_group_data (gr_data, 0) != 0)    {      fprintf (stderr, _("%s: Error changing password.\n"),               program);      sec_log (program, MSG_ERROR_CHANGE_GROUP_PASSWORD, group, getuid ());      free_group_t (gr_data);      return E_FAILURE;    }  if (strcmp(gr_data->newpassword,"") == 0)    {      printf (_("Password removed.\n"));      sec_log (program, MSG_GROUP_PASSWORD_REMOVED, group,               gr_data->gr.gr_gid, getuid ());    }  else    {      printf (_("Password changed.\n"));      sec_log (program, MSG_GROUP_PASSWORD_CHANGED,               group, gr_data->gr.gr_gid, getuid ());    }#ifdef HAVE_NSCD_FLUSH_CACHE  nscd_flush_cache ("group");#endif  free_group_t (gr_data);  return E_SUCCESS;}

⌨️ 快捷键说明

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