Changeset 545 for branches/stable/dns.cgi
- Timestamp:
- 12/10/13 17:47:44 (11 years ago)
- Location:
- branches/stable
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
branches/stable
- Property svn:mergeinfo changed
/trunk merged: 264-316,318-416
- Property svn:mergeinfo changed
-
branches/stable/dns.cgi
r544 r545 3 3 ## 4 4 # $Id$ 5 # Copyright 2008-201 1Kris Deugau <kdeugau@deepnet.cx>5 # Copyright 2008-2012 Kris Deugau <kdeugau@deepnet.cx> 6 6 # 7 7 # This program is free software: you can redistribute it and/or modify … … 96 96 $session->param('reclistsortby','host'); 97 97 $session->param('reclistorder','ASC'); 98 $session->param('loclistsortby','description'); 99 $session->param('loclistorder','ASC'); 100 $session->param('logsortby','stamp'); 101 $session->param('logorder','DESC'); 98 102 } 99 103 … … 122 126 $webvar{startwith} =~ s/^(0-9|[a-z]).*/$1/ if $webvar{startwith}; 123 127 # not much call for chars not allowed in domain names 124 $webvar{filter} =~ s/[^a-zA-Z0-9_.: @-]//g if $webvar{filter};128 $webvar{filter} =~ s/[^a-zA-Z0-9_.:\@-]//g if $webvar{filter}; 125 129 ## only set 'y' if box is checked, no other values legal 126 130 ## however, see https://secure.deepnet.cx/trac/dnsadmin/ticket/31 … … 227 231 if ($webvar{action} eq 'login') { 228 232 # Snag ACL/permissions here too 229 my $sth = $dbh->prepare("SELECT user_id,group_id,password,firstname,lastname,status FROM users WHERE username=?"); 230 $sth->execute($webvar{username}); 231 232 if (my ($uid,$gid,$pass,$fname,$lname,$status) = $sth->fetchrow_array) { 233 $webvar{password} = '' if !$webvar{password}; 234 if (!$status) { 235 $webvar{loginfailed} = 1; 236 } elsif ($pass =~ m|^\$1\$([A-Za-z0-9/.]+)\$|) { 237 # native passwords (crypt-md5) 238 $webvar{loginfailed} = 1 if $pass ne unix_md5_crypt($webvar{password},$1); 239 } elsif ($pass =~ /^[0-9a-f]{32}$/) { 240 # VegaDNS import (hex-coded MD5) 241 $webvar{loginfailed} = 1 if $pass ne md5_hex($webvar{password}); 242 } else { 243 # plaintext (convenient now and then) 244 $webvar{loginfailed} = 1 if $pass ne $webvar{password}; 245 } 233 234 my $userdata = login($dbh, $webvar{username}, $webvar{password}); 235 236 if ($userdata) { 246 237 247 238 # set session bits 248 $session->param('logingroup',$ gid);249 $session->param('curgroup',$ gid);250 $session->param('uid',$u id);239 $session->param('logingroup',$userdata->{group_id}); 240 $session->param('curgroup',$userdata->{group_id}); 241 $session->param('uid',$userdata->{user_id}); 251 242 $session->param('username',$webvar{username}); 252 243 253 changepage(page => "domlist") if !defined($webvar{loginfailed});244 changepage(page => "domlist"); 254 245 255 246 } else { … … 299 290 } # handle global webvar{action}s 300 291 301 initPermissions($dbh,$session->param('uid')); 292 # finally check if the user was disabled. we could just leave this for logout/session expiry, 293 # but if they keep the session active they'll continue to have access long after being disabled. :/ 294 # Treat it as a session expiry. 295 if ($session->param('uid') && !userStatus($dbh, $session->param('uid')) ) { 296 $sid = ''; 297 $session->delete; # force expiry of the session Right Away 298 $session->flush; # make sure it hits storage 299 changepage(page=> "login", sessexpired => 1); 300 } 301 302 # Misc Things To Do on most pages 303 initPermissions($dbh, $session->param('uid')); 304 initActionLog($dbh, $session->param('uid')); 302 305 303 306 $page->param(sid => $sid) unless $webvar{page} eq 'login'; # no session ID on the login page … … 307 310 $page->param(loginfailed => 1) if $webvar{loginfailed}; 308 311 $page->param(sessexpired => 1) if $webvar{sessexpired}; 309 # $page->param(orgname => $config{orgname}) if $config{orgname} ne 'Example Corp';310 312 $page->param(version => $DNSDB::VERSION); 311 313 … … 316 318 # hmm. seeing problems in some possibly-not-so-corner cases. 317 319 # this currently only handles "domain on", "domain off" 318 if (defined($webvar{ domstatus})) {320 if (defined($webvar{zonestatus})) { 319 321 # security check - does the user have permission to access this entity? 320 322 my $flag = 0; … … 323 325 } 324 326 if ($flag && ($permissions{admin} || $permissions{domain_edit})) { 325 my $stat = domStatus($dbh,$webvar{id},$webvar{domstatus}); 326 ##fixme switch to more consise "Enabled <domain"/"Disabled <domain>" as with users? 327 logaction($webvar{id}, $session->param("username"), 328 parentID($dbh, (id => $webvar{id}, type => 'domain', revrec => $webvar{revrec})), 329 "Changed ".domainName($dbh, $webvar{id})." state to ".($stat ? 'active' : 'inactive')); 330 $page->param(resultmsg => "Changed ".domainName($dbh, $webvar{id})." state to ". 331 ($stat ? 'active' : 'inactive')); 327 my $stat = zoneStatus($dbh,$webvar{id},'n',$webvar{zonestatus}); 328 $page->param(resultmsg => $DNSDB::resultstr); 332 329 } else { 333 330 $page->param(errmsg => "You are not permitted to view or change the requested domain"); 334 331 } 335 $uri_self =~ s/\&domstatus=[^&]*//g; # clean up URL for stuffing into templates 336 } 337 338 if ($session->param('resultmsg')) { 339 $page->param(resultmsg => $session->param('resultmsg')); 340 $session->clear('resultmsg'); 341 } 342 if ($session->param('errmsg')) { 343 $page->param(errmsg => $session->param('errmsg')); 344 $session->clear('errmsg'); 345 } 332 $uri_self =~ s/\&zonestatus=[^&]*//g; # clean up URL for stuffing into templates 333 } 334 335 show_msgs(); 346 336 347 337 $page->param(curpage => $webvar{page}); … … 354 344 unless ($permissions{admin} || $permissions{domain_create}); 355 345 356 fill_grouplist("grouplist"); 346 $webvar{group} = $curgroup if !$webvar{group}; 347 fill_grouplist("grouplist", $webvar{group}); 348 fill_loclist(); 357 349 358 350 if ($session->param('add_failed')) { … … 362 354 $session->clear('errmsg'); 363 355 $page->param(domain => $webvar{domain}); 356 $page->param(addinactive => $webvar{makeactive} eq 'n'); 364 357 } 365 358 … … 379 372 $webvar{makeactive} = 0 if !defined($webvar{makeactive}); 380 373 381 my ($code,$msg) = addDomain($dbh,$webvar{domain},$webvar{group},($webvar{makeactive} eq 'on' ? 1 : 0), 382 (username => $session->param("username"), id => $session->param("uid"))); 374 my ($code,$msg) = addDomain($dbh,$webvar{domain},$webvar{group},($webvar{makeactive} eq 'on' ? 1 : 0)); 383 375 384 376 if ($code eq 'OK') { … … 388 380 changepage(page => "reclist", id => $msg); 389 381 } else { 390 logaction(0, $session->param("username"), $webvar{group}, "Failed adding domain $webvar{domain} ($msg)")391 if $config{log_failures};392 382 $session->param('add_failed', 1); 393 383 ##fixme: domain a security risk for XSS? 394 ##fixme: keep active/inactive state, group selection 395 changepage(page => "newdomain", domain => $webvar{domain}, errmsg => $msg);384 changepage(page => "newdomain", domain => $webvar{domain}, errmsg => $msg, 385 makeactive => ($webvar{makeactive} ? 'y' : 'n'), group => $webvar{group}); 396 386 } 397 387 … … 416 406 } elsif ($webvar{del} eq 'ok') { 417 407 my $pargroup = parentID($dbh, (id => $webvar{id}, type => 'domain', revrec => $webvar{revrec})); 418 my $dom = domainName($dbh, $webvar{id}); 419 my ($code,$msg) = delDomain($dbh, $webvar{id}); 408 my ($code,$msg) = delZone($dbh, $webvar{id}, $webvar{revrec}); 420 409 if ($code eq 'OK') { 421 logaction($webvar{id}, $session->param("username"), $pargroup, "Deleted domain $dom"); 422 changepage(page => "domlist", resultmsg => "Deleted domain $dom"); 410 changepage(page => "domlist", resultmsg => $msg); 423 411 } else { 424 logaction($webvar{id}, $session->param("username"), $pargroup, "Failed to delete domain $dom ($msg)") 425 if $config{log_failures}; 426 changepage(page => "domlist", errmsg => "Error deleting domain $dom: $msg"); 412 changepage(page => "domlist", errmsg => $msg); 427 413 } 428 414 … … 435 421 436 422 $webvar{revrec} = 'y'; 423 424 if (defined($webvar{zonestatus})) { 425 # security check - does the user have permission to access this entity? 426 my $flag = 0; 427 foreach (@viewablegroups) { 428 $flag = 1 if isParent($dbh, $_, 'group', $webvar{id}, 'revzone'); 429 } 430 if ($flag && ($permissions{admin} || $permissions{domain_edit})) { 431 my $stat = zoneStatus($dbh,$webvar{id},'y',$webvar{zonestatus}); 432 $page->param(resultmsg => $DNSDB::resultstr); 433 } else { 434 $page->param(errmsg => "You are not permitted to view or change the requested reverse zone"); 435 } 436 $uri_self =~ s/\&zonestatus=[^&]*//g; # clean up URL for stuffing into templates 437 } 438 439 show_msgs(); 440 437 441 $page->param(curpage => $webvar{page}); 438 442 listzones(); … … 446 450 fill_grouplist("grouplist"); 447 451 448 if ($webvar{add_failed}) { 449 $page->param(add_failed => 1); 450 $page->param(errmsg => $webvar{errmsg}); 452 # prepopulate revpatt with the matching default record 453 # getRecByName($dbh, (revrec => $webvar{revrec}, defrec => $webvar{defrec}, host => 'string')); 454 455 if ($session->param('add_failed')) { 456 $session->clear('add_failed'); 457 $page->param(errmsg => $session->param('errmsg')); 458 $session->clear('errmsg'); 451 459 $page->param(revzone => $webvar{revzone}); 452 460 $page->param(revpatt => $webvar{revpatt}); … … 465 473 466 474 my ($code,$msg) = addRDNS($dbh, $webvar{revzone}, $webvar{revpatt}, $webvar{group}, 467 ($webvar{makeactive} eq 'on' ? 1 : 0), 468 (username => $session->param("username"), id => $session->param("uid")) ); 475 ($webvar{makeactive} eq 'on' ? 1 : 0)); 469 476 470 477 if ($code eq 'OK') { 471 logaction(0, $session->param("username"), $webvar{group}, "Added reverse zone $webvar{revzone}", $msg);472 478 changepage(page => "reclist", id => $msg, revrec => 'y'); 479 } elsif ($code eq 'WARN') { 480 changepage(page => "reclist", id => $msg, revrec => 'y', warnmsg => $DNSDB::resultstr); 473 481 } else { 474 logaction(0, $session->param("username"), $webvar{group}, "Failed adding reverse zone $webvar{revzone} ($msg)"); 475 changepage(page => "newrevzone", add_failed => 1, revzone => $webvar{revzone}, revpatt => $webvar{revpatt}, 476 errmsg => $msg); 477 } 478 479 #} elsif ($webvar{page} eq 'delrevzone') { 482 $session->param('add_failed', 1); 483 changepage(page => "newrevzone", revzone => $webvar{revzone}, revpatt => $webvar{revpatt}, errmsg => $msg); 484 } 485 486 } elsif ($webvar{page} eq 'delrevzone') { 487 488 changepage(page => "revzones", errmsg => "You are not permitted to delete reverse zones") 489 unless ($permissions{admin} || $permissions{domain_delete}); 490 491 # security check - does the user have permission to access this entity? 492 if (!check_scope(id => $webvar{id}, type => 'revzone')) { 493 changepage(page => "revzones", errmsg => "You do not have permission to delete the requested reverse zone"); 494 } 495 496 $page->param(id => $webvar{id}); 497 498 # first pass = confirm y/n (sorta) 499 if (!defined($webvar{del})) { 500 501 $page->param(del_getconf => 1); 502 $page->param(revzone => revName($dbh,$webvar{id})); 503 504 } elsif ($webvar{del} eq 'ok') { 505 my $pargroup = parentID($dbh, (id => $webvar{id}, type => 'revzone', revrec => $webvar{revrec})); 506 my $zone = revName($dbh, $webvar{id}); 507 my ($code,$msg) = delZone($dbh, $webvar{id}, 'y'); 508 if ($code eq 'OK') { 509 changepage(page => "revzones", resultmsg => $msg); 510 } else { 511 changepage(page => "revzones", errmsg => $msg); 512 } 513 514 } else { 515 # cancelled. whee! 516 changepage(page => "revzones"); 517 } 480 518 481 519 } elsif ($webvar{page} eq 'reclist') { … … 531 569 distance => 'Distance', weight => 'Weight', port => 'Port', ttl => 'TTL'); 532 570 } else { 533 @cols = (' host', 'type', 'val', 'ttl');534 %colheads = ( host => 'IP Address', type => 'Type', val=> 'Hostname', ttl => 'TTL');571 @cols = ('val', 'type', 'host', 'ttl'); 572 %colheads = (val => 'IP Address', type => 'Type', host => 'Hostname', ttl => 'TTL'); 535 573 } 536 574 my %custom = (id => $webvar{id}, defrec => $webvar{defrec}, revrec => $webvar{revrec}); … … 547 585 showzone($webvar{defrec}, $webvar{revrec}, $webvar{id}); 548 586 if ($webvar{defrec} eq 'n') { 549 # showzone('n',$webvar{id});550 ##fixme: permission for viewing logs?551 ##fixme: determine which slice of the log we view (group, domain, revzone)552 587 if ($webvar{revrec} eq 'n') { 553 588 $page->param(logdom => 1); … … 557 592 } 558 593 559 if ($session->param('resultmsg')) { 560 $page->param(resultmsg => $session->param('resultmsg')); 561 $session->clear('resultmsg'); 562 } 563 if ($session->param('warnmsg')) { 564 $page->param(warnmsg => $session->param('warnmsg')); 565 $session->clear('warnmsg'); 566 } 567 if ($session->param('errmsg')) { 568 $page->param(errmsg => $session->param('errmsg')); 569 $session->clear('errmsg'); 570 } 594 show_msgs(); 571 595 572 596 } # close "you can't edit default records" check … … 608 632 fill_recdata(); 609 633 634 if ($webvar{defrec} eq 'n') { 635 my $defloc = getZoneLocation($dbh, $webvar{revrec}, $webvar{parentid}); 636 fill_loclist($curgroup, $defloc); 637 } 638 610 639 } elsif ($webvar{recact} eq 'add') { 611 640 … … 613 642 unless ($permissions{admin} || $permissions{record_create}); 614 643 644 # location check - if user does not have record_locchg, set $webvar{location} to default location for zone 645 my $parloc = getZoneLocation($dbh, $webvar{revrec}, $webvar{parentid}); 646 $webvar{location} = $parloc unless ($permissions{admin} || $permissions{record_locchg}); 647 615 648 my @recargs = ($dbh,$webvar{defrec},$webvar{revrec},$webvar{parentid}, 616 \$webvar{name},\$webvar{type},\$webvar{address},$webvar{ttl} );649 \$webvar{name},\$webvar{type},\$webvar{address},$webvar{ttl},$webvar{location}); 617 650 if ($webvar{type} == $reverse_typemap{MX} or $webvar{type} == $reverse_typemap{SRV}) { 618 651 push @recargs, $webvar{distance}; … … 626 659 627 660 if ($code eq 'OK' || $code eq 'WARN') { 628 my $restr;629 if ($webvar{defrec} eq 'y') {630 $restr = "Added default record '$webvar{name} $typemap{$webvar{type}}";631 $restr .= " [distance $webvar{distance}]" if $typemap{$webvar{type}} eq 'MX';632 $restr .= " [priority $webvar{distance}] [weight $webvar{weight}] [port $webvar{port}]"633 if $typemap{$webvar{type}} eq 'SRV';634 $restr .= " $webvar{address}', TTL $webvar{ttl}";635 logaction(0, $session->param("username"), $webvar{parentid}, $restr);636 } else {637 $restr = "Added record '$webvar{name} $typemap{$webvar{type}}";638 $restr .= " [distance $webvar{distance}]" if $typemap{$webvar{type}} eq 'MX';639 $restr .= " [priority $webvar{distance}] [weight $webvar{weight}] [port $webvar{port}]"640 if $typemap{$webvar{type}} eq 'SRV';641 $restr .= " $webvar{address}', TTL $webvar{ttl}";642 logaction($webvar{parentid}, $session->param("username"),643 parentID($dbh, (id => $webvar{parentid}, type => 'domain', revrec => $webvar{revrec})), $restr);644 }645 661 my %pageparams = (page => "reclist", id => $webvar{parentid}, 646 662 defrec => $webvar{defrec}, revrec => $webvar{revrec}); 647 $pageparams{warnmsg} = $msg."<br><br>\n".$ restr if $code eq 'WARN';648 $pageparams{resultmsg} = $ restr if $code eq 'OK';663 $pageparams{warnmsg} = $msg."<br><br>\n".$DNSDB::resultstr if $code eq 'WARN'; 664 $pageparams{resultmsg} = $DNSDB::resultstr if $code eq 'OK'; 649 665 changepage(%pageparams); 650 666 } else { … … 657 673 $page->param(id => $webvar{id}); 658 674 fill_recdata(); # populate the form... er, mostly. 659 if ($config{log_failures}) { 660 if ($webvar{defrec} eq 'y') { 661 logaction(0, $session->param("username"), $webvar{parentid}, 662 "Failed adding default record '$webvar{name} $typemap{$webvar{type}} $webvar{address}', TTL $webvar{ttl} ($msg)"); 663 } else { 664 logaction($webvar{parentid}, $session->param("username"), 665 parentID($dbh, (id => $webvar{parentid}, type => 'domain', revrec => $webvar{revrec})), 666 "Failed adding record '$webvar{name} $typemap{$webvar{type}} $webvar{address}', TTL $webvar{ttl} ($msg)"); 667 } 675 if ($webvar{defrec} eq 'n') { 676 fill_loclist($curgroup, $webvar{location}); 668 677 } 669 678 } … … 685 694 $page->param(port => $recdata->{port}); 686 695 $page->param(ttl => $recdata->{ttl}); 687 $page->param(typelist => getTypelist($dbh, $webvar{revrec}, $webvar{type})); 696 $page->param(typelist => getTypelist($dbh, $webvar{revrec}, $recdata->{type})); 697 698 if ($webvar{defrec} eq 'n') { 699 fill_loclist($curgroup, $recdata->{location}); 700 } 688 701 689 702 } elsif ($webvar{recact} eq 'update') { … … 692 705 unless ($permissions{admin} || $permissions{record_edit}); 693 706 694 # prevent out-of-domain records from getting added by appending the domain, or DOMAIN for default records 695 my $pname = ($webvar{defrec} eq 'y' ? 'DOMAIN' : domainName($dbh,$webvar{parentid})); 696 $webvar{name} =~ s/\s+$//; 697 $webvar{name} =~ s/\.*$/\.$pname/ if $webvar{name} !~ /$pname$/; 698 699 # get current/previous record info so we can log "updated 'foo A 1.2.3.4' to 'foo A 2.3.4.5'" 707 # retain old location if user doesn't have permission to fiddle locations 700 708 my $oldrec = getRecLine($dbh, $webvar{defrec}, $webvar{revrec}, $webvar{id}); 701 702 my ($code,$msg) = updateRec($dbh,$webvar{defrec},$webvar{id}, 703 $webvar{name},$webvar{type},$webvar{address},$webvar{ttl}, 709 $webvar{location} = $oldrec->{location} unless ($permissions{admin} || $permissions{record_locchg}); 710 711 my ($code,$msg) = updateRec($dbh,$webvar{defrec},$webvar{revrec},$webvar{id},$webvar{parentid}, 712 \$webvar{name},\$webvar{type},\$webvar{address},$webvar{ttl},$webvar{location}, 704 713 $webvar{distance},$webvar{weight},$webvar{port}); 705 714 706 if ($code eq 'OK') { 707 ##fixme: retrieve old record info for full logging of change 708 if ($webvar{defrec} eq 'y') { 709 my $restr = "Updated default record from '$oldrec->{host} $typemap{$oldrec->{type}} $oldrec->{val}', TTL $oldrec->{ttl}\n". 710 "to '$webvar{name} $typemap{$webvar{type}} $webvar{address}', TTL $webvar{ttl}"; 711 logaction(0, $session->param("username"), $webvar{parentid}, $restr); 712 changepage(page => "reclist", id => $webvar{parentid}, defrec => $webvar{defrec}, resultmsg => $restr); 713 } else { 714 my $restr = "Updated record from '$oldrec->{host} $typemap{$oldrec->{type}} $oldrec->{val}', TTL $oldrec->{ttl}\n". 715 "to '$webvar{name} $typemap{$webvar{type}} $webvar{address}', TTL $webvar{ttl}"; 716 logaction($webvar{parentid}, $session->param("username"), 717 parentID($dbh, (id => $webvar{id}, type => 'record', defrec => $webvar{defrec}, 718 revrec => $webvar{revrec}, partype => 'group')), 719 $restr); 720 changepage(page => "reclist", id => $webvar{parentid}, defrec => $webvar{defrec}, resultmsg => $restr); 721 } 715 if ($code eq 'OK' || $code eq 'WARN') { 716 my %pageparams = (page => "reclist", id => $webvar{parentid}, 717 defrec => $webvar{defrec}, revrec => $webvar{revrec}); 718 $pageparams{warnmsg} = $msg."<br><br>\n".$DNSDB::resultstr if $code eq 'WARN'; 719 $pageparams{resultmsg} = $DNSDB::resultstr if $code eq 'OK'; 720 changepage(%pageparams); 722 721 } else { 723 722 $page->param(failed => 1); … … 729 728 $page->param(id => $webvar{id}); 730 729 fill_recdata(); 731 if ($config{log_failures}) {732 if ($webvar{defrec} eq 'y') {733 logaction(0, $session->param("username"), $webvar{parentid},734 "Failed updating default record '$typemap{$webvar{type}} $webvar{name} $webvar{address}', TTL $webvar{ttl} ($msg)");735 } else {736 logaction($webvar{parentid}, $session->param("username"),737 parentID($dbh, (id => $webvar{parentid}, type => 'domain', revrec => $webvar{revrec})),738 "Failed updating record '$typemap{$webvar{type}} $webvar{name} $webvar{address}', TTL $webvar{ttl} ($msg)");739 }740 }741 730 } 742 731 } … … 745 734 $page->param(dohere => "default records in group ".groupName($dbh,$webvar{parentid})); 746 735 } else { 747 $page->param(parentid => $webvar{parentid});748 736 $page->param(dohere => domainName($dbh,$webvar{parentid})) if $webvar{revrec} eq 'n'; 749 737 $page->param(dohere => revName($dbh,$webvar{parentid})) if $webvar{revrec} eq 'y'; … … 781 769 $page->param(recval => $rec->{val}); 782 770 } elsif ($webvar{del} eq 'ok') { 783 # get rec data before we try to delete it784 my $rec = getRecLine($dbh, $webvar{defrec}, $webvar{revrec}, $webvar{id});785 771 my ($code,$msg) = delRec($dbh, $webvar{defrec}, $webvar{revrec}, $webvar{id}); 786 772 if ($code eq 'OK') { 787 if ($webvar{defrec} eq 'y') { 788 my $recclass = ($webvar{revrec} eq 'n' ? 'default record' : 'default reverse record'); 789 ##fixme: log distance for MX; log port/weight/distance for SRV 790 my $restr = "Deleted $recclass '$rec->{host} $typemap{$rec->{type}} $rec->{val}', TTL $rec->{ttl}"; 791 logaction(0, $session->param("username"), $rec->{parid}, $restr); 792 changepage(page => "reclist", id => $webvar{parentid}, defrec => $webvar{defrec}, 793 revrec => $webvar{revrec}, resultmsg => $restr); 794 } else { 795 my $recclass = ($webvar{revrec} eq 'n' ? 'record' : 'reverse record'); 796 my $restr = "Deleted $recclass '$rec->{host} $typemap{$rec->{type}} $rec->{val}', TTL $rec->{ttl}"; 797 logaction($rec->{parid}, $session->param("username"), 798 parentID($dbh, (id => $rec->{parid}, type => 'domain', revrec => $webvar{revrec})), 799 $restr); 800 changepage(page => "reclist", id => $webvar{parentid}, defrec => $webvar{defrec}, 801 revrec => $webvar{revrec}, resultmsg => $restr); 802 } 773 changepage(page => "reclist", id => $webvar{parentid}, defrec => $webvar{defrec}, 774 revrec => $webvar{revrec}, resultmsg => $msg); 803 775 } else { 804 776 ## need to find failure mode 805 if ($config{log_failures}) {806 if ($webvar{defrec} eq 'y') {807 logaction(0, $session->param("username"), $rec->{parid},808 "Failed deleting default record '$rec->{host} $typemap{$rec->{type}} $rec->{val}',".809 " TTL $rec->{ttl} ($msg)");810 } else {811 logaction($rec->{parid}, $session->param("username"),812 parentID($dbh, (id => $rec->{parid}, type => 'domain', revrec => $webvar{revrec})),813 "Failed deleting record '$rec->{host} $typemap{$rec->{type}} $rec->{val}', TTL $rec->{ttl} ($msg)");814 }815 }816 777 changepage(page => "reclist", id => $webvar{parentid}, defrec => $webvar{defrec}, 817 revrec => $webvar{revrec}, errmsg => "Error deleting record: $msg");778 revrec => $webvar{revrec}, errmsg => $msg); 818 779 } 819 780 } else { … … 840 801 } 841 802 842 fillsoa($webvar{defrec},$webvar{ id});803 fillsoa($webvar{defrec},$webvar{revrec},$webvar{id}); 843 804 844 805 } elsif ($webvar{page} eq 'updatesoa') { … … 848 809 if (!check_scope(id => $webvar{recid}, type => 849 810 ($webvar{defrec} eq 'y' ? ($webvar{revrec} eq 'y' ? 'defrevrec' : 'defrec') : 'record'))) { 811 ##fixme: should we redirect to the requested record list page instead of the domain list? 850 812 changepage(page => 'domlist', errmsg => "You do not have permission to edit the requested SOA record"); 851 813 } … … 853 815 if (!check_scope(id => $webvar{id}, type => 854 816 ($webvar{defrec} eq 'y' ? 'group' : ($webvar{revrec} eq 'y' ? 'revzone' : 'domain')))) { 855 changepage(page => 'domlist', errmsg => "You do not have permission to edit the ". 817 changepage(page => ($webvar{revrec} eq 'y' ? 'revzones' : 'domlist'), 818 errmsg => "You do not have permission to edit the ". 856 819 ($webvar{defrec} eq 'y' ? 'default ' : '')."SOA record for the requested ". 857 ($webvar{defrec} eq 'y' ? 'group' : 'domain'));820 ($webvar{defrec} eq 'y' ? 'group' : ($webvar{revrec} eq 'y' ? 'reverse zone' : 'domain')) ); 858 821 } 859 822 … … 861 824 unless ($permissions{admin} || $permissions{domain_edit}); 862 825 863 # get old SOA for log 864 my %soa = getSOA($dbh,$webvar{defrec},$webvar{id}); 865 866 my $sth; 867 ##fixme: push SQL into DNSDB.pm 868 ##fixme: data validation: make sure {recid} is really the SOA for {id} 869 # no domain ID, so we're editing the default SOA for a group (we don't care which one here) 870 # plus a bit of magic to update the appropriate table 871 my $sql = "UPDATE ".($webvar{defrec} eq 'y' ? "default_records" : "records"). 872 " SET host=?, val=?, ttl=? WHERE record_id=?"; 873 $sth = $dbh->prepare($sql); 874 $sth->execute("$webvar{contact}:$webvar{prins}", 875 "$webvar{refresh}:$webvar{retry}:$webvar{expire}:$webvar{minttl}", 876 $webvar{ttl}, 877 $webvar{recid}); 878 879 if ($sth->err) { 826 my ($code, $msg) = updateSOA($dbh, $webvar{defrec}, $webvar{revrec}, 827 (contact => $webvar{contact}, prins => $webvar{prins}, refresh => $webvar{refresh}, 828 retry => $webvar{retry}, expire => $webvar{expire}, minttl => $webvar{minttl}, 829 ttl => $webvar{ttl}, id => $webvar{id}) ); 830 if ($code eq 'OK') { 831 changepage(page => "reclist", id => $webvar{id}, defrec => $webvar{defrec}, revrec => $webvar{revrec}, 832 resultmsg => "SOA record updated"); 833 } else { 880 834 $page->param(update_failed => 1); 881 $page->param(msg => $DBI::errstr); 882 fillsoa($webvar{defrec},$webvar{id}); 883 ##fixme: faillog 884 } else { 885 886 # do this in the order of "default to most common case" 887 my $loggroup; 888 my $logdomain = $webvar{id}; 889 if ($webvar{defrec} eq 'y') { 890 $loggroup = $webvar{id}; 891 $logdomain = 0; 892 } else { 893 $loggroup = parentID($dbh, (id => $logdomain, type => 'domain', revrec => $webvar{revrec})); 894 } 895 896 logaction($logdomain, $session->param("username"), $loggroup, 897 "Updated ".($webvar{defrec} eq 'y' ? 'default ' : '')."SOA for ". 898 ($webvar{defrec} eq 'y' ? groupName($dbh, $webvar{id}) : domainName($dbh, $webvar{id}) ). 899 ": (ns $soa{prins}, contact $soa{contact}, refresh $soa{refresh},". 900 " retry $soa{retry}, expire $soa{expire}, minTTL $soa{minttl}, TTL $soa{ttl}) to ". 901 "(ns $webvar{prins}, contact $webvar{contact}, refresh $webvar{refresh},". 902 " retry $webvar{retry}, expire $webvar{expire}, minTTL $webvar{minttl}, TTL $webvar{ttl})"); 903 changepage(page => "reclist", id => $webvar{id}, defrec => $webvar{defrec}, 904 resultmsg => "SOA record updated"); 835 $page->param(msg => $msg); 836 fillsoa($webvar{defrec}, $webvar{revrec}, $webvar{id}, 'w'); 905 837 } 906 838 … … 914 846 $page->param(delgrp => $permissions{admin} || $permissions{group_delete}); 915 847 916 if ($session->param('resultmsg')) { 917 $page->param(resultmsg => $session->param('resultmsg')); 918 $session->clear('resultmsg'); 919 } 920 if ($session->param('warnmsg')) { 921 $page->param(warnmsg => $session->param('warnmsg')); 922 $session->clear('warnmsg'); 923 } 924 if ($session->param('errmsg')) { 925 $page->param(errmsg => $session->param('errmsg')); 926 $session->clear('errmsg'); 927 } 848 show_msgs(); 928 849 $page->param(curpage => $webvar{page}); 929 850 … … 951 872 } 952 873 } 953 # force inheritance of parent group's default records with inherit flag, 954 # otherwise we end up with the hardcoded defaults from DNSDB.pm. See 955 # https://secure.deepnet.cx/trac/dnsadmin/ticket/8 for the UI enhancement 956 # that will make this variable. 957 my ($code,$msg) = addGroup($dbh, $webvar{newgroup}, $webvar{pargroup}, \%newperms, 1); 874 # "Chained" permissions. Some permissions imply others; make sure they get set. 875 foreach (keys %permchains) { 876 if ($newperms{$_} && !$newperms{$permchains{$_}}) { 877 $newperms{$permchains{$_}} = 1; 878 } 879 } 880 # not gonna provide the 4th param: template-or-clone flag, just yet 881 my ($code,$msg) = addGroup($dbh, $webvar{newgroup}, $webvar{pargroup}, \%newperms); 958 882 if ($code eq 'OK') { 959 logaction(0, $session->param("username"), $webvar{pargroup}, "Added group $webvar{newgroup}");960 883 if ($alterperms) { 961 884 changepage(page => "grpman", warnmsg => … … 965 888 } 966 889 } # fallthrough else 967 logaction(0, $session->param("username"), $webvar{pargroup}, "Failed to add group $webvar{newgroup}: $msg")968 if $config{log_failures};969 890 # no point in doing extra work 970 891 fill_permissions($page, \%newperms); … … 1001 922 1002 923 } elsif ($webvar{del} eq 'ok') { 1003 my $deleteme = groupName($dbh,$webvar{id}); # get this before we delete it...1004 my $delparent = parentID($dbh, (id => $webvar{id}, type => 'group'));1005 924 my ($code,$msg) = delGroup($dbh, $webvar{id}); 1006 925 if ($code eq 'OK') { 1007 926 ##fixme: need to clean up log when deleting a major container 1008 logaction(0, $session->param("username"), $delparent, "Deleted group $deleteme"); 1009 changepage(page => "grpman", resultmsg => "Deleted group $deleteme"); 927 changepage(page => "grpman", resultmsg => $msg); 1010 928 } else { 1011 929 # need to find failure mode 1012 logaction(0, $session->param("username"), $delparent, "Failed to delete group $deleteme: $msg") 1013 if $config{log_failures}; 1014 changepage(page => "grpman", errmsg => "Error deleting group $deleteme: $msg"); 930 changepage(page => "grpman", errmsg => $msg); 1015 931 } 1016 932 } else { … … 1030 946 } 1031 947 1032 if ($webvar{grpaction} eq 'updperms') {948 if ($webvar{grpaction} && $webvar{grpaction} eq 'updperms') { 1033 949 # extra safety check; make sure user can't construct a URL to bypass ACLs 1034 950 my %curperms; … … 1046 962 } 1047 963 } 964 # "Chained" permissions. Some permissions imply others; make sure they get set. 965 foreach (keys %permchains) { 966 if ($chperms{$_} && !$chperms{$permchains{$_}}) { 967 $chperms{$permchains{$_}} = 1; 968 } 969 } 1048 970 my ($code,$msg) = changePermissions($dbh, 'group', $webvar{gid}, \%chperms); 1049 971 if ($code eq 'OK') { 1050 logaction(0, $session->param("username"), $webvar{gid},1051 "Updated default permissions in group $webvar{gid} (".groupName($dbh, $webvar{gid}).")");1052 972 if ($alterperms) { 1053 973 changepage(page => "grpman", warnmsg => … … 1055 975 groupName($dbh, $webvar{gid})." updated with reduced access"); 1056 976 } else { 1057 changepage(page => "grpman", resultmsg => 1058 "Updated default permissions in group ".groupName($dbh, $webvar{gid})); 977 changepage(page => "grpman", resultmsg => $msg); 1059 978 } 1060 979 } # fallthrough else 1061 logaction(0, $session->param("username"), $webvar{gid}, "Failed to update default permissions in group ".1062 groupName($dbh, $webvar{gid}).": $msg")1063 if $config{log_failures};1064 980 # no point in doing extra work 1065 981 fill_permissions($page, \%chperms); … … 1074 990 } elsif ($webvar{page} eq 'bulkdomain') { 1075 991 # Bulk operations on domains. Note all but group move are available on the domain list. 992 ##fixme: do we care about bulk operations on revzones? Move-to-group, activate, deactivate, 993 # and delete should all be much rarer for revzones than for domains. 1076 994 1077 995 changepage(page => "domlist", errmsg => "You are not permitted to make bulk domain changes") … … 1080 998 fill_grouplist("grouplist"); 1081 999 1082 ##fixme 1083 ##fixme push the SQL and direct database fiddling off into a sub in DNSDB.pm 1084 ##fixme 1085 1086 my $sth = $dbh->prepare("SELECT count(*) FROM domains WHERE group_id=?"); 1087 $sth->execute($curgroup); 1088 my ($count) = ($sth->fetchrow_array); 1000 my $count = getZoneCount($dbh, (revrec => 'n', curgroup => $curgroup) ); 1089 1001 1090 1002 $page->param(curpage => $webvar{page}); … … 1093 1005 $page->param(perpage => $perpage); 1094 1006 1095 my @domlist; 1096 my $sql = "SELECT domain_id,domain FROM domains". 1097 " WHERE group_id=?". 1098 " ORDER BY domain". 1099 ($offset eq 'all' ? '' : " LIMIT $perpage OFFSET ".$offset*$perpage); 1100 $sth = $dbh->prepare($sql); 1101 $sth->execute($curgroup); 1007 my $domlist = getZoneList($dbh, (revrec => 'n', curgroup => $curgroup) ); 1102 1008 my $rownum = 0; 1103 while (my @data = $sth->fetchrow_array) { 1104 my %row; 1105 $row{domid} = $data[0]; 1106 $row{domain} = $data[1]; 1107 $rownum++; # putting this in the expression below causes failures. *eyeroll* 1108 $row{newrow} = $rownum % 5 == 0; 1109 push @domlist, \%row; 1110 } 1111 $page->param(domtable => \@domlist); 1009 foreach my $dom (@{$domlist}) { 1010 delete $dom->{status}; 1011 delete $dom->{group}; 1012 $dom->{newrow} = (++$rownum) % 5 == 0; 1013 } 1014 1015 $page->param(domtable => $domlist); 1112 1016 # ACLs 1113 1017 $page->param(maymove => ($permissions{admin} || ($permissions{domain_edit} && $permissions{domain_create} && $permissions{domain_delete}))); … … 1123 1027 } 1124 1028 1029 # per-action scope checks 1125 1030 if ($webvar{bulkaction} eq 'move') { 1126 1031 changepage(page => "domlist", errmsg => "You are not permitted to bulk-move domains") … … 1128 1033 my $newgname = groupName($dbh,$webvar{destgroup}); 1129 1034 $page->param(action => "Move to group $newgname"); 1130 my @bulkresults;1131 # nngh. due to alpha-sorting on the previous page, we can't use domid-numeric1132 # order here, and since we don't have the domain names until we go around this1133 # loop, we can't alpha-sort them here. :(1134 foreach (keys %webvar) {1135 my %row;1136 next unless $_ =~ /^dom_\d+$/;1137 # second security check - does the user have permission to meddle with this domain?1138 if (!check_scope(id => $webvar{$_}, type => 'domain')) {1139 $row{domerr} = "You are not permitted to make changes to the requested domain";1140 $row{domain} = $webvar{$_};1141 push @bulkresults, \%row;1142 next;1143 }1144 $row{domain} = domainName($dbh,$webvar{$_});1145 my ($code, $msg) = changeGroup($dbh, 'domain', $webvar{$_}, $webvar{destgroup});1146 if ($code eq 'OK') {1147 logaction($webvar{$_}, $session->param("username"),1148 parentID($dbh, (id => $webvar{$_}, type => 'domain', revrec => $webvar{revrec})),1149 "Moved domain ".domainName($dbh, $webvar{$_})." to group $newgname");1150 $row{domok} = ($code eq 'OK');1151 } else {1152 logaction($webvar{$_}, $session->param("username"),1153 parentID($dbh, (id => $webvar{$_}, type => 'domain', revrec => $webvar{revrec})),1154 "Failed to move domain ".domainName($dbh, $webvar{$_})." to group $newgname: $msg")1155 if $config{log_failures};1156 }1157 $row{domerr} = $msg;1158 push @bulkresults, \%row;1159 }1160 $page->param(bulkresults => \@bulkresults);1161 1162 1035 } elsif ($webvar{bulkaction} eq 'deactivate' || $webvar{bulkaction} eq 'activate') { 1163 1036 changepage(page => "domlist", errmsg => "You are not permitted to bulk-$webvar{bulkaction} domains") 1164 1037 unless ($permissions{admin} || $permissions{domain_edit}); 1165 1038 $page->param(action => "$webvar{bulkaction} domains"); 1166 my @bulkresults;1167 foreach (keys %webvar) {1168 my %row;1169 next unless $_ =~ /^dom_\d+$/;1170 # second security check - does the user have permission to meddle with this domain?1171 if (!check_scope(id => $webvar{$_}, type => 'domain')) {1172 $row{domerr} = "You are not permitted to make changes to the requested domain";1173 $row{domain} = $webvar{$_};1174 push @bulkresults, \%row;1175 next;1176 }1177 $row{domain} = domainName($dbh,$webvar{$_});1178 ##fixme: error handling on status change1179 my $stat = domStatus($dbh,$webvar{$_},($webvar{bulkaction} eq 'activate' ? 'domon' : 'domoff'));1180 logaction($webvar{$_}, $session->param("username"),1181 parentID($dbh, (id => $webvar{$_}, type => 'domain', revrec => $webvar{revrec})),1182 "Changed domain ".domainName($dbh, $webvar{$_})." state to ".($stat ? 'active' : 'inactive'));1183 $row{domok} = 1;1184 # $row{domok} = ($code eq 'OK');1185 # $row{domerr} = $msg;1186 push @bulkresults, \%row;1187 }1188 $page->param(bulkresults => \@bulkresults);1189 1190 1039 } elsif ($webvar{bulkaction} eq 'delete') { 1191 1040 changepage(page => "domlist", errmsg => "You are not permitted to bulk-delete domains") 1192 1041 unless ($permissions{admin} || $permissions{domain_delete}); 1193 1042 $page->param(action => "$webvar{bulkaction} domains"); 1194 my @bulkresults; 1195 foreach (keys %webvar) { 1196 my %row; 1197 next unless $_ =~ /^dom_\d+$/; 1198 # second security check - does the user have permission to meddle with this domain? 1199 if (!check_scope(id => $webvar{$_}, type => 'domain')) { 1200 $row{domerr} = "You are not permitted to make changes to the requested domain"; 1201 $row{domain} = $webvar{$_}; 1202 push @bulkresults, \%row; 1203 next; 1204 } 1205 $row{domain} = domainName($dbh,$webvar{$_}); 1206 my $pargroup = parentID($dbh, (id => $webvar{$_}, type => 'domain', revrec => $webvar{revrec})); 1207 my $dom = domainName($dbh, $webvar{$_}); 1208 my ($code, $msg) = delDomain($dbh, $webvar{$_}); 1209 if ($code eq 'OK') { 1210 logaction($webvar{$_}, $session->param("username"), $pargroup, "Deleted domain $dom"); 1211 $row{domok} = ($code eq 'OK'); 1212 } else { 1213 logaction($webvar{$_}, $session->param("username"), $pargroup, "Failed to delete domain $dom: $msg") 1214 if $config{log_failures}; 1215 } 1043 } else { 1044 # unknown action, bypass actually doing anything. it should not be possible in 1045 # normal operations, and anyone who meddles with the URL gets what they deserve. 1046 goto DONEBULK; 1047 } # move/(de)activate/delete if() 1048 1049 my @bulkresults; 1050 # nngh. due to alpha-sorting on the previous page, we can't use domid-numeric 1051 # order here, and since we don't have the domain names until we go around this 1052 # loop, we can't alpha-sort them here. :( 1053 foreach (keys %webvar) { 1054 my %row; 1055 next unless $_ =~ /^dom_\d+$/; 1056 # second security check - does the user have permission to meddle with this domain? 1057 if (!check_scope(id => $webvar{$_}, type => 'domain')) { 1058 $row{domerr} = "You are not permitted to make changes to the requested domain"; 1059 $row{domain} = $webvar{$_}; 1060 push @bulkresults, \%row; 1061 next; 1062 } 1063 $row{domain} = domainName($dbh,$webvar{$_}); 1064 1065 # Do the $webvar{bulkaction} 1066 my ($code, $msg); 1067 ($code, $msg) = changeGroup($dbh, 'domain', $webvar{$_}, $webvar{destgroup}) 1068 if $webvar{bulkaction} eq 'move'; 1069 if ($webvar{bulkaction} eq 'deactivate' || $webvar{bulkaction} eq 'activate') { 1070 my $stat = zoneStatus($dbh,$webvar{$_},'n',($webvar{bulkaction} eq 'activate' ? 'domon' : 'domoff')); 1071 $code = (defined($stat) ? 'OK' : 'FAIL'); 1072 $msg = (defined($stat) ? $DNSDB::resultstr : $DNSDB::errstr); 1073 } 1074 ($code, $msg) = delZone($dbh, $webvar{$_}, 'n') 1075 if $webvar{bulkaction} eq 'delete'; 1076 1077 # Set the result output from the action 1078 if ($code eq 'OK') { 1079 $row{domok} = $msg; 1080 } elsif ($code eq 'WARN') { 1081 $row{domwarn} = $msg; 1082 } else { 1216 1083 $row{domerr} = $msg; 1217 push @bulkresults, \%row; 1218 } 1219 $page->param(bulkresults => \@bulkresults); 1220 1221 } # move/(de)activate/delete if() 1222 1223 # not going to handle the unknown $webvar{action} else; it should not be possible in normal 1224 # operations, and anyone who meddles with the URL gets what they deserve. 1084 } 1085 push @bulkresults, \%row; 1086 1087 } # foreach (keys %webvar) 1088 $page->param(bulkresults => \@bulkresults); 1225 1089 1226 1090 # Yes, this is a GOTO target. PTHBTTT. … … 1235 1099 $flag = 1 if isParent($dbh, $_, 'group', $webvar{id}, 'user'); 1236 1100 } 1237 if ($flag && ($permissions{admin} || $permissions{user_edit})) { 1101 if ($flag && ($permissions{admin} || $permissions{user_edit} || 1102 ($permissions{self_edit} && $webvar{id} == $session->param('uid')) )) { 1238 1103 my $stat = userStatus($dbh,$webvar{id},$webvar{userstatus}); 1239 logaction(0, $session->param("username"), parentID($dbh, (id => $webvar{id}, type => 'user')), 1240 ($stat ? 'Enabled' : 'Disabled')." ".userFullName($dbh, $webvar{id}, '%u')); 1241 $page->param(resultmsg => ($stat ? 'Enabled' : 'Disabled')." ".userFullName($dbh, $webvar{id}, '%u')); 1104 $page->param(resultmsg => $DNSDB::resultstr); 1242 1105 } else { 1243 1106 $page->param(errmsg => "You are not permitted to view or change the requested user"); … … 1255 1118 $page->param(deluser => $permissions{admin} || $permissions{user_delete}); 1256 1119 1257 if ($session->param('resultmsg')) { 1258 $page->param(resultmsg => $session->param('resultmsg')); 1259 $session->clear('resultmsg'); 1260 } 1261 if ($session->param('warnmsg')) { 1262 $page->param(warnmsg => $session->param('warnmsg')); 1263 $session->clear('warnmsg'); 1264 } 1265 if ($session->param('errmsg')) { 1266 $page->param(errmsg => $session->param('errmsg')); 1267 $session->clear('errmsg'); 1268 } 1120 show_msgs(); 1269 1121 $page->param(curpage => $webvar{page}); 1270 1122 … … 1293 1145 $page->param(add => 1) if $webvar{useraction} eq 'add'; 1294 1146 1295 my ($code,$msg); 1147 # can't re-use $code and $msg for update if we want to be able to identify separate failure states 1148 my ($code,$code2,$msg,$msg2) = ('OK','OK','OK','OK'); 1296 1149 1297 1150 my $alterperms = 0; # flag iff we need to force custom permissions due to user's current access limits … … 1340 1193 $permstring = 'i'; 1341 1194 } 1195 # "Chained" permissions. Some permissions imply others; make sure they get set. 1196 foreach (keys %permchains) { 1197 if ($newperms{$_} && !$newperms{$permchains{$_}}) { 1198 $newperms{$permchains{$_}} = 1; 1199 $permstring .= ",$permchains{$_}"; 1200 } 1201 } 1342 1202 if ($webvar{useraction} eq 'add') { 1343 1203 changepage(page => "useradmin", errmsg => "You do not have permission to add new users") … … 1347 1207 ($webvar{makeactive} eq 'on' ? 1 : 0), $webvar{accttype}, $permstring, 1348 1208 $webvar{fname}, $webvar{lname}, $webvar{phone}); 1349 logaction(0, $session->param("username"), $curgroup, "Added user $webvar{uname} (uid $msg)")1350 if $code eq 'OK';1351 1209 } else { 1352 1210 changepage(page => "useradmin", errmsg => "You do not have permission to edit users") 1353 unless $permissions{admin} || $permissions{user_edit}; 1211 unless $permissions{admin} || $permissions{user_edit} || 1212 ($permissions{self_edit} && $session->param('uid') == $webvar{uid}); 1354 1213 # security check - does the user have permission to access this entity? 1355 1214 if (!check_scope(id => $webvar{user}, type => 'user')) { 1356 1215 changepage(page => "useradmin", errmsg => "You do not have permission to edit the requested user"); 1357 1216 } 1358 # User update is icky. I'd really like to do this in one atomic 1359 # operation, but that would duplicate a **lot** of code in DNSDB.pm 1217 # User update is icky. I'd really like to do this in one atomic operation, 1218 # but that gets hairy by either duplicating a **lot** of code in DNSDB.pm 1219 # or self-torture trying to not commit the transaction until we're really done. 1360 1220 # Allowing for changing group, but not coding web support just yet. 1361 1221 ($code,$msg) = updateUser($dbh, $webvar{uid}, $webvar{uname}, $webvar{gid}, $webvar{pass1}, … … 1364 1224 if ($code eq 'OK') { 1365 1225 $newperms{admin} = 1 if $webvar{accttype} eq 'S'; 1366 ($code,$msg) = changePermissions($dbh, 'user', $webvar{uid}, \%newperms, ($permstring eq 'i')); 1367 logaction(0, $session->param("username"), $curgroup, 1368 "Updated uid $webvar{uid}, user $webvar{uname} ($webvar{fname} $webvar{lname})"); 1226 ($code2,$msg2) = changePermissions($dbh, 'user', $webvar{uid}, \%newperms, ($permstring eq 'i')); 1369 1227 } 1370 1228 } 1371 1229 } 1372 1230 1373 if ($code eq 'OK' ) {1374 1231 if ($code eq 'OK' && $code2 eq 'OK') { 1232 my %pageparams = (page => "useradmin"); 1375 1233 if ($alterperms) { 1376 changepage(page => "useradmin", warnmsg =>1377 "You can only grant permissions you hold. $webvar{uname} ".1378 ($webvar{useraction} eq 'add' ? 'added' : 'updated')." with reduced access.");1234 $pageparams{warnmsg} = "You can only grant permissions you hold.\nUser ". 1235 ($webvar{useraction} eq 'add' ? "$webvar{uname} added" : "info updated for $webvar{uname}"). 1236 ".\nPermissions ".($webvar{useraction} eq 'add' ? 'added' : 'updated')." with reduced access."; 1379 1237 } else { 1380 changepage(page => "useradmin", resultmsg => "Successfully ". 1381 ($webvar{useraction} eq 'add' ? 'added' : 'updated')." user $webvar{uname}"); 1238 $pageparams{resultmsg} = "$msg".($webvar{useraction} eq 'add' ? '' : "\n$msg2"); 1382 1239 } 1240 changepage(%pageparams); 1383 1241 1384 1242 # add/update failed: … … 1399 1257 $page->param(pass1 => $webvar{pass1}); 1400 1258 $page->param(pass2 => $webvar{pass2}); 1401 $page->param(errmsg => $msg); 1259 $page->param(errmsg => "User info updated but permissions update failed: $msg2") if $code eq 'OK'; 1260 $page->param(errmsg => $msg) if $code ne 'OK'; 1402 1261 fill_permissions($page, \%newperms); 1403 1262 fill_actypelist($webvar{accttype}); 1404 1263 fill_clonemelist(); 1405 logaction(0, $session->param("username"), $curgroup, "Failed to $webvar{useraction} user ".1406 "$webvar{uname}: $msg")1407 if $config{log_failures};1408 1264 } 1409 1265 … … 1411 1267 1412 1268 changepage(page => "useradmin", errmsg => "You do not have permission to edit users") 1413 unless $permissions{admin} || $permissions{user_edit}; 1269 unless $permissions{admin} || $permissions{user_edit} || 1270 ($permissions{self_edit} && $session->param('uid') == $webvar{user}); 1414 1271 1415 1272 # security check - does the user have permission to access this entity? … … 1426 1283 fill_actypelist($userinfo->{type}); 1427 1284 # not using this yet, but adding it now means we can *much* more easily do so later. 1428 $page->param(gid => $ webvar{group_id});1285 $page->param(gid => $userinfo->{group_id}); 1429 1286 1430 1287 my %curperms; … … 1467 1324 $page->param(user => userFullName($dbh,$webvar{id})); 1468 1325 } elsif ($webvar{del} eq 'ok') { 1469 ##fixme: find group id user is in (for logging) *before* we delete the user1470 ##fixme: get other user data too for log1471 my $userref = getUserData($dbh, $webvar{id});1472 1326 my ($code,$msg) = delUser($dbh, $webvar{id}); 1473 1327 if ($code eq 'OK') { 1474 1328 # success. go back to the user list, do not pass "GO" 1475 # actions on users have a domain id of 0, always 1476 logaction(0, $session->param("username"), $curgroup, "Deleted user $webvar{id}/".$userref->{username}. 1477 " (".$userref->{lastname}.", ".$userref->{firstname}.")"); 1478 changepage(page => "useradmin", resultmsg => "Deleted user ".$userref->{username}. 1479 " (".$userref->{lastname}.", ".$userref->{firstname}.")"); 1329 changepage(page => "useradmin", resultmsg => $msg); 1480 1330 } else { 1481 # need to find failure mode 1482 $page->param(del_failed => 1); 1483 $page->param(errmsg => $msg); 1484 list_users($curgroup); 1485 logaction(0, $session->param("username"), $curgroup, "Failed to delete user ". 1486 "$webvar{id}/".$userref->{username}.": $msg") 1487 if $config{log_failures}; 1331 changepage(page => "useradmin", errmsg => $msg); 1488 1332 } 1489 1333 } else { 1490 1334 # cancelled. whee! 1491 1335 changepage(page => "useradmin"); 1336 } 1337 1338 } elsif ($webvar{page} eq 'loclist') { 1339 1340 changepage(page => "domlist", errmsg => "You are not allowed access to this function") 1341 unless $permissions{admin} || $permissions{location_view}; 1342 1343 # security check - does the user have permission to access this entity? 1344 # if (!check_scope(id => $webvar{id}, type => 'loc')) { 1345 # changepage(page => "loclist", errmsg => "You are not permitted to <foo> the requested location/view"); 1346 # } 1347 list_locations(); 1348 show_msgs(); 1349 1350 # Permissions! 1351 $page->param(addloc => $permissions{admin} || $permissions{location_create}); 1352 $page->param(delloc => $permissions{admin} || $permissions{location_delete}); 1353 1354 } elsif ($webvar{page} eq 'location') { 1355 1356 changepage(page => "domlist", errmsg => "You are not allowed access to this function") 1357 unless $permissions{admin} || $permissions{location_view}; 1358 1359 # security check - does the user have permission to access this entity? 1360 # if (!check_scope(id => $webvar{id}, type => 'loc')) { 1361 # changepage(page => "loclist", errmsg => "You are not permitted to <foo> the requested location/view"); 1362 # } 1363 1364 if ($webvar{locact} eq 'new') { 1365 # uuhhmm.... 1366 } elsif ($webvar{locact} eq 'add') { 1367 changepage(page => "loclist", errmsg => "You are not permitted to add locations/views", id => $webvar{parentid}) 1368 unless ($permissions{admin} || $permissions{location_create}); 1369 1370 my ($code,$msg) = addLoc($dbh, $curgroup, $webvar{locname}, $webvar{comments}, $webvar{iplist}); 1371 1372 if ($code eq 'OK' || $code eq 'WARN') { 1373 my %pageparams = (page => "loclist", id => $webvar{parentid}, 1374 defrec => $webvar{defrec}, revrec => $webvar{revrec}); 1375 $pageparams{warnmsg} = $msg."<br><br>\n".$DNSDB::resultstr if $code eq 'WARN'; 1376 $pageparams{resultmsg} = $DNSDB::resultstr if $code eq 'OK'; 1377 changepage(%pageparams); 1378 } else { 1379 $page->param(failed => 1); 1380 $page->param(errmsg => $msg); 1381 $page->param(wastrying => "adding"); 1382 $page->param(todo => "Add location/view"); 1383 $page->param(locact => "add"); 1384 $page->param(id => $webvar{id}); 1385 $page->param(locname => $webvar{locname}); 1386 $page->param(comments => $webvar{comments}); 1387 $page->param(iplist => $webvar{iplist}); 1388 } 1389 1390 } elsif ($webvar{locact} eq 'edit') { 1391 changepage(page => "loclist", errmsg => "You are not permitted to edit locations/views", id => $webvar{parentid}) 1392 unless ($permissions{admin} || $permissions{location_edit}); 1393 1394 my $loc = getLoc($dbh, $webvar{loc}); 1395 $page->param(wastrying => "editing"); 1396 $page->param(todo => "Edit location/view"); 1397 $page->param(locact => "update"); 1398 $page->param(id => $webvar{loc}); 1399 $page->param(locname => $loc->{description}); 1400 $page->param(comments => $loc->{comments}); 1401 $page->param(iplist => $loc->{iplist}); 1402 1403 } elsif ($webvar{locact} eq 'update') { 1404 changepage(page => "loclist", errmsg => "You are not permitted to edit locations/views", id => $webvar{parentid}) 1405 unless ($permissions{admin} || $permissions{location_edit}); 1406 1407 my ($code,$msg) = updateLoc($dbh, $webvar{id}, $curgroup, $webvar{locname}, $webvar{comments}, $webvar{iplist}); 1408 1409 if ($code eq 'OK') { 1410 changepage(page => "loclist", resultmsg => $msg); 1411 } else { 1412 $page->param(failed => 1); 1413 $page->param(errmsg => $msg); 1414 $page->param(wastrying => "editing"); 1415 $page->param(todo => "Edit location/view"); 1416 $page->param(locact => "update"); 1417 $page->param(id => $webvar{loc}); 1418 $page->param(locname => $webvar{locname}); 1419 $page->param(comments => $webvar{comments}); 1420 $page->param(iplist => $webvar{iplist}); 1421 } 1422 } else { 1423 changepage(page => "loclist", errmsg => "You are not permitted to add locations/views", id => $webvar{parentid}) 1424 unless ($permissions{admin} || $permissions{location_create}); 1425 1426 $page->param(todo => "Add location/view"); 1427 $page->param(locact => "add"); 1428 $page->param(locname => ($webvar{locname} ? $webvar{locname} : '')); 1429 $page->param(iplist => ($webvar{iplist} ? $webvar{iplist} : '')); 1430 1431 show_msgs(); 1492 1432 } 1493 1433 … … 1571 1511 $page->param(forcettl => $webvar{forcettl}) if $webvar{forcettl}; 1572 1512 $page->param(newttl => $webvar{newttl}) if $webvar{newttl}; 1513 # This next one is arguably better on by default, but Breaking Things Is Bad, Mmmkay? 1514 $page->param(mergematching => $webvar{mergematching}) if $webvar{mergematching}; 1573 1515 $page->param(dominactive => 1) if (!$webvar{domactive} && $webvar{doit}); # eww. 1574 1516 $page->param(importdoms => $webvar{importdoms}) if $webvar{importdoms}; … … 1589 1531 } 1590 1532 1533 # Bizarre Things Happen when you AXFR a null-named zone. 1534 $webvar{importdoms} =~ s/^\s+//; 1591 1535 my @domlist = split /\s+/, $webvar{importdoms}; 1592 1536 my @results; … … 1594 1538 my %row; 1595 1539 my ($code,$msg) = importAXFR($dbh, $webvar{ifrom}, $domain, $webvar{group}, 1596 $webvar{domstatus}, $webvar{rwsoa}, $webvar{rwns}, ($webvar{forcettl} ? $webvar{newttl} : 0) ); 1540 $webvar{domstatus}, $webvar{rwsoa}, $webvar{rwns}, ($webvar{forcettl} ? $webvar{newttl} : 0), 1541 $webvar{mergematching}); 1597 1542 $row{domok} = $msg if $code eq 'OK'; 1598 1543 if ($code eq 'WARN') { … … 1605 1550 } 1606 1551 $msg = "<br />\n".$msg if $msg =~ m|<br />|; 1607 logaction(domainID($dbh, $domain), $session->param("username"), $webvar{group},1608 "AXFR import $domain from $webvar{ifrom} ($code): $msg");1609 1552 $row{domain} = $domain; 1610 1553 push @results, \%row; … … 1649 1592 } elsif ($webvar{page} eq 'log') { 1650 1593 1651 ##fixme put in some real log-munching stuff1652 my $sql = "SELECT user_id, email, name, entry, date_trunc('second',stamp) FROM log WHERE ";1653 1594 my $id = $curgroup; # we do this because the group log may be called from (almost) any page, 1654 1595 # but the others are much more limited. this is probably non-optimal. 1655 1596 1656 1597 if ($webvar{ltype} && $webvar{ltype} eq 'user') { 1657 $sql .= "user_id=?"; 1598 ##fixme: where should we call this from? 1658 1599 $id = $webvar{id}; 1659 1600 if (!check_scope(id => $id, type => 'user')) { … … 1663 1604 $page->param(logfor => 'user '.userFullName($dbh,$id)); 1664 1605 } elsif ($webvar{ltype} && $webvar{ltype} eq 'dom') { 1665 $sql .= "domain_id=?";1666 1606 $id = $webvar{id}; 1667 1607 if (!check_scope(id => $id, type => 'domain')) { … … 1671 1611 $page->param(logfor => 'domain '.domainName($dbh,$id)); 1672 1612 } elsif ($webvar{ltype} && $webvar{ltype} eq 'rdns') { 1673 $sql .= "rdns_id=?";1674 1613 $id = $webvar{id}; 1675 1614 if (!check_scope(id => $id, type => 'revzone')) { … … 1680 1619 } else { 1681 1620 # Default to listing curgroup log 1682 $sql .= "group_id=?";1683 1621 $page->param(logfor => 'group '.groupName($dbh,$id)); 1684 1622 # note that scope limitations are applied via the change-group check; 1685 1623 # group log is always for the "current" group 1686 1624 } 1625 $webvar{ltype} = 'group' if !$webvar{ltype}; 1626 my $lcount = getLogCount($dbh, (id => $id, logtype => $webvar{ltype})) or push @debugbits, $DNSDB::errstr; 1627 1628 $page->param(id => $id); 1629 $page->param(ltype => $webvar{ltype}); 1630 1631 fill_fpnla($lcount); 1632 fill_pgcount($lcount, "log entries", ''); 1633 $page->param(curpage => $webvar{page}.($webvar{ltype} ? "&ltype=$webvar{ltype}" : '')); 1634 1635 $sortby = 'stamp'; 1636 $sortorder = 'DESC'; # newest-first; although filtering is probably going to be more useful than sorting 1637 # sort/order 1638 $session->param($webvar{page}.'sortby', $webvar{sortby}) if $webvar{sortby}; 1639 $session->param($webvar{page}.'order', $webvar{order}) if $webvar{order}; 1640 1641 $sortby = $session->param($webvar{page}.'sortby') if $session->param($webvar{page}.'sortby'); 1642 $sortorder = $session->param($webvar{page}.'order') if $session->param($webvar{page}.'order'); 1643 1644 # Set up the column headings with the sort info 1645 my @cols = ('fname','username','entry','stamp'); 1646 my %colnames = (fname => 'Name', username => 'Username/Email', entry => 'Log Entry', stamp => 'Date/Time'); 1647 fill_colheads($sortby, $sortorder, \@cols, \%colnames); 1648 1649 ##fixme: increase per-page limit or use separate limit for log? some ops give *lots* of entries... 1650 my $logentries = getLogEntries($dbh, (id => $id, logtype => $webvar{ltype}, 1651 offset => $webvar{offset}, sortby => $sortby, sortorder => $sortorder)); 1652 $page->param(logentries => $logentries); 1653 1687 1654 ##fixme: 1688 1655 # - filtering 1689 1656 # - show reverse zone column? 1690 # - pagination/limiting number of records - put newest-first so user 1691 # doesn't always need to go to the last page for recent activity? 1692 my $sth = $dbh->prepare($sql); 1693 $sth->execute($id); 1694 my @logbits; 1695 while (my ($uid, $email, $name, $entry, $stamp) = $sth->fetchrow_array) { 1696 my %row; 1697 $row{userfname} = $name; 1698 $row{userid} = $uid; 1699 $row{useremail} = $email; 1700 $row{logentry} = $entry; 1701 ($row{logtime}) = ($stamp =~ /^(.+)-\d\d$/); 1702 push @logbits, \%row; 1703 } 1704 $page->param(logentries => \@logbits); 1657 # - on log record creation, bundle "parented" log actions (eg, "AXFR record blah for domain foo", 1658 # or "Add record bar for new domain baz") into one entry (eg, "AXFR domain foo", "Add domain baz")? 1659 # need a way to expand this into the complete list, and to exclude "child" entries 1705 1660 1706 1661 # scope check fail target … … 1714 1669 1715 1670 ##common bits 1671 # mostly things in the menu 1716 1672 if ($webvar{page} ne 'login' && $webvar{page} ne 'badpage') { 1717 1673 $page->param(username => $session->param("username")); … … 1724 1680 ##fixme 1725 1681 $page->param(mayrdns => 1); 1682 1683 $page->param(mayloc => ($permissions{admin} || $permissions{location_view})); 1726 1684 1727 1685 $page->param(maydefrec => $permissions{admin}); … … 1811 1769 # than set them locally everywhere. 1812 1770 foreach my $sessme ('resultmsg','warnmsg','errmsg') { 1813 if ($params{$sessme}) { 1814 $session->param($sessme, $params{$sessme}); 1771 if (my $tmp = $params{$sessme}) { 1772 $tmp =~ s/^\n//; 1773 $tmp =~ s|\n|<br />\n|g; 1774 $session->param($sessme, $tmp); 1815 1775 delete $params{$sessme}; 1816 1776 } … … 1830 1790 } # end changepage 1831 1791 1792 # wrap up the usual suspects for result, warning, or error messages to be displayed 1793 sub show_msgs { 1794 if ($session->param('resultmsg')) { 1795 $page->param(resultmsg => $session->param('resultmsg')); 1796 $session->clear('resultmsg'); 1797 } 1798 if ($session->param('warnmsg')) { 1799 $page->param(warnmsg => $session->param('warnmsg')); 1800 $session->clear('warnmsg'); 1801 } 1802 if ($session->param('errmsg')) { 1803 $page->param(errmsg => $session->param('errmsg')); 1804 $session->clear('errmsg'); 1805 } 1806 } # end show_msgs 1807 1832 1808 sub fillsoa { 1833 my $def = shift; 1809 my $defrec = shift; 1810 my $revrec = shift; 1834 1811 my $id = shift; 1835 my $domname = ($def eq 'y' ? '' : "DOMAIN"); 1836 1837 $page->param(defrec => $def); 1812 my $preserve = shift || 'd'; # Flag to use webvar fields or retrieve from database 1813 1814 my $domname = ($defrec eq 'y' ? '' : "DOMAIN"); 1815 1816 $page->param(defrec => $defrec); 1817 $page->param(revrec => $revrec); 1838 1818 1839 1819 # i had a good reason to do this when I wrote it... 1840 1820 # $page->param(domain => $domname); 1841 1821 # $page->param(group => $DNSDB::group); 1842 $page->param(isgrp => 1) if $def eq 'y'; 1843 $page->param(parent => ($def eq 'y' ? groupName($dbh, $DNSDB::group) : domainName($dbh, $id)) ); 1822 $page->param(isgrp => 1) if $defrec eq 'y'; 1823 $page->param(parent => ($defrec eq 'y' ? groupName($dbh, $id) : 1824 ($revrec eq 'n' ? domainName($dbh, $id) : revName($dbh, $id)) ) ); 1844 1825 1845 1826 # defaults … … 1852 1833 $page->param(defminttl => $DNSDB::def{minttl}); 1853 1834 1854 # there are probably better ways to do this. TMTOWTDI.1855 my %soa = getSOA($dbh,$def,$id);1856 1857 1835 $page->param(id => $id); 1858 $page->param(recid => $soa{recid}); 1859 $page->param(prins => ($soa{prins} ? $soa{prins} : $DNSDB::def{prins})); 1860 $page->param(contact => ($soa{contact} ? $soa{contact} : $DNSDB::def{contact})); 1861 $page->param(refresh => ($soa{refresh} ? $soa{refresh} : $DNSDB::def{refresh})); 1862 $page->param(retry => ($soa{retry} ? $soa{retry} : $DNSDB::def{retry})); 1863 $page->param(expire => ($soa{expire} ? $soa{expire} : $DNSDB::def{expire})); 1864 $page->param(minttl => ($soa{minttl} ? $soa{minttl} : $DNSDB::def{minttl})); 1865 $page->param(ttl => ($soa{ttl} ? $soa{ttl} : $DNSDB::def{soattl})); 1836 1837 if ($preserve eq 'd') { 1838 # there are probably better ways to do this. TMTOWTDI. 1839 my $soa = getSOA($dbh,$defrec,$revrec,$id); 1840 1841 $page->param(prins => ($soa->{prins} ? $soa->{prins} : $DNSDB::def{prins})); 1842 $page->param(contact => ($soa->{contact} ? $soa->{contact} : $DNSDB::def{contact})); 1843 $page->param(refresh => ($soa->{refresh} ? $soa->{refresh} : $DNSDB::def{refresh})); 1844 $page->param(retry => ($soa->{retry} ? $soa->{retry} : $DNSDB::def{retry})); 1845 $page->param(expire => ($soa->{expire} ? $soa->{expire} : $DNSDB::def{expire})); 1846 $page->param(minttl => ($soa->{minttl} ? $soa->{minttl} : $DNSDB::def{minttl})); 1847 $page->param(ttl => ($soa->{ttl} ? $soa->{ttl} : $DNSDB::def{soattl})); 1848 } else { 1849 $page->param(prins => ($webvar{prins} ? $webvar{prins} : $DNSDB::def{prins})); 1850 $page->param(contact => ($webvar{contact} ? $webvar{contact} : $DNSDB::def{contact})); 1851 $page->param(refresh => ($webvar{refresh} ? $webvar{refresh} : $DNSDB::def{refresh})); 1852 $page->param(retry => ($webvar{retry} ? $webvar{retry} : $DNSDB::def{retry})); 1853 $page->param(expire => ($webvar{expire} ? $webvar{expire} : $DNSDB::def{expire})); 1854 $page->param(minttl => ($webvar{minttl} ? $webvar{minttl} : $DNSDB::def{minttl})); 1855 $page->param(ttl => ($webvar{ttl} ? $webvar{ttl} : $DNSDB::def{soattl})); 1856 } 1866 1857 } 1867 1858 … … 1872 1863 1873 1864 # get the SOA first 1874 my %soa = getSOA($dbh,$def,$rev,$id);1875 1876 $page->param(contact => $soa {contact});1877 $page->param(prins => $soa {prins});1878 $page->param(refresh => $soa {refresh});1879 $page->param(retry => $soa {retry});1880 $page->param(expire => $soa {expire});1881 $page->param(minttl => $soa {minttl});1882 $page->param(ttl => $soa {ttl});1883 1884 my $foo2 = getDomRecs($dbh, $def,$rev,$id,$perpage,$webvar{offset},$sortby,$sortorder,$filter);1885 1886 my $row = 0; 1865 my $soa = getSOA($dbh,$def,$rev,$id); 1866 1867 $page->param(contact => $soa->{contact}); 1868 $page->param(prins => $soa->{prins}); 1869 $page->param(refresh => $soa->{refresh}); 1870 $page->param(retry => $soa->{retry}); 1871 $page->param(expire => $soa->{expire}); 1872 $page->param(minttl => $soa->{minttl}); 1873 $page->param(ttl => $soa->{ttl}); 1874 1875 my $foo2 = getDomRecs($dbh,(defrec => $def, revrec => $rev, id => $id, offset => $webvar{offset}, 1876 sortby => $sortby, sortorder => $sortorder, filter => $filter)); 1877 1887 1878 foreach my $rec (@$foo2) { 1888 1879 $rec->{type} = $typemap{$rec->{type}}; 1889 $rec->{row} = $row % 2;1890 $rec->{defrec} = $def;1891 $rec->{revrec} = $rev;1892 1880 $rec->{sid} = $webvar{sid}; 1893 $rec->{id} = $id;1894 1881 $rec->{fwdzone} = $rev eq 'n'; 1895 1882 $rec->{distance} = 'n/a' unless ($rec->{type} eq 'MX' || $rec->{type} eq 'SRV'); 1896 1883 $rec->{weight} = 'n/a' unless ($rec->{type} eq 'SRV'); 1897 1884 $rec->{port} = 'n/a' unless ($rec->{type} eq 'SRV'); 1898 $row++;1899 1885 # ACLs 1900 1886 $rec->{record_edit} = ($permissions{admin} || $permissions{record_edit}); 1901 1887 $rec->{record_delete} = ($permissions{admin} || $permissions{record_delete}); 1888 $rec->{locname} = '' unless ($permissions{admin} || $permissions{location_view}); 1902 1889 } 1903 1890 $page->param(reclist => $foo2); … … 1914 1901 if ($webvar{revrec} eq 'n') { 1915 1902 my $domroot = ($webvar{defrec} eq 'y' ? 'DOMAIN' : domainName($dbh,$webvar{parentid})); 1916 $page->param(name => $domroot);1903 $page->param(name => ($webvar{name} ? $webvar{name} : $domroot)); 1917 1904 $page->param(address => $webvar{address}); 1918 1905 $page->param(distance => $webvar{distance}) … … 1928 1915 } 1929 1916 # retrieve the right ttl instead of falling (way) back to the hardcoded system default 1930 my %soa = getSOA($dbh,$webvar{defrec},$webvar{revrec},$webvar{parentid});1931 $page->param(ttl => ($webvar{ttl} ? $webvar{ttl} : $soa {minttl}));1917 my $soa = getSOA($dbh,$webvar{defrec},$webvar{revrec},$webvar{parentid}); 1918 $page->param(ttl => ($webvar{ttl} ? $webvar{ttl} : $soa->{minttl})); 1932 1919 } 1933 1920 … … 1949 1936 1950 1937 sub fill_clonemelist { 1951 my $sth = $dbh->prepare("SELECT username,user_id FROM users WHERE group_id=$curgroup");1952 $sth->execute;1953 1954 1938 # shut up some warnings, but don't stomp on caller's state 1955 1939 local $webvar{clonesrc} = 0 if !defined($webvar{clonesrc}); 1956 1940 1957 my @clonesrc; 1958 while (my ($username,$uid) = $sth->fetchrow_array) { 1959 my %row = ( 1960 username => $username, 1961 uid => $uid, 1962 selected => ($webvar{clonesrc} == $uid ? 1 : 0) 1963 ); 1964 push @clonesrc, \%row; 1965 } 1966 $page->param(clonesrc => \@clonesrc); 1941 my $clones = getUserDropdown($dbh, $curgroup, $webvar{clonesrc}); 1942 $page->param(clonesrc => $clones); 1967 1943 } 1968 1944 … … 2091 2067 my $childlist = join(',',@childgroups); 2092 2068 2093 my $sql = "SELECT count(*) FROM groups WHERE parent_group_id IN ($curgroup".($childlist ? ",$childlist" : '').")". 2094 ($startwith ? " AND group_name ~* ?" : ''). 2095 ($filter ? " AND group_name ~* ?" : ''); 2096 my $sth = $dbh->prepare($sql); 2097 $sth->execute(@filterargs); 2098 my ($count) = ($sth->fetchrow_array); 2069 my ($count) = getGroupCount($dbh, (childlist => $childlist, curgroup => $curgroup, 2070 filter => ($filter ? $filter : undef), startwith => ($startwith ? $startwith : undef) ) ); 2099 2071 2100 2072 # fill page count and first-previous-next-last-all bits … … 2113 2085 2114 2086 # set up the headers 2115 my @cols = ('group','parent','nusers','ndomains' );2116 my %colnames = (group => 'Group', parent => 'Parent Group', nusers => 'Users', ndomains => 'Domains' );2087 my @cols = ('group','parent','nusers','ndomains','nrevzones'); 2088 my %colnames = (group => 'Group', parent => 'Parent Group', nusers => 'Users', ndomains => 'Domains', nrevzones => 'Reverse Zones'); 2117 2089 fill_colheads($sortby, $sortorder, \@cols, \%colnames); 2118 2090 … … 2127 2099 $sortby = 'g2.group_name' if $sortby eq 'parent'; 2128 2100 2129 my @grouplist; 2130 $sql = "SELECT g.group_id, g.group_name, g2.group_name, ". 2131 "count(distinct(u.username)) AS nusers, count(distinct(d.domain)) AS ndomains ". 2132 "FROM groups g ". 2133 "INNER JOIN groups g2 ON g2.group_id=g.parent_group_id ". 2134 "LEFT OUTER JOIN users u ON u.group_id=g.group_id ". 2135 "LEFT OUTER JOIN domains d ON d.group_id=g.group_id ". 2136 "WHERE g.parent_group_id IN ($curgroup".($childlist ? ",$childlist" : '').") ". 2137 ($startwith ? " AND g.group_name ~* ?" : ''). 2138 ($filter ? " AND g.group_name ~* ?" : ''). 2139 " GROUP BY g.group_id, g.group_name, g2.group_name ". 2140 " ORDER BY $sortby $sortorder ". 2141 ($offset eq 'all' ? '' : " LIMIT $perpage OFFSET ".$offset*$perpage); 2142 $sth = $dbh->prepare($sql); 2143 $sth->execute(@filterargs); 2144 2145 my $rownum = 0; 2146 while (my @data = $sth->fetchrow_array) { 2147 my %row; 2148 $row{groupid} = $data[0]; 2149 $row{groupname} = $data[1]; 2150 $row{pgroup} = $data[2]; 2151 $row{nusers} = $data[3]; 2152 $row{ndomains} = $data[4]; 2153 $row{bg} = ($rownum++)%2; 2154 $row{sid} = $sid; 2155 $row{edgrp} = ($permissions{admin} || $permissions{group_edit}); 2156 $row{delgrp} = ($permissions{admin} || $permissions{group_delete}); 2157 push @grouplist, \%row; 2158 } 2159 $page->param(grouptable => \@grouplist); 2101 my $glist = getGroupList($dbh, (childlist => $childlist, curgroup => $curgroup, 2102 filter => ($filter ? $filter : undef), startwith => ($startwith ? $startwith : undef), 2103 offset => $webvar{offset}, sortby => $sortby, sortorder => $sortorder) ); 2104 2105 $page->param(grouptable => $glist); 2160 2106 } # end listgroups() 2161 2107 … … 2165 2111 my $cur = shift || $curgroup; 2166 2112 2167 my @childgroups; 2168 getChildren($dbh, $logingroup, \@childgroups, 'all'); 2169 my $childlist = join(',',@childgroups); 2170 2171 ##fixme: need to reorder list so that we can display a pseudotree in group dropdowns 2172 2173 # weesa gonna discard parent_group_id for now 2174 my $sth = $dbh->prepare("SELECT group_id,parent_group_id,group_name FROM groups ". 2175 "WHERE group_id IN ($logingroup".($childlist ? ",$childlist" : '').")". 2176 "ORDER BY group_id"); 2177 $sth->execute; 2113 # little recursive utility sub-sub 2114 sub getgroupdrop { 2115 my $root = shift; 2116 my $cur = shift; # to tag the selected group 2117 my $grplist = shift; 2118 my $indent = shift || ' '; 2119 2120 my @childlist; 2121 getChildren($dbh,$root,\@childlist,'immediate'); 2122 return if $#childlist == -1; 2123 foreach (@childlist) { 2124 my %row; 2125 $row{groupval} = $_; 2126 $row{groupactive} = ($_ == $cur); 2127 $row{groupname} = $indent.groupName($dbh, $_); 2128 push @{$grplist}, \%row; 2129 getgroupdrop($_, $cur, $grplist, $indent.' '); 2130 } 2131 } 2132 2178 2133 my @grouplist; 2179 while (my ($groupid,$pargroup,$groupname) = $sth->fetchrow_array()) { 2180 my %row; 2181 $row{groupname} = $groupname; 2182 $row{groupval} = $groupid; 2183 ##fixme: need magic 2184 ## ... WTF? 2185 # $row{defgroup} = ''; 2186 $row{groupactive} = 1 if $groupid == $cur; 2187 push @grouplist, \%row; 2188 } 2134 push @grouplist, { groupval => $logingroup, groupactive => $logingroup == $curgroup, 2135 groupname => groupName($dbh, $logingroup) }; 2136 getgroupdrop($logingroup, $curgroup, \@grouplist); 2189 2137 2190 2138 $page->param("$template_var" => \@grouplist); 2191 2192 2139 } # end fill_grouplist() 2140 2141 2142 sub fill_loclist { 2143 my $cur = shift || $curgroup; 2144 my $defloc = shift || ''; 2145 2146 return unless ($permissions{admin} || $permissions{location_view}); 2147 2148 $page->param(location_view => ($permissions{admin} || $permissions{location_view})); 2149 2150 if ($permissions{admin} || $permissions{record_locchg}) { 2151 my $loclist = getLocDropdown($dbh, $cur, $defloc); 2152 $page->param(record_locchg => 1); 2153 $page->param(loclist => $loclist); 2154 } else { 2155 my $loc = getLoc($dbh, $defloc); 2156 $page->param(loc_name => $loc->{description}); 2157 } 2158 } # end fill_loclist() 2193 2159 2194 2160 … … 2199 2165 my $childlist = join(',',@childgroups); 2200 2166 2201 my $sql = "SELECT count(*) FROM users WHERE group_id IN ($curgroup".($childlist ? ",$childlist" : '').")". 2202 ($startwith ? " AND username ~* ?" : ''). 2203 ($filter ? " AND username ~* ?" : ''); 2204 my $sth = $dbh->prepare($sql); 2205 $sth->execute(@filterargs); 2206 my ($count) = ($sth->fetchrow_array); 2167 my $count = getUserCount($dbh, (childlist => $childlist, curgroup => $curgroup, 2168 filter => ($filter ? $filter : undef), startwith => ($startwith ? $startwith : undef) ) ); 2207 2169 2208 2170 # fill page count and first-previous-next-last-all bits … … 2229 2191 $page->param(searchsubs => $searchsubs) if $searchsubs; 2230 2192 2231 # munge sortby for columns in database 2232 $sortby = 'u.username' if $sortby eq 'user'; 2233 $sortby = 'u.type' if $sortby eq 'type'; 2234 $sortby = 'g.group_name' if $sortby eq 'group'; 2235 $sortby = 'u.status' if $sortby eq 'status'; 2236 2237 my @userlist; 2238 $sql = "SELECT u.user_id, u.username, u.firstname || ' ' || u.lastname AS fname, u.type, g.group_name, u.status ". 2239 "FROM users u ". 2240 "INNER JOIN groups g ON u.group_id=g.group_id ". 2241 "WHERE u.group_id IN ($curgroup".($childlist ? ",$childlist" : '').")". 2242 ($startwith ? " AND u.username ~* ?" : ''). 2243 ($filter ? " AND u.username ~* ?" : ''). 2244 " ORDER BY $sortby $sortorder ". 2245 ($offset eq 'all' ? '' : " LIMIT $perpage OFFSET ".$offset*$perpage); 2246 2247 $sth = $dbh->prepare($sql); 2248 $sth->execute(@filterargs); 2249 2250 my $rownum = 0; 2251 while (my @data = $sth->fetchrow_array) { 2252 no warnings "uninitialized"; # Just In Case something stupid happens and a user gets no first or last name 2253 my %row; 2254 $row{userid} = $data[0]; 2255 $row{username} = $data[1]; 2256 $row{userfull} = $data[2]; 2257 $row{usertype} = ($data[3] eq 'S' ? 'superuser' : "user"); 2258 $row{usergroup} = $data[4]; 2259 $row{active} = $data[5]; 2260 $row{bg} = ($rownum++)%2; 2261 $row{sid} = $sid; 2262 $row{eduser} = ($permissions{admin} || $permissions{user_edit}); 2263 $row{deluser} = ($permissions{admin} || $permissions{user_delete}); 2264 push @userlist, \%row; 2265 } 2266 $page->param(usertable => \@userlist); 2193 my $ulist = getUserList($dbh, (childlist => $childlist, curgroup => $curgroup, 2194 filter => ($filter ? $filter : undef), startwith => ($startwith ? $startwith : undef), 2195 offset => $webvar{offset}, sortby => $sortby, sortorder => $sortorder) ); 2196 # Some UI things need to be done to the list (unlike other lists) 2197 foreach my $u (@{$ulist}) { 2198 $u->{eduser} = ($permissions{admin} || 2199 ($permissions{user_edit} && $u->{type} ne 'S') || 2200 ($permissions{self_edit} && $u->{user_id} == $session->param('uid')) ); 2201 $u->{deluser} = ($permissions{admin} || ($permissions{user_delete} && $u->{type} ne 'S')); 2202 $u->{type} = ($u->{type} eq 'S' ? 'superuser' : 'user'); 2203 } 2204 $page->param(usertable => $ulist); 2267 2205 } # end list_users() 2206 2207 2208 sub list_locations { 2209 2210 my @childgroups; 2211 getChildren($dbh, $curgroup, \@childgroups, 'all') if $searchsubs; 2212 my $childlist = join(',',@childgroups); 2213 2214 my $count = getLocCount($dbh, (childlist => $childlist, curgroup => $curgroup, 2215 filter => ($filter ? $filter : undef), startwith => ($startwith ? $startwith : undef) ) ); 2216 2217 # fill page count and first-previous-next-last-all bits 2218 fill_pgcount($count,"locations/views",''); 2219 fill_fpnla($count); 2220 2221 $sortby = 'user'; 2222 # sort/order 2223 $session->param($webvar{page}.'sortby', $webvar{sortby}) if $webvar{sortby}; 2224 $session->param($webvar{page}.'order', $webvar{order}) if $webvar{order}; 2225 2226 $sortby = $session->param($webvar{page}.'sortby') if $session->param($webvar{page}.'sortby'); 2227 $sortorder = $session->param($webvar{page}.'order') if $session->param($webvar{page}.'order'); 2228 2229 # set up the headers 2230 my @cols = ('description', 'iplist', 'group'); 2231 my %colnames = (description => 'Location/View Name', iplist => 'Permitted IPs/Ranges', group => 'Group'); 2232 fill_colheads($sortby, $sortorder, \@cols, \%colnames); 2233 2234 # waffle, waffle - keep state on these as well as sortby, sortorder? 2235 $page->param("start$startwith" => 1) if $startwith && $startwith =~ /^(?:[a-z]|0-9)$/; 2236 2237 $page->param(filter => $filter) if $filter; 2238 $page->param(searchsubs => $searchsubs) if $searchsubs; 2239 2240 my $loclist = getLocList($dbh, (childlist => $childlist, curgroup => $curgroup, 2241 filter => ($filter ? $filter : undef), startwith => ($startwith ? $startwith : undef), 2242 offset => $webvar{offset}, sortby => $sortby, sortorder => $sortorder) ); 2243 # Some UI things need to be done to the list 2244 foreach my $l (@{$loclist}) { 2245 $l->{iplist} = "(All IPs)" if !$l->{iplist}; 2246 $l->{edloc} = ($permissions{admin} || $permissions{loc_edit}); 2247 $l->{delloc} = ($permissions{admin} || $permissions{loc_delete}); 2248 } 2249 $page->param(loctable => $loclist); 2250 } # end list_locations() 2268 2251 2269 2252 … … 2282 2265 foreach my $col (@$cols) { 2283 2266 my %coldata; 2284 $coldata{firstcol} = 1 if $col eq $cols->[0];2285 2267 $coldata{sid} = $sid; 2286 2268 $coldata{page} = $webvar{page}; … … 2307 2289 2308 2290 2309 sub logaction {2310 my $domid = shift;2311 my $username = shift;2312 my $groupid = shift;2313 my $entry = shift;2314 my $revid = shift || 0;2315 2316 ##fixme: push SQL into DNSDB.pm2317 ##fixme: add bits to retrieve group/domain name info to retain after entity is deleted?2318 my $sth = $dbh->prepare("SELECT user_id, firstname || ' ' || lastname FROM users WHERE username=?");2319 $sth->execute($username);2320 my ($user_id, $fullname) = $sth->fetchrow_array;2321 2322 $sth = $dbh->prepare("INSERT INTO log (domain_id,user_id,group_id,email,name,entry,rdns_id) ".2323 "VALUES (?,?,?,?,?,?,?)") or warn $dbh->errstr;2324 $sth->execute($domid,$user_id,$groupid,$username,$fullname,$entry,$revid) or warn $sth->errstr;2325 } # end logaction()2326 2327 2328 2291 # we have to do this in a variety of places; let's make it consistent 2329 2292 sub fill_permissions {
Note:
See TracChangeset
for help on using the changeset viewer.