📄 group.c
字号:
/* Copyright (C) 2003, 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 <nss.h>#include <dlfcn.h>#include <errno.h>#include <unistd.h>#include <sys/stat.h>#include <rpcsvc/yp_prot.h>#include <rpcsvc/ypclnt.h>#ifdef USE_LDAP#ifdef HAVE_LDAP_H#include <ldap.h>#endif#include "libldap.h"#endif#include "nsw.h"#include "i18n.h"#include "group.h"#include "yppasswd.h"#include "read-files.h"voidfree_group_t (group_t *data){ unsigned int i; if (data == NULL) return; if (data->new_name) free (data->new_name); if (data->grpbuffer) free (data->grpbuffer); if (data->newpassword) free (data->newpassword); if (data->oldclearpwd) free (data->oldclearpwd); if (data->new_gr_mem) { for (i = 0; data->new_gr_mem[i]; i++) { if (data->new_gr_mem[i]) free (data->new_gr_mem[i]); } free (data->new_gr_mem); } if (data->binddn) free (data->binddn); free (data);}group_t *find_group_data (const char *name, gid_t gid, const char *use_service){ enum nss_status (*nss_getgrnam_r)(const char *gr_name, struct group *grp, char *buffer, size_t buflen, int *errnop); enum nss_status (*nss_getgrgid_r)(gid_t grpid, struct group *grp, char *buffer, size_t buflen, int *errnop); enum nss_status status; void *nss_handle = NULL; group_t *data; struct nsw *nswp; int i; data = calloc (1, sizeof (group_t)); if (data == NULL) return NULL; data->service = S_NONE; /* UNIX passwords area */ if (use_service) { nswp = calloc (1, sizeof (struct nsw)); if (nswp == NULL) return data; nswp->name = strdup ("group"); nswp->orderc = 1; nswp->orders = calloc (2, sizeof (char *)); nswp->orders[0] = strdup (use_service); nswp->orders[1] = NULL; } else nswp = _getnswbyname ("group"); if (nswp == NULL) return data; for (i = 0; i < nswp->orderc; ++i) { const char *cmpptr = nswp->orders[i]; again: if (nswp->orders[i][0] == '[') continue; if (strcasecmp ("files", cmpptr) == 0 || strcasecmp ("compat", cmpptr) == 0) { nss_getgrnam_r = files_getgrnam_r; nss_getgrgid_r = files_getgrgid_r; /* Get group file entry... */ do { errno = 0; data->grpbuflen += 1024; data->grpbuffer = realloc (data->grpbuffer, data->grpbuflen); if (name) status = (*nss_getgrnam_r)(name, &data->gr, data->grpbuffer, data->grpbuflen, &errno); else status = (*nss_getgrgid_r)(gid, &data->gr, data->grpbuffer, data->grpbuflen, &errno); } while (status == NSS_STATUS_TRYAGAIN && errno == ERANGE); if (status != NSS_STATUS_SUCCESS) { free (data->grpbuffer); data->grpbuffer = NULL; data->grpbuflen = 0; if (strcasecmp ("compat", cmpptr) == 0) { struct nsw *nswp2 = _getnswbyname ("group_compat"); if (nswp2 == NULL) cmpptr = "nis"; else { char *cp = alloca (strlen (nswp2->orders[0]) + 1); strcpy (cp, nswp2->orders[0]); cmpptr = cp; nsw_free (nswp2); } goto again; } } else { data->service = S_LOCAL; break; } } else if (strcasecmp ("nis", cmpptr) == 0 || strcasecmp ("yp", cmpptr) == 0) { nss_handle = dlopen ("libnss_nis.so.2", RTLD_NOW); if (!nss_handle) continue; nss_getgrnam_r = dlsym (nss_handle, "_nss_nis_getgrnam_r"); nss_getgrgid_r = dlsym (nss_handle, "_nss_nis_getgrgid_r"); if (dlerror () != NULL) { dlclose (nss_handle); continue; } /* Get NIS group entry... */ do { errno = 0; data->grpbuflen += 1024; data->grpbuffer = realloc (data->grpbuffer, data->grpbuflen); if (name) status = (*nss_getgrnam_r)(name, &data->gr, data->grpbuffer, data->grpbuflen, &errno); else status = (*nss_getgrgid_r)(gid, &data->gr, data->grpbuffer, data->grpbuflen, &errno); } while (status == NSS_STATUS_TRYAGAIN && errno == ERANGE); if (status != NSS_STATUS_SUCCESS) { dlclose (nss_handle); free (data->grpbuffer); data->grpbuffer = NULL; data->grpbuflen = 0; } else { data->service = S_YP; break; } } else if (strcasecmp ("nisplus", cmpptr) == 0 || strcasecmp ("nis+", cmpptr) == 0) { nss_handle = dlopen ("libnss_nisplus.so.2", RTLD_NOW); if (!nss_handle) continue; nss_getgrnam_r = dlsym (nss_handle, "_nss_nisplus_getgrnam_r"); nss_getgrgid_r = dlsym (nss_handle, "_nss_nisplus_getgrgid_r"); if (dlerror () != NULL) { dlclose (nss_handle); continue; } /* Get group NIS+ entry... */ do { errno = 0; data->grpbuflen += 1024; data->grpbuffer = realloc (data->grpbuffer, data->grpbuflen); if (name) status = (*nss_getgrnam_r)(name, &data->gr, data->grpbuffer, data->grpbuflen, &errno); else status = (*nss_getgrgid_r)(gid, &data->gr, data->grpbuffer, data->grpbuflen, &errno); } while (status == NSS_STATUS_TRYAGAIN && errno == ERANGE); if (status != NSS_STATUS_SUCCESS) { dlclose (nss_handle); free (data->grpbuffer); data->grpbuffer = NULL; data->grpbuflen = 0; } else { data->service = S_NISPLUS; break; } }#ifdef USE_LDAP else if (strcasecmp ("ldap", cmpptr) == 0) { nss_handle = dlopen ("libnss_ldap.so.2", RTLD_NOW); if (!nss_handle) continue; nss_getgrnam_r = dlsym (nss_handle, "_nss_ldap_getgrnam_r"); nss_getgrgid_r = dlsym (nss_handle, "_nss_ldap_getgrgid_r"); if (dlerror () != NULL) { dlclose (nss_handle); continue; } /* Get LDAP group entry... */ do { errno = 0; data->grpbuflen += 1024; data->grpbuffer = realloc (data->grpbuffer, data->grpbuflen); if (name) status = (*nss_getgrnam_r)(name, &data->gr, data->grpbuffer, data->grpbuflen, &errno); else status = (*nss_getgrgid_r)(gid, &data->gr, data->grpbuffer, data->grpbuflen, &errno); } while (status == NSS_STATUS_TRYAGAIN && errno == ERANGE); if (status != NSS_STATUS_SUCCESS) { dlclose (nss_handle); free (data->grpbuffer); data->grpbuffer = NULL; data->grpbuflen = 0; } else { data->service = S_LDAP; break; } }#endif } nsw_free (nswp); if (data->service != S_LOCAL && data->service != S_NONE) dlclose (nss_handle); return data;}intwrite_group_data (group_t *data, int is_locked){ int retval = 0; if (data->service == S_LOCAL) { if (!is_locked && lock_database() != 0) { fputs (_("Cannot lock group file: already locked.\n"), stderr); retval = -1; } else if ((data->newpassword && !data->use_gshadow) || data->new_gr_mem || data->have_new_gid || data->new_name || data->todo == DO_CREATE || data->todo == DO_DELETE) { /* Only run through /etc/group if we really have something to change. */ const char *file_tmp = "/group.tmpXXXXXX"; char *group_tmp = alloca (strlen (files_etc_dir) + strlen (file_tmp) + 1); char *group_orig = alloca (strlen (files_etc_dir) + 8); char *group_old = alloca (strlen (files_etc_dir) + 12); struct stat group_stat; struct group *gr; /* group struct obtained from fgetgrent() */ FILE *oldgf, *newgf; int gotit, newgf_fd; char *cp; cp = stpcpy (group_tmp, files_etc_dir); strcpy (cp, file_tmp); cp = stpcpy (group_orig, files_etc_dir); strcpy (cp, "/group"); cp = stpcpy (group_old, group_orig); strcpy (cp, ".old"); if ((oldgf = fopen (group_orig, "r")) == NULL) { fprintf (stderr, _("Can't open `%s': %m\n"), group_orig); retval = -1; goto error_group; } if (fstat (fileno (oldgf), &group_stat) < 0) { fprintf (stderr, _("Can't stat `%s': %m\n"), group_orig); fclose (oldgf);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -