Index: /branches/eam_branches/ipp-20150419/dbconfig/pstamp.md
===================================================================
--- /branches/eam_branches/ipp-20150419/dbconfig/pstamp.md	(revision 38450)
+++ /branches/eam_branches/ipp-20150419/dbconfig/pstamp.md	(revision 38451)
@@ -69,11 +69,34 @@
 END
 
-pstampWebRequest METADATA
+pstampWebRequest        METADATA
     num         S64         0    # Primary Key AUTO_INCREMENT
 END
 
-pstampFile METADATA
+pstampFile              METADATA
     file_id     S64         0   # Primary Key AUTO_INCREMENT
     job_id      S64         0
     path        STR         255
-end
+END
+
+pstampUserDomain        METADATA
+    domainName      STR     64
+    accessLevel     S32     0
+    defaultProduct  STR     255
+    defaultLabel    STR     64
+END
+
+pstampUser              METADATA
+    userName        STR     64  # Primary Key (userName, domainName)
+    domainName      STR     64  
+    accessLevel     S32     0
+    defaultProduct  STR     255
+    defaultLabel    STR     64
+END
+
+pstampAccessLevel       METADATA
+    proj_id         S64     0   # Primary Key (proj_id, accessLevel) fkey(proj_id) 
+    accessLevel     S32     0
+    mjd_min         F32     0
+    mjd_max         F32     0
+END
+
Index: /branches/eam_branches/ipp-20150419/ippScripts/scripts/lap_queue_diff.pl
===================================================================
--- /branches/eam_branches/ipp-20150419/ippScripts/scripts/lap_queue_diff.pl	(revision 38450)
+++ /branches/eam_branches/ipp-20150419/ippScripts/scripts/lap_queue_diff.pl	(revision 38451)
@@ -25,5 +25,5 @@
 my ( $help, $verbose, $debug, $do_nothing);
 my ( $camera, $dbname);
-my ( $lap_id );
+my ( $lap_id, $data_group );
 my ( $queue_list );
 
@@ -38,12 +38,16 @@
     
     'lap_id=s'     => \$lap_id,
+    'data_group=s' => \$data_group,
     'queue_list=s' => \$queue_list,
     ) or pod2usage ( 2 );
 pod2usage( -msg => "Unknown option: @ARGV", -exitval => 2 ) if @ARGV;
 pod2usage(
-    -msg => "--lap_id is required",
+    -msg => "--lap_id --data_group --queue_list are required",
     -exitval => 3,
     ) unless
