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 + -
显示快捷键?