root/source4/libnet/libnet_lookup.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. libnet_Lookup_send
  2. continue_name_resolved
  3. libnet_Lookup_recv
  4. libnet_Lookup
  5. libnet_LookupHost_send
  6. libnet_LookupHost
  7. libnet_LookupDCs_send
  8. libnet_LookupDCs_recv
  9. libnet_LookupDCs
  10. libnet_LookupName_send
  11. prepare_lookup_params
  12. continue_lookup_name
  13. continue_name_found
  14. libnet_LookupName_recv
  15. libnet_LookupName

   1 /* 
   2    Unix SMB/CIFS implementation.
   3 
   4    Copyright (C) Rafal Szczesniak 2005
   5    
   6    This program is free software; you can redistribute it and/or modify
   7    it under the terms of the GNU General Public License as published by
   8    the Free Software Foundation; either version 3 of the License, or
   9    (at your option) any later version.
  10    
  11    This program is distributed in the hope that it will be useful,
  12    but WITHOUT ANY WARRANTY; without even the implied warranty of
  13    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  14    GNU General Public License for more details.
  15    
  16    You should have received a copy of the GNU General Public License
  17    along with this program.  If not, see <http://www.gnu.org/licenses/>.
  18 */
  19 
  20 /*
  21   a composite function for name resolving
  22 */
  23 
  24 #include "includes.h"
  25 #include "lib/events/events.h"
  26 #include "libnet/libnet.h"
  27 #include "libcli/composite/composite.h"
  28 #include "auth/credentials/credentials.h"
  29 #include "lib/messaging/messaging.h"
  30 #include "lib/messaging/irpc.h"
  31 #include "libcli/resolve/resolve.h"
  32 #include "libcli/finddcs.h"
  33 #include "libcli/security/security.h"
  34 #include "librpc/gen_ndr/lsa.h"
  35 #include "librpc/gen_ndr/ndr_lsa_c.h"
  36 
  37 #include "param/param.h"
  38 
  39 struct lookup_state {
  40         struct nbt_name hostname;
  41         const char *address;
  42 };
  43 
  44 
  45 static void continue_name_resolved(struct composite_context *ctx);
  46 
  47 
  48 /**
  49  * Sends asynchronous Lookup request
  50  *
  51  * @param io arguments and result of the call
  52  */
  53 
  54 struct composite_context *libnet_Lookup_send(struct libnet_context *ctx,
     /* [<][>][^][v][top][bottom][index][help] */
  55                                              struct libnet_Lookup *io)
  56 {
  57         struct composite_context *c;
  58         struct lookup_state *s;
  59         struct composite_context *cresolve_req;
  60         struct resolve_context *resolve_ctx;
  61 
  62         /* allocate context and state structures */
  63         c = composite_create(ctx, ctx->event_ctx);
  64         if (c == NULL) return NULL;
  65 
  66         s = talloc_zero(c, struct lookup_state);
  67         if (composite_nomem(s, c)) return c;
  68 
  69         c->private_data = s;
  70 
  71         if (io == NULL || io->in.hostname == NULL) {
  72                 composite_error(c, NT_STATUS_INVALID_PARAMETER);
  73                 return c;
  74         }
  75 
  76         /* parameters */
  77         s->hostname.name   = talloc_strdup(s, io->in.hostname);
  78         if (composite_nomem(s->hostname.name, c)) return c;
  79 
  80         s->hostname.type   = io->in.type;
  81         s->hostname.scope  = NULL;
  82 
  83         /* name resolution methods */
  84         if (io->in.resolve_ctx) {
  85                 resolve_ctx = io->in.resolve_ctx;
  86         } else {
  87                 resolve_ctx = ctx->resolve_ctx;
  88         }
  89 
  90         /* send resolve request */
  91         cresolve_req = resolve_name_send(resolve_ctx, &s->hostname, c->event_ctx);
  92         if (composite_nomem(cresolve_req, c)) return c;
  93 
  94         composite_continue(c, cresolve_req, continue_name_resolved, c);
  95         return c;
  96 }
  97 
  98 
  99 static void continue_name_resolved(struct composite_context *ctx)
     /* [<][>][^][v][top][bottom][index][help] */
 100 {
 101         struct composite_context *c;
 102         struct lookup_state *s;
 103 
 104         c = talloc_get_type(ctx->async.private_data, struct composite_context);
 105         s = talloc_get_type(c->private_data, struct lookup_state);
 106 
 107         c->status = resolve_name_recv(ctx, s, &s->address);
 108         
 109         composite_done(c);
 110 }
 111 
 112 
 113 /**
 114  * Waits for and receives results of asynchronous Lookup call
 115  *
 116  * @param c composite context returned by asynchronous Lookup call
 117  * @param mem_ctx memory context of the call
 118  * @param io pointer to results (and arguments) of the call
 119  * @return nt status code of execution
 120  */
 121 
 122 NTSTATUS libnet_Lookup_recv(struct composite_context *c, TALLOC_CTX *mem_ctx,
     /* [<][>][^][v][top][bottom][index][help] */
 123                             struct libnet_Lookup *io)
 124 {
 125         NTSTATUS status;
 126         struct lookup_state *s;
 127 
 128         status = composite_wait(c);
 129         if (NT_STATUS_IS_OK(status)) {
 130                 s = talloc_get_type(c->private_data, struct lookup_state);
 131 
 132                 io->out.address = (const char **)str_list_make(mem_ctx, s->address, NULL);
 133                 NT_STATUS_HAVE_NO_MEMORY(io->out.address);
 134         }
 135 
 136         talloc_free(c);
 137         return status;
 138 }
 139 
 140 
 141 /**
 142  * Synchronous version of Lookup call
 143  *
 144  * @param mem_ctx memory context for the call
 145  * @param io arguments and results of the call
 146  * @return nt status code of execution
 147  */
 148 
 149 NTSTATUS libnet_Lookup(struct libnet_context *ctx, TALLOC_CTX *mem_ctx,
     /* [<][>][^][v][top][bottom][index][help] */
 150                        struct libnet_Lookup *io)
 151 {
 152         struct composite_context *c = libnet_Lookup_send(ctx, io);
 153         return libnet_Lookup_recv(c, mem_ctx, io);
 154 }
 155 
 156 
 157 /*
 158  * Shortcut functions to find common types of name
 159  * (and skip nbt name type argument)
 160  */
 161 
 162 
 163 /**
 164  * Sends asynchronous LookupHost request
 165  */
 166 struct composite_context* libnet_LookupHost_send(struct libnet_context *ctx,
     /* [<][>][^][v][top][bottom][index][help] */
 167                                                  struct libnet_Lookup *io)
 168 {
 169         io->in.type = NBT_NAME_SERVER;
 170         return libnet_Lookup_send(ctx, io);
 171 }
 172 
 173 
 174 
 175 /**
 176  * Synchronous version of LookupHost call
 177  */
 178 NTSTATUS libnet_LookupHost(struct libnet_context *ctx, TALLOC_CTX *mem_ctx,
     /* [<][>][^][v][top][bottom][index][help] */
 179                            struct libnet_Lookup *io)
 180 {
 181         struct composite_context *c = libnet_LookupHost_send(ctx, io);
 182         return libnet_Lookup_recv(c, mem_ctx, io);
 183 }
 184 
 185 
 186 /**
 187  * Sends asynchronous LookupDCs request
 188  */
 189 struct composite_context* libnet_LookupDCs_send(struct libnet_context *ctx,
     /* [<][>][^][v][top][bottom][index][help] */
 190                                                 TALLOC_CTX *mem_ctx,
 191                                                 struct libnet_LookupDCs *io)
 192 {
 193         struct composite_context *c;
 194         struct messaging_context *msg_ctx = 
 195                 messaging_client_init(mem_ctx, lp_messaging_path(mem_ctx, ctx->lp_ctx), 
 196                                       lp_iconv_convenience(ctx->lp_ctx), ctx->event_ctx);
 197 
 198         c = finddcs_send(mem_ctx, lp_netbios_name(ctx->lp_ctx), lp_nbt_port(ctx->lp_ctx),
 199                          io->in.domain_name, io->in.name_type,
 200                          NULL, lp_iconv_convenience(ctx->lp_ctx), 
 201                          ctx->resolve_ctx, ctx->event_ctx, msg_ctx);
 202         return c;
 203 }
 204 
 205 /**
 206  * Waits for and receives results of asynchronous Lookup call
 207  *
 208  * @param c composite context returned by asynchronous Lookup call
 209  * @param mem_ctx memory context of the call
 210  * @param io pointer to results (and arguments) of the call
 211  * @return nt status code of execution
 212  */
 213 
 214 NTSTATUS libnet_LookupDCs_recv(struct composite_context *c, TALLOC_CTX *mem_ctx,
     /* [<][>][^][v][top][bottom][index][help] */
 215                                struct libnet_LookupDCs *io)
 216 {
 217         NTSTATUS status;
 218         status = finddcs_recv(c, mem_ctx, &io->out.num_dcs, &io->out.dcs);
 219         if (!NT_STATUS_IS_OK(status)) {
 220                 return status;
 221         }
 222         return status;
 223 }
 224 
 225 
 226 /**
 227  * Synchronous version of LookupDCs
 228  */
 229 NTSTATUS libnet_LookupDCs(struct libnet_context *ctx, TALLOC_CTX *mem_ctx,
     /* [<][>][^][v][top][bottom][index][help] */
 230                           struct libnet_LookupDCs *io)
 231 {
 232         struct composite_context *c = libnet_LookupDCs_send(ctx, mem_ctx, io);
 233         return libnet_LookupDCs_recv(c, mem_ctx, io);
 234 }
 235 
 236 
 237 struct lookup_name_state {
 238         struct libnet_context *ctx;
 239         const char *name;
 240         uint32_t count;
 241         struct libnet_DomainOpen domopen;
 242         struct lsa_LookupNames lookup;
 243         struct lsa_TransSidArray sids;
 244         struct lsa_String *names;
 245 
 246         /* information about the progress */
 247         void (*monitor_fn)(struct monitor_msg *);
 248 };
 249 
 250 
 251 static bool prepare_lookup_params(struct libnet_context *ctx,
 252                                   struct composite_context *c,
 253                                   struct lookup_name_state *s);
 254 static void continue_lookup_name(struct composite_context *ctx);
 255 static void continue_name_found(struct rpc_request *req);
 256 
 257 
 258 struct composite_context* libnet_LookupName_send(struct libnet_context *ctx,
     /* [<][>][^][v][top][bottom][index][help] */
 259                                                  TALLOC_CTX *mem_ctx,
 260                                                  struct libnet_LookupName *io,
 261                                                  void (*monitor)(struct monitor_msg*))
 262 {
 263         struct composite_context *c;
 264         struct lookup_name_state *s;
 265         struct rpc_request *lookup_req;
 266         bool prereq_met = false;
 267 
 268         c = composite_create(mem_ctx, ctx->event_ctx);
 269         if (c == NULL) return NULL;
 270 
 271         s = talloc_zero(c, struct lookup_name_state);
 272         if (composite_nomem(s, c)) return c;
 273 
 274         c->private_data = s;
 275         
 276         s->name = talloc_strdup(c, io->in.name);
 277         s->monitor_fn = monitor;
 278         s->ctx = ctx;
 279 
 280         prereq_met = lsa_domain_opened(ctx, io->in.domain_name, &c, &s->domopen,
 281                                        continue_lookup_name, monitor);
 282         if (!prereq_met) return c;
 283 
 284         if (!prepare_lookup_params(ctx, c, s)) return c;
 285 
 286         lookup_req = dcerpc_lsa_LookupNames_send(ctx->lsa.pipe, c, &s->lookup);
 287         if (composite_nomem(lookup_req, c)) return c;
 288 
 289         composite_continue_rpc(c, lookup_req, continue_name_found, c);
 290         return c;
 291 }
 292 
 293 
 294 static bool prepare_lookup_params(struct libnet_context *ctx,
     /* [<][>][^][v][top][bottom][index][help] */
 295                                   struct composite_context *c,
 296                                   struct lookup_name_state *s)
 297 {
 298         const int single_name = 1;
 299 
 300         s->sids.count = 0;
 301         s->sids.sids  = NULL;
 302         
 303         s->names = talloc_array(ctx, struct lsa_String, single_name);
 304         if (composite_nomem(s->names, c)) return false;
 305         s->names[0].string = s->name;
 306         
 307         s->lookup.in.handle    = &ctx->lsa.handle;
 308         s->lookup.in.num_names = single_name;
 309         s->lookup.in.names     = s->names;
 310         s->lookup.in.sids      = &s->sids;
 311         s->lookup.in.level     = 1;
 312         s->lookup.in.count     = &s->count;
 313         s->lookup.out.count    = &s->count;
 314         s->lookup.out.sids     = &s->sids;
 315         s->lookup.out.domains  = talloc_zero(ctx, struct lsa_RefDomainList *);
 316         if (composite_nomem(s->lookup.out.domains, c)) return false;
 317         
 318         return true;
 319 }
 320 
 321 
 322 static void continue_lookup_name(struct composite_context *ctx)
     /* [<][>][^][v][top][bottom][index][help] */
 323 {
 324         struct composite_context *c;
 325         struct lookup_name_state *s;
 326         struct rpc_request *lookup_req;
 327 
 328         c = talloc_get_type(ctx->async.private_data, struct composite_context);
 329         s = talloc_get_type(c->private_data, struct lookup_name_state);
 330 
 331         c->status = libnet_DomainOpen_recv(ctx, s->ctx, c, &s->domopen);
 332         if (!composite_is_ok(c)) return;
 333         
 334         if (!prepare_lookup_params(s->ctx, c, s)) return;
 335 
 336         lookup_req = dcerpc_lsa_LookupNames_send(s->ctx->lsa.pipe, c, &s->lookup);
 337         if (composite_nomem(lookup_req, c)) return;
 338         
 339         composite_continue_rpc(c, lookup_req, continue_name_found, c);
 340 }
 341 
 342 
 343 static void continue_name_found(struct rpc_request *req)
     /* [<][>][^][v][top][bottom][index][help] */
 344 {
 345         struct composite_context *c;
 346         struct lookup_name_state *s;
 347 
 348         c = talloc_get_type(req->async.private_data, struct composite_context);
 349         s = talloc_get_type(c->private_data, struct lookup_name_state);
 350 
 351         c->status = dcerpc_ndr_request_recv(req);
 352         if (!composite_is_ok(c)) return;
 353 
 354         c->status = s->lookup.out.result;
 355         if (!composite_is_ok(c)) return;
 356 
 357         composite_done(c);
 358 }
 359 
 360 
 361 NTSTATUS libnet_LookupName_recv(struct composite_context *c, TALLOC_CTX *mem_ctx,
     /* [<][>][^][v][top][bottom][index][help] */
 362                                 struct libnet_LookupName *io)
 363 {
 364         NTSTATUS status;
 365         struct lookup_name_state *s;
 366 
 367         status = composite_wait(c);
 368 
 369         if (NT_STATUS_IS_OK(status)) {
 370                 s = talloc_get_type(c->private_data, struct lookup_name_state);
 371 
 372                 io->out.rid = 0;
 373                 io->out.sid = NULL;
 374                 io->out.sidstr = NULL;
 375 
 376                 if (*s->lookup.out.count > 0) {
 377                         struct lsa_RefDomainList *domains = *s->lookup.out.domains;
 378                         struct lsa_TransSidArray *sids = s->lookup.out.sids;
 379 
 380                         if (domains == NULL || sids == NULL) {
 381                                 status = NT_STATUS_UNSUCCESSFUL;
 382                                 io->out.error_string = talloc_asprintf(mem_ctx, "Error: %s", nt_errstr(status));
 383                                 goto done;
 384                         }
 385 
 386                         if (sids->count > 0) {
 387                                 io->out.rid        = sids->sids[0].rid;
 388                                 io->out.sid_type   = sids->sids[0].sid_type;
 389                                 if (domains->count > 0) {
 390                                         io->out.sid = dom_sid_add_rid(mem_ctx, domains->domains[0].sid, io->out.rid);
 391                                         NT_STATUS_HAVE_NO_MEMORY(io->out.sid);
 392                                         io->out.sidstr = dom_sid_string(mem_ctx, io->out.sid);
 393                                         NT_STATUS_HAVE_NO_MEMORY(io->out.sidstr);
 394                                 }
 395                         }
 396                 }
 397 
 398                 io->out.error_string = talloc_strdup(mem_ctx, "Success");
 399 
 400         } else if (!NT_STATUS_IS_OK(status)) {
 401                 io->out.error_string = talloc_asprintf(mem_ctx, "Error: %s", nt_errstr(status));
 402         }
 403 
 404 done:
 405         talloc_free(c);
 406         return status;
 407 }
 408 
 409 
 410 NTSTATUS libnet_LookupName(struct libnet_context *ctx, TALLOC_CTX *mem_ctx,
     /* [<][>][^][v][top][bottom][index][help] */
 411                            struct libnet_LookupName *io)
 412 {
 413         struct composite_context *c;
 414         
 415         c = libnet_LookupName_send(ctx, mem_ctx, io, NULL);
 416         return libnet_LookupName_recv(c, mem_ctx, io);
 417 }

/* [<][>][^][v][top][bottom][index][help] */