Index: trunk/DNSDB.pm
===================================================================
--- trunk/DNSDB.pm	(revision 65)
+++ trunk/DNSDB.pm	(revision 66)
@@ -25,5 +25,5 @@
 @ISA		= qw(Exporter);
 @EXPORT_OK	= qw(
-	&initGlobals &initPermissions &getPermissions
+	&initGlobals &initPermissions &getPermissions &changePermissions
 	&connectDB &finish
 	&addDomain &delDomain &domainName
@@ -34,10 +34,10 @@
 	&domStatus &importAXFR
 	%typemap %reverse_typemap
-	%permissions
+	%permissions @permtypes $permlist
 	);
 
 @EXPORT		= (); # Export nothing by default.
 %EXPORT_TAGS	= ( ALL => [qw(
-		&initGlobals &initPermissions &getPermissions
+		&initGlobals &initPermissions &getPermissions &changePermissions
 		&connectDB &finish
 		&addDomain &delDomain &domainName
@@ -48,5 +48,5 @@
 		&domStatus &importAXFR
 		%typemap %reverse_typemap
-		%permissions
+		%permissions @permtypes $permlist
 		)]
 	);
@@ -66,4 +66,14 @@
 	ttl	10800
 );
+
+# Arguably defined wholly in the db, but little reason to change without supporting code changes
+our @permtypes = qw (
+	group_edit	group_create	group_delete
+	user_edit	user_create	user_delete
+	domain_edit	domain_create	domain_delete
+	record_edit	record_create	record_delete
+	self_edit	admin
+);
+our $permlist = join(',',@permtypes);
 
 # DNS record type map and reverse map.
@@ -235,10 +245,49 @@
   my $newperms = shift;
 
+my $failmsg = '';
+
   # see if we're switching from inherited to custom
-  my $sth = $dbh->prepare("SELECT (u.permission_id=g.permission_id) AS was_inherited".
+  my $sth = $dbh->prepare("SELECT (u.permission_id=g.permission_id) AS was_inherited,u.permission_id".
 	" FROM ".($type eq 'user' ? 'users' : 'groups')." u ".
-	" JOIN groups g ON u.group_id=g.group_id ".
+	" JOIN groups g ON u.".($type eq 'user' ? '' : 'parent_')."group_id=g.group_id ".
 	" WHERE u.".($type eq 'user' ? 'user' : 'group')."_id=?");
   $sth->execute($id);
+
+  my ($wasinherited,$permid) = $sth->fetchrow_array;
+
+  local $dbh->{AutoCommit} = 0;
+  local $dbh->{RaiseError} = 1;
+
+  # Wrap all the SQL in a transaction
+  eval {
+    if ($wasinherited) {
+$failmsg = "wasinherited: '$wasinherited'";
+die "don't wanna add perms where we don't need to";
+##fixme: need to add semirecursive bit to properly munge inherited permission ID on subgroups and users
+## FIXME:  need to fiddle permissions table to track back to users or groups table
+      my $sql = "INSERT INTO permissions ($permlist) ".
+	"SELECT $permlist FROM permissions WHERE permission_id=?";
+      $sth = $dbh->prepare($sql);
+      $sth->execute($permid);
+      $sth = $dbh->prepare("SELECT permission_id FROM ".($type eq 'user' ? 'users' : 'groups').
+	" WHERE ".($type eq 'user' ? 'user' : 'group')."_id=?");
+      $sth->execute($id);
+      ($permid) = $sth->fetchrow_array;
+    }
+    foreach (@permtypes) {
+      if (defined ($newperms->{$_})) {
+	$sth = $dbh->prepare("UPDATE permissions SET $_=? WHERE permission_id=?");
+	$sth->execute($newperms->{$_},$permid);
+      }
+    }
+    $dbh->commit;
+  }; # end eval
+  if ($@) {
+    my $msg = $@;
+    eval { $dbh->rollback; };
+    return ('FAIL',"$failmsg: $msg");
+  } else {
+    return ('OK',$permid);
+  }
 
 } # end changePermissions()
@@ -379,5 +428,6 @@
 ## DNSDB::addGroup()
 # Add a group
-# Takes a database handle, group name, parent group, and template-vs-cloneme flag
+# Takes a database handle, group name, parent group, hashref for permissions,
+# and optional template-vs-cloneme flag
 # Returns a status code and message
 sub addGroup {
@@ -386,8 +436,10 @@
   my $groupname = shift;
   my $pargroup = shift;
-
-  # 0 indicates "template", hardcoded.
+  my $permissions = shift;
+
+  # 0 indicates "custom", hardcoded.
   # Any other value clones that group's default records, if it exists.
-  my $torc = shift || 0;	
+  my $inherit = shift || 0;	
+##fixme:  need a flag to indicate clone records or <?> ?
 
   # Allow transactions, and raise an exception on errors so we can catch it later.
@@ -414,7 +466,31 @@
     my ($groupid) = $sth->fetchrow_array();
 
+# Permissions
+    if ($inherit) {
+    } else {
+      my @permvals;
+      foreach (@permtypes) {
+	if (!defined ($permissions->{$_})) {
+	  push @permvals, 0;
+	} else {
+	  push @permvals, $permissions->{$_};
+	}
+      }
+
+      $sth = $dbh->prepare("INSERT INTO permissions (group_id,$permlist) values (?".',?'x($#permtypes+1).")");
+      $sth->execute($groupid,@permvals);
+
+      $sth = $dbh->prepare("SELECT permission_id FROM permissions WHERE group_id=?");
+      $sth->execute($groupid);
+      my ($permid) = $sth->fetchrow_array();
+
+      $dbh->do("UPDATE groups SET permission_id=$permid WHERE group_id=$groupid");
+    } # done permission fiddling
+
+# Default records
     $sth = $dbh->prepare("INSERT INTO default_records (group_id,host,type,val,distance,weight,port,ttl) ".
 	"VALUES ($groupid,?,?,?,?,?,?,?)");
-    if ($torc) {
+    if ($inherit) {
+##fixme:  fixme!
       my $sth2 = $dbh->prepare("SELECT host,type,val,distance,weight,port,ttl FROM default_records WHERE group_id=?");
       while (my @clonedata = $sth2->fetchrow_array) {
@@ -422,4 +498,5 @@
       }
     } else {
+##fixme: Hardcoding is Bad, mmmmkaaaay?
       # reasonable basic defaults for SOA, MX, NS, and minimal hosting
       # could load from a config file, but somewhere along the line we need hardcoded bits.
