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

📄 passwd.c

📁 pwdutils是一套密码管理工具
💻 C
📖 第 1 页 / 共 2 页
字号:
/* 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.  */#if defined(HAVE_CONFIG_H)#include "config.h"#endif#define _GNU_SOURCE#include <pwd.h>#include <time.h>#include <errno.h>#include <stdio.h>#include <stdlib.h>#include <string.h>#include <shadow.h>#include <unistd.h>#include <getopt.h>#include <syslog.h>#include <security/pam_appl.h>#include <security/pam_misc.h>#ifdef WITH_SELINUX#include <selinux/selinux.h>#include <selinux/av_permissions.h>#endif#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"#ifndef GPASSWD_PROGRAM#define GPASSWD_PROGRAM "gpasswd"#endif#ifndef CHFN_PROGRAM#define CHFN_PROGRAM "chfn"#endif#ifndef CHSH_PROGRAM#define CHSH_PROGRAM "chsh"#endif/* How often should we try to lock the passwd database ?  */#define MAX_LOCK_RETRIES 3static struct pam_conv conv = {  misc_conv,  NULL};static longconv2long (const char *param){  long val;  char *cp;  val = strtol (param, &cp, 10);  if (*cp)    return -2;  return val;}static const char *pw_status (const char *pass){  if (*pass == '*' || *pass == '!' || *pass == 'x')    return "LK";  if (*pass == '\0')    return "NP";  return "PS";}static char *date_to_str (time_t t){  static char buf[80];  struct tm *tm;  tm = gmtime (&t);  strftime (buf, sizeof buf, "%m/%d/%Y", tm);  return buf;}static voiddisplay_pw (const struct passwd *pw){  struct spwd *sp;#define DAY (24L*3600L)#define SCALE DAY  sp = getspnam (pw->pw_name);  if (sp)    {      printf ("%s %s %s %ld %ld %ld %ld\n",              sp->sp_namp,              pw_status (sp->sp_pwdp),              date_to_str (sp->sp_lstchg * SCALE),              (sp->sp_min * SCALE) / DAY,              (sp->sp_max * SCALE) / DAY,              (sp->sp_warn * SCALE) / DAY,              (sp->sp_inact * SCALE) / DAY);    }  else    printf ("%s %s\n", pw->pw_name, pw_status (pw->pw_passwd));}/* A conversation function which uses an internally-stored value for * the responses. */static intstdin_conv (int num_msg, const struct pam_message **msgm,	    struct pam_response **response, void *appdata_ptr){  struct pam_response *reply;  int count;  /* Sanity test. */  if (num_msg <= 0)    return PAM_CONV_ERR;  /* Allocate memory for the responses. */  reply = calloc (num_msg, sizeof (struct pam_response));  if (reply == NULL)    return PAM_CONV_ERR;  /* Each prompt elicits the same response. */  for (count = 0; count < num_msg; ++count)    {      reply[count].resp_retcode = 0;      reply[count].resp = strdup (appdata_ptr);    }  /* Set the pointers in the response structure and return. */  *response = reply;  return PAM_SUCCESS;}static voidprint_usage (FILE *stream, const char *program){  fprintf (stream, _("Usage: %s [-f|-g|-s|-k[-q]] [account]\n"), program);  fprintf (stream, _("       %s [-D binddn] [-n min] [-x max] [-w warn] [-i inact] account\n"), program);  fprintf (stream, _("       %s {-l|-u|-d|-S[-a]|-e|-h} account\n"), program);  fprintf (stream, _("       %s --stdin account\n"), program);}static voidprint_help (const char *program){  print_usage (stdout, program);  fprintf (stdout, _("%s - change password information\n\n"), program);  fputs (_("  -f             Change the finger (GECOS) information\n"),         stdout);  fputs (_("  -h             Change the home directory\n"), stdout);  fputs (_("  -s             Change the login shell\n"), stdout);  fputs (_("  -g             Change the group password\n"), stdout);  fputs (_("  -k             Change the password only if expired\n"), stdout);  fputs (_("  -q             Try to be quiet\n"), stdout);  fputs (_("  -S             Show the password attributes\n"), stdout);  fputs (_("  -a             Only with -S, show for all accounts\n"), stdout);  fputs (_("  -d             Delete the password for the named account\n"), stdout);  fputs (_("  -l             Locks the password entry for \"account\"\n"), stdout);  fputs (_("  -u             Try to unlock the password entry for \"account\"\n"), stdout);  fputs (_("  -e             Force the user to change password at next login\n"), stdout);  fputs (_("  -n min         Set minimum field for \"account\"\n"), stdout);  fputs (_("  -x max         Set maximum field for \"account\"\n"), stdout);  fputs (_("  -w warn        Set warn field for \"account\"\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 passwd and shadow file in \"path\"\n"),	 stdout);  fputs (_("  --stdin        Read new password from stdin (root only)\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 are: files, nis, nisplus, ldap\n"), stdout);}static intpasswd_main (const char *program, int argc, char **argv){  int buflen = 256;  char *buffer = alloca (buflen);  struct passwd resultbuf;  struct passwd *pw = NULL;  int admin_only = 0;  int silent = 0;  uid_t uid = getuid ();  user_t *pw_data = NULL;  char *caller_name = NULL;  char *use_service = NULL;  char *binddn = NULL;  int k_flag = 0, a_flag = 0, d_flag = 0, e_flag = 0, h_flag = 0,    i_flag = 0, l_flag = 0, n_flag = 0, u_flag = 0, x_flag = 0,    S_flag = 0, w_flag = 0, P_flag = 0, stdin_flag = 0;  long inact = 0, age_min = 0, age_max = 0, warn = 0;  /* Parse program arguments */  while (1)    {      int c;      int option_index = 0;      static struct option long_options[] =	{	  {"binddn", required_argument, NULL, 'D'},	  {"path", required_argument, NULL, 'P'},	  {"version", no_argument, NULL, '\255'},	  {"usage", no_argument, NULL, '\254'},	  {"help", no_argument, NULL, '\253'},	  {"stdin", no_argument, NULL, '\252'},	  {"service", required_argument, NULL, '\251'},	  {NULL, 0, NULL, '\0'}	};      c = getopt_long (argc, argv, "adD:hlquSekn:x:i:w:P:", long_options,                       &option_index);      if (c == EOF)        break;      switch (c)	{	case 'a':	  a_flag = 1;	  break;        case 'd':          d_flag = 1;          admin_only = 1;          break;	case 'D':	  binddn = optarg;	  break;        case 'e':          e_flag = 1;          admin_only = 1;          break;        case 'h':          h_flag = 1;          admin_only = 1;          break;        case 'i':	  i_flag = 1;          inact = conv2long (optarg);          if (inact <= -2)	    {	      print_error (program);	      return E_BAD_ARG;	    }	  admin_only = 1;          break;        case 'k':          k_flag = 1;  /* ok for users */          break;        case 'l':          l_flag = 1;          admin_only = 1;          break;        case 'n':	  n_flag = 1;          age_min = conv2long (optarg);	  if (age_min <= -2)	    {	      print_error (program);	      return E_BAD_ARG;	    }          admin_only = 1;          break;        case 'q':          silent = 1;  /* ok for users */          break;        case '\251':          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";	  else if (strcasecmp (optarg, "ldap") == 0)	    use_service = "ldap";          else            {              fprintf (stderr, _("Service `%s' not supported.\n"), optarg);              print_usage (stderr, program);              return E_BAD_ARG;            }          break;        case 'x':	  x_flag = 1;          age_max = conv2long (optarg);	  if (age_max <= -2)	    {	      print_error (program);	      return E_BAD_ARG;	    }	  admin_only = 1;          break;        case 'S':          S_flag = 1;  /* ok for users */          break;        case 'u':          u_flag = 1;          admin_only = 1;          break;        case 'w':	  w_flag = 1;          warn = conv2long (optarg);          if (warn <= -2)	    {	      print_error (program);	      return E_BAD_ARG;	    }          admin_only = 1;          break;	case 'P':	  P_flag = 1;	  files_etc_dir = strdup (optarg);	  break;	case '\252':	  stdin_flag = 1;	  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 username or we have -S -a with a     username */  if (argc > 1|| (a_flag && S_flag && argc != 0))    {      fprintf (stderr, _("%s: Too many arguments.\n"), program);      print_error (program);      return E_USAGE;    }  /* For admin only commands we need a user name */  if (argc == 0 && admin_only)    {      fprintf (stderr, _("%s: User argument missing\n"), program);      print_error (program);      return E_USAGE;    }  /* Print a list of all users with status informations.     The -a flag requires -S, no other flags, no username, and     you must be root.  */  if (a_flag)    {      if (admin_only || !S_flag || (argc != 0))	{	  print_error (program);	  return E_USAGE;	}      if (uid != 0)        {          fprintf (stderr, _("%s: Permission denied.\n"), program);	  sec_log (program, MSG_PASSWORD_STATUS_FOR_ALL_DENIED, uid);          return E_NOPERM;        }      sec_log (program, MSG_DISPLAY_PASSWORD_STATUS_FOR_ALL, uid);      setpwent ();      while ((pw = getpwent ()))        display_pw (pw);      endpwent ();

⌨️ 快捷键说明

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