aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavid M. Syzdek <syzdek@bindlebinaries.com>2019-05-14 10:49:37 -0800
committerDavid M. Syzdek <syzdek@bindlebinaries.com>2019-05-14 10:49:37 -0800
commit8c9a797d9b096047ee65cd816844f1bc4d7f57de (patch)
treee7af45709a1e433413356961b977f598bcc3d7ad
parent6095c1ebd48ea7559f64346eab606ad2835b94b0 (diff)
downloadscratchpad-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.sql196
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 */
355CREATE OR REPLACE FUNCTION ip_assign 363CREATE 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 $$
366DECLARE 376DECLARE
367 assignNasId INTEGER; 377 assignNasId INTEGER;
378 assignPortCount INTEGER;
368BEGIN 379BEGIN
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;
401END; 437END;
@@ -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 */
478CREATE 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 $$
491DECLARE
492 assignedIp INET;
493 assignNasId INTEGER;
494BEGIN
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;
565END;
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;