diff options
| author | David M. Syzdek <syzdek@bindlebinaries.com> | 2019-05-14 10:49:37 -0800 |
|---|---|---|
| committer | David M. Syzdek <syzdek@bindlebinaries.com> | 2019-05-14 10:49:37 -0800 |
| commit | 8c9a797d9b096047ee65cd816844f1bc4d7f57de (patch) | |
| tree | e7af45709a1e433413356961b977f598bcc3d7ad | |
| parent | 6095c1ebd48ea7559f64346eab606ad2835b94b0 (diff) | |
| download | scratchpad-8c9a797d9b096047ee65cd816844f1bc4d7f57de.tar.gz scratchpad-8c9a797d9b096047ee65cd816844f1bc4d7f57de.tar.bz2 scratchpad-8c9a797d9b096047ee65cd816844f1bc4d7f57de.tar.xz scratchpad-8c9a797d9b096047ee65cd816844f1bc4d7f57de.zip | |
starting on IP assignment functions
| -rw-r--r-- | notes/projects/radius/sql/ippool-schema.sql | 196 |
1 files changed, 181 insertions, 15 deletions
diff --git a/notes/projects/radius/sql/ippool-schema.sql b/notes/projects/radius/sql/ippool-schema.sql index 5372bc6..59914d3 100644 --- a/notes/projects/radius/sql/ippool-schema.sql +++ b/notes/projects/radius/sql/ippool-schema.sql | |||
| @@ -325,17 +325,19 @@ $$; | |||
| 325 | 325 | ||
| 326 | 326 | ||
| 327 | /* | 327 | /* |
| 328 | * Assigns IP address to specific user/session | 328 | * Assigns specific IP address to specified user/session |
| 329 | * | 329 | * |
| 330 | * % SELECT ip_add_network( | 330 | * % SELECT ip_assign( |
| 331 | * assignIp := '198.51.100.1/32', | 331 | * assignIp := '198.51.100.1/32', |
| 332 | * assignUser := 'jdoe@acsalaska.net' | 332 | * assignUser := 'jdoe@acsalaska.net' |
| 333 | * ); | 333 | * ); |
| 334 | * % SELECT ip_add_network( | 334 | * % SELECT ip_assign( |
| 335 | * assignIp := '198.51.100.1/32', | 335 | * assignIp := '198.51.100.1/32', |
| 336 | * assignUser := 'jdoe@acsalaska.net', | 336 | * assignUser := 'jdoe@acsalaska.net', |
| 337 | * assignNas := 'br1.cwc', | 337 | * assignPortLimit := 5, |
| 338 | * assignSess := '596c3b82-75df-11e9-bcbb-6003089b9f24' | 338 | * assignNas := 'br1.cwc', |
| 339 | * assignSess := '596c3b82-75df-11e9-bcbb-6003089b9f24', | ||
| 340 | * assignForce := FALSE | ||
| 339 | * ); | 341 | * ); |
| 340 | * | 342 | * |
| 341 | * assignIp | 343 | * assignIp |
| @@ -344,20 +346,28 @@ $$; | |||
| 344 | * assignUser | 346 | * assignUser |
| 345 | * : user to assign IP address | 347 | * : user to assign IP address |
| 346 | * | 348 | * |
| 349 | * assignPortLimit | ||
| 350 | * : specifies maximum IP assignments per user allowed | ||
| 351 | * | ||
| 347 | * assignNas | 352 | * assignNas |
| 348 | * : session NAS (attempt to guess if not specified) | 353 | * : session NAS (attempt to guess if not specified) |
| 349 | * | 354 | * |
| 350 | * assignSess | 355 | * assignSess |
| 351 | * : RADIUS session | 356 | * : RADIUS session |
| 352 | * | 357 | * |
| 358 | * assignForce | ||
| 359 | * : force IP assignment, even if netblock is inactive (i.e. static assignments) | ||
| 360 | * | ||
| 353 | * Returns TRUE if assigned and FALSE if not assigned | 361 | * Returns TRUE if assigned and FALSE if not assigned |
| 354 | */ | 362 | */ |
| 355 | CREATE OR REPLACE FUNCTION ip_assign | 363 | CREATE OR REPLACE FUNCTION ip_assign |
| 356 | ( | 364 | ( |
| 357 | assignIp INET, | 365 | assignIp INET, |
| 358 | assignUser TEXT, | 366 | assignUser TEXT, |
| 367 | assignPortLimit INTEGER DEFAULT 2, | ||
| 359 | assignNas TEXT DEFAULT NULL, | 368 | assignNas TEXT DEFAULT NULL, |
| 360 | assignSess TEXT DEFAULT NULL | 369 | assignSess TEXT DEFAULT NULL, |
| 370 | assignForce BOOLEAN DEFAULT FALSE | ||
| 361 | ) | 371 | ) |
| 362 | RETURNS BOOLEAN | 372 | RETURNS BOOLEAN |
| 363 | LANGUAGE plpgsql | 373 | LANGUAGE plpgsql |
| @@ -365,6 +375,7 @@ CREATE OR REPLACE FUNCTION ip_assign | |||
| 365 | AS $$ | 375 | AS $$ |
| 366 | DECLARE | 376 | DECLARE |
| 367 | assignNasId INTEGER; | 377 | assignNasId INTEGER; |
| 378 | assignPortCount INTEGER; | ||
| 368 | BEGIN | 379 | BEGIN |
| 369 | 380 | ||
| 370 | -- sets defaults | 381 | -- sets defaults |
| @@ -372,13 +383,37 @@ BEGIN | |||
| 372 | assignSess := 'user:' || assignUser; | 383 | assignSess := 'user:' || assignUser; |
| 373 | END IF; | 384 | END IF; |
| 374 | 385 | ||
| 386 | -- tallies existing sessions | ||
| 387 | SELECT count(id) | ||
| 388 | INTO assignPortCount | ||
| 389 | FROM ip | ||
| 390 | WHERE ip.username LIKE assignUser | ||
| 391 | AND ip.nasId IS NOT NULL | ||
| 392 | AND ip.address != assignIp; | ||
| 393 | IF ( assignPortCount >= assignPortLimit ) THEN | ||
| 394 | RETURN FALSE; | ||
| 395 | END IF; | ||
| 396 | |||
| 397 | -- verifies IP address is not inactive | ||
| 398 | IF ( assignForce = FALSE ) THEN | ||
| 399 | SELECT network | ||
| 400 | FROM netblock | ||
| 401 | WHERE netblock.network >>= assignIp | ||
| 402 | AND netblock.active IS FALSE; | ||
| 403 | IF FOUND THEN | ||
| 404 | RETURN FALSE; | ||
| 405 | END IF; | ||
| 406 | END IF; | ||
| 407 | |||
| 375 | -- attempts to determine NAS | 408 | -- attempts to determine NAS |
| 376 | IF ( assignNas IS NOT NULL ) THEN | 409 | IF ( assignNas IS NOT NULL ) THEN |
| 377 | SELECT id INTO assignNasId | 410 | SELECT id |
| 411 | INTO assignNasId | ||
| 378 | FROM nas | 412 | FROM nas |
| 379 | WHERE name LIKE assignNas; | 413 | WHERE name LIKE assignNas; |
| 380 | ELSE | 414 | ELSE |
| 381 | SELECT nas.id INTO assignNasId | 415 | SELECT nas.id |
| 416 | INTO assignNasId | ||
| 382 | FROM nas | 417 | FROM nas |
| 383 | INNER JOIN region | 418 | INNER JOIN region |
| 384 | ON region.id = nas.regionId | 419 | ON region.id = nas.regionId |
| @@ -387,7 +422,7 @@ BEGIN | |||
| 387 | WHERE netblock.network >>= assignIp; | 422 | WHERE netblock.network >>= assignIp; |
| 388 | END IF; | 423 | END IF; |
| 389 | IF ( assignNasId IS NULL ) THEN | 424 | IF ( assignNasId IS NULL ) THEN |
| 390 | RAISE EXCEPTION 'NAS not found'; | 425 | RETURN FALSE; |
| 391 | END IF; | 426 | END IF; |
| 392 | 427 | ||
| 393 | -- updates record | 428 | -- updates record |
| @@ -395,7 +430,8 @@ BEGIN | |||
| 395 | SET nasId = ( SELECT id FROM nas WHERE name LIKE assignNas ), | 430 | SET nasId = ( SELECT id FROM nas WHERE name LIKE assignNas ), |
| 396 | username = assignUser, | 431 | username = assignUser, |
| 397 | acctSession = assignSess | 432 | acctSession = assignSess |
| 398 | WHERE address = set_masklen( assignIp, 32 ); | 433 | WHERE address = set_masklen( assignIp, 32 ) |
| 434 | AND nasId IS NULL; | ||
| 399 | 435 | ||
| 400 | RETURN FOUND; | 436 | RETURN FOUND; |
| 401 | END; | 437 | END; |
| @@ -403,6 +439,135 @@ $$; | |||
| 403 | 439 | ||
| 404 | 440 | ||
| 405 | /* | 441 | /* |
| 442 | * Auto-assigns IP address to specified user/session | ||
| 443 | * | ||
| 444 | * % SELECT ip_autoassign( | ||
| 445 | * assignUser := 'jdoe@acsalaska.net', | ||
| 446 | * assignNas := 'br1.sol', | ||
| 447 | * assignPool := 'dhcp' | ||
| 448 | * ); | ||
| 449 | * % SELECT ip_autoassign( | ||
| 450 | * assignUser := 'jdoe@acsalaska.net', | ||
| 451 | * assignNas := 'br1.sol', | ||
| 452 | * assignPool := 'dhcp', | ||
| 453 | * assignPortLimit := 5, | ||
| 454 | * assignSess := 'b4356b24-7670-11e9-84a0-6003089b9f24', | ||
| 455 | * assignPrevIp := TRUE | ||
| 456 | * ); | ||
| 457 | * | ||
| 458 | * assignUser | ||
| 459 | * : user to assign IP address | ||
| 460 | * | ||
| 461 | * assignNas | ||
| 462 | * : NAS to assign to IP address and implies region from which to pull IP | ||
| 463 | * | ||
| 464 | * assignPool | ||
| 465 | * : IP pool to assign from which to assign IP address | ||
| 466 | * | ||
| 467 | * assignPortLimit | ||
| 468 | * : specifies maximum IP assignments per user allowed | ||
| 469 | * | ||
| 470 | * assignSess (default: auto-generated from username) | ||
| 471 | * : RADIUS session | ||
| 472 | * | ||
| 473 | * assignPrevIp (default: TRUE) | ||
| 474 | * : attempt to re-assign user's previous IP address | ||
| 475 | * | ||
| 476 | * Returns INET with value of assigned IP address | ||
| 477 | */ | ||
| 478 | CREATE OR REPLACE FUNCTION ip_autoassign | ||
| 479 | ( | ||
| 480 | assignUser TEXT, | ||
| 481 | assignNas TEXT, | ||
| 482 | assignPool TEXT, | ||
| 483 | assignPortLimit INTEGER, DEFAULT 2, | ||
| 484 | assignSess TEXT DEFAULT NULL, | ||
| 485 | assignPrevIp BOOLEAN DEFAULT TRUE | ||
| 486 | ) | ||
| 487 | RETURNS INET | ||
| 488 | LANGUAGE plpgsql | ||
| 489 | SECURITY DEFINER | ||
| 490 | AS $$ | ||
| 491 | DECLARE | ||
| 492 | assignedIp INET; | ||
| 493 | assignNasId INTEGER; | ||
| 494 | BEGIN | ||
| 495 | |||
| 496 | -- sets defaults | ||
| 497 | IF ( assignSess IS NULL ) THEN | ||
| 498 | assignSess := 'user:' || assignUser; | ||
| 499 | END IF; | ||
| 500 | |||
| 501 | -- search for user's previous address | ||
| 502 | IF ( assignPrevIp IS TRUE ) THEN | ||
| 503 | SELECT ip.address, | ||
| 504 | nas.id | ||
| 505 | INTO assignedIp, | ||
| 506 | assignNasId | ||
| 507 | FROM ip | ||
| 508 | INNER JOIN netblock | ||
| 509 | ON netblock.network >>= ip.address | ||
| 510 | INNER JOIN region | ||
| 511 | ON region.id = netblock.regionId | ||
| 512 | INNER JOIN pool | ||
| 513 | ON pool.id = netblock.poolId | ||
| 514 | INNER JOIN nas | ||
| 515 | ON nas.regionId = region.id | ||
| 516 | WHERE ip.nasId IS NULL | ||
| 517 | AND ip.username LIKE lower( assignUser ) | ||
| 518 | AND nas.name LIKE lower( assignNas ) | ||
| 519 | AND pool.name LIKE lower( assignPool ) | ||
| 520 | AND netblock.active = TRUE | ||
| 521 | ORDER BY ip.modified DESC, | ||
| 522 | ip.address ASC | ||
| 523 | LIMIT 1; | ||
| 524 | END IF; | ||
| 525 | |||
| 526 | -- if previous address is unavailable, find longest idle address | ||
| 527 | IF ( assignedIp IS NULL ) THEN | ||
| 528 | SELECT ip.address, | ||
| 529 | nas.id | ||
| 530 | INTO assignedIp, | ||
| 531 | assignNasId | ||
| 532 | FROM ip | ||
| 533 | INNER JOIN netblock | ||
| 534 | ON netblock.network >>= ip.address | ||
| 535 | INNER JOIN region | ||
| 536 | ON region.id = netblock.regionId | ||
| 537 | INNER JOIN pool | ||
| 538 | ON pool.id = netblock.poolId | ||
| 539 | INNER JOIN nas | ||
| 540 | ON nas.regionId = region.id | ||
| 541 | WHERE ip.nasId IS NULL | ||
| 542 | AND ip.username LIKE lower( assignUser ) | ||
| 543 | AND nas.name LIKE lower( assignNas ) | ||
| 544 | AND pool.name LIKE lower( assignPool ) | ||
| 545 | AND netblock.active = TRUE | ||
| 546 | ORDER BY ip.modified DESC, | ||
| 547 | ip.address ASC | ||
| 548 | LIMIT 1; | ||
| 549 | IF NOT FOUND THEN | ||
| 550 | RETURN NULL; | ||
| 551 | END IF; | ||
| 552 | END IF; | ||
| 553 | |||
| 554 | -- update record | ||
| 555 | UPDATE ip | ||
| 556 | SET nasId = assignNasId, | ||
| 557 | username = assignUser, | ||
| 558 | acctSession = assignSess | ||
| 559 | WHERE address = assignedIp; | ||
| 560 | IF NOT FOUND THEN | ||
| 561 | RETURN NULL; | ||
| 562 | END IF; | ||
| 563 | |||
| 564 | RETURN assignedIp; | ||
| 565 | END; | ||
| 566 | $$; | ||
| 567 | |||
| 568 | |||
| 569 | |||
| 570 | /* | ||
| 406 | * updates timestamp of addresses | 571 | * updates timestamp of addresses |
| 407 | * | 572 | * |
| 408 | * returns trigger | 573 | * returns trigger |
| @@ -420,7 +585,8 @@ BEGIN | |||
| 420 | 585 | ||
| 421 | -- updates record | 586 | -- updates record |
| 422 | UPDATE ip | 587 | UPDATE ip |
| 423 | SET nasId = NULL | 588 | SET nasId = NULL, |
| 589 | acctSession = NULL | ||
| 424 | WHERE address = set_masklen( assignIp, 32 ); | 590 | WHERE address = set_masklen( assignIp, 32 ); |
| 425 | 591 | ||
| 426 | RETURN FOUND; | 592 | RETURN FOUND; |
