Ignore:
Timestamp:
Nov 14, 2012, 12:59:34 PM (13 years ago)
Author:
Silvan Scherrer
Message:

Samba Server: update vendor to 3.6.0

File:
1 edited

Legend:

Unmodified
Added
Removed
  • vendor/current/libcli/nbt/nameregister.c

    r414 r740  
    2121
    2222#include "includes.h"
     23#include <tevent.h>
    2324#include "../libcli/nbt/libnbt.h"
    2425#include "../libcli/nbt/nbt_proto.h"
    25 #include "libcli/composite/composite.h"
    2626#include "lib/socket/socket.h"
    2727#include "librpc/gen_ndr/ndr_nbt.h"
     28#include "../lib/util/tevent_ntstatus.h"
    2829
    2930/*
     
    149150  a name registration demand
    150151*/
    151 struct register_bcast_state {
     152struct nbt_name_register_bcast_state {
    152153        struct nbt_name_socket *nbtsock;
    153         struct nbt_name_register *io;
    154         struct nbt_name_request *req;
     154        struct nbt_name_register io;
    155155};
    156156
    157 
    158 /*
    159   state handler for 4 stage name registration
    160 */
    161 static void name_register_bcast_handler(struct nbt_name_request *req)
    162 {
    163         struct composite_context *c = talloc_get_type(req->async.private_data, struct composite_context);
    164         struct register_bcast_state *state = talloc_get_type(c->private_data, struct register_bcast_state);
    165         NTSTATUS status;
    166 
    167         status = nbt_name_register_recv(state->req, state, state->io);
     157static void nbt_name_register_bcast_handler(struct nbt_name_request *subreq);
     158
     159/*
     160  the async send call for a 4 stage name registration
     161*/
     162_PUBLIC_ struct tevent_req *nbt_name_register_bcast_send(TALLOC_CTX *mem_ctx,
     163                                        struct tevent_context *ev,
     164                                        struct nbt_name_socket *nbtsock,
     165                                        struct nbt_name_register_bcast *io)
     166{
     167        struct tevent_req *req;
     168        struct nbt_name_register_bcast_state *state;
     169        struct nbt_name_request *subreq;
     170
     171        req = tevent_req_create(mem_ctx, &state,
     172                                struct nbt_name_register_bcast_state);
     173        if (req == NULL) {
     174                return NULL;
     175        }
     176
     177        state->io.in.name            = io->in.name;
     178        state->io.in.dest_addr       = io->in.dest_addr;
     179        state->io.in.dest_port       = io->in.dest_port;
     180        state->io.in.address         = io->in.address;
     181        state->io.in.nb_flags        = io->in.nb_flags;
     182        state->io.in.register_demand = false;
     183        state->io.in.broadcast       = true;
     184        state->io.in.multi_homed     = false;
     185        state->io.in.ttl             = io->in.ttl;
     186        state->io.in.timeout         = 1;
     187        state->io.in.retries         = 2;
     188
     189        state->nbtsock = nbtsock;
     190
     191        subreq = nbt_name_register_send(nbtsock, &state->io);
     192        if (tevent_req_nomem(subreq, req)) {
     193                return tevent_req_post(req, ev);
     194        }
     195
     196        subreq->async.fn = nbt_name_register_bcast_handler;
     197        subreq->async.private_data = req;
     198
     199        return req;
     200}
     201
     202static void nbt_name_register_bcast_handler(struct nbt_name_request *subreq)
     203{
     204        struct tevent_req *req =
     205                talloc_get_type_abort(subreq->async.private_data,
     206                struct tevent_req);
     207        struct nbt_name_register_bcast_state *state =
     208                tevent_req_data(req,
     209                struct nbt_name_register_bcast_state);
     210        NTSTATUS status;
     211
     212        status = nbt_name_register_recv(subreq, state, &state->io);
    168213        if (NT_STATUS_EQUAL(status, NT_STATUS_IO_TIMEOUT)) {
    169                 if (state->io->in.register_demand == true) {
    170                         /* all done */
    171                         c->state = COMPOSITE_STATE_DONE;
    172                         c->status = NT_STATUS_OK;
    173                         goto done;
     214                if (state->io.in.register_demand == true) {
     215                        tevent_req_done(req);
     216                        return;
    174217                }
    175218
    176219                /* the registration timed out - good, send the demand */
    177                 state->io->in.register_demand = true;
    178                 state->io->in.retries         = 0;
    179                 state->req = nbt_name_register_send(state->nbtsock, state->io);
    180                 if (state->req == NULL) {
    181                         c->state = COMPOSITE_STATE_ERROR;
    182                         c->status = NT_STATUS_NO_MEMORY;
    183                 } else {
    184                         state->req->async.fn      = name_register_bcast_handler;
    185                         state->req->async.private_data = c;
     220                state->io.in.register_demand = true;
     221                state->io.in.retries         = 0;
     222
     223                subreq = nbt_name_register_send(state->nbtsock, &state->io);
     224                if (tevent_req_nomem(subreq, req)) {
     225                        return;
    186226                }
    187         } else if (!NT_STATUS_IS_OK(status)) {
    188                 c->state = COMPOSITE_STATE_ERROR;
    189                 c->status = status;
    190         } else {
    191                 c->state = COMPOSITE_STATE_ERROR;
    192                 c->status = NT_STATUS_CONFLICTING_ADDRESSES;
    193                 DEBUG(3,("Name registration conflict from %s for %s with ip %s - rcode %d\n",
    194                          state->io->out.reply_from,
    195                          nbt_name_string(state, &state->io->out.name),
    196                          state->io->out.reply_addr,
    197                          state->io->out.rcode));
    198         }
    199 
    200 done:
    201         if (c->state >= COMPOSITE_STATE_DONE &&
    202             c->async.fn) {
    203                 c->async.fn(c);
    204         }
    205 }
    206 
    207 /*
    208   the async send call for a 4 stage name registration
    209 */
    210 _PUBLIC_ struct composite_context *nbt_name_register_bcast_send(struct nbt_name_socket *nbtsock,
    211                                                        struct nbt_name_register_bcast *io)
    212 {
    213         struct composite_context *c;
    214         struct register_bcast_state *state;
    215 
    216         c = talloc_zero(nbtsock, struct composite_context);
    217         if (c == NULL) goto failed;
    218 
    219         state = talloc(c, struct register_bcast_state);
    220         if (state == NULL) goto failed;
    221 
    222         state->io = talloc(state, struct nbt_name_register);
    223         if (state->io == NULL) goto failed;
    224 
    225         state->io->in.name            = io->in.name;
    226         state->io->in.dest_addr       = io->in.dest_addr;
    227         state->io->in.dest_port       = io->in.dest_port;
    228         state->io->in.address         = io->in.address;
    229         state->io->in.nb_flags        = io->in.nb_flags;
    230         state->io->in.register_demand = false;
    231         state->io->in.broadcast       = true;
    232         state->io->in.multi_homed     = false;
    233         state->io->in.ttl             = io->in.ttl;
    234         state->io->in.timeout         = 1;
    235         state->io->in.retries         = 2;
    236 
    237         state->nbtsock = nbtsock;
    238 
    239         state->req = nbt_name_register_send(nbtsock, state->io);
    240         if (state->req == NULL) goto failed;
    241 
    242         state->req->async.fn      = name_register_bcast_handler;
    243         state->req->async.private_data = c;
    244 
    245         c->private_data = state;
    246         c->state        = COMPOSITE_STATE_IN_PROGRESS;
    247         c->event_ctx    = nbtsock->event_ctx;
    248 
    249         return c;
    250 
    251 failed:
    252         talloc_free(c);
    253         return NULL;
     227
     228                subreq->async.fn = nbt_name_register_bcast_handler;
     229                subreq->async.private_data = req;
     230                return;
     231        }
     232
     233        if (!NT_STATUS_IS_OK(status)) {
     234                tevent_req_nterror(req, status);
     235                return;
     236        }
     237
     238        DEBUG(3,("Name registration conflict from %s for %s with ip %s - rcode %d\n",
     239                 state->io.out.reply_from,
     240                 nbt_name_string(state, &state->io.out.name),
     241                 state->io.out.reply_addr,
     242                 state->io.out.rcode));
     243
     244        tevent_req_nterror(req, NT_STATUS_CONFLICTING_ADDRESSES);
    254245}
    255246
     
    257248  broadcast 4 part name register - recv
    258249*/
    259 _PUBLIC_ NTSTATUS nbt_name_register_bcast_recv(struct composite_context *c)
    260 {
    261         NTSTATUS status;
    262         status = composite_wait(c);
    263         talloc_free(c);
    264         return status;
     250_PUBLIC_ NTSTATUS nbt_name_register_bcast_recv(struct tevent_req *req)
     251{
     252        NTSTATUS status;
     253
     254        if (tevent_req_is_nterror(req, &status)) {
     255                tevent_req_received(req);
     256                return status;
     257        }
     258
     259        tevent_req_received(req);
     260        return NT_STATUS_OK;
    265261}
    266262
     
    271267                                 struct nbt_name_register_bcast *io)
    272268{
    273         struct composite_context *c = nbt_name_register_bcast_send(nbtsock, io);
    274         return nbt_name_register_bcast_recv(c);
     269        TALLOC_CTX *frame = talloc_stackframe();
     270        struct tevent_context *ev;
     271        struct tevent_req *subreq;
     272        NTSTATUS status;
     273
     274        /*
     275         * TODO: create a temporary event context
     276         */
     277        ev = nbtsock->event_ctx;
     278
     279        subreq = nbt_name_register_bcast_send(frame, ev, nbtsock, io);
     280        if (subreq == NULL) {
     281                talloc_free(frame);
     282                return NT_STATUS_NO_MEMORY;
     283        }
     284
     285        if (!tevent_req_poll(subreq, ev)) {
     286                status = map_nt_error_from_unix(errno);
     287                talloc_free(frame);
     288                return status;
     289        }
     290
     291        status = nbt_name_register_bcast_recv(subreq);
     292        if (!NT_STATUS_IS_OK(status)) {
     293                talloc_free(frame);
     294                return status;
     295        }
     296
     297        TALLOC_FREE(frame);
     298        return NT_STATUS_OK;
    275299}
    276300
     
    281305  reply for each address
    282306*/
    283 struct register_wins_state {
     307struct nbt_name_register_wins_state {
    284308        struct nbt_name_socket *nbtsock;
    285         struct nbt_name_register *io;
    286         const char **wins_servers;
     309        struct nbt_name_register io;
     310        char **wins_servers;
    287311        uint16_t wins_port;
    288         const char **addresses;
    289         int address_idx;
    290         struct nbt_name_request *req;
     312        char **addresses;
     313        uint32_t address_idx;
    291314};
    292315
     316static void nbt_name_register_wins_handler(struct nbt_name_request *subreq);
     317
     318/*
     319  the async send call for a multi-server WINS register
     320*/
     321_PUBLIC_ struct tevent_req *nbt_name_register_wins_send(TALLOC_CTX *mem_ctx,
     322                                                struct tevent_context *ev,
     323                                                struct nbt_name_socket *nbtsock,
     324                                                struct nbt_name_register_wins *io)
     325{
     326        struct tevent_req *req;
     327        struct nbt_name_register_wins_state *state;
     328        struct nbt_name_request *subreq;
     329
     330        req = tevent_req_create(mem_ctx, &state,
     331                                struct nbt_name_register_wins_state);
     332        if (req == NULL) {
     333                return NULL;
     334        }
     335
     336        if (io->in.wins_servers == NULL) {
     337                tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER);
     338                return tevent_req_post(req, ev);
     339        }
     340
     341        if (io->in.wins_servers[0] == NULL) {
     342                tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER);
     343                return tevent_req_post(req, ev);
     344        }
     345
     346        if (io->in.addresses == NULL) {
     347                tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER);
     348                return tevent_req_post(req, ev);
     349        }
     350
     351        if (io->in.addresses[0] == NULL) {
     352                tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER);
     353                return tevent_req_post(req, ev);
     354        }
     355
     356        state->wins_port = io->in.wins_port;
     357        state->wins_servers = str_list_copy(state, io->in.wins_servers);
     358        if (tevent_req_nomem(state->wins_servers, req)) {
     359                return tevent_req_post(req, ev);
     360        }
     361
     362        state->addresses = str_list_copy(state, io->in.addresses);
     363        if (tevent_req_nomem(state->addresses, req)) {
     364                return tevent_req_post(req, ev);
     365        }
     366
     367        state->io.in.name            = io->in.name;
     368        state->io.in.dest_addr       = state->wins_servers[0];
     369        state->io.in.dest_port       = state->wins_port;
     370        state->io.in.address         = io->in.addresses[0];
     371        state->io.in.nb_flags        = io->in.nb_flags;
     372        state->io.in.broadcast       = false;
     373        state->io.in.register_demand = false;
     374        state->io.in.multi_homed     = (io->in.nb_flags & NBT_NM_GROUP)?false:true;
     375        state->io.in.ttl             = io->in.ttl;
     376        state->io.in.timeout         = 3;
     377        state->io.in.retries         = 2;
     378
     379        state->nbtsock     = nbtsock;
     380        state->address_idx = 0;
     381
     382        subreq = nbt_name_register_send(nbtsock, &state->io);
     383        if (tevent_req_nomem(subreq, req)) {
     384                return tevent_req_post(req, ev);
     385        }
     386
     387        subreq->async.fn = nbt_name_register_wins_handler;
     388        subreq->async.private_data = req;
     389
     390        return req;
     391}
    293392
    294393/*
    295394  state handler for WINS multi-homed multi-server name register
    296395*/
    297 static void name_register_wins_handler(struct nbt_name_request *req)
    298 {
    299         struct composite_context *c = talloc_get_type(req->async.private_data,
    300                                                       struct composite_context);
    301         struct register_wins_state *state = talloc_get_type(c->private_data,
    302                                                             struct register_wins_state);
    303         NTSTATUS status;
    304 
    305         status = nbt_name_register_recv(state->req, state, state->io);
     396static void nbt_name_register_wins_handler(struct nbt_name_request *subreq)
     397{
     398        struct tevent_req *req =
     399                talloc_get_type_abort(subreq->async.private_data,
     400                struct tevent_req);
     401        struct nbt_name_register_wins_state *state =
     402                tevent_req_data(req,
     403                struct nbt_name_register_wins_state);
     404        NTSTATUS status;
     405
     406        status = nbt_name_register_recv(subreq, state, &state->io);
    306407        if (NT_STATUS_EQUAL(status, NT_STATUS_IO_TIMEOUT)) {
    307408                /* the register timed out - try the next WINS server */
    308409                state->wins_servers++;
     410                if (state->wins_servers[0] == NULL) {
     411                        tevent_req_nterror(req, status);
     412                        return;
     413                }
     414
    309415                state->address_idx = 0;
    310                 if (state->wins_servers[0] == NULL) {
    311                         c->state = COMPOSITE_STATE_ERROR;
    312                         c->status = status;
    313                         goto done;
     416                state->io.in.dest_addr = state->wins_servers[0];
     417                state->io.in.dest_port = state->wins_port;
     418                state->io.in.address   = state->addresses[0];
     419
     420                subreq = nbt_name_register_send(state->nbtsock, &state->io);
     421                if (tevent_req_nomem(subreq, req)) {
     422                        return;
    314423                }
    315                 state->io->in.dest_addr = state->wins_servers[0];
    316                 state->io->in.dest_port = state->wins_port;
    317                 state->io->in.address   = state->addresses[0];
    318                 state->req = nbt_name_register_send(state->nbtsock, state->io);
    319                 if (state->req == NULL) {
    320                         c->state = COMPOSITE_STATE_ERROR;
    321                         c->status = NT_STATUS_NO_MEMORY;
    322                 } else {
    323                         state->req->async.fn      = name_register_wins_handler;
    324                         state->req->async.private_data = c;
     424
     425                subreq->async.fn = nbt_name_register_wins_handler;
     426                subreq->async.private_data = req;
     427                return;
     428        }
     429
     430        if (!NT_STATUS_IS_OK(status)) {
     431                tevent_req_nterror(req, status);
     432                return;
     433        }
     434
     435        if (state->io.out.rcode == 0 &&
     436            state->addresses[state->address_idx+1] != NULL) {
     437                /* register our next address */
     438                state->io.in.address = state->addresses[++(state->address_idx)];
     439
     440                subreq = nbt_name_register_send(state->nbtsock, &state->io);
     441                if (tevent_req_nomem(subreq, req)) {
     442                        return;
    325443                }
    326         } else if (!NT_STATUS_IS_OK(status)) {
    327                 c->state = COMPOSITE_STATE_ERROR;
    328                 c->status = status;
    329         } else {
    330                 if (state->io->out.rcode == 0 &&
    331                     state->addresses[state->address_idx+1] != NULL) {
    332                         /* register our next address */
    333                         state->io->in.address = state->addresses[++(state->address_idx)];
    334                         state->req = nbt_name_register_send(state->nbtsock, state->io);
    335                         if (state->req == NULL) {
    336                                 c->state = COMPOSITE_STATE_ERROR;
    337                                 c->status = NT_STATUS_NO_MEMORY;
    338                         } else {
    339                                 state->req->async.fn      = name_register_wins_handler;
    340                                 state->req->async.private_data = c;
    341                         }
    342                 } else {
    343                         c->state = COMPOSITE_STATE_DONE;
    344                         c->status = NT_STATUS_OK;
    345                 }
    346         }
    347 
    348 done:
    349         if (c->state >= COMPOSITE_STATE_DONE &&
    350             c->async.fn) {
    351                 c->async.fn(c);
    352         }
    353 }
    354 
    355 /*
    356   the async send call for a multi-server WINS register
    357 */
    358 _PUBLIC_ struct composite_context *nbt_name_register_wins_send(struct nbt_name_socket *nbtsock,
    359                                                       struct nbt_name_register_wins *io)
    360 {
    361         struct composite_context *c;
    362         struct register_wins_state *state;
    363 
    364         c = talloc_zero(nbtsock, struct composite_context);
    365         if (c == NULL) goto failed;
    366 
    367         state = talloc(c, struct register_wins_state);
    368         if (state == NULL) goto failed;
    369 
    370         state->io = talloc(state, struct nbt_name_register);
    371         if (state->io == NULL) goto failed;
    372 
    373         state->wins_port = io->in.wins_port;
    374         state->wins_servers = (const char **)str_list_copy(state, io->in.wins_servers);
    375         if (state->wins_servers == NULL ||
    376             state->wins_servers[0] == NULL) goto failed;
    377 
    378         state->addresses = (const char **)str_list_copy(state, io->in.addresses);
    379         if (state->addresses == NULL ||
    380             state->addresses[0] == NULL) goto failed;
    381 
    382         state->io->in.name            = io->in.name;
    383         state->io->in.dest_addr       = state->wins_servers[0];
    384         state->io->in.dest_port       = state->wins_port;
    385         state->io->in.address         = io->in.addresses[0];
    386         state->io->in.nb_flags        = io->in.nb_flags;
    387         state->io->in.broadcast       = false;
    388         state->io->in.register_demand = false;
    389         state->io->in.multi_homed     = (io->in.nb_flags & NBT_NM_GROUP)?false:true;
    390         state->io->in.ttl             = io->in.ttl;
    391         state->io->in.timeout         = 3;
    392         state->io->in.retries         = 2;
    393 
    394         state->nbtsock     = nbtsock;
    395         state->address_idx = 0;
    396 
    397         state->req = nbt_name_register_send(nbtsock, state->io);
    398         if (state->req == NULL) goto failed;
    399 
    400         state->req->async.fn      = name_register_wins_handler;
    401         state->req->async.private_data = c;
    402 
    403         c->private_data = state;
    404         c->state        = COMPOSITE_STATE_IN_PROGRESS;
    405         c->event_ctx    = nbtsock->event_ctx;
    406 
    407         return c;
    408 
    409 failed:
    410         talloc_free(c);
    411         return NULL;
     444
     445                subreq->async.fn = nbt_name_register_wins_handler;
     446                subreq->async.private_data = req;
     447                return;
     448        }
     449
     450        tevent_req_done(req);
    412451}
    413452
     
    415454  multi-homed WINS name register - recv side
    416455*/
    417 _PUBLIC_ NTSTATUS nbt_name_register_wins_recv(struct composite_context *c, TALLOC_CTX *mem_ctx,
    418                                      struct nbt_name_register_wins *io)
    419 {
    420         NTSTATUS status;
    421         status = composite_wait(c);
    422         if (NT_STATUS_IS_OK(status)) {
    423                 struct register_wins_state *state =
    424                         talloc_get_type(c->private_data, struct register_wins_state);
    425                 io->out.wins_server = talloc_steal(mem_ctx, state->wins_servers[0]);
    426                 io->out.rcode = state->io->out.rcode;
    427         }
    428         talloc_free(c);
    429         return status;
     456_PUBLIC_ NTSTATUS nbt_name_register_wins_recv(struct tevent_req *req,
     457                                              TALLOC_CTX *mem_ctx,
     458                                              struct nbt_name_register_wins *io)
     459{
     460        struct nbt_name_register_wins_state *state =
     461                tevent_req_data(req,
     462                struct nbt_name_register_wins_state);
     463        NTSTATUS status;
     464
     465        if (tevent_req_is_nterror(req, &status)) {
     466                tevent_req_received(req);
     467                return status;
     468        }
     469
     470        io->out.wins_server = talloc_move(mem_ctx, &state->wins_servers[0]);
     471        io->out.rcode = state->io.out.rcode;
     472
     473        tevent_req_received(req);
     474        return NT_STATUS_OK;
    430475}
    431476
     
    437482                                struct nbt_name_register_wins *io)
    438483{
    439         struct composite_context *c = nbt_name_register_wins_send(nbtsock, io);
    440         return nbt_name_register_wins_recv(c, mem_ctx, io);
    441 }
     484        TALLOC_CTX *frame = talloc_stackframe();
     485        struct tevent_context *ev;
     486        struct tevent_req *subreq;
     487        NTSTATUS status;
     488
     489        /*
     490         * TODO: create a temporary event context
     491         */
     492        ev = nbtsock->event_ctx;
     493
     494        subreq = nbt_name_register_wins_send(frame, ev, nbtsock, io);
     495        if (subreq == NULL) {
     496                talloc_free(frame);
     497                return NT_STATUS_NO_MEMORY;
     498        }
     499
     500        if (!tevent_req_poll(subreq, ev)) {
     501                status = map_nt_error_from_unix(errno);
     502                talloc_free(frame);
     503                return status;
     504        }
     505
     506        status = nbt_name_register_wins_recv(subreq, mem_ctx, io);
     507        if (!NT_STATUS_IS_OK(status)) {
     508                talloc_free(frame);
     509                return status;
     510        }
     511
     512        TALLOC_FREE(frame);
     513        return NT_STATUS_OK;
     514}
Note: See TracChangeset for help on using the changeset viewer.