winbindd_async.c

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

C
1,441
字号
/*    Unix SMB/CIFS implementation.   Async helpers for blocking functions   Copyright (C) Volker Lendecke 2005      The helpers always consist of three functions:    * A request setup function that takes the necessary parameters together     with a continuation function that is to be called upon completion   * A private continuation function that is internal only. This is to be     called by the lower-level functions in do_async(). Its only task is to     properly call the continuation function named above.   * A worker function that is called inside the appropriate child process.   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"#undef DBGC_CLASS#define DBGC_CLASS DBGC_WINBINDstruct do_async_state {	TALLOC_CTX *mem_ctx;	struct winbindd_request request;	struct winbindd_response response;	void (*cont)(TALLOC_CTX *mem_ctx,		     BOOL success,		     struct winbindd_response *response,		     void *c, void *private_data);	void *c, *private_data;};static void do_async_recv(void *private_data, BOOL success){	struct do_async_state *state =		talloc_get_type_abort(private_data, struct do_async_state);	state->cont(state->mem_ctx, success, &state->response,		    state->c, state->private_data);}static void do_async(TALLOC_CTX *mem_ctx, struct winbindd_child *child,		     const struct winbindd_request *request,		     void (*cont)(TALLOC_CTX *mem_ctx, BOOL success,				  struct winbindd_response *response,				  void *c, void *private_data),		     void *c, void *private_data){	struct do_async_state *state;	state = TALLOC_P(mem_ctx, struct do_async_state);	if (state == NULL) {		DEBUG(0, ("talloc failed\n"));		cont(mem_ctx, False, NULL, c, private_data);		return;	}	state->mem_ctx = mem_ctx;	state->request = *request;	state->request.length = sizeof(state->request);	state->cont = cont;	state->c = c;	state->private_data = private_data;	async_request(mem_ctx, child, &state->request,		      &state->response, do_async_recv, state);}void do_async_domain(TALLOC_CTX *mem_ctx, struct winbindd_domain *domain,		     const struct winbindd_request *request,		     void (*cont)(TALLOC_CTX *mem_ctx, BOOL success,				  struct winbindd_response *response,				  void *c, void *private_data),		     void *c, void *private_data){	struct do_async_state *state;	state = TALLOC_P(mem_ctx, struct do_async_state);	if (state == NULL) {		DEBUG(0, ("talloc failed\n"));		cont(mem_ctx, False, NULL, c, private_data);		return;	}	state->mem_ctx = mem_ctx;	state->request = *request;	state->request.length = sizeof(state->request);	state->cont = cont;	state->c = c;	state->private_data = private_data;	async_domain_request(mem_ctx, domain, &state->request,			     &state->response, do_async_recv, state);}static void idmap_set_mapping_recv(TALLOC_CTX *mem_ctx, BOOL success,				   struct winbindd_response *response,				   void *c, void *private_data){	void (*cont)(void *priv, BOOL succ) = c;	if (!success) {		DEBUG(5, ("Could not trigger idmap_set_mapping\n"));		cont(private_data, False);		return;	}	if (response->result != WINBINDD_OK) {		DEBUG(5, ("idmap_set_mapping returned an error\n"));		cont(private_data, False);		return;	}	cont(private_data, True);}void idmap_set_mapping_async(TALLOC_CTX *mem_ctx, const DOM_SID *sid,			     unid_t id, int id_type,			     void (*cont)(void *private_data, BOOL success),			     void *private_data){	struct winbindd_request request;	ZERO_STRUCT(request);	request.cmd = WINBINDD_DUAL_IDMAPSET;	if (id_type == ID_USERID)		request.data.dual_idmapset.uid = id.uid;	else		request.data.dual_idmapset.gid = id.gid;	request.data.dual_idmapset.type = id_type;	sid_to_string(request.data.dual_idmapset.sid, sid);	do_async(mem_ctx, idmap_child(), &request, idmap_set_mapping_recv,		 cont, private_data);}enum winbindd_result winbindd_dual_idmapset(struct winbindd_domain *domain,					    struct winbindd_cli_state *state){	DOM_SID sid;	unid_t id;	NTSTATUS result;	DEBUG(3, ("[%5lu]: dual_idmapset\n", (unsigned long)state->pid));	if (!string_to_sid(&sid, state->request.data.dual_idmapset.sid))		return WINBINDD_ERROR;	if (state->request.data.dual_idmapset.type == ID_USERID)		id.uid = state->request.data.dual_idmapset.uid;	else		id.gid = state->request.data.dual_idmapset.gid;	result = idmap_set_mapping(&sid, id,				   state->request.data.dual_idmapset.type);	return NT_STATUS_IS_OK(result) ? WINBINDD_OK : WINBINDD_ERROR;}static void idmap_sid2uid_recv(TALLOC_CTX *mem_ctx, BOOL success,			       struct winbindd_response *response,			       void *c, void *private_data);void idmap_sid2uid_async(TALLOC_CTX *mem_ctx, const DOM_SID *sid, BOOL alloc,			 void (*cont)(void *private_data, BOOL success, uid_t uid),			 void *private_data){	struct winbindd_request request;	ZERO_STRUCT(request);	request.cmd = WINBINDD_DUAL_SID2UID;	sid_to_string(request.data.dual_sid2id.sid, sid);	request.data.dual_sid2id.alloc = alloc;	do_async(mem_ctx, idmap_child(), &request, idmap_sid2uid_recv,		 cont, private_data);}enum winbindd_result winbindd_dual_sid2uid(struct winbindd_domain *domain,					   struct winbindd_cli_state *state){	DOM_SID sid;	NTSTATUS result;	DEBUG(3, ("[%5lu]: sid to uid %s\n", (unsigned long)state->pid,		  state->request.data.dual_sid2id.sid));	if (!string_to_sid(&sid, state->request.data.dual_sid2id.sid)) {		DEBUG(1, ("Could not get convert sid %s from string\n",			  state->request.data.dual_sid2id.sid));		return WINBINDD_ERROR;	}	/* Find uid for this sid and return it, possibly ask the slow remote	 * idmap */	result = idmap_sid_to_uid(&sid, &(state->response.data.uid),				  state->request.data.dual_sid2id.alloc ?				  0 : ID_QUERY_ONLY);	return NT_STATUS_IS_OK(result) ? WINBINDD_OK : WINBINDD_ERROR;}static void idmap_sid2uid_recv(TALLOC_CTX *mem_ctx, BOOL success,			       struct winbindd_response *response,			       void *c, void *private_data){	void (*cont)(void *priv, BOOL succ, uid_t uid) = c;	if (!success) {		DEBUG(5, ("Could not trigger sid2uid\n"));		cont(private_data, False, 0);		return;	}	if (response->result != WINBINDD_OK) {		DEBUG(5, ("sid2uid returned an error\n"));		cont(private_data, False, 0);		return;	}	cont(private_data, True, response->data.uid);}			 static void uid2name_recv(TALLOC_CTX *mem_ctx, BOOL success,			  struct winbindd_response *response,			  void *c, void *private_data);void winbindd_uid2name_async(TALLOC_CTX *mem_ctx, uid_t uid,			     void (*cont)(void *private_data, BOOL success,					  const char *name),			     void *private_data){	struct winbindd_request request;	ZERO_STRUCT(request);	request.cmd = WINBINDD_DUAL_UID2NAME;	request.data.uid = uid;	do_async(mem_ctx, idmap_child(), &request, uid2name_recv,		 cont, private_data);}enum winbindd_result winbindd_dual_uid2name(struct winbindd_domain *domain,					    struct winbindd_cli_state *state){	struct passwd *pw;	DEBUG(3, ("[%5lu]: uid2name %lu\n", (unsigned long)state->pid, 		  (unsigned long)state->request.data.uid));	pw = getpwuid(state->request.data.uid);	if (pw == NULL) {		DEBUG(5, ("User %lu not found\n",			  (unsigned long)state->request.data.uid));		return WINBINDD_ERROR;	}	fstrcpy(state->response.data.name.name, pw->pw_name);	return WINBINDD_OK;}static void uid2name_recv(TALLOC_CTX *mem_ctx, BOOL success,			  struct winbindd_response *response,			  void *c, void *private_data){	void (*cont)(void *priv, BOOL succ, const char *name) = c;	if (!success) {		DEBUG(5, ("Could not trigger uid2name\n"));		cont(private_data, False, NULL);		return;	}	if (response->result != WINBINDD_OK) {		DEBUG(5, ("uid2name returned an error\n"));		cont(private_data, False, NULL);		return;	}	cont(private_data, True, response->data.name.name);}static void name2uid_recv(TALLOC_CTX *mem_ctx, BOOL success,			  struct winbindd_response *response,			  void *c, void *private_data);static void winbindd_name2uid_async(TALLOC_CTX *mem_ctx, const char *name,				    void (*cont)(void *private_data, BOOL success,						 uid_t uid),				    void *private_data){	struct winbindd_request request;	ZERO_STRUCT(request);	request.cmd = WINBINDD_DUAL_NAME2UID;	fstrcpy(request.data.username, name);	do_async(mem_ctx, idmap_child(), &request, name2uid_recv,		 cont, private_data);}enum winbindd_result winbindd_dual_name2uid(struct winbindd_domain *domain,					    struct winbindd_cli_state *state){	struct passwd *pw;	/* Ensure null termination */	state->request.data.username		[sizeof(state->request.data.username)-1] = '\0';	DEBUG(3, ("[%5lu]: name2uid %s\n", (unsigned long)state->pid, 		  state->request.data.username));	pw = getpwnam(state->request.data.username);	if (pw == NULL) {		return WINBINDD_ERROR;	}	state->response.data.uid = pw->pw_uid;	return WINBINDD_OK;}static void name2uid_recv(TALLOC_CTX *mem_ctx, BOOL success,			  struct winbindd_response *response,			  void *c, void *private_data){	void (*cont)(void *priv, BOOL succ, uid_t uid) = c;	if (!success) {		DEBUG(5, ("Could not trigger name2uid\n"));		cont(private_data, False, 0);		return;	}	if (response->result != WINBINDD_OK) {		DEBUG(5, ("name2uid returned an error\n"));		cont(private_data, False, 0);		return;	}	cont(private_data, True, response->data.uid);}static void idmap_sid2gid_recv(TALLOC_CTX *mem_ctx, BOOL success,			       struct winbindd_response *response,			       void *c, void *private_data);void idmap_sid2gid_async(TALLOC_CTX *mem_ctx, const DOM_SID *sid, BOOL alloc,			 void (*cont)(void *private_data, BOOL success, gid_t gid),			 void *private_data){	struct winbindd_request request;	ZERO_STRUCT(request);	request.cmd = WINBINDD_DUAL_SID2GID;	sid_to_string(request.data.dual_sid2id.sid, sid);	request.data.dual_sid2id.alloc = alloc;	do_async(mem_ctx, idmap_child(), &request, idmap_sid2gid_recv,		 cont, private_data);}enum winbindd_result winbindd_dual_sid2gid(struct winbindd_domain *domain,					   struct winbindd_cli_state *state){	DOM_SID sid;	NTSTATUS result;	DEBUG(3, ("[%5lu]: sid to gid %s\n", (unsigned long)state->pid,		  state->request.data.dual_sid2id.sid));	if (!string_to_sid(&sid, state->request.data.dual_sid2id.sid)) {		DEBUG(1, ("Could not get convert sid %s from string\n",			  state->request.data.dual_sid2id.sid));		return WINBINDD_ERROR;	}	/* Find gid for this sid and return it, possibly ask the slow remote	 * idmap */	result = idmap_sid_to_gid(&sid, &(state->response.data.gid),				  state->request.data.dual_sid2id.alloc ?				  0 : ID_QUERY_ONLY);	return NT_STATUS_IS_OK(result) ? WINBINDD_OK : WINBINDD_ERROR;}static void idmap_sid2gid_recv(TALLOC_CTX *mem_ctx, BOOL success,			       struct winbindd_response *response,			       void *c, void *private_data){	void (*cont)(void *priv, BOOL succ, gid_t gid) = c;	if (!success) {		DEBUG(5, ("Could not trigger sid2gid\n"));		cont(private_data, False, 0);		return;	}	if (response->result != WINBINDD_OK) {		DEBUG(5, ("sid2gid returned an error\n"));		cont(private_data, False, 0);		return;	}	cont(private_data, True, response->data.gid);}			 static void gid2name_recv(TALLOC_CTX *mem_ctx, BOOL success,			  struct winbindd_response *response,			  void *c, void *private_data){	void (*cont)(void *priv, BOOL succ, const char *name) = c;	if (!success) {		DEBUG(5, ("Could not trigger gid2name\n"));		cont(private_data, False, NULL);		return;	}	if (response->result != WINBINDD_OK) {		DEBUG(5, ("gid2name returned an error\n"));		cont(private_data, False, NULL);		return;	}	cont(private_data, True, response->data.name.name);}void winbindd_gid2name_async(TALLOC_CTX *mem_ctx, gid_t gid,			     void (*cont)(void *private_data, BOOL success,					  const char *name),			     void *private_data){	struct winbindd_request request;	ZERO_STRUCT(request);	request.cmd = WINBINDD_DUAL_GID2NAME;	request.data.gid = gid;	do_async(mem_ctx, idmap_child(), &request, gid2name_recv,		 cont, private_data);}enum winbindd_result winbindd_dual_gid2name(struct winbindd_domain *domain,					    struct winbindd_cli_state *state){	struct group *gr;	DEBUG(3, ("[%5lu]: gid2name %lu\n", (unsigned long)state->pid, 		  (unsigned long)state->request.data.gid));	gr = getgrgid(state->request.data.gid);	if (gr == NULL)		return WINBINDD_ERROR;	fstrcpy(state->response.data.name.name, gr->gr_name);	return WINBINDD_OK;}static void name2gid_recv(TALLOC_CTX *mem_ctx, BOOL success,			  struct winbindd_response *response,			  void *c, void *private_data);static void winbindd_name2gid_async(TALLOC_CTX *mem_ctx, const char *name,				    void (*cont)(void *private_data, BOOL success,						 gid_t gid),				    void *private_data){	struct winbindd_request request;	ZERO_STRUCT(request);	request.cmd = WINBINDD_DUAL_NAME2GID;	fstrcpy(request.data.groupname, name);	do_async(mem_ctx, idmap_child(), &request, name2gid_recv,

⌨️ 快捷键说明

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