1/* 2 Unix SMB/CIFS implementation. 3 4 Backend for getgrgid 5 6 Copyright (C) Kai Blin 2007 7 8 This program is free software; you can redistribute it and/or modify 9 it under the terms of the GNU General Public License as published by 10 the Free Software Foundation; either version 3 of the License, or 11 (at your option) any later version. 12 13 This program is distributed in the hope that it will be useful, 14 but WITHOUT ANY WARRANTY; without even the implied warranty of 15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 GNU General Public License for more details. 17 18 You should have received a copy of the GNU General Public License 19 along with this program. If not, see <http://www.gnu.org/licenses/>. 20*/ 21 22#include "includes.h" 23#include "libcli/composite/composite.h" 24#include "winbind/wb_server.h" 25#include "winbind/wb_async_helpers.h" 26#include "winbind/wb_helper.h" 27#include "smbd/service_task.h" 28#include "libnet/libnet_proto.h" 29#include "param/param.h" 30#include "libcli/security/proto.h" 31#include "auth/credentials/credentials.h" 32 33struct cmd_getgrgid_state { 34 struct composite_context *ctx; 35 struct wbsrv_service *service; 36 gid_t gid; 37 struct dom_sid *sid; 38 char *workgroup; 39 struct wbsrv_domain *domain; 40 41 struct winbindd_gr *result; 42}; 43 44static void cmd_getgrgid_recv_sid(struct composite_context *ctx); 45static void cmd_getgrgid_recv_domain(struct composite_context *ctx); 46static void cmd_getgrgid_recv_group_info(struct composite_context *ctx); 47 48/* Get the SID using the gid */ 49 50struct composite_context *wb_cmd_getgrgid_send(TALLOC_CTX *mem_ctx, 51 struct wbsrv_service *service, 52 gid_t gid) 53{ 54 struct composite_context *ctx, *result; 55 struct cmd_getgrgid_state *state; 56 57 DEBUG(5, ("wb_cmd_getgrgid_send called\n")); 58 59 result = composite_create(mem_ctx, service->task->event_ctx); 60 if (!result) return NULL; 61 62 state = talloc(result, struct cmd_getgrgid_state); 63 if (composite_nomem(state, result)) return result; 64 state->ctx = result; 65 result->private_data = state; 66 state->service = service; 67 state->gid = gid; 68 69 ctx = wb_gid2sid_send(state, service, gid); 70 if (composite_nomem(ctx, state->ctx)) return result; 71 72 composite_continue(result, ctx, cmd_getgrgid_recv_sid, state); 73 return result; 74} 75 76 77/* Receive the sid and get the domain structure with it */ 78 79static void cmd_getgrgid_recv_sid(struct composite_context *ctx) 80{ 81 struct cmd_getgrgid_state *state = 82 talloc_get_type(ctx->async.private_data, 83 struct cmd_getgrgid_state); 84 85 DEBUG(5, ("cmd_getgrgid_recv_sid called %p\n", ctx->private_data)); 86 87 state->ctx->status = wb_gid2sid_recv(ctx, state, &state->sid); 88 if (!composite_is_ok(state->ctx)) return; 89 90 ctx = wb_sid2domain_send(state, state->service, state->sid); 91 92 composite_continue(state->ctx, ctx, cmd_getgrgid_recv_domain, state); 93} 94 95/* Receive the domain struct and call libnet to get the user info struct */ 96 97static void cmd_getgrgid_recv_domain(struct composite_context *ctx) 98{ 99 struct cmd_getgrgid_state *state = 100 talloc_get_type(ctx->async.private_data, 101 struct cmd_getgrgid_state); 102 struct libnet_GroupInfo *group_info; 103 104 DEBUG(5, ("cmd_getgrgid_recv_domain called\n")); 105 106 state->ctx->status = wb_sid2domain_recv(ctx, &state->domain); 107 if (!composite_is_ok(state->ctx)) return; 108 109 group_info = talloc(state, struct libnet_GroupInfo); 110 if (composite_nomem(group_info, state->ctx)) return; 111 112 group_info->in.level = GROUP_INFO_BY_SID; 113 group_info->in.data.group_sid = state->sid; 114 group_info->in.domain_name = state->domain->libnet_ctx->samr.name; 115 116 /* We need the workgroup later, so copy it */ 117 state->workgroup = talloc_strdup(state, 118 state->domain->libnet_ctx->samr.name); 119 if (composite_nomem(state->workgroup, state->ctx)) return; 120 121 ctx = libnet_GroupInfo_send(state->domain->libnet_ctx, state,group_info, 122 NULL); 123 124 composite_continue(state->ctx, ctx, cmd_getgrgid_recv_group_info,state); 125} 126 127/* Receive the group info struct */ 128 129static void cmd_getgrgid_recv_group_info(struct composite_context *ctx) 130{ 131 struct cmd_getgrgid_state *state = 132 talloc_get_type(ctx->async.private_data, 133 struct cmd_getgrgid_state); 134 struct libnet_GroupInfo *group_info; 135 struct winbindd_gr *gr; 136 137 DEBUG(5, ("cmd_getgrgid_recv_group_info called\n")); 138 139 gr = talloc(state, struct winbindd_gr); 140 if (composite_nomem(gr, state->ctx)) return; 141 142 group_info = talloc(state, struct libnet_GroupInfo); 143 if(composite_nomem(group_info, state->ctx)) return; 144 145 state->ctx->status = libnet_GroupInfo_recv(ctx, state, group_info); 146 if (!composite_is_ok(state->ctx)) return; 147 148 WBSRV_SAMBA3_SET_STRING(gr->gr_name, group_info->out.group_name); 149 WBSRV_SAMBA3_SET_STRING(gr->gr_passwd, "*"); 150 151 gr->gr_gid = state->gid; 152 153 state->result = gr; 154 155 composite_done(state->ctx); 156} 157 158NTSTATUS wb_cmd_getgrgid_recv(struct composite_context *ctx, 159 TALLOC_CTX *mem_ctx, struct winbindd_gr **gr) 160{ 161 NTSTATUS status = composite_wait(ctx); 162 163 DEBUG(5, ("wb_cmd_getgrgid_recv called\n")); 164 165 DEBUG(5, ("status is %s\n", nt_errstr(status))); 166 167 if (NT_STATUS_IS_OK(status)) { 168 struct cmd_getgrgid_state *state = 169 talloc_get_type(ctx->private_data, 170 struct cmd_getgrgid_state); 171 *gr = talloc_steal(mem_ctx, state->result); 172 } 173 talloc_free(ctx); 174 return status; 175 176} 177 178