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

📄 userdel.c

📁 pwdutils是一套密码管理工具
💻 C
📖 第 1 页 / 共 2 页
字号:
/* Copyright (C) 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 <time.h>#include <utmp.h>#include <fcntl.h>#include <paths.h>#include <ctype.h>#include <errno.h>#include <stdio.h>#include <getopt.h>#include <unistd.h>#include <string.h>#include <signal.h>#include <libgen.h>#include <sys/resource.h>#ifdef HAVE_LIBNSCD_H#include <libnscd.h>#endif#ifdef USE_LDAP#include "libldap.h"#endif#include "i18n.h"#include "public.h"#include "group.h"#include "logging.h"#include "logindefs.h"#include "read-files.h"#include "error_codes.h"static voidprint_usage (FILE *stream, const char *program){  fprintf (stream, _("Usage: %s [-D binddn] [-P path] [-r [-f]] user\n"), program);}static voidprint_help (const char *program){  print_usage (stdout, program);  fprintf (stdout, _("%s - delete a user and related files\n\n"), program);  fputs (_("  -r             Remove home directory and mail spool\n"),	 stdout);  fputs (_("  -f             Force removel of files, even if not owned by user\n"),	 stdout);#ifdef USE_LDAP  fputs (_("  -D binddn      Use dn \"binddn\" to bind to the LDAP directory\n"),         stdout);#endif  fputs (_("  -P path        Search passwd, shadow and group file in \"path\"\n"),	 stdout);  fputs (_(" --service srv   Add account to 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);  fputs (_("Valid services for --service are: files, ldap\n"), stdout);}static const char *program = "userdel";static struct option long_options[] = {#ifdef USE_LDAP  {"binddn",      required_argument, NULL, 'D' },#endif  {"force",       no_argument,       NULL, 'f'},  {"remove-home", no_argument,       NULL, 'r'},  {"path",        required_argument, NULL, 'P'},  {"version",     no_argument,       NULL, 'v'},  {"service",     required_argument, NULL, '\253'},  {"usage",       no_argument,       NULL, 'u'},  {"help",        no_argument,       NULL, '\255'},  {NULL, 0, NULL, '\0'}};static const char *short_options = "D:frP:uv";static intis_owned_by (const char *path, uid_t uid){  struct stat st;  if (lstat (path, &st) != 0)    return -1;  return (st.st_uid == uid);}static struct passwd *files_getpwent (void){  enum nss_status status;  static int buflen = 256;  static char *buffer = NULL;  static struct passwd resultbuf;  if (buffer == NULL)    buffer = malloc (buflen);  while ((status = files_getpwent_r (&resultbuf, buffer, buflen, &errno))	 == NSS_STATUS_TRYAGAIN && errno == ERANGE)    {      errno = 0;      buflen += 256;      buffer = realloc (buffer, buflen);    }  if (status == NSS_STATUS_SUCCESS)    return &resultbuf;  else    return NULL;}static struct group *files_getgrent (void){  enum nss_status status;  static int buflen = 256;  static char *buffer = NULL;  static struct group resultbuf;  if (buffer == NULL)    buffer = malloc (buflen);  while ((status = files_getgrent_r (&resultbuf, buffer, buflen, &errno))	 == NSS_STATUS_TRYAGAIN && errno == ERANGE)    {      errno = 0;      buflen += 256;      buffer = realloc (buffer, buflen);    }  if (status == NSS_STATUS_SUCCESS)    return &resultbuf;  else    return NULL;}static intin_use_by_other_users (const char *dir, const char *user,		       int have_extrapath){  struct passwd *pw;  size_t dirlen = strlen (dir);  int retval = 0;  setpwent ();  while ((pw = getpwent ()))    {      /* don't count ourself.  */      if (strcmp (pw->pw_name, user) == 0)	continue;      /* Another user can have the same directory or a subdirectory	 of our own directory as home directory.  */      if ((dirlen < strlen (pw->pw_dir) && strncmp (dir, pw->pw_dir, dirlen) == 0	   && pw->pw_dir[dirlen] == '/') || strcmp (dir, pw->pw_dir) == 0)	{	  fprintf (stderr,		   _("%s: directory `%s' is in use by `%s'.\n"),		   program, dir, pw->pw_name);	  retval = 1;	}    }  endpwent ();  if (have_extrapath)    while ((pw = files_getpwent ()))      {	/* don't count ourself.  */	if (strcmp (pw->pw_name, user) == 0)	  continue;	/* Another user can have the same directory or a subdirectory	   of our own directory as home directory.  */	if (strncmp (dir, pw->pw_dir, dirlen) == 0)	  {	    fprintf (stderr,		     _("%s: directory `%s' is in use by `%s'.\n"),		     program, dir, pw->pw_name);	    retval = 1;	  }      }  return retval;}static intremove_from_secondary_groups (user_t *pw_data, int have_extrapath){  struct item_t {    char *value;    struct item_t *next;  } *list = NULL, *item;  struct group *gr;  int retval = E_SUCCESS;  if (have_extrapath)    {      while ((gr = files_getgrent ()))	{	  unsigned int i;	  for (i = 0; gr->gr_mem[i]; i++)	    {	      if (strcmp (gr->gr_mem[i], pw_data->pw.pw_name) == 0)		{		  item = malloc (sizeof (*item));		  item->value = strdup (gr->gr_name);		  item->next = list;		  list = item;		}	    }	}    }  else    {      setgrent ();      while ((gr = getgrent ()))	{	  unsigned int i;	  for (i = 0; gr->gr_mem[i]; i++)	    {	      if (strcmp (gr->gr_mem[i], pw_data->pw.pw_name) == 0)		{		  item = malloc (sizeof (*item));		  item->value = strdup (gr->gr_name);		  item->next = list;		  list = item;		}	    }	}      endgrent ();    }  item = list;  while (item != NULL)    {      group_t *gr_data = find_group_data (item->value, 0, NULL);      if (gr_data == NULL || gr_data->service == S_NONE)	{	  fprintf (stderr,		   _("%s: ERROR: cannot find group `%s' anymore!.\n"),		   program, item->value);	  if (retval == E_SUCCESS)	    retval = E_NOTFOUND;	}      else	{	  gr_data->todo = DO_MODIFY;#ifdef USE_LDAP	  if (gr_data->service == S_LDAP)	    {	      if (pw_data->binddn == NULL)		{		  pw_data->binddn = get_caller_dn ();		  if (pw_data->binddn == NULL)		    {		      fprintf (stderr, _("%s: Cannot remove user from groups stored in LDAP database without DN.\n"),			       program);		    }		}	      if (pw_data->binddn == NULL)		{		  fprintf (stderr,			   _("%s: User not removed from LDAP group `%s'.\n"),			   program, gr_data->gr.gr_name);		  item = item->next;		  free_group_t (gr_data);		  retval = E_GRP_UPDATE;		  continue;		}	      gr_data->binddn = strdup (pw_data->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 removed from LDAP group `%s'.\n"),			       program, gr_data->gr.gr_name);		      item = item->next;		      free_group_t (gr_data);		      retval = E_GRP_UPDATE;		      continue;		    }		}	    }#endif	  if (pw_data->oldclearpwd)	    gr_data->oldclearpwd = strdup (pw_data->oldclearpwd);	  gr_data->new_gr_mem = remove_gr_mem (pw_data->pw.pw_name,					       gr_data->gr.gr_mem);	  if (write_group_data (gr_data, 1) != 0)	    {	      sec_log (program, MSG_ERROR_REMOVE_USER_FROM_GROUP,		       pw_data->pw.pw_name, pw_data->pw.pw_uid,		       gr_data->gr.gr_name, gr_data->gr.gr_gid, getuid ());	      fprintf (stderr,		       _("%s: User not removed from group `%s'.\n"),		       program, gr_data->gr.gr_name);	      retval = E_GRP_UPDATE;	    }	  else	    {	      sec_log (program, MSG_USER_REMOVED_FROM_GROUP,		       pw_data->pw.pw_name, gr_data->gr.gr_name,

⌨️ 快捷键说明

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