Changeset 740 for vendor/current/libcli/nbt/nameregister.c
- Timestamp:
- Nov 14, 2012, 12:59:34 PM (13 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
vendor/current/libcli/nbt/nameregister.c
r414 r740 21 21 22 22 #include "includes.h" 23 #include <tevent.h> 23 24 #include "../libcli/nbt/libnbt.h" 24 25 #include "../libcli/nbt/nbt_proto.h" 25 #include "libcli/composite/composite.h"26 26 #include "lib/socket/socket.h" 27 27 #include "librpc/gen_ndr/ndr_nbt.h" 28 #include "../lib/util/tevent_ntstatus.h" 28 29 29 30 /* … … 149 150 a name registration demand 150 151 */ 151 struct register_bcast_state {152 struct nbt_name_register_bcast_state { 152 153 struct nbt_name_socket *nbtsock; 153 struct nbt_name_register *io; 154 struct nbt_name_request *req; 154 struct nbt_name_register io; 155 155 }; 156 156 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); 157 static 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 202 static 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); 168 213 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; 174 217 } 175 218 176 219 /* 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; 186 226 } 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); 254 245 } 255 246 … … 257 248 broadcast 4 part name register - recv 258 249 */ 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; 265 261 } 266 262 … … 271 267 struct nbt_name_register_bcast *io) 272 268 { 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; 275 299 } 276 300 … … 281 305 reply for each address 282 306 */ 283 struct register_wins_state {307 struct nbt_name_register_wins_state { 284 308 struct nbt_name_socket *nbtsock; 285 struct nbt_name_register *io;286 c onst char **wins_servers;309 struct nbt_name_register io; 310 char **wins_servers; 287 311 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; 291 314 }; 292 315 316 static 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 } 293 392 294 393 /* 295 394 state handler for WINS multi-homed multi-server name register 296 395 */ 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); 396 static 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); 306 407 if (NT_STATUS_EQUAL(status, NT_STATUS_IO_TIMEOUT)) { 307 408 /* the register timed out - try the next WINS server */ 308 409 state->wins_servers++; 410 if (state->wins_servers[0] == NULL) { 411 tevent_req_nterror(req, status); 412 return; 413 } 414 309 415 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; 314 423 } 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; 325 443 } 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); 412 451 } 413 452 … … 415 454 multi-homed WINS name register - recv side 416 455 */ 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; 430 475 } 431 476 … … 437 482 struct nbt_name_register_wins *io) 438 483 { 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.