📄 userdel.c
字号:
/* 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 + -