Changeset 988 for vendor/current/source4/libcli/wbclient
- Timestamp:
- Nov 24, 2016, 1:14:11 PM (9 years ago)
- Location:
- vendor/current/source4/libcli/wbclient
- Files:
-
- 3 edited
Legend:
- Unmodified
- Added
- Removed
-
vendor/current/source4/libcli/wbclient/wbclient.c
r740 r988 22 22 #include "includes.h" 23 23 #include <tevent.h> 24 #include "lib/util/tevent_unix.h" 24 25 #include "libcli/wbclient/wbclient.h" 25 26 /** 27 * Initialize the wbclient context, talloc_free() when done. 28 * 29 * \param mem_ctx talloc context to allocate memory from 30 * \param msg_ctx message context to use 31 * \param 32 */ 33 struct wbc_context *wbc_init(TALLOC_CTX *mem_ctx, 34 struct messaging_context *msg_ctx, 35 struct tevent_context *event_ctx) 36 { 37 struct wbc_context *ctx; 38 39 ctx = talloc(mem_ctx, struct wbc_context); 40 if (ctx == NULL) return NULL; 41 42 ctx->event_ctx = event_ctx; 43 44 ctx->irpc_handle = irpc_binding_handle_by_name(ctx, msg_ctx, 45 "winbind_server", 46 &ndr_table_winbind); 47 if (ctx->irpc_handle == NULL) { 48 talloc_free(ctx); 26 #include "nsswitch/wb_reqtrans.h" 27 #include "system/network.h" 28 #include "libcli/util/error.h" 29 #include "libcli/security/dom_sid.h" 30 31 static int wb_simple_trans(struct tevent_context *ev, int fd, 32 struct winbindd_request *wb_req, 33 TALLOC_CTX *mem_ctx, 34 struct winbindd_response **resp, int *err) 35 { 36 struct tevent_req *req; 37 bool polled; 38 int ret; 39 40 req = wb_simple_trans_send(ev, ev, NULL, fd, wb_req); 41 if (req == NULL) { 42 *err = ENOMEM; 43 return -1; 44 } 45 46 polled = tevent_req_poll(req, ev); 47 if (!polled) { 48 *err = errno; 49 DEBUG(10, ("tevent_req_poll returned %s\n", 50 strerror(*err))); 51 return -1; 52 } 53 54 ret = wb_simple_trans_recv(req, mem_ctx, resp, err); 55 TALLOC_FREE(req); 56 return ret; 57 } 58 59 static const char *winbindd_socket_dir(void) 60 { 61 #ifdef SOCKET_WRAPPER 62 const char *env_dir; 63 64 env_dir = getenv("SELFTEST_WINBINDD_SOCKET_DIR"); 65 if (env_dir) { 66 return env_dir; 67 } 68 #endif 69 70 return WINBINDD_SOCKET_DIR; 71 } 72 73 static int winbindd_pipe_sock(void) 74 { 75 struct sockaddr_un sunaddr = {}; 76 int ret, fd; 77 char *path; 78 79 ret = asprintf(&path, "%s/%s", winbindd_socket_dir(), 80 WINBINDD_SOCKET_NAME); 81 if (ret == -1) { 82 errno = ENOMEM; 83 return -1; 84 } 85 sunaddr.sun_family = AF_UNIX; 86 strlcpy(sunaddr.sun_path, path, sizeof(sunaddr.sun_path)); 87 free(path); 88 89 fd = socket(AF_UNIX, SOCK_STREAM, 0); 90 if (fd == -1) { 91 return -1; 92 } 93 94 ret = connect(fd, (struct sockaddr *)&sunaddr, sizeof(sunaddr)); 95 if (ret == -1) { 96 int err = errno; 97 close(fd); 98 errno = err; 99 return -1; 100 } 101 102 return fd; 103 } 104 105 NTSTATUS wbc_sids_to_xids(struct tevent_context *ev, struct id_map *ids, 106 uint32_t count) 107 { 108 TALLOC_CTX *mem_ctx; 109 struct winbindd_request req = {}; 110 struct winbindd_response *resp; 111 uint32_t i; 112 int fd, ret, err; 113 char *sids, *p; 114 size_t sidslen; 115 116 fd = winbindd_pipe_sock(); 117 if (fd == -1) { 118 return map_nt_error_from_unix_common(errno); 119 } 120 121 mem_ctx = talloc_new(NULL); 122 if (mem_ctx == NULL) { 123 close(fd); 124 return NT_STATUS_NO_MEMORY; 125 } 126 127 sidslen = count * (DOM_SID_STR_BUFLEN + 1); 128 129 sids = talloc_array(mem_ctx, char, sidslen); 130 if (sids == NULL) { 131 close(fd); 132 TALLOC_FREE(mem_ctx); 133 return NT_STATUS_NO_MEMORY; 134 } 135 136 p = sids; 137 for (i=0; i<count; i++) { 138 p += dom_sid_string_buf(ids[i].sid, p, sidslen - (p - sids)); 139 *p++ = '\n'; 140 } 141 *p++ = '\0'; 142 143 DEBUG(10, ("sids=\n%s", sids)); 144 145 req.length = sizeof(struct winbindd_request); 146 req.cmd = WINBINDD_SIDS_TO_XIDS; 147 req.pid = getpid(); 148 req.extra_data.data = sids; 149 req.extra_len = (p - sids); 150 151 ret = wb_simple_trans(ev, fd, &req, mem_ctx, &resp, &err); 152 if (ret == -1) { 153 return map_nt_error_from_unix_common(err); 154 } 155 156 close(fd); 157 158 if (resp->result != WINBINDD_OK || p == NULL) { 159 return NT_STATUS_INTERNAL_ERROR; 160 } 161 162 p = resp->extra_data.data; 163 164 for (i=0; i<count; i++) { 165 struct unixid *id = &ids[i].xid; 166 char *q; 167 168 switch (p[0]) { 169 case 'U': 170 id->type = ID_TYPE_UID; 171 id->id = strtoul(p+1, &q, 10); 172 break; 173 case 'G': 174 id->type = ID_TYPE_GID; 175 id->id = strtoul(p+1, &q, 10); 176 break; 177 case 'B': 178 id->type = ID_TYPE_BOTH; 179 id->id = strtoul(p+1, &q, 10); 180 break; 181 default: 182 id->type = ID_TYPE_NOT_SPECIFIED; 183 id->id = UINT32_MAX; 184 q = strchr(p, '\n'); 185 break; 186 }; 187 ids[i].status = ID_MAPPED; 188 189 if (q == NULL || q[0] != '\n') { 190 TALLOC_FREE(mem_ctx); 191 return NT_STATUS_INTERNAL_ERROR; 192 } 193 p = q+1; 194 } 195 196 return NT_STATUS_OK; 197 } 198 199 struct wbc_id_to_sid_state { 200 struct winbindd_request wbreq; 201 struct dom_sid sid; 202 }; 203 204 static void wbc_id_to_sid_done(struct tevent_req *subreq); 205 206 static struct tevent_req *wbc_id_to_sid_send(TALLOC_CTX *mem_ctx, 207 struct tevent_context *ev, 208 int fd, const struct unixid *id) 209 { 210 struct tevent_req *req, *subreq; 211 struct wbc_id_to_sid_state *state; 212 213 req = tevent_req_create(mem_ctx, &state, struct wbc_id_to_sid_state); 214 if (req == NULL) { 49 215 return NULL; 50 216 } 51 217 52 return ctx; 53 } 54 55 struct wbc_idmap_state { 56 struct composite_context *ctx; 57 struct winbind_get_idmap *req; 218 switch(id->type) { 219 case ID_TYPE_UID: 220 state->wbreq.cmd = WINBINDD_UID_TO_SID; 221 state->wbreq.data.uid = id->id; 222 break; 223 case ID_TYPE_GID: 224 state->wbreq.cmd = WINBINDD_GID_TO_SID; 225 state->wbreq.data.gid = id->id; 226 break; 227 default: 228 tevent_req_error(req, ENOENT); 229 return tevent_req_post(req, ev); 230 } 231 232 subreq = wb_simple_trans_send(state, ev, NULL, fd, &state->wbreq); 233 if (tevent_req_nomem(subreq, req)) { 234 return tevent_req_post(req, ev); 235 } 236 tevent_req_set_callback(subreq, wbc_id_to_sid_done, req); 237 return req; 238 } 239 240 static void wbc_id_to_sid_done(struct tevent_req *subreq) 241 { 242 struct tevent_req *req = tevent_req_callback_data( 243 subreq, struct tevent_req); 244 struct wbc_id_to_sid_state *state = tevent_req_data( 245 req, struct wbc_id_to_sid_state); 246 struct winbindd_response *wbresp; 247 int ret, err; 248 249 ret = wb_simple_trans_recv(subreq, state, &wbresp, &err); 250 TALLOC_FREE(subreq); 251 if (ret == -1) { 252 tevent_req_error(req, err); 253 return; 254 } 255 if ((wbresp->result != WINBINDD_OK) || 256 !dom_sid_parse(wbresp->data.sid.sid, &state->sid)) { 257 tevent_req_error(req, ENOENT); 258 return; 259 } 260 tevent_req_done(req); 261 } 262 263 static int wbc_id_to_sid_recv(struct tevent_req *req, struct dom_sid *sid) 264 { 265 struct wbc_id_to_sid_state *state = tevent_req_data( 266 req, struct wbc_id_to_sid_state); 267 int err; 268 269 if (tevent_req_is_unix_error(req, &err)) { 270 return err; 271 } 272 sid_copy(sid, &state->sid); 273 return 0; 274 } 275 276 struct wbc_ids_to_sids_state { 277 struct tevent_context *ev; 278 int fd; 58 279 struct id_map *ids; 280 uint32_t count; 281 uint32_t idx; 59 282 }; 60 283 61 static void sids_to_xids_recv_ids(struct tevent_req *subreq); 62 63 struct composite_context *wbc_sids_to_xids_send(struct wbc_context *wbc_ctx, 64 TALLOC_CTX *mem_ctx, 65 uint32_t count, 66 struct id_map *ids) 67 { 68 struct composite_context *ctx; 69 struct wbc_idmap_state *state; 70 struct tevent_req *subreq; 71 72 DEBUG(5, ("wbc_sids_to_xids called\n")); 73 74 ctx = composite_create(mem_ctx, wbc_ctx->event_ctx); 75 if (ctx == NULL) return NULL; 76 77 state = talloc(ctx, struct wbc_idmap_state); 78 if (composite_nomem(state, ctx)) return ctx; 79 ctx->private_data = state; 80 81 state->req = talloc(state, struct winbind_get_idmap); 82 if (composite_nomem(state->req, ctx)) return ctx; 83 84 state->req->in.count = count; 85 state->req->in.level = WINBIND_IDMAP_LEVEL_SIDS_TO_XIDS; 86 state->req->in.ids = ids; 87 state->ctx = ctx; 88 89 subreq = dcerpc_winbind_get_idmap_r_send(state, 90 wbc_ctx->event_ctx, 91 wbc_ctx->irpc_handle, 92 state->req); 93 if (composite_nomem(subreq, ctx)) return ctx; 94 95 tevent_req_set_callback(subreq, sids_to_xids_recv_ids, state); 96 97 return ctx; 98 } 99 100 static void sids_to_xids_recv_ids(struct tevent_req *subreq) 101 { 102 struct wbc_idmap_state *state = 103 tevent_req_callback_data(subreq, 104 struct wbc_idmap_state); 105 106 state->ctx->status = dcerpc_winbind_get_idmap_r_recv(subreq, state); 284 static void wbc_ids_to_sids_done(struct tevent_req *subreq); 285 286 static struct tevent_req *wbc_ids_to_sids_send( 287 TALLOC_CTX *mem_ctx, struct tevent_context *ev, 288 int fd, struct id_map *ids, uint32_t count) 289 { 290 struct tevent_req *req, *subreq; 291 struct wbc_ids_to_sids_state *state; 292 293 req = tevent_req_create(mem_ctx, &state, 294 struct wbc_ids_to_sids_state); 295 if (req == NULL) { 296 return NULL; 297 } 298 state->ev = ev; 299 state->fd = fd; 300 state->ids = ids; 301 state->count = count; 302 303 if (count == 0) { 304 tevent_req_done(req); 305 return tevent_req_post(req, ev); 306 } 307 308 subreq = wbc_id_to_sid_send(state, state->ev, state->fd, 309 &state->ids[state->idx].xid); 310 if (tevent_req_nomem(subreq, req)) { 311 return tevent_req_post(req, ev); 312 } 313 tevent_req_set_callback(subreq, wbc_ids_to_sids_done, req); 314 return req; 315 } 316 317 static void wbc_ids_to_sids_done(struct tevent_req *subreq) 318 { 319 struct tevent_req *req = tevent_req_callback_data( 320 subreq, struct tevent_req); 321 struct wbc_ids_to_sids_state *state = tevent_req_data( 322 req, struct wbc_ids_to_sids_state); 323 struct id_map *id; 324 struct dom_sid sid; 325 int ret; 326 327 ret = wbc_id_to_sid_recv(subreq, &sid); 107 328 TALLOC_FREE(subreq); 108 if (!composite_is_ok(state->ctx)) return; 109 110 state->ids = state->req->out.ids; 111 composite_done(state->ctx); 112 } 113 114 NTSTATUS wbc_sids_to_xids_recv(struct composite_context *ctx, 115 struct id_map **ids) 116 { 117 NTSTATUS status = composite_wait(ctx); 118 DEBUG(5, ("wbc_sids_to_xids_recv called\n")); 119 if (NT_STATUS_IS_OK(status)) { 120 struct wbc_idmap_state *state = talloc_get_type_abort( 121 ctx->private_data, 122 struct wbc_idmap_state); 123 *ids = state->ids; 124 } 125 329 330 id = &state->ids[state->idx]; 331 if (ret == 0) { 332 id->status = ID_MAPPED; 333 id->sid = dom_sid_dup(state->ids, &sid); 334 if (id->sid == NULL) { 335 tevent_req_error(req, ENOMEM); 336 return; 337 } 338 } else { 339 id->status = ID_UNMAPPED; 340 id->sid = NULL; 341 } 342 343 state->idx += 1; 344 if (state->idx == state->count) { 345 tevent_req_done(req); 346 return; 347 } 348 349 subreq = wbc_id_to_sid_send(state, state->ev, state->fd, 350 &state->ids[state->idx].xid); 351 if (tevent_req_nomem(subreq, req)) { 352 return; 353 } 354 tevent_req_set_callback(subreq, wbc_ids_to_sids_done, req); 355 } 356 357 static int wbc_ids_to_sids_recv(struct tevent_req *req) 358 { 359 int err; 360 if (tevent_req_is_unix_error(req, &err)) { 361 return err; 362 } 363 return 0; 364 } 365 366 NTSTATUS wbc_xids_to_sids(struct tevent_context *ev, struct id_map *ids, 367 uint32_t count) 368 { 369 struct tevent_req *req; 370 NTSTATUS status; 371 bool polled; 372 int ret, fd; 373 374 DEBUG(5, ("wbc_xids_to_sids called: %u ids\n", (unsigned)count)); 375 376 fd = winbindd_pipe_sock(); 377 if (fd == -1) { 378 status = map_nt_error_from_unix_common(errno); 379 DEBUG(10, ("winbindd_pipe_sock returned %s\n", 380 strerror(errno))); 381 return status; 382 } 383 384 req = wbc_ids_to_sids_send(ev, ev, fd, ids, count); 385 if (req == NULL) { 386 status = NT_STATUS_NO_MEMORY; 387 goto done; 388 } 389 390 polled = tevent_req_poll(req, ev); 391 if (!polled) { 392 status = map_nt_error_from_unix_common(errno); 393 DEBUG(10, ("tevent_req_poll returned %s\n", 394 strerror(errno))); 395 goto done; 396 } 397 398 ret = wbc_ids_to_sids_recv(req); 399 TALLOC_FREE(req); 400 if (ret != 0) { 401 status = map_nt_error_from_unix_common(ret); 402 DEBUG(10, ("tevent_req_poll returned %s\n", 403 strerror(ret))); 404 } else { 405 status = NT_STATUS_OK; 406 } 407 408 done: 409 close(fd); 126 410 return status; 127 411 } 128 129 static void xids_to_sids_recv_ids(struct tevent_req *subreq);130 131 struct composite_context *wbc_xids_to_sids_send(struct wbc_context *wbc_ctx,132 TALLOC_CTX *mem_ctx,133 uint32_t count,134 struct id_map *ids)135 {136 struct composite_context *ctx;137 struct wbc_idmap_state *state;138 struct tevent_req *subreq;139 140 DEBUG(5, ("wbc_xids_to_sids called\n"));141 142 ctx = composite_create(mem_ctx, wbc_ctx->event_ctx);143 if (ctx == NULL) return NULL;144 145 state = talloc(ctx, struct wbc_idmap_state);146 if (composite_nomem(state, ctx)) return ctx;147 ctx->private_data = state;148 149 state->req = talloc(state, struct winbind_get_idmap);150 if (composite_nomem(state->req, ctx)) return ctx;151 152 state->req->in.count = count;153 state->req->in.level = WINBIND_IDMAP_LEVEL_XIDS_TO_SIDS;154 state->req->in.ids = ids;155 state->ctx = ctx;156 157 subreq = dcerpc_winbind_get_idmap_r_send(state,158 wbc_ctx->event_ctx,159 wbc_ctx->irpc_handle,160 state->req);161 if (composite_nomem(subreq, ctx)) return ctx;162 163 tevent_req_set_callback(subreq, xids_to_sids_recv_ids, state);164 165 return ctx;166 }167 168 static void xids_to_sids_recv_ids(struct tevent_req *subreq)169 {170 struct wbc_idmap_state *state =171 tevent_req_callback_data(subreq,172 struct wbc_idmap_state);173 174 state->ctx->status = dcerpc_winbind_get_idmap_r_recv(subreq, state);175 TALLOC_FREE(subreq);176 if (!composite_is_ok(state->ctx)) return;177 178 state->ids = state->req->out.ids;179 composite_done(state->ctx);180 }181 182 NTSTATUS wbc_xids_to_sids_recv(struct composite_context *ctx,183 struct id_map **ids)184 {185 NTSTATUS status = composite_wait(ctx);186 DEBUG(5, ("wbc_xids_to_sids_recv called\n"));187 if (NT_STATUS_IS_OK(status)) {188 struct wbc_idmap_state *state = talloc_get_type_abort(189 ctx->private_data,190 struct wbc_idmap_state);191 *ids = state->ids;192 }193 194 return status;195 }196 -
vendor/current/source4/libcli/wbclient/wbclient.h
r740 r988 19 19 along with this program. If not, see <http://www.gnu.org/licenses/>. 20 20 */ 21 #include "lib/messaging/irpc.h" 22 #include "libcli/composite/composite.h" 23 #include "librpc/gen_ndr/ndr_winbind_c.h" 21 #include "librpc/gen_ndr/idmap.h" 24 22 25 struct wbc_context { 26 struct tevent_context *event_ctx; 27 struct dcerpc_binding_handle *irpc_handle; 28 }; 23 NTSTATUS wbc_sids_to_xids(struct tevent_context *ev, struct id_map *ids, 24 uint32_t count); 29 25 30 struct wbc_context *wbc_init(TALLOC_CTX *mem_ctx, 31 struct messaging_context *msg_ctx, 32 struct tevent_context *event_ctx); 33 34 struct composite_context *wbc_sids_to_xids_send(struct wbc_context *wbc_ctx, 35 TALLOC_CTX *mem_ctx, 36 uint32_t count, 37 struct id_map *ids); 38 39 NTSTATUS wbc_sids_to_xids_recv(struct composite_context *ctx, 40 struct id_map **ids); 41 42 struct composite_context *wbc_xids_to_sids_send(struct wbc_context *wbc_ctx, 43 TALLOC_CTX *mem_ctx, 44 uint32_t count, 45 struct id_map *ids); 46 47 NTSTATUS wbc_xids_to_sids_recv(struct composite_context *ctx, 48 struct id_map **ids); 49 26 NTSTATUS wbc_xids_to_sids(struct tevent_context *ev, struct id_map *ids, 27 uint32_t count); -
vendor/current/source4/libcli/wbclient/wscript_build
r740 r988 1 1 #!/usr/bin/env python 2 2 3 bld.SAMBA_SUBSYSTEM('LIBWBCLIENT_OLD', 4 source='wbclient.c', 5 public_deps='errors events', 6 deps='NDR_WINBIND MESSAGING RPC_NDR_WINBIND' 3 bld.SAMBA_LIBRARY('LIBWBCLIENT_OLD', 4 source='wbclient.c', 5 public_deps='samba-errors events', 6 cflags='-DWINBINDD_SOCKET_DIR=\"%s\"' % bld.env.WINBINDD_SOCKET_DIR, 7 deps='WB_REQTRANS NDR_WINBIND MESSAGING RPC_NDR_WINBIND', 8 private_library=True 7 9 ) 8 10
Note:
See TracChangeset
for help on using the changeset viewer.