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

📄 passwd.c

📁 cygwin, 著名的在win32下模拟unix操作系统的东东
💻 C
字号:
/* passwd.c: Changing passwords and managing account information   Copyright 1999, 2000, 2001, 2002 Red Hat, Inc.   Written by Corinna Vinschen <corinna.vinschen@cityweb.de>This file is part of Cygwin.This software is a copyrighted work licensed under the terms of theCygwin license.  Please consult the file "CYGWIN_LICENSE" fordetails. */#include <windows.h>#include <wininet.h>#include <lmaccess.h>#include <lmerr.h>#include <lmcons.h>#include <lmapibuf.h>#include <stdio.h>#include <stdlib.h>#include <string.h>#include <unistd.h>#include <getopt.h>#include <pwd.h>#include <sys/cygwin.h>#include <sys/types.h>#include <time.h>#define USER_PRIV_ADMIN		 2#define UF_LOCKOUT            0x00010static const char version[] = "$Revision: 1.4 $";static char *prog_name;static struct option longopts[] ={  {"help", no_argument, NULL, 'h' },  {"inactive", required_argument, NULL, 'i'},  {"lock", no_argument, NULL, 'l'},  {"minage", required_argument, NULL, 'n'},  {"unlock", no_argument, NULL, 'u'},  {"version", no_argument, NULL, 'v'},  {"maxage", required_argument, NULL, 'x'},  {"length", required_argument, NULL, 'L'},  {"status", no_argument, NULL, 'S'},  {NULL, 0, NULL, 0}};static char opts[] = "L:x:n:i:luShv";inteprint (int with_name, const char *fmt, ...){  va_list ap;  if (with_name)    fprintf(stderr, "%s: ", prog_name);  va_start (ap, fmt);  vfprintf (stderr, fmt, ap);  va_end (ap);  fprintf(stderr, "\n");  return 1;}intEvalRet (int ret, const char *user){  switch (ret)    {    case NERR_Success:      return 0;    case ERROR_ACCESS_DENIED:      if (! user)        eprint (0, "You may not change password expiry information.");      else        eprint (0, "You may not change the password for %s.", user);      break;      eprint (0, "Bad password: Invalid.");      break;    case NERR_PasswordTooShort:      eprint (0, "Bad password: Too short.");      break;    case NERR_UserNotFound:      eprint (1, "unknown user %s", user);      break;    case ERROR_INVALID_PASSWORD:    case NERR_BadPassword:      eprint (0, "Incorrect password for %s.", user);      eprint (0, "The password for %s is unchanged.", user);      break;    default:      eprint (1, "unrecoverable error %d", ret);      break;    }  return 1;}PUSER_INFO_3GetPW (char *user, int print_win_name){  char usr_buf[UNLEN + 1];  WCHAR name[2 * (UNLEN + 1)];  DWORD ret;  PUSER_INFO_3 ui;  struct passwd *pw;  char *domain = (char *) alloca (INTERNET_MAX_HOST_NAME_LENGTH + 1);       /* Try getting a Win32 username in case the user edited /etc/passwd */  if ((pw = getpwnam (user)))    {      cygwin_internal (CW_EXTRACT_DOMAIN_AND_USER, pw, domain, usr_buf);      if (strcasecmp (pw->pw_name, usr_buf))	{	  /* Hack to avoid problem with LookupAccountSid after impersonation */	  if (strcasecmp (usr_buf, "SYSTEM"))	    {	      user = usr_buf;	      if (print_win_name)		printf ("Windows username : %s\n", user);	    }	}    }  MultiByteToWideChar (CP_ACP, 0, user, -1, name, 2 * (UNLEN + 1));  ret = NetUserGetInfo (NULL, name, 3, (LPBYTE *) &ui);  return EvalRet (ret, user) ? NULL : ui;}intChangePW (const char *user, const char *oldpwd, const char *pwd, int justcheck){  WCHAR name[2 * (UNLEN + 1)], oldpass[512], pass[512];  DWORD ret;  MultiByteToWideChar (CP_ACP, 0, user, -1, name, 2 * (UNLEN + 1));  MultiByteToWideChar (CP_ACP, 0, pwd, -1, pass, 512);  if (! oldpwd)    {      USER_INFO_1003 ui;      ui.usri1003_password = pass;      ret = NetUserSetInfo (NULL, name, 1003, (LPBYTE) &ui, NULL);    }  else    {      MultiByteToWideChar (CP_ACP, 0, oldpwd, -1, oldpass, 512);      ret = NetUserChangePassword (NULL, name, oldpass, pass);    }  if (justcheck && ret != ERROR_INVALID_PASSWORD)    return 0;  if (! EvalRet (ret, user) && ! justcheck)    {      eprint (0, "Password changed.");    }  return ret;}voidPrintPW (PUSER_INFO_3 ui){  time_t t = time (NULL) - ui->usri3_password_age;  int ret;  PUSER_MODALS_INFO_0 mi;  printf ("Account disabled : %s", (ui->usri3_flags & UF_ACCOUNTDISABLE)                                ? "yes\n" : "no\n");  printf ("Password required: %s", (ui->usri3_flags & UF_PASSWD_NOTREQD)                                ? "no\n" : "yes\n");  printf ("Password expired : %s", (ui->usri3_password_expired)                                ? "yes\n" : "no\n");  printf ("Password changed : %s", ctime(&t));  ret = NetUserModalsGet (NULL, 0, (LPBYTE *) &mi);  if (! ret)    {      if (mi->usrmod0_max_passwd_age == TIMEQ_FOREVER          || ui->usri3_priv == USER_PRIV_ADMIN)        mi->usrmod0_max_passwd_age = 0;      if (mi->usrmod0_min_passwd_age == TIMEQ_FOREVER          || ui->usri3_priv == USER_PRIV_ADMIN)        mi->usrmod0_min_passwd_age = 0;      if (mi->usrmod0_force_logoff == TIMEQ_FOREVER          || ui->usri3_priv == USER_PRIV_ADMIN)        mi->usrmod0_force_logoff = 0;      if (ui->usri3_priv == USER_PRIV_ADMIN)        mi->usrmod0_min_passwd_len = 0;      printf ("Max. password age %ld days\n",              mi->usrmod0_max_passwd_age / ONE_DAY);      printf ("Min. password age %ld days\n",              mi->usrmod0_min_passwd_age / ONE_DAY);      printf ("Force logout after %ld days\n",              mi->usrmod0_force_logoff / ONE_DAY);      printf ("Min. password length: %ld\n",              mi->usrmod0_min_passwd_len);    }}intSetModals (int xarg, int narg, int iarg, int Larg){  int ret;  PUSER_MODALS_INFO_0 mi;  ret = NetUserModalsGet (NULL, 0, (LPBYTE *) &mi);  if (! ret)    {      if (xarg == 0)	mi->usrmod0_max_passwd_age = TIMEQ_FOREVER;      else if (xarg > 0)	mi->usrmod0_max_passwd_age = xarg * ONE_DAY;      if (narg == 0)	{	  mi->usrmod0_min_passwd_age = TIMEQ_FOREVER;	  mi->usrmod0_password_hist_len = 0;	}      else if (narg > 0)	mi->usrmod0_min_passwd_age = narg * ONE_DAY;      if (iarg == 0)	mi->usrmod0_force_logoff = TIMEQ_FOREVER;      else if (iarg > 0)	mi->usrmod0_force_logoff = iarg * ONE_DAY;      if (Larg >= 0)	mi->usrmod0_min_passwd_len = Larg;      ret = NetUserModalsSet (NULL, 0, (LPBYTE) mi, NULL);      NetApiBufferFree (mi);    }  return EvalRet (ret, NULL);}static voidusage (FILE * stream, int status){  fprintf (stream, ""  "Usage: %s (-l|-u|-S) [USER]\n"  "       %s [-i NUM] [-n MINDAYS] [-x MAXDAYS] [-L LEN]\n"  "\n"  "User operations:\n"  " -l, --lock      lock USER's account\n"  " -u, --unlock    unlock USER's account\n"  " -S, --status    display password status for USER (locked, expired, etc.)\n"  "\n"  "System operations:\n"  " -i, --inactive  set NUM of days before inactive accounts are disabled\n"  "                 (inactive accounts are those with expired passwords)\n"  " -n, --minage    set system minimum password age to MINDAYS\n"  " -x, --maxage    set system maximum password age to MAXDAYS\n"  " -L, --length    set system minimum password length to LEN\n"  "\n"  "Other options:\n"  " -h, --help      output usage information and exit\n"  " -v, --version   output version information and exit\n"  "", prog_name, prog_name);  exit (status);}static voidprint_version (){  const char *v = strchr (version, ':');  int len;  if (!v)    {      v = "?";      len = 1;    }  else    {      v += 2;      len = strchr (v, ' ') - v;    }  printf ("\%s (cygwin) %.*s\n\Password Utility\n\Copyright 1999, 2000, 2001, 2002 Red Hat, Inc.\n\Compiled on %s\n\", prog_name, len, v, __DATE__);}intmain (int argc, char **argv){  char *c;  char user[64], oldpwd[64], newpwd[64];  int ret = 0;  int cnt = 0;  int opt;  int Larg = -1;  int xarg = -1;  int narg = -1;  int iarg = -1;  int lopt = 0;  int uopt = 0;  int Sopt = 0;  PUSER_INFO_3 ui, li;  prog_name = strrchr (argv[0], '/');  if (prog_name == NULL)    prog_name = strrchr (argv[0], '\\');  if (prog_name == NULL)    prog_name = argv[0];  else    prog_name++;  c = strrchr (prog_name, '.');  if (c)    *c = '\0';  while ((opt = getopt_long (argc, argv, opts, longopts, NULL)) != EOF)    switch (opt)      {      case 'h':	usage (stdout, 0);        break;      case 'i':	if ((iarg = atoi (optarg)) < 0 || iarg > 999)	  return eprint (1, "Force logout time must be between 0 and 999.");        break;      case 'l':	if (xarg >= 0 || narg >= 0 || iarg >= 0 || Larg >= 0 || uopt || Sopt)	  usage (stderr, 1);	lopt = 1;        break;      case 'n':	if ((narg = atoi (optarg)) < 0 || narg > 999)	  return eprint (1, "Minimum password age must be between 0 and 999.");	if (xarg >= 0 && narg > xarg)	  return eprint (1, "Minimum password age must be less than "	                    "maximum password age.");        break;      case 'u':	if (xarg >= 0 || narg >= 0 || iarg >= 0 || Larg >= 0 || lopt || Sopt)	  usage (stderr, 1);	uopt = 1;        break;      case 'v':	print_version ();        exit (0);        break;      case 'x':	if ((xarg = atoi (optarg)) < 0 || xarg > 999)	  return eprint (1, "Maximum password age must be between 0 and 999.");	if (narg >= 0 && xarg < narg)	  return eprint (1, "Maximum password age must be greater than "	                    "minimum password age.");        break;      case 'L':	if ((Larg = atoi (optarg)) < 0 || Larg > LM20_PWLEN)	  return eprint (1, "Minimum password length must be between "	                    "0 and %d.", LM20_PWLEN);        break;      case 'S':	if (xarg >= 0 || narg >= 0 || iarg >= 0 || Larg >= 0 || lopt || uopt)	  usage (stderr, 1);	Sopt = 1;        break;      default:        usage (stderr, 1);      }  if (Larg >= 0 || xarg >= 0 || narg >= 0 || iarg >= 0)    {      if (optind < argc)        usage (stderr, 1);      return SetModals (xarg, narg, iarg, Larg);    }  strcpy (user, optind >= argc ? getlogin () : argv[optind]);  li = GetPW (getlogin (), 0);  if (! li)    return 1;  ui = GetPW (user, 1);  if (! ui)    return 1;  if (lopt || uopt || Sopt)    {      if (li->usri3_priv != USER_PRIV_ADMIN)        return eprint (0, "You have no maintenance privileges.");      if (lopt)        {	  if (ui->usri3_priv == USER_PRIV_ADMIN)	    return eprint (0, "Locking an admin account is disallowed.");          ui->usri3_flags |= UF_ACCOUNTDISABLE;        }      if (uopt)        ui->usri3_flags &= ~UF_ACCOUNTDISABLE;      if (lopt || uopt)	{          ret = NetUserSetInfo (NULL, ui->usri3_name, 3, (LPBYTE) ui, NULL);          return EvalRet (ret, NULL);	}      // Sopt      PrintPW (ui);      return 0;    }  if (li->usri3_priv != USER_PRIV_ADMIN && strcmp (getlogin (), user))    return eprint (0, "You may not change the password for %s.", user);  eprint (0, "Enter the new password (minimum of 5, maximum of 8 characters).");  eprint (0, "Please use a combination of upper and lower case letters and numbers.");  oldpwd[0] = '\0';  if (li->usri3_priv != USER_PRIV_ADMIN)    {      strcpy (oldpwd, getpass ("Old password: "));      if (ChangePW (user, oldpwd, oldpwd, 1))        return 1;    }  do    {      strcpy (newpwd, getpass ("New password: "));      if (strcmp (newpwd, getpass ("Re-enter new password: ")))        eprint (0, "Password is not identical.");      else if (! ChangePW (user, *oldpwd ? oldpwd : NULL, newpwd, 0))        ret = 1;      if (! ret && cnt < 2)        eprint (0, "Try again.");    }  while (! ret && ++cnt < 3);  return ! ret;}

⌨️ 快捷键说明

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