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

📄 chfn.c

📁 pwdutils是一套密码管理工具
💻 C
📖 第 1 页 / 共 2 页
字号:
/* 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.  */#ifdef HAVE_CONFIG_H#include <config.h>#endif#define _GNU_SOURCE#include <pwd.h>#include <wchar.h>#include <ctype.h>#include <errno.h>#include <stdio.h>#include <syslog.h>#include <string.h>#include <wctype.h>#include <signal.h>#include <unistd.h>#include <getopt.h>#include <shadow.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 "utf8conv.h"#include "logindefs.h"#include "error_codes.h"#include "read-files.h"#ifdef USE_LDAP#include "libldap.h"#endif#ifndef _#define _(String) gettext (String)#endifstatic int shadow_chfn = 0;struct fn_info {  char *fullname;  char *roomno;  char *work_phone;  char *home_phone;  char *other;};typedef struct fn_info fn_info;static voidprint_usage_shadow (FILE *stream, const char *program){  fprintf (stream, _("Usage: %s [-f name] [-r room] [-w work_phone]\n       [-h home_phone] [-o other] [-q] [-u] [-v] [user]\n"),	   program);}static voidprint_help_shadow (const char *program){  print_usage_shadow (stdout, program);  fprintf (stdout, _("%s - change user name and information\n\n"),	   program);  fputs (_("  -f full-name   Change your real name\n"), stdout);  fputs (_("  -r room        Change your office room number\n"), stdout);  fputs (_("  -w work_phone  Change your office phone number\n"), stdout);  fputs (_("  -h home_phone  Change your home phone number\n"), stdout);  fputs (_("  -o other       Change the undefined portions of the GECOS field\n"), stdout);  fputs (_("  -q, --quiet    Don't be verbose\n"), stdout);  if (strcmp(program, "chfn") == 0)    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);  if (strcmp(program, "chfn") == 0)    fputs (_("Valid services are: files, nis, nisplus, ldap\n"),	   stdout);}static voidprint_usage_util (FILE *stream, const char *program){  fprintf (stream, _("Usage: %s [-D binddn] [-P path] [-f name] [-o office] [-p office-phone]\n       [-h home-phone][-m other] [-q] [-u] [-v] [user]\n"),	   program);}static voidprint_help_util (const char *program){  print_usage_util (stdout, program);  fprintf (stdout, _("%s - change user name and 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 (_("  -f full-name   Change your real name\n"), stdout);  fputs (_("  -o office      Change your office room number\n"), stdout);  fputs (_("  -p phone       Change your office phone number\n"), stdout);  fputs (_("  -h home-phone  Change your home phone number\n"), stdout);  fputs (_("  -m other       Change the undefined portions of the GECOS field\n"), stdout);  if (strcmp(program, "chfn") == 0)    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);  if (strcmp(program, "chfn") == 0)    fputs (_("Valid services are: files, nis, nisplus, ldap\n"),	   stdout);}static intmay_change_field (int field){  const char *cp;  /* root is always allowed to change everything.  */  if (getuid () == 0)    return 1;  cp = getlogindefs_str ("CHFN_RESTRICT", "");  /* CHFN_RESTRICT specifies exactly which fields may be changed     by regular users.  */  if (!cp)    cp = "";  /*  For backward compatibility, "yes" is equivalent to "rwh",      "no" is equivalent to "frwh".  */  else if (strcmp (cp, "yes") == 0)    cp = "rwh";  else if (strcmp (cp, "no") == 0)    cp = "frwh";  if (strchr (cp, field))    return 1;  return 0;}/* get_fields - change the user's GECOS information interactively   prompt the user for each of the four fields and fill in the fields from   the user's response, or leave alone if nothing was entered.  */static voidget_fields (fn_info *old, fn_info *new){  printf (_("Enter the new value, or press ENTER for the default\n"));  /* Allow the user to abort with Ctrl-C.  */  signal (SIGINT, SIG_DFL);  if (may_change_field ('f'))    new->fullname = get_value (old->fullname, _("Full Name"));  else    printf (_("\tFull Name: %s\n"), old->fullname ?:"");  if (may_change_field ('r'))    new->roomno = get_value (old->roomno, _("Room Number"));  else    printf (_("\tRoom Number: %s\n"), old->roomno ?:"");  if (may_change_field ('w'))    new->work_phone = get_value (old->work_phone, _("Work Phone"));  else    printf (_("\tWork Phone: %s\n"), old->work_phone ?:"");  if (may_change_field ('h'))    new->home_phone = get_value (old->home_phone, _("Home Phone"));  else    printf (_("\tHome Phone: %s\n"), old->home_phone ?:"");  if (getuid() == 0)    new->other = get_value (old->other, _("Other"));  else    printf (_("\tOther: %s\n"), old->other ?:"");  signal (SIGINT, SIG_IGN);}/* parse_passwd () -- take a struct password and fill in the   fields of the struct fn_info.  */static voidparse_passwd (const char *gecos, struct fn_info *info){  if (gecos)    {      char *cp = strdup (gecos);      info->fullname = cp;      cp = strchr (cp, ',');      if (cp) { *cp = 0, cp++; } else return;      info->roomno = cp;      cp = strchr (cp, ',');      if (cp) { *cp = 0, cp++; } else return;      info->work_phone = cp;      cp = strchr (cp, ',');      if (cp) { *cp = 0, cp++; } else return;      info->home_phone = cp;      /*  extra fields contain site-specific information, and       *  can not be changed by this version of chfn.  */      cp = strchr (cp, ',');      if (cp) { *cp = 0, cp++; } else return;      info->other = cp;    }}/* convert a multibye string to a wide character string, so   that we can use iswprint.  */static wchar_t *mbstowcs_alloc (const char *string){  size_t size = strlen (string) + 1;  wchar_t *buf = malloc (size * sizeof (wchar_t));  if (buf == NULL)    return NULL;  size = mbstowcs (buf, string, size);  if (size == (size_t) -1)    return NULL;  buf = realloc (buf, (size + 1) * sizeof (wchar_t));  return buf;}static intcheck_field (const char *program, const char *field, const char *illegal){  wchar_t *wstr = mbstowcs_alloc (field);  wchar_t *willegal = mbstowcs_alloc (illegal);  size_t i;  /* keep /etc/passwd clean. */  for (i = 0; i < wcslen (wstr); i++)    {      wchar_t c = wstr[i];      if (wcschr (willegal, c) != NULL || c == '"' || c == '\n')	{	  printf (_("%s: The characters '%s\"' are not allowed.\n"),		  program, illegal);	  return 1;        }      if (iswcntrl (c))	{	  printf (_("%s: Control characters are not allowed.\n"), program);	  return 1;        }    }  return 0;}intmain (int argc, char *argv[]){  uid_t uid = getuid ();  user_t *pw_data = NULL;  char *use_service = NULL;  char *caller_name = NULL;  char *new_gecos = NULL;  char *locale_name;  int interactive = 1;  fn_info new;  int silent = 0;#ifdef USE_LDAP  char *binddn = NULL;#endif  static struct option long_options_shadow[] = {    {"full-name",   required_argument, NULL, 'f' },    {"room",        required_argument, NULL, 'r' },    {"work-phone",  required_argument, NULL, 'w' },    {"home-phone",  required_argument, NULL, 'h' },    {"other",       required_argument, NULL, 'o' },    {"service",     required_argument, NULL, '\254' },    {"quiet",       no_argument,       NULL, 'q' },    {"version",     no_argument,       NULL, 'v' },    {"usage",       no_argument,       NULL, 'u' },    {"help",        no_argument,       NULL, '\255' },    {NULL,          0,                 NULL, '\0'}  };  static char *optstring_shadow = "f:r:w:h:o:qvu";  static struct option long_options_util[] = {#ifdef USE_LDAP    {"binddn",      required_argument, NULL, 'D' },#endif    {"path",        required_argument, NULL, 'P' },    {"full-name",   required_argument, NULL, 'f' },    {"office",      required_argument, NULL, 'o' },    {"phone",       required_argument, NULL, 'p' },    {"home-phone",  required_argument, NULL, 'h' },    {"other",       required_argument, NULL, 'm' },    {"quiet",       no_argument,       NULL, 'q' },    {"version",     no_argument,       NULL, 'v' },    {"usage",       no_argument,       NULL, 'u' },    {"service",     required_argument, NULL, '\254' },    {"help",        no_argument,       NULL, '\255' },    {NULL,          0,                 NULL, '\0'}  };  static char *optstring_util = "D:P:f:o:p:h:m:qvu";  struct option *long_options;  char *optstring;  char *envstr;  const char *program = basename (argv[0]);  setlocale(LC_ALL, "");  bindtextdomain(PACKAGE, LOCALEDIR);  textdomain(PACKAGE);  if (strcasecmp (program, "ypchfn") == 0)    use_service = "nis";  else if (strcasecmp (program, "chfn") != 0)    {      fprintf (stderr, _("%s: Don't know what I should do.\n"), program);      return 1;    }  openlog (program, LOG_PID, LOG_AUTHPRIV);  /* Before going any further, raise the ulimit and ignore     signals.  */  init_environment ();  envstr = getenv ("SHADOW_CHFN");  if (envstr)    {      if (strcmp (envstr, "0") == 0)	shadow_chfn = 0;      else if (strcmp (envstr, "1") == 0)	shadow_chfn = 1;    }  memset (&new, 0, sizeof (new));  if (shadow_chfn)    {      long_options = long_options_shadow;      optstring = optstring_shadow;    }  else    {      long_options = long_options_util;      optstring = optstring_util;    }  while (1)    {      int c;      int option_index = 0;      c = getopt_long (argc, argv, optstring,		       long_options, &option_index);      if (c == (-1))        break;

⌨️ 快捷键说明

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