1/* 2 Unix SMB/CIFS implementation. 3 4 Backend for getpwuid 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_getpwuid_state { 34 struct composite_context *ctx; 35 struct wbsrv_service *service; 36 uid_t uid; 37 struct dom_sid *sid; 38 char *workgroup; 39 struct wbsrv_domain *domain; 40 41 struct winbindd_pw *result; 42}; 43 44static void cmd_getpwuid_recv_sid(struct composite_context *ctx); 45static void cmd_getpwuid_recv_domain(struct composite_context *ctx); 46static void cmd_getpwuid_recv_user_info(struct composite_context *ctx); 47static void cmd_getpwuid_recv_gid(struct composite_context *ctx); 48 49/* Get the SID using the uid */ 50 51struct composite_context *wb_cmd_getpwuid_send(TALLOC_CTX *mem_ctx, 52 struct wbsrv_service *service, 53 uid_t uid) 54{ 55 struct composite_context *ctx, *result; 56 struct cmd_getpwuid_state *state; 57 58 DEBUG(5, ("wb_cmd_getpwuid_send called\n")); 59 60 result = composite_create(mem_ctx, service->task->event_ctx); 61 if (!result) return NULL; 62 63 state = talloc(result, struct cmd_getpwuid_state); 64 if (composite_nomem(state, result)) return result; 65 state->ctx = result; 66 result->private_data = state; 67 state->service = service; 68 state->uid = uid; 69 70 ctx = wb_uid2sid_send(state, service, uid); 71 if (composite_nomem(ctx, state->ctx)) return result; 72 73 composite_continue(result, ctx, cmd_getpwuid_recv_sid, state); 74 return result; 75} 76 77 78/* Receive the sid and get the domain structure with it */ 79 80static void cmd_getpwuid_recv_sid(struct composite_context *ctx) 81{ 82 struct cmd_getpwuid_state *state = 83 talloc_get_type(ctx->async.private_data, 84 struct cmd_getpwuid_state); 85 86 DEBUG(5, ("cmd_getpwuid_recv_sid called %p\n", ctx->private_data)); 87 88 state->ctx->status = wb_uid2sid_recv(ctx, state, &state->sid); 89 if (!composite_is_ok(state->ctx)) return; 90 91 ctx = wb_sid2domain_send(state, state->service, state->sid); 92 93 composite_continue(state->ctx, ctx, cmd_getpwuid_recv_domain, state); 94} 95 96/* Receive the domain struct and call libnet to get the user info struct */ 97 98static void cmd_getpwuid_recv_domain(struct composite_context *ctx) 99{ 100 struct cmd_getpwuid_state *state = 101 talloc_get_type(ctx->async.private_data, 102 struct cmd_getpwuid_state); 103 struct libnet_UserInfo *user_info; 104 105 DEBUG(5, ("cmd_getpwuid_recv_domain called\n")); 106 107 state->ctx->status = wb_sid2domain_recv(ctx, &state->domain); 108 if (!composite_is_ok(state->ctx)) return; 109 110 user_info = talloc(state, struct libnet_UserInfo); 111 if (composite_nomem(user_info, state->ctx)) return; 112 113 user_info->in.level = USER_INFO_BY_SID; 114 user_info->in.data.user_sid = state->sid; 115 user_info->in.domain_name = state->domain->libnet_ctx->samr.name; 116 117 /* We need the workgroup later, so copy it */ 118 state->workgroup = talloc_strdup(state, 119 state->domain->libnet_ctx->samr.name); 120 if (composite_nomem(state->workgroup, state->ctx)) return; 121 122 ctx = libnet_UserInfo_send(state->domain->libnet_ctx, state, user_info, 123 NULL); 124 125 composite_continue(state->ctx, ctx, cmd_getpwuid_recv_user_info, state); 126} 127 128/* Receive the user info struct and get the gid for the user */ 129 130static void cmd_getpwuid_recv_user_info(struct composite_context *ctx) 131{ 132 struct cmd_getpwuid_state *state = 133 talloc_get_type(ctx->async.private_data, 134 struct cmd_getpwuid_state); 135 struct libnet_UserInfo *user_info; 136 struct winbindd_pw *pw; 137 138 DEBUG(5, ("cmd_getpwuid_recv_user_info called\n")); 139 140 pw = talloc(state, struct winbindd_pw); 141 if (composite_nomem(pw, state->ctx)) return; 142 143 user_info = talloc(state, struct libnet_UserInfo); 144 if(composite_nomem(user_info, state->ctx)) return; 145 146 state->ctx->status = libnet_UserInfo_recv(ctx, state, user_info); 147 if (!composite_is_ok(state->ctx)) return; 148 149 WBSRV_SAMBA3_SET_STRING(pw->pw_name, user_info->out.account_name); 150 WBSRV_SAMBA3_SET_STRING(pw->pw_passwd, "*"); 151 WBSRV_SAMBA3_SET_STRING(pw->pw_gecos, user_info->out.full_name); 152 WBSRV_SAMBA3_SET_STRING(pw->pw_dir, 153 lp_template_homedir(state->service->task->lp_ctx)); 154 all_string_sub(pw->pw_dir, "%WORKGROUP%", state->workgroup, 155 sizeof(fstring) - 1); 156 all_string_sub(pw->pw_dir, "%ACCOUNTNAME%", user_info->out.account_name, 157 sizeof(fstring) - 1); 158 WBSRV_SAMBA3_SET_STRING(pw->pw_shell, 159 lp_template_shell(state->service->task->lp_ctx)); 160 161 pw->pw_uid = state->uid; 162 163 state->result = pw; 164 165 ctx = wb_sid2gid_send(state, state->service, 166 user_info->out.primary_group_sid); 167 168 composite_continue(state->ctx, ctx, cmd_getpwuid_recv_gid, state); 169} 170 171static void cmd_getpwuid_recv_gid(struct composite_context *ctx) 172{ 173 struct cmd_getpwuid_state *state = 174 talloc_get_type(ctx->async.private_data, 175 struct cmd_getpwuid_state); 176 gid_t gid; 177 178 DEBUG(5, ("cmd_getpwuid_recv_gid called\n")); 179 180 state->ctx->status = wb_sid2gid_recv(ctx, &gid); 181 if (!composite_is_ok(state->ctx)) return; 182 183 state->result->pw_gid = gid; 184 185 composite_done(state->ctx); 186} 187 188NTSTATUS wb_cmd_getpwuid_recv(struct composite_context *ctx, 189 TALLOC_CTX *mem_ctx, struct winbindd_pw **pw) 190{ 191 NTSTATUS status = composite_wait(ctx); 192 193 DEBUG(5, ("wb_cmd_getpwuid_recv called\n")); 194 195 if (NT_STATUS_IS_OK(status)) { 196 struct cmd_getpwuid_state *state = 197 talloc_get_type(ctx->private_data, 198 struct cmd_getpwuid_state); 199 *pw = talloc_steal(mem_ctx, state->result); 200 } 201 talloc_free(ctx); 202 return status; 203 204} 205 206