Changeset 592


Ignore:
Timestamp:
02/13/14 17:43:02 (10 years ago)
Author:
Kris Deugau
Message:

/trunk

Review, fix, tweak, and fine-tune user permission add/update handling.

Confirm that it now correctly limits a user to granting only those
permissions they already hold, and only warns when the requested
permissions are really greater or mismatched.

Also catch a possible malicious escalation to superuser/admin status.

Confirm it *should* be impossible to generate this warning via normal
web UI actions; someone would have to manually construct a URL or POST
request with the appropriate fields.

See #30.

Location:
trunk
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/DNSDB.pm

    r586 r592  
    17351735# Returns '>', '<', '=', '!'
    17361736sub comparePermissions {
     1737  my $self = shift;
    17371738  my $p1 = shift;
    17381739  my $p2 = shift;
     
    28162817    # insert the user...  note we set inherited perms by default since
    28172818    # it's simple and cleans up some other bits of state
     2819##fixme:  need better handling of case of inherited or missing (!!) permissions entries
    28182820    my $sth = $dbh->prepare("INSERT INTO users ".
    28192821        "(group_id,username,password,firstname,lastname,phone,type,status,permission_id,inherit_perm) ".
  • trunk/dns.cgi

    r591 r592  
    12471247    } else {
    12481248
    1249       # assemble a permission string - far simpler than trying to pass an
    1250       # indeterminate set of permission flags individually
    1251 
    1252       # But first, we have to see if the user can add any particular
    1253       # permissions;  otherwise we have a priviledge escalation.  Whee.
    1254 
     1249      my $permstring = 'i';     # start with "inherit"
     1250
     1251      # Remap passed checkbox states from webvar to integer/boolean values in %newperms
     1252      foreach (@permtypes) {
     1253        $newperms{$_} = (defined($webvar{$_}) && $webvar{$_} eq 'on' ? 1 : 0);
     1254      }
     1255
     1256      # Check for chained permissions.  Some permissions imply others;  make sure they get set.
     1257      foreach (keys %permchains) {
     1258        if ($newperms{$_} && !$newperms{$permchains{$_}}) {
     1259          $newperms{$permchains{$_}} = 1;
     1260        }
     1261      }
     1262
     1263      # check for possible priviledge escalations
    12551264      if (!$permissions{admin}) {
    1256         my %grpperms;
    1257         $dnsdb->getPermissions('group', $curgroup, \%grpperms);
    1258         my $ret = comparePermissions(\%permissions, \%grpperms);
    1259         if ($ret eq '<' || $ret eq '!') {
    1260           # User's permissions are not a superset or equivalent to group.  Can't inherit
    1261           # (and include access user doesn't currently have), so we force custom.
     1265        if ($webvar{perms_type} eq 'inherit') {
     1266          # Group permissions are only relevant if inheriting
     1267          my %grpperms;
     1268          $dnsdb->getPermissions('group', $curgroup, \%grpperms);
     1269          my $ret = $dnsdb->comparePermissions(\%permissions, \%grpperms);
     1270          if ($ret eq '<' || $ret eq '!') {
     1271            # User's permissions are not a superset or equivalent to group.  Can't inherit
     1272            # (and include access user doesn't currently have), so we force custom.
     1273            $webvar{perms_type} = 'custom';
     1274            $alterperms = 1;
     1275          }
     1276        }
     1277        my $ret = $dnsdb->comparePermissions(\%newperms, \%permissions);
     1278        if ($ret eq '>' || $ret eq '!') {
     1279          # User's new permissions are not a subset or equivalent to previous.  Can't add
     1280          # permissions user doesn't currently have, so we force custom.
    12621281          $webvar{perms_type} = 'custom';
    12631282          $alterperms = 1;
     
    12651284      }
    12661285
    1267       my $permstring;
     1286##fixme:
     1287# could possibly factor building the meat of the permstring out of this if/elsif set, so
     1288# as to avoid running around @permtypes quite so many times
    12681289      if ($webvar{perms_type} eq 'custom') {
    12691290        $permstring = 'C:';
     
    12711292          if ($permissions{admin} || $permissions{$_}) {
    12721293            $permstring .= ",$_" if defined($webvar{$_}) && $webvar{$_} eq 'on';
    1273             $newperms{$_} = (defined($webvar{$_}) && $webvar{$_} eq 'on' ? 1 : 0);
     1294          } else {
     1295            $newperms{$_} = 0;  # remove permissions user doesn't currently have
    12741296          }
    12751297        }
     
    12791301        $dnsdb->getPermissions('user', $webvar{clonesrc}, \%newperms);
    12801302        $page->param(perm_clone => 1);
    1281       } else {
    1282         $permstring = 'i';
    1283       }
    1284       # "Chained" permissions.  Some permissions imply others;  make sure they get set.
     1303      }
     1304      # Recheck chained permissions, in the supposedly impossible case that the removals
     1305      # above mangled one of them.  This *should* be impossible via normal web UI operations.
    12851306      foreach (keys %permchains) {
    12861307        if ($newperms{$_} && !$newperms{$permchains{$_}}) {
     
    13121333                $webvar{fname}, $webvar{lname}, $webvar{phone});
    13131334        if ($code eq 'OK') {
    1314           $newperms{admin} = 1 if $webvar{accttype} eq 'S';
     1335          $newperms{admin} = 1 if $permissions{admin} && $webvar{accttype} eq 'S';
    13151336          ($code2,$msg2) = $dnsdb->changePermissions('user', $webvar{uid}, \%newperms, ($permstring eq 'i'));
    13161337        }
Note: See TracChangeset for help on using the changeset viewer.