1/* 2 Unix SMB/CIFS implementation. 3 4 endpoint server for the unixinfo pipe 5 6 Copyright (C) Volker Lendecke 2005 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 "rpc_server/dcerpc_server.h" 24#include "librpc/gen_ndr/ndr_unixinfo.h" 25#include "libcli/wbclient/wbclient.h" 26#include "system/passwd.h" 27 28static NTSTATUS dcerpc_unixinfo_bind(struct dcesrv_call_state *dce_call, 29 const struct dcesrv_interface *iface) 30{ 31 struct wbc_context *wbc_ctx; 32 33 wbc_ctx = wbc_init(dce_call->context, dce_call->msg_ctx, 34 dce_call->event_ctx); 35 NT_STATUS_HAVE_NO_MEMORY(wbc_ctx); 36 37 dce_call->context->private_data = wbc_ctx; 38 39 return NT_STATUS_OK; 40} 41 42#define DCESRV_INTERFACE_UNIXINFO_BIND dcerpc_unixinfo_bind 43 44static NTSTATUS dcesrv_unixinfo_SidToUid(struct dcesrv_call_state *dce_call, 45 TALLOC_CTX *mem_ctx, 46 struct unixinfo_SidToUid *r) 47{ 48 NTSTATUS status; 49 struct wbc_context *wbc_ctx = talloc_get_type_abort( 50 dce_call->context->private_data, 51 struct wbc_context); 52 struct id_mapping *ids; 53 struct composite_context *ctx; 54 55 DEBUG(5, ("dcesrv_unixinfo_SidToUid called\n")); 56 57 ids = talloc(mem_ctx, struct id_mapping); 58 NT_STATUS_HAVE_NO_MEMORY(ids); 59 60 ids->sid = &r->in.sid; 61 ids->status = NT_STATUS_NONE_MAPPED; 62 ids->unixid = NULL; 63 ctx = wbc_sids_to_xids_send(wbc_ctx, ids, 1, ids); 64 NT_STATUS_HAVE_NO_MEMORY(ctx); 65 66 status = wbc_sids_to_xids_recv(ctx, &ids); 67 NT_STATUS_NOT_OK_RETURN(status); 68 69 if (ids->unixid->type == ID_TYPE_BOTH || 70 ids->unixid->type == ID_TYPE_UID) { 71 *r->out.uid = ids->unixid->id; 72 return NT_STATUS_OK; 73 } else { 74 return NT_STATUS_INVALID_SID; 75 } 76} 77 78static NTSTATUS dcesrv_unixinfo_UidToSid(struct dcesrv_call_state *dce_call, 79 TALLOC_CTX *mem_ctx, 80 struct unixinfo_UidToSid *r) 81{ 82 struct wbc_context *wbc_ctx = talloc_get_type_abort( 83 dce_call->context->private_data, 84 struct wbc_context); 85 struct id_mapping *ids; 86 struct composite_context *ctx; 87 uint32_t uid; 88 NTSTATUS status; 89 90 DEBUG(5, ("dcesrv_unixinfo_UidToSid called\n")); 91 92 uid = r->in.uid; /* This cuts uid to 32 bit */ 93 if ((uint64_t)uid != r->in.uid) { 94 DEBUG(10, ("uid out of range\n")); 95 return NT_STATUS_INVALID_PARAMETER; 96 } 97 98 ids = talloc(mem_ctx, struct id_mapping); 99 NT_STATUS_HAVE_NO_MEMORY(ids); 100 101 ids->sid = NULL; 102 ids->status = NT_STATUS_NONE_MAPPED; 103 ids->unixid = talloc(ids, struct unixid); 104 NT_STATUS_HAVE_NO_MEMORY(ids->unixid); 105 106 ids->unixid->id = uid; 107 ids->unixid->type = ID_TYPE_UID; 108 109 ctx = wbc_xids_to_sids_send(wbc_ctx, ids, 1, ids); 110 NT_STATUS_HAVE_NO_MEMORY(ctx); 111 112 status = wbc_xids_to_sids_recv(ctx, &ids); 113 NT_STATUS_NOT_OK_RETURN(status); 114 115 r->out.sid = ids->sid; 116 return NT_STATUS_OK; 117} 118 119static NTSTATUS dcesrv_unixinfo_SidToGid(struct dcesrv_call_state *dce_call, 120 TALLOC_CTX *mem_ctx, 121 struct unixinfo_SidToGid *r) 122{ 123 NTSTATUS status; 124 struct wbc_context *wbc_ctx = talloc_get_type_abort( 125 dce_call->context->private_data, 126 struct wbc_context); 127 struct id_mapping *ids; 128 struct composite_context *ctx; 129 130 DEBUG(5, ("dcesrv_unixinfo_SidToGid called\n")); 131 132 ids = talloc(mem_ctx, struct id_mapping); 133 NT_STATUS_HAVE_NO_MEMORY(ids); 134 135 ids->sid = &r->in.sid; 136 ids->status = NT_STATUS_NONE_MAPPED; 137 ids->unixid = NULL; 138 ctx = wbc_sids_to_xids_send(wbc_ctx, ids, 1, ids); 139 NT_STATUS_HAVE_NO_MEMORY(ctx); 140 141 status = wbc_sids_to_xids_recv(ctx, &ids); 142 NT_STATUS_NOT_OK_RETURN(status); 143 144 if (ids->unixid->type == ID_TYPE_BOTH || 145 ids->unixid->type == ID_TYPE_GID) { 146 *r->out.gid = ids->unixid->id; 147 return NT_STATUS_OK; 148 } else { 149 return NT_STATUS_INVALID_SID; 150 } 151} 152 153static NTSTATUS dcesrv_unixinfo_GidToSid(struct dcesrv_call_state *dce_call, 154 TALLOC_CTX *mem_ctx, 155 struct unixinfo_GidToSid *r) 156{ 157 struct wbc_context *wbc_ctx = talloc_get_type_abort( 158 dce_call->context->private_data, 159 struct wbc_context); 160 struct id_mapping *ids; 161 struct composite_context *ctx; 162 uint32_t gid; 163 NTSTATUS status; 164 165 DEBUG(5, ("dcesrv_unixinfo_GidToSid called\n")); 166 167 gid = r->in.gid; /* This cuts gid to 32 bit */ 168 if ((uint64_t)gid != r->in.gid) { 169 DEBUG(10, ("gid out of range\n")); 170 return NT_STATUS_INVALID_PARAMETER; 171 } 172 173 ids = talloc(mem_ctx, struct id_mapping); 174 NT_STATUS_HAVE_NO_MEMORY(ids); 175 176 ids->sid = NULL; 177 ids->status = NT_STATUS_NONE_MAPPED; 178 ids->unixid = talloc(ids, struct unixid); 179 NT_STATUS_HAVE_NO_MEMORY(ids->unixid); 180 181 ids->unixid->id = gid; 182 ids->unixid->type = ID_TYPE_GID; 183 184 ctx = wbc_xids_to_sids_send(wbc_ctx, ids, 1, ids); 185 NT_STATUS_HAVE_NO_MEMORY(ctx); 186 187 status = wbc_xids_to_sids_recv(ctx, &ids); 188 NT_STATUS_NOT_OK_RETURN(status); 189 190 r->out.sid = ids->sid; 191 return NT_STATUS_OK; 192} 193 194static NTSTATUS dcesrv_unixinfo_GetPWUid(struct dcesrv_call_state *dce_call, 195 TALLOC_CTX *mem_ctx, 196 struct unixinfo_GetPWUid *r) 197{ 198 int i; 199 200 *r->out.count = 0; 201 202 r->out.infos = talloc_zero_array(mem_ctx, struct unixinfo_GetPWUidInfo, 203 *r->in.count); 204 NT_STATUS_HAVE_NO_MEMORY(r->out.infos); 205 *r->out.count = *r->in.count; 206 207 for (i=0; i < *r->in.count; i++) { 208 uid_t uid; 209 struct passwd *pwd; 210 211 uid = r->in.uids[i]; 212 pwd = getpwuid(uid); 213 if (pwd == NULL) { 214 DEBUG(10, ("uid %d not found\n", uid)); 215 r->out.infos[i].homedir = ""; 216 r->out.infos[i].shell = ""; 217 r->out.infos[i].status = NT_STATUS_NO_SUCH_USER; 218 continue; 219 } 220 221 r->out.infos[i].homedir = talloc_strdup(mem_ctx, pwd->pw_dir); 222 r->out.infos[i].shell = talloc_strdup(mem_ctx, pwd->pw_shell); 223 224 if ((r->out.infos[i].homedir == NULL) || 225 (r->out.infos[i].shell == NULL)) { 226 r->out.infos[i].homedir = ""; 227 r->out.infos[i].shell = ""; 228 r->out.infos[i].status = NT_STATUS_NO_MEMORY; 229 continue; 230 } 231 232 r->out.infos[i].status = NT_STATUS_OK; 233 } 234 235 return NT_STATUS_OK; 236} 237 238/* include the generated boilerplate */ 239#include "librpc/gen_ndr/ndr_unixinfo_s.c" 240