winbindd_util.c

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

C
1,210
字号
struct winbindd_domain *find_domain_from_sid(const DOM_SID *sid){	struct winbindd_domain *domain;	domain = find_domain_from_sid_noinit(sid);	if (domain == NULL)		return NULL;	if (!domain->initialized)		set_dc_type_and_flags(domain);	return domain;}struct winbindd_domain *find_our_domain(void){	struct winbindd_domain *domain;	/* Search through list */	for (domain = domain_list(); domain != NULL; domain = domain->next) {		if (domain->primary)			return domain;	}	smb_panic("Could not find our domain\n");	return NULL;}struct winbindd_domain *find_builtin_domain(void){	DOM_SID sid;	struct winbindd_domain *domain;	string_to_sid(&sid, "S-1-5-32");	domain = find_domain_from_sid(&sid);	if (domain == NULL)		smb_panic("Could not find BUILTIN domain\n");	return domain;}/* Find the appropriate domain to lookup a name or SID */struct winbindd_domain *find_lookup_domain_from_sid(const DOM_SID *sid){	/* A DC can't ask the local smbd for remote SIDs, here winbindd is the	 * one to contact the external DC's. On member servers the internal	 * domains are different: These are part of the local SAM. */	DEBUG(10, ("find_lookup_domain_from_sid(%s)\n",		   sid_string_static(sid)));	if (IS_DC || is_internal_domain(sid) || is_in_internal_domain(sid)) {		DEBUG(10, ("calling find_domain_from_sid\n"));		return find_domain_from_sid(sid);	}	/* On a member server a query for SID or name can always go to our	 * primary DC. */	DEBUG(10, ("calling find_our_domain\n"));	return find_our_domain();}struct winbindd_domain *find_lookup_domain_from_name(const char *domain_name){	if (IS_DC || strequal(domain_name, "BUILTIN") ||	    strequal(domain_name, get_global_sam_name()))		return find_domain_from_name_noinit(domain_name);	return find_our_domain();}/* Lookup a sid in a domain from a name */BOOL winbindd_lookup_sid_by_name(TALLOC_CTX *mem_ctx,				 struct winbindd_domain *domain, 				 const char *domain_name,				 const char *name, DOM_SID *sid, 				 enum SID_NAME_USE *type){	NTSTATUS result;	/* Lookup name */	result = domain->methods->name_to_sid(domain, mem_ctx, domain_name, name, sid, type);	/* Return rid and type if lookup successful */	if (!NT_STATUS_IS_OK(result)) {		*type = SID_NAME_UNKNOWN;	}	return NT_STATUS_IS_OK(result);}/** * @brief Lookup a name in a domain from a sid. * * @param sid Security ID you want to look up. * @param name On success, set to the name corresponding to @p sid. * @param dom_name On success, set to the 'domain name' corresponding to @p sid. * @param type On success, contains the type of name: alias, group or * user. * @retval True if the name exists, in which case @p name and @p type * are set, otherwise False. **/BOOL winbindd_lookup_name_by_sid(TALLOC_CTX *mem_ctx,				 DOM_SID *sid,				 fstring dom_name,				 fstring name,				 enum SID_NAME_USE *type){	char *names;	char *dom_names;	NTSTATUS result;	BOOL rv = False;	struct winbindd_domain *domain;	domain = find_lookup_domain_from_sid(sid);	if (!domain) {		DEBUG(1,("Can't find domain from sid\n"));		return False;	}	/* Lookup name */	result = domain->methods->sid_to_name(domain, mem_ctx, sid, &dom_names, &names, type);	/* Return name and type if successful */        	if ((rv = NT_STATUS_IS_OK(result))) {		fstrcpy(dom_name, dom_names);		fstrcpy(name, names);	} else {		*type = SID_NAME_UNKNOWN;		fstrcpy(name, name_deadbeef);	}        	return rv;}/* Free state information held for {set,get,end}{pw,gr}ent() functions */void free_getent_state(struct getent_state *state){	struct getent_state *temp;	/* Iterate over state list */	temp = state;	while(temp != NULL) {		struct getent_state *next;		/* Free sam entries then list entry */		SAFE_FREE(state->sam_entries);		DLIST_REMOVE(state, state);		next = temp->next;		SAFE_FREE(temp);		temp = next;	}}/* Parse winbindd related parameters */BOOL winbindd_param_init(void){	/* Parse winbind uid and winbind_gid parameters */	if (!lp_idmap_uid(&server_state.uid_low, &server_state.uid_high)) {		DEBUG(0, ("winbindd: idmap uid range missing or invalid\n"));		DEBUG(0, ("winbindd: cannot continue, exiting.\n"));		return False;	}		if (!lp_idmap_gid(&server_state.gid_low, &server_state.gid_high)) {		DEBUG(0, ("winbindd: idmap gid range missing or invalid\n"));		DEBUG(0, ("winbindd: cannot continue, exiting.\n"));		return False;	}		return True;}BOOL is_in_uid_range(uid_t uid){	return ((uid >= server_state.uid_low) &&		(uid <= server_state.uid_high));}BOOL is_in_gid_range(gid_t gid){	return ((gid >= server_state.gid_low) &&		(gid <= server_state.gid_high));}/* Is this a domain which we may assume no DOMAIN\ prefix? */static BOOL assume_domain(const char *domain) {	if ((lp_winbind_use_default_domain()  		  || lp_winbind_trusted_domains_only()) &&	    strequal(lp_workgroup(), domain)) 		return True;	if (strequal(get_global_sam_name(), domain)) 		return True;		return False;}/* Parse a string of the form DOMAIN\user into a domain and a user */BOOL parse_domain_user(const char *domuser, fstring domain, fstring user){	char *p = strchr(domuser,*lp_winbind_separator());	if ( !p ) {		fstrcpy(user, domuser);				if ( assume_domain(lp_workgroup())) {			fstrcpy(domain, lp_workgroup());		} else {			fstrcpy( domain, get_global_sam_name() ); 		}	} 	else {		fstrcpy(user, p+1);		fstrcpy(domain, domuser);		domain[PTR_DIFF(p, domuser)] = 0;	}		strupper_m(domain);		return True;}BOOL parse_domain_user_talloc(TALLOC_CTX *mem_ctx, const char *domuser,			      char **domain, char **user){	fstring fstr_domain, fstr_user;	parse_domain_user(domuser, fstr_domain, fstr_user);	*domain = talloc_strdup(mem_ctx, fstr_domain);	*user = talloc_strdup(mem_ctx, fstr_user);	return ((*domain != NULL) && (*user != NULL));}/*    Fill DOMAIN\\USERNAME entry accounting 'winbind use default domain' and    'winbind separator' options.    This means:	- omit DOMAIN when 'winbind use default domain = true' and DOMAIN is	lp_workgroup()    If we are a PDC or BDC, and this is for our domain, do likewise.    Also, if omit DOMAIN if 'winbind trusted domains only = true', as the     username is then unqualified in unix	 */void fill_domain_username(fstring name, const char *domain, const char *user){	fstring tmp_user;	fstrcpy(tmp_user, user);	strlower_m(tmp_user);	if (assume_domain(domain)) {		strlcpy(name, user, sizeof(fstring));	} else {		slprintf(name, sizeof(fstring) - 1, "%s%c%s",			 domain, *lp_winbind_separator(),			 tmp_user);	}}/* * Winbindd socket accessor functions */char *get_winbind_priv_pipe_dir(void) {	return lock_path(WINBINDD_PRIV_SOCKET_SUBDIR);}/* Open the winbindd socket */static int _winbindd_socket = -1;static int _winbindd_priv_socket = -1;int open_winbindd_socket(void){	if (_winbindd_socket == -1) {		_winbindd_socket = create_pipe_sock(			WINBINDD_SOCKET_DIR, WINBINDD_SOCKET_NAME, 0755);		DEBUG(10, ("open_winbindd_socket: opened socket fd %d\n",			   _winbindd_socket));	}	return _winbindd_socket;}int open_winbindd_priv_socket(void){	if (_winbindd_priv_socket == -1) {		_winbindd_priv_socket = create_pipe_sock(			get_winbind_priv_pipe_dir(), WINBINDD_SOCKET_NAME, 0750);		DEBUG(10, ("open_winbindd_priv_socket: opened socket fd %d\n",			   _winbindd_priv_socket));	}	return _winbindd_priv_socket;}/* Close the winbindd socket */void close_winbindd_socket(void){	if (_winbindd_socket != -1) {		DEBUG(10, ("close_winbindd_socket: closing socket fd %d\n",			   _winbindd_socket));		close(_winbindd_socket);		_winbindd_socket = -1;	}	if (_winbindd_priv_socket != -1) {		DEBUG(10, ("close_winbindd_socket: closing socket fd %d\n",			   _winbindd_priv_socket));		close(_winbindd_priv_socket);		_winbindd_priv_socket = -1;	}}/* * Client list accessor functions */static struct winbindd_cli_state *_client_list;static int _num_clients;/* Return list of all connected clients */struct winbindd_cli_state *winbindd_client_list(void){	return _client_list;}/* Add a connection to the list */void winbindd_add_client(struct winbindd_cli_state *cli){	DLIST_ADD(_client_list, cli);	_num_clients++;}/* Remove a client from the list */void winbindd_remove_client(struct winbindd_cli_state *cli){	DLIST_REMOVE(_client_list, cli);	_num_clients--;}/* Demote a client to be the last in the list */void winbindd_demote_client(struct winbindd_cli_state *cli){	struct winbindd_cli_state *tmp;	DLIST_DEMOTE(_client_list, cli, tmp);}/* Close all open clients */void winbindd_kill_all_clients(void){	struct winbindd_cli_state *cl = winbindd_client_list();	DEBUG(10, ("winbindd_kill_all_clients: going postal\n"));	while (cl) {		struct winbindd_cli_state *next;				next = cl->next;		winbindd_remove_client(cl);		cl = next;	}}/* Return number of open clients */int winbindd_num_clients(void){	return _num_clients;}/***************************************************************************** For idmap conversion: convert one record to new format Ancient versions (eg 2.2.3a) of winbindd_idmap.tdb mapped DOMAINNAME/rid instead of the SID.*****************************************************************************/static int convert_fn(TDB_CONTEXT *tdb, TDB_DATA key, TDB_DATA data, void *state){	struct winbindd_domain *domain;	char *p;	DOM_SID sid;	uint32 rid;	fstring keystr;	fstring dom_name;	TDB_DATA key2;	BOOL *failed = (BOOL *)state;	DEBUG(10,("Converting %s\n", key.dptr));	p = strchr(key.dptr, '/');	if (!p)		return 0;	*p = 0;	fstrcpy(dom_name, key.dptr);	*p++ = '/';	domain = find_domain_from_name(dom_name);	if (domain == NULL) {		/* We must delete the old record. */		DEBUG(0,("Unable to find domain %s\n", dom_name ));		DEBUG(0,("deleting record %s\n", key.dptr ));		if (tdb_delete(tdb, key) != 0) {			DEBUG(0, ("Unable to delete record %s\n", key.dptr));			*failed = True;			return -1;		}		return 0;	}	rid = atoi(p);	sid_copy(&sid, &domain->sid);	sid_append_rid(&sid, rid);	sid_to_string(keystr, &sid);	key2.dptr = keystr;	key2.dsize = strlen(keystr) + 1;	if (tdb_store(tdb, key2, data, TDB_INSERT) != 0) {		DEBUG(0,("Unable to add record %s\n", key2.dptr ));		*failed = True;		return -1;	}	if (tdb_store(tdb, data, key2, TDB_REPLACE) != 0) {		DEBUG(0,("Unable to update record %s\n", data.dptr ));		*failed = True;		return -1;	}	if (tdb_delete(tdb, key) != 0) {		DEBUG(0,("Unable to delete record %s\n", key.dptr ));		*failed = True;		return -1;	}	return 0;}/* These definitions are from sam/idmap_tdb.c. Replicated here just   out of laziness.... :-( *//* High water mark keys */#define HWM_GROUP  "GROUP HWM"#define HWM_USER   "USER HWM"/* idmap version determines auto-conversion */#define IDMAP_VERSION 2/***************************************************************************** Convert the idmap database from an older version.*****************************************************************************/static BOOL idmap_convert(const char *idmap_name){	int32 vers;	BOOL bigendianheader;	BOOL failed = False;	TDB_CONTEXT *idmap_tdb;	if (!(idmap_tdb = tdb_open_log(idmap_name, 0,					TDB_DEFAULT, O_RDWR,					0600))) {		DEBUG(0, ("idmap_convert: Unable to open idmap database\n"));		return False;	}	bigendianheader = (idmap_tdb->flags & TDB_BIGENDIAN) ? True : False;	vers = tdb_fetch_int32(idmap_tdb, "IDMAP_VERSION");	if (((vers == -1) && bigendianheader) || (IREV(vers) == IDMAP_VERSION)) {		/* Arrggghh ! Bytereversed or old big-endian - make order independent ! */		/*		 * high and low records were created on a		 * big endian machine and will need byte-reversing.		 */		int32 wm;		wm = tdb_fetch_int32(idmap_tdb, HWM_USER);		if (wm != -1) {			wm = IREV(wm);		}  else {			wm = server_state.uid_low;		}		if (tdb_store_int32(idmap_tdb, HWM_USER, wm) == -1) {			DEBUG(0, ("idmap_convert: Unable to byteswap user hwm in idmap database\n"));			tdb_close(idmap_tdb);			return False;		}		wm = tdb_fetch_int32(idmap_tdb, HWM_GROUP);		if (wm != -1) {			wm = IREV(wm);		} else {			wm = server_state.gid_low;		}		if (tdb_store_int32(idmap_tdb, HWM_GROUP, wm) == -1) {			DEBUG(0, ("idmap_convert: Unable to byteswap group hwm in idmap database\n"));			tdb_close(idmap_tdb);			return False;		}	}	/* the old format stored as DOMAIN/rid - now we store the SID direct */	tdb_traverse(idmap_tdb, convert_fn, &failed);	if (failed) {		DEBUG(0, ("Problem during conversion\n"));		tdb_close(idmap_tdb);		return False;	}	if (tdb_store_int32(idmap_tdb, "IDMAP_VERSION", IDMAP_VERSION) == -1) {		DEBUG(0, ("idmap_convert: Unable to dtore idmap version in databse\n"));		tdb_close(idmap_tdb);		return False;	}	tdb_close(idmap_tdb);	return True;}/***************************************************************************** Convert the idmap database from an older version if necessary*****************************************************************************/BOOL winbindd_upgrade_idmap(void){	pstring idmap_name;	pstring backup_name;	SMB_STRUCT_STAT stbuf;	TDB_CONTEXT *idmap_tdb;	pstrcpy(idmap_name, lock_path("winbindd_idmap.tdb"));	if (!file_exist(idmap_name, &stbuf)) {		/* nothing to convert return */		return True;	}	if (!(idmap_tdb = tdb_open_log(idmap_name, 0,					TDB_DEFAULT, O_RDWR,					0600))) {		DEBUG(0, ("idmap_convert: Unable to open idmap database\n"));		return False;	}	if (tdb_fetch_int32(idmap_tdb, "IDMAP_VERSION") == IDMAP_VERSION) {		/* nothing to convert return */		tdb_close(idmap_tdb);		return True;	}	/* backup_tdb expects the tdb not to be open */	tdb_close(idmap_tdb);	DEBUG(0, ("Upgrading winbindd_idmap.tdb from an old version\n"));	pstrcpy(backup_name, idmap_name);	pstrcat(backup_name, ".bak");	if (backup_tdb(idmap_name, backup_name) != 0) {		DEBUG(0, ("Could not backup idmap database\n"));		return False;	}	return idmap_convert(idmap_name);}

⌨️ 快捷键说明

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