winbindd_group.c

来自「samba-3.0.22.tar.gz 编译smb服务器的源码」· C语言 代码 · 共 1,191 行 · 第 1/3 页

C
1,191
字号
/*    Unix SMB/CIFS implementation.   Winbind daemon for ntdom nss module   Copyright (C) Tim Potter 2000   Copyright (C) Jeremy Allison 2001.   Copyright (C) Gerald (Jerry) Carter 2003.   Copyright (C) Volker Lendecke 2005      This program is free software; you can redistribute it and/or modify   it under the terms of the GNU General Public License as published by   the Free Software Foundation; either version 2 of the License, or   (at your option) any later version.      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., 675 Mass Ave, Cambridge, MA 02139, USA.*/#include "includes.h"#include "winbindd.h"extern BOOL opt_nocache;#undef DBGC_CLASS#define DBGC_CLASS DBGC_WINBIND/*************************************************************** Empty static struct for negative caching.****************************************************************//* Fill a grent structure from various other information */static BOOL fill_grent(struct winbindd_gr *gr, const char *dom_name, 		       const char *gr_name, gid_t unix_gid){	fstring full_group_name;	/* Fill in uid/gid */	fill_domain_username(full_group_name, dom_name, gr_name);	gr->gr_gid = unix_gid;    	/* Group name and password */    	safe_strcpy(gr->gr_name, full_group_name, sizeof(gr->gr_name) - 1);	safe_strcpy(gr->gr_passwd, "x", sizeof(gr->gr_passwd) - 1);	return True;}/* Fill in the group membership field of a NT group given by group_sid */static BOOL fill_grent_mem(struct winbindd_domain *domain,			   DOM_SID *group_sid, 			   enum SID_NAME_USE group_name_type, 			   size_t *num_gr_mem, char **gr_mem, size_t *gr_mem_len){	DOM_SID *sid_mem = NULL;	uint32 num_names = 0;	uint32 *name_types = NULL;	unsigned int buf_len, buf_ndx, i;	char **names = NULL, *buf;	BOOL result = False;	TALLOC_CTX *mem_ctx;	NTSTATUS status;	fstring sid_string;	if (!(mem_ctx = talloc_init("fill_grent_mem(%s)", domain->name)))		return False;	/* Initialise group membership information */		DEBUG(10, ("group SID %s\n", sid_to_string(sid_string, group_sid)));	*num_gr_mem = 0;	/* HACK ALERT!! This whole routine does not cope with group members	 * from more than one domain, ie aliases. Thus we have to work it out	 * ourselves in a special routine. */	if (domain->internal)		return fill_passdb_alias_grmem(domain, group_sid,					       num_gr_mem,					       gr_mem, gr_mem_len);		if ( !((group_name_type==SID_NAME_DOM_GRP) ||		((group_name_type==SID_NAME_ALIAS) && domain->primary)) )	{		DEBUG(1, ("SID %s in domain %s isn't a domain group (%d)\n", 			  sid_to_string(sid_string, group_sid), domain->name, 			  group_name_type));                goto done;	}	/* Lookup group members */	status = domain->methods->lookup_groupmem(domain, mem_ctx, group_sid, &num_names, 						  &sid_mem, &names, &name_types);	if (!NT_STATUS_IS_OK(status)) {		DEBUG(1, ("could not lookup membership for group rid %s in domain %s (error: %s)\n", 			  sid_to_string(sid_string, group_sid), domain->name, nt_errstr(status)));		goto done;	}	DEBUG(10, ("looked up %d names\n", num_names));	if (DEBUGLEVEL >= 10) {		for (i = 0; i < num_names; i++)			DEBUG(10, ("\t%20s %s %d\n", names[i],				   sid_string_static(&sid_mem[i]),				   name_types[i]));	}	/* Add members to list */	buf = NULL;	buf_len = buf_ndx = 0; again:	for (i = 0; i < num_names; i++) {		char *the_name;		fstring name;		int len;					the_name = names[i];		DEBUG(10, ("processing name %s\n", the_name));		/* FIXME: need to cope with groups within groups.  These                   occur in Universal groups on a Windows 2000 native mode                   server. */		/* make sure to allow machine accounts */		if (name_types[i] != SID_NAME_USER && name_types[i] != SID_NAME_COMPUTER) {			DEBUG(3, ("name %s isn't a domain user\n", the_name));			continue;		}		/* Append domain name */		fill_domain_username(name, domain->name, the_name);		len = strlen(name);				/* Add to list or calculate buffer length */		if (!buf) {			buf_len += len + 1; /* List is comma separated */			(*num_gr_mem)++;			DEBUG(10, ("buf_len + %d = %d\n", len + 1, buf_len));		} else {			DEBUG(10, ("appending %s at ndx %d\n", name, len));			safe_strcpy(&buf[buf_ndx], name, len);			buf_ndx += len;			buf[buf_ndx] = ',';			buf_ndx++;		}	}	/* Allocate buffer */	if (!buf && buf_len != 0) {		if (!(buf = SMB_MALLOC(buf_len))) {			DEBUG(1, ("out of memory\n"));			result = False;			goto done;		}		memset(buf, 0, buf_len);		goto again;	}	if (buf && buf_ndx > 0) {		buf[buf_ndx - 1] = '\0';	}	*gr_mem = buf;	*gr_mem_len = buf_len;	DEBUG(10, ("num_mem = %d, len = %d, mem = %s\n", *num_gr_mem, 		   buf_len, *num_gr_mem ? buf : "NULL")); 	result = True;done:	talloc_destroy(mem_ctx);		DEBUG(10, ("fill_grent_mem returning %d\n", result));	return result;}/* Return a group structure from a group name */void winbindd_getgrnam(struct winbindd_cli_state *state){	DOM_SID group_sid;	struct winbindd_domain *domain;	enum SID_NAME_USE name_type;	fstring name_domain, name_group;	char *tmp, *gr_mem;	size_t gr_mem_len;	gid_t gid;		/* Ensure null termination */	state->request.data.groupname[sizeof(state->request.data.groupname)-1]='\0';	DEBUG(3, ("[%5lu]: getgrnam %s\n", (unsigned long)state->pid,		  state->request.data.groupname));	/* Parse domain and groupname */		memset(name_group, 0, sizeof(fstring));	tmp = state->request.data.groupname;		parse_domain_user(tmp, name_domain, name_group);	/* if no domain or our local domain and no local tdb group, default to	 * our local domain for aliases */	if ( !*name_domain || strequal(name_domain, get_global_sam_name()) ) {		fstrcpy(name_domain, get_global_sam_name());	}	/* Get info for the domain */	if ((domain = find_domain_from_name(name_domain)) == NULL) {		DEBUG(3, ("could not get domain sid for domain %s\n",			  name_domain));		request_error(state);		return;	}	/* should we deal with users for our domain? */		if ( lp_winbind_trusted_domains_only() && domain->primary) {		DEBUG(7,("winbindd_getgrnam: My domain -- rejecting getgrnam() for %s\\%s.\n", 			name_domain, name_group));		request_error(state);		return;	}	/* Get rid and name type from name */        	if (!winbindd_lookup_sid_by_name(state->mem_ctx, domain, domain->name,					 name_group, &group_sid, &name_type)) {		DEBUG(1, ("group %s in domain %s does not exist\n", 			  name_group, name_domain));		request_error(state);		return;	}	if ( !((name_type==SID_NAME_DOM_GRP) ||	       ((name_type==SID_NAME_ALIAS) && domain->primary) ||	       ((name_type==SID_NAME_ALIAS) && domain->internal) ||	       ((name_type==SID_NAME_WKN_GRP) && domain->internal)) )	{		DEBUG(1, ("name '%s' is not a local, domain or builtin group: %d\n", 			  name_group, name_type));		request_error(state);		return;	}	if (!NT_STATUS_IS_OK(idmap_sid_to_gid(&group_sid, &gid, 0))) {		DEBUG(1, ("error converting unix gid to sid\n"));		request_error(state);		return;	}	if (!fill_grent(&state->response.data.gr, name_domain,			name_group, gid) ||	    !fill_grent_mem(domain, &group_sid, name_type,			    &state->response.data.gr.num_gr_mem,			    &gr_mem, &gr_mem_len)) {		request_error(state);		return;	}	/* Group membership lives at start of extra data */	state->response.data.gr.gr_mem_ofs = 0;	state->response.length += gr_mem_len;	state->response.extra_data = gr_mem;	request_ok(state);}/* Return a group structure from a gid number */void winbindd_getgrgid(struct winbindd_cli_state *state){	struct winbindd_domain *domain;	DOM_SID group_sid;	enum SID_NAME_USE name_type;	fstring dom_name;	fstring group_name;	size_t gr_mem_len;	char *gr_mem;	DEBUG(3, ("[%5lu]: getgrgid %lu\n", (unsigned long)state->pid, 		  (unsigned long)state->request.data.gid));	/* Bug out if the gid isn't in the winbind range */	if ((state->request.data.gid < server_state.gid_low) ||	    (state->request.data.gid > server_state.gid_high)) {		request_error(state);		return;	}	/* Get rid from gid */	if (!NT_STATUS_IS_OK(idmap_gid_to_sid(&group_sid, state->request.data.gid, 0))) {		DEBUG(1, ("could not convert gid %lu to rid\n", 			  (unsigned long)state->request.data.gid));		request_error(state);		return;	}	/* Get name from sid */	if (!winbindd_lookup_name_by_sid(state->mem_ctx, &group_sid, dom_name,					 group_name, &name_type)) {		DEBUG(1, ("could not lookup sid\n"));		request_error(state);		return;	}	/* Fill in group structure */	domain = find_domain_from_sid_noinit(&group_sid);	if (!domain) {		DEBUG(1,("Can't find domain from sid\n"));		request_error(state);		return;	}	if ( !((name_type==SID_NAME_DOM_GRP) ||	       ((name_type==SID_NAME_ALIAS) && domain->primary) ||	       ((name_type==SID_NAME_ALIAS) && domain->internal)) )	{		DEBUG(1, ("name '%s' is not a local or domain group: %d\n", 			  group_name, name_type));		request_error(state);		return;	}	if (!fill_grent(&state->response.data.gr, dom_name, group_name, 			state->request.data.gid) ||	    !fill_grent_mem(domain, &group_sid, name_type,			    &state->response.data.gr.num_gr_mem,			    &gr_mem, &gr_mem_len)) {		request_error(state);		return;	}	/* Group membership lives at start of extra data */	state->response.data.gr.gr_mem_ofs = 0;	state->response.length += gr_mem_len;	state->response.extra_data = gr_mem;	request_ok(state);}/* * set/get/endgrent functions *//* "Rewind" file pointer for group database enumeration */static BOOL winbindd_setgrent_internal(struct winbindd_cli_state *state){	struct winbindd_domain *domain;	DEBUG(3, ("[%5lu]: setgrent\n", (unsigned long)state->pid));	/* Check user has enabled this */	if (!lp_winbind_enum_groups()) {		return False;	}			/* Free old static data if it exists */		if (state->getgrent_state != NULL) {		free_getent_state(state->getgrent_state);		state->getgrent_state = NULL;	}	

⌨️ 快捷键说明

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