-    defined $lap_id;
+    defined $lap_id and
+    defined $queue_list and
+    defined $data_group
+;
 
 unless (defined $dbname) {
@@ -91,5 +95,5 @@
 	    if ($can_diff == 1) {
 		# This needs a check to ensure it hasn't been done yet.
-		my $diff_id = &launch_diff($warp_id);
+		my $diff_id = &launch_diff($warp_id,$label,$data_group);
 		print "Made diff for $warp_id => $diff_id\n";
 		$Ndiff++;
@@ -255,15 +259,18 @@
     my $warp_id = shift;
     my $label = shift;
+    my $data_group = shift;
+    my $command = "$difftool -definewarpstack -available -bothways -good_frac 0.2 ";
+    $command   .= " -warp_label $label -stack_label $label -set_label $label ";
+    $command   .= " -set_data_group $data_group ";
+    $command   .= " -set_workdir neb://\@HOST\@.0/gpc1/${label}/${data_group}/ ";
+    $command   .= " -set_reduction WARPSTACK_PV3 ";
+    $command   .= " -warp_id ${warp_id} ";
+    $command .= " -dbname $dbname " if defined $dbname;
+    
     if (($debug)||($do_nothing)) {
+	print "DEBUG! WOULD RUN: >> $command\n";
 	return(99);
     }
     else {
-	my $command = "$difftool -definewarpstack -available -bothways -good_frac 0.2 ";
-	$command   .= " -warp_label $label -stack_label $label -set_label $label ";
-	$command   .= " -set_data_group ${label}.";
-	$command   .= " -set_workdir neb://@HOST@.0/gpc1/LAP.PV3.20140730/diff01.20150311/ ";
-	$command   .= " -set_reduction WARPSTACK_PV3 ";
-	$command   .= " -warp_id ${warp_id} ";
-	$command .= " -dbname $dbname " if defined $dbname;
 	my ($success, $error_code, $full_buf, $stdout_buf, $stderr_buf ) =
 	    run(command => $command, verbose => $verbose);
Index: /branches/eam_branches/ipp-20150419/ippTools/share/Makefile.am
===================================================================
--- /branches/eam_branches/ipp-20150419/ippTools/share/Makefile.am	(revision 38450)
+++ /branches/eam_branches/ipp-20150419/ippTools/share/Makefile.am	(revision 38451)
@@ -359,4 +359,5 @@
 	pstamptool_stopdependentjob.sql \
 	pstamptool_updatejob.sql \
+	pstamptool_addaccesslevel.sql \
 	pxadmin_create_tables.sql \
 	pxadmin_create_mirror_tables.sql \
Index: /branches/eam_branches/ipp-20150419/ippTools/share/pstamptool_addaccesslevel.sql
===================================================================
--- /branches/eam_branches/ipp-20150419/ippTools/share/pstamptool_addaccesslevel.sql	(revision 38451)
+++ /branches/eam_branches/ipp-20150419/ippTools/share/pstamptool_addaccesslevel.sql	(revision 38451)
@@ -0,0 +1,4 @@
+INSERT 
+    INTO pstampAccessLevel 
+        SELECT proj_id, %d, %f, %f FROM pstampProject
+        WHERE name = '%s'
Index: /branches/eam_branches/ipp-20150419/ippTools/share/pxadmin_create_tables.sql
===================================================================
--- /branches/eam_branches/ipp-20150419/ippTools/share/pxadmin_create_tables.sql	(revision 38450)
+++ /branches/eam_branches/ipp-20150419/ippTools/share/pxadmin_create_tables.sql	(revision 38451)
@@ -1511,4 +1511,31 @@
 ) ENGINE=innodb DEFAULT CHARSET=latin1;
 
+CREATE TABLE pstampUserDomain (
+    domainName      VARCHAR(64),
+    accessLevel     INT,
+    defaultProduct  VARCHAR(255),
+    defaultLabel    VARCHAR(64),
+    PRIMARY KEY(domainName)
+) ENGINE=innodb DEFAULT CHARSET=latin1;
+
+CREATE TABLE pstampUser (
+    userName        VARCHAR(64),
+    domainName      VARCHAR(64),
+    accessLevel     INT,
+    defaultProduct  VARCHAR(255),
+    defaultLabel    VARCHAR(64),
+    PRIMARY KEY (userName, domainName)
+) ENGINE=innodb DEFAULT CHARSET=latin1;
+
+CREATE TABLE pstampAccessLevel (
+    proj_id         BIGINT,
+    accessLevel     INT,
+    mjd_min         FLOAT DEFAULT 0,
+    mjd_max         FLOAT DEFAULT 0,
+    PRIMARY KEY (proj_id, accessLevel),
+    UNIQUE KEY (proj_id, accessLevel),
+    FOREIGN KEY(proj_id) REFERENCES pstampProject(proj_id)
+) ENGINE=innodb DEFAULT CHARSET=latin1;
+
 CREATE TABLE pstampWebRequest (
         num BIGINT AUTO_INCREMENT,
Index: /branches/eam_branches/ipp-20150419/ippTools/share/pxadmin_drop_tables.sql
===================================================================
--- /branches/eam_branches/ipp-20150419/ippTools/share/pxadmin_drop_tables.sql	(revision 38450)
+++ /branches/eam_branches/ipp-20150419/ippTools/share/pxadmin_drop_tables.sql	(revision 38451)
@@ -69,5 +69,11 @@
 DROP TABLE IF EXISTS pstampProject;
 DROP TABLE IF EXISTS pstampRequest;
+DROP TABLE IF EXISTS pstampDependent;
+DROP TABLE IF EXISTS pstampWebRequest;
+DROP TABLE IF EXISTS pstampFile;
 DROP TABLE IF EXISTS pstampJob;
+DROP TABLE IF EXISTS pstampUserDomain;
+DROP TABLE IF EXISTS pstampUser;
+DROP TABLE IF EXISTS pstampAccessLevel;
 DROP TABLE IF EXISTS distRun;
 DROP TABLE IF EXISTS distTarget;
@@ -85,11 +91,8 @@
 DROP TABLE IF EXISTS publishRun;
 DROP TABLE IF EXISTS publishDone;
-DROP TABLE IF EXISTS pstampDependent;
-DROP TABLE IF EXISTS pstampFile;
 DROP TABLE IF EXISTS staticskyInput;
 DROP TABLE IF EXISTS staticskyResult;
 DROP TABLE IF EXISTS staticskyRun;
 DROP TABLE IF EXISTS Label;
-DROP TABLE IF EXISTS pstampWebRequest;
 DROP TABLE IF EXISTS chipBackgroundRun;
 DROP TABLE IF EXISTS chipBackgroundImfile;
Index: /branches/eam_branches/ipp-20150419/ippTools/src/pstamptool.c
===================================================================
--- /branches/eam_branches/ipp-20150419/ippTools/src/pstamptool.c	(revision 38450)
+++ /branches/eam_branches/ipp-20150419/ippTools/src/pstamptool.c	(revision 38451)
@@ -61,6 +61,13 @@
 static bool deletefileMode(pxConfig *config);
 
+static bool adddomainMode(pxConfig * config);
+static bool updatedomainMode(pxConfig * config);
 static bool listdomainMode(pxConfig *config);
+static bool adduserMode(pxConfig * config);
+static bool updateuserMode(pxConfig * config);
 static bool listuserMode(pxConfig * config);
+static bool addaccesslevelMode(pxConfig * config);
+static bool updateaccesslevelMode(pxConfig * config);
+static bool listaccesslevelMode(pxConfig * config);
 
 # define MODECASE(caseName, func) \
@@ -114,6 +121,13 @@
         MODECASE(PSTAMPTOOL_MODE_DELETEFILE, deletefileMode);
 
+        MODECASE(PSTAMPTOOL_MODE_ADDDOMAIN, adddomainMode);
+        MODECASE(PSTAMPTOOL_MODE_UPDATEDOMAIN, updatedomainMode);
         MODECASE(PSTAMPTOOL_MODE_LISTDOMAIN, listdomainMode);
+        MODECASE(PSTAMPTOOL_MODE_ADDUSER, adduserMode);
+        MODECASE(PSTAMPTOOL_MODE_UPDATEUSER, updateuserMode);
         MODECASE(PSTAMPTOOL_MODE_LISTUSER, listuserMode);
+        MODECASE(PSTAMPTOOL_MODE_ADDACCESSLEVEL, addaccesslevelMode);
+        MODECASE(PSTAMPTOOL_MODE_UPDATEACCESSLEVEL, updateaccesslevelMode);
+        MODECASE(PSTAMPTOOL_MODE_LISTACCESSLEVEL, listaccesslevelMode);
 
         default:
@@ -1709,4 +1723,80 @@
 }
 
+static bool adddomainMode(pxConfig *config)
+{
+    PS_ASSERT_PTR_NON_NULL(config, false);
+
+    PXOPT_LOOKUP_STR(domainName,      config->args, "-set_domain",  true, false);
+    PXOPT_LOOKUP_S32(accessLevel,     config->args, "-set_accessLevel", true, false);
+    PXOPT_LOOKUP_STR(defaultProduct,  config->args, "-set_defaultProduct",  false, false);
+    PXOPT_LOOKUP_STR(defaultLabel,    config->args, "-set_defaultLabel",  false, false);
+
+    if (!pstampUserDomainInsert(config->dbh,
+        domainName,
+        accessLevel,
+        defaultProduct,
+        defaultLabel
+        )) {
+        psError(PS_ERR_UNKNOWN, false, "failed to insert domain");
+        return false;
+    }
+
+    return true;
+}
+static bool updatedomainMode(pxConfig *config)
+{
+    PS_ASSERT_PTR_NON_NULL(config, false);
+
+    PXOPT_LOOKUP_STR(domainName,      config->args, "-domain",  true, false);
+    PXOPT_LOOKUP_S32(accessLevel,     config->args, "-set_accessLevel", false, false);
+    PXOPT_LOOKUP_STR(defaultProduct,  config->args, "-set_defaultProduct",  false, false);
+    PXOPT_LOOKUP_STR(defaultLabel,    config->args, "-set_defaultLabel",  false, false);
+
+    if (!accessLevel && !defaultProduct && !defaultLabel) {
+        psError(PS_ERR_UNKNOWN, true, "at least one set option is required");
+        return false;
+    }
+
+    psMetadata *where = psMetadataAlloc();
+    PXOPT_COPY_STR(config->args, where, "-domain",   "domainName", "==");
+    if (!psListLength(where->list)) {
+        psFree(where);
+        psError(PXTOOLS_ERR_CONFIG, false, "search parameters are required");
+        return false;
+    }
+
+    psString query = psStringCopy("UPDATE pstampUserDomain SET");
+
+    char * sep = "";
+    if (accessLevel) {
+        psStringAppend(&query, "%s accessLevel = '%d'", sep, accessLevel);
+        sep = ", ";
+    }
+    if (defaultProduct) {
+        psStringAppend(&query, "%s  defaultProduct = '%s'", sep, defaultProduct);
+        sep = ", ";
+    }
+    if (defaultLabel) {
+        psStringAppend(&query, "%s defaultLabel = '%s'", sep, defaultLabel);
+        sep = ", ";
+    }
+
+    psString whereClause = psDBGenerateWhereConditionSQL(where, NULL);
+    psStringAppend(&query, "\nWHERE %s", whereClause);
+    psFree(whereClause);
+    psFree(where);
+
+    if (!p_psDBRunQuery(config->dbh, query)) {
+        psError(PS_ERR_UNKNOWN, false, "database error");
+        psFree(query);
+        return false;
+    }
+
+    // psU64 affected = psDBAffectedRows(config->dbh);
+    // psLogMsg("pstamptool", PS_LOG_INFO, "Updated %" PRIu64 " pstampRequests", affected);
+
+    return true;
+}
+
 static bool listdomainMode(pxConfig *config)
 {
@@ -1715,5 +1805,5 @@
     psMetadata *where = psMetadataAlloc();
     PXOPT_COPY_STR(config->args, where, "-domain", "domainName", "=");
-    PXOPT_COPY_S32(config->args, where, "-access_level", "accessLevel", "=");
+    PXOPT_COPY_S32(config->args, where, "-accessLevel", "accessLevel", "=");
 
     PXOPT_LOOKUP_BOOL(simple, config->args, "-simple", false);
@@ -1764,4 +1854,83 @@
     return true;
 }
+static bool adduserMode(pxConfig *config)
+{
+    PS_ASSERT_PTR_NON_NULL(config, false);
+
+    PXOPT_LOOKUP_STR(userName,        config->args, "-set_user",  true, false);
+    PXOPT_LOOKUP_STR(domainName,      config->args, "-set_domain",  true, false);
+    PXOPT_LOOKUP_S32(accessLevel,     config->args, "-set_accessLevel", false, false);
+    PXOPT_LOOKUP_STR(defaultProduct,  config->args, "-set_defaultProduct",  false, false);
+    PXOPT_LOOKUP_STR(defaultLabel,    config->args, "-set_defaultLabel",  false, false);
+
+    if (!pstampUserInsert(config->dbh,
+        userName,
+        domainName,
+        accessLevel,
+        defaultProduct,
+        defaultLabel
+        )) {
+        psError(PS_ERR_UNKNOWN, false, "failed to insert user");
+        return false;
+    }
+
+    return true;
+}
+static bool updateuserMode(pxConfig *config)
+{
+    PS_ASSERT_PTR_NON_NULL(config, false);
+
+    PXOPT_LOOKUP_STR(userName,        config->args, "-user",  true, false);
+    PXOPT_LOOKUP_STR(domainName,      config->args, "-domain",  true, false);
+    PXOPT_LOOKUP_S32(accessLevel,     config->args, "-set_accessLevel", false, false);
+    PXOPT_LOOKUP_STR(defaultProduct,  config->args, "-set_defaultProduct",  false, false);
+    PXOPT_LOOKUP_STR(defaultLabel,    config->args, "-set_defaultLabel",  false, false);
+
+    if (!accessLevel && !defaultProduct && !defaultLabel) {
+        psError(PS_ERR_UNKNOWN, true, "at least one set option is required");
+        return false;
+    }
+
+    psMetadata *where = psMetadataAlloc();
+    PXOPT_COPY_STR(config->args, where, "-user",     "userName", "==");
+    PXOPT_COPY_STR(config->args, where, "-domain",   "domainName", "==");
+    if (!psListLength(where->list)) {
+        psFree(where);
+        psError(PXTOOLS_ERR_CONFIG, false, "search parameters are required");
+        return false;
+    }
+
+    psString query = psStringCopy("UPDATE pstampUser SET");
+
+    char * sep = "";
+    if (accessLevel) {
+        psStringAppend(&query, "%s accessLevel = '%d'", sep, accessLevel);
+        sep = ", ";
+    }
+    if (defaultProduct) {
+        psStringAppend(&query, "%s  defaultProduct = '%s'", sep, defaultProduct);
+        sep = ", ";
+    }
+    if (defaultLabel) {
+        psStringAppend(&query, "%s defaultLabel = '%s'", sep, defaultLabel);
+        sep = ", ";
+    }
+
+    psString whereClause = psDBGenerateWhereConditionSQL(where, NULL);
+    psStringAppend(&query, "\nWHERE %s", whereClause);
+    psFree(whereClause);
+    psFree(where);
+
+    if (!p_psDBRunQuery(config->dbh, query)) {
+        psError(PS_ERR_UNKNOWN, false, "database error");
+        psFree(query);
+        return false;
+    }
+
+    // psU64 affected = psDBAffectedRows(config->dbh);
+    // psLogMsg("pstamptool", PS_LOG_INFO, "Updated %" PRIu64 " pstampRequests", affected);
+
+    return true;
+}
 static bool listuserMode(pxConfig *config)
 {
@@ -1771,5 +1940,5 @@
     PXOPT_COPY_STR(config->args, where, "-user", "userName", "=");
     PXOPT_COPY_STR(config->args, where, "-domain", "domainName", "=");
-    PXOPT_COPY_S32(config->args, where, "-access_level", "pstampUser.accessLevel", "=");
+    PXOPT_COPY_S32(config->args, where, "-accessLevel", "pstampUser.accessLevel", "=");
     PXOPT_LOOKUP_BOOL(simple, config->args, "-simple", false);
     PXOPT_LOOKUP_U64(limit, config->args, "-limit", false, false);
@@ -1822,3 +1991,100 @@
     return true;
 }
+
+static bool addaccesslevelMode(pxConfig *config)
+{
+    PS_ASSERT_PTR_NON_NULL(config, false);
+
+    PXOPT_LOOKUP_S64(proj_id,         config->args, "-set_proj_id", false, false);
+    PXOPT_LOOKUP_STR(project_name,    config->args, "-set_project_name",  false, false);
+    PXOPT_LOOKUP_S32(accessLevel,     config->args, "-set_accessLevel", true, false);
+    PXOPT_LOOKUP_F32(mjd_min,         config->args, "-set_mjd_min", false, false);
+    PXOPT_LOOKUP_F32(mjd_max,         config->args, "-set_mjd_max", false, false);
+
+    if (proj_id) {
+        if (!pstampAccessLevelInsert(config->dbh,
+            proj_id,
+            accessLevel,
+            mjd_min,
+            mjd_max
+        )) {
+            psError(PS_ERR_UNKNOWN, false, "failed to insert accessLevel");
+            return false;
+        }
+    } else if (project_name) {
+        // use select insert getting proj_id from pstampProject
+        psString query = pxDataGet("pstamptool_addaccesslevel.sql");
+        if (!p_psDBRunQueryF(config->dbh, query, accessLevel, mjd_min, mjd_max, project_name)) {
+            psError(PS_ERR_UNKNOWN, false, "database error");
+            psFree(query);
+            return false;
+        }
+        psFree(query);
+    } else {
+        psError(PS_ERR_UNKNOWN, true, "proj_id or project_name is required");
+        return false;
+    }
+
+    return true;
+}
+static bool updateaccesslevelMode(pxConfig *config)
+{
+    return false;
+}
+static bool listaccesslevelMode(pxConfig *config)
+{
+    PS_ASSERT_PTR_NON_NULL(config, false);
+
+    psMetadata *where = psMetadataAlloc();
+    PXOPT_COPY_STR(config->args, where, "-project_name", "pstampProject.name", "=");
+    PXOPT_COPY_S64(config->args, where, "-proj_id", "proj_id", "=");
+    PXOPT_COPY_S32(config->args, where, "-accessLevel", "accessLevel", "=");
+
+    PXOPT_LOOKUP_BOOL(simple, config->args, "-simple", false);
+    PXOPT_LOOKUP_U64(limit, config->args, "-limit", false, false);
+
+    psString query = psStringCopy("SELECT * from pstampAccessLevel join pstampProject USING(proj_id)");
+
+    if (psListLength(where->list)) {
+        psString whereClause = psDBGenerateWhereConditionSQL(where, NULL);
+        psStringAppend(&query, " WHERE %s", whereClause);
+        psFree(whereClause);
+    }
+    psFree(where);
+
+    // treat limit == 0 as "no limit"
+    if (limit) {
+        psString limitString = psDBGenerateLimitSQL(limit);
+        psStringAppend(&query, " %s", limitString);
+        psFree(limitString);
+    }
+
+    if (!p_psDBRunQuery(config->dbh, query)) {
+        psError(PS_ERR_UNKNOWN, false, "database error");
+        psFree(query);
+        return false;
+    }
+    psFree(query);
+
+    psArray *output = p_psDBFetchResult(config->dbh);
+    if (!output) {
+        psError(PS_ERR_UNKNOWN, false, "database error");
+        return false;
+    }
+    if (!psArrayLength(output)) {
+        psFree(output);
+        return true;
+    }
+
+    // negative simple so the default is true
+    if (!ippdbPrintMetadatas(stdout, output, "pstampAccessLevel", !simple)) {
+        psError(PS_ERR_UNKNOWN, false, "failed to print array");
+        psFree(output);
+        return false;
+    }
+
+    psFree(output);
+
+    return true;
+}
 # endif
Index: /branches/eam_branches/ipp-20150419/ippTools/src/pstamptool.h
===================================================================
--- /branches/eam_branches/ipp-20150419/ippTools/src/pstamptool.h	(revision 38450)
+++ /branches/eam_branches/ipp-20150419/ippTools/src/pstamptool.h	(revision 38451)
@@ -65,5 +65,5 @@
     PSTAMPTOOL_MODE_ADDACCESSLEVEL,
     PSTAMPTOOL_MODE_UPDATEACCESSLEVEL,
-    PSTAMPTOOL_MODE_LISTACCCESSLEVEL,
+    PSTAMPTOOL_MODE_LISTACCESSLEVEL,
 } pstamptoolMode;
 
Index: /branches/eam_branches/ipp-20150419/ippTools/src/pstamptoolConfig.c
===================================================================
--- /branches/eam_branches/ipp-20150419/ippTools/src/pstamptoolConfig.c	(revision 38450)
+++ /branches/eam_branches/ipp-20150419/ippTools/src/pstamptoolConfig.c	(revision 38451)
@@ -277,5 +277,5 @@
     // -project
     psMetadata *projectArgs = psMetadataAlloc();
-    psMetadataAddStr(projectArgs, PS_LIST_TAIL, "-name", 0, "define project name to list (required)", NULL);
+    psMetadataAddStr(projectArgs, PS_LIST_TAIL, "-name", 0, "define project name to list", NULL);
     psMetadataAddBool(projectArgs, PS_LIST_TAIL, "-simple", 0, "use the simple output format", false);
 
@@ -303,15 +303,24 @@
     psMetadataAddS64(deletefileArgs, PS_LIST_TAIL, "-job_id",      0, "select by job ID (required)", 0);
 
-    // -adduserdomain
-    psMetadata *adduserdomainArgs = psMetadataAlloc();
-    psMetadataAddStr(adduserdomainArgs, PS_LIST_TAIL, "-domain",   0, "define domain name (required)", NULL);
-    psMetadataAddS32(adduserdomainArgs, PS_LIST_TAIL, "-access_level", 0, "define default access level for users in this domain (required)", 0);
-    psMetadataAddStr(adduserdomainArgs, PS_LIST_TAIL, "-default_product",      0, "define default data store product for users in this domain", NULL);
-    psMetadataAddStr(adduserdomainArgs, PS_LIST_TAIL, "-default_label",      0, "define default label for requests from users in this domain", NULL);
+    // Access control tables
+
+    // -adddomain
+    psMetadata *adddomainArgs = psMetadataAlloc();
+    psMetadataAddStr(adddomainArgs, PS_LIST_TAIL, "-set_domain",   0, "define domain name (required)", NULL);
+    psMetadataAddS32(adddomainArgs, PS_LIST_TAIL, "-set_accessLevel", 0, "define access level for this domain (required)", 0);
+    psMetadataAddStr(adddomainArgs, PS_LIST_TAIL, "-set_defaultProduct",   0, "define default product", NULL);
+    psMetadataAddStr(adddomainArgs, PS_LIST_TAIL, "-set_defaultLabel",   0, "define default Label", NULL);
+
+    // -updatedomain
+    psMetadata *updatedomainArgs = psMetadataAlloc();
+    psMetadataAddStr(updatedomainArgs, PS_LIST_TAIL, "-domain",   0, "define domain name (required)", NULL);
+    psMetadataAddS32(updatedomainArgs, PS_LIST_TAIL, "-set_accessLevel", 0, "define access level for this domain", 0);
+    psMetadataAddStr(updatedomainArgs, PS_LIST_TAIL, "-set_defaultProduct",   0, "define default product", NULL);
+    psMetadataAddStr(updatedomainArgs, PS_LIST_TAIL, "-set_defaultLabel",   0, "define default Label", NULL);
 
     // -listdomain
     psMetadata *listdomainArgs = psMetadataAlloc();
     psMetadataAddStr(listdomainArgs, PS_LIST_TAIL, "-domain",   0, "define domain name", NULL);
-    psMetadataAddS32(listdomainArgs, PS_LIST_TAIL, "-access_level", 0, "select by  access level", 0);
+    psMetadataAddS32(listdomainArgs, PS_LIST_TAIL, "-accessLevel", 0, "select by  access level", 0);
     psMetadataAddU64(listdomainArgs, PS_LIST_TAIL, "-limit",       0, "limit result set to N items", 0);
     psMetadataAddBool(listdomainArgs, PS_LIST_TAIL, "-simple",     0, "use the simple output format", false);
@@ -319,9 +328,17 @@
     // -adduser
     psMetadata *adduserArgs = psMetadataAlloc();
-    psMetadataAddStr(adduserArgs, PS_LIST_TAIL, "-user",   0, "define user name (required)", NULL);
-    psMetadataAddStr(adduserArgs, PS_LIST_TAIL, "-domain",   0, "define user's domain name (required)", NULL);
-    psMetadataAddS32(adduserArgs, PS_LIST_TAIL, "-access_level", 0, "define maximum access level for this user (required)", 0);
-    psMetadataAddStr(adduserArgs, PS_LIST_TAIL, "-default_product",      0, "define default data store product for this user", NULL);
-    psMetadataAddStr(adduserArgs, PS_LIST_TAIL, "-default_label",      0, "define default label for requests from this user", NULL);
+    psMetadataAddStr(adduserArgs, PS_LIST_TAIL, "-set_user",   0, "define user name (required)", NULL);
+    psMetadataAddStr(adduserArgs, PS_LIST_TAIL, "-set_domain",   0, "define user's domain name (required)", NULL);
+    psMetadataAddS32(adduserArgs, PS_LIST_TAIL, "-set_accessLevel", 0, "define maximum access level for this user", 0);
+    psMetadataAddStr(adduserArgs, PS_LIST_TAIL, "-set_defaultProduct",      0, "define default data store product for this user", NULL);
+    psMetadataAddStr(adduserArgs, PS_LIST_TAIL, "-set_defaultLabel",      0, "define default label for requests from this user", NULL);
+
+    // -updateuser
+    psMetadata *updateuserArgs = psMetadataAlloc();
+    psMetadataAddStr(updateuserArgs, PS_LIST_TAIL, "-user",   0, "select user to update (required)", NULL);
+    psMetadataAddStr(updateuserArgs, PS_LIST_TAIL, "-domain",   0, "select domain of user to update (required)", NULL);
+    psMetadataAddS32(updateuserArgs, PS_LIST_TAIL, "-set_accessLevel", 0, "define access level for this domain", 0);
+    psMetadataAddStr(updateuserArgs, PS_LIST_TAIL, "-set_defaultProduct",   0, "define default product", NULL);
+    psMetadataAddStr(updateuserArgs, PS_LIST_TAIL, "-set_defaultLabel",   0, "define default Label", NULL);
 
     // -listuser
@@ -329,7 +346,31 @@
     psMetadataAddStr(listuserArgs, PS_LIST_TAIL, "-user",   0, "select by user name", NULL);
     psMetadataAddStr(listuserArgs, PS_LIST_TAIL, "-domain",   0, "select by user's domain name", NULL);
-    psMetadataAddS32(listuserArgs, PS_LIST_TAIL, "-access_level", 0, "select by maximum access level", 0);
+    psMetadataAddS32(listuserArgs, PS_LIST_TAIL, "-accessLevel", 0, "select by maximum access level", 0);
     psMetadataAddU64(listuserArgs, PS_LIST_TAIL, "-limit",       0, "limit result set to N items", 0);
     psMetadataAddBool(listuserArgs, PS_LIST_TAIL, "-simple",     0, "use the simple output format", false);
+
+    // -addaccesslevel
+    psMetadata *addaccesslevelArgs = psMetadataAlloc();
+    psMetadataAddStr(addaccesslevelArgs, PS_LIST_TAIL, "-set_project_name",   0, "define project name", NULL);
+    psMetadataAddS64(addaccesslevelArgs, PS_LIST_TAIL, "-set_proj_id", 0, "define project ID", 0);
+    psMetadataAddS32(addaccesslevelArgs, PS_LIST_TAIL, "-set_accessLevel", 0, "define access level (required)", 0);
+    psMetadataAddF32(addaccesslevelArgs, PS_LIST_TAIL, "-set_mjd_min", 0, "define mjd_min", 0.0);
+    psMetadataAddF32(addaccesslevelArgs, PS_LIST_TAIL, "-set_mjd_max", 0, "define mjd_max", 0.0);
+
+    // -listaccesslevel
+    psMetadata *listaccesslevelArgs = psMetadataAlloc();
+    psMetadataAddStr(listaccesslevelArgs, PS_LIST_TAIL, "-project_name",   0, "search by project name", NULL);
+    psMetadataAddS64(listaccesslevelArgs, PS_LIST_TAIL, "-proj_id", 0, "select by  project ID", 0);
+    psMetadataAddS32(listaccesslevelArgs, PS_LIST_TAIL, "-accessLevel", 0, "select by  access level", 0);
+    psMetadataAddU64(listaccesslevelArgs, PS_LIST_TAIL, "-limit",       0, "limit result set to N items", 0);
+    psMetadataAddBool(listaccesslevelArgs, PS_LIST_TAIL, "-simple",     0, "use the simple output format", false);
+
+    // -updateaccesslevel
+    psMetadata *updateaccesslevelArgs = psMetadataAlloc();
+    psMetadataAddStr(updateaccesslevelArgs, PS_LIST_TAIL, "-project_name",   0, "select by project name", NULL);
+    psMetadataAddS64(updateaccesslevelArgs, PS_LIST_TAIL, "-proj_id", 0, "select by project ID", 0);
+    psMetadataAddS32(updateaccesslevelArgs, PS_LIST_TAIL, "-accessLevel", 0, "select by access level (required)", 0);
+    psMetadataAddF32(updateaccesslevelArgs, PS_LIST_TAIL, "-set_mjd_min", 0, "define new mjd_min", NAN);
+    psMetadataAddF32(updateaccesslevelArgs, PS_LIST_TAIL, "-set_mjd_max", 0, "define new mjd_max", NAN);
 
     PXOPT_ADD_MODE("-addreq",          "", PSTAMPTOOL_MODE_ADDREQ,       addreqArgs);
@@ -365,6 +406,12 @@
     PXOPT_ADD_MODE("-deletefile",      "", PSTAMPTOOL_MODE_DELETEFILE,   deletefileArgs);
 
+    PXOPT_ADD_MODE("-adddomain",       "", PSTAMPTOOL_MODE_ADDDOMAIN, adddomainArgs);
+    PXOPT_ADD_MODE("-updatedomain",    "", PSTAMPTOOL_MODE_UPDATEDOMAIN, updatedomainArgs);
     PXOPT_ADD_MODE("-listdomain",      "", PSTAMPTOOL_MODE_LISTDOMAIN, listdomainArgs);
+    PXOPT_ADD_MODE("-adduser",         "", PSTAMPTOOL_MODE_ADDUSER, adduserArgs);
+    PXOPT_ADD_MODE("-updateuser",      "", PSTAMPTOOL_MODE_UPDATEUSER, updateuserArgs);
     PXOPT_ADD_MODE("-listuser",        "", PSTAMPTOOL_MODE_LISTUSER, listuserArgs);
+    PXOPT_ADD_MODE("-addaccesslevel",  "", PSTAMPTOOL_MODE_ADDACCESSLEVEL, addaccesslevelArgs);
+    PXOPT_ADD_MODE("-listaccesslevel", "", PSTAMPTOOL_MODE_LISTACCESSLEVEL, listaccesslevelArgs);
 
     if (!pxGetOptions(stderr, argc, argv, config, modes, argSets)) {
Index: /branches/eam_branches/ipp-20150419/pstamp/scripts/pstampparse.pl
===================================================================
--- /branches/eam_branches/ipp-20150419/pstamp/scripts/pstampparse.pl	(revision 38450)
+++ /branches/eam_branches/ipp-20150419/pstamp/scripts/pstampparse.pl	(revision 38451)
@@ -33,4 +33,7 @@
 my $dest_requires_magic;
 my $dump_params = 0;
+my $new_email;
+
+my %accessLevelCache;
 
 # set this to true to disable update processing
@@ -43,4 +46,5 @@
     'product=s' =>  \$product,
     'label=s'   =>  \$label,
+    'new_email=s' => \$new_email,
     'mode=s'    =>  \$mode,
     'need_magic'=>  \$dest_requires_magic,
@@ -142,7 +146,11 @@
     print STDERR "Note that EMAIL will not be optional\n";
 
+    # if need be we can hack Peter Veres' email in here if label = 'WEB.UP' and req_name like 'Peter_Veres%'
+
 } elsif (!$email) {
     my_die("ERROR: Required parameter EMAIL not found in request file header.\n", $PSTAMP_INVALID_REQUEST) 
 }
+
+
     
 
@@ -158,6 +166,4 @@
     my_die("email not supplied in version $extver request file $request_file_name\n", $PSTAMP_INVALID_REQUEST)
         unless $email;
-
-    # XXX check for "valid" $email
 } else {
     # for version 1 file the action is process and email is not used
@@ -167,4 +173,10 @@
 
 print "Request Header Keywords EXTVER: $extver REQ_NAME: $req_name ACTION: $action EMAIL: $email\n";
+
+if ($new_email) {
+    # this is primarily for ease in testing
+    print "Setting email to command line provided value $new_email\n";
+    $email = $new_email
+}
 
 # check for duplicate request name
@@ -239,5 +251,5 @@
 
 # if the request came through the upload channel, change it to the user's specific label
-# if any is known.
+# if any is known. Do we want to do this for any other channels?
 if ($label and $label eq 'WEB.UP') {
     if ($labelForUser) {
@@ -749,5 +761,6 @@
 
             if ($mjd > $mjd_max) {
-                print STDERR "User is not authorized for stamps from this exposure.\n";
+                print "User is not authorized for stamps from this exposure exp_id $exp_id.\n";
+                print STDERR "User is not authorized for stamps from this exposure exp_id $exp_id.\n";
                 insertFakeJobForRow($row, $job_num, $PSTAMP_NOT_AUTHORIZED, $exp_id);
                 return 1;
@@ -1343,15 +1356,33 @@
     my $adjusted = 0;
 
-    my $MJD_PS1_BEGIN = 54922;    # 2009-04-01
-    my $MJD_PS1_END   = 57082;    # 2015-03-01
-
-    if ($row->{accessLevel} == 1) {
-        # User has access to PS1 data only
-        my $mjd_max_user = $row->{MJD_MAX};
-        if (!$mjd_max_user or $mjd_max_user > $MJD_PS1_END) {
-            $$r_mjd_max = $MJD_PS1_END;
+    my $accessLevel = $row->{accessLevel};
+    my $project = $row->{PROJECT};
+    my $mjd_max_user = $row->{MJD_MAX};
+
+    my $key = "$project.$accessLevel";
+
+    my $levelInfo = $accessLevelCache{$key};
+
+    if (!$levelInfo) {
+        my $cmd = "$pstamptool -listaccesslevel -accessLevel $accessLevel -project_name $project";
+        my $results = runToolAndParse($cmd, $verbose);
+        if (!$results or !$results->[0]) {
+            my_die("failed to find accessLevel info for project: $project level: $accessLevel\n", $PS_EXIT_CONFIG_ERROR);
+        }
+        $levelInfo = $results->[0];
+        $accessLevelCache{$key} = $levelInfo;
+    }
+
+    my $mjd_max_thisLevel = $levelInfo->{mjd_max};
+    if ($mjd_max_thisLevel)  {
+        # This project has a limit for this level
+        # adjust the user supplied limit unless it is less than the maximum
+
+        if (!$mjd_max_user or ($mjd_max_user > $mjd_max_thisLevel)) {
+            $$r_mjd_max = $mjd_max_thisLevel;
             $adjusted = 1;
         }
     }
+
     return $adjusted;
 }
