📄 chage.c
字号:
/* Copyright (C) 2002-2005 Thorsten Kukuk Author: Thorsten Kukuk <kukuk@thkukuk.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 <ctype.h>#include <errno.h>#include <stdio.h>#include <string.h>#include <signal.h>#include <unistd.h>#include <getopt.h>#include <shadow.h>#include <sys/stat.h>#include <sys/resource.h>#ifdef HAVE_LIBNSCD_H#include <libnscd.h>#endif#include "i18n.h"#include "error_codes.h"#include "public.h"#include "logindefs.h"#include "read-files.h"#include "utf8conv.h"#include "logging.h"#ifdef USE_LDAP#include "libldap.h"#endif#define DAY (24L*3600L)#define SCALE DAYstatic voidprint_usage (FILE *stream, const char *program){ fprintf (stream, _("Usage: %s [-D binddn][-P path][-m mindays][-M maxdays][-d lastday][-I inactive][-E expiredate][-W warndays] user\n"), program); fprintf (stream, _(" %s -l user\n"), program);}static voidprint_help (const char *program){ print_usage (stdout, program); fprintf (stdout, _("%s - change user password expiry information\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 (_(" --service srv Use nameservice 'srv'\n"), stdout); fputs (_(" -q, --quiet Don't be verbose\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);}/* Print the time in a human readable format. */static voidprint_date (time_t date){#ifdef HAVE_STRFTIME struct tm *tp; char buf[80]; tp = gmtime (&date); strftime (buf, sizeof buf, "%b %d, %Y", tp); puts (buf);#else struct tm *tp; char *cp; tp = gmtime (&date); cp = asctime (tp); printf ("%6.6s, %4.4s\n", cp + 4, cp + 20);#endif}/* Print the current values of the expiration fields. */static voidprint_shadow_info (user_t *data){ printf (_("Minimum:\t%ld\n"), data->sp.sp_min); printf (_("Maximum:\t%ld\n"), data->sp.sp_max); printf (_("Warning:\t%ld\n"), data->sp.sp_warn); printf (_("Inactive:\t%ld\n"), data->sp.sp_inact); printf (_("Last Change:\t\t")); if (data->sp.sp_lstchg == 0) printf (_("Unknown, password is forced to change at next login\n")); else if (data->sp.sp_lstchg < 0) printf (_("Never\n")); else print_date (data->sp.sp_lstchg * SCALE); printf (_("Password Expires:\t")); if (data->sp.sp_lstchg <= 0 || data->sp.sp_max >= 10000 * (DAY / SCALE) || data->sp.sp_max < 0) printf (_("Never\n")); else print_date (data->sp.sp_lstchg * SCALE + data->sp.sp_max * SCALE); printf (_("Password Inactive:\t")); if (data->sp.sp_lstchg <= 0 || data->sp.sp_inact < 0 || data->sp.sp_max >= 10000 * (DAY / SCALE) || data->sp.sp_max < 0) printf (_("Never\n")); else print_date (data->sp.sp_lstchg * SCALE + (data->sp.sp_max + data->sp.sp_inact) * SCALE); printf (_("Account Expires:\t")); if (data->sp.sp_expire < 0) printf (_("Never\n")); else print_date (data->sp.sp_expire * SCALE);}static intchange_shadow_info (user_t *data){ char *buf, *res, *cp; asprintf (&buf, "%ld", data->sp.sp_min); res = get_value (buf, _("Minimum Password Age")); free (buf); if (res == NULL || ((data->spn.sp_min = strtol (res, &cp, 10)) == 0 && *cp) || data->spn.sp_min < -1) { if (cp && *cp) fprintf (stderr, _("Input is no integer value\n")); else fprintf (stderr, _("Negative numbers are not allowed as input (except -1)\n")); return E_FAILURE; } free (res); asprintf (&buf, "%ld", data->sp.sp_max); res = get_value (buf, _("Maximum Password Age")); free (buf); if (res == NULL || ((data->spn.sp_max = strtol (res, &cp, 10)) == 0 && *cp) || data->spn.sp_max < -1) { if (cp && *cp) fprintf (stderr, _("Input is no integer value\n")); else fprintf (stderr, _("Negative numbers are not allowed as input (except -1)\n")); return E_FAILURE; } free (res); asprintf (&buf, "%ld", data->sp.sp_warn); res = get_value (buf, _("Password Expiration Warning")); free (buf); if (res == NULL || ((data->spn.sp_warn = strtol (res, &cp, 10)) == 0 && *cp) || data->spn.sp_warn < -1) { if (cp && *cp) fprintf (stderr, _("Input is no integer value\n")); else fprintf (stderr, _("Negative numbers are not allowed as input (except -1)\n")); return E_FAILURE; } free (res); asprintf (&buf, "%ld", data->sp.sp_inact); res = get_value (buf, _("Password Inactive")); free (buf); if (res == NULL || ((data->spn.sp_inact = strtol (res, &cp, 10)) == 0 && *cp) || data->spn.sp_inact < -1) return E_FAILURE; buf = date2str (data->sp.sp_lstchg * SCALE); res = get_value (buf, _("Last Password Change (YYYY-MM-DD)")); free (buf); if (res == NULL) return E_FAILURE; else if (strcmp (res, "1969-12-31") == 0 || strcmp (res, "0") == 0 || strcmp (res, "-1") == 0) data->sp.sp_lstchg = -1; else { data->spn.sp_lstchg = str2date (res); free (res); if (data->spn.sp_lstchg == -1) { fprintf (stderr, _("Invalid date\n")); return E_FAILURE; } } buf = date2str (data->sp.sp_expire * SCALE); res = get_value (buf, _("Account Expiration Date (YYYY-MM-DD)")); free (buf); if (res == NULL) return E_FAILURE; else if (strcmp (res, "1969-12-31") == 0 || strcmp (res, "0") == 0 || strcmp (res, "-1") == 0) data->spn.sp_expire = -1; else { data->spn.sp_expire = str2date (res); free (res); if (data->spn.sp_expire == -1) { fprintf (stderr, _("Invalid date\n")); return E_FAILURE; } } return 0;}intmain (int argc, char *argv[]){ const char *program = "chage"; uid_t uid = getuid (); user_t *pw_data = NULL; char *use_service = NULL; char *caller_name = NULL; char *mindays = NULL, *maxdays = NULL, *lastday = NULL, *inactive = NULL; char *expiredate = NULL, *warndays = NULL;#ifdef USE_LDAP char *binddn = NULL;#endif int interactive = 1; int silent = 0; int l_flag = 0; setlocale(LC_ALL, ""); bindtextdomain(PACKAGE, LOCALEDIR); textdomain(PACKAGE); open_sec_log(program); /* Before going any further, raise the ulimit and ignore signals. */ init_environment (); while (1) { int c; int option_index = 0; static struct option long_options[] = { {"mindays", required_argument, NULL, 'm' }, {"maxdays", required_argument, NULL, 'M' }, {"lastday", required_argument, NULL, 'd' }, {"inactive", required_argument, NULL, 'I' }, {"expiredate", required_argument, NULL, 'E' }, {"warndays", required_argument, NULL, 'W' }, {"list", no_argument, NULL, 'l' },#ifdef USE_LDAP {"binddn", required_argument, NULL, 'D' },#endif {"quiet", no_argument, NULL, 'q' }, {"path", required_argument, NULL, 'P' }, {"version", no_argument, NULL, 'v' }, {"usage", no_argument, NULL, 'u' }, {"service", required_argument, NULL, '\254' }, {"help", no_argument, NULL, '\255' }, {NULL, 0, NULL, '\0'} }; c = getopt_long (argc, argv, "lm:M:d:D:I:E:W:P:vuq", long_options, &option_index); if (c == (-1)) break; switch (c) { case 'm': mindays = optarg; interactive = 0; break; case 'M': maxdays = optarg; interactive = 0; break; case 'd': lastday = optarg; interactive = 0; break; case 'I': inactive = optarg; interactive = 0; break; case 'E': expiredate = optarg; interactive = 0; break; case 'W': warndays = optarg; interactive = 0; break;#ifdef USE_LDAP case 'D': binddn = optarg; break;#endif case 'l': l_flag = 1; break; case 'P': if (uid != 0) { sec_log (program, MSG_PATH_ARG_DENIED, uid); fprintf (stderr, _("Only root is allowed to specify another path\n")); return E_NOPERM; } else files_etc_dir = strdup (optarg); break; case 'q': silent = 1; 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;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -