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

📄 useradd.c

📁 pwdutils是一套密码管理工具
💻 C
📖 第 1 页 / 共 3 页
字号:
		{		  if (((expire = strtol (optarg, &cp, 10)) == 0 && *cp) ||		      expire < -1)		    {		      fprintf (stderr,			       _("%s: Expiredate `%s' is no date and no integer value >= -1.\n"),			       program, optarg);		      return E_BAD_ARG;		    }		}	      dflt.expire = expire;	    }	  break;	case 'f':	  {	    long int inactive;	    char *cp;	    inactive = strtol (optarg, &cp, 10);	    if (*cp != '\0')	/* invalid number */	      {		fprintf (stderr, _("%s: Invalid numeric argument `%s' for `-f'.\n"),			 program, optarg);		return E_BAD_ARG;	      }	    dflt.inactive = inactive;	  }	  break;	case 'G':	  /* Only save the arguments for later checking. We can find a	     -P <path> option later.  */	  new_groups_arg = optarg;	  break;	case 'g':	  new_group = optarg;	  break;	case 'k':	  if (access (optarg, F_OK) != 0)	    {	      fprintf (stderr,		       _("%s: Skel directory `%s' does not exist.\n"),		       program, optarg);	      return E_BAD_ARG;	    }	  skeldir = strdup (optarg);	  break;	case 'M':	  /* This is the default: don't create users home dir.	     Ignored for RedHat/PLD useradd compatibility. */	  break;	case 'm':	  create_homedir = 1;	  break;	case 'o':	  non_unique = 1;	  break;	case 'P':	  files_etc_dir = strdup (optarg);	  have_extrapath = 1;	  /* If -P option is used, set use_service to "files" if not	     already set through an option. If we don't limitate to	     service files, we can get trouble finding the right	     source.  */	  if (!use_service)	    use_service = "files";	  break;	case 'p':		/* set encrypted password */	  if (strcspn (optarg, ":\n") != strlen (optarg))	    {	      fprintf (stderr, _("%s: Invalid characters in password `%s'.\n"),		       program, optarg);	      return E_BAD_ARG;	    }	  new_password = optarg;	  break;	case 'r':	  system_account = 1;	  break;	case 's':	  if (strcspn (optarg, ",=\":*\n") != strlen (optarg) ||	      *optarg != '/')	    {	      fprintf (stderr, _("%s: Invalid shell `%s'.\n"),		       program, optarg);	      return E_BAD_ARG;	    }	  new_shell = optarg;	  break;	case 'u':	  if (strtoid (optarg, &new_uid) == -1)	/* invalid number */	    {	      fprintf (stderr, _("%s: Invalid numeric argument `%s' for User ID.\n"),		       program, optarg);	      return E_BAD_ARG;	    }	  know_uid = 1;	  break;	case '\251':	case '\252':	  if (!modify_defaults)	    {	      print_error (program);	      return E_USAGE;	    }	  break;	case '\253':	  if (use_service != NULL)            {              print_usage (stderr, program);              return E_BAD_ARG;            }	  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 '\254':	  print_usage (stdout, program);	  return 0;	default:	  print_error (program);	  return E_USAGE;	}    }  if (new_group)    {      int retval;      gid_t gid;      if ((retval = convert_grpopt_to_name (new_group, NULL,					    &gid, use_service)) != 0)	return retval;      dflt.group = gid;    }  if (new_groups_arg)    {      char *arg = new_groups_arg;      unsigned int errors = 0, i, j;      j = 1;      for (i = 0; i < strlen (arg); i++)	if (arg[i] == ',')	  ++j;      new_groups = malloc (sizeof (char *) * j);      new_groupscnt = 0;      do	{	  char *cp = strchr (arg, ',');	  if (cp)	    *cp++ = '\0';	  if (arg && *arg)	    {	      if (convert_grpopt_to_name (arg,					  &new_groups[new_groupscnt],					  NULL, use_service) != 0)		++errors;	      else		{		  new_groupscnt++;		  if (new_groupscnt > j)		    abort ();		}	    }	  arg = cp;	}      while (arg);      if (errors)	{	  /* XXX This is more a guess than something else.  */	  if (files_etc_dir)	    return E_NOTFOUND;	  else	    return E_BAD_ARG;	}      if (modify_defaults)	{	  dflt.groupscnt = new_groupscnt;	  dflt.groups = new_groups;	}    }  argc -= optind;  argv += optind;  if (argc > 1)    {      fprintf (stderr, _("%s: Too many arguments.\n"), program);      print_error (program);      return E_USAGE;    }  else if (argc == 0 && !modify_defaults)    {      fprintf (stderr, _("%s: Too few arguments.\n"), program);      print_error (program);      return E_USAGE;    }  else if (skeldir && !(create_homedir || modify_defaults))    {      print_usage (stderr, program);      return E_USAGE;    }  else    {      int buflen = 256;      char *buffer = alloca (buflen);      struct passwd resultbuf;      struct passwd *pw;      /* Determine our own user name for PAM 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_UNKNOWN_USER;	}      if (do_authentication (program, pw->pw_name, NULL) != 0)	{	  sec_log (program, MSG_PERMISSION_DENIED, pw->pw_name,                   pw->pw_uid, getuid ());	  return E_NOPERM;	}    }  if (modify_defaults)    {      /* -D option was given and we plan to modify         entries in /etc/default/useradd.  */      if (new_home)	dflt.home = new_home;      if (new_shell)	dflt.shell = new_shell;      if (skeldir)	dflt.skel = skeldir;      if (write_defaults (useradd_default_file, &dflt) != 0)	{	  sec_log (program, MSG_UPDATING_DEFAULT_CONFIG_FAILED,		   useradd_default_file, getuid ());	  fprintf (stderr, _("%s: Writing of `%s' was not successful.\n"),		   program, useradd_default_file);	  return E_LOGIN_DEFS;	}      sec_log (program, MSG_CONFIG_DEFAULTS_CHANGED,	       dflt.group, new_home, dflt.shell, dflt.inactive,	       date2str(DAY*dflt.expire), getuid ());      return E_SUCCESS;    }  /* After this, we can start creating the new account.  */  if (know_uid && !non_unique)    {      if (getpwuid (new_uid) != NULL ||	  (have_extrapath && files_getpwuid (new_uid) != NULL))	{	  sec_log (program, MSG_UID_NOT_UNIQUE, new_uid, getuid ());	  fprintf (stderr, _("%s: UID %u is not unique.\n"),		   program, new_uid);	  return E_UID_IN_USE;	}    }  new_account = argv[0];  if (check_name (new_account) != 0)    {      sec_log (program, MSG_USER_NAME_INVALID,	       new_account, getuid ());      fprintf (stderr, _("%s: Invalid account name `%s'.\n"),	       program, new_account);      return E_BAD_ARG;    }  if (system_account && new_shell == NULL)    new_shell = "/bin/false";  /* Lock passwd file, so that a concurrent useradd process will not     add the user a second time or a second user with the same uid.  */  if ((use_service == NULL || strcmp (use_service, "files") == 0) &&      lock_database () != 0)    {      sec_log (program, MSG_PASSWD_FILE_ALREADY_LOCKED);      fputs (_("Cannot lock password file: already locked.\n"), stderr);      return E_PWDBUSY;    }  else if (getpwnam (new_account) != NULL ||	   (have_extrapath && files_getpwnam (new_account) != NULL))    {				/* User does already exists.  */      sec_log (program, MSG_USER_ALREADY_EXISTS, new_account, getuid ());      fprintf (stderr, _("%s: Account `%s' already exists.\n"),	       program, new_account);      return E_NAME_IN_USE;    }  else    {      user_t pw_data;      char homebuf[strlen (dflt.home) + strlen (new_account) + 2];      char shadowfile[strlen (files_etc_dir) + 8];      char *cp;      unsigned int i;      int retval = E_SUCCESS;      memset (&pw_data, 0, sizeof (pw_data));      /* check if we have shadow support.  */      cp = stpcpy (shadowfile, files_etc_dir);      strcpy (cp, "/shadow");      pw_data.use_shadow = (access (shadowfile, F_OK) == 0);      if (use_service)	{	  if (strcmp (use_service, "files") == 0)	    pw_data.service = S_LOCAL;	  else if (strcmp (use_service, "ldap") == 0)	    pw_data.service = S_LDAP;	}      else	pw_data.service = S_LOCAL;      pw_data.todo = DO_CREATE;      if (new_home == NULL)	{	  snprintf (homebuf, sizeof (homebuf), "%s/%s", dflt.home,		    new_account);	  new_home = homebuf;	}      pw_data.pw.pw_name = new_account;      if (pw_data.use_shadow)	pw_data.pw.pw_passwd = "x";      else	pw_data.pw.pw_passwd = new_password;      pw_data.pw.pw_uid = know_uid ? new_uid : find_free_uid (system_account,							      have_extrapath);      pw_data.pw.pw_gid = dflt.group;      pw_data.pw.pw_gecos = new_comment;      pw_data.pw.pw_dir = new_home;      pw_data.pw.pw_shell = new_shell ? : dflt.shell;      if (pw_data.use_shadow)	{	  pw_data.sp.sp_namp = new_account;	  pw_data.sp.sp_pwdp = new_password;	  pw_data.sp.sp_lstchg = time ((time_t *) 0) / (24L * 3600L);	  pw_data.sp.sp_min = getlogindefs_num ("PASS_MIN_DAYS", -1);	  pw_data.sp.sp_max = getlogindefs_num ("PASS_MAX_DAYS", -1);	  pw_data.sp.sp_warn = getlogindefs_num ("PASS_WARN_AGE", -1);	  pw_data.sp.sp_inact = dflt.inactive;	  pw_data.sp.sp_expire = dflt.expire;	  pw_data.sp.sp_flag = -1;	}      sec_log (program, MSG_NEW_USER_ADDED,	       pw_data.pw.pw_name, (unsigned int) pw_data.pw.pw_uid,	       (unsigned int) pw_data.pw.pw_gid, pw_data.pw.pw_dir,	       pw_data.pw.pw_shell, getuid ());      /* Clear old log entries, but only if this UID is not shared         with another account.  */      if (getpwuid (pw_data.pw.pw_uid) == NULL &&	  (!have_extrapath || files_getpwuid (pw_data.pw.pw_uid) == NULL))	{	  int fd;	  if ((fd = open ("/var/log/faillog", O_RDWR)) >= 0)	    {	      struct faillog fl;	      memset (&fl, 0, sizeof (fl));	      if ((lseek (fd, (off_t) sizeof (fl) * pw_data.pw.pw_uid, SEEK_SET)		   == (off_t)-1) || (write (fd, &fl, sizeof (fl)) == -1))		fprintf (stderr,			 _("%s: Error: Cannot clear old faillog entry: %s\n"),			 program, strerror (errno));	      close (fd);	    }	  if ((fd = open (_PATH_LASTLOG, O_RDWR, 0)) >= 0)	    {	      struct lastlog ll;	      memset (&ll, 0, sizeof (ll));	      if ((lseek (fd, (off_t) sizeof (ll) * pw_data.pw.pw_uid, SEEK_SET)		   == (off_t)-1) || (write (fd, &ll, sizeof (ll)) == -1))		fprintf (stderr,			 _("%s: Error: Cannot clear old lastlog entry: %s\n"),			 program, strerror (errno));	      close (fd);	    }	}#ifdef USE_LDAP      if (pw_data.service == S_LDAP)	{	  if (binddn == NULL)	    {	      binddn = get_caller_dn ();	      if (binddn == NULL)		{		  fprintf (stderr, _("%s: Cannot add user to LDAP database without DN.\n"),			   program);		}	      else pw_data.binddn = strdup (binddn);	    }	  else	    pw_data.binddn = strdup (binddn);	  if (pw_data.oldclearpwd == NULL)	    {	      cp = get_ldap_password (pw_data.binddn);	      if (cp)		pw_data.oldclearpwd = strdup (cp);	      else		{		  fprintf (stderr,			   _("%s: User not added to LDAP database.\n"),			   program);		  return E_FAILURE;		}	    }	}#endif      if (write_user_data (&pw_data, 1) != 0)	return E_FAILURE;      /* If user does not specify extra secondary groups, add the         default one. With one exception: Don't add default extra         groups to system accounts.  */      if (new_groups == NULL && !system_account)	{	  new_groupscnt = dflt.groupscnt;	  new_groups = dflt.groups;	}      for (i = 0; i < new_groupscnt; i++)	{	  group_t *gr_data = find_group_data (new_groups[i], 0, use_service);	  if (gr_data == NULL || gr_data->service == S_NONE)	    {	      if (use_service == NULL)		fprintf (stderr,			 _("%s: ERROR: Cannot find group `%s' anymore!\n"),			 program, new_groups[i]);	      else		fprintf (stderr,			 _("%s: Cannot find group `%s' in service `%s', ignored.\n"),			 program, new_groups[i], use_service);	      retval = E_NOTFOUND;	    }	  else	    {	      gr_data->todo = DO_MODIFY;#ifdef USE_LDAP	      if (gr_data->service == S_LDAP)		{		  if (binddn == NULL)		    {		      binddn = get_caller_dn ();		      if (binddn == NULL)			{			  fprintf (stderr,				   _("%s: Cannot add user to groups stored in LDAP database without DN.\n"),				   program);			}		    }		  if (binddn == NULL)		    {		      fprintf (stderr,			       _("%s: User not added to LDAP group `%s'.\n"),			       program, gr_data->gr.gr_name);		      free_group_t (gr_data);		      retval = E_GRP_UPDATE;		      continue;		    }		   gr_data->binddn = strdup (binddn);		  if (pw_data.oldclearpwd == NULL)		    {		      cp = get_ldap_password (binddn);		      if (cp)			pw_data.oldclearpwd = strdup (cp);		      else			{			  fprintf (stderr,				   _("%s: User not added to LDAP group `%s'.\n"),				   program, gr_data->gr.gr_name);			  free_group_t (gr_data);			  retval = E_GRP_UPDATE;			  continue;			}		    }		  if (pw_data.oldclearpwd)		    gr_data->oldclearpwd = strdup (pw_data.oldclearpwd);		}#endif	      gr_data->new_gr_mem = add_gr_mem (pw_data.pw.pw_name,						gr_data->gr.gr_mem);	      if (write_group_data (gr_data, 1) != 0)		{		  fprintf (stderr,			   _("%s: User not added to LDAP group `%s'.\n"),			   program, gr_data->gr.gr_name);		  retval = E_GRP_UPDATE;		}	      else		{		  sec_log (program, MSG_USER_ADDED_TO_GROUP,			   pw_data.pw.pw_name, gr_data->gr.gr_name,			   gr_data->gr.gr_gid, getuid ());		}	    }	  free_group_t (gr_data);	}#ifdef HAVE_NSCD_FLUSH_CACHE      /* flush NSCD cache, else creating of home directory could fail         because of unknown user.  */      nscd_flush_cache ("passwd");      nscd_flush_cache ("group");#endif      if (use_service == NULL || strcmp (use_service, "files") == 0)	ulckpwdf ();      if (dflt.create_mail_spool)	{	  int ret = create_mail_file (pw_data.pw.pw_name,				      pw_data.pw.pw_uid,				      pw_data.pw.pw_gid);	  if (ret != 0)	    return ret;	  sec_log (program, MSG_MAIL_FILE_CREATED,		   pw_data.pw.pw_name, getuid ());	}      if (create_homedir)	{	  int ret = create_home_directory (new_home, pw_data.pw.pw_uid,					   pw_data.pw.pw_gid,					   skeldir ? : dflt.skel);	  if (ret != 0)	    return ret;	  sec_log (program, MSG_HOME_DIR_CREATED,		   pw_data.pw.pw_name, pw_data.pw.pw_uid, new_home,		   getuid ());	}      i = call_script ("USERADD_CMD", pw_data.pw.pw_name, pw_data.pw.pw_uid,		       pw_data.pw.pw_gid, pw_data.pw.pw_dir, program);      if (i != 0)	{	  fprintf (stderr, _("%s: USERADD_CMD fails with exit code %d.\n"),		   program, i);	  retval = E_FAILURE;	}      return retval;    }  return E_SUCCESS;}

⌨️ 快捷键说明

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