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

📄 nss_wrapper.c

📁 samba最新软件
💻 C
📖 第 1 页 / 共 2 页
字号:
/* * Copyright (C) Stefan Metzmacher 2007 <metze@samba.org> * * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright *    notice, this list of conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright *    notice, this list of conditions and the following disclaimer in the *    documentation and/or other materials provided with the distribution. * * 3. Neither the name of the author nor the names of its contributors *    may be used to endorse or promote products derived from this software *    without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */#ifdef _SAMBA_BUILD_#define NSS_WRAPPER_NOT_REPLACE#include "lib/replace/replace.h"#include "system/passwd.h"#include "system/filesys.h"#else /* _SAMBA_BUILD_ */#error nss_wrapper_only_supported_in_samba_yet#endif#ifndef _PUBLIC_#define _PUBLIC_#endif/* not all systems have _r functions... */#ifndef HAVE_GETPWNAM_R#define getpwnam_r(name, pwdst, buf, buflen, pwdstp)	ENOSYS#endif#ifndef HAVE_GETPWUID_R#define getpwuid_r(uid, pwdst, buf, buflen, pwdstp)	ENOSYS#endif#ifndef HAVE_GETPWENT_R#define getpwent_r(pwdst, buf, buflen, pwdstp)		ENOSYS#endif#ifndef HAVE_GETGRNAM_R#define getgrnam_r(name, grdst, buf, buflen, grdstp)	ENOSYS#endif#ifndef HAVE_GETGRUID_R#define getgrgid_r(uid, grdst, buf, buflen, grdstp)	ENOSYS#endif#ifndef HAVE_GETGRENT_R#define getgrent_r(grdst, buf, buflen, grdstp)		ENOSYS#endif/* LD_PRELOAD doesn't work yet, so REWRITE_CALLS is all we support * for now */#define REWRITE_CALLS#ifdef REWRITE_CALLS#define real_getpwnam		getpwnam#define real_getpwnam_r		getpwnam_r#define real_getpwuid		getpwuid#define real_getpwuid_r		getpwuid_r#define real_setpwent		setpwent#define real_getpwent		getpwent#define real_getpwent_r		getpwent_r#define real_endpwent		endpwent/*#define real_getgrlst		getgrlst#define real_getgrlst_r		getgrlst_r#define real_initgroups_dyn	initgroups_dyn*/#define real_initgroups		initgroups#define real_getgrnam		getgrnam#define real_getgrnam_r		getgrnam_r#define real_getgrgid		getgrgid#define real_getgrgid_r		getgrgid_r#define real_setgrent		setgrent#define real_getgrent		getgrent#define real_getgrent_r		getgrent_r#define real_endgrent		endgrent#endif#if 0# ifdef DEBUG# define NWRAP_ERROR(args)	DEBUG(0, args)# else# define NWRAP_ERROR(args)	printf args# endif#else#define NWRAP_ERROR(args)#endif#if 0# ifdef DEBUG# define NWRAP_DEBUG(args)	DEBUG(0, args)# else# define NWRAP_DEBUG(args)	printf args# endif#else#define NWRAP_DEBUG(args)#endif#if 0# ifdef DEBUG# define NWRAP_VERBOSE(args)	DEBUG(0, args)# else# define NWRAP_VERBOSE(args)	printf args# endif#else#define NWRAP_VERBOSE(args)#endifstruct nwrap_cache {	const char *path;	int fd;	struct stat st;	uint8_t *buf;	void *private_data;	bool (*parse_line)(struct nwrap_cache *, char *line);	void (*unload)(struct nwrap_cache *);};struct nwrap_pw {	struct nwrap_cache *cache;	struct passwd *list;	int num;	int idx;};struct nwrap_cache __nwrap_cache_pw;struct nwrap_pw nwrap_pw_global;static bool nwrap_pw_parse_line(struct nwrap_cache *nwrap, char *line);static void nwrap_pw_unload(struct nwrap_cache *nwrap);struct nwrap_gr {	struct nwrap_cache *cache;	struct group *list;	int num;	int idx;};struct nwrap_cache __nwrap_cache_gr;struct nwrap_gr nwrap_gr_global;static bool nwrap_gr_parse_line(struct nwrap_cache *nwrap, char *line);static void nwrap_gr_unload(struct nwrap_cache *nwrap);static void nwrap_init(void){	static bool initialized;	if (initialized) return;	initialized = true;	nwrap_pw_global.cache = &__nwrap_cache_pw;	nwrap_pw_global.cache->path = getenv("NSS_WRAPPER_PASSWD");	nwrap_pw_global.cache->fd = -1;	nwrap_pw_global.cache->private_data = &nwrap_pw_global;	nwrap_pw_global.cache->parse_line = nwrap_pw_parse_line;	nwrap_pw_global.cache->unload = nwrap_pw_unload;	nwrap_gr_global.cache = &__nwrap_cache_gr;	nwrap_gr_global.cache->path = getenv("NSS_WRAPPER_GROUP");	nwrap_gr_global.cache->fd = -1;	nwrap_gr_global.cache->private_data = &nwrap_gr_global;	nwrap_gr_global.cache->parse_line = nwrap_gr_parse_line;	nwrap_gr_global.cache->unload = nwrap_gr_unload;}static bool nwrap_enabled(void){	nwrap_init();	if (!nwrap_pw_global.cache->path) {		return false;	}	if (nwrap_pw_global.cache->path[0] == '\0') {		return false;	}	if (!nwrap_gr_global.cache->path) {		return false;	}	if (nwrap_gr_global.cache->path[0] == '\0') {		return false;	}	return true;}static bool nwrap_parse_file(struct nwrap_cache *nwrap){	int ret;	uint8_t *buf = NULL;	char *nline;	if (nwrap->st.st_size == 0) {		NWRAP_DEBUG(("%s: size == 0\n",			     __location__));		goto done;	}	if (nwrap->st.st_size > INT32_MAX) {		NWRAP_ERROR(("%s: size[%u] larger than INT32_MAX\n",			     __location__, (unsigned)nwrap->st.st_size));		goto failed;	}	ret = lseek(nwrap->fd, 0, SEEK_SET);	if (ret != 0) {		NWRAP_ERROR(("%s: lseek - %d\n",__location__,ret));		goto failed;	}	buf = malloc(nwrap->st.st_size + 1);	if (!buf) {		NWRAP_ERROR(("%s: malloc failed\n",__location__));		goto failed;	}	ret = read(nwrap->fd, buf, nwrap->st.st_size);	if (ret != nwrap->st.st_size) {		NWRAP_ERROR(("%s: read(%u) gave %d\n",			     __location__, (unsigned)nwrap->st.st_size, ret));		goto failed;	}	buf[nwrap->st.st_size] = '\0';	nline = (char *)buf;	while (nline && nline[0]) {		char *line;		char *e;		bool ok;		line = nline;		nline = NULL;		e = strchr(line, '\n');		if (e) {			e[0] = '\0';			e++;			if (e[0] == '\r') {				e[0] = '\0';				e++;			}			nline = e;		}		NWRAP_VERBOSE(("%s:'%s'\n",__location__, line));		if (strlen(line) == 0) {			continue;		}		ok = nwrap->parse_line(nwrap, line);		if (!ok) {			goto failed;		}	}done:	nwrap->buf = buf;	return true;failed:	if (buf) free(buf);	return false;}static void nwrap_cache_unload(struct nwrap_cache *nwrap){	nwrap->unload(nwrap);	if (nwrap->buf) free(nwrap->buf);	nwrap->buf = NULL;}static void nwrap_cache_reload(struct nwrap_cache *nwrap){	struct stat st;	int ret;	bool ok;	bool retried = false;reopen:	if (nwrap->fd < 0) {		nwrap->fd = open(nwrap->path, O_RDONLY);		if (nwrap->fd < 0) {			NWRAP_ERROR(("%s: unable to open '%s' readonly %d:%s\n",				     __location__,				     nwrap->path, nwrap->fd,				     strerror(errno)));			return;		}		NWRAP_VERBOSE(("%s: open '%s'\n", __location__, nwrap->path));	}	ret = fstat(nwrap->fd, &st);	if (ret != 0) {		NWRAP_ERROR(("%s: fstat(%s) - %d:%s\n",			     __location__,			     nwrap->path,			     ret, strerror(errno)));		return;	}	if (retried == false && st.st_nlink == 0) {		/* maybe someone has replaced the file... */		NWRAP_DEBUG(("%s: st_nlink == 0, reopen %s\n",			     __location__, nwrap->path));		retried = true;		memset(&nwrap->st, 0, sizeof(nwrap->st));		close(nwrap->fd);		nwrap->fd = -1;		goto reopen;	}	if (st.st_mtime == nwrap->st.st_mtime) {		NWRAP_VERBOSE(("%s: st_mtime[%u] hasn't changed, skip reload\n",			       __location__, (unsigned)st.st_mtime));		return;	}	NWRAP_DEBUG(("%s: st_mtime has changed [%u] => [%u], start reload\n",		     __location__, (unsigned)st.st_mtime,		     (unsigned)nwrap->st.st_mtime));	nwrap->st = st;	nwrap_cache_unload(nwrap);	ok = nwrap_parse_file(nwrap);	if (!ok) {		NWRAP_ERROR(("%s: failed to reload %s\n",			     __location__, nwrap->path));		nwrap_cache_unload(nwrap);	}	NWRAP_DEBUG(("%s: reloaded %s\n",		     __location__, nwrap->path));}/* * the caller has to call nwrap_unload() on failure */static bool nwrap_pw_parse_line(struct nwrap_cache *nwrap, char *line){	struct nwrap_pw *nwrap_pw;	char *c;	char *p;	char *e;	struct passwd *pw;	size_t list_size;	nwrap_pw = (struct nwrap_pw *)nwrap->private_data;	list_size = sizeof(*nwrap_pw->list) * (nwrap_pw->num+1);	pw = (struct passwd *)realloc(nwrap_pw->list, list_size);	if (!pw) {		NWRAP_ERROR(("%s:realloc(%u) failed\n",			     __location__, list_size));		return false;	}	nwrap_pw->list = pw;	pw = &nwrap_pw->list[nwrap_pw->num];	c = line;	/* name */	p = strchr(c, ':');	if (!p) {		NWRAP_ERROR(("%s:invalid line[%s]: '%s'\n",			     __location__, line, c));		return false;	}	*p = '\0';	p++;	pw->pw_name = c;	c = p;	NWRAP_VERBOSE(("name[%s]\n", pw->pw_name));	/* password */	p = strchr(c, ':');	if (!p) {		NWRAP_ERROR(("%s:invalid line[%s]: '%s'\n",			     __location__, line, c));		return false;	}	*p = '\0';	p++;	pw->pw_passwd = c;	c = p;	NWRAP_VERBOSE(("password[%s]\n", pw->pw_passwd));	/* uid */	p = strchr(c, ':');	if (!p) {		NWRAP_ERROR(("%s:invalid line[%s]: '%s'\n",			     __location__, line, c));		return false;	}	*p = '\0';	p++;	e = NULL;	pw->pw_uid = (uid_t)strtoul(c, &e, 10);	if (c == e) {		NWRAP_ERROR(("%s:invalid line[%s]: '%s' - %s\n",			     __location__, line, c, strerror(errno)));		return false;	}	if (e == NULL) {		NWRAP_ERROR(("%s:invalid line[%s]: '%s' - %s\n",			     __location__, line, c, strerror(errno)));		return false;	}	if (e[0] != '\0') {		NWRAP_ERROR(("%s:invalid line[%s]: '%s' - %s\n",			     __location__, line, c, strerror(errno)));		return false;	}	c = p;	NWRAP_VERBOSE(("uid[%u]\n", pw->pw_uid));	/* gid */	p = strchr(c, ':');	if (!p) {		NWRAP_ERROR(("%s:invalid line[%s]: '%s'\n",			     __location__, line, c));		return false;	}	*p = '\0';	p++;	e = NULL;	pw->pw_gid = (gid_t)strtoul(c, &e, 10);	if (c == e) {		NWRAP_ERROR(("%s:invalid line[%s]: '%s' - %s\n",			     __location__, line, c, strerror(errno)));		return false;	}	if (e == NULL) {		NWRAP_ERROR(("%s:invalid line[%s]: '%s' - %s\n",			     __location__, line, c, strerror(errno)));		return false;	}	if (e[0] != '\0') {		NWRAP_ERROR(("%s:invalid line[%s]: '%s' - %s\n",			     __location__, line, c, strerror(errno)));		return false;	}	c = p;	NWRAP_VERBOSE(("gid[%u]\n", pw->pw_gid));	/* gecos */	p = strchr(c, ':');	if (!p) {		NWRAP_ERROR(("%s:invalid line[%s]: '%s'\n",			     __location__, line, c));		return false;	}	*p = '\0';	p++;	pw->pw_gecos = c;	c = p;	NWRAP_VERBOSE(("gecos[%s]\n", pw->pw_gecos));	/* dir */	p = strchr(c, ':');	if (!p) {		NWRAP_ERROR(("%s:'%s'\n",__location__,c));		return false;	}	*p = '\0';	p++;	pw->pw_dir = c;	c = p;	NWRAP_VERBOSE(("dir[%s]\n", pw->pw_dir));	/* shell */	pw->pw_shell = c;	NWRAP_VERBOSE(("shell[%s]\n", pw->pw_shell));	NWRAP_DEBUG(("add user[%s:%s:%u:%u:%s:%s:%s]\n",		     pw->pw_name, pw->pw_passwd,		     pw->pw_uid, pw->pw_gid,		     pw->pw_gecos, pw->pw_dir, pw->pw_shell));	nwrap_pw->num++;	return true;}static void nwrap_pw_unload(struct nwrap_cache *nwrap){	struct nwrap_pw *nwrap_pw;	nwrap_pw = (struct nwrap_pw *)nwrap->private_data;	if (nwrap_pw->list) free(nwrap_pw->list);	nwrap_pw->list = NULL;	nwrap_pw->num = 0;	nwrap_pw->idx = 0;}static int nwrap_pw_copy_r(const struct passwd *src, struct passwd *dst,			   char *buf, size_t buflen, struct passwd **dstp){	char *first;	char *last;	off_t ofs;	first = src->pw_name;	last = src->pw_shell;	while (*last) last++;	ofs = PTR_DIFF(last + 1, first);	if (ofs > buflen) {		return ERANGE;	}	memcpy(buf, first, ofs);	ofs = PTR_DIFF(src->pw_name, first);	dst->pw_name = buf + ofs;	ofs = PTR_DIFF(src->pw_passwd, first);	dst->pw_passwd = buf + ofs;	dst->pw_uid = src->pw_uid;	dst->pw_gid = src->pw_gid;	ofs = PTR_DIFF(src->pw_gecos, first);	dst->pw_gecos = buf + ofs;	ofs = PTR_DIFF(src->pw_dir, first);	dst->pw_dir = buf + ofs;

⌨️ 快捷键说明

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