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

📄 usermod.c

📁 pwdutils是一套密码管理工具
💻 C
📖 第 1 页 / 共 3 页
字号:
			       utf8_to_locale (new_groups[new_groupscnt]));		      /* return E_BAD_ARG; */		    }		  else		    {		      new_groupscnt++;		      if (new_groupscnt > j)			abort ();		    }		}	    }	  arg = cp;	}      while (arg);      if (errors)	{	  /* This is more a guess than something else.  */	  if (files_etc_dir)	    return E_NOTFOUND;	  else	    return E_BAD_ARG;	}    }  /* Create list of groups, to which we should add this account. -R option.  */  /* XXX merge with new_groups_arg above.  */  if (remove_groups_arg)    {      char *arg = remove_groups_arg;      unsigned int errors = 0, i, j;      j = 1;      for (i = 0; i < strlen (arg); i++)	if (arg[i] == ',')	  ++j;      del_groups = malloc (sizeof (char *) * j);      del_groupscnt = 0;      do	{	  char *cp = strchr (arg, ',');	  if (cp)	    *cp++ = '\0';	  if (arg && *arg)	    {	      gid_t gid;	      if (convert_grpopt_to_name (arg,					  &del_groups[del_groupscnt],					  &gid, use_service) != 0)		++errors;	      else		{		  del_groupscnt++;		  if (del_groupscnt > j)		    abort ();		}	    }	  arg = cp;	}      while (arg);      if (errors)	{	  /* This is more a guess than something else.  */	  if (files_etc_dir)	    return E_NOTFOUND;	  else	    return E_BAD_ARG;	}    }  /* Check if user is logged in.  */  if ((new_login || know_uid || new_home) &&      is_logged_in (modify_account))    {      sec_log (program, MSG_ACCOUNT_IN_USE, modify_account,	       pw_data->pw.pw_uid, getuid ());      fprintf (stderr, _("%s: Account `%s' is currently in use.\n"),	       program, utf8_to_locale (modify_account));      return E_USER_BUSY;    }  /* After this, we can start modifying the existing account.  */  if (know_uid != NULL && !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;	}    }  /* If account should be renamed, check that the new name is valid     and does not already exist.  */  if (new_login)    {      if (check_name (new_login) != 0)	{	  sec_log (program, MSG_USER_NAME_INVALID,		   new_login, getuid ());	  fprintf (stderr, _("%s: Invalid account name `%s'.\n"),		   program, utf8_to_locale (new_login));	  return E_BAD_ARG;	}      else	{	  if (getpwnam (new_login) != NULL ||	      (have_extrapath && files_getpwnam (new_login) != NULL))	    {	      sec_log (program, MSG_USER_ALREADY_EXISTS,		       new_login, getuid ());	      fprintf (stderr, _("%s: Account `%s' already exists.\n"),		       program, utf8_to_locale (new_login));	      return E_NAME_IN_USE;	    }	}    }  /* Lock passwd file, so that a concurrent usermod 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 (new_login || new_password || know_uid || new_group ||	   new_comment || new_home || new_shell || know_inactive ||	   know_expire)    {      /* Only change passwd/shadow file if there are really changes.  */      pw_data->todo = DO_MODIFY;      if (new_login)	pw_data->new_name = strdup (new_login);      if (know_uid)	{	  pw_data->have_new_uid = 1;	  pw_data->new_uid = new_uid;	}      if (new_group)	{	  pw_data->have_new_gid = 1;	  pw_data->new_gid = new_gid;	}      if (new_comment)	pw_data->new_gecos = strdup (new_comment);      if (new_home)	pw_data->new_home = strdup (new_home);      if (new_shell)	pw_data->new_shell = strdup (new_shell);      if (know_inactive || know_expire)	{	  if (pw_data->use_shadow)	    {	      pw_data->spn = pw_data->sp;	      pw_data->sp_changed = 1;	      if (know_inactive)		pw_data->spn.sp_inact = new_inactive;	      if (know_expire)		pw_data->spn.sp_expire = new_expire;	    }	  else	    {	      fprintf (stderr,		       _("%s: Shadow passwords required for -e and -f.\n"),		       program);	      return E_NO_SHADOW;	    }	}      if (new_password)	{	  pw_data->newpassword = strdup (new_password);	  if (pw_data->use_shadow)	    {	      pw_data->spn.sp_lstchg = time ((time_t *) 0) / SCALE;	      pw_data->sp_changed = 1;	    }	}#ifdef USE_LDAP      if (pw_data->service == S_LDAP)	{	  if (binddn == NULL)	    {	      binddn = get_caller_dn ();	      if (binddn == NULL)		{		  fprintf (stderr,			   _("%s: Cannot modify user in LDAP database without DN.\n"),			   program);		}	      else		pw_data->binddn = strdup (binddn);	    }	  else	    pw_data->binddn = strdup (binddn);	  if (pw_data->oldclearpwd == NULL)	    {	      char *cp = get_ldap_password (pw_data->binddn);	      if (cp)		pw_data->oldclearpwd = strdup (cp);	      else		{		  fprintf (stderr,			   _("%s: User not modified in LDAP database.\n"),			   program);		  return E_FAILURE;		}	    }	}#endif      if (write_user_data (pw_data, 1) != 0)	{	  sec_log (program, MSG_ERROR_MODIFYING_USER,		   pw_data->pw.pw_name, pw_data->pw.pw_uid,		   getuid())	    return E_FAILURE;	}      else	{	  if (new_login)	    sec_log (program, MSG_USER_NAME_CHANGED,		     pw_data->new_name, pw_data->pw.pw_name,		     pw_data->pw.pw_uid, getuid ());	  if (new_password)	    sec_log (program, MSG_PASSWORD_CHANGED,		     pw_data->pw.pw_name, pw_data->pw.pw_uid, getuid ());	  if (pw_data->new_uid)	    sec_log (program, MSG_USER_ID_CHANGED,		     pw_data->pw.pw_name, pw_data->new_uid,		     pw_data->pw.pw_uid, getuid ());	  if (new_comment)	    sec_log (program, MSG_GECOS_CHANGED,		     pw_data->pw.pw_name, pw_data->pw.pw_uid,		     pw_data->new_gecos, pw_data->pw.pw_gecos, getuid ());	  if (new_group)	    sec_log (program, MSG_PRIMARY_GROUP_CHANGED,		     pw_data->pw.pw_name, pw_data->pw.pw_uid, pw_data->new_gid,		     pw_data->pw.pw_gid , getuid ());	  if (new_home)	    sec_log (program, MSG_HOME_DIR_CHANGED,		     pw_data->pw.pw_name, pw_data->pw.pw_uid,		     pw_data->new_home, pw_data->pw.pw_dir, getuid ());	  if (new_shell)	    sec_log (program, MSG_SHELL_CHANGED,		     pw_data->pw.pw_name, pw_data->pw.pw_uid,		     pw_data->new_shell, pw_data->pw.pw_shell, getuid ());	  if (know_inactive)	    sec_log (program, MSG_INACTIVE_DAYS_CHANGED,		     pw_data->pw.pw_name, pw_data->pw.pw_uid,		     pw_data->spn.sp_inact, pw_data->sp.sp_inact, getuid ());	  if (know_expire)	    sec_log (program, MSG_EXPIRE_DATE_CHANGED,		     pw_data->pw.pw_name, pw_data->pw.pw_uid,		     date2str(DAY*pw_data->spn.sp_expire),		     date2str(DAY*pw_data->sp.sp_expire), getuid ());        }#ifdef HAVE_NSCD_FLUSH_CACHE      /* flush NSCD cache, else later calls could get obsolete data.  */      nscd_flush_cache ("passwd");#endif    }  /* Change the login name in group entries, too.     But only, if we don't need to remove them all later.  */  if (new_login && (new_groups_arg == NULL || new_groupscnt == 0))    {      if (rename_in_secondary_groups (pw_data, have_extrapath) != 0)	retval = E_FAILURE;      /* Make sure, written group changes will be active now.  */#ifdef HAVE_NSCD_FLUSH_CACHE      nscd_flush_cache ("group");#endif    }  /* Now we need to change the group file (-G/-A option).  */  if (new_groups_arg || add_groups_arg)    {      unsigned int i;      int ret;      if (new_groups_arg)	{	  /* Remove user from all groups. */	  if (new_login)	    ret = remove_from_secondary_groups (pw_data, have_extrapath,						new_login);	  else	    ret = remove_from_secondary_groups (pw_data, have_extrapath,						pw_data->pw.pw_name);	  if (ret != 0)	    retval = ret;	}      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, utf8_to_locale (new_groups[i]));	      else		fprintf (stderr,			 _("%s: Cannot find group `%s' in service `%s', ignored.\n"),			 program, utf8_to_locale (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,			       utf8_to_locale (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)		    {		      char *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,				   utf8_to_locale (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 (modify_account,						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,			   utf8_to_locale (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 ());		}	      /* Make sure, written group changes will be active now.  */#ifdef HAVE_NSCD_FLUSH_CACHE	      nscd_flush_cache ("group");#endif	    }	  free_group_t (gr_data);	}    }  /* Now we need to change the group file (-R option).  */  /* XXX merge with above.  */  if (remove_groups_arg)    {      unsigned int i;      for (i = 0; i < del_groupscnt; i++)	{	  group_t *gr_data = find_group_data (del_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, utf8_to_locale (del_groups[i]));	      else		fprintf (stderr,			 _("%s: Cannot find group `%s' in service `%s', ignored.\n"),			 program, utf8_to_locale (del_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 remove user from groups stored in LDAP database without DN.\n"),				   program);			}		    }		  if (binddn == NULL)		    {		      fprintf (stderr,			       _("%s: User not removed from LDAP group `%s'.\n"),			       program,			       utf8_to_locale (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)		    {		      char *cp = get_ldap_password (binddn);		      if (cp)			pw_data->oldclearpwd = strdup (cp);		      else			{			  fprintf (stderr,				   _("%s: User not removed from LDAP group `%s'.\n"),				   program,				   utf8_to_locale (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 = remove_gr_mem (modify_account,						   gr_data->gr.gr_mem);	      if (write_group_data (gr_data, 1) != 0)		{		  fprintf (stderr,			   _("%s: User not removed from LDAP group `%s'.\n"),			   program,			   utf8_to_locale (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 ());		}	      /* Make sure, written group changes will be active now.  */#ifdef HAVE_NSCD_FLUSH_CACHE	      nscd_flush_cache ("group");#endif	    }	  free_group_t (gr_data);	}    }  if (move_homedir)    if (move_home_directory (old_home, new_home) != 0)      retval = E_FAILURE;  /* If UID has changed, change the UID of the homedirectory, too.  */  if (know_uid)    {      int fd;      int ret;      char *home = new_home ? new_home : old_home;      /* Only change the UID of the home directory, if it exist.	 Else ignore it.  */      if (access (home, F_OK) == 0)	{	  /* If know_uid is set, change UID on filesystem of file	     in the home directory.  */	  ret = chown_dir_rec (home, pw_data->pw.pw_uid, new_uid,			       pw_data->pw.pw_gid,			       new_group ? new_gid : pw_data->pw.pw_gid);	  if (ret != 0)	    retval = E_FAILURE;	}      /* Relocate the "lastlog/faillog" entries for the user. */      if ((fd = open ("/var/log/faillog", O_RDWR)) >= 0)	{	  struct faillog fl;	  if (lseek (fd, (off_t) sizeof (fl) * pw_data->pw.pw_uid, SEEK_SET)	      == (off_t) -1)	    {	      fprintf (stderr, _("%s: Error: Cannot copy faillog entry: %s\n"),		       program, strerror (errno));	      retval = E_FAILURE;	    }	  else	    if (read (fd, &fl, sizeof (fl)) == sizeof (fl))	      {		if ((lseek (fd, (off_t) sizeof (fl) * new_uid, SEEK_SET)		     == (off_t) -1) || (write (fd, &fl, sizeof (fl)) == -1))		  {		    fprintf (stderr,			     _("%s: Error: Cannot copy faillog entry: %s\n"),			    program, strerror (errno));		    retval = E_FAILURE;		  }	      }	  close (fd);	}      if ((fd = open (_PATH_LASTLOG, O_RDWR, 0)) >= 0)	{	  struct lastlog ll;	  if (lseek (fd, (off_t) sizeof (ll) * pw_data->pw.pw_uid, SEEK_SET)	      == (off_t) -1)	    {	      fprintf (stderr, _("%s: Error: Cannot copy lastlog entry: %s\n"),		       program, strerror (errno));	      retval = E_FAILURE;	    }	  else	    if (read (fd, &ll, sizeof ll) == sizeof ll)	      {		if ((lseek (fd, (off_t) sizeof (ll) * new_uid, SEEK_SET)		     == (off_t) -1) || (write (fd, &ll, sizeof (ll)) == -1))		  {		    fprintf (stderr,			     _("%s: Error: Cannot copy faillog entry: %s\n"),			     program, strerror (errno));		    retval = E_FAILURE;		  }	      }	  close (fd);	}    }  if (use_service == NULL || strcmp (use_service, "files") == 0)    ulckpwdf ();  return retval;}

⌨️ 快捷键说明

